192 lines
5.5 KiB
Vue
192 lines
5.5 KiB
Vue
<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>
|