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

684 lines
18 KiB
Vue
Raw Normal View History

<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>