docs: 更新项目文档,完善需求和技术细节

This commit is contained in:
ylweng
2025-09-01 01:23:49 +08:00
parent 816a51ae82
commit e1647902e2
4 changed files with 119 additions and 163 deletions

View File

@@ -37,33 +37,33 @@
<!-- 订单列表 -->
<el-table :data="orderList" border style="width: 100%" v-loading="loading">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="orderNo" label="订单号" width="180" />
<el-table-column prop="order_number" label="订单号" width="180" />
<el-table-column prop="username" label="用户" />
<el-table-column prop="phone" label="手机号" width="120" />
<el-table-column prop="amount" label="订单金额" width="100">
<el-table-column prop="total_amount" label="订单金额" width="100">
<template #default="scope">
¥{{ scope.row.amount }}
¥{{ scope.row.total_amount }}
</template>
</el-table-column>
<el-table-column label="支付状态" width="100">
<template #default="scope">
<el-tag v-if="scope.row.paymentStatus === 'pending'">待支付</el-tag>
<el-tag v-else-if="scope.row.paymentStatus === 'paid'" type="success">已支付</el-tag>
<el-tag v-else-if="scope.row.paymentStatus === 'cancelled'" type="danger">已取消</el-tag>
<el-tag v-else>{{ scope.row.paymentStatus }}</el-tag>
<el-tag v-if="scope.row.payment_status === 'pending'">待支付</el-tag>
<el-tag v-else-if="scope.row.payment_status === 'paid'" type="success">已支付</el-tag>
<el-tag v-else-if="scope.row.payment_status === 'cancelled'" type="danger">已取消</el-tag>
<el-tag v-else>{{ scope.row.payment_status }}</el-tag>
</template>
</el-table-column>
<el-table-column label="发货状态" width="100">
<template #default="scope">
<el-tag v-if="scope.row.shippingStatus === 'pending'">待发货</el-tag>
<el-tag v-else-if="scope.row.shippingStatus === 'shipped'" type="success">已发货</el-tag>
<el-tag v-else-if="scope.row.shippingStatus === 'completed'" type="primary">已完成</el-tag>
<el-tag v-else>{{ scope.row.shippingStatus }}</el-tag>
<el-tag v-if="scope.row.shipping_status === 'pending'">待发货</el-tag>
<el-tag v-else-if="scope.row.shipping_status === 'shipped'" type="success">已发货</el-tag>
<el-tag v-else-if="scope.row.shipping_status === 'completed'" type="primary">已完成</el-tag>
<el-tag v-else>{{ scope.row.shipping_status }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="下单时间" width="180">
<el-table-column prop="created_at" label="下单时间" width="180">
<template #default="scope">
{{ formatDate(scope.row.createTime) }}
{{ formatDate(scope.row.created_at) }}
</template>
</el-table-column>
<el-table-column label="操作" width="150">
@@ -73,7 +73,7 @@
size="small"
type="primary"
@click="handleUpdateStatus(scope.row)"
:disabled="scope.row.paymentStatus === 'cancelled'"
:disabled="scope.row.payment_status === 'cancelled'"
>
状态
</el-button>
@@ -96,37 +96,37 @@
<!-- 订单详情对话框 -->
<el-dialog v-model="detailDialogVisible" title="订单详情" width="700px">
<el-descriptions :column="1" border>
<el-descriptions-item label="订单号">{{ currentOrder.orderNo }}</el-descriptions-item>
<el-descriptions-item label="订单号">{{ currentOrder.order_number }}</el-descriptions-item>
<el-descriptions-item label="用户">{{ currentOrder.username }}</el-descriptions-item>
<el-descriptions-item label="手机号">{{ currentOrder.phone }}</el-descriptions-item>
<el-descriptions-item label="订单金额">¥{{ currentOrder.amount }}</el-descriptions-item>
<el-descriptions-item label="订单金额">¥{{ currentOrder.total_amount }}</el-descriptions-item>
<el-descriptions-item label="支付状态">
<el-tag v-if="currentOrder.paymentStatus === 'pending'">待支付</el-tag>
<el-tag v-else-if="currentOrder.paymentStatus === 'paid'" type="success">已支付</el-tag>
<el-tag v-else-if="currentOrder.paymentStatus === 'cancelled'" type="danger">已取消</el-tag>
<el-tag v-else>{{ currentOrder.paymentStatus }}</el-tag>
<el-tag v-if="currentOrder.payment_status === 'pending'">待支付</el-tag>
<el-tag v-else-if="currentOrder.payment_status === 'paid'" type="success">已支付</el-tag>
<el-tag v-else-if="currentOrder.payment_status === 'cancelled'" type="danger">已取消</el-tag>
<el-tag v-else>{{ currentOrder.payment_status }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="发货状态">
<el-tag v-if="currentOrder.shippingStatus === 'pending'">待发货</el-tag>
<el-tag v-else-if="currentOrder.shippingStatus === 'shipped'" type="success">已发货</el-tag>
<el-tag v-else-if="currentOrder.shippingStatus === 'completed'" type="primary">已完成</el-tag>
<el-tag v-else>{{ currentOrder.shippingStatus }}</el-tag>
<el-tag v-if="currentOrder.shipping_status === 'pending'">待发货</el-tag>
<el-tag v-else-if="currentOrder.shipping_status === 'shipped'" type="success">已发货</el-tag>
<el-tag v-else-if="currentOrder.shipping_status === 'completed'" type="primary">已完成</el-tag>
<el-tag v-else>{{ currentOrder.shipping_status }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="收货地址">{{ currentOrder.shippingAddress }}</el-descriptions-item>
<el-descriptions-item label="下单时间">{{ formatDate(currentOrder.createTime) }}</el-descriptions-item>
<el-descriptions-item label="收货地址">{{ currentOrder.shipping_address }}</el-descriptions-item>
<el-descriptions-item label="下单时间">{{ formatDate(currentOrder.created_at) }}</el-descriptions-item>
</el-descriptions>
<el-table :data="currentOrder.items" style="margin-top: 20px;" border>
<el-table-column prop="productName" label="商品名称" />
<el-table-column prop="product_name" label="商品名称" />
<el-table-column prop="quantity" label="数量" width="80" />
<el-table-column prop="unitPrice" label="单价" width="100">
<el-table-column prop="unit_price" label="单价" width="100">
<template #default="scope">
¥{{ scope.row.unitPrice }}
¥{{ scope.row.unit_price }}
</template>
</el-table-column>
<el-table-column label="小计" width="100">
<template #default="scope">
¥{{ (scope.row.unitPrice * scope.row.quantity).toFixed(2) }}
¥{{ (scope.row.unit_price * scope.row.quantity).toFixed(2) }}
</template>
</el-table-column>
</el-table>
@@ -142,14 +142,14 @@
<el-dialog v-model="statusDialogVisible" title="更新订单状态" width="500px">
<el-form :model="statusForm" label-width="100px">
<el-form-item label="支付状态">
<el-select v-model="statusForm.paymentStatus" placeholder="请选择">
<el-select v-model="statusForm.payment_status" placeholder="请选择">
<el-option label="待支付" value="pending" />
<el-option label="已支付" value="paid" />
<el-option label="已取消" value="cancelled" />
</el-select>
</el-form-item>
<el-form-item label="发货状态">
<el-select v-model="statusForm.shippingStatus" placeholder="请选择">
<el-select v-model="statusForm.shipping_status" placeholder="请选择">
<el-option label="待发货" value="pending" />
<el-option label="已发货" value="shipped" />
<el-option label="已完成" value="completed" />
@@ -169,7 +169,8 @@
<script>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ElMessage } from 'element-plus'
import { orderAPI } from '../utils/api'
export default {
name: 'Orders',
@@ -186,8 +187,8 @@ export default {
const statusForm = reactive({
id: null,
paymentStatus: '',
shippingStatus: ''
payment_status: '',
shipping_status: ''
})
const orderList = ref([])
@@ -209,58 +210,23 @@ export default {
const fetchOrders = async () => {
loading.value = true
try {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 500))
const params = {
page: pagination.page,
limit: pagination.limit,
status: searchForm.status,
start_date: dateRange.value && dateRange.value[0] ? dateRange.value[0] : undefined,
end_date: dateRange.value && dateRange.value[1] ? dateRange.value[1] : undefined
}
// 模拟数据
orderList.value = [
{
id: 1,
orderNo: 'ORD202401150001',
username: 'user001',
phone: '13800001111',
amount: 199,
paymentStatus: 'paid',
shippingStatus: 'shipped',
createTime: '2024-01-15 10:30:00',
shippingAddress: '浙江省杭州市西湖区文三路159号',
items: [
{ productName: 'AI鉴花小程序', quantity: 1, unitPrice: 199 }
]
},
{
id: 2,
orderNo: 'ORD202401160002',
username: 'admin',
phone: '13900002222',
amount: 598,
paymentStatus: 'paid',
shippingStatus: 'pending',
createTime: '2024-01-16 14:20:00',
shippingAddress: '浙江省杭州市滨江区网商路699号',
items: [
{ productName: '花卉识别API', quantity: 2, unitPrice: 299 }
]
},
{
id: 3,
orderNo: 'ORD202401170003',
username: 'editor001',
phone: '13700003333',
amount: 999,
paymentStatus: 'pending',
shippingStatus: 'pending',
createTime: '2024-01-17 09:15:00',
shippingAddress: '浙江省杭州市余杭区五常大道1001号',
items: [
{ productName: '企业版解决方案', quantity: 1, unitPrice: 999 }
]
}
]
pagination.total = orderList.value.length
const response = await orderAPI.getOrders(params)
if (response.code === 200) {
orderList.value = response.data.orders
pagination.total = response.data.pagination.total
} else {
ElMessage.error(response.message || '获取订单列表失败')
}
} catch (error) {
ElMessage.error('获取订单列表失败')
ElMessage.error('获取订单列表失败: ' + error.message)
} finally {
loading.value = false
}
@@ -282,35 +248,35 @@ export default {
// 查看订单详情
const handleView = (row) => {
currentOrder.value = { ...row }
currentOrder.value = row
detailDialogVisible.value = true
}
// 更新订单状态
const handleUpdateStatus = (row) => {
statusForm.id = row.id
statusForm.paymentStatus = row.paymentStatus
statusForm.shippingStatus = row.shippingStatus
statusForm.payment_status = row.payment_status
statusForm.shipping_status = row.shipping_status
statusDialogVisible.value = true
}
// 提交状态更新
const submitStatusUpdate = async () => {
try {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 300))
const response = await orderAPI.updateOrderStatus(statusForm.id, {
payment_status: statusForm.payment_status,
shipping_status: statusForm.shipping_status
})
// 更新订单状态
const index = orderList.value.findIndex(item => item.id === statusForm.id)
if (index !== -1) {
orderList.value[index].paymentStatus = statusForm.paymentStatus
orderList.value[index].shippingStatus = statusForm.shippingStatus
if (response.code === 200) {
ElMessage.success('状态更新成功')
statusDialogVisible.value = false
fetchOrders()
} else {
ElMessage.error(response.message || '状态更新失败')
}
ElMessage.success('状态更新成功')
statusDialogVisible.value = false
} catch (error) {
ElMessage.error('状态更新失败')
ElMessage.error('状态更新失败: ' + error.message)
}
}

View File

@@ -107,6 +107,7 @@
import { ref, reactive, onMounted } from 'vue'
import * as echarts from 'echarts'
import { statisticsAPI } from '../utils/api'
import { ElMessage } from 'element-plus'
export default {
name: 'Statistics',
@@ -137,60 +138,62 @@ export default {
// 获取统计数据
const fetchStatsData = async () => {
try {
// 模拟数据
statsData.userCount = 1234
statsData.productCount = 567
statsData.orderCount = 890
statsData.totalRevenue = 123456.78
const response = await statisticsAPI.getUserStats()
if (response.code === 200) {
statsData.userCount = response.data.user_count
statsData.productCount = response.data.product_count
statsData.orderCount = response.data.order_count
statsData.totalRevenue = response.data.total_revenue
} else {
ElMessage.error(response.message || '获取统计数据失败')
}
} catch (error) {
console.error('获取统计数据失败:', error)
ElMessage.error('获取统计数据失败: ' + error.message)
}
}
// 获取用户图表数据
const fetchUserChartData = async () => {
try {
// 模拟数据
chartData.userGrowth = {
dates: ['1月1日', '1月2日', '1月3日', '1月4日', '1月5日', '1月6日', '1月7日'],
counts: [10, 25, 15, 30, 20, 35, 40]
const response = await statisticsAPI.getUserStats()
if (response.code === 200) {
chartData.userGrowth = response.data.user_growth
renderUserChart()
} else {
ElMessage.error(response.message || '获取用户图表数据失败')
}
renderUserChart()
} catch (error) {
console.error('获取用户图表数据失败:', error)
ElMessage.error('获取用户图表数据失败: ' + error.message)
}
}
// 获取分类图表数据
const fetchCategoryChartData = async () => {
try {
// 模拟数据
chartData.categoryDistribution = [
{ name: '鲜花', value: 45 },
{ name: '盆栽', value: 30 },
{ name: '种子', value: 15 },
{ name: '工具', value: 10 }
]
renderCategoryChart()
const response = await statisticsAPI.getProductStats()
if (response.code === 200) {
chartData.categoryDistribution = response.data.category_distribution
renderCategoryChart()
} else {
ElMessage.error(response.message || '获取分类图表数据失败')
}
} catch (error) {
console.error('获取分类图表数据失败:', error)
ElMessage.error('获取分类图表数据失败: ' + error.message)
}
}
// 获取订单状态图表数据
const fetchOrderStatusChartData = async () => {
try {
// 模拟数据
chartData.orderStatusDistribution = [
{ name: '待支付', value: 20 },
{ name: '已支付', value: 50 },
{ name: '已发货', value: 15 },
{ name: '已完成', value: 10 },
{ name: '已取消', value: 5 }
]
renderOrderStatusChart()
const response = await statisticsAPI.getOrderStats()
if (response.code === 200) {
chartData.orderStatusDistribution = response.data.status_distribution
renderOrderStatusChart()
} else {
ElMessage.error(response.message || '获取订单状态图表数据失败')
}
} catch (error) {
console.error('获取订单状态图表数据失败:', error)
ElMessage.error('获取订单状态图表数据失败: ' + error.message)
}
}

View File

@@ -6,18 +6,15 @@
## 基础信息
- **基础URL**: `http://localhost:3200/api/v1`
- **Base URL**: `http://localhost:3200/api/v1`
- **认证方式**: Bearer Token (JWT)
- **数据格式**: JSON
- **字符编码**: UTF-8
- **响应格式**: JSON
## 认证接口
### 用户注册
```http
POST /auth/register
```
**POST** `/auth/register`
**请求参数**:
@@ -30,6 +27,7 @@ POST /auth/register
| user_type | string | 否 | 用户类型farmer/buyer/admin |
**响应示例**:
```json
{
"code": 201,
@@ -47,9 +45,7 @@ POST /auth/register
### 用户登录
```http
POST /auth/login
```
**POST** `/auth/login`
**请求参数**:
@@ -59,6 +55,7 @@ POST /auth/login
| password | string | 是 | 密码 |
**响应示例**:
```json
{
"code": 200,
@@ -79,9 +76,7 @@ POST /auth/login
### 获取用户信息
```http
GET /users/me
```
**GET** `/users/me`
**请求头**:
```
@@ -89,6 +84,7 @@ Authorization: Bearer <token>
```
**响应示例**:
```json
{
"code": 200,
@@ -108,9 +104,7 @@ Authorization: Bearer <token>
### 更新用户信息
```http
PUT /users/{id}
```
**PUT** `/users/{id}`
**请求参数**:
@@ -124,9 +118,7 @@ PUT /users/{id}
### 获取商品列表
```http
GET /products
```
**GET** `/products`
**查询参数**:
@@ -142,6 +134,7 @@ GET /products
| sort_order | string | 排序方向asc/desc |
**响应示例**:
```json
{
"code": 200,
@@ -171,17 +164,13 @@ GET /products
### 获取商品详情
```http
GET /products/{id}
```
**GET** `/products/{id}`
## 订单接口
### 创建订单
```http
POST /orders
```
**POST** `/orders`
**请求参数**:
@@ -204,9 +193,7 @@ POST /orders
### 花卉识别
```http
POST /identifications/identify
```
**POST** `/identifications/identify`
**请求格式**: `multipart/form-data`
@@ -217,6 +204,7 @@ POST /identifications/identify
| image | file | 是 | 花卉图片文件 |
**响应示例**:
```json
{
"code": 200,
@@ -244,9 +232,7 @@ POST /identifications/identify
### 获取识别历史
```http
GET /identifications
```
**GET** `/identifications`
## 错误码说明

View File

@@ -4,7 +4,7 @@
## 基础信息
- **Base URL**: `http://localhost:3200/api`
- **Base URL**: `http://localhost:3200/api/v1`
- **认证方式**: Bearer Token (JWT)
- **响应格式**: JSON
@@ -258,9 +258,10 @@
| 错误码 | 说明 |
|--------|------|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 201 | 创建成功 |
| 400 | 参数错误 |
| 401 | 未授权 |
| 403 | 权限不足 |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 409 | 资源冲突 |
| 500 | 服务器内部错误 |