feat(plugin): P1-P4 审计修复 — 第一批 (Excel/CSV导出 + 市场API + 对账扫描)
1.1 Excel/CSV 导出:
- 后端 export 支持 format 参数 (json/csv/xlsx)
- rust_xlsxwriter 生成带样式 Excel
- 前端导出按钮改为 Dropdown 格式选择 (JSON/CSV/Excel)
- blob 下载支持 CSV/XLSX 二进制格式
1.2 市场后端 API + 前端对接:
- SeaORM Entity: market_entry, market_review
- API: 浏览/详情/一键安装/评论列表/提交评分
- 一键安装: upload → install → enable 一条龙 + 依赖检查
- 前端 PluginMarket 对接真实 API (搜索/分类/安装/评分)
1.3 对账扫描:
- reconcile_references() 扫描跨插件引用悬空 UUID
- POST /plugins/{plugin_id}/reconcile 端点
This commit is contained in:
@@ -178,10 +178,17 @@ pub struct ExportParams {
|
||||
pub sort_by: Option<String>,
|
||||
/// "asc" or "desc"
|
||||
pub sort_order: Option<String>,
|
||||
/// 导出格式: "csv" (默认) | "json"
|
||||
/// 导出格式: "json" (默认) | "csv" | "xlsx"
|
||||
pub format: Option<String>,
|
||||
}
|
||||
|
||||
/// 导出结果 — 根据格式返回不同内容
|
||||
pub enum ExportPayload {
|
||||
Json(Vec<serde_json::Value>),
|
||||
Csv(Vec<u8>),
|
||||
Xlsx(Vec<u8>),
|
||||
}
|
||||
|
||||
/// 数据导入请求
|
||||
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
|
||||
pub struct ImportReq {
|
||||
@@ -209,3 +216,92 @@ pub struct ImportRowError {
|
||||
/// 错误消息列表
|
||||
pub errors: Vec<String>,
|
||||
}
|
||||
|
||||
// ─── 市场目录 DTO ──────────────────────────────────────────────────
|
||||
|
||||
/// 市场条目列表查询参数
|
||||
#[derive(Debug, Serialize, Deserialize, utoipa::IntoParams)]
|
||||
pub struct MarketListParams {
|
||||
pub page: Option<u64>,
|
||||
pub page_size: Option<u64>,
|
||||
pub category: Option<String>,
|
||||
pub search: Option<String>,
|
||||
}
|
||||
|
||||
/// 市场条目响应(不含二进制数据)
|
||||
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
|
||||
pub struct MarketEntryResp {
|
||||
pub id: String,
|
||||
pub plugin_id: String,
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
pub description: Option<String>,
|
||||
pub author: Option<String>,
|
||||
pub category: Option<String>,
|
||||
pub tags: Option<serde_json::Value>,
|
||||
pub icon_url: Option<String>,
|
||||
pub screenshots: Option<serde_json::Value>,
|
||||
pub min_platform_version: Option<String>,
|
||||
pub status: String,
|
||||
pub download_count: i32,
|
||||
pub rating_avg: f64,
|
||||
pub rating_count: i32,
|
||||
pub changelog: Option<String>,
|
||||
pub created_at: Option<chrono::DateTime<chrono::Utc>>,
|
||||
pub updated_at: Option<chrono::DateTime<chrono::Utc>>,
|
||||
}
|
||||
|
||||
/// 市场条目详情响应(含完整信息)
|
||||
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
|
||||
pub struct MarketEntryDetailResp {
|
||||
#[serde(flatten)]
|
||||
pub entry: MarketEntryResp,
|
||||
/// 依赖提示(安装时检查 manifest.dependencies)
|
||||
pub dependency_warnings: Vec<String>,
|
||||
}
|
||||
|
||||
/// 提交评分/评论请求
|
||||
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
|
||||
pub struct SubmitReviewReq {
|
||||
/// 评分 1-5
|
||||
pub rating: i32,
|
||||
/// 评论内容
|
||||
pub review_text: Option<String>,
|
||||
}
|
||||
|
||||
/// 评论响应
|
||||
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
|
||||
pub struct MarketReviewResp {
|
||||
pub id: String,
|
||||
pub user_id: String,
|
||||
pub market_entry_id: String,
|
||||
pub rating: i32,
|
||||
pub review_text: Option<String>,
|
||||
pub created_at: Option<chrono::DateTime<chrono::Utc>>,
|
||||
}
|
||||
|
||||
// ─── 对账扫描 DTO ──────────────────────────────────────────────────
|
||||
|
||||
/// 对账报告
|
||||
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
|
||||
pub struct ReconciliationReport {
|
||||
/// 有效引用数
|
||||
pub valid_count: i64,
|
||||
/// 悬空引用数
|
||||
pub dangling_count: i64,
|
||||
/// 悬空引用详情
|
||||
pub details: Vec<DanglingRef>,
|
||||
}
|
||||
|
||||
/// 悬空引用详情
|
||||
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
|
||||
pub struct DanglingRef {
|
||||
/// 实体名
|
||||
pub entity: String,
|
||||
/// 字段名
|
||||
pub field: String,
|
||||
/// 记录 ID
|
||||
pub record_id: String,
|
||||
/// 悬空的 UUID 值
|
||||
pub dangling_value: String,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user