From ccfd07feeaa670a3d56548d7fea0936e299df95b Mon Sep 17 00:00:00 2001 From: huangyinfeng <1244041895@qq.com> Date: 星期三, 18 九月 2024 14:33:31 +0800 Subject: [PATCH] 部分功能 --- src/components/Tinymce/src/index.vue | 4 src/views/email/Drafts/index.vue | 44 + src/views/email/UnreadEmail/index.vue | 55 + src/views/email/HandlingEmailsOnBehalfOfOthers/components/list.vue | 206 ++++++ src/views/email/components/ListPage/list.vue | 9 src/views/email/HandlingEmailsOnBehalfOfOthers/table.vue | 443 +++++++++++++ src/router/routes/modules/email.ts | 6 src/api/email/model/userListModel.ts | 8 src/views/email/components/ListPage/pageHeadLeft.vue | 2 src/views/email/HandlingEmailsOnBehalfOfOthers/index.vue | 44 + src/views/email/Edit/index.vue | 563 +++++++++------- src/views/email/components/ListPage/table.vue | 25 src/api/email/userList.ts | 19 src/views/email/components/LeftNav.vue | 6 src/views/email/Inbox/index.vue | 7 src/views/email/components/SelectUser/index.vue | 5 src/views/email/components/ListPage/drawerDetail.vue | 511 ++++++++------- src/App.vue | 20 18 files changed, 1,434 insertions(+), 543 deletions(-) diff --git a/src/App.vue b/src/App.vue index 072aa7b..e6c59fb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -17,20 +17,20 @@ import { computed, ref } from 'vue'; import { getCurrentInstance } from 'vue'; -console.log(getCurrentInstance,'=====-'); + console.log(getCurrentInstance, '=====-'); // 鑾峰彇褰撳墠瀹炰緥 -const instance = getCurrentInstance(); -const proxy = instance?.proxy; + const instance = getCurrentInstance(); + const proxy = instance?.proxy; const setCookie = () => { -// 鍏堟鏌roxy鏄惁瀛樺湪锛屽啀杩涜鎿嶄綔 -if (proxy && proxy.$cookies) { - proxy.$cookies.remove('JSESSIONID'); - proxy.$cookies.set('JSESSIONID', '6D5DE448FED8F63528B386BF5E78D3EE.jvm_59_9010', '1d'); -} else { - console.error('proxy瀵硅薄鏈垵濮嬪寲鎴栦笉鍖呭惈$cookies灞炴��'); -} + // 鍏堟鏌roxy鏄惁瀛樺湪锛屽啀杩涜鎿嶄綔 + if (proxy && proxy.$cookies) { + proxy.$cookies.remove('JSESSIONID'); + proxy.$cookies.set('JSESSIONID', '5F931240BCF8638C4FEA7B36277CECE2.jvm_59_9010', '1d'); + } else { + console.error('proxy瀵硅薄鏈垵濮嬪寲鎴栦笉鍖呭惈$cookies灞炴��'); + } }; setCookie(); // support Multi-language diff --git a/src/api/email/model/userListModel.ts b/src/api/email/model/userListModel.ts index 880a8da..8c64bf9 100644 --- a/src/api/email/model/userListModel.ts +++ b/src/api/email/model/userListModel.ts @@ -11,12 +11,12 @@ } export interface sendingMailModel { sender: string; - receiver: string; - cc: string; - bcc: string; + receiver: Object; + cc: Object; + bcc: Object; subject: string; content: string; - fileUNID: string; + attachmentList: string; docCode: string; } diff --git a/src/api/email/userList.ts b/src/api/email/userList.ts index dd3ffa5..7344fbf 100644 --- a/src/api/email/userList.ts +++ b/src/api/email/userList.ts @@ -28,6 +28,9 @@ DELETE_QUICK_TEXT = '/crm/mail/quickText/deleteQuickText.do', GET_MAIL_LIST = '/crm/mail/getMailList.do', GET_USER_INFO = '/crm/base/userInfo.do', + GET_MAIL_INFO = '/crm/mail/getMailInfo.do', + EMAIL_LIST = '/crm/base/emailList.do', + } @@ -125,4 +128,20 @@ url: Api.GET_USER_INFO, params, }) + + + // 鑾峰彇閭欢璇︽儏 + export const getMailInfoApi = (params) => + defHttp.get({ + url: Api.GET_MAIL_INFO, + params, + }) + + + // 鑾峰彇妯$硦鎼滅储浜哄憳 + export const emailListAPi = (params) => + defHttp.post({ + url: Api.EMAIL_LIST, + params, + }) \ No newline at end of file diff --git a/src/components/Tinymce/src/index.vue b/src/components/Tinymce/src/index.vue index c2ef6fb..1053692 100644 --- a/src/components/Tinymce/src/index.vue +++ b/src/components/Tinymce/src/index.vue @@ -7,7 +7,7 @@ v-if="!initOptions.inline" ></textarea> <slot v-else></slot> - <div class="p-2 tox-statusbar"> + <!-- <div class="p-2 tox-statusbar"> <a-upload v-if="isElse" v-model:file-list="fileListTemp" @@ -61,7 +61,7 @@ > </div> </div> - </div> + </div> --> </div> </template> diff --git a/src/router/routes/modules/email.ts b/src/router/routes/modules/email.ts index b55c637..2a01f6a 100644 --- a/src/router/routes/modules/email.ts +++ b/src/router/routes/modules/email.ts @@ -49,7 +49,7 @@ name: 'Index', component: () => import('@/views/email/UnreadEmail/index.vue'), meta: { - title: '閭欢', + title: '鏈閭欢', currentActiveMenu: '/email/index', }, }, @@ -78,7 +78,7 @@ { path: 'HandlingEmailsOnBehalfOfOthers', name: 'HandlingEmailsOnBehalfOfOthers', - component: () => import('@/views/email/Edit/index.vue'), + component: () => import('@/views/email/HandlingEmailsOnBehalfOfOthers/index.vue'), meta: { title: '浠e鐞嗛偖浠�', hideTab: true, @@ -89,7 +89,7 @@ { path: 'Drafts', name: 'Drafts', - component: () => import('@/views/email/Edit/index.vue'), + component: () => import('@/views/email/Drafts/index.vue'), meta: { title: '鑽夌绠�', hideTab: true, diff --git a/src/views/email/Drafts/index.vue b/src/views/email/Drafts/index.vue new file mode 100644 index 0000000..ef2bccf --- /dev/null +++ b/src/views/email/Drafts/index.vue @@ -0,0 +1,44 @@ +<template> + <div> + <PageIndex :pageList="pageList" :mailType='0'></PageIndex> + </div> +</template> + +<script lang="ts" setup> + name: 'Drafts'; + import { ref, onMounted, computed, provide } from 'vue'; + import PageIndex from '@/views/email/components/ListPage/list.vue'; + import { useRoute } from 'vue-router'; + + const route = useRoute(); + // 鑾峰彇褰撳墠瀹屾暣 URL + const routerId = computed(() => { + try { + const url = window.location.href; + if (!url) { + throw new Error('Invalid URL'); + } + const basePart = url.split('?')[1]; + console.log(basePart, 'basePart'); + return basePart; + } catch (error) { + console.error('Error processing URL:', error); + // 杩斿洖榛樿鍊兼垨绌哄瓧绗︿覆 + return ''; + } + }); + import { receiveApi, getMailListApi } from '@/api/email/userList'; + const pageList = ref([]); + function getDataList() { + getMailListApi({ mail: routerId.value, mailType: 0 }).then((res) => { + if (res.code == 0) { + pageList.value = res.data; + } + }); + } + provide('getDataList', getDataList); + onMounted(() => { + getDataList(); + }); +</script> +<style scoped lang="less"></style> diff --git a/src/views/email/Edit/index.vue b/src/views/email/Edit/index.vue index 425d986..4770092 100644 --- a/src/views/email/Edit/index.vue +++ b/src/views/email/Edit/index.vue @@ -1,240 +1,261 @@ <template> - <a-card size="small"> - <div class="p-1"> - <a-form - ref="formRef" - :label-col="{ span: 2 }" - :wrapper-col="{ span: 24 }" - :model="modelRef" - > - <a-form-item :wrapper-col="{ span: 8 }"> - <div style="display: flex; justify-content: space-evenly"> - <a-button type="primary" shape="round" @click="fnHandleSubmit(modelRef)" - >鍙戦��</a-button + <div class="p-3"> + <a-spin :spinning="loading" class="p-1"> + <a-form ref="formRef" :label-col="{ span: 2 }" :wrapper-col="{ span: 24 }" :model="modelRef"> + <a-form-item :wrapper-col="{ span: 8 }"> + <div style="display: flex; justify-content: space-evenly"> + <a-button type="primary" shape="round" @click="fnHandleSubmit(modelRef)">鍙戦��</a-button> + <a-button shape="round" @click="fnSaveMailDrafts">瀛樿崏绋�</a-button> + <a-button shape="round" @click="fnPreview">棰勮</a-button> + <a-button shape="round">鎻愪氦瀹℃壒</a-button> + <a-button shape="round">鍙栨秷</a-button></div + > + </a-form-item> + <a-form-item label="鍙戜欢浜�" v-bind="validateInfos.sender" :wrapper-col="{ span: 12 }"> + <a-select + v-model:value="modelRef.sender" + placeholder="閫夋嫨鍙戜欢浜�" + show-search + :field-names="{ label: 'email', value: 'email' }" + :options="state.senderList" + :filter-option="fnFilterOption" + > + </a-select> + </a-form-item> + <a-form-item label="鏀朵欢浜�" v-bind="validateInfos.recipients" :wrapper-col="{ span: 18 }"> + <a-row> + <a-col class="gutter-row" :span="16"> + <a-select + mode="tags" + placeholder="璇烽�夋嫨鏀朵欢浜烘垨鑰呰緭鍏ユ敹浠朵汉閭" + v-model:value="modelRef.recipients" + :options="state.recipientsList" + :field-names="{ label: 'email', value: 'userName' }" + :maxTagCount="4" + @search="fetchUser" > - <a-button shape="round" @click="fnSaveMailDrafts">瀛樿崏绋�</a-button> - <a-button shape="round" @click="fnPreview">棰勮</a-button> - <a-button shape="round">鎻愪氦瀹℃壒</a-button> - <a-button shape="round">鍙栨秷</a-button></div - > - </a-form-item> - <a-form-item label="鍙戜欢浜�" v-bind="validateInfos.sender" :wrapper-col="{ span: 12 }"> - <a-select - v-model:value="modelRef.sender" - placeholder="閫夋嫨鍙戜欢浜�" - show-search - :field-names="{ label: 'name', value: 'id' }" - :options="state.data" - :filter-option="fnFilterOption" - > - </a-select> - </a-form-item> - <a-form-item label="鏀朵欢浜�" v-bind="validateInfos.recipients" :wrapper-col="{ span: 18 }"> - <a-row> - <a-col class="gutter-row" :span="16"> - <a-select - mode="multiple" - show-search - placeholder="璇烽�夋嫨鏀朵欢浜烘垨鑰呰緭鍏ユ敹浠朵汉閭" - v-model:value="modelRef.recipients" - :options="state.data" - :field-names="{ label: 'name', value: 'id' }" - :maxTagCount="4" - :filter-option="fnFilterOption" - /> - </a-col> - <a-col - class="gutter-row" - :span="2" - style="display: flex; align-items: center; justify-content: center" - > - <plus-circle-outlined - style="color: rgb(0 0 0 / 45%)" - @click="fnHandleSelect('recipients')" - /> - </a-col> - <a-col class="gutter-row" :span="1"> - <a-form-item-rest> - <a-button - shape="round" - type="link" - block - size="small" - @click="ccCheckboxChange($event)" + <template #tagRender="{ label, closable, onClose, option }"> + <a-tag + :closable="closable" + style="margin-right: 3px" + @close="onClose" + :color="validateEmail(label) ? 'default' : 'red'" > - {{ !isSecretDeliveryPerson ? '鎶勯��' : '鍙栨秷鎶勯��' }} - </a-button> - </a-form-item-rest> - </a-col> - <a-col class="gutter-row" :span="1"> - <a-form-item-rest> - <a-button - shape="round" - type="link" - block - size="small" - @click="bccCheckboxChange($event)" - > - {{ !isCRecipient ? '瀵嗛��' : '鍙栨秷瀵嗛��' }} - </a-button> - </a-form-item-rest> - </a-col> - </a-row> - </a-form-item> - <span style="position: relative; top: -18px; left: 9%" v-if="modelRef.recipients.length"> - {{ userParticulars && `${userParticulars.name}<${userParticulars.email}` }}> - <span v-if="!userParticulars.title" style="margin-right: 10px; margin-left: 5px"> - 鏆傛湭鏌ヨ鍒拌瀹㈡埛鐨勫綋鍦版椂闂� - <a @click="fnHandleTimeZone(userParticulars, 'add')">琛ュ厖鏃跺尯</a> - </span> - <span v-else> - {{ userParticulars.title }} - <a @click="fnHandleTimeZone(userParticulars, 'update')">鏃跺尯涓嶅锛�</a> - </span> - - <a v-if="modelRef.recipients.length > 2">鏌ョ湅鍏ㄩ儴</a> + {{ label }} + </a-tag> + </template> + </a-select> + </a-col> + <a-col + class="gutter-row" + :span="2" + style="display: flex; align-items: center; justify-content: center" + > + <plus-circle-outlined + style="color: rgb(0 0 0 / 45%)" + @click="fnHandleSelect('recipients')" + /> + </a-col> + <a-col class="gutter-row" :span="1"> + <a-form-item-rest> + <a-button + shape="round" + type="link" + block + size="small" + @click="ccCheckboxChange($event)" + > + {{ !isSecretDeliveryPerson ? '鎶勯��' : '鍙栨秷鎶勯��' }} + </a-button> + </a-form-item-rest> + </a-col> + <a-col class="gutter-row" :span="1"> + <a-form-item-rest> + <a-button + shape="round" + type="link" + block + size="small" + @click="bccCheckboxChange($event)" + > + {{ !isCRecipient ? '瀵嗛��' : '鍙栨秷瀵嗛��' }} + </a-button> + </a-form-item-rest> + </a-col> + </a-row> + </a-form-item> + <span style="position: relative; top: -18px; left: 9%" v-if="modelRef.recipients.length"> + {{ userParticulars && `${userParticulars.userName}<${userParticulars.email}` }}> + <span v-if="!userParticulars.title" style="margin-right: 10px; margin-left: 5px"> + 鏆傛湭鏌ヨ鍒拌瀹㈡埛鐨勫綋鍦版椂闂� + <a @click="fnHandleTimeZone(userParticulars, 'add')">琛ュ厖鏃跺尯</a> + </span> + <span v-else> + {{ userParticulars.title }} + <a @click="fnHandleTimeZone(userParticulars, 'update')">鏃跺尯涓嶅锛�</a> </span> - <a-form-item - label="鎶勯�佷汉" - v-bind="validateInfos.ccRecipients" - v-if="isSecretDeliveryPerson" - :wrapper-col="{ span: 18 }" - > - <a-row> - <a-col class="gutter-row" :span="16"> - <a-select - mode="multiple" - show-search - placeholder="璇烽�夋嫨鎶勯�佷汉鎴栬�呰緭鍏ユ妱閫佷汉閭" - v-model:value="modelRef.ccRecipients" - :options="state.data" - :field-names="{ label: 'name', value: 'id' }" - :maxTagCount="4" - :filter-option="fnFilterOption" - /> - </a-col> - <a-col - class="gutter-row" - :span="2" - style="display: flex; align-items: center; justify-content: center" - > - <plus-circle-outlined - style="color: rgb(0 0 0 / 45%)" - @click="fnHandleSelect('ccRecipients')" - /> - </a-col> - </a-row> - </a-form-item> - <a-form-item - label="瀵嗛�佷汉" - v-bind="validateInfos.bccRecipients" - v-if="isCRecipient" - :wrapper-col="{ span: 18 }" - > - <a-row> - <a-col class="gutter-row" :span="16"> - <a-select - mode="multiple" - show-search - placeholder="璇烽�夋嫨鎶勯�佷汉鎴栬�呰緭鍏ユ妱閫佷汉閭" - v-model:value="modelRef.bccRecipients" - :options="state.data" - :field-names="{ label: 'name', value: 'id' }" - :maxTagCount="4" - :filter-option="fnFilterOption" - /> - </a-col> - <a-col - class="gutter-row" - :span="2" - style="display: flex; align-items: center; justify-content: center" - > - <plus-circle-outlined - style="color: rgb(0 0 0 / 45%)" - @click="fnHandleSelect('bccRecipients')" - /> - </a-col> - </a-row> - </a-form-item> - <div - style="position: relative; top: -20px; left: 9%; color: #909090; font-size: 12px" - v-if="modelRef.recipients.length" - > - {{ `${userLength}/100 鏀朵欢浜恒�佹妱閫佷汉鍜屽瘑閫佺殑鑱旂郴浜烘�绘暟涓嶅彲瓒呰繃100` }} - </div> - <a-form-item label="涓婚" :wrapper-col="{ span: 12 }" :label-col="{ span: 2 }"> - <a-input placeholder="璇疯緭鍏ラ偖浠朵富棰�" v-model:value="modelRef.subject" /> - </a-form-item> - <a-form-item - v-bind="validateInfos.content" - :wrapper-col="{ span: 24 }" - :label-col="{ span: 2 }" - > - <Tinymce @change="fnChangeContent"></Tinymce> - </a-form-item> - </a-form> - </div> - <SelectUser - ref="selectUserRef" - v-model="openSelectUser" - :selectIds="selectIds" - :idName="idName" - :title="selectUserTitle" - @updateData="fnSelectUser" - /> - <a-modal - v-model:open="openTimeZone" - :title="`${titleTimeZone}鏃跺尯`" - :confirm-loading="confirmLoading" - @ok="fnHandleTimeZoneOk" - > - <a-form - ref="formTimeZoneRef" - :label-col="{ span: 6 }" - :wrapper-col="{ span: 24 }" - :model="modelRef" - > - <a-form-item label="鍥藉鍦板尯锛�" :wrapper-col="{ span: 12 }"> - <a-select - v-model:value="modelRef.sender" - placeholder="閫夋嫨鍥藉鍦板尯" - show-search - :field-names="{ label: 'name', value: 'id' }" - :options="state.data" - > - </a-select> - </a-form-item> - <a-form-item label="鏃跺尯锛�" :wrapper-col="{ span: 12 }"> - <a-select - v-model:value="modelRef.sender" - placeholder="閫夋嫨鏃跺尯" - show-search - :field-names="{ label: 'name', value: 'id' }" - :options="state.data" - > - </a-select> - </a-form-item> - <a-form-item :label-col="{ span: 6 }"> - <a-row> - <a-col span="6"> </a-col> - <a-col span="18"> - <div style="color: #909090" - >褰撳湴瀹炴椂鏃堕棿鏍规嵁鏃跺尯淇℃伅鏄剧ず<br /> - 鍥藉鍦板尯/鏃跺尯淇℃伅鍦ㄥ鎴疯祫鏂�-鐗瑰緛淇℃伅鏌ョ湅</div - > - </a-col> - </a-row> - </a-form-item> - </a-form> - </a-modal> - </a-card> + <a v-if="modelRef.recipients.length > 2">鏌ョ湅鍏ㄩ儴</a> + </span> + <a-form-item + label="鎶勯�佷汉" + v-bind="validateInfos.ccRecipients" + v-if="isSecretDeliveryPerson" + :wrapper-col="{ span: 18 }" + > + <a-row> + <a-col class="gutter-row" :span="16"> + <a-select + mode="tags" + placeholder="璇烽�夋嫨鎶勯�佷汉鎴栬�呰緭鍏ユ妱閫佷汉閭" + v-model:value="modelRef.recipients" + :options="state.recipientsList" + :field-names="{ label: 'email', value: 'userName' }" + :maxTagCount="4" + > + <template #tagRender="{ label, closable, onClose }"> + <a-tag + :closable="closable" + style="margin-right: 3px" + @close="onClose" + :color="validateEmail(label) ? 'default' : 'red'" + > + {{ label }} + </a-tag> + </template> + </a-select> + </a-col> + <a-col + class="gutter-row" + :span="2" + style="display: flex; align-items: center; justify-content: center" + > + <plus-circle-outlined + style="color: rgb(0 0 0 / 45%)" + @click="fnHandleSelect('ccRecipients')" + /> + </a-col> + </a-row> + </a-form-item> + <a-form-item + label="瀵嗛�佷汉" + v-bind="validateInfos.bccRecipients" + v-if="isCRecipient" + :wrapper-col="{ span: 18 }" + > + <a-row> + <a-col class="gutter-row" :span="16"> + <a-select + mode="tags" + placeholder="璇烽�夋嫨鎶勯�佷汉鎴栬�呰緭鍏ユ妱閫佷汉閭" + v-model:value="modelRef.bccRecipients" + :options="state.recipientsList" + :field-names="{ label: 'email', value: 'userName' }" + :maxTagCount="4" + > + <template #tagRender="{ label, closable, onClose }"> + <a-tag + :closable="closable" + style="margin-right: 3px" + @close="onClose" + :color="validateEmail(label) ? 'default' : 'red'" + > + {{ label }} + </a-tag> + </template> + </a-select> + </a-col> + <a-col + class="gutter-row" + :span="2" + style="display: flex; align-items: center; justify-content: center" + > + <plus-circle-outlined + style="color: rgb(0 0 0 / 45%)" + @click="fnHandleSelect('bccRecipients')" + /> + </a-col> + </a-row> + </a-form-item> + <div + style="position: relative; top: -20px; left: 9%; color: #909090; font-size: 12px" + v-if="modelRef.recipients.length" + > + {{ `${userLength}/100 鏀朵欢浜恒�佹妱閫佷汉鍜屽瘑閫佺殑鑱旂郴浜烘�绘暟涓嶅彲瓒呰繃100` }} + </div> + <a-form-item label="涓婚" :wrapper-col="{ span: 12 }" :label-col="{ span: 2 }"> + <a-input placeholder="璇疯緭鍏ラ偖浠朵富棰�" v-model:value="modelRef.subject" /> + </a-form-item> + <a-form-item + v-bind="validateInfos.content" + :wrapper-col="{ span: 24 }" + :label-col="{ span: 2 }" + > + <Tinymce @change="fnChangeContent"></Tinymce> + </a-form-item> + </a-form> + </a-spin> + <SelectUser + ref="selectUserRef" + v-model="openSelectUser" + :selectIds="selectIds" + :idName="idName" + :title="selectUserTitle" + @sudUserList="fnGetRecipientsList" + @updateData="fnSelectUser" + /> + <a-modal + v-model:open="openTimeZone" + :title="`${titleTimeZone}鏃跺尯`" + :confirm-loading="confirmLoading" + @ok="fnHandleTimeZoneOk" + > + <a-form + ref="formTimeZoneRef" + :label-col="{ span: 6 }" + :wrapper-col="{ span: 24 }" + :model="modelRef" + > + <a-form-item label="鍥藉鍦板尯锛�" :wrapper-col="{ span: 12 }"> + <a-select + v-model:value="modelRef.sender" + placeholder="閫夋嫨鍥藉鍦板尯" + show-search + :field-names="{ label: 'name', value: 'id' }" + :options="state.data" + > + </a-select> + </a-form-item> + <a-form-item label="鏃跺尯锛�" :wrapper-col="{ span: 12 }"> + <a-select + v-model:value="modelRef.sender" + placeholder="閫夋嫨鏃跺尯" + show-search + :field-names="{ label: 'name', value: 'id' }" + :options="state.data" + > + </a-select> + </a-form-item> + <a-form-item :label-col="{ span: 6 }"> + <a-row> + <a-col span="6"> </a-col> + <a-col span="18"> + <div style="color: #909090" + >褰撳湴瀹炴椂鏃堕棿鏍规嵁鏃跺尯淇℃伅鏄剧ず<br /> + 鍥藉鍦板尯/鏃跺尯淇℃伅鍦ㄥ鎴疯祫鏂�-鐗瑰緛淇℃伅鏌ョ湅</div + > + </a-col> + </a-row> + </a-form-item> + </a-form> + </a-modal> + </div> </template> <script lang="ts" setup> -name: 'Edit'; - import { useDesign } from '@/hooks/web/useDesign' + name: 'Edit'; + import { useDesign } from '@/hooks/web/useDesign'; import { ref, reactive, computed } from 'vue'; import { useMessage } from '@/hooks/web/useMessage'; @@ -247,10 +268,11 @@ recipients: [], ccRecipients: [], bccRecipients: [], - fileUNID: [], + attachmentList: [], subject: '', content: '', }); + const loading = ref(false); const rulesRef = reactive({ sender: [ { @@ -291,22 +313,30 @@ }; const { createMessage } = useMessage(); - import { getUserListApi, sendingMailApi, saveMailDraftsApi } from '@/api/email/userList'; + import { + getAccountListApi, + sendingMailApi, + saveMailDraftsApi, + emailListAPi, + } from '@/api/email/userList'; // 瀹氫箟鐘舵�佺鐞嗗璞� const state = reactive({ data: [], fetching: false, error: null, + senderList: [], + recipientsList: [], }); // 鑾峰彇鐢ㄦ埛鍒楄〃鐨勫嚱鏁� const fnGetUserList = async (params) => { try { state.fetching = true; - const res = await getUserListApi(params); + const res = await getAccountListApi(); + console.log(res, 'res'); - if (res && res.items && Array.isArray(res.items)) { - state.data = res.items; + if (res && res.data && Array.isArray(res.data)) { + state.senderList = res.data; } else { console.error('Invalid response format:', res); } @@ -326,7 +356,7 @@ fetchData(); const fnFilterOption = (input: string, option: any) => { - return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0; + return option.email.toLowerCase().indexOf(input.toLowerCase()) >= 0; }; const openSelectUser = ref(false); @@ -352,7 +382,7 @@ function fnChangeContent(e) { modelRef.content = e.content; - modelRef.fileUNID = e.fileUNID; + modelRef.attachmentList = e.attachmentList; } function fnBuildingCommitData() { @@ -363,7 +393,7 @@ bcc: modelRef.bccRecipients, subject: modelRef.subject, content: modelRef.content, - fileUNID: '4DFEFEB4-3BB1-448D-9712-DC6C106A7A44;7732', + attachmentList: '', docCode: docCode.value, }; } @@ -389,19 +419,40 @@ createMessage.error('琛ㄥ崟楠岃瘉澶辫触'); }); } - + import { useRouter } from 'vue-router'; + const router = useRouter(); function pushSendingMail() { const data = fnBuildingCommitData(); - sendingMailApi(data).then((res) => {}); + loading.value = true; + sendingMailApi(data) + .then((res) => { + if (res.code === 0) { + loading.value = false; + createMessage.success(res.msg); + router.push('/email/list'); + } + }) + .catch((error) => { + loading.value = false; + }); } function fnPreview() {} function fnSaveMailDrafts() { const data = fnBuildingCommitData(); - saveMailDraftsApi(data).then((res) => { - docCode.value = res.data.docCode; - createMessage.success(res.msg); - }); + loading.value = true; + + saveMailDraftsApi(data) + .then((res) => { + loading.value = false; + if (res === 0) { + docCode.value = res.data.docCode; + createMessage.success('淇濆瓨鎴愬姛'); + } + }) + .catch((error) => { + loading.value = false; + }); } const fnSelectUser = (e) => { @@ -427,7 +478,7 @@ return { value: '', email: '', title: '' }; } // 浣跨敤 find 鏂规硶鏌ユ壘鍖归厤椤� - const foundItem = state.data.find((item) => item.id === recipientId); + const foundItem = state.recipientsList.find((item) => item.email === recipientId); // 杩斿洖鎵惧埌鐨勯」锛屽鏋滄湭鎵惧埌鍒欒繑鍥� null return foundItem || { value: '', email: '', title: '' }; @@ -456,7 +507,31 @@ confirmLoading.value = false; }, 2000); }; - const { prefixCls } = useDesign('email'); + + function fnGetRecipientsList(data) { + state.recipientsList = data; + } + + // 閭鏍¢獙姝e垯琛ㄨ揪寮� + const validateEmail = (email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); + import { debounce } from 'lodash-es'; + let lastFetchId = 0; + + const fetchUser = debounce((value) => { + lastFetchId += 1; + const fetchId = lastFetchId; + state.data = []; + state.fetching = true; + emailListAPi({ key: value }).then((body) => { + if (fetchId !== lastFetchId) { + // for fetch callback order + return; + } + + state.recipientsList = body.data; + state.fetching = false; + }); + }, 300); </script> <style lang="less" scoped> @prefix-cls: ~'@{namespace}-email'; diff --git a/src/views/email/HandlingEmailsOnBehalfOfOthers/components/list.vue b/src/views/email/HandlingEmailsOnBehalfOfOthers/components/list.vue new file mode 100644 index 0000000..2e7b51f --- /dev/null +++ b/src/views/email/HandlingEmailsOnBehalfOfOthers/components/list.vue @@ -0,0 +1,206 @@ +<template> + <PageWrapper> + <div style="height: calc(100vh - 84px)"> + <div class="head"> + <div class="left"> + <div class="left-box p-3"> + <!-- 澶氶�� --> + <a-checkbox + class="icon" + style="margin-right: 10px" + v-model:checked="state.checkAll" + :indeterminate="state.indeterminate" + @change="fnCheckedChange" + ></a-checkbox> + <!--鏇存柊 --> + <SyncOutlined class="icon" v-show="!checked" /> + <pageHeadLeft :checked="checked" :selectAllRow="selectAllRow" + :parentTableList='newList' + ></pageHeadLeft> + </div> + </div> + + <div class="right p-3" + >鍏�<span style="padding: 0 5px">20</span>灏� + <a-pagination + v-model:current="pageCurrent" + simple + :total="50" + style="margin-left: 10px" + /> + <FilterOutlined style="margin-left: 10px" /> + <a-popover placement="left" trigger="click"> + <template #content> + <div> + <span>寰�鏉ラ偖浠惰仛鍚�</span> + <a-switch style="margin-left: 50px" v-model:checked="checked3"> </a-switch> + </div> + <a-divider style="margin: 10px" /> + <div> + <span>鍒楄〃灞曠ず鍐呭</span> + </div> + <div class="p-2"> + <a-checkbox v-model:checked="checked">閭欢鎽樿</a-checkbox> + </div> + <div class="p-2"> + <a-checkbox v-model:checked="checked">闄勪欢</a-checkbox> + </div> + <div style="text-align: center"> + <a-button @click="$router.push('/email/utils')">鏇村閭璁剧疆</a-button> + </div> + </template> + <SettingOutlined style="margin-left: 10px" /> + </a-popover> + <a-switch style="margin-left: 10px" v-model:checked="checked3"> + <template #checkedChildren><PushpinOutlined style="color: #0a6aff" /></template> + <template #unCheckedChildren><PushpinOutlined /></template> + </a-switch> + </div> + </div> + <div v-if="checked" class="left-bt p-3"> + 宸查�夋嫨姝ら〉闈笂鎵�鏈� 20 灏侀偖浠� 锛� 閫夋嫨鍏ㄩ儴 335 灏侀偖浠� + </div> + <div class="p-4" style="height: 90%; overflow: hidden"> + <a-tabs v-model:activeKey="activeKey"> + <a-tab-pane + v-for="item in tabsList" + :key="item.key" + :tab="`${item.label}${item.num ? '(' + item.num + ')' : ''}`" + style="height: 200px" + > + <Table + ref="tableRef" + :page="pageCurrent" + :pageList="newList" + @selectAll="fnSelectAll" + @updateSelectAll="updateSelectAll" + /> + </a-tab-pane> + </a-tabs> + </div> + </div> + </PageWrapper> +</template> + +<script lang="ts" setup> + name: 'ListPage'; + import { + SyncOutlined, + SettingOutlined, + FilterOutlined, + PushpinOutlined, + } from '@ant-design/icons-vue'; + import pageHeadLeft from '@/views/email/components/ListPage/pageHeadLeft.vue'; + import { PageWrapper } from '@/components/Page'; + + import { ref, watch, defineProps, defineEmits, computed, reactive, onMounted } from 'vue'; + + // 瀹氫箟灞炴�� + interface Props { + pageList: []; + } + const props = defineProps<Props>(); + const newList = ref([]); + const selectAllRow = ref([]); + watch( + () => props.pageList, + (newValue) => { + newList.value = newValue; + }, + ); + + const checked = ref(false); + const pageCurrent = ref(1); + const tableRef = ref(); + const state = reactive({ + indeterminate: false, + checkAll: false, + }); + function fnCheckedChange(e) { + Object.assign(state, { + indeterminate: false, + }); + tableRef.value[0].fnSelectAll(e.target.checked); + checked.value = e.target.checked; + } + function updateSelectAll(data) { + selectAllRow.value = data.records; + if (!data.isAll) { + state.indeterminate = true; + state.checkAll = false; + if (data.records.length === 0) { + state.indeterminate = false; + } + } else { + state.indeterminate = false; + state.checkAll = true; + } + } + const tabsList = computed(() => { + return [ + { + key: '1', + label: '闇�瑕佸鐞�', + num: 20, + }, + { + key: '2', + label: '灏氭湭鍒版湡', + num: 0, + }, + { + key: '3', + label: '宸插畬鎴�', + num: 0, + }, + ]; + }); + const activeKey = ref('1'); + const checked3 = ref(false); + import Table from '../table.vue'; + onMounted(() => { + console.log('tableRef:', tableRef.value[0]); + }); + function fnSelectAll() { + console.log('44444444444'); + } + +</script> +<style scoped lang="less"> + .head { + display: flex; + justify-content: space-between; + width: 100%; + border-bottom: 1px solid rgb(5 5 5 / 6%); + + /* 澧炲姞閫夋嫨鍣ㄧ壒寮傛�� */ + & .left { + width: 20%; + + & .left-box { + display: flex; + align-items: center; + justify-content: space-flex-start; + width: 100%; + + & .icon { + margin-right: 15px; + font-size: 16px; + } + } + } + + & .right { + display: flex; + align-items: center; + } + } + + .left-bt { + display: flex; + align-items: center; + justify-content: center; + padding-left: 27px; + background: #fffbe6; + } +</style> diff --git a/src/views/email/HandlingEmailsOnBehalfOfOthers/index.vue b/src/views/email/HandlingEmailsOnBehalfOfOthers/index.vue new file mode 100644 index 0000000..f614d9c --- /dev/null +++ b/src/views/email/HandlingEmailsOnBehalfOfOthers/index.vue @@ -0,0 +1,44 @@ +<template> + <div> + <PageIndex :pageList="pageList"></PageIndex> + </div> +</template> + +<script lang="ts" setup> + name: 'Inbox'; + import { ref, onMounted, computed, provide } from 'vue'; + import PageIndex from './components/list.vue'; + import { useRoute } from 'vue-router'; + + const route = useRoute(); + // 鑾峰彇褰撳墠瀹屾暣 URL + const routerId = computed(() => { + try { + const url = window.location.href; + if (!url) { + throw new Error('Invalid URL'); + } + const basePart = url.split('?')[1]; + console.log(basePart, 'basePart'); + return basePart; + } catch (error) { + console.error('Error processing URL:', error); + // 杩斿洖榛樿鍊兼垨绌哄瓧绗︿覆 + return ''; + } + }); + import { getMailListApi } from '@/api/email/userList'; + const pageList = ref([]); + function getDataList() { + getMailListApi({}).then((res) => { + if (res.code == 0) { + pageList.value = res.data; + } + }); + } + provide('getDataList', getDataList); + onMounted(() => { + getDataList(); + }); +</script> +<style scoped lang="less"></style> diff --git a/src/views/email/HandlingEmailsOnBehalfOfOthers/table.vue b/src/views/email/HandlingEmailsOnBehalfOfOthers/table.vue new file mode 100644 index 0000000..a87d458 --- /dev/null +++ b/src/views/email/HandlingEmailsOnBehalfOfOthers/table.vue @@ -0,0 +1,443 @@ +<template> + <div style="height: 70vh; overflow: auto"> + <div v-for="(item, index) in groupedEmails" :key="index"> + <span class="span-title">{{ `${item.name}(${item.data.length})` }}</span> + <vxe-table + ref="vxeTableRef" + style="margin: 10px 0" + :showHeader="false" + :data="item.data" + size="small" + min-height="40px" + :row-config="{ isCurrent: true, isHover: true }" + :menu-config="tableMenu" + @menu-click="contextMenuClickEvent" + @cell-click="cellClickEvent" + @checkbox-change="selectChangeEvent" + > + <vxe-column type="checkbox" width="30"></vxe-column> + <vxe-column field="sender" title="鍙戜欢浜�" data-index="sender" min-width="300px"> + <template #default="{ row }"> + <div style="display: flex; align-items: center"> + <div + class="dot" + :class="row.readFlag ? 'dot-color' : ''" + @click.stop="fnRowUpdateRead(row)" + ></div> + <a-tooltip placement="bottom"> + <template #title> + <span>闄岀敓浜�</span> + </template> + <a-avatar size="small" style="margin-right: 8px" :src="row.avatar" /> + </a-tooltip> + + <a-popover placement="bottom"> + <template #content> + <div + class="p-2" + style=" + display: flex; + align-items: center; + border-bottom: 1px solid rgb(5 5 5 / 6%); + " + > + <a-avatar size="small" style="margin-right: 8px" :src="row.avatar" /> + <span style="color: #000; font-weight: 700">{{ row.sender }}</span> + <CopyOutlined /> + </div> + <div class="display-flex p-2"> + <a-button type="link" size="small">鏂板缓瀹㈡埛</a-button> + <a-dropdown> + <a style="margin-right: 5px" class="ant-dropdown-link" @click.prevent> + <DownOutlined /> + </a> + <template #overlay> + <a-menu> + <a-menu-item> + <a href="javascript:;">娣诲姞鍒板凡鏈夊鎴�</a> + </a-menu-item> + </a-menu> + </template> + </a-dropdown> + <a-button type="link" size="small">娣诲姞涓虹嚎绱�</a-button> + + <a-dropdown style="margin-right: 5px"> + <a style="margin-right: 5px" class="ant-dropdown-link" @click.prevent> + <DownOutlined /> + </a> + <template #overlay> + <a-menu> + <a-menu-item> + <a href="javascript:;">娣诲姞鍒伴�氳褰�</a> + </a-menu-item> + </a-menu> + </template> + </a-dropdown> + <a-button type="link" size="small">寰�鏉ラ偖浠�</a-button></div + > + </template> + <div class="title-dot" :class="row.readFlag ? 'title-dot-color' : ''"> + <span style="font-weight: 700">{{ row.senderName }}</span + ><span style="padding: 0 8px">|</span> + <span style="font-weight: 500">{{ row.sender }}</span> + </div> + </a-popover> + </div> + </template> + </vxe-column> + <vxe-column show-overflow field="subject" title="琛ㄩ" data-index="subject" min-width="250"> + <template #default="{ row }"> + <span + class="title-dot" + :class="row.readFlag ? 'title-dot-color' : ''" + style="font-weight: 500" + >{{ row.subject }}</span + > + - + <span style="color: #999">{{ row.subject }}</span> + </template> + </vxe-column> + <vxe-column field="action" title="Action" width="180"> + <template #default="{ row }"> + <span style="display: flex; justify-content: space-around"> + <span>{{ row.receiveTime }}</span> + <span><FieldTimeOutlined @click.stop="fnProcessingTime" /></span> + <span><PushpinOutlined @click.stop="fnTagging" /></span> + </span> + </template> + </vxe-column> + </vxe-table> + </div> + <DrawerDetail + ref="drawerDetailRef" + v-model="openDrawerDetail" + :mailId="rowMailId" + :allList="dataSource" + /> + </div> +</template> + +<script lang="ts" setup> + name: 'ListPageTable'; + import { + FieldTimeOutlined, + PushpinOutlined, + CopyOutlined, + DownOutlined, + } from '@ant-design/icons-vue'; + + import { ref, watch, defineProps, defineEmits, computed, defineExpose, inject } from 'vue'; + + // 瀹氫箟灞炴�� + interface Props { + pageList: []; + } + const props = defineProps<Props>(); + + const groupedEmails = ref<GroupedDataItem[]>([]); + + const dataSource = ref([]); + watch( + () => props.pageList, + (newValue) => { + dataSource.value = newValue; + groupedEmails.value = groupEmailsByDate(newValue); + }, + ); + import dayjs from 'dayjs'; + import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'; + import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'; + import isoWeek from 'dayjs/plugin/isoWeek'; + dayjs.extend(isSameOrAfter); + dayjs.extend(isSameOrBefore); + dayjs.extend(isoWeek); + + interface EmailItem { + id: number; + subject: string; + } + + // 纭繚 groupedData 鐨勭粨鏋勬纭笖 data 鏄� EmailItem 绫诲瀷鐨勬暟缁� + interface GroupedDataItem { + key: string; + data: EmailItem[]; + name: string; + } + + function groupEmailsByDate(dataSource) { + const today = dayjs(); + const yesterday = dayjs().subtract(1, 'day'); + const startOfWeek = dayjs().startOf('week'); + const startOfMonth = dayjs().startOf('month'); + const startOfLastMonth = dayjs().subtract(1, 'month').startOf('month'); + const endOfLastMonth = dayjs().subtract(1, 'month').endOf('month'); + + const groupedData: GroupedDataItem[] = [ + { + data: [], + name: '浠婂ぉ', + key: 'today', + }, + { + data: [], + name: '鏄ㄥぉ', + key: 'yesterday', + }, + { + data: [], + name: '鏈懆', + key: 'thisWeek', + }, + { + data: [], + name: '杩欎釜鏈�', + key: 'thisMonth', + }, + { + data: [], + name: '涓婁釜鏈�', + key: 'lastMonth', + }, + { + data: [], + name: '鏇存棭', + key: 'earlier', + }, + ]; + + dataSource.forEach((item: any) => { + try { + const emailDate = dayjs(item.date); + + if (emailDate.isSame(today, 'day')) { + groupedData[0].data.push(item); + } else if (emailDate.isSame(yesterday, 'day')) { + groupedData[1].data.push(item); + } else if (emailDate.isSameOrAfter(startOfWeek) && emailDate.isBefore(today, 'day')) { + groupedData[2].data.push(item); + } else if (emailDate.isSameOrAfter(startOfMonth) && emailDate.isBefore(today, 'day')) { + groupedData[3].data.push(item); + } else if ( + emailDate.isSameOrAfter(startOfLastMonth) && + emailDate.isSameOrBefore(endOfLastMonth) + ) { + groupedData[4].data.push(item); + } else { + groupedData[5].data.push(item); + } + } catch (error) { + console.error(`Error processing item date: ${item.date}`, error); + } + }); + // 灏嗙粨鏋滄寜涓枃鏄犲皠杩涜杩斿洖 + const result = <{ data: any; name: string; key: string }[]>[]; + groupedData.forEach((group: { data: any; name: string; key: string }) => { + if (group.data.length > 0) { + result.push(group); + } + }); + + return result; + } + + // 鍙抽敭鑿滃崟 + const tableMenu = { + className: 'my-menus', + body: { + options: [ + [ + { + code: 'reply', + name: '鍥炲', + }, + { code: 'replyAll', name: '鍥炲鍏ㄩ儴' }, + { code: 'replyWithAttachment', name: '甯﹂檮浠跺洖澶�' }, + { code: 'replyAllWithAttachment', name: '甯﹂檮浠跺洖澶嶅叏閮�' }, + { code: 'forward', name: '杞彂' }, + { code: 'forwardAsAttachment', name: '浣滀负闄勪欢杞彂' }, + { code: 'distribute', name: '鍒嗗彂' }, + { code: 'setRemark', name: '璁剧疆澶囨敞' }, + ], + [ + { code: 'toHandle', name: '寰呭鐞�' }, + { code: 'markAsUnread', name: '鏍囦负鏈' }, + { code: 'labelAs', name: '鏍囨敞涓�' }, + ], + [ + { code: 'newRule', name: '鏂板缓鏀跺彂浠惰鍒�' }, + { code: 'moveTo', name: '绉诲姩鍒�' }, + ], + [ + { code: 'exportEmail', name: '瀵煎嚭閭欢' }, + { code: 'createFollowUp', name: '寤轰负瀹㈡埛璺熻繘' }, + { code: 'createSchedule', name: '鏂板缓鏃ョ▼' }, + ], + [ + { code: 'markAsSpam', name: '鏍囦负鍨冨溇閭欢' }, + { code: 'delete', name: '鍒犻櫎' }, + ], + ], + }, + }; + + function contextMenuClickEvent({ menu, row, column }) { + switch (menu.code) { + case 'copy': + if (row && column) { + } + break; + default: + } + } + const vxeTableRef = ref(); + function fnSelectAll(is) { + vxeTableRef.value.forEach((row) => { + row.setAllCheckboxRow(is); + }); + selectChangeEvent(); + } + + function selectChangeEvent() { + const isAll = getCheckboxRecords().length === dataSource.value.length; + const data = { + isAll, + records: getCheckboxRecords(), + }; + emit('updateSelectAll', data); + } + function getCheckboxRecords() { + const list = new Set(); + + vxeTableRef.value.forEach((row) => { + const records = row.getCheckboxRecords(); // 鍋囪璇ユ柟娉曡繑鍥炰竴涓暟缁� + if (Array.isArray(records)) { + // 纭繚 records 鏄暟缁� + records.forEach((record) => list.add(record)); // 灏嗚褰曟坊鍔犲埌 Set 涓� + } + }); + + return Array.from(list); // 灏� Set 杞崲鍥炴暟缁� + } + // 鎿嶄綔row + function fnProcessingTime(row) { + console.log(row); + } + function fnTagging(row) { + console.log(row); + } + import DrawerDetail from '../components/ListPage/drawerDetail.vue'; + // 璇︽儏鍐呭 + const openDrawerDetail = ref(false); + const rowMailId = ref(''); + const cellClickEvent = (event) => { + console.log(event.row, '--------455433'); + rowMailId.value = event.row.docCode; + openDrawerDetail.value = true; + }; + + // 鏇存柊绁栫埗缁勪欢鏁版嵁 + const getDataList = inject('getDataList'); + console.log(getDataList, '0000004'); + + import { updateReadApi } from '@/api/email/userList'; + // 鏍囧織鏈/缁忚 + function fnRowUpdateRead(row) { + const data = { + status: !row.readFlag, + list: [row.docCode], + }; + pushReadApi(data); + } + function pushReadApi(params) { + updateReadApi(params).then((res) => { + if (res.code == 0) { + // + getDataList({}); + } + }); + } + const emit = defineEmits(['selectAll', 'updateSelectAll']); + defineExpose({ + fnSelectAll, + }); +</script> +<style scoped lang="less"> + .display-flex { + display: flex; + align-items: center; + justify-content: space-between; + } + + .head { + display: flex; + justify-content: space-between; + width: 100%; + border-bottom: 1px solid rgb(5 5 5 / 6%); + + /* 澧炲姞閫夋嫨鍣ㄧ壒寮傛�� */ + & .left { + width: 20%; + + & .left-box { + display: flex; + align-items: center; + justify-content: space-flex-start; + width: 100%; + + & .icon { + margin-right: 15px; + font-size: 16px; + } + } + } + + & .right { + display: flex; + align-items: center; + } + } + + .left-bt { + display: flex; + align-items: center; + justify-content: center; + padding-left: 27px; + background: #fffbe6; + } + + .span-title { + padding: 20px; + color: #000; + font-weight: 700; + } + + .table { + height: 80vh; + } + + .my-menus { + background-color: #f8f8f9; + } + // 鍦嗙偣 + .dot { + display: inline-block; + width: 8px; + height: 8px; + margin-right: 10px; + border-radius: 50%; + background-color: #0a6aff; + } + + .dot-color { + background-color: #d9d9d9; + color: #d9d9d9; + } + + .title-dot { + color: #0a6aff; + } + + .title-dot-color { + color: #999; + } +</style> diff --git a/src/views/email/Inbox/index.vue b/src/views/email/Inbox/index.vue index bad0cd4..d28fc90 100644 --- a/src/views/email/Inbox/index.vue +++ b/src/views/email/Inbox/index.vue @@ -1,6 +1,6 @@ <template> <div> - <PageIndex :pageList="pageList"></PageIndex> + <PageIndex :pageList="pageList" :mailType='1'></PageIndex> </div> </template> @@ -27,11 +27,10 @@ return ''; } }); - import { receiveApi, getMailListApi } from '@/api/email/userList'; + import { getMailListApi } from '@/api/email/userList'; const pageList = ref([]); function getDataList() { - receiveApi({ mail: routerId.value }).then((res) => {}); - getMailListApi({ mail: routerId.value }).then((res) => { + getMailListApi({ mail: routerId.value,mailType:1 }).then((res) => { if (res.code == 0) { pageList.value = res.data; } diff --git a/src/views/email/UnreadEmail/index.vue b/src/views/email/UnreadEmail/index.vue index 3e7d767..de15cd1 100644 --- a/src/views/email/UnreadEmail/index.vue +++ b/src/views/email/UnreadEmail/index.vue @@ -1,19 +1,44 @@ - <template> - <PageWrapper dense contentFullHeight fixedHeight> -<div> -sdfdsfds -</div> -<div class='table-list'> -sdffsdfsdffdsdsfdsf -</div> - - - </PageWrapper> + <div> + <PageIndex :pageList="pageList" :mailType='1'></PageIndex> + </div> </template> -<script lang="ts" setup> -name: 'UnreadEmail' -import {PageWrapper} from '@/components/Page'; - import { ref, watch } from 'vue'; +<script lang="ts" setup> + name: 'Inbox'; + import { ref, onMounted, computed, provide } from 'vue'; + import PageIndex from '@/views/email/components/ListPage/list.vue'; + import { useRoute } from 'vue-router'; + + const route = useRoute(); + // 鑾峰彇褰撳墠瀹屾暣 URL + const routerId = computed(() => { + try { + const url = window.location.href; + if (!url) { + throw new Error('Invalid URL'); + } + const basePart = url.split('?')[1]; + console.log(basePart, 'basePart'); + return basePart; + } catch (error) { + console.error('Error processing URL:', error); + // 杩斿洖榛樿鍊兼垨绌哄瓧绗︿覆 + return ''; + } + }); + import { getMailListApi } from '@/api/email/userList'; + const pageList = ref([]); + function getDataList() { + getMailListApi({ mail: routerId.value,mailType:1,isNoRead:true }).then((res) => { + if (res.code == 0) { + pageList.value = res.data; + } + }); + } + provide('getDataList',getDataList); + onMounted(() => { + getDataList(); + }); </script> +<style scoped lang="less"></style> diff --git a/src/views/email/components/LeftNav.vue b/src/views/email/components/LeftNav.vue index 34cc286..7aa8ec7 100644 --- a/src/views/email/components/LeftNav.vue +++ b/src/views/email/components/LeftNav.vue @@ -34,7 +34,8 @@ <template #title> <div class="my-display"> <span>{{ item.title }}</span - ><span class="my-left" v-if="item.total > 0">{{ item.total }}</span> + > + <!-- <span class="my-left" v-if="item.total > 0">{{ item.total }}</span> --> </div> </template> <a-menu-item @@ -52,7 +53,8 @@ <a-menu-item v-else :key="item.key" @click="handleClick(item)"> <div class="my-display"> <span>{{ item.title }}</span - ><span class="my-left" v-if="item.total > 0">{{ item.total }}</span> + > + <span class="my-left" v-if="item.total > 0">{{ item.total }}</span> </div> </a-menu-item> </template> diff --git a/src/views/email/components/ListPage/drawerDetail.vue b/src/views/email/components/ListPage/drawerDetail.vue index 4ce4eaf..47bd123 100644 --- a/src/views/email/components/ListPage/drawerDetail.vue +++ b/src/views/email/components/ListPage/drawerDetail.vue @@ -13,294 +13,323 @@ </template> <template #extra> <div style="font-size: 16px"> - 鍏�<span class="m-1">222</span>灏� <LeftOutlined style="padding: 0 20px" /><RightOutlined /> + 鍏�<span class="m-1">222</span>灏� + <LeftOutlined style="padding: 0 20px" /> + <RightOutlined /> </div> </template> - - <div class="flex-between"> - <div class="ct-left p-2" :class="isOpen ? 'isOpen' : 'onOpen'"> - <div class="title" style="margin-bottom: 20px;"> - <div class="left"> - <span style="margin-right: 20px; font-size: 24px; font-weight: 700">鏍囬</span> - <span style="margin-right: 10px; font-size: 16px"><PushpinOutlined /></span> - </div> - <div class="right"> - <div class="tate"> 2024-06-08 15:03:09 </div> - <div> - <a-dropdown-button> - <span><LeftOutlined /></span> - <a-divider type="vertical" /> - <span><DoubleLeftOutlined /></span> - <template #overlay> - <a-menu> - <a-menu-item key="1"> - <UserOutlined /> - 1st menu item - </a-menu-item> - <a-menu-item key="2"> - <UserOutlined /> - 2nd menu item - </a-menu-item> - <a-menu-item key="3"> - <UserOutlined /> - 3rd item - </a-menu-item> - </a-menu> + <template #footer> + <div style="display: flex;"> + <a-textarea autoSize size="large" v-model:value="userName" placeholder="蹇�熷洖澶�"> + <template #prefix> + <RollbackOutlined style="color: #999;" /> + </template> + </a-textarea> + <a-button size="large" type="primary" style="margin-left: 10px;">鍙戦�� + </a-button> + </div> + </template> + <div + style=" + position: fixed; + z-index: 99; + top: 6.8%; + width: 72%; + padding-top: 24px; + background: #fff; + " + > + <div class="title" style="margin-bottom: 20px;"> + <div class="left"> + <span style="margin-right: 20px; font-size: 24px; font-weight: 700"> + <a-tooltip placement="bottom"> + <template #title> + <span>{{ tableRowData.subject }}</span> + </template> + {{ truncateString(tableRowData.subject, 23) }} + </a-tooltip> + </span> + <span style="margin-right: 10px; font-size: 16px"> + <PushpinOutlined /> + </span> + </div> + <div class="right"> + <div class="tate">{{ tableRowData.receiveTime }}</div> + <div> + <a-dropdown-button> + <span> + <a-tooltip placement="bottom"> + <template #title> + <span>鍥炲</span> </template> - </a-dropdown-button> - </div> - </div> - </div> - <div class="user p-1"> - <div style="display: flex;align-items: center;"> - <a-avatar size="small" style="margin-right: 8px" src="#" /> xxx <span>{{`<dddddddddd@qq.com>`}}</span> - <span style="margin: 0 10px;">鍙戦��</span> - <a-popover placement="bottom"> - <template #content> - <div - class="p-2" - style=" - display: flex; - align-items: center; - border-bottom: 1px solid rgb(5 5 5 / 6%); - " - > - <a-avatar size="small" style="margin-right: 8px" src="#" /> - <span style="color: #000; font-weight: 700">ssss</span> - <CopyOutlined /> - </div> - <div class="display-flex p-2"> - <a-button type="link" size="small">寰�鏉ラ偖浠�</a-button></div - > - </template> - <a-avatar size="small" style="margin-right: 8px" src="#" /> xxx <span>{{`<dddddddddd@qq.com>`}}</span> - </a-popover> - </div> - <div type="info" class="p-2" style="margin-top: 10px;background-color: #e4f1ff;font-size: 14px;"> - <span>{{`<dddddddddd@qq.com>`}}</span><span>鏆傛湭鏌ヨ鍒拌瀹㈡埛鐨勫綋鍦版椂闂�</span><span>2024-06-08 22:22</span> - </div> - <div class="ct"> - <Tinymce></Tinymce> - </div> - <a-input size="large" v-model:value="userName" placeholder="蹇�熷洖澶�"> - <template #prefix> - <LeftOutlined style="color: #999;"/> - </template> - </a-input> + <LeftOutlined /> + </a-tooltip> + </span> + <a-divider type="vertical" /> + <span> + <a-tooltip placement="bottom"> + <template #title> + <span>蹇�熷洖澶�</span> + </template> + <DoubleLeftOutlined /> + </a-tooltip> + </span> + <template #overlay> + <a-menu> + <a-menu-item key="1"> + <UserOutlined /> + 1st menu item + </a-menu-item> + <a-menu-item key="2"> + <UserOutlined /> + 2nd menu item + </a-menu-item> + <a-menu-item key="3"> + <UserOutlined /> + 3rd item + </a-menu-item> + </a-menu> + </template> + </a-dropdown-button> </div> </div> - <div v-show="isOpen" class="ct-right p-2"> - sssss </div> </div> - - - <div @click="fuToggleContent" class="toggle-btn" :class="isOpen ? 'onIconOpen' : 'iconOpen'"> + <div class="flex-between"> + <div class="ct-left p-2" :class="isOpen ? 'isOpen' : 'onOpen'"> + <div class="user p-1"> + <div style="display: flex; align-items: center;"> + <a-avatar size="small" style="margin-right: 8px" src="#" /> + {{ tableRowData.sender }} + <span>{{ `<${tableRowData.sender}>` }}</span> + <span style="margin: 0 10px;">鍙戦��</span> + <a-popover placement="bottom"> + <template #content> + <div + class="p-2" + style=" + display: flex; + align-items: center; + border-bottom: 1px solid rgb(5 5 5 / 6%); + " + > + <a-avatar size="small" style="margin-right: 8px" src="#" /> + <span style="color: #000; font-weight: 700"> {{ `${tableRowData.receiver}` }}</span> + <CopyOutlined /> + </div> + <div class="display-flex p-2"> + <a-button type="link" size="small">寰�鏉ラ偖浠�</a-button> + </div> + </template> + <a-avatar size="small" style="margin-right: 8px" src="#" /> + {{ `${tableRowData.receiver}` }}<span>{{ `<${tableRowData.receiver}>` }}</span> + </a-popover> + </div> + <div + type="info" + class="p-2" + style=" + margin-top: 10px; + background-color: #e4f1ff; + font-size: 14px; + " + > + <span>{{ `<${tableRowData.sender}>` }}</span> + <span>鏆傛湭鏌ヨ鍒拌瀹㈡埛鐨勫綋鍦版椂闂�</span> + <!-- <span>2024-06-08 22:22</span> --> + </div> + <div class="ct" v-if="tableRowData.content"> + <TinymcePw v-model="tableRowData.content" /> + </div> + </div> + </div> + <div v-show="isOpen" class="ct-right p-2">sssss</div> + </div> + <div @click="fuToggleContent" class="toggle-btn" :class="isOpen ? 'onIconOpen' : 'iconOpen'"> <LeftOutlined v-if="!isOpen" /> <RightOutlined v-else /> </div> </a-drawer> </template> -<script lang="ts" setup>; - name: 'drawerDetail'; - import { ref, watch, defineProps, defineEmits, computed, reactive } from 'vue'; - import { - LeftOutlined, - RightOutlined, - DoubleLeftOutlined, +<script lang="ts" setup> +name: 'drawerDetail'; + +import { ref, watch, defineProps, defineEmits, computed, h } from 'vue'; +import { + LeftOutlined, + RightOutlined, + DoubleLeftOutlined, PushpinOutlined, CopyOutlined, - UserOutlined - } from '@ant-design/icons-vue'; + UserOutlined, + RollbackOutlined +} from '@ant-design/icons-vue'; import pageHeadLeft from './pageHeadLeft.vue'; - import Tinymce from '@/components/Tinymce/src/index.vue'; +import { TinymcePw } from '@/components/Tinymce'; +import { getMailInfoApi } from '@/api/email/userList'; +import { useCollapseStore } from '@/store/modules/useCollapseStore'; - // 瀹氫箟灞炴�� - interface Props { - modelValue: boolean; - title?: string; - placement?: 'left' | 'right' | 'top' | 'bottom'; - idName?: string; - selectIds?: number[]; +// 瀹氫箟灞炴�� +interface Props { + modelValue: boolean; + title?: string; + placement?: 'left' | 'right' | 'top' | 'bottom'; + idName?: string; + selectIds?: number[]; + mailId?: string; + allList; +} + +const props = defineProps<Props>(); +const tableRowData = ref<Record<string, any>>({}); +const emit = defineEmits(['update:modelValue', 'updateData']); +const drawerOpen = ref(props.modelValue); + +// 鐩戝惉灞炴�у彉鍖� +watch(() => props.modelValue, (newValue) => { + drawerOpen.value = newValue; + console.log(newValue, '---------4'); + if (newValue) { + getMailInfoApi({ docCode: props.mailId }).then((res) => { + tableRowData.value = res.data; + }); } - const props = defineProps<Props>(); +}); - // 瀹氫箟浜嬩欢 - const emit = defineEmits(['update:modelValue', 'updateData']); +// 鏇存柊澶栭儴灞炴�� +watch(drawerOpen, (newValue) => { + emit('update:modelValue', newValue); +}); - // 鍐呴儴鐘舵�� - const drawerOpen = ref(props.modelValue); - - // 鐩戝惉灞炴�у彉鍖� - watch( - () => props.modelValue, - (newValue) => { - drawerOpen.value = newValue; - if (props.selectIds && props.selectIds.length > 0) { - } else { - } - }, - ); - - // 鏇存柊澶栭儴灞炴�� - watch(drawerOpen, (newValue) => { - emit('update:modelValue', newValue); - }); - import { getUserListApi } from '@/api/email/userList'; - - // 鏂规硶 - - import { useCollapseStore } from '@/store/modules/useCollapseStore'; - const collapseStore = useCollapseStore(); - const afterOpenChange = (bool: boolean) => { - if (bool) { - fnGetUserList({ page: 1, pageSize: 30 }); - } - - collapseStore.toggle(false); - - - }; - const close = (e) => { - drawerOpen.value = false; - }; - const fnGetUserList = (params) => { - // getUserListApi(params).then((res) => { - // if (res && res.items && Array.isArray(res.items)) { - // dataSource.value = res.items; - // selectContactNum.value = res.total; - // } else { - // console.error('Invalid response format:', res); - // } - // }); +// 鏂规硶 +const collapseStore = useCollapseStore(); +const afterOpenChange = (bool: boolean) => { + if (bool) { + fnGetUserList({ page: 1, pageSize: 30 }); } - // 璁$畻灞炴�� - const title = computed(() => props.title || 'Basic Drawer'); - const placement = computed(() => props.placement || 'right'); - const idName = computed(() => props.idName || 'recipients'); + collapseStore.toggle(false); +}; +const close = (e) => { + drawerOpen.value = false; +}; - // // 鏄剧ず鎶藉眽鐨勬柟娉� - // const showDrawer = () => { - // drawerOpen.value = true; - // }; +function truncateString(str, maxLength) { + return str.length > maxLength ? str.substring(0, maxLength) + '...' : str; +} - const fnSaveOpenChange = () => { - // console.log('selectedRowKeys changed: ', state.selectedRowKeys); - // drawerOpen.value = false; - // emit('update:modelValue', false); - // const data = { - // selectedRowKeys: state.selectedRowKeys, - //; idName: idName.value, - // }; - // emit('updateData', data); - }; +const fnGetUserList = (params) => { + // 璋冪敤鎺ュ彛閫昏緫 +}; - const userName = ref(''); - const isOpen = ref(false) - function fuToggleContent (){ - isOpen.value = !isOpen.value - } +// 璁$畻灞炴�� +const title = computed(() => props.title || 'Basic Drawer'); +const placement = computed(() => props.placement || 'right'); +const idName = computed(() => props.idName || 'recipients'); + +// 鎶藉眽寮�鍏� +const fnSaveOpenChange = () => { + // 鎶藉眽淇濆瓨閫昏緫 +}; + +const userName = ref(''); +const isOpen = ref(false); + +function fuToggleContent() { + isOpen.value = !isOpen.value; +} </script> <style scoped lang="less"> - /* 鏍峰紡鍙互鍦ㄨ繖閲屽畾涔� */ +.table-content { + display: flex; + justify-content: space-between; + border-top: 1px solid #f0f0f0; - .table-content { + .left { + width: 80%; + height: 100%; + border-right: 1px solid #f0f0f0; + } + + .right { + height: 100%; + } +} + +::v-deep(.ant-table) { + min-height: 355px !important; +} + +.title { + display: flex; + align-items: center; + justify-content: space-between; + + & .left { display: flex; - justify-content: space-between; - border-top: 1px solid #f0f0f0; - - .left { - width: 50%; - height: 100%; - border-right: 1px solid #f0f0f0; - } - - .right { - width: 50%; - height: 100%; - } + align-items: center; + width: 50%; } - ::v-deep(.ant-table) { - min-height: 355px !important; - } - - .title { + & .right { display: flex; align-items: center; justify-content: space-between; + width: 25%; - & .left { - display: flex; - align-items: center; - width: 50%; - } - - & .right { - display: flex; - align-items: center; - justify-content: space-between; - width: 25%; - - & .tate { - color: #999; - font-size: 14px; - } + & .tate { + color: #999; + font-size: 14px; } } +} - .ct{ - // height: 66vh;height - margin: 20px 0; - } +.ct { + margin: 20px 0; +} - .flex-between{ - display: flex; - } +.flex-between { + display: flex; + margin-top: 4%; +} -.ct-left{ +.ct-left { padding-right: 20px; - // border-right: 1px solid #f0f0f0; } -.ct-right{ - border-left: 1px solid #f0f0f0; - +.ct-right { + border-left: 1px solid #f0f0f0; } - .toggle-btn { - display: flex; - position: absolute; - z-index: 99; - top: 50%; - width: 20px; /* 鍘熷瀹藉害 */ - height: 54px; - padding-left: 5px; - transform: translateY(-50%); - border: 1px solid #f0f0f0; - border-right: none; - border-radius: 10px 0 0 10px; - background: #fafafa; +.toggle-btn { + display: flex; + position: absolute; + z-index: 99; + top: 50%; + width: 20px; + height: 54px; + padding-left: 5px; + transform: translateY(-50%); + border: 1px solid #f0f0f0; + border-right: none; + border-radius: 10px 0 0 10px; + background: #fafafa; +} - } +.onOpen { + width: 100%; +} - .onOpen { - width: 100%; - } +.isOpen { + width: 69%; +} - .isOpen { - width: 69%; - } +.iconOpen { + right: 0%; +} - .iconOpen { - right: 0%; - - } - - .onIconOpen { - right: 32%; - - } +.onIconOpen { + right: 32%; +} </style> diff --git a/src/views/email/components/ListPage/list.vue b/src/views/email/components/ListPage/list.vue index 9022bd5..1848a50 100644 --- a/src/views/email/components/ListPage/list.vue +++ b/src/views/email/components/ListPage/list.vue @@ -14,9 +14,11 @@ ></a-checkbox> <!--鏇存柊 --> <SyncOutlined class="icon" v-show="!checked" /> - <pageHeadLeft :checked="checked" :selectAllRow="selectAllRow" - :parentTableList='newList' - ></pageHeadLeft> + <pageHeadLeft + :checked="checked" + :selectAllRow="selectAllRow" + :parentTableList="newList" + ></pageHeadLeft> </div> </div> @@ -174,7 +176,6 @@ function fnSelectAll() { console.log('44444444444'); } - </script> <style scoped lang="less"> .head { diff --git a/src/views/email/components/ListPage/pageHeadLeft.vue b/src/views/email/components/ListPage/pageHeadLeft.vue index 8e5ec17..1e138ce 100644 --- a/src/views/email/components/ListPage/pageHeadLeft.vue +++ b/src/views/email/components/ListPage/pageHeadLeft.vue @@ -77,7 +77,7 @@ checked: boolean; handleId?: number; selectAllRow?: Array<any>; - parentTableList: Array<any>; + parentTableList?: Array<any>; } const props = defineProps<Props>(); const checked = computed(() => props.checked); diff --git a/src/views/email/components/ListPage/table.vue b/src/views/email/components/ListPage/table.vue index 161eb3f..bac6098 100644 --- a/src/views/email/components/ListPage/table.vue +++ b/src/views/email/components/ListPage/table.vue @@ -20,6 +20,7 @@ <template #default="{ row }"> <div style="display: flex; align-items: center"> <div + v-if="row.mailType != 0" class="dot" :class="row.readFlag ? 'dot-color' : ''" @click.stop="fnRowUpdateRead(row)" @@ -91,7 +92,7 @@ class="title-dot" :class="row.readFlag ? 'title-dot-color' : ''" style="font-weight: 500" - >{{ row.subject }}</span + >{{ row.subject || '锛堟棤涓婚锛�' }}</span > - <span style="color: #999">{{ row.subject }}</span> @@ -100,7 +101,7 @@ <vxe-column field="action" title="Action" width="180"> <template #default="{ row }"> <span style="display: flex; justify-content: space-around"> - <span>{{ row.date }}</span> + <span>{{ row.mailType !== 0 ? row.receiveTime : row.createTime }}</span> <span><FieldTimeOutlined @click.stop="fnProcessingTime" /></span> <span><PushpinOutlined @click.stop="fnTagging" /></span> </span> @@ -108,7 +109,12 @@ </vxe-column> </vxe-table> </div> - <DrawerDetail ref="drawerDetailRef" v-model="openDrawerDetail" /> + <DrawerDetail + ref="drawerDetailRef" + v-model="openDrawerDetail" + :mailId="rowMailId" + :allList="dataSource" + /> </div> </template> @@ -289,7 +295,7 @@ vxeTableRef.value.forEach((row) => { row.setAllCheckboxRow(is); }); - selectChangeEvent() + selectChangeEvent(); } function selectChangeEvent() { @@ -323,19 +329,16 @@ import DrawerDetail from './drawerDetail.vue'; // 璇︽儏鍐呭 const openDrawerDetail = ref(false); + const rowMailId = ref(''); const cellClickEvent = (event) => { - console.log(event); + console.log(event.row, '--------455433'); + rowMailId.value = event.row.docCode; openDrawerDetail.value = true; - // collapseStore.toggle(); }; // 鏇存柊绁栫埗缁勪欢鏁版嵁 const getDataList = inject('getDataList'); console.log(getDataList, '0000004'); - - // function sendUpdate() { - // getDataList({ a: '33' }); - // } import { updateReadApi } from '@/api/email/userList'; // 鏍囧織鏈/缁忚 @@ -350,7 +353,7 @@ updateReadApi(params).then((res) => { if (res.code == 0) { // - getDataList({ a: '33' }); + getDataList({}); } }); } diff --git a/src/views/email/components/SelectUser/index.vue b/src/views/email/components/SelectUser/index.vue index 8877557..df68825 100644 --- a/src/views/email/components/SelectUser/index.vue +++ b/src/views/email/components/SelectUser/index.vue @@ -62,7 +62,7 @@ }" :scroll="{ y: 300 }" size="small" - rowKey="id" + rowKey="email" > <!-- :pagination="{ pageSize: 100 }" --> <a-table-column key="userName" title="name" data-index="name"> @@ -157,7 +157,7 @@ ]); // 瀹氫箟浜嬩欢 - const emit = defineEmits(['update:modelValue', 'updateData']); + const emit = defineEmits(['update:modelValue', 'updateData','sudUserList']); // 鍐呴儴鐘舵�� const drawerOpen = ref(props.modelValue); @@ -199,6 +199,7 @@ if (res && res.data && Array.isArray(res.data)) { dataSource.value = flattenAndDeduplicateData(res.data) || ([] as User[]); selectContactNum.value = dataSource.value.length; + emit('sudUserList', dataSource.value) } else { console.error('Invalid response format:', res); } -- Gitblit v1.8.0