1717
1818<template >
1919 <div class =" form-layout" v-ctrl-enter =" handleSubmit" >
20- <span v-if =" uploadPercentage > 0 " >
20+ <span v-if =" uploading " >
2121 <loading-outlined />
2222 {{ $t('message.upload.file.processing') }}
2323 <a-progress :percent =" uploadPercentage" />
2424 </span >
25+ <div v-else-if =" ssvmCertUntrusted" class =" ssvm-cert-warning" >
26+ <a-alert
27+ type =" warning"
28+ show-icon
29+ :message =" $t('message.ssvm.cert.untrusted')"
30+ :description =" $t('message.ssvm.cert.trust.instructions')" />
31+ <div class =" action-button" style =" margin-top : 16px " >
32+ <a-button @click =" closeAction" >{{ $t('label.cancel') }}</a-button >
33+ <a :href =" ssvmOrigin" target =" _blank" rel =" noopener noreferrer" >
34+ <a-button >{{ $t('label.ssvm.open.cert.page') }}</a-button >
35+ </a >
36+ <a-button type =" primary" :loading =" loading" @click =" retryUpload" >
37+ {{ $t('label.retry.upload') }}
38+ </a-button >
39+ </div >
40+ </div >
2541 <a-spin :spinning =" loading" v-else >
2642 <a-form
2743 :ref =" formRef"
@@ -178,7 +194,10 @@ export default {
178194 customDiskOffering: false ,
179195 isCustomizedDiskIOps: false ,
180196 loading: false ,
181- uploadPercentage: 0
197+ uploading: false ,
198+ uploadPercentage: 0 ,
199+ ssvmCertUntrusted: false ,
200+ ssvmOrigin: ' '
182201 }
183202 },
184203 beforeCreate () {
@@ -267,6 +286,70 @@ export default {
267286 this .form .account = accountName
268287 this .account = accountName
269288 },
289+ async probeSsvmCert (origin ) {
290+ try {
291+ await fetch (origin, { method: ' HEAD' , mode: ' no-cors' })
292+ return true
293+ } catch (e) {
294+ return false
295+ }
296+ },
297+ async retryUpload () {
298+ this .loading = true
299+ const trusted = await this .probeSsvmCert (this .ssvmOrigin )
300+ this .loading = false
301+ if (! trusted) {
302+ this .$message .warning (this .$t (' message.ssvm.cert.still.untrusted' ))
303+ return
304+ }
305+ this .ssvmCertUntrusted = false
306+ this .handleUpload ()
307+ },
308+ handleUpload () {
309+ const { fileList } = this
310+ if (this .fileList .length > 1 ) {
311+ this .$notification .error ({
312+ message: this .$t (' message.upload.volume.failed' ),
313+ description: this .$t (' message.upload.file.limit' ),
314+ duration: 0
315+ })
316+ }
317+ const formData = new FormData ()
318+ fileList .forEach (file => {
319+ formData .append (' files[]' , file)
320+ })
321+ this .uploading = true
322+ this .uploadPercentage = 0
323+ axios .post (this .uploadParams .postURL ,
324+ formData,
325+ {
326+ headers: {
327+ ' content-type' : ' multipart/form-data' ,
328+ ' x-signature' : this .uploadParams .signature ,
329+ ' x-expires' : this .uploadParams .expires ,
330+ ' x-metadata' : this .uploadParams .metadata
331+ },
332+ onUploadProgress : (progressEvent ) => {
333+ this .uploadPercentage = Number (parseFloat (100 * progressEvent .loaded / progressEvent .total ).toFixed (1 ))
334+ },
335+ timeout: 86400000
336+ }).then ((json ) => {
337+ this .$notification .success ({
338+ message: this .$t (' message.success.upload' ),
339+ description: this .$t (' message.success.upload.volume.description' )
340+ })
341+ this .closeAction ()
342+ }).catch (e => {
343+ this .$notification .error ({
344+ message: this .$t (' message.upload.failed' ),
345+ description: ` ${ this .$t (' message.upload.volume.failed' )} - ${ e} ` ,
346+ duration: 0
347+ })
348+ }).finally (() => {
349+ this .uploading = false
350+ this .loading = false
351+ })
352+ },
270353 handleSubmit (e ) {
271354 e .preventDefault ()
272355 if (this .loading ) return
@@ -286,49 +369,15 @@ export default {
286369 }
287370 params .domainId = this .domainId
288371 this .loading = true
289- api (' getUploadParamsForVolume' , params).then (json => {
372+ api (' getUploadParamsForVolume' , params).then (async json => {
290373 this .uploadParams = json .postuploadvolumeresponse ? .getuploadparams || ' '
291- const { fileList } = this
292- if (this .fileList .length > 1 ) {
293- this .$notification .error ({
294- message: this .$t (' message.upload.volume.failed' ),
295- description: this .$t (' message.upload.file.limit' ),
296- duration: 0
297- })
374+ this .ssvmOrigin = new URL (this .uploadParams .postURL ).origin
375+ const trusted = await this .probeSsvmCert (this .ssvmOrigin )
376+ if (! trusted) {
377+ this .ssvmCertUntrusted = true
378+ return
298379 }
299- const formData = new FormData ()
300- fileList .forEach (file => {
301- formData .append (' files[]' , file)
302- })
303- this .uploadPercentage = 0
304- axios .post (this .uploadParams .postURL ,
305- formData,
306- {
307- headers: {
308- ' content-type' : ' multipart/form-data' ,
309- ' x-signature' : this .uploadParams .signature ,
310- ' x-expires' : this .uploadParams .expires ,
311- ' x-metadata' : this .uploadParams .metadata
312- },
313- onUploadProgress : (progressEvent ) => {
314- this .uploadPercentage = Number (parseFloat (100 * progressEvent .loaded / progressEvent .total ).toFixed (1 ))
315- },
316- timeout: 86400000
317- }).then ((json ) => {
318- this .$notification .success ({
319- message: this .$t (' message.success.upload' ),
320- description: this .$t (' message.success.upload.volume.description' )
321- })
322- this .closeAction ()
323- }).catch (e => {
324- this .$notification .error ({
325- message: this .$t (' message.upload.failed' ),
326- description: ` ${ this .$t (' message.upload.volume.failed' )} - ${ e} ` ,
327- duration: 0
328- })
329- }).finally (() => {
330- this .loading = false
331- })
380+ this .handleUpload ()
332381 }).catch (e => {
333382 this .$notification .error ({
334383 message: this .$t (' message.upload.failed' ),
0 commit comments