- 闇€姹傛枃妗e崌绾у埌 v0.5锛氳ˉ鍏呬簩缁寸爜娴锋姤淇濆瓨鏂囦欢鍚嶉粯璁ゆ牸寮忋€佸ぇ鏂囦欢涓婁紶涓夊眰闄愬埗锛圛IS+ASP.NET+鍓嶇锛夐儴缃茬害鏉熴€佹柊澧炵11绔犲紑鍙戣繘搴︾姸鎬佸綊妗o紙宸蹭笂绾垮姛鑳?宸蹭慨澶嶇己闄?宸茬煡闄愬埗/鍚庣画浼樺寲锛?- 鍚庣 FileController.Upload 澧炲姞 [RequestFormLimits(MultipartBodyLengthLimit=220_200_960)]锛屼慨澶?128MB multipart 涓婁紶琚嫆 - 鍓嶇 UploadView 浜岀淮鐮佹捣鎶ワ細淇 drawImage 缂╂斁閿欎綅銆侀《閮╨ogo/鏍囬鍨傜洿灞呬腑銆佸垎鍖烘爣棰橀棿璺濄€佸ぇ灏忎笌鏈夋晥鏈熷垎琛屾樉绀猴紱淇濆瓨鏂囦欢鍚嶆敼涓?鏂囦紶鏄撳彇浠剁爜-鍙栦欢鐮?鍘熸枃浠跺悕)-娴佹按鍙?png - 鏂板閮ㄧ讲鑴氭湰锛歛pply_backend.ps1 / force_dll.ps1锛坅pp_offline 瑙i攣DLL锛? ftp_fe.ps1 / ftp_diag.ps1 / ftp_apply.ps1 / _diag/check_dll.ps1 (閮ㄧ讲鎵嬪唽 IIS閮ㄧ讲涓嶧TP鍙戝竷.md 浠呭惈缂栫爜/BOM 宸紓锛屾湭绾冲叆鏈鎻愪氦)
387 lines
34 KiB
Markdown
387 lines
34 KiB
Markdown
# 文传易 · 需求文档
|
||
|
||
> **文档版本**:v0.5
|
||
> **创建日期**:2026-08-23
|
||
> **更新日期**:2026-08-24
|
||
> **文档状态**:已上线(前后端已实现、本地冒烟测试通过、已部署至正式站 `https://wenchuanyi.bbitcn.net`;累计修复:大文件上传 135MB 失败、二维码海报排版、保存文件名带原文件名)
|
||
> **技术栈**:.NET 8 + FreeSql + MySQL(后端)| Vue 3 + Vite + TypeScript + TDesign(前端)
|
||
> **正式站**:https://wenchuanyi.bbitcn.net(中文名「文传易」)
|
||
|
||
---
|
||
|
||
## 1. 项目概述
|
||
|
||
### 1.1 项目背景
|
||
「文传易」是一个匿名临时文件传输网站(类似文叔叔 / 奶牛快传 / tmp.link):
|
||
发送者无需注册登录即可上传文件,系统生成**取件凭证**;将凭证发给收件人后,收件人凭凭证即可下载文件。
|
||
适用于"想传文件给对方、但不想注册 / 登录 / 加好友"的场景。
|
||
|
||
### 1.2 项目目标
|
||
- 实现"上传 → 取件凭证 → 凭码下载"的完整闭环,全流程匿名、中文界面。
|
||
- 单文件传输,操作尽量简单:3 步完成(加入文件 → 上传 → 发码)。
|
||
- **二维码 + 取件码两种分享方式**:上传成功后生成二维码(内容为取件页链接,扫码自动进入下载页并填入取件码)——二维码发给新用户、取件码发给熟悉用户。
|
||
- 支持大段文字粘贴生成 txt 传递(**文件名 = 文字前 12 位 + 日期时间**);常见格式(文本/PDF/图片/音视频)支持在线预览与下载。
|
||
|
||
### 1.3 术语定义
|
||
| 术语 | 定义 |
|
||
| --- | --- |
|
||
| 发送者 | 上传文件的一方,匿名,不登录 |
|
||
| 收件人 | 凭取件凭证下载文件的一方,匿名,不登录 |
|
||
| 共享文件 | 不设密码/标签的文件类型,取件码为 **8 位纯数字** |
|
||
| 私密文件 | 设置 4-12 位密码的文件类型(**可同时设置标签**),取件码为 **6 位纯数字**,下载需校验密码 |
|
||
| 标签文件 | 设置标签的文件类型(**可同时设置密码**);**一个标签可关联多个文件**,输入标签后展示该标签下的文件列表;含标签的文件永久保存 |
|
||
| 取件码 | 上传成功后生成的下载凭证:共享文件 **8 位纯数字**、私密文件 **6 位纯数字**,输入时按位数实时识别(8 位 = 共享,6 位 = 私密) |
|
||
| 标签 | 标签文件的取件凭证,**仅允许英文(A-Za-z)与数字、不含任何符号**;纯数字须 >8 位(推荐 11 位手机号)、含英文字母须 >4 位;同一标签可关联多个文件,不要求唯一 |
|
||
| 管理码 | 发送者管理已上传文件的凭证,8 位字母数字;**不提供找回**,仅展示一次 |
|
||
| 有效期 | 文件可被下载的时间范围,**固定三档**:24 小时 / 7 天 / 永久 |
|
||
| 取件页链接 | 前端取件页地址,格式 `{BaseUrl}/#/pickup?code=xxx`,用于二维码/分享链接,扫码自动填入取件码 |
|
||
| 二维码 | 上传成功后前端本地生成的分享码,内容为取件页链接(仅含取件码、不含敏感信息),可下载/长按转发 |
|
||
|
||
---
|
||
|
||
## 2. 用户与角色
|
||
|
||
### 2.1 角色
|
||
| 角色 | 说明 | 是否登录 |
|
||
| --- | --- | --- |
|
||
| 发送者 | 上传文件、复制取件凭证/管理码、凭管理码管理 | 否(匿名) |
|
||
| 收件人 | 凭取件码/标签查询并下载文件 | 否(匿名) |
|
||
| 运维人员 | 部署 IIS、FTP 发布、配置数据库连接串与 OSS 凭据 | 系统后台 |
|
||
|
||
### 2.2 核心使用场景
|
||
1. **快速传文件**:同事/朋友间临时传文件,发送者上传后把**二维码**(新用户)或**取件码**(熟悉用户)通过微信/短信发给对方,对方扫码/输码下载。
|
||
2. **大段文字传递**:需要把一段很长的文字(如代码、会议纪要、账号信息)传给对方,直接粘贴文字生成 txt(文件名 = 文字前 12 位 + 日期时间)上传,对方在线阅读或下载。
|
||
3. **标签批量投递**:给同一对象传多个文件(如以手机号 `13800138000` 为标签),收件人输入该标签即可看到全部文件,逐个查看/下载。
|
||
4. **发送者管理**:想查看自己传过哪些文件、被下载几次(**仅统计、不限制**),或删除不再需要的文件,凭管理码操作。
|
||
|
||
---
|
||
|
||
## 3. 核心业务流程
|
||
|
||
### 3.1 发件流程(上传)
|
||
1. 发送者进入首页 → 通过任意方式加入文件:
|
||
- **拖拽**文件到上传区;
|
||
- **复制文件后 Ctrl+V 粘贴**上传;
|
||
- **点击选择**(打开文件夹直接选中文件);
|
||
- **粘贴一段文字** → 自动生成 .txt 文件上传,**文件名 = 文字前 12 位 + 日期时间**(`{文字前12位}_{yyyyMMdd_HHmmss}.txt`;剔除 `\/:*?"<>|` 等 Windows 非法文件名字符,剔除后为空用「文本」兜底),不提供自定义命名;
|
||
2. 选择有效期:**固定三档 24 小时 / 7 天 / 永久**(无自定义时长);
|
||
3. 按需设置**密码(4-12 位)**与**标签(仅英文+数字)**,**两者可同时设置、不互斥**;均不设置则默认为共享文件:
|
||
- **共享文件**:不设密码与标签 → **8 位数字取件码**;
|
||
- **私密文件**:设置密码(可同时设置标签)→ **6 位数字取件码**(下载需密码);
|
||
- **标签文件**:设置标签(可同时设置密码)→ **标签即取件凭证**,同一标签可关联多个文件;
|
||
- **含标签的文件有效期强制「永久」**(无论是否同时设置密码);
|
||
4. 点击上传 → 系统保存文件并生成取件凭证 + 管理码:
|
||
- 无密码无标签 → **8 位数字取件码**(共享文件);
|
||
- 设密码(可有标签)→ **6 位数字取件码**(私密文件,下载需密码);
|
||
- 仅设标签 → **标签即取件凭证**(标签文件,可关联多个文件,永久保存);
|
||
5. 页面展示凭证卡片:**二维码**(取件页链接,扫码直达下载页并自动填码,可下载/长按转发)+ 大号取件凭证 + 一键复制;下方可收起的管理码 + 复制;并提示"二维码发给新用户、取件码发给熟悉用户"。
|
||
|
||
### 3.2 取件流程(下载)
|
||
1. 收件人进入取件页 → 输入取件凭证(取件码或标签),或直接扫码(URL `?code=` 参数自动填入并查询);
|
||
2. 系统识别类型并校验:8 位纯数字 → 共享文件;6 位纯数字 → 私密文件(需输入密码);**满 7 位纯数字 → 提示"取件码为 6 位或 8 位,请继续输入完整取件码",不自动查询、等用户继续输入或修正**;非纯数字 → 按**标签**查询文件列表;
|
||
3. 校验通过后展示文件信息(名称、大小、剩余有效期)→ 【在线预览】【下载】;标签查询展示该标签下文件列表(按上传时间倒序),逐项【在线预览】【下载】【删除】(列表项为私密文件时,下载/预览需输入该文件密码)。
|
||
|
||
### 3.3 管理流程(发送者)
|
||
1. 输入管理码 → 查看该管理码下的文件列表(文件名、大小、过期时间、下载次数、**上传 IP**);
|
||
2. 可删除指定文件(删除后取件凭证立即失效);标签文件也可在取件页标签列表凭管理码删除。
|
||
|
||
---
|
||
|
||
## 4. 功能需求
|
||
|
||
> 优先级:P0 = 必须|P1 = 应当|P2 = 可选
|
||
|
||
### 4.1 上传功能
|
||
- [P0] 文件格式**不限制**;对可执行/脚本类文件(如 .exe/.bat/.sh/.dll)上传时展示"可执行文件风险提示"
|
||
- [P0] 多种方式加入文件:
|
||
- 拖拽文件到上传区(拖入高亮);
|
||
- 复制文件后 **Ctrl+V 粘贴**上传;
|
||
- 点击打开文件夹选择**单个**文件;
|
||
- **粘贴一段文字** → 自动生成 .txt 文件上传,**文件名 = 文字前 12 位 + 日期时间**(`{文字前12位}_{yyyyMMdd_HHmmss}.txt`;剔除 `\/:*?"<>|` 等 Windows 非法文件名字符,剔除后为空用「文本」兜底),**不提供自定义命名**
|
||
- [P0] 上传前展示文件名、大小;超限文件前端拦截并提示
|
||
- [P0] 有效期选择:**固定三档**——默认 **24 小时**,可选 **7 天 / 永久**(无自定义时长);**设置标签(无论是否同时设置密码)时强制「永久」**(隐藏有效期选择器)
|
||
- [P0] 文件模式(**密码与标签可同时设置、不互斥**,上传时按设置自动识别):
|
||
|
||
| 模式 | 触发条件 | 取件凭证 | 下载要求 |
|
||
| --- | --- | --- | --- |
|
||
| 共享文件 | 不设密码与标签 | **8 位数字取件码**(全局唯一) | 输入取件码即可下载 |
|
||
| 私密文件 | 设置 **4-12 位密码**(可同时设置标签) | **6 位数字取件码**(全局唯一) | 取件码 + 密码校验 |
|
||
| 标签文件 | 设置**标签**(仅英文+数字,可同时设置密码) | **标签即取件凭证**,同一标签可关联多个文件 | 输入标签 → 展示该标签下的文件列表(带密码项需密码) |
|
||
|
||
> **同时设置密码与标签**:按私密文件识别(6 位取件码,下载需密码),且因含标签强制永久保存(`IsPermanent=true`)。
|
||
|
||
- [P0] **密码与标签不互斥、可同时设置**:密码与标签为两个独立输入项,互不影响;同时设置时按私密文件(6 位取件码)识别,且因含标签有效期强制永久
|
||
- [P0] **标签规则**:仅允许英文(A-Za-z)与数字,不含任何符号(中划线/下划线/空格/汉字等均不允许);**纯数字须 >8 位**(≥9,推荐 11 位手机号,输入时提示"建议使用手机号码");**含英文字母须 >4 位**(≥5);前端实时校验并给出中文提示,后端同规则兜底(400 明确报错)
|
||
- [P0] 通过取件码位数识别文件类型:**8 位 = 共享文件,6 位 = 私密文件**;取件码全局不重复
|
||
- [P0] 上传成功返回:取件凭证(取件码或标签)+ 管理码(8 位字母数字)+ 文件信息
|
||
- [P0] **二维码分享**:上传成功后前端用 `qrcode` 库本地生成二维码(内容为取件页链接 `{BaseUrl}/#/pickup?code=xxx`,仅含取件码、不含敏感信息),与取件码同卡片展示,可下载/长按转发
|
||
- [P0] **二维码海报保存**:点击"保存二维码"时前端将成功卡片合成为一张 PNG 海报(含品牌条、下载方式、文件信息卡、取件码、二维码);**保存文件名默认格式**为 `文传易取件码-取件码(原文件名)-流水号.png`(原文件名清洗 Windows 非法字符 `\/:*?"<>|`,空名兜底「未命名」)
|
||
- [P0] 取件码 / 管理码一键复制
|
||
- [P1] 上传进度百分比展示
|
||
- [P2] 上传失败一键重试
|
||
|
||
### 4.2 取件下载功能(输入时实时识别)
|
||
- [P0] 取件凭证输入框**实时联动识别**(输入内容为纯数字时):
|
||
- 输入满 **6 位** → 识别为**私密文件**,显示【密码输入框】;密码输入满 **4 位**后显示【下载】按钮;
|
||
- 继续输入到 **7 位** → 显示提示"**取件码为 6 位或 8 位,请继续输入完整取件码**",不自动查询,等用户继续输入或修正;
|
||
- 输入满 **8 位** → 识别为**共享文件**,显示【下载】按钮;单击后加载文件信息并启动下载;
|
||
- [P0] 非纯数字输入(英文 / 数字混合)→ 按**标签**查询:输入标签后点击查询/回车,加载**该标签下的文件列表**(按上传时间倒序),逐项展示文件名/大小/上传时间,可对任一项【在线预览】【下载】【删除】(**列表项为私密文件(带密码)时,下载/预览需输入该文件密码**);无文件时提示"该标签下暂无文件"
|
||
- [P0] 私密文件下载必须校验密码,密码错误提示"密码错误"
|
||
- [P0] 凭码下载还原原始文件名(含中文/特殊字符);**下载次数仅统计、不限制**(`download_count` 只累加展示,不拦截下载)
|
||
- [P0] 已过期提示"文件已过期";凭证不存在提示"取件码/标签无效"
|
||
- [P0] **在线预览**(取件结果提供【在线预览】【下载】双操作,预览不计下载次数):
|
||
- 文本类(txt / md / xml / json 等)→ 在线直接阅读文字 + 下载,**上限 2MB**(超限仅提供下载);
|
||
- PDF → 在线阅读 + 下载;
|
||
- 图片类(jpg / png / gif / webp 等)→ 在线查看 + 下载,**上限 30MB**(超限提示"文件过大,请下载后查看");
|
||
- 音视频 → 在线播放 + 下载,**不设大小上限**(流式播放);**格式白名单**:视频 mp4(H.264/AAC,兼容性最佳)/ webm,音频 mp3 / wav / m4a / aac / ogg;非白名单格式前端提示下载查看
|
||
- [P1] 展示剩余有效期、文件大小
|
||
- [P1] 展示下载次数(仅统计)
|
||
|
||
### 4.3 发送者管理功能
|
||
- [P0] 凭管理码查看自己的文件列表(文件名/大小/过期时间/下载次数/**上传 IP**)
|
||
- [P0] 删除文件(需二次确认);标签文件删除在取件页标签列表凭管理码触发
|
||
- [P1] 展示下载次数(**仅统计不限制**)/ 剩余有效期 / 上传时间
|
||
|
||
### 4.4 过期与清理
|
||
- [P0] 过期文件自动清理(**OSS 对象 + 数据库记录**,先删记录再删 OSS 对象),取件凭证失效**即时生效**(查询/下载时懒检查)
|
||
- [P1] 后台定时任务兜底清理(每 30 分钟,仅扫描 `IsPermanent = false` 且已过期的记录;**含标签的文件永久保存、不参与自动过期**)
|
||
- [P0] **含标签的文件永久保存**:设置标签(无论是否同时设置密码)上传时有效期强制「永久」(前端隐藏有效期选择器,后端落库 `IsPermanent=true`、`ExpiresAt=null`),由上传者凭管理码主动删除
|
||
|
||
---
|
||
|
||
## 5. 非功能需求
|
||
|
||
### 5.1 性能
|
||
- 单文件大小上限:**200MB**(前端上传前拦截 + 服务端双重校验,Kestrel 请求上限 210MB 留余量)
|
||
- 大文件上传依赖三道限制**一致放开**,否则请求在到达应用前被拦(日志无记录):
|
||
1. **前端**:`axios` 配置 `maxContentLength` / `maxBodyLength` 放开(上传前另有 200MB 拦截提示);
|
||
2. **IIS 请求过滤**:站点 `web.config` 需含 `<security><requestFiltering><requestLimits maxAllowedContentLength="220200960"/></requestFiltering></security>`(~210MB;IIS 默认 30MB);
|
||
3. **ASP.NET Core multipart**:`FileController.Upload` 需同时有 `[RequestSizeLimit(220_200_960)]` 与 `[RequestFormLimits(MultipartBodyLengthLimit = 220_200_960)]`(multipart 默认 128MB,缺 `RequestFormLimits` 会拒 >128MB 上传)。
|
||
- 上传 / 下载全程流式 I/O,内存占用恒定,不整体读入内存
|
||
- 下载附带 `Content-Length` + `Accept-Ranges`,支持断点续传(`Range` 透传,OSS 原生支持 206)
|
||
- 表查询走唯一索引(PickCode / AdminCode)与普通索引(Tag);标签列表按 CreatedAt 倒序,limit 100 防大列表
|
||
|
||
### 5.2 安全
|
||
- 匿名性:全流程无需注册登录,无手机号/邮箱绑定
|
||
- **OSS 后端中转模式**:OSS AK/SK 仅存服务端 `appsettings.json`,前端始终只与后端 API 交互,不接触 OSS 凭据;对象键 `文传易2026/{yyyyMM}/{Guid}{ext}`,GUID 文件名杜绝重名与路径问题,原始文件名仅存数据库
|
||
- 取件码 / 管理码均全局唯一,取件码冲突自动重生成;**标签不唯一(一对多)**,同一标签可关联多个文件
|
||
- 管理码丢失**不提供找回**(只展示一次,UI 明确提示)
|
||
- 开放 API 的 `filePath` 入参必须位于配置白名单目录 `OpenApi:UploadRoot` 下(`Path.GetFullPath` 规范化后校验前缀,防路径穿越)
|
||
- 上传内容默认不做敏感/病毒扫描(如需可后续扩展)
|
||
- 文件格式不限制,但对可执行/脚本类文件(.exe/.bat/.sh/.dll 等)在上传与下载时展示"可执行文件风险提示",提醒谨慎运行
|
||
- 日志不打印 OSS 凭据与数据库密码明文
|
||
|
||
### 5.3 可用性
|
||
- 中文界面,核心操作 ≤3 步
|
||
- 所有错误均有友好提示(无效码 / 过期 / 文件不存在 / 网络错误 / 标签格式错误)
|
||
- **移动端优先**:桌面 + 手机浏览器均可用,手机端完整支持上传 / 取件 / 管理全流程
|
||
- **微信扫码可用**:正式站 `https://wenchuanyi.bbitcn.net` 有公网地址,手机微信扫码打开即可使用;**部署公网前先在本地跑通全流程测试**(浏览器自动化冒烟 + 局域网手机访问验证)
|
||
- **磁盘无需提醒**:本系统不实现磁盘空间监控与提醒功能
|
||
|
||
### 5.4 兼容性
|
||
- 浏览器:Chrome / Edge / Safari / **微信内置浏览器**(最新两个大版本)
|
||
- 微信内置浏览器中点击选择文件,可支持选择**微信聊天记录中的文件**(标准 `<input type="file">` 原生能力,真机验证)
|
||
- 前端构建目标保持 ES2018,兼容微信 X5 内核
|
||
- 不支持 IE
|
||
|
||
---
|
||
|
||
## 6. 技术方案
|
||
|
||
### 6.1 技术栈(已确认)
|
||
| 层 | 选型 |
|
||
| --- | --- |
|
||
| 后端 | ASP.NET Core Web API(.NET 8 LTS,支持 IIS 托管)+ FreeSql.Provider.MySql(CodeFirst 自动建表) |
|
||
| 数据库 | 远程 MySQL 8.x(`116.198.221.125:3306`,库 `wenchuanyi`,用户 `wenchuanyi`) |
|
||
| 文件存储 | 阿里云 OSS(`Aliyun.OSS` SDK,Endpoint `oss-cn-chengdu.aliyuncs.com`,Bucket `bbit-f8-web`,STSEndpoint 预留备用) |
|
||
| 前端 | Vue 3 + Vite + TypeScript + TDesign + Vue Router + Axios + Tailwind CSS + qrcode |
|
||
| 部署 | Windows Server + IIS 10 + .NET 8 Hosting Bundle;FTP 发布(`ftp://116.198.221.125`,用户 `wenchuanyi`) |
|
||
|
||
### 6.2 系统架构
|
||
```
|
||
Vue3 SPA ──REST/JSON──> ASP.NET Core Web API ──FreeSql──> 远程 MySQL(files 表)
|
||
│
|
||
├── 阿里云 OSS bbit-f8-web(对象键 文传易2026/{yyyyMM}/{Guid}{ext})
|
||
└── BackgroundService 定时清理过期文件(先删记录再删 OSS 对象)
|
||
```
|
||
- Controller:`FileController`(上传 / 查询 / 标签列表 / 预览 / 下载)、`AdminController`(管理列表 / 删除)、`OpenApiController`(公开接口)
|
||
- Service:`CodeGeneratorService`(取件码/管理码生成)、`OssStorageService`(OSS 对象键构造、流式上传/下载/删除)
|
||
- 后台任务:`ExpiredFileCleanerService`(每 30 分钟,仅扫 `IsPermanent = false` 的过期文件)
|
||
- 生产部署:前端构建产物与后端发布输出**同目录放置于 IIS 站点物理路径**(默认文件夹或 wwwroot);后端 `UseStaticFiles` + `MapFallbackToFile("index.html")` 实现 SPA 路由与 `/api` 共存
|
||
|
||
### 6.3 数据表设计(files 表,FreeSql CodeFirst 自动建表)
|
||
| 字段 | 类型 | 说明 |
|
||
| --- | --- | --- |
|
||
| Id | bigint 自增 | 主键 |
|
||
| PickCode | varchar(8) 唯一索引 | 取件码(共享 8 位 / 私密 6 位) |
|
||
| AdminCode | varchar(8) 唯一索引 | 管理码(8 位字母数字) |
|
||
| FileType | varchar(16) | 文件类型:standard(共享)/ private(私密)/ tagged(标签) |
|
||
| Password | varchar(12) 可空 | 私密文件密码(4-12 位);可与标签同时设置(不互斥) |
|
||
| Tag | varchar(64) 可空 普通索引(非唯一) | 标签(仅英文+数字),非空即为标签文件;可与密码同时设置(不互斥);同一标签可关联多个文件 |
|
||
| OriginalName | varchar(255) | 原始文件名(下载展示用) |
|
||
| ObjectKey | varchar(255) | OSS 对象键:文传易2026/{yyyyMM}/{Guid}{ext} |
|
||
| Size | bigint | 文件大小(字节) |
|
||
| MimeType | varchar(100) 可空 | Content-Type |
|
||
| DownloadCount | int 默认 0 | 下载次数(仅统计、不限制) |
|
||
| UploadIp | varchar(45) | 上传者 IP 地址(IPv4/IPv6,安全审计,仅管理列表可见,取件页不展示) |
|
||
| IsPermanent | bool | 是否永久保存(含标签的文件强制 true) |
|
||
| ExpiresAt | datetime 可空 | 过期时间(IsPermanent=true 时为 null) |
|
||
| CreatedAt | datetime | 上传时间 |
|
||
|
||
### 6.4 接口清单
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| POST | `/api/files/upload` | multipart 上传(file + expire + password + tag);**password 与 tag 可同时设置(不互斥)**、tag 格式校验(仅英文+数字、纯数字>8位/英文>4位)→ 返回取件凭证 + 管理码 + 文件信息(**自动记录上传者 IP**) |
|
||
| GET | `/api/files/{code}` | 查询文件信息(code 为取件码;私密文件需带密码校验;过期返回 410) |
|
||
| GET | `/api/files/by-tag/{tag}` | 按标签查询文件列表(按上传时间倒序;含标签均永久保存,仅返回未被删除记录;列表项带密码时下载/预览需密码) |
|
||
| GET | `/api/files/{code}/download` | 流式下载,下载计数 +1(仅统计不限制),还原原始文件名,支持 Range 断点续传(私密文件需密码) |
|
||
| GET | `/api/files/{code}/preview` | 在线预览:PDF/图片(≤30MB)/音视频(白名单 mp4/webm/mp3/wav/m4a/aac/ogg,不限大小)以 inline 流返回(私密文件需密码),不计下载次数 |
|
||
| GET | `/api/files/{code}/content` | 文本类文件(txt/md/xml/json 等,≤2MB)内容,供在线阅读渲染(私密文件需密码) |
|
||
| GET | `/api/admin/files/{adminCode}` | 管理码查询文件列表(含上传 IP) |
|
||
| DELETE | `/api/admin/files/{adminCode}` | 删除指定文件(body 传文件 id/取件码,校验管理码);取件页标签列表删除复用此接口 |
|
||
| POST | `/api/open/upload-public` | 公开:body `{ filePath, expiresHours }`(long 有效期小时数,0=永久,缺省 24)→ `{ pickCode, pickUrl, downloadUrl }` |
|
||
| POST | `/api/open/upload-price` | 公开:body `{ filePath, pwd }` → `{ pickCode, pickUrl, downloadUrl }`(下载需密码) |
|
||
| POST | `/api/open/upload-tag` | 公开:body `{ filePath, tag }` → `{ pickCode, pickUrl, downloadUrl }`(标签文件永久保存) |
|
||
| GET | `/api/open/download/{pickCode}` | 公开:返回 `{ downloadUrl, pickUrl, needPassword }`;共享/标签为直接下载 URL,私密跳取件页手动输密码 |
|
||
|
||
> 开放 API 说明:入参 `filePath` 为服务端文件路径,必须位于配置白名单目录 `OpenApi:UploadRoot` 下(`Path.GetFullPath` 规范化后校验前缀,防路径穿越);响应含识别码、`pickUrl`(前端取件页链接,带 `?code=` 参数,点击进入下载页)、`downloadUrl`。
|
||
|
||
---
|
||
|
||
## 7. 页面与交互设计
|
||
|
||
### 7.1 页面清单
|
||
| 页面 | 路由 | 内容 |
|
||
| --- | --- | --- |
|
||
| 上传页(首页) | `/` | 品牌区(Logo + 标语「文传易,免登录,传文件,真容易」+ 三步使用提示) + 上传区(拖拽 / Ctrl+V 粘贴文件 / 点击选择 / 粘贴文字生成「文字前12位+日期时间」txt)+ 有效期固定三档(24小时/7天/永久,含标签强制永久)+ 密码(4-12 位)与标签(实时校验)**两个独立输入项、可同时设置** + 结果卡片(**二维码** + 大号取件凭证 + 复制 + 可收起管理码) |
|
||
| 取件页 | `/pickup` | 取件凭证输入框(实时识别:6 位→密码框、7 位→提示继续输入、8 位→下载按钮;非纯数字→按标签查询;URL `?code=` 自动填充)+ 单文件结果卡片或标签文件列表 + 预览层(文本/PDF/图片/音视频) |
|
||
| 管理页 | `/admin` | 管理码输入框 + 文件列表表格(名称/大小/上传时间/过期时间/下载次数/**上传 IP**)+ 每行删除按钮(二次确认) |
|
||
|
||
### 7.2 视觉风格
|
||
- 现代简约 + 清爽科技感:蓝青渐变主色(`#2D6CFF` → `#00B4FF`),浅色底 + 大圆角白色卡片 + 柔和阴影
|
||
- 导航:桌面顶部固定导航栏,移动端**底部固定 Tab**(上传 / 取件 / 管理)
|
||
- 微动效:拖拽高亮、hover 上浮、复制成功 Toast、页面淡入、凭证识别平滑过渡
|
||
|
||
---
|
||
|
||
## 8. 异常与边界情况
|
||
| 场景 | 处理 |
|
||
| --- | --- |
|
||
| 取件凭证不存在 | 提示"取件码/标签无效" |
|
||
| 标签查询无结果 | 提示"该标签下暂无文件" |
|
||
| 输入到 7 位数字 | 提示"取件码为 6 位或 8 位,请继续输入完整取件码",不自动查询 |
|
||
| 标签含符号 / 汉字 | 前端实时提示"仅支持英文+数字",后端返回 400 |
|
||
| 标签为纯 6/8 位数字 | 已被"纯数字须 >8 位"规则规避(纯数字 ≥9 位,不会与 6/8 位取件码冲突) |
|
||
| 标签列表项为私密文件(带密码) | 下载/预览前需输入该文件密码,密码错误提示"密码错误" |
|
||
| 私密文件密码错误 | 提示"密码错误",不泄露文件信息 |
|
||
| 可执行/脚本类文件 | 上传与下载时展示"可执行文件风险提示" |
|
||
| 文本文件超 2MB / PDF/图片超 30MB | 不提供在线预览,仅提供下载(提示"文件过大,请下载后查看") |
|
||
| 音视频非白名单格式 | 不提供在线播放,提示下载查看 |
|
||
| 文件已过期 | 提示"文件已过期",并触发懒清理 |
|
||
| 文件超过大小上限(200MB) | 前端上传前拦截 + 服务端双重校验;若超过 IIS(30MB 默认)或 ASP.NET multipart(128MB 默认)限制,请求在到达应用前被拒(500.30/404.13/413,日志无记录),需按 §5.1 放开三层限制 |
|
||
| 上传中断 / 网络错误 | 前端提示并可重试 |
|
||
| OSS 写入/读取失败 | 记录日志,返回明确错误码 |
|
||
| 管理码错误 | 提示"管理码无效" |
|
||
| 下载时 OSS 对象已被清理 / 缺失 | 提示"文件已不存在" |
|
||
| 同一取件码被并发下载 | 下载计数原子自增,不丢失 |
|
||
|
||
---
|
||
|
||
## 9. 验收标准
|
||
1. 端到端流程:加入文件 → 上传 → 获得取件凭证 → 新会话输入凭证 → 下载成功,文件名与内容正确。
|
||
2. 三种文件模式端到端均可用:**共享文件**(输入 8 位取件码后显示下载按钮)、**私密文件**(输入 6 位后出现密码框,密码 4 位后显示下载按钮,密码错误无法下载)、**标签文件**(输入标签 → 展示该标签下文件列表 → 逐项预览/下载;同一标签可关联多个文件);**密码与标签可同时设置**(同时设置时按私密 6 位码识别,且强制永久保存)。
|
||
3. 取件码位数实时识别正确(6 位 → 私密,7 位 → 提示继续输入,8 位 → 共享);取件码全局不重复。
|
||
4. **二维码分享**:上传成功生成二维码,扫码打开取件页并自动填入取件码、直接查询到文件。
|
||
5. 在线预览:文本(≤2MB)/PDF/图片(≤30MB)可在线阅读查看、音视频(白名单格式)可在线播放,均可下载;超限/非白名单仅下载。
|
||
6. 多种上传方式可用:拖拽、Ctrl+V 粘贴文件、点击选择、粘贴文字生成「文字前 12 位 + 日期时间」txt。
|
||
7. 有效期固定三档(24小时/7天/永久);含标签的文件永久保存不自动过期;过期文件到期后无法下载且被自动清理(懒检查 + 定时任务)。
|
||
8. 管理码可查列表、可删除;删除后取件凭证立即失效;下载次数仅统计不限制;**上传自动记录上传者 IP(IPv4/IPv6,仅管理列表可见)**。
|
||
9. **标签规则**:仅英文+数字;纯数字 >8 位(推荐手机号)、含字母 >4 位;**密码与标签可同时设置(不互斥)**,前端提示 + 后端校验兜底。
|
||
10. 超过大小上限(200MB)的文件被正确拦截。
|
||
11. 手机浏览器与微信内置浏览器均可用;手机微信扫码可完成上传/取件,可选择微信聊天记录中的文件。
|
||
12. **部署**:本地全流程测试通过后,经 FTP 发布至 IIS 站点(`https://wenchuanyi.bbitcn.net`)访问正常。
|
||
13. 前后端代码可一键本地启动,数据库自动建表。
|
||
|
||
---
|
||
|
||
## 10. 里程碑与交付
|
||
| 阶段 | 内容 | 状态 |
|
||
| --- | --- | --- |
|
||
| M1 需求确认 | 本需求文档定稿、待确认问题全部拍板 | ✅ 已完成 |
|
||
| M2 开发 | 后端 API + 前端三页面 + 前后端联调 | ✅ 已完成 |
|
||
| M3 交付 | 本地测试通过、IIS+FTP 部署说明与脚本齐全 | ✅ 已完成 |
|
||
|
||
---
|
||
|
||
## 11. 开发进度状态(归档)
|
||
|
||
> 更新于:2026-08-24。以下为已上线功能与已修复缺陷的归档记录,便于后续迭代回溯。
|
||
|
||
### 11.1 已上线功能
|
||
- 完整匿名文件传输闭环:上传(拖拽 / Ctrl+V / 点击 / 粘贴文字生成 txt)→ 取件码/标签 → 取件下载。
|
||
- 三种文件模式:共享(8 位码)/ 私密(6 位码 + 密码)/ 标签(一对多、含标签强制永久)。
|
||
- 二维码分享 + 一键复制取件码/管理码;二维码海报保存(默认文件名 `文传易取件码-取件码(原文件名)-流水号.png`)。
|
||
- 在线预览:文本(≤2MB)/ PDF / 图片(≤30MB)/ 音视频(白名单格式,流式)。
|
||
- 发送者凭管理码查看列表、删除文件;管理列表展示上传 IP。
|
||
- 过期文件懒清理 + 后台定时任务(每 30 分钟)。
|
||
- 开放 API(public / price / tag)供外部系统直接生成取件链接。
|
||
- 已部署至正式站 `https://wenchuanyi.bbitcn.net`(IIS + .NET 8 + 阿里云 OSS 中转)。
|
||
|
||
### 11.2 已修复缺陷(2026-08-23 ~ 08-24)
|
||
| 日期 | 问题 | 根因 | 修复 |
|
||
| --- | --- | --- | --- |
|
||
| 08-23 | 135MB zip 上传失败 | 三层大小限制未全放开:①前端 axios 未放开;②IIS `web.config` 缺 `maxAllowedContentLength`(默认 30MB);③`FileController.Upload` 缺 `[RequestFormLimits]`(multipart 默认 128MB) | 前端放开 maxBodyLength;web.config 加 `maxAllowedContentLength=220200960`;Upload 加 `[RequestFormLimits(MultipartBodyLengthLimit=220_200_960)]` |
|
||
| 08-23 | 服务器 DLL 更新后仍跑旧版 | in-process 下 DLL 被 IIS 锁定,FTP 覆盖被 550;且**大小巧合相同(60416 字节)导致同步脚本按大小校验跳过上传** | 采用 `app_offline.htm` 方案:先放该文件触发 ANCM 优雅停止解锁 DLL → 覆盖 → 删除文件自动重启。脚本见 `deploy/apply_backend.ps1` / `deploy/force_dll.ps1` |
|
||
| 08-24 | 保存二维码海报"格式、文字错位"(底部大留白、二维码悬空) | 动态调高画布时 `drawImage(backup,0,0)` 未指定目标尺寸,浏览器按新高度缩放整张图 | `drawImage(backup,0,0,backup.width,backup.height)` 显式指定目标尺寸,仅裁剪底部空白 |
|
||
| 08-24 | 海报顶部 logo / 标题文字偏上 | canvas `textBaseline` 默认 `alphabetic`,文字顶贴品牌条顶 | 品牌条文字加 `textBaseline='middle'` 并按 logo 块中线定位 |
|
||
| 08-24 | 海报「下载方式/文件信息」小竖条贴住标题首字 | 竖条与文字间距仅 12px | 竖条 x 40→38、文字 x 62→66,间距扩至 24 |
|
||
| 08-24 | 海报「大小 / 有效期」挤在一行 | 单卡片内合并绘制 | 拆为「大小」一行 +「有效期」一行,卡片高度公式同步更新 |
|
||
| 08-24 | 保存二维码文件名不带原文件名 | 原文件名格式为 `文传易取件凭证_取件码.png` | 改为 `文传易取件码-取件码(原文件名)-流水号.png`,原文件名清洗非法字符 |
|
||
|
||
### 11.3 已知限制 / 注意事项
|
||
- **DLL 部署**:每次后端变更后必须核对服务器 DLL 是否真的更新(内容校验/时间戳),**不能只看大小**——大小可能巧合相同而漏传。
|
||
- **大文件配置**:IIS 与 ASP.NET 两道限制务必同步放开,否则 >128MB 上传会在应用外被拒且无日志。
|
||
- **微信内置浏览器**:支持扫码取件/下载;华为鸿蒙微信内置浏览器中上传文件 **可能无法直接读取微信聊天文件、且点击上传不弹系统选择器**(华为自带浏览器正常)。可引导用户改用系统浏览器或华为浏览器上传。
|
||
- **二维码海报**为前端 canvas 合成,依赖浏览器字体渲染;个别机型字体度量差异可能导致细微间距偏差。
|
||
|
||
### 11.4 待办 / 后续可优化
|
||
- 微信内置浏览器上传取件(聊天文件读取 + 系统选择器弹窗)的兼容性进一步增强。
|
||
- 多文件上传(下载打包 zip)。
|
||
- 下载次数限制(本期仅统计)。
|
||
- 网盘容量与配额管理、界面中英文切换、前端 STS 直传 OSS。
|
||
|
||
---
|
||
|
||
## 12. 未来扩展(可选,本期不实现)
|
||
- 多文件上传(下载打包 zip)
|
||
- 下载次数限制(本期仅统计不限制)
|
||
- 网盘容量与配额管理
|
||
- 界面中英文切换
|
||
- 前端 STS 直传 OSS(需提供 RAM RoleArn)
|
||
|
||
---
|
||
|
||
## 13. 待确认问题清单(已全部确认)
|
||
|
||
> ✅ = 已确认(已更新到对应章节)
|
||
|
||
1. **单文件大小上限**:200MB(前后端双重校验,Kestrel 请求上限留余量)。✅
|
||
2. **文件类型**:格式不限;可执行/脚本类文件(.exe/.bat/.sh/.dll)展示风险提示。✅
|
||
3. **标签为"一对多"**:同一标签可关联多个文件,标签不要求唯一。✅
|
||
4. **标签文件取件方式**:以标签为取件凭证,输入标签 → 展示该标签下文件列表 → 逐项预览/下载。✅
|
||
5. **有效期档位**:固定三档 24 小时 / 7 天 / 永久,无自定义时长。✅
|
||
6. **下载次数**:不限次,仅统计。✅
|
||
7. **部署与微信扫码**:有公网;正式站 `https://wenchuanyi.bbitcn.net`;服务端支持 IIS 部署,FTP 发包(`ftp://116.198.221.125`,默认端口 21,用户 `wenchuanyi`),文件放 IIS 站点默认文件夹或 `wwwroot`;**部署公网前先在本地测试**。✅
|
||
8. **磁盘策略**:无总容量上限、无单管理码文件数限制。✅
|
||
9. **运维告警**:磁盘空间无需提醒(不做磁盘监控/提醒功能)。✅
|
||
10. **密码与标签是否同时设置**:**不互斥、可同时设置**(同时设置时按私密文件识别 6 位取件码,且因含标签强制永久保存)。✅
|
||
11. **标签规则**:仅英文(A-Za-z)+ 数字、不含任何符号;纯数字须 >8 位(推荐 11 位手机号);含英文字母须 >4 位;大小写敏感(按原文存储匹配)。✅
|
||
12. **粘贴文字生成 txt 文件名**:**文字前 12 位 + 日期时间**(`{前12位}_{yyyyMMdd_HHmmss}.txt`,剔除 Windows 非法文件名字符,剔除后为空用「文本」兜底),不提供自定义。✅
|
||
13. **在线预览上限**:文本 2MB、PDF/图片 30MB、音视频不限大小(流式);超限仅下载。✅
|
||
14. **音视频预览格式**:仅浏览器原生播放格式——视频 mp4/webm,音频 mp3/wav/m4a/aac/ogg;不支持转码,非白名单提示下载。✅
|
||
15. **7 位数字输入的最终处理**:输入满 7 位时提示"取件码为 6 位或 8 位,请继续输入完整取件码",不自动查询,等用户继续输入或修正。✅
|
||
16. **品牌 Slogan**:**「文传易,免登录,传文件,真容易」**(上传页品牌区展示:Logo + 标语 + 三步使用提示)。✅
|
||
17. **私密文件密码长度**:**4-12 位**(≥4 且 ≤12,原 4-6 位扩展);前端校验 4-12 位,后端同规则兜底。✅
|
||
18. **标签为纯 6/8 位数字的冲突**:通过"纯数字标签须 >8 位(≥9)"规则规避,天然不与 6/8 位取件码冲突。✅
|
||
19. **记录上传者 IP**:上传(含开放 API)自动记录客户端 IP(IPv4/IPv6,`RemoteIpAddress`,varchar(45)),仅管理列表展示,取件页/公开接口不暴露;如后续引入反向代理需启用 `ForwardedHeaders`。✅
|