mirror of https://github.com/halo-dev/halo-admin
refactor: attachment detail (#375)
* refactor: attachment detail modal * refactor: attachment media type judgment * refactor: pagination * refactor: delete AttachmentDetailDrawer.vue * refactor: remove unnecessary code * perf: previous and next button statepull/376/head^2
parent
d3eb288327
commit
2939cbbfbd
|
@ -31,7 +31,6 @@
|
||||||
"filepond": "^4.30.3",
|
"filepond": "^4.30.3",
|
||||||
"filepond-plugin-file-validate-type": "^1.2.6",
|
"filepond-plugin-file-validate-type": "^1.2.6",
|
||||||
"filepond-plugin-image-preview": "^4.6.10",
|
"filepond-plugin-image-preview": "^4.6.10",
|
||||||
"flv.js": "^1.6.2",
|
|
||||||
"halo-editor": "^2.8.3",
|
"halo-editor": "^2.8.3",
|
||||||
"marked": "^2.1.3",
|
"marked": "^2.1.3",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
|
@ -41,7 +40,6 @@
|
||||||
"vue-clipboard2": "^0.3.3",
|
"vue-clipboard2": "^0.3.3",
|
||||||
"vue-contextmenujs": "^1.3.13",
|
"vue-contextmenujs": "^1.3.13",
|
||||||
"vue-count-to": "^1.0.13",
|
"vue-count-to": "^1.0.13",
|
||||||
"vue-dplayer": "0.0.10",
|
|
||||||
"vue-filepond": "^6.0.3",
|
"vue-filepond": "^6.0.3",
|
||||||
"vue-ls": "^3.2.2",
|
"vue-ls": "^3.2.2",
|
||||||
"vue-router": "^3.5.3",
|
"vue-router": "^3.5.3",
|
||||||
|
|
|
@ -26,7 +26,6 @@ specifiers:
|
||||||
filepond: ^4.30.3
|
filepond: ^4.30.3
|
||||||
filepond-plugin-file-validate-type: ^1.2.6
|
filepond-plugin-file-validate-type: ^1.2.6
|
||||||
filepond-plugin-image-preview: ^4.6.10
|
filepond-plugin-image-preview: ^4.6.10
|
||||||
flv.js: ^1.6.2
|
|
||||||
halo-editor: ^2.8.3
|
halo-editor: ^2.8.3
|
||||||
husky: ^6.0.0
|
husky: ^6.0.0
|
||||||
less: ^3.13.1
|
less: ^3.13.1
|
||||||
|
@ -42,7 +41,6 @@ specifiers:
|
||||||
vue-clipboard2: ^0.3.3
|
vue-clipboard2: ^0.3.3
|
||||||
vue-contextmenujs: ^1.3.13
|
vue-contextmenujs: ^1.3.13
|
||||||
vue-count-to: ^1.0.13
|
vue-count-to: ^1.0.13
|
||||||
vue-dplayer: 0.0.10
|
|
||||||
vue-filepond: ^6.0.3
|
vue-filepond: ^6.0.3
|
||||||
vue-ls: ^3.2.2
|
vue-ls: ^3.2.2
|
||||||
vue-router: ^3.5.3
|
vue-router: ^3.5.3
|
||||||
|
@ -62,7 +60,6 @@ dependencies:
|
||||||
filepond: 4.30.3
|
filepond: 4.30.3
|
||||||
filepond-plugin-file-validate-type: 1.2.6_filepond@4.30.3
|
filepond-plugin-file-validate-type: 1.2.6_filepond@4.30.3
|
||||||
filepond-plugin-image-preview: 4.6.10_filepond@4.30.3
|
filepond-plugin-image-preview: 4.6.10_filepond@4.30.3
|
||||||
flv.js: 1.6.2
|
|
||||||
halo-editor: 2.8.3
|
halo-editor: 2.8.3
|
||||||
marked: 2.1.3
|
marked: 2.1.3
|
||||||
nprogress: 0.2.0
|
nprogress: 0.2.0
|
||||||
|
@ -72,7 +69,6 @@ dependencies:
|
||||||
vue-clipboard2: 0.3.3
|
vue-clipboard2: 0.3.3
|
||||||
vue-contextmenujs: 1.3.13
|
vue-contextmenujs: 1.3.13
|
||||||
vue-count-to: 1.0.13
|
vue-count-to: 1.0.13
|
||||||
vue-dplayer: 0.0.10
|
|
||||||
vue-filepond: 6.0.3_filepond@4.30.3+vue@2.6.14
|
vue-filepond: 6.0.3_filepond@4.30.3+vue@2.6.14
|
||||||
vue-ls: 3.2.2
|
vue-ls: 3.2.2
|
||||||
vue-router: 3.5.3
|
vue-router: 3.5.3
|
||||||
|
@ -2820,13 +2816,6 @@ packages:
|
||||||
resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==}
|
resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/axios/0.19.2:
|
|
||||||
resolution: {integrity: sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==}
|
|
||||||
deprecated: Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410
|
|
||||||
dependencies:
|
|
||||||
follow-redirects: 1.5.10
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/axios/0.21.4:
|
/axios/0.21.4:
|
||||||
resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
|
resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3142,10 +3131,6 @@ packages:
|
||||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/balloon-css/1.2.0:
|
|
||||||
resolution: {integrity: sha512-urXwkHgwp6GsXVF+it01485Z2Cj4pnW02ICnM0TemOlkKmCNnDLmyy+ZZiRXBpwldUXO+aRNr7Hdia4CBvXJ5A==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/base/0.11.2:
|
/base/0.11.2:
|
||||||
resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==}
|
resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
@ -4383,12 +4368,6 @@ packages:
|
||||||
ms: 2.0.0
|
ms: 2.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/debug/3.1.0:
|
|
||||||
resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==}
|
|
||||||
dependencies:
|
|
||||||
ms: 2.0.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/debug/3.2.7:
|
/debug/3.2.7:
|
||||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -4714,14 +4693,6 @@ packages:
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/dplayer/1.26.0:
|
|
||||||
resolution: {integrity: sha512-uOE0w/WdlX7N9d0ppIEcAYrcnUjY52TMX+MBL4lj9Mj+JMljVuaEc5w88HkZp5Q11VqvN/jxnM8ktx2Dr7/MgA==}
|
|
||||||
dependencies:
|
|
||||||
axios: 0.19.2
|
|
||||||
balloon-css: 1.2.0
|
|
||||||
promise-polyfill: 8.1.3
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/duplexer/0.1.2:
|
/duplexer/0.1.2:
|
||||||
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
|
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -4893,10 +4864,6 @@ packages:
|
||||||
is-symbol: 1.0.4
|
is-symbol: 1.0.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/es6-promise/4.2.8:
|
|
||||||
resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/escalade/3.1.1:
|
/escalade/3.1.1:
|
||||||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
@ -5537,13 +5504,6 @@ packages:
|
||||||
readable-stream: 2.3.7
|
readable-stream: 2.3.7
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/flv.js/1.6.2:
|
|
||||||
resolution: {integrity: sha512-xre4gUbX1MPtgQRKj2pxJENp/RnaHaxYvy3YToVVCrSmAWUu85b9mug6pTXF6zakUjNP2lFWZ1rkSX7gxhB/2A==}
|
|
||||||
dependencies:
|
|
||||||
es6-promise: 4.2.8
|
|
||||||
webworkify-webpack: 2.1.5
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/follow-redirects/1.14.4:
|
/follow-redirects/1.14.4:
|
||||||
resolution: {integrity: sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==}
|
resolution: {integrity: sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==}
|
||||||
engines: {node: '>=4.0'}
|
engines: {node: '>=4.0'}
|
||||||
|
@ -5553,13 +5513,6 @@ packages:
|
||||||
debug:
|
debug:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/follow-redirects/1.5.10:
|
|
||||||
resolution: {integrity: sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==}
|
|
||||||
engines: {node: '>=4.0'}
|
|
||||||
dependencies:
|
|
||||||
debug: 3.1.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/for-each/0.3.3:
|
/for-each/0.3.3:
|
||||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -8055,6 +8008,7 @@ packages:
|
||||||
|
|
||||||
/ms/2.0.0:
|
/ms/2.0.0:
|
||||||
resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=}
|
resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/ms/2.1.1:
|
/ms/2.1.1:
|
||||||
resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==}
|
resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==}
|
||||||
|
@ -9318,10 +9272,6 @@ packages:
|
||||||
resolution: {integrity: sha1-mEcocL8igTL8vdhoEputEsPAKeM=}
|
resolution: {integrity: sha1-mEcocL8igTL8vdhoEputEsPAKeM=}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/promise-polyfill/8.1.3:
|
|
||||||
resolution: {integrity: sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/prompts/2.4.1:
|
/prompts/2.4.1:
|
||||||
resolution: {integrity: sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==}
|
resolution: {integrity: sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
@ -11222,13 +11172,6 @@ packages:
|
||||||
resolution: {integrity: sha512-6R4OVBVNtQTlcbXu6SJ8ENR35M2/CdWt3Jmv57jOUM+1ojiFmjVGvZPH8DfHpMDSA+ITs+EW5V6qthADxeyYOQ==}
|
resolution: {integrity: sha512-6R4OVBVNtQTlcbXu6SJ8ENR35M2/CdWt3Jmv57jOUM+1ojiFmjVGvZPH8DfHpMDSA+ITs+EW5V6qthADxeyYOQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/vue-dplayer/0.0.10:
|
|
||||||
resolution: {integrity: sha512-l6d6OnhEUO87lhAees9mEBUFsG5Thqv/VeEVZlSQ993/S0oxvWTDLjjkzH59hO2PALimBK2kB6yNYsHyJBgotw==}
|
|
||||||
dependencies:
|
|
||||||
dplayer: 1.26.0
|
|
||||||
vue-github-badge: 1.0.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/vue-eslint-parser/7.11.0_eslint@6.8.0:
|
/vue-eslint-parser/7.11.0_eslint@6.8.0:
|
||||||
resolution: {integrity: sha512-qh3VhDLeh773wjgNTl7ss0VejY9bMMa0GoDG2fQVyDzRFdiU3L7fw74tWZDHNQXdZqxO3EveQroa9ct39D2nqg==}
|
resolution: {integrity: sha512-qh3VhDLeh773wjgNTl7ss0VejY9bMMa0GoDG2fQVyDzRFdiU3L7fw74tWZDHNQXdZqxO3EveQroa9ct39D2nqg==}
|
||||||
engines: {node: '>=8.10'}
|
engines: {node: '>=8.10'}
|
||||||
|
@ -11257,10 +11200,6 @@ packages:
|
||||||
vue: 2.6.14
|
vue: 2.6.14
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/vue-github-badge/1.0.1:
|
|
||||||
resolution: {integrity: sha1-3/fOBzIOZKIY7fEGsVpDF27AYQY=}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/vue-hot-reload-api/2.3.4:
|
/vue-hot-reload-api/2.3.4:
|
||||||
resolution: {integrity: sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==}
|
resolution: {integrity: sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -11607,10 +11546,6 @@ packages:
|
||||||
engines: {node: '>=0.8.0'}
|
engines: {node: '>=0.8.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/webworkify-webpack/2.1.5:
|
|
||||||
resolution: {integrity: sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/whatwg-encoding/1.0.5:
|
/whatwg-encoding/1.0.5:
|
||||||
resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==}
|
resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
|
@ -1,41 +1,41 @@
|
||||||
<template>
|
<template>
|
||||||
<page-view>
|
<page-view>
|
||||||
<a-row :gutter="12" type="flex" align="middle">
|
<a-row :gutter="12" align="middle" type="flex">
|
||||||
<a-col :span="24" class="pb-3">
|
<a-col :span="24" class="pb-3">
|
||||||
<a-card :bordered="false" :bodyStyle="{ padding: '16px' }">
|
<a-card :bodyStyle="{ padding: '16px' }" :bordered="false">
|
||||||
<div class="table-page-search-wrapper">
|
<div class="table-page-search-wrapper">
|
||||||
<a-form layout="inline">
|
<a-form layout="inline">
|
||||||
<a-row :gutter="48">
|
<a-row :gutter="48">
|
||||||
<a-col :md="6" :sm="24">
|
<a-col :md="6" :sm="24">
|
||||||
<a-form-item label="关键词:">
|
<a-form-item label="关键词:">
|
||||||
<a-input v-model="queryParam.keyword" @keyup.enter="handleQuery()" />
|
<a-input v-model="list.params.keyword" @keyup.enter="handleQuery()" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :md="6" :sm="24">
|
<a-col :md="6" :sm="24">
|
||||||
<a-form-item label="存储位置:">
|
<a-form-item label="存储位置:">
|
||||||
<a-select
|
<a-select
|
||||||
v-model="queryParam.attachmentType"
|
v-model="list.params.attachmentType"
|
||||||
@change="handleQuery()"
|
:loading="types.loading"
|
||||||
:loading="typesLoading"
|
|
||||||
allowClear
|
allowClear
|
||||||
|
@change="handleQuery()"
|
||||||
>
|
>
|
||||||
<a-select-option v-for="item in types" :key="item" :value="item">{{
|
<a-select-option v-for="item in types.data" :key="item" :value="item">
|
||||||
attachmentType[item].text
|
{{ item | typeText }}
|
||||||
}}</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :md="6" :sm="24">
|
<a-col :md="6" :sm="24">
|
||||||
<a-form-item label="文件类型:">
|
<a-form-item label="文件类型:">
|
||||||
<a-select
|
<a-select
|
||||||
v-model="queryParam.mediaType"
|
v-model="list.params.mediaType"
|
||||||
@change="handleQuery()"
|
:loading="mediaTypes.loading"
|
||||||
:loading="mediaTypesLoading"
|
|
||||||
allowClear
|
allowClear
|
||||||
|
@change="handleQuery()"
|
||||||
>
|
>
|
||||||
<a-select-option v-for="(item, index) in mediaTypes" :key="index" :value="item">{{
|
<a-select-option v-for="(item, index) in mediaTypes.data" :key="index" :value="item"
|
||||||
item
|
>{{ item }}
|
||||||
}}</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -51,19 +51,19 @@
|
||||||
</a-form>
|
</a-form>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-0 table-operator">
|
<div class="mb-0 table-operator">
|
||||||
<a-button type="primary" icon="cloud-upload" @click="() => (uploadVisible = true)">上传</a-button>
|
<a-button icon="cloud-upload" type="primary" @click="upload.visible = true">上传</a-button>
|
||||||
<a-button icon="select" v-show="!supportMultipleSelection" @click="handleMultipleSelection">
|
<a-button v-show="!supportMultipleSelection" icon="select" @click="handleMultipleSelection">
|
||||||
批量操作
|
批量操作
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button
|
<a-button
|
||||||
type="danger"
|
|
||||||
icon="delete"
|
|
||||||
v-show="supportMultipleSelection"
|
v-show="supportMultipleSelection"
|
||||||
|
icon="delete"
|
||||||
|
type="danger"
|
||||||
@click="handleDeleteAttachmentInBatch"
|
@click="handleDeleteAttachmentInBatch"
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button icon="close" v-show="supportMultipleSelection" @click="handleCancelMultipleSelection">
|
<a-button v-show="supportMultipleSelection" icon="close" @click="handleCancelMultipleSelection">
|
||||||
取消
|
取消
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -71,36 +71,36 @@
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-list
|
<a-list
|
||||||
class="attachments-group"
|
:dataSource="list.data"
|
||||||
:grid="{ gutter: 12, xs: 2, sm: 2, md: 4, lg: 6, xl: 6, xxl: 6 }"
|
:grid="{ gutter: 12, xs: 2, sm: 2, md: 4, lg: 6, xl: 6, xxl: 6 }"
|
||||||
:dataSource="formattedDatas"
|
:loading="list.loading"
|
||||||
:loading="listLoading"
|
class="attachments-group"
|
||||||
>
|
>
|
||||||
<a-list-item slot="renderItem" slot-scope="item, index" :key="index">
|
<a-list-item :key="index" slot="renderItem" slot-scope="item, index">
|
||||||
<a-card
|
<a-card
|
||||||
:bodyStyle="{ padding: 0 }"
|
:bodyStyle="{ padding: 0 }"
|
||||||
hoverable
|
hoverable
|
||||||
@click="handleShowDetailDrawer(item)"
|
@click="handleOpenDetail(item)"
|
||||||
@contextmenu.prevent="handleContextMenu($event, item)"
|
@contextmenu.prevent="handleContextMenu($event, item)"
|
||||||
>
|
>
|
||||||
<div class="attach-thumb attachments-group-item">
|
<div class="attach-thumb attachments-group-item">
|
||||||
<span v-if="!handleJudgeMediaType(item)" class="attachments-group-item-type">{{ item.suffix }}</span>
|
<span v-if="!isImage(item)" class="attachments-group-item-type">{{ item.suffix }}</span>
|
||||||
<span
|
<span
|
||||||
v-else
|
v-else
|
||||||
class="attachments-group-item-img"
|
|
||||||
:style="`background-image:url(${item.thumbPath})`"
|
:style="`background-image:url(${item.thumbPath})`"
|
||||||
|
class="attachments-group-item-img"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<a-card-meta class="p-3">
|
<a-card-meta class="p-3">
|
||||||
<ellipsis :length="isMobile() ? 12 : 16" tooltip slot="description">{{ item.name }}</ellipsis>
|
<ellipsis slot="description" :length="isMobile() ? 12 : 16" tooltip>{{ item.name }}</ellipsis>
|
||||||
</a-card-meta>
|
</a-card-meta>
|
||||||
<a-checkbox
|
<a-checkbox
|
||||||
class="select-attachment-checkbox"
|
|
||||||
:style="getCheckStatus(item.id) ? selectedAttachmentStyle : ''"
|
|
||||||
:checked="getCheckStatus(item.id)"
|
|
||||||
@click="handleAttachmentSelectionChanged($event, item)"
|
|
||||||
v-show="supportMultipleSelection"
|
v-show="supportMultipleSelection"
|
||||||
|
:checked="getCheckStatus(item.id)"
|
||||||
|
:style="getCheckStatus(item.id) ? selectedAttachmentStyle : ''"
|
||||||
|
class="select-attachment-checkbox"
|
||||||
|
@click="handleAttachmentSelectionChanged($event, item)"
|
||||||
></a-checkbox>
|
></a-checkbox>
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-list-item>
|
</a-list-item>
|
||||||
|
@ -109,87 +109,120 @@
|
||||||
</a-row>
|
</a-row>
|
||||||
<div class="page-wrapper">
|
<div class="page-wrapper">
|
||||||
<a-pagination
|
<a-pagination
|
||||||
class="pagination"
|
|
||||||
:current="pagination.page"
|
:current="pagination.page"
|
||||||
:total="pagination.total"
|
|
||||||
:defaultPageSize="pagination.size"
|
:defaultPageSize="pagination.size"
|
||||||
:pageSizeOptions="['18', '36', '54', '72', '90', '108']"
|
:pageSizeOptions="['18', '36', '54', '72', '90', '108']"
|
||||||
showSizeChanger
|
:total="pagination.total"
|
||||||
@change="handlePaginationChange"
|
class="pagination"
|
||||||
@showSizeChange="handlePaginationChange"
|
|
||||||
showLessItems
|
showLessItems
|
||||||
|
showSizeChanger
|
||||||
|
@change="handlePageChange"
|
||||||
|
@showSizeChange="handlePageSizeChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<a-modal title="上传附件" v-model="uploadVisible" :footer="null" :afterClose="onUploadClose" destroyOnClose>
|
<a-modal v-model="upload.visible" :afterClose="onUploadClose" :footer="null" destroyOnClose title="上传附件">
|
||||||
<FilePondUpload ref="upload" :uploadHandler="uploadHandler"></FilePondUpload>
|
<FilePondUpload ref="upload" :uploadHandler="upload.handler"></FilePondUpload>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
<AttachmentDetailDrawer
|
<AttachmentDetailModal
|
||||||
v-model="drawerVisible"
|
|
||||||
v-if="selectAttachment"
|
|
||||||
:attachment="selectAttachment"
|
|
||||||
:addToPhoto="true"
|
:addToPhoto="true"
|
||||||
|
:attachment="list.selected"
|
||||||
|
:visible.sync="detailVisible"
|
||||||
@delete="handleListAttachments()"
|
@delete="handleListAttachments()"
|
||||||
/>
|
>
|
||||||
|
<template #extraFooter>
|
||||||
|
<a-button :disabled="selectPreviousButtonDisabled" @click="handleSelectPrevious">上一项</a-button>
|
||||||
|
<a-button :disabled="selectNextButtonDisabled" @click="handleSelectNext">下一项</a-button>
|
||||||
|
</template>
|
||||||
|
</AttachmentDetailModal>
|
||||||
</page-view>
|
</page-view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mixin, mixinDevice } from '@/mixins/mixin.js'
|
import { mixin, mixinDevice } from '@/mixins/mixin.js'
|
||||||
import { PageView } from '@/layouts'
|
import { PageView } from '@/layouts'
|
||||||
import AttachmentDetailDrawer from './components/AttachmentDetailDrawer'
|
import AttachmentDetailModal from './components/AttachmentDetailModal.vue'
|
||||||
import attachmentApi from '@/api/attachment'
|
import attachmentApi from '@/api/attachment'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
PageView,
|
PageView,
|
||||||
AttachmentDetailDrawer
|
AttachmentDetailModal
|
||||||
},
|
},
|
||||||
mixins: [mixin, mixinDevice],
|
mixins: [mixin, mixinDevice],
|
||||||
|
filters: {
|
||||||
|
typeText(type) {
|
||||||
|
return attachmentApi.type[type].text
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
attachmentType: attachmentApi.type,
|
list: {
|
||||||
listLoading: true,
|
data: [],
|
||||||
uploadVisible: false,
|
loading: false,
|
||||||
supportMultipleSelection: false,
|
total: 0,
|
||||||
selectedAttachmentCheckbox: {},
|
hasNext: false,
|
||||||
batchSelectedAttachments: [],
|
hasPrevious: false,
|
||||||
selectAttachment: {},
|
selected: {},
|
||||||
attachments: [],
|
params: {
|
||||||
mediaTypes: [],
|
|
||||||
mediaTypesLoading: false,
|
|
||||||
types: [],
|
|
||||||
typesLoading: false,
|
|
||||||
editable: false,
|
|
||||||
pagination: {
|
|
||||||
page: 1,
|
|
||||||
size: 18,
|
|
||||||
sort: null,
|
|
||||||
total: 1
|
|
||||||
},
|
|
||||||
queryParam: {
|
|
||||||
page: 0,
|
page: 0,
|
||||||
size: 18,
|
size: 18,
|
||||||
sort: null,
|
|
||||||
keyword: null,
|
keyword: null,
|
||||||
mediaType: null,
|
mediaType: null,
|
||||||
attachmentType: null
|
attachmentType: null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
drawerVisible: false,
|
|
||||||
uploadHandler: attachmentApi.upload
|
mediaTypes: {
|
||||||
|
data: [],
|
||||||
|
loading: false
|
||||||
|
},
|
||||||
|
|
||||||
|
types: {
|
||||||
|
data: [],
|
||||||
|
loading: false
|
||||||
|
},
|
||||||
|
|
||||||
|
upload: {
|
||||||
|
handler: attachmentApi.upload,
|
||||||
|
visible: false
|
||||||
|
},
|
||||||
|
|
||||||
|
detailVisible: false,
|
||||||
|
|
||||||
|
supportMultipleSelection: false,
|
||||||
|
selectedAttachmentCheckbox: {},
|
||||||
|
batchSelectedAttachments: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
formattedDatas() {
|
|
||||||
return this.attachments.map(attachment => {
|
|
||||||
attachment.typeProperty = this.attachmentType[attachment.type]
|
|
||||||
return attachment
|
|
||||||
})
|
|
||||||
},
|
|
||||||
selectedAttachmentStyle() {
|
selectedAttachmentStyle() {
|
||||||
return {
|
return {
|
||||||
border: `2px solid ${this.color()}`
|
border: `2px solid ${this.color()}`
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
isImage() {
|
||||||
|
return function(attachment) {
|
||||||
|
if (!attachment || !attachment.mediaType) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return attachment.mediaType.startsWith('image')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pagination() {
|
||||||
|
return {
|
||||||
|
page: this.list.params.page + 1,
|
||||||
|
size: this.list.params.size,
|
||||||
|
total: this.list.total
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectPreviousButtonDisabled() {
|
||||||
|
const index = this.list.data.findIndex(attachment => attachment.id === this.list.selected.id)
|
||||||
|
return index === 0 && !this.list.hasPrevious
|
||||||
|
},
|
||||||
|
selectNextButtonDisabled() {
|
||||||
|
const index = this.list.data.findIndex(attachment => attachment.id === this.list.selected.id)
|
||||||
|
return index === this.list.data.length - 1 && !this.list.hasNext
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -197,71 +230,79 @@ export default {
|
||||||
this.handleListMediaTypes()
|
this.handleListMediaTypes()
|
||||||
this.handleListTypes()
|
this.handleListTypes()
|
||||||
},
|
},
|
||||||
destroyed: function() {
|
|
||||||
if (this.drawerVisible) {
|
|
||||||
this.drawerVisible = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeRouteLeave(to, from, next) {
|
|
||||||
if (this.drawerVisible) {
|
|
||||||
this.drawerVisible = false
|
|
||||||
}
|
|
||||||
next()
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
...mapGetters(['color']),
|
...mapGetters(['color']),
|
||||||
handleListAttachments() {
|
|
||||||
this.listLoading = true
|
/**
|
||||||
this.queryParam.page = this.pagination.page - 1
|
* List attachments
|
||||||
this.queryParam.size = this.pagination.size
|
*/
|
||||||
this.queryParam.sort = this.pagination.sort
|
async handleListAttachments() {
|
||||||
attachmentApi
|
try {
|
||||||
.query(this.queryParam)
|
this.list.loading = true
|
||||||
.then(response => {
|
|
||||||
this.attachments = response.data.data.content
|
const response = await attachmentApi.query(this.list.params)
|
||||||
this.pagination.total = response.data.data.total
|
|
||||||
})
|
this.list.data = response.data.data.content
|
||||||
.finally(() => {
|
this.list.total = response.data.data.total
|
||||||
setTimeout(() => {
|
this.list.hasNext = response.data.data.hasNext
|
||||||
this.listLoading = false
|
this.list.hasPrevious = response.data.data.hasPrevious
|
||||||
}, 200)
|
} catch (error) {
|
||||||
})
|
this.$log.error(error)
|
||||||
|
} finally {
|
||||||
|
this.list.loading = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleListMediaTypes() {
|
|
||||||
this.mediaTypesLoading = true
|
/**
|
||||||
attachmentApi
|
* List attachment media types
|
||||||
.getMediaTypes()
|
*/
|
||||||
.then(response => {
|
async handleListMediaTypes() {
|
||||||
this.mediaTypes = response.data.data
|
try {
|
||||||
})
|
this.mediaTypes.loading = true
|
||||||
.finally(() => {
|
|
||||||
setTimeout(() => {
|
const response = await attachmentApi.getMediaTypes()
|
||||||
this.mediaTypesLoading = false
|
|
||||||
}, 200)
|
this.mediaTypes.data = response.data.data
|
||||||
})
|
} catch (error) {
|
||||||
|
this.$log.error(error)
|
||||||
|
} finally {
|
||||||
|
this.mediaTypes.loading = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleListTypes() {
|
|
||||||
this.typesLoading = true
|
/**
|
||||||
attachmentApi
|
* List attachment upload types
|
||||||
.getTypes()
|
*/
|
||||||
.then(response => {
|
async handleListTypes() {
|
||||||
this.types = response.data.data
|
try {
|
||||||
})
|
this.types.loading = true
|
||||||
.finally(() => {
|
|
||||||
setTimeout(() => {
|
const response = await attachmentApi.getTypes()
|
||||||
this.typesLoading = false
|
|
||||||
}, 200)
|
this.types.data = response.data.data
|
||||||
})
|
} catch (error) {
|
||||||
|
this.$log.error(error)
|
||||||
|
} finally {
|
||||||
|
this.types.loading = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleShowDetailDrawer(attachment) {
|
|
||||||
this.selectAttachment = attachment
|
/**
|
||||||
this.drawerVisible = !this.supportMultipleSelection
|
* Handle open attachment detail modal event
|
||||||
|
*/
|
||||||
|
handleOpenDetail(attachment) {
|
||||||
|
this.list.selected = attachment
|
||||||
|
this.detailVisible = !this.supportMultipleSelection
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show context menu
|
||||||
|
*/
|
||||||
handleContextMenu(event, item) {
|
handleContextMenu(event, item) {
|
||||||
this.$contextmenu({
|
this.$contextmenu({
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
label: `${this.handleJudgeMediaType(item) ? '复制图片链接' : '复制文件链接'}`,
|
label: `复制${this.isImage(item) ? '图片' : '文件'}链接`,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const text = `${encodeURI(item.path)}`
|
const text = `${encodeURI(item.path)}`
|
||||||
this.$copyText(text)
|
this.$copyText(text)
|
||||||
|
@ -277,7 +318,7 @@ export default {
|
||||||
divided: true
|
divided: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
disabled: !this.handleJudgeMediaType(item),
|
disabled: !this.isImage(item),
|
||||||
label: '复制 Markdown 格式链接',
|
label: '复制 Markdown 格式链接',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const text = `![${item.name}](${encodeURI(item.path)})`
|
const text = `![${item.name}](${encodeURI(item.path)})`
|
||||||
|
@ -290,6 +331,22 @@ export default {
|
||||||
this.$log.debug('copy.err', err)
|
this.$log.debug('copy.err', err)
|
||||||
this.$message.error('复制失败!')
|
this.$message.error('复制失败!')
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
divided: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '删除',
|
||||||
|
onClick: () => {
|
||||||
|
this.$confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '确定删除该附件?',
|
||||||
|
okText: '确定',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk: async () => {
|
||||||
|
await attachmentApi.delete(item.id)
|
||||||
|
this.handleListAttachments()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -298,54 +355,63 @@ export default {
|
||||||
})
|
})
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
handlePaginationChange(page, size) {
|
|
||||||
this.$log.debug(`Current: ${page}, PageSize: ${size}`)
|
/**
|
||||||
this.pagination.page = page
|
* Handle page change
|
||||||
this.pagination.size = size
|
*/
|
||||||
|
handlePageChange(page = 1) {
|
||||||
|
this.list.params.page = page - 1
|
||||||
this.handleListAttachments()
|
this.handleListAttachments()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle page size change
|
||||||
|
*/
|
||||||
|
handlePageSizeChange(current, size) {
|
||||||
|
this.$log.debug(`Current: ${current}, PageSize: ${size}`)
|
||||||
|
this.list.params.page = 0
|
||||||
|
this.list.params.size = size
|
||||||
|
this.handleListAttachments()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset query params
|
||||||
|
*/
|
||||||
handleResetParam() {
|
handleResetParam() {
|
||||||
this.queryParam.keyword = null
|
this.list.params.keyword = null
|
||||||
this.queryParam.mediaType = null
|
this.list.params.mediaType = null
|
||||||
this.queryParam.attachmentType = null
|
this.list.params.attachmentType = null
|
||||||
this.handlePaginationChange(1, this.pagination.size)
|
this.handlePageChange()
|
||||||
this.handleListMediaTypes()
|
this.handleListMediaTypes()
|
||||||
this.handleListTypes()
|
this.handleListTypes()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search attachments
|
||||||
|
*/
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
this.handlePaginationChange(1, this.pagination.size)
|
this.handlePageChange()
|
||||||
},
|
},
|
||||||
onUploadClose() {
|
onUploadClose() {
|
||||||
this.$refs.upload.handleClearFileList()
|
this.$refs.upload.handleClearFileList()
|
||||||
this.handlePaginationChange(1, this.pagination.size)
|
this.handlePageChange()
|
||||||
this.handleListMediaTypes()
|
this.handleListMediaTypes()
|
||||||
this.handleListTypes()
|
this.handleListTypes()
|
||||||
},
|
},
|
||||||
handleJudgeMediaType(attachment) {
|
|
||||||
const mediaType = attachment.mediaType
|
|
||||||
// 判断文件类型
|
|
||||||
if (mediaType) {
|
|
||||||
const prefix = mediaType.split('/')[0]
|
|
||||||
|
|
||||||
return prefix === 'image'
|
|
||||||
}
|
|
||||||
// 没有获取到文件返回false
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
getCheckStatus(key) {
|
getCheckStatus(key) {
|
||||||
return this.selectedAttachmentCheckbox[key] || false
|
return this.selectedAttachmentCheckbox[key] || false
|
||||||
},
|
},
|
||||||
handleMultipleSelection() {
|
handleMultipleSelection() {
|
||||||
this.supportMultipleSelection = true
|
this.supportMultipleSelection = true
|
||||||
// 不允许附件详情抽屉显示
|
// 不允许附件详情抽屉显示
|
||||||
this.drawerVisible = false
|
this.detailVisible = false
|
||||||
this.attachments.forEach(item => {
|
this.list.data.forEach(item => {
|
||||||
this.$set(this.selectedAttachmentCheckbox, item.id, false)
|
this.$set(this.selectedAttachmentCheckbox, item.id, false)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleCancelMultipleSelection() {
|
handleCancelMultipleSelection() {
|
||||||
this.supportMultipleSelection = false
|
this.supportMultipleSelection = false
|
||||||
this.drawerVisible = false
|
this.detailVisible = false
|
||||||
this.batchSelectedAttachments = []
|
this.batchSelectedAttachments = []
|
||||||
for (const key in this.selectedCheckbox) {
|
for (const key in this.selectedCheckbox) {
|
||||||
this.$set(this.selectedAttachmentCheckbox, key, false)
|
this.$set(this.selectedAttachmentCheckbox, key, false)
|
||||||
|
@ -363,6 +429,10 @@ export default {
|
||||||
this.batchSelectedAttachments.splice(index, 1)
|
this.batchSelectedAttachments.splice(index, 1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes selected attachments
|
||||||
|
*/
|
||||||
handleDeleteAttachmentInBatch() {
|
handleDeleteAttachmentInBatch() {
|
||||||
const that = this
|
const that = this
|
||||||
if (this.batchSelectedAttachments.length <= 0) {
|
if (this.batchSelectedAttachments.length <= 0) {
|
||||||
|
@ -385,6 +455,40 @@ export default {
|
||||||
},
|
},
|
||||||
onCancel() {}
|
onCancel() {}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select previous attachment
|
||||||
|
*/
|
||||||
|
async handleSelectPrevious() {
|
||||||
|
const index = this.list.data.findIndex(item => item.id === this.list.selected.id)
|
||||||
|
if (index > 0) {
|
||||||
|
this.list.selected = this.list.data[index - 1]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (index === 0 && this.list.hasPrevious) {
|
||||||
|
this.list.params.page--
|
||||||
|
await this.handleListAttachments()
|
||||||
|
|
||||||
|
this.list.selected = this.list.data[this.list.data.length - 1]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select next attachment
|
||||||
|
*/
|
||||||
|
async handleSelectNext() {
|
||||||
|
const index = this.list.data.findIndex(item => item.id === this.list.selected.id)
|
||||||
|
if (index < this.list.data.length - 1) {
|
||||||
|
this.list.selected = this.list.data[index + 1]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (index === this.list.data.length - 1 && this.list.hasNext) {
|
||||||
|
this.list.params.page++
|
||||||
|
await this.handleListAttachments()
|
||||||
|
|
||||||
|
this.list.selected = this.list.data[0]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,294 +0,0 @@
|
||||||
<template>
|
|
||||||
<a-drawer
|
|
||||||
title="附件详情"
|
|
||||||
:width="isMobile() ? '100%' : '480'"
|
|
||||||
closable
|
|
||||||
:visible="visible"
|
|
||||||
destroyOnClose
|
|
||||||
@close="onClose"
|
|
||||||
>
|
|
||||||
<a-row type="flex" align="middle">
|
|
||||||
<a-col :span="24">
|
|
||||||
<div class="attach-detail-img">
|
|
||||||
<div v-show="nonsupportPreviewVisible">此文件不支持预览</div>
|
|
||||||
<a :href="attachment.path" target="_blank">
|
|
||||||
<img :src="attachment.path" v-show="photoPreviewVisible" class="w-full" loading="lazy" />
|
|
||||||
</a>
|
|
||||||
<d-player ref="player" :options="videoOptions" v-show="videoPreviewVisible" class="w-full video-player-box">
|
|
||||||
</d-player>
|
|
||||||
</div>
|
|
||||||
</a-col>
|
|
||||||
<a-divider />
|
|
||||||
<a-col :span="24">
|
|
||||||
<a-list itemLayout="horizontal">
|
|
||||||
<a-list-item>
|
|
||||||
<a-list-item-meta>
|
|
||||||
<template slot="description" v-if="editable">
|
|
||||||
<a-input ref="nameInput" v-model="attachment.name" @blur="doUpdateAttachment" />
|
|
||||||
</template>
|
|
||||||
<template slot="description" v-else>{{ attachment.name }}</template>
|
|
||||||
<span slot="title">
|
|
||||||
附件名:
|
|
||||||
<a href="javascript:void(0);">
|
|
||||||
<a-icon type="edit" @click="handleEditName" />
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</a-list-item-meta>
|
|
||||||
</a-list-item>
|
|
||||||
<a-list-item>
|
|
||||||
<a-list-item-meta :description="attachment.mediaType">
|
|
||||||
<span slot="title">附件类型:</span>
|
|
||||||
</a-list-item-meta>
|
|
||||||
</a-list-item>
|
|
||||||
<a-list-item>
|
|
||||||
<a-list-item-meta :description="attachment.typeProperty">
|
|
||||||
<span slot="title">存储位置:</span>
|
|
||||||
</a-list-item-meta>
|
|
||||||
</a-list-item>
|
|
||||||
<a-list-item>
|
|
||||||
<a-list-item-meta>
|
|
||||||
<template slot="description">
|
|
||||||
{{ attachment.size | fileSizeFormat }}
|
|
||||||
</template>
|
|
||||||
<span slot="title">附件大小:</span>
|
|
||||||
</a-list-item-meta>
|
|
||||||
</a-list-item>
|
|
||||||
<a-list-item v-if="photoPreviewVisible">
|
|
||||||
<a-list-item-meta :description="attachment.height + 'x' + attachment.width">
|
|
||||||
<span slot="title">图片尺寸:</span>
|
|
||||||
</a-list-item-meta>
|
|
||||||
</a-list-item>
|
|
||||||
<a-list-item>
|
|
||||||
<a-list-item-meta>
|
|
||||||
<template slot="description">
|
|
||||||
{{ attachment.createTime | moment }}
|
|
||||||
</template>
|
|
||||||
<span slot="title">上传日期:</span>
|
|
||||||
</a-list-item-meta>
|
|
||||||
</a-list-item>
|
|
||||||
<a-list-item>
|
|
||||||
<a-list-item-meta :description="attachment.path">
|
|
||||||
<span slot="title">
|
|
||||||
普通链接:
|
|
||||||
<a href="javascript:void(0);" @click="handleCopyNormalLink">
|
|
||||||
<a-icon type="copy" />
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</a-list-item-meta>
|
|
||||||
</a-list-item>
|
|
||||||
<a-list-item v-if="photoPreviewVisible">
|
|
||||||
<a-list-item-meta>
|
|
||||||
<span slot="description">![{{ attachment.name }}]({{ attachment.path }})</span>
|
|
||||||
<span slot="title">
|
|
||||||
Markdown 格式:
|
|
||||||
<a href="javascript:void(0);" @click="handleCopyMarkdownLink">
|
|
||||||
<a-icon type="copy" />
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</a-list-item-meta>
|
|
||||||
</a-list-item>
|
|
||||||
</a-list>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
<a-divider class="divider-transparent" />
|
|
||||||
<div class="bottom-control">
|
|
||||||
<a-space>
|
|
||||||
<a-popconfirm
|
|
||||||
title="你确定要添加到图库?"
|
|
||||||
@confirm="handleAddToPhoto"
|
|
||||||
okText="确定"
|
|
||||||
cancelText="取消"
|
|
||||||
v-if="addToPhoto"
|
|
||||||
>
|
|
||||||
<a-button type="dashed">添加到图库</a-button>
|
|
||||||
</a-popconfirm>
|
|
||||||
<a-popconfirm title="你确定要删除该附件?" @confirm="handleDeleteAttachment" okText="确定" cancelText="取消">
|
|
||||||
<ReactiveButton
|
|
||||||
type="danger"
|
|
||||||
@callback="handleDeletedCallback"
|
|
||||||
:loading="deleting"
|
|
||||||
:errored="deleteErrored"
|
|
||||||
text="删除"
|
|
||||||
loadedText="删除成功"
|
|
||||||
erroredText="删除失败"
|
|
||||||
></ReactiveButton>
|
|
||||||
</a-popconfirm>
|
|
||||||
</a-space>
|
|
||||||
</div>
|
|
||||||
</a-drawer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mixin, mixinDevice } from '@/mixins/mixin.js'
|
|
||||||
import attachmentApi from '@/api/attachment'
|
|
||||||
import photoApi from '@/api/photo'
|
|
||||||
import 'vue-dplayer/dist/vue-dplayer.css'
|
|
||||||
import VueDPlayer from 'vue-dplayer'
|
|
||||||
import flvjs from 'flv.js'
|
|
||||||
window.flvjs = flvjs
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'AttachmentDetailDrawer',
|
|
||||||
mixins: [mixin, mixinDevice],
|
|
||||||
components: {
|
|
||||||
'd-player': VueDPlayer
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
editable: false,
|
|
||||||
photo: {},
|
|
||||||
photoPreviewVisible: false,
|
|
||||||
videoPreviewVisible: false,
|
|
||||||
nonsupportPreviewVisible: false,
|
|
||||||
player: {},
|
|
||||||
deleting: false,
|
|
||||||
deleteErrored: false,
|
|
||||||
videoOptions: {
|
|
||||||
lang: 'zh-cn',
|
|
||||||
video: {
|
|
||||||
url: '',
|
|
||||||
type: 'auto'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
model: {
|
|
||||||
prop: 'visible',
|
|
||||||
event: 'close'
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
attachment: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
addToPhoto: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.player = this.$refs.player
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
attachment(newValue) {
|
|
||||||
if (newValue) {
|
|
||||||
this.handleJudgeMediaType(newValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleDeleteAttachment() {
|
|
||||||
this.deleting = true
|
|
||||||
attachmentApi
|
|
||||||
.delete(this.attachment.id)
|
|
||||||
.catch(() => {
|
|
||||||
this.deleteErrored = true
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.deleting = false
|
|
||||||
}, 400)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleDeletedCallback() {
|
|
||||||
this.$emit('delete', this.attachment)
|
|
||||||
this.deleteErrored = false
|
|
||||||
this.onClose()
|
|
||||||
},
|
|
||||||
handleEditName() {
|
|
||||||
this.editable = !this.editable
|
|
||||||
if (this.editable) {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.nameInput.focus()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
doUpdateAttachment() {
|
|
||||||
if (!this.attachment.name) {
|
|
||||||
this.$notification['error']({
|
|
||||||
message: '提示',
|
|
||||||
description: '附件名称不能为空!'
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
attachmentApi.update(this.attachment.id, this.attachment).then(response => {
|
|
||||||
this.$log.debug('Updated attachment', response.data.data)
|
|
||||||
})
|
|
||||||
this.editable = false
|
|
||||||
},
|
|
||||||
handleCopyNormalLink() {
|
|
||||||
const text = `${encodeURI(this.attachment.path)}`
|
|
||||||
this.$copyText(text)
|
|
||||||
.then(message => {
|
|
||||||
this.$log.debug('copy', message)
|
|
||||||
this.$message.success('复制成功!')
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
this.$log.debug('copy.err', err)
|
|
||||||
this.$message.error('复制失败!')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleCopyMarkdownLink() {
|
|
||||||
const text = `![${this.attachment.name}](${encodeURI(this.attachment.path)})`
|
|
||||||
this.$copyText(text)
|
|
||||||
.then(message => {
|
|
||||||
this.$log.debug('copy', message)
|
|
||||||
this.$message.success('复制成功!')
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
this.$log.debug('copy.err', err)
|
|
||||||
this.$message.error('复制失败!')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleAddToPhoto() {
|
|
||||||
this.photo['name'] = this.attachment.name
|
|
||||||
this.photo['thumbnail'] = encodeURI(this.attachment.thumbPath)
|
|
||||||
this.photo['url'] = encodeURI(this.attachment.path)
|
|
||||||
this.photo['takeTime'] = new Date().getTime()
|
|
||||||
photoApi.create(this.photo).then(() => {
|
|
||||||
this.$message.success('添加成功!')
|
|
||||||
this.photo = {}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onClose() {
|
|
||||||
this.$emit('close', false)
|
|
||||||
},
|
|
||||||
handleJudgeMediaType(attachment) {
|
|
||||||
const mediaType = attachment.mediaType
|
|
||||||
// 判断文件类型
|
|
||||||
if (mediaType) {
|
|
||||||
const prefix = mediaType.split('/')[0]
|
|
||||||
|
|
||||||
if (prefix === 'video' || prefix === 'flv') {
|
|
||||||
// 控制各个组件的显示
|
|
||||||
this.handlePreviewVisible(false, true, false)
|
|
||||||
|
|
||||||
// 去除视频地址后面的参数
|
|
||||||
const lastIndex = attachment.path.lastIndexOf('?')
|
|
||||||
const path = attachment.path.substring(0, lastIndex)
|
|
||||||
|
|
||||||
// 设置视频地址
|
|
||||||
this.$set(this.videoOptions.video, 'url', path)
|
|
||||||
this.$log.debug('video url', path)
|
|
||||||
} else if (prefix === 'image') {
|
|
||||||
this.handlePreviewVisible(true, false, false)
|
|
||||||
} else {
|
|
||||||
this.handlePreviewVisible(false, false, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handlePreviewVisible(photo, video, nonsupport) {
|
|
||||||
// 为了更好的使vue监听到组件变化及时刷新,方式修改组件后需要刷新才能显示一下部分
|
|
||||||
this.$set(this, 'photoPreviewVisible', photo)
|
|
||||||
this.$set(this, 'videoPreviewVisible', video)
|
|
||||||
this.$set(this, 'nonsupportPreviewVisible', nonsupport)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -0,0 +1,230 @@
|
||||||
|
<template>
|
||||||
|
<a-modal title="附件详情" :width="isMobile() ? '100%' : '50%'" v-model="modalVisible">
|
||||||
|
<a-row type="flex" :gutter="24">
|
||||||
|
<a-col :xl="9" :lg="9" :md="24" :sm="24" :xs="24">
|
||||||
|
<div class="attach-detail-img pb-3">
|
||||||
|
<a v-if="isImage" :href="attachment.path" target="_blank">
|
||||||
|
<img :src="attachment.path" class="w-full" loading="lazy" />
|
||||||
|
</a>
|
||||||
|
<div v-else>此文件不支持预览</div>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
<a-col :xl="15" :lg="15" :md="24" :sm="24" :xs="24">
|
||||||
|
<a-list itemLayout="horizontal">
|
||||||
|
<a-list-item style="padding-top: 0;">
|
||||||
|
<a-list-item-meta>
|
||||||
|
<template slot="description" v-if="editable">
|
||||||
|
<a-input ref="nameInput" v-model="attachment.name" @blur="handleUpdateName" />
|
||||||
|
</template>
|
||||||
|
<template slot="description" v-else>{{ attachment.name }}</template>
|
||||||
|
<span slot="title">
|
||||||
|
附件名:
|
||||||
|
<a href="javascript:void(0);">
|
||||||
|
<a-icon type="edit" @click="handleEditName" />
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
<a-list-item>
|
||||||
|
<a-list-item-meta :description="attachment.mediaType">
|
||||||
|
<span slot="title">附件类型:</span>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
<a-list-item>
|
||||||
|
<a-list-item-meta :description="attachment.type | typeText">
|
||||||
|
<span slot="title">存储位置:</span>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
<a-list-item>
|
||||||
|
<a-list-item-meta>
|
||||||
|
<template slot="description">
|
||||||
|
{{ attachment.size | fileSizeFormat }}
|
||||||
|
</template>
|
||||||
|
<span slot="title">附件大小:</span>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
<a-list-item v-if="isImage">
|
||||||
|
<a-list-item-meta :description="attachment.height + 'x' + attachment.width">
|
||||||
|
<span slot="title">图片尺寸:</span>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
<a-list-item>
|
||||||
|
<a-list-item-meta>
|
||||||
|
<template slot="description">
|
||||||
|
{{ attachment.createTime | moment }}
|
||||||
|
</template>
|
||||||
|
<span slot="title">上传日期:</span>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
<a-list-item>
|
||||||
|
<a-list-item-meta>
|
||||||
|
<template #description>
|
||||||
|
<a :href="attachment.path" target="_blank">{{ attachment.path }}</a>
|
||||||
|
</template>
|
||||||
|
<span slot="title">
|
||||||
|
普通链接:
|
||||||
|
<a href="javascript:void(0);" @click="handleCopyLink(`${encodeURI(attachment.path)}`)">
|
||||||
|
<a-icon type="copy" />
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
<a-list-item v-if="isImage">
|
||||||
|
<a-list-item-meta>
|
||||||
|
<span slot="description">![{{ attachment.name }}]({{ attachment.path }})</span>
|
||||||
|
<span slot="title">
|
||||||
|
Markdown 格式:
|
||||||
|
<a
|
||||||
|
href="javascript:void(0);"
|
||||||
|
@click="handleCopyLink(`![${attachment.name}](${encodeURI(attachment.path)})`)"
|
||||||
|
>
|
||||||
|
<a-icon type="copy" />
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
</a-list>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<slot name="extraFooter" />
|
||||||
|
<a-popconfirm title="你确定要删除该附件?" @confirm="handleDelete" okText="确定" cancelText="取消">
|
||||||
|
<ReactiveButton
|
||||||
|
type="danger"
|
||||||
|
@callback="handleDeletedCallback"
|
||||||
|
:loading="deleting"
|
||||||
|
:errored="deleteErrored"
|
||||||
|
text="删除"
|
||||||
|
icon="delete"
|
||||||
|
loadedText="删除成功"
|
||||||
|
erroredText="删除失败"
|
||||||
|
></ReactiveButton>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mixin, mixinDevice } from '@/mixins/mixin.js'
|
||||||
|
import attachmentApi from '@/api/attachment'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AttachmentDetailModal',
|
||||||
|
mixins: [mixin, mixinDevice],
|
||||||
|
filters: {
|
||||||
|
typeText(type) {
|
||||||
|
return type ? attachmentApi.type[type].text : ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
attachment: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editable: false,
|
||||||
|
deleting: false,
|
||||||
|
deleteErrored: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
modalVisible: {
|
||||||
|
get() {
|
||||||
|
return this.visible
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('update:visible', value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isImage() {
|
||||||
|
if (!this.attachment || !this.attachment.mediaType) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return this.attachment.mediaType.startsWith('image')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* Deletes the attachment
|
||||||
|
*/
|
||||||
|
async handleDelete() {
|
||||||
|
try {
|
||||||
|
this.deleting = true
|
||||||
|
|
||||||
|
await attachmentApi.delete(this.attachment.id)
|
||||||
|
} catch (error) {
|
||||||
|
this.$log.error(error)
|
||||||
|
this.deleteErrored = true
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.deleting = false
|
||||||
|
}, 400)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the deletion callback event
|
||||||
|
*/
|
||||||
|
handleDeletedCallback() {
|
||||||
|
this.$emit('delete', this.attachment)
|
||||||
|
this.deleteErrored = false
|
||||||
|
this.modalVisible = false
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the edit name input
|
||||||
|
*/
|
||||||
|
handleEditName() {
|
||||||
|
this.editable = !this.editable
|
||||||
|
if (this.editable) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.nameInput.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the attachment name
|
||||||
|
*/
|
||||||
|
async handleUpdateName() {
|
||||||
|
if (!this.attachment.name) {
|
||||||
|
this.$notification['error']({
|
||||||
|
message: '提示',
|
||||||
|
description: '附件名称不能为空!'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await attachmentApi.update(this.attachment.id, this.attachment)
|
||||||
|
} catch (error) {
|
||||||
|
this.$log.error(error)
|
||||||
|
} finally {
|
||||||
|
this.editable = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the copy link event
|
||||||
|
* @param {String} link
|
||||||
|
*/
|
||||||
|
handleCopyLink(link) {
|
||||||
|
this.$copyText(link)
|
||||||
|
.then(message => {
|
||||||
|
this.$log.debug('copy', message)
|
||||||
|
this.$message.success('复制成功!')
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
this.$log.debug('copy.err', err)
|
||||||
|
this.$message.error('复制失败!')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -47,12 +47,12 @@
|
||||||
></a-pagination>
|
></a-pagination>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<AttachmentDetailDrawer
|
<!-- <AttachmentDetailDrawer
|
||||||
v-model="detailVisible"
|
v-model="detailVisible"
|
||||||
v-if="selectedAttachment"
|
v-if="selectedAttachment"
|
||||||
:attachment="selectedAttachment"
|
:attachment="selectedAttachment"
|
||||||
@delete="handleListAttachments"
|
@delete="handleListAttachments"
|
||||||
/>
|
/> -->
|
||||||
<a-divider class="divider-transparent" />
|
<a-divider class="divider-transparent" />
|
||||||
<div class="bottom-control">
|
<div class="bottom-control">
|
||||||
<a-button @click="uploadVisible = true" type="primary">上传附件</a-button>
|
<a-button @click="uploadVisible = true" type="primary">上传附件</a-button>
|
||||||
|
@ -67,14 +67,14 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mixin, mixinDevice } from '@/mixins/mixin.js'
|
import { mixin, mixinDevice } from '@/mixins/mixin.js'
|
||||||
import AttachmentDetailDrawer from './AttachmentDetailDrawer'
|
// import AttachmentDetailDrawer from './AttachmentDetailDrawer'
|
||||||
import attachmentApi from '@/api/attachment'
|
import attachmentApi from '@/api/attachment'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AttachmentDrawer',
|
name: 'AttachmentDrawer',
|
||||||
mixins: [mixin, mixinDevice],
|
mixins: [mixin, mixinDevice],
|
||||||
components: {
|
components: {
|
||||||
AttachmentDetailDrawer
|
// AttachmentDetailDrawer
|
||||||
},
|
},
|
||||||
model: {
|
model: {
|
||||||
prop: 'visible',
|
prop: 'visible',
|
||||||
|
|
|
@ -574,9 +574,7 @@ export default {
|
||||||
this.pagination.total = response.data.data.total
|
this.pagination.total = response.data.data.total
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
|
||||||
this.postsLoading = false
|
this.postsLoading = false
|
||||||
}, 200)
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleListCategories() {
|
handleListCategories() {
|
||||||
|
|
Loading…
Reference in New Issue