|
@@ -12,12 +12,16 @@
|
|
<div class="thumbnails">
|
|
<div class="thumbnails">
|
|
<div class="viewer-header slide-header">
|
|
<div class="viewer-header slide-header">
|
|
<h3 v-show="!slidePanelCollapsed">课程大纲</h3>
|
|
<h3 v-show="!slidePanelCollapsed">课程大纲</h3>
|
|
- <button class="collapse-btn" @click="slidePanelCollapsed = !slidePanelCollapsed" :title="slidePanelCollapsed ? '展开' : '收起'">
|
|
|
|
- <span v-if="slidePanelCollapsed">›</span>
|
|
|
|
- <span v-else>‹</span>
|
|
|
|
|
|
+ <button class="collapse-btn" @click="slidePanelCollapsed = !slidePanelCollapsed" :title="slidePanelCollapsed ? '展开' : '收起'" style="right: 8px;">
|
|
|
|
+ <span v-if="slidePanelCollapsed">
|
|
|
|
+ <img src="@/assets/img/arrow.svg">
|
|
|
|
+ </span>
|
|
|
|
+ <span v-else>
|
|
|
|
+ <img src="@/assets/img/arrow.svg" style="transform: rotate(180deg);">
|
|
|
|
+ </span>
|
|
</button>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
- <div v-show="!slidePanelCollapsed">
|
|
|
|
|
|
+ <div v-show="!slidePanelCollapsed" class="panel-content">
|
|
<div class="thumbnail-list">
|
|
<div class="thumbnail-list">
|
|
<div v-for="(slide, index) in slides" :key="slide.id" class="thumbnail-item"
|
|
<div v-for="(slide, index) in slides" :key="slide.id" class="thumbnail-item"
|
|
:class="{ 'active': slideIndex === index }" @click="goToSlide(index)">
|
|
:class="{ 'active': slideIndex === index }" @click="goToSlide(index)">
|
|
@@ -68,7 +72,7 @@
|
|
:manualExitFullscreen="() => { }" /> -->
|
|
:manualExitFullscreen="() => { }" /> -->
|
|
|
|
|
|
<!-- 不全屏时:使用编辑模式的显示比例和居中逻辑 -->
|
|
<!-- 不全屏时:使用编辑模式的显示比例和居中逻辑 -->
|
|
- <div class="slide-list-wrap" :style="{
|
|
|
|
|
|
+ <div class="slide-list-wrap" :class="{'slide-list-wrap-n': !isFullscreen}" :style="{
|
|
width: isFullscreen ? '100%' : (slideWidth * canvasScale) + 'px',
|
|
width: isFullscreen ? '100%' : (slideWidth * canvasScale) + 'px',
|
|
height: isFullscreen ? '100%' : (slideHeight * canvasScale) + 'px',
|
|
height: isFullscreen ? '100%' : (slideHeight * canvasScale) + 'px',
|
|
left: isFullscreen ? '0' : `${(containerWidth - slideWidth * canvasScale) / 2}px`,
|
|
left: isFullscreen ? '0' : `${(containerWidth - slideWidth * canvasScale) / 2}px`,
|
|
@@ -82,8 +86,10 @@
|
|
:manualExitFullscreen="() => { }" :is-visible="slideIndex === index" />
|
|
:manualExitFullscreen="() => { }" :is-visible="slideIndex === index" />
|
|
</div>
|
|
</div>
|
|
|
|
|
|
- <ScreenSlideList :slideWidth="slideWidth * canvasScale" :slideHeight="slideHeight * canvasScale"
|
|
|
|
|
|
+ <ScreenSlideList :style="{ width: isFullscreen ? '100%' : slideWidth2 * canvasScale + 'px', height: isFullscreen ? '100%' : slideHeight2 * canvasScale + 'px', margin: '0 auto' }" :slideWidth="isFullscreen ? slideWidth * canvasScale : slideWidth2 * canvasScale" :slideHeight="isFullscreen ? slideHeight * canvasScale : slideHeight2 * canvasScale"
|
|
:animationIndex="0" :turnSlideToId="() => { }" :manualExitFullscreen="() => { }" :slideIndex="slideIndex"/>
|
|
:animationIndex="0" :turnSlideToId="() => { }" :manualExitFullscreen="() => { }" :slideIndex="slideIndex"/>
|
|
|
|
+
|
|
|
|
+ <div class="slide-bottom" v-if="!isFullscreen"></div>
|
|
</div>
|
|
</div>
|
|
<!-- 全屏时的左右下角工具按钮 -->
|
|
<!-- 全屏时的左右下角工具按钮 -->
|
|
<div v-if="isFullscreen && (!isFollowModeActive || props.type == '1')" class="tools-left">
|
|
<div v-if="isFullscreen && (!isFollowModeActive || props.type == '1')" class="tools-left">
|
|
@@ -135,18 +141,48 @@
|
|
<div class="layout-content-right" v-show="type == '1'" :class="{ collapsed: workPanelCollapsed }">
|
|
<div class="layout-content-right" v-show="type == '1'" :class="{ collapsed: workPanelCollapsed }">
|
|
<div class="thumbnails">
|
|
<div class="thumbnails">
|
|
<div class="viewer-header right-panel-header">
|
|
<div class="viewer-header right-panel-header">
|
|
- <h3 v-show="!workPanelCollapsed">{{
|
|
|
|
- rightPanelMode === 'homework' ? '作业区' :
|
|
|
|
- rightPanelMode === 'dialogue' ? '对话区' : rightPanelMode === 'choice' ? '统计' : ''
|
|
|
|
- }}</h3>
|
|
|
|
- <button class="collapse-btn" @click="workPanelCollapsed = !workPanelCollapsed" :title="workPanelCollapsed ? '展开' : '收起'" v-if="rightPanelMode != ''">
|
|
|
|
- <span v-if="workPanelCollapsed">›</span>
|
|
|
|
- <span v-else>‹</span>
|
|
|
|
|
|
+ <button class="collapse-btn" @click="workPanelCollapsed = !workPanelCollapsed" :title="workPanelCollapsed ? '展开' : '收起'" v-if="rightPanelMode != ''" style="left: 8px;">
|
|
|
|
+ <span v-if="workPanelCollapsed">
|
|
|
|
+ <img src="@/assets/img/arrow.svg" style="transform: rotate(180deg);">
|
|
|
|
+ </span>
|
|
|
|
+ <span v-else>
|
|
|
|
+ <img src="@/assets/img/arrow.svg">
|
|
|
|
+ </span>
|
|
</button>
|
|
</button>
|
|
|
|
+ <!-- 标签页切换按钮 -->
|
|
|
|
+ <div v-show="!workPanelCollapsed" class="tab-switcher">
|
|
|
|
+ <button
|
|
|
|
+ class="tab-btn"
|
|
|
|
+ :class="{ active: rightPanelMode === 'homework' }"
|
|
|
|
+ @click="switchToHomework"
|
|
|
|
+ title="回答结果"
|
|
|
|
+ >
|
|
|
|
+ 回答结果
|
|
|
|
+ </button>
|
|
|
|
+ <button
|
|
|
|
+ class="tab-btn"
|
|
|
|
+ :class="{ active: rightPanelMode === 'dialogue' }"
|
|
|
|
+ @click="switchToDialogue"
|
|
|
|
+ title="对话区"
|
|
|
|
+ >
|
|
|
|
+ 对话区
|
|
|
|
+ </button>
|
|
|
|
+ <!-- <button
|
|
|
|
+ v-if="isChoiceQuestion"
|
|
|
|
+ class="tab-btn"
|
|
|
|
+ :class="{ active: rightPanelMode === 'choice' }"
|
|
|
|
+ @click="switchToChoice"
|
|
|
|
+ title="统计"
|
|
|
|
+ >
|
|
|
|
+ 统计
|
|
|
|
+ </button> -->
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- 侧边导航标签 - 无论展开还是收缩都显示在左侧 -->
|
|
<!-- 侧边导航标签 - 无论展开还是收缩都显示在左侧 -->
|
|
- <div class="side-nav-tabs">
|
|
|
|
|
|
+ <!-- <div class="side-nav-tabs">
|
|
<button
|
|
<button
|
|
v-if="currentSlideHasIframe"
|
|
v-if="currentSlideHasIframe"
|
|
class="side-nav-btn"
|
|
class="side-nav-btn"
|
|
@@ -165,19 +201,19 @@
|
|
>
|
|
>
|
|
<img :src="rightPanelMode === 'choice' ? choiceActiveIcon : choiceIcon" alt="统计">
|
|
<img :src="rightPanelMode === 'choice' ? choiceActiveIcon : choiceIcon" alt="统计">
|
|
</button>
|
|
</button>
|
|
- <!-- <button
|
|
|
|
|
|
+ <button
|
|
class="side-nav-btn"
|
|
class="side-nav-btn"
|
|
:class="{ active: rightPanelMode === 'dialogue' }"
|
|
:class="{ active: rightPanelMode === 'dialogue' }"
|
|
@click="switchToDialogue"
|
|
@click="switchToDialogue"
|
|
title="对话"
|
|
title="对话"
|
|
>
|
|
>
|
|
<img :src="rightPanelMode === 'dialogue' ? dialogueActiveIcon : dialogueIcon" alt="对话">
|
|
<img :src="rightPanelMode === 'dialogue' ? dialogueActiveIcon : dialogueIcon" alt="对话">
|
|
- </button> -->
|
|
|
|
- </div>
|
|
|
|
|
|
+ </button>
|
|
|
|
+ </div> -->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- <!-- 作业区内容 -->
|
|
|
|
|
|
+ <!-- 回答结果内容 -->
|
|
<div v-show="!workPanelCollapsed && rightPanelMode === 'homework'" class="panel-content">
|
|
<div v-show="!workPanelCollapsed && rightPanelMode === 'homework'" class="panel-content">
|
|
<div class="homework-title">已提交</div>
|
|
<div class="homework-title">已提交</div>
|
|
<div v-if="workLoading" class="homework-loading">正在加载作业...</div>
|
|
<div v-if="workLoading" class="homework-loading">正在加载作业...</div>
|
|
@@ -307,6 +343,8 @@ const isSubmitting = ref(false)
|
|
const showSlideList = ref(true)
|
|
const showSlideList = ref(true)
|
|
const slideWidth = ref(0)
|
|
const slideWidth = ref(0)
|
|
const slideHeight = ref(0)
|
|
const slideHeight = ref(0)
|
|
|
|
+const slideWidth2 = ref(0)
|
|
|
|
+const slideHeight2 = ref(0)
|
|
|
|
|
|
// 添加loading状态
|
|
// 添加loading状态
|
|
const isLoading = ref(false)
|
|
const isLoading = ref(false)
|
|
@@ -329,7 +367,7 @@ const visibleQA = ref(false)
|
|
const visibleChoice = ref(false)
|
|
const visibleChoice = ref(false)
|
|
const visibleAI = ref(false)
|
|
const visibleAI = ref(false)
|
|
|
|
|
|
-// 作业区收缩状态
|
|
|
|
|
|
+// 回答结果收缩状态
|
|
const workPanelCollapsed = ref(true)
|
|
const workPanelCollapsed = ref(true)
|
|
// 幻灯片导航收缩状态
|
|
// 幻灯片导航收缩状态
|
|
const slidePanelCollapsed = ref(true)
|
|
const slidePanelCollapsed = ref(true)
|
|
@@ -362,7 +400,7 @@ const providerSocket = ref<WebsocketProvider | null>(null)
|
|
const mId = ref<string | null>(null)
|
|
const mId = ref<string | null>(null)
|
|
|
|
|
|
|
|
|
|
-// 切换到作业区
|
|
|
|
|
|
+// 切换到回答结果
|
|
const switchToHomework = () => {
|
|
const switchToHomework = () => {
|
|
rightPanelMode.value = 'homework'
|
|
rightPanelMode.value = 'homework'
|
|
if (workPanelCollapsed.value) {
|
|
if (workPanelCollapsed.value) {
|
|
@@ -388,7 +426,7 @@ const switchToChoice = () => {
|
|
|
|
|
|
// 自动切换到可用的面板
|
|
// 自动切换到可用的面板
|
|
const autoSwitchToAvailablePanel = () => {
|
|
const autoSwitchToAvailablePanel = () => {
|
|
- // 如果当前在作业区但没有iframe,自动切换到其他可用面板
|
|
|
|
|
|
+ // 如果当前在回答结果但没有iframe,自动切换到其他可用面板
|
|
if (rightPanelMode.value === 'homework' && !currentSlideHasIframe.value) {
|
|
if (rightPanelMode.value === 'homework' && !currentSlideHasIframe.value) {
|
|
if (isChoiceQuestion.value) {
|
|
if (isChoiceQuestion.value) {
|
|
rightPanelMode.value = 'choice'
|
|
rightPanelMode.value = 'choice'
|
|
@@ -455,6 +493,9 @@ const calculateSlideSize = () => {
|
|
const slideWrapRef = isFullscreen.value ? document.body : viewerCanvasRef.value
|
|
const slideWrapRef = isFullscreen.value ? document.body : viewerCanvasRef.value
|
|
const winWidth = slideWrapRef?.clientWidth || 0
|
|
const winWidth = slideWrapRef?.clientWidth || 0
|
|
const winHeight = slideWrapRef?.clientHeight || 0
|
|
const winHeight = slideWrapRef?.clientHeight || 0
|
|
|
|
+ const winWidth2 = slideWrapRef && typeof slideWrapRef.clientWidth === 'number' ? slideWrapRef.clientWidth - 40 : 0
|
|
|
|
+ const winHeight2 = slideWrapRef && typeof slideWrapRef.clientHeight === 'number' ? slideWrapRef.clientHeight - 85 : 0
|
|
|
|
+
|
|
|
|
|
|
// 根据视口比例计算最佳尺寸
|
|
// 根据视口比例计算最佳尺寸
|
|
if (winHeight / winWidth === viewportRatio.value) {
|
|
if (winHeight / winWidth === viewportRatio.value) {
|
|
@@ -470,7 +511,38 @@ const calculateSlideSize = () => {
|
|
slideHeight.value = winHeight
|
|
slideHeight.value = winHeight
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // 这里的逻辑存在一些问题和可以优化的地方:
|
|
|
|
+ // 1. winWidth2 或 winHeight2 可能为0,导致后续计算为NaN。
|
|
|
|
+ // 2. slideHeight.value - slideHeight2.value < 85 这个判断,slideHeight2.value 可能还未被合理赋值,导致判断不准确。
|
|
|
|
+ // 3. 反复赋值 slideHeight2/slideWidth2,可能导致宽高比被破坏。
|
|
|
|
+ // 4. 代码重复,可合并优化。
|
|
|
|
+
|
|
|
|
+ // 先按比例计算
|
|
|
|
+ let tempWidth = 0
|
|
|
|
+ let tempHeight = 0
|
|
|
|
+ if (winHeight2 / winWidth2 === viewportRatio.value) {
|
|
|
|
+ tempWidth = winWidth2
|
|
|
|
+ tempHeight = winHeight2
|
|
|
|
+ }
|
|
|
|
+ else if (winHeight2 / winWidth2 > viewportRatio.value) {
|
|
|
|
+ tempWidth = winWidth2
|
|
|
|
+ tempHeight = winWidth2 * viewportRatio.value
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ tempHeight = winHeight2
|
|
|
|
+ tempWidth = winHeight2 / viewportRatio.value
|
|
|
|
+ }
|
|
|
|
+ // 检查底部空间
|
|
|
|
+ if (slideHeight.value - tempHeight < 85) {
|
|
|
|
+ tempHeight = Math.max(slideHeight.value - 85, 0)
|
|
|
|
+ tempWidth = tempHeight > 0 ? tempHeight / viewportRatio.value : 0
|
|
|
|
+ }
|
|
|
|
+ slideWidth2.value = tempWidth
|
|
|
|
+ slideHeight2.value = tempHeight
|
|
|
|
+
|
|
|
|
+
|
|
console.log('calculateSlideSize', slideWidth.value, slideHeight.value, viewportRatio.value, canvasScale.value)
|
|
console.log('calculateSlideSize', slideWidth.value, slideHeight.value, viewportRatio.value, canvasScale.value)
|
|
|
|
+ console.log('calculateSlideSize', slideWidth2.value, slideHeight2.value, viewportRatio.value, canvasScale.value)
|
|
}
|
|
}
|
|
|
|
|
|
// 使用编辑模式的缩放逻辑
|
|
// 使用编辑模式的缩放逻辑
|
|
@@ -1455,7 +1527,7 @@ const getHomeworkButtonRight = () => {
|
|
return 30 // 全屏时按钮在右侧30px
|
|
return 30 // 全屏时按钮在右侧30px
|
|
}
|
|
}
|
|
if (props.type === '1') {
|
|
if (props.type === '1') {
|
|
- // 展开作业区:按钮更靠左;收起时:按钮更靠右侧
|
|
|
|
|
|
+ // 展开回答结果:按钮更靠左;收起时:按钮更靠右侧
|
|
return workPanelCollapsed.value ? 60 : 430
|
|
return workPanelCollapsed.value ? 60 : 430
|
|
}
|
|
}
|
|
return 30 // type=2时按钮在右侧30px
|
|
return 30 // type=2时按钮在右侧30px
|
|
@@ -1467,7 +1539,7 @@ const getRefreshButtonRight = () => {
|
|
return 160 // 全屏时按钮在右侧150px
|
|
return 160 // 全屏时按钮在右侧150px
|
|
}
|
|
}
|
|
if (props.type === '1') {
|
|
if (props.type === '1') {
|
|
- // 展开作业区:按钮更靠左;收起时:按钮更靠右侧
|
|
|
|
|
|
+ // 展开回答结果:按钮更靠左;收起时:按钮更靠右侧
|
|
return workPanelCollapsed.value ? 190 : 560
|
|
return workPanelCollapsed.value ? 190 : 560
|
|
}
|
|
}
|
|
return 160 // type=2时按钮在右侧150px
|
|
return 160 // type=2时按钮在右侧150px
|
|
@@ -1966,7 +2038,7 @@ onUnmounted(() => {
|
|
height: 100vh;
|
|
height: 100vh;
|
|
display: flex;
|
|
display: flex;
|
|
background-color: #f4f4f4;
|
|
background-color: #f4f4f4;
|
|
- padding: 15px 10px;
|
|
|
|
|
|
+ padding: 15px 0;
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
|
|
|
|
// 全屏模式样式
|
|
// 全屏模式样式
|
|
@@ -1995,12 +2067,14 @@ onUnmounted(() => {
|
|
width: 200px;
|
|
width: 200px;
|
|
height: 100%;
|
|
height: 100%;
|
|
background-color: #fff;
|
|
background-color: #fff;
|
|
- border-right: 1px solid #e0e0e0;
|
|
|
|
- overflow-y: auto;
|
|
|
|
|
|
+ border-radius: 0 5px 0 5px;
|
|
|
|
+ overflow: hidden;
|
|
transition: width .2s ease;
|
|
transition: width .2s ease;
|
|
|
|
+ margin-left: 10px;
|
|
}
|
|
}
|
|
.layout-content-left.collapsed {
|
|
.layout-content-left.collapsed {
|
|
width: 48px;
|
|
width: 48px;
|
|
|
|
+ margin-left: 0;
|
|
}
|
|
}
|
|
.slide-header {
|
|
.slide-header {
|
|
display: flex;
|
|
display: flex;
|
|
@@ -2017,20 +2091,22 @@ onUnmounted(() => {
|
|
width: 400px;
|
|
width: 400px;
|
|
height: 100%;
|
|
height: 100%;
|
|
background-color: #fff;
|
|
background-color: #fff;
|
|
- border-left: 1px solid #e0e0e0;
|
|
|
|
- overflow-y: auto;
|
|
|
|
|
|
+ border-radius: 5px 0 5px 0;
|
|
|
|
+ overflow: hidden;
|
|
transition: width .2s ease;
|
|
transition: width .2s ease;
|
|
position: relative;
|
|
position: relative;
|
|
|
|
+ margin-right: 10px;
|
|
}
|
|
}
|
|
|
|
|
|
.panel-content {
|
|
.panel-content {
|
|
- margin-right: 52px;
|
|
|
|
- padding: 0 8px;
|
|
|
|
- height: calc(100% - 76px);
|
|
|
|
|
|
+ margin-right: 0;
|
|
|
|
+ // padding: 0 8px;
|
|
|
|
+ height: calc(100% - 65px);
|
|
overflow: auto;
|
|
overflow: auto;
|
|
}
|
|
}
|
|
.layout-content-right.collapsed {
|
|
.layout-content-right.collapsed {
|
|
width: 52px;
|
|
width: 52px;
|
|
|
|
+ margin-right: 0px;
|
|
}
|
|
}
|
|
.right-panel-header {
|
|
.right-panel-header {
|
|
display: flex;
|
|
display: flex;
|
|
@@ -2160,17 +2236,19 @@ onUnmounted(() => {
|
|
justify-content: center;
|
|
justify-content: center;
|
|
width: 32px;
|
|
width: 32px;
|
|
height: 32px;
|
|
height: 32px;
|
|
- border: 1px solid #d9d9d9;
|
|
|
|
|
|
+ // border: 1px solid #d9d9d9;
|
|
|
|
+ border: none;
|
|
border-radius: 8px;
|
|
border-radius: 8px;
|
|
background: #fff;
|
|
background: #fff;
|
|
color: #333;
|
|
color: #333;
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
line-height: 1;
|
|
line-height: 1;
|
|
font-weight: 700;
|
|
font-weight: 700;
|
|
|
|
+ position: absolute;
|
|
}
|
|
}
|
|
.collapse-btn:hover {
|
|
.collapse-btn:hover {
|
|
- border-color: #1890ff;
|
|
|
|
- color: #1890ff;
|
|
|
|
|
|
+ // border-color: #1890ff;
|
|
|
|
+ // color: #1890ff;
|
|
}
|
|
}
|
|
|
|
|
|
.homework-title {
|
|
.homework-title {
|
|
@@ -2249,6 +2327,8 @@ onUnmounted(() => {
|
|
font-size: 16px;
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
font-weight: 600;
|
|
color: #333;
|
|
color: #333;
|
|
|
|
+ text-align: center;
|
|
|
|
+ width: 100%;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2331,7 +2411,7 @@ onUnmounted(() => {
|
|
}
|
|
}
|
|
|
|
|
|
.viewer-header {
|
|
.viewer-header {
|
|
- height: 60px;
|
|
|
|
|
|
+ height: 45px;
|
|
background-color: #fff;
|
|
background-color: #fff;
|
|
border-bottom: 1px solid #e0e0e0;
|
|
border-bottom: 1px solid #e0e0e0;
|
|
display: flex;
|
|
display: flex;
|
|
@@ -2339,6 +2419,7 @@ onUnmounted(() => {
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
padding: 0 8px;
|
|
padding: 0 8px;
|
|
transition: transform 0.3s ease;
|
|
transition: transform 0.3s ease;
|
|
|
|
+ position: relative;
|
|
|
|
|
|
&.hidden {
|
|
&.hidden {
|
|
transform: translateY(-100%);
|
|
transform: translateY(-100%);
|
|
@@ -2411,7 +2492,7 @@ onUnmounted(() => {
|
|
.viewer-canvas {
|
|
.viewer-canvas {
|
|
flex: 1;
|
|
flex: 1;
|
|
position: relative;
|
|
position: relative;
|
|
- background-color: rgb(249, 249, 249);
|
|
|
|
|
|
+ background-color: rgb(244, 244, 244);
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
|
|
|
// 全屏时隐藏滚动条和边框
|
|
// 全屏时隐藏滚动条和边框
|
|
@@ -2434,6 +2515,20 @@ onUnmounted(() => {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+.slide-list-wrap-n{
|
|
|
|
+ border: 5px solid #595959;
|
|
|
|
+ background: #000;
|
|
|
|
+ padding: 15px 0 0 0;
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.slide-bottom{
|
|
|
|
+ height: 60px;
|
|
|
|
+ background: #000;
|
|
|
|
+ position: relative;
|
|
|
|
+ z-index: 10;
|
|
|
|
+}
|
|
|
|
+
|
|
.loading-indicator {
|
|
.loading-indicator {
|
|
position: absolute;
|
|
position: absolute;
|
|
top: 50%;
|
|
top: 50%;
|
|
@@ -2724,4 +2819,52 @@ onUnmounted(() => {
|
|
0% { transform: rotate(0deg); }
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+/* 标签页切换器样式 */
|
|
|
|
+.tab-switcher {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex: 1;
|
|
|
|
+ margin-right: 12px;
|
|
|
|
+ border-bottom: 1px solid #e0e0e0;
|
|
|
|
+ padding-bottom: 0;
|
|
|
|
+ height: 100%;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ gap: 20px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.tab-btn {
|
|
|
|
+ // flex: 1;
|
|
|
|
+ // padding: 12px 16px;
|
|
|
|
+ border: none;
|
|
|
|
+ background: transparent;
|
|
|
|
+ color: #666;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ transition: all 0.2s ease;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ font-weight: 500;
|
|
|
|
+ text-align: center;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ position: relative;
|
|
|
|
+ border-radius: 0;
|
|
|
|
+
|
|
|
|
+ &:hover {
|
|
|
|
+ color: #333;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ &.active {
|
|
|
|
+ color: #333;
|
|
|
|
+ font-weight: 600;
|
|
|
|
+
|
|
|
|
+ &::after {
|
|
|
|
+ content: '';
|
|
|
|
+ position: absolute;
|
|
|
|
+ bottom: -1px;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ height: 2px;
|
|
|
|
+ background: #333;
|
|
|
|
+ border-radius: 1px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
</style>
|
|
</style>
|