|
|
@@ -1,40 +1,97 @@
|
|
|
<template>
|
|
|
<div class="knowledge_graph" ref="knowledgeGraph" :style="{ maxHeight: containerHeight + 'px' }">
|
|
|
- <!-- 环形扩散图组件 -->
|
|
|
- <circular-diffusion
|
|
|
- :activeView="activeView"
|
|
|
- :subjectName="subjectName"
|
|
|
- :subjectScoreRate="subjectScoreRate"
|
|
|
- :tableData="displayTableData"
|
|
|
- :fatalVulnerability="displayFatalVulnerability"
|
|
|
- :highVulnerability="displayHighVulnerability"
|
|
|
- :allKnowledgeList="displayAllKnowledgeList"
|
|
|
- :classLevel="classLevel"
|
|
|
- :classGroupName="classGroupName"
|
|
|
- :currentKnowledgeId="currentKnowledgeId"
|
|
|
- @view-change="handleViewChange"
|
|
|
- @legend-change="handleLegendChange"
|
|
|
- @activeTabChange="handleActiveTabChange"
|
|
|
- @knowledge-item-click="handleKnowledgeItemClick"
|
|
|
- />
|
|
|
+
|
|
|
+ <div class="graph_top">
|
|
|
+ <!-- 顶部信息模块 -->
|
|
|
+ <div class="knowledge_header">
|
|
|
+ <div class="header_top">
|
|
|
+ <span class="header_title">我的知识图谱</span>
|
|
|
+ <!-- 年级选择标签,只有一个年级时不显示 -->
|
|
|
+ <el-checkbox-group v-if="gradeList && gradeList.length > 1" v-model="currentGradeList" @change="handleGradeChange">
|
|
|
+ <el-checkbox v-for="grade in gradeList" :key="grade.value" :label="grade.value">
|
|
|
+ {{ grade.label }}
|
|
|
+ </el-checkbox>
|
|
|
+ </el-checkbox-group>
|
|
|
+ </div>
|
|
|
+ <div class="header_stats">
|
|
|
+ <span class="stats_text">
|
|
|
+ 你的知识图谱共包含 <span class="stats_num">{{ totalCount }}</span> 个知识点。当前
|
|
|
+ <span class="stats_weak">红色薄弱知识点 {{ weakCount }}</span> 个,
|
|
|
+ <span class="stats_good">黄色待提升知识点 {{ goodCount }}</span> 个,
|
|
|
+ <span class="stats_excellent">坚持练习,把全部知识点都进阶为绿色已掌握状态吧!</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 环形扩散图组件 -->
|
|
|
+ <circular-diffusion :activeView="activeView" :subjectName="subjectName" :subjectScoreRate="subjectScoreRate"
|
|
|
+ :tableData="displayTableData" :fatalVulnerability="displayFatalVulnerability"
|
|
|
+ :highVulnerability="displayHighVulnerability" :allKnowledgeList="displayAllKnowledgeList"
|
|
|
+ :classLevel="classLevel" :classGroupName="classGroupName" :currentKnowledgeId="currentKnowledgeId"
|
|
|
+ @view-change="handleViewChange" @legend-change="handleLegendChange" @activeTabChange="handleActiveTabChange"
|
|
|
+ @knowledge-item-click="handleKnowledgeItemClick" />
|
|
|
+ </div>
|
|
|
+
|
|
|
|
|
|
<!-- 区域展示组件 -->
|
|
|
- <region
|
|
|
- :allKnowledgeList="displayAllKnowledgeList"
|
|
|
- @add-practice="handleAddPractice"
|
|
|
- />
|
|
|
+ <region :allKnowledgeList="displayAllKnowledgeList" @add-practice="handleAddPractice" />
|
|
|
+
|
|
|
+ <!-- ==================== 测试:CommonTree 公共树形组件 ==================== -->
|
|
|
+ <div class="tree_test_section">
|
|
|
+ <div class="tree_test_title">
|
|
|
+ <span>📋 公共树形组件(CommonTree)测试区域</span>
|
|
|
+ <el-button-group>
|
|
|
+ <el-button size="mini" type="primary" @click="testGetChecked">获取选中节点</el-button>
|
|
|
+ <el-button size="mini" @click="testClearChecked">清空选中</el-button>
|
|
|
+ </el-button-group>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 左侧树形组件 -->
|
|
|
+ <div class="tree_test_body">
|
|
|
+ <div class="tree_panel">
|
|
|
+ <CommonTree
|
|
|
+ ref="treeTestRef"
|
|
|
+ :tree-data="mockTreeData"
|
|
|
+ :tree-props="{ label: 'label', children: 'children' }"
|
|
|
+ node-key="id"
|
|
|
+ show-checkbox
|
|
|
+ :default-expand-all="false"
|
|
|
+ @node-click="handleTestNodeClick"
|
|
|
+ @node-check="handleTestNodeCheck"
|
|
|
+ @ai-explain="handleTestAiExplain"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 右侧回传日志面板 -->
|
|
|
+ <div class="tree_log_panel">
|
|
|
+ <div class="log_title">回传事件日志:</div>
|
|
|
+ <div class="log_list">
|
|
|
+ <div v-for="(log, idx) in eventLogs" :key="idx" class="log_item" :class="'log-' + log.type">
|
|
|
+ <div class="log_tag">[{{ log.tag }}]</div>
|
|
|
+ <div class="log_time">{{ log.time }}</div>
|
|
|
+ <pre class="log_content">{{ log.msg }}</pre>
|
|
|
+ </div>
|
|
|
+ <div v-if="eventLogs.length === 0" class="log_empty">
|
|
|
+ 请点击左侧树节点 / 勾选复选框 / 悬停后点"AI讲解"按钮 ↖
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import CircularDiffusion from './knowledgeGraph/circularDiffusion.vue';
|
|
|
import Region from './knowledgeGraph/region.vue';
|
|
|
+import CommonTree from '@/components/CommonTree.vue';
|
|
|
|
|
|
export default {
|
|
|
name: 'KnowledgeGraph',
|
|
|
components: {
|
|
|
CircularDiffusion,
|
|
|
- Region
|
|
|
+ Region,
|
|
|
+ CommonTree
|
|
|
},
|
|
|
props: {
|
|
|
activeView: {
|
|
|
@@ -86,6 +143,92 @@ export default {
|
|
|
return {
|
|
|
// 容器最大高度
|
|
|
containerHeight: 600,
|
|
|
+ // 当前选中的年级列表(多选)
|
|
|
+ currentGradeList: ['grade3'],
|
|
|
+ // 年级列表
|
|
|
+ gradeList: [
|
|
|
+ { label: '初一', value: 'grade1' },
|
|
|
+ { label: '初二', value: 'grade2' },
|
|
|
+ { label: '初三', value: 'grade3' }
|
|
|
+ ],
|
|
|
+ // CommonTree 事件日志列表(用于右侧回传展示)
|
|
|
+ eventLogs: [],
|
|
|
+ // ========== 测试 CommonTree 组件的树形假数据 ==========
|
|
|
+ // 结构:id / label / count(可选)/ children(可选)
|
|
|
+ mockTreeData: [
|
|
|
+ {
|
|
|
+ id: 'chinese',
|
|
|
+ label: '语言文学应用',
|
|
|
+ count: 60,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ id: 'modern-reading',
|
|
|
+ label: '现代文阅读',
|
|
|
+ count: 60,
|
|
|
+ children: [
|
|
|
+ { id: 'discourse', label: '论述类文本阅读', count: 60 },
|
|
|
+ { id: 'practical', label: '实用类文本阅读', count: 60 },
|
|
|
+ { id: 'literary', label: '文学类文本阅读', count: 60 }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'ancient-reading',
|
|
|
+ label: '古代诗文阅读',
|
|
|
+ count: 60,
|
|
|
+ children: [
|
|
|
+ { id: 'classical-chinese', label: '文言文阅读', count: 60 },
|
|
|
+ { id: 'ancient-poetry', label: '古代诗歌阅读', count: 60 },
|
|
|
+ { id: 'water-resource', label: '水资源跨区域调配对区域发展的影响', count: 60 }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'whole-book',
|
|
|
+ label: '整本书阅读',
|
|
|
+ count: 60,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ id: 'literary-classics',
|
|
|
+ label: '文学名著',
|
|
|
+ count: 60,
|
|
|
+ children: [
|
|
|
+ { id: 'luoshen', label: '《洛神赋》', count: 60 },
|
|
|
+ { id: 'tengwang', label: '《滕王阁序》', count: 60 }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ { id: 'culture-classics', label: '文化经典', count: 60 },
|
|
|
+ { id: 'academic-works', label: '学术著作', count: 60 }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'math',
|
|
|
+ label: '数学知识体系',
|
|
|
+ count: 140,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ id: 'math-function',
|
|
|
+ label: '函数与方程',
|
|
|
+ count: 30,
|
|
|
+ children: [
|
|
|
+ { id: 'quadratic', label: '一元二次方程', count: 20 },
|
|
|
+ { id: 'function-graph', label: '函数图像', count: 10 }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'math-geometry',
|
|
|
+ label: '几何图形',
|
|
|
+ count: 50,
|
|
|
+ children: [
|
|
|
+ { id: 'triangle', label: '三角形', count: 20 },
|
|
|
+ { id: 'circle-prop', label: '圆的性质', count: 30 }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ { id: 'math-probability', label: '概率统计', count: 30 },
|
|
|
+ { id: 'math-solid', label: '立体几何', count: 30 }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
// 假数据:表格树形结构数据(用于图表渲染)
|
|
|
// knowledgeType: 1=薄弱(红色), 2=良好(黄色), 3=优秀(绿色)
|
|
|
// gradeScoreRate: 年级得分率,用于判断节点是否有数据
|
|
|
@@ -252,6 +395,22 @@ export default {
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
|
+ // 统计知识点总数
|
|
|
+ totalCount() {
|
|
|
+ return this.displayAllKnowledgeList.length;
|
|
|
+ },
|
|
|
+ // 薄弱知识点数量(knowledgeType === 1)
|
|
|
+ weakCount() {
|
|
|
+ return this.displayAllKnowledgeList.filter(item => item.knowledgeType === 1).length;
|
|
|
+ },
|
|
|
+ // 良好/待提升知识点数量(knowledgeType === 2)
|
|
|
+ goodCount() {
|
|
|
+ return this.displayAllKnowledgeList.filter(item => item.knowledgeType === 2).length;
|
|
|
+ },
|
|
|
+ // 优秀知识点数量(knowledgeType === 3)
|
|
|
+ excellentCount() {
|
|
|
+ return this.displayAllKnowledgeList.filter(item => item.knowledgeType === 3).length;
|
|
|
+ },
|
|
|
// 实际显示的表格数据:props为空时使用假数据
|
|
|
displayTableData() {
|
|
|
if (this.tableData && this.tableData.length > 0) {
|
|
|
@@ -319,6 +478,11 @@ export default {
|
|
|
window.removeEventListener('resize', this.calculateContainerHeight);
|
|
|
},
|
|
|
methods: {
|
|
|
+ // 年级切换(多选)
|
|
|
+ handleGradeChange(gradeList) {
|
|
|
+ this.currentGradeList = gradeList;
|
|
|
+ this.$emit('grade-change', gradeList);
|
|
|
+ },
|
|
|
// 计算容器高度
|
|
|
calculateContainerHeight() {
|
|
|
if (this.$refs.knowledgeGraph) {
|
|
|
@@ -334,25 +498,114 @@ export default {
|
|
|
handleViewChange(view) {
|
|
|
this.$emit('view-change', view);
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
// 处理图例变化
|
|
|
handleLegendChange(data) {
|
|
|
this.$emit('legend-change', data);
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
// 处理tab切换
|
|
|
handleActiveTabChange(tab) {
|
|
|
this.$emit('activeTabChange', tab);
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
// 处理知识点点击
|
|
|
handleKnowledgeItemClick(data) {
|
|
|
this.$emit('knowledge-item-click', data);
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
// 处理加入练习
|
|
|
handleAddPractice(item) {
|
|
|
this.$emit('add-practice', item);
|
|
|
+ },
|
|
|
+
|
|
|
+ // ==================== CommonTree 组件测试方法 ====================
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 追加日志到右侧面板
|
|
|
+ * @param {String} type - 日志类型(info/warn/success/error)
|
|
|
+ * @param {String} tag - 显示标签
|
|
|
+ * @param {String} msg - 日志内容
|
|
|
+ */
|
|
|
+ appendLog(type, tag, msg) {
|
|
|
+ const now = new Date();
|
|
|
+ const time = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;
|
|
|
+ this.eventLogs.unshift({ type, tag, time, msg });
|
|
|
+ // 只保留最近10条日志
|
|
|
+ if (this.eventLogs.length > 10) this.eventLogs.pop();
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 【事件回传1】树节点点击(单选)
|
|
|
+ * @param {Object} data - 当前节点用户数据
|
|
|
+ * @param {Object} node - el-tree 节点实例
|
|
|
+ */
|
|
|
+ handleTestNodeClick(data, node) {
|
|
|
+ const logMsg =
|
|
|
+ `节点ID: ${data.id}\n` +
|
|
|
+ `节点名称: ${data.label}\n` +
|
|
|
+ `节点层级: ${node.level}\n` +
|
|
|
+ `是否叶子: ${node.isLeaf ? '是' : '否'}\n` +
|
|
|
+ `计数count: ${data.count ?? '无'}\n` +
|
|
|
+ `\n完整data: ${JSON.stringify(data, null, 2)}`;
|
|
|
+ console.log('%c[KnowledgeGraph] node-click 回传数据: ', 'background:#2E64FA;color:#fff;padding:4px 8px;border-radius:4px;', { data, node });
|
|
|
+ this.appendLog('info', '节点点击', logMsg);
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 【事件回传2】复选框勾选变化(多选)
|
|
|
+ * @param {Object} data - 当前操作的节点数据
|
|
|
+ * @param {Object} checkedInfo - 勾选状态详情 { checkedNodes, checkedKeys, halfCheckedKeys }
|
|
|
+ */
|
|
|
+ handleTestNodeCheck(data, checkedInfo) {
|
|
|
+ const selectedLabels = checkedInfo.checkedNodes.map(n => n.label).join('、') || '(无)';
|
|
|
+ const logMsg =
|
|
|
+ `当前操作节点: ${data.label}\n` +
|
|
|
+ `已勾选节点数: ${checkedInfo.checkedNodes.length}\n` +
|
|
|
+ `已勾选key: [${checkedInfo.checkedKeys.join(', ')}]\n` +
|
|
|
+ `半选key: [${(checkedInfo.halfCheckedKeys || []).join(', ') || '无'}]\n` +
|
|
|
+ `\n已勾选节点名称: ${selectedLabels}`;
|
|
|
+ console.log('%c[KnowledgeGraph] node-check 回传数据: ', 'background:#3BA272;color:#fff;padding:4px 8px;border-radius:4px;', { data, checkedInfo });
|
|
|
+ this.appendLog('success', '复选框勾选', logMsg);
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 【事件回传3】AI讲解按钮点击
|
|
|
+ * @param {Object} payload { nodeData, nodeInstance, nodeKey, nodeLabel }
|
|
|
+ */
|
|
|
+ handleTestAiExplain(payload) {
|
|
|
+ const { nodeData, nodeKey, nodeLabel } = payload;
|
|
|
+ const logMsg =
|
|
|
+ `节点Key: ${nodeKey}\n` +
|
|
|
+ `节点名称: ${nodeLabel}\n` +
|
|
|
+ `节点层级: ${payload.nodeInstance.level}\n` +
|
|
|
+ `计数count: ${nodeData.count ?? '无'}\n` +
|
|
|
+ `\n完整节点数据: ${JSON.stringify(nodeData, null, 2)}`;
|
|
|
+ console.log('%c[KnowledgeGraph] ai-explain 回传数据: ', 'background:#FAC858;color:#333;padding:4px 8px;border-radius:4px;', payload);
|
|
|
+ this.appendLog('warn', 'AI讲解', logMsg);
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 按钮测试:获取所有勾选的节点(调用组件暴露方法)
|
|
|
+ */
|
|
|
+ testGetChecked() {
|
|
|
+ const nodes = this.$refs.treeTestRef.getCheckedNodes(false);
|
|
|
+ const keys = this.$refs.treeTestRef.getCheckedKeys(false);
|
|
|
+ const logMsg =
|
|
|
+ `勾选节点对象数: ${nodes.length}\n` +
|
|
|
+ `勾选节点key数组: ${JSON.stringify(keys)}\n` +
|
|
|
+ `勾选节点名称: ${nodes.map(n => n.label).join('、') || '(无)'}`;
|
|
|
+ console.log('%c[KnowledgeGraph] getCheckedNodes 结果: ', 'background:#67C23A;color:#fff;padding:4px 8px;border-radius:4px;', nodes, keys);
|
|
|
+ this.appendLog('success', '获取选中节点', logMsg);
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 按钮测试:清空所有勾选节点
|
|
|
+ */
|
|
|
+ testClearChecked() {
|
|
|
+ this.$refs.treeTestRef.clearChecked();
|
|
|
+ console.log('%c[KnowledgeGraph] clearChecked 已清空', 'background:#E6A23C;color:#fff;padding:4px 8px;border-radius:4px;');
|
|
|
+ this.appendLog('info', '清空选中', '已通过 clearChecked() 方法清空所有复选框勾选状态');
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
@@ -362,24 +615,199 @@ export default {
|
|
|
.knowledge_graph {
|
|
|
overflow-y: auto;
|
|
|
overflow-x: hidden;
|
|
|
-}
|
|
|
|
|
|
-/* 自定义滚动条样式 */
|
|
|
-.knowledge_graph::-webkit-scrollbar {
|
|
|
- width: 6px;
|
|
|
-}
|
|
|
+ .graph_top {
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 10px;
|
|
|
+ padding: 20px;
|
|
|
+ }
|
|
|
|
|
|
-.knowledge_graph::-webkit-scrollbar-track {
|
|
|
- background: #f1f1f1;
|
|
|
- border-radius: 3px;
|
|
|
-}
|
|
|
+ /* 顶部信息模块 */
|
|
|
+ .knowledge_header {
|
|
|
+ margin-bottom: 10px;
|
|
|
+
|
|
|
+ .header_top {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 20px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+
|
|
|
+ .header_title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ .el-checkbox-group{
|
|
|
+ .el-checkbox{
|
|
|
+ margin-right:20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .header_stats {
|
|
|
+ font-size: 14px;
|
|
|
+ .stats_text {
|
|
|
+ color: #999999;
|
|
|
+ }
|
|
|
+
|
|
|
+ .stats_num {
|
|
|
+ font-weight: 600;
|
|
|
+ color: #2E64FA;
|
|
|
+ margin: 0 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .stats_weak {
|
|
|
+ color: #F56C6C;
|
|
|
+ }
|
|
|
+
|
|
|
+ .stats_good {
|
|
|
+ color: #FAC858;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* ==================== CommonTree 测试区域样式 ==================== */
|
|
|
+ .tree_test_section {
|
|
|
+ margin-top: 15px;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 10px;
|
|
|
+ padding: 15px 20px 20px;
|
|
|
+
|
|
|
+ /* 测试区标题栏 */
|
|
|
+ .tree_test_title {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding-bottom: 12px;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ border-bottom: 1px solid #eceef3;
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
|
|
|
-.knowledge_graph::-webkit-scrollbar-thumb {
|
|
|
- background: #c1c1c1;
|
|
|
- border-radius: 3px;
|
|
|
+ /* 测试区主体:左树右日志 */
|
|
|
+ .tree_test_body {
|
|
|
+ display: flex;
|
|
|
+ gap: 16px;
|
|
|
+ }
|
|
|
|
|
|
- &:hover {
|
|
|
- background: #a8a8a8;
|
|
|
+ /* 左侧树形面板(必须白色,因为树形末尾竖线用白色块截断) */
|
|
|
+ .tree_panel {
|
|
|
+ flex: 1;
|
|
|
+ height: 420px;
|
|
|
+ border: 1px solid #eceef3;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 8px 0 8px 4px;
|
|
|
+ overflow-y: auto;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 右侧事件日志面板 */
|
|
|
+ .tree_log_panel {
|
|
|
+ width: 420px;
|
|
|
+ height: 420px;
|
|
|
+ border: 1px solid #eceef3;
|
|
|
+ border-radius: 8px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .log_title {
|
|
|
+ padding: 10px 14px;
|
|
|
+ font-size: 13px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #666;
|
|
|
+ background: #f5f7fa;
|
|
|
+ border-bottom: 1px solid #eceef3;
|
|
|
+ }
|
|
|
+
|
|
|
+ .log_list {
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: auto;
|
|
|
+ padding: 10px 12px;
|
|
|
+
|
|
|
+ /* 单条日志 */
|
|
|
+ .log_item {
|
|
|
+ border: 1px solid #eef0f3;
|
|
|
+ border-radius: 6px;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .log_tag, .log_time {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 2px 8px;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .log_tag {
|
|
|
+ font-weight: 600;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .log_time {
|
|
|
+ color: #909399;
|
|
|
+ background: #f5f7fa;
|
|
|
+ border-bottom: 1px solid #eef0f3;
|
|
|
+ }
|
|
|
+
|
|
|
+ .log_content {
|
|
|
+ margin: 0;
|
|
|
+ padding: 8px 10px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #444;
|
|
|
+ line-height: 1.6;
|
|
|
+ white-space: pre-wrap;
|
|
|
+ word-break: break-all;
|
|
|
+ font-family: Consolas, Monaco, monospace;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 按事件类型设置标签颜色 */
|
|
|
+ &.log-info {
|
|
|
+ .log_tag { background: #2E64FA; }
|
|
|
+ border-left: 3px solid #2E64FA;
|
|
|
+ }
|
|
|
+ &.log-success {
|
|
|
+ .log_tag { background: #3BA272; }
|
|
|
+ border-left: 3px solid #3BA272;
|
|
|
+ }
|
|
|
+ &.log-warn {
|
|
|
+ .log_tag { background: #E6A23C; }
|
|
|
+ border-left: 3px solid #E6A23C;
|
|
|
+ }
|
|
|
+ &.log-error {
|
|
|
+ .log_tag { background: #F56C6C; }
|
|
|
+ border-left: 3px solid #F56C6C;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .log_empty {
|
|
|
+ padding: 30px 12px;
|
|
|
+ text-align: center;
|
|
|
+ color: #909399;
|
|
|
+ font-size: 13px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 自定义滚动条样式 */
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ width: 6px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &::-webkit-scrollbar-track {
|
|
|
+ background: #f1f1f1;
|
|
|
+ border-radius: 3px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
+ background: #c1c1c1;
|
|
|
+ border-radius: 3px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: #a8a8a8;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
</style>
|