tremble 4 年之前
父节点
当前提交
08392e5568

+ 2 - 1
src/main.js

@@ -6,12 +6,13 @@ import App from './App'
 import router from './router'
 import ElementUI from 'element-ui'
 import 'element-ui/lib/theme-chalk/index.css'
-import http, {setHandle} from '@/util/http'
+import http, {setHandle, server} from '@/util/http'
 
 Vue.use(ElementUI)
 Vue.config.productionTip = false
 Vue.prototype.$http = http
 Vue.prototype.$bus = new Vue()
+Vue.prototype.$server = server
 
 setHandle(router)
 

+ 364 - 0
src/page/client/index.vue

@@ -0,0 +1,364 @@
+<template>
+  <div id="device-management">
+    <div class="device-management-body" v-loading.fullscreen.lock="fullscreenLoading">
+      <div class="order-management-body">
+        <div class="order-management-inner">
+          <div class="base-info">
+            <span>关键词:</span>
+            <el-input style="width:220px;" @keyup.enter.native="currentPage=1&&_getCameraData()" v-model="searchKey" placeholder="关键词"></el-input>
+            <el-button type="primary" @click="currentPage=1&&_getCameraData()" color='red'>搜索</el-button>
+            <el-button icon="el-icon-plus" type="primary" style="float: right;" @click="showCameraDialog" color='red'>添加客户</el-button>
+          </div>
+        </div>
+        <!-- 全部 -->
+        <div class="device-management_bottom">
+          <div class="order-management-table">
+            <el-table ref="order_table" class='e-table' :data="cameras" style="width: 100%">
+              <el-table-column prop="id" label="客户ID">
+              </el-table-column>
+              <el-table-column prop="companyName" label="客户名称">
+              </el-table-column>
+              <el-table-column prop="topLogo" label="顶部logo">
+                <template slot-scope="scope">
+                  <img :src="scope.row.topLogo" width="100%" height />
+                </template>
+              </el-table-column>
+              <el-table-column prop="floorLogo" label="地面logo">
+                <template slot-scope="scope">
+                  <img :src="scope.row.floorLogo" width="100%" height />
+                </template>
+              </el-table-column>
+              <el-table-column prop="qrLogo" label="二维码logo">
+                <template slot-scope="scope">
+                  <img :src="scope.row.qrLogo" width="100%" height />
+                </template>
+              </el-table-column>
+              <el-table-column label="初始logo">
+                <template slot-scope="scope">
+                  <span>{{scope.row.showLogo==1?'显示':'隐藏'}}</span>
+                </template>
+              </el-table-column>
+              <el-table-column width="300" label="创建时间">
+                <template slot-scope="scope">
+                  <div>{{scope.row.createTime}}</div>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作">
+                <template slot-scope="scope">
+                  <el-button type="text" @click="showDialog(scope.row)" class="edit_btn">编辑</el-button>
+                  <el-button type="text" @click="del(scope.row.id)" class="delete_btn">删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+          <div class="order-management-pagination">
+            <el-pagination  @current-change="handleCurrentChange" :current-page.sync="currentPage" :page-size="pagesize" layout="total, prev, pager, next, jumper" :total="total">
+            </el-pagination>
+          </div>
+        </div>
+        <el-dialog width="500px" title="添加客户" :visible.sync="companyVisible">
+          <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px">
+            <el-form-item label="客户名称" prop="companyName">
+              <el-input v-model="ruleForm.companyName"></el-input>
+            </el-form-item>
+            <el-form-item  label="客户账号" >
+              <el-select v-model="ruleForm.managerId" placeholder="请选择">
+                <el-option label="无" value="">无</el-option>
+                <el-option :label="item.userName" :value="item.id" v-for="(item,i) in clients" :key="i">{{item.userName}}</el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="默认注册相机">
+              <el-radio-group v-model="ruleForm.cameraDelete">
+                <el-radio :label="1">是</el-radio>
+                <el-radio :label="0">否</el-radio>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="顶部logo" prop="topLogo">
+              <el-upload
+                class="avatar-uploader"
+                :headers="{token}"
+                :action="uploadUrl"
+                :show-file-list="false"
+                :on-success="handleAvatarSuccess"
+                :before-upload="beforeAvatarUpload">
+                <div @click="currentImgType='topLogo'">
+                  <img v-if="ruleForm.topLogo" :src="ruleForm.topLogo" class="avatar">
+                  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+                </div>
+              </el-upload>
+            </el-form-item>
+            <el-form-item label="地面logo" prop="floorLogo">
+              <el-upload
+                class="avatar-uploader"
+                :headers="{token}"
+                :action="uploadUrl"
+                :show-file-list="false"
+                :on-success="handleAvatarSuccess"
+                :before-upload="beforeAvatarUpload">
+                <div @click="currentImgType='floorLogo'">
+                  <img v-if="ruleForm.floorLogo" :src="ruleForm.floorLogo" class="avatar">
+                  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+                </div>
+              </el-upload>
+            </el-form-item>
+            <el-form-item label="二维码logo" prop="qrLogo">
+              <el-upload
+                class="avatar-uploader"
+                :headers="{token}"
+                :action="uploadUrl"
+                :show-file-list="false"
+                :on-success="handleAvatarSuccess"
+                :before-upload="beforeAvatarUpload">
+                <div @click="currentImgType='qrLogo'">
+                  <img v-if="ruleForm.qrLogo" :src="ruleForm.qrLogo" class="avatar">
+                  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+                </div>
+              </el-upload>
+            </el-form-item>
+            <el-form-item label="初始logo">
+              <el-radio-group v-model="ruleForm.showLogo">
+                <el-radio :label="1">是</el-radio>
+                <el-radio :label="0">否</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-form>
+          <div slot="footer" class="dialog-footer">
+            <el-button @click="companyVisible = false">取 消</el-button>
+            <el-button type="primary" @click="submit">确 定</el-button>
+          </div>
+        </el-dialog>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+let tempForm = {
+  id: '',
+  createTime: '',
+  updateTime: '',
+  companyName: '',
+  topLogo: '',
+  floorLogo: '',
+  qrLogo: '',
+  showLogo: 1,
+  cameraDelete: 1,
+  managerId: ''
+}
+export default {
+  data () {
+    return {
+      expands: [],
+      expandedArr: [],
+      cameras: [],
+      currentPage: 1,
+      key_input: '',
+      fullscreenLoading: false,
+      searchKey: '',
+      total: 0,
+      uploadUrl: this.$server + '/manager/company/uploadLogoImg',
+      token: sessionStorage.getItem('token'),
+      // expressNum_input: "",
+      searchDate: [],
+      searchOrderNumber: '',
+      searchPhone: '',
+      searchExpressNum: '',
+      hasClickSearch: false,
+      tabIndex: 0,
+      companyVisible: false,
+      ruleForm: tempForm,
+      currentImgType: '',
+      rules: {
+        companyName: [
+          { required: true, message: '请输入客户名称', trigger: 'blur' }
+        ]
+        // topLogo: [
+        //   { required: true, message: '请上传顶部logo', trigger: 'change' }
+        // ],
+        // floorLogo: [
+        //   { required: true, message: '请上传地面logo', trigger: 'change' }
+        // ],
+        // qrLogo: [
+        //   { required: true, message: '请上传二维码logo', trigger: 'change' }
+        // ]
+      },
+      cameraInfo: {
+        wifi: '',
+        type: '',
+        address: '',
+        initPoint: '',
+        orderNum: ''
+      },
+
+      formLabelWidth: '30%',
+      value2: true,
+      currentChildName: '',
+      currentDeviceId: '',
+      currentBalance: '',
+      pagesize: 10,
+      clients: []
+    }
+  },
+  watch: {
+    currentPage () {
+      this._getCameraData()
+    }
+  },
+  methods: {
+    async getclientData () {
+      let res = await this.$http.post('/manager/user/managerList')
+      if (res.code === 0) {
+        this.clients = res.data
+      }
+    },
+    del (id) {
+      this.$confirm('此操作将删除该条数据, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          this.fullscreenLoading = true
+          let res = await this.$http.post('/manager/company/deleteById', {
+            id: id
+          })
+          if (res.code === 0) {
+            this.$message({
+              type: 'success',
+              message: '删除成功!'
+            })
+            this._getCameraData()
+          } else {
+            this.$message({
+              type: 'error',
+              message: res.msg
+            })
+            this._getCameraData()
+          }
+          this.fullscreenLoading = false
+        })
+        .catch(() => {
+          this.$message({
+            type: 'info',
+            message: '已取消删除'
+          })
+          this.fullscreenLoading = false
+        })
+    },
+    async _getCameraData () {
+      this.fullscreenLoading = true
+      if (!Number(this.currentPage)) this.currentPage = 1
+      let res = await this.$http.post('/manager/company/list', {
+        pageNum: this.currentPage,
+        pageSize: this.pagesize,
+        companyName: this.searchKey
+      })
+      this.fullscreenLoading = false
+      if (res.code === 0) {
+        let temp = res.data.list
+        for (var i = 0; i < temp.length; i++) {
+          temp[i]['userName'] = temp[i]['userName'] ? temp[i]['userName'] : '未绑定'
+          temp[i]['activatedTime'] = temp[i]['activatedTime'] ? new Date(temp[i]['activatedTime']).format('yyyy-MM-dd hh:mm:ss') : '/'
+        }
+        this.cameras = temp
+        this.total = res.data.total ? res.data.total : this.total
+      }
+    },
+    handleCurrentChange (val) {
+      this.currentPage = val
+    },
+    handleAvatarSuccess (res, file) {
+      this.ruleForm[this.currentImgType] = res.data
+    },
+    beforeAvatarUpload (file) {
+      const isLt2M = file.size / 1024 / 1024 < 5
+
+      if (!isLt2M) {
+        this.$message.error('上传头像图片大小不能超过 5MB!')
+      }
+      return isLt2M
+    },
+    showDialog (row) {
+      this.ruleForm = row
+      this.companyVisible = true
+    },
+
+    submit () {
+      this.$refs['ruleForm'].validate((valid) => {
+        if (valid) {
+          this._editCompany()
+        } else {
+          return false
+        }
+      })
+    },
+
+    async _editCompany () {
+      let {
+        id = '',
+        createTime,
+        updateTime,
+        companyName,
+        topLogo,
+        floorLogo,
+        qrLogo,
+        showLogo,
+        managerId,
+        cameraDelete
+      } = this.ruleForm
+
+      this.fullscreenLoading = true
+      let res = await this.$http.post('/manager/company/insertOrUpdate', {
+        id,
+        createTime,
+        updateTime,
+        companyName,
+        topLogo,
+        floorLogo,
+        qrLogo,
+        showLogo,
+        managerId,
+        cameraDelete
+      })
+      this.fullscreenLoading = false
+      if (res.code === 0) {
+        this.$alert('该客户信息已成功添加入库', '添加成功', {
+          confirmButtonText: '确定'
+        })
+        this._getCameraData()
+        this.ruleForm = tempForm
+        this.companyVisible = false
+      } else {
+        this.$alert(res.msg, '操作失败', {
+          confirmButtonText: '确定'
+        })
+      }
+    },
+    showCameraDialog (row) {
+      this.ruleForm = tempForm
+      this.companyVisible = true
+    }
+  },
+  created () {
+    this._getCameraData()
+    this.getclientData()
+  }
+}
+
+</script>
+<style lang="css" scoped>
+@import './style.css';
+</style>
+<style type="text/css">
+.el-table__expand-icon>i {
+  display: none !important;
+}
+
+.edit_btn span {
+  color: #09e1c0
+}
+
+.delete_btn span {
+  color: #f56c6c
+}
+
+</style>

