══════════════════════════════════════════════════════════
  项目云「删除接口」客户端对接文档
  2026-09-24 · 适用服务端 v1.5.1
══════════════════════════════════════════════════════════

一、接口总览
──────────────────────────────
删除接口是项目云 API 之一，与其他项目云接口共用同一套
鉴权方式(手机号 + 密码)。全部项目云接口：

  POST /api/proj/upload     上传项目 zip(覆盖式,≤2GB,每会员共 1GB)
  GET  /api/proj/list       列出该手机号名下全部项目
  GET  /api/proj/download    下载项目 zip
  POST /api/proj/delete     ★ 本文档：删除一个项目

项目云所有接口都有两种调用方式：
  · 方式 A：信封加密通道(推荐，与登录/注册同一套封装)
  · 方式 B：HTTPS 明文 JSON(与上传/下载同一套封装)

二、服务端实现说明(方式 B：HTTPS 明文)
──────────────────────────────
【请求】
  POST https://服务器IP:端口/api/proj/delete
  Content-Type: application/json

  请求体(JSON，UTF-8)：
  {
    "手机号": "13800001111",
    "密码":   "该会员的登录密码",
    "编号":   "要删除的项目编号"
  }

【服务端处理流程】
  1. 校验手机号+密码与 huiyuan.json 中会员记录匹配
     (不匹配 → {ok:false, msg:"手机号或密码错误"})
  2. 编号经文件名安全化后拼出项目目录，并做防路径穿越校验
     (拼接结果必须仍在 项目云 根目录之下)
  3. 直接递归删除该项目的整个目录(项目.zip + meta.json)
  4. 删除是不可恢复的物理删除

【响应】
  成功: {"ok": true}
  失败: {"ok": false, "msg": "失败原因"}
  常见失败：
    "手机号或密码错误"    鉴权失败
    "参数错误"            手机号或编号缺失
    "该接口已迁移至加密通道,请升级客户端并使用 https://IP:端口 连接"
                         用了 http:// (必须 https)

三、服务端实现说明(方式 A：信封加密通道 /api/enc)
──────────────────────────────
删除接口与项目列表一起，同时注册在加密通道内
(ENC_ROUTES)，客户端如果已经在用登录/注册的信封封装，
删除不需要单独再发明文请求，走同一封装即可。

【流程】
  1. GET https://服务器IP:端口/api/pubkey
     → {"ok":true, "pubkey":"RSA公钥PEM", "keyfp":"指纹"}
  2. 客户端随机生成 32 字节 AES-256 密钥 + 16 字节 IV
  3. 业务 JSON(下述 inner)用 AES-256-CBC 加密
  4. AES 密钥用 RSA-2048 OAEP(SHA-1) 封装
  5. POST /api/enc，请求体：
     {
       "k":    AES密钥的RSA-OAEP封装(base64),
       "iv":   AES IV(hex),
       "data": 密文(base64),
       "mac":  HMAC-SHA256(ts+'.'+nonce+'.'+iv+'.'+data) hex,
       "ts":   毫秒时间戳(±5分钟有效),
       "nonce":随机数(10分钟内不可重复)
     }
     其中密文解开后是 inner：
     { "path": "/api/proj/delete",
       "body": { "手机号":"...", "密码":"...", "编号":"..." } }
  6. 响应也是加密的：{"ok":true,"iv":..,"mac":..,"data":..}
     data 用同一 AES 密钥解开即 {"ok":true}

【注意】
  · /api/enc 只在 HTTPS 端口提供，http 端口一律返回
    TLS_REQUIRED 迁移提示
  · 防重放：同一 nonce 10 分钟内第二次提交会被拒绝
  · HMAC 校验失败 = 数据被篡改，服务端直接拒绝

四、端口与地址
──────────────────────────────
  · 客户端所有接口一律走 HTTPS：
    https://飞牛主机IP:HTTPS端口
  · HTTPS 端口 = 网页端口 + 1(默认网页 12701 → HTTPS 12702)
  · 证书是自签的，客户端需忽略证书校验
    (.NET: ServicePointManager.ServerCertificateValidationCallback
     返回 true；或比对 /api/pubkey 的 keyfp 指纹)
  · 手机号 11 位数字；密码即会员登录密码(与 /api/login 相同)

五、调用时序建议
──────────────────────────────
  1. (首次)GET /api/pubkey 取公钥与指纹，指纹可展示给
     用户核对，防中间人
  2. 客户端本地登录缓存手机号+密码(或调用 /api/login 验证)
  3. GET /api/proj/list 拿项目编号列表(编号即删除参数)
  4. 用户确认要删除后，POST /api/proj/delete 传编号
  5. 依返回 ok 刷新本地项目列表

六、删除的边界行为
──────────────────────────────
  · 删除的单位是"项目编号"：一个编号对应项目云里一个
    目录(项目.zip + meta.json)，整体删除
  · 编号不存在时不会报错，同样返回 {ok:true}(幂等)
  · 不提供批量删除参数，多个项目由客户端循环逐条调用
    (每条之间建议留 200ms 间隔，避免触发限速)
  · 登录/管理接口按 IP 限速(1 分钟内失败≥10 次锁 60 秒)，
    删除接口的鉴权失败不计入限速计数，无请求频率限制

七、明文调用示例(方式 B，C#)
──────────────────────────────
// 忽略自签证书
ServicePointManager.ServerCertificateValidationCallback =
    (s, cert, chain, err) => true;

var url = "https://192.168.1.10:12702/api/proj/delete";
var body = "{\"手机号\":\"13800001111\",\"密码\":\"123456\",\"编号\":\"XM20260924001\"}";
var req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/json";
var bytes = Encoding.UTF8.GetBytes(body);
using (var st = req.GetRequestStream()) st.Write(bytes, 0, bytes.Length);
try {
    using (var resp = (HttpWebResponse)req.GetResponse())
    using (var rs = new StreamReader(resp.GetResponseStream(), Encoding.UTF8)) {
        Console.WriteLine(rs.ReadToEnd());
        // 成功输出: {"ok":true}
    }
} catch (WebException ex) {
    using (var rs = new StreamReader(ex.Response.GetResponseStream(), Encoding.UTF8))
        Console.WriteLine(rs.ReadToEnd());   // {"ok":false,"msg":"..."}
}

八、错误码速查
──────────────────────────────
  {"ok":true}                       删除成功(含"项目本来就不存在")
  手机号或密码错误                   鉴权失败
  参数错误                          手机号或编号为空
  TLS_REQUIRED / 该接口已迁移…       用了 http，改 https
  时间戳超出允许窗口(±5分钟)        信封模式 ts 偏差过大，校时
  重复的请求(疑似抓包重放)           信封模式 nonce 重复

九、与原「客户端对接示例.cs」的关系
──────────────────────────────
  原示例文件(项目根目录 客户端对接示例.cs)覆盖登录/注册/
  信封加密的完整实现。本文档只补充"删除"这一个接口：
  两种调用方式与列表/上传/下载完全同构，把示例中已有的
  信封 path 换成 /api/proj/delete、body 换成
  {手机号,密码,编号} 即可，无任何新协议。
