Files
kenaito-media-picker/frontend/src/views/Settings.vue
T
2025-09-24 21:19:55 +08:00

192 lines
5.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="settings-page">
<el-card class="box-card">
<div slot="header" class="card-header">
<span>系统信息</span>
</div>
<el-row :gutter="20" class="system-info">
<el-col :span="8">
<div class="info-item">
<div class="info-label">CPU 核心数</div>
<div class="info-value">{{ systemInfo.cpuCores }}</div>
</div>
</el-col>
<el-col :span="8">
<div class="info-item">
<div class="info-label">内存大小</div>
<div class="info-value">{{ systemInfo.memoryGB.toFixed(1) }} GB</div>
</div>
</el-col>
<el-col :span="8">
<div class="info-item">
<div class="info-label">推荐 Worker</div>
<div class="info-value">
Go {{ systemInfo.recommendedGo }} / 人类 {{ systemInfo.recommendedNsfw }} / 二次元 {{ systemInfo.recommendedAnime }}
<el-button type="text" size="mini" @click="applyRecommended">一键应用</el-button>
</div>
</div>
</el-col>
</el-row>
</el-card>
<el-card class="box-card" style="margin-top: 20px">
<div slot="header" class="card-header">
<span>色情检测配置</span>
</div>
<el-form :model="form" label-width="140px" class="settings-form">
<el-form-item label="Go 端 Worker 数">
<el-input-number v-model="form.goWorkers" :min="0" :max="64"></el-input-number>
<div class="form-tip">探测/MIME/移动的并发数,0 表示使用文件配置(当前推荐 {{ systemInfo.recommendedGo }})</div>
</el-form-item>
<el-form-item label="检测类型">
<el-radio-group v-model="form.type">
<el-radio label="">关闭</el-radio>
<el-radio label="human">人类 (NudeNet)</el-radio>
<el-radio label="anime">二次元 (WD Tagger)</el-radio>
</el-radio-group>
<div class="form-tip">
<span v-if="form.type === ''">不启用色情检测</span>
<span v-else-if="form.type === 'human'">使用 NudeNet 检测真人色情内容</span>
<span v-else-if="form.type === 'anime'">使用 WD Tagger v3 检测二次元色情内容</span>
</div>
</el-form-item>
<el-form-item v-if="form.type === 'human'" label="推理 Worker 数">
<el-input-number v-model="form.humanWorkers" :min="1" :max="32"></el-input-number>
<div class="form-tip">并行推理的 worker 数量,越大越快但占用更多内存(每个 worker 约 300MB)</div>
</el-form-item>
<el-form-item v-if="form.type === 'anime'" label="推理 Worker 数">
<el-input-number v-model="form.animeWorkers" :min="1" :max="32"></el-input-number>
<div class="form-tip">并行推理的 worker 数量,越大越快但占用更多内存(每个 worker 约 1.5GB)</div>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="saveConfig" :loading="saving">保存配置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
import request from '../utils/request'
export default {
name: 'Settings',
data() {
return {
form: {
type: '',
humanWorkers: 4,
animeWorkers: 2,
goWorkers: 0
},
systemInfo: {
cpuCores: 0,
memoryGB: 0,
recommendedGo: 0,
recommendedNsfw: 4,
recommendedAnime: 2
},
saving: false
}
},
created() {
this.loadConfig()
this.loadSystemInfo()
},
methods: {
async loadConfig() {
try {
const res = await request.get('/api/config/nsfw')
if (res.data) {
this.form.type = res.data.type || ''
this.form.humanWorkers = res.data.humanWorkers || 4
this.form.animeWorkers = res.data.animeWorkers || 2
this.form.goWorkers = res.data.goWorkers || 0
}
} catch (error) {
this.$message.error('加载配置失败')
}
},
async loadSystemInfo() {
try {
const res = await request.get('/api/config/system')
if (res.data) {
this.systemInfo = res.data
}
} catch (error) {
// 忽略
}
},
applyRecommended() {
this.form.goWorkers = this.systemInfo.recommendedGo
this.form.humanWorkers = this.systemInfo.recommendedNsfw
this.form.animeWorkers = this.systemInfo.recommendedAnime
this.$message.success('已应用推荐值,请点击保存配置')
},
async saveConfig() {
this.saving = true
try {
await request.put('/api/config/nsfw', {
type: this.form.type,
humanWorkers: this.form.humanWorkers,
animeWorkers: this.form.animeWorkers,
goWorkers: this.form.goWorkers
})
this.$message.success('配置已保存,下次扫描生效')
} catch (error) {
this.$message.error('保存失败')
} finally {
this.saving = false
}
}
}
}
</script>
<style scoped>
.settings-page {
padding: 20px;
}
.card-header {
font-size: 16px;
font-weight: 600;
}
.system-info {
margin-top: 10px;
}
.info-item {
text-align: center;
padding: 10px 0;
}
.info-label {
font-size: 13px;
color: #909399;
margin-bottom: 8px;
}
.info-value {
font-size: 20px;
font-weight: 600;
color: #1f3a6b;
}
.settings-form {
margin-top: 20px;
}
.form-tip {
font-size: 12px;
color: #909399;
margin-top: 5px;
}
</style>