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="width: 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="width: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="width: 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="width: 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="width: 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-width: 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="width: 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="width: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;
    width: 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;
        width: 59px;
        line-height: 26px;
      }
      .topbar-logos {
        float: left;
        width: 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;
        width: 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-width: 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-width: 60px;
      }
      .el-menu {
        width: 180px;
      }
      .el-menu--collapse {
        width: 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="width:100%; height:400px;"></div>
          </el-col>
          <el-col :span="12">
            <div id="chartBar" style="width:100%; height:400px;"></div>
          </el-col>
          <el-col :span="12">
            <div id="chartLine" style="width:100%; height:400px;"></div>
          </el-col>
          <el-col :span="12">
            <div id="chartPie" style="width: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 {
    width: 100%;
    display: block;
  }

  .clearfix:before,
  .clearfix:after {
    display: table;
    content: "";
  }

  .clearfix:after {
    clear: both
  }

  .chart-container {
    width: 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="width:100%;">
      <el-button type="primary" style="width: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": "[email protected]",
  "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"
  ]
}

猜你喜欢

转载自www.cnblogs.com/yaowen/p/8963986.html
今日推荐