first
This commit is contained in:
114
domain-web/src/views/sensitive-words/SensitiveWordsView.vue
Normal file
114
domain-web/src/views/sensitive-words/SensitiveWordsView.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<PageCard title="敏感词配置" description="对齐旧桌面版主功能,支持加载、编辑、导入、导出和整库保存。">
|
||||
<el-alert
|
||||
:title="`当前共 ${total} 个敏感词`"
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon
|
||||
style="margin-bottom: 16px"
|
||||
/>
|
||||
|
||||
<el-input
|
||||
v-model="text"
|
||||
type="textarea"
|
||||
:rows="22"
|
||||
placeholder="请输入敏感词,一行一个"
|
||||
style="margin-bottom: 16px"
|
||||
/>
|
||||
|
||||
<div class="actions">
|
||||
<el-button @click="triggerImport">导入</el-button>
|
||||
<el-button @click="exportWords">导出</el-button>
|
||||
<el-button @click="loadWords">加载</el-button>
|
||||
<el-button type="primary" :loading="saving" @click="saveWords">保存</el-button>
|
||||
<input ref="fileInput" type="file" accept=".txt,text/plain" class="hidden-input" @change="handleImport" />
|
||||
</div>
|
||||
</PageCard>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import PageCard from "@/components/PageCard.vue";
|
||||
import { sensitiveWordsApi } from "@/api/modules";
|
||||
|
||||
const text = ref("");
|
||||
const total = ref(0);
|
||||
const saving = ref(false);
|
||||
const fileInput = ref<HTMLInputElement | null>(null);
|
||||
|
||||
const normalizeText = (value: string) =>
|
||||
value
|
||||
.split(/\r?\n/)
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean)
|
||||
.join("\n");
|
||||
|
||||
const loadWords = async () => {
|
||||
try {
|
||||
const response = await sensitiveWordsApi.get();
|
||||
text.value = response.data?.text || "";
|
||||
total.value = Number(response.data?.total || 0);
|
||||
} catch (error: any) {
|
||||
ElMessage.error(error?.message || "加载敏感词失败");
|
||||
}
|
||||
};
|
||||
|
||||
const saveWords = async () => {
|
||||
saving.value = true;
|
||||
try {
|
||||
const response = await sensitiveWordsApi.save({ text: normalizeText(text.value) });
|
||||
text.value = response.data?.text || normalizeText(text.value);
|
||||
total.value = Number(response.data?.total || 0);
|
||||
ElMessage.success(response.message || "敏感词已保存");
|
||||
} catch (error: any) {
|
||||
ElMessage.error(error?.message || "保存敏感词失败");
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const triggerImport = () => {
|
||||
fileInput.value?.click();
|
||||
};
|
||||
|
||||
const handleImport = async (event: Event) => {
|
||||
const input = event.target as HTMLInputElement;
|
||||
const file = input.files?.[0];
|
||||
if (!file) return;
|
||||
text.value = normalizeText(await file.text());
|
||||
total.value = text.value ? text.value.split("\n").length : 0;
|
||||
ElMessage.success(`已导入 ${total.value} 个敏感词`);
|
||||
input.value = "";
|
||||
};
|
||||
|
||||
const exportWords = () => {
|
||||
const content = normalizeText(text.value);
|
||||
if (!content) {
|
||||
ElMessage.warning("没有敏感词可导出");
|
||||
return;
|
||||
}
|
||||
const blob = new Blob([`${content}\n`], { type: "text/plain;charset=utf-8" });
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = "sensitive_words.txt";
|
||||
link.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
ElMessage.success("敏感词已导出");
|
||||
};
|
||||
|
||||
onMounted(loadWords);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.hidden-input {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user