作者 朱兆平

Merge branch 'master_dev'

@@ -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",
@@ -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
@@ -69,7 +69,7 @@ import WaybillQuerys from './views/nmms_fast/WaybillQuerys.vue' @@ -69,7 +69,7 @@ import WaybillQuerys from './views/nmms_fast/WaybillQuerys.vue'
69 69
70 70
71 71
72 -import echarts from './views/charts/echarts.vue' 72 +import echarts from './views/charts/dataEcharts.vue'
73 import earthCharts from './views/charts/earthCharts.vue' 73 import earthCharts from './views/charts/earthCharts.vue'
74 74
75 import SecrityInspection from './views/staff/security_inspection.vue' 75 import SecrityInspection from './views/staff/security_inspection.vue'
@@ -104,6 +104,7 @@ import queryConfirmatory from './views/airtransport/queryConfirmatory.vue' @@ -104,6 +104,7 @@ import queryConfirmatory from './views/airtransport/queryConfirmatory.vue'
104 import configure from './views/airtransport/configure.vue' 104 import configure from './views/airtransport/configure.vue'
105 import queryConfigure from './views/airtransport/queryConfigure.vue' 105 import queryConfigure from './views/airtransport/queryConfigure.vue'
106 import transit from './views/transit/transit.vue' 106 import transit from './views/transit/transit.vue'
  107 +import transitCharts from './views/transit/transitCharts.vue'
