Files
xyzw_web_helper/MD说明文件夹/快速实施指南-v2.1.1集成.md
2025-10-17 20:56:50 +08:00

18 KiB
Raw Blame History

v2.1.1 快速实施指南

🎯 目标

将开源版本v2.1.1的核心功能集成到你的项目中,优先实现最重要的功能。


📋 推荐实施方案

根据重要性和难度,建议按以下顺序实施:

第一阶段性能优化1天

目标: 减少控制台日志,提升性能

  1. 添加logger.js

    复制文件src/utils/logger.js
    
  2. 修改tokenStore.js

    // 替换
    import { tokenLogger, wsLogger, gameLogger } from '../utils/logger.js'
    
    // 所有的 console.log 改为 wsLogger.debug()
    // 所有的 console.error 改为 wsLogger.error()
    
  3. 测试

    // 浏览器控制台测试
    wsDebug.quiet()    // 只显示警告
    wsDebug.normal()   // 正常模式
    wsDebug.verbose()  // 详细模式
    

验收标准:

  • 生产环境不再有大量日志输出
  • 控制台可以动态调整日志级别
  • WebSocket连接正常工作

第二阶段月度任务系统2-3天

目标: 实现月度任务进度跟踪和自动补齐

Step 1: 准备工作

  1. 备份GameStatus.vue
    cp src/components/GameStatus.vue src/components/GameStatus.vue.backup
    

