mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-08-27 11:10:17 +08:00
feat: add mailbox multi delete and download (#292)
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
- worker: 增加 `FORWARD_ADDRESS_LIST` 全局邮件转发地址(等同于 `catch all`)
|
- worker: 增加 `FORWARD_ADDRESS_LIST` 全局邮件转发地址(等同于 `catch all`)
|
||||||
- UI: 多语言使用路由进行切换
|
- UI: 多语言使用路由进行切换
|
||||||
- 添加保存附件到 S3 的功能
|
- 添加保存附件到 S3 的功能
|
||||||
|
- UI: 增加收取邮件列表 `批量删除` 和 `批量下载`
|
||||||
|
|
||||||
## v0.4.6
|
## v0.4.6
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
|
"jszip": "^3.10.1",
|
||||||
"mail-parser-wasm": "^0.1.6",
|
"mail-parser-wasm": "^0.1.6",
|
||||||
"naive-ui": "^2.38.2",
|
"naive-ui": "^2.38.2",
|
||||||
"postal-mime": "^2.2.5",
|
"postal-mime": "^2.2.5",
|
||||||
|
|||||||
80
frontend/pnpm-lock.yaml
generated
80
frontend/pnpm-lock.yaml
generated
@@ -26,6 +26,9 @@ importers:
|
|||||||
axios:
|
axios:
|
||||||
specifier: ^1.7.2
|
specifier: ^1.7.2
|
||||||
version: 1.7.2
|
version: 1.7.2
|
||||||
|
jszip:
|
||||||
|
specifier: ^3.10.1
|
||||||
|
version: 3.10.1
|
||||||
mail-parser-wasm:
|
mail-parser-wasm:
|
||||||
specifier: ^0.1.6
|
specifier: ^0.1.6
|
||||||
version: 0.1.6
|
version: 0.1.6
|
||||||
@@ -1641,6 +1644,9 @@ packages:
|
|||||||
core-js-compat@3.37.1:
|
core-js-compat@3.37.1:
|
||||||
resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==}
|
resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==}
|
||||||
|
|
||||||
|
core-util-is@1.0.3:
|
||||||
|
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
|
||||||
|
|
||||||
crypto-random-string@2.0.0:
|
crypto-random-string@2.0.0:
|
||||||
resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
|
resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1969,6 +1975,9 @@ packages:
|
|||||||
idb@7.1.1:
|
idb@7.1.1:
|
||||||
resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==}
|
resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==}
|
||||||
|
|
||||||
|
immediate@3.0.6:
|
||||||
|
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
|
||||||
|
|
||||||
immer@9.0.21:
|
immer@9.0.21:
|
||||||
resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
|
resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
|
||||||
|
|
||||||
@@ -2081,6 +2090,9 @@ packages:
|
|||||||
is-weakref@1.0.2:
|
is-weakref@1.0.2:
|
||||||
resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
|
resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
|
||||||
|
|
||||||
|
isarray@1.0.0:
|
||||||
|
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
|
||||||
|
|
||||||
isarray@2.0.5:
|
isarray@2.0.5:
|
||||||
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
|
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
|
||||||
|
|
||||||
@@ -2123,10 +2135,16 @@ packages:
|
|||||||
resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==}
|
resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
jszip@3.10.1:
|
||||||
|
resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
|
||||||
|
|
||||||
leven@3.1.0:
|
leven@3.1.0:
|
||||||
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
|
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
lie@3.3.0:
|
||||||
|
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
|
||||||
|
|
||||||
local-pkg@0.5.0:
|
local-pkg@0.5.0:
|
||||||
resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==}
|
resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
@@ -2267,6 +2285,9 @@ packages:
|
|||||||
once@1.4.0:
|
once@1.4.0:
|
||||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||||
|
|
||||||
|
pako@1.0.11:
|
||||||
|
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
|
||||||
|
|
||||||
path-is-absolute@1.0.1:
|
path-is-absolute@1.0.1:
|
||||||
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -2319,6 +2340,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
|
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
process-nextick-args@2.0.1:
|
||||||
|
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
||||||
|
|
||||||
proxy-from-env@1.1.0:
|
proxy-from-env@1.1.0:
|
||||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||||
|
|
||||||
@@ -2332,6 +2356,9 @@ packages:
|
|||||||
randombytes@2.1.0:
|
randombytes@2.1.0:
|
||||||
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
|
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
|
||||||
|
|
||||||
|
readable-stream@2.3.8:
|
||||||
|
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
|
||||||
|
|
||||||
readdirp@3.6.0:
|
readdirp@3.6.0:
|
||||||
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
||||||
engines: {node: '>=8.10.0'}
|
engines: {node: '>=8.10.0'}
|
||||||
@@ -2410,6 +2437,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==}
|
resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==}
|
||||||
engines: {node: '>=0.4'}
|
engines: {node: '>=0.4'}
|
||||||
|
|
||||||
|
safe-buffer@5.1.2:
|
||||||
|
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
|
||||||
|
|
||||||
safe-buffer@5.2.1:
|
safe-buffer@5.2.1:
|
||||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||||
|
|
||||||
@@ -2448,6 +2478,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
|
resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
setimmediate@1.0.5:
|
||||||
|
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
|
||||||
|
|
||||||
side-channel@1.0.6:
|
side-channel@1.0.6:
|
||||||
resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
|
resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -2508,6 +2541,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
|
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
string_decoder@1.1.1:
|
||||||
|
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
|
||||||
|
|
||||||
stringify-object@3.3.0:
|
stringify-object@3.3.0:
|
||||||
resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==}
|
resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@@ -2680,6 +2716,9 @@ packages:
|
|||||||
uri-js@4.4.1:
|
uri-js@4.4.1:
|
||||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||||
|
|
||||||
|
util-deprecate@1.0.2:
|
||||||
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
|
|
||||||
uuid@9.0.1:
|
uuid@9.0.1:
|
||||||
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -4485,6 +4524,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.23.0
|
browserslist: 4.23.0
|
||||||
|
|
||||||
|
core-util-is@1.0.3: {}
|
||||||
|
|
||||||
crypto-random-string@2.0.0: {}
|
crypto-random-string@2.0.0: {}
|
||||||
|
|
||||||
css-render@0.15.14:
|
css-render@0.15.14:
|
||||||
@@ -4891,6 +4932,8 @@ snapshots:
|
|||||||
|
|
||||||
idb@7.1.1: {}
|
idb@7.1.1: {}
|
||||||
|
|
||||||
|
immediate@3.0.6: {}
|
||||||
|
|
||||||
immer@9.0.21: {}
|
immer@9.0.21: {}
|
||||||
|
|
||||||
inflight@1.0.6:
|
inflight@1.0.6:
|
||||||
@@ -4991,6 +5034,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
call-bind: 1.0.7
|
call-bind: 1.0.7
|
||||||
|
|
||||||
|
isarray@1.0.0: {}
|
||||||
|
|
||||||
isarray@2.0.5: {}
|
isarray@2.0.5: {}
|
||||||
|
|
||||||
jake@10.9.1:
|
jake@10.9.1:
|
||||||
@@ -5026,8 +5071,19 @@ snapshots:
|
|||||||
|
|
||||||
jsonpointer@5.0.1: {}
|
jsonpointer@5.0.1: {}
|
||||||
|
|
||||||
|
jszip@3.10.1:
|
||||||
|
dependencies:
|
||||||
|
lie: 3.3.0
|
||||||
|
pako: 1.0.11
|
||||||
|
readable-stream: 2.3.8
|
||||||
|
setimmediate: 1.0.5
|
||||||
|
|
||||||
leven@3.1.0: {}
|
leven@3.1.0: {}
|
||||||
|
|
||||||
|
lie@3.3.0:
|
||||||
|
dependencies:
|
||||||
|
immediate: 3.0.6
|
||||||
|
|
||||||
local-pkg@0.5.0:
|
local-pkg@0.5.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
mlly: 1.7.0
|
mlly: 1.7.0
|
||||||
@@ -5180,6 +5236,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
wrappy: 1.0.2
|
wrappy: 1.0.2
|
||||||
|
|
||||||
|
pako@1.0.11: {}
|
||||||
|
|
||||||
path-is-absolute@1.0.1: {}
|
path-is-absolute@1.0.1: {}
|
||||||
|
|
||||||
path-parse@1.0.7: {}
|
path-parse@1.0.7: {}
|
||||||
@@ -5218,6 +5276,8 @@ snapshots:
|
|||||||
|
|
||||||
prismjs@1.29.0: {}
|
prismjs@1.29.0: {}
|
||||||
|
|
||||||
|
process-nextick-args@2.0.1: {}
|
||||||
|
|
||||||
proxy-from-env@1.1.0: {}
|
proxy-from-env@1.1.0: {}
|
||||||
|
|
||||||
punycode@2.3.1: {}
|
punycode@2.3.1: {}
|
||||||
@@ -5228,6 +5288,16 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer: 5.2.1
|
safe-buffer: 5.2.1
|
||||||
|
|
||||||
|
readable-stream@2.3.8:
|
||||||
|
dependencies:
|
||||||
|
core-util-is: 1.0.3
|
||||||
|
inherits: 2.0.4
|
||||||
|
isarray: 1.0.0
|
||||||
|
process-nextick-args: 2.0.1
|
||||||
|
safe-buffer: 5.1.2
|
||||||
|
string_decoder: 1.1.1
|
||||||
|
util-deprecate: 1.0.2
|
||||||
|
|
||||||
readdirp@3.6.0:
|
readdirp@3.6.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
@@ -5335,6 +5405,8 @@ snapshots:
|
|||||||
has-symbols: 1.0.3
|
has-symbols: 1.0.3
|
||||||
isarray: 2.0.5
|
isarray: 2.0.5
|
||||||
|
|
||||||
|
safe-buffer@5.1.2: {}
|
||||||
|
|
||||||
safe-buffer@5.2.1: {}
|
safe-buffer@5.2.1: {}
|
||||||
|
|
||||||
safe-regex-test@1.0.3:
|
safe-regex-test@1.0.3:
|
||||||
@@ -5380,6 +5452,8 @@ snapshots:
|
|||||||
functions-have-names: 1.2.3
|
functions-have-names: 1.2.3
|
||||||
has-property-descriptors: 1.0.2
|
has-property-descriptors: 1.0.2
|
||||||
|
|
||||||
|
setimmediate@1.0.5: {}
|
||||||
|
|
||||||
side-channel@1.0.6:
|
side-channel@1.0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bind: 1.0.7
|
call-bind: 1.0.7
|
||||||
@@ -5458,6 +5532,10 @@ snapshots:
|
|||||||
define-properties: 1.2.1
|
define-properties: 1.2.1
|
||||||
es-object-atoms: 1.0.0
|
es-object-atoms: 1.0.0
|
||||||
|
|
||||||
|
string_decoder@1.1.1:
|
||||||
|
dependencies:
|
||||||
|
safe-buffer: 5.1.2
|
||||||
|
|
||||||
stringify-object@3.3.0:
|
stringify-object@3.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
get-own-enumerable-property-symbols: 3.0.2
|
get-own-enumerable-property-symbols: 3.0.2
|
||||||
@@ -5663,6 +5741,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
|
|
||||||
|
util-deprecate@1.0.2: {}
|
||||||
|
|
||||||
uuid@9.0.1: {}
|
uuid@9.0.1: {}
|
||||||
|
|
||||||
vdirs@0.1.8(vue@3.4.27(typescript@5.4.5)):
|
vdirs@0.1.8(vue@3.4.27(typescript@5.4.5)):
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isDark, mailboxSplitSize, indexTab,
|
isDark, mailboxSplitSize, indexTab, loading,
|
||||||
useIframeShowMail, sendMailModel, preferShowTextMail
|
useIframeShowMail, sendMailModel, preferShowTextMail
|
||||||
} = useGlobalState()
|
} = useGlobalState()
|
||||||
const autoRefresh = ref(false)
|
const autoRefresh = ref(false)
|
||||||
@@ -66,6 +66,12 @@ const curAttachments = ref([])
|
|||||||
const curMail = ref(null);
|
const curMail = ref(null);
|
||||||
const showTextMail = ref(preferShowTextMail.value)
|
const showTextMail = ref(preferShowTextMail.value)
|
||||||
|
|
||||||
|
const multiActionMode = ref(false)
|
||||||
|
const showMultiActionDownload = ref(false)
|
||||||
|
const showMultiActionDelete = ref(false)
|
||||||
|
const multiActionDownloadZip = ref({})
|
||||||
|
const multiActionDeleteProgress = ref({ percentage: 0, tip: '0/0' })
|
||||||
|
|
||||||
const { t } = useI18n({
|
const { t } = useI18n({
|
||||||
messages: {
|
messages: {
|
||||||
en: {
|
en: {
|
||||||
@@ -75,13 +81,17 @@ const { t } = useI18n({
|
|||||||
refresh: 'Refresh',
|
refresh: 'Refresh',
|
||||||
attachments: 'Show Attachments',
|
attachments: 'Show Attachments',
|
||||||
downloadMail: 'Download Mail',
|
downloadMail: 'Download Mail',
|
||||||
pleaseSelectMail: "Please select a mail to view.",
|
pleaseSelectMail: "Please select mail",
|
||||||
delete: 'Delete',
|
delete: 'Delete',
|
||||||
deleteMailTip: 'Are you sure you want to delete this mail?',
|
deleteMailTip: 'Are you sure you want to delete mail?',
|
||||||
reply: 'Reply',
|
reply: 'Reply',
|
||||||
showTextMail: 'Show Text Mail',
|
showTextMail: 'Show Text Mail',
|
||||||
showHtmlMail: 'Show Html Mail',
|
showHtmlMail: 'Show Html Mail',
|
||||||
saveToS3: 'Save to S3',
|
saveToS3: 'Save to S3',
|
||||||
|
multiAction: 'Multi Action',
|
||||||
|
cancelMultiAction: 'Cancel Multi Action',
|
||||||
|
selectAll: 'Select All',
|
||||||
|
unselectAll: 'Unselect All',
|
||||||
},
|
},
|
||||||
zh: {
|
zh: {
|
||||||
success: '成功',
|
success: '成功',
|
||||||
@@ -90,13 +100,17 @@ const { t } = useI18n({
|
|||||||
refresh: '刷新',
|
refresh: '刷新',
|
||||||
downloadMail: '下载邮件',
|
downloadMail: '下载邮件',
|
||||||
attachments: '查看附件',
|
attachments: '查看附件',
|
||||||
pleaseSelectMail: "请选择一封邮件查看。",
|
pleaseSelectMail: "请选择邮件",
|
||||||
delete: '删除',
|
delete: '删除',
|
||||||
deleteMailTip: '确定要删除这封邮件吗?',
|
deleteMailTip: '确定要删除邮件吗?',
|
||||||
reply: '回复',
|
reply: '回复',
|
||||||
showTextMail: '显示纯文本邮件',
|
showTextMail: '显示纯文本邮件',
|
||||||
showHtmlMail: '显示HTML邮件',
|
showHtmlMail: '显示HTML邮件',
|
||||||
saveToS3: '保存到S3',
|
saveToS3: '保存到S3',
|
||||||
|
multiAction: '多选',
|
||||||
|
cancelMultiAction: '取消多选',
|
||||||
|
selectAll: '全选',
|
||||||
|
unselectAll: '取消全选',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -134,12 +148,14 @@ const refresh = async () => {
|
|||||||
pageSize.value, (page.value - 1) * pageSize.value
|
pageSize.value, (page.value - 1) * pageSize.value
|
||||||
);
|
);
|
||||||
data.value = await Promise.all(results.map(async (item) => {
|
data.value = await Promise.all(results.map(async (item) => {
|
||||||
|
item.checked = false;
|
||||||
return await processItem(item);
|
return await processItem(item);
|
||||||
}));
|
}));
|
||||||
if (totalCount > 0) {
|
if (totalCount > 0) {
|
||||||
count.value = totalCount;
|
count.value = totalCount;
|
||||||
}
|
}
|
||||||
if (!isMobile.value && !curMail.value && data.value.length > 0) {
|
curMail.value = null;
|
||||||
|
if (!isMobile.value && data.value.length > 0) {
|
||||||
curMail.value = data.value[0];
|
curMail.value = data.value[0];
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -149,6 +165,10 @@ const refresh = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const clickRow = async (row) => {
|
const clickRow = async (row) => {
|
||||||
|
if (multiActionMode.value) {
|
||||||
|
row.checked = !row.checked;
|
||||||
|
return;
|
||||||
|
}
|
||||||
curMail.value = row;
|
curMail.value = row;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -205,6 +225,82 @@ const saveToS3Proxy = async (filename, blob) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const multiActionModeClick = (enableMulti) => {
|
||||||
|
if (enableMulti) {
|
||||||
|
data.value.forEach((item) => {
|
||||||
|
item.checked = false;
|
||||||
|
});
|
||||||
|
multiActionMode.value = true;
|
||||||
|
} else {
|
||||||
|
multiActionMode.value = false;
|
||||||
|
data.value.forEach((item) => {
|
||||||
|
item.checked = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const multiActionSelectAll = (checked) => {
|
||||||
|
data.value.forEach((item) => {
|
||||||
|
item.checked = checked;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const multiActionDeleteMail = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const selectedMails = data.value.filter((item) => item.checked);
|
||||||
|
if (selectedMails.length === 0) {
|
||||||
|
message.error(t('pleaseSelectMail'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
multiActionDeleteProgress.value = {
|
||||||
|
percentage: 0,
|
||||||
|
tip: `0/${selectedMails.length}`
|
||||||
|
};
|
||||||
|
for (const [index, mail] of selectedMails.entries()) {
|
||||||
|
await props.deleteMail(mail.id);
|
||||||
|
showMultiActionDelete.value = true;
|
||||||
|
multiActionDeleteProgress.value = {
|
||||||
|
percentage: Math.floor((index + 1) / selectedMails.length * 100),
|
||||||
|
tip: `${index + 1}/${selectedMails.length}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
message.success(t("success"));
|
||||||
|
await refresh();
|
||||||
|
} catch (error) {
|
||||||
|
message.error(error.message || "error");
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
showMultiActionDelete.value = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const multiActionDownload = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const selectedMails = data.value.filter((item) => item.checked);
|
||||||
|
if (selectedMails.length === 0) {
|
||||||
|
message.error(t('pleaseSelectMail'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const JSZipModlue = await import('jszip');
|
||||||
|
const JSZip = JSZipModlue.default;
|
||||||
|
const zip = new JSZip();
|
||||||
|
for (const mail of selectedMails) {
|
||||||
|
zip.file(`${mail.id}.eml`, mail.raw);
|
||||||
|
}
|
||||||
|
multiActionDownloadZip.value = {
|
||||||
|
url: URL.createObjectURL(await zip.generateAsync({ type: "blob" })),
|
||||||
|
filename: `mails-${new Date().toISOString().replace(/:/g, '-')}.zip`
|
||||||
|
}
|
||||||
|
showMultiActionDownload.value = true;
|
||||||
|
} catch (error) {
|
||||||
|
message.error(error.message || "error");
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await refresh();
|
await refresh();
|
||||||
});
|
});
|
||||||
@@ -216,14 +312,38 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<n-split class="left" v-if="!isMobile" direction="horizontal" :max="0.75" :min="0.25"
|
<div v-if="!isMobile" class="left">
|
||||||
:default-size="mailboxSplitSize" :on-update:size="onSpiltSizeChange">
|
<div style="margin-bottom: 10px;">
|
||||||
<template #1>
|
<n-space v-if="multiActionMode">
|
||||||
<div class="center">
|
<n-button @click="multiActionModeClick(false)" tertiary>
|
||||||
<div style="display: inline-block;">
|
{{ t('cancelMultiAction') }}
|
||||||
<n-pagination v-model:page="page" v-model:page-size="pageSize" :item-count="count" simple size="small" />
|
</n-button>
|
||||||
</div>
|
<n-button @click="multiActionSelectAll(true)" tertiary>
|
||||||
<n-switch v-model:value="autoRefresh" size="small" :round="false">
|
{{ t('selectAll') }}
|
||||||
|
</n-button>
|
||||||
|
<n-button @click="multiActionSelectAll(false)" tertiary>
|
||||||
|
{{ t('unselectAll') }}
|
||||||
|
</n-button>
|
||||||
|
<n-popconfirm v-if="enableUserDeleteEmail" @positive-click="multiActionDeleteMail">
|
||||||
|
<template #trigger>
|
||||||
|
<n-button tertiary type="error">{{ t('delete') }}</n-button>
|
||||||
|
</template>
|
||||||
|
{{ t('deleteMailTip') }}
|
||||||
|
</n-popconfirm>
|
||||||
|
<n-button @click="multiActionDownload" tertiary type="info">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon :component="CloudDownloadRound" />
|
||||||
|
</template>
|
||||||
|
{{ t('downloadMail') }}
|
||||||
|
</n-button>
|
||||||
|
</n-space>
|
||||||
|
<n-space v-else>
|
||||||
|
<n-button @click="multiActionModeClick(true)" type="primary" tertiary>
|
||||||
|
{{ t('multiAction') }}
|
||||||
|
</n-button>
|
||||||
|
<n-pagination v-model:page="page" v-model:page-size="pageSize" :item-count="count" :page-sizes="[20, 50, 100]"
|
||||||
|
show-size-picker />
|
||||||
|
<n-switch v-model:value="autoRefresh" :round="false">
|
||||||
<template #checked>
|
<template #checked>
|
||||||
{{ t('refreshAfter', { msg: autoRefreshInterval }) }}
|
{{ t('refreshAfter', { msg: autoRefreshInterval }) }}
|
||||||
</template>
|
</template>
|
||||||
@@ -231,90 +351,98 @@ onBeforeUnmount(() => {
|
|||||||
{{ t('autoRefresh') }}
|
{{ t('autoRefresh') }}
|
||||||
</template>
|
</template>
|
||||||
</n-switch>
|
</n-switch>
|
||||||
<n-button @click="refresh" size="small" type="primary" tertiary>
|
<n-button @click="refresh" type="primary" tertiary>
|
||||||
{{ t('refresh') }}
|
{{ t('refresh') }}
|
||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</n-space>
|
||||||
<div style="overflow: auto; height: 80vh;">
|
</div>
|
||||||
<n-list hoverable clickable>
|
<n-split class="left" direction="horizontal" :max="0.75" :min="0.25" :default-size="mailboxSplitSize"
|
||||||
<n-list-item v-for="row in data" v-bind:key="row.id" @click="() => clickRow(row)"
|
:on-update:size="onSpiltSizeChange">
|
||||||
:class="mailItemClass(row)">
|
<template #1>
|
||||||
<n-thing :title="row.subject">
|
<div style="overflow: auto; height: 80vh;">
|
||||||
<template #description>
|
<n-list hoverable clickable>
|
||||||
<n-tag type="info">
|
<n-list-item v-for="row in data" v-bind:key="row.id" @click="() => clickRow(row)"
|
||||||
ID: {{ row.id }}
|
:class="mailItemClass(row)">
|
||||||
</n-tag>
|
<template #prefix v-if="multiActionMode">
|
||||||
<n-tag type="info">
|
<n-checkbox v-model:checked="row.checked" />
|
||||||
{{ `${row.created_at} UTC` }}
|
|
||||||
</n-tag>
|
|
||||||
<n-tag type="info">
|
|
||||||
FROM: {{ row.source }}
|
|
||||||
</n-tag>
|
|
||||||
<n-tag v-if="showEMailTo" type="info">
|
|
||||||
TO: {{ row.address }}
|
|
||||||
</n-tag>
|
|
||||||
</template>
|
</template>
|
||||||
</n-thing>
|
<n-thing :title="row.subject">
|
||||||
</n-list-item>
|
<template #description>
|
||||||
</n-list>
|
<n-tag type="info">
|
||||||
</div>
|
ID: {{ row.id }}
|
||||||
</template>
|
</n-tag>
|
||||||
<template #2>
|
<n-tag type="info">
|
||||||
<n-card v-if="curMail" class="mail-item" :title="curMail.subject" style="overflow: auto; max-height: 100vh;">
|
{{ `${row.created_at} UTC` }}
|
||||||
<n-space>
|
</n-tag>
|
||||||
<n-tag type="info">
|
<n-tag type="info">
|
||||||
ID: {{ curMail.id }}
|
FROM: {{ row.source }}
|
||||||
</n-tag>
|
</n-tag>
|
||||||
<n-tag type="info">
|
<n-tag v-if="showEMailTo" type="info">
|
||||||
{{ `${curMail.created_at} UTC` }}
|
TO: {{ row.address }}
|
||||||
</n-tag>
|
</n-tag>
|
||||||
<n-tag type="info">
|
</template>
|
||||||
FROM: {{ curMail.source }}
|
</n-thing>
|
||||||
</n-tag>
|
</n-list-item>
|
||||||
<n-tag v-if="showEMailTo" type="info">
|
</n-list>
|
||||||
TO: {{ curMail.address }}
|
</div>
|
||||||
</n-tag>
|
</template>
|
||||||
<n-popconfirm v-if="enableUserDeleteEmail" @positive-click="deleteMail">
|
<template #2>
|
||||||
<template #trigger>
|
<n-card v-if="curMail" class="mail-item" :title="curMail.subject" style="overflow: auto; max-height: 100vh;">
|
||||||
<n-button tertiary type="error" size="small">{{ t('delete') }}</n-button>
|
<n-space>
|
||||||
</template>
|
<n-tag type="info">
|
||||||
{{ t('deleteMailTip') }}
|
ID: {{ curMail.id }}
|
||||||
</n-popconfirm>
|
</n-tag>
|
||||||
<n-button v-if="curMail.attachments && curMail.attachments.length > 0" size="small" tertiary type="info"
|
<n-tag type="info">
|
||||||
@click="getAttachments(curMail.attachments)">
|
{{ `${curMail.created_at} UTC` }}
|
||||||
{{ t('attachments') }}
|
</n-tag>
|
||||||
</n-button>
|
<n-tag type="info">
|
||||||
<n-button tag="a" target="_blank" tertiary type="info" size="small" :download="curMail.id + '.eml'"
|
FROM: {{ curMail.source }}
|
||||||
:href="getDownloadEmlUrl(curMail.raw)">
|
</n-tag>
|
||||||
<template #icon>
|
<n-tag v-if="showEMailTo" type="info">
|
||||||
<n-icon :component="CloudDownloadRound" />
|
TO: {{ curMail.address }}
|
||||||
</template>
|
</n-tag>
|
||||||
{{ t('downloadMail') }}
|
<n-popconfirm v-if="enableUserDeleteEmail" @positive-click="deleteMail">
|
||||||
</n-button>
|
<template #trigger>
|
||||||
<n-button v-if="showReply" size="small" tertiary type="info" @click="replyMail">
|
<n-button tertiary type="error" size="small">{{ t('delete') }}</n-button>
|
||||||
<template #icon>
|
</template>
|
||||||
<n-icon :component="ReplyFilled" />
|
{{ t('deleteMailTip') }}
|
||||||
</template>
|
</n-popconfirm>
|
||||||
{{ t('reply') }}
|
<n-button v-if="curMail.attachments && curMail.attachments.length > 0" size="small" tertiary type="info"
|
||||||
</n-button>
|
@click="getAttachments(curMail.attachments)">
|
||||||
<n-button size="small" tertiary type="info" @click="showTextMail = !showTextMail">
|
{{ t('attachments') }}
|
||||||
{{ showTextMail ? t('showHtmlMail') : t('showTextMail') }}
|
</n-button>
|
||||||
</n-button>
|
<n-button tag="a" target="_blank" tertiary type="info" size="small" :download="curMail.id + '.eml'"
|
||||||
</n-space>
|
:href="getDownloadEmlUrl(curMail.raw)">
|
||||||
<pre v-if="showTextMail" style="margin-top: 10px;">{{ curMail.text }}</pre>
|
<template #icon>
|
||||||
<iframe v-else-if="useIframeShowMail" :srcdoc="curMail.message"
|
<n-icon :component="CloudDownloadRound" />
|
||||||
style="margin-top: 10px;width: 100%; height: 100%;">
|
</template>
|
||||||
</iframe>
|
{{ t('downloadMail') }}
|
||||||
<div v-else v-html="curMail.message" style="margin-top: 10px;"></div>
|
</n-button>
|
||||||
</n-card>
|
<n-button v-if="showReply" size="small" tertiary type="info" @click="replyMail">
|
||||||
<n-card class="mail-item" v-else>
|
<template #icon>
|
||||||
<n-result status="info" :title="t('pleaseSelectMail')">
|
<n-icon :component="ReplyFilled" />
|
||||||
</n-result>
|
</template>
|
||||||
</n-card>
|
{{ t('reply') }}
|
||||||
</template>
|
</n-button>
|
||||||
</n-split>
|
<n-button size="small" tertiary type="info" @click="showTextMail = !showTextMail">
|
||||||
|
{{ showTextMail ? t('showHtmlMail') : t('showTextMail') }}
|
||||||
|
</n-button>
|
||||||
|
</n-space>
|
||||||
|
<pre v-if="showTextMail" style="margin-top: 10px;">{{ curMail.text }}</pre>
|
||||||
|
<iframe v-else-if="useIframeShowMail" :srcdoc="curMail.message"
|
||||||
|
style="margin-top: 10px;width: 100%; height: 100%;">
|
||||||
|
</iframe>
|
||||||
|
<div v-else v-html="curMail.message" style="margin-top: 10px;"></div>
|
||||||
|
</n-card>
|
||||||
|
<n-card class="mail-item" v-else>
|
||||||
|
<n-result status="info" :title="t('pleaseSelectMail')">
|
||||||
|
</n-result>
|
||||||
|
</n-card>
|
||||||
|
</template>
|
||||||
|
</n-split>
|
||||||
|
</div>
|
||||||
<div class="left" v-else>
|
<div class="left" v-else>
|
||||||
<div class="center">
|
<n-space justify="center">
|
||||||
<div style="display: inline-block;">
|
<div style="display: inline-block;">
|
||||||
<n-pagination v-model:page="page" v-model:page-size="pageSize" :item-count="count" simple size="small" />
|
<n-pagination v-model:page="page" v-model:page-size="pageSize" :item-count="count" simple size="small" />
|
||||||
</div>
|
</div>
|
||||||
@@ -326,10 +454,10 @@ onBeforeUnmount(() => {
|
|||||||
{{ t('autoRefresh') }}
|
{{ t('autoRefresh') }}
|
||||||
</template>
|
</template>
|
||||||
</n-switch>
|
</n-switch>
|
||||||
<n-button @click="refresh" size="small" type="primary">
|
<n-button @click="refresh" tertiary size="small" type="primary">
|
||||||
{{ t('refresh') }}
|
{{ t('refresh') }}
|
||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</n-space>
|
||||||
<div style="overflow: auto; height: 80vh;">
|
<div style="overflow: auto; height: 80vh;">
|
||||||
<n-list hoverable clickable>
|
<n-list hoverable clickable>
|
||||||
<n-list-item v-for="row in data" v-bind:key="row.id" @click="() => clickRow(row)">
|
<n-list-item v-for="row in data" v-bind:key="row.id" @click="() => clickRow(row)">
|
||||||
@@ -433,6 +561,26 @@ onBeforeUnmount(() => {
|
|||||||
</n-list>
|
</n-list>
|
||||||
</n-spin>
|
</n-spin>
|
||||||
</n-modal>
|
</n-modal>
|
||||||
|
<n-modal v-model:show="showMultiActionDownload" preset="dialog" :title="t('downloadMail')">
|
||||||
|
<n-tag type="info">
|
||||||
|
{{ multiActionDownloadZip.filename }}
|
||||||
|
</n-tag>
|
||||||
|
<n-button tag="a" target="_blank" tertiary type="info" size="small" :download="multiActionDownloadZip.filename"
|
||||||
|
:href="multiActionDownloadZip.url">
|
||||||
|
<n-icon :component="CloudDownloadRound" />
|
||||||
|
{{ t('downloadMail') + " zip" }}
|
||||||
|
</n-button>
|
||||||
|
</n-modal>
|
||||||
|
<n-modal v-model:show="showMultiActionDelete" preset="dialog" :title="t('delete') + t('success')"
|
||||||
|
negative-text="OK">
|
||||||
|
<n-space justify="center">
|
||||||
|
<n-progress type="circle" status="error" :percentage="multiActionDeleteProgress.percentage">
|
||||||
|
<span style="text-align: center">
|
||||||
|
{{ multiActionDeleteProgress.tip }}
|
||||||
|
</span>
|
||||||
|
</n-progress>
|
||||||
|
</n-space>
|
||||||
|
</n-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user