diff --git a/components/ai-chat-message/ai-chat-message.vue b/components/ai-chat-message/ai-chat-message.vue
index 0790fae..13a8bab 100644
--- a/components/ai-chat-message/ai-chat-message.vue
+++ b/components/ai-chat-message/ai-chat-message.vue
@@ -27,6 +27,8 @@
+
+ {{ localUserNickname }}
{{ message.content }}
@@ -41,6 +43,8 @@
+
+ 智能助手
@@ -189,6 +193,10 @@
+
+
@@ -311,6 +319,42 @@
+
+
+
@@ -334,6 +378,11 @@ export default {
type: String,
default: ''
},
+ // 初始用户昵称(外部传入,可选)
+ initUserNickname: {
+ type: String,
+ default: ''
+ },
// 是否显示加载更多
showLoadMore: {
type: Boolean,
@@ -380,6 +429,11 @@ export default {
defaultAvatar: '/static/images/default-avatar.png',
// 头像选择弹窗控制
showAvatarSelector: false,
+ // 新增:用户昵称相关
+ localUserNickname: '', // 当前用户昵称
+ defaultNickname: '我', // 默认昵称
+ showNicknameEditor: false, // 昵称编辑弹窗控制
+ tempNickname: '', // 昵称编辑临时值
// Dify API相关
currentConversationId: null,
isAIServiceAvailable: true,
@@ -392,6 +446,8 @@ export default {
this.initAudioContext()
// 初始化用户头像(缓存优先)
this.initUserAvatarData()
+ // 初始化用户昵称(缓存优先)
+ this.initUserNicknameData()
},
mounted() {
this.scrollToBottom()
@@ -436,6 +492,26 @@ export default {
}
},
+ // 新增:初始化用户昵称(支持缓存持久化)
+ initUserNicknameData() {
+ // 1. 优先读取本地缓存的昵称
+ const cachedNickname = uni.getStorageSync('user_nickname')
+
+ if (cachedNickname) {
+ this.localUserNickname = cachedNickname
+ }
+ // 2. 无缓存时,使用外部传入的初始昵称
+ else if (this.initUserNickname) {
+ this.localUserNickname = this.initUserNickname
+ // 缓存初始昵称
+ uni.setStorageSync('user_nickname', this.initUserNickname)
+ }
+ // 3. 最后使用默认昵称
+ else {
+ this.localUserNickname = this.defaultNickname
+ }
+ },
+
// 打开头像选择弹窗
openAvatarSelector() {
this.showAvatarSelector = true
@@ -504,6 +580,44 @@ export default {
})
},
+ // 新增:打开昵称编辑弹窗
+ openNicknameEditor() {
+ // 初始化临时昵称值为当前昵称
+ this.tempNickname = this.localUserNickname
+ this.showNicknameEditor = true
+ },
+
+ // 新增:关闭昵称编辑弹窗
+ closeNicknameEditor() {
+ this.showNicknameEditor = false
+ // 清空临时值
+ this.tempNickname = ''
+ },
+
+ // 新增:保存用户昵称
+ saveNickname() {
+ if (!this.tempNickname.trim()) return
+
+ // 1. 更新本地昵称
+ this.localUserNickname = this.tempNickname.trim()
+
+ // 2. 持久化缓存(支持页面刷新后保留)
+ uni.setStorageSync('user_nickname', this.localUserNickname)
+
+ // 3. 通知父组件(可选,用于同步到服务器等场景)
+ this.$emit('nickname-changed', this.localUserNickname)
+
+ // 4. 关闭弹窗
+ this.closeNicknameEditor()
+
+ // 5. 提示成功
+ uni.showToast({
+ title: '昵称修改成功',
+ icon: 'success',
+ duration: 1500
+ })
+ },
+
// 发送消息
async sendMessage() {
if (!this.inputText.trim()) return
@@ -1194,8 +1308,11 @@ $radius-lg: 36rpx;
font-size: 24rpx;
color: $color-text-light;
margin-bottom: 8rpx;
- text-align: right; // 与用户消息右对齐
letter-spacing: 0.5rpx;
+ // 用户昵称右对齐,AI昵称左对齐
+ &:not(.ai-message .message-nickname) {
+ text-align: right;
+ }
}
.message-bubble {
@@ -1835,737 +1952,767 @@ $radius-lg: 36rpx;
z-index: 1001;
}
}
+
+
+
+
+
+// 昵称编辑弹窗样式(修复右侧溢出问题)
+.nickname-editor-popup {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 1001;
+}
- // 昵称编辑弹窗样式
- .nickname-editor-popup {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 1001;
- }
+.nickname-editor-mask {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.4);
+ backdrop-filter: blur(6rpx);
+}
- .nickname-editor-mask {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.4);
- backdrop-filter: blur(6rpx);
- }
+.nickname-editor-panel {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ background-color: $bg-card;
+ border-radius: $radius-lg;
+ padding: 24rpx 32rpx; // 统一内边距
+ width: calc(100% - 80rpx); // 限制弹窗宽度(避免超出屏幕)
+ max-width: 520rpx; // 最大宽度(适配不同设备)
+ box-shadow: 0 8rpx 36rpx rgba(0, 0, 0, 0.15);
+ box-sizing: border-box; // 确保内边距不影响宽度
- .nickname-editor-panel {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- background-color: $bg-card;
- border-radius: $radius-lg;
- padding: 32rpx;
- width: 580rpx;
- box-shadow: 0 8rpx 36rpx rgba(0, 0, 0, 0.15);
+ .nickname-editor-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 24rpx;
+ border-bottom: 2rpx solid #f0f4f8;
+ padding-bottom: 16rpx;
- .nickname-editor-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 32rpx;
- border-bottom: 2rpx solid #f0f4f8;
- padding-bottom: 24rpx;
-
- text {
- font-size: 34rpx;
- font-weight: 600;
- color: $color-text;
- }
-
- .close-btn {
- width: 64rpx;
- height: 64rpx;
- border-radius: 50%;
- background-color: $bg-main;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.2s ease;
- border: none;
-
- &:hover {
- background-color: #e8edf3;
- }
-
- .iconfont {
- font-size: 34rpx;
- color: $color-text-light;
- }
- }
+ text {
+ font-size: 34rpx;
+ font-weight: 600;
+ color: $color-text;
}
- .nickname-editor-content {
- .nickname-input-container {
- margin-bottom: 24rpx;
+ .close-btn {
+ width: 56rpx;
+ height: 56rpx;
+ border-radius: 50%;
+ background-color: $bg-main;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s ease;
+ border: none;
- .nickname-input {
- width: 100%;
- height: 96rpx;
- padding: 0 24rpx;
- border-radius: $radius-lg;
- border: 2rpx solid #f0f4f8;
- font-size: 28rpx;
- color: $color-text;
- background-color: $bg-main;
- transition: all 0.2s ease;
-
- &:focus {
- border-color: $color-primary;
- box-shadow: 0 0 0 4rpx rgba(108, 142, 191, 0.1);
- }
-
- &::placeholder {
- color: $color-text-light;
- opacity: 0.8;
- }
- }
+ &:hover {
+ background-color: #e8edf3;
}
- .nickname-tip {
- font-size: 24rpx;
+ .iconfont {
+ font-size: 28rpx;
color: $color-text-light;
- margin-bottom: 32rpx;
- text-align: center;
- }
-
- .nickname-editor-actions {
- display: flex;
- gap: 24rpx;
-
- .nickname-action-btn {
- flex: 1;
- height: 96rpx;
- border-radius: $radius-lg;
- font-size: 28rpx;
- font-weight: 500;
- transition: all 0.2s ease;
-
- &.cancel {
- background-color: $bg-card;
- border: 2rpx solid #f0f4f8;
- color: $color-text-light;
-
- &:hover {
- background-color: #f8fafc;
- }
- }
-
- &.confirm {
- background-color: $color-primary;
- color: white;
- box-shadow: 0 4rpx 12rpx rgba(108, 142, 191, 0.2);
-
- &:hover {
- background-color: #5a7cb0;
- transform: translateY(-2rpx);
- }
-
- &.disabled {
- background-color: $color-primary-light;
- box-shadow: none;
- opacity: 0.7;
- transform: none;
- }
- }
- }
}
}
}
- /* 弹窗样式基础 */
- .tools-popup, .voice-popup, .avatar-selector-popup {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 999;
- }
+ .nickname-editor-content {
+ .nickname-input-container {
+ margin-bottom: 24rpx;
+ width: 100%; // 输入框容器占满弹窗宽度
+ box-sizing: border-box;
- .tools-mask, .voice-mask, .avatar-selector-mask {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.4);
- backdrop-filter: blur(6rpx);
- }
-
- /* 工具面板样式 */
- .tools-panel {
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- background-color: $bg-card;
- border-radius: $radius-lg $radius-lg 0 0;
- box-shadow: 0 -4rpx 24rpx rgba(0, 0, 0, 0.1);
-
- .tools-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 32rpx;
- border-bottom: 2rpx solid #f0f4f8;
-
- text {
- font-size: 34rpx;
- font-weight: 600;
+ .nickname-input {
+ width: 100%;
+ height: 96rpx;
+ padding: 0 24rpx;
+ border-radius: $radius-lg;
+ border: 2rpx solid #f0f4f8;
+ font-size: 28rpx;
color: $color-text;
- }
-
- .close-btn {
- width: 64rpx;
- height: 64rpx;
- border-radius: 50%;
- background-color: $bg-main;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.2s ease;
- border: none;
-
- &:hover {
- background-color: #e8edf3;
- }
-
- .iconfont {
- font-size: 34rpx;
- color: $color-text-light;
- }
- }
- }
-
- .tools-grid {
- display: grid;
- grid-template-columns: repeat(4, 1fr);
- padding: 32rpx;
- gap: 32rpx;
-
- .tool-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- transition: all 0.3s ease;
-
- &:hover {
- transform: translateY(-4rpx);
- }
-
- .tool-icon {
- width: 96rpx;
- height: 96rpx;
- border-radius: 50%;
- background-color: $bg-main;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 16rpx;
- box-shadow: $shadow-sm;
-
- .iconfont {
- font-size: 48rpx;
- color: $color-primary;
- }
- }
-
- .tool-text {
- font-size: 26rpx;
- color: $color-text;
- }
- }
- }
- }
-
- /* 语音输入面板样式 */
- .voice-input-panel {
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- background-color: $bg-card;
- border-radius: $radius-lg $radius-lg 0 0;
- box-shadow: 0 -4rpx 24rpx rgba(0, 0, 0, 0.1);
-
- .voice-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 32rpx;
- border-bottom: 2rpx solid #f0f4f8;
-
- text {
- font-size: 34rpx;
- font-weight: 600;
- color: $color-text;
- }
-
- .close-btn {
- width: 64rpx;
- height: 64rpx;
- border-radius: 50%;
- background-color: $bg-main;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.2s ease;
- border: none;
-
- &:hover {
- background-color: #e8edf3;
- }
-
- .iconfont {
- font-size: 34rpx;
- color: $color-text-light;
- }
- }
- }
-
- .voice-content {
- padding: 64rpx 32rpx;
- display: flex;
- flex-direction: column;
- align-items: center;
-
- .voice-wave {
- width: 240rpx;
- height: 240rpx;
- border-radius: 50%;
- background-color: $bg-main;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 48rpx;
- box-shadow: $shadow-md;
-
- .wave-bar {
- width: 12rpx;
- height: 40rpx;
- background-color: $color-primary-light;
- border-radius: 6rpx;
- margin: 0 8rpx;
- transition: height 0.3s ease;
- }
-
- &.recording {
- .wave-bar {
- animation: waveAnimation 1.2s infinite ease-in-out;
- }
- }
- }
-
- .voice-tip {
- font-size: 28rpx;
- color: $color-text;
- }
- }
-
- .voice-actions {
- padding: 32rpx;
- display: flex;
- justify-content: center;
-
- .voice-btn {
- width: 120rpx;
- height: 120rpx;
- border-radius: 50%;
- background-color: $color-user;
- display: flex;
- align-items: center;
- justify-content: center;
- box-shadow: 0 8rpx 24rpx rgba(134, 117, 169, 0.3);
- transition: all 0.3s ease;
-
- &:hover {
- transform: scale(1.05);
- background-color: #756298;
- }
-
- .iconfont {
- font-size: 56rpx;
- color: white;
- }
- }
- }
- }
-
- /* 头像选择弹窗样式 */
- .avatar-selector-panel {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- background-color: $bg-card;
- border-radius: $radius-lg;
- padding: 32rpx;
- width: 580rpx;
- box-shadow: 0 8rpx 36rpx rgba(0, 0, 0, 0.15);
-
- .avatar-selector-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 32rpx;
- border-bottom: 2rpx solid #f0f4f8;
- padding-bottom: 24rpx;
-
- text {
- font-size: 34rpx;
- font-weight: 600;
- color: $color-text;
- }
-
- .close-btn {
- width: 64rpx;
- height: 64rpx;
- border-radius: 50%;
- background-color: $bg-main;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.2s ease;
- border: none;
-
- &:hover {
- background-color: #e8edf3;
- }
-
- .iconfont {
- font-size: 34rpx;
- color: $color-text-light;
- }
- }
- }
-
- .avatar-selector-content {
- .current-avatar-preview {
- width: 200rpx;
- height: 200rpx;
- border-radius: 50%;
- overflow: hidden;
- margin: 0 auto 48rpx;
- box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
- border: 8rpx solid $bg-main;
-
- image {
- width: 100%;
- height: 100%;
- object-fit: cover;
- }
- }
-
- .avatar-selector-actions {
- display: flex;
- flex-direction: column;
- gap: 24rpx;
-
- .avatar-select-action {
- height: 96rpx;
- border-radius: $radius-lg;
- background-color: $bg-main;
- font-size: 28rpx;
- color: $color-text;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 16rpx;
- transition: all 0.2s ease;
- border: 2rpx solid #f0f4f8;
-
- &:hover {
- background-color: #e8edf3;
- }
-
- &.cancel {
- background-color: $bg-card;
- color: $color-text-light;
-
- &:hover {
- background-color: #f8fafc;
- }
- }
-
- .iconfont {
- font-size: 36rpx;
- color: $color-primary;
- }
- }
- }
- }
- }
-
- /* 动画定义 */
- @keyframes dotPulse {
- 0%, 100% {
- transform: scale(1);
- opacity: 0.7;
- }
- 50% {
- transform: scale(1.3);
- opacity: 1;
- }
- }
-
- @keyframes shine {
- 0% {
- left: -100%;
- }
- 100% {
- left: 200%;
- }
- }
-
- @keyframes waveAnimation {
- 0%, 100% {
- height: 40rpx;
- background-color: $color-primary-light;
- }
- 50% {
- height: 120rpx;
- background-color: $color-primary;
- }
+ background-color: $bg-main;
+ transition: all 0.2s ease;
+ box-shadow: none;
+ box-sizing: border-box; // 确保输入框不超出容器
+
+ &:focus {
+ border-color: $color-primary;
+ box-shadow: 0 0 0 4rpx rgba(108, 142, 191, 0.1);
}
- /* 新增:渐变流动动画(仅为背景增加动效,不影响其他样式) */
- @keyframes gradient-flow {
- 0% {
- background-position: 0% 50%;
- }
- 50% {
- background-position: 100% 50%;
- }
- 100% {
- background-position: 0% 50%;
- }
- }
-
- /* 富文本样式补充 */
- rich-text {
- line-height: 1.8;
- font-size: 26rpx;
- color: $color-text;
- display: block;
-
- strong {
- font-weight: 600;
- color: $color-text;
- }
-
- em {
- font-style: italic;
- color: $color-text-light;
- }
-
- code {
- background-color: #f0f4f8;
- padding: 4rpx 8rpx;
- border-radius: $radius-sm;
- font-family: monospace;
- font-size: 24rpx;
- color: $color-primary;
- }
-
- a {
- color: $color-primary;
- text-decoration: underline;
- text-underline-offset: 4rpx;
- }
-
- br {
- display: block;
- height: 24rpx;
- }
- }
-
- /* 适配小程序和H5的按钮默认样式重置 */
- button {
- padding: 0;
- margin: 0;
- border: none;
- background: none;
- line-height: normal;
- font-weight: normal;
- outline: none;
-
- &::after {
- border: none;
- }
- }
-
- /* 滑块样式优化 */
- slider {
- height: 12rpx;
-
- &::before {
- height: 12rpx;
- border-radius: 6rpx;
- }
-
- &::after {
- width: 24rpx;
- height: 24rpx;
- border-radius: 50%;
- background-color: $color-primary;
- border: none;
- box-shadow: 0 2rpx 8rpx rgba(108, 142, 191, 0.3);
- }
- }
-
- /* 输入框聚焦样式优化 */
- input:focus, textarea:focus {
- outline: none;
- }
-
- /* 响应式适配:小屏幕设备 */
- @media (max-width: 375px) {
- .ai-chat-container {
- padding-bottom: calc(env(safe-area-inset-bottom) + 16rpx);
- }
-
- .chat-messages {
- padding: 16rpx 24rpx;
- }
-
- .message-item {
- margin-bottom: 24rpx;
- }
-
- .user-message, .ai-message {
- .avatar {
- width: 72rpx;
- height: 72rpx;
- }
-
- .message-content {
- margin-left: 16rpx;
- max-width: calc(100% - 88rpx);
- }
-
- .user-message .message-content {
- margin-right: 16rpx;
- }
- }
-
- .message-bubble {
- padding: 20rpx 24rpx !important;
- }
-
- .message-text {
- font-size: 26rpx !important;
- }
-
- .input-area {
- padding: 16rpx 24rpx;
- padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
- }
-
- .input-tools .tool-btn {
- width: 56rpx;
- height: 56rpx;
- margin-right: 12rpx;
- }
-
- .input-container .message-input {
- min-height: 76rpx;
- padding: 20rpx 24rpx;
- font-size: 26rpx;
- }
-
- .send-btn {
- width: 96rpx;
- height: 68rpx;
- font-size: 26rpx;
- }
-
- .avatar-selector-panel, .nickname-editor-panel {
- width: 90vw;
- padding: 24rpx;
- }
-
- .avatar-selector-content .current-avatar-preview {
- width: 160rpx;
- height: 160rpx;
- margin-bottom: 32rpx;
- }
-
- .voice-input-panel .voice-content .voice-wave {
- width: 200rpx;
- height: 200rpx;
- }
- }
-
- /* 深色模式适配(可选) */
- @media (prefers-color-scheme: dark) {
- $bg-main: #1e2128;
- $bg-card: #2d3139;
- $color-text: #e5e7eb;
- $color-text-light: #9ca3af;
- $color-primary: #8197c3;
- $color-primary-light: #9aa7c0;
- $color-user: #a594cc;
-
- .ai-chat-container {
- background-color: $bg-main;
- }
-
- .message-bubble {
- border-color: #3d4149;
- }
-
- .ai-message .message-bubble::before {
- background: $bg-card;
- border-color: #3d4149;
- }
-
- .input-area {
- background-color: $bg-card;
- border-top-color: #3d4149;
- }
-
- .input-tools .tool-btn,
- .tools-header .close-btn,
- .voice-header .close-btn,
- .avatar-selector-header .close-btn,
- .nickname-editor-header .close-btn {
- background-color: $bg-main;
- }
-
- .message-input,
- .nickname-input {
- background-color: $bg-main;
- border-color: #3d4149;
- color: $color-text;
- }
-
- .tools-panel, .voice-input-panel, .avatar-selector-panel, .nickname-editor-panel {
- background-color: $bg-card;
- }
-
- .tools-header, .voice-header, .avatar-selector-header, .nickname-editor-header {
- border-bottom-color: #3d4149;
- }
-
- .tool-item .tool-icon,
- .voice-wave {
- background-color: $bg-main;
- }
-
- .avatar-select-action,
- .nickname-action-btn.cancel {
- background-color: $bg-main;
- border-color: #3d4149;
- }
+ &::placeholder {
+ color: $color-text-light;
+ opacity: 0.8;
}
}
-
\ No newline at end of file
+ }
+
+ .nickname-tip {
+ font-size: 24rpx;
+ color: $color-text-light;
+ margin-bottom: 32rpx;
+ text-align: center;
+ width: 100%;
+ box-sizing: border-box;
+ }
+
+ .nickname-editor-actions {
+ display: flex;
+ gap: 24rpx;
+ width: 100%;
+ box-sizing: border-box;
+ justify-content: center;
+ padding: 0 20rpx;
+
+ .nickname-action-btn {
+ flex: none;
+ width: 160rpx;
+ height: 96rpx;
+ border-radius: $radius-lg;
+ font-size: 28rpx;
+ font-weight: 500;
+ transition: all 0.2s ease;
+ box-sizing: border-box;
+ // 核心:文字下移 + 垂直居中
+ padding-top: 12rpx; // 顶部内边距增加,文字下移
+ padding-bottom: 0;
+ line-height: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ // hover动效:文字轻微上移
+ &:hover {
+ padding-top: 8rpx;
+ }
+
+ &.cancel {
+ background-color: $bg-card;
+ border: 2rpx solid #f0f4f8;
+ color: $color-text-light;
+
+ // 修复:替换未定义的 $f8fafc 为已定义的 $bg-main
+ &:hover {
+ background-color: $bg-main;
+ }
+ }
+
+ &.confirm {
+ background-color: $color-primary;
+ color: white;
+ box-shadow: 0 4rpx 12rpx rgba(108, 142, 191, 0.2);
+
+ &:hover {
+ background-color: #5a7cb0;
+ transform: translateY(-2rpx);
+ }
+
+ &.disabled {
+ background-color: $color-primary-light;
+ box-shadow: none;
+ opacity: 0.7;
+ transform: none;
+ }
+ }
+ }
+ }
+ }
+ }
+ /* 弹窗样式基础 */
+ .tools-popup, .voice-popup, .avatar-selector-popup {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 999;
+ }
+
+ .tools-mask, .voice-mask, .avatar-selector-mask {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.4);
+ backdrop-filter: blur(6rpx);
+ }
+
+ /* 工具面板样式 */
+ .tools-panel {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background-color: $bg-card;
+ border-radius: $radius-lg $radius-lg 0 0;
+ box-shadow: 0 -4rpx 24rpx rgba(0, 0, 0, 0.1);
+
+ .tools-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 32rpx;
+ border-bottom: 2rpx solid #f0f4f8;
+
+ text {
+ font-size: 34rpx;
+ font-weight: 600;
+ color: $color-text;
+ }
+
+ .close-btn {
+ width: 64rpx;
+ height: 64rpx;
+ border-radius: 50%;
+ background-color: $bg-main;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s ease;
+ border: none;
+
+ &:hover {
+ background-color: #e8edf3;
+ }
+
+ .iconfont {
+ font-size: 34rpx;
+ color: $color-text-light;
+ }
+ }
+ }
+
+ .tools-grid {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ padding: 32rpx;
+ gap: 32rpx;
+
+ .tool-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ transition: all 0.3s ease;
+
+ &:hover {
+ transform: translateY(-4rpx);
+ }
+
+ .tool-icon {
+ width: 96rpx;
+ height: 96rpx;
+ border-radius: 50%;
+ background-color: $bg-main;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 16rpx;
+ box-shadow: $shadow-sm;
+
+ .iconfont {
+ font-size: 48rpx;
+ color: $color-primary;
+ }
+ }
+
+ .tool-text {
+ font-size: 26rpx;
+ color: $color-text;
+ }
+ }
+ }
+ }
+
+ /* 语音输入面板样式 */
+ .voice-input-panel {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background-color: $bg-card;
+ border-radius: $radius-lg $radius-lg 0 0;
+ box-shadow: 0 -4rpx 24rpx rgba(0, 0, 0, 0.1);
+
+ .voice-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 32rpx;
+ border-bottom: 2rpx solid #f0f4f8;
+
+ text {
+ font-size: 34rpx;
+ font-weight: 600;
+ color: $color-text;
+ }
+
+ .close-btn {
+ width: 64rpx;
+ height: 64rpx;
+ border-radius: 50%;
+ background-color: $bg-main;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s ease;
+ border: none;
+
+ &:hover {
+ background-color: #e8edf3;
+ }
+
+ .iconfont {
+ font-size: 34rpx;
+ color: $color-text-light;
+ }
+ }
+ }
+
+ .voice-content {
+ padding: 64rpx 32rpx;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ .voice-wave {
+ width: 240rpx;
+ height: 240rpx;
+ border-radius: 50%;
+ background-color: $bg-main;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 48rpx;
+ box-shadow: $shadow-md;
+
+ .wave-bar {
+ width: 12rpx;
+ height: 40rpx;
+ background-color: $color-primary-light;
+ border-radius: 6rpx;
+ margin: 0 8rpx;
+ transition: height 0.3s ease;
+ }
+
+ &.recording {
+ .wave-bar {
+ animation: waveAnimation 1.2s infinite ease-in-out;
+ }
+ }
+ }
+
+ .voice-tip {
+ font-size: 28rpx;
+ color: $color-text;
+ }
+ }
+
+ .voice-actions {
+ padding: 32rpx;
+ display: flex;
+ justify-content: center;
+
+ .voice-btn {
+ width: 120rpx;
+ height: 120rpx;
+ border-radius: 50%;
+ background-color: $color-user;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 8rpx 24rpx rgba(134, 117, 169, 0.3);
+ transition: all 0.3s ease;
+
+ &:hover {
+ transform: scale(1.05);
+ background-color: #756298;
+ }
+
+ .iconfont {
+ font-size: 56rpx;
+ color: white;
+ }
+ }
+ }
+ }
+
+ /* 头像选择弹窗样式 */
+ .avatar-selector-panel {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ background-color: $bg-card;
+ border-radius: $radius-lg;
+ padding: 32rpx;
+ width: 580rpx;
+ box-shadow: 0 8rpx 36rpx rgba(0, 0, 0, 0.15);
+
+ .avatar-selector-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 32rpx;
+ border-bottom: 2rpx solid #f0f4f8;
+ padding-bottom: 24rpx;
+
+ text {
+ font-size: 34rpx;
+ font-weight: 600;
+ color: $color-text;
+ }
+
+ .close-btn {
+ width: 64rpx;
+ height: 64rpx;
+ border-radius: 50%;
+ background-color: $bg-main;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s ease;
+ border: none;
+
+ &:hover {
+ background-color: #e8edf3;
+ }
+
+ .iconfont {
+ font-size: 34rpx;
+ color: $color-text-light;
+ }
+ }
+ }
+
+ .avatar-selector-content {
+ .current-avatar-preview {
+ width: 200rpx;
+ height: 200rpx;
+ border-radius: 50%;
+ overflow: hidden;
+ margin: 0 auto 48rpx;
+ box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
+ border: 8rpx solid $bg-main;
+
+ image {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+ }
+
+ .avatar-selector-actions {
+ display: flex;
+ flex-direction: column;
+ gap: 24rpx;
+
+ .avatar-select-action {
+ height: 96rpx;
+ border-radius: $radius-lg;
+ background-color: $bg-main;
+ font-size: 28rpx;
+ color: $color-text;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 16rpx;
+ transition: all 0.2s ease;
+ border: 2rpx solid #f0f4f8;
+
+ &:hover {
+ background-color: #e8edf3;
+ }
+
+ &.cancel {
+ background-color: $bg-card;
+ color: $color-text-light;
+
+ &:hover {
+ background-color: #f8fafc;
+ }
+ }
+
+ .iconfont {
+ font-size: 36rpx;
+ color: $color-primary;
+ }
+ }
+ }
+ }
+ }
+
+ /* 动画定义 */
+ @keyframes dotPulse {
+ 0%, 100% {
+ transform: scale(1);
+ opacity: 0.7;
+ }
+ 50% {
+ transform: scale(1.3);
+ opacity: 1;
+ }
+ }
+
+ @keyframes shine {
+ 0% {
+ left: -100%;
+ }
+ 100% {
+ left: 200%;
+ }
+ }
+
+ @keyframes waveAnimation {
+ 0%, 100% {
+ height: 40rpx;
+ background-color: $color-primary-light;
+ }
+ 50% {
+ height: 120rpx;
+ background-color: $color-primary;
+ }
+ }
+
+ /* 新增:渐变流动动画(仅为背景增加动效,不影响其他样式) */
+ @keyframes gradient-flow {
+ 0% {
+ background-position: 0% 50%;
+ }
+ 50% {
+ background-position: 100% 50%;
+ }
+ 100% {
+ background-position: 0% 50%;
+ }
+ }
+
+ /* 富文本样式补充 */
+ rich-text {
+ line-height: 1.8;
+ font-size: 26rpx;
+ color: $color-text;
+ display: block;
+
+ strong {
+ font-weight: 600;
+ color: $color-text;
+ }
+
+ em {
+ font-style: italic;
+ color: $color-text-light;
+ }
+
+ code {
+ background-color: #f0f4f8;
+ padding: 4rpx 8rpx;
+ border-radius: $radius-sm;
+ font-family: monospace;
+ font-size: 24rpx;
+ color: $color-primary;
+ }
+
+ a {
+ color: $color-primary;
+ text-decoration: underline;
+ text-underline-offset: 4rpx;
+ }
+
+ br {
+ display: block;
+ height: 24rpx;
+ }
+ }
+
+ /* 适配小程序和H5的按钮默认样式重置 */
+ button {
+ padding: 0;
+ margin: 0;
+ border: none;
+ background: none;
+ line-height: normal;
+ font-weight: normal;
+ outline: none;
+
+ &::after {
+ border: none;
+ }
+ }
+
+ /* 滑块样式优化 */
+ slider {
+ height: 12rpx;
+
+ &::before {
+ height: 12rpx;
+ border-radius: 6rpx;
+ }
+
+ &::after {
+ width: 24rpx;
+ height: 24rpx;
+ border-radius: 50%;
+ background-color: $color-primary;
+ border: none;
+ box-shadow: 0 2rpx 8rpx rgba(108, 142, 191, 0.3);
+ }
+ }
+
+ /* 输入框聚焦样式优化 */
+ input:focus, textarea:focus {
+ outline: none;
+ }
+
+ /* 响应式适配:小屏幕设备 */
+ @media (max-width: 375px) {
+ .ai-chat-container {
+ padding-bottom: calc(env(safe-area-inset-bottom) + 16rpx);
+ }
+
+ .chat-messages {
+ padding: 16rpx 24rpx;
+ }
+
+ .message-item {
+ margin-bottom: 24rpx;
+ }
+
+ .user-message, .ai-message {
+ .avatar {
+ width: 72rpx;
+ height: 72rpx;
+ }
+
+ .message-content {
+ margin-left: 16rpx;
+ max-width: calc(100% - 88rpx);
+ }
+
+ .user-message .message-content {
+ margin-right: 16rpx;
+ }
+ }
+
+ .message-bubble {
+ padding: 20rpx 24rpx !important;
+ }
+
+ .message-text {
+ font-size: 26rpx !important;
+ }
+
+ .input-area {
+ padding: 16rpx 24rpx;
+ padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
+ }
+
+ .input-tools .tool-btn {
+ width: 56rpx;
+ height: 56rpx;
+ margin-right: 12rpx;
+ }
+
+ .input-container .message-input {
+ min-height: 76rpx;
+ padding: 20rpx 24rpx;
+ font-size: 26rpx;
+ }
+
+ .send-btn {
+ width: 96rpx;
+ height: 68rpx;
+ font-size: 26rpx;
+ }
+
+ .avatar-selector-panel, .nickname-editor-panel {
+ width: 90vw;
+ padding: 24rpx;
+ }
+
+ .avatar-selector-content .current-avatar-preview {
+ width: 160rpx;
+ height: 160rpx;
+ margin-bottom: 32rpx;
+ }
+
+ .voice-input-panel .voice-content .voice-wave {
+ width: 200rpx;
+ height: 200rpx;
+ }
+ }
+
+ /* 深色模式适配(可选) */
+ @media (prefers-color-scheme: dark) {
+ $bg-main: #1e2128;
+ $bg-card: #2d3139;
+ $color-text: #e5e7eb;
+ $color-text-light: #9ca3af;
+ $color-primary: #8197c3;
+ $color-primary-light: #9aa7c0;
+ $color-user: #a594cc;
+
+ .ai-chat-container {
+ background-color: $bg-main;
+ }
+
+ .message-bubble {
+ border-color: #3d4149;
+ }
+
+ .ai-message .message-bubble::before {
+ background: $bg-card;
+ border-color: #3d4149;
+ }
+
+ .input-area {
+ background-color: $bg-card;
+ border-top-color: #3d4149;
+ }
+
+ .input-tools .tool-btn,
+ .tools-header .close-btn,
+ .voice-header .close-btn,
+ .avatar-selector-header .close-btn,
+ .nickname-editor-header .close-btn {
+ background-color: $bg-main;
+ }
+
+ .message-input,
+ .nickname-input {
+ background-color: $bg-main;
+ border-color: #3d4149;
+ color: $color-text;
+ }
+
+ .tools-panel, .voice-input-panel, .avatar-selector-panel, .nickname-editor-panel {
+ background-color: $bg-card;
+ }
+
+ .tools-header, .voice-header, .avatar-selector-header, .nickname-editor-header {
+ border-bottom-color: #3d4149;
+ }
+
+ .tool-item .tool-icon,
+ .voice-wave {
+ background-color: $bg-main;
+ }
+
+ .avatar-select-action,
+ .nickname-action-btn.cancel {
+ background-color: $bg-main;
+ border-color: #3d4149;
+ }
+ }
+ }
+
\ No newline at end of file