<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"
						>
			<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?'挖掘话术：':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">规则说明</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>
	export default {
	  data(){
		return {
		  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>&nbsp;</text>");
					}else{
					this.insertHtmlAtCaret("<span contentEditable='false' style='color:red'>"+item.value+"</span><text>&nbsp;</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>&nbsp;</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>\&nbsp\;<\/text>/g,'');
				temp = temp.replace(/\&nbsp\;/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),// 问题表达式,关键词加#号
								originalExpression: 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),// 问题表达式,关键词加#号
						originalExpression: 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>
	