日历组件 el-calendar 实现标记功能

需求:在日历组件中选择月份时,可以显示当月已经质检或需质检的数据

思路:前端每次点击日期选择器的时候调用接口,接口返回当月需要质检或已质检的数据,前端拿到数据就开始做判断然后回显。

大体样式

 

 代码:

<!-- 日历组件 -->
				<div style="width: 28% !important">
					<el-date-picker v-model="selectDate" type="date" placeholder="选择日期" :picker-options="pickerOptions" @change="dataPickerHandle"> </el-date-picker>
					<el-calendar v-model="selectDate" value-format="yyyy-MM-dd">
						<template :disabled="data.styleFlag == true" slot="dateCell" slot-scope="{ data }">
							<span>{{ dealMyDate(data.day, data) }}</span>
							<p @click="calendarOnClick(data)" :class="data.styleFlag == true ? 'preventClick' : ''">
								{{
									data.day
										.split('-')
										.slice(2)
										.join('')
								}}<br />
							</p>
							<div v-for="item in resDate" :key="item.dt">
								<div v-if="data.day == item.dt">
									<span class="redStyle" v-if="item.type == 2">需质检</span>
									<span class="greenStyle" v-if="item.type == 1">已质检</span>
								</div>
							</div>
						</template>
					</el-calendar>
				</div>
        dealMyDate(v, data) {
			if (v > this.defaultDate) {
				Object.assign(data, { styleFlag: true });
			}
		},
		dataPickerHandle(date) {
			let obj = {
				date: this.dateFormat('YYYY-mm-dd', date),
			};
			getCalenderList(obj).then((res) => {
				if (res.data.code == 0) {
					this.resDate = res.data.data;
				}
			});
		},
        // 页面一开始进来调用前天的日历接口
	    getCalenderData() {
			let obj = {
				date: this.defaultDate,
			};
			getCalenderList(obj).then((res) => {
				if (res.data.code == 0) {
					this.resDate = res.data.data;
				}
			});
		},

 完整代码

