上传组件支持常见格式的文件

master
toesbieya 6 years ago
parent aea61edb66
commit b640dcdf85
  1. 0
      vue/public/static/img/403.gif
  2. 0
      vue/public/static/img/404.png
  3. 0
      vue/public/static/img/404_cloud.png
  4. BIN
      vue/public/static/img/fileType/docx.png
  5. BIN
      vue/public/static/img/fileType/pdf.png
  6. BIN
      vue/public/static/img/fileType/ppt.png
  7. BIN
      vue/public/static/img/fileType/rar.png
  8. BIN
      vue/public/static/img/fileType/txt.png
  9. BIN
      vue/public/static/img/fileType/xlsx.png
  10. BIN
      vue/public/static/img/fileType/zip.png
  11. 0
      vue/public/static/img/sprite.1.2.4.png
  12. 225
      vue/src/components/PuzzleVerify/main.vue
  13. 223
      vue/src/components/PuzzleVerify/style.scss
  14. 154
      vue/src/components/UploadFile/index.vue
  15. 36
      vue/src/components/UploadFile/style.scss
  16. 9
      vue/src/config/index.js
  17. 6
      vue/src/mixins/bizDocumentDialogMixin.js
  18. 21
      vue/src/utils/file.js
  19. 80
      vue/src/utils/validate.js
  20. 2
      vue/src/views/app/403.vue
  21. 8
      vue/src/views/app/404.vue
  22. 8
      vue/vue.config.js

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 160 KiB

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

