123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664 |
- <template>
- <div style="display:flex" ref="outerDom" v-loading="loading">
- <div style="overflow:auto" :style="{width:boxWidth+'px',height:boxHeight+'px'}">
- <div class="box">
- <div style="
- margin-bottom: 10px;
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- ">
- <el-button :disabled="currentMailIndex === 0" @click="handleChangeEail('10')">上一封</el-button>
- <el-button :disabled="currentMailIndex === allLength - 1" @click="handleChangeEail('20')">下一封</el-button>
- <el-button type="primary" @click="handleReply('10')">回复</el-button>
- <el-button type="primary" @click="handleReply('30')">全部回复</el-button>
- <el-button type="warning" @click="handleReply('20')">转发</el-button>
- <el-button @click="handleReply('40')">再次编辑</el-button>
- <el-button @click="handleMove">移动</el-button>
- <el-button @click="handleRemove">删除</el-button>
- <div style="
- background-color: #eff6ff;
- padding: 6px;
- margin-left: 10px;
- cursor: pointer;
- border-radius: 2px 2px 2px 2px;
- " @click="handleAddTag">
- <span class="iconfont icon-icon_biaoqian2" style="color: #0084ff; font-size: 20px"></span>
- </div>
- <!-- <el-tag
- style="margin-left: 8px; cursor: pointer"
- type="success"
- @click="handleAddTag"
- >
- +
- </el-tag> -->
- </div>
- <div class="top">
- <div class="top-row">
- <div class="subject">
- {{ subject }}
- </div>
- </div>
- <div class="top-row" v-if="mailTagList && mailTagList.length > 0">
- <el-tag style="margin-left: 8px" type="success" closable v-for="(tag, index) in mailTagList" :key="index" @close="tagClose(tag)">
- {{ tag.name }}
- </el-tag>
- </div>
- <div class="top-row">
- <div class="label">发 件 人:</div>
- <div class="value">
- <span v-for="item in replyTo" :key="item.id" style="margin-right: 10px">
- {{ item.email || item.personalName }}</span>
- </div>
- </div>
- <div class="top-row">
- <div class="label">收 件 人:</div>
- <div class="value">
- <span v-for="item in to" :key="item.id" style="margin-right: 10px">{{
- item.email || item.personalName
- }}</span>
- </div>
- </div>
- <div class="top-row" v-if="cc && cc.length > 0">
- <div class="label">抄 送 人:</div>
- <div class="value">
- <span v-for="item in cc" :key="item.id" style="margin-right: 10px">
- {{ item.email || item.personalName }}</span>
- </div>
- </div>
- <div class="top-row" v-if="bcc && bcc.length > 0">
- <div class="label">密 送 人:</div>
- <div class="value">
- <span v-for="item in bcc" :key="item.id" style="margin-right: 10px">
- {{ item.email || item.personalName }}</span>
- </div>
- </div>
- <div class="top-row">
- <div class="label">时 间:</div>
- <div class="value">
- {{ time }}
- </div>
- </div>
- <div class="top-row" v-if="fileList && fileList.length > 0">
- <div class="label">附 件:</div>
- <div class="value">
- <div v-for="(item, index) in fileList" style="margin-right: 20px; display: flex; align-items: center" :key="index">
- <span style="cursor: pointer" @click="handleClickFile(item)">{{
- item.name
- }}</span>
- <span style="margin-left: 8px; cursor: pointer" @click="handleClickDownload(item)"><el-icon color="#0084FF">
- <Download />
- </el-icon></span>
- </div>
- </div>
- </div>
- </div>
- <div class="body">
- <iframe frameborder="0" allowTransparency="true" style="
- width: 99% !important;
- overflow-x: scroll;
- padding-top: 10px;
- " :srcdoc="showBodyText(detailsData.data.content)" :ref="'iframeText_' + mailStore.currentId" :id="'iframeText_' + mailStore.currentId">
- </iframe>
- </div>
- </div>
- </div>
- <div style="width:210px;margin-left:10px;overflow:auto" :style="{height:boxHeight+'px'}" v-if="isShowCommunication">
- <el-tabs v-model="activeName" class="demo-tabs" type="card" @tab-click="handleClick">
- <el-tab-pane label="往来附件" name="first"></el-tab-pane>
- <el-tab-pane label="往来邮件" name="second"></el-tab-pane>
- </el-tabs>
- <div class="communication">
- <div class="list" v-show="activeName=='first'">
- <div class="item" v-for="(item,index) in communicationAtt" :key="item.id" @click="handleRowClick(item)">
- <div>
- 发件时间: {{item.sendDate}}
- </div>
- <div style="margin:5px 0">
- 主题: {{item.subject}}
- </div>
- <div>
- 附件: aa.png
- </div>
- </div>
- </div>
- <div class="list" v-show="activeName=='second'">
- <div class="item" v-for="(item,index) in communicationMail" :key="item.id" @click="handleRowClick(item)">
- <div>
- 发件时间: {{item.sendDate}}
- </div>
- <div style="margin-top:5px">
- 主题: {{item.subject}}
- </div>
- </div>
- </div>
- </div>
- </div>
- <el-dialog title="移动邮件" 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="添加标签" v-model="tagDialog" width="300px" destroy-on-close v-loading="submitLoading">
- <byForm :formConfig="tagFormConfig" :formOption="formOption" v-model="formData.tagData" :rules="rules" 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";
- import { nextTick } from "vue";
- const { proxy } = getCurrentInstance();
- const outerDom = ref(null);
- const boxHeight = ref(0);
- const boxWidth = ref(700);
- const getTableHeight = () => {
- boxHeight.value = window.innerHeight - 180;
- };
- getTableHeight();
- window.addEventListener("resize", () => {
- getTableHeight();
- });
- const isShowCommunication = ref(true);
- const mailStore = useMailStore();
- let loading = ref(false);
- const detailsData = reactive({
- data: {},
- });
- const currentMailIndex = computed(() => mailStore.currentMailIndex);
- const allLength = computed(() => mailStore.mailDataList.length);
- const to = ref([]);
- const cc = ref([]);
- const bcc = ref([]);
- const replyTo = ref([]);
- const fileList = ref([]);
- const requestData = ref({});
- const time = ref("");
- const subject = 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: "treeSelect",
- prop: "myFolderId",
- label: "文件夹",
- disabled: false,
- itemWidth: 100,
- data: myFolderTreeData.value,
- style: {
- width: "100%",
- },
- },
- ]);
- const formData = reactive({
- myFolderData: {},
- tagData: {},
- });
- const rules = ref({
- myFolderId: [{ required: true, message: "请选择文件夹", trigger: "change" }],
- myTagId: [{ required: true, message: "请选择标签", trigger: "change" }],
- });
- const allTagList = ref([]);
- const mailTagList = ref([]);
- const tagForm = ref(null);
- const tagDialog = ref(false);
- const tagFormConfig = computed(() => [
- {
- type: "select",
- prop: "myTagId",
- label: "标签名称",
- disabled: false,
- itemWidth: 100,
- data: allTagList.value,
- style: {
- width: "100%",
- },
- },
- ]);
- const getMyFolderTree = (flag) => {
- if (flag) {
- setTimeout(() => {
- proxy
- .post("/myFolder/tree", { mailboxId: mailStore.selectMail.id })
- .then((res) => {
- myFolderTreeData.value = res.map((x) => ({ ...x, value: x.id }));
- });
- }, 1500);
- } else {
- proxy
- .post("/myFolder/tree", { mailboxId: mailStore.selectMail.id })
- .then((res) => {
- myFolderTreeData.value = res.map((x) => ({ ...x, value: x.id }));
- });
- }
- };
- const handleMove = () => {
- formData.myFolderData.messageId = mailStore.currentMenu.messageId;
- myFolderDialog.value = true;
- };
- const handleRemove = () => {
- ElMessageBox.confirm(`此操作将删除该邮件, 是否继续?`, "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- }).then(() => {
- // 删除
- proxy
- .post("/mailService/deleteMail", {
- id: mailStore.currentMenu.messageId,
- type: mailStore.currentMenu.type,
- })
- .then((res) => {
- ElMessage({
- message: `操作成功!`,
- type: "success",
- });
- });
- });
- };
- const submitMyFolderForm = () => {
- myFolderForm.value.handleSubmit(() => {
- submitLoading.value = true;
- proxy.post("/myFolderMessage/add", formData.myFolderData).then(
- (res) => {
- ElMessage({
- message: `操作成功!`,
- type: "success",
- });
- myFolderDialog.value = false;
- submitLoading.value = false;
- getMyFolderTree(false);
- },
- (err) => {
- submitLoading.value = false;
- }
- );
- });
- };
- const getAllTagData = () => {
- proxy
- .post("/myTag/page", {
- pageNum: 1,
- pageSize: 9999,
- id: useUserStore().user.userId,
- })
- .then((res) => {
- allTagList.value = res.rows;
- });
- };
- const getMailTag = () => {
- if (mailStore.currentMenu.messageId) {
- proxy
- .post("/myTag/getListByMessageId", {
- id: mailStore.currentMenu.messageId,
- })
- .then((res) => {
- mailTagList.value = res;
- });
- }
- };
- const tagClose = (tag) => {
- proxy
- .post("/myTagMessage/deleteTag", {
- myTagId: tag.id,
- messageId: mailStore.currentMenu.messageId,
- })
- .then(() => {
- ElMessage({
- message: "操作成功",
- type: "success",
- });
- getMailTag();
- });
- };
- const handleAddTag = () => {
- formData.tagData.messageId = mailStore.currentMenu.messageId;
- formData.tagData.myTagId = "";
- tagDialog.value = true;
- };
- const submitTagForm = () => {
- tagForm.value.handleSubmit(() => {
- submitLoading.value = true;
- proxy.post("/myTagMessage/add", formData.tagData).then(
- (res) => {
- ElMessage({
- message: `操作成功!`,
- type: "success",
- });
- tagDialog.value = false;
- submitLoading.value = false;
- getMailTag();
- },
- (err) => {
- submitLoading.value = false;
- }
- );
- });
- };
- const getDetails = (messageId) => {
- loading.value = true;
- proxy
- .post("/mailService/getMessageDetail", {
- type: mailStore.currentMenu.type,
- messageId,
- })
- .then((res) => {
- if (mailStore.currentMenu.time) {
- time.value = mailStore.currentMenu.time;
- }
- if (mailStore.currentMenu.subject) {
- subject.value = mailStore.currentMenu.subject;
- }
- if (mailStore.currentMenu.fromEmail) {
- // 如果发件人是自己的话就不显示往来邮件
- let flag =
- mailStore.currentMenu.fromEmail == mailStore.selectMail.mailUser;
- if (flag) {
- isShowCommunication.value = false;
- nextTick(() => {
- boxWidth.value = outerDom.value.offsetWidth;
- });
- } else {
- getCommunicationData();
- nextTick(() => {
- boxWidth.value = outerDom.value.offsetWidth - 220;
- });
- }
- }
- detailsData.data = res;
- to.value = res.messageAddressList.filter((x) => x.type === 1);
- cc.value = res.messageAddressList.filter((x) => x.type === 2);
- bcc.value = res.messageAddressList.filter((x) => x.type === 3);
- replyTo.value = res.messageAddressList.filter((x) => x.type === 4);
- fileList.value = res.messageAttachmentList;
- loading.value = false;
- });
- };
- const showBodyText = (text) => {
- if (text) {
- let val = JSON.parse(JSON.stringify(text));
- val = val.replace("body {", "tbody {");
- val = val.replace(
- "td, p, li, th {",
- "tbody td, tbody p, tbody li, tbody th {"
- );
- val = val.replace(
- /<p>/g,
- '<p style="margin-block-start: 0; margin-block-end: 0;">'
- );
- return val;
- } else {
- return text;
- }
- };
- const handleReply = (pageType) => {
- // pageType 10为回复 20为转发 30为全部回复 40为再次编辑 0为写信
- let title = "";
- if (pageType === "10") {
- title = "回复";
- } else if (pageType === "20") {
- title = "转发";
- } else if (pageType === "30") {
- title = "全部回复";
- } else if (pageType === "40") {
- title = "再次编辑";
- }
- const menu = {
- title: title,
- type: mailStore.currentMenu.type,
- id: "write",
- pageType: pageType,
- details: {
- ...detailsData.data,
- ...mailStore.currentMenu.row,
- },
- };
- 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 handleChangeEail = (type) => {
- if (type === "10") {
- mailStore.currentMailIndex = currentMailIndex.value - 1;
- } else if (type === "20") {
- mailStore.currentMailIndex = currentMailIndex.value + 1;
- }
- // 拿到更变索引之后的行数据
- const row = mailStore.mailDataList[mailStore.currentMailIndex];
- // 查当前菜单的数据
- const arr = mailStore.currentMenu.id.split(",");
- if (arr.length > 1) {
- const index = mailStore.mailMenuList.findIndex(
- (x) => x.messageId === arr[1]
- );
- const menu = {
- title: row.subject.slice(0, 4) + "...",
- type: mailStore.selectMail.type,
- messageId: row.id,
- id: "detail" + "," + row.id,
- time: row.sendDate,
- row: { ...row },
- };
- const menuItem = mailStore.mailMenuList.find((x) => x.id === menu.id);
- if (menuItem === undefined) {
- mailStore.mailMenuList[index] = menu;
- }
- mailStore.currentMenu = menu;
- mailStore.currentId = menu.id;
- }
- };
- const handleClickFile = (file) => {
- const path = file.path ? file.path : file.url ? file.url : "";
- if (path) {
- window.open(path, "_blank");
- }
- };
- const handleClickDownload = (file) => {
- let xhr = new XMLHttpRequest();
- //域名是华为云的
- xhr.open("GET", `${file.url}`, true);
- xhr.responseType = "blob";
- xhr.send();
- xhr.onreadystatechange = function () {
- if (xhr.readyState === 4 && xhr.status === 200) {
- let url = window.URL.createObjectURL(xhr.response);
- const a = document.createElement("a");
- a.href = url;
- a.download = file.name; // 下载后文件名
- a.style.display = "none";
- document.body.appendChild(a);
- a.click(); // 点击下载
- window.URL.revokeObjectURL(a.href);
- document.body.removeChild(a); // 下载完成移除元素
- }
- };
- };
- onMounted(() => {
- // getMyFolderTree(true);
- // getAllTagData();
- // iframe动态高度
- const iframe = proxy.$refs["iframeText_" + mailStore.currentId];
- iframe.addEventListener("load", () => {
- iframe.style.height =
- iframe.contentWindow.document.body.scrollHeight + 30 + "px";
- });
- });
- const communicationMail = ref([]);
- const communicationAtt = ref([]);
- const getCommunicationData = () => {
- let data = {
- folderId: "",
- type: mailStore.selectMail.type,
- mailboxId: mailStore.selectMail.id,
- dealingsEmail: mailStore.currentMenu.fromEmail,
- };
- proxy.post("/mailService/getMessagePage", data).then((res) => {
- communicationMail.value = res.rows.filter((x) => !x.isAttachments);
- communicationAtt.value = res.rows.filter((x) => x.isAttachments == 1);
- });
- };
- const handleRowClick = (row) => {
- const menu = {
- title: row.subject.slice(0, 4) + "...",
- type: mailStore.selectMail.type,
- messageId: row.id,
- id: "detail" + "," + row.id,
- time: row.sendDate,
- subject: row.subject,
- fromEmail: row.fromEmail,
- row: { ...row },
- };
- const menuItem = mailStore.mailMenuList.find((x) => x.id === menu.id);
- if (menuItem === undefined) {
- mailStore.mailMenuList.push(menu);
- }
- mailStore.currentMenu = menu;
- mailStore.currentId = menu.id;
- };
- const init = () => {
- //实时更换索引
- if (mailStore.currentMenu.messageId) {
- mailStore.currentMailIndex = mailStore.mailDataList.findIndex(
- (x) => x.id === mailStore.currentMenu.messageId
- );
- }
- getDetails(mailStore.currentMenu.messageId);
- getMailTag();
- getMyFolderTree(true);
- getAllTagData();
- };
- const activeName = ref("first");
- defineExpose({
- initFn: init,
- });
- </script>
- <style lang="scss" scoped>
- .box {
- padding: 0 10px;
- font-size: 12px;
- .top {
- padding: 10px;
- background: #eeeeee;
- .top-row {
- display: flex;
- margin-bottom: 10px;
- .subject {
- font-size: 14px;
- font-weight: bold;
- }
- .label {
- min-width: 60px;
- color: #999999;
- text-align: right;
- }
- .value {
- flex: 1;
- color: #333333;
- font-weight: 700;
- margin-right: 10px;
- display: flex;
- flex-wrap: wrap;
- }
- }
- }
- }
- .el-tag {
- background: #ffffff;
- color: #0084ff;
- }
- .el-tag.el-tag--success {
- color: #0084ff;
- }
- :deep(.el-tabs__item) {
- font-size: 12px;
- line-height: 30px;
- height: 30px;
- font-weight: normal;
- }
- :deep(.el-tabs__header) {
- margin: 8px 0;
- height: 32px;
- }
- </style>
- <style lang="scss">
- .top-row {
- .el-tag .el-tag__close {
- color: #0084ff !important;
- }
- .el-tag .el-tag__close:hover {
- color: #fff !important;
- background: #0084ff !important ;
- }
- }
- .communication {
- font-size: 12px;
- padding: 0 10px;
- .list {
- display: flex;
- flex-direction: column;
- .item {
- border-bottom: 1px solid #eee;
- margin-bottom: 10px;
- cursor: pointer;
- padding-bottom: 10px;
- }
- }
- }
- </style>
|