<template>
	<div>
		<basic-container>
			<div style="float: left">
				<!-- 日历组件 -->
				<div style="width: 28% !important">
					<el-date-picker v-model="selectDate" type="date" placeholder="选择日期" :picker-options="pickerOptions" @change="dataPickerHandle"> </el-date-picker>
					<el-calendar v-model="selectDate" value-format="yyyy-MM-dd">
						<template :disabled="data.styleFlag == true" slot="dateCell" slot-scope="{ data }">
							<span>{{ dealMyDate(data.day, data) }}</span>
							<p @click="calendarOnClick(data)" :class="data.styleFlag == true ? 'preventClick' : ''">
								{{
									data.day
										.split('-')
										.slice(2)
										.join('')
								}}<br />
							</p>
							<div v-for="item in resDate" :key="item.dt">
								<div v-if="data.day == item.dt">
									<span class="redStyle" v-if="item.type == 2">需质检</span>
									<span class="greenStyle" v-if="item.type == 1">已质检</span>
								</div>
							</div>
						</template>
					</el-calendar>
				</div>
				<el-table
					v-loading="listLoading"
					:data="tableList"
					:header-cell-style="{
						background: 'rgb(255, 191, 191)',
						color: 'rgb(44,44,44)',
					}"
					stripe
					border
					style="width: 28%; margin-top: 15px; margin-bottom: 20px"
				>
					<el-table-column label="序号" width="70">
						<template slot-scope="scope">
							{{ scope.$index + 1 }}
						</template>
					</el-table-column>
					<el-table-column label="状态" prop="type"></el-table-column>
					<el-table-column width="100" label="人数" prop="number"> </el-table-column>
					<el-table-column label="操作" width="100">
						<template slot-scope="scope">
							<el-button type="text" v-if="scope.row.type == '需质检'" @click="handleInspect(scope.row)">质检</el-button>
							<el-button type="text" v-if="scope.row.type == '已质检'" @click="handleView(scope.row)">详情</el-button>
						</template>
					</el-table-column>
				</el-table>
			</div>
			<div class="inspection-right-table">
				<el-table
					v-loading="detailLoading"
					:data="detailTable"
					:header-cell-style="{
						background: 'rgb(255, 191, 191)',
						color: 'rgb(44,44,44)',
					}"
					stripe
					border
					:default-sort="{ prop: 'time', order: 'descending' }"
				>
					<el-table-column label="序号" width="60" type="index">
						<template slot-scope="scope">{{ page.size * (page.current - 1) + scope.$index + 1 }}</template>
					</el-table-column>
					<el-table-column label="成员" prop="name"></el-table-column>
					<el-table-column width="90" label="客户" prop="contactName"></el-table-column>
					<el-table-column width="90" label="敏感内容(分)" prop="sensitiveContent"></el-table-column>
					<el-table-column width="90" label="用语规范(分)" prop="terminologyNorm"></el-table-column>
					<el-table-column width="90" label="服务禁语(分)" prop="serviceTaboo"></el-table-column>
					<el-table-column width="90" label="加分项(分)" prop="pluses"></el-table-column>
					<el-table-column width="70" label="总分" prop="score"></el-table-column>
					<el-table-column width="100" label="质检人" prop="checkeName"></el-table-column>
					<el-table-column width="100" label="质检时间" prop="checkDt" sortable></el-table-column>
					<el-table-column label="操作" width="100">
						<template slot-scope="scope">
							<el-button v-if="scope.row.type == '2'" type="text" @click="dialogInspect(scope.row)">质检</el-button>
							<el-button type="text" v-if="scope.row.type == '1'" @click="dialogView(scope.row)">详情</el-button>
						</template>
					</el-table-column>
				</el-table>
				<!-- 分页 -->
				<div class="madp-pagination">
					<el-pagination
						background
						@size-change="handleSizeChange"
						@current-change="handleCurrentChange"
						:current-page="page.current"
						:page-sizes="[10, 20, 30, 50, 100]"
						:page-size="page.size"
						layout="total, sizes, prev, pager, next, jumper"
						:total="page.total"
					></el-pagination>
				</div>
			</div>

			<el-dialog :title="dialogTitle" :close-on-click-modal="false" :visible.sync="dialogVisible" :before-close="handleCancel" width="88%">
				<div class="dialog-left">
					<div class="dialog-left-title">聊天记录</div>
					<el-row style="padding: 7px; border-left: 1px solid #ebebeb">
						<el-col :span="12" :offset="6">
							<el-input maxlength="30" v-model="searchCont" placeholder="请输入聊天内容"></el-input>
						</el-col>
						<el-col :span="6">
							<el-button style="margin-left: 20%" type="primary" @click="handleSearch">搜索</el-button>
						</el-col>
					</el-row>
					<div class="scrollStyle">
						<div class="madp-chatInfo" v-for="(it, i) in chatData" :key="i">
							<div>
								<p :class="it.toListType == 0 ? 'madp-chat-link' : 'madp-chat-link madp-chat-right'">
									<span v-if="it.toListType == 0">
										<img class="madp-chatInfo-avatar" :src="it.avatar" />
										<span class="madp-chatInfo-name">{{ it.name }}</span>
										<span class="madp-chatInfo-time">{{ it.msgDataTime }}</span>
									</span>
									<span v-else>
										<span class="madp-chatInfo-etime">{{ it.msgDataTime }}</span>
										<span class="madp-chatInfo-ename">{{ it.name }}</span>
										<img class="madp-chatInfo-eavatar" :src="it.avatar" />
									</span>
								</p>
								<div v-if="it.type == 1" :class="it.toListType == 0 ? '' : 'madp-chat-right'">
									<p :class="it.toListType == 0 ? 'madp-chatInfo-chat madp-text-over' : 'madp-chatInfo-echat madp-text-over'">
										{{ it.content.content }}
									</p>
								</div>
								<div v-if="it.type == 2" :class="it.toListType == 0 ? 'madp-chat-box' : 'madp-chat-box madp-chatInfo-eimg'">
									<img
										:src="it.content.ossPath"
										class="madp-chatInfo-img"
										@click="
											isLargeImgShow = true;
											largeImgUrl = it.content.ossPath;
										"
									/>
								</div>
								<div v-if="it.type == 13" :class="it.toListType == 0 ? '' : 'madp-chat-right'">
									<p :class="it.toListType == 0 ? 'madp-chatInfo-chat madp-text-over' : 'madp-chatInfo-echat madp-text-over'">
										<a :href="it.content.link_url" target="_blank">{{ it.content.link_url }}</a>
									</p>
								</div>
								<div v-if="it.type == 4" :class="it.toListType == 0 ? '' : 'madp-right-audio'">
									<audio :src="it.content.ossPath" controls="controls" class="madp-chatInfo-audio"></audio>
								</div>
								<div :class="it.toListType == 0 ? '' : 'madp-chatInfo-eimg'" v-if="it.type == 5">
									<video :src="it.content.ossPath" controls="controls" class="madp-chatInfo-img"></video>
								</div>
								<div v-if="it.type == 7" :class="it.toListType == 0 ? '' : 'madp-right-audio'">
									<!-- 音频 -->
									<div v-if="it.content.fileext == 'mp3'">
										<audio :src="it.content.ossPath" controls="controls" class="madp-chatInfo-audio"></audio>
									</div>
									<!-- 视频 -->
									<div v-if="it.content.fileext == 'mp4'">
										<video :src="it.content.ossPath" controls="controls" class="madp-chatInfo-img"></video>
									</div>
									<div class="madp-file" v-else>
										<div>
											<p class="madp-file-name">
												{{ it.content.filename }}
											</p>
											<p>{{ (it.content.filesize / 1024).toFixed(2) }}kb</p>
										</div>
										<a :href="it.content.ossPath" target="_blank">
											<img src="/img/xlsx.png" v-show="it.content.fileext == 'xlsx'" class="madp-chatInfo-file" />
											<img src="/img/pdf.jpg" v-show="it.content.fileext == 'pdf'" class="madp-chatInfo-file" />

											<img src="/img/ppt.jpg" v-show="it.content.fileext == 'pptx'" class="madp-chatInfo-file" />

											<img src="/img/txt.png" v-show="it.content.fileext == 'txt'" class="madp-chatInfo-file" />

											<img src="/img/word.png" v-show="it.content.fileext == 'docx'" class="madp-chatInfo-file" />

											<img src="/img/csv.png" v-show="it.content.fileext == 'csv'" class="madp-chatInfo-file" />
											<img :src="it.content.ossPath" v-show="it.content.fileext == 'jpg'" class="madp-chatInfo-file" />
											<img :src="it.content.ossPath" v-show="it.content.fileext == 'png'" class="madp-chatInfo-file" />
										</a>
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
				<div class="dialog-right">
					<el-table
						:data="dialogTableData"
						:span-method="objectSpanMethod"
						border
						:key="randomKey"
						show-summary
						:summary-method="getTotalScore"
						style="width: 100%; margin-top: 10px"
						max-height="700"
						align="center"
					>
						<el-table-column prop="sort" label="分类" width="110"> </el-table-column>
						<el-table-column prop="class" label="类别" width="110"> </el-table-column>
						<el-table-column prop="standards" label="标准"> </el-table-column>
						<el-table-column prop="checkPoints" label="考核扣分"> </el-table-column>
						<el-table-column property="inspectScore" label="得分">
							<template slot-scope="scope">
								<el-input
									:disabled="isEdit"
									v-if="!scope.row[scope.column.property + 'isShow'] && scope.row.sort !== '加分项' && scope.row.class == '敏感内容(40分)'"
									:ref="scope.column.property"
									v-model="scope.row.inspectScore"
									oninput="value=value.replace(/[^\d]/g,'');if(value>40)value=40"
									@blur="editCellSensitive(scope.row, scope.column)"
								>
								</el-input>
								<el-input
									:disabled="isEdit"
									v-if="!scope.row[scope.column.property + 'isShow'] && scope.row.sort !== '加分项' && scope.row.class == '用语规范(20分)'"
									:ref="scope.column.property"
									v-model="scope.row.inspectScore"
									oninput="value=value.replace(/[^\d]/g,'');if(value>20)value=20"
									@blur="editCellNorms(scope.row, scope.column)"
								>
								</el-input>
								<el-input
									:disabled="isEdit"
									v-if="!scope.row[scope.column.property + 'isShow'] && scope.row.sort !== '加分项' && scope.row.class == '服务禁语(40分)'"
									:ref="scope.column.property"
									v-model="scope.row.inspectScore"
									oninput="value=value.replace(/[^\d]/g,'');if(value>40)value=40"
									@blur="editCellService(scope.row, scope.column)"
								>
								</el-input>

								<el-input
									:disabled="isEdit"
									v-if="!scope.row[scope.column.property + 'isShow'] && scope.row.sort == '加分项'"
									:ref="scope.column.property"
									v-model="scope.row.inspectScore"
									oninput="value=value.replace(/[^\d]/g,'');if(value>10)value=10;"
									@blur="editCellPraise(scope.row, scope.column)"
								>
								</el-input>
								<el-select :disabled="isEdit" @change="selectChange" clearable v-if="scope.row.sort == '其他'" v-model="selectValue" placeholder="请选择">
									<el-option style="text-align: center" v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
								</el-select>
								<!-- <span v-else>{{ scope.row.inspectScore }}</span> -->
							</template>
						</el-table-column>
						<el-table-column property="inspectAdvice" label="问题建议">
							<template slot-scope="scope">
								<el-input
									:disabled="isEdit"
									type="textarea"
									:autosize="{ minRows: 4, maxRows: 5 }"
									v-if="!scope.row[scope.column.property + 'isShow'] && scope.row.class == '敏感内容(40分)'"
									:ref="scope.column.property"
									v-model="scope.row.inspectAdvice"
									@blur="editCellQuestionSensitive(scope.row, scope.column)"
								>
								</el-input>
								<el-input
									:disabled="isEdit"
									type="textarea"
									:autosize="{ minRows: 4, maxRows: 5 }"
									v-if="!scope.row[scope.column.property + 'isShow'] && scope.row.class == '用语规范(20分)'"
									:ref="scope.column.property"
									v-model="scope.row.inspectAdvice"
									@blur="editCellQuestionNorms(scope.row, scope.column)"
								>
								</el-input>
								<el-input
									:disabled="isEdit"
									type="textarea"
									:autosize="{ minRows: 2, maxRows: 2 }"
									v-if="!scope.row[scope.column.property + 'isShow'] && scope.row.class !== '用语规范(20分)' && scope.row.class !== '敏感内容(40分)'"
									:ref="scope.column.property"
									v-model="scope.row.inspectAdvice"
									@blur="editCellQuestion(scope.row, scope.column)"
								>
								</el-input>
								<!-- <span v-else>{{ scope.row.inspectAdvice }}</span> -->
							</template>
						</el-table-column>
					</el-table>
				</div>
				<div slot="footer" class="dialog-footer">
					<el-button type="primary" v-if="this.dialogTitle == '会话质检'" @click="dialogConfim">确定</el-button>
					<el-button type="primary" @click="handleCancel">取消</el-button>
				</div>
			</el-dialog>
		</basic-container>
	</div>