@ -301,227 +301,4 @@
}
</script>
<style lang="scss">
.puzzle-container {
position: absolute;
box-shadow: 0 0 10px #cccccc;
border: 1px solid #cccccc;
background: #ffffff;
.puzzle-text-container {
&:hover {
overflow: visible !important;
}
.puzzle-text-tip {
position: absolute;
top: -32px;
left: 10px;
border-radius: 2px;
padding: 0 4px;
height: 22px;
min-width: 50px;
line-height: 22px;
background-color: #5F5F5F;
white-space: nowrap;
font-size: 12px;
text-align: center;
color: white;
&::before {
display: block;
position: absolute;
bottom: -6px;
left: 0;
content: '';
border-style: solid;
border-width: 4px 6px;
border-color: #5F5F5F transparent transparent #5F5F5F;
width: 0;
height: 0;
}
}
}
.puzzle-view {
position: relative;
overflow: hidden;
margin: 10px 10px 0;
.puzzle-image-loading {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: #e5e5e5;
padding-top: 10%;
&__icon {
background-size: 764.70588%;
background-position: 0 70.70218%;
margin: 11% auto 10px;
width: 34px;
height: 26px;
overflow: hidden;
background-repeat: no-repeat;
background-image: url(~@/assets/images/sprite.1.2.4.png);
}
&__text {
text-align: center;
font-size: 14px;
margin-bottom: 1%;
color: #b2b2b2;
}
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
.puzzle-lost-box {
position: absolute;
left: 0;
top: 0;
}
canvas {
position: absolute;
left: 0;
top: 0;
z-index: 22;
}
.verify-result {
position: absolute;
z-index: 999;
color: white;
height: 24px;
line-height: 24px;
left: 0;
bottom: -25px;
font-size: 14px;
width: 100%;
transition: bottom 0.3s;
text-indent: 16px;
&.verify-success {
background-color: $--color-success
}
&.verify-fail {
background-color: $--color-danger
}
&.show-result {
bottom: 0;
}
}
}
.slider-container {
position: relative;
margin: 5.39% 3.24%;
width: 93.52%;
padding: 0 0 13.67% 0;
background-color: white;
background-size: 100%;
background-position: 0 0;
background-repeat: no-repeat;
background-image: url(~@/assets/images/sprite.1.2.4.png);
.slider-track {
position: absolute;
top: 50%;
margin: -19px 0 0 0;
padding: 0 0 0 25%;
.slider-tip {
position: relative;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity .5s;
line-height: 38px;
font-size: 14px;
text-align: center;
white-space: nowrap;
color: #88949d;
}
}
.slider-btn {
position: absolute;
margin: -4.62% 0 0 -2.31%;
width: 25.38%;
padding: 0 0 25.38% 0;
cursor: pointer;
background-size: 393.93939%;
background-repeat: no-repeat;
background-image: url(~@/assets/images/sprite.1.2.4.png);
}
}
.puzzle-footer {
position: relative;
border-top: 1px solid #EEEEEE;
width: 100%;
margin: 0;
padding: 0 0 17.27% 0;
.puzzle-small {
position: absolute;
left: 5.1%;
top: 50%;
margin-top: -4.13%;
padding: 0 0 8.27% 0;
width: 40.45%;
height: 0;
.puzzle-close, .puzzle-refresh {
margin-left: 8.9%;
width: 17.8%;
cursor: pointer;
text-decoration: none;
vertical-align: top;
position: relative;
display: inline-block;
height: 0;
padding-bottom: 17.8%;
background-repeat: no-repeat;
background-image: url(~@/assets/images/sprite.1.2.4.png);
overflow: hidden;
background-size: 1300%;
}
.puzzle-close {
margin-left: 0;
background-position: 0 44.86874%;
}
.puzzle-refresh {
background-position: 0 81.38425%;
}
}
}
}
.puzzle-shake {
animation: shake 0.2s linear 3 both;
}
@keyframes shake {
25% {
transform: translate3d(-6px, 0, 0)
}
75% {
transform: translate3d(6px, 0, 0)
}
100% {
transform: translate3d(0, 0, 0)
}
}
</style>
<style lang="scss" src="./style.scss"></style>

@ -0,0 +1,223 @@
.puzzle-container {
position: absolute;
box-shadow: 0 0 10px #cccccc;
border: 1px solid #cccccc;
background: #ffffff;
.puzzle-text-container {
&:hover {
overflow: visible !important;
}
.puzzle-text-tip {
position: absolute;
top: -32px;
left: 10px;
border-radius: 2px;
padding: 0 4px;
height: 22px;
min-width: 50px;
line-height: 22px;
background-color: #5F5F5F;
white-space: nowrap;
font-size: 12px;
text-align: center;
color: white;
&::before {
display: block;
position: absolute;
bottom: -6px;
left: 0;
content: '';
border-style: solid;
border-width: 4px 6px;
border-color: #5F5F5F transparent transparent #5F5F5F;
width: 0;
height: 0;
}
}
}
.puzzle-view .puzzle-image-loading__icon,
.slider-container,
.slider-container .slider-btn,
.puzzle-footer .puzzle-small .puzzle-close,
.puzzle-footer .puzzle-small .puzzle-refresh {
background-repeat: no-repeat;
background-image: url(/static/img/sprite.1.2.4.png);
}
.puzzle-view {
position: relative;
overflow: hidden;
margin: 10px 10px 0;
.puzzle-image-loading {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: #e5e5e5;
padding-top: 10%;
&__icon {
background-size: 764.70588%;
background-position: 0 70.70218%;
margin: 11% auto 10px;
width: 34px;
height: 26px;
overflow: hidden;
}
&__text {
text-align: center;
font-size: 14px;
margin-bottom: 1%;
color: #b2b2b2;
}
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
.puzzle-lost-box {
position: absolute;
left: 0;
top: 0;
}
canvas {
position: absolute;
left: 0;
top: 0;
z-index: 22;
}
.verify-result {
position: absolute;
z-index: 999;
color: white;
height: 24px;
line-height: 24px;
left: 0;
bottom: -25px;
font-size: 14px;
width: 100%;
transition: bottom 0.3s;
text-indent: 16px;
&.verify-success {
background-color: $--color-success
}
&.verify-fail {
background-color: $--color-danger
}
&.show-result {
bottom: 0;
}
}
}
.slider-container {
position: relative;
margin: 5.39% 3.24%;
width: 93.52%;
padding: 0 0 13.67% 0;
background-color: white;
background-size: 100%;
background-position: 0 0;
.slider-track {
position: absolute;
top: 50%;
margin: -19px 0 0 0;
padding: 0 0 0 25%;
.slider-tip {
position: relative;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity .5s;
line-height: 38px;
font-size: 14px;
text-align: center;
white-space: nowrap;
color: #88949d;
}
}
.slider-btn {
position: absolute;
margin: -4.62% 0 0 -2.31%;
width: 25.38%;
padding: 0 0 25.38% 0;
cursor: pointer;
background-size: 393.93939%;
}
}
.puzzle-footer {
position: relative;
border-top: 1px solid #EEEEEE;
width: 100%;
margin: 0;
padding: 0 0 17.27% 0;
.puzzle-small {
position: absolute;
left: 5.1%;
top: 50%;
margin-top: -4.13%;
padding: 0 0 8.27% 0;
width: 40.45%;
height: 0;
.puzzle-close, .puzzle-refresh {
margin-left: 8.9%;
width: 17.8%;
cursor: pointer;
text-decoration: none;
vertical-align: top;
position: relative;
display: inline-block;
height: 0;
padding-bottom: 17.8%;
overflow: hidden;
background-size: 1300%;
}
.puzzle-close {
margin-left: 0;
background-position: 0 44.86874%;
}
.puzzle-refresh {
background-position: 0 81.38425%;
}
}
}
}
.puzzle-shake {
animation: shake 0.2s linear 3 both;
}
@keyframes shake {
25% {
transform: translate3d(-6px, 0, 0)
}
75% {
transform: translate3d(6px, 0, 0)
}
100% {
transform: translate3d(0, 0, 0)
}
}

@ -21,32 +21,24 @@
@mouseenter="e => handleBlockMouseEnter(e,file)"
@mouseleave="handleBlockMouseLeave"
>
<span
v-if="showPreview(file)"
class="el-upload-list__item-preview"
@click="() => preview(file)"
>
<span class="el-upload-list__item-preview" @click="() => preview(file)">
<i class="el-icon-zoom-in"/>
</span>
<span
v-if="showDownload(file)"
class="el-upload-list__item-delete"
@click="() => download(file)"
>
<span class="el-upload-list__item-delete" @click="() => download(file)">
<i class="el-icon-download"/>
</span>
<span
v-if="!disabled"
class="el-upload-list__item-delete"
@click="() => remove(file)"
>
<span v-if="!disabled" class="el-upload-list__item-delete" @click="() => remove(file)">
<i class="el-icon-delete"/>
</span>
</span>
<img v-if="file.status === 'success'" :src="file.url" class="el-upload-list__item-thumbnail">
<label class="el-upload-list__item-status-label">
<i class="el-icon-upload-success el-icon-check"/>
</label>
<template v-if="file.status === 'success'">
<img :src="file.url" class="el-upload-list__item-thumbnail">
<label class="el-upload-list__item-status-label">
<i class="el-icon-upload-success el-icon-check"/>
</label>
</template>
<div v-if="file.status === 'uploading'" class="progress-mask">
<el-progress :percentage="file.percentage" type="circle"/>
</div>
@ -59,16 +51,44 @@
<script>
/*
* 直传七牛云
* 传入fileList自动拼接七牛云外链前缀
* successremove事件中的file.url均不带七牛云外链前缀
* 传入fileList自动拼接七牛云外链前缀并增加downloadUrl属性图片类型的文件url与downloadUrl相同
* successremove事件中的file.downloadUrl均不带七牛云外链前缀
* */
import axios from 'axios'
import {attachmentPrefix} from '@/config'
import {elError} from "@/utils/message"
import {debounce, isEmpty} from '@/utils'
import {isImage} from "@/utils/validate"
import {deleteUpload, download, upload, autoCompleteUrl} from "@/utils/file"
import {numberFormatter} from "@/filter"
import {debounce, isEmpty} from '@/utils'
import {elError} from "@/utils/message"
import {isImage, isDoc, isPdf, isPpt, isRar, isXls, isTxt, isZip} from "@/utils/validate"
import {preview, deleteUpload, download, upload, autoCompleteUrl} from "@/utils/file"
function parseMaxSize(maxSize) {
if (typeof maxSize === 'number') {
return maxSize
}
const map = {KB: 1024, MB: 1024 * 1024},
upper = maxSize.toUpperCase(),
num = upper.replace(/[^0-9]/ig, ""),
unit = upper.replace(num, "")
return parseInt(num) * (map[unit] || 1)
}
function isFileTypeSupported(fileType) {
return [isImage, isDoc, isPdf, isPpt, isRar, isXls, isTxt, isZip].some(i => i(fileType))
}
function getCoverImage(url, fileType) {
if (isImage(fileType)) return url
if (isDoc(fileType)) return '/static/img/fileType/docx.png'
if (isPdf(fileType)) return '/static/img/fileType/pdf.png'
if (isPpt(fileType)) return '/static/img/fileType/ppt.png'
if (isRar(fileType)) return '/static/img/fileType/rar.png'
if (isXls(fileType)) return '/static/img/fileType/xls.png'
if (isTxt(fileType)) return '/static/img/fileType/txt.png'
if (isZip(fileType)) return '/static/img/fileType/zip.png'
}
export default {
name: 'UploadFile',
@ -96,7 +116,7 @@
return this.disabled || this.count >= this.limit
},
previewUrlList() {
return this.data ? this.data.map(i => i.url) : []
return this.data ? this.data.map(i => i.downloadUrl) : []
}
},
@ -105,32 +125,17 @@
immediate: true,
handler(fileList) {
if (isEmpty(fileList)) {
this.data = []
return
return this.data = []
}
this.data = [...this.fileList.map(file => ({...file, url: autoCompleteUrl(file.url)}))]
this.data = [...this.fileList.map(file => {
const downloadUrl = autoCompleteUrl(file.url)
return {...file, url: getCoverImage(downloadUrl, file.name), downloadUrl}
})]
}
}
},
methods: {
showPreview(file) {
return file.name && isImage(file.name)
},
showDownload(file) {
return file.name && !isImage(file.name)
},
parseMaxSize(maxSize) {
if (typeof maxSize === 'number') {
return maxSize
}
const map = {KB: 1024, MB: 1024 * 1024}
let upper = maxSize.toUpperCase()
let num = upper.replace(/[^0-9]/ig, "")
let unit = upper.replace(num, "")
return parseInt(num) * (map[unit] || 1)
},
//仿el-tabletooltip
handleBlockMouseEnter(event, file) {
const tooltip = this.$refs.tooltip
@ -153,24 +158,26 @@
remove(file) {
//
//
if (!file.raw) this.$emit('remove', {...file, url: file.url.replace(attachmentPrefix, '')})
if (!file.raw) this.$emit('remove', {url: file.downloadUrl.replace(attachmentPrefix, '')})
//
else if (file.response && !file.response.err) deleteUpload(file.raw.key)
this.$refs.upload.handleRemove(file)
let index = this.data.findIndex(i => i.url === file.url)
const index = this.data.findIndex(i => i.downloadUrl === file.downloadUrl)
if (index > -1) this.data.splice(index, 1)
},
//
preview(file) {
const index = this.data.findIndex(i => i.url === file.url)
if (!isImage(file.name)) return preview(file.downloadUrl)
const index = this.data.findIndex(i => i.downloadUrl === file.downloadUrl)
this.$image({index, urlList: this.previewUrlList})
},
//
download(file) {
download(file.url, file.name)
download(file.downloadUrl, file.name)
},
//
@ -180,7 +187,9 @@
//successkey
success(res, file) {
file.url = getCoverImage(file.url, file.name)
file.raw.key = res.key
file.downloadUrl = autoCompleteUrl(res.key)
this.data.push(file)
this.$emit('success', file, res)
},
@ -194,11 +203,11 @@
//
beforeUpload(file) {
if (!file.type.includes('image')) {
elError('暂时只支持图片上传')
if (!isFileTypeSupported(file.name)) {
elError('只支持图片、word、pdf、ppt、rar、excel、txt、zip类型的文件')
return false
}
const maxSize = this.parseMaxSize(this.maxSize)
const maxSize = parseMaxSize(this.maxSize)
if (file.size > maxSize) {
elError(`${file.name}的大小超出${numberFormatter(maxSize)}`)
return false
@ -229,41 +238,4 @@
}
</script>
<style lang="scss">
.disabled .el-upload--picture-card {
display: none;
}
.el-upload-list--picture-card {
.el-progress {
width: 100%;
height: 100%;
.el-progress-circle {
height: 100% !important;
width: 100% !important;
}
}
.progress-mask {
position: absolute;
top: 0;
height: 100%;
width: 100%;
background-color: #fff;
opacity: 0.9;
.el-progress__text {
color: $--color-primary;
}
}
}
.el-upload-list__item-thumbnail {
object-fit: cover;
}
.upload-tooltip {
max-width: 146px;
}
</style>
<style lang="scss" src="./style.scss"></style>

@ -0,0 +1,36 @@
.disabled .el-upload--picture-card {
display: none;
}
.el-upload-list--picture-card {
.el-progress {
width: 100%;
height: 100%;
.el-progress-circle {
height: 100% !important;
width: 100% !important;
}
}
.progress-mask {
position: absolute;
top: 0;
height: 100%;
width: 100%;
background-color: #fff;
opacity: 0.9;
.el-progress__text {
color: $--color-primary;
}
}
}
.el-upload-list__item-thumbnail {
object-fit: cover;
}
.upload-tooltip {
max-width: 146px;
}

@ -1,3 +1,5 @@
const isDevelopment = process.env.NODE_ENV === 'development'
module.exports = {
title: 'BiuBiuBiu~',
@ -8,7 +10,7 @@ module.exports = {
routerMode: 'history',
//socket连接地址
socketUrl: process.env.NODE_ENV === 'development' ? 'localhost:12580' : 'wss://toesbieya.cn',
socketUrl: isDevelopment ? 'localhost:12580' : 'wss://toesbieya.cn',
sidebarLogoUrl: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png',
@ -26,9 +28,12 @@ module.exports = {
//七牛云上传地址
attachmentUploadUrl: 'https://upload.qiniup.com',
//附件上传后的预览地址前缀
//附件上传后的存储地址前缀
attachmentPrefix: 'https://static.toesbieya.cn/',
//文件预览接口前缀
filePreviewPrefix: isDevelopment ? 'http://localhost:8012/file/preview' : 'https://preview.toesbieya.cn',
//省市地区json数据请求地址
regionDataUrl: '/static/json/region-pcas.json'
}

@ -126,7 +126,7 @@ export default {
this.$refs.form.validate(v => {
if (!v) return
if (this.validate) {
let valid = this.validate()
const valid = this.validate()
if (!isEmpty(valid)) return elAlert(valid)
}
elConfirm('确认提交审核?')
@ -251,7 +251,7 @@ export default {
this.needSearch && this.$emit('search')
//删除未保存的上传附件
let deleteArr = []
const deleteArr = []
if (this.form.uploadImageList.length > 0) {
deleteArr.push(...this.form.uploadImageList.map(i => i.url))
}
@ -278,7 +278,7 @@ export default {
},
removeUpload(file) {
this.form.deleteImageList.push(file.url)
let index = this.form.uploadImageList.findIndex(i => i.url === file.url)
const index = this.form.uploadImageList.findIndex(i => i.url === file.url)
if (index > -1) this.form.uploadImageList.splice(index, 1)
}
}

@ -1,9 +1,7 @@
import request from '@/config/request'
import {attachmentUploadUrl, attachmentPrefix} from '@/config'
import {attachmentUploadUrl, attachmentPrefix, filePreviewPrefix} from '@/config'
import {isEmpty, timeFormat} from "@/utils"
const baseUrl = '/file'
const defaultOptions = {
headers: {"Content-Type": "multipart/form-data"},
generateKey(filename) {
@ -14,9 +12,20 @@ const defaultOptions = {
}
}
//文件预览
export function preview(url) {
const anchor = document.createElement('a')
anchor.style.visibility = 'hidden'
anchor.href = `${filePreviewPrefix}/onlinePreview?url=${encodeURIComponent(url)}`
anchor.target = '_blank'
document.body.appendChild(anchor)
anchor.click()
document.body.removeChild(anchor)
}
//获取七牛云直传需要的token
export function getToken() {
return request.get(baseUrl + '/getToken').then(({data}) => data.data)
return request.get('/file/getToken').then(({data}) => data.data)
}
//下载文件
@ -36,13 +45,15 @@ export function download(url, name) {
//删除已上传的文件
export function deleteUpload(url) {
return request.get(baseUrl + '/delete?url=' + encodeURIComponent(url))
return request.get('/file/delete?url=' + encodeURIComponent(url))
}
//七牛云直传
export function upload(blob, filename, options = {}) {
return getToken()
.then(token => {
if (!options.generateKey) options.generateKey = defaultOptions.generateKey
const param = new FormData()
param.append('token', token)
param.append('key', options.generateKey(filename))

@ -1,66 +1,50 @@
/**
* @param {string} url
* @returns {Boolean}
*/
export function validURL(url) {
const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
return reg.test(url)
}
export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validLowerCase(str) {
const reg = /^[a-z]+$/
return reg.test(str)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUpperCase(str) {
const reg = /^[A-Z]+$/
return reg.test(str)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validAlphabets(str) {
const reg = /^[A-Za-z]+$/
return reg.test(str)
}
/**
* @param {string} email
* @returns {Boolean}
*/
export function validEmail(email) {
const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return reg.test(email)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function isString(str) {
return typeof str === 'string' || str instanceof String
}
export function isInteger(v) {
let t = parseFloat(v)
const t = parseFloat(v)
return t.toString() !== 'NaN' && t < 2147483647 && t > -2147483648
}
export function isImage(str) {
let reg = /\.(png|jpg|gif|jpeg|webp|bmp)$/
return reg.test(str.toLowerCase())
export function isImage(suffix) {
const reg = /\.(png|jpg|gif|jpeg|webp|bmp)$/
return reg.test(suffix.toLowerCase())
}
export function isDoc(suffix) {
return /\.(doc|docx)$/.test(suffix.toLowerCase())
}
export function isPdf(suffix) {
return /\.pdf$/.test(suffix.toLowerCase())
}
export function isPpt(suffix) {
return /\.(ppt|pptx)$/.test(suffix.toLowerCase())
}
export function isRar(suffix) {
return /\.rar$/.test(suffix.toLowerCase())
}
export function isXls(suffix) {
return /\.(xls|xlsx)$/.test(suffix.toLowerCase())
}
export function isTxt(suffix) {
return /\.txt$/.test(suffix.toLowerCase())
}
export function isZip(suffix) {
return /\.zip$/.test(suffix.toLowerCase())
}

@ -2,7 +2,7 @@
<div class="error-container">
<div>
<div class="pic">
<img alt="403" height="428" src="@/assets/images/403.gif" width="313">
<img alt="403" height="428" src="static/img/403.gif" width="313">
</div>
<div class="bullshit">
<div class="bullshit__oops">Oops!</div>

@ -2,10 +2,10 @@
<div class="error-container">
<div>
<div class="pic">
<img alt="404" class="pic__parent" src="@/assets/images/404.png">
<img alt="404" class="pic__child left" src="@/assets/images/404_cloud.png">
<img alt="404" class="pic__child mid" src="@/assets/images/404_cloud.png">
<img alt="404" class="pic__child right" src="@/assets/images/404_cloud.png">
<img alt="404" class="pic__parent" src="static/img/404.png">
<img alt="404" class="pic__child left" src="static/img/404_cloud.png">
<img alt="404" class="pic__child mid" src="static/img/404_cloud.png">
<img alt="404" class="pic__child right" src="static/img/404_cloud.png">
</div>
<div class="bullshit">
<div class="bullshit__oops">Oops!</div>

@ -28,10 +28,10 @@ module.exports = {
},
proxy: {
[settings.apiPrefix]: {
target: 'http://localhost:8081', // 后台接口域名
ws: true, //如果要代理 websockets,配置这个参数
secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, //是否跨域
target: 'http://localhost:8081', //后台接口域名
ws: true, //如果要代理 websockets,配置这个参数
secure: false, //如果是https接口,需要配置这个参数
changeOrigin: true, //是否跨域
pathRewrite: {
[`^${settings.apiPrefix}`]: ''
}

Loading…
Cancel
Save