|
|
|
@ -2,12 +2,7 @@
|
|
|
|
|
<view class="debate-component">
|
|
|
|
|
<!-- 动态背景元素 -->
|
|
|
|
|
<view class="animated-bg">
|
|
|
|
|
<view
|
|
|
|
|
v-for="i in 6"
|
|
|
|
|
:key="i"
|
|
|
|
|
class="bg-circle"
|
|
|
|
|
:style="getRandomCircleStyle()"
|
|
|
|
|
></view>
|
|
|
|
|
<view v-for="i in 6" :key="i" class="bg-circle" :style="getRandomCircleStyle()"></view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 顶部卡片 - 可收缩 -->
|
|
|
|
@ -15,17 +10,12 @@
|
|
|
|
|
<view class="card-header" @click="toggleCard">
|
|
|
|
|
<view class="card-icon-wrapper">
|
|
|
|
|
<view class="card-icon">
|
|
|
|
|
<image
|
|
|
|
|
src="/static/icons/robot-2-line.png"
|
|
|
|
|
mode="aspectFit"
|
|
|
|
|
></image>
|
|
|
|
|
<image src="/static/icons/robot-2-line.png" mode="aspectFit"></image>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="card-text">
|
|
|
|
|
<view class="card-title">模拟辩论</view>
|
|
|
|
|
<view class="card-content" v-if="!isCardCollapsed"
|
|
|
|
|
>与AI进行实时辩论对练,提升应变能力</view
|
|
|
|
|
>
|
|
|
|
|
<view class="card-content" v-if="!isCardCollapsed">与AI进行实时辩论对练,提升应变能力</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="card-icon-wrapper">
|
|
|
|
|
<view class="card-icon" @click.stop="showHistory = true">
|
|
|
|
@ -33,14 +23,10 @@
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="collapse-icon">
|
|
|
|
|
<image
|
|
|
|
|
:src="
|
|
|
|
|
isCardCollapsed
|
|
|
|
|
? '/static/icons/arrow-down-s-line.png'
|
|
|
|
|
: '/static/icons/arrow-up-s-line.png'
|
|
|
|
|
"
|
|
|
|
|
mode="aspectFit"
|
|
|
|
|
></image>
|
|
|
|
|
<image :src="isCardCollapsed
|
|
|
|
|
? '/static/icons/arrow-down-s-line.png'
|
|
|
|
|
: '/static/icons/arrow-up-s-line.png'
|
|
|
|
|
" mode="aspectFit"></image>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
@ -48,32 +34,17 @@
|
|
|
|
|
<!-- 辩论主题选择器 -->
|
|
|
|
|
<view class="topic-selector" v-if="!isCardCollapsed">
|
|
|
|
|
<scroll-view scroll-x class="topic-scroll" show-scrollbar="false">
|
|
|
|
|
<view
|
|
|
|
|
v-for="(topic, idx) in debateTopics"
|
|
|
|
|
:key="idx"
|
|
|
|
|
:class="['topic-pill', { active: selectedTopic === idx }]"
|
|
|
|
|
@click="selectTopic(idx)"
|
|
|
|
|
>
|
|
|
|
|
<view v-for="(topic, idx) in debateTopics" :key="idx" :class="['topic-pill', { active: selectedTopic === idx }]"
|
|
|
|
|
@click="selectTopic(idx)">
|
|
|
|
|
{{ topic }}
|
|
|
|
|
</view>
|
|
|
|
|
</scroll-view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 聊天展示区 -->
|
|
|
|
|
<scroll-view
|
|
|
|
|
class="chat-area"
|
|
|
|
|
scroll-y
|
|
|
|
|
:scroll-into-view="scrollToView"
|
|
|
|
|
scroll-with-animation
|
|
|
|
|
>
|
|
|
|
|
<view
|
|
|
|
|
v-for="(msg, index) in messages"
|
|
|
|
|
:key="index"
|
|
|
|
|
:id="'msg' + index"
|
|
|
|
|
class="chat-message"
|
|
|
|
|
:class="msg.role === 'user' ? 'from-user' : 'from-ai'"
|
|
|
|
|
@longpress="onLongPress()"
|
|
|
|
|
>
|
|
|
|
|
<scroll-view class="chat-area" scroll-y :scroll-into-view="scrollToView" scroll-with-animation>
|
|
|
|
|
<view v-for="(msg, index) in messages" :key="index" :id="'msg' + index" class="chat-message"
|
|
|
|
|
:class="msg.role === 'user' ? 'from-user' : 'from-ai'" @longpress="onLongPress()">
|
|
|
|
|
<view class="avatar" v-if="msg.role === 'ai'">AI</view>
|
|
|
|
|
<view class="bubble">
|
|
|
|
|
<block v-if="msg.loading">
|
|
|
|
@ -91,22 +62,41 @@
|
|
|
|
|
</view>
|
|
|
|
|
</scroll-view>
|
|
|
|
|
|
|
|
|
|
<!-- 轮数选择与进度条区域 -->
|
|
|
|
|
<view class="rounds-control" :class="{ 'rounds-selected': debateRounds > 0 }">
|
|
|
|
|
<!-- 未选择轮数时,显示选择按钮 -->
|
|
|
|
|
<view v-if="roundsSelected === false" class="select-rounds-btn" @click="showRoundsPopup = true">
|
|
|
|
|
<image src="/static/icons/repeat-line.png" mode="aspectFit"></image>
|
|
|
|
|
<text>选择辩论轮数</text>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 已选择轮数时,显示进度条 -->
|
|
|
|
|
<view v-else class="rounds-selected-container">
|
|
|
|
|
<view class="rounds-label" @click="showRoundsPopup = true">
|
|
|
|
|
<image src="/static/icons/repeat-line.png" mode="aspectFit"></image>
|
|
|
|
|
<text>{{ debateRounds }}回合</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="progress-container">
|
|
|
|
|
<view class="progress-bar">
|
|
|
|
|
<view class="progress-inner" :style="{ width: progressPercentage + '%' }"></view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="rounds-counter">{{ currentRound }}/{{ debateRounds }}</view>
|
|
|
|
|
<!-- 添加复盘按钮 -->
|
|
|
|
|
<view v-if="showReviewButton" class="review-button" @click="showReviewModal">
|
|
|
|
|
<image src="/static/icons/file-chart-line.png" mode="aspectFit"></image>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 输入框与发送按钮 -->
|
|
|
|
|
<view class="chat-input">
|
|
|
|
|
<view class="input-group">
|
|
|
|
|
<view class="textarea-container">
|
|
|
|
|
<textarea
|
|
|
|
|
class="textarea-box"
|
|
|
|
|
v-model="content"
|
|
|
|
|
placeholder="输入你的辩论观点,与AI进行思辨交锋"
|
|
|
|
|
auto-height
|
|
|
|
|
maxlength="1000"
|
|
|
|
|
/>
|
|
|
|
|
<textarea class="textarea-box" v-model="content" placeholder="输入你的辩论观点,与AI进行思辨交锋" auto-height
|
|
|
|
|
maxlength="1000" />
|
|
|
|
|
<button class="send-button-embedded" @click="sendMessage()">
|
|
|
|
|
<image
|
|
|
|
|
src="/static/icons/send-plane-fill.png"
|
|
|
|
|
mode="aspectFit"
|
|
|
|
|
></image>
|
|
|
|
|
<image src="/static/icons/send-plane-fill.png" mode="aspectFit"></image>
|
|
|
|
|
</button>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
@ -115,22 +105,59 @@
|
|
|
|
|
<!-- 底部安全区域 -->
|
|
|
|
|
<view class="safe-area-bottom"></view>
|
|
|
|
|
|
|
|
|
|
<Popup
|
|
|
|
|
:visible="showSheet"
|
|
|
|
|
buttonText="开始复盘"
|
|
|
|
|
buttonIcon="🧠"
|
|
|
|
|
@close="showSheet = false"
|
|
|
|
|
@click="handleSheetClick"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<ConversationHistory
|
|
|
|
|
:visible="showHistory"
|
|
|
|
|
:history-list="chatHistory"
|
|
|
|
|
:type="1"
|
|
|
|
|
@update:visible="showHistory = $event"
|
|
|
|
|
@select="handleSelect"
|
|
|
|
|
@createNew="createNew"
|
|
|
|
|
/>
|
|
|
|
|
<Popup :visible="showSheet" buttonText="开始复盘" buttonIcon="🧠" @close="showSheet = false"
|
|
|
|
|
@click="handleSheetClick" />
|
|
|
|
|
|
|
|
|
|
<!-- 轮数选择弹窗 -->
|
|
|
|
|
<view v-if="showRoundsPopup" class="rounds-popup-mask" @click="showRoundsPopup = false">
|
|
|
|
|
<view class="rounds-popup" @click.stop>
|
|
|
|
|
<view class="popup-header">
|
|
|
|
|
<view class="popup-title">选择辩论轮数</view>
|
|
|
|
|
<view class="close-icon" @click="showRoundsPopup = false">
|
|
|
|
|
<image src="/static/icons/close-line.png" mode="aspectFit"></image>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<view class="rounds-options">
|
|
|
|
|
<view class="round-option" :class="{ selected: selectedOption === 1 }" @click="selectRounds(1)">
|
|
|
|
|
<view class="option-icon">⚡</view>
|
|
|
|
|
<view class="option-text">
|
|
|
|
|
<view class="option-title">快速交锋</view>
|
|
|
|
|
<view class="option-desc">10回合 · 适合快速练习</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="round-option" :class="{ selected: selectedOption === 2 }" @click="selectRounds(2)">
|
|
|
|
|
<view class="option-icon">🔍</view>
|
|
|
|
|
<view class="option-text">
|
|
|
|
|
<view class="option-title">深度辩论</view>
|
|
|
|
|
<view class="option-desc">20回合 · 深入探讨话题</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<button class="confirm-button-selectRounds" @click="confirmRounds">开始辩论</button>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 复盘确认弹窗 -->
|
|
|
|
|
<view v-if="showReviewConfirm" class="review-confirm-mask" @click="showReviewConfirm = false">
|
|
|
|
|
<view class="review-confirm-popup" @click.stop>
|
|
|
|
|
<view class="popup-header">
|
|
|
|
|
<view class="popup-title">辩论完成</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="popup-content">
|
|
|
|
|
<text>辩论已完成{{ debateRounds }}回合,是否立即进行复盘分析?</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="popup-buttons">
|
|
|
|
|
<button class="cancel-button" @click="showReviewConfirm = false">稍后再说</button>
|
|
|
|
|
<button class="confirm-button-gotoReview" @click="startReview">立即复盘</button>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<ConversationHistory :visible="showHistory" :history-list="chatHistory" :type="1"
|
|
|
|
|
@update:visible="showHistory = $event" @select="handleSelect" @createNew="createNew" />
|
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
@ -142,7 +169,7 @@ import ConversationHistory from "./ConversationHistory.vue";
|
|
|
|
|
import { useTokenStore } from "../stores/tokenStore";
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
components: { Popup,ConversationHistory },
|
|
|
|
|
components: { Popup, ConversationHistory },
|
|
|
|
|
props: {
|
|
|
|
|
argument: {
|
|
|
|
|
type: Object,
|
|
|
|
@ -152,13 +179,16 @@ export default {
|
|
|
|
|
mounted() {
|
|
|
|
|
const pinia = this.$pinia;
|
|
|
|
|
const store = useArgumentStore(pinia);
|
|
|
|
|
if(store.selectedArgument.content)this.content = store.selectedArgument.content;
|
|
|
|
|
if (store.selectedArgument.content) this.content = store.selectedArgument.content;
|
|
|
|
|
|
|
|
|
|
this.getHistoryList();
|
|
|
|
|
this.conversationId = useDebateStore().conversationId;
|
|
|
|
|
console.log("conversationId:", this.conversationId);
|
|
|
|
|
|
|
|
|
|
this.messages = useDebateStore().conversation;
|
|
|
|
|
|
|
|
|
|
// 页面加载时显示轮数选择弹窗
|
|
|
|
|
this.showRoundsPopup = true;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
data() {
|
|
|
|
@ -167,8 +197,8 @@ export default {
|
|
|
|
|
showHistory: false,
|
|
|
|
|
chatHistory: ["test1", "test2"],
|
|
|
|
|
|
|
|
|
|
showSheet:false,
|
|
|
|
|
StoreHistory:"",
|
|
|
|
|
showSheet: false,
|
|
|
|
|
StoreHistory: "",
|
|
|
|
|
input: "",
|
|
|
|
|
messages: [
|
|
|
|
|
{
|
|
|
|
@ -189,8 +219,39 @@ export default {
|
|
|
|
|
],
|
|
|
|
|
selectedTopic: -1,
|
|
|
|
|
isCardCollapsed: false, // 控制卡片是否收缩
|
|
|
|
|
|
|
|
|
|
// 新增辩论轮数相关数据
|
|
|
|
|
showRoundsPopup: false, // 控制弹窗显示
|
|
|
|
|
roundsSelected: false, // 是否已选择轮数
|
|
|
|
|
debateRounds: 0, // 辩论轮数
|
|
|
|
|
currentRound: 0, // 当前轮数
|
|
|
|
|
selectedOption: 0, // 选中的轮数选项
|
|
|
|
|
|
|
|
|
|
showReviewConfirm: false,// 控制复盘确认弹窗
|
|
|
|
|
showReviewButton: false,// 控制是否显示复盘按钮
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
computed: {
|
|
|
|
|
// 计算进度条的百分比
|
|
|
|
|
progressPercentage() {
|
|
|
|
|
if (this.debateRounds === 0) return 0;
|
|
|
|
|
return (this.currentRound / this.debateRounds) * 100;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
watch: {
|
|
|
|
|
//监听当前轮数变化
|
|
|
|
|
currentRound(newVal) {
|
|
|
|
|
if (newVal >= this.debateRounds && this.debateRounds > 0) {
|
|
|
|
|
// 延迟显示弹窗,让用户看到最后一条消息
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
this.showReviewConfirm = true;
|
|
|
|
|
}, 1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
|
async getHistoryList() {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
@ -263,15 +324,15 @@ export default {
|
|
|
|
|
success: (res) => {
|
|
|
|
|
console.log("res:", res);
|
|
|
|
|
if (res.statusCode === 200 && res.data.code === 200) {
|
|
|
|
|
this.messages=[];
|
|
|
|
|
for(let item of res.data.data){
|
|
|
|
|
this.messages = [];
|
|
|
|
|
for (let item of res.data.data) {
|
|
|
|
|
this.messages.push({
|
|
|
|
|
role:"user",
|
|
|
|
|
content:item.userMessage
|
|
|
|
|
role: "user",
|
|
|
|
|
content: item.userMessage
|
|
|
|
|
});
|
|
|
|
|
this.messages.push({
|
|
|
|
|
role:"ai",
|
|
|
|
|
content:item.content
|
|
|
|
|
role: "ai",
|
|
|
|
|
content: item.content
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
useDebateStore().setConversation(this.messages);
|
|
|
|
@ -353,6 +414,28 @@ export default {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async sendMessage() {
|
|
|
|
|
//------
|
|
|
|
|
// 检查是否选择轮数
|
|
|
|
|
if (!this.roundsSelected) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
title: "请选择辩论轮数",
|
|
|
|
|
icon: "none",
|
|
|
|
|
duration: 2000,
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否达到最大轮数
|
|
|
|
|
if (this.currentRound >= this.debateRounds) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
title: "辩论轮数已达上限",
|
|
|
|
|
icon: "none",
|
|
|
|
|
duration: 2000,
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//--------
|
|
|
|
|
|
|
|
|
|
if (!this.content.trim()) return;
|
|
|
|
|
|
|
|
|
|
// 添加用户消息
|
|
|
|
@ -388,6 +471,24 @@ export default {
|
|
|
|
|
// 替换 loading 消息为真实 AI 回答
|
|
|
|
|
this.messages.splice(aiIndex, 1, { role: "ai", content: reply });
|
|
|
|
|
this.scrollToBottom();
|
|
|
|
|
|
|
|
|
|
//-----------辩论轮数设置-----------
|
|
|
|
|
// 增加当前轮数
|
|
|
|
|
this.currentRound++;
|
|
|
|
|
|
|
|
|
|
// 检查是否到达最大轮数
|
|
|
|
|
if (this.currentRound >= this.debateRounds) {
|
|
|
|
|
this.messages.push({
|
|
|
|
|
role: "ai",
|
|
|
|
|
content: `本轮辩论已完成(${this.debateRounds}回合)。您可以点击消息进行复盘分析。`,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (this.currentRound >= this.debateRounds) {
|
|
|
|
|
// 显示复盘按钮
|
|
|
|
|
this.showReviewButton = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async callAI(history, content) {
|
|
|
|
@ -446,6 +547,82 @@ export default {
|
|
|
|
|
this.scrollToView = "msg" + (this.messages.length - 1);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
//------------
|
|
|
|
|
// 选择轮数类型
|
|
|
|
|
selectRounds(type) {
|
|
|
|
|
this.selectedOption = type;
|
|
|
|
|
},
|
|
|
|
|
// 确定轮数选择
|
|
|
|
|
confirmRounds() {
|
|
|
|
|
if (this.selectedOption === 0) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
title: '请选择轮数',
|
|
|
|
|
icon: 'none',
|
|
|
|
|
duration: 2000
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 已选择轮数
|
|
|
|
|
if (this.roundsSelected) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
title: '已选择轮数',
|
|
|
|
|
icon: 'none',
|
|
|
|
|
duration: 2000
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//设置轮数
|
|
|
|
|
if (this.selectedOption === 1) {
|
|
|
|
|
this.debateRounds = 10;
|
|
|
|
|
} else if (this.selectedOption === 2) {
|
|
|
|
|
this.debateRounds = 20;
|
|
|
|
|
}
|
|
|
|
|
this.currentRound = 0;
|
|
|
|
|
this.roundsSelected = true;
|
|
|
|
|
this.showRoundsPopup = false;
|
|
|
|
|
this.showReviewButton = false;
|
|
|
|
|
this.showReviewConfirm = false;
|
|
|
|
|
|
|
|
|
|
// 更新系统信息
|
|
|
|
|
this.message = [{
|
|
|
|
|
role: 'ai',
|
|
|
|
|
content: `已选择 ${this.debateRounds} 回合辩论!请分享你的观点,我们开始吧!`
|
|
|
|
|
}];
|
|
|
|
|
this.scrollToBottom();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 开始复盘
|
|
|
|
|
startReview() {
|
|
|
|
|
// // 收集所有消息
|
|
|
|
|
// let history = this.messages
|
|
|
|
|
// .filter((msg) => !msg.loading)
|
|
|
|
|
// .map((msg) => {
|
|
|
|
|
// if (msg.role === 'user') {
|
|
|
|
|
// return '用户:${ msg.content}';
|
|
|
|
|
// } else if (msg.role === 'ai') {
|
|
|
|
|
// return 'AI :${ msg.content}';
|
|
|
|
|
// }
|
|
|
|
|
// return '';
|
|
|
|
|
// }).join('\n');
|
|
|
|
|
//
|
|
|
|
|
// //存储到store
|
|
|
|
|
// const pinia = this.$pinia;
|
|
|
|
|
// const store = useDebateStore(pinia);
|
|
|
|
|
// store.setDebate(history);
|
|
|
|
|
// // 通知父组件切换到复盘界面
|
|
|
|
|
// this.$emit('tab-change', 3);
|
|
|
|
|
this.onLongPress();
|
|
|
|
|
// 关闭弹窗
|
|
|
|
|
this.showReviewConfirm = false;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 显示复盘弹窗
|
|
|
|
|
showReviewModal() {
|
|
|
|
|
this.showReviewConfirm = true;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
@ -460,7 +637,8 @@ export default {
|
|
|
|
|
background: linear-gradient(135deg, #4338ca 0%, #7c3aed 100%);
|
|
|
|
|
overflow-x: hidden;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
padding-bottom: 180rpx; /* 为底部TabBar留出空间 */
|
|
|
|
|
padding-bottom: 180rpx;
|
|
|
|
|
/* 为底部TabBar留出空间 */
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -478,11 +656,9 @@ export default {
|
|
|
|
|
.bg-circle {
|
|
|
|
|
position: absolute;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
background: linear-gradient(
|
|
|
|
|
135deg,
|
|
|
|
|
rgba(255, 255, 255, 0.05),
|
|
|
|
|
rgba(255, 255, 255, 0.02)
|
|
|
|
|
);
|
|
|
|
|
background: linear-gradient(135deg,
|
|
|
|
|
rgba(255, 255, 255, 0.05),
|
|
|
|
|
rgba(255, 255, 255, 0.02));
|
|
|
|
|
animation: float 20s infinite ease-in-out;
|
|
|
|
|
opacity: 0.4;
|
|
|
|
|
/* 添加过渡效果 */
|
|
|
|
@ -490,16 +666,20 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes float {
|
|
|
|
|
|
|
|
|
|
0%,
|
|
|
|
|
100% {
|
|
|
|
|
transform: translate(0, 0) scale(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
25% {
|
|
|
|
|
transform: translate(5%, 10%) scale(1.05);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
50% {
|
|
|
|
|
transform: translate(10%, 5%) scale(0.95);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
75% {
|
|
|
|
|
transform: translate(5%, 15%) scale(1.1);
|
|
|
|
|
}
|
|
|
|
@ -552,6 +732,7 @@ export default {
|
|
|
|
|
opacity: 0;
|
|
|
|
|
transform: translateY(-30rpx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
to {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
transform: translateY(0);
|
|
|
|
@ -588,12 +769,10 @@ export default {
|
|
|
|
|
left: -50%;
|
|
|
|
|
width: 200%;
|
|
|
|
|
height: 200%;
|
|
|
|
|
background: linear-gradient(
|
|
|
|
|
to bottom right,
|
|
|
|
|
rgba(255, 255, 255, 0) 0%,
|
|
|
|
|
rgba(255, 255, 255, 0.1) 50%,
|
|
|
|
|
rgba(255, 255, 255, 0) 100%
|
|
|
|
|
);
|
|
|
|
|
background: linear-gradient(to bottom right,
|
|
|
|
|
rgba(255, 255, 255, 0) 0%,
|
|
|
|
|
rgba(255, 255, 255, 0.1) 50%,
|
|
|
|
|
rgba(255, 255, 255, 0) 100%);
|
|
|
|
|
transform: rotate(45deg);
|
|
|
|
|
animation: shine 3s infinite;
|
|
|
|
|
}
|
|
|
|
@ -602,6 +781,7 @@ export default {
|
|
|
|
|
0% {
|
|
|
|
|
transform: translateX(-100%) rotate(45deg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
20%,
|
|
|
|
|
100% {
|
|
|
|
|
transform: translateX(100%) rotate(45deg);
|
|
|
|
@ -708,6 +888,7 @@ export default {
|
|
|
|
|
opacity: 0;
|
|
|
|
|
transform: translateY(20rpx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
to {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
transform: translateY(0);
|
|
|
|
@ -754,7 +935,8 @@ export default {
|
|
|
|
|
word-break: break-word;
|
|
|
|
|
box-shadow: 0 4rpx 15rpx rgba(0, 0, 0, 0.1);
|
|
|
|
|
position: relative;
|
|
|
|
|
transition: all 0.3s ease; /* 添加过渡效果 */
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
/* 添加过渡效果 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.from-user .bubble {
|
|
|
|
@ -773,7 +955,8 @@ export default {
|
|
|
|
|
height: 0;
|
|
|
|
|
border-left: 16rpx solid #f59e0b;
|
|
|
|
|
border-top: 16rpx solid transparent;
|
|
|
|
|
transition: all 0.3s ease; /* 添加过渡效果 */
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
/* 添加过渡效果 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.from-ai .bubble {
|
|
|
|
@ -792,7 +975,8 @@ export default {
|
|
|
|
|
height: 0;
|
|
|
|
|
border-right: 16rpx solid rgba(255, 255, 255, 0.2);
|
|
|
|
|
border-top: 16rpx solid transparent;
|
|
|
|
|
transition: all 0.3s ease; /* 添加过渡效果 */
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
/* 添加过渡效果 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 加载动画 */
|
|
|
|
@ -821,16 +1005,144 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes bounce {
|
|
|
|
|
|
|
|
|
|
0%,
|
|
|
|
|
80%,
|
|
|
|
|
100% {
|
|
|
|
|
transform: scale(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
40% {
|
|
|
|
|
transform: scale(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 轮数控制区域 ------------------------*/
|
|
|
|
|
.rounds-control {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 20rpx 30rpx;
|
|
|
|
|
background: rgba(255, 255, 255, 0.15);
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
margin: 0 auto 20rpx;
|
|
|
|
|
backdrop-filter: blur(10px);
|
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
|
|
|
animation: slideUp 0.4s ease-out;
|
|
|
|
|
width: 70%;
|
|
|
|
|
transition: all 0.5s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@keyframes slideUp {
|
|
|
|
|
from {
|
|
|
|
|
opacity: 0;
|
|
|
|
|
transform: translateY(30rpx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
to {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
transform: translateY(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 选择轮数按钮样式 */
|
|
|
|
|
.select-rounds-btn {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
width: 100%;
|
|
|
|
|
padding: 20rpx;
|
|
|
|
|
background: rgba(104, 57, 224, 0.3);
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
color: white;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.select-rounds-btn image {
|
|
|
|
|
width: 30rpx;
|
|
|
|
|
height: 30rpx;
|
|
|
|
|
margin-right: 10rpx;
|
|
|
|
|
filter: brightness(0) invert(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.rounds-selected-container {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
width: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.rounds-label {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 10rpx 20rpx;
|
|
|
|
|
background: rgba(104, 57, 224, 0.3);
|
|
|
|
|
border-radius: 12rpx;
|
|
|
|
|
margin-right: 20rpx;
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
color: white;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
min-width: 140rpx;
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
margin-right: 20rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.rounds-label image {
|
|
|
|
|
width: 30rpx;
|
|
|
|
|
height: 30rpx;
|
|
|
|
|
margin-right: 10rpx;
|
|
|
|
|
filter: brightness(0) invert(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.progress-container {
|
|
|
|
|
flex: 1;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.progress-bar {
|
|
|
|
|
flex: 1;
|
|
|
|
|
height: 16rpx;
|
|
|
|
|
background: rgba(255, 255, 255, 0.2);
|
|
|
|
|
border-radius: 8rpx;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
margin-right: 20rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 进度条动画 */
|
|
|
|
|
.progress-inner {
|
|
|
|
|
height: 100%;
|
|
|
|
|
background: linear-gradient(90deg, #f59e0b, #fcd34d);
|
|
|
|
|
border-radius: 8rpx;
|
|
|
|
|
transition: width 0.5s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 进度条加载动画 */
|
|
|
|
|
@keyframes progress-grow {
|
|
|
|
|
from {
|
|
|
|
|
width: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
to {
|
|
|
|
|
width: v-bind('progressPercentage + "%"');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.progress-inner {
|
|
|
|
|
animation: progress-grow 0.8s ease-out forwards;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.rounds-counter {
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: white;
|
|
|
|
|
min-width: 80rpx;
|
|
|
|
|
text-align: center;
|
|
|
|
|
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 输入区域 */
|
|
|
|
|
.chat-input {
|
|
|
|
|
display: flex;
|
|
|
|
@ -847,13 +1159,15 @@ export default {
|
|
|
|
|
.textarea-box {
|
|
|
|
|
background: rgba(255, 255, 255, 0.2);
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
padding: 16rpx 20rpx 16rpx 90rpx; /* 增加左侧内边距为发送按钮留出空间 */
|
|
|
|
|
padding: 16rpx 20rpx 16rpx 90rpx;
|
|
|
|
|
/* 增加左侧内边距为发送按钮留出空间 */
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
|
|
|
transition: all 0.3s;
|
|
|
|
|
min-height: 70rpx;
|
|
|
|
|
max-height: 180rpx; /* 限制最大高度 */
|
|
|
|
|
max-height: 180rpx;
|
|
|
|
|
/* 限制最大高度 */
|
|
|
|
|
width: 100%;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
@ -923,14 +1237,252 @@ export default {
|
|
|
|
|
.send-button-embedded image {
|
|
|
|
|
width: 40rpx;
|
|
|
|
|
height: 40rpx;
|
|
|
|
|
filter: invert(72%) sepia(87%) saturate(1242%) hue-rotate(325deg)
|
|
|
|
|
brightness(101%) contrast(96%);
|
|
|
|
|
filter: invert(72%) sepia(87%) saturate(1242%) hue-rotate(325deg) brightness(101%) contrast(96%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 底部安全区域 */
|
|
|
|
|
.safe-area-bottom {
|
|
|
|
|
height: 20rpx;
|
|
|
|
|
height: calc(20rpx + constant(safe-area-inset-bottom)); /* iOS 11.0-11.2 */
|
|
|
|
|
height: calc(20rpx + env(safe-area-inset-bottom)); /* iOS 11.2+ */
|
|
|
|
|
height: calc(20rpx + constant(safe-area-inset-bottom));
|
|
|
|
|
/* iOS 11.0-11.2 */
|
|
|
|
|
height: calc(20rpx + env(safe-area-inset-bottom));
|
|
|
|
|
/* iOS 11.2+ */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 轮数选择弹窗样式 */
|
|
|
|
|
.rounds-popup-mask {
|
|
|
|
|
position: fixed;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
background: rgba(0, 0, 0, 0.6);
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
z-index: 1000;
|
|
|
|
|
animation: fadeIn 0.3s ease-out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes fadeIn {
|
|
|
|
|
from {
|
|
|
|
|
opacity: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
to {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.rounds-popup {
|
|
|
|
|
width: 80%;
|
|
|
|
|
max-width: 600rpx;
|
|
|
|
|
background: white;
|
|
|
|
|
border-radius: 28rpx;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.3);
|
|
|
|
|
animation: scaleIn 0.3s ease-out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes scaleIn {
|
|
|
|
|
from {
|
|
|
|
|
transform: scale(0.9);
|
|
|
|
|
opacity: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
to {
|
|
|
|
|
transform: scale(1);
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.popup-header {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 30rpx;
|
|
|
|
|
background: #7C3AED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.popup-title {
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
color: white;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.close-icon {
|
|
|
|
|
width: 50rpx;
|
|
|
|
|
height: 50rpx;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
background: rgba(255, 255, 255, 0.2);
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.close-icon image {
|
|
|
|
|
width: 30rpx;
|
|
|
|
|
height: 30rpx;
|
|
|
|
|
filter: brightness(0) invert(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.rounds-options {
|
|
|
|
|
padding: 30rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.round-option {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 30rpx;
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
background: #f8f9ff;
|
|
|
|
|
border: 2rpx solid #e6e6ff;
|
|
|
|
|
margin-bottom: 25rpx;
|
|
|
|
|
transition: all 0.3s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.round-option.selected {
|
|
|
|
|
background: #6839E0;
|
|
|
|
|
border-color: #6839E0;
|
|
|
|
|
transform: translateY(-5rpx);
|
|
|
|
|
box-shadow: 0 8rpx 20rpx rgba(104, 57, 224, 0.3);
|
|
|
|
|
width: auto;
|
|
|
|
|
margin: 0 30rpx 20rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.option-icon {
|
|
|
|
|
font-size: 50rpx;
|
|
|
|
|
margin-right: 25rpx;
|
|
|
|
|
width: 80rpx;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.round-option.selected .option-icon {
|
|
|
|
|
color: white;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.option-title {
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
margin-bottom: 8rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.option-desc {
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
color: #666;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.round-option.selected .option-title,
|
|
|
|
|
.round-option.selected .option-desc {
|
|
|
|
|
color: white;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.confirm-button-selectRounds {
|
|
|
|
|
background: #6839E0;
|
|
|
|
|
color: white;
|
|
|
|
|
border-radius: 0;
|
|
|
|
|
height: 100rpx;
|
|
|
|
|
line-height: 100rpx;
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
border: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 复盘确认弹窗样式 */
|
|
|
|
|
.review-confirm-mask {
|
|
|
|
|
position: fixed;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
background: rgba(0, 0, 0, 0.6);
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
z-index: 2000;
|
|
|
|
|
animation: fadeIn 0.3s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.review-confirm-popup {
|
|
|
|
|
width: 80%;
|
|
|
|
|
max-width: 600rpx;
|
|
|
|
|
background: white;
|
|
|
|
|
border-radius: 28rpx;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.popup-header {
|
|
|
|
|
padding: 30rpx;
|
|
|
|
|
background: #7C3AED;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.popup-title {
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
color: white;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.popup-content {
|
|
|
|
|
padding: 40rpx 30rpx;
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
color: #333;
|
|
|
|
|
text-align: center;
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.popup-buttons {
|
|
|
|
|
display: flex;
|
|
|
|
|
padding: 20rpx;
|
|
|
|
|
border-top: 1rpx solid #eee;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.cancel-button {
|
|
|
|
|
flex: 1;
|
|
|
|
|
background: #f5f5f5;
|
|
|
|
|
color: #666;
|
|
|
|
|
border-radius: 12rpx;
|
|
|
|
|
margin-right: 15rpx;
|
|
|
|
|
height: 80rpx;
|
|
|
|
|
line-height: 80rpx;
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.confirm-button-gotoReview {
|
|
|
|
|
flex: 1;
|
|
|
|
|
background: #6839E0;
|
|
|
|
|
color: white;
|
|
|
|
|
border-radius: 12rpx;
|
|
|
|
|
margin-left: 15rpx;
|
|
|
|
|
height: 80rpx;
|
|
|
|
|
line-height: 80rpx;
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 复盘按钮样式 */
|
|
|
|
|
.review-button {
|
|
|
|
|
width: 50rpx;
|
|
|
|
|
height: 50rpx;
|
|
|
|
|
margin-left: 20rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
background: rgba(255, 255, 255, 0.2);
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
padding: 8rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.review-button image {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
filter: brightness(0) invert(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 调整进度条容器布局 */
|
|
|
|
|
.progress-container {
|
|
|
|
|
flex: 1;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|