1143 lines
26 KiB
Vue
1143 lines
26 KiB
Vue
<template>
|
||
<view class="result-container" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||
<!-- 顶部导航 -->
|
||
<view class="nav-bar">
|
||
<view class="nav-left" @click="goBack">
|
||
<text class="iconfont icon-fanhui"></text>
|
||
</view>
|
||
<view class="nav-title">生成结果</view>
|
||
<view class="nav-right"></view>
|
||
</view>
|
||
|
||
<!-- AI生成内容标识 -->
|
||
<view class="ai-notice">
|
||
<text class="ai-notice-icon">🤖</text>
|
||
<text class="ai-notice-text">图片由AI生成,结果仅供参考</text>
|
||
</view>
|
||
|
||
<scroll-view scroll-y class="main-content">
|
||
<!-- 生成进度提示(生成中状态) -->
|
||
<view class="generating-tip" v-if="isGenerating">
|
||
<view class="generating-animation">
|
||
<view class="dot dot-1"></view>
|
||
<view class="dot dot-2"></view>
|
||
<view class="dot dot-3"></view>
|
||
</view>
|
||
<text class="generating-text">正在创作中...</text>
|
||
<text class="generating-time">预计{{ estimatedTime }}秒</text>
|
||
</view>
|
||
|
||
<!-- 图片结果展示 -->
|
||
<view class="result-section" v-if="!isGenerating">
|
||
<!-- 单张图片显示 -->
|
||
<view class="single-image-container" v-if="generatedImages.length > 0">
|
||
<view class="image-item" @click="previewImage(0)">
|
||
<image
|
||
:src="generatedImages[0].url"
|
||
mode="aspectFit"
|
||
class="result-image"
|
||
:class="{ 'loading': generatedImages[0].loading }"
|
||
@load="onImageLoad"
|
||
@error="onImageError"
|
||
:show-menu-by-longpress="true"
|
||
></image>
|
||
|
||
<!-- 加载动画 -->
|
||
<view class="image-loading" v-if="generatedImages[0].loading">
|
||
<view class="loading-spinner"></view>
|
||
</view>
|
||
|
||
<!-- 图片加载失败提示 -->
|
||
<view class="image-error" v-if="imageLoadError">
|
||
<text class="error-text">图片加载</text>
|
||
<text class="error-url">{{ generatedImages[0].url }}</text>
|
||
</view>
|
||
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 调试信息 -->
|
||
<view class="debug-info" v-if="showDebugInfo && generatedImages.length > 0">
|
||
<text class="debug-title">调试信息:</text>
|
||
<text class="debug-text">图片数量: {{ generatedImages.length }}</text>
|
||
<text class="debug-text">图片URL: {{ generatedImages[0].url }}</text>
|
||
<text class="debug-text">标题: {{ promptText }}</text>
|
||
<text class="debug-text">加载状态: {{ generatedImages[0].loading ? '加载中' : '已完成' }}</text>
|
||
<text class="debug-text">错误状态: {{ imageLoadError ? '失败' : '正常' }}</text>
|
||
<button class="debug-btn" @click="testImageLoad">测试图片加载</button>
|
||
<button class="debug-btn" @click="showDebugInfo = false">关闭调试</button>
|
||
</view>
|
||
|
||
<!-- 生成信息 -->
|
||
<view class="info-section">
|
||
<view class="info-header" @click="showPrompt = !showPrompt">
|
||
<text class="info-title">生成描述</text>
|
||
<text class="iconfont" :class="showPrompt ? 'icon-xiangshang' : 'icon-xiangxia'"></text>
|
||
</view>
|
||
|
||
<view class="prompt-content" v-if="showPrompt">
|
||
<!-- 直接显示编辑输入框 -->
|
||
<textarea
|
||
v-model="promptText"
|
||
class="prompt-input"
|
||
placeholder="请输入生成描述"
|
||
:maxlength="800"
|
||
:auto-height="true"
|
||
></textarea>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 配置选项 -->
|
||
<view class="section config-section">
|
||
<!-- 生成比例选择 -->
|
||
<view class="ratio-section">
|
||
<view class="ratio-header" @click="showRatioList = !showRatioList">
|
||
<view class="ratio-title-wrapper">
|
||
<text class="ratio-title">生成比例</text>
|
||
<text class="ratio-current" v-if="!showRatioList">{{ selectedRatio }}</text>
|
||
</view>
|
||
<text class="iconfont" :class="showRatioList ? 'icon-xiangshang' : 'icon-xiangxia'"></text>
|
||
</view>
|
||
|
||
<view class="ratio-content" v-if="showRatioList">
|
||
<view class="ratio-list">
|
||
<view
|
||
v-for="(ratio, index) in ratios"
|
||
:key="index"
|
||
:class="['ratio-item', selectedRatio === ratio.value ? 'active' : '']"
|
||
@click="selectRatio(ratio.value)"
|
||
>
|
||
<view class="ratio-box" :style="{ aspectRatio: ratio.aspect }"></view>
|
||
<text class="ratio-text">{{ ratio.value }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 联想词助手开关 -->
|
||
<view class="config-item assistant-item">
|
||
<view class="assistant-info">
|
||
<text class="assistant-title">联想词助手</text>
|
||
<text class="assistant-desc">AI智能补充和优化提示词</text>
|
||
</view>
|
||
<switch
|
||
:checked="enableAssistant"
|
||
@change="toggleAssistant"
|
||
color="#42ca4d"
|
||
/>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 操作按钮 -->
|
||
<view class="action-section">
|
||
<button class="action-btn primary" @click="handleReGenerate">
|
||
<text class="btn-text">再次生成</text>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部占位 -->
|
||
<view class="bottom-placeholder"></view>
|
||
</scroll-view>
|
||
|
||
<!-- 底部操作栏 -->
|
||
<view class="footer-bar" v-if="!isGenerating">
|
||
<button class="footer-btn secondary" @click="handleShare">
|
||
<text class="iconfont icon-fenxiang"></text>
|
||
<text class="btn-text">分享</text>
|
||
</button>
|
||
<button class="footer-btn secondary" @click="handleDownload">
|
||
<text class="iconfont icon-xiazai"></text>
|
||
<text class="btn-text">下载</text>
|
||
</button>
|
||
<button class="footer-btn primary" @click="handleApply">
|
||
<text class="btn-text">应用作品</text>
|
||
</button>
|
||
</view>
|
||
|
||
<!-- 图片预览弹窗 -->
|
||
<view class="preview-overlay" v-if="showPreview" @click="closePreview">
|
||
<swiper
|
||
class="preview-swiper"
|
||
:current="currentPreviewIndex"
|
||
@change="onSwiperChange"
|
||
@click.stop
|
||
>
|
||
<swiper-item v-for="(img, index) in generatedImages" :key="index">
|
||
<view class="swiper-item-content">
|
||
<image
|
||
:src="img.url"
|
||
mode="aspectFit"
|
||
class="preview-full-image"
|
||
></image>
|
||
</view>
|
||
</swiper-item>
|
||
</swiper>
|
||
|
||
<!-- 预览工具栏 -->
|
||
<view class="preview-toolbar" @click.stop>
|
||
<view class="toolbar-left">
|
||
<text class="page-indicator">{{ currentPreviewIndex + 1 }}/{{ generatedImages.length }}</text>
|
||
</view>
|
||
<view class="toolbar-right">
|
||
<view class="tool-btn" @click.stop="downloadSingleImage(currentPreviewIndex)">
|
||
<text class="iconfont icon-xiazai"></text>
|
||
</view>
|
||
<view class="tool-btn" @click.stop="closePreview">
|
||
<text class="iconfont icon-guanbi"></text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import api from '@/api/models-api.js'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
statusBarHeight: 0,
|
||
|
||
// 生成状态
|
||
isGenerating: false,
|
||
estimatedTime: 30,
|
||
|
||
// 生成参数
|
||
model: '4.0',
|
||
promptText: '按照参考图的宽高比例,生成一个新的"会员礼包"的商城小程序banner,展示沉香类商品,电商活动,限时特惠,满赠香薰',
|
||
referenceImages: [], // 参考图列表
|
||
|
||
// 生成比例
|
||
selectedRatio: '9:16',
|
||
ratios: [
|
||
{ value: '9:16', aspect: '9/16', label: '竖屏' },
|
||
{ value: '3:4', aspect: '3/4', label: '竖屏' },
|
||
{ value: '2:3', aspect: '2/3', label: '竖屏' },
|
||
{ value: '1:1', aspect: '1/1', label: '方形' },
|
||
{ value: '3:2', aspect: '3/2', label: '横屏' }
|
||
],
|
||
showRatioList: false, // 比例列表展开状态
|
||
|
||
// 联想词助手
|
||
enableAssistant: true,
|
||
|
||
// 生成结果
|
||
generatedImages: [
|
||
{
|
||
url: '/static/images/demo-result-1.jpg',
|
||
loading: false
|
||
}
|
||
],
|
||
|
||
// UI控制
|
||
showPrompt: true,
|
||
showPreview: false,
|
||
currentPreviewIndex: 0,
|
||
imageLoadError: false,
|
||
showDebugInfo: false // 开启调试信息显示
|
||
};
|
||
},
|
||
|
||
onLoad(options) {
|
||
console.log('result.vue onLoad 接收参数:', options);
|
||
this.initPage();
|
||
|
||
// 接收生成参数
|
||
if (options.promptText) {
|
||
this.promptText = decodeURIComponent(options.promptText);
|
||
}
|
||
if (options.ratio) {
|
||
this.selectedRatio = options.ratio;
|
||
}
|
||
if (options.model) {
|
||
this.model = options.model;
|
||
}
|
||
if (options.referenceImages) {
|
||
try {
|
||
this.referenceImages = JSON.parse(decodeURIComponent(options.referenceImages));
|
||
} catch (e) {
|
||
console.error('解析参考图失败:', e);
|
||
}
|
||
}
|
||
|
||
// 如果是新生成,显示生成动画
|
||
if (options.generate === 'true') {
|
||
this.startGenerating();
|
||
return;
|
||
}
|
||
|
||
// 如果是从灵感广场跳转过来,加载对应的图片
|
||
if (options.image) {
|
||
const imageUrl = decodeURIComponent(options.image);
|
||
const title = options.title ? decodeURIComponent(options.title) : '未命名作品';
|
||
|
||
console.log('解码后的图片URL:', imageUrl);
|
||
console.log('解码后的标题:', title);
|
||
|
||
// 更新显示数据
|
||
this.promptText = title;
|
||
this.generatedImages = [
|
||
{
|
||
url: imageUrl,
|
||
loading: false
|
||
}
|
||
];
|
||
|
||
// 将图片URL作为参考图
|
||
this.referenceImages = [imageUrl];
|
||
|
||
console.log('更新后的 generatedImages:', this.generatedImages);
|
||
console.log('更新后的 referenceImages:', this.referenceImages);
|
||
} else {
|
||
console.warn('未接收到 options.image 参数');
|
||
}
|
||
},
|
||
|
||
methods: {
|
||
initPage() {
|
||
const systemInfo = uni.getSystemInfoSync();
|
||
this.statusBarHeight = systemInfo.statusBarHeight || 0;
|
||
},
|
||
|
||
// 图片加载成功
|
||
onImageLoad(e) {
|
||
console.log('图片加载成功:', e);
|
||
this.imageLoadError = false;
|
||
if (this.generatedImages.length > 0) {
|
||
this.generatedImages[0].loading = false;
|
||
}
|
||
},
|
||
|
||
// 图片加载失败
|
||
onImageError(e) {
|
||
console.error('图片加载失败:', e);
|
||
if (this.generatedImages.length > 0) {
|
||
console.error('失败的图片URL:', this.generatedImages[0].url);
|
||
this.generatedImages[0].loading = false;
|
||
}
|
||
this.imageLoadError = true;
|
||
uni.showToast({
|
||
title: '图片加载失败',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
},
|
||
|
||
// 测试图片加载
|
||
testImageLoad() {
|
||
if (this.generatedImages.length > 0) {
|
||
const imageUrl = this.generatedImages[0].url;
|
||
console.log('测试图片URL:', imageUrl);
|
||
|
||
// 尝试重新加载图片
|
||
this.imageLoadError = false;
|
||
this.generatedImages[0].loading = true;
|
||
|
||
// 强制刷新
|
||
const tempUrl = this.generatedImages[0].url;
|
||
this.generatedImages[0].url = '';
|
||
this.$nextTick(() => {
|
||
this.generatedImages[0].url = tempUrl;
|
||
this.generatedImages[0].loading = false;
|
||
});
|
||
|
||
uni.showToast({
|
||
title: '正在重新加载图片',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
|
||
// 开始生成
|
||
startGenerating() {
|
||
this.isGenerating = true;
|
||
|
||
// 模拟生成过程
|
||
const timer = setInterval(() => {
|
||
this.estimatedTime--;
|
||
if (this.estimatedTime <= 0) {
|
||
clearInterval(timer);
|
||
this.isGenerating = false;
|
||
uni.showToast({
|
||
title: '生成完成',
|
||
icon: 'success'
|
||
});
|
||
setTimeout(() => {
|
||
uni.navigateTo({ url: '/pages/ai-generate/inspiration' });
|
||
}, 600);
|
||
}
|
||
}, 1000);
|
||
},
|
||
|
||
// 返回
|
||
goBack() {
|
||
uni.navigateBack();
|
||
},
|
||
|
||
// 预览图片
|
||
previewImage(index) {
|
||
this.currentPreviewIndex = index;
|
||
this.showPreview = true;
|
||
},
|
||
|
||
// 关闭预览
|
||
closePreview() {
|
||
this.showPreview = false;
|
||
},
|
||
|
||
// 切换预览图片
|
||
onSwiperChange(e) {
|
||
this.currentPreviewIndex = e.detail.current;
|
||
},
|
||
|
||
// 选择比例
|
||
selectRatio(value) {
|
||
this.selectedRatio = value;
|
||
},
|
||
|
||
// 切换联想词助手
|
||
toggleAssistant(e) {
|
||
this.enableAssistant = e.detail.value;
|
||
},
|
||
|
||
// 再次生成
|
||
async handleReGenerate() {
|
||
// 验证提示词
|
||
if (!this.promptText.trim()) {
|
||
uni.showToast({
|
||
title: '请输入生成描述',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 验证是否有参考图
|
||
if (this.referenceImages.length === 0) {
|
||
uni.showToast({
|
||
title: '缺少参考图,请返回重新配置',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
return;
|
||
}
|
||
|
||
try {
|
||
uni.showLoading({
|
||
title: '生成中...'
|
||
});
|
||
|
||
// 调用图片编辑API
|
||
const response = await api.createImageEditTask({
|
||
prompt: this.promptText,
|
||
image_urls: this.referenceImages,
|
||
output_format: 'png',
|
||
image_size: this.selectedRatio,
|
||
title: this.promptText
|
||
});
|
||
|
||
console.log('图片编辑任务创建成功:', response);
|
||
|
||
uni.hideLoading();
|
||
|
||
// 显示生成动画
|
||
this.startGenerating();
|
||
|
||
uni.showToast({
|
||
title: '任务已提交',
|
||
icon: 'success'
|
||
});
|
||
|
||
} catch (error) {
|
||
console.error('图片编辑任务创建失败:', error);
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: error.message || '生成失败,请重试',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
}
|
||
},
|
||
|
||
// 分享
|
||
handleShare() {
|
||
uni.showActionSheet({
|
||
itemList: ['分享到微信', '分享到朋友圈', '分享到微博'],
|
||
success: (res) => {
|
||
uni.showToast({
|
||
title: '分享功能开发中',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
});
|
||
},
|
||
|
||
// 下载
|
||
handleDownload() {
|
||
if (this.generatedImages.length === 0) {
|
||
uni.showToast({
|
||
title: '暂无图片',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
uni.showLoading({
|
||
title: '下载中...'
|
||
});
|
||
|
||
// TODO: 实现图片下载
|
||
setTimeout(() => {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '已保存到相册',
|
||
icon: 'success'
|
||
});
|
||
}, 1500);
|
||
},
|
||
|
||
// 下载单张图片
|
||
downloadSingleImage(index) {
|
||
uni.showLoading({
|
||
title: '下载中...'
|
||
});
|
||
|
||
// TODO: 实现单张下载
|
||
setTimeout(() => {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '已保存到相册',
|
||
icon: 'success'
|
||
});
|
||
}, 1000);
|
||
},
|
||
|
||
// 应用到商品
|
||
handleApply() {
|
||
uni.showActionSheet({
|
||
itemList: ['设置为商品主图', '添加到商品详情', '用作活动Banner', '生成推广海报'],
|
||
success: (res) => {
|
||
uni.showToast({
|
||
title: '应用成功',
|
||
icon: 'success'
|
||
});
|
||
}
|
||
});
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.result-container {
|
||
width: 100%;
|
||
min-height: 100vh;
|
||
background: linear-gradient(180deg, #000000 0%, #1a1a1a 100%);
|
||
position: relative;
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
// 顶部导航
|
||
.nav-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
height: 44px;
|
||
padding: 0 16px;
|
||
|
||
.nav-left,
|
||
.nav-right {
|
||
width: 44px;
|
||
height: 44px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.iconfont {
|
||
font-size: 20px;
|
||
color: #ffffff;
|
||
}
|
||
}
|
||
|
||
.nav-title {
|
||
font-size: 17px;
|
||
font-weight: 500;
|
||
color: #ffffff;
|
||
}
|
||
}
|
||
|
||
// AI生成内容标识
|
||
.ai-notice {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 8px;
|
||
padding: 8px 16px;
|
||
margin: 8px 16px;
|
||
background: rgba(66, 202, 77, 0.1);
|
||
border: 1px solid rgba(66, 202, 77, 0.3);
|
||
border-radius: 8px;
|
||
backdrop-filter: blur(10px);
|
||
|
||
.ai-notice-icon {
|
||
font-size: 16px;
|
||
}
|
||
|
||
.ai-notice-text {
|
||
font-size: 12px;
|
||
color: #42ca4d;
|
||
line-height: 1.4;
|
||
}
|
||
}
|
||
|
||
// 主内容区
|
||
.main-content {
|
||
height: calc(100vh - 44px - 80px);
|
||
padding: 0 16px; width:92%
|
||
}
|
||
|
||
// 生成中提示
|
||
.generating-tip {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 80px 0;
|
||
|
||
.generating-animation {
|
||
display: flex;
|
||
gap: 12px;
|
||
margin-bottom: 24px;
|
||
|
||
.dot {
|
||
width: 12px;
|
||
height: 12px;
|
||
background: #42ca4d;
|
||
border-radius: 50%;
|
||
animation: bounce 1.4s infinite ease-in-out both;
|
||
|
||
&.dot-1 {
|
||
animation-delay: -0.32s;
|
||
}
|
||
|
||
&.dot-2 {
|
||
animation-delay: -0.16s;
|
||
}
|
||
|
||
&.dot-3 {
|
||
animation-delay: 0s;
|
||
}
|
||
}
|
||
}
|
||
|
||
.generating-text {
|
||
font-size: 16px;
|
||
color: #ffffff;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.generating-time {
|
||
font-size: 13px;
|
||
color: #8f9bb3;
|
||
}
|
||
}
|
||
|
||
// 结果区域
|
||
.result-section {
|
||
padding-top: 12px;
|
||
}
|
||
|
||
// 单张图片容器
|
||
.single-image-container {
|
||
width: 100%;
|
||
margin-bottom: 12px;
|
||
|
||
.image-item {
|
||
width: 100%;
|
||
min-height: 200px;
|
||
border-radius: 16px;
|
||
overflow: hidden;
|
||
position: relative;
|
||
background: rgba(61, 68, 88, 0.3);
|
||
|
||
.result-image {
|
||
width: 100%;
|
||
display: block;
|
||
|
||
&.loading {
|
||
opacity: 0.3;
|
||
}
|
||
}
|
||
|
||
.image-loading {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.loading-spinner {
|
||
width: 40px;
|
||
height: 40px;
|
||
border: 3px solid rgba(255, 255, 255, 0.2);
|
||
border-top-color: #42ca4d;
|
||
border-radius: 50%;
|
||
animation: spin 0.8s linear infinite;
|
||
}
|
||
}
|
||
|
||
.image-error {
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 20px;
|
||
background: rgba(0, 0, 0, 0.8);
|
||
border-radius: 12px;
|
||
max-width: 80%;
|
||
|
||
.error-icon {
|
||
font-size: 48px;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.error-text {
|
||
font-size: 14px;
|
||
color: #ff6b6b;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.error-url {
|
||
font-size: 11px;
|
||
color: #8f9bb3;
|
||
word-break: break-all;
|
||
text-align: center;
|
||
}
|
||
}
|
||
|
||
.image-tags {
|
||
position: absolute;
|
||
bottom: 12px;
|
||
left: 12px;
|
||
display: flex;
|
||
gap: 8px;
|
||
|
||
.tag {
|
||
padding: 6px 12px;
|
||
background: rgba(0, 0, 0, 0.7);
|
||
border-radius: 6px;
|
||
font-size: 12px;
|
||
color: #ffffff;
|
||
backdrop-filter: blur(10px);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 调试信息
|
||
.debug-info {
|
||
background: rgba(61, 68, 88, 0.3);
|
||
border: 2px solid #42ca4d;
|
||
border-radius: 12px;
|
||
padding: 16px;
|
||
margin-bottom: 16px;
|
||
|
||
.debug-title {
|
||
display: block;
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: #42ca4d;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.debug-text {
|
||
display: block;
|
||
font-size: 12px;
|
||
color: #c5cee0;
|
||
line-height: 1.8;
|
||
margin-bottom: 6px;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.debug-btn {
|
||
margin-top: 12px;
|
||
margin-right: 8px;
|
||
padding: 8px 16px;
|
||
background: #42ca4d;
|
||
color: #ffffff;
|
||
border: none;
|
||
border-radius: 6px;
|
||
font-size: 12px;
|
||
}
|
||
}
|
||
|
||
// 信息区域
|
||
.info-section {
|
||
background: rgba(61, 68, 88, 0.3);
|
||
border-radius: 16px;
|
||
padding: 16px;
|
||
margin-bottom: 16px;
|
||
|
||
.info-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
|
||
.info-title {
|
||
font-size: 15px;
|
||
font-weight: 500;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.iconfont {
|
||
font-size: 14px;
|
||
color: #8f9bb3;
|
||
}
|
||
}
|
||
|
||
.prompt-content {
|
||
margin-top: 12px;
|
||
|
||
.prompt-text {
|
||
display: block;
|
||
font-size: 14px;
|
||
color: #c5cee0;
|
||
line-height: 1.6;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.prompt-input {
|
||
width: 100%;
|
||
min-height: 100px;
|
||
padding: 12px;
|
||
background: rgba(0, 0, 0, 0.2);
|
||
border: 1px solid rgba(143, 155, 179, 0.3);
|
||
border-radius: 8px;
|
||
font-size: 14px;
|
||
color: #ffffff;
|
||
line-height: 1.6;
|
||
box-sizing: border-box;
|
||
|
||
&:focus {
|
||
border-color: #42ca4d;
|
||
background: rgba(0, 0, 0, 0.3);
|
||
}
|
||
}
|
||
|
||
.info-meta {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
|
||
.meta-item {
|
||
font-size: 12px;
|
||
color: #8f9bb3;
|
||
}
|
||
|
||
.meta-divider {
|
||
color: #4a5568;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 配置选项
|
||
.config-section {
|
||
.config-item {
|
||
margin-bottom: 20px;
|
||
}
|
||
}
|
||
|
||
// 比例选择区域
|
||
.ratio-section {
|
||
background: rgba(61, 68, 88, 0.3);
|
||
border-radius: 16px;
|
||
padding: 16px;
|
||
margin-bottom: 16px;
|
||
|
||
.ratio-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
cursor: pointer;
|
||
|
||
.ratio-title-wrapper {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
|
||
.ratio-title {
|
||
font-size: 15px;
|
||
font-weight: 500;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.ratio-current {
|
||
font-size: 14px;
|
||
color: #42ca4d;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.iconfont {
|
||
font-size: 14px;
|
||
color: #8f9bb3;
|
||
}
|
||
}
|
||
|
||
.ratio-content {
|
||
margin-top: 12px;
|
||
}
|
||
}
|
||
|
||
// 比例列表
|
||
.ratio-list {
|
||
display: flex;
|
||
gap: 12px;
|
||
|
||
.ratio-item {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 12px;
|
||
background: rgba(61, 68, 88, 0.3);
|
||
border-radius: 12px;
|
||
border: 2px solid transparent;
|
||
|
||
.ratio-box {
|
||
width: 32px;
|
||
background: #8f9bb3;
|
||
border-radius: 4px;
|
||
margin-bottom: 6px;
|
||
}
|
||
|
||
.ratio-text {
|
||
font-size: 12px;
|
||
color: #8f9bb3;
|
||
}
|
||
|
||
&.active {
|
||
background: rgba(6, 67, 14, 0.1);
|
||
border-color: #42ca4d;
|
||
|
||
.ratio-box {
|
||
background: #42ca4d;
|
||
}
|
||
|
||
.ratio-text {
|
||
color: #42ca4d;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 联想词助手
|
||
.assistant-item {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 11px 16px;
|
||
background: rgba(61, 68, 88, 0.3);
|
||
border-radius: 12px;
|
||
|
||
.assistant-info {
|
||
flex: 1;
|
||
|
||
.assistant-title {
|
||
display: block;
|
||
font-size: 15px;
|
||
color: #ffffff;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.assistant-desc {
|
||
display: block;
|
||
font-size: 12px;
|
||
color: #8f9bb3;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 操作按钮
|
||
.action-section {
|
||
display: flex;
|
||
gap: 12px;
|
||
margin-bottom: 16px;
|
||
|
||
.action-btn {
|
||
flex: 1;
|
||
height: 48px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 6px;
|
||
border-radius: 12px;
|
||
border: none;
|
||
|
||
&.primary {
|
||
background: linear-gradient(135deg, #42ca4d 0%, #38b045 100%);
|
||
|
||
.btn-text {
|
||
color: #ffffff;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.btn-text {
|
||
font-size: 16px;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 底部占位
|
||
.bottom-placeholder {
|
||
height: 20px;
|
||
}
|
||
|
||
// 底部操作栏
|
||
.footer-bar {
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
display: flex;
|
||
gap: 12px;
|
||
padding: 16px;
|
||
background: linear-gradient(0deg, rgba(10, 14, 26, 0.95) 0%, rgba(10, 14, 26, 0.8) 100%);
|
||
backdrop-filter: blur(20px);
|
||
|
||
.footer-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 6px;
|
||
height: 48px;
|
||
border-radius: 12px;
|
||
border: none;
|
||
|
||
&.secondary {
|
||
flex: 0 0 80px;
|
||
background: rgba(61, 68, 88, 0.4);
|
||
|
||
.iconfont,
|
||
.btn-text {
|
||
color: #ffffff;
|
||
}
|
||
}
|
||
|
||
&.primary {
|
||
flex: 1;
|
||
background: linear-gradient(135deg, #42ca4d 0%, #38b045 100%);
|
||
|
||
.btn-text {
|
||
color: #ffffff;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.iconfont {
|
||
font-size: 18px;
|
||
}
|
||
|
||
.btn-text {
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 图片预览
|
||
.preview-overlay {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.95);
|
||
z-index: 9999;
|
||
|
||
.preview-swiper {
|
||
width: 100%;
|
||
height: 100%;
|
||
|
||
.swiper-item-content {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.preview-full-image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
}
|
||
|
||
.preview-toolbar {
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 20px;
|
||
background: linear-gradient(0deg, rgba(0, 0, 0, 0.8) 0%, transparent 100%);
|
||
|
||
.toolbar-left {
|
||
.page-indicator {
|
||
font-size: 14px;
|
||
color: #ffffff;
|
||
}
|
||
}
|
||
|
||
.toolbar-right {
|
||
display: flex;
|
||
gap: 20px;
|
||
|
||
.tool-btn {
|
||
width: 40px;
|
||
height: 40px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: rgba(255, 255, 255, 0.2);
|
||
border-radius: 50%;
|
||
backdrop-filter: blur(10px);
|
||
|
||
.iconfont {
|
||
font-size: 20px;
|
||
color: #ffffff;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 动画
|
||
@keyframes bounce {
|
||
0%, 80%, 100% {
|
||
transform: scale(0);
|
||
}
|
||
40% {
|
||
transform: scale(1);
|
||
}
|
||
}
|
||
|
||
@keyframes spin {
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
</style>
|
||
|