From a9a03d64cf190188d3db04d14970fc0908b03491 Mon Sep 17 00:00:00 2001 From: huangyinfeng <1244041895@qq.com> Date: 星期五, 27 九月 2024 09:02:26 +0800 Subject: [PATCH] 部分功能 --- src/components/Tinymce/src/index.vue | 4 src/views/email/Drafts/index.vue | 2 src/views/email/Utils/label.vue | 5 src/views/email/components/ListPage/list.vue | 7 src/views/email/Utils/folder.vue | 70 ++++- src/views/email/components/ListPage/TooltipAndDropdown .vue | 1 src/views/email/index.vue | 4 src/views/email/components/LeftMenu/index.vue | 162 +++++++++++++ src/router/routes/modules/email.ts | 6 src/components/ColorPicker/index.vue | 13 /dev/null | 11 src/views/email/outbox/index.vue | 2 src/views/email/components/ListPage/pageHeadLeft.vue | 42 ++- src/views/email/components/userTips/index.vue | 61 +++++ src/views/email/Edit/index.vue | 30 + src/views/email/components/ListPage/table.vue | 48 +++- src/api/email/userList.ts | 10 src/router/routes/modules/preview.ts | 4 src/views/email/components/ListPage/drawerDetail.vue | 222 ++++++++++-------- src/layouts/page/email.vue | 12 src/App.vue | 2 21 files changed, 531 insertions(+), 187 deletions(-) diff --git a/src/App.vue b/src/App.vue index 401b213..0e74772 100644 --- a/src/App.vue +++ b/src/App.vue @@ -26,7 +26,7 @@ // 鍏堟鏌roxy鏄惁瀛樺湪锛屽啀杩涜鎿嶄綔 if (proxy && proxy.$cookies) { proxy.$cookies.remove('JSESSIONID'); - proxy.$cookies.set('JSESSIONID', '23542F948D2C450599CF5850631B432D.jvm_59_9010', '1d'); + proxy.$cookies.set('JSESSIONID', '741E9E2AAD7578915B16287A5ECAE1DF.jvm_59_9010', '1d'); } else { console.error('proxy瀵硅薄鏈垵濮嬪寲鎴栦笉鍖呭惈$cookies灞炴��'); } diff --git a/src/api/email/userList.ts b/src/api/email/userList.ts index 675a1ee..2b67de7 100644 --- a/src/api/email/userList.ts +++ b/src/api/email/userList.ts @@ -40,7 +40,7 @@ DELETE_FOLDER = '/crm/mail/folder/deleteFolder.do', GET_FOLDER = '/crm/mail/folder/getFolder.do', GET_ROW_ID = '/getRowid.do', - ADD_TAG = '/crm/mail/blacklist/getBlackList.do', + ADD_TAG = '/crm/mail/tag/addTag.do', UPDATE_TAG = '/crm/mail/tag/updateTag.do', DELETE_TAG = '/crm/mail/tag/deleteTag.do', GET_TAG = '/crm/mail/tag/getTagList.do', @@ -48,6 +48,7 @@ UPDATE_BLACKLIST = '/crm/mail/blacklist/updateBlackList.do', DELETE_BLACKLIST = '/crm/mail/blacklist/deleteBlackList.do', GET_BLACKLIST = '/crm/mail/blacklist/getBlackList.do', + GET_EMAIL_MODULE_BELOW = '/crm/mail/getEmailModuleBelow.do', } // 鑾峰彇閭欢璺敱鍒楄〃 export const getEmailModuleApi = () => defHttp.get({ url: Api.GET_EMAIL_MODULE }); @@ -279,3 +280,10 @@ url: Api.GET_BLACKLIST, params, }); + + + export const getEmailModuleBelowApi = () => + defHttp.get({ + url: Api.GET_EMAIL_MODULE_BELOW, + }); + \ No newline at end of file diff --git a/src/components/ColorPicker/index.vue b/src/components/ColorPicker/index.vue index 2bffb93..b35c196 100644 --- a/src/components/ColorPicker/index.vue +++ b/src/components/ColorPicker/index.vue @@ -28,6 +28,7 @@ button-style="solid" size="small" name="color" + @change="groupChange" > <a-radio-button v-for="item in colors" @@ -55,7 +56,7 @@ const props = defineProps({ modelValue: { type: String, - default:'#000000', + default: '#000000', required: true, }, // 1鏅�氾紝2閫夋嫨鍣ㄦā寮� @@ -67,7 +68,7 @@ }); // 瀹氫箟 emits锛岀敤浜庡弻鍚戠粦瀹� - const emit = defineEmits(['update:modelValue','change']); + const emit = defineEmits(['update:modelValue', 'change']); // 棰滆壊閫夐」 const colors = ref([ @@ -105,8 +106,13 @@ // 褰撴湰鍦板�煎彂鐢熷彉鍖栨椂锛屽彂鍑� update:modelValue 浜嬩欢锛岄�氱煡鐖剁粍浠舵洿鏂� watch(localValue, (newValue) => { emit('update:modelValue', newValue); - emit('change', newValue); + // emit('change', newValue); }); + + function groupChange() { + console.log(localValue.value, '------------2'); + emit('change', localValue.value); + } </script> <style lang="less" scoped> @@ -155,6 +161,5 @@ height: 8px; background-color: #fff; clip-path: polygon(50% 60%, 0% 100%, 100% 100%); /* Triangle at the bottom */ - } </style> diff --git a/src/components/Tinymce/src/index.vue b/src/components/Tinymce/src/index.vue index 9015a80..a2b2246 100644 --- a/src/components/Tinymce/src/index.vue +++ b/src/components/Tinymce/src/index.vue @@ -104,7 +104,7 @@ import 'tinymce/plugins/image'; import 'tinymce/plugins/table'; import 'tinymce/plugins/charmap'; - import 'tinymce/plugins/imagetools'; + // import 'tinymce/plugins/imagetools'; import 'tinymce/plugins/help'; import 'tinymce/plugins/emoticons'; import 'tinymce/plugins/emoticons/js/emojis'; @@ -120,7 +120,7 @@ // import 'tinymce/plugins/tinyddrive'; // import 'tinymce/plugins/advcode'; // import 'tinymce/plugins/mediaembed'; - import 'tinymce/plugins/toc'; + // import 'tinymce/plugins/toc'; // import 'tinymce/plugins/checklist'; // import 'tinymce/plugins/tinycespellchecker'; // import 'tinymce/plugins/a11ychecker'; diff --git a/src/layouts/page/email.vue b/src/layouts/page/email.vue index 7bf5dc7..8e7bf0d 100644 --- a/src/layouts/page/email.vue +++ b/src/layouts/page/email.vue @@ -1,11 +1,11 @@ <template> <div> <PageWrapper :class="`${prefixCls}`" dense contentFullHeight fixedHeight> - <div class="default-theme" style="display: flex;height: 100%;background-color: #fff;"> - <div style="width: 10%;height: 100%;"> + <div class="default-theme" style="display: flex; height: 100%; background-color: #fff"> + <div style="width: 10%; height: 100%"> <LeftNav></LeftNav> </div> - <div style="width: 84%;height: 100%;"> + <div style="width: 84%; height: 100%"> <RouterView> <template #default="{ Component, route }"> <transition @@ -36,10 +36,10 @@ </template> <script lang="ts" setup> -import {PageWrapper} from '@/components/Page'; -import { Splitpanes, Pane } from 'splitpanes'; + import { PageWrapper } from '@/components/Page'; + import { Splitpanes, Pane } from 'splitpanes'; - import LeftNav from '@/views/email/components/LeftNav.vue'; + import LeftNav from '@/views/email/components/LeftMenu/index.vue'; import { computed, unref } from 'vue'; import FrameLayout from '@/layouts/iframe/index.vue'; diff --git a/src/router/routes/modules/email.ts b/src/router/routes/modules/email.ts index 06dfdce..a362a3a 100644 --- a/src/router/routes/modules/email.ts +++ b/src/router/routes/modules/email.ts @@ -99,16 +99,14 @@ meta: { title: '鍙戜欢绠�', hideTab: true, - currentActiveMenu: '/email/index', }, children: [ { path: 'list', - name: 'Outbox', + name: 'IndexPage1', component: () => import('@/views/email/outbox/index.vue'), meta: { - title: '鍏ㄩ儴閭欢', - currentActiveMenu: '/email/index', + title: '鍏ㄩ儴鍙戜欢', }, }] }, diff --git a/src/router/routes/modules/preview.ts b/src/router/routes/modules/preview.ts index 81b94b5..6765246 100644 --- a/src/router/routes/modules/preview.ts +++ b/src/router/routes/modules/preview.ts @@ -11,7 +11,9 @@ meta: { orderNo: 10, icon: 'ion:grid-outline', - title: '閭欢棰勮鈥�', + title: '閭欢棰勮', + hideTab: true, + hideMenu: true, }, children: [ { diff --git a/src/views/email/Drafts/index.vue b/src/views/email/Drafts/index.vue index b56bbee..6dc51e3 100644 --- a/src/views/email/Drafts/index.vue +++ b/src/views/email/Drafts/index.vue @@ -1,7 +1,7 @@ <template> <div> <a-spin :spinning="loading" class="p-1" style="height: 100%"> - <PageIndex :pageList="pageList" :mailType="1" :pageData="pageData"> </PageIndex> + <PageIndex :pageList="pageList" :mailType="1" :pageData="pageData" :isDrafts='true'> </PageIndex> </a-spin> </div> </template> diff --git a/src/views/email/Edit/index.vue b/src/views/email/Edit/index.vue index c855cd3..ae47131 100644 --- a/src/views/email/Edit/index.vue +++ b/src/views/email/Edit/index.vue @@ -300,6 +300,9 @@ if (TYPE.value === 'reply') { fuGetReplyEmailData(); } + if (TYPE.value === 'edit') { + fuGetEditEmailData(); + } }); const useForm = Form.useForm; const { validate, validateInfos } = useForm(modelRef, rulesRef); @@ -326,7 +329,7 @@ sendingMailApi, saveMailDraftsApi, emailListAPi, - getMailInfoApi + getMailInfoApi, } from '@/api/email/userList'; // 瀹氫箟鐘舵�佺鐞嗗璞� const state = reactive({ @@ -544,24 +547,35 @@ state.fetching = false; }); }, 300); + // 缂栬緫 + function fuGetEditEmailData() { + getMailInfoApi({ docCode: router.currentRoute.value.query.docCode }) + .then((res) => { + modelRef.sender = res.data.sender; + modelRef.recipients = res.data.receiver; + modelRef.subject = res.data.subject; + modelRef.content = res.data.content; + }) + .catch(() => {}); + } // 鍥炲 function fuGetReplyEmailData() { getMailInfoApi({ docCode: router.currentRoute.value.query.docCode }) .then((res) => { - console.log(ref.data,'---3022'); - modelRef.sender = res.data.receiver[0] - modelRef.recipients = [res.data.sender] - modelRef.subject = 'Re锛�'+ res.data.subject - modelRef.content = setContent(res.data) + console.log(ref.data, '---3022'); + modelRef.sender = res.data.receiver[0]; + modelRef.recipients = [res.data.sender]; + modelRef.subject = 'Re锛�' + res.data.subject; + modelRef.content = setContent(res.data); // tableRowData.value = res.data; }) .catch(() => {}); console.log('----------------4'); } const setContent = (row) => { - const text = `<div style=\"font-size: 12px; font-family: Arial Narrow,serif; padding: 2px 0 2px 0;\">------------------ Original ------------------</div>\n<div style=\"font-size: 12px; background: #efefef; padding: 8px;\">\n<div><strong>From: </strong> ${row.sender} <<a style=\"color: #1e7bf9; text-decoration: none;\" href=\"mailto:${row.sender}\" target=\"_blank\" rel=\"noopener noreferrer\">${row.sender}</a>></div>\n<div><strong>Send time: </strong> ${row.createTime}</div>\n<div><strong>To: </strong> ${row.userName} <<a style=\"color: #1e7bf9; text-decoration: none;\" href=\"mailto:${row.receiver}\" target=\"_blank\" rel=\"noopener noreferrer\">${row.receiver}</a>></div>\n<div><strong>Subject: </strong> ${row.subject}</div>\n</div>` - return text + row.content + const text = `<div style=\"font-size: 12px; font-family: Arial Narrow,serif; padding: 2px 0 2px 0;\">------------------ Original ------------------</div>\n<div style=\"font-size: 12px; background: #efefef; padding: 8px;\">\n<div><strong>From: </strong> ${row.sender} <<a style=\"color: #1e7bf9; text-decoration: none;\" href=\"mailto:${row.sender}\" target=\"_blank\" rel=\"noopener noreferrer\">${row.sender}</a>></div>\n<div><strong>Send time: </strong> ${row.createTime}</div>\n<div><strong>To: </strong> ${row.userName} <<a style=\"color: #1e7bf9; text-decoration: none;\" href=\"mailto:${row.receiver}\" target=\"_blank\" rel=\"noopener noreferrer\">${row.receiver}</a>></div>\n<div><strong>Subject: </strong> ${row.subject}</div>\n</div>`; + return text + row.content; }; </script> <style lang="less" scoped> diff --git a/src/views/email/Utils/folder.vue b/src/views/email/Utils/folder.vue index 65e1ce5..09769c5 100644 --- a/src/views/email/Utils/folder.vue +++ b/src/views/email/Utils/folder.vue @@ -22,7 +22,7 @@ :row-config="{ keyField: 'id' }" :column-config="{ resizable: true }" :export-config="{}" - :tree-config="{ transform: true,rowField: 'rowId', parentField: 'parentRowId' }" + :tree-config="{ transform: true, rowField: 'rowId', parentField: 'parentRowId' }" :edit-config="{ trigger: 'manual', mode: 'row' }" height="600" > @@ -36,7 +36,7 @@ <vxe-column field="folderName" title="鏂囦欢澶瑰悕绉�" minWidth="250" tree-node :edit-render="{}"> <template #edit="{ row }"> <vxe-input - :ref="el => inputRefs[row.id] = el" + :ref="(el) => (inputRefs[row.id] = el)" v-model="row.folderName" type="text" style="width: 300px" @@ -83,9 +83,10 @@ const currRow: Record<string, any> = demo.tableData.splice(oldIndex, 1)[0]; // demo.tableData.splice(newIndex, 0, currRow); updateFolderApi({ - textId: currRow.textId, - textName: currRow.textName, - content: currRow.content, + folderId: currRow.folderId, + folderName: currRow.folderName, + treeControl: currRow.treeControl, + parentRowId: currRow.parentRowId, sortId: newIndex, }) .then(() => { @@ -114,8 +115,30 @@ function fnGetList() { getFolderApi({}).then((res) => { console.log(res); - demo.tableData = res.data; + demo.tableData = convertToTableData(res.data); + console.log(demo.tableData, '3333333333333'); }); + } + function convertToTableData(data, parentId = null) { + let tableData = []; + + data.forEach((item) => { + let tableItem = { + folderId: item.folderId, + parentRowId: parentId, + rowId: item.rowId, + folderName: item.folderName, + treeControl: item.treeControl, + }; + + if (item.list && item.list.length > 0) { + let children = convertToTableData(item.list, item.rowId); + tableData = tableData.concat(children); + } + + tableData.push(tableItem); + }); + return tableData; } const inputRefs = ref<{ [key: number]: HTMLElement | null }>({}); @@ -136,13 +159,28 @@ const { createMessage } = useMessage(); function fnInputHandle(row) { console.log(row, '----333'); - const data = { - folderName: row.folderName, - parentRowId: row.rowId, - }; - addFolderApi(data).then((res) => { + if (row.folderName == '') { + editRowEvent(row) + return createMessage.error('璇疯緭鍏ユ枃浠跺す鍚嶇О'); + } + const data = + row.opType == 'edit' + ? { + folderId: row.folderId, + folderName: row.folderName, + treeControl: row.treeControl, + parentRowId: row.parentRowId, + sortId: row.sortId, + } + : { + folderName: row.folderName, + parentRowId: row.parentRowId, + }; + const api = row.opType == 'edit' ? updateFolderApi : addFolderApi; + const title = row.opType == 'edit' ? '缂栬緫' : '娣诲姞'; + api(data).then((res) => { if (res.code == 0) { - createMessage.success('娣诲姞鎴愬姛'); + createMessage.success(`${title}鎴愬姛`); fnGetList(); } else { createMessage.error(res.msg); @@ -157,9 +195,9 @@ id: rid, parentRowId: row.rowId, // 闇�瑕佹寚瀹氱埗鑺傜偣锛岃嚜鍔ㄦ彃鍏ヨ鑺傜偣涓� }; + console.log(record, '99999993'); const { row: newRow } = await $table.insert(record); - console.log(row,'99999993'); - + await $table.setTreeExpand(row, true); // 灏嗙埗鑺傜偣灞曞紑 await $table.setEditRow(newRow); // 鎻掑叆瀛愯妭鐐� } @@ -178,8 +216,8 @@ function editRowEvent(row) { const $table = xTable.value; - console.log(row,'---30494'); - + console.log(row, '---30494'); + row.opType = 'edit'; $table.setEditRow(row); } onMounted(() => { diff --git a/src/views/email/Utils/label.vue b/src/views/email/Utils/label.vue index e4039ed..a5a057c 100644 --- a/src/views/email/Utils/label.vue +++ b/src/views/email/Utils/label.vue @@ -10,7 +10,7 @@ </div> </template> <template #tools> - <a-button type="primary" @click="showModal('add')">鏂板缓涓汉鏍囩</a-button> + <a-button type="primary" @click="showModal('add','')">鏂板缓涓汉鏍囩</a-button> </template> </vxe-toolbar> @@ -206,9 +206,8 @@ } function fnRowColorChange(color, row) { - console.log(color, row); const data = { - tagColor: row.tagColor, + tagColor: color, tagName: row.tagName, tagType: row.tagType, systemFlag: row.systemFlag, diff --git a/src/views/email/components/LeftMenu/index.vue b/src/views/email/components/LeftMenu/index.vue new file mode 100644 index 0000000..ad5e369 --- /dev/null +++ b/src/views/email/components/LeftMenu/index.vue @@ -0,0 +1,162 @@ +<template> + <PageWrapper dense contentFullHeight fixedHeight> + <div> + <div class="header-container"> + <span class="button-group"> + <a-button shape="circle" size="large"> + <MailOutlined /> + </a-button> + <a-button shape="circle" size="large"> + <UserOutlined /> + </a-button> + </span> + <a-button + class="write-button" + type="primary" + size="large" + shape="round" + @click="$router.push('/email/edit')" + > + 鍐欎俊 + </a-button> + </div> + + <div class="menu-container"> + <a-menu + id="email-left-nav" + v-model:open-keys="openKeys" + v-model:selected-keys="selectedKeys" + mode="inline" + :popupClassName="popupClassName" + > + <template v-for="item in menuItems" :key="item.key"> + <render-menu-item :item="item" @click="handleClick" /> + </template> + </a-menu> + <a-divider /> + <a-menu + id="email-left-nav2" + v-model:open-keys="openKeys" + v-model:selected-keys="selectedKeys" + mode="inline" + :popupClassName="popupClassName" + > + <template v-for="item in menuItems2" :key="item.key"> + <render-menu-item :item="item" @click="handleClick" /> + </template> + </a-menu> + </div> + </div> + </PageWrapper> +</template> + +<script lang="ts" setup> +import { ref, onMounted, computed } from 'vue'; +import { PageWrapper } from '@/components/Page'; +import { MailOutlined, UserOutlined } from '@ant-design/icons-vue'; +import { getEmailModuleApi, getEmailModuleBelowApi } from '@/api/email/userList'; +import { useRouter } from 'vue-router'; + +interface MenuItem { + key: string; + title: string; + total?: number; + children?: MenuItem[]; +} + +const selectedKeys = ref<string[]>(['Index']); +const openKeys = ref<string[]>(['Inbox']); +const items = ref<MenuItem[]>([]); +const items2 = ref<MenuItem[]>([]); + +const fetchEmailModules = async () => { + try { + const [res, res2] = await Promise.all([getEmailModuleApi(), getEmailModuleBelowApi()]); + items.value = convertRoutesToMenuItems(res.data); + items2.value = convertRoutesToMenuItems2(res2.data); + } catch (error) { + console.error('鑾峰彇閭妯″潡澶辫触:', error); + } +}; + +const convertRoutesToMenuItems = (routes: any[]): MenuItem[] => { + return routes + .map(route => ({ + key: route.key, + title: route.mailName, + total: route.total, + children: route.children ? convertRoutesToMenuItems(route.children) : undefined, + })) + .filter(Boolean) as MenuItem[]; +}; + +const convertRoutesToMenuItems2 = (routes: any[]): MenuItem[] => { + return routes + .map(route => ({ + key: route.key, + title: route.name, + total: route.number, + children: route.list ? convertRoutesToMenuItems2(route.list) : undefined, + })) + .filter(Boolean) as MenuItem[]; +}; + +onMounted(fetchEmailModules); + +const routesConfig = { + InboxPage1: '/email/index', + receiver: '/email/Inbox/list', + sender: '/email/outbox/list', + IndexPage1: '/email/outbox', +}; + +const router = useRouter(); +const handleClick = (item: MenuItem) => { + const routePath = routesConfig[item.key] || router.getRoutes().find(r => r.name === item.key)?.path; + if (routePath) { + router.push(routePath); + } else { + console.warn(`Unknown key: ${item.key}`); + } +}; + +const popupClassName = { + display: 'flex', + 'align-items': 'center', + 'justify-content': 'space-between', +}; +</script> + +<style lang="less" scoped> +.header-container { + height: 15vh; + padding: 20px 40px; + text-align: center; +} + +.button-group { + display: flex; + justify-content: space-around; +} + +.write-button { + width: 100%; + margin-top: 10px; + padding: 0 30px; +} + +.menu-container { + height: 70vh; + overflow: auto; +} + +.my-display { + display: flex; + align-items: center; + justify-content: space-between; +} + +.my-left { + margin-left: 5px; +} +</style> diff --git a/src/views/email/components/ListPage/TooltipAndDropdown .vue b/src/views/email/components/ListPage/TooltipAndDropdown .vue index 19b6c55..d179450 100644 --- a/src/views/email/components/ListPage/TooltipAndDropdown .vue +++ b/src/views/email/components/ListPage/TooltipAndDropdown .vue @@ -168,7 +168,6 @@ row: Object, // 褰撳墠琛屽璞� docCodeS: Array, }); -console.log(props,'-59585855'); const emit = defineEmits(['updateHandleTime', 'completeAction', 'customTimeSubmit', 'tagRow']); diff --git a/src/views/email/components/ListPage/drawerDetail.vue b/src/views/email/components/ListPage/drawerDetail.vue index f3443c4..862ff7c 100644 --- a/src/views/email/components/ListPage/drawerDetail.vue +++ b/src/views/email/components/ListPage/drawerDetail.vue @@ -2,76 +2,20 @@ <a-drawer v-model:open="drawerOpen" :placement="placement" - width="1200" + width="68%" :body-style="{ paddingBottom: '80px' }" :footer-style="{ textAlign: 'right' }" @after-open-change="afterOpenChange" @close="drawerClose" > <template #title> - <div class="ctb"> + <div> <pageHeadLeft :checked="true" :selectAllRow="[{ docCode }]" @nextNum="drawerClose" ></pageHeadLeft> - <div class="ct-top"> - <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">{{ formatToDateDay(tableRowData.receiveTime) }}</div> - <div> - <a-dropdown-button> - <span> - <a-tooltip placement="bottom"> - <template #title> - <span>鍥炲</span> - </template> - <LeftOutlined @click="replyEmail(tableRowData)" /> - </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> - </div></div> + </div> </template> <template #extra> <div style="font-size: 16px"> @@ -93,14 +37,81 @@ </a-button> </div> </template> + <div class="ct-top" :class="isOpen ? 'isOpenTop' : 'onOpenTop'"> + <div class="title"> + <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> + <div :style="{ maxWidth: isOpen ? '300px' : '600px' }" class="text-ellipsis">{{ + tableRowData.subject + }}</div> + </a-tooltip> + </span> + <span style="margin-right: 10px; font-size: 16px"> + <PushpinOutlined /> + </span> + </div> + <div class="right"> + <div class="tate">{{ formatToDateDay(tableRowData.receiveTime || tableRowData.updateTime) }}</div> + <div> + <a-dropdown-button> + <div v-if="!isDrafts"> + <span> + <a-tooltip placement="bottom"> + <template #title> + <span>鍥炲</span> + </template> + <LeftOutlined @click="replyEmail(tableRowData, 'reply')" /> + </a-tooltip> + </span> + <a-divider type="vertical" /> + <span> + <a-tooltip placement="bottom"> + <template #title> + <span>蹇�熷洖澶�</span> + </template> + <DoubleLeftOutlined /> + </a-tooltip> + </span> + </div> + <div v-else> + <span @click="replyEmail(tableRowData, 'edit')">鍐嶆缂栬緫</span> + </div> + + <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> + </div> + <div> <div class="flex-between"> <div class="ct-left p-2" :class="isOpen ? 'isOpen' : 'onOpen'"> - <div class="user p-1"> + <div class="user p-1 f-z-14" style="margin-top: 40px"> <div style="display: flex; align-items: center"> <a-avatar size="small" style="margin-right: 8px" src="#" /> - {{ tableRowData.sender }} - <span>{{ `<${tableRowData.sender}>` }}</span> + <div> + <span>{{ tableRowData.senderName }} {{ `<${tableRowData.sender}>` }}</span> + </div> <span style="margin: 0 10px">鍙戦��</span> <a-popover placement="bottom"> <template #content> @@ -126,21 +137,25 @@ {{ `${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" - > + <div type="info" class="p-2 f-z-14" style="margin-top: 10px; background-color: #e4f1ff"> <span>{{ `<${tableRowData.sender}>` }}</span> <span>鏆傛湭鏌ヨ鍒拌瀹㈡埛鐨勫綋鍦版椂闂�</span> <!-- <span>2024-06-08 22:22</span> --> </div> - <div class="ct" v-if="tableRowData.content"> - <TinymcePw ref="TinymcePwRef" v-model="tableRowData.content" /> + <div class="ct"> + <div v-if="tableRowData.content"> + <TinymcePw ref="TinymcePwRef" v-model="tableRowData.content" /> + </div> </div> </div> </div> - <div v-show="isOpen" class="ct-right p-2">sssss</div> + <div v-show="isOpen" class="ct-right"> + <div style="position: relative"> + <div style="position: absolute; top: 0; left: 10px"> + <UserTips></UserTips> + </div> + </div> + </div> </div> <div @click="fuToggleContent" class="toggle-btn" :class="isOpen ? 'onIconOpen' : 'iconOpen'"> <LeftOutlined v-if="!isOpen" /> @@ -164,6 +179,7 @@ RollbackOutlined, } from '@ant-design/icons-vue'; import pageHeadLeft from './pageHeadLeft.vue'; + import UserTips from '@/views/email/components/userTips/index.vue'; import { TinymcePw } from '@/components/Tinymce'; import { getMailInfoApi, setQuickReplyAPi } from '@/api/email/userList'; import { useCollapseStore } from '@/store/modules/useCollapseStore'; @@ -182,6 +198,7 @@ mailId?: string; selectAllRow: Array<any>; allList; + isDrafts?: boolean; } const props = defineProps<Props>(); @@ -201,9 +218,12 @@ watch( () => props.modelValue, (newValue) => { - drawerOpen.value = newValue; nextTick(() => { - console.log(newValue, '---------4', TinymcePwRef.value); + drawerOpen.value = newValue; + setTimeout(() => { + console.log(newValue, '---------4', TinymcePwRef.value); + tableRowData.value.content = tableRowData.value.content; + }, 500); }); if (newValue) { fnGetMailInfo(props.mailId); @@ -214,8 +234,10 @@ function fnGetMailInfo(id) { getMailInfoApi({ docCode: id }) .then((res) => { - docCode.value = id; - tableRowData.value = res.data; + nextTick(() => { + docCode.value = id; + tableRowData.value = res.data; + }); }) .catch(() => {}); } @@ -236,21 +258,12 @@ drawerOpen.value = false; }; - function truncateString(str, maxLength) { - return str.length > maxLength ? str.substring(0, maxLength) + '...' : str; - } - const fnGetUserList = (params) => { // 璋冪敤鎺ュ彛閫昏緫 }; // 璁$畻灞炴�� const placement = computed(() => props.placement || 'right'); - - // 鎶藉眽寮�鍏� - const fnSaveOpenChange = () => { - // 鎶藉眽淇濆瓨閫昏緫 - }; const content = ref(''); const isOpen = ref(false); @@ -306,8 +319,8 @@ } import { useRouter } from 'vue-router'; const router = useRouter(); - function replyEmail(row) { - router.push({ path: '/email/edit', query: { docCode: row.docCode, type: 'reply' } }); + function replyEmail(row, type) { + router.push({ path: '/email/edit', query: { docCode: row.docCode, type: type } }); } </script> @@ -345,13 +358,12 @@ & .right { display: flex; + flex: 1; align-items: center; - justify-content: space-between; - width: 25%; + justify-content: flex-end; & .tate { - color: #999; - font-size: 14px; + margin-right: 10px; } } } @@ -362,7 +374,6 @@ .flex-between { display: flex; - padding-top: 4%; } .ct-left { @@ -370,7 +381,7 @@ } .ct-right { - border-left: 1px solid #f0f0f0; + flex: 1; } .toggle-btn { @@ -393,7 +404,15 @@ } .isOpen { - width: 69%; + width: calc(100% - 420px); + } + + .onOpenTop { + width: 98%; + } + + .isOpenTop { + width: calc(98% - 460px); } .iconOpen { @@ -401,20 +420,29 @@ } .onIconOpen { - right: 32%; + right: 425px; } .ctb { position: relative; } - .ctb .ct-top { + .ct-top { position: absolute; z-index: 99; - top: 41px; - left: -28px; - width: 116%; + top: 57px; + left: 10px; padding: 10px; background: #fff; } + + .text-ellipsis { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .f-z-14 { + font-size: 12px; + } </style> diff --git a/src/views/email/components/ListPage/list.vue b/src/views/email/components/ListPage/list.vue index b760c3e..3ac5a6e 100644 --- a/src/views/email/components/ListPage/list.vue +++ b/src/views/email/components/ListPage/list.vue @@ -61,7 +61,7 @@ </a-switch> </div> </div> - <div v-if="checked" class="left-bt p-3"> + <div v-if="checked" style="height: 30px;" class="left-bt p-3"> 宸查�夋嫨姝ら〉闈笂鎵�鏈� 20 灏侀偖浠� 锛� 閫夋嫨鍏ㄩ儴 335 灏侀偖浠� </div> <div class="p-4" style="height: 90%; overflow: hidden"> @@ -76,6 +76,7 @@ ref="tableRef" :page="pageCurrent" :pageList="newList" + :isDrafts="isDrafts" @selectAll="fnSelectAll" @updateSelectAll="updateSelectAll" /> @@ -102,7 +103,9 @@ // 瀹氫箟灞炴�� interface Props { pageList?: []; - pageData?:any; + pageData?: any; + mailType?: number; + isDrafts?: boolean; } const props = defineProps<Props>(); const newList = ref([]); diff --git a/src/views/email/components/ListPage/pageHeadLeft.vue b/src/views/email/components/ListPage/pageHeadLeft.vue index 0280483..8791f36 100644 --- a/src/views/email/components/ListPage/pageHeadLeft.vue +++ b/src/views/email/components/ListPage/pageHeadLeft.vue @@ -47,25 +47,25 @@ </template> <a-dropdown :arrow="{ pointAtCenter: true }" placement="bottom" :trigger="['click']"> <template #overlay> - <a-menu> + <a-menu v-if="checked"> <a-menu-item key="2" @click="fnSelectAllRead(true)"> 鏍囦负宸茶</a-menu-item> <a-menu-item key="3" @click="fnSelectAllRead(false)"> 鏍囦负鏈</a-menu-item> <a-menu-item key="4"> 璁句负缃《</a-menu-item> <a-divider style="margin: 2px; padding: 2px" /> <a-menu-item key="5"> 鏍囪涓哄瀮鍦鹃偖浠�</a-menu-item> </a-menu> - </template> - <MoreOutlined v-show="checked" class="icon" /> + <!-- </template> + <MoreOutlined v-if="checked" class="icon" /> </a-dropdown> <a-dropdown :arrow="{ pointAtCenter: true }" placement="bottom" :trigger="['click']"> - <template #overlay> - <a-menu> + <template #overlay> --> + <a-menu v-else> <a-menu-item key="1" @click="fnAllRead">鍏ㄩ儴鏍囪涓哄凡璇�</a-menu-item> <a-divider style="margin: 2px; padding: 2px" /> <p style="color: #999; font-size: 12px">鍕鹃�夐偖浠跺嵆鍙煡鐪嬫洿澶氭搷浣�</p> </a-menu> </template> - <MoreOutlined v-show="!checked" class="icon" /> + <MoreOutlined class="icon" /> </a-dropdown> </a-tooltip> </div> @@ -105,10 +105,17 @@ pushUpdateReadApi(data); } const getSelectAllBocCode = computed(() => { - let data = props.selectAllRow.map((item) => item.docCode); - console.log(data, '00003'); + try { + if (props.parentTableList?.length == 0) { + return []; + } + let data = props.selectAllRow.map((item) => item.docCode); + console.log(data, '00003'); - return data; + return data; + } catch (error) { + return []; + } }); function pushUpdateReadApi(data) { updateReadApi(data).then((res) => { @@ -130,11 +137,18 @@ pushUpdateReadApi(data); } function getReadId() { - const ids = []; - props.parentTableList.forEach((item: Record<string, any>) => { - ids.push(item.docCode); - }); - return ids; + try { + const ids = []; + if (props.parentTableList?.length == 0) { + return []; + } + props.parentTableList.forEach((item: Record<string, any>) => { + ids.push(item.docCode); + }); + return ids; + } catch (error) { + return []; + } } const emit = defineEmits(['nextNum']); function fuDeleteEmail() { diff --git a/src/views/email/components/ListPage/table.vue b/src/views/email/components/ListPage/table.vue index cf832e1..9e107d4 100644 --- a/src/views/email/components/ListPage/table.vue +++ b/src/views/email/components/ListPage/table.vue @@ -23,7 +23,7 @@ <div v-if="row.mailType != 0" class="dot" - :class="row.readFlag ? 'dot-color' : ''" + :class="fnIsItHighlighted(row) ? 'dot-color' : ''" @click.stop="fnRowUpdateRead(row)" ></div> <a-tooltip placement="bottom"> @@ -45,7 +45,7 @@ > <a-avatar size="small" style="margin-right: 8px" :src="row.avatar" /> <span style="color: #000; font-weight: 700">{{ row.sender }}</span> - <CopyOutlined /> + <CopyOutlined @click="copyText(row.sender)" /> </div> <div class="display-flex p-2"> <a-button type="link" size="small">鏂板缓瀹㈡埛</a-button> @@ -78,7 +78,7 @@ <a-button type="link" size="small">寰�鏉ラ偖浠�</a-button></div > </template> - <div class="title-dot" :class="row.readFlag ? 'title-dot-color' : ''"> + <div class="title-dot" :class="fnIsItHighlighted(row) ? '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> @@ -97,7 +97,7 @@ <template #default="{ row }"> <span class="title-dot" - :class="row.readFlag ? 'title-dot-color' : ''" + :class="fnIsItHighlighted(row) ? 'title-dot-color' : ''" style="font-weight: 500" >{{ row.subject || '锛堟棤涓婚锛�' }}</span > @@ -126,11 +126,10 @@ </span> </template> </vxe-column> - </vxe-table> - </div + </vxe-table> </div ></div> - <div v-else style="height: 70vh; display: flex; align-items: center; justify-content: center"> + <div v-else style="display: flex; align-items: center; justify-content: center; height: 70vh"> <a-empty /> </div> <DrawerDetail @@ -139,6 +138,7 @@ :mailId="rowMailId" :selectAllRow="selectRow" :allList="dataSource" + :isDrafts="isDrafts" /> <a-dropdown :trigger="['click']" placement="bottomLeft" ref="dropdownRefs"> </a-dropdown> </div> @@ -158,6 +158,7 @@ // 瀹氫箟灞炴�� interface Props { pageList: []; + isDrafts?: boolean; } const props = defineProps<Props>(); @@ -316,11 +317,21 @@ } } const vxeTableRef = ref(); + function fnIsItHighlighted(row) { + return row.readFlag && props.isDrafts; + } function fnSelectAll(is) { - vxeTableRef.value.forEach((row) => { - row.setAllCheckboxRow(is); - }); - selectChangeEvent(); + try { + if (!vxeTableRef.value) { + return; + } + vxeTableRef.value.forEach((row) => { + row.setAllCheckboxRow(is); + }); + selectChangeEvent(); + } catch (error) { + console.log(error); + } } function selectChangeEvent() { @@ -360,12 +371,12 @@ selectRow.value = []; rowMailId.value = event.row.docCode; selectRow.value.push({ docCode: event.row.docCode }); + fnRowUpdateRead(event.row); openDrawerDetail.value = true; }; // 鏇存柊绁栫埗缁勪欢鏁版嵁 const getDataList = inject('getDataList'); - console.log(getDataList, '0000004'); import { updateReadApi, updateHandleAPi } from '@/api/email/userList'; // 鏍囧織鏈/缁忚 @@ -384,6 +395,19 @@ } }); } + import { useMessage } from '@/hooks/web/useMessage'; + + const { createMessage } = useMessage(); + const copyText = async (value) => { + try { + await navigator.clipboard.writeText(value); + setTimeout(() => { + createMessage.success('澶嶅埗鎴愬姛'); + }, 500); + } catch (err) { + console.error('澶嶅埗澶辫触: ', err); + } + }; const emit = defineEmits(['selectAll', 'updateSelectAll']); defineExpose({ fnSelectAll, diff --git a/src/views/email/components/emailDetail.vue b/src/views/email/components/emailDetail.vue deleted file mode 100644 index 2b41ec9..0000000 --- a/src/views/email/components/emailDetail.vue +++ /dev/null @@ -1,11 +0,0 @@ -<template> - <PageWrapper dense contentFullHeight fixedHeight> - 888 - </PageWrapper> -</template> - -<script lang="ts" setup> -import { PageWrapper } from '@/components/Page'; -</script> - -<style lang="less" scoped></style> diff --git a/src/views/email/components/userTips/index.vue b/src/views/email/components/userTips/index.vue new file mode 100644 index 0000000..717335f --- /dev/null +++ b/src/views/email/components/userTips/index.vue @@ -0,0 +1,61 @@ +<template> + <a-layout class="p-2" style="width: 420px; background-color: #fff"> + <div :style="headerStyle"> + <div class="my-d-f"> + <a-avatar style="margin-right: 8px" src="#" /> + <div> + <div style="color: #000; font-weight: 700">XXX</div> + <div style="color: #000"> 124404189@qq.com </div> + </div> + </div> + </div> + <a-layout-content> + <a-tabs v-model:activeKey="activeKey" class="m-t-4"> + <a-tab-pane key="1" tab="瀹㈡埛鐢诲儚"> + <div class="tabs-bk p-2" v-if="activeKey === '1'">sssssssssssssss</div> + </a-tab-pane> + <a-tab-pane key="2" tab="寤烘。寤鸿" force-render> + <div class="tabs-bk p-2" v-if="activeKey === '2'"></div> + </a-tab-pane> + <a-tab-pane key="3" tab="璋堝崟鎸囧崡" + ><div class="tabs-bk p-2" v-if="activeKey === '3'"></div + ></a-tab-pane> + <a-tab-pane key="4" tab="鏂囨。璁板綍" + ><div class="tabs-bk p-2" v-if="activeKey === '4'" + /></a-tab-pane> + <a-tab-pane key="5" tab="鐗╂祦鏌ヤ环" + ><div class="tabs-bk p-2" v-if="activeKey === '5'" + /></a-tab-pane> + <a-tab-pane key="6" tab="寰�鏉ラ偖浠�" + ><div class="tabs-bk p-2" v-if="activeKey === '6'" + /></a-tab-pane> + <a-tab-pane key="6" tab="Tips" + ><div class="tabs-bk p-2" v-if="activeKey === '6'" + /></a-tab-pane> + </a-tabs> + </a-layout-content> + </a-layout> +</template> + +<script lang="ts" setup> + name: 'Utils'; + import { ref } from 'vue'; + const headerStyle = { + color: '#fff', + height: 104, + paddingInline: 50, + backgroundColor: '#fff', + }; + const activeKey = ref('1'); +</script> +<style scoped lang="less"> + .tabs-bk { + height: 60vh; + background-color: #fafafa; + } + + + .vxe-tabs-header--bar { + border: 0 solid transparent; + } +</style> diff --git a/src/views/email/index.vue b/src/views/email/index.vue index a3186f6..d7e1dc5 100644 --- a/src/views/email/index.vue +++ b/src/views/email/index.vue @@ -42,8 +42,8 @@ <script lang="ts" setup> import { PageWrapper } from '@/components/Page'; - import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue'; - import LeftNav from '@/views/email/components/LeftNav.vue'; +import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue'; + import LeftNav from '@/views/email/components/LeftMenu/index.vue'; import { computed, unref, ref } from 'vue'; import FrameLayout from '@/layouts/iframe/index.vue'; diff --git a/src/views/email/outbox/index.vue b/src/views/email/outbox/index.vue index e5386d2..1107ef1 100644 --- a/src/views/email/outbox/index.vue +++ b/src/views/email/outbox/index.vue @@ -7,7 +7,7 @@ </template> <script lang="ts" setup> - name: 'outbox'; + name: 'IndexPage1'; import { ref, onMounted, computed, provide } from 'vue'; import PageIndex from '@/views/email/components/ListPage/list.vue'; import { useRoute } from 'vue-router'; -- Gitblit v1.8.0