1. 设备管理界面完成
2. 用户管理界面完成
3. 会话列表完成
This commit is contained in:
Zy
2026-10-10 17:02:31 +08:00
parent 23703a66c2
commit 2ccce95d44
64 changed files with 5341 additions and 1254 deletions

View File

@@ -0,0 +1,146 @@
<template>
<div class="chat-input-wrap">
<div class="input-area">
<!-- 多行输入框 -->
<el-input
ref="inputRef"
v-model="inputText"
:autosize="{ minRows:5, maxRows:8 }"
placeholder="请输入回复内容"
type="textarea"
@keydown="handleKeyDown"
/>
<!-- 发送按钮 -->
<el-button
:disabled="!canSend || sending"
class="btn-send"
size="large"
type="primary"
@click="handleSend"
>
{{ sending ? '发送中' : '发送' }}
</el-button>
</div>
<div>
<!-- 图片上传按钮 -->
<el-button
class="btn-img"
plain
type="info"
@click="handleSelectImage"
>
上传图片
</el-button>
</div>
<!-- 隐藏input用于选图 -->
<input
ref="fileRef"
accept="image/*"
style="display:none"
type="file"
@change="onFileChange"
/>
</div>
</template>
<script lang="ts" setup>
import {ref, computed} from 'vue'
import type {PropType} from 'vue'
const props = defineProps({
/** 是否正在发送中(外部控制,防止重复点击) */
sending: {
type: Boolean,
default: false
}
})
const emit = defineEmits<{
/** 发送文本消息 */
(e: 'send', text: string): void
/** 选中图片文件,交给父组件上传oss */
(e: 'uploadImage', file: File): void
}>()
const inputRef = ref<InstanceType<typeof elInput>>()
const fileRef = ref<HTMLInputElement | null>(null)
const inputText = ref('')
// 是否可以发送
const canSend = computed(() => {
return !!inputText.value.trim()
})
// 点击图片图标,唤起文件选择
const handleSelectImage = () => {
fileRef.value?.click()
}
// 文件选择回调
const onFileChange = (e: Event) => {
const target = e.target as HTMLInputElement
const file = target.files?.[0]
if (!file) return
emit('uploadImage', file)
// 清空file,选同一个图片也能触发change
target.value = ''
}
// 键盘事件:回车发送,Shift+Enter换行
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Enter') {
if (e.shiftKey) {
// shift+enter 原生换行,不拦截
return
}
// 直接回车发送
e.preventDefault()
handleSend()
}
}
// 发送消息
const handleSend = () => {
const rawText = inputText.value.trim()
if (!rawText) return
// 把换行 \n 替换成 <br/>
const htmlText = rawText.replaceAll('\n', '<br/>')
emit('send', htmlText)
// 发送成功后清空输入框
inputText.value = ''
}
</script>
<style lang="scss" scoped>
.chat-input-wrap {
flex-shrink: 0;
padding: 12px;
background: #fff;
}
.input-area {
display: flex;
gap: 8px;
align-items: flex-end;
:deep(.el-textarea__inner) {
background-color: #f7f9fc;
}
}
.btn-img {
flex-shrink: 0;
margin-top: 12px;
padding: 9px 13px;
color: rgba(75, 85, 99, 1);
font-size: 12px;
}
.btn-send {
flex-shrink: 0;
}
:deep(.el-textarea__inner) {
padding: 8px 12px;
}
</style>