107 import technological from './views/technological/technological.vue' 108 import technological from './views/technological/technological.vue'
108 import example from './views/technological/example.vue' 109 import example from './views/technological/example.vue'
109 import task from './views/technological/task.vue' 110 import task from './views/technological/task.vue'
@@ -532,6 +533,7 @@ let routes = [ @@ -532,6 +533,7 @@ let routes = [
532 iconCls: 'el-icon-delete-location', 533 iconCls: 'el-icon-delete-location',
533 children: [ 534 children: [
534 {path:'/transit',component:transit,name:'转关运抵申报'}, 535 {path:'/transit',component:transit,name:'转关运抵申报'},
  536 + {path:'/transitCharts',component:transitCharts,name:'转关运抵统计'}
535 ] 537 ]
536 }, 538 },
537 { 539 {
@@ -47,9 +47,10 @@ @@ -47,9 +47,10 @@
47 <el-table-column 47 <el-table-column
48 fixed="right" 48 fixed="right"
49 label="操作" 49 label="操作"
50 - width="120"> 50 + width="220">
51 <template slot-scope="scope"> 51 <template slot-scope="scope">
52 <el-button type="danger" size="mini" @click="applyEnd(scope.row)">结束出勤</el-button> 52 <el-button type="danger" size="mini" @click="applyEnd(scope.row)">结束出勤</el-button>
  53 + <el-button type="success" @click="centerDialogVisible = true">图片上传</el-button>
53 </template> 54 </template>
54 </el-table-column> 55 </el-table-column>
55 </el-table> 56 </el-table>
@@ -65,6 +66,31 @@ @@ -65,6 +66,31 @@
65 :total="total"> 66 :total="total">
66 </el-pagination> 67 </el-pagination>
67 </el-row> 68 </el-row>
  69 +
  70 + <el-dialog
  71 + title="提示"
  72 + :visible.sync="centerDialogVisible"
  73 + width="30%"
  74 + center>
  75 + <div>
  76 + <el-upload
  77 + class="avatar-uploader"
  78 + action="https://jsonplaceholder.typicode.com/posts/"
  79 + :show-file-list="false"
  80 + :on-success="handleAvatarSuccess"
  81 + :before-upload="beforeAvatarUpload">
  82 + <img v-if="imageUrl" :src="imageUrl" class="avatar">
  83 + <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  84 + </el-upload>
  85 + <el-input v-model="description" placeholder="请输入图片描述"></el-input>
  86 + </div>
  87 +
  88 +
  89 + <span slot="footer" class="dialog-footer">
  90 + <el-button @click="centerDialogVisible = false">取 消</el-button>
  91 + <el-button type="primary" @click="centerDialogVisible = false">确 定</el-button>
  92 + </span>
  93 + </el-dialog>
68 </el-card> 94 </el-card>
69 </el-row> 95 </el-row>
70 </template> 96 </template>
@@ -75,68 +101,114 @@ @@ -75,68 +101,114 @@
75 export default { 101 export default {
76 data() { 102 data() {
77 return { 103 return {
  104 + centerDialogVisible: false,
78 queryInfo: { 105 queryInfo: {
79 - lisenceNo:'', 106 + lisenceNo: '',
80 // 当前页数 107 // 当前页数
81 pageNum: 1, 108 pageNum: 1,
82 // 每页几条数据 109 // 每页几条数据
83 pageSize: 10, 110 pageSize: 10,
84 }, 111 },
85 total: 0, 112 total: 0,
86 - tableData:[], 113 + tableData: [],
  114 + formInline: {
  115 + user: '',
  116 + },
  117 + imageUrl: '',
  118 + description:''
87 } 119 }
88 }, 120 },
89 methods: { 121 methods: {
90 - handleSizeChange(val) {  
91 - this.queryInfo.pageSize = val  
92 - this.getList() 122 + handleAvatarSuccess(res, file) {
  123 + this.imageUrl = URL.createObjectURL(file.raw);
93 }, 124 },
94 - handleCurrentChange(val) {  
95 - this.queryInfo.pageNum = val  
96 - this.getList()  
97 - },  
98 - getList() {  
99 - const _this = this  
100 - selectList(this.queryInfo).then((response) => {  
101 - const res = response.data  
102 - console.log(response.data)  
103 - if (res.code !== '200') {  
104 - return _this.$message.error('获取消息收发记录,失败!')  
105 - }  
106 - // 获取列表数据  
107 - _this.tableData = res.data.list;  
108 - // 获取列表的总记录数  
109 - _this.total = res.data.total  
110 - _this.$message.success('获取消息收发记录,成功!')  
111 - }).catch(error => {  
112 - // 关闭加载  
113 - _this.$message.error(error.toString())  
114 - }) 125 + beforeAvatarUpload(file) {
  126 + const isJPG = file.type === 'image/jpeg';
  127 + const isLt2M = file.size / 1024 / 1024 < 2;
  128 +
  129 + if (!isJPG) {
  130 + this.$message.error('上传头像图片只能是 JPG 格式!');
  131 + }
  132 + if (!isLt2M) {
  133 + this.$message.error('上传头像图片大小不能超过 2MB!');
  134 + }
  135 + return isJPG && isLt2M;
115 }, 136 },
116 - // 结束出勤  
117 - applyEnd(row) {  
118 - // 弹框询问是否结束?  
119 - this.$confirm('是否继续?', '警告', {  
120 - confirmButtonText: '确定结束',  
121 - cancelButtonText: '取消',  
122 - type: 'warning'  
123 - }  
124 - ).then(() => {  
125 - DoneTask(row).then((response) => { 137 + handleSizeChange(val) {
  138 + this.queryInfo.pageSize = val
  139 + this.getList()
  140 + },
  141 + handleCurrentChange(val) {
  142 + this.queryInfo.pageNum = val
  143 + this.getList()
  144 + },
  145 + getList() {
  146 + const _this = this
  147 + selectList(this.queryInfo).then((response) => {
126 const res = response.data 148 const res = response.data
127 - this.$message.success(res.msg)  
128 - this.getList() 149 + console.log(response.data)
  150 + if (res.code !== '200') {
  151 + return _this.$message.error('获取消息收发记录,失败!')
  152 + }
  153 + // 获取列表数据
  154 + _this.tableData = res.data.list;
  155 + // 获取列表的总记录数
  156 + _this.total = res.data.total
  157 + _this.$message.success('获取消息收发记录,成功!')
129 }).catch(error => { 158 }).catch(error => {
130 - this.$message.error(error) 159 + // 关闭加载
  160 + _this.$message.error(error.toString())
131 }) 161 })
132 - }).catch(() => {  
133 - }) 162 + },
  163 + // 结束出勤
  164 + applyEnd(row) {
  165 + // 弹框询问是否结束?
  166 + this.$confirm('是否继续?', '警告', {
  167 + confirmButtonText: '确定结束',
  168 + cancelButtonText: '取消',
  169 + type: 'warning'
  170 + }
  171 + ).then(() => {
  172 + DoneTask(row).then((response) => {
  173 + const res = response.data
  174 + this.$message.success(res.msg)
  175 + this.getList()
  176 + }).catch(error => {
  177 + this.$message.error(error)
  178 + })
  179 + }).catch(() => {
  180 + })
  181 + },
134 }, 182 },
135 - }, 183 +
136 mounted() { 184 mounted() {
137 this.getList(); 185 this.getList();
138 } 186 }
139 187
140 } 188 }
141 </script> 189 </script>
142 - 190 +<style>
  191 + .avatar-uploader .el-upload {
  192 + border: 1px dashed #d9d9d9;
  193 + border-radius: 6px;
  194 + cursor: pointer;
  195 + position: relative;
  196 + overflow: hidden;
  197 + }
  198 + .avatar-uploader .el-upload:hover {
  199 + border-color: #409EFF;
  200 + }
  201 + .avatar-uploader-icon {
  202 + font-size: 28px;
  203 + color: #8c939d;
  204 + width: 178px;
  205 + height: 178px;
  206 + line-height: 178px;
  207 + text-align: center;
  208 + }
  209 + .avatar {
  210 + width: 178px;
  211 + height: 178px;
  212 + display: block;
  213 + }
  214 +</style>
  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>
@@ -883,6 +883,7 @@ @@ -883,6 +883,7 @@
883 }, 883 },
884 // 获取消息标签列表 884 // 获取消息标签列表
885 trnList() { 885 trnList() {
  886 + this.listLoading = true;
886 const _this = this 887 const _this = this
887 let para = Object.assign({}, this.formTrn) 888 let para = Object.assign({}, this.formTrn)
888 para.creattime = '' 889 para.creattime = ''
@@ -899,6 +900,8 @@ @@ -899,6 +900,8 @@
899 }).catch(error => { 900 }).catch(error => {
900 // 关闭加载 901 // 关闭加载
901 _this.$message.error(error.toString()) 902 _this.$message.error(error.toString())
  903 + }).finally(()=>{
  904 + _this.listLoading = false;
902 }) 905 })
903 }, 906 },
904 //新增编辑弹框关闭重置 907 //新增编辑弹框关闭重置
  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>