亮点 - 26.9 带宽限速(upload_rate/download_rate,字节/秒,0=不限速;管理端立即生效) - middleware/bandwidth.go 时间窗对齐 sleep 算法 + 单元测试(400KB@100KB/s 4.00s 精度) - 下载:serveFile 包裹 storage.ReadCloser(统一覆盖 local/webdav/s3 代理下载) - 上传:UploadBandwidthMiddleware 包裹 Request.Body(shareFile/chunk/presign proxy) - S3 预签名直传不可服务端限速——UI/文档明示 - 后台 SettingsView 增加 MB/s 友好输入;i18n zh-CN/en-US 双语 - 26.9 文档:新增 docs/api/13-bandwidth.md 专题;10-config 指针;00-overview changelog 与限流表带宽行;openapi.yaml 三处 schema + description 更新 - README.md / web/README.md / server/README.md / deploy/README.md 全部覆盖 品牌(26.9 收尾) - 文件快递柜 → 文件快传(前端/后端默认值/文档/产物/运行 KV) - 「复制取件码」按钮删除;取件码块点击即复制(保持原尺寸) - 「复制链接」→「复制链接和提取码」(一并复制链接和提取码) 产品修复(26.9) - 文本分享 Content-Type text/plain + urlencoded body:前端显式声明 urlencoded 头根治; 后端 bindJSONOrForm 兜底兼容 text/plain + JSON/urlencoded 嗅探 - Docker 部署文档校对到 26.9 现状(热切换 + 端口/卷/健康检查)
2 lines
2.1 KiB
JavaScript
2 lines
2.1 KiB
JavaScript
import{v as x,S as s,U as m,V as g,x as u,W as w,H as i,X as f,Y as h}from"./index-DSPQyv0Z.js";function T(n,t,r,a=""){return x(u.shareText,{method:"POST",form:{text:n,expire_value:String(t),expire_style:r,code:a}})}function y(n,t,r,a,o=""){const e=new FormData;return e.append("file",n),e.append("expire_value",String(t)),e.append("expire_style",r),o&&e.append("code",o),h(u.shareFile,e,a)}async function S(n){const t=await x(u.shareMetadata,{query:{code:n}}),r=!!(s(t,["is_text","isText"])??s(t,["type"])==="text");return{code:String(s(t,["code"])??n),name:String(s(t,["name"])??"未命名"),size:Number(s(t,["size"])??0),type:r?"text":"file",isText:r,createdAt:s(t,["created_at","createdAt"])??null,expiredAt:s(t,["expired_at","expires_at","expiredAt","expiresAt"])??null,expiredCount:s(t,["expired_count","expiredCount","remaining_downloads","remainingDownloads"])??null,usedCount:Number(s(t,["used_count","usedCount"])??0),remainingDownloads:s(t,["remaining_downloads","remainingDownloads","expired_count","expiredCount"])??null}}async function b(n){const{blob:t}=await m(u.shareSelect,{query:{code:n}});return t.text()}function A(n,t){return new Promise((r,a)=>{const o=new URL(g(u.shareSelect),location.origin);o.searchParams.set("code",n);const e=new XMLHttpRequest;e.open("GET",o.toString()),e.timeout=6e5,e.responseType="blob";const l=w();l&&e.setRequestHeader("Authorization",`Bearer ${l}`),e.onprogress=p=>{p.lengthComputable&&t&&t(Math.round(p.loaded/p.total*100))},e.onload=()=>{if((e.getResponseHeader("content-type")??"").includes("application/json")){const d=new FileReader;d.onload=()=>{try{const c=JSON.parse(String(d.result));a(new i(c.code??e.status,c.msg||"取件失败",e.status))}catch{a(new i(e.status,"取件失败",e.status))}},d.readAsText(e.response);return}e.status>=200&&e.status<300?r({blob:e.response,filename:f(e.getResponseHeader("content-disposition"))}):a(new i(e.status,`取件失败(HTTP ${e.status})`,e.status))},e.onerror=()=>a(new i(0,"网络异常,取件失败")),e.ontimeout=()=>a(new i(0,"下载超时,请重试")),e.send()})}export{y as a,A as b,S as g,b as p,T as s};
|