diff --git a/vue/src/assets/images/403.gif b/vue/public/static/img/403.gif similarity index 100% rename from vue/src/assets/images/403.gif rename to vue/public/static/img/403.gif diff --git a/vue/src/assets/images/404.png b/vue/public/static/img/404.png similarity index 100% rename from vue/src/assets/images/404.png rename to vue/public/static/img/404.png diff --git a/vue/src/assets/images/404_cloud.png b/vue/public/static/img/404_cloud.png similarity index 100% rename from vue/src/assets/images/404_cloud.png rename to vue/public/static/img/404_cloud.png diff --git a/vue/public/static/img/fileType/docx.png b/vue/public/static/img/fileType/docx.png new file mode 100644 index 0000000..fddc667 Binary files /dev/null and b/vue/public/static/img/fileType/docx.png differ diff --git a/vue/public/static/img/fileType/pdf.png b/vue/public/static/img/fileType/pdf.png new file mode 100644 index 0000000..95e2ca2 Binary files /dev/null and b/vue/public/static/img/fileType/pdf.png differ diff --git a/vue/public/static/img/fileType/ppt.png b/vue/public/static/img/fileType/ppt.png new file mode 100644 index 0000000..1a4609b Binary files /dev/null and b/vue/public/static/img/fileType/ppt.png differ diff --git a/vue/public/static/img/fileType/rar.png b/vue/public/static/img/fileType/rar.png new file mode 100644 index 0000000..d13ec4c Binary files /dev/null and b/vue/public/static/img/fileType/rar.png differ diff --git a/vue/public/static/img/fileType/txt.png b/vue/public/static/img/fileType/txt.png new file mode 100644 index 0000000..5ea447d Binary files /dev/null and b/vue/public/static/img/fileType/txt.png differ diff --git a/vue/public/static/img/fileType/xlsx.png b/vue/public/static/img/fileType/xlsx.png new file mode 100644 index 0000000..afe3480 Binary files /dev/null and b/vue/public/static/img/fileType/xlsx.png differ diff --git a/vue/public/static/img/fileType/zip.png b/vue/public/static/img/fileType/zip.png new file mode 100644 index 0000000..3cbcd76 Binary files /dev/null and b/vue/public/static/img/fileType/zip.png differ diff --git a/vue/src/assets/images/sprite.1.2.4.png b/vue/public/static/img/sprite.1.2.4.png similarity index 100% rename from vue/src/assets/images/sprite.1.2.4.png rename to vue/public/static/img/sprite.1.2.4.png diff --git a/vue/src/components/PuzzleVerify/main.vue b/vue/src/components/PuzzleVerify/main.vue index 15b2258..2d307f3 100644 --- a/vue/src/components/PuzzleVerify/main.vue +++ b/vue/src/components/PuzzleVerify/main.vue @@ -301,227 +301,4 @@ } - + diff --git a/vue/src/components/PuzzleVerify/style.scss b/vue/src/components/PuzzleVerify/style.scss new file mode 100644 index 0000000..e750fe8 --- /dev/null +++ b/vue/src/components/PuzzleVerify/style.scss @@ -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) + } +} diff --git a/vue/src/components/UploadFile/index.vue b/vue/src/components/UploadFile/index.vue index 11578b9..d6cfb8d 100644 --- a/vue/src/components/UploadFile/index.vue +++ b/vue/src/components/UploadFile/index.vue @@ -21,32 +21,24 @@ @mouseenter="e => handleBlockMouseEnter(e,file)" @mouseleave="handleBlockMouseLeave" > - + - + - + - - + + +
@@ -59,16 +51,44 @@ - + diff --git a/vue/src/components/UploadFile/style.scss b/vue/src/components/UploadFile/style.scss new file mode 100644 index 0000000..2c22ea0 --- /dev/null +++ b/vue/src/components/UploadFile/style.scss @@ -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; +} diff --git a/vue/src/config/index.js b/vue/src/config/index.js index 2fcb5e1..bb6cd03 100644 --- a/vue/src/config/index.js +++ b/vue/src/config/index.js @@ -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' } diff --git a/vue/src/mixins/bizDocumentDialogMixin.js b/vue/src/mixins/bizDocumentDialogMixin.js index 52efc92..90230ea 100644 --- a/vue/src/mixins/bizDocumentDialogMixin.js +++ b/vue/src/mixins/bizDocumentDialogMixin.js @@ -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) } } diff --git a/vue/src/utils/file.js b/vue/src/utils/file.js index 47ec584..7175dce 100644 --- a/vue/src/utils/file.js +++ b/vue/src/utils/file.js @@ -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)) diff --git a/vue/src/utils/validate.js b/vue/src/utils/validate.js index 721a2df..9c51d16 100644 --- a/vue/src/utils/validate.js +++ b/vue/src/utils/validate.js @@ -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()) } diff --git a/vue/src/views/app/403.vue b/vue/src/views/app/403.vue index 2b928e1..19cc807 100644 --- a/vue/src/views/app/403.vue +++ b/vue/src/views/app/403.vue @@ -2,7 +2,7 @@
- 403 + 403
Oops!
diff --git a/vue/src/views/app/404.vue b/vue/src/views/app/404.vue index b728522..ba409b2 100644 --- a/vue/src/views/app/404.vue +++ b/vue/src/views/app/404.vue @@ -2,10 +2,10 @@
- 404 - 404 - 404 - 404 + 404 + 404 + 404 + 404
Oops!
diff --git a/vue/vue.config.js b/vue/vue.config.js index b161fe2..fe5badf 100644 --- a/vue/vue.config.js +++ b/vue/vue.config.js @@ -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}`]: '' }