diff --git a/src/api/system/sensitiveWord/index.ts b/src/api/system/sensitiveWord/index.ts index 7da2c28e..08078ba6 100644 --- a/src/api/system/sensitiveWord/index.ts +++ b/src/api/system/sensitiveWord/index.ts @@ -1,4 +1,5 @@ import request from '@/config/axios' +import qs from 'qs' export interface SensitiveWordVO { id: number @@ -23,6 +24,11 @@ export interface SensitiveWordExportReqVO { createTime?: Date[] } +export interface SensitiveWordTestReqVO { + text: string + tag: string[] +} + // 查询敏感词列表 export const getSensitiveWordPage = (params: SensitiveWordPageReqVO) => { return request.get({ url: '/system/sensitive-word/page', params }) @@ -59,6 +65,8 @@ export const getSensitiveWordTags = () => { } // 获得文本所包含的不合法的敏感词数组 -export const validateText = (id: number) => { - return request.get({ url: '/system/sensitive-word/validate-text?' + id }) +export const validateText = (query: SensitiveWordTestReqVO) => { + return request.get({ + url: '/system/sensitive-word/validate-text?' + qs.stringify(query, { arrayFormat: 'repeat' }) + }) } diff --git a/src/types/auto-components.d.ts b/src/types/auto-components.d.ts index 2b199f1a..374893bb 100644 --- a/src/types/auto-components.d.ts +++ b/src/types/auto-components.d.ts @@ -23,13 +23,11 @@ declare module '@vue/runtime-core' { DictTag: typeof import('./../components/DictTag/src/DictTag.vue')['default'] Echart: typeof import('./../components/Echart/src/Echart.vue')['default'] Editor: typeof import('./../components/Editor/src/Editor.vue')['default'] - ElAvatar: typeof import('element-plus/es')['ElAvatar'] ElBadge: typeof import('element-plus/es')['ElBadge'] ElButton: typeof import('element-plus/es')['ElButton'] ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup'] ElCard: typeof import('element-plus/es')['ElCard'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] - ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] ElCol: typeof import('element-plus/es')['ElCol'] ElCollapse: typeof import('element-plus/es')['ElCollapse'] ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] @@ -56,30 +54,24 @@ declare module '@vue/runtime-core' { ElIcon: typeof import('element-plus/es')['ElIcon'] ElImageViewer: typeof import('element-plus/es')['ElImageViewer'] ElInput: typeof import('element-plus/es')['ElInput'] - ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] ElLink: typeof import('element-plus/es')['ElLink'] ElOption: typeof import('element-plus/es')['ElOption'] ElPagination: typeof import('element-plus/es')['ElPagination'] ElPopover: typeof import('element-plus/es')['ElPopover'] ElRadio: typeof import('element-plus/es')['ElRadio'] - ElRadioButton: typeof import('element-plus/es')['ElRadioButton'] ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] ElRow: typeof import('element-plus/es')['ElRow'] ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] ElSelect: typeof import('element-plus/es')['ElSelect'] ElSkeleton: typeof import('element-plus/es')['ElSkeleton'] - ElSpace: typeof import('element-plus/es')['ElSpace'] ElSwitch: typeof import('element-plus/es')['ElSwitch'] ElTable: typeof import('element-plus/es')['ElTable'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] - ElTableV2: typeof import('element-plus/es')['ElTableV2'] ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabs: typeof import('element-plus/es')['ElTabs'] ElTag: typeof import('element-plus/es')['ElTag'] ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTransfer: typeof import('element-plus/es')['ElTransfer'] - ElTree: typeof import('element-plus/es')['ElTree'] - ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect'] ElUpload: typeof import('element-plus/es')['ElUpload'] Error: typeof import('./../components/Error/src/Error.vue')['default'] FlowCondition: typeof import('./../components/bpmnProcessDesigner/package/penal/flow-condition/FlowCondition.vue')['default'] diff --git a/src/views/system/sensitiveWord/form.vue b/src/views/system/sensitiveWord/form.vue index 0736542e..ce5de578 100644 --- a/src/views/system/sensitiveWord/form.vue +++ b/src/views/system/sensitiveWord/form.vue @@ -67,10 +67,11 @@ const formRules = reactive({ tags: [{ required: true, message: '标签不能为空', trigger: 'blur' }] }) const formRef = ref() // 表单 Ref -const tags = ref([]) // todo @blue-syd:在 openModal 里加载下 +const tags: Ref<string[]> = ref([]) // todo @blue-syd:在 openModal 里加载下 /** 打开弹窗 */ -const openModal = async (type: string, id?: number) => { +const openModal = async (type: string, paramTags: string[], id?: number) => { + tags.value = paramTags modelVisible.value = true modelTitle.value = t('action.' + type) formType.value = type diff --git a/src/views/system/sensitiveWord/index.vue b/src/views/system/sensitiveWord/index.vue index 17da6ca3..93ea3c71 100644 --- a/src/views/system/sensitiveWord/index.vue +++ b/src/views/system/sensitiveWord/index.vue @@ -45,13 +45,14 @@ <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> <el-button type="primary" + plain @click="openModal('create')" v-hasPermi="['system:sensitive-word:create']" > <Icon icon="ep:plus" class="mr-5px" /> 新增 </el-button> <el-button - type="success" + type="warning" plain @click="handleExport" :loading="exportLoading" @@ -59,6 +60,9 @@ > <Icon icon="ep:download" class="mr-5px" /> 导出 </el-button> + <el-button type="success" plain @click="handleTest"> + <Icon icon="ep:document-checked" class="mr-5px" /> 测试 + </el-button> </el-form-item> </el-form> </content-wrap> @@ -127,6 +131,9 @@ <!-- 表单弹窗:添加/修改 --> <SensitiveWordForm ref="modalRef" @success="getList" /> + + <!-- 表单弹窗:测试敏感词 --> + <SensitiveWordTestForm ref="modalTestRef" /> </template> <script setup lang="ts" name="SensitiveWord"> import { DICT_TYPE, getDictOptions } from '@/utils/dict' @@ -134,6 +141,8 @@ import { dateFormatter } from '@/utils/formatTime' import download from '@/utils/download' import * as SensitiveWordApi from '@/api/system/sensitiveWord' import SensitiveWordForm from './form.vue' // TODO @blue-syd:组件名不对 +import SensitiveWordTestForm from './testForm.vue' + const message = useMessage() // 消息弹窗 const { t } = useI18n() // 国际化 @@ -179,10 +188,15 @@ const resetQuery = () => { /** 添加/修改操作 */ const modalRef = ref() const openModal = (type: string, id?: number) => { - modalRef.value.openModal(type, id) + modalRef.value.openModal(type, tags.value, id) } // TODO @blue-syd:还少一个【测试】按钮的功能,参见 http://dashboard.yudao.iocoder.cn/system/sensitive-word +/* 测试敏感词按钮操作 */ +const modalTestRef = ref() +const handleTest = () => { + modalTestRef.value.openModal(tags.value) +} /** 删除按钮操作 */ const handleDelete = async (id: number) => { diff --git a/src/views/system/sensitiveWord/testForm.vue b/src/views/system/sensitiveWord/testForm.vue new file mode 100644 index 00000000..766d771f --- /dev/null +++ b/src/views/system/sensitiveWord/testForm.vue @@ -0,0 +1,92 @@ +<template> + <!-- 对话框(测试敏感词) --> + <Dialog :title="modelTitle" v-model="modelVisible"> + <el-form + ref="formRef" + :model="formData" + :rules="formRules" + label-width="80px" + v-loading="formLoading" + > + <el-form-item label="文本" prop="text"> + <el-input type="textarea" v-model="formData.text" placeholder="请输入测试文本" /> + </el-form-item> + <el-form-item label="标签" prop="tags"> + <el-select + v-model="formData.tags" + multiple + filterable + allow-create + placeholder="请选择文章标签" + style="width: 380px" + > + <el-option v-for="tag in tags" :key="tag" :label="tag" :value="tag" /> + </el-select> + </el-form-item> + </el-form> + <template #footer> + <div class="dialog-footer"> + <el-button @click="submitForm" type="primary" :disabled="formLoading">检 测</el-button> + <el-button @click="modelVisible = false">取 消</el-button> + </div> + </template> + </Dialog> +</template> +<script setup lang="ts"> +import * as SensitiveWordApi from '@/api/system/sensitiveWord' + +const message = useMessage() // 消息弹窗 + +const modelVisible = ref(false) // 弹窗的是否展示 +const modelTitle = ref('检测敏感词') // 弹窗的标题 +const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 +const tags: Ref<string[]> = ref([]) +const formData = ref({ + text: '', + tags: [] +}) +const formRules = reactive({ + text: [{ required: true, message: '测试文本不能为空', trigger: 'blur' }], + tags: [{ required: true, message: '标签不能为空', trigger: 'blur' }] +}) +const formRef = ref() // 表单 Ref + +/** 打开弹窗 */ +const openModal = async (paramTags: string[]) => { + tags.value = paramTags + modelVisible.value = true + resetForm() +} +defineExpose({ openModal }) // 提供 openModal 方法,用于打开弹窗 + +/** 提交表单 */ +const submitForm = async () => { + // 校验表单 + if (!formRef) return + const valid = await formRef.value.validate() + if (!valid) return + // 提交请求 + formLoading.value = true + try { + const form = formData.value as unknown as SensitiveWordApi.SensitiveWordTestReqVO + const data = await SensitiveWordApi.validateText(form) + if (data.length === 0) { + message.success('不包含敏感词!') + return + } + message.warning('包含敏感词:' + data.join(', ')) + modelVisible.value = false + } finally { + formLoading.value = false + } +} + +/** 重置表单 */ +const resetForm = () => { + formData.value = { + text: '', + tags: [] + } + formRef.value?.resetFields() +} +</script>