fujian_water_biz_doc/scripts/doc-toolkit.sh

694 lines
18 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# 福建水务营收系统概要设计文档工具链
# Author: System Design Team
# Version: 1.0
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 配置文件
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
CONFIG_FILE="$PROJECT_ROOT/.doc-config.json"
TEMPLATE_DIR="$PROJECT_ROOT/templates"
OUTPUT_DIR="$PROJECT_ROOT/output"
# 创建必要的目录
mkdir -p "$TEMPLATE_DIR"
mkdir -p "$OUTPUT_DIR"
# 日志函数
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 显示帮助信息
show_help() {
echo "福建水务营收系统概要设计文档工具链"
echo ""
echo "用法: $0 [命令] [选项]"
echo ""
echo "命令:"
echo " create <module_name> 创建新的模块设计文档"
echo " validate [file_path] 验证文档格式和内容"
echo " export <format> [file] 导出文档为指定格式"
echo " generate-diagram <type> 生成指定类型的图表"
echo " check-links 检查文档中的链接有效性"
echo " merge-docs 合并所有文档为单一文档"
echo " init 初始化工具链配置"
echo ""
echo "格式选项:"
echo " word, pdf, html, epub"
echo ""
echo "图表类型:"
echo " architecture, flow, er, sequence, class"
echo ""
}
# 初始化配置
init_config() {
log_info "初始化文档工具链配置..."
# 创建配置文件
cat > "$CONFIG_FILE" << 'EOF'
{
"project": {
"name": "福建水务营收系统",
"version": "1.0.0",
"author": "系统设计团队"
},
"templates": {
"module_design": "module_design_template.md",
"database_design": "database_design_template.md",
"interface_design": "interface_design_template.md"
},
"validation": {
"min_section_length": 200,
"required_sections": [
"功能概述",
"需求分析",
"技术架构",
"功能模块设计",
"数据库设计",
"接口设计",
"安全设计",
"性能设计",
"部署设计"
]
},
"export": {
"pandoc_options": {
"word": "--reference-doc=templates/reference.docx",
"pdf": "--pdf-engine=xelatex",
"html": "--css=templates/style.css --self-contained"
}
}
}
EOF
# 创建模块设计模板
create_module_template
# 创建样式文件
create_style_files
log_success "配置初始化完成!"
}
# 创建模块设计模板
create_module_template() {
# 使用 printf 而不是 heredoc 来避免反引号冲突
cat > "$TEMPLATE_DIR/module_design_template.md" << 'TEMPLATE_EOF'
# {{MODULE_NAME}}模块设计说明
## 一、功能概述
### 1.1 模块简介
{{MODULE_DESCRIPTION}}
### 1.2 主要功能
- 功能点1描述
- 功能点2描述
- 功能点3描述
## 二、需求分析
### 2.1 功能性需求
{{FUNCTIONAL_REQUIREMENTS}}
### 2.2 非功能性需求
{{NON_FUNCTIONAL_REQUIREMENTS}}
## 三、技术架构
### 3.1 技术选型
- 后端框架RuoYi-Vue-Pro
- 前端框架yudao-ui-admin-vue3
- 数据库MySQL 8.0+
- 缓存Redis
### 3.2 架构图
## 四、功能模块设计
### 4.1 模块结构
{{MODULE_STRUCTURE}}
### 4.2 核心类设计
{{CLASS_DESIGN}}
## 五、数据库设计
### 5.1 数据表设计
{{TABLE_DESIGN}}
## 六、接口设计
### 6.1 REST API设计
{{API_DESIGN}}
### 6.2 接口列表
{{API_LIST}}
## 七、安全设计
### 7.1 权限控制
{{PERMISSION_DESIGN}}
### 7.2 数据安全
{{DATA_SECURITY}}
## 八、性能设计
### 8.1 性能指标
{{PERFORMANCE_METRICS}}
### 8.2 优化策略
{{OPTIMIZATION_STRATEGY}}
## 九、部署设计
### 9.1 部署架构
{{DEPLOYMENT_ARCHITECTURE}}
### 9.2 环境配置
{{ENVIRONMENT_CONFIG}}
## 十、测试方案
### 10.1 测试策略
{{TEST_STRATEGY}}
### 10.2 测试用例
{{TEST_CASES}}
TEMPLATE_EOF
}
# 创建样式文件
create_style_files() {
cat > "$TEMPLATE_DIR/style.css" << 'CSS_EOF'
body {
font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
h1, h2, h3, h4, h5, h6 {
color: #2c3e50;
margin-top: 2em;
margin-bottom: 1em;
}
h1 {
border-bottom: 3px solid #3498db;
padding-bottom: 10px;
}
h2 {
border-bottom: 1px solid #bdc3c7;
padding-bottom: 5px;
}
code {
background-color: #f8f8f8;
padding: 2px 4px;
border-radius: 3px;
font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
}
pre {
background-color: #f8f8f8;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
}
table {
border-collapse: collapse;
width: 100%;
margin: 1em 0;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
font-weight: bold;
}
.mermaid {
text-align: center;
margin: 20px 0;
}
CSS_EOF
log_info "样式文件创建完成"
}
# 创建新的模块设计文档
create_module_doc() {
local module_name="$1"
if [[ -z "$module_name" ]]; then
log_error "请提供模块名称"
exit 1
fi
local filename="water_biz_${module_name}_design.md"
local template_file="$TEMPLATE_DIR/module_design_template.md"
if [[ ! -f "$template_file" ]]; then
log_error "模板文件不存在,请先运行: $0 init"
exit 1
fi
if [[ -f "$filename" ]]; then
log_warning "文件 $filename 已存在,是否覆盖?(y/N)"
read -r response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
log_info "操作已取消"
exit 0
fi
fi
log_info "创建模块文档: $filename"
# 替换模板变量
cp "$template_file" "$filename"
# 使用 sed 替换变量
sed -i.bak "s/{{MODULE_NAME}}/${module_name}/g" "$filename"
sed -i.bak "s/{{MODULE_DESCRIPTION}}/[请在此处添加${module_name}模块的详细描述]/g" "$filename"
sed -i.bak "s/{{FUNCTIONAL_REQUIREMENTS}}/[请在此处添加功能性需求]/g" "$filename"
sed -i.bak "s/{{NON_FUNCTIONAL_REQUIREMENTS}}/[请在此处添加非功能性需求]/g" "$filename"
sed -i.bak "s/{{MODULE_STRUCTURE}}/[请在此处添加模块结构说明]/g" "$filename"
sed -i.bak "s/{{CLASS_DESIGN}}/[请在此处添加核心类设计]/g" "$filename"
sed -i.bak "s/{{TABLE_DESIGN}}/[请在此处添加数据表设计]/g" "$filename"
sed -i.bak "s/{{API_DESIGN}}/[请在此处添加API设计说明]/g" "$filename"
sed -i.bak "s/{{API_LIST}}/[请在此处添加API列表]/g" "$filename"
sed -i.bak "s/{{PERMISSION_DESIGN}}/[请在此处添加权限控制设计]/g" "$filename"
sed -i.bak "s/{{DATA_SECURITY}}/[请在此处添加数据安全设计]/g" "$filename"
sed -i.bak "s/{{PERFORMANCE_METRICS}}/[请在此处添加性能指标]/g" "$filename"
sed -i.bak "s/{{OPTIMIZATION_STRATEGY}}/[请在此处添加优化策略]/g" "$filename"
sed -i.bak "s/{{DEPLOYMENT_ARCHITECTURE}}/[请在此处添加部署架构]/g" "$filename"
sed -i.bak "s/{{ENVIRONMENT_CONFIG}}/[请在此处添加环境配置]/g" "$filename"
sed -i.bak "s/{{TEST_STRATEGY}}/[请在此处添加测试策略]/g" "$filename"
sed -i.bak "s/{{TEST_CASES}}/[请在此处添加测试用例]/g" "$filename"
# 删除备份文件
rm -f "${filename}.bak"
log_success "模块文档创建完成: $filename"
log_info "请使用编辑器打开文件并完善内容"
}
# 验证文档
validate_doc() {
local file_path="$1"
local errors=0
if [[ -z "$file_path" ]]; then
# 验证所有markdown文件
for file in *.md; do
if [[ -f "$file" ]]; then
validate_single_doc "$file"
errors=$((errors + $?))
fi
done
else
validate_single_doc "$file_path"
errors=$?
fi
if [[ $errors -eq 0 ]]; then
log_success "文档验证通过"
else
log_error "发现 $errors 个问题,请修复后重新验证"
exit 1
fi
}
# 验证单个文档
validate_single_doc() {
local file_path="$1"
local errors=0
log_info "验证文档: $file_path"
if [[ ! -f "$file_path" ]]; then
log_error "文件不存在: $file_path"
return 1
fi
# 检查必需的章节(根据文档类型进行检查)
if [[ "$file_path" == *"module_design.md" ]]; then
local required_sections=("系统整体架构" "技术架构")
for section in "${required_sections[@]}"; do
if ! grep -q "$section" "$file_path"; then
log_warning "缺少必需章节: $section"
errors=$((errors + 1))
fi
done
elif [[ "$file_path" == *"system_architecture.md" ]]; then
local required_sections=("系统架构概述" "技术架构")
for section in "${required_sections[@]}"; do
if ! grep -q "$section" "$file_path"; then
log_warning "缺少必需章节: $section"
errors=$((errors + 1))
fi
done
elif [[ "$file_path" == *"database_design.md" ]]; then
local required_sections=("数据库设计概述" "数据库架构")
for section in "${required_sections[@]}"; do
if ! grep -q "$section" "$file_path"; then
log_warning "缺少必需章节: $section"
errors=$((errors + 1))
fi
done
elif [[ "$file_path" == *"interface_design.md" ]]; then
local required_sections=("接口概述")
for section in "${required_sections[@]}"; do
if ! grep -q "$section" "$file_path"; then
log_warning "缺少必需章节: $section"
errors=$((errors + 1))
fi
done
fi
# 检查代码块语言标记
local code_blocks=$(grep -c '^```[a-z]' "$file_path" || true)
local total_start_blocks=$(grep -c '^```' "$file_path" || true)
# 代码块总数应该是开始标记数的一半(因为有开始和结束标记)
local actual_total_blocks=$((total_start_blocks / 2))
if [[ $actual_total_blocks -gt 0 && $code_blocks -lt $actual_total_blocks ]]; then
log_warning "部分代码块缺少语言标记 (有语言标记: $code_blocks, 总代码块: $actual_total_blocks)"
errors=$((errors + 1))
fi
log_info "验证完成: $file_path (发现 $errors 个问题)"
return $errors
}
# 导出文档
export_doc() {
local format="$1"
local file_path="$2"
if [[ -z "$format" ]]; then
log_error "请指定导出格式: word, pdf, html, epub"
exit 1
fi
# 检查pandoc是否安装
if ! command -v pandoc &> /dev/null; then
log_error "pandoc 未安装,请先安装 pandoc"
log_info "安装命令: brew install pandoc (macOS) 或 apt-get install pandoc (Ubuntu)"
exit 1
fi
local output_file
local pandoc_options=""
case "$format" in
word)
output_file="$OUTPUT_DIR/福建水务营收系统概要设计文档.docx"
;;
pdf)
output_file="$OUTPUT_DIR/福建水务营收系统概要设计文档.pdf"
pandoc_options="--pdf-engine=xelatex -V CJKmainfont='PingFang SC'"
;;
html)
output_file="$OUTPUT_DIR/福建水务营收系统概要设计文档.html"
pandoc_options="--css=$TEMPLATE_DIR/style.css --self-contained"
;;
epub)
output_file="$OUTPUT_DIR/福建水务营收系统概要设计文档.epub"
;;
*)
log_error "不支持的格式: $format"
exit 1
;;
esac
log_info "导出格式: $format"
log_info "输出文件: $output_file"
if [[ -n "$file_path" ]]; then
# 导出单个文件
if [[ ! -f "$file_path" ]]; then
log_error "文件不存在: $file_path"
exit 1
fi
pandoc "$file_path" -o "$output_file" $pandoc_options
else
# 合并所有markdown文件并导出
local merged_file="$OUTPUT_DIR/merged_docs.md"
merge_all_docs "$merged_file"
pandoc "$merged_file" -o "$output_file" $pandoc_options
fi
log_success "文档导出完成: $output_file"
}
# 合并所有文档
merge_all_docs() {
local output_file="$1"
log_info "合并所有文档..."
echo "---" > "$output_file"
echo "title: \"福建水务营收系统概要设计文档\"" >> "$output_file"
echo "author: \"系统设计团队\"" >> "$output_file"
echo "date: \"$(date '+%Y年%m月%d日')\"" >> "$output_file"
echo "---" >> "$output_file"
echo "" >> "$output_file"
# 按特定顺序合并文档
local doc_order=(
"water_biz_design_plan.md"
"water_biz_summary.md"
"water_biz_system_architecture.md"
"water_biz_module_design.md"
"water_biz_database_design.md"
"water_biz_interface_design.md"
"water_biz_deployment_design.md"
)
for doc in "${doc_order[@]}"; do
if [[ -f "$doc" ]]; then
echo "" >> "$output_file"
echo "---" >> "$output_file"
echo "" >> "$output_file"
cat "$doc" >> "$output_file"
fi
done
log_success "文档合并完成: $output_file"
}
# 生成图表
generate_diagram() {
local diagram_type="$1"
case "$diagram_type" in
architecture)
generate_architecture_diagram
;;
flow)
generate_flow_diagram
;;
er)
generate_er_diagram
;;
sequence)
generate_sequence_diagram
;;
*)
log_error "不支持的图表类型: $diagram_type"
log_info "支持的类型: architecture, flow, er, sequence"
exit 1
;;
esac
}
# 生成架构图
generate_architecture_diagram() {
echo '```mermaid'
echo 'graph TD'
echo ' subgraph "用户层"'
echo ' A[Web浏览器]'
echo ' B[移动应用]'
echo ' end'
echo ' '
echo ' subgraph "网关层"'
echo ' C[API网关]'
echo ' D[负载均衡器]'
echo ' end'
echo ' '
echo ' subgraph "应用层"'
echo ' E[用户管理服务]'
echo ' F[抄表管理服务]'
echo ' G[收费管理服务]'
echo ' H[账务管理服务]'
echo ' end'
echo ' '
echo ' A --> C'
echo ' B --> C'
echo ' C --> D'
echo ' D --> E'
echo ' D --> F'
echo ' D --> G'
echo ' D --> H'
echo '```'
log_success "架构图模板已生成"
}
# 生成流程图
generate_flow_diagram() {
echo '```mermaid'
echo 'flowchart TD'
echo ' A[开始] --> B{用户登录}'
echo ' B -->|成功| C[选择功能模块]'
echo ' B -->|失败| D[显示错误信息]'
echo ' D --> B'
echo ' C --> E[抄表管理]'
echo ' C --> F[收费管理]'
echo ' C --> G[账务管理]'
echo '```'
log_success "流程图模板已生成"
}
# 生成ER图
generate_er_diagram() {
echo '```mermaid'
echo 'erDiagram'
echo ' USER ||--o{ CUSTOMER : manages'
echo ' CUSTOMER ||--o{ WATER_METER : owns'
echo ' WATER_METER ||--o{ READING : generates'
echo ' '
echo ' USER {'
echo ' int user_id PK'
echo ' string username'
echo ' string password'
echo ' }'
echo '```'
log_success "ER图模板已生成"
}
# 生成时序图
generate_sequence_diagram() {
echo '```mermaid'
echo 'sequenceDiagram'
echo ' participant U as 用户'
echo ' participant W as Web界面'
echo ' participant S as 服务层'
echo ' participant D as 数据库'
echo ' '
echo ' U->>W: 登录请求'
echo ' W->>S: 验证用户'
echo ' S->>D: 查询用户信息'
echo ' D-->>S: 返回用户数据'
echo ' S-->>W: 登录响应'
echo ' W-->>U: 显示结果'
echo '```'
log_success "时序图模板已生成"
}
# 检查链接有效性
check_links() {
log_info "检查文档链接有效性..."
local broken_links=0
for file in *.md; do
if [[ -f "$file" ]]; then
log_info "检查文件: $file"
# 简化的链接检查,使用 grep 而不是正则表达式
local links=$(grep -o '\](.*\.md)' "$file" | sed 's/](\(.*\))/\1/' || true)
for link in $links; do
if [[ ! -f "$link" ]]; then
log_warning "断开的链接: $link (在文件 $file 中)"
broken_links=$((broken_links + 1))
fi
done
fi
done
if [[ $broken_links -eq 0 ]]; then
log_success "所有链接检查通过"
else
log_error "发现 $broken_links 个断开的链接"
fi
}
# 主函数
main() {
case "$1" in
init)
init_config
;;
create)
create_module_doc "$2"
;;
validate)
validate_doc "$2"
;;
export)
export_doc "$2" "$3"
;;
generate-diagram)
generate_diagram "$2"
;;
check-links)
check_links
;;
merge-docs)
merge_all_docs "$OUTPUT_DIR/merged_docs.md"
;;
help|--help|-h)
show_help
;;
*)
log_error "未知命令: $1"
show_help
exit 1
;;
esac
}
# 运行主函数
main "$@"