hookehuyr

feat(husky): 使用 prepare-commit-msg + amend 实现 CHANGELOG 自动更新

- 创建 prepare-commit-msg hook
- 创建 update-changelog-prepare.sh 脚本
- 修改 post-commit 检查暂存区并 amend
- 使用 --no-verify 避免 amend 触发循环

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
......@@ -5,7 +5,7 @@
#
# 功能:
# 1. 显示提交成功信息
# 2. 补充 CHANGELOG 中的 commit hash
# 2. 将 CHANGELOG amend 到当前提交(如果需要)
#
# 作者:Claude Code
# 日期:2026-02-28
......@@ -49,36 +49,23 @@ echo " 删除行数: -$LINES_DELETED"
echo ""
# ============================================
# 补充 CHANGELOG 中的 commit hash
# 将 CHANGELOG amend 到当前提交(如果在暂存区)
# ============================================
CHANGELOG_FILE="CHANGELOG.md"
if [ -f "$CHANGELOG_FILE" ]; then
# 检查 CHANGELOG 中是否有 "pending" hash 需要替换
if grep -q "\`pending\`" "$CHANGELOG_FILE"; then
# 获取当前日期时间戳
NOW_TIME=$(date +%H:%M:%S)
TODAY=$(date +%Y-%m-%d)
# 解析 commit message
COMMIT_TYPE=$(echo "$COMMIT_MSG" | head -n 1 | sed -E 's/^([a-z]+)\(.*/\1/')
COMMIT_SCOPE=$(echo "$COMMIT_MSG" | head -n 1 | sed -E 's/^[a-z]+\(([a-z-]+)\).*/\1/')
COMMIT_SUBJECT=$(echo "$COMMIT_MSG" | head -n 1 | sed -E 's/^[a-z]+\([a-z-]+\): (.*)$/\1/')
# 替换 pending hash 为真实的 commit hash
# 使用 sed 进行替换
sed -i.tmp "s/\[\$NOW_TIME - $COMMIT_TYPE($COMMIT_SCOPE): $COMMIT_SUBJECT/[$NOW_TIME - $COMMIT_TYPE($COMMIT_SCOPE): $COMMIT_SUBJECT/" "$CHANGELOG_FILE" 2>/dev/null || \
sed -i.tmp "s/\`pending\` - $COMMIT_TYPE($COMMIT_SCOPE): $COMMIT_SUBJECT/\`$COMMIT_HASH\` - $COMMIT_TYPE($COMMIT_SCOPE): $COMMIT_SUBJECT/" "$CHANGELOG_FILE"
# 清理临时文件
rm -f "${CHANGELOG_FILE}.tmp"
# 如果 CHANGELOG 有变更, amend 到当前提交
if ! git diff --quiet "$CHANGELOG_FILE" 2>/dev/null; then
git add "$CHANGELOG_FILE"
git commit --amend --no-edit --no-verify >/dev/null 2>&1
echo " ${GREEN}✅ CHANGELOG commit hash 已更新${NC}"
fi
if ! git diff --cached --quiet CHANGELOG.md 2>/dev/null; then
echo "📝 ${BLUE}将 CHANGELOG 加入当前提交...${NC}"
# 使用 amend 将 CHANGELOG 加入当前提交
# --no-edit: 不修改 commit message
# --no-verify: 跳过 hooks,避免循环
git commit --amend --no-edit --no-verify >/dev/null 2>&1
if [ $? -eq 0 ]; then
# 获取 amend 后的 hash
NEW_HASH=$(git log -1 --pretty=%h)
echo " ${GREEN}✅ CHANGELOG 已加入提交${NC}"
echo " ${BLUE} 新 Hash: $NEW_HASH${NC}"
else
echo " ${YELLOW}⚠️ CHANGELOG amend 失败${NC}"
fi
fi
......
......@@ -120,37 +120,10 @@ fi
echo " ${GREEN}✅ 改动规模检查通过${NC}"
# ============================================
# 4. 自动更新 CHANGELOG.md(在提交前)
# ============================================
echo ""
echo "📋 ${BLUE}步骤 4/4: 更新 CHANGELOG${NC}"
# 获取暂存的 commit message
COMMIT_MSG_FILE=".git/COMMIT_EDITMSG"
if [ -f "$COMMIT_MSG_FILE" ]; then
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
# 解析 commit type
COMMIT_TYPE=$(echo "$COMMIT_MSG" | head -n 1 | sed -E 's/^([a-z]+)\(.*/\1/')
# 只对特定类型更新 CHANGELOG
# 跳过: docs(changelog) 类型的提交,避免循环
if echo "$COMMIT_MSG" | head -n 1 | grep -qE "^docs\(changelog\):"; then
echo " ⏭️ 跳过 CHANGELOG 更新(docs(changelog) 类型提交)"
elif [ "$COMMIT_TYPE" = "feat" ] || [ "$COMMIT_TYPE" = "fix" ] || [ "$COMMIT_TYPE" = "refactor" ] || [ "$COMMIT_TYPE" = "perf" ]; then
# 调用 CHANGELOG 更新脚本
bash scripts/changelog/update-changelog-precommit.sh "$COMMIT_MSG_FILE"
else
echo " ⏭️ 跳过 CHANGELOG 更新(类型: $COMMIT_TYPE)"
fi
else
echo " ⚠️ 无法读取 commit message,跳过 CHANGELOG 更新"
fi
# ============================================
# 所有检查通过
# ============================================
echo ""
echo "✅ ${GREEN}所有检查通过!${NC}"
echo "🚀 ${BLUE}开始提交...${NC}"
echo "📝 ${BLUE}CHANGELOG.md 将在 prepare-commit-msg 阶段更新${NC}"
echo ""
......
#!/bin/sh
# ============================================
# Prepare-commit-msg Hook
# ============================================
#
# 功能:
# 1. 自动更新 CHANGELOG.md(包含在当前提交中)
#
# 关键特性:
# - 只在初始提交时执行,amend 时不会触发
# - 配合 post-commit 使用 amend --no-verify 完成流程
#
# 作者:Claude Code
# 日期:2026-02-28
# ============================================
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 获取 commit message 文件
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2 # commit 来源:message/template/merge/squash等
# 只在正常的 commit 时执行,跳过 merge/rebase/amend
# amend 时 COMMIT_SOURCE 为空
if [ "$COMMIT_SOURCE" = "message" ] || [ "$COMMIT_SOURCE" = "template" ] || [ "$COMMIT_SOURCE" = "" ]; then
# 检查是否是 amend 操作(通过检查是否已有 commit)
# 如果 HEAD 存在且不是初始提交,可能是 amend
if git rev-parse HEAD >/dev/null 2>&1; then
# 有 HEAD,检查是否是正在 amend
# 简单的判断:如果已经有 commit 且当前没有在 rebase 等操作中
# 这里我们允许继续,因为关键在于 post-commit 的 --no-verify
:
fi
# 读取 commit message
if [ -f "$COMMIT_MSG_FILE" ]; then
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
# 只处理第一行(subject)
FIRST_LINE=$(echo "$COMMIT_MSG" | head -n 1)
# 解析 commit type
COMMIT_TYPE=$(echo "$FIRST_LINE" | sed -E 's/^([a-z]+)\(.*/\1/')
# 只对特定类型更新 CHANGELOG
# 跳过: docs(changelog) 类型的提交,避免循环
if echo "$FIRST_LINE" | grep -qE "^docs\(changelog\):"; then
# 跳过
:
elif [ "$COMMIT_TYPE" = "feat" ] || [ "$COMMIT_TYPE" = "fix" ] || [ "$COMMIT_TYPE" = "refactor" ] || [ "$COMMIT_TYPE" = "perf" ]; then
echo ""
echo "📝 ${BLUE}更新 CHANGELOG...${NC}"
# 调用 CHANGELOG 更新脚本
bash scripts/changelog/update-changelog-prepare.sh "$COMMIT_MSG_FILE"
fi
fi
fi
......@@ -3,722 +3,15 @@
记录项目开发过程中的重要变更和完成任务。
## 2026-02-28
### 20:08:07 - docs(changelog): 更新 CHANGELOG
**影响文件**:
- `无`
**变更摘要**:
- 更新 CHANGELOG
**相关提交**:
- `cd4a559` - docs(changelog): 更新 CHANGELOG
---
### 20:07:54 - refactor(search): 搜索 Tab 显示结果数量
**影响文件**:
- `无`
**变更摘要**:
- 搜索 Tab 显示结果数量
**相关提交**:
- `f059121` - refactor(search): 搜索 Tab 显示结果数量
---
### 20:00:51 - fix(changelog): 修复多行 commit message 导致的重复内容问题
**影响文件**:
- `无`
**变更摘要**:
- 修复多行 commit message 导致的重复内容问题
**相关提交**:
- `8b44aa1` - fix(changelog): 修复多行 commit message 导致的重复内容问题
---
### 19:54:54 - docs
- 更新搜索 API 响应字段:files → article
- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
- 文章详情 API 添加 file_list 字段类型定义
- 计划书 API 完善参数文档说明
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>(api
- 更新搜索 API 响应字段:files → article
- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
- 文章详情 API 添加 file_list 字段类型定义
- 计划书 API 完善参数文档说明
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>): 同步搜索 API 文档,将 file 类型改为 article
- 更新搜索 API 响应字段:files → article
- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
- 文章详情 API 添加 file_list 字段类型定义
- 计划书 API 完善参数文档说明
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
**影响文件**:
- `docs/api-specs/search/search.md`
- `src/api/article.js`
- `src/api/plan.js`
**变更摘要**:
- 同步搜索 API 文档,将 file 类型改为 article
- 更新搜索 API 响应字段:files → article
- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
- 文章详情 API 添加 file_list 字段类型定义
- 计划书 API 完善参数文档说明
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
**相关提交**:
- `a4ef54a` - docs
- 更新搜索 API 响应字段:files → article
- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
- 文章详情 API 添加 file_list 字段类型定义
- 计划书 API 完善参数文档说明
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>(api
- 更新搜索 API 响应字段:files → article
- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
- 文章详情 API 添加 file_list 字段类型定义
- 计划书 API 完善参数文档说明
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>): 同步搜索 API 文档,将 file 类型改为 article
- 更新搜索 API 响应字段:files → article
- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
- 文章详情 API 添加 file_list 字段类型定义
- 计划书 API 完善参数文档说明
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
### 17:11:05 - fix
- 删除 if/else 块外部的重复 mv 命令
- TEMP_FILE 变量只在块内有效,外部无法访问
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>(husky
- 删除 if/else 块外部的重复 mv 命令
- TEMP_FILE 变量只在块内有效,外部无法访问
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>): 修复 CHANGELOG 脚本重复 mv 命令错误
- 删除 if/else 块外部的重复 mv 命令
- TEMP_FILE 变量只在块内有效,外部无法访问
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
**影响文件**:
- `CHANGELOG.md`
**变更摘要**:
- 修复 CHANGELOG 脚本重复 mv 命令错误
- 删除 if/else 块外部的重复 mv 命令
- TEMP_FILE 变量只在块内有效,外部无法访问
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
**相关提交**:
- `04f7261` - fix
- 删除 if/else 块外部的重复 mv 命令
- TEMP_FILE 变量只在块内有效,外部无法访问
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>(husky
- 删除 if/else 块外部的重复 mv 命令
- TEMP_FILE 变量只在块内有效,外部无法访问
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>): 修复 CHANGELOG 脚本重复 mv 命令错误
- 删除 if/else 块外部的重复 mv 命令
- TEMP_FILE 变量只在块内有效,外部无法访问
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
### 17:10:43 - refactor
- 检测逻辑:从 "## [日期] - 标题" 改为 "^## 日期"
- 生成格式:匹配根目录格式(时间 + commit hash + 文件列表)
- 插入逻辑:追加到日期下,而非文件开头
- 解决误判问题,现在能正确识别今日已有条目
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>(husky
- 检测逻辑:从 "## [日期] - 标题" 改为 "^## 日期"
- 生成格式:匹配根目录格式(时间 + commit hash + 文件列表)
- 插入逻辑:追加到日期下,而非文件开头
- 解决误判问题,现在能正确识别今日已有条目
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>): 重写 CHANGELOG 自动更新格式匹配根目录
- 检测逻辑:从 "## [日期] - 标题" 改为 "^## 日期"
- 生成格式:匹配根目录格式(时间 + commit hash + 文件列表)
- 插入逻辑:追加到日期下,而非文件开头
- 解决误判问题,现在能正确识别今日已有条目
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
**影响文件**:
- `无`
**变更摘要**:
- 重写 CHANGELOG 自动更新格式匹配根目录
- 检测逻辑:从 "## [日期] - 标题" 改为 "^## 日期"
- 生成格式:匹配根目录格式(时间 + commit hash + 文件列表)
- 插入逻辑:追加到日期下,而非文件开头
- 解决误判问题,现在能正确识别今日已有条目
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
**相关提交**:
- `06fe556` - refactor
- 检测逻辑:从 "## [日期] - 标题" 改为 "^## 日期"
- 生成格式:匹配根目录格式(时间 + commit hash + 文件列表)
- 插入逻辑:追加到日期下,而非文件开头
- 解决误判问题,现在能正确识别今日已有条目
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>(husky
- 检测逻辑:从 "## [日期] - 标题" 改为 "^## 日期"
- 生成格式:匹配根目录格式(时间 + commit hash + 文件列表)
- 插入逻辑:追加到日期下,而非文件开头
- 解决误判问题,现在能正确识别今日已有条目
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>): 重写 CHANGELOG 自动更新格式匹配根目录
- 检测逻辑:从 "## [日期] - 标题" 改为 "^## 日期"
- 生成格式:匹配根目录格式(时间 + commit hash + 文件列表)
- 插入逻辑:追加到日期下,而非文件开头
- 解决误判问题,现在能正确识别今日已有条目
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
### 17:02:37 - feat(plan): 年缴保费显示添加千分位分隔符
**影响文件**:
- `src/components/plan/PlanFields/AmountKeyboard.vue`
**变更摘要**:
- 修改 AmountKeyboard 组件的 displayValue 计算属性
- 显示已确认数值时自动添加千分位(如 1,000、15,000)
- 输入过程中保持原始显示,避免跳动干扰
- 数据存储不变,仅影响显示层
**相关提交**:
- `efbd4d8` - feat(plan): 年缴保费显示添加千分位分隔符
### 16:47:38 - feat(plan): 新增提取期自定义输入功能
**影响文件**:
- `src/components/plan/PlanFields/PeriodInput.vue` - 新增自定义提取期输入组件
- `src/components/plan/PlanFields/SelectPickerGlobal.vue` - 支持自定义选项触发器
- `src/components/plan/PlanTemplates/SavingsTemplate.vue` - 多阶段提取期支持自定义输入
**变更摘要**:
- 新增 PeriodInput 组件,支持用户自定义输入提取期
- 支持数值验证(min/max/allowed_formats/custom_validators)
- SelectPickerGlobal 新增 @custom-select 事件,触发自定义输入弹窗
- 多阶段提取期选项合并:预设选项 + 用户自定义选项
- 配置驱动:multi_stage_withdrawal.custom_period 控制功能开关
**相关提交**:
- `34bf2e8` - feat(plan): 新增提取期自定义输入功能
### 16:09:33 - fix(plan): 修复计划书文件预览功能
**影响文件**:
- `src/composables/usePlanView.js` - 恢复 useFileOperation 依赖
**变更摘要**:
- 修复计划书文件预览无法打开的问题
- 恢复 useFileOperation composable 的导入
**相关提交**:
- `2f8937c` - fix(plan): 修复计划书文件预览功能,恢复 useFileOperation 依赖
### 15:59:26 - fix(mock): 修复小程序环境 process 不存在的错误
**影响文件**:
- `src/utils/mockData.js`
**变更摘要**:
- 修复小程序环境调用 process.env 导致的报错
- 改用 Taro.getEnv() 判断运行环境
**相关提交**:
- `72e59da` - fix(mock): 修复小程序环境 process 不存在的错误
### 15:58:40 - feat(mock): 新增 POST API Mock 支持 AI 自动测试
**影响文件**:
- `src/utils/mockData.js`
- `src/utils/__tests__/postMock.test.js`
**变更摘要**:
- 新增 POST 请求 Mock 数据支持
- 支持根据请求体动态返回不同结果
- 新增 AI 自动测试用例(覆盖增删改查)
**相关提交**:
- `d8ffb54` - feat(mock): 新增 POST API Mock 支持 AI 自动测试
### 15:33:22 - docs(api): 更新计划书 API 文档
**影响文件**:
- `docs/api-specs/plan/add.md`
**变更摘要**:
- 更新计划书 API 文档,年龄与出生年月日改为二选一
- 明确字段校验规则
**相关提交**:
- `5e7bfe7` - docs(api): 更新计划书API文档,年龄与出生年月日改为二选一
### 15:32:08 - fix(plan): 修复储蓄类多阶段模版保存问题
**影响文件**:
- `src/components/plan/PlanTemplates/SavingsTemplate.vue`
**变更摘要**:
- 修复多阶段模式下 stages 数据无法从 props.modelValue 恢复的问题
- 修复 validate() 函数中单阶段字段被错误校验的问题
- 添加详细的调试日志以方便排查问题
**相关提交**:
- `4b8f69d` - fix(plan): 修复储蓄类多阶段模版保存问题
### 13:36:27 - docs(changelog): 记录 htmlUtils 工具库新增
**影响文件**:
- `docs/CHANGELOG.md`
**变更摘要**:
- 记录 htmlUtils 工具库新增到文档变更日志
**相关提交**:
- `03c4609` - docs(changelog): 记录 htmlUtils 工具库新增
### 13:17:26 - fix(article): 文章列表页收藏状态与详情页同步
**影响文件**:
- `src/pages/article-detail/index.vue`
- `src/pages/material-list/index.vue`
**变更摘要**:
- 修复文章详情页收藏后返回列表页状态未更新的问题
- 使用 Taro.eventCenter 监听收藏事件,实现跨页面通信
**相关提交**:
- `fc49890` - fix(article): 文章列表页收藏状态与详情页同步
### 11:14:25 - feat(ui): RichTextRenderer 新增链接长按复制功能
**影响文件**:
- `src/components/RichTextRenderer.vue`
- `src/pages/rich-text-test/index.vue`
**变更摘要**:
- 新增链接长按复制功能(支持 http/https 链接)
- 使用 Taro.setClipboardData 实现复制
- 新增复制成功提示 Toast
**相关提交**:
- `2cb6454` - feat(ui): RichTextRenderer 新增链接长按复制功能
### 01:03:28 - docs(changelog): 补充 2-27 的详细更新记录
**影响文件**:
- `docs/CHANGELOG.md`
**变更摘要**:
- 补充 2026-02-27 富文本和文章模块的详细更新记录
**相关提交**:
- `c653298` - docs(changelog): 补充 2-27 的详细更新记录
### 00:21:17 - fix(rich-text): 修复 v-html 样式不生效问题
**影响文件**:
- `src/components/RichTextRenderer.vue`
- `src/pages/rich-text-test/index.vue`
**变更摘要**:
- 修复 v-html 渲染的富文本样式不生效的问题
- 改用内联样式 + scoped 样式的 ID 选择器方案
**相关提交**:
- `cd36f28` - fix(rich-text): 修复 v-html 样式不生效问题
---
### 00:34:39 - feat(plan): 储蓄类计划书表单调整
**影响文件**:
- `src/components/plan/PlanTemplates/SavingsTemplate.vue` - 注释掉年龄-出生日期自动联动逻辑
- `src/config/plan-templates.js` - 移除储蓄类产品的吸烟字段和映射
**变更摘要**:
- 移除储蓄类产品的"吸烟"字段(客户需求)
- 切断年龄与出生日期的自动联动,改为独立填写(客户需求)
- 更新储蓄类提交字段映射(savingsSubmitMapping),移除吸烟字段
- 更新组件注释,移除"是否吸烟"描述
**相关提交**:
- `5c7df88` - feat(plan): 储蓄类计划书表单调整
### 00:37:01 - docs(components): 更新组件文档和 CHANGELOG
**影响文件**:
- `src/components/RichTextRenderer.vue` - 修正 scoped 样式相关注释
- `src/components/README.md` - 添加 RichTextRenderer 组件完整文档
- `docs/CHANGELOG.md` - 记录今日计划书表单调整
**变更摘要**:
- 修正 RichTextRenderer.vue 的注释说明( scoped 样式 → 内联样式 + ID 选择器)
- 更新 components/README.md,添加 RichTextRenderer 组件到文档索引
- 添加 RichTextRenderer 详细文档(Props、Events、功能特性、使用示例)
**相关提交**:
- `cd09fc9` - docs(components): 更新组件文档和 CHANGELOG
### 00:39:10 - docs(changelog): 更新根目录 CHANGELOG 记录今日任务
**影响文件**:
- `CHANGELOG.md` - 添加 2026-02-28 计划书表单调整记录
**变更摘要**:
- 添加 2026-02-28 计划书表单调整记录
- 添加组件文档更新记录
**相关提交**:
- `247c63d` - docs(changelog): 更新根目录 CHANGELOG 记录今日任务
### 00:40:50 - docs(changelog): 移除错误添加的项目功能变更记录
**影响文件**:
- `docs/CHANGELOG.md` - 删除错误的项目功能变更记录
**变更摘要**:
- docs/CHANGELOG.md 应只记录文档相关的变更,不应记录项目功能变更
- 项目功能变更应记录在根目录的 CHANGELOG.md 中
**相关提交**:
- `ac207cf` - docs(changelog): 移除错误添加的项目功能变更记录
### 13:35:17 - refactor(utils): 新增 htmlUtils 工具库并重构 RichTextRenderer
**影响文件**:
- `src/utils/htmlUtils.js` - 新增 HTML 工具函数库
- `src/components/RichTextRenderer.vue` - 使用工具库,移除内联实现
**变更摘要**:
- 新增 htmlUtils.js 工具函数库,包含 200+ HTML 实体解码支持
- 支持 DOM API(H5)和手动映射(小程序)双模式自适应
- 新增工具函数:
- `decodeHtmlEntities()` - HTML 实体解码(支持基本符号、货币、数学符号、希腊字母等)
- `encodeHtmlEntities()` - HTML 实体编码(XSS 防护)
- `stripHtmlTags()` - 移除 HTML 标签
- `truncateHtml()` - 截取 HTML 并保留标签完整性
- RichTextRenderer 组件改用工具库,移除内联实现(减少 53 行代码)
- 清理所有测试 console.log(保留 error 日志)
**相关提交**:
- `fb33196` - refactor(utils): 新增 htmlUtils 工具库并重构 RichTextRenderer
---
## 2026-02-27
### 09:56-10:00 - docs(utils): 更新工具函数库文档
**影响文件**:
- `src/utils/README.md`
**变更摘要**:
- 添加工具函数库文档说明
---
### 12:57-13:03 - fix(api): 修复 API 生成器路径配置错误
**影响文件**:
- `scripts/api-generator/generateApiFromOpenAPI.js`
- `docs/api-specs/article/article_detail.md`
- `docs/api-specs/article/favorite.md`
- `docs/api-specs/article/list.md`
- `docs/api-specs/article/week_hot.md`
- `src/api/article.js`
**变更摘要**:
- 修复 openAPIDir 路径:../docs/api-specs → ../../docs/api-specs
- 修复 outputDir 路径:../src/api → ../../src/api
- 新增 article 模块 API(文章详情、收藏、列表、热门)
---
### 13:03-22:49 - feat(rich-text): 新增 RichTextRenderer 富文本渲染组件
**影响文件**:
- `package.json` - 新增 mp-html 和 @tarojs/extend 依赖
- `src/components/RichTextRenderer.vue` - 新增富文本渲染组件
- `src/pages/rich-text-test/` - 新增测试页面
- `src/pages/rich-text-test/README.md` - 测试页面说明文档
**变更摘要**:
- HTML 实体自动解码(&nbsp;, &amp;, &lt;, &gt;, &quot;, &apos;
- <a> 标签自动替换为 <div data-href="">
- 图片长按预览功能
- PDF 文件链接点击处理
- transformElement 图片自动处理(默认启用)
- 支持图片 mode="widthFix" 和 style="width: 100%"
---
### 22:48-22:49 - test(rich-text): 完善 v-html 测试页面功能
**影响文件**:
- `src/pages/rich-text-test/index.vue`
**变更摘要**:
- 添加 HTML 实体解析(&nbsp;, &amp;, &lt;, &gt;, &quot;
- 实现 a 标签替换为 div + data-href 属性
- 添加 PDF 文件链接点击处理(useFileOperation)
- 新增 transformElement 图片处理测试开关
---
### fix(rich-text): 修复图片自动处理并应用到文章详情页
**影响文件**:
- `src/components/RichTextRenderer.vue` - 修复 transformElement 初始化顺序
- `src/pages/article-detail/index.vue` - 使用 RichTextRenderer 组件替换 <rich-text>
**变更摘要**:
- 修复 transformElement 初始化顺序问题(在 watch 之前设置)
- 增强图片样式:添加 width:100%!important
- 删除文章图片列表模块(由组件处理)
- 删除富文本处理逻辑(formatRichText、extractImageUrls 等)
- 代码精简:199 行 → 147 行(减少约 26%)
---
### fix(rich-text): 移除全局CSS导入避免影响其他组件样式
**影响文件**:
- `src/components/RichTextRenderer.vue`
**变更摘要**:
- 移除 @tarojs/taro/html.css 全局样式导入
- 在组件 style 中添加完整的富文本样式(使用 ID 选择器避免污染)
- 解决 NavHeader 标题不居中的问题
---
### feat(article): 文章模块功能开发
**影响文件**:
- `src/components/cards/ArticleCard.vue` - 新增 ArticleCard 组件
- `src/pages/article-detail/index.vue` - 新增文章详情页
- `src/pages/article-favorites/index.vue` - 新增文章收藏页
- `src/pages/category-list/index.vue` - 优化分类列表页
**变更摘要**:
- ArticleCard 支持可配置封面图显示 (showCover prop)
- 分类列表页支持混合渲染模式:
* max_depth > 1: 显示二级分类卡片 (SectionCard)
* max_depth === 1: 直接显示文章列表 (ArticleCard)
- 过滤空状态项 (max_depth === 1 且 list 为空)
---
### feat(article): 文章详情页添加图片预览功能
**影响文件**:
- `src/pages/article-detail/index.vue`
**变更摘要**:
- 使用 Taro 原生 rich-text 组件渲染富文本
- 富文本内容自动格式化,处理图片宽度适配移动端
- 提取文章中的图片 URL,支持 Taro.previewImage 预览
- 新增收藏功能,支持文章收藏/取消收藏
---
### feat(article): 文章图片列表改为网格布局
**影响文件**:
- `src/pages/article-detail/index.vue`
**变更摘要**:
- 移除横向滚动视图
- 使用 flex-wrap 实现网格布局
- 每行显示3张图片,自动换行
---
### feat(index): 首页热门资料改为热门文章
**影响文件**:
- `src/pages/index/index.vue`
**变更摘要**:
- 将"本周热门资料"改为"本周热门文章"
- 使用 ArticleCard 替换 MaterialCard
- 更新 API 调用从 file/weekHotAPI 到 article/weekHotAPI
---
### refactor(collect): 收藏功能改为 API 驱动模式
**影响文件**:
- `src/composables/useCollectOperation.js`
- `src/components/cards/ArticleCard.vue`
- `src/components/cards/MaterialCard.vue`
- `src/components/list/ListItemActions/index.vue`
**变更摘要**:
- 移除乐观更新逻辑,改为 API 成功后更新 UI
- useCollectOperation 返回 { success, newStatus } 对象
- ArticleCard/MaterialCard 使用 async/await 等待 API 响应
- ListItemActions 添加 @tap.stop 防止事件冒泡
---
### style(plan): 弹窗标题显示产品名称而非模板名称
**影响文件**:
- `src/components/plan/PlanFormContainer.vue`
**变更摘要**:
- 弹窗标题改为显示产品名称
---
### style(plan): 调整每年提取金额字段位置至提取期下方
**影响文件**:
- `src/components/plan/PlanTemplates/SavingsTemplate.vue`
**变更摘要**:
- 统一单阶段和多阶段模式的字段录入顺序
---
### refactor(plan): 重构多阶段提取方案 UI 渲染逻辑
**影响文件**:
- `src/components/plan/PlanTemplates/SavingsTemplate.vue`
**变更摘要**:
- 重构多阶段提取方案 UI 渲染逻辑
---
### docs: 更新变更日志
### 20:30:15 - feat(husky): 使用 prepare-commit-msg + amend 实现 CHANGELOG 自动更新
**影响文件**:
- `.husky/post-commit`
- `.husky/prepare-commit-msg`
- `CHANGELOG.md`
**变更摘要**:
- 更新项目变更日志
---
### docs(changelog): 更新 CHANGELOG
**影响文件**:
- `docs/CHANGELOG.md`
**变更摘要**:
- 更新文档变更日志
---
### chore: 更新组件类型定义
**影响文件**:
- `components.d.ts`
**变更摘要**:
- 更新组件类型定义
- 使用 prepare-commit-msg + amend 实现 CHANGELOG 自动更新
---
## 2026-02-25
### 21:00:00 - feat(plan): 新增多阶段提取方案功能
**影响文件**:
- `src/config/plan-templates.js` - 新增多阶段产品配置和 `savings-gs-multistage` 产品
- `src/components/plan/PlanTemplates/SavingsTemplate.vue` - 实现多阶段提取渲染和交互逻辑
- `src/api/mock/mock/hotProducts.js` - 添加多阶段产品 mock 数据
**变更摘要**:
- 新增产品:宏挚传承保障计划(多阶段) (`savings-gs-multistage`)
- 多阶段功能:
- 年龄 < 12岁:固定显示 3 个阶段
- 年龄 ≥ 12岁:初始 1 个阶段,可添加至 4 个
- 提取期新增"一笔过"选项
- 递增百分比改为可选字段(不填传 null)
- 提交数据格式:`withdrawal_stages` 数组
- 样式优化:阶段卡片白色背景
**相关文档**:
- `docs/tasks/2026-02-25/archive/多阶段提取方案设计.md`
- `docs/tasks/2026-02-25/archive/客户新需求-2026-02-25.md`
---
## 2026-02-24
### 23:59:18 - 完成任务
**影响文件**:
- `.husky/README.md`
- `.husky/post-commit`
- `docs/CHANGELOG.md`
- `scripts/changelog/README.md`
- `scripts/changelog/update-changelog.sh`
**变更摘要**:
- CHANGELOG 自动更新功能配置
### 2026-02-28 - 修复储蓄类多阶段模版保存问题
**影响文件**:
- `src/components/plan/PlanTemplates/SavingsTemplate.vue`
**变更摘要**:
- 修复多阶段模式下 stages 数据无法从 props.modelValue 恢复的问题
- 修复 validate() 函数中单阶段字段被错误校验的问题
- 添加详细的调试日志以方便排查问题
......
#!/bin/bash
# ============================================
# CHANGELOG 自动更新脚本(Prepare-commit-msg 版本)
# ============================================
#
# 功能:在 prepare-commit-msg 阶段更新 CHANGELOG.md,加入暂存区
# 配合 post-commit 的 amend --no-verify 完成流程
#
# 作者:Claude Code
# 日期:2026-02-28
# ============================================
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 参数
COMMIT_MSG_FILE=$1
CHANGELOG_FILE="CHANGELOG.md"
# 检查文件是否存在
if [ ! -f "$CHANGELOG_FILE" ]; then
echo " ${YELLOW}⚠️ CHANGELOG.md 不存在,跳过自动更新${NC}"
exit 0
fi
# 读取 commit message
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
# 解析 commit message
# 格式: type(scope): subject
if ! echo "$COMMIT_MSG" | grep -qE "^([a-z]+)\(([a-z-]+)\): .{1,50}"; then
# 格式不匹配,跳过
exit 0
fi
# 提取信息
COMMIT_TYPE=$(echo "$COMMIT_MSG" | head -n 1 | sed -E 's/^([a-z]+)\(.*/\1/')
COMMIT_SCOPE=$(echo "$COMMIT_MSG" | head -n 1 | sed -E 's/^[a-z]+\(([a-z-]+)\).*/\1/')
COMMIT_SUBJECT=$(echo "$COMMIT_MSG" | head -n 1 | sed -E 's/^[a-z]+\([a-z-]+\): (.*)$/\1/')
# 类型映射到中文
case "$COMMIT_TYPE" in
feat)
CHANGE_TYPE="新增"
;;
fix)
CHANGE_TYPE="修复"
;;
docs)
CHANGE_TYPE="文档"
;;
style)
CHANGE_TYPE="样式"
;;
refactor)
CHANGE_TYPE="优化"
;;
perf)
CHANGE_TYPE="性能"
;;
test)
CHANGE_TYPE="测试"
;;
chore)
CHANGE_TYPE="配置"
;;
revert)
CHANGE_TYPE="回滚"
;;
*)
CHANGE_TYPE="其他"
;;
esac
# 获取当前日期和时间
TODAY=$(date +%Y-%m-%d)
NOW_TIME=$(date +%H:%M:%S)
# 获取暂存的变更文件(使用 git diff --cached)
CHANGED_FILES=$(git diff --cached --name-only | tr '\n' '\n' | sed 's/^/- \`/;s/$/`/' | sed '$d')
if [ -z "$CHANGED_FILES" ]; then
CHANGED_FILES="- \`\`"
fi
# 生成 CHANGELOG 条目
CHANGELOG_ENTRY="### $NOW_TIME - $COMMIT_TYPE($COMMIT_SCOPE): $COMMIT_SUBJECT
**影响文件**:
$CHANGED_FILES
**变更摘要**:
- $COMMIT_SUBJECT
---
"
# 检查今天是否已有条目
if grep -q "^## $TODAY" "$CHANGELOG_FILE"; then
# 今天已有条目,找到日期行号,在日期后追加
DATE_LINE=$(grep -n "^## $TODAY" "$CHANGELOG_FILE" | head -1 | cut -d: -f1)
# 创建临时文件
TEMP_FILE=$(mktemp)
# 读取日期行之前的内容
head -n $DATE_LINE "$CHANGELOG_FILE" > "$TEMP_FILE"
# 在日期后追加新条目
echo "$CHANGELOG_ENTRY" >> "$TEMP_FILE"
# 追加日期行之后的内容(从日期行+1开始)
tail -n +$((DATE_LINE + 1)) "$CHANGELOG_FILE" >> "$TEMP_FILE"
# 替换原文件
mv "$TEMP_FILE" "$CHANGELOG_FILE"
else
# 今天没有条目,创建新的日期部分
TEMP_FILE=$(mktemp)
# 新建日期标题和条目
echo "## $TODAY" > "$TEMP_FILE"
echo "" >> "$TEMP_FILE"
echo "$CHANGELOG_ENTRY" >> "$TEMP_FILE"
echo "" >> "$TEMP_FILE"
# 追加原文件内容
cat "$CHANGELOG_FILE" >> "$TEMP_FILE"
# 替换原文件
mv "$TEMP_FILE" "$CHANGELOG_FILE"
fi
# 将 CHANGELOG.md 加入暂存区
# 重要:这里只是加入暂存区,实际包含在提交中由 post-commit 的 amend 完成
git add "$CHANGELOG_FILE"
echo " ${GREEN}✅ CHANGELOG.md 已自动更新${NC}"
echo " ${BLUE} 类型: $CHANGE_TYPE${NC}"
echo " ${BLUE} 范围: $COMMIT_SCOPE${NC}"
echo " ${BLUE} 描述: $COMMIT_SUBJECT${NC}"