zoukankan      html  css  js  c++  java
  • springboot-vue项目前台2

    api_account.js

    import * as API from './'
    
    export default {
      //登录
      login: params => {
        return API.POST('login/', params)
      },
      //登出
      logout: params => {
        return API.GET('/api/v1/users/logout', params)
      },
      //修改个人信息
      changeProfile: params => {
        return API.PATCH('/api/v1/users/profile', params)
      },
    
      //查询获取user列表(通过page分页)
      findList: params => {
        return API.GET('account/all', params)
      },
    
      add: params => {
        return API.POST('account/add', params)
      },
      findPermissionList:params => {
        return API.POST('account/permissions', params)
      },
    }

    api_device.js

    import * as API from './'
    
    export default {
    
      //查询获取列表(通过page分页)
      findList: params => {
        return API.POST('deviceType/all', params)
      },
      
      //添加
      add: params => {
        return API.POST(`deviceType/add`, params)
      },
      
    /*  //查询获取一条信息
      findById: id => {
        return API.GET(`/api/v1/books/${id}`)
      },
    
    
      //更新
      update: (id, params) => {
        return API.PUT(`/api/v1/books/${id}`, params)
      },
    
      //单个删除
      remove: id => {
        return API.DELETE(`/api/v1/books/${id}`)
      },
    
      //批量删除,传ids数组
      removeBatch: (ids) => {
        return API.DELETE(`/api/v1/books/batch/${ids}`)
      },*/
    
      //添加车型
      addCM: params => {
        return API.POST(`carmodel/add`, params)
      },
    
      delCM:id => {
        return API.GET(`carmodel/delete/${id}`)
      },
      delDT:id => {
        return API.GET(`deviceType/delete/${id}`)
      },
    }

    api_file.js

    import * as API from './'
    import Vue from 'vue'
    
    export default {
    
    /*  //查询获取列表(通过page分页)
      findList: params => {
        return API.GET('/api/v1/books', params)
      },
      
      //查询获取一条信息
      findById: id => {
        return API.GET(`/api/v1/books/${id}`)
      },
    
      add: params => {
        return API.POST(`/api/v1/books`, params)
      },
      update: (id, params) => {
        return API.PUT(`/api/v1/books/${id}`, params)
      },
    
      //单个删除
      remove: id => {
        return API.DELETE(`/api/v1/books/${id}`)
      },
    
      //批量删除,传ids数组
      removeBatch: (ids) => {
        return API.DELETE(`/api/v1/books/batch/${ids}`)
      },*/
    
      //新增方法
      findTboxList: params => {
        return API.POST('package/all', params)
      },
      addtboxForm: (params,config) => {
        return API.POSTFORM(`package/add`, params,config)
      },
      modify:(params) => {
        return API.POST(`package/modify`, params)
      }
    }

    index.js

    import axios from 'axios'
    import {bus} from '../bus.js'
    // Object.defineProperty(Vue.prototype, '$axios', { value: axios });
    
    axios.defaults.withCredentials = true;
    // axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
    // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';//配置请求头
    
    //添加一个请求拦截器
    axios.interceptors.request.use(function (config) {
      console.dir(config);
      return config;
    }, function (error) {
      // Do something with request error
      return Promise.reject(error);
    });
    
    // 添加一个响应拦截器
    axios.interceptors.response.use(function (response) {
      // alert("响应拦截器")
      if (response.data && response.data.errcode) {
        if (parseInt(response.data.errcode) === 40001) {
          //未登录
          bus.$emit('goto', '/login')
        }
      }
      return response;
    }, function (error) {
      // Do something with response error
      return Promise.reject(error);
    });
    
    //基地址
    let base = 'http://127.0.0.1:8086/';  //接口代理地址参见:config/index.js中的proxyTable配置
    
    //通用方法
    export const POST = (url, params) => {
      return axios.post(`${base}${url}`, params).then(res => res.data).catch(function (error) {
        alert("请求出现异常");
        console.log(error);
        // window.location.reload();
      });
    }
    
    export const GET = (url, params) => {
      return axios.get(`${base}${url}`, {params: params}).then(res => res.data).catch(function (error) {
        alert("请求出现异常");
        console.log(error);
        // window.location.reload();
      });
    }
    
    export const PUT = (url, params) => {
      return axios.put(`${base}${url}`, params).then(res => res.data)
    }
    
    export const DELETE = (url, params) => {
      return axios.delete(`${base}${url}`, {params: params}).then(res => res.data)
    }
    
    export const PATCH = (url, params) => {
      return axios.patch(`${base}${url}`, params).then(res => res.data)
    }
    
    export const POSTFORM = (url, params,config) => {
      return axios.post(`${base}${url}`, params,config).then(res => res.data).catch(function (error) {
        alert("请求出现异常");
        console.log(error);
        // window.location.reload();
      });
    }

    util.js

    /**
     * Created by jerry on 2017/4/14.
     */
    var SIGN_REGEXP = /([yMdhsm])(1*)/g
    var DEFAULT_PATTERN = 'yyyy-MM-dd'
    function padding (s, len) {
      let l = len - (s + '').length
      for (var i = 0; i < l; i++) { s = '0' + s }
      return s
    };
    
    export default {
      getQueryStringByName: function (name) {
        var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
        var r = window.location.search.substr(1).match(reg)
        var context = ''
        if (r != null) { context = r[2] }
        reg = null
        r = null
        return context === null || context === '' || context === 'undefined' ? '' : context
      },
      formatDate: {
    
        format: function (date, pattern) {
          pattern = pattern || DEFAULT_PATTERN
          return pattern.replace(SIGN_REGEXP, function ($0) {
            switch ($0.charAt(0)) {
              case 'y': return padding(date.getFullYear(), $0.length)
              case 'M': return padding(date.getMonth() + 1, $0.length)
              case 'd': return padding(date.getDate(), $0.length)
              case 'w': return date.getDay() + 1
              case 'h': return padding(date.getHours(), $0.length)
              case 'm': return padding(date.getMinutes(), $0.length)
              case 's': return padding(date.getSeconds(), $0.length)
            }
          })
        },
        parse: function (dateString, pattern) {
          var matchs1 = pattern.match(SIGN_REGEXP)
          var matchs2 = dateString.match(/(d)+/g)
          if (matchs1.length === matchs2.length) {
            var _date = new Date(1970, 0, 1)
            for (var i = 0; i < matchs1.length; i++) {
              var _int = parseInt(matchs2[i])
              var sign = matchs1[i]
              switch (sign.charAt(0)) {
                case 'y': _date.setFullYear(_int); break
                case 'M': _date.setMonth(_int - 1); break
                case 'd': _date.setDate(_int); break
                case 'h': _date.setHours(_int); break
                case 'm': _date.setMinutes(_int); break
                case 's': _date.setSeconds(_int); break
              }
            }
            return _date
          }
          return null
        }
    
      }
    
    }

    list.vue

    <template>
      <el-row class="warp">
        <el-col :span="24" class="warp-breadcrum">
          <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item>
          </el-breadcrumb>
        </el-col>
    
        <el-col :span="24" class="warp-main">
          <h2>仄仄仄仄仄仄!</h2>
        </el-col>
      </el-row>
    </template>
    <script>
      export default{
        data(){
          return {
            msg: 'hello vue'
          }
        }
      }
    </script>

    device.vue

    <template>
      <el-row class="warp">
        <el-col :span="24" class="warp-breadcrum">
          <el-breadcrumb separator="/">
            <!-- <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item> -->
            <el-breadcrumb-item>设备类型列表</el-breadcrumb-item>
          </el-breadcrumb>
        </el-col>
    
        <el-col :span="24" class="warp-main" v-loading="loading" element-loading-text="拼命加载中">
    
            <el-button size="medium " @click="adddevice" type="primary" round> 新增设备类型 </el-button>
            <!--列表-->
            <el-table :data="alldevicetype" highlight-current-row @selection-change="selsChange" style=" 100%;">
            <el-table-column type="index" width="40"></el-table-column>
            <el-table-column prop="dtid" width="40" v-if="false"></el-table-column>
            <el-table-column type="expand">
              <template slot-scope="props">
                <el-form label-position="left" inline class="demo-table-expand">
                  <el-form-item label="[设备描述]">
                    <span>{{ props.row.description }}</span>
                  </el-form-item>
                </el-form>
              </template>
            </el-table-column>
            <el-table-column prop="dtname" label="设备类型" width="300" sortable></el-table-column>
            <el-table-column  label="车型         车型操作" width="300" prop="carModels">  
                <!-- 数据的遍历  scope.row就代表数据的每一个对象-->
                <template scope="scope" >  
                    <p v-for="(item, index) in scope.row.carModels" :key="index" :label="item" style="font-size:16px;">
                        <span style="150px;display:block;float:left;">{{item.cname}}</span>
                        <el-button @click.native="delCarModel(item)" size="mini" type="danger" plain round>删除车型</el-button>
                    </p>
                </template>  
            </el-table-column>
            <el-table-column label="设备操作" width="400">
              <template slot-scope="scope">
                <el-button @click.native="addCarModel(scope.row)" size="mini" type="primary" plain round>新增车型</el-button>
                <el-button @click.native="delDeviceType(scope.row)" size="mini" type="danger" round>删除设备类型</el-button>
              </template>
            </el-table-column>
            </el-table>
    
            <!--新增设备类型界面-->
            <el-dialog title="新增设备类型" :visible.sync="dtvisible" :close-on-click-modal="false">
                <el-form :model="devicetype" label-width="80px" :rules="rules" ref="devicetypeForm">
                  <el-form-item label="设备名称" prop="name">
                    <el-input v-model="devicetype.name" auto-complete="off" placeholder="请输入设备名称"></el-input>
                  </el-form-item>
                  <el-form-item label="描述" prop="description">
                    <el-input v-model="devicetype.description" auto-complete="off" placeholder="请输入设备描述"></el-input>
                  </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                  <el-button @click.native="dtvisible = false">取消</el-button>
                  <el-button type="submit"  @click.native="addSubmit" :loading="addLoading">提交</el-button>
                </div>
            </el-dialog>
    
            <!--新增车型界面-->
            <el-dialog title="新增车型" :visible.sync="cmvisible" :close-on-click-modal="false">
                <el-form :model="carModel" label-width="80px" :rules="carModelrules" ref="carModelForm">
                  <el-form-item label="车型名称" prop="name">
                    <el-input v-model="carModel.name" auto-complete="off"  placeholder="请输入车型名称"></el-input>
                  </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                  <el-button @click.native="cmvisible = false">取消</el-button>
                  <el-button type="submit"  @click.native="addSubmit1" :loading="addLoading">提交</el-button>
                </div>
            </el-dialog>
        </el-col>
      </el-row>
    </template>
    <script>
    let id = 1000;
    import util from '../../common/util'
    import API from '../../api/api_device'
    import { mapState, mapActions } from 'vuex'
    
    export default {
        data() {
            return{
                loading: false,
                // devicetypes: [],
                //新增设备类型
                devicetype: {
                  name: '',
                  description: '',
                },
                dtvisible:false,
                rules: {
                    name: [
                        {required: true, message: '输入设备名称', trigger: 'blur'}
                    ],
                    description:[
                        {required: true, message: '输入设备描述', trigger: 'blur'}
                    ],
                },
                sels: [], //列表勾选的列
                addLoading: false, //转圈圈
    
                //新增车型
                cmvisible:false,
                carModel:{
                    name:"",
                    devicetypeId:"",
                },
                carModelrules: {
                    name: [
                        {required: true, message: '输入车型名称', trigger: 'blur'}
                    ],
                },
            }
        },
    
        methods: {
            adddevice: function () {
                this.dtvisible = true;
                this.devicetype = {
                  name: '',
                  description: '',
                };
            },
            //新增
            addSubmit: function () {
                let that = this;
                this.$refs.devicetypeForm.validate((valid) => {
                  if (valid) {
                    let para = Object.assign({}, that.devicetype);//复制对象,有filelist数组对象
                    // console.log("para:",para);
                    API.add(para).then(function (result) {
                      if (result && parseInt(result.errcode) === 0) {
                        that.$message.success({showClose: true, message: result.mess, duration: 3000});
                        that.$refs['devicetypeForm'].resetFields();
                        that.dtvisible = false;
                        that.search();
                      } else {
                        that.$message.error({showClose: true, message: result.mess, duration: 3000});
                        that.$refs['devicetypeForm'].resetFields();
                        that.dtvisible = false;
                        that.search();
                      }
                    }).catch(function (error) {
                        that.loading = false;
                        that.search();
                        that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                      });
                  }
                });
            },
            search(){
                this.loading = true;
                let that = this;
                API.findList().then(function (result) {
                  // console.log("result",result)
                  that.loading = false;
                  if (result && result.devicetypes) {
                    // that.devicetypes = result.devicetypes;
                    console.log("result.devicetypes:::",result.devicetypes);
                    that.dispatch_devicetypes(result.devicetypes);
                      // that.$store.commit('dispatch_devicetypes');
                  }
                }, function (err) {
                  that.loading = false;
                  that.$message.error({showClose: true, message: err.toString(), duration: 2000});
                }).catch(function (error) {
                    that.loading = false;
                    // that.search();
                    that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                  });
            },
            ...mapActions([
                  'dispatch_devicetypes'
              ]),
            addCarModel(row){
                // console.log("addCarModelrow:",row);
                this.cmvisible = true;
                this.carModel = {
                  name: '',
                  devicetypeId: row.dtid,
                };
            },
            selsChange: function (sels) {
                this.sels = sels;
            },
            delCarModel(row){
                // console.log("delCarModelrow:",row);
                let that = this;
                API.delCM(row.cmid).then(function (result) {
                  if (result && parseInt(result.errcode) === 0) {
                    that.$message.success({showClose: true, message: result.mess, duration: 3000});
                    that.search();
                  } else {
                    that.$message.error({showClose: true, message: result.mess, duration: 3000});
                    that.search();
                  }
                }).catch(function (error) {
                        that.loading = false;
                        that.search();
                        that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                      });;
            },
            addSubmit1: function () {
                let that = this;
                this.$refs.carModelForm.validate((valid) => {
                  if (valid) {
                    let para = Object.assign({}, that.carModel);//carModel是addCarModel方法里面的,也是表单里面的,跟表单绑定的。
                    // console.log("para:",para);
                    API.addCM(para).then(function (result) {
                      if (result && parseInt(result.errcode) === 0) {
                        that.$message.success({showClose: true, message: result.mess, duration: 3000});
                        that.$refs['carModelForm'].resetFields();
                        that.cmvisible = false;
                        that.search();
                      } else {
                        that.$message.error({showClose: true, message: result.mess, duration: 3000});
                        that.$refs['carModelForm'].resetFields();
                        that.cmvisible = false;
                        that.search();
                      }
                    }).catch(function (error) {
                        that.loading = false;
                        that.search();
                        that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                      });;
                  }
                });
            },
            delDeviceType: function(row){
                // console.log("delDeviceType:",row);
                let that = this;
                API.delDT(row.dtid).then(function (result) {
                  if (result && parseInt(result.errcode) === 0) {
                    that.$message.success({showClose: true, message: result.mess, duration: 3000});
                    that.search();
                  } else {
                    that.$message.error({showClose: true, message: result.mess, duration: 3000});
                    that.search();
                  }
                }).catch(function (error) {
                    that.loading = false;
                    that.search();
                    that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                  });
            },
        },
        computed: {
            alldevicetype:{
              get:function(){
                return this.$store.getters.getDevicetypes;
              },
              set:function(){
              }
            },
        },
    
        mounted() {
          this.search();
        }
    };
    </script>
    
    <style>
      .demo-table-expand label {
        font-weight: bold;
      }
      .el-table .warning-row {
        background: oldlace;
      }
    
      .el-table .success-row {
        background: #f0f9eb;
      }
    </style>

    avnlist.vue

    <template>
      <el-row class="warp">
        <el-col :span="24" class="warp-breadcrum">
          <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item>
            <el-breadcrumb-item>升级包管理</el-breadcrumb-item>
            <el-breadcrumb-item>tbox升级包列表</el-breadcrumb-item>
          </el-breadcrumb>
        </el-col>
    
        <el-col :span="24" class="warp-main" v-loading="loading" element-loading-text="拼命加载中">
          <!--工具条-->
          <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
            <el-form :inline="true" :model="filters">
              <el-form-item>
                <el-input v-model="filters.name" placeholder="tbox文件名" @keyup.enter.native="handleSearch"></el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" v-on:click="handleSearch">查询</el-button>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="showAddDialog">新增</el-button>
              </el-form-item>
            </el-form>
          </el-col>
    
          <!--列表-->
          <el-table :data="books" highlight-current-row @selection-change="selsChange"
                    style=" 100%;">
            <el-table-column type="selection" width="55"></el-table-column>
            <el-table-column type="index" width="60"></el-table-column>
            <el-table-column type="expand">
              <template slot-scope="props">
                <el-form label-position="left" inline class="demo-table-expand">
                  <el-form-item label="[升级包简介]">
                    <span>{{ props.row.description }}</span>
                  </el-form-item>
                </el-form>
              </template>
            </el-table-column>
            <el-table-column prop="name" label="文件名" sortable></el-table-column>
            <el-table-column prop="author" label="上传者" width="100" sortable></el-table-column>
            <el-table-column prop="publishAt" label="上传日期" width="150" sortable></el-table-column>
            <el-table-column label="操作" width="150">
              <template slot-scope="scope">
                <el-button size="small" @click="showEditDialog(scope.$index,scope.row)">编辑</el-button>
                <el-button type="danger" @click="delbook(scope.$index,scope.row)" size="small">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
    
          <!--工具条-->
          <el-col :span="24" class="toolbar">
            <el-button type="danger" @click="batchDeletebook" :disabled="this.sels.length===0">批量删除</el-button>
            <el-pagination layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="10" :total="total"
                           style="float:right;">
            </el-pagination>
          </el-col>
    
          <el-dialog title="编辑" :visible.sync ="editFormVisible" :close-on-click-modal="false">
            <el-form :model="editForm" label-width="100px" :rules="editFormRules" ref="editForm">
              <el-form-item label="书名" prop="name">
                <el-input v-model="editForm.name" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="作者" prop="author">
                <el-input v-model="editForm.author" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="出版日期">
                <el-date-picker type="date" placeholder="选择日期" v-model="editForm.publishAt"></el-date-picker>
              </el-form-item>
              <el-form-item label="简介" prop="description">
                <el-input type="textarea" v-model="editForm.description" :rows="8"></el-input>
              </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
              <el-button @click.native="editFormVisible = false">取消</el-button>
              <el-button type="primary" @click.native="editSubmit">提交</el-button>
            </div>
          </el-dialog>
    
          <!--新增界面-->
          <el-dialog title="新增" :visible.sync ="addFormVisible" :close-on-click-modal="false">
            <el-form :model="addForm" label-width="80px" :rules="addFormRules" ref="addForm">
              <el-form-item label="书名" prop="name">
                <el-input v-model="addForm.name" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="作者" prop="author">
                <el-input v-model="addForm.author" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="出版日期">
                <el-date-picker type="date" placeholder="选择日期" v-model="addForm.publishAt"></el-date-picker>
              </el-form-item>
              <el-form-item label="简介" prop="description">
                <el-input type="textarea" v-model="addForm.description" :rows="8"></el-input>
              </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
              <el-button @click.native="addFormVisible = false">取消</el-button>
              <el-button type="primary" @click.native="addSubmit" :loading="addLoading">提交</el-button>
            </div>
          </el-dialog>
    
        </el-col>
      </el-row>
    </template>
    <script>
      import util from '../../common/util'
      import API from '../../api/api_file';
    
      export default{
        data(){
          return {
            filters: {
              name: ''
            },
            books: [],
            total: 0,
            page: 1,
            limit: 10,
            loading: false,
            sels: [], //列表选中列
    
            //编辑相关数据
            editFormVisible: false,//编辑界面是否显示
            editFormRules: {
              name: [
                {required: true, message: '请输入书名', trigger: 'blur'}
              ],
              author: [
                {required: true, message: '请输入作者', trigger: 'blur'}
              ],
              description: [
                {required: true, message: '请输入简介', trigger: 'blur'}
              ]
            },
            editForm: {
              id: 0,
              name: '',
              author: '',
              publishAt: '',
              description: ''
            },
    
            //新增相关数据
            addFormVisible: false,//新增界面是否显示
            addLoading: false,
            addFormRules: {
              name: [
                {required: true, message: '请输入书名', trigger: 'blur'}
              ],
              author: [
                {required: true, message: '请输入作者', trigger: 'blur'}
              ],
              description: [
                {required: true, message: '请输入简介', trigger: 'blur'}
              ]
            },
            addForm: {
              name: '',
              author: '',
              publishAt: '',
              description: ''
            }
          }
        },
        methods: {
          handleCurrentChange(val) {
            this.page = val;
            this.search();
          },
          handleSearch(){
            this.total = 0;
            this.page = 1;
            this.search();
          },
          search(){
            let that = this;
            let params = {
              page: that.page,
              limit: 10,
              name: that.filters.name
            };
    
            that.loading = true;
            API.findList(params).then(function (result) {
              that.loading = false;
              if (result && result.books) {
                that.total = result.total;
                that.books = result.books;
              }
            }, function (err) {
              that.loading = false;
              that.$message.error({showClose: true, message: err.toString(), duration: 2000});
            }).catch(function (error) {
              that.loading = false;
              console.log(error);
              that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
            });
          },
          selsChange: function (sels) {
            this.sels = sels;
          },
          //删除
          delbook: function (index, row) {
            let that = this;
            this.$confirm('确认删除该记录吗?', '提示', {type: 'warning'}).then(() => {
              that.loading = true;
              API.remove(row.id).then(function (result) {
                that.loading = false;
                if (result && parseInt(result.errcode) === 0) {
                  that.$message.success({showClose: true, message: '删除成功', duration: 1500});
                  that.search();
                }
              }, function (err) {
                that.loading = false;
                that.$message.error({showClose: true, message: err.toString(), duration: 2000});
              }).catch(function (error) {
                that.loading = false;
                console.log(error);
                that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
              });
            }).catch(() => {
            });
          },
          //显示编辑界面
          showEditDialog: function (index, row) {
            this.editFormVisible = true;
            this.editForm = Object.assign({}, row);
          },
          //编辑
          editSubmit: function () {
            let that = this;
            this.$refs.editForm.validate((valid) => {
              if (valid) {
                this.loading = true;
                let para = Object.assign({}, this.editForm);
                para.publishAt = (!para.publishAt || para.publishAt == '') ? '' : util.formatDate.format(new Date(para.publishAt), 'yyyy-MM-dd');
                API.update(para.id, para).then(function (result) {
                  that.loading = false;
                  if (result && parseInt(result.errcode) === 0) {
                    that.$message.success({showClose: true, message: '修改成功', duration: 2000});
                    that.$refs['editForm'].resetFields();
                    that.editFormVisible = false;
                    that.search();
                  } else {
                    that.$message.error({showClose: true, message: '修改失败', duration: 2000});
                  }
                }, function (err) {
                  that.loading = false;
                  that.$message.error({showClose: true, message: err.toString(), duration: 2000});
                }).catch(function (error) {
                  that.loading = false;
                  console.log(error);
                  that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                });
              }
            });
          },
          showAddDialog: function () {
            this.addFormVisible = true;
            this.addForm = {
              name: '',
              author: '',
              publishAt: '',
              description: ''
            };
          },
          //新增
          addSubmit: function () {
            let that = this;
            this.$refs.addForm.validate((valid) => {
              if (valid) {
                that.loading = true;
                let para = Object.assign({}, this.addForm);
                para.publishAt = (!para.publishAt || para.publishAt === '') ? '' : util.formatDate.format(new Date(para.publishAt), 'yyyy-MM-dd');
                API.add(para).then(function (result) {
                  that.loading = false;
                  if (result && parseInt(result.errcode) === 0) {
                    that.$message.success({showClose: true, message: '新增成功', duration: 2000});
                    that.$refs['addForm'].resetFields();
                    that.addFormVisible = false;
                    that.search();
                  } else {
                    that.$message.error({showClose: true, message: '修改失败', duration: 2000});
                  }
                }, function (err) {
                  that.loading = false;
                  that.$message.error({showClose: true, message: err.toString(), duration: 2000});
                }).catch(function (error) {
                  that.loading = false;
                  console.log(error);
                  that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                });
    
              }
            });
          },
          //批量删除
          batchDeletebook: function () {
            let ids = this.sels.map(item => item.id).toString();
            let that = this;
            this.$confirm('确认删除选中记录吗?', '提示', {
              type: 'warning'
            }).then(() => {
              that.loading = true;
              API.removeBatch(ids).then(function (result) {
                that.loading = false;
                if (result && parseInt(result.errcode) === 0) {
                  that.$message.success({showClose: true, message: '删除成功', duration: 1500});
                  that.search();
                }
              }, function (err) {
                that.loading = false;
                that.$message.error({showClose: true, message: err.toString(), duration: 2000});
              }).catch(function (error) {
                that.loading = false;
                console.log(error);
                that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
              });
            }).catch(() => {
    
            });
          }
        },
        mounted() {
          this.handleSearch()
        }
      }
    </script>
    
    <style>
      .demo-table-expand label {
        font-weight: bold;
      }
    </style>

    ipclist.vue

    <template>
      <el-row class="warp">
        <el-col :span="24" class="warp-breadcrum">
          <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item>
            <el-breadcrumb-item>升级包管理</el-breadcrumb-item>
            <el-breadcrumb-item>tbox升级包列表</el-breadcrumb-item>
          </el-breadcrumb>
        </el-col>
    
        <el-col :span="24" class="warp-main" v-loading="loading" element-loading-text="拼命加载中">
          <!--工具条-->
          <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
            <el-form :inline="true" :model="filters">
              <el-form-item>
                <el-input v-model="filters.name" placeholder="tbox文件名" @keyup.enter.native="handleSearch"></el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" v-on:click="handleSearch">查询</el-button>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="showAddDialog">新增</el-button>
              </el-form-item>
            </el-form>
          </el-col>
    
          <!--列表-->
          <el-table :data="books" highlight-current-row @selection-change="selsChange"
                    style=" 100%;">
            <el-table-column type="selection" width="55"></el-table-column>
            <el-table-column type="index" width="60"></el-table-column>
            <el-table-column type="expand">
              <template slot-scope="props">
                <el-form label-position="left" inline class="demo-table-expand">
                  <el-form-item label="[升级包简介]">
                    <span>{{ props.row.description }}</span>
                  </el-form-item>
                </el-form>
              </template>
            </el-table-column>
            <el-table-column prop="name" label="文件名" sortable></el-table-column>
            <el-table-column prop="author" label="上传者" width="100" sortable></el-table-column>
            <el-table-column prop="publishAt" label="上传日期" width="150" sortable></el-table-column>
            <el-table-column label="操作" width="150">
              <template slot-scope="scope">
                <el-button size="small" @click="showEditDialog(scope.$index,scope.row)">编辑</el-button>
                <el-button type="danger" @click="delbook(scope.$index,scope.row)" size="small">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
    
          <!--工具条-->
          <el-col :span="24" class="toolbar">
            <el-button type="danger" @click="batchDeletebook" :disabled="this.sels.length===0">批量删除</el-button>
            <el-pagination layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="10" :total="total"
                           style="float:right;">
            </el-pagination>
          </el-col>
    
          <el-dialog title="编辑" :visible.sync ="editFormVisible" :close-on-click-modal="false">
            <el-form :model="editForm" label-width="100px" :rules="editFormRules" ref="editForm">
              <el-form-item label="书名" prop="name">
                <el-input v-model="editForm.name" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="作者" prop="author">
                <el-input v-model="editForm.author" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="出版日期">
                <el-date-picker type="date" placeholder="选择日期" v-model="editForm.publishAt"></el-date-picker>
              </el-form-item>
              <el-form-item label="简介" prop="description">
                <el-input type="textarea" v-model="editForm.description" :rows="8"></el-input>
              </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
              <el-button @click.native="editFormVisible = false">取消</el-button>
              <el-button type="primary" @click.native="editSubmit">提交</el-button>
            </div>
          </el-dialog>
    
          <!--新增界面-->
          <el-dialog title="新增" :visible.sync ="addFormVisible" :close-on-click-modal="false">
            <el-form :model="addForm" label-width="80px" :rules="addFormRules" ref="addForm">
              <el-form-item label="书名" prop="name">
                <el-input v-model="addForm.name" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="作者" prop="author">
                <el-input v-model="addForm.author" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="出版日期">
                <el-date-picker type="date" placeholder="选择日期" v-model="addForm.publishAt"></el-date-picker>
              </el-form-item>
              <el-form-item label="简介" prop="description">
                <el-input type="textarea" v-model="addForm.description" :rows="8"></el-input>
              </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
              <el-button @click.native="addFormVisible = false">取消</el-button>
              <el-button type="primary" @click.native="addSubmit" :loading="addLoading">提交</el-button>
            </div>
          </el-dialog>
    
        </el-col>
      </el-row>
    </template>
    <script>
      import util from '../../common/util'
      import API from '../../api/api_file';
    
      export default{
        data(){
          return {
            filters: {
              name: ''
            },
            books: [],
            total: 0,
            page: 1,
            limit: 10,
            loading: false,
            sels: [], //列表选中列
    
            //编辑相关数据
            editFormVisible: false,//编辑界面是否显示
            editFormRules: {
              name: [
                {required: true, message: '请输入书名', trigger: 'blur'}
              ],
              author: [
                {required: true, message: '请输入作者', trigger: 'blur'}
              ],
              description: [
                {required: true, message: '请输入简介', trigger: 'blur'}
              ]
            },
            editForm: {
              id: 0,
              name: '',
              author: '',
              publishAt: '',
              description: ''
            },
    
            //新增相关数据
            addFormVisible: false,//新增界面是否显示
            addLoading: false,
            addFormRules: {
              name: [
                {required: true, message: '请输入书名', trigger: 'blur'}
              ],
              author: [
                {required: true, message: '请输入作者', trigger: 'blur'}
              ],
              description: [
                {required: true, message: '请输入简介', trigger: 'blur'}
              ]
            },
            addForm: {
              name: '',
              author: '',
              publishAt: '',
              description: ''
            }
          }
        },
        methods: {
          handleCurrentChange(val) {
            this.page = val;
            this.search();
          },
          handleSearch(){
            this.total = 0;
            this.page = 1;
            this.search();
          },
          search(){
            let that = this;
            let params = {
              page: that.page,
              limit: 10,
              name: that.filters.name
            };
    
            that.loading = true;
            API.findList(params).then(function (result) {
              that.loading = false;
              if (result && result.books) {
                that.total = result.total;
                that.books = result.books;
              }
            }, function (err) {
              that.loading = false;
              that.$message.error({showClose: true, message: err.toString(), duration: 2000});
            }).catch(function (error) {
              that.loading = false;
              console.log(error);
              that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
            });
          },
          selsChange: function (sels) {
            this.sels = sels;
          },
          //删除
          delbook: function (index, row) {
            let that = this;
            this.$confirm('确认删除该记录吗?', '提示', {type: 'warning'}).then(() => {
              that.loading = true;
              API.remove(row.id).then(function (result) {
                that.loading = false;
                if (result && parseInt(result.errcode) === 0) {
                  that.$message.success({showClose: true, message: '删除成功', duration: 1500});
                  that.search();
                }
              }, function (err) {
                that.loading = false;
                that.$message.error({showClose: true, message: err.toString(), duration: 2000});
              }).catch(function (error) {
                that.loading = false;
                console.log(error);
                that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
              });
            }).catch(() => {
            });
          },
          //显示编辑界面
          showEditDialog: function (index, row) {
            this.editFormVisible = true;
            this.editForm = Object.assign({}, row);
          },
          //编辑
          editSubmit: function () {
            let that = this;
            this.$refs.editForm.validate((valid) => {
              if (valid) {
                this.loading = true;
                let para = Object.assign({}, this.editForm);
                para.publishAt = (!para.publishAt || para.publishAt == '') ? '' : util.formatDate.format(new Date(para.publishAt), 'yyyy-MM-dd');
                API.update(para.id, para).then(function (result) {
                  that.loading = false;
                  if (result && parseInt(result.errcode) === 0) {
                    that.$message.success({showClose: true, message: '修改成功', duration: 2000});
                    that.$refs['editForm'].resetFields();
                    that.editFormVisible = false;
                    that.search();
                  } else {
                    that.$message.error({showClose: true, message: '修改失败', duration: 2000});
                  }
                }, function (err) {
                  that.loading = false;
                  that.$message.error({showClose: true, message: err.toString(), duration: 2000});
                }).catch(function (error) {
                  that.loading = false;
                  console.log(error);
                  that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                });
              }
            });
          },
          showAddDialog: function () {
            this.addFormVisible = true;
            this.addForm = {
              name: '',
              author: '',
              publishAt: '',
              description: ''
            };
          },
          //新增
          addSubmit: function () {
            let that = this;
            this.$refs.addForm.validate((valid) => {
              if (valid) {
                that.loading = true;
                let para = Object.assign({}, this.addForm);
                para.publishAt = (!para.publishAt || para.publishAt === '') ? '' : util.formatDate.format(new Date(para.publishAt), 'yyyy-MM-dd');
                API.add(para).then(function (result) {
                  that.loading = false;
                  if (result && parseInt(result.errcode) === 0) {
                    that.$message.success({showClose: true, message: '新增成功', duration: 2000});
                    that.$refs['addForm'].resetFields();
                    that.addFormVisible = false;
                    that.search();
                  } else {
                    that.$message.error({showClose: true, message: '修改失败', duration: 2000});
                  }
                }, function (err) {
                  that.loading = false;
                  that.$message.error({showClose: true, message: err.toString(), duration: 2000});
                }).catch(function (error) {
                  that.loading = false;
                  console.log(error);
                  that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                });
    
              }
            });
          },
          //批量删除
          batchDeletebook: function () {
            let ids = this.sels.map(item => item.id).toString();
            let that = this;
            this.$confirm('确认删除选中记录吗?', '提示', {
              type: 'warning'
            }).then(() => {
              that.loading = true;
              API.removeBatch(ids).then(function (result) {
                that.loading = false;
                if (result && parseInt(result.errcode) === 0) {
                  that.$message.success({showClose: true, message: '删除成功', duration: 1500});
                  that.search();
                }
              }, function (err) {
                that.loading = false;
                that.$message.error({showClose: true, message: err.toString(), duration: 2000});
              }).catch(function (error) {
                that.loading = false;
                console.log(error);
                that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
              });
            }).catch(() => {
    
            });
          }
        },
        mounted() {
          this.handleSearch()
        }
      }
    </script>
    
    <style>
      .demo-table-expand label {
        font-weight: bold;
      }
    </style>

    packagelist.vue

    <template>
      <el-row class="warp">
        <el-col :span="24" class="warp-breadcrum">
          <el-breadcrumb separator="/">
            <!-- <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item> -->
            <el-breadcrumb-item>升级包管理</el-breadcrumb-item>
            <a href="http://localhost:8086/package/download">下载</a>
            <!-- <el-breadcrumb-item>tbox升级包列表</el-breadcrumb-item> -->
          </el-breadcrumb>
        </el-col>
    
        <el-col :span="24" class="warp-main" v-loading="loading" element-loading-text="拼命加载中">
          <!--工具条-->
          <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
            <el-form :inline="true" :model="filters">
              <!-- <el-form-item>
                <el-input v-model="filters.name" placeholder="tbox文件名" @keyup.enter.native="handleSearch"></el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" v-on:click="handleSearch">查询</el-button>
              </el-form-item> -->
              <!-- <el-form-item>
                <template>
                  <el-select v-model="selectvalue" placeholder="所有设备类型" v-on:change="selectchange()">
                    <el-option
                      v-for="item in devicetypes" :key="item.dtid" :label="item.dtname" :value="item.dtid">
                    </el-option>
                  </el-select>
                </template>
              </el-form-item> -->
              <el-form-item>
                <el-button type="primary" @click="showAddDialog">上传升级包</el-button>
              </el-form-item>
            </el-form>
          </el-col>
    
          <!--列表-->
          <el-table :data="packages" highlight-current-row @selection-change="selsChange" style=" 100%;">
            <!-- <el-table-column type="selection" width="55"></el-table-column> -->
            <el-table-column type="index" width="40"></el-table-column>
            <el-table-column prop="pid" width="40" v-if="false"></el-table-column>
            <el-table-column type="expand">
              <template slot-scope="props">
                <el-form label-position="left" inline class="demo-table-expand">
                  <el-form-item label="[升级包changelog]">
                    <span>{{ props.row.description }}</span>
                  </el-form-item>
                </el-form>
              </template>
            </el-table-column>
            <!-- <el-table-column type="expand">
              <template slot-scope="props1">
                <el-form label-position="right" inline class="demo-table-expand">
                  <el-form-item label="[文件]">
                    <span>{{ props1.row.files }}</span>
                  </el-form-item>
                </el-form>
              </template>
            </el-table-column> -->
            <el-table-column prop="deviceType" label="设备类型" width="100" sortable></el-table-column>
            <el-table-column prop="carModel" label="车型" width="80" sortable></el-table-column>
            <el-table-column prop="packageVersion" label="版本号" width="140" sortable></el-table-column>
            <el-table-column prop="state" label="状态" width="110" sortable><!-- :formatter="fmtstate" -->
              <template scope="scope">
                <span v-if="scope.row.state=== 1" style="color: red">正在使用</span>
                <span v-else >停用</span>
              </template>
            </el-table-column>
            <el-table-column prop="updateTime" label="上传时间" width="200" sortable></el-table-column>
            <el-table-column  label="文件" width="480" prop="files">  
               <!-- 数据的遍历  scope.row就代表数据的每一个对象-->  
               <template scope="scope" >  
                <span v-for="(item, index) in scope.row.files" :key="index" :label="item">{{item.orignName}} (md5:{{item.md5}})<br></span>
               </template>  
            </el-table-column> 
            <el-table-column label="操作" width="150">
              <template slot-scope="scope">
                <el-button v-if="scope.row.state=== 0" @click.native="editDialog(scope.row,1)" type="primary" size="small">启用</el-button>
                <el-button v-if="scope.row.state=== 1" @click.native="editDialog(scope.row,0)" type="warning" size="small">停用</el-button>
                <!-- <el-button type="warning" size="small" @click="showEditDialog(scope.$index,scope.row)">修改</el-button> -->
                <el-button type="danger" @click.native="editDialog(scope.row,2)" size="small">删除</el-button>
                <!-- <el-button type="danger" @click="delbook(scope.$index,scope.row)" size="small">删除</el-button> -->
              </template>
            </el-table-column>
          </el-table>
    
          <!--工具条-->
          <!-- <el-col :span="24" class="toolbar toolbartop">
            <el-button type="danger" @click="batchDeletebook" :disabled="this.sels.length===0">批量删除</el-button>
            <el-pagination layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="10" :total="total"
                           style="float:right;">
            </el-pagination>
          </el-col> -->
    
          <!-- <el-dialog title="编辑" :visible.sync="editFormVisible" :close-on-click-modal="false">
            <el-form :model="editForm" label-width="100px" :rules="editFormRules" ref="editForm">
              <el-form-item label="文件名" prop="name">
                <el-input v-model="editForm.name" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="上传者" prop="author">
                <el-input v-model="editForm.author" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="上传日期">
                <el-date-picker type="date" placeholder="选择日期" v-model="editForm.publishAt"></el-date-picker>
              </el-form-item>
              <el-form-item label="升级包说明" prop="description">
                <el-input type="textarea" v-model="editForm.description" :rows="8"></el-input>
              </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
              <el-button @click.native="editFormVisible = false">取消</el-button>
              <el-button type="primary" @click.native="editSubmit">提交</el-button>
            </div>
          </el-dialog> -->
    
          <!--新增界面-->
          <el-dialog title="新增" :visible.sync="addFormVisible" :close-on-click-modal="false">
            <el-form :model="addForm" label-width="120px" :rules="addFormRules" ref="addForm" method="POST" id="uploadForm-tbox"><!-- id="uploadForm-tbox" enctype="multipart/form-data" -->
              <!-- <el-form-item label="类型" prop="fileType" v-show="false">
                <el-input v-model="addForm.fileType" auto-complete="off" value="tbox" ></el-input>
              </el-form-item> -->
              <el-form-item label="版本号" prop="fileVersion">
                <el-input v-model="addForm.fileVersion" auto-complete="off" placeholder="请输入版本号"></el-input>
              </el-form-item>
              <el-form-item label="设备类型/车型" prop="selectedOptions" width="200px">
                <!-- <el-input v-model="addForm.fileName" auto-complete="off"></el-input> -->
                <el-cascader
                  expand-trigger="hover" :options="newDeviceType" v-model="addForm.selectedOptions" @change="handleChange">
                </el-cascader>
              </el-form-item>
              <!--<el-form-item label="出版日期">
                <el-date-picker type="date" placeholder="选择日期" v-model="addForm.publishAt"></el-date-picker>
              </el-form-item>-->
              <el-form-item label="是否启用" prop="state">
                 <el-radio v-model="addForm.state" label="1">是</el-radio>
                 <el-radio v-model="addForm.state" label="0">否</el-radio>
              </el-form-item>
              <el-form-item label="简介" prop="description">
                <el-input type="textarea" v-model="addForm.description" :rows="8" placeholder="请输入版本修改日志"></el-input>
              </el-form-item>
              <el-form-item label="选择文件" >
                <!-- <input type="file" @change="getFile($event)" multiple/> -->
                <el-upload 
                  class="upload" 
                  action="" 
                  ref="fileupload" 
                  :on-preview="handlePreview" 
                  :before-upload="beforeAvatarUpload"
                  :on-remove="handleRemove" 
                  :auto-upload = 'false' 
                  :on-success = 'handleSuccess' 
                  :on-change="fileChange"
                  name="tboxfile" 
                  prop="file" multiple>
                  <el-button size="small" type="primary">点击上传</el-button>
                  <!-- <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> -->
                </el-upload>
                <!-- <p :class="" v-if="names.length != 0">已选文件:</p> -->
                <!-- <span v-for="val  in names">
                    {{val}}
                  </span>
                <el-button type="button" @click.native="removeFile" v-if="files.length != 0">移除</el-button> -->
              </el-form-item>
              <!-- <el-form-item label="files" prop="files">
                <el-input v-model="addForm.fileList" auto-complete="off"></el-input>
              </el-form-item> -->
            </el-form>
            <div slot="footer" class="dialog-footer">
              <el-button @click.native="addFormVisible = false">取消</el-button>
              <el-button type="submit"  @click.native="addSubmit" :loading="addLoading">提交</el-button>
            </div>
          </el-dialog>
    
          <!-- 提示对话框 -->
          <el-dialog
            title="提示"
            :visible.sync="notedialogVisible"
            width="30%"
            :before-close="handleClose">
            <span>{{notemessage}}</span>
            <span slot="footer" class="dialog-footer">
              <el-button @click.native="cancelldialog">取 消</el-button>
              <el-button type="primary" @click.native="notedialog">确 定</el-button>
            </span>
          </el-dialog>
        </el-col>
      </el-row>
    </template>
    <script>
      import util from '../../common/util'
      import API from '../../api/api_file';
      import APIdevice from '../../api/api_device';
      import axios from 'axios'
      import { mapState, mapActions } from 'vuex'
    
      export default{
        data(){
          return {
            filters: {
              name: ''
            },
            /*file:"",
            files: {},
            names:{},
            fileList:[],*/
            // packages: [],
            total: 0,
            page: 1,
            limit: 10,
            loading: false,
            sels: [], //列表选中列
            radio: '',
            //编辑相关数据
            /*editFormVisible: false,//编辑界面是否显示
            editFormRules: {
              name: [
                {required: true, message: '请输入文件名', trigger: 'blur'}
              ],
              version: [
                {required: true, message: '请输入版本号', trigger: 'blur'}
              ],
              description: [
                {required: true, message: '请输入简介', trigger: 'blur'}
              ]
            },
            editForm: {
              id: 0,
              name: '',
              version: '',
              publishAt: '',
              description: ''
            },*/
            //编辑相关数据
            //新增相关数据
            addFormVisible: false,//新增界面是否显示
            addLoading: false,
            addFormRules: {
              fileName: [
                {required: true, message: '输入文件名', trigger: 'blur'}
              ],
              fileVersion: [
                {required: true, message: '输入版本号', trigger: 'blur'}
              ],
              description: [
                {required: true, message: '请输入升级包描述', trigger: 'blur'}
              ],
              state: [
                {required: true, message: '请输入状态', trigger: 'blur'}
              ],
              file: [
                {required: true, message: '请选择升级包', trigger: 'blur'}
              ],
              selectedOptions:[
                {required: true, message: '请选择设备类型/车型', trigger: 'blur'}
              ]
            },
            addForm: {
              fileName: '',
              fileVersion: '',
              publishAt: '',
              description: '',
              fileList: [],
              selectedOptions:[]
            },
            //新增相关数据
            //启用相关数据
            notedialogVisible:false,
            notemessage:"",
            arow:{},
            filed:"",
            //启用相关数据
            //设备相关
            // devicetypes: [],
            // newDeviceType:[],
            //设备相关
            //下拉相关
            allpackages:[],
            selectvalue:"",
            selectedOptions:[],
            //下拉相关
          }
        },
        methods: {
          selectchange(command) {
            // console.log(this.selectvalue);
          },
          handleChange(value){
            console.log("value:",value);
            console.log("this.selectedOptions:",this.selectedOptions);
          },
          /*fmtstate(row, column){
            const arr = row[column.property];
            if(arr == 1){
              return "正在使用";
            }else{
              return "已停用";
            }
          },*/
          handleCurrentChange(val) {
            this.page = val;
            this.search();
          },
          handleSearch(){
            this.total = 0;
            this.page = 1;
            this.search();
          },
          ...mapActions([
            'dispatch_packages','dispatch_devicetypes'
          ]),
          search(){
            let that = this;
            let params = {
              page: that.page,
              limit: 10,
              name: that.filters.name
            };
            that.loading = true;
            API.findTboxList(params).then(function (result) {
              that.loading = false;
              if (result && result.packages) {
                that.dispatch_packages(result.packages);
                // that.total = result.total;
                // that.packages = result.packages;
                // that.allpackages = result.packages;
              }
            }, function (err) {
              that.loading = false;
              that.$message.error({showClose: true, message: err.toString(), duration: 2000});
            }).catch(function (error) {
              that.loading = false;
              console.log(error);
              that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
            });
    
            APIdevice.findList().then(function (result) {
              // console.log("devicetypesresult",result)
              that.loading = false;
              if (result && result.devicetypes) {
                // console.log("result.devicetypes:",result.devicetypes);
                // that.newDeviceType = result.devicetypes;
                that.dispatch_devicetypes(result.devicetypes);
                // console.log("newDeviceType:",newDeviceType);
              }
            }, function (err) {
            that.loading = false;
            that.$message.error({showClose: true, message: err.toString(), duration: 2000});
            }).catch(function (error) {
              that.loading = false;
              that.search();
              that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
            });
          },
          selsChange: function (sels) {
            this.sels = sels;
          },
          //删除
          delbook: function (index, row) {
            let that = this;
            this.$confirm('确认删除该记录吗?', '提示', {type: 'warning'}).then(() => {
              that.loading = true;
              API.remove(row.id).then(function (result) {
                that.loading = false;
                if (result && parseInt(result.errcode) === 0) {
                  that.$message.success({showClose: true, message: '删除成功', duration: 1500});
                  that.search();
                }
              }, function (err) {
                that.loading = false;
                that.$message.error({showClose: true, message: err.toString(), duration: 2000});
              }).catch(function (error) {
                that.loading = false;
                console.log(error);
                that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
              });
            }).catch(() => {
            });
          },
          //显示编辑界面
          /*showEditDialog: function (index, row) {
            this.editFormVisible = true;
            this.editForm = Object.assign({}, row);
          },*/
          //启用相关数据
          editDialog: function (row,index) {
            console.log("index, row",index, row);
            this.filed = index;
            let type = "";
            if(index == 1){
              type="启用:";
            }else if(index == 0){
              type="停用:";
            }else if(index == 2){
              type="删除:";
            }
            this.notemessage = "确定"+type+row.deviceType+"--"+row.carModel+"--"+row.packageVersion+"的升级包吗?";
            this.notedialogVisible = true;
            this.arow = Object.assign({}, row);
          },
          handleClose(done) {
            /*this.$confirm('确认关闭?')
              .then(_ => {
                done();
              })
              .catch(_ => {});*/
            this.notedialogVisible = false;
            this.arow={};
            this.filed="";
          },
          cancelldialog(){
            this.notedialogVisible = false;
            this.arow={};
            this.filed="";
          },
          notedialog(){
            let params = {
              "pid": this.arow.pid,
              "deviceType": this.arow.deviceType,
              "carModel": this.arow.carModel,
              "state": this.filed
            };
            let that = this;
            API.modify(params).then(function (result) {
              that.loading = true;
              if (result && parseInt(result.errcode) === 0) {
                // alert(456);
                that.$message.success({showClose: true, message: '修改成功', duration: 2000});
                /*that.$refs['editForm'].resetFields();
                that.editFormVisible = false;*/
                that.search();
              } else {
                that.$message.error({showClose: true, message: result.mess, duration: 2000});
                that.search();
              }
            }, function (err) {
              that.loading = false;
              that.$message.error({showClose: true, message: err.toString(), duration: 2000});
              that.search();
            }).catch(function (error) {
              that.loading = false;
              console.log(error);
              that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
              that.search();
            });
            this.notedialogVisible = false;
            this.arow={};
            this.filed="";
          },
          //启用相关数据
          //编辑
          /*editSubmit: function () {
            let that = this;
            this.$refs.editForm.validate((valid) => {
              if (valid) {
                this.loading = true;
                let para = Object.assign({}, this.editForm);
                para.publishAt = (!para.publishAt || para.publishAt == '') ? '' : util.formatDate.format(new Date(para.publishAt), 'yyyy-MM-dd');
                API.update(para.id, para).then(function (result) {
                  that.loading = false;
                  if (result && parseInt(result.errcode) === 0) {
                    that.$message.success({showClose: true, message: '修改成功', duration: 2000});
                    that.$refs['editForm'].resetFields();
                    that.editFormVisible = false;
                    that.search();
                  } else {
                    that.$message.error({showClose: true, message: '修改失败', duration: 2000});
                  }
                }, function (err) {
                  that.loading = false;
                  that.$message.error({showClose: true, message: err.toString(), duration: 2000});
                }).catch(function (error) {
                  that.loading = false;
                  console.log(error);
                  that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                });
              }
            });
          },*/
          showAddDialog: function () {
            this.addFormVisible = true;
            this.addForm = {
              fileName: '',
              fileVersion: '',
              publishAt: '',
              description: '',
              fileList:[],
              selectedOptions:[]
            };
            // alert("that.$refs['fileupload'].fileList:",this.$refs['addForm'].$refs['fileupload'].fileList);
            // this.$refs['addForm'].$refs['fileupload'].fileList=[];
            /*this.files = {};*/
          },
          //文件相关
          beforeAvatarUpload(file, fileList) {
            console.log("4444444444444");
              /*console.log("beforeAvatarUpload")
              console.log("beforeAvatarUploadfile:",file)
              console.log("beforeAvatarUploadfileList:",fileList)
              let Xls = file.name.split('.');
              if(Xls[1] === 'xls'||Xls[1] === 'xlsx'){
                  return file
              }else {
                  // this.$message.error('上传文件只能是 xls/xlsx 格式!')
                  return file
                  // return false
              }*/
          },
          handleRemove(file, fileList) {
            /*console.log("handleRemove:","file:",file,":fileList:",fileList);
             for(var i=0;i<fileList.length;i++){
              if(file.name == fileList[i].name){
                fileList.splice(i--,1);
                // break;
              }
             }*/
             for(var i=0;i<this.addForm.fileList.length;i++){
              if(file.name == this.addForm.fileList[i].name){
                this.addForm.fileList.splice(i--,1);
                // break;
              }
             }
            console.log("handleRemove:","file:",file,":fileList:",fileList);
          },
          handlePreview(file) {
            console.log("22222222222");
          },
          handleSuccess(res,file,fileList){
            console.log("333333333333");
            /*console.log("handleSuccess:",fileList)
              if(res.code===20000){
                  this.$message({
                      message: '上传成功!',
                      type: 'success'
                  });
              }else {
                  this.$message({
                      message: res.msg,
                      type: 'error'
                  });
              }*/
    
          },
          fileChange(file, fileList){
            //因为原生的选择文件标签获取的是FileList {0: File(8192), 1: File(18432), length: 2}一个object对象,
            //后台需要的是File对象数组,原生的方法也要遍历这个object拼接成一个File数组
            //el-upload的File对象的file.raw才是一个File对象,所以这里只截取el-upload里面的File对象,拼接成数组,后台@RequestParam("fileList[]") MultipartFile[] files接收
            this.addForm.fileList.push(file.raw);//上传文件变化时将文件对象push进files数组
            fileList = [];
            /*this.fileList.push(file.raw);*/
          },
          /*getFile: function (event) {
            this.files = event.target.files;
            console.log('this.files:',this.files)
          },
          removeFile: function () {
          },*/
          //文件相关
          //新增
          addSubmit: function () {
           let that = this;
           this.$refs.addForm.validate((valid) => {
              if (valid) {
                that.loading = true;
                // console.log("addForm",that.addForm)
                let para = Object.assign({}, that.addForm);//复制对象,有filelist数组对象
                // console.log("para",para)
                para.publishAt = /*(!para.publishAt || para.publishAt === '') ? '' : */util.formatDate.format(new Date(), 'yyyy-MM-dd');
                /*var form = document.getElementById("uploadForm-tbox");也可以直接提交表单
                var formData = new FormData(form);*/
                // console.log("para:",para);
                let formData = new FormData();
                for( var attr in para){ //排除文件列表属性
                  // console.log("attr1",attr)
                  if(attr != "fileList") {
                    // console.log("attr2",attr)
                    formData.append(attr, para[attr]);
                  }
                } 
                for (var i = para.fileList.length - 1; i >= 0; i--) {
                  formData.append("fileList", para.fileList[i]);  //文件列表只能这么添加,不能添加一个数组
                }
                let config = {
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    }
                };
                API.addtboxForm(formData,config).then(function (result) {
                  that.loading = false;
                  if (result && parseInt(result.errcode) === 0) {
                    alert(1);
                    console.log(result);
                    that.$message.success({showClose: true, message: result.mess, duration: 3000});
                    that.$refs['addForm'].resetFields();
                    that.addFormVisible = false;
                    that.$refs['fileupload'].fileList=[];
                    that.search();
                    // window.location.reload();
                  } else {
                    alert(2);
                    alert(result.errcode);
                    that.$message.error({showClose: true, message: result.mess, duration: 3000});
                    that.$refs['addForm'].resetFields();
                    that.addFormVisible = false;
                    that.$refs['fileupload'].fileList=[];
                    that.search();
                    // window.location.reload();
                  }
                }, function (err) {
                  alert(3);
                  that.loading = false;
                  that.$message.error({showClose: true, message: err.toString(), duration: 3000});
                  that.$refs['addForm'].resetFields();
                  that.$refs['fileupload'].fileList=[];
                  window.location.reload();
                }).catch(function (error) {
                  alert(4);
                  that.loading = false;
                  // console.log(error);
                  that.$message.error({showClose: true, message: '请求出现异常', duration: 3000});
                  that.$refs['addForm'].resetFields();
                  that.$refs['fileupload'].fileList=[];
                  window.location.reload();
                });
                /*let formData = new FormData();
                for (var i = that.files.length - 1; i >= 0; i--) {
                  formData.append("fileList[]", that.files[i]);
                }
                */
               
              }
           });
          },
          //批量删除
          batchDeletebook: function () {
            let ids = this.sels.map(item => item.id).toString();
            let that = this;
            this.$confirm('确认删除选中记录吗?', '提示', {
              type: 'warning'
            }).then(() => {
              that.loading = true;
              API.removeBatch(ids).then(function (result) {
                that.loading = false;
                if (result && parseInt(result.errcode) === 0) {
                  that.$message.success({showClose: true, message: '删除成功', duration: 1500});
                  that.search();
                }
              }, function (err) {
                that.loading = false;
                that.$message.error({showClose: true, message: err.toString(), duration: 2000});
              }).catch(function (error) {
                that.loading = false;
                // console.log(error);
                that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
              });
            }).catch(() => {
    
            });
          },
          /*changeDeviceType: function(obj){
            console.log("obj",obj);
            for(let i in obj) {
              let ob = {};
              ob.label = obj[i].dtname;
              ob.value = obj[i].dtname;
              ob.children = [];
              for(let j in obj[i].carModels){
                let oc = {};
                oc.label = obj[i].carModels[j].cname;
                oc.value = obj[i].carModels[j].cname;
                ob.children.push(oc);
              }
              this.newDeviceType.push(ob);
            }
            console.log("changeDeviceType2",this.newDeviceType);
          },*/
          /*searchDeviceType:function(){
            let that = this;
            APIdevice.findList().then(function (result) {
              console.log("devicetypesresult",result)
              that.loading = false;
              if (result && result.devicetypes) {
                console.log("result.devicetypes:",result.devicetypes);
                // that.newDeviceType = result.devicetypes;
                that.changeDeviceType(result.devicetypes);
                console.log("newDeviceType:",newDeviceType);
              }
              }, function (err) {
              that.loading = false;
              that.$message.error({showClose: true, message: err.toString(), duration: 2000});
              }).catch(function (error) {
                that.loading = false;
                that.search();
                that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
              });
          },*/
        },
        mounted() {
          this.handleSearch();
          /*console.log("this.newDeviceType.length1",this.$store.getters.getDevicetypes);
          if(this.$store.getters.getDevicetypes.length == 0){
            this.searchDeviceType();
            console.log("this.newDeviceType.length2",this.newDeviceType.length);
          }else{
            this.newDeviceType = this.$store.getters.getDevicetypes;
          }*/
        },
        computed: {
            newDeviceType:{
              get:function(){
                return this.$store.getters.getNewDeviceType;
              },
              set:function(){
    
              }
            },
            packages:{
              get:function(){
                return this.$store.getters.getPackages;
              },
              set:function(){
    
              }
            },
        },
      }
    </script>
    
    <style>
      .demo-table-expand label {
        font-weight: bold;
      }
      .el-table .warning-row {
        background: oldlace;
      }
    
      .el-table .success-row {
        background: #f0f9eb;
      }
      .el-table--scrollable-x .el-table__body-wrapper{
        overflow-x:hidden !important;
      }
    </style>

    changepwd.vue

    <template>
      <el-row class="warp">
        <el-col :span="24" class="warp-breadcrum">
          <el-breadcrumb separator="/">
            <!-- <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item> -->
            <el-breadcrumb-item>设置</el-breadcrumb-item>
            <el-breadcrumb-item>修改密码</el-breadcrumb-item>
          </el-breadcrumb>
        </el-col>
    
        <el-col :span="24" class="warp-main">
          <el-form ref="form" :model="form" label-width="120px">
            <el-form-item label="原密码">
              <el-input v-model="form.oldPwd"></el-input>
            </el-form-item>
            <el-form-item label="新密码">
              <el-input v-model="form.newPwd"></el-input>
            </el-form-item>
            <el-form-item label="确认新密码">
              <el-input v-model="form.confirmPwd"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="default" @click="handleChangepwd">提交</el-button>
            </el-form-item>
          </el-form>
        </el-col>
      </el-row>
    </template>
    <script>
      export default{
        data(){
          return {
            form: {
              oldPwd: '',
              newPwd: '',
              confirmPwd: ''
            }
          }
        },
        methods: {
          handleChangepwd() {
            this.$message({message: "此功能只是让你看看,不会开发!", duration: 2000});
          }
        }
      }
    </script>

    list.vue

    <template>
      <el-row class="warp">
        <el-col :span="24" class="warp-breadcrum">
          <el-breadcrumb separator="/">
            <!-- <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item> -->
            <el-breadcrumb-item>用户列表</el-breadcrumb-item>
          </el-breadcrumb>
        </el-col>
    
        <el-col :span="24" class="warp-main" v-loading="loading" element-loading-text="拼命加载中">
            <!--工具条-->
            <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
              <el-form :inline="true" :model="filters">
                <!-- <el-form-item>
                  <el-input v-model="filters.name" placeholder="用户名/姓名/昵称" style="min- 240px;" @keyup.enter.native="handleSearch"></el-input>
                </el-form-item> -->
                <el-form-item>
                  <el-button type="primary" @click="addAccount">添加账号</el-button>
                </el-form-item>
              </el-form>
            </el-col>
    
          <!--列表-->
          <el-table :data="accounts" highlight-current-row v-loading="loading" style=" 100%;">
            <el-table-column type="index" width="60">
            </el-table-column>
            <el-table-column prop="username" label="账号名" width="120" sortable>
            </el-table-column>
            <!-- <el-table-column prop="nickname" label="角色" width="120" :formatter="formatSex" sortable>
            </el-table-column> -->
            <el-table-column prop="permissions" label="权限" width="300"  sortable>
              <!-- 数据的遍历  scope.row就代表数据的每一个对象-->
              <template scope="scope" >  
                <p v-for="(item, index) in scope.row.permissions" :key="index" :label="item" style="font-size:16px;">
                  <span style="150px;display:block;float:left;">{{item.description}}</span>
                  <!-- <el-button @click.native="delCarModel(item)" size="mini" type="danger" plain round>删除车型</el-button> -->
                </p>
              </template>
            </el-table-column>
            <!-- <el-table-column prop="email" label="邮箱" min-width="160" sortable>
            </el-table-column>
            <el-table-column prop="addr" label="地址" sortable>
            </el-table-column> -->
            <el-table-column label="操作" width="220">
              <template slot-scope="scope">
                <el-button v-if="scope.row.state=== 1" @click.native="editDialog(scope.row)" type="warning" size="small">停用</el-button>
                <el-button v-if="" @click.native="editPermission(scope.row)" type="primary" size="small">修改权限</el-button>
                <!-- <el-button type="danger" @click.native="editDialog(scope.row,2)" size="small">删除</el-button> -->
                <!-- <el-button type="danger" @click="delbook(scope.$index,scope.row)" size="small">删除</el-button> -->
              </template>
            </el-table-column>
          </el-table>
    
          <!--新增账号界面-->
          <el-dialog title="新增账号" :visible.sync="accountvisible" :close-on-click-modal="false">
            <el-form :model="account" label-width="80px" :rules="accountrules" ref="accountForm">
              <el-form-item label="账号名" prop="username">
                <el-input v-model="account.username" auto-complete="off" placeholder="请输入账号名"></el-input>
              </el-form-item>
              <el-form-item label="账号密码" prop="password">
                <el-input v-model="account.password" type="password" auto-complete="off" placeholder="请输入6-10位字母、数字、下划线密码"></el-input>
              </el-form-item>
              <el-form-item label="重复密码" prop="password1">
                <el-input v-model="account.password1" type="password" auto-complete="off" placeholder="请输入重复密码"></el-input>
              </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
              <el-button @click.native="accountvisible = false">取消</el-button>
              <el-button type="submit"  @click.native="addSubmit" :loading="addLoading">提交</el-button>
            </div>
          </el-dialog>
    
          <!--修改权限界面-->
          <el-dialog title="修改权限" :visible.sync="permissionvisible" :close-on-click-modal="false">
            <el-form :model="account" label-width="80px" :rules="accountrules" ref="accountForm">
              <template>
                <el-transfer v-model="account_permission" :data="permissions"></el-transfer>
              </template>
            </el-form>
            <div slot="footer" class="dialog-footer">
              <el-button @click.native="permissionvisible = false">取消</el-button>
              <el-button type="submit"  @click.native="addSubmit" :loading="addLoading">提交</el-button>
            </div>
          </el-dialog>
    
        </el-col>
      </el-row>
    </template>
    
    <script>
      import API from '../../api/api_account';
      import md5 from 'js-md5';
      import { mapState, mapActions } from 'vuex';
    
      export default {
        data() {
          var validatePass2 = (rule, value, callback) => {
            if (value === '') {
              callback(new Error('请再次输入密码'));
            } else if (value !== this.account.password) {
              callback(new Error('两次输入密码不一致!'));
            } else {
              callback();
            }
          };
          return {
            filters: {
              name: ''
            },
            loading: false,
            // accounts: [],
            total: 0,
            page: 1,
            limit: 10,
            loading: false,
            accountvisible:false,
            addLoading: false, //转圈圈
            account: {
              username: '',
              password: '',
              password1:''
            },
            accountrules: {
              username: [
                {required: true, message: '请输入账号名', trigger: 'blur'},
                {pattern: /^(w){3,10}$/,message: '只能输入3-10个字母、数字、下划线'}
              ],
              password:[
                {required: true, message: '请输入账号密码', trigger: 'blur'},
                {pattern: /^(w){6,10}$/,message: '只能输入6-10个字母、数字、下划线'}
              ],
              password1:[
                {validator: validatePass2, trigger: 'blur'}
              ],
            },
            permissionvisible:false,
            // value1: [1, 4],
    
          }
        },
        methods: {
          editPermission(row){
            console.log("row:", row);
            this.permissionvisible = true;
          },
          addAccount(){
            this.accountvisible = true;
            this.account = {
              username:'',
              password:'',
              password1: '',
            };
          },
          //新增
          addSubmit: function () {
            let that = this;
            this.$refs.accountForm.validate((valid) => {
              if (valid) {
                let para = Object.assign({}, that.account);//复制对象,有filelist数组对象
                console.log("para:",para);
                para.password = md5(para.password);
                console.log("para:",para);
                API.add(para).then(function (result) {
                  if (result && parseInt(result.errcode) === 0) {
                    that.$message.success({showClose: true, message: result.mess, duration: 3000});
                    that.$refs['accountForm'].resetFields();
                    that.accountvisible = false;
                    that.search();
                  } else {
                    that.$message.error({showClose: true, message: result.mess, duration: 3000});
                    that.$refs['accountForm'].resetFields();
                    that.accountvisible = false;
                    that.search();
                  }
                }).catch(function (error) {
                      that.loading = false;
                      that.search();
                      that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                    });
              }
            });
          },
    
          //性别显示转换
          formatSex: function (row, column) {
            return row.sex == 1 ? '男' : row.sex == 0 ? '女' : '未知';
          },
          handleCurrentChange(val) {
            this.page = val;
            this.search();
          },
          handleSearch(){
            this.total = 0;
            this.page = 1;
            this.search();
          },
          //获取用户列表
          search: function () {
            let that = this;
            let params = {
              page: that.page,
              limit: 10,
              name: that.filters.name
            };
    
            that.loading = true;
            API.findList(params).then(function (result) {
              that.loading = false;
              if (result && result.accounts) {
                // that.total = result.total;
                // that.accounts = result.accounts;
                // console.log("result.accounts:",result.accounts);
                that.dispatch_accounts(result.accounts);
              }
            }, function (err) {
              that.loading = false;
              that.$message.error({showClose: true, message: err.toString(), duration: 2000});
            }).catch(function (error) {
              that.loading = false;
              console.log(error);
              that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
            });
    
            API.findPermissionList().then(function (result) {
              that.loading = false;
              if (result && result.permissions) {
                // that.total = result.total;
                // that.accounts = result.accounts;
                // console.log("result.permissions:",result.permissions);
                that.dispatch_permission(result.permissions);
              }
            }, function (err) {
              that.loading = false;
              that.$message.error({showClose: true, message: err.toString(), duration: 2000});
            }).catch(function (error) {
              that.loading = false;
              console.log(error);
              that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
            });
    
          },
          ...mapActions([
            'dispatch_accounts','dispatch_permission'
          ]),
        },
        computed: {
            accounts:{
              get:function(){
                return this.$store.getters.getAccounts;
              },
              set:function(){
              }
            },
            permissions:{
              get:function(){
                return this.$store.getters.getNewpermissions;
              },
              set:function(){
              }
            },
            account_permission:{
              get:function(){
                return this.accounts.permissions;
              },
              set:function(){
              }
            },
        },
        mounted() {
          this.handleSearch()
        }
      }
    </script>
    
    <style scoped>
    
    </style>

    profile.vue

    <template>
      <el-row class="warp">
        <el-col :span="24" class="warp-breadcrum" :loading="loading">
          <el-breadcrumb separator="/">
            <!-- <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item> -->
            <el-breadcrumb-item>设置</el-breadcrumb-item>
            <el-breadcrumb-item>个人信息</el-breadcrumb-item>
          </el-breadcrumb>
        </el-col>
    
        <el-col :span="24" class="warp-main">
          <el-form ref="form" :model="form" :rules="rules" label-width="80px">
            <el-form-item label="账号">
              <el-input v-model="form.useranme" disabled></el-input>
            </el-form-item>
            <el-form-item prop="nickname" label="昵称">
              <el-input v-model="form.nickname"></el-input>
            </el-form-item>
            <el-form-item prop="name" label="姓名">
              <el-input v-model="form.name"></el-input>
            </el-form-item>
            <el-form-item prop="email" label="邮箱">
              <el-input v-model="form.email"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="handleSaveProfile">修改并保存</el-button>
            </el-form-item>
          </el-form>
        </el-col>
      </el-row>
    </template>
    
    <script>
      import API from '../../api/api_account';
      import {bus} from '../../bus.js'
    
      export default {
        data() {
          return {
            loading: false,
            form: {
              useranme: '',
              nickname: '',
              name: '',
              email: ''
            },
            rules: {
              nickname: [
                {required: true, message: '请输入昵称', trigger: 'blur'}
              ],
              email: [
                {required: true, message: '请输入邮箱', trigger: 'blur'},
                {type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur,change'}
              ]
            },
          }
        },
        methods: {
          handleSaveProfile() {
            let that = this;
            that.$refs.form.validate((valid) => {
              if (valid) {
                that.loading = true;
                let args = {
                  nickname: that.form.nickname,
                  name: that.form.name,
                  email: that.form.email
                };
                API.changeProfile(args).then(function (result) {
                  that.loading = false;
                  if (result && parseInt(result.errcode) === 0) {
                    //修改成功
                    let user = JSON.parse(window.localStorage.getItem('access-user'));
                    user.nickname = that.form.nickname;
                    user.name = that.form.name;
                    user.email = that.form.email;
                    localStorage.setItem('access-user', JSON.stringify(user));
                    bus.$emit('setNickName', that.form.nickname);
                    that.$message.success({showClose: true, message: '修改成功', duration: 2000});
                  } else {
                    that.$message.error({showClose: true, message: result.errmsg, duration: 2000});
                  }
                }, function (err) {
                  that.loading = false;
                  that.$message.error({showClose: true, message: err.toString(), duration: 2000});
                }).catch(function (error) {
                  that.loading = false;
                  console.log(error);
                  that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                });
              }
            });
          }
        },
        mounted() {
          let user = localStorage.getItem('access-user');
          if (user) {
            user = JSON.parse(user);
            this.form.useranme = user.username;
            this.form.nickname = user.nickname || '';
            this.form.email = user.email || '';
            this.form.name = user.name || '';
          }
        }
      }
    </script>

    Home.vue

    <template>
      <el-row class="container">
        <!--头部-->
        <el-col :span="24" class="topbar-wrap">
          <div class="topbar-logo topbar-btn">
            <a href="/"><img src="../assets/logo.png" style="padding-left:8px;"></a>
          </div>
          <div class="topbar-logos" v-show="!collapsed">
            <a href="/"><img src="../assets/logotxt.png" width="120px"></a>
          </div>
          <div class="topbar-title">
            <span style="font-size: 18px;color: #fff;">远程升级平台后台管理系统</span>
          </div>
          <div class="topbar-account topbar-btn">
            <el-dropdown trigger="click">
              <span class="el-dropdown-link userinfo-inner"><i class="iconfont icon-user"></i> {{nickname}}  <i
                class="iconfont icon-down"></i></span>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item>
                  <div @click="jumpTo('/user/profile')"><span style="color: #555;font-size: 14px;">个人信息</span></div>
                </el-dropdown-item>
                <el-dropdown-item>
                  <div @click="jumpTo('/user/changepwd')"><span style="color: #555;font-size: 14px;">修改密码</span></div>
                </el-dropdown-item>
                <el-dropdown-item divided @click.native="logout">退出登录</el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </div>
        </el-col>
    
        <!--中间-->
        <el-col :span="24" class="main">
          <!--左侧导航-->
          <aside :class="{showSidebar:!collapsed}">
            <!--展开大折叠开关-->
            <div class="menu-toggle" @click.prevent="collapse">
              <i class="iconfont icon-menufold" v-show="!collapsed"></i>
              <i class="iconfont icon-menuunfold" v-show="collapsed"></i>
            </div>
            <!--导航菜单-->
            <el-menu :default-active="defaultActiveIndex" router :collapse="collapsed" @select="handleSelect">
              <template v-for="(item,index) in $router.options.routes" v-if="item.menuShow">
                <el-submenu v-if="!item.leaf" :index="index+''">
                  <!--主菜单-->
                  <template slot="title"><i :class="item.iconCls"></i><span slot="title">{{item.name}}</span></template>
                  <!--子菜单-->
                  <el-menu-item v-for="term in item.children" :key="term.path" :index="term.path" v-if="term.menuShow"
                                :class="$route.path==term.path?'is-active':''">
                    <!--"$route.path==term.path?'is-active':''"  菜单栏高亮-->
                    <i :class="term.iconCls"></i><span slot="title">{{term.name}}</span>
                  </el-menu-item>
                </el-submenu>
                <el-menu-item v-else-if="item.leaf&&item.children&&item.children.length" :index="item.children[0].path"
                              :class="$route.path==item.children[0].path?'is-active':''">
                  <i :class="item.iconCls"></i><span slot="title">{{item.children[0].name}}</span>
                </el-menu-item>
              </template>
            </el-menu>
          </aside>
    
          <!--右侧内容区-->
          <section class="content-container">
            <div class="grid-content bg-purple-light">
              <el-col :span="24" class="content-wrapper">
                <transition name="fade" mode="out-in">
                  <router-view></router-view>
                </transition>
              </el-col>
    
              <!--<el-col :span="14" class="footbar-wrap">
                <footer class="footer">
                  <hc-footer></hc-footer>
                </footer>
              </el-col>-->
    
            </div>
          </section>
        </el-col>
    
      <!-- <el-col :span="24" style="margin-down:0px;">
          <HcFooter></HcFooter>
      </el-col> -->
      </el-row>
    </template>
    
    <script>
      import {bus} from '../bus.js'
      import API from '../api/api_account';
      import HcFooter from '@/components/Footer'
    
      export default {
        name: 'home',
        components: {HcFooter},
        created(){//修改账号时触发事件
          bus.$on('setNickName', (text) => {
            this.nickname = text;
          })
          bus.$on('goto', (url) => {
            if (url === "/login") {
              localStorage.removeItem('access-user');
            }
            this.$router.push(url);
          })
        },
        data () {
          return {
            defaultActiveIndex: "0",
            nickname: '',
            collapsed: false,
          }
        },
        methods: {
          handleSelect(index){
            this.defaultActiveIndex = index;
          },
          //折叠导航栏
          collapse: function () {
            this.collapsed = !this.collapsed;
          },
          jumpTo(url){
            this.defaultActiveIndex = url;
            this.$router.push(url); //用go刷新
          },
          logout(){
            let that = this;
            this.$confirm('确认退出吗?', '提示', {
              confirmButtonClass: 'el-button--warning'
            }).then(() => {
              //确认
              that.loading = true;
              API.logout().then(function (result) {
                that.loading = false;
                localStorage.removeItem('access-user');
                that.$router.go('/login'); //用go刷新
              }, function (err) {
                that.loading = false;
                that.$message.error({showClose: true, message: err.toString(), duration: 2000});
              }).catch(function (error) {
                that.loading = false;
                console.log(error);
                that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
              });
            }).catch(() => {});
          }
        },
        mounted() {
          let user = localStorage.getItem('access-user');
          if (user) {
            user = JSON.parse(user);
            this.nickname = user.nickname || '';
          }
        }
      }
    </script>
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped lang="scss">
      .container {
        position: absolute;
        top: 0px;
        bottom: 0px;
         100%;
    
        .topbar-wrap {
          height: 50px;
          line-height: 50px;
          background: #373d41;
          padding: 0px;
    
          .topbar-btn {
            color: #fff;
          }
          /*.topbar-btn:hover {*/
          /*background-color: #4A5064;*/
          /*}*/
          .topbar-logo {
            float: left;
             59px;
            line-height: 26px;
          }
          .topbar-logos {
            float: left;
             120px;
            line-height: 26px;
          }
          .topbar-logo img, .topbar-logos img {
            height: 40px;
            margin-top: 5px;
            margin-left: 2px;
          }
          .topbar-title {
            float: left;
            text-align: left;
             200px;
            padding-left: 10px;
            border-left: 1px solid #000;
          }
          .topbar-account {
            float: right;
            padding-right: 12px;
          }
          .userinfo-inner {
            cursor: pointer;
            color: #fff;
            padding-left: 10px;
          }
        }
        .main {
          display: -webkit-box;
          display: -webkit-flex;
          display: -ms-flexbox;
          display: flex;
          position: absolute;
          top: 50px;
          bottom: 0px;
          overflow: hidden;
        }
    
        aside {
          min- 50px;
          background: #333744;
          &::-webkit-scrollbar {
            display: none;
          }
    
          &.showSidebar {
            overflow-x: hidden;
            overflow-y: auto;
          }
    
          .el-menu {
            height: 100%; /*写给不支持calc()的浏览器*/
            height: -moz-calc(100% - 80px);
            height: -webkit-calc(100% - 80px);
            height: calc(100% - 80px);
            border-radius: 0px;
            background-color: #333744;
            border-right: 0px;
          }
    
          .el-submenu .el-menu-item {
            min- 60px;
          }
          .el-menu {
             180px;
          }
          .el-menu--collapse {
             60px;
          }
    
          .el-menu .el-menu-item, .el-submenu .el-submenu__title {
            height: 46px;
            line-height: 46px;
          }
    
          .el-menu-item:hover, .el-submenu .el-menu-item:hover, .el-submenu__title:hover {
            background-color: #7ed2df;
          }
        }
    
        .menu-toggle {
          background: #4A5064;
          text-align: center;
          color: white;
          height: 26px;
          line-height: 30px;
        }
    
        .content-container {
          background: #fff;
          flex: 1;
          overflow-y: auto;
          padding: 10px;
          padding-bottom: 1px;
    
          .content-wrapper {
            background-color: #fff;
            box-sizing: border-box;
          }
    
          .footbar-wrap{
            bottom: 0px;
            padding-bottom: 0px;
          }
        }
      }
    </style>

    Index.vue

    <template>
      <el-row class="warp">
        <el-col :span="24" class="warp-breadcrum">
          <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item>
          </el-breadcrumb>
        </el-col>
    
        <el-col :span="24" class="warp-main">
          <section class="chart-container">
            <el-row>
              <el-col :span="8">
                <el-card :body-style="{ padding: '0px' }">
                  <img src="../assets/images/forest.png" class="image">
                  <div style="padding: 14px;">
                    <span>行行出状元,处处有金杯</span>
                    <div class="bottom clearfix">
                      <time class="time">{{ currentDate }}</time>
                    </div>
                  </div>
                </el-card>
              </el-col>
              <el-col :span="8">
                <el-card :body-style="{ padding: '0px' }">
                  <img src="../assets/images/sunrise.png" class="image">
                  <div style="padding: 14px;">
                    <span>华晨金杯750</span>
                    <div class="bottom clearfix">
                      <time class="time">{{ currentDate }}</time>
                    </div>
                  </div>
                </el-card>
              </el-col>
              <el-col :span="8">
                <el-card :body-style="{ padding: '0px' }">
                  <img src="../assets/images/sunshine.png" class="image">
                  <div style="padding: 14px;">
                    <span>斯威汽车</span>
                    <div class="bottom clearfix">
                      <time class="time">{{ currentDate }}</time>
                    </div>
                  </div>
                </el-card>
              </el-col>
              <el-col :span="12">
                <div id="chartColumn" style="100%; height:400px;"></div>
              </el-col>
              <el-col :span="12">
                <div id="chartBar" style="100%; height:400px;"></div>
              </el-col>
              <el-col :span="12">
                <div id="chartLine" style="100%; height:400px;"></div>
              </el-col>
              <el-col :span="12">
                <div id="chartPie" style="100%; height:400px;"></div>
              </el-col>
              <el-col :span="24">
                <a href="http://echarts.baidu.com/examples.html" target="_blank" style="float: right;">more>></a>
              </el-col>
            </el-row>
          </section>
    
        </el-col>
      </el-row>
    </template>
    <style>
      .time {
        font-size: 13px;
        color: #999;
      }
    
      .bottom {
        margin-top: 13px;
        line-height: 12px;
      }
    
      .image {
         100%;
        display: block;
      }
    
      .clearfix:before,
      .clearfix:after {
        display: table;
        content: "";
      }
    
      .clearfix:after {
        clear: both
      }
    
      .chart-container {
         100%;
      }
      .chart-container .el-col {
        padding: 30px 20px;
      }
    </style>
    
    <script>
      import echarts from 'echarts'
    
      export default {
        data() {
          return {
            currentDate: new Date(),
            chartColumn: null,
            chartBar: null,
            chartLine: null,
            chartPie: null
          };
        },
        mounted: function () {
          var _this = this;
          //基于准备好的dom,初始化echarts实例
          this.chartColumn = echarts.init(document.getElementById('chartColumn'));
          this.chartBar = echarts.init(document.getElementById('chartBar'));
          this.chartLine = echarts.init(document.getElementById('chartLine'));
          this.chartPie = echarts.init(document.getElementById('chartPie'));
    
          this.chartColumn.setOption({
            title: { text: '销量柱状图' },
            tooltip: {},
            xAxis: {
              data: ["鑫源小海狮", "鑫源s402", "鑫源x7", "鑫源摩托", "鑫源头盔", "鑫源农机"]
            },
            yAxis: {},
            series: [{
              name: '销量',
              type: 'bar',
              data: [50000, 20009, 36000, 10000, 10000, 20000]
            }]
          });
    
          this.chartBar.setOption({
            title: {
              text: '条状图',
              subtext: '数据来自网络'
            },
            tooltip: {
              trigger: 'axis',
              axisPointer: {
                type: 'shadow'
              }
            },
            legend: {
              data: ['2011年', '2012年']
            },
            grid: {
              left: '3%',
              right: '4%',
              bottom: '3%',
              containLabel: true
            },
            xAxis: {
              type: 'value',
              boundaryGap: [0, 0.01]
            },
            yAxis: {
              type: 'category',
              data: ['鑫源小海狮', '鑫源s402', '鑫源x7', '鑫源摩托', '鑫源头盔', '鑫源总数(万)']
            },
            series: [
              {
                name: '2011年',
                type: 'bar',
                data: [18203, 23489, 29034, 104970, 131744, 630230]
              },
              {
                name: '2012年',
                type: 'bar',
                data: [19325, 23438, 31000, 121594, 134141, 681807]
              }
            ]
          });
    
          this.chartLine.setOption({
            title: {
              text: '线状图'
            },
            tooltip: {
              trigger: 'axis'
            },
            legend: {
              data: ['鑫源小海狮', '鑫源s402', '鑫源x7']
            },
            grid: {
              left: '3%',
              right: '4%',
              bottom: '3%',
              containLabel: true
            },
            xAxis: {
              type: 'category',
              boundaryGap: false,
              data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
            },
            yAxis: {
              type: 'value'
            },
            series: [
              {
                name: '鑫源小海狮',
                type: 'line',
                stack: '总量',
                data: [120, 132, 101, 134, 90, 230, 210]
              },
              {
                name: '鑫源s402',
                type: 'line',
                stack: '总量',
                data: [220, 182, 191, 234, 290, 330, 310]
              },
              {
                name: '鑫源x7',
                type: 'line',
                stack: '总量',
                data: [820, 932, 901, 934, 1290, 1330, 1320]
              }
            ]
          });
    
          this.chartPie.setOption({
            title: {
              text: '饼状图',
              subtext: '数据来自网络',
              x: 'center'
            },
            tooltip: {
              trigger: 'item',
              formatter: "{a} <br/>{b} : {c} ({d}%)"
            },
            legend: {
              orient: 'vertical',
              left: 'left',
              data: ['鑫源小海狮', '鑫源s402', '鑫源x7', '鑫源摩托', '鑫源头盔']
            },
            series: [
              {
                name: '访问来源',
                type: 'pie',
                radius: '55%',
                center: ['50%', '60%'],
                data: [
                  { value: 335, name: '鑫源小海狮' },
                  { value: 310, name: '鑫源s402' },
                  { value: 234, name: '鑫源x7' },
                  { value: 135, name: '鑫源摩托' },
                  { value: 1548, name: '鑫源头盔' }
                ],
                itemStyle: {
                  emphasis: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                  }
                }
              }
            ]
          });
        }
      }
    </script>

    Login.vue

    <template>
      <el-form ref="AccountFrom" :model="account" :rules="rules" label-position="left" label-width="0px"
               class="demo-ruleForm login-container">
        <h3 class="title">管理员登录</h3>
        <el-form-item prop="username">
          <el-input type="text" v-model="account.username" auto-complete="off" placeholder="账号"></el-input>
        </el-form-item>
        <el-form-item prop="pwd">
          <el-input type="password" v-model="account.pwd" auto-complete="off" placeholder="密码"></el-input>
        </el-form-item>
        <!--<el-checkbox v-model="checked" checked class="remember">记住密码</el-checkbox>-->
        <el-form-item style="100%;">
          <el-button type="primary" style="100%;" @click.native.prevent="handleLogin" :loading="loading">登录</el-button>
        </el-form-item>
      </el-form>
    </template>
    
    <script>
      import API from '../api/api_account';
    
      export default {
        data() {
          return {
            loading: false,
            account: {
              username: 'admin',
              pwd: '123456'
            },
            rules: {
              username: [
                {required: true, message: '请输入账号', trigger: 'blur'},
                //{ validator: validaePass }
              ],
              pwd: [
                {required: true, message: '请输入密码', trigger: 'blur'},
                //{ validator: validaePass2 }
              ]
            },
            checked: true
          };
        },
        methods: {
          handleLogin() {
            let that = this;
            this.$refs.AccountFrom.validate((valid) => {
              if (valid) {
                this.loading = true;
                let loginParams = {username: this.account.username, pwd: this.account.pwd};
                API.login(loginParams).then(function (result) {
                  that.loading = false;
                  if (result && result.id) {
                    localStorage.setItem('access-user', JSON.stringify(result));
    //                that.$store.commit('SET_ROUTERS', user.permissions)
    //                that.$router.addRoutes(that.$store.getters.addRouters);
    //                that.$router.options.routes = that.$store.getters.routers;
                      that.$router.push({path: '/'});
                  } else {
                    that.$message.error({showClose: true, message: result.errmsg || '登录失败', duration: 2000});
                  }
                }, function (err) {
                  that.loading = false;
                  that.$message.error({showClose: true, message: err.toString(), duration: 2000});
                }).catch(function (error) {
                  that.loading = false;
                  console.log(error);
                  that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
                });
              }
            });
          }
        }
      }
    </script>
    <style>
      body {
        background: #DFE9FB;
      }
    </style>
    <style lang="scss" scoped>
      .login-container {
        /*box-shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.06), 0 1px 0px 0 rgba(0, 0, 0, 0.02);*/
        -webkit-border-radius: 5px;
        border-radius: 5px;
        -moz-border-radius: 5px;
        background-clip: padding-box;
        margin: 160px auto;
        width: 350px;
        padding: 35px 35px 15px 35px;
        background: #fff;
        border: 1px solid #eaeaea;
        box-shadow: 0 0 25px #cac6c6;
    
        background: -ms-linear-gradient(top, #ace, #00C1DE); /* IE 10 */
        background: -moz-linear-gradient(top, #ace, #00C1DE); /*火狐*/
        background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ace), to(#00C1DE)); /*谷歌*/
        background: -webkit-linear-gradient(top, #ace, #00C1DE); /*Safari5.1 Chrome 10+*/
        background: -o-linear-gradient(top,#ace, #00C1DE); /*Opera 11.10+*/
    
        .title {
          margin: 0px auto 40px auto;
          text-align: center;
          color: #505458;
        }
        .remember {
          margin: 0px 0px 35px 0px;
        }
      }
    </style>

    index.js

    import Vue from 'vue'
    import Router from 'vue-router'
    import Home from '@/components/Home'
    import index from '@/components/Index'
    
    import packageList from '@/components/filelist/packageList'
    import avnList from '@/components/filelist/avnlist'
    import ipcList from '@/components/filelist/ipclist'
    
    import bookCategoryList from '@/components/bookcategory/list'
    import UserList from '@/components/user/list'
    import UserChangePwd from '@/components/user/changepwd'
    import UserProbook from '@/components/user/profile'
    
    import Device from '@/components/device/device'
    
    import store from '@/store/'
    
    // 懒加载方式,当路由被访问的时候才加载对应组件
    //箭头函数是省略了function函数名和return,resolve是形参,require是函数体并且是return。
    const Login = resolve => require(['@/components/Login'], resolve)
    
    Vue.use(Router)
    
    let router = new Router({
    // mode: 'history',
      routes: [ //根据这个遍历得到左边菜单
        {
          path: '/login',
          name: '登录',
          component: Login
        },
        /*{
          path: '/',
          name: 'home',
          component: Home,
          redirect: '/index',  //加载右边
          leaf: true, // 只有一个节点
          menuShow: true,
          iconCls: 'iconfont icon-home', // 图标样式class
          children: [
            {
              path: '/index',
              component: index,
              name: '鑫源简介',
              menuShow: true
            }
    
          ]
        },*/
        /*{
          path: '/',
          component: Home,
          name: '升级包管理',
          menuShow: true,
          iconCls: 'iconfont icon-books',
          children: [
            {
              path: '/filelist/tboxlist',
              component: tboxList,
              name: 'tbox升级包列表',
              menuShow: true  //true则Home.vue会加载这个条目,否则不加载
            },
            {
              path: '/filelist/avnlist',
              component: avnList,
              name: 'AVN升级包列表',
              menuShow: true
            },
            {
              path: '/filelist/ipclist',
              component: ipcList,
              name: 'IPC升级包列表',
              menuShow: true
            }
          ]
        },*/
        {
          path: '/',
          component: Home,
          name: '升级包管理',
          menuShow: true,
          leaf: true, // 只有一个节点
          redirect: '/filelist/packagelist',  //加载右边
          iconCls: 'iconfont icon-users', // 图标样式class
          children: [
            {
              path: '/filelist/packagelist',
              component: packageList,
              name: '升级包管理',
              menuShow: true
            }
          ]
        },
        {
          path: '/',
          component: Home,
          name: '设备类型管理',
          menuShow: true,
          leaf: true, // 只有一个节点
          iconCls: 'iconfont icon-users', // 图标样式class
          children: [
            {
              path: '/device/list',
              component: Device,
              name: '设备类型列表',
              menuShow: true
            }
          ]
        },
        {
          path: '/',
          component: Home,
          name: '用户管理',
          menuShow: true,
          leaf: true, // 只有一个节点
          iconCls: 'iconfont icon-users', // 图标样式class
          children: [
            {
              path: '/user/list',
              component: UserList,
              name: '用户列表',
              menuShow: true
            }
          ]
        },
        {
          path: '/',
          component: Home,
          name: '设置',
          menuShow: true,
          iconCls: 'iconfont icon-setting1',
          children: [
            {
              path: '/user/probook', 
              component: UserProbook, 
              name: '个人信息', 
              menuShow: true
            },
            {
              path: '/user/changepwd', 
              component: UserChangePwd, 
              name: '修改密码', 
              menuShow: true
            }
          ]
        },
      ]
    })
    
    router.beforeEach((to, from, next) => {//每次路由都会走
      /*console.log('to:' + to.path)
      console.log('from:' + from.path)
      console.log('next:' + next.path)*/
      /*if(to.path.startsWith('/filelist/packagelist')){
        store:Store {_committing: false, _actions: {…}, _actionSubscribers: 
        Array(0), _mutations: {…}, _wrappedGetters: {…}, …}
        if(store.getters.getDevicetypes.length = 0)
          console.log("store.getters.getDevicetypes;",store.getters.getDevicetypes);
      }*/
      if (to.path.startsWith('/login')) {
        window.localStorage.removeItem('access-user')
        next()
      } else {
        let user = JSON.parse(window.localStorage.getItem('access-user'))
        if (!user) {
          next({path: '/login'})
        } else {
          next()
        }
    
      }
    })
    
    export default router

    actions.js

    // 页面调用action,action调用mutation来设置数据state
    import * as types from './mutations_types';
    
    export default {
        dispatch_devicetypes:({
            commit
        }, obj) => {
            commit(types.ALL_DEVICETYPES, obj);
        },
        dispatch_packages:({
            commit
        }, obj) => {
            commit(types.ALL_PACKAGES, obj);
        },
        dispatch_accounts:({
            commit
        }, obj) => {
            commit(types.ALL_ACCOUNTS, obj);
        },
        dispatch_permission:({
            commit
        }, obj) => {
            commit(types.ALL_PERMISSION, obj);
        },
    
        /*update_cur_shop_status: ({
            commit
        }, obj) => {
            commit(types.UPDATE_CUR_SHOP_STATUS, obj);
        },
        create_db: ({
            commit
        }, {
            shop
        }) => {
            commit(types.CREATE_DB, shop);
            commit(types.UPDATE_LOCAL);
        },
        add_db: ({
            commit
        }) => {
            commit(types.ADD_DB);
            commit(types.UPDATE_LOCAL);
        },*/
    };

    getters.js

    /*getter是state的get方法,没有get页面就获取不到数据
    
    获取页面:
    import {mapGetters,mapActions} from 'vuex'
     <h1>{{count}}</h1>
    computed:mapGetters([
     'count'
     ]),
    
    store.js:
    
    var state = {
     count:6
    },
    var getters={
     count(state){
      return state.count
     }
    }
    
    改变数据页面:
    <button @click="increment">增加</button>
    methods:mapActions([
     //该 increment 来自 store.js 中导出的 actions 和 mutations 中的 increment 
     'increment',
     ])
    
    先发给action:
    const actions ={
     // ({commit,state}) 这种写法是 es6 中的对象解构
     increment({commit,state}){
      //提交一个名为 increment 的变化,名字可自定义,可以认为是类型名,与下方 mutations 中的 increment 对应
      //commit 提交变化,修改数据的唯一方式就是显式的提交 mutations
      commit('increment') 
     }
    }
    再发给mutations:
    const mutations ={
     //与上方 commit 中的 ‘increment' 相对应
     increment(state){
      state.count ++;
     }
    }
    */
    //页面调用数据的getter方法来获取数据states
    export default {
        getInfos(state) {
            state.cartInfos.total_price = 0;
            state.cartInfos.total_nums = 0;
            var list = state.cartList;
            for (var i = 0; i < list.length; i++) {
                var price = parseInt(list[i].price),
                    num = parseInt(list[i].num);
    
                state.cartInfos.total_price += price * num;
                state.cartInfos.total_nums += num;
            }
            return state.cartInfos;
        },
        getCartList(state) {
            return state.cartList;
        },
        getDevicetypes(state) {
            return state.devicetypes;
        },
        getNewDeviceType(state) {
            return state.newDeviceType;
        },
        getPackages(state) {
            return state.packages;
        },
        getAccounts:state=> state.accounts,
    
        getPermissions:state => state.permissions,
    
        getNewpermissions:state => state.newpermissions,
    
        /*getAccounts:state =>state.accounts,
    
        getPermissions:state => state.permissions,*/
    };

    index.js

    import Vue from 'vue'
    import state from './state';
    import mutations from './mutations';
    import getters from './getters';
    import actions from './actions';
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
        state,
        mutations,
        getters,
        actions
    })

    mutations.js

    import * as types from './mutations_types'
    
    export default {
        [types.ALL_DEVICETYPES](state, obj) {
            state.devicetypes = obj;
            let newDeviceType = [];
            for(let i in obj) {
              let ob = {};
              ob.label = obj[i].dtname;
              ob.value = obj[i].dtname;
              ob.children = [];
              for(let j in obj[i].carModels){
                let oc = {};
                oc.label = obj[i].carModels[j].cname;
                oc.value = obj[i].carModels[j].cname;
                ob.children.push(oc);
              }
              newDeviceType.push(ob);
            }
            state.newDeviceType = newDeviceType;
        },
    
        [types.ALL_PACKAGES](state, obj) {
            state.packages = obj;
        },
        [types.ALL_ACCOUNTS](state, obj) {
            console.log("ALL_ACCOUNTS : ",obj);
            state.accounts = obj;
        },
        [types.ALL_PERMISSION](state, obj) {
            state.permissions = obj;
            console.log("state.permissions:",state.permissions);
            let newpermissions = [];
            for(let i in obj) {
              let ob = {};
              ob.key = obj[i].pid;
              ob.label = obj[i].pdescription;
              newpermissions.push(ob);
            }
            state.newpermissions = newpermissions;
            console.log("state.newpermissions:",state.newpermissions);
        },
    
        /*[types.CLEAR_LOCAL](state) {
            state.cartList.forEach(function(item) {
                item.num = 0;
            });
            state.cartList = [];
            localStorage.removeItem('vuex_cart');
        },
        [types.UPDATE_LOCAL](state) {
            localStorage.setItem('vuex_cart', JSON.stringify(state.cartList));
        },
        [types.UPDATE_CUR_SHOP_STATUS](state, {
            index = -1
        }) {
            state.curIndex = index;
        },
        [types.DELETE_DB](state) {
            if (state.curIndex >= 0) {
                state.cartList[state.curIndex].num = 0;
                state.cartList.splice(state.curIndex, 1);
            }
        },
        [types.CREATE_DB](state, shop) {
            // console.log('mu create');
    
            state.cartList.push(shop);
        },
        [types.ADD_DB](state) {
            // console.log('mu add id:' + state.curIndex);
    
            state.cartList[state.curIndex].num = parseInt(state.cartList[state.curIndex].num);
            state.cartList[state.curIndex].num++;
        },
        [types.REDUCE_DB](state) {
            // console.log('mu reduce');
    
            state.cartList[state.curIndex].num = parseInt(state.cartList[state.curIndex].num);
            state.cartList[state.curIndex].num--;
    
            // console.log(state.cartList[state.curIndex].num);
            if (state.cartList[state.curIndex].num == 0) {
                state.cartList.splice(state.curIndex, 1);
            }
        },
        [types.CHECK_DB](state, {
            id
        }) {
            // console.log('mu check id :' + id);
            // console.log(state.cartList);
    
            state.curIndex = -1;
    
            var list = state.cartList;
            if (list.length) {
                for (var i = 0; i < list.length; i++) {
                    if (list[i].id == id) {
                        state.curIndex = i;
                        break;
                    }
                }
            }
        }*/
    };

    mutations_types.js

    /*//添加菜品到购物车
    export const CREATE_DB = 'CREATE_DB';
    
    //给购物车的菜品++
    export const ADD_DB = 'ADD_DB';
    
    //给购物车的菜品--
    export const REDUCE_DB = 'REDUCE_DB';
    
    //删除购物车的索引
    export const DELETE_DB = 'DELETE_DB';
    
    //更新当前菜品在购物车的状态
    export const UPDATE_CUR_SHOP_STATUS = 'UPDATE_CUR_SHOP_STATUS';
    
    //检测购物车内是否存在某菜品
    export const CHECK_DB = 'CHECK_DB';
    
    //更新本地数据
    export const UPDATE_LOCAL = 'UPDATE_LOCAL';
    
    //清空本地数据
    export const CLEAR_LOCAL = 'CLEAR_LOCAL';*/
    
    export const ALL_DEVICETYPES = 'ALL_DEVICETYPES';
    export const ALL_PACKAGES = 'ALL_PACKAGES';
    export const ALL_ACCOUNTS = 'ALL_ACCOUNTS';
    export const ALL_PERMISSION = 'ALL_PERMISSION';

    state.js

    export default {
    
        devicetypes:[], //设备类型
        newDeviceType:[],
        packages: [],//升级包
        accounts: [],//账号
        permissions:[],//权限
        newpermissions:[],
    
        /*//购物车列表
        cartList: localStorage.getItem('vuex_cart') ? JSON.parse(localStorage.getItem('vuex_cart')) : [],
    
        //当前购物车信息
        cartInfos: {
            total_price: 0,
            total_nums: 0
        },
    
        //当前菜品是否在购物车的状态。在则是对应的索引,不在则是-1
        curIndex: -1*/
    };

    App.vue

    <template>
      <div id="app">
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    export default {
      name: 'app'
    }
    </script>
    
    <style>
    body{
      padding:0px;
      margin:0px auto;
    }
    a{
      text-decoration:none;
    }
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: left;
      color: #2c3e50;
    }
    </style>

    bus.js

    /**
     * Created by jerry on 2017/4/14.
     */
    import Vue from 'vue'
    
    export let bus = new Vue()

    main.js

    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    import '@/assets/iconfont.css'
    import '@/assets/styles/main.scss'
    import curvejs from 'curvejs'  //画线的
    
    Object.defineProperty(Vue.prototype, '$curvejs', { value: curvejs });
    Vue.config.productionTip = false
    Vue.use(ElementUI)
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      template: '<App/>',
      components: {App}
    })

    index.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>远程升级服务</title>
      </head>
      <body>
        <div id="app"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>

    package.json

    {
      "name": "litadmin",
      "version": "1.2.1",
      "description": "A Vue.js project for admin",
      "author": "jerry9022@qq.com",
      "private": true,
      "scripts": {
        "server": "node server/bin/www",
        "dev": "node build/dev-server.js",
        "build": "node build/build.js"
      },
      "dependencies": {
        "axios": "^0.16.2",
        "echarts": "^3.7.1",
        "element-ui": "^2.0.7",
        "js-md5": "^0.7.3",
        "lodash": "^4.17.4",
        "vue": "^2.5.9",
        "vue-router": "^2.8.1",
        "vue-template-compiler": "^2.5.9",
        "vuex": "^3.0.1"
      },
      "devDependencies": {
        "autoprefixer": "^6.7.2",
        "babel-core": "^6.26.0",
        "babel-loader": "^6.2.10",
        "babel-plugin-transform-runtime": "^6.22.0",
        "babel-preset-env": "^1.6.0",
        "babel-preset-stage-2": "^6.24.1",
        "babel-register": "^6.26.0",
        "chalk": "^1.1.3",
        "connect-history-api-fallback": "^1.3.0",
        "copy-webpack-plugin": "^4.0.1",
        "css-loader": "^0.26.4",
        "eventsource-polyfill": "^0.9.6",
        "express": "^4.15.4",
        "extract-text-webpack-plugin": "^2.1.2",
        "file-loader": "^0.10.0",
        "friendly-errors-webpack-plugin": "^1.1.3",
        "function-bind": "^1.1.1",
        "html-webpack-plugin": "^2.30.1",
        "http-proxy-middleware": "^0.17.3",
        "node-sass": "^4.5.3",
        "opn": "^4.0.2",
        "optimize-css-assets-webpack-plugin": "^1.3.2",
        "ora": "^1.3.0",
        "rimraf": "^2.6.2",
        "sass-loader": "^6.0.6",
        "semver": "^5.4.1",
        "style-loader": "^0.16.1",
        "url-loader": "^0.5.9",
        "vue-loader": "^11.1.4",
        "vue-style-loader": "^2.0.0",
        "webpack": "^2.7.0",
        "webpack-bundle-analyzer": "^2.9.0",
        "webpack-dev-middleware": "^1.12.0",
        "webpack-hot-middleware": "^2.19.1",
        "webpack-merge": "^2.6.1"
      },
      "engines": {
        "node": ">= 4.0.0",
        "npm": ">= 3.0.0"
      },
      "browserslist": [
        "> 1%",
        "last 2 versions",
        "not ie <= 8"
      ]
    }

     main.js

    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    import '@/assets/iconfont.css'
    import '@/assets/styles/main.scss'
    import curvejs from 'curvejs'  //画线的
    import store from '@/store/'
    
    Object.defineProperty(Vue.prototype, '$curvejs', { value: curvejs });
    Vue.config.productionTip = false
    Vue.use(ElementUI)
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      store, //会自动注册给子组件,在子组件中通过 this.$store 访问
      template: '<App/>',
      components: {App}
    })
  • 相关阅读:
    博客图片上传picgo工具安装配置github图传使用
    安装配置hexo icarus主题配置
    通往远方的道路总是漫长的
    java 关于值引用、地址引用的问题
    Java设计模式の迭代器模式
    Java设计模式の模版方法模式
    vim 常用快捷键(整理版)
    Java设计模式の责任链模式
    Java设计模式の代理模式
    java rmi远程方法调用实例
  • 原文地址:https://www.cnblogs.com/yaowen/p/8963986.html
Copyright © 2011-2022 走看看