feat: 在线客服(移动端)聊天静态界面
parent
e025ee6f64
commit
b6997d4158
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@ -0,0 +1,22 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
export default defineStore('chat', {
|
||||
state: () => ({
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: '查询中,请稍后!',
|
||||
cmd: 'common',
|
||||
timestamp: new Date().getTime(),
|
||||
},
|
||||
],
|
||||
}),
|
||||
actions: {
|
||||
addMessage(message: Array<[]>) {
|
||||
this.messages.push({
|
||||
...message,
|
||||
timestamp: new Date().getTime(),
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div class="chat-input">
|
||||
<!-- 输入框 -->
|
||||
<div class="input-box">
|
||||
<input
|
||||
type="text"
|
||||
class="input"
|
||||
:value="input"
|
||||
readonly
|
||||
placeholder=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 数字键盘 -->
|
||||
<div class="keyboard-grid">
|
||||
<div
|
||||
v-for="(key, index) in keyboardKeys"
|
||||
:key="index"
|
||||
class="keyboard-key"
|
||||
:class="{ 'keyboard-key-delete': key === 'delete', 'keyboard-key-confirm': key === 'confirm' }"
|
||||
@click="handleInput(key)"
|
||||
>
|
||||
<span v-if="key === 'delete'">
|
||||
<span>删除</span>
|
||||
</span>
|
||||
<span v-else-if="key === 'confirm'">发送</span>
|
||||
<span v-else>{{ key }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import useChatStore from '@/store/modules/chat';
|
||||
|
||||
const $store = useChatStore();
|
||||
|
||||
const addMessage = (message) => {
|
||||
$store.addMessage({
|
||||
role: 'user',
|
||||
cmd: 'common',
|
||||
senderName: '匿名',
|
||||
content: message,
|
||||
});
|
||||
input.value = '';
|
||||
};
|
||||
|
||||
const input = ref('');
|
||||
const keyboardKeys = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#', 'delete', 'confirm'];
|
||||
|
||||
const handleInput = (char) => {
|
||||
if (char === 'delete') {
|
||||
input.value = input.value.slice(0, -1);
|
||||
} else if (char === 'confirm') {
|
||||
addMessage(input.value);
|
||||
} else {
|
||||
input.value += char;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.chat-input {
|
||||
position: relative;
|
||||
height: 320px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 9;
|
||||
}
|
||||
.input-box {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
padding: 15px;
|
||||
}
|
||||
.input {
|
||||
box-sizing: border-box;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 2px solid transparent;
|
||||
background:
|
||||
linear-gradient(white, white) padding-box,
|
||||
linear-gradient(45deg, #f6855c, #e29cf9, #5cacfe) border-box;
|
||||
padding-left: 5px;
|
||||
}
|
||||
.keyboard-grid {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
background: #d1d5db;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-template-rows: repeat(4, 1fr);
|
||||
grid-gap: 10px 6px;
|
||||
padding: 10px 6px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.keyboard-grid .keyboard-key {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 25px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 1px 0 0 #898a8d;
|
||||
background: #fff;
|
||||
}
|
||||
.keyboard-key-delete,
|
||||
.keyboard-key-confirm {
|
||||
grid-column: 4;
|
||||
font-size: 18px !important;
|
||||
}
|
||||
.keyboard-key-delete {
|
||||
grid-row: 1 / span 2;
|
||||
}
|
||||
.keyboard-key-confirm {
|
||||
grid-row: 3 / span 2;
|
||||
}
|
||||
.keyboard-key-delete > span {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-self: center;
|
||||
}
|
||||
.keyboard-key-delete > span > span {
|
||||
margin-top: 5px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import ChatInput from './components/ChatInput.vue';
|
||||
import ChatMessages from './components/ChatMessages.vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="chat-container">
|
||||
<!-- 聊天内容区域 -->
|
||||
<ChatMessages />
|
||||
|
||||
<!-- 底部输入区域 -->
|
||||
<ChatInput />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.chat-container {
|
||||
width: 100vw;
|
||||
height: calc(100vh - 48px - 33px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue