Files
lucky_shop/pages_tool/ai-chat/components/ai-chat-nickname-editor.vue
ZF sun 556ce9d132 refactor(ai-chat): 重构AI聊天国际化文件结构
- 将 ai-chat 语言文件从 ai/ 迁移至 ai-chat/ 目录
- 重构消息组件及多个子组件
2026-05-18 15:36:13 +08:00

235 lines
5.6 KiB
Vue

<template>
<view class="nickname-editor-popup" v-if="visible">
<view class="nickname-editor-mask" @click="close"></view>
<view class="nickname-editor-panel">
<view class="nickname-editor-header">
<text>{{ $lang('editNickname') }}</text>
<button class="close-btn" @click="close">
<text class="iconfont icon-close"></text>
</button>
</view>
<view class="nickname-editor-content">
<view class="nickname-input-container">
<input
v-model="tempNickname"
class="nickname-input"
:placeholder="$lang('newNicknamePlaceholder')"
:maxlength="12"
type="text" />
</view>
<view class="nickname-tip">{{ $lang('nicknameTip') }}</view>
<view class="nickname-editor-actions">
<button class="nickname-action-btn cancel" @click="close">
<text>{{ $lang('cancel') }}</text>
</button>
<button
class="nickname-action-btn confirm"
:class="{ disabled: !tempNickname.trim() }"
:disabled="!tempNickname.trim()"
@click="saveNickname">
<text>{{ $lang('save') }}</text>
</button>
</view>
</view>
</view>
</view>
</template>
<script>
/**
* ai-chat-nickname-editor - 昵称编辑弹窗组件
*
* Props:
* visible: Boolean - 控制显示/隐藏
* nickname: String - 当前昵称
*
* Events:
* update:visible - 同步关闭状态
* nickname-change - 昵称变更,参数:新昵称
*/
export default {
name: 'AiChatNicknameEditor',
props: {
visible: {
type: Boolean,
default: false
},
nickname: {
type: String,
default: ''
}
},
data() {
return {
tempNickname: ''
}
},
watch: {
visible(val) {
if (val) {
this.tempNickname = this.nickname
}
}
},
methods: {
close() {
this.tempNickname = ''
this.$emit('update:visible', false)
},
saveNickname() {
if (!this.tempNickname.trim()) return
const newNickname = this.tempNickname.trim()
uni.setStorageSync('user_nickname', newNickname)
this.$emit('nickname-change', newNickname)
this.close()
uni.showToast({ title: this.$lang('nicknameChangeSuccess'), icon: 'success', duration: 1500 })
}
}
}
</script>
<style lang="scss" scoped>
/* 引入图标字体 */
@import url('/common/css/iconfont.css');
/* 引入全局变量 */
@import '../styles/ai-chat-global.scss';
.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);
}
.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-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
border-bottom: 2rpx solid #f0f4f8;
padding-bottom: 16rpx;
text {
font-size: 34rpx;
font-weight: 600;
color: $color-text;
}
.close-btn {
width: 56rpx;
height: 56rpx;
border-radius: 50%;
background-color: $bg-main;
display: flex;
align-items: center;
justify-content: center;
border: none;
.iconfont {
font-size: 28rpx;
color: $color-text-light;
}
}
}
.nickname-editor-content {
.nickname-input-container {
margin-bottom: 24rpx;
width: 100%;
box-sizing: border-box;
.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;
box-sizing: border-box;
&: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;
}
}
}
.nickname-tip {
font-size: 24rpx;
color: $color-text-light;
margin-bottom: 32rpx;
display: block;
line-height: 1.5;
}
.nickname-editor-actions {
display: flex;
justify-content: flex-end;
gap: 16rpx;
.nickname-action-btn {
padding: 16rpx 32rpx;
border-radius: $radius-lg;
font-size: 28rpx;
font-weight: 500;
border: none;
&.cancel {
background-color: $bg-main;
color: $color-text-light;
}
&.confirm {
background-color: $color-primary;
color: white;
box-shadow: 0 4rpx 12rpx rgba(108, 142, 191, 0.2);
&.disabled {
background-color: $color-primary-light;
opacity: 0.7;
box-shadow: none;
}
}
}
}
}
}
}
</style>