|  | @@ -15,13 +15,18 @@ import EditLabelDialog from '/@/views/product-manage/comment-detail/component/Ed
 | 
	
		
			
				|  |  |  import { useResponse } from '/@/utils/useResponse';
 | 
	
		
			
				|  |  |  import { ElMessage } from 'element-plus';
 | 
	
		
			
				|  |  |  import { handleCopy } from '/@/utils/useCopyText';
 | 
	
		
			
				|  |  | +import * as echarts from 'echarts';
 | 
	
		
			
				|  |  | +import 'echarts-wordcloud';
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const isShowLabel = defineModel({ default: false });
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  const props = defineProps({
 | 
	
		
			
				|  |  | -	rowData: <any>Object,
 | 
	
		
			
				|  |  | +  rowData: <any>Object,
 | 
	
		
			
				|  |  |  });
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  const { rowData } = props;
 | 
	
		
			
				|  |  |  const { tableOptions, handlePageChange } = usePagination(fetchList);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -32,317 +37,181 @@ const editData = ref<any>();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const gridRef = ref();
 | 
	
		
			
				|  |  |  const gridOptions: any = reactive({
 | 
	
		
			
				|  |  | -	// id: 'NegativeLabel-table',
 | 
	
		
			
				|  |  | -	// keepSource: true,
 | 
	
		
			
				|  |  | -	height: 620,
 | 
	
		
			
				|  |  | -	size: 'mini',
 | 
	
		
			
				|  |  | -	border: false,
 | 
	
		
			
				|  |  | -	round: true,
 | 
	
		
			
				|  |  | -	stripe: true,
 | 
	
		
			
				|  |  | -	showHeader: true,
 | 
	
		
			
				|  |  | -	showOverflow: true,
 | 
	
		
			
				|  |  | -	currentRowHighLight: true,
 | 
	
		
			
				|  |  | -	toolbarConfig: {
 | 
	
		
			
				|  |  | -		size: 'large',
 | 
	
		
			
				|  |  | -		slots: {
 | 
	
		
			
				|  |  | -			buttons: 'toolbar_buttons',
 | 
	
		
			
				|  |  | -			// tools: 'toolbar_tools',
 | 
	
		
			
				|  |  | -		},
 | 
	
		
			
				|  |  | -	},
 | 
	
		
			
				|  |  | -	rowConfig: {
 | 
	
		
			
				|  |  | -		isHover: true,
 | 
	
		
			
				|  |  | -	},
 | 
	
		
			
				|  |  | -	columnConfig: {
 | 
	
		
			
				|  |  | -		resizable: true,
 | 
	
		
			
				|  |  | -	},
 | 
	
		
			
				|  |  | -	pagerConfig: {
 | 
	
		
			
				|  |  | -		total: tableOptions.value.total,
 | 
	
		
			
				|  |  | -		page: tableOptions.value.page,
 | 
	
		
			
				|  |  | -		limit: tableOptions.value.limit,
 | 
	
		
			
				|  |  | -	},
 | 
	
		
			
				|  |  | -	loading: false,
 | 
	
		
			
				|  |  | -	loadingConfig: {
 | 
	
		
			
				|  |  | -		icon: 'vxe-icon-indicator roll',
 | 
	
		
			
				|  |  | -		text: '正在拼命加载中...',
 | 
	
		
			
				|  |  | -	},
 | 
	
		
			
				|  |  | -	columns: '',
 | 
	
		
			
				|  |  | -	data: '',
 | 
	
		
			
				|  |  | +  // id: 'NegativeLabel-table',
 | 
	
		
			
				|  |  | +  // keepSource: true,
 | 
	
		
			
				|  |  | +  height: 620,
 | 
	
		
			
				|  |  | +  size: 'mini',
 | 
	
		
			
				|  |  | +  border: false,
 | 
	
		
			
				|  |  | +  round: true,
 | 
	
		
			
				|  |  | +  stripe: true,
 | 
	
		
			
				|  |  | +  showHeader: true,
 | 
	
		
			
				|  |  | +  showOverflow: true,
 | 
	
		
			
				|  |  | +  currentRowHighLight: true,
 | 
	
		
			
				|  |  | +  toolbarConfig: {
 | 
	
		
			
				|  |  | +    size: 'large',
 | 
	
		
			
				|  |  | +    slots: {
 | 
	
		
			
				|  |  | +      buttons: 'toolbar_buttons'
 | 
	
		
			
				|  |  | +      // tools: 'toolbar_tools',
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  rowConfig: {
 | 
	
		
			
				|  |  | +    isHover: true
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  columnConfig: {
 | 
	
		
			
				|  |  | +    resizable: true
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  pagerConfig: {
 | 
	
		
			
				|  |  | +    total: tableOptions.value.total,
 | 
	
		
			
				|  |  | +    page: tableOptions.value.page,
 | 
	
		
			
				|  |  | +    limit: tableOptions.value.limit
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  loading: false,
 | 
	
		
			
				|  |  | +  loadingConfig: {
 | 
	
		
			
				|  |  | +    icon: 'vxe-icon-indicator roll',
 | 
	
		
			
				|  |  | +    text: '正在拼命加载中...'
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  columns: '',
 | 
	
		
			
				|  |  | +  data: ''
 | 
	
		
			
				|  |  |  });
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  async function fetchList() {
 | 
	
		
			
				|  |  | -	gridOptions.data = [];
 | 
	
		
			
				|  |  | -	gridOptions.columns = [];
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	const query = {
 | 
	
		
			
				|  |  | -		review: rowData.id,
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -	await useTableData(api.getNegativeTags, query, gridOptions);
 | 
	
		
			
				|  |  | -	await gridRef.value.loadColumn(NegativeLabelColumns);
 | 
	
		
			
				|  |  | -	gridOptions.showHeader = Boolean(gridOptions.data?.length);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -function handleCreate() {
 | 
	
		
			
				|  |  | -	createOpen.value = true;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -function handleEdit(row) {
 | 
	
		
			
				|  |  | -	editOpen.value = true;
 | 
	
		
			
				|  |  | -	editData.value = row;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -import { onBeforeUnmount, ref } from 'vue';
 | 
	
		
			
				|  |  | -import * as api from '../api';
 | 
	
		
			
				|  |  | -import * as echarts from 'echarts';
 | 
	
		
			
				|  |  | -import 'echarts-wordcloud';
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -const props = defineProps({
 | 
	
		
			
				|  |  | -  asin: String
 | 
	
		
			
				|  |  | -});
 | 
	
		
			
				|  |  | -const { asin } = props;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -const loading = ref(false);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -let responseData: any = null;
 | 
	
		
			
				|  |  | -const chartRef: any = useTemplateRef('chartRef');
 | 
	
		
			
				|  |  | -let chart: echarts.ECharts | null = null;
 | 
	
		
			
				|  |  | -let resizeObserver: ResizeObserver | null = null;
 | 
	
		
			
				|  |  | -const hasData = ref(true);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -onBeforeMount(() => {
 | 
	
		
			
				|  |  | -  fetchWordCloudData();
 | 
	
		
			
				|  |  | -});
 | 
	
		
			
				|  |  | +  gridOptions.data = [];
 | 
	
		
			
				|  |  | +  gridOptions.columns = [];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -onBeforeUnmount(() => {
 | 
	
		
			
				|  |  | -  // 清理 ResizeObserver
 | 
	
		
			
				|  |  | -  if (resizeObserver) {
 | 
	
		
			
				|  |  | -    resizeObserver.disconnect();
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  if (chart) {
 | 
	
		
			
				|  |  | -    chart.dispose();
 | 
	
		
			
				|  |  | -    chart = null;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -});
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -async function fetchWordCloudData() {
 | 
	
		
			
				|  |  | -  loading.value = true;
 | 
	
		
			
				|  |  |    const query = {
 | 
	
		
			
				|  |  | -    asin,
 | 
	
		
			
				|  |  | -    agg_field: 'raw_label'
 | 
	
		
			
				|  |  | +    review: rowData.id
 | 
	
		
			
				|  |  |    };
 | 
	
		
			
				|  |  | -  try {
 | 
	
		
			
				|  |  | -    responseData = await api.getWordCloudData(query);
 | 
	
		
			
				|  |  | -    if (!responseData.data || responseData.data.length === 0) {
 | 
	
		
			
				|  |  | -      // 处理空数据的情况
 | 
	
		
			
				|  |  | -      hasData.value = false;
 | 
	
		
			
				|  |  | -      if (chart) {
 | 
	
		
			
				|  |  | -        chart.clear();
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      return;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    hasData.value = true;
 | 
	
		
			
				|  |  | -    setOption();
 | 
	
		
			
				|  |  | -    // initChart(option);
 | 
	
		
			
				|  |  | -  } catch (error) {
 | 
	
		
			
				|  |  | -    console.error('==Error==', error);
 | 
	
		
			
				|  |  | -  } finally {
 | 
	
		
			
				|  |  | -    loading.value = false;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +  await useTableData(api.getNegativeTags, query, gridOptions);
 | 
	
		
			
				|  |  | +  await gridRef.value.loadColumn(NegativeLabelColumns);
 | 
	
		
			
				|  |  | +  gridOptions.showHeader = Boolean(gridOptions.data?.length);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -function setOption() {
 | 
	
		
			
				|  |  | -  const option = {
 | 
	
		
			
				|  |  | -    title: {
 | 
	
		
			
				|  |  | -      text: '负面标签'
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    tooltip: {
 | 
	
		
			
				|  |  | -      show: true
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    series: [
 | 
	
		
			
				|  |  | -      {
 | 
	
		
			
				|  |  | -        type: 'wordCloud',
 | 
	
		
			
				|  |  | -        width: '90%',
 | 
	
		
			
				|  |  | -        height: '85%',
 | 
	
		
			
				|  |  | -        // 词云图的形状
 | 
	
		
			
				|  |  | -        shape: 'star', // 可以是 'circle', 'cardioid', 'diamond', 'triangle-forward', 'triangle', 'pentagon', 'star'
 | 
	
		
			
				|  |  | -        // 控制字体大小
 | 
	
		
			
				|  |  | -        sizeRange: [12, 60],
 | 
	
		
			
				|  |  | -        // 文本旋转角度
 | 
	
		
			
				|  |  | -        rotationRange: [0, 0],
 | 
	
		
			
				|  |  | -        rotationStep: 45,
 | 
	
		
			
				|  |  | -        gridSize: 8,
 | 
	
		
			
				|  |  | -        drawOutOfBound: false,
 | 
	
		
			
				|  |  | -        shrinkToFit: false,
 | 
	
		
			
				|  |  | -        layoutAnimation: true,
 | 
	
		
			
				|  |  | -        // 全局的文字样式
 | 
	
		
			
				|  |  | -        textStyle: {
 | 
	
		
			
				|  |  | -          fontFamily: 'PingFang',
 | 
	
		
			
				|  |  | -          fontWeight: 'bold',
 | 
	
		
			
				|  |  | -          // Color can be a callback function or a color string
 | 
	
		
			
				|  |  | -          color: function () {
 | 
	
		
			
				|  |  | -            // Random color
 | 
	
		
			
				|  |  | -            return 'rgb(' + [
 | 
	
		
			
				|  |  | -              Math.round(Math.random() * 160),
 | 
	
		
			
				|  |  | -              Math.round(Math.random() * 160),
 | 
	
		
			
				|  |  | -              Math.round(Math.random() * 160)
 | 
	
		
			
				|  |  | -            ].join(',') + ')'
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -        },
 | 
	
		
			
				|  |  | -        // 鼠标hover时的样式
 | 
	
		
			
				|  |  | -        emphasis: {
 | 
	
		
			
				|  |  | -          focus: 'self',
 | 
	
		
			
				|  |  | -          textStyle: {
 | 
	
		
			
				|  |  | -            textShadowBlur: 10,
 | 
	
		
			
				|  |  | -            textShadowColor: '#333'
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -        },
 | 
	
		
			
				|  |  | -        // left: '10%',
 | 
	
		
			
				|  |  | -        // top: '10%',
 | 
	
		
			
				|  |  | -        // right: '10%',
 | 
	
		
			
				|  |  | -        // bottom: '10%',
 | 
	
		
			
				|  |  | -        data: responseData.data,
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    ],
 | 
	
		
			
				|  |  | -    backgroundColor: '#fff'
 | 
	
		
			
				|  |  | -  };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  if (!chart) {
 | 
	
		
			
				|  |  | -    chart = echarts.init(chartRef.value);
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  chart.setOption(option);
 | 
	
		
			
				|  |  | +function handleCreate() {
 | 
	
		
			
				|  |  | +  createOpen.value = true;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // 添加 ResizeObserver 以处理图表大小变化
 | 
	
		
			
				|  |  | -  if (!resizeObserver) {
 | 
	
		
			
				|  |  | -    resizeObserver = new ResizeObserver(() => {
 | 
	
		
			
				|  |  | -      chart?.resize();
 | 
	
		
			
				|  |  | -    });
 | 
	
		
			
				|  |  | -    resizeObserver.observe(chartRef.value);
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +function handleEdit(row: any) {
 | 
	
		
			
				|  |  | +  editOpen.value = true;
 | 
	
		
			
				|  |  | +  editData.value = row;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  async function singleDelete(row: any) {
 | 
	
		
			
				|  |  | -	const res = await useResponse(api.deleteNegativeTags, row);
 | 
	
		
			
				|  |  | -	if (res.code === 2000) {
 | 
	
		
			
				|  |  | -		ElMessage.success({ message: '删除成功', plain: true });
 | 
	
		
			
				|  |  | -		await fetchList();
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +  const res = await useResponse(api.deleteNegativeTags, row);
 | 
	
		
			
				|  |  | +  if (res.code === 2000) {
 | 
	
		
			
				|  |  | +    ElMessage.success({ message: '删除成功', plain: true });
 | 
	
		
			
				|  |  | +    await fetchList();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  function cellStyle() {
 | 
	
		
			
				|  |  | -	return{
 | 
	
		
			
				|  |  | -		fontWeight: 500,
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +  return {
 | 
	
		
			
				|  |  | +    fontWeight: 500
 | 
	
		
			
				|  |  | +  };
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  onMounted(() => {
 | 
	
		
			
				|  |  | -	fetchList();
 | 
	
		
			
				|  |  | +  fetchList();
 | 
	
		
			
				|  |  |  });
 | 
	
		
			
				|  |  |  </script>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  <template>
 | 
	
		
			
				|  |  | -	<div class="drawer-container">
 | 
	
		
			
				|  |  | -		<el-drawer
 | 
	
		
			
				|  |  | -			ref="editDrawer"
 | 
	
		
			
				|  |  | -			v-model="isShowLabel"
 | 
	
		
			
				|  |  | -			:show-close="false"
 | 
	
		
			
				|  |  | -			direction="rtl"
 | 
	
		
			
				|  |  | -			size="50%"
 | 
	
		
			
				|  |  | -			style="background-color: #f3f4fb"
 | 
	
		
			
				|  |  | -			title="负面标签"
 | 
	
		
			
				|  |  | -		>
 | 
	
		
			
				|  |  | -			<div class="sticky top-0" style="background-color: #f3f4fb; min-height: 20px; z-index: 2"></div>
 | 
	
		
			
				|  |  | -			<div class="px-5">
 | 
	
		
			
				|  |  | -				<el-card class="mb-3">
 | 
	
		
			
				|  |  | -					<el-descriptions :column="1" direction="vertical">
 | 
	
		
			
				|  |  | -						<el-descriptions-item>
 | 
	
		
			
				|  |  | -							<template #label>
 | 
	
		
			
				|  |  | -								<div class="title-item">标题</div>
 | 
	
		
			
				|  |  | -							</template>
 | 
	
		
			
				|  |  | -							<span class="cell-item">{{ rowData.title }}</span>
 | 
	
		
			
				|  |  | -						</el-descriptions-item>
 | 
	
		
			
				|  |  | -						<el-descriptions-item>
 | 
	
		
			
				|  |  | -							<template #label>
 | 
	
		
			
				|  |  | -								<div class="title-item">评论内容</div>
 | 
	
		
			
				|  |  | -							</template>
 | 
	
		
			
				|  |  | -							<span class="cell-item">{{ rowData.content }}</span>
 | 
	
		
			
				|  |  | -							<el-icon class="ml-2 cursor-pointer" @click="handleCopy(rowData.content)">
 | 
	
		
			
				|  |  | -								<DocumentCopy />
 | 
	
		
			
				|  |  | -							</el-icon>
 | 
	
		
			
				|  |  | -						</el-descriptions-item>
 | 
	
		
			
				|  |  | -					</el-descriptions>
 | 
	
		
			
				|  |  | -				</el-card>
 | 
	
		
			
				|  |  | -				<el-card>
 | 
	
		
			
				|  |  | -					<vxe-grid ref="gridRef" v-bind="gridOptions" :cell-style="cellStyle">
 | 
	
		
			
				|  |  | -						<template #toolbar_buttons>
 | 
	
		
			
				|  |  | -							<div class="flex gap-2">
 | 
	
		
			
				|  |  | -								<PermissionButton :icon="Plus" plain round type="primary" @click="handleCreate"> 新 增 </PermissionButton>
 | 
	
		
			
				|  |  | -							</div>
 | 
	
		
			
				|  |  | -						</template>
 | 
	
		
			
				|  |  | -						<template #operate="{ row }">
 | 
	
		
			
				|  |  | -							<div class="flex justify-center gap-2">
 | 
	
		
			
				|  |  | -							<el-button :icon="Edit" link type="primary" @click="handleEdit(row)"></el-button>
 | 
	
		
			
				|  |  | -							<el-popconfirm
 | 
	
		
			
				|  |  | -								:icon="InfoFilled"
 | 
	
		
			
				|  |  | -								icon-color="#626AEF"
 | 
	
		
			
				|  |  | -								title="你确定要删除此项吗?"
 | 
	
		
			
				|  |  | -								width="220"
 | 
	
		
			
				|  |  | -								@confirm="singleDelete(row)"
 | 
	
		
			
				|  |  | -							>
 | 
	
		
			
				|  |  | -								<template #reference>
 | 
	
		
			
				|  |  | -									<PermissionButton link type="danger">
 | 
	
		
			
				|  |  | -										<el-icon>
 | 
	
		
			
				|  |  | -											<Delete />
 | 
	
		
			
				|  |  | -										</el-icon>
 | 
	
		
			
				|  |  | -									</PermissionButton>
 | 
	
		
			
				|  |  | -								</template>
 | 
	
		
			
				|  |  | -								<template #actions="{ confirm, cancel }">
 | 
	
		
			
				|  |  | -									<el-button size="small" @click="cancel">No!</el-button>
 | 
	
		
			
				|  |  | -									<el-button
 | 
	
		
			
				|  |  | -										size="small"
 | 
	
		
			
				|  |  | -										type="danger"
 | 
	
		
			
				|  |  | -										@click="confirm"
 | 
	
		
			
				|  |  | -									>
 | 
	
		
			
				|  |  | -										Yes?
 | 
	
		
			
				|  |  | -									</el-button>
 | 
	
		
			
				|  |  | -								</template>
 | 
	
		
			
				|  |  | -							</el-popconfirm>
 | 
	
		
			
				|  |  | -								</div>
 | 
	
		
			
				|  |  | -						</template>
 | 
	
		
			
				|  |  | -						<template #pager>
 | 
	
		
			
				|  |  | -							<vxe-pager
 | 
	
		
			
				|  |  | -								v-model:currentPage="gridOptions.pagerConfig.page"
 | 
	
		
			
				|  |  | -								v-model:pageSize="gridOptions.pagerConfig.limit"
 | 
	
		
			
				|  |  | -								:total="gridOptions.pagerConfig.total"
 | 
	
		
			
				|  |  | -								class="mt-1.5"
 | 
	
		
			
				|  |  | -								@page-change="handlePageChange"
 | 
	
		
			
				|  |  | -							/>
 | 
	
		
			
				|  |  | -						</template>
 | 
	
		
			
				|  |  | -					</vxe-grid>
 | 
	
		
			
				|  |  | -				</el-card>
 | 
	
		
			
				|  |  | -			</div>
 | 
	
		
			
				|  |  | -		</el-drawer>
 | 
	
		
			
				|  |  | -		<CreateLabelDialog v-if="createOpen" v-model="createOpen" :rowData="rowData" @refresh="fetchList"></CreateLabelDialog>
 | 
	
		
			
				|  |  | -		<EditLabelDialog v-if="editOpen" v-model="editOpen" :editData="editData" :rowData="rowData" @refresh="fetchList"></EditLabelDialog>
 | 
	
		
			
				|  |  | -	</div>
 | 
	
		
			
				|  |  | -  <el-card v-loading="loading" class="border-none" shadow="never">
 | 
	
		
			
				|  |  | -    <!-- 空状态 和 词云图 -->
 | 
	
		
			
				|  |  | -    <div class="w-full" style="min-height: 500px">
 | 
	
		
			
				|  |  | -      <div v-show="!loading && !hasData" style="min-height: 500px">
 | 
	
		
			
				|  |  | -        <el-empty :image-size="300" />
 | 
	
		
			
				|  |  | +  <div class="drawer-container">
 | 
	
		
			
				|  |  | +    <el-drawer
 | 
	
		
			
				|  |  | +        ref="editDrawer"
 | 
	
		
			
				|  |  | +        v-model="isShowLabel"
 | 
	
		
			
				|  |  | +        :show-close="false"
 | 
	
		
			
				|  |  | +        direction="rtl"
 | 
	
		
			
				|  |  | +        size="50%"
 | 
	
		
			
				|  |  | +        style="background-color: #f3f4fb"
 | 
	
		
			
				|  |  | +        title="负面标签"
 | 
	
		
			
				|  |  | +    >
 | 
	
		
			
				|  |  | +      <div class="sticky top-0" style="background-color: #f3f4fb; min-height: 20px; z-index: 2"></div>
 | 
	
		
			
				|  |  | +      <div class="px-5">
 | 
	
		
			
				|  |  | +        <el-card class="mb-3">
 | 
	
		
			
				|  |  | +          <el-descriptions :column="1" direction="vertical">
 | 
	
		
			
				|  |  | +            <el-descriptions-item>
 | 
	
		
			
				|  |  | +              <template #label>
 | 
	
		
			
				|  |  | +                <div class="title-item">标题</div>
 | 
	
		
			
				|  |  | +              </template>
 | 
	
		
			
				|  |  | +              <span class="cell-item">{{ rowData.title }}</span>
 | 
	
		
			
				|  |  | +            </el-descriptions-item>
 | 
	
		
			
				|  |  | +            <el-descriptions-item>
 | 
	
		
			
				|  |  | +              <template #label>
 | 
	
		
			
				|  |  | +                <div class="title-item">评论内容</div>
 | 
	
		
			
				|  |  | +              </template>
 | 
	
		
			
				|  |  | +              <span class="cell-item">{{ rowData.content }}</span>
 | 
	
		
			
				|  |  | +              <el-icon class="ml-2 cursor-pointer" @click="handleCopy(rowData.content)">
 | 
	
		
			
				|  |  | +                <DocumentCopy />
 | 
	
		
			
				|  |  | +              </el-icon>
 | 
	
		
			
				|  |  | +            </el-descriptions-item>
 | 
	
		
			
				|  |  | +          </el-descriptions>
 | 
	
		
			
				|  |  | +        </el-card>
 | 
	
		
			
				|  |  | +        <el-card>
 | 
	
		
			
				|  |  | +          <vxe-grid ref="gridRef" :cell-style="cellStyle" v-bind="gridOptions">
 | 
	
		
			
				|  |  | +            <template #toolbar_buttons>
 | 
	
		
			
				|  |  | +              <div class="flex gap-2">
 | 
	
		
			
				|  |  | +                <PermissionButton :icon="Plus" plain round type="primary" @click="handleCreate"> 新 增</PermissionButton>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            </template>
 | 
	
		
			
				|  |  | +            <template #operate="{ row }">
 | 
	
		
			
				|  |  | +              <div class="flex justify-center gap-2">
 | 
	
		
			
				|  |  | +                <el-button :icon="Edit" link type="primary" @click="handleEdit(row)"></el-button>
 | 
	
		
			
				|  |  | +                <el-popconfirm
 | 
	
		
			
				|  |  | +                    :icon="InfoFilled"
 | 
	
		
			
				|  |  | +                    icon-color="#626AEF"
 | 
	
		
			
				|  |  | +                    title="你确定要删除此项吗?"
 | 
	
		
			
				|  |  | +                    width="220"
 | 
	
		
			
				|  |  | +                    @confirm="singleDelete(row)"
 | 
	
		
			
				|  |  | +                >
 | 
	
		
			
				|  |  | +                  <template #reference>
 | 
	
		
			
				|  |  | +                    <PermissionButton link type="danger">
 | 
	
		
			
				|  |  | +                      <el-icon>
 | 
	
		
			
				|  |  | +                        <Delete />
 | 
	
		
			
				|  |  | +                      </el-icon>
 | 
	
		
			
				|  |  | +                    </PermissionButton>
 | 
	
		
			
				|  |  | +                  </template>
 | 
	
		
			
				|  |  | +                  <template #actions="{ confirm, cancel }">
 | 
	
		
			
				|  |  | +                    <el-button size="small" @click="cancel">No!</el-button>
 | 
	
		
			
				|  |  | +                    <el-button
 | 
	
		
			
				|  |  | +                        size="small"
 | 
	
		
			
				|  |  | +                        type="danger"
 | 
	
		
			
				|  |  | +                        @click="confirm"
 | 
	
		
			
				|  |  | +                    >
 | 
	
		
			
				|  |  | +                      Yes?
 | 
	
		
			
				|  |  | +                    </el-button>
 | 
	
		
			
				|  |  | +                  </template>
 | 
	
		
			
				|  |  | +                </el-popconfirm>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            </template>
 | 
	
		
			
				|  |  | +            <template #pager>
 | 
	
		
			
				|  |  | +              <vxe-pager
 | 
	
		
			
				|  |  | +                  v-model:currentPage="gridOptions.pagerConfig.page"
 | 
	
		
			
				|  |  | +                  v-model:pageSize="gridOptions.pagerConfig.limit"
 | 
	
		
			
				|  |  | +                  :total="gridOptions.pagerConfig.total"
 | 
	
		
			
				|  |  | +                  class="mt-1.5"
 | 
	
		
			
				|  |  | +                  @page-change="handlePageChange"
 | 
	
		
			
				|  |  | +              />
 | 
	
		
			
				|  |  | +            </template>
 | 
	
		
			
				|  |  | +          </vxe-grid>
 | 
	
		
			
				|  |  | +        </el-card>
 | 
	
		
			
				|  |  |        </div>
 | 
	
		
			
				|  |  | -      <div v-show="hasData" ref="chartRef" style="width: 100%; height: 500px"></div>
 | 
	
		
			
				|  |  | -    </div>
 | 
	
		
			
				|  |  | -  </el-card>
 | 
	
		
			
				|  |  | +    </el-drawer>
 | 
	
		
			
				|  |  | +    <CreateLabelDialog v-if="createOpen" v-model="createOpen" :rowData="rowData" @refresh="fetchList"></CreateLabelDialog>
 | 
	
		
			
				|  |  | +    <EditLabelDialog v-if="editOpen" v-model="editOpen" :editData="editData" :rowData="rowData"
 | 
	
		
			
				|  |  | +                     @refresh="fetchList"></EditLabelDialog>
 | 
	
		
			
				|  |  | +  </div>
 | 
	
		
			
				|  |  | +  
 | 
	
		
			
				|  |  |  </template>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  <style scoped>
 | 
	
		
			
				|  |  |  .title-item {
 | 
	
		
			
				|  |  | -	font-weight: bold;
 | 
	
		
			
				|  |  | -	font-size: 16px;
 | 
	
		
			
				|  |  | +  font-weight: bold;
 | 
	
		
			
				|  |  | +  font-size: 16px;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  .cell-item {
 | 
	
		
			
				|  |  | -	font-size: 14px;
 | 
	
		
			
				|  |  | -	font-weight: 600;
 | 
	
		
			
				|  |  | -	color: #666;
 | 
	
		
			
				|  |  | +  font-size: 14px;
 | 
	
		
			
				|  |  | +  font-weight: 600;
 | 
	
		
			
				|  |  | +  color: #666;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  </style>
 |