xy 1 year ago
parent be1105774e
commit 5dcb60ee6a

@ -34,7 +34,11 @@
"vxe-table": "^3.8.22",
"wujie-vue2": "^1.0.22",
"moment": "^2.29.4",
"vue-grid-layout": "^2.4.0"
"vue-grid-layout": "^2.4.0",
"@vue-office/docx": "^1.6.2",
"@vue-office/excel": "^1.7.11",
"@vue-office/pdf": "^2.0.2",
"@vue/composition-api": "^1.7.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "4.4.4",

@ -41,9 +41,13 @@ export default {
},
methods: {
open(url) {
this.codeUri = `${process.env.VUE_APP_PREVIEW}?url=${encodeURIComponent(
new Buffer(url).toString('base64')
)}`
const resolve = this.$router.resolve({
path: '/preview',
query: {
url
}
})
this.codeUri = resolve.href
this.showModal = true
}
}

@ -3,6 +3,7 @@
v-model="myValue"
:size="size"
clearable
:reserve-keyword="reserveKeyword"
:popper-append-to-body="popperAppendToBody"
:style="{ width: width }"
value-key="id"
@ -10,7 +11,7 @@
filterable
:multiple="multiple"
:loading="loading"
@change="e => $emit('input',e)"
@input="e => $emit('input',e)"
>
<el-option
v-for="(item) in list"
@ -26,6 +27,10 @@ let listData = []
import { userListNoAuth as index } from '@/api/common'
export default {
props: {
reserveKeyword: {
type: Boolean,
default: true
},
popperAppendToBody: {
type: Boolean,
default: true
@ -35,8 +40,7 @@ export default {
size: String,
value: {
type: [String, Number, Array],
default: '',
required: true
default: ''
}
},
data() {

@ -216,6 +216,7 @@ export default {
async logout() {
await this.$store.dispatch('user/logout')
await this.$store.commit('permission/SET_ROUTES', [])
await this.$store.commit('permission/RESET_ADD_ROUTES')
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
}
}

@ -8,7 +8,7 @@ import getPageTitle from '@/utils/get-page-title'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/login'] // no redirect whitelist
const whiteList = ['/login','/preview'] // no redirect whitelist
router.beforeEach(async(to, from, next) => {
// start progress bar
NProgress.start()

@ -42,7 +42,11 @@ export const constantRoutes = [
component: () => import('@/views/404'),
hidden: true
},
{
path: '/preview',
component: () => import('@/views/preview'),
hidden: true
},
{
path: '/',
component: Layout,

@ -65,6 +65,9 @@ const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
},
RESET_ADD_ROUTES: (state) => {
state.addRoutes = []
}
}

@ -0,0 +1,84 @@
<template>
<div class="container">
<template v-if="type === 'docx'">
<VueOfficeDocx :src="url" style="height: 100vh;" />
</template>
<template v-else-if="type === 'xlsx' || type === 'xls'">
<VueOfficeExcel :src="url" style="height: 100vh;" />
</template>
<template v-else-if="type === 'pdf'">
<VueOfficePdf :src="url" style="height: 100vh;" />
</template>
<template v-else-if="['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'].indexOf(type) !== -1">
<el-image ref="elImage" fit="contain" :preview-src-list="[url]" :src="url" style="width: 100vw;height: 100vh;" alt="" @load="loadImg" />
</template>
<template v-else>
<div>
<h4>文件类型暂不支持在线预览请下载查看</h4>
<el-link target="_blank" type="primary" :href="url">点击下载</el-link>
</div>
</template>
</div>
</template>
<script>
// VueOfficeDocx
import VueOfficeDocx from '@vue-office/docx'
//
import '@vue-office/docx/lib/index.css'
// VueOfficeExcel
import VueOfficeExcel from '@vue-office/excel'
//
import '@vue-office/excel/lib/index.css'
// VueOfficePdf
import VueOfficePdf from '@vue-office/pdf'
// import { renderAsync } from 'docx-preview'
export default {
components: {
VueOfficeDocx,
VueOfficePdf,
VueOfficeExcel
},
data() {
return {
url: '',
type: ''
}
},
computed: {},
watch: {
'$route.query': {
handler(newVal) {
this.resolveUrl(newVal.url)
},
immediate: true
}
},
methods: {
loadImg() {
this.$refs['elImage']?.$el?.children[0].click()
this.$nextTick(() => {
document.querySelector('.el-image-viewer__close').style.display = 'none'
document.querySelector('.el-image__inner').style.display = 'none'
})
},
async resolveUrl(url) {
if (url) {
try {
this.url = window.atob(window.decodeURIComponent(this.$route.query.url ?? ''))
} catch (err) {
this.url = window.decodeURIComponent(this.$route.query.url ?? '')
}
this.type = this.$route.query.type || this.url.split('.').at(-1)
}
}
}
}
</script>
<style scoped lang="scss">
.container {
height: 100vh;
width: 100vw;
}
</style>

@ -145,7 +145,9 @@ export default {
showClose: false
})
await this.$store.dispatch('user/logout')
this.$router.push('/')
await this.$store.commit('permission/SET_ROUTES', [])
await this.$store.commit('permission/RESET_ADD_ROUTES')
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
}
})
} else {

@ -123,6 +123,10 @@ export default {
return isLt10M
},
uploadSuccess(response, file, fileList) {
if (response.code) {
fileList.splice(fileList.indexOf(file), 1)
this.$message.warning(response.msg)
}
this.fileList = fileList
},
removeHandle(file, fileList) {

@ -42,7 +42,7 @@
<span v-if="row.deputy_manager && row.deputy_manager instanceof Array">{{ row.deputy_manager.map(i => i.name).toString() }}</span>
</template>
<template #edit="{ row }">
<user-picker :value="row.deputy_manager_id.split(',').map(i => Number(i))" multiple size="small" @input="e => row.deputy_manager_id = e.toString()" />
<user-picker :value="row.deputy_manager_id ? row.deputy_manager_id.split(',').map(i => Number(i)) : []" multiple size="small" @input="e => row.deputy_manager_id = e.toString()" />
</template>
</vxe-column>
<vxe-column field="sortnumber" width="80" title="排序" align="center" :edit-render="{ name: 'input', attrs: { type: 'number' } }" />

Loading…
Cancel
Save