增加导出功能.

This commit is contained in:
小陌 2024-01-25 14:58:49 +08:00
parent e5f2d27184
commit 71e21f9189
12 changed files with 378 additions and 394 deletions

2
dist/index.html vendored
View File

@ -1,4 +1,4 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"/><meta content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=0" name="viewport"/><link rel="icon" href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/favicon.ico"><title>X-PHP</title><script>document.write("<script src='config.js'><\/script>");</script><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/js/echarts.49558cc4.js"></script><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/js/elicons.4bccae06.js"></script><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/js/modules.af2834df.js"></script><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/js/app.b3dc07da.js"></script><link href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/css/modules.34563575.css" rel="stylesheet"><link href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/css/app.661f9899.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but X-PHP doesn't work properly without JavaScript enabled.</strong></noscript><div id="app" class="aminui"><div class="app-loading"><div class="app-loading__logo"></div><div class="app-loading__loader"></div></div></div></body><div id="versionCheck" class="versionCheck"><h2>当前浏览器内核版本过低</h2><p>当前版本:<span id="versionCheck-type">--</span> <span id="versionCheck-version">--</span></p><p>最低版本要求Chrome 71+、Firefox 65+、Safari 12+、Edge 97+。</p><p>请升级浏览器版本,或更换现代浏览器,如果你使用的是双核浏览器,请切换到极速/高速模式。</p></div><style>.app-loading {
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"/><meta content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=0" name="viewport"/><link rel="icon" href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/favicon.ico"><title>X-PHP</title><script>document.write("<script src='config.js'><\/script>");</script><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/js/echarts.49558cc4.js"></script><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/js/elicons.4bccae06.js"></script><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/js/modules.af2834df.js"></script><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/js/app.6e805385.js"></script><link href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/css/modules.34563575.css" rel="stylesheet"><link href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/x-Admin/static/css/app.f6c11b91.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but X-PHP doesn't work properly without JavaScript enabled.</strong></noscript><div id="app" class="aminui"><div class="app-loading"><div class="app-loading__logo"></div><div class="app-loading__loader"></div></div></div></body><div id="versionCheck" class="versionCheck"><h2>当前浏览器内核版本过低</h2><p>当前版本:<span id="versionCheck-type">--</span> <span id="versionCheck-version">--</span></p><p>最低版本要求Chrome 71+、Firefox 65+、Safari 12+、Edge 97+。</p><p>请升级浏览器版本,或更换现代浏览器,如果你使用的是双核浏览器,请切换到极速/高速模式。</p></div><style>.app-loading {
position: absolute;
top:0px;
left:0px;

