jvs-ppt-ui 0.0.17 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/jvs-ppt-ui.es.js +21902 -19957
- package/dist/lib/jvs-ppt-ui.umd.js +98 -98
- package/dist/lib/style.css +1 -1
- package/package.json +1 -1
- package/src/components/CanvasArea.vue +36 -4
- package/src/components/TemplateGallery.vue +412 -6
- package/src/components/material/CreateMaterialPanel.vue +2229 -0
- package/src/components/material/MyAssetsPanel.vue +1524 -0
- package/src/components/material/useDamAuth.ts +445 -0
package/package.json
CHANGED
|
@@ -58,6 +58,7 @@ import {
|
|
|
58
58
|
} from '../utils/line'
|
|
59
59
|
import { type SlideTextType, TEXT_TYPE_CONFIGS } from '../utils/textTypes'
|
|
60
60
|
import { defaultStyleRecipe } from '../composables/presetThemes'
|
|
61
|
+
import { useDamAuth } from './material/useDamAuth'
|
|
61
62
|
|
|
62
63
|
const {
|
|
63
64
|
activeSlide, selectedElementId, selectedElementIds, deleteElement, combineElements, uncombineElement, updateGroupBounds, zoomRatio, fitTrigger, activeTool, pendingTextType, pendingShapeSubtype, pendingShapeViewBox, pendingLineContent, activeIndex, slides, undo, redo, notify,
|
|
@@ -72,6 +73,7 @@ const {
|
|
|
72
73
|
isMaterialEnabled, materialPopoverVisible, placeholderMaterialTargetId, setPlaceholderMaterialTargetId, replacePlaceholderElement
|
|
73
74
|
} = useSlides()
|
|
74
75
|
const activeTab = activeTabRaw as any
|
|
76
|
+
const { isDamLoggedIn, sharedMaterialMainTab, setSharedMaterialMainTab, refreshSessionState } = useDamAuth()
|
|
75
77
|
|
|
76
78
|
const isDragging = ref(false)
|
|
77
79
|
|
|
@@ -1958,7 +1960,8 @@ function handleWindowMouseDown(e: MouseEvent) {
|
|
|
1958
1960
|
target.closest('.el-dialog') ||
|
|
1959
1961
|
target.closest('.el-overlay') ||
|
|
1960
1962
|
target.closest('.custom-fullscreen-preview-modal') ||
|
|
1961
|
-
target.closest('.placeholder-action-popover')
|
|
1963
|
+
target.closest('.placeholder-action-popover') ||
|
|
1964
|
+
target.closest('.material-drawer-container')
|
|
1962
1965
|
) {
|
|
1963
1966
|
return
|
|
1964
1967
|
}
|
|
@@ -2313,6 +2316,7 @@ function handleImagePlaceholderClick(elId: string) {
|
|
|
2313
2316
|
triggerPlaceholderImageUpload(elId)
|
|
2314
2317
|
return
|
|
2315
2318
|
}
|
|
2319
|
+
refreshSessionState()
|
|
2316
2320
|
activePlaceholderMenuElId.value = elId
|
|
2317
2321
|
}
|
|
2318
2322
|
|
|
@@ -2321,8 +2325,7 @@ function handlePlaceholderMenuUpload(elId: string) {
|
|
|
2321
2325
|
triggerPlaceholderImageUpload(elId)
|
|
2322
2326
|
}
|
|
2323
2327
|
|
|
2324
|
-
function
|
|
2325
|
-
activePlaceholderMenuElId.value = null
|
|
2328
|
+
function bindPlaceholderTarget(elId: string) {
|
|
2326
2329
|
if (setPlaceholderMaterialTargetId) {
|
|
2327
2330
|
setPlaceholderMaterialTargetId(elId)
|
|
2328
2331
|
} else if (placeholderMaterialTargetId) {
|
|
@@ -2334,6 +2337,23 @@ function handlePlaceholderMenuMaterial(elId: string) {
|
|
|
2334
2337
|
if (materialPopoverVisible) {
|
|
2335
2338
|
materialPopoverVisible.value = false
|
|
2336
2339
|
}
|
|
2340
|
+
}
|
|
2341
|
+
|
|
2342
|
+
function handlePlaceholderMenuMaterial(elId: string) {
|
|
2343
|
+
activePlaceholderMenuElId.value = null
|
|
2344
|
+
bindPlaceholderTarget(elId)
|
|
2345
|
+
if (sharedMaterialMainTab.value === 'create') {
|
|
2346
|
+
setSharedMaterialMainTab('search')
|
|
2347
|
+
}
|
|
2348
|
+
activeTab.value = 'material'
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
function handlePlaceholderMenuAiCreate(elId: string) {
|
|
2352
|
+
activePlaceholderMenuElId.value = null
|
|
2353
|
+
refreshSessionState()
|
|
2354
|
+
if (!isDamLoggedIn.value) return
|
|
2355
|
+
bindPlaceholderTarget(elId)
|
|
2356
|
+
setSharedMaterialMainTab('create')
|
|
2337
2357
|
activeTab.value = 'material'
|
|
2338
2358
|
}
|
|
2339
2359
|
|
|
@@ -2351,7 +2371,7 @@ const getPlaceholderActionMenuStyle = (el: any) => {
|
|
|
2351
2371
|
const iconHalfWPhysical = Math.min(28, rect.width * 0.225) * scale
|
|
2352
2372
|
|
|
2353
2373
|
const menuW = 148
|
|
2354
|
-
const menuH = 80
|
|
2374
|
+
const menuH = isDamLoggedIn.value ? 114 : 80
|
|
2355
2375
|
let left = centerXPhysical + iconHalfWPhysical + 8
|
|
2356
2376
|
if (left + menuW > slideW - 8) {
|
|
2357
2377
|
left = Math.max(8, centerXPhysical - iconHalfWPhysical - 8 - menuW)
|
|
@@ -9064,6 +9084,18 @@ async function handleGlobalPaste(e: ClipboardEvent) {
|
|
|
9064
9084
|
</svg>
|
|
9065
9085
|
<span>从素材库选择</span>
|
|
9066
9086
|
</button>
|
|
9087
|
+
<button
|
|
9088
|
+
v-if="isDamLoggedIn"
|
|
9089
|
+
type="button"
|
|
9090
|
+
class="placeholder-action-item is-ai-create"
|
|
9091
|
+
@click.stop="handlePlaceholderMenuAiCreate(selectedElement.id)"
|
|
9092
|
+
>
|
|
9093
|
+
<svg viewBox="0 0 24 24" class="placeholder-action-icon">
|
|
9094
|
+
<path d="M12 3l1.9 4.6L18.5 9.5l-4.6 1.9L12 16l-1.9-4.6L5.5 9.5l4.6-1.9L12 3z" />
|
|
9095
|
+
<path d="M19 15l.9 2.1L22 18l-2.1.9L19 21l-.9-2.1L16 18l2.1-.9L19 15z" />
|
|
9096
|
+
</svg>
|
|
9097
|
+
<span>AI生成</span>
|
|
9098
|
+
</button>
|
|
9067
9099
|
</div>
|
|
9068
9100
|
</div>
|
|
9069
9101
|
</div>
|
|
@@ -12,6 +12,9 @@ import {
|
|
|
12
12
|
} from '@element-plus/icons-vue'
|
|
13
13
|
import { useSlides, DEFAULT_MATERIAL_PAGE_API_URL } from '../composables/useSlides'
|
|
14
14
|
import { isImagePlaceholder } from '../utils/canvas/elementStyles'
|
|
15
|
+
import { useDamAuth } from './material/useDamAuth'
|
|
16
|
+
import MyAssetsPanel from './material/MyAssetsPanel.vue'
|
|
17
|
+
import CreateMaterialPanel from './material/CreateMaterialPanel.vue'
|
|
15
18
|
|
|
16
19
|
const {
|
|
17
20
|
addElement,
|
|
@@ -103,6 +106,52 @@ const subTypeNameMap: Record<StockSubType, string> = {
|
|
|
103
106
|
Videos: '高清视频'
|
|
104
107
|
}
|
|
105
108
|
|
|
109
|
+
// 顶层 3-Tab 状态(检索 / 我的素材 / 创建素材)与 jvs_session_v3 鉴权
|
|
110
|
+
export type MaterialMainTab = 'search' | 'mine' | 'create'
|
|
111
|
+
const {
|
|
112
|
+
isDamLoggedIn,
|
|
113
|
+
sharedMaterialMainTab: activeMainTab,
|
|
114
|
+
refreshSessionState,
|
|
115
|
+
probeRemoteSessionV3
|
|
116
|
+
} = useDamAuth()
|
|
117
|
+
|
|
118
|
+
const myAssetsRef = ref<InstanceType<typeof MyAssetsPanel> | null>(null)
|
|
119
|
+
const createPanelRef = ref<InstanceType<typeof CreateMaterialPanel> | null>(null)
|
|
120
|
+
|
|
121
|
+
// 未登录点击受限 Tab 时的顶部轻量胶囊提示(不遮挡 Tab,不暴露技术字段)
|
|
122
|
+
const guestToastVisible = ref(false)
|
|
123
|
+
const guestToastText = ref('请先登录后使用该功能')
|
|
124
|
+
let guestToastTimer: ReturnType<typeof setTimeout> | null = null
|
|
125
|
+
|
|
126
|
+
function showGuestAuthToast(tabName: string) {
|
|
127
|
+
guestToastText.value = tabName === '我的素材'
|
|
128
|
+
? '请先登录后查看「我的素材」'
|
|
129
|
+
: '请先登录后使用「创建素材」'
|
|
130
|
+
guestToastVisible.value = true
|
|
131
|
+
if (guestToastTimer) clearTimeout(guestToastTimer)
|
|
132
|
+
guestToastTimer = setTimeout(() => {
|
|
133
|
+
guestToastVisible.value = false
|
|
134
|
+
}, 2200)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function handleSwitchMainTab(tab: MaterialMainTab) {
|
|
138
|
+
refreshSessionState()
|
|
139
|
+
if (tab !== 'search' && !isDamLoggedIn.value) {
|
|
140
|
+
const verified = await probeRemoteSessionV3(true)
|
|
141
|
+
if (!verified && !isDamLoggedIn.value) {
|
|
142
|
+
showGuestAuthToast(tab === 'mine' ? '我的素材' : '创建素材')
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
activeMainTab.value = tab
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
watch(isDamLoggedIn, (loggedIn) => {
|
|
150
|
+
if (!loggedIn && activeMainTab.value !== 'search') {
|
|
151
|
+
activeMainTab.value = 'search'
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
|
|
106
155
|
// 视图状态:先图二 (overview) 再图三 (detail)
|
|
107
156
|
const viewMode = ref<'overview' | 'detail'>('overview')
|
|
108
157
|
const overviewQuery = ref('')
|
|
@@ -248,6 +297,99 @@ function openPreview(item: MaterialItem, e?: Event) {
|
|
|
248
297
|
previewVisible.value = true
|
|
249
298
|
}
|
|
250
299
|
|
|
300
|
+
// 供「我的素材」与「创建素材」子面板复用的全屏大图/视频预览
|
|
301
|
+
function openCustomListPreview(item: MaterialItem, list: MaterialItem[], e?: Event) {
|
|
302
|
+
if (e) {
|
|
303
|
+
e.stopPropagation()
|
|
304
|
+
e.preventDefault()
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const currentUrl = isVideoMaterial(item)
|
|
308
|
+
? (item.sourceUrl || item.url || item.downloadUrl || getMaterialThumb(item))
|
|
309
|
+
: getMaterialThumb(item)
|
|
310
|
+
|
|
311
|
+
if (!currentUrl) {
|
|
312
|
+
notify('该素材暂无可用预览地址')
|
|
313
|
+
return
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const sourceList = Array.isArray(list) && list.length > 0 ? list : [item]
|
|
317
|
+
const validItems: PreviewItem[] = []
|
|
318
|
+
|
|
319
|
+
sourceList.forEach(m => {
|
|
320
|
+
const isVid = isVideoMaterial(m)
|
|
321
|
+
const u = isVid
|
|
322
|
+
? (m.sourceUrl || m.url || m.downloadUrl || getMaterialThumb(m))
|
|
323
|
+
: getMaterialThumb(m)
|
|
324
|
+
if (u) {
|
|
325
|
+
validItems.push({
|
|
326
|
+
url: u,
|
|
327
|
+
isVideo: isVid && isVideoUrl(u),
|
|
328
|
+
title: m.title || '素材预览',
|
|
329
|
+
format: getItemFormat(m),
|
|
330
|
+
meta: m
|
|
331
|
+
})
|
|
332
|
+
}
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
const targetIdx = validItems.findIndex(i => i.url === currentUrl)
|
|
336
|
+
if (targetIdx >= 0) {
|
|
337
|
+
previewInitialIndex.value = targetIdx
|
|
338
|
+
} else {
|
|
339
|
+
validItems.unshift({
|
|
340
|
+
url: currentUrl,
|
|
341
|
+
isVideo: isVideoMaterial(item) && isVideoUrl(currentUrl),
|
|
342
|
+
title: item.title || '素材预览',
|
|
343
|
+
format: getItemFormat(item),
|
|
344
|
+
meta: item
|
|
345
|
+
})
|
|
346
|
+
previewInitialIndex.value = 0
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
previewList.value = validItems
|
|
350
|
+
|
|
351
|
+
if (materialPopoverVisible && materialPopoverVisible.value) {
|
|
352
|
+
wasPopoverOpenBeforePreview.value = true
|
|
353
|
+
materialPopoverVisible.value = false
|
|
354
|
+
} else {
|
|
355
|
+
wasPopoverOpenBeforePreview.value = false
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
previewVisible.value = true
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// 将「检索」或「我的素材」中的图片一键送入「创建素材」作为参考图
|
|
362
|
+
async function handleSendToCreateRef(item: MaterialItem, e?: Event) {
|
|
363
|
+
if (e) {
|
|
364
|
+
e.stopPropagation()
|
|
365
|
+
e.preventDefault()
|
|
366
|
+
}
|
|
367
|
+
refreshSessionState()
|
|
368
|
+
if (!isDamLoggedIn.value) {
|
|
369
|
+
const verified = await probeRemoteSessionV3(true)
|
|
370
|
+
if (!verified && !isDamLoggedIn.value) {
|
|
371
|
+
showGuestAuthToast('创建素材')
|
|
372
|
+
return
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
const thumbUrl = getMaterialThumb(item)
|
|
376
|
+
if (!thumbUrl) {
|
|
377
|
+
notify('该素材暂无可用参考图地址')
|
|
378
|
+
return
|
|
379
|
+
}
|
|
380
|
+
activeMainTab.value = 'create'
|
|
381
|
+
nextTick(() => {
|
|
382
|
+
createPanelRef.value?.addReferenceItem({
|
|
383
|
+
url: thumbUrl,
|
|
384
|
+
name: item.title || '参考图'
|
|
385
|
+
})
|
|
386
|
+
})
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function handleOnMaterialGenerated() {
|
|
390
|
+
myAssetsRef.value?.reloadAssets?.()
|
|
391
|
+
}
|
|
392
|
+
|
|
251
393
|
function closePreview() {
|
|
252
394
|
previewVisible.value = false
|
|
253
395
|
if (wasPopoverOpenBeforePreview.value && materialPopoverVisible) {
|
|
@@ -770,9 +912,21 @@ watch([() => materialApiUrl?.value, () => materialPageApiUrl?.value, () => mater
|
|
|
770
912
|
|
|
771
913
|
<template>
|
|
772
914
|
<div class="material-drawer-container">
|
|
915
|
+
<!-- 未登录点击「我的素材/创建素材」时的顶部轻量胶囊提示 -->
|
|
916
|
+
<transition name="guest-toast-fade">
|
|
917
|
+
<div v-if="guestToastVisible" class="guest-auth-toast">
|
|
918
|
+
<svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="#d97706" stroke-width="2.2">
|
|
919
|
+
<circle cx="12" cy="12" r="10" />
|
|
920
|
+
<line x1="12" y1="8" x2="12" y2="12" />
|
|
921
|
+
<line x1="12" y1="16" x2="12.01" y2="16" />
|
|
922
|
+
</svg>
|
|
923
|
+
<span>{{ guestToastText }}</span>
|
|
924
|
+
</div>
|
|
925
|
+
</transition>
|
|
926
|
+
|
|
773
927
|
<!-- 顶部抽屉标题栏:图二显示「素材库」,图三显示「← 分类/搜索词」 -->
|
|
774
928
|
<div class="material-drawer-header">
|
|
775
|
-
<div v-if="viewMode === 'overview'" class="drawer-header-left">
|
|
929
|
+
<div v-if="activeMainTab !== 'search' || viewMode === 'overview'" class="drawer-header-left">
|
|
776
930
|
<span class="drawer-header-title">素材库</span>
|
|
777
931
|
</div>
|
|
778
932
|
<button v-else type="button" class="drawer-back-btn" @click="backToOverview">
|
|
@@ -793,8 +947,77 @@ watch([() => materialApiUrl?.value, () => materialPageApiUrl?.value, () => mater
|
|
|
793
947
|
</button>
|
|
794
948
|
</div>
|
|
795
949
|
|
|
796
|
-
<!--
|
|
797
|
-
<div v-if="viewMode === 'overview'" class="material-
|
|
950
|
+
<!-- 顶层 3-Tab 分段切换器(检索 | 我的素材 | 创建素材) -->
|
|
951
|
+
<div v-if="activeMainTab !== 'search' || viewMode === 'overview'" class="material-top-tabs-wrap">
|
|
952
|
+
<div class="material-top-segmented">
|
|
953
|
+
<button
|
|
954
|
+
type="button"
|
|
955
|
+
class="material-main-tab-btn"
|
|
956
|
+
:class="{ active: activeMainTab === 'search' }"
|
|
957
|
+
@click="handleSwitchMainTab('search')"
|
|
958
|
+
>
|
|
959
|
+
<span>检索</span>
|
|
960
|
+
</button>
|
|
961
|
+
|
|
962
|
+
<button
|
|
963
|
+
type="button"
|
|
964
|
+
class="material-main-tab-btn"
|
|
965
|
+
:class="{
|
|
966
|
+
active: activeMainTab === 'mine',
|
|
967
|
+
'is-disabled': !isDamLoggedIn
|
|
968
|
+
}"
|
|
969
|
+
:title="!isDamLoggedIn ? '请先登录后查看我的素材' : '查看我的项目与个人素材'"
|
|
970
|
+
@click="handleSwitchMainTab('mine')"
|
|
971
|
+
>
|
|
972
|
+
<span>我的素材</span>
|
|
973
|
+
<svg
|
|
974
|
+
v-if="!isDamLoggedIn"
|
|
975
|
+
class="tab-lock-svg"
|
|
976
|
+
viewBox="0 0 24 24"
|
|
977
|
+
width="11"
|
|
978
|
+
height="11"
|
|
979
|
+
fill="none"
|
|
980
|
+
stroke="currentColor"
|
|
981
|
+
stroke-width="2.2"
|
|
982
|
+
>
|
|
983
|
+
<rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
|
|
984
|
+
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
985
|
+
</svg>
|
|
986
|
+
</button>
|
|
987
|
+
|
|
988
|
+
<button
|
|
989
|
+
type="button"
|
|
990
|
+
class="material-main-tab-btn"
|
|
991
|
+
:class="{
|
|
992
|
+
active: activeMainTab === 'create',
|
|
993
|
+
'is-disabled': !isDamLoggedIn
|
|
994
|
+
}"
|
|
995
|
+
:title="!isDamLoggedIn ? '请先登录后使用创建素材' : 'AI 生成图片或视频素材'"
|
|
996
|
+
@click="handleSwitchMainTab('create')"
|
|
997
|
+
>
|
|
998
|
+
<span>创建素材</span>
|
|
999
|
+
<span v-if="isDamLoggedIn" class="tab-ai-spark">✦</span>
|
|
1000
|
+
<svg
|
|
1001
|
+
v-else
|
|
1002
|
+
class="tab-lock-svg"
|
|
1003
|
+
viewBox="0 0 24 24"
|
|
1004
|
+
width="11"
|
|
1005
|
+
height="11"
|
|
1006
|
+
fill="none"
|
|
1007
|
+
stroke="currentColor"
|
|
1008
|
+
stroke-width="2.2"
|
|
1009
|
+
>
|
|
1010
|
+
<rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
|
|
1011
|
+
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
1012
|
+
</svg>
|
|
1013
|
+
</button>
|
|
1014
|
+
</div>
|
|
1015
|
+
</div>
|
|
1016
|
+
|
|
1017
|
+
<!-- ==================== Tab 1:检索(公网素材分类概览 & 详情瀑布流) ==================== -->
|
|
1018
|
+
<template v-if="activeMainTab === 'search'">
|
|
1019
|
+
<!-- 图二:素材库分类概览视图 -->
|
|
1020
|
+
<div v-if="viewMode === 'overview'" class="material-overview-body">
|
|
798
1021
|
<!-- 搜索框 -->
|
|
799
1022
|
<div class="overview-search-wrap">
|
|
800
1023
|
<div class="overview-search-box">
|
|
@@ -873,6 +1096,15 @@ watch([() => materialApiUrl?.value, () => materialPageApiUrl?.value, () => mater
|
|
|
873
1096
|
<span v-if="cat.subType === 'Videos' || isVideoMaterial(item)" class="video-badge-icon">
|
|
874
1097
|
<el-icon><VideoPlay /></el-icon>
|
|
875
1098
|
</span>
|
|
1099
|
+
<button
|
|
1100
|
+
v-if="isDamLoggedIn && cat.subType !== 'Videos' && !isVideoMaterial(item) && getMaterialThumb(item)"
|
|
1101
|
+
type="button"
|
|
1102
|
+
class="overview-card-ref-btn"
|
|
1103
|
+
title="作为参考图发送到「创建素材」"
|
|
1104
|
+
@click.stop.prevent="handleSendToCreateRef(item, $event)"
|
|
1105
|
+
>
|
|
1106
|
+
@参考
|
|
1107
|
+
</button>
|
|
876
1108
|
</div>
|
|
877
1109
|
</template>
|
|
878
1110
|
|
|
@@ -1014,6 +1246,17 @@ watch([() => materialApiUrl?.value, () => materialPageApiUrl?.value, () => mater
|
|
|
1014
1246
|
<el-icon><VideoPlay /></el-icon>
|
|
1015
1247
|
</span>
|
|
1016
1248
|
|
|
1249
|
+
<!-- 悬浮设为参考图按钮 -->
|
|
1250
|
+
<button
|
|
1251
|
+
v-if="isDamLoggedIn && filterParams.activeSubType !== 'Videos' && !isVideoMaterial(item) && getMaterialThumb(item)"
|
|
1252
|
+
type="button"
|
|
1253
|
+
class="detail-card-ref-btn"
|
|
1254
|
+
title="作为参考图发送到「创建素材」"
|
|
1255
|
+
@click.stop.prevent="handleSendToCreateRef(item, $event)"
|
|
1256
|
+
>
|
|
1257
|
+
@参考
|
|
1258
|
+
</button>
|
|
1259
|
+
|
|
1017
1260
|
<!-- 悬浮预览小按钮 -->
|
|
1018
1261
|
<button
|
|
1019
1262
|
v-if="getMaterialThumb(item)"
|
|
@@ -1064,6 +1307,25 @@ watch([() => materialApiUrl?.value, () => materialPageApiUrl?.value, () => mater
|
|
|
1064
1307
|
</div>
|
|
1065
1308
|
</div>
|
|
1066
1309
|
</div>
|
|
1310
|
+
</template>
|
|
1311
|
+
|
|
1312
|
+
<!-- ==================== Tab 2:我的素材(jvs-material-ui 资产库接入) ==================== -->
|
|
1313
|
+
<MyAssetsPanel
|
|
1314
|
+
v-else-if="activeMainTab === 'mine' && isDamLoggedIn"
|
|
1315
|
+
ref="myAssetsRef"
|
|
1316
|
+
@select="handleSelectMaterial"
|
|
1317
|
+
@preview="openCustomListPreview"
|
|
1318
|
+
@use-as-ref="(item) => handleSendToCreateRef(item)"
|
|
1319
|
+
/>
|
|
1320
|
+
|
|
1321
|
+
<!-- ==================== Tab 3:创建素材(AI 图片生成器 & 视频生成) ==================== -->
|
|
1322
|
+
<CreateMaterialPanel
|
|
1323
|
+
v-else-if="activeMainTab === 'create' && isDamLoggedIn"
|
|
1324
|
+
ref="createPanelRef"
|
|
1325
|
+
@select="handleSelectMaterial"
|
|
1326
|
+
@preview="openCustomListPreview"
|
|
1327
|
+
@generated="handleOnMaterialGenerated"
|
|
1328
|
+
/>
|
|
1067
1329
|
|
|
1068
1330
|
<!-- 全屏大图/视频预览 Modal -->
|
|
1069
1331
|
<teleport to="body">
|
|
@@ -1146,6 +1408,7 @@ watch([() => materialApiUrl?.value, () => materialPageApiUrl?.value, () => mater
|
|
|
1146
1408
|
|
|
1147
1409
|
<style scoped lang="scss">
|
|
1148
1410
|
.material-drawer-container {
|
|
1411
|
+
position: relative;
|
|
1149
1412
|
display: flex;
|
|
1150
1413
|
flex-direction: column;
|
|
1151
1414
|
width: 288px;
|
|
@@ -1157,18 +1420,112 @@ watch([() => materialApiUrl?.value, () => materialPageApiUrl?.value, () => mater
|
|
|
1157
1420
|
user-select: none;
|
|
1158
1421
|
}
|
|
1159
1422
|
|
|
1423
|
+
/* 未登录点击受限 Tab 时的顶部轻量胶囊提示 */
|
|
1424
|
+
.guest-auth-toast {
|
|
1425
|
+
position: absolute;
|
|
1426
|
+
top: 10px;
|
|
1427
|
+
left: 50%;
|
|
1428
|
+
transform: translateX(-50%);
|
|
1429
|
+
background: #fffbeb;
|
|
1430
|
+
border: 1px solid #fde68a;
|
|
1431
|
+
color: #b45309;
|
|
1432
|
+
font-size: 11.5px;
|
|
1433
|
+
font-weight: 500;
|
|
1434
|
+
padding: 5px 12px;
|
|
1435
|
+
border-radius: 99px;
|
|
1436
|
+
white-space: nowrap;
|
|
1437
|
+
z-index: 200;
|
|
1438
|
+
box-shadow: 0 4px 12px rgba(217, 119, 6, 0.12);
|
|
1439
|
+
display: flex;
|
|
1440
|
+
align-items: center;
|
|
1441
|
+
gap: 5px;
|
|
1442
|
+
pointer-events: none;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
.guest-toast-fade-enter-active,
|
|
1446
|
+
.guest-toast-fade-leave-active {
|
|
1447
|
+
transition: opacity 0.18s ease, transform 0.18s ease;
|
|
1448
|
+
}
|
|
1449
|
+
.guest-toast-fade-enter-from,
|
|
1450
|
+
.guest-toast-fade-leave-to {
|
|
1451
|
+
opacity: 0;
|
|
1452
|
+
transform: translate(-50%, -6px);
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1160
1455
|
/* 顶部栏(图二:素材库 / 图三:← 分类名) */
|
|
1161
1456
|
.material-drawer-header {
|
|
1162
1457
|
display: flex;
|
|
1163
1458
|
align-items: center;
|
|
1164
1459
|
justify-content: space-between;
|
|
1165
|
-
height:
|
|
1460
|
+
height: 44px;
|
|
1166
1461
|
padding: 0 16px;
|
|
1167
|
-
border-bottom:
|
|
1462
|
+
border-bottom: none;
|
|
1168
1463
|
flex-shrink: 0;
|
|
1169
1464
|
box-sizing: border-box;
|
|
1170
1465
|
}
|
|
1171
1466
|
|
|
1467
|
+
/* 顶层 3-Tab 分段切换器(检索 | 我的素材 | 创建素材) */
|
|
1468
|
+
.material-top-tabs-wrap {
|
|
1469
|
+
padding: 2px 16px 10px;
|
|
1470
|
+
border-bottom: 1px solid #f1f5f9;
|
|
1471
|
+
flex-shrink: 0;
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
.material-top-segmented {
|
|
1475
|
+
display: grid;
|
|
1476
|
+
grid-template-columns: repeat(3, 1fr);
|
|
1477
|
+
background: #f1f5f9;
|
|
1478
|
+
padding: 3px;
|
|
1479
|
+
border-radius: 8px;
|
|
1480
|
+
gap: 2px;
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
.material-main-tab-btn {
|
|
1484
|
+
height: 28px;
|
|
1485
|
+
border: none;
|
|
1486
|
+
background: transparent;
|
|
1487
|
+
border-radius: 6px;
|
|
1488
|
+
font-size: 12px;
|
|
1489
|
+
font-weight: 500;
|
|
1490
|
+
color: #64748b;
|
|
1491
|
+
cursor: pointer;
|
|
1492
|
+
display: inline-flex;
|
|
1493
|
+
align-items: center;
|
|
1494
|
+
justify-content: center;
|
|
1495
|
+
gap: 3px;
|
|
1496
|
+
padding: 0 4px;
|
|
1497
|
+
white-space: nowrap;
|
|
1498
|
+
transition: all 0.18s ease;
|
|
1499
|
+
|
|
1500
|
+
&:hover:not(.active):not(.is-disabled) {
|
|
1501
|
+
color: #1e293b;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
&.active {
|
|
1505
|
+
background: #ffffff;
|
|
1506
|
+
color: #1e6fff;
|
|
1507
|
+
font-weight: 600;
|
|
1508
|
+
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08);
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
&.is-disabled {
|
|
1512
|
+
color: #94a3b8;
|
|
1513
|
+
cursor: not-allowed;
|
|
1514
|
+
opacity: 0.72;
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
.tab-ai-spark {
|
|
1519
|
+
font-size: 11px;
|
|
1520
|
+
line-height: 1;
|
|
1521
|
+
color: #8b5cf6;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
.tab-lock-svg {
|
|
1525
|
+
flex-shrink: 0;
|
|
1526
|
+
color: #94a3b8;
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1172
1529
|
.drawer-header-left {
|
|
1173
1530
|
display: flex;
|
|
1174
1531
|
align-items: center;
|
|
@@ -1382,6 +1739,32 @@ watch([() => materialApiUrl?.value, () => materialPageApiUrl?.value, () => mater
|
|
|
1382
1739
|
&:hover .overview-thumb-img {
|
|
1383
1740
|
transform: scale(1.04);
|
|
1384
1741
|
}
|
|
1742
|
+
|
|
1743
|
+
&:hover .overview-card-ref-btn {
|
|
1744
|
+
opacity: 1;
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
.overview-card-ref-btn {
|
|
1749
|
+
position: absolute;
|
|
1750
|
+
left: 5px;
|
|
1751
|
+
bottom: 5px;
|
|
1752
|
+
height: 19px;
|
|
1753
|
+
padding: 0 6px;
|
|
1754
|
+
border-radius: 4px;
|
|
1755
|
+
border: none;
|
|
1756
|
+
background: rgba(15, 23, 42, 0.68);
|
|
1757
|
+
color: #ffffff;
|
|
1758
|
+
font-size: 10px;
|
|
1759
|
+
font-weight: 500;
|
|
1760
|
+
cursor: pointer;
|
|
1761
|
+
opacity: 0;
|
|
1762
|
+
transition: all 0.15s ease;
|
|
1763
|
+
z-index: 3;
|
|
1764
|
+
|
|
1765
|
+
&:hover {
|
|
1766
|
+
background: #1e6fff;
|
|
1767
|
+
}
|
|
1385
1768
|
}
|
|
1386
1769
|
|
|
1387
1770
|
.overview-thumb-img {
|
|
@@ -1579,11 +1962,34 @@ watch([() => materialApiUrl?.value, () => materialPageApiUrl?.value, () => mater
|
|
|
1579
1962
|
transform: scale(1.03);
|
|
1580
1963
|
}
|
|
1581
1964
|
|
|
1582
|
-
&:hover .detail-card-preview-btn
|
|
1965
|
+
&:hover .detail-card-preview-btn,
|
|
1966
|
+
&:hover .detail-card-ref-btn {
|
|
1583
1967
|
opacity: 1;
|
|
1584
1968
|
}
|
|
1585
1969
|
}
|
|
1586
1970
|
|
|
1971
|
+
.detail-card-ref-btn {
|
|
1972
|
+
position: absolute;
|
|
1973
|
+
left: 6px;
|
|
1974
|
+
bottom: 6px;
|
|
1975
|
+
height: 20px;
|
|
1976
|
+
padding: 0 6px;
|
|
1977
|
+
border-radius: 4px;
|
|
1978
|
+
border: none;
|
|
1979
|
+
background: rgba(15, 23, 42, 0.68);
|
|
1980
|
+
color: #ffffff;
|
|
1981
|
+
font-size: 10px;
|
|
1982
|
+
font-weight: 500;
|
|
1983
|
+
cursor: pointer;
|
|
1984
|
+
opacity: 0;
|
|
1985
|
+
transition: all 0.15s ease;
|
|
1986
|
+
z-index: 3;
|
|
1987
|
+
|
|
1988
|
+
&:hover {
|
|
1989
|
+
background: #1e6fff;
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1587
1993
|
.detail-card-img {
|
|
1588
1994
|
width: 100%;
|
|
1589
1995
|
height: auto;
|