|
@@ -0,0 +1,811 @@ |
|
|
|
|
|
<template> |
|
|
|
|
|
<div class="box-center"> |
|
|
|
|
|
<div class="app-top"> |
|
|
|
|
|
<div class="control-tab"> |
|
|
|
|
|
<el-radio-group v-model="type" size="medium" @change="changeType"> |
|
|
|
|
|
<el-radio-button :label="1">待处理</el-radio-button> |
|
|
|
|
|
<el-radio-button :label="0">已处理</el-radio-button> |
|
|
|
|
|
</el-radio-group> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="app-titel" style="margin-top: 5px"> |
|
|
|
|
|
<div class="label">更新时间:</div> |
|
|
|
|
|
<el-date-picker |
|
|
|
|
|
style="width: 270px;" |
|
|
|
|
|
@change="confirmtime" |
|
|
|
|
|
v-model="searchForm.customtime" |
|
|
|
|
|
type="daterange" |
|
|
|
|
|
range-separator="-" |
|
|
|
|
|
value-format="yyyy-MM-dd" |
|
|
|
|
|
start-placeholder="开始日期" |
|
|
|
|
|
end-placeholder="结束日期" |
|
|
|
|
|
></el-date-picker> |
|
|
|
|
|
<div class="label">名称: |
|
|
|
|
|
<el-input placeholder="处理人" v-model="searchForm.updateUserName" style="width:140px"></el-input> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="label" v-if="type==0">处理人: |
|
|
|
|
|
<el-input placeholder="处理人" v-model="searchForm.updateUserName" style="width:140px"></el-input> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="label">项目名称: |
|
|
|
|
|
<el-input placeholder="处理人" v-model="searchForm.updateUserName" style="width:140px"></el-input> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div style="margin-left: 20px"> |
|
|
|
|
|
<el-button @click="Screening" type="primary">筛选</el-button> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<el-table |
|
|
|
|
|
:data="tableData" |
|
|
|
|
|
stripe |
|
|
|
|
|
:header-cell-style="{ |
|
|
|
|
|
background: '#F7F8FA', |
|
|
|
|
|
borderColor: '#E0E0E0', |
|
|
|
|
|
color: '#606775', |
|
|
|
|
|
}" |
|
|
|
|
|
style="width: 100%;margin-top:20px" |
|
|
|
|
|
> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="createTime" |
|
|
|
|
|
label="更新时间" |
|
|
|
|
|
align="center" |
|
|
|
|
|
> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column prop="type" label="类型" align="center"> |
|
|
|
|
|
<template slot-scope="scope"> |
|
|
|
|
|
<!-- 0需求挖掘 1销讲词 2客户标签 3违禁 --> |
|
|
|
|
|
<span v-if="scope.row.type==1">销讲话术</span> |
|
|
|
|
|
<span v-if="scope.row.type==2">客户标签</span> |
|
|
|
|
|
<span v-if="scope.row.type==0">挖掘话术</span> |
|
|
|
|
|
<span v-if="scope.row.type==3">违禁词</span> |
|
|
|
|
|
</template> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column prop="level1Name" label="一级分类" align="center"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column prop="name" label="名称" align="center"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column prop="houseName" label="项目" align="center"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column prop="updateTime" label="处理时间" align="center" v-if="type==0"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column prop="updateUserName" label="处理人" v-if="type==0" align="center"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column label="操作" align="center"> |
|
|
|
|
|
<template slot-scope="scope"> |
|
|
|
|
|
<div |
|
|
|
|
|
style="color: #2671e2; cursor: pointer" |
|
|
|
|
|
@click="editFun(scope.row)" |
|
|
|
|
|
> |
|
|
|
|
|
匹配模型 |
|
|
|
|
|
</div> |
|
|
|
|
|
</template> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
</el-table> |
|
|
|
|
|
<div class="block"> |
|
|
|
|
|
<div class="blockbox"> |
|
|
|
|
|
<el-pagination |
|
|
|
|
|
@size-change="handleSizeChange" |
|
|
|
|
|
@current-change="handleCurrentChange" |
|
|
|
|
|
:current-page="pageNum" |
|
|
|
|
|
:page-sizes="[10, 20, 30, 40, 50, 100]" |
|
|
|
|
|
:page-size="pageSize" |
|
|
|
|
|
layout="total, sizes, prev, pager, next, jumper" |
|
|
|
|
|
:total="total" |
|
|
|
|
|
> |
|
|
|
|
|
</el-pagination> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<el-dialog |
|
|
|
|
|
title="编辑模型" |
|
|
|
|
|
@open="openModel" |
|
|
|
|
|
:close-on-click-modal="false" |
|
|
|
|
|
:visible.sync="dialogVisible" |
|
|
|
|
|
> |
|
|
|
|
|
<el-dialog |
|
|
|
|
|
title="匹配规则" |
|
|
|
|
|
:visible.sync="innerVisible" |
|
|
|
|
|
append-to-body> |
|
|
|
|
|
<div style="max-height: 430px;overflow: auto"> |
|
|
|
|
|
<p><b>匹配距离</b>:关键字匹配字数距离,主要针对near/after/w- 生效,w- 的字数统计从挖掘话术后,客户的第一句话开始统计;</p> |
|
|
|
|
|
<p style="padding-left: 15px">例如:设置为10,面积 after 140</br> |
|
|
|
|
|
命中话术:"想买一个面积在140平的"</br> |
|
|
|
|
|
超出10个字,有关键字不命中话术参考:“房屋面积啊,你们这边有多大的,有没有140平左右的”;</p> |
|
|
|
|
|
<p><b>or(或)</b>:多个关键词,匹配上1个就行</p> |
|
|
|
|
|
<p style="padding-left: 15px">例如标签:自住</br> |
|
|
|
|
|
匹配模型:自己住 or 给自己</br> |
|
|
|
|
|
命中话术:我们自己住/给自己买的</p> |
|
|
|
|
|
<p><b>and not(非)</b>:排除反面意思</p> |
|
|
|
|
|
<p style="padding-left: 15px">例如:北京户口,</br> |
|
|
|
|
|
匹配模型:是北京户口 and not 不是北京户口</br> |
|
|
|
|
|
命中话术:我是北京户口;</br> |
|
|
|
|
|
反面话术:我不是北京户口</p> |
|
|
|
|
|
<p><b>near ( 临近)</b>:1个关键词前后一定范围出现过另一个关键词就算命中,有距离限制</p> |
|
|
|
|
|
<p style="padding-left: 15px">例如标签:购房预算 140w</br> |
|
|
|
|
|
匹配模型:预算 near 140</br> |
|
|
|
|
|
命中话术:我的预算是140w或大概140w的购房预算</p> |
|
|
|
|
|
<p><b>after(后面)</b>:一段文本出现2个关键词,并且按照先后的顺序即算命中,有距离限制</p> |
|
|
|
|
|
<p style="padding-left: 15px">例如标签:意向面积 140平</br> |
|
|
|
|
|
匹配模型: 面积 after 140 ,140在面积后面才算生效;</br> |
|
|
|
|
|
命中话术:想买一个面积在140平的;</p> |
|
|
|
|
|
<p><b>answer(挖掘话术业务)</b>:顾问执行了挖掘话术,客户回答结果,有距离限制,从客户话术文本开始</p> |
|
|
|
|
|
<p style="padding-left: 15px">例如标签:北京户口</br> |
|
|
|
|
|
匹配模型:(w-是 or w-有) and not (w-不是 or w-没有)</br> |
|
|
|
|
|
命中话术:销售:你有北京户口吗?</br> |
|
|
|
|
|
客户:有的;</p> |
|
|
|
|
|
<p><b>-n(命中距离)</b>:near/after-n ,单个near/after的匹配距离,n大于0,小于500</p> |
|
|
|
|
|
<p style="padding-left: 15px">例如 :面积 after-10 140</br> |
|
|
|
|
|
10个字内,命中话术参考:"想买一个面积在140平的"</br> |
|
|
|
|
|
超出10个字,有关键字不命中话术参考:“房屋面积啊,你们这边有多大的,有没有140平左右的”;</p> |
|
|
|
|
|
<p><b>注意</b>:-n 与 near/after/answer 之间<b>不能有空格</b>;</p></br> |
|
|
|
|
|
<p><b>注意</b>:优先匹配关键词可以排在前面;</p> |
|
|
|
|
|
</div> |
|
|
|
|
|
</el-dialog> |
|
|
|
|
|
<el-form ref="form" size="mini" :inline="true" :model="form" label-position="right"> |
|
|
|
|
|
<el-form-item :label="keyType==0?'挖掘话术:':'标签名称:'"> |
|
|
|
|
|
<div style="max-width:400px;min-width: 200px;font-weight: bold">{{form.keywordsName}}</div> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="场景描述:" > |
|
|
|
|
|
<div v-if="form.sceneDesc" style="width:500px;border: 1px dashed #ccc;padding:5px 10px;line-height: 25px"> {{form.sceneDesc}}</div> |
|
|
|
|
|
<div v-else>暂无描述</div> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="after,near,answer 匹配距离:"> |
|
|
|
|
|
<el-input-number v-model="form.distance" controls-position="right" :min="0" :max="500"></el-input-number></el-input><span style="color:red;margin-left:10px">*请输入0~500内的整数</span> <el-button type="text" style="margin-left:30px" @click="innerVisible=true">规则说明</el-button> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<div contentEditable="true" |
|
|
|
|
|
@click="myeditorenter($event)" |
|
|
|
|
|
@keypress.enter="myeditorenter($event)" |
|
|
|
|
|
@blur="saveRange" |
|
|
|
|
|
class="editDiv" |
|
|
|
|
|
id="huashuModel"> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div v-if="keyType==0||dynamiclist.length">{{keyType==0?'匹配标签:':'需求挖掘匹配:'}}</div> |
|
|
|
|
|
<!-- keyType 0需求挖掘 1销讲词 2客户标签 3违禁 --> |
|
|
|
|
|
<div class="dynamicbox" v-if="keyType==0"> |
|
|
|
|
|
<div v-for="(item,index) in dynamiclist" :key="item" class="itemlist"> |
|
|
|
|
|
<el-select size="small" v-model="item.markid" @change="checkrepeat" placeholder="标签" clearable> |
|
|
|
|
|
<el-option v-for="(mark,i) in wajueList" :disabled="mark.disabled" :key="i" :label="mark.name" :value="mark.id"></el-option> |
|
|
|
|
|
</el-select> |
|
|
|
|
|
<div contentEditable="true" |
|
|
|
|
|
@click="myeditorenter($event)" |
|
|
|
|
|
@keypress.enter="myeditorenter($event)" |
|
|
|
|
|
@blur="saveRange" |
|
|
|
|
|
class="item-input" |
|
|
|
|
|
v-html="item.editValue" |
|
|
|
|
|
:id="'huashuModel'+index"></div> |
|
|
|
|
|
<el-button size="small" type="primary" @click="delItemFun(index)">删除</el-button> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="dynamicbox" v-else> |
|
|
|
|
|
<div v-for="item in dynamiclist" :key="item" class="itemlist"> |
|
|
|
|
|
<el-input size="small" disabled style="width: 220px" v-model="item.question"></el-input> |
|
|
|
|
|
<div class="item-input" style="pointer-events: none;" v-html="item.editValue"></div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div> |
|
|
|
|
|
<el-button :disabled="dynamiclist.length==wajueList.length" v-if="keyType==0" @click="addItemFun" icon="el-icon-plus" type="primary" size="mini" style="width: 120px;margin:20px 0;"></el-button> |
|
|
|
|
|
</div> |
|
|
|
|
|
<el-form-item label="插入节点:"> |
|
|
|
|
|
<el-button size="mini" type="primary" plain style="margin-left:8px;" v-for="(item,index) in taglist" :key="index" @click="insertTag(item,index)">{{item.label}}</el-button> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
</el-form> |
|
|
|
|
|
<span slot="footer" class="dialog-footer"> |
|
|
|
|
|
<el-button @click="dialogVisible = false">取 消</el-button> |
|
|
|
|
|
<el-button type="primary" @click="saveFun">保 存</el-button> |
|
|
|
|
|
</span> |
|
|
|
|
|
</el-dialog> |
|
|
|
|
|
</div> |
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
<script> |
|
|
|
|
|
export default { |
|
|
|
|
|
data() { |
|
|
|
|
|
return { |
|
|
|
|
|
huashu: '', |
|
|
|
|
|
wajueList: [], |
|
|
|
|
|
level: '', |
|
|
|
|
|
innerVisible:false, |
|
|
|
|
|
dialogVisible: false, |
|
|
|
|
|
dynamiclist: [], |
|
|
|
|
|
taglist:[ |
|
|
|
|
|
{ |
|
|
|
|
|
label: 'or (或)', |
|
|
|
|
|
value: 'or' |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
label: 'near (临近)', |
|
|
|
|
|
value: 'near' |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
label: 'after (后面)', |
|
|
|
|
|
value: 'after' |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
label: 'and not (非)', |
|
|
|
|
|
value: 'andnot' |
|
|
|
|
|
}, |
|
|
|
|
|
// { |
|
|
|
|
|
// label: '~ (至)', |
|
|
|
|
|
// value: '~' |
|
|
|
|
|
// }, |
|
|
|
|
|
], |
|
|
|
|
|
form: { |
|
|
|
|
|
keywordsName: '', |
|
|
|
|
|
id: '', |
|
|
|
|
|
keywordsId: '', |
|
|
|
|
|
distance: 10, |
|
|
|
|
|
sceneDesc:'', |
|
|
|
|
|
originalExpression: '' |
|
|
|
|
|
}, |
|
|
|
|
|
searchForm:{ |
|
|
|
|
|
updateUserName: '', |
|
|
|
|
|
houseName: '', |
|
|
|
|
|
name:'', |
|
|
|
|
|
customtime: [], |
|
|
|
|
|
startTime:'',//搜索开始时间 |
|
|
|
|
|
endTime:'' //搜索结束时间 |
|
|
|
|
|
}, |
|
|
|
|
|
tableData: [{}], |
|
|
|
|
|
type: 1, |
|
|
|
|
|
keyType: '', |
|
|
|
|
|
pageSize: 10, |
|
|
|
|
|
total: 0, |
|
|
|
|
|
pageNum: 1, |
|
|
|
|
|
currentHouseId: '' |
|
|
|
|
|
}; |
|
|
|
|
|
}, |
|
|
|
|
|
mounted() { |
|
|
|
|
|
// this.houseId = localStorage.getItem("AitemId"); |
|
|
|
|
|
// this.gettableList() |
|
|
|
|
|
}, |
|
|
|
|
|
methods: { |
|
|
|
|
|
// keytype =0,获取需求挖掘类型的数据回显接口 |
|
|
|
|
|
wajuehuixian(){ |
|
|
|
|
|
// 获取模型数据回显 |
|
|
|
|
|
axios({ |
|
|
|
|
|
url: `${jypath}/zk/keymodel/findById`, |
|
|
|
|
|
method: 'get', |
|
|
|
|
|
params: { |
|
|
|
|
|
houseId: this.currentHouseId, |
|
|
|
|
|
level: this.level, |
|
|
|
|
|
keyType: 0, |
|
|
|
|
|
questionId: this.questionId, |
|
|
|
|
|
keywordsId: this.form.keywordsId |
|
|
|
|
|
} |
|
|
|
|
|
}).then(res => { |
|
|
|
|
|
this.dialogVisible = true |
|
|
|
|
|
if (res.data.res == 1) { |
|
|
|
|
|
let obj = res.data.obj |
|
|
|
|
|
if(obj!=null){ |
|
|
|
|
|
this.form.distance=obj.distance||10 |
|
|
|
|
|
this.form.originalExpression= obj.originalExpression |
|
|
|
|
|
this.form.id = obj.id |
|
|
|
|
|
this.form.sceneDesc = obj.desc||'' |
|
|
|
|
|
|
|
|
|
|
|
// 回显标签模型数据 |
|
|
|
|
|
if(obj.answerList&&obj.answerList.length){ |
|
|
|
|
|
this.dynamiclist = obj.answerList.map(obj1=>{ |
|
|
|
|
|
return { |
|
|
|
|
|
id: obj1.id, |
|
|
|
|
|
mark: obj1.name, |
|
|
|
|
|
level: obj1.level3Id?3:2, |
|
|
|
|
|
editValue: obj1.originalExpression, |
|
|
|
|
|
markid:obj1.level3Id?obj1.level3Id:obj1.level2Id |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
this.wajueList.forEach(item=>{ |
|
|
|
|
|
this.dynamiclist.forEach(obj=>{ |
|
|
|
|
|
if(item.id==obj.markid){ |
|
|
|
|
|
item.disabled = true |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
}) |
|
|
|
|
|
// console.log(this.dynamiclist) |
|
|
|
|
|
}else{ |
|
|
|
|
|
this.dynamiclist = [] |
|
|
|
|
|
} |
|
|
|
|
|
}else{ |
|
|
|
|
|
this.form.distance=10 |
|
|
|
|
|
this.form.originalExpression= '' |
|
|
|
|
|
this.form.id ='' |
|
|
|
|
|
this.form.sceneDesc = '' |
|
|
|
|
|
this.dynamiclist = [] |
|
|
|
|
|
} |
|
|
|
|
|
}else{ |
|
|
|
|
|
this.form.sceneDesc = '' |
|
|
|
|
|
this.form.distance = 10 |
|
|
|
|
|
this.form.originalExpression = data.name |
|
|
|
|
|
} |
|
|
|
|
|
this.$nextTick(()=>{ |
|
|
|
|
|
let huashuModel = document.getElementById('huashuModel') |
|
|
|
|
|
huashuModel.innerHTML = this.form.originalExpression |
|
|
|
|
|
}) |
|
|
|
|
|
}).catch((e)=>{ |
|
|
|
|
|
this.dialogVisible = true |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
|
|
|
otherhuixian(type){ |
|
|
|
|
|
// 获取模型数据回显 |
|
|
|
|
|
axios({ |
|
|
|
|
|
url: `${jypath}/zk/keymodel/findById`, |
|
|
|
|
|
method: 'get', |
|
|
|
|
|
params: { |
|
|
|
|
|
houseId: this.currentHouseId, |
|
|
|
|
|
level: type==3?1:this.level, |
|
|
|
|
|
keyType: type, |
|
|
|
|
|
keywordsId: this.form.keywordsId |
|
|
|
|
|
} |
|
|
|
|
|
}).then(res => { |
|
|
|
|
|
this.dialogVisible = true |
|
|
|
|
|
if (res.data.res == 1) { |
|
|
|
|
|
let obj = res.data.obj |
|
|
|
|
|
if(obj!=null){ |
|
|
|
|
|
this.form.distance=obj.distance||10 |
|
|
|
|
|
this.form.originalExpression= obj.originalExpression||'' |
|
|
|
|
|
this.form.id =obj.id||'' |
|
|
|
|
|
this.form.sceneDesc = obj.desc||'' |
|
|
|
|
|
// 回显标签模型数据 |
|
|
|
|
|
if(obj.answerList&&obj.answerList.length){ |
|
|
|
|
|
this.dynamiclist = obj.answerList.map(cont=>{ |
|
|
|
|
|
return { |
|
|
|
|
|
question: cont.question, |
|
|
|
|
|
editValue: cont.originalExpression |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
console.log(this.dynamiclist) |
|
|
|
|
|
}else{ |
|
|
|
|
|
this.dynamiclist = [] |
|
|
|
|
|
} |
|
|
|
|
|
}else{ |
|
|
|
|
|
this.form.distance=10 |
|
|
|
|
|
this.form.originalExpression= '' |
|
|
|
|
|
this.form.id ='' |
|
|
|
|
|
this.form.sceneDesc = '' |
|
|
|
|
|
} |
|
|
|
|
|
}else{ |
|
|
|
|
|
this.form.distance = 10 |
|
|
|
|
|
this.form.originalExpression = '' |
|
|
|
|
|
this.form.sceneDesc = '' |
|
|
|
|
|
} |
|
|
|
|
|
this.$nextTick(()=>{ |
|
|
|
|
|
let huashuModel = document.getElementById('huashuModel') |
|
|
|
|
|
huashuModel.innerHTML = this.form.originalExpression |
|
|
|
|
|
}) |
|
|
|
|
|
}).catch((e)=>{ |
|
|
|
|
|
this.dialogVisible = true |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
|
|
|
//点击编辑按钮 |
|
|
|
|
|
async editFun(item){ |
|
|
|
|
|
this.keyType = item.type |
|
|
|
|
|
this.todoId = item.id |
|
|
|
|
|
this.level = item.level |
|
|
|
|
|
this.form.keywordsId = item.keywordsId |
|
|
|
|
|
this.currentHouseId = item.houseId |
|
|
|
|
|
this.form.distance = item.distance||10 |
|
|
|
|
|
let level1Id = item.level1 |
|
|
|
|
|
this.form.keywordsName = item.name |
|
|
|
|
|
await this.findKeywordsById(level1Id)// 获取标签下拉数据 |
|
|
|
|
|
if(item.type==0){// 挖掘话术类型 |
|
|
|
|
|
this.questionId = item.wordId |
|
|
|
|
|
this.wajuehuixian(level1Id) |
|
|
|
|
|
}else{ |
|
|
|
|
|
this.otherhuixian(item.type) |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
// 处理标签,删除不需要的标签格式 |
|
|
|
|
|
delMark(str) { |
|
|
|
|
|
const hasStr = (str) => { |
|
|
|
|
|
let index = str.indexOf('<') |
|
|
|
|
|
let index1 = str.indexOf('>') |
|
|
|
|
|
if(index>0&&index1>0){ |
|
|
|
|
|
let replaceStr= str.substring(index, index1+1) |
|
|
|
|
|
str= str.replace(replaceStr,'') |
|
|
|
|
|
hasStr(str) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
hasStr(str) |
|
|
|
|
|
}, |
|
|
|
|
|
// 处理模型 关键词加#号 |
|
|
|
|
|
replaceFun(str){ |
|
|
|
|
|
let temp = str |
|
|
|
|
|
temp = temp.replace(/<text>\ \;<\/text>/g,''); |
|
|
|
|
|
temp = temp.replace(/\ \;/g,''); |
|
|
|
|
|
temp = temp.replace(/<text>/g,''); |
|
|
|
|
|
temp = temp.replace(/<\/text>/g,''); |
|
|
|
|
|
temp = temp.replace(/<span contenteditable="false" style="color:red">/g,' #');// 后台返回是这样的,变了,需要也处理一下 |
|
|
|
|
|
temp = temp.replace(/<span style="color:red" contenteditable="false">/g,' #'); |
|
|
|
|
|
temp = temp.replace(/<\/span>/g,'#') |
|
|
|
|
|
// console.log(temp); |
|
|
|
|
|
// console.log('截取前',temp); |
|
|
|
|
|
this.delMark(temp); |
|
|
|
|
|
return temp |
|
|
|
|
|
}, |
|
|
|
|
|
//修改保存标签模型 |
|
|
|
|
|
saveFun(){ |
|
|
|
|
|
if(this.cansave) return ; // 防止多次点击 |
|
|
|
|
|
this.cansave = true; |
|
|
|
|
|
let text = document.getElementById('huashuModel'); |
|
|
|
|
|
let answerList = [] |
|
|
|
|
|
// console.log(text.innerHTML); |
|
|
|
|
|
// console.log(text.innerText); |
|
|
|
|
|
let temp = text.innerHTML |
|
|
|
|
|
if(this.form.distance=='') {this.$message.error('请输入距离'); return;} |
|
|
|
|
|
if(text.innerText=='') {this.$message.error('请输入标签模型'); return;} |
|
|
|
|
|
if(this.keyType==0){ |
|
|
|
|
|
for (var i=0;i<this.dynamiclist.length;i++){ |
|
|
|
|
|
if(!this.dynamiclist[i].markid) {this.$message.error('请完善要选择的标签'); return ;} |
|
|
|
|
|
this.wajueList.map(item1=>{ |
|
|
|
|
|
if(item1.id==this.dynamiclist[i].markid){ |
|
|
|
|
|
this.dynamiclist[i].level = item1.level |
|
|
|
|
|
this.dynamiclist[i].name = item1.name |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
let huashuModel = document.getElementById('huashuModel'+i); |
|
|
|
|
|
if(huashuModel.innerText=='') {this.$message.error('请完善选择的标签模型'); return ;} |
|
|
|
|
|
this.dynamiclist[i].editValue = huashuModel.innerHTML |
|
|
|
|
|
this.dynamiclist[i].editText = huashuModel.innerText |
|
|
|
|
|
} |
|
|
|
|
|
answerList = this.dynamiclist.map(item=>{ |
|
|
|
|
|
return { |
|
|
|
|
|
keyType: 2, |
|
|
|
|
|
id: item.id||null, |
|
|
|
|
|
level: item.level, |
|
|
|
|
|
keywordsId: item.markid, |
|
|
|
|
|
showFormatExpression: item.editText,//文本形式 |
|
|
|
|
|
formatExpression: this.replaceFun(item.editValue),// 问题表达式,关键词加#号 |
|
|
|
|
|
originalExpression: item.editValue // html==带span标签 |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
axios({ |
|
|
|
|
|
url: `${jypath}/zk/keymodel/updateKeywordsModel`, |
|
|
|
|
|
method: 'post', |
|
|
|
|
|
data: { |
|
|
|
|
|
id:this.form.id, |
|
|
|
|
|
questionId: this.keyType==0?this.questionId:'', |
|
|
|
|
|
houseId:this.currentHouseId, |
|
|
|
|
|
keyType: this.keyType, |
|
|
|
|
|
level: this.keyType==3?1:this.level, |
|
|
|
|
|
todoId: this.todoId, |
|
|
|
|
|
keywordsId: this.form.keywordsId, |
|
|
|
|
|
keywordsName: this.form.keywordsName, |
|
|
|
|
|
formatExpression: this.replaceFun(temp),// 问题表达式,关键词加#号 |
|
|
|
|
|
originalExpression: temp, // html==带span标签 |
|
|
|
|
|
answerList: answerList, |
|
|
|
|
|
showFormatExpression: text.innerText, |
|
|
|
|
|
} |
|
|
|
|
|
}).then(data => { |
|
|
|
|
|
this.cansave = false; |
|
|
|
|
|
this.dialogVisible = false |
|
|
|
|
|
if(data.data.res==1){ |
|
|
|
|
|
this.$message.success(data.data.obj) |
|
|
|
|
|
this.gettableList() |
|
|
|
|
|
}else{ |
|
|
|
|
|
this.$message.error(data.data.resMsg) |
|
|
|
|
|
} |
|
|
|
|
|
}).catch((e)=>{ |
|
|
|
|
|
this.cansave = false; |
|
|
|
|
|
this.dialogVisible = false |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
|
|
|
// 校验是否已经选择过此标签 |
|
|
|
|
|
checkrepeat(){ |
|
|
|
|
|
this.wajueList.forEach(item=>{ |
|
|
|
|
|
item.disabled = false |
|
|
|
|
|
}) |
|
|
|
|
|
this.wajueList.forEach(item=>{ |
|
|
|
|
|
this.dynamiclist.forEach(obj=>{ |
|
|
|
|
|
if(item.id==obj.markid){ |
|
|
|
|
|
item.disabled = true |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
|
|
|
addItemFun(){ |
|
|
|
|
|
this.dynamiclist.push({ |
|
|
|
|
|
editValue: '',//匹配模型正则表达式 |
|
|
|
|
|
markid:'', |
|
|
|
|
|
level: '', |
|
|
|
|
|
name:'' |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
delItemFun(index){ |
|
|
|
|
|
this.wajueList.forEach(item=>{ |
|
|
|
|
|
if(item.id==this.dynamiclist[index].markid){ |
|
|
|
|
|
item.disabled = false |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
this.dynamiclist.splice(index,1); |
|
|
|
|
|
document.getElementById('huashuModel').focus(); |
|
|
|
|
|
}, |
|
|
|
|
|
// 基于保存的光标插入内容 --用于失去焦点后再继续插入内容 |
|
|
|
|
|
insertContent(str) { |
|
|
|
|
|
let selection, range = window._range;// 当前光标位置对象 |
|
|
|
|
|
if (!window.getSelection) { |
|
|
|
|
|
range.pasteHTML(str); |
|
|
|
|
|
range.collapse(false); |
|
|
|
|
|
range.select(); |
|
|
|
|
|
} else { |
|
|
|
|
|
selection = window.getSelection ? window.getSelection() : document.selection; |
|
|
|
|
|
range.collapse(false); |
|
|
|
|
|
let hasR = range.createContextualFragment(str); |
|
|
|
|
|
let hasR_lastChild = hasR.lastChild; |
|
|
|
|
|
while (hasR_lastChild && hasR_lastChild.nodeName.toLowerCase() == "br" && hasR_lastChild.previousSibling && hasR_lastChild.previousSibling.nodeName.toLowerCase() == "br") { |
|
|
|
|
|
let e = hasR_lastChild; |
|
|
|
|
|
hasR_lastChild = hasR_lastChild.previousSibling; |
|
|
|
|
|
hasR.removeChild(e); |
|
|
|
|
|
} |
|
|
|
|
|
range.insertNode(hasR); |
|
|
|
|
|
if (hasR_lastChild) { |
|
|
|
|
|
range.setEndAfter(hasR_lastChild); |
|
|
|
|
|
range.setStartAfter(hasR_lastChild); |
|
|
|
|
|
} |
|
|
|
|
|
selection.removeAllRanges(); |
|
|
|
|
|
selection.addRange(range); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
// 失去焦点时保存光标位置,记录光标位置 |
|
|
|
|
|
saveRange: () => { |
|
|
|
|
|
let selection = window.getSelection ? window.getSelection() : document.selection; |
|
|
|
|
|
if (!selection.rangeCount) return; |
|
|
|
|
|
let range = selection.createRange ? selection.createRange() : selection.getRangeAt(0); |
|
|
|
|
|
window._range = range; |
|
|
|
|
|
}, |
|
|
|
|
|
// 回显模型数据,Dialog 的内容是懒渲染的,即在第一次被打开之前,传入的默认 slot 不会被渲染到 DOM 上,so在 open 事件回调中进行 |
|
|
|
|
|
openModel(){ |
|
|
|
|
|
this.$nextTick(()=>{ |
|
|
|
|
|
let huashuModel = document.getElementById('huashuModel') |
|
|
|
|
|
huashuModel.innerHTML = this.form.originalExpression |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
|
|
|
//格式化粘贴文本方法 |
|
|
|
|
|
onPaste(event) { |
|
|
|
|
|
var e = event || window.event |
|
|
|
|
|
// 阻止默认粘贴 |
|
|
|
|
|
e.preventDefault(); |
|
|
|
|
|
// 粘贴事件有一个clipboardData的属性,提供了对剪贴板的访问 |
|
|
|
|
|
// clipboardData的getData(fomat) 从剪贴板获取指定格式的数据 |
|
|
|
|
|
var text = (e.originalEvent || e).clipboardData.getData('text/plain') || prompt('在这里输入文本'); |
|
|
|
|
|
//清除回车 |
|
|
|
|
|
text = text.replace(/\[\d+\]|\n|\r/ig,"") |
|
|
|
|
|
// 插入 |
|
|
|
|
|
document.execCommand("insertText", false, text); |
|
|
|
|
|
}, |
|
|
|
|
|
myeditorenter(e) { |
|
|
|
|
|
e.preventDefault(); |
|
|
|
|
|
}, |
|
|
|
|
|
// 插入节点 |
|
|
|
|
|
insertHtmlAtCaret(html) { |
|
|
|
|
|
document.getElementById('huashuModel').focus(); |
|
|
|
|
|
var sel, range; |
|
|
|
|
|
if (window.getSelection) { |
|
|
|
|
|
// IE9 and non-IE |
|
|
|
|
|
sel = window.getSelection(); |
|
|
|
|
|
if (sel.getRangeAt && sel.rangeCount) { |
|
|
|
|
|
range = sel.getRangeAt(0); |
|
|
|
|
|
range.deleteContents(); |
|
|
|
|
|
// Range.createContextualFragment() would be useful here but is |
|
|
|
|
|
// non-standard and not supported in all browsers (IE9, for one) |
|
|
|
|
|
var el = document.createElement("div"); |
|
|
|
|
|
el.innerHTML = html; |
|
|
|
|
|
var frag = document.createDocumentFragment(), |
|
|
|
|
|
node, lastNode; |
|
|
|
|
|
while ((node = el.firstChild)) { |
|
|
|
|
|
lastNode = frag.appendChild(node); |
|
|
|
|
|
} |
|
|
|
|
|
range.insertNode(frag); |
|
|
|
|
|
// Preserve the selection |
|
|
|
|
|
if (lastNode) { |
|
|
|
|
|
range = range.cloneRange(); |
|
|
|
|
|
range.setStartAfter(lastNode); |
|
|
|
|
|
range.collapse(true); |
|
|
|
|
|
sel.removeAllRanges(); |
|
|
|
|
|
sel.addRange(range); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} else if (document.selection && document.selection.type != "Control") { |
|
|
|
|
|
// IE < 9 |
|
|
|
|
|
document.selection.createRange().pasteHTML(html); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
// 拿问题获取所在的标签数据 |
|
|
|
|
|
findKeywordsById(level1Id){ |
|
|
|
|
|
this.wajueList = [] |
|
|
|
|
|
axios({ |
|
|
|
|
|
url: `${jypath}/zk/keywords/findKeywordsById`, |
|
|
|
|
|
method: 'get', |
|
|
|
|
|
params: { |
|
|
|
|
|
houseId: this.currentHouseId, |
|
|
|
|
|
keywordsId: level1Id, |
|
|
|
|
|
level: 1 |
|
|
|
|
|
} |
|
|
|
|
|
}).then(res => { |
|
|
|
|
|
if (res.data.res == 1){ |
|
|
|
|
|
console.log(res.data) |
|
|
|
|
|
this.wajueList = res.data.obj |
|
|
|
|
|
if(this.wajueList&&this.wajueList.length){ |
|
|
|
|
|
this.wajueList.forEach(item=>{ |
|
|
|
|
|
item.disabled = false |
|
|
|
|
|
}) |
|
|
|
|
|
// this.wajueList.forEach(item=>{ |
|
|
|
|
|
// this.dynamiclist.forEach(obj=>{ |
|
|
|
|
|
// if(item.id==obj.markid){ |
|
|
|
|
|
// item.disabled = true |
|
|
|
|
|
// } |
|
|
|
|
|
// }) |
|
|
|
|
|
// }) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
// 插入节点 |
|
|
|
|
|
insertTag(item,index){ |
|
|
|
|
|
if(window._range){ |
|
|
|
|
|
this.insertContent("<span contentEditable='false' style='color:red'>"+item.value+"</span><text> </text>"); |
|
|
|
|
|
}else{ |
|
|
|
|
|
this.insertHtmlAtCaret("<span contentEditable='false' style='color:red'>"+item.value+"</span><text> </text>"); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
searchFun(){ |
|
|
|
|
|
this.tableData = [] |
|
|
|
|
|
this.pageNum = 1 |
|
|
|
|
|
this.gettableList() |
|
|
|
|
|
}, |
|
|
|
|
|
//时间选择 |
|
|
|
|
|
confirmtime() { |
|
|
|
|
|
this.searchForm.startTime = this.searchForm.customtime[0]; |
|
|
|
|
|
this.searchForm.endTime = this.searchForm.customtime[1]; |
|
|
|
|
|
}, |
|
|
|
|
|
Emptycondition(){ |
|
|
|
|
|
this.searchForm.updateUserName = '' |
|
|
|
|
|
this.searchForm.houseName = '' |
|
|
|
|
|
this.searchForm.name = '' |
|
|
|
|
|
this.searchForm.startTime = '' |
|
|
|
|
|
this.searchForm.endTime = '' |
|
|
|
|
|
this.searchForm.customtime = [] |
|
|
|
|
|
this.gettableList() |
|
|
|
|
|
}, |
|
|
|
|
|
changeType(){ |
|
|
|
|
|
this.searchFun() |
|
|
|
|
|
}, |
|
|
|
|
|
gettableList() { |
|
|
|
|
|
axios({ |
|
|
|
|
|
url: `${jypath}/zk/todo/list`, |
|
|
|
|
|
method: "get", |
|
|
|
|
|
params: { |
|
|
|
|
|
pageNum: this.pageNum, |
|
|
|
|
|
pageSize: this.pageSize, |
|
|
|
|
|
houseName: this.searchForm.houseName, |
|
|
|
|
|
updateUserName: this.searchForm.updateUserName, |
|
|
|
|
|
name: this.searchForm.name, |
|
|
|
|
|
status: this.type, //status 状态 0已处理 1未处理 |
|
|
|
|
|
startTime: this.searchForm.startTime, |
|
|
|
|
|
endTime: this.searchForm.endTime |
|
|
|
|
|
}, |
|
|
|
|
|
}).then((data) => { |
|
|
|
|
|
console.log(data); |
|
|
|
|
|
if (data.data.res == 1) { |
|
|
|
|
|
this.tableData = data.data.obj.results||[] |
|
|
|
|
|
this.total = data.data.obj.totalRecord |
|
|
|
|
|
}else{ |
|
|
|
|
|
this.tableData = [] |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
handleSizeChange(val) { |
|
|
|
|
|
console.log("每页条" + val); |
|
|
|
|
|
this.pageSize = val; |
|
|
|
|
|
this.gettableList(); |
|
|
|
|
|
}, |
|
|
|
|
|
handleCurrentChange(val) { |
|
|
|
|
|
console.log("当前页" + val); |
|
|
|
|
|
this.pageNum = val; |
|
|
|
|
|
this.gettableList(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<style scoped="scoped" lang="scss" > |
|
|
|
|
|
// /deep/ .el-table__header-wrapper{ |
|
|
|
|
|
// thead{ |
|
|
|
|
|
// tr{ |
|
|
|
|
|
// th{ |
|
|
|
|
|
// background: #F5F7FA; |
|
|
|
|
|
// color: #333333; |
|
|
|
|
|
// } |
|
|
|
|
|
// } |
|
|
|
|
|
// } |
|
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.box-center { |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
padding: 5px 15px 40px; |
|
|
|
|
|
min-width: 1000px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.app-top { |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
background: #ffffff; |
|
|
|
|
|
box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.04); |
|
|
|
|
|
border-radius: 4px; |
|
|
|
|
|
padding-top: 15px; |
|
|
|
|
|
padding-bottom: 15px; |
|
|
|
|
|
|
|
|
|
|
|
.app-titel { |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
display: flex; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
|
|
|
|
|
|
.label { |
|
|
|
|
|
font-size: 14px; |
|
|
|
|
|
font-weight: 400; |
|
|
|
|
|
color: #32363d; |
|
|
|
|
|
line-height: 14px; |
|
|
|
|
|
margin-left: 15px; |
|
|
|
|
|
// min-width: 100px; |
|
|
|
|
|
text-align: right; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
.control-tab{ |
|
|
|
|
|
margin-left: 15px; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
.button1 { |
|
|
|
|
|
padding-left: 16px; |
|
|
|
|
|
padding-right: 16px; |
|
|
|
|
|
height: 32px; |
|
|
|
|
|
line-height: 32px; |
|
|
|
|
|
background: #2671e2; |
|
|
|
|
|
border-radius: 2px; |
|
|
|
|
|
color: #ffffff; |
|
|
|
|
|
font-size: 16px; |
|
|
|
|
|
border: none; |
|
|
|
|
|
cursor: pointer; |
|
|
|
|
|
} |
|
|
|
|
|
.el-pagination{ |
|
|
|
|
|
display: flex; |
|
|
|
|
|
justify-content: flex-end; |
|
|
|
|
|
margin-top: 20px; |
|
|
|
|
|
} |
|
|
|
|
|
.editDiv{ |
|
|
|
|
|
width:100%; |
|
|
|
|
|
min-height:60px; |
|
|
|
|
|
max-height:120px; |
|
|
|
|
|
overflow:auto; |
|
|
|
|
|
margin-bottom:10px; |
|
|
|
|
|
padding: 15px; |
|
|
|
|
|
outline: none; |
|
|
|
|
|
border:1px solid #409EFF; |
|
|
|
|
|
border-radius: 10px; |
|
|
|
|
|
box-sizing: border-box; |
|
|
|
|
|
} |
|
|
|
|
|
.itemlist{ |
|
|
|
|
|
display: flex; |
|
|
|
|
|
justify-content: space-between; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
margin: 20px 0; |
|
|
|
|
|
} |
|
|
|
|
|
.item-input{ |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
padding: 4px 10px; |
|
|
|
|
|
outline: none; |
|
|
|
|
|
border:1px solid #409EFF; |
|
|
|
|
|
border-radius: 4px; |
|
|
|
|
|
overflow:auto; |
|
|
|
|
|
line-height: 24px; |
|
|
|
|
|
min-height: 24px; |
|
|
|
|
|
max-height: 100px; |
|
|
|
|
|
margin: 0 10px; |
|
|
|
|
|
} |
|
|
|
|
|
.el-dialog{ |
|
|
|
|
|
width: 800px |
|
|
|
|
|
} |
|
|
|
|
|
.el-dialog__body{ |
|
|
|
|
|
max-height: 400px; |
|
|
|
|
|
overflow: auto; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
</style> |