Step 2: 修改GameStatus.vue

  1. 添加月度任务相关变量

    <script setup>
    // 月度任务相关
    const FISH_TARGET = 320
    const ARENA_TARGET = 240
    const monthLoading = ref(false)
    const fishToppingUp = ref(false)
    const arenaToppingUp = ref(false)
    const monthActivity = ref(null)
    
    // 时间计算
    const now = new Date()
    const daysInMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate()
    const dayOfMonth = now.getDate()
    const remainingDays = computed(() => Math.max(0, daysInMonth - dayOfMonth))
    const monthProgress = computed(() => Math.min(1, Math.max(0, dayOfMonth / daysInMonth)))
    
    // 进度数据
    const myMonthInfo = computed(() => monthActivity.value?.myMonthInfo || {})
    const myArenaInfo = computed(() => monthActivity.value?.myArenaInfo || {})
    const fishNum = computed(() => Number(myMonthInfo.value?.['2']?.num || 0))
    const arenaNum = computed(() => Number(myArenaInfo.value?.num || 0))
    const fishPercent = computed(() => Math.min(100, Math.round((fishNum.value / FISH_TARGET) * 100)))
    const arenaPercent = computed(() => Math.min(100, Math.round((arenaNum.value / ARENA_TARGET) * 100)))
    
    // 应该完成的数量
    const fishShouldBe = computed(() => 
      remainingDays.value === 0 ? FISH_TARGET : Math.min(FISH_TARGET, Math.ceil(monthProgress.value * FISH_TARGET))
    )
    const arenaShouldBe = computed(() => 
      remainingDays.value === 0 ? ARENA_TARGET : Math.min(ARENA_TARGET, Math.ceil(monthProgress.value * ARENA_TARGET))
    )
    const fishNeeded = computed(() => Math.max(0, fishShouldBe.value - fishNum.value))
    const arenaNeeded = computed(() => Math.max(0, arenaShouldBe.value - arenaNum.value))
    </script>
    
  2. 添加刷新进度函数

    const fetchMonthlyActivity = async () => {
      if (!tokenStore.selectedToken) {
        message.warning('请先选择Token')
        return
      }
      const status = tokenStore.getWebSocketStatus(tokenStore.selectedToken.id)
      if (status !== 'connected') return
    
      monthLoading.value = true
      try {
        const tokenId = tokenStore.selectedToken.id
        const result = await tokenStore.sendMessageWithPromise(tokenId, 'activity_get', {}, 10000)
        const act = result?.activity || result?.body?.activity || result
        monthActivity.value = act || null
        if (act) message.success('月度任务进度已更新')
      } catch (e) {
        message.error(`获取月度任务失败:${e.message}`)
      } finally {
        monthLoading.value = false
      }
    }
    
  3. 添加物品解析函数

    const getItemCount = (items, itemId) => {
      if (!items) return 0
    
      if (Array.isArray(items)) {
        const found = items.find(it => Number(it.id ?? it.itemId) === itemId)
        if (!found) return 0
        return Number(found.num ?? found.count ?? found.quantity ?? 0)
      }
    
      const node = items[String(itemId)] ?? items[itemId]
      if (node == null) return 0
    
      if (typeof node === 'number') return Number(node)
      if (typeof node === 'object') {
        return Number(node.num ?? node.count ?? node.quantity ?? 0)
      }
    
      return Number(node) || 0
    }
    
  4. 添加钓鱼补齐函数

    const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))
    
    const topUpFish = async (needed) => {
      fishToppingUp.value = true
      try {
        const roleInfo = tokenStore.gameData?.roleInfo?.role
        const items = roleInfo?.items || {}
        const normalRod = getItemCount(items, 1011) || 0
        const goldRod = getItemCount(items, 1012) || 0
    
        let useFree = Math.min(normalRod, needed)
        let useGold = Math.min(goldRod, needed - useFree)
        const total = useFree + useGold
    
        if (total === 0) {
          message.error('没有可用的鱼竿')
          return
        }
    
        message.info(`开始钓鱼:普通鱼竿${useFree}次,金鱼竿${useGold}次`)
    
        // 使用普通鱼竿
        for (let i = 0; i < useFree; i++) {
          await tokenStore.sendMessageWithPromise(
            tokenStore.selectedToken.id,
            'fishing_fish',
            { fishingType: 1 },
            5000
          )
          await sleep(500)
        }
    
        // 使用金鱼竿
        for (let i = 0; i < useGold; i++) {
          await tokenStore.sendMessageWithPromise(
            tokenStore.selectedToken.id,
            'fishing_fish',
            { fishingType: 2 },
            5000
          )
          await sleep(500)
        }
    
        await sleep(1000)
        await fetchMonthlyActivity()
        message.success(`钓鱼补齐完成!共完成${total}次`)
    
      } catch (error) {
        message.error(`钓鱼补齐失败:${error.message}`)
      } finally {
        fishToppingUp.value = false
      }
    }
    
  5. 添加竞技场补齐函数

    const topUpArena = async (needed) => {
      arenaToppingUp.value = true
      try {
        const roleInfo = tokenStore.gameData?.roleInfo?.role
        const energy = roleInfo?.energy || 0
        const ENERGY_PER_BATTLE = 5
        const possibleBattles = Math.floor(energy / ENERGY_PER_BATTLE)
    
        if (possibleBattles < needed) {
          message.warning(`体力不足!当前仅可进行${possibleBattles}次战斗`)
          needed = possibleBattles
        }
    
        if (needed === 0) {
          message.error('体力不足')
          return
        }
    
        message.info(`开始竞技场战斗:共${needed}次`)
    
        let successCount = 0
        for (let i = 0; i < needed; i++) {
          try {
            const matchResult = await tokenStore.sendMessageWithPromise(
              tokenStore.selectedToken.id,
              'arena_matchopponent',
              {},
              5000
            )
    
            await sleep(300)
    
            await tokenStore.sendMessageWithPromise(
              tokenStore.selectedToken.id,
              'arena_battle',
              { 
                targetRoleId: matchResult?.opponent?.roleId,
                battleType: 1
              },
              5000
            )
    
            successCount++
            await sleep(1000)
    
          } catch (error) {
            console.error(`第${i+1}次战斗失败:`, error)
          }
        }
    
        await sleep(1000)
        await fetchMonthlyActivity()
        message.success(`竞技场补齐完成!成功${successCount}次`)
    
      } catch (error) {
        message.error(`竞技场补齐失败:${error.message}`)
      } finally {
        arenaToppingUp.value = false
      }
    }
    
  6. 添加补齐入口函数

    const topUpMonthly = (type) => {
      const isFish = type === 'fish'
      const needed = isFish ? fishNeeded.value : arenaNeeded.value
    
      if (needed === 0) {
        message.info(`${isFish ? '钓鱼' : '竞技场'}已达标`)
        return
      }
    
      if (isFish) {
        topUpFish(needed)
      } else {
        topUpArena(needed)
      }
    }
    
    const fishMoreOptions = [{ label: '一键完成', key: 'complete-fish' }]
    const arenaMoreOptions = [{ label: '一键完成', key: 'complete-arena' }]
    
    const onFishMoreSelect = (key) => {
      if (key === 'complete-fish') {
        topUpFish(FISH_TARGET - fishNum.value)
      }
    }
    
    const onArenaMoreSelect = (key) => {
      if (key === 'complete-arena') {
        topUpArena(ARENA_TARGET - arenaNum.value)
      }
    }
    
  7. 添加UI组件

    <template>
      <!-- 在适当位置添加月度任务卡片 -->
      <div class="status-card monthly-tasks">
        <div class="card-header">
          <img src="/icons/1736425783912140.png" alt="月度任务" class="status-icon">
          <div class="status-info">
            <h3>月度任务</h3>
            <p>进度与一键补齐</p>
          </div>
          <div class="status-badge" :class="{ active: monthActivity }">
            <div class="status-dot" />
            <span v-if="remainingDays > 0">剩余 {{ remainingDays }} </span>
            <span v-else>本月最后一天</span>
          </div>
        </div>
    
        <div class="card-content">
          <div class="monthly-row">
            <div class="row-title">钓鱼进度</div>
            <div class="row-value">{{ fishNum }} / {{ FISH_TARGET }}{{ fishPercent }}%</div>
          </div>
    
          <div class="monthly-row">
            <div class="row-title">竞技场进度</div>
            <div class="row-value">{{ arenaNum }} / {{ ARENA_TARGET }}{{ arenaPercent }}%</div>
          </div>
    
          <div class="action-row">
            <button 
              class="action-button secondary" 
              :disabled="monthLoading || fishToppingUp || arenaToppingUp" 
              @click="fetchMonthlyActivity"
            >
              {{ monthLoading ? '刷新中...' : '刷新进度' }}
            </button>
    
            <n-button-group>
              <n-button 
                class="action-button" 
                :disabled="monthLoading || fishToppingUp" 
                @click="topUpMonthly('fish')"
              >
                {{ fishToppingUp ? '补齐中...' : '钓鱼补齐' }}
              </n-button>
              <n-dropdown :options="fishMoreOptions" trigger="click" @select="onFishMoreSelect">
                <n-button :disabled="monthLoading || fishToppingUp"></n-button>
              </n-dropdown>
            </n-button-group>
    
            <n-button-group>
              <n-button 
                class="action-button" 
                :disabled="monthLoading || arenaToppingUp" 
                @click="topUpMonthly('arena')"
              >
                {{ arenaToppingUp ? '补齐中...' : '竞技场补齐' }}
              </n-button>
              <n-dropdown :options="arenaMoreOptions" trigger="click" @select="onArenaMoreSelect">
                <n-button :disabled="monthLoading || arenaToppingUp"></n-button>
              </n-dropdown>
            </n-button-group>
          </div>
    
          <p class="description muted">
            补齐规则"当前天数比例""完成比例"一致
          </p>
        </div>
      </div>
    </template>
    
  8. 添加样式

    <style scoped lang="scss">
    .monthly-tasks {
      .monthly-row {
        display: flex;
        justify-content: space-between;
        padding: var(--spacing-sm) 0;
        border-bottom: 1px solid var(--border-light);
    
        .row-title {
          color: var(--text-secondary);
        }
    
        .row-value {
          font-weight: var(--font-weight-semibold);
        }
      }
    
      .action-row {
        display: flex;
        gap: var(--spacing-sm);
        margin-top: var(--spacing-md);
      }
    
      .description.muted {
        margin-top: var(--spacing-sm);
        font-size: var(--font-size-xs);
        color: var(--text-tertiary);
      }
    }
    </style>
    

