Files
msh-system/scripts/fix-bugs-scheduled.sh

252 lines
14 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# =============================================================================
# MSH Bug 自动修复 + 回归测试 定时任务主脚本
#
# 对应 bug 清单(来自手工测试报告 + Playwright 回归结果):
# BUG-001 打卡积分显示提前跳变 & 累加逻辑未生效
# BUG-002 食谱计算器结果页 Tab 选中样式不明显
# BUG-003 食物百科列表缺配图与营养简介
# BUG-004 食物百科详情页提示「数据加载失败」
# BUG-005 AI 营养师始终返回固定默认答复
# BUG-006 「健康知识」与「营养知识」名称不统一
# BUG-007 饮食指南 / 科普文章详情页无任何内容
# BUG-008 帖子详情页营养统计数据未显示
# BUG-009 社区帖子类型命名未统一为中文
#
# 总时间估算(含 Playwright 验证):≤ 5 h
# 执行顺序:先修快速项(风险低),后修复杂项,最后全量回归
# =============================================================================
set -euo pipefail
# ─── 路径配置 ──────────────────────────────────────────────────────────────
WORKSPACE="/Users/apple/scott2026/msh-system"
SCRIPTS_DIR="$WORKSPACE/scripts"
LOG_DIR="$WORKSPACE/scripts/logs"
CURSOR="/Applications/Cursor.app/Contents/Resources/app/bin/cursor"
PW="npx playwright test tests/e2e/bug-regression.spec.ts --project=mobile-chrome --reporter=list"
mkdir -p "$LOG_DIR"
MAIN_LOG="$LOG_DIR/fix-bugs-$(date '+%Y%m%d_%H%M').log"
LOCK_FILE="$LOG_DIR/fix-bugs.lock"
# ─── 锁:防止多实例并发 ────────────────────────────────────────────────────
if [ -e "$LOCK_FILE" ]; then
echo "[SKIP] 已有一个修复任务在运行 (lock: $LOCK_FILE),退出。" >&2
exit 0
fi
trap 'rm -f "$LOCK_FILE"' EXIT
touch "$LOCK_FILE"
# ─── 日志工具 ─────────────────────────────────────────────────────────────
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$MAIN_LOG"; }
phase() {
echo "" | tee -a "$MAIN_LOG"
echo "═══════════════════════════════════════════════" | tee -a "$MAIN_LOG"
log "$*"
echo "═══════════════════════════════════════════════" | tee -a "$MAIN_LOG"
}
# ─── Cursor Agent 调用工具 ────────────────────────────────────────────────
# 参数: $1=bug_id $2=prompt文本
run_agent() {
local bug_id="$1"
local prompt="$2"
local agent_log="$LOG_DIR/agent-${bug_id}-$(date '+%H%M%S').log"
log "[${bug_id}] 启动 Cursor Agent 修复..."
"$CURSOR" agent --print --trust --model auto \
--workspace "$WORKSPACE" \
"$prompt" 2>&1 | tee -a "$agent_log" >> "$MAIN_LOG" || true
log "[${bug_id}] Agent 执行完成 → $agent_log"
}
# ─── Playwright 局部验证 ──────────────────────────────────────────────────
# 参数: $1=grep_pattern (匹配用例名)
run_partial_test() {
local pattern="$1"
log "[TEST] 验证: $pattern"
cd "$WORKSPACE"
$PW --grep "$pattern" 2>&1 | tee -a "$MAIN_LOG" || true
}
# ─── 全量回归 ────────────────────────────────────────────────────────────
run_full_regression() {
log "[TEST] 全量回归测试..."
cd "$WORKSPACE"
$PW 2>&1 | tee -a "$MAIN_LOG" || true
log "[TEST] 全量回归完成,报告: tests/e2e/reports/index.html"
}
# =============================================================================
# 开始
# =============================================================================
START_TS=$(date +%s)
phase "阶段 0 — 基线确认(运行回归测试,记录当前失败情况)"
# 软失败:仅记录,不中断脚本
cd "$WORKSPACE"
$PW 2>&1 | tee -a "$MAIN_LOG" || true
log "基线记录完成"
# =============================================================================
# 阶段 1快速修复~60 min
# BUG-002 Tab 样式 | BUG-006 名称统一 | BUG-009 中文命名
# =============================================================================
phase "阶段 1 — 快速修复BUG-002, BUG-006, BUG-009"
run_agent "BUG-002" "修复 BUG-002
文件msh_single_uniapp/pages/tool/calculator-result.vue
问题:食谱计算器结果页的「健康概览」和「营养配餐」两个 Tab 切换后,选中与未选中的视觉差异不明显,用户难以辨识当前激活项。
要求:
1. 增强 .tab-item.active 的视觉样式例如加粗字体font-weight: 700、橙色底部下划线border-bottom: 3px solid #f97316、字色变为主色color: #f97316
2. 未激活 Tab 字色应明显变灰color: #9ca3af不加下划线。
3. 不得修改 Tab 的 JS 逻辑,只改 CSS 样式。
4. 修改前先阅读该文件的 .tab-container / .tab-item / .tab-item.active 样式。
请执行修改。"
run_agent "BUG-006" "修复 BUG-006
文件msh_single_uniapp/pages/tool_main/index.vue 以及 msh_single_uniapp/pages/tool/nutrition-knowledge.vue
问题:主页「健康知识」区块标题与营养知识页面导航栏标题命名不一致,一处用「健康知识」,另一处用「营养知识」。
要求:
1. 先阅读两个文件,确认各自现有文案。
2. 统一将两处名称改为「健康知识」(若现在 nutrition-knowledge.vue 导航栏写的是「营养知识」,改成「健康知识」)。
3. 仅修改文案字符串,不改动任何逻辑或样式。
请执行修改。"
run_agent "BUG-009" "修复 BUG-009
文件msh_single_uniapp/pages/tool_main/community.vue
问题:社区页面的 Tab 标签(推荐/最新/关注/热门)和帖子类型标签(.type-tag / .meal-tag中存在英文命名或非中文命名需统一为中文。
要求:
1. 阅读 community.vue 的 template 部分,找出所有 Tab 文案和帖子类型标签文案。
2. 将所有英文或拼音命名改为对应中文(如 recommend→推荐, latest→最新 等)。
3. 检查数据中的类型字段(如 type: 'breakfast'),如显示时有 label 映射,确保 label 均为中文。
4. 不改动路由、接口调用等逻辑。
请执行修改。"
log "[阶段1] 阶段1修复完成进行局部验证..."
run_partial_test "TC-B02|TC-B06|TC-B09"
# =============================================================================
# 阶段 2中等难度修复~60 min
# BUG-001 打卡积分 | BUG-007 文章详情内容
# =============================================================================
phase "阶段 2 — 中等修复BUG-001, BUG-007"
run_agent "BUG-001" "修复 BUG-001共两个子问题
文件msh_single_uniapp/pages/tool/checkin.vue
子问题 A — 打卡前积分提前跳变:
点击「立即打卡」后,在页面跳转前,前端已将积分 +30 显示出来,造成视觉误导。
修复handleCheckin 方法中,不得在 API 返回成功前修改 currentPoints。
仅在 API 调用成功、且获取到服务端最新积分后才更新 currentPoints优先用服务端返回的值不做前端本地累加
子问题 B — 打卡成功后积分未实际增加:
后端积分累加逻辑可能未被正确触发。
修复:
1. 阅读 handleCheckin 中的 API 调用,确认调用的是 /api/front/user/checkin 或类似接口。
2. 若调用成功,再发请求 GET /api/front/user/info 刷新用户积分,并将返回值赋给 currentPoints。
3. 不可使用硬编码 +30积分值必须来自服务端响应。
请先阅读文件,再执行修改。
"
run_agent "BUG-007" "修复 BUG-007
文件msh_single_uniapp/pages/tool/nutrition-knowledge.vue
问题切换到「饮食指南」或「科普文章」Tab 后列表为空guideList / articleList 均为 []),点击条目进入详情页后也无任何内容,页面一片空白。
要求:
1. 阅读 loadKnowledgeList 方法和 getKnowledgeList API 调用。
2. 如果 API 正常但数据为空请检查请求参数type 字段的值是否正确guide / article
3. 如果 API 失败,添加 catch 后的错误提示uni.showToast并确保 guideList / articleList 不被设为 undefined。
4. 在 onLoad 中,若没有 id 参数,应默认加载当前 tab 对应的列表(当前为 nutrients应在 switchTab 后加载 guide/articles 列表)。
5. 修复详情页跳转goToDetail 方法中,确保 knowledgeId 或 id 字段存在才跳转,否则提示「暂无详情」。
请先阅读文件,再执行修改。"
log "[阶段2] 阶段2修复完成进行局部验证..."
run_partial_test "TC-B01|TC-B07"
# =============================================================================
# 阶段 3数据展示修复~60 min
# BUG-003 食物列表 | BUG-008 营养统计
# =============================================================================
phase "阶段 3 — 数据展示修复BUG-003, BUG-008"
run_agent "BUG-003" "修复 BUG-003
文件msh_single_uniapp/pages/tool/food-encyclopedia.vue
问题:食物百科全部列表页中,所有食物条目均未展示配图(.food-image和营养简介.nutrition-item
要求:
1. 阅读 food-encyclopedia.vue 的 template 中 .food-item 部分,找到 .food-image 的 :src 绑定和 .nutrition-item 的 v-for 数据来源。
2. 检查数据加载方法(如 loadFoodList 或 getFoodList API确认响应数据结构找出 image/imageUrl/img 字段和 nutrition/nutrients 字段。
3. 修复字段映射:确保 .food-image 的 :src 绑定到正确字段(如 item.imageUrl || item.image且 .nutrition-item 遍历正确的数组(如 item.nutrients || item.nutritions
4. 若图片字段为空,显示一个默认占位图(可使用已有的本地资源或灰色背景)。
请先阅读文件和相关 API 文件api/tool.js再执行修改。"
run_agent "BUG-008" "修复 BUG-008
文件msh_single_uniapp/pages/tool/post-detail.vue
问题:帖子详情页中,营养统计数据(.nutrition-stats-card不显示.stat-item 数组为空。
要求:
1. 阅读 post-detail.vue 的 data 中 postData.nutritionStats 的初始化和赋值逻辑。
2. 找到加载帖子详情的方法(如 loadPostDetail确认后端响应中是否有 nutritionStats 字段。
3. 若后端无该字段,根据帖子关联的饮食打卡数据(如 dietaryData / mealData计算蛋白质、热量、钾、磷等关键营养素填充 nutritionStats 数组格式:[{label:'蛋白质', value:'56g'}, ...]
4. 若后端有该字段但字段名不一致,修复映射。
5. 营养统计卡片的显示条件v-if应改为nutritionStats.length > 0而不是依赖后端字段存在性。
请先阅读文件,再执行修改。"
log "[阶段3] 阶段3修复完成进行局部验证..."
run_partial_test "TC-B03|TC-B08"
# =============================================================================
# 阶段 4复杂修复~90 min
# BUG-004 食物详情 | BUG-005 AI 回复
# =============================================================================
phase "阶段 4 — 复杂修复BUG-004, BUG-005"
run_agent "BUG-004" "修复 BUG-004
文件msh_single_uniapp/pages/tool/food-detail.vue
问题:点击任意食物条目进入详情页,提示「数据加载失败」,页面无法正常展示食物名称、营养成分等信息。
要求:
1. 阅读 food-detail.vue 的 onLoad 和数据加载方法(如 loadFoodDetail
2. 打印或记录 API 请求参数id、name 等),确认传参是否正确。
3. 如果 API 调用失败catch 块中不要只 showToast应同时
a. 将 loadError 置为具体错误信息(用于调试),
b. 使用 defaultFoodData 填充页面,保证用户能看到基础界面而不是空白,
c. 在页面显示「当前数据来自缓存,可能不是最新」提示。
4. 确认 .food-name-overlay / .nutrient-card / .nutrition-row 等元素在 defaultFoodData 状态下也能正常渲染(数据不为空数组/空字符串)。
5. 如果问题是 API 路径或参数有误(如 id 传了 name 字段),同时修复调用参数。
请先阅读文件和 api/tool.js再执行修改。"
run_agent "BUG-005" "修复 BUG-005对话接口已改为 KieAI Gemini chat若仍有固定回复再修
文件msh_single_uniapp/pages/tool/ai-nutritionist.vue、api/models-api.js
后端msh_crmeb_22 的 /api/front/kieai/gemini/chatToolKieAIServiceImpl.geminiChat
要求:
1. 文本对话必须走 KieAI Gemini 大模型:调用 POST /api/front/kieai/gemini/chat请求体为 { messages: [{ role: 'user', content: 用户输入 }], stream: false }
2. 前端从响应 data.choices[0].message.content 取回复并展示,不得使用 getAIResponse 等固定话术作为接口成功时的回复。
3. 若后端 ToolKieAIServiceImpl.geminiChat 或 buildGeminiRequestBody 中存在硬编码 prompt改为使用 request.getMessages() 透传用户内容。
4. 不修改 UI 布局,仅保证数据流:用户输入 → kieai/gemini/chat → 展示模型返回内容。"
log "[阶段4] 阶段4修复完成进行局部验证..."
run_partial_test "TC-B04|TC-B05"
# =============================================================================
# 阶段 5全量回归 + 报告
# =============================================================================
phase "阶段 5 — 全量回归测试 + 报告生成"
run_full_regression
END_TS=$(date +%s)
ELAPSED=$(( END_TS - START_TS ))
ELAPSED_MIN=$(( ELAPSED / 60 ))
log "────────────────────────────────────────────────"
log "全部阶段完成!总耗时:${ELAPSED_MIN} 分钟(${ELAPSED} 秒)"
log "回归报告:$WORKSPACE/tests/e2e/reports/index.html"
log "详细日志:$MAIN_LOG"
log "────────────────────────────────────────────────"