Commit c8d58c47 authored by yaoke.yk's avatar yaoke.yk

微信小程序demo

parent 24b905e2
<template>
<view class="timeline">
<view v-for="(step, index) in normalizedSteps" :key="step.key" class="timeline__item">
<view class="timeline__rail">
<view class="timeline__mark" :class="`timeline__mark--${String(step.status).toLowerCase()}`">
<text>{{ index + 1 }}</text>
</view>
<view v-if="index < normalizedSteps.length - 1" class="timeline__line" />
</view>
<view class="timeline__content">
<view class="timeline__head">
<text class="timeline__name">{{ step.name }}</text>
......@@ -71,26 +74,38 @@ function stepHint(status?: AgentRunStatus) {
.timeline__item {
display: flex;
gap: 18rpx;
padding: 18rpx 0;
}
.timeline__rail {
display: flex;
flex-direction: column;
align-items: center;
flex-shrink: 0;
}
.timeline__mark {
width: 48rpx;
height: 48rpx;
width: 52rpx;
height: 52rpx;
border-radius: 50%;
background: #eef2ff;
background: #eef4ff;
color: #5b5cf6;
font-size: 22rpx;
font-weight: 800;
font-weight: 860;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.timeline__line {
width: 2rpx;
min-height: 62rpx;
flex: 1;
background: #e7ebf3;
}
.timeline__mark--running {
background: #d8faf3;
color: #0f766e;
background: #e0f2fe;
color: #075985;
}
.timeline__mark--done,
......@@ -107,8 +122,7 @@ function stepHint(status?: AgentRunStatus) {
.timeline__content {
flex: 1;
min-width: 0;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #eef1f6;
padding-bottom: 28rpx;
}
.timeline__head {
......@@ -119,14 +133,15 @@ function stepHint(status?: AgentRunStatus) {
}
.timeline__name {
color: #182230;
color: #101828;
font-size: 28rpx;
font-weight: 750;
font-weight: 800;
}
.timeline__status {
color: #667085;
font-size: 23rpx;
white-space: nowrap;
}
.timeline__output {
......@@ -134,6 +149,6 @@ function stepHint(status?: AgentRunStatus) {
margin-top: 10rpx;
color: #475467;
font-size: 24rpx;
line-height: 1.5;
line-height: 1.55;
}
</style>
......@@ -9,7 +9,10 @@
<text class="status-pill" :class="statusClass(project.status)">{{ statusText(project.status) }}</text>
</view>
<text class="project-card__desc">{{ project.description || "等待 Agent 制作内容" }}</text>
<text class="project-card__time">{{ formatDateTime(project.updatedAt || project.createdAt) }}</text>
<view class="project-card__meta">
<text>{{ project.type || "AI 短剧" }}</text>
<text>{{ formatDateTime(project.updatedAt || project.createdAt) }}</text>
</view>
</view>
</view>
</template>
......@@ -40,18 +43,21 @@ const indexLabel = computed(() => String((props.index || 0) + 1).padStart(2, "0"
}
.project-card__cover {
width: 112rpx;
height: 112rpx;
border-radius: 14rpx;
background: linear-gradient(145deg, #20283a, #5b5cf6);
width: 118rpx;
height: 118rpx;
border-radius: 20rpx;
background:
linear-gradient(155deg, rgba(91, 92, 246, 0.95), rgba(30, 167, 255, 0.82)),
#101828;
color: #ffffff;
font-size: 28rpx;
font-weight: 800;
font-size: 27rpx;
font-weight: 860;
display: flex;
align-items: flex-end;
justify-content: flex-start;
padding: 16rpx;
flex-shrink: 0;
box-shadow: inset 0 0 0 1rpx rgba(255, 255, 255, 0.16);
}
.project-card__body {
......@@ -69,9 +75,9 @@ const indexLabel = computed(() => String((props.index || 0) + 1).padStart(2, "0"
.project-card__title {
min-width: 0;
flex: 1;
color: #141923;
font-size: 29rpx;
font-weight: 750;
color: #101828;
font-size: 30rpx;
font-weight: 820;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
......@@ -82,14 +88,17 @@ const indexLabel = computed(() => String((props.index || 0) + 1).padStart(2, "0"
margin-top: 12rpx;
color: #667085;
font-size: 25rpx;
line-height: 1.45;
line-height: 1.5;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.project-card__time {
display: block;
.project-card__meta {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16rpx;
margin-top: 14rpx;
color: #98a2b3;
font-size: 22rpx;
......
......@@ -3,8 +3,9 @@
<view class="upload__icon">+</view>
<view class="upload__body">
<text class="upload__title">{{ fileName || "上传剧本文件" }}</text>
<text class="upload__desc">支持 doc、docx、txt、pdf、md,上传后可直接启动 Agent</text>
<text class="upload__desc">支持 doc、docx、txt、pdf、md,上传后可直接启动 Agent</text>
</view>
<text class="upload__action">选择</text>
</view>
</template>
......@@ -61,13 +62,13 @@ function pickFile() {
}
.upload__icon {
width: 74rpx;
height: 74rpx;
border-radius: 18rpx;
background: #eef2ff;
width: 76rpx;
height: 76rpx;
border-radius: 22rpx;
background: #eef4ff;
color: #5b5cf6;
font-size: 42rpx;
font-weight: 500;
font-weight: 560;
display: flex;
align-items: center;
justify-content: center;
......@@ -81,9 +82,9 @@ function pickFile() {
.upload__title {
display: block;
color: #141923;
color: #101828;
font-size: 29rpx;
font-weight: 750;
font-weight: 800;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
......@@ -96,4 +97,10 @@ function pickFile() {
font-size: 24rpx;
line-height: 1.45;
}
.upload__action {
color: #5b5cf6;
font-size: 25rpx;
font-weight: 760;
}
</style>
......@@ -2,8 +2,9 @@
<view class="preview panel">
<video v-if="src" class="preview__video" :src="src" controls object-fit="contain" />
<view v-else class="preview__empty">
<text class="preview__title">视频生成完成后会出现在这里</text>
<text class="preview__desc">当前小程序先承接创建和进度查看,成片地址接入后可直接预览。</text>
<view class="preview__badge">AI VIDEO</view>
<text class="preview__title">成片完成后会出现在这里</text>
<text class="preview__desc">极速出片会自动等待视频任务和分集合成;PC 精修模式可回到网页端继续制作。</text>
</view>
</view>
</template>
......@@ -23,7 +24,7 @@ defineProps<{
.preview__video,
.preview__empty {
width: 100%;
height: 720rpx;
height: 700rpx;
}
.preview__empty {
......@@ -32,22 +33,33 @@ defineProps<{
flex-direction: column;
justify-content: flex-end;
background:
linear-gradient(180deg, rgba(16, 21, 34, 0.2), rgba(16, 21, 34, 0.96)),
radial-gradient(circle at 20% 16%, rgba(91, 92, 246, 0.44), transparent 36%),
linear-gradient(180deg, rgba(16, 21, 34, 0.18), rgba(16, 21, 34, 0.96)),
linear-gradient(135deg, rgba(91, 92, 246, 0.5), rgba(30, 167, 255, 0.18)),
#101522;
}
.preview__badge {
width: fit-content;
margin-bottom: 20rpx;
padding: 8rpx 14rpx;
border-radius: 999rpx;
color: #bfdbfe;
background: rgba(255, 255, 255, 0.12);
font-size: 20rpx;
font-weight: 760;
}
.preview__title {
color: #ffffff;
font-size: 32rpx;
font-weight: 800;
font-weight: 840;
}
.preview__desc {
display: block;
margin-top: 14rpx;
color: rgba(255, 255, 255, 0.72);
color: rgba(255, 255, 255, 0.74);
font-size: 25rpx;
line-height: 1.55;
line-height: 1.58;
}
</style>
......@@ -4,49 +4,62 @@
"path": "pages/home/index",
"style": {
"navigationBarTitleText": "瑶光 AI 短剧",
"navigationBarBackgroundColor": "#f7f8fc",
"navigationBarTextStyle": "black"
"navigationBarBackgroundColor": "#0b1020",
"navigationBarTextStyle": "white"
}
},
{
"path": "pages/create/index",
"style": {
"navigationBarTitleText": "创建视频任务"
"navigationBarTitleText": "创建视频任务",
"navigationBarBackgroundColor": "#0b1020",
"navigationBarTextStyle": "white"
}
},
{
"path": "pages/projects/index",
"style": {
"navigationBarTitleText": "项目"
"navigationBarTitleText": "项目",
"navigationBarBackgroundColor": "#0b1020",
"navigationBarTextStyle": "white"
}
},
{
"path": "pages/project-progress/index",
"style": {
"navigationBarTitleText": "Agent 制作"
"navigationBarTitleText": "Agent 制作",
"navigationBarBackgroundColor": "#0b1020",
"navigationBarTextStyle": "white",
"enablePullDownRefresh": true
}
},
{
"path": "pages/result/index",
"style": {
"navigationBarTitleText": "视频结果"
"navigationBarTitleText": "视频结果",
"navigationBarBackgroundColor": "#0b1020",
"navigationBarTextStyle": "white"
}
},
{
"path": "pages/mine/index",
"style": {
"navigationBarTitleText": "我的"
"navigationBarTitleText": "我的",
"navigationBarBackgroundColor": "#0b1020",
"navigationBarTextStyle": "white"
}
},
{
"path": "pages/login/index",
"style": {
"navigationBarTitleText": "登录"
"navigationBarTitleText": "登录",
"navigationBarBackgroundColor": "#0b1020",
"navigationBarTextStyle": "white"
}
}
],
"tabBar": {
"color": "#667085",
"color": "#8a94a6",
"selectedColor": "#5b5cf6",
"backgroundColor": "#ffffff",
"borderStyle": "white",
......@@ -66,9 +79,9 @@
]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "瑶光 AI 短剧",
"navigationBarBackgroundColor": "#f7f8fc",
"backgroundColor": "#f7f8fc"
"navigationBarBackgroundColor": "#0b1020",
"backgroundColor": "#0b1020"
}
}
......@@ -3,7 +3,7 @@
<text class="page-title">创建视频任务</text>
<text class="page-subtitle">选择制作模式后上传剧本,Agent 会按不同链路推进。</text>
<view class="mode-switch panel">
<view class="mode-switch">
<button
v-for="mode in RUN_MODES"
:key="mode.value"
......@@ -20,7 +20,7 @@
<text class="mode-card__desc">{{ selectedMode.description }}</text>
</view>
<view class="form">
<view class="form panel">
<view>
<text class="field-label">项目名称</text>
<input v-model="projectName" class="field-input" placeholder="例如:都市逆袭第 1 集" />
......@@ -34,19 +34,19 @@
</view>
<view class="option-grid">
<view class="option panel">
<view class="option">
<text class="option__label">风格</text>
<picker :range="styleLabels" :value="styleIndex" @change="styleIndex = Number($event.detail.value)">
<text class="option__value">{{ styleLabels[styleIndex] }}</text>
</picker>
</view>
<view class="option panel">
<view class="option">
<text class="option__label">画幅</text>
<picker :range="ASPECT_RATIOS" :value="ratioIndex" @change="ratioIndex = Number($event.detail.value)">
<text class="option__value">{{ ASPECT_RATIOS[ratioIndex] }}</text>
</picker>
</view>
<view class="option panel">
<view class="option">
<text class="option__label">清晰度</text>
<picker :range="RESOLUTIONS" :value="resolutionIndex" @change="resolutionIndex = Number($event.detail.value)">
<text class="option__value">{{ RESOLUTIONS[resolutionIndex] }}</text>
......@@ -160,19 +160,19 @@ async function submit() {
.mode-switch {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8rpx;
margin-top: 30rpx;
gap: 10rpx;
margin-top: 34rpx;
padding: 8rpx;
background: #eef1f7;
box-shadow: none;
border-radius: 22rpx;
background: rgba(255, 255, 255, 0.12);
}
.mode-switch__item {
height: 76rpx;
border-radius: 12rpx;
color: #667085;
min-height: 80rpx;
border-radius: 16rpx;
color: rgba(255, 255, 255, 0.72);
font-size: 27rpx;
font-weight: 760;
font-weight: 800;
display: flex;
align-items: center;
justify-content: center;
......@@ -180,20 +180,20 @@ async function submit() {
.mode-switch__item--active {
background: #ffffff;
color: #111827;
box-shadow: 0 10rpx 24rpx rgba(17, 24, 39, 0.08);
color: #101828;
box-shadow: 0 14rpx 30rpx rgba(0, 0, 0, 0.16);
}
.mode-card {
margin-top: 18rpx;
padding: 26rpx;
padding: 28rpx;
}
.mode-card__title {
display: block;
color: #141923;
font-size: 30rpx;
font-weight: 820;
color: #101828;
font-size: 31rpx;
font-weight: 860;
}
.mode-card__desc {
......@@ -201,37 +201,41 @@ async function submit() {
margin-top: 10rpx;
color: #667085;
font-size: 25rpx;
line-height: 1.55;
line-height: 1.58;
}
.form {
display: flex;
flex-direction: column;
gap: 28rpx;
margin-top: 28rpx;
gap: 30rpx;
margin-top: 24rpx;
padding: 28rpx;
}
.option-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16rpx;
gap: 14rpx;
}
.option {
padding: 22rpx;
min-height: 118rpx;
padding: 20rpx;
border-radius: 18rpx;
background: #f6f8fc;
}
.option__label {
display: block;
color: #667085;
font-size: 23rpx;
font-size: 22rpx;
}
.option__value {
display: block;
margin-top: 14rpx;
color: #141923;
font-size: 28rpx;
font-weight: 760;
color: #101828;
font-size: 27rpx;
font-weight: 820;
}
</style>
......@@ -3,13 +3,18 @@
<view class="home-head">
<view>
<text class="page-title">今天生成哪条短剧?</text>
<text class="page-subtitle">手机端可以快速出片,也可以先让 Agent 制作素材后回 PC 精修。</text>
<text class="page-subtitle">极速出片拿样片,或先让 Agent 制作素材后回 PC 精修。</text>
</view>
<button class="home-head__mine" @tap="goMine">我的</button>
</view>
<view class="quick panel">
<textarea v-model="idea" class="quick__textarea" placeholder="例如:把这个都市逆袭剧本做成 9:16 真人短剧,节奏紧凑,先生成前 10 个分镜。" />
<view class="quick__badge">AI VIDEO AGENT</view>
<textarea
v-model="idea"
class="quick__textarea"
placeholder="例如:把这个都市逆袭剧本做成 9:16 真人短剧,节奏紧凑,先生成前 10 个分镜。"
/>
<view class="quick__actions">
<button class="primary-button quick__primary" @tap="startQuickVideo">极速出片</button>
<button class="secondary-button quick__secondary" @tap="goCreate">上传剧本</button>
......@@ -17,13 +22,29 @@
<button class="ghost-button quick__refine" @tap="goCreateForRefine">Agent 制作后去 PC 精修</button>
</view>
<view class="section-head">
<text>最近项目</text>
<button @tap="goProjects">全部</button>
<view class="home-metrics">
<view class="home-metric">
<text>2</text>
<text>制作模式</text>
</view>
<view class="home-metric">
<text>6</text>
<text>自动步骤</text>
</view>
<view class="home-metric">
<text>9:16</text>
<text>默认短剧</text>
</view>
</view>
<view class="section-head home-section">
<text class="section-head__title">最近项目</text>
<button class="section-head__action" @tap="goProjects">全部</button>
</view>
<view v-if="loading" class="empty panel">
<text>正在读取项目...</text>
<text class="empty__title">正在读取项目</text>
<text class="empty__desc">项目列表马上就绪。</text>
</view>
<view v-else-if="projects.length" class="project-list">
<ProjectCard v-for="(project, index) in projects" :key="project.id" :project="project" :index="index" @open="openProject(project.id)" />
......@@ -147,33 +168,44 @@ function goMine() {
}
.home-head__mine {
width: 104rpx;
height: 62rpx;
min-width: 104rpx;
height: 64rpx;
padding: 0 22rpx;
border-radius: 999rpx;
background: #ffffff;
color: #475467;
background: rgba(255, 255, 255, 0.14);
color: #ffffff;
font-size: 24rpx;
font-weight: 700;
box-shadow: 0 10rpx 28rpx rgba(17, 24, 39, 0.06);
font-weight: 760;
}
.quick {
margin-top: 32rpx;
padding: 26rpx;
margin-top: 34rpx;
padding: 28rpx;
}
.quick__badge {
width: fit-content;
margin-bottom: 20rpx;
padding: 8rpx 14rpx;
border-radius: 999rpx;
color: #075985;
background: #e0f2fe;
font-size: 20rpx;
font-weight: 800;
}
.quick__textarea {
width: 100%;
min-height: 210rpx;
color: #182230;
min-height: 220rpx;
color: #101828;
font-size: 29rpx;
line-height: 1.55;
line-height: 1.58;
}
.quick__actions {
display: flex;
gap: 18rpx;
margin-top: 22rpx;
margin-top: 24rpx;
}
.quick__primary {
......@@ -188,48 +220,43 @@ function goMine() {
margin-top: 8rpx;
}
.section-head {
margin-top: 38rpx;
margin-bottom: 18rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.section-head text {
color: #141923;
font-size: 31rpx;
font-weight: 800;
.home-metrics {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 14rpx;
margin-top: 22rpx;
}
.section-head button {
color: #5b5cf6;
font-size: 25rpx;
font-weight: 700;
.home-metric {
padding: 22rpx 12rpx;
border-radius: 20rpx;
background: #ffffff;
text-align: center;
box-shadow: 0 12rpx 30rpx rgba(16, 24, 40, 0.05);
}
.project-list {
display: flex;
flex-direction: column;
gap: 18rpx;
.home-metric text:first-child {
display: block;
color: #101828;
font-size: 30rpx;
font-weight: 860;
}
.empty {
padding: 38rpx;
.home-metric text:last-child {
display: block;
margin-top: 6rpx;
color: #667085;
font-size: 22rpx;
}
.empty__title {
display: block;
color: #182230;
font-size: 29rpx;
font-weight: 760;
.home-section {
margin-top: 40rpx;
margin-bottom: 18rpx;
}
.empty__desc {
display: block;
margin-top: 10rpx;
color: #667085;
font-size: 25rpx;
line-height: 1.5;
.project-list {
display: flex;
flex-direction: column;
gap: 18rpx;
}
</style>
<template>
<view class="page login-page">
<view class="login-brand">
<text class="login-brand__mark">AI</text>
<view class="login-hero">
<view class="login-hero__mark">AI</view>
<text class="page-title">瑶光 AI 短剧</text>
<text class="page-subtitle">登录后即可在手机上上传剧本、启动 Agent、查看制作进度。</text>
<text class="page-subtitle">在手机上上传剧本、启动 Agent、查看制作进度。</text>
</view>
<view class="login-form panel">
<text class="login-form__title">登录工作台</text>
<text class="login-form__desc">继续你的短剧项目</text>
<text class="field-label">账号</text>
<input
:value="email"
......@@ -87,26 +90,46 @@ async function handleLogin() {
<style scoped lang="scss">
.login-page {
padding-top: 96rpx;
padding-top: 84rpx;
}
.login-hero {
padding-bottom: 18rpx;
}
.login-brand__mark {
width: 92rpx;
height: 92rpx;
.login-hero__mark {
width: 96rpx;
height: 96rpx;
margin-bottom: 28rpx;
border-radius: 24rpx;
background: #141923;
border-radius: 28rpx;
background: linear-gradient(135deg, #5b5cf6, #1ea7ff);
color: #ffffff;
font-size: 30rpx;
font-weight: 900;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 18rpx 42rpx rgba(30, 167, 255, 0.24);
}
.login-form {
margin-top: 56rpx;
padding: 30rpx;
margin-top: 42rpx;
padding: 32rpx;
}
.login-form__title {
display: block;
color: #101828;
font-size: 34rpx;
font-weight: 860;
}
.login-form__desc {
display: block;
margin-top: 8rpx;
margin-bottom: 30rpx;
color: #667085;
font-size: 25rpx;
}
.login-form__label {
......
......@@ -52,13 +52,14 @@ function goLogin() {
align-items: center;
gap: 22rpx;
padding: 30rpx;
margin-top: 10rpx;
}
.profile__avatar {
width: 104rpx;
height: 104rpx;
border-radius: 28rpx;
background: #141923;
width: 108rpx;
height: 108rpx;
border-radius: 30rpx;
background: linear-gradient(135deg, #5b5cf6, #1ea7ff);
color: #ffffff;
font-size: 28rpx;
font-weight: 900;
......@@ -67,11 +68,16 @@ function goLogin() {
justify-content: center;
}
.profile__body {
min-width: 0;
flex: 1;
}
.profile__name {
display: block;
color: #141923;
color: #101828;
font-size: 32rpx;
font-weight: 820;
font-weight: 860;
}
.profile__email {
......@@ -79,6 +85,9 @@ function goLogin() {
margin-top: 8rpx;
color: #667085;
font-size: 25rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.setting {
......@@ -101,8 +110,11 @@ function goLogin() {
}
.setting__row text:last-child {
color: #182230;
min-width: 0;
flex: 1;
color: #101828;
text-align: right;
word-break: break-all;
}
.logout {
......
......@@ -2,13 +2,19 @@
<view class="page progress-page">
<view class="progress-head panel">
<view class="progress-head__top">
<view>
<view class="progress-head__main">
<text class="progress-head__label">{{ modeTitle }}</text>
<text class="progress-head__title">{{ project?.name || project?.title || "视频项目" }}</text>
</view>
<text class="status-pill" :class="statusClass(run?.status)">{{ statusText(run?.status) }}</text>
</view>
<progress class="progress-head__bar" :percent="percent" activeColor="#5b5cf6" backgroundColor="#e8ecf5" stroke-width="8" />
<view class="progress-head__track">
<view class="progress-head__fill" :style="{ width: `${percent}%` }" />
</view>
<view class="progress-head__percent">
<text>制作进度</text>
<text>{{ percent }}%</text>
</view>
<text class="progress-head__goal">{{ run?.goal || project?.description || "等待 Agent 返回任务目标" }}</text>
</view>
......@@ -115,32 +121,57 @@ function goResult() {
<style scoped lang="scss">
.progress-head {
padding: 28rpx;
padding: 30rpx;
}
.progress-head__top {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 20rpx;
}
.progress-head__main {
min-width: 0;
flex: 1;
}
.progress-head__label {
display: block;
color: #5b5cf6;
font-size: 24rpx;
font-weight: 800;
font-weight: 820;
}
.progress-head__title {
display: block;
margin-top: 8rpx;
color: #141923;
color: #101828;
font-size: 34rpx;
font-weight: 820;
font-weight: 860;
line-height: 1.3;
}
.progress-head__track {
height: 16rpx;
margin-top: 30rpx;
overflow: hidden;
border-radius: 999rpx;
background: #e8ecf5;
}
.progress-head__bar {
margin-top: 28rpx;
.progress-head__fill {
height: 100%;
border-radius: 999rpx;
background: linear-gradient(90deg, #5b5cf6, #1ea7ff);
}
.progress-head__percent {
display: flex;
justify-content: space-between;
margin-top: 14rpx;
color: #667085;
font-size: 24rpx;
}
.progress-head__goal {
......@@ -148,17 +179,17 @@ function goResult() {
margin-top: 20rpx;
color: #667085;
font-size: 25rpx;
line-height: 1.55;
line-height: 1.58;
}
.timeline-panel {
margin-top: 22rpx;
padding: 10rpx 28rpx;
padding: 20rpx 28rpx;
}
.actions {
display: grid;
grid-template-columns: 1fr 1.5fr;
grid-template-columns: 1fr 1.45fr;
gap: 18rpx;
margin-top: 26rpx;
padding-bottom: 40rpx;
......@@ -167,8 +198,4 @@ function goResult() {
.actions .primary-button:only-child {
grid-column: 1 / -1;
}
.disabled {
opacity: 0.58;
}
</style>
......@@ -8,13 +8,14 @@
<button class="projects-head__add" @tap="goCreate">+</button>
</view>
<view v-if="loading" class="empty panel">
<text>正在加载...</text>
<view v-if="loading" class="empty panel projects-empty">
<text class="empty__title">正在加载</text>
<text class="empty__desc">项目列表马上就绪。</text>
</view>
<view v-else-if="projects.length" class="project-list">
<ProjectCard v-for="(project, index) in projects" :key="project.id" :project="project" :index="index" @open="openProject(project.id)" />
</view>
<view v-else class="empty panel">
<view v-else class="empty panel projects-empty">
<text class="empty__title">暂无项目</text>
<text class="empty__desc">创建第一个视频任务后,进度和结果会自动出现在这里。</text>
<button class="primary-button empty__button" @tap="goCreate">创建任务</button>
......@@ -71,12 +72,12 @@ function goCreate() {
}
.projects-head__add {
width: 76rpx;
height: 76rpx;
border-radius: 22rpx;
background: #141923;
width: 80rpx;
height: 80rpx;
border-radius: 24rpx;
background: rgba(255, 255, 255, 0.14);
color: #ffffff;
font-size: 40rpx;
font-size: 42rpx;
display: flex;
align-items: center;
justify-content: center;
......@@ -86,27 +87,11 @@ function goCreate() {
display: flex;
flex-direction: column;
gap: 18rpx;
margin-top: 32rpx;
margin-top: 34rpx;
}
.empty {
margin-top: 32rpx;
padding: 38rpx;
}
.empty__title {
display: block;
color: #182230;
font-size: 30rpx;
font-weight: 780;
}
.empty__desc {
display: block;
margin-top: 10rpx;
color: #667085;
font-size: 25rpx;
line-height: 1.5;
.projects-empty {
margin-top: 34rpx;
}
.empty__button {
......
......@@ -23,7 +23,7 @@
<text>合成状态</text>
<text>{{ assemblyStatus }}</text>
</view>
<view class="result-info__row">
<view class="result-info__row result-info__row--goal">
<text>制作目标</text>
<text>{{ run?.goal || project?.description || "暂无" }}</text>
</view>
......@@ -103,39 +103,43 @@ function backToProgress() {
<style scoped lang="scss">
.result-preview {
margin-top: 28rpx;
margin-top: 34rpx;
}
.result-info {
margin-top: 24rpx;
padding: 28rpx;
padding: 30rpx;
}
.result-info__title {
display: block;
margin-bottom: 16rpx;
color: #141923;
font-size: 30rpx;
font-weight: 800;
color: #101828;
font-size: 31rpx;
font-weight: 840;
}
.result-info__row {
display: flex;
justify-content: space-between;
gap: 28rpx;
padding: 18rpx 0;
padding: 20rpx 0;
border-top: 1rpx solid #eef1f6;
color: #475467;
font-size: 25rpx;
line-height: 1.45;
line-height: 1.5;
}
.result-info__row text:last-child {
flex: 1;
color: #182230;
color: #101828;
text-align: right;
}
.result-info__row--goal {
align-items: flex-start;
}
.result-back {
margin-top: 26rpx;
}
......
page {
min-height: 100%;
background: #f7f8fc;
color: #141923;
background: #0b1020;
color: #101828;
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
}
/* #ifdef H5 */
body {
margin: 0;
background: #edf1f7;
background: #070b16;
}
#app {
min-height: 100vh;
max-width: 430px;
margin: 0 auto;
background: #f7f8fc;
box-shadow: 0 0 60rpx rgba(17, 24, 39, 0.08);
background: #0b1020;
box-shadow: 0 0 80rpx rgba(0, 0, 0, 0.32);
}
/* #endif */
......@@ -44,121 +44,174 @@ button::after {
.page {
min-height: 100vh;
padding: 28rpx;
background:
linear-gradient(180deg, #0b1020 0%, #111a2e 430rpx, #f5f7fb 431rpx, #f5f7fb 100%);
}
.page-title {
display: block;
font-size: 42rpx;
font-weight: 800;
color: #111827;
color: #ffffff;
font-size: 44rpx;
font-weight: 860;
line-height: 1.18;
letter-spacing: 0;
}
.page-subtitle {
display: block;
margin-top: 10rpx;
margin-top: 14rpx;
color: rgba(255, 255, 255, 0.72);
font-size: 26rpx;
line-height: 1.6;
color: #667085;
line-height: 1.65;
}
.panel {
border: 1rpx solid #e7eaf3;
border-radius: 16rpx;
border: 1rpx solid rgba(217, 224, 239, 0.94);
border-radius: 24rpx;
background: #ffffff;
box-shadow: 0 16rpx 40rpx rgba(17, 24, 39, 0.05);
box-shadow: 0 18rpx 46rpx rgba(16, 24, 40, 0.08);
}
.primary-button {
height: 92rpx;
border-radius: 16rpx;
background: #5b5cf6;
color: #ffffff;
font-size: 30rpx;
font-weight: 700;
.glass-panel {
border: 1rpx solid rgba(255, 255, 255, 0.18);
border-radius: 28rpx;
background: rgba(255, 255, 255, 0.11);
}
.primary-button,
.secondary-button,
.ghost-button {
min-height: 88rpx;
border-radius: 18rpx;
font-size: 29rpx;
font-weight: 760;
display: flex;
align-items: center;
justify-content: center;
transition: opacity 0.18s ease, transform 0.18s ease;
}
.primary-button {
background: linear-gradient(135deg, #5b5cf6, #1ea7ff);
color: #ffffff;
box-shadow: 0 16rpx 36rpx rgba(79, 70, 229, 0.26);
}
.secondary-button {
height: 84rpx;
border: 1rpx solid #d9deea;
border-radius: 16rpx;
color: #252b37;
background: #ffffff;
font-size: 28rpx;
font-weight: 650;
display: flex;
align-items: center;
justify-content: center;
}
.ghost-button {
height: 76rpx;
color: #5b5cf6;
font-size: 27rpx;
font-weight: 650;
display: flex;
align-items: center;
justify-content: center;
}
.primary-button[disabled],
.secondary-button[disabled],
.ghost-button[disabled],
.disabled {
opacity: 0.56;
}
.field-label {
display: block;
margin-bottom: 14rpx;
color: #303846;
color: #344054;
font-size: 26rpx;
font-weight: 700;
font-weight: 760;
}
.field-input,
.field-textarea {
width: 100%;
border: 1rpx solid #dfe4ef;
border-radius: 14rpx;
border: 1rpx solid #d9deea;
border-radius: 18rpx;
background: #ffffff;
color: #141923;
font-size: 28rpx;
color: #101828;
font-size: 29rpx;
}
.field-input {
height: 88rpx;
min-height: 88rpx;
padding: 0 24rpx;
height: 92rpx;
min-height: 92rpx;
padding: 0 26rpx;
display: block;
position: relative;
z-index: 1;
line-height: 88rpx;
line-height: 92rpx;
}
.field-textarea {
min-height: 190rpx;
padding: 22rpx 24rpx;
line-height: 1.55;
min-height: 210rpx;
padding: 24rpx 26rpx;
line-height: 1.58;
}
.muted {
color: #667085;
}
.section-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 20rpx;
}
.section-head__title {
color: #141923;
font-size: 32rpx;
font-weight: 820;
}
.section-head__action {
min-height: 64rpx;
padding: 0 20rpx;
border-radius: 999rpx;
color: #5b5cf6;
font-size: 25rpx;
font-weight: 760;
}
.empty {
padding: 42rpx;
}
.empty__title {
display: block;
color: #182230;
font-size: 31rpx;
font-weight: 820;
}
.empty__desc {
display: block;
margin-top: 12rpx;
color: #667085;
font-size: 25rpx;
line-height: 1.56;
}
.status-pill {
height: 42rpx;
min-height: 44rpx;
padding: 0 16rpx;
border-radius: 999rpx;
font-size: 22rpx;
font-weight: 700;
font-weight: 760;
display: inline-flex;
align-items: center;
justify-content: center;
white-space: nowrap;
}
.status-running {
color: #115e59;
background: #d8faf3;
color: #075985;
background: #e0f2fe;
}
.status-done {
color: #245b1e;
color: #166534;
background: #dcfce7;
}
......@@ -169,6 +222,6 @@ button::after {
.status-paused,
.status-pending {
color: #5b3b00;
color: #8a4b00;
background: #fff3c4;
}
......@@ -9,7 +9,7 @@ export const PROJECT_STYLES = [
{ label: "真人短剧", value: "live_action_drama" },
{ label: "国漫风", value: "guoman" },
{ label: "写实电影感", value: "cinematic_realism" },
{ label: "3D动画", value: "three_d_animation" }
{ label: "3D 动画", value: "three_d_animation" }
];
export const ASPECT_RATIOS = ["9:16", "16:9", "1:1"];
......@@ -47,7 +47,7 @@ export const RUN_MODES: Array<{
value: "pc_refine",
label: "PC 精修",
title: "Agent 制作,PC 精修",
description: "生成剧本理解、角色和分镜,完成后回到 PC 工作台继续改图、改分镜、生成视频。",
description: "生成剧本理解、角色和分镜,完成后回到 PC 工作台继续改图、改分镜、生成视频。",
runIntent: "auto",
selectedSteps: PC_REFINE_AGENT_STEPS,
actionLabel: "创建 Agent 制作任务"
......@@ -55,8 +55,8 @@ export const RUN_MODES: Array<{
{
value: "quick_video",
label: "极速出片",
title: "一键自动出片",
description: "让 Agent 尝试自动跑完图片、视频和合成,适合先快速拿到一版样片。",
title: "一键自动出片",
description: "让 Agent 自动跑完图片、视频和合成流程,适合先快速拿到一版样片。",
runIntent: "quick_video",
selectedSteps: QUICK_VIDEO_AGENT_STEPS,
actionLabel: "开始极速出片"
......
......@@ -27,6 +27,8 @@ export function statusText(status?: AgentRunStatus) {
return "草稿";
case "CREATED":
return "已创建";
case "SKIPPED":
return "已跳过";
default:
return status || "未开始";
}
......@@ -39,6 +41,7 @@ export function statusClass(status?: AgentRunStatus) {
case "RUNNING":
return "status-running";
case "DONE":
case "SKIPPED":
return "status-done";
case "FAILED":
return "status-failed";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment