增加readme

This commit is contained in:
leo 2026-05-23 11:32:49 +08:00
parent df394ce81c
commit 676a12b46a
4 changed files with 709 additions and 222 deletions

325
README.md Normal file
View File

@ -0,0 +1,325 @@
# 空运宝 - 无人机物流供需匹配平台
无人机物流供需匹配平台,连接发货方与无人机运营方,实现同城即时配送。
---
## 目录
1. [项目概述](#1-项目概述)
2. [产品功能](#2-产品功能)
3. [技术路径](#3-技术路径)
4. [范围管理](#4-范围管理)
5. [WBS 工作分解](#5-wbs-工作分解)
6. [进度管理](#6-进度管理)
7. [项目结构](#7-项目结构)
8. [快速启动](#8-快速启动)
---
## 1. 项目概述
### 1.1 项目背景
传统同城物流存在时效长、成本高、信息不对称等问题。无人机物流作为低空经济的重要组成,正处于政策开放与市场爆发的窗口期。空运宝平台旨在降低无人机物流的使用门槛,让中小商户和个人用户能够便捷地使用无人机配送服务。
### 1.2 项目目标
| 目标 | 描述 |
|------|------|
| **MVP** | 完成供需双方核心交易闭环:发布需求 → 智能匹配 → 接单配送 → 完成交付 |
| **验证** | 通过原型验证产品概念与市场需求,收集种子用户反馈 |
| **扩展** | 为后续平台化、智能化演进奠定架构基础 |
### 1.3 项目范围
- **平台端**Web 单页应用,支持发货方和运营方两种角色
- **后端**RESTful API预留当前为离线 Mock 数据)
- **文档**:产品文档、商业计划书、项目管理文档
---
## 2. 产品功能
### 2.1 发货方
| 模块 | 功能 |
|------|------|
| 发货大厅 | 查看实时运力、我的订单列表、运营统计 |
| 发布需求 | 填写起运地/目的地、货物类型、重量、时效要求 |
| 匹配运力 | 查看多家供应商报价,比价下单 |
| 我的订单 | 查看所有订单状态、订单详情、确认收货 |
| 运力地图 | 基于 Leaflet 查看附近可用无人机 |
### 2.2 运营方
| 模块 | 功能 |
|------|------|
| 运营概览 | 今日订单、收入、飞行时长、评分等统计看板 |
| 任务大厅 | 查看待接订单,一键接单 |
| 订单管理 | 查看全部订单及状态 |
| 无人机管理 | 添加/移除无人机设备,查看设备状态 |
| 运力地图 | 地图可视化运力分布 |
| 收入明细 | 账户余额、收入记录、提现 |
---
## 3. 技术路径
### 3.1 架构演进路线
```mermaid
graph LR
subgraph T1年 MVP验证期
A1[HTML/CSS/JS<br>单页应用]
A2[Leaflet地图]
A3[Mock数据<br>离线运行]
end
subgraph T2-T3年 平台化期
B1[Vue3/React18<br>TypeScript]
B2[Go/Node.js<br>微服务]
B3[MySQL+Redis<br>+MongoDB]
B4[自研匹配引擎]
end
subgraph T4-T5年 智能化期
C1[强化学习<br>动态调度]
C2[LSTM<br>运力预测]
C3[多Agent<br>协同编排]
C4[垂域LLM<br>私有化部署]
end
A1 --> B1 --> C1
A2 --> B2 --> C2
A3 --> B3 --> C3
B4 --> C4
```
### 3.2 当前技术栈MVP
| 层级 | 技术选型 |
|------|---------|
| **前端** | 原生 HTML5 + CSS3 + JavaScript (ES6+) |
| **地图** | Leaflet 1.9.4 + CartoDB 深色底图 |
| **字体** | Google Fonts - Noto Sans SC |
| **部署** | 静态文件,浏览器直接打开 |
| **后端** | RESTful API 预留(可选) |
### 3.3 核心技术要点
- **单页应用架构**:通过原生 JS 实现客户端路由、状态管理、动态渲染
- **API 抽象层**:统一 `API.request()` 方法,支持后端/离线双模式
- **响应式适配**:支持桌面端与移动端布局
- **深色主题**CSS 变量驱动的暗色设计系统
---
## 4. 范围管理
### 4.1 产品范围
```mermaid
graph TB
subgraph 包含 In Scope
IS1[角色选择与登录]
IS2[发货方: 发布/匹配/追踪]
IS3[运营方: 接单/无人机管理/收入]
IS4[运力地图展示]
IS5[订单全生命周期管理]
end
subgraph 不包含 Out of Scope
OS1[在线支付系统]
OS2[用户注册/实名认证]
OS3[移动端App/小程序]
OS4[后台管理系统]
OS5[航线规划与空域审批]
end
subgraph 待定 TBD
TB1[评价体系]
TB2[消息推送]
TB3[数据统计看板]
end
```
### 4.2 功能清单
| 模块 | 优先级 | 状态 |
|------|--------|------|
| 角色选择(发货方/运营方) | P0 | ✅ 已完成 |
| 发货方 - 发货大厅 | P0 | ✅ 已完成 |
| 发货方 - 发布需求 | P0 | ✅ 已完成 |
| 发货方 - 匹配运力 | P0 | ✅ 已完成 |
| 发货方 - 我的订单 | P0 | ✅ 已完成 |
| 发货方 - 运力地图 | P1 | ✅ 已完成 |
| 运营方 - 运营概览 | P0 | ✅ 已完成 |
| 运营方 - 任务大厅 | P0 | ✅ 已完成 |
| 运营方 - 订单管理 | P0 | ✅ 已完成 |
| 运营方 - 无人机管理 | P0 | ✅ 已完成 |
| 运营方 - 运力地图 | P1 | ✅ 已完成 |
| 运营方 - 收入明细 | P1 | ✅ 已完成 |
| 添加无人机(弹窗表单) | P1 | ✅ 已完成 |
| 订单详情弹窗 | P1 | ✅ 已完成 |
| 匹配动画交互 | P1 | ✅ 已完成 |
| Toast 通知反馈 | P1 | ✅ 已完成 |
---
## 5. WBS 工作分解
### 5.1 项目工作分解结构
```mermaid
graph TD
P[空运宝平台] --> A[产品设计]
P --> B[前端开发]
P --> C[后端开发]
P --> D[测试与部署]
P --> E[项目管理]
A --> A1[需求分析]
A --> A2[原型设计]
A --> A3[UI设计]
A --> A4[产品文档]
B --> B1[项目脚手架]
B --> B2[登录/角色选择]
B --> B3[发货方模块]
B --> B3a[发货大厅]
B --> B3b[发布需求]
B --> B3c[匹配报价]
B --> B3d[我的订单]
B --> B4[运营方模块]
B --> B4a[运营概览]
B --> B4b[任务大厅]
B --> B4c[订单管理]
B --> B4d[无人机管理]
B --> B4e[收入明细]
B --> B5[通用组件]
B --> B5a[侧边导航]
B --> B5b[弹窗/Modal]
B --> B5c[地图组件]
B --> B5d[Toast通知]
B --> B6[地图集成]
C --> C1[API设计]
C --> C2[数据库设计]
C --> C3[认证模块]
C --> C4[业务接口]
D --> D1[功能测试]
D --> D2[兼容性测试]
D --> D3[部署上线]
E --> E1[进度管理]
E --> E2[文档管理]
E --> E3[代码管理]
```
### 5.2 工作包说明
| WBS 编号 | 工作包 | 负责人 | 产出物 |
|----------|--------|--------|--------|
| 1.1 | 需求分析 | PM | PRD 文档 |
| 1.2 | 原型设计 | Designer | 交互原型 |
| 1.3 | UI设计 | Designer | 设计稿 |
| 1.4 | 产品文档 | PM | 产品文档.md |
| 2.1 | 项目脚手架 | FE | index.html |
| 2.2 | 登录/角色选择 | FE | 角色选择页面 |
| 2.3 | 发货方模块 | FE | 发货方全套页面 |
| 2.4 | 运营方模块 | FE | 运营方全套页面 |
| 2.5 | 通用组件 | FE | 导航/弹窗/地图/Toast |
| 2.6 | 地图集成 | FE | Leaflet 地图实例 |
| 3.1 | API设计 | BE | API 接口文档 |
| 4.1 | 功能测试 | QA | 测试报告 |
| 5.1 | 进度管理 | PM | 甘特图/周报 |
---
## 6. 进度管理
### 6.1 里程碑计划
```mermaid
gantt
title 空运宝项目里程碑
dateFormat YYYY-MM-DD
axisFormat %m-%d
section 产品设计
需求分析与PRD :a1, 2026-05-01, 5d
原型与UI设计 :a2, after a1, 5d
产品文档编制 :a3, after a2, 3d
section 前端开发
项目脚手架与架构 :b1, after a2, 2d
角色选择与登录 :b2, after b1, 2d
发货方模块 :b3, after b2, 5d
运营方模块 :b4, after b3, 5d
通用组件与地图 :b5, after b4, 3d
联调与集成 :b6, after b5, 3d
section 后端开发
API设计与开发 :c1, after a1, 10d
section 测试部署
功能测试 :d1, after b6, 3d
兼容性测试 :d2, after d1, 2d
部署上线 :d3, after d2, 1d
```
### 6.2 关键里程碑
| 里程碑 | 时间 | 交付物 | 验收标准 |
|--------|------|--------|---------|
| M1 需求确认 | Day 5 | PRD 文档 | 需求评审通过 |
| M2 设计定稿 | Day 10 | UI 设计稿 | 设计评审通过 |
| M3 角色选择 | Day 14 | 登录页面 | 可切换两种角色进入 |
| M4 发货方MVP | Day 19 | 发货方功能 | 发布→匹配→下单全流程跑通 |
| M5 运营方MVP | Day 24 | 运营方功能 | 接单→配送→完成全流程跑通 |
| M6 集成测试 | Day 27 | 全功能版本 | 核心功能无阻塞 Bug |
| M7 上线交付 | Day 28 | 产品发布 | 所有 P0 功能通过验收 |
### 6.3 风险管理
| 风险 | 概率 | 影响 | 应对措施 |
|------|------|------|---------|
| 需求变更频繁 | 中 | 中 | 采用敏捷迭代,优先级管理 |
| 技术方案不成熟 | 低 | 高 | MVP 使用成熟技术栈验证 |
| 人员资源不足 | 中 | 中 | 明确优先级,确保核心功能 |
| 浏览器兼容性 | 低 | 低 | 使用标准 API主流浏览器测试 |
| 交付延期 | 中 | 高 | 预留缓冲时间,严格控制范围 |
---
## 7. 项目结构
```
lae-log/
├── README.md # 项目说明(本文件)
├── platform/
│ ├── index.html # 主应用入口2048 行单页应用)
│ └── docs/
│ ├── 产品文档.md # 产品需求与功能说明
│ └── 商业计划书.md # 商业模式与财务预测
```
---
## 8. 快速启动
```bash
# 1. 克隆仓库
git clone <repo-url>
cd lae-log
# 2. 直接在浏览器打开
start platform/index.html
```
**使用流程**
1. 打开页面,选择角色(发货方 / 运营方)
2. 发货方:发布需求 → 查看报价 → 下单 → 追踪配送
3. 运营方:查看任务大厅 → 接单 → 无人机管理 → 查看收入

View File

@ -40,20 +40,24 @@
## 三、页面结构
```
平台入口
├── 角色选择
│ ├── 发货方入口
│ │ ├── 发货大厅(首页)
│ │ ├── 发布需求
│ │ ├── 匹配运力
│ │ ├── 我的订单
│ │ └── 运力地图
│ └── 接单方入口
│ ├── 运营概览(首页)
│ ├── 运力地图
│ ├── 订单管理
│ └── 收入明细
```mermaid
graph TD
A[平台入口] --> B[角色选择]
B --> C[发货方]
B --> D[接单方]
C --> C1[发货大厅<br>首页]
C --> C2[发布需求]
C --> C3[匹配运力]
C --> C4[我的订单]
C --> C5[运力地图]
D --> D1[运营概览<br>首页]
D --> D2[运力地图]
D --> D3[任务大厅]
D --> D4[订单管理]
D --> D5[无人机管理]
D --> D6[收入明细]
```
---
@ -61,16 +65,14 @@
## 四、匹配机制
### 4.1 匹配流程
```
1. 用户发布运货需求
2. 系统根据距离、时效、机型筛选可用无人机
3. 向符合条件供应商推送订单
4. 供应商确认接单
5. 订单生效,开始配送
```mermaid
flowchart TD
A[用户发布运货需求] --> B[系统根据距离<br>时效、机型筛选可用无人机]
B --> C[向符合条件供应商推送订单]
C --> D{供应商是否接单}
D -->|是| E[订单生效<br>开始配送]
D -->|否| B
```
### 4.2 报价因素
@ -83,6 +85,21 @@
## 五、订单状态
```mermaid
stateDiagram-v2
[*] --> 待接单
待接单 --> 匹配中
待接单 --> 已取消
匹配中 --> 已接单
匹配中 --> 已取消
已接单 --> 配送中
已接单 --> 已取消
配送中 --> 已完成
配送中 --> 已取消
已完成 --> [*]
已取消 --> [*]
```
| 状态 | 说明 |
|------|------|
| 待接单 | 订单已发布,等待供应商接单 |

View File

@ -34,43 +34,50 @@
### 2.1 产品架构
```
┌─────────────────────────────┐
│ 接入层 │
│ Web端 | 小程序 | API │
└──────────────┬──────────────┘
┌──────────────┴──────────────┐
│ 业务中台 │
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │订单│ │匹配│ │支付│ │评价│ │
│ └───┘ └───┘ └───┘ └───┘ │
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │运力│ │航线│ │保险│ │用户│ │
│ └───┘ └───┘ └───┘ └───┘ │
└──────────────┬──────────────┘
┌──────────────┴──────────────┐
│ AI Agent 层 ★ │
│ ┌──────────────────────┐ │
│ │ 供应商托管Agent │ │
│ │ 智能匹配定价Agent │ │
│ │ 异常处理Agent │ │
│ │ 调度优化Agent │ │
│ └──────────────────────┘ │
└──────────────┬──────────────┘
┌──────────────┴──────────────┐
│ 技术中台 │
│ 匹配算法 | 地图引擎 │
│ 数据平台 | 监控系统 │
└──────────────┬──────────────┘
┌──────────────┴──────────────┐
│ 基础设施 │
│ 云计算 | 5G/物联网 │
│ 北斗定位 | 空域数据 │
└─────────────────────────────┘
```mermaid
graph TB
subgraph 接入层
A1[Web端]
A2[小程序]
A3[API]
end
subgraph 业务中台
B1[订单]
B2[匹配]
B3[支付]
B4[评价]
B5[运力]
B6[航线]
B7[保险]
B8[用户]
end
subgraph AI Agent 层 ★
C1[供应商托管Agent]
C2[智能匹配定价Agent]
C3[异常处理Agent]
C4[调度优化Agent]
end
subgraph 技术中台
D1[匹配算法]
D2[地图引擎]
D3[数据平台]
D4[监控系统]
end
subgraph 基础设施
E1[云计算]
E2[5G/物联网]
E3[北斗定位]
E4[空域数据]
end
接入层 --> 业务中台
业务中台 --> AI Agent 层 ★
AI Agent 层 ★ --> 技术中台
技术中台 --> 基础设施
```
### 2.2 技术路径规划
@ -405,25 +412,39 @@ T5年扩展15城日均订单50,000单客单价¥70抽佣15%
├── 设备故障Agent实时匹配备用运力自动生成用户赔偿方案
├── 安全事故Agent第一时间锁定事故区域同步推送处置团队与保险公司
└── 数据安全定期渗透测试Agent辅助审计异常访问行为
Agent异常处置流程 ★
┌─────────────────────────────────────────────────────┐
│ 1. 感知层 │
│ Agent持续接入气象API、无人机遥测、订单状态等多源数据 │
│ ↓ │
│ 2. 诊断层 │
│ 大模型推理引擎分析异常模式 → 分类定级(轻微/严重/紧急) │
│ ↓ │
│ 3. 决策层 │
│ 匹配预案库 → 生成处置建议 → 自动执行或推送人工确认 │
│ ↓ │
│ 4. 执行层 │
│ 调用业务API自动重调度/补偿/告警 → 全链路日志记录 │
│ ↓ │
│ 5. 学习层 │
│ 异常案例入库 → 微调Agent模型 → 持续提升处置准确率 │
└─────────────────────────────────────────────────────┘
```
```mermaid
flowchart TD
subgraph 感知层
A1[气象API]
A2[无人机遥测]
A3[订单状态]
end
subgraph 诊断层
B[大模型推理引擎<br>分析异常模式 → 分类定级]
end
subgraph 决策层
C[匹配预案库<br>生成处置建议<br>自动执行或推送人工确认]
end
subgraph 执行层
D[调用业务API<br>自动重调度/补偿/告警<br>全链路日志记录]
end
subgraph 学习层
E[异常案例入库<br>微调Agent模型<br>持续提升处置准确率]
end
A1 --> B
A2 --> B
A3 --> B
B --> C
C --> D
D --> E
```
---
@ -481,35 +502,36 @@ Agent异常处置流程 ★
### 8.1 Agent体系总体架构
```
┌──────────────────────────────────────┐
│ Agent 编排引擎 │
│ 任务分解 | 工作流编排 | 记忆管理 │
└──────────────┬───────────────────────┘
┌──────────────────────────────┼──────────────────────────────┐
│ ┌──────────────┴──────────────┐ │
│ │ 大模型推理层 │ │
│ │ GLM-4 / Qwen2.5 微调模型 │ │
│ │ 垂域知识增强 + RAG检索 │ │
│ └──────────────┬──────────────┘ │
│ │ │
▼ ▼ ▼ ▼
┌──────────────────┐ ┌──────────────────────┐ ┌──────────────────┐ ┌──────────────────────┐
│ 供应商托管Agent │ │ 智能匹配定价Agent │ │ 异常处理Agent │ │ 信誉评价Agent ★ │
├──────────────────┤ ├──────────────────────┤ ├──────────────────┤ ├──────────────────────┤
│ 设备健康巡检 │ │ 供需曲线实时分析 │ │ 多源数据感知 │ │ 多维度信誉评分 │
│ 运力状态同步 │ │ 动态调价策略 │ │ 故障诊断分级 │ │ AI反欺诈检测 │
│ 资质到期提醒 │ │ 订单分配优化 │ │ 处置方案生成 │ │ 评价真实性校验 │
│ 自动对账结算 │ │ 空载率预测干预 │ │ 自动补偿触发 │ │ 信用动态调整 │
└──────────────────┘ └──────────────────────┘ └──────────────────┘ └──────────────────────┘
│ │ │ │
└──────────────────────────────┼──────────────────────────────┼──────────────────────────────┘
┌──────────────┴──────────────┐
│ 执行与反馈层 │
│ API调用 | 消息推送 | 日志回放 │
└─────────────────────────────┘
```mermaid
graph TB
subgraph 编排层
O[Agent 编排引擎<br>任务分解 · 工作流编排 · 记忆管理]
end
subgraph 推理层
R[大模型推理层<br>GLM-4 / Qwen2.5 微调模型<br>垂域知识增强 + RAG检索]
end
subgraph Agent层
A1[供应商托管Agent<br>设备健康巡检<br>运力状态同步<br>资质到期提醒<br>自动对账结算]
A2[智能匹配定价Agent<br>供需曲线实时分析<br>动态调价策略<br>订单分配优化<br>空载率预测干预]
A3[异常处理Agent<br>多源数据感知<br>故障诊断分级<br>处置方案生成<br>自动补偿触发]
A4[信誉评价Agent ★<br>多维度信誉评分<br>AI反欺诈检测<br>评价真实性校验<br>信用动态调整]
end
subgraph 执行层
E[执行与反馈<br>API调用 · 消息推送 · 日志回放]
end
O --> R
R --> A1
R --> A2
R --> A3
R --> A4
A1 --> E
A2 --> E
A3 --> E
A4 --> E
```
### 8.2 供应商托管Agent
@ -642,31 +664,31 @@ Agent决策流程
#### AI反欺诈检测流程
```
评价提交
1. 规则引擎初筛
├── 账号画像:注册时长、历史行为模式、设备指纹
├── 时间异常:短时间内批量评价、非营业时段集中操作
└── 内容异常:相似文本模板、无意义字符
2. 大模型深层语义分析
├── 情感一致性:评价内容与订单体验是否匹配(如给了低分但评价文字称赞)
├── 文本复杂度:真实评价的词汇分布、句式结构符合自然语言分布
└── 对比建模:同一用户对不同订单的评价风格是否异常一致
3. 跨订单关联分析
├── 同IP/设备下的评价网络
├── 同收货地址的异常高频评价
└── 同运营商收到的好评率突变检测
4. 综合判定与处置
├── 正常评价 → 计入信誉分
├── 疑似刷单 → 标记观察,降权展示
└── 确认虚假 → 隐藏评价,扣减信誉分,限制账号权限
5. 持续进化
└── 误判案例回流入库 → 标注 → 微调Agent模型
```mermaid
flowchart TD
S[评价提交] --> A{规则引擎初筛}
A -->|账号画像| A1[注册时长、行为模式、设备指纹]
A -->|时间异常| A2[批量评价、非营业时段操作]
A -->|内容异常| A3[相似模板、无意义字符]
A --> B{大模型深层语义分析}
B -->|情感一致性| B1[评价内容与订单体验是否匹配]
B -->|文本复杂度| B2[词汇分布、句式符合自然语言]
B -->|对比建模| B3[同一用户评价风格异常一致]
B --> C{跨订单关联分析}
C -->|评价网络| C1[同IP/设备评价关联]
C -->|收货地址| C2[异常高频评价]
C -->|好评突变| C3[运营商好评率突变检测]
C --> D{综合判定与处置}
D -->|正常| D1[计入信誉分]
D -->|疑似| D2[标记观察、降权展示]
D -->|确认虚假| D3[隐藏评价、扣减信誉分、限制账号权限]
D3 --> E[误判案例回流入库 → 标注 → 微调Agent模型]
D2 --> E
```
#### 多维信誉评分模型

View File

@ -1084,9 +1084,6 @@
<div class="page" id="page-provider-dashboard">
<div class="page-header">
<h1 class="page-title">运营概览</h1>
<div class="page-actions">
<button class="btn btn-primary" onclick="showAddDroneModal()">+ 添加无人机</button>
</div>
</div>
<div class="stats-grid">
@ -1112,29 +1109,7 @@
</div>
</div>
<div class="panel">
<div class="panel-header">
<span class="panel-title">我的无人机</span>
<span style="color: #666; font-size: 13px;">共 4 架</span>
</div>
<div class="panel-body">
<div class="drone-grid" id="drone-list">
<!-- Drone cards -->
</div>
</div>
</div>
<div class="panel">
<div class="panel-header">
<span class="panel-title">待接订单</span>
<span style="color: #666; font-size: 13px;">5 单可接</span>
</div>
<div class="panel-body">
<div class="order-list" id="provider-orders">
<!-- Orders -->
</div>
</div>
</div>
</div>
<!-- Provider Orders -->
@ -1152,6 +1127,47 @@
</div>
</div>
<!-- Provider Task Hall -->
<div class="page" id="page-task-hall">
<div class="page-header">
<h1 class="page-title">任务大厅</h1>
</div>
<div class="panel">
<div class="panel-header">
<span class="panel-title">待接订单</span>
<span style="color: #666; font-size: 13px;" id="pending-count">0 单可接</span>
</div>
<div class="panel-body">
<div class="order-list" id="task-hall-orders">
<!-- Orders -->
</div>
</div>
</div>
</div>
<!-- Provider Drone Management -->
<div class="page" id="page-drone-management">
<div class="page-header">
<h1 class="page-title">无人机管理</h1>
<div class="page-actions">
<button class="btn btn-primary" onclick="showAddDroneModal()">+ 添加无人机</button>
</div>
</div>
<div class="panel">
<div class="panel-header">
<span class="panel-title">我的无人机</span>
<span style="color: #666; font-size: 13px;" id="drone-count">共 0 架</span>
</div>
<div class="panel-body">
<div class="drone-grid" id="drone-management-list">
<!-- Drone cards -->
</div>
</div>
</div>
</div>
<!-- Provider Earnings -->
<div class="page" id="page-provider-earnings">
<div class="page-header">
@ -1473,6 +1489,44 @@
<button class="btn btn-primary" id="order-action-btn" onclick="">确认收货</button>
</div>
</div>
</div>
<!-- Add Drone Modal -->
<div class="modal-overlay" id="add-drone-modal">
<div class="modal">
<div class="modal-header">
<span class="modal-title">添加无人机</span>
<button class="modal-close" onclick="closeModal('add-drone-modal')">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label">无人机名称</label>
<input type="text" class="form-input" placeholder="例如大疆M30T" id="drone-name-input">
</div>
<div class="form-group">
<label class="form-label">型号</label>
<input type="text" class="form-input" placeholder="例如:行业级" id="drone-model-input">
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">最大载重 (kg)</label>
<input type="number" class="form-input" placeholder="15" id="drone-weight-input">
</div>
<div class="form-group">
<label class="form-label">航程 (km)</label>
<input type="number" class="form-input" placeholder="10" id="drone-range-input">
</div>
</div>
<div class="form-group">
<label class="form-label">位置</label>
<input type="text" class="form-input" placeholder="例如:朝阳区望京" id="drone-location-input">
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" onclick="closeModal('add-drone-modal')">取消</button>
<button class="btn btn-primary" onclick="addDrone()">确认添加</button>
</div>
</div>
</div>
<!-- Toast -->
@ -1569,8 +1623,12 @@
{ id: 'dashboard', icon: '📊', label: '运营概览', page: 'page-provider-dashboard' },
{ id: 'map', icon: '🗺️', label: '运力地图', page: 'page-marketplace' },
]},
{ section: '订单', items: [
{ id: 'orders', icon: '📋', label: '订单管理', page: 'page-provider-orders' },
{ section: '任务', items: [
{ id: 'taskhall', icon: '📋', label: '任务大厅', page: 'page-task-hall' },
{ id: 'orders', icon: '📑', label: '订单管理', page: 'page-provider-orders' },
]},
{ section: '无人机', items: [
{ id: 'drones', icon: '🚁', label: '无人机管理', page: 'page-drone-management' },
]},
{ section: '财务', items: [
{ id: 'earnings', icon: '💰', label: '收入明细', page: 'page-provider-earnings' },
@ -1592,9 +1650,20 @@
];
// Functions
function loginAs(role) {
async function loginAs(role) {
currentRole = role;
currentUser = role === 'demander' ? { name: '王先生', type: 'demander' } : { name: '张师傅', type: 'provider' };
const phone = role === 'demander' ? '13800138001' : '13900139002';
const name = role === 'demander' ? '王先生' : '张师傅';
if (API.enabled) {
try {
currentUser = await API.login(phone, role);
} catch {
currentUser = { id: role === 'demander' ? 'U001' : 'U002', name, role, phone, avatar: name[0], company: role === 'demander' ? '星耀科技' : '飞驰无人机物流', credit_score: 850 };
}
} else {
currentUser = { id: role === 'demander' ? 'U001' : 'U002', name, role, phone, avatar: name[0], company: role === 'demander' ? '星耀科技' : '飞驰无人机物流', credit_score: 850 };
}
document.getElementById('landing-page').style.display = 'none';
document.getElementById('app-container').classList.add('active');
@ -1608,12 +1677,12 @@
const defaultPage = role === 'demander' ? 'page-demander-dashboard' : 'page-provider-dashboard';
showPage(defaultPage);
showToast('登录成功', 'success');
showToast('登录成功' + (API.enabled ? ' (后端已连接)' : ''), 'success');
if (role === 'provider') {
renderProviderContent();
await renderProviderContent();
} else {
renderDemanderContent();
await renderDemanderContent();
}
}
@ -1659,64 +1728,9 @@
}
function renderProviderContent() {
// Render drones
const droneContainer = document.getElementById('drone-list');
droneContainer.innerHTML = drones.map(drone => `
<div class="drone-card">
<div class="drone-header">
<div class="drone-icon">🚁</div>
<div>
<div class="drone-name">${drone.name}</div>
<div class="drone-model">${drone.model}</div>
</div>
</div>
<div class="drone-stats">
<div class="drone-stat">
<div class="drone-stat-label">载重</div>
<div class="drone-stat-value">${drone.maxWeight}kg</div>
</div>
<div class="drone-stat">
<div class="drone-stat-label">航程</div>
<div class="drone-stat-value">${drone.range}km</div>
</div>
<div class="drone-stat">
<div class="drone-stat-label">飞行次</div>
<div class="drone-stat-value">${drone.totalFlights}</div>
</div>
<div class="drone-stat">
<div class="drone-stat-label">位置</div>
<div class="drone-stat-value">${drone.location}</div>
</div>
</div>
<div class="drone-status-badge ${drone.status}">
<span class="drone-dot"></span>
${drone.status === 'available' ? '可接单' : drone.status === 'busy' ? '配送中' : '离线'}
</div>
</div>
`).join('');
// Render pending orders
renderProviderOrders();
renderProviderAllOrders();
}
function renderProviderOrders() {
const container = document.getElementById('provider-orders');
const pendingOrders = orders.filter(o => o.status === 'pending');
container.innerHTML = pendingOrders.map(order => `
<div class="order-item">
<div class="order-icon">📦</div>
<div class="order-info">
<div class="order-title">${order.id}</div>
<div class="order-route">${order.from} → ${order.to}</div>
</div>
<div class="order-meta">
<div class="order-price">¥${order.price}</div>
<button class="btn btn-primary" style="padding: 8px 16px;" onclick="acceptOrder('${order.id}')">接单</button>
</div>
</div>
`).join('');
renderTaskHallOrders();
renderDroneManagement();
}
function renderProviderAllOrders() {
@ -1849,6 +1863,115 @@
`).join('');
}
function renderTaskHallOrders() {
const container = document.getElementById('task-hall-orders');
const pendingOrders = orders.filter(o => o.status === 'pending');
document.getElementById('pending-count').textContent = pendingOrders.length + ' 单可接';
container.innerHTML = pendingOrders.map(order => `
<div class="order-item">
<div class="order-icon">📦</div>
<div class="order-info">
<div class="order-title">${order.id}</div>
<div class="order-route">${order.from} → ${order.to}</div>
</div>
<div class="order-meta">
<div class="order-price">¥${order.price}</div>
<button class="btn btn-primary" style="padding: 8px 16px;" onclick="acceptOrder('${order.id}')">接单</button>
</div>
</div>
`).join('');
}
function renderDroneManagement() {
const container = document.getElementById('drone-management-list');
document.getElementById('drone-count').textContent = '共 ' + drones.length + ' 架';
container.innerHTML = drones.map((drone, index) => `
<div class="drone-card">
<div class="drone-header">
<div class="drone-icon">🚁</div>
<div>
<div class="drone-name">${drone.name}</div>
<div class="drone-model">${drone.model}</div>
</div>
</div>
<div class="drone-stats">
<div class="drone-stat">
<div class="drone-stat-label">载重</div>
<div class="drone-stat-value">${drone.maxWeight}kg</div>
</div>
<div class="drone-stat">
<div class="drone-stat-label">航程</div>
<div class="drone-stat-value">${drone.range}km</div>
</div>
<div class="drone-stat">
<div class="drone-stat-label">飞行次</div>
<div class="drone-stat-value">${drone.totalFlights}</div>
</div>
<div class="drone-stat">
<div class="drone-stat-label">位置</div>
<div class="drone-stat-value">${drone.location}</div>
</div>
</div>
<div style="display: flex; justify-content: space-between; align-items: center;">
<div class="drone-status-badge ${drone.status}">
<span class="drone-dot"></span>
${drone.status === 'available' ? '可接单' : drone.status === 'busy' ? '配送中' : '离线'}
</div>
<button class="btn btn-secondary" style="padding: 6px 12px; font-size: 12px;" onclick="removeDrone(${index})">移除</button>
</div>
</div>
`).join('');
}
function showAddDroneModal() {
document.getElementById('drone-name-input').value = '';
document.getElementById('drone-model-input').value = '';
document.getElementById('drone-weight-input').value = '';
document.getElementById('drone-range-input').value = '';
document.getElementById('drone-location-input').value = '';
document.getElementById('add-drone-modal').classList.add('active');
}
function addDrone() {
const name = document.getElementById('drone-name-input').value.trim();
const model = document.getElementById('drone-model-input').value.trim();
const maxWeight = parseFloat(document.getElementById('drone-weight-input').value);
const range = parseFloat(document.getElementById('drone-range-input').value);
const location = document.getElementById('drone-location-input').value.trim();
if (!name || !model || !maxWeight || !range || !location) {
showToast('请填写完整信息', 'error');
return;
}
drones.push({
id: 'D' + String(drones.length + 1).padStart(3, '0'),
name: name,
model: model,
maxWeight: maxWeight,
range: range,
status: 'available',
totalFlights: 0,
location: location
});
closeModal('add-drone-modal');
showToast('无人机添加成功', 'success');
renderDroneManagement();
renderAvailableDrones();
renderSupplyList();
}
function removeDrone(index) {
drones.splice(index, 1);
showToast('无人机已移除', 'info');
renderDroneManagement();
renderAvailableDrones();
renderSupplyList();
}
function getStatusText(status) {
const map = {
pending: '待接单',