feat: 新增存储路径自定义,修复s3存储未删除文件#246

This commit is contained in:
Lan
2025-02-08 22:41:32 +08:00
parent 7ca840cfa1
commit 964d091d0b
21 changed files with 52 additions and 43 deletions
+12 -5
View File
@@ -13,12 +13,19 @@ from core.utils import get_random_num, get_random_string, max_save_times_desc
async def get_file_path_name(file: UploadFile) -> Tuple[str, str, str, str, str]:
"""获取文件路径和文件名"""
today = datetime.datetime.now()
path = f"share/data/{today.strftime('%Y/%m/%d')}"
prefix, suffix = os.path.splitext(file.filename)
storage_path = settings.storage_path.strip('/') # 移除开头和结尾的斜杠
file_uuid = uuid.uuid4().hex
uuid_file_name = f"{file_uuid}{suffix}"
save_path = f"{path}/{uuid_file_name}"
return path, suffix, prefix, uuid_file_name, save_path
# 使用 UUID 作为子目录名
base_path = f"share/data/{today.strftime('%Y/%m/%d')}/{file_uuid}"
# 如果设置了存储路径,将其添加到基础路径中
path = f"{storage_path}/{base_path}" if storage_path else base_path
prefix, suffix = os.path.splitext(file.filename)
# 保持原始文件名
save_path = f"{path}/{file.filename}"
return path, suffix, prefix, file.filename, save_path
async def get_expire_info(expire_value: int, expire_style: str) -> Tuple[Optional[datetime.datetime], int, int, str]:
+1
View File
@@ -12,6 +12,7 @@ if not data_root.exists():
DEFAULT_CONFIG = {
'file_storage': 'local',
'storage_path': '',
'name': '文件快递柜 - FileCodeBox',
'description': '开箱即用的文件快传系统',
'notify_title': '系统通知',
+1
View File
@@ -16,6 +16,7 @@ from core.utils import get_now
async def delete_expire_files():
file_storage: FileStorageInterface = storages[settings.file_storage]()
print(settings.file_storage)
while True:
try:
# 遍历 share目录下的所有文件夹,删除空的文件夹,并判断父目录是否为空,如果为空也删除
+3 -3
View File
@@ -39,13 +39,13 @@ async def lifespan(app: FastAPI):
# 初始化数据库
await init_db()
# 启动后台任务
task = asyncio.create_task(delete_expire_files())
# 加载配置
await load_config()
app.mount('/assets', StaticFiles(directory=f'./{settings.themesSelect}/assets'), name="assets")
# 启动后台任务
task = asyncio.create_task(delete_expire_files())
try:
yield
finally:
@@ -1,4 +1,4 @@
import{c as i,B as k,r as h,o as u,I as v,d as x,e as t,n as o,g as e,i as w,f as n,X as _,F as M,q as C,p as z,y as B,J as L,m as D,K as F,t as I,z as d}from"./index-Dm7yhqOC.js";import{B as j}from"./box-D82IEWOS.js";/**
import{c as i,B as k,r as h,o as u,I as v,d as x,e as t,n as o,g as e,i as w,f as n,X as _,F as M,q as C,p as z,y as B,J as L,m as D,K as F,t as I,z as d}from"./index-Ch_yhQYc.js";import{B as j}from"./box-D_IdGY4o.js";/**
* @license lucide-vue-next v0.445.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as g,B as v,H as w,o as _,d as u,e as t,n as a,g as e,i as k,t as i,f as y,F as U,q as F,A as M,z as p,J as z,K as C}from"./index-Dm7yhqOC.js";import{F as m}from"./file-rOVCfWLN.js";import{H as D,T as S}from"./trash-CSx5DaSf.js";/**
import{c as g,B as v,H as w,o as _,d as u,e as t,n as a,g as e,i as k,t as i,f as y,F as U,q as F,A as M,z as p,J as z,K as C}from"./index-Ch_yhQYc.js";import{F as m}from"./file-CY1Cm1A5.js";import{H as D,T as S}from"./trash-Y8g6Hj4p.js";/**
* @license lucide-vue-next v0.445.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as V,B as T,u as q,r as _,b as k,d as c,e as t,n as o,g as a,i as A,j as P,f as m,v as H,m as I,F as v,q as w,t as d,A as S,z as g}from"./index-Dm7yhqOC.js";import{F as L}from"./file-rOVCfWLN.js";/**
import{c as V,B as T,u as q,r as _,b as k,d as c,e as t,n as o,g as a,i as A,j as P,f as m,v as H,m as I,F as v,q as w,t as d,A as S,z as g}from"./index-Ch_yhQYc.js";import{F as L}from"./file-CY1Cm1A5.js";/**
* @license lucide-vue-next v0.445.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1 +1 @@
import{G as y,r as u,B as v,u as b,d as w,e,n as l,g as o,i as x,f as h,h as k,j as S,v as A,m as V,t as B,y as D,z as j,A as P,_}from"./index-Dm7yhqOC.js";import{B as z}from"./box-D82IEWOS.js";const M=y("adminData",()=>{const d=u(localStorage.getItem("adminPassword")||"");function n(t){d.value=t,localStorage.setItem("token",t)}return{adminPassword:d,updateAdminPwd:n}}),I={class:"mx-auto h-16 w-16 relative"},L={class:"rounded-md shadow-sm -space-y-px"},N=["disabled"],T=v({__name:"LoginView",setup(d){const n=b(),t=u(""),i=u(!1),s=x("isDarkMode"),c=M(),p=()=>{let a=!0;return t.value?t.value.length<6&&(n.showAlert("密码长度至少为6位","error"),a=!1):(n.showAlert("无效的密码","error"),a=!1),a},m=D(),f=async()=>{if(p()){c.updateAdminPwd(t.value),P.post("/admin/login",{password:t.value}).then(()=>{m.push("/admin")}).catch(a=>{n.showAlert(a.response.data.detail,"error")}),i.value=!0;try{await new Promise(a=>setTimeout(a,2e3))}catch{}finally{i.value=!1}}};return(a,r)=>(j(),w("div",{class:l(["min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 transition-colors duration-200 relative overflow-hidden",o(s)?"bg-gray-900":"bg-gray-50"])},[r[6]||(r[6]=e("div",{class:"absolute inset-0 z-0"},[e("div",{class:"cyber-grid"}),e("div",{class:"floating-particles"})],-1)),e("div",{class:l(["max-w-md w-full space-y-8 backdrop-blur-lg bg-opacity-20 p-8 rounded-xl border border-opacity-20",[o(s)?"bg-gray-800 border-gray-600":"bg-white/70 border-gray-200"]])},[e("div",null,[e("div",I,[r[1]||(r[1]=e("div",{class:"absolute inset-0 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full animate-spin-slow"},null,-1)),r[2]||(r[2]=e("div",{class:"absolute -inset-2 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full opacity-50 blur-md animate-pulse"},null,-1)),e("div",{class:l(["absolute inset-1 rounded-full flex items-center justify-center",o(s)?"bg-gray-800":"bg-white"])},[h(o(z),{class:l(["h-8 w-8",o(s)?"text-cyan-400":"text-cyan-600"])},null,8,["class"])],2)]),e("h2",{class:l(["mt-6 text-center text-3xl font-extrabold",o(s)?"text-white":"text-gray-900"])}," 登录 ",2)]),e("form",{class:"mt-8 space-y-6",onSubmit:k(f,["prevent"])},[r[5]||(r[5]=e("input",{type:"hidden",name:"remember",value:"true"},null,-1)),e("div",L,[e("div",null,[r[3]||(r[3]=e("label",{for:"password",class:"sr-only"},"密码",-1)),S(e("input",{id:"password",name:"password",type:"password",autocomplete:"current-password",required:"","onUpdate:modelValue":r[0]||(r[0]=g=>t.value=g),class:l(["appearance-none rounded-t-md relative block w-full px-4 py-3 border transition-all duration-200 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-cyan-500 focus:z-10 sm:text-sm backdrop-blur-sm",o(s)?"bg-gray-800/50 border-gray-600 text-white placeholder-gray-400 hover:border-gray-500":"bg-white/50 border-gray-300 text-gray-900 hover:border-gray-400"]),placeholder:"密码"},null,2),[[A,t.value]])])]),e("div",null,[e("button",{type:"submit",class:l(["group relative w-full flex justify-center py-3 px-4 border border-transparent text-sm font-medium rounded-md text-white transition-all duration-300 transform hover:scale-[1.02] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-500 shadow-lg hover:shadow-cyan-500/50",o(s)?"bg-gradient-to-r from-cyan-500 to-purple-500 hover:from-cyan-600 hover:to-purple-600":"bg-gradient-to-r from-cyan-600 to-purple-600 hover:from-cyan-700 hover:to-purple-700",i.value?"opacity-75 cursor-not-allowed":""]),disabled:i.value},[r[4]||(r[4]=e("span",{class:"absolute left-0 inset-y-0 flex items-center pl-3"},null,-1)),V(" "+B(i.value?"登录中...":"登录"),1)],10,N)])],32)],2)],2))}}),E=_(T,[["__scopeId","data-v-2e50c3fa"]]);export{E as default};
import{G as y,r as u,B as v,u as b,d as w,e,n as l,g as o,i as x,f as h,h as k,j as S,v as A,m as V,t as B,y as D,z as j,A as P,_}from"./index-Ch_yhQYc.js";import{B as z}from"./box-D_IdGY4o.js";const M=y("adminData",()=>{const d=u(localStorage.getItem("adminPassword")||"");function n(t){d.value=t,localStorage.setItem("token",t)}return{adminPassword:d,updateAdminPwd:n}}),I={class:"mx-auto h-16 w-16 relative"},L={class:"rounded-md shadow-sm -space-y-px"},N=["disabled"],T=v({__name:"LoginView",setup(d){const n=b(),t=u(""),i=u(!1),s=x("isDarkMode"),c=M(),p=()=>{let a=!0;return t.value?t.value.length<6&&(n.showAlert("密码长度至少为6位","error"),a=!1):(n.showAlert("无效的密码","error"),a=!1),a},m=D(),f=async()=>{if(p()){c.updateAdminPwd(t.value),P.post("/admin/login",{password:t.value}).then(()=>{m.push("/admin")}).catch(a=>{n.showAlert(a.response.data.detail,"error")}),i.value=!0;try{await new Promise(a=>setTimeout(a,2e3))}catch{}finally{i.value=!1}}};return(a,r)=>(j(),w("div",{class:l(["min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 transition-colors duration-200 relative overflow-hidden",o(s)?"bg-gray-900":"bg-gray-50"])},[r[6]||(r[6]=e("div",{class:"absolute inset-0 z-0"},[e("div",{class:"cyber-grid"}),e("div",{class:"floating-particles"})],-1)),e("div",{class:l(["max-w-md w-full space-y-8 backdrop-blur-lg bg-opacity-20 p-8 rounded-xl border border-opacity-20",[o(s)?"bg-gray-800 border-gray-600":"bg-white/70 border-gray-200"]])},[e("div",null,[e("div",I,[r[1]||(r[1]=e("div",{class:"absolute inset-0 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full animate-spin-slow"},null,-1)),r[2]||(r[2]=e("div",{class:"absolute -inset-2 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full opacity-50 blur-md animate-pulse"},null,-1)),e("div",{class:l(["absolute inset-1 rounded-full flex items-center justify-center",o(s)?"bg-gray-800":"bg-white"])},[h(o(z),{class:l(["h-8 w-8",o(s)?"text-cyan-400":"text-cyan-600"])},null,8,["class"])],2)]),e("h2",{class:l(["mt-6 text-center text-3xl font-extrabold",o(s)?"text-white":"text-gray-900"])}," 登录 ",2)]),e("form",{class:"mt-8 space-y-6",onSubmit:k(f,["prevent"])},[r[5]||(r[5]=e("input",{type:"hidden",name:"remember",value:"true"},null,-1)),e("div",L,[e("div",null,[r[3]||(r[3]=e("label",{for:"password",class:"sr-only"},"密码",-1)),S(e("input",{id:"password",name:"password",type:"password",autocomplete:"current-password",required:"","onUpdate:modelValue":r[0]||(r[0]=g=>t.value=g),class:l(["appearance-none rounded-t-md relative block w-full px-4 py-3 border transition-all duration-200 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-cyan-500 focus:z-10 sm:text-sm backdrop-blur-sm",o(s)?"bg-gray-800/50 border-gray-600 text-white placeholder-gray-400 hover:border-gray-500":"bg-white/50 border-gray-300 text-gray-900 hover:border-gray-400"]),placeholder:"密码"},null,2),[[A,t.value]])])]),e("div",null,[e("button",{type:"submit",class:l(["group relative w-full flex justify-center py-3 px-4 border border-transparent text-sm font-medium rounded-md text-white transition-all duration-300 transform hover:scale-[1.02] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-500 shadow-lg hover:shadow-cyan-500/50",o(s)?"bg-gradient-to-r from-cyan-500 to-purple-500 hover:from-cyan-600 hover:to-purple-600":"bg-gradient-to-r from-cyan-600 to-purple-600 hover:from-cyan-700 hover:to-purple-700",i.value?"opacity-75 cursor-not-allowed":""]),disabled:i.value},[r[4]||(r[4]=e("span",{class:"absolute left-0 inset-y-0 flex items-center pl-3"},null,-1)),V(" "+B(i.value?"登录中...":"登录"),1)],10,N)])],32)],2)],2))}}),E=_(T,[["__scopeId","data-v-2e50c3fa"]]);export{E as default};
@@ -1,4 +1,4 @@
var qe=Object.defineProperty;var De=(d,e,t)=>e in d?qe(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var v=(d,e,t)=>De(d,typeof e!="symbol"?e+"":e,t);import{c as $e,_ as Pe,u as Fe,s as Ze,r as q,o as Ue,a as Oe,w as Qe,b as He,d as I,e as h,f as $,n as w,g as f,i as Ne,h as Ve,j as Ge,k as Y,v as We,t as D,l as O,m as Z,p as Xe,X as ge,T as Ke,F as Je,q as Ye,x as oe,y as et,z as C,A as tt}from"./index-Dm7yhqOC.js";import{c as Q,u as nt,S as st,C as it,a as rt,Q as ot,E as lt}from"./_commonjsHelpers-BCjwediS.js";import{B as at}from"./box-D82IEWOS.js";import{F as xe}from"./file-rOVCfWLN.js";import{H as ct,T as ut}from"./trash-CSx5DaSf.js";/**
var qe=Object.defineProperty;var De=(d,e,t)=>e in d?qe(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var v=(d,e,t)=>De(d,typeof e!="symbol"?e+"":e,t);import{c as $e,_ as Pe,u as Fe,s as Ze,r as q,o as Ue,a as Oe,w as Qe,b as He,d as I,e as h,f as $,n as w,g as f,i as Ne,h as Ve,j as Ge,k as Y,v as We,t as D,l as O,m as Z,p as Xe,X as ge,T as Ke,F as Je,q as Ye,x as oe,y as et,z as C,A as tt}from"./index-Ch_yhQYc.js";import{c as Q,u as nt,S as st,C as it,a as rt,Q as ot,E as lt}from"./_commonjsHelpers-Bz0FHX1E.js";import{B as at}from"./box-D_IdGY4o.js";import{F as xe}from"./file-CY1Cm1A5.js";import{H as ct,T as ut}from"./trash-Y8g6Hj4p.js";/**
* @license lucide-vue-next v0.445.0 - ISC
*
* This source code is licensed under the ISC license.
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.border-progress-container[data-v-2fbf5085]{position:relative;width:100%;height:100%}.border-progress-canvas[data-v-2fbf5085]{position:absolute;top:0;left:0;width:100%;height:100%;transition:all .3s ease}.fade-enter-active[data-v-f88861ef],.fade-leave-active[data-v-f88861ef]{transition:opacity .3s ease,transform .3s ease}.fade-enter-from[data-v-f88861ef],.fade-leave-to[data-v-f88861ef]{opacity:0;transform:translateY(10px)}@media (min-width: 640px){.sm\:w-120[data-v-f88861ef]{width:30rem}}.fade-enter-to[data-v-f88861ef],.fade-leave-from[data-v-f88861ef]{opacity:1;transform:translateY(0)}.drawer-enter-active[data-v-f88861ef],.drawer-leave-active[data-v-f88861ef]{transition:transform .3s ease}.drawer-enter-from[data-v-f88861ef],.drawer-leave-to[data-v-f88861ef]{transform:translate(100%)}.list-enter-active[data-v-f88861ef],.list-leave-active[data-v-f88861ef]{transition:all .5s ease}.list-enter-from[data-v-f88861ef],.list-leave-to[data-v-f88861ef]{opacity:0;transform:translate(30px)}
@@ -0,0 +1 @@
.border-progress-container[data-v-2fbf5085]{position:relative;width:100%;height:100%}.border-progress-canvas[data-v-2fbf5085]{position:absolute;top:0;left:0;width:100%;height:100%;transition:all .3s ease}.fade-enter-active[data-v-ce38a7bd],.fade-leave-active[data-v-ce38a7bd]{transition:opacity .3s ease,transform .3s ease}.fade-enter-from[data-v-ce38a7bd],.fade-leave-to[data-v-ce38a7bd]{opacity:0;transform:translateY(10px)}@media (min-width: 640px){.sm\:w-120[data-v-ce38a7bd]{width:30rem}}.fade-enter-to[data-v-ce38a7bd],.fade-leave-from[data-v-ce38a7bd]{opacity:1;transform:translateY(0)}.drawer-enter-active[data-v-ce38a7bd],.drawer-leave-active[data-v-ce38a7bd]{transition:transform .3s ease}.drawer-enter-from[data-v-ce38a7bd],.drawer-leave-to[data-v-ce38a7bd]{transform:translate(100%)}.list-enter-active[data-v-ce38a7bd],.list-leave-active[data-v-ce38a7bd]{transition:all .5s ease}.list-enter-from[data-v-ce38a7bd],.list-leave-to[data-v-ce38a7bd]{opacity:0;transform:translate(30px)}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
import{c as k,B as F,D as R,r as _,E as K,o as V,F as X,G as x,H as Y}from"./index-Dm7yhqOC.js";/**
import{c as k,B as F,D as R,r as _,E as K,o as V,F as X,G as x,H as Y}from"./index-Ch_yhQYc.js";/**
* @license lucide-vue-next v0.445.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as a}from"./index-Dm7yhqOC.js";/**
import{c as a}from"./index-Ch_yhQYc.js";/**
* @license lucide-vue-next v0.445.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as a}from"./index-Dm7yhqOC.js";/**
import{c as a}from"./index-Ch_yhQYc.js";/**
* @license lucide-vue-next v0.445.0 - ISC
*
* This source code is licensed under the ISC license.
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
import{c as a}from"./index-Dm7yhqOC.js";/**
import{c as a}from"./index-Ch_yhQYc.js";/**
* @license lucide-vue-next v0.445.0 - ISC
*
* This source code is licensed under the ISC license.
+1 -1
View File
@@ -11,7 +11,7 @@
<meta name="keywords" content="{{keywords}}" />
<meta name="generator" content="FileCodeBox2.2" />
<title>{{title}}</title>
<script type="module" crossorigin src="/assets/index-Dm7yhqOC.js"></script>
<script type="module" crossorigin src="/assets/index-Ch_yhQYc.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Bx419AMb.css">
</head>
<body>