# bindbox-mini 代码冗余分析 ## 项目概述 bindbox-mini 是一个基于 uni-app 的微信小程序项目,主要实现盲盒/抽赏类活动功能。 ### 技术栈 - 框架:uni-app (Vue 3 Composition API) - 样式:SCSS - 状态管理:Vue ref/computed ### 核心页面 | 页面 | 路径 | 行数 | 功能描述 | |------|------|------|----------| | 一番赏 | `pages/activity/yifanshang/index.vue` | 1229 | 格位选择抽奖 | | 对对碰 | `pages/activity/duiduipeng/index.vue` | 2291 | 配对游戏 | | 无限赏 | `pages/activity/wuxianshang/index.vue` | 1559 | 多次抽奖 | | 扭蛋(啪嗒) | `pages/activity/pata/index.vue` | 399 | 入口页面 | --- ## 🔴 已识别的冗余问题 ### 1. 模板结构重复 三个主要活动页面(yifanshang/duiduipeng/wuxianshang)共享**几乎相同的页面布局结构**: ```vue ``` **冗余程度**:约100-150行相似模板代码 × 3个页面 = ~400行冗余 --- ### 2. 工具函数重复 以下函数在多个页面中**完全重复定义**: | 函数名 | 出现位置 | 功能 | |--------|----------|------| | `cleanUrl(u)` | yifanshang, duiduipeng, wuxianshang | 清理URL字符串 | | `truthy(v)` | yifanshang, duiduipeng, wuxianshang | 判断真值 | | `detectBoss(i)` | yifanshang, duiduipeng, wuxianshang | 检测BOSS奖 | | `unwrap(list)` | yifanshang, duiduipeng, wuxianshang | 解包API返回 | | `normalizeIssues(list)` | yifanshang, duiduipeng, wuxianshang | 标准化期数据 | | `normalizeRewards(list)` | yifanshang, duiduipeng, wuxianshang | 标准化奖励数据 | | `statusToText(s)` | yifanshang, duiduipeng, wuxianshang | 状态转文本 | | `formatPercent(v)` | yifanshang, duiduipeng, wuxianshang | 格式化百分比 | | `levelToAlpha(level)` | duiduipeng, wuxianshang | 等级数字转字母 | | `isFresh(ts)` | yifanshang, duiduipeng, wuxianshang | 判断缓存新鲜度 | | `getRewardCache()` | yifanshang, duiduipeng, wuxianshang | 获取奖励缓存 | | `pickLatestIssueId(list)` | yifanshang, duiduipeng, wuxianshang | 查找最新期ID | | `setSelectedById(id)` | yifanshang, duiduipeng, wuxianshang | 设置选中期 | | `prevIssue()` / `nextIssue()` | yifanshang, duiduipeng, wuxianshang | 期数切换 | **冗余程度**:约200-300行工具函数 × 3个页面 = ~700行冗余 --- ### 3. API调用逻辑重复 以下API调用模式在多个页面中重复: ```javascript // fetchDetail - 获取活动详情(3处重复) async function fetchDetail(id) { const data = await getActivityDetail(id) detail.value = data || {} statusText.value = statusToText(detail.value.status) // ... } // fetchIssues - 获取期列表(3处重复) async function fetchIssues(id) { const data = await getActivityIssues(id) issues.value = normalizeIssues(data) // ... } // fetchRewardsForIssues - 获取奖励(3处重复) async function fetchRewardsForIssues(activityId) { // ~50行相似代码 } // fetchWinRecords - 获取购买记录(3处重复) async function fetchWinRecords(actId, issId) { // ~30行相似代码 } ``` **冗余程度**:约150-200行API调用代码 × 3个页面 = ~500行冗余 --- ### 4. 样式代码重复 以下SCSS样式在三个页面中几乎**完全相同**: ```scss // 基础布局(~80行) .page-wrapper, .bg-decoration, .orb, @keyframes float .page-bg, .bg-image, .bg-mask, .main-scroll // 头部卡片(~100行) .header-card, .header-cover, .header-info, .header-title .header-price-row, .price-symbol, .price-num, .price-unit .header-tags, .tag-item, .header-actions, .action-btn, .action-icon // 板块容器(~50行) .section-container, .section-header, .section-title, .section-more // Tabs切换(~50行) .modern-tabs, .tab-item, .active-dot // 奖池预览(~80行) .preview-scroll, .preview-item, .preview-img, .preview-name, .prize-tag // 购买记录(~60行) .records-list, .record-item, .record-img, .record-info // 弹窗样式(~100行) .rewards-overlay, .rewards-mask, .rewards-panel, .rewards-header, .rewards-list ``` **冗余程度**:约500-600行样式代码 × 3个页面 = ~1500行冗余 --- ### 5. 状态管理重复 以下响应式状态在多个页面中重复定义: ```javascript // 每个页面都有类似的状态定义 const detail = ref({}) const issues = ref([]) const rewardsMap = ref({}) const currentIssueId = ref('') const selectedIssueIndex = ref(0) const activityId = ref('') const tabActive = ref('pool') const winRecords = ref([]) const rewardsVisible = ref(false) // ... ``` --- ## 📊 冗余统计汇总 | 类别 | 估算冗余行数 | 占比 | |------|-------------|------| | 模板结构 | ~400行 | 13% | | 工具函数 | ~700行 | 22% | | API调用逻辑 | ~500行 | 16% | | SCSS样式 | ~1500行 | 48% | | **合计** | **~3100行** | **100%** | 当前三个主要活动页面总计约 **5079行**(1229+2291+1559),冗余代码约占 **61%**。 --- ## ❓ 需要确认的问题 1. **重构方向**:是希望进行完整的组件化重构,还是仅提取共用工具函数? 2. **优先级**: - 先处理工具函数冗余?(影响最小,风险最低) - 先处理模板/组件冗余?(收益最大,但改动较大) - 先处理样式冗余?(提取公共样式文件) 3. **兼容性考虑**:是否需要保留现有的页面独立性(便于后续定制化)? 4. **测试策略**:目前项目有自动化测试吗?重构后如何验证功能正确性? --- ## 🎯 初步建议 ### 方案A:渐进式重构(推荐) 1. **第一步**:提取共用工具函数到 `utils/activity.js` 2. **第二步**:提取共用样式到 `styles/activity-common.scss` 3. **第三步**:创建共用组件(ActivityHeader, ActivityTabs, RewardsPopup) 4. **第四步**:重构各活动页面使用共用组件 ### 方案B:完全组件化 创建通用活动页面框架 `ActivityPageLayout.vue`,各玩法页面只需实现差异化部分。 --- *文档创建时间:2025-12-25*