mirror of
http://112.124.100.131/ebiz-ai/ebiz-ai-knowledge-manage.git
synced 2025-12-06 17:36:48 +08:00
feat(knowledge): 新增知识库检索设置功能
- 添加检索设置相关 API 和功能组件 - 实现嵌入式模型列表获取和选择 - 添加重新排序模型配置功能 - 实现权重设置和混合检索功能 - 优化检索设置界面布局和交互
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: ['@vue/app'],
|
presets: ['@vue/app'],
|
||||||
plugins: [
|
plugins: [
|
||||||
[
|
// [
|
||||||
'transform-remove-console',
|
// 'transform-remove-console',
|
||||||
{
|
// {
|
||||||
exclude: ['warn', 'error'] // 可选:保留 warn 和 error
|
// exclude: ['warn', 'error'] // 可选:保留 warn 和 error
|
||||||
}
|
// }
|
||||||
]
|
// ]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,3 +10,22 @@ export function getRerankModels() {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @description 知识库检索模式配置
|
||||||
|
*/
|
||||||
|
export function retrievalSetting(data) {
|
||||||
|
return request({
|
||||||
|
url: getUrl('/datasets/detailConfigEx/retrievalSetting'),
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @description 查询系统支持的embedding模型列表
|
||||||
|
*/
|
||||||
|
export function getEmbeddingModels() {
|
||||||
|
return request({
|
||||||
|
url: getUrl('/third/models/text-embedding'),
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
let envInfo = process.env
|
let envInfo = process.env
|
||||||
let [admin, jifen, zixi, hz] = [
|
let [admin, jifen, zixi, hz] = [
|
||||||
envInfo.VUE_APP_ADMIN,
|
envInfo.VUE_APP_ADMIN,
|
||||||
'http://192.168.2.62:7196/',
|
'http://192.168.8.58:7196/',
|
||||||
'http://192.168.8.165:7196/',
|
'http://192.168.8.165:7196/',
|
||||||
'http://10.147.17.161:7196/'
|
'http://10.147.17.161:7196/'
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,51 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-drawer
|
<el-drawer
|
||||||
title="搜索设置"
|
title="检索设置"
|
||||||
:visible.sync="visible"
|
:visible.sync="visible"
|
||||||
size="50%"
|
size="40%"
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
>
|
>
|
||||||
<el-form ref="form" :model="form" label-width="80%" label-position="top">
|
<el-form ref="form" :model="form" label-width="80%" label-position="top">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="10">
|
||||||
<el-form-item label="Embedding模型">
|
<el-form-item label="Embedding模型">
|
||||||
<el-select v-model="form.embeddingModel" placeholder="请选择">
|
<el-select
|
||||||
|
v-model="form.embeddingModel"
|
||||||
|
@change="getModel"
|
||||||
|
placeholder="请选择"
|
||||||
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in modelList"
|
v-for="item in modelList"
|
||||||
:key="item.value"
|
:key="item.model"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value"
|
:value="item.model"
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<!-- <el-form-item label="检索设置">
|
<el-collapse v-model="searchMethod" accordion>
|
||||||
<div class="flex justify-content-b">
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in settingList"
|
|
||||||
:key="item.name"
|
|
||||||
class="setting_item flex"
|
|
||||||
:class="{ activeItem: index === activeIndex }"
|
|
||||||
@click="handleClick(index)"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="@/assets/images/konwledge/knowledge-5.png"
|
|
||||||
alt=""
|
|
||||||
style="height: 40px"
|
|
||||||
/>
|
|
||||||
<div class="ml10">
|
|
||||||
<p class="fwb label fs15">
|
|
||||||
{{ item.name }}
|
|
||||||
<span v-if="index === 2" class="point fs12 ml10">推荐</span>
|
|
||||||
</p>
|
|
||||||
<p class="desc">{{ item.desc }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-form-item>-->
|
|
||||||
<el-collapse v-model="activeName" accordion>
|
|
||||||
<el-collapse-item
|
<el-collapse-item
|
||||||
v-for="(item, index) in settingList"
|
v-for="(item, index) in settingList"
|
||||||
:key="item.name"
|
:key="item.name"
|
||||||
@@ -69,16 +49,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div>
|
<div>
|
||||||
<search-form :activeIndex="activeName"></search-form>
|
<search-form
|
||||||
|
ref="searchForm"
|
||||||
|
:searchMethod="searchMethod"
|
||||||
|
:embeddingItem="embeddingItem"
|
||||||
|
@handleClose="handleClose"
|
||||||
|
></search-form>
|
||||||
</div>
|
</div>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
<div class="demo-drawer__footer mt10 text-right">
|
||||||
|
<el-button @click="handleCancel" size="medium">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSubmit" size="medium"
|
||||||
|
>保存</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import SearchForm from '@/views/knowledge/detail/components/SearchSetting/SearchForm.vue'
|
import SearchForm from '@/views/knowledge/detail/components/SearchSetting/SearchForm.vue'
|
||||||
|
import { getEmbeddingModels } from '@/api/knowledge/hit-test'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SearchSetting',
|
name: 'SearchSetting',
|
||||||
@@ -86,7 +78,9 @@ export default {
|
|||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activeName: 0,
|
// 0-向量检索 1-全文检索 2-混合检索
|
||||||
|
searchMethod: 0,
|
||||||
|
embeddingItem: {},
|
||||||
visible: false,
|
visible: false,
|
||||||
form: {
|
form: {
|
||||||
embeddingModel: '',
|
embeddingModel: '',
|
||||||
@@ -116,15 +110,38 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
this.getModelList()
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 获取Embedding模型列表
|
||||||
|
getModelList() {
|
||||||
|
getEmbeddingModels().then(res => {
|
||||||
|
if (res) {
|
||||||
|
const { content } = res.content
|
||||||
|
this.modelList = content.flatMap(item => item.models)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
init() {
|
init() {
|
||||||
this.visible = true
|
this.visible = true
|
||||||
},
|
},
|
||||||
handleClose() {
|
handleClose() {
|
||||||
this.$emit('close')
|
this.visible = false
|
||||||
},
|
},
|
||||||
handleClick(index) {
|
handleSubmit() {
|
||||||
this.activeIndex = index
|
console.log(this.$refs.searchForm)
|
||||||
|
this.$refs.searchForm[this.searchMethod].submitData()
|
||||||
|
// this.$refs.searchForm.submitData()
|
||||||
|
},
|
||||||
|
handleCancel() {
|
||||||
|
this.visible = false
|
||||||
|
},
|
||||||
|
getModel() {
|
||||||
|
console.log(this.form.embeddingModel)
|
||||||
|
this.embeddingItem = this.modelList.find(
|
||||||
|
item => item.model === this.form.embeddingModel
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="pl10 searchForm_cont">
|
<div class="pl10 searchForm_cont">
|
||||||
<el-form :model="form" label-width="80%" label-position="top">
|
<el-form :model="form" label-width="80%" label-position="top" class="pt20">
|
||||||
<el-form-item label="">
|
<el-form-item label="" v-if="searchMethod !== 2">
|
||||||
<el-switch v-model="form.modelOpen"></el-switch>
|
<el-switch v-model="form.rerankingEnable"></el-switch>
|
||||||
<span>Rerank 模型</span>
|
<span>Rerank 模型</span>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
class="item"
|
class="item"
|
||||||
@@ -13,26 +13,80 @@
|
|||||||
<i class="el-icon-info ml5" style="color: #909399;"></i>
|
<i class="el-icon-info ml5" style="color: #909399;"></i>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-row v-if="activeIndex === 2">
|
<!-- 混合检索 -->
|
||||||
<el-slider v-model="value" :marks="marks"> </el-slider
|
<div v-if="searchMethod === 2" class="flex mb20">
|
||||||
></el-row>
|
<div
|
||||||
<el-row v-else>
|
class="fixItem flex"
|
||||||
<el-col :span="8">
|
v-for="(item, index) in fixSearchList"
|
||||||
|
:key="index"
|
||||||
|
@click="chooseFixSearch(item)"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="@/assets/images/konwledge/knowledge-2.png"
|
||||||
|
alt=""
|
||||||
|
style="height: 30px"
|
||||||
|
/>
|
||||||
|
<div class="ml10">
|
||||||
|
<div class="flex justify-content-b">
|
||||||
|
<p>{{ item.name }}</p>
|
||||||
|
<i
|
||||||
|
class="el-icon-check"
|
||||||
|
v-if="item.isCheck"
|
||||||
|
style="color: #4f47f5"
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>{{ item.desc }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-row
|
||||||
|
v-if="
|
||||||
|
(form.rerankingEnable && searchMethod !== 2) ||
|
||||||
|
(searchMethod === 2 && fixSearchList[1].isCheck === true)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-col :span="10">
|
||||||
<el-form-item label="">
|
<el-form-item label="">
|
||||||
<el-select v-model="form.embeddingModel" placeholder="请选择">
|
<el-select
|
||||||
|
v-model="form.rerankingModelName"
|
||||||
|
@change="getRankModel"
|
||||||
|
placeholder="请选择"
|
||||||
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in modelList"
|
v-for="item in rankModelList"
|
||||||
:key="item.value"
|
:key="item.model"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value"
|
:value="item.model"
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row v-if="searchMethod === 2 && fixSearchList[0].isCheck === true">
|
||||||
|
<RSlider
|
||||||
|
v-model="form.weights"
|
||||||
|
:hit-test="true"
|
||||||
|
:show-tooltip="false"
|
||||||
|
@input="getWeight"
|
||||||
|
style="width: 98%"
|
||||||
|
/>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<!-- Top K -->
|
||||||
<el-col :span="10" class="flex">
|
<el-col :span="10" class="flex">
|
||||||
<el-form-item label="Top K">
|
<el-form-item label="">
|
||||||
|
<div class="flex align-items-c">
|
||||||
|
<p class="ml5 fwb">Top K</p>
|
||||||
|
<el-tooltip
|
||||||
|
class="item"
|
||||||
|
effect="dark"
|
||||||
|
content="用于筛选与用户问题相似度最高的文档片段。系统同时会根据选用模型上下文窗口大小动态调整分段数量。"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<i class="el-icon-info ml5" style="color: #909399;"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="form.topK"
|
v-model="form.topK"
|
||||||
:min="1"
|
:min="1"
|
||||||
@@ -42,53 +96,169 @@
|
|||||||
size="mini"
|
size="mini"
|
||||||
></el-input-number>
|
></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div style="width: 300px;">
|
<div class="ml20 mt40" style="width: 80%;">
|
||||||
<el-slider v-model="value" :min="1" :max="10" :step="1"></el-slider>
|
<el-slider
|
||||||
|
v-model="form.topK"
|
||||||
|
:min="1"
|
||||||
|
:max="10"
|
||||||
|
:step="1"
|
||||||
|
></el-slider>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
<!-- Score阈值-->
|
||||||
<el-row>
|
<el-col :span="10" class="flex">
|
||||||
<el-col :span="10">
|
<el-form-item label="">
|
||||||
<el-form-item label="Score阈值">
|
<template slot="label">
|
||||||
<el-slider
|
<div class="flex align-items-c">
|
||||||
v-model="value"
|
<el-switch v-model="form.scoreThresholdEnabled"></el-switch>
|
||||||
show-input
|
<p class="ml5 fwb">Score阈值</p>
|
||||||
show-input-controls
|
<el-tooltip
|
||||||
|
class="item"
|
||||||
|
effect="dark"
|
||||||
|
content="用于设置文本片段筛选的相似度阈值"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<i class="el-icon-info ml5" style="color: #909399;"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-input-number
|
||||||
|
v-model="form.scoreThreshold"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="1"
|
:max="1"
|
||||||
:step="0.01"
|
:step="0.01"
|
||||||
:precision="2"
|
label="Top K"
|
||||||
></el-slider>
|
controls-position="right"
|
||||||
|
size="mini"
|
||||||
|
:disabled="!form.scoreThresholdEnabled"
|
||||||
|
></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<div class="ml20 mt40" style="width: 80%;">
|
||||||
|
<el-slider
|
||||||
|
v-model="form.scoreThreshold"
|
||||||
|
:disabled="!form.scoreThresholdEnabled"
|
||||||
|
:min="0"
|
||||||
|
:max="1"
|
||||||
|
:step="0.01"
|
||||||
|
></el-slider>
|
||||||
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import { getRerankModels, retrievalSetting } from '@/api/knowledge/hit-test'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SearchForm',
|
name: 'SearchForm',
|
||||||
props: {
|
props: {
|
||||||
activeIndex: {
|
searchMethod: {
|
||||||
type: Number
|
type: Number
|
||||||
|
},
|
||||||
|
embeddingItem: {
|
||||||
|
type: Object
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {
|
form: {
|
||||||
modelOpen: true,
|
// 是否启用rerank模型
|
||||||
embeddingModel: 'sentence-transformers/all-MiniLM-L6-v2',
|
rerankingEnable: true,
|
||||||
topK: 3,
|
// Rerank模型
|
||||||
scoreThreshold: 0.5
|
rerankingModelName: '',
|
||||||
|
rerankingProviderName: '',
|
||||||
|
|
||||||
|
topK: 0,
|
||||||
|
|
||||||
|
// 是否启用score阈值
|
||||||
|
scoreThresholdEnabled: false,
|
||||||
|
// score阈值
|
||||||
|
scoreThreshold: 0,
|
||||||
|
|
||||||
|
// 混合模式- reranking_model:使用rerank模型; weighted_score:使用权重
|
||||||
|
rerankingMode: '',
|
||||||
|
// 关键词
|
||||||
|
keywordWeight: 0,
|
||||||
|
// 语义
|
||||||
|
vectorWeight: 0
|
||||||
},
|
},
|
||||||
modelList: [
|
rankModelList: [
|
||||||
{
|
{
|
||||||
value: 'sentence-transformers/all-MiniLM-L6-v2',
|
value: 'sentence-transformers/all-MiniLM-L6-v2',
|
||||||
label: 'sentence-transformers/all-MiniLM-L6-v2'
|
label: 'sentence-transformers/all-MiniLM-L6-v2'
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
|
],
|
||||||
|
fixSearchList: [
|
||||||
|
{
|
||||||
|
name: '权重设置',
|
||||||
|
desc:
|
||||||
|
'通过调整分配的权重,重新排序策略确定是优先进行语义匹配还是关键字匹配',
|
||||||
|
isCheck: true,
|
||||||
|
value: 'weighted_score'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Rerank 模型',
|
||||||
|
value: 'reranking_model',
|
||||||
|
desc:
|
||||||
|
'重排序模型将根据候选文档列表与用户问题语义匹配度进行重新排序,从而改进语义排序的结果'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getRerankModelList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getRerankModelList() {
|
||||||
|
getRerankModels().then(res => {
|
||||||
|
if (res) {
|
||||||
|
const { content } = res.content
|
||||||
|
this.rankModelList = content.flatMap(item => item.models)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getRankModel() {
|
||||||
|
let rankItem = this.rankModelList.find(
|
||||||
|
item => item.model === this.form.rerankingModelName
|
||||||
|
)
|
||||||
|
this.form.rerankingProviderName = rankItem.provider
|
||||||
|
},
|
||||||
|
chooseFixSearch(val) {
|
||||||
|
this.fixSearchList.forEach(item => {
|
||||||
|
item.isCheck = false
|
||||||
|
})
|
||||||
|
val.isCheck = true
|
||||||
|
this.form.rerankingMode = val.value
|
||||||
|
},
|
||||||
|
getWeight(val) {
|
||||||
|
console.log(val)
|
||||||
|
},
|
||||||
|
submitData() {
|
||||||
|
let params = {
|
||||||
|
datasetId: this.$route.query.datasetId,
|
||||||
|
searchMethod: this.searchMethod,
|
||||||
|
embeddingModel: this.embeddingItem.model,
|
||||||
|
embeddingModelProvider: this.embeddingItem.provider,
|
||||||
|
...this.form
|
||||||
|
}
|
||||||
|
params.rerankingEnable = this.handleBoolean(this.form.rerankingEnable)
|
||||||
|
params.scoreThresholdEnabled = this.handleBoolean(
|
||||||
|
this.form.scoreThresholdEnabled
|
||||||
|
)
|
||||||
|
retrievalSetting(params).then(res => {
|
||||||
|
if (res) {
|
||||||
|
this.$message.success('保存成功')
|
||||||
|
this.$emit('handleClose')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleBoolean(val) {
|
||||||
|
let value = JSON.parse(JSON.stringify(val))
|
||||||
|
return value ? 1 : 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -100,4 +270,10 @@ export default {
|
|||||||
border-bottom: 1px solid #ebeef5;
|
border-bottom: 1px solid #ebeef5;
|
||||||
border-radius: 0 5px 5px 0;
|
border-radius: 0 5px 5px 0;
|
||||||
}
|
}
|
||||||
|
.fixItem {
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
margin-right: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -16,11 +16,12 @@
|
|||||||
v-for="(item, index) in list"
|
v-for="(item, index) in list"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="block flex justify-content-b "
|
class="block flex justify-content-b "
|
||||||
|
style="align-items: baseline"
|
||||||
>
|
>
|
||||||
<div class="flex">
|
<div class="flex" style="align-items: baseline">
|
||||||
<i class="el-icon-reading"></i>
|
<i class="el-icon-reading"></i>
|
||||||
<p class="ml5 mr5">{{ item.metadataKey }}</p>
|
<p class="ml5 mr10">{{ item.metadataKey }}</p>
|
||||||
<p>{{ item.dataType }}</p>
|
<p class="fs12">{{ item.dataType }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex align-items-c" >
|
<div class="flex align-items-c" >
|
||||||
<div class="amount">{{ item.amount ? item.amount :0}}个值</div>
|
<div class="amount">{{ item.amount ? item.amount :0}}个值</div>
|
||||||
|
|||||||
@@ -65,14 +65,14 @@
|
|||||||
@click="jumpEditKnowledge"
|
@click="jumpEditKnowledge"
|
||||||
>修改知识库
|
>修改知识库
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- <el-button-->
|
<el-button
|
||||||
<!-- type="primary"-->
|
type="primary"
|
||||||
<!-- size="medium"-->
|
size="medium"
|
||||||
<!-- icon="el-icon-search"-->
|
icon="el-icon-search"
|
||||||
<!-- class="line-button"-->
|
class="line-button"
|
||||||
<!-- @click="searchSetting"-->
|
@click="searchSetting"
|
||||||
<!-- >检索设置-->
|
>检索设置
|
||||||
<!-- </el-button>-->
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-s-promotion"
|
icon="el-icon-s-promotion"
|
||||||
|
|||||||
Reference in New Issue
Block a user