|
|
@@ -0,0 +1,459 @@
|
|
|
+<template>
|
|
|
+ <div class="app-container">
|
|
|
+ <div
|
|
|
+ class="filter-container"
|
|
|
+ v-loading="loading.filter">
|
|
|
+ <div class="filter-row">
|
|
|
+ <label class="el-form-item__label">Report Type:</label>
|
|
|
+ <el-select
|
|
|
+ v-model="filter.pageVo.reportType"
|
|
|
+ @change="changeReportType"
|
|
|
+ class="filter-input"
|
|
|
+ placeholder="Filter Report Type"
|
|
|
+ clearable>
|
|
|
+ <el-option
|
|
|
+ v-for="reportType in options.reportType"
|
|
|
+ :label="reportType.name"
|
|
|
+ :value="reportType.value"
|
|
|
+ :key="reportType.value"/>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="filter-row">
|
|
|
+ <label class="el-form-item__label">Filters:</label>
|
|
|
+ <el-date-picker
|
|
|
+ v-model="dateRange"
|
|
|
+ type="daterange"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ start-placeholder="Start Date"
|
|
|
+ end-placeholder="End Date"
|
|
|
+ :picker-options="pickerOptions"
|
|
|
+ clearable
|
|
|
+ @change="changeDateRange"
|
|
|
+ class="filter-input"
|
|
|
+ v-if="filter.pageVo.reportType == 'APENDIXF'"/>
|
|
|
+ <template v-else>
|
|
|
+ <el-date-picker
|
|
|
+ v-model="filter.pageVo.year"
|
|
|
+ type="year"
|
|
|
+ format="yyyy"
|
|
|
+ value-format="yyyy"
|
|
|
+ :clearable="false"
|
|
|
+ class="filter-input half"
|
|
|
+ placeholder="Filter Year"/>
|
|
|
+ <el-select
|
|
|
+ v-model="filter.pageVo.month"
|
|
|
+ class="filter-input half"
|
|
|
+ placeholder="Filter Month"
|
|
|
+ clearable>
|
|
|
+ <el-option
|
|
|
+ v-for="month in options.monthOptions"
|
|
|
+ :label="month.name"
|
|
|
+ :value="month.value"
|
|
|
+ :key="month.value"/>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ <el-select
|
|
|
+ v-if="filter.pageVo.reportType == 'MNTHTRAN' || filter.pageVo.reportType == 'MNTHSEPR'"
|
|
|
+ v-model="filter.pageVo.providerPks"
|
|
|
+ class="filter-input"
|
|
|
+ placeholder="Service Provider"
|
|
|
+ clearable
|
|
|
+ multiple>
|
|
|
+ <el-option
|
|
|
+ v-for="(item,index) in options.serviceProvider"
|
|
|
+ :label="item.providerName"
|
|
|
+ :value="item.providerPk"
|
|
|
+ :key="index"/>
|
|
|
+ </el-select>
|
|
|
+ <!--:remote-method="(s) => getSiteOptions(s)"-->
|
|
|
+ <el-select
|
|
|
+ clearable
|
|
|
+ filterable multiple
|
|
|
+ v-if="filter.pageVo.reportType == 'MNTHSITE' || filter.pageVo.reportType == 'APENDIXF'"
|
|
|
+ v-model="filter.pageVo.sitePks"
|
|
|
+ class="filter-input"
|
|
|
+ placeholder="Sites">
|
|
|
+ <el-option
|
|
|
+ v-for="(item, index) in options.siteOptions"
|
|
|
+ :key="index"
|
|
|
+ :label="item.siteName"
|
|
|
+ :value="item.sitePk"/>
|
|
|
+ </el-select>
|
|
|
+ <el-select
|
|
|
+ clearable
|
|
|
+ multiple
|
|
|
+ v-if="filter.pageVo.reportType == 'MNTHFLET'"
|
|
|
+ v-model="filter.pageVo.groupPks"
|
|
|
+ class="filter-input"
|
|
|
+ placeholder="Fleet">
|
|
|
+ <el-option
|
|
|
+ v-for="(item, index) in options.groupOptions"
|
|
|
+ :key="index"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.value"/>
|
|
|
+ </el-select>
|
|
|
+ <el-select
|
|
|
+ clearable
|
|
|
+ multiple
|
|
|
+ v-if="filter.pageVo.reportType == 'MNTHMEMB'"
|
|
|
+ v-model="filter.pageVo.groupPks"
|
|
|
+ class="filter-input"
|
|
|
+ placeholder="Member">
|
|
|
+ <el-option
|
|
|
+ v-for="(item, index) in options.groupOptions"
|
|
|
+ :key="index"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.value"/>
|
|
|
+ </el-select>
|
|
|
+ <el-select
|
|
|
+ clearable
|
|
|
+ multiple
|
|
|
+ v-if="filter.pageVo.reportType == 'MNTHPART'"
|
|
|
+ v-model="filter.pageVo.groupPks"
|
|
|
+ class="filter-input"
|
|
|
+ placeholder="Partner">
|
|
|
+ <el-option
|
|
|
+ v-for="(item, index) in options.groupOptions"
|
|
|
+ :key="index"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.value"/>
|
|
|
+ </el-select>
|
|
|
+ <el-button
|
|
|
+ class="generate-button"
|
|
|
+ type="primary"
|
|
|
+ @click="onSearch"
|
|
|
+ :disabled="loading.table">
|
|
|
+ Search
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ class="generate-button"
|
|
|
+ v-waves
|
|
|
+ type="primary"
|
|
|
+ :loading="loading.generate"
|
|
|
+ @click="reGenerateReport">
|
|
|
+ Generate
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <el-table
|
|
|
+ :data="table.data"
|
|
|
+ class="no-border"
|
|
|
+ v-loading="loading.table">
|
|
|
+ <el-table-column
|
|
|
+ label="Report Type"
|
|
|
+ prop="reportType"
|
|
|
+ align="center"
|
|
|
+ min-width="180"/>
|
|
|
+ <el-table-column
|
|
|
+ label="Year"
|
|
|
+ prop="year"
|
|
|
+ align="center"
|
|
|
+ min-width="80"/>
|
|
|
+ <el-table-column
|
|
|
+ label="Month"
|
|
|
+ prop="month"
|
|
|
+ align="center"
|
|
|
+ min-width="80"/>
|
|
|
+ <el-table-column
|
|
|
+ label="Creation Date/Time"
|
|
|
+ prop="createTime"
|
|
|
+ align="center"
|
|
|
+ min-width="150"/>
|
|
|
+ <el-table-column
|
|
|
+ label="Created By"
|
|
|
+ prop="createBy"
|
|
|
+ align="center"
|
|
|
+ min-width="150"/>
|
|
|
+ <el-table-column
|
|
|
+ label="Role"
|
|
|
+ prop="role"
|
|
|
+ align="center"
|
|
|
+ min-width="100"/>
|
|
|
+ <el-table-column
|
|
|
+ label="Name"
|
|
|
+ prop="reportName"
|
|
|
+ align="center"
|
|
|
+ min-width="220"/>
|
|
|
+ <el-table-column
|
|
|
+ v-if="!$route.meta.onlyView"
|
|
|
+ label="Action"
|
|
|
+ align="center"
|
|
|
+ width="130">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <el-button
|
|
|
+ :loading="row.loading"
|
|
|
+ icon="el-icon-download"
|
|
|
+ class="export-button"
|
|
|
+ @click="handleExportExcel(row)">
|
|
|
+ Export
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <div class="right">
|
|
|
+ <pagination
|
|
|
+ v-show="table.total > 0"
|
|
|
+ :total="table.total"
|
|
|
+ :page.sync="filter.pageNo"
|
|
|
+ :limit.sync="filter.pageSize"
|
|
|
+ @pagination="getReportsPages" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import site from '@/http/api/site'
|
|
|
+import api from '@/http/api/apiReport'
|
|
|
+import provider from '@/http/api/provider'
|
|
|
+import Pagination from '@/components/Pagination'
|
|
|
+import TableAction from '@/components/TableAction.vue'
|
|
|
+
|
|
|
+export default {
|
|
|
+ components: { Pagination, TableAction },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ loading: {
|
|
|
+ filter: false,
|
|
|
+ table: false,
|
|
|
+ generate: false
|
|
|
+ },
|
|
|
+ dateRange: [],
|
|
|
+ filter: {
|
|
|
+ pageNo: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ pageVo: {
|
|
|
+ year: ''+new Date().getFullYear(),
|
|
|
+ month: '',
|
|
|
+ startDate: "",
|
|
|
+ endDate: "",
|
|
|
+ reportType: '',
|
|
|
+ sitePks: [],
|
|
|
+ groupPks: [],
|
|
|
+ providerPks: []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ options: {
|
|
|
+ reportType: [],
|
|
|
+ siteOptions: [],
|
|
|
+ monthOptions: [],
|
|
|
+ groupOptions: [],
|
|
|
+ serviceProvider: []
|
|
|
+ },
|
|
|
+ table: {
|
|
|
+ data: [],
|
|
|
+ total: 0
|
|
|
+ },
|
|
|
+ pickerOptions: {
|
|
|
+ shortcuts: [{
|
|
|
+ text: 'Nearest Week',
|
|
|
+ onClick(picker) {
|
|
|
+ const end = new Date();
|
|
|
+ const start = new Date();
|
|
|
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
|
|
|
+ picker.$emit('pick', [start, end]);
|
|
|
+ }
|
|
|
+ }]
|
|
|
+ },
|
|
|
+ hasGrouptype: ["MNTHFLET", "MNTHMEMB", "MNTHPART"]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.getFilterOptions();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getFilterOptions() {
|
|
|
+ this.loading.filter = true
|
|
|
+ Promise.all([
|
|
|
+ this.getMonthOptions(),
|
|
|
+ this.getReportTypeOptions(),
|
|
|
+ this.getSiteOptions(),
|
|
|
+ this.getServiceProviderList()
|
|
|
+ ]).then(() => {
|
|
|
+ this.loading.filter = false;
|
|
|
+ this.getReportsPages();
|
|
|
+ }).catch(err => {
|
|
|
+ this.loading.filter = false;
|
|
|
+ this.$message({
|
|
|
+ type: 'error',
|
|
|
+ message: err
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ changeReportType() {
|
|
|
+ if (this.hasGrouptype.indexOf(this.filter.pageVo.reportType) >= 0) {
|
|
|
+ this.getGroupOptions();
|
|
|
+ }
|
|
|
+ this.filter.pageVo = {
|
|
|
+ ...this.filter.pageVo,
|
|
|
+ sitePks: [],
|
|
|
+ groupPks: [],
|
|
|
+ providerPks: []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ changeDateRange(range) {
|
|
|
+ if (this.dateRange.length == 2) {
|
|
|
+ this.filter.pageVo.startDate = this.dateRange[0]
|
|
|
+ this.filter.pageVo.endDate = this.dateRange[1]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onSearch() {
|
|
|
+ this.filter.pageNo = 1;
|
|
|
+ this.loading.table = true;
|
|
|
+ setTimeout(() => {
|
|
|
+ this.getReportsPages()
|
|
|
+ }, 3000);
|
|
|
+ },
|
|
|
+ reGenerateReport() {
|
|
|
+ this.loading.generate = true;
|
|
|
+ api.generateReport(this.filter.pageVo).then(res => {
|
|
|
+ this.loading.generate = false;
|
|
|
+ this.$message({
|
|
|
+ type: res.success?'success':'error',
|
|
|
+ message: res.msg
|
|
|
+ })
|
|
|
+ }).catch(err => {
|
|
|
+ this.loading.generate = false;
|
|
|
+ this.$message({
|
|
|
+ type: 'error',
|
|
|
+ message: err
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getServiceProviderList() {
|
|
|
+ return provider.getAllServiceProvider().then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ this.options.serviceProvider = res.data;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getMonthOptions() {
|
|
|
+ return api.getMonthList().then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ this.options.monthOptions = res.data
|
|
|
+ this.filter.pageVo.month = res.data[0].value
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getReportTypeOptions() {
|
|
|
+ return api.getReportTypeList().then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ this.options.reportType = res.data
|
|
|
+ this.filter.pageVo.reportType = res.data[0].value
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getSiteOptions(search) {
|
|
|
+ site.getAllSiteList({siteName: search ?? ""}).then(res => {
|
|
|
+ if (res.data && res.data.length > 0) {
|
|
|
+ this.options.siteOptions = res.data
|
|
|
+ } else {
|
|
|
+ this.options.siteOptions = []
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ this.$message({
|
|
|
+ message: err,
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ this.options.siteOptions = []
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getGroupOptions() {
|
|
|
+ api.getGroupList({
|
|
|
+ reportType: this.filter.pageVo.reportType
|
|
|
+ }).then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ this.options.groupOptions = res.data
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getReportsPages() {
|
|
|
+ this.loading.table = true;
|
|
|
+ api.getReportsPages(this.filter).then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ this.table.data = res.data.map((report) => {
|
|
|
+ report.loading = false
|
|
|
+ return report
|
|
|
+ })
|
|
|
+ this.table.total = res.total
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ this.$message({
|
|
|
+ message: err,
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ }).finally(() => {
|
|
|
+ this.loading.table = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleExportExcel(row) {
|
|
|
+ row.loading = true
|
|
|
+ api.exportReports({ filePk: row.filePk }).then((res) => {
|
|
|
+ this.downloadExcel(res, row.reportName)
|
|
|
+ }).catch(err => {
|
|
|
+ this.$message({
|
|
|
+ message: err,
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ }).finally(() => {
|
|
|
+ row.loading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ downloadExcel(res, fileName) {
|
|
|
+ const blob = new Blob([res], {
|
|
|
+ type: 'application/vnd.ms-excel;charset=utf-8'
|
|
|
+ })
|
|
|
+ if ('download' in document.createElement('a')) {
|
|
|
+ // 非IE下载
|
|
|
+ const elink = document.createElement('a')
|
|
|
+ elink.download = fileName
|
|
|
+ elink.style.display = 'none'
|
|
|
+ elink.href = URL.createObjectURL(blob)
|
|
|
+ document.body.appendChild(elink)
|
|
|
+ elink.click()
|
|
|
+ URL.revokeObjectURL(elink.href) // 释放URL 对象
|
|
|
+ document.body.removeChild(elink)
|
|
|
+ } else {
|
|
|
+ // IE10+下载
|
|
|
+ navigator.msSaveBlob(blob, fileName)
|
|
|
+ }
|
|
|
+ this.excelLoad = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .filter-row {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ .el-form-item__label {
|
|
|
+ color: #333;
|
|
|
+ width: 100px;
|
|
|
+ text-align: right;
|
|
|
+ }
|
|
|
+ .filter-input {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 180px;
|
|
|
+ max-width: 260px;
|
|
|
+ &.half {
|
|
|
+ min-width: 85px;
|
|
|
+ max-width: 125px;
|
|
|
+ }
|
|
|
+ & + .filter-input {
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .generate-button {
|
|
|
+ width: 100px;
|
|
|
+ height: 40px;
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .export-button {
|
|
|
+ background-color: #fff;
|
|
|
+ }
|
|
|
+</style>
|