xsh před 1 rokem
rodič
revize
881b316d45

+ 75 - 0
src/api/admin/dashboard/index.js

@@ -0,0 +1,75 @@
+import utils from '@/utils/lib'
+
+const Query1 = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminDashboardQuerySelfRes = data => {
+      utils.SockEventMap.adminDashboardQuerySelfRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminDashboardQuerySelf', query)
+  })
+}
+
+const Query2 = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminDashboardRankDevicesRes = data => {
+      utils.SockEventMap.adminDashboardRankDevicesRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminDashboardRankDevices', query)
+  })
+}
+
+const Query2Detail = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminDashboardQueryDeviceRes = data => {
+      utils.SockEventMap.adminDashboardQueryDeviceRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminDashboardQueryDevice', query)
+  })
+}
+
+const Query3 = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminDashboardRankWinesRes = data => {
+      utils.SockEventMap.adminDashboardRankWinesRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminDashboardRankWines', query)
+  })
+}
+
+const Query3Detail = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminDashboardQueryWineRes = data => {
+      utils.SockEventMap.adminDashboardQueryWineRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminDashboardQueryWine', query)
+  })
+}
+
+const Query4 = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminDashboardRankWorkersRes = data => {
+      utils.SockEventMap.adminDashboardRankWorkersRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminDashboardRankWorkers', query)
+  })
+}
+
+const Query4Detail = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminDashboardQueryWorkerRes = data => {
+      utils.SockEventMap.adminDashboardQueryWorkerRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminDashboardQueryWorker', query)
+  })
+}
+
+export default {
+  Query1, Query2, Query2Detail, Query3, Query3Detail, Query4, Query4Detail
+}

+ 40 - 0
src/api/admin/trade.js

@@ -0,0 +1,40 @@
+import utils from '@/utils/lib'
+
+const QueryUser = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminTradeQueryUserRes = data => {
+      utils.SockEventMap.adminTradeQueryUserRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminTradeQueryUser', query)
+  })
+}
+
+const Query = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminTradeQueryTradeRes = data => {
+      utils.SockEventMap.adminTradeQueryTradeRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminTradeQueryTrade', query)
+  })
+}
+
+const Refund = info => {
+  return new Promise((resolve, reject) => {
+    utils.SockEventMap.adminTradeRefundRes = data => {
+      utils.SockEventMap.adminTradeRefundRes = undefined
+      if (data.status) {
+        resolve()
+      } else {
+        reject(data.msg)
+      }
+    }
+    utils.SendWss('adminTradeRefund', info)
+  })
+}
+
+export default {
+  QueryUser, Query, Refund
+}
+

+ 45 - 0
src/api/admin/wine/change.js

@@ -0,0 +1,45 @@
+import utils from '@/utils/lib'
+
+const Query = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminWineChangeQueryRes = data => {
+      utils.SockEventMap.adminWineChangeQueryRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminWineChangeQuery', query)
+  })
+}
+
+const QueryWine = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminWineChangeQueryWineRes = data => {
+      utils.SockEventMap.adminWineChangeQueryWineRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminWineChangeQueryWine', query)
+  })
+}
+
+const QueryWorker = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminWineChangeQueryWorkerRes = data => {
+      utils.SockEventMap.adminWineChangeQueryWorkerRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminWineChangeQueryWorker', query)
+  })
+}
+
+const Assign = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminWineChangeAssignRes = data => {
+      utils.SockEventMap.adminWineChangeAssignRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminWineChangeAssign', query)
+  })
+}
+
+export default {
+  Query, QueryWine, QueryWorker, Assign
+}

+ 54 - 0
src/api/admin/wine/history.js

@@ -0,0 +1,54 @@
+import utils from '@/utils/lib'
+
+const QueryWorker = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminWineHistoryQueryWorkerRes = data => {
+      utils.SockEventMap.adminWineHistoryQueryWorkerRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminWineHistoryQueryWorker', query)
+  })
+}
+
+const QueryOrder = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminWineHistoryQueryOrderRes = data => {
+      utils.SockEventMap.adminWineHistoryQueryOrderRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminWineHistoryQueryOrder', query)
+  })
+}
+
+const UpdateOrder = info => {
+  return new Promise((resolve, reject) => {
+    utils.SockEventMap.adminWineHistoryOrderUpdateRes = data => {
+      utils.SockEventMap.adminWineHistoryOrderUpdateRes = undefined
+      if (data.status) {
+        resolve()
+      } else {
+        reject(data.msg)
+      }
+    }
+    utils.SendWss('adminWineHistoryOrderUpdate', info)
+  })
+}
+
+const Delete = info => {
+  return new Promise((resolve, reject) => {
+    utils.SockEventMap.adminWineHistoryOrderDeleteRes = data => {
+      utils.SockEventMap.adminWineHistoryOrderDeleteRes = undefined
+      if (data.status) {
+        resolve()
+      } else {
+        reject(data.msg)
+      }
+    }
+    utils.SendWss('adminWineHistoryOrderDelete', info)
+  })
+}
+
+export default {
+  QueryWorker, QueryOrder, UpdateOrder, Delete
+}
+

+ 54 - 0
src/api/admin/worker.js

@@ -0,0 +1,54 @@
+import utils from '@/utils/lib'
+
+const Query = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminWorkerQueryRes = data => {
+      utils.SockEventMap.adminWorkerQueryRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminWorkerQuery', query)
+  })
+}
+
+const Update = info => {
+  return new Promise((resolve, reject) => {
+    utils.SockEventMap.adminWorkerUpdateRes = data => {
+      utils.SockEventMap.adminWorkerUpdateRes = undefined
+      if (data.status) {
+        resolve()
+      } else {
+        reject(data.msg)
+      }
+    }
+    utils.SendWss('adminWorkerUpdate', info)
+  })
+}
+
+const Delete = ids => {
+  return new Promise(resolve => {
+    utils.SockEventMap.adminWorkerDeleteRes = data => {
+      utils.SockEventMap.adminWorkerDeleteRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('adminWorkerDelete', ids)
+  })
+}
+
+const Add = info => {
+  return new Promise((resolve, reject) => {
+    utils.SockEventMap.adminWorkerAddRes = data => {
+      utils.SockEventMap.adminWorkerAddRes = undefined
+      if (data.status) {
+        resolve()
+      } else {
+        reject(data.msg)
+      }
+    }
+    utils.SendWss('adminWorkerAdd', info)
+  })
+}
+
+export default {
+  Query, Update, Delete, Add
+}
+

+ 91 - 0
src/api/super/dashboard/index.js

@@ -0,0 +1,91 @@
+import utils from '@/utils/lib'
+
+const Query1 = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.superDashboardRankAdminsRes = data => {
+      utils.SockEventMap.superDashboardRankAdminsRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('superDashboardRankAdmins', query)
+  })
+}
+const QueryDetail = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.superDashboardQueryAdminRes = data => {
+      utils.SockEventMap.superDashboardQueryAdminRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('superDashboardQueryAdmin', query)
+  })
+}
+
+const Query2 = info => {
+  return new Promise((resolve, reject) => {
+    utils.SockEventMap.superDashboardRankDevicesRes = data => {
+      utils.SockEventMap.superDashboardRankDevicesRes = undefined
+      if (data.status) {
+        resolve(data)
+      } else {
+        reject(data.msg)
+      }
+    }
+    utils.SendWss('superDashboardRankDevices', info)
+  })
+}
+const Query2Detail = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.superDashboardQueryDeviceRes = data => {
+      utils.SockEventMap.superDashboardQueryDeviceRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('superDashboardQueryDevice', query)
+  })
+}
+
+const Query3 = ids => {
+  return new Promise(resolve => {
+    utils.SockEventMap.superDashboardRankWinesRes = data => {
+      utils.SockEventMap.superDashboardRankWinesRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('superDashboardRankWines', ids)
+  })
+}
+
+const Query3Detail = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.superDashboardQueryWineRes = data => {
+      utils.SockEventMap.superDashboardQueryWineRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('superDashboardQueryWine', query)
+  })
+}
+
+const Query4 = info => {
+  return new Promise((resolve, reject) => {
+    utils.SockEventMap.superDashboardRankWorkersRes = data => {
+      utils.SockEventMap.superDashboardRankWorkersRes = undefined
+      if (data.status) {
+        resolve(data)
+      } else {
+        reject(data.msg)
+      }
+    }
+    utils.SendWss('superDashboardRankWorkers', info)
+  })
+}
+
+const Query4Detail = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.superDashboardQueryWorkerRes = data => {
+      utils.SockEventMap.superDashboardQueryWorkerRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('superDashboardQueryWorker', query)
+  })
+}
+
+export default {
+  Query1, QueryDetail, Query2, Query2Detail, Query3, Query3Detail, Query4, Query4Detail
+}

+ 40 - 0
src/api/super/order/trade.js

@@ -0,0 +1,40 @@
+import utils from '@/utils/lib'
+
+const QueryUser = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.superOrderTradeQueryUserRes = data => {
+      utils.SockEventMap.superOrderTradeQueryUserRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('superOrderTradeQueryUser', query)
+  })
+}
+
+const Query = query => {
+  return new Promise(resolve => {
+    utils.SockEventMap.superOrderTradeQueryTradeRes = data => {
+      utils.SockEventMap.superOrderTradeQueryTradeRes = undefined
+      resolve(data)
+    }
+    utils.SendWss('superOrderTradeQueryTrade', query)
+  })
+}
+
+const Refund = info => {
+  return new Promise((resolve, reject) => {
+    utils.SockEventMap.superOrderTradeRefundRes = data => {
+      utils.SockEventMap.superOrderTradeRefundRes = undefined
+      if (data.status) {
+        resolve()
+      } else {
+        reject(data.msg)
+      }
+    }
+    utils.SendWss('superOrderTradeRefund', info)
+  })
+}
+
+export default {
+  QueryUser, Query, Refund
+}
+

+ 13 - 4
src/utils/index.js

