├── .gitattributes ├── .gitee └── ISSUE_TEMPLATE │ ├── bug.yml │ ├── config.yml │ └── feature.yml ├── .github └── ISSUE_TEMPLATE │ ├── bug.yml │ ├── config.yml │ └── feature.yml ├── .gitignore ├── LICENSE ├── README.md ├── pom.xml ├── risenet-y9boot-api-feignclient-webmail ├── lombok.config ├── pom.xml └── src │ └── main │ └── java │ └── y9 │ └── client │ └── rest │ └── webmail │ └── StandardEmailApiClient.java ├── risenet-y9boot-api-interface-webmail ├── lombok.config ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── risesoft │ └── api │ └── webmail │ └── StandardEmailApi.java ├── risenet-y9boot-support-webmail ├── lombok.config ├── pom.xml └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── risesoft │ │ │ ├── api │ │ │ └── StandardEmailApiImpl.java │ │ │ ├── config │ │ │ └── EmailConfiguration.java │ │ │ ├── controller │ │ │ ├── EmailAttachmentController.java │ │ │ ├── EmailController.java │ │ │ ├── EmailFolderController.java │ │ │ ├── GroupController.java │ │ │ ├── ImportEmlController.java │ │ │ ├── JamesAddressBookController.java │ │ │ ├── JamesUserController.java │ │ │ ├── OrgController.java │ │ │ ├── SyncController.java │ │ │ ├── dto │ │ │ │ ├── EmailAttachmentDTO.java │ │ │ │ ├── EmailContactDTO.java │ │ │ │ ├── EmailDTO.java │ │ │ │ ├── EmailDetailDTO.java │ │ │ │ ├── EmailFolderDTO.java │ │ │ │ ├── EmailListDTO.java │ │ │ │ ├── EmailSearchDTO.java │ │ │ │ └── ToDTO.java │ │ │ ├── rest │ │ │ │ └── EmailMobileController.java │ │ │ └── vo │ │ │ │ ├── ImportEmlAttchMentVO.java │ │ │ │ └── ImportEmlVO.java │ │ │ ├── filter │ │ │ └── EmailAddressFilter.java │ │ │ ├── james │ │ │ ├── entity │ │ │ │ ├── ImportEml.java │ │ │ │ ├── ImportEmlAttchMents.java │ │ │ │ ├── JamesAddressBook.java │ │ │ │ ├── JamesUser.java │ │ │ │ └── term │ │ │ │ │ ├── MyAttachmentTerm.java │ │ │ │ │ ├── MyBodyTerm.java │ │ │ │ │ ├── MyFlagTerm.java │ │ │ │ │ ├── MyFormTerm.java │ │ │ │ │ ├── MyMessageIDTerm.java │ │ │ │ │ ├── MyReceiverTerm.java │ │ │ │ │ └── MySubjectTerm.java │ │ │ ├── repository │ │ │ │ ├── ImportEmlAttchMentsRepository.java │ │ │ │ ├── ImportEmlRepository.java │ │ │ │ ├── JamesAddressBookRepository.java │ │ │ │ └── JamesUserRepository.java │ │ │ └── service │ │ │ │ ├── ImportEmlAttchMentsService.java │ │ │ │ ├── ImportEmlService.java │ │ │ │ ├── JamesAddressBookService.java │ │ │ │ ├── JamesUserService.java │ │ │ │ └── impl │ │ │ │ ├── ImportEmlAttchMentsServiceImpl.java │ │ │ │ ├── ImportEmlServiceImpl.java │ │ │ │ ├── JamesAddressBookServiceImpl.java │ │ │ │ └── JamesUserServiceImpl.java │ │ │ ├── listener │ │ │ └── Y9EventOrgListener.java │ │ │ ├── pojo │ │ │ └── EmlResult.java │ │ │ ├── service │ │ │ ├── EmailAttachmentService.java │ │ │ ├── EmailFolderService.java │ │ │ ├── EmailMessageService.java │ │ │ ├── EmailService.java │ │ │ └── impl │ │ │ │ ├── EmailAttachmentServiceImpl.java │ │ │ │ ├── EmailFolderServiceImpl.java │ │ │ │ ├── EmailMessageServiceImpl.java │ │ │ │ ├── EmailServiceImpl.java │ │ │ │ └── MailHelper.java │ │ │ ├── support │ │ │ ├── DefaultFolder.java │ │ │ ├── EmailConst.java │ │ │ ├── EmailErrorCodeEnum.java │ │ │ └── EmailThreadLocalHolder.java │ │ │ ├── util │ │ │ ├── ConvertPinYin.java │ │ │ ├── EmailUtil.java │ │ │ └── MimeMessageParser.java │ │ │ └── y9 │ │ │ └── configuration │ │ │ └── app │ │ │ └── y9webmail │ │ │ └── Y9WebMailProperties.java │ └── resources │ │ ├── smart-doc.json │ │ ├── todo.md │ │ └── 新用户收件.eml │ └── test │ └── java │ └── net │ └── risesoft │ └── EmlBasicTest.java ├── risenet-y9boot-webapp-webmail ├── lombok.config ├── pom.xml └── src │ └── main │ ├── java │ └── net │ │ └── risesoft │ │ ├── ServletInitializer.java │ │ ├── WebmailApplication.java │ │ └── config │ │ ├── ListenerAsyncConfig.java │ │ └── WebmailConfigurer.java │ └── resources │ ├── application-demo.yml │ ├── application-dev.yml │ ├── application-local.yml │ ├── application-prod.yml │ ├── application-test.yml │ ├── application.yml │ ├── banner.txt │ ├── logback.xml │ └── templates │ └── signature.txt └── vue └── y9vue-webmail ├── .env.development ├── .env.localEnv ├── .env.production ├── .eslintignore ├── .eslintrc.js ├── .prettierignore ├── README.md ├── auto-imports.d.ts ├── components.d.ts ├── index.html ├── package-lock.json ├── package.json ├── prettier.config.js ├── public ├── tinymce │ ├── langs │ │ └── zh-Hans.js │ └── skins │ │ ├── content │ │ ├── dark │ │ │ ├── content.css │ │ │ ├── content.js │ │ │ └── content.min.css │ │ ├── default │ │ │ ├── content.css │ │ │ ├── content.js │ │ │ └── content.min.css │ │ ├── document │ │ │ ├── content.css │ │ │ ├── content.js │ │ │ └── content.min.css │ │ ├── tinymce-5-dark │ │ │ ├── content.css │ │ │ ├── content.js │ │ │ └── content.min.css │ │ ├── tinymce-5 │ │ │ ├── content.css │ │ │ ├── content.js │ │ │ └── content.min.css │ │ └── writer │ │ │ ├── content.css │ │ │ ├── content.js │ │ │ └── content.min.css │ │ └── ui │ │ ├── oxide-dark │ │ ├── content.css │ │ ├── content.inline.css │ │ ├── content.inline.js │ │ ├── content.inline.min.css │ │ ├── content.js │ │ ├── content.min.css │ │ ├── skin.css │ │ ├── skin.js │ │ ├── skin.min.css │ │ ├── skin.shadowdom.css │ │ ├── skin.shadowdom.js │ │ └── skin.shadowdom.min.css │ │ ├── oxide │ │ ├── content.css │ │ ├── content.inline.css │ │ ├── content.inline.js │ │ ├── content.inline.min.css │ │ ├── content.js │ │ ├── content.min.css │ │ ├── skin.css │ │ ├── skin.js │ │ ├── skin.min.css │ │ ├── skin.shadowdom.css │ │ ├── skin.shadowdom.js │ │ └── skin.shadowdom.min.css │ │ ├── tinymce-5-dark │ │ ├── content.css │ │ ├── content.inline.css │ │ ├── content.inline.js │ │ ├── content.inline.min.css │ │ ├── content.js │ │ ├── content.min.css │ │ ├── skin.css │ │ ├── skin.js │ │ ├── skin.min.css │ │ ├── skin.shadowdom.css │ │ ├── skin.shadowdom.js │ │ └── skin.shadowdom.min.css │ │ └── tinymce-5 │ │ ├── content.css │ │ ├── content.inline.css │ │ ├── content.inline.js │ │ ├── content.inline.min.css │ │ ├── content.js │ │ ├── content.min.css │ │ ├── skin.css │ │ ├── skin.js │ │ ├── skin.min.css │ │ ├── skin.shadowdom.css │ │ ├── skin.shadowdom.js │ │ └── skin.shadowdom.min.css └── yun.ico ├── src ├── App.vue ├── api │ ├── email │ │ ├── attachment.ts │ │ └── index.ts │ ├── folder │ │ └── index.ts │ ├── importEml │ │ └── index.ts │ ├── lib │ │ └── emailRequest.js │ └── org │ │ └── index.ts ├── assets │ ├── css │ │ ├── nprogress.css │ │ └── variables.scss │ ├── icons │ │ ├── png │ │ │ ├── cloud.png │ │ │ ├── file.png │ │ │ ├── folder-open.png │ │ │ ├── metro.png │ │ │ ├── node_home.png │ │ │ ├── node_system.png │ │ │ ├── search.png │ │ │ ├── user_female.png │ │ │ ├── user_gray.png │ │ │ └── user_male.png │ │ └── svg │ │ │ ├── ask.svg │ │ │ ├── chart.svg │ │ │ ├── components.svg │ │ │ ├── control.svg │ │ │ ├── editor.svg │ │ │ ├── history.svg │ │ │ ├── home.svg │ │ │ ├── image-text.svg │ │ │ ├── layers.svg │ │ │ ├── message.svg │ │ │ ├── monitoring.svg │ │ │ ├── other.svg │ │ │ ├── page.svg │ │ │ ├── pagedetails.svg │ │ │ ├── pageform.svg │ │ │ ├── pagelist.svg │ │ │ ├── roles.svg │ │ │ ├── s-fold.svg │ │ │ ├── s-unfold.svg │ │ │ ├── set.svg │ │ │ ├── tree.svg │ │ │ ├── users.svg │ │ │ └── y9-logo.svg │ ├── iconsvg │ │ ├── arrow-down.svg │ │ ├── arrow-left.svg │ │ ├── arrow-left2.svg │ │ ├── arrow-right.svg │ │ ├── arrow-right2.svg │ │ ├── arrow-up.svg │ │ ├── chart.svg │ │ ├── close.svg │ │ ├── close2.svg │ │ ├── components.svg │ │ ├── control.svg │ │ ├── detail.svg │ │ ├── edit.svg │ │ ├── editor.svg │ │ ├── home.svg │ │ ├── icon.svg │ │ ├── language-outline.svg │ │ ├── list.svg │ │ ├── menu-fold.svg │ │ ├── menu-unfold.svg │ │ ├── message.svg │ │ ├── more.svg │ │ ├── page.svg │ │ ├── permissions.svg │ │ ├── pwd.svg │ │ ├── refresh.svg │ │ ├── search.svg │ │ ├── set.svg │ │ ├── svgo.yml │ │ └── user.svg │ └── images │ │ ├── app-icon.png │ │ ├── bg-smooth.jpg │ │ ├── bg.jpg │ │ ├── logo.png │ │ ├── meeting.jpg │ │ ├── menu-bg1.png │ │ ├── menu-bg10.png │ │ ├── menu-bg5.png │ │ ├── menu-bg7.png │ │ ├── menu-bg8.png │ │ ├── menu-bg9.png │ │ ├── todo.jpg │ │ ├── touxiang.png │ │ ├── xiangqing │ │ ├── file-download-line.png │ │ ├── file-excel-line.png │ │ ├── file-pdf-line.png │ │ ├── file-ppt-line.png │ │ ├── file-text-line.png │ │ ├── file-unknow-line.png │ │ ├── file-word-line.png │ │ ├── image-line.png │ │ └── zip.png │ │ ├── youshengyunLogo.png │ │ ├── yun.png │ │ └── yunLogo.png ├── components │ ├── Editor │ │ ├── index.vue │ │ └── plugins │ │ │ └── powerpaste │ │ │ ├── js │ │ │ └── wordimport.js │ │ │ └── plugin.min.js │ └── selectPerson │ │ └── index.vue ├── language │ ├── en.json │ ├── index.js │ └── zh.json ├── layouts │ ├── Y9-default │ │ ├── Left.vue │ │ ├── RightTop.vue │ │ └── index.vue │ ├── Y9-horizontal │ │ ├── Navs.vue │ │ ├── RightTop.vue │ │ └── index.vue │ ├── Y9-mobile │ │ ├── Left.vue │ │ ├── RightTop.vue │ │ └── index.vue │ ├── components │ │ ├── ALink │ │ │ └── index.vue │ │ ├── BreadCrumbs │ │ │ └── index.vue │ │ ├── Icon.vue │ │ ├── IconSvg │ │ │ ├── index.ts │ │ │ ├── index.vue │ │ │ └── plugin.ts │ │ ├── Lock │ │ │ ├── index.vue │ │ │ └── pass.vue │ │ ├── RightTabNav.vue │ │ ├── RightTopMessage.vue │ │ ├── RightTopPosition.vue │ │ ├── RightTopUser.vue │ │ ├── SettingsMobile.vue │ │ ├── SiderMenu.vue │ │ ├── SiderMenuItem.vue │ │ ├── Tabs │ │ │ └── index.vue │ │ ├── search │ │ │ └── index.vue │ │ └── useTopMenuWidth.ts │ └── index.vue ├── main.ts ├── router │ ├── checkRole.js │ ├── checkRouter.js │ ├── getInitData.js │ ├── index.ts │ └── modules │ │ ├── authRouter.js │ │ ├── dynamicRouter.ts │ │ ├── emailDetailRouter.js │ │ ├── homeRouter.js │ │ ├── importEmlRouter.js │ │ └── menuRouter.js ├── settings.ts ├── store │ ├── index.ts │ └── modules │ │ ├── dictionaryStore.ts │ │ ├── folderStore.ts │ │ ├── publicTreeStore.ts │ │ ├── routerStore.ts │ │ ├── selectTreeStore.ts │ │ └── settingStore.ts ├── theme │ ├── blue │ │ └── blue.scss │ ├── dark │ │ └── dark.scss │ ├── default │ │ └── default.scss │ ├── global-vars.scss │ ├── global.scss │ ├── green │ │ └── green.scss │ └── red │ │ └── red.scss ├── types │ └── global.ts ├── utils │ ├── data.ts │ ├── directive.ts │ ├── echarts.ts │ ├── index.ts │ ├── object.ts │ ├── render.vue │ ├── routes.ts │ ├── storage.js │ ├── time.ts │ └── validate.ts └── views │ ├── 401 │ └── index.vue │ ├── 404 │ └── index.vue │ ├── collect │ └── index.vue │ ├── draft │ └── index.vue │ ├── dynamic │ └── dynamic.vue │ ├── emailDetail │ └── index.vue │ ├── garbage │ └── index.vue │ ├── importEml │ ├── dialogContent │ │ └── uploadEml.vue │ ├── emailDetail │ │ └── index.vue │ └── index.vue │ ├── receive │ └── index.vue │ ├── search │ └── index.vue │ ├── sent │ └── index.vue │ └── write │ └── index.vue ├── tsconfig.json └── vite.config.js /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.vue linguist-language=Java 3 | *.java linguist-language=Java 4 | *.js linguist-language=Java 5 | *.css linguist-language=Java 6 | *.html linguist-language=Java -------------------------------------------------------------------------------- /.gitee/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: Bug 反馈 2 | description: 当你在代码中发现了一个 Bug,导致应用崩溃或抛出异常,或者有一个组件存在问题,或者某些地方看起来不对劲。 3 | title: "[Bug]: " 4 | labels: ["bug"] 5 | assignees: 6 | - risesoft-y9 7 | body: 8 | - type: markdown 9 | attributes: 10 | value: | 11 | 感谢对项目的支持与关注。在提出问题之前,请确保你已查看相关开发或使用文档: 12 | - https://docs.youshengyun.com/email/backend/introduction 13 | - type: checkboxes 14 | attributes: 15 | label: 这个问题是否已经存在? 16 | options: 17 | - label: 我已经搜索过现有的问题 (https://gitee.com/risesoft-y9/y9-email/issues) 18 | required: true 19 | - type: textarea 20 | attributes: 21 | label: 如何复现 22 | description: 请详细告诉我们如何复现你遇到的问题,如涉及代码,可提供一个最小代码示例,并使用反引号```附上它 23 | placeholder: | 24 | 1. ... 25 | 2. ... 26 | 3. ... 27 | validations: 28 | required: true 29 | - type: textarea 30 | attributes: 31 | label: 预期结果 32 | description: 请告诉我们你预期会发生什么。 33 | validations: 34 | required: true 35 | - type: textarea 36 | attributes: 37 | label: 实际结果 38 | description: 请告诉我们实际发生了什么。 39 | validations: 40 | required: true 41 | - type: textarea 42 | attributes: 43 | label: 截图或视频 44 | description: 如果可以的话,上传任何关于 bug 的截图。 45 | value: | 46 | [在这里上传图片] 47 | - type: input 48 | id: version 49 | attributes: 50 | label: 版本 51 | description: 你当前正在使用我们软件的主分支哪个版本? 52 | placeholder: 输入你当前正在使用我们软件的主分支的版本 53 | validations: 54 | required: true -------------------------------------------------------------------------------- /.gitee/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 电子邮件文档 4 | url: https://docs.youshengyun.com/email/backend/introduction 5 | about: 提供电子邮件介绍、基本组件使用和常见问题解答 -------------------------------------------------------------------------------- /.gitee/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: 功能建议 2 | description: 对本项目提出一个功能建议 3 | title: "[功能建议]: " 4 | labels: ["enhancement"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | 感谢提出功能建议,我们将仔细考虑! 10 | - type: textarea 11 | id: related-problem 12 | attributes: 13 | label: 你的功能建议是否和某个问题相关? 14 | description: 清晰并简洁地描述问题是什么,例如,当我...时,我总是感到困扰。 15 | validations: 16 | required: false 17 | - type: textarea 18 | id: desired-solution 19 | attributes: 20 | label: 你希望看到什么解决方案? 21 | description: 清晰并简洁地描述你希望发生的事情。 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: alternatives 26 | attributes: 27 | label: 你考虑过哪些替代方案? 28 | description: 清晰并简洁地描述你考虑过的任何替代解决方案或功能。 29 | validations: 30 | required: false 31 | - type: textarea 32 | id: additional-context 33 | attributes: 34 | label: 你有其他上下文或截图吗? 35 | description: 在此处添加有关功能请求的任何其他上下文或截图。 36 | validations: 37 | required: false 38 | - type: checkboxes 39 | attributes: 40 | label: 意向参与贡献 41 | options: 42 | - label: 我有意向参与具体功能的开发实现并将代码贡献回到上游社区 43 | required: false -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: Bug 反馈 2 | description: 当你在代码中发现了一个 Bug,导致应用崩溃或抛出异常,或者有一个组件存在问题,或者某些地方看起来不对劲。 3 | title: "[Bug]: " 4 | labels: ["bug"] 5 | assignees: 6 | - hongzhew 7 | body: 8 | - type: markdown 9 | attributes: 10 | value: | 11 | 感谢对项目的支持与关注。在提出问题之前,请确保你已查看相关开发或使用文档: 12 | - https://docs.youshengyun.com/email/backend/introduction 13 | - type: checkboxes 14 | attributes: 15 | label: 这个问题是否已经存在? 16 | options: 17 | - label: 我已经搜索过现有的问题 (https://gitee.com/risesoft-y9/y9-email/issues) 18 | required: true 19 | - type: textarea 20 | attributes: 21 | label: 如何复现 22 | description: 请详细告诉我们如何复现你遇到的问题,如涉及代码,可提供一个最小代码示例,并使用反引号```附上它 23 | placeholder: | 24 | 1. ... 25 | 2. ... 26 | 3. ... 27 | validations: 28 | required: true 29 | - type: textarea 30 | attributes: 31 | label: 预期结果 32 | description: 请告诉我们你预期会发生什么。 33 | validations: 34 | required: true 35 | - type: textarea 36 | attributes: 37 | label: 实际结果 38 | description: 请告诉我们实际发生了什么。 39 | validations: 40 | required: true 41 | - type: textarea 42 | attributes: 43 | label: 截图或视频 44 | description: 如果可以的话,上传任何关于 bug 的截图。 45 | value: | 46 | [在这里上传图片] 47 | - type: input 48 | id: version 49 | attributes: 50 | label: 版本 51 | description: 你当前正在使用我们软件的主分支哪个版本? 52 | placeholder: 输入你当前正在使用我们软件的主分支的版本 53 | validations: 54 | required: true -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 电子邮件文档 4 | url: https://docs.youshengyun.com/email/backend/introduction 5 | about: 提供电子邮件介绍、基本组件使用和常见问题解答 -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: 功能建议 2 | description: 对本项目提出一个功能建议 3 | title: "[功能建议]: " 4 | labels: ["enhancement"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | 感谢提出功能建议,我们将仔细考虑! 10 | - type: textarea 11 | id: related-problem 12 | attributes: 13 | label: 你的功能建议是否和某个问题相关? 14 | description: 清晰并简洁地描述问题是什么,例如,当我...时,我总是感到困扰。 15 | validations: 16 | required: false 17 | - type: textarea 18 | id: desired-solution 19 | attributes: 20 | label: 你希望看到什么解决方案? 21 | description: 清晰并简洁地描述你希望发生的事情。 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: alternatives 26 | attributes: 27 | label: 你考虑过哪些替代方案? 28 | description: 清晰并简洁地描述你考虑过的任何替代解决方案或功能。 29 | validations: 30 | required: false 31 | - type: textarea 32 | id: additional-context 33 | attributes: 34 | label: 你有其他上下文或截图吗? 35 | description: 在此处添加有关功能请求的任何其他上下文或截图。 36 | validations: 37 | required: false 38 | - type: checkboxes 39 | attributes: 40 | label: 意向参与贡献 41 | options: 42 | - label: 我有意向参与具体功能的开发实现并将代码贡献回到上游社区 43 | required: false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build and Release Folders 2 | target/ 3 | 4 | # Eclipse 5 | .settings/ 6 | *.classpath 7 | *.project 8 | *.factorypath 9 | 10 | # IntelliJ IDEA 11 | .idea 12 | *.iml 13 | 14 | # vscode 15 | .vscode 16 | 17 | # JRebel 18 | rebel.xml 19 | 20 | # macOS 21 | .DS_Store 22 | 23 | # svn 24 | .svn/ 25 | 26 | # vue 27 | node_modules/ 28 | 29 | .flattened-pom.xml 30 | 31 | vue/y9vue-webmail/webmail/ -------------------------------------------------------------------------------- /risenet-y9boot-api-feignclient-webmail/lombok.config: -------------------------------------------------------------------------------- 1 | lombok.log.fieldName=LOGGER 2 | lombok.log.fieldIsStatic=true 3 | 4 | lombok.toString.doNotUseGetters=true 5 | lombok.toString.callSuper=call 6 | 7 | lombok.equalsAndHashCode.doNotUseGetters=true 8 | lombok.equalsAndHashCode.callSuper=call 9 | 10 | lombok.addLombokGeneratedAnnotation=true 11 | 12 | config.stopBubbling=true 13 | -------------------------------------------------------------------------------- /risenet-y9boot-api-feignclient-webmail/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 4.0.0 6 | 7 | net.risesoft 8 | y9-email 9 | ${revision} 10 | 11 | 12 | risenet-y9boot-api-feignclient-webmail 13 | ${revision} 14 | jar 15 | risenet-y9boot-api-feignclient-webmail 16 | RiseSoft/Email feignclient api 17 | https://gitee.com/risesoft-y9/y9-email 18 | 19 | 20 | 21 | 22 | 23 | ${gitee.url} 24 | ${gitee.connection} 25 | ${gitee.developerConnection} 26 | 27 | 28 | 29 | 30 | net.risesoft 31 | risenet-y9boot-starter-openfeign 32 | ${project.version} 33 | 34 | 35 | 36 | net.risesoft 37 | risenet-y9boot-api-interface-webmail 38 | ${project.version} 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /risenet-y9boot-api-feignclient-webmail/src/main/java/y9/client/rest/webmail/StandardEmailApiClient.java: -------------------------------------------------------------------------------- 1 | package y9.client.rest.webmail; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | 5 | import net.risesoft.api.webmail.StandardEmailApi; 6 | 7 | /** 8 | * 标准电子邮件 (webmail) 9 | * 10 | */ 11 | 12 | @FeignClient(contextId = "StandardEmail4ApiClient", name = "${y9.service.webmail.name:webmail}", 13 | url = "${y9.service.webmail.directUrl:}", path = "/${y9.service.webmail.name:webmail}/services/rest/standardEmail") 14 | public interface StandardEmailApiClient extends StandardEmailApi { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /risenet-y9boot-api-interface-webmail/lombok.config: -------------------------------------------------------------------------------- 1 | lombok.log.fieldName=LOGGER 2 | lombok.log.fieldIsStatic=true 3 | 4 | lombok.toString.doNotUseGetters=true 5 | lombok.toString.callSuper=call 6 | 7 | lombok.equalsAndHashCode.doNotUseGetters=true 8 | lombok.equalsAndHashCode.callSuper=call 9 | 10 | lombok.addLombokGeneratedAnnotation=true 11 | 12 | config.stopBubbling=true 13 | -------------------------------------------------------------------------------- /risenet-y9boot-api-interface-webmail/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | net.risesoft 7 | y9-email 8 | ${revision} 9 | 10 | 11 | risenet-y9boot-api-interface-webmail 12 | ${revision} 13 | jar 14 | risenet-y9boot-api-interface-webmail 15 | RiseSoft/Email interface api 16 | https://gitee.com/risesoft-y9/y9-email 17 | 18 | 19 | 20 | 21 | 22 | ${gitee.url} 23 | ${gitee.connection} 24 | ${gitee.developerConnection} 25 | 26 | 27 | 28 | 29 | net.risesoft 30 | risenet-y9boot-common-model 31 | ${project.version} 32 | 33 | 34 | 35 | org.springframework 36 | spring-web 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-validation 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /risenet-y9boot-api-interface-webmail/src/main/java/net/risesoft/api/webmail/StandardEmailApi.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.api.webmail; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.http.MediaType; 6 | import org.springframework.web.bind.annotation.PostMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.RequestPart; 9 | import org.springframework.web.multipart.MultipartFile; 10 | 11 | import net.risesoft.pojo.Y9Result; 12 | 13 | /** 14 | * 标准电子邮件 (webmail) 15 | */ 16 | public interface StandardEmailApi { 17 | 18 | /** 19 | * 发送标准电子邮件 20 | * 21 | * @param userId 发件人Id 22 | * @param tenantId 租户id 23 | * @param subject 邮件主题 24 | * @param content 邮件内容 25 | * @param fromEmail 发件人 (可不填,默认当前userId的email) 26 | * @param toEmail 收件人 27 | * @param file 邮件附件 28 | * @return {@code Y9Result} 29 | */ 30 | @PostMapping(value = "/send", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) 31 | Y9Result send(@RequestParam("userId") String userId, @RequestParam("tenantId") String tenantId, 32 | @RequestParam("subject") String subject, @RequestParam("content") String content, 33 | @RequestParam(value = "fromEmail", required = false) String fromEmail, 34 | @RequestParam("toEmail") List toEmail, @RequestPart("file") MultipartFile file); 35 | } 36 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/lombok.config: -------------------------------------------------------------------------------- 1 | lombok.log.fieldName=LOGGER 2 | lombok.log.fieldIsStatic=true 3 | 4 | lombok.toString.doNotUseGetters=true 5 | lombok.toString.callSuper=call 6 | 7 | lombok.equalsAndHashCode.doNotUseGetters=true 8 | lombok.equalsAndHashCode.callSuper=call 9 | 10 | lombok.addLombokGeneratedAnnotation=true 11 | 12 | config.stopBubbling=true 13 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/config/EmailConfiguration.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.config; 2 | 3 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 4 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | import net.risesoft.filter.EmailAddressFilter; 10 | import net.risesoft.y9.configuration.Y9Properties; 11 | import net.risesoft.y9.configuration.app.y9webmail.Y9WebMailProperties; 12 | 13 | @Configuration 14 | @EnableConfigurationProperties({Y9Properties.class, Y9WebMailProperties.class}) 15 | public class EmailConfiguration implements WebMvcConfigurer { 16 | 17 | @Bean 18 | public FilterRegistrationBean checkUserLoginFilter() { 19 | FilterRegistrationBean filterBean = new FilterRegistrationBean<>(); 20 | filterBean.setFilter(new EmailAddressFilter()); 21 | filterBean.setAsyncSupported(false); 22 | filterBean.setOrder(50); 23 | filterBean.addUrlPatterns("/*"); 24 | return filterBean; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/controller/JamesUserController.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.controller; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import lombok.RequiredArgsConstructor; 11 | 12 | import net.risesoft.james.service.JamesUserService; 13 | import net.risesoft.pojo.Y9Result; 14 | 15 | @RestController(value = "standardJamesUserController") 16 | @RequestMapping(value = "/api/standard/jamesUser") 17 | @RequiredArgsConstructor 18 | public class JamesUserController { 19 | 20 | private final JamesUserService jamesUserService; 21 | 22 | /** 23 | * 根据组织架构id获取下面所有人的邮箱地址 24 | * 25 | * @param orgUnitIdList 格式 orgType:orgUnitId 26 | * @return {@code Y9Result>} 27 | */ 28 | @GetMapping(value = "/addressList") 29 | public Y9Result> 30 | getEmailAddressListByOrgUnitId(@RequestParam(name = "orgUnitIds") List orgUnitIdList) { 31 | List emailAddressList = jamesUserService.getEmailAddressListByOrgUnitId(orgUnitIdList); 32 | return Y9Result.success(emailAddressList); 33 | } 34 | 35 | /** 36 | * 修改密码 37 | * 38 | * @param id 人员id 39 | * @param plainText 密码 40 | * @return {@code Y9Result} 41 | */ 42 | @RequestMapping(value = "/modifyPassWord") 43 | public Y9Result modifyPassWord(String id, String plainText) { 44 | jamesUserService.modifyPassword(id, plainText); 45 | return Y9Result.success(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/controller/dto/EmailAttachmentDTO.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.controller.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @NoArgsConstructor 10 | public class EmailAttachmentDTO implements Serializable { 11 | 12 | private static final long serialVersionUID = 8259583975872573080L; 13 | 14 | /** 15 | * y9文件存储名称 16 | */ 17 | private String fileName; 18 | 19 | /** 20 | * 展示的文件大小 K M G 21 | */ 22 | private String displaySize; 23 | 24 | /** 25 | * 文件扩展名 26 | */ 27 | private String fileExt; 28 | 29 | private String md5; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/controller/dto/EmailContactDTO.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.controller.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @NoArgsConstructor 10 | public class EmailContactDTO implements Serializable { 11 | private static final long serialVersionUID = 8222438278258649120L; 12 | 13 | // 地址 14 | private String contactPerson; 15 | 16 | // 接收人id 17 | private String contactPersonId; 18 | 19 | // 接收人姓名 20 | private String contactPersonName; 21 | 22 | /** 23 | * 接收人头像(仅包含.@youshengyun.com的) 24 | */ 25 | private String contactPersonAvator; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/controller/dto/EmailDTO.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.controller.dto; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | import com.fasterxml.jackson.annotation.JsonFormat; 8 | 9 | import lombok.Data; 10 | import lombok.NoArgsConstructor; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | public class EmailDTO implements Serializable { 15 | 16 | private static final long serialVersionUID = -3786840646717751241L; 17 | 18 | private String folder; 19 | 20 | /** 21 | * 邮件的唯一id 22 | */ 23 | private String messageId; 24 | 25 | private String replyMessageId; 26 | 27 | private String forwardMessageId; 28 | 29 | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 30 | private Date sendTime; 31 | 32 | /** 33 | * 发件人 34 | */ 35 | private String from; 36 | 37 | /** 38 | * 邮件主题 39 | */ 40 | private String subject; 41 | 42 | /** 43 | * 邮件正文纯文本 44 | */ 45 | private String text; 46 | 47 | /** 48 | * 邮件正文富文本 49 | */ 50 | private String richText; 51 | 52 | /** 是否星标 */ 53 | private boolean flagged; 54 | 55 | /** 56 | * 是否为分开发送 57 | */ 58 | private boolean separated; 59 | 60 | private List toEmailAddressList; 61 | private List ccEmailAddressList; 62 | private List bccEmailAddressList; 63 | 64 | private List emailAttachmentDTOList; 65 | 66 | public enum Type { 67 | NORMAL(1), REPLY(2), FORWARD(3); 68 | 69 | Integer value; 70 | 71 | Type() { 72 | 73 | } 74 | 75 | Type(Integer value) { 76 | this.value = value; 77 | } 78 | 79 | public Integer getValue() { 80 | return value; 81 | } 82 | 83 | public void setValue(Integer value) { 84 | this.value = value; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/controller/dto/EmailDetailDTO.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.controller.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * 电子邮件详情dto 10 | * 11 | * @author shidaobang 12 | * @date 2023/04/27 13 | */ 14 | @Data 15 | @NoArgsConstructor 16 | public class EmailDetailDTO extends EmailDTO implements Serializable { 17 | private static final long serialVersionUID = 8222438278258649119L; 18 | 19 | /** 20 | * IMAP UID,在一个账户中是唯一的 21 | */ 22 | private Long uid; 23 | 24 | /** 25 | * 上一封邮件的 uid,用于邮件详情页中跳转 26 | */ 27 | private Long previousUid; 28 | 29 | /** 30 | * 下一封邮件的 uid,用于邮件详情页中跳转 31 | */ 32 | private Long nextUid; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/controller/dto/EmailFolderDTO.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.controller.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @NoArgsConstructor 10 | public class EmailFolderDTO implements Serializable { 11 | 12 | private static final long serialVersionUID = -157039089680216641L; 13 | 14 | /** 15 | * 主键id 16 | */ 17 | private Integer id; 18 | 19 | /** 20 | * 文件夹名称 21 | */ 22 | private String name; 23 | 24 | /** 25 | * 文件夹全名(子文件夹会包含父文件夹名,例如:MyFolder.test) 26 | */ 27 | private String fullName; 28 | 29 | /** 30 | * 用于展示的文件夹名 31 | */ 32 | private String title; 33 | 34 | private Integer messageCount; 35 | 36 | public EmailFolderDTO(String name, String fullName, String title) { 37 | this.name = name; 38 | this.fullName = fullName; 39 | this.title = title; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/controller/dto/EmailSearchDTO.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.controller.dto; 2 | 3 | import java.util.Date; 4 | 5 | import org.springframework.format.annotation.DateTimeFormat; 6 | 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Data 11 | @NoArgsConstructor 12 | public class EmailSearchDTO { 13 | 14 | /** 文件夹 */ 15 | private String folder; 16 | 17 | /** 主题 */ 18 | private String subject; 19 | 20 | /** 正文 */ 21 | private String text; 22 | 23 | /** 发件人 */ 24 | private String from; 25 | 26 | /** 收件人 */ 27 | private String to; 28 | 29 | /** 开始时间 */ 30 | @DateTimeFormat(pattern = "yyyy-MM-dd") 31 | private Date startDate; 32 | 33 | /** 开始时间 */ 34 | @DateTimeFormat(pattern = "yyyy-MM-dd") 35 | private Date endDate; 36 | 37 | /** 是否有附件 */ 38 | private Boolean attachment; 39 | 40 | /** 是否已读 */ 41 | private Boolean read; 42 | 43 | /** 是否星标 */ 44 | private Boolean flagged; 45 | 46 | /** 分页 */ 47 | private Integer page; 48 | 49 | private Integer size; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/controller/dto/ToDTO.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.controller.dto; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | @Data 7 | @NoArgsConstructor 8 | public class ToDTO { 9 | /** 10 | * 收件人(仅包含.@youshengyun.com的发送人) 11 | */ 12 | private String to; 13 | 14 | /** 15 | * 收件人姓名(仅包含.@youshengyun.com的发送人) 16 | */ 17 | private String toName; 18 | 19 | /** 20 | * 收件人头像(仅包含.@youshengyun.com的发送人) 21 | */ 22 | private String toAvator; 23 | } 24 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/controller/vo/ImportEmlAttchMentVO.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.controller.vo; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class ImportEmlAttchMentVO { 7 | /** 主键id */ 8 | private String id; 9 | 10 | /** 历史邮件ID */ 11 | private String importEmlId; 12 | 13 | /** 附件名称 */ 14 | private String fileName; 15 | 16 | /** 文件大小 */ 17 | private String fileSize; 18 | 19 | /** 下载路径 */ 20 | private String url; 21 | 22 | /** 文件服务器存储路径 */ 23 | private String fileStoreId; 24 | 25 | /** 文件类型 */ 26 | private String fileExt; 27 | } 28 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/controller/vo/ImportEmlVO.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.controller.vo; 2 | 3 | import java.util.List; 4 | 5 | import lombok.Data; 6 | 7 | @Data 8 | public class ImportEmlVO { 9 | 10 | /** 主键id */ 11 | private String id; 12 | /** 人员ID */ 13 | private String personId; 14 | /** 15 | * 消息ID 16 | */ 17 | private String messageId; 18 | /** 19 | * 邮件主题 20 | */ 21 | private String subject; 22 | /** 23 | * 纯文本邮件内容 24 | */ 25 | private String textContent; 26 | /** 27 | * 富文本邮件内容 28 | */ 29 | private String htmlContent; 30 | /** 31 | * 发件人 32 | */ 33 | private String from; 34 | /** 35 | * 收件人 36 | */ 37 | private String to; 38 | /** 39 | * 抄送人 40 | */ 41 | private String cc; 42 | /** 43 | * 密送人 44 | */ 45 | private String bcc; 46 | /** 47 | * 邮件时间 48 | */ 49 | private String dateTime; 50 | 51 | /** 是否有附件 */ 52 | private Boolean existAttchMent; 53 | 54 | /** 附件列表 */ 55 | private List attchMentsList; 56 | 57 | /** 下一封 */ 58 | private String nextUid; 59 | 60 | /** 上一封 */ 61 | private String previousUid; 62 | } 63 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/filter/EmailAddressFilter.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.filter; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.Filter; 6 | import javax.servlet.FilterChain; 7 | import javax.servlet.FilterConfig; 8 | import javax.servlet.ServletException; 9 | import javax.servlet.ServletRequest; 10 | import javax.servlet.ServletResponse; 11 | 12 | import org.apache.commons.lang3.StringUtils; 13 | 14 | import net.risesoft.james.service.JamesUserService; 15 | import net.risesoft.model.user.UserInfo; 16 | import net.risesoft.support.EmailThreadLocalHolder; 17 | import net.risesoft.y9.Y9Context; 18 | import net.risesoft.y9.Y9LoginUserHolder; 19 | 20 | /** 21 | * 查找当前用户关联的邮箱并设值到 EmailThreadLocalHolder 中 22 | * 23 | * @author shidaobang 24 | * @date 2023/05/08 25 | */ 26 | public class EmailAddressFilter implements Filter { 27 | 28 | @Override 29 | public void destroy() {} 30 | 31 | @Override 32 | public void init(FilterConfig filterConfig) throws ServletException {} 33 | 34 | @Override 35 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 36 | throws IOException, ServletException { 37 | try { 38 | UserInfo userInfo = Y9LoginUserHolder.getUserInfo(); 39 | if (userInfo != null) { 40 | JamesUserService jamesUserService = Y9Context.getBean(JamesUserService.class); 41 | String emailAddress = jamesUserService.getEmailAddressByPersonId(userInfo.getPersonId()); 42 | if (StringUtils.isNotBlank(emailAddress)) { 43 | EmailThreadLocalHolder.setEmailAddress(emailAddress); 44 | } else { 45 | // 当前用户没有注册邮箱,直接注册 46 | jamesUserService.add(userInfo.getPersonId(), userInfo.getLoginName()); 47 | } 48 | } 49 | chain.doFilter(request, response); 50 | } finally { 51 | Y9LoginUserHolder.clear(); 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/entity/ImportEmlAttchMents.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.Id; 8 | import javax.persistence.Table; 9 | 10 | import org.hibernate.annotations.Comment; 11 | 12 | import lombok.Data; 13 | import lombok.NoArgsConstructor; 14 | 15 | @Data 16 | @NoArgsConstructor 17 | @Entity 18 | @Table(name = "JAMES_IMPORT_EML_ATTCHMENTS") 19 | @org.hibernate.annotations.Table(comment = " 历史邮件附件详细信息", appliesTo = "JAMES_IMPORT_EML_ATTCHMENTS") 20 | public class ImportEmlAttchMents implements Serializable { 21 | 22 | private static final long serialVersionUID = -1899142526752041802L; 23 | 24 | /** 主键id */ 25 | @Id 26 | @Column(name = "ID", length = 38, nullable = false) 27 | @Comment("主键id") 28 | private String id; 29 | 30 | /** 历史邮件ID */ 31 | @Column(name = "IMPORT_EML_ID", length = 38, nullable = false) 32 | @Comment("历史邮件ID") 33 | private String importEmlId; 34 | 35 | /** 附件名称 */ 36 | @Column(name = "FILE_NAME", length = 800) 37 | @Comment(value = "附件名称") 38 | private String fileName; 39 | 40 | /** 文件大小 */ 41 | @Column(name = "FILE_SIZE", length = 20) 42 | @Comment(value = "文件大小") 43 | private String fileSize; 44 | 45 | /** 下载路径 */ 46 | @Column(name = "URL", length = 800) 47 | @Comment(value = "下载路径") 48 | private String url; 49 | 50 | /** 文件服务器存储路径 */ 51 | @Column(name = "FILESTORE_ID", nullable = false, length = 100) 52 | @Comment(value = "文件服务器存储路径") 53 | private String fileStoreId; 54 | 55 | @Column(name = "FILESTORE_EXT", length = 100) 56 | @Comment(value = "文件类型") 57 | private String fileExt; 58 | } 59 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/entity/JamesUser.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.Id; 8 | import javax.persistence.Table; 9 | 10 | import org.hibernate.annotations.Comment; 11 | 12 | import lombok.Data; 13 | import lombok.NoArgsConstructor; 14 | 15 | /** 16 | * james邮件服务器定义的用户表 在这里新增了 personId plainText 两个字段, 为了能让数字底座人员能登录邮件服务器 todo 实际不应该直接修改其他系统的表 而是通过接口等其他方式操作且又能实现账号密码同步 17 | * 目前暂无较好的方法 18 | * 19 | * @author shidaobang 20 | * @date 2023/05/06 21 | */ 22 | @Data 23 | @NoArgsConstructor 24 | @Entity 25 | @Table(name = "JAMES_USER") 26 | @org.hibernate.annotations.Table(comment = "邮件用户", appliesTo = "JAMES_USER") 27 | public class JamesUser implements Serializable { 28 | 29 | private static final long serialVersionUID = 7817380951308002778L; 30 | 31 | @Id 32 | @Column(name = "USER_NAME", length = 100, nullable = false) 33 | @Comment("邮箱地址") 34 | private String emailAddress; 35 | 36 | @Column(name = "PASSWORD", length = 128, nullable = false) 37 | @Comment("密码") 38 | private String password; 39 | 40 | @Column(name = "PASSWORD_HASH_ALGORITHM", length = 100) 41 | @Comment("加密算法") 42 | private String passwordHashAlgorithm; 43 | 44 | @Column(name = "PERSON_ID", length = 100) 45 | @Comment("人员ID") 46 | private String personId; 47 | 48 | @Column(name = "PLAINTEXT", length = 50) 49 | @Comment("密码明文") 50 | private String plainText; 51 | 52 | @Column(name = "VERSION", length = 11) 53 | @Comment("版本") 54 | private Integer version; 55 | } 56 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/entity/term/MyAttachmentTerm.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.entity.term; 2 | 3 | import javax.mail.Message; 4 | import javax.mail.search.StringTerm; 5 | 6 | import lombok.extern.slf4j.Slf4j; 7 | 8 | import net.risesoft.service.impl.EmailServiceImpl; 9 | 10 | /** 11 | * description: 附件搜索 12 | * 13 | * @author lzw 14 | * @date 2023-04-25 9:25 15 | */ 16 | @Slf4j 17 | public final class MyAttachmentTerm extends StringTerm { 18 | 19 | Boolean hasAttachment = false; 20 | 21 | /** 22 | * Construct a StringTerm with the given pattern. Case will be ignored. 23 | * 24 | * @param pattern the pattern 25 | * @param hasAttachment if has Attachment 26 | */ 27 | public MyAttachmentTerm(String pattern, Boolean hasAttachment) { 28 | super(pattern); 29 | this.hasAttachment = hasAttachment; 30 | } 31 | 32 | /** 33 | * This method applies a specific match criterion to the given message and returns the result. 34 | * 35 | * @param msg The match criterion is applied on this message 36 | * @return true, it the match succeeds, false if the match fails 37 | */ 38 | @Override 39 | public boolean match(Message msg) { 40 | try { 41 | boolean isAttachment = EmailServiceImpl.isHasAttachment(msg); 42 | if (isAttachment) { 43 | return hasAttachment; 44 | } else { 45 | return !hasAttachment; 46 | } 47 | } catch (Exception e) { 48 | LOGGER.warn("exception", e); 49 | } 50 | return false; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/entity/term/MyFormTerm.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.entity.term; 2 | 3 | import javax.mail.Address; 4 | import javax.mail.Message; 5 | import javax.mail.search.AddressStringTerm; 6 | 7 | /** 8 | * description:发件人搜索 9 | * 10 | * @author lzw 11 | * @date 2023-04-24 9:14 12 | */ 13 | public final class MyFormTerm extends AddressStringTerm { 14 | 15 | private static final long serialVersionUID = -8293562089611618849L; 16 | 17 | /** 18 | * Constructor. 19 | * 20 | * @param pattern the address pattern to be compared. 21 | */ 22 | public MyFormTerm(String pattern) { 23 | super(pattern); 24 | } 25 | 26 | /** 27 | * This method applies a specific match criterion to the given message and returns the result. 28 | * 29 | * @param msg The match criterion is applied on this message 30 | * @return true, it the match succeeds, false if the match fails 31 | */ 32 | @Override 33 | public boolean match(Message msg) { 34 | Address[] from; 35 | try { 36 | from = msg.getFrom(); 37 | } catch (Exception e) { 38 | return false; 39 | } 40 | 41 | if (from == null) 42 | return false; 43 | 44 | for (Address address : from) 45 | if (super.match(address)) 46 | return true; 47 | return false; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/entity/term/MyMessageIDTerm.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.entity.term; 2 | 3 | import javax.mail.Message; 4 | import javax.mail.search.MessageIDTerm; 5 | import javax.mail.search.StringTerm; 6 | 7 | public final class MyMessageIDTerm extends StringTerm { 8 | 9 | private static final long serialVersionUID = -2121096296454694315L; 10 | 11 | /** 12 | * Constructor. 13 | * 14 | * @param msgid the msgid to search for 15 | */ 16 | public MyMessageIDTerm(String msgid) { 17 | // Note: comparison is case-insensitive 18 | super(msgid); 19 | } 20 | 21 | /** 22 | * The match method. 23 | * 24 | * @param msg the match is applied to this Message's Message-ID header 25 | * @return true if the match succeeds, otherwise false 26 | */ 27 | @Override 28 | public boolean match(Message msg) { 29 | String[] s; 30 | 31 | try { 32 | s = msg.getHeader("Message-ID"); 33 | } catch (Exception e) { 34 | return false; 35 | } 36 | 37 | if (s == null) { 38 | return false; 39 | } 40 | 41 | for (String value : s) { 42 | if (super.match(value)) { 43 | return true; 44 | } 45 | } 46 | return false; 47 | } 48 | 49 | /** 50 | * Equality comparison. 51 | */ 52 | @Override 53 | public boolean equals(Object obj) { 54 | if (!(obj instanceof MessageIDTerm)) { 55 | return false; 56 | } 57 | return super.equals(obj); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/entity/term/MyReceiverTerm.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.entity.term; 2 | 3 | import javax.mail.Address; 4 | import javax.mail.Message; 5 | import javax.mail.search.AddressStringTerm; 6 | 7 | /** 8 | * description:收件人搜索 9 | * 10 | * @author lzw 11 | * @date 2023-04-24 9:21 12 | */ 13 | public final class MyReceiverTerm extends AddressStringTerm { 14 | 15 | String pattern; 16 | 17 | /** 18 | * Construct a StringTerm with the given pattern. Case will be ignored. 19 | * 20 | * @param pattern the pattern 21 | */ 22 | public MyReceiverTerm(String pattern) { 23 | super(pattern); 24 | this.pattern = pattern; 25 | } 26 | 27 | /** 28 | * This method applies a specific match criterion to the given message and returns the result. 29 | * 30 | * @param msg The match criterion is applied on this message 31 | * @return true, it the match succeeds, false if the match fails 32 | */ 33 | @Override 34 | public boolean match(Message msg) { 35 | Address[] tos; 36 | try { 37 | tos = msg.getAllRecipients(); 38 | } catch (Exception e) { 39 | return false; 40 | } 41 | 42 | if (tos == null) { 43 | return false; 44 | } 45 | 46 | for (Address to : tos) { 47 | if (super.match(to)) { 48 | return true; 49 | } 50 | } 51 | return false; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/entity/term/MySubjectTerm.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.entity.term; 2 | 3 | import javax.mail.Message; 4 | import javax.mail.search.StringTerm; 5 | 6 | /** 7 | * description:邮件主题搜索 8 | * 9 | * @author lzw 10 | * @date 2023-04-23 17:48 11 | */ 12 | public final class MySubjectTerm extends StringTerm { 13 | 14 | /** 15 | * Construct a StringTerm with the given pattern. Case will be ignored. 16 | * 17 | * @param pattern the pattern 18 | */ 19 | 20 | public MySubjectTerm(String pattern) { 21 | super(pattern); 22 | } 23 | 24 | @Override 25 | public boolean match(Message msg) { 26 | String subj; 27 | 28 | try { 29 | subj = msg.getSubject(); 30 | } catch (Exception e) { 31 | return false; 32 | } 33 | 34 | if (subj == null) { 35 | return false; 36 | } 37 | 38 | return super.match(subj); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/repository/ImportEmlAttchMentsRepository.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.repository; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 7 | 8 | import net.risesoft.james.entity.ImportEmlAttchMents; 9 | 10 | public interface ImportEmlAttchMentsRepository 11 | extends JpaRepository, JpaSpecificationExecutor { 12 | 13 | List findByImportEmlId(String importEmlId); 14 | } 15 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/repository/ImportEmlRepository.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.repository; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | 6 | import org.springframework.data.domain.Page; 7 | import org.springframework.data.domain.Pageable; 8 | import org.springframework.data.jpa.repository.JpaRepository; 9 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 10 | 11 | import net.risesoft.james.entity.ImportEml; 12 | 13 | public interface ImportEmlRepository extends JpaRepository, JpaSpecificationExecutor { 14 | 15 | Optional findByMessageId(String messageId); 16 | 17 | Page findByPersonId(String personId, Pageable pageable); 18 | 19 | List findByPersonIdOrderByDateTimeDesc(String personId); 20 | } 21 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/repository/JamesAddressBookRepository.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.repository; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 7 | import org.springframework.data.jpa.repository.Query; 8 | 9 | import net.risesoft.james.entity.JamesAddressBook; 10 | 11 | public interface JamesAddressBookRepository 12 | extends JpaRepository, JpaSpecificationExecutor { 13 | 14 | @Query("from JamesAddressBook a where a.personId=?1 and (a.emailAddress like %?2% or a.name like %?3%) order by a.name ASC") 15 | List findByPersonIdAndEmailAddressLikeOrNameLikeOrderByNameAsc(String personId, 16 | String emailAddress, String name); 17 | 18 | List findByPersonIdOrderByNameAsc(String personId); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/repository/JamesUserRepository.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.repository; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 8 | import org.springframework.data.jpa.repository.Modifying; 9 | import org.springframework.data.jpa.repository.Query; 10 | import org.springframework.stereotype.Repository; 11 | import org.springframework.transaction.annotation.Transactional; 12 | 13 | import net.risesoft.james.entity.JamesUser; 14 | 15 | @Repository 16 | public interface JamesUserRepository extends JpaRepository, JpaSpecificationExecutor { 17 | 18 | @Query("select emailAddress from JamesUser where personId=?1") 19 | String findEmailAddressByPersonId(String personId); 20 | 21 | @Query("select emailAddress from JamesUser where personId in (?1)") 22 | List findEmailAddressByPersonIds(List ids); 23 | 24 | Optional findByPersonId(String personId); 25 | 26 | Optional findByEmailAddress(String emailAddress); 27 | 28 | @Transactional(readOnly = false) 29 | @Modifying 30 | void deleteByPersonId(String personId); 31 | } 32 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/service/ImportEmlAttchMentsService.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.service; 2 | 3 | import java.io.InputStream; 4 | import java.util.List; 5 | 6 | import net.risesoft.james.entity.ImportEmlAttchMents; 7 | 8 | public interface ImportEmlAttchMentsService { 9 | 10 | void saveAttchMents(String importEmlId, String fileName, Long fileSize, InputStream file); 11 | 12 | List listByImportEmlId(String importEmlId); 13 | 14 | ImportEmlAttchMents getById(String id); 15 | } 16 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/service/ImportEmlService.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.service; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import org.apache.james.mime4j.dom.Message; 7 | import org.springframework.data.domain.Page; 8 | 9 | import net.risesoft.james.entity.ImportEml; 10 | import net.risesoft.pojo.Y9PageQuery; 11 | 12 | public interface ImportEmlService { 13 | 14 | /** 15 | * 删除历史邮件 16 | * 17 | * @param ids 历史邮件id列表 18 | */ 19 | void delete(List ids); 20 | 21 | /** 22 | * 转发(还存在问题) 23 | * 24 | * @param id 邮件id 25 | * @throws Exception 异常 26 | */ 27 | void forward(String id) throws Exception; 28 | 29 | /** 30 | * 根据id,获取历史邮件 31 | * 32 | * @param id 历史邮件id 33 | * @return {@code ImportEml} 34 | */ 35 | ImportEml getById(String id); 36 | 37 | /** 38 | * 导入历史邮件 39 | * 40 | * @param message 邮件信息 41 | * @throws IOException IO异常 42 | */ 43 | void importEmailByEml(Message message) throws IOException; 44 | 45 | /** 46 | * 获取历史邮件id列表 47 | * 48 | * @param personId 人员id 49 | * @return {@code List} 50 | */ 51 | List listIdsByPersonId(String personId); 52 | 53 | /** 54 | * 根据人员id,获取历史邮件分页 55 | * 56 | * @param personId 人员id 57 | * @param pageQuery 分页信息 58 | * @return {@code Page} 59 | */ 60 | Page pageByPersonId(String personId, Y9PageQuery pageQuery); 61 | 62 | /** 63 | * 搜索历史邮件 64 | * 65 | * @param personId 人员id 66 | * @param subject 主题 67 | * @param htmlContent 内容 68 | * @param pageQuery 分页信息 69 | * @return {@code Page} 70 | */ 71 | Page pageSearch(String personId, String subject, String htmlContent, Y9PageQuery pageQuery); 72 | } 73 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/service/JamesAddressBookService.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.service; 2 | 3 | import java.util.List; 4 | 5 | import net.risesoft.james.entity.JamesAddressBook; 6 | 7 | public interface JamesAddressBookService { 8 | 9 | JamesAddressBook saveOrUpdate(JamesAddressBook jamesAddressBook); 10 | 11 | void delete(String id); 12 | 13 | JamesAddressBook findOne(String id); 14 | 15 | List findSearch(String search); 16 | 17 | List findAll(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/james/service/JamesUserService.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.james.service; 2 | 3 | import java.util.List; 4 | 5 | import net.risesoft.james.entity.JamesUser; 6 | import net.risesoft.model.platform.Person; 7 | 8 | public interface JamesUserService { 9 | 10 | /** 11 | * 根据id查找用户 12 | * 13 | * @param id 人员id 14 | * @return {@link JamesUser} 15 | */ 16 | JamesUser findById(String id); 17 | 18 | /** 19 | * 根据邮箱地址查找用户 20 | * 21 | * @param emailAddress 邮箱地址 22 | * @return {@link JamesUser} 23 | */ 24 | JamesUser findByEmailAddress(String emailAddress); 25 | 26 | /** 27 | * 添加 28 | * 29 | * @param personId 人员id 30 | * @param loginName 登录名称 31 | */ 32 | void add(String personId, String loginName); 33 | 34 | /** 35 | * 修改密码 36 | * 37 | * @param id 人员id 38 | * @param plainText 密码 39 | */ 40 | void modifyPassword(String id, String plainText); 41 | 42 | /** 43 | * 获取密码 44 | * 45 | * @param personId 人员id 46 | * @return String 47 | */ 48 | String getPlainTextByPersonId(String personId); 49 | 50 | /** 51 | * 被人电子邮件地址id 52 | * 53 | * @param personId 人员id 54 | * @return {@link String} 55 | */ 56 | String getEmailAddressByPersonId(String personId); 57 | 58 | List getIdByPersonIDs(List personIds); 59 | 60 | List getEmailAddressListByOrgUnitId(List orgUnitIdList); 61 | 62 | void delete(Person person); 63 | } 64 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/pojo/EmlResult.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.pojo; 2 | 3 | import java.io.InputStream; 4 | import java.util.List; 5 | 6 | import org.apache.commons.lang3.tuple.MutableTriple; 7 | import org.apache.commons.lang3.tuple.Pair; 8 | import org.apache.james.mime4j.dom.Message; 9 | 10 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 11 | import com.fasterxml.jackson.annotation.JsonInclude; 12 | import com.google.common.collect.Lists; 13 | 14 | import lombok.Data; 15 | 16 | /** 17 | * Eml文件解析数据对象 18 | * 19 | * @author chendd 20 | * @date 2023/2/11 21:40 21 | */ 22 | @Data 23 | @JsonIgnoreProperties(value = {"message"}) 24 | @JsonInclude(JsonInclude.Include.NON_NULL) 25 | public class EmlResult { 26 | 27 | /** 28 | * 原始message对象 29 | */ 30 | private Message message; 31 | 32 | /** 33 | * 消息ID 34 | */ 35 | private String messageId; 36 | 37 | /** 38 | * 邮件主题 39 | */ 40 | private String subject; 41 | 42 | /** 43 | * 纯文本邮件内容 44 | */ 45 | private String textContent; 46 | 47 | /** 48 | * 富文本邮件内容 49 | */ 50 | private String htmlContent; 51 | 52 | /** 53 | * 邮件附件 54 | */ 55 | private List> attachments = Lists.newArrayList(); 56 | 57 | /** 58 | * 发件人 59 | */ 60 | private String from; 61 | 62 | /** 63 | * 收件人 64 | */ 65 | private List> to; 66 | 67 | /** 68 | * 抄送人 69 | */ 70 | private List> cc; 71 | 72 | /** 73 | * 密送人 74 | */ 75 | private List> bcc; 76 | 77 | /** 78 | * 邮件时间 79 | */ 80 | private String dateTime; 81 | 82 | } 83 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/service/EmailAttachmentService.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.service; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.mail.MessagingException; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | import org.springframework.web.multipart.MultipartFile; 10 | 11 | import net.risesoft.controller.dto.EmailAttachmentDTO; 12 | 13 | public interface EmailAttachmentService { 14 | 15 | void download(String folderName, String messageId, String name, HttpServletResponse response, 16 | HttpServletRequest request) throws IOException, MessagingException; 17 | 18 | void batchDownload(String folderName, String messageId, HttpServletRequest request, HttpServletResponse response); 19 | 20 | EmailAttachmentDTO addAttachment(String folder, String messageId, MultipartFile file) 21 | throws MessagingException, IOException; 22 | 23 | void removeAttachment(String folder, String messageId, String filename) throws MessagingException, IOException; 24 | } 25 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/service/EmailFolderService.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.service; 2 | 3 | import java.util.List; 4 | 5 | import javax.mail.MessagingException; 6 | 7 | import net.risesoft.controller.dto.EmailFolderDTO; 8 | 9 | public interface EmailFolderService { 10 | 11 | List list() throws MessagingException; 12 | 13 | List getDefaultFolderList(); 14 | 15 | void save(String originFolderName, String newFolderName); 16 | 17 | void delete(String id); 18 | } 19 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/service/EmailMessageService.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.service; 2 | 3 | import java.util.List; 4 | 5 | public interface EmailMessageService { 6 | 7 | void send(Integer messageNumber, String subject, String richText, List emailAddressList, 8 | List ccEmailAddressList, List bccEmailAddressList, List attachmentIdList) 9 | throws Exception; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/support/DefaultFolder.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.support; 2 | 3 | import java.util.Arrays; 4 | 5 | import org.apache.commons.lang3.StringUtils; 6 | 7 | public enum DefaultFolder { 8 | INBOX("INBOX", "收件箱", false), DRAFTS("Drafts", "草稿箱", false), SENT("Sent", "已发送", false), 9 | TRASH("Trash", "回收站", false), MY_FOLDER("My Folder", "我的文件夹", true); 10 | 11 | /** 12 | * 英文名称 13 | */ 14 | private final String name; 15 | /** 16 | * 中文名称 17 | */ 18 | private final String cName; 19 | 20 | private final boolean existSubFolder; 21 | 22 | DefaultFolder(String name, String cName, boolean existSubFolder) { 23 | this.name = name; 24 | this.cName = cName; 25 | this.existSubFolder = existSubFolder; 26 | } 27 | 28 | public static boolean is(String folderName) { 29 | if (StringUtils.isBlank(folderName)) { 30 | return false; 31 | } 32 | return Arrays.stream(DefaultFolder.values()).anyMatch(folder -> folderName.equals(folder.getName())); 33 | } 34 | 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | public String getcName() { 40 | return cName; 41 | } 42 | 43 | public boolean isExistSubFolder() { 44 | return existSubFolder; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/support/EmailConst.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.support; 2 | 3 | public class EmailConst { 4 | 5 | public static final String ALTERNATIVE = "alternative"; 6 | public static final String RELATED = "related"; 7 | 8 | public static final String HEADER_MESSAGE_ID = "Message-ID"; 9 | public static final String HEADER_CONTENT_ID = "Content-ID"; 10 | public static final String HEADER_ATTACHMENT_ID = "X-Attachment-Id"; 11 | public static final String HEADER_MAILER = "X-Mailer"; 12 | } 13 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/support/EmailErrorCodeEnum.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.support; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import net.risesoft.exception.ErrorCode; 6 | 7 | /** 8 | * 电子邮件错误代码枚举 9 | * 10 | * @author shidaobang 11 | * @date 2023/04/27 12 | */ 13 | @RequiredArgsConstructor 14 | public enum EmailErrorCodeEnum implements ErrorCode { 15 | EMAIL_NOT_EXIST(0, "邮件不存在"); 16 | 17 | private final int moduleErrorCode; 18 | private final String description; 19 | 20 | @Override 21 | public int systemCode() { 22 | return 13; 23 | } 24 | 25 | @Override 26 | public int moduleCode() { 27 | return 0; 28 | } 29 | 30 | @Override 31 | public int moduleErrorCode() { 32 | return this.moduleErrorCode; 33 | } 34 | 35 | @Override 36 | public int getCode() { 37 | return ErrorCode.super.formatCode(); 38 | } 39 | 40 | @Override 41 | public String getDescription() { 42 | return this.description; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/support/EmailThreadLocalHolder.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.support; 2 | 3 | import com.alibaba.ttl.TransmittableThreadLocal; 4 | 5 | public class EmailThreadLocalHolder { 6 | 7 | private static final TransmittableThreadLocal emailAddressThreadLocal = 8 | new TransmittableThreadLocal(); 9 | 10 | public static String getEmailAddress() { 11 | return emailAddressThreadLocal.get(); 12 | } 13 | 14 | public static void setEmailAddress(String emailAddress) { 15 | emailAddressThreadLocal.set(emailAddress); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/util/ConvertPinYin.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.util; 2 | 3 | import net.sourceforge.pinyin4j.PinyinHelper; 4 | import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; 5 | import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat; 6 | import net.sourceforge.pinyin4j.format.HanyuPinyinToneType; 7 | import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType; 8 | import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination; 9 | 10 | public class ConvertPinYin { 11 | 12 | /** 13 | * 讲字符串中的中文转化为拼音,其他字符不变 14 | * 15 | * @param chinese 中文 16 | * @return 汉语拼音 17 | */ 18 | public static String getPinyin(String chinese) { 19 | HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); 20 | format.setCaseType(HanyuPinyinCaseType.LOWERCASE); 21 | format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); 22 | format.setVCharType(HanyuPinyinVCharType.WITH_U_AND_COLON); 23 | 24 | char[] hanYuArr = chinese.trim().toCharArray(); 25 | StringBuilder pinYin = new StringBuilder(); 26 | try { 27 | for (char c : hanYuArr) { 28 | if (Character.toString(c).matches("[\\u4E00-\\u9FA5]+")) {// 匹配是否是汉字 29 | String[] temp = PinyinHelper.toHanyuPinyinStringArray(c, format);// 如果是多音字,返回多个拼音,这里只取第一个 30 | pinYin.append(temp[0]); 31 | } else { 32 | pinYin.append(c); 33 | } 34 | } 35 | } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) { 36 | badHanyuPinyinOutputFormatCombination.printStackTrace(); 37 | } 38 | return pinYin.toString(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/java/net/risesoft/y9/configuration/app/y9webmail/Y9WebMailProperties.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.y9.configuration.app.y9webmail; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | @Getter 9 | @Setter 10 | @ConfigurationProperties(prefix = "y9.app.webmail", ignoreInvalidFields = true, ignoreUnknownFields = true) 11 | public class Y9WebMailProperties { 12 | 13 | /** 14 | * 邮箱域名 15 | */ 16 | private String host = "youshengyun.com"; 17 | 18 | /** 19 | * imap 域名 20 | */ 21 | private String imapHost = "imap.youshengyun.com"; 22 | /** 23 | * imap 协议端口 24 | */ 25 | private Integer imapPort = 143; 26 | 27 | /** 28 | * smtp 域名 29 | */ 30 | private String smtpHost = "smtp.youshengyun.com"; 31 | 32 | /** 33 | * smtp 端口 34 | */ 35 | private Integer smtpPort = 25; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/resources/todo.md: -------------------------------------------------------------------------------- 1 | - 邮件搜索 -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/main/resources/新用户收件.eml: -------------------------------------------------------------------------------- 1 | Return-Path: 2 | MIME-Version: 1.0 3 | X-UserIsAuth: true 4 | Delivered-To: mengjuhua@youshengyun.com 5 | Received: from 119.123.240.220 (EHLO Tobins-Mac-Studio) ([119.123.240.220]) 6 | by appserver.novalocal (JAMES SMTP Server ) with ESMTPA ID -466931707 7 | for ; 8 | Wed, 12 Apr 2023 11:20:03 +0800 (CST) 9 | X-GUID: DF91E9DD-E272-84BD-E4AD-4B9604EAFE6D 10 | From: "=?utf-8?B?c2hpZGFvYmFuZw==?=" 11 | To: "=?utf-8?B?bWVuZ2p1aHVh?=" 12 | Subject: =?utf-8?B?5paw55So5oi35pS25Lu2?= 13 | Content-Type: multipart/alternative; 14 | boundary="----=_NextPart_64362362_02607960_1E4D2A54" 15 | Content-Transfer-Encoding: 8Bit 16 | Date: Wed, 12 Apr 2023 11:20:02 +0800 17 | X-Priority: 3 18 | Message-ID: 19 | X-QQ-MIME: TCMime 1.0 by Tencent 20 | X-Mailer: Foxmail_for_Mac 1.5.8.94588 21 | 22 | This is a multi-part message in MIME format. 23 | 24 | ------=_NextPart_64362362_02607960_1E4D2A54 25 | Content-Type: text/plain; 26 | charset="utf-8" 27 | Content-Transfer-Encoding: base64 28 | 29 | 30 | 31 | ------=_NextPart_64362362_02607960_1E4D2A54 32 | Content-Type: text/html; 33 | charset="utf-8" 34 | Content-Transfer-Encoding: base64 35 | 36 | PHAgc3R5bGU9ImZvbnQ6MTRweC8xLjUgTHVjaWRhIEdyYW5kZTttYXJnaW46MDsiPjxici8+ 37 | PC9wPg== 38 | 39 | ------=_NextPart_64362362_02607960_1E4D2A54-- 40 | 41 | -------------------------------------------------------------------------------- /risenet-y9boot-support-webmail/src/test/java/net/risesoft/EmlBasicTest.java: -------------------------------------------------------------------------------- 1 | package net.risesoft; 2 | 3 | import java.io.InputStream; 4 | 5 | import org.apache.james.mime4j.dom.Message; 6 | import org.junit.jupiter.api.BeforeEach; 7 | import org.junit.jupiter.api.Test; 8 | import org.mockito.InjectMocks; 9 | import org.mockito.MockitoAnnotations; 10 | 11 | import net.risesoft.james.service.impl.ImportEmlServiceImpl; 12 | 13 | /** 14 | * 基本的eml文件解析示例 15 | * 16 | * @author chendd 17 | * @date 2023/2/11 19:26 18 | */ 19 | public class EmlBasicTest { 20 | 21 | @InjectMocks 22 | private ImportEmlServiceImpl importEmlService; 23 | 24 | @Test 25 | public void importEml() { 26 | try (InputStream inputStream = EmlBasicTest.class.getResourceAsStream("/新用户收件.eml")) { 27 | Message message = Message.Builder.of(inputStream).build(); 28 | importEmlService.importEmailByEml(message); 29 | 30 | } catch (Exception e) { 31 | e.printStackTrace(); 32 | } 33 | } 34 | 35 | @BeforeEach() 36 | public void setup() { 37 | MockitoAnnotations.openMocks(this); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/lombok.config: -------------------------------------------------------------------------------- 1 | lombok.log.fieldName=LOGGER 2 | lombok.log.fieldIsStatic=true 3 | 4 | lombok.toString.doNotUseGetters=true 5 | lombok.toString.callSuper=call 6 | 7 | lombok.equalsAndHashCode.doNotUseGetters=true 8 | lombok.equalsAndHashCode.callSuper=call 9 | 10 | lombok.addLombokGeneratedAnnotation=true 11 | 12 | config.stopBubbling=true 13 | -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/src/main/java/net/risesoft/ServletInitializer.java: -------------------------------------------------------------------------------- 1 | package net.risesoft; 2 | 3 | import org.springframework.boot.builder.SpringApplicationBuilder; 4 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 5 | 6 | public class ServletInitializer extends SpringBootServletInitializer { 7 | 8 | @Override 9 | protected SpringApplicationBuilder configure(final SpringApplicationBuilder builder) { 10 | setRegisterErrorPageFilter(false); 11 | builder.sources(WebmailApplication.class); 12 | return builder; 13 | } 14 | } -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/src/main/java/net/risesoft/WebmailApplication.java: -------------------------------------------------------------------------------- 1 | package net.risesoft; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class WebmailApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(WebmailApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/src/main/java/net/risesoft/config/ListenerAsyncConfig.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.config; 2 | 3 | import java.util.concurrent.Executor; 4 | 5 | import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.scheduling.annotation.AsyncConfigurer; 8 | import org.springframework.scheduling.annotation.EnableAsync; 9 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 10 | 11 | @Configuration 12 | @EnableAsync 13 | public class ListenerAsyncConfig implements AsyncConfigurer { 14 | /** 15 | * 获取异步线程池执行对象 16 | * 17 | * @return 18 | */ 19 | @Override 20 | public Executor getAsyncExecutor() { 21 | // 使用Spring内置线程池任务对象 22 | ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); 23 | // 设置线程池参数 24 | taskExecutor.setCorePoolSize(5); 25 | taskExecutor.setMaxPoolSize(10); 26 | taskExecutor.setQueueCapacity(25); 27 | taskExecutor.initialize(); 28 | return taskExecutor; 29 | } 30 | 31 | @Override 32 | public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 33 | return null; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/src/main/java/net/risesoft/config/WebmailConfigurer.java: -------------------------------------------------------------------------------- 1 | package net.risesoft.config; 2 | 3 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.scheduling.annotation.EnableScheduling; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | import net.risesoft.y9.Y9Context; 10 | import net.risesoft.y9.configuration.Y9Properties; 11 | 12 | @Configuration 13 | @EnableScheduling 14 | @EnableConfigurationProperties(Y9Properties.class) 15 | public class WebmailConfigurer implements WebMvcConfigurer { 16 | 17 | @Bean 18 | public Y9Context y9Context() { 19 | return new Y9Context(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/src/main/resources/application-demo.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | nacos: 4 | config: 5 | enabled: true 6 | group: DEFAULT_GROUP 7 | namespace: demo 8 | server-addr: nacos:8848 9 | username: nacos 10 | password: ${NACOS_PASSWORD:111111} 11 | config: 12 | import: 13 | - optional:nacos:webmail.yml -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | nacos: 4 | config: 5 | enabled: true 6 | namespace: dev 7 | group: DEFAULT_GROUP 8 | server-addr: https://dev.youshengyun.com:443 9 | username: nacos 10 | password: ${NACOS_PASSWORD:111111} 11 | config: 12 | import: 13 | - optional:nacos:webmail.yml -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/src/main/resources/application-local.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | nacos: 4 | config: 5 | enabled: false 6 | namespace: local 7 | group: DEFAULT_GROUP 8 | server-addr: https://dev.youshengyun.com:443 9 | username: nacos 10 | password: ${NACOS_PASSWORD:111111} 11 | config: 12 | import: 13 | - optional:nacos:webmail.yml -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | nacos: 4 | config: 5 | enabled: true 6 | group: DEFAULT_GROUP 7 | namespace: vue 8 | server-addr: nacos:8848 9 | username: nacos 10 | password: ${NACOS_PASSWORD:111111} 11 | config: 12 | import: 13 | - optional:nacos:webmail.yml -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/src/main/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | nacos: 4 | config: 5 | enabled: true 6 | group: DEFAULT_GROUP 7 | namespace: test 8 | server-addr: nacos:8848 9 | username: nacos 10 | password: ${NACOS_PASSWORD:111111} 11 | config: 12 | import: 13 | - optional:nacos:webmail.yml -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | _ _ _ 2 | __ _____| |__ _ __ ___ __ _(_) | 3 | \ \ /\ / / _ \ '_ \| '_ ` _ \ / _` | | | 4 | \ V V / __/ |_) | | | | | | (_| | | | 5 | \_/\_/ \___|_.__/|_| |_| |_|\__,_|_|_| 6 | -------------------------------------------------------------------------------- /risenet-y9boot-webapp-webmail/src/main/resources/templates/signature.txt: -------------------------------------------------------------------------------- 1 |


