chat-pc/src/views/message/inner/IndexContent.vue

290 lines
8.1 KiB
Vue

<script lang="ts" setup>
import { reactive, computed, watch } from 'vue'
import { NDrawer, NCard, NTag } from 'naive-ui'
import { useUserStore, useDialogueStore, useUploadsStore } from '@/store'
import PanelHeader from './panel/PanelHeader.vue'
import PanelContent from './panel/PanelContent.vue'
import PanelFooter from './panel/PanelFooter.vue'
import GroupPanel from '@/components/group/GroupPanel.vue'
import GroupNotice from '@/components/group/GroupNotice.vue'
import UploadsModal from '@/components/base/UploadsModal.vue'
import customModal from '@/components/common/customModal.vue'
import historyRecord from '@/components/search/searchByCondition.vue'
const userStore = useUserStore()
const dialogueStore = useDialogueStore()
const uploadsStore = useUploadsStore()
const members = computed(() => dialogueStore.members)
const isShowEditor = computed(() => dialogueStore.isShowEditor)
// 当前对话参数
const talkParams = reactive({
uid: computed(() => userStore.uid),
index_name: computed(() => dialogueStore.index_name),
type: computed(() => dialogueStore.talk.talk_type),
receiver_id: computed(() => dialogueStore.talk.receiver_id),
username: computed(() => dialogueStore.talk.username),
online: computed(() => dialogueStore.online),
keyboard: computed(() => dialogueStore.keyboard),
num: computed(() => dialogueStore.members.length)
})
const state = reactive({
// 是否显示群面板
isShowGroupAside: false,
isShowGroupNotice: false,
isShowSearchRecordByConditionModal: false, //是否显示按条件搜索记录弹窗
customSearchRecordByConditionModalStyle: {
width: '997px',
height: '740px',
backgroundColor: '#F9F9FD'
}, //按条件搜索记录弹窗样式
searchRecordByConditionText: '', //按条件搜索记录文本
conditionTag: '', //当前条件标签
conditionType: '' //当前条件类型
})
const events = {
notice: () => {
state.isShowGroupNotice = !state.isShowGroupNotice
},
group: () => {
state.isShowGroupAside = !state.isShowGroupAside
}
}
watch(
() => talkParams,
(newValue, oldValue) => {
console.log(newValue)
},
{ deep: true, immediate: true }
)
// Header 工具栏事件
const onPanelHeaderEvent = (eventType: string) => {
events[eventType] && events[eventType]()
}
//点击切换搜索条件/分类
const changeConditionTag = (tag) => {
console.log(tag)
state.conditionType = tag
if (tag === 'file') {
state.conditionTag = '文件'
} else if (tag === 'imgAndVideo') {
state.conditionTag = '图片与视频'
} else if (tag === 'date') {
state.conditionTag = '日期'
} else if (tag === 'member') {
state.conditionTag = '群成员'
} else {
state.conditionTag = ''
}
}
</script>
<template>
<section id="drawer-container" class="el-container is-vertical">
<!-- 头部区域 -->
<header class="el-header bdr-b">
<PanelHeader
:type="talkParams.type"
:username="talkParams.username"
:online="talkParams.online"
:keyboard="talkParams.keyboard"
:num="talkParams.num"
@evnet="onPanelHeaderEvent"
/>
</header>
<!-- 聊天区域 -->
<main class="el-main">
<PanelContent
:uid="talkParams.uid"
:talk_type="talkParams.type"
:receiver_id="talkParams.receiver_id"
:index_name="talkParams.index_name"
/>
</main>
<!-- 编辑器区域 -->
<footer
v-show="isShowEditor"
class="el-footer"
:style="{ height: 200 + 'px' }"
v-dropsize="{ min: 200, max: 600, direction: 'top', key: 'editor' }"
>
<PanelFooter
:uid="talkParams.uid"
:index_name="talkParams.index_name"
:talk_type="talkParams.type"
:receiver_id="talkParams.receiver_id"
:online="talkParams.online"
:members="members"
/>
</footer>
</section>
<n-drawer
v-model:show="uploadsStore.isShow"
:width="400"
placement="right"
:trap-focus="false"
:block-scroll="false"
show-mask="transparent"
to="#drawer-container"
>
<UploadsModal />
</n-drawer>
<n-drawer
v-model:show="state.isShowGroupNotice"
:width="400"
placement="right"
:trap-focus="false"
:block-scroll="false"
show-mask="transparent"
to="#drawer-container"
>
<GroupNotice :group-id="talkParams.receiver_id" @close="state.isShowGroupNotice = false" />
</n-drawer>
<n-drawer
v-model:show="state.isShowGroupAside"
:width="400"
placement="right"
:trap-focus="false"
:block-scroll="false"
show-mask="transparent"
to="#drawer-container"
>
<GroupPanel
:gid="talkParams.receiver_id"
@close="state.isShowGroupAside = false"
:talkType="talkParams.type"
@handleSearchRecordByConditionModalShow="state.isShowSearchRecordByConditionModal = true"
/>
</n-drawer>
<customModal
v-model:show="state.isShowSearchRecordByConditionModal"
:title='`${talkParams.type === 1 ? "与" : ""}"${talkParams.username}"的聊天记录`'
:style="state.customSearchRecordByConditionModalStyle"
:customCloseBtn="true"
:closable="false"
>
<template #content>
<div class="search-record-modal-searchArea">
<n-card style="padding: 0 12px;">
<div class="search-record-input">
<span class="search-record-input-title">搜索</span>
<n-input
type="text"
v-model:value="state.searchRecordByConditionText"
placeholder="请输入"
clearable
>
<template #clear-icon>
<img src="@/assets/image/icon/close-btn-grey-line.png" alt="close" />
</template>
<template #prefix>
<n-tag closable v-if="state.conditionTag" @close="changeConditionTag('')">
{{ state.conditionTag }}
</n-tag>
</template>
</n-input>
</div>
<div class="search-area-condition">
<span @click="changeConditionTag('file')">文件</span>
<span @click="changeConditionTag('imgAndVideo')">图片与视频</span>
<span @click="changeConditionTag('date')">日期</span>
<span @click="changeConditionTag('member')">群成员</span>
</div>
</n-card>
</div>
<div class="search-record-modal-content">
<n-card style="padding: 0 12px;">
<div class="search-record-card" v-if="state.searchRecordByConditionText || state.conditionType">
<historyRecord :conditionType="state.conditionType" />
</div>
<div class="search-record-empty" v-if="!state.searchRecordByConditionText && !state.conditionType">
<img src="@/assets/image/chatList/search-empty.png" alt="" />
<span>无内容</span>
</div>
</n-card>
</div>
</template>
</customModal>
</template>
<style lang="less" scoped>
.drawer-target {
overflow: hidden;
}
.search-record-modal-searchArea {
box-sizing: border-box;
width: 100%;
padding: 0 12px;
:deep(.n-card) {
border: 0;
box-shadow: 0 3px 6px 1px rgba(188, 188, 188, 0.18);
}
:deep(.n-card__content) {
padding: 27px 12px 0;
}
.search-record-input {
display: flex;
align-items: center;
justify-content: center;
.search-record-input-title {
width: 78px;
}
}
.search-area-condition {
display: flex;
align-items: center;
justify-content: flex-start;
padding: 22px 0 11px;
span {
font-size: 14px;
color: #46299d;
font-weight: 400;
line-height: 20px;
margin: 0 62px 0 0;
cursor: pointer;
}
}
}
.search-record-modal-content {
box-sizing: border-box;
width: 100%;
padding: 0 12px;
margin: 18px 0 0;
:deep(.n-card) {
border: 0;
box-shadow: 0 3px 6px 1px rgba(188, 188, 188, 0.18);
}
.search-record-card {
}
.search-record-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 455px;
box-sizing: border-box;
img {
width: 160px;
height: 104px;
}
span {
font-size: 14px;
color: #999;
font-weight: 400;
margin: 13px 0 0;
}
}
}
</style>