ソースを参照

Merge branch 'deploy_0106' of chelingzhu-web/zxyj-admin-html into master

lilei 4 年 前
コミット
ec1da00a06
30 ファイル変更3792 行追加362 行削除
  1. 228 0
      src/api/cleanManage.js
  2. 40 0
      src/api/electronicScale.js
  3. 1 1
      src/api/power-user.js
  4. 1 1
      src/api/releaseRecord.js
  5. 23 1
      src/api/userInfo.js
  6. 69 47
      src/components/Echarts/bar.vue
  7. 32 13
      src/components/Echarts/line.vue
  8. 4 0
      src/components/Echarts/pie.vue
  9. 100 2
      src/config/router.config.js
  10. 153 0
      src/views/cleanManage/addDiverModal.vue
  11. 251 0
      src/views/cleanManage/cleanDetail.vue
  12. 77 0
      src/views/cleanManage/cleanDetailModal.vue
  13. 132 0
      src/views/cleanManage/cleanModal.vue
  14. 187 0
      src/views/cleanManage/driverManage.vue
  15. 101 0
      src/views/cleanManage/netWorkCleanModal.vue
  16. 224 0
      src/views/cleanManage/netWorkCleanRecord.vue
  17. 412 0
      src/views/cleanManage/notCleanNetwork.vue
  18. 607 0
      src/views/cleanManage/statisticalReport.vue
  19. 217 234
      src/views/equipmentManage/boxSetting/boxSetting.vue
  20. 139 0
      src/views/equipmentManage/electronicScale/addElectronicScale.vue
  21. 226 0
      src/views/equipmentManage/electronicScale/electronicScale.vue
  22. 1 1
      src/views/equipmentManage/equipment/equipment.vue
  23. 8 5
      src/views/equipmentManage/exchangeSetting/ExchangeSetting.vue
  24. 8 2
      src/views/equipmentManage/network/detailsModal.vue
  25. 13 19
      src/views/equipmentManage/network/equipmentModal.vue
  26. 1 1
      src/views/map/NodeMap.vue
  27. 258 0
      src/views/market/luckDrawRecord.vue
  28. 43 34
      src/views/releaseRecord/releaseRecordList.vue
  29. 235 0
      src/views/userInfo/allLdDetail.vue
  30. 1 1
      vue.config.js

+ 228 - 0
src/api/cleanManage.js

@@ -0,0 +1,228 @@
+import { axios } from '@/utils/request'
+
+// 清运管理--网点清运记录
+
+// 列表
+export const cleanRecordList = (params) => {
+  const url = `cleanStationDevice/queryCountByStation/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 总计
+export const getCleanStationTotal = (params) => {
+  const url = `cleanStationDevice/getCleanStationDeviceTotal`
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 详情
+export const networkDetail = (params) => {
+  const url = `cleanStationDevice/querycleanStationParticular/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 清运明细
+// 列表
+export const cleanDetailsList = (params) => {
+  const url = `cleanStationDevice/queryCleanStationDeviceByDevice/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 总计
+export const getCleanDetailsTotal = (params) => {
+  const url = `cleanStationDevice/getCleanStationDeviceTotal`
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 详情
+export const getCleanDetails = (params) => {
+  const url = `cleanLog/queryCleanStationDeviceParticular`
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 操作人
+export const cleanUserList = (params) => {
+  const url = `zxyj/user/queryCleanUserList`
+  return axios.request({
+    url: url,
+    data: {},
+    method: 'post'
+  })
+}
+
+// 待清运列表
+export const netWorkCleanRecordList = (params) => {
+  const url = `cleanStationDevice/waitToClean/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 总计
+export const getCleanStationSum = (params) => {
+  const url = `cleanStationDevice/waitToClean/sum`
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 立即清运
+export const cleanByDevice = params => {
+  return axios({
+    url: `cleanStationDevice/cleanByDevice`,
+    data: params,
+    method: 'POST'
+  })
+}
+
+// 司机管理
+// 重置密码
+export const resetPSD = params => {
+  return axios({
+    url: `zxyj/user/resetPwd`,
+    data: params,
+    method: 'POST'
+  })
+}
+
+// 获取列表数据
+export const getDriverList = params => {
+  const url = `/driver/queryLike/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'POST'
+  })
+}
+
+// 清运司机  全部
+export const driverQueryList = (params) => {
+  const url = `driver/queryDriverList`
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 查司机
+export const findDriverName = params => {
+  return axios({
+    url: `driver/findById/${params.id}`,
+    data: params,
+    method: 'get'
+  })
+}
+
+// 删除用户接口
+export const delectDriver = params => {
+  return axios({
+    url: `driver/delete/${params.id}`,
+    data: params,
+    method: 'get'
+  })
+}
+
+// 新增/编辑保存接口
+export const saveDriver = params => {
+  return axios({
+    url: '/driver/save',
+    data: params,
+    method: 'POST'
+  })
+}
+
+// 编辑查详情
+export const driverDetails = (params) => {
+  const url = `driver/findById/${params.id}`
+  return axios({
+    url: url,
+    data: params,
+    method: 'get'
+  })
+}
+
+// 清运管理  统计报表
+export const getCleanReport = (params) => {
+  const url = `cleanReport/getReport`
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 各回收物类型清运数据总计
+export const findTotalGroupRubbi = (params) => {
+  const url = `cleanReport/findTotalGroupRubbishType`
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 各清运司机占比
+export const findTotalGroupUser = (params) => {
+  const url = `cleanReport/findTotalGroupUser`
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+// 清运量趋势
+export const findTotalGroupDate = (params) => {
+  const url = `cleanReport/findTotalGroupDate`
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+// 各回收物类型清运数据柱状图
+export const findTotalGroupDateAndRubbishType = (params) => {
+  const url = `cleanReport/findTotalGroupDateAndRubbishType`
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}

+ 40 - 0
src/api/electronicScale.js

@@ -0,0 +1,40 @@
+import { axios } from '@/utils/request'
+
+// 电子秤
+// 获取列表数据
+export const getDeviceList = params => {
+  const url = `device/query/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'POST'
+  })
+}
+
+// 删除
+export const delectDevice = params => {
+  return axios({
+    url: `device/deleteSteelyardById/${params.id}`,
+    data: {},
+    method: 'get'
+  })
+}
+
+// 新增/编辑保存接口
+export const saveDevice = params => {
+  return axios({
+    url: 'device/saveSteelyard',
+    data: params,
+    method: 'POST'
+  })
+}
+
+// 查详情
+export const deviceDetails = params => {
+  return axios({
+    url: `device/findBySrcDeviceNo/${params.srcDeviceCode}`,
+    method: 'get'
+  })
+}

+ 1 - 1
src/api/power-user.js

@@ -3,7 +3,7 @@ import { axios } from '@/utils/request'
 // 重置密码
 export const resetPSD = params => {
   return axios({
-    url: `/zxyj/user/resetPwd`,
+    url: `zxyj/user/resetPwd`,
     data: params,
     method: 'POST'
   })

+ 1 - 1
src/api/releaseRecord.js

@@ -30,7 +30,7 @@ export const getDeliveryLogTotal = (params) => {
   })
 }
 
-// 网点名称
+// 网点列表
 export const stationList = params => {
   return axios.request({
     url: `/station/queryList`,

+ 23 - 1
src/api/userInfo.js

@@ -44,7 +44,7 @@ export const customeExport = (params) => {
   })
 }
 
-// 乐豆详情
+// 用户管理-乐豆详情
 export const customerGoldLogDetail = (params) => {
   const url = `customerGoldLog/query/${params.pageNo}/${params.pageSize}`
   delete params.pageNo
@@ -80,3 +80,25 @@ export const updateRole = (params) => {
     method: 'post'
   })
 }
