Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mengchangaigc
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
姚珂
mengchangaigc
Commits
96e60a33
Commit
96e60a33
authored
Aug 28, 2026
by
黄同智
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
快速创作的首页内容
parent
9c61bde6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
843 additions
and
2 deletions
+843
-2
common.scss
apps/web-vue/public/styles/common.scss
+5
-0
index.vue
apps/web-vue/src/layout/index.vue
+2
-2
index.ts
apps/web-vue/src/router/index.ts
+13
-0
CreativeComposer.vue
...e/src/views/quickCreation/components/CreativeComposer.vue
+0
-0
InspirationGallery.vue
...src/views/quickCreation/components/InspirationGallery.vue
+306
-0
InspirationPreviewDialog.vue
...ews/quickCreation/components/InspirationPreviewDialog.vue
+313
-0
ToolGroup.vue
.../web-vue/src/views/quickCreation/components/ToolGroup.vue
+133
-0
index.vue
apps/web-vue/src/views/quickCreation/index.vue
+70
-0
types.ts
apps/web-vue/src/views/quickCreation/types.ts
+1
-0
No files found.
apps/web-vue/public/styles/common.scss
View file @
96e60a33
...
...
@@ -232,4 +232,8 @@ $spacing-values: ();
.el-checkbox__label
{
display
:
none
!
important
;
}
}
.
hide-scroll
:
:-
webkit-scrollbar
{
display
:
none
;
}
\ No newline at end of file
apps/web-vue/src/layout/index.vue
View file @
96e60a33
...
...
@@ -81,7 +81,7 @@ const menus = [
},
{
name
:
'快速创作'
,
path
:
'/'
,
path
:
'/
quickCreation
'
,
icon
:
'add'
,
},
{
...
...
@@ -106,7 +106,7 @@ const menus = [
},
{
name
:
'画布'
,
path
:
'/'
,
path
:
'/
vueFlow
'
,
icon
:
'redraw'
,
},
{
...
...
apps/web-vue/src/router/index.ts
View file @
96e60a33
...
...
@@ -9,6 +9,7 @@ import VideoOutMp4 from '@/views/vue-flow/components/VideoOutMp4.vue'
import
ThreeD
from
'@/views/vue-flow/3d.vue'
import
Layout
from
'@/layout/index.vue'
import
Task
from
'@/views/task/index.vue'
import
QuickCreation
from
'@/views/quickCreation/index.vue'
const
routes
=
[
{
...
...
@@ -42,6 +43,18 @@ const routes = [
]
},
{
path
:
'/quickCreation'
,
component
:
Layout
,
children
:
[
{
path
:
''
,
name
:
'QuickCreation'
,
component
:
QuickCreation
,
meta
:
{
title
:
'快速创作'
,
icon
:
'add'
,
affix
:
true
}
}
]
},
{
path
:
'/zhibo'
,
component
:
Layout
,
children
:
[
...
...
apps/web-vue/src/views/quickCreation/components/CreativeComposer.vue
0 → 100644
View file @
96e60a33
This diff is collapsed.
Click to expand it.
apps/web-vue/src/views/quickCreation/components/InspirationGallery.vue
0 → 100644
View file @
96e60a33
<
template
>
<section>
<div
class=
"flex-between mb-16"
>
<h2
class=
"fs-18 lh-28 fw-700"
>
电商爆款灵感画廊
</h2>
<div
class=
"category-tabs flex-items-center gap-4 h-34 p-4 round-10 bg-fff"
>
<el-button
v-for=
"item in categories"
:key=
"item"
class=
"tab-btn h-26 px-12 round-8 border-none fs-12 fw-700"
:class=
"
{ active: activeCategory === item }"
text
@click="activeCategory = item"
>
{{
item
}}
</el-button>
</div>
</div>
<div
class=
"gallery-list flex flex-wrap gap-20"
>
<el-card
v-for=
"(item, index) in filteredList"
:key=
"item.title"
class=
"gallery-card flex-item round-14 hidden pointer"
shadow=
"never"
@
click=
"openPreview(index)"
>
<div
class=
"image-wrap relative h-240 hidden"
>
<img
:src=
"item.cover"
:alt=
"item.title"
class=
"w-full h-full cover"
/>
<span
class=
"play-btn absolute flex-center wh-50 round color-fff fs-24"
>
<el-icon><VideoPlay
/></el-icon>
</span>
<span
class=
"copy-btn absolute flex-center gap-6 h-30 px-12 round-8 color-fff fs-12 fw-700"
>
<el-icon><MagicStick
/></el-icon>
<span>
一键同款
</span>
</span>
<span
class=
"duration absolute h-20 lh-20 px-6 round-4 color-fff fs-10 fw-700"
>
{{
item
.
duration
}}
</span>
</div>
<div
class=
"p-16"
>
<h3
class=
"fs-14 lh-22 fw-700 ellipsis"
>
{{
item
.
title
}}
</h3>
<div
class=
"flex-between mt-12"
>
<div
class=
"flex-items-center minw-0"
>
<span
class=
"avatar flex-center wh-18 round mr-6 color-fff fs-10"
>
{{
item
.
author
.
slice
(
0
,
1
)
}}
</span>
<span
class=
"fs-12 color-789 ellipsis"
>
{{
item
.
author
}}
</span>
</div>
<div
class=
"flex-items-center gap-10 fs-12 color-789"
>
<span
class=
"flex-items-center gap-4"
>
<el-icon
class=
"like-icon"
><Star
/></el-icon>
{{
item
.
likes
}}
</span>
<span
class=
"flex-items-center gap-4"
>
<el-icon><View
/></el-icon>
{{
item
.
views
}}
</span>
</div>
</div>
</div>
</el-card>
</div>
<InspirationPreviewDialog
v-model=
"previewVisible"
:items=
"filteredList"
:index=
"previewIndex"
/>
</section>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
ref
}
from
'vue'
;
import
{
MagicStick
,
Star
,
VideoPlay
,
View
}
from
'@element-plus/icons-vue'
;
import
productImg
from
'@/static/image/huaban.png'
;
import
peopleImg
from
'@/static/image/meinv.png'
;
import
detailImg
from
'@/static/image/long.png'
;
import
InspirationPreviewDialog
from
'./InspirationPreviewDialog.vue'
;
type
GalleryCategory
=
'全部爆款'
|
'日化美妆'
|
'数码科技'
|
'鞋履服饰'
;
type
GalleryItem
=
{
title
:
string
;
author
:
string
;
category
:
GalleryCategory
;
cover
:
string
;
duration
:
string
;
likes
:
number
;
views
:
number
;
heat
:
number
;
prompt
:
string
;
tags
:
string
[];
};
const
categories
:
GalleryCategory
[]
=
[
'全部爆款'
,
'日化美妆'
,
'数码科技'
,
'鞋履服饰'
];
const
activeCategory
=
ref
<
GalleryCategory
>
(
'全部爆款'
);
const
previewVisible
=
ref
(
false
);
const
previewIndex
=
ref
(
0
);
const
galleryList
:
GalleryItem
[]
=
[
{
title
:
'极简日系高奢美妆主视觉视频'
,
author
:
'Mika_Design'
,
category
:
'日化美妆'
,
cover
:
productImg
,
duration
:
'12s'
,
likes
:
1240
,
views
:
8900
,
heat
:
2630
,
prompt
:
'A bottle of luxury cosmetic serum on a minimalist beige sand surface, soft studio lighting, organic shadows, high-end editorial product video.'
,
tags
:
[
'美妆'
,
'日化'
,
'极简高奢'
,
'大理石晨光'
],
},
{
title
:
'时尚轻奢真丝吊带裙模特视频'
,
author
:
'电商爆款制造机'
,
category
:
'鞋履服饰'
,
cover
:
peopleImg
,
duration
:
'10s'
,
likes
:
852
,
views
:
12400
,
heat
:
2280
,
prompt
:
'Fashion model wearing a silk dress in a modern corridor, cinematic walking shot, soft contrast, premium apparel campaign.'
,
tags
:
[
'服饰'
,
'模特'
,
'轻奢'
,
'街拍'
],
},
{
title
:
'多功能不粘锅户外场景画质增强'
,
author
:
'Chef_Creative'
,
category
:
'日化美妆'
,
cover
:
detailImg
,
duration
:
'15s'
,
likes
:
412
,
views
:
3100
,
heat
:
1860
,
prompt
:
'Outdoor cooking scene with non-stick pan, natural daylight, joyful lifestyle composition, clean product close-up.'
,
tags
:
[
'厨具'
,
'户外'
,
'画质增强'
,
'生活方式'
],
},
{
title
:
'智能运动手表多机位动态展示视频'
,
author
:
'Tech_Reviewer'
,
category
:
'数码科技'
,
cover
:
productImg
,
duration
:
'8s'
,
likes
:
981
,
views
:
6540
,
heat
:
1988
,
prompt
:
'Smart sports watch rotating on a clean gray surface, multi-angle product showcase, premium tech lighting.'
,
tags
:
[
'数码'
,
'手表'
,
'动态展示'
,
'科技感'
],
},
{
title
:
'法式复古高帮帆布鞋户外场景视频'
,
author
:
'SoleMate'
,
category
:
'鞋履服饰'
,
cover
:
peopleImg
,
duration
:
'15s'
,
likes
:
1540
,
views
:
11000
,
heat
:
2960
,
prompt
:
'Red canvas sneaker on vivid red background, dynamic product hero shot, energetic streetwear commercial.'
,
tags
:
[
'鞋履'
,
'红色视觉'
,
'户外'
,
'潮流'
],
},
{
title
:
'暮华金箔高脚杯澄澈饮品倾倒视频'
,
author
:
'Mika_Design'
,
category
:
'日化美妆'
,
cover
:
detailImg
,
duration
:
'10s'
,
likes
:
672
,
views
:
4200
,
heat
:
1740
,
prompt
:
'Refreshing drink poured into a glass with mint and lime, dark moody background, crisp bubbles, summer beverage video.'
,
tags
:
[
'饮品'
,
'清爽'
,
'慢动作'
,
'暗调'
],
},
{
title
:
'蓝牙耳机通勤痛点对比短视频'
,
author
:
'Tech_Reviewer'
,
category
:
'数码科技'
,
cover
:
productImg
,
duration
:
'11s'
,
likes
:
736
,
views
:
7820
,
heat
:
2050
,
prompt
:
'Wireless earbuds commute pain point comparison, split scene, clean tech product lighting, fast-paced social video.'
,
tags
:
[
'数码科技'
,
'痛点对比'
,
'通勤'
,
'蓝牙耳机'
],
},
{
title
:
'夏季防晒衣户外试穿种草视频'
,
author
:
'SoleMate'
,
category
:
'鞋履服饰'
,
cover
:
peopleImg
,
duration
:
'13s'
,
likes
:
1188
,
views
:
9340
,
heat
:
2410
,
prompt
:
'Summer sun-protection jacket try-on in outdoor daylight, lightweight fabric detail, natural model movement.'
,
tags
:
[
'服饰'
,
'防晒衣'
,
'试穿'
,
'户外'
],
},
];
const
filteredList
=
computed
(()
=>
{
if
(
activeCategory
.
value
===
'全部爆款'
)
{
return
galleryList
;
}
return
galleryList
.
filter
((
item
)
=>
item
.
category
===
activeCategory
.
value
);
});
const
openPreview
=
(
index
:
number
)
=>
{
previewIndex
.
value
=
index
;
previewVisible
.
value
=
true
;
};
</
script
>
<
style
lang=
"scss"
scoped
>
.category-tabs
,
.gallery-card
{
border
:
1px
solid
#dfe7f2
;
box-shadow
:
0
2px
6px
rgba
(
21
,
44
,
76
,
.05
);
}
:deep
(
.el-button
+
.el-button
)
{
margin-left
:
0
;
}
.tab-btn
{
color
:
#4c6583
;
}
.tab-btn.active
{
color
:
#001a3d
;
background
:
#fff
;
box-shadow
:
0
1px
4px
rgba
(
17
,
36
,
62
,
.1
);
}
.gallery-card
{
flex
:
0
0
calc
((
100%
-
60px
)
/
4
);
background
:
#fff
;
transition
:
border-color
.24s
,
box-shadow
.24s
,
transform
.24s
;
}
:deep
(
.gallery-card
.el-card__body
)
{
padding
:
0
;
}
.image-wrap
img
{
transition
:
transform
.42s
ease
,
filter
.42s
ease
;
}
.gallery-card
:hover
{
border-color
:
rgba
(
var
(
--
main-color
)
,
.55
);
box-shadow
:
0
14px
30px
rgba
(
28
,
46
,
76
,
.14
);
transform
:
translateY
(
-3px
);
}
.gallery-card
:hover
.image-wrap
img
{
filter
:
brightness
(
.88
);
transform
:
scale
(
1
.08
);
}
.play-btn
{
top
:
50%
;
left
:
50%
;
background
:
rgba
(
var
(
--
main-color
)
,
1
);
box-shadow
:
0
10px
24px
rgba
(
var
(
--
main-color
)
,
.34
);
transform
:
translate
(
-50%
,
-50%
);
transition
:
transform
.24s
,
box-shadow
.24s
;
}
.gallery-card
:hover
.play-btn
{
box-shadow
:
0
14px
30px
rgba
(
var
(
--
main-color
)
,
.46
);
transform
:
translate
(
-50%
,
-50%
)
scale
(
1
.12
);
}
.copy-btn
{
left
:
14px
;
bottom
:
12px
;
background
:
rgba
(
var
(
--
main-color
)
,
1
);
box-shadow
:
0
6px
16px
rgba
(
var
(
--
main-color
)
,
.3
);
}
.duration
{
right
:
10px
;
bottom
:
12px
;
background
:
rgba
(
9
,
16
,
28
,
.72
);
}
.avatar
{
flex
:
0
0
auto
;
background
:
linear-gradient
(
135deg
,
#9d19ff
,
#ff8a00
);
}
h3
{
color
:
#001a3d
;
}
.color-789
{
color
:
#7890ae
;
}
.like-icon
{
color
:
#ff4ca0
;
}
@media
(
max-width
:
1280px
)
{
.gallery-card
{
flex-basis
:
calc
((
100%
-
40px
)
/
3
);
}
}
@media
(
max-width
:
900px
)
{
.gallery-card
{
flex-basis
:
calc
((
100%
-
20px
)
/
2
);
}
}
</
style
>
apps/web-vue/src/views/quickCreation/components/InspirationPreviewDialog.vue
0 → 100644
View file @
96e60a33
<
template
>
<Dialog
v-model=
"dialogVisible"
bg-color=
"#fff"
width=
"900"
>
<div
v-if=
"currentItem"
class=
"preview-dialog flex bg-fff hidden"
>
<aside
class=
"preview-aside flex-col items-center justify-between py-18"
>
<div
class=
"nav-btn wh-24 flex-center pointer"
@
click=
"prevItem"
>
<el-icon>
<ArrowUp
/>
</el-icon>
</div>
<div
class=
"thumb-list flex-col gap-10"
>
<div
v-for=
"(item, index) in items"
:key=
"item.title"
class=
"thumb-btn w-46 h-58 p-0 round-8 hidden pointer"
:class=
"
{ active: index === activeIndex }" text @click="activeIndex = index">
<img
:src=
"item.cover"
:alt=
"item.title"
class=
"w-full h-full cover"
/>
</div>
</div>
<div
class=
"nav-btn wh-24 flex-center pointer"
@
click=
"nextItem"
>
<el-icon>
<ArrowDown
/>
</el-icon>
</div>
</aside>
<section
class=
"preview-stage relative flex-1 hidden"
>
<img
:src=
"currentItem.cover"
:alt=
"currentItem.title"
class=
"stage-cover w-full h-full cover"
/>
<div
class=
"stage-shade absolute top-0 left-0 w-full h-full"
></div>
<span
class=
"video-badge absolute top-14 left-14 h-22 lh-22 px-8 round-6 color-fff fs-12"
>
{{
currentItem
.
duration
}}
VIDEO
</span>
<span
class=
"play-large absolute flex-center wh-64 round color-fff fs-30"
>
<el-icon>
<VideoPlay
/>
</el-icon>
</span>
<!--
<div
class=
"fake-controls absolute left-16 right-16 bottom-18"
>
<div
class=
"flex-between color-fff mb-10"
>
<div
class=
"flex-items-center gap-18"
>
<el-icon
class=
"fs-20"
>
<VideoPlay
/>
</el-icon>
<span
class=
"fs-16"
>
0:00
</span>
</div>
<div
class=
"flex-items-center gap-20 fs-18"
>
<span>
◔
</span>
<span>
□
</span>
<span>
⋮
</span>
</div>
</div>
<div
class=
"progress-line h-4 round-4"
></div>
</div>
-->
</section>
<section
class=
"preview-info flex-col p-20"
style=
"max-width: 380px;min-width: 380px;"
>
<div
class=
"flex-1 over-y-auto hide-scroll"
>
<div
class=
"flex-items-center gap-10 fs-12 color-789"
>
<span>
创意详情
</span>
<span>
|
</span>
<span
class=
"heat flex-items-center gap-4"
>
<span>
🔥
</span>
<span>
热度
</span>
<strong>
{{
currentItem
.
heat
}}
</strong>
</span>
</div>
<h2
class=
"mt-10 fs-16 lh-30 color-001"
>
{{
currentItem
.
title
}}
</h2>
<div
class=
"flex-items-center gap-8 mt-6"
>
<span
class=
"avatar flex-center wh-22 round color-fff fs-12"
>
{{
currentItem
.
author
.
slice
(
0
,
1
)
}}
</span>
<span
class=
"fs-12 color-334"
>
{{
currentItem
.
author
}}
</span>
<span
class=
"dot wh-4 round"
></span>
<span
class=
"type-tag h-22 lh-22 px-10 round-6 fs-12"
>
视频
</span>
</div>
<div
class=
"flex-between mt-10"
>
<span
class=
"fs-12 color-789"
>
视频提示词
</span>
<el-button
class=
"copy-text h-24 p-0 border-none fs-12 color-main"
text
>
<el-icon>
<CopyDocument
/>
</el-icon>
<span>
复制
</span>
</el-button>
</div>
<div
class=
"prompt-box mt-4 p-10 round-6 fs-12 lh-22 color-334"
>
{{
currentItem
.
prompt
}}
</div>
<div
class=
"mt-20"
>
<div
class=
"fs-12 color-789 mb-10"
>
视频参考图
</div>
<div
class=
"reference-img relative w-96 h-96 round-12 hidden"
>
<img
:src=
"currentItem.cover"
:alt=
"currentItem.title"
class=
"w-full h-full cover"
/>
<span
class=
"source-tag absolute top-8 left-8 h-20 lh-20 px-8 round-6 color-fff fs-10"
>
参考
</span>
</div>
</div>
</div>
<div
class=
"mt-20"
>
<div
class=
"fs-12 color-789 mb-12"
>
视频标签
</div>
<div
class=
"flex-items-center flex-wrap gap-10"
>
<span
v-for=
"tag in currentItem.tags"
:key=
"tag"
class=
"tag-pill h-28 lh-28 px-12 round-14 fs-12 color-main"
>
{{
tag
}}
</span>
</div>
</div>
<div
class=
"dialog-footer flex-items-center mt-20 pt-16"
>
<el-button
class=
"footer-icon wh-32 p-0"
plain
>
<el-icon>
<Star
/>
</el-icon>
</el-button>
<el-button
class=
"footer-icon wh-32 p-0"
plain
>
<el-icon>
<Share
/>
</el-icon>
</el-button>
<el-button
type=
"primary"
class=
"same-btn flex-1"
>
<el-icon>
<MagicStick
/>
</el-icon>
<span>
一键同款
</span>
</el-button>
</div>
</section>
</div>
</Dialog>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
ref
,
watch
}
from
'vue'
;
import
{
ArrowDown
,
ArrowUp
,
CopyDocument
,
MagicStick
,
Share
,
Star
,
VideoPlay
}
from
'@element-plus/icons-vue'
;
export
type
InspirationPreviewItem
=
{
title
:
string
;
author
:
string
;
cover
:
string
;
duration
:
string
;
heat
:
number
;
prompt
:
string
;
tags
:
string
[];
};
const
props
=
defineProps
<
{
modelValue
:
boolean
;
items
:
InspirationPreviewItem
[];
index
:
number
;
}
>
();
const
emit
=
defineEmits
<
{
'update:modelValue'
:
[
value
:
boolean
];
}
>
();
const
activeIndex
=
ref
(
0
);
const
dialogVisible
=
computed
({
get
:
()
=>
props
.
modelValue
,
set
:
(
value
)
=>
emit
(
'update:modelValue'
,
value
),
});
const
currentItem
=
computed
(()
=>
props
.
items
[
activeIndex
.
value
]);
watch
(
()
=>
props
.
index
,
(
value
)
=>
{
activeIndex
.
value
=
Math
.
max
(
0
,
Math
.
min
(
value
,
props
.
items
.
length
-
1
));
},
{
immediate
:
true
},
);
const
prevItem
=
()
=>
{
if
(
!
props
.
items
.
length
)
return
;
activeIndex
.
value
=
activeIndex
.
value
===
0
?
props
.
items
.
length
-
1
:
activeIndex
.
value
-
1
;
};
const
nextItem
=
()
=>
{
if
(
!
props
.
items
.
length
)
return
;
activeIndex
.
value
=
activeIndex
.
value
===
props
.
items
.
length
-
1
?
0
:
activeIndex
.
value
+
1
;
};
</
script
>
<
style
lang=
"scss"
scoped
>
.preview-dialog
{
height
:
572px
;
border-radius
:
10px
;
}
.preview-aside
{
flex
:
0
0
74px
;
background
:
#02091d
;
}
.nav-btn
{
&
:hover
{
background-color
:
#ffffff
13
;
border-radius
:
6px
;
}
}
.thumb-list
{
max-height
:
390px
;
overflow
:
hidden
;
}
.thumb-btn
{
border
:
2px
solid
transparent
!
important
;
opacity
:
.58
;
}
.thumb-btn.active
{
border-color
:
rgba
(
var
(
--
main-color
)
,
1
)
!
important
;
opacity
:
1
;
}
:deep
(
.thumb-btn
>
span
)
{
width
:
100%
;
height
:
100%
;
}
.preview-stage
{
background
:
#2f2f2f
;
}
.stage-cover
{
opacity
:
.32
;
filter
:
grayscale
(
.08
);
}
.stage-shade
{
background
:
rgba
(
0
,
0
,
0
,
.36
);
}
.video-badge
,
.source-tag
{
background
:
rgba
(
9
,
13
,
22
,
.76
);
}
.play-large
{
top
:
50%
;
left
:
50%
;
background
:
rgba
(
var
(
--
main-color
)
,
1
);
transform
:
translate
(
-50%
,
-50%
);
}
.fake-controls
{
z-index
:
1
;
}
.progress-line
{
background
:
rgba
(
255
,
255
,
255
,
.36
);
}
.preview-info
{
background
:
#fff
;
}
.heat
{
color
:
#ff8200
;
}
.avatar
{
background
:
linear-gradient
(
135deg
,
#1877ff
,
#9d19ff
);
}
.dot
{
background
:
#d4deeb
;
}
.type-tag
{
color
:
#526f91
;
background
:
#edf3fb
;
}
.prompt-box
{
background
:
#f8fbff
;
border
:
1px
solid
#e6edf5
;
}
.reference-img
{
border
:
1px
solid
#e6edf5
;
}
.tag-pill
{
background
:
#fbf0ff
;
border
:
1px
solid
#ead0ff
;
}
.dialog-footer
{
border-top
:
1px
solid
#edf2f7
;
}
.footer-icon
{
color
:
#526f91
;
border-color
:
#dfe7f2
;
}
.same-btn
{
background
:
rgba
(
var
(
--
main-color
)
,
1
);
border-color
:
rgba
(
var
(
--
main-color
)
,
1
);
}
.color-001
{
color
:
#001a3d
;
}
.color-334
{
color
:
#334b68
;
}
.color-789
{
color
:
#7890ae
;
}
</
style
>
apps/web-vue/src/views/quickCreation/components/ToolGroup.vue
0 → 100644
View file @
96e60a33
<
template
>
<section>
<div
class=
"fs-18 lh-28 fw-700 mb-16"
>
电商核心创意工具组
</div>
<div
class=
"tool-grid flex gap-16"
>
<div
v-for=
"item in tools"
:key=
"item.title"
class=
"core-card flex-col justify-between flex-1 minh-160 p-16 round-14 bg-fff text-left pointer"
:style=
"
{ '--accent': item.color, '--soft': item.bgColor }">
<div>
<span
class=
"core-icon flex-center wh-36 round-10 mb-12 fs-20"
>
<el-icon>
<component
:is=
"item.icon"
/>
</el-icon>
</span>
<div
class=
"lh-22 fw-700"
>
{{
item
.
title
}}
</div>
<p
class=
"fs-12 lh-20"
>
{{
item
.
desc
}}
</p>
</div>
<div
class=
"card-action flex-items-center gap-4 fs-12 fw-700"
>
{{
item
.
action
}}
<el-icon>
<ArrowRight
/>
</el-icon>
</div>
</div>
</div>
</section>
</
template
>
<
script
setup
lang=
"ts"
>
import
type
{
Component
}
from
'vue'
;
import
{
ArrowRight
,
Edit
,
Picture
,
Scissor
,
User
,
ZoomIn
}
from
'@element-plus/icons-vue'
;
type
ToolItem
=
{
title
:
string
;
desc
:
string
;
action
:
string
;
color
:
string
;
bgColor
:
string
;
icon
:
Component
;
};
const
tools
:
ToolItem
[]
=
[
{
title
:
'视频去水印'
,
desc
:
'智能擦除视频水印与遮挡元素'
,
action
:
'立即擦除'
,
color
:
'#ff1f82'
,
bgColor
:
'#fff0f7'
,
icon
:
Edit
,
},
{
title
:
'字幕擦除'
,
desc
:
'一键去除视频字幕与画面文字'
,
action
:
'立即清除'
,
color
:
'#1877ff'
,
bgColor
:
'#edf5ff'
,
icon
:
Scissor
,
},
{
title
:
'画质增强'
,
desc
:
'提升视频清晰度与画作多倍质感'
,
action
:
'立即增强'
,
color
:
'#ff9900'
,
bgColor
:
'#fff8e8'
,
icon
:
ZoomIn
,
},
{
title
:
'数字人分身'
,
desc
:
'高保真克隆音容姿态,输入文本即产出主播视频'
,
action
:
'极速制作'
,
color
:
'#f2187d'
,
bgColor
:
'#fff0f7'
,
icon
:
User
,
},
{
title
:
'模特换衣'
,
desc
:
'上传服装图搭配不同肤色AI模特和逼真场景'
,
action
:
'AI试穿'
,
color
:
'#1877ff'
,
bgColor
:
'#edf5ff'
,
icon
:
Picture
,
},
];
</
script
>
<
style
lang=
"scss"
scoped
>
.core-card
{
height
:
auto
;
white-space
:
normal
;
border
:
1px
solid
#e4ebf4
;
transition
:
border-color
.2s
,
box-shadow
.2s
,
transform
.2s
;
}
:deep
(
.core-card
>
span
)
{
display
:
flex
;
flex
:
1
;
flex-direction
:
column
;
align-items
:
stretch
;
justify-content
:
space-between
;
width
:
100%
;
height
:
100%
;
}
.core-card
p
,
.card-action
{
color
:
#86a0bd
;
}
.core-icon
{
color
:
var
(
--
accent
);
background
:
var
(
--
soft
);
}
.core-card
:hover
{
border-color
:
var
(
--
accent
);
box-shadow
:
0
10px
24px
rgba
(
22
,
37
,
67
,
.1
);
transform
:
translateY
(
-2px
);
}
.core-card
:hover
h3
,
.core-card
:hover
.card-action
{
color
:
var
(
--
accent
);
}
@media
(
max-width
:
1100px
)
{
.tool-grid
{
flex-wrap
:
wrap
;
}
.core-card
{
flex
:
0
0
calc
((
100%
-
16px
)
/
2
);
}
}
</
style
>
apps/web-vue/src/views/quickCreation/index.vue
0 → 100644
View file @
96e60a33
<
template
>
<div
class=
"quick-page h-full over-y-auto py-40"
>
<div
class=
"card-box"
>
<header
class=
"quick-header"
>
<div
class=
"premium-chip items-center gap-6 h-26 px-12 round-14 fs-12 fw-700"
>
<el-icon>
<StarFilled
/>
</el-icon>
<span>
PREMIUM PLATFORM
</span>
</div>
<h1
class=
"mt-8 fs-24 lh-44 fw-700"
>
<span>
梦畅AIGC,
</span>
<span
class=
"gradient-title"
>
为电商而生的 AIGC 平台
</span>
</h1>
</header>
<CreativeComposer
class=
"mt-30"
:active-scene=
"activeScene"
@
select-scene=
"activeScene = $event"
@
clear-scene=
"activeScene = undefined"
/>
</div>
<div
class=
"content"
>
<ToolGroup
class=
"mt-86"
/>
<InspirationGallery
class=
"mt-36"
/>
</div>
</div>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
ref
}
from
'vue'
;
import
{
StarFilled
}
from
'@element-plus/icons-vue'
;
import
CreativeComposer
from
'./components/CreativeComposer.vue'
;
import
ToolGroup
from
'./components/ToolGroup.vue'
;
import
InspirationGallery
from
'./components/InspirationGallery.vue'
;
import
type
{
SceneKey
}
from
'./types'
;
const
activeScene
=
ref
<
SceneKey
>
();
</
script
>
<
style
scoped
lang=
"scss"
>
.card-box
{
width
:
1400px
;
margin
:
auto
;
}
.content
{
width
:
1600px
;
margin
:
auto
;
}
.quick-page
{
background
:
#f6f9fc
;
}
.quick-header
h1
{
color
:
#001a3d
;
letter-spacing
:
0
;
}
.premium-chip
{
display
:
inline-flex
;
color
:
rgba
(
var
(
--
main-color
)
,
1
);
background
:
#fbf1ff
;
border
:
1px
solid
#efd6ff
;
letter-spacing
:
1
.4px
;
}
.gradient-title
{
background
:
linear-gradient
(
90deg
,
#9d19ff
0%
,
#e01892
48%
,
#ff8a00
100%
);
background-clip
:
text
;
-webkit-background-clip
:
text
;
color
:
transparent
;
}
</
style
>
apps/web-vue/src/views/quickCreation/types.ts
0 → 100644
View file @
96e60a33
export
type
SceneKey
=
'product'
|
'pain'
|
'process'
|
'koc'
|
'story'
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment