From e45e74e5ae207f7642be9a88ed99b593de89fb3b Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期三, 24 六月 2026 16:54:46 +0800
Subject: [PATCH] 1.0
---
frontend-admin/src/views/SensitiveWordsView.vue | 75 +++++++++++++++++++++++++++++++++++++
1 files changed, 74 insertions(+), 1 deletions(-)
diff --git a/frontend-admin/src/views/SensitiveWordsView.vue b/frontend-admin/src/views/SensitiveWordsView.vue
index d3860a5..215f03b 100644
--- a/frontend-admin/src/views/SensitiveWordsView.vue
+++ b/frontend-admin/src/views/SensitiveWordsView.vue
@@ -2,7 +2,20 @@
<div class="page">
<div class="header">
<h3 class="section-title">敏感词库</h3>
- <el-button v-permission="'config:sensitive-words:create'" type="primary" @click="openCreate">新增</el-button>
+ <div class="header-actions">
+ <el-button v-permission="'config:sensitive-words:import'" type="primary" plain @click="downloadTemplate">
+ 下载模板
+ </el-button>
+ <el-upload
+ v-permission="'config:sensitive-words:import'"
+ :show-file-list="false"
+ accept=".xls,.xlsx"
+ :http-request="importSensitiveWords"
+ >
+ <el-button type="primary" :loading="importing">导入</el-button>
+ </el-upload>
+ <el-button v-permission="'config:sensitive-words:create'" type="primary" @click="openCreate">新增</el-button>
+ </div>
</div>
<el-form class="filters" :inline="true" :model="filters" @submit.prevent>
@@ -89,6 +102,7 @@
<script setup lang="ts">
import { onMounted, reactive, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
+import type { UploadRequestOptions } from "element-plus";
import http from "../api/http";
type Row = {
@@ -101,6 +115,7 @@
const loading = ref(false);
const saving = ref(false);
+const importing = ref(false);
const rows = ref<Row[]>([]);
const page = ref(1);
const size = ref(10);
@@ -213,6 +228,59 @@
}
}
+async function importSensitiveWords(opt: UploadRequestOptions) {
+ const file = opt.file as File;
+ if (!file) return;
+ if (!/\.(xls|xlsx)$/i.test(file.name)) {
+ ElMessage.warning("请上传 xls 或 xlsx 文件");
+ return;
+ }
+ const fd = new FormData();
+ fd.append("file", file);
+ importing.value = true;
+ try {
+ const { data } = await http.post("/config/sensitive-words/manage/import", fd, {
+ headers: { "Content-Type": "multipart/form-data" },
+ });
+ const result = data.result || {};
+ const success = Number(result.successCount) || 0;
+ const duplicate = Number(result.duplicateCount) || 0;
+ const invalid = Number(result.invalidCount) || 0;
+ const errors = Array.isArray(result.errorMessages) ? result.errorMessages : [];
+ const message = `导入完成:成功${success}条,重复跳过${duplicate}条,无效${invalid}条`;
+ if (errors.length) {
+ ElMessageBox.alert(`${message}\n${errors.join("\n")}`, "导入结果", {
+ confirmButtonText: "知道了",
+ });
+ } else {
+ ElMessage.success(message);
+ }
+ page.value = 1;
+ load();
+ } catch (e: unknown) {
+ ElMessage.error(e instanceof Error ? e.message : "导入失败");
+ } finally {
+ importing.value = false;
+ }
+}
+
+async function downloadTemplate() {
+ try {
+ const res = await http.get("/config/sensitive-words/manage/import-template", { responseType: "blob" });
+ const blob = new Blob([res.data], {
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ });
+ const url = window.URL.createObjectURL(blob);
+ const a = document.createElement("a");
+ a.href = url;
+ a.download = "sensitive-word-import-template.xlsx";
+ a.click();
+ window.URL.revokeObjectURL(url);
+ } catch (e: unknown) {
+ ElMessage.error(e instanceof Error ? e.message : "下载模板失败");
+ }
+}
+
function toggleEnabled(row: Row) {
const nextEnabled = row.enabled === 1 ? 0 : 1;
const actionText = nextEnabled === 1 ? "启用" : "禁用";
@@ -269,6 +337,11 @@
margin-bottom: 12px;
flex: none;
}
+.header-actions {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
.section-title {
font-size: 16px;
font-weight: 600;
--
Gitblit v1.7.1