test/custom-admin-ui #3

Merged
orion merged 673 commits from test/custom-admin-ui into master 2026-06-05 17:20:58 +08:00
5 changed files with 174 additions and 32 deletions
Showing only changes of commit 165064f243 - Show all commits
+1 -1
View File
@@ -1,7 +1,7 @@
FROM python:3.9.5-slim-buster
LABEL author="Lan"
LABEL email="vast@tom.com"
LABEL version="1.5.9.2"
LABEL version="6"
COPY . /app
+1 -1
View File
@@ -68,7 +68,7 @@ async def init_models():
)
else:
# 从数据库更新缓存中的setting
await settings.update(await conn.execute(select(Options).filter()))
await settings.updates(await conn.execute(select(Options).filter()))
async def get_session():
+20 -4
View File
@@ -75,9 +75,15 @@ async def admin_post(page: int = Form(default=1), size: int = Form(default=10),
}}
# @app.patch(f'/{settings.ADMIN_ADDRESS}', dependencies=[Depends(admin_required)], description='修改数据库数据')
# async def admin_patch(request: Request, s: AsyncSession = Depends(get_session)):
# return {'detail': '修改成功'}
@app.patch(f'/{settings.ADMIN_ADDRESS}', dependencies=[Depends(admin_required)], description='修改数据库数据')
async def admin_patch(request: Request, s: AsyncSession = Depends(get_session)):
data = await request.json()
data.pop('INSTALL')
for key, value in data.items():
await s.execute(update(Options).where(Options.key == key).values(value=value))
await settings.update(key, value)
await s.commit()
return {'detail': '修改成功'}
@app.delete(f'/{settings.ADMIN_ADDRESS}', dependencies=[Depends(admin_required)], description='删除数据库记录')
@@ -98,7 +104,17 @@ async def admin_delete(code: str, s: AsyncSession = Depends(get_session)):
@app.get(f'/{settings.ADMIN_ADDRESS}/config', description='获取系统配置', dependencies=[Depends(admin_required)])
async def config(s: AsyncSession = Depends(get_session)):
return {'detail': '获取成功', 'data': (await s.execute(select(Options))).scalars().all()}
# 查询数据库
data = {}
for i in (await s.execute(select(Options))).scalars().all():
data[i.key] = i.value
return {'detail': '获取成功', 'data': data, 'menus': [
{'key': 'INSTALL', 'name': '版本信息'},
{'key': 'WEBSITE', 'name': '网站设置'},
{'key': 'SHARE', 'name': '分享设置'},
{'key': 'BANNERS', 'name': 'Banner'},
{'key': 'WEBSITE', 'name': '网站设置'},
]}
@app.get('/')
+8 -3
View File
@@ -61,11 +61,16 @@ class Settings:
'url': 'https://www.lanol.cn',
'src': '/static/banners/img_2.png'
}]
int_dict = {'PORT', 'MAX_DAYS', 'ERROR_COUNT', 'ERROR_MINUTE', 'UPLOAD_COUNT', 'UPLOAD_MINUTE',
'DELETE_EXPIRE_FILES_INTERVAL', 'FILE_SIZE_LIMIT'}
async def update(self, options) -> None:
async def update(self, key, value) -> None:
if hasattr(self, key):
setattr(self, key, int(value) if key in self.int_dict else value)
async def updates(self, options) -> None:
for i, key, value in options:
if hasattr(self, key):
setattr(self, key, value)
await self.update(key, value)
settings = Settings()
+144 -23
View File
@@ -22,6 +22,34 @@
body {
background: #f5f5f5;
}
@media (prefers-color-scheme: dark) {
body {
background-color: #18181c;
}
.el-card, .el-textarea__inner, .el-upload-dragger {
border-radius: 20px;
border: 1px solid transparent;
background-color: rgba(255, 255, 255, 0.1);
box-shadow: 5px 5px 0 0 rgba(0, 0, 0, 0.2);
}
#app * {
color: #ccc !important;
}
.el-input-group__prepend, .el-menu, .btn-prev, .el-input__inner, .el-input-group__append, .el-empty__description, .el-select-dropdown, .el-button {
border: 1px solid transparent;
background-color: rgba(0, 0, 0, 0.2);
}
.el-drawer, #el-drawer__title, .el-drawer__body, .el-drawer__wrapper {
background-color: rgba(0, 0, 0, 0.5);
border: 1px solid transparent;
}
}
</style>
</head>
<body>
@@ -29,8 +57,9 @@
<el-row v-if="login" :gutter="10">
<el-col :span="24" style="text-align: center">
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
<el-menu-item index="2">文件管理</el-menu-item>
<el-menu-item index="3">系统配置</el-menu-item>
<el-menu-item index="2">分享文件管理</el-menu-item>
<el-menu-item index="3">本地文件列表</el-menu-item>
<el-menu-item index="4">系统配置</el-menu-item>
</el-menu>
</el-col>
<el-col v-if="activeIndex === '2'">
@@ -72,24 +101,113 @@
>
</el-pagination>
</el-col>
<el-col v-if="activeIndex === '3'">
<el-form ref="form" style="width: 50%;margin:2rem auto" :model="config" label-width="200px"><el-form-item v-for="(banner,index) in config.banners" :label="'Banner'+ (index+1)">
<div style="width: 50%;display: inline-block">
<el-input v-model="banner.text" placeholder="文本"></el-input>
<el-input v-model="banner.url" placeholder="跳转链接"></el-input>
<el-input v-model="banner.src" placeholder="图片路径"></el-input>
</div>
<div style="display: inline-block">
<el-button type="danger" @click="deleteBanner(index)">删除</el-button>
</div>
</el-form-item>
<el-form-item>
<el-button size="mini" @click="addBanner" type="primary">新增Banner</el-button>
</el-form-item>
<el-form-item>
<el-button @click="updateConfig" type="primary">更新</el-button>
</el-form-item>
</el-form>
<el-col v-if="activeIndex === '4'">
<el-row>
<el-col :span="5" style="height: 88vh;overflow: scroll" :gutter="10">
<el-card v-for="menu in menus" :key="menu.key">
<div style="cursor: pointer;" @click="updateTab=menu.key">${menu.name}</div>
</el-card>
</el-col>
<el-col :span="19">
<el-card style="height: 88vh;overflow: scroll">
<div v-if="updateTab=='INSTALL'">
<div>
<h1>FileCodeBox V${config.INSTALL}</h1>
<h2>Github<a target="_blank"
href="https://github.com/vastsa/FileCodeBox">FileCodeBox</a></h2>
</div>
</div>
<div v-else-if="updateTab=='BANNERS'">
<el-form ref="form" style="margin:1rem auto" :model="config" label-width="200px">
<el-form-item v-for="(banner,index) in config.BANNERS" :label="'Banner'+ (index+1)">
<div style="display: inline-block">
<el-input v-model="banner.text" placeholder="文本"></el-input>
<el-input v-model="banner.url" placeholder="跳转链接"></el-input>
<el-input v-model="banner.src" placeholder="图片路径"></el-input>
</div>
<div style="display: inline-block">
<el-button type="danger" @click="deleteBanner(index)">删除</el-button>
</div>
</el-form-item>
<el-form-item>
<el-button size="mini" @click="addBanner" type="primary">新增Banner</el-button>
</el-form-item>
<el-form-item>
<el-button @click="updateConfig" type="primary">更新</el-button>
</el-form-item>
</el-form>
</div>
<div v-else-if="updateTab=='WEBSITE'">
<el-form ref="form" style="margin:1rem auto" :model="config" label-width="200px">
<el-form-item>
<el-alert
title="当前页面信息修改后需要手动重启系统"
type="warning">
</el-alert>
</el-form-item>
<el-form-item label="网站名称">
<el-input v-model="config.TITLE" placeholder="网站名称"></el-input>
</el-form-item>
<el-form-item label="网站描述">
<el-input v-model="config.DESCRIPTION" placeholder="网站描述"></el-input>
</el-form-item>
<el-form-item label="网站关键词">
<el-input v-model="config.KEYWORDS" placeholder="网站关键词"></el-input>
</el-form-item>
<el-form-item label="存储引擎">
<el-input v-model="config.STORAGE_ENGINE" placeholder="存储引擎"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="updateConfig" type="primary">更新</el-button>
</el-form-item>
</el-form>
</div>
<div v-else-if="updateTab=='SHARE'">
<el-form ref="form" style="margin:1rem auto" :model="config" label-width="200px">
<el-form-item label="开启上传">
<el-input v-model="config.ENABLE_UPLOAD" placeholder="开启上传"></el-input>
</el-form-item>
<el-form-item label="最长天数">
<el-input v-model="config.MAX_DAYS" placeholder="最长允许保留多少天"></el-input>
</el-form-item>
<el-form-item label="删除过期间隔">
<el-input v-model="config.DELETE_EXPIRE_FILES_INTERVAL"
placeholder="删除过期文件的间隔(分钟)"></el-input>
</el-form-item>
<el-form-item label="上传大小限制">
<small>单位:bit),1mb=1 * 1024 * 1024</small>
<el-input v-model="config.FILE_SIZE_LIMIT"
placeholder="上传大小限制(bit"></el-input>
</el-form-item>
<el-form-item>
<el-alert
title="下列信息修改后需要手动重启系统"
type="warning">
</el-alert>
</el-form-item>
<el-form-item label="口令错误限制">
<small>每几分钟</small>
<el-input v-model="config.ERROR_MINUTE"
placeholder="错误次数过多后限制时间"></el-input>
<small>允许错误几次</small>
<el-input v-model="config.ERROR_COUNT" placeholder="允许错误次数"></el-input>
</el-form-item>
<el-form-item label="上传次数限制">
<small>每几分钟</small>
<el-input v-model="config.UPLOAD_MINUTE"
placeholder="每几分钟"></el-input>
<small>允许上传几次</small>
<el-input v-model="config.UPLOAD_COUNT"
placeholder="允许次数"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="updateConfig" type="primary">更新</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
</el-col>
</el-row>
</el-col>
</el-row>
<div v-else style="width: 250px;text-align: center;margin: 40vh auto">
@@ -113,6 +231,8 @@
config: {
banners: []
},
menus: [],
updateTab: 'INSTALL',
files: [],
paginate: {
page: 1,
@@ -126,12 +246,13 @@
if (pwd) {
login = true;
this.pwd = pwd;
axios.get('{{admin_address}}/config', {
axios.get(window.location.href + '/config', {
headers: {
pwd: pwd
}
}).then(res => {
this.config = res.data.data;
this.menus = res.data.menus;
});
this.loginAdmin();
}
@@ -146,10 +267,10 @@
this.loginAdmin();
},
deleteBanner: function (index) {
this.config.banners.splice(index, 1);
this.config.BANNERS.splice(index, 1);
},
addBanner: function () {
this.config.banners.push({
this.config.BANNERS.push({
'url': '',
'src': '',
'text': '',