@@ -365,9 +365,18 @@ export function videoToBase64(file) {
 // 数字变成时分秒
 export function convertSeconds(val) {
   // 转换为小时、分钟和秒
-  var hours = Math.floor(val / 3600)
-  var minutes = Math.floor((val % 3600) / 60)
-  var seconds = val % 60
-  var result = hours + '小时 ' + minutes + '分钟 ' + seconds + '秒'
+  const hours = Math.floor(val / 3600)
+  const minutes = Math.floor((val % 3600) / 60)
+  const seconds = val % 60
+  const result = hours + '小时 ' + minutes + '分钟 ' + seconds + '秒'
   return result
 }
+
+// 时间格式化
+export function timeDate(timestamp) {
+  const date = new Date(timestamp)
+  const Y = date.getFullYear() + '-'
+  const M = (date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) + '-' : (date.getMonth() + 1) + '-'
+  const D = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
+  return Y + M + D
+}

+ 28 - 2
src/views/about/index.vue

@@ -1,5 +1,25 @@
 <template>
-  <div>about us index</div>
+  <div class="box">
+    <h3>关于我们</h3>
+    <div class="padding-left">欢迎来到智能散酒销售后台管理的关于页面! 我们为您介绍我们的使命、价值观以及团队,让您更好地了解我们所追求的目标和为之努力的价值。</div>
+    <h3>使命</h3>
+    <div class="padding-left">我们的使命是通过创新科技和智能系统,为散酒销售行业提供高效、智能的后台管理解决方案,协助企业提升销售效率、降低成本,并实现可持续发展。</div>
+    <h3>愿景</h3>
+    <div class="padding-left">我们的愿景是成为散酒销售行业中最受信赖、最具创新力的后台管理系统提供商,通过技术的力量,推动行业发展,为客户创造更大价值。</div>
+    <h3>价值观</h3>
+    <div class="padding-left">1.创新领先:我们秉承技术创新,不断研发出更智能、更高效的解决方案,引领行业发展的潮流。</div>
+    <div class="padding-left">2.客户至上:客户是我们的核心,我们不仅致力于满足他们的需求,更努力超越期望,为他们创造出色的体验。</div>
+    <div class="padding-left">3.合作共赢: 我们坚信合作是实现共赢的关键,与客户、合作伙伴紧密合作,共同成长,共同成功。</div>
+    <div class="padding-left">4.品质保障:我们严格把控产品品质,从系统设计到用户体验,始终如一地追求点越。</div>
+    <div class="padding-left">5.社会责任:我们关注环境保护和社会责任,致力于推动可持续发展,为社会创造更大的正面影响。</div>
+    <h3>团队</h3>
+    <div class="padding-left">我们的团队由来自技术、销售、市场等多个领域的专业人土组成。他们在各自领域拥有丰富的经验和深厚的知识,致力于为您提供最佳的后台管理解决方案感谢您选择我们的智能散酒销售后台管理系统。如果您有任何问题、建议或合作意向,欢迎随时联系我们。我们期待与您携手,共创更美好的未来</div>
+    <h3>联系方式</h3>
+    <div class="padding-left">地址:xxxx</div>
+    <div class="padding-left">电话:xxxx</div>
+    <div class="padding-left">邮箱:xxxx</div>
+    <div class="padding-left">官方网站:xxxx</div>
+  </div>
 </template>
 
 <script>
@@ -9,5 +29,11 @@ export default {
 </script>
 
 <style scoped>
-
+  .box {
+    box-sizing: border-box;
+    padding: 20px;
+  }
+  .padding-left {
+    padding-left: 20px;
+  }
 </style>

+ 328 - 3
src/views/admin/dashboard/index.vue

@@ -1,13 +1,338 @@
 <template>
-  <div>admin dashboard index</div>
+  <div>
+    <el-row :gutter="20">
+      <el-col :span="12">
+        <el-card header="自身业绩">
+          <el-form inline>
+            <el-form-item label="日期">
+              <el-select v-model="type1">
+                <el-option label="不限" :value="0" />
+                <el-option label="一周" :value="1" />
+                <el-option label="一月" :value="2" />
+                <el-option label="一季" :value="3" />
+                <el-option label="半年" :value="4" />
+                <el-option label="一年" :value="5" />
+              </el-select>
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="search1">查询</el-button>
+            </el-form-item>
+          </el-form>
+          <div class="chart_content">
+            <chart-lines v-if="list1.length > 0" :id="0" :list="list1" />
+            <div style="line-height: 400px; text-align: center">暂无数据</div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card header="贩卖机业绩">
+          <el-form inline>
+            <el-form-item label="日期">
+              <el-date-picker
+                v-model="dateTime2"
+                type="daterange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                format="YYYY-MM-dd"
+                value-format="YYYY-MM-dd"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="search2">查询</el-button>
+            </el-form-item>
+          </el-form>
+          <div class="chart_content">
+            <chart-device v-if="list2.length > 0" :id="0" :item="{ unit: '', list: list2 }" @onClick="handlerDevice" />
+            <div style="line-height: 400px; text-align: center">暂无数据</div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="12" style="margin-top: 20px">
+        <el-card header="酒品业绩">
+          <el-form inline>
+            <el-form-item label="日期">
+              <el-date-picker
+                v-model="dateTime3"
+                type="daterange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                format="YYYY-MM-dd"
+                value-format="YYYY-MM-dd"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="search3">查询</el-button>
+            </el-form-item>
+          </el-form>
+          <div class="chart_content">
+            <chart-wine v-if="list3.length > 0" :id="2" :item="{ unit: '', list: list3 } " @onClick="handlerWine" />
+            <div style="line-height: 400px; text-align: center">暂无数据</div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="12" style="margin-top: 20px">
+        <el-card header="上酒工业绩">
+          <el-form inline>
+            <el-form-item label="日期">
+              <el-date-picker
+                v-model="dateTime4"
+                type="daterange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                format="YYYY-MM-dd"
+                value-format="YYYY-MM-dd"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="search4">查询</el-button>
+            </el-form-item>
+          </el-form>
+          <div class="chart_content">
+            <chart-worker v-if="list4.length > 0" :id="4" :item="{ unit: '次', list: list4 } " @onClick="handlerWorker" />
+            <div style="line-height: 400px; text-align: center">暂无数据</div>
+            <!--            <chart-pie :id="4" :item="{ unit: '', list: list4 } " @onClick="handlerWorker"></chart-pie>-->
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+    <el-dialog
+      width="60%"
+      :visible.sync="showDevice"
+      :close-on-click-modal="false"
+      title="贩卖机业绩详情"
+      @close="reset"
+    >
+      <el-form inline>
+        <el-form-item>
+          <el-select v-model="type">
+            <el-option label="不限" :value="0" />
+            <el-option label="一周" :value="1" />
+            <el-option label="一月" :value="2" />
+            <el-option label="一季" :value="3" />
+            <el-option label="半年" :value="4" />
+            <el-option label="一年" :value="5" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="queryDetail2">查询</el-button>
+        </el-form-item>
+      </el-form>
+      <div class="chart_page">
+        <chart-line :id="1" :list="detailList2" />
+      </div>
+    </el-dialog>
+    <el-dialog
+      width="60%"
+      :visible.sync="showWine"
+      :close-on-click-modal="false"
+      title="酒品业绩详情"
+      @close="reset"
+    >
+      <el-form inline>
+        <el-form-item>
+          <el-select v-model="type">
+            <el-option label="不限" :value="0" />
+            <el-option label="一周" :value="1" />
+            <el-option label="一月" :value="2" />
+            <el-option label="一季" :value="3" />
+            <el-option label="半年" :value="4" />
+            <el-option label="一年" :value="5" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="queryDetail3">查询</el-button>
+        </el-form-item>
+      </el-form>
+      <div class="chart_page">
+        <chart-line :id="2" :list="detailList3" />
+      </div>
+    </el-dialog>
+    <el-dialog
+      width="60%"
+      :visible.sync="showWorker"
+      :close-on-click-modal="false"
+      title="上酒工业绩详情"
+      @close="reset"
+    >
+      <el-form inline>
+        <el-form-item>
+          <el-select v-model="type">
+            <el-option label="不限" :value="0" />
+            <el-option label="一周" :value="1" />
+            <el-option label="一月" :value="2" />
+            <el-option label="一季" :value="3" />
+            <el-option label="半年" :value="4" />
+            <el-option label="一年" :value="5" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="queryDetail4">查询</el-button>
+        </el-form-item>
+      </el-form>
+      <div class="chart_page">
+        <ChartWokerLine :id="3" :list="detailList4" />
+      </div>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
+
+import api from '@/api/admin/dashboard/index'
+import { timeDate } from '@/utils/index'
+import ChartLine from '@/views/super/dashboard/chart/ChartLine'
+import ChartLines from '@/views/super/dashboard/chart/ChartLines'
+import ChartDevice from '@/views/super/dashboard/chart/ChartDevice'
+import ChartWorker from '@/views/super/dashboard/chart/ChartWorker'
+import ChartWine from '@/views/super/dashboard/chart/ChartWine'
+import ChartWokerLine from '@/views/super/dashboard/chart/ChartWokerLine'
 export default {
-  name: 'AdminDashboard'
+  name: 'AdminDashboard',
+  components: {
+    ChartLine,
+    ChartLines,
+    ChartDevice,
+    ChartWorker,
+    ChartWine,
+    ChartWokerLine
+  },
+  data() {
+    return {
+      type1: 0,
+      list1: [],
+      showModal: false,
+      selectId1: '',
+      detailList1: [],
+      type: 0,
+      dateTime2: [timeDate((new Date().getTime() - 1000 * 60 * 60 * 24 * 30)), timeDate(new Date().getTime())],
+      list2: [],
+      showDevice: false,
+      detailList2: [],
+      dateTime3: [timeDate((new Date().getTime() - 1000 * 60 * 60 * 24 * 30)), timeDate(new Date().getTime())],
+      list3: [],
+      showWine: false,
+      detailList3: [],
+      dateTime4: [timeDate((new Date().getTime() - 1000 * 60 * 60 * 24 * 30)), timeDate(new Date().getTime())],
+      list4: [],
+      showWorker: false,
+      detailList4: []
+    }
+  },
+  mounted() {
+    this.search1()
+    this.search2()
+    this.search3()
+    this.search4()
+  },
+  methods: {
+    search1() {
+      const params = {
+        type: this.type1
+      }
+      api.Query1(params).then(res => {
+        this.list1 = res.data
+      })
+    },
+    reset() {
+      this.showModal = false
+      this.showDevice = false
+      this.showWine = false
+      this.showWorker = false
+      this.selectId1 = ''
+      this.type = 0
+    },
+    search2() {
+      const params = {
+        start: this.dateTime2.length > 0 ? this.dateTime2[0] : '',
+        end: this.dateTime2.length > 0 ? this.dateTime2[1] : ''
+      }
+      api.Query2(params).then(res => {
+        this.list2 = res.data
+      })
+    },
+    handlerDevice(row) {
+      this.showDevice = true
+      this.selectId1 = row.id
+      this.queryDetail2()
+    },
+    queryDetail2() {
+      const params = {
+        id: this.selectId1,
+        type: this.type
+      }
+      api.Query2Detail(params).then(res => {
+        this.detailList2 = []
+        if (res.data.length > 0) {
+          this.detailList2 = res.data
+        }
+      })
+    },
+    search3() {
+      const params = {
+        start: this.dateTime3.length > 0 ? this.dateTime3[0] : '',
+        end: this.dateTime3.length > 0 ? this.dateTime3[1] : ''
+      }
+      api.Query3(params).then(res => {
+        this.list3 = res.data
+      })
+    },
+    handlerWine(row) {
+      this.showWine = true
+      this.selectId1 = row.id
+      this.queryDetail3()
+    },
+    queryDetail3() {
+      const params = {
+        id: this.selectId1,
+        type: this.type
+      }
+      api.Query3Detail(params).then(res => {
+        this.detailList3 = []
+        if (res.data.length > 0) {
+          this.detailList3 = res.data
+        }
+      })
+    },
+    search4() {
+      const params = {
+        start: this.dateTime4.length > 0 ? this.dateTime4[0] : '',
+        end: this.dateTime4.length > 0 ? this.dateTime4[1] : ''
+      }
+      api.Query4(params).then(res => {
+        this.list4 = res.data
+      })
+    },
+    handlerWorker(row) {
+      this.showWorker = true
+      this.selectId1 = row.id
+      this.queryDetail4()
+    },
+    queryDetail4() {
+      const params = {
+        id: this.selectId1,
+        type: this.type
+      }
+      api.Query4Detail(params).then(res => {
+        this.detailList4 = []
+        if (res.data.length > 0) {
+          this.detailList4 = res.data
+        }
+      })
+    }
+  }
 }
 </script>
 
 <style scoped>
-
+.chart_content {
+  width: 100%;
+  height: 400px;
+}
+.chart_page {
+  width: 100%;
+  height: 500px;
+}
 </style>

+ 474 - 3
src/views/admin/trade/index.vue

@@ -1,13 +1,484 @@
 <template>
-  <div>trade record index</div>
+  <div class="box">
+    <el-card>
+      <div
+        slot="header"
+        class="clearfix"
+      >
+        <span>指标一览</span>
+      </div>
+      <div class="grid">
+        <div class="grid_item" />
+        <div class="grid_item" />
+        <div class="grid_item" />
+        <div class="grid_item" />
+        <div class="grid_item" />
+      </div>
+    </el-card>
+    <br>
+    <div class="app-container">
+      <div class="filter-container">
+        <el-input
+          v-model="trade.query.id"
+          placeholder="请输入用户ID"
+          style="width: 300px;"
+          class="filter-item"
+        />
+        <el-select v-model="trade.query.vip" class="filter-item">
+          <el-option label="不限" :value="-1" />
+          <el-option label="VIP" :value="1" />
+          <el-option label="非VIP" :value="0" />
+        </el-select>
+        <el-button
+          class="filter-item"
+          style="margin-left: 10px;"
+          type="primary"
+          icon="el-icon-search"
+          @click="handleQuery"
+        >
+          查询
+        </el-button>
+      </div>
+    </div>
+    <el-table
+      :key="tableKey"
+      v-loading="trade.loading"
+      :data="trade.list"
+      border
+      fit
+      highlight-current-row
+      style="width: 100%;"
+    >
+      <el-table-column
+        type="index"
+        label="序号"
+        width="80"
+        align="center"
+      />
+      <el-table-column
+        label="用户id"
+        width="300"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.id }}</span></template>
+      </el-table-column>
+      <el-table-column
+        label="消费次数"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.buy_count }}次</span></template>
+      </el-table-column>
+      <el-table-column
+        label="消费金额"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.buy_cost / 100 }}元</span></template>
+      </el-table-column>
+      <el-table-column
+        label="是否会员"
+        width="100"
+        align="center"
+      >
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.vip" type="success">会员</el-tag>
+          <el-tag v-else type="warning">非会员</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="退款次数"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.refund_count }}次</span></template>
+      </el-table-column>
+      <el-table-column
+        label="退款总额"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.refund_cost / 100 }}元</span></template>
+      </el-table-column>
+      <el-table-column
+        label="单笔消费最大消费"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.max_cost / 100 }}元</span></template>
+      </el-table-column>
+      <el-table-column
+        type="first"
+        label="注册时间"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.first }}</span></template>
+      </el-table-column>
+      <el-table-column
+        type="last"
+        label="最新活跃"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.last }}</span></template>
+      </el-table-column>
+      <el-table-column label="操作" fixed="right">
+        <template slot-scope="{ row }">
+          <el-button type="text" @click="open(row)">查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      hide-on-single-page
+      :total="trade.total"
+      :page.sync="trade.query.page"
+      :limit.sync="trade.query.limit"
+      @pagination="getList"
+    />
+    <el-drawer
+      size="50%"
+      :title="'用户'+showTitle+'历史订单'"
+      :visible.sync="showModal"
+      direction="rtl"
+      @close="resetUser"
+    >
+      <div class="box">
+        <div class="app-container">
+          <div class="filter-container">
+            <el-input
+              v-model="user.query.cond"
+              placeholder="请输入订单id,酒名"
+              style="width: 300px;"
+              class="filter-item"
+            />
+            <el-button
+              class="filter-item"
+              style="margin-left: 10px;"
+              type="primary"
+              icon="el-icon-search"
+              @click="handleQueryUser"
+            >
+              查询
+            </el-button>
+          </div>
+        </div>
+        <el-table
+          :key="tableKey"
+          v-loading="user.loading"
+          :data="user.list"
+          border
+          fit
+          highlight-current-row
+          style="width: 100%;"
+        >
+          <el-table-column
+            type="index"
+            label="序号"
+            width="80"
+            align="center"
+          />
+          <el-table-column
+            label="订单id"
+            width="300"
+            align="center"
+          >
+            <template slot-scope="{ row }"><span>{{ row.id }}</span></template>
+          </el-table-column>
+          <el-table-column
+            label="设备序列号"
+            width="200"
+            align="center"
+            prop="device"
+          />
+          <el-table-column
+            label="酒名"
+            width="100"
+            align="center"
+            prop="wine"
+          />
+          <el-table-column
+            label="出售单价"
+            width="200"
+            align="center"
+          >
+            <template slot-scope="{ row }"><span>{{ row.price / 100 }}元/两</span></template>
+          </el-table-column>
+          <el-table-column
+            label="出售量"
+            width="200"
+            align="center"
+          >
+            <template slot-scope="{ row }"><span>{{ row.weight }}两</span></template>
+          </el-table-column>
+          <el-table-column
+            label="出售价"
+            width="200"
+            align="center"
+          >
+            <template slot-scope="{ row }"><span>{{ row.cash / 100 }}元</span></template>
+          </el-table-column>
+          <el-table-column
+            label="退款金额"
+            width="200"
+            align="center"
+          >
+            <template slot-scope="{ row }"><span>{{ row.refund / 100 }}元</span></template>
+          </el-table-column>
+          <el-table-column
+            prop="reason"
+            label="退款原因"
+            width="200"
+            align="center"
+          />
+          <el-table-column
+            label="时间"
+            width="200"
+            align="center"
+            prop="time"
+          />
+          <el-table-column label="操作" fixed="right">
+            <template slot-scope="{ row }">
+              <el-button type="primary" @click="amount(row)">退款</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination
+          hide-on-single-page
+          :total="user.total"
+          :page.sync="user.query.page"
+          :limit.sync="user.query.limit"
+          @pagination="getUserList"
+        />
+      </div>
+    </el-drawer>
+    <el-dialog
+      width="30%"
+      :visible.sync="showOrder"
+      title="退款"
+      :close-on-click-modal="false"
+      center
+      @close="resetOrder"
+    >
+      <el-form ref="myForm" :model="form" label-width="120px">
+        <el-form-item label="订单id">
+          <el-input v-model="form.tid" disabled />
+        </el-form-item>
+        <el-form-item label="退款额" prop="cash" :rules="[{ required: true, message: '请输入退款额', trigger: 'blur' }, { validator: validateNumber, max: max, trigger: 'blur' }]">
+          <el-input v-model.number="form.cash" type="number" placeholder="请输入退款额">
+            <template #append>元</template>
+          </el-input>
+        </el-form-item>
+        <el-form-item label="退款原因">
+          <el-input v-model="form.reason" type="textarea" placeholder="请输入退款原因" />
+        </el-form-item>
+      </el-form>
+      <span
+        slot="footer"
+        class="dialog-footer"
+      >
+        <el-button @click="resetOrder">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="onSubmit"
+        >确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
+import api from '@/api/admin/trade'
+import Pagination from '@/components/Pagination'
 export default {
-  name: 'TradeRecord'
+  name: 'TradeRecord',
+  components: { Pagination },
+  data() {
+    return {
+      tableKey: 0,
+      trade: {
+        list: [],
+        total: 0,
+        loading: true,
+        sort: {
+          time: 'ascending',
+          price: 'ascending',
+          degree: 'ascending',
+          density: 'ascending'
+        },
+        query: {
+          page: 1,
+          limit: 10,
+          vip: -1,
+          id: ''
+        }
+      },
+      showModal: false,
+      showTitle: '',
+      user: {
+        list: [],
+        total: 0,
+        loading: true,
+        query: {
+          page: 1,
+          limit: 10,
+          cond: '',
+          uid: ''
+        }
+      },
+      showOrder: false,
+      form: {
+        tid: '',
+        cash: '',
+        reason: ''
+      },
+      max: ''
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    getList() {
+      this.trade.loading = true
+      api.QueryUser(this.trade.query).then(res => {
+        for (let i = 0; i < res.data.list.length; ++i) {
+          //   res.data.list[i].time = new Date(res.data.list[i].time)
+          res.data.list[i].first = this.$moment(new Date(res.data.list[i].first)).format('YYYY-MM-DD HH:mm:ss')
+          res.data.list[i].last = this.$moment(new Date(res.data.list[i].last)).format('YYYY-MM-DD HH:mm:ss')
+        }
+        this.trade.list = res.data.list
+        this.trade.total = res.data.total
+        this.trade.loading = false
+        console.log(this.trade.list)
+      }).catch(msg => {
+        this.trade.loading = false
+        this.$notify({
+          title: '失败',
+          message: msg,
+          type: 'error',
+          duration: 0
+        })
+      })
+    },
+    handleQuery() {
+      this.trade.query.page = 1
+      this.getList()
+    },
+    open(row) {
+      this.showTitle = row.id
+      this.showModal = true
+      this.user.query.uid = row.id
+      this.getUserList()
+    },
+    getUserList() {
+      api.Query(this.user.query).then((res) => {
+        for (let i = 0; i < res.data.list.length; ++i) {
+          res.data.list[i].time = this.$moment(new Date(res.data.list[i].time)).format('YYYY-MM-DD HH:mm:ss')
+        }
+        this.user.list = res.data.list
+        this.user.total = res.data.total
+        this.user.loading = false
+      })
+    },
+    handleQueryUser() {
+      this.user.query.page = 1
+      this.getUserList()
+    },
+    resetUser() {
+      this.showModal = false
+      this.showTitle = ''
+      this.user = {
+        list: [],
+        total: 0,
+        loading: true,
+        query: {
+          page: 1,
+          limit: 10,
+          cond: '',
+          uid: ''
+        }
+      }
+    },
+    validateNumber(rule, value, callback) {
+      if (value <= 0) {
+        callback(new Error('退款额不能小于或等于0'))
+      } else if (value > rule.max) {
+        callback(new Error('退款额不能大于出售价'))
+      } else {
+        callback()
+      }
+    },
+    amount(row) {
+      this.showOrder = true
+      this.max = row.cash / 100
+      this.form = {
+        tid: row.id,
+        cash: row.refund / 100,
+        reason: row.reason
+      }
+    },
+    resetOrder() {
+      this.showOrder = false
+      this.form = {
+        tid: '',
+        cash: '',
+        reason: ''
+      }
+      this.max = ''
+    },
+    onSubmit() {
+      this.$refs['myForm'].validate((valid) => {
+        if (valid) {
+          const params = {
+            tid: this.form.tid,
+            cash: this.form.cash * 100,
+            reason: this.form.reason
+          }
+          api.Refund(params).then(() => {
+            this.$notify({
+              title: '成功',
+              message: '退款成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.resetOrder()
+            this.getUserList()
+            this.getList()
+          }).catch((msg) => {
+            this.$notify({
+              title: '失败',
+              message: msg,
+              type: 'error',
+              duration: 0
+            })
+          })
+        }
+      })
+    }
+  }
 }
 </script>
 
 <style scoped>
-
+.box {
+  box-sizing: border-box;
+  padding: 20px;
+}
+.grid {
+  width: 100%;
+  height: 150px;
+  display: flex;
+  align-items: center;
+}
+.grid_item {
+  flex: 1;
+  height: 150px;
+  box-sizing: border-box;
+  border-right: 1px solid #ddd;
+  padding-left: 20px;
+}
+.grid_item:last-child {
+  border: 0
+}
 </style>

+ 482 - 3
src/views/admin/wine/change/index.vue

@@ -1,13 +1,492 @@
 <template>
-  <div>wine change index</div>
+  <div>
+    <div class="app-container">
+      <div class="filter-container">
+        <el-input
+          v-model="trade.query.cond"
+          placeholder="请输入用户"
+          style="width: 300px;"
+          class="filter-item"
+        />
+        <el-select v-model="trade.query.deal" class="filter-item">
+          <el-option label="不限" :value="-1" />
+          <el-option label="已处理" :value="1" />
+          <el-option label="未处理" :value="0" />
+        </el-select>
+        <el-button
+          class="filter-item"
+          style="margin-left: 10px;"
+          type="primary"
+          icon="el-icon-search"
+          @click="handleQuery"
+        >
+          查询
+        </el-button>
+      </div>
+    </div>
+    <el-table
+      :key="tableKey"
+      v-loading="trade.loading"
+      :data="trade.list"
+      border
+      fit
+      highlight-current-row
+      style="width: 100%;"
+    >
+      <el-table-column
+        type="index"
+        label="序号"
+        width="80"
+        align="center"
+      />
+      <el-table-column
+        label="贩卖机ID"
+        width="200"
+        align="center"
+        prop="device"
+      />
+      <el-table-column
+        label="地址"
+        width="300"
+        align="center"
+        prop="addr"
+      />
+      <el-table-column
+        label="报警时间"
+        width="300"
+        align="center"
+        prop="time"
+      />
+      <el-table-column
+        label="酒余量(ML)"
+        width="400"
+        align="center"
+      >
+        <el-table-column label="1">
+          <template slot-scope="{ row }">
+            <span>{{ row.old[0].remain + 'ml' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="2">
+          <template slot-scope="{ row }">
+            <span>{{ row.old[1].remain + 'ml' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="3">
+          <template slot-scope="{ row }">
+            <span>{{ row.old[2].remain + 'ml' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="4">
+          <template slot-scope="{ row }">
+            <span>{{ row.old[3].remain + 'ml' }}</span>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="操作" fixed="right">
+        <template slot-scope="{ row }">
+          <el-button v-if="row.deal === false" type="text" @click="open(row)">查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      hide-on-single-page
+      :total="trade.total"
+      :page.sync="trade.query.page"
+      :limit.sync="trade.query.limit"
+      @pagination="getList"
+    />
+    <el-dialog
+      width="60%"
+      :visible.sync="showModal"
+      title="上酒详情"
+      :close-on-click-modal="false"
+      center
+      @close="resetForm"
+    >
+      <div class="flex">
+        <div>贩卖机ID:{{ select.device }}</div>
+        <div>报警时间:{{ select.time }}</div>
+        <div>地址:{{ select.addr }}</div>
+      </div>
+      <div class="grid">
+        <div>酒名</div>
+        <div>{{ select.old[0].name ? select.old[0].name : '' }}</div>
+        <div>{{ select.old[1].name ? select.old[1].name : '' }}</div>
+        <div>{{ select.old[2].name ? select.old[2].name : '' }}</div>
+        <div>{{ select.old[3].name ? select.old[3].name : '' }}</div>
+        <div>酒量</div>
+        <div>{{ select.old[0].remain }}ml</div>
+        <div>{{ select.old[1].remain }}ml</div>
+        <div>{{ select.old[2].remain }}ml</div>
+        <div>{{ select.old[3].remain }}ml</div>
+      </div>
+      <el-form ref="myForm" :model="form" label-width="80px" :rules="rules">
+        <el-row :gutter="30">
+          <el-col :span="6">
+            <el-form-item label="酒名1" prop="name1">
+              <el-select
+                ref="mySelect1"
+                v-model="form.name1"
+                filterable
+                remote
+                reserve-keyword
+                placeholder="请输入酒名"
+                :remote-method="remoteMethod1"
+                @change="onSelectChange1"
+              >
+                <el-option
+                  v-for="item in options"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.name"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="酒名2" prop="name2">
+              <el-select
+                ref="mySelect2"
+                v-model="form.name2"
+                filterable
+                remote
+                reserve-keyword
+                placeholder="请输入酒名"
+                :remote-method="remoteMethod1"
+                @change="onSelectChange2"
+              >
+                <el-option
+                  v-for="item in options"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.name"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="酒名3" prop="name3">
+              <el-select
+                ref="mySelect3"
+                v-model="form.name3"
+                filterable
+                remote
+                reserve-keyword
+                placeholder="请输入酒名"
+                :remote-method="remoteMethod1"
+                @change="onSelectChange3"
+              >
+                <el-option
+                  v-for="item in options"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.name"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="酒名4" prop="name4">
+              <el-select
+                ref="mySelect4"
+                v-model="form.name4"
+                filterable
+                remote
+                reserve-keyword
+                placeholder="请输入酒名"
+                :remote-method="remoteMethod1"
+                @change="onSelectChange4"
+              >
+                <el-option
+                  v-for="item in options"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.name"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="酒量1" prop="value1">
+              <el-input v-model.number="form.value1" type="number">
+                <template #append>ml</template>
+              </el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="酒量2" prop="value2">
+              <el-input v-model.number="form.value2" type="number">
+                <template #append>ml</template>
+              </el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="酒量3" prop="value3">
+              <el-input v-model.number="form.value3" type="number">
+                <template #append>ml</template>
+              </el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="酒量4" prop="value4">
+              <el-input v-model.number="form.value4" type="number">
+                <template #append>ml</template>
+              </el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="上酒工">
+          <el-select
+            v-model="form.worker"
+            filterable
+            remote
+            reserve-keyword
+            placeholder="请输入上酒工查询"
+            :remote-method="remoteMethod2"
+          >
+            <el-option v-for="item in userOptions" :key="item.id" :value="item.id" :label="item.name + '(' + item.phone +')' " />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <span
+        slot="footer"
+        class="dialog-footer"
+      >
+        <el-button @click="resetForm">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="onSubmit"
+        >确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
+import api from '@/api/admin/wine/change'
+import Pagination from '@/components/Pagination'
 export default {
-  name: 'WineChange'
+  name: 'WineChange',
+  components: { Pagination },
+  data() {
+    return {
+      tableKey: 0,
+      trade: {
+        list: [],
+        total: 0,
+        loading: true,
+        sort: {
+          time: 'ascending',
+          price: 'ascending',
+          degree: 'ascending',
+          density: 'ascending'
+        },
+        query: {
+          page: 1,
+          limit: 10,
+          deal: -1,
+          cond: ''
+        }
+      },
+      showModal: false,
+      form: {
+        id1: '',
+        name1: '',
+        value1: '',
+        id2: '',
+        name2: '',
+        value2: '',
+        id3: '',
+        name3: '',
+        value3: '',
+        id4: '',
+        name4: '',
+        value4: '',
+        worker: ''
+      },
+      rules: {
+        name1: [{ required: true, message: '酒名不能为空', trigger: 'blur' }],
+        name2: [{ required: true, message: '酒名不能为空', trigger: 'blur' }],
+        name3: [{ required: true, message: '酒名不能为空', trigger: 'blur' }],
+        name4: [{ required: true, message: '酒名不能为空', trigger: 'blur' }],
+        value1: [{ required: true, message: '酒量不能为空', trigger: 'blur' }],
+        value2: [{ required: true, message: '酒量不能为空', trigger: 'blur' }],
+        value3: [{ required: true, message: '酒量不能为空', trigger: 'blur' }],
+        value4: [{ required: true, message: '酒量不能为空', trigger: 'blur' }]
+      },
+      select: {
+        id: '',
+        deal: false,
+        device: '',
+        time: '',
+        old: [
+          { name: '', remain: '', id: '' },
+          { name: '', remain: '', id: '' },
+          { name: '', remain: '', id: '' },
+          { name: '', remain: '', id: '' }
+        ]
+      },
+      options: [],
+      userOptions: []
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    handleQuery() {
+      this.trade.query.page = 1
+      this.getList()
+    },
+    getList() {
+      this.trade.loading = true
+      api.Query(this.trade.query).then(res => {
+        for (let i = 0; i < res.data.list.length; ++i) {
+          //   res.data.list[i].time = new Date(res.data.list[i].time)
+          res.data.list[i].time = this.$moment(new Date(res.data.list[i].time)).format('YYYY-MM-DD HH:mm:ss')
+          // res.data.list[i].last = this.$moment(new Date(res.data.list[i].last)).format('YYYY-MM-DD HH:mm:ss')
+        }
+        this.trade.list = res.data.list
+        this.trade.total = res.data.total
+        this.trade.loading = false
+      }).catch(msg => {
+        this.trade.loading = false
+        this.$notify({
+          title: '失败',
+          message: msg,
+          type: 'error',
+          duration: 0
+        })
+      })
+    },
+    open(row) {
+      this.showModal = true
+      this.select = row
+      this.form = {
+        id1: row.old[0].id,
+        name1: row.old[0].name,
+        value1: 0,
+        id2: row.old[1].id,
+        name2: row.old[1].name,
+        value2: 0,
+        id3: row.old[2].id,
+        name3: row.old[2].name,
+        value3: 0,
+        id4: row.old[3].id,
+        name4: row.old[3].name,
+        value4: 0
+      }
+    },
+    remoteMethod1(query) {
+      api.QueryWine(query).then(res => {
+        this.options = res.data
+      })
+    },
+    remoteMethod2(query) {
+      api.QueryWorker(query).then(res => {
+        this.userOptions = res.data
+      })
+    },
+    onSelectChange1(val) {
+      this.options.forEach(item => {
+        if (item.name === val) {
+          this.form.id1 = item.id
+        }
+      })
+    },
+    onSelectChange2(val) {
+      this.options.forEach(item => {
+        if (item.name === val) {
+          this.form.id2 = item.id
+        }
+      })
+    },
+    onSelectChange3(val) {
+      this.options.forEach(item => {
+        if (item.name === val) {
+          this.form.id3 = item.id
+        }
+      })
+    },
+    onSelectChange4(val) {
+      this.options.forEach(item => {
+        if (item.name === val) {
+          this.form.id4 = item.id
+        }
+      })
+    },
+    resetForm() {
+      this.showModal = false
+      this.form = {
+        id1: '',
+        name1: '',
+        value1: '',
+        id2: '',
+        name2: '',
+        value2: '',
+        id3: '',
+        name3: '',
+        value3: '',
+        id4: '',
+        name4: '',
+        value4: '',
+        worker: ''
+      }
+    },
+    onSubmit() {
+      const params = {
+        id: this.select.id,
+        worker: this.form.worker,
+        old: this.select.old,
+        new: [
+          { id: Number(this.form.id1), name: this.form.name1, remain: this.form.value1 },
+          { id: Number(this.form.id2), name: this.form.name2, remain: this.form.value2 },
+          { id: Number(this.form.id3), name: this.form.name3, remain: this.form.value3 },
+          { id: Number(this.form.id4), name: this.form.name4, remain: this.form.value4 }
+        ]
+      }
+      api.Assign(params).then(() => {
+        this.$notify({
+          title: '成功',
+          message: '上酒成功',
+          type: 'success',
+          duration: 2000
+        })
+        this.getList()
+        this.resetForm()
+      }).catch(msg => {
+        this.$notify({
+          title: '失败',
+          message: msg,
+          type: 'error',
+          duration: 0
+        })
+      })
+    }
+  }
 }
 </script>
 
 <style scoped>
-
+  .flex {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+  }
+  .grid {
+    box-sizing: border-box;
+    border: 1px solid #ddd;
+    margin-bottom: 20px;
+    width: 100%;
+    height: 60px;
+    display: grid;
+    grid-template-columns: repeat(5, 1fr);
+    grid-template-rows: repeat(2, 1fr);
+    grid-column-gap: 0px;
+    grid-row-gap: 0px;
+    text-align: center;
+    line-height: 30px;
+  }
 </style>

+ 713 - 3
src/views/admin/wine/history/index.vue

@@ -1,13 +1,723 @@
 <template>
-  <div>change history index</div>
+  <div>
+    <div class="app-container">
+      <div class="filter-container">
+        <el-input
+          v-model="history.query.cond"
+          placeholder="请输入员工电话,姓名"
+          style="width: 300px;"
+          class="filter-item"
+        />
+        <el-button
+          class="filter-item"
+          style="margin-left: 10px;"
+          type="primary"
+          icon="el-icon-search"
+          @click="handleQuery"
+        >
+          查询
+        </el-button>
+      </div>
+    </div>
+    <el-table
+      :key="tableKey"
+      v-loading="history.loading"
+      :data="history.list"
+      border
+      fit
+      highlight-current-row
+      style="width: 100%;"
+    >
+      <el-table-column
+        type="index"
+        label="序号"
+        width="80"
+        align="center"
+        fixed
+      />
+      <el-table-column
+        label="员工姓名"
+        width="200"
+        align="center"
+        prop="name"
+        fixed
+      />
+      <el-table-column
+        label="联系方式"
+        width="300"
+        align="center"
+        prop="phone"
+      />
+      <el-table-column
+        label="最近出勤时间"
+        width="300"
+        align="center"
+        prop="last"
+      />
+      <el-table-column
+        label="已完成订单数"
+        width="300"
+        align="center"
+        prop="count"
+      />
+      <el-table-column
+        label="待完成订单数"
+        width="300"
+        align="center"
+        prop="todo"
+      />
+      <el-table-column
+        label="平均出勤时长"
+        width="300"
+        align="center"
+      >
+        <template slot-scope="{ row }">
+          <span>{{ convertSeconds(row.avg) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="最久出勤时长"
+        width="300"
+        align="center"
+      >
+        <template slot-scope="{ row }">
+          <span>{{ convertSeconds(row.max) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" fixed="right">
+        <template slot-scope="{ row }">
+          <el-button type="text" @click="open(row)">查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      hide-on-single-page
+      :total="history.total"
+      :page.sync="history.query.page"
+      :limit.sync="history.query.limit"
+      @pagination="getList"
+    />
+    <el-dialog
+      :visible.sync="showModal"
+      :close-on-click-modal="false"
+      center
+      width="80%"
+      title="员工上酒详情"
+    >
+      <div class="flex_grid">
+        <div>员工ID:<span>{{ select.id }}</span></div>
+        <div>员工姓名:<span>{{ select.name }}</span></div>
+        <div>联系方式:<span>{{ select.phone }}</span></div>
+        <div>最近出勤时间:<span>{{ select.last }}</span></div>
+        <div>已完成上酒订单:<span>{{ select.count }}</span></div>
+        <div>未完成上酒订单:<span class="red">{{ select.todo }}</span></div>
+        <div>平均上酒时长:{{ convertSeconds(select.avg) }}</div>
+        <div>最久上酒时长:{{ convertSeconds(select.max) }}</div>
+      </div>
+      <el-card header="历史记录">
+        <div class="filter-container">
+          <el-input
+            v-model="order.query.cond"
+            placeholder="请输入员工电话,姓名"
+            style="width: 300px;"
+            class="filter-item"
+          />
+          <el-select v-model="order.query.deal" class="filter-item">
+            <el-option label="不限" :value="-1" />
+            <el-option label="已处理" :value="1" />
+            <el-option label="未处理" :value="0" />
+          </el-select>
+          <el-button
+            class="filter-item"
+            style="margin-left: 10px;"
+            type="primary"
+            icon="el-icon-search"
+            @click="handleQueryOrder"
+          >
+            查询
+          </el-button>
+        </div>
+        <el-table
+          :key="tableKey"
+          v-loading="order.loading"
+          :data="order.list"
+          border
+          fit
+          highlight-current-row
+          style="width: 100%;"
+        >
+          <el-table-column
+            type="index"
+            label="序号"
+            width="80"
+            align="center"
+            fixed
+          />
+          <el-table-column
+            label="订单ID"
+            width="200"
+            align="center"
+            prop="id"
+            fixed
+          />
+          <el-table-column
+            label="贩卖机ID"
+            width="300"
+            align="center"
+          >
+            <template slot-scope="{ row }">
+              <span>{{ row.device.id }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="贩卖机地址"
+            width="300"
+            align="center"
+          >
+            <template slot-scope="{ row }">
+              <span>{{ row.device.addr }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="发布时间"
+            width="300"
+            align="center"
+            prop="publish"
+          />
+          <el-table-column
+            label="完成时间"
+            width="300"
+            align="center"
+            prop="finish"
+          />
+          <el-table-column
+            label="订单状态"
+            width="100"
+            align="center"
+          >
+            <template slot-scope="{ row }">
+              <el-tag v-if="row.deal" type="success">已完成</el-tag>
+              <el-tag v-else type="warning">待完成</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="授权码"
+            width="300"
+            align="center"
+            prop="code"
+          />
+          <el-table-column label="操作" width="150" fixed="right">
+            <template slot-scope="{ row }">
+              <el-button style="margin-right: 10px" type="text" @click="openOrder(row)">查看</el-button>
+              <el-popconfirm
+                v-if="row.deal === false"
+                title="确定要删除这个订单吗?"
+                @confirm="del(row)"
+              >
+                <el-button slot="reference" size="mini" round plain type="danger">删除</el-button>
+              </el-popconfirm>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination
+          hide-on-single-page
+          :total="order.total"
+          :page.sync="order.query.page"
+          :limit.sync="order.query.limit"
+          @pagination="getWorkerOrder"
+        />
+      </el-card>
+      <el-dialog
+        width="60%"
+        :visible.sync="showOrder"
+        :close-on-click-modal="false"
+        center
+        title="订单详情"
+        append-to-body
+        @close="resetForm"
+      >
+        <div class="flex_grid">
+          <div>订单id:{{ orderSelect.id }}</div>
+          <div>贩卖机id:{{ orderSelect.device.id }}</div>
+          <div>贩卖机地址:{{ orderSelect.device.addr }}</div>
+          <div>订单状态:<span :class="[ orderSelect.deal ? 'green': 'red' ]">{{ orderSelect.deal ? '已完成' : '待完成' }}</span></div>
+          <div>发布时间:{{ orderSelect.publish }}</div>
+          <div>完成时间:{{ orderSelect.deal ? orderSelect.finish : '-' }}</div>
+          <div>授权码:{{ orderSelect.code }}</div>
+        </div>
+        <template v-if="orderSelect.deal">
+          <el-card header="更新前">
+            <div class="grid">
+              <div>酒名</div>
+              <div>{{ orderSelect.old[0].name ? orderSelect.old[0].name : '' }}</div>
+              <div>{{ orderSelect.old[1].name ? orderSelect.old[1].name : '' }}</div>
+              <div>{{ orderSelect.old[2].name ? orderSelect.old[2].name : '' }}</div>
+              <div>{{ orderSelect.old[3].name ? orderSelect.old[3].name : '' }}</div>
+              <div>酒量</div>
+              <div>{{ orderSelect.old[0].remain }}ml</div>
+              <div>{{ orderSelect.old[1].remain }}ml</div>
+              <div>{{ orderSelect.old[2].remain }}ml</div>
+              <div>{{ orderSelect.old[3].remain }}ml</div>
+            </div>
+          </el-card>
+          <el-card header="更新后">
+            <div class="grid">
+              <div>酒名</div>
+              <div>{{ orderSelect.new[0].name ? orderSelect.new[0].name : '' }}</div>
+              <div>{{ orderSelect.new[1].name ? orderSelect.new[1].name : '' }}</div>
+              <div>{{ orderSelect.new[2].name ? orderSelect.new[2].name : '' }}</div>
+              <div>{{ orderSelect.new[3].name ? orderSelect.new[3].name : '' }}</div>
+              <div>酒量</div>
+              <div>{{ orderSelect.new[0].remain }}ml</div>
+              <div>{{ orderSelect.new[1].remain }}ml</div>
+              <div>{{ orderSelect.new[2].remain }}ml</div>
+              <div>{{ orderSelect.new[3].remain }}ml</div>
+            </div>
+          </el-card>
+        </template>
+        <template v-else>
+          <div class="grid">
+            <div>酒名</div>
+            <div>{{ orderSelect.old[0].name ? orderSelect.old[0].name : '' }}</div>
+            <div>{{ orderSelect.old[1].name ? orderSelect.old[1].name : '' }}</div>
+            <div>{{ orderSelect.old[2].name ? orderSelect.old[2].name : '' }}</div>
+            <div>{{ orderSelect.old[3].name ? orderSelect.old[3].name : '' }}</div>
+            <div>酒量</div>
+            <div>{{ orderSelect.old[0].remain }}ml</div>
+            <div>{{ orderSelect.old[1].remain }}ml</div>
+            <div>{{ orderSelect.old[2].remain }}ml</div>
+            <div>{{ orderSelect.old[3].remain }}ml</div>
+          </div>
+          <el-form ref="myForm" :model="form" label-width="80px" :rules="rules">
+            <el-row :gutter="30">
+              <el-col :span="6">
+                <el-form-item label="酒名1" prop="name1">
+                  <el-select
+                    ref="mySelect1"
+                    v-model="form.name1"
+                    filterable
+                    remote
+                    reserve-keyword
+                    placeholder="请输入酒名"
+                    :remote-method="remoteMethod1"
+                    @change="onSelectChange1"
+                  >
+                    <el-option
+                      v-for="item in options"
+                      :key="item.id"
+                      :label="item.name"
+                      :value="item.name"
+                    />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="酒名2" prop="name2">
+                  <el-select
+                    ref="mySelect2"
+                    v-model="form.name2"
+                    filterable
+                    remote
+                    reserve-keyword
+                    placeholder="请输入酒名"
+                    :remote-method="remoteMethod1"
+                    @change="onSelectChange2"
+                  >
+                    <el-option
+                      v-for="item in options"
+                      :key="item.id"
+                      :label="item.name"
+                      :value="item.name"
+                    />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="酒名3" prop="name3">
+                  <el-select
+                    ref="mySelect3"
+                    v-model="form.name3"
+                    filterable
+                    remote
+                    reserve-keyword
+                    placeholder="请输入酒名"
+                    :remote-method="remoteMethod1"
+                    @change="onSelectChange3"
+                  >
+                    <el-option
+                      v-for="item in options"
+                      :key="item.id"
+                      :label="item.name"
+                      :value="item.name"
+                    />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="酒名4" prop="name4">
+                  <el-select
+                    ref="mySelect4"
+                    v-model="form.name4"
+                    filterable
+                    remote
+                    reserve-keyword
+                    placeholder="请输入酒名"
+                    :remote-method="remoteMethod1"
+                    @change="onSelectChange4"
+                  >
+                    <el-option
+                      v-for="item in options"
+                      :key="item.id"
+                      :label="item.name"
+                      :value="item.name"
+                    />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="酒量1" prop="value1">
+                  <el-input v-model.number="form.value1" type="number">
+                    <template #append>ml</template>
+                  </el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="酒量2" prop="value2">
+                  <el-input v-model.number="form.value2" type="number">
+                    <template #append>ml</template>
+                  </el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="酒量3" prop="value3">
+                  <el-input v-model.number="form.value3" type="number">
+                    <template #append>ml</template>
+                  </el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="酒量4" prop="value4">
+                  <el-input v-model.number="form.value4" type="number">
+                    <template #append>ml</template>
+                  </el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form>
+        </template>
+        <span
+          v-if="orderSelect.deal === false"
+          slot="footer"
+          class="dialog-footer"
+        >
+          <el-button @click="resetForm">取 消</el-button>
+          <el-button
+            type="primary"
+            @click="onSubmit"
+          >确 定</el-button>
+        </span>
+      </el-dialog>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
+import api from '@/api/admin/wine/history'
+import changeApi from '@/api/admin/wine/change'
+import Pagination from '@/components/Pagination'
 export default {
-  name: 'ChangeHistory'
+  name: 'ChangeHistory',
+  components: {
+    Pagination
+  },
+  data() {
+    return {
+      tableKey: 0,
+      history: {
+        list: [],
+        total: 0,
+        loading: true,
+        sort: {
+          time: 'ascending',
+          price: 'ascending',
+          degree: 'ascending',
+          density: 'ascending'
+        },
+        query: {
+          page: 1,
+          limit: 10,
+          cond: ''
+        }
+      },
+      showModal: false,
+      select: {
+        id: '',
+        name: '',
+        phone: '',
+        last: '',
+        count: '',
+        todo: '',
+        avg: 0,
+        max: 0
+      },
+      order: {
+        query: {
+          page: 1,
+          limit: 10,
+          deal: -1,
+          cond: '',
+          worker: ''
+        },
+        list: [],
+        total: 0,
+        loading: true
+      },
+      orderSelect: {
+        id: '',
+        deal: false,
+        device: {
+          id: '',
+          addr: ''
+        },
+        publish: '',
+        finish: '',
+        code: '',
+        old: [
+          { name: '', remain: '', id: '' },
+          { name: '', remain: '', id: '' },
+          { name: '', remain: '', id: '' },
+          { name: '', remain: '', id: '' }
+        ],
+        new: [
+          { name: '', remain: '', id: '' },
+          { name: '', remain: '', id: '' },
+          { name: '', remain: '', id: '' },
+          { name: '', remain: '', id: '' }
+        ]
+      },
+      form: {
+        id1: '',
+        name1: '',
+        value1: '',
+        id2: '',
+        name2: '',
+        value2: '',
+        id3: '',
+        name3: '',
+        value3: '',
+        id4: '',
+        name4: '',
+        value4: '',
+        worker: ''
+      },
+      rules: {
+        name1: [{ required: true, message: '酒名不能为空', trigger: 'blur' }],
+        name2: [{ required: true, message: '酒名不能为空', trigger: 'blur' }],
+        name3: [{ required: true, message: '酒名不能为空', trigger: 'blur' }],
+        name4: [{ required: true, message: '酒名不能为空', trigger: 'blur' }],
+        value1: [{ required: true, message: '酒量不能为空', trigger: 'blur' }],
+        value2: [{ required: true, message: '酒量不能为空', trigger: 'blur' }],
+        value3: [{ required: true, message: '酒量不能为空', trigger: 'blur' }],
+        value4: [{ required: true, message: '酒量不能为空', trigger: 'blur' }]
+      },
+      showOrder: false,
+      options: [],
+      userOptions: []
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    convertSeconds(val) {
+      // 转换为小时、分钟和秒
+      var hours = Math.floor(val / 3600)
+      var minutes = Math.floor((val % 3600) / 60)
+      var seconds = val % 60
+      var result = hours + '小时 ' + minutes + '分钟 ' + seconds + '秒'
+      return result
+    },
+    getList() {
+      api.QueryWorker(this.history.query).then(res => {
+        for (let i = 0; i < res.data.list.length; ++i) {
+          //   res.data.list[i].time = new Date(res.data.list[i].time)
+          // res.data.list[i].time = this.$moment(new Date(res.data.list[i].time)).format('YYYY-MM-DD HH:mm:ss')
+          res.data.list[i].last = this.$moment(new Date(res.data.list[i].last)).format('YYYY-MM-DD HH:mm:ss')
+        }
+        this.history.list = res.data.list
+        this.history.total = res.data.total
+        this.history.loading = false
+      })
+    },
+    handleQuery() {
+      this.history.query.page = 1
+      this.getList()
+    },
+    open(row) {
+      this.showModal = true
+      this.select = row
+      this.order.query.worker = row.id
+      this.getWorkerOrder()
+    },
+    getWorkerOrder() {
+      api.QueryOrder(this.order.query).then(res => {
+        for (let i = 0; i < res.data.list.length; ++i) {
+          res.data.list[i].publish = this.$moment(new Date(res.data.list[i].publish)).format('YYYY-MM-DD HH:mm:ss')
+          if (res.data.list[i].finish) {
+            res.data.list[i].finish = this.$moment(new Date(res.data.list[i].finish)).format('YYYY-MM-DD HH:mm:ss')
+          }
+        }
+        this.order.list = res.data.list
+        this.order.total = res.data.total
+        this.order.loading = false
+      })
+    },
+    handleQueryOrder() {
+      this.order.query.page = 1
+      this.getWorkerOrder()
+    },
+    del(row) {
+      api.Delete(row.id).then(() => {
+        this.$notify({
+          title: '成功',
+          message: '删除订单成功成功',
+          type: 'success',
+          duration: 2000
+        })
+        this.getWorkerOrder()
+      }).catch(msg => {
+        this.$notify({
+          title: '失败',
+          message: msg,
+          type: 'error',
+          duration: 0
+        })
+      })
+    },
+    openOrder(row) {
+      this.showOrder = true
+      this.orderSelect = row
+    },
+    resetForm() {
+      this.showOrder = false
+      this.form = {
+        id1: '',
+        name1: '',
+        value1: '',
+        id2: '',
+        name2: '',
+        value2: '',
+        id3: '',
+        name3: '',
+        value3: '',
+        id4: '',
+        name4: '',
+        value4: '',
+        worker: ''
+      }
+    },
+    remoteMethod1(query) {
+      changeApi.QueryWine(query).then(res => {
+        this.options = res.data
+      })
+    },
+    remoteMethod2(query) {
+      changeApi.QueryWorker(query).then(res => {
+        this.userOptions = res.data
+      })
+    },
+    onSelectChange1(val) {
+      this.options.forEach(item => {
+        if (item.name === val) {
+          this.form.id1 = item.id
+        }
+      })
+    },
+    onSelectChange2(val) {
+      this.options.forEach(item => {
+        if (item.name === val) {
+          this.form.id2 = item.id
+        }
+      })
+    },
+    onSelectChange3(val) {
+      this.options.forEach(item => {
+        if (item.name === val) {
+          this.form.id3 = item.id
+        }
+      })
+    },
+    onSelectChange4(val) {
+      this.options.forEach(item => {
+        if (item.name === val) {
+          this.form.id4 = item.id
+        }
+      })
+    },
+    onSubmit() {
+      const params = {
+        id: this.orderSelect.id,
+        new: [
+          { id: Number(this.form.id1), name: this.form.name1, remain: this.form.value1 },
+          { id: Number(this.form.id2), name: this.form.name2, remain: this.form.value2 },
+          { id: Number(this.form.id3), name: this.form.name3, remain: this.form.value3 },
+          { id: Number(this.form.id4), name: this.form.name4, remain: this.form.value4 }
+        ]
+      }
+      api.UpdateOrder(params).then(() => {
+        this.$notify({
+          title: '成功',
+          message: '上酒成功',
+          type: 'success',
+          duration: 2000
+        })
+        this.resetForm()
+        this.getWorkerOrder()
+      }).catch(msg => {
+        this.$notify({
+          title: '失败',
+          message: msg,
+          type: 'error',
+          duration: 0
+        })
+      })
+    }
+  }
 }
 </script>
 
 <style scoped>
-
+.flex_grid {
+  box-sizing: border-box;
+  margin-bottom: 20px;
+  width: 100%;
+  padding: 0 20px;
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  grid-template-rows: repeat(4, 1fr);
+  grid-column-gap: 0px;
+  grid-row-gap: 0px;
+  line-height: 30px;
+  text-align: left;
+}
+.green {
+  color: #2ac06d;
+}
+.red {
+  color: red;
+}
+.grid {
+  box-sizing: border-box;
+  border: 1px solid #ddd;
+  margin-bottom: 20px;
+  width: 100%;
+  height: 60px;
+  display: grid;
+  grid-template-columns: repeat(5, 1fr);
+  grid-template-rows: repeat(2, 1fr);
+  grid-column-gap: 0px;
+  grid-row-gap: 0px;
+  text-align: center;
+  line-height: 30px;
+}
 </style>

+ 466 - 3
src/views/admin/worker/index.vue

@@ -1,13 +1,476 @@
 <template>
-  <div>worker manage index</div>
+  <div class="box">
+    <el-card>
+      <div
+        slot="header"
+        class="clearfix"
+      >
+        <span>指标一览</span>
+      </div>
+      <div class="grid">
+        <div class="grid_item" />
+        <div class="grid_item" />
+        <div class="grid_item" />
+        <div class="grid_item" />
+        <div class="grid_item" />
+      </div>
+    </el-card>
+    <br>
+    <div class="app-container">
+      <div class="filter-container">
+        <el-input
+          v-model="admin.query.cond"
+          placeholder="请输入姓名、电话"
+          style="width: 300px;"
+          class="filter-item"
+        />
+        <el-button
+          class="filter-item"
+          style="margin-left: 10px;"
+          type="primary"
+          icon="el-icon-search"
+          @click="handleQuery"
+        >
+          查询
+        </el-button>
+        <el-button
+          plain
+          class="filter-item"
+          style="margin-left: 10px;"
+          type="success"
+          icon="el-icon-plus"
+          @click="handleShowCreate"
+        >
+          添加
+        </el-button>
+        <el-button
+          plain
+          class="filter-item"
+          style="margin-left: 10px;"
+          icon="el-icon-delete"
+          type="danger"
+          @click="handleBatchDelete"
+        >
+          删除
+        </el-button>
+      </div>
+    </div>
+    <el-table
+      :key="tableKey"
+      v-loading="admin.loading"
+      :data="admin.list"
+      border
+      fit
+      highlight-current-row
+      style="width: 100%;"
+      @sort-change="sortChange"
+      @selection-change="selectionChange"
+    >
+      <el-table-column
+        type="selection"
+        width="80"
+        align="center"
+        :selectable="selectableList"
+      />
+      <el-table-column
+        type="index"
+        label="序号"
+        width="80"
+        align="center"
+      />
+      <el-table-column
+        label="姓名"
+        prop="name"
+        align="center"
+        width="250"
+      />
+      <el-table-column
+        label="联系方式"
+        prop="phone"
+        align="center"
+        width="250"
+      />
+      <el-table-column
+        label="出勤次数"
+        prop="count"
+        align="center"
+        width="250"
+      />
+      <el-table-column
+        label="平均出勤时长(min)"
+        align="center"
+        width="250"
+      >
+        <template slot-scope="{ row }">
+          <span>{{ convertSeconds(row.cost) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="注册时间"
+        prop="first"
+        align="center"
+        width="250"
+      />
+      <el-table-column
+        label="最近活跃"
+        prop="last"
+        align="center"
+        width="250"
+      />
+      <el-table-column
+        label="操作"
+        fixed="right"
+        align="center"
+        width="240"
+        class-name="small-padding fixed-width"
+      >
+        <template slot-scope="{row}">
+          <el-button
+            plain
+            type="primary"
+            size="mini"
+            icon="el-icon-edit"
+            @click="handleShowDetail(row)"
+          >
+            编辑
+          </el-button>
+          <el-button
+            v-if="canDelete(row.id)"
+            plain
+            type="danger"
+            size="mini"
+            icon="el-icon-delete"
+            @click="handleDeleteOne(row.id)"
+          >
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      hide-on-single-page
+      :total="admin.total"
+      :page.sync="admin.query.page"
+      :limit.sync="admin.query.limit"
+      @pagination="getList"
+    />
+    <el-dialog
+      width="30%"
+      :visible.sync="detailVisible"
+      :title="detail.title"
+      :close-on-click-modal="false"
+      center
+      @close="resetDetail"
+    >
+      <el-form
+        ref="myForm"
+        label-width="120px"
+        :rules="rules"
+        :model="detail"
+      >
+        <el-form-item
+          label="姓名"
+          prop="name"
+        >
+          <el-input
+            v-model="detail.name"
+            placeholder="请输入姓名"
+          />
+        </el-form-item>
+        <el-form-item
+          label="手机号码"
+          prop="phone"
+        >
+          <el-input
+            v-model="detail.phone"
+            placeholder="请输入手机号码"
+          />
+        </el-form-item>
+        <el-form-item label="密码">
+          <el-input
+            v-model="detail.password"
+            type="password"
+            placeholder="请输入密码"
+          />
+        </el-form-item>
+      </el-form>
+      <span
+        slot="footer"
+        class="dialog-footer"
+      >
+        <el-button @click="resetDetail">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="onSubmit"
+        >确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
+import api from '@/api/admin/worker'
+import Pagination from '@/components/Pagination'
+import utils from '@/utils/lib'
+const InitWineId = 10100
 export default {
-  name: 'WorkerManage'
+  name: 'WorkerManage',
+  components: { Pagination },
+  data() {
+    var validatePhoneNumber = (rule, value, callback) => {
+      // 使用正则表达式验证手机号码
+      const reg = /^[1][3,4,5,6.7,8,9][0-9]{9}$/
+      if (!reg.test(value)) {
+        callback(new Error('请输入有效的手机号码'))
+      } else {
+        callback()
+      }
+    }
+    return {
+      tableKey: 0,
+      admin: {
+        list: [],
+        total: 0,
+        loading: true,
+        sort: {
+          time: 'ascending',
+          price: 'ascending',
+          degree: 'ascending',
+          density: 'ascending'
+        },
+        query: {
+          page: 1,
+          limit: 10,
+          cond: ''
+        }
+      },
+      batch: [],
+      detailVisible: false,
+      detail: {
+        title: '',
+        id: 0,
+        name: '',
+        phone: '',
+        password: ''
+      },
+      password: '',
+      rules: {
+        name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
+        phone: [{ required: true, message: '请输入手机号码', trigger: 'blur' }, { validator: validatePhoneNumber, trigger: 'blur' }],
+        password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
+      }
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    convertSeconds(val) {
+      // 转换为小时、分钟和秒
+      var hours = Math.floor(val / 3600)
+      var minutes = Math.floor((val % 3600) / 60)
+      var seconds = val % 60
+      var result = hours + '小时 ' + minutes + '分钟 ' + seconds + '秒'
+      return result
+    },
+    handleManagerSearch(value) {
+      this.manager.loading = true
+      api.QueryManager(value).then(res => {
+        this.manager.groups[1].options = res
+        this.manager.loading = false
+      })
+    },
+    selectableList(row) {
+      return row.id !== InitWineId
+    },
+    canDelete(id) {
+      return id !== InitWineId
+    },
+    handleDeleteOne(id) {
+      this.$confirm('此操作将删除该酒品, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        api.Delete([id]).then(() => {
+          this.$notify({
+            title: '成功',
+            message: '删除酒品信息成功',
+            type: 'success',
+            duration: 2000
+          })
+          this.getList()
+        }).catch(msg => {
+          this.$notify({
+            title: '失败',
+            message: msg,
+            type: 'error',
+            duration: 0
+          })
+        })
+      })
+    },
+    handleBatchDelete() {
+      if (this.batch.length === 0) return this.$message.info('请勾选需要删除的酒品')
+      this.$confirm('此操作将删除选中的酒品, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        api.Delete(this.batch).then(() => {
+          this.$notify({
+            title: '成功',
+            message: '删除酒品信息成功',
+            type: 'success',
+            duration: 2000
+          })
+          this.getList()
+        }).catch(msg => {
+          this.$notify({
+            title: '失败',
+            message: msg,
+            type: 'error',
+            duration: 0
+          })
+        })
+      })
+    },
+    getList() {
+      this.admin.loading = true
+      api.Query(this.admin.query).then(res => {
+        for (let i = 0; i < res.data.list.length; ++i) {
+          res.data.list[i].time = new Date(res.data.list[i].time)
+          res.data.list[i].first = this.$moment(new Date(res.data.list[i].first)).format('YYYY-MM-DD HH:mm:ss')
+          res.data.list[i].last = this.$moment(new Date(res.data.list[i].last)).format('YYYY-MM-DD HH:mm:ss')
+        }
+        this.admin.list = res.data.list
+        this.admin.total = res.data.total
+        this.admin.loading = false
+      }).catch(msg => {
+        this.admin.loading = false
+        this.$notify({
+          title: '失败',
+          message: msg,
+          type: 'error',
+          duration: 0
+        })
+      })
+    },
+    handleQuery() {
+      this.admin.query.page = 1
+      this.getList()
+    },
+    sortChange(data) {
+      const { prop, order } = data
+      this.admin.sort[prop] = order
+      const cmp = order === 'ascending' ? (a, b) => a[prop] - b[prop] : (a, b) => b[prop] - a[prop]
+      this.admin.list.sort(cmp)
+    },
+    selectionChange(val) {
+      this.batch = val.map(e => e.id)
+    },
+    handleShowCreate() {
+      this.detailVisible = true
+      this.detail.title = '新增员工'
+    },
+    handleShowDetail(row) {
+      this.detailVisible = true
+      this.detail = {
+        title: '编辑员工',
+        id: row.id,
+        name: row.name,
+        phone: row.phone,
+        password: ''
+      }
+    },
+    resetDetail() {
+      this.detailVisible = false
+      this.password = ''
+      this.detail = {
+        title: '',
+        id: 0,
+        name: '',
+        phone: '',
+        password: ''
+      }
+    },
+    onSubmit() {
+      this.$refs['myForm'].validate((valid) => {
+        if (valid) {
+          if (this.detail.title === '新增员工') {
+            const params = {
+              name: this.detail.name,
+              phone: this.detail.phone,
+              password: utils.EncryptHandler.encrypt(this.detail.password)
+            }
+            api.Add(params).then(res => {
+              this.$notify({
+                title: '成功',
+                message: '新增员工成功',
+                type: 'success',
+                duration: 2000
+              })
+              this.resetDetail()
+              this.getList()
+            }).catch((msg) => {
+              this.$notify({
+                title: '失败',
+                message: msg,
+                type: 'error',
+                duration: 0
+              })
+            })
+          } else {
+            const params = {
+              id: this.detail.id,
+              name: this.detail.name,
+              phone: this.detail.phone,
+              password: this.detail.password ? utils.EncryptHandler.encrypt(this.detail.password) : ''
+            }
+            api.Update(params).then(() => {
+              this.$notify({
+                title: '成功',
+                message: '编辑员工成功',
+                type: 'success',
+                duration: 2000
+              })
+              this.resetDetail()
+              this.getList()
+            }).catch((msg) => {
+              this.$notify({
+                title: '失败',
+                message: msg,
+                type: 'error',
+                duration: 0
+              })
+            })
+          }
+        }
+      })
+    }
+  }
 }
 </script>
 
 <style scoped>
-
+.box {
+  box-sizing: border-box;
+  padding: 20px;
+}
+.grid {
+  width: 100%;
+  height: 150px;
+  display: flex;
+  align-items: center;
+}
+.grid_item {
+  flex: 1;
+  height: 150px;
+  box-sizing: border-box;
+  border-right: 1px solid #ddd;
+  padding-left: 20px;
+}
+.grid_item:last-child {
+  border: 0
+}
 </style>

+ 0 - 1
src/views/super/config/advertise/index.vue

@@ -509,7 +509,6 @@ export default {
       })
     },
     handleShowCreate() {
-      this.resetDetail()
       this.detail.title = '新增广告'
       this.detailVisible = true
     },

+ 78 - 0
src/views/super/dashboard/chart/ChartDevice.vue

@@ -0,0 +1,78 @@
+<template>
+  <div :id="'chart-device' + id" style="width: 100%; height: 100%" />
+</template>
+
+<script>
+import echarts from 'echarts'
+let myChart = null
+export default {
+  name: 'ChartDevice',
+  props: {
+    id: {
+      type: Number,
+      default: 0
+    },
+    item: {
+      type: Object,
+      default: () => {
+        return {
+          unit: '',
+          list: []
+        }
+      }
+    }
+  },
+  watch: {
+    item: {
+      handler() {
+        myChart.clear()
+        this.init()
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      myChart = echarts.init(document.getElementById('chart-device' + this.id))
+      const that = this
+      let data = []
+      if (this.item.list.length > 0) {
+        this.item.list.forEach(item => {
+          item.value = item.total / 100
+          item.name = item.id
+        })
+        data = this.item.list
+      }
+      const options = {
+        tooltip: {
+          trigger: 'item'
+        },
+        legend: {
+          left: 'center'
+        },
+        color: ['#EE752F', '#5894FF', '#F2BD42', '#72CDD7', '#60B565'],
+        series: [
+          {
+            name: '',
+            type: 'pie',
+            radius: '60%',
+            data: data
+          }
+        ]
+      }
+      myChart.setOption(options)
+      myChart.off('click')
+      myChart.on('click', function(params) {
+        that.$emit('onClick', params.data)
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 101 - 0
src/views/super/dashboard/chart/ChartLine.vue

@@ -0,0 +1,101 @@
+<template>
+  <div :id="'chart-line'+id" style="width: 100%; height: 100%" />
+</template>
+
+<script>
+let myChart = null
+import echarts from 'echarts'
+export default {
+  name: 'ChartLine',
+  props: {
+    id: {
+      type: Number,
+      default: 0
+    },
+    list: {
+      type: Array,
+      default: () => []
+    }
+  },
+  watch: {
+    list: {
+      handler() {
+        myChart.clear()
+        this.init()
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      myChart = echarts.init(document.getElementById('chart-line' + this.id))
+      const time = []
+      const data = []
+      if (this.list.length > 0) {
+        this.list.forEach(item => {
+          time.push(item.time)
+          data.push(item.total / 100)
+        })
+      }
+      const options = {
+        tooltip: {
+          trigger: 'axis'
+        },
+        color: ['#6BBEAE', '#1890FF'],
+        xAxis: {
+          type: 'category',
+          boundaryGap: true,
+          data: time,
+          axisLine: {
+            show: true,
+            lineStyle: {
+              color: '#aaa'
+            }
+          },
+          axisLabel: {
+            color: '#aaa'
+          }
+        },
+        yAxis: [
+          {
+            type: 'value',
+            name: '单位:元',
+            boundaryGap: [0, '100%'],
+            axisLine: { // y轴
+              show: false
+            },
+            axisTick: {
+              show: false
+            },
+            splitLine: {
+              show: false
+            }
+          }
+        ],
+        series: [
+          {
+            name: `总收入`,
+            type: 'line',
+            // stack: 'Total',
+            data: data,
+            barWidth: 20,
+            tooltip: {
+              valueFormatter: function(value) {
+                return value + ' 元'
+              }
+            }
+          }
+        ]
+      }
+      myChart.setOption(options)
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 101 - 0
src/views/super/dashboard/chart/ChartLines.vue

@@ -0,0 +1,101 @@
+<template>
+  <div :id="'chart-lines' + id" style="width: 100%; height: 100%" />
+</template>
+
+<script>
+let myChart = null
+import echarts from 'echarts'
+export default {
+  name: 'ChartLines',
+  props: {
+    id: {
+      type: Number,
+      default: 0
+    },
+    list: {
+      type: Array,
+      default: () => []
+    }
+  },
+  watch: {
+    list: {
+      handler() {
+        myChart.clear()
+        this.init()
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      myChart = echarts.init(document.getElementById('chart-lines' + this.id))
+      const time = []
+      const data = []
+      if (this.list.length > 0) {
+        this.list.forEach(item => {
+          time.push(item.time)
+          data.push(item.total / 100)
+        })
+      }
+      const options = {
+        tooltip: {
+          trigger: 'axis'
+        },
+        color: ['#6BBEAE', '#1890FF'],
+        xAxis: {
+          type: 'category',
+          boundaryGap: true,
+          data: time,
+          axisLine: {
+            show: true,
+            lineStyle: {
+              color: '#aaa'
+            }
+          },
+          axisLabel: {
+            color: '#aaa'
+          }
+        },
+        yAxis: [
+          {
+            type: 'value',
+            name: '单位:元',
+            boundaryGap: [0, '100%'],
+            axisLine: { // y轴
+              show: false
+            },
+            axisTick: {
+              show: false
+            },
+            splitLine: {
+              show: false
+            }
+          }
+        ],
+        series: [
+          {
+            name: `总收入`,
+            type: 'line',
+            // stack: 'Total',
+            data: data,
+            barWidth: 20,
+            tooltip: {
+              valueFormatter: function(value) {
+                return value + ' 元'
+              }
+            }
+          }
+        ]
+      }
+      myChart.setOption(options)
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 77 - 0
src/views/super/dashboard/chart/ChartPie.vue

@@ -0,0 +1,77 @@
+<template>
+  <div :id="'chart-pie' + id" style="width: 100%; height: 100%" />
+</template>
+
+<script>
+import echarts from 'echarts'
+let myChart = null
+export default {
+  name: 'ChartPie',
+  props: {
+    id: {
+      type: Number,
+      default: 0
+    },
+    item: {
+      type: Object,
+      default: () => {
+        return {
+          unit: '',
+          list: []
+        }
+      }
+    }
+  },
+  watch: {
+    item: {
+      handler() {
+        myChart.clear()
+        this.init()
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      myChart = echarts.init(document.getElementById('chart-pie' + this.id))
+      const that = this
+      let data = []
+      if (this.item.list.length > 0) {
+        this.item.list.forEach(item => {
+          item.value = item.total / 100
+        })
+        data = this.item.list
+      }
+      const options = {
+        tooltip: {
+          trigger: 'item'
+        },
+        legend: {
+          left: 'center'
+        },
+        color: ['#EE752F', '#5894FF', '#F2BD42', '#72CDD7', '#60B565'],
+        series: [
+          {
+            name: '',
+            type: 'pie',
+            radius: '60%',
+            data: data
+          }
+        ]
+      }
+      myChart.setOption(options)
+      myChart.off('click')
+      myChart.on('click', function(params) {
+        that.$emit('onClick', params.data)
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 77 - 0
src/views/super/dashboard/chart/ChartWine.vue

@@ -0,0 +1,77 @@
+<template>
+  <div :id="'chart-wine' + id" style="width: 100%; height: 100%" />
+</template>
+
+<script>
+import echarts from 'echarts'
+let myChart = null
+export default {
+  name: 'ChartWine',
+  props: {
+    id: {
+      type: Number,
+      default: 0
+    },
+    item: {
+      type: Object,
+      default: () => {
+        return {
+          unit: '',
+          list: []
+        }
+      }
+    }
+  },
+  watch: {
+    item: {
+      handler() {
+        myChart.clear()
+        this.init()
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      myChart = echarts.init(document.getElementById('chart-wine' + this.id))
+      const that = this
+      let data = []
+      if (this.item.list.length > 0) {
+        this.item.list.forEach(item => {
+          item.value = item.total / 100
+        })
+        data = this.item.list
+      }
+      const options = {
+        tooltip: {
+          trigger: 'item'
+        },
+        legend: {
+          left: 'center'
+        },
+        color: ['#EE752F', '#5894FF', '#F2BD42', '#72CDD7', '#60B565'],
+        series: [
+          {
+            name: '',
+            type: 'pie',
+            radius: '60%',
+            data: data
+          }
+        ]
+      }
+      myChart.setOption(options)
+      myChart.off('click')
+      myChart.on('click', function(params) {
+        that.$emit('onClick', params.data)
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 101 - 0
src/views/super/dashboard/chart/ChartWokerLine.vue

@@ -0,0 +1,101 @@
+<template>
+  <div :id="'chart-worker-line' + id" style="width: 100%;height: 100%" />
+</template>
+
+<script>
+import echarts from 'echarts'
+let myChart = null
+export default {
+  name: 'ChartWokerLine',
+  props: {
+    id: {
+      type: Number,
+      default: 0
+    },
+    list: {
+      type: Array,
+      default: () => []
+    }
+  },
+  watch: {
+    list: {
+      handler() {
+        myChart.clear()
+        this.init()
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      myChart = echarts.init(document.getElementById('chart-worker-line' + this.id))
+      const time = []
+      const data = []
+      if (this.list.length > 0) {
+        this.list.forEach(item => {
+          time.push(item.time)
+          data.push(item.total)
+        })
+      }
+      const options = {
+        tooltip: {
+          trigger: 'axis'
+        },
+        color: ['#6BBEAE', '#1890FF'],
+        xAxis: {
+          type: 'category',
+          boundaryGap: true,
+          data: time,
+          axisLine: {
+            show: true,
+            lineStyle: {
+              color: '#aaa'
+            }
+          },
+          axisLabel: {
+            color: '#aaa'
+          }
+        },
+        yAxis: [
+          {
+            type: 'value',
+            name: '单位:次',
+            boundaryGap: [0, '100%'],
+            axisLine: { // y轴
+              show: false
+            },
+            axisTick: {
+              show: false
+            },
+            splitLine: {
+              show: false
+            }
+          }
+        ],
+        series: [
+          {
+            name: `订单数`,
+            type: 'line',
+            // stack: 'Total',
+            data: data,
+            barWidth: 20,
+            tooltip: {
+              valueFormatter: function(value) {
+                return value + ' 次'
+              }
+            }
+          }
+        ]
+      }
+      myChart.setOption(options)
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 77 - 0
src/views/super/dashboard/chart/ChartWorker.vue

@@ -0,0 +1,77 @@
+<template>
+  <div :id="'chart-worker' + id" style="width: 100%; height: 100%" />
+</template>
+
+<script>
+import echarts from 'echarts'
+let myChart = null
+export default {
+  name: 'ChartWorker',
+  props: {
+    id: {
+      type: Number,
+      default: 0
+    },
+    item: {
+      type: Object,
+      default: () => {
+        return {
+          unit: '',
+          list: []
+        }
+      }
+    }
+  },
+  watch: {
+    item: {
+      handler() {
+        myChart.clear()
+        this.init()
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      myChart = echarts.init(document.getElementById('chart-worker' + this.id))
+      const that = this
+      let data = []
+      if (this.item.list.length > 0) {
+        this.item.list.forEach(item => {
+          item.value = item.total
+        })
+        data = this.item.list
+      }
+      const options = {
+        tooltip: {
+          trigger: 'item'
+        },
+        legend: {
+          left: 'center'
+        },
+        color: ['#EE752F', '#5894FF', '#F2BD42', '#72CDD7', '#60B565'],
+        series: [
+          {
+            name: '',
+            type: 'pie',
+            radius: '60%',
+            data: data
+          }
+        ]
+      }
+      myChart.setOption(options)
+      myChart.off('click')
+      myChart.on('click', function(params) {
+        that.$emit('onClick', params.data)
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 369 - 2
src/views/super/dashboard/index.vue

@@ -1,24 +1,391 @@
 <template>
-  <div>super dashboard index</div>
+  <div>
+    <el-row :gutter="20">
+      <el-col :span="12">
+        <el-card header="管理员业绩">
+          <el-form inline>
+            <el-form-item label="日期">
+              <el-date-picker
+                v-model="dateTime1"
+                type="daterange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                format="YYYY-MM-dd"
+                value-format="YYYY-MM-dd"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="search1">查询</el-button>
+            </el-form-item>
+          </el-form>
+          <div class="chart_content">
+            <chart-pie v-if="list1.length > 0" :id="0" :item="{ unit: '', list: list1 }" @onClick="handlerOrder" />
+            <div style="line-height: 400px; text-align: center">暂无数据</div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card header="贩卖机业绩">
+          <el-form inline>
+            <el-form-item label="日期">
+              <el-date-picker
+                v-model="dateTime2"
+                type="daterange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                format="YYYY-MM-dd"
+                value-format="YYYY-MM-dd"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="search2">查询</el-button>
+            </el-form-item>
+          </el-form>
+          <div class="chart_content">
+            <chart-device v-if="list2.length > 0" :id="0" :item="{ unit: '', list: list2 }" @onClick="handlerDevice" />
+            <div style="line-height: 400px; text-align: center">暂无数据</div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="12" style="margin-top: 20px">
+        <el-card header="酒品业绩">
+          <el-form inline>
+            <el-form-item label="日期">
+              <el-date-picker
+                v-model="dateTime3"
+                type="daterange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                format="YYYY-MM-dd"
+                value-format="YYYY-MM-dd"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="search3">查询</el-button>
+            </el-form-item>
+          </el-form>
+          <div class="chart_content">
+            <chart-wine v-if="list3.length > 0" :id="2" :item="{ unit: '', list: list3 } " @onClick="handlerWine" />
+            <div style="line-height: 400px; text-align: center">暂无数据</div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="12" style="margin-top: 20px">
+        <el-card header="上酒工业绩">
+          <el-form inline>
+            <el-form-item label="日期">
+              <el-date-picker
+                v-model="dateTime4"
+                type="daterange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                format="YYYY-MM-dd"
+                value-format="YYYY-MM-dd"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="search4">查询</el-button>
+            </el-form-item>
+          </el-form>
+          <div class="chart_content">
+            <chart-worker v-if="list4.length > 0" :id="4" :item="{ unit: '', list: list4 } " @onClick="handlerWorker" />
+            <div style="line-height: 400px; text-align: center">暂无数据</div>
+            <!--            <chart-pie :id="4" :item="{ unit: '', list: list4 } " @onClick="handlerWorker"></chart-pie>-->
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+    <el-dialog
+      width="60%"
+      :visible.sync="showModal"
+      :close-on-click-modal="false"
+      title="管理员业绩详情"
+      @close="reset"
+    >
+      <el-form inline>
+        <el-form-item>
+          <el-select v-model="type">
+            <el-option label="不限" :value="0" />
+            <el-option label="一周" :value="1" />
+            <el-option label="一月" :value="2" />
+            <el-option label="一季" :value="3" />
+            <el-option label="半年" :value="4" />
+            <el-option label="一年" :value="5" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="queryDetail1">查询</el-button>
+        </el-form-item>
+      </el-form>
+      <div class="chart_page">
+        <chart-line :id="0" :list="detailList1" />
+      </div>
+    </el-dialog>
+    <el-dialog
+      width="60%"
+      :visible.sync="showDevice"
+      :close-on-click-modal="false"
+      title="贩卖机业绩详情"
+      @close="reset"
+    >
+      <el-form inline>
+        <el-form-item>
+          <el-select v-model="type">
+            <el-option label="不限" :value="0" />
+            <el-option label="一周" :value="1" />
+            <el-option label="一月" :value="2" />
+            <el-option label="一季" :value="3" />
+            <el-option label="半年" :value="4" />
+            <el-option label="一年" :value="5" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="queryDetail2">查询</el-button>
+        </el-form-item>
+      </el-form>
+      <div class="chart_page">
+        <chart-line :id="1" :list="detailList2" />
+      </div>
+    </el-dialog>
+    <el-dialog
+      width="60%"
+      :visible.sync="showWine"
+      :close-on-click-modal="false"
+      title="酒品业绩详情"
+      @close="reset"
+    >
+      <el-form inline>
+        <el-form-item>
+          <el-select v-model="type">
+            <el-option label="不限" :value="0" />
+            <el-option label="一周" :value="1" />
+            <el-option label="一月" :value="2" />
+            <el-option label="一季" :value="3" />
+            <el-option label="半年" :value="4" />
+            <el-option label="一年" :value="5" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="queryDetail3">查询</el-button>
+        </el-form-item>
+      </el-form>
+      <div class="chart_page">
+        <chart-line :id="2" :list="detailList3" />
+      </div>
+    </el-dialog>
+    <el-dialog
+      width="60%"
+      :visible.sync="showWorker"
+      :close-on-click-modal="false"
+      title="上酒工业绩详情"
+      @close="reset"
+    >
+      <el-form inline>
+        <el-form-item>
+          <el-select v-model="type">
+            <el-option label="不限" :value="0" />
+            <el-option label="一周" :value="1" />
+            <el-option label="一月" :value="2" />
+            <el-option label="一季" :value="3" />
+            <el-option label="半年" :value="4" />
+            <el-option label="一年" :value="5" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="queryDetail4">查询</el-button>
+        </el-form-item>
+      </el-form>
+      <div class="chart_page">
+        <ChartWokerLine :id="3" :list="detailList4" />
+      </div>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
 import Driver from 'driver.js'
 import 'driver.js/dist/driver.min.css'
 import steps from '@/utils/steps'
+import api from '@/api/super/dashboard/index'
+import { timeDate } from '@/utils/index'
+import ChartPie from '@/views/super/dashboard/chart/ChartPie'
+import ChartLine from '@/views/super/dashboard/chart/ChartLine'
+import ChartDevice from '@/views/super/dashboard/chart/ChartDevice'
+import ChartWorker from '@/views/super/dashboard/chart/ChartWorker'
+import ChartWine from '@/views/super/dashboard/chart/ChartWine'
+import ChartWokerLine from '@/views/super/dashboard/chart/ChartWokerLine'
 
 export default {
   name: 'SuperDashboard',
+  components: {
+    ChartPie,
+    ChartLine,
+    ChartDevice,
+    ChartWorker,
+    ChartWine,
+    ChartWokerLine
+  },
+  data() {
+    return {
+      dateTime1: [timeDate((new Date().getTime() - 1000 * 60 * 60 * 24 * 30)), timeDate(new Date().getTime())],
+      list1: [],
+      showModal: false,
+      selectId1: '',
+      detailList1: [],
+      type: 0,
+      dateTime2: [timeDate((new Date().getTime() - 1000 * 60 * 60 * 24 * 30)), timeDate(new Date().getTime())],
+      list2: [],
+      showDevice: false,
+      detailList2: [],
+      dateTime3: [timeDate((new Date().getTime() - 1000 * 60 * 60 * 24 * 30)), timeDate(new Date().getTime())],
+      list3: [],
+      showWine: false,
+      detailList3: [],
+      dateTime4: [timeDate((new Date().getTime() - 1000 * 60 * 60 * 24 * 30)), timeDate(new Date().getTime())],
+      list4: [],
+      showWorker: false,
+      detailList4: []
+    }
+  },
   mounted: async function() {
     if (await this.$store.dispatch('user/isFirst')) {
       const driver = new Driver()
       driver.defineSteps(steps)
       driver.start()
     }
+    this.search1()
+    this.search2()
+    this.search3()
+    this.search4()
+  },
+  methods: {
+    search1() {
+      const params = {
+        start: this.dateTime1.length > 0 ? this.dateTime1[0] : '',
+        end: this.dateTime1.length > 0 ? this.dateTime1[1] : ''
+      }
+      api.Query1(params).then(res => {
+        this.list1 = res.data
+      })
+    },
+    handlerOrder(row) {
+      this.showModal = true
+      this.selectId1 = row.id
+      this.queryDetail1()
+    },
+    queryDetail1() {
+      const params = {
+        id: this.selectId1,
+        type: this.type
+      }
+      api.QueryDetail(params).then(res => {
+        this.detailList1 = []
+        if (res.data.length > 0) {
+          this.detailList1 = res.data
+        }
+      })
+    },
+    reset() {
+      this.showModal = false
+      this.showDevice = false
+      this.showWine = false
+      this.showWorker = false
+      this.selectId1 = ''
+      this.type = 0
+    },
+    search2() {
+      const params = {
+        start: this.dateTime2.length > 0 ? this.dateTime2[0] : '',
+        end: this.dateTime2.length > 0 ? this.dateTime2[1] : ''
+      }
+      api.Query2(params).then(res => {
+        this.list2 = res.data
+      })
+    },
+    handlerDevice(row) {
+      this.showDevice = true
+      this.selectId1 = row.id
+      this.queryDetail2()
+    },
+    queryDetail2() {
+      const params = {
+        id: this.selectId1,
+        type: this.type
+      }
+      api.Query2Detail(params).then(res => {
+        this.detailList2 = []
+        if (res.data.length > 0) {
+          this.detailList2 = res.data
+        }
+      })
+    },
+    search3() {
+      const params = {
+        start: this.dateTime3.length > 0 ? this.dateTime3[0] : '',
+        end: this.dateTime3.length > 0 ? this.dateTime3[1] : ''
+      }
+      api.Query3(params).then(res => {
+        this.list3 = res.data
+      })
+    },
+    handlerWine(row) {
+      this.showWine = true
+      this.selectId1 = row.id
+      this.queryDetail3()
+    },
+    queryDetail3() {
+      const params = {
+        id: this.selectId1,
+        type: this.type
+      }
+      api.Query3Detail(params).then(res => {
+        this.detailList3 = []
+        if (res.data.length > 0) {
+          this.detailList3 = res.data
+        }
+      })
+    },
+    search4() {
+      const params = {
+        start: this.dateTime4.length > 0 ? this.dateTime4[0] : '',
+        end: this.dateTime4.length > 0 ? this.dateTime4[1] : ''
+      }
+      api.Query4(params).then(res => {
+        this.list4 = res.data
+      })
+    },
+    handlerWorker(row) {
+      this.showWorker = true
+      this.selectId1 = row.id
+      this.queryDetail4()
+    },
+    queryDetail4() {
+      const params = {
+        id: this.selectId1,
+        type: this.type
+      }
+      api.Query4Detail(params).then(res => {
+        this.detailList4 = []
+        if (res.data.length > 0) {
+          this.detailList4 = res.data
+        }
+      })
+    }
   }
 }
 </script>
 
 <style scoped>
-
+  .chart_content {
+    width: 100%;
+    height: 400px;
+  }
+  .chart_page {
+    width: 100%;
+    height: 500px;
+  }
 </style>

+ 474 - 3
src/views/super/order/trade/index.vue

@@ -1,13 +1,484 @@
 <template>
-  <div>trade order index</div>
+  <div class="box">
+    <el-card>
+      <div
+        slot="header"
+        class="clearfix"
+      >
+        <span>指标一览</span>
+      </div>
+      <div class="grid">
+        <div class="grid_item" />
+        <div class="grid_item" />
+        <div class="grid_item" />
+        <div class="grid_item" />
+        <div class="grid_item" />
+      </div>
+    </el-card>
+    <br>
+    <div class="app-container">
+      <div class="filter-container">
+        <el-input
+          v-model="trade.query.id"
+          placeholder="请输入用户ID"
+          style="width: 300px;"
+          class="filter-item"
+        />
+        <el-select v-model="trade.query.vip" class="filter-item">
+          <el-option label="不限" :value="-1" />
+          <el-option label="VIP" :value="1" />
+          <el-option label="非VIP" :value="0" />
+        </el-select>
+        <el-button
+          class="filter-item"
+          style="margin-left: 10px;"
+          type="primary"
+          icon="el-icon-search"
+          @click="handleQuery"
+        >
+          查询
+        </el-button>
+      </div>
+    </div>
+    <el-table
+      :key="tableKey"
+      v-loading="trade.loading"
+      :data="trade.list"
+      border
+      fit
+      highlight-current-row
+      style="width: 100%;"
+    >
+      <el-table-column
+        type="index"
+        label="序号"
+        width="80"
+        align="center"
+      />
+      <el-table-column
+        label="用户id"
+        width="300"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.id }}</span></template>
+      </el-table-column>
+      <el-table-column
+        label="消费次数"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.buy_count }}次</span></template>
+      </el-table-column>
+      <el-table-column
+        label="消费金额"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.buy_cost / 100 }}元</span></template>
+      </el-table-column>
+      <el-table-column
+        label="是否会员"
+        width="100"
+        align="center"
+      >
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.vip" type="success">会员</el-tag>
+          <el-tag v-else type="warning">非会员</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="退款次数"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.refund_count }}次</span></template>
+      </el-table-column>
+      <el-table-column
+        label="退款总额"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.refund_cost / 100 }}元</span></template>
+      </el-table-column>
+      <el-table-column
+        label="单笔消费最大消费"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.max_cost / 100 }}元</span></template>
+      </el-table-column>
+      <el-table-column
+        type="first"
+        label="注册时间"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.first }}</span></template>
+      </el-table-column>
+      <el-table-column
+        type="last"
+        label="最新活跃"
+        width="200"
+        align="center"
+      >
+        <template slot-scope="{ row }"><span>{{ row.last }}</span></template>
+      </el-table-column>
+      <el-table-column label="操作" fixed="right">
+        <template slot-scope="{ row }">
+          <el-button type="text" @click="open(row)">查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      hide-on-single-page
+      :total="trade.total"
+      :page.sync="trade.query.page"
+      :limit.sync="trade.query.limit"
+      @pagination="getList"
+    />
+    <el-drawer
+      size="50%"
+      :title="'用户'+showTitle+'历史订单'"
+      :visible.sync="showModal"
+      direction="rtl"
+      @close="resetUser"
+    >
+      <div class="box">
+        <div class="app-container">
+          <div class="filter-container">
+            <el-input
+              v-model="user.query.cond"
+              placeholder="请输入订单id,酒名"
+              style="width: 300px;"
+              class="filter-item"
+            />
+            <el-button
+              class="filter-item"
+              style="margin-left: 10px;"
+              type="primary"
+              icon="el-icon-search"
+              @click="handleQueryUser"
+            >
+              查询
+            </el-button>
+          </div>
+        </div>
+        <el-table
+          :key="tableKey"
+          v-loading="user.loading"
+          :data="user.list"
+          border
+          fit
+          highlight-current-row
+          style="width: 100%;"
+        >
+          <el-table-column
+            type="index"
+            label="序号"
+            width="80"
+            align="center"
+          />
+          <el-table-column
+            label="订单id"
+            width="300"
+            align="center"
+          >
+            <template slot-scope="{ row }"><span>{{ row.id }}</span></template>
+          </el-table-column>
+          <el-table-column
+            label="设备序列号"
+            width="200"
+            align="center"
+            prop="device"
+          />
+          <el-table-column
+            label="酒名"
+            width="100"
+            align="center"
+            prop="wine"
+          />
+          <el-table-column
+            label="出售单价"
+            width="200"
+            align="center"
+          >
+            <template slot-scope="{ row }"><span>{{ row.price / 100 }}元/两</span></template>
+          </el-table-column>
+          <el-table-column
+            label="出售量"
+            width="200"
+            align="center"
+          >
+            <template slot-scope="{ row }"><span>{{ row.weight }}两</span></template>
+          </el-table-column>
+          <el-table-column
+            label="出售价"
+            width="200"
+            align="center"
+          >
+            <template slot-scope="{ row }"><span>{{ row.cash / 100 }}元</span></template>
+          </el-table-column>
+          <el-table-column
+            label="退款金额"
+            width="200"
+            align="center"
+          >
+            <template slot-scope="{ row }"><span>{{ row.refund / 100 }}元</span></template>
+          </el-table-column>
+          <el-table-column
+            prop="reason"
+            label="退款原因"
+            width="200"
+            align="center"
+          />
+          <el-table-column
+            label="时间"
+            width="200"
+            align="center"
+            prop="time"
+          />
+          <el-table-column label="操作" fixed="right">
+            <template slot-scope="{ row }">
+              <el-button type="primary" @click="amount(row)">退款</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination
+          hide-on-single-page
+          :total="user.total"
+          :page.sync="user.query.page"
+          :limit.sync="user.query.limit"
+          @pagination="getUserList"
+        />
+      </div>
+    </el-drawer>
+    <el-dialog
+      width="30%"
+      :visible.sync="showOrder"
+      title="退款"
+      :close-on-click-modal="false"
+      center
+      @close="resetOrder"
+    >
+      <el-form ref="myForm" :model="form" label-width="120px">
+        <el-form-item label="订单id">
+          <el-input v-model="form.tid" disabled />
+        </el-form-item>
+        <el-form-item label="退款额" prop="cash" :rules="[{ required: true, message: '请输入退款额', trigger: 'blur' }, { validator: validateNumber, max: max, trigger: 'blur' }]">
+          <el-input v-model.number="form.cash" type="number" placeholder="请输入退款额">
+            <template #append>元</template>
+          </el-input>
+        </el-form-item>
+        <el-form-item label="退款原因">
+          <el-input v-model="form.reason" type="textarea" placeholder="请输入退款原因" />
+        </el-form-item>
+      </el-form>
+      <span
+        slot="footer"
+        class="dialog-footer"
+      >
+        <el-button @click="resetOrder">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="onSubmit"
+        >确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
+import api from '@/api/super/order/trade'
+import Pagination from '@/components/Pagination'
 export default {
-  name: 'TradeOrder'
+  name: 'TradeOrder',
+  components: { Pagination },
+  data() {
+    return {
+      tableKey: 0,
+      trade: {
+        list: [],
+        total: 0,
+        loading: true,
+        sort: {
+          time: 'ascending',
+          price: 'ascending',
+          degree: 'ascending',
+          density: 'ascending'
+        },
+        query: {
+          page: 1,
+          limit: 10,
+          vip: -1,
+          id: ''
+        }
+      },
+      showModal: false,
+      showTitle: '',
+      user: {
+        list: [],
+        total: 0,
+        loading: true,
+        query: {
+          page: 1,
+          limit: 10,
+          cond: '',
+          uid: ''
+        }
+      },
+      showOrder: false,
+      form: {
+        tid: '',
+        cash: '',
+        reason: ''
+      },
+      max: ''
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    getList() {
+      this.trade.loading = true
+      api.QueryUser(this.trade.query).then(res => {
+        for (let i = 0; i < res.data.list.length; ++i) {
+        //   res.data.list[i].time = new Date(res.data.list[i].time)
+          res.data.list[i].first = this.$moment(new Date(res.data.list[i].first)).format('YYYY-MM-DD HH:mm:ss')
+          res.data.list[i].last = this.$moment(new Date(res.data.list[i].last)).format('YYYY-MM-DD HH:mm:ss')
+        }
+        this.trade.list = res.data.list
+        this.trade.total = res.data.total
+        this.trade.loading = false
+        console.log(this.trade.list)
+      }).catch(msg => {
+        this.trade.loading = false
+        this.$notify({
+          title: '失败',
+          message: msg,
+          type: 'error',
+          duration: 0
+        })
+      })
+    },
+    handleQuery() {
+      this.trade.query.page = 1
+      this.getList()
+    },
+    open(row) {
+      this.showTitle = row.id
+      this.showModal = true
+      this.user.query.uid = row.id
+      this.getUserList()
+    },
+    getUserList() {
+      api.Query(this.user.query).then((res) => {
+        for (let i = 0; i < res.data.list.length; ++i) {
+          res.data.list[i].time = this.$moment(new Date(res.data.list[i].time)).format('YYYY-MM-DD HH:mm:ss')
+        }
+        this.user.list = res.data.list
+        this.user.total = res.data.total
+        this.user.loading = false
+      })
+    },
+    handleQueryUser() {
+      this.user.query.page = 1
+      this.getUserList()
+    },
+    resetUser() {
+      this.showModal = false
+      this.showTitle = ''
+      this.user = {
+        list: [],
+        total: 0,
+        loading: true,
+        query: {
+          page: 1,
+          limit: 10,
+          cond: '',
+          uid: ''
+        }
+      }
+    },
+    validateNumber(rule, value, callback) {
+      if (value <= 0) {
+        callback(new Error('退款额不能小于或等于0'))
+      } else if (value > rule.max) {
+        callback(new Error('退款额不能大于出售价'))
+      } else {
+        callback()
+      }
+    },
+    amount(row) {
+      this.showOrder = true
+      this.max = row.cash / 100
+      this.form = {
+        tid: row.id,
+        cash: row.refund / 100,
+        reason: row.reason
+      }
+    },
+    resetOrder() {
+      this.showOrder = false
+      this.form = {
+        tid: '',
+        cash: '',
+        reason: ''
+      }
+      this.max = ''
+    },
+    onSubmit() {
+      this.$refs['myForm'].validate((valid) => {
+        if (valid) {
+          const params = {
+            tid: this.form.tid,
+            cash: this.form.cash * 100,
+            reason: this.form.reason
+          }
+          api.Refund(params).then(() => {
+            this.$notify({
+              title: '成功',
+              message: '退款成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.resetOrder()
+            this.getUserList()
+            this.getList()
+          }).catch((msg) => {
+            this.$notify({
+              title: '失败',
+              message: msg,
+              type: 'error',
+              duration: 0
+            })
+          })
+        }
+      })
+    }
+  }
 }
 </script>
 
 <style scoped>
-
+.box {
+  box-sizing: border-box;
+  padding: 20px;
+}
+.grid {
+  width: 100%;
+  height: 150px;
+  display: flex;
+  align-items: center;
+}
+.grid_item {
+  flex: 1;
+  height: 150px;
+  box-sizing: border-box;
+  border-right: 1px solid #ddd;
+  padding-left: 20px;
+}
+.grid_item:last-child {
+  border: 0
+}
 </style>

+ 1 - 8
src/views/super/role/admin/index.vue

@@ -91,12 +91,6 @@
         width="250"
       />
       <el-table-column
-        label="账号"
-        prop="account"
-        align="center"
-        width="250"
-      />
-      <el-table-column
         label="订单总数"
         prop="order"
         align="center"
@@ -196,7 +190,7 @@
           <el-input
             v-model="detail.password"
             type="password"
-            placeholder="请输入度数"
+            placeholder="请输入密码"
           />
         </el-form-item>
       </el-form>
@@ -320,7 +314,6 @@ export default {
     getList() {
       this.admin.loading = true
       api.Query(this.admin.query).then(res => {
-        console.log(res)
         for (let i = 0; i < res.data.list.length; ++i) {
           res.data.list[i].time = new Date(res.data.list[i].time)
           res.data.list[i].first = this.$moment(new Date(res.data.list[i].first)).format('YYYY-MM-DD HH:mm:ss')