diff --git a/miniprogram/assets/icons/sparkles.svg b/miniprogram/assets/icons/sparkles.svg index a3b9133c..e2a4461f 100644 --- a/miniprogram/assets/icons/sparkles.svg +++ b/miniprogram/assets/icons/sparkles.svg @@ -1,4 +1,6 @@ - - + + + + diff --git a/miniprogram/custom-tab-bar/index.js b/miniprogram/custom-tab-bar/index.js index 01e98621..2ccba866 100644 --- a/miniprogram/custom-tab-bar/index.js +++ b/miniprogram/custom-tab-bar/index.js @@ -3,7 +3,10 @@ * 根据后台配置动态显示/隐藏"找伙伴"按钮 */ +console.log('[TabBar] ===== 组件文件开始加载 =====') + const app = getApp() +console.log('[TabBar] App 对象:', app) Component({ data: { @@ -38,37 +41,73 @@ Component({ lifetimes: { attached() { + console.log('[TabBar] Component attached 生命周期触发') this.loadFeatureConfig() + }, + ready() { + console.log('[TabBar] Component ready 生命周期触发') + // 如果 attached 中没有成功加载,在 ready 中再次尝试 + if (this.data.matchEnabled === undefined || this.data.matchEnabled === null) { + console.log('[TabBar] 在 ready 中重新加载配置') + this.loadFeatureConfig() + } } }, + + // 页面加载时也调用(兼容性更好) + attached() { + console.log('[TabBar] attached() 方法触发') + this.loadFeatureConfig() + }, methods: { // 加载功能配置 async loadFeatureConfig() { try { - const res = await app.request({ - url: '/api/db/config', + console.log('[TabBar] 开始加载功能配置...') + console.log('[TabBar] API地址:', app.globalData.baseUrl + '/api/db/config') + + // app.request 的第一个参数是 url 字符串,第二个参数是 options 对象 + const res = await app.request('/api/db/config', { method: 'GET' }) - if (res && res.features) { - const matchEnabled = res.features.matchEnabled === true - this.setData({ matchEnabled }, () => { - // 配置加载完成后,根据当前路由设置选中状态 - this.updateSelected() - }) - - // 如果当前在找伙伴页面,但功能已关闭,跳转到首页 - if (!matchEnabled) { - const pages = getCurrentPages() - const currentPage = pages[pages.length - 1] - if (currentPage && currentPage.route === 'pages/match/match') { - wx.switchTab({ url: '/pages/index/index' }) - } + + // 兼容两种返回格式 + let matchEnabled = false + + if (res && res.success && res.features) { + console.log('[TabBar] features配置:', JSON.stringify(res.features)) + matchEnabled = res.features.matchEnabled === true + console.log('[TabBar] matchEnabled值:', matchEnabled) + } else if (res && res.configs && res.configs.feature_config) { + // 备用格式:从 configs.feature_config 读取 + console.log('[TabBar] 使用备用格式,从configs读取') + matchEnabled = res.configs.feature_config.matchEnabled === true + console.log('[TabBar] matchEnabled值:', matchEnabled) + } else { + console.log('[TabBar] ⚠️ 未找到features配置,使用默认值false') + console.log('[TabBar] res对象keys:', Object.keys(res || {})) + } + + this.setData({ matchEnabled }, () => { + console.log('[TabBar] ✅ matchEnabled已设置为:', this.data.matchEnabled) + // 配置加载完成后,根据当前路由设置选中状态 + this.updateSelected() + }) + + // 如果当前在找伙伴页面,但功能已关闭,跳转到首页 + if (!matchEnabled) { + const pages = getCurrentPages() + const currentPage = pages[pages.length - 1] + if (currentPage && currentPage.route === 'pages/match/match') { + console.log('[TabBar] 找伙伴功能已关闭,从match页面跳转到首页') + wx.switchTab({ url: '/pages/index/index' }) } } } catch (error) { - console.log('TabBar加载功能配置失败:', error) + console.log('[TabBar] ❌ 加载功能配置失败:', error) + console.log('[TabBar] 错误详情:', error.message || error) // 默认关闭找伙伴功能 this.setData({ matchEnabled: false }, () => { this.updateSelected() diff --git a/miniprogram/pages/index/index.js b/miniprogram/pages/index/index.js index aa78390b..4e9570f6 100644 --- a/miniprogram/pages/index/index.js +++ b/miniprogram/pages/index/index.js @@ -4,6 +4,8 @@ * 技术支持: 存客宝 */ +console.log('[Index] ===== 首页文件开始加载 =====') + const app = getApp() Page({ @@ -46,6 +48,8 @@ Page({ }, onLoad(options) { + console.log('[Index] ===== onLoad 触发 =====') + // 获取系统信息 this.setData({ statusBarHeight: app.globalData.statusBarHeight, @@ -63,14 +67,27 @@ Page({ }, onShow() { + console.log('[Index] onShow 触发') + // 设置TabBar选中状态 if (typeof this.getTabBar === 'function' && this.getTabBar()) { const tabBar = this.getTabBar() - if (tabBar.updateSelected) { + console.log('[Index] TabBar 组件:', tabBar ? '已找到' : '未找到') + + // 主动触发配置加载 + if (tabBar && tabBar.loadFeatureConfig) { + console.log('[Index] 主动调用 TabBar.loadFeatureConfig()') + tabBar.loadFeatureConfig() + } + + // 更新选中状态 + if (tabBar && tabBar.updateSelected) { tabBar.updateSelected() - } else { + } else if (tabBar) { tabBar.setData({ selected: 0 }) } + } else { + console.log('[Index] TabBar 组件未找到或 getTabBar 方法不存在') } // 更新用户状态 diff --git a/miniprogram/pages/index/index.wxml b/miniprogram/pages/index/index.wxml index fdfaf704..523fe6a9 100644 --- a/miniprogram/pages/index/index.wxml +++ b/miniprogram/pages/index/index.wxml @@ -5,7 +5,7 @@ - + diff --git a/miniprogram/交付清单.md b/miniprogram/交付清单.md deleted file mode 100644 index ec4a66c7..00000000 --- a/miniprogram/交付清单.md +++ /dev/null @@ -1,212 +0,0 @@ -# 功能同步交付清单 - -**交付日期**: 2026-02-04 -**执行任务**: Next.js 功能同步到微信小程序 -**完成度**: 100% - ---- - -## 📦 新增文件清单 (10个) - -### 地址管理模块 (8个) -``` -miniprogram/pages/addresses/ -├── addresses.js ✅ 地址列表 - 逻辑层 -├── addresses.wxml ✅ 地址列表 - 视图层 -├── addresses.wxss ✅ 地址列表 - 样式层 -├── addresses.json ✅ 地址列表 - 配置 -├── edit.js ✅ 地址编辑 - 逻辑层 -├── edit.wxml ✅ 地址编辑 - 视图层 -├── edit.wxss ✅ 地址编辑 - 样式层 -└── edit.json ✅ 地址编辑 - 配置 -``` - -### 文档文件 (2个) -``` -miniprogram/ -├── 样式检查清单.md ✅ 样式统一性检查文档 -├── 功能同步完成报告.md ✅ 详细完成报告 -└── 交付清单.md ✅ 本文档 -``` - ---- - -## 🔄 修改文件清单 (7个) - -| 文件 | 修改内容 | 状态 | -|-----|---------|------| -| `app.json` | 注册地址管理页面 | ✅ | -| `app.wxss` | 添加 CSS 变量系统 | ✅ | -| `pages/chapters/chapters.wxml` | 添加搜索按钮 | ✅ | -| `pages/chapters/chapters.wxss` | 搜索按钮样式 | ✅ | -| `pages/chapters/chapters.js` | 搜索跳转方法 | ✅ | -| `pages/my/my.wxml` | 添加收益卡片 | ✅ | -| `pages/my/my.wxss` | 收益卡片艺术化样式 | ✅ | -| `pages/settings/settings.wxml` | 地址管理入口 | ✅ | -| `pages/settings/settings.wxss` | 样式微调 | ✅ | -| `pages/settings/settings.js` | 跳转方法 | ✅ | - ---- - -## 🎯 核心成果 - -### 1. 功能完整性 - -| 功能模块 | 状态 | 说明 | -|---------|------|-----| -| 首页 | ✅ | 搜索、推荐、进度卡 | -| 目录 | ✅ | 搜索按钮、章节列表 | -| 阅读 | ✅ | 付费墙、分享、海报 | -| 匹配 | ✅ | 4种类型、匹配次数 | -| 我的 | ✅ | 收益卡片、Tab切换 | -| 推广中心 | ✅ | 绑定列表、分享、提现 | -| 设置 | ✅ | 账号绑定、地址入口 | -| 地址管理 | ✅ | 列表、新增、编辑、删除 | -| 订单 | ✅ | 订单列表、详情 | -| 搜索 | ✅ | 关键词、热门章节 | -| 关于 | ✅ | 作者介绍 | - -### 2. 样式一致性 - -- ✅ 背景色: #000000 (纯黑) -- ✅ 品牌色: #00CED1 (青绿) -- ✅ 卡片圆角: 24-32rpx -- ✅ 渐变效果: 完整复刻 -- ✅ 毛玻璃效果: backdrop-filter -- ✅ 动画效果: 流畅自然 - -### 3. 登录体系 - -| 端 | 登录方式 | 状态 | -|---|---------|------| -| 小程序 | 微信一键登录 | ✅ 保持原生体验 | -| Next.js | 手机号+密码 | 保持不变 | -| 数据互通 | 手机号统一 | ✅ 后端处理 | - ---- - -## 🧪 测试验证清单 - -### 必测项 (优先级高) - -- [ ] **登录**: 微信一键登录流程 -- [ ] **目录**: 搜索按钮点击跳转 -- [ ] **我的**: 收益卡片显示和交互 -- [ ] **设置**: 地址管理入口点击 -- [ ] **地址列表**: 显示、编辑、删除 -- [ ] **地址编辑**: 表单填写、省市区选择、保存 -- [ ] **推广中心**: Tab切换、用户列表展示 -- [ ] **提现**: 提现按钮和流程 - -### 建议测项 (优先级中) - -- [ ] 搜索功能(关键词搜索、热门推荐) -- [ ] 海报生成和保存 -- [ ] 匹配功能(4种类型) -- [ ] 阅读页(付费墙、分享) -- [ ] 所有页面的空状态显示 - -### 兼容性测项 (优先级低) - -- [ ] iOS 显示和交互 -- [ ] Android 显示和交互 -- [ ] 不同屏幕尺寸 -- [ ] 安全区域适配 - ---- - -## 📋 API 接口清单 - -确认以下接口已实现并可用: - -### 用户相关 -- `/api/user/addresses` - 地址列表 (GET) -- `/api/user/addresses` - 新增地址 (POST) -- `/api/user/addresses/:id` - 地址详情 (GET) -- `/api/user/addresses/:id` - 更新地址 (PUT) -- `/api/user/addresses/:id` - 删除地址 (DELETE) - -### 推广相关 -- `/api/withdraw` - 提现接口 (POST) -- `/api/distribution` - 绑定用户列表 (GET) - -### 其他 -- `/api/book/search` - 搜索接口 (GET) -- `/api/match/config` - 匹配配置 (GET) - ---- - -## 📝 开发约束(重要) - -根据 `开发文档/0、Mycontent-book 项目总览.md` 第5节: - -### ⚠️ 前端开发策略 - -``` -┌───────────────┬──────────┬────────────────────────┐ -│ 微信小程序 │ ✅ 活跃 │ 所有C端新功能在此开发 │ -│ Next.js C端 │ 🔒 冻结 │ app/view/ 不再新增功能 │ -│ Next.js 管理端 │ ✅ 活跃 │ app/admin/ 继续开发 │ -│ API 接口 │ ✅ 活跃 │ 小程序和管理端共用 │ -└───────────────┴──────────┴────────────────────────┘ -``` - -### ⚠️ 登录体系差异 - -- 小程序保持**微信一键登录**,不要改成手机号密码 -- Next.js 保持手机号密码登录 -- 后端以手机号为唯一标识,处理数据互通 - ---- - -## 🎉 交付成果 - -### 代码质量 -- ✅ 代码结构清晰 -- ✅ 注释完整 -- ✅ 命名规范 -- ✅ 易于维护 - -### 功能完整性 -- ✅ 所有核心功能已实现 -- ✅ 无功能缺失或降级 -- ✅ 符合 1:1 复刻要求 - -### 样式一致性 -- ✅ 颜色、圆角、间距统一 -- ✅ 渐变、阴影效果完整 -- ✅ 动画流畅自然 - -### 文档完善 -- ✅ 转换提示词文档 -- ✅ 样式检查清单 -- ✅ 功能完成报告 -- ✅ 交付清单(本文档) - ---- - -## 🚀 下一步 - -1. **在微信开发者工具中测试** - - 打开项目 - - 逐页测试功能 - - 验证样式显示 - -2. **修复发现的问题** - - 记录 Bug - - 优先修复高优先级问题 - -3. **准备上线** - - 提交代码审核 - - 准备版本说明 - - 发布小程序 - ---- - -**交付人员**: AI Assistant -**审核状态**: ⏳ 待测试验收 -**联系方式**: 通过 Cursor 提问 - ---- - -*本次功能同步严格遵循 1:1 复刻要求,确保样式、交互、功能完全一致。* diff --git a/miniprogram/分享图标对齐Next说明.md b/miniprogram/分享图标对齐Next说明.md deleted file mode 100644 index 694d6d59..00000000 --- a/miniprogram/分享图标对齐Next说明.md +++ /dev/null @@ -1,346 +0,0 @@ -# 分享图标对齐 Next.js 说明 - -**更新日期**: 2026-02-04 -**目标**: 小程序分享图标与 Next.js 保持一致 -**Next.js 使用**: `Share2` 图标(lucide-react) - ---- - -## 🎯 Next.js 实现 - -### 引入图标 - -```tsx -import { Share2 } from "lucide-react" -``` - -### 使用场景 - -在 `components/chapter-content.tsx` 的顶部导航栏: - -```tsx - -``` - -**特点**: -- 圆形按钮(36px × 36px) -- 深色背景 `#1c1c1e` -- 图标尺寸 16px × 16px -- 图标颜色灰色 `text-gray-400` -- 点击效果:背景变深 `#2c2c2e` - ---- - -## 📱 小程序实现 - -### Share2 图标 SVG - -创建 `/assets/icons/share.svg`: - -```svg - - - - - - - -``` - -**说明**: 这是 lucide-react 的 Share2 图标的 SVG 代码,完全一致。 - ---- - -### WXML 代码 - -```xml - - -``` - -**关键点**: -- 使用 `` 组件加载 SVG 文件 -- `mode="aspectFit"` 保持图标比例 -- `open-type="share"` 触发微信分享 - ---- - -### WXSS 样式 - -```css -.fab-share { - position: fixed; - right: 32rpx; - width: 60rpx!important; - bottom: calc(120rpx + env(safe-area-inset-bottom)); - height: 60rpx; - border-radius: 60rpx; - background: linear-gradient(135deg, #00CED1 0%, #20B2AA 100%); - box-shadow: 0 8rpx 32rpx rgba(0, 206, 209, 0.4); - padding: 0; - margin: 0; - border: none; - z-index: 9999; - display: flex; - align-items: center; - justify-content: center; - transition: transform 0.2s ease, box-shadow 0.2s ease; -} - -.fab-share::after { - border: none; -} - -.fab-share:active { - transform: scale(0.95); - box-shadow: 0 4rpx 20rpx rgba(0, 206, 209, 0.5); -} - -.fab-icon { - width: 48rpx; - height: 48rpx; - display: block; -} -``` - ---- - -## 📊 对比 - -### 图标 - -| 平台 | 图标来源 | 图标类型 | 实现方式 | -|-----|---------|---------|---------| -| **Next.js** | lucide-react | Share2 | React 组件 | -| **小程序** | SVG 文件 | Share2 | image 组件 | -| **一致性** | ✅ | ✅ 完全相同 | ✅ SVG 代码相同 | - ---- - -### 按钮位置 - -| 平台 | 位置 | 说明 | -|-----|------|------| -| **Next.js** | 顶部导航栏右侧 | 与返回按钮对称 | -| **小程序** | 右下角悬浮 | 更适合移动端交互 | - -**差异原因**: 小程序需要悬浮按钮以避免被内容遮挡,且更符合移动端操作习惯。 - ---- - -### 视觉风格 - -| 属性 | Next.js | 小程序 | 说明 | -|-----|---------|--------|------| -| **图标** | Share2 | Share2 | ✅ 完全相同 | -| **按钮形状** | 圆形 | 圆形 | ✅ 一致 | -| **图标颜色** | 灰色 `#9ca3af` | 白色 `#ffffff` | 小程序背景是品牌色,用白色更清晰 | -| **按钮背景** | 深灰 `#1c1c1e` | 品牌色渐变 | 小程序更突出分享功能 | -| **尺寸** | 36px × 36px | 60rpx × 60rpx (~45px) | 小程序略大,更易点击 | - ---- - -## ✅ 核心一致性 - -### 1. 图标形状 ✅ - -**Share2 图标** (三个圆点连线): -- 左上圆点(18, 5) -- 左中圆点(6, 12) -- 右下圆点(18, 19) -- 两条连接线 - -Next.js 和小程序使用**完全相同的 SVG path**,视觉效果一致。 - ---- - -### 2. 语义一致 ✅ - -**功能**: 分享当前章节内容 -**触发**: 点击分享图标 -**行为**: -- Next.js: 打开分享弹窗,显示专属链接和分享选项 -- 小程序: 触发微信原生分享(朋友、群聊、朋友圈) - ---- - -## 🔧 技术实现 - -### 为什么用 SVG 文件? - -| 方案 | 优点 | 缺点 | 结论 | -|-----|------|------|------| -| **直接 `` 标签** | 简洁 | ❌ 小程序不支持 | ❌ 不可行 | -| **Base64 SVG** | 无需文件 | ⚠️ 不稳定 | ❌ 不可靠 | -| **SVG 文件** | ✅ 稳定可靠 | 需要额外文件 | ✅ **最佳方案** | -| **Unicode Emoji** | 简单 | ❌ 无法完全匹配 Share2 | ❌ 不够准确 | - -**选择 SVG 文件的原因**: -1. ✅ 小程序 `image` 组件**完全支持** SVG 文件 -2. ✅ 与 Next.js 使用**完全相同的 SVG 代码** -3. ✅ 稳定可靠,不会出现显示问题 -4. ✅ 可以精确控制颜色和样式 - ---- - -### image 组件加载 SVG - -```xml - -``` - -**关键属性**: -- `src`: 本地 SVG 文件路径(相对于小程序根目录) -- `mode="aspectFit"`: 保持图标宽高比,完整显示 - -**优势**: -- 矢量图标,任意缩放清晰 -- 与 Next.js 的 SVG 代码完全相同 -- 不依赖外部网络,加载快速 - ---- - -## 🎨 可扩展性 - -### 添加更多 lucide 图标 - -在 `/assets/icons/` 目录创建更多 SVG 文件: - -``` -miniprogram/ -└── assets/ - └── icons/ - ├── share.svg # Share2 (分享) - ├── chevron-left.svg # ChevronLeft (返回) - ├── search.svg # Search (搜索) - ├── heart.svg # Heart (收藏) - └── ... -``` - -**使用方式**: -```xml - -``` - ---- - -### 从 lucide.dev 复制 SVG - -1. 访问 [lucide.dev](https://lucide.dev) -2. 搜索所需图标(如 "Share2") -3. 点击 "Copy SVG" -4. 粘贴到小程序的 `/assets/icons/` 目录 -5. 修改 `stroke` 颜色为 `white`(或其他所需颜色) - -**示例 - Star 图标**: - -```svg - - - -``` - ---- - -## 📋 修改文件清单 - -| 文件 | 操作 | 说明 | -|-----|------|------| -| `/assets/icons/share.svg` | ✅ 新增 | Share2 图标 SVG 文件 | -| `pages/read/read.wxml` | ✅ 修改 | 使用 image 组件加载 SVG | -| `pages/read/read.wxss` | ✅ 修改 | 调整图标样式(宽高) | - ---- - -## 🧪 测试验证 - -### 必测项 - -- [x] 分享按钮显示 Share2 图标(三个圆点连线) -- [x] 图标颜色为白色,清晰可见 -- [x] 图标尺寸 48rpx × 48rpx -- [x] 图标在圆形品牌色背景上居中 -- [x] 点击触发微信分享功能 -- [x] 图标清晰,无锯齿或模糊 - -### 兼容性 - -- ✅ 微信开发者工具 -- ✅ iOS 真机 -- ✅ Android 真机 - ---- - -## 💡 最佳实践 - -### 1. 统一图标库 - -建议创建一个统一的图标管理方案: - -``` -/assets/icons/ - - share.svg # 分享 - - back.svg # 返回 - - search.svg # 搜索 - - heart.svg # 收藏 - - star.svg # 评分 - - user.svg # 用户 - - settings.svg # 设置 -``` - ---- - -### 2. 颜色变体 - -如果需要不同颜色的图标,创建多个变体: - -``` -/assets/icons/ - - share-white.svg # 白色分享图标 - - share-brand.svg # 品牌色分享图标 - - share-gray.svg # 灰色分享图标 -``` - -或者使用 CSS `filter` 动态改变颜色(但效果有限)。 - ---- - -### 3. 尺寸规范 - -建议统一图标尺寸规范: - -| 场景 | 尺寸 | 说明 | -|-----|------|------| -| **小图标** | 32rpx × 32rpx | 列表项、标签 | -| **中图标** | 48rpx × 48rpx | 按钮、导航栏 | -| **大图标** | 64rpx × 64rpx | 功能入口、卡片 | - ---- - -## ✨ 总结 - -### 实现效果 - -- ✅ 小程序使用与 Next.js **完全相同的 Share2 图标** -- ✅ SVG 文件方案,稳定可靠 -- ✅ 视觉一致,语义清晰 -- ✅ 矢量图标,任意缩放清晰 - -### 技术亮点 - -- 🎯 使用 lucide-react 的原生 SVG 代码 -- 🎨 通过 `image` 组件加载 SVG 文件 -- 🚀 零依赖,无需字体文件或网络请求 -- 💯 跨端一致,Next.js 和小程序视觉统一 - ---- - -**分享图标已完全对齐 Next.js!** 🎉 diff --git a/miniprogram/分享按钮图标方案说明.md b/miniprogram/分享按钮图标方案说明.md deleted file mode 100644 index bf95c005..00000000 --- a/miniprogram/分享按钮图标方案说明.md +++ /dev/null @@ -1,273 +0,0 @@ -# 分享按钮图标方案说明 - -**更新日期**: 2026-02-04 -**最终方案**: Unicode Emoji 图标 -**原因**: 小程序 SVG 显示存在兼容性问题 - ---- - -## 🔄 方案演变 - -### 方案 1: 文本符号 ↗ (初始版本) -- **图标**: `↗` (U+2197) -- **问题**: 视觉效果不够专业 - ---- - -### 方案 2: SVG 组件(尝试失败) -- **实现**: 创建 icon 组件,使用 `` 标签 -- **问题**: ❌ 小程序不支持直接使用 `` 标签 -- **状态**: 已放弃 - ---- - -### 方案 3: Base64 SVG + image 组件(尝试失败) -- **实现**: 将 SVG 转换为 Base64 Data URL,通过 `` 组件显示 -- **代码**: - ```javascript - const svgData = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}` - ``` -- **问题**: ❌ 在小程序中仍然无法显示 -- **可能原因**: - - 小程序 `image` 组件对 Base64 SVG 的支持有限制 - - 可能需要使用外部 SVG 文件 URL -- **状态**: 已放弃 - ---- - -### 方案 4: Unicode Emoji 图标(最终方案)✅ - -**选择的图标**: `⇧` (U+21E7, Upwards White Arrow) - -**为什么选择这个图标**: -1. ✅ **兼容性好**: Unicode 标准,所有设备都支持 -2. ✅ **视觉清晰**: 简洁的白色向上箭头 -3. ✅ **符合语义**: 分享 = 向上/向外传播 -4. ✅ **无需额外文件**: 直接使用文本 -5. ✅ **可靠稳定**: 不依赖组件或外部资源 - ---- - -## 📱 实现代码 - -### WXML (read.wxml) - -```xml - - -``` - ---- - -### WXSS (read.wxss) - -```css -.fab-share { - position: fixed; - right: 32rpx; - width: 60rpx!important; - bottom: calc(120rpx + env(safe-area-inset-bottom)); - height: 60rpx; - border-radius: 60rpx; - background: linear-gradient(135deg, #00CED1 0%, #20B2AA 100%); - box-shadow: 0 8rpx 32rpx rgba(0, 206, 209, 0.4); - padding: 0; - margin: 0; - border: none; - z-index: 9999; - display: flex; - align-items: center; - justify-content: center; - transition: transform 0.2s ease, box-shadow 0.2s ease; -} - -.fab-share::after { - border: none; -} - -.fab-share:active { - transform: scale(0.95); - box-shadow: 0 4rpx 20rpx rgba(0, 206, 209, 0.5); -} - -.fab-icon { - font-size: 48rpx; - color: #ffffff; - line-height: 1; - font-weight: bold; -} -``` - ---- - -## 🎨 视觉效果 - -**按钮样式**: -- 圆形悬浮按钮(60rpx × 60rpx) -- 品牌色渐变背景(青色 → 浅绿色) -- 白色箭头图标(48rpx,粗体) -- 阴影和点击反馈效果 - -**位置**: -- 右下角固定定位 -- 距离右侧 32rpx -- 底部留出安全区域 + 120rpx(为底部导航栏留空间) - ---- - -## 🔤 可选的分享图标 - -### 向上箭头类 - -| 图标 | Unicode | 说明 | 推荐度 | -|-----|---------|------|--------| -| ⇧ | U+21E7 | 向上白色箭头 | ⭐⭐⭐⭐⭐ **当前使用** | -| ↑ | U+2191 | 向上箭头 | ⭐⭐⭐⭐ | -| ⬆ | U+2B06 | 向上黑色箭头 | ⭐⭐⭐⭐ | -| ⤴ | U+2934 | 向右上弯曲箭头 | ⭐⭐⭐ | -| ↗ | U+2197 | 右上箭头 | ⭐⭐⭐ | - ---- - -### 分享/链接类 - -| 图标 | Unicode | 说明 | 推荐度 | -|-----|---------|------|--------| -| 🔗 | U+1F517 | 链接 | ⭐⭐⭐ (太具象) | -| 📤 | U+1F4E4 | 发送盒子 | ⭐⭐⭐ (太具象) | -| ⇪ | U+21EA | 向上双箭头 | ⭐⭐ | - ---- - -## 💡 为什么不用其他方案 - -### vs. SVG 文件 - -| 方案 | 优点 | 缺点 | 结论 | -|-----|------|------|------| -| **SVG 文件** | 矢量图标,专业 | 需要额外文件,网络请求 | ❌ 复杂 | -| **Unicode Emoji** | 简单直接,无需文件 | 样式受系统字体限制 | ✅ **最佳** | - ---- - -### vs. 图片图标 - -| 方案 | 优点 | 缺点 | 结论 | -|-----|------|------|------| -| **PNG/JPG** | 视觉可控 | 不同尺寸需要多张图,放大模糊 | ❌ 不灵活 | -| **Unicode Emoji** | 矢量,任意缩放 | 样式不可完全自定义 | ✅ **更好** | - ---- - -### vs. 字体图标 - -| 方案 | 优点 | 缺点 | 结论 | -|-----|------|------|------| -| **iconfont** | 图标丰富 | 需要字体文件,增加包体积 | ❌ 不值得 | -| **Unicode Emoji** | 系统自带,零体积 | 图标数量有限 | ✅ **足够用** | - ---- - -## 🧪 测试验证 - -### 已测试项 - -- [x] 阅读页分享按钮显示白色箭头图标 -- [x] 图标居中对齐 -- [x] 图标大小合适(48rpx) -- [x] 点击触发分享功能 -- [x] 在不同屏幕尺寸下显示正常 - -### 兼容性 - -- ✅ iOS 微信 -- ✅ Android 微信 -- ✅ 微信开发者工具 - ---- - -## 🔧 如何更换图标 - -只需修改 `read.wxml` 中的 emoji 字符: - -```xml - - - - - - - - - - - -``` - -**无需修改任何样式**,直接替换即可。 - ---- - -## 📊 技术总结 - -### 小程序 SVG 支持情况 - -| 使用方式 | 是否支持 | 说明 | -|---------|---------|------| -| 直接使用 `` 标签 | ❌ 不支持 | 小程序不支持 | -| Base64 SVG + `` | ⚠️ 不稳定 | 理论支持,实际可能失败 | -| 外部 SVG 文件 URL + `` | ✅ 支持 | 需要网络请求 | -| Canvas 绘制 SVG | ✅ 支持 | 复杂,性能差 | - -**结论**: 对于简单图标,**Unicode Emoji 是最佳选择**。 - ---- - -## 📋 相关文件 - -| 文件 | 说明 | -|-----|------| -| `pages/read/read.wxml` | 分享按钮结构(使用 emoji) | -| `pages/read/read.wxss` | 分享按钮样式 | -| `components/icon/` | SVG 图标组件(暂不使用,保留备用) | - ---- - -## 🚀 后续优化建议 - -### 如果需要更专业的图标 - -1. **使用 iconfont 字体文件** - - 生成 Base64 字体文件 - - 通过 CSS `@font-face` 引入 - - 使用 class 名引用图标 - -2. **使用外部 SVG 文件** - - 托管 SVG 文件到 CDN - - `` - -3. **使用 Canvas 绘制** - - 通过 Canvas API 绘制图标 - - 性能开销较大,不推荐 - ---- - -## ✨ 总结 - -### 最终方案 -- ✅ 使用 Unicode Emoji 图标 `⇧` -- ✅ 简单、可靠、零依赖 -- ✅ 兼容性好,所有设备支持 -- ✅ 视觉效果清晰 - -### 优点 -- 🎯 实现简单,只需一个字符 -- 🚀 零额外资源,不增加包体积 -- 💯 稳定可靠,不依赖外部服务 -- 🎨 视觉效果良好,符合设计预期 - ---- - -**分享按钮图标问题最终解决!** 🎉 diff --git a/miniprogram/功能同步完成报告.md b/miniprogram/功能同步完成报告.md deleted file mode 100644 index 1dea1352..00000000 --- a/miniprogram/功能同步完成报告.md +++ /dev/null @@ -1,330 +0,0 @@ -# 微信小程序功能同步完成报告 - -**执行时间**: 2026-02-04 -**参考文档**: `转换提示词.md` -**开发约束**: `开发文档/0、Mycontent-book 项目总览.md` 第5节 - ---- - -## 一、执行总结 - -### 1.1 任务完成情况 - -| 阶段 | 任务数 | 完成数 | 状态 | -|-----|-------|-------|------| -| P1 完善现有页面 | 3 | 3 | ✅ 全部完成 | -| P2 新建缺失页面 | 2 | 2 | ✅ 全部完成 | -| P3 组件优化 | 3 | 3 | ✅ 全部完成 | -| P4 样式统一 | 2 | 2 | ✅ 全部完成 | -| **总计** | **10** | **10** | **✅ 100%** | - -### 1.2 详细任务清单 - -#### P1 阶段:完善现有页面功能 - -- [x] **任务1**: 完善目录页 - - ✅ 添加右上角搜索按钮 - - ✅ 样式细节对齐 - - 文件: `pages/chapters/*` - -- [x] **任务2**: 完善我的页面 - - ✅ 收益卡片艺术化设计 - - ✅ 渐变背景 + 装饰元素 - - ✅ 渐变文字效果 - - 文件: `pages/my/my.wxml`, `pages/my/my.wxss` - -- [x] **任务3**: 完善推广中心 - - ✅ 过期提醒横幅(已有) - - ✅ 绑定用户列表 Tab切换(已有) - - ✅ 用户列表展示(已有) - - ✅ 分销规则说明(已有) - - ✅ 分享按钮组(已有) - - 结论: 功能已完整,无需修改 - -#### P2 阶段:新建缺失页面 - -- [x] **任务4**: 完善设置页 - - ✅ 添加收货地址管理入口 - - ✅ 绑定状态图标保持一致 - - 文件: `pages/settings/settings.wxml`, `pages/settings/settings.js` - -- [x] **任务5**: 创建地址管理模块 - - ✅ 创建地址列表页 (`pages/addresses/addresses.*`) - - ✅ 创建地址编辑页 (`pages/addresses/edit.*`) - - ✅ 更新 `app.json` 注册页面 - - 新增文件: 8个 - -#### P3 阶段:组件优化 - -- [x] **任务6**: 优化搜索功能 - - ✅ 搜索页已完整实现(已有) - - ✅ 热门搜索、热门章节、搜索结果 - - 结论: 功能已完整,无需修改 - -- [x] **任务7**: 优化海报生成功能 - - ✅ Canvas 绘制海报(已有) - - ✅ 小程序码集成(已有) - - ✅ 保存到相册(已有) - - 结论: 功能已完整,无需修改 - -- [x] **任务8**: 创建提现弹窗组件 - - ✅ 提现功能已实现(已有) - - ✅ 提现确认弹窗(已有) - - ✅ 绑定检查(已有) - - 结论: 功能已完整,无需修改 - -#### P4 阶段:样式统一 - -- [x] **任务9**: 统一全局样式变量 - - ✅ 添加 CSS 变量系统 - - ✅ 品牌色、背景色、文字色变量 - - ✅ iOS 系统色变量 - - 文件: `app.wxss` - -- [x] **任务10**: 逐页样式核对 - - ✅ 检查12个页面样式 - - ✅ 所有页面背景色统一 - - ✅ 所有卡片样式统一 - - ✅ 所有按钮样式统一 - - 文档: `样式检查清单.md` - ---- - -## 二、新增文件清单 - -### 2.1 地址管理模块 (8个文件) - -``` -miniprogram/pages/addresses/ -├── addresses.js (地址列表页 - 逻辑) -├── addresses.wxml (地址列表页 - 结构) -├── addresses.wxss (地址列表页 - 样式) -├── addresses.json (地址列表页 - 配置) -├── edit.js (地址编辑页 - 逻辑) -├── edit.wxml (地址编辑页 - 结构) -├── edit.wxss (地址编辑页 - 样式) -└── edit.json (地址编辑页 - 配置) -``` - -### 2.2 文档文件 (2个文件) - -``` -miniprogram/ -├── 样式检查清单.md (样式统一性检查文档) -└── 功能同步完成报告.md (本报告) -``` - ---- - -## 三、修改文件清单 - -### 3.1 核心配置文件 - -- `app.json` - 添加地址管理页面注册 -- `app.wxss` - 添加 CSS 变量系统 - -### 3.2 页面文件 - -| 页面 | 修改内容 | -|-----|---------| -| `pages/chapters/` | 添加搜索按钮 | -| `pages/my/` | 添加收益卡片艺术化设计 | -| `pages/settings/` | 添加地址管理入口 | - ---- - -## 四、功能对比 - 最终版 - -### 4.1 登录体系差异(已明确) - -| 端 | 登录方式 | 处理方式 | -|---|---------|---------| -| 小程序 | 微信一键登录 | ✅ 保持原生体验 | -| Next.js | 手机号+密码 | 保持现状 | -| 账号统一 | 手机号为唯一标识 | 后端处理数据互通 | - -### 4.2 功能完整性对比 - -| 功能模块 | Next.js | 小程序 | 对比结果 | -|---------|---------|--------|---------| -| 首页 | ✅ | ✅ | 1:1 复刻 | -| 目录 | ✅ | ✅ | 1:1 复刻(含搜索) | -| 阅读 | ✅ | ✅ | 1:1 复刻 | -| 匹配 | ✅ | ✅ | 1:1 复刻 | -| 我的 | ✅ | ✅ | 1:1 复刻(含收益卡片) | -| 推广中心 | ✅ | ✅ | 1:1 复刻 | -| 设置 | ✅ | ✅ | 1:1 复刻(含地址入口) | -| 地址管理 | ✅ | ✅ | 1:1 复刻(新建) | -| 订单 | ✅ | ✅ | 1:1 复刻 | -| 关于 | ✅ | ✅ | 1:1 复刻 | -| 搜索 | ✅ | ✅ | 1:1 复刻 | -| 登录 | ✅ 独立页 | ✅ 弹窗 | 适配差异✅ | - -### 4.3 组件完整性对比 - -| 组件 | Next.js | 小程序 | 对比结果 | -|-----|---------|--------|---------| -| 搜索功能 | SearchModal | 独立页面 | ✅ 功能等效 | -| 海报生成 | PosterModal | Canvas绘制 | ✅ 功能等效 | -| 提现功能 | WithdrawalModal | Modal弹窗 | ✅ 功能等效 | -| 自动提现 | AutoWithdrawModal | 设置页集成 | ✅ 功能等效 | -| 底部导航 | BottomNav | CustomTabBar | ✅ 原生组件 | - ---- - -## 五、测试验证清单 - -### 5.1 功能测试 - -- [ ] 登录流程(微信一键登录) -- [ ] 目录页搜索入口点击 -- [ ] 我的页收益卡片显示 -- [ ] 设置页跳转地址管理 -- [ ] 地址列表增删改查 -- [ ] 地址编辑表单验证 -- [ ] 推广中心绑定列表Tab切换 -- [ ] 海报生成和保存 -- [ ] 提现流程 -- [ ] 搜索功能 - -### 5.2 样式测试 - -- [ ] 所有页面背景色为纯黑 -- [ ] 品牌色 #00CED1 统一应用 -- [ ] 卡片圆角 24-32rpx -- [ ] 渐变效果正常显示 -- [ ] 毛玻璃效果正常 -- [ ] 动画流畅无卡顿 - -### 5.3 兼容性测试 - -- [ ] iOS 显示正常 -- [ ] Android 显示正常 -- [ ] 不同屏幕尺寸适配 -- [ ] 安全区域适配 - ---- - -## 六、注意事项 - -### 6.1 开发约束(重要) - -> **2026-02-04 起生效** - -- ✅ 所有 C 端新功能只在小程序开发 -- 🔒 Next.js `app/view/` 已冻结,不再新增功能 -- ✅ Next.js `app/admin/` 继续用于管理后台 -- ✅ API 接口层保持统一 - -### 6.2 登录体系说明 - -- 小程序保持微信一键登录,**不复刻** Next.js 的手机号密码登录 -- 两端以手机号为账号唯一标识 -- 数据互通由后端处理 - -### 6.3 样式维护建议 - -1. 新增页面使用 `app.wxss` 中的 CSS 变量 -2. 参考 `样式检查清单.md` 保持统一 -3. 避免硬编码颜色值,优先使用变量 -4. 卡片、按钮、标签等复用全局样式类 - ---- - -## 七、相关文档 - -1. **开发约束**: `开发文档/0、Mycontent-book 项目总览.md` 第5节 -2. **转换提示词**: `转换提示词.md` -3. **样式检查**: `miniprogram/样式检查清单.md` -4. **API 接口**: `开发文档/5、接口/API接口.md` -5. **部署说明**: `开发文档/8、部署/` 目录 - ---- - -## 八、下一步工作 - -### 8.1 功能测试(当前优先) - -1. 在微信开发者工具中逐页测试 -2. 验证所有新增功能可用 -3. 测试所有交互反馈 -4. 检查样式在不同设备的显示 - -### 8.2 后续优化(可选) - -1. 性能优化 (首屏加载、图片懒加载) -2. 动画优化 (添加更流畅的过渡) -3. 用户体验优化 (加载提示、错误提示) -4. 数据缓存策略优化 - -### 8.3 API 对接 - -确保以下接口已实现: -- `/api/user/addresses` - 地址列表 -- `/api/user/addresses/:id` - 地址详情/更新/删除 -- `/api/withdraw` - 提现接口 -- `/api/match/config` - 匹配配置 -- `/api/book/search` - 搜索接口 - ---- - -## 九、成果交付 - -### 9.1 新增功能 - -1. ✅ 目录页搜索按钮 -2. ✅ 我的页艺术化收益卡片 -3. ✅ 设置页地址管理入口 -4. ✅ 完整的地址管理模块(列表/新增/编辑) -5. ✅ CSS 变量系统 - -### 9.2 代码质量 - -- ✅ 代码结构清晰,注释完整 -- ✅ 样式统一,遵循设计规范 -- ✅ 命名规范,易于维护 -- ✅ 错误处理完善 - -### 9.3 文档完善 - -- ✅ 转换提示词文档 -- ✅ 样式检查清单 -- ✅ 功能同步完成报告(本文档) -- ✅ 开发约束说明 - ---- - -## 十、验收标准 - -### ✅ 功能完整性 -- 所有 Next.js 功能已同步到小程序(除登录体系差异) -- 所有必需功能可正常使用 -- 无功能缺失或降级 - -### ✅ 样式一致性 -- 背景色、品牌色统一 -- 卡片、按钮、标签样式统一 -- 渐变、阴影、动画效果完整 -- 符合 1:1 复刻要求 - -### ✅ 交互体验 -- 所有点击反馈流畅 -- 加载状态清晰 -- 错误提示友好 -- 页面切换流畅 - -### ✅ 代码规范 -- 代码结构清晰 -- 注释完整 -- 命名规范 -- 易于维护 - ---- - -**执行人员**: AI Assistant -**审核状态**: ⏳ 待测试验收 -**下一步**: 在微信开发者工具中进行完整功能测试 - ---- - -*本报告记录了从 Next.js 到微信小程序的功能同步全过程。* diff --git a/miniprogram/图标系统实现说明.md b/miniprogram/图标系统实现说明.md deleted file mode 100644 index 72028fe9..00000000 --- a/miniprogram/图标系统实现说明.md +++ /dev/null @@ -1,388 +0,0 @@ -# 小程序图标系统实现说明 - -**更新日期**: 2026-02-04 -**功能**: 创建 SVG 图标组件,对标 Next.js 的 lucide-react -**首次应用**: 阅读页右下角悬浮分享按钮 - ---- - -## 🎯 背景 - -Next.js 使用 `lucide-react` 图标库,提供了丰富的 SVG 图标。小程序需要对应的图标系统来保持 UI 一致性。 - -**Next.js 引入方式**: -```jsx -import { Share2, ArrowUpRight, Search, Heart } from "lucide-react" - - -``` - -**挑战**: 小程序无法使用 React 组件库,需要自建图标系统。 - ---- - -## ✅ 解决方案 - -### 创建自定义图标组件 - -基于 SVG 的自定义组件,支持动态尺寸和颜色。 - -**组件位置**: `/components/icon/` - -**组件文件**: -- `icon.wxml` - 模板(SVG 定义) -- `icon.js` - 逻辑(属性定义) -- `icon.wxss` - 样式 -- `icon.json` - 配置 -- `README.md` - 使用文档 - ---- - -## 📦 组件实现 - -### 1. 组件属性 (`icon.js`) - -```javascript -Component({ - properties: { - name: { // 图标名称 - type: String, - value: 'share' - }, - size: { // 图标大小(rpx) - type: Number, - value: 48 - }, - color: { // 图标颜色 - type: String, - value: 'currentColor' - }, - customClass: { // 自定义类名 - type: String, - value: '' - }, - customStyle: { // 自定义样式 - type: String, - value: '' - } - } -}) -``` - ---- - -### 2. SVG 图标定义 (`icon.wxml`) - -**Share 图标** (对应 lucide-react 的 `Share2`): -```xml - - - - - - - - - -``` - -**其他图标**: -- `arrow-up-right` - 右上箭头 (对应 `ArrowUpRight`) -- `chevron-left` - 左箭头 (对应 `ChevronLeft`) -- `search` - 搜索 (对应 `Search`) -- `heart` - 心形 (对应 `Heart`) - ---- - -### 3. 样式定义 (`icon.wxss`) - -```css -.icon { - display: inline-flex; - align-items: center; - justify-content: center; - flex-shrink: 0; -} - -.icon-svg { - width: 100%; - height: 100%; - display: flex; - align-items: center; - justify-content: center; -} - -.icon-svg svg { - display: block; -} -``` - ---- - -## 🚀 使用示例 - -### 在页面中引入组件 - -**页面 JSON 配置** (`read.json`): -```json -{ - "usingComponents": { - "icon": "/components/icon/icon" - } -} -``` - ---- - -### 阅读页悬浮分享按钮 - -**WXML** (`pages/read/read.wxml`): -```xml - -``` - -**WXSS** (`pages/read/read.wxss`): -```css -.fab-share { - position: fixed; - right: 32rpx; - bottom: calc(120rpx + env(safe-area-inset-bottom)); - width: 96rpx; - height: 96rpx; - border-radius: 50%; - background: linear-gradient(135deg, #00CED1 0%, #20B2AA 100%); - box-shadow: 0 8rpx 32rpx rgba(0, 206, 209, 0.4); - display: flex; - align-items: center; - justify-content: center; -} -``` - -**效果**: -- ✅ 右下角圆形悬浮按钮 -- ✅ 品牌色渐变背景 -- ✅ 白色分享图标(Share2) -- ✅ 点击触发微信分享 - ---- - -## 📊 图标对照表 - -| 小程序 | Next.js (lucide-react) | 说明 | -|-------|----------------------|-----| -| `` | `` | 分享(三个点连线)| -| `` | `` | 右上箭头 ↗ | -| `` | `` | 左箭头 < | -| `` | `` | 搜索 🔍 | -| `` | `` | 心形 ❤️ | - ---- - -## 🔧 添加新图标 - -### 步骤 - -1. **访问 lucide.dev**,搜索需要的图标 -2. **复制 SVG 代码** -3. **在 `icon.wxml` 中添加**: - -```xml - - - - - -``` - -### 示例:添加 Star 图标 - -**从 lucide.dev 复制 Star 的 SVG**: -```xml - - - - - -``` - -**使用**: -```xml - -``` - ---- - -## 💡 技术优势 - -### 与 lucide-react 保持一致 - -| 特性 | lucide-react | 小程序 icon 组件 | -|-----|--------------|----------------| -| **图标来源** | Lucide 官方 SVG | Lucide 官方 SVG(相同) | -| **实现方式** | React 组件 | 小程序自定义组件 | -| **图标格式** | SVG | SVG(相同) | -| **动态颜色** | className/style | color 属性 | -| **动态尺寸** | className/style | size 属性 | - -**一致性**: ✅ SVG path 数据完全相同,视觉效果一致 - ---- - -### 相比其他方案的优势 - -#### vs. 字体图标 (iconfont) - -| 方案 | 优点 | 缺点 | -|-----|------|-----| -| **字体图标** | 兼容性好 | ❌ 需要字体文件(增加包体积)
❌ Base64 编码体积大
❌ 只能单色 | -| **SVG 组件** | ✅ 无需字体文件
✅ 支持多色
✅ 按需加载
✅ 完全矢量 | 需要创建组件 | - -#### vs. 图片图标 - -| 方案 | 优点 | 缺点 | -|-----|------|-----| -| **PNG/JPG** | 简单 | ❌ 不同尺寸需要多张图
❌ 放大模糊
❌ 无法动态着色 | -| **SVG 组件** | ✅ 任意缩放清晰
✅ 动态着色
✅ 体积更小 | 需要创建组件 | - ---- - -## 🎨 使用场景 - -### 1. 悬浮按钮 - -```xml - -``` - -### 2. 导航按钮 - -```xml - - - -``` - -### 3. 搜索按钮 - -```xml - - - -``` - -### 4. 列表右箭头 - -```xml - - 菜单项 - - -``` - ---- - -## 📋 后续优化 - -### 1. 扩展图标库 - -根据需求逐步添加更多 lucide 图标: -- `wallet` - 钱包 -- `gift` - 礼物 -- `info` - 信息 -- `settings` - 设置 -- `user` - 用户 -- `book-open` - 打开的书 -- `eye` - 眼睛 -- `clock` - 时钟 -- `users` - 用户组 -- `chevron-right` - 右箭头 -- `x` - 关闭 - -### 2. 全局引入 - -在 `app.json` 中全局引入组件: -```json -{ - "usingComponents": { - "icon": "/components/icon/icon" - } -} -``` - -**优点**: 所有页面都可直接使用,无需单独引入 - ---- - -### 3. 创建图标文档 - -维护一个图标速查表,方便团队使用: -``` -/components/icon/ICONS.md -``` - ---- - -## 🧪 测试验证 - -### 必测项 - -- [ ] 阅读页悬浮分享按钮显示正确 -- [ ] 图标大小和颜色符合预期 -- [ ] 图标清晰无锯齿 -- [ ] 点击分享按钮功能正常 -- [ ] 图标在不同屏幕尺寸下显示正常 - -### 兼容性测试 - -- [ ] iOS 真机测试 -- [ ] Android 真机测试 -- [ ] 微信开发者工具测试 - ---- - -## 📋 修改文件清单 - -| 文件 | 说明 | -|-----|------| -| `/components/icon/icon.wxml` | SVG 图标模板 | -| `/components/icon/icon.js` | 组件逻辑 | -| `/components/icon/icon.wxss` | 组件样式 | -| `/components/icon/icon.json` | 组件配置 | -| `/components/icon/README.md` | 使用文档 | -| `pages/read/read.json` | 引入 icon 组件 | -| `pages/read/read.wxml` | 使用 icon 组件替换文本图标 | -| `pages/read/read.wxss` | 移除旧的 `.fab-share-icon` 样式 | - ---- - -## ✨ 总结 - -### 实现效果 - -- ✅ 创建了与 lucide-react 对应的 SVG 图标组件 -- ✅ 支持动态尺寸、颜色、样式 -- ✅ 轻量级、无需字体文件 -- ✅ 完全矢量、任意缩放不失真 -- ✅ SVG path 与 lucide 完全相同,视觉一致 - -### 技术亮点 - -- 🎯 对标 lucide-react,保持跨端一致 -- 🎨 SVG 矢量图标,高清无损 -- 🚀 轻量级,按需加载 -- 🔧 易扩展,复制粘贴即可添加新图标 -- 📱 兼容性好,所有小程序都支持 - ---- - -**图标系统创建完成!阅读页分享按钮已使用专业的 SVG 分享图标。** 🎉 diff --git a/miniprogram/图标组件SVG显示修复说明.md b/miniprogram/图标组件SVG显示修复说明.md deleted file mode 100644 index b22decb5..00000000 --- a/miniprogram/图标组件SVG显示修复说明.md +++ /dev/null @@ -1,348 +0,0 @@ -# 图标组件 SVG 显示修复说明 - -**修复日期**: 2026-02-04 -**问题**: 阅读页悬浮分享按钮图标不显示 -**原因**: 微信小程序不支持直接使用 `` 标签 -**解决方案**: 使用 Base64 编码 + `image` 组件 - ---- - -## 🐛 问题描述 - -### 原始实现(错误) - -在 `icon.wxml` 中直接使用 SVG 标签: - -```xml - - - - - - -``` - -**结果**: ❌ 图标不显示 - -**原因**: 微信小程序**不支持直接使用 SVG 标签**,只有 `image` 组件支持 SVG 格式。 - ---- - -## ✅ 解决方案 - -### Base64 编码 + image 组件 - -将 SVG 转换为 Base64 Data URL,通过 `image` 组件加载。 - ---- - -## 🔧 修复实现 - -### 1. 修改 `icon.wxml` - -**简化模板,使用 image 组件**: - -```xml - - - - {{name}} - -``` - -**关键变化**: -- ❌ 移除所有 `` 标签 -- ✅ 使用 `` 组件 -- ✅ 数据绑定 `svgData`(Base64 编码) - ---- - -### 2. 修改 `icon.js` - -**添加 SVG 到 Base64 转换逻辑**: - -```javascript -Component({ - properties: { - name: { - type: String, - value: 'share', - observer: 'updateIcon' // 监听变化 - }, - color: { - type: String, - value: '#ffffff', - observer: 'updateIcon' // 监听变化 - }, - // ... 其他属性 - }, - - data: { - svgData: '' // 存储 Base64 Data URL - }, - - lifetimes: { - attached() { - this.updateIcon() // 组件加载时生成图标 - } - }, - - methods: { - // SVG 图标数据映射 - getSvgPath(name) { - const svgMap = { - 'share': '', - // ... 其他图标 - } - return svgMap[name] || '' - }, - - // 更新图标(生成 Base64 Data URL) - updateIcon() { - const { name, color } = this.data - let svgString = this.getSvgPath(name) - - if (svgString) { - // 1. 替换颜色占位符 - svgString = svgString.replace(/COLOR/g, color) - - // 2. 转换为 Base64 Data URL - const svgData = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}` - - this.setData({ svgData }) - } else { - this.setData({ svgData: '' }) - } - } - } -}) -``` - -**核心逻辑**: - -1. **SVG 模板**: 在 `getSvgPath` 中定义 SVG 字符串,使用 `COLOR` 占位符 -2. **颜色替换**: `svgString.replace(/COLOR/g, color)` 动态替换颜色 -3. **Base64 编码**: `encodeURIComponent(svgString)` 进行 URL 编码 -4. **Data URL**: 拼接成 `data:image/svg+xml;charset=utf-8,...` 格式 -5. **Observer**: 监听 `name` 和 `color` 变化,自动更新图标 - ---- - -### 3. 修改 `icon.wxss` - -**简化样式**: - -```css -.icon { - display: inline-flex; - align-items: center; - justify-content: center; - flex-shrink: 0; -} - -.icon-image { - display: block; - width: 100%; - height: 100%; -} - -.icon-text { - font-size: 24rpx; - color: currentColor; -} -``` - ---- - -## 📊 技术对比 - -### 方案对比 - -| 方案 | 优点 | 缺点 | 小程序支持 | -|-----|------|------|-----------| -| **直接使用 `` 标签** | 简洁直观 | ❌ 小程序不支持 | ❌ 不支持 | -| **SVG 文件 + ``** | 兼容性好 | 需要多个文件,不灵活 | ✅ 支持 | -| **Base64 SVG + ``** | 动态生成,灵活着色 | 需要编码处理 | ✅ 支持(最佳) | -| **字体图标** | 兼容性好 | 包体积大,只能单色 | ✅ 支持 | - -**选择理由**: Base64 SVG 方案**最灵活**,支持动态颜色、任意尺寸,且无需额外文件。 - ---- - -### Base64 Data URL 格式 - -``` -data:image/svg+xml;charset=utf-8, -``` - -**示例**: -``` -data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D%220%200%2024%2024%22... -``` - -**为什么用 `encodeURIComponent`**: -- SVG 中的特殊字符(`<`, `>`, `"`, `#` 等)需要转义 -- `encodeURIComponent` 会将这些字符转换为 `%xx` 格式 - ---- - -## 🎯 使用效果 - -### 阅读页分享按钮 - -**WXML**: -```xml - -``` - -**效果**: -- ✅ 图标正常显示 -- ✅ 白色分享图标(三个圆点连线) -- ✅ 尺寸 48rpx -- ✅ 矢量图,清晰无锯齿 -- ✅ 支持动态改变颜色和尺寸 - ---- - -## 🔧 添加新图标 - -### 步骤 - -1. 访问 [lucide.dev](https://lucide.dev) -2. 搜索所需图标,复制 SVG 代码 -3. 在 `icon.js` 的 `getSvgPath` 中添加: - -```javascript -getSvgPath(name) { - const svgMap = { - 'share': '...', - - // 新增图标 - 'star': '', - } - return svgMap[name] || '' -} -``` - -**注意事项**: -- ✅ 保持 `viewBox="0 0 24 24"` -- ✅ 使用 `stroke="COLOR"` 作为颜色占位符 -- ✅ 保持 `stroke-width="2"` 和其他样式属性 -- ✅ 去掉换行和多余空格(压缩 SVG) - ---- - -## 🧪 测试验证 - -### 测试项 - -- [x] 阅读页分享按钮图标显示正常 -- [x] 图标颜色为白色 -- [x] 图标尺寸 48rpx -- [x] 图标清晰无锯齿 -- [x] 更改 `color` 属性,图标颜色动态变化 -- [x] 更改 `size` 属性,图标尺寸动态变化 - -### 在微信开发者工具中验证 - -1. 打开阅读页 -2. 检查右下角悬浮分享按钮 -3. 应看到清晰的分享图标(三个圆点连线) - ---- - -## 📋 修改文件清单 - -| 文件 | 修改内容 | -|-----|---------| -| `components/icon/icon.wxml` | 移除 SVG 标签,改用 image 组件 | -| `components/icon/icon.js` | 添加 Base64 转换逻辑,监听属性变化 | -| `components/icon/icon.wxss` | 简化样式,移除 SVG 相关样式 | -| `components/icon/README.md` | 更新使用文档,说明技术实现 | - ---- - -## 💡 关键技术点 - -### 1. Observer 模式 - -监听属性变化,自动更新图标: -```javascript -name: { - type: String, - value: 'share', - observer: 'updateIcon' // name 变化时调用 updateIcon -} -``` - -### 2. encodeURIComponent - -将 SVG 字符串转换为 URL 安全格式: -```javascript -const svgData = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}` -``` - -### 3. 动态颜色替换 - -使用占位符 `COLOR`,运行时替换: -```javascript -svgString = svgString.replace(/COLOR/g, color) -``` - ---- - -## 🚀 扩展性 - -### 支持更多图标 - -在 `svgMap` 中添加更多 lucide 图标: -- `wallet` - 钱包 -- `gift` - 礼物 -- `settings` - 设置 -- `user` - 用户 -- `book-open` - 打开的书 -- 等等... - -### 支持多色图标 - -修改 SVG 模板,使用多个占位符: -```javascript -'icon-name': '' -``` - -添加新属性: -```javascript -properties: { - color: { type: String, value: '#ffffff' }, - color2: { type: String, value: '#00CED1' }, // 第二种颜色 -} -``` - ---- - -## ✨ 总结 - -### 问题 -- ❌ 小程序不支持直接使用 `` 标签 - -### 解决方案 -- ✅ Base64 编码 SVG + `image` 组件 -- ✅ 动态生成 Data URL -- ✅ 支持动态颜色和尺寸 - -### 效果 -- ✅ 图标正常显示 -- ✅ 完全矢量,任意缩放清晰 -- ✅ 灵活着色,与 lucide-react 一致 -- ✅ 轻量级,无需外部文件 - ---- - -**图标显示问题已修复!** 🎉 diff --git a/miniprogram/小程序快速配置指南.md b/miniprogram/小程序快速配置指南.md deleted file mode 100644 index 7c902486..00000000 --- a/miniprogram/小程序快速配置指南.md +++ /dev/null @@ -1,272 +0,0 @@ -# 小程序快速配置指南 ⚡ - -> 5分钟内完成配置,快速开始开发! - -## 🎯 配置前准备 - -- ✅ 已安装微信开发者工具 -- ✅ 已有小程序AppID(或使用测试AppID) -- ✅ 后端API服务器已启动 - -## 📝 必须配置的3个地方 - -### 1️⃣ 配置小程序AppID - -**文件**: `project.config.json` - -\`\`\`json -{ - "appid": "你的小程序AppID", // ⬅️ 改这里 - "projectname": "soul-party-book" -} -\`\`\` - -> 💡 没有AppID?使用测试号:`wxd7e8c8a8e8c8a8e8` - ---- - -### 2️⃣ 配置API服务器地址 - -**文件**: `app.js` - -\`\`\`javascript -globalData: { - apiBase: 'http://localhost:3000/api', // ⬅️ 改这里 - // 本地开发: http://localhost:3000/api - // 线上环境: https://your-domain.com/api -} -\`\`\` - ---- - -### 3️⃣ 配置服务器域名(线上部署时) - -登录[小程序后台](https://mp.weixin.qq.com/): - -开发管理 → 开发设置 → 服务器域名 - -\`\`\` -request合法域名: -https://your-domain.com - -uploadFile合法域名: -https://your-domain.com - -downloadFile合法域名: -https://your-domain.com -\`\`\` - ---- - -## 🚀 启动步骤 - -### 第一步:启动后端服务器 - -在项目根目录运行: - -\`\`\`bash -# Mac/Linux -chmod +x start-miniprogram.sh -./start-miniprogram.sh - -# Windows -npm run dev -# 或 -pnpm dev -\`\`\` - -看到以下信息表示成功: - -\`\`\` -✓ Ready in 2.3s -○ Local: http://localhost:3000 -\`\`\` - ---- - -### 第二步:打开微信开发者工具 - -1. 点击"导入项目" -2. 选择 `miniprogram` 文件夹 -3. 填入AppID(或选择测试号) -4. 点击"导入" - ---- - -### 第三步:点击编译 - -点击工具栏的"编译"按钮,等待编译完成。 - ---- - -### 第四步:开始开发!🎉 - -现在你可以: - -- 👀 在模拟器中查看效果 -- 📱 扫码在真机预览 -- 🔧 修改代码实时刷新 -- 📊 查看Network请求 - ---- - -## 🧪 功能测试清单 - -### ✅ 首页测试 - -- [ ] 书籍封面正常显示 -- [ ] 最新章节列表加载 -- [ ] 点击章节可跳转阅读 -- [ ] 购买按钮有响应 - -### ✅ 匹配书友测试 - -- [ ] 星空背景动画流畅 -- [ ] 点击"开始匹配"有动画 -- [ ] 3-6秒后匹配成功 -- [ ] 显示匹配用户信息 - -### ✅ 我的页面测试 - -- [ ] 点击头像可登录 -- [ ] 分销中心数据显示 -- [ ] 生成推广海报功能 -- [ ] 复制邀请码功能 - -### ✅ 阅读页测试 - -- [ ] 章节内容正常渲染 -- [ ] 书签功能正常 -- [ ] 目录侧滑打开 -- [ ] 分享功能正常 - ---- - -## 🔧 常见问题 - -### Q1: 编译报错 "Cannot find module" - -**解决**:检查后端服务器是否启动 - -\`\`\`bash -# 重新启动后端 -pnpm dev -\`\`\` - ---- - -### Q2: 页面空白,没有数据 - -**解决**:检查API地址配置 - -1. 打开 `app.js` -2. 确认 `apiBase` 地址正确 -3. 在浏览器访问 `http://localhost:3000/api` 测试 - ---- - -### Q3: 图片不显示 - -**解决**:图片路径问题 - -临时方案:使用在线图片URL - -\`\`\`javascript -// 将本地路径 -src="/assets/images/book-cover.png" - -// 改为在线URL -src="https://picsum.photos/400/560" -\`\`\` - ---- - -### Q4: 支付测试失败 - -**解决**:本地开发暂时无法测试真实支付 - -- 使用Mock数据模拟支付成功 -- 真实支付需要: - 1. 配置微信支付商户号 - 2. 部署到HTTPS域名 - 3. 在小程序后台配置支付权限 - ---- - -### Q5: 模拟器和真机效果不一致 - -**解决**:以真机为准 - -\`\`\`bash -# 真机调试步骤: -1. 点击工具栏"预览" -2. 手机微信扫码 -3. 在手机上调试 -\`\`\` - ---- - -## 📞 获取帮助 - -### 技术支持 - -- **文档**: 查看 `开发文档/` 目录 - -### 官方文档 - -- [微信小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/framework/) -- [微信支付文档](https://pay.weixin.qq.com/wiki/doc/api/index.html) - ---- - -## 🎨 自定义配置(可选) - -### 修改主题色 - -**文件**: `app.wxss` - -\`\`\`css -.brand-color { - color: #FF4D4F; /* 改成你的品牌色 */ -} -\`\`\` - ---- - -### 修改TabBar图标 - -替换 `assets/icons/` 目录下的图片: - -- `home.png` / `home-active.png` - 首页 -- `match.png` / `match-active.png` - 匹配 -- `my.png` / `my-active.png` - 我的 - -要求:尺寸81x81像素,PNG格式 - ---- - -### 修改分享海报 - -**文件**: `pages/my/my.js` 中的 `drawPoster()` 函数 - -可自定义: - -- 背景颜色 -- 文字内容 -- 二维码位置 -- Logo展示 - ---- - -## ✨ 下一步 - -配置完成后,你可以: - -1. 📖 阅读[开发文档](../开发文档/小程序开发完成说明.md) -2. 🎨 自定义UI样式 -3. 🔧 添加新功能 -4. 🚀 准备上线发布 - ---- - -**祝开发顺利!** 🎉 diff --git a/miniprogram/小程序部署说明.md b/miniprogram/小程序部署说明.md deleted file mode 100644 index 7df2d19d..00000000 --- a/miniprogram/小程序部署说明.md +++ /dev/null @@ -1,463 +0,0 @@ -# 🚀 Soul派对小程序 - 部署完成说明 - -**部署时间**: 2025年1月14日 -**配置状态**: ✅ 已完成配置 - ---- - -## ✅ 当前配置信息 - -### 小程序配置 - -| 项目 | 配置值 | -|------|--------| -| **AppID** | `wx0976665c3a3d5a7c` | -| **AppSecret** | `a262f1be43422f03734f205d0bca1882` | -| **API域名** | `http://kr-soul.lytiao.com` | -| **API路径** | `http://kr-soul.lytiao.com/api` | - -### 已配置文件 - -✅ `miniprogram/project.config.json` - AppID已配置 -✅ `miniprogram/app.js` - API地址已配置 -✅ `.env.production` - 生产环境配置 -✅ `app/api/wechat/login/route.ts` - 微信登录接口 -✅ `app/api/book/latest-chapters/route.ts` - 章节接口 - ---- - -## 🎯 快速测试(3步骤) - -### 第1步:启动本地服务器 - -\`\`\`bash -cd "/Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验" - -# 安装依赖(如果还没安装) -pnpm install - -# 启动开发服务器 -pnpm dev -\`\`\` - -✅ 看到 `Ready in 2.3s` 表示成功 - ---- - -### 第2步:打开微信开发者工具 - -1. 打开微信开发者工具 -2. 点击 **"导入项目"** -3. 选择目录: - \`\`\` - /Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验/miniprogram - \`\`\` -4. AppID会自动识别:`wx0976665c3a3d5a7c` -5. 点击 **"导入"** - ---- - -### 第3步:本地联调测试 - -在微信开发者工具中: - -1. 点击右上角 **"详情"** -2. 找到 **"本地设置"** -3. 勾选 **"不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书"** -4. 点击 **"编译"** 按钮 - -✅ 现在可以在模拟器中测试了! - ---- - -## 📱 功能测试清单 - -### 首页测试 - -- [ ] 书籍封面显示 -- [ ] 最新章节列表 -- [ ] 点击章节跳转 -- [ ] 购买按钮响应 - -### 匹配书友测试 - -- [ ] 星空动画流畅 -- [ ] 匹配功能运行 -- [ ] 匹配成功显示 - -### 我的页面测试 - -- [ ] 点击登录功能 -- [ ] 分销中心展示 -- [ ] 海报生成功能 - -### 阅读页测试 - -- [ ] 章节内容加载 -- [ ] 目录侧滑 -- [ ] 书签功能 - ---- - -## 🌐 正式部署到服务器 - -### 域名配置检查 - -你的域名:`http://kr-soul.lytiao.com` - -#### ⚠️ 重要:需要配置HTTPS - -小程序要求所有网络请求必须使用HTTPS! - -**配置SSL证书步骤**: - -1. 登录阿里云控制台 -2. 进入 **"SSL证书"** 服务 -3. 申请免费SSL证书(DV证书) -4. 下载证书文件 -5. 在服务器上配置证书 - -**配置后域名应该是**: -\`\`\` -https://kr-soul.lytiao.com -\`\`\` - ---- - -### 服务器部署步骤 - -#### 1. 将代码上传到服务器 - -\`\`\`bash -# 方式1:使用Git -cd /var/www -git clone your-repo-url soul-party -cd soul-party - -# 方式2:使用SCP上传 -scp -r ./一场soul的创业实验 root@kr-soul.lytiao.com:/var/www/soul-party -\`\`\` - -#### 2. 安装依赖并构建 - -\`\`\`bash -# 在服务器上执行 -cd /var/www/soul-party - -# 安装依赖 -npm install - -# 构建生产版本 -npm run build -\`\`\` - -#### 3. 使用PM2启动服务 - -\`\`\`bash -# 安装PM2(如果没有) -npm install -g pm2 - -# 启动服务 -pm2 start npm --name "soul-party" -- start - -# 设置开机自启 -pm2 startup -pm2 save -\`\`\` - -#### 4. 配置Nginx反向代理 - -创建Nginx配置文件:`/etc/nginx/sites-available/soul-party` - -\`\`\`nginx -server { - listen 80; - server_name kr-soul.lytiao.com; - - # 强制跳转HTTPS - return 301 https://$server_name$request_uri; -} - -server { - listen 443 ssl http2; - server_name kr-soul.lytiao.com; - - # SSL证书配置 - ssl_certificate /path/to/your/cert.pem; - ssl_certificate_key /path/to/your/key.pem; - - # API代理 - location /api { - proxy_pass http://localhost:3000; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header Host $host; - proxy_cache_bypass $http_upgrade; - } - - # 静态文件 - location / { - proxy_pass http://localhost:3000; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header Host $host; - proxy_cache_bypass $http_upgrade; - } -} -\`\`\` - -启用配置: - -\`\`\`bash -# 创建软链接 -ln -s /etc/nginx/sites-available/soul-party /etc/nginx/sites-enabled/ - -# 测试配置 -nginx -t - -# 重启Nginx -systemctl restart nginx -\`\`\` - ---- - -### 小程序后台配置 - -#### 1. 登录小程序后台 - -访问:https://mp.weixin.qq.com/ - -使用AppID `wx0976665c3a3d5a7c` 对应的账号登录 - -#### 2. 配置服务器域名 - -**开发管理** → **开发设置** → **服务器域名** - -添加以下域名: - -\`\`\` -request合法域名: -https://kr-soul.lytiao.com - -uploadFile合法域名: -https://kr-soul.lytiao.com - -downloadFile合法域名: -https://kr-soul.lytiao.com -\`\`\` - -⚠️ **注意**:必须是HTTPS域名,HTTP会被拒绝! - -#### 3. 配置业务域名(可选) - -如果需要在小程序内打开网页: - -**开发管理** → **开发设置** → **业务域名** - -添加:`kr-soul.lytiao.com` - ---- - -## 📤 上传代码到微信后台 - -### 1. 上传代码 - -在微信开发者工具中: - -1. 点击工具栏 **"上传"** 按钮 -2. 填写版本号:`1.0.0` -3. 填写项目备注:`Soul派对小程序正式版` -4. 点击 **"上传"** - -✅ 上传成功后,代码会出现在小程序后台 - ---- - -### 2. 提交审核 - -登录小程序后台: - -1. **版本管理** → **开发版本** -2. 找到刚上传的版本 -3. 点击 **"提交审核"** -4. 填写审核信息: - - 类别:图书/阅读 - - 标签:电子书、创业、私域运营 - - 功能说明:提供电子书阅读和分销功能 - -审核时间:通常1-3个工作日 - ---- - -### 3. 发布上线 - -审核通过后: - -1. **版本管理** → **审核版本** -2. 点击 **"发布"** -3. 全量发布给所有用户 - -🎉 **上线成功!** - ---- - -## 🔧 本地开发配置 - -### 方式1:使用本地API(推荐开发时) - -**文件**: `miniprogram/app.js` - -\`\`\`javascript -apiBase: 'http://localhost:3000/api' -\`\`\` - -然后在开发者工具中勾选 **"不校验合法域名"** - ---- - -### 方式2:使用线上API - -**文件**: `miniprogram/app.js` - -\`\`\`javascript -apiBase: 'https://kr-soul.lytiao.com/api' -\`\`\` - -必须配置好HTTPS和域名白名单 - ---- - -## 📊 API接口测试 - -### 测试微信登录接口 - -\`\`\`bash -curl -X POST http://kr-soul.lytiao.com/api/wechat/login \ - -H "Content-Type: application/json" \ - -d '{"code":"test_code"}' -\`\`\` - -### 测试章节列表接口 - -\`\`\`bash -curl http://kr-soul.lytiao.com/api/book/latest-chapters -\`\`\` - -### 测试后台管理接口 - -\`\`\`bash -curl http://kr-soul.lytiao.com/api/admin -\`\`\` - ---- - -## 🎨 生成小程序码 - -### 方式1:使用微信开发者工具 - -1. 点击工具栏 **"预览"** -2. 自动生成小程序码 -3. 用微信扫码即可预览 - ---- - -### 方式2:使用官方API生成 - -需要调用微信接口: - -\`\`\`javascript -// 获取小程序码 -POST https://api.weixin.qq.com/wxa/getwxacode?access_token=TOKEN - -{ - "path": "pages/index/index", - "width": 430 -} -\`\`\` - -会生成二维码图片,保存后可分享 - ---- - -## ⚠️ 常见问题 - -### Q1: 提示"不在以下request合法域名列表中" - -**解决**: -1. 开发时:勾选"不校验合法域名" -2. 正式环境:在小程序后台配置域名白名单 - ---- - -### Q2: API请求失败 - -**检查清单**: -- [ ] 服务器是否启动? -- [ ] 域名是否配置HTTPS? -- [ ] 小程序后台是否配置域名? -- [ ] API接口是否正常? - ---- - -### Q3: 登录失败 - -**解决**: -1. 检查AppID和AppSecret是否正确 -2. 查看控制台错误信息 -3. 确认微信登录接口正常 - ---- - -## 📞 技术支持 - -### 联系方式 - -- **项目路径**: `/Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验` - -### 快速命令 - -\`\`\`bash -# 启动开发服务器 -cd "/Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验" -pnpm dev - -# 构建生产版本 -pnpm build - -# 启动生产服务器 -pnpm start - -# 查看日志(如果使用PM2) -pm2 logs soul-party -\`\`\` - ---- - -## ✅ 配置完成清单 - -- [x] AppID配置完成 -- [x] API地址配置完成 -- [x] 微信登录接口创建完成 -- [x] 书籍接口创建完成 -- [x] 环境变量配置完成 -- [x] 部署脚本创建完成 -- [ ] HTTPS证书配置(需要在服务器上操作) -- [ ] 小程序后台域名配置(需要在微信后台操作) -- [ ] 代码上传审核(需要在开发者工具操作) - ---- - -## 🎉 下一步 - -1. **本地测试** - 在开发者工具中测试所有功能 -2. **服务器部署** - 将代码部署到 `kr-soul.lytiao.com` -3. **配置HTTPS** - 申请并配置SSL证书 -4. **配置域名** - 在小程序后台配置服务器域名 -5. **提交审核** - 上传代码并提交审核 -6. **发布上线** - 审核通过后发布 - ---- - -**祝部署顺利!** 🚀 diff --git a/miniprogram/底部菜单图标对齐Next说明.md b/miniprogram/底部菜单图标对齐Next说明.md deleted file mode 100644 index e836fec6..00000000 --- a/miniprogram/底部菜单图标对齐Next说明.md +++ /dev/null @@ -1,363 +0,0 @@ -# 底部菜单图标对齐 Next.js 说明 - -**更新日期**: 2026-02-04 -**目标**: 小程序底部菜单图标与 Next.js 保持一致 -**使用**: lucide-react SVG 图标 - ---- - -## 🎯 图标对应关系 - -| Tab | 小程序名称 | Next.js 图标 | SVG 文件 | 说明 | -|-----|----------|-------------|---------|------| -| **1** | 首页 | `Home` | `home.svg` | 房子图标 | -| **2** | 目录 | `List` | `list.svg` | 列表图标(三条横线+圆点)| -| **3** | 找伙伴 | `Sparkles` | `sparkles.svg` | 星光/闪烁图标 | -| **4** | 我的 | `User` | `user.svg` | 用户头像图标 | - ---- - -## 📱 Next.js 底部导航 - -从 `app/view/temp_page.tsx` 可以看到: - -```tsx -import { Home, Sparkles, User } from "lucide-react" - -首页 - - - {/* 匹配书友 */} - - - 匹配书友 - - - {/* 我的 */} - - - 我的 - - -``` - -**注意**: Next.js 版本只有 3 个 Tab(首页、匹配书友、我的),小程序有 4 个 Tab(首页、目录、找伙伴、我的)。 - ---- - -## 🔧 小程序实现 - -### 1. 创建 SVG 图标文件 - -所有图标放在 `/assets/icons/` 目录: - -``` -miniprogram/ -└── assets/ - └── icons/ - ├── home.svg # Home - 首页图标 - ├── list.svg # List - 目录图标 - ├── sparkles.svg # Sparkles - 找伙伴图标 - ├── user.svg # User - 我的图标 - └── share.svg # Share2 - 分享图标 -``` - ---- - -### 2. Home 图标 (首页) - -**lucide-react**: `` - -**SVG** (`home.svg`): -```svg - - - - -``` - ---- - -### 3. List 图标 (目录) - -**lucide-react**: `` - -**SVG** (`list.svg`): -```svg - - - - - - - - -``` - -**说明**: 三条横线 + 左侧圆点,标准的列表/目录图标 - ---- - -### 4. Sparkles 图标 (找伙伴) - -**lucide-react**: `` - -**SVG** (`sparkles.svg`): -```svg - - - - -``` - -**说明**: 星光/闪烁效果,表示匹配、发现 - ---- - -### 5. User 图标 (我的) - -**lucide-react**: `` - -**SVG** (`user.svg`): -```svg - - - - -``` - ---- - -## 📝 WXML 实现 - -`custom-tab-bar/index.wxml`: - -```xml - - - - - - 首页 - - - - - - - - 目录 - - - - - - - - 找伙伴 - - - - - - - - 我的 - -``` - ---- - -## 🎨 WXSS 样式 - -`custom-tab-bar/index.wxss`: - -```css -/* SVG 图标基础样式 */ -.tab-icon { - width: 48rpx; - height: 48rpx; - display: block; - /* 默认灰色 - 使用 CSS filter 改变颜色 */ - filter: brightness(0) saturate(100%) - invert(60%) sepia(0%) saturate(0%) - hue-rotate(0deg) brightness(95%) contrast(85%); -} - -/* 激活状态 - 品牌色 (#00CED1) */ -.tab-icon.icon-active { - filter: brightness(0) saturate(100%) - invert(72%) sepia(54%) saturate(2933%) - hue-rotate(134deg) brightness(101%) contrast(101%); -} - -/* 找伙伴特殊按钮中的图标 */ -.special-icon { - width: 56rpx; - height: 56rpx; - display: block; - /* 白色 */ - filter: brightness(0) saturate(100%) - invert(100%) sepia(0%) saturate(0%) - hue-rotate(0deg) brightness(100%) contrast(100%); -} -``` - ---- - -## 💡 CSS Filter 颜色转换 - -### 为什么用 CSS filter? - -SVG 中的 `stroke="currentColor"` 在小程序 `image` 组件中**不生效**。需要使用 CSS `filter` 来改变 SVG 颜色。 - ---- - -### 颜色对应的 filter 值 - -| 颜色 | Hex | Filter 值 | -|-----|-----|----------| -| **灰色**(未选中)| `#8e8e93` | `brightness(0) saturate(100%) invert(60%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(95%) contrast(85%)` | -| **品牌色**(选中)| `#00CED1` | `brightness(0) saturate(100%) invert(72%) sepia(54%) saturate(2933%) hue-rotate(134deg) brightness(101%) contrast(101%)` | -| **白色**(特殊按钮)| `#ffffff` | `brightness(0) saturate(100%) invert(100%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(100%) contrast(100%)` | - ---- - -### 如何生成 filter 值? - -使用在线工具: [CSS Filter Generator](https://codepen.io/sosuke/pen/Pjoqqp) - -1. 输入目标颜色 Hex 值 -2. 点击 "Compute Filters" -3. 复制生成的 filter 值 - ---- - -## 📊 对比总结 - -### 图标一致性 - -| 特性 | Next.js | 小程序 | 一致性 | -|-----|---------|--------|--------| -| **首页图标** | Home | Home | ✅ 完全相同 | -| **目录图标** | - | List | ⚠️ Next.js 无目录 Tab | -| **匹配图标** | Sparkles | Sparkles | ✅ 完全相同 | -| **我的图标** | User | User | ✅ 完全相同 | -| **SVG 代码** | lucide | lucide | ✅ 完全相同 | - ---- - -### 视觉风格 - -| 属性 | Next.js | 小程序 | 一致性 | -|-----|---------|--------|--------| -| **图标来源** | lucide-react | lucide SVG | ✅ 相同 | -| **图标形状** | SVG 矢量 | SVG 矢量 | ✅ 相同 | -| **未选中颜色** | `text-white/40` | 灰色 `#8e8e93` | ✅ 相近 | -| **选中颜色** | `text-[#30D158]`(绿色) | `#00CED1`(青色) | ⚠️ 品牌色不同 | - -**说明**: -- Next.js 使用绿色 `#30D158`(iOS 绿) -- 小程序使用青色 `#00CED1`(品牌色) -- 这是设计上的差异,两边各自保持一致 - ---- - -## 🔧 技术优势 - -### vs. 自绘图标 - -| 方案 | 优点 | 缺点 | -|-----|------|------| -| **CSS 绘制** | 灵活 | 复杂图标难以实现,代码冗长 | -| **SVG 文件** | 专业标准图标,与 Next.js 一致 | 需要额外文件 | - -**选择 SVG**: 为了与 Next.js 保持视觉一致性 - ---- - -### vs. 图片图标 - -| 方案 | 优点 | 缺点 | -|-----|------|------| -| **PNG 图片** | 简单 | 不同尺寸需要多张图,放大模糊 | -| **SVG 文件** | 矢量,任意缩放清晰 | 需要 CSS filter 改变颜色 | - ---- - -## ✅ 实现效果 - -### 未选中状态 -- ✅ 灰色图标 `#8e8e93` -- ✅ 灰色文字 -- ✅ 清晰的 lucide 图标 - -### 选中状态 -- ✅ 品牌色图标 `#00CED1` -- ✅ 品牌色文字 -- ✅ 图标与文字同步变色 - -### 找伙伴特殊按钮 -- ✅ 圆形渐变背景 -- ✅ 白色 Sparkles 图标 -- ✅ 居中对齐 - ---- - -## 📋 修改文件清单 - -| 文件 | 操作 | 说明 | -|-----|------|------| -| `/assets/icons/home.svg` | ✅ 新增 | Home 图标 | -| `/assets/icons/list.svg` | ✅ 新增 | List 图标 | -| `/assets/icons/sparkles.svg` | ✅ 新增 | Sparkles 图标 | -| `/assets/icons/user.svg` | ✅ 新增 | User 图标 | -| `custom-tab-bar/index.wxml` | ✅ 修改 | 使用 SVG 图标替换自绘图标 | -| `custom-tab-bar/index.wxss` | ✅ 修改 | 移除自绘样式,添加 SVG 样式 | - ---- - -## 🧪 测试验证 - -### 必测项 - -- [x] 首页图标显示正确(房子) -- [x] 目录图标显示正确(列表) -- [x] 找伙伴图标显示正确(星光) -- [x] 我的图标显示正确(用户) -- [x] 未选中状态为灰色 -- [x] 选中状态为品牌色 -- [x] 图标清晰无锯齿 -- [x] 切换 Tab 颜色正确变化 - ---- - -## ✨ 总结 - -### 实现效果 -- ✅ 所有底部菜单图标与 Next.js 使用**完全相同的 lucide 图标** -- ✅ SVG 矢量图标,清晰美观 -- ✅ 通过 CSS filter 实现颜色变化 -- ✅ 视觉风格统一,专业规范 - -### 技术亮点 -- 🎯 使用 lucide 官方 SVG 代码 -- 🎨 CSS filter 动态改变图标颜色 -- 🚀 矢量图标,任意缩放清晰 -- 💯 跨端一致,Next.js 和小程序视觉统一 - ---- - -**底部菜单图标已完全对齐 Next.js!** 🎉 diff --git a/miniprogram/底部菜单选中状态修复说明.md b/miniprogram/底部菜单选中状态修复说明.md deleted file mode 100644 index 52ad1c93..00000000 --- a/miniprogram/底部菜单选中状态修复说明.md +++ /dev/null @@ -1,488 +0,0 @@ -# 底部菜单选中状态修复说明 - -**更新日期**: 2026-02-04 -**问题**: 底部菜单没有根据当前路由启动激活高亮 -**修复**: 在 TabBar 组件中添加 `updateSelected()` 方法,自动根据当前路由设置选中状态 - ---- - -## 🐛 问题分析 - -### 原问题 - -**现象**: 打开小程序或刷新页面时,底部 TabBar 的选中状态不正确,没有高亮当前页面对应的 Tab。 - -**原因**: -1. TabBar 组件在 `attached` 时加载配置是**异步操作** -2. 配置加载完成后,没有根据当前路由自动设置 `selected` 状态 -3. 页面的 `onShow` 方法设置 `selected` 时,TabBar 的配置可能还未加载完成 -4. 导致 `matchEnabled` 状态不确定,"我的"页面的索引计算错误 - ---- - -## ✅ 修复方案 - -### 1. 在 TabBar 组件中添加 `updateSelected()` 方法 - -**文件**: `custom-tab-bar/index.js` - -**新增方法**: -```javascript -// 根据当前路由更新选中状态 -updateSelected() { - const pages = getCurrentPages() - if (pages.length === 0) return - - const currentPage = pages[pages.length - 1] - const route = currentPage.route - - let selected = 0 - const { matchEnabled } = this.data - - // 根据路由匹配对应的索引 - if (route === 'pages/index/index') { - selected = 0 - } else if (route === 'pages/chapters/chapters') { - selected = 1 - } else if (route === 'pages/match/match') { - selected = 2 - } else if (route === 'pages/my/my') { - selected = matchEnabled ? 3 : 2 // 动态计算索引 - } - - this.setData({ selected }) -} -``` - -**说明**: -- ✅ 获取当前页面的路由 -- ✅ 根据路由匹配对应的 Tab 索引 -- ✅ "我的"页面根据 `matchEnabled` 动态计算索引(3 或 2) -- ✅ 设置 TabBar 的 `selected` 状态 - ---- - -### 2. 在配置加载完成后调用 `updateSelected()` - -**修改 `loadFeatureConfig()` 方法**: - -**修改前**: -```javascript -async loadFeatureConfig() { - try { - const res = await app.request({...}) - if (res && res.features) { - const matchEnabled = res.features.matchEnabled === true - this.setData({ matchEnabled }) // 只设置配置,没有更新选中状态 - } - } catch (error) { - this.setData({ matchEnabled: false }) - } -} -``` - -**修改后**: -```javascript -async loadFeatureConfig() { - try { - const res = await app.request({...}) - if (res && res.features) { - const matchEnabled = res.features.matchEnabled === true - this.setData({ matchEnabled }, () => { - // 配置加载完成后,根据当前路由设置选中状态 - this.updateSelected() - }) - } - } catch (error) { - this.setData({ matchEnabled: false }, () => { - this.updateSelected() // 容错时也更新选中状态 - }) - } -} -``` - -**改进**: -- ✅ 使用 `setData` 的回调函数,确保配置更新后再设置选中状态 -- ✅ 配置加载成功和失败时都调用 `updateSelected()` -- ✅ 确保选中状态与配置同步 - ---- - -### 3. 更新各页面的 `onShow` 方法 - -**优先调用 TabBar 的 `updateSelected()` 方法**,确保使用最新的配置和路由信息。 - -#### 首页 (`pages/index/index.js`) - -**修改前**: -```javascript -onShow() { - if (typeof this.getTabBar === 'function' && this.getTabBar()) { - this.getTabBar().setData({ selected: 0 }) - } - this.updateUserStatus() -} -``` - -**修改后**: -```javascript -onShow() { - if (typeof this.getTabBar === 'function' && this.getTabBar()) { - const tabBar = this.getTabBar() - if (tabBar.updateSelected) { - tabBar.updateSelected() // 优先使用新方法 - } else { - tabBar.setData({ selected: 0 }) // 降级处理 - } - } - this.updateUserStatus() -} -``` - ---- - -#### 目录 (`pages/chapters/chapters.js`) - -**修改前**: -```javascript -onShow() { - if (typeof this.getTabBar === 'function' && this.getTabBar()) { - this.getTabBar().setData({ selected: 1 }) - } - this.updateUserStatus() -} -``` - -**修改后**: -```javascript -onShow() { - if (typeof this.getTabBar === 'function' && this.getTabBar()) { - const tabBar = this.getTabBar() - if (tabBar.updateSelected) { - tabBar.updateSelected() - } else { - tabBar.setData({ selected: 1 }) - } - } - this.updateUserStatus() -} -``` - ---- - -#### 找伙伴 (`pages/match/match.js`) - -**修改前**: -```javascript -onShow() { - if (typeof this.getTabBar === 'function' && this.getTabBar()) { - this.getTabBar().setData({ selected: 2 }) - } - this.initUserStatus() -} -``` - -**修改后**: -```javascript -onShow() { - if (typeof this.getTabBar === 'function' && this.getTabBar()) { - const tabBar = this.getTabBar() - if (tabBar.updateSelected) { - tabBar.updateSelected() - } else { - tabBar.setData({ selected: 2 }) - } - } - this.initUserStatus() -} -``` - ---- - -#### 我的 (`pages/my/my.js`) - -**修改前**: -```javascript -onShow() { - if (typeof this.getTabBar === 'function' && this.getTabBar()) { - const tabBar = this.getTabBar() - const selected = tabBar.data.matchEnabled ? 3 : 2 // 手动计算 - tabBar.setData({ selected }) - } - this.initUserStatus() -} -``` - -**修改后**: -```javascript -onShow() { - if (typeof this.getTabBar === 'function' && this.getTabBar()) { - const tabBar = this.getTabBar() - if (tabBar.updateSelected) { - tabBar.updateSelected() // 自动计算 - } else { - const selected = tabBar.data.matchEnabled ? 3 : 2 - tabBar.setData({ selected }) - } - } - this.initUserStatus() -} -``` - ---- - -## 🔄 执行流程 - -### 页面启动流程 - -``` -1. 小程序启动,进入 Tab 页面(如首页) - ↓ -2. TabBar 组件 attached,触发 loadFeatureConfig() - ↓ -3. 异步请求 /api/db/config - ↓ -4. 获取 matchEnabled 配置 - ↓ -5. setData({ matchEnabled }, () => { - this.updateSelected() ← 自动根据当前路由设置 selected - }) - ↓ -6. 页面 onShow,调用 tabBar.updateSelected() - ↓ -7. TabBar 正确高亮当前页面对应的 Tab -``` - ---- - -### 切换 Tab 流程 - -``` -1. 用户点击 Tab(如从首页切换到目录) - ↓ -2. wx.switchTab({ url: '/pages/chapters/chapters' }) - ↓ -3. 目录页面 onShow - ↓ -4. 调用 tabBar.updateSelected() - ↓ -5. 根据当前路由 'pages/chapters/chapters' 设置 selected = 1 - ↓ -6. 目录 Tab 高亮 -``` - ---- - -## 📊 索引映射表 - -### matchEnabled = true - -| 页面路由 | Tab名称 | selected值 | -|---------|--------|-----------| -| pages/index/index | 首页 | 0 | -| pages/chapters/chapters | 目录 | 1 | -| pages/match/match | 找伙伴 | 2 | -| pages/my/my | 我的 | **3** | - ---- - -### matchEnabled = false - -| 页面路由 | Tab名称 | selected值 | -|---------|--------|-----------| -| pages/index/index | 首页 | 0 | -| pages/chapters/chapters | 目录 | 1 | -| ~~pages/match/match~~ | ~~隐藏~~ | ~~无~~ | -| pages/my/my | 我的 | **2** | - ---- - -## 🎯 关键技术点 - -### 1. getCurrentPages() 获取当前路由 - -```javascript -const pages = getCurrentPages() -if (pages.length === 0) return - -const currentPage = pages[pages.length - 1] -const route = currentPage.route // 如: 'pages/index/index' -``` - -**注意**: -- `route` 属性不带前导斜杠 -- 需要与 Tab 列表中的 `pagePath` 对比时去掉斜杠 - ---- - -### 2. setData 回调确保同步 - -```javascript -this.setData({ matchEnabled }, () => { - // 回调中的代码在 setData 完成后执行 - this.updateSelected() -}) -``` - -**原因**: -- `setData` 是异步的 -- 使用回调确保配置更新完成后再设置选中状态 - ---- - -### 3. 方法降级处理 - -```javascript -if (tabBar.updateSelected) { - tabBar.updateSelected() // 优先使用新方法 -} else { - tabBar.setData({ selected: 0 }) // 降级处理 -} -``` - -**原因**: -- 兼容旧版本或配置未加载完成的情况 -- 确保代码健壮性 - ---- - -### 4. 动态索引计算 - -```javascript -if (route === 'pages/my/my') { - selected = matchEnabled ? 3 : 2 // 根据配置动态计算 -} -``` - -**原因**: -- "我的"页面的索引取决于是否显示"找伙伴" -- 配置开启时为 3,关闭时为 2 - ---- - -## 🧪 测试验证 - -### 测试场景 - -#### 1. 首次启动 - -**操作**: 清除缓存,打开小程序 - -**预期**: -- [ ] 进入首页时,"首页" Tab 高亮 -- [ ] 进入目录页时,"目录" Tab 高亮 -- [ ] 进入找伙伴页时,"找伙伴" Tab 高亮(如果功能开启) -- [ ] 进入我的页时,"我的" Tab 高亮 - ---- - -#### 2. Tab 切换 - -**操作**: 在各个 Tab 之间切换 - -**预期**: -- [ ] 点击每个 Tab 后,对应 Tab 正确高亮 -- [ ] 高亮状态与当前页面一致 -- [ ] 不会出现多个 Tab 同时高亮或无 Tab 高亮的情况 - ---- - -#### 3. 配置切换 - -**操作**: -1. 管理后台关闭找伙伴功能 -2. 重新进入小程序,进入"我的"页 - -**预期**: -- [ ] "我的" Tab 正确高亮(索引为 2) -- [ ] 不会因为索引错误导致高亮错误 - ---- - -#### 4. 页面刷新 - -**操作**: 在任意 Tab 页面,下拉刷新或重新编译 - -**预期**: -- [ ] 当前 Tab 保持高亮状态 -- [ ] 选中状态不会丢失 - ---- - -## 📋 修改文件清单 - -| 文件 | 修改内容 | -|-----|---------| -| `custom-tab-bar/index.js` | 新增 `updateSelected()` 方法,修改 `loadFeatureConfig()` | -| `pages/index/index.js` | 修改 `onShow()`,优先调用 `updateSelected()` | -| `pages/chapters/chapters.js` | 修改 `onShow()`,优先调用 `updateSelected()` | -| `pages/match/match.js` | 修改 `onShow()`,优先调用 `updateSelected()` | -| `pages/my/my.js` | 修改 `onShow()`,优先调用 `updateSelected()` | - ---- - -## 💡 优化建议 - -### 1. 统一页面 onShow 逻辑 - -可以考虑在 `app.js` 中添加全局方法: - -```javascript -// app.js -App({ - globalData: { - // ... - }, - - // 全局更新 TabBar 选中状态 - updateTabBarSelected() { - const pages = getCurrentPages() - if (pages.length === 0) return - - const currentPage = pages[pages.length - 1] - if (typeof currentPage.getTabBar === 'function' && currentPage.getTabBar()) { - const tabBar = currentPage.getTabBar() - if (tabBar.updateSelected) { - tabBar.updateSelected() - } - } - } -}) -``` - -**页面中简化调用**: -```javascript -onShow() { - getApp().updateTabBarSelected() - this.updateUserStatus() -} -``` - ---- - -### 2. 监听路由变化 - -可以考虑使用 `wx.onAppRoute` 或类似方法,自动监听路由变化并更新 TabBar。 - ---- - -## ✨ 总结 - -### 修复效果 - -- ✅ TabBar 根据当前路由自动高亮对应 Tab -- ✅ 配置加载完成后立即更新选中状态 -- ✅ 支持 `matchEnabled` 动态配置 -- ✅ "我的"页面索引自动适配(3 或 2) -- ✅ 降级处理确保兼容性 - -### 技术亮点 - -- 🎯 集中管理选中状态逻辑 -- 🔄 自动根据路由计算索引 -- 🛡️ 完善的降级处理 -- 📱 与配置系统无缝集成 - ---- - -**修复完成!TabBar 现在会根据当前路由正确高亮。** 🎉 diff --git a/miniprogram/底部菜单配置化说明.md b/miniprogram/底部菜单配置化说明.md deleted file mode 100644 index aba8acec..00000000 --- a/miniprogram/底部菜单配置化说明.md +++ /dev/null @@ -1,475 +0,0 @@ -# 底部菜单配置化说明 - -**更新日期**: 2026-02-04 -**功能**: 根据后台配置动态显示/隐藏"找伙伴"Tab -**默认状态**: 不显示"找伙伴"(matchEnabled = false) - ---- - -## 📋 功能说明 - -底部自定义 TabBar 现在支持根据后台配置 `features.matchEnabled` 动态显示/隐藏"找伙伴"Tab: - -- **matchEnabled = true**: 显示 4 个 Tab(首页、目录、找伙伴、我的) -- **matchEnabled = false**: 显示 3 个 Tab(首页、目录、我的) - ---- - -## 🎯 实现方案 - -### 1. 配置加载 - -**文件**: `custom-tab-bar/index.js` - -**在组件 attached 生命周期中加载配置**: -```javascript -lifetimes: { - attached() { - this.loadFeatureConfig() - } -}, - -methods: { - // 加载功能配置 - async loadFeatureConfig() { - try { - const res = await app.request({ - url: '/api/db/config', - method: 'GET' - }) - - if (res && res.features) { - const matchEnabled = res.features.matchEnabled === true - this.setData({ matchEnabled }) - - // 如果当前在找伙伴页面,但功能已关闭,跳转到首页 - if (!matchEnabled) { - const pages = getCurrentPages() - const currentPage = pages[pages.length - 1] - if (currentPage && currentPage.route === 'pages/match/match') { - wx.switchTab({ url: '/pages/index/index' }) - } - } - } - } catch (error) { - console.log('TabBar加载功能配置失败:', error) - // 默认关闭找伙伴功能 - this.setData({ matchEnabled: false }) - } - } -} -``` - ---- - -### 2. 条件渲染 - -**文件**: `custom-tab-bar/index.wxml` - -**使用 `wx:if` 控制"找伙伴"Tab 显示**: -```xml - - - ... - - - ... - - - - ... - - - - - ... - - -``` - -**关键点**: -- ✅ 使用 `wx:if="{{matchEnabled}}"` 控制"找伙伴"Tab 显示 -- ✅ "我的"Tab 的 `data-index` 根据 `matchEnabled` 动态设置(3 或 2) -- ✅ TabBar 根类名动态切换(`tab-bar-four` 或 `tab-bar-three`) - ---- - -### 3. 选中状态逻辑 - -**"我的"Tab 选中判断**: -```xml - -``` - -**逻辑**: -- 当 `matchEnabled = true` 且 `selected = 3` → 选中 -- 当 `matchEnabled = false` 且 `selected = 2` → 选中 - ---- - -### 4. 样式适配 - -**文件**: `custom-tab-bar/index.wxss` - -**新增三个/四个 Tab 布局样式**: -```css -/* 三个tab布局(找伙伴功能关闭时) */ -.tab-bar-three .tab-bar-item { - flex: 1; -} - -/* 四个tab布局(找伙伴功能开启时) */ -.tab-bar-four .tab-bar-item { - flex: 1; -} -``` - ---- - -### 5. 页面选中状态同步 - -**"我的"页面动态设置 selected**: - -**文件**: `pages/my/my.js` - -```javascript -onShow() { - // 设置TabBar选中状态(根据 matchEnabled 动态设置) - if (typeof this.getTabBar === 'function' && this.getTabBar()) { - const tabBar = this.getTabBar() - const selected = tabBar.data.matchEnabled ? 3 : 2 - tabBar.setData({ selected }) - } - this.initUserStatus() -} -``` - -**其他页面保持固定索引**: -- 首页: `selected: 0` -- 目录: `selected: 1` -- 找伙伴: `selected: 2` - ---- - -## 🎨 UI 展示 - -### matchEnabled = true (4个Tab) - -``` -┌─────────────────────────────────────┐ -│ │ -│ 页面内容区域 │ -│ │ -├─────────────────────────────────────┤ -│ 首页 目录 🔵找伙伴🔵 我的 │ -└─────────────────────────────────────┘ - (25%) (25%) (25%) (25%) -``` - -**特点**: -- 4 个 Tab 等宽分布 -- "找伙伴" 使用中间突出的圆形按钮 -- 每个 Tab 占 25% 宽度 - ---- - -### matchEnabled = false (3个Tab) - -``` -┌─────────────────────────────────────┐ -│ │ -│ 页面内容区域 │ -│ │ -├─────────────────────────────────────┤ -│ 首页 目录 我的 │ -└─────────────────────────────────────┘ - (33.3%) (33.3%) (33.3%) -``` - -**特点**: -- 3 个 Tab 等宽分布 -- 不显示"找伙伴" Tab -- 每个 Tab 占 33.3% 宽度 - ---- - -## 📊 Tab 索引映射 - -### matchEnabled = true - -| Tab名称 | 路径 | selected值 | -|---------|------|-----------| -| 首页 | /pages/index/index | 0 | -| 目录 | /pages/chapters/chapters | 1 | -| 找伙伴 | /pages/match/match | 2 | -| 我的 | /pages/my/my | 3 | - ---- - -### matchEnabled = false - -| Tab名称 | 路径 | selected值 | -|---------|------|-----------| -| 首页 | /pages/index/index | 0 | -| 目录 | /pages/chapters/chapters | 1 | -| ~~找伙伴~~ | ~~隐藏~~ | ~~无~~ | -| 我的 | /pages/my/my | **2** | - ---- - -## 🔄 配置切换流程 - -### 开启找伙伴功能 - -1. **后台操作**: 管理后台 → 系统设置 → 找伙伴功能 → ✅ 开启 -2. **API 更新**: `/api/db/config` 返回 `matchEnabled: true` -3. **TabBar 刷新**: - - 下次进入 Tab 页面时,TabBar 重新 attached - - 调用 `loadFeatureConfig()` 获取最新配置 - - 设置 `matchEnabled: true` -4. **UI 变化**: - - 显示"找伙伴" Tab(中间突出按钮) - - 调整为 4 个 Tab 布局 - - "我的" Tab 索引变为 3 - ---- - -### 关闭找伙伴功能 - -1. **后台操作**: 管理后台 → 系统设置 → 找伙伴功能 → ❌ 关闭 -2. **API 更新**: `/api/db/config` 返回 `matchEnabled: false` -3. **TabBar 刷新**: - - 下次进入 Tab 页面时,TabBar 重新 attached - - 调用 `loadFeatureConfig()` 获取最新配置 - - 设置 `matchEnabled: false` -4. **UI 变化**: - - 隐藏"找伙伴" Tab - - 调整为 3 个 Tab 布局 - - "我的" Tab 索引变为 2 -5. **自动跳转**: - - 如果用户当前在"找伙伴"页面,自动跳转到首页 - ---- - -## 🛡️ 容错处理 - -### 1. 配置加载失败 - -**场景**: API 请求失败、网络异常 - -**处理**: -```javascript -catch (error) { - console.log('TabBar加载功能配置失败:', error) - // 默认关闭找伙伴功能(保守策略) - this.setData({ matchEnabled: false }) -} -``` - -**结果**: 默认不显示"找伙伴" Tab - ---- - -### 2. 用户在"找伙伴"页面时功能关闭 - -**场景**: 用户正在浏览"找伙伴"页面,管理员关闭了该功能 - -**处理**: -```javascript -// 如果当前在找伙伴页面,但功能已关闭,跳转到首页 -if (!matchEnabled) { - const pages = getCurrentPages() - const currentPage = pages[pages.length - 1] - if (currentPage && currentPage.route === 'pages/match/match') { - wx.switchTab({ url: '/pages/index/index' }) - } -} -``` - -**结果**: 自动跳转到首页,避免用户停留在已关闭的功能页面 - ---- - -### 3. 默认状态 - -**初始值**: `matchEnabled: false` - -**原因**: -- ✅ 保守策略,避免显示未启用的功能 -- ✅ 配置加载失败时的安全状态 -- ✅ 首次安装时的默认状态 - ---- - -## 🧪 测试验证 - -### 测试步骤 - -#### 1. 测试默认状态(关闭) - -**操作**: -1. 清除缓存并重新编译 -2. 打开小程序 - -**预期**: -- [ ] 底部显示 3 个 Tab(首页、目录、我的) -- [ ] 不显示"找伙伴" Tab -- [ ] 各 Tab 等宽分布 -- [ ] 点击"我的"进入,TabBar selected = 2 - ---- - -#### 2. 测试开启找伙伴功能 - -**操作**: -1. 管理后台开启找伙伴功能 -2. 重新进入小程序(或切换 Tab 页面) - -**预期**: -- [ ] 底部显示 4 个 Tab(首页、目录、找伙伴、我的) -- [ ] "找伙伴" Tab 显示为中间突出的圆形按钮 -- [ ] 各 Tab 正常分布 -- [ ] 点击"找伙伴"可以跳转 -- [ ] 点击"我的"进入,TabBar selected = 3 - ---- - -#### 3. 测试关闭找伙伴功能 - -**操作**: -1. 在"找伙伴"页面停留 -2. 管理后台关闭找伙伴功能 -3. 切换到其他 Tab 再返回 - -**预期**: -- [ ] 自动跳转到首页(不停留在已关闭的功能页面) -- [ ] 底部显示 3 个 Tab -- [ ] "找伙伴" Tab 消失 - ---- - -#### 4. 测试配置加载失败 - -**操作**: -1. 断网或 Mock API 返回错误 -2. 进入小程序 - -**预期**: -- [ ] 底部显示 3 个 Tab(默认关闭状态) -- [ ] Console 输出错误日志 -- [ ] 不影响其他功能正常使用 - ---- - -## 📋 修改文件清单 - -| 文件 | 修改内容 | -|-----|---------| -| `custom-tab-bar/index.js` | 新增 `matchEnabled` 字段、`loadFeatureConfig` 方法 | -| `custom-tab-bar/index.wxml` | 添加 `wx:if` 条件渲染、动态索引、动态选中状态 | -| `custom-tab-bar/index.wxss` | 新增 `.tab-bar-three` 和 `.tab-bar-four` 样式 | -| `pages/my/my.js` | 修改 `onShow` 方法,动态设置 selected | - ---- - -## 💡 技术要点 - -### 1. 组件生命周期 - -**使用 `lifetimes.attached` 而非 `attached`**: -```javascript -lifetimes: { - attached() { - this.loadFeatureConfig() - } -} -``` - -**原因**: Component 2.0 推荐使用 `lifetimes` 字段定义生命周期 - ---- - -### 2. 动态索引处理 - -**问题**: "我的" Tab 的索引在不同配置下不同 -- matchEnabled = true: index = 3 -- matchEnabled = false: index = 2 - -**解决方案**: 使用三目运算符动态设置 -```xml - -``` - ---- - -### 3. 选中状态判断 - -**问题**: 需要根据 matchEnabled 判断"我的" Tab 是否选中 - -**解决方案**: 复合条件判断 -```xml -{{(matchEnabled && selected === 3) || (!matchEnabled && selected === 2) ? 'icon-active' : ''}} -``` - ---- - -### 4. 配置缓存问题 - -**问题**: 配置更新后,TabBar 可能显示旧状态 - -**解决方案**: -- 每次 `attached` 都重新加载配置 -- 不使用本地缓存,直接请求 API - ---- - -## 🔗 相关配置 - -### API 端点 - -``` -GET /api/db/config -``` - -### 返回数据结构 - -```json -{ - "features": { - "matchEnabled": false, - "referralEnabled": true, - "searchEnabled": true, - "aboutEnabled": true - } -} -``` - -### 后台管理位置 - -``` -Next.js Admin → /admin/settings → 功能开关配置 → 找伙伴功能 -``` - ---- - -## ✨ 总结 - -### 实现效果 - -- ✅ 底部 TabBar 根据后台配置动态显示/隐藏"找伙伴" -- ✅ 默认不显示"找伙伴"(matchEnabled = false) -- ✅ 布局自动适配 3 个或 4 个 Tab -- ✅ 选中状态正确同步 -- ✅ 配置更新自动生效 -- ✅ 完善的容错处理 - -### 技术亮点 - -- 🎯 配置驱动的 UI 显示 -- 🎨 动态布局切换 -- 🛡️ 完善的容错机制 -- 📱 与 Next.js 保持一致的功能控制 - ---- - -**配置化实现完成!请清除缓存后测试。** 🎉 diff --git a/miniprogram/快速测试指南.md b/miniprogram/快速测试指南.md deleted file mode 100644 index b8e28c64..00000000 --- a/miniprogram/快速测试指南.md +++ /dev/null @@ -1,259 +0,0 @@ -# 小程序功能测试快速指南 - -**测试时间**: 2026-02-04 -**测试范围**: 新增和修改的功能 - ---- - -## 🚀 快速开始 - -### 1. 打开项目 - -```bash -# 使用微信开发者工具打开 -打开 -> 选择 miniprogram 目录 -``` - -### 2. 编译预览 - -点击「编译」按钮,确保无报错。 - ---- - -## 🧪 核心功能测试路径 - -### 测试路径1: 目录页搜索 (新增✅) - -``` -操作步骤: -1. 点击底部 Tab「目录」 -2. 查看右上角是否有搜索按钮 🔍 -3. 点击搜索按钮 -4. 应跳转到搜索页 -5. 尝试搜索关键词(如"私域") - -预期结果: -✅ 搜索按钮显示正常,圆形灰色背景 -✅ 点击后跳转到搜索页 -✅ 搜索功能正常 -``` - ---- - -### 测试路径2: 收益卡片艺术化 (新增✅) - -``` -操作步骤: -1. 点击底部 Tab「我的」 -2. 查看用户卡片下方的收益卡片 - -预期结果: -✅ 收益卡片有深蓝渐变背景 -✅ 右上角有金色装饰圆 -✅ 左下角有青色装饰圆 -✅ 收益金额使用金色渐变文字 -✅ 「推广中心/提现」按钮有金色渐变背景 -``` - -效果参考: -``` -背景: #1a1a2e → #16213e → #0f3460 -装饰: 金色圆(右上) + 青色圆(左下) -文字: 金色渐变 #FFD700 → #FFA500 -``` - ---- - -### 测试路径3: 地址管理 (新增✅) - -``` -操作步骤: -1. 我的 → 点击菜单中的「设置」 -2. 在设置页找到「收货地址」项 -3. 点击「管理」按钮 -4. 应跳转到地址列表页 - -地址列表页测试: -- 查看空状态显示 -- 点击「新增收货地址」按钮 -- 跳转到编辑页 - -地址编辑页测试: -- 填写收货人姓名 -- 填写手机号 -- 点击地区选择器,选择省市区 -- 填写详细地址 -- 开启「设为默认地址」开关 -- 点击「保存」按钮 - -返回列表页: -- 查看刚创建的地址卡片 -- 点击「编辑」修改地址 -- 点击「删除」删除地址 - -预期结果: -✅ 所有页面跳转流畅 -✅ 表单验证正常 -✅ 省市区选择器正常 -✅ 保存/编辑/删除功能正常 -✅ 样式与 Next.js 一致 -``` - ---- - -### 测试路径4: 推广中心绑定列表 (已有,验证) - -``` -操作步骤: -1. 我的 → 点击「推广中心」卡片或菜单 -2. 查看「绑定用户」卡片 -3. 点击 Tab 切换(绑定中/已付款/已过期) - -预期结果: -✅ 3个Tab正常切换 -✅ 用户列表正常显示 -✅ 状态标签颜色正确(绿色/橙色/红色) -✅ 空状态显示正常 -``` - ---- - -## 🎨 样式验证要点 - -### 全局色彩 - -打开任意页面,检查: -- 背景色: 纯黑 #000000 ✅ -- 品牌色: 青绿 #00CED1 ✅ -- 卡片背景: #1c1c1e / #2c2c2e ✅ -- 金色: #FFD700 ✅ - -### 卡片样式 - -检查所有卡片: -- 圆角: 24-32rpx ✅ -- 边框: 2rpx solid rgba(255,255,255,0.05) ✅ -- 渐变背景正常 ✅ -- 阴影效果正常 ✅ - -### 按钮样式 - -检查所有按钮: -- 主按钮: 青绿渐变 ✅ -- 金色按钮: 金色渐变 ✅ -- 点击反馈: active 状态 ✅ -- 禁用状态: opacity 0.5 ✅ - ---- - -## ⚠️ 常见问题排查 - -### 问题1: 页面空白或报错 - -**可能原因:** -- 页面未在 `app.json` 注册 -- 路径写错 - -**解决方法:** -```javascript -// 检查 app.json 中是否有: -"pages/addresses/addresses" -"pages/addresses/edit" -``` - -### 问题2: 搜索按钮不显示 - -**可能原因:** -- 缓存问题 - -**解决方法:** -``` -微信开发者工具 → 清除缓存 → 重新编译 -``` - -### 问题3: 收益卡片样式异常 - -**可能原因:** -- CSS 渐变不支持 -- 变量未定义 - -**解决方法:** -```css -/* 检查 app.wxss 是否有 CSS 变量定义 */ ---app-brand: #00CED1; ---gold: #FFD700; -``` - -### 问题4: 地址管理功能报错 - -**可能原因:** -- API 接口未实现 -- 用户未登录 - -**解决方法:** -```javascript -// 检查登录状态 -console.log(app.globalData.isLoggedIn) -console.log(app.globalData.userInfo) - -// 检查 API 接口 -// 需要后端实现以下接口: -// GET /api/user/addresses?userId=xxx -// POST /api/user/addresses -// PUT /api/user/addresses/:id -// DELETE /api/user/addresses/:id -``` - ---- - -## 📱 真机测试 - -### iOS 测试要点 -- 安全区域适配 -- 毛玻璃效果 -- 手势交互 - -### Android 测试要点 -- 渐变显示 -- 动画流畅度 -- 兼容性 - ---- - -## ✅ 测试完成标准 - -### 功能测试通过 -- [ ] 所有新增功能可用 -- [ ] 无报错和崩溃 -- [ ] 交互流畅 - -### 样式测试通过 -- [ ] 颜色显示正确 -- [ ] 布局无错位 -- [ ] 动画流畅 - -### 兼容性测试通过 -- [ ] iOS 正常 -- [ ] Android 正常 -- [ ] 不同机型正常 - ---- - -## 📞 问题反馈 - -如发现问题,请记录: -1. 问题页面 -2. 复现步骤 -3. 截图/录屏 -4. 设备型号和系统版本 - ---- - -**测试人员**: _________ -**测试时间**: _________ -**测试结果**: ⭕ 通过 / ❌ 不通过 -**问题记录**: _________ - ---- - -*预祝测试顺利!* diff --git a/miniprogram/测试二维码.html b/miniprogram/测试二维码.html deleted file mode 100644 index 51ba44cb..00000000 --- a/miniprogram/测试二维码.html +++ /dev/null @@ -1,366 +0,0 @@ - - - - - - Soul派对小程序 - 测试二维码 - - - -
-
-
Soul派对·创业实验
-
微信小程序测试版
-
- -
-
-
配置完成,可以开始测试!
-
- -
-
📋 当前配置
-
-
小程序AppID
-
wx0976665c3a3d5a7c
-
-
-
API域名
-
http://kr-soul.lytiao.com
-
-
-
本地开发地址
-
http://localhost:3000
-
-
-
配置状态
-
✅ 已完成
-
-
- -
-
📱 扫码体验小程序
-
-
📱
-
请在微信开发者工具中生成预览码
-
-

- 在开发者工具中点击"预览"按钮,自动生成小程序码 -

-
- -
-
🚀 快速测试步骤
- -
-
1
-
-
打开微信开发者工具
-
- 选择"导入项目",导入以下目录: -
/Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验/miniprogram
- AppID会自动识别为:wx0976665c3a3d5a7c -
-
-
- -
-
2
-
-
启用本地调试
-
- 点击右上角"详情" → "本地设置" → 勾选"不校验合法域名"
- (这样可以使用本地API: http://localhost:3000) -
-
-
- -
-
3
-
-
点击编译运行
-
- 在模拟器中查看效果,测试所有功能:
- - 首页书籍展示
- - 匹配书友功能
- - 我的页面和分销中心
- - 阅读页面 -
-
-
- -
-
4
-
-
真机预览测试
-
- 点击工具栏"预览"按钮,生成小程序码
- 用微信扫码即可在手机上预览 -
-
-
-
- -
-
⚠️
-
-
正式发布前注意事项
-
- 1. 必须配置HTTPS证书(小程序要求必须HTTPS)
- 2. 在小程序后台配置服务器域名白名单
- 3. 将API地址改为:https://kr-soul.lytiao.com/api
- 4. 上传代码到微信后台提交审核 -
-
-
-
- - - - diff --git a/miniprogram/生成图标.html b/miniprogram/生成图标.html deleted file mode 100644 index 6f041cd5..00000000 --- a/miniprogram/生成图标.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - 生成小程序图标 - - -

小程序底部导航图标生成器

-
- - - -