Files
msh-system/msh_single_uniapp/pages/ai-generate/agent.vue

684 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="agent-container" :style="{ paddingTop: statusBarHeight + 'px' }">
<!-- 顶部导航 -->
<view class="nav-bar">
<view class="nav-title">智能体</view>
</view>
<scroll-view scroll-y class="main-content" :style="{ height: scrollViewHeight }">
<!-- Banner区域 -->
<view class="banner-section">
<view class="banner-content">
<view class="banner-left">
<view class="banner-icon">
<image src="/static/images/logo-white.png" mode="aspectFit" class="logo-img"></image>
</view>
</view>
<view class="banner-right">
<view class="chat-bubble">
<text class="bubble-title">我是鲸小智</text>
<text class="bubble-desc">您的专属旧改助理</text>
</view>
<view class="sparkle-group">
<text class="sparkle sparkle-1"></text>
<text class="sparkle sparkle-2"></text>
</view>
</view>
</view>
</view>
<!-- 搜索栏 -->
<view class="search-section">
<view class="search-bar">
<text class="iconfont icon-sousuo search-icon"></text>
<input
type="text"
class="search-input"
placeholder="搜索您想要的内容"
placeholder-class="search-placeholder"
v-model="searchText"
@confirm="handleSearch"
/>
<view class="chat-icon-wrapper">
<text class="iconfont icon-kefu chat-icon"></text>
</view>
</view>
</view>
<!-- AI设计 -->
<view class="grid-section">
<view class="section-header">
<view class="section-title-wrapper">
<text class="section-title">AI设计</text>
<text class="section-icon"></text>
</view>
<view class="section-more" @click="goToMore('design')">
<text>更多</text>
<text class="iconfont icon-xiangyou"></text>
</view>
</view>
<view class="grid-content">
<view
v-for="(item, index) in designTools"
:key="index"
class="grid-item"
@click="handleToolClick(item)"
>
<view class="item-icon-box" :class="item.bgClass">
<!-- 使用 emoji iconfont 作为临时图标 -->
<text class="item-emoji">{{ item.emoji }}</text>
</view>
<view class="item-info">
<text class="item-name">{{ item.name }}</text>
<text class="item-desc">{{ item.desc }}</text>
</view>
</view>
</view>
</view>
<!-- AI视频 -->
<view class="grid-section grid-section-bottom">
<view class="section-header">
<view class="section-title-wrapper">
<text class="section-title">AI视频</text>
<text class="section-icon"></text>
</view>
<view class="section-more" @click="goToMore('video')">
<text>更多</text>
<text class="iconfont icon-xiangyou"></text>
</view>
</view>
<view class="grid-content">
<view
v-for="(item, index) in videoTools"
:key="index"
class="grid-item"
@click="handleToolClick(item)"
>
<view class="item-icon-box" :class="item.bgClass">
<text class="item-emoji">{{ item.emoji }}</text>
</view>
<view class="item-info">
<text class="item-name">{{ item.name }}</text>
<text class="item-desc">{{ item.desc }}</text>
</view>
</view>
</view>
</view>
<!-- 底部占位 -->
<view class="bottom-placeholder"></view>
</scroll-view>
<!-- 底部导航栏 -->
<view class="bottom-tabbar">
<view
v-for="(tab, index) in tabs"
:key="index"
:class="['tab-item', currentTab === index ? 'active' : '']"
@click="switchTab(index)"
>
<!-- 想象图标 - 使用纯CSS绘制 -->
<view v-if="tab.name === '想象'" class="tab-icon-imagine">
<view class="snowflake">
<view class="snowflake-line snowflake-line-1"></view>
<view class="snowflake-line snowflake-line-2"></view>
<view class="snowflake-line snowflake-line-3"></view>
</view>
</view>
<!-- 字体图标 -->
<text v-else class="iconfont" :class="tab.icon"></text>
<text class="tab-label">{{ tab.name }}</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
statusBarHeight: 0,
scrollViewHeight: '100vh',
searchText: '',
currentTab: 2, // 默认为智能体
tabs: [
{ name: '推荐', icon: 'icon-shouye' },
{ name: '想象', icon: 'icon-faxian' },
{ name: '智能体', icon: 'icon-kefujiedai' },
{ name: '我的', icon: 'icon-wode' }
],
designTools: [
{ name: '一键设计', desc: '快速生成设计方案', emoji: '⚡', bgClass: 'bg-yellow', path: '/pages/ai-generate/design' },
{ name: '一句话设计', desc: '描述需求即刻生成', emoji: '💬', bgClass: 'bg-grey', path: '/pages/ai-generate/index' },
{ name: '毛坯装修', desc: '空间规划全屋设计', emoji: '🏗️', bgClass: 'bg-blue', path: '' },
{ name: '家具更换', desc: '智能替换家具单品', emoji: '🛋️', bgClass: 'bg-indigo', path: '' },
{ name: '局部修图', desc: '精准修改局部区域', emoji: '✂️', bgClass: 'bg-grey', path: '' },
{ name: '风格转换', desc: '一键切换装修风格', emoji: '🎨', bgClass: 'bg-orange', path: '' }
],
videoTools: [
{ name: '一句话生视频', desc: '描述想法即刻成片', emoji: '💬', bgClass: 'bg-blue-dark', path: '/pages/ai-generate/oneclick' },
{ name: '文生视频', desc: '文字描述生成视频', emoji: '📝', bgClass: 'bg-purple', path: '/pages/ai-generate/oneclick' },
{ name: '图生视频', desc: '图片一键生成视频', emoji: '🖼️', bgClass: 'bg-green', path: '/pages/ai-generate/oneclick?type=image' },
{ name: '智能分镜', desc: '自动规划视频镜头', emoji: '🎬', bgClass: 'bg-cyan', path: '' },
{ name: '视频延长', desc: '智能延长视频时长', emoji: '⏱️', bgClass: 'bg-pink', path: '' },
{ name: '自动配乐', desc: '智能匹配背景音乐', emoji: '🎵', bgClass: 'bg-teal', path: '' }
]
};
},
onLoad() {
const systemInfo = uni.getSystemInfoSync();
this.statusBarHeight = systemInfo.statusBarHeight || 0;
// 计算滚动区域高度 (tabbar height approx 50px)
const navHeight = 44; // Custom nav height
const tabBarHeight = 50;
this.scrollViewHeight = `calc(100vh - ${this.statusBarHeight + navHeight + tabBarHeight}px)`;
},
methods: {
goToMore(type) {
uni.showToast({
title: '查看全部功能',
icon: 'none'
});
},
handleSearch() {
if (this.searchText) {
uni.showToast({
title: '搜索功能开发中: ' + this.searchText,
icon: 'none'
});
}
},
handleToolClick(item) {
if (item.path) {
uni.navigateTo({
url: item.path,
fail: (err) => {
console.error('Navigate failed', err);
uni.showToast({ title: '功能开发中', icon: 'none' });
}
});
} else {
uni.showToast({
title: '功能即将上线',
icon: 'none'
});
}
},
switchTab(index) {
this.currentTab = index;
// Handle navigation if needed
if (index === 1) {
uni.navigateTo({ url: '/pages/ai-generate/inspiration' });
} else if (index === 3) {
uni.switchTab({ url: '/pages/user/index' });
} else if (index === 0) {
uni.switchTab({ url: '/pages/index/index' });
}
}
}
};
</script>
<style lang="scss" scoped>
.agent-container {
width: 100%;
height: 100vh;
background: #000000;
color: #ffffff;
display: flex;
flex-direction: column;
}
.nav-bar {
height: 44px;
display: flex;
align-items: center;
justify-content: center;
.nav-title {
font-size: 18px;
font-weight: 500;
color: #ffffff;
}
}
.main-content {
flex: 1;
padding: 0 16px;
box-sizing: border-box;
}
.banner-section {
margin: 16px 0 20px;
padding: 0 16px;
.banner-content {
background: linear-gradient(135deg, rgba(26, 60, 46, 0.4) 0%, rgba(20, 40, 32, 0.6) 100%);
border-radius: 20px;
padding: 16px;
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
border: 1px solid rgba(66, 202, 77, 0.15);
backdrop-filter: blur(10px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
.banner-left {
flex-shrink: 0;
.banner-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, rgba(66, 202, 77, 0.2) 0%, rgba(56, 176, 69, 0.3) 100%);
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(66, 202, 77, 0.2);
.logo-img {
width: 56px;
height: 56px;
}
}
}
.banner-right {
flex: 1;
display: flex;
align-items: center;
margin-left: 16px;
position: relative;
.chat-bubble {
flex: 1;
background: linear-gradient(135deg, rgba(66, 202, 77, 0.15) 0%, rgba(56, 176, 69, 0.1) 100%);
border: 1px solid rgba(66, 202, 77, 0.3);
border-radius: 16px;
padding: 12px 16px;
position: relative;
// 气泡尾巴
&::before {
content: '';
position: absolute;
left: -8px;
top: 50%;
transform: translateY(-50%);
width: 0;
height: 0;
border-style: solid;
border-width: 8px 8px 8px 0;
border-color: transparent rgba(66, 202, 77, 0.3) transparent transparent;
}
&::after {
content: '';
position: absolute;
left: -6px;
top: 50%;
transform: translateY(-50%);
width: 0;
height: 0;
border-style: solid;
border-width: 7px 7px 7px 0;
border-color: transparent rgba(66, 202, 77, 0.15) transparent transparent;
}
.bubble-title {
display: block;
font-size: 15px;
font-weight: 600;
color: #ffffff;
margin-bottom: 4px;
line-height: 1.3;
}
.bubble-desc {
display: block;
font-size: 13px;
color: rgba(255, 255, 255, 0.8);
line-height: 1.3;
}
}
.sparkle-group {
position: absolute;
top: -8px;
right: -8px;
display: flex;
gap: 4px;
.sparkle {
font-size: 20px;
animation: sparkle 2s ease-in-out infinite;
&.sparkle-1 {
animation-delay: 0s;
}
&.sparkle-2 {
animation-delay: 0.5s;
}
}
}
}
}
}
@keyframes sparkle {
0%, 100% {
opacity: 1;
transform: scale(1) rotate(0deg);
}
50% {
opacity: 0.6;
transform: scale(1.2) rotate(20deg);
}
}
.search-section {
margin-bottom: 24px;
.search-bar {
background: #1a1a1a;
border-radius: 24px;
height: 44px;
display: flex;
align-items: center;
padding: 0 16px;
.search-icon {
font-size: 18px;
color: #666;
margin-right: 8px;
}
.search-input {
flex: 1;
font-size: 14px;
color: #fff;
}
.search-placeholder {
color: #666;
}
.chat-icon-wrapper {
border-left: 1px solid #333;
padding-left: 12px;
margin-left: 8px;
.chat-icon {
font-size: 20px;
color: #42ca4d;
}
}
}
}
.grid-section-bottom {
margin-bottom: 80px !important;
}
.grid-section {
margin-bottom: 24px;
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
.section-title-wrapper {
display: flex;
align-items: center;
.section-title {
font-size: 16px;
font-weight: bold;
color: #ffffff;
margin-right: 6px;
}
.section-icon {
color: #42ca4d;
font-size: 14px;
}
}
.section-more {
display: flex;
align-items: center;
font-size: 12px;
color: #666;
.iconfont {
font-size: 12px;
margin-left: 2px;
}
}
}
.grid-content {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12px;
.grid-item {
background: #1a1a1a;
border-radius: 12px;
padding: 16px;
display: flex;
align-items: center;
.item-icon-box {
width: 40px;
height: 40px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
.item-emoji {
font-size: 20px;
}
&.bg-yellow { background: rgba(255, 193, 7, 0.1); }
&.bg-grey { background: rgba(158, 158, 158, 0.1); }
&.bg-blue { background: rgba(33, 150, 243, 0.1); }
&.bg-indigo { background: rgba(63, 81, 181, 0.1); }
&.bg-red { background: rgba(244, 67, 54, 0.1); }
&.bg-orange { background: rgba(255, 152, 0, 0.1); }
&.bg-blue-dark { background: rgba(13, 71, 161, 0.1); }
&.bg-purple { background: rgba(156, 39, 176, 0.1); }
&.bg-green { background: rgba(76, 175, 80, 0.1); }
&.bg-cyan { background: rgba(0, 188, 212, 0.1); }
&.bg-pink { background: rgba(233, 30, 99, 0.1); }
&.bg-teal { background: rgba(0, 150, 136, 0.1); }
}
.item-info {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.item-name {
font-size: 14px;
color: #fff;
margin-bottom: 4px;
font-weight: 500;
}
.item-desc {
font-size: 10px;
color: #666;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
}
.bottom-placeholder {
height: 20px;
}
// 底部导航栏
.bottom-tabbar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
height: calc(50px + env(safe-area-inset-bottom));
box-sizing: border-box;
align-items: center;
background: linear-gradient(180deg, rgba(20, 24, 34, 0.96) 0%, rgba(10, 12, 18, 0.98) 100%);
backdrop-filter: blur(20px);
border-top: 1px solid rgba(255, 255, 255, 0.06);
padding-bottom: env(safe-area-inset-bottom);
z-index: 999;
box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.35), 0 -12px 24px rgba(0, 0, 0, 0.25);
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(90deg, rgba(255,255,255,0.18), rgba(255,255,255,0.06), rgba(255,255,255,0.18));
opacity: 0.6;
pointer-events: none;
}
.tab-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2px;
border-radius: 12px;
padding: 2px 6px;
margin: 0px 20px;
transition: all 180ms ease;
position: relative;
.iconfont {
font-size: 22px;
color: #8f9bb3;
transition: color 180ms ease, transform 180ms ease, text-shadow 180ms ease;
}
.tab-icon-imagine {
width: 22px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.snowflake {
width: 22px;
height: 22px;
position: relative;
.snowflake-line {
position: absolute;
top: 50%;
left: 50%;
width: 18px;
height: 2px;
background: #8f9bb3;
transform-origin: center;
&::before,
&::after {
content: '';
position: absolute;
width: 6px;
height: 2px;
background: #8f9bb3;
}
&::before {
top: -4px;
left: 2px;
transform: rotate(-45deg);
}
&::after {
top: 4px;
left: 2px;
transform: rotate(45deg);
}
}
.snowflake-line-1 {
transform: translate(-50%, -50%) rotate(0deg);
}
.snowflake-line-2 {
transform: translate(-50%, -50%) rotate(60deg);
}
.snowflake-line-3 {
transform: translate(-50%, -50%) rotate(120deg);
}
}
}
.tab-label {
font-size: 10px;
color: #8f9bb3;
transition: color 180ms ease, text-shadow 180ms ease;
}
&.active {
background: radial-gradient(circle at 50% 20%, rgba(255,255,255,0.16) 0%, rgba(255,255,255,0.06) 42%, rgba(255,255,255,0) 60%),
linear-gradient(180deg, rgba(255,255,255,0.10) 0%, rgba(255,255,255,0.02) 100%);
box-shadow: inset 0 2px 6px rgba(255,255,255,0.12), 0 6px 12px rgba(0,0,0,0.35);
border: 1px solid rgba(255,255,255,0.08);
transform: translateY(-1px);
.iconfont,
.tab-label {
color: #42ca4d;
text-shadow: 0 0 8px rgba(66, 202, 77, 0.45);
}
.tab-icon-imagine {
.snowflake-line {
background: #42ca4d;
&::before,
&::after {
background: #42ca4d;
}
}
}
}
}
}
</style>