作者 朱兆平

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

change: echarts组件版本适配从5.0降级到4.9.0
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 "@xkeshi/vue-barcode": "^1.0.0", 14 "@xkeshi/vue-barcode": "^1.0.0",
15 "axios": "^0.19.0", 15 "axios": "^0.19.0",
16 "common": "^0.2.5", 16 "common": "^0.2.5",
17 - "echarts": "^5.0.1", 17 + "echarts": "^4.9.0",
18 "echarts-liquidfill": "^3.0.0", 18 "echarts-liquidfill": "^3.0.0",
19 "element-ui": "^2.13.2", 19 "element-ui": "^2.13.2",
20 "eslint": "^5.14.1", 20 "eslint": "^5.14.1",
1 import http from './http.js' 1 import http from './http.js'
2 -let baseUrl = 'wlpt-nmms-manage/trans' 2 +let baseUrl = 'wlpt-nmms-manage-trans-arrive/trans'
3 let baseUrl1 = 'cloud-user-center/perm' 3 let baseUrl1 = 'cloud-user-center/perm'
4 4
5 5
@@ -14,6 +14,7 @@ export const addTrans = params => { return http.post(`${baseUrl}/addTrans`, par @@ -14,6 +14,7 @@ export const addTrans = params => { return http.post(`${baseUrl}/addTrans`, par
14 export const ediTrans = params => { return http.post(`${baseUrl}/ediTrans`, params); }; 14 export const ediTrans = params => { return http.post(`${baseUrl}/ediTrans`, params); };
15 export const send = params => { return http.post(`${baseUrl}/send`, params); }; 15 export const send = params => { return http.post(`${baseUrl}/send`, params); };
16 export const role = params => { return http.get(`${baseUrl1}/getPermission`, params); }; 16 export const role = params => { return http.get(`${baseUrl1}/getPermission`, params); };
  17 +export const analysisAPI = params => { return http.post(`${baseUrl}/totalAnalysis`, params); };
17 18
18 19
19 20
@@ -68,7 +68,7 @@ import WaybillQuerys from './views/nmms_fast/WaybillQuerys.vue' @@ -68,7 +68,7 @@ import WaybillQuerys from './views/nmms_fast/WaybillQuerys.vue'
68 68
69 69
70 70
71 -import echarts from './views/charts/echarts.vue' 71 +import echarts from './views/charts/dataEcharts.vue'
72 import earthCharts from './views/charts/earthCharts.vue' 72 import earthCharts from './views/charts/earthCharts.vue'
73 73
74 import SecrityInspection from './views/staff/security_inspection.vue' 74 import SecrityInspection from './views/staff/security_inspection.vue'
@@ -103,6 +103,7 @@ import queryConfirmatory from './views/airtransport/queryConfirmatory.vue' @@ -103,6 +103,7 @@ import queryConfirmatory from './views/airtransport/queryConfirmatory.vue'
103 import configure from './views/airtransport/configure.vue' 103 import configure from './views/airtransport/configure.vue'
104 import queryConfigure from './views/airtransport/queryConfigure.vue' 104 import queryConfigure from './views/airtransport/queryConfigure.vue'
105 import transit from './views/transit/transit.vue' 105 import transit from './views/transit/transit.vue'
  106 +import transitCharts from './views/transit/transitCharts.vue'
106 import technological from './views/technological/technological.vue' 107 import technological from './views/technological/technological.vue'
107 import example from './views/technological/example.vue' 108 import example from './views/technological/example.vue'
108 import task from './views/technological/task.vue' 109 import task from './views/technological/task.vue'
@@ -530,6 +531,7 @@ let routes = [ @@ -530,6 +531,7 @@ let routes = [
530 iconCls: 'el-icon-delete-location', 531 iconCls: 'el-icon-delete-location',
531 children: [ 532 children: [
532 {path:'/transit',component:transit,name:'转关运抵申报'}, 533 {path:'/transit',component:transit,name:'转关运抵申报'},
  534 + {path:'/transitCharts',component:transitCharts,name:'转关运抵统计'}
533 ] 535 ]
534 }, 536 },
535 { 537 {
  1 +<template>
  2 + <section class="todoapp">
  3 + <!-- header -->
  4 + <header class="header">
  5 + <input class="new-todo" autocomplete="off" placeholder="今日申报" @keyup.enter="addTodo">
  6 + </header>
  7 + <!-- main section -->
  8 + <section v-show="todos.length" class="main">
  9 + <input id="toggle-all" :checked="allChecked" class="toggle-all" type="checkbox" @change="toggleAll({ done: !allChecked })">
  10 + <label for="toggle-all" />
  11 + <ul class="todo-list">
  12 + <todo
  13 + v-for="(todo, index) in filteredTodos"
  14 + :key="index"
  15 + :todo="todo"
  16 + @toggleTodo="toggleTodo"
  17 + @editTodo="editTodo"
  18 + @deleteTodo="deleteTodo"
  19 + />
  20 + </ul>
  21 + </section>
  22 + <!-- footer -->
  23 + <footer v-show="todos.length" class="footer">
  24 + <span class="todo-count">
  25 + <strong>{{ remaining }}</strong>
  26 + {{ remaining | pluralize('个转关运抵申请') }} 未申报
  27 + </span>
  28 + <ul class="filters">
  29 + <li v-for="(val, key) in filters" :key="key">
  30 + <a :class="{ selected: visibility === key }" @click.prevent="visibility = key">{{ key | capitalize }}</a>
  31 + </li>
  32 + </ul>
  33 + <!-- <button class="clear-completed" v-show="todos.length > remaining" @click="clearCompleted">
  34 + Clear completed
  35 + </button> -->
  36 + </footer>
  37 + </section>
  38 +</template>
  39 +
  40 +<script>
  41 +import Todo from '@/views/dashboard/components/TodoList/Todo.vue'
  42 +import {selectTrans} from "@/api/trn";
  43 +
  44 +const STORAGE_KEY = 'todos'
  45 +const filters = {
  46 + all: todos => todos,
  47 + active: todos => todos.filter(todo => !todo.done),
  48 + completed: todos => todos.filter(todo => todo.done)
  49 +}
  50 +const defalutList = [
  51 + { text: '78406346432', done: false },
  52 + { text: '78406305165_JHJ42194', done: false },
  53 + { text: '78406347272', done: false },
  54 + { text: '78406346782_DIM896002168', done: true },
  55 + { text: 'vue', done: true },
  56 + { text: 'element-ui', done: true },
  57 + { text: 'axios', done: true },
  58 + { text: 'webpack', done: true }
  59 +]
  60 +export default {
  61 + components: { Todo },
  62 + filters: {
  63 + pluralize: (n, w) => n === 1 ? w : w + ' ',
  64 + capitalize: s => s.charAt(0).toUpperCase() + s.slice(1)
  65 + },
  66 + data() {
  67 + return {
  68 + visibility: 'all',
  69 + filters,
  70 + // todos: JSON.parse(window.localStorage.getItem(STORAGE_KEY)) || defalutList
  71 + todos: []
  72 + }
  73 + },
  74 + computed: {
  75 + allChecked() {
  76 + return this.todos.every(todo => todo.done)
  77 + },
  78 + filteredTodos() {
  79 + return filters[this.visibility](this.todos)
  80 + },
  81 + remaining() {
  82 + return this.todos.filter(todo => !todo.done).length
  83 + }
  84 + },
  85 + mounted:function () {
  86 + this.trnList();
  87 + },
  88 + methods: {
  89 + setLocalStorage() {
  90 + window.localStorage.setItem(STORAGE_KEY, JSON.stringify(this.todos))
  91 + },
  92 + addTodo(e) {
  93 + const text = e.target.value
  94 + if (text.trim()) {
  95 + this.todos.push({
  96 + text,
  97 + done: false
  98 + })
  99 + this.setLocalStorage()
  100 + }
  101 + e.target.value = ''
  102 + },
  103 + toggleTodo(val) {
  104 + val.done = !val.done
  105 + this.setLocalStorage()
  106 + },
  107 + deleteTodo(todo) {
  108 + this.todos.splice(this.todos.indexOf(todo), 1)
  109 + this.setLocalStorage()
  110 + },
  111 + editTodo({ todo, value }) {
  112 + todo.text = value
  113 + this.setLocalStorage()
  114 + },
  115 + clearCompleted() {
  116 + this.todos = this.todos.filter(todo => !todo.done)
  117 + this.setLocalStorage()
  118 + },
  119 + toggleAll({ done }) {
  120 + this.todos.forEach(todo => {
  121 + todo.done = done
  122 + this.setLocalStorage()
  123 + })
  124 + },
  125 + // 获取消息标签列表
  126 + trnList() {
  127 + const loading = this.$loading({
  128 + lock: true,
  129 + text: 'Loading',
  130 + spinner: 'el-icon-loading',
  131 + background: 'rgba(0, 0, 0, 0.7)'
  132 + });
  133 + const _this = this
  134 + let para = {
  135 + billno: '',
  136 + customscode:'',
  137 + username:'',
  138 + trnmode:'',
  139 + unloadcode:'',
  140 + creattime:'',
  141 + startDate:'',
  142 + endDate:'',
  143 + pageNum: 1,
  144 + pageSize: 10
  145 + }
  146 + selectTrans(para).then((response) => {
  147 + const res = response.data
  148 + if (res.code !== '200') {
  149 + return _this.$message.error('获取消息收发记录,失败!')
  150 + }
  151 + // // 获取列表数据
  152 + let tableData = res.data.list
  153 + if (tableData){
  154 + for (let item of tableData) {
  155 + let todoListItem = {text: item.billno, done: false}
  156 + if (item.dstatus === '001') {
  157 + todoListItem.done = true;
  158 + }else{
  159 + todoListItem.done = false;
  160 + }
  161 + _this.todos.push(todoListItem)
  162 + }
  163 + }
  164 + // // 获取列表的总记录数
  165 + // _this.total = res.data.total
  166 + _this.$message.success('获取消息收发记录,成功!')
  167 + }).catch(error => {
  168 + // 关闭加载
  169 + _this.$message.error(error.toString())
  170 + }).finally(()=>{
  171 + loading.close();
  172 + })
  173 + },
  174 + }
  175 +}
  176 +</script>
  177 +
  178 +<style lang="scss">
  179 + @import '~@/views/dashboard/components/TodoList/index.scss';
  180 +</style>
  1 +<template>
  2 + <div :class="className" :style="{height:height,width:width}" />
  3 +</template>
  4 +
  5 +<script>
  6 +import echarts from 'echarts'
  7 +require('echarts/theme/macarons') // echarts theme
  8 +import resize from '@/views/dashboard/components/mixins/resize'
  9 +
  10 +export default {
  11 + mixins: [resize],
  12 + props: {
  13 + className: {
  14 + type: String,
  15 + default: 'chart'
  16 + },
  17 + width: {
  18 + type: String,
  19 + default: '100%'
  20 + },
  21 + height: {
  22 + type: String,
  23 + default: '350px'
  24 + },
  25 + autoResize: {
  26 + type: Boolean,
  27 + default: true
  28 + },
  29 + chartData: {
  30 + type: Object,
  31 + required: true
  32 + }
  33 + },
  34 + data() {
  35 + return {
  36 + chart: null
  37 + }
  38 + },
  39 + watch: {
  40 + chartData: {
  41 + deep: true,
  42 + handler(val) {
  43 + this.setOptions(val)
  44 + }
  45 + }
  46 + },
  47 + mounted() {
  48 + this.$nextTick(() => {
  49 + this.initChart()
  50 + })
  51 + },
  52 + beforeDestroy() {
  53 + if (!this.chart) {
  54 + return
  55 + }
  56 + this.chart.dispose()
  57 + this.chart = null
  58 + },
  59 + methods: {
  60 + initChart() {
  61 + this.chart = echarts.init(this.$el, 'macarons')
  62 + this.setOptions(this.chartData)
  63 + },
  64 + setOptions({ lastWeek, thisWeek, lastYear,thisYear} = {}) {
  65 + this.chart.setOption({
  66 + xAxis: {
  67 + data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
  68 + boundaryGap: true,
  69 + type: 'category',
  70 + axisTick: {
  71 + show: true
  72 + }
  73 + },
  74 + grid: {
  75 + left: 10,
  76 + right: 10,
  77 + bottom: 20,
  78 + top: 30,
  79 + containLabel: true
  80 + },
  81 + tooltip: {
  82 + trigger: 'axis',
  83 + axisPointer: {
  84 + type: 'cross'
  85 + },
  86 + padding: [5, 10]
  87 + },
  88 + yAxis: {
  89 + type: 'value',
  90 + axisTick: {
  91 + show: false
  92 + }
  93 + },
  94 + legend: {
  95 + data: ['本周总申报单量', '上周总申报单量','本周总申报货量','上周总申报货量']
  96 + },
  97 + series: [{
  98 + name: '本周总申报单量', itemStyle: {
  99 + normal: {
  100 + color: '#FF005A',
  101 + lineStyle: {
  102 + color: '#FF005A',
  103 + width: 2
  104 + }
  105 + }
  106 + },
  107 + smooth: true,
  108 + type: 'line',
  109 + data: thisWeek.totalCount,
  110 + animationDuration: 2800,
  111 + animationEasing: 'cubicInOut'
  112 + },
  113 + {
  114 + name: '上周总申报单量',
  115 + smooth: true,
  116 + type: 'line',
  117 + data: lastWeek.totalCount,
  118 + animationDuration: 2800,
  119 + animationEasing: 'cubicInOut'
  120 + },
  121 + {
  122 + name: '本周总申报货量',
  123 + smooth: true,
  124 + type: 'bar',
  125 + itemStyle: {
  126 + normal: {
  127 + color: '#3888fa',
  128 + lineStyle: {
  129 + color: '#3888fa',
  130 + width: 2
  131 + },
  132 + areaStyle: {
  133 + color: '#f3f8ff'
  134 + }
  135 + }
  136 + },
  137 + data: thisWeek.totalWeight,
  138 + animationDuration: 2800,
  139 + animationEasing: 'quadraticOut'
  140 + },
  141 + {
  142 + name: '上周总申报货量',
  143 + smooth: true,
  144 + type: 'bar',
  145 + stack: 'Ad',
  146 + emphasis: {
  147 + focus: 'series'
  148 + },
  149 + data: lastWeek.totalWeight,
  150 + animationDuration: 2800,
  151 + animationEasing: 'quadraticOut'
  152 + },
  153 + ]
  154 + })
  155 + }
  156 + }
  157 +}
  158 +</script>
  1 +<template>
  2 + <div :class="className" :style="{height:height,width:width}" />
  3 +</template>
  4 +
  5 +<script>
  6 +import echarts from 'echarts'
  7 +require('echarts/theme/macarons') // echarts theme
  8 +import resize from '@/views/dashboard/components/mixins/resize'
  9 +
  10 +export default {
  11 + mixins: [resize],
  12 + props: {
  13 + className: {
  14 + type: String,
  15 + default: 'chart'
  16 + },
  17 + width: {
  18 + type: String,
  19 + default: '100%'
  20 + },
  21 + height: {
  22 + type: String,
  23 + default: '350px'
  24 + },
  25 + autoResize: {
  26 + type: Boolean,
  27 + default: true
  28 + },
  29 + chartData: {
  30 + type: Object,
  31 + required: true
  32 + }
  33 + },
  34 + data() {
  35 + return {
  36 + chart: null
  37 + }
  38 + },
  39 + watch: {
  40 + chartData: {
  41 + deep: true,
  42 + handler(val) {
  43 + this.setOptions(val)
  44 + }
  45 + }
  46 + },
  47 + mounted() {
  48 + this.$nextTick(() => {
  49 + this.initChart()
  50 + })
  51 + },
  52 + beforeDestroy() {
  53 + if (!this.chart) {
  54 + return
  55 + }
  56 + this.chart.dispose()
  57 + this.chart = null
  58 + },
  59 + methods: {
  60 + initChart() {
  61 + this.chart = echarts.init(this.$el, 'macarons')
  62 + this.setOptions(this.chartData)
  63 + },
  64 + setOptions({ lastWeek, thisWeek, lastYear,thisYear} = {}) {
  65 + this.chart.setOption({
  66 + xAxis: {
  67 + data: ['一月', '二月', '三月', '四月', '五月', '六月', '七月','八月','九月','十月','十一月','十二月'],
  68 + boundaryGap: true,
  69 + type: 'category',
  70 + axisTick: {
  71 + show: true
  72 + }
  73 + },
  74 + grid: {
  75 + left: 10,
  76 + right: 10,
  77 + bottom: 20,
  78 + top: 30,
  79 + containLabel: true
  80 + },
  81 + tooltip: {
  82 + trigger: 'axis',
  83 + axisPointer: {
  84 + type: 'cross'
  85 + },
  86 + padding: [5, 10]
  87 + },
  88 + yAxis: {
  89 + type: 'value',
  90 + axisTick: {
  91 + show: false
  92 + }
  93 + },
  94 + legend: {
  95 + data: ['本年总申报单量', '去年总申报单量','本年总申报货量','去年总申报货量']
  96 + },
  97 + series: [{
  98 + name: '本年总申报单量', itemStyle: {
  99 + normal: {
  100 + color: '#FF005A',
  101 + lineStyle: {
  102 + color: '#FF005A',
  103 + width: 2
  104 + }
  105 + }
  106 + },
  107 + smooth: true,
  108 + type: 'line',
  109 + data: thisYear.totalCount,
  110 + animationDuration: 2800,
  111 + animationEasing: 'cubicInOut'
  112 + },
  113 + {
  114 + name: '去年总申报单量',
  115 + smooth: true,
  116 + type: 'line',
  117 + data: lastYear.totalCount,
  118 + animationDuration: 2800,
  119 + animationEasing: 'cubicInOut'
  120 + },
  121 + {
  122 + name: '本年总申报货量',
  123 + smooth: true,
  124 + type: 'bar',
  125 + itemStyle: {
  126 + normal: {
  127 + color: '#3888fa',
  128 + lineStyle: {
  129 + color: '#3888fa',
  130 + width: 2
  131 + },
  132 + areaStyle: {
  133 + color: '#f3f8ff'
  134 + }
  135 + }
  136 + },
  137 + data: thisYear.totalWeight,
  138 + animationDuration: 2800,
  139 + animationEasing: 'quadraticOut'
  140 + },
  141 + {
  142 + name: '去年总申报货量',
  143 + smooth: true,
  144 + type: 'bar',
  145 + stack: 'Ad',
  146 + emphasis: {
  147 + focus: 'series'
  148 + },
  149 + data: lastYear.totalWeight,
  150 + animationDuration: 2800,
  151 + animationEasing: 'quadraticOut'
  152 + },
  153 + ]
  154 + })
  155 + }
  156 + }
  157 +}
  158 +</script>
  1 +<template>
  2 + <div class="dashboard-editor-container">
  3 + <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
  4 + <line-chart :chart-data="lineChartData" />
  5 + </el-row>
  6 + <el-row :gutter="8">
  7 + <el-col :xs="{span: 6}" :sm="{span: 6}" :md="{span: 6}" :lg="{span: 6}" :xl="{span: 6}" style="margin-bottom:30px;">
  8 + <todo-list />
  9 + </el-col>
  10 + <el-col :xs="{span: 18}" :sm="{span: 18}" :md="{span: 18}" :lg="{span: 18}" :xl="{span: 18}" style="margin-bottom:30px;background:#fff">
  11 + <week-line-chart :chart-data="lineChartData" />
  12 + </el-col>
  13 + </el-row>
  14 + </div>
  15 +</template>
  16 +
  17 +<script>
  18 + import LineChart from './dashboard/YearLineChart'
  19 + import WeekLineChart from './dashboard/WeekLineChart'
  20 + import TodoList from './dashboard/TodoList'
  21 + import {analysisAPI} from "@/api/trn";
  22 +
  23 + export default {
  24 + name: 'transDashboard',
  25 + components: {
  26 + LineChart,
  27 + TodoList,
  28 + WeekLineChart
  29 + },
  30 + data() {
  31 + return {
  32 + lineChartData: {
  33 + lastWeek:{totalCount:[],totalWeight:[]},
  34 + thisWeek:{totalCount:[],totalWeight:[]},
  35 + lastYear:{totalCount:[],totalWeight:[]},
  36 + thisYear:{totalCount:[],totalWeight:[]}
  37 + }
  38 + }
  39 + },
  40 + methods: {
  41 + getAnalysis:function () {
  42 + const loading = this.$loading({
  43 + lock: true,
  44 + text: '正在加载统计数据',
  45 + spinner: 'el-icon-loading',
  46 + background: 'rgba(0, 0, 0, 0.6)'
  47 + });
  48 + analysisAPI().then(res =>{
  49 + const result = res.data;
  50 + if (result.code === '200') {
  51 + this.lineChartData = this.formatAnalysisData(result)
  52 + this.$message.success('获取数据成功')
  53 + } else {
  54 + this.$message.error('获取数据成功失败,请稍后重试')
  55 + }
  56 + }).catch(err => {
  57 + this.$message.error(err.toString())
  58 + }).finally(()=>{
  59 + loading.close()
  60 + })
  61 + },
  62 + formatAnalysisData:function transformData(originalData) {
  63 + const analysisData = {
  64 + thisWeek: { totalWeight: [], totalCount: [] },
  65 + lastWeek: { totalWeight: [], totalCount: [] },
  66 + lastYear: { totalWeight: [], totalCount: [] },
  67 + thisYear: { totalWeight: [], totalCount: [] },
  68 + };
  69 +
  70 + originalData.data.forEach(item => {
  71 + switch (item.type) {
  72 + case 'thisWeek':
  73 + analysisData.thisWeek.totalWeight.push(item.totalWeight);
  74 + analysisData.thisWeek.totalCount.push(item.totalCount);
  75 + break;
  76 + case 'lastWeek':
  77 + analysisData.lastWeek.totalWeight.push(item.totalWeight);
  78 + analysisData.lastWeek.totalCount.push(item.totalCount);
  79 + break;
  80 + case 'lastYear':
  81 + analysisData.lastYear.totalWeight.push(item.totalWeight);
  82 + analysisData.lastYear.totalCount.push(item.totalCount);
  83 + break;
  84 + case 'thisYear':
  85 + analysisData.thisYear.totalWeight.push(item.totalWeight);
  86 + analysisData.thisYear.totalCount.push(item.totalCount);
  87 + break;
  88 + default:
  89 + console.warn(`Unknown type encountered: ${item.type}`);
  90 + }
  91 + });
  92 +
  93 + // Ensure that each array in 'lastYear' and 'thisYear' has 12 elements for consistency.
  94 + // Fill missing months with zeros if necessary.
  95 + // const months = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
  96 + // months.forEach(month => {
  97 + // if (!analysisData.lastYear[month]) {
  98 + // analysisData.lastYear[month] = { totalWeight: Array(12).fill(0), totalCount: Array(12).fill(0) };
  99 + // }
  100 + // if (!analysisData.thisYear[month]) {
  101 + // analysisData.thisYear[month] = { totalWeight: Array(12).fill(0), totalCount: Array(12).fill(0) };
  102 + // }
  103 + // });
  104 + console.log(JSON.stringify(analysisData))
  105 + return analysisData;
  106 + }
  107 + },
  108 + mounted:function () {
  109 + this.getAnalysis();
  110 + }
  111 + }
  112 +</script>
  113 +
  114 +<style lang="scss" scoped>
  115 + .dashboard-editor-container {
  116 + padding: 32px;
  117 + background-color: rgb(240, 242, 245);
  118 + position: relative;
  119 +
  120 + .github-corner {
  121 + position: absolute;
  122 + top: 0px;
  123 + border: 0;
  124 + right: 0;
  125 + }
  126 +
  127 + .chart-wrapper {
  128 + background: #fff;
  129 + padding: 16px 16px 0;
  130 + margin-bottom: 32px;
  131 + }
  132 + }
  133 +
  134 + @media (max-width:1024px) {
  135 + .chart-wrapper {
  136 + padding: 6px;
  137 + }
  138 + }
  139 +</style>