656 lines
29 KiB
HTML
656 lines
29 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>API接口文档 - 活牛采购智能数字化系统</title>
|
||
<meta name="description" content="活牛采购智能数字化系统API接口文档,提供完整的接口说明和示例代码。">
|
||
|
||
<!-- Bootstrap 5 CSS -->
|
||
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
|
||
<!-- Font Awesome Icons -->
|
||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||
<!-- Prism.js 代码高亮 -->
|
||
<link href="https://cdn.bootcdn.net/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet">
|
||
<!-- 自定义样式 -->
|
||
<link href="css/custom.css" rel="stylesheet">
|
||
<link href="css/responsive.css" rel="stylesheet">
|
||
|
||
<style>
|
||
.api-container {
|
||
background: #f8f9fa;
|
||
min-height: 100vh;
|
||
padding-top: 100px;
|
||
}
|
||
|
||
.api-header {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
color: white;
|
||
padding: 4rem 0;
|
||
margin-top: -100px;
|
||
padding-top: 150px;
|
||
}
|
||
|
||
.api-sidebar {
|
||
background: white;
|
||
border-radius: 15px;
|
||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
||
padding: 2rem;
|
||
position: sticky;
|
||
top: 120px;
|
||
max-height: calc(100vh - 140px);
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.api-content {
|
||
background: white;
|
||
border-radius: 15px;
|
||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
||
padding: 2rem;
|
||
}
|
||
|
||
.api-nav-item {
|
||
padding: 0.5rem 0.75rem;
|
||
margin: 0.25rem 0;
|
||
border-radius: 8px;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
border: none;
|
||
background: none;
|
||
width: 100%;
|
||
text-align: left;
|
||
font-size: 0.9rem;
|
||
text-decoration: none;
|
||
color: #333;
|
||
}
|
||
|
||
.api-nav-item:hover {
|
||
background: rgba(76, 175, 80, 0.1);
|
||
color: var(--primary-color);
|
||
transform: translateX(5px);
|
||
}
|
||
|
||
.api-nav-item.active {
|
||
background: var(--primary-color);
|
||
color: white;
|
||
}
|
||
|
||
.endpoint-card {
|
||
border: 1px solid #e9ecef;
|
||
border-radius: 12px;
|
||
margin-bottom: 2rem;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.endpoint-header {
|
||
background: #f8f9fa;
|
||
padding: 1.5rem;
|
||
border-bottom: 1px solid #e9ecef;
|
||
}
|
||
|
||
.method-badge {
|
||
padding: 0.25rem 0.75rem;
|
||
border-radius: 4px;
|
||
font-size: 0.75rem;
|
||
font-weight: 600;
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
.method-get { background: #28a745; color: white; }
|
||
.method-post { background: #007bff; color: white; }
|
||
.method-put { background: #ffc107; color: black; }
|
||
.method-delete { background: #dc3545; color: white; }
|
||
|
||
.endpoint-content {
|
||
padding: 1.5rem;
|
||
}
|
||
|
||
.param-table {
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.param-table th {
|
||
background: #f8f9fa;
|
||
border: none;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.param-table td {
|
||
border: 1px solid #e9ecef;
|
||
vertical-align: top;
|
||
}
|
||
|
||
.code-block {
|
||
background: #1e1e1e;
|
||
border-radius: 8px;
|
||
padding: 1rem;
|
||
margin: 1rem 0;
|
||
overflow-x: auto;
|
||
}
|
||
|
||
.response-example {
|
||
background: #f8f9fa;
|
||
border-left: 4px solid var(--primary-color);
|
||
padding: 1rem;
|
||
border-radius: 0 8px 8px 0;
|
||
}
|
||
|
||
.api-section {
|
||
display: none;
|
||
}
|
||
|
||
.api-section.active {
|
||
display: block;
|
||
}
|
||
|
||
.copy-btn {
|
||
position: absolute;
|
||
top: 0.5rem;
|
||
right: 0.5rem;
|
||
padding: 0.25rem 0.5rem;
|
||
background: rgba(255, 255, 255, 0.1);
|
||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||
border-radius: 4px;
|
||
color: white;
|
||
font-size: 0.75rem;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.copy-btn:hover {
|
||
background: rgba(255, 255, 255, 0.2);
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<!-- 导航栏 -->
|
||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
|
||
<div class="container">
|
||
<a class="navbar-brand d-flex align-items-center" href="index.html">
|
||
<div class="logo-container me-2">
|
||
<i class="fas fa-cow text-primary fs-2"></i>
|
||
</div>
|
||
<div class="brand-text">
|
||
<div class="brand-name fw-bold">NiuMall</div>
|
||
<div class="brand-subtitle">活牛采购智能系统</div>
|
||
</div>
|
||
</a>
|
||
|
||
<div class="navbar-nav ms-auto">
|
||
<a href="index.html" class="nav-link">
|
||
<i class="fas fa-home me-1"></i>返回首页
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<!-- API文档页面 -->
|
||
<div class="api-container">
|
||
<!-- 页面标题 -->
|
||
<section class="api-header">
|
||
<div class="container">
|
||
<div class="row align-items-center">
|
||
<div class="col-lg-8">
|
||
<h1 class="display-4 fw-bold mb-3">API接口文档</h1>
|
||
<p class="lead">完整的REST API接口文档,支持开发者快速集成活牛采购系统</p>
|
||
<div class="d-flex gap-3 mt-4">
|
||
<div class="badge bg-primary fs-6 px-3 py-2">
|
||
<i class="fas fa-code me-2"></i>RESTful API
|
||
</div>
|
||
<div class="badge bg-success fs-6 px-3 py-2">
|
||
<i class="fas fa-shield-alt me-2"></i>JWT认证
|
||
</div>
|
||
<div class="badge bg-info fs-6 px-3 py-2">
|
||
<i class="fas fa-database me-2"></i>JSON格式
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-lg-4 text-center">
|
||
<div class="api-info">
|
||
<h5 class="mb-3">API信息</h5>
|
||
<p><strong>基础URL:</strong><br>https://api.niumall.com/v1</p>
|
||
<p><strong>版本:</strong> v1.0</p>
|
||
<p><strong>认证:</strong> Bearer Token</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- API文档内容 -->
|
||
<section class="py-5">
|
||
<div class="container">
|
||
<div class="row">
|
||
<!-- 侧边导航 -->
|
||
<div class="col-lg-3">
|
||
<div class="api-sidebar">
|
||
<h5 class="mb-3">接口分类</h5>
|
||
<div class="api-nav">
|
||
<a href="#overview" class="api-nav-item active" onclick="showSection('overview')">
|
||
<i class="fas fa-info-circle me-2"></i>概述
|
||
</a>
|
||
<a href="#auth" class="api-nav-item" onclick="showSection('auth')">
|
||
<i class="fas fa-key me-2"></i>认证授权
|
||
</a>
|
||
<a href="#users" class="api-nav-item" onclick="showSection('users')">
|
||
<i class="fas fa-users me-2"></i>用户管理
|
||
</a>
|
||
<a href="#orders" class="api-nav-item" onclick="showSection('orders')">
|
||
<i class="fas fa-shopping-cart me-2"></i>订单管理
|
||
</a>
|
||
<a href="#suppliers" class="api-nav-item" onclick="showSection('suppliers')">
|
||
<i class="fas fa-store me-2"></i>供应商管理
|
||
</a>
|
||
<a href="#transport" class="api-nav-item" onclick="showSection('transport')">
|
||
<i class="fas fa-truck me-2"></i>运输管理
|
||
</a>
|
||
<a href="#finance" class="api-nav-item" onclick="showSection('finance')">
|
||
<i class="fas fa-chart-line me-2"></i>财务管理
|
||
</a>
|
||
<a href="#errors" class="api-nav-item" onclick="showSection('errors')">
|
||
<i class="fas fa-exclamation-triangle me-2"></i>错误处理
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- API文档内容区域 -->
|
||
<div class="col-lg-9">
|
||
<div class="api-content">
|
||
|
||
<!-- 概述 -->
|
||
<div id="overview" class="api-section active">
|
||
<h3 class="mb-4">API概述</h3>
|
||
<p class="text-muted mb-4">活牛采购智能数字化系统提供完整的REST API接口,支持开发者快速集成和自定义开发。</p>
|
||
|
||
<h5>快速开始</h5>
|
||
<p>所有API请求都需要使用HTTPS协议,并在请求头中包含有效的JWT Token。</p>
|
||
|
||
<div class="code-block position-relative">
|
||
<button class="copy-btn" onclick="copyCode(this)">复制</button>
|
||
<pre><code class="language-bash">curl -X GET "https://api.niumall.com/v1/orders" \
|
||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
|
||
-H "Content-Type: application/json"</code></pre>
|
||
</div>
|
||
|
||
<h5 class="mt-4">响应格式</h5>
|
||
<p>所有API响应都使用JSON格式,并遵循统一的响应结构:</p>
|
||
|
||
<div class="response-example">
|
||
<pre><code class="language-json">{
|
||
"success": true,
|
||
"data": {},
|
||
"message": "操作成功",
|
||
"timestamp": "2024-01-20T12:00:00Z"
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 认证授权 -->
|
||
<div id="auth" class="api-section">
|
||
<h3 class="mb-4">认证授权</h3>
|
||
|
||
<div class="endpoint-card">
|
||
<div class="endpoint-header">
|
||
<div class="d-flex align-items-center">
|
||
<span class="method-badge method-post">POST</span>
|
||
<span class="ms-3 fw-bold">/auth/login</span>
|
||
<span class="ms-auto text-muted">用户登录</span>
|
||
</div>
|
||
</div>
|
||
<div class="endpoint-content">
|
||
<h6>请求参数</h6>
|
||
<table class="table param-table">
|
||
<thead>
|
||
<tr>
|
||
<th>参数名</th>
|
||
<th>类型</th>
|
||
<th>必填</th>
|
||
<th>说明</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>username</td>
|
||
<td>string</td>
|
||
<td>是</td>
|
||
<td>用户名或手机号</td>
|
||
</tr>
|
||
<tr>
|
||
<td>password</td>
|
||
<td>string</td>
|
||
<td>是</td>
|
||
<td>密码</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h6 class="mt-3">请求示例</h6>
|
||
<div class="code-block position-relative">
|
||
<button class="copy-btn" onclick="copyCode(this)">复制</button>
|
||
<pre><code class="language-json">{
|
||
"username": "admin@example.com",
|
||
"password": "password123"
|
||
}</code></pre>
|
||
</div>
|
||
|
||
<h6 class="mt-3">响应示例</h6>
|
||
<div class="response-example">
|
||
<pre><code class="language-json">{
|
||
"success": true,
|
||
"data": {
|
||
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||
"token_type": "Bearer",
|
||
"expires_in": 3600,
|
||
"user": {
|
||
"id": 1,
|
||
"username": "admin",
|
||
"email": "admin@example.com",
|
||
"role": "admin"
|
||
}
|
||
},
|
||
"message": "登录成功"
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 订单管理 -->
|
||
<div id="orders" class="api-section">
|
||
<h3 class="mb-4">订单管理</h3>
|
||
|
||
<div class="endpoint-card">
|
||
<div class="endpoint-header">
|
||
<div class="d-flex align-items-center">
|
||
<span class="method-badge method-get">GET</span>
|
||
<span class="ms-3 fw-bold">/orders</span>
|
||
<span class="ms-auto text-muted">获取订单列表</span>
|
||
</div>
|
||
</div>
|
||
<div class="endpoint-content">
|
||
<h6>查询参数</h6>
|
||
<table class="table param-table">
|
||
<thead>
|
||
<tr>
|
||
<th>参数名</th>
|
||
<th>类型</th>
|
||
<th>必填</th>
|
||
<th>说明</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>page</td>
|
||
<td>integer</td>
|
||
<td>否</td>
|
||
<td>页码,默认1</td>
|
||
</tr>
|
||
<tr>
|
||
<td>limit</td>
|
||
<td>integer</td>
|
||
<td>否</td>
|
||
<td>每页数量,默认20</td>
|
||
</tr>
|
||
<tr>
|
||
<td>status</td>
|
||
<td>string</td>
|
||
<td>否</td>
|
||
<td>订单状态筛选</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h6 class="mt-3">响应示例</h6>
|
||
<div class="response-example">
|
||
<pre><code class="language-json">{
|
||
"success": true,
|
||
"data": {
|
||
"orders": [
|
||
{
|
||
"id": 1,
|
||
"order_no": "ORD20240120001",
|
||
"supplier_id": 101,
|
||
"supplier_name": "山东畜牧合作社",
|
||
"cattle_count": 50,
|
||
"total_weight": 25000,
|
||
"unit_price": 28.5,
|
||
"total_amount": 712500,
|
||
"status": "shipping",
|
||
"created_at": "2024-01-20T10:00:00Z"
|
||
}
|
||
],
|
||
"pagination": {
|
||
"current_page": 1,
|
||
"total_pages": 5,
|
||
"total_count": 100
|
||
}
|
||
},
|
||
"message": "获取成功"
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="endpoint-card">
|
||
<div class="endpoint-header">
|
||
<div class="d-flex align-items-center">
|
||
<span class="method-badge method-post">POST</span>
|
||
<span class="ms-3 fw-bold">/orders</span>
|
||
<span class="ms-auto text-muted">创建新订单</span>
|
||
</div>
|
||
</div>
|
||
<div class="endpoint-content">
|
||
<h6>请求参数</h6>
|
||
<table class="table param-table">
|
||
<thead>
|
||
<tr>
|
||
<th>参数名</th>
|
||
<th>类型</th>
|
||
<th>必填</th>
|
||
<th>说明</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>supplier_id</td>
|
||
<td>integer</td>
|
||
<td>是</td>
|
||
<td>供应商ID</td>
|
||
</tr>
|
||
<tr>
|
||
<td>cattle_breed</td>
|
||
<td>string</td>
|
||
<td>是</td>
|
||
<td>牛种类型</td>
|
||
</tr>
|
||
<tr>
|
||
<td>cattle_count</td>
|
||
<td>integer</td>
|
||
<td>是</td>
|
||
<td>牛只数量</td>
|
||
</tr>
|
||
<tr>
|
||
<td>expected_weight</td>
|
||
<td>decimal</td>
|
||
<td>是</td>
|
||
<td>预期重量(kg)</td>
|
||
</tr>
|
||
<tr>
|
||
<td>unit_price</td>
|
||
<td>decimal</td>
|
||
<td>是</td>
|
||
<td>单价(元/kg)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h6 class="mt-3">请求示例</h6>
|
||
<div class="code-block position-relative">
|
||
<button class="copy-btn" onclick="copyCode(this)">复制</button>
|
||
<pre><code class="language-json">{
|
||
"supplier_id": 101,
|
||
"cattle_breed": "西门塔尔",
|
||
"cattle_count": 30,
|
||
"expected_weight": 15000,
|
||
"unit_price": 28.5,
|
||
"delivery_address": "北京市朝阳区xx养殖场",
|
||
"expected_delivery_date": "2024-01-25"
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 错误处理 -->
|
||
<div id="errors" class="api-section">
|
||
<h3 class="mb-4">错误处理</h3>
|
||
|
||
<p class="text-muted mb-4">API使用标准HTTP状态码来表示请求的成功或失败状态。</p>
|
||
|
||
<h5>HTTP状态码</h5>
|
||
<table class="table">
|
||
<thead>
|
||
<tr>
|
||
<th>状态码</th>
|
||
<th>说明</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><span class="badge bg-success">200</span></td>
|
||
<td>请求成功</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge bg-primary">201</span></td>
|
||
<td>创建成功</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge bg-warning">400</span></td>
|
||
<td>请求参数错误</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge bg-danger">401</span></td>
|
||
<td>未授权,需要登录</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge bg-danger">403</span></td>
|
||
<td>禁止访问,权限不足</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge bg-danger">404</span></td>
|
||
<td>资源不存在</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge bg-danger">500</span></td>
|
||
<td>服务器内部错误</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h5 class="mt-4">错误响应格式</h5>
|
||
<div class="response-example">
|
||
<pre><code class="language-json">{
|
||
"success": false,
|
||
"error": {
|
||
"code": "VALIDATION_ERROR",
|
||
"message": "请求参数验证失败",
|
||
"details": [
|
||
{
|
||
"field": "cattle_count",
|
||
"message": "牛只数量必须大于0"
|
||
}
|
||
]
|
||
},
|
||
"timestamp": "2024-01-20T12:00:00Z"
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 其他部分省略,实际项目中会包含所有API接口 -->
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- Bootstrap JS -->
|
||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
|
||
<!-- Prism.js 代码高亮 -->
|
||
<script src="https://cdn.bootcdn.net/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
|
||
<script src="https://cdn.bootcdn.net/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
||
<!-- 自定义脚本 -->
|
||
<script src="js/main.js"></script>
|
||
|
||
<script>
|
||
// 显示指定的API部分
|
||
function showSection(sectionId) {
|
||
// 隐藏所有部分
|
||
document.querySelectorAll('.api-section').forEach(section => {
|
||
section.classList.remove('active');
|
||
});
|
||
|
||
// 移除所有导航项的active类
|
||
document.querySelectorAll('.api-nav-item').forEach(item => {
|
||
item.classList.remove('active');
|
||
});
|
||
|
||
// 显示选中的部分
|
||
document.getElementById(sectionId).classList.add('active');
|
||
|
||
// 激活对应的导航项
|
||
event.target.classList.add('active');
|
||
|
||
// 更新URL hash
|
||
window.location.hash = sectionId;
|
||
}
|
||
|
||
// 复制代码功能
|
||
function copyCode(button) {
|
||
const codeBlock = button.nextElementSibling;
|
||
const code = codeBlock.textContent;
|
||
|
||
navigator.clipboard.writeText(code).then(() => {
|
||
const originalText = button.textContent;
|
||
button.textContent = '已复制';
|
||
button.style.background = 'rgba(40, 167, 69, 0.8)';
|
||
|
||
setTimeout(() => {
|
||
button.textContent = originalText;
|
||
button.style.background = 'rgba(255, 255, 255, 0.1)';
|
||
}, 2000);
|
||
}).catch(err => {
|
||
console.error('复制失败:', err);
|
||
});
|
||
}
|
||
|
||
// 页面加载时根据hash显示对应部分
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
const hash = window.location.hash.substring(1);
|
||
if (hash && document.getElementById(hash)) {
|
||
showSection(hash);
|
||
}
|
||
|
||
// 初始化代码高亮
|
||
if (typeof Prism !== 'undefined') {
|
||
Prism.highlightAll();
|
||
}
|
||
});
|
||
|
||
// 平滑滚动到锚点
|
||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||
anchor.addEventListener('click', function(e) {
|
||
e.preventDefault();
|
||
const target = document.querySelector(this.getAttribute('href'));
|
||
if (target) {
|
||
target.scrollIntoView({
|
||
behavior: 'smooth',
|
||
block: 'start'
|
||
});
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
</body>
|
||
</html> |