4
dist/report.html vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
dist/static/js/app.6e805385.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,53 +0,0 @@
<template>
<el-table ref="table" :data="columnData" row-key="prop" style="width: 100%" border>
<el-table-column prop="" label="排序" width="60">
<el-tag disable-transitions class="move" style="cursor: move;"><el-icon style="cursor: move;"><el-icon-d-caret/></el-icon></el-tag>
</el-table-column>
<el-table-column prop="label" label="列名">
<template #default="scope">
<el-tag round disable-transitions :effect="scope.row.hide?'light':'dark'" :type="scope.row.hide?'info':''">{{ scope.row.label }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="hide" label="显示" width="60">
<template #default="scope">
<el-switch v-model="scope.row.hide" size="small" :active-value="false" :inactive-value="true"/>
</template>
</el-table-column>
</el-table>
</template>
<script>
import Sortable from 'sortablejs'
export default {
emits: ['success'],
props: {
column: { type: Array, default: () => [] }
},
data() {
return {
columnData: this.column
}
},
mounted() {
this.rowDrop()
},
methods: {
rowDrop(){
const _this = this
const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody')
Sortable.create(tbody, {
handle: ".move",
animation: 200,
ghostClass: "ghost",
onEnd({ newIndex, oldIndex }) {
const tableData = _this.columnData
const currRow = tableData.splice(oldIndex, 1)[0]
tableData.splice(newIndex, 0, currRow)
}
})
}
}
}
</script>

View File

@ -1,193 +0,0 @@
<!--
* @Descripttion: 文件导出
-->
<template>
<slot :open="open">
<el-button type="primary" plain @click="open">导出</el-button>
</slot>
<el-drawer v-model="dialog" title="导出" :size="400" direction="rtl" append-to-body destroy-on-close>
<el-main style="padding: 0 20px 20px 20px;">
<div v-loading="downLoading" element-loading-text="正在处理中...">
<div v-if="downLoading && progress" style="position: absolute;width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;z-index: 3000;">
<el-progress :text-inside="true" :stroke-width="20" :percentage="downLoadProgress" style="width: 100%;margin-bottom: 120px;"/>
</div>
<el-tabs>
<el-tab-pane label="常规" lazy>
<el-form label-width="100px" label-position="left" style="margin: 10px 0 20px 0;">
<el-form-item label="文件名">
<el-input v-model="formData.fileName" placeholder="请输入文件名" />
</el-form-item>
<el-form-item label="文件类型">
<el-select v-model="formData.fileType" placeholder="请选择文件类型">
<el-option v-for="item in fileTypes" :key="item" :label="'*.'+item" :value="item" />
</el-select>
</el-form-item>
<slot name="form" :formData="formData"></slot>
</el-form>
<el-button v-if="async" type="primary" size="large" icon="el-icon-plus" style="width: 100%;" @click="download" :loading="asyncLoading">发起导出任务</el-button>
<el-button v-else type="primary" size="large" icon="el-icon-download" style="width: 100%;" @click="download"> </el-button>
</el-tab-pane>
<el-tab-pane label="列设置" v-if="columnData.length>0" lazy>
<columnSet :column="columnData"></columnSet>
</el-tab-pane>
<el-tab-pane label="其他参数" v-if="data && showData" lazy>
<el-descriptions :column="1" border size="small">
<el-descriptions-item v-for=" (val, key) in data" :key="key" :label="key">{{val}}</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
</el-tabs>
</div>
</el-main>
</el-drawer>
</template>
<script>
import columnSet from './column'
export default {
components: {
columnSet
},
props: {
apiObj: { type: Object, default: () => {} },
fileName: { type: String, default: "" },
fileTypes: { type: Array, default: () => ['xlsx'] },
data: { type: Object, default: () => {} },
showData: { type: Boolean, default: false },
async: { type: Boolean, default: false },
column: { type: Array, default: () => [] },
blob: { type: Boolean, default: false },
progress: { type: Boolean, default: true }
},
data() {
return {
dialog: false,
formData: {
fileName: this.fileName,
fileType: this.fileTypes[0]
},
columnData: [],
downLoading: false,
downLoadProgress: 0,
asyncLoading: false
}
},
watch:{
'formData.fileType'(val) {
if(this.formData.fileName.includes(".")){
this.formData.fileName = this.formData.fileName.substring(0, this.formData.fileName.lastIndexOf('.')) + "." + val
}else{
this.formData.fileName = this.formData.fileName + "." + val
}
}
},
mounted() {
},
methods: {
open() {
this.dialog = true
this.formData = {
fileName: (this.fileName?this.fileName:(new Date().getTime()+'')) + "." + this.fileTypes[0],
fileType: this.fileTypes[0]
}
this.columnData = JSON.parse(JSON.stringify(this.column))
},
close() {
this.dialog = false
},
download() {
let columnArr = {
column: this.columnData.filter(n => !n.hide).map(n => n.prop).join(",")
}
let assignData = {...this.data, ...this.formData, ...columnArr}
if(this.async){
this.asyncDownload(this.apiObj, this.formData.fileName, assignData)
}else if(this.blob){
this.downloadFile(this.apiObj, this.formData.fileName, assignData)
}else{
this.linkFile(this.apiObj.url, this.formData.fileName, assignData)
}
},
linkFile(url, fileName, data={}){
let a = document.createElement("a")
a.style = "display: none"
a.target = "_blank"
//a.download = fileName
a.href = url + this.toQueryString(data)
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
},
downloadFile(apiObj, fileName, data={}){
this.downLoading = true
var _this = this
apiObj.get(data, {
responseType: 'blob',
onDownloadProgress(e){
if(e.lengthComputable){
_this.downLoadProgress = parseInt(e.loaded / e.total * 100)
}
}
}).then(res => {
this.downLoading = false
this.downLoadProgress = 0
let url = URL.createObjectURL(res)
let a = document.createElement("a")
a.style = "display: none"
a.target = "_blank"
a.download = fileName
a.href = url
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
URL.revokeObjectURL(url)
}).catch(err => {
this.downLoading = false
this.downLoadProgress = 0
this.$notify.error({
title: '下载文件失败',
message: err
})
})
},
asyncDownload(apiObj, fileName, data={}){
this.asyncLoading = true
apiObj.get(data).then(res => {
this.asyncLoading = false
if(res.code == 200){
this.dialog = false
this.$msgbox({
title: "成功发起任务",
message: `<div><img style="height:200px" src="@/assets/img/tasks-example.png"/></div><p>已成功发起导出任务,您可以操作其他事务</p><p>稍后可在 <b>任务中心</b> 查看执行结果</p>`,
type: "success",
confirmButtonText: "知道了",
dangerouslyUseHTMLString: true,
center: true
}).catch(() => {})
}else{
this.$alert(res.message || "未知错误", "发起任务失败", {
type: "error",
center: true
}).catch(() => {})
}
}).catch(() => {
this.asyncLoading = false
})
},
toQueryString(obj){
let arr = []
for (var k in obj) {
arr.push(`${k}=${obj[k]}`)
}
return (arr.length>0?"?":"") + arr.join('&')
}
}
}
</script>
<style>
</style>

View File

@ -1,128 +0,0 @@
<!--
* @Descripttion: 文件导入
-->
<template>
<slot :open="open">
<el-button type="primary" plain @click="open">导入</el-button>
</slot>
<el-dialog v-model="dialog" title="导入" :width="550" :close-on-click-modal="false" append-to-body destroy-on-close>
<el-progress v-if="loading" :text-inside="true" :stroke-width="20" :percentage="percentage" style="margin-bottom: 15px;"/>
<div v-loading="loading">
<el-upload ref="uploader"
drag
:accept="accept"
:maxSize="maxSize"
:limit="1"
:data="data"
:show-file-list="false"
:http-request="request"
:before-upload="before"
:on-progress="progress"
:on-success="success"
:on-error="error"
>
<slot name="uploader">
<el-icon class="el-icon--upload"><el-icon-upload-filled /></el-icon>
<div class="el-upload__text">
将文件拖到此处或 <em>点击选择文件上传</em>
</div>
</slot>
<template #tip>
<div class="el-upload__tip">
<template v-if="tip">{{tip}}</template>
<template v-else>请上传小于或等于 {{maxSize}}M {{accept}} 格式文件</template>
<p v-if="templateUrl" style="margin-top: 7px;">
<el-link :href="templateUrl" target="_blank" type="primary" :underline="false">下载导入模板</el-link>
</p>
</div>
</template>
</el-upload>
<el-form v-if="$slots.form" inline label-width="100px" label-position="left" style="margin-top: 18px;">
<slot name="form" :formData="formData"></slot>
</el-form>
</div>
</el-dialog>
</template>
<script>
export default {
emits: ['success'],
props: {
apiObj: { type: Object, default: () => {} },
data: { type: Object, default: () => {} },
accept: { type: String, default: ".xls, .xlsx" },
maxSize: { type: Number, default: 10 },
tip: { type: String, default: "" },
templateUrl: { type: String, default: "" }
},
data() {
return {
dialog: false,
loading: false,
percentage: 0,
formData: {}
}
},
mounted() {
},
methods: {
open(){
this.dialog = true
this.formData = {}
},
close(){
this.dialog = false
},
before(file){
const maxSize = file.size / 1024 / 1024 < this.maxSize;
if (!maxSize) {
this.$message.warning(`上传文件大小不能超过 ${this.maxSize}MB!`);
return false;
}
this.loading = true
},
progress(e){
this.percentage = e.percent
},
success(res, file){
this.$refs.uploader.handleRemove(file)
this.$refs.uploader.clearFiles()
this.loading = false
this.percentage = 0
this.$emit('success', res, this.close)
},
error(err){
this.loading = false
this.percentage = 0
this.$notify.error({
title: '上传文件未成功',
message: err
})
},
request(param){
Object.assign(param.data, this.formData)
const data = new FormData();
data.append(param.filename, param.file);
for (const key in param.data) {
data.append(key, param.data[key]);
}
this.apiObj.post(data, {
onUploadProgress: e => {
const complete = parseInt(((e.loaded / e.total) * 100) | 0, 10)
param.onProgress({percent: complete})
}
}).then(res => {
param.onSuccess(res)
}).catch(err => {
param.onError(err)
})
}
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,53 @@
<template>
<el-table ref="table" :data="columnData" row-key="prop" style="width: 100%" border>
<el-table-column prop="" label="排序" width="60">
<el-tag disable-transitions class="move" style="cursor: move;"><el-icon style="cursor: move;"><el-icon-d-caret /></el-icon></el-tag>
</el-table-column>
<el-table-column prop="label" label="列名">
<template #default="scope">
<el-tag round disable-transitions :effect="scope.row.hide ? 'light' : 'dark'" :type="scope.row.hide ? 'info' : ''">{{ scope.row.label }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="hide" label="显示" width="60">
<template #default="scope">
<el-switch v-model="scope.row.hide" size="small" :active-value="false" :inactive-value="true" />
</template>
</el-table-column>
</el-table>
</template>
<script>
import Sortable from 'sortablejs'
export default {
emits: ['success'],
props: {
column: { type: Array, default: () => [] }
},
data() {
return {
columnData: this.column
}
},
mounted() {
this.rowDrop()
},
methods: {
rowDrop() {
const _this = this
const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody')
Sortable.create(tbody, {
handle: ".move",
animation: 200,
ghostClass: "ghost",
onEnd({ newIndex, oldIndex }) {
const tableData = _this.columnData
const currRow = tableData.splice(oldIndex, 1)[0]
tableData.splice(newIndex, 0, currRow)
}
})
}
}
}
</script>

View File

@ -0,0 +1,188 @@
<!--
* @Descripttion: 文件导出
-->
<template>
<slot :open="open">
<el-button type="primary" plain @click="open">导出</el-button>
</slot>
<el-drawer v-model="dialog" title="导出" :size="400" direction="rtl" append-to-body destroy-on-close>
<el-main style="padding: 0 20px 20px 20px;">
<div v-loading="downLoading" element-loading-text="正在处理中...">
<div v-if="downLoading && progress" style="position: absolute;width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;z-index: 3000;">
<el-progress :text-inside="true" :stroke-width="20" :percentage="downLoadProgress" style="width: 100%;margin-bottom: 120px;" />
</div>
<el-tabs>
<el-tab-pane label="常规" lazy>
<el-form label-width="100px" label-position="left" style="margin: 10px 0 20px 0;">
<el-form-item label="文件名">
<el-input v-model="formData.filename" placeholder="请输入文件名" />
</el-form-item>
<el-form-item label="文件类型">
<el-select v-model="formData.fileType" placeholder="请选择文件类型">
<el-option v-for="item in fileTypes" :key="item" :label="'*.' + item" :value="item" />
</el-select>
</el-form-item>
<slot name="form" :formData="formData"></slot>
</el-form>
<el-button v-if="async" type="primary" size="large" icon="el-icon-plus" style="width: 100%;" @click="download" :loading="asyncLoading">发起导出任务</el-button>
<el-button v-else type="primary" size="large" icon="el-icon-download" style="width: 100%;" @click="download"> </el-button>
</el-tab-pane>
<el-tab-pane label="列设置" v-if="columnData.length > 0" lazy>
<columnSet :column="columnData"></columnSet>
</el-tab-pane>
<el-tab-pane label="其他参数" v-if="data && showData" lazy>
<el-descriptions :column="1" border size="small">
<el-descriptions-item v-for=" (val, key) in data" :key="key" :label="key">{{ val }}</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
</el-tabs>
</div>
</el-main>
</el-drawer>
</template>
<script>
import columnSet from './column'
export default {
components: {
columnSet
},
props: {
api: { type: Object, default: () => { } },
filename: { type: String, default: "" },
fileTypes: { type: Array, default: () => ['xlsx'] },
data: { type: Object, default: () => { } },
showData: { type: Boolean, default: false },
async: { type: Boolean, default: false },
column: { type: Array, default: () => [] },
blob: { type: Boolean, default: false },
progress: { type: Boolean, default: true }
},
data() {
return {
dialog: false,
formData: {
filename: this.filename,
fileType: this.fileTypes[0]
},
columnData: [],
downLoading: false,
downLoadProgress: 0,
asyncLoading: false
}
},
watch: {
'formData.fileType'(val) {
if (this.formData.filename.includes(".")) {
this.formData.filename = this.formData.filename.substring(0, this.formData.filename.lastIndexOf('.')) + "." + val
} else {
this.formData.filename = this.formData.filename + "." + val
}
}
},
mounted() {
},
methods: {
open() {
this.dialog = true
this.formData = {
filename: (this.filename ? this.filename : (new Date().getTime() + '')) + "." + this.fileTypes[0],
fileType: this.fileTypes[0]
}
this.columnData = JSON.parse(JSON.stringify(this.column))
},
close() {
this.dialog = false
},
download() {
let columnArr = {
column: this.columnData.filter(n => !n.hide).map(n => n.prop).join(",")
}
let assignData = { ...this.data, ...this.formData, ...columnArr }
if (this.async) {
this.asyncDownload(this.api, this.formData.filename, assignData)
} else if (this.blob) {
this.downloadFile(this.api, this.formData.filename, assignData)
} else {
this.linkFile(this.api, this.formData.filename, assignData)
}
},
linkFile(url, filename, data = {}) {
let a = document.createElement("a")
a.style = "display: none"
a.target = "_blank"
a.download = filename
a.href = url + (url.match('[?]') ? '&' : '?') + this.toQueryString(data);
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
},
downloadFile(api, filename, data = {}) {
this.downLoading = true
var _this = this
this.$http.get(api, data, {
responseType: 'blob',
onDownloadProgress(e) {
if (e.lengthComputable) {
_this.downLoadProgress = parseInt(e.loaded / e.total * 100)
}
}
}).then(res => {
this.downLoading = false
this.downLoadProgress = 0
let url = URL.createObjectURL(res)
let a = document.createElement("a")
a.style = "display: none"
a.target = "_blank"
a.download = filename
a.href = url
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
URL.revokeObjectURL(url)
}).catch(err => {
this.downLoading = false
this.downLoadProgress = 0
this.$notify.error({
title: '下载文件失败',
message: err
})
})
},
asyncDownload(api, filename, data = {}) {
this.asyncLoading = true
this.$http.get(api, data).then(res => {
this.asyncLoading = false
if (res.code == 200) {
this.dialog = false
this.$msgbox({
title: "成功发起任务",
message: `<div><img style="height:200px" src="@/assets/img/tasks-example.png"/></div><p>已成功发起导出任务,您可以操作其他事务</p><p>稍后可在 <b>任务中心</b> 查看执行结果</p>`,
type: "success",
confirmButtonText: "知道了",
dangerouslyUseHTMLString: true,
center: true
}).catch(() => { })
} else {
this.$alert(res.message || "未知错误", "发起任务失败", {
type: "error",
center: true
}).catch(() => { })
}
}).catch(() => {
this.asyncLoading = false
})
},
toQueryString(obj) {
let arr = []
for (var k in obj) {
arr.push(`${k}=${obj[k]}`)
}
return arr.join('&')
}
}
}
</script>

View File

@ -0,0 +1,114 @@
<!--
* @Descripttion: 文件导入
-->
<template>
<slot :open="open">
<el-button type="primary" plain @click="open">导入</el-button>
</slot>
<el-dialog v-model="dialog" title="导入" :width="550" :close-on-click-modal="false" append-to-body destroy-on-close>
<el-progress v-if="loading" :text-inside="true" :stroke-width="20" :percentage="percentage" style="margin-bottom: 15px;" />
<div v-loading="loading">
<el-upload ref="uploader" drag :accept="accept" :maxSize="maxSize" :limit="1" :data="data" :show-file-list="false" :http-request="request" :before-upload="before" :on-progress="progress" :on-success="success" :on-error="error">
<slot name="uploader">
<el-icon class="el-icon--upload"><el-icon-upload-filled /></el-icon>
<div class="el-upload__text">
将文件拖到此处或 <em>点击选择文件上传</em>
</div>
</slot>
<template #tip>
<div class="el-upload__tip">
<template v-if="tip">{{ tip }}</template>
<template v-else>请上传小于或等于 {{ maxSize }}M {{ accept }} 格式文件</template>
<p v-if="templateUrl" style="margin-top: 7px;">
<el-link :href="templateUrl" target="_blank" type="primary" :underline="false">下载导入模板</el-link>
</p>
</div>
</template>
</el-upload>
<el-form v-if="$slots.form" inline label-width="100px" label-position="left" style="margin-top: 18px;">
<slot name="form" :formData="formData"></slot>
</el-form>
</div>
</el-dialog>
</template>
<script>
export default {
emits: ['success'],
props: {
apiObj: { type: Object, default: () => { } },
data: { type: Object, default: () => { } },
accept: { type: String, default: ".xls, .xlsx" },
maxSize: { type: Number, default: 10 },
tip: { type: String, default: "" },
templateUrl: { type: String, default: "" }
},
data() {
return {
dialog: false,
loading: false,
percentage: 0,
formData: {}
}
},
mounted() {
},
methods: {
open() {
this.dialog = true
this.formData = {}
},
close() {
this.dialog = false
},
before(file) {
const maxSize = file.size / 1024 / 1024 < this.maxSize;
if (!maxSize) {
this.$message.warning(`上传文件大小不能超过 ${this.maxSize}MB!`);
return false;
}
this.loading = true
},
progress(e) {
this.percentage = e.percent
},
success(res, file) {
this.$refs.uploader.handleRemove(file)
this.$refs.uploader.clearFiles()
this.loading = false
this.percentage = 0
this.$emit('success', res, this.close)
},
error(err) {
this.loading = false
this.percentage = 0
this.$notify.error({
title: '上传文件未成功',
message: err
})
},
request(param) {
Object.assign(param.data, this.formData)
const data = new FormData();
data.append(param.filename, param.file);
for (const key in param.data) {
data.append(key, param.data[key]);
}
this.apiObj.post(data, {
onUploadProgress: e => {
const complete = parseInt(((e.loaded / e.total) * 100) | 0, 10)
param.onProgress({ percent: complete })
}
}).then(res => {
param.onSuccess(res)
}).catch(err => {
param.onError(err)
})
}
}
}
</script>
<style></style>

View File

@ -2,10 +2,13 @@
<el-container>
<el-header>
<div class="left-panel">
<el-radio-group v-model="dateType" v-if="data.dateGroup && data.dateGroup.length > 0" @change="changedateGroup" style="margin-right: 10px;">
<el-radio-button v-for="item in data.dateGroup" :key="item.key" :label="item.value" :value="item.value">{{ item.label }}</el-radio-button>
</el-radio-group>
<el-date-picker class="hidden-sm-and-down" @change="changedate" format="YYYY-MM-DD HH:mm" value-format="YYYY-MM-DD HH:mm" v-model="search.date" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
<el-select v-if="data.select && data.select.items && data.select.items.length > 0" v-model="search[data.select.key || 'value']" v-bind="data.select.options" style="max-width: 240px; margin-right: 10px;">
<el-option v-for="item in data.select.items" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-date-picker class="hidden-sm-and-down" format="YYYY-MM-DD HH:mm" value-format="YYYY-MM-DD HH:mm" v-model="search.date" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
</div>
<div class="right-panel" v-if="data.export && data.export.api">
<x-file-export v-bind="data.export"> </x-file-export>
</div>
</el-header>
<el-main v-loading="statloading">
@ -40,18 +43,25 @@
<script>
import xEcharts from '@/components/xEcharts';
import xStatistic from '@/components/xStatistic';
import xFileExport from '@/components/xFileExport';
export default {
name: 'chartlist',
components: {
xEcharts,
xStatistic,
xFileExport,
},
props: {
data: {
type: Object, default: () => ({
statistic: [],
chartList: [],
dateGroup: [],
select: {
options: {},
items: [],
key: 'value'
},
export: {},
table: {},
})
},
@ -60,8 +70,7 @@ export default {
},
data() {
return {
search: this.info,
dateType: null,
search: this.info
}
},
watch: {
@ -77,13 +86,7 @@ export default {
this.search = this.info;
},
methods: {
changedateGroup() {
this.data.dateGroup.forEach((item) => {
if (this.dateType === item.value) {
this.search[item.key] = item.value;
}
})
},
}
}
</script>
@ -97,7 +100,7 @@ export default {
padding: 10px
}
.chart .el-col{
.chart .el-col {
margin: 15px 0;
}