<template> <div class="left"> <div class="top"> <el-dropdown> <span class="mail"> {{ selectMail.mailUser }} <el-icon class="el-icon--right"> <arrow-down /> </el-icon> </span> <template #dropdown> <el-dropdown-menu> <el-dropdown-item v-for="item in mailList" :key="item.id" @click="handleClickMail(item)" >{{ item.mailUser }}</el-dropdown-item > </el-dropdown-menu> </template> </el-dropdown> <el-tabs v-model="activeName" class="demo-tabs" stretch> <el-tab-pane label="邮箱" name="first"> <template #label> <div> <i class="iconfont icon-iconm_dianzyx" style="margin-right: 5px" ></i> <span>邮箱</span> </div> </template> </el-tab-pane> <el-tab-pane label="联系人" name="second"> <template #label> <div> <i class="iconfont icon-icomm_contact" style="margin-right: 5px" ></i> <span>联系人</span> </div> </template> </el-tab-pane> <el-tab-pane label="客户" name="third"> <template #label> <div> <i class="iconfont icon-icon_kh" style="margin-right: 5px"></i> <span>客户</span> </div> </template> </el-tab-pane> </el-tabs> <div> <el-button type="primary" style="width: 100%; font-size: 12px" @click="handleGoWrite()" >写信</el-button > </div> </div> <div class="body"> <div v-if="activeName === 'first'"> <ul class="mail-menu"> <li class="menu-item" v-bind:class="{ 'select-menu': item.id === selectFloderId }" v-for="item in selectMail.mailFolderInfoListCopy" :key="item.id" @click="handleOpenMenu(item, '10')" > <i class="iconfont icon-iconm_inbox leftIcon" v-if="item.sort === 1" ></i> <i class="iconfont icon-iconm_unread leftIcon" v-else-if="item.sort === 2" ></i> <i class="iconfont icon-icomm_draftbox leftIcon" v-else-if="item.sort === 3" ></i> <i class="iconfont icon-iconm_sent leftIcon" v-else-if="item.sort === 4" ></i> <i class="iconfont icon-icomm_delete leftIcon" v-else-if="item.sort === 5" ></i> <i class="iconfont icon-iconm_ljyx leftIcon" v-else-if="item.sort === 6" ></i> <span style="margin-left: 5px">{{ item.name }}</span> </li> </ul> <!-- 员工邮箱 --> <div class="tree" v-if="staffMailData && staffMailData.length > 0"> <el-tree :data="staffMailData" node-key="id" default-expand-all :expand-on-click-node="false" @node-click="(data, node) => clickTreeMail(data, node)" > <template #default="{ node, data }"> <span class="tree-content"> <i class="iconfont icon-icomm_ygyx iconColor" v-if="data.id == '0'" style="margin-right: 5px" ></i> <span>{{ data.mailUser }}</span> </span> </template> </el-tree> </div> <!-- 官方文件夹 --> <div class="tree" v-if="selectMail.otherFolder && selectMail.otherFolder.length > 0" > <el-tree :data="selectMail.otherFolder" node-key="id" default-expand-all :expand-on-click-node="false" @node-click="(data) => handleTreeNodeClick(data, 'official')" > <template #default="{ node, data }"> <span class="tree-content"> <i class="iconfont icon-iconm_gfwjj iconColor" v-if="data.id == '0'" style="margin-right: 5px" ></i> <span>{{ data.name }}</span> </span> </template></el-tree > </div> <!-- 我的文件夹 --> <div class="tree" v-if="myFolderTreeData && myFolderTreeData.length > 0" > <el-tree :data="myFolderTreeData" node-key="id" default-expand-all :expand-on-click-node="false" @node-click="(data) => handleTreeNodeClick(data, 'folder')" > <template #default="{ node, data }"> <span class="tree-content"> <i class="iconfont icon-icomm_wdwjj iconColor" v-if="data.id == '0'" style="margin-right: 5px" ></i> <span>{{ data.label }}</span> <el-popover placement="bottom-start" title="" :width="200" trigger="click" > <div default style="display: flex"> <el-button size="small" @click.stop="handleEditFolder(data, 'add')" >添加</el-button > <el-button size="small" v-if="data.id != '0'" @click.stop="handleEditFolder(data, 'edit')" >编辑</el-button > <el-button size="small" v-if="data.id != '0'" @click.stop="handleDelFolder(data)" >删除</el-button > </div> <template #reference> <span class="iconfont icon_more iconColor" style="padding-bottom: 5px; margin-left: auto" >...</span > </template> </el-popover> </span> </template> </el-tree> </div> <!-- 我的标签 --> <div class="tree" v-if="tagsTreeData && tagsTreeData.length > 0"> <el-tree :data="tagsTreeData" node-key="id" default-expand-all :expand-on-click-node="false" @node-click="(data) => handleTreeNodeClick(data, 'tag')" > <template #default="{ node, data }"> <span class="tree-content"> <i class="iconfont icon-icomm_label iconColor" v-if="data.id == '0'" style="margin-right: 5px" ></i> <span>{{ data.name }}</span> <el-popover placement="bottom-start" title="" :width="150" trigger="click" > <div default style="display: flex"> <el-button size="small" v-if="data.id == '0'" @click.stop="handleEditTag(data, 'add')" >添加</el-button > <el-button size="small" v-if="data.id != '0'" @click.stop="handleEditTag(data, 'edit')" >编辑</el-button > <el-button size="small" v-if="data.id != '0'" @click.stop="handleDelTag(data)" >删除</el-button > </div> <template #reference> <span class="iconfont icon_more iconColor" style="padding-bottom: 5px; margin-left: auto" >...</span > </template> </el-popover> </span> </template> </el-tree> </div> </div> <div v-if="activeName === 'second'">暂未开放</div> <div v-if="activeName === 'third'">暂未开放</div> </div> <el-dialog :title="editType === 'add' ? '添加文件夹' : '编辑文件夹'" v-model="myFolderDialog" width="300px" destroy-on-close v-loading="submitLoading" > <byForm :formConfig="myFolderFormConfig" :formOption="formOption" v-model="formData.myFolderData" :rules="rules" ref="myFolderForm" > </byForm> <template #footer> <el-button @click="myFolderDialog = false" size="large" >取 消</el-button > <el-button type="primary" @click="submitMyFolderForm()" size="large" :loading="submitLoading" > 确 定 </el-button> </template> </el-dialog> <el-dialog :title="editType === 'add' ? '添加标签' : '编辑标签'" v-model="tagDialog" width="300px" destroy-on-close v-loading="submitLoading" > <byForm :formConfig="tagFormConfig" :formOption="formOption" v-model="formData.tagData" :rules="tagRules" ref="tagForm" > </byForm> <template #footer> <el-button @click="tagDialog = false" size="large">取 消</el-button> <el-button type="primary" @click="submitTagForm()" size="large" :loading="submitLoading" > 确 定 </el-button> </template> </el-dialog> </div> </template> <script setup> import useMailStore from "@/store/modules/mail"; import useUserStore from "@/store/modules/user"; import byForm from "@/components/byForm/index"; import { ElMessage, ElMessageBox } from "element-plus"; const mailStore = useMailStore(); const { proxy } = getCurrentInstance(); let selectMail = ref({}); let activeName = ref("first"); const mailMapData = { inbox: ["INBOX"], unread: ["UNREAD"], draft: ["草稿箱", "草稿", "Drafts"], sent: ["已发送", "Sent Messages"], delete: ["已删除", "Deleted Messages"], waste: ["垃圾邮件", "Junk"], }; let selectFloderId = ref(""); const mailList = ref([]); const staffMailData = ref([]); const formOption = reactive({ inline: true, labelWidth: 100, itemWidth: 100, }); const myFolderForm = ref(null); const myFolderTreeData = ref([]); const myFolderDialog = ref(false); const submitLoading = ref(false); const editType = ref("add"); const myFolderFormConfig = computed(() => [ { type: "input", prop: "name", label: "文件夹名称", disabled: false, itemWidth: 100, }, ]); const formData = reactive({ myFolderData: {}, tagData: {}, }); const rules = ref({ name: [{ required: true, message: "请输入文件夹名称", trigger: "blur" }], }); const tagForm = ref(null); const tagsTreeData = ref([]); const tagDialog = ref(false); const tagFormConfig = computed(() => [ { type: "input", prop: "name", label: "标签名称", disabled: false, itemWidth: 100, }, ]); const tagRules = ref({ name: [{ required: true, message: "请输入标签名称", trigger: "blur" }], }); const getTagsList = () => { proxy .post("/myTag/page", { pageNum: 1, pageSize: 9999, id: useUserStore().user.userId, }) .then((res) => { if (res && res.rows.length > 0) { tagsTreeData.value = [ { name: "我的标签", id: "0", children: res.rows, }, ]; } }); }; const submitTagForm = () => { tagForm.value.handleSubmit(() => { submitLoading.value = true; proxy.post("/myTag/" + editType.value, formData.tagData).then( (res) => { ElMessage({ message: `操作成功!`, type: "success", }); tagDialog.value = false; submitLoading.value = false; getTagsList(selectMail.value); }, (err) => { submitLoading.value = false; } ); }); }; const handleEditTag = (data, type) => { editType.value = type; if (type === "add") { formData.tagData.name = ""; formData.tagData.type = selectMail.value.type; formData.tagData.mailboxId = selectMail.value.id; } else { formData.tagData = data; } tagDialog.value = true; }; const handleDelTag = (data) => { ElMessageBox.confirm(`此操作将删除该标签, 是否继续?`, "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }).then(() => { // 删除 proxy.post("/myTag/delete", { id: data.id }).then((res) => { ElMessage({ message: `操作成功!`, type: "success", }); getTagsList(); }); }); }; const getMyFolderTree = (data) => { proxy.post("/myFolder/tree", { mailboxId: data.id }).then((res) => { if (res && res.length > 0) { myFolderTreeData.value = [ { label: "我的文件夹", id: "0", children: res, }, ]; } }); }; const submitMyFolderForm = () => { myFolderForm.value.handleSubmit(() => { submitLoading.value = true; proxy.post("/myFolder/" + editType.value, formData.myFolderData).then( (res) => { ElMessage({ message: `操作成功!`, type: "success", }); myFolderDialog.value = false; submitLoading.value = false; getMyFolderTree(selectMail.value); }, (err) => { submitLoading.value = false; } ); }); }; const handleEditFolder = (data, type) => { formData.myFolderData = {}; editType.value = type; if (type === "add") { formData.myFolderData.parentId = data.id; } else { formData.myFolderData = data; formData.myFolderData.name = data.label; } formData.myFolderData.type = selectMail.value.type; formData.myFolderData.mailboxId = selectMail.value.id; myFolderDialog.value = true; }; const handleDelFolder = (data) => { ElMessageBox.confirm(`此操作将删除该文件夹, 是否继续?`, "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }).then(() => { // 删除 proxy.post("/myFolder/delete", { id: data.id }).then((res) => { ElMessage({ message: `操作成功!`, type: "success", }); getMyFolderTree(selectMail.value); }); }); }; const getMialList = () => { proxy.get("/mailService/getUserEmailList").then((res) => { for (let i = 0; i < res.data.length; i++) { const iele = res.data[i]; iele.mailFolderInfoListCopy = []; iele.otherFolder = []; for (let j = 0; j < iele.mailFolderInfoList.length; j++) { const jele = iele.mailFolderInfoList[j]; if (mailMapData["inbox"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "收件箱", sort: 1, }); } else if (mailMapData["unread"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "未读邮件", sort: 2, }); } else if (mailMapData["draft"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "草稿箱", sort: 3, }); } else if (mailMapData["sent"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "已发送", sort: 4, }); } else if (mailMapData["delete"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "已删除", sort: 5, }); } else if (mailMapData["waste"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "垃圾邮件", sort: 6, }); } else { iele.otherFolder.push(jele); } } if (iele.otherFolder.length > 0) { iele.otherFolder = [ { name: "官方文件夹", id: "0", children: iele.otherFolder, }, ]; } iele.mailFolderInfoListCopy.sort((a, b) => a.sort - b.sort); } mailList.value = res.data; if (mailList.value.length) { // 默认赋值第一邮箱 selectMail.value = mailList.value[0]; mailStore.selectMail = mailList.value[0]; // 获取我的文件夹树形 getMyFolderTree(selectMail.value); // 默认打开第一邮箱文件夹 if (selectMail.value.mailFolderInfoListCopy.length > 0) { handleOpenMenu(selectMail.value.mailFolderInfoListCopy[0], "10"); } } }); proxy .post("/mailInfo/getUserEmailList", { id: useUserStore().user.userId }) .then((res) => { if (res && res.length > 0) { res = res.map((x) => { return { ...x, sort: 1, children: x.mailFolderInfoList.map((y) => ({ ...y, mailUser: y.name, })), }; }); for (let i = 0; i < res.length; i++) { const iele = res[i]; iele.mailFolderInfoListCopy = []; iele.otherFolder = []; for (let j = 0; j < iele.mailFolderInfoList.length; j++) { const jele = iele.mailFolderInfoList[j]; if (mailMapData["inbox"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "收件箱", sort: 1, }); } else if (mailMapData["unread"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "未读邮件", sort: 2, }); } else if (mailMapData["draft"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "草稿箱", sort: 3, }); } else if (mailMapData["sent"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "已发送", sort: 4, }); } else if (mailMapData["delete"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "已删除", sort: 5, }); } else if (mailMapData["waste"].includes(jele.name)) { iele.mailFolderInfoListCopy.push({ ...jele, name: "垃圾邮件", sort: 6, }); } else { iele.otherFolder.push(jele); } } if (iele.otherFolder.length > 0) { iele.otherFolder = [ { name: "官方文件夹", id: "0", children: iele.otherFolder, }, ]; } iele.mailFolderInfoListCopy.sort((a, b) => a.sort - b.sort); } staffMailData.value = [ { mailUser: "员工邮箱", id: "0", children: res, }, ]; } }); }; const handleClickMail = (item, flag = true) => { mailStore.mailMenuList = []; selectMail.value = item; mailStore.selectMail = item; // 默认打开第一邮箱文件夹 if (selectMail.value.mailFolderInfoListCopy.length > 0 && flag) { handleOpenMenu(selectMail.value.mailFolderInfoListCopy[0], "10"); } }; const changeFloderId = (val) => { selectFloderId.value = val; }; const handleOpenMenu = (item, listPageType = "10") => { // 10为官方文件夹以及六个外侧文件夹 20为我的文件夹 30为标签文件夹 selectFloderId.value = item.id; const menu = { title: item.name, type: selectMail.value.type, folderId: item.id, id: "folder" + "," + item.id, listPageType, }; // 如没有这个菜单则push const menuItem = mailStore.mailMenuList.find((x) => x.id === menu.id); if (menuItem === undefined) { mailStore.mailMenuList.push(menu); } // 更新当前选择的tab数据和tab的Id值 mailStore.currentMenu = menu; mailStore.currentId = menu.id; }; const handleGoWrite = (mail = "", pageType = "0") => { const menu = { title: "写信", type: selectMail.value.type, id: "write", pageType, }; if (mail) { menu.reMail = mail; } const index = mailStore.mailMenuList.findIndex((x) => x.id === menu.id); if (index >= 0) { mailStore.mailMenuList[index] = menu; } else { mailStore.mailMenuList.push(menu); } mailStore.currentMenu = menu; mailStore.currentId = menu.id; }; const handleTreeNodeClick = (data, type) => { if (data.id != "0") { let menuData = { id: data.id, }; let listPageType = "10"; if (type === "official") { menuData.name = data.name; } else if (type === "folder") { menuData.name = data.label; listPageType = "20"; } else if (type === "tag") { menuData.name = data.name; listPageType = "30"; } handleOpenMenu(menuData, listPageType); } }; const clickTreeMail = (data, node) => { if (data.id !== "0" && data.sort !== 1) { let mailData = node.parent.data; if (mailStore.selectMail.id === mailData.id) { const menuData = { id: data.id, name: data.name, }; handleOpenMenu(menuData, "10"); } else { handleClickMail(mailData, false); handleOpenMenu(data, "10"); } } }; getMialList(); getTagsList(); defineExpose({ handleGoWrite, changeFloderId, }); </script> <style lang="scss" scoped> .left { font-size: 12px; .top { padding: 10px; text-align: center; border-bottom: 1px solid #ddd; .mail { color: #333333; font-weight: 700; font-size: 14px; } } .body { height: calc(100vh - 260px); overflow: auto; // padding: 10px; .mail-menu { list-style: none; margin-block-start: 0; margin-block-end: 0; padding: 0px; padding: 10px 10px 0 10px; .menu-item { display: flex; align-items: center; font-weight: 700; padding-left: 10px; font-size: 12px; width: 100%; height: 40px; line-height: 40px; border-radius: 3px; color: #333333; cursor: pointer; &:hover { background: #ddedfe; } .leftIcon { font-size: 16px; color: #999999; } } } } } .select-menu { background: #ddedfe; color: #0084ff !important; .leftIcon { color: #0084ff !important; } } .tree { margin-top: 10px; border-top: 1px solid #ddd; padding: 10px 10px 0 10px; .tree-content { width: 100%; display: flex; // justify-content: space-between; padding-right: 10px; align-items: center; .iconColor { color: #666 !important; } } } </style> <style lang="scss"> .body { .el-tree-node__content { font-weight: 700; color: #333333 !important; font-size: 12px !important; } } .top { .el-tabs__item { color: #616161; font-size: 12px; } .el-tabs__item:hover { color: #409eff; } .el-tabs__item.is-active { color: #409eff; } } </style>