# 数据库动态渲染系统 - 完整需求文档 ## 项目概述 构建一个可配置的数据渲染应用,通过读取 YAML 配置文件连接到指定数据库,根据配置查询不同数据表的内容,并按照预设的格式和模板进行处理,最终通过通用的列表页面向前端用户分页展示数据。 ## 技术栈与框架选型 ### 后端技术栈 - **HTTP 框架**: `github.com/gofiber/fiber/v3` - 高性能、零内存分配的 Go Web 框架 - **数据库 ORM**: `gorm.io/gorm` - 强大的数据库 ORM,支持多种数据库 - **日志系统**: `log/slog` - Go 官方结构化日志库 - **配置管理**: `github.com/spf13/viper` - 支持动态监听配置文件修改 - **依赖注入**: `github.com/google/wire` - Google 的依赖注入工具 ### 数据库支持 - **SQLite**: `github.com/mattn/go-sqlite3` - 轻量级嵌入式数据库 - **MySQL**: `github.com/go-sql-driver/mysql` - MySQL 驱动 - **PostgreSQL**: `github.com/lib/pq` - PostgreSQL 驱动 ### 前端技术栈 - **HTML 模板**: Go 标准库 `html/template` - 服务端模板渲染 - **CSS 框架**: TailwindCSS - 实用优先的 CSS 框架 - **JavaScript**: 原生 JavaScript (ES6+) - 轻量级交互 - **Markdown 渲染**: `marked.js` - Markdown 转 HTML ## 核心功能需求 ### 1. 配置系统 (YAML) #### 1.1 配置文件结构 ```yaml database: type: sqlite path: ./data/content.db # MySQL配置示例 # type: mysql # host: localhost # port: 3306 # user: root # password: password # dbname: testdb tables: - name: "articles" alias: "技术文章" page_size: 15 columns: - name: "id" alias: "ID" render_type: "raw" sortable: true width: "80px" - name: "title" alias: "标题" render_type: "raw" searchable: true max_length: 50 - name: "content" alias: "内容" render_type: "markdown" is_primary_content: true # 弹窗展示全文 show_in_list: false - name: "category" alias: "分类" render_type: "category" - name: "tags" alias: "标签" render_type: "tag" values: 1: { label: "Go", color: "#00ADD8" } 2: { label: "JavaScript", color: "#f7df1e" } - name: "created_at" alias: "发布时间" render_type: "time" format: "2006-01-02 15:04:05" sortable: true filters: - name: "category" type: "select" options: ["全部", "技术", "生活"] - name: "logs" alias: "系统日志" page_size: 50 columns: - name: "id" alias: "ID" render_type: "raw" - name: "level" alias: "级别" render_type: "tag" values: 1: { label: "INFO", color: "#52c41a" } 2: { label: "WARN", color: "#faad14" } 3: { label: "ERROR", color: "#f5222d" } - name: "message" alias: "日志信息" render_type: "raw" is_primary_content: true - name: "timestamp" alias: "时间" render_type: "time" format: "2006-01-02 15:04:05" ``` ### 2. 字段渲染类型规范 | 类型 | 描述 | 配置参数 | 示例 | | ---------- | ------------- | ------------------ | ------------------- | | `raw` | 原始文本 | 无 | 普通文本显示 | | `markdown` | Markdown 渲染 | `max_length` | 文章内容 | | `time` | 时间格式化 | `format` | 2024-01-01 12:00:00 | | `tag` | 标签样式 | `values`, `colors` | 状态标签 | | `category` | 分类显示 | 无 | 分类名称 | | `html` | HTML 内容 | `sanitize` | 富文本内容 | ### 3. 后端 API 接口 #### 3.1 获取表列表 ```http GET /api/tables ``` 响应: ```json { "tables": ["技术文章", "系统日志"] } ``` #### 3.2 获取分页数据 ```http GET /api/data/{table_alias}?page=1&per_page=20&search=keyword&sort=created_at&order=desc ``` 响应: ```json { "data": [ { "id": 1, "title": "Go语言入门", "category": "技术", "tags": "Go", "created_at": "2024-01-01 12:00:00" } ], "total": 100, "page": 1, "per_page": 20, "pages": 5 } ``` ### 4. Go 模板引擎规范 #### 4.1 通用列表模板 ```html {{.TableAlias}} - 数据管理
{{range .Columns}} {{if .ShowInList}} {{end}} {{end}} {{range .Data}} {{range $.Columns}} {{if .ShowInList}} {{end}} {{end}} {{end}}
{{.Alias}} 操作
{{template "render_field" dict "Value" (index $.Data (printf "%s" .Name)) "Type" .RenderType "Column" .}}
共 {{.Total}} 条记录,第 {{.Page}} / {{.Pages}} 页
{{if gt .Page 1}} 上一页 {{end}} {{if lt .Page .Pages}} 下一页 {{end}}
``` #### 4.2 模板辅助函数 ```go // 模板函数注册 func templateFuncs() template.FuncMap { return template.FuncMap{ "dict": func(values ...interface{}) map[string]interface{} { dict := make(map[string]interface{}) for i := 0; i < len(values); i += 2 { key := values[i].(string) dict[key] = values[i+1] } return dict }, "add": func(a, b int) int { return a + b }, "sub": func(a, b int) int { return a - b }, "json": func(v interface{}) string { b, _ := json.Marshal(v) return string(b) }, "renderField": func(value interface{}, renderType string, column interface{}) template.HTML { switch renderType { case "time": if t, ok := value.(time.Time); ok { return template.HTML(t.Format("2006-01-02 15:04:05")) } return template.HTML(fmt.Sprintf("%v", value)) case "tag": if columnMap, ok := column.(map[string]interface{}); ok { if values, ok := columnMap["values"].(map[string]interface{}); ok { if tag, ok := values[fmt.Sprintf("%v", value)].(map[string]interface{}); ok { color := tag["color"].(string) label := tag["label"].(string) return template.HTML(fmt.Sprintf( `%s`, color, label, )) } } } return template.HTML(fmt.Sprintf("%v", value)) case "markdown": // 服务端渲染Markdown return template.HTML(fmt.Sprintf("%v", value)) default: return template.HTML(fmt.Sprintf("%v", value)) } }, } } ``` ## 项目结构 ``` database-render/ ├── cmd/ │ └── server/ │ └── main.go ├── internal/ │ ├── config/ │ │ └── config.go │ ├── database/ │ │ └── connection.go │ ├── handler/ │ │ └── data_handler.go │ ├── model/ │ │ └── table_config.go │ ├── repository/ │ │ └── data_repository.go │ ├── service/ │ │ └── data_service.go │ └── template/ │ └── renderer.go ├── web/ │ ├── static/ │ │ ├── css/ │ │ ├── js/ │ │ └── images/ │ └── templates/ │ └── list.html ├── config/ │ └── config.yaml ├── migrations/ ├── scripts/ ├── tests/ ├── Makefile ├── Dockerfile ├── go.mod └── README.md ``` ## 构建与部署 ### 开发环境 ```bash # 安装依赖 go mod tidy # 运行开发服务器 make dev # 运行测试 make test ``` ### 生产部署 ```bash # 构建二进制 make build # 构建Docker镜像 docker build -t database-render . # 运行容器 docker run -p 8080:8080 -v ./config:/app/config database-render ``` ## 环境要求 - **开发环境**: Go 1.21+, Node.js 18+, SQLite3 - **生产环境**: Linux/Windows/macOS, Docker, SQLite/MySQL 5.7+/PostgreSQL 12+