Files
course/frontend/src/views/admin/AdminSettingsView.vue
T
nanxunandClaude Fable 5 cd486a36ef feat: UOOC/Zhihuishu dual-platform brushing platform
- ASP.NET Core 9 Web API backend with JWT auth, EF Core MySQL
- Vue 3 + Vite + Pinia + Ant Design Vue frontend
- Multi-platform connection management (UOOC & Zhihuishu)
- Video brushing with AES-CBC encryption for Zhihuishu
- Multi-task queue with cross-platform parallel execution
- Task persistence via MySQL database
- Progress tracking with inline catalog enrichment
- Mobile-responsive UI

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-24 15:31:32 +08:00

130 lines
4.8 KiB
Vue

<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue';
import { message } from 'ant-design-vue';
import { getSystemSettings, updateSystemSettings } from '../../lib/api';
import type { UpdateSystemSettingRequest } from '../../types/api';
const loading = ref(false);
const saving = ref(false);
const form = reactive<UpdateSystemSettingRequest>({
systemName: 'UOOC Progress',
registrationMode: 'open',
allowMockFallback: false,
browserChallengeTimeoutSeconds: 600,
connectionEncryptionVersion: 1,
defaultPlatformVisibility: 'active_only',
requireEmailVerification: false,
smtpHost: null,
smtpPort: 587,
smtpUseSsl: true,
smtpUsername: null,
smtpPassword: null,
smtpFromEmail: null,
});
onMounted(async () => {
loading.value = true;
try {
const s = await getSystemSettings();
form.systemName = s.systemName;
form.registrationMode = s.registrationMode;
form.allowMockFallback = s.allowMockFallback;
form.browserChallengeTimeoutSeconds = s.browserChallengeTimeoutSeconds;
form.connectionEncryptionVersion = s.connectionEncryptionVersion;
form.defaultPlatformVisibility = s.defaultPlatformVisibility;
form.requireEmailVerification = s.requireEmailVerification;
form.smtpHost = s.smtpHost;
form.smtpPort = s.smtpPort;
form.smtpUseSsl = s.smtpUseSsl;
form.smtpUsername = s.smtpUsername;
form.smtpFromEmail = s.smtpFromEmail;
form.smtpPassword = null; // never pre-fill from server
} catch (err) { message.error(err instanceof Error ? err.message : '加载失败。'); }
finally { loading.value = false; }
});
async function submit() {
saving.value = true;
try {
await updateSystemSettings({ ...form });
message.success('已保存。');
form.smtpPassword = null;
} catch (err) { message.error(err instanceof Error ? err.message : '保存失败。'); }
finally { saving.value = false; }
}
</script>
<template>
<a-card title="系统设置" :loading="loading">
<a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 12 }" style="max-width: 720px;">
<!-- System name -->
<a-form-item label="系统名称">
<a-input v-model:value="form.systemName" placeholder="UOOC Progress" />
</a-form-item>
<a-divider orientation="left" plain>注册</a-divider>
<a-form-item label="注册模式">
<a-select v-model:value="form.registrationMode">
<a-select-option value="open">开放注册</a-select-option>
<a-select-option value="invite_only">仅邀请码注册</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="默认平台可见性">
<a-select v-model:value="form.defaultPlatformVisibility">
<a-select-option value="active_only">仅显示启用的平台</a-select-option>
<a-select-option value="all">显示全部平台</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="Mock 数据回退">
<a-switch v-model:checked="form.allowMockFallback" />
<span style="margin-left: 8px;">上游接口异常时回退到 mock 数据</span>
</a-form-item>
<a-divider orientation="left" plain>邮箱验证</a-divider>
<a-form-item label="启用邮箱验证">
<a-switch v-model:checked="form.requireEmailVerification" />
</a-form-item>
<template v-if="form.requireEmailVerification">
<a-form-item label="SMTP 服务器" required>
<a-input v-model:value="form.smtpHost" placeholder="例如 smtp.qq.com" />
</a-form-item>
<a-form-item label="端口">
<a-input-number v-model:value="form.smtpPort" :min="1" :max="65535" />
</a-form-item>
<a-form-item label="使用 SSL">
<a-switch v-model:checked="form.smtpUseSsl" />
</a-form-item>
<a-form-item label="发件邮箱" required>
<a-input v-model:value="form.smtpFromEmail" placeholder="例如 noreply@example.com" />
</a-form-item>
<a-form-item label="SMTP 账号">
<a-input v-model:value="form.smtpUsername" placeholder="留空则无需认证" />
</a-form-item>
<a-form-item label="SMTP 密码">
<a-input-password v-model:value="form.smtpPassword" placeholder="留空则不修改" />
</a-form-item>
</template>
<a-divider orientation="left" plain>其他</a-divider>
<a-form-item label="挑战超时秒数">
<a-input-number v-model:value="form.browserChallengeTimeoutSeconds" :min="30" />
</a-form-item>
<a-form-item label="连接加密版本">
<a-input-number v-model:value="form.connectionEncryptionVersion" :min="1" />
</a-form-item>
<a-form-item :wrapper-col="{ offset: 6 }">
<a-button type="primary" :loading="saving" @click="submit">{{ saving ? '保存中...' : '保存设置' }}</a-button>
</a-form-item>
</a-form>
</a-card>
</template>