mirror of
http://112.124.100.131/ebiz-ai/ebiz-ai-knowledge-manage.git
synced 2025-12-23 17:55:44 +08:00
feat(knowledge): 新增知识拆分规则功能
- 添加了自动拆分和自定义拆分两种方式 - 实现了拆分规则的添加、编辑和删除- 增加了拆分结果预览功能 - 优化了用户界面和交互设计
This commit is contained in:
@@ -1,105 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="splitConfig mt20">
|
|
||||||
文件拆分规则
|
|
||||||
<ul>
|
|
||||||
<!-- 自动拆分 -->
|
|
||||||
<li class="flex" v-for="(item, index) in splitOptions" :key="index" @click="handleClick(index)">
|
|
||||||
<div>
|
|
||||||
<i :class="item.icon" size="50"></i>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h3>{{ item.title }}</h3>
|
|
||||||
{{ item.description }}<br>
|
|
||||||
<span v-if="item.tip">{{ item.tip }}</span>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<!-- 弹窗组件 -->
|
|
||||||
<custom-split-dialog
|
|
||||||
v-if="dialogVisible"
|
|
||||||
:visible="dialogVisible"
|
|
||||||
:form="form"
|
|
||||||
:table-data="tableData">
|
|
||||||
</custom-split-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import CustomSplitDialog from './split/CustomSplitDialog.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'splitConfig',
|
|
||||||
components: {
|
|
||||||
CustomSplitDialog
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
dialogVisible: false,
|
|
||||||
form: {
|
|
||||||
// 表单数据
|
|
||||||
},
|
|
||||||
tableData: [
|
|
||||||
// 表格数据示例
|
|
||||||
{ id: 1, name: 'Item 1', selected: false },
|
|
||||||
{ id: 2, name: 'Item 2', selected: false },
|
|
||||||
{ id: 3, name: 'Item 3', selected: false }
|
|
||||||
],
|
|
||||||
splitOptions: [
|
|
||||||
{
|
|
||||||
icon: 'el-icon-setting',
|
|
||||||
title: '自动拆分',
|
|
||||||
description: '使用系统默认的拆分方式,适合新手或紧急任务,直接使用系统优化后的算法处理文本。',
|
|
||||||
tip: '提示:首次使用时建议先用自动拆分测试效果,再决定是否调整。'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'el-icon-medal',
|
|
||||||
title: '自定义拆分',
|
|
||||||
description: '使用自定义拆分方式可以根据具体需求灵活调整文本分割逻辑,但需要权衡灵活性与复杂度,需要用户具备一定的规则定制经验。',
|
|
||||||
tip: ''
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {},
|
|
||||||
watch: {},
|
|
||||||
filters: {},
|
|
||||||
methods: {
|
|
||||||
designSplit() {
|
|
||||||
this.dialogVisible = true;
|
|
||||||
},
|
|
||||||
handleClick(index) {
|
|
||||||
console.log('Clicked index:', index);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {},
|
|
||||||
mounted() {},
|
|
||||||
computed: {}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style scoped lang='scss'>
|
|
||||||
.splitConfig {
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 6px;
|
|
||||||
list-style-type: none;
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 10px 0;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,85 +1,103 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- 添加预处理结果预览对话框 -->
|
<!-- 添加预处理结果预览对话框 -->
|
||||||
<el-dialog
|
<el-drawer
|
||||||
title="添加知识拆分规则"
|
title="添加知识拆分规则"
|
||||||
:visible.sync="dialogVisible"
|
:visible.sync="dialogVisible"
|
||||||
width="650px">
|
size="50%">
|
||||||
<el-form ref="ruleForm" :model="form" :rules="rules" label-width="100px">
|
<div class="content">
|
||||||
<el-form-item label="规则名称:" prop="ruleName">
|
<el-form ref="ruleForm" :model="form" :rules="rules" label-width="120px">
|
||||||
<el-input v-model="form.ruleName" placeholder="请输入规则名称"></el-input>
|
<el-row :gutter="20">
|
||||||
<span>支持中文、英文、数字、下划线(_),50个字符以内,不能以下划线为开头</span>
|
<el-col :span="12">
|
||||||
<el-button type="primary" size="mini" @click="queryExistingRules">查询并导入现有规则</el-button>
|
<el-form-item label="规则名称" prop="ruleName">
|
||||||
</el-form-item>
|
<el-input v-model="form.ruleName" placeholder="请输入规则名称"></el-input>
|
||||||
<el-form-item label="属性:" prop="style">
|
</el-form-item>
|
||||||
<el-input v-model="form.ruleName" placeholder="请输入属性"></el-input>
|
</el-col>
|
||||||
</el-form-item>
|
<el-col :span="12">
|
||||||
<el-form-item label="属性描述:" prop="style">
|
<el-select v-model="form.ruleName" placeholder="查询并导入现有规则"></el-select>
|
||||||
<el-input v-model="form.ruleName" placeholder="请输入属性描述"></el-input>
|
</el-col>
|
||||||
</el-form-item>
|
</el-row>
|
||||||
<el-form-item label="关键词:" prop="style">
|
<p class="tips">支持中文、英文、数字、下划线(_),50个字符以内,不能以下划线为开头</p>
|
||||||
<el-input v-model="form.ruleName" placeholder="请输入关键词"></el-input>
|
<div v-for="(rule, index) in form.rules" :key="index">
|
||||||
</el-form-item>
|
<el-form-item label="样式" :prop="'rules.' + index + '.style'">
|
||||||
<el-form-item label="题词示例:" prop="style">
|
<el-input v-model="rule.style" placeholder="请输入样式"></el-input>
|
||||||
<el-input v-model="form.ruleName" placeholder="请输入题词示例"></el-input>
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="提示词" :prop="'rules.' + index + '.promptWord'">
|
||||||
<el-form-item label="提示词:" prop="promptWord">
|
<el-input type="textarea" v-model="rule.promptWord" placeholder="请输入提示词"></el-input>
|
||||||
<el-input type="textarea" v-model="form.promptWord" placeholder="请输入提示词"></el-input>
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="备注" :prop="'rules.' + index + '.remark'">
|
||||||
</el-form>
|
<el-input type="textarea" v-model="rule.remark" placeholder="请输入规则备注"></el-input>
|
||||||
|
</el-form-item>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div class="text-right mb20">
|
||||||
<el-button type="primary" size="medium" @click="addSplitRule">+ 新增拆分规则</el-button>
|
<el-button type="primary" size="medium" @click="copyRule">复制拆分规则</el-button>
|
||||||
<el-button size="medium" @click="deleteSplitRule">- 删除拆分规则</el-button>
|
<el-button type="primary" size="medium" @click="addSplitRule">+ 新增拆分规则</el-button>
|
||||||
|
<el-button v-if="form.rules.length > 1" type="danger" size="small" @click="removeRule(index)">删除规则</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'AddRule',
|
name: 'AddRule',
|
||||||
props: {
|
|
||||||
dialogVisible: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
form: {
|
form: {
|
||||||
ruleName: '',
|
rules: [
|
||||||
style: '',
|
{
|
||||||
promptWord: '',
|
ruleName: '',
|
||||||
remark: ''
|
style: '',
|
||||||
|
promptWord: '',
|
||||||
|
remark: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
ruleName: [
|
ruleName: [
|
||||||
{ required: true, message: '请输入规则名称', trigger: 'blur' }
|
{ required: true, message: '请输入规则名称', trigger: 'blur' }
|
||||||
],
|
],
|
||||||
style: [
|
rules: {
|
||||||
{ required: true, message: '请选择样式', trigger: 'change' }
|
required: true,
|
||||||
],
|
type: 'array',
|
||||||
promptWord: [
|
fields: {
|
||||||
{ required: true, message: '请输入提示词', trigger: 'blur' }
|
style: [
|
||||||
]
|
{ required: true, message: '请选择样式', trigger: 'change' }
|
||||||
|
],
|
||||||
|
promptWord: [
|
||||||
|
{ required: true, message: '请输入提示词', trigger: 'blur' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.dialogVisible = true;
|
||||||
|
},
|
||||||
queryExistingRules() {
|
queryExistingRules() {
|
||||||
// 查询并导入现有规则的逻辑
|
// 查询并导入现有规则的逻辑
|
||||||
},
|
},
|
||||||
|
// 复制
|
||||||
|
copyRule(){
|
||||||
|
|
||||||
|
},
|
||||||
|
// 新增
|
||||||
addSplitRule() {
|
addSplitRule() {
|
||||||
this.$refs.ruleForm.validate((valid) => {
|
this.form.rules.push({
|
||||||
if (valid) {
|
ruleName: '',
|
||||||
// 新增拆分规则的逻辑
|
style: '',
|
||||||
} else {
|
promptWord: '',
|
||||||
console.log('表单验证失败');
|
remark: ''
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
removeRule(index) {
|
||||||
|
this.form.rules.splice(index, 1);
|
||||||
|
},
|
||||||
deleteSplitRule() {
|
deleteSplitRule() {
|
||||||
// 删除拆分规则的逻辑
|
// 删除拆分规则的逻辑
|
||||||
console.log('删除拆分规则');
|
console.log('删除拆分规则');
|
||||||
@@ -96,5 +114,13 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang='scss'>
|
<style scoped lang='scss'>
|
||||||
|
.content{
|
||||||
|
padding: 20px;
|
||||||
|
.tips{
|
||||||
|
font-size: 14px ;
|
||||||
|
color: #999;
|
||||||
|
margin-left: 120px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
<!-- 表单内容 -->
|
<!-- 表单内容 -->
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="知识名称">
|
<el-form-item label="知识拆分规则">
|
||||||
<el-input v-model="form.field1" size="medium" placeholder="知识名称"></el-input>
|
<el-input v-model="form.field1" size="medium" placeholder="请输入知识拆分规则"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<!-- 其他表单项 -->
|
<!-- 其他表单项 -->
|
||||||
</el-form>
|
</el-form>
|
||||||
<r-table :columns="columns" :data="list" :deletion="false"></r-table>
|
<r-table :columns="columns" :data="tableData" :deletion="false"></r-table>
|
||||||
<!-- 添加 AddRule 组件 -->
|
<!-- 添加 AddRule 组件 -->
|
||||||
<add-rule :dialogVisible.sync="addRuleVisible"></add-rule>
|
<add-rule ref="addRule"></add-rule>
|
||||||
|
|
||||||
<!-- 添加预览弹窗 -->
|
<!-- 添加预览弹窗 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
@@ -44,27 +44,30 @@ export default {
|
|||||||
AddRule // 注册 AddRule 组件
|
AddRule // 注册 AddRule 组件
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
form: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
tableData: {
|
|
||||||
type: Array,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
list: [{}],
|
visible: false,
|
||||||
|
form: {
|
||||||
|
// 表单数据
|
||||||
|
},
|
||||||
|
tableData: [
|
||||||
|
// 表格数据示例
|
||||||
|
{ id: 1, name: 'Item 1', selected: false },
|
||||||
|
{ id: 2, name: 'Item 2', selected: false },
|
||||||
|
{ id: 3, name: 'Item 3', selected: false }
|
||||||
|
],
|
||||||
addRuleVisible: false, // 控制 AddRule 组件的显示状态
|
addRuleVisible: false, // 控制 AddRule 组件的显示状态
|
||||||
previewDialogVisible: false // 控制预览弹窗的显示状态
|
previewDialogVisible: false // 控制预览弹窗的显示状态
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
init(){
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
close(){
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
handlePreview(row) {
|
handlePreview(row) {
|
||||||
// 预览逻辑
|
// 预览逻辑
|
||||||
console.log('Preview', row);
|
console.log('Preview', row);
|
||||||
@@ -78,7 +81,8 @@ export default {
|
|||||||
this.$emit('update:visible', false)
|
this.$emit('update:visible', false)
|
||||||
},
|
},
|
||||||
addRule() {
|
addRule() {
|
||||||
this.addRuleVisible = true; // 显示 AddRule 组件
|
this.$refs.addRule.init()
|
||||||
|
// this.addRuleVisible = true; // 显示 AddRule 组件
|
||||||
},
|
},
|
||||||
handleClose(done) {
|
handleClose(done) {
|
||||||
this.$confirm('确认关闭?')
|
this.$confirm('确认关闭?')
|
||||||
@@ -94,35 +98,29 @@ export default {
|
|||||||
{
|
{
|
||||||
type: 'selection',
|
type: 'selection',
|
||||||
prop: 'knowledgeName',
|
prop: 'knowledgeName',
|
||||||
width: '200px',
|
width: '50',
|
||||||
align: 'center',
|
align: 'center'
|
||||||
render: (h, params) => {
|
|
||||||
return h('div', [h('span', params.row.knowledgeName)])
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '知识拆分规则名称',
|
key: '知识拆分规则名称',
|
||||||
prop: 'knowledgeName',
|
prop: 'knowledgeName',
|
||||||
width: '200px',
|
align: 'center'
|
||||||
align: 'center',
|
|
||||||
render: (h, params) => {
|
|
||||||
return h('div', [h('span', params.row.knowledgeName)])
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '规则内容',
|
key: '规则内容',
|
||||||
prop: 'knowledgeName',
|
prop: 'knowledgeName',
|
||||||
width: '200px',
|
|
||||||
align: 'center'
|
align: 'center'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '备注',
|
key: '备注',
|
||||||
prop: 'knowledgeDesc'
|
prop: 'knowledgeDesc',
|
||||||
|
align: 'center'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '操作',
|
key: '操作',
|
||||||
prop: 'knowledgeDesc',
|
prop: 'knowledgeDesc',
|
||||||
width: '200px',
|
width: '150px',
|
||||||
|
align: 'center',
|
||||||
render: (h, params) => {
|
render: (h, params) => {
|
||||||
return h('span', {}, [
|
return h('span', {}, [
|
||||||
h(
|
h(
|
||||||
|
|||||||
116
src/views/knowledge/detail/components/split/SplitConfig.vue
Normal file
116
src/views/knowledge/detail/components/split/SplitConfig.vue
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<template>
|
||||||
|
<div class="splitConfig mt20">
|
||||||
|
<p class="title">
|
||||||
|
文件拆分规则:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<!-- 自动拆分 -->
|
||||||
|
<li class="flex" :class="activeIndex === index ? 'active' : ''" v-for="(item, index) in splitOptions" :key="index" @click="handleClick(index)">
|
||||||
|
<div>
|
||||||
|
<svg v-if="index === 0" t="1744335709188" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2464" width="32" height="32"><path d="M933.868272 511.691752a140.807706 140.807706 0 0 1 90.131728-131.067068 525.562914 525.562914 0 0 0-57.334136-138.64997 139.882962 139.882962 0 0 1-184.948826-184.948826A525.562914 525.562914 0 0 0 643.067068 0a140.376159 140.376159 0 0 1-262.134136 0A525.562914 525.562914 0 0 0 242.282962 57.334136a139.882962 139.882962 0 0 1-184.948826 184.948826A506.698134 506.698134 0 0 0 0 380.932932a140.376159 140.376159 0 0 1 0 262.134136 525.562914 525.562914 0 0 0 57.334136 138.64997 139.882962 139.882962 0 0 1 184.948826 184.948826 525.562914 525.562914 0 0 0 138.64997 57.334136 140.376159 140.376159 0 0 1 262.134136 0 525.562914 525.562914 0 0 0 138.64997-57.334136 139.882962 139.882962 0 0 1 184.948826-184.948826 506.698134 506.698134 0 0 0 57.334136-138.64997A140.807706 140.807706 0 0 1 933.868272 511.691752zM511.691752 652.437809A140.437809 140.437809 0 1 1 652.437809 511.691752 140.499458 140.499458 0 0 1 511.691752 652.437809z" fill="#1D85ED" p-id="2465"></path></svg>
|
||||||
|
<svg v-if="index === 1" t="1744335834635" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7994" width="32" height="32"><path d="M746 181.1c10.3 0 19.4 6.1 23.3 15.6l1 2.3 1.2 2.2 110.4 210c2.9 8.6 0.9 18.3-5.3 25l-0.6 0.7-0.6 0.7-344.5 401.9c-6.4 6.7-14.1 7.7-18.2 7.7s-11.7-1-18.2-7.7L150.1 437.6l-0.6-0.7-0.6-0.7c-6.2-6.8-8.2-16.4-5.3-25l110.4-210 1.2-2.2 1-2.3c3.9-9.5 13.1-15.6 23.3-15.6H746m0-54.6H279.4c-32.3 0-61.4 19.5-73.8 49.3L93.8 388.7c-11.9 28.7-6 61.6 14.9 84.4l345.2 402.7c15.8 17.3 37.3 25.9 58.9 25.9 21.5 0 43-8.6 58.9-25.9l345.2-402.7c20.9-22.9 26.8-55.8 14.9-84.4l-112-212.9c-12.3-29.8-41.5-49.3-73.8-49.3z" p-id="7995" fill="#d81e06"></path><path d="M513.9 524.6c-19.1 0-37.5-8.1-50.4-22.2l-97.7-106.7c-10.2-11.1-9.4-28.4 1.7-38.5 11.1-10.2 28.4-9.4 38.5 1.7l97.7 106.7c3.6 3.9 7.9 4.5 10.2 4.5 2.3 0 6.6-0.6 10.2-4.5l95.5-104.2c10.2-11.1 27.4-11.9 38.5-1.7 11.1 10.2 11.9 27.4 1.7 38.5l-95.5 104.2c-13 14.1-31.3 22.2-50.4 22.2z" p-id="7996" fill="#d81e06"></path></svg>
|
||||||
|
</div>
|
||||||
|
<div class="block">
|
||||||
|
<h3>{{ item.title }}</h3>
|
||||||
|
<p class="tips">{{ item.description }}</p>
|
||||||
|
<p v-if="item.tip" class="tips">{{ item.tip }}</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<!-- 弹窗组件 -->
|
||||||
|
<custom-split-dialog
|
||||||
|
class="active"
|
||||||
|
ref="customTable">
|
||||||
|
</custom-split-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CustomSplitDialog from './CustomSplitDialog.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'splitConfig',
|
||||||
|
components: {
|
||||||
|
CustomSplitDialog
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
activeIndex: 0,
|
||||||
|
splitOptions: [
|
||||||
|
{
|
||||||
|
icon: 'el-icon-setting',
|
||||||
|
title: '自动拆分',
|
||||||
|
description: '使用系统默认的拆分方式,适合新手或紧急任务,直接使用系统优化后的算法处理文本。',
|
||||||
|
tip: '提示:首次使用时建议先用自动拆分测试效果,再决定是否调整。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'el-icon-medal',
|
||||||
|
title: '自定义拆分',
|
||||||
|
description: '使用自定义拆分方式可以根据具体需求灵活调整文本分割逻辑,但需要权衡灵活性与复杂度,需要用户具备一定的规则定制经验。',
|
||||||
|
tip: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {},
|
||||||
|
watch: {},
|
||||||
|
filters: {},
|
||||||
|
methods: {
|
||||||
|
handleClick(index) {
|
||||||
|
this.activeIndex = index;
|
||||||
|
if (index === 1) {
|
||||||
|
this.$refs.customTable.init()
|
||||||
|
} else {
|
||||||
|
this.$refs.customTable.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
mounted() {},
|
||||||
|
computed: {}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang='scss'>
|
||||||
|
.splitConfig {
|
||||||
|
.title {
|
||||||
|
font-size: 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 6px;
|
||||||
|
list-style-type: none;
|
||||||
|
width: 80%;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 10px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.block{
|
||||||
|
margin-left: 20px;
|
||||||
|
h3 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.tips{
|
||||||
|
color: #9E9E9E;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.active{
|
||||||
|
border: 1px solid #409EFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
132
src/views/knowledge/detail/components/words/AddRule.vue
Normal file
132
src/views/knowledge/detail/components/words/AddRule.vue
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 添加预处理结果预览对话框 -->
|
||||||
|
<el-drawer
|
||||||
|
title="添加知识拆分规则"
|
||||||
|
:visible.sync="dialogVisible"
|
||||||
|
size="50%">
|
||||||
|
<div class="content">
|
||||||
|
<el-form ref="ruleForm" :model="form" :rules="rules" label-width="120px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="规则名称" prop="ruleName">
|
||||||
|
<el-input v-model="form.ruleName" placeholder="请输入规则名称"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-select v-model="form.ruleName" placeholder="查询并导入现有规则"></el-select>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<p class="tips">支持中文、英文、数字、下划线(_),50个字符以内,不能以下划线为开头</p>
|
||||||
|
<div v-for="(rule, index) in form.rules" :key="index">
|
||||||
|
<el-form-item label="属性" :prop="'rules.' + index + '.style'">
|
||||||
|
<el-input v-model="rule.style" placeholder="请输入属性"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="属性描述" :prop="'rules.' + index + '.style'">
|
||||||
|
<el-input v-model="rule.style" placeholder="请输入属性描述"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="关键词" :prop="'rules.' + index + '.style'">
|
||||||
|
<el-input v-model="rule.style" placeholder="请输入关键词"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="题词示例" :prop="'rules.' + index + '.style'">
|
||||||
|
<el-input v-model="rule.style" placeholder="请输入题词示例"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="提示词" :prop="'rules.' + index + '.promptWord'">
|
||||||
|
<el-input type="textarea" v-model="rule.promptWord" placeholder="请输入提示词"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<div class="text-right mb20">
|
||||||
|
<el-button type="primary" size="medium" @click="copyRule">复制题词规则</el-button>
|
||||||
|
<el-button type="primary" size="medium" @click="addSplitRule">+ 新增题词规则</el-button>
|
||||||
|
<el-button v-if="form.rules.length > 1" type="danger" size="small" @click="removeRule(index)">删除题词规则</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'AddRule',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
form: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
ruleName: '',
|
||||||
|
style: '',
|
||||||
|
promptWord: '',
|
||||||
|
remark: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
ruleName: [
|
||||||
|
{ required: true, message: '请输入规则名称', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
required: true,
|
||||||
|
type: 'array',
|
||||||
|
fields: {
|
||||||
|
style: [
|
||||||
|
{ required: true, message: '请选择样式', trigger: 'change' }
|
||||||
|
],
|
||||||
|
promptWord: [
|
||||||
|
{ required: true, message: '请输入提示词', trigger: 'blur' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.dialogVisible = true;
|
||||||
|
},
|
||||||
|
queryExistingRules() {
|
||||||
|
// 查询并导入现有规则的逻辑
|
||||||
|
},
|
||||||
|
// 复制
|
||||||
|
copyRule(){
|
||||||
|
|
||||||
|
},
|
||||||
|
// 新增
|
||||||
|
addSplitRule() {
|
||||||
|
this.form.rules.push({
|
||||||
|
ruleName: '',
|
||||||
|
style: '',
|
||||||
|
promptWord: '',
|
||||||
|
remark: ''
|
||||||
|
});
|
||||||
|
},
|
||||||
|
removeRule(index) {
|
||||||
|
this.form.rules.splice(index, 1);
|
||||||
|
},
|
||||||
|
deleteSplitRule() {
|
||||||
|
// 删除拆分规则的逻辑
|
||||||
|
console.log('删除题词规则');
|
||||||
|
},
|
||||||
|
handleClose(done) {
|
||||||
|
this.$confirm('确认关闭?')
|
||||||
|
.then(_ => {
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(_ => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang='scss'>
|
||||||
|
.content{
|
||||||
|
padding: 20px;
|
||||||
|
.tips{
|
||||||
|
font-size: 14px ;
|
||||||
|
color: #999;
|
||||||
|
margin-left: 120px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
165
src/views/knowledge/detail/components/words/CustomWords.vue
Normal file
165
src/views/knowledge/detail/components/words/CustomWords.vue
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="visible">
|
||||||
|
<el-form :model="form" label-width="100px">
|
||||||
|
<!-- 表单内容 -->
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="知识拆分规则">
|
||||||
|
<el-input v-model="form.field1" size="medium" placeholder="请输入知识拆分规则"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-button type="primary" size="medium" @click="addRule" class="ml20">+ 新增规则</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<!-- 其他表单项 -->
|
||||||
|
</el-form>
|
||||||
|
<r-table :columns="columns" :data="tableData" :deletion="false"></r-table>
|
||||||
|
<!-- 添加 AddRule 组件 -->
|
||||||
|
<add-rule ref="addRule"></add-rule>
|
||||||
|
|
||||||
|
<!-- 添加预览弹窗 -->
|
||||||
|
<el-dialog
|
||||||
|
title="拆分结果预览"
|
||||||
|
:visible.sync="previewDialogVisible"
|
||||||
|
width="60%">
|
||||||
|
<div class="preview-content">
|
||||||
|
<!-- 预览内容区域 -->
|
||||||
|
这里是预览的内容
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button size="medium" type="primary" @click="previewDialogVisible = false">确定</el-button>
|
||||||
|
<el-button size="medium" @click="previewDialogVisible = false">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import AddRule from './AddRule.vue'; // 导入 AddRule 组件
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CustomSplitDialog',
|
||||||
|
components: {
|
||||||
|
AddRule // 注册 AddRule 组件
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
visible: false,
|
||||||
|
form: {
|
||||||
|
// 表单数据
|
||||||
|
},
|
||||||
|
tableData: [
|
||||||
|
// 表格数据示例
|
||||||
|
{ id: 1, name: 'Item 1', selected: false },
|
||||||
|
{ id: 2, name: 'Item 2', selected: false },
|
||||||
|
{ id: 3, name: 'Item 3', selected: false }
|
||||||
|
],
|
||||||
|
addRuleVisible: false, // 控制 AddRule 组件的显示状态
|
||||||
|
previewDialogVisible: false // 控制预览弹窗的显示状态
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init(){
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
close(){
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
handlePreview(row) {
|
||||||
|
// 预览逻辑
|
||||||
|
console.log('Preview', row);
|
||||||
|
this.previewDialogVisible = true; // 显示预览弹窗
|
||||||
|
},
|
||||||
|
handleEdit(row) {
|
||||||
|
// 修改逻辑
|
||||||
|
console.log('Edit', row)
|
||||||
|
},
|
||||||
|
closeDialog() {
|
||||||
|
this.$emit('update:visible', false)
|
||||||
|
},
|
||||||
|
addRule() {
|
||||||
|
this.$refs.addRule.init()
|
||||||
|
// this.addRuleVisible = true; // 显示 AddRule 组件
|
||||||
|
},
|
||||||
|
handleClose(done) {
|
||||||
|
this.$confirm('确认关闭?')
|
||||||
|
.then(_ => {
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(_ => {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
columns() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'selection',
|
||||||
|
prop: 'knowledgeName',
|
||||||
|
width: '50',
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '知识拆分规则名称',
|
||||||
|
prop: 'knowledgeName',
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '规则内容',
|
||||||
|
prop: 'knowledgeName',
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '备注',
|
||||||
|
prop: 'knowledgeDesc',
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '操作',
|
||||||
|
prop: 'knowledgeDesc',
|
||||||
|
width: '150px',
|
||||||
|
align: 'center',
|
||||||
|
render: (h, params) => {
|
||||||
|
return h('span', {}, [
|
||||||
|
h(
|
||||||
|
'el-button',
|
||||||
|
{
|
||||||
|
class: 'floatSpan',
|
||||||
|
props: {
|
||||||
|
type: 'primary',
|
||||||
|
size: 'medium'
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
click: () => this.handleEdit(params.row)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'修改'
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
'el-button',
|
||||||
|
{
|
||||||
|
class: 'floatSpan',
|
||||||
|
props: {
|
||||||
|
type: 'primary',
|
||||||
|
size: 'medium'
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
click: () => this.handlePreview(params.row)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'预览'
|
||||||
|
)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
// 样式可以根据需要调整
|
||||||
|
</style>
|
||||||
@@ -1,15 +1,116 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="splitConfig mt20">
|
||||||
<div class="container">
|
<p class="title">
|
||||||
</div>
|
文件题词规则:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<!-- 自动题词 -->
|
||||||
|
<li class="flex" :class="activeIndex === index ? 'active' : ''" v-for="(item, index) in splitOptions" :key="index" @click="handleClick(index)">
|
||||||
|
<div>
|
||||||
|
<svg v-if="index === 0" t="1744335709188" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2464" width="32" height="32"><path d="M933.868272 511.691752a140.807706 140.807706 0 0 1 90.131728-131.067068 525.562914 525.562914 0 0 0-57.334136-138.64997 139.882962 139.882962 0 0 1-184.948826-184.948826A525.562914 525.562914 0 0 0 643.067068 0a140.376159 140.376159 0 0 1-262.134136 0A525.562914 525.562914 0 0 0 242.282962 57.334136a139.882962 139.882962 0 0 1-184.948826 184.948826A506.698134 506.698134 0 0 0 0 380.932932a140.376159 140.376159 0 0 1 0 262.134136 525.562914 525.562914 0 0 0 57.334136 138.64997 139.882962 139.882962 0 0 1 184.948826 184.948826 525.562914 525.562914 0 0 0 138.64997 57.334136 140.376159 140.376159 0 0 1 262.134136 0 525.562914 525.562914 0 0 0 138.64997-57.334136 139.882962 139.882962 0 0 1 184.948826-184.948826 506.698134 506.698134 0 0 0 57.334136-138.64997A140.807706 140.807706 0 0 1 933.868272 511.691752zM511.691752 652.437809A140.437809 140.437809 0 1 1 652.437809 511.691752 140.499458 140.499458 0 0 1 511.691752 652.437809z" fill="#1D85ED" p-id="2465"></path></svg>
|
||||||
|
<svg v-if="index === 1" t="1744335834635" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7994" width="32" height="32"><path d="M746 181.1c10.3 0 19.4 6.1 23.3 15.6l1 2.3 1.2 2.2 110.4 210c2.9 8.6 0.9 18.3-5.3 25l-0.6 0.7-0.6 0.7-344.5 401.9c-6.4 6.7-14.1 7.7-18.2 7.7s-11.7-1-18.2-7.7L150.1 437.6l-0.6-0.7-0.6-0.7c-6.2-6.8-8.2-16.4-5.3-25l110.4-210 1.2-2.2 1-2.3c3.9-9.5 13.1-15.6 23.3-15.6H746m0-54.6H279.4c-32.3 0-61.4 19.5-73.8 49.3L93.8 388.7c-11.9 28.7-6 61.6 14.9 84.4l345.2 402.7c15.8 17.3 37.3 25.9 58.9 25.9 21.5 0 43-8.6 58.9-25.9l345.2-402.7c20.9-22.9 26.8-55.8 14.9-84.4l-112-212.9c-12.3-29.8-41.5-49.3-73.8-49.3z" p-id="7995" fill="#d81e06"></path><path d="M513.9 524.6c-19.1 0-37.5-8.1-50.4-22.2l-97.7-106.7c-10.2-11.1-9.4-28.4 1.7-38.5 11.1-10.2 28.4-9.4 38.5 1.7l97.7 106.7c3.6 3.9 7.9 4.5 10.2 4.5 2.3 0 6.6-0.6 10.2-4.5l95.5-104.2c10.2-11.1 27.4-11.9 38.5-1.7 11.1 10.2 11.9 27.4 1.7 38.5l-95.5 104.2c-13 14.1-31.3 22.2-50.4 22.2z" p-id="7996" fill="#d81e06"></path></svg>
|
||||||
|
</div>
|
||||||
|
<div class="block">
|
||||||
|
<h3>{{ item.title }}</h3>
|
||||||
|
<p class="tips">{{ item.description }}</p>
|
||||||
|
<p v-if="item.tip" class="tips">{{ item.tip }}</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<!-- 弹窗组件 -->
|
||||||
|
<custom-split-dialog
|
||||||
|
class="active"
|
||||||
|
ref="customTable">
|
||||||
|
</custom-split-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import CustomSplitDialog from './CustomWords.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'splitConfig',
|
||||||
|
components: {
|
||||||
|
CustomSplitDialog
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
activeIndex: 0,
|
||||||
|
splitOptions: [
|
||||||
|
{
|
||||||
|
icon: 'el-icon-setting',
|
||||||
|
title: '自动题词',
|
||||||
|
description: '使用系统默认的题词方式,适合新手或紧急任务,直接使用系统预设题词规则处理文本。',
|
||||||
|
tip: '提示:首次使用时建议先用自动题词测试效果,再决定是否调整。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'el-icon-medal',
|
||||||
|
title: '自定义题词',
|
||||||
|
description: '使用自定义题词方式可以根据具体需求灵活调整文本分割逻辑,但需要权衡灵活性与复杂度,需要用户具备一定的题词经验。',
|
||||||
|
tip: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {},
|
||||||
|
watch: {},
|
||||||
|
filters: {},
|
||||||
|
methods: {
|
||||||
|
handleClick(index) {
|
||||||
|
this.activeIndex = index;
|
||||||
|
if (index === 1) {
|
||||||
|
this.$refs.customTable.init()
|
||||||
|
} else {
|
||||||
|
this.$refs.customTable.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
mounted() {},
|
||||||
|
computed: {}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang='scss'>
|
||||||
|
.splitConfig {
|
||||||
|
.title {
|
||||||
|
font-size: 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
<style scoped lang="scss">
|
li {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 6px;
|
||||||
|
list-style-type: none;
|
||||||
|
width: 80%;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 10px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.block{
|
||||||
|
margin-left: 20px;
|
||||||
|
h3 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.tips{
|
||||||
|
color: #9E9E9E;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.active{
|
||||||
|
border: 1px solid #409EFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
<div class='components'>
|
<div class='components'>
|
||||||
<step-preprocessing v-if='active===0' @getForm='getForm'></step-preprocessing>
|
<step-preprocessing v-if='active===0' @getForm='getForm'></step-preprocessing>
|
||||||
<split-config v-if='active===1'></split-config>
|
<split-config v-if='active===1'></split-config>
|
||||||
|
<words v-if='active===2'></words>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -31,7 +32,8 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import StepPreprocessing from './components/preprocessing.vue'
|
import StepPreprocessing from './components/preprocessing.vue'
|
||||||
import SplitConfig from "@/views/knowledge/detail/components/SplitConfig.vue";
|
import SplitConfig from '@/views/knowledge/detail/components/split/SplitConfig.vue'
|
||||||
|
import Words from '@/views/knowledge/detail/components/words/Index.vue'
|
||||||
// import StepC
|
// import StepC
|
||||||
export default {
|
export default {
|
||||||
name: 'create',
|
name: 'create',
|
||||||
@@ -43,6 +45,7 @@ export default {
|
|||||||
props: {},
|
props: {},
|
||||||
watch: {},
|
watch: {},
|
||||||
components: {
|
components: {
|
||||||
|
Words,
|
||||||
SplitConfig,
|
SplitConfig,
|
||||||
StepPreprocessing
|
StepPreprocessing
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user