|
@@ -0,0 +1,613 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="collapsible-toolbar" :class="{ collapsed: isCollapsed }">
|
|
|
|
|
+ <div class="toolbar-content" v-show="!isCollapsed">
|
|
|
|
|
+ <div class="sidebar-content">
|
|
|
|
|
+ <div class="sidebar-item" :class="{ active: activeSubmenu === 'interactive' }" @click="toggleSubmenu('interactive')">
|
|
|
|
|
+ <svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <circle cx="12" cy="12" r="3"/>
|
|
|
|
|
+ <path d="M12 1v6m0 6v6M5.64 5.64l4.24 4.24m4. 4.24l4.24 4.24M1 12h6m6 0h6M5.64 18.36l4.24-4.24m4.24-4.24l4kt-4.24"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ <span class="item-label">互动工具</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="sidebar-item" @click="handleToolClick('h5page')">
|
|
|
|
|
+ <svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <circle cx="12" cy="12" r="10"/>
|
|
|
|
|
+ <path d="M2 12h20"/>
|
|
|
|
|
+ <path d="M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10 15.3 15.3 0 01-4-10 15.3 15.3 0 014-10z"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ <span class="item-label">H5页面</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="sidebar-item" @click="handleToolClick('aiapp')">
|
|
|
|
|
+ <svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <rect x="3" y="3" width="7" height="7"/>
|
|
|
|
|
+ <rect x="14" y="3" width="7" height="7"/>
|
|
|
|
|
+ <rect x="14" y="14" width="7" height="7"/>
|
|
|
|
|
+ <rect x="3" y="14" width="7" height="7"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ <span class="item-label">AI应用</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="sidebar-item" @click="handleToolClick('video')">
|
|
|
|
|
+ <svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <rect x="3" y="4" width="18" height="16" rx="2" ry="2"/>
|
|
|
|
|
+ <polygon points="10 9 16 12 10 15 10 9"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ <span class="item-label">视频</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="sidebar-item" @click="handleToolClick('creative')">
|
|
|
|
|
+ <svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <circle cx="12" cy="12" r="10"/>
|
|
|
|
|
+ <line x1="12" y1="8" x2="12" y2="16"/>
|
|
|
|
|
+ <line x1="8" y1="12" x2="16" y2="12"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ <span class="item-label">创作空间</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="sidebar-item" :class="{ active: activeSubmenu === 'contentlist' }" @click="toggleSubmenu('contentlist')">
|
|
|
|
|
+ <svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/>
|
|
|
|
|
+ <path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ <span class="item-label">内容列表</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="submenu" :class="{ visible: activeSubmenu === 'interactive' }">
|
|
|
|
|
+ <div class="submenu-item" @click="handleToolClick('choice')">
|
|
|
|
|
+ <svg class="submenu-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <circle cx="12" cy="12" r="10"/>
|
|
|
|
|
+ <path d="M12 16v-4m0-4h.01"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ <span class="submenu-label">选择题</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="submenu-item" @click="handleToolClick('qa')">
|
|
|
|
|
+ <svg class="submenu-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ <span class="submenu-label">问答</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="content-list-submenu" :class="{ visible: activeSubmenu === 'contentlist' }">
|
|
|
|
|
+ <div v-if="contentList.length === 0" class="empty-state">
|
|
|
|
|
+ <div class="empty-icon">📚</div>
|
|
|
|
|
+ <div class="empty-title">暂无学习内容</div>
|
|
|
|
|
+ <div class="empty-title">请先上传或创建学习内容</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-else class="content-list">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="(item, index) in contentList"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ class="content-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="content-main" @click="insertContent(item)">
|
|
|
|
|
+ <svg class="content-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/>
|
|
|
|
|
+ <path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ <span class="content-label">{{ item.title }}</span>
|
|
|
|
|
+ <span class="type-tag" :class="getTypeClass(item.tool)">{{ getTypeLabel(item.tool) }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="content-actions">
|
|
|
|
|
+ <template v-if="item.tool === 74 || item.tool === 75">
|
|
|
|
|
+ <div class="action-btn" @click.stop="previewVideo(item)" title="预览">
|
|
|
|
|
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <polygon points="5 3 19 12 5 21 5 3"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-if="item.tool !== 74 && item.tool !== 75 && item.tool !== 76">
|
|
|
|
|
+ <div class="action-btn" @click.stop="editContent(item)" title="编辑">
|
|
|
|
|
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
|
|
|
|
|
+ <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-if="item.tool !== 76">
|
|
|
|
|
+ <div class="action-btn" @click.stop="copyContent(item)" title="复制">
|
|
|
|
|
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
|
|
|
|
|
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <div class="action-btn delete" @click.stop="deleteContent(item)" title="删除">
|
|
|
|
|
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <polyline points="3 6 5 6 21 6"/>
|
|
|
|
|
+ <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
|
+import { ref } from 'vue'
|
|
|
|
|
+import useCreateElement from '@/hooks/useCreateElement'
|
|
|
|
|
+
|
|
|
|
|
+interface ContentItem {
|
|
|
|
|
+ tool?: number
|
|
|
|
|
+ title?: string
|
|
|
|
|
+ url?: string
|
|
|
|
|
+ id?: string
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const props = withDefaults(defineProps<{
|
|
|
|
|
+ defaultCollapsed?: boolean
|
|
|
|
|
+}>(), {
|
|
|
|
|
+ defaultCollapsed: false
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const emit = defineEmits<{
|
|
|
|
|
+ (e: 'toggle', collapsed: boolean): void
|
|
|
|
|
+}>()
|
|
|
|
|
+
|
|
|
|
|
+const isCollapsed = ref(props.defaultCollapsed)
|
|
|
|
|
+const activeSubmenu = ref<string | null>(null)
|
|
|
|
|
+const contentList = ref<ContentItem[]>([])
|
|
|
|
|
+
|
|
|
|
|
+const { createFrameElement } = useCreateElement()
|
|
|
|
|
+
|
|
|
|
|
+const toggleCollapse = () => {
|
|
|
|
|
+ isCollapsed.value = !isCollapsed.value
|
|
|
|
|
+ emit('toggle', isCollapsed.value)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const toggleSubmenu = (menu: string) => {
|
|
|
|
|
+ if (activeSubmenu.value === menu) {
|
|
|
|
|
+ activeSubmenu.value = null
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ activeSubmenu.value = menu
|
|
|
|
|
+ if (menu === 'contentlist') {
|
|
|
|
|
+ loadContentList()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleToolClick = (tool: string) => {
|
|
|
|
|
+ interface ParentWindowWithToolList extends Window {
|
|
|
|
|
+ addTool?: (id: number) => void;
|
|
|
|
|
+ openVideoUploadDialog?: () => void;
|
|
|
|
|
+ openApplicationCenter?: () => void;
|
|
|
|
|
+ }
|
|
|
|
|
+ const parentWindow = window.parent as ParentWindowWithToolList
|
|
|
|
|
+ console.log('点击工具:', tool)
|
|
|
|
|
+ if (tool === 'h5page') {
|
|
|
|
|
+ parentWindow?.addTool?.(73)
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (tool === 'aiapp') {
|
|
|
|
|
+ parentWindow?.addTool?.(72)
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (tool === 'video') {
|
|
|
|
|
+ parentWindow?.openVideoUploadDialog?.()
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (tool === 'creative') {
|
|
|
|
|
+ parentWindow?.openApplicationCenter?.()
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (tool === 'choice') {
|
|
|
|
|
+ parentWindow?.addTool?.(45)
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (tool === 'qa') {
|
|
|
|
|
+ parentWindow?.addTool?.(15)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const loadContentList = () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ interface ParentWindowWithToolList extends Window {
|
|
|
|
|
+ pptToolList?: ContentItem[]
|
|
|
|
|
+ }
|
|
|
|
|
+ const parentWindow = window.parent as ParentWindowWithToolList
|
|
|
|
|
+ contentList.value = parentWindow?.pptToolList || []
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (error) {
|
|
|
|
|
+ console.error('加载内容列表失败:', error)
|
|
|
|
|
+ contentList.value = []
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+(window as any).loadContentList = loadContentList
|
|
|
|
|
+
|
|
|
|
|
+const insertContent = (item: ContentItem) => {
|
|
|
|
|
+ if (!item.tool || !item.url) return
|
|
|
|
|
+ createFrameElement(item.url, item.tool)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const previewVideo = (item: ContentItem) => {
|
|
|
|
|
+ interface ParentWindowWithToolList extends Window {
|
|
|
|
|
+ previewVideo?: (item: ContentItem) => void;
|
|
|
|
|
+ }
|
|
|
|
|
+ const parentWindow = window.parent as ParentWindowWithToolList
|
|
|
|
|
+ parentWindow?.previewVideo?.(item)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const editContent = (item: ContentItem) => {
|
|
|
|
|
+ interface ParentWindowWithToolList extends Window {
|
|
|
|
|
+ toolBtn?: (action: number, id: string) => void;
|
|
|
|
|
+ }
|
|
|
|
|
+ const parentWindow = window.parent as ParentWindowWithToolList
|
|
|
|
|
+ parentWindow?.toolBtn?.(0, item.id || '')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const copyContent = (item: ContentItem) => {
|
|
|
|
|
+ interface ParentWindowWithToolList extends Window {
|
|
|
|
|
+ toolBtn?: (action: number, id: string) => void;
|
|
|
|
|
+ }
|
|
|
|
|
+ const parentWindow = window.parent as ParentWindowWithToolList
|
|
|
|
|
+ parentWindow?.toolBtn?.(1, item.id || '')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const deleteContent = (item: ContentItem) => {
|
|
|
|
|
+ interface ParentWindowWithToolList extends Window {
|
|
|
|
|
+ toolBtn?: (action: number, id: string) => void;
|
|
|
|
|
+ }
|
|
|
|
|
+ const parentWindow = window.parent as ParentWindowWithToolList
|
|
|
|
|
+ parentWindow?.toolBtn?.(2, item.id || '')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getTypeLabel = (type?: number) => {
|
|
|
|
|
+ const typeMap: Record<number, string> = {
|
|
|
|
|
+ 45: '选择题',
|
|
|
|
|
+ 15: '问答题',
|
|
|
|
|
+ 72: 'AI应用',
|
|
|
|
|
+ 73: 'H5页面',
|
|
|
|
|
+ 74: '视频',
|
|
|
|
|
+ 75: 'B站视频',
|
|
|
|
|
+ 76: '创作空间'
|
|
|
|
|
+ }
|
|
|
|
|
+ return typeMap[type || 0] || '未知'
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getTypeClass = (type?: number) => {
|
|
|
|
|
+ const classMap: Record<number, string> = {
|
|
|
|
|
+ 45: 'type-choice',
|
|
|
|
|
+ 15: 'type-question',
|
|
|
|
|
+ 72: 'type-ai',
|
|
|
|
|
+ 73: 'type-h5',
|
|
|
|
|
+ 74: 'type-video',
|
|
|
|
|
+ 75: 'type-bilibili',
|
|
|
|
|
+ 76: 'type-app-center'
|
|
|
|
|
+ }
|
|
|
|
|
+ return classMap[type || 0] || 'type-default'
|
|
|
|
|
+}
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+.collapsible-toolbar {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-right: 1px solid #e5e7eb;
|
|
|
|
|
+ transition: width 0.3s ease;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.toolbar-content {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ padding: 16px 8px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.sidebar-content {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 6px;
|
|
|
|
|
+ width: 84px;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.sidebar-item {
|
|
|
|
|
+ width: 84px;
|
|
|
|
|
+ padding: 12px 8px;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ gap: 6px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ transition: all 0.2s;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ background: #f3f4f6;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &:active {
|
|
|
|
|
+ background: #e5e7eb;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.active {
|
|
|
|
|
+ background: #eef3ff;
|
|
|
|
|
+ box-shadow: 0 2px 8px rgba(40, 92, 245, 0.15);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.active::after {
|
|
|
|
|
+ content: '';
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ left: -8px;
|
|
|
|
|
+ top: 50%;
|
|
|
|
|
+ transform: translateY(-50%);
|
|
|
|
|
+ width: 4px;
|
|
|
|
|
+ height: 32px;
|
|
|
|
|
+ background: #285cf5;
|
|
|
|
|
+ border-radius: 0 2px 2px 0;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-icon {
|
|
|
|
|
+ width: 22px;
|
|
|
|
|
+ height: 22px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ color: #6b7280;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.sidebar-item:hover .item-icon,
|
|
|
|
|
+.sidebar-item.active .item-icon {
|
|
|
|
|
+ color: #285cf5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-label {
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ color: #6b7280;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ line-height: 1.2;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.sidebar-item:hover .item-label,
|
|
|
|
|
+.sidebar-item.active .item-label {
|
|
|
|
|
+ color: #285cf5;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.submenu {
|
|
|
|
|
+ width: 0;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ z-index: 100;
|
|
|
|
|
+
|
|
|
|
|
+ &.visible {
|
|
|
|
|
+ width: 160px;
|
|
|
|
|
+ min-width: 160px;
|
|
|
|
|
+ padding: 8px 0;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.submenu-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+ padding: 10px 16px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ transition: all 0.2s ease;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #6b7280;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ margin: 4px 8px;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ background-color: #f3f4f6;
|
|
|
|
|
+ color: #285cf5;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &:active {
|
|
|
|
|
+ background-color: #e5e7eb;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.submenu-icon {
|
|
|
|
|
+ width: 18px;
|
|
|
|
|
+ height: 18px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ color: #9ca3af;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.submenu-item:hover .submenu-icon {
|
|
|
|
|
+ color: #285cf5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.submenu-label {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #6b7280;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.submenu-item:hover .submenu-label {
|
|
|
|
|
+ color: #285cf5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.content-list-submenu {
|
|
|
|
|
+ width: 0;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ z-index: 100;
|
|
|
|
|
+
|
|
|
|
|
+ &.visible {
|
|
|
|
|
+ width: 380px;
|
|
|
|
|
+ min-width: 380px;
|
|
|
|
|
+ padding: 8px 0;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.empty-state {
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ padding: 20px 10px;
|
|
|
|
|
+ color: #666;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.empty-icon {
|
|
|
|
|
+ font-size: 32px;
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.empty-title {
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.content-list {
|
|
|
|
|
+ max-height: 400px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ padding: 4px 0;
|
|
|
|
|
+
|
|
|
|
|
+ &::-webkit-scrollbar {
|
|
|
|
|
+ width: 4px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &::-webkit-scrollbar-track {
|
|
|
|
|
+ background: #f1f1f1;
|
|
|
|
|
+ border-radius: 2px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
|
|
+ background: #c1c1c1;
|
|
|
|
|
+ border-radius: 2px;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ background: #a8a8a8;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.content-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ padding: 8px 12px;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ margin: 2px 8px;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ transition: all 0.2s ease;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ background-color: #f8f9fa;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.content-main {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ padding: 4px;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ transition: all 0.2s ease;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ background-color: #f3f4f6;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.content-icon {
|
|
|
|
|
+ width: 16px;
|
|
|
|
|
+ height: 16px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ color: #9ca3af;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.content-main:hover .content-icon {
|
|
|
|
|
+ color: #285cf5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.content-label {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #6b7280;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.content-main:hover .content-label {
|
|
|
|
|
+ color: #285cf5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.content-actions {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.action-btn {
|
|
|
|
|
+ width: 28px;
|
|
|
|
|
+ height: 28px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ transition: all 0.2s ease;
|
|
|
|
|
+ color: #9ca3af;
|
|
|
|
|
+
|
|
|
|
|
+ svg {
|
|
|
|
|
+ width: 14px;
|
|
|
|
|
+ height: 14px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ background-color: #f3f4f6;
|
|
|
|
|
+ color: #285cf5;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.delete {
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ background-color: #fee2e2;
|
|
|
|
|
+ color: #ef4444;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.type-tag {
|
|
|
|
|
+ padding: 2px 6px;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ font-size: 10px;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+
|
|
|
|
|
+ &.type-choice {
|
|
|
|
|
+ background-color: #4caf50;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.type-question {
|
|
|
|
|
+ background-color: #ff9800;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.type-ai {
|
|
|
|
|
+ background-color: #2196f3;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.type-h5 {
|
|
|
|
|
+ background-color: #9c27b0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.type-video {
|
|
|
|
|
+ background-color: #f44336;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.type-bilibili {
|
|
|
|
|
+ background-color: #fb7299;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.type-default {
|
|
|
|
|
+ background-color: #757575;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.type-app-center {
|
|
|
|
|
+ background-color: #673ab7;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|