Step 3: 测试

  1. 基础测试

    • 刷新进度显示正确
    • 补齐次数计算正确
    • 钓鱼补齐功能正常
    • 竞技场补齐功能正常
    • 一键完成功能正常
  2. 边界测试

    • 鱼竿不足时的处理
    • 体力不足时的处理
    • 已达标时的提示
    • 本月最后一天的计算

验收标准:

  • 月度任务面板正常显示
  • 进度计算准确
  • 自动补齐功能正常
  • 不影响现有功能

第三阶段身份卡系统2天

目标: 添加角色身份卡展示

Step 1: 添加组件

  1. 复制IdentityCard.vue

    复制文件src/components/IdentityCard.vue
    
  2. 在GameStatus.vue中使用

    <script setup>
    import IdentityCard from './IdentityCard.vue'
    </script>
    
    <template>
      <!-- 在页面顶部添加 -->
      <IdentityCard embedded />
    </template>
    

Step 2: 测试

  • 身份卡正常显示
  • 战力段位显示正确
  • 资源信息显示正确
  • 头像加载正常

验收标准:

  • 身份卡美观显示
  • 数据获取正常
  • 动画效果正常

第四阶段俱乐部功能2-3天

目标: 增强俱乐部功能

Step 1: 添加工具函数

  1. 添加clubBattleUtils.js
    复制文件src/utils/clubBattleUtils.js
    

