feat: 接口交互的调整

This commit is contained in:
2026-04-06 17:08:06 +08:00
parent ba3a1ba894
commit 3135957dda
9 changed files with 300 additions and 205 deletions

View File

@@ -14,7 +14,9 @@ const KeepAliveList = ref([])
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
const keepAlive = to?.meta?.keepAlive const keepAlive = to?.meta?.keepAlive
if (to.query.token) {
Session.set('token', to.query.token) Session.set('token', to.query.token)
}
if (!router.hasRoute(to.name)) { if (!router.hasRoute(to.name)) {
router.push('/home') router.push('/home')

View File

@@ -1,29 +1,29 @@
/* eslint-disable */ /* eslint-disable */
// @ts-ignore // @ts-ignore
import request from '@common/ajax'; import request from '@common/ajax'
import type { Response } from './types'; import type { Response } from './types'
export interface GeneratorPhotoTask { export interface GeneratorPhotoTask {
pageNum: number; pageNum: number
pageSize: number; pageSize: number
taskStatus: string; taskStatus?: string
} }
export interface GeneratorPhotoTaskListItem { export interface GeneratorPhotoTaskListItem {
records: PhotoTaskRecordsItem[]; records: PhotoTaskRecordsItem[]
} }
export interface PhotoTaskRecordsItem { export interface PhotoTaskRecordsItem {
sceneName: string; sceneName: string
createTime: string; createTime: string
taskStatus: string; taskStatus: string
generatorPhoto: string; generatorPhoto: string
} }
export const generatorPhotoTaskList = (params: GeneratorPhotoTask) => { export const generatorPhotoTaskList = (params: GeneratorPhotoTask) => {
return request<Response<GeneratorPhotoTaskListItem[]>>({ return request<Response<GeneratorPhotoTaskListItem>>({
url: '/aigc/generatorPhotoTaskList', url: '/aigc/generatorPhotoTaskList',
method: 'post', method: 'post',
params, params
}); })
}; }

View File

@@ -3,7 +3,8 @@ import { tansParams } from '@utils/tansParams'
import { getAccessToken } from '@/constant/token' import { getAccessToken } from '@/constant/token'
// 获取.env中的服务地址 // 获取.env中的服务地址
const { VITE_BASE_API, VITE_ENV } = import.meta.env const VITE_BASE_API = (import.meta.env.VITE_BASE_API || '').trim()
const VITE_ENV = (import.meta.env.VITE_ENV || '').trim()
console.log('🚀 ~ VITE_ENV:', VITE_ENV) console.log('🚀 ~ VITE_ENV:', VITE_ENV)
console.log('🚀 ~ VITE_BASE_API:', VITE_BASE_API) console.log('🚀 ~ VITE_BASE_API:', VITE_BASE_API)
@@ -18,21 +19,31 @@ const instance = axios.create({
// 添加拦截器 // 添加拦截器
instance.interceptors.request.use((config) => { instance.interceptors.request.use((config) => {
const token = getAccessToken(); const token = getAccessToken()
config.headers['Authorization'] = `Bearer ${token}` console.log('🚀 ~ Request Token:', token)
if (token) {
// 兼容不同版本的 axios 设置 header
config.headers = config.headers || {}
config.headers.Authorization = `Bearer ${token}`
}
console.log('🚀 ~ Final Headers:', config.headers)
// get请求映射params参数 // get请求映射params参数
if (config.method === 'get' && config.params) { const method = (config.method || '').toLowerCase()
if (method === 'get' && config.params) {
let url = config.url + '?' + tansParams(config.params) let url = config.url + '?' + tansParams(config.params)
console.log('🚀 ~ url:', url)
url = url.slice(0, -1) url = url.slice(0, -1)
config.params = {} config.params = {}
config.url = url config.url = url
} }
// post/put/patch 请求将 params 映射到 bodydata // post/put/patch 请求将 params 映射到 bodydata
if ((config.method === 'post' || config.method === 'put' || config.method === 'patch') && config.params) { if (
(method === 'post' || method === 'put' || method === 'patch') &&
config.params
) {
config.data = config.params config.data = config.params
config.params = {} config.params = {}
} }
@@ -43,9 +54,16 @@ instance.interceptors.request.use((config) => {
// 添加响应拦截器 // 添加响应拦截器
instance.interceptors.response.use( instance.interceptors.response.use(
(res) => { (res) => {
console.log('🚀 ~ res:', res)
if (res.data.code === 0) {
return Promise.resolve(res.data.data) return Promise.resolve(res.data.data)
} else {
console.error('业务报错:', res.data.msg)
return Promise.reject(res.data)
}
}, },
(error) => { (error) => {
console.error('网络或服务器报错:', error)
return Promise.reject(error) return Promise.reject(error)
} }
) )

View File

@@ -1,7 +1,7 @@
import { Session } from '@/utils/storage' import { Session } from '@/utils/storage'
export const getAccessToken = () => { export const getAccessToken = () => {
const token = Session.getToken() const token = Session.getToken()
// const token = 'H7rzcCtsvPqwc0ecDnBT9mlhOqHsWDyS6nXkRjnd1oAgOQqlEhsCy4OZPQ8YyVBj57pmNpwSXJYcd6Ox4YB-W1pHr4aTM9_d6nYJ3OrbRB9f0J7kP9FbbviN609nGO0m' // const token = 'AqmeApe592cOm__Xx8B8NAwJuS_3l8T9GLq9jYqxGSPojQUjmMLbgkG-h5OijP6OdTxwtFm-4ZlShqKYS_pr1OJ1ItZkbRKZjGZh0BIokJ0QIxcOkMQOAf9_XudBedvT'
return token; return token
} }

View File

@@ -44,13 +44,24 @@ export const Local = {
export const Session = { export const Session = {
// 设置临时缓存 // 设置临时缓存
set(key: string, val: any) { set(key: string, val: any) {
if (val === undefined || val === null) {
window.sessionStorage.removeItem(key)
} else {
window.sessionStorage.setItem(key, JSON.stringify(val)) window.sessionStorage.setItem(key, JSON.stringify(val))
}
}, },
// 获取临时缓存 // 获取临时缓存
get(key: string) { get(key: string) {
let json = <string>window.sessionStorage.getItem(key) let json = <string>window.sessionStorage.getItem(key)
if (!json || json === 'undefined' || json === 'null') {
return null
}
try {
return JSON.parse(json) return JSON.parse(json)
} catch (e) {
return json
}
}, },
// 移除临时缓存 // 移除临时缓存

View File

@@ -1,7 +1,13 @@
<template> <template>
<div class="page"> <div class="page">
<!-- 顶部栏 --> <!-- 顶部栏 -->
<TopNavBar title="生成中" color="white" :showHistory="true" @back="onBack" @history="onHistory" /> <TopNavBar
title="生成中"
color="white"
:showHistory="true"
@back="onBack"
@history="onHistory"
/>
<!-- 中间内容 --> <!-- 中间内容 -->
<div class="content"> <div class="content">
@@ -9,17 +15,13 @@
<div class="desc"> <div class="desc">
<div class="main">预计等待5~7分钟</div> <div class="main">预计等待5~7分钟</div>
<div class="sub"> <div class="sub">WHEE云处理中特效生成需要一定时间请耐心等待</div>
WHEE云处理中特效生成需要一定时间请耐心等待
</div>
</div> </div>
</div> </div>
<!-- 底部按钮 --> <!-- 底部按钮 -->
<div class="footer"> <div class="footer">
<button class="btn primary" @click="handleGenerate"> <button class="btn primary" @click="handleGenerate">生成新的特效</button>
生成新的特效
</button>
<button class="btn outline" @click="handleHistory"> <button class="btn outline" @click="handleHistory">
<span>查看生成记录</span> <span>查看生成记录</span>
@@ -28,30 +30,30 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts" name="generate">
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router'
// @ts-ignore // @ts-ignore
import TopNavBar from '../components/TopNavBar.vue'; import TopNavBar from '../components/TopNavBar.vue'
const router = useRouter(); const router = useRouter()
const handleGenerate = () => { const handleGenerate = () => {
console.log('重新生成') console.log('重新生成')
router.back()
} }
const handleHistory = () => { const handleHistory = () => {
console.log('查看记录') console.log('查看记录')
router.push('/history'); router.push('/history')
} }
const onBack = () => { const onBack = () => {
router.back(); router.back()
}; }
const onHistory = () => { const onHistory = () => {
handleHistory(); handleHistory()
}; }
</script> </script>
<style scoped> <style scoped>
@@ -86,7 +88,7 @@ const onHistory = () => {
text-align: center; text-align: center;
font-style: italic; font-style: italic;
text-stroke: 1px rgba(255, 255, 255, 0.2); text-stroke: 1px rgba(255, 255, 255, 0.2);
background: linear-gradient(45deg, #A6E0C6 0%, #7DBBF6 100%); background: linear-gradient(45deg, #a6e0c6 0%, #7dbbf6 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
-webkit-text-stroke: 1px rgba(255, 255, 255, 0.2); -webkit-text-stroke: 1px rgba(255, 255, 255, 0.2);
@@ -120,7 +122,7 @@ const onHistory = () => {
.main { .main {
font-size: 20px; font-size: 20px;
margin-bottom: 8px; margin-bottom: 8px;
color: #FFFFFF; color: #ffffff;
} }
.sub { .sub {
@@ -149,7 +151,7 @@ const onHistory = () => {
/* 渐变按钮 */ /* 渐变按钮 */
.primary { .primary {
background: linear-gradient(90deg, #D9FBC8 0%, #8BE2FF 100%); background: linear-gradient(90deg, #d9fbc8 0%, #8be2ff 100%);
color: #000; color: #000;
border: none; border: none;
font-weight: 500; font-weight: 500;
@@ -170,18 +172,16 @@ const onHistory = () => {
/* 内层内容 */ /* 内层内容 */
.outline::before { .outline::before {
content: ""; content: '';
position: absolute; position: absolute;
inset: 0; inset: 0;
border-radius: inherit; border-radius: inherit;
background: linear-gradient(90deg, #D9FBC8 0%, #8BE2FF 100%); background: linear-gradient(90deg, #d9fbc8 0%, #8be2ff 100%);
padding: 1.5px; padding: 1.5px;
/* 控制边框粗细 */ /* 控制边框粗细 */
/* 核心:挖空中间 */ /* 核心:挖空中间 */
-webkit-mask: -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: xor; -webkit-mask-composite: xor;
mask-composite: exclude; mask-composite: exclude;
} }

View File

@@ -1,11 +1,20 @@
<template> <template>
<div class="page"> <div class="page">
<!-- Header --> <!-- Header -->
<TopNavBar title="最近任务" color="white" :showHistory="false" @back="onBack" /> <TopNavBar
title="最近任务"
color="white"
:showHistory="false"
@back="onBack"
/>
<!-- 列表 --> <!-- 列表 -->
<div class="list"> <div class="list">
<div v-for="(item, index) in list" :key="`${item.name}-${index}`" class="card"> <div
v-for="(item, index) in list"
:key="`${item.name}-${index}`"
class="card"
>
<!-- 排队中 --> <!-- 排队中 -->
<template v-if="item.status == 0"> <template v-if="item.status == 0">
<div class="left queued-box">排队中</div> <div class="left queued-box">排队中</div>
@@ -25,10 +34,15 @@
<div class="name">{{ item.name }}</div> <div class="name">{{ item.name }}</div>
<div class="progress"> <div class="progress">
<div class="bar" :style="{ width: (item.progress || 0) + '%' }"></div> <div
class="bar"
:style="{ width: (item.progress || 0) + '%' }"
></div>
</div> </div>
<div class="status-text">生成中 {{ item.progress ? item.progress + '%' : '' }}</div> <div class="status-text">
生成中 {{ item.progress ? item.progress + '%' : '' }}
</div>
</div> </div>
</template> </template>
@@ -56,20 +70,22 @@
</div> </div>
</template> </template>
</div> </div>
<div class="tip"> {{ list.length == 0 ? '暂无记录' : `仅保留最近20天生成记录` }}</div> <div class="tip">
{{ list.length == 0 ? '暂无记录' : `仅保留最近20天生成记录` }}
</div>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onMounted } from 'vue'; import { onMounted, reactive } from 'vue'
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router'
// @ts-ignore // @ts-ignore
import TopNavBar from '../components/TopNavBar.vue'; import TopNavBar from '../components/TopNavBar.vue'
// @ts-ignore // @ts-ignore
import { generatorPhotoTaskList } from '@api'; import { generatorPhotoTaskList } from '@api'
import { closeToast, showLoadingToast } from 'vant'; import { closeToast, showLoadingToast } from 'vant'
import 'vant/lib/toast/style'; import 'vant/lib/toast/style'
interface TaskItem { interface TaskItem {
name: string name: string
@@ -79,44 +95,58 @@ interface TaskItem {
time?: string time?: string
} }
const list: TaskItem[] = [] const list = reactive<TaskItem[]>([])
const router = useRouter(); const router = useRouter()
const onBack = () => { const onBack = () => {
router.back(); router.back()
};
const lookPicture = (item: TaskItem) => {
console.log('查看图片');
const encoded = encodeURIComponent(JSON.stringify(item));
router.push({ path: '/prepicture', query: { data: encoded } });
} }
const getTaskList = () => { const lookPicture = (item: TaskItem) => {
showLoadingToast('加载中...'); console.log('查看图片')
generatorPhotoTaskList({ pageNum: 1, pageSize: 20 }).then(res => { const encoded = encodeURIComponent(JSON.stringify(item))
closeToast(); router.push({ path: '/prepicture', query: { data: encoded } })
if (res.code === 0) { }
const data = res.data || [];
list.splice(0, list.length, ...data.map(item => { const getTaskList = async () => {
let statusNum: number = item.taskStatus as unknown as number; // 先尝试直接转换为数字 showLoadingToast('加载中...')
try {
const res = await generatorPhotoTaskList({
pageNum: 1,
pageSize: 20,
taskStatus: '1'
})
console.log('🚀 ~ generatorPhotoTaskList res:', res)
closeToast()
// 因为拦截器返回了 res.data.data所以这里的 res 直接就是数据内容
// 根据后端返回结构,这里 res 应该是 { records: [] }
const data = res?.records || []
list.splice(
0,
list.length,
...data.map((item: any) => {
let statusNum: number = Number(item.taskStatus)
return { return {
name: item.sceneName, name: item.sceneName,
status: statusNum as 0 | 1 | 2 | 3, status: statusNum as 0 | 1 | 2 | 3,
progress: statusNum === 1 ? 50 : undefined, // 若后端有真实进度请替换 progress: statusNum === 1 ? 50 : undefined,
cover: item.generatorPhoto, cover: item.generatorPhoto,
time: item.createTime, time: item.createTime
} as TaskItem; } as TaskItem
})); })
)
} catch (error) {
console.error('🚀 ~ getTaskList error details:', error)
closeToast()
} }
});
} }
onMounted(() => { onMounted(() => {
getTaskList(); getTaskList()
}); })
</script> </script>
<style scoped> <style scoped>

View File

@@ -1,24 +1,42 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<transition name="fade" mode="out-in"> <transition name="fade" mode="out-in">
<img :key="activeScene.sceneName" :src="activeScene.sceneCoverUrl" class="bg-image" /> <img
:key="activeScene.sceneName"
:src="activeScene.sceneCoverUrl"
class="bg-image"
/>
</transition> </transition>
<div class="gradient-overlay"></div> <div class="gradient-overlay"></div>
<TopNavBar title="" color="white" :showHistory="true" @back="onBack" @history="onHistory" /> <TopNavBar
title=""
color="white"
:showHistory="true"
@back="onBack"
@history="onHistory"
/>
<div class="content-layer"> <div class="content-layer">
<div class="style-tabs"> <div class="style-tabs">
<div v-for="tab in styles" :key="tab.id" :class="['tab-item', { active: activeStyleId === tab.id }]" <div
@click="handleStyleChange(tab.id)"> v-for="tab in styles"
:key="tab.id"
:class="['tab-item', { active: activeStyleId === tab.id }]"
@click="handleStyleChange(tab.id)"
>
{{ tab.name }} {{ tab.name }}
</div> </div>
</div> </div>
<div class="scene-list-container"> <div class="scene-list-container">
<div v-for="(item, index) in currentScenes" :key="`${activeStyleId}-${index}`" <div
:class="['scene-card', { active: activeSceneIndex === index }]" @click="activeSceneIndex = index"> v-for="(item, index) in currentScenes"
:key="`${activeStyleId}-${index}`"
:class="['scene-card', { active: activeSceneIndex === index }]"
@click="activeSceneIndex = index"
>
<img :src="item.sceneCoverUrl" class="thumb-img" /> <img :src="item.sceneCoverUrl" class="thumb-img" />
<div class="scene-name">{{ item.sceneName }}</div> <div class="scene-name">{{ item.sceneName }}</div>
</div> </div>
@@ -35,92 +53,108 @@
</div> </div>
<!-- 协议提示 --> <!-- 协议提示 -->
<van-popup v-model:show="showAgree" round :close-on-click-overlay="false" <van-popup
:style="{ padding: '30px 24px', width: '80%' }"> v-model:show="showAgree"
<AgreementTip @cancel="cancelAgree" @confirm="onAgree" @view-rule="onViewRule" /> round
:close-on-click-overlay="false"
:style="{ padding: '30px 24px', width: '80%' }"
>
<AgreementTip
@cancel="cancelAgree"
@confirm="onAgree"
@view-rule="onViewRule"
/>
</van-popup> </van-popup>
<!-- 选图说明 --> <!-- 选图说明 -->
<van-popup v-model:show="showGuide" round position="bottom" closeable close-icon-position="top-left"> <van-popup
v-model:show="showGuide"
round
position="bottom"
closeable
close-icon-position="top-left"
>
<PhotoGuide @start="onStartSelect" /> <PhotoGuide @start="onStartSelect" />
</van-popup> </van-popup>
</template> </template>
<script setup lang="ts"> <script setup lang="ts" name="home">
import { ref, computed, onMounted, reactive } from 'vue'; import { ref, computed, onMounted, reactive, watch } from 'vue'
import { useRouter } from 'vue-router'; import { useRouter, useRoute } from 'vue-router'
import { Session } from '@/utils/storage'
// @ts-ignore // @ts-ignore
import TopNavBar from '../components/TopNavBar.vue'; import TopNavBar from '../components/TopNavBar.vue'
// @ts-ignore // @ts-ignore
import PhotoGuide from '../components/PhotoGuide.vue'; import PhotoGuide from '../components/PhotoGuide.vue'
// @ts-ignore // @ts-ignore
import AgreementTip from '../components/AgreementTip.vue'; import AgreementTip from '../components/AgreementTip.vue'
// @ts-ignore // @ts-ignore
import { getAigcSceneList, AigcSceneListItem, AigcSceneStyleItem } from '@api'; import { getAigcSceneList, AigcSceneListItem, AigcSceneStyleItem } from '@api'
// @ts-ignore // @ts-ignore
import { createGeneratorPhotoTask } from '@api'; import { createGeneratorPhotoTask } from '@api'
import { showFailToast, showSuccessToast } from 'vant'; import { showFailToast, showSuccessToast } from 'vant'
import 'vant/lib/toast/style'; import 'vant/lib/toast/style'
// --- 测试数据 --- // --- 测试数据 ---
const styles = [ const styles = [
{ id: 'real', name: '真实风格', sceneStyle: '0' }, { id: 'real', name: '真实风格', sceneStyle: '0' },
{ id: 'comic', name: '漫画风格', sceneStyle: '1' } { id: 'comic', name: '漫画风格', sceneStyle: '1' }
]; ]
const mockData = reactive({ const mockData = reactive({
real: [] as AigcSceneStyleItem[], real: [] as AigcSceneStyleItem[],
comic: [] as AigcSceneStyleItem[] comic: [] as AigcSceneStyleItem[]
}); })
const router = useRouter(); const router = useRouter()
const route = useRoute()
// --- 状态 --- // --- 状态 ---
const activeStyleId = ref<'real' | 'comic'>('real'); const activeStyleId = ref<'real' | 'comic'>('real')
const activeSceneIndex = ref(0); const activeSceneIndex = ref(0)
const showGuide = ref(false); const showGuide = ref(false)
const showAgree = ref(true); const showAgree = ref(!Session.get('hasAgreedPrivacy'))
const cancelAgree = () => { const cancelAgree = () => {
console.log("用户拒绝了协议"); console.log('用户拒绝了协议')
showAgree.value = false; showAgree.value = false
if (window.wx && wx.miniProgram) { const wx = (window as any).wx
wx.miniProgram.navigateBack(); if (wx && wx.miniProgram) {
wx.miniProgram.navigateBack()
} }
}; }
const onAgree = () => { const onAgree = () => {
console.log("用户同意了协议"); console.log('用户同意了协议')
showAgree.value = false; showAgree.value = false
Session.set('hasAgreedPrivacy', true)
// 执行下一步选图逻辑 // 执行下一步选图逻辑
}; }
const onViewRule = () => { const onViewRule = () => {
console.log("跳转到规则详情页"); console.log('跳转到规则详情页')
// 可以是打开另一个 popup 或者 router.push // 可以是打开另一个 popup 或者 router.push
}; }
const onBack = () => { const onBack = () => {
router.back(); router.back()
}; }
const onHistory = () => { const onHistory = () => {
router.push('/history'); router.push('/history')
}; }
const generateAction = () => { const generateAction = () => {
showGuide.value = true; showGuide.value = true
} }
const onStartSelect = () => { const onStartSelect = () => {
console.log("用户已阅读说明,开始打开相册逻辑..."); console.log('用户已阅读说明,开始打开相册逻辑...')
showGuide.value = false; showGuide.value = false
// 这里写调用系统相册的代码 // 这里写调用系统相册的代码
uploadImage(); uploadImage()
}; }
// 调用上传 // 调用上传
const uploadImage = () => { const uploadImage = () => {
@@ -133,73 +167,71 @@ const uploadImage = () => {
// return // return
/// 调用小程序上传接口 /// 调用小程序上传接口
if (window.wx && wx.miniProgram) { const wx = (window as any).wx
if (wx && wx.miniProgram) {
wx.miniProgram.navigateTo({ wx.miniProgram.navigateTo({
url: '/pages-bridge/UploadImage' url: '/pages-bridge/UploadImage'
}); })
} }
} }
window.addEventListener('hashchange', () => { // 监听 URL 中的 imageUrl 参数(通常从小程序跳转回来时携带)
const imageUrl = getHashParam('imageUrl') watch(
console.log('从 hash 中获取的 imageUrl:', imageUrl) () => route.query.imageUrl,
if (imageUrl) { (newUrl) => {
sendGeneratorPhotoTask(imageUrl) if (newUrl && typeof newUrl === 'string' && newUrl !== 'error') {
} console.log('检测到 hash 中的 imageUrl:', newUrl)
}) sendGeneratorPhotoTask(newUrl)
const getHashParam = (key) => { // 处理完后清除 URL 参数,防止返回或刷新时重复触发
const hash = window.location.hash const newQuery = { ...route.query }
console.log('hash URL:', hash) delete newQuery.imageUrl
router.replace({ query: newQuery })
const queryStr = hash.split('?')[1] || ''
const params = queryStr.split('&')
for (let i = 0; i < params.length; i++) {
const [k, v] = params[i].split('=')
if (k === key) {
return decodeURIComponent(v || '')
} }
} },
return null { immediate: true }
} )
/// 发送生成任务 /// 发送生成任务
const sendGeneratorPhotoTask = async (photoUrl: string) => { const sendGeneratorPhotoTask = async (photoUrl: string) => {
const photoUrlList = [photoUrl]; const photoUrlList = [photoUrl]
try { try {
const response = await createGeneratorPhotoTask({ photoUrlList: photoUrlList, sceneId: activeScene.value.sceneStyleId }); const response = await createGeneratorPhotoTask({
photoUrlList: photoUrlList,
sceneId: activeScene.value.sceneStyleId
})
if (response) { if (response) {
showSuccessToast('生成任务创建成功!'); showSuccessToast('生成任务创建成功!')
router.push('/generate'); router.push('/generate')
} else { } else {
showFailToast('生成任务创建失败,请试。'); showFailToast('生成任务创建失败,请稍后再试。')
} }
} catch (error) { } catch (error) {
console.error('创建生成任务时发生错误:', error); console.error('创建生成任务时发生错误:', error)
showFailToast('创建生成任务时发生错误,请稍后再试。'); showFailToast('创建生成任务时发生错误,请稍后再试。')
} }
}; }
// --- 计算属性 --- // --- 计算属性 ---
const currentScenes = computed(() => mockData[activeStyleId.value] || []); const currentScenes = computed(() => mockData[activeStyleId.value] || [])
const activeScene = computed(() => currentScenes.value[activeSceneIndex.value] || {}); const activeScene = computed(
() => currentScenes.value[activeSceneIndex.value] || {}
)
// --- 方法 --- // --- 方法 ---
const handleStyleChange = (id: 'real' | 'comic') => { const handleStyleChange = (id: any) => {
activeStyleId.value = id; activeStyleId.value = id
activeSceneIndex.value = 0; activeSceneIndex.value = 0
}; }
// 数据请求 // 数据请求
const fetchSceneList = async () => { const fetchSceneList = async () => {
const list: AigcSceneListItem[] = await getAigcSceneList(); const list: AigcSceneListItem[] = await getAigcSceneList()
const realArr: any[] = []; const realArr: any[] = []
const comicArr: any[] = []; const comicArr: any[] = []
list.forEach((scene) => { list.forEach((scene) => {
const styles = scene.aigcSceneStyleList || []; const styles = scene.aigcSceneStyleList || []
styles.forEach((s: AigcSceneStyleItem) => { styles.forEach((s: AigcSceneStyleItem) => {
const styleItem: AigcSceneStyleItem = { const styleItem: AigcSceneStyleItem = {
sceneName: scene.sceneName, sceneName: scene.sceneName,
@@ -207,27 +239,25 @@ const fetchSceneList = async () => {
sortIndex: scene.sortIndex, sortIndex: scene.sortIndex,
sceneStyle: s.sceneStyle, sceneStyle: s.sceneStyle,
sceneStyleId: s.sceneStyleId, sceneStyleId: s.sceneStyleId,
sceneCoverUrl: s.sceneCoverUrl, sceneCoverUrl: s.sceneCoverUrl
}; }
if (s.sceneStyle === '0') { if (s.sceneStyle === '0') {
realArr.push(styleItem); realArr.push(styleItem)
} }
if (s.sceneStyle === '1') { if (s.sceneStyle === '1') {
comicArr.push(styleItem); comicArr.push(styleItem)
} }
}); })
}); })
mockData.real = realArr;
mockData.comic = comicArr;
console.log('处理后的场景列表:', JSON.stringify(mockData));
};
mockData.real = realArr
mockData.comic = comicArr
console.log('处理后的场景列表:', JSON.stringify(mockData))
}
onMounted(() => { onMounted(() => {
fetchSceneList(); fetchSceneList()
}); })
</script> </script>
<style scoped> <style scoped>
@@ -257,11 +287,15 @@ onMounted(() => {
inset: 0; inset: 0;
height: 60%; height: 60%;
z-index: 1; z-index: 1;
background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.1) 70%, rgba(0, 0, 0, 0.7) 85%, #000 100%); background: linear-gradient(
to bottom,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 0.1) 70%,
rgba(0, 0, 0, 0.7) 85%,
#000 100%
);
} }
/* 内容布局层 */ /* 内容布局层 */
.content-layer { .content-layer {
position: relative; position: relative;
@@ -379,7 +413,7 @@ onMounted(() => {
text-align: center; text-align: center;
font-size: 56px; font-size: 56px;
margin: 12px 0 32px; margin: 12px 0 32px;
background: linear-gradient(to bottom, #FFFFFF 0%, #CBF2FC 100%); background: linear-gradient(to bottom, #ffffff 0%, #cbf2fc 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
font-weight: 900; font-weight: 900;
@@ -419,7 +453,7 @@ onMounted(() => {
height: 60px; height: 60px;
border-radius: 30px; border-radius: 30px;
border: none; border: none;
background: linear-gradient(90deg, #D9FBC8 0%, #8BE2FF 100%); background: linear-gradient(90deg, #d9fbc8 0%, #8be2ff 100%);
box-shadow: 0px 0px 20px 0px rgba(217, 251, 200, 0.3); box-shadow: 0px 0px 20px 0px rgba(217, 251, 200, 0.3);
font-weight: bold; font-weight: bold;
font-size: 20px; font-size: 20px;

View File

@@ -29,7 +29,7 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts" name="prepicture">
import { ref, computed } from 'vue'; import { ref, computed } from 'vue';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
// @ts-ignore // @ts-ignore