GoViewBoard 系统中前端和后端的联系:
🏗️ 架构概述
这个系统采用 前后端分离架构,包含两个独立的部分:
后端 (Backend)
- 技术栈: Go + Gin 框架
- 端口: 8080
- 功能: 提供 RESTful API 接口,处理业务逻辑,数据库操作
- 位置 :
go/目录
前端 (Frontend)
- 技术栈: Vue 3 + Element Plus + Vite
- 端口: 构建后静态文件,通过 API 与后端通信
- 功能: 用户界面展示,数据可视化,用户交互
- 位置 :
vue/目录
🔄 前端和后端的通信方式
1. API 调用
前端通过 HTTP 请求调用后端的 API 接口来获取和操作数据:
javascript
// 前端代码示例 (vue/src/api/dashboard.js)
export function getDashboardData() {
return request({
url: '/api/dashboard',
method: 'get'
})
}
2. 数据格式
- 通信采用 JSON 格式
- 使用 RESTful API 设计规范
🌐 主要 API 接口
让我为您查看实际的前后端接口
🗂️ 前端和后端的具体联系
1. API 接口对应关系
让我展示前端如何调用后端的 API:
#mermaid-svg-J7JwZid7MxvjyhiC{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-J7JwZid7MxvjyhiC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-J7JwZid7MxvjyhiC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-J7JwZid7MxvjyhiC .error-icon{fill:#552222;}#mermaid-svg-J7JwZid7MxvjyhiC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-J7JwZid7MxvjyhiC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-J7JwZid7MxvjyhiC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-J7JwZid7MxvjyhiC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-J7JwZid7MxvjyhiC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-J7JwZid7MxvjyhiC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-J7JwZid7MxvjyhiC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-J7JwZid7MxvjyhiC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-J7JwZid7MxvjyhiC .marker.cross{stroke:#333333;}#mermaid-svg-J7JwZid7MxvjyhiC svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-J7JwZid7MxvjyhiC p{margin:0;}#mermaid-svg-J7JwZid7MxvjyhiC .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-J7JwZid7MxvjyhiC .cluster-label text{fill:#333;}#mermaid-svg-J7JwZid7MxvjyhiC .cluster-label span{color:#333;}#mermaid-svg-J7JwZid7MxvjyhiC .cluster-label span p{background-color:transparent;}#mermaid-svg-J7JwZid7MxvjyhiC .label text,#mermaid-svg-J7JwZid7MxvjyhiC span{fill:#333;color:#333;}#mermaid-svg-J7JwZid7MxvjyhiC .node rect,#mermaid-svg-J7JwZid7MxvjyhiC .node circle,#mermaid-svg-J7JwZid7MxvjyhiC .node ellipse,#mermaid-svg-J7JwZid7MxvjyhiC .node polygon,#mermaid-svg-J7JwZid7MxvjyhiC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-J7JwZid7MxvjyhiC .rough-node .label text,#mermaid-svg-J7JwZid7MxvjyhiC .node .label text,#mermaid-svg-J7JwZid7MxvjyhiC .image-shape .label,#mermaid-svg-J7JwZid7MxvjyhiC .icon-shape .label{text-anchor:middle;}#mermaid-svg-J7JwZid7MxvjyhiC .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-J7JwZid7MxvjyhiC .rough-node .label,#mermaid-svg-J7JwZid7MxvjyhiC .node .label,#mermaid-svg-J7JwZid7MxvjyhiC .image-shape .label,#mermaid-svg-J7JwZid7MxvjyhiC .icon-shape .label{text-align:center;}#mermaid-svg-J7JwZid7MxvjyhiC .node.clickable{cursor:pointer;}#mermaid-svg-J7JwZid7MxvjyhiC .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-J7JwZid7MxvjyhiC .arrowheadPath{fill:#333333;}#mermaid-svg-J7JwZid7MxvjyhiC .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-J7JwZid7MxvjyhiC .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-J7JwZid7MxvjyhiC .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-J7JwZid7MxvjyhiC .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-J7JwZid7MxvjyhiC .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-J7JwZid7MxvjyhiC .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-J7JwZid7MxvjyhiC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-J7JwZid7MxvjyhiC .cluster text{fill:#333;}#mermaid-svg-J7JwZid7MxvjyhiC .cluster span{color:#333;}#mermaid-svg-J7JwZid7MxvjyhiC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-J7JwZid7MxvjyhiC .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-J7JwZid7MxvjyhiC rect.text{fill:none;stroke-width:0;}#mermaid-svg-J7JwZid7MxvjyhiC .icon-shape,#mermaid-svg-J7JwZid7MxvjyhiC .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-J7JwZid7MxvjyhiC .icon-shape p,#mermaid-svg-J7JwZid7MxvjyhiC .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-J7JwZid7MxvjyhiC .icon-shape .label rect,#mermaid-svg-J7JwZid7MxvjyhiC .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-J7JwZid7MxvjyhiC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-J7JwZid7MxvjyhiC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-J7JwZid7MxvjyhiC :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} HTTP 请求
JSON 数据
GET /api/orders
POST /api/orders
GET /api/dashboard
GET /api/product-configs
前端 Vue 应用
后端 Go API
获取订单列表
创建订单
获取大屏数据
获取产品配置
2. 核心 API 接口列表
后端提供的主要接口 (main.go 第47-75行):
| 前端页面 | 后端 API 接口 | 功能描述 |
|---|---|---|
| 订单管理 | /api/orders |
CRUD 订单操作 |
| 产品配置 | /api/product-configs |
管理产品SQL配置 |
| 数据大屏 | /api/dashboard |
获取大屏展示数据 |
| 系统配置 | /api/board-configs |
管理系统参数 |
3. 前端调用示例
javascript
// 前端发送请求 (vue/src/api/dashboard.js)
export function getDashboardData(params) {
return request.get('/dashboard', { params })
}
// 实际请求过程:
// 1. 前端发送: GET http://localhost:8080/api/dashboard
// 2. 后端接收: 查询数据库 → 返回JSON数据
// 3. 前端接收: 解析JSON → 更新页面显示
🔄 数据流转过程
让我以一个典型的操作来说明前后端的联系:
场景:页面加载时获取订单数据
数据库 (MySQL) 后端 (Go) 前端 (Vue) 用户 数据库 (MySQL) 后端 (Go) 前端 (Vue) 用户 #mermaid-svg-Y18mL7HsdTQfg0XZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Y18mL7HsdTQfg0XZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Y18mL7HsdTQfg0XZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Y18mL7HsdTQfg0XZ .error-icon{fill:#552222;}#mermaid-svg-Y18mL7HsdTQfg0XZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Y18mL7HsdTQfg0XZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Y18mL7HsdTQfg0XZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Y18mL7HsdTQfg0XZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Y18mL7HsdTQfg0XZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Y18mL7HsdTQfg0XZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Y18mL7HsdTQfg0XZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Y18mL7HsdTQfg0XZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Y18mL7HsdTQfg0XZ .marker.cross{stroke:#333333;}#mermaid-svg-Y18mL7HsdTQfg0XZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Y18mL7HsdTQfg0XZ p{margin:0;}#mermaid-svg-Y18mL7HsdTQfg0XZ .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Y18mL7HsdTQfg0XZ text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-Y18mL7HsdTQfg0XZ .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Y18mL7HsdTQfg0XZ .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-Y18mL7HsdTQfg0XZ .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-Y18mL7HsdTQfg0XZ .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-Y18mL7HsdTQfg0XZ #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-Y18mL7HsdTQfg0XZ .sequenceNumber{fill:white;}#mermaid-svg-Y18mL7HsdTQfg0XZ #sequencenumber{fill:#333;}#mermaid-svg-Y18mL7HsdTQfg0XZ #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-Y18mL7HsdTQfg0XZ .messageText{fill:#333;stroke:none;}#mermaid-svg-Y18mL7HsdTQfg0XZ .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Y18mL7HsdTQfg0XZ .labelText,#mermaid-svg-Y18mL7HsdTQfg0XZ .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-Y18mL7HsdTQfg0XZ .loopText,#mermaid-svg-Y18mL7HsdTQfg0XZ .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-Y18mL7HsdTQfg0XZ .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Y18mL7HsdTQfg0XZ .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-Y18mL7HsdTQfg0XZ .noteText,#mermaid-svg-Y18mL7HsdTQfg0XZ .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-Y18mL7HsdTQfg0XZ .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Y18mL7HsdTQfg0XZ .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Y18mL7HsdTQfg0XZ .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Y18mL7HsdTQfg0XZ .actorPopupMenu{position:absolute;}#mermaid-svg-Y18mL7HsdTQfg0XZ .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-Y18mL7HsdTQfg0XZ .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Y18mL7HsdTQfg0XZ .actor-man circle,#mermaid-svg-Y18mL7HsdTQfg0XZ line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-Y18mL7HsdTQfg0XZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 打开订单管理页面GET /api/orders?page=1&page_size=10SELECT * FROM board_order LIMIT 0,10返回订单数据返回JSON格式的订单数据在表格中显示订单列表
让我查找 vue 文件中的 API 调用
📂 项目结构分离
现在让我显示项目的结构来解释前后端如何分离:
bash
GoViewBoard/
├── go/ # 后端代码 (Go)
│ ├── api/ # API 接口实现
│ │ ├── order.go # 订单管理 API
│ │ ├── dashboard.go # 大屏数据 API
│ │ └── product_config.go # 产品配置 API
│ ├── dao/ # 数据库操作层
│ ├── model/ # 数据模型
│ └── main.go # 后端入口文件
│
└── vue/ # 前端代码 (Vue)
├── src/
│ ├── api/ # API 调用封装
│ │ ├── order.js # 订单相关 API 调用
│ │ ├── dashboard.js # 大屏数据 API 调用
│ │ └── index.js
│ ├── views/ # 页面组件
│ │ ├── OrderManage.vue # 订单管理页面
│ │ ├── Dashboard.vue # 数据大屏页面
│ │ └── ProductConfig.vue # 产品配置页面
│ └── utils/request.js # HTTP 请求工具
└── vite.config.js # 前端构建配置
🎯 前后端联系的关键要点
1. 通信格式统一
- 前端通过
request.js统一配置baseURL: '/api' - 后端路由统一以
/api开头 - 保证前后端接口路径对应
2. 数据格式标准
json
{
"code": 0, // 0=成功, 其他=失败
"msg": "success", // 状态消息
"data": {...} // 业务数据
}
3. 具体联系示例
前端调用 (vue/src/api/order.js):
javascript
export function getOrders(params) {
return request.get('/orders', { params })
}
后端处理 (go/main.go 第51行):
go
apiGroup.GET("/orders", api.GetOrders)
实际通信路径:
前端: request.get('/orders')
→ 实际请求: http://localhost:8080/api/orders
→ 后端接收: apiGroup.GET("/orders", api.GetOrders)
现在您清楚了吗?前端和后端就像两个独立的公司部门,通过标准化的接口协议(API)进行数据交换。前端负责展示和交互,后端负责数据处理和存储。