@@ -36,66 +30,41 @@
{{ msg.content }}
- 💡 {{ msg.error }}
+ {{ msg.error }}
-
🤖
-
+
+
+
+
{{ getSchemeLabel(i) }}
+
{{ scheme.name }}
+
~{{ scheme.totalKm }}km {{ scheme.totalDriveTime }}h {{ scheme.days }}天 {{ scheme.budget }}
+
选择此方案进入工作台
+
+
+
-
@@ -120,6 +89,10 @@ const scrollToBottom = async () => {
}
}
+function getSchemeLabel(i) {
+ return String.fromCharCode(65 + (i % 26))
+}
+
const sendMessage = async () => {
if (!inputText.value.trim() || isGenerating.value) return
@@ -136,31 +109,27 @@ const sendMessage = async () => {
let thinkingContent = ''
const result = await chatWithAI(userMsg, (streamContent) => {
- // Parse streaming content for thinking
thinkingContent = streamContent
- // Update thinking status based on progress
if (streamContent.includes('thinking')) {
- thinkingStatus.value = '🧠 AI 正在思考并搜索目的地信息...'
+ thinkingStatus.value = 'AI 正在思考并搜索目的地信息...'
} else if (streamContent.includes('schemes')) {
- thinkingStatus.value = '📋 正在生成旅行方案...'
+ thinkingStatus.value = '正在生成旅行方案...'
} else if (streamContent.includes('points')) {
- thinkingStatus.value = '📍 正在规划详细行程...'
+ thinkingStatus.value = '正在规划详细行程...'
}
})
isGenerating.value = false
- // Add bot response message with thinking process
const botMsg = {
role: 'bot',
- content: `已为你生成 ${result.schemes.length} 个方案,请查看下方卡片。\n\n${result.schemes.map((s, i) => `【方案${String.fromCharCode(65 + i)}】${s.name}\n路线:${s.route}\n${s.days}天 · ${s.totalKm}km · ${s.budget}`).join('\n\n')}`,
+ content: `已为你生成 ${result.schemes.length} 个方案,请查看下方卡片。\n\n${result.schemes.map((s, i) => `【${getSchemeLabel(i)}】${s.name}\n路线:${s.route}\n${s.days}天 \u00b7 ${s.totalKm}km \u00b7 ${s.budget}`).join('\n\n')}`,
thinking: result.thinking,
thinkingExpanded: false
}
messages.value.push(botMsg)
- // Set schemes for card display
schemes.value = result.schemes
await scrollToBottom()
@@ -171,7 +140,7 @@ const sendMessage = async () => {
role: 'bot',
content: '抱歉,生成方案时遇到了问题。',
error: error.message.includes('API Key')
- ? '请先访问 /settings 配置你的 AI API Key'
+ ? '请先访问设置页面配置你的 AI API Key'
: error.message + ',请重试'
})
await scrollToBottom()
@@ -182,7 +151,6 @@ const selectScheme = (index) => {
const scheme = schemes.value[index]
if (!scheme) return
- // Load the selected scheme into the itinerary store
store.loadFromAI(scheme)
store.setPhase('workbench')
}
@@ -192,75 +160,79 @@ const selectScheme = (index) => {
.chat-interface {
display: flex;
flex-direction: column;
- height: 100vh;
- background: #f5f5f5;
- position: relative;
+ height: calc(100vh - 130px);
+ max-width: 800px;
+ margin: 0 auto;
+ padding: 24px 32px;
}
-.chat-header {
- text-align: center;
- padding: 30px 20px;
- background: linear-gradient(135deg, #1b4332, #2d6a4f);
- color: #fff;
-}
-
-.chat-header h1 { margin: 0 0 8px; font-size: 24px; }
-.chat-header p { margin: 0; opacity: 0.8; font-size: 14px; }
-
-.chat-messages {
+.chat-msgs {
flex: 1;
overflow-y: auto;
- padding: 20px;
+ padding: 20px 0;
display: flex;
flex-direction: column;
- gap: 16px;
+ gap: 18px;
}
-.message {
+.chat-bubble {
display: flex;
- gap: 12px;
- max-width: 85%;
+ gap: 10px;
+ max-width: 75%;
}
-.message.bot { align-self: flex-start; }
-.message.user { align-self: flex-end; flex-direction: row-reverse; }
+.chat-bubble.bot { align-self: flex-start; }
+.chat-bubble.user { align-self: flex-end; flex-direction: row-reverse; }
-.avatar {
- width: 36px;
- height: 36px;
- border-radius: 50%;
+.cb-av {
+ width: 34px;
+ height: 34px;
+ border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
- font-size: 18px;
- background: #e8f5e9;
+ font-size: 16px;
flex-shrink: 0;
}
-.message.user .avatar { background: #e3f2fd; }
+.bot-av {
+ background: #e8e4ff;
+}
+
+.bot-av::before {
+ content: '🤖';
+}
+
+.user-av {
+ background: #d1fae5;
+}
-.bubble {
+.user-av::before {
+ content: '👤';
+}
+
+.cb-body {
padding: 12px 16px;
- border-radius: 16px;
+ border-radius: 14px;
font-size: 14px;
line-height: 1.6;
}
-.message.bot .bubble {
+.chat-bubble.bot .cb-body {
background: #fff;
- color: #333;
+ color: #2d3436;
border-bottom-left-radius: 4px;
+ box-shadow: 0 2px 6px rgba(0,0,0,0.04);
}
-.message.user .bubble {
- background: #2a9d8f;
+.chat-bubble.user .cb-body {
+ background: linear-gradient(135deg, #6c5ce7, #a29bfe);
color: #fff;
border-bottom-right-radius: 4px;
}
-.example {
- opacity: 0.8;
- font-size: 13px;
+.message-content {
+ white-space: pre-wrap;
}
/* Thinking process */
@@ -285,6 +257,10 @@ const selectScheme = (index) => {
.thinking-header:hover { background: #f0f0f0; }
+.thinking-icon::before {
+ content: '🧠';
+}
+
.thinking-toggle {
margin-left: auto;
font-size: 12px;
@@ -315,10 +291,6 @@ const selectScheme = (index) => {
color: #856404;
}
-.message-content {
- white-space: pre-wrap;
-}
-
/* Loading */
.thinking {
display: flex;
@@ -330,7 +302,7 @@ const selectScheme = (index) => {
width: 6px;
height: 6px;
border-radius: 50%;
- background: #2a9d8f;
+ background: #6c5ce7;
animation: pulse 1.4s infinite;
}
@@ -342,156 +314,122 @@ const selectScheme = (index) => {
40% { opacity: 1; transform: scale(1); }
}
-/* Input */
-.chat-input-area {
- display: flex;
- gap: 8px;
- padding: 16px 20px;
- background: #fff;
- border-top: 1px solid #eee;
-}
-
-.chat-input-area input {
- flex: 1;
- padding: 12px 16px;
- border: 1px solid #ddd;
- border-radius: 24px;
- font-size: 14px;
- outline: none;
- transition: border-color 0.2s;
-}
-
-.chat-input-area input:focus { border-color: #2a9d8f; }
-.chat-input-area input:disabled { background: #f5f5f5; cursor: not-allowed; }
-
-.chat-input-area button {
- padding: 12px 24px;
- background: #2a9d8f;
- color: #fff;
- border: none;
- border-radius: 24px;
- font-size: 14px;
- cursor: pointer;
- transition: background 0.2s;
-}
-
-.chat-input-area button:hover:not(:disabled) { background: #21867a; }
-.chat-input-area button:disabled { opacity: 0.5; cursor: not-allowed; }
-
/* Scheme cards */
-.scheme-cards {
- position: absolute;
- bottom: 80px;
- left: 20px;
- right: 20px;
- background: #fff;
- border-radius: 16px;
- padding: 20px;
- box-shadow: 0 -4px 20px rgba(0,0,0,0.1);
- max-height: 60vh;
- overflow-y: auto;
-}
-
-.scheme-cards h3 {
- margin: 0 0 16px;
- font-size: 16px;
- color: #1b4332;
-}
-
-.cards-grid {
+.chat-cards {
display: grid;
- grid-template-columns: repeat(3, 1fr);
+ grid-template-columns: 1fr 1fr;
gap: 12px;
+ padding: 16px 0;
}
-.scheme-card {
- border: 2px solid #e0e0e0;
+.cc {
+ background: #fff;
border-radius: 12px;
padding: 16px;
+ border: 1.5px solid #eee;
cursor: pointer;
transition: all 0.2s;
}
-.scheme-card:hover {
- border-color: #2a9d8f;
- transform: translateY(-2px);
- box-shadow: 0 4px 12px rgba(42,157,143,0.2);
+.cc:hover {
+ border-color: #6c5ce7;
}
-.card-header {
- display: flex;
- align-items: center;
- gap: 8px;
- margin-bottom: 12px;
-}
-
-.card-badge {
- background: #f4a261;
- color: #1b4332;
+.cc-badge {
+ font-size: 11px;
padding: 2px 8px;
border-radius: 4px;
- font-size: 11px;
+ background: #fff3e0;
+ color: #e17055;
font-weight: 600;
}
-.card-header h4 {
- margin: 0;
+.cc-badge.badge-b {
+ background: #e0f2fe;
+ color: #0984e3;
+}
+
+.cc h4 {
font-size: 14px;
- color: #333;
+ margin: 6px 0 4px;
+ color: #2d3436;
}
-.card-stats {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 4px;
- margin-bottom: 8px;
+.cc-meta {
font-size: 12px;
- color: #666;
+ color: #636e72;
}
-.card-highlights {
+.cc-link {
+ margin-top: 10px;
+ font-size: 12px;
+ color: #6c5ce7;
+ font-weight: 600;
+}
+
+/* Input */
+.chat-input-bar {
+ padding: 14px 0;
display: flex;
- flex-wrap: wrap;
- gap: 4px;
- margin-bottom: 8px;
+ gap: 10px;
}
-.highlight-tag {
- background: #e8f5e9;
- color: #2a9d8f;
- padding: 2px 8px;
- border-radius: 4px;
- font-size: 11px;
+.chat-input-bar input {
+ flex: 1;
+ padding: 12px 18px;
+ border: 1.5px solid #dfe6e9;
+ border-radius: 24px;
+ font-size: 14px;
+ outline: none;
+ transition: border 0.2s;
}
-.card-route {
- font-size: 11px;
- color: #888;
- margin-bottom: 12px;
- padding: 6px;
- background: #f8f9fa;
- border-radius: 6px;
+.chat-input-bar input:focus {
+ border-color: #6c5ce7;
}
-.card-action {
- text-align: center;
- color: #2a9d8f;
- font-weight: 600;
- font-size: 13px;
+.chat-input-bar input:disabled {
+ background: #f5f7fa;
+ cursor: not-allowed;
}
-.slide-up-enter-active, .slide-up-leave-active {
- transition: all 0.3s ease;
+.chat-input-bar button {
+ width: 44px;
+ height: 44px;
+ border-radius: 50%;
+ background: linear-gradient(135deg, #6c5ce7, #a29bfe);
+ color: #fff;
+ border: none;
+ cursor: pointer;
+ font-size: 16px;
+ transition: all 0.2s;
+}
+
+.chat-input-bar button:hover:not(:disabled) {
+ transform: translateY(-1px);
+ box-shadow: 0 4px 14px rgba(108,92,231,0.35);
+}
+
+.chat-input-bar button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
}
-.slide-up-enter-from, .slide-up-leave-to {
- transform: translateY(20px);
- opacity: 0;
+.chat-input-bar button::before {
+ content: '➤';
}
-@media (max-width: 900px) {
- .cards-grid {
+@media (max-width: 768px) {
+ .chat-interface {
+ padding: 16px;
+ }
+
+ .chat-cards {
grid-template-columns: 1fr;
}
+
+ .chat-bubble {
+ max-width: 90%;
+ }
}
diff --git a/src/components/CustomPlanPanel.vue b/src/components/CustomPlanPanel.vue
index 1137d38..9cbeac8 100644
--- a/src/components/CustomPlanPanel.vue
+++ b/src/components/CustomPlanPanel.vue
@@ -1,74 +1,57 @@
-