feat: 拆分系统设置数据库和远程分页
This commit is contained in:
@@ -612,3 +612,10 @@
|
|||||||
- `app/services/auto_scheduler.py` now keeps RJ directory status keys clean instead of prefixing them with `rj:` in the combined scheduler response.
|
- `app/services/auto_scheduler.py` now keeps RJ directory status keys clean instead of prefixing them with `rj:` in the combined scheduler response.
|
||||||
- `frontend/src/components/SettingsPanel.vue` strips any legacy `rj:` prefix before rendering the scheduler directory name, so the UI shows `RJ/2.6G/...` instead of `rj:RJ/2.6G/...`.
|
- `frontend/src/components/SettingsPanel.vue` strips any legacy `rj:` prefix before rendering the scheduler directory name, so the UI shows `RJ/2.6G/...` instead of `rj:RJ/2.6G/...`.
|
||||||
- This is display-only cleanup; the underlying RJ directory detection and readiness logic were not changed.
|
- This is display-only cleanup; the underlying RJ directory detection and readiness logic were not changed.
|
||||||
|
|
||||||
|
## 2026-06-01: Settings page split
|
||||||
|
|
||||||
|
- `frontend/src/components/SettingsPanel.vue` splits the former combined connection page into a dedicated `数据库配置` tab and a separate `远程数据源` tab.
|
||||||
|
- Database-related settings now stay together with `数据库配置` and `处理历史保留`; remote automation settings now own the FTP/SFTP fields, auto-delete toggle, scheduler configuration, and scheduler status panel.
|
||||||
|
- `frontend/src/styles.css` now uses dedicated layout classes for the database and remote settings panes, with independent scrolling and responsive single-column stacking on narrower screens.
|
||||||
|
- Verification performed: `cd frontend && npm run build` passed. Browser inspection on `http://127.0.0.1:9081/settings` confirmed the two new tabs render correctly, the remote panel shows its own configuration and scheduler cards, and horizontal overflow remained at `0`.
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
<n-card size="small" class="work-card settings-tabs-card">
|
<n-card size="small" class="work-card settings-tabs-card">
|
||||||
<n-tabs type="line" animated class="settings-tabs">
|
<n-tabs type="line" animated class="settings-tabs">
|
||||||
<n-tab-pane name="connection" tab="连接配置">
|
<n-tab-pane name="database" tab="数据库配置">
|
||||||
<div class="settings-section-grid">
|
<div class="settings-database-panel">
|
||||||
<div class="settings-connection-stack">
|
<div class="settings-database-stack">
|
||||||
<n-card title="数据库配置" size="small" class="work-card">
|
<n-card title="数据库配置" size="small" class="work-card">
|
||||||
<n-form label-placement="top">
|
<n-form label-placement="top">
|
||||||
<n-grid :cols="12" :x-gap="12">
|
<n-grid :cols="12" :x-gap="12">
|
||||||
@@ -78,8 +78,12 @@
|
|||||||
</template>
|
</template>
|
||||||
</n-card>
|
</n-card>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</n-tab-pane>
|
||||||
|
|
||||||
<n-card title="远程数据源" size="small" class="work-card">
|
<n-tab-pane name="remote" tab="远程数据源">
|
||||||
|
<div class="settings-remote-grid">
|
||||||
|
<n-card title="远程数据源配置" size="small" class="work-card settings-remote-card">
|
||||||
<n-form label-placement="top">
|
<n-form label-placement="top">
|
||||||
<n-grid :cols="12" :x-gap="12">
|
<n-grid :cols="12" :x-gap="12">
|
||||||
<n-gi :span="6">
|
<n-gi :span="6">
|
||||||
@@ -145,65 +149,77 @@
|
|||||||
<n-input v-model:value="remoteForm.remote_dir" placeholder="/CapacityReportData" />
|
<n-input v-model:value="remoteForm.remote_dir" placeholder="/CapacityReportData" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<p class="form-hint">自动化执行会递归下载该目录下的全部文件和文件夹到本地缓存,再按现有处理流程入库和执行脚本;自动删除源文件只会在处理成功后删除远程文件,保留目录结构。</p>
|
<p class="form-hint">自动化执行会递归下载该目录下的全部文件和文件夹到本地缓存,再按现有处理流程入库和执行脚本;自动删除源文件只会在处理成功后删除远程文件,保留目录结构。</p>
|
||||||
|
</n-form>
|
||||||
|
|
||||||
<n-divider class="settings-compact-divider">自动调度</n-divider>
|
<template #footer>
|
||||||
<n-grid :cols="12" :x-gap="12">
|
<n-space justify="end">
|
||||||
<n-gi :span="4">
|
<n-button type="primary" :loading="savingRemote" @click="saveRemote">保存配置</n-button>
|
||||||
<n-form-item label="启用自动调度">
|
<n-button :loading="testingRemote" @click="testRemote">测试连接</n-button>
|
||||||
<n-switch v-model:value="remoteForm.auto_scheduler.enabled" />
|
</n-space>
|
||||||
</n-form-item>
|
</template>
|
||||||
</n-gi>
|
</n-card>
|
||||||
<n-gi :span="4">
|
|
||||||
<n-form-item label="检查间隔(小时)">
|
<div class="settings-remote-stack">
|
||||||
<n-input-number
|
<n-card title="自动调度" size="small" class="work-card settings-scheduler-card">
|
||||||
v-model:value="remoteForm.auto_scheduler.check_interval_hours"
|
<n-form label-placement="top">
|
||||||
class="full-width"
|
<n-grid :cols="12" :x-gap="12">
|
||||||
:min="1"
|
<n-gi :span="4">
|
||||||
:precision="0"
|
<n-form-item label="启用自动调度">
|
||||||
:disabled="!remoteForm.auto_scheduler.enabled"
|
<n-switch v-model:value="remoteForm.auto_scheduler.enabled" />
|
||||||
/>
|
</n-form-item>
|
||||||
</n-form-item>
|
</n-gi>
|
||||||
</n-gi>
|
<n-gi :span="4">
|
||||||
<n-gi :span="4">
|
<n-form-item label="检查间隔(小时)">
|
||||||
<n-form-item label="目标周期">
|
<n-input-number
|
||||||
<n-select
|
v-model:value="remoteForm.auto_scheduler.check_interval_hours"
|
||||||
v-model:value="remoteForm.auto_scheduler.week_offset"
|
class="full-width"
|
||||||
:options="schedulerWeekOptions"
|
:min="1"
|
||||||
:disabled="!remoteForm.auto_scheduler.enabled"
|
:precision="0"
|
||||||
/>
|
:disabled="!remoteForm.auto_scheduler.enabled"
|
||||||
</n-form-item>
|
/>
|
||||||
</n-gi>
|
</n-form-item>
|
||||||
</n-grid>
|
</n-gi>
|
||||||
<n-form-item label="预期目录">
|
<n-gi :span="4">
|
||||||
<div class="scheduler-dir-editor">
|
<n-form-item label="目标周期">
|
||||||
<n-input-group>
|
<n-select
|
||||||
<n-input
|
v-model:value="remoteForm.auto_scheduler.week_offset"
|
||||||
v-model:value="newSchedulerDirectory"
|
:options="schedulerWeekOptions"
|
||||||
placeholder="例如 4G/FDD"
|
:disabled="!remoteForm.auto_scheduler.enabled"
|
||||||
:disabled="!remoteForm.auto_scheduler.enabled"
|
/>
|
||||||
@keydown.enter.prevent="addSchedulerDirectory"
|
</n-form-item>
|
||||||
/>
|
</n-gi>
|
||||||
<n-button :disabled="!remoteForm.auto_scheduler.enabled" @click="addSchedulerDirectory">
|
</n-grid>
|
||||||
添加
|
<n-form-item label="预期目录">
|
||||||
</n-button>
|
<div class="scheduler-dir-editor">
|
||||||
</n-input-group>
|
<n-input-group>
|
||||||
<div class="scheduler-dir-tags">
|
<n-input
|
||||||
<n-tag
|
v-model:value="newSchedulerDirectory"
|
||||||
v-for="(directory, index) in remoteForm.auto_scheduler.expected_directories"
|
placeholder="例如 4G/FDD"
|
||||||
:key="`${directory}-${index}`"
|
:disabled="!remoteForm.auto_scheduler.enabled"
|
||||||
closable
|
@keydown.enter.prevent="addSchedulerDirectory"
|
||||||
:disabled="!remoteForm.auto_scheduler.enabled"
|
/>
|
||||||
@close="removeSchedulerDirectory(index)"
|
<n-button :disabled="!remoteForm.auto_scheduler.enabled" @click="addSchedulerDirectory">
|
||||||
>
|
添加
|
||||||
{{ directory }}
|
</n-button>
|
||||||
</n-tag>
|
</n-input-group>
|
||||||
<n-tag v-if="remoteForm.auto_scheduler.expected_directories.length === 0" type="default">
|
<div class="scheduler-dir-tags">
|
||||||
按实际 ZIP 目录检测
|
<n-tag
|
||||||
</n-tag>
|
v-for="(directory, index) in remoteForm.auto_scheduler.expected_directories"
|
||||||
|
:key="`${directory}-${index}`"
|
||||||
|
closable
|
||||||
|
:disabled="!remoteForm.auto_scheduler.enabled"
|
||||||
|
@close="removeSchedulerDirectory(index)"
|
||||||
|
>
|
||||||
|
{{ directory }}
|
||||||
|
</n-tag>
|
||||||
|
<n-tag v-if="remoteForm.auto_scheduler.expected_directories.length === 0" type="default">
|
||||||
|
按实际 ZIP 目录检测
|
||||||
|
</n-tag>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</n-form-item>
|
||||||
</n-form-item>
|
<p class="form-hint">自动调度会按文件名日期检查目标自然周 7 天;开启后会强制启用远程自动化和处理成功后删除源文件。</p>
|
||||||
<p class="form-hint">自动调度会按文件名日期检查目标自然周 7 天;开启后会强制启用远程自动化和处理成功后删除源文件。</p>
|
</n-form>
|
||||||
|
|
||||||
<div class="scheduler-status-panel">
|
<div class="scheduler-status-panel">
|
||||||
<div class="scheduler-status-header">
|
<div class="scheduler-status-header">
|
||||||
@@ -250,15 +266,14 @@
|
|||||||
</n-button>
|
</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
</div>
|
</div>
|
||||||
</n-form>
|
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<n-space justify="end">
|
<n-space justify="end">
|
||||||
<n-button type="primary" :loading="savingRemote" @click="saveRemote">保存配置</n-button>
|
<n-button type="primary" :loading="savingRemote" @click="saveRemote">保存调度</n-button>
|
||||||
<n-button :loading="testingRemote" @click="testRemote">测试连接</n-button>
|
</n-space>
|
||||||
</n-space>
|
</template>
|
||||||
</template>
|
</n-card>
|
||||||
</n-card>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
|
|
||||||
|
|||||||
+30
-12
@@ -1382,15 +1382,16 @@ select {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-section-grid,
|
.settings-database-panel,
|
||||||
|
.settings-remote-grid,
|
||||||
.settings-rules-grid {
|
.settings-rules-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
gap: 18px;
|
gap: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-section-grid {
|
.settings-database-panel {
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: minmax(420px, 680px);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
padding-right: 6px;
|
padding-right: 6px;
|
||||||
@@ -1400,27 +1401,47 @@ select {
|
|||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-connection-stack {
|
.settings-database-stack,
|
||||||
|
.settings-remote-stack {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 18px;
|
gap: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-section-grid::-webkit-scrollbar {
|
.settings-remote-grid {
|
||||||
|
grid-template-columns: minmax(380px, 0.9fr) minmax(360px, 1.1fr);
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
padding-right: 6px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
scrollbar-color: var(--td-scrollbar-color) transparent;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-database-panel::-webkit-scrollbar,
|
||||||
|
.settings-remote-grid::-webkit-scrollbar {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-section-grid::-webkit-scrollbar-thumb {
|
.settings-database-panel::-webkit-scrollbar-thumb,
|
||||||
|
.settings-remote-grid::-webkit-scrollbar-thumb {
|
||||||
background: var(--td-scrollbar-color);
|
background: var(--td-scrollbar-color);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-section-grid::-webkit-scrollbar-track {
|
.settings-database-panel::-webkit-scrollbar-track,
|
||||||
|
.settings-remote-grid::-webkit-scrollbar-track {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settings-remote-card,
|
||||||
|
.settings-scheduler-card {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.settings-rules-grid {
|
.settings-rules-grid {
|
||||||
grid-template-columns: minmax(280px, 0.72fr) minmax(0, 1.4fr);
|
grid-template-columns: minmax(280px, 0.72fr) minmax(0, 1.4fr);
|
||||||
grid-template-rows: minmax(0, 1fr);
|
grid-template-rows: minmax(0, 1fr);
|
||||||
@@ -1484,10 +1505,6 @@ select {
|
|||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-compact-divider {
|
|
||||||
margin: 12px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scheduler-dir-editor {
|
.scheduler-dir-editor {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -1917,7 +1934,8 @@ select {
|
|||||||
|
|
||||||
/* ==================== Responsive ==================== */
|
/* ==================== Responsive ==================== */
|
||||||
@media (max-width: 1200px) {
|
@media (max-width: 1200px) {
|
||||||
.settings-section-grid,
|
.settings-database-panel,
|
||||||
|
.settings-remote-grid,
|
||||||
.settings-rules-grid {
|
.settings-rules-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user