重构首页
This commit is contained in:
216
src/views/home/components/InputBar.vue
Normal file
216
src/views/home/components/InputBar.vue
Normal file
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<div class="input-shell">
|
||||
<div class="input-card">
|
||||
<el-input
|
||||
v-model="message"
|
||||
type="textarea"
|
||||
:rows="1"
|
||||
:autosize="{ minRows: 2, maxRows: 5 }"
|
||||
placeholder="多说说你的偏好和要求,我会越用越懂你"
|
||||
class="message-input"
|
||||
@keydown.enter.exact="handleSend"
|
||||
/>
|
||||
|
||||
<div class="input-toolbar">
|
||||
<div class="toolbar-left">
|
||||
<el-button circle class="tool-btn" @click="handleAttachment">
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-button>
|
||||
<el-dropdown trigger="click" @command="handleCommandSelect">
|
||||
<el-button class="pill-btn">快捷指令</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="rewrite">帮我润色这段文案</el-dropdown-item>
|
||||
<el-dropdown-item command="summary">总结当前对话重点</el-dropdown-item>
|
||||
<el-dropdown-item command="todo">整理下一步 TODO</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
||||
<el-dropdown trigger="click" @command="handleReplySelect">
|
||||
<el-button class="pill-btn">快捷回复</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="ok">收到,我马上处理</el-dropdown-item>
|
||||
<el-dropdown-item command="confirm">这个方向可以,继续</el-dropdown-item>
|
||||
<el-dropdown-item command="adjust">这个比例还要再调一下</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-right">
|
||||
<el-button class="mode-btn">启动</el-button>
|
||||
<el-button circle class="send-btn" :disabled="!message.trim()" @click="handleSend">
|
||||
<el-icon><Top /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { Top, Plus } from '@element-plus/icons-vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
interface Emits {
|
||||
(e: 'send', message: string): void;
|
||||
}
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
const message = ref('');
|
||||
|
||||
const quickCommands: Record<string, string> = {
|
||||
rewrite: '请帮我润色下面这段内容,保持原意并提升表达质感:',
|
||||
summary: '请总结我们当前对话的重点,并给出 3 条执行建议。',
|
||||
todo: '请把当前需求拆解成可执行的 TODO 列表。',
|
||||
};
|
||||
|
||||
const quickReplies: Record<string, string> = {
|
||||
ok: '收到,我马上处理。',
|
||||
confirm: '这个方向可以,继续。',
|
||||
adjust: '这个比例还要再调一下。',
|
||||
};
|
||||
|
||||
const handleSend = (event?: KeyboardEvent) => {
|
||||
if (event) event.preventDefault();
|
||||
const msg = message.value.trim();
|
||||
if (!msg) return;
|
||||
emit('send', msg);
|
||||
message.value = '';
|
||||
};
|
||||
|
||||
const handleAttachment = () => {
|
||||
ElMessage.info('附件上传功能开发中...');
|
||||
};
|
||||
|
||||
const handleCommandSelect = (key: string | number | object) => {
|
||||
const k = String(key);
|
||||
message.value = quickCommands[k] || message.value;
|
||||
};
|
||||
|
||||
const handleReplySelect = (key: string | number | object) => {
|
||||
const k = String(key);
|
||||
message.value = quickReplies[k] || message.value;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.input-shell {
|
||||
position: relative;
|
||||
z-index: 12;
|
||||
margin-top: -20px;
|
||||
padding: 0 0 50px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.input-card {
|
||||
width: min(1060px, 82%);
|
||||
margin: 0 auto;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255, 255, 255, 0.97) 0%, rgba(255, 255, 255, 0.92) 100%),
|
||||
radial-gradient(120% 180% at 0% 0%, rgba(59, 130, 246, 0.12) 0%, rgba(59, 130, 246, 0) 38%);
|
||||
border: 1px solid rgba(191, 219, 254, 0.62);
|
||||
border-radius: 18px;
|
||||
box-shadow:
|
||||
0 20px 44px rgba(15, 23, 42, 0.14),
|
||||
0 0 0 1px rgba(59, 130, 246, 0.09) inset,
|
||||
0 10px 24px rgba(37, 99, 235, 0.16);
|
||||
padding: 14px 16px 12px;
|
||||
backdrop-filter: blur(14px);
|
||||
}
|
||||
|
||||
.message-input {
|
||||
:deep(.el-textarea__inner) {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
resize: none;
|
||||
padding: 8px 6px 14px;
|
||||
font-size: 15px;
|
||||
line-height: 1.65;
|
||||
color: #0f172a;
|
||||
background: transparent;
|
||||
min-height: 50px;
|
||||
font-weight: 500;
|
||||
|
||||
&::placeholder {
|
||||
color: #90a1b7;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.toolbar-left,
|
||||
.toolbar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.tool-btn {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 1px solid #d9e4f5;
|
||||
color: #5b6b84;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #f8fbff 100%);
|
||||
box-shadow: 0 2px 6px rgba(15, 23, 42, 0.08);
|
||||
|
||||
&:hover {
|
||||
color: #2b4d8f;
|
||||
background: #f3f8ff;
|
||||
}
|
||||
}
|
||||
|
||||
.pill-btn {
|
||||
height: 30px;
|
||||
padding: 0 12px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid #dbe7f7;
|
||||
color: #30435f;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #f6f9ff 100%);
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mode-btn {
|
||||
height: 30px;
|
||||
padding: 0 13px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid #dbe7f7;
|
||||
color: #30435f;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #f6f9ff 100%);
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
.send-btn {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: none;
|
||||
background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 55%, #2563eb 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 6px 14px rgba(59, 130, 246, 0.4);
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
filter: brightness(1.06);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.55;
|
||||
box-shadow: none;
|
||||
background: #cbd5e1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user