</template>
<script>
import { getCalenderList, getInspectionList, getChatData, inspectionCinfirmList } from '@/api/session-quality-inspection/inspection';
export default {
	name: 'starff-inspection',
	data() {
		return {
			defaultDate: '',
			selectDate: '',
			pickerOptions: {
				disabledDate(time) {
					return time.getTime() > Date.now() - 60 * 60 * 24 * 1000;
				},
			},
			searchCont: '', //搜索框内容
			//聊天记录数据
			chatData: [],
			//日历组件数据
			resDate: [],
			listLoading: false, //左边表格loading
			tableList: [], //左边表格数据
			detailLoading: false, //右边详情表格loading
			detailTable: [], //右边表格数据
			page: {
				current: 1,
				size: 10,
				total: 0,
			},
			isEdit: false, //得分和意见是否可编辑
			dialogVisible: false,
			//弹窗表格数据
			dialogTableData: [],
			//弹窗表格的接口数据
			dialogHandleData: {},
			//弹窗表格自己定义的数据
			dialogTableList: [
				{
					sort: '服务规范',
					class: '敏感内容(40分)',
					standards: '遵守法律法规,坚持道德准则,不得妄议党的方针政策,不得传播色情、低俗等不当内容',
					checkPoints:
						'1.出现敏感词,如党政领导人、政治敏感事件、军事名称相关敏感词汇,扣5分/次;2.传播色情、低俗、恐怖等不当内容行为,扣10分/次;3.妄议党的方针政策、转播政治负面言论,发表违背中央精神言论,扣15分/次;',
				},
				{
					sort: '服务规范',
					class: '用语规范(20分)',
					standards: '态度积极友善、耐心诚恳,不得反问、客户或与客户争辩质问、责怪、嘲讽',
					checkPoints:
						'出现“不清楚”、“不知道”、“不了解”等关联词语未做任何解释,扣5分一次;2.出现“这是你的问题”,“你这话什么意思”、“你去投诉啊,我害怕你”、“我就这态度,你能怎样”、“不会用就别用”、“不关我的事”扣10分/次;',
				},
				{
					sort: '服务规范',
					class: '服务禁语(40分)',
					standards: '尊重客户、不得训斥、辱骂客户',
					checkPoints: '出现训斥、辱骂客户的字眼,扣40分/次;',
				},
				{
					sort: '加分项',
					class: '表扬',
					standards: '客户在线提出表扬',
					checkPoints: '如出现"你服务真好!"、"我对你的回答很满意"、"我想表扬你等"加10分;',
				},
				{
					sort: '其他',
					class: '投诉事件',
					standards: '出现因工作人员自身原因引起客户投诉,有损银行名誉、形象行为',
					checkPoints: '如:因服务态度不好引发有责投诉,业务解答、引导、流程有误引发有责投诉或造成客户经济损失,索要红包等扣20分/次;',
				},
			],
			//弹窗标题
			dialogTitle: '',
			randomKey: '',
			options: [
				{
					value: 1,
					label: '是',
				},
				{
					value: 0,
					label: '否',
				},
			],
			selectValue: '',
			calanderType: '',
			sumsScore: '',
			classFlag: false,
			searchData: {},
			allInspectDate: [],
			allDetailDate: [],
		};
	},
	created() {
		this.$nextTick(() => {
			// 点击上个月
			let prevBtn = document.querySelector('.el-calendar__button-group .el-button-group>button:nth-child(1)');
			prevBtn.addEventListener('click', () => {
				let obj = {
					date: this.dateFormat('YYYY-mm-dd', this.selectDate),
				};
				getCalenderList(obj).then((res) => {
					if (res.data.code == 0) {
						this.resDate = res.data.data;
						this.tableList = [];
					}
				});
			});
			// 点击今天
			let currBtn = document.querySelector('.el-calendar__button-group .el-button-group>button:nth-child(2)');
			currBtn.addEventListener('click', () => {
				let obj = {
					date: this.dateFormat('YYYY-mm-dd', this.selectDate),
				};
				getCalenderList(obj).then((res) => {
					if (res.data.code == 0) {
						this.resDate = res.data.data;
						this.tableList = [];
					}
				});
			});
			// 点击下个月
			let nextBtn = document.querySelector('.el-calendar__button-group .el-button-group>button:nth-child(3)');
			nextBtn.addEventListener('click', () => {
				let obj = {
					date: this.dateFormat('YYYY-mm-dd', this.selectDate),
				};
				getCalenderList(obj).then((res) => {
					if (res.data.code == 0) {
						this.resDate = res.data.data;
						this.tableList = [];
					}
				});
			});
		});
		// this.page.total = this.detailTable.length;
	},
	activated() {},
	mounted() {
		this.getdatatime();
		//得到今天前一天的日期
		var now = new Date();
		var year = now.getFullYear(); //得到年份
		var month = (now.getMonth() + 1).toString().padStart(2, '0'); //得到月份
		var date = now.getDate().toString(); //得到日期
		if (date.length == 1) {
			this.defaultDate = `${year}-${month}-0${date - 1}`;
		} else if (date.length == 2) {
			this.defaultDate = `${year}-${month}-${date - 1}`;
		}
		this.getCalenderData();
		this.dealMyDate();
	},
	updated() {},
	methods: {
		dealMyDate(v, data) {
			if (v > this.defaultDate) {
				Object.assign(data, { styleFlag: true });
			}
		},
		dataPickerHandle(date) {
			let obj = {
				date: this.dateFormat('YYYY-mm-dd', date),
			};
			getCalenderList(obj).then((res) => {
				if (res.data.code == 0) {
					this.resDate = res.data.data;
				}
			});
		},
		// 页面一开始进来调用前天的日历接口
		getCalenderData() {
			let obj = {
				date: this.defaultDate,
			};
			getCalenderList(obj).then((res) => {
				if (res.data.code == 0) {
					this.resDate = res.data.data;
				}
			});
		},
		//时间格式化
		dateFormat(fmt, date) {
			let ret;
			const opt = {
				'Y+': date.getFullYear().toString(), // 年
				'm+': (date.getMonth() + 1).toString(), // 月
				'd+': date.getDate().toString(), // 日
				'H+': date.getHours().toString(), // 时
				'M+': date.getMinutes().toString(), // 分
				'S+': date.getSeconds().toString(), // 秒
			};
			for (let k in opt) {
				ret = new RegExp('(' + k + ')').exec(fmt);
				if (ret) {
					fmt = fmt.replace(ret[1], ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0'));
				}
			}
			return fmt;
		},
		//日期选择器 默认显示当前日期的前一天
		getdatatime() {
			const start = new Date();
			this.selectDate = start.getTime() - 60 * 60 * 24 * 1000;
		},
		//点击日历每一天
		calendarOnClick(e) {
			console.log(e);
			this.detailTable = [];
			if (this.resDate.length == 0) {
				this.calanderType = '3';
				this.tableList = [];
			} else {
				this.calanderType = this.resDate[0].type;
			}
			// 调用左边表格的接口
			let obj = {
				date: e.day,
				type: this.calanderType,
			};
			getInspectionList(obj).then((res) => {
				if (res.data.code == 0) {
					this.tableList = res.data.data;
					// this.page.total = res.data.data.page.total;
					// this.page.current = res.data.data.page.current;
					// this.page.size = res.data.data.page.size;
				}
			});
		},
		// 点击质检按钮
		handleInspect(data) {
			console.log(data);
			this.allInspectDate = data.page.records;
			// this.detailTable = data.page.records;
			// this.page.size = data.page.size;
			// this.page.current = data.page.current;
			this.page.total = data.page.total;
			this.detailTable = this.allInspectDate.slice((this.page.current - 1) * this.page.size, this.page.current * this.page.size);
		},
		// 点击详情按钮
		handleView(data) {
			this.allDetailDate = data.page.records;

			this.detailTable = this.allDetailDate.slice((this.page.current - 1) * this.page.size, this.page.current * this.page.size);
		},
		// 分页
		handleSizeChange(size) {
			console.log('当前页多少数据:', size);
			this.page.size = size;
			this.detailTable = this.allInspectDate.slice((this.page.current - 1) * this.page.size, this.page.current * this.page.size);
		},
		handleCurrentChange(current) {
			console.log('当前页数:', current);
			this.page.current = current;
			this.detailTable = this.allInspectDate.slice((current - 1) * this.page.size, current * this.page.size);
		},
		// 合并单元格操作
		objectSpanMethod({ row, column, rowIndex, columnIndex }) {
			if (columnIndex == 0) {
				if (rowIndex == 0) {
					//第一行
					return {
						rowspan: 3,
						colspan: 1,
					};
				} else if (rowIndex < 3) {
					return {
						rowspan: 0,
						colspan: 0,
					};
				}
			}
			if (rowIndex == 5) {
				if (columnIndex == 0) {
					return {
						rowspan: 1,
						colspan: 4,
					};
				} else if (columnIndex < 4) {
					return {
						rowspan: 0,
						colspan: 0,
					};
				} else {
					return {
						rowspan: 1,
						colspan: 2,
					};
				}
			}
		},
		//编辑表格单元格
		// editTableData(row, column) {
		// 	row[column.property + 'isShow'] = true;
		// 	//refreshTable是table数据改动时,刷新table的
		// 	this.refreshTable();
		// 	this.$nextTick(() => {
		// 		this.$refs[column.property] && this.$refs[column.property].focus();
		// 	});
		// },
		//得分一列编辑 敏感内容打分(不包含加分项)
		editCellSensitive(row, column) {
			row[column.property + 'isShow'] = false;

			this.refreshTable();
			if ((row.sort = '敏感内容(40%)')) {
				if (row.inspectScore != '') {
					this.selectValue = 0;
				}
			}
		},
		//得分一列编辑 用语规范(不包含加分项)
		editCellNorms(row, column) {
			row[column.property + 'isShow'] = false;

			this.refreshTable();
			if ((row.sort = '敏感内容(40%)')) {
				if (row.inspectScore != '') {
					this.selectValue = 0;
				}
			}
		},
		//得分一列编辑 服务禁语(不包含加分项)
		editCellService(row, column) {
			row[column.property + 'isShow'] = false;

			this.refreshTable();
			if ((row.sort = '敏感内容(40%)')) {
				if (row.inspectScore != '') {
					this.selectValue = 0;
				}
			}
		},
		//加分项编辑
		editCellPraise(row, column) {
			row[column.property + 'isShow'] = false;

			this.refreshTable();
		},
		//问题建议编辑  敏感
		editCellQuestionSensitive(row, column) {
			row[column.property + 'isShow'] = false;

			this.refreshTable();
		},
		//问题建议编辑  规范
		editCellQuestionNorms(row, column) {
			row[column.property + 'isShow'] = false;

			this.refreshTable();
		},
		//问题建议编辑
		editCellQuestion(row, column) {
			row[column.property + 'isShow'] = false;

			this.refreshTable();
		},
		//是否投诉
		selectChange(val) {
			this.dialogTableData[4].inspectScore = val;
		},
		refreshTable() {
			this.randomKey = Math.random();
		},
		// 表尾合计总分
		getTotalScore(param) {
			const { columns, data } = param;
			const sums = [];
			columns.forEach((column, index) => {
				if (index === 1) {
					sums[index] = '最终得分';
					return;
				}
                const values = data.map((item) => Number(item[column.property]));
                if (!values.every((value) => isNaN(value))) {
                    sums[index] = values.reduce((prev, curr) => {
                        const value = Number(curr);
                        if (!isNaN(value)) {
                            return prev + curr;
                        } else {
                            return prev;
                        }
                    }, 0);
                    sums[index] = 0;
                    this.sumsScore = sums[index]; 
                } else {
                    sums[index] = '';
                }	
			});
			return sums;
		},
		// 弹窗搜索聊天记录
		handleSearch() {
			//调用聊天数据接口
			let obj = {
				chatDate: this.searchData.sessionDt,
				wxUserId: this.searchData.wxUserId,
				name: this.searchData.name,
				wxExternalUserid: this.searchData.wxExternalUserid,
				contactName: this.searchData.contactName,
				content: this.searchCont,
			};
			getChatData(obj).then((res) => {
				if (res.data.code == 0) {
					this.chatData = res.data.data.records;
				}
			});
		},
		//质检弹窗
		dialogInspect(data) {
			this.searchData = data;
			this.dialogHandleData = data;
			this.dialogVisible = true;
			this.isEdit = false;
			this.dialogTitle = '会话质检';
			if (data.ifComplain == '') {
				this.selectValue = 0;
			} else if (data.ifComplain > 1) {
				this.selectValue = 1;
			} else {
				this.selectValue = data.ifComplain;
			}
			let amout3Key = [data.sensitiveContent, data.terminologyNorm, data.serviceTaboo, data.pluses, data.ifComplain];
			let amout4key = [data.sensitiveDis, data.terminologyDis, data.serviceDis, data.plusesDis, data.complainDis];
			this.dialogTableData = this.dialogTableList.map((i, index) => {
				return {
					...i,
					inspectScore: amout3Key[index],
					inspectAdvice: amout4key[index],
				};
			});
			//调用聊天数据接口
			let obj = {
				chatDate: data.sessionDt,
				wxUserId: data.wxUserId,
				name: data.name,
				wxExternalUserid: data.wxExternalUserid,
				contactName: data.contactName,
			};
			getChatData(obj).then((res) => {
				if (res.data.code == 0) {
					this.chatData = res.data.data.records;
				}
			});
		},
		//详情弹窗
		dialogView(data) {
			this.searchData = data;
			this.dialogVisible = true;
			this.dialogTitle = '质检详情';
			if (data.ifComplain == '') {
				this.selectValue = 0;
			} else if (data.ifComplain > 1) {
				this.selectValue = 1;
			} else {
				this.selectValue = data.ifComplain;
			}
			this.isEdit = true;
			let amout3Key = [data.sensitiveContent, data.terminologyNorm, data.serviceTaboo, data.pluses, data.ifComplain];
			let amout4key = [data.sensitiveDis, data.terminologyDis, data.serviceDis, data.plusesDis, data.complainDis];
			this.dialogTableData = this.dialogTableList.map((i, index) => {
				return {
					...i,
					inspectScore: amout3Key[index],
					inspectAdvice: amout4key[index],
				};
			});
			//调用聊天数据接口
			let obj = {
				chatDate: data.sessionDt,
				wxUserId: data.wxUserId,
				name: data.name,
				wxExternalUserid: data.wxExternalUserid,
				contactName: data.contactName,
			};
			getChatData(obj).then((res) => {
				if (res.data.code == 0) {
					this.chatData = res.data.data.records;
				}
			});
		},
		// 弹窗确定按钮
		dialogConfim() {
			this.dialogTableData[4].inspectScore = this.selectValue;
			//否0   是1
			if (this.dialogTableData[4].inspectScore == 0) {
				if (this.dialogTableData[0].inspectScore == '' || this.dialogTableData[1].inspectScore == '' || this.dialogTableData[2].inspectScore == '') {
					this.$message({
						showClose: true,
						message: '请对我的服务进行评分',
						type: 'warning',
					});
				} else {
					this.dialogVisible = false;
				}
			} else if (this.dialogTableData[4].inspectScore == 1) {
				this.dialogVisible = false;
				this.sumsScore = 0;
			}
			let obj = {
				sessionDt: this.dialogHandleData.sessionDt,
				wxUserId: this.dialogHandleData.wxUserId,
				deptId: this.dialogHandleData.deptId,
				name: this.dialogHandleData.name,
				wxExternalUserid: this.dialogHandleData.wxExternalUserid,
				contactName: this.dialogHandleData.contactName,
				checkPeople: this.dialogHandleData.checkPeople,
				checkDt: this.dialogHandleData.checkDt,
				sq: this.dialogHandleData.sq,
				sensitiveContent: this.dialogTableData[0].inspectScore,
				sensitiveDis: this.dialogTableData[0].inspectAdvice,
				terminologyNorm: this.dialogTableData[1].inspectScore,
				terminologyDis: this.dialogTableData[1].inspectAdvice,
				serviceTaboo: this.dialogTableData[2].inspectScore,
				serviceDis: this.dialogTableData[2].inspectAdvice,
				pluses: this.dialogTableData[3].inspectScore,
				plusesDis: this.dialogTableData[3].inspectAdvice,
				ifComplain: this.dialogTableData[4].inspectScore,
				complainDis: this.dialogTableData[4].inspectAdvice,
				score: this.sumsScore,
			};
			inspectionCinfirmList(obj).then((res) => {
				if (res.data.code == 0) {
					let obj = {
						date: this.dialogHandleData.sessionDt,
					};
					getCalenderList(obj).then((res) => {
						if (res.data.code == 0) {
							this.resDate = res.data.data;
							console.log(res.data.data, 'youbing');
							this.tableList = [];
							this.detailTable = [];
							// 调用左边表格的接口
							let obj = {
								date: this.resDate[0].dt,
								type: this.resDate[0].type,
							};
							getInspectionList(obj).then((res) => {
								if (res.data.code == 0) {
									this.tableList = res.data.data;
									// this.page.total = res.data.data.page.total;
									// this.page.current = res.data.data.page.current;
									// this.page.size = res.data.data.page.size;
								}
							});
						}
					});
				}
			});
		},
		handleCancel() {
			this.dialogVisible = false;
		},
	},
	watch: {
		selectDate: {
			handler(val, old) {
				let date = new Date(val);
				let date1 = new Date(old);
				let yy = date.getFullYear();
				let yy1 = date1.getFullYear();
				let mm = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
				let mm1 = date1.getMonth() + 1 < 10 ? '0' + (date1.getMonth() + 1) : date1.getMonth() + 1;
				let mm2 = date.getMonth() + 1;
				//如果新值和旧值所在的月份相同,则不触发方法。
				if (yy + '-' + mm != yy1 + '-' + mm1) {
					this.$emit('watchChild', yy + '-' + mm, mm2);
				}
			},
			deep: true,
		},
	},
};
</script>
<style lang="scss" scoped>
.redStyle {
	color: white;
	background: #ed5555;
	text-align: center;
	margin-left: 3%;
}
.greenStyle {
	color: white;
	background: rgb(59, 191, 59);
	text-align: center;
	margin-left: 3%;
}
.preventClick {
	pointer-events: none;
	color: #c0c4cc;
}
.el-calendar-table:not(.is-range) td.next,
.el-calendar-table:not(.is-range) td.prev {
	pointer-events: none;
}
td.is-pervDay {
	pointer-events: none;
	background-color: rgba(0, 0, 0, 0.3);
	color: #fff;
}
/deep/.el-calendar__header {
	padding: 0px 0px 10px 0px;
}
/deep/.el-calendar-table .el-calendar-day {
	height: 55px;
	cursor: default;
}
/deep/.el-calendar-table td {
	border-bottom: 0px solid #ebeef5;
	border-right: 0px solid #ebeef5;
}
/deep/.el-calendar-table tr td:first-child {
	border-left: 0px solid #ebeef5;
}
/deep/.el-calendar-table tr:first-child td {
	border-top: 0px solid #ebeef5;
}
/deep/.el-calendar__body {
	border: 1px solid #ebeef5;
	padding: 5px;
}

/deep/ .el-calendar__header {
	border-bottom: 0px solid #ebeef5;
}
/deep/ .el-calendar__title {
	display: none;
}
/deep/ .el-calendar-day {
	text-align: center;
}
/deep/.el-calendar__button-group {
	margin-left: 10%;
}
/deep/ .el-input--medium .el-input__inner {
	text-align: center;
}
/deep/ .el-textarea__inner {
	text-align: center;
}
.el-input__inner {
	text-align: center !important;
	line-height: 28px;
	height: 28px;
	width: 100%;
}
.el-date-editor.el-input {
	width: 31%;
	float: left;
}
.el-input__icon {
	line-height: 28px;
}
.el-input--suffix .el-input__inner {
	padding-right: 0px;
}
.el-input__suffix {
	display: none;
}
div:hover {
	color: #2c3e50;
}
.inspection-right-table {
	width: 70%;
	right: 1%;
	top: 7%;
	position: absolute;
}
/deep/.el-select .el-input__inner {
	cursor: pointer;
	padding-right: 1.842105rem;
	text-align: center;
	border: none;
}
.madp-pagination {
	text-align: right;
	position: relative;
	margin-top: 3%;
}
.el-dialog {
	height: 100%;
}
.dialog-left {
	width: 32%;
	height: 100%;
	float: left;
	overflow: hidden;
	.dialog-left-title {
		font-size: 0.9rem;
		text-align: center;
		height: 2.1rem;
		line-height: 2.1rem;
		border-bottom: 1px solid #ebeef5;
	}
	.scrollStyle {
		overflow-y: auto;
		border: 1px solid #ebeef5;
		height: 75vh;
	}
	.madp-chatInfo {
		margin: 25px auto 68px;
		.madp-chatInfo-avatar {
			width: 2.3rem;
			height: 2.3rem;
			margin-bottom: -11px;
			border-radius: 100%;
			margin-right: 10px;
		}
		.madp-chatInfo-name {
			color: #696969;
			font-size: 12px;
		}
		.madp-chatInfo-ename {
			color: #696969;
			font-size: 12px;
			padding-left: 20px;
		}
		.madp-chatInfo-etime {
			color: #80a7e6;
			font-size: 12px;
		}
		.madp-chatInfo-time {
			color: #80a7e6;
			font-size: 12px;
			padding-left: 20px;
		}
		.madp-chatInfo-eavatar {
			width: 2.3rem;
			height: 2.3rem;
			margin-bottom: -11px;
			border-radius: 100%;
			margin-left: 10px;
		}
		.madp-chatInfo-chat {
			display: inline-block;
			padding: 8px 10px;
			border-radius: 8px;
			background: #ed5555;
			color: #fff;
			font-size: 15px;
			margin-top: 10px;
			margin-left: 9%;
		}
		.madp-chatInfo-img {
			width: 125px;
			height: 125px;
			padding: 8px;
			border-radius: 8px;
			background: #ed5555;
			color: #fff;
			font-size: 15px;
			margin-top: 10px;
		}
		.madp-text-over {
			display: inline-block;
			word-wrap: break-all;
			word-break: normal;
			white-space: normal;
			word-break: break-all;
			word-wrap: break-word;
			padding: 0 4px;
		}
		.madp-chatInfo-echat {
			border-radius: 8px;
			background: #ed5555;
			color: #fff;
			font-size: 15px;
			margin-top: 10px;
			margin-right: 9%;
		}
		.madp-chat-box {
			height: 160px;
		}
	}
	.madp-chatInfo-eimg {
		display: flex;
		justify-content: flex-end;
		width: 100%;
		height: 125px !important;
		padding: 8px;
		border-radius: 8px;
		color: #fff;
		font-size: 15px;
		margin-top: 10px;
	}
	.madp-right-audio {
		display: flex;
		justify-content: flex-end;
		width: 100%;
	}
	.madp-chatInfo-audio {
		padding: 8px;
		height: 34px;
		border-radius: 8px;
		background: #2a57a0;
		color: #fff;
		font-size: 15px;
		margin-top: 10px;
	}
	.madp-chatInfo-file {
		width: 84px;
		height: 84px;
		object-fit: contain;
	}
	.madp-file-name {
		width: 160px;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
	.madp-file {
		height: 104px;
		width: 250px;
		display: flex;
		justify-content: space-between;
		align-items: center;
		border: 1px solid #ccc;
		padding: 10px;
		border-radius: 8px;
	}
	.madp-chatInfo-link {
		padding: 8px;
		height: 34px;
		border-radius: 8px;
		background: #2a57a0;
		color: #fff;
		width: 400px;
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
	}
	/deep/.el-date-editor .el-range-separator {
		width: 7%;
	}
	.madp-chat-right {
		display: flex;
		justify-content: flex-end;
	}
}

.dialog-right {
	width: 69%;
	height: 100%;
	margin-left: 32%;
	margin-top: 2.1rem;
}
.dialog-footer {
	margin-top: -2%;
	margin-right: 5%;
}
.el-dialog__footer {
	margin-top: -2%;
	height: 78px;
	background: #fff;
	padding: 4.052632rem;
	text-align: right;
	-webkit-box-sizing: border-box;
	box-sizing: border-box;
}
</style>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/33239.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis7【① 概述 安装 配置】

1. Redis入门概述 1. Redis是什么 Redis全称 远程字典服务器&#xff08;Remote Dictionary Server&#xff09;&#xff0c;它是完全开源的&#xff0c;使用ANSIC语言编写遵守BSD协议&#xff0c;是一个高性能的基于内存的Key-Value数据库&#xff0c;提供了丰富的数据结构&…

windows无法启动RemoteDesktopServices服务(位于本地计算机上)。错误126:找不到指定的模块。

win10的搜索栏输入 注册表编辑器。打开&#xff0c;找到如下路径 计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService\Parameters 将指定数值项ServiceDll的数值数据改成默认值&#xff1a; %SystemRoot%\System32\termsrv.dll 再重新尝试就好了。 …

Spring是什么?

目录 1、Spring的简介 2、Spring七大功能模块 3、Spring的优点 4、Spring的缺点 5、Sprig容器 6、Spring的生态圈&#xff08;重点&#xff09;***** 7、Spring中bean的生命周期 1、Spring的简介 Spring的英文翻译为春天&#xff0c;可以说是给Java程序员带来了春天&…

DAMA数据治理CDGA/CDGP认证考试备考经验分享

一&#xff0c;关于DAMA中国和CDGA/CDGP考试 国际数据管理协会&#xff08;DAMA国际&#xff09;是一个全球性的专业组织&#xff0c;由数据管理和相关的专业人士组成&#xff0c;非营利性机构&#xff0c;厂商中立。协会自1980年成立以来&#xff0c;一直致力于数据管理和数字…

Baumer工业相机堡盟工业相机如何通过BGAPISDK设置多帧采集模式(C#)

Baumer工业相机堡盟工业相机如何通过BGAPISDK设置多帧采集模式&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机BGAPISDK和多帧采集模式的技术背景Baumer工业相机通过BGAPISDK设置多帧采集模式功能1.引用合适的类文件2.通过BGAPISDK设置多帧采集模式功能 Baumer工业相…

Wolfram Mathematica 13.3 特别版

WOLFRAM MATHEMATICA 全球現代技術計算的權威系統 MATHEMATICA 三十年來&#xff0c;Mathematica 定義了技術計算領域的最新技術—並為全球數百萬創新者、教育工作者、學生和其他人提供了主要的計算環境。 Mathematica 以其卓越的技術和簡易實用廣受讚譽&#xff0c;提供了單…

13.RocketMQ之消息的存储与发送

1. 消息存储 1.1 消息存储 分布式队列因为有高可靠性的要求&#xff0c;所以数据要进行持久化存储。 消息生成者发送消息Broker收到消息&#xff0c;将消息进行持久化&#xff0c;在存储中新增一条记录返回ACK给生产者Broker消息给对应的消费者&#xff0c;然后等待消费者返回A…

【MOOC 作业】第5章 链接层

不是标答也不是参考答案 仅从个人理解出发去做题 1、(20分) 在某网络中标识为 A 到 E 的 5 个结点以星形与一台交换机连接&#xff0c;考虑在该网络环境中某个正在学习的交换机的运行情况。假定&#xff1a;该交换机表初始为空。B 向 E 发送一个帧&#xff0c;此时交换机将该数…

[内核笔记1]内核文件结构与缓存——inode和对应描述

由来&#xff1a;公司内部外网记录日志的方式现在都是通过Nginx模块收到数据发送到系统消息队列&#xff0c;然后由另外一个进程来从消息队列读取然后写回磁盘这样的操作&#xff0c;尽量的减少Nginx的阻塞。 但是由于System/V消息队列在使用前需要规定消息长度&#xff0c;且…

自动驾驶专题介绍 ———— 激光雷达标定

文章目录 介绍激光雷达与激光雷达之间的外参标定激光雷达与摄像头的标定 介绍 激光雷达在感知、定位方面发挥着重要作用。跟摄像头一样&#xff0c;激光雷达也是需要进行内外参数标定的。内参标定是指内部激光发射器坐标系与雷达自身坐标系的转换关系&#xff0c;在出厂之前就已…

预训练、微调和上下文学习

最近语言模型在自然语言理解和生成方面取得了显著进展。这些模型通过预训练、微调和上下文学习的组合来学习。在本文中将深入研究这三种主要方法&#xff0c;了解它们之间的差异&#xff0c;并探讨它们如何有助于语言模型的学习过程。 预训练 预训练&#xff08;Pre-training&…

计算机网络--网络传输基本概念

什么是IP地址&#xff1f; 在计算机出厂的时候&#xff0c;有一个唯一标识的物理地址。但是因为厂商不同等各种原因&#xff0c;用来标识一台计算机在网络中是比较麻烦的&#xff0c;于是出现了IP地址&#xff0c;IP地址是互联网协议地址的意思&#xff0c;是“Internet Protoc…

H.264帧结构和RTSP协议源码框架

目录 1、H264编码原理和基本概念 1.1、h.264编码原理 1.2、h.264编码相关的一些概念 2、H264的NAL单元详解 2.1、VCL和NAL的关系 2.2、H.264视频流分析工具 2.3、h264视频流总体分析 2.4、相关概念 3、H264的NAL单元---sps和pps 3.1、sps和pps详解 3.2、H264的profil…

InnoDB的三种行锁(提供具体sql执行案例分析)

InnoDB存储引擎有3种行锁的算法&#xff0c;其分别是&#xff1a; Record Lock&#xff08;记录锁&#xff09;&#xff1a;单个行记录上的范围 (锁住某一行记录)Gap Lock&#xff08;间隙锁&#xff09;&#xff1a;间隙锁&#xff0c;锁定一个范围&#xff0c;但不包含记录本…

人工智能(pytorch)搭建模型14-pytorch搭建Siamese Network模型(孪生网络),实现模型的训练与预测

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型14-pytorch搭建Siamese Network模型(孪生网络)&#xff0c;实现模型的训练与预测。孪生网络是一种用于度量学习&#xff08;Metric Learning&#xff09;和比较学习&#xff08;Compariso…

基于深度学习的人脸面部表情识别系统【含Python源码+PyqtUI界面+原理详解】

功能演示 摘要&#xff1a;面部表情识别&#xff08;Facial Expression Recognition&#xff09;是一种通过技术手段识别人物图像中人脸面部表情的技术。本文详细介绍了其实现的技术原理&#xff0c;同时给出完整的Python实现代码、训练好的深度学习模型&#xff0c;并且通过Py…

GO语言使用最简单的UI方案govcl

接触go语言有一两年时间了。 之前用Qt和C#写过桌面程序&#xff0c;C#会被别人扒皮&#xff0c;极度不爽&#xff1b;Qt默认要带一堆dll&#xff0c;或者静态编译要自己弄或者找库&#xff0c;有的库还缺这缺那&#xff0c;很难编译成功。 如果C# winform可以编译成二进制原生…

商品减库在Redis中的运用

一.商品减库中存在问题 1.传统的代码 1.1引入jar包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.…

基于tensorflow深度学习的猫狗分类识别

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

机器学习之K-means聚类算法

目录 K-means聚类算法 算法流程 优点 缺点 随机点聚类 人脸聚类 旋转物体聚类 K-means聚类算法 K-means聚类算法是一种无监督的学习方法&#xff0c;通过对样本数据进行分组来发现数据内在的结构。K-means的基本思想是将n个实例分成k个簇&#xff0c;使得同一簇内数据相…