Step 2: 添加组件

  1. 添加ClubInfo.vue

    复制文件src/components/ClubInfo.vue
    
  2. 添加ClubBattleRecords.vue

    复制文件src/components/ClubBattleRecords.vue
    
  3. 在GameStatus中使用

    <script setup>
    import ClubInfo from './ClubInfo.vue'
    </script>
    
    <template>
      <!-- 在俱乐部区域添加 -->
      <ClubInfo />
    </template>
    

验收标准:

  • 俱乐部信息正常显示
  • 盐场战绩可以查询
  • 导出功能正常

🎨 可选:布局优化

如果你想采用开源版的Tab切换布局

<template>
  <div class="game-status-container">
    <!-- 身份卡常驻顶部 -->
    <IdentityCard embedded />
    
    <!-- Tab切换 -->
    <n-tabs v-model:value="activeSection" type="line" animated size="small">
      <n-tab-pane name="daily" tab="日常" />
      <n-tab-pane name="club" tab="俱乐部" />
      <n-tab-pane name="activity" tab="活动" />
    </n-tabs>
    
    <!-- 根据activeSection显示不同内容 -->
    <DailyTaskStatus v-show="activeSection === 'daily'" />
    <ClubInfo v-show="activeSection === 'club'" />
    <div class="monthly-tasks" v-show="activeSection === 'activity'">
      <!-- 月度任务 -->
    </div>
  </div>
</template>

<script setup>
const activeSection = ref('daily')
</script>

⚠️ 注意事项

1. 保留你的特色功能

确保不要覆盖以下文件:

  • BatchTaskPanel.vue
  • SchedulerConfig.vue
  • TaskProgressCard.vue
  • ExecutionHistory.vue
  • UpgradeModule.vue
  • CarManagement.vue

2. 游戏命令兼容性

你的版本的gameCommands.js有额外字段rtt, code保持使用你的版本。

3. 数据库方案

开源版有tokenDb.jsIndexedDB但你的localStorage方案也很好可以暂时不迁移。

4. 测试要求

每个阶段完成后都要充分测试:

  • WebSocket连接
  • 批量任务功能
  • 定时任务功能
  • 现有的所有功能

📊 时间估算

阶段 工作量 说明
第一阶段 0.5-1天 添加logger系统
第二阶段 2-3天 月度任务系统(最复杂)
第三阶段 1-2天 身份卡系统
第四阶段 2-3天 俱乐部功能
总计 6-9天 包含测试时间

检查清单

开发前

  • 创建功能分支
  • 备份关键文件
  • 阅读完整对比报告

第一阶段完成

  • logger.js已添加
  • tokenStore.js已集成logger
  • 浏览器控制台测试通过
  • 生产环境日志减少

第二阶段完成

  • 月度任务面板显示
  • 刷新进度功能正常
  • 钓鱼补齐测试通过
  • 竞技场补齐测试通过
  • 一键完成测试通过

第三阶段完成

  • IdentityCard组件添加
  • 战力段位显示正确
  • 资源信息显示正确

第四阶段完成

  • ClubInfo组件添加
  • ClubBattleRecords组件添加
  • 盐场战绩功能正常

上线前

  • 所有功能测试通过
  • 批量任务不受影响
  • 定时任务不受影响
  • 性能测试通过
  • 用户体验良好

🆘 遇到问题?

常见问题

  1. 月度任务进度不显示

    • 检查WebSocket连接状态
    • 检查activity_get命令响应
    • 查看浏览器控制台错误
  2. 钓鱼补齐失败

    • 检查鱼竿数量获取
    • 检查fishing_fish命令
    • 查看错误提示
  3. 样式显示异常

    • 检查CSS变量定义
    • 检查naive-ui组件引入
    • 清理浏览器缓存

获取帮助

如果遇到问题,可以:

  1. 查看详细文档:代码对比报告-v2.1.1.md
  2. 查看实现细节:月度任务系统详细实现.md
  3. 向我提问,提供详细错误信息

🎉 完成后

恭喜完成v2.1.1功能集成!

你的项目现在拥有:

  • 高性能的日志系统
  • 智能的月度任务自动化
  • 精美的角色身份卡
  • 强大的俱乐部管理
  • 你原有的批量任务系统
  • 你原有的定时任务系统

下一步:

  1. 部署到测试环境
  2. 用户测试反馈
  3. 优化和完善
  4. 部署到生产环境

祝开发顺利! 🚀