+ 194 - 0
src/page/client/style.css

@@ -0,0 +1,194 @@
+.device-management-body {
+  width: 100%;
+  float: left;
+  /*  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  -webkit-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);*/
+  /*border: 1px solid #ebeef5;*/
+}
+
+.order_check_row {
+  display: flex;
+  width: 100%;
+}
+
+.product_info {
+  width: 50%;
+  flex-direction: column;
+  display: flex;
+  padding: 20px;
+  background: #fff;
+}
+
+.order_info {
+  width: 50%;
+  padding: 20px;
+  margin-left: 20px;
+  background: #fff;
+}
+
+.product_info_title {
+  text-align: left;
+  font-weight: 700;
+  margin-bottom: 20px;
+}
+
+.product_info_body {
+  margin-left: 30px;
+  display: flex;
+}
+
+.product_info_body_img {
+  width: 110px;
+  height: 110px;
+  border: 1px solid #ddd;
+}
+
+.product_img {
+  margin: 5px auto;
+  width: 100px;
+  height: 100px;
+}
+
+.product_info_body_info {
+  margin-left: 50px;
+}
+
+.product_info_body_info_item {
+  line-height: 27px;
+  text-align: left;
+}
+
+.product_info_body_info_item_title {
+  width: 100px;
+  display: inline-block;
+  margin-right: 20px;
+  font-weight: 700;
+}
+
+.order_info_title {
+  text-align: left;
+  font-weight: 700;
+  margin-bottom: 20px;
+}
+
+.order_info_body {
+  margin-left: 30px;
+  text-align: left;
+}
+
+/* .order_info_body_info {} */
+
+.order_info_body_info_item {
+  line-height: 23px;
+  padding: 10px 0;
+  border-bottom: 1px solid #f5f5f5;
+  text-align: left;
+}
+
+.order_info_body_info_item_title {
+  width: 100px;
+  display: inline-block;
+  margin-right: 20px;
+  font-weight: 700;
+}
+
+.order-management-body {
+  width: 100%;
+  margin: 30px 0 20px 0;
+  float: left;
+}
+
+.order-management-inner {
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  -webkit-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  /*border: 1px solid #ebeef5;*/
+  padding: 20px;
+  background: #fff;
+  border-radius: 5px;
+}
+
+.base-info {
+  margin: 20px 0;
+}
+
+.device-management_bottom {
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  -webkit-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  /*border: 1px solid #ebeef5;*/
+  margin-top: 30px;
+  background: #fff;
+  border-radius: 5px;
+  padding: 20px 0;
+}
+
+.device-management_tab {
+  margin: 0 0 20px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.device-management_tab ul {
+  display: inline-block;
+}
+
+.device-management_tab li {
+  display: inline-block;
+  cursor: pointer;
+  color: #999;
+  line-height: 1;
+}
+
+.device-management_tab_li_active {
+  color: #000!important;
+  font-weight: bold;
+}
+
+.order-management-table {
+  margin: 0 20px;
+}
+
+.order-management-pagination {
+  padding: 20px 20px 0;
+  position: relative;
+  text-align: right;
+}
+
+.el-select {
+  width: 340px!important;
+}
+
+.el-input {
+  width: 340px;
+}
+
+
+
+.avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+.avatar-uploader .el-upload:hover {
+  border-color: #409EFF;
+}
+
+.avatar-uploader-icon {
+  font-size: 28px;
+  border: 1px dashed #d9d9d9;
+  color: #8c939d;
+  width: 100px;
+  height: 100px;
+  line-height: 100px;
+  text-align: center;
+}
+.avatar {
+  width: 100px;
+  height: 100px;
+  display: block;
+}

+ 23 - 5
src/page/device/index.vue

@@ -29,6 +29,11 @@
               </el-table-column>
               <el-table-column prop="own" label="出货类型">
               </el-table-column>
+              <el-table-column prop="companyName" label="客户名称">
+                <template slot-scope="scope">
+                  <div>{{scope.row.companyName||'-'}}</div>
+                </template>
+              </el-table-column>
               <el-table-column prop="balance" label="当前余额(点)">
               </el-table-column>
               <el-table-column label="操作">
@@ -102,6 +107,11 @@
             <el-form-item label="订单号" prop="orderNum">
               <el-input v-model="ruleForm.orderNum"></el-input>
             </el-form-item>
+            <el-form-item label="客户名称" prop="own">
+              <el-select v-model="ruleForm.companyId" placeholder="请选择">
+                <el-option v-for="(item,i) in companyList" :key="i" :label="item.companyName" :value="item.id">{{item.companyName}}</el-option>
+              </el-select>
+            </el-form-item>
           </el-form>
           <div slot="footer" class="dialog-footer">
             <el-button @click="cameraVisible = false">取 消</el-button>
@@ -167,7 +177,8 @@ export default {
         type: [],
         own: [],
         snCode: '',
-        orderNum: ''
+        orderNum: '',
+        companyId: ''
       },
       rules: {
         wifi: [
@@ -193,9 +204,10 @@ export default {
         type: '',
         address: '',
         initPoint: '',
-        orderNum: ''
+        orderNum: '',
+        companyId: ''
       },
-
+      companyList: [],
       formLabelWidth: '30%',
       value2: true,
       currentChildName: '',
@@ -245,7 +257,6 @@ export default {
       }
     },
     handleCurrentChange (val) {
-      console.log('----', val)
       this.currentPage = val
     },
     showDialog (row) {
@@ -256,8 +267,11 @@ export default {
       this.currentBalance = row.balance
       this.dialogFormVisible = true
     },
+    async getCompanyList () {
+      let result = await this.$http.post('/manager/company/listAll')
+      this.companyList = result.data
+    },
     async _unbindDevice (row) {
-      let cameraId = row.cameraId
       this.$confirm('确定把该设备从账号中解除绑定', '解绑设备', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
@@ -344,6 +358,7 @@ export default {
         own,
         type,
         snCode,
+        companyId,
         orderNum: orderSn
       } = this.ruleForm
       if (wifiName === '' || childName === '' || snCode === '' || balance === '' || own === '' || type === '') {
@@ -356,6 +371,7 @@ export default {
         wifiName,
         orderSn,
         snCode,
+        companyId,
         balance: Number(balance),
         type: Number(type),
         own
@@ -373,6 +389,7 @@ export default {
         this.ruleForm.snCode = ''
         this.ruleForm.type = ''
         this.ruleForm.initPoint = ''
+        this.ruleForm.companyId = ''
 
         this.cameraVisible = false
       } else {
@@ -387,6 +404,7 @@ export default {
   },
   created () {
     this._getCameraData()
+    this.getCompanyList()
   }
 }
 

+ 0 - 1
src/page/distributor/query-list/index.vue

@@ -1,6 +1,5 @@
 <template>
   <div class="layout">
-    {{this.pag.current}}
     <el-table :data="users" style="width: 100%" class="creamtable table" :highlight-current-row="false"  v-loading="loading" :header-cell-class-name="tableHeaderClassName">
       <el-table-column label="">
         <el-table-column prop="id" label="序号" class="test">

+ 13 - 18
src/page/edition/index.vue

@@ -183,12 +183,12 @@ export default {
       this.active = item
     },
     async updateAduitStatus (id, state) {
-      let m = state === 'A' ? 'I' : 'A';
-      let data = (await this.$http.get('/manager/goods/version/update/'+id+'/'+m))
+      let m = state === 'A' ? 'I' : 'A'
+      let data = (await this.$http.get('/manager/goods/version/update/' + id + '/' + m))
       this._searchOrderData(this.currentPage)
     },
     async updateMaker () {
-      var formData = new FormData();
+      var formData = new FormData()
       formData.append('version', this.active.version)
       formData.append('description', this.active.description)
       formData.append('file', this.$refs.file.files[0])
@@ -220,7 +220,7 @@ export default {
           callback: action => {
 
           }
-        });
+        })
       }
 
       let data = await this.$http.post('/manager/order/confirmDelivery', {
@@ -301,7 +301,7 @@ export default {
       // console.log(searchDate,searchPhone,searchExpressNum,searchOrderNumber)
       this.fullscreenLoading = true
       let status = this.status
-      
+
       let para = {
         pageNum: page - 1,
         type: status,
@@ -312,7 +312,6 @@ export default {
         pageSize: 10
       }
 
-      
       let url = '/manager/goods/version/list'
       let method = 'get'
       let data
@@ -320,7 +319,7 @@ export default {
         url = '/manager/goods/version/search'
         method = 'post'
       }
-      
+
       console.log(method, para)
       if (method === 'get') {
         let paras = []
@@ -333,15 +332,11 @@ export default {
         })
 
         para = paras.join('&')
-        data = (await this.$http[method](url+'?'+para)).data
+        data = (await this.$http[method](url + '?' + para)).data
       } else {
         data = (await this.$http[method](url, para)).data
       }
 
-
-
-
-
       this.fullscreenLoading = false
       let temp = data.list
       for (var i = 0; i < temp.length; i++) {
@@ -365,12 +360,12 @@ export default {
       let status = this.status
 
       let data = {
-        "type": this.status,
-        "startDate": date1,
-        "endDate": date2,
-        "orderSn": orderNum,
-        "phoneNum": userName,
-        "expressNum": expressNum
+        'type': this.status,
+        'startDate': date1,
+        'endDate': date2,
+        'orderSn': orderNum,
+        'phoneNum': userName,
+        'expressNum': expressNum
       }
       this.fullscreenLoading = true
 

+ 2 - 1
src/page/layout/slide.vue

@@ -57,7 +57,8 @@ export default {
         children: [
           { text: '场景管理', link: {name: 'scene'} },
           { text: '反馈消息', link: {name: 'feedback'} },
-          { text: '设备管理', link: {name: 'device'} }
+          { text: '设备管理', link: {name: 'device'} },
+          { text: '客户管理', link: {name: 'client'} }
         ],
         top: 154
       },

+ 162 - 187
src/page/scene/index.vue

@@ -5,11 +5,11 @@
         <div class="base-info">
           <span>关键词:</span>
           <el-input
-            @keyup.enter.native="currentPage=1&&_getSceneData()"
+            @keyup.enter.native="()=>{currentPage=1;_getSceneData()}"
             v-model="searchKey"
             placeholder="关键词"
           ></el-input>
-          <el-button type="primary" @click="currentPage=1&&_getSceneData()" color="red">搜索</el-button>
+          <el-button type="primary" @click="()=>{currentPage=1;_getSceneData()}" color="red">搜索</el-button>
           <span style="margin-left:10px;">SN码:</span>
           <el-input
             @keyup.enter.native="getSceneBySN"
@@ -17,10 +17,11 @@
             placeholder="输入SN码下载场景数据"
           ></el-input>
           <el-button type="primary" @click="getSceneBySN" color="red">下载场景数据</el-button>
+
         </div>
       </div>
       <!-- 全部 -->
-      <div class="scene-management_bottom" v-if="tabIndex==0">
+      <div class="scene-management_bottom">
         <div class="order-management-table">
           <div class="scene-management_tab">
             <ul>
@@ -37,10 +38,12 @@
                 >/</span>
               </li>
             </ul>
-            <!-- <div style="float: right;vertical-align: middle;">
-              <el-button type="primary" icon="el-icon-upload" @click="" color='red'>恢复</el-button>
-              <el-button type="danger" icon="el-icon-delete" @click="" color='red'>删除</el-button>
-            </div>-->
+            <div style="float: right;vertical-align: middle;">
+              <el-button type="primary" @click="openTransfer" color="red">迁移</el-button>
+              <el-button type="success" @click="downloadMultipleScene" color="red">下载</el-button>
+              <el-button type="danger" @click="_deleMultipleScene" color="red">删除</el-button>
+
+            </div>
           </div>
 
           <el-table
@@ -49,7 +52,12 @@
             class="e-table"
             :data="scenes"
             style="width: 100%"
+            @selection-change="handleSelectionChange"
           >
+           <el-table-column
+            type="selection"
+            width="55">
+          </el-table-column>
             <el-table-column label="场景封面" width="120">
               <template slot-scope="scope">
                 <a :href="scope.row.webSite" target="_blank" style="cursor: pointer;">
@@ -89,7 +97,7 @@
             <el-table-column prop="sceneType" label="平台展示">
               <template slot-scope="scope">
                 <el-switch
-                  @change="_updateSceneStatus(scope.row.id,scope.row.status)"
+                  @change="_updateSceneStatus(scope.row.num,scope.row.status)"
                   v-model="scope.row.statusBoo"
                   active-color="#13ce66"
                   inactive-color="#ff4949"
@@ -104,7 +112,7 @@
                   @click="_showDownloadSelect(scope.row.num);"
                   class="download_btn"
                 >下载</el-button>
-                <el-button type="text" @click="_deleScene(scope.row.id)" class="delete_btn">删除</el-button>
+                <el-button type="text" @click="_deleScene(scope.row.num)" class="delete_btn">删除</el-button>
               </template>
             </el-table-column>
           </el-table>
@@ -119,172 +127,26 @@
           ></el-pagination>
         </div>
       </div>
-      <!-- 展示中 -->
-      <div class="scene-management_bottom" v-if="tabIndex==1">
-        <div class="order-management-table">
-          <div class="scene-management_tab">
-            <ul>
-              <li
-                v-for="(item,index) in tabs"
-                :key="index"
-                :class="{'scene-management_tab_li_active':item.idx==tabIndex}"
-                @click="clickTabItem(item.idx)"
-              >
-                {{item.name}}
-                <span
-                  v-if="item.idx != -2"
-                  style="margin:0 10px;color: #999;font-weight: normal;"
-                >/</span>
-              </li>
-            </ul>
-            <!-- <div style="float: right;vertical-align: middle;">
-              <el-button type="primary" icon="el-icon-upload" @click="" color='red'>恢复</el-button>
-              <el-button type="danger" icon="el-icon-delete" @click="" color='red'>删除</el-button>
-            </div>-->
-          </div>
-          <el-table
-            key="order_table1"
-            ref="order_table1"
-            class="e-table"
-            :data="scenes"
-            style="width: 100%"
-          >
-            <el-table-column label="场景封面" width="120">
-              <template slot-scope="scope">
-                <a :href="scope.row.webSite" target="_blank" style="cursor: pointer;">
-                  <img :src="scope.row.thumb" width="100%" height />
-                </a>
-              </template>
-            </el-table-column>
-            <el-table-column prop="sceneType" label="分类"></el-table-column>
-            <el-table-column prop="sceneName" width="200" label="标题"></el-table-column>
-            <el-table-column label="拍摄时间" width="200">
-              <template slot-scope="scope">
-                <div>{{new Date(scope.row.createTime).format('yyyy-MM-dd hh:mm:ss')}}</div>
-              </template>
-            </el-table-column>
-            <el-table-column label="经纬度" width="200">
-              <template slot-scope="scope">
-                <div v-if="scope.row.longitude">经度:{{scope.row.longitude}}</div>
-                <div v-if="scope.row.latitude">维度:{{scope.row.latitude }}</div>
-                <span v-if="!scope.row.latitude&&!scope.row.longitude">/</span>
-              </template>
-            </el-table-column>
-            <el-table-column prop="childName" width="150" label="设备ID"></el-table-column>
-            <el-table-column prop="userName" width="150" label="用户名"></el-table-column>
-            <el-table-column prop="scenekey" label="权限"></el-table-column>
-            <el-table-column prop="viewCount" label="浏览数"></el-table-column>
-            <el-table-column prop="sceneType" label="平台展示">
-              <template slot-scope="scope">
-                <el-switch
-                  @change="_updateSceneStatus(scope.row.id,scope.row.status)"
-                  v-model="scope.row.statusBoo"
-                  active-color="#13ce66"
-                  inactive-color="#ff4949"
-                ></el-switch>
-              </template>
-            </el-table-column>
-            <el-table-column prop="status" label="操作">
-              <template slot-scope="scope">
-                <el-button type="text" @click="_deleScene(scope.row.id)" class="delete_btn">删除</el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-        </div>
-        <div class="order-management-pagination">
-          <el-pagination
-            @current-change="handleCurrentChange"
-            :current-page.sync="currentPage"
-            :page-size="10"
-            layout="total, prev, pager, next, jumper"
-            :total="total"
-          ></el-pagination>
-        </div>
-      </div>
-      <!-- 已隐藏 -->
-      <div class="scene-management_bottom" v-if="tabIndex==-2">
-        <div class="order-management-table">
-          <div class="scene-management_tab">
-            <ul>
-              <li
-                v-for="(item,index) in tabs"
-                :key="index"
-                :class="{'scene-management_tab_li_active':item.idx==tabIndex}"
-                @click="clickTabItem(item.idx)"
-              >
-                {{item.name}}
-                <span
-                  v-if="item.idx != -2"
-                  style="margin:0 10px;color: #999;font-weight: normal;"
-                >/</span>
-              </li>
-            </ul>
-            <!-- <div style="float: right;vertical-align: middle;">
-              <el-button type="primary" icon="el-icon-upload" @click="" color='red'>恢复</el-button>
-              <el-button type="danger" icon="el-icon-delete" @click="" color='red'>删除</el-button>
-            </div>-->
-          </div>
-          <el-table
-            key="order_table2"
-            ref="order_table2"
-            class="e-table"
-            :data="scenes"
-            style="width: 100%"
-          >
-            <el-table-column label="场景封面" width="120">
-              <template slot-scope="scope">
-                <a :href="scope.row.webSite" target="_blank" style="cursor: pointer;">
-                  <img :src="scope.row.thumb" width="100%" height />
-                </a>
-              </template>
-            </el-table-column>
-            <el-table-column prop="sceneType" label="分类"></el-table-column>
-            <el-table-column prop="sceneName" width="200" label="标题"></el-table-column>
-            <el-table-column label="拍摄时间" width="200">
-              <template slot-scope="scope">
-                <div>{{new Date(scope.row.createTime).format('yyyy-MM-dd hh:mm:ss')}}</div>
-              </template>
-            </el-table-column>
-            <el-table-column label="经纬度" width="200">
-              <template slot-scope="scope">
-                <div v-if="scope.row.longitude">经度:{{scope.row.longitude}}</div>
-                <div v-if="scope.row.latitude">维度:{{scope.row.latitude }}</div>
-                <span v-if="!scope.row.latitude&&!scope.row.longitude">/</span>
-              </template>
-            </el-table-column>
-            <el-table-column prop="childName" width="150" label="设备ID"></el-table-column>
-            <el-table-column prop="userName" width="150" label="用户名"></el-table-column>
-            <el-table-column prop="scenekey" label="权限"></el-table-column>
-            <el-table-column prop="viewCount" label="浏览数"></el-table-column>
-            <el-table-column prop="sceneType" label="平台展示">
-              <template slot-scope="scope">
-                <el-switch
-                  @change="_updateSceneStatus(scope.row.id,scope.row.status)"
-                  v-model="scope.row.statusBoo"
-                  active-color="#13ce66"
-                  inactive-color="#ff4949"
-                ></el-switch>
-              </template>
-            </el-table-column>
-            <el-table-column prop="status" label="操作">
-              <template slot-scope="scope">
-                <el-button type="text" @click="_deleScene(scope.row.id)" class="delete_btn">删除</el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-        </div>
-        <div class="order-management-pagination">
-          <el-pagination
-            @current-change="handleCurrentChange"
-            :current-page.sync="currentPage"
-            :page-size="10"
-            layout="total, prev, pager, next, jumper"
-            :total="total"
-          ></el-pagination>
-        </div>
-      </div>
     </div>
 
+    <el-dialog width="450px" title="迁移场景" :visible.sync="dialogTransferVisible">
+          <el-form >
+            <el-form-item label="当前SN码:" width="100%">
+                <div style="max-height:300px;overflow: auto;">
+                  <p v-for="(item,i) in multipleSelection" :key="i">{{item.snCode||item.childName}}</p>
+                </div>
+            </el-form-item>
+
+            <el-form-item label="迁往SN码:" width="100%">
+              <el-input v-model="transferSN"></el-input>
+            </el-form-item>
+          </el-form>
+          <div slot="footer" class="dialog-footer">
+            <el-button @click="dialogTransferVisible = false">取 消</el-button>
+            <el-button type="primary" @click="transferScene">确 定</el-button>
+          </div>
+        </el-dialog>
+
     <el-dialog
       width="500px"
       title="场景下载"
@@ -339,8 +201,8 @@ const _sceneTypeName = {
 }
 
 // const serverName = 'https://test.4dkankan.com'
-// const serverName = 'http://192.168.0.208:8887'
-const serverName = 'https://www.4dage.com'
+const serverName = 'http://192.168.0.28:8887'
+// const serverName = 'https://www.4dage.com'
 
 export default {
   data () {
@@ -357,6 +219,7 @@ export default {
         timer: 0
       },
       downloadDialogVisible: false,
+      dialogTransferVisible: false,
       progressColor: '#09e1c0',
       tabs: [
         { name: '全部', idx: 0 },
@@ -381,7 +244,9 @@ export default {
       tabIndex: 0,
       pageSize: 10,
       value2: true,
-      downloadOptions: {}
+      multipleSelection: '',
+      downloadOptions: {},
+      transferSN: ''
     }
   },
   watch: {
@@ -397,12 +262,15 @@ export default {
       this.fullscreenLoading = true
       await this.$http.post('/manager/scene/updateSceneType', {
         sceneType: item.sceneType,
-        sceneId: item.id
+        sceneNum: item.num
       })
 
       this._getSceneData()
       this.fullscreenLoading = false
     },
+    handleSelectionChange (val) {
+      this.multipleSelection = val
+    },
 
     handleCurrentChange (val) {
       let page = val
@@ -419,10 +287,38 @@ export default {
       this.total = 0
       this.hasClickSearch = false
       this.currentPage = 0
-      this.$refs.searchKey.currentValue = this.key_input = ''
+      this.$refs.searchKey = this.key_input = ''
       this._getSceneData(1)
     },
 
+    async downloadMultipleScene () {
+      if (!this.multipleSelection && this.multipleSelection.length === 0) {
+        return this.$alert('请选择场景', '提示', {
+          confirmButtonText: '确定'
+        })
+      }
+      let arr = []
+      arr = this.multipleSelection.map((item) => item.num)
+      this.fullscreenLoading = true
+
+      this.$confirm(`此操作将下载您选择的${arr.length}个场景, 是否继续?`, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(() => {
+          this._downloadScene('', arr, this.downloadOptions.isTiles)
+        })
+        .catch(() => {
+          this.$message({
+            type: 'info',
+            message: '已取消'
+          })
+          this.fullscreenLoading = false
+        })
+      console.log(arr)
+    },
+
     async getSceneBySN () {
       if (!this.snKey) {
         return
@@ -461,6 +357,38 @@ export default {
         })
     },
 
+    openTransfer () {
+      if (!this.multipleSelection && this.multipleSelection.length === 0) {
+        return this.$alert('请选择场景', '提示', {
+          confirmButtonText: '确定'
+        })
+      }
+      this.dialogTransferVisible = true
+    },
+
+    async transferScene () {
+      let sceneNumArr = this.multipleSelection.map(item => {
+        return item.num
+      })
+
+      let res = await this.$http.post('/manager/scene/moveScene', {
+        snCode: this.transferSN,
+        sceneNum: sceneNumArr.join(',')
+      })
+      if (res.code === 0) {
+        this.$message({
+          type: 'success',
+          message: '迁移成功!'
+        })
+        this._getSceneData()
+      } else {
+        this.$alert(`迁移失败,${res.msg}`, '提示', {
+          confirmButtonText: '确定'
+        })
+      }
+      this.dialogTransferVisible = false
+    },
+
     async _getSceneData () {
       this.fullscreenLoading = true
       let status = this.tabIndex === 0 ? null : this.tabIndex
@@ -503,7 +431,7 @@ export default {
           }
         }
         this.scenes = temp
-        this.total = res.data.total ? res.data.total : this.total
+        this.total = res.data.total
       }
     },
 
@@ -530,7 +458,7 @@ export default {
       this.fullscreenLoading = true
       await this.$http.post('/manager/scene/updateStatus', {
         type: tempStatus,
-        sceneId: num
+        sceneNum: num
       })
 
       this._getSceneData()
@@ -571,7 +499,8 @@ export default {
         let temp = []
         res.forEach(ele => {
           if (ele && ele.code === 0) {
-            ele.data.sceneScheme = 1 // 禁止本地端放大缩小
+            this.$http.get(`/scene/addDownloadNum?sceneNum=${ele.data.num}&t=${new Date().getTime()}`)
+            ele.data.sceneScheme = ele.data.sceneScheme === 11 ? 2 : 1 // 禁止本地端放大缩小
             temp.push({
               sceneCode: ele.data.num,
               sceneInfo: JSON.stringify(ele)
@@ -581,7 +510,6 @@ export default {
           }
         })
 
-        console.log('------temp----', temp)
         if (temp.length <= 0) {
           this.downloadDialogVisible = false
           this.fullscreenLoading = false
@@ -592,12 +520,18 @@ export default {
         }
 
         let snCode = SNCode ? ('SN_' + SNCode) : temp[0].sceneCode
+        let version = ''
+        try {
+          console.log(JSON.parse(temp[0].sceneInfo))
+
+          version = JSON.parse(temp[0].sceneInfo).data.buildType.toLowerCase() === 'v2' ? 'v2/' : ''
+        } catch (error) {
+        }
 
-        console.log('-snCode---', snCode)
         this.downloadDialogVisible = false
         this.fullscreenLoading = false
         this.$http
-          .post(`${serverName}/downloadData/`, {
+          .post(`${serverName}/downloadData/${version}`, {
             sceneCodeArr: temp,
             isTiles: isTiles,
             snCode
@@ -622,7 +556,7 @@ export default {
               this.download.timer = setInterval(() => {
                 this.$http
                   .get(
-                    `${serverName}/downloadData/process?snCode=${snCode}`
+                    `${serverName}/downloadData/process/${version}?snCode=${snCode}`
                   )
                   .then(resp => {
                     console.log(resp)
@@ -677,7 +611,48 @@ export default {
       a.click()
       document.body.removeChild(a)
     },
-
+    _deleMultipleScene () {
+      if (!this.multipleSelection && this.multipleSelection.length === 0) {
+        return this.$alert('请选择场景', '提示', {
+          confirmButtonText: '确定'
+        })
+      }
+      let sceneIdArr = this.multipleSelection.map(item => {
+        return item.num
+      })
+      this.$confirm('此操作将删除您选择的多个场景, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          this.fullscreenLoading = true
+          let res = await this.$http.post('/manager/scene/delete', {
+            sceneNum: sceneIdArr.join(',')
+          })
+          if (res.code === 0) {
+            this.$message({
+              type: 'success',
+              message: '删除成功!'
+            })
+            this._getSceneData()
+          } else {
+            this.$message({
+              type: 'error',
+              message: res.msg
+            })
+            this._getSceneData()
+          }
+          this.fullscreenLoading = false
+        })
+        .catch(() => {
+          this.$message({
+            type: 'info',
+            message: '已取消删除'
+          })
+          this.fullscreenLoading = false
+        })
+    },
     _deleScene (num) {
       this.$confirm('此操作将删除该场景, 是否继续?', '提示', {
         confirmButtonText: '确定',
@@ -687,7 +662,7 @@ export default {
         .then(async () => {
           this.fullscreenLoading = true
           let res = await this.$http.post('/manager/scene/delete', {
-            sceneId: num
+            sceneNum: num
           })
           if (res.code === 0) {
             this.$message({

+ 50 - 48
src/page/statistics/index.vue

@@ -52,22 +52,22 @@ require('echarts/lib/component/legend')
 require('echarts/lib/component/legendScroll')
 
 const data = {
-	"header": {
-		"account_type": 1,
-		"password": "4DAge2018",
-		"token": "17a1e010f1be38abead0066b2b02cb4c",
-		"username": "四维时代"
-	},
-	"body": {
-		"target": 4,
-		"siteId": "13790587",
-		"method": "visit/toppage/a",
-		"start_date": "20160501",
-		"end_date": (new Date()).format('yyyyMMdd'),
-		"metrics": "pv_count,visitor_count",
-    "search_word": "123",
-    "order": "desc"
-	}
+  'header': {
+    'account_type': 1,
+    'password': '4DAge2018',
+    'token': '17a1e010f1be38abead0066b2b02cb4c',
+    'username': '四维时代'
+  },
+  'body': {
+    'target': 4,
+    'siteId': '13790587',
+    'method': 'visit/toppage/a',
+    'start_date': '20160501',
+    'end_date': (new Date()).format('yyyyMMdd'),
+    'metrics': 'pv_count,visitor_count',
+    'search_word': '123',
+    'order': 'desc'
+  }
 }
 
 export default {
@@ -111,7 +111,9 @@ export default {
           let ikey = ~key.indexOf('PC.html') ? 'PC' : (~key.indexOf('Mobile.html') ? 'Mobile' : null)
           if (!data[ik]) {
             data[ik] = {
-              count: 0, PC: 0, Mobile: 0,
+              count: 0,
+              PC: 0,
+              Mobile: 0,
               children: {wx_friends: 0, wx_friend: 0, weibo: 0, qq_zone: 0, qq: 0, default: 0}
             }
           }
@@ -159,27 +161,27 @@ export default {
 
       data.legend.data = ['朋友圈', '微信好友', 'QQ好友', 'QQ空间', '微博', '直接打开']
       data.title.text = scene + '场景打开方式占比'
-      data.series[0].name = '打开场景'+scene+'方式'
+      data.series[0].name = '打开场景' + scene + '方式'
       data.series[0].data = [{
-          name: '朋友圈',
-          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.wx_friends : 0), 0)
-        }, {
-          name: '微信好友',
-          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.wx_friend : 0), 0)
-        }, {
-          name: 'QQ好友',
-          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.qq : 0), 0)
-        }, {
-          name: 'QQ空间',
-          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.qq_zone : 0), 0)
-        }, {
-          name: '微博',
-          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.weibo : 0), 0)
-        }, {
-          name: '直接打开',
-          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.default : 0), 0)
+        name: '朋友圈',
+        value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.wx_friends : 0), 0)
+      }, {
+        name: '微信好友',
+        value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.wx_friend : 0), 0)
+      }, {
+        name: 'QQ好友',
+        value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.qq : 0), 0)
+      }, {
+        name: 'QQ空间',
+        value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.qq_zone : 0), 0)
+      }, {
+        name: '微博',
+        value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.weibo : 0), 0)
+      }, {
+        name: '直接打开',
+        value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.default : 0), 0)
       }]
-      return data;
+      return data
     },
     terminal () {
       let scene = this.searchKey || ''
@@ -191,15 +193,15 @@ export default {
       }
       data.legend.data = ['电脑端', '移动端']
       data.title.text = scene + '场景终端打开占比'
-      data.series[0].name = '打开场景'+scene+'使用终端'
+      data.series[0].name = '打开场景' + scene + '使用终端'
       data.series[0].data = [{
-          name: '电脑端',
-          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].PC : 0), 0)
-        }, {
-          name: '移动端',
-          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].Mobile : 0), 0)
+        name: '电脑端',
+        value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].PC : 0), 0)
+      }, {
+        name: '移动端',
+        value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].Mobile : 0), 0)
       }]
-      return data;
+      return data
     },
     secene () {
       let grouping = this.grouping
@@ -210,18 +212,18 @@ export default {
       data.title.text = '场景打开' + (this.searchType === 'uv' ? '人数' : '次数') + '占比'
       data.legend.selected = {}
       keys.forEach(key => {
-        data.legend.selected[key] = grouping[key].count / total > 0.01 
+        data.legend.selected[key] = grouping[key].count / total > 0.01
       })
       data.series[0].data = keys.map(k => ({name: k, value: grouping[k].count}))
 
-      return data;
+      return data
     }
   },
   methods: {
-    async referData() {
+    async referData () {
       this.loadding = true
       let ret = (await this.$http.post('/manager/statistics', JSON.stringify(this.body))).data
-      this.result =  JSON.parse(ret).body.data[0].result
+      this.result = JSON.parse(ret).body.data[0].result
       // this.result = (await this.$http.post('https://api.baidu.com/json/tongji/v1/ReportService/getData', JSON.stringify(this.body))).body.data[0].result
       this.loadding = false
     }
@@ -254,4 +256,4 @@ export default {
 
 <style scoped>
 @import url('./style.css');
-</style>
+</style>

+ 3 - 3
src/page/user/query-list/index.vue

@@ -58,8 +58,8 @@ export default {
       loading: true
     }
   },
-  watch:{
-    statistics(){
+  watch: {
+    statistics () {
     }
   },
   methods: {
@@ -143,7 +143,7 @@ export default {
       this.$router.push({ name: 'user-detail', params: {id: name, rid: childName}})
     },
     getSummaries () {
-      let {subCharge,subPoint,subSubStract,subSubStractPoint} = this.statistics
+      let {subCharge, subPoint, subSubStract, subSubStractPoint} = this.statistics
       console.log({...this.statistics})
       let tmp = [
         '', '', '', '',

+ 6 - 0
src/router/index.js

@@ -40,6 +40,12 @@ export default new Router({
           meta: {text: '设备管理'}
         },
         {
+          path: '/client',
+          name: 'client',
+          component: require('@/page/client').default,
+          meta: {text: '客户管理'}
+        },
+        {
           path: '/invoice',
           name: 'invoice',
           component: require('@/page/invoice').default,

+ 5 - 5
src/util/http.js

@@ -1,10 +1,10 @@
 import axios from 'axios'
 
 // 配置请求域名
-// axios.defaults.baseURL = 'https://www.4dkankan.com/api'
-// axios.defaults.baseURL = 'https://test.4dkankan.com/api'
-// axios.defaults.baseURL = '/apid'
-axios.defaults.baseURL = '/api'
+let server = process.env.NODE_ENV === 'development' ? 'https://www.4dkankan.com/api' : '/api'
+axios.defaults.baseURL = server
+
+// axios.defaults.baseURL = '/api'
 // axios.defaults.baseURL = 'http://192.168.0.207:8066/api'
 
 axios.interceptors.request.use(function (config) {
@@ -79,5 +79,5 @@ function setHandle (router) {
   )
 }
 
-export { setHandle }
+export { setHandle, server }
 export default axios

二进制
四维看看后台管理系统.rar