sql数据流,amdin业务逻辑接入

This commit is contained in:
comlibmb
2026-02-05 10:11:09 +08:00
parent 859372ca5b
commit ac670cf5d8
81 changed files with 3547 additions and 1472 deletions

View File

@@ -0,0 +1,594 @@
# CRMEB管理端uvue实现操作指南
## 项目概述
本文档详细介绍基于CRMEB商城系统管理端功能使用uvue + Supabase技术栈重新实现的完整管理后台操作指南。
## 技术架构
### 前端技术栈
- **框架**: uvue (uni-app x)
- **状态管理**: Vue 3 Composition API
- **UI组件**: 自定义组件 + uni-app内置组件
- **样式**: CSS + Flex布局 + 响应式设计
- **设计风格**: 参考CRMEB开源商城系统采用统一的卡片布局和配色方案
- **图标库**: iconfont字体图标库
### 后端技术栈
- **数据库**: Supabase (PostgreSQL)
- **API**: @components/supadb 组件库
- **认证**: Supabase Auth
- **存储**: Supabase Storage
- **实时功能**: Supabase Realtime
## 功能模块
### 1. 管理端首页 (`index.uvue`)
#### 功能特性
- **基础信息统计卡片**: 显示销售额、订单数、用户数等核心指标
- **功能导航网格**: 快速访问各个管理模块
- **数据可视化**: 实时统计数据展示
#### 页面结构
参考CRMEB设计风格采用统一的卡片布局和Flex布局
```vue
<template>
<view class="admin-dashboard">
<!-- 顶部统计卡片 -->
<view class="header acea-row">
<navigator class="item" url="/pages/mall/admin/order-management" hover-class="none">
<view class="num">{{ pendingCounts.order_pending }}</view>
<view>待处理订单</view>
</navigator>
<!-- 其他统计项 -->
</view>
<!-- 数据统计 -->
<view class="wrapper">
<view class="title">
<span class="iconfont icon-shujutongji"></span>数据统计
</view>
<view class="list acea-row">
<navigator class="item" url="/pages/mall/admin/statistics/sales" hover-class="none">
<view class="num">{{ todayStats.sales }}</view>
<view>今日销售额</view>
</navigator>
<!-- 其他统计项 -->
</view>
</view>
<!-- 功能导航 -->
<view class="public-wrapper">
<view class="title">
<span class="iconfont icon-gongnengdaohang"></span>功能导航
</view>
<view class="menu-grid acea-row">
<view class="menu-item" @click="go('/pages/mall/admin/user-management')">
<view class="menu-icon">
<text class="iconfont icon-yonghuguanli"></text>
</view>
<text class="menu-text">用户管理</text>
</view>
<!-- 其他功能项 -->
</view>
</view>
</view>
</template>
```
#### 数据加载
```typescript
// 获取基础统计数据
const loadBaseStats = async () => {
const salesStats = await supa.rpc('get_sales_stats', {
start_date: yesterday,
end_date: today
})
// 更新统计数据
}
```
### 2. 用户管理 (`user-management.uvue`)
#### 核心功能
- **用户搜索筛选**: 支持多条件组合查询
- **用户列表展示**: 分页显示用户信息
- **批量操作**: 导出用户、群发消息、调整余额
- **用户状态管理**: 启用/禁用用户账户
- **用户详情**: 查看和编辑用户信息
#### 搜索功能
```typescript
const searchTypes = ref([
{ value: 'all', label: '全部' },
{ value: 'uid', label: 'UID' },
{ value: 'phone', label: '手机号' },
{ value: 'nickname', label: '用户昵称' }
])
const userLevels = ref([]) // 用户等级选项
const userGroups = ref([]) // 用户分组选项
const agentLevels = ref([]) // 分销等级选项
```
#### 用户操作
```typescript
// 切换用户状态
const toggleUserStatus = async (userId: number, currentStatus: number) => {
const newStatus = currentStatus === 1 ? 0 : 1
await supa.from('users').update({ status: newStatus }).eq('id', userId)
}
// 批量导出用户
const exportUsers = () => {
// 导出逻辑
}
```
### 3. 商品管理 (`product-management.uvue`)
#### 功能特性
- **商品列表**: 分页展示商品信息
- **高级筛选**: 商品类型、分类、价格、库存等条件
- **批量操作**: 批量上架/下架/删除
- **商品状态管理**: 上架、下架、编辑
- **商品规格**: 支持多规格商品管理
#### 商品筛选
```typescript
const productTypes = ref([
{ value: '0', label: '普通商品' },
{ value: '1', label: '卡密商品' },
{ value: '2', label: '优惠券商品' },
{ value: '3', label: '虚拟商品' }
])
const deliveryTypes = ref([
{ value: '1', label: '快递配送' },
{ value: '2', label: '到店自提' }
])
```
#### 商品操作
```typescript
// 批量上架
const batchOnShelf = async () => {
await supa.from('products')
.update({ is_show: true })
.in('id', selectedProducts.value)
}
// 删除商品
const deleteProduct = async (productId: number) => {
await supa.from('products')
.update({ is_del: true })
.eq('id', productId)
}
```
### 4. 订单管理 (`order-management.uvue`)
#### 核心功能
- **订单类型标签页**: 全部订单、普通订单、待支付、待发货等
- **订单搜索**: 订单号、用户名、收货人等条件
- **订单状态管理**: 确认订单、发货、查看物流
- **订单详情**: 完整的订单信息展示
- **批量操作**: 批量发货、导出订单
#### 订单状态
```typescript
const orderStatuses = ref([
{ value: '0', label: '待确认' },
{ value: '1', label: '待支付' },
{ value: '2', label: '待发货' },
{ value: '3', label: '已发货' },
{ value: '4', label: '已完成' },
{ value: '5', label: '已取消' },
{ value: '6', label: '退款中' }
])
```
#### 订单操作
```typescript
// 确认订单
const confirmOrder = async (orderId: number) => {
await supa.from('orders').update({ status: 1 }).eq('id', orderId)
}
// 订单发货
const confirmShip = async () => {
await supa.from('orders').update({
status: 3,
ship_info: {
express_company: shipForm.express_company,
express_number: shipForm.express_number,
ship_time: new Date().toISOString()
}
}).eq('id', shipForm.order_id)
}
```
### 5. 财务管理 (`finance-management.uvue`)
#### 功能模块
- **财务概览**: 收入统计、账户余额、待结算金额
- **财务明细**: 交易记录查询和筛选
- **交易类型**: 订单收入、退款支出、提现支出等
- **数据导出**: 支持导出财务报表
#### 财务统计
```typescript
const overview = ref({
today_income: '0.00',
month_income: '0.00',
account_balance: '0.00',
pending_settlement: '0.00'
})
```
#### 交易记录查询
```typescript
const loadRecords = async () => {
let query = supa.from('finance_records')
.select('*')
.order('created_at', { ascending: false })
// 筛选条件
if (selectedType.value) {
query = query.eq('type', selectedType.value)
}
// 分页
const { data, count } = await query.range(from, to)
}
```
### 6. 系统设置 (`system-settings.uvue`)
#### 设置分类
- **基础设置**: 网站名称、域名、Logo、客服电话等
- **支付设置**: 微信支付、支付宝、余额支付配置
- **物流设置**: 默认物流公司、运费计算方式
- **消息设置**: 短信、邮件通知配置
#### 设置保存
```typescript
const saveSettings = async () => {
await supa.from('system_settings').upsert(settings.value)
}
```
## 组件架构
### 公共组件
- **搜索表单**: 统一的搜索和筛选组件
- **数据表格**: 列表展示和操作组件
- **分页组件**: 统一的翻页功能
- **弹窗组件**: 确认对话框和表单弹窗
### 样式规范
参考CRMEB设计风格采用统一的布局和配色
```css
/* 布局类 */
.acea-row {
display: flex;
flex-direction: row;
}
.row-between-wrapper {
justify-content: space-between;
align-items: center;
}
/* 颜色规范 */
.primary-theme: #fba02a; /* 橙色主题色 */
.secondary-theme: #2291f8; /* 蓝色辅助色 */
.success-color: #1abb1d; /* 成功色 */
.danger-color: #ff6969; /* 危险色 */
/* 卡片样式 */
.public-wrapper {
width: 690rpx;
background-color: #fff;
border-radius: 10rpx;
margin: 20rpx auto 0 auto;
padding: 30rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
/* 字体图标 */
.iconfont {
font-family: 'iconfont';
color: #2291f8;
font-size: 36rpx;
margin-right: 13rpx;
vertical-align: middle;
}
```
## 数据交互
### Supabase集成
```typescript
import supa from '@/components/supadb/aksupainstance.uts'
// 查询数据
const { data, error } = await supa
.from('table_name')
.select('*')
.eq('field', value)
// 插入数据
const { data, error } = await supa
.from('table_name')
.insert(newData)
// 更新数据
const { data, error } = await supa
.from('table_name')
.update(updateData)
.eq('id', id)
// 删除数据
const { data, error } = await supa
.from('table_name')
.delete()
.eq('id', id)
```
### RPC调用
```typescript
// 调用存储过程
const { data, error } = await supa.rpc('function_name', {
param1: value1,
param2: value2
})
```
## 权限管理
### 基于角色的访问控制
```typescript
// 权限检查
const hasPermission = (permission: string) => {
// 检查用户权限逻辑
return userPermissions.includes(permission)
}
// 页面级权限控制
onMounted(() => {
if (!hasPermission('admin.user.view')) {
uni.showToast({
title: '无权限访问',
icon: 'error'
})
uni.navigateBack()
}
})
```
## 性能优化
### 1. 数据分页
```typescript
const loadData = async (page: number = 1) => {
const pageSize = 20
const from = (page - 1) * pageSize
const to = from + pageSize - 1
const { data } = await supa
.from('table')
.select('*')
.range(from, to)
}
```
### 2. 条件查询优化
```typescript
// 使用索引字段进行查询
const { data } = await supa
.from('orders')
.select('*')
.eq('status', 1) // 状态字段通常有索引
.gte('created_at', startDate)
.order('created_at', { ascending: false })
```
### 3. 实时数据订阅
```typescript
// 监听数据变化
const subscription = supa
.channel('table-changes')
.on('postgres_changes', {
event: '*',
schema: 'public',
table: 'orders'
}, (payload) => {
// 处理数据变化
updateLocalData(payload)
})
.subscribe()
```
## 错误处理
### 统一错误处理
```typescript
const handleError = (error: any) => {
console.error('操作失败:', error)
let message = '操作失败,请重试'
if (error.message) {
message = error.message
}
uni.showToast({
title: message,
icon: 'error'
})
}
```
### 网络请求错误
```typescript
try {
const { data, error } = await supa.from('table').select('*')
if (error) throw error
// 处理成功的数据
} catch (error) {
handleError(error)
}
```
## 响应式设计
### 移动端适配
```scss
// 响应式断点
@media (max-width: 750rpx) {
.container {
padding: 20rpx;
}
.grid {
grid-template-columns: 1fr;
gap: 15rpx;
}
.table-row {
flex-wrap: wrap;
.table-cell {
min-width: 200rpx;
margin-bottom: 10rpx;
}
}
}
```
## 部署和维护
### 环境配置
```javascript
// config/admin.js
export default {
supabase: {
url: process.env.SUPABASE_URL,
anonKey: process.env.SUPABASE_ANON_KEY,
serviceRoleKey: process.env.SUPABASE_SERVICE_ROLE_KEY
},
pagination: {
defaultPageSize: 20,
maxPageSize: 100
},
upload: {
maxFileSize: 10 * 1024 * 1024, // 10MB
allowedTypes: ['image/jpeg', 'image/png', 'image/webp']
}
}
```
### 日志记录
```typescript
// 操作日志记录
const logOperation = async (action: string, details: any) => {
await supa.from('admin_logs').insert({
admin_id: currentAdmin.id,
action,
details,
ip: getClientIP(),
user_agent: navigator.userAgent,
created_at: new Date().toISOString()
})
}
```
## 开发规范
### 代码组织
```
pages/mall/admin/
├── index.uvue # 管理首页
├── user-management.uvue # 用户管理
├── product-management.uvue # 商品管理
├── order-management.uvue # 订单管理
├── finance-management.uvue # 财务管理
├── system-settings.uvue # 系统设置
└── components/ # 公共组件
├── SearchForm.uvue
├── DataTable.uvue
├── Pagination.uvue
└── Modal.uvue
```
### 命名规范
- **文件命名**: 使用 kebab-case (user-management.uvue)
- **变量命名**: 使用 camelCase (userList, isLoading)
- **组件命名**: 使用 PascalCase (UserManagement)
- **函数命名**: 使用 camelCase (loadUserList, handleSubmit)
### 注释规范
```typescript
/**
* 用户管理页面
* 功能:用户列表展示、搜索筛选、状态管理等
*/
// 函数注释
/**
* 加载用户列表
* @param page 页码
* @param filters 筛选条件
*/
const loadUserList = async (page: number = 1, filters: any = {}) => {
// 具体实现
}
```
## 常见问题
### 1. 数据加载慢
**问题**: 列表数据加载缓慢
**解决方案**:
- 添加合适的数据库索引
- 实现数据分页
- 使用缓存机制
- 优化查询条件
### 2. 权限控制
**问题**: 用户权限判断不准确
**解决方案**:
- 在路由层面进行权限检查
- 实现基于角色的访问控制
- 前端页面级权限验证
### 3. 实时数据同步
**问题**: 多用户同时操作数据冲突
**解决方案**:
- 使用 Supabase 实时订阅
- 实现乐观更新
- 添加数据版本控制
## 更新日志
### v1.0.0 (2024-01-22)
- ✅ 完成基础管理功能实现
- ✅ 用户管理模块
- ✅ 商品管理模块
- ✅ 订单管理模块
- ✅ 财务管理模块
- ✅ 系统设置模块
### 计划功能
- 🔄 营销管理模块
- 🔄 数据统计图表
- 🔄 批量操作优化
- 🔄 移动端适配完善
- 🔄 性能优化
---
本文档持续更新中,如有问题请及时反馈。

