作者 朱兆平

add: 增加转关运抵统计界面

change: echarts组件版本适配从5.0降级到4.9.0
... ... @@ -14,7 +14,7 @@
"@xkeshi/vue-barcode": "^1.0.0",
"axios": "^0.19.0",
"common": "^0.2.5",
"echarts": "^5.0.1",
"echarts": "^4.9.0",
"echarts-liquidfill": "^3.0.0",
"element-ui": "^2.13.2",
"eslint": "^5.14.1",
... ...
import http from './http.js'
let baseUrl = 'wlpt-nmms-manage/trans'
let baseUrl = 'wlpt-nmms-manage-trans-arrive/trans'
let baseUrl1 = 'cloud-user-center/perm'
... ... @@ -14,6 +14,7 @@ export const addTrans = params => { return http.post(`${baseUrl}/addTrans`, par
export const ediTrans = params => { return http.post(`${baseUrl}/ediTrans`, params); };
export const send = params => { return http.post(`${baseUrl}/send`, params); };
export const role = params => { return http.get(`${baseUrl1}/getPermission`, params); };
export const analysisAPI = params => { return http.post(`${baseUrl}/totalAnalysis`, params); };
... ...
... ... @@ -68,7 +68,7 @@ import WaybillQuerys from './views/nmms_fast/WaybillQuerys.vue'
import echarts from './views/charts/echarts.vue'
import echarts from './views/charts/dataEcharts.vue'
import earthCharts from './views/charts/earthCharts.vue'
import SecrityInspection from './views/staff/security_inspection.vue'
... ... @@ -103,6 +103,7 @@ import queryConfirmatory from './views/airtransport/queryConfirmatory.vue'
import configure from './views/airtransport/configure.vue'
import queryConfigure from './views/airtransport/queryConfigure.vue'
import transit from './views/transit/transit.vue'
import transitCharts from './views/transit/transitCharts.vue'
import technological from './views/technological/technological.vue'
import example from './views/technological/example.vue'
import task from './views/technological/task.vue'
... ... @@ -530,6 +531,7 @@ let routes = [
iconCls: 'el-icon-delete-location',
children: [
{path:'/transit',component:transit,name:'转关运抵申报'},
{path:'/transitCharts',component:transitCharts,name:'转关运抵统计'}
]
},
{
... ...
<template>
<section class="todoapp">
<!-- header -->
<header class="header">
<input class="new-todo" autocomplete="off" placeholder="今日申报" @keyup.enter="addTodo">
</header>
<!-- main section -->
<section v-show="todos.length" class="main">
<input id="toggle-all" :checked="allChecked" class="toggle-all" type="checkbox" @change="toggleAll({ done: !allChecked })">
<label for="toggle-all" />
<ul class="todo-list">
<todo
v-for="(todo, index) in filteredTodos"
:key="index"
:todo="todo"
@toggleTodo="toggleTodo"
@editTodo="editTodo"
@deleteTodo="deleteTodo"
/>
</ul>
</section>
<!-- footer -->
<footer v-show="todos.length" class="footer">
<span class="todo-count">
<strong>{{ remaining }}</strong>
{{ remaining | pluralize('个转关运抵申请') }} 未申报
</span>
<ul class="filters">
<li v-for="(val, key) in filters" :key="key">
<a :class="{ selected: visibility === key }" @click.prevent="visibility = key">{{ key | capitalize }}</a>
</li>
</ul>
<!-- <button class="clear-completed" v-show="todos.length > remaining" @click="clearCompleted">
Clear completed
</button> -->
</footer>
</section>
</template>
<script>
import Todo from '@/views/dashboard/components/TodoList/Todo.vue'
import {selectTrans} from "@/api/trn";
const STORAGE_KEY = 'todos'
const filters = {
all: todos => todos,
active: todos => todos.filter(todo => !todo.done),
completed: todos => todos.filter(todo => todo.done)
}
const defalutList = [
{ text: '78406346432', done: false },
{ text: '78406305165_JHJ42194', done: false },
{ text: '78406347272', done: false },
{ text: '78406346782_DIM896002168', done: true },
{ text: 'vue', done: true },
{ text: 'element-ui', done: true },
{ text: 'axios', done: true },
{ text: 'webpack', done: true }
]
export default {
components: { Todo },
filters: {
pluralize: (n, w) => n === 1 ? w : w + ' ',
capitalize: s => s.charAt(0).toUpperCase() + s.slice(1)
},
data() {
return {
visibility: 'all',
filters,
// todos: JSON.parse(window.localStorage.getItem(STORAGE_KEY)) || defalutList
todos: []
}
},
computed: {
allChecked() {
return this.todos.every(todo => todo.done)
},
filteredTodos() {
return filters[this.visibility](this.todos)
},
remaining() {
return this.todos.filter(todo => !todo.done).length
}
},
mounted:function () {
this.trnList();
},
methods: {
setLocalStorage() {
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(this.todos))
},
addTodo(e) {
const text = e.target.value
if (text.trim()) {
this.todos.push({
text,
done: false
})
this.setLocalStorage()
}
e.target.value = ''
},
toggleTodo(val) {
val.done = !val.done
this.setLocalStorage()
},
deleteTodo(todo) {
this.todos.splice(this.todos.indexOf(todo), 1)
this.setLocalStorage()
},
editTodo({ todo, value }) {
todo.text = value
this.setLocalStorage()
},
clearCompleted() {
this.todos = this.todos.filter(todo => !todo.done)
this.setLocalStorage()
},
toggleAll({ done }) {
this.todos.forEach(todo => {
todo.done = done
this.setLocalStorage()
})
},
// 获取消息标签列表
trnList() {
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
const _this = this
let para = {
billno: '',
customscode:'',
username:'',
trnmode:'',
unloadcode:'',
creattime:'',
startDate:'',
endDate:'',
pageNum: 1,
pageSize: 10
}
selectTrans(para).then((response) => {
const res = response.data
if (res.code !== '200') {
return _this.$message.error('获取消息收发记录,失败!')
}
// // 获取列表数据
let tableData = res.data.list
if (tableData){
for (let item of tableData) {
let todoListItem = {text: item.billno, done: false}
if (item.dstatus === '001') {
todoListItem.done = true;
}else{
todoListItem.done = false;
}
_this.todos.push(todoListItem)
}
}
// // 获取列表的总记录数
// _this.total = res.data.total
_this.$message.success('获取消息收发记录,成功!')
}).catch(error => {
// 关闭加载
_this.$message.error(error.toString())
}).finally(()=>{
loading.close();
})
},
}
}
</script>
<style lang="scss">
@import '~@/views/dashboard/components/TodoList/index.scss';
</style>
... ...
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from '@/views/dashboard/components/mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '350px'
},
autoResize: {
type: Boolean,
default: true
},
chartData: {
type: Object,
required: true
}
},
data() {
return {
chart: null
}
},
watch: {
chartData: {
deep: true,
handler(val) {
this.setOptions(val)
}
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.setOptions(this.chartData)
},
setOptions({ lastWeek, thisWeek, lastYear,thisYear} = {}) {
this.chart.setOption({
xAxis: {
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
boundaryGap: true,
type: 'category',
axisTick: {
show: true
}
},
grid: {
left: 10,
right: 10,
bottom: 20,
top: 30,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: {
type: 'value',
axisTick: {
show: false
}
},
legend: {
data: ['本周总申报单量', '上周总申报单量','本周总申报货量','上周总申报货量']
},
series: [{
name: '本周总申报单量', itemStyle: {
normal: {
color: '#FF005A',
lineStyle: {
color: '#FF005A',
width: 2
}
}
},
smooth: true,
type: 'line',
data: thisWeek.totalCount,
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
{
name: '上周总申报单量',
smooth: true,
type: 'line',
data: lastWeek.totalCount,
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
{
name: '本周总申报货量',
smooth: true,
type: 'bar',
itemStyle: {
normal: {
color: '#3888fa',
lineStyle: {
color: '#3888fa',
width: 2
},
areaStyle: {
color: '#f3f8ff'
}
}
},
data: thisWeek.totalWeight,
animationDuration: 2800,
animationEasing: 'quadraticOut'
},
{
name: '上周总申报货量',
smooth: true,
type: 'bar',
stack: 'Ad',
emphasis: {
focus: 'series'
},
data: lastWeek.totalWeight,
animationDuration: 2800,
animationEasing: 'quadraticOut'
},
]
})
}
}
}
</script>
... ...
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from '@/views/dashboard/components/mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '350px'
},
autoResize: {
type: Boolean,
default: true
},
chartData: {
type: Object,
required: true
}
},
data() {
return {
chart: null
}
},
watch: {
chartData: {
deep: true,
handler(val) {
this.setOptions(val)
}
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.setOptions(this.chartData)
},
setOptions({ lastWeek, thisWeek, lastYear,thisYear} = {}) {
this.chart.setOption({
xAxis: {
data: ['一月', '二月', '三月', '四月', '五月', '六月', '七月','八月','九月','十月','十一月','十二月'],
boundaryGap: true,
type: 'category',
axisTick: {
show: true
}
},
grid: {
left: 10,
right: 10,
bottom: 20,
top: 30,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: {
type: 'value',
axisTick: {
show: false
}
},
legend: {
data: ['本年总申报单量', '去年总申报单量','本年总申报货量','去年总申报货量']
},
series: [{
name: '本年总申报单量', itemStyle: {
normal: {
color: '#FF005A',
lineStyle: {
color: '#FF005A',
width: 2
}
}
},
smooth: true,
type: 'line',
data: thisYear.totalCount,
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
{
name: '去年总申报单量',
smooth: true,
type: 'line',
data: lastYear.totalCount,
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
{
name: '本年总申报货量',
smooth: true,
type: 'bar',
itemStyle: {
normal: {
color: '#3888fa',
lineStyle: {
color: '#3888fa',
width: 2
},
areaStyle: {
color: '#f3f8ff'
}
}
},
data: thisYear.totalWeight,
animationDuration: 2800,
animationEasing: 'quadraticOut'
},
{
name: '去年总申报货量',
smooth: true,
type: 'bar',
stack: 'Ad',
emphasis: {
focus: 'series'
},
data: lastYear.totalWeight,
animationDuration: 2800,
animationEasing: 'quadraticOut'
},
]
})
}
}
}
</script>
... ...
<template>
<div class="dashboard-editor-container">
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
<line-chart :chart-data="lineChartData" />
</el-row>
<el-row :gutter="8">
<el-col :xs="{span: 6}" :sm="{span: 6}" :md="{span: 6}" :lg="{span: 6}" :xl="{span: 6}" style="margin-bottom:30px;">
<todo-list />
</el-col>
<el-col :xs="{span: 18}" :sm="{span: 18}" :md="{span: 18}" :lg="{span: 18}" :xl="{span: 18}" style="margin-bottom:30px;background:#fff">
<week-line-chart :chart-data="lineChartData" />
</el-col>
</el-row>
</div>
</template>
<script>
import LineChart from './dashboard/YearLineChart'
import WeekLineChart from './dashboard/WeekLineChart'
import TodoList from './dashboard/TodoList'
import {analysisAPI} from "@/api/trn";
export default {
name: 'transDashboard',
components: {
LineChart,
TodoList,
WeekLineChart
},
data() {
return {
lineChartData: {
lastWeek:{totalCount:[],totalWeight:[]},
thisWeek:{totalCount:[],totalWeight:[]},
lastYear:{totalCount:[],totalWeight:[]},
thisYear:{totalCount:[],totalWeight:[]}
}
}
},
methods: {
getAnalysis:function () {
const loading = this.$loading({
lock: true,
text: '正在加载统计数据',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.6)'
});
analysisAPI().then(res =>{
const result = res.data;
if (result.code === '200') {
this.lineChartData = this.formatAnalysisData(result)
this.$message.success('获取数据成功')
} else {
this.$message.error('获取数据成功失败,请稍后重试')
}
}).catch(err => {
this.$message.error(err.toString())
}).finally(()=>{
loading.close()
})
},
formatAnalysisData:function transformData(originalData) {
const analysisData = {
thisWeek: { totalWeight: [], totalCount: [] },
lastWeek: { totalWeight: [], totalCount: [] },
lastYear: { totalWeight: [], totalCount: [] },
thisYear: { totalWeight: [], totalCount: [] },
};
originalData.data.forEach(item => {
switch (item.type) {
case 'thisWeek':
analysisData.thisWeek.totalWeight.push(item.totalWeight);
analysisData.thisWeek.totalCount.push(item.totalCount);
break;
case 'lastWeek':
analysisData.lastWeek.totalWeight.push(item.totalWeight);
analysisData.lastWeek.totalCount.push(item.totalCount);
break;
case 'lastYear':
analysisData.lastYear.totalWeight.push(item.totalWeight);
analysisData.lastYear.totalCount.push(item.totalCount);
break;
case 'thisYear':
analysisData.thisYear.totalWeight.push(item.totalWeight);
analysisData.thisYear.totalCount.push(item.totalCount);
break;
default:
console.warn(`Unknown type encountered: ${item.type}`);
}
});
// Ensure that each array in 'lastYear' and 'thisYear' has 12 elements for consistency.
// Fill missing months with zeros if necessary.
// const months = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
// months.forEach(month => {
// if (!analysisData.lastYear[month]) {
// analysisData.lastYear[month] = { totalWeight: Array(12).fill(0), totalCount: Array(12).fill(0) };
// }
// if (!analysisData.thisYear[month]) {
// analysisData.thisYear[month] = { totalWeight: Array(12).fill(0), totalCount: Array(12).fill(0) };
// }
// });
console.log(JSON.stringify(analysisData))
return analysisData;
}
},
mounted:function () {
this.getAnalysis();
}
}
</script>
<style lang="scss" scoped>
.dashboard-editor-container {
padding: 32px;
background-color: rgb(240, 242, 245);
position: relative;
.github-corner {
position: absolute;
top: 0px;
border: 0;
right: 0;
}
.chart-wrapper {
background: #fff;
padding: 16px 16px 0;
margin-bottom: 32px;
}
}
@media (max-width:1024px) {
.chart-wrapper {
padding: 6px;
}
}
</style>
... ...