From 59a9743992821890ef0dacd8aec3140839876c4c Mon Sep 17 00:00:00 2001 From: peng Date: Tue, 28 Oct 2025 09:40:08 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=9F=E4=BA=A7=E7=AE=A1=E7=90=86=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=20=E5=89=8D=E7=AB=AF=E4=B8=8D=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E7=9A=84=E6=96=87=E4=BB=B6=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crop-x/API_SETUP.md | 178 ------------ crop-x/scripts/openapi.json | 342 +++++++++++++++++++++++ crop-x/src/apis/index.ts | 21 -- crop-x/src/apis/modules/ai-model.ts | 163 ----------- crop-x/src/apis/modules/asset.ts | 135 --------- crop-x/src/apis/modules/auth.ts | 72 ----- crop-x/src/apis/modules/config.ts | 262 ----------------- crop-x/src/apis/modules/irrigation.ts | 192 ------------- crop-x/src/apis/modules/land.ts | 127 --------- crop-x/src/apis/modules/machinery.ts | 105 ------- crop-x/src/apis/modules/operation.ts | 147 ---------- crop-x/src/apis/request.ts | 80 ------ crop-x/src/apis/types.ts | 51 ---- crop-x/src/lib/api/client.gen.ts | 2 +- crop-x/src/router/index.tsx | 55 ---- crop-x/src/router/modules/ai-model.tsx | 28 -- crop-x/src/router/modules/asset.tsx | 28 -- crop-x/src/router/modules/config.tsx | 38 --- crop-x/src/router/modules/irrigation.tsx | 28 -- crop-x/src/router/modules/land.tsx | 48 ---- crop-x/src/router/modules/machinery.tsx | 43 --- crop-x/src/router/modules/operation.tsx | 38 --- crop-x/src/services/api/messageLogApi.ts | 267 ------------------ 23 files changed, 343 insertions(+), 2107 deletions(-) delete mode 100644 crop-x/API_SETUP.md create mode 100644 crop-x/scripts/openapi.json delete mode 100644 crop-x/src/apis/index.ts delete mode 100644 crop-x/src/apis/modules/ai-model.ts delete mode 100644 crop-x/src/apis/modules/asset.ts delete mode 100644 crop-x/src/apis/modules/auth.ts delete mode 100644 crop-x/src/apis/modules/config.ts delete mode 100644 crop-x/src/apis/modules/irrigation.ts delete mode 100644 crop-x/src/apis/modules/land.ts delete mode 100644 crop-x/src/apis/modules/machinery.ts delete mode 100644 crop-x/src/apis/modules/operation.ts delete mode 100644 crop-x/src/apis/request.ts delete mode 100644 crop-x/src/apis/types.ts delete mode 100644 crop-x/src/router/index.tsx delete mode 100644 crop-x/src/router/modules/ai-model.tsx delete mode 100644 crop-x/src/router/modules/asset.tsx delete mode 100644 crop-x/src/router/modules/config.tsx delete mode 100644 crop-x/src/router/modules/irrigation.tsx delete mode 100644 crop-x/src/router/modules/land.tsx delete mode 100644 crop-x/src/router/modules/machinery.tsx delete mode 100644 crop-x/src/router/modules/operation.tsx delete mode 100644 crop-x/src/services/api/messageLogApi.ts diff --git a/crop-x/API_SETUP.md b/crop-x/API_SETUP.md deleted file mode 100644 index 31457b0..0000000 --- a/crop-x/API_SETUP.md +++ /dev/null @@ -1,178 +0,0 @@ -# OpenAPI TypeScript 设置指南 - -## 🚀 快速开始 - -### 1. 已完成的步骤 - -✅ 创建了示例 OpenAPI 规范文件 (`./api/v1.yaml`) -✅ 生成了 TypeScript 类型定义 (`./src/lib/api/v1.d.ts`) -✅ 创建了 API 客户端 (`./src/lib/api/client.ts`) -✅ 创建了使用示例组件 (`./src/components/examples/ApiExample.tsx`) - -### 2. 如何使用 - -#### 基本用法 - -```typescript -import { api } from '@/lib/api/client'; - -// 获取用户列表 -const users = await api.users.getList({ page: 1, limit: 20 }); - -// 获取用户详情 -const user = await api.users.getDetail(1); - -// 创建农机 -const newMachine = await api.machinery.create({ - name: '新拖拉机', - type: 'tractor', - model: 'John Deere 6M', -}); -``` - -#### 类型安全 - -```typescript -// ✅ 类型安全的 API 调用 -const params = { - page: 1, - limit: 20, - status: 'running' as const, // TypeScript 会检查枚举值 -}; - -// ❌ 错误会被 TypeScript 捕获 -const wrongParams = { - status: 'invalid-status', // TypeScript 错误: 类型不匹配 -}; -``` - -## 🔄 更新 API 规范 - -### 当后端 API 发生变化时: - -1. **更新 OpenAPI 规范文件** - ```bash - # 方式一:手动编辑 ./api/v1.yaml - # 方式二:从后端自动生成(如果后端支持) - curl https://gitea-admin-test-app-app.dev.maimaiag.com/v3/api-docs > ./api/v1.yaml - ``` - -2. **重新生成 TypeScript 类型** - ```bash - npx openapi-typescript ./api/v1.yaml -o ./src/lib/api/v1.d.ts - ``` - -3. **更新客户端代码**(如果接口有重大变化) - -## 🛠️ 进阶配置 - -### 添加认证 - -```typescript -import { authClient } from '@/lib/api/client'; - -// 使用认证客户端 -const token = localStorage.getItem('jwt-token'); -const authenticatedApi = authClient.withAuth(token); - -const user = await authenticatedApi.users.getDetail(1); -``` - -### 错误处理 - -```typescript -try { - const result = await api.users.getList(); - // 处理成功响应 -} catch (error) { - if (error.message.includes('404')) { - // 处理 404 错误 - } else if (error.message.includes('401')) { - // 处理认证错误 - } -} -``` - -### 自定义配置 - -```typescript -const customClient = createClient({ - baseUrl: 'https://gitea-admin-test-app-app.dev.maimaiag.com/api/v1', - headers: { - 'User-Agent': 'Smart-Crop-UI/1.0', - 'X-API-Key': process.env.API_KEY, - }, - // 添加请求拦截器 - onRequest: async ({ request }) => { - // 可以在这里添加日志、重试逻辑等 - console.log('发送请求:', request.url); - return request; - }, - // 添加响应拦截器 - onResponse: async ({ response }) => { - if (response.status === 401) { - // 处理 token 过期 - window.location.href = '/login'; - } - return response; - }, -}); -``` - -## 📁 文件结构 - -``` -crop-x/ -├── api/ -│ └── v1.yaml # OpenAPI 规范文件 -├── src/ -│ ├── lib/ -│ │ └── api/ -│ │ ├── v1.d.ts # 生成的类型定义 -│ │ └── client.ts # API 客户端封装 -│ └── components/ -│ └── examples/ -│ └── ApiExample.tsx # 使用示例 -``` - -## 🎯 最佳实践 - -### 1. 版本控制 -- 将 `v1.yaml` 纳入版本控制 -- 将生成的 `v1.d.ts` 也纳入版本控制,方便代码审查 -- 在 CI/CD 中自动重新生成类型文件 - -### 2. 类型安全 -- 优先使用 `api.machinery.create()` 这样的封装方法 -- 避免直接使用 `client.POST()` -- 充分利用 TypeScript 的类型检查 - -### 3. 错误处理 -- 在客户端封装中统一处理 API 错误 -- 提供有意义的错误信息给用户 -- 实现重试机制和降级策略 - -### 4. 性能优化 -- 实现请求缓存 -- 使用 React Query 或 SWR 进行数据获取 -- 考虑添加请求去重 - -## 🔗 相关资源 - -- [openapi-typescript 官方文档](https://github.com/drwp/openapi-typescript) -- [OpenAPI 规范](https://swagger.io/specification/) -- [shadcn/ui](https://ui.shadcn.com/) - -## ❓ 常见问题 - -**Q: 如何处理分页?** -A: API 已经支持分页参数 `page` 和 `limit`,响应中包含 `total` 字段。 - -**Q: 如何处理文件上传?** -A: 需要在 OpenAPI 规范中定义 `multipart/form-data` 格式的接口。 - -**Q: 如何实现 WebSocket 连接?** -A: 当前只支持 HTTP REST API,WebSocket 需要单独实现。 - -**Q: 如何添加 Mock 数据?** -A: 可以创建另一个客户端实例,返回模拟数据而不是真实请求。 \ No newline at end of file diff --git a/crop-x/scripts/openapi.json b/crop-x/scripts/openapi.json new file mode 100644 index 0000000..637b4aa --- /dev/null +++ b/crop-x/scripts/openapi.json @@ -0,0 +1,342 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Crop Admin API", + "description": "一个支持OpenAPI和前端代码自动生成的后台管理系统", + "version": "1.0.0" + }, + "paths": { + "/api/v1/auth/login": { + "post": { + "tags": [ + "认证" + ], + "summary": "用户登录", + "description": "用户登录接口\n\n- **username**: 用户名\n- **password**: 密码\n\n返回JWT访问令牌", + "operationId": "login_api_v1_auth_login_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserLogin" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/auth/register": { + "post": { + "tags": [ + "认证" + ], + "summary": "用户注册", + "description": "用户注册接口\n\n- **username**: 用户名 (必须唯一)\n- **password**: 密码\n\n注意:这是一个演示版本,实际生产环境需要更严格的验证", + "operationId": "register_api_v1_auth_register_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRegister" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/auth/me": { + "get": { + "tags": [ + "认证" + ], + "summary": "获取当前用户信息", + "description": "获取当前登录用户的信息", + "operationId": "get_current_user_api_v1_auth_me_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIResponse" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, + "/api/v1/auth/logout": { + "post": { + "tags": [ + "认证" + ], + "summary": "用户登出", + "description": "用户登出接口\n\n注意:由于JWT是无状态的,实际登出需要客户端删除token\n这里只是验证token并返回成功消息", + "operationId": "logout_api_v1_auth_logout_post", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIResponse" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, + "/api/v1/auth/users": { + "get": { + "tags": [ + "认证" + ], + "summary": "获取所有用户列表", + "description": "获取系统中所有用户的列表 (仅用于演示)", + "operationId": "get_all_users_api_v1_auth_users_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIResponse" + } + } + } + } + } + } + }, + "/": { + "get": { + "summary": "Root", + "operationId": "root__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, + "/health": { + "get": { + "summary": "Health Check", + "operationId": "health_check_health_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + } + }, + "components": { + "schemas": { + "APIResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "data": { + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Data" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "APIResponse", + "example": { + "data": {}, + "message": "操作成功", + "success": true + } + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "UserLogin": { + "properties": { + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "title": "Password" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "UserLogin", + "example": { + "password": "admin123", + "username": "admin" + } + }, + "UserRegister": { + "properties": { + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "title": "Password" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "UserRegister", + "example": { + "password": "newpassword", + "username": "newuser" + } + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + } + }, + "securitySchemes": { + "HTTPBearer": { + "type": "http", + "scheme": "bearer" + } + } + }, + "servers": [ + { + "url": "https://gitea-admin-smart-crop-x-app.dev.maimaiag.com/", + "description": "测试环境服务器" + } + ] +} \ No newline at end of file diff --git a/crop-x/src/apis/index.ts b/crop-x/src/apis/index.ts deleted file mode 100644 index f929945..0000000 --- a/crop-x/src/apis/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { authApi } from './modules/auth' -import { machineryApi } from './modules/machinery' -import { landApi } from './modules/land' -import { operationApi } from './modules/operation' -import { assetApi } from './modules/asset' -import { aiModelApi } from './modules/ai-model' -import { irrigationApi } from './modules/irrigation' -import { configApi } from './modules/config' - -export const api = { - auth: authApi, - machinery: machineryApi, - land: landApi, - operation: operationApi, - asset: assetApi, - aiModel: aiModelApi, - irrigation: irrigationApi, - config: configApi -} - -export * from './types' \ No newline at end of file diff --git a/crop-x/src/apis/modules/ai-model.ts b/crop-x/src/apis/modules/ai-model.ts deleted file mode 100644 index e5bb6b5..0000000 --- a/crop-x/src/apis/modules/ai-model.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { request } from '../request' -import { ApiResponse, PaginatedResponse, QueryRequest } from '../types' - -// AI模型相关类型 -export interface AIModel { - id: string - name: string - version: string - type: 'prediction' | 'classification' | 'recommendation' | 'anomaly_detection' - domain: 'crop_yield' | 'disease_detection' | 'pest_prediction' | 'irrigation_optimization' | 'fertilizer_recommendation' - description: string - algorithm: string - accuracy: number - trainingDataset: string - trainingDate: string - status: 'training' | 'trained' | 'deployed' | 'deprecated' - parameters: Record - features: string[] - targetVariable: string - modelFile?: string - tenantId: string - createdAt: string - updatedAt: string -} - -export interface ModelTraining { - id: string - modelId: string - name: string - datasetId: string - parameters: Record - status: 'pending' | 'running' | 'completed' | 'failed' - progress: number - startTime?: string - endTime?: string - metrics?: { - accuracy: number - precision: number - recall: number - f1Score: number - loss?: number - } - logs?: string[] - errorMessage?: string - createdAt: string - updatedAt: string -} - -export interface PredictionRequest { - modelId: string - inputData: Record - options?: { - probability?: boolean - explanations?: boolean - } -} - -export interface PredictionResult { - id: string - modelId: string - prediction: any - confidence?: number - probability?: Record - explanations?: Array<{ - feature: string - importance: number - contribution: string - }> - inputData: Record - timestamp: string - processingTime: number -} - -export interface Recommendation { - id: string - type: 'fertilizer' | 'irrigation' | 'planting' | 'harvesting' | 'pest_control' - priority: 'low' | 'medium' | 'high' - title: string - description: string - recommendation: string - confidence: number - validFrom: string - validTo: string - applicableArea?: string - estimatedCost?: number - estimatedBenefit?: number - landParcelId?: string - cropType?: string - metadata: Record - status: 'active' | 'applied' | 'expired' | 'dismissed' - createdAt: string - updatedAt: string -} - -export const aiModelApi = { - // 模型管理 - getModelList: (params: QueryRequest): Promise>> => { - return request.get('/ai-model/models', params) - }, - - getModelDetail: (id: string): Promise> => { - return request.get(`/ai-model/models/${id}`) - }, - - createModel: (data: Omit): Promise> => { - return request.post('/ai-model/models', data) - }, - - updateModel: (id: string, data: Partial): Promise> => { - return request.put(`/ai-model/models/${id}`, data) - }, - - deleteModel: (id: string): Promise> => { - return request.delete(`/ai-model/models/${id}`) - }, - - deployModel: (id: string): Promise> => { - return request.post(`/ai-model/models/${id}/deploy`) - }, - - // 模型训练 - startTraining: (data: Omit): Promise> => { - return request.post('/ai-model/training', data) - }, - - getTrainingDetail: (id: string): Promise> => { - return request.get(`/ai-model/training/${id}`) - }, - - getTrainingList: (params: QueryRequest): Promise>> => { - return request.get('/ai-model/training', params) - }, - - stopTraining: (id: string): Promise> => { - return request.post(`/ai-model/training/${id}/stop`) - }, - - // 预测分析 - makePrediction: (data: PredictionRequest): Promise> => { - return request.post('/ai-model/predict', data) - }, - - getPredictionHistory: (params: QueryRequest): Promise>> => { - return request.get('/ai-model/predictions', params) - }, - - getPredictionDetail: (id: string): Promise> => { - return request.get(`/ai-model/predictions/${id}`) - }, - - // 推荐系统 - getRecommendations: (params: QueryRequest & { type?: string; landParcelId?: string }): Promise>> => { - return request.get('/ai-model/recommendations', params) - }, - - applyRecommendation: (id: string): Promise> => { - return request.put(`/ai-model/recommendations/${id}/apply`) - }, - - dismissRecommendation: (id: string, reason: string): Promise> => { - return request.put(`/ai-model/recommendations/${id}/dismiss`, { reason }) - } -} \ No newline at end of file diff --git a/crop-x/src/apis/modules/asset.ts b/crop-x/src/apis/modules/asset.ts deleted file mode 100644 index 53c2926..0000000 --- a/crop-x/src/apis/modules/asset.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { request } from '../request' -import { ApiResponse, PaginatedResponse, QueryRequest } from '../types' - -// 资产管理相关类型 -export interface AgriculturalAsset { - id: string - name: string - category: 'machinery' | 'equipment' | 'building' | 'land_improvement' | 'livestock' | 'other' - subcategory: string - serialNumber?: string - model?: string - brand?: string - purchaseDate: string - purchasePrice: number - currentValue: number - depreciationMethod: 'straight_line' | 'declining_balance' | 'units_of_production' - usefulLifeYears: number - salvageValue: number - location: string - status: 'active' | 'inactive' | 'disposed' | 'maintenance' - assignedTo?: string - description?: string - images?: string[] - documents?: string[] - tenantId: string - createdAt: string - updatedAt: string -} - -export interface MaintenanceRecord { - id: string - assetId: string - type: 'preventive' | 'corrective' | 'emergency' - description: string - performedDate: string - performedBy: string - cost: number - partsUsed?: Array<{ - name: string - quantity: number - unitCost: number - }> - nextMaintenanceDate?: string - notes?: string - documents?: string[] - createdAt: string - updatedAt: string -} - -export interface AssetInventory { - id: string - assetId: string - quantity: number - unit: string - location: string - lastCountDate: string - expectedQuantity: number - variance: number - varianceReason?: string - countedBy: string - verifiedBy?: string - status: 'verified' | 'pending_verification' | 'discrepancy' - tenantId: string - createdAt: string - updatedAt: string -} - -export const assetApi = { - // 资产管理 - getAssetList: (params: QueryRequest): Promise>> => { - return request.get('/asset/assets', params) - }, - - getAssetDetail: (id: string): Promise> => { - return request.get(`/asset/assets/${id}`) - }, - - createAsset: (data: Omit): Promise> => { - return request.post('/asset/assets', data) - }, - - updateAsset: (id: string, data: Partial): Promise> => { - return request.put(`/asset/assets/${id}`, data) - }, - - deleteAsset: (id: string): Promise> => { - return request.delete(`/asset/assets/${id}`) - }, - - calculateDepreciation: (id: string, date: string): Promise> => { - return request.post(`/asset/assets/${id}/depreciation`, { date }) - }, - - // 维护记录 - getMaintenanceRecords: (params: QueryRequest): Promise>> => { - return request.get('/asset/maintenance', params) - }, - - getMaintenanceDetail: (id: string): Promise> => { - return request.get(`/asset/maintenance/${id}`) - }, - - createMaintenanceRecord: (data: Omit): Promise> => { - return request.post('/asset/maintenance', data) - }, - - updateMaintenanceRecord: (id: string, data: Partial): Promise> => { - return request.put(`/asset/maintenance/${id}`, data) - }, - - deleteMaintenanceRecord: (id: string): Promise> => { - return request.delete(`/asset/maintenance/${id}`) - }, - - // 库存管理 - getInventoryList: (params: QueryRequest): Promise>> => { - return request.get('/asset/inventory', params) - }, - - getInventoryDetail: (id: string): Promise> => { - return request.get(`/asset/inventory/${id}`) - }, - - createInventoryRecord: (data: Omit): Promise> => { - return request.post('/asset/inventory', data) - }, - - updateInventoryRecord: (id: string, data: Partial): Promise> => { - return request.put(`/asset/inventory/${id}`, data) - }, - - verifyInventory: (id: string, verifiedBy: string): Promise> => { - return request.put(`/asset/inventory/${id}/verify`, { verifiedBy }) - } -} \ No newline at end of file diff --git a/crop-x/src/apis/modules/auth.ts b/crop-x/src/apis/modules/auth.ts deleted file mode 100644 index b2ae83c..0000000 --- a/crop-x/src/apis/modules/auth.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { request } from '../request' -import { ApiResponse } from '../types' - -// 认证相关类型 -export interface LoginRequest { - username: string - password: string -} - -export interface PhoneLoginRequest { - phone: string - code: string -} - -export interface LoginResponse { - token: string - refreshToken: string - user: { - id: string - username: string - phone: string - role: string - tenantId: string - } -} - -export interface User { - id: string - username: string - phone: string - role: string - tenantId: string - avatar?: string - email?: string -} - -export const authApi = { - // 用户名密码登录 - login: (data: LoginRequest): Promise> => { - return request.post('/auth/login', data) - }, - - // 手机验证码登录 - loginByPhone: (data: PhoneLoginRequest): Promise> => { - return request.post('/auth/login/phone', data) - }, - - // 获取验证码 - sendSmsCode: (phone: string): Promise> => { - return request.post('/auth/sms/send', { phone }) - }, - - // 刷新token - refreshToken: (refreshToken: string): Promise> => { - return request.post('/auth/refresh', { refreshToken }) - }, - - // 登出 - logout: (): Promise> => { - return request.post('/auth/logout') - }, - - // 获取用户信息 - getUserInfo: (): Promise> => { - return request.get('/auth/user') - }, - - // 更新用户信息 - updateUserInfo: (data: Partial): Promise> => { - return request.put('/auth/user', data) - } -} \ No newline at end of file diff --git a/crop-x/src/apis/modules/config.ts b/crop-x/src/apis/modules/config.ts deleted file mode 100644 index f496d6b..0000000 --- a/crop-x/src/apis/modules/config.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { request } from '../request' -import { ApiResponse, PaginatedResponse, QueryRequest } from '../types' - -// 中心配置相关类型 -export interface Tenant { - id: string - name: string - code: string - type: 'individual' | 'enterprise' | 'cooperative' - status: 'active' | 'inactive' | 'suspended' - contactPerson: string - contactPhone: string - contactEmail: string - address: string - maxUsers: number - currentUsers: number - subscriptionPlan: 'basic' | 'standard' | 'premium' - subscriptionExpiry?: string - settings: { - timezone: string - language: string - currency: string - dateFormat: string - numberFormat: string - } - features: string[] - createdAt: string - updatedAt: string -} - -export interface User { - id: string - username: string - email: string - phone: string - realName: string - avatar?: string - role: 'admin' | 'manager' | 'operator' | 'viewer' - tenantId: string - status: 'active' | 'inactive' | 'locked' - lastLoginAt?: string - permissions: string[] - preferences: { - language: string - theme: 'light' | 'dark' | 'auto' - notifications: { - email: boolean - sms: boolean - push: boolean - } - } - createdAt: string - updatedAt: string -} - -export interface SystemParameter { - id: string - category: 'system' | 'business' | 'notification' | 'security' | 'integration' - key: string - value: string - type: 'string' | 'number' | 'boolean' | 'json' - description: string - isEditable: boolean - requiresRestart: boolean - validationRules?: { - required?: boolean - min?: number - max?: number - pattern?: string - options?: string[] - } - tenantId?: string - createdAt: string - updatedAt: string -} - -export interface SystemLog { - id: string - level: 'debug' | 'info' | 'warn' | 'error' | 'fatal' - category: 'system' | 'business' | 'security' | 'performance' - message: string - details?: any - userId?: string - tenantId?: string - ip?: string - userAgent?: string - timestamp: string - duration?: number - stackTrace?: string -} - -export interface Message { - id: string - type: 'system' | 'business' | 'notification' | 'alert' - category: 'info' | 'warning' | 'error' | 'success' - title: string - content: string - senderId?: string - recipientId?: string - recipientRole?: string - tenantId?: string - status: 'unread' | 'read' | 'archived' - priority: 'low' | 'medium' | 'high' | 'urgent' - expiresAt?: string - metadata?: Record - createdAt: string - readAt?: string -} - -export const configApi = { - // 租户管理 - getTenantList: (params: QueryRequest): Promise>> => { - return request.get('/config/tenants', params) - }, - - getTenantDetail: (id: string): Promise> => { - return request.get(`/config/tenants/${id}`) - }, - - createTenant: (data: Omit): Promise> => { - return request.post('/config/tenants', data) - }, - - updateTenant: (id: string, data: Partial): Promise> => { - return request.put(`/config/tenants/${id}`, data) - }, - - deleteTenant: (id: string): Promise> => { - return request.delete(`/config/tenants/${id}`) - }, - - suspendTenant: (id: string): Promise> => { - return request.post(`/config/tenants/${id}/suspend`) - }, - - activateTenant: (id: string): Promise> => { - return request.post(`/config/tenants/${id}/activate`) - }, - - // 用户管理 - getUserList: (params: QueryRequest): Promise>> => { - return request.get('/config/users', params) - }, - - getUserDetail: (id: string): Promise> => { - return request.get(`/config/users/${id}`) - }, - - createUser: (data: Omit): Promise> => { - return request.post('/config/users', data) - }, - - updateUser: (id: string, data: Partial): Promise> => { - return request.put(`/config/users/${id}`, data) - }, - - deleteUser: (id: string): Promise> => { - return request.delete(`/config/users/${id}`) - }, - - resetPassword: (id: string, newPassword: string): Promise> => { - return request.post(`/config/users/${id}/reset-password`, { newPassword }) - }, - - lockUser: (id: string): Promise> => { - return request.post(`/config/users/${id}/lock`) - }, - - unlockUser: (id: string): Promise> => { - return request.post(`/config/users/${id}/unlock`) - }, - - // 系统参数 - getParameterList: (params: QueryRequest): Promise>> => { - return request.get('/config/parameters', params) - }, - - getParameterDetail: (id: string): Promise> => { - return request.get(`/config/parameters/${id}`) - }, - - createParameter: (data: Omit): Promise> => { - return request.post('/config/parameters', data) - }, - - updateParameter: (id: string, data: Partial): Promise> => { - return request.put(`/config/parameters/${id}`, data) - }, - - deleteParameter: (id: string): Promise> => { - return request.delete(`/config/parameters/${id}`) - }, - - getParametersByCategory: (category: string): Promise> => { - return request.get(`/config/parameters/category/${category}`) - }, - - // 系统监控 - getSystemLogs: (params: QueryRequest & { level?: string; category?: string }): Promise>> => { - return request.get('/config/logs', params) - }, - - getSystemMetrics: (): Promise> => { - return request.get('/config/metrics') - }, - - getSystemHealth: (): Promise - issues: Array<{ - type: 'error' | 'warning' - message: string - timestamp: string - }> - }>> => { - return request.get('/config/health') - }, - - // 消息中心 - getMessageList: (params: QueryRequest): Promise>> => { - return request.get('/config/messages', params) - }, - - getMessageDetail: (id: string): Promise> => { - return request.get(`/config/messages/${id}`) - }, - - createMessage: (data: Omit): Promise> => { - return request.post('/config/messages', data) - }, - - markMessageAsRead: (id: string): Promise> => { - return request.put(`/config/messages/${id}/read`) - }, - - archiveMessage: (id: string): Promise> => { - return request.put(`/config/messages/${id}/archive`) - }, - - deleteMessage: (id: string): Promise> => { - return request.delete(`/config/messages/${id}`) - }, - - getUnreadCount: (): Promise> => { - return request.get('/config/messages/unread/count') - } -} \ No newline at end of file diff --git a/crop-x/src/apis/modules/irrigation.ts b/crop-x/src/apis/modules/irrigation.ts deleted file mode 100644 index 2553284..0000000 --- a/crop-x/src/apis/modules/irrigation.ts +++ /dev/null @@ -1,192 +0,0 @@ -import { request } from '../request' -import { ApiResponse, PaginatedResponse, QueryRequest } from '../types' - -// 灌溉控制相关类型 -export interface IrrigationSystem { - id: string - name: string - type: 'drip' | 'sprinkler' | 'flood' | 'micro_sprinkler' - location: string - landParcelId: string - area: number - waterSource: string - pumpCapacity: number - flowRate: number - pressure: number - status: 'active' | 'inactive' | 'maintenance' - installationDate: string - lastMaintenanceDate?: string - nextMaintenanceDate?: string - description?: string - tenantId: string - createdAt: string - updatedAt: string -} - -export interface IrrigationZone { - id: string - systemId: string - name: string - area: number - cropType: string - soilType: string - waterRequirement: number - currentMoisture: number - targetMoisture: number - status: 'active' | 'inactive' | 'irrigating' - sensors: Array<{ - id: string - type: 'moisture' | 'temperature' | 'humidity' | 'ph' - location: string - currentValue: number - unit: string - lastReading: string - }> - valves: Array<{ - id: string - name: string - status: 'open' | 'closed' - flowRate: number - }> - createdAt: string - updatedAt: string -} - -export interface IrrigationSchedule { - id: string - zoneId: string - name: string - type: 'fixed_time' | 'sensor_based' | 'weather_based' - startTime: string - duration: number - waterAmount: number - frequency: 'daily' | 'weekly' | 'custom' - daysOfWeek?: number[] - startDate: string - endDate?: string - priority: 'low' | 'medium' | 'high' - status: 'active' | 'paused' | 'completed' | 'cancelled' - conditions?: { - moistureThreshold?: number - weatherCondition?: string - temperatureRange?: { - min: number - max: number - } - } - createdAt: string - updatedAt: string -} - -export interface MonitoringData { - id: string - zoneId: string - sensorType: 'moisture' | 'temperature' | 'humidity' | 'ph' | 'flow_rate' | 'pressure' - value: number - unit: string - timestamp: string - location?: string -} - -export interface ControlCommand { - id: string - systemId: string - zoneId?: string - command: 'start_irrigation' | 'stop_irrigation' | 'open_valve' | 'close_valve' | 'adjust_flow_rate' - parameters: Record - status: 'pending' | 'executing' | 'completed' | 'failed' - executedAt?: string - errorMessage?: string - createdAt: string - updatedAt: string -} - -export const irrigationApi = { - // 系统控制 - getSystemList: (params: QueryRequest): Promise>> => { - return request.get('/irrigation/systems', params) - }, - - getSystemDetail: (id: string): Promise> => { - return request.get(`/irrigation/systems/${id}`) - }, - - createSystem: (data: Omit): Promise> => { - return request.post('/irrigation/systems', data) - }, - - updateSystem: (id: string, data: Partial): Promise> => { - return request.put(`/irrigation/systems/${id}`, data) - }, - - deleteSystem: (id: string): Promise> => { - return request.delete(`/irrigation/systems/${id}`) - }, - - startIrrigation: (systemId: string, zoneId?: string, duration?: number): Promise> => { - return request.post(`/irrigation/systems/${systemId}/start`, { zoneId, duration }) - }, - - stopIrrigation: (systemId: string, zoneId?: string): Promise> => { - return request.post(`/irrigation/systems/${systemId}/stop`, { zoneId }) - }, - - // 分区管理 - getZoneList: (systemId: string, params: QueryRequest): Promise>> => { - return request.get(`/irrigation/systems/${systemId}/zones`, params) - }, - - getZoneDetail: (id: string): Promise> => { - return request.get(`/irrigation/zones/${id}`) - }, - - createZone: (data: Omit): Promise> => { - return request.post('/irrigation/zones', data) - }, - - updateZone: (id: string, data: Partial): Promise> => { - return request.put(`/irrigation/zones/${id}`, data) - }, - - deleteZone: (id: string): Promise> => { - return request.delete(`/irrigation/zones/${id}`) - }, - - // 监控系统 - getMonitoringData: (zoneId: string, params: QueryRequest & { sensorType?: string }): Promise>> => { - return request.get(`/irrigation/zones/${zoneId}/monitoring`, params) - }, - - getRealTimeData: (zoneId: string): Promise> => { - return request.get(`/irrigation/zones/${zoneId}/realtime`) - }, - - // 调度系统 - getScheduleList: (params: QueryRequest): Promise>> => { - return request.get('/irrigation/schedules', params) - }, - - getScheduleDetail: (id: string): Promise> => { - return request.get(`/irrigation/schedules/${id}`) - }, - - createSchedule: (data: Omit): Promise> => { - return request.post('/irrigation/schedules', data) - }, - - updateSchedule: (id: string, data: Partial): Promise> => { - return request.put(`/irrigation/schedules/${id}`, data) - }, - - deleteSchedule: (id: string): Promise> => { - return request.delete(`/irrigation/schedules/${id}`) - }, - - pauseSchedule: (id: string): Promise> => { - return request.post(`/irrigation/schedules/${id}/pause`) - }, - - resumeSchedule: (id: string): Promise> => { - return request.post(`/irrigation/schedules/${id}/resume`) - } -} \ No newline at end of file diff --git a/crop-x/src/apis/modules/land.ts b/crop-x/src/apis/modules/land.ts deleted file mode 100644 index 57e3a0d..0000000 --- a/crop-x/src/apis/modules/land.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { request } from '../request' -import { ApiResponse, PaginatedResponse, QueryRequest } from '../types' - -// 地块相关类型 -export interface LandParcel { - id: string - name: string - code: string - area: number - areaUnit: 'mu' | 'hectare' | 'acre' - location: { - latitude: number - longitude: number - address: string - } - boundaries: Array<{ - latitude: number - longitude: number - }> - soilType: string - landUse: string - ownershipType: 'owned' | 'rented' | 'shared' - tenantId: string - description?: string - createdAt: string - updatedAt: string -} - -export interface LandClassification { - id: string - landParcelId: string - category: string - subcategory: string - tags: string[] - attributes: Record - createdAt: string - updatedAt: string -} - -export interface MapLayer { - id: string - name: string - type: 'base' | 'overlay' | 'analysis' - url: string - opacity: number - visible: boolean - attribution?: string -} - -export interface SpatialAnalysis { - id: string - name: string - type: 'buffer' | 'overlay' | 'proximity' | 'suitability' - parameters: Record - result: { - area: number - geometry: any - statistics: Record - } - createdAt: string -} - -export const landApi = { - // 地块档案管理 - getLandParcelList: (params: QueryRequest): Promise>> => { - return request.get('/land/parcels', params) - }, - - getLandParcelDetail: (id: string): Promise> => { - return request.get(`/land/parcels/${id}`) - }, - - createLandParcel: (data: Omit): Promise> => { - return request.post('/land/parcels', data) - }, - - updateLandParcel: (id: string, data: Partial): Promise> => { - return request.put(`/land/parcels/${id}`, data) - }, - - deleteLandParcel: (id: string): Promise> => { - return request.delete(`/land/parcels/${id}`) - }, - - // 地块分类管理 - getClassificationList: (params: QueryRequest): Promise>> => { - return request.get('/land/classifications', params) - }, - - createClassification: (data: Omit): Promise> => { - return request.post('/land/classifications', data) - }, - - updateClassification: (id: string, data: Partial): Promise> => { - return request.put(`/land/classifications/${id}`, data) - }, - - deleteClassification: (id: string): Promise> => { - return request.delete(`/land/classifications/${id}`) - }, - - // 地图管理 - getMapLayers: (): Promise> => { - return request.get('/land/maps/layers') - }, - - createMapLayer: (data: Omit): Promise> => { - return request.post('/land/maps/layers', data) - }, - - updateMapLayer: (id: string, data: Partial): Promise> => { - return request.put(`/land/maps/layers/${id}`, data) - }, - - deleteMapLayer: (id: string): Promise> => { - return request.delete(`/land/maps/layers/${id}`) - }, - - // 空间分析 - performSpatialAnalysis: (data: Omit): Promise> => { - return request.post('/land/analysis/spatial', data) - }, - - getAnalysisHistory: (params: QueryRequest): Promise>> => { - return request.get('/land/analysis/history', params) - } -} \ No newline at end of file diff --git a/crop-x/src/apis/modules/machinery.ts b/crop-x/src/apis/modules/machinery.ts deleted file mode 100644 index 7fd2cda..0000000 --- a/crop-x/src/apis/modules/machinery.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { request } from '../request' -import { ApiResponse, PaginatedResponse, QueryRequest } from '../types' - -// 农机相关类型 -export interface Machinery { - id: string - name: string - type: string - model: string - status: 'active' | 'inactive' | 'maintenance' | 'repair' - location: { - latitude: number - longitude: number - address: string - } - driverId?: string - lastMaintenanceDate?: string - nextMaintenanceDate?: string - purchaseDate: string - price: number - description?: string - createdAt: string - updatedAt: string -} - -export interface Driver { - id: string - name: string - phone: string - licenseNumber: string - licenseType: string - experience: number - status: 'active' | 'inactive' - machineryId?: string - tenantId: string - createdAt: string - updatedAt: string -} - -export interface MonitoringData { - id: string - machineryId: string - location: { - latitude: number - longitude: number - } - speed: number - fuelLevel: number - engineHours: number - workingStatus: 'working' | 'idle' | 'stopped' - timestamp: string -} - -export const machineryApi = { - // 农机管理 - getMachineryList: (params: QueryRequest): Promise>> => { - return request.get('/machinery', params) - }, - - getMachineryDetail: (id: string): Promise> => { - return request.get(`/machinery/${id}`) - }, - - createMachinery: (data: Omit): Promise> => { - return request.post('/machinery', data) - }, - - updateMachinery: (id: string, data: Partial): Promise> => { - return request.put(`/machinery/${id}`, data) - }, - - deleteMachinery: (id: string): Promise> => { - return request.delete(`/machinery/${id}`) - }, - - // 驾驶员管理 - getDriverList: (params: QueryRequest): Promise>> => { - return request.get('/machinery/drivers', params) - }, - - getDriverDetail: (id: string): Promise> => { - return request.get(`/machinery/drivers/${id}`) - }, - - createDriver: (data: Omit): Promise> => { - return request.post('/machinery/drivers', data) - }, - - updateDriver: (id: string, data: Partial): Promise> => { - return request.put(`/machinery/drivers/${id}`, data) - }, - - deleteDriver: (id: string): Promise> => { - return request.delete(`/machinery/drivers/${id}`) - }, - - // 实时监控 - getRealTimeData: (machineryId: string): Promise> => { - return request.get(`/machinery/monitoring/${machineryId}`) - }, - - getMonitoringHistory: (machineryId: string, params: QueryRequest): Promise>> => { - return request.get(`/machinery/monitoring/${machineryId}/history`, params) - } -} \ No newline at end of file diff --git a/crop-x/src/apis/modules/operation.ts b/crop-x/src/apis/modules/operation.ts deleted file mode 100644 index 489a7d2..0000000 --- a/crop-x/src/apis/modules/operation.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { request } from '../request' -import { ApiResponse, PaginatedResponse, QueryRequest } from '../types' - -// 农事操作相关类型 -export interface FarmingTask { - id: string - title: string - description: string - type: 'planting' | 'harvesting' | 'fertilizing' | 'irrigating' | 'pest_control' | 'other' - status: 'pending' | 'in_progress' | 'completed' | 'cancelled' - priority: 'low' | 'medium' | 'high' | 'urgent' - assignedTo?: string - landParcelId: string - machineryId?: string - scheduledStartDate: string - scheduledEndDate: string - actualStartDate?: string - actualEndDate?: string - estimatedCost?: number - actualCost?: number - notes?: string - tenantId: string - createdAt: string - updatedAt: string -} - -export interface TaskTemplate { - id: string - name: string - description: string - taskType: string - defaultDuration: number - requiredResources: string[] - checklistItems: string[] - costEstimate: number - tenantId: string -} - -export interface ResourceAllocation { - id: string - taskId: string - resourceType: 'machinery' | 'labor' | 'material' | 'tool' - resourceId: string - quantity: number - allocatedDate: string - returnDate?: string - status: 'allocated' | 'in_use' | 'returned' -} - -export interface Workflow { - id: string - name: string - description: string - stages: Array<{ - id: string - name: string - description: string - duration: number - dependencies: string[] - resources: string[] - }> - landParcelId: string - status: 'draft' | 'active' | 'completed' | 'paused' - startDate?: string - endDate?: string - tenantId: string - createdAt: string - updatedAt: string -} - -export const operationApi = { - // 任务管理 - getTaskList: (params: QueryRequest): Promise>> => { - return request.get('/operation/tasks', params) - }, - - getTaskDetail: (id: string): Promise> => { - return request.get(`/operation/tasks/${id}`) - }, - - createTask: (data: Omit): Promise> => { - return request.post('/operation/tasks', data) - }, - - updateTask: (id: string, data: Partial): Promise> => { - return request.put(`/operation/tasks/${id}`, data) - }, - - deleteTask: (id: string): Promise> => { - return request.delete(`/operation/tasks/${id}`) - }, - - updateTaskStatus: (id: string, status: FarmingTask['status']): Promise> => { - return request.put(`/operation/tasks/${id}/status`, { status }) - }, - - // 任务模板 - getTaskTemplateList: (params: QueryRequest): Promise>> => { - return request.get('/operation/templates', params) - }, - - createTaskTemplate: (data: Omit): Promise> => { - return request.post('/operation/templates', data) - }, - - updateTaskTemplate: (id: string, data: Partial): Promise> => { - return request.put(`/operation/templates/${id}`, data) - }, - - deleteTaskTemplate: (id: string): Promise> => { - return request.delete(`/operation/templates/${id}`) - }, - - // 资源分配 - getResourceAllocations: (params: QueryRequest): Promise>> => { - return request.get('/operation/resources', params) - }, - - allocateResource: (data: Omit): Promise> => { - return request.post('/operation/resources/allocate', data) - }, - - returnResource: (id: string): Promise> => { - return request.put(`/operation/resources/${id}/return`) - }, - - // 工作流管理 - getWorkflowList: (params: QueryRequest): Promise>> => { - return request.get('/operation/workflows', params) - }, - - getWorkflowDetail: (id: string): Promise> => { - return request.get(`/operation/workflows/${id}`) - }, - - createWorkflow: (data: Omit): Promise> => { - return request.post('/operation/workflows', data) - }, - - updateWorkflow: (id: string, data: Partial): Promise> => { - return request.put(`/operation/workflows/${id}`, data) - }, - - deleteWorkflow: (id: string): Promise> => { - return request.delete(`/operation/workflows/${id}`) - } -} \ No newline at end of file diff --git a/crop-x/src/apis/request.ts b/crop-x/src/apis/request.ts deleted file mode 100644 index 2dc991f..0000000 --- a/crop-x/src/apis/request.ts +++ /dev/null @@ -1,80 +0,0 @@ -import axios, { AxiosInstance, AxiosResponse } from 'axios' -import { config } from '@/config/features' -import { ApiResponse, ApiError } from './types' - -/** - * 请求管理器类 - * 封装了基于Axios的HTTP请求操作,包括请求和响应拦截器 - */ -/** - private instance: AxiosInstance // Axios实例,用于发送HTTP请求 - * 使用Axios库进行HTTP请求,并添加了请求和响应拦截器 - */ -class RequestManager { - private instance: AxiosInstance - - constructor() { - this.instance = axios.create({ - baseURL: config.apiUrl, - timeout: 10000, - headers: { - 'Content-Type': 'application/json' - } - }) - - this.setupInterceptors() - } - - private setupInterceptors() { - // 请求拦截器 - this.instance.interceptors.request.use( - (config) => { - const token = localStorage.getItem('token') - if (token) { - config.headers.Authorization = `Bearer ${token}` - } - return config - }, - (error) => { - return Promise.reject(error) - } - ) - - // 响应拦截器 - this.instance.interceptors.response.use( - (response: AxiosResponse) => { - const { data } = response - if (data.success) { - return response - } else { - return Promise.reject(new Error(data.message)) - } - }, - (error) => { - if (error.response?.status === 401) { - localStorage.removeItem('token') - window.location.href = '/login' - } - return Promise.reject(error) - } - ) - } - - public get(url: string, params?: any): Promise> { - return this.instance.get(url, { params }).then(res => res.data) - } - - public post(url: string, data?: any): Promise> { - return this.instance.post(url, data).then(res => res.data) - } - - public put(url: string, data?: any): Promise> { - return this.instance.put(url, data).then(res => res.data) - } - - public delete(url: string): Promise> { - return this.instance.delete(url).then(res => res.data) - } -} - -export const request = new RequestManager() \ No newline at end of file diff --git a/crop-x/src/apis/types.ts b/crop-x/src/apis/types.ts deleted file mode 100644 index 2eac1c7..0000000 --- a/crop-x/src/apis/types.ts +++ /dev/null @@ -1,51 +0,0 @@ -// API 响应类型定义 -export interface ApiResponse { - code: number - message: string - data: T - success: boolean -} - -// 分页请求参数 -export interface PaginationParams { - page: number - pageSize: number - total?: number -} - -// 分页响应数据 -export interface PaginatedResponse { - items: T[] - total: number - page: number - pageSize: number - totalPages: number -} - -// 错误响应 -export interface ApiError { - code: number - message: string - details?: any -} - -// 通用CRUD操作类型 -export interface CreateRequest { - data: Omit -} - -export interface UpdateRequest { - id: string | number - data: Partial -} - -export interface DeleteRequest { - id: string | number -} - -export interface QueryRequest extends PaginationParams { - keyword?: string - filters?: Record - sortBy?: string - sortOrder?: 'asc' | 'desc' -} \ No newline at end of file diff --git a/crop-x/src/lib/api/client.gen.ts b/crop-x/src/lib/api/client.gen.ts index 8087612..4f6cc39 100644 --- a/crop-x/src/lib/api/client.gen.ts +++ b/crop-x/src/lib/api/client.gen.ts @@ -14,5 +14,5 @@ import type { ClientOptions as ClientOptions2 } from './types.gen'; export type CreateClientConfig = (override?: Config) => Config & T>; export const client = createClient(createConfig({ - baseUrl: 'http://localhost:8080' + baseUrl: 'http://26.26.26.1:8080' })); diff --git a/crop-x/src/router/index.tsx b/crop-x/src/router/index.tsx deleted file mode 100644 index b938def..0000000 --- a/crop-x/src/router/index.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { createBrowserRouter, RouterProvider, Navigate } from 'react-router-dom' -import { Layout } from '@/components/layout/Layout' -import { Login } from '@/pages/auth/Login' -import { Dashboard } from '@/pages/dashboard/Dashboard' - -// 模块路由 -import { machineryRoutes } from './modules/machinery' -import { landRoutes } from './modules/land' -import { operationRoutes } from './modules/operation' -import { assetRoutes } from './modules/asset' -import { aiModelRoutes } from './modules/ai-model' -import { irrigationRoutes } from './modules/irrigation' -import { configRoutes } from './modules/config' - -// 错误页面 -import { NotFound } from '@/pages/error/NotFound' -import { ServerError } from '@/pages/error/ServerError' - -export const router = createBrowserRouter([ - { - path: '/login', - element: , - errorElement: - }, - { - path: '/', - element: , - errorElement: , - children: [ - { - index: true, - element: - }, - { - path: 'dashboard', - element: - }, - ...machineryRoutes, - ...landRoutes, - ...operationRoutes, - ...assetRoutes, - ...aiModelRoutes, - ...irrigationRoutes, - ...configRoutes, - { - path: '*', - element: - } - ] - } -]) - -export const AppRouter = () => { - return -} \ No newline at end of file diff --git a/crop-x/src/router/modules/ai-model.tsx b/crop-x/src/router/modules/ai-model.tsx deleted file mode 100644 index b793822..0000000 --- a/crop-x/src/router/modules/ai-model.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { AIModelEntry } from '@/pages/ai-model/AIModelEntry' -import { ModelTraining } from '@/pages/ai-model/ModelTraining' -import { PredictionAnalysis } from '@/pages/ai-model/PredictionAnalysis' -import { RecommendationSystem } from '@/pages/ai-model/RecommendationSystem' - -export const aiModelRoutes = [ - { - path: 'ai-model', - children: [ - { - index: true, - element: - }, - { - path: 'model-training', - element: - }, - { - path: 'prediction-analysis', - element: - }, - { - path: 'recommendation-system', - element: - } - ] - } -] \ No newline at end of file diff --git a/crop-x/src/router/modules/asset.tsx b/crop-x/src/router/modules/asset.tsx deleted file mode 100644 index 2232fb2..0000000 --- a/crop-x/src/router/modules/asset.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { AssetEntry } from '@/pages/asset/AssetEntry' -import { InventoryManagement } from '@/pages/asset/InventoryManagement' -import { AssetDepreciation } from '@/pages/asset/AssetDepreciation' -import { MaintenanceRecords } from '@/pages/asset/MaintenanceRecords' - -export const assetRoutes = [ - { - path: 'asset', - children: [ - { - index: true, - element: - }, - { - path: 'inventory-management', - element: - }, - { - path: 'asset-depreciation', - element: - }, - { - path: 'maintenance-records', - element: - } - ] - } -] \ No newline at end of file diff --git a/crop-x/src/router/modules/config.tsx b/crop-x/src/router/modules/config.tsx deleted file mode 100644 index c3d406b..0000000 --- a/crop-x/src/router/modules/config.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { CentralConfigEntry } from '@/pages/config/CentralConfigEntry' -import { TenantManagement } from '@/pages/config/TenantManagement' -import { UserManagement } from '@/pages/config/UserManagement' -import { SystemParameters } from '@/pages/config/SystemParameters' -import { SystemMonitoring } from '@/pages/config/SystemMonitoring' -import { MessageCenter } from '@/pages/config/MessageCenter' - -export const configRoutes = [ - { - path: 'config', - children: [ - { - index: true, - element: - }, - { - path: 'tenant-management', - element: - }, - { - path: 'user-management', - element: - }, - { - path: 'system-parameters', - element: - }, - { - path: 'system-monitoring', - element: - }, - { - path: 'message-center', - element: - } - ] - } -] \ No newline at end of file diff --git a/crop-x/src/router/modules/irrigation.tsx b/crop-x/src/router/modules/irrigation.tsx deleted file mode 100644 index 8b7a70f..0000000 --- a/crop-x/src/router/modules/irrigation.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { IrrigationEntry } from '@/pages/irrigation/IrrigationEntry' -import { SystemControl } from '@/pages/irrigation/SystemControl' -import { MonitoringSystem } from '@/pages/irrigation/MonitoringSystem' -import { SchedulingSystem } from '@/pages/irrigation/SchedulingSystem' - -export const irrigationRoutes = [ - { - path: 'irrigation', - children: [ - { - index: true, - element: - }, - { - path: 'system-control', - element: - }, - { - path: 'monitoring-system', - element: - }, - { - path: 'scheduling-system', - element: - } - ] - } -] \ No newline at end of file diff --git a/crop-x/src/router/modules/land.tsx b/crop-x/src/router/modules/land.tsx deleted file mode 100644 index 3d694e4..0000000 --- a/crop-x/src/router/modules/land.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { LandEntry } from '@/pages/land/LandEntry' -import { LandArchiveManagement } from '@/pages/land/LandArchiveManagement' -import { LandClassification } from '@/pages/land/LandClassification' -import { MapManagement } from '@/pages/land/MapManagement' -import { SpatialAnalysis } from '@/pages/land/SpatialAnalysis' -import { SuitabilityEvaluation } from '@/pages/land/SuitabilityEvaluation' -import { ComparativeAnalysis } from '@/pages/land/ComparativeAnalysis' -import { RiskWarning } from '@/pages/land/RiskWarning' - -export const landRoutes = [ - { - path: 'land', - children: [ - { - index: true, - element: - }, - { - path: 'archive-management', - element: - }, - { - path: 'classification', - element: - }, - { - path: 'map-management', - element: - }, - { - path: 'spatial-analysis', - element: - }, - { - path: 'suitability-evaluation', - element: - }, - { - path: 'comparative-analysis', - element: - }, - { - path: 'risk-warning', - element: - } - ] - } -] \ No newline at end of file diff --git a/crop-x/src/router/modules/machinery.tsx b/crop-x/src/router/modules/machinery.tsx deleted file mode 100644 index 922d6c5..0000000 --- a/crop-x/src/router/modules/machinery.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { MachineryEntry } from '@/pages/machinery/MachineryEntry' -import { MachineryArchive } from '@/pages/machinery/MachineryArchive' -import { DriverArchive } from '@/pages/machinery/DriverArchive' -import { RealTimeMonitoring } from '@/pages/machinery/RealTimeMonitoring' -import { FaultDiagnosis } from '@/pages/machinery/FaultDiagnosis' -import { PrecisionFarming } from '@/pages/machinery/PrecisionFarming' -import { SchedulingManagement } from '@/pages/machinery/SchedulingManagement' - -export const machineryRoutes = [ - { - path: 'machinery', - children: [ - { - index: true, - element: - }, - { - path: 'archive', - element: - }, - { - path: 'driver-archive', - element: - }, - { - path: 'real-time-monitoring', - element: - }, - { - path: 'fault-diagnosis', - element: - }, - { - path: 'precision-farming', - element: - }, - { - path: 'scheduling-management', - element: - } - ] - } -] \ No newline at end of file diff --git a/crop-x/src/router/modules/operation.tsx b/crop-x/src/router/modules/operation.tsx deleted file mode 100644 index b0b8ad3..0000000 --- a/crop-x/src/router/modules/operation.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { FarmingEntry } from '@/pages/operation/FarmingEntry' -import { TaskPlanning } from '@/pages/operation/TaskPlanning' -import { TaskTracking } from '@/pages/operation/TaskTracking' -import { TaskAnalysis } from '@/pages/operation/TaskAnalysis' -import { ResourceManagement } from '@/pages/operation/ResourceManagement' -import { WorkflowManagement } from '@/pages/operation/WorkflowManagement' - -export const operationRoutes = [ - { - path: 'operation', - children: [ - { - index: true, - element: - }, - { - path: 'task-planning', - element: - }, - { - path: 'task-tracking', - element: - }, - { - path: 'task-analysis', - element: - }, - { - path: 'resource-management', - element: - }, - { - path: 'workflow-management', - element: - } - ] - } -] \ No newline at end of file diff --git a/crop-x/src/services/api/messageLogApi.ts b/crop-x/src/services/api/messageLogApi.ts deleted file mode 100644 index 09a4ba7..0000000 --- a/crop-x/src/services/api/messageLogApi.ts +++ /dev/null @@ -1,267 +0,0 @@ -import { MessageLog } from '@/types/message'; - -export interface MessageLogFilters { - searchKeyword?: string; - type?: string; - status?: string; - page?: number; - pageSize?: number; -} - -export interface MessageLogResponse { - data: MessageLog[]; - total: number; - page: number; - pageSize: number; -} - -/** - * 消息日志API服务 - * 提供消息日志相关的接口调用方法 - */ -class MessageLogApiService { - /** - * 获取消息日志列表 - * @param filters 过滤条件 - * @returns 消息日志列表数据 - */ - async getMessageLogs(filters: MessageLogFilters = {}): Promise { - // TODO: 替换为实际的API调用 - // const response = await fetch('/api/message-logs', { - // method: 'GET', - // headers: { - // 'Content-Type': 'application/json', - // }, - // body: JSON.stringify(filters), - // }); - // return response.json(); - - // 模拟API调用延迟 - await new Promise(resolve => setTimeout(resolve, 300)); - - // 从localStorage获取数据作为模拟数据 - const data = localStorage.getItem('smart_agriculture_message_logs'); - let logs: MessageLog[] = []; - - if (data) { - logs = JSON.parse(data); - } else { - // 初始化模拟数据 - logs = this.generateMockData(); - localStorage.setItem('smart_agriculture_message_logs', JSON.stringify(logs)); - } - - // 应用过滤条件 - let filteredLogs = logs.filter(log => { - const matchKeyword = !filters.searchKeyword || - (log.recipientName && log.recipientName.includes(filters.searchKeyword)) || - log.recipient.includes(filters.searchKeyword) || - log.content.includes(filters.searchKeyword); - const matchType = !filters.type || filters.type === 'all' || log.type === filters.type; - const matchStatus = !filters.status || filters.status === 'all' || log.status === filters.status; - return matchKeyword && matchType && matchStatus; - }); - - // 排序(按发送时间倒序) - filteredLogs.sort((a, b) => new Date(b.sentTime).getTime() - new Date(a.sentTime).getTime()); - - // 分页 - const page = filters.page || 1; - const pageSize = filters.pageSize || 20; - const startIndex = (page - 1) * pageSize; - const endIndex = startIndex + pageSize; - const paginatedLogs = filteredLogs.slice(startIndex, endIndex); - - return { - data: paginatedLogs, - total: filteredLogs.length, - page, - pageSize, - }; - } - - /** - * 导出消息日志 - * @param filters 过滤条件 - * @returns 导出文件 - */ - async exportMessageLogs(filters: MessageLogFilters = {}): Promise { - const response = await this.getMessageLogs(filters); - const dataStr = JSON.stringify(response.data, null, 2); - const dataBlob = new Blob([dataStr], { type: 'application/json' }); - const url = URL.createObjectURL(dataBlob); - const link = document.createElement('a'); - link.href = url; - link.download = `message_logs_${new Date().getTime()}.json`; - link.click(); - URL.revokeObjectURL(url); - } - - /** - * 批量标记消息为已读 - * @param ids 消息ID列表 - */ - async markMessagesAsRead(ids: string[]): Promise { - // TODO: 替换为实际的API调用 - // await fetch('/api/message-logs/mark-read', { - // method: 'POST', - // headers: { - // 'Content-Type': 'application/json', - // }, - // body: JSON.stringify({ ids }), - // }); - - // 模拟API调用 - await new Promise(resolve => setTimeout(resolve, 200)); - - // 更新本地数据 - const data = localStorage.getItem('smart_agriculture_message_logs'); - if (data) { - const logs: MessageLog[] = JSON.parse(data); - const updatedLogs = logs.map(log => - ids.includes(log.id) - ? { ...log, status: 'read' as const, readTime: new Date().toISOString() } - : log - ); - localStorage.setItem('smart_agriculture_message_logs', JSON.stringify(updatedLogs)); - } - } - - /** - * 删除消息日志 - * @param ids 消息ID列表 - */ - async deleteMessageLogs(ids: string[]): Promise { - // TODO: 替换为实际的API调用 - // await fetch('/api/message-logs', { - // method: 'DELETE', - // headers: { - // 'Content-Type': 'application/json', - // }, - // body: JSON.stringify({ ids }), - // }); - - // 模拟API调用 - await new Promise(resolve => setTimeout(resolve, 200)); - - // 更新本地数据 - const data = localStorage.getItem('smart_agriculture_message_logs'); - if (data) { - const logs: MessageLog[] = JSON.parse(data); - const updatedLogs = logs.filter(log => !ids.includes(log.id)); - localStorage.setItem('smart_agriculture_message_logs', JSON.stringify(updatedLogs)); - } - } - - /** - * 生成模拟数据 - * @returns 模拟消息日志数据 - */ - private generateMockData(): MessageLog[] { - const mockLogs: MessageLog[] = [ - { - id: 'msg-1', - templateId: 'tpl-1', - templateName: '任务分配通知', - type: 'internal', - recipient: 'user-2', - recipientName: '张三', - subject: '新任务分配', - content: '您好,张三!您有新的作业任务:小麦播种作业,计划执行时间:2024-10-15 08:00。请及时查看并准备。', - status: 'sent', - sentTime: '2024-10-14T09:30:00', - readTime: '2024-10-14T10:15:00', - retryCount: 0, - variables: { - username: '张三', - taskName: '小麦播种作业', - executeTime: '2024-10-15 08:00', - }, - }, - { - id: 'msg-2', - templateId: 'tpl-2', - templateName: '设备预警通知', - type: 'sms', - recipient: '13800138000', - recipientName: '李四', - content: '【智慧农业】设备预警:约翰迪尔拖拉机检测到异常,发动机温度过高,请及时处理。', - status: 'sent', - sentTime: '2024-10-14T11:20:00', - retryCount: 0, - }, - { - id: 'msg-3', - templateId: 'tpl-3', - templateName: '保养提醒', - type: 'email', - recipient: 'wangwu@example.com', - recipientName: '王五', - subject: '设备保养提醒', - content: '尊敬的用户:\n\n您的设备约翰迪尔拖拉机(编号:JD-001)已使用500小时,建议进行保养维护...', - status: 'sent', - sentTime: '2024-10-14T14:00:00', - retryCount: 0, - }, - { - id: 'msg-4', - templateId: 'tpl-4', - templateName: '任务完成通知', - type: 'push', - recipient: 'user-2', - recipientName: '张三', - subject: '任务完成', - content: '作业任务小麦播种作业已完成,作业面积:50亩,耗时:3小时。', - status: 'read', - sentTime: '2024-10-14T15:30:00', - readTime: '2024-10-14T15:32:00', - retryCount: 0, - }, - { - id: 'msg-5', - templateId: 'tpl-5', - templateName: '验证码通知', - type: 'sms', - recipient: '13900139000', - recipientName: '赵六', - subject: '验证码', - content: '【智慧农业】验证码:123456,有效期5分钟。', - status: 'failed', - sentTime: '2024-10-14T16:00:00', - failReason: '手机号码格式错误', - retryCount: 2, - }, - ]; - - // 添加更多模拟数据 - for (let i = 6; i <= 50; i++) { - const types: MessageLog['type'][] = ['sms', 'email', 'internal', 'push']; - const statuses: MessageLog['status'][] = ['sent', 'read', 'failed', 'pending']; - const type = types[Math.floor(Math.random() * types.length)]; - const status = statuses[Math.floor(Math.random() * statuses.length)]; - - mockLogs.push({ - id: `msg-${i}`, - templateId: `tpl-${Math.floor(Math.random() * 4) + 1}`, - templateName: `通知模板${Math.floor(Math.random() * 4) + 1}`, - type, - recipient: type === 'sms' ? `138${String(Math.floor(Math.random() * 100000000)).padStart(8, '0')}` : - type === 'email' ? `user${i}@example.com` : `user-${i}`, - recipientName: `用户${i}`, - subject: status === 'read' || status === 'sent' ? `通知主题${i}` : undefined, - content: `这是第${i}条测试消息内容,用于展示消息日志功能。`, - status, - sentTime: new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000).toISOString(), - readTime: status === 'read' ? new Date(Date.now() - Math.random() * 24 * 60 * 60 * 1000).toISOString() : undefined, - failReason: status === 'failed' ? '网络连接失败' : undefined, - retryCount: status === 'failed' ? Math.floor(Math.random() * 3) : 0, - variables: type === 'internal' ? { userId: `user-${i}` } : undefined, - }); - } - - return mockLogs; - } -} - -// 导出单例实例 -export const messageLogApi = new MessageLogApiService(); \ No newline at end of file