+
+// 乐豆明细--所有用户
+export const offPartnerGoldLog = (params) => {
+  const url = `customerGoldLog/query/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+
+//  乐豆明细--总计(所有用户)
+export const getStatistic = (params) => {
+  const url = `customerGoldLog/getGoldChangeNumTotal`
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}

+ 69 - 47
src/components/Echarts/bar.vue

@@ -5,10 +5,7 @@
 <script>
 import echarts from 'echarts'
 import tdTheme from './theme.json'
-import {
-  on,
-  off
-} from '@/libs/tools'
+import { on, off } from '@/libs/tools'
 
 echarts.registerTheme('tdTheme', tdTheme)
 export default {
@@ -18,12 +15,17 @@ export default {
     value: {
       type: Array,
       default: function () {
-		  return []
+        return []
       }
     },
     text: String,
     subtext: String,
-    color: String,
+    color: {
+      type: Array,
+      default: function () {
+        return []
+      }
+    },
     // 当有多列柱状图展示时的X轴坐标数据
     xAxisData: {
       type: Array,
@@ -31,11 +33,6 @@ export default {
         return []
       }
     },
-    // y轴坐标最大值
-    yMax: {
-      type: [Number, String],
-      default: 100
-    },
     // y轴坐标单位
     yUnit: {
       type: String,
@@ -99,9 +96,9 @@ export default {
     },
     value: {
       handler (nVal, oVal) {
-		  if (nVal) {
-		    this.pageInit()
-		  }
+        if (nVal) {
+          this.pageInit()
+        }
       },
       deep: true,
       immediate: true
@@ -119,14 +116,16 @@ export default {
       this.dom.resize()
     },
     pageInit () {
+      const that = this
       const legend = this.seriesData.map(_ => _.name)
       this.$nextTick(() => {
-		  const keys = this.value.map(item => item = item.name)
-		  const values = this.value.map(item => item = item.value)
+        const keys = this.value.map(item => (item = item.name))
+        const values = this.value.map(item => (item = item.value))
         const xAxisData = this.value.length ? keys : this.xAxisData
         const seriesData = this.value.length ? values : this.seriesData
+        const yMax = this.getYMax(this.seriesData) // 计算最大值
         const option = {
-          color: [this.color],
+          color: this.color,
           title: {
             text: this.text,
             subtext: this.subtext,
@@ -138,16 +137,18 @@ export default {
           tooltip: {
             trigger: 'axis'
           },
-          dataZoom: [{
-            type: 'slider',
-            show: this.isShowZoom, // flase直接隐藏图形
-            xAxisIndex: [0],
-            left: '9%', // 滚动条靠左侧的百分比
-            bottom: -5,
-            start: 0, // 滚动条的起始位置
-            end: this.xZoomEnd, // 滚动条的截止位置(按比例分割你的柱状图x轴长度)
-            zoomLock: true // 锁定区域禁止缩放(鼠标滚动会缩放,所以禁止)
-          }],
+          dataZoom: [
+            {
+              type: 'slider',
+              show: this.isShowZoom, // flase直接隐藏图形
+              xAxisIndex: [0],
+              left: '9%', // 滚动条靠左侧的百分比
+              bottom: -5,
+              start: 0, // 滚动条的起始位置
+              end: this.xZoomEnd, // 滚动条的截止位置(按比例分割你的柱状图x轴长度)
+              zoomLock: true // 锁定区域禁止缩放(鼠标滚动会缩放,所以禁止)
+            }
+          ],
           xAxis: {
             type: 'category',
             data: xAxisData,
@@ -159,42 +160,63 @@ export default {
           yAxis: {
             type: 'value',
             min: 0,
-            max: this.yMax,
+            max: yMax,
             axisLabel: {
               formatter: `{value} ${this.yUnit}`
             },
             // interval: 2,
             position: 'left'
           },
-		  grid: {
-			  left: '3%',
-			  right: '4%',
-			  bottom: '3%',
-			  containLabel: true
-		  }
+          grid: {
+            left: '3%',
+            right: '4%',
+            bottom: '3%',
+            containLabel: true
+          }
         }
-        if (this.value) {
-          option.series = [{
-            data: seriesData,
-            type: 'bar',
-            barWidth: 35,
-            label: {
-              normal: {
-                show: true,
-                position: 'top'
+        // 单柱图
+        if (this.value.length) {
+          option.series = [
+            {
+              data: seriesData,
+              type: 'bar',
+              barWidth: 35,
+              label: {
+                normal: {
+                  show: true,
+                  position: 'top'
+                }
               }
             }
-          }]
+          ]
         } else {
-          console.log(this.seriesData, '111111111')
           option.series = this.seriesData
         }
-        // console.log(option.series, 'ppppppp')
+        // 已创建的先销毁
+        if (this.dom) {
+          this.dom.dispose()
+        }
         this.dom = echarts.init(this.$refs.dom, 'tdTheme')
         this.dom.setOption(option)
-        this.dom.resize() // 解决首次加载宽度超出容器bug
+        // 更新y轴最大值
+        this.dom.on('legendselectchanged', function (params) {
+          // console.log(params, that.seriesData, 'legendselectchanged')
+          const data = that.seriesData.filter(item => params.selected[item.name])
+          option.yAxis.max = that.getYMax(data)
+          that.dom.setOption(option)
+        })
+        // 解决首次加载宽度超出容器bug
+        this.dom.resize()
         on(window, 'resize', this.resize)
       })
+    },
+    // 计算y轴最大值
+    getYMax (data) {
+      let max = []
+      data.map(item => {
+        max = max.concat(item.data)
+      })
+      return Math.max.apply(null, max)
     }
   },
   mounted () {

+ 32 - 13
src/components/Echarts/line.vue

@@ -17,7 +17,12 @@ export default {
     value: Object, // 单列折线图,key为x轴,value为y轴
     text: String,
     subtext: String,
-    color: String,
+    color: {
+      type: Array,
+      default: function () {
+        return []
+      }
+    },
     // 当有多列折线图展示时的X轴坐标数据
     xAxisData: {
       type: Array,
@@ -32,11 +37,6 @@ export default {
         return []
       }
     },
-    // y轴坐标最大值
-    yMax: {
-      type: Number,
-      default: 100
-    },
     // y轴坐标单位
     yUnit: {
       type: String,
@@ -51,7 +51,6 @@ export default {
   watch: {
     xAxisData: {
       handler (nVal, oVal) {
-        console.log(nVal, 'nnnnnnnn')
         if (nVal) {
           // 根据x轴时间长度控制滚动条位置及显示状态 x轴长度大于25时,显示滚动条并且滚动条结束位置在80%
           if (nVal.length > 25) {
@@ -96,7 +95,8 @@ export default {
     return {
       dom: null, // echarts实例对象
       isShowZoom: false, // 是否展示滚动条
-      xZoomEnd: 100 // x轴滚动条结束位置
+      xZoomEnd: 100, // x轴滚动条结束位置
+      yMax: 1000 // y轴最大值
     }
   },
   methods: {
@@ -104,13 +104,14 @@ export default {
       this.dom.resize()
     },
     pageInit () {
+      const that = this
       const legend = this.seriesData.map(_ => _.name)
       this.$nextTick(() => {
         const xAxisData = this.value ? Object.keys(this.value) : this.xAxisData
-        console.log(xAxisData, 'xAxisData')
         const seriesData = this.value ? Object.values(this.value) : this.seriesData
+        const yMax = this.getYMax(this.seriesData) // 计算最大值
         const option = {
-          color: [this.color],
+          color: this.color,
           title: {
             text: this.text,
             subtext: this.subtext,
@@ -149,7 +150,7 @@ export default {
           yAxis: {
             type: 'value',
             min: 0,
-            max: this.yMax,
+            max: yMax,
             axisLabel: {
               formatter: `{value} ${this.yUnit}`
             },
@@ -170,15 +171,33 @@ export default {
             }
           }]
         } else {
-          // console.log(this.seriesData, '111111111')
           option.series = this.seriesData
         }
-        // console.log(option.series, 'ppppppp')
+        // 已创建的先销毁
+        if (this.dom) {
+          this.dom.dispose()
+        }
         this.dom = echarts.init(this.$refs.dom, 'tdTheme')
         this.dom.setOption(option)
+        // 更新y轴最大值
+        this.dom.on('legendselectchanged', function (params) {
+          // console.log(params, that.seriesData, 'legendselectchanged')
+          const data = that.seriesData.filter(item => params.selected[item.name])
+          option.yAxis.max = that.getYMax(data)
+          that.dom.setOption(option)
+        })
+        // 重置图标大小
         this.dom.resize()
         on(window, 'resize', this.resize)
       })
+    },
+    // 计算y轴最大值
+    getYMax (data) {
+      let max = []
+      data.map(item => {
+        max = max.concat(item.data)
+      })
+      return Math.max.apply(null, max)
     }
   },
   mounted () {

+ 4 - 0
src/components/Echarts/pie.vue

@@ -173,6 +173,10 @@ export default {
             }
           ]
         }
+        // 已创建的先销毁
+        if (this.dom) {
+          this.dom.dispose()
+        }
         this.dom = echarts.init(this.$refs.dom, 'tdTheme')
         console.log(option, 'option')
         this.dom.setOption(option)

+ 100 - 2
src/config/router.config.js

@@ -219,7 +219,7 @@ export const asyncRouterMap = [{
       component: RouteView,
       meta: {
         title: '用户管理',
-        icon: 'profile',
+        icon: 'user',
         permission: 'M_user_userManage_list'
       },
       hideChildrenInMenu: true,
@@ -258,6 +258,16 @@ export const asyncRouterMap = [{
       }
       ]
     },
+    {
+      path: '/userInfo/allLdDetail',
+      name: 'allLdDetail',
+      component: () => import(/* webpackChunkName: "releaseRecord" */ '@/views/userInfo/allLdDetail.vue'),
+      meta: {
+        title: '乐豆明细',
+        icon: 'profile',
+        permission: 'M_allLdDetail'
+      }
+    },
     {
       path: '/userInfo/releaseRecord/list',
       name: 'releaseRecordList',
@@ -270,6 +280,73 @@ export const asyncRouterMap = [{
     }
     ]
   },
+  // 清运管理
+  {
+    path: '/cleanManage',
+    redirect: '/cleanManage/statisticalReport',
+    component: PageView,
+    meta: {
+      title: '清运管理',
+      icon: 'car',
+      permission: 'M_cleanManage'
+    },
+    children: [{
+      path: '/cleanManage/statisticalReport',
+      name: 'statisticalReport',
+      component: () => import(/* webpackChunkName: "equipmentManage" */
+        '@/views/cleanManage/statisticalReport.vue'),
+      meta: {
+        title: '统计报表',
+        icon: 'bar-chart',
+        permission: 'M_statisticalReport'
+      }
+    },
+    {
+      path: '/cleanManage/driverManage',
+      name: 'driverManage',
+      component: () => import(/* webpackChunkName: "equipmentManage" */
+        '@/views/cleanManage/driverManage.vue'),
+      meta: {
+        title: '司机管理',
+        icon: 'contacts',
+        permission: 'M_driverManage_list'
+      }
+    },
+    {
+      path: '/cleanManage/cleanDetail',
+      name: 'cleanDetail',
+      component: () => import(/* webpackChunkName: "equipmentManage" */
+        '@/views/cleanManage/cleanDetail.vue'),
+      meta: {
+        title: '清运明细',
+        icon: 'unordered-list',
+        permission: 'M_cleanDetail_list'
+      }
+    },
+    {
+      path: '/cleanManage/netWorkCleanRecord',
+      name: 'netWorkCleanRecord',
+      component: () => import(/* webpackChunkName: "equipmentManage" */
+        '@/views/cleanManage/netWorkCleanRecord.vue'),
+      meta: {
+        title: '网点清运记录',
+        icon: 'line-chart',
+        permission: 'M_netWorkCleanRecord_list'
+      }
+    },
+    {
+      path: '/cleanManage/notCleanNetwork',
+      name: 'notCleanNetwork',
+      component: () => import(/* webpackChunkName: "equipmentManage" */
+        '@/views/cleanManage/notCleanNetwork.vue'),
+      meta: {
+        title: '待清运清单',
+        icon: 'cluster',
+        permission: 'M_notCleanNetwork_list'
+      }
+    }
+    ]
+  },
   // 报表
   {
     path: '/reportForm',
@@ -332,6 +409,16 @@ export const asyncRouterMap = [{
         permission: 'M_lottery_list'
       }
     },
+    // {
+    //   path: '/market/luckDrawRecord',
+    //   name: 'luckDrawRecord',
+    //   component: () => import(/* webpackChunkName: "market" */ '@/views/market/luckDrawRecord.vue'),
+    //   meta: {
+    //     title: '抽奖记录',
+    //     icon: 'profile'
+    //     // permission: 'M_lottery_list'
+    //   }
+    // },
     {
       path: '/market/giftCard',
       name: 'giftCardManage',
@@ -390,11 +477,22 @@ export const asyncRouterMap = [{
       component: () => import(/* webpackChunkName: "equipmentManage" */
         '@/views/equipmentManage/equipment/equipment.vue'),
       meta: {
-        title: '设备管理',
+        title: '回收箱体管理',
         icon: 'usb',
         permission: 'M_equipment_list'
       }
     },
+    {
+      path: '/equipmentManage/electronicScale',
+      name: 'electronicScale',
+      component: () => import(/* webpackChunkName: "equipmentManage" */
+        '@/views/equipmentManage/electronicScale/electronicScale.vue'),
+      meta: {
+        title: '电子秤管理',
+        icon: 'dashboard',
+        permission: 'M_electronicScale_list'
+      }
+    },
     {
       path: '/equipmentManage/boxSetting',
       name: 'boxSetting',

+ 153 - 0
src/views/cleanManage/addDiverModal.vue

@@ -0,0 +1,153 @@
+<template>
+  <div>
+    <a-modal
+      :footer="null"
+      :title="titleText"
+      v-model="isshow"
+      @cancle="cancel"
+      :centered="true">
+      <a-spin :spinning="loading">
+        <a-form-model ref="ruleForm" :model="formData" :rules="rules">
+          <a-form-model-item label="司机姓名" prop="name" :label-col="{ span: 6 }" :wrapper-col="{ span: 15 }">
+            <a-input v-model.trim="formData.name" :maxLength="30" placeholder="请输入司机姓名(最多30个字符)" id="addDiverModal-name"/>
+          </a-form-model-item>
+          <a-form-model-item label="手机号码" prop="phone" :label-col="{ span: 6 }" :wrapper-col="{ span: 15 }">
+            <a-input v-model.trim="formData.phone" :maxLength="11" placeholder="请输入手机号" id="addDiverModal-phone"/>
+          </a-form-model-item>
+          <a-form-model-item label="状态" prop="loginFlag" :label-col="{ span: 6 }" :wrapper-col="{ span: 15 }">
+            <a-radio-group
+              name="radioGroup"
+              v-model="formData.loginFlag"
+              id="addDiverModal-loginFlag"
+            >
+              <a-radio :value="1">是</a-radio>
+              <a-radio :value="0">否</a-radio>
+            </a-radio-group>
+          </a-form-model-item>
+          <a-form-model-item :wrapper-col="{ span: 24, offset: 8 }">
+            <a-button type="primary" @click="onSubmit" :style="{ marginRight: '15px' }" id="addDiverModal-onSubmit">保存</a-button>
+            <a-button @click="cancel" :style="{ marginLeft: '15px' }" id="addDiverModal-cancel">取消</a-button>
+          </a-form-model-item>
+        </a-form-model>
+      </a-spin >
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import {
+  STable,
+  VSelect
+} from '@/components'
+import { saveDriver, driverDetails } from '@/api/cleanManage.js'
+export default {
+  name: 'AddDiverModal',
+  components: {
+    STable,
+    VSelect
+  },
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    itemId: {
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+    return {
+      titleText: '新增',
+      isshow: this.visible,
+      formLayout: 'horizontal',
+      optionData: [],
+      formData: {
+        name: '',	// 姓名
+        loginFlag: '', // 状态
+        phone: '' // 手机号码
+      },
+      rules: {
+        phone: [{ required: true, pattern: /^\d{11}$/, message: '请输入手机号', trigger: 'blur' }],
+        name: [{ required: true, message: '请输入司机姓名', trigger: 'blur' }],
+        loginFlag: [{ required: true, message: '请选择状态', trigger: 'blur' }]
+      },
+      loading: false
+    }
+  },
+  methods: {
+    cancel (e) {
+      this.clear()
+      this.$emit('close')
+    },
+    // 编辑查详情
+    getPageInfo () {
+      this.loading = true
+      driverDetails({
+        id: this.itemId
+      }).then(res => {
+        if (res.status == 200) {
+          this.loading = false
+          this.formData = Object.assign({}, this.formData, res.data)
+          this.formData.loginFlag = Number(this.formData.loginFlag)
+        }
+      })
+    },
+    // 保存提交
+    onSubmit () {
+      this.$refs.ruleForm.validate(valid => {
+        const _this = this
+        if (valid) {
+          const params = JSON.parse(JSON.stringify(this.formData))
+          saveDriver(params).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$emit('refresh')
+              setTimeout(function () {
+                _this.cancel()
+              }, 300)
+            }
+          })
+        }
+      })
+    },
+    // 取消
+    handleCancel () {
+      this.cancel()
+    },
+    clear () {
+      this.$refs.ruleForm.resetFields()
+      delete this.formData.id
+      this.formData.name = ''
+      this.formData.loginFlag = ''
+      this.formData.phone = ''
+    }
+  },
+  watch: {
+    visible (newValue, oldValue) {
+      this.isshow = newValue
+    },
+    isshow (val) {
+      if (!val) {
+        this.$emit('close')
+      } else {
+        this.$nextTick(() => {
+          this.$refs.ruleForm.resetFields()
+        })
+      }
+    },
+    itemId (newValue, oldValue) {
+      if (newValue && this.isshow) {
+        this.titleText = '编辑'
+        this.getPageInfo(newValue)
+      } else {
+        this.titleText = '新增'
+        console.log(this.loading)
+      }
+    }
+  }
+}
+</script>
+
+<style>
+</style>

+ 251 - 0
src/views/cleanManage/cleanDetail.vue

@@ -0,0 +1,251 @@
+<template>
+  <a-card :bordered="false" class="cleanDetail-container">
+    <!-- 搜索条件 -->
+    <div class="cleanDetail-container-searchForm">
+      <a-form-model
+        ref="queryParam"
+        :model="queryParam"
+        layout="inline"
+        @keyup.enter.native="refresh"
+        v-bind="formItemLayout">
+        <a-row :gutter="24">
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="清运时间:" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-range-picker
+                :disabledDate="disabledDate"
+                v-model="time"
+                id="cleanDetail-time"
+                :format="dateFormat"
+                :placeholder="['开始时间', '结束时间']" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="网点名称" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-select
+                id="cleanDetail-stationNo"
+                placeholder="请选择网点名称"
+                allowClear
+                v-model="queryParam.stationNo"
+                showSearch
+                option-filter-prop="children"
+                :filter-option="filterOption">
+                <a-select-option v-for="item in optionData" :key="item.stationNo" :value="item.stationNo">{{ item.name }}</a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="设备编号" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-input allowClear placeholder="请输入设备编号" v-model.trim="queryParam.srcDeviceCode" id="cleanDetail-srcDeviceCode" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="清运司机" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-select
+                id="cleanDetail-dirverUserId"
+                placeholder="请选择清运司机"
+                allowClear
+                v-model="queryParam.dirverUserId"
+                showSearch
+                option-filter-prop="children"
+                :filter-option="filterOption">
+                <a-select-option v-for="item in cleanUserData" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="4">
+            <a-button type="primary" @click="refresh" style="margin: 4px 10px 0 20px" id="cleanDetail-refresh">查询</a-button>
+            <a-button type="" @click="reset" style="margin-top: 4px" id="cleanDetail-reset">重置</a-button>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </div>
+    <!-- 合计 -->
+    <a-alert type="info" showIcon style="margin-bottom:15px">
+      <div class="ftext" slot="message">总计<span> {{ totalNum }} </span>条,可回收物清运量总计<span> {{ cleanWeightTotal }} </span>kg</div>
+    </a-alert>
+    <!-- 列表 -->
+    <s-table
+      ref="table"
+      :rowKey="(record) => record.id"
+      :columns="columns"
+      :data="loadData"
+      bordered
+    >
+      <span slot="action" slot-scope="text,record">
+        <a-button type="primary" @click="handleDetail(record)" v-hasPermission="'B_cleanDetail'" id="cleanDetail-handleDetail">查看清运明细</a-button>
+        <span v-if="!$hasPermissions('B_cleanDetail')">--</span>
+      </span>
+    </s-table>
+    <!-- 详情弹窗 -->
+    <cleanDetailModal :deviceNo="itemDeviceNo" :cleanTime="itemCleanTime" :visible="isOpenModal" @close="isOpenModal=false"></cleanDetailModal>
+  </a-card>
+</template>
+
+<script>
+import { STable, VSelect } from '@/components'
+import { stationList } from '@/api/releaseRecord.js'
+import cleanDetailModal from './cleanDetailModal.vue'
+import { cleanDetailsList, getCleanDetailsTotal, cleanUserList } from '@/api/cleanManage.js'
+import moment from 'moment'
+export default {
+  components: { STable, VSelect, cleanDetailModal },
+  data () {
+    return {
+      formItemLayout: {
+        labelCol: {
+          span: 7
+        },
+        wrapperCol: {
+          span: 17
+        }
+      },
+      isOpenModal: false, // 默认弹窗关闭
+      itemDeviceNo: '', // 每行设备编号
+      itemCleanTime: '', // 每行清运时间
+      // 查询参数
+      queryParam: {
+        dirverUserId: undefined, // 操作人id
+        stationNo: undefined, // 网点编号
+        srcDeviceCode: null, // 设备编号
+        beginDate: null, // 开始时间
+        endDate: null // 结束时间
+      },
+      optionData: [], // 网点名称数据
+      cleanUserData: [], // 操作人数据
+      // 将默认当天时间日期回显在时间选择框中
+      time: [],
+      dateFormat: 'YYYY-MM-DD', // 日期格式
+      totalNum: 0, // 总条数
+      cleanWeightTotal: 0, // 可回收物清运量总计
+      columns: [{ title: '序号', dataIndex: 'no', width: 60, align: 'center' },
+        { title: '清运时间', dataIndex: 'cleanTime', width: 100, align: 'center' },
+        { title: '网点名称', dataIndex: 'stationName', width: 100, align: 'center', customRender: (text) => { return text || '--' } },
+        { title: '设备编号', dataIndex: 'srcDeviceCode', width: 100, align: 'center', customRender: (text) => { return text || '--' } },
+        { title: '可回收物清运量(kg)', dataIndex: 'cleanWeight', width: 100, align: 'center', sorter: true, customRender: (text) => { return text || 0 } },
+        { title: '清运司机', dataIndex: 'driverName', width: 100, align: 'center', customRender: (text) => { return text || '--' } },
+        { title: '操作人', dataIndex: 'operatorName', width: 100, align: 'center' },
+        { title: '备注', dataIndex: 'remarks', width: 100, align: 'center', ellipsis: true, customRender: (text) => { return text || '--' } },
+        { title: '操作', dataIndex: 'action', width: 100, align: 'center', scopedSlots: { customRender: 'action' } }],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        const searchData = Object.assign(parameter, this.queryParam)
+        if (this.time && this.time.length) {
+          searchData.beginDate = moment(this.time[0]).format('YYYY-MM-DD 00:00:00')
+          searchData.endDate = moment(this.time[1]).format('YYYY-MM-DD 23:59:59')
+        } else {
+          searchData.beginDate = null
+          searchData.endDate = null
+        }
+        return cleanDetailsList(searchData).then(res => {
+          if (res.status == 200) {
+            const no = (res.data.pageNo - 1) * res.data.pageSize
+            for (let i = 0; i < res.data.list.length; i++) {
+              const _item = res.data.list[i]
+              _item.no = no + i + 1
+              if (_item.cleanWeight != null || 0) {
+                _item.cleanWeight = (_item.cleanWeight / 1000).toFixed(3)
+              }
+            }
+            this.totalNum = res.data.count
+            return res.data
+          } else {
+            this.totalNum = 0
+          }
+        })
+      }
+    }
+  },
+  mounted () {
+    this.getStationList()
+    this.getTotal()
+    this.getCleanUserList()
+  },
+  methods: {
+    // 不可选日期
+    disabledDate (date, dateStrings) {
+      return date && date.valueOf() > Date.now()
+    },
+    // 创建时间change
+    onChange (dates, dateStrings) {
+      if ((dates, dateStrings)) {
+        this.queryParam.beginDate = dateStrings[0]
+        this.queryParam.endDate = dateStrings[1]
+      }
+    },
+    filterOption (input, option) {
+      return (
+        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+      )
+    },
+    // 获取操作人数据
+    getCleanUserList () {
+      cleanUserList().then(res => {
+        if (res.status == 200) {
+          this.cleanUserData = res.data || []
+        }
+      })
+    },
+    // 获取合作商数据
+    getStationList () {
+      stationList().then(res => {
+        if (res.status == 200) {
+          this.optionData = res.data || []
+        }
+      })
+    },
+    // 合计
+    getTotal () {
+      const params = this.queryParam
+      if (this.time && this.time.length) {
+        params.beginDate = moment(this.time[0]).format('YYYY-MM-DD 00:00:00')
+        params.endDate = moment(this.time[1]).format('YYYY-MM-DD 23:59:59')
+      } else {
+        params.beginDate = null
+        params.endDate = null
+      }
+      getCleanDetailsTotal(params).then(res => {
+        if (res.status == 200) {
+          if (res.data != 0 || null) {
+            this.cleanWeightTotal = (res.data.cleanWeight / 1000).toFixed(3)
+          }
+        } else {
+          this.cleanWeightTotal = 0
+        }
+      })
+    },
+    // 查询
+    refresh () {
+      this.$refs.table.refresh(true)
+      this.getTotal()
+    },
+    // 重置
+    reset () {
+      this.queryParam = {
+        dirverUserId: undefined, // 操作人id
+        stationNo: undefined, // 网点编号
+        srcDeviceCode: null, // 设备编号
+        beginDate: null, // 开始时间
+        endDate: null // 结束时间
+      }
+      this.time = []
+      this.refresh()
+    },
+    // 查看清运详情
+    handleDetail (record) {
+      this.itemDeviceNo = record.deviceNo
+      this.itemCleanTime = record.cleanTime
+      this.isOpenModal = true
+    }
+  }
+}
+</script>
+<style lang='less' scoped>
+	.cleanDetail-container {
+		.cleanDetail-container-searchForm {
+			.ant-form-inline .ant-form-item {
+				width: 100%;
+				margin-bottom: 15px;
+			}
+		}
+	}
+</style>

+ 77 - 0
src/views/cleanManage/cleanDetailModal.vue

@@ -0,0 +1,77 @@
+<template>
+  <a-modal title="清运详情" :footer="null" v-model="isShow" @cancel="cancel" centered>
+    <a-spin :spinning="loading">
+      <div class="detail-item" v-for="item in itemData" :key="item.index"><span>{{ item.rubbishTypeDictValue }}:</span>{{ (item.cleanWeight/1000).toFixed(3) }} kg</div>
+      <a-empty v-if="itemData.length == 0" style="text-align: center;" />
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { getCleanDetails } from '@/api/cleanManage.js'
+export default {
+  name: 'CleanDetailModal',
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    deviceNo: {
+      type: [Number, String],
+      default: ''
+    },
+    cleanTime: {
+      type: [Number, String],
+      default: ''
+    }
+  },
+  data () {
+    return {
+      isShow: this.visible,
+      itemData: [],
+      loading: false
+    }
+  },
+  methods: {
+    cancel (e) {
+      this.$emit('close')
+    },
+    getDetailInfo () {
+      this.loading = true
+      getCleanDetails({ deviceNo: this.deviceNo, cleanDate: this.cleanTime }).then(res => {
+        if (res.status == 200) {
+          this.itemData = res.data || []
+          console.log(this.itemData)
+        }
+        this.loading = false
+      })
+    }
+  },
+  watch: {
+    visible (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+      } else {
+        this.getDetailInfo()
+      }
+    }
+  }
+}
+
+</script>
+
+<style lang="less" scoped="scoped">
+	.detail-item{
+		margin:10px 0;
+		letter-spacing: 0.5px;
+		span{
+			display: inline-block;
+			text-align: right;
+			width: 50%;
+			font-weight:normal
+		}
+	}
+</style>

+ 132 - 0
src/views/cleanManage/cleanModal.vue

@@ -0,0 +1,132 @@
+<template>
+  <div>
+    <a-modal title="确认清运" :footer="null" v-model="isShow" @cancel="cancel" centered>
+      <a-form-model ref="ruleForm" :model="queryParam" :label-col="{span:5}" :wrapper-col="{span:17}">
+        <a-form-model-item label="清运司机">
+          {{ driverName }}
+        </a-form-model-item>
+        <a-form-model-item label="备注">
+          <a-textarea
+            :maxLength="500"
+            id="cleanModal-remarks"
+            v-model="queryParam.remarks"
+            style="min-height: 60px;"
+            placeholder="请输入备注(最多500个字符)"
+            autoSize />
+        </a-form-model-item>
+        <a-form-model-item :wrapper-col="{ span: 24, offset: 8 }">
+          <a-button type="primary" @click="handleSubmit" id="cleanModal-handleSubmit":style="{ marginRight: '15px' }">
+            保存
+          </a-button>
+          <a-button :style="{ marginLeft: '15px' }" id="cleanModal-cancel" @click="cancel" >
+            取消
+          </a-button>
+        </a-form-model-item>
+      </a-form-model>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import { findDriverName, cleanByDevice } from '@/api/cleanManage.js'
+export default {
+  name: 'CleanModal',
+  props: {
+    openModal: {
+      type: Boolean,
+      default: false
+    },
+    cleanStationDeviceNo: {
+      type: [Number, String],
+      default: ''
+    },
+    dirverUserId: {
+      type: [Number, String],
+      default: ''
+    }
+  },
+  data () {
+    return {
+      optionData: [], // 司机列表数据
+      isShow: this.openModal,
+      queryParam: {
+        remark: ''
+      },
+      driverName: ''
+    }
+  },
+  methods: {
+    filterOption (input, option) {
+      return (
+        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+      )
+    },
+    // 司机数据
+    getDriverName () {
+      findDriverName({ id: this.dirverUserId }).then(res => {
+        if (res.status == 200) {
+          console.log(res)
+          this.driverName = res.data.name
+        } else {
+          this.driverName = ''
+        }
+      })
+    },
+    // 保存
+    handleSubmit () {
+      this.$refs.ruleForm.validate(valid => {
+        const _this = this
+        if (valid) {
+          const params = {
+            cleanStationDeviceNo: this.cleanStationDeviceNo,
+            remarks: this.queryParam.remarks
+          }
+          cleanByDevice(params).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$emit('refresh')
+              setTimeout(function () {
+                _this.cancel()
+              }, 300)
+            }
+          })
+        }
+      })
+    },
+    // 取消
+    cancel (e) {
+      this.clear()
+      this.$emit('close')
+    },
+    // 重置input框
+    clear () {
+      this.$refs.ruleForm.resetFields()
+      this.queryParam = {
+        remark: ''
+      }
+    }
+  },
+  watch: {
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    isShow (val) {
+      if (!val) {
+        this.$emit('close')
+      } else {
+        this.$nextTick(() => {
+          this.$refs.ruleForm.resetFields()
+        })
+      }
+    },
+    cleanStationDeviceNo (newValue, oldValue) {
+      if (this.isShow && newValue) {
+        this.getDriverName()
+      }
+    }
+  }
+}
+</script>
+
+<style>
+</style>

+ 187 - 0
src/views/cleanManage/driverManage.vue

@@ -0,0 +1,187 @@
+<template>
+  <a-card :bordered="false" class="userManage-page-info">
+    <!-- 搜索条件 -->
+    <div class="userManage-search">
+      <a-form-model layout="inline" :model="queryParam" v-bind="formItemLayout" @keyup.enter.native="$refs.table.refresh(true)">
+        <a-row :gutter="24">
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="司机姓名" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-input allowClear placeholder="请输入司机姓名" v-model.trim="queryParam.name" id="driverManage-name" :maxLength="30"/>
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="手机号码" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-input allowClear placeholder="请输入手机号码" :maxLength="11" v-model.trim="queryParam.phone" id="driverManage-phone" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="状态" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <v-select code="ENABLE_FLAG" v-model="queryParam.loginFlag" allowClear placeholder="请选择状态" id="driverManage-loginFlag"></v-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-button type="primary" @click="$refs.table.refresh(true)" style="margin: 4px 10px 0 20px" id="driverManage-refresh">查询</a-button>
+            <a-button type="" @click="reset" style="margin-top: 4px" id="driverManage-reset">重置</a-button>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </div>
+    <!-- 新增 -->
+    <div class="table-operator">
+      <a-button
+        type="primary"
+        icon="plus"
+        @click="openModal"
+        id="driverManage-openModal"
+        style="margin-top: 18px;"
+        v-hasPermission="'B_driverManage_add'">新增</a-button>
+    </div>
+    <!-- 列表 -->
+    <s-table
+      ref="table"
+      size="default"
+      rowKey="id"
+      :columns="columns"
+      :data="loadData"
+      bordered>
+      <template slot="loginFlag" slot-scope="text, record">
+        <span :style="{'color': (record.loginFlag == 0 ? 'red' : 'green')}">{{ record.loginFlag == 0 ? '禁用' :record.loginFlag == 1 ? '启用' : '--' }}</span>
+      </template>
+      <span slot="action" slot-scope="text, record">
+        <a-icon type="unlock" title="重置密码" class="actionBtn icon-orange" @click="resetPassword(record)" v-hasPermission="'B_driverManage_restPwd'"/>
+        <a-icon type="edit" title="编辑" class="actionBtn icon-blues" @click="handleEdit(record)" v-hasPermission="'B_driverManage_edit'"/>
+        <a-icon v-if="record.loginFlag == 0 && $hasPermissions('B_driverManage_del')" type="delete" title="删除" class="actionBtn icon-red" @click="delect(record)" />
+        <span v-if="!$hasPermissions('B_driverManage_edit') && !($hasPermissions('B_driverManage_restPwd')) && !($hasPermissions('B_driverManage_del') && record.loginFlag==0) ">--</span>
+      </span>
+    </s-table>
+    <!-- 新增、编辑弹窗 -->
+    <addDiverModal :visible="showModal" @refresh="refreshTable" :itemId="itemId" @close="cancel"></addDiverModal>
+  </a-card>
+</template>
+
+<script>
+import { STable, VSelect } from '@/components'
+import addDiverModal from './addDiverModal.vue'
+import { resetPSD, getDriverList, delectDriver } from '@/api/cleanManage.js'
+export default {
+  name: 'DriverManage',
+  components: { STable, VSelect, addDiverModal },
+  data () {
+    return {
+      formItemLayout: {
+        labelCol: {
+          span: 7
+        },
+        wrapperCol: {
+          span: 17
+        }
+      },
+      // 查询参数
+      queryParam: {
+        name: '',
+        phone: '',
+        loginFlag: ''
+      },
+      showModal: false,
+      itemId: null, // 编辑行id
+      // 表头
+      columns: [{ title: '序号', dataIndex: 'no', width: 60, align: 'center' },
+        { title: '司机姓名', dataIndex: 'name', width: 150, align: 'center' },
+        { title: '手机号码', dataIndex: 'phone', width: 100, align: 'center' },
+        { title: '状态', dataIndex: 'loginFlag', width: 100, align: 'center', scopedSlots: { customRender: 'loginFlag' } },
+        { title: '操作', width: 100, align: 'center', scopedSlots: { customRender: 'action' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        return getDriverList(Object.assign(parameter, this.queryParam)).then(res => {
+          const no = (res.data.pageNo - 1) * res.data.pageSize
+          for (let i = 0; i < res.data.list.length; i++) {
+            const _item = res.data.list[i]
+            _item.no = no + i + 1
+            _item.loginFlag = _item.loginFlag + '' === '1'
+          }
+          return res.data
+        })
+      }
+    }
+  },
+  methods: {
+    cancel () {
+      this.itemId = null
+      this.showModal = false
+    },
+    // 刷新列表
+    refreshTable () {
+      if (this.itemId) {
+        this.$refs.table.refresh()
+      } else {
+        this.$refs.table.refresh(true)
+      }
+    },
+    // refreshTable () {
+    //   if (!this.itemId) {
+		  // console.log(!this.itemId)
+    //     this.$refs.table.refresh()
+    //   }
+    // },
+    // 新建
+    openModal () {
+      this.showModal = true
+      this.itemData = {}
+    },
+    // 重置
+    reset () {
+      this.queryParam.name = ''
+      this.queryParam.phone = ''
+      this.queryParam.loginFlag = ''
+      this.refreshTable()
+    },
+    // 重置密码
+    resetPassword (row) {
+      resetPSD({
+        id: row.id
+      }).then(res => {
+        if (res.status == 200) {
+          this.$message.success(res.message)
+          this.$refs.table.refresh()
+        }
+      })
+    },
+    // 删除
+    delect (row) {
+      const _this = this
+      this.$confirm({
+        title: '警告',
+        centered: true,
+        content: '删除后无法恢复,确认删除?',
+        okText: '确定',
+        cancelText: '取消',
+        onOk () {
+          delectDriver({
+            id: row.id
+          }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+            }
+          })
+        }
+      })
+    },
+    // 编辑
+    handleEdit (row) {
+      this.itemId = row.id
+      this.showModal = true
+    }
+  }
+}
+</script>
+<style lang="less">
+    .userManage-page-info {
+        .userManage-search {
+            .ant-form-inline .ant-form-item {
+                width: 100%;
+            }
+        }
+    }
+</style>

+ 101 - 0
src/views/cleanManage/netWorkCleanModal.vue

@@ -0,0 +1,101 @@
+<template>
+  <a-modal
+    title="清运详情"
+    :footer="null"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :centered="true"
+    width="60%">
+    <s-table
+      ref="table"
+      :rowKey="(record) => record.id"
+      :columns="columns"
+      :data="loadData"
+      bordered
+      :scroll="{ y: 400 }">
+    </s-table>
+  </a-modal>
+</template>
+
+<script>
+import { STable } from '@/components'
+import { networkDetail } from '@/api/cleanManage.js'
+import moment from 'moment'
+export default {
+  name: 'CleanDetailModal',
+  components: {
+    STable
+  },
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    stationNo: {
+      type: [Number, String],
+      default: ''
+    },
+    searchDate: {
+      type: Array,
+      default: function () {
+        return []
+      }
+    }
+  },
+  data () {
+    return {
+      isShow: this.visible, // 弹窗的状态
+      columns: [{ title: '序号', dataIndex: 'no', width: 60, align: 'center' },
+        { title: '清运时间', dataIndex: 'cleanTime', width: 100, align: 'center' },
+        { title: '设备编号', dataIndex: 'srcDeviceCode', width: 100, align: 'center' },
+        { title: '清运重量(kg)', dataIndex: 'cleanWeight', width: 100, align: 'center' },
+        { title: '清运司机', dataIndex: 'driverName', width: 100, align: 'center' }],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        const searchDateModal = this.searchDate
+        if (this.searchDate && this.searchDate.length) {
+          searchDateModal.beginDate = moment(this.searchDate[0]).format('YYYY-MM-DD 00:00:00')
+          searchDateModal.endDate = moment(this.searchDate[1]).format('YYYY-MM-DD 23:59:59')
+        } else {
+          searchDateModal.beginDate = null
+          searchDateModal.endDate = null
+        }
+        const searchData = Object.assign(parameter, { stationNo: this.stationNo }, { beginDate: searchDateModal.beginDate }, { endDate: searchDateModal.endDate })
+        return networkDetail(searchData).then(res => {
+          if (res.status == 200) {
+            const no = (res.data.pageNo - 1) * res.data.pageSize
+            for (let i = 0; i < res.data.list.length; i++) {
+              const _item = res.data.list[i]
+              _item.no = no + i + 1
+              if (_item.cleanWeight != null || 0) {
+                _item.cleanWeight = (_item.cleanWeight / 1000).toFixed(3)
+              }
+            }
+            return res.data
+          }
+        })
+      }
+    }
+  },
+  watch: {
+    visible (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+      } else {
+        this.$refs.table.refresh(true)
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped="scoped">
+	.detail-item {
+		text-align: center;
+		margin: 10px 0;
+		letter-spacing: 0.5px;
+	}
+</style>

+ 224 - 0
src/views/cleanManage/netWorkCleanRecord.vue

@@ -0,0 +1,224 @@
+<template>
+  <a-card :bordered="false" class="cleanDetail-container">
+    <!-- 搜索条件 -->
+    <div class="cleanDetail-container-searchForm">
+      <a-form-model
+        ref="queryParam"
+        :model="queryParam"
+        layout="inline"
+        @keyup.enter.native="refresh"
+        v-bind="formItemLayout">
+        <a-row :gutter="24">
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="创建时间" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-range-picker
+                id="netWorkCleanRecord-time"
+                v-model="time"
+                style="width: 100%;"
+                :format="dateFormat"
+                :placeholder="['开始时间','结束时间']"
+                :disabledDate="disabledDate"
+                @change="onChange" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="网点名称" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-select
+                id="netWorkCleanRecord-stationNo"
+                placeholder="请选择网点名称"
+                allowClear
+                v-model="queryParam.stationNo"
+                :showSearch="true"
+                option-filter-prop="children"
+                :filter-option="filterOption">
+                <a-select-option v-for="item in optionData" :key="item.stationNo" :value="item.stationNo">{{ item.name }}</a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-button type="primary" @click="refreshSearch" id="netWorkCleanRecord-refresh" style="margin: 4px 10px 0 20px">查询</a-button>
+            <a-button type="" @click="reset" id="netWorkCleanRecord-reset" style="margin-top: 4px">重置</a-button>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </div>
+    <!-- 合计 -->
+    <a-alert type="info" showIcon style="margin-bottom:15px">
+      <div class="ftext" slot="message">总计<span> {{ totalNum }} </span>条,可回收物清运量总计<span> {{ cleanWeightTotal }} </span>kg</div>
+    </a-alert>
+    <!-- 列表 -->
+    <s-table
+      ref="table"
+      :rowKey="(record) => record.id"
+      :columns="columns"
+      :data="loadData"
+      bordered
+    >
+      <span slot="action" slot-scope="text,record">
+        <a-button type="primary" @click="handleDetail(record)" v-hasPermission="'B_netWorkCleanRecord_detail'" id="netWorkCleanRecord-handleDetail">查看详情</a-button>
+        <span v-if="!$hasPermissions('B_netWorkCleanRecord_detail')">--</span>
+      </span>
+    </s-table>
+    <!-- 详情弹窗 -->
+    <netWorkCleanModal :stationNo="itemStationNo" :searchDate="time" :visible="isOpenModal" @close="isOpenModal=false"></netWorkCleanModal>
+  </a-card>
+</template>
+
+<script>
+import { STable, VSelect } from '@/components'
+import { stationList } from '@/api/releaseRecord.js'
+import { cleanRecordList, getCleanStationTotal } from '@/api/cleanManage.js'
+import netWorkCleanModal from './netWorkCleanModal.vue'
+import moment from 'moment'
+import getDate from '@/libs/getDate.js'
+export default {
+  components: { STable, VSelect, netWorkCleanModal },
+  data () {
+    return {
+      formItemLayout: {
+        labelCol: {
+          span: 7
+        },
+        wrapperCol: {
+          span: 17
+        }
+      },
+      isOpenModal: false, // 默认弹窗关闭
+      itemStationNo: '', // 每行网点编号
+      // 查询参数
+      queryParam: {
+        beginDate: null, // 开始时间
+        endDate: null, // 结束时间
+        stationNo: undefined // 网点编号
+      },
+      totalNum: 0, // 总条数
+      cleanWeightTotal: 0, // 回收物总计
+      optionData: [], // 网点名称数据
+      // 将默认近一周时间日期回显在时间选择框中
+      time: [
+        moment(getDate.getRecentday().starttime, 'YYYY-MM-DD'),
+        moment(getDate.getRecentday().endtime, 'YYYY-MM-DD')
+      ],
+      dateFormat: 'YYYY-MM-DD',
+      columns: [{ title: '序号', dataIndex: 'no', width: 60, align: 'center' },
+        { title: '网点名称', dataIndex: 'stationName', width: 200, align: 'center', customRender: (text) => { return text || '--' } },
+        { title: '清运次数', dataIndex: 'cleanTimes', width: 50, align: 'center', sorter: true },
+        { title: '清运重量(kg)', dataIndex: 'cleanWeight', width: 100, align: 'center', sorter: true, customRender: (text) => { return text || 0 } },
+        { title: '最后清运时间', dataIndex: 'cleanTime', width: 100, align: 'center', customRender: (text) => { return text || '--' } },
+        { title: '操作', dataIndex: 'action', width: 100, align: 'center', scopedSlots: { customRender: 'action' } }],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        const searchData = Object.assign(parameter, this.queryParam)
+        if (this.time && this.time.length) {
+          searchData.beginDate = moment(this.time[0]).format('YYYY-MM-DD 00:00:00')
+          searchData.endDate = moment(this.time[1]).format('YYYY-MM-DD 23:59:59')
+        } else {
+          searchData.beginDate = null
+          searchData.endDate = null
+        }
+        return cleanRecordList(searchData).then(res => {
+          if (res.status == 200) {
+            const no = (res.data.pageNo - 1) * res.data.pageSize
+            for (let i = 0; i < res.data.list.length; i++) {
+              const _item = res.data.list[i]
+              _item.no = no + i + 1
+              if (_item.cleanWeight != null || 0) {
+                _item.cleanWeight = (_item.cleanWeight / 1000).toFixed(3)
+              }
+            }
+            this.totalNum = res.data.count
+            return res.data
+          } else {
+            this.totalNum = 0
+          }
+        })
+      }
+    }
+  },
+  mounted () {
+    this.getStationList()
+    this.getTotal()
+  },
+  methods: {
+    // 不可选日期
+    disabledDate (date, dateStrings) {
+      return date && date.valueOf() > Date.now()
+    },
+    // 创建时间change
+    onChange (dates, dateStrings) {
+      if ((dates, dateStrings)) {
+        this.queryParam.beginDate = dateStrings[0]
+        this.queryParam.endDate = dateStrings[1]
+      }
+    },
+    filterOption (input, option) {
+      return (
+        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+      )
+    },
+    // 获取网点名称数据
+    getStationList () {
+      stationList().then(res => {
+        if (res.status == 200) {
+          this.optionData = res.data || []
+        }
+      })
+    },
+    // 总计
+    getTotal () {
+      const params = this.queryParam
+      if (this.time && this.time.length) {
+        params.beginDate = moment(this.time[0]).format('YYYY-MM-DD 00:00:00')
+        params.endDate = moment(this.time[1]).format('YYYY-MM-DD 23:59:59')
+      } else {
+        params.beginDate = null
+        params.endDate = null
+      }
+      getCleanStationTotal(params).then(res => {
+        if (res.status == 200) {
+          if (res.data != 0 || null) {
+            this.cleanWeightTotal = (res.data.cleanWeight / 1000).toFixed(3)
+          }
+        } else {
+          this.cleanWeightTotal = 0
+        }
+      })
+    },
+    // 查询
+    refreshSearch () {
+      this.$refs.table.refresh(true)
+      this.getTotal()
+    },
+    // 重置
+    reset () {
+      this.queryParam = {
+        stationNo: undefined,
+        beginDate: null,
+        endDate: null
+      }
+      this.time = [
+        moment(getDate.getRecentday().starttime, 'YYYY-MM-DD 00:00:00'),
+        moment(getDate.getRecentday().endtime, 'YYYY-MM-DD 23:59:59')
+      ]
+      this.refreshSearch()
+    },
+    // 查看清运详情
+    handleDetail (record) {
+      this.itemStationNo = record.stationNo
+      this.searchDate = this.time
+      this.isOpenModal = true
+    }
+  }
+}
+</script>
+
+<style lang='less' scoped>
+	.cleanDetail-container {
+		.cleanDetail-container-searchForm {
+			.ant-form-inline .ant-form-item {
+				width: 100%;
+				margin-bottom: 15px;
+			}
+		}
+	}
+</style>

+ 412 - 0
src/views/cleanManage/notCleanNetwork.vue

@@ -0,0 +1,412 @@
+<template>
+  <a-card :bordered="false" class="cleanDetail-container">
+    <!-- 搜索条件 -->
+    <div class="cleanDetail-container-searchForm">
+      <a-form-model
+        ref="queryParam"
+        :model="queryParam"
+        layout="inline"
+        @keyup.enter.native="$refs.table.refresh(true)"
+        v-bind="formItemLayout">
+        <a-row :gutter="24">
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="最后清运时间" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-range-picker
+                id="notCleanNetwork-time"
+                v-model="time"
+                style="width: 100%;"
+                :format="dateFormat"
+                :placeholder="['开始时间','结束时间']"
+                :disabledDate="disabledDate"
+                @change="onChange" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="网点名称" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-select
+                id="notCleanNetwork-stationNo"
+                placeholder="请选择网点名称"
+                allowClear
+                v-model="queryParam.stationNo"
+                :showSearch="true"
+                option-filter-prop="children"
+                :filter-option="filterOption">
+                <a-select-option v-for="item in optionData" :key="item.stationNo" :value="item.stationNo">{{ item.name }}</a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="设备编号" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-input allowClear placeholder="请输入设备编号" v-model.trim="queryParam.srcDeviceCode" id="notCleanNetwork-srcDeviceCode" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item label="排序规则" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <v-select code="WAIT_CLEAN_SORT_RULE" v-model="queryParam.orderType" allowClear placeholder="请选择" id="notCleanNetwork-orderType"></v-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="4">
+            <a-button type="primary" @click="$refs.table.refresh(true)" id="notCleanNetwork-refresh" style="margin: 4px 10px 0 20px">查询</a-button>
+            <a-button type="" @click="reset" id="notCleanNetwork-reset" style="margin-top: 4px">重置</a-button>
+          </a-col>
+        </a-row>
+        <a-row :gutter="24">
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item prop="provinceCode" label="所属区域:" :label-col="{ span:8 }" :wrapper-col="{ span:16}">
+              <a-select
+                id="notCleanNetwork-provinceCode"
+                allowClear
+                v-model="queryParam.provinceCode"
+                @change="getCityList"
+                placeholder="请选择省">
+                <a-select-option v-for="item in addrProvinceList" :value="item.id" :key="item.id + 'a'">{{ item.name }}</a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item prop="cityCode" label=" " :colon="false" :label-col="{ span:8 }" :wrapper-col="{ span:16}">
+              <a-select
+                allowClear
+                id="notCleanNetwork-cityCode"
+                v-model="queryParam.cityCode"
+                @change="getAreaList"
+                placeholder="请选择市">
+                <a-select-option v-for="item in addrCityList" :value="item.id" :key="item.id + 'b'">{{ item.name }}</a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-model-item prop="districtCode" label=" " :colon="false" :label-col="{ span:8}" :wrapper-col="{ span:16}">
+              <a-select allowClear id="notCleanNetwork-districtCode" v-model="queryParam.districtCode" placeholder="请选择区/县">
+                <a-select-option v-for="item in addrDistrictList" :value="item.id" :key="item.id + 'c'">{{ item.name }}</a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </div>
+    <!-- 合计 -->
+    <a-alert type="info" showIcon style="margin-bottom:15px">
+      <div class="ftext" slot="message">总计<span> {{ orderTotal }} </span>条,可回收垃圾总计<span> {{ recyclableWasteTotal }} </span>kg。
+        其中,废旧衣物<span> {{ wasteClothes }} </span>kg,废旧塑料<span>{{ wastePlastics }} </span>kg,废旧金属<span> {{ wasteMetal }} </span>kg,废旧纸张<span> {{ wastePaper }} </span>kg,废旧金属/塑料<span> {{ wasteMetalPlastic }} </span>kg,废旧玻璃<span> {{ wasteGlass }} </span>kg,可回收物<span>
+          {{ recyclable }} </span>kg</div>
+    </a-alert>
+    <!-- 列表 -->
+    <s-table ref="table" :rowKey="(record) => record.id" :columns="columns" :data="loadData" bordered>
+      <template slot="customTitle">
+        <a-tooltip placement="top">
+          <template slot="title">
+            <span>1.可回收垃圾库存量:当箱体未清运过时,库存量即投递量;当箱体清运过时,库存量即最近一次清运时间后的投递量。2.红色:表示投递重量最大的分类。</span>
+          </template>
+          可回收垃圾库存量(kg)
+          <a-icon type="question-circle" :style="{ color: '#1890FF' }" />
+        </a-tooltip>
+      </template>
+      <!-- 废旧衣物 -->
+      <template slot="clothes" slot-scope="text,record">
+        <span :style="{ color: record.maxVal==record.clothes ? 'red' : '' }">{{ record.clothes ? (record.clothes/1000).toFixed(3) : '0.00' }}</span>
+      </template>
+      <!-- 废旧纸张 -->
+      <template slot="paper" slot-scope="text,record">
+        <span :style="{ color: record.maxVal==record.paper ? 'red' : '' }">{{ record.paper ? (record.paper/1000).toFixed(3) : '0.00' }}</span>
+      </template>
+      <!-- 废旧塑料 -->
+      <template slot="plastic" slot-scope="text,record">
+        <span :style="{ color: record.maxVal==record.plastic ? 'red' : '' }">{{ record.plastic ? (record.plastic/1000).toFixed(3) : '0.000' }}</span>
+      </template>
+      <!-- 废旧金属 -->
+      <template slot="metal" slot-scope="text,record">
+        <span :style="{ color: record.maxVal==record.metal ? 'red' : '' }">{{ record.metal ? (record.metal/1000).toFixed(3) : '0.000' }}</span>
+      </template>
+      <!-- 废旧金属/塑料 -->
+      <template slot="plaMet" slot-scope="text,record">
+        <span :style="{ color: record.maxVal==record.plaMet ? 'red' : '' }">{{ record.plaMet ? (record.plaMet/1000).toFixed(3) : '0.000' }}</span>
+      </template>
+      <!-- 废旧玻璃 -->
+      <template slot="glass" slot-scope="text,record">
+        <span :style="{ color: record.maxVal==record.glass ? 'red' : '' }">{{ record.glass ? (record.glass/1000).toFixed(3) : '0.000' }}</span>
+      </template>
+      <!-- 可回收物 -->
+      <template slot="recycling" slot-scope="text,record">
+        <span :style="{ color: record.maxVal==record.recycling ? 'red' : '' }">{{ record.recycling ? (record.recycling/1000).toFixed(3) : '0.000' }}</span>
+      </template>
+      <!-- 可回收物小计 -->
+      <template slot="totalWeight" slot-scope="text,record">
+        <span >{{ record.totalWeight ? (record.totalWeight/1000).toFixed(3) : '0.000' }}</span>
+      </template>
+      <!-- 操作 -->
+      <span slot="action" slot-scope="text,record">
+        <a-button type="primary" @click="handleDetail(record)" v-hasPermission="'B_notCleanNetwork_edit'" id="notCleanNetwork-handleDetail">立即清运</a-button>
+        <span v-if="!$hasPermissions('B_notCleanNetwork_edit')">--</span>
+      </span>
+    </s-table>
+    <!-- 清运弹窗 -->
+    <cleanModal
+      :cleanStationDeviceNo="itemCleanStationDeviceNo"
+      :dirverUserId="itemDirverUserId"
+      :openModal="isOpenModal"
+      @refresh="refreshTable"
+      @close="closeCleanModal"></cleanModal>
+  </a-card>
+</template>
+
+<script>
+import { STable, VSelect } from '@/components'
+import { stationList } from '@/api/releaseRecord.js'
+import { netWorkCleanRecordList, getCleanStationSum } from '@/api/cleanManage.js'
+import { getProvince, getCityByPro, getDistrictByCity } from '@/api/station'
+import cleanModal from './cleanModal.vue'
+import moment from 'moment'
+export default {
+  components: {
+    STable,
+    VSelect,
+    cleanModal
+  },
+  data () {
+    return {
+      formItemLayout: {
+        labelCol: {
+          span: 8
+        },
+        wrapperCol: {
+          span: 16
+        }
+      },
+      isOpenModal: false, // 默认弹窗关闭
+      itemCleanStationDeviceNo: null, // 当前待清运记录司机id
+	  itemDirverUserId: null,
+      orderTotal: '', //  总计条数
+      recyclableWasteTotal: '', //  可回收垃圾总计
+      wasteClothes: '', //  废旧衣物总计
+      wastePaper: '', //  废旧纸张总计
+      wasteMetal: '', //  废旧金属总计
+      wastePlastics: '', //  废旧塑料总计
+      wasteMetalPlastic: '', //  废旧金属/塑料总计
+      wasteGlass: '', //  废旧玻璃总计
+      recyclable: '', //  可回收物总计
+      queryParam: {
+        srcDeviceCode: undefined, // 设备编号
+        stationNo: undefined, // 网点名称
+        orderType: 'max', // 排序规则
+        beginDate: null, // 开始时间
+        endDate: null, // 结束时间
+        provinceCode: undefined, //  省
+        cityCode: undefined, // 市
+        districtCode: undefined // 区
+      },
+      optionData: [], // 网点列表数据
+      addrProvinceList: [], //  省下拉
+      addrCityList: [], //  市下拉
+      addrDistrictList: [], //  区下拉
+      // 将默认当天时间日期回显在时间选择框中
+      time: [],
+      dateFormat: 'YYYY-MM-DD', // 日期格式
+      columns: [
+        { title: '网点名称', dataIndex: 'stationName', width: 100, align: 'center', customRender: (text) => { return text || '--' } },
+        { title: '设备编号', dataIndex: 'srcDeviceCode', width: 100, align: 'center', customRender: (text) => { return text || '--' } },
+        { slots: { title: 'customTitle' },
+          children: [{ title: '废旧衣物', scopedSlots: { customRender: 'clothes' }, width: 100, align: 'center' },
+            { title: '废旧塑料', scopedSlots: { customRender: 'plastic' }, width: 100, align: 'center' },
+            { title: '废旧金属', scopedSlots: { customRender: 'metal' }, width: 100, align: 'center' },
+            { title: '废旧纸张', scopedSlots: { customRender: 'paper' }, width: 100, align: 'center' },
+            { title: '废旧金属/塑料', scopedSlots: { customRender: 'plaMet' }, width: 100, align: 'center' },
+            { title: '废旧玻璃', scopedSlots: { customRender: 'glass' }, width: 100, align: 'center' },
+            { title: '可回收物', scopedSlots: { customRender: 'recycling' }, width: 100, align: 'center' }]
+        },
+        { title: '可回收垃圾小计(kg)', dataIndex: 'totalWeight', width: 100, align: 'center', scopedSlots: { customRender: 'totalWeight' } },
+        { title: '最后清运时间', dataIndex: 'lastCleanDate', width: 100, align: 'center', customRender: (text) => { return text || '--' } },
+        { title: '操作', dataIndex: 'action', width: 100, align: 'center', scopedSlots: { customRender: 'action' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        const searchData = Object.assign(parameter, this.queryParam)
+        if (this.time && this.time.length) {
+          searchData.beginDate = moment(this.time[0]).format('YYYY-MM-DD 00:00:00')
+          searchData.endDate = moment(this.time[1]).format('YYYY-MM-DD 23:59:59')
+        } else {
+          searchData.beginDate = null
+          searchData.endDate = null
+        }
+        return netWorkCleanRecordList(searchData).then(res => {
+          if (res.status == 200) {
+            for (let i = 0; i < res.data.list.length; i++) {
+              const _item = res.data.list[i]
+              //  找出可回收垃圾库存量最大的值
+              const arr = [_item.clothes, _item.paper, _item.plastic, _item.metal, _item.plaMet, _item.glass, _item.recycling]
+              const maxVal = Math.max(...arr)
+              if (maxVal == 0) {
+                _item.maxVal = null
+              } else {
+                _item.maxVal = maxVal
+              }
+            }
+            this.orderTotal = res.data.count || 0
+            this.getTotal()
+            return res.data
+          } else {
+            this.orderTotal = 0
+          }
+        })
+      }
+    }
+  },
+  mounted () {
+    this.getStationList()
+    this.getProvinceList()
+  },
+  methods: {
+    // 不可选日期
+    disabledDate (date, dateStrings) {
+      return date && date.valueOf() > Date.now()
+    },
+    // 创建时间change
+    onChange (dates, dateStrings) {
+      if ((dates, dateStrings)) {
+        this.queryParam.beginDate = dateStrings[0]
+        this.queryParam.endDate = dateStrings[1]
+      }
+    },
+    filterOption (input, option) {
+      return (
+        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+      )
+    },
+    // 编辑后刷新列表
+    refreshTable () {
+      // 编辑
+      if (this.itemStationNo && this.itemDeviceNo) {
+        this.$refs.table.refresh()
+      } else {
+        // 保存
+        this.$refs.table.refresh(true)
+      }
+    },
+    // 获取网点数据
+    getStationList () {
+      stationList().then(res => {
+        if (res.status == 200) {
+          this.optionData = res.data || []
+        } else {
+          this.optionData = []
+        }
+      })
+    },
+    //  关闭清运弹框
+    closeCleanModal () {
+      this.clernId = null
+      this.isOpenModal = false
+    },
+    // 获取省列表
+    getProvinceList () {
+      getProvince().then(res => {
+        if (res.status == 200) {
+          this.addrProvinceList = res.data || []
+        } else {
+          this.addrProvinceList = []
+        }
+      })
+    },
+    // 获取城市列表
+    getCityList (val) {
+      this.addrCityList = []
+      this.addrDistrictList = []
+      this.queryParam.cityCode = undefined
+      this.queryParam.districtCode = undefined
+      this.getCityListRequest(val)
+    },
+    getCityListRequest (val) {
+      getCityByPro({
+        id: val
+      }).then(res => {
+        if (res.status == 200) {
+          this.addrCityList = res.data || []
+        } else {
+          this.addrCityList = []
+        }
+      })
+    },
+    // 获取区县列表
+    getAreaList (val) {
+      this.addrDistrictList = []
+      this.queryParam.districtCode = undefined
+      this.getAreaListRequest(val)
+    },
+    getAreaListRequest (val) {
+      getDistrictByCity({
+        id: val
+      }).then(res => {
+        if (res.status == 200) {
+          this.addrDistrictList = res.data || []
+        } else {
+          this.addrDistrictList = []
+        }
+      })
+    },
+    // 总计
+    getTotal () {
+      const params = this.queryParam
+      if (this.time && this.time.length) {
+        params.beginDate = moment(this.time[0]).format('YYYY-MM-DD 00:00:00')
+        params.endDate = moment(this.time[1]).format('YYYY-MM-DD 23:59:59')
+      } else {
+        params.beginDate = null
+        params.endDate = null
+      }
+      getCleanStationSum(params).then(res => {
+        if (res.status == 200) {
+          if (res.data) {
+            this.recyclableWasteTotal = res.data.totalWeight ? (res.data.totalWeight / 1000).toFixed(3) : '0.000'
+            this.wastePaper = res.data.paper ? (res.data.paper / 1000).toFixed(3) : '0.000'
+            this.wasteClothes = res.data.clothes ? (res.data.clothes / 1000).toFixed(3) : '0.000'
+            this.wasteMetal = res.data.metal ? (res.data.metal / 1000).toFixed(3) : '0.000'
+            this.wastePlastics = res.data.plastic ? (res.data.plastic / 1000).toFixed(3) : '0.000'
+            this.wasteMetalPlastic = res.data.plaMet ? (res.data.plaMet / 1000).toFixed(3) : '0.000'
+            this.wasteGlass = res.data.glass ? (res.data.glass / 1000).toFixed(3) : '0.000'
+            this.recyclable = res.data.recycling ? (res.data.recycling / 1000).toFixed(3) : '0.000'
+          } else {
+            this.recyclableWasteTotal = 0
+            this.wasteClothes = 0
+            this.wastePaper = 0
+            this.wasteMetal = 0
+            this.wastePlastics = 0
+            this.wasteMetalPlastic = 0
+            this.wasteGlass = 0
+            this.recyclable = 0
+          }
+        }
+      })
+    },
+    // 重置
+    reset () {
+      this.queryParam.srcDeviceCode = undefined
+      this.queryParam.stationNo = undefined
+      this.queryParam.orderType = 'max'
+      this.queryParam.beginDate = null
+      this.queryParam.endDate = null
+      this.queryParam.provinceCode = undefined
+      this.queryParam.cityCode = undefined
+      this.queryParam.districtCode = undefined
+      this.time = []
+      this.$refs.table.refresh(true)
+    },
+    // 立即清运
+    handleDetail (record) {
+      this.itemCleanStationDeviceNo = record.cleanStationDeviceNo
+	  this.itemDirverUserId = record.dirverUserId
+      this.isOpenModal = true
+    }
+  }
+}
+</script>
+
+<style lang='less' scoped>
+	.cleanDetail-container {
+		.cleanDetail-container-searchForm {
+			.ant-form-inline .ant-form-item {
+				width: 100%;
+				margin-bottom: 15px;
+			}
+		}
+	}
+</style>

+ 607 - 0
src/views/cleanManage/statisticalReport.vue

@@ -0,0 +1,607 @@
+<template>
+  <div class="home">
+    <div class="report-page">
+      <!-- 查询条件 -->
+      <a-row>
+        <a-card class="search-panel">
+          <div class="toolsBar">
+            <a-form ref="searchForm" :model="searchForm" layout="inline">
+              <a-form-item props="queryWord" label="统计区间">
+                <a-range-picker style="width: 220px;" @change="dateChange" v-model.trim="searchForm.queryWord" :disabledDate="disabledDate" />
+              </a-form-item>
+              <a-form-item props="storeIds" label="清运网点">
+                <a-select
+                  allowClear
+                  mode="multiple"
+                  placeholder="选择网点"
+                  v-model="searchForm.storeIdList"
+                  style="width: 200px"
+                  option-filter-prop="children"
+                  :filter-option="filterOption"
+                >
+                  <a-select-option :disabled="!isStationAll && searchForm.storeIdList.length > 0" value="all" key="all">全部</a-select-option>
+                  <a-select-option :disabled="isStationAll" v-for="item in stationList" :value="item.stationNo" :key="item.id">{{ item.name }}</a-select-option>
+                </a-select>
+              </a-form-item>
+              <a-form-item>
+                <a-button type="primary" class="search-btn" @click="handleSearch()">查询</a-button>
+                <a-button type="" style="margin-left: 10px;" @click="handleReset()">重置</a-button>
+              </a-form-item>
+              <a-form-item>
+                快捷筛选:
+                <span :class="['searchItem', curentType == item.type ? 'active' : '']" v-for="(item, index) in tabList" :key="index" @click="getCurentSearchTime(item)">
+                  {{ item.name }}
+                </span>
+              </a-form-item>
+            </a-form>
+          </div>
+        </a-card>
+      </a-row>
+      <!-- 清运量数据 -->
+      <a-card class="panel" title="清运量趋势">
+        <!-- 清运量趋势图表展示 -->
+        <chart-line
+          style="height: 300px;"
+          ref="chartLine"
+          yUnit="kg"
+          :xAxisRotate="resize"
+          :xAxisData="XdaysData"
+          :seriesData="clearnChartData"
+          :color="washTypePieColor"
+          text=""
+        />
+        <span v-if="isNoData" class="noData">暂无数据</span>
+      </a-card>
+      <!-- 各回收物类型数据 -->
+      <a-card class="panel " title="各回收物类型清运数据">
+        <a-row :gutter="24">
+          <a-col :md="24" :lg="24">
+            <div style="display: flex;align-items: center;flex-wrap: wrap;">
+              <div v-for="(item, index) in qyTotalPieData" :key="index" class="module-list" :style="{ background: washTypePieColor[index] }">
+                <div>{{ item.name }}</div>
+                <span>{{ item.value }} kg</span>
+              </div>
+            </div>
+          </a-col>
+        </a-row>
+        <!-- 各回收物类型数据图表展示 -->
+        <a-row :gutter="24">
+          <a-col class="tab-card">
+            <span :class="['tab-card-item', currentTabChart == 'tab1' ? 'checked-item' : '']" @click="currentTabChart = 'tab1'">详情数据</span>
+            <span :class="['tab-card-item', currentTabChart == 'tab2' ? 'checked-item' : '']" @click="currentTabChart = 'tab2'">变化趋势</span>
+          </a-col>
+          <!-- 详情数据 -->
+          <a-col span="24" v-if="currentTabChart == 'tab1'">
+            <chart-bar
+              ref="ChartBar"
+              style="height: 300px;"
+              :xAxisRotate="resize"
+              yUnit="kg"
+              :xAxisData="XdaysData1"
+              :seriesData="hswTypeBarData"
+              :color="washTypePieColor" />
+            <span v-if="isNoData1" class="noData">暂无数据</span>
+          </a-col>
+          <!-- 变化趋势 -->
+          <a-col span="24" v-if="currentTabChart == 'tab2'">
+            <chart-line
+              ref="ChartLine"
+              style="height: 300px;"
+              yUnit="kg"
+              :xAxisRotate="resize"
+              :xAxisData="XdaysData1"
+              :seriesData="hswTypeLineData"
+              :color="washTypePieColor" />
+            <span v-if="isNoData1" class="noData">暂无数据</span>
+          </a-col>
+        </a-row>
+      </a-card>
+      <a-row :gutter="24">
+        <a-col span="12">
+          <a-card class="panel chart-pie" title="各回收物类型占比">
+            <chart-pie
+              ref="chartPie"
+              class="chartPie-box"
+              :value="qyTotalPieData"
+              title="清运总量(kg)"
+              :total="totalGroupRubbiData.cleanWeight"
+              :color="washTypePieColor"
+              :xAxisRotate="resize"
+              text=""
+            />
+          </a-card>
+        </a-col>
+        <a-col span="12">
+          <a-card class="panel chart-pie" title="各清运司机占比">
+            <!-- 各清运司机占比 百分比展示 -->
+            <chart-pie
+              ref="serverChartPie"
+              class="chartPie-box"
+              :value="sjTotalPieData"
+              title="清运总量(台)"
+              :total="totalGroupUserData.cleanWeight"
+              :color="couponColor"
+              :xAxisRotate="resize"
+              text=""
+            />
+          </a-card>
+        </a-col>
+      </a-row>
+    </div>
+  </div>
+</template>
+
+<script>
+import { ChartPie, ChartBar, ChartLine } from '@/components/Echarts'
+import _ from 'lodash'
+import getDate from '@/libs/getDate'
+import moment from 'moment'
+import { findTotalGroupRubbi, findTotalGroupUser, findTotalGroupDate, findTotalGroupDateAndRubbishType } from '@/api/cleanManage.js'
+import { stationList } from '@/api/releaseRecord.js'
+import { getLookUpData } from '@/api/data'
+export default {
+  name: 'Home',
+  components: {
+    ChartPie,
+    ChartBar,
+    ChartLine
+  },
+  watch: {
+    screenWidth (val) {
+      // 为了避免频繁触发resize函数,使用定时器
+      if (!this.timer) {
+        this.screenWidth = val
+        this.timer = true
+        const that = this
+        setTimeout(function () {
+          // that.screenWidth = that.$store.state.canvasWidth
+          console.log(that.screenWidth)
+          that.timer = false
+        }, 400)
+      }
+    }
+  },
+  computed: {
+    isStationAll () {
+      //  是否选择全部网点
+      let boolean
+      if (this.searchForm.storeIdList.length > 0) {
+        if (this.searchForm.storeIdList.indexOf('all') >= 0) {
+          boolean = true
+        } else {
+          boolean = false
+        }
+      } else {
+        boolean = false
+      }
+      return boolean
+    },
+    resize () {
+      if (this.screenWidth < 1640) {
+        return 40
+      } else {
+        return 30
+      }
+    },
+    // 各回收物类型占比
+    qyTotalPieData () {
+      const list = this.totalGroupRubbiData ? this.totalGroupRubbiData.cleanReportData : []
+      const temp = []
+      if (list.length) {
+        this.rubbishType.map(item => {
+          const has = list.find(obj => obj.rubbishType == item.code)
+          temp.push({
+            name: item.dispName,
+            value: has ? Number(has.cleanWeight / 1000).toFixed(3) : 0
+          })
+        })
+      }
+      return temp
+    },
+    // 各清运司机占比
+    sjTotalPieData () {
+      const list = this.totalGroupUserData ? this.totalGroupUserData.cleanReportData : []
+      const temp = []
+      if (list) {
+        list.map(item => {
+          temp.push({
+            name: item.operatorName,
+            value: Number(item.cleanWeight / 1000).toFixed(3)
+          })
+        })
+      }
+      return temp
+    }
+  },
+  data () {
+    return {
+      screenWidth: document.body.clientWidth, // 这里是给到了一个默认值
+      timer: false,
+      form: this.$form.createForm(this, { name: 'searchForm' }),
+      isNoData: false, // 是否有每天营业额及进店量数据
+      isNoData1: false,
+      stationList: [], // 清运网点列表
+      searchForm: {
+        queryWord: null, // 时间查询条件,默认本周
+        storeIdList: [] // 已选清运网点
+      },
+      // 快速删选tab
+      tabList: [
+        {
+          name: '今天',
+          type: 'today'
+        },
+        {
+          name: '本周',
+          type: 'thisWeek'
+        },
+        {
+          name: '上周',
+          type: 'lastWeek'
+        },
+        {
+          name: '本月',
+          type: 'thisMonth'
+        }
+      ],
+      curentType: 'thisWeek', // 当前所选时间查询类型
+      beginDate: null, // 开始时间
+      endDate: null, // 结束时间
+      // 各回收物类型占比
+      totalGroupRubbiData: {
+        cleanWeight: 0,
+        cleanReportData: []
+      },
+      // 各清运司机占比
+      totalGroupUserData: {
+        cleanWeight: 0,
+        cleanReportData: []
+      },
+      // 洗车类型数据
+      currentTabChart: 'tab1', // 洗车类型详情数据与变化趋势的tab 默认展示详情数据
+      XdaysData: [], // 图表X轴时间集合
+      XdaysData1: [],
+      // 各类型占比
+      washTypePieColor: ['#ffaa00', '#aaaa00', '#00aaff', '#ff55ff', '#1dc5d4', '#8465c7', '#ff5500', '#00aa00'],
+      couponColor: ['#ffaa00', '#ff5500', '#00aaff', '#ff55ff', '#1dc5d4', '#8465c7', '#55aa00', '#527aff'],
+      // 清运量趋势
+      clearnChartData: [
+        {
+          name: '投递量',
+          type: 'line',
+          data: []
+        },
+        {
+          name: '清运量',
+          type: 'line',
+          data: []
+        }
+      ],
+      hswTypeBarData: [],
+      hswTypeLineData: [],
+      rubbishType: []
+    }
+  },
+  methods: {
+    moment,
+    // 时间改变
+    dateChange (dates) {
+      this.curentType = ''
+    },
+    // 不可选日期
+    disabledDate (date) {
+      return (date && date.valueOf() > Date.now()) || date.valueOf() < Date.now() - 90 * 24 * 60 * 60 * 1000
+    },
+    filterOption (input, option) {
+      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+    },
+    // 查询分类数据字典
+    getTypeCode (params) {
+      const _this = this
+      getLookUpData({
+        pageNo: 1,
+        pageSize: 1000,
+        lookupCode: 'RUBBISH_TYPE'
+      }).then(res => {
+        const list = res.data.list.filter(item => item.code != 'HARM')
+        _this.rubbishType = list
+        list.map(item => {
+          // 柱状图
+          _this.hswTypeBarData.push({
+            name: item.dispName,
+            code: item.code,
+            type: 'bar',
+            data: []
+          })
+          // 折线图
+          _this.hswTypeLineData.push({
+            name: item.dispName,
+            code: item.code,
+            type: 'line',
+            data: []
+          })
+        })
+        setTimeout(() => {
+          _this.getGroupDateAndRubbishType(params)
+        }, 100)
+      })
+    },
+    // 查询网点列表
+    getListStation () {
+      stationList().then(res => {
+        if (res.status == 200) {
+          this.stationList = res.data || []
+        } else {
+          this.stationList = []
+        }
+      })
+    },
+    // 页面初始化
+    pageInit () {
+      this.form.resetFields()
+    },
+    // 查询
+    handleSearch () {
+      this.showChart = false
+      if (this.searchForm.queryWord != ',' && this.searchForm.queryWord.length) {
+        const searchTime = this.searchForm.queryWord.toString().split(',')
+        this.beginDate = this.exitTime(searchTime[0])
+        this.endDate = this.exitTime(searchTime[1])
+        this.XdaysData = []
+        this.XdaysData1 = []
+        this.getPageData()
+      } else {
+        this.$message.error('请选择统计区间')
+      }
+    },
+    // 重置
+    handleReset () {
+      this.searchForm.storeIdList = []
+      this.curentType = 'thisWeek'
+      this.getCurentSearchTime()
+    },
+    // 格式化时间
+    exitTime (time) {
+      const D = new Date(time)
+      const RES_DATE = D.getFullYear() + '-' + this.p(D.getMonth() + 1) + '-' + this.p(D.getDate())
+      return RES_DATE
+    },
+    // p为不够10添加0的函数
+    p (s) {
+      return s < 10 ? '0' + s : s
+    },
+    // 获取快速查询时间 并 赋值到时间选择框中
+    getCurentSearchTime (item) {
+      this.curentType = item ? item.type : this.curentType
+      const quickType = {
+        lastMonth: [moment(getDate.getLastMonthDays().starttime), moment(getDate.getLastMonthDays().endtime)],
+        thisMonth: [moment(getDate.getCurrMonthDays().starttime), moment(getDate.getCurrMonthDays().endtime)],
+        lastWeek: [moment(getDate.getLastWeekDays().starttime), moment(getDate.getLastWeekDays().endtime)],
+        thisWeek: [moment(getDate.getCurrWeekDays().starttime), moment(getDate.getCurrWeekDays().endtime)],
+        yesterday: [moment(getDate.getYesterday().starttime), moment(getDate.getYesterday().endtime)],
+        today: [moment(getDate.getToday().starttime), moment(getDate.getToday().endtime)]
+      }
+      console.log(quickType[this.curentType])
+      this.searchForm.queryWord = quickType[this.curentType]
+      this.beginDate = quickType[this.curentType][0].format('YYYY-MM-DD')
+      this.endDate = quickType[this.curentType][1].format('YYYY-MM-DD')
+      console.log(this.searchForm.queryWord, '1111111')
+      this.getPageData()
+    },
+    // 重置图表数据
+    resetChartsData () {
+      this.XdaysData = [] // x轴置空
+      this.XdaysData1 = [] // x轴置空
+      // 各回收物类型占比
+      this.totalGroupRubbiData = {
+        cleanWeight: 0,
+        cleanReportData: []
+      }
+      // 各清运司机占比
+      this.totalGroupUserData = {
+        cleanWeight: 0,
+        cleanReportData: []
+      }
+      // 重置清运量趋势图表数据
+      this.clearnChartData[0].data = []
+      this.clearnChartData[1].data = []
+      // 重置各回收物类型清运数据
+      this.hswTypeBarData.map(item => (item.data = []))
+      this.hswTypeLineData.map(item => (item.data = []))
+    },
+    // 根据查询条件获取所有数据
+    getPageData () {
+      this.resetChartsData()
+      const params = {
+        beginDate: this.beginDate + ' 00:00:00',
+        endDate: this.endDate + ' 00:00:00',
+        stationNoList: this.searchForm.storeIdList
+      }
+      // 各回收物类型占比
+      findTotalGroupRubbi(params).then(res => {
+        console.log(res, '各回收物类型占比')
+        if (res.status == 200) {
+          this.totalGroupRubbiData = res.data
+        }
+      })
+      // 各清运司机占比
+      findTotalGroupUser(params).then(res => {
+        console.log(res, '各清运司机占比')
+        if (res.status == 200) {
+          this.totalGroupUserData = res.data
+        }
+      })
+      // 清运量趋势
+      findTotalGroupDate(params).then(res => {
+        console.log(res, '清运量趋势')
+        if (res.status == 200) {
+          const a = res.data.deliveryReportData
+          const b = res.data.cleanReportData
+          for (const key in a) {
+            const val = Number(a[key] / 1000).toFixed(3)
+            this.clearnChartData[0].data.push(val)
+          }
+          for (const key in b) {
+            this.XdaysData.push(key)
+            const val = Number(b[key] / 1000).toFixed(3)
+            this.clearnChartData[1].data.push(val)
+          }
+          this.isNoData = false
+        } else {
+          this.isNoData = true
+        }
+      })
+
+      if (this.hswTypeBarData.length == 0) {
+        this.getTypeCode(params)
+      } else {
+        this.getGroupDateAndRubbishType(params)
+      }
+    },
+    // 各回收物类型清运数据柱状图
+    getGroupDateAndRubbishType (params) {
+      findTotalGroupDateAndRubbishType(params).then(res => {
+        console.log(res, '各回收物类型清运数据柱状图')
+        if (res.status == 200 && res.data.cleanReportData) {
+          const data = res.data.cleanReportData
+          // x 时间轴
+          for (const key in data) {
+            this.XdaysData1.push(key)
+          }
+          this.hswTypeBarData = this.formAtGroupDateAndRubbishType(data, this.hswTypeBarData)
+          this.hswTypeLineData = this.formAtGroupDateAndRubbishType(data, this.hswTypeLineData)
+          this.isNoData1 = false
+        } else {
+          this.isNoData1 = true
+        }
+      })
+    },
+    // 格式化数据
+    formAtGroupDateAndRubbishType (data, obj) {
+      obj.map(item => {
+        const ret = []
+        for (const key in data) {
+          const leve2 = data[key]
+          const row = leve2[item.code]
+          const val = row ? Number(row.cleanWeight / 1000).toFixed(3) : 0
+          ret.push(val)
+        }
+        item.data = ret
+      })
+      return obj
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {
+      vm.pageInit()
+      vm.getListStation() // 获取网点列表
+      vm.curentType = 'thisWeek'
+      vm.getCurentSearchTime()
+    })
+  },
+  // 将 reisze 事件在 vue mounted 的时候 去挂载一下它的方法
+  mounted () {
+    const that = this
+    window.onresize = () => {
+      return (() => {
+        window.screenWidth = document.body.clientWidth
+        that.screenWidth = window.screenWidth
+      })()
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+.home {
+  width: 100%;
+}
+.report-page {
+  margin-top: 10px;
+  overflow-y: scroll;
+  overflow-x: hidden;
+  .search-panel {
+    .ivu-card-body > div {
+      display: inline-block;
+      margin-right: 20px;
+    }
+
+    .desc {
+      color: #999;
+    }
+
+    .searchItem {
+      padding: 8px 20px;
+      border: 1px dashed #eeeeee;
+      margin: 0 5px;
+      border-radius: 5px;
+    }
+
+    .active {
+      background-color: #ff9900;
+      color: #fff;
+      border: none;
+    }
+  }
+  .search-panel /deep/ .ant-select-selection {
+    max-height: 150px;
+    overflow: auto;
+  }
+  .panel {
+    margin-top: 10px;
+    background-color: #ffffff;
+
+    .noData {
+      background-color: rgba(50, 50, 50, 0.7);
+      color: #fff;
+      padding: 15px 30px;
+      position: absolute;
+      top: 40%;
+      left: 40%;
+    }
+    .chartPie-box {
+      height: 300px;
+      max-width: 600px;
+      margin: 0 auto;
+    }
+    .panel-title {
+      font-size: 18px;
+      color: #333;
+      padding-bottom: 5px;
+    }
+
+    .tab-card {
+      float: right;
+      margin: 30px 0;
+      .tab-card-item {
+        padding: 5px 10px;
+        border: 1px solid #eee;
+        cursor: pointer;
+      }
+      .checked-item {
+        border-color: #2d8cf0;
+        color: #2d8cf0;
+      }
+    }
+  }
+
+  .module-list {
+    color: #ffffff;
+    padding: 10px;
+    border-radius: 10px;
+    display: flex;
+    align-items: center;
+    flex-direction: column;
+    margin: 5px;
+    min-width: 150px;
+    span {
+      font-weight: 600;
+      font-size: 20px;
+    }
+  }
+
+  .module-icon {
+    width: 52px;
+    height: 54px;
+  }
+}
+</style>

+ 217 - 234
src/views/equipmentManage/boxSetting/boxSetting.vue

@@ -1,242 +1,225 @@
 <template>
-  <a-card :bordered="false" class="network-table-page-search-wrapper">
-    <div class="network-searchForm">
-      <a-form layout="inline" :form="form" ref="form" v-bind="formItemLayout" @keyup.enter.native="$refs.table.refresh(true)">
-        <a-row :gutter="48">
-          <a-col :span="6">
-            <a-form-item label="箱体类型名称" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
-              <a-input id="boxSetting-name" allowClear :maxLength="30" v-model="queryParam.name" placeholder="请输入箱体类型名称" />
-            </a-form-item>
-          </a-col>
-          <a-col :span="6">
-            <a-button class="handle-btn serach-btn" id="boxSetting-btn-serach" type="primary" @click="$refs.table.refresh(true)">查询</a-button>
-            <a-button class="handle-btn" type="" id="boxSetting-btn-reset" @click="handleReset">重置</a-button>
-          </a-col>
-        </a-row>
-      </a-form>
-    </div>
-    <div class="table-operator">
-      <a-button type="primary" icon="plus" @click="openModal" id="boxSetting-add" v-hasPermission="'B_boxSetting_add'">新增</a-button>
-    </div>
-    <s-table
-      ref="table"
-      size="default"
-      :rowKey="(record) => record.id"
-      :columns="columns"
-      :data="loadData"
-      bordered>
-      <!-- 操作 -->
-      <template slot="action" slot-scope="text, record">
-        <a-icon
-          type="edit"
-          id="boxSetting-edit"
-          title="编辑"
-          class="actionBtn icon-blues"
-          @click="handleEdit(record)"
-          v-hasPermission="'B_boxSetting_edit'" />
-        <a-icon
-          type="delete"
-          id="boxSetting-del"
-          title="删除"
-          class="actionBtn icon-red"
-          @click="delect(record)"
-          v-if="$hasPermissions('B_boxSetting_del') && !record.isEnable"/>
-        <span v-if="!$hasPermissions('B_boxSetting_edit') && (!$hasPermissions('B_boxSetting_del') && !record.isEnable)">--</span>
-      </template>
-    </s-table>
-    <!-- 新增/编辑 弹窗 -->
-    <add-box-modal :visible="openBoxModal" :id="itemId" @refresh="refreshTable" @close="openBoxModal = false"></add-box-modal>
-  </a-card>
+	<a-card :bordered="false" class="network-table-page-search-wrapper">
+		<div class="network-searchForm">
+			<a-form layout="inline" :form="form" ref="form" v-bind="formItemLayout" @keyup.enter.native="$refs.table.refresh(true)">
+				<a-row :gutter="48">
+					<a-col :span="6">
+						<a-form-item label="箱体类型名称" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+							<a-input id="boxSetting-name" allowClear :maxLength="30" v-model="queryParam.name" placeholder="请输入箱体类型名称" />
+						</a-form-item>
+					</a-col>
+					<a-col :span="6">
+						<a-button class="handle-btn serach-btn" id="boxSetting-btn-serach" type="primary" @click="$refs.table.refresh(true)">查询</a-button>
+						<a-button class="handle-btn" type="" id="boxSetting-btn-reset" @click="handleReset">重置</a-button>
+					</a-col>
+				</a-row>
+			</a-form>
+		</div>
+		<div class="table-operator">
+			<a-button type="primary" icon="plus" @click="openModal" id="boxSetting-add" v-hasPermission="'B_boxSetting_add'">新增</a-button>
+		</div>
+		<s-table ref="table" size="default" :rowKey="(record) => record.id" :columns="columns" :data="loadData" bordered>
+			<!-- 操作 -->
+			<template slot="action" slot-scope="text, record">
+				<a-icon type="edit" id="boxSetting-edit" title="编辑" class="actionBtn icon-blues" @click="handleEdit(record)"
+				 v-hasPermission="'B_boxSetting_edit'" />
+				<a-icon type="delete" id="boxSetting-del" title="删除" class="actionBtn icon-red" @click="delect(record)" v-if="$hasPermissions('B_boxSetting_del') && !record.isEnable" />
+				<span v-if="!$hasPermissions('B_boxSetting_edit') && (!$hasPermissions('B_boxSetting_del') && !record.isEnable)">--</span>
+			</template>
+		</s-table>
+		<!-- 新增/编辑 弹窗 -->
+		<add-box-modal :visible="openBoxModal" :id="itemId" @refresh="refreshTable" @close="openBoxModal = false"></add-box-modal>
+	</a-card>
 </template>
 
 <script>
-import {
-  STable,
-  VSelect
-} from '@/components'
-import AddBoxModal from './AddBoxModal.vue'
-import {
-  getBoxList,
-  deleteBoxSetting
-} from '@/api/boxSetting.js'
-export default {
-  name: 'Equipment',
-  components: {
-    STable,
-    VSelect,
-    AddBoxModal
-  },
-  data () {
-    return {
-      form: this.$form.createForm(this),
-      formItemLayout: {
-        labelCol: {
-          span: 7
-        },
-        wrapperCol: {
-          span: 17
-        }
-      },
-      // 查询参数
-      queryParam: {
-        name: '' // 箱体类型
-      },
-      openBoxModal: false, // 新增/编辑弹窗
-      itemId: '', //  箱体id
-      // 表头
-      columns: [{
-        title: '序号',
-        dataIndex: 'no',
-        width: 70,
-        align: 'center'
-      },
-      {
-        title: '创建时间',
-        dataIndex: 'createDate',
-        width: 180,
-        align: 'center'
-      },
-      {
-        title: '箱体类型名称',
-        dataIndex: 'name',
-        width: 200,
-        align: 'center'
-      },
-      {
-        title: '内置箱体数量(个)',
-        dataIndex: 'boxNum',
-        width: 80,
-        align: 'center'
-      },
-      {
-        title: '内置箱体投放限重(g)/ 对应资源分类',
-        children: [{
-          title: '1号箱',
-          dataIndex: 'one',
-          width: 120,
-          align: 'center',
-		  customRender: (record, text) => {
-		    return record ? (record.maxWeight ? (record.maxWeight + '/' + record.rubbishTypeDictValue) : '--') : '--'
-		  }
-        },
-        {
-          title: '2号箱',
-          dataIndex: 'two',
-          width: 120,
-          align: 'center',
-		  customRender: (record, text) => {
-		    return record ? (record.maxWeight ? (record.maxWeight + '/' + record.rubbishTypeDictValue) : '--') : '--'
-		  }
-        },
-        {
-          title: '3号箱',
-          dataIndex: 'three',
-          width: 120,
-          align: 'center',
-          customRender: (record, text) => {
-            return record ? (record.maxWeight ? (record.maxWeight + '/' + record.rubbishTypeDictValue) : '--') : '--'
-          }
-        },
-        {
-          title: '4号箱',
-          dataIndex: 'four',
-          width: 120,
-          align: 'center',
-          customRender: (record, text) => {
-            return record ? (record.maxWeight ? (record.maxWeight + '/' + record.rubbishTypeDictValue) : '--') : '--'
-          }
-        },
-        {
-          title: '5号箱',
-          dataIndex: 'five',
-          width: 120,
-          align: 'center',
-          customRender: (record, text) => {
-            return record ? (record.maxWeight ? (record.maxWeight + '/' + record.rubbishTypeDictValue) : '--') : '--'
-          }
-        }
-        ]
-      },
-      {
-        title: '操作',
-        scopedSlots: {
-          customRender: 'action'
-        },
-        width: 120,
-        align: 'center'
-      }
-      ],
-      // 加载数据方法 必须为 Promise 对象
-      loadData: parameter => {
-        return getBoxList(Object.assign(parameter, this.queryParam)).then(res => {
-          if (res.status == 200) {
-            const no = (res.data.pageNo - 1) * res.data.pageSize
-            for (let i = 0; i < res.data.list.length; i++) {
-              const _item = res.data.list[i]
-              _item.no = no + i + 1
-            }
-            return res.data
-          }
-        })
-      }
+	import {
+		STable,
+		VSelect
+	} from '@/components'
+	import AddBoxModal from './AddBoxModal.vue'
+	import {
+		getBoxList,
+		deleteBoxSetting
+	} from '@/api/boxSetting.js'
+	export default {
+		name: 'Equipment',
+		components: {
+			STable,
+			VSelect,
+			AddBoxModal
+		},
+		data() {
+			return {
+				form: this.$form.createForm(this),
+				formItemLayout: {
+					labelCol: {
+						span: 7
+					},
+					wrapperCol: {
+						span: 17
+					}
+				},
+				// 查询参数
+				queryParam: {
+					name: '' // 箱体类型
+				},
+				openBoxModal: false, // 新增/编辑弹窗
+				itemId: '', //  箱体id
+				// 表头
+				columns: [{
+						title: '序号',
+						dataIndex: 'no',
+						width: 70,
+						align: 'center'
+					},
+					{
+						title: '创建时间',
+						dataIndex: 'createDate',
+						width: 180,
+						align: 'center'
+					},
+					{
+						title: '箱体类型名称',
+						dataIndex: 'name',
+						width: 200,
+						align: 'center'
+					},
+					{
+						title: '内置箱体数量(个)',
+						dataIndex: 'boxNum',
+						width: 80,
+						align: 'center'
+					},
+					{
+						title: '内置箱体投放限重(g)/ 对应资源分类',
+						children: [{
+								title: '1号箱',
+								dataIndex: 'one',
+								width: 120,
+								align: 'center',
+								customRender: (record, text) => {
+									return record ? (record.maxWeight ? (record.maxWeight + '/' + record.rubbishTypeDictValue) : '--') : '--'
+								}
+							},
+							{
+								title: '2号箱',
+								dataIndex: 'two',
+								width: 120,
+								align: 'center',
+								customRender: (record, text) => {
+									return record ? (record.maxWeight ? (record.maxWeight + '/' + record.rubbishTypeDictValue) : '--') : '--'
+								}
+							},
+							{
+								title: '3号箱',
+								dataIndex: 'three',
+								width: 120,
+								align: 'center',
+								customRender: (record, text) => {
+									return record ? (record.maxWeight ? (record.maxWeight + '/' + record.rubbishTypeDictValue) : '--') : '--'
+								}
+							},
+							{
+								title: '4号箱',
+								dataIndex: 'four',
+								width: 120,
+								align: 'center',
+								customRender: (record, text) => {
+									return record ? (record.maxWeight ? (record.maxWeight + '/' + record.rubbishTypeDictValue) : '--') : '--'
+								}
+							},
+							{
+								title: '5号箱',
+								dataIndex: 'five',
+								width: 120,
+								align: 'center',
+								customRender: (record, text) => {
+									return record ? (record.maxWeight ? (record.maxWeight + '/' + record.rubbishTypeDictValue) : '--') : '--'
+								}
+							}
+						]
+					},
+					{
+						title: '操作',
+						scopedSlots: {
+							customRender: 'action'
+						},
+						width: 120,
+						align: 'center'
+					}
+				],
+				// 加载数据方法 必须为 Promise 对象
+				loadData: parameter => {
+					return getBoxList(Object.assign(parameter, this.queryParam)).then(res => {
+						if (res.status == 200) {
+							const no = (res.data.pageNo - 1) * res.data.pageSize
+							for (let i = 0; i < res.data.list.length; i++) {
+								const _item = res.data.list[i]
+								_item.no = no + i + 1
+							}
+							return res.data
+						}
+					})
+				}
 
-    }
-  },
-  beforeRouteEnter (to, from, next) {
-    next(vm => {
-      vm.queryParam.name = ''
-    })
-  },
-  methods: {
-    // 重置
-    handleReset () {
-      console.log('重置', this.queryParam)
-      this.form.resetFields()
-	  this.queryParam.name = ''
-      this.$refs.table.refresh(true)
-    },
-    // 新建
-    openModal () {
-      this.openBoxModal = true
-      this.itemId = ''
-    },
-    // 编辑
-    handleEdit (item) {
-      this.openBoxModal = true
-	    this.itemId = item.id
-    },
-    // 新增/编辑 后刷新列表
-    refreshTable () {
-      if (this.itemId) {
-        this.$refs.table.refresh()
-      } else {
-        this.$refs.table.refresh(true)
-      }
-    },
-    // 删除
-    delect (row) {
-      const _this = this
-      this.$confirm({
-        title: '警告',
-        centered: true,
-        content: '删除后无法恢复,确认删除?',
-        okText: '确定',
-        cancelText: '取消',
-        onOk () {
-          deleteBoxSetting({
-            id: row.id
-          }).then(res => {
-            console.log(res, 'res1111')
-            if (res.status == 200) {
-              _this.$message.success(res.message)
-              _this.$refs.table.refresh()
-            }
-          })
-        }
-      })
-    }
-  }
-}
+			}
+		},
+		beforeRouteEnter(to, from, next) {
+			next(vm => {
+				vm.queryParam.name = ''
+			})
+		},
+		methods: {
+			// 重置
+			handleReset() {
+				console.log('重置', this.queryParam)
+				this.form.resetFields()
+				this.queryParam.name = ''
+				this.$refs.table.refresh(true)
+			},
+			// 新建
+			openModal() {
+				this.openBoxModal = true
+				this.itemId = ''
+			},
+			// 编辑
+			handleEdit(item) {
+				this.openBoxModal = true
+				this.itemId = item.id
+			},
+			// 新增/编辑 后刷新列表
+			refreshTable() {
+				if (this.itemId) {
+					this.$refs.table.refresh()
+				} else {
+					this.$refs.table.refresh(true)
+				}
+			},
+			// 删除
+			delect(row) {
+				const _this = this
+				this.$confirm({
+					title: '警告',
+					centered: true,
+					content: '删除后无法恢复,确认删除?',
+					okText: '确定',
+					cancelText: '取消',
+					onOk() {
+						deleteBoxSetting({
+							id: row.id
+						}).then(res => {
+							console.log(res, 'res1111')
+							if (res.status == 200) {
+								_this.$message.success(res.message)
+								_this.$refs.table.refresh()
+							}
+						})
+					}
+				})
+			}
+		}
+	}
 </script>
 <style lang="less" scoped>
 	.network-table-page-search-wrapper {

+ 139 - 0
src/views/equipmentManage/electronicScale/addElectronicScale.vue

@@ -0,0 +1,139 @@
+<template>
+  <a-modal :footer="null" centered :title="titleText" v-model="isShow" @cancle="cancel">
+    <a-spin :spinning="loading">
+      <a-form-model :model="formData" ref="ruleForm" :rules="rules">
+        <a-form-model-item label="设备MAC地址" :label-col="{span:6}" :wrapper-col="{span:16}" prop="macAddress">
+          <a-input
+            placeholder="请输入设备MAC地址"
+            :disabled="id?true:false"
+            v-model="formData.macAddress"
+            allowClea
+            oninput="value=value.toLowerCase()"
+            :maxLength="12" />
+        </a-form-model-item>
+        <a-form-model-item label="设备名称" :label-col="{span:6}" :wrapper-col="{span:16}" prop="deviceName">
+          <a-input placeholder="请输入设备名称" v-model="formData.deviceName" allowClear :maxLength="30"/>
+        </a-form-model-item>
+        <a-form-model-item label="设备编号" :label-col="{span:6}" :wrapper-col="{span:16}" prop="deviceCode">
+          <a-input placeholder="请输入设备编号" v-model="formData.deviceCode" allowClear :maxLength="30"/>
+        </a-form-model-item>
+        <a-form-model-item label="设备型号" :label-col="{span:6}" :wrapper-col="{span:16}" prop="deviceModel">
+          <a-input placeholder="请输入设备型号" v-model="formData.deviceModel" allowClear :maxLength="30"/>
+        </a-form-model-item>
+        <a-form-model-item label="生产厂家" :label-col="{span:6}" :wrapper-col="{span:16}" prop="manufacturer">
+          <a-input placeholder="请输入生产厂家" v-model="formData.manufacturer" allowClear :maxLength="30"/>
+        </a-form-model-item>
+        <a-form-model-item :wrapper-col="{ span: 24, offset: 8 }">
+          <a-button type="primary" @click="handleSubmit()" :style="{ marginRight: '15px' }">
+            保存
+          </a-button>
+          <a-button :style="{ marginLeft: '15px' }" @click="cancel">
+            取消
+          </a-button>
+        </a-form-model-item>
+      </a-form-model>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { saveDevice, deviceDetails } from '@/api/electronicScale.js'
+export default {
+  name: 'AddElectronicScale',
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    deviceCode: {
+      type: [Number, String],
+      default: ''
+    },
+    id: {
+      type: [Number, String],
+      default: ''
+    }
+  },
+  data () {
+    return {
+      formData: { macAddress: '', deviceCode: '', deviceName: '', deviceModel: '', manufacturer: '' },
+      isShow: this.visible, // 弹框状态
+      titleText: '新增',
+      rules: {
+        macAddress: [{ required: true, message: '请输入设备MAC地址(数字与英文字母组合)', trigger: 'blur', pattern: /^[A-Za-z0-9]+$/ }]
+      },
+      loading: false
+    }
+  },
+  methods: {
+    // 数据详情
+    getPageInfo () {
+      const _this = this
+      _this.loading = true
+      deviceDetails({
+        srcDeviceCode: _this.deviceCode
+      }).then(res => {
+        if (res.status == 200) {
+          _this.loading = false
+          _this.formData = Object.assign({}, this.formData, res.data)
+          _this.formData.loginFlag = Number(this.formData.loginFlag)
+        }
+      })
+    },
+    // 保存
+    handleSubmit () {
+      this.$refs.ruleForm.validate(valid => {
+        const _this = this
+        if (valid) {
+          const params = JSON.parse(JSON.stringify(this.formData))
+          saveDevice(params).then(res => {
+            console.log(res, 'rrrrrrrrr')
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$emit('refresh')
+              setTimeout(function () {
+                _this.cancel()
+              }, 300)
+            }
+          })
+        }
+      })
+    },
+    cancel (e) {
+      this.clear()
+      this.$emit('close')
+    },
+    clear () {
+      this.$refs.ruleForm.resetFields()
+      delete this.formData.id
+      this.formData.macAddress = ''
+      this.formData.deviceCode = ''
+      this.formData.deviceName = ''
+      this.formData.deviceModel = ''
+      this.formData.manufacturer = ''
+    }
+  },
+  // 监听弹窗
+  watch: {
+    // 父页面传过来的弹窗状态
+    visible (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    isShow (newValue, oldValue) {
+      if (newValue) {
+        if (this.id) { // 编辑
+          this.titleText = '编辑'
+          this.getPageInfo()
+        } else {
+          this.titleText = '新增'
+        }
+      } else {
+        this.cancel()
+      }
+    }
+  }
+}
+</script>
+
+<style>
+</style>

+ 226 - 0
src/views/equipmentManage/electronicScale/electronicScale.vue

@@ -0,0 +1,226 @@
+<template>
+  <a-card class="electronicScale-container" :bordered="false">
+    <!-- 搜索框 -->
+    <div class="electronicScale-container-searchForm">
+      <a-form-model :model="searchForm" layout="inline" ref="searchForm" @keyup.enter.native="$refs.table.refresh(true)">
+        <a-row :gutter="24">
+          <a-col :xs="24" :sm="12" :md="8" :lg="6">
+            <a-form-model-item label="设备MAC地址" :label-col="{ span: 7 }" :wrapper-col="{ span: 17 }">
+              <a-input v-model="searchForm.macAddress" placeholder="请输入设备MAC地址" :maxLength="12" allowClear id="electronicScale-macAddress"/>
+            </a-form-model-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="8" :lg="6">
+            <a-button class="handle-btn serach-btn" type="primary" @click="$refs.table.refresh(true)" id="electronicScale-refresh">查询</a-button>
+            <a-button class="handle-btn" type="" @click="handleReset" id="electronicScale-handleReset">重置</a-button>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </div>
+    <!-- 新增 -->
+    <div class="electronicScale-container-add"><a-button type="primary" icon="plus" @click="openModal" id="electronicScale-openModal" v-hasPermission="'B_electronicScale_add'">新增</a-button></div>
+    <!-- 合计 -->
+    <a-alert type="info" showIcon style="margin-bottom:15px">
+      <div class="ftext" slot="message">
+        总计
+        <span>{{ totalNum }} 个</span>
+      </div>
+    </a-alert>
+    <!-- 列表 -->
+    <s-table ref="table" :rowKey="record => record.id" :columns="columns" :data="loadData" bordered>
+      <span slot="action" slot-scope="text, record">
+        <a-icon type="qrcode" title="二维码" class="actionBtn icon-green" @click="getQrCode(record)" />
+        <a-icon type="edit" title="编辑" class="actionBtn icon-blues" @click="handleEdit(record)" v-hasPermission="'B_electronicScale_edit'"/>
+        <a-icon type="delete" title="删除" class="actionBtn icon-red" @click="delect(record)" v-hasPermission="'B_electronicScale_del'"/>
+      </span>
+      <span v-if="!($hasPermissions('B_electronicScale_edit') && $hasPermissions('B_electronicScale_del'))">--</span>
+    </s-table>
+    <!-- 新增/编辑弹窗 -->
+    <addElectronicScale :visible="isOpenModal" :id="itemId" :deviceCode="itemDeviceCode" @refresh="refreshTable" @close="isOpenModal = false"></addElectronicScale>
+    <!-- 查看小程序码 -->
+    <a-modal
+      class="qrCodeModal"
+      title="查看MAC地址二维码"
+      :width="400"
+      :footer="null"
+      :shName="shName"
+      :destroyOnClose="true"
+      @cancel="isQrCodeModal = false"
+      v-model="isQrCodeModal">
+      <img :src="qrCode" width="300" height="300" class="qrCode" />
+      <a-button type="primary" class="downQrCode" @click="downloadCode">下载二维码</a-button>
+    </a-modal>
+  </a-card>
+</template>
+
+<script>
+import { STable } from '@/components'
+import addElectronicScale from './addElectronicScale.vue'
+import { getDeviceList, delectDevice } from '@/api/electronicScale.js'
+import QRCode from 'qrcode'
+export default {
+  components: { STable, addElectronicScale },
+  data () {
+    return {
+      searchForm: {
+        macAddress: '' // 设备MAC地址
+      },
+      isOpenModal: false, // 默认弹窗关闭
+      itemDeviceCode: '', // 编辑行设备编号
+      itemId: '', // 编辑行id
+      totalNum: '', // 总计条数
+      isQrCodeModal: false,
+      shName: '',
+      qrCode: '',
+      // 列表表头
+      columns: [
+        { title: '序号', dataIndex: 'no', width: 60, align: 'center' },
+        { title: '创建时间', dataIndex: 'createDate', width: 100, align: 'center' },
+        { title: '设备MAC地址', dataIndex: 'macAddress', width: 100, align: 'center' },
+        { title: '设备名称', dataIndex: 'deviceName', width: 100, align: 'center', ellipsis: true, customRender: text => { return text || '--' } },
+        { title: '设备编号', dataIndex: 'deviceCode', width: 100, align: 'center', ellipsis: true, customRender: text => { return text || '--' } },
+        { title: '设备型号', dataIndex: 'deviceModel', width: 100, align: 'center', ellipsis: true, customRender: text => { return text || '--' } },
+        { title: '生产厂家', dataIndex: 'manufacturer', width: 100, align: 'center', ellipsis: true, customRender: text => { return text || '--' } },
+        { title: '操作', dataIndex: 'action', width: 100, align: 'center', scopedSlots: { customRender: 'action' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        return getDeviceList(Object.assign(parameter, this.searchForm, { deviceType: 'STEELYARD' })).then(res => {
+          if (res.status == 200) {
+            const no = (res.data.pageNo - 1) * res.data.pageSize
+            for (let i = 0; i < res.data.list.length; i++) {
+              const _item = res.data.list[i]
+              _item.no = no + i + 1
+            }
+            this.totalNum = res.data.count
+            return res.data
+          } else {
+            this.totalNum = 0
+          }
+        })
+      }
+    }
+  },
+  methods: {
+    //  下载二维码
+    downloadCode (item) {
+      const link = document.createElement('a')
+      link.href = this.qrCode
+      if (this.shName) {
+        link.download = this.shName + '.png'
+      } else {
+        link.download = 'MAC地址二维码' + '.png'
+      }
+
+      link.click()
+    },
+    // 查看二维码
+    getQrCode (item) {
+      const _this = this
+      const opts = {
+        errorCorrectionLevel: 'H',
+        type: 'image/jpeg',
+        quality: 0.3,
+        margin: 1.5,
+        width: 240,
+        color: {
+          dark: '#000000',
+          light: '#ffffff'
+        }
+      }
+      const url = item.macAddress
+      _this.shName = item.deviceName
+      if (url) {
+        QRCode.toDataURL(url, opts, function (err, url) {
+          _this.qrCode = url
+          _this.isQrCodeModal = true
+        })
+      }
+    },
+    // 重置
+    handleReset () {
+      this.searchForm = {
+        macAddress: ''
+      }
+      this.$refs.table.refresh(true)
+    },
+    // 新增
+    openModal () {
+      this.itemId = ''
+      this.itemDeviceCode = ''
+      this.isOpenModal = true
+    },
+    // 编辑
+    handleEdit (record) {
+      this.itemId = record.id
+      this.itemDeviceCode = record.srcDeviceCode
+      this.isOpenModal = true
+    },
+    // 删除
+    delect (record) {
+      const _this = this
+      _this.$confirm({
+        title: '警告',
+        centered: true,
+        content: '删除后无法恢复,确认删除?',
+        okText: '确定',
+        cancelText: '取消',
+        onOk () {
+          delectDevice({
+            id: record.id
+          }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+            }
+          })
+        }
+      })
+    },
+    // 保存或编辑后刷新列表
+    refreshTable () {
+      // 编辑
+      if (this.itemId) {
+        this.$refs.table.refresh()
+      } else {
+        // 保存
+        this.$refs.table.refresh(true)
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.electronicScale-container {
+  .electronicScale-container-searchForm {
+    .ant-form-inline .ant-form-item {
+      width: 100%;
+    }
+  }
+
+  // 查询按钮
+  .handle-btn {
+    margin-top: 4px;
+  }
+
+  .serach-btn {
+    margin-right: 10px;
+  }
+
+  .electronicScale-container-add {
+    margin: 15px 0;
+  }
+}
+ // 查看小程序码  弹框
+  .qrCodeModal {
+    .qrCode {
+      display: block;
+      max-width: 100%;
+      margin: 0 auto;
+    }
+    .downQrCode {
+      display: block;
+      margin: 30px auto;
+    }
+  }
+</style>

+ 1 - 1
src/views/equipmentManage/equipment/equipment.vue

@@ -136,7 +136,7 @@ export default {
       ],
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
-        return deviceList(Object.assign(parameter, this.queryParam)).then(res => {
+        return deviceList(Object.assign(parameter, this.queryParam,{ deviceType:"BOX"})).then(res => {
           if (res.status == 200) {
             const no = (res.data.pageNo - 1) * res.data.pageSize
             this.orderTotal = res.data.count

+ 8 - 5
src/views/equipmentManage/exchangeSetting/ExchangeSetting.vue

@@ -107,7 +107,10 @@ export default {
         title: '兑换规则说明',
         dataIndex: 'remarks',
         width: 200,
-        align: 'center'
+        align: 'center',
+        customRender: (text) => {
+          return text || '--'
+        }
       },
       {
         title: '兑换规则(投放重量(g)/可兑换乐豆数(个))',
@@ -165,7 +168,7 @@ export default {
             return record ? (record.rubbishWeight ? (record.rubbishWeight + 'g/' + record.goleNum + '个') : '不兑换') : '不兑换'
           }
         },
-		{
+        {
 		  title: '废旧玻璃',
 		  dataIndex: 'glass',
 		  width: 100,
@@ -173,8 +176,8 @@ export default {
 		  customRender: (record, text) => {
 		    return record ? (record.rubbishWeight ? (record.rubbishWeight + 'g/' + record.goleNum + '个') : '不兑换') : '不兑换'
 		  }
-		},
-		{
+        },
+        {
 		  title: '可回收物',
 		  dataIndex: 'recycling',
 		  width: 100,
@@ -182,7 +185,7 @@ export default {
 		  customRender: (record, text) => {
 		    return record ? (record.rubbishWeight ? (record.rubbishWeight + 'g/' + record.goleNum + '个') : '不兑换') : '不兑换'
 		  }
-		}
+        }
         ]
       },
       {

+ 8 - 2
src/views/equipmentManage/network/detailsModal.vue

@@ -51,6 +51,7 @@
         :rowKey="record => record.id"
         :columns="columns"
         :dataSource="equipmentData"
+        :loading="loading"
         :pagination="false"
         bordered>
         <!-- 设备状态 -->
@@ -59,7 +60,8 @@
         </template>
         <!-- 工作状态 -->
         <template slot="state" slot-scope="text, record">
-          <span :class="record.state==0 ? 'red' : record.state==1 ? 'green' : ''">{{ record.state == 0 ? '已禁用' : record.state == 1 ? '已启用' : '--' }}</span>
+          <span v-if="record.deviceType!='STEELYARD'" :class="record.state==0 ? 'red' : record.state==1 ? 'green' : ''">{{ record.state == 0 ? '已禁用' : record.state == 1 ? '已启用' : '--' }}</span>
+          <span v-else>--</span>
         </template>
       </a-table>
     </div>
@@ -97,7 +99,8 @@ export default {
         { title: '工作状态', scopedSlots: { customRender: 'state' }, width: 200, align: 'center' },
         { title: '箱体类型', dataIndex: 'deviceTypeName', width: 200, align: 'center' }
       ],
-      equipmentData: []
+      equipmentData: [],
+      loading: false
     }
   },
   methods: {
@@ -111,6 +114,7 @@ export default {
     },
     //  已绑设备
     getDevice () {
+      this.loading = true
       deviceListQuery({ stationNo: this.networkNo }).then(res => {
         console.log(res)
         if (res.status == 200) {
@@ -121,6 +125,7 @@ export default {
         } else {
           this.equipmentData = []
         }
+        this.loading = false
       })
     }
   },
@@ -132,6 +137,7 @@ export default {
     //  重定义的弹框状态
     isShow (newValue, oldValue) {
       if (!newValue) {
+        this.equipmentData = []
         this.$emit('close')
       }
     },

+ 13 - 19
src/views/equipmentManage/network/equipmentModal.vue

@@ -4,7 +4,7 @@
     class="edit-network-modal"
     :footer="null"
     :maskClosable="false"
-    title="绑定箱体设备"
+    title="绑定设备"
     v-model="isShow"
     @cancle="isShow=false"
     :width="1000">
@@ -14,7 +14,7 @@
         id="equipment-search"
         class="search-s"
         allow-clear
-        placeholder="请通过设备编号搜索"
+        placeholder="请通过设备编号或MAC地址搜索"
         enter-button="查询"
         size="large"
         v-model="searchVal"
@@ -50,8 +50,9 @@
         :data-source="equipmentData"
         :pagination="false">
         <!-- 设备状态 -->
-        <template slot="onlineFlag" slot-scope="text, record">
-          <span :class="record.onlineFlag==0 ? 'red' : record.onlineFlag==1 ? 'green' : ''">{{ record.onlineFlag == 0 ? '离线' : record.onlineFlag == 1 ? '在线' : '--' }}</span>
+        <template slot="onlineFlag" slot-scope="record">
+          <span v-if="record.deviceType!='STEELYARD'" :style="{'color':(record.onlineFlag==0 ? 'red' : record.onlineFlag==1 ? 'green' : '')}">{{ record.onlineFlag == 0 ? '离线' : record.onlineFlag == 1 ? '在线' :'--' }}</span>
+          <span v-else>--</span>
         </template>
         <!-- 箱体类型 -->
         <template slot="type" slot-scope="record">
@@ -60,12 +61,14 @@
             placeholder="请选择箱体类型"
             style="width: 100%;"
             v-model="record.deviceTypeNo"
+            v-if="record.deviceType!='STEELYARD'"
             :disabled="record.state == 1"
             @change="typeChange($event, record)">
             <a-select-option v-for="(item,index) in record.deviceTypeList" :key="index" :value="item.deviceTypeNo">
               {{ item.name }}
             </a-select-option>
           </a-select>
+          <span v-else>--</span>
         </template>
         <!-- 工作状态 -->
         <template slot="workStatus" slot-scope="record">
@@ -73,9 +76,11 @@
             checkedChildren="启用"
             unCheckedChildren="禁用"
             id="equipment-changeFlagHandle"
+            v-if="record.state && record.deviceType!='STEELYARD'"
             v-model="record.state == 1 ? true : false"
             @change="changeFlagHandle(record)"
           />
+          <span v-else>--</span>
         </template>
         <!-- 操作 -->
         <template slot="action" slot-scope="record">
@@ -123,6 +128,7 @@ export default {
         { title: '序号', dataIndex: 'no', width: 60, align: 'center' },
         { title: '设备编号', dataIndex: 'srcDeviceCode', width: 100, align: 'center' },
         { title: '设备状态', scopedSlots: { customRender: 'onlineFlag' }, width: 150, align: 'center' },
+        { title: '设备类型', dataIndex: 'deviceTypeDictValue', width: 150, align: 'center' },
         { title: '箱体类型', scopedSlots: { customRender: 'type' }, width: 150, align: 'center' },
         { title: '工作状态', scopedSlots: { customRender: 'workStatus' }, width: 150, align: 'center' },
         { title: '操作', scopedSlots: { customRender: 'action' }, width: 80, align: 'center' }
@@ -137,12 +143,11 @@ export default {
     getDevice () {
       deviceListQuery({ stationNo: this.networkNo }).then(res => {
         if (res.status == 200) {
-          res.data.map((item, index) => {
-            item.no = index + 1
-          })
           this.equipmentData = res.data
           this.equipmentData.map((item, index) => {
-            item.deviceTypeList = this.setDeviceType(item.boxNum)
+            item.no = index + 1
+            //  处理每个设备所对应的箱体类型
+            item.deviceTypeList = this.typeList.filter(tk => !item.boxNum || tk.boxNum == item.boxNum)
           })
         } else {
           this.equipmentData = []
@@ -161,17 +166,6 @@ export default {
         this.getDevice()
       })
     },
-    //  处理每个设备所对应的箱体类型
-    setDeviceType (boxNum) {
-      const arr = []
-      let j = 0
-      for (const i in this.typeList) {
-        if (this.typeList[i].boxNum == boxNum) {
-          arr[j++] = this.typeList[i]
-        }
-      }
-      return arr
-    },
     //  搜索设备
     onSearch (value) {
       if (value) {

+ 1 - 1
src/views/map/NodeMap.vue

@@ -148,7 +148,7 @@
             <chart-bar
               ref="ChartBar"
               class="chart-box"
-              color="#0000fe"
+              :color="['#0000fe']"
               :yMax="1000"
               yUnit="台"
               :value="equipmentBarData"

+ 258 - 0
src/views/market/luckDrawRecord.vue

@@ -0,0 +1,258 @@
+<template>
+  <a-card :bordered="false" class="luckDrawRecord-table-page-search-wrapper">
+    <div class="luckDrawRecord-searchForm">
+      <a-form layout="inline" v-bind="formItemLayout" @keyup.enter.native="$refs.table.refresh(true)">
+        <a-row :gutter="24">
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-item label="抽奖时间" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-range-picker
+                id="luckDrawRecord-time"
+                v-model="time"
+                :format="dateFormat"
+                :placeholder="['开始时间','结束时间']"
+                :disabledDate="disabledDate"
+                @change="onChange" />
+            </a-form-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-item label="用户账号" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-input id="luckDrawRecord-customerMobile" allowClear v-model="queryParam.customerMobile" placeholder="请输入用户账号" />
+            </a-form-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-item label="活动名称" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-input id="luckDrawRecord-activeName" allowClear v-model="queryParam.activeName" placeholder="请输入活动名称" />
+            </a-form-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="5">
+            <a-form-item label="是否中奖" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <v-select
+                v-model="queryParam.state"
+                ref="orderState"
+                id="luckDrawRecord-state"
+                code="PRIZE_WIN_STATE"
+                placeholder="请选择"
+                allowClear></v-select>
+            </a-form-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="6" :lg="4">
+            <a-button class="handle-btn serach-btn" id="luckDrawRecord-btn-serach" type="primary" @click="$refs.table.refresh(true)">查询</a-button>
+            <a-button class="handle-btn serach-btn" type="" id="luckDrawRecord-btn-reset" @click="handleReset">重置</a-button>
+            <a-button class="export-btn" id="luckDrawRecord-btn--export" :loading="loading" v-hasPermission="'B_winingRecord_export'" @click="handleExport">导出</a-button>
+          </a-col>
+        </a-row>
+        <a-row :gutter="20">
+        </a-row>
+      </a-form>
+    </div>
+    <s-table
+      ref="table"
+      size="default"
+      :rowKey="(record) => record.id"
+      :columns="columns"
+      :data="loadData"
+      bordered>
+    </s-table>
+  </a-card>
+</template>
+
+<script>
+import {
+  STable,
+  VSelect
+} from '@/components'
+import {
+  getLuckyWinList
+} from '@/api/luckyDraw.js'
+import moment from 'moment'
+export default {
+  name: 'LuckDrawRecord',
+  components: {
+    STable,
+    VSelect
+  },
+  data () {
+    return {
+      formItemLayout: {
+        labelCol: {
+          span: 6
+        },
+        wrapperCol: {
+          span: 18
+        }
+      },
+      // 查询参数
+      queryParam: {
+        beginDate: null, // 开始时间
+        endDate: null, // 结束时间
+        customerMobile: '', // 用户
+        activeName: '' // 活动名称
+      },
+      loading: false, // 导出loading
+      // 表头
+      columns: [{
+        title: '序号',
+        dataIndex: 'no',
+        width: 80,
+        align: 'center'
+      },
+      {
+        title: '参与抽奖时间',
+        dataIndex: 'winTime',
+        width: 200,
+        align: 'center'
+      },
+      {
+        title: '活动名称',
+        dataIndex: 'activeName',
+        width: 200,
+        align: 'center'
+      },
+      {
+        title: '用户账号',
+        dataIndex: 'customerMobile',
+        width: 200,
+        align: 'center'
+      },
+      {
+        title: '是否中奖',
+        dataIndex: 'stateDictValue',
+        width: 200,
+        align: 'center'
+      }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        const searchData = Object.assign(parameter, this.queryParam)
+        if (this.time && this.time.length) {
+          searchData.beginDate = moment(this.time[0]).format('YYYY-MM-DD 00:00:00')
+          searchData.endDate = moment(this.time[1]).format('YYYY-MM-DD 23:59:59')
+        } else {
+          searchData.beginDate = ''
+          searchData.endDate = ''
+        }
+        return getLuckyWinList(searchData).then(res => {
+          if (res.status == 200) {
+            const no = (res.data.pageNo - 1) * res.data.pageSize
+            for (let i = 0; i < res.data.list.length; i++) {
+              const _item = res.data.list[i]
+              _item.no = no + i + 1
+              _item.status = _item.status + '' === '1'
+            }
+            return res.data
+          }
+        })
+      },
+      // 将默认当天时间日期回显在时间选择框中  抽奖时间
+      time: [],
+      dateFormat: 'YYYY-MM-DD'
+    }
+  },
+  methods: {
+    moment,
+    // 不可选日期
+    disabledDate (date, dateStrings) {
+      return date && date.valueOf() > Date.now()
+    },
+    // 创建时间change
+    onChange (dates, dateStrings) {
+      if ((dates, dateStrings)) {
+        this.queryParam.beginDate = dateStrings[0]
+        this.queryParam.endDate = dateStrings[1]
+      }
+    },
+    // 重置
+    handleReset () {
+      this.queryParam.beginDate = null
+      this.queryParam.endDate = null
+      this.time = []
+      this.queryParam.customerMobile = ''
+      this.queryParam.activeName = ''
+      this.$refs.table.refresh(true)
+    },
+    // 导出
+    handleExport () {
+      const params = this.queryParam
+      if (this.time && this.time.length) {
+        params.beginDate = moment(this.time[0]).format('YYYY-MM-DD 00:00:00')
+        params.endDate = moment(this.time[1]).format('YYYY-MM-DD 23:59:59')
+      } else {
+        params.beginDate = ''
+        params.endDate = ''
+      }
+      if (!params.beginDate && !params.endDate) {
+        this.$message.error('请先选择需要导出的抽奖时间区间再进行导出!')
+        return
+      }
+      // 判断两个时间段是否相差m个月  第二个参数指相差单位,第三个参数指是否返回浮点形式(小数)
+      if (moment(params.endDate).diff(moment(params.beginDate), 'months', true) > 3) {
+        this.$message.error('单次最多只能导出3个月的数据,请缩小查询区间后再进行导出!')
+        return
+      }
+      this.$confirm({
+        title: '提示',
+        content: '导出过程可能需要一段时间,且导出期间不可进行其他操作,确认要导出吗?',
+        onOk: () => {
+          this.loading = true
+          // exportLuckyDrawWin(params).then(res => {
+          //   this.loading = false
+          //   this.download(res)
+          // })
+        },
+        onCancel () {}
+      })
+    },
+    download (data) {
+      if (!data) {
+        return
+      }
+      const url = window.URL.createObjectURL(new Blob([data]))
+      const link = document.createElement('a')
+      link.style.display = 'none'
+      link.href = url
+      // const a = moment().format('YYYY-MM-DD')
+      const a = moment(this.queryParam.beginDate).format('LL') + '-' + moment(this.queryParam.endDate).format('LL')
+      console.log(a)
+      const fname = a + '抽奖记录表'
+      link.setAttribute('download', fname + '.xlsx')
+      document.body.appendChild(link)
+      link.click()
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+	.luckDrawRecord-table-page-search-wrapper {
+		.luckDrawRecord-searchForm {
+			.ant-form-inline .ant-form-item {
+				width: 100%;
+			}
+
+			// 搜索框的下间距
+			.ant-form-item {
+				margin-bottom: 10px;
+			}
+
+			.handle-btn {
+				margin-top: 4px;
+				margin-bottom: 20px;
+			}
+
+			.serach-btn {
+				margin-right: 10px;
+			}
+		}
+
+		.export-btn {
+			background-color: #ff9900;
+			border-color: #ff9900;
+			color: #fff;
+		}
+
+		.export-btn.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),
+		.export-btn.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger) {
+			color: #fff;
+			border-color: #ff9900;
+		}
+	}
+</style>

+ 43 - 34
src/views/releaseRecord/releaseRecordList.vue

@@ -2,8 +2,8 @@
   <a-card :bordered="false" class="shopOrder-table-page-search-wrapper">
     <div class="shopOrder-searchForm">
       <a-form layout="inline" @keyup.enter.native="refresh">
-        <a-row :gutter="20">
-          <a-col :span="5">
+        <a-row :gutter="24">
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
             <a-form-item label="投放时间:" :label-col="{ span: 7 }" :wrapper-col="{ span: 17}">
               <a-range-picker
                 style="width:100%"
@@ -14,17 +14,17 @@
                 :placeholder="['开始时间', '结束时间']" />
             </a-form-item>
           </a-col>
-          <a-col :span="5">
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
             <a-form-item label="用户账号" :label-col="{ span:7 }" :wrapper-col="{ span:17}">
               <a-input id="releaseRecordList-customerMobile" allowClear :maxLength="11" v-model=" queryParam.customerMobile" placeholder="请输入用户账号" />
             </a-form-item>
           </a-col>
-          <a-col :span="5">
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
             <a-form-item label="投放类型" :label-col="{ span:7 }" :wrapper-col="{ span:17}">
               <v-select code="RUBBISH_TYPE" v-model="queryParam.rubbishType" allowClear placeholder="请选择投放类型" id="releaseRecordList-rubbishType"></v-select>
             </a-form-item>
           </a-col>
-          <a-col :span="5">
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
             <a-form-item label="兑换乐豆" :label-col="{ span:7 }" :wrapper-col="{ span:17}">
               <div class="input-number">
                 <a-input-number id="releaseRecordList-inputNumber" v-model="queryParam.goldNumStart" :max="999999999" @change="onChange" />-
@@ -32,19 +32,19 @@
               </div>
             </a-form-item>
           </a-col>
-          <a-col :span="4">
-            <a-button class="handle-btn serach-btn" id="releaseRecordList-serach" type="primary" @click="refresh">查询</a-button>
-            <a-button class="handle-btn serach-btn" type="" id="releaseRecordList-reset" @click="handleReset">重置</a-button>
-            <a-button class="export-btn" id="releaseRecordList-export" v-hasPermission="'B_exportDeliveryLog'" :loading="loading" @click="handleExport">导出</a-button>
+          <a-col :xs="24" :sm="12" :md="8" :lg="4">
+            <a-form-item label="设备类型" :label-col="{ span:7 }" :wrapper-col="{ span:17}">
+              <v-select code="DEVICE_TYPE" v-model="queryParam.deviceType" allowClear placeholder="请选择设备类型" id="releaseRecordList-deviceType"></v-select>
+            </a-form-item>
           </a-col>
         </a-row>
-        <a-row :gutter="20">
-          <a-col :span="5">
+        <a-row :gutter="24">
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
             <a-form-item label="设备编号" :label-col="{ span:7 }" :wrapper-col="{ span:17}">
               <a-input id="releaseRecordList-srcDeviceCode" allowClear :maxLength="120" v-model=" queryParam.srcDeviceCode " placeholder="请输入设备编号" />
             </a-form-item>
           </a-col>
-          <a-col :span="5">
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
             <a-form-item label="网点名称" :label-col="{ span:7 }" :wrapper-col="{ span:17}">
               <a-select
                 id="releaseRecordList-stationNo"
@@ -59,12 +59,12 @@
               </a-select>
             </a-form-item>
           </a-col>
-          <a-col :span="5">
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
             <a-form-item label="投放方式" :label-col="{ span:7 }" :wrapper-col="{ span:17}">
               <v-select code="DELIVERY_WAY" v-model="queryParam.deliveryWay" allowClear placeholder="请选择投放方式" id="releaseRecordList-deliveryWay"></v-select>
             </a-form-item>
           </a-col>
-          <a-col :span="5">
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
             <a-form-item label="投放重量" :label-col="{ span:7 }" :wrapper-col="{ span:17}">
               <div class="input-number">
                 <a-input-number id="releaseRecordList-inputNumber" v-model="queryParam.rubbishWeightStart" :max="999999999" @change="onChange" />-
@@ -72,9 +72,11 @@
               </div>
             </a-form-item>
           </a-col>
-          <!-- <a-col :span="4">
+          <a-col :xs="24" :sm="12" :md="8" :lg="4">
+            <a-button class="handle-btn serach-btn" id="releaseRecordList-serach" type="primary" @click="refresh">查询</a-button>
+            <a-button class="handle-btn serach-btn" type="" id="releaseRecordList-reset" @click="handleReset">重置</a-button>
             <a-button class="export-btn" id="releaseRecordList-export" v-hasPermission="'B_exportDeliveryLog'" :loading="loading" @click="handleExport">导出</a-button>
-          </a-col> -->
+          </a-col>
         </a-row>
       </a-form>
     </div>
@@ -155,7 +157,7 @@ export default {
         customerMobile: '', //  用户手机
         srcDeviceCode: '', //  设备编号
         stationNo: undefined, // 网点名称
-        rubbishType: '', // 投放类型
+        deviceType: '', // 设备类型
         deliveryWay: '', // 投放方式
         goldNumStart: null, // 兑换最小值
         goldNumEnd: null, // 兑换最大值
@@ -171,6 +173,7 @@ export default {
         { title: '投放时间', dataIndex: 'deliveryTime', width: 200, align: 'center' },
         { title: '网点名称', dataIndex: 'stationName', width: 200, align: 'center' },
         { title: '设备编号', dataIndex: 'srcDeviceCode', width: 200, align: 'center' },
+        { title: '设备类型', dataIndex: 'deviceTypeDictValue', width: 200, align: 'center' },
         { title: '用户账号', dataIndex: 'customerMobile', width: 200, align: 'center' },
         { title: '投放方式', dataIndex: 'deliveryWayDictValue', width: 200, align: 'center' },
         { title: '本次兑换乐豆(个)', dataIndex: 'goldNum', width: 100, align: 'center' },
@@ -186,7 +189,6 @@ export default {
             { title: '可回收物', width: 100, align: 'center', scopedSlots: { customRender: 'eight' } }
           ]
         }
-
       ],
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
@@ -214,10 +216,29 @@ export default {
   },
   beforeRouteEnter (to, from, next) {
     next(vm => {
-      vm.handleReset()
-      vm.getStationList()
+      vm.queryOrderDate = [
+        moment(getDate.getRecentday().starttime, vm.dateFormat),
+        moment(getDate.getRecentday().endtime, vm.dateFormat)
+      ],
+      // 查询参数
+      vm.queryParam = {
+        beginDate: null, // 开始时间
+        endDate: null, // 结束时间
+        customerMobile: '', //  用户手机
+        srcDeviceCode: '', //  设备编号
+        stationNo: undefined, // 网点名称
+        deviceType: '', // 设备类型
+        deliveryWay: '', // 投放方式
+        goldNumStart: null, // 兑换最小值
+        goldNumEnd: null, // 兑换最大值
+        rubbishWeightStart: null, // 投放重量最小值
+        rubbishWeightEnd: null// 投放重量最小值
+      }
     })
   },
+  mounted () {
+    this.getStationList()
+  },
   methods: {
     moment,
     // 不可选日期
@@ -306,19 +327,7 @@ export default {
     },
     // 合计
     getListTotal () {
-      const params = {
-        customerMobile: this.queryParam.customerMobile,
-        beginDate: this.queryParam.beginDate,
-        endDate: this.queryParam.endDate,
-        srcDeviceCode: this.queryParam.srcDeviceCode, //  设备编号
-        stationNo: this.queryParam.stationNo, // 网点名称
-        goldNumStart: this.queryParam.goldNumStart, // 兑换最小值
-        goldNumEnd: this.queryParam.goldNumEnd, // 兑换最大值
-        rubbishWeightStart: this.queryParam.rubbishWeightStart, // 投放重量最小值
-        rubbishWeightEnd: this.queryParam.rubbishWeightEnd,
-        rubbishType: this.queryParam.rubbishType, // 投放类型
-        deliveryWay: this.queryParam.deliveryWay // 投放方式
-      }
+	  const params = this.queryParam
       if (this.queryOrderDate && this.queryOrderDate.length) {
         params.beginDate = moment(this.queryOrderDate[0]).format('YYYY-MM-DD')
         params.endDate = moment(this.queryOrderDate[1]).format('YYYY-MM-DD')
@@ -347,7 +356,7 @@ export default {
       this.queryParam.customerMobile = ''
       this.queryParam.srcDeviceCode = ''
       this.queryParam.stationNo = undefined
-      this.queryParam.rubbishType = '' // 投放类型
+      this.queryParam.deviceType = '' // 设备类型
       this.queryParam.goldNumStart = '' // 兑换最小值
       this.queryParam.goldNumEnd = '' // 兑换最大值
       this.queryParam.rubbishWeightStart = ''// 投放重量最小值

+ 235 - 0
src/views/userInfo/allLdDetail.vue

@@ -0,0 +1,235 @@
+<template>
+  <a-card :bordered="false" class="allLdDetail-page-info">
+    <!-- 搜索条件 -->
+    <div class="allLdDetail-searchForm">
+      <a-form layout="inline" v-bind="formItemLayout" @keyup.enter.native="refresh">
+        <a-row :gutter="24">
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
+            <a-form-item label="创建时间" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-range-picker
+                id="allLdDetail-time"
+                v-model="time"
+                style="width: 100%;"
+                :format="dateFormat"
+                :placeholder="['开始时间','结束时间']"
+                :disabledDate="disabledDate"
+                @change="onChange" />
+            </a-form-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
+            <a-form-item label="变动类型" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <v-select
+                v-model="queryParam.changeType"
+                ref="changeType"
+                id="allLdDetail-status"
+                code="GOLD_CHANGE_TYPE"
+                placeholder="请选择"
+                allowClear></v-select>
+            </a-form-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
+            <a-form-item label="变动原因" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <v-select
+                v-model="queryParam.operateType"
+                ref="operateType"
+                id="allLdDetail-status"
+                code="GOLD_OPERATE_TYPE_ALL"
+                placeholder="请选择"
+                allowClear></v-select>
+            </a-form-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="8" :lg="5">
+            <a-form-item label="用户手机" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
+              <a-input id="allLdDetail-customerMobile" allowClear :maxLength="11" v-model="queryParam.customerMobile" placeholder="请输入用户手机" />
+            </a-form-item>
+          </a-col>
+          <a-col :xs="24" :sm="12" :md="8" :lg="4">
+            <a-button class="handle-btn serach-btn" id="allLdDetail-btn-serach" type="primary" @click="refresh">查询</a-button>
+            <a-button class="handle-btn" type="" id="allLdDetail-btn-reset" @click="handleReset">重置</a-button>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 总计 -->
+    <a-alert type="info" showIcon style="margin-bottom:15px">
+      <div class="ftext" slot="message">共<span> {{ total }} </span>条,乐豆变动总计<span> {{ ldChangeNum }} </span>个</div>
+    </a-alert>
+    <!-- 列表 -->
+    <s-table
+      ref="table"
+      size="default"
+      :rowKey="(record) => record.id"
+      :columns="columns"
+      :data="loadData"
+      bordered>
+    </s-table>
+  </a-card>
+</template>
+
+<script>
+import { STable, VSelect } from '@/components'
+import { offPartnerGoldLog, getStatistic } from '@/api/userInfo.js'
+import moment from 'moment'
+import getDate from '@/libs/getDate.js'
+export default {
+  name: 'AllLdDetail',
+  components: { STable, VSelect },
+  data () {
+    return {
+      formItemLayout: {
+        labelCol: { span: 7 },
+        wrapperCol: { span: 17 }
+      },
+      // 将默认近七天时间日期回显在时间选择框中
+      time: [
+        moment(getDate.getRecentday().starttime, this.dateFormat),
+        moment(getDate.getRecentday().endtime, this.dateFormat)
+      ],
+      total: 0, // 总条数
+      ldChangeNum: 0, // 乐豆变动量总计
+      dateFormat: 'YYYY-MM-DD',
+      // 查询参数
+      queryParam: {
+        beginDate: null, // 开始时间
+        endDate: null, // 结束时间
+        customerMobile: '', // 用户手机
+        changeType: '', // 类型
+        operateType: '' // 原因
+      },
+      // 表头
+      columns: [
+        { title: '序号', dataIndex: 'no', width: 60, align: 'center' },
+        { title: '创建时间', dataIndex: 'createDate', width: 200, align: 'center' },
+        { title: '用户手机', dataIndex: 'customerMobile', width: 200, align: 'center', customRender: (text) => { return text || '--' } },
+        { title: '变动类型', dataIndex: 'changeTypeDictValue', width: 200, align: 'center' },
+        { title: '变动原因', dataIndex: 'operateTypeDictValue', width: 200, align: 'center' },
+        { title: '乐豆变动量(个)', dataIndex: 'changeNum', width: 200, align: 'center' }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        const searchData = Object.assign(parameter, this.queryParam)
+        if (this.time && this.time.length) {
+          searchData.beginDate = moment(this.time[0]).format('YYYY-MM-DD')
+          searchData.endDate = moment(this.time[1]).format('YYYY-MM-DD')
+        } else {
+          searchData.beginDate = null
+          searchData.endDate = null
+        }
+        return offPartnerGoldLog(Object.assign(parameter, searchData)).then(res => {
+          if (res.status == 200) {
+            const no = (res.data.pageNo - 1) * res.data.pageSize
+            for (let i = 0; i < res.data.list.length; i++) {
+              const _item = res.data.list[i]
+              _item.no = no + i + 1
+            }
+            // 总条数
+            this.total = res.data.count
+            return res.data
+          } else {
+            this.total = 0
+          }
+        })
+      }
+    }
+  },
+  methods: {
+    // 不可选日期
+    disabledDate (date, dateStrings) {
+      return date && date.valueOf() > Date.now()
+    },
+    // 创建时间change
+    onChange (dates, dateStrings) {
+      if ((dates, dateStrings)) {
+        this.queryParam.beginDate = dateStrings[0]
+        this.queryParam.endDate = dateStrings[1]
+      }
+    },
+    // 查询
+    refresh () {
+      this.$refs.table.refresh(true)
+      this.getTotal()
+    },
+    // 重置
+    handleReset () {
+      this.time = [
+        moment(getDate.getRecentday().starttime, this.dateFormat),
+        moment(getDate.getRecentday().endtime, this.dateFormat)
+      ]
+      this.queryParam = {
+        beginDate: null, // 开始时间
+        endDate: null, // 结束时间
+        customerMobile: '', // 用户手机
+        changeType: '', // 类型
+        operateType: '' // 原因
+      }
+      this.$refs.table.refresh(true)
+      this.getTotal()
+    },
+    // 总计
+    getTotal () {
+      const params = this.queryParam
+      if (this.time && this.time.length) {
+        params.beginDate = moment(this.time[0]).format('YYYY-MM-DD')
+        params.endDate = moment(this.time[1]).format('YYYY-MM-DD')
+      } else {
+        params.beginDate = null
+        params.endDate = null
+      }
+      getStatistic(params).then(res => {
+        if (res.status == 200) {
+          this.ldChangeNum = res.data || 0
+        } else {
+          this.ldChangeNum = 0
+        }
+      })
+    }
+  },
+  mounted () {
+    this.getTotal()
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {
+      vm.time = [
+        moment(getDate.getRecentday().starttime, vm.dateFormat),
+        moment(getDate.getRecentday().endtime, vm.dateFormat)
+      ]
+      vm.queryParam = {
+        beginDate: null, // 开始时间
+        endDate: null, // 结束时间
+        customerMobile: '', // 用户手机
+        changeType: '', // 类型
+        operateType: '' // 原因
+      }
+    })
+  }
+}
+</script>
+<style lang="less" scoped>
+	.allLdDetail-page-info{
+		.page-header{
+			margin-bottom: 15px;
+			span{
+				margin-left: 20px;
+			}
+			.page-header-info{
+				margin-left:0;
+				font-weight: bold;
+			}
+		}
+    .allLdDetail-searchForm{
+      .ant-form-inline .ant-form-item{
+        width: 100%;
+      }
+      // 搜索框的下间距
+      .ant-form-item {
+      	margin-bottom: 15px;
+      }
+      .handle-btn{
+        margin-top: 4px;
+      }
+      .serach-btn{
+        margin-right: 10px;
+      }
+    }
+  }
+</style>

+ 1 - 1
vue.config.js

@@ -108,7 +108,7 @@ const vueConfig = {
     // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
     proxy: {
       '/api': {
-        // target: 'http://192.168.16.149:8301/gc-admin/',
+        // target: 'http://192.168.16.102:8301/gc-admin/',
         target: 'https://lese.test.sxzxyj.net/gc-admin/',
         ws: false,
         changeOrigin: true,