聊天模块

This commit is contained in:
icssoa 2022-06-08 18:37:55 +08:00
parent ae58e804f9
commit e4ad03a744
6 changed files with 351 additions and 1 deletions

View File

@ -3,4 +3,4 @@ export * from "./bootstrap";
export * from "./hook";
export * from "./router";
export * from "./config";
export { storage } from "./utils";
export { storage, module } from "./utils";

View File

@ -19,6 +19,10 @@
<!-- 工具栏 -->
<ul class="app-topbar__tools">
<li>
<cl-chat />
</li>
<li>
<cl-theme />
</li>
@ -115,6 +119,7 @@ function onCommand(name: string) {
width: 45px;
border-radius: 3px;
cursor: pointer;
margin-left: 10px;
&:hover {
background-color: rgba(0, 0, 0, 0.1);

View File

@ -0,0 +1,130 @@
<template>
<div class="cl-chat__wrap">
<div class="cl-chat__icon" @click="open">
<el-badge :value="19">
<el-icon><BellFilled /></el-icon>
</el-badge>
</div>
<!-- 弹框 -->
<cl-dialog
v-model="visible"
title="聊天窗口"
height="630px"
width="1200px"
keep-alive
custom-class="cl-chat__dialog"
:close-on-click-modal="false"
append-to-body
:controls="['slot-expand', 'cl-flex1', 'fullscreen', 'close']"
>
<div class="cl-chat">
<chat-session />
<chat-message />
</div>
<!-- 展开按钮 -->
<template #slot-expand>
<button class="cl-dialog__controls-icon">
<el-icon @click="session.visible = false" v-if="session.visible">
<notebook />
</el-icon>
<el-icon @click="session.visible = true" v-else>
<arrow-left />
</el-icon>
</button>
</template>
</cl-dialog>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive } from "vue";
export default defineComponent({
name: "cl-chat"
});
</script>
<script lang="ts" setup>
import { provide, ref, watch } from "vue";
import { module } from "/@/cool/utils";
import { useCool } from "/@/cool";
import { useBase } from "/$/base";
import ChatMessage from "./message.vue";
import ChatSession from "./session.vue";
import { Notebook, ArrowLeft, BellFilled } from "@element-plus/icons-vue";
const { service } = useCool();
//
const { app } = useBase();
//
const { options } = module.get("upload");
//
const visible = ref<boolean>(false);
//
const session = reactive({
visible: true,
list: []
});
//
watch(
() => app.browser.isMini,
(val) => {
session.visible = val ? false : true;
},
{
immediate: true
}
);
//
function open() {
visible.value = true;
}
//
function close() {
visible.value = false;
}
provide("chat", {
session
});
defineExpose({
open,
close
});
</script>
<style lang="scss">
.cl-chat {
display: flex;
background-color: #eee;
height: 100%;
padding: 5px;
box-sizing: border-box;
&__icon {
.el-badge__content {
transform: translateY(-50%) translateX(100%) scale(0.8) !important;
}
}
&__dialog {
.el-dialog__body {
padding: 0;
}
}
&__footer {
padding: 9px 0;
}
}
</style>

View File

@ -0,0 +1,69 @@
<template>
<div class="cl-chat__message">
<div class="head"></div>
<div class="list scroller1"></div>
<div class="footer">
<div class="tools">
<ul>
<li></li>
</ul>
</div>
<div class="input">
<el-input type="textarea" :rows="1" placeholder="输入内容"></el-input>
<el-button type="success">发送</el-button>
</div>
</div>
</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.cl-chat__message {
display: flex;
flex-direction: column;
background-color: #fff;
flex: 1;
border-radius: 5px;
.head {
display: flex;
height: 50px;
border-bottom: 1px solid #eee;
}
.list {
flex: 1;
}
.footer {
border-top: 1px solid #eee;
padding: 10px;
.tools {
display: flex;
margin-bottom: 10px;
ul {
li {
height: 30px;
width: 30px;
border-radius: 3px;
background-color: #eee;
margin-right: 10px;
list-style: none;
}
}
}
.input {
display: flex;
.el-button {
margin-left: 10px;
}
}
}
}
</style>

View File

@ -0,0 +1,130 @@
<template>
<div
class="cl-chat__session"
:class="{
'is-position': app.browser.isMini,
'is-show': chat?.session.visible
}"
>
<div class="head"></div>
<div class="list scroller1">
<div class="item" v-for="(item, index) in 13" :key="index">
<div class="avatar">
<el-badge value="2">
<el-avatar shape="square"></el-avatar>
</el-badge>
</div>
<div class="det">
<p class="name">神仙都没用</p>
<p class="message">
https://g0qwq7gr7l.feishu.cn/docx/doxcnkMF3PFehilJTyHbEivkUod
</p>
</div>
<div class="status">
<p class="date">2022-04-21 12:22</p>
<el-tag size="small">厦门</el-tag>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { useChat } from "../hooks";
import { useBase } from "/$/base";
const { app } = useBase();
const { chat } = useChat();
</script>
<style lang="scss" scoped>
.cl-chat__session {
height: 100%;
width: 0;
background-color: #fff;
overflow: hidden;
transition: width 0.2s ease-in-out;
border-radius: 5px;
&.is-show {
width: 350px;
margin-right: 5px;
}
&.is-position {
position: absolute;
left: 5px;
top: 51px;
height: calc(100% - 56px);
z-index: 3000;
&.is-show {
width: calc(100% - 10px);
}
}
.head {
display: flex;
height: 50px;
border-bottom: 1px solid #f7f7f7;
}
.list {
height: calc(100% - 51px);
.item {
display: flex;
padding: 15px 10px;
cursor: pointer;
.avatar {
margin-right: 15px;
:deep(.el-badge__content) {
transform: translateY(-50%) translateX(100%) scale(0.8) !important;
}
}
.det {
flex: 1;
.name,
.message {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
.name {
font-size: 14px;
margin-bottom: 2px;
}
.message {
font-size: 12px;
color: #666;
}
}
.status {
display: flex;
flex-direction: column;
align-items: flex-end;
font-size: 12px;
.date {
margin-bottom: 5px;
}
}
&:hover {
background-color: #f7f7f7;
}
}
}
}
</style>

View File

@ -0,0 +1,16 @@
import { inject } from "vue";
declare interface Chat {
session: {
visible: boolean;
list: any[];
};
}
export function useChat() {
const chat = inject<Chat>("chat");
return {
chat
};
}