|
- <template>
- <div class="box-center">
- <div class="app-top">
- <el-radio-group v-model="keyType" size="medium" @change="search">
- <el-radio-button :label="0">需求挖掘</el-radio-button>
- <el-radio-button :label="1">销讲词</el-radio-button>
- <el-radio-button :label="2">客户标签</el-radio-button>
- <el-radio-button :label="3">违禁词</el-radio-button>
- </el-radio-group>
- <el-input size="small" clearable style="margin: 0 10px;width: 220px" v-model="value" placeholder="标签名称"></el-input>
- <el-select
- v-if="orgType==0"
- v-model="houseId"
- @change="houseChange"
- placeholder="请选择"
- filterable
- >
- <el-option
- v-for="item in houseList"
- :key="item.id"
- :label="item.propertyName"
- :value="item.id"
- >
- </el-option>
- </el-select>
- <el-button size="small" type="primary" @click="search()">筛选</el-button>
- <el-button size="small" type="text" @click="Emptycondition()">清空筛选条件</el-button>
- </div>
- <div class="app-box">
- <el-table
- :data="tableData"
- stripe
- :load="loading"
- :header-cell-style="{background:'#F7F8FA',borderColor:'#E0E0E0',color:'#606775'}"
- style="width: 100%">
-
- <el-table-column
- prop="level1Name"
- :label="keyType==3?'违禁词':'画像一级'"
- align="center">
- </el-table-column>
- <el-table-column
- v-if="keyType!=3"
- prop="level2Name"
- label="画像二级"
- align="center">
- </el-table-column>
- <el-table-column
- v-if="keyType!=3"
- prop="level3Name"
- :label="keyType==0?'挖掘话术':'画像三级'"
- align="center">
- </el-table-column>
- <el-table-column
- prop="showFormatExpression"
- label="匹配模型"
- width="330"
- align="center">
- <template slot-scope="scope">
- <el-tooltip class="item" effect="dark" placement="top">
- <div v-html="scope.row.showFormatExpression" slot="content" style="max-width: 530px;"></div>
- <div class="hidden-tooltip">{{scope.row.showFormatExpression}}</div>
- </el-tooltip>
- </template>
- </el-table-column>
- <el-table-column
- prop="distance"
- label="匹配距离"
- align="center">
- </el-table-column>
- <el-table-column
- prop="updateUserName"
- label="最后修改人"
- align="center">
- </el-table-column>
- <el-table-column
- prop="updateTime"
- label="最后修改时间"
- width="110"
- align="center">
- </el-table-column>
- <el-table-column label="操作" width="140" fixed="right" align="center">
- <template slot-scope="scope">
- <el-button type="text" @click="editFun(scope.row)">编辑</el-button>
- <el-button type="text" @click="deleteFun(scope.row)">删除</el-button>
- </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>
- </div>
- <el-dialog
- title="编辑模型"
- @open="openModel"
- :close-on-click-modal="false"
- :visible.sync="dialogVisible"
- >
- <matching-rules :key="timer" :innerVisible="innerVisible"></matching-rules>
- <el-form ref="form" size="mini" :inline="true" :model="form" label-position="right">
- <el-form-item :label="keyType==0?'挖掘话术:':keyType==3?'违禁词:':'标签名称:'">
- <div style="max-width:400px;min-width: 200px;">{{form.keywordsName}}</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;timer=new Date().getTime()">规则说明</el-button>
- </el-form-item>
- <div contentEditable="true"
- @click="myeditorenter($event)"
- @keypress.enter="myeditorenter($event)"
- @blur="saveRange"
- @paste="onPaste"
- class="editDiv"
- id="huashuModel">
- </div>
- <div v-if="keyType==0||dynamiclist.length">{{keyType==0?'匹配标签:':'需求挖掘匹配:'}}</div>
- <!-- <%-- keyType=0 需求挖掘--%> -->
- <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" plain 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 v-if="keyType==0" :disabled="dynamiclist.length==wajueList.length" @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" 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>
- import matchingRules from "@/components/matchingRules/matchingRules.vue";
- export default {
- components: { matchingRules },
- data() {
- return {
- timer: 0,
- dynamiclist: [],
- taglist: [
- {
- label: "or (或)",
- value: "or",
- },
- {
- label: "near (临近)",
- value: "near",
- },
- {
- label: "after (后面)",
- value: "after",
- },
- {
- label: "and not (非)",
- value: "andnot",
- },
- // {
- // label: 'answer (问题)',
- // value: 'answer'
- // },
- ],
- form: {
- keywordsName: "",
- id: "",
- keywordsId: "",
- distance: 10,
- originalExpression: "",
- },
- innerVisible: false,
- innerVisible1: false,
- dialogVisible: false,
- value: "",
- keyType: 0,
- loading: false,
- currentPage: 1,
- tableData: [],
- type: "0",
- pageNum: 1,
- pageSize: 10,
- total: 0,
- huashu: "",
- wajueList: [],
- level: "",
- houseId: "",
- orgType: "",
- houseList: [],
- };
- },
- created() {
- this.houseId = localStorage.getItem("houseId");
- this.orgType = localStorage.getItem("orgType");
- this.orgType == 0 ? this.zkhousePage() : this.getorgCode();
- },
- methods: {
- // 获取项目列表
- zkhousePage() {
- this.$api.api
- .findHouseByUser({
- orgType: localStorage.getItem("orgType"),
- })
- .then((res) => {
- this.houseList = res.data;
- this.houseId = res.data[0].id;
- this.getorgCode();
- });
- },
- houseChange() {
- this.getorgCode();
- },
- // 校验是否已经选择过此标签
- 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);
- let e = event || window.event;
- let types = event.clipboardData.types;
- // 粘贴事件有一个clipboardData的属性,提供了对剪贴板的访问
- let flag = false;
- if (types && types.length > 0) {
- types.forEach((ele) => {
- if (ele == "Files") {
- flag = true;
- }
- });
- }
- if (flag) {
- event.preventDefault();
- }
- },
- 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(keywordsId) {
- axios({
- url: `/autoSR/zk/keywords/findKeywordsById`,
- method: "get",
- params: {
- houseId: this.houseId,
- keywordsId: keywordsId,
- level: 1,
- },
- }).then((res) => {
- if (res.code == 0) {
- // console.log(res.data)
- this.wajueList = res.data;
- 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 (index == 4) {
- // answer
- this.huashu = "";
- this.innerVisible1 = true;
- } else {
- 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>"
- );
- }
- }
- },
- // 处理标签,删除不需要的标签格式
- 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);
- },
- // 确认插入选择的话术
- clickOK() {
- this.innerVisible1 = false;
- if (!this.huashu) {
- this.$message.error("请选择话术");
- return;
- }
- this.insertContent(
- "<text>" +
- this.huashu +
- "</text><span contentEditable='false' style='color:red'>answer</span><text> </text>"
- );
- },
- search() {
- this.pageNum = 1;
- this.getorgCode();
- },
- //点击编辑按钮
- editFun(item) {
- this.dialogVisible = true;
- this.form.id = item.id;
- if (this.keyType == 0) {
- // 挖掘话术类型
- // 回显标签模型数据
- if (item.answerList && item.answerList.length) {
- this.dynamiclist = item.answerList.map((obj) => {
- return {
- id: obj.id,
- mark: obj.level3Name ? obj.level3Name : obj.level2Name,
- level: obj.level3Id ? 3 : 2,
- editValue: obj.originalExpression,
- markid: obj.level3Id ? obj.level3Id : obj.level2Id,
- };
- });
- // console.log(this.dynamiclist)
- } else {
- this.dynamiclist = [];
- }
- this.form.keywordsName = item.level3Name;
- this.form.distance = item.distance || 10;
- this.form.originalExpression =
- item.originalExpression || item.level3Name;
- this.level = item.level2Id ? 2 : 1;
- this.questionId = item.questionId;
- this.form.keywordsId = item.level2Id ? item.level2Id : item.level1Id;
- this.findKeywordsById(item.level1Id); // 获取标签下拉数据
- } else if (this.keyType == 3) {
- // 违禁词
- this.form.keywordsName = item.level1Name;
- this.level = 1;
- this.form.distance = item.distance || 10;
- this.form.originalExpression =
- item.originalExpression || item.level1Name;
- this.dynamiclist = [];
- } else {
- this.form.keywordsId = item.level3Id ? item.level3Id : item.level2Id;
- this.level = item.level3Id ? 3 : 2;
- this.form.keywordsName = item.level3Name || item.level2Name;
- this.form.distance = item.distance || 10;
- this.form.originalExpression =
- item.originalExpression || item.level3Name || item.level2Name;
- if (item.answerList && item.answerList.length) {
- this.dynamiclist = item.answerList.map((obj) => {
- return {
- question: obj.question,
- editValue: obj.originalExpression,
- };
- });
- } else {
- this.dynamiclist = [];
- }
- }
- },
- // 删除列表
- deleteFun(item) {
- this.$alert(item.keywordsName, "确定删除该条数据吗", {
- confirmButtonText: "确定",
- callback: (action) => {
- axios({
- url: `/autoSR/zk/keymodel/delKeywordsModel`,
- method: "get",
- params: {
- id: item.id,
- houseId: this.houseId,
- },
- })
- .then((data) => {
- if (data.code == 0) {
- this.getorgCode();
- }
- })
- .catch((e) => {});
- },
- });
- },
- // 处理模型 关键词加#号
- 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(/<\/br>/g, "");
- temp = temp.replace(/<br>/g, "");
- temp = temp.replace(/<\/span>/g, "#");
- // console.log('处理前temp',temp);
- this.delMark(temp);
- // console.log(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++) {
- // 使用for循环判断可以跳出循环
- 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), // 问题表达式,关键词加#号
- original: item.editValue, // html==带span标签
- };
- });
- }
- axios({
- url: `/autoSR/zk/keymodel/updateKeywordsModel`,
- method: "post",
- data: {
- id: this.form.id,
- questionId: this.keyType == 0 ? this.questionId : "",
- houseId: this.houseId,
- keyType: this.keyType,
- level: this.level,
- keywordsId: this.form.keywordsId,
- keywordsName: this.form.keywordsName,
- formatExpression: this.replaceFun(temp), // 问题表达式,关键词加#号
- original: temp, // html==带span标签
- answerList: answerList,
- showFormatExpression: text.innerText,
- distance: this.form.distance, // 距离
- },
- })
- .then((res) => {
- this.cansave = false;
- this.dialogVisible = false;
- if (res.code == 0) {
- this.$message.success(res.data);
- this.getorgCode();
- } else {
- this.$message.error(res.msg);
- }
- })
- .catch((e) => {
- this.cansave = false;
- this.dialogVisible = false;
- });
- },
- //清空筛选条件
- Emptycondition() {
- this.value = "";
- this.keyType = 0;
- this.pageNum = 1;
- this.getorgCode();
- },
- //初始化
- getorgCode() {
- this.loading = true;
- this.tableData = [];
- axios({
- url: `/autoSR/zk/keymodel/findKeywordsModel`,
- method: "get",
- params: {
- houseId: this.houseId,
- current: this.pageNum,
- size: this.pageSize,
- keywordsName: this.value,
- keyType: this.keyType,
- },
- })
- .then((res) => {
- this.loading = false;
- if (res.code == 0) {
- this.tableData = res.data.records || [];
- this.total = res.data.total;
- }
- })
- .catch((e) => {
- this.loading = false;
- });
- },
- handleSizeChange(val) {
- console.log("每页条" + val);
- this.pageSize = val;
- this.getorgCode();
- },
- handleCurrentChange(val) {
- console.log("当前页" + val);
- this.pageNum = val;
- this.getorgCode();
- },
- },
- };
- </script>
-
- <style lang="scss" scoped >
- .box-center {
- width: 100%;
- padding: 5px 15px 40px;
- min-width: 1000px;
- }
- .app-top {
- margin-bottom: 20px;
- width: 100%;
- background: #ffffff;
- box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.04);
- border-radius: 4px;
- padding: 15px;
- }
- .block {
- width: 100%;
- margin-top: 5px;
- display: flex;
- }
- .blockbox {
- margin-left: auto;
- }
- .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;
- }
- .hidden-tooltip {
- width: 330px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- position: relative;
- }
- .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>
-
|