Files
cz-web/src/views/service/cpns/ChatInput.vue
2026-10-10 08:12:18 +08:00

154 lines
3.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { nextTick, ref } from 'vue'
import { ElButton, ElMessage } from 'element-plus'
const MAX_FILE_SIZE = 1024 * 1024 * 1024
const content = ref('')
const emit = defineEmits<{
send: [content: string]
sendFile: [file: File]
}>()
async function doSend(): Promise<void> {
const text = content.value.trim()
if (!text) return
emit('send', text)
content.value = ''
await nextTick()
}
function onKeydown(event: KeyboardEvent): void {
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault()
void doSend()
}
}
function onFileChange(event: Event): void {
const target = event.target
if (!(target instanceof HTMLInputElement)) return
const file = target.files?.[0]
target.value = ''
if (!file) return
if (file.size > MAX_FILE_SIZE) {
ElMessage.warning('文件大小不能超过1G')
return
}
emit('sendFile', file)
}
</script>
<template>
<div class="chat-input">
<textarea
v-model="content"
class="chat-input__textarea"
placeholder="输入消息,按Enter发送,Shift+Enter换行..."
rows="3"
@keydown="onKeydown"
/>
<div class="chat-input__bar">
<span class="chat-input__hint">
按 Enter 发送 | 支持拖拽上传文件
</span>
<div class="chat-input__actions">
<input
type="file"
class="chat-input__file"
@change="onFileChange"
>
<el-button
class="chat-input__send"
@click="doSend"
>
发送
</el-button>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
.chat-input {
.flex(column, flex-start, stretch);
gap: 0;
padding: 16px 22px 20px;
border-top: 1px solid @service-card-line;
background: @white;
box-sizing: border-box;
&__textarea {
width: 100%;
height: 72px;
padding: 12px 14px;
border: none;
border-radius: @radius-sm;
background: @service-input-bg;
color: @service-bubble-text;
font-size: 13px;
line-height: 1.6;
resize: none;
outline: none;
transition: background 0.2s;
box-sizing: border-box;
&:focus {
border: none;
background: @service-input-bg;
}
&::placeholder {
color: @project-muted;
}
}
&__bar {
.flex(row, space-between, center);
gap: @spacing-base;
width: 100%;
margin-top: 0;
padding-top: 14px;
background: @service-bar-bg;
}
&__hint {
font-size: 11px;
line-height: 16px;
color: @project-muted;
}
&__actions {
.flex(row, flex-end, center);
gap: @spacing-sm;
}
&__attach {
display: none;
}
&__file {
display: none;
}
&__send {
width: 76px;
height: 30px;
padding: 0;
border-color: @primary-strong;
border-radius: @radius-sm;
background: @primary-strong;
color: @white;
font-size: 12px;
font-weight: 500;
&:hover {
border-color: @primary-strong;
background: @primary-strong;
color: @white;
}
}
}
</style>