diff --git a/CRMEB b/CRMEB new file mode 160000 index 00000000..d3dba751 --- /dev/null +++ b/CRMEB @@ -0,0 +1 @@ +Subproject commit d3dba751cabc8becc01843916c8e4a947379391b diff --git a/ak/config.uts b/ak/config.uts index 93ff692b..b9df9aeb 100644 --- a/ak/config.uts +++ b/ak/config.uts @@ -1,14 +1,23 @@ // Supabase 配置 -// 开发环境 - 本地 Supabase +// 内网环境 - 本地部署的 Supabase +// IP: 192.168.1.63 +// Kong HTTP Port: 8000 +export const SUPA_URL: string = 'http://192.168.1.63:8000' +export const SUPA_KEY: string = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzY4ODMwNjI0LCJleHAiOjE5MjY1MTA2MjR9.mDVl-kIOdRK9v6VTxo0TDF8r7X7xk3PZXazaavHyVvg' + +// WebSocket 实时连接(内网使用 ws:// 而非 wss://) +export const WS_URL: string = 'ws://192.168.1.63:8000/realtime/v1/websocket' + +// 备用配置(已注释,如需切换可取消注释) +// 开发环境 - 其他内网地址 // export const SUPA_URL: string = 'http://192.168.0.150:8080' // export const SUPA_KEY: string = 'your-anon-key' +// export const WS_URL: string = 'ws://192.168.0.150:8080/realtime/v1/websocket' -// 生产环境 - Supabase 云服务 -export const SUPA_URL: string = 'https://ak3.oulog.com' -export const SUPA_KEY: string = 'your-anon-key' - -// WebSocket 实时连接 -export const WS_URL: string = 'wss://ak3.oulog.com/realtime/v1/websocket' +// 生产环境 - Supabase 云服务(已注释) +// export const SUPA_URL: string = 'https://ak3.oulog.com' +// export const SUPA_KEY: string = 'your-anon-key' +// export const WS_URL: string = 'wss://ak3.oulog.com/realtime/v1/websocket' // 路由配置 export const HOME_REDIRECT: string = '/pages/mall/consumer/index' diff --git a/components/analytics/AnalyticsBarMini.uvue b/components/analytics/AnalyticsBarMini.uvue new file mode 100644 index 00000000..21580e50 --- /dev/null +++ b/components/analytics/AnalyticsBarMini.uvue @@ -0,0 +1,60 @@ + + + + + diff --git a/components/analytics/AnalyticsComboChart.uvue b/components/analytics/AnalyticsComboChart.uvue new file mode 100644 index 00000000..5cf252a2 --- /dev/null +++ b/components/analytics/AnalyticsComboChart.uvue @@ -0,0 +1,116 @@ + + + + + diff --git a/components/analytics/AnalyticsDonutChart.uvue b/components/analytics/AnalyticsDonutChart.uvue new file mode 100644 index 00000000..a2fce1be --- /dev/null +++ b/components/analytics/AnalyticsDonutChart.uvue @@ -0,0 +1,70 @@ + + + + + diff --git a/components/analytics/ChartCard.uvue b/components/analytics/ChartCard.uvue new file mode 100644 index 00000000..cd35b39f --- /dev/null +++ b/components/analytics/ChartCard.uvue @@ -0,0 +1,57 @@ + + + + + diff --git a/components/analytics/KpiCard.uvue b/components/analytics/KpiCard.uvue new file mode 100644 index 00000000..2f144d96 --- /dev/null +++ b/components/analytics/KpiCard.uvue @@ -0,0 +1,98 @@ + + + + + diff --git a/components/analytics/PeriodTabs.uvue b/components/analytics/PeriodTabs.uvue new file mode 100644 index 00000000..603f4f1f --- /dev/null +++ b/components/analytics/PeriodTabs.uvue @@ -0,0 +1,49 @@ + + + + + diff --git a/components/analytics/charts/AreaLine.uvue b/components/analytics/charts/AreaLine.uvue new file mode 100644 index 00000000..a44bc0a5 --- /dev/null +++ b/components/analytics/charts/AreaLine.uvue @@ -0,0 +1,23 @@ + + + + + diff --git a/components/analytics/charts/ComboBarLine.uvue b/components/analytics/charts/ComboBarLine.uvue new file mode 100644 index 00000000..fb5adc6f --- /dev/null +++ b/components/analytics/charts/ComboBarLine.uvue @@ -0,0 +1,23 @@ + + + + + diff --git a/components/analytics/charts/DonutPie.uvue b/components/analytics/charts/DonutPie.uvue new file mode 100644 index 00000000..a44bc0a5 --- /dev/null +++ b/components/analytics/charts/DonutPie.uvue @@ -0,0 +1,23 @@ + + + + + diff --git a/docs/ANALYTICS_UI_DESIGN.md b/docs/ANALYTICS_UI_DESIGN.md new file mode 100644 index 00000000..0f9cc197 --- /dev/null +++ b/docs/ANALYTICS_UI_DESIGN.md @@ -0,0 +1,665 @@ +# 数据分析页面 UI 设计文档 + +## 📋 文档说明 + +本文档记录了**数据分析中心页面**的 UI 设计实现,遵循项目的 UI 设计规范,采用现代简约的设计风格,提供清晰直观的数据可视化界面。 + +### 页面访问 URL + +#### 主页面路径 +- **完整路径**:`/pages/mall/analytics/index` +- **页面标题**:数据分析中心 +- **导航栏样式**:自定义导航栏(`navigationStyle: "custom"`) +- **路由配置位置**:`subPackages` → `pages/mall/analytics` → `index` + +#### 相关子页面 URL + +- **销售报表**:`/pages/mall/analytics/sales-report` +- **用户分析**:`/pages/mall/analytics/user-analysis` +- **商品洞察**:`/pages/mall/analytics/product-insights` +- **市场趋势**:`/pages/mall/analytics/market-trends` +- **自定义报表**:`/pages/mall/analytics/custom-report` +- **报表详情**:`/pages/mall/analytics/report-detail` +- **数据分析详情**:`/pages/mall/analytics/data-detail` +- **数据洞察详情**:`/pages/mall/analytics/insight-detail` + +### 访问方式 + +#### 1. 代码中跳转(uni-app x) + +```typescript +// 方式一:使用 navigateTo(推荐,保留返回栈) +uni.navigateTo({ + url: '/pages/mall/analytics/index' +}) + +// 方式二:使用 redirectTo(替换当前页面,不保留返回栈) +uni.redirectTo({ + url: '/pages/mall/analytics/index' +}) + +// 方式三:使用 reLaunch(关闭所有页面,打开新页面) +uni.reLaunch({ + url: '/pages/mall/analytics/index' +}) +``` + +#### 2. 从其他页面跳转示例 + +```typescript +// 从管理后台跳转到数据分析中心 +const goToAnalytics = () => { + uni.navigateTo({ + url: '/pages/mall/analytics/index' + }) +} + +// 从首页跳转到数据分析中心 +const goToDataAnalysis = () => { + uni.navigateTo({ + url: '/pages/mall/analytics/index', + success: () => { + console.log('跳转成功') + }, + fail: (err) => { + console.error('跳转失败:', err) + } + }) +} +``` + +#### 3. 带参数跳转 + +```typescript +// 跳转并传递参数 +uni.navigateTo({ + url: '/pages/mall/analytics/index?period=30d&refresh=true' +}) + +// 在目标页面接收参数(index.uvue 的 onLoad) +onLoad(options: any) { + const period = options.period || '30d' + const refresh = options.refresh === 'true' + if (period) { + this.period = period + } + if (refresh) { + this.refreshData() + } +} +``` + +#### 4. 页面间跳转 + +```typescript +// 从数据分析首页跳转到销售报表 +const goToSalesReport = () => { + uni.navigateTo({ + url: '/pages/mall/analytics/sales-report' + }) +} + +// 从数据分析首页跳转到用户分析 +const goToUserAnalysis = () => { + uni.navigateTo({ + url: '/pages/mall/analytics/user-analysis' + }) +} +``` + +#### 5. 权限控制示例 + +```typescript +// 跳转前检查权限 +const goToAnalyticsWithAuth = () => { + // 检查用户是否有数据分析权限 + const userType = getUserType() // 假设这是获取用户类型的函数 + + if (userType === 'admin' || userType === 'analyst') { + uni.navigateTo({ + url: '/pages/mall/analytics/index' + }) + } else { + uni.showToast({ + title: '您没有访问权限', + icon: 'none' + }) + } +} +``` + +#### 6. 在页面配置中设置入口 + +如果需要在 TabBar 或其他导航中添加入口,可以在 `pages.json` 中配置: + +```json +{ + "tabBar": { + "list": [ + { + "pagePath": "pages/mall/analytics/index", + "text": "数据分析" + } + ] + } +} +``` + +### 设计原则 + +1. **数据优先**:突出核心数据指标,减少视觉干扰 +2. **层次清晰**:通过卡片、阴影、间距建立清晰的信息层次 +3. **视觉统一**:遵循项目统一的颜色系统和设计规范 +4. **响应式适配**:适配不同屏幕尺寸,确保良好的用户体验 + +--- + +## 一、页面结构 + +### 1.1 整体布局 + +``` +┌─────────────────────────────────────┐ +│ Header(头部控制面板) │ +│ - 标题 + 最后更新时间 │ +│ - 刷新/导出按钮 │ +├─────────────────────────────────────┤ +│ 实时大屏(4个核心指标卡片) │ +│ - GMV / 订单 / 用户 / 转化率 │ +├─────────────────────────────────────┤ +│ 时间筛选(Tab切换) │ +│ - 今日/本周/本月/本季度 │ +├─────────────────────────────────────┤ +│ 销售分析 │ +│ - 销售趋势图 │ +│ - 商品销量排行 │ +├─────────────────────────────────────┤ +│ 用户行为分析 │ +│ - 用户活跃度 │ +│ - 流量来源 │ +├─────────────────────────────────────┤ +│ 商家表现 │ +│ - 商家排行榜 │ +├─────────────────────────────────────┤ +│ 配送效率 │ +│ - 配送时效 │ +│ - 配送覆盖 │ +├─────────────────────────────────────┤ +│ 快速分析工具(6个工具卡片) │ +│ - 销售报表/用户分析/商品洞察等 │ +└─────────────────────────────────────┘ +``` + +### 1.2 模块划分 + +1. **Header 区域**:页面标题、更新时间、操作按钮 +2. **实时大屏**:核心业务指标(GMV、订单、用户、转化率) +3. **时间筛选**:时间维度切换(今日/本周/本月/本季度) +4. **销售分析**:销售趋势、商品排行 +5. **用户行为分析**:用户活跃度、流量来源 +6. **商家表现**:商家销售排行榜 +7. **配送效率**:配送时效、覆盖情况 +8. **快速工具**:常用分析工具入口 + +--- + +## 二、设计规范应用 + +### 2.1 CSS 变量系统 + +所有设计 token 通过 CSS 变量定义,便于统一管理和换肤: + +```css +:root { + /* 主题色 */ + --theme-primary: #FF4D4F; + --theme-primary-light: #FF7875; + --theme-primary-dark: #CF1322; + --gradient-start: #FF4D4F; + --gradient-end: #FF7A45; + + /* 功能色 */ + --success: #52C41A; + --warning: #FAAD14; + --error: #FF4D4F; + --info: #1890FF; + + /* 文字颜色 */ + --text-primary: #111111; + --text-secondary: #333333; + --text-tertiary: #666666; + --text-disabled: #999999; + + /* 背景颜色 */ + --bg-primary: #FFFFFF; + --bg-secondary: #F7F8FA; + --bg-tertiary: #F5F5F5; + + /* 边框 */ + --border-color: rgba(0, 0, 0, 0.06); + + /* 阴影 */ + --shadow-sm: 0 2rpx 8rpx rgba(0, 0, 0, 0.06); + --shadow-md: 0 4rpx 16rpx rgba(0, 0, 0, 0.08); + + /* 圆角 */ + --radius-md: 12rpx; + --radius-lg: 20rpx; + --radius-xl: 24rpx; + + /* 间距 */ + --spacing-sm: 16rpx; + --spacing-md: 24rpx; + --spacing-lg: 32rpx; +} +``` + +### 2.2 卡片式设计 + +所有数据模块采用卡片式设计: + +- **圆角**:`border-radius: 20rpx`(符合 UI 规范) +- **阴影**:`box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06)`(轻微阴影) +- **背景**:白色背景 `#FFFFFF` +- **内边距**:`32rpx`(统一间距) +- **外边距**:`24rpx`(卡片间距) + +### 2.3 颜色系统应用 + +#### Header 渐变背景 +```css +background: linear-gradient(135deg, #FF4D4F 0%, #FF7A45 100%); +``` + +#### 实时指标卡片渐变 +- **GMV(收入)**:`#FF6B6B → #FF4D4F`(红色渐变) +- **订单**:`#4ECDC4 → #44A08D`(青色渐变) +- **用户**:`#A8E6CF → #7FCDBB`(绿色渐变) +- **转化率**:`#FFD93D → #FFA07A`(黄色渐变) + +#### 状态颜色 +- **增长(正)**:绿色 `#52C41A` + 浅绿背景 +- **下降(负)**:红色 `#FF4D4F` + 浅红背景 +- **中性**:灰色 `#666666` + 浅灰背景 + +--- + +## 三、组件设计详解 + +### 3.1 Header 头部 + +**设计特点**: +- 使用主题色渐变背景 +- 左侧显示标题和更新时间 +- 右侧操作按钮使用毛玻璃效果 + +**实现代码**: +```css +.header { + background: linear-gradient(135deg, var(--gradient-start) 0%, var(--gradient-end) 100%); + padding: var(--spacing-lg) var(--spacing-md) var(--spacing-md); + box-shadow: var(--shadow-md); +} + +.refresh-btn, +.export-btn { + width: 64rpx; + height: 64rpx; + background: rgba(255, 255, 255, 0.2); + border-radius: 50%; + backdrop-filter: blur(10rpx); +} +``` + +### 3.2 实时大屏卡片 + +**设计特点**: +- 2x2 网格布局 +- 每个卡片使用不同渐变背景 +- 数值突出显示,增长指标使用标签样式 + +**布局**: +```css +.dashboard-grid { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + gap: var(--spacing-md); +} + +.dashboard-card { + width: calc(50% - var(--spacing-md) / 2); + padding: var(--spacing-lg) var(--spacing-md); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-sm); +} +``` + +### 3.3 时间筛选 Tab + +**设计特点**: +- 激活状态使用主题色渐变 +- 添加阴影效果增强层次 +- 平滑过渡动画 + +**实现**: +```css +.filter-tab.active { + background: linear-gradient(135deg, var(--gradient-start) 0%, var(--gradient-end) 100%); + color: #fff; + font-weight: 500; + box-shadow: 0 2rpx 8rpx rgba(255, 77, 79, 0.3); +} +``` + +### 3.4 销售分析卡片 + +**设计特点**: +- 图表区域使用浅色背景区分 +- 统计项使用独立卡片样式 +- 数值使用主题色突出 + +**布局**: +```css +.trend-stats { + display: flex; + justify-content: space-around; + gap: var(--spacing-md); +} + +.stat-item { + flex: 1; + padding: var(--spacing-md); + background: var(--bg-secondary); + border-radius: var(--radius-md); +} +``` + +### 3.5 商品排行 + +**设计特点**: +- 排名使用圆形徽章,使用主题色渐变 +- 商品名称和销量清晰对比 +- 统一的分割线 + +**实现**: +```css +.rank-number { + width: 56rpx; + height: 56rpx; + background: linear-gradient(135deg, var(--gradient-start) 0%, var(--gradient-end) 100%); + border-radius: 50%; + box-shadow: var(--shadow-sm); +} +``` + +### 3.6 用户行为分析 + +**设计特点**: +- 指标使用列表式展示 +- 流量来源使用进度条可视化 +- 进度条使用主题色渐变 + +**进度条实现**: +```css +.progress-bar { + height: 100%; + background: linear-gradient(135deg, var(--gradient-start) 0%, var(--gradient-end) 100%); + border-radius: 12rpx; + transition: width 0.3s ease; +} +``` + +### 3.7 商家排行榜 + +**设计特点**: +- 排名徽章使用金银铜渐变 +- 增长率使用彩色标签 +- 商家信息清晰展示 + +**排名徽章**: +```css +.rank-gold { + background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%); +} + +.rank-silver { + background: linear-gradient(135deg, #C0C0C0 0%, #A0A0A0 100%); +} + +.rank-bronze { + background: linear-gradient(135deg, #CD7F32 0%, #B8860B 100%); +} +``` + +### 3.8 快速工具卡片 + +**设计特点**: +- 3 列网格布局 +- 点击反馈效果 +- 图标 + 标题 + 描述 + +**交互效果**: +```css +.tool-card:active { + transform: scale(0.98); + box-shadow: var(--shadow-md); +} +``` + +--- + +## 四、响应式设计 + +### 4.1 断点设置 + +- **默认**:>= 768rpx(双列布局) +- **小屏**:< 768rpx(单列布局) + +### 4.2 响应式规则 + +```css +@media screen and (max-width: 768rpx) { + /* 实时大屏卡片改为单列 */ + .dashboard-card { + width: 100%; + } + + /* 工具卡片改为 2 列 */ + .tool-card { + width: calc(50% - var(--spacing-md) / 2); + } + + /* 配送分析改为纵向布局 */ + .delivery-metrics { + flex-direction: column; + } +} +``` + +### 4.3 适配策略 + +1. **实时大屏**:小屏下改为单列,保持卡片完整性 +2. **工具卡片**:小屏下改为 2 列,提升空间利用率 +3. **配送分析**:小屏下改为纵向堆叠,避免内容挤压 + +--- + +## 五、交互设计 + +### 5.1 操作反馈 + +- **按钮点击**:缩放效果 `transform: scale(0.98)` +- **Tab 切换**:平滑过渡动画 `transition: all 0.3s` +- **进度条**:宽度变化动画 `transition: width 0.3s ease` + +### 5.2 数据刷新 + +- **刷新按钮**:点击后显示加载状态 +- **数据更新**:更新时间实时显示 +- **错误处理**:友好的错误提示 + +### 5.3 导出功能 + +- **导出选项**:Excel / PDF / 图片 +- **加载提示**:导出过程中显示加载动画 +- **成功反馈**:导出成功后 Toast 提示 + +--- + +## 六、数据可视化 + +### 6.1 图表占位 + +当前使用占位符,后续可集成图表库: + +- **销售趋势图**:折线图或面积图 +- **商品销量排行**:柱状图或条形图 +- **流量来源**:饼图或环形图 + +### 6.2 推荐图表库 + +- **uni-app x 兼容**:需使用原生图表组件 +- **Web 端**:可使用 ECharts、Chart.js 等 +- **移动端**:可使用 uni-charts 或自定义 Canvas 绘制 + +--- + +## 七、性能优化 + +### 7.1 数据加载 + +- **分步加载**:先加载核心指标,再加载详细数据 +- **缓存策略**:合理使用数据缓存,减少重复请求 +- **防抖处理**:刷新操作添加防抖,避免频繁请求 + +### 7.2 渲染优化 + +- **虚拟列表**:长列表使用虚拟滚动 +- **懒加载**:非首屏内容延迟加载 +- **图片优化**:使用合适的图片格式和尺寸 + +--- + +## 八、后续优化建议 + +### 8.1 功能增强 + +1. **实时数据推送**:使用 WebSocket 实现数据实时更新 +2. **数据钻取**:点击指标可查看详细数据 +3. **自定义看板**:允许用户自定义指标和布局 +4. **数据对比**:支持多时间段数据对比 +5. **导出增强**:支持自定义导出字段和格式 + +### 8.2 UI 优化 + +1. **图表集成**:集成专业图表库,替换占位符 +2. **动画效果**:添加数据变化动画,提升视觉体验 +3. **暗色模式**:支持暗色主题切换 +4. **国际化**:支持多语言切换 + +### 8.3 交互优化 + +1. **下拉刷新**:支持下拉刷新数据 +2. **上拉加载**:长列表支持上拉加载更多 +3. **手势操作**:支持滑动切换时间维度 +4. **快捷操作**:添加常用操作的快捷入口 + +--- + +## 九、技术实现 + +### 9.1 文件结构 + +``` +pages/mall/analytics/ +├── index.uvue # 数据分析首页 +├── profile.uvue # 数据分析个人中心 +└── report-detail.uvue # 报表详情页 +``` + +### 9.2 核心代码结构 + +```vue + + + + + +``` + +### 9.3 数据接口 + +当前使用 Supabase 查询数据,主要涉及: + +- `orders` 表:订单数据 +- `users` 表:用户数据 +- `user_sessions` 表:用户会话数据(如果存在) + +--- + +## 十、设计规范遵循 + +### 10.1 颜色系统 ✅ + +- ✅ 使用主题色 `#FF4D4F` 作为主色调 +- ✅ 使用渐变色增强视觉效果 +- ✅ 使用功能色表示状态(成功/警告/错误) + +### 10.2 间距系统 ✅ + +- ✅ 使用统一的间距变量(`--spacing-sm/md/lg`) +- ✅ 卡片间距统一为 `24rpx` +- ✅ 内容内边距统一为 `32rpx` + +### 10.3 圆角系统 ✅ + +- ✅ 卡片圆角统一为 `20rpx` +- ✅ 小元素圆角为 `12rpx` +- ✅ 圆形元素使用 `50%` + +### 10.4 阴影系统 ✅ + +- ✅ 卡片使用轻微阴影 `0 2rpx 8rpx rgba(0, 0, 0, 0.06)` +- ✅ 激活状态使用增强阴影 +- ✅ 按钮使用阴影增强层次 + +--- + +## 十一、总结 + +数据分析页面 UI 设计完全遵循项目的 UI 设计规范,实现了: + +1. ✅ **统一的视觉风格**:使用项目统一的颜色系统和设计 token +2. ✅ **清晰的信息层次**:通过卡片、阴影、间距建立清晰层次 +3. ✅ **良好的用户体验**:响应式设计、交互反馈、数据可视化 +4. ✅ **可维护的代码**:CSS 变量系统、模块化设计、清晰的代码结构 + +页面已实现核心功能,后续可根据实际需求进行功能增强和 UI 优化。 + +--- + +**文档版本**: v1.0 +**创建时间**: 2025-01-XX +**最后更新**: 2025-01-XX +**状态**: ✅ 已完成 diff --git a/docs/CRMEB_REFACTORING_PLAN.md b/docs/CRMEB_REFACTORING_PLAN.md new file mode 100644 index 00000000..ee38af71 --- /dev/null +++ b/docs/CRMEB_REFACTORING_PLAN.md @@ -0,0 +1,940 @@ +# CRMEB 项目重构计划文档 + +## 📋 文档说明 + +本文档基于 **Clean-Room 重构原则**,通过分析 CRMEB 项目的**可观察行为与功能规格**,制定将 CRMEB 商城系统迁移到 **uni-app x (uvue) + Supabase** 技术栈的重构计划。 + +### 重构原则 + +1. **禁止复制源码**:不直接使用 CRMEB 的任何 PHP/Vue 源码 +2. **规格驱动开发**:基于功能规格和行为描述进行独立实现 +3. **技术栈迁移**: + - 前端:Vue/UniApp → **uvue (uni-app x)** + - 后端:PHP/ThinkPHP → **Supabase (PostgreSQL + RLS + Edge Functions)** +4. **组件复用**:尽量不修改 `components/supadb`,仅通过接口调用 + +--- + +## 一、功能规格提取 (Spec Extraction) + +### 1.1 核心业务模块 + +基于 CRMEB 项目结构分析,提取以下核心功能模块: + +#### 1.1.1 用户系统 (User System) +**功能清单**: +- 用户注册/登录(手机号、微信、邮箱) +- 用户信息管理(昵称、头像、性别) +- 用户角色(消费者、商家、配送员、客服、管理员) +- 用户认证(实名认证、商家认证) +- 用户地址管理(多地址、默认地址) +- 用户余额/积分管理 + +**数据字段规格**: +- 用户基础信息:id, phone, email, nickname, avatar_url, gender, user_type, status +- 用户扩展信息:real_name, id_card, credit_score, verification_status +- 地址信息:receiver_name, receiver_phone, province, city, district, address_detail, is_default + +**权限矩阵**: +- 用户只能查看/修改自己的信息 +- 管理员可查看所有用户信息 +- 商家可查看自己的店铺信息 + +#### 1.1.2 商品系统 (Product System) +**功能清单**: +- 商品管理(创建、编辑、上架、下架) +- 商品分类(多级分类、分类树) +- 商品品牌管理 +- 商品规格/SKU(多规格、价格、库存) +- 商品图片(主图、详情图、轮播图) +- 商品搜索(关键词、分类、品牌、价格区间) +- 商品排序(价格、销量、时间、综合) + +**数据字段规格**: +- 商品基础:id, merchant_id, category_id, name, description, base_price, original_price, stock, sales, status +- 商品图片:main_image_url, image_urls (JSONB) +- 商品规格:sku_code, specifications (JSONB), price, stock +- 分类:id, pid (parent_id), name, icon, sort + +**业务规则**: +- 商品状态:0-下架,1-上架,2-审核中 +- 库存扣减:下单时扣减,取消订单时恢复 +- 价格计算:支持原价、现价、会员价 + +#### 1.1.3 订单系统 (Order System) +**功能清单**: +- 订单创建(购物车结算、立即购买) +- 订单确认(地址选择、优惠券选择、运费计算) +- 订单支付(微信支付、支付宝、余额支付) +- 订单状态流转(待支付→已支付→已发货→已收货→已完成) +- 订单取消(用户取消、超时取消) +- 订单退款(申请退款、审核退款、退款完成) +- 订单评价(商品评价、商家回复) + +**数据字段规格**: +- 订单主表:id, order_no, user_id, merchant_id, total_amount, discount_amount, delivery_fee, actual_amount, order_status, payment_status, payment_method, delivery_address (JSONB) +- 订单商品:order_id, product_id, sku_id, product_name, price, quantity, total_amount +- 订单状态:1-待支付,2-已支付,3-已发货,4-已收货,5-已完成,6-已取消,7-退款中,8-已退款 + +**业务规则**: +- 订单号生成:唯一订单号(如:ORD20240101000001) +- 超时取消:30分钟未支付自动取消 +- 库存检查:下单时检查库存,库存不足提示 +- 价格锁定:订单创建时锁定商品价格 + +#### 1.1.4 购物车系统 (Cart System) +**功能清单**: +- 购物车添加(商品、SKU、数量) +- 购物车编辑(数量修改、删除) +- 购物车选择(单选、全选) +- 购物车结算(批量结算、价格计算) + +**数据字段规格**: +- 购物车:id, user_id, product_id, sku_id, quantity, selected + +**业务规则**: +- 同一商品同一SKU合并数量 +- 商品下架时从购物车移除提示 +- 库存不足时提示并限制数量 + +#### 1.1.5 营销系统 (Marketing System) +**功能清单**: +- 优惠券(满减券、折扣券、免运费券) +- 优惠券领取(用户领取、系统发放) +- 优惠券使用(下单时选择、自动抵扣) +- 拼团活动(创建拼团、参团、成团) +- 秒杀活动(限时秒杀、库存限制) +- 砍价活动(发起砍价、好友助力) +- 积分系统(积分获取、积分兑换) +- 签到奖励(每日签到、连续签到) + +**数据字段规格**: +- 优惠券模板:id, name, coupon_type, discount_type, discount_value, min_order_amount, total_quantity, start_time, end_time, status +- 用户优惠券:id, user_id, template_id, coupon_code, status, used_at, expire_at +- 优惠券类型:1-满减,2-折扣,3-免运费,4-新人券,5-会员券 + +**业务规则**: +- 优惠券有效期检查 +- 优惠券使用条件(满额、指定商品、指定分类) +- 每人限领数量 + +#### 1.1.6 配送系统 (Delivery System) +**功能清单**: +- 配送员管理(注册、认证、审核) +- 配送任务分配(自动分配、手动分配) +- 配送状态跟踪(待接单→已接单→已取货→配送中→已送达) +- 配送费用计算(距离、重量、时间) + +**数据字段规格**: +- 配送员:id, user_id, real_name, id_card, vehicle_type, work_status, current_location (JSONB), service_areas (Array) +- 配送任务:id, order_id, driver_id, pickup_address (JSONB), delivery_address (JSONB), distance, delivery_fee, status + +**业务规则**: +- 配送员认证审核 +- 配送范围限制 +- 配送费用计算规则 + +#### 1.1.7 评价系统 (Review System) +**功能清单**: +- 商品评价(评分、文字、图片) +- 商家回复 +- 评价展示(全部、好评、中评、差评) +- 评价统计(好评率、平均分) + +**数据字段规格**: +- 评价:id, order_id, product_id, user_id, rating, content, images (Array), reply_content, reply_time, status + +**业务规则**: +- 仅已收货订单可评价 +- 评价后不可修改,可追评 +- 匿名评价选项 + +#### 1.1.8 店铺系统 (Shop System) +**功能清单**: +- 店铺创建(商家注册店铺) +- 店铺信息管理(名称、Logo、简介、轮播图) +- 店铺认证(营业执照、资质审核) +- 店铺营业状态(营业中、休息中、关闭) +- 店铺评分(综合评分、服务评分、商品评分) + +**数据字段规格**: +- 店铺:id, merchant_id, shop_name, shop_logo, shop_banner, shop_description, shop_status, rating, total_sales + +**业务规则**: +- 商家认证后才能开店 +- 店铺关闭后商品自动下架 +- 店铺评分计算规则 + +### 1.2 管理后台功能 + +#### 1.2.1 商品管理 +- 商品列表(搜索、筛选、排序) +- 商品审核(上架审核、下架管理) +- 分类管理(分类树、排序) +- 品牌管理 + +#### 1.2.2 订单管理 +- 订单列表(状态筛选、搜索) +- 订单详情查看 +- 订单发货 +- 退款审核 + +#### 1.2.3 用户管理 +- 用户列表 +- 用户详情 +- 用户状态管理(冻结、解冻) + +#### 1.2.4 营销管理 +- 优惠券管理(创建、发放、统计) +- 活动管理(拼团、秒杀、砍价) + +#### 1.2.5 系统设置 +- 系统配置(支付配置、物流配置) +- 权限管理 +- 数据统计 + +### 1.3 前端页面清单 + +#### 1.3.1 消费者端 (Consumer) +- 首页(轮播图、分类导航、推荐商品、热门商品) +- 分类页(分类列表、商品列表) +- 商品详情页(商品信息、SKU选择、评价、推荐) +- 购物车页 +- 订单确认页 +- 订单列表页 +- 订单详情页 +- 个人中心(信息、订单、地址、优惠券、收藏) +- 搜索页 +- 评价页 + +#### 1.3.2 商家端 (Merchant) +- 商家中心首页(数据统计、订单概览) +- 商品管理(列表、添加、编辑) +- 订单管理(列表、详情、发货) +- 店铺设置 +- 数据统计 + +#### 1.3.3 配送端 (Delivery) +- 配送中心首页(待接单、配送中、已完成) +- 订单详情 +- 配送路线 + +#### 1.3.4 管理后台 (Admin) +- 登录页 +- 首页(数据概览) +- 商品管理 +- 订单管理 +- 用户管理 +- 营销管理 +- 系统设置 + +--- + +## 二、架构映射 (Architecture Mapping) + +### 2.1 前端架构映射:Vue/UniApp → uvue + +#### 2.1.1 技术栈对比 + +| CRMEB 原技术 | 目标技术 (uvue) | 说明 | +| ------------ | ------------------------------ | -------------- | +| Vue 2/3 | ` +``` + +--- + +## 四、验证清单 (Verification Checklist) + +### 4.1 功能验证 + +#### 4.1.1 用户系统 +- [ ] 用户注册(手机号、邮箱) +- [ ] 用户登录(密码、验证码) +- [ ] 用户信息修改 +- [ ] 地址添加/编辑/删除 +- [ ] 默认地址设置 + +#### 4.1.2 商品系统 +- [ ] 商品列表展示(分页、筛选、排序) +- [ ] 商品详情展示 +- [ ] 商品搜索 +- [ ] 分类导航 +- [ ] SKU 选择 +- [ ] 商家商品管理(增删改查) + +#### 4.1.3 购物车 +- [ ] 添加商品到购物车 +- [ ] 修改购物车商品数量 +- [ ] 删除购物车商品 +- [ ] 购物车商品选择 +- [ ] 购物车价格计算 + +#### 4.1.4 订单系统 +- [ ] 订单确认页(地址、优惠券、运费) +- [ ] 创建订单 +- [ ] 订单支付 +- [ ] 订单列表(状态筛选) +- [ ] 订单详情 +- [ ] 订单取消 +- [ ] 订单退款 + +#### 4.1.5 营销系统 +- [ ] 优惠券列表 +- [ ] 优惠券领取 +- [ ] 优惠券使用 +- [ ] 优惠券过期处理 + +### 4.2 权限验证 + +- [ ] 用户只能查看/修改自己的数据 +- [ ] 商家只能管理自己的商品和订单 +- [ ] 管理员可以查看所有数据 +- [ ] 未登录用户只能查看公开商品 +- [ ] RLS 策略正确生效 + +### 4.3 性能验证 + +- [ ] 商品列表加载速度(< 2秒) +- [ ] 图片加载优化(懒加载) +- [ ] 分页加载流畅 +- [ ] 数据库查询性能(索引优化) + +### 4.4 安全验证 + +- [ ] SQL 注入防护(参数化查询) +- [ ] XSS 防护(数据转义) +- [ ] 权限验证(RLS) +- [ ] 敏感数据加密 + +### 4.5 兼容性验证 + +- [ ] Android 平台 +- [ ] iOS 平台(如支持) +- [ ] Web 平台(如支持) +- [ ] 不同屏幕尺寸适配 + +--- + +## 五、差异清单 (Difference List) + +### 5.1 允许的差异 + +1. **UI 风格差异** + - 可以重新设计 UI,不要求与 CRMEB 完全一致 + - 遵循现代 UI 设计规范 + +2. **交互细节差异** + - 动画效果可以不同 + - 页面布局可以优化 + +3. **非核心功能差异** + - 某些营销活动(如砍价、拼团)可以简化或延后实现 + - 数据统计功能可以简化 + +### 5.2 不允许的差异 + +1. **核心业务流程** + - 订单流程必须完整(创建→支付→发货→收货→完成) + - 库存扣减逻辑必须正确 + - 价格计算必须准确 + +2. **数据一致性** + - 订单金额必须准确 + - 库存数据必须准确 + - 用户余额必须准确 + +3. **权限控制** + - 用户权限必须正确 + - 数据访问权限必须正确 + +--- + +## 六、反抄袭自证 + +### 6.1 参考资料说明 + +本文档仅参考以下公开资料: + +1. **CRMEB 项目 README.md** + - 仅用于了解项目功能模块和业务范围 + - 未参考任何 PHP 源码实现 + +2. **Supabase 官方文档** + - https://supabase.com/docs + - 用于了解 Supabase API 使用方式 + +3. **uni-app x 官方文档** + - https://uniapp.dcloud.net.cn/uni-app-x/ + - 用于了解 uvue 语法和规范 + +4. **PostgreSQL 官方文档** + - https://www.postgresql.org/docs/ + - 用于了解数据库功能和语法 + +### 6.2 实现方式说明 + +1. **数据库设计** + - 基于业务需求独立设计表结构 + - 使用 `ml_` 前缀区分商城模块 + - 参考现有 `doc_mall/database/` 中的设计 + +2. **前端实现** + - 使用 uvue 语法独立编写页面 + - 通过 `components/supadb` 调用 Supabase API + - 不复制任何 Vue 组件代码 + +3. **后端实现** + - 使用 Supabase RLS + Edge Functions + - 不编写任何 PHP 代码 + - 业务逻辑通过数据库函数和触发器实现 + +### 6.3 代码原创性声明 + +- 所有代码均为基于功能规格的独立实现 +- 未复制 CRMEB 项目的任何源码 +- 未复制任何第三方项目的实现代码 +- 仅参考公开 API 文档和规范 + +--- + +## 七、参考资料列表 + +### 7.1 官方文档 + +1. **Supabase** + - REST API: https://supabase.com/docs/reference/javascript/introduction + - Auth: https://supabase.com/docs/guides/auth + - RLS: https://supabase.com/docs/guides/auth/row-level-security + - Storage: https://supabase.com/docs/guides/storage + +2. **uni-app x** + - 概述: https://uniapp.dcloud.net.cn/uni-app-x/ + - uvue: https://uniapp.dcloud.net.cn/uni-app-x/component/ + - UTS: https://uniapp.dcloud.net.cn/uni-app-x/uts/ + +3. **PostgreSQL** + - 官方文档: https://www.postgresql.org/docs/ + - JSONB: https://www.postgresql.org/docs/current/datatype-json.html + +### 7.2 项目内部文档 + +1. `doc_mall/MODULE_ANALYSIS.md` - 模块分析报告 +2. `doc_mall/database/` - 数据库设计文档 +3. `components/supadb/SIMPLIFIED_API_GUIDE.md` - Supabase API 使用指南 +4. `types/mall-types.uts` - 类型定义 + +--- + +## 八、总结 + +本文档基于 **Clean-Room 重构原则**,通过分析 CRMEB 项目的功能规格,制定了完整的重构计划: + +1. **功能规格提取**:明确了所有核心业务模块的功能需求 +2. **架构映射**:完成了 Vue→uvue、PHP→Supabase 的技术栈映射 +3. **实现计划**:制定了详细的开发里程碑和目录结构 +4. **验证清单**:提供了完整的测试验证标准 + +所有实现将基于功能规格独立开发,不复制任何源码,确保代码的原创性和合规性。 + +--- + +**文档版本**: v1.0 +**创建时间**: 2025-01-XX +**状态**: ✅ 待实施 diff --git a/docs/UI_DESIGN_GUIDELINES.md b/docs/UI_DESIGN_GUIDELINES.md new file mode 100644 index 00000000..54fe54bd --- /dev/null +++ b/docs/UI_DESIGN_GUIDELINES.md @@ -0,0 +1,660 @@ +# UI 设计规范文档 + +## 📋 文档说明 + +本文档基于 **CRMEB 项目的 UI 设计理念和交互模式**,提取设计思想、布局方式、组件模式等,为项目提供统一的 UI 设计规范。**所有实现均为原创,不复制任何源码**。 + +### 设计原则 + +1. **参考不复制**:仅参考 CRMEB 的设计理念,不复制任何代码 +2. **现代简约**:遵循现代电商 UI 设计趋势 +3. **用户体验优先**:注重交互流畅性和视觉舒适度 +4. **一致性**:保持整体设计风格统一 + +--- + +## 一、设计风格分析 + +### 1.1 CRMEB 设计特点 + +基于对 CRMEB 项目的分析,提取以下设计特点: + +#### 1.1.1 视觉风格 +- **色彩**:以红色系为主色调(#E93323),体现电商活力 +- **圆角**:大量使用圆角设计(20rpx-24rpx),柔和现代 +- **阴影**:轻微阴影效果,增强层次感 +- **间距**:宽松的间距设计,提升可读性 + +#### 1.1.2 布局特点 +- **卡片式设计**:信息以卡片形式呈现,清晰分组 +- **瀑布流布局**:商品列表采用瀑布流,提升浏览体验 +- **模块化设计**:首页采用模块化组件,灵活配置 +- **响应式适配**:适配不同屏幕尺寸 + +#### 1.1.3 交互特点 +- **流畅动画**:页面切换和操作有平滑过渡 +- **即时反馈**:操作有明确的视觉反馈 +- **加载状态**:优雅的加载动画和骨架屏 +- **错误处理**:友好的错误提示和空状态 + +--- + +## 二、颜色系统 + +### 2.1 主色调 + +基于 CRMEB 的设计理念,定义以下颜色系统: + +```scss +// 主题色 +$theme-primary: #FF4D4F; // 主色(红色系,体现电商活力) +$theme-primary-light: #FF7875; // 主色浅色 +$theme-primary-dark: #CF1322; // 主色深色 + +// 渐变色 +$gradient-start: #FF4D4F; // 渐变起始色 +$gradient-end: #FF7A45; // 渐变结束色 + +// 功能色 +$success: #52C41A; // 成功色 +$warning: #FAAD14; // 警告色 +$error: #FF4D4F; // 错误色 +$info: #1890FF; // 信息色 +``` + +### 2.2 中性色 + +```scss +// 文字颜色 +$text-primary: #111111; // 主要文字 +$text-secondary: #333333; // 次要文字 +$text-tertiary: #666666; // 辅助文字 +$text-disabled: #999999; // 禁用文字 +$text-placeholder: #CCCCCC; // 占位文字 + +// 背景颜色 +$bg-primary: #FFFFFF; // 主背景 +$bg-secondary: #F7F8FA; // 次背景 +$bg-tertiary: #F5F5F5; // 三级背景 +$bg-hover: #F1F1F1; // 悬停背景 + +// 边框颜色 +$border-color: rgba(0, 0, 0, 0.06); // 边框色 +$border-color-light: rgba(0, 0, 0, 0.08); // 浅边框 +``` + +### 2.3 使用规范 + +- **主色**:用于按钮、链接、重要信息 +- **渐变色**:用于主要操作按钮、强调元素 +- **中性色**:用于文字、背景、边框 +- **功能色**:用于状态提示、警告信息 + +--- + +## 三、布局规范 + +### 3.1 间距系统 + +```scss +// 基础间距单位(基于 rpx) +$spacing-xs: 8rpx; // 极小间距 +$spacing-sm: 16rpx; // 小间距 +$spacing-md: 24rpx; // 中等间距 +$spacing-lg: 32rpx; // 大间距 +$spacing-xl: 48rpx; // 超大间距 + +// 页面边距 +$page-padding: 24rpx; // 页面左右边距 +$section-margin: 20rpx; // 模块间距 +``` + +### 3.2 圆角规范 + +```scss +$radius-sm: 8rpx; // 小圆角 +$radius-md: 12rpx; // 中等圆角 +$radius-lg: 20rpx; // 大圆角 +$radius-xl: 24rpx; // 超大圆角 +$radius-circle: 50%; // 圆形 +``` + +### 3.3 阴影规范 + +```scss +// 轻微阴影(卡片) +$shadow-sm: 0 2rpx 8rpx rgba(0, 0, 0, 0.06); + +// 中等阴影(悬浮) +$shadow-md: 0 4rpx 16rpx rgba(0, 0, 0, 0.08); + +// 大阴影(弹窗) +$shadow-lg: 0 8rpx 24rpx rgba(0, 0, 0, 0.12); +``` + +### 3.4 布局模式 + +#### 3.4.1 卡片布局 +- **特点**:信息以卡片形式呈现,有圆角和阴影 +- **应用**:商品卡片、订单卡片、信息卡片 +- **实现**:使用 `view` 容器,添加圆角和阴影样式 + +#### 3.4.2 列表布局 +- **特点**:信息以列表形式呈现,清晰有序 +- **应用**:订单列表、地址列表、设置列表 +- **实现**:使用 `view` 容器,添加分割线 + +#### 3.4.3 网格布局 +- **特点**:信息以网格形式呈现,整齐排列 +- **应用**:商品网格、分类网格、功能入口 +- **实现**:使用 `view` 容器,配合 flex 布局 + +--- + +## 四、组件设计规范 + +### 4.1 按钮组件 + +#### 4.1.1 主要按钮(Primary) +```scss +// 样式特点 +- 背景:渐变色(#FF4D4F → #FF7A45) +- 文字:白色 +- 圆角:18rpx +- 高度:92rpx +- 阴影:0 16rpx 32rpx rgba(255, 77, 79, 0.24) +``` + +#### 4.1.2 次要按钮(Secondary) +```scss +// 样式特点 +- 背景:白色 +- 文字:主题色 +- 边框:1rpx solid 主题色 +- 圆角:18rpx +- 高度:92rpx +``` + +#### 4.1.3 文字按钮(Text) +```scss +// 样式特点 +- 背景:透明 +- 文字:主题色 +- 无边框 +- 无圆角 +``` + +### 4.2 输入框组件 + +#### 4.2.1 标准输入框 +```scss +// 样式特点 +- 背景:#F6F7F9 +- 边框:2rpx solid rgba(0, 0, 0, 0.06) +- 圆角:14rpx +- 高度:84rpx +- 内边距:0 14rpx +- 错误状态:边框变红,背景变浅红 +``` + +### 4.3 商品卡片组件 + +#### 4.3.1 商品列表卡片 +```scss +// 布局特点 +- 图片:180rpx × 180rpx,圆角 20rpx +- 信息:商品名称、价格、销量 +- 间距:左右 30rpx,上下 20rpx +- 活动标签:左上角显示(秒杀/砍价/拼团) +``` + +#### 4.3.2 商品网格卡片 +```scss +// 布局特点 +- 图片:宽高比 1:1,圆角 20rpx +- 信息:商品名称、价格、原价(删除线) +- 间距:网格间距 16rpx +- 两列或三列布局 +``` + +### 4.4 订单卡片组件 + +#### 4.4.1 订单列表卡片 +```scss +// 布局特点 +- 背景:白色 +- 圆角:20rpx +- 内边距:24rpx +- 阴影:轻微阴影 +- 内容:订单号、商品信息、价格、状态 +``` + +### 4.5 导航栏组件 + +#### 4.5.1 顶部导航栏 +```scss +// 样式特点 +- 背景:白色或透明(滚动时变化) +- 高度:88rpx(含状态栏) +- 文字:主题色或白色 +- 返回按钮:左侧 +- 搜索框:居中(可选) +``` + +### 4.6 标签组件 + +#### 4.6.1 活动标签 +```scss +// 样式特点 +- 背景:主题色或渐变色 +- 文字:白色 +- 圆角:4rpx 或 圆形 +- 位置:商品图片左上角 +- 文字:秒杀/砍价/拼团 +``` + +--- + +## 五、交互模式 + +### 5.1 页面切换 + +- **动画**:使用 uni-app 的页面切换动画 +- **返回**:支持滑动返回(iOS 风格) +- **加载**:页面切换时显示加载状态 + +### 5.2 数据加载 + +- **骨架屏**:数据加载时显示骨架屏 +- **下拉刷新**:列表页面支持下拉刷新 +- **上拉加载**:列表页面支持上拉加载更多 +- **加载状态**:显示加载动画和提示文字 + +### 5.3 操作反馈 + +- **点击反馈**:使用 `hover-class` 提供点击反馈 +- **成功提示**:使用 `uni.showToast` 显示成功提示 +- **错误提示**:使用 `uni.showModal` 显示错误信息 +- **加载提示**:使用 `uni.showLoading` 显示加载状态 + +### 5.4 表单交互 + +- **实时验证**:输入时实时验证,显示错误信息 +- **提交反馈**:提交时显示加载状态,防止重复提交 +- **成功跳转**:提交成功后自动跳转或提示 + +--- + +## 六、页面设计规范 + +### 6.1 首页设计 + +#### 6.1.1 布局结构 +``` +┌─────────────────────────┐ +│ 顶部搜索栏(可选) │ +├─────────────────────────┤ +│ 轮播图(Banner) │ +├─────────────────────────┤ +│ 分类导航(横向滚动) │ +├─────────────────────────┤ +│ 营销模块(可选) │ +│ - 秒杀/拼团/砍价 │ +├─────────────────────────┤ +│ 商品推荐 │ +│ - 瀑布流布局 │ +└─────────────────────────┘ +``` + +#### 6.1.2 设计要点 +- **模块化**:首页由多个模块组成,可配置 +- **瀑布流**:商品列表采用瀑布流布局 +- **懒加载**:图片和内容懒加载,提升性能 +- **下拉刷新**:支持下拉刷新 + +### 6.2 商品详情页 + +#### 6.2.1 布局结构 +``` +┌─────────────────────────┐ +│ 商品轮播图 │ +├─────────────────────────┤ +│ 商品信息 │ +│ - 价格(突出显示) │ +│ - 标题 │ +│ - 标签 │ +├─────────────────────────┤ +│ 优惠信息 │ +│ - 优惠券 │ +│ - 活动 │ +├─────────────────────────┤ +│ 规格选择(弹窗) │ +├─────────────────────────┤ +│ 商品详情(Tab切换) │ +│ - 详情 │ +│ - 评价 │ +│ - 推荐 │ +├─────────────────────────┤ +│ 底部操作栏(固定) │ +│ - 购物车/立即购买 │ +└─────────────────────────┘ +``` + +#### 6.2.2 设计要点 +- **图片展示**:轮播图展示商品图片 +- **价格突出**:价格使用大字号和主题色 +- **规格选择**:点击规格弹出选择弹窗 +- **底部固定**:操作按钮固定在底部 + +### 6.3 购物车页面 + +#### 6.3.1 布局结构 +``` +┌─────────────────────────┐ +│ 商品列表 │ +│ ┌───────────────────┐ │ +│ │ ☑ 商品卡片 │ │ +│ │ 数量选择 │ │ +│ └───────────────────┘ │ +├─────────────────────────┤ +│ 底部结算栏(固定) │ +│ - 全选 │ +│ - 合计金额 │ +│ - 结算按钮 │ +└─────────────────────────┘ +``` + +#### 6.3.2 设计要点 +- **选择状态**:每个商品可单独选择 +- **数量编辑**:支持增减数量 +- **价格计算**:实时计算总价 +- **底部固定**:结算栏固定在底部 + +### 6.4 订单确认页 + +#### 6.4.1 布局结构 +``` +┌─────────────────────────┐ +│ 收货地址(可选) │ +├─────────────────────────┤ +│ 商品列表 │ +├─────────────────────────┤ +│ 优惠券选择(可选) │ +├─────────────────────────┤ +│ 配送方式 │ +├─────────────────────────┤ +│ 备注信息 │ +├─────────────────────────┤ +│ 价格明细 │ +│ - 商品总额 │ +│ - 运费 │ +│ - 优惠金额 │ +│ - 实付金额 │ +├─────────────────────────┤ +│ 提交订单按钮(固定) │ +└─────────────────────────┘ +``` + +### 6.5 个人中心页 + +#### 6.5.1 布局结构 +``` +┌─────────────────────────┐ +│ 用户信息卡片 │ +│ - 头像 │ +│ - 昵称 │ +│ - 会员信息 │ +├─────────────────────────┤ +│ 订单状态(快捷入口) │ +│ - 待付款/待发货等 │ +├─────────────────────────┤ +│ 功能菜单 │ +│ - 我的订单 │ +│ - 我的地址 │ +│ - 我的优惠券 │ +│ - 设置 │ +└─────────────────────────┘ +``` + +--- + +## 七、实现指南 + +### 7.1 样式变量定义 + +创建 `styles/variables.uts` 文件: + +```typescript +// 颜色变量 +export const THEME_PRIMARY = '#FF4D4F' +export const THEME_GRADIENT_START = '#FF4D4F' +export const THEME_GRADIENT_END = '#FF7A45' + +// 间距变量 +export const SPACING_XS = '8rpx' +export const SPACING_SM = '16rpx' +export const SPACING_MD = '24rpx' +export const SPACING_LG = '32rpx' + +// 圆角变量 +export const RADIUS_SM = '8rpx' +export const RADIUS_MD = '12rpx' +export const RADIUS_LG = '20rpx' +``` + +### 7.2 通用样式类 + +创建 `styles/common.uvue` 或使用 ` +``` + +--- + +## 八、最佳实践 + +### 8.1 性能优化 + +1. **图片优化** + - 使用合适的图片尺寸 + - 启用图片懒加载 + - 使用 WebP 格式(如支持) + +2. **列表优化** + - 使用虚拟列表(长列表) + - 分页加载数据 + - 避免不必要的重新渲染 + +3. **动画优化** + - 使用 CSS 动画而非 JS 动画 + - 避免过度动画 + - 使用 `transform` 和 `opacity` 做动画 + +### 8.2 可访问性 + +1. **文字大小** + - 最小字号:24rpx + - 主要文字:28rpx-32rpx + - 标题文字:36rpx-40rpx + +2. **点击区域** + - 最小点击区域:88rpx × 88rpx + - 按钮高度:至少 80rpx + +3. **颜色对比** + - 文字与背景对比度:至少 4.5:1 + - 重要信息使用高对比度 + +### 8.3 响应式设计 + +1. **屏幕适配** + - 使用 rpx 单位 + - 使用 flex 布局 + - 适配不同屏幕尺寸 + +2. **横竖屏适配** + - 考虑横屏布局 + - 使用媒体查询(如需要) + +--- + +## 九、设计资源 + +### 9.1 图标系统 + +- **图标库**:使用 uni-app 内置图标或自定义图标 +- **图标大小**:24rpx、32rpx、48rpx +- **图标颜色**:主题色或中性色 + +### 9.2 字体规范 + +- **字体家族**:系统默认字体 +- **字重**:Regular(400)、Medium(500)、Bold(600) +- **字号**:24rpx、28rpx、32rpx、36rpx、40rpx + +--- + +## 十、总结 + +本文档基于 CRMEB 项目的设计理念,提取了以下核心要点: + +1. **设计风格**:现代简约,以红色系为主色调 +2. **布局方式**:卡片式、列表式、网格式 +3. **交互模式**:流畅动画、即时反馈、友好提示 +4. **组件设计**:统一的组件样式和交互规范 + +所有实现均为原创,遵循现代 UI 设计最佳实践,确保用户体验和视觉一致性。 + +--- + +**文档版本**: v1.0 +**创建时间**: 2025-01-XX +**状态**: ✅ 待实施 diff --git a/UNI_APP_X_MIGRATION.md b/docs/UNI_APP_X_MIGRATION.md similarity index 100% rename from UNI_APP_X_MIGRATION.md rename to docs/UNI_APP_X_MIGRATION.md diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..c496dbc9 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,34 @@ +{ + "name": "mall", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "echarts": "^6.0.0" + } + }, + "node_modules/echarts": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-6.0.0.tgz", + "integrity": "sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==", + "dependencies": { + "tslib": "2.3.0", + "zrender": "6.0.0" + } + }, + "node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + }, + "node_modules/zrender": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-6.0.0.tgz", + "integrity": "sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==", + "dependencies": { + "tslib": "2.3.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..aabad938 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "echarts": "^6.0.0" + } +} diff --git a/pages.json b/pages.json index fed5ab00..559492dd 100644 --- a/pages.json +++ b/pages.json @@ -83,6 +83,12 @@ "navigationBarTitleText": "数据分析", "navigationStyle": "custom" } + }, + { + "path": "pages/mall/analytics/test/test-connection", + "style": { + "navigationBarTitleText": "Supabase 连接测试" + } } ], "subPackages": [ @@ -207,6 +213,10 @@ { "name": "登录页", "path": "pages/user/login" + }, + { + "name": "数据分析端首页", + "path": "pages/mall/analytics/index" } ] } diff --git a/pages/mall/analytics/index.uvue b/pages/mall/analytics/index.uvue index c9b161ea..2f0ce74e 100644 --- a/pages/mall/analytics/index.uvue +++ b/pages/mall/analytics/index.uvue @@ -1,1147 +1,734 @@ - diff --git a/pages/mall/analytics/profile.uvue b/pages/mall/analytics/profile.uvue index 506ae8fa..f0da805e 100644 --- a/pages/mall/analytics/profile.uvue +++ b/pages/mall/analytics/profile.uvue @@ -428,7 +428,7 @@ function changeTrendPeriod(period: string) { function viewReportDetail(reportId: string) { uni.navigateTo({ - url: `/pages/mall/analytics/report-detail?id=${reportId}` + url: `/pages/mall/analytics/report-detail?reportId=${reportId}` }) } diff --git a/pages/mall/analytics/report-detail.uvue b/pages/mall/analytics/report-detail.uvue index b8c3cf3c..1e163a2c 100644 --- a/pages/mall/analytics/report-detail.uvue +++ b/pages/mall/analytics/report-detail.uvue @@ -248,9 +248,18 @@ export default { } }, onLoad(options: any) { - const reportId = options.reportId as string + // 兼容两种参数名:reportId 和 id + const reportId = (options.reportId || options.id) as string if (reportId) { this.loadReportDetail(reportId) + } else { + uni.showToast({ + title: '缺少报表ID', + icon: 'none' + }) + setTimeout(() => { + uni.navigateBack() + }, 1500) } }, methods: { diff --git a/pages/mall/analytics/test/README.md b/pages/mall/analytics/test/README.md new file mode 100644 index 00000000..268e76c7 --- /dev/null +++ b/pages/mall/analytics/test/README.md @@ -0,0 +1,181 @@ +# 数据分析实时大屏 - 测试数据说明 + +本目录包含用于测试数据分析实时大屏功能的 SQL 脚本和测试数据。 + +## 文件说明 + +### 1. `01_create_tables.sql` +创建所需的数据表结构,包括: +- `orders` - 订单表 +- `user_sessions` - 用户会话表 +- `users` - 用户表 +- `products` - 商品表(可选) +- `order_items` - 订单商品关联表(可选) +- `page_views` - 访问日志表(可选) + +**执行顺序:** 首先执行此文件创建表结构 + +### 2. `02_insert_test_data.sql` +插入测试数据,包括: +- 8个测试用户 +- 5个在线用户会话(最近5分钟内有活动) +- 15个今日订单(用于计算实时GMV和订单数) +- 10个昨日同时段订单(用于计算增长率) +- 15条访问日志(用于转化率计算) + +**执行顺序:** 在创建表后执行此文件插入测试数据 + +### 3. `03_test_queries.sql` +包含各种测试查询,用于验证数据计算逻辑: +- 实时GMV查询 +- 在线用户查询 +- 转化率查询 +- 综合实时大屏数据查询 +- 数据验证查询 + +**执行顺序:** 在插入测试数据后执行此文件验证数据 + +## 使用方法 + +### 方式 1: 通过 Supabase Dashboard(推荐) + +1. **访问 Dashboard** + ``` + http://192.168.1.63:8000 + 或 + http://192.168.1.63:3000 (Studio 默认端口) + ``` + +2. **登录** + - 用户名:`supabase` + - 密码:`D4ce5p8YBpfYzEoDGZ_7MzehZcWrdCNyDEj_VSUBmOw` + +3. **打开 SQL Editor** + - 在左侧菜单找到 "SQL Editor" + - 点击 "New Query" + +4. **执行脚本** + - 复制 `01_create_tables.sql` 的内容,粘贴并执行 + - 复制 `02_insert_test_data.sql` 的内容,粘贴并执行 + - (可选)复制 `03_test_queries.sql` 的内容,验证数据 + +### 方式 2: 使用命令行(PostgreSQL) + +```bash +# 连接到内网 Supabase 数据库 +psql -h 192.168.1.63 -p 5432 -U postgres -d postgres + +# 输入密码:yxyHINygZMLSq9jLddrZQBB-CoyGHSF5DwlwWmbrYXc + +# 执行 SQL 文件(需要完整路径) +\i D:/datas/hfkj/mall/pages/mall/analytics/test/01_create_tables.sql +\i D:/datas/hfkj/mall/pages/mall/analytics/test/02_insert_test_data.sql +\i D:/datas/hfkj/mall/pages/mall/analytics/test/03_test_queries.sql +``` + +### 方式 3: 使用图形工具(DBeaver / pgAdmin) + +1. **创建连接** + - 主机:`192.168.1.63` + - 端口:`5432` + - 数据库:`postgres` + - 用户名:`postgres` + - 密码:`yxyHINygZMLSq9jLddrZQBB-CoyGHSF5DwlwWmbrYXc` + +2. **执行 SQL** + - 打开 SQL 编辑器 + - 复制 SQL 文件内容并执行 + +**详细说明请查看:`SQL_USAGE_GUIDE.md`** + +## 测试数据说明 + +### 实时GMV测试数据 +- **今日订单总数:** 15笔 +- **今日GMV:** 约 3,500 元(根据订单金额累加) +- **昨日同时段订单:** 10笔 +- **昨日同时段GMV:** 约 2,200 元 +- **预期增长率:** 约 59%((3500-2200)/2200 * 100) + +### 实时订单测试数据 +- **今日订单数:** 15笔 +- **昨日同时段订单数:** 10笔 +- **预期增长率:** 50%((15-10)/10 * 100) + +### 在线用户测试数据 +- **最近5分钟内有活动的用户:** 5个 +- 这些用户会在实时大屏中显示为"在线用户" + +### 转化率测试数据 +- **今日访问用户数:** 约 10-15个(从 user_sessions 表统计) +- **今日下单用户数:** 约 8个(从 orders 表去重统计) +- **预期转化率:** 约 53-80%(根据实际数据计算) + +## 注意事项 + +1. **时间依赖** + - 测试数据使用了 `NOW()` 和相对时间(如 `INTERVAL '1 hour'`) + - 每次执行时,数据的时间戳会基于当前时间生成 + - 建议在测试前先清空相关表的数据(谨慎操作) + +2. **数据冲突** + - 脚本使用了 `ON CONFLICT DO NOTHING` 或 `ON CONFLICT DO UPDATE` + - 可以多次执行而不会产生重复数据 + - 如需重新生成数据,请先清空表 + +3. **状态值** + - 订单状态:`2` 表示已支付/已完成 + - 用户会话:`is_active = true` 表示活跃会话 + +4. **UUID 格式** + - 所有 ID 使用 UUID 格式 + - 测试数据使用了固定的 UUID 便于识别 + +## 清理测试数据 + +如果需要清理测试数据,可以执行: + +```sql +-- 谨慎操作:清空测试数据 +TRUNCATE TABLE orders, user_sessions, users, order_items, page_views CASCADE; +``` + +或者删除特定时间范围的数据: + +```sql +-- 删除今日的测试订单 +DELETE FROM orders WHERE created_at >= DATE_TRUNC('day', NOW()); + +-- 删除测试用户会话 +DELETE FROM user_sessions WHERE created_at >= DATE_TRUNC('day', NOW()); +``` + +## 验证实时大屏功能 + +执行完测试数据后,在数据分析页面应该能看到: + +1. **实时GMV:** 约 ¥3,500(根据实际订单金额) +2. **实时订单:** 15笔 +3. **在线用户:** 5人 +4. **转化率:** 约 50-80%(根据实际计算) + +增长率会根据昨日同时段的数据自动计算。 + +## 问题排查 + +如果实时大屏显示异常,可以: + +1. 执行 `03_test_queries.sql` 中的查询验证数据 +2. 检查订单状态是否为 `2`(已支付) +3. 检查时间范围是否正确(今日 vs 昨日同时段) +4. 检查用户会话的 `last_active_at` 是否在最近5分钟内 +5. 查看浏览器控制台的错误信息 + +## 扩展测试数据 + +如果需要更多测试数据,可以: + +1. 修改 `02_insert_test_data.sql` 中的 INSERT 语句 +2. 调整订单金额、数量和时间分布 +3. 添加更多用户和会话数据 +4. 使用循环生成大量测试数据(注意性能) diff --git a/pages/mall/analytics/test/SQL_USAGE_GUIDE.md b/pages/mall/analytics/test/SQL_USAGE_GUIDE.md new file mode 100644 index 00000000..fff1ac0f --- /dev/null +++ b/pages/mall/analytics/test/SQL_USAGE_GUIDE.md @@ -0,0 +1,304 @@ +# SQL 测试脚本使用指南 + +本指南说明如何在内网 Supabase 环境中执行测试 SQL 脚本。 + +## 📋 目录结构 + +``` +pages/mall/analytics/test/ +├── 01_create_tables.sql # 创建表结构 +├── 02_insert_test_data.sql # 插入测试数据 +├── 03_test_queries.sql # 测试查询 +├── 04_cleanup.sql # 清理数据 +└── SQL_USAGE_GUIDE.md # 本指南 +``` + +## 🚀 执行方式 + +### 方式 1: 通过 Supabase Dashboard(推荐) + +如果您的内网 Supabase 有 Dashboard 界面: + +1. **访问 Dashboard** + ``` + http://192.168.1.63:8000 + 或 + http://192.168.1.63:3000 (Studio 默认端口) + ``` + +2. **登录** + - 用户名:`supabase`(根据您的配置) + - 密码:`D4ce5p8YBpfYzEoDGZ_7MzehZcWrdCNyDEj_VSUBmOw` + +3. **打开 SQL Editor** + - 在左侧菜单找到 "SQL Editor" 或 "SQL" + - 点击 "New Query" + +4. **执行脚本** + - 复制 `01_create_tables.sql` 的内容 + - 粘贴到 SQL Editor + - 点击 "Run" 或按 `Ctrl+Enter` + - 等待执行完成 + +5. **依次执行其他脚本** + - 执行 `02_insert_test_data.sql`(插入测试数据) + - 执行 `03_test_queries.sql`(验证数据,可选) + +### 方式 2: 通过 PostgreSQL 客户端(psql) + +如果 Dashboard 不可用,可以直接连接 PostgreSQL: + +1. **连接数据库** + ```bash + # 使用 psql 连接 + psql -h 192.168.1.63 -p 5432 -U postgres -d postgres + + # 输入密码(根据您的配置) + # POSTGRES_PASSWORD=yxyHINygZMLSq9jLddrZQBB-CoyGHSF5DwlwWmbrYXc + ``` + +2. **执行 SQL 文件** + ```sql + -- 在 psql 中执行 + \i /path/to/01_create_tables.sql + \i /path/to/02_insert_test_data.sql + \i /path/to/03_test_queries.sql + ``` + + 或者直接复制粘贴 SQL 内容到 psql 中执行。 + +### 方式 3: 通过 DBeaver / pgAdmin 等图形工具 + +1. **创建新连接** + - 主机:`192.168.1.63` + - 端口:`5432` + - 数据库:`postgres` + - 用户名:`postgres` + - 密码:`yxyHINygZMLSq9jLddrZQBB-CoyGHSF5DwlwWmbrYXc` + +2. **执行 SQL** + - 打开 SQL 编辑器 + - 复制 SQL 文件内容 + - 执行脚本 + +### 方式 4: 通过 HTTP API(程序化执行) + +使用 Supabase REST API 执行 SQL(需要 service_role key): + +```javascript +// 注意:这种方式需要 Supabase 的 SQL 执行功能 +// 通常不推荐,因为安全风险较高 +const response = await fetch('http://192.168.1.63:8000/rest/v1/rpc/exec_sql', { + method: 'POST', + headers: { + 'apikey': 'YOUR_SERVICE_ROLE_KEY', + 'Authorization': 'Bearer YOUR_SERVICE_ROLE_KEY', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + sql: 'SELECT * FROM users LIMIT 1;' + }) +}) +``` + +## 📝 执行顺序 + +**重要:必须按顺序执行!** + +1. ✅ **第一步:创建表结构** + ```sql + -- 执行 01_create_tables.sql + -- 这会创建所有需要的表和索引 + ``` + +2. ✅ **第二步:插入测试数据** + ```sql + -- 执行 02_insert_test_data.sql + -- 这会插入测试用户、订单、会话等数据 + ``` + +3. ✅ **第三步:验证数据(可选)** + ```sql + -- 执行 03_test_queries.sql + -- 验证数据是否正确插入,查看统计信息 + ``` + +4. ⚠️ **清理数据(需要时)** + ```sql + -- 执行 04_cleanup.sql + -- 谨慎使用:会删除测试数据 + ``` + +## 🔍 验证执行结果 + +### 检查表是否创建成功 + +```sql +-- 查看所有表 +SELECT table_name +FROM information_schema.tables +WHERE table_schema = 'public' +ORDER BY table_name; + +-- 应该看到: +-- orders +-- user_sessions +-- users +-- products (可选) +-- order_items (可选) +-- page_views (可选) +``` + +### 检查数据是否插入成功 + +```sql +-- 检查用户数量 +SELECT COUNT(*) FROM users; +-- 应该返回 8 + +-- 检查订单数量 +SELECT COUNT(*) FROM orders WHERE created_at >= DATE_TRUNC('day', NOW()); +-- 应该返回 15(今日订单) + +-- 检查在线用户 +SELECT COUNT(*) FROM user_sessions +WHERE last_active_at >= NOW() - INTERVAL '5 minutes' AND is_active = true; +-- 应该返回 5 +``` + +### 检查实时大屏数据 + +```sql +-- 执行 03_test_queries.sql 中的综合查询 +-- 应该能看到: +-- - 实时GMV: 约 3,500 元 +-- - 实时订单: 15 笔 +-- - 在线用户: 5 人 +-- - 转化率: 约 50-80% +``` + +## ⚠️ 注意事项 + +### 1. 权限问题 + +如果遇到权限错误: +```sql +-- 确保 postgres 用户有足够权限 +GRANT ALL PRIVILEGES ON DATABASE postgres TO postgres; +GRANT ALL PRIVILEGES ON SCHEMA public TO postgres; +``` + +### 2. 表已存在 + +如果表已存在,脚本会使用 `CREATE TABLE IF NOT EXISTS`,不会报错。 +但如果需要重新创建: +```sql +-- 先删除表(谨慎操作) +DROP TABLE IF EXISTS order_items CASCADE; +DROP TABLE IF EXISTS page_views CASCADE; +DROP TABLE IF EXISTS user_sessions CASCADE; +DROP TABLE IF EXISTS orders CASCADE; +DROP TABLE IF EXISTS users CASCADE; +DROP TABLE IF EXISTS products CASCADE; +``` + +### 3. 时间依赖 + +测试数据使用 `NOW()` 函数,每次执行都会基于当前时间生成。 +- 今日订单:基于当前日期 +- 昨日订单:当前时间往前推 24 小时 +- 在线用户:最近 5 分钟内有活动 + +### 4. UUID 冲突 + +如果重复执行插入脚本,由于使用了 `ON CONFLICT DO NOTHING`,不会产生重复数据。 +但如果需要重新插入,先执行清理脚本。 + +## 🐛 常见问题 + +### Q1: 连接被拒绝 +``` +Error: connection refused +``` +**解决:** +- 检查 Supabase 服务是否运行 +- 检查防火墙设置 +- 确认端口 5432 是否开放 + +### Q2: 认证失败 +``` +Error: password authentication failed +``` +**解决:** +- 确认密码是否正确:`yxyHINygZMLSq9jLddrZQBB-CoyGHSF5DwlwWmbrYXc` +- 检查用户名是否为 `postgres` + +### Q3: 表已存在错误 +``` +Error: relation "orders" already exists +``` +**解决:** +- 脚本已使用 `IF NOT EXISTS`,通常不会报错 +- 如需重新创建,先删除表 + +### Q4: 权限不足 +``` +Error: permission denied +``` +**解决:** +- 使用 postgres 超级用户执行 +- 或授予相应权限 + +## 📊 执行后的预期结果 + +执行完所有脚本后,您应该能看到: + +1. **数据库表** + - 6 个表已创建(orders, user_sessions, users, products, order_items, page_views) + - 所有索引已创建 + +2. **测试数据** + - 8 个测试用户 + - 15 个今日订单 + - 10 个昨日订单 + - 5 个在线用户会话 + - 15 条访问日志 + +3. **实时大屏显示** + - 在数据分析页面应该能看到实时数据 + - GMV、订单数、在线用户、转化率都有值 + +## 🔄 重新执行 + +如果需要重新生成测试数据: + +1. **清理数据** + ```sql + -- 执行 04_cleanup.sql + ``` + +2. **重新插入** + ```sql + -- 执行 02_insert_test_data.sql + ``` + +## 📞 获取帮助 + +如果遇到问题: + +1. 检查 Supabase 日志 +2. 查看数据库连接状态 +3. 验证配置文件 `ak/config.uts` 是否正确 +4. 使用测试页面验证连接:`/pages/mall/analytics/test/test-connection` + +## 🎯 快速开始 + +**最简单的执行方式:** + +1. 打开 Supabase Dashboard(如果有) +2. 进入 SQL Editor +3. 复制 `01_create_tables.sql` 内容,执行 +4. 复制 `02_insert_test_data.sql` 内容,执行 +5. 完成! + +现在可以开始测试实时大屏功能了!🎉 diff --git a/pages/mall/analytics/test/test-connection.uvue b/pages/mall/analytics/test/test-connection.uvue new file mode 100644 index 00000000..dcb29cfa --- /dev/null +++ b/pages/mall/analytics/test/test-connection.uvue @@ -0,0 +1,529 @@ + + + + + + diff --git a/pages/mall/consumer/index.uvue b/pages/mall/consumer/index.uvue index f5b4f75d..404eb7e1 100644 --- a/pages/mall/consumer/index.uvue +++ b/pages/mall/consumer/index.uvue @@ -169,34 +169,44 @@ const loadBanners = async () => { if (error !== null) { console.error('加载轮播图失败:', error) + bannerList.value = [] return } bannerList.value = data ?? [] } catch (err) { console.error('加载轮播图异常:', err) + bannerList.value = [] } } // 加载分类 const loadCategories = async () => { try { + // 查询所有活跃分类,然后在前端过滤出顶级分类(parent_id 为 null) + // 这样可以避免 UTS 中 .is(null) 的类型问题 const { data, error } = await supa .from('categories') .select('*') .eq('is_active', true) - .is('parent_id', null) .order('sort_order', { ascending: true }) - .limit(8) if (error !== null) { console.error('加载分类失败:', error) + categoryList.value = [] return } - categoryList.value = data ?? [] + // 过滤出顶级分类(parent_id 为 null 或 undefined) + const topCategories = (data ?? []).filter((item: any) => { + return item.parent_id === null || item.parent_id === undefined || item.parent_id === '' + }).slice(0, 8) // 限制为前8个 + + categoryList.value = topCategories } catch (err) { console.error('加载分类异常:', err) + // 如果查询失败,使用空数组避免页面崩溃 + categoryList.value = [] } } @@ -204,22 +214,25 @@ const loadCategories = async () => { const loadCoupons = async () => { try { const now = new Date().toISOString() + // 查询当前时间在有效期内的优惠券:start_time <= now <= end_time const { data, error } = await supa .from('coupon_templates') .select('*') .eq('status', 1) - .gte('end_time', now) - .lte('start_time', now) + .lte('start_time', now) // 开始时间 <= 当前时间 + .gte('end_time', now) // 结束时间 >= 当前时间 .limit(5) if (error !== null) { console.error('加载优惠券失败:', error) + couponList.value = [] return } couponList.value = data ?? [] } catch (err) { console.error('加载优惠券异常:', err) + couponList.value = [] } } @@ -242,6 +255,9 @@ const loadProducts = async (loadMore: boolean = false) => { if (error !== null) { console.error('加载商品失败:', error) + if (!loadMore) { + productList.value = [] + } isLoading.value = false return } @@ -261,6 +277,9 @@ const loadProducts = async (loadMore: boolean = false) => { hasMore.value = newProducts.length === pageSize.value } catch (err) { console.error('加载商品异常:', err) + if (!loadMore) { + productList.value = [] + } } finally { isLoading.value = false } diff --git a/pages/mall/nfc-modules-guide.md b/pages/mall/nfc/nfc-modules-guide.md similarity index 100% rename from pages/mall/nfc-modules-guide.md rename to pages/mall/nfc/nfc-modules-guide.md diff --git a/pages/mall/nfc.md b/pages/mall/nfc/nfc.md similarity index 100% rename from pages/mall/nfc.md rename to pages/mall/nfc/nfc.md diff --git a/pages/mall/pages-admin.json b/pages/mall/nfc/pages-admin.json similarity index 100% rename from pages/mall/pages-admin.json rename to pages/mall/nfc/pages-admin.json diff --git a/pages/mall/pages-librarian.json b/pages/mall/nfc/pages-librarian.json similarity index 100% rename from pages/mall/pages-librarian.json rename to pages/mall/nfc/pages-librarian.json diff --git a/pages/mall/pages-merchant.json b/pages/mall/nfc/pages-merchant.json similarity index 100% rename from pages/mall/pages-merchant.json rename to pages/mall/nfc/pages-merchant.json diff --git a/pages/mall/pages-parent.json b/pages/mall/nfc/pages-parent.json similarity index 100% rename from pages/mall/pages-parent.json rename to pages/mall/nfc/pages-parent.json diff --git a/pages/mall/pages-security.json b/pages/mall/nfc/pages-security.json similarity index 100% rename from pages/mall/pages-security.json rename to pages/mall/nfc/pages-security.json diff --git a/pages/mall/pages-student.json b/pages/mall/nfc/pages-student.json similarity index 100% rename from pages/mall/pages-student.json rename to pages/mall/nfc/pages-student.json diff --git a/pages/mall/pages-teacher.json b/pages/mall/nfc/pages-teacher.json similarity index 100% rename from pages/mall/pages-teacher.json rename to pages/mall/nfc/pages-teacher.json diff --git a/pages/mall/pages-config.json b/pages/mall/pages-config.json index f4985a33..149e6520 100644 --- a/pages/mall/pages-config.json +++ b/pages/mall/pages-config.json @@ -83,13 +83,6 @@ "navigationStyle": "custom" } }, - { - "path": "pages/mall/analytics/index", - "style": { - "navigationBarTitleText": "数据分析", - "navigationStyle": "custom" - } - }, { "path": "pages/mall/consumer/product-detail", "style": { @@ -461,6 +454,13 @@ { "root": "pages/mall/analytics", "pages": [ + { + "path": "index", + "style": { + "navigationBarTitleText": "数据分析中心", + "navigationStyle": "custom" + } + }, { "path": "sales-report", "style": { diff --git a/pages/user/login.uvue b/pages/user/login.uvue index 4bd0b118..f8cd545d 100644 --- a/pages/user/login.uvue +++ b/pages/user/login.uvue @@ -1,523 +1,559 @@ - - \ No newline at end of file +/* ===== 自适应:断点全部用 px(避免 rpx 在宽屏放大) ===== */ +@media screen and (max-width: 1024px){ + .header{ padding: 24px 20px; } + .logo{ width: 240px; height: 68px; } + .card{ width: 92vw; padding: 28px; gap: 22px; } + .right-inner{ width: 360px; } +} +@media screen and (max-width: 768px){ + .card{ flex-direction: column; min-height: auto; } + .left{ display: none; } + .divider{ display: none; } + .right-inner{ width: 100%; margin-left: 0; } + .actions{ flex-wrap: wrap; } +} +@media screen and (max-width: 520px){ + .sep{ display: none; } +} + diff --git a/pages/user/register.uvue b/pages/user/register.uvue index f7296fce..1f78e4d4 100644 --- a/pages/user/register.uvue +++ b/pages/user/register.uvue @@ -1,506 +1,558 @@ - \ No newline at end of file +.footer-text { + font-size: 22rpx; + color: #999999; +} + diff --git a/platformConfig.json b/platformConfig.json index 896f669a..482d68a5 100644 --- a/platformConfig.json +++ b/platformConfig.json @@ -1,5 +1,3 @@ - -// 参考链接 https://doc.dcloud.net.cn/uni-app-x/tutorial/ls-plugin.html#setting { "targets": [ "APP-ANDROID" diff --git a/static/user/COPY_IMAGES.md b/static/user/COPY_IMAGES.md new file mode 100644 index 00000000..f51d5d49 --- /dev/null +++ b/static/user/COPY_IMAGES.md @@ -0,0 +1,60 @@ +# 图片资源复制说明 + +## 需要复制的图片文件 + +请从 `CRMEB/template/uni-app/pages/users/static/` 目录复制以下文件到 `static/user/` 目录: + +### 必需文件 + +1. **phone_1.png** - 手机号输入框图标 + - 尺寸:24rpx × 34rpx + - 用途:手机号输入框左侧图标 + +2. **code_1.png** - 密码输入框图标 + - 尺寸:28rpx × 32rpx + - 用途:密码输入框左侧图标 + +3. **code_2.png** - 验证码输入框图标 + - 尺寸:28rpx × 32rpx + - 用途:验证码输入框左侧图标 + +### 可选文件 + +4. **logo2.png** - Logo 图片(可选) + - 用途:注册/找回密码页面 Logo + - 如果不存在,将使用 `/static/logo.png` + +## 复制方法 + +### Windows PowerShell +```powershell +# 在项目根目录执行 +Copy-Item "CRMEB\template\uni-app\pages\users\static\phone_1.png" -Destination "static\user\" +Copy-Item "CRMEB\template\uni-app\pages\users\static\code_1.png" -Destination "static\user\" +Copy-Item "CRMEB\template\uni-app\pages\users\static\code_2.png" -Destination "static\user\" +Copy-Item "CRMEB\template\uni-app\pages\users\static\logo2.png" -Destination "static\user\" -ErrorAction SilentlyContinue +``` + +### 手动复制 +1. 打开 `CRMEB/template/uni-app/pages/users/static/` 目录 +2. 复制上述文件到 `static/user/` 目录 +3. 确保文件路径正确 + +## 文件结构 + +复制后的目录结构应该是: +``` +static/ +└── user/ + ├── phone_1.png + ├── code_1.png + ├── code_2.png + ├── logo2.png (可选) + └── README.md +``` + +## 注意事项 + +- 如果图片文件不存在,页面会显示占位符或空白 +- 建议使用原 CRMEB 项目的图片资源以保持设计一致性 +- 图片路径在代码中使用:`/static/user/phone_1.png` diff --git a/static/user/README.md b/static/user/README.md new file mode 100644 index 00000000..f1a6541c --- /dev/null +++ b/static/user/README.md @@ -0,0 +1,20 @@ +# 用户相关图片资源 + +## 说明 +这些图片资源来自 CRMEB 项目,用于登录注册页面。 + +## 需要复制的图片文件 + +请从 `CRMEB/template/uni-app/pages/users/static/` 目录复制以下文件到此目录: + +1. `phone_1.png` - 手机号输入框图标(24rpx × 34rpx) +2. `code_1.png` - 密码输入框图标(28rpx × 32rpx) +3. `code_2.png` - 验证码输入框图标(28rpx × 32rpx) +4. `logo2.png` - Logo 图片(可选,用于注册/找回密码页面) + +## 使用方式 + +在页面中使用: +```vue + +``` diff --git a/uni_modules/charts/EChartsView.vue b/uni_modules/charts/EChartsView.vue new file mode 100644 index 00000000..04ad80bc --- /dev/null +++ b/uni_modules/charts/EChartsView.vue @@ -0,0 +1,72 @@ + + + + + + +