2 |


3 |


4 |
5 |
6 |
{{personName}}({{jobName}})
7 |
电话:{{mobile}}
8 |
租户:{{tenantName}}
9 |
IP:{{ip}}
10 |
-------------------------------------------------------------------------------- /vue/y9vue-webmail/.env.development: -------------------------------------------------------------------------------- 1 | #运行环境 2 | NODE_ENV = 'development' 3 | 4 | # 工程名 5 | VUE_APP_NAME = 'webmail' 6 | # 公共资源路径 7 | VUE_APP_PUBLIC_PATH = '/webmail/' 8 | #api接口域名 9 | VUE_APP_HOST = 'https://demo-api.youshengyun.com/' 10 | # index页面 11 | VUE_APP_HOST_INDEX = 'http://localhost:7070/webmail/' 12 | # home首页 13 | VUE_APP_HOME_INDEX = 'https://demo.youshengyun.com/home/' 14 | # y9home 首页 15 | VUE_APP_CONTEXT_Y9HOME = 'https://demo.youshengyun.com/desktop/' 16 | # email接口 17 | VUE_APP_EMAIL_URL = 'https://demo-api.youshengyun.com/webmail/' 18 | 19 | # sso接口 20 | VUE_APP_SSO_DOMAINURL = 'https://demo.youshengyun.com/' 21 | # sso接口上下文 22 | VUE_APP_SSO_CONTEXT = 'sso' 23 | # sso授权码接口(必须带上主域名,方便调试,避免拼接出现问题) 24 | VUE_APP_SSO_AUTHORIZE_URL = 'https://demo.youshengyun.com/sso/oidc/authorize' 25 | # 退出URL,service的值,在这里可不带上(则由后端默认),也可带上(则由前端默认),可在退出时传入这个值给到单点登录插件 26 | VUE_APP_SSO_LOGOUT_URL = 'https://demo.youshengyun.com/sso/logout?service=http://localhost:7070/' 27 | # 单点登录客户端唯一标示 28 | VUE_APP_SSO_CLIENT_ID = 'clientid_oidc' 29 | # 单点登录客户端密钥 30 | VUE_APP_SSO_SECRET = 'secret_oidc' 31 | # sso接口的固定字段 32 | VUE_APP_SSO_GRANT_TYPE = 'authorization_code' 33 | # token 缓存到前端的key属性 34 | VUE_APP_SSO_SITETOKEN_KEY = 'y9AT' 35 | 36 | # 跨域携带cookie,单点登录插件里有这个属性配置,方便适配客户环境调试因插件的这个参数导致的跨域问题 37 | VUE_APP_CREDENTIALS = true 38 | # 记住我时间 单位:天(新版本已没有开发此功能) 39 | # VUE_APP_REMEMBER_TIME = 30 40 | # 由前端定制单点登录页面(当前由后端统一配置此页面,不建议个别工程使用,除非所有微服务工程都统一使用) 41 | # VUE_APP_APPFEATURES = '1' 42 | 43 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/.env.localEnv: -------------------------------------------------------------------------------- 1 | #运行环境 2 | NODE_ENV = 'localEnv' 3 | 4 | # 工程名 5 | VUE_APP_NAME = 'webmail' 6 | # 公共资源路径 7 | VUE_APP_PUBLIC_PATH = '/webmail/' 8 | #api接口域名 9 | VUE_APP_HOST = 'http://localhost:7056/' 10 | # index页面 11 | VUE_APP_HOST_INDEX = 'http://localhost:7070/webmail/' 12 | # home首页 13 | VUE_APP_HOME_INDEX = 'http://localhost:7055/home/' 14 | # y9home 首页 15 | VUE_APP_CONTEXT_Y9HOME = 'http://localhost:7055/desktop/' 16 | # email接口 17 | VUE_APP_EMAIL_URL = 'http://localhost:7056/webmail/' 18 | 19 | # sso接口 20 | VUE_APP_SSO_DOMAINURL = 'http://localhost:7055/' 21 | # sso接口上下文 22 | VUE_APP_SSO_CONTEXT = 'sso' 23 | # sso授权码接口(必须带上主域名,方便调试,避免拼接出现问题) 24 | VUE_APP_SSO_AUTHORIZE_URL = 'http://localhost:7055/sso/oidc/authorize' 25 | # 退出URL,service的值,在这里可不带上(则由后端默认),也可带上(则由前端默认),可在退出时传入这个值给到单点登录插件 26 | VUE_APP_SSO_LOGOUT_URL = 'http://localhost:7055/sso/logout?service=http://localhost:7070/' 27 | # 单点登录客户端唯一标示 28 | VUE_APP_SSO_CLIENT_ID = 'clientid_oidc' 29 | # 单点登录客户端密钥 30 | VUE_APP_SSO_SECRET = 'secret_oidc' 31 | # sso接口的固定字段 32 | VUE_APP_SSO_GRANT_TYPE = 'authorization_code' 33 | # token 缓存到前端的key属性 34 | VUE_APP_SSO_SITETOKEN_KEY = 'y9AT' 35 | 36 | # 跨域携带cookie,单点登录插件里有这个属性配置,方便适配客户环境调试因插件的这个参数导致的跨域问题 37 | VUE_APP_CREDENTIALS = true 38 | # 记住我时间 单位:天(新版本已没有开发此功能) 39 | # VUE_APP_REMEMBER_TIME = 30 40 | # 由前端定制单点登录页面(当前由后端统一配置此页面,不建议个别工程使用,除非所有微服务工程都统一使用) 41 | # VUE_APP_APPFEATURES = '1' -------------------------------------------------------------------------------- /vue/y9vue-webmail/.env.production: -------------------------------------------------------------------------------- 1 | #运行环境 2 | NODE_ENV = 'production' 3 | 4 | # 工程名 5 | VUE_APP_NAME = 'webmail' 6 | # 公共资源路径 7 | VUE_APP_PUBLIC_PATH = '/webmail/' 8 | #api接口域名 9 | VUE_APP_HOST = 'https://demo-api.youshengyun.com/' 10 | # index页面 11 | VUE_APP_HOST_INDEX = 'https://demo.youshengyun.com/webmail/' 12 | # home首页 13 | VUE_APP_HOME_INDEX = 'https://demo.youshengyun.com/home/' 14 | # y9home 首页 15 | VUE_APP_CONTEXT_Y9HOME = 'https://demo.youshengyun.com/desktop/' 16 | # email接口 17 | VUE_APP_EMAIL_URL = 'https://demo-api.youshengyun.com/webmail/' 18 | 19 | # sso接口 20 | VUE_APP_SSO_DOMAINURL = 'https://demo.youshengyun.com/' 21 | # sso接口上下文 22 | VUE_APP_SSO_CONTEXT = 'sso' 23 | # sso授权码接口(必须带上主域名,方便调试,避免拼接出现问题) 24 | VUE_APP_SSO_AUTHORIZE_URL = 'https://demo.youshengyun.com/sso/oidc/authorize' 25 | # 退出URL,service的值,在这里可不带上(则由后端默认),也可带上(则由前端默认),可在退出时传入这个值给到单点登录插件 26 | VUE_APP_SSO_LOGOUT_URL = 'https://demo.youshengyun.com/sso/logout?service=https://demo.youshengyun.com/' 27 | # 单点登录客户端唯一标示 28 | VUE_APP_SSO_CLIENT_ID = 'clientid_oidc' 29 | # 单点登录客户端密钥 30 | VUE_APP_SSO_SECRET = 'secret_oidc' 31 | # sso接口的固定字段 32 | VUE_APP_SSO_GRANT_TYPE = 'authorization_code' 33 | # token 缓存到前端的key属性 34 | VUE_APP_SSO_SITETOKEN_KEY = 'y9AT' 35 | 36 | # 跨域携带cookie,单点登录插件里有这个属性配置,方便适配客户环境调试因插件的这个参数导致的跨域问题 37 | VUE_APP_CREDENTIALS = true 38 | # 记住我时间 单位:天(新版本已没有开发此功能) 39 | # VUE_APP_REMEMBER_TIME = 30 40 | # 由前端定制单点登录页面(当前由后端统一配置此页面,不建议个别工程使用,除非所有微服务工程都统一使用) 41 | # VUE_APP_APPFEATURES = '1' 42 | 43 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/.eslintignore: -------------------------------------------------------------------------------- 1 | 2 | *.sh 3 | node_modules 4 | *.md 5 | *.woff 6 | *.ttf 7 | .vscode 8 | .idea 9 | dist 10 | /public 11 | .husky 12 | .local 13 | /bin 14 | Dockerfile 15 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/.prettierignore: -------------------------------------------------------------------------------- 1 | /dist/* 2 | .local 3 | .output.js 4 | /node_modules/** 5 | 6 | **/*.svg 7 | **/*.sh 8 | 9 | /public/* 10 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + Vite 2 | 3 | This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` 24 | 25 | 26 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | tabWidth: 4, 4 | useTabs: false, 5 | semi: true, // 末尾分号 6 | vueIndentScriptAndStyle: true, 7 | singleQuote: true, // 单引号 8 | quoteProps: 'as-needed', 9 | bracketSpacing: true, 10 | trailingComma: 'none', // 数组末尾逗号 11 | jsxBracketSameLine: false, 12 | jsxSingleQuote: false, 13 | arrowParens: 'always', 14 | insertPragma: false, 15 | requirePragma: false, 16 | proseWrap: 'never', 17 | htmlWhitespaceSensitivity: 'strict', 18 | endOfLine: 'lf', 19 | rangeStart: 0 20 | }; 21 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/dark/content.js: -------------------------------------------------------------------------------- 1 | tinymce.Resource.add('content/dark/content.css', "body{background-color:#222f3e;color:#fff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border=\"0\"]):not([style*=border-width]) td,table[border]:not([border=\"0\"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border=\"0\"]):not([style*=border-style]) td,table[border]:not([border=\"0\"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border=\"0\"]):not([style*=border-color]) td,table[border]:not([border=\"0\"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}") 2 | //# sourceMappingURL=content.js.map 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/dark/content.min.css: -------------------------------------------------------------------------------- 1 | body{background-color:#222f3e;color:#fff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/default/content.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 3 | line-height: 1.4; 4 | margin: 1rem; 5 | } 6 | table { 7 | border-collapse: collapse; 8 | } 9 | /* Apply a default padding if legacy cellpadding attribute is missing */ 10 | table:not([cellpadding]) th, 11 | table:not([cellpadding]) td { 12 | padding: 0.4rem; 13 | } 14 | /* Set default table styles if a table has a positive border attribute 15 | and no inline css */ 16 | table[border]:not([border="0"]):not([style*="border-width"]) th, 17 | table[border]:not([border="0"]):not([style*="border-width"]) td { 18 | border-width: 1px; 19 | } 20 | /* Set default table styles if a table has a positive border attribute 21 | and no inline css */ 22 | table[border]:not([border="0"]):not([style*="border-style"]) th, 23 | table[border]:not([border="0"]):not([style*="border-style"]) td { 24 | border-style: solid; 25 | } 26 | /* Set default table styles if a table has a positive border attribute 27 | and no inline css */ 28 | table[border]:not([border="0"]):not([style*="border-color"]) th, 29 | table[border]:not([border="0"]):not([style*="border-color"]) td { 30 | border-color: #ccc; 31 | } 32 | figure { 33 | display: table; 34 | margin: 1rem auto; 35 | } 36 | figure figcaption { 37 | color: #999; 38 | display: block; 39 | margin-top: 0.25rem; 40 | text-align: center; 41 | } 42 | hr { 43 | border-color: #ccc; 44 | border-style: solid; 45 | border-width: 1px 0 0 0; 46 | } 47 | code { 48 | background-color: #e8e8e8; 49 | border-radius: 3px; 50 | padding: 0.1rem 0.2rem; 51 | } 52 | .mce-content-body:not([dir=rtl]) blockquote { 53 | border-left: 2px solid #ccc; 54 | margin-left: 1.5rem; 55 | padding-left: 1rem; 56 | } 57 | .mce-content-body[dir=rtl] blockquote { 58 | border-right: 2px solid #ccc; 59 | margin-right: 1.5rem; 60 | padding-right: 1rem; 61 | } 62 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/default/content.js: -------------------------------------------------------------------------------- 1 | tinymce.Resource.add('content/default/content.css', "body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border=\"0\"]):not([style*=border-width]) td,table[border]:not([border=\"0\"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border=\"0\"]):not([style*=border-style]) td,table[border]:not([border=\"0\"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border=\"0\"]):not([style*=border-color]) td,table[border]:not([border=\"0\"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}") 2 | //# sourceMappingURL=content.js.map 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/default/content.min.css: -------------------------------------------------------------------------------- 1 | body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/document/content.js: -------------------------------------------------------------------------------- 1 | tinymce.Resource.add('content/document/content.css', "@media screen{html{background:#f4f4f4;min-height:100%}}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif}@media screen{body{background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.15);box-sizing:border-box;margin:1rem auto 0;max-width:820px;min-height:calc(100vh - 1rem);padding:4rem 6rem 6rem 6rem}}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border=\"0\"]):not([style*=border-width]) td,table[border]:not([border=\"0\"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border=\"0\"]):not([style*=border-style]) td,table[border]:not([border=\"0\"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border=\"0\"]):not([style*=border-color]) td,table[border]:not([border=\"0\"]):not([style*=border-color]) th{border-color:#ccc}figure figcaption{color:#999;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}") 2 | //# sourceMappingURL=content.js.map 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/document/content.min.css: -------------------------------------------------------------------------------- 1 | @media screen{html{background:#f4f4f4;min-height:100%}}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif}@media screen{body{background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.15);box-sizing:border-box;margin:1rem auto 0;max-width:820px;min-height:calc(100vh - 1rem);padding:4rem 6rem 6rem 6rem}}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure figcaption{color:#999;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/tinymce-5-dark/content.js: -------------------------------------------------------------------------------- 1 | tinymce.Resource.add('content/tinymce-5-dark/content.css', "body{background-color:#2f3742;color:#dfe0e4;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border=\"0\"]):not([style*=border-width]) td,table[border]:not([border=\"0\"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border=\"0\"]):not([style*=border-style]) td,table[border]:not([border=\"0\"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border=\"0\"]):not([style*=border-color]) td,table[border]:not([border=\"0\"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}") 2 | //# sourceMappingURL=content.js.map 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/tinymce-5-dark/content.min.css: -------------------------------------------------------------------------------- 1 | body{background-color:#2f3742;color:#dfe0e4;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/tinymce-5/content.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 3 | line-height: 1.4; 4 | margin: 1rem; 5 | } 6 | table { 7 | border-collapse: collapse; 8 | } 9 | /* Apply a default padding if legacy cellpadding attribute is missing */ 10 | table:not([cellpadding]) th, 11 | table:not([cellpadding]) td { 12 | padding: 0.4rem; 13 | } 14 | /* Set default table styles if a table has a positive border attribute 15 | and no inline css */ 16 | table[border]:not([border="0"]):not([style*="border-width"]) th, 17 | table[border]:not([border="0"]):not([style*="border-width"]) td { 18 | border-width: 1px; 19 | } 20 | /* Set default table styles if a table has a positive border attribute 21 | and no inline css */ 22 | table[border]:not([border="0"]):not([style*="border-style"]) th, 23 | table[border]:not([border="0"]):not([style*="border-style"]) td { 24 | border-style: solid; 25 | } 26 | /* Set default table styles if a table has a positive border attribute 27 | and no inline css */ 28 | table[border]:not([border="0"]):not([style*="border-color"]) th, 29 | table[border]:not([border="0"]):not([style*="border-color"]) td { 30 | border-color: #ccc; 31 | } 32 | figure { 33 | display: table; 34 | margin: 1rem auto; 35 | } 36 | figure figcaption { 37 | color: #999; 38 | display: block; 39 | margin-top: 0.25rem; 40 | text-align: center; 41 | } 42 | hr { 43 | border-color: #ccc; 44 | border-style: solid; 45 | border-width: 1px 0 0 0; 46 | } 47 | code { 48 | background-color: #e8e8e8; 49 | border-radius: 3px; 50 | padding: 0.1rem 0.2rem; 51 | } 52 | .mce-content-body:not([dir=rtl]) blockquote { 53 | border-left: 2px solid #ccc; 54 | margin-left: 1.5rem; 55 | padding-left: 1rem; 56 | } 57 | .mce-content-body[dir=rtl] blockquote { 58 | border-right: 2px solid #ccc; 59 | margin-right: 1.5rem; 60 | padding-right: 1rem; 61 | } 62 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/tinymce-5/content.js: -------------------------------------------------------------------------------- 1 | tinymce.Resource.add('content/tinymce-5/content.css', "body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border=\"0\"]):not([style*=border-width]) td,table[border]:not([border=\"0\"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border=\"0\"]):not([style*=border-style]) td,table[border]:not([border=\"0\"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border=\"0\"]):not([style*=border-color]) td,table[border]:not([border=\"0\"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}") 2 | //# sourceMappingURL=content.js.map 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/tinymce-5/content.min.css: -------------------------------------------------------------------------------- 1 | body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/writer/content.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 3 | line-height: 1.4; 4 | margin: 1rem auto; 5 | max-width: 900px; 6 | } 7 | table { 8 | border-collapse: collapse; 9 | } 10 | /* Apply a default padding if legacy cellpadding attribute is missing */ 11 | table:not([cellpadding]) th, 12 | table:not([cellpadding]) td { 13 | padding: 0.4rem; 14 | } 15 | /* Set default table styles if a table has a positive border attribute 16 | and no inline css */ 17 | table[border]:not([border="0"]):not([style*="border-width"]) th, 18 | table[border]:not([border="0"]):not([style*="border-width"]) td { 19 | border-width: 1px; 20 | } 21 | /* Set default table styles if a table has a positive border attribute 22 | and no inline css */ 23 | table[border]:not([border="0"]):not([style*="border-style"]) th, 24 | table[border]:not([border="0"]):not([style*="border-style"]) td { 25 | border-style: solid; 26 | } 27 | /* Set default table styles if a table has a positive border attribute 28 | and no inline css */ 29 | table[border]:not([border="0"]):not([style*="border-color"]) th, 30 | table[border]:not([border="0"]):not([style*="border-color"]) td { 31 | border-color: #ccc; 32 | } 33 | figure { 34 | display: table; 35 | margin: 1rem auto; 36 | } 37 | figure figcaption { 38 | color: #999; 39 | display: block; 40 | margin-top: 0.25rem; 41 | text-align: center; 42 | } 43 | hr { 44 | border-color: #ccc; 45 | border-style: solid; 46 | border-width: 1px 0 0 0; 47 | } 48 | code { 49 | background-color: #e8e8e8; 50 | border-radius: 3px; 51 | padding: 0.1rem 0.2rem; 52 | } 53 | .mce-content-body:not([dir=rtl]) blockquote { 54 | border-left: 2px solid #ccc; 55 | margin-left: 1.5rem; 56 | padding-left: 1rem; 57 | } 58 | .mce-content-body[dir=rtl] blockquote { 59 | border-right: 2px solid #ccc; 60 | margin-right: 1.5rem; 61 | padding-right: 1rem; 62 | } 63 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/writer/content.js: -------------------------------------------------------------------------------- 1 | tinymce.Resource.add('content/writer/content.css', "body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem auto;max-width:900px}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border=\"0\"]):not([style*=border-width]) td,table[border]:not([border=\"0\"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border=\"0\"]):not([style*=border-style]) td,table[border]:not([border=\"0\"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border=\"0\"]):not([style*=border-color]) td,table[border]:not([border=\"0\"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}") 2 | //# sourceMappingURL=content.js.map 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/content/writer/content.min.css: -------------------------------------------------------------------------------- 1 | body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem auto;max-width:900px}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/oxide-dark/skin.shadowdom.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll { 2 | overflow: hidden; 3 | } 4 | .tox-fullscreen { 5 | border: 0; 6 | height: 100%; 7 | margin: 0; 8 | overflow: hidden; 9 | overscroll-behavior: none; 10 | padding: 0; 11 | touch-action: pinch-zoom; 12 | width: 100%; 13 | } 14 | .tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle { 15 | display: none; 16 | } 17 | .tox.tox-tinymce.tox-fullscreen, 18 | .tox-shadowhost.tox-fullscreen { 19 | left: 0; 20 | position: fixed; 21 | top: 0; 22 | z-index: 1200; 23 | } 24 | .tox.tox-tinymce.tox-fullscreen { 25 | background-color: transparent; 26 | } 27 | .tox-fullscreen .tox.tox-tinymce-aux, 28 | .tox-fullscreen ~ .tox.tox-tinymce-aux { 29 | z-index: 1201; 30 | } 31 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/oxide-dark/skin.shadowdom.js: -------------------------------------------------------------------------------- 1 | tinymce.Resource.add('ui/dark/skin.shadowdom.css', "body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201}") 2 | //# sourceMappingURL=skin.shadowdom.js.map 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/oxide-dark/skin.shadowdom.min.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201} 2 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/oxide/skin.shadowdom.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll { 2 | overflow: hidden; 3 | } 4 | .tox-fullscreen { 5 | border: 0; 6 | height: 100%; 7 | margin: 0; 8 | overflow: hidden; 9 | overscroll-behavior: none; 10 | padding: 0; 11 | touch-action: pinch-zoom; 12 | width: 100%; 13 | } 14 | .tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle { 15 | display: none; 16 | } 17 | .tox.tox-tinymce.tox-fullscreen, 18 | .tox-shadowhost.tox-fullscreen { 19 | left: 0; 20 | position: fixed; 21 | top: 0; 22 | z-index: 1200; 23 | } 24 | .tox.tox-tinymce.tox-fullscreen { 25 | background-color: transparent; 26 | } 27 | .tox-fullscreen .tox.tox-tinymce-aux, 28 | .tox-fullscreen ~ .tox.tox-tinymce-aux { 29 | z-index: 1201; 30 | } 31 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/oxide/skin.shadowdom.js: -------------------------------------------------------------------------------- 1 | tinymce.Resource.add('ui/default/skin.shadowdom.css', "body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201}") 2 | //# sourceMappingURL=skin.shadowdom.js.map 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/oxide/skin.shadowdom.min.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201} 2 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll { 2 | overflow: hidden; 3 | } 4 | .tox-fullscreen { 5 | border: 0; 6 | height: 100%; 7 | margin: 0; 8 | overflow: hidden; 9 | overscroll-behavior: none; 10 | padding: 0; 11 | touch-action: pinch-zoom; 12 | width: 100%; 13 | } 14 | .tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle { 15 | display: none; 16 | } 17 | .tox.tox-tinymce.tox-fullscreen, 18 | .tox-shadowhost.tox-fullscreen { 19 | left: 0; 20 | position: fixed; 21 | top: 0; 22 | z-index: 1200; 23 | } 24 | .tox.tox-tinymce.tox-fullscreen { 25 | background-color: transparent; 26 | } 27 | .tox-fullscreen .tox.tox-tinymce-aux, 28 | .tox-fullscreen ~ .tox.tox-tinymce-aux { 29 | z-index: 1201; 30 | } 31 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.js: -------------------------------------------------------------------------------- 1 | tinymce.Resource.add('ui/tinymce-5-dark/skin.shadowdom.css', "body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201}") 2 | //# sourceMappingURL=skin.shadowdom.js.map 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.min.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201} 2 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/tinymce-5/skin.shadowdom.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll { 2 | overflow: hidden; 3 | } 4 | .tox-fullscreen { 5 | border: 0; 6 | height: 100%; 7 | margin: 0; 8 | overflow: hidden; 9 | overscroll-behavior: none; 10 | padding: 0; 11 | touch-action: pinch-zoom; 12 | width: 100%; 13 | } 14 | .tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle { 15 | display: none; 16 | } 17 | .tox.tox-tinymce.tox-fullscreen, 18 | .tox-shadowhost.tox-fullscreen { 19 | left: 0; 20 | position: fixed; 21 | top: 0; 22 | z-index: 1200; 23 | } 24 | .tox.tox-tinymce.tox-fullscreen { 25 | background-color: transparent; 26 | } 27 | .tox-fullscreen .tox.tox-tinymce-aux, 28 | .tox-fullscreen ~ .tox.tox-tinymce-aux { 29 | z-index: 1201; 30 | } 31 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/tinymce-5/skin.shadowdom.js: -------------------------------------------------------------------------------- 1 | tinymce.Resource.add('ui/tinymce-5/skin.shadowdom.css', "body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201}") 2 | //# sourceMappingURL=skin.shadowdom.js.map 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/tinymce/skins/ui/tinymce-5/skin.shadowdom.min.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201} 2 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/public/yun.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/public/yun.ico -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/api/email/attachment.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2021-08-31 14:32:57 4 | * @LastEditTime: 2023-02-12 20:11:54 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: \workspace-y9boot-v9.5.x-vue\y9vue-info\src\api\tpl\upload.js 8 | */ 9 | import Request from '@/api/lib/emailRequest'; 10 | 11 | const emailRequest = Request(); 12 | 13 | export const uploadFile = async (file) => { 14 | const data = new FormData(); 15 | data.append('file', file); 16 | return await emailRequest({ 17 | url: '/api/standard/emailAttachment/uploadFile', 18 | method: 'POST', 19 | cType: false, 20 | data: data 21 | }); 22 | }; 23 | 24 | /** 25 | * 上传 26 | */ 27 | export const addAttachment = async (folder, messageId, file) => { 28 | const data = new FormData(); 29 | data.append('folder', folder); 30 | data.append('messageId', messageId); 31 | data.append('file', file); 32 | 33 | return await emailRequest({ 34 | url: '/api/standard/emailAttachment', 35 | method: 'POST', 36 | cType: false, 37 | data: data 38 | }); 39 | }; 40 | 41 | export const deleteAttachment = async (folder, messageId, fileName) => { 42 | const data = new FormData(); 43 | data.append('folder', folder); 44 | data.append('messageId', messageId); 45 | data.append('fileName', fileName); 46 | 47 | return await emailRequest({ 48 | url: '/api/standard/emailAttachment/delete', 49 | method: 'POST', 50 | cType: false, 51 | data: data 52 | }); 53 | }; 54 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/api/folder/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Descripttion: 3 | * @version: 4 | * @Author: fanzhengyang 5 | * @Date: 2022-11-08 10:48:32 6 | * @LastEditors: Please set LastEditors 7 | * @LastEditTime: 2022-12-27 18:52:38 8 | */ 9 | import Request from '@/api/lib/emailRequest'; 10 | import qs from 'qs'; 11 | 12 | const folderRequest = Request(); 13 | 14 | /** 15 | * 获取文件夹列表 16 | * @param params 17 | * @returns 18 | */ 19 | export const getFolderList = async (params) => { 20 | return await folderRequest({ 21 | url: '/api/standard/emailFolder/customList', 22 | method: 'GET', 23 | cType: false, 24 | params: params 25 | }); 26 | }; 27 | 28 | /** 29 | * 获取所有文件夹列表 30 | * @returns 31 | */ 32 | export const getAllFolderList = async () => { 33 | return await folderRequest({ 34 | url: '/api/standard/emailFolder/allList', 35 | method: 'GET', 36 | cType: false 37 | }); 38 | }; 39 | 40 | /** 41 | * 保存文件夹 42 | * @param params 43 | * @returns 44 | */ 45 | export const saveFolder = async (params) => { 46 | const data = qs.stringify(params); 47 | return await folderRequest({ 48 | url: '/api/standard/emailFolder', 49 | method: 'POST', 50 | cType: false, 51 | data: data 52 | }); 53 | }; 54 | /** 55 | * 删除文件夹 56 | * @param params 57 | * @returns 58 | */ 59 | export const deleteFolder = async (params) => { 60 | const data = qs.stringify(params); 61 | return await folderRequest({ 62 | url: '/api/standard/emailFolder/delete', 63 | method: 'POST', 64 | cType: false, 65 | data: data 66 | }); 67 | }; 68 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/api/importEml/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Descripttion: 3 | * @version: 4 | * @Author: fanzhengyang 5 | * @Date: 2022-11-08 10:48:32 6 | * @LastEditors: mengjuhua 7 | * @LastEditTime: 2024-08-12 17:01:04 8 | */ 9 | import Request from '@/api/lib/emailRequest'; 10 | import qs from 'qs'; 11 | 12 | const emailRequest = Request(); 13 | 14 | /* 15 | * 带搜索条件的邮件列表 16 | */ 17 | export const searchEml = async (params) => { 18 | const data = qs.stringify(params); 19 | return await emailRequest({ 20 | url: '/api/rest/importEml/page', 21 | method: 'GET', 22 | cType: false, 23 | params: params 24 | }); 25 | }; 26 | 27 | /** 28 | * 上传 29 | */ 30 | export const importEml = async (file) => { 31 | const data = new FormData(); 32 | data.append('file', file); 33 | 34 | return await emailRequest({ 35 | url: '/api/rest/importEml/importEml', 36 | method: 'POST', 37 | cType: false, 38 | data: data 39 | }); 40 | }; 41 | 42 | /** 43 | * 邮件详情 44 | * @param id 45 | * @returns 46 | */ 47 | 48 | export const emlDetail = async (id) => { 49 | return await emailRequest({ 50 | url: '/api/rest/importEml/getById', 51 | method: 'GET', 52 | params: { id: id } 53 | }); 54 | }; 55 | 56 | /** 57 | * 批量删除各箱邮件 58 | * @param ids 59 | * @returns 60 | */ 61 | export const deleteEml = async (ids) => { 62 | const params = { 63 | ids: ids 64 | }; 65 | const data = qs.stringify(params); 66 | return await emailRequest({ 67 | url: '/api/rest/importEml/deleteEml', 68 | method: 'POST', 69 | cType: false, 70 | data: data 71 | }); 72 | }; 73 | 74 | export const getAttById = async (importEmlId) => { 75 | return await emailRequest({ 76 | url: '/api/rest/importEml/getAttById', 77 | method: 'GET', 78 | cType: false, 79 | params: { importEmlId: importEmlId } 80 | }); 81 | }; 82 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/css/nprogress.css: -------------------------------------------------------------------------------- 1 | /* Make clicks pass-through */ 2 | #nprogress { 3 | pointer-events: none; 4 | } 5 | 6 | #nprogress .bar { 7 | background: #29d; 8 | 9 | position: fixed; 10 | z-index: 1031; 11 | top: 0; 12 | left: 0; 13 | 14 | width: 100%; 15 | height: 2px; 16 | } 17 | 18 | /* Fancy blur effect */ 19 | #nprogress .peg { 20 | display: block; 21 | position: absolute; 22 | right: 0px; 23 | width: 100px; 24 | height: 100%; 25 | box-shadow: 0 0 10px #29d, 0 0 5px #29d; 26 | opacity: 1.0; 27 | 28 | -webkit-transform: rotate(3deg) translate(0px, -4px); 29 | -ms-transform: rotate(3deg) translate(0px, -4px); 30 | transform: rotate(3deg) translate(0px, -4px); 31 | } 32 | 33 | /* Remove these to get rid of the spinner */ 34 | #nprogress .spinner { 35 | display: block; 36 | position: fixed; 37 | z-index: 1031; 38 | top: 15px; 39 | right: 15px; 40 | } 41 | 42 | #nprogress .spinner-icon { 43 | width: 18px; 44 | height: 18px; 45 | box-sizing: border-box; 46 | 47 | border: solid 2px transparent; 48 | border-top-color: #29d; 49 | border-left-color: #29d; 50 | border-radius: 50%; 51 | 52 | -webkit-animation: nprogress-spinner 400ms linear infinite; 53 | animation: nprogress-spinner 400ms linear infinite; 54 | } 55 | 56 | .nprogress-custom-parent { 57 | overflow: hidden; 58 | position: relative; 59 | } 60 | 61 | .nprogress-custom-parent #nprogress .spinner, 62 | .nprogress-custom-parent #nprogress .bar { 63 | position: absolute; 64 | } 65 | 66 | @-webkit-keyframes nprogress-spinner { 67 | 0% { 68 | -webkit-transform: rotate(0deg); 69 | } 70 | 100% { 71 | -webkit-transform: rotate(360deg); 72 | } 73 | } 74 | 75 | @keyframes nprogress-spinner { 76 | 0% { 77 | transform: rotate(0deg); 78 | } 79 | 100% { 80 | transform: rotate(360deg); 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/css/variables.scss: -------------------------------------------------------------------------------- 1 | // 主窗口背景色 2 | $mainBgColor: #f0f3f4; 3 | // 左边宽度 4 | $leftSideBarWidth: 200px; 5 | // 头部高度 6 | $headerHeight: 60px; 7 | // 头部下方面包屑高度 8 | $headerBreadcrumbHeight: 34px; 9 | // 头部面包屑下tab导航高度 10 | $headerTabNavHeight: 36px -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/png/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/icons/png/cloud.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/png/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/icons/png/file.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/png/folder-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/icons/png/folder-open.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/png/metro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/icons/png/metro.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/png/node_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/icons/png/node_home.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/png/node_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/icons/png/node_system.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/png/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/icons/png/search.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/png/user_female.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/icons/png/user_female.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/png/user_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/icons/png/user_gray.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/png/user_male.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/icons/png/user_male.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/ask.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/chart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/control.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/editor.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/history.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/image-text.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/layers.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/message.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/monitoring.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/other.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/page.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/pagedetails.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/pageform.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/pagelist.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/roles.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/s-fold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/s-unfold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/set.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/tree.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/icons/svg/users.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/arrow-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/arrow-left2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/arrow-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/arrow-right2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/arrow-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/chart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/close2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/control.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/detail.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/editor.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/language-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/list.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/menu-fold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/menu-unfold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/message.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/more.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/page.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/permissions.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/pwd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/refresh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/set.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/svgo.yml: -------------------------------------------------------------------------------- 1 | # replace default config 2 | 3 | # multipass: true 4 | # full: true 5 | 6 | plugins: 7 | 8 | # - name 9 | # 10 | # or: 11 | # - name: false 12 | # - name: true 13 | # 14 | # or: 15 | # - name: 16 | # param1: 1 17 | # param2: 2 18 | 19 | - removeAttrs: 20 | attrs: 21 | - 'fill' 22 | - 'fill-rule' 23 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/iconsvg/user.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/app-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/app-icon.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/bg-smooth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/bg-smooth.jpg -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/bg.jpg -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/logo.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/meeting.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/meeting.jpg -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/menu-bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/menu-bg1.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/menu-bg10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/menu-bg10.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/menu-bg5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/menu-bg5.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/menu-bg7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/menu-bg7.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/menu-bg8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/menu-bg8.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/menu-bg9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/menu-bg9.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/todo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/todo.jpg -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/touxiang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/touxiang.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/xiangqing/file-download-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/xiangqing/file-download-line.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/xiangqing/file-excel-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/xiangqing/file-excel-line.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/xiangqing/file-pdf-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/xiangqing/file-pdf-line.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/xiangqing/file-ppt-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/xiangqing/file-ppt-line.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/xiangqing/file-text-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/xiangqing/file-text-line.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/xiangqing/file-unknow-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/xiangqing/file-unknow-line.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/xiangqing/file-word-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/xiangqing/file-word-line.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/xiangqing/image-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/xiangqing/image-line.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/xiangqing/zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/xiangqing/zip.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/youshengyunLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/youshengyunLogo.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/yun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/yun.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/assets/images/yunLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/risesoft-y9/Email/4e36f52083f6c3a9309b606fda40935a384bfbf6/vue/y9vue-webmail/src/assets/images/yunLogo.png -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/language/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2022-02-18 14:49:54 4 | * @LastEditTime: 2023-07-10 16:58:44 5 | * @LastEditors: mengjuhua 6 | * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE 7 | * @FilePath: /Vue3x/work/demoVue3/src/language/index.js 8 | */ 9 | 10 | import zh from './zh.json'; 11 | import en from './en.json'; 12 | import { createI18n } from 'vue-i18n'; 13 | // 获取本地语言 14 | const info = JSON.parse(localStorage.getItem('userSettingData')); 15 | const messages = { 16 | zh: { 17 | ...zh 18 | }, 19 | en: { 20 | ...en 21 | } 22 | }; 23 | 24 | // 用于动态功能配置 25 | const i18n = createI18n({ 26 | locale: info?.webLanguage || 'zh', 27 | // 使用 Composition API 模式,则需要将其设置为false 28 | legacy: false, 29 | // 全局注入 $t 函数 30 | globalInjection: true, 31 | messages 32 | }); 33 | 34 | export default i18n; 35 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/layouts/components/ALink/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 32 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/layouts/components/Icon.vue: -------------------------------------------------------------------------------- 1 | 8 | 11 | 36 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/layouts/components/IconSvg/index.ts: -------------------------------------------------------------------------------- 1 | import iconsvg from './index.vue'; 2 | 3 | export default iconsvg; 4 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/layouts/components/IconSvg/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 14 | 43 | 52 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/layouts/components/RightTopMessage.vue: -------------------------------------------------------------------------------- 1 | 8 | 14 | 34 | 53 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/layouts/components/search/index.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 45 | 46 | 55 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/layouts/components/useTopMenuWidth.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2022-01-13 17:34:55 4 | * @LastEditTime: 2022-01-13 17:43:25 5 | * @LastEditors: your name 6 | * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE 7 | * @FilePath: /sz- team-frontend-9.6.x/y9vue-email/src/layouts/components/useTopMenuWidth.ts 8 | */ 9 | /** 10 | * 设置 IndexLayout TopMenuWidth 11 | * @author LiQingSong 12 | */ 13 | import {ComputedRef, nextTick, onMounted, ref, Ref, watch} from 'vue'; 14 | 15 | export default function useTopMenuWidth(topNavEnable: ComputedRef | Ref) { 16 | const topMenuCon = ref(null); 17 | 18 | const topMenuWidth = ref('auto'); 19 | 20 | const setWidth = async () => { 21 | await nextTick(); 22 | if (topMenuCon.value && topNavEnable.value) { 23 | let width = 0; 24 | const child = topMenuCon.value.children; 25 | for (let index = 0, len = child.length; index < len; index++) { 26 | const element = child[index] as HTMLElement; 27 | width = width + element.offsetWidth + 0.5; 28 | } 29 | topMenuWidth.value = width + 'px'; 30 | } else { 31 | topMenuWidth.value = 'auto'; 32 | } 33 | }; 34 | 35 | watch(topNavEnable, () => { 36 | setWidth(); 37 | }); 38 | 39 | onMounted(() => { 40 | setWidth(); 41 | }); 42 | 43 | return { 44 | topMenuCon, 45 | topMenuWidth 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/router/modules/authRouter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: fanzhengyang 3 | */ 4 | 5 | const authRouter = [ 6 | { 7 | path: '/auth', 8 | redirect: '/receive', 9 | name: 'authOrg', 10 | hidden: true, 11 | meta: { 12 | title: '普通用户', 13 | icon: 'el-icon-s-custom', 14 | roles: ['user'], 15 | notShowAdmin: true 16 | } 17 | } 18 | ]; 19 | 20 | export default authRouter; 21 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/router/modules/dynamicRouter.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: fanzhengyang 3 | */ 4 | /* 5 | * @Author: fanzhengyang 6 | */ 7 | /* 8 | * @Author: fanzhengyang 9 | */ 10 | const dynamicRouter = { 11 | path: '/dynamicIndex', 12 | component: () => import('@/layouts/index.vue'), 13 | redirect: '/archived', 14 | name: 'dynamicIndex', 15 | meta: { 16 | title: '文件夹', 17 | isDynamic: true, 18 | icon: 'ri-folder-add-line' 19 | }, 20 | children: [ 21 | // { 22 | // path: "/archived", 23 | // component: () => import("@/views/dynamic/archived.vue"), 24 | // name: "archived", 25 | // meta: { title: "办件邮件", icon: "ri-archive-drawer-line" } 26 | // }, 27 | // { 28 | // path: "/spam", 29 | // component: () => import("@/views/dynamic//spam.vue"), 30 | // name: "/spam", 31 | // meta: { title: "提醒邮件", icon: "ri-indeterminate-circle-line" } 32 | // } 33 | // , 34 | // { 35 | // path: "/deleted", 36 | // component: () => import("@/views/dynamic/deleted.vue"), 37 | // name: "deleted", 38 | // meta: { title: "待办邮件", icon: "ri-delete-bin-line" } 39 | // } 40 | ] 41 | }; 42 | 43 | export default dynamicRouter; 44 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/router/modules/emailDetailRouter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: fanzhengyang 3 | */ 4 | const emailDetailRouter = { 5 | path: '/emailDetail', 6 | component: () => import('@/layouts/index.vue'), 7 | redirect: '/emailDetailInfo', 8 | name: 'emailDetail', 9 | hidden: true, 10 | meta: { 11 | title: '邮件详情', 12 | roles: ['user'] 13 | }, 14 | children: [ 15 | { 16 | path: '/emailDetailInfo', 17 | component: () => import('@/views/emailDetail/index.vue'), 18 | name: 'emailDetailInfo', 19 | hidden: true, 20 | meta: { 21 | title: '邮件详情', 22 | roles: ['user'] 23 | }, 24 | // props: true 25 | props: (route) => ({ folder: route.query.folder, uid: route.query.uid }) 26 | } 27 | ] 28 | }; 29 | 30 | export default emailDetailRouter; 31 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/router/modules/homeRouter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: hongzhew 3 | * @Date: 2022-03-31 18:01:58 4 | * @LastEditors: Please set LastEditors 5 | * @LastEditTime: 2022-11-23 16:47:18 6 | * @Description: 首页路由 7 | */ 8 | 9 | const homeRouter = { 10 | path: '/home', 11 | component: () => import('@/layouts/index.vue'), 12 | redirect: '/home', 13 | name: 'home', 14 | meta: { 15 | title: '首页', 16 | roles: ['user'] 17 | }, 18 | children: [ 19 | { 20 | path: '/home', 21 | component: () => import('@/views/home/index.vue'), 22 | name: 'homeIndex', 23 | meta: { 24 | title: '首页', 25 | icon: 'ri-home-2-line', 26 | roles: ['user'] 27 | } 28 | } 29 | ] 30 | }; 31 | 32 | export default homeRouter; 33 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/router/modules/importEmlRouter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: hongzhew 3 | * @Date: 2022-03-31 18:01:58 4 | * @LastEditors: mengjuhua 5 | * @LastEditTime: 2024-08-14 09:50:59 6 | * @Description: 菜单路由 7 | */ 8 | 9 | const importEmlRouter = [ 10 | { 11 | path: '/importEml', 12 | component: () => import('@/layouts/index.vue'), 13 | redirect: '/importEml', 14 | name: 'importEml', 15 | meta: { 16 | title: '历史邮件', 17 | roles: ['user'] 18 | }, 19 | children: [ 20 | { 21 | path: '/importEml', 22 | component: () => import('@/views/importEml/index.vue'), 23 | name: 'importEmlIndex', 24 | meta: { 25 | title: '历史邮件', 26 | icon: 'ri-mail-lock-line', 27 | roles: ['user'] 28 | } 29 | } 30 | ] 31 | }, 32 | { 33 | path: '/emlDetail', 34 | component: () => import('@/layouts/index.vue'), 35 | redirect: '/emlDetail', 36 | name: 'emlDetail', 37 | meta: { 38 | title: '历史邮件详情', 39 | roles: ['user'] 40 | }, 41 | hidden: true, 42 | children: [ 43 | { 44 | path: '/emlDetail', 45 | component: () => import('@/views/importEml/emailDetail/index.vue'), 46 | name: 'emlDetailInfo', 47 | meta: { 48 | title: '历史邮件详情', 49 | icon: 'ri-search-line', 50 | roles: ['user'] 51 | }, 52 | hidden: true, 53 | props: (route) => ({ id: route.query.id }) 54 | } 55 | ] 56 | } 57 | ]; 58 | 59 | export default importEmlRouter; 60 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/settings.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2022-01-13 17:37:14 4 | * @LastEditTime: 2022-01-17 18:35:30 5 | * @LastEditors: your name 6 | * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE 7 | * @FilePath: /sz- team-frontend-9.6.x/y9vue-email/src/settings.ts 8 | */ 9 | import { RoutesDataItem } from '@/utils/routes'; 10 | 11 | /** 12 | * 站点配置 13 | * @author LiQingSong 14 | */ 15 | export interface SettingsType { 16 | /** 17 | * 站点名称 18 | */ 19 | siteTitle: string; 20 | 21 | /** 22 | * 顶部菜单开启 23 | */ 24 | topNavEnable: boolean; 25 | 26 | /** 27 | * 头部固定开启 28 | */ 29 | headFixed: boolean; 30 | 31 | /** 32 | * tab菜单开启 33 | */ 34 | tabNavEnable: boolean; 35 | 36 | /** 37 | * 站点首页路由 38 | */ 39 | homeRouteItem: RoutesDataItem; 40 | 41 | /** 42 | * 站点本地存储Token 的 Key值 43 | */ 44 | siteTokenKey: string; 45 | 46 | /** 47 | * Ajax请求头发送Token 的 Key值 48 | */ 49 | ajaxHeadersTokenKey: string; 50 | 51 | /** 52 | * Ajax返回值不参加统一验证的api地址 53 | */ 54 | ajaxResponseNoVerifyUrl: string[]; 55 | 56 | /** 57 | * iconfont.cn 项目在线生成的 js 地址 58 | */ 59 | iconfontUrl: string[]; 60 | } 61 | 62 | const settings: SettingsType = { 63 | siteTitle: 'Y9-ADMIN-VUE', 64 | topNavEnable: true, 65 | headFixed: true, 66 | tabNavEnable: true, 67 | homeRouteItem: { 68 | icon: 'control', 69 | title: 'index-layout.menu.home.workplace', 70 | path: '/home/workplace', 71 | component: () => import('@/App.vue') 72 | }, 73 | siteTokenKey: 'y9AT', 74 | ajaxHeadersTokenKey: 'x-token', 75 | ajaxResponseNoVerifyUrl: [ 76 | '/user/login', // 用户登录 77 | '/user/info' // 获取用户信息 78 | ], 79 | iconfontUrl: [] 80 | }; 81 | 82 | export default settings; 83 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { createPinia } from 'pinia'; 2 | import { useSettingStore } from './modules/settingStore'; 3 | // init pinia 4 | const pinia = createPinia(); 5 | 6 | export function setupStore(app) { 7 | app.use(pinia); 8 | 9 | // 示例代码(持久化pinia的settingStore模块) 10 | const settingStore = useSettingStore(); 11 | // settingStore-persist-key 12 | const persistKey = 'userSettingData'; 13 | const object = localStorage.getItem(persistKey) && JSON.parse(localStorage.getItem(persistKey)); 14 | if (object) { 15 | for (const key in object) { 16 | settingStore.$patch({ 17 | [key]: object[key] 18 | }); 19 | } 20 | } 21 | settingStore.$subscribe((mutation, state) => { 22 | localStorage.setItem(persistKey, JSON.stringify(state)); 23 | }); 24 | } 25 | 26 | export default pinia; 27 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/store/modules/folderStore.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia'; 2 | import { getAllFolderList } from '@/api/folder'; 3 | import { Folder } from '@/types/global'; 4 | 5 | export const useFolderStore = defineStore('folderStore', { 6 | state: () => { 7 | const customFolders: Folder[] = []; 8 | const defaultFolders: Folder[] = []; 9 | return { 10 | customFolders, 11 | defaultFolders 12 | }; 13 | }, 14 | getters: { 15 | // 获取所有自定义文件夹 16 | getCustomFolders: (state) => { 17 | return state.customFolders; 18 | }, 19 | // 获取所有默认文件夹 20 | getDefaultFolders: (state) => { 21 | return state.defaultFolders; 22 | }, 23 | getAllFolders: (state) => { 24 | return state.defaultFolders.concat(state.customFolders); 25 | } 26 | }, 27 | actions: { 28 | async initAllFolders() { 29 | const result = await getAllFolderList(); 30 | if (result.success) { 31 | this.customFolders = []; 32 | result.data.customFolderList.map((item) => { 33 | this.customFolders.push({ name: item.name, fullName: item.fullName, title: item.title }); 34 | }); 35 | this.defaultFolders = []; 36 | result.data.defaultFolderList.map((item) => { 37 | this.defaultFolders.push({ name: item.name, fullName: item.fullName, title: item.title }); 38 | }); 39 | } 40 | } 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/store/modules/routerStore.ts: -------------------------------------------------------------------------------- 1 | import { remove } from 'lodash'; 2 | import { defineStore } from 'pinia'; 3 | 4 | export const useRouterStore = defineStore('routerStore', { 5 | state: () => { 6 | return { 7 | PermissionRoutes: [], 8 | tabs: [], 9 | activeRoute: '/index' 10 | }; 11 | }, 12 | getters: { 13 | getPermissionRoutes: (state) => { 14 | return state.PermissionRoutes; 15 | }, 16 | getTabs: (state) => { 17 | return state.tabs; 18 | }, 19 | getActiveRoute: (state) => { 20 | return state.activeRoute; 21 | } 22 | }, 23 | actions: { 24 | addTab(item) { 25 | // 当前 active路由 26 | this.activeRoute = item.path; 27 | 28 | // 检查是否存在 29 | function checkItem(it) { 30 | return it.path === item.path; 31 | } 32 | 33 | // 添加 34 | if (!this.tabs.some(checkItem)) { 35 | this.tabs.push(item); 36 | } 37 | // tabs是否超过6个 38 | }, 39 | removeTab(tabName: String, tabPosition: String) { 40 | // 位置是top时 移除时,如果有则留下一个名为首页的标签 41 | if (tabPosition === 'top' && tabName !== '首页') { 42 | this.tabs = remove(this.tabs, (item) => item.path !== tabName); 43 | } 44 | // 位置不是top时 移除时,不留任何标签 45 | if (tabPosition !== 'top') { 46 | this.tabs = remove(this.tabs, (item) => item.path !== tabName); 47 | } 48 | } 49 | } 50 | }); 51 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/theme/blue/blue.scss: -------------------------------------------------------------------------------- 1 | @forward "element-plus/theme-chalk/src/common/var.scss" with ( 2 | $colors: ( 3 | "primary": ( 4 | "base": #1e5896, 5 | ), 6 | ), 7 | $bg-color: ("":"#ffffff !default") 8 | ); 9 | 10 | // .theme-test2:root { 11 | // --primary-color: #448800; 12 | // --ddd: #55f900; 13 | // } 14 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/theme/dark/dark.scss: -------------------------------------------------------------------------------- 1 | @forward 'element-plus/theme-chalk/src/common/var.scss' with ( 2 | $colors: ( 3 | 'primary': ( 4 | 'base': #3F4561, 5 | "light-1": #212133, 6 | "light-2": #181C2F, 7 | "light-3": #ededed, 8 | "light-4": #d9dade, 9 | "light-5": #c4c6cf, 10 | "light-6": #9b9fb0, 11 | "light-7": #3f4561, 12 | "light-8": #343850, 13 | "light-9": #2a2a3f 14 | ), 15 | ), 16 | $color-white:#1e1e2d, 17 | $bg-color: ("":"#1e1e2d !default"), 18 | $text-color: ( 19 | 'primary': #ededed, 20 | 'regular': #e2e2e2, 21 | 'secondary': #cdcdcd, 22 | 'placeholder': var(--el-color-primary-light-5), 23 | ), 24 | $input:( 25 | 'text-color': var(--el-color-primary-light-5) 26 | ), 27 | $border-color:( 28 | 'base':var(--el-bg-color), 29 | 'light': #222231, 30 | 'lighter': #2D2D3B, 31 | 'extra-light': #575762, 32 | ), 33 | $menu:( 34 | 'bg-color':#1e1e2d, 35 | 'text-color':#c7c7cb, 36 | 'hover-text-color':#ededed 37 | ), 38 | ); 39 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/theme/default/default.scss: -------------------------------------------------------------------------------- 1 | /* 2 | 重写element-UI的所有基础色 3 | 颜色值必须和原有的不一样,才会加载这里的定义的基础色 4 | */ 5 | 6 | @forward 'element-plus/theme-chalk/src/common/var.scss' with ( 7 | $colors: ( 8 | 'primary': ( 9 | 'base': #586cb1, 10 | ), 11 | 'white': #ffffff, 12 | 'black': #000000, 13 | 'success': ( 14 | 'base': #67c67c, 15 | ), 16 | 'warning': ( 17 | 'base': #e6ae6a, 18 | ), 19 | 'danger': ( 20 | 'base': #f56f56, 21 | ), 22 | 'error': ( 23 | 'base': #f56f56, 24 | ), 25 | 'info': ( 26 | 'base': #909909, 27 | ), 28 | ), 29 | $text-color: ( 30 | 'primary': #555555, 31 | // 'regular': #606606, 32 | // 'secondary': #909909, 33 | // 'placeholder': #c0c040, 34 | 'disabled': #c0cccc, 35 | 'disabled-base': #bbbccc 36 | ), 37 | $bg-color: ("":"#ffffff !default"), 38 | $color-info: #ddd 39 | 40 | !default 41 | , 42 | $border-color: ( 43 | // 'light': #e4ee4e, 44 | // 'lighter': #ebeebe, 45 | // 'extra-light': #f2ff2f, 46 | // 'dark': #d4dd4d, 47 | // 'darker': #cddcdd, 48 | // 'base': #dcddcd, 49 | )) 50 | ; 51 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/theme/global-vars.scss: -------------------------------------------------------------------------------- 1 | // logo宽度 2 | $logoWidth: 34px; 3 | // 菜单宽度 4 | $leftSideBarWidth: 260px; 5 | // 头部高度 6 | $headerHeight: 60px; 7 | // 头部下方面包屑高度 8 | $headerBreadcrumbHeight: 80px; 9 | // 头部下方面包屑宽度 10 | $headerBreadcrumbWidth: 1000px; 11 | // 头部面包屑下tab导航高度 12 | $headerTabNavHeight: 36px; 13 | // Menu 14 | $menu-collapsed-width: 54px; 15 | // menu separate后的边界宽度 16 | $sidebar-separate-margin-left: 20px; 17 | //pc main-padding 18 | $main-padding: 35px; 19 | //mobile main-padding 20 | $mobile-main-padding: 15px; 21 | // 固定背景色 22 | $background-color: #eff1f7; 23 | 24 | // 滚轴适应性和样式 25 | @mixin scrollbar { 26 | ::-webkit-scrollbar { 27 | width: 6px; 28 | height: 6px; 29 | } 30 | ::-webkit-scrollbar-thumb { 31 | background: hsla(0, 0%, 100%, .2); 32 | border-radius: 3px; 33 | box-shadow: inset 0 0 5px hsla(0, 0%, 100%, .05); 34 | } 35 | ::-webkit-scrollbar-track { 36 | background: hsla(0, 0%, 100%, .15); 37 | border-radius: 3px; 38 | box-shadow: inset 0 0 5px rgba(37, 37, 37, .05); 39 | } 40 | } -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/theme/green/green.scss: -------------------------------------------------------------------------------- 1 | @forward "element-plus/theme-chalk/src/common/var.scss" with ( 2 | $colors: ( 3 | "primary": ( 4 | "base": #4e9876, 5 | ), 6 | ), 7 | $bg-color: ("":"#ffffff !default"), 8 | $color-info: #ddd 9 | 10 | !default 11 | ) 12 | ; 13 | 14 | // .theme-test2:root { 15 | // --primary-color: #448800; 16 | // --ddd: #55f900; 17 | // } 18 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/theme/red/red.scss: -------------------------------------------------------------------------------- 1 | @forward "element-plus/theme-chalk/src/common/var.scss" with ( 2 | $colors: ( 3 | "primary": ( 4 | "base": #F40002, 5 | ), 6 | ), 7 | $bg-color: ("": "#fff !default"), 8 | ); 9 | 10 | // .theme-test2:root { 11 | // --primary-color: #448800; 12 | // --ddd: #55f900; 13 | // } 14 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/types/global.ts: -------------------------------------------------------------------------------- 1 | export interface Folder { 2 | name: string; 3 | fullName: string; 4 | title: string; 5 | } 6 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/utils/data.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 全局数据 3 | */ 4 | import { useDictionaryStore } from '@/store/modules/dictionaryStore'; 5 | 6 | export const $dictionaryFunc = async (dictionaryName, interfaceName, interfaceParams) => { 7 | //请求字典表的方法 8 | return await useDictionaryStore().getDictionaryList(dictionaryName, interfaceName, interfaceParams); 9 | }; 10 | 11 | export const $dictionary = () => { 12 | //获取字典表 13 | return useDictionaryStore().$state.dictionary; 14 | }; 15 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/utils/echarts.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 按需引入echart 3 | * @Author: fuyu 4 | * @Date: 2022-06-09 17:12:30 5 | * 6 | */ 7 | 8 | // 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。 9 | import * as echarts from 'echarts/core'; 10 | 11 | // 标签自动布局,全局过渡动画等特性 12 | import {LabelLayout, UniversalTransition} from 'echarts/features'; 13 | 14 | // 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步 15 | import {CanvasRenderer} from 'echarts/renderers'; 16 | 17 | // 引入需要的图表 18 | import {BarChart, GaugeChart, LineChart, PieChart, TreeChart, TreeSeriesOption} from 'echarts/charts'; 19 | 20 | // 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component 21 | import { 22 | GridComponent, 23 | LegendComponent, 24 | PolarComponent, 25 | TooltipComponent, 26 | TooltipComponentOption 27 | } from 'echarts/components'; 28 | 29 | // 注册必须的组件 30 | echarts.use([ 31 | TooltipComponent, 32 | TreeChart, 33 | CanvasRenderer, 34 | PolarComponent, 35 | LineChart, 36 | GridComponent, 37 | LegendComponent, 38 | BarChart, 39 | UniversalTransition, 40 | PieChart, 41 | LabelLayout, 42 | GaugeChart 43 | ]); 44 | 45 | // 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型 46 | type EChartsOption = echarts.ComposeOption; 47 | 48 | export default echarts; 49 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/utils/render.vue: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/utils/time.ts: -------------------------------------------------------------------------------- 1 | export function changeTime() { 2 | const list = []; 3 | const time = new Date(); 4 | const year = time.getFullYear(); 5 | let month: any = time.getMonth() + 1; 6 | let day: any = time.getDate(); 7 | let hour: any = time.getHours(); 8 | let minutes: any = time.getMinutes(); 9 | let seconds: any = time.getSeconds(); 10 | if (month < 10) { 11 | month = `0${month}`; 12 | } 13 | if (day < 10) { 14 | day = `0${day}`; 15 | } 16 | if (hour < 10) { 17 | hour = ` 0${hour}`; 18 | } else { 19 | hour = `${hour}`; 20 | } 21 | if (minutes < 10) { 22 | minutes = `0${minutes}`; 23 | } 24 | if (seconds < 10) { 25 | seconds = `0${seconds}`; 26 | } 27 | // 年份 28 | const yearValue = `${year}-${month}-${day}`; 29 | // 时间 30 | const timeValue = `${hour}:${minutes}`; 31 | // 星期 32 | const weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']; 33 | list.splice(0, 0, yearValue, weeks[time.getDay()], timeValue); 34 | return list; 35 | } 36 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/utils/validate.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 判断是否是外链 3 | * @param {string} path 4 | * @returns {Boolean} 5 | * @author LiQingSong 6 | */ 7 | export const isExternal = (path: string): boolean => { 8 | return /^(https?:|mailto:|tel:)/.test(path); 9 | }; 10 | 11 | /** 12 | * @description 判断是否为空 13 | * @param value 14 | * @returns {boolean} 15 | */ 16 | export function isBlank(value) { 17 | return ( 18 | value === null || false || value === '' || value.trim() === '' || value.toLocaleLowerCase().trim() === 'null' 19 | ); 20 | } 21 | 22 | /** 23 | * 校验正则 24 | * @param {string} type 25 | * @param {string} value 26 | * @returns {Boolean} 27 | * @author Fuyu 28 | */ 29 | export function $validCheck(type: string, value: string, isCallbackMsg: boolean): boolean | object { 30 | let regular = ''; //正则 31 | let msg = ''; 32 | switch (type) { 33 | case 'email': //邮箱 34 | regular = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]w+)*$/; 35 | msg = '请输入正确的邮箱格式'; 36 | break; 37 | case 'phone': //11位手机号 38 | regular = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/; 39 | msg = '请输入正确的手机号码格式'; 40 | break; 41 | case 'idCard': 42 | regular = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/; 43 | msg = '请输入正确的身份证格式'; 44 | break; 45 | case 'moreThan0': 46 | regular = /^[1-9]d*$/; 47 | msg = '请输入大于0的正整数'; 48 | break; 49 | case 'url': 50 | regular = /^(http|ftp|https):\/\/[^\u4e00-\u9fa5]/; 51 | msg = '必须以http、https、ftp开头,且不能缺少url字段'; 52 | break; 53 | } 54 | 55 | if (regular) { 56 | return isCallbackMsg ? { valid: regular.test(value), msg: msg } : value ? regular.test(value) : regular; 57 | } else { 58 | return false; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/views/401/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | 32 | 67 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/src/views/404/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 18 | 19 | 50 | -------------------------------------------------------------------------------- /vue/y9vue-webmail/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "allowSyntheticDefaultImports": true, 9 | "jsx": "preserve", 10 | "baseUrl": ".", 11 | "importHelpers": true, 12 | "isolatedModules": true, 13 | "sourceMap": true, 14 | "resolveJsonModule": true, 15 | "esModuleInterop": true, 16 | "noImplicitAny": false, 17 | "lib": [ 18 | "esnext", 19 | "dom", 20 | "dom.iterable", 21 | "scripthost" 22 | ], 23 | "types": [ 24 | "vite/client", 25 | "element-plus/global" 26 | ], 27 | "paths": { 28 | "@/*": [ 29 | "src/*" 30 | ] 31 | } 32 | }, 33 | "include": [ 34 | "src/**/*.ts", 35 | "src/**/*.d.ts", 36 | "src/**/*.tsx", 37 | "src/**/*.vue", 38 | "tests/**/*.ts", 39 | "tests/**/*.tsx" 40 | ], 41 | "exclude": [ 42 | "node_modules", 43 | "dist", 44 | "**/*.js" 45 | ] 46 | } 47 | --------------------------------------------------------------------------------