+
+
+
+
+ 开发模式
+
+
+
+
+
- 📤
+
正在上传...
- 🖼️
- 上传孩子的画作
- 支持拍照或从相册选择
AI会自动识别画中的角色
+
+ 上传你的画作
+ 支持拍照或从相册选择
AI 会自动识别画中的角色
@@ -39,44 +51,41 @@
-
+
-
- 🎨
- ✏️
- 🖌️
-
-
{{ uploadProgress || 'AI 小画家正在认识你的角色...' }}
+
+
{{ uploadProgress || 'AI 正在识别你的角色...' }}
-
+
-
✨ AI 正在为你做这些事
+
AI 正在为你做这些事
- 📤
+
上传画作到云端
- ✓
+
- 👀
+
AI 识别画中角色
- ✓
+
- 🎭
+
提取角色特征
- 💡
- 你知道吗?AI 画师可以识别超过 100 种不同的卡通角色哦!
+
+ 小知识:AI 画师可以识别超过 100 种不同的卡通角色
@@ -84,8 +93,15 @@
{{ uploadError }}
-
@@ -99,6 +115,27 @@ import { useRouter } from 'vue-router'
import PageHeader from '@/components/aicreate/PageHeader.vue'
import { useAicreateStore } from '@/stores/aicreate'
import { extractCharacters, ossUpload, checkQuota } from '@/api/aicreate'
+import {
+ PictureOutlined,
+ CameraOutlined,
+ FolderOpenOutlined,
+ CloudUploadOutlined,
+ LoadingOutlined,
+ CheckOutlined,
+ CheckCircleFilled,
+ EyeOutlined,
+ TeamOutlined,
+ BulbOutlined,
+ ArrowRightOutlined,
+ ExperimentOutlined,
+} from '@ant-design/icons-vue'
+
+const isDev = import.meta.env.DEV
+
+const handleSkipUpload = (count: number) => {
+ store.fillMockData(count)
+ router.push('/p/create/characters')
+}
const router = useRouter()
const store = useAicreateStore()
@@ -314,17 +351,44 @@ const goNext = async () => {
flex-direction: column;
align-items: center;
justify-content: center;
- border: 3px dashed var(--ai-border);
+ border: 2px dashed rgba(99, 102, 241, 0.28);
+ border-radius: var(--ai-radius);
+ background: rgba(99, 102, 241, 0.03);
text-align: center;
padding: 32px;
+ transition: all 0.2s;
}
-.upload-icon, .uploading-icon {
- font-size: 64px;
+.upload-icon-wrap {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 72px;
+ height: 72px;
+ border-radius: 22px;
+ background: linear-gradient(135deg, rgba(99, 102, 241, 0.1), rgba(236, 72, 153, 0.1));
+ margin-bottom: 18px;
}
-.uploading-icon { animation: pulse 1.5s infinite; }
-.upload-title { font-size: 18px; font-weight: 700; margin-top: 16px; }
-.upload-desc { font-size: 14px; color: var(--ai-text-sub); margin-top: 8px; line-height: 1.6; }
-.uploading-text { font-size: 16px; font-weight: 600; margin-top: 16px; }
+.upload-icon {
+ font-size: 36px;
+ color: var(--ai-primary);
+}
+.uploading-icon {
+ font-size: 56px;
+ color: var(--ai-primary);
+ animation: pulse 1.5s infinite;
+}
+.upload-title {
+ font-size: 17px;
+ font-weight: 700;
+ color: var(--ai-text);
+}
+.upload-desc {
+ font-size: 13px;
+ color: var(--ai-text-sub);
+ margin-top: 8px;
+ line-height: 1.6;
+}
+.uploading-text { font-size: 16px; font-weight: 600; margin-top: 16px; color: var(--ai-text); }
.progress-bar {
width: 200px; height: 6px; background: var(--ai-border); border-radius: 3px; margin-top: 16px; overflow: hidden;
}
@@ -341,93 +405,174 @@ const goNext = async () => {
}
.action-btn {
flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
border-radius: var(--ai-radius);
- padding: 20px 0;
+ padding: 18px 0;
text-align: center;
cursor: pointer;
- box-shadow: var(--ai-shadow);
+ transition: all 0.2s;
- &.camera { background: var(--ai-gradient); }
- &.album { background: var(--ai-gradient-purple); }
+ &.camera {
+ background: var(--ai-gradient);
+ color: #fff;
+ box-shadow: 0 8px 22px rgba(99, 102, 241, 0.32);
+ .action-icon { color: #fff; }
+ .action-label { color: #fff; }
+ &:hover { transform: translateY(-2px); box-shadow: 0 10px 26px rgba(99, 102, 241, 0.38); }
+ &:active { transform: scale(0.98); }
+ }
+
+ &.album {
+ background: #fff;
+ border: 1.5px solid rgba(99, 102, 241, 0.22);
+ box-shadow: 0 2px 10px rgba(99, 102, 241, 0.06);
+ .action-icon { color: var(--ai-primary); }
+ .action-label { color: var(--ai-primary); }
+ &:hover {
+ transform: translateY(-2px);
+ border-color: var(--ai-primary);
+ box-shadow: 0 6px 18px rgba(99, 102, 241, 0.14);
+ }
+ &:active { transform: scale(0.98); }
+ }
}
-.action-emoji { font-size: 32px; }
-.action-label { font-size: 15px; font-weight: 700; color: #fff; margin-top: 8px; }
+.action-icon { font-size: 26px; }
+.action-label { font-size: 15px; font-weight: 700; }
.preview-card { overflow: hidden; flex: 1; }
.preview-image {
width: 100%;
aspect-ratio: 4/3;
- background: #F5F0E8;
+ background: #f1f0f7;
img { width: 100%; height: 100%; object-fit: cover; }
}
-.preview-info { padding: 20px; text-align: center; }
-.preview-ok { font-size: 15px; font-weight: 600; color: var(--ai-success); }
+.preview-info {
+ padding: 18px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+}
+.preview-ok-icon { font-size: 18px; color: var(--ai-success); }
+.preview-ok-text { font-size: 14px; font-weight: 600; color: var(--ai-success); }
-/* 儿童风格识别中动画 */
+/* 识别中 */
.recognizing-box {
- background: linear-gradient(135deg, #FFF8E1, #FFFDE7);
- border-radius: 0 0 16px 16px;
- padding: 20px 16px;
+ background: linear-gradient(135deg, rgba(99,102,241,0.06), rgba(236,72,153,0.04));
+ border-radius: 0 0 var(--ai-radius) var(--ai-radius);
+ padding: 24px 16px;
text-align: center;
}
-.recognizing-emojis {
- display: flex;
- justify-content: center;
- gap: 12px;
+.recognizing-spinner {
+ font-size: 32px;
+ color: var(--ai-primary);
margin-bottom: 12px;
- padding: 8px 0;
-}
-.recognizing-emoji {
- font-size: 28px;
- display: inline-block;
- animation: emojiPop 1.8s ease-in-out infinite;
-}
-.recognizing-emoji.e1 { animation-delay: 0s; }
-.recognizing-emoji.e2 { animation-delay: 0.4s; }
-.recognizing-emoji.e3 { animation-delay: 0.8s; }
-@keyframes emojiPop {
- 0%, 100% { transform: scale(1) rotate(0deg); opacity: 0.5; }
- 50% { transform: scale(1.3) rotate(10deg); opacity: 1; }
}
.recognizing-text {
- font-size: 15px;
- font-weight: 700;
- color: #F59E0B;
- letter-spacing: 0.5px;
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--ai-primary);
}
-// 等待内容 — 填满空白
+// 等待内容
.waiting-content {
display: flex; flex-direction: column; gap: 12px; flex: 1;
}
.waiting-card {
- background: rgba(255,255,255,0.92); border-radius: 20px;
- padding: 18px 20px; box-shadow: 0 4px 16px rgba(0,0,0,0.05);
+ background: #fff;
+ border: 1px solid rgba(99, 102, 241, 0.06);
+ border-radius: var(--ai-radius);
+ padding: 18px 20px;
+ box-shadow: 0 4px 16px rgba(99, 102, 241, 0.06);
}
.waiting-title {
- font-size: 15px; font-weight: 800; color: #1E293B; margin-bottom: 14px;
+ font-size: 15px; font-weight: 700; color: var(--ai-text); margin-bottom: 14px;
}
.waiting-steps { display: flex; flex-direction: column; gap: 10px; }
.w-step {
display: flex; align-items: center; gap: 10px;
- padding: 10px 14px; border-radius: 14px; background: #F8F8F5;
- font-size: 14px; color: #94A3B8; transition: all 0.3s;
- &.active { background: #FFF8E7; color: #1E293B; font-weight: 600; }
+ padding: 10px 14px; border-radius: 12px;
+ background: rgba(99, 102, 241, 0.04);
+ font-size: 14px; color: var(--ai-text-sub); transition: all 0.3s;
+ &.active {
+ background: rgba(99, 102, 241, 0.1);
+ color: var(--ai-text);
+ font-weight: 600;
+ }
}
-.w-icon { font-size: 20px; }
-.w-done { margin-left: auto; color: #10B981; font-weight: 700; font-size: 16px; }
+.w-icon { font-size: 18px; color: var(--ai-primary); }
+.w-done { margin-left: auto; color: var(--ai-success); font-size: 16px; }
.waiting-funfact {
- display: flex; align-items: flex-start; gap: 10px;
- background: linear-gradient(135deg, #EDE9FE, #F5F3FF);
- border-radius: 16px; padding: 14px 16px;
+ display: flex; align-items: center; gap: 10px;
+ background: linear-gradient(135deg, rgba(167, 139, 250, 0.1), rgba(236, 72, 153, 0.06));
+ border: 1px solid rgba(99, 102, 241, 0.08);
+ border-radius: var(--ai-radius-sm);
+ padding: 14px 16px;
}
-.ff-icon { font-size: 20px; flex-shrink: 0; }
-.ff-text { font-size: 13px; color: #6D28D9; line-height: 1.6; }
+.ff-icon { font-size: 18px; flex-shrink: 0; color: #8b5cf6; }
+.ff-text { font-size: 13px; color: var(--ai-text); line-height: 1.6; }
+
.quota-warn {
- background: #FEF3C7; color: #92400E; font-size: 13px; text-align: center;
- padding: 10px 16px; border-radius: 10px; margin-top: 12px; font-weight: 600;
+ background: rgba(245, 158, 11, 0.1);
+ color: #b45309;
+ font-size: 13px;
+ text-align: center;
+ padding: 10px 16px;
+ border-radius: 10px;
+ margin-top: 12px;
+ font-weight: 600;
+}
+.upload-error {
+ color: #ef4444;
+ font-size: 13px;
+ text-align: center;
+ margin-top: 12px;
+ font-weight: 500;
}
-.upload-error { color: #EF4444; font-size: 13px; text-align: center; margin-top: 12px; font-weight: 500; }
.preview-actions { display: flex; gap: 12px; margin-top: 12px; button { flex: 1; } }
+.preview-next-btn {
+ display: flex !important;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ :deep(.anticon) { font-size: 16px; }
+}
+
+/* 开发模式跳过按钮 */
+.dev-skip {
+ margin-bottom: 12px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ flex-wrap: wrap;
+}
+.dev-skip-label {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 11px;
+ font-weight: 600;
+ color: var(--ai-text-sub);
+ :deep(.anticon) { font-size: 12px; }
+}
+.dev-skip-btn {
+ padding: 6px 12px;
+ border-radius: 14px;
+ background: rgba(99, 102, 241, 0.06);
+ color: var(--ai-primary);
+ font-size: 11px;
+ font-weight: 600;
+ border: 1px dashed rgba(99, 102, 241, 0.32);
+ cursor: pointer;
+ transition: all 0.2s;
+ &:hover {
+ background: rgba(99, 102, 241, 0.1);
+ border-color: var(--ai-primary);
+ }
+}
diff --git a/frontend/src/views/public/create/views/WelcomeView.vue b/frontend/src/views/public/create/views/WelcomeView.vue
index 2273621..2b6da00 100644
--- a/frontend/src/views/public/create/views/WelcomeView.vue
+++ b/frontend/src/views/public/create/views/WelcomeView.vue
@@ -1,88 +1,63 @@
-
-
-
⭐
-
🌈
-
✨
-
-
- {{ b }}
-
-
-
{{ brandTitle }}
-
{{ brandSubtitle }}
-
+
+
+
+
+
+
- ✨ 拍一张画,AI帮你变成绘本
-
+
+
+
+
AI 绘本创作
+
把你的画变成会讲故事的绘本
+
-
-
-
-
-
-
-
-
-
-
- {{ s.emoji }}
- {{ s.title }}
-
-
{{ s.desc }}
+
+
+ 创作流程
+
+
+
+
+
+
+ {{ s.title }}
+ 可选
+
{{ s.desc }}
+
-
-
-
🎨 AI绘画
-
📖 自动排版
-
🔊 语音配音
-
🎤 人工配音
-
-
-
-
-
- 🖌️
- 上传孩子的画作,AI 自动识别角色
-
-
- 📖
- 一键生成多页精美绘本故事
-
-
- 🔊
- AI 配音或亲自录音,让故事活起来
-
-
-
-
-
-
-
+
+
-
-
本应用需要通过企业入口访问
-
请联系您的管理员获取访问链接
-
- 🔑 前往企业认证
-
-
-
-
-
-
- 🚀 开始创作
+
+
+ 前往企业认证
+
+ 需通过企业入口访问
+
+ 请联系管理员获取访问链接
+
+
+
+
+ 开始创作
+
+ 你的画作,会讲故事
-
让每个孩子都是小画家 ✨
@@ -90,24 +65,38 @@
diff --git a/frontend/src/views/public/works/Index.vue b/frontend/src/views/public/works/Index.vue
index 13e76be..3c89687 100644
--- a/frontend/src/views/public/works/Index.vue
+++ b/frontend/src/views/public/works/Index.vue
@@ -65,18 +65,28 @@