12451 06765f99db feat: H5 用户端 Taro 重写 + 前后端接口对齐修复
- 使用 Taro + React 重写 H5 用户端(替换旧的 React+Vite+H5 实现)
- 6 个页面:登录、首页、设备列表、设备详情、仓体详情、个人中心
- Zustand 状态管理 + API 层封装 11 个接口
- 后端 H5 路由:新增仪表盘/项目/设备/充电控制接口,组织数据隔离
- 扫码入口:/h5/{abstract_id} → 免认证查设备 + 登录后跳转
- 管理端:新增绑定码管理、二维码展示下载、设备绑定/替换 IMEI
- 产品落地页更新(hero-bg + logo 替换)
- 接口对齐修复:修正 action 路径/请求体,DashboardData 和 CabinetItem 字段匹配后端
- 布局兼容性:grid → flex,提升移动浏览器兼容性
- 移除旧 H5 项目 software/h5/
2026-07-03 02:45:00 +08:00

71 lines
2.2 KiB
Rust

//! 统一错误处理
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::Json;
use serde_json::json;
/// 应用统一错误类型
#[derive(thiserror::Error, Debug)]
#[allow(dead_code)]
pub enum AppError {
#[error("数据库错误: {0}")]
Database(#[from] sqlx::Error),
#[error("Redis错误: {0}")]
Redis(#[from] redis::RedisError),
#[error("未找到: {0}")]
NotFound(String),
#[error("参数错误: {0}")]
BadRequest(String),
#[error("未授权: {0}")]
Unauthorized(String),
#[error("无权限: {0}")]
Forbidden(String),
#[error("请求过于频繁: {0}")]
TooManyRequests(String),
#[error("冲突: {0}")]
Conflict(String),
#[error("内部错误: {0}")]
Internal(String),
}
impl IntoResponse for AppError {
fn into_response(self) -> Response {
let (status, code, message) = match &self {
AppError::Database(e) => {
tracing::error!("数据库错误: {}", e);
(StatusCode::INTERNAL_SERVER_ERROR, "DATABASE_ERROR", "服务器内部错误")
}
AppError::Redis(e) => {
tracing::error!("Redis错误: {}", e);
(StatusCode::INTERNAL_SERVER_ERROR, "REDIS_ERROR", "缓存服务错误")
}
AppError::NotFound(msg) => (StatusCode::NOT_FOUND, "NOT_FOUND", msg.as_str()),
AppError::BadRequest(msg) => (StatusCode::BAD_REQUEST, "BAD_REQUEST", msg.as_str()),
AppError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, "UNAUTHORIZED", msg.as_str()),
AppError::Forbidden(msg) => (StatusCode::FORBIDDEN, "FORBIDDEN", msg.as_str()),
AppError::TooManyRequests(msg) => (StatusCode::TOO_MANY_REQUESTS, "TOO_MANY_REQUESTS", msg.as_str()),
AppError::Conflict(msg) => (StatusCode::CONFLICT, "CONFLICT", msg.as_str()),
AppError::Internal(msg) => {
tracing::error!("内部错误: {}", msg);
(StatusCode::INTERNAL_SERVER_ERROR, "INTERNAL_ERROR", "服务器内部错误")
}
};
let body = json!({
"code": code,
"message": message,
});
(status, Json(body)).into_response()
}
}