作者 朱兆平

进出港统计分析部分

... ... @@ -1972,9 +1972,9 @@
}
},
"cfb": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/cfb/-/cfb-1.1.3.tgz",
"integrity": "sha512-joXBW0nMuwV9no7UTMiyVJnQL6XIU3ThXVjFUDHgl9MpILPOomyfaGqC290VELZ48bbQKZXnQ81UT5HouTxHsw==",
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/cfb/-/cfb-1.1.4.tgz",
"integrity": "sha512-rwFkl3aFO3f+ljR27YINwC0x8vPjyiEVbYbrTCKzspEf7Q++3THdfHVgJYNUbxNcupJECrLX+L40Mjm9hm/Bgw==",
"requires": {
"adler-32": "~1.2.0",
"commander": "^2.16.0",
... ... @@ -6313,7 +6313,7 @@
},
"normalize-wheel": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/normalize-wheel/download/normalize-wheel-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
"integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
},
"npm": {
... ... @@ -10548,7 +10548,8 @@
"raw-loader": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
"integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao="
"integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=",
"dev": true
},
"read-pkg": {
"version": "1.1.0",
... ... @@ -11355,6 +11356,7 @@
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/script-loader/-/script-loader-0.7.2.tgz",
"integrity": "sha512-UMNLEvgOAQuzK8ji8qIscM3GIrRCWN6MmMXGD4SD5l6cSycgGsCo0tX5xRnfQcoghqct0tjHjcykgI1PyBE2aA==",
"dev": true,
"requires": {
"raw-loader": "~0.5.1"
}
... ... @@ -11769,9 +11771,9 @@
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"ssf": {
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.10.2.tgz",
"integrity": "sha512-rDhAPm9WyIsY8eZEKyE8Qsotb3j/wBdvMWBUsOhJdfhKGLfQidRjiBUV0y/MkyCLiXQ38FG6LWW/VYUtqlIDZQ==",
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.10.3.tgz",
"integrity": "sha512-pRuUdW0WwyB2doSqqjWyzwCD6PkfxpHAHdZp39K3dp/Hq7f+xfMwNAWIi16DyrRg4gg9c/RvLYkJTSawTPTm1w==",
"requires": {
"frac": "~1.1.2"
}
... ... @@ -13105,6 +13107,11 @@
"integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
"dev": true
},
"wmf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw=="
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
... ... @@ -13180,17 +13187,18 @@
}
},
"xlsx": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.15.1.tgz",
"integrity": "sha512-z+o4+QPMc32EPboLCzJAz94o0Zyy+8jrmWTsVpfzwknFln9qDO6/HN1KrGGVC4//sGA7dh4R3HA4fhbGIKCDOA==",
"version": "0.15.6",
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.15.6.tgz",
"integrity": "sha512-7vD9eutyLs65iDjNFimVN+gk/oDkfkCgpQUjdE82QgzJCrBHC4bGPH7fzKVyy0UPp3gyFVQTQEFJaWaAvZCShQ==",
"requires": {
"adler-32": "~1.2.0",
"cfb": "^1.1.3",
"cfb": "^1.1.4",
"codepage": "~1.14.0",
"commander": "~2.17.1",
"crc-32": "~1.2.0",
"exit-on-epipe": "~1.0.1",
"ssf": "~0.10.2"
"ssf": "~0.10.3",
"wmf": "~1.0.1"
}
},
"xtend": {
... ...
... ... @@ -22,12 +22,11 @@
"moment": "^2.24.0",
"npm": "^6.8.0",
"nprogress": "^0.2.0",
"script-loader": "^0.7.2",
"vue": "^2.2.2",
"vue-i18n": "^8.14.0",
"vue-router": "^2.3.0",
"vuex": "^2.0.0-rc.6",
"xlsx": "^0.15.1"
"xlsx": "^0.15.6"
},
"devDependencies": {
"autoprefixer": "^6.7.2",
... ... @@ -64,6 +63,7 @@
"qs": "^6.7.0",
"rimraf": "^2.6.0",
"sass-loader": "^6.0.0",
"script-loader": "^0.7.2",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"url-loader": "^0.5.8",
... ...
import http from '../http.js'
let baseUrl = '/analysis-agent/agent'
export const getAnalysisList = params => { return http.get(`${baseUrl}/analysis`,params) };
export const getNmmsAnalysisList = params => { return http.get(`/analysis-nmms/nmmsAnalysis/analysis`,params) };
... ...
... ... @@ -18,6 +18,7 @@ export default {
method: 'GET',
url: url,
params: params,
timeout: 30000,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
... ...
... ... @@ -65,6 +65,7 @@ router.beforeEach((to, from, next) => {
const message = Vue.prototype.$message;
axios.defaults.baseURL = '/api';
axios.defaults.timeout = 120000;
axios.interceptors.response.use(
res => {
//对响应数据做些事
... ... @@ -119,6 +120,14 @@ axios.interceptors.response.use(
path: "/error/502"
});
}
if (error.response.status === 503) {
message({
// 饿了么的消息弹窗组件
message: '503相关服务服务未找到',
type: "error"
});
}
if (error.response.status === 404) {
message({
// 饿了么的消息弹窗组件
... ...
... ... @@ -48,6 +48,8 @@ import ComeCar from './views/staff/come_car.vue'
import OnDuty from './views/staff/on_duty.vue'
import WaterStationsPatrol from './views/water/water_stations_patrol.vue'
import Location from './views/empt/Location.vue'
import AgentExcelExport from './views/excel/exportExcel-agent'
import NMMSExcelExport from './views/excel/exportExcel-NMMS'
let routes = [
{
... ... @@ -100,6 +102,16 @@ let routes = [
]
},
{
path: '/analysis',
component: Home,
name: '统计分析',
iconCls: 'fa fa-id-card-o',
children: [
{ path: '/agentexport', component: AgentExcelExport, name: '出港统计' },
{ path: '/nmmsexport', component: NMMSExcelExport, name: '进港统计' },
]
},
{
path: '/output',
component: Home,
name: '出港业务申报',
... ...
<template>
<div style="display:inline-block;">
<label class="radio-label">导出是否自动适配列宽: </label>
<el-radio-group v-model="autoWidth">
<el-radio :label="true" border>True</el-radio>
<el-radio :label="false" border>False</el-radio>
</el-radio-group>
</div>
</template>
<script>
export default {
props: {
value: {
type: Boolean,
default: true
}
},
computed: {
autoWidth: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>
... ...
<template>
<div style="display:inline-block;">
<label class="radio-label">导出类型: </label>
<el-select v-model="bookType" style="width:120px;" >
<el-option
v-for="item in options"
:key="item"
:label="item"
:value="item"/>
</el-select>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: 'xlsx'
}
},
data() {
return {
options: ['xlsx', 'csv', 'txt']
}
},
computed: {
bookType: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>
... ...
<template>
<div style="display:inline-block;">
<!-- $t is vue-i18n global function to translate lang -->
<label class="radio-label" style="padding-left:0;">导出文件名: </label>
<el-input placeholder="非必填,默认导出文件名为excel-list.xlsx" v-model="filename" style="width:340px;" prefix-icon="el-icon-document"/>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: ''
}
},
computed: {
filename: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>
... ...
<template>
<!-- $t is vue-i18n global function to translate lang -->
<div class="app-container">
<!--工具条-->
<el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
<el-form :inline="true" :model="searchText">
<el-form-item>
<el-date-picker v-model="searchText.startdate" value-format="yyyy-MM-dd" type="date"
placeholder="开始航班日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-date-picker v-model="searchText.enddate" value-format="yyyy-MM-dd" type="date"
placeholder="结束航班日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button :loading="listLoading" style="margin:0 0 20px 20px;" type="primary" icon="document" @click="fetchData">查询</el-button>
</el-form-item>
<el-tag
:key="note.message"
:type="note.type">
{{note.message}}
</el-tag>
</el-form>
</el-col>
<div>
<FilenameOption v-model="filename" />
<AutoWidthOption v-model="autoWidth" />
<BookTypeOption v-model="bookType" />
<el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="document" @click="handleDownload">导出 Excel</el-button>
</div>
<el-table v-loading="listLoading" element-loading-text="拼命加载中" border fit highlight-current-row>
<el-table-column align="center" label="Id" width="95">
<template slot-scope="scope">
{{ scope.$index }}
</template>
</el-table-column>
<el-table-column label="运单号">
<template slot-scope="scope">
{{ scope.row.waybillnomaster }}
</template>
</el-table-column>
<el-table-column label="航班号" width="115" align="center">
<template slot-scope="scope">
{{ scope.row.flightno }}
</template>
</el-table-column>
<el-table-column align="center" label="航班日期" width="220" :formatter="dateFormat">
<template slot-scope="scope">
<i class="el-icon-time"/>
<span>{{ scope.row.flightDate | parseTime('{y}-{m}-{d}')}}</span>
</template>
</el-table-column>
<el-table-column label="航段" width="110" align="center">
<template slot-scope="scope">
<el-tag>{{ scope.row.segment }}</el-tag>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { getNmmsAnalysisList } from '@/api/agent-excel'
import { parseTime } from '@/utils'
// options components
import FilenameOption from './components/FilenameOption'
import AutoWidthOption from './components/AutoWidthOption'
import BookTypeOption from './components/BookTypeOption'
import Export2Excel from '@/vendor/Export2Excel'
export default {
name: 'ExportExcelNMMS',
components: { FilenameOption, AutoWidthOption, BookTypeOption },
data() {
return {
list: [],
fetchList: [],
listLoading: false,
downloadLoading: false,
filename: '',
autoWidth: true,
bookType: 'xlsx',
searchText: {
startdate: undefined,
enddate: undefined
},
note: {
type: 'info',
message: ''
}
}
},
created() {
// this.fetchData()
},
filters: {
parseTime: parseTime
},
methods: {
dateFormat:function(row,column){
var t=new Date(row.updateTime);//row 表示一行数据, updateTime 表示要格式化的字段名称
return t.getFullYear()+"-"+(t.getMonth()+1)+"-"+t.getDate();
},
fetchData() {
this.listLoading = true
getNmmsAnalysisList(this.searchText).then(response => {
this.list = response.data.data
this.listLoading = false
this.$message({
message: '数据查询成功,可以下载excel',
type: 'success'
});
this.note.message = '数据查询成功,可以下载excel;共'+this.list.length+'条数据';
this.note.type = 'success';
})
},
handleDownload() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = [
'航班号',
'航班日期',
'航段',
'主运单号',
'分单号',
'运单件数',
'运单重量',
'舱单件数',
'舱单重量',
'品名',
'航班起始站',
'航班起始站中文',
'航班目的站',
'航班目的站中文',
'发货人国家',
'发货人国家中文',
'发货人区域'
]
const filterVal = [
'flightno',
'flightDate',
'segment',
'waybillnomaster',
'waybillnosecondary',
'totalpiece',
'totalweight',
'manifesttotalpiece',
'manifesttotalweight',
'productname',
'originatingstation',
'originatingstationcn',
'destinationstation',
'destinationstationcn',
'shipperCountrycode',
'countrydescchn',
'areadescchn'
]
const list = this.list
const data = this.formatJson(filterVal, list)
excel.export_json_to_excel({
header: tHeader,
data,
filename: this.filename,
autoWidth: this.autoWidth,
bookType: this.bookType
})
this.downloadLoading = false
})
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => {
if (j === 'timestamp') {
return parseTime(v[j])
} else {
return v[j]
}
}))
}
}
}
</script>
<style>
.radio-label {
font-size: 14px;
color: #606266;
line-height: 40px;
padding: 0 12px 0 30px;
}
</style>
... ...
<template>
<!-- $t is vue-i18n global function to translate lang -->
<div class="app-container">
<!--工具条-->
<el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
<el-form :inline="true" :model="searchText">
<el-form-item>
<el-date-picker v-model="searchText.startdate" value-format="yyyy-MM-dd" type="date"
placeholder="开始航班日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-date-picker v-model="searchText.enddate" value-format="yyyy-MM-dd" type="date"
placeholder="结束航班日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="document" @click="fetchData">查询</el-button>
</el-form-item>
</el-form>
</el-col>
<div>
<FilenameOption v-model="filename" />
<AutoWidthOption v-model="autoWidth" />
<BookTypeOption v-model="bookType" />
<el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="document" @click="handleDownload">导出 Excel</el-button>
</div>
<el-table v-loading="listLoading" :data="list" element-loading-text="拼命加载中" border fit highlight-current-row>
<el-table-column align="center" label="Id" width="95">
<template slot-scope="scope">
{{ scope.$index }}
</template>
</el-table-column>
<el-table-column label="运单号">
<template slot-scope="scope">
{{ scope.row.autoid }}
</template>
</el-table-column>
<el-table-column label="承运人" width="110" align="center">
<template slot-scope="scope">
<el-tag>{{ scope.row.totalpiece }}</el-tag>
</template>
</el-table-column>
<el-table-column label="航班号" width="115" align="center">
<template slot-scope="scope">
{{ scope.row.manifesttotalpiece }}
</template>
</el-table-column>
<el-table-column align="center" label="航班日期" width="220" :formatter="dateFormat">
<template slot-scope="scope">
<i class="el-icon-time"/>
<span>{{ scope.row.manifesttotalweight | parseTime('{y}-{m}-{d}')}}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { getAnalysisList } from '@/api/agent-excel'
import { parseTime } from '@/utils'
// options components
import FilenameOption from './components/FilenameOption'
import AutoWidthOption from './components/AutoWidthOption'
import BookTypeOption from './components/BookTypeOption'
import Export2Excel from '@/vendor/Export2Excel'
export default {
name: 'ExportExcel',
components: { FilenameOption, AutoWidthOption, BookTypeOption },
data() {
return {
list: [],
fetchList: [],
listLoading: false,
downloadLoading: false,
filename: '',
autoWidth: true,
bookType: 'xlsx',
searchText: {
startdate: undefined,
enddate: undefined
}
}
},
created() {
// this.fetchData()
},
filters: {
parseTime: parseTime
},
methods: {
dateFormat:function(row,column){
var t=new Date(row.updateTime);//row 表示一行数据, updateTime 表示要格式化的字段名称
return t.getFullYear()+"-"+(t.getMonth()+1)+"-"+t.getDate();
},
fetchData() {
this.listLoading = true
getAnalysisList(this.searchText).then(response => {
this.list = response.data.data
this.listLoading = false
})
},
handleDownload() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['运单号',
'航空托运人名称',
'航空销售代理人名称',
'航协编号',
'航空公司运输证明',
'运输条件鉴定书',
'承运人',
'航班号',
'航班日期',
'航班起始站',
'航班目的站',
'运单件数',
'运单重量',
'操作时间',
'关区',
'预配品名',
'收货人公司',
'收货人地址',
'收货人城市',
'收货人电话',
'收货人国家',
'收货人名称',
'发货人名称',
'发货人地址',
'发货人城市',
'发货人国家',
'发货人电话',
'发货人名称',
'海关回执状态',
'海关回执信息',
'发货人编码',
'收货人编码',
'货物品名',
'二级类名称',
'一级类名称',
'代理人三字码',
'代理人全称',
'代理人类别',
'代理联系人',
'代理联系人电话'
]
const filterVal = [
'autoid',
'waybillnomaster',
'segment',
'originatingstation',
'destinationstation',
'totalweight',
'totalpiece',
'manifesttotalpiece',
'manifesttotalweight',
'flightno',
'productname',
'customsstatus',
'carrier1',
'arrivalstation1',
'carrier2',
'arrivalstation2',
'carrier3',
'arrivalstation3',
'paymode',
'customscode',
'specialgoodscode',
'shippername',
'shipperaddress',
'consigneename',
'consigneeaddress',
'receiptinformation',
'specificConsigneePhone',
'consigneePhone',
'status',
'isbatch',
'originatingstationBill',
'destinationstationBill',
'reportorder',
'islast',
'shipperCode',
'shipperCountrycode',
'shipperPhone',
'shipperFax',
'consigneeCode',
'consigneeCountrycode'
]
const list = this.list
const data = this.formatJson(filterVal, list)
excel.export_json_to_excel({
header: tHeader,
data,
filename: this.filename,
autoWidth: this.autoWidth,
bookType: this.bookType
})
this.downloadLoading = false
})
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => {
if (j === 'timestamp') {
return parseTime(v[j])
} else {
return v[j]
}
}))
}
}
}
</script>
<style>
.radio-label {
font-size: 14px;
color: #606266;
line-height: 40px;
padding: 0 12px 0 30px;
}
</style>
... ...