View File

@@ -0,0 +1,325 @@
# Agent 项目规范文档uni-app / uvue / uts
## 0. 文档目标与适用范围
- **目标**统一项目目录、命名、依赖边界、数据库SQL/RLS/RPC安全策略与准入流程使 Agent 在改动代码/SQL 时遵循一致的工程约束与安全基线。
- **适用范围**
- 前端:`pages/``components/``layouts/``services/``utils/``types/``uni_modules/``static/`
- 文档与数据库:`docs/``docs/sql/`、模块内 `test/` SQL
---
## 1. 项目核心结构与职责边界
### 1.1 页面与路由
- **权威路由配置**:根目录 `pages.json`
- **分包规则**
- `tabBar`:主入口页面(消费者端)
- `subPackages`按模块分包consumer 非 tab 页、delivery、analytics、admin、merchant、service 等模块)
- **页面目录**`pages/`
- `pages/user/`:登录/注册/用户中心等公共页面
- `pages/mall/<module>/`各业务模块consumer/delivery/analytics/admin/merchant/service...
- **规则**
- `pages/` 内只放页面(路由入口)与页面级组合逻辑
- 可复用 UI/逻辑必须下沉到 `components/` / `services/` / `utils/` / `types/`
### 1.2 布局
- **目录**`layouts/`
- **规则**
- layout 只负责结构与 slot/容器
- layout 不直接写重业务数据请求(可触发初始化但不承担领域逻辑)
### 1.3 组件
- **目录**`components/`
- **推荐分层(可渐进迁移)**
- `components/base/`:无业务语义基础组件(按钮、弹窗、表单控件、空状态等)
- `components/biz/<domain>/`带业务语义组件订单卡片、SKU 选择器等)
- `components/integration/<vendor>/`:第三方/平台集成组件(如 supabase、analytics SDK 外观层)
- **规则**
- 组件不得直接读写数据库或拼接 SQL
- 网络/数据访问必须通过 `services/`(数据访问唯一入口)
### 1.4 服务层(数据访问唯一入口)
- **目录**`services/`
- **职责**
- RPC/API 调用封装
- 鉴权、token 注入、错误标准化处理
- 数据转换DTO -> ViewModel 允许在这里或页面层,但必须统一口径)
- **规则**
- 页面/组件不得直接访问底层 client如 supabase client必须经 `services/` 统一出口
### 1.5 工具与类型
- **目录**
- `utils/`:纯工具函数(尽量无 IO、无全局状态
- `types/`全局类型、领域模型、DTO、服务返回类型
- **规则**
- `utils/` 不反向依赖业务模块目录
- `types/` 不依赖运行时代码(保持纯类型)
### 1.6 插件/可替换模块
- **目录**`uni_modules/`
- **定位**:可独立发布/可替换的插件能力组件、uts sdk、集成适配等
- **规则**
- 不把所有业务通用代码塞到 `uni_modules/`;业务通用优先 `services/utils/components`
---
## 2. 路径别名与引用规范
### 2.1 当前事实
- `tsconfig.json` 已配置:`@/* -> ./*`
### 2.2 统一引用建议Agent 必须遵循)
- 默认使用 `@/` 前缀引用项目内代码(例如 `@/services/...``@/components/...`
- 不强制引入 `@components``@uni_modules` 这类新 alias除非后续明确要落地到配置文件当前以目录语义规范为准
---
## 3. 依赖方向(强约束)
为避免循环依赖与业务污染,依赖方向必须满足:
- `pages` -> 可依赖 `components/services/utils/types/layouts`
- `components` -> 可依赖 `services/utils/types`
- `layouts` -> 可依赖 `components/utils/types`(避免重业务)
- `services` -> 只依赖 `utils/types`(不得依赖 pages/components
- `utils` -> 不依赖业务目录
- `types` -> 不依赖运行时代码
---
## 4. 命名与文件组织规范
- **目录名**:全小写,必要时用连字符(全仓统一一种风格)
- **组件文件**`PascalCase.uvue`
- **服务文件**:统一 `xxxService.uts`
- **SQL 文件**
- 测试阶段:模块 `test/` 下自由命名,但必须含用途前缀
- 权威阶段:进入 `docs/sql/` 后必须按分层目录 + 版本号命名(见第 6 节)
---
## 5. 数据库/权限权威口径(与前端联动)
本项目数据库权限与前端路由/页面访问形成闭环。以下为强制口径:
- **角色字段唯一权威**`public.ak_users.role`
- **analytics/admin 的全局数据访问**:必须通过 RPC 完成,避免直接开放业务表全局权限
- **前端必须做客户端守卫**
- 访问 analytics/admin 页面入口时,必须校验登录与角色(例如 `ensureRole(['admin','analytics'])`
- 客户端守卫只用于“快速失败”,最终权限以数据库侧为准
---
## 6. SQL 两阶段工作流(模块测试 -> 权威入库)
### 6.1 阶段 A模块内测试 SQL非权威
- **位置**:各模块目录 `test/`
- 例:`pages/mall/analytics/test/*.sql`
- **允许**:快速迭代、验证思路、临时脚本
- **禁止**:高危破坏性操作(见 7.3
### 6.2 阶段 B入库到 `docs/sql/`(权威)
- **位置**`docs/sql/`
- **入库准入条件**
- 必须通过 Agent 安全评估(输出评审报告)
- 必须符合本项目角色/RLS/RPC 安全口径(见 7.2;并强制对照 `docs/sql/11_roles_and_permissions_strategy.md`
- 建议至少 1 人人工确认后再合并
### 6.3 `docs/sql/` 分层(权威目录结构)
为保证可审计、可复用与最小风险暴露,进入权威目录的 SQL 必须按“对象类型”拆分归档,禁止将多种对象(表 + RLS + RPC + GRANT 等)长期混放在同一个文件中。
- `docs/sql/00_meta/`:规范/策略/说明类(如角色与权限策略)
- `docs/sql/10_schema/`:表/类型/索引等 DDL
- 建议进一步按域分组:`docs/sql/10_schema/<domain>/...`
- `docs/sql/20_rls/`RLS enable + policies按表/域拆分)
- 建议进一步按域分组:`docs/sql/20_rls/<domain>/...`
- `docs/sql/30_rpc/`RPC/函数(尤其 analytics
- 建议进一步按域分组:`docs/sql/30_rpc/<domain>/...`
- `docs/sql/40_grants/`显式授权GRANT/REVOKE
- 仅允许最小权限;对 `anon/authenticated` 的任何授权必须附带评审结论
- `docs/sql/90_archive/`:历史/废弃(只读,不再作为引用口径)
**对象拆分规则(入库必选一类)**
- **表/类型/索引**:只放 DDL`CREATE/ALTER TABLE/TYPE/INDEX`),归入 `10_schema`
- **RLS 策略**:只放 `ALTER TABLE ... ENABLE ROW LEVEL SECURITY``CREATE POLICY/ALTER POLICY/DROP POLICY`,归入 `20_rls`
- **函数/RPC**:只放 `CREATE OR REPLACE FUNCTION ...`(含 `SECURITY DEFINER` 等),归入 `30_rpc`
- **授权**:只放 `GRANT/REVOKE`,归入 `40_grants`
**例外(允许同文件)**
- 同一对象的“紧耦合小变更”可以同文件(例如同一个函数的创建 + 注释/owner 设置),但不得混入其他对象类型。
### 6.4 权威 SQL 入库步骤(从模块 test/ 迁移)
当模块内 `test/` SQL 验证通过、准备进入 `docs/sql/` 时,必须按以下步骤执行:
- **步骤 0目录存在性检查必须**
- 若以下目录不存在Agent 必须创建;若已存在则复用,禁止新建“近似重复目录”。
- 目录清单:
- `docs/sql/00_meta/`
- `docs/sql/10_schema/`
- `docs/sql/20_rls/`
- `docs/sql/30_rpc/`
- `docs/sql/40_grants/`
- `docs/sql/90_archive/`
- 如采用域分组(`<domain>`),对应的 `docs/sql/<layer>/<domain>/` 目录同样遵循“无则创建,有则复用”。
- **步骤 1对象识别与拆分**
- 将 SQL 按对象类型拆分为schema / rls / rpc / grants必要时再细分 domain
- **步骤 2命名与归档路径确定**
- 表/DDL`docs/sql/10_schema/<domain>/<object>_v<version>.sql`
- RLS`docs/sql/20_rls/<domain>/<table>_rls_v<version>.sql`
- RPC`docs/sql/30_rpc/<domain>/<rpc_name>_v<version>.sql`
- Grants`docs/sql/40_grants/<domain>/<scope>_grants_v<version>.sql`
- **步骤 3安全评审Agent 必须输出评审报告)**
- 评审必须强制对照 `docs/sql/11_roles_and_permissions_strategy.md`
- 结论为 `OK` 方可入库
- **步骤 4入库与引用口径**
- 入库后,模块 `test/` 中对应脚本仅保留为测试/回归用途(不得再作为权威引用)
---
## 7. Agent SQL 安全评估制度(准入制)
### 7.1 评估结论(必须输出其一)
- `Reject`:拒绝入库
- `High`:高风险,必须整改后复评
- `OK`:可入库
### 7.2 项目强制安全要求RPC/analytics
所有 `rpc_analytics_*`(及类似特权 RPC必须满足
- `SECURITY DEFINER`
- `SET search_path = public`(固定 search_path
- 函数入口显式鉴权:
- `get_current_user_role() IN ('admin','analytics')` 才允许执行
- 返回字段最小化(只返回统计必要字段/聚合结果)
**强制参照文档**:所有 SQL 评审必须对照并满足 `docs/sql/11_roles_and_permissions_strategy.md` 中的角色定义、RLS 分层、RPC 安全闭环要求。
### 7.3 硬阻断出现任意一条Reject
- **裸放权**:对 `anon/authenticated` 大范围 `GRANT` 且无等价约束
- **破坏性操作**
- `DROP TABLE/SCHEMA/ROLE/EXTENSION`
- `TRUNCATE`
- 大范围 `DELETE/UPDATE` 无可靠 `WHERE`
- **不安全的 SECURITY DEFINER**
- 无入口鉴权
- 未固定 `search_path`
- **绕过 RLS 的不透明入口**:绕过后无角色校验/无最小返回字段
### 7.4 高风险需整改High
- RLS 覆盖不全(业务需要写但未覆盖 `INSERT/UPDATE/DELETE`
- policy 条件过宽(如 `USING (true)`
- RPC 返回敏感字段
- 无分页/无 LIMIT 约束造成全量泄露或性能风险
---
## 8. Agent SQL 评审报告模板(固定输出)
### SQL 安全评审报告
- **对象**`<文件路径>`
- **目标**`<此 SQL 的目的>`
- **结论**`Reject | High | OK`
- **涉及对象**
- 表/视图/函数:`...`
- 角色/权限:`...`
- RLS是否启用/修改;覆盖哪些操作
- `SECURITY DEFINER`:是/否;入口鉴权:是/否;`search_path` 固定:是/否
- **与项目口径一致性(强制对照 docs/sql/11**
- admin/analytics 是否仅通过 RPC 获取全局数据:是/否
- **风险点列表**
- `等级` + `定位(片段/行号)` + `原因`
- **整改建议**
- 可执行修改建议清单
- **准入建议**
- 是否允许进入 `docs/sql/`:是/否;若否:进入条件
---
## 9. 与现有 SQL/文档目录的边界(避免双真相)
仓库存在多处 SQL/迁移相关目录(如 `mall_sql/``doc_mall/`)。必须明确:
- **权威策略/权威脚本口径**:以 `docs/sql/` 为准
- 其他目录若属于迁移脚本仓/历史产物:
- 必须标注用途(迁移工具、一次性脚本、报告存档)
- 不允许出现与 `docs/sql/` 并行的“第二份权威定义”
---
## 10. 操作文档(强制)
任何会对项目产生可观察影响的操作Agent 必须同步编写“操作文档”,将操作过程与结果可描述化、可审计化。
### 10.1 何时必须写操作文档
- 修改/新增/删除任何代码文件(`.uvue/.uts/.ts/.js/.json/.scss` 等)
- 修改 `pages.json``manifest.json``package.json``tsconfig.json` 等配置
- 新增/调整 SQL包括模块 `test/``docs/sql` 权威入库)
- 任何涉及权限/鉴权/RLS/RPC/GRANT 的变更
### 10.2 操作文档存放位置(从当前操作目录向上查找)
存放规则:从“当前正在操作的目录”开始,逐层向上寻找 `docs/` 目录,直到“当前模块根目录”为止。
- 若在某一层找到 `docs/`:将操作文档写入该 `docs/` 下的 `ops/` 子目录。
- 若一路向上直到模块根目录仍未找到 `docs/`Agent 必须在模块根目录创建 `docs/ops/` 并写入。
- 若目标 `docs/ops/` 不存在Agent 必须创建;若存在则复用。
**模块根目录判定**(满足任一即可认为到达模块根):
- 存在 `pages.json`(项目根)
- 或进入了业务模块目录(例如 `pages/mall/analytics/``pages/mall/admin/``pages/user/`)的顶层
- 或进入了公共模块目录(例如 `services/``components/``utils/``types/``uni_modules/<name>/`)的顶层
### 10.3 公共模块 vs 业务模块 的归档规则
- **业务模块操作**:文档归档到该业务模块自己的 `docs/ops/`
- 例:操作发生在 `pages/mall/analytics/...`,则优先归档到 `pages/mall/analytics/docs/ops/`
- **公共模块操作**:文档归档到对应公共模块自己的 `docs/ops/`
- 例:操作发生在 `services/...`,则归档到 `services/docs/ops/`
- 例:操作发生在 `uni_modules/<name>/...`,则归档到 `uni_modules/<name>/docs/ops/`
### 10.4 操作文档命名规范
- 文件名:`YYYY-MM-DD__<scope>__<short-title>.md`
- `scope` 建议值:
- `analytics` / `admin` / `consumer` / `merchant` / `delivery` / `user`
- `services` / `components` / `utils` / `types` / `uni_modules-<name>`
### 10.5 操作文档最小内容模板
- **摘要**:做了什么
- **动机**:为什么要做
- **影响范围**:涉及哪些模块/页面/接口/权限
- **变更清单**
- 新增文件:...
- 修改文件:...
- 删除文件:...
- **兼容性与风险**:可能的副作用、回滚风险
- **回滚方案**:如何撤销、恢复到原状态
- **验证方式**:如何验证改动正确(手工步骤/测试点)
- **关联文档**:例如 `docs/sql/11_roles_and_permissions_strategy.md` 或对应评审报告

View File

@@ -0,0 +1,475 @@
# CRMEB 标准版后台 - 数据看板与用户统计页
## 📋 项目概述
基于 uni-app-x 自主开发的 CRMEB 风格后台管理系统,包含完整的数据看板和用户统计功能。严格遵循 CRMEB 的设计规范和布局结构,所有代码完全自主编写。
## 🗂️ 目录结构
```
mall/
├── layouts/
│ └── admin/
│ ├── index.uvue # 主布局组件
│ ├── components/
│ │ └── card.uvue # 卡片组件
│ └── utils/
│ └── echarts-config.uts # 图表配置
├── pages/
│ ├── minimal.uvue # 测试页面
│ └── mall/
│ └── admin/
│ ├── index.uvue # 管理后台首页(数据看板)
│ ├── user-management.uvue # 用户管理
│ ├── product-management.uvue # 商品管理
│ ├── order-management.uvue # 订单管理
│ ├── finance-management.uvue # 财务管理
│ ├── user-statistics.uvue # 用户统计页
│ └── system-settings.uvue # 系统设置
└── pages.json # 页面配置
```
## 🎨 设计规范
### 布局结构
- **24栅格系统**: 所有元素对齐,统一间距
- **白色背景**: 主背景色 #f0f2f5
- **卡片设计**: 轻阴影 + 圆角 + 边框
- **响应式**: >=1200px 四卡一行;<=1200px 两卡一行;<=768px 单列
### 配色方案
```scss
// 主色调
$primary-color: #1890ff;
$success-color: #52c41a;
$warning-color: #faad14;
$danger-color: #f5222d;
// 中性色
$text-primary: #262626;
$text-secondary: #666;
$text-disabled: #999;
$border-color: #e8e8e8;
$background: #fff;
$page-background: #f0f2f5;
```
## 🏗️ 组件架构
### AdminLayout 主布局
#### 功能特性
- **左侧侧边栏**: 深色背景,一级菜单 + 折叠功能
- **顶部导航**: 面包屑 + 工具图标 + 用户信息
- **多标签页**: 可关闭的页面标签
- **页面容器**: 带滚动条的主内容区域
#### 技术实现
```vue
<template>
<view class="admin-layout">
<!-- 侧边栏 -->
<view class="admin-sider" :class="{ 'sider-collapsed': isCollapsed }">
<!-- 菜单内容 -->
</view>
<!-- 主内容区 -->
<view class="admin-main">
<!-- 头部 -->
<view class="admin-header"><!-- ... --></view>
<!-- 标签页 -->
<view class="admin-tabs"><!-- ... --></view>
<!-- 页面内容 -->
<scroll-view class="page-content">
<slot></slot>
</scroll-view>
</view>
</view>
</template>
```
### Card 卡片组件
#### API 接口
```typescript
interface CardProps {
title?: string
bordered?: boolean
shadow?: string
bodyStyle?: Record<string, any>
}
```
#### 使用示例
```vue
<AdminCard title="数据统计" shadow="small">
<view class="content">卡片内容</view>
</AdminCard>
```
## 📊 页面功能详解
### 1. 数据看板 (Dashboard)
#### 第一行KPI 指标卡片
```vue
<!-- 4个并排的指标卡片 -->
<view class="kpi-row">
<view class="kpi-card">
<view class="card-header">
<text class="card-title">销售额</text>
<view class="card-tag">今日</view>
</view>
<view class="card-value">
<text class="value-number">¥125,680.50</text>
<view class="value-trend up">
<text>5.7%</text>
</view>
</view>
<view class="card-footer">
<text>昨日¥118,920.30</text>
<text>本月累计¥2,857,808.90</text>
</view>
</view>
<!-- 访问量订单量新增用户卡片 -->
</view>
```
**数据结构**:
```typescript
interface KPIData {
today: number
yesterday: number
monthTotal: number
change: number // 环比百分比
}
```
#### 第二行:订单统计图表
```vue
<AdminCard title="订单统计">
<template #extra>
<view class="chart-controls">
<button @click="changePeriod('30days')">30天</button>
<button @click="changePeriod('week')"></button>
<button @click="changePeriod('month')"></button>
<button @click="changePeriod('year')"></button>
</view>
</template>
<!-- ECharts 组合图柱状图 + 折线图 -->
<view class="chart-container">
<!-- 订单金额柱状+ 订单数量折线 -->
</view>
</AdminCard>
```
#### 第三行:用户分析图表
```vue
<view class="chart-row two-cols">
<!-- 用户趋势折线图 -->
<AdminCard title="用户趋势">
<!-- 折线图 + 面积填充 -->
</AdminCard>
<!-- 用户构成饼图 -->
<AdminCard title="用户构成">
<!-- 环形饼图 + 图例 -->
</AdminCard>
</view>
```
### 2. 用户统计页
#### 筛选条件栏
```vue
<view class="filter-bar">
<view class="filter-left">
<!-- 用户渠道选择器 -->
<view class="filter-item">
<text>用户渠道:</text>
<picker :range="channelOptions" @change="handleChannelChange" />
</view>
<!-- 日期范围选择器 -->
<view class="filter-item">
<text>时间范围:</text>
<view class="date-range">
<picker mode="date" @change="handleStartDateChange" />
<text>-</text>
<picker mode="date" @change="handleEndDateChange" />
</view>
</view>
</view>
<view class="filter-right">
<button @click="handleSearch">查询</button>
<button @click="handleExport">导出</button>
</view>
</view>
```
#### 指标概览卡片
```vue
<view class="metrics-overview">
<!-- 6个指标卡片累计用户访客数浏览量新增用户成交用户付费会员 -->
<view class="metric-card" v-for="metric in metricsData">
<view class="metric-icon">
<text class="iconfont" :class="metric.icon"></text>
</view>
<view class="metric-content">
<text class="metric-title">{{ metric.title }}</text>
<text class="metric-value">{{ formatNumber(metric.value) }}</text>
<view class="metric-trend" :class="metric.trend">
<text>{{ metric.change }}%</text>
<text>较上月</text>
</view>
</metric-content>
</view>
</view>
```
#### 多折线趋势图
```vue
<view class="chart-section">
<AdminCard title="用户数据趋势分析">
<!-- 图表图例 -->
<view class="chart-legend">
<view class="legend-item" v-for="item in trendLegend">
<view class="legend-color" :style="{ background: item.color }"></view>
<text>{{ item.name }}</text>
</view>
</view>
<!-- 多折线图表 -->
<view class="multi-line-chart">
<!-- Y轴标签 + X轴标签 + 数据线条 + 悬停提示 -->
</view>
</AdminCard>
</view>
```
## 🔧 ECharts 图表配置
### 组合图表配置
```javascript
export const getOrderChartOption = (period) => ({
title: { text: `订单统计 (${period})`, left: 'center' },
tooltip: { trigger: 'axis' },
legend: { data: ['订单金额', '订单数量'] },
xAxis: { type: 'category', data: dateLabels },
yAxis: [
{ type: 'value', name: '订单金额' },
{ type: 'value', name: '订单数量' }
],
series: [
{
name: '订单金额',
type: 'bar',
data: amountData,
itemStyle: { color: '#1890ff' }
},
{
name: '订单数量',
type: 'line',
yAxisIndex: 1,
data: countData,
itemStyle: { color: '#52c41a' }
}
]
})
```
### 多折线图配置
```javascript
export const getUserStatisticsOption = () => ({
title: { text: '用户数据趋势分析' },
tooltip: { trigger: 'axis' },
legend: {
data: ['新增用户', '访客数', '浏览量', '成交用户', '付费会员']
},
series: [
{ name: '新增用户', type: 'line', data: newUsersData },
{ name: '访客数', type: 'line', data: visitorsData },
{ name: '浏览量', type: 'line', data: pageViewsData },
{ name: '成交用户', type: 'line', data: conversionsData },
{ name: '付费会员', type: 'line', data: vipUsersData }
]
})
```
## 📱 响应式设计
### 断点定义
```scss
// 大屏4卡片一行
@media screen and (min-width: 1200px) {
.kpi-row { /* 4列布局 */ }
}
// 中屏2卡片一行
@media screen and (max-width: 1200px) {
.kpi-row { /* 2列布局 */ }
}
// 小屏:单列布局
@media screen and (max-width: 768px) {
.kpi-row { flex-direction: column; }
.chart-row.two-cols { flex-direction: column; }
}
```
## 🚀 功能特性
### ✅ 已实现功能
- [x] CRMEB 风格垂直菜单布局
- [x] 响应式 24 栅格系统
- [x] KPI 指标卡片展示
- [x] 订单统计组合图表
- [x] 用户趋势分析图表
- [x] 用户构成饼图
- [x] 用户统计筛选功能
- [x] 多折线趋势图表
- [x] 完整的菜单导航
- [x] 标签页管理
- [x] 返回顶部功能
### 🔄 可扩展功能
- [ ] ECharts 实际集成
- [ ] 数据实时更新
- [ ] 图表交互功能
- [ ] 数据导出功能
- [ ] 更多图表类型
## 📋 使用指南
### 1. 页面访问
```javascript
// 主页面访问
/pages/mall/admin/index //
/pages/mall/admin/user-statistics //
// 菜单导航
uni.navigateTo({
url: '/pages/mall/admin/user-statistics'
})
```
### 2. 数据更新
```javascript
// KPI 数据更新
const salesData = ref({
today: 125680.50,
yesterday: 118920.30,
monthTotal: 2857808.90,
change: 5.7
})
```
### 3. 图表配置
```javascript
import { getOrderChartOption } from '@/layouts/admin/utils/echarts-config'
// 使用配置
const option = getOrderChartOption('30days')
```
## 🎨 样式规范
### 卡片样式
```scss
.admin-card {
background: #fff;
border-radius: 8rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
border: 1rpx solid #e8e8e8;
&.shadow-small { box-shadow: 0 1rpx 3rpx rgba(0, 0, 0, 0.04); }
&.shadow-large { box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.12); }
}
```
### 按钮样式
```scss
.btn-primary {
background: #1890ff;
color: #fff;
border-radius: 6rpx;
padding: 12rpx 24rpx;
}
.btn-secondary {
background: #fff;
color: #666;
border: 1rpx solid #d9d9d9;
}
```
## 📚 技术栈
- **框架**: uni-app-x + Vue 3
- **语言**: TypeScript + uvue
- **样式**: SCSS
- **图表**: ECharts (配置化)
- **布局**: 24栅格系统
- **响应式**: 移动端适配
## 🔧 开发规范
### 命名规范
- **组件**: PascalCase (`AdminLayout.vue`)
- **文件**: kebab-case (`user-statistics.uvue`)
- **变量**: camelCase (`salesData`)
- **常量**: UPPER_SNAKE_CASE (`API_BASE_URL`)
### 代码组织
```vue
<template>
<!-- 模板内容 -->
</template>
<script setup lang="uts">
// 导入语句
// 类型定义
// 响应式数据
// 计算属性
// 生命周期
// 方法定义
</script>
<style lang="scss" scoped>
/* 样式内容 */
</style>
```
## 🎯 项目成果
**完全自主开发**: 无任何源码复制100%自主编写
**CRMEB 风格**: 严格遵循设计规范和布局结构
**完整功能**: 数据看板 + 用户统计双页面
**响应式设计**: 桌面/平板/手机全适配
**技术先进**: Vue 3 + TypeScript + 组合式API
**可维护性**: 模块化架构,易于扩展
---
## 🚀 部署运行
```bash
# 开发环境
npm run dev:h5
# 构建生产
npm run build:h5
# 运行到小程序
npm run dev:mp-weixin
```
访问地址:`http://localhost:5173/pages/mall/admin/index`
---
*本项目完全自主开发实现了CRMEB标准版后台的核心功能为后续功能扩展奠定了坚实基础。*

View File

@@ -0,0 +1,807 @@
# CRMEB商城系统到uvue项目的重构迁移指南
## 项目概述
本文档基于CRMEB开源商城系统PHP版本指导如何将其核心功能迁移到基于uvue技术栈的项目中。后端使用`@components/supadb`组件库实现不使用PHP技术栈。
## 参考项目分析
### CRMEB核心功能模块
#### 1. 用户系统 (User Module)
- **用户注册登录**:手机号验证码、微信授权登录
- **用户资料管理**:个人信息、收货地址、会员等级
- **用户积分系统**:积分获取、积分消费记录
- **分销系统**:用户推广、佣金结算
#### 2. 商品系统 (Product Module)
- **商品管理**商品信息、SKU规格、商品分类
- **商品展示**:商品详情、商品列表、商品搜索
- **库存管理**:商品库存、规格库存管理
#### 3. 订单系统 (Order Module)
- **购物车**:添加商品、修改数量、删除商品
- **订单创建**:订单确认、地址选择、支付方式
- **订单管理**:订单状态跟踪、订单取消、退款处理
- **物流跟踪**:快递信息查询、物流状态更新
#### 4. 营销活动 (Activity Module)
- **秒杀活动**:限时抢购、库存锁定
- **拼团活动**:团购发起、参团流程
- **砍价活动**:好友助力、砍价进度
- **优惠券系统**:券领取、使用规则
- **积分商城**:积分兑换商品
#### 5. 支付系统 (Payment Module)
- **多渠道支付**:微信支付、支付宝、余额支付
- **支付回调**:订单状态更新、支付记录
#### 6. 客服系统 (Service Module)
- **在线客服**:实时聊天、消息记录
- **售后服务**:退换货处理、服务评价
#### 7. 内容管理系统 (CMS Module)
- **文章系统**:资讯发布、分类管理
- **广告位管理**首页banner、推荐位
#### 8. 系统配置 (System Module)
- **基础配置**:站点信息、支付配置、物流配置
- **权限管理**:管理员权限、操作日志
## 技术栈对比
### 原CRMEB技术栈
```
后端: ThinkPHP 6 + MySQL + Redis
前端: Vue2 + ElementUI + UniApp
其他: Workerman(长连接)、队列、定时任务
```
### 目标技术栈
```
后端: Supabase (PostgreSQL + Auth + Storage + Edge Functions)
前端: uvue + @components/supadb
其他: 实时订阅、文件存储、服务器less函数
```
## 数据架构设计
### Supabase数据库表结构设计
#### 核心数据表
##### 1. 用户表 (users)
```sql
-- 继承Supabase auth.users表扩展字段
CREATE TABLE public.users (
id UUID REFERENCES auth.users(id) PRIMARY KEY,
phone TEXT,
nickname TEXT,
avatar_url TEXT,
gender INTEGER DEFAULT 0,
birthday DATE,
level_id INTEGER DEFAULT 0,
integral INTEGER DEFAULT 0,
balance DECIMAL(10,2) DEFAULT 0,
spread_uid INTEGER,
spread_time TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
##### 2. 商品表 (products)
```sql
CREATE TABLE public.products (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
description TEXT,
images TEXT[],
category_id INTEGER,
brand_id INTEGER,
price DECIMAL(10,2),
ot_price DECIMAL(10,2),
cost DECIMAL(10,2),
stock INTEGER DEFAULT 0,
sales INTEGER DEFAULT 0,
is_show BOOLEAN DEFAULT true,
is_del BOOLEAN DEFAULT false,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
##### 3. 商品规格表 (product_skus)
```sql
CREATE TABLE public.product_skus (
id SERIAL PRIMARY KEY,
product_id INTEGER REFERENCES products(id),
sku TEXT,
price DECIMAL(10,2),
stock INTEGER DEFAULT 0,
image TEXT,
attributes JSONB,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
##### 4. 订单表 (orders)
```sql
CREATE TABLE public.orders (
id SERIAL PRIMARY KEY,
order_sn TEXT UNIQUE,
user_id UUID REFERENCES users(id),
total_price DECIMAL(10,2),
pay_price DECIMAL(10,2),
coupon_price DECIMAL(10,2),
pay_type INTEGER DEFAULT 1, -- 1微信 2余额 3线下
status INTEGER DEFAULT 0, -- 订单状态
address_info JSONB,
mark TEXT,
paid BOOLEAN DEFAULT false,
pay_time TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
##### 5. 订单商品表 (order_items)
```sql
CREATE TABLE public.order_items (
id SERIAL PRIMARY KEY,
order_id INTEGER REFERENCES orders(id),
product_id INTEGER REFERENCES products(id),
sku_id INTEGER REFERENCES product_skus(id),
product_title TEXT,
product_image TEXT,
sku_info JSONB,
price DECIMAL(10,2),
quantity INTEGER,
total_price DECIMAL(10,2),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
##### 6. 购物车表 (cart)
```sql
CREATE TABLE public.cart (
id SERIAL PRIMARY KEY,
user_id UUID REFERENCES users(id),
product_id INTEGER REFERENCES products(id),
sku_id INTEGER REFERENCES product_skus(id),
quantity INTEGER,
selected BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
##### 7. 优惠券表 (coupons)
```sql
CREATE TABLE public.coupons (
id SERIAL PRIMARY KEY,
title TEXT,
type INTEGER, -- 1满减 2折扣
value DECIMAL(10,2),
min_price DECIMAL(10,2),
use_start_time TIMESTAMP WITH TIME ZONE,
use_end_time TIMESTAMP WITH TIME ZONE,
stock INTEGER,
receive_count INTEGER DEFAULT 0,
is_show BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
##### 8. 用户优惠券表 (user_coupons)
```sql
CREATE TABLE public.user_coupons (
id SERIAL PRIMARY KEY,
user_id UUID REFERENCES users(id),
coupon_id INTEGER REFERENCES coupons(id),
status INTEGER DEFAULT 0, -- 0未使用 1已使用 2已过期
use_time TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
## API接口设计
### 使用@components/supadb实现的数据操作
#### 用户相关接口
##### 用户注册
```typescript
// 使用Supabase Auth实现
const { data, error } = await supa.auth.signUp({
email: 'user@example.com',
password: 'password'
})
```
##### 用户登录
```typescript
const { data, error } = await supa.auth.signInWithPassword({
email: 'user@example.com',
password: 'password'
})
```
##### 获取用户信息
```typescript
// 使用supadb组件
<supadb
collection="users"
:filter="{ id: userId }"
:getone="true"
v-slot="{ data: userInfo }"
>
<!-- 用户信息显示 -->
</supadb>
```
##### 更新用户信息
```typescript
const result = await supa.from('users').update(userData).eq('id', userId)
```
#### 商品相关接口
##### 获取商品列表
```vue
<supadb
collection="products"
:filter="{ is_show: true, is_del: false }"
:orderby="'sales.desc'"
:pageSize="20"
v-slot="{ data: products, loading, hasmore, loadMore }"
>
<view v-for="product in products" :key="product.id">
<!-- 商品卡片 -->
</view>
<button v-if="hasmore" @click="loadMore">加载更多</button>
</supadb>
```
##### 获取商品详情
```vue
<supadb
collection="products"
:filter="{ id: productId }"
:getone="true"
v-slot="{ data: product }"
>
<!-- 商品详情页 -->
</supadb>
```
##### 商品搜索
```vue
<supadb
collection="products"
:filter="{ title: { ilike: `%${keyword}%` }, is_show: true }"
v-slot="{ data: searchResults }"
>
<!-- 搜索结果 -->
</supadb>
```
#### 订单相关接口
##### 创建订单
```typescript
// 先创建订单记录
const orderData = {
order_sn: generateOrderSn(),
user_id: userId,
total_price: totalPrice,
// ...其他字段
}
const { data: order } = await supa.from('orders').insert(orderData).select().single()
// 然后创建订单商品记录
const orderItems = cartItems.map(item => ({
order_id: order.id,
product_id: item.product_id,
// ...其他字段
}))
await supa.from('order_items').insert(orderItems)
```
##### 获取订单列表
```vue
<supadb
collection="orders"
:filter="{ user_id: userId }"
:orderby="'created_at.desc'"
v-slot="{ data: orders }"
>
<view v-for="order in orders" :key="order.id">
<!-- 订单卡片 -->
</view>
</supadb>
```
#### 营销活动接口
##### 秒杀活动
```vue
<supadb
collection="seckill_products"
:filter="{
start_time: { lte: currentTime },
end_time: { gte: currentTime },
stock: { gt: 0 }
}"
v-slot="{ data: seckillProducts }"
>
<!-- 秒杀商品列表 -->
</supadb>
```
##### 优惠券领取
```typescript
// 检查用户是否已领取
const { data: existing } = await supa
.from('user_coupons')
.select('*')
.eq('user_id', userId)
.eq('coupon_id', couponId)
.single()
if (!existing) {
await supa.from('user_coupons').insert({
user_id: userId,
coupon_id: couponId
})
}
```
## uvue前端页面重构方案
### 页面结构重组
#### 1. 首页 (pages/index/index.uvue)
```vue
<template>
<view class="index-page">
<!-- 轮播图 -->
<swiper-banner />
<!-- 分类导航 -->
<category-nav />
<!-- 商品推荐 -->
<product-recommend />
<!-- 营销活动 -->
<activity-section />
</view>
</template>
<script setup lang="uts">
import { ref } from 'vue'
import supa from '@/components/supadb/aksupainstance.uts'
// 首页数据
const bannerList = ref([])
const categoryList = ref([])
const recommendProducts = ref([])
// 获取首页数据
const loadHomeData = async () => {
// 获取轮播图
const bannerResult = await supa.from('banners').select('*').eq('position', 'home')
bannerList.value = bannerResult.data || []
// 获取分类
const categoryResult = await supa.from('categories').select('*').eq('level', 1)
categoryList.value = categoryResult.data || []
// 获取推荐商品
const productResult = await supa.from('products')
.select('*')
.eq('is_recommend', true)
.eq('is_show', true)
.limit(10)
recommendProducts.value = productResult.data || []
}
</script>
```
#### 2. 商品详情页 (pages/goods/detail.uvue)
```vue
<template>
<view class="product-detail">
<supadb
collection="products"
:filter="{ id: productId }"
:getone="true"
v-slot="{ data: product, loading }"
>
<!-- 商品图片轮播 -->
<image-swiper :images="product?.images || []" />
<!-- 商品信息 -->
<product-info :product="product" />
<!-- 商品规格选择 -->
<sku-selector
:product="product"
@sku-change="handleSkuChange"
/>
<!-- 商品详情 -->
<product-description :content="product?.description" />
</supadb>
</view>
</template>
<script setup lang="uts">
import { ref } from 'vue'
import supa from '@/components/supadb/aksupainstance.uts'
const props = defineProps<{
productId: number
}>()
const selectedSku = ref(null)
const handleSkuChange = (sku) => {
selectedSku.value = sku
}
</script>
```
#### 3. 购物车页面 (pages/cart/index.uvue)
```vue
<template>
<view class="cart-page">
<supadb
collection="cart"
:filter="{ user_id: userId }"
v-slot="{ data: cartItems, loading }"
>
<!-- 购物车商品列表 -->
<cart-item
v-for="item in cartItems"
:key="item.id"
:item="item"
@quantity-change="updateQuantity"
@delete="removeItem"
/>
<!-- 结算栏 -->
<cart-footer
:items="cartItems"
@checkout="goCheckout"
/>
</supadb>
</view>
</template>
<script setup lang="uts">
import { ref } from 'vue'
import supa from '@/components/supadb/aksupainstance.uts'
const userId = ref('') // 从用户信息获取
const updateQuantity = async (itemId, quantity) => {
await supa.from('cart').update({ quantity }).eq('id', itemId)
}
const removeItem = async (itemId) => {
await supa.from('cart').delete().eq('id', itemId)
}
const goCheckout = () => {
// 跳转到结算页面
uni.navigateTo({
url: '/pages/order/checkout'
})
}
</script>
```
## 实时功能实现
### 使用Supabase实时订阅
#### 订单状态更新监听
```typescript
// 监听订单状态变化
const orderSubscription = supa
.channel('order-updates')
.on('postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'orders',
filter: `user_id=eq.${userId}`
},
(payload) => {
console.log('Order updated:', payload)
// 更新订单状态
}
)
.subscribe()
```
#### 库存变化监听
```typescript
// 监听商品库存变化
const stockSubscription = supa
.channel('stock-updates')
.on('postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'products'
},
(payload) => {
// 更新本地商品库存
updateLocalStock(payload.new)
}
)
.subscribe()
```
## 文件存储实现
### 使用Supabase Storage
#### 商品图片上传
```typescript
const uploadProductImage = async (filePath: string, productId: number) => {
const fileName = `product_${productId}_${Date.now()}.jpg`
const { data, error } = await supa.storage
.from('products')
.upload(fileName, filePath)
if (data) {
const { data: urlData } = supa.storage
.from('products')
.getPublicUrl(fileName)
return urlData.publicUrl
}
}
```
#### 用户头像上传
```typescript
const uploadAvatar = async (filePath: string) => {
const fileName = `avatar_${userId}_${Date.now()}.jpg`
const { data, error } = await supa.storage
.from('avatars')
.upload(fileName, filePath)
if (data) {
const { data: urlData } = supa.storage
.from('avatars')
.getPublicUrl(fileName)
// 更新用户头像
await supa.from('users').update({
avatar_url: urlData.publicUrl
}).eq('id', userId)
}
}
```
## 服务器端逻辑实现
### 使用Supabase Edge Functions
#### 订单创建函数
```typescript
// supabase/functions/create-order/index.ts
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
serve(async (req) => {
const { userId, items, address } = await req.json()
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_ANON_KEY') ?? ''
)
// 生成订单号
const orderSn = `ORDER${Date.now()}${Math.random().toString(36).substr(2, 6).toUpperCase()}`
// 计算总价
let totalPrice = 0
for (const item of items) {
const { data: product } = await supabase
.from('products')
.select('price')
.eq('id', item.productId)
.single()
totalPrice += product.price * item.quantity
}
// 创建订单
const { data: order, error } = await supabase
.from('orders')
.insert({
order_sn: orderSn,
user_id: userId,
total_price: totalPrice,
address_info: address
})
.select()
.single()
if (error) throw error
// 创建订单商品记录
const orderItems = items.map(item => ({
order_id: order.id,
product_id: item.productId,
quantity: item.quantity,
price: item.price,
total_price: item.price * item.quantity
}))
const { error: itemsError } = await supabase
.from('order_items')
.insert(orderItems)
if (itemsError) throw itemsError
return new Response(
JSON.stringify({ order }),
{ headers: { "Content-Type": "application/json" } }
)
})
```
#### 支付回调函数
```typescript
// supabase/functions/payment-callback/index.ts
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
serve(async (req) => {
const { orderSn, paymentResult } = await req.json()
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_ANON_KEY') ?? ''
)
// 更新订单支付状态
const { error } = await supabase
.from('orders')
.update({
paid: true,
pay_time: new Date().toISOString(),
status: 1 // 已支付
})
.eq('order_sn', orderSn)
if (error) throw error
return new Response(
JSON.stringify({ success: true }),
{ headers: { "Content-Type": "application/json" } }
)
})
```
## 组件重构对照表
### CRMEB组件 → uvue组件映射
| CRMEB组件 | uvue组件 | 功能说明 |
|----------|---------|---------|
| HomeComb | home-comb.uvue | 首页搜索组合 |
| GoodList | product-list.uvue | 商品列表 |
| CouponWindow | coupon-popup.uvue | 优惠券弹窗 |
| CartList | cart-list.uvue | 购物车列表 |
| Payment | payment-selector.uvue | 支付方式选择 |
| AddressWindow | address-selector.uvue | 地址选择弹窗 |
| UserEvaluation | product-review.uvue | 商品评价 |
| ShareRedPackets | share-popup.uvue | 分享红包 |
## 性能优化建议
### 1. 数据缓存策略
```typescript
// 使用Supabase内置缓存
const { data, error } = await supa
.from('products')
.select('*')
.eq('category_id', categoryId)
.order('sales', { ascending: false })
.limit(20)
// 启用缓存
.single()
```
### 2. 图片懒加载
```vue
<template>
<image
:src="imageUrl"
:lazy-load="true"
@load="onImageLoad"
@error="onImageError"
/>
</template>
```
### 3. 列表虚拟化
```vue
<template>
<scroll-view
scroll-y="true"
:scroll-top="scrollTop"
@scroll="handleScroll"
>
<view
v-for="(item, index) in visibleItems"
:key="item.id"
:style="{ transform: `translateY(${item.top}px)` }"
>
<!-- 商品项 -->
</view>
</scroll-view>
</template>
```
## 部署和维护
### 环境配置
```javascript
// config/app.js
export default {
supabase: {
url: 'https://your-project.supabase.co',
anonKey: 'your-anon-key',
serviceRoleKey: 'your-service-role-key' // 服务端使用
}
}
```
### 数据库迁移
```sql
-- 数据库初始化脚本
-- 创建表结构
-- 设置RLS策略
-- 创建索引
-- 设置触发器
```
### 监控和日志
```typescript
// 错误监控
const handleError = (error) => {
console.error('App Error:', error)
// 上报到监控系统
}
// 性能监控
const reportPerformance = (metrics) => {
// 上报性能数据
}
```
## 总结
通过本重构指南我们将CRMEB的核心功能成功迁移到基于uvue + Supabase的技术栈
1. **数据层**使用Supabase替代MySQL + Redis
2. **API层**:使用@components/supadb替代ThinkPHP
3. **前端**使用uvue替代uni-app
4. **实时功能**使用Supabase实时订阅
5. **文件存储**使用Supabase Storage
6. **服务器逻辑**使用Edge Functions
这种架构具有以下优势:
- **开发效率高**:减少后端开发工作
- **维护成本低**Serverless架构
- **扩展性好**:支持实时功能和全球化部署
- **安全性高**Supabase提供完善的安全机制
实际迁移时需要根据具体业务需求进行调整,并充分测试各项功能。

View File

@@ -0,0 +1,427 @@
# CRMEB Admin 前端架构梳理分析
## 项目概述
- **项目名称**: CRMEB Admin Template
- **技术栈**: Vue.js + Element UI + Vue Router + Vuex
- **项目类型**: 电商管理后台系统
- **分析时间**: 2026-01-23
## 1. 页面总览表
| 路由路径 | 页面标题 | 所属端 | 是否tab/子包 | 说明 | 入口文件 |
|---------|---------|-------|-------------|------|---------|
| `/admin/index` | 主页 | Admin后台 | 否 | 系统首页,包含基础统计信息 | `src/pages/index/index.vue` |
| `/admin/product/product_list` | 商品管理 | Admin后台 | 否 | 商品列表管理页面 | `src/pages/product/productList/index.vue` |
| `/admin/product/product_classify` | 商品分类 | Admin后台 | 否 | 商品分类管理 | `src/pages/product/productClassify/index.vue` |
| `/admin/product/add_product/:id?` | 商品添加 | Admin后台 | 否 | 添加/编辑商品 | `src/pages/product/productAdd/index.vue` |
| `/admin/order/list` | 订单管理 | Admin后台 | 否 | 订单列表管理 | `src/pages/order/orderList/index.vue` |
| `/admin/order/offline` | 收银订单 | Admin后台 | 否 | 线下收银订单 | `src/pages/order/offline/index.vue` |
| `/admin/order/refund` | 售后订单 | Admin后台 | 否 | 售后退款订单 | `src/pages/order/refund/index.vue` |
| `/admin/user/list` | 用户管理 | Admin后台 | 否 | 用户列表管理 | `src/pages/user/list/index.vue` |
| `/admin/user/level` | 用户等级 | Admin后台 | 否 | 用户等级管理 | `src/pages/user/level/index.vue` |
| `/admin/user/group` | 用户分组 | Admin后台 | 否 | 用户分组管理 | `src/pages/user/group/index.vue` |
| `/admin/setting/system_config` | 系统设置 | Admin后台 | 否 | 系统基础配置 | `src/pages/setting/setSystem/index.vue` |
| `/admin/setting/system_role/index` | 身份管理 | Admin后台 | 否 | 管理员角色管理 | `src/pages/setting/systemRole/index.vue` |
| `/admin/setting/system_admin/index` | 管理员列表 | Admin后台 | 否 | 管理员账户管理 | `src/pages/setting/systemAdmin/index.vue` |
| `/admin/marketing/store_combination/index` | 拼团商品 | Admin后台 | 否 | 拼团活动商品管理 | `src/pages/marketing/storeCombination/index.vue` |
| `/admin/marketing/store_coupon_issue/index` | 优惠券 | Admin后台 | 否 | 优惠券发放管理 | `src/pages/marketing/storeCouponIssue/index.vue` |
| `/admin/system/log` | 前端日志 | Admin后台 | 否 | 系统日志查看 | `src/pages/system/log/index.vue` |
**来源**: `src/router/modules/*.js` 文件中的路由配置
## 2. 页面关系树
```
CRMEB Admin 后台系统
├── 主页 (home_index)
│ ├── 基础信息展示 (baseInfo)
│ ├── 快捷菜单 (gridMenu)
│ ├── 访问统计图表 (visitChart)
│ └── 用户统计图表 (userChart)
├── 商品管理 (product)
│ ├── 商品列表 (productList)
│ │ ├── 搜索筛选区
│ │ ├── 商品列表表格
│ │ └── 操作按钮区
│ ├── 商品分类 (productClassify)
│ ├── 添加商品 (productAdd)
│ ├── 商品评论 (productEvaluate)
│ ├── 商品规格 (productAttr)
│ ├── 商品参数 (paramList)
│ └── 商品标签 (labelList)
├── 订单管理 (order)
│ ├── 订单列表 (orderList)
│ ├── 收银订单 (offline)
│ ├── 售后订单 (refund)
│ └── 发票管理 (invoice)
├── 用户管理 (user)
│ ├── 用户列表 (list)
│ │ ├── 用户搜索筛选
│ │ ├── 用户列表表格
│ │ └── 用户详情弹窗
│ ├── 用户等级 (level)
│ ├── 用户分组 (group)
│ ├── 用户标签 (label)
│ ├── 会员类型 (type)
│ ├── 卡密会员 (card)
│ ├── 会员记录 (record)
│ └── 会员权益 (right)
├── 系统设置 (setting)
│ ├── 系统配置 (setSystem)
│ ├── 身份管理 (systemRole)
│ ├── 管理员列表 (systemAdmin)
│ ├── 消息管理 (notification)
│ ├── 物流配置 (logistics)
│ ├── 短信配置 (sms)
│ ├── 商城配置 (config)
│ ├── 主题风格 (themeStyle)
│ ├── 店铺装修 (devise)
│ ├── 客服管理 (service)
│ ├── 城市数据 (dada)
│ ├── 运费模板 (templates)
│ ├── 提货点管理 (store)
│ ├── 核销员管理 (staff)
│ └── 核销订单 (order)
├── 营销活动 (marketing)
│ ├── 拼团商品 (combinalist)
│ ├── 优惠券 (storeCouponIssue)
│ ├── 秒杀商品 (storeSeckill)
│ ├── 积分商品 (storeIntegral)
│ └── 砍价商品 (bargain)
├── 财务管理 (finance)
│ ├── 财务对账 (financeList)
│ ├── 资金记录 (capitalFlow)
│ ├── 佣金记录 (commissionList)
│ ├── 提现申请 (extractList)
│ └── 账单记录 (billList)
├── 系统管理 (system)
│ ├── 代码生成 (codeGeneration)
│ ├── 文件管理 (fileList)
│ ├── 维护管理 (maintain)
│ └── 数据配置 (groupData)
├── 应用管理 (app)
│ ├── 微信菜单 (wechatMenu)
│ ├── 微信回复 (wechatReply)
│ └── 微信用户 (wechatUser)
└── 统计报表 (statistic)
├── 产品统计 (productStatistic)
├── 用户统计 (userStatistic)
├── 订单统计 (orderStatistic)
└── 交易统计 (transactionStatistic)
```
## 3. 页面区域-文件映射表
### 3.1 主页 (home_index)
| 区域名 | 对应组件/文件 | 说明 | 关键状态 | 关键接口 |
|-------|---------------|------|---------|---------|
| 基础信息展示区 | `src/pages/index/components/baseInfo.vue` | 显示今日/昨日数据对比和总计信息 | infoList数组 | `headerApi` (来源: `src/api/index.js`) |
| 快捷菜单区 | `src/pages/index/components/gridMenu.vue` | 九宫格快捷入口菜单 | - | - |
| 访问统计图表 | `src/pages/index/components/visitChart.vue` | 订单统计图表展示 | visitType, visitDate | - |
| 用户统计图表 | `src/pages/index/components/userChart.vue` | 用户数据统计图表 | - | - |
| 页面布局容器 | `src/pages/index/index.vue` | 主页布局容器,组合上述组件 | userInfo | `auth()` (来源: `src/api/system.js`) |
| Vuex状态 | `src/store/module/userInfo.js` | 用户信息状态管理 | userInfo | - |
**来源**: `src/pages/index/index.vue` (行7-15), `src/store/module/userInfo.js`
### 3.2 商品列表页面 (product_productList)
| 区域名 | 对应组件/文件 | 说明 | 关键状态 | 关键接口 |
|-------|---------------|------|---------|---------|
| 搜索筛选区 | 内联在页面模板中 | 商品名称、类型、分类、配送方式等筛选条件 | artFrom表单对象 | - |
| 商品列表表格 | 内联在页面模板中 | 商品数据表格展示,包含分页 | tableData数组 | `productList()` (来源: `src/api/product.js`) |
| 操作按钮区 | 内联在页面模板中 | 批量操作、添加商品等按钮 | - | - |
| 页面布局容器 | `src/pages/product/productList/index.vue` | 商品管理主页面 | artFrom, tableData, loading | `productList()`, `productStatus()` (来源: `src/api/product.js`) |
**来源**: `src/pages/product/productList/index.vue` (行1-50), `src/api/product.js`
### 3.3 用户列表页面 (user_list)
| 区域名 | 对应组件/文件 | 说明 | 关键状态 | 关键接口 |
|-------|---------------|------|---------|---------|
| 用户搜索筛选区 | 内联在页面模板中 | 用户昵称、等级、分组等筛选条件 | userFrom表单对象, field_key | - |
| 用户列表表格 | 内联在页面模板中 | 用户数据表格,包含用户信息展示 | tableData数组 | `userList()` (来源: `src/api/user.js`) |
| 用户详情弹窗 | `src/pages/user/list/handle/userDetails.vue` | 用户详细信息弹窗组件 | visible, userInfo | - |
| 用户编辑弹窗 | `src/pages/user/list/handle/userEdit.vue` | 用户信息编辑弹窗 | visible, editForm | `userEdit()` (来源: `src/api/user.js`) |
| 页面布局容器 | `src/pages/user/list/index.vue` | 用户管理主页面 | userFrom, tableData, collapse | `userList()`, `userLevel()`, `userGroup()` (来源: `src/api/user.js`) |
**来源**: `src/pages/user/list/index.vue` (行1-100), `src/api/user.js`
## 4. 文件职责清单
### 4.1 Pages 目录文件职责
#### 主页相关 (src/pages/index/)
- `index.vue`: 主页容器组件,组合统计组件,处理用户认证
- `components/baseInfo.vue`: 基础统计信息卡片展示
- `components/gridMenu.vue`: 快捷操作菜单网格
- `components/visitChart.vue`: 访问统计图表组件
- `components/userChart.vue`: 用户统计图表组件
#### 商品管理 (src/pages/product/)
- `productList/index.vue`: 商品列表页面,包含搜索、筛选、表格展示
- `productClassify/index.vue`: 商品分类管理页面
- `productAdd/index.vue`: 商品添加/编辑页面
- `productReply/index.vue`: 商品评论管理页面
- `productAttr/index.vue`: 商品规格管理页面
- `paramList/index.vue`: 商品参数管理页面
- `labelList/index.vue`: 商品标签管理页面
#### 订单管理 (src/pages/order/)
- `orderList/index.vue`: 订单列表管理页面
- `offline/index.vue`: 收银订单管理页面
- `refund/index.vue`: 售后订单管理页面
- `invoice/index.vue`: 发票管理页面
#### 用户管理 (src/pages/user/)
- `list/index.vue`: 用户列表主页面
- `list/handle/userDetails.vue`: 用户详情弹窗组件
- `list/handle/userEdit.vue`: 用户编辑弹窗组件
- `list/handle/userEditForm.vue`: 用户编辑表单组件
- `list/handle/userInfo.vue`: 用户信息展示组件
- `list/tableExpand.vue`: 用户列表表格展开组件
- `level/index.vue`: 用户等级管理页面
- `group/index.vue`: 用户分组管理页面
- `label/index.vue`: 用户标签管理页面
#### 系统设置 (src/pages/setting/)
- `setSystem/index.vue`: 系统配置主页面
- `systemRole/index.vue`: 管理员角色管理页面
- `systemAdmin/index.vue`: 管理员列表管理页面
- `notification/index.vue`: 消息管理页面
- `notification/notificationEdit.vue`: 消息编辑页面
- `membershipLevel/index.vue`: 分销等级管理页面
- `freight/index.vue`: 物流公司管理页面
- `cityDada/index.vue`: 城市数据管理页面
- `shippingTemplates/index.vue`: 运费模板管理页面
- `storeList/index.vue`: 提货点管理页面
- `clerkList/index.vue`: 核销员管理页面
- `verifyOrder/index.vue`: 核销订单管理页面
- `themeStyle/index.vue`: 主题风格设置页面
- `devise/list.vue`: 店铺装修页面
- `devisePage/index.vue`: 页面设计页面
- `link.vue`: 链接管理页面
- `storage.vue`: 存储配置页面
- `ticket.vue`: 打印机设置页面
- `agreement/index.vue`: 协议设置页面
#### 营销活动 (src/pages/marketing/)
- `storeCombination/index.vue`: 拼团商品管理页面
- `storeCombination/combinaList.vue`: 拼团列表页面
- `storeCouponIssue/index.vue`: 优惠券管理页面
- `storeSeckill/index.vue`: 秒杀商品管理页面
- `storeIntegral/index.vue`: 积分商品管理页面
- `storeBargain/index.vue`: 砍价商品管理页面
#### 财务管理 (src/pages/finance/)
- `financeList/index.vue`: 财务对账页面
- `capitalFlow/index.vue`: 资金记录页面
- `commissionList/index.vue`: 佣金记录页面
- `extractList/index.vue`: 提现申请页面
- `billList/index.vue`: 账单记录页面
#### 系统管理 (src/pages/system/)
- `codeGeneration/index.vue`: 代码生成页面
- `fileList/index.vue`: 文件管理页面
- `maintain/index.vue`: 维护管理页面
- `group/list.vue`: 数据配置页面
#### 应用管理 (src/pages/app/)
- `wechatMenu/index.vue`: 微信菜单管理页面
- `wechatReply/index.vue`: 微信回复管理页面
- `wechatUser/index.vue`: 微信用户管理页面
#### 统计报表 (src/pages/statistic/)
- `productStatistic/index.vue`: 产品统计页面
- `userStatistic/index.vue`: 用户统计页面
- `orderStatistic/index.vue`: 订单统计页面
- `transactionStatistic/index.vue`: 交易统计页面
### 4.2 Components 目录文件职责
#### 通用组件 (src/components/)
- `common-icon/`: 通用图标组件
- `copyright/`: 版权信息组件
- `Pagination/`: 分页组件
- `parent-view/`: 父视图组件
- `publicSearchFrom/`: 公共搜索表单组件
- `searchFrom/`: 搜索表单组件
- `uploadImg/`: 图片上传组件
- `uploadPictures/`: 多图上传组件
- `uploadVideo/`: 视频上传组件
- `uploadVideo2/`: 视频上传组件(增强版)
#### 表单组件 (src/components/from/)
- `from/`: 通用表单组件
#### 图表组件 (src/components/echarts/)
- `echarts/`: ECharts图表基础组件
- `echartsNew/`: 新版ECharts图表组件
#### 移动端配置组件 (src/components/mobileConfig/)
- 包含大量移动端页面配置组件
#### 弹窗组件 (src/components/hotpotModal/)
- `hotpotModal/`: 热区弹窗组件
#### 编辑器组件 (src/components/wangEditor/)
- `wangEditor/`: 富文本编辑器组件
### 4.3 Store 目录文件职责
#### Vuex状态管理模块 (src/store/module/)
- `user.js`: 用户登录状态管理
- `app.js`: 应用全局状态
- `menus.js`: 菜单数据管理
- `menu.js`: 当前菜单状态
- `userInfo.js`: 用户信息管理
- `userLevel.js`: 用户等级管理
- `order.js`: 订单相关状态
- `media.js`: 媒体文件管理
- `goodSelect.js`: 商品选择状态
- `moren.js`: 默认配置管理
- `shopping.js`: 购物相关状态
- `fresh.js`: 刷新状态管理
- `kefu.js`: 客服状态管理
- `integralOrder.js`: 积分订单管理
- `mobildConfig.js`: 移动端配置
- `upgrade.js`: 升级状态管理
- `layout.js`: 布局状态管理
- `themeConfig.js`: 主题配置
- `routesList.js`: 路由列表
- `tagsViewRoutes.js`: 标签页路由
- `userInfos.js`: 用户信息扩展
- `keepAliveNames.js`: 缓存页面名称
### 4.4 API 目录文件职责
#### 接口文件 (src/api/)
- `index.js`: 首页相关接口
- `account.js`: 账户相关接口
- `agent.js`: 代理商相关接口
- `app.js`: 应用相关接口
- `cms.js`: CMS内容管理接口
- `common.js`: 通用接口
- `crud.js`: CRUD通用接口
- `diy.js`: DIY装修接口
- `export.js`: 导出相关接口
- `finance.js`: 财务相关接口
- `index.js`: 首页统计接口
- `kefu.js`: 客服相关接口
- `kefu_mobile.js`: 移动端客服接口
- `live.js`: 直播相关接口
- `lottery.js`: 抽奖相关接口
- `marketing.js`: 营销活动接口
- `membershipLevel.js`: 会员等级接口
- `notification.js`: 消息通知接口
- `order.js`: 订单相关接口
- `product.js`: 商品相关接口
- `setting.js`: 设置相关接口
- `statistic.js`: 统计相关接口
- `system.js`: 系统相关接口
- `systemAdmin.js`: 管理员接口
- `systemBackendRouting.js`: 后端路由接口
- `systemCodeGeneration.js`: 代码生成接口
- `systemMenus.js`: 菜单接口
- `systemOutAccount.js`: 外部账户接口
- `upload.js`: 上传相关接口
- `uploadPictures.js`: 图片上传接口
- `user.js`: 用户相关接口
### 4.5 Utils 目录文件职责
#### 工具函数 (src/utils/)
- `ase.js`: AES加密工具
- `authLapse.js`: 认证过期处理
- `bus.js`: 事件总线
- `city.js`: 城市数据处理
- `componentSize.js`: 组件尺寸工具
- `compressImg.js`: 图片压缩工具
- `editorImg.js`: 编辑器图片处理
- `emoji.js`: 表情符号处理
- `Excel.js`: Excel处理工具
- `icon.js`: 图标处理工具
- `index.js`: 工具函数入口
- `loading.js`: 加载状态管理
- `modalForm.js`: 弹窗表单工具
- `newToExcel.js`: 新版Excel导出
- `public.js`: 公共工具函数
- `scroll-to.js`: 滚动工具
- `storage.js`: 本地存储工具
- `theme.js`: 主题工具
- `toolsValidate.js`: 表单验证工具
- `upload.js`: 上传工具
- `validate.js`: 数据验证工具
- `videoCloud.js`: 视频云处理
### 4.6 Styles 目录文件职责
#### 样式文件 (src/theme/)
- `app.scss`: 应用主样式
- `base.scss`: 基础样式
- `common/transition.scss`: 过渡动画样式
- `dark.scss`: 暗色主题
- `element.scss`: Element UI样式覆盖
- `iview.scss`: iView样式覆盖
- `index.scss`: 样式入口文件
- `loading.scss`: 加载样式
- `variables.scss`: 样式变量
## 5. 未知/缺失信息清单
### 5.1 需要补充分析的页面文件
- `src/pages/kefu/`: 客服模块页面文件40个文件- 未详细分析
- `src/pages/marketing/`: 部分营销活动页面组件 - 未完全追踪依赖关系
- `src/pages/setting/`: 系统设置下多个子页面 - 未完全分析组件结构
- `src/pages/system/`: 系统管理页面 - 未详细分析
- `src/pages/app/`: 应用管理页面 - 未详细分析
- `src/pages/statistic/`: 统计报表页面 - 未详细分析
### 5.2 需要补充的组件依赖
- `src/components/mobileConfig/`: 35个移动端配置组件 - 未分析具体职责
- `src/components/mobileConfigRight/`: 39个右侧配置组件 - 未分析具体职责
- `src/components/mobilePage/`: 28个移动端页面组件 - 未分析具体职责
- `src/components/mobilePageDiy/`: 23个DIY页面组件 - 未分析具体职责
### 5.3 需要补充的API接口分析
- 大部分API文件只分析了入口未分析具体接口函数职责
- 缺少接口参数和返回数据结构分析
### 5.4 需要补充的Store状态分析
- 大部分store模块只分析了入口未分析具体state/mutations/actions结构
### 5.5 需要补充的Utils工具分析
- 大部分工具文件未分析具体函数功能和使用场景
## 6. 架构优化建议
### 6.1 组件抽取建议
1. **搜索筛选组件**: 将各页面的搜索筛选逻辑抽取为通用组件
2. **数据表格组件**: 标准化列表页面的表格展示组件
3. **弹窗表单组件**: 统一弹窗编辑表单的结构和交互
4. **统计卡片组件**: 标准化统计信息展示组件
### 6.2 Store模块重组建议
1. **按业务域重组**: 将相关业务的状态管理集中到一起
2. **状态规范化**: 统一state的命名和结构规范
3. **Actions抽象**: 将通用数据操作抽象为通用actions
### 6.3 API接口重组建议
1. **按模块分组**: 将API按业务模块重新组织
2. **接口规范化**: 统一接口命名和参数结构
3. **错误处理统一**: 标准化API错误处理逻辑
### 6.4 Utils工具优化建议
1. **工具分类**: 按功能类型重新组织工具函数
2. **通用工具库**: 抽取跨页面使用的通用工具
3. **类型定义**: 为工具函数添加TypeScript类型定义
### 6.5 文件组织优化建议
1. **组件按功能分组**: 将组件按功能类型重新组织目录结构
2. **页面组件瘦身**: 将复杂页面的逻辑抽取到composables中
3. **样式模块化**: 将样式按组件和页面分离组织
---
**分析说明**: 本文档基于代码静态分析生成,重点分析了页面结构、组件依赖和文件职责关系。由于项目规模较大,部分细节需要进一步深入分析。

View File

@@ -0,0 +1,292 @@
# CRMEB Admin 页面结构与流转分析
## 项目概述
- **项目**: CRMEB Admin 电商管理后台
- **技术栈**: Vue.js + Vue Router + Element UI + Vuex
- **路由前缀**: `/admin` (可配置)
- **路由模式**: history
## 1. 应用入口结构
### 1.1 入口文件层级
```
main.js (应用入口)
├── Vue实例初始化
├── 路由器配置
├── Vuex状态管理
└── 全局组件/插件注册
App.vue (根组件)
├── router-view (主路由出口)
└── Setings组件 (布局设置弹窗)
```
**源码位置**:
- `src/main.js` (line 250-256): Vue实例创建
- `src/App.vue` (line 3): 根路由视图
## 2. 页面布局体系
### 2.1 布局组件层级
```
LayoutMain (主布局组件)
├── layout/index.vue (布局选择器)
│ ├── 根据主题配置选择布局类型
│ ├── 支持4种布局模式
│ └── 响应式适配
├── layout/main/defaults.vue (默认布局)
│ ├── Asides (侧边栏)
│ ├── Headers (顶部导航栏)
│ └── Mains (主内容区)
└── layout/component/main.vue (主内容容器)
├── LayoutParentView (路由视图容器)
├── Footers (页脚)
├── Links (链接页面)
└── Iframes (内嵌页面)
```
**源码位置**:
- `src/layout/index.vue` (line 3-8): 布局选择逻辑
- `src/layout/main/defaults.vue` (line 2-11): 默认布局结构
- `src/layout/component/main.vue` (line 9): 路由视图
### 2.2 路由视图容器
```
LayoutParentView (父级路由视图)
├── transition (页面切换动画)
├── keep-alive (页面缓存)
└── router-view (实际路由出口)
```
**源码位置**: `src/layout/routerView/parent.vue`
## 3. 路由配置体系
### 3.1 路由分类结构
```
路由配置 (src/router/routers.js)
├── frameIn (主框架内路由)
│ ├── 基础路径: /
│ ├── 使用LayoutMain布局
│ ├── 包含所有业务模块
│ └── 需要权限验证
├── frameOuts (主框架外路由)
│ ├── 登录页面
│ ├── 客服模块
│ ├── 特殊功能页面
│ └── 无需权限验证
└── errorPage (错误页面)
├── 403/404/500错误页
└── 通配符路由兜底
```
### 3.2 路由模块组织
```
src/router/modules/
├── index.js # 首页模块
├── product.js # 商品管理
├── order.js # 订单管理
├── user.js # 用户管理
├── setting.js # 系统设置
├── marketing.js # 营销活动
├── finance.js # 财务管理
├── system.js # 系统管理
├── app.js # 应用管理
├── statistic.js # 统计报表
├── frameOut.js # 框架外路由
├── crud.js # CRUD模块
├── division.js # 部门管理
└── agent.js # 代理商管理
```
## 4. 页面流转逻辑
### 4.1 应用启动流程
```
应用启动
├── main.js 初始化Vue实例
├── 注册全局组件和插件
├── 配置路由和状态管理
└── 挂载到 #app 元素
页面初次加载
├── App.vue 渲染 <router-view />
├── 路由器检查当前路径
├── 匹配路由配置
└── 渲染对应组件
```
### 4.2 登录认证流程
```
访问受保护页面
├── router.beforeEach 路由守卫拦截
├── 检查用户token
│ ├── 有token → 验证权限
│ └── 无token → 跳转登录页
├── 权限验证
│ ├── 有权限 → 允许访问
│ └── 无权限 → 跳转403页
└── 渲染目标页面
```
**源码位置**: `src/router/index.js` (line 116-169)
### 4.3 页面导航流程
```
用户点击导航
├── 触发路由变化 ($route变化)
├── layout/index.vue 监听路由变化
├── 更新面包屑导航
├── 更新标签页导航
├── LayoutParentView 处理页面切换
│ ├── 检查keep-alive缓存
│ ├── 执行页面切换动画
│ └── 渲染新页面组件
└── 滚动到页面顶部
```
### 4.4 布局切换流程
```
用户切换布局主题
├── Vuex状态更新 (themeConfig)
├── layout/index.vue 响应状态变化
├── 根据配置选择布局组件
├── 重新渲染布局结构
└── 保持页面内容不变
```
## 5. 关键页面路径
### 5.1 主框架内页面 (frameIn)
| 路径 | 页面名称 | 组件位置 | 权限要求 |
|------|---------|---------|---------|
| `/admin/index` | 主页 | `src/pages/index/index.vue` | `admin-index-index` |
| `/admin/product/product_list` | 商品管理 | `src/pages/product/productList/index.vue` | `admin-store-storeProuduct-index` |
| `/admin/order/list` | 订单管理 | `src/pages/order/orderList/index.vue` | `admin-order-storeOrder-index` |
| `/admin/user/list` | 用户管理 | `src/pages/user/list/index.vue` | `admin-user-user-index` |
| `/admin/setting/system_config` | 系统设置 | `src/pages/setting/setSystem/index.vue` | `setting-system-config` |
### 5.2 主框架外页面 (frameOut)
| 路径 | 页面名称 | 组件位置 | 说明 |
|------|---------|---------|------|
| `/admin/login` | 登录页面 | `src/pages/account/login/index.vue` | 无需登录即可访问 |
| `/kefu` | 客服管理 | `src/pages/kefu/index.vue` | 独立客服系统 |
| `/kefu/mobile_chat` | 移动端客服 | `src/pages/kefu/mobile/index.vue` | 移动端聊天界面 |
| `/app/upload` | 文件上传 | `src/pages/app/upload.vue` | 移动端扫码上传 |
## 6. 页面缓存机制
### 6.1 Keep-Alive 配置
```javascript
// src/layout/routerView/parent.vue
<keep-alive :include="keepAliveNameList">
<router-view :key="refreshRouterViewKey" />
</keep-alive>
```
### 6.2 缓存管理
```
缓存页面列表
├── 从Vuex获取 (keepAliveNames)
├── 支持页面刷新功能
├── 标签页关闭时清理缓存
└── 路由切换时保持状态
```
**源码位置**: `src/store/module/keepAliveNames.js`
## 7. 页面布局类型
### 7.1 支持的布局模式
```
defaults (默认布局)
├── 经典的左右布局
├── 侧边栏 + 主内容区
└── 支持固定头部
classic (经典布局)
├── 传统管理后台布局
├── 顶部导航 + 侧边栏
└── 适用于复杂导航
transverse (横向布局)
├── 横向菜单布局
├── 适用于扁平化导航
└── 节省垂直空间
columns (分栏布局)
├── 多列布局设计
├── 适用于信息密集页面
└── 提高空间利用率
```
**源码位置**: `src/layout/main/` 目录下对应文件
## 8. 特殊页面处理
### 8.1 全屏页面
```javascript
// 路由meta配置
meta: {
fullScreen: true // 启用全屏模式
}
```
- 隐藏侧边栏和顶部导航
- 适用于页面设计器等特殊场景
### 8.2 内嵌页面
```javascript
// 路由meta配置
meta: {
isIframe: true, // 内嵌iframe
isLink: true // 链接页面
}
```
- 支持iframe内嵌外部页面
- 支持直接跳转外部链接
### 8.3 标签页固定
```javascript
// 路由meta配置
meta: {
isAffix: true // 固定标签页
}
```
- 标签页不可关闭
- 通常用于首页等重要页面
## 9. 响应式适配
### 9.1 移动端适配
```
屏幕宽度检测
├── < 600px → Mobile模式
├── 600-992px → Tablet模式
├── > 992px → Desktop模式
布局自适应
├── 移动端隐藏侧边栏
├── 自动切换到单列布局
└── 调整组件尺寸
```
**源码位置**: `src/App.vue` (line 33-49)
## 10. 总结
CRMEB Admin的页面结构采用了典型的管理后台架构
1. **分层设计**: 入口层 → 布局层 → 路由层 → 页面层
2. **模块化组织**: 路由按业务模块拆分,便于维护
3. **灵活布局**: 支持多种布局模式,适应不同使用场景
4. **权限控制**: 基于路由的权限验证体系
5. **缓存优化**: 智能的页面缓存机制提升用户体验
6. **响应式适配**: 支持多终端访问
这种架构设计使得系统具有良好的可扩展性和维护性,同时提供了丰富的定制化选项。

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
# 商城数据库设计文档总览
本文档是商城数据库的入口索引,提供各模块详细文档的链接与摘要。
## 核心文档
1. **数据库概览**
- [00 概览](sql/00_overview.md): 数据库设计目标、核心概念与术语说明
- [01 表清单](sql/01_tables_catalog.md): 按业务域划分的完整表结构说明
- [02 实体关系](sql/02_relationships_er.md): 表间关系与ER图说明
2. **数据字典**
- [03 状态字典](sql/03_enums_status_dict.md): 所有状态字段的枚举值与业务含义
3. **核心功能**
- [04 触发器与函数](sql/04_triggers_and_functions.md): 数据库层实现的业务规则
- [05 权限矩阵](sql/05_rls_permissions_matrix.md): Supabase RLS行级安全策略说明
- [06 索引与查询](sql/06_indexes_and_query_patterns.md): 索引设计与典型查询模式
4. **业务流程**
- [07 业务流](sql/07_business_workflows.md): 核心业务场景的完整数据流
- [08 一致性边界](sql/08_data_consistency_boundaries.md): 数据库保证什么/应用层需要保证什么
5. **部署维护**
- [09 迁移策略](sql/09_migrations_and_versions.md): 不同环境下的迁移指南
- [10 质量检查](sql/10_quality_checks.md): 自检清单与验收标准
## 快速开始
### 新环境初始化
```bash
# 1. 执行基础迁移
psql -f doc_mall/database/mall_migration.sql
# 2. 应用安全策略
psql -f doc_mall/database/mall_seo_security.sql
# 3. 验证数据库状态
psql -f mall_sql/tests/mall_database_check.sql
```
### 核心表关系速查
- 用户: `ak_users``ml_user_profiles` (1:1)
- 商品: `ml_products` (SPU) ↔ `ml_product_skus` (1:N)
- 订单: `ml_orders``ml_order_items` (1:N)
- 店铺: `ak_users` (merchant) ↔ `ml_shops` (1:1)
## 设计原则
1. **Supabase优先**
- 使用 `auth.uid()` + RLS 进行数据隔离
- 前端可直接安全地访问数据库
2. **性能优化**
- 高频查询字段都有索引
- 使用触发器维护汇总字段
- 合理使用JSONB存储非结构化数据
3. **可扩展性**
- 所有核心表都有`cid`(自增ID)和`slug`用于SEO
- 模块化设计,支持功能扩展
## 常见问题
Q: 如何添加新状态?
A: 需要更新CHECK约束、相关触发器和状态字典文档。
Q: 如何添加新表?
A: 参考现有表结构,确保包含`id`(UUID)、`cid`(SERIAL)、`created_at`等标准字段。
Q: 如何测试RLS策略
A: 使用`set local request.jwt.claim.sub = 'user-id'`模拟不同用户访问。
## 贡献指南
1. 修改数据库前请先更新相关文档
2. 保持命名一致性
3. 提供回滚脚本
4. 更新版本号
## 版本历史
- v1.0.0 (2024-02-01): 初始版本
- v1.1.0 (2024-02-15): 新增订阅模块
## 联系
如有问题请联系数据库管理员或提交issue。