Commit 2223a16f authored by 姜耀祖's avatar 姜耀祖

前端代码修改

parent 89e233a0
Pipeline #21044 passed with stages
in 3 minutes and 6 seconds
...@@ -415,6 +415,194 @@ public class LangChainController { ...@@ -415,6 +415,194 @@ public class LangChainController {
.body(emitter); .body(emitter);
} }
@GetMapping("/sseBigTwo")
public ResponseEntity<SseEmitter> sseBigTwoTest(){
SseEmitter emitter = new SseEmitter(0L);
new Thread(() -> {
try {
// 模拟大模型分次生成回复
String[] chunks = {
"思考中...'}",
"你好!'}",
"这是流式'}",
"回复的演示'}",
"完整回答:关于\\\"氨基酸的活动阿\\\"的回复'}",
"是的教案设计'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}", "啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}", "啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}", "啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}", "啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}", "啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}",
"按实际到手的你'}",
"啊实打实的就按设你的'}",
"爱神的箭阿三电脑'}",
"按设计大奖十大'}"
};
for (String chunk : chunks) {
// 每次发送一个数据块
emitter.send(SseEmitter.event().data(chunk), MediaType.parseMediaType("application/json; charset=UTF-8"));
Thread.sleep(100);
}
emitter.send(SseEmitter.event().data("stop"),MediaType.parseMediaType("application/json; charset=UTF-8"));
} catch (IOException e) {
emitter.completeWithError(e); // 出错时关闭连接
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
return ResponseEntity.ok().header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_EVENT_STREAM_VALUE)
.body(emitter);
}
//调用大模型接口 //调用大模型接口
@GetMapping("/sseQwen") @GetMapping("/sseQwen")
......
...@@ -50,10 +50,11 @@ ...@@ -50,10 +50,11 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 中间聊天区域 -->
<div class="chat-wrapper"> <!-- 右侧聊天区域 -->
<div class="chat-container"> <div class="chat-area">
<!-- 消息历史区域 --> <!-- 消息历史区域 -->
<div id="scrollContainer" class="scrollContainer">
<div id="chat-messages" class="chat-messages"> <div id="chat-messages" class="chat-messages">
<div v-for="(message, index) in messages" <div v-for="(message, index) in messages"
:key="index" :key="index"
...@@ -66,19 +67,39 @@ ...@@ -66,19 +67,39 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- 输入区域 --> <!-- 输入区域 -->
<div class="input-area"> <div class="input-area">
<textarea id="user-input" v-model="userInput" placeholder="请输入您的问题..." rows="2"></textarea> <textarea id="user-input" v-model="userInput" placeholder="请输入您的问题 shift+enter换行" rows="3"></textarea>
<div class="input-area-content">
<div>
<div class="custom-select" v-click-outside="closeExpertDropdown">
<div class="selected-option" @click.stop="toggleExpertDropdown">
<span>{{ selectedExpert }}</span>
<svg class="dropdown-icon" :class="{ 'rotated': showExpertDropdown }" viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none">
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
</div>
<div class="dropdown-menu" v-show="showExpertDropdown">
<div class="dropdown-item" @click.stop="selectExpert('内部专家')" :class="{ 'active': selectedExpert === '内部专家' }">
<span>内部专家</span>
</div>
<div class="dropdown-item" @click.stop="selectExpert('外部专家')" :class="{ 'active': selectedExpert === '外部专家' }">
<span>外部专家</span>
</div>
</div>
</div>
</div>
<div>
<button id="send-btn" class="send-btn" @click="sendMessage" v-show="!isResponding"> <button id="send-btn" class="send-btn" @click="sendMessage" v-show="!isResponding">
<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" <svg class="send-icon" viewBox="0 0 24 24" width="18" height="18" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
stroke-linecap="round" stroke-linejoin="round" class="send-icon"> <line x1="12" y1="19" x2="12" y2="5"></line>
<line x1="22" y1="2" x2="11" y2="13"></line> <polyline points="5 12 12 5 19 12"></polyline>
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
</svg> </svg>
</button> </button>
<button id="stop-btn" class="stop-btn" @click="stopResponse" v-show="isResponding"> <button id="stop-btn" class="stop-btn" @click="stopResponse" v-show="isResponding">
<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" <svg viewBox="0 0 24 24" width="18" height="18" stroke="currentColor" stroke-width="2" fill="none"
stroke-linecap="round" stroke-linejoin="round" class="stop-icon"> stroke-linecap="round" stroke-linejoin="round" class="stop-icon">
<rect x="6" y="6" width="12" height="12" rx="2" ry="2"></rect> <rect x="6" y="6" width="12" height="12" rx="2" ry="2"></rect>
</svg> </svg>
...@@ -86,6 +107,7 @@ ...@@ -86,6 +107,7 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</div> </div>
<script type="text/javascript" src="../../libs/require.js/require.min.js"></script> <script type="text/javascript" src="../../libs/require.js/require.min.js"></script>
<script type="text/javascript" src="../../scripts/require-config.js"></script> <script type="text/javascript" src="../../scripts/require-config.js"></script>
......
...@@ -2,6 +2,21 @@ ...@@ -2,6 +2,21 @@
* AI聊天页面Vue应用 * AI聊天页面Vue应用
*/ */
require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils, echarts) { require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils, echarts) {
// 添加点击外部关闭指令
Vue.directive('click-outside', {
bind: function (el, binding, vnode) {
el.clickOutsideEvent = function (event) {
if (!(el == event.target || el.contains(event.target))) {
vnode.context[binding.expression](event);
}
};
document.body.addEventListener('click', el.clickOutsideEvent);
},
unbind: function (el) {
document.body.removeEventListener('click', el.clickOutsideEvent);
}
});
const app = new Vue({ const app = new Vue({
el: '#app', el: '#app',
data: { data: {
...@@ -18,6 +33,10 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils ...@@ -18,6 +33,10 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils
isResponding: false, isResponding: false,
userInput: "", userInput: "",
// 专家选择相关数据
selectedExpert: '内部专家',
showExpertDropdown: false,
// 历史对话分类 // 历史对话分类
historySections: [ historySections: [
{ {
...@@ -68,6 +87,7 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils ...@@ -68,6 +87,7 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils
this.getSessionId(); this.getSessionId();
}, },
mounted: function () { mounted: function () {
this.pageEvent();
// 监听输入框的键盘事件 // 监听输入框的键盘事件
this.$nextTick(() => { this.$nextTick(() => {
const textarea = document.getElementById('user-input'); const textarea = document.getElementById('user-input');
...@@ -82,9 +102,37 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils ...@@ -82,9 +102,37 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils
this.closeAllMenus(); this.closeAllMenus();
} }
}); });
// // 获取滚动容器和消息容器
// const scrollContainer = document.getElementById('chat-messages').parentElement;
// const chatMessages = document.getElementById('chat-messages');
// // 创建MutationObserver监听消息变化
// const observer = new MutationObserver(function(mutations) {
// mutations.forEach(mutation => {
// if (mutation.addedNodes.length) {
// // 使用延时确保内容已渲染
// setTimeout(() => {
// scrollContainer.scrollTo({
// top: scrollContainer.scrollHeight,
// behavior: 'smooth' // 可选平滑滚动
// });
// }, 50);
// }
// });
// });
//
// // 开始观察子元素变化
// observer.observe(chatMessages, {
// childList: true
// });
}); });
}, },
methods: { methods: {
pageEvent:function(){
// 确保在DOM加载完成后执行
document.addEventListener('DOMContentLoaded', function() {
});
},
// 用户相关方法 // 用户相关方法
currentUser: function () { currentUser: function () {
const that = this; const that = this;
...@@ -131,6 +179,7 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils ...@@ -131,6 +179,7 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils
const message = this.userInput.trim(); const message = this.userInput.trim();
if (!message) return; if (!message) return;
this.stopResponse();
// 添加用户消息 // 添加用户消息
this.addMessage('user', message); this.addMessage('user', message);
this.userInput = ''; this.userInput = '';
...@@ -154,8 +203,9 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils ...@@ -154,8 +203,9 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils
const aiMessages = this.messages.filter(msg => msg.role === 'ai'); const aiMessages = this.messages.filter(msg => msg.role === 'ai');
if (aiMessages.length > 0) { if (aiMessages.length > 0) {
const lastAIMessage = aiMessages[aiMessages.length - 1]; const lastAIMessage = aiMessages[aiMessages.length - 1];
if (!lastAIMessage.content.includes('(已终止)')) { lastAIMessage.typing = false;
lastAIMessage.content += ' (已终止)'; if (!lastAIMessage.content.includes('(已手动结束回答)')) {
lastAIMessage.content += ' (已手动结束回答)';
} }
} }
} }
...@@ -167,7 +217,7 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils ...@@ -167,7 +217,7 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils
// 自动滚动到底部 // 自动滚动到底部
this.$nextTick(() => { this.$nextTick(() => {
const messagesDiv = document.getElementById('chat-messages'); const messagesDiv = document.getElementById('scrollContainer');
if (messagesDiv) { if (messagesDiv) {
messagesDiv.scrollTop = messagesDiv.scrollHeight; messagesDiv.scrollTop = messagesDiv.scrollHeight;
} }
...@@ -181,7 +231,7 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils ...@@ -181,7 +231,7 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils
// 自动滚动到底部 // 自动滚动到底部
this.$nextTick(() => { this.$nextTick(() => {
const messagesDiv = document.getElementById('chat-messages'); const messagesDiv = document.getElementById('scrollContainer');
if (messagesDiv) { if (messagesDiv) {
messagesDiv.scrollTop = messagesDiv.scrollHeight; messagesDiv.scrollTop = messagesDiv.scrollHeight;
} }
...@@ -212,7 +262,7 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils ...@@ -212,7 +262,7 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils
// 自动滚动到底部 // 自动滚动到底部
this.$nextTick(() => { this.$nextTick(() => {
const messagesDiv = document.getElementById('chat-messages'); const messagesDiv = document.getElementById('scrollContainer');
if (messagesDiv) { if (messagesDiv) {
messagesDiv.scrollTop = messagesDiv.scrollHeight; messagesDiv.scrollTop = messagesDiv.scrollHeight;
} }
...@@ -348,6 +398,18 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils ...@@ -348,6 +398,18 @@ require(['jquery', 'vue', 'utils', 'echarts', 'global'], function ($, Vue, utils
if (isActiveChat) { if (isActiveChat) {
this.clearChat(); this.clearChat();
} }
},
// 专家选择相关方法
toggleExpertDropdown() {
this.showExpertDropdown = !this.showExpertDropdown;
},
closeExpertDropdown() {
this.showExpertDropdown = false;
},
selectExpert(expert) {
this.selectedExpert = expert;
// 立即关闭下拉框
this.showExpertDropdown = false;
} }
} }
}); });
......
...@@ -65,6 +65,7 @@ body { ...@@ -65,6 +65,7 @@ body {
display: flex; display: flex;
height: 100vh; height: 100vh;
width: 100%; width: 100%;
overflow: hidden;
} }
/* 左侧边栏样式 */ /* 左侧边栏样式 */
...@@ -212,101 +213,54 @@ body { ...@@ -212,101 +213,54 @@ body {
color: var(--text-secondary); color: var(--text-secondary);
} }
/* 聊天包装器样式 - 新增 */ /* 右侧聊天区域 */
.chat-wrapper { .chat-area {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start;
align-items: center;
background-color: var(--bg-color);
padding: 0;
position: relative; position: relative;
height: 100vh; height: 100vh;
overflow: hidden; overflow-y: auto; /* 使整个聊天区域可滚动,滚动条显示在最右边 */
} overflow-x: hidden;
/* 聊天容器样式 */
.chat-container {
width: 900px;
max-width: 95%;
height: 100%;
display: flex;
flex-direction: column;
background-color: var(--bg-color); background-color: var(--bg-color);
overflow: hidden;
position: relative;
padding-bottom: 80px; /* 为底部输入框留出空间 */
} }
/* 聊天头部样式 */ .scrollContainer{
.chat-header { width: 100%;
padding: 15px 20px; overflow-y: auto; /* 让内容继续流动 */
background-color: #fff; height: calc(100vh - 150px); /* 确保占据足够高度 */
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #e8e8e8;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.current-chat-info {
display: flex;
align-items: center;
} }
.current-chat-title { /* 聊天消息区域 */
font-size: 1rem; .chat-messages {
font-weight: 600; width: 900px;
color: #333; max-width: 95%;
margin: 0 auto;
padding: 20px;
margin-bottom: 10px;
} }
.chat-info { /* 输入区域 */
.input-area {
width: 900px;
max-width: 95%;
margin: 0 auto 30px auto;
padding: 8px 10px;
display: flex; display: flex;
align-items: center; background-color: var(--input-area-bg);
gap: 15px; border-radius: 15px;
box-shadow: 0 1px 8px var(--box-shadow);
position: sticky;
bottom: 30px;
flex-shrink: 0; /* 防止被压缩 */
flex-direction: column;
justify-content: flex-start;
} }
.status { .input-area-content{
display: flex; display: flex;
align-items: center; justify-content: space-between;
font-size: 0.9rem; padding-left: 10px;
}
.status::before {
content: '';
display: inline-block;
width: 8px;
height: 8px;
margin-right: 5px;
border-radius: 50%;
}
.status.online::before {
background-color: #52c41a;
}
.clear-btn {
padding: 6px 12px;
background-color: #f0f0f0;
color: #595959;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.clear-btn:hover {
background-color: #e0e0e0;
}
/* 消息区域样式 */
.chat-messages {
flex: 1;
padding: 20px;
overflow-y: auto;
background-color: var(--bg-color);
height: calc(100vh - 80px);
} }
/* 单条消息样式 */ /* 单条消息样式 */
...@@ -363,23 +317,6 @@ body { ...@@ -363,23 +317,6 @@ body {
word-break: break-word; word-break: break-word;
} }
/* 输入区域样式 */
.input-area {
display: flex;
padding: 8px 10px;
background-color: var(--input-area-bg);
align-items: center;
position: absolute;
bottom: 30px;
left: 20px;
right: 20px;
width: calc(100% - 40px);
z-index: 10;
box-shadow: 0 1px 8px var(--box-shadow);
border-radius: 15px;
border-top: none;
}
#user-input { #user-input {
flex: 1; flex: 1;
padding: 8px 10px; padding: 8px 10px;
...@@ -387,7 +324,7 @@ body { ...@@ -387,7 +324,7 @@ body {
border-radius: 0; border-radius: 0;
resize: none; resize: none;
outline: none; outline: none;
height: 70px; height: 100px;
max-height: 150px; max-height: 150px;
background-color: transparent; background-color: transparent;
transition: all 0.3s; transition: all 0.3s;
...@@ -407,13 +344,13 @@ body { ...@@ -407,13 +344,13 @@ body {
} }
.send-btn, .stop-btn { .send-btn, .stop-btn {
width: 44px; width: 36px;
height: 44px; height: 36px;
min-height: 44px; min-height: 36px;
background-color: var(--primary-color); background-color: var(--primary-color);
color: white; color: white;
border: none; border: none;
border-radius: 12px; border-radius: 50%;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -434,9 +371,9 @@ body { ...@@ -434,9 +371,9 @@ body {
background-color: #ff7875; background-color: #ff7875;
} }
.stop-icon { .stop-icon, .send-icon {
width: 20px; width: 18px;
height: 20px; height: 18px;
stroke: white; stroke: white;
} }
...@@ -473,15 +410,10 @@ body { ...@@ -473,15 +410,10 @@ body {
left: 0; left: 0;
} }
.chat-wrapper { .chat-messages,
padding: 10px; .input-area {
}
.chat-container {
width: 100%; width: 100%;
max-width: 100%; max-width: 100%;
height: 100vh;
border-radius: 0;
} }
.message .content { .message .content {
...@@ -522,3 +454,97 @@ body { ...@@ -522,3 +454,97 @@ body {
transform: translateY(0); transform: translateY(0);
} }
} }
/* 自定义选择器样式 */
.custom-select {
position: relative;
width: auto;
min-width: 70px;
cursor: pointer;
user-select: none;
margin-right: 10px;
margin-left: 0;
}
.selected-option {
display: flex;
align-items: center;
justify-content: center;
padding: 2px 5px;
border-radius: 8px;
background-color: rgba(230, 220, 250, 0.5);
color: #6633ff;
font-size: 14px;
transition: all 0.2s;
}
.selected-option span {
margin-right: 2px;
text-align: center;
display: inline-block;
width: 100%;
}
.dark-theme .selected-option {
background-color: rgba(130, 100, 200, 0.2);
color: #9980ff;
}
.selected-option:hover {
background-color: rgba(210, 200, 250, 0.7);
}
.dark-theme .selected-option:hover {
background-color: rgba(150, 120, 220, 0.3);
}
.dropdown-icon {
transition: transform 0.2s;
margin-left: 2px;
flex-shrink: 0;
stroke: #6633ff;
}
.dark-theme .dropdown-icon {
stroke: #9980ff;
}
.dropdown-icon.rotated {
transform: rotate(180deg);
}
.dropdown-menu {
position: absolute;
bottom: 100%;
left: 0;
width: 100%;
margin-bottom: 5px;
background-color: var(--message-bg);
border-radius: 8px;
box-shadow: 0 2px 10px var(--box-shadow);
z-index: 100;
overflow: hidden;
}
.dropdown-item {
padding: 6px 8px;
transition: background-color 0.2s;
font-size: 13px;
color: var(--text-color);
text-align: center;
}
.dropdown-item:hover {
background-color: var(--hover-bg);
}
.dropdown-item.active {
background-color: var(--active-bg);
font-weight: 500;
}
/* 输入区域内容样式 */
.input-area-content {
display: flex;
align-items: center;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment