api_account.js
import * as API from './' export default { //登录 login: params => { return API.POST('login/', params) }, //登出 logout: params => { return API.GET('/api/v1/users/logout', params) }, //修改个人信息 changeProfile: params => { return API.PATCH('/api/v1/users/profile', params) }, //查询获取user列表(通过page分页) findList: params => { return API.GET('account/all', params) }, add: params => { return API.POST('account/add', params) }, findPermissionList:params => { return API.POST('account/permissions', params) }, }
api_device.js
import * as API from './' export default { //查询获取列表(通过page分页) findList: params => { return API.POST('deviceType/all', params) }, //添加 add: params => { return API.POST(`deviceType/add`, params) }, /* //查询获取一条信息 findById: id => { return API.GET(`/api/v1/books/${id}`) }, //更新 update: (id, params) => { return API.PUT(`/api/v1/books/${id}`, params) }, //单个删除 remove: id => { return API.DELETE(`/api/v1/books/${id}`) }, //批量删除,传ids数组 removeBatch: (ids) => { return API.DELETE(`/api/v1/books/batch/${ids}`) },*/ //添加车型 addCM: params => { return API.POST(`carmodel/add`, params) }, delCM:id => { return API.GET(`carmodel/delete/${id}`) }, delDT:id => { return API.GET(`deviceType/delete/${id}`) }, }
api_file.js
import * as API from './' import Vue from 'vue' export default { /* //查询获取列表(通过page分页) findList: params => { return API.GET('/api/v1/books', params) }, //查询获取一条信息 findById: id => { return API.GET(`/api/v1/books/${id}`) }, add: params => { return API.POST(`/api/v1/books`, params) }, update: (id, params) => { return API.PUT(`/api/v1/books/${id}`, params) }, //单个删除 remove: id => { return API.DELETE(`/api/v1/books/${id}`) }, //批量删除,传ids数组 removeBatch: (ids) => { return API.DELETE(`/api/v1/books/batch/${ids}`) },*/ //新增方法 findTboxList: params => { return API.POST('package/all', params) }, addtboxForm: (params,config) => { return API.POSTFORM(`package/add`, params,config) }, modify:(params) => { return API.POST(`package/modify`, params) } }
index.js
import axios from 'axios' import {bus} from '../bus.js' // Object.defineProperty(Vue.prototype, '$axios', { value: axios }); axios.defaults.withCredentials = true; // axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';//配置请求头 //添加一个请求拦截器 axios.interceptors.request.use(function (config) { console.dir(config); return config; }, function (error) { // Do something with request error return Promise.reject(error); }); // 添加一个响应拦截器 axios.interceptors.response.use(function (response) { // alert("响应拦截器") if (response.data && response.data.errcode) { if (parseInt(response.data.errcode) === 40001) { //未登录 bus.$emit('goto', '/login') } } return response; }, function (error) { // Do something with response error return Promise.reject(error); }); //基地址 let base = 'http://127.0.0.1:8086/'; //接口代理地址参见:config/index.js中的proxyTable配置 //通用方法 export const POST = (url, params) => { return axios.post(`${base}${url}`, params).then(res => res.data).catch(function (error) { alert("请求出现异常"); console.log(error); // window.location.reload(); }); } export const GET = (url, params) => { return axios.get(`${base}${url}`, {params: params}).then(res => res.data).catch(function (error) { alert("请求出现异常"); console.log(error); // window.location.reload(); }); } export const PUT = (url, params) => { return axios.put(`${base}${url}`, params).then(res => res.data) } export const DELETE = (url, params) => { return axios.delete(`${base}${url}`, {params: params}).then(res => res.data) } export const PATCH = (url, params) => { return axios.patch(`${base}${url}`, params).then(res => res.data) } export const POSTFORM = (url, params,config) => { return axios.post(`${base}${url}`, params,config).then(res => res.data).catch(function (error) { alert("请求出现异常"); console.log(error); // window.location.reload(); }); }
util.js
/** * Created by jerry on 2017/4/14. */ var SIGN_REGEXP = /([yMdhsm])(1*)/g var DEFAULT_PATTERN = 'yyyy-MM-dd' function padding (s, len) { let l = len - (s + '').length for (var i = 0; i < l; i++) { s = '0' + s } return s }; export default { getQueryStringByName: function (name) { var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i') var r = window.location.search.substr(1).match(reg) var context = '' if (r != null) { context = r[2] } reg = null r = null return context === null || context === '' || context === 'undefined' ? '' : context }, formatDate: { format: function (date, pattern) { pattern = pattern || DEFAULT_PATTERN return pattern.replace(SIGN_REGEXP, function ($0) { switch ($0.charAt(0)) { case 'y': return padding(date.getFullYear(), $0.length) case 'M': return padding(date.getMonth() + 1, $0.length) case 'd': return padding(date.getDate(), $0.length) case 'w': return date.getDay() + 1 case 'h': return padding(date.getHours(), $0.length) case 'm': return padding(date.getMinutes(), $0.length) case 's': return padding(date.getSeconds(), $0.length) } }) }, parse: function (dateString, pattern) { var matchs1 = pattern.match(SIGN_REGEXP) var matchs2 = dateString.match(/(d)+/g) if (matchs1.length === matchs2.length) { var _date = new Date(1970, 0, 1) for (var i = 0; i < matchs1.length; i++) { var _int = parseInt(matchs2[i]) var sign = matchs1[i] switch (sign.charAt(0)) { case 'y': _date.setFullYear(_int); break case 'M': _date.setMonth(_int - 1); break case 'd': _date.setDate(_int); break case 'h': _date.setHours(_int); break case 'm': _date.setMinutes(_int); break case 's': _date.setSeconds(_int); break } } return _date } return null } } }
list.vue
<template>
<el-row class="warp">
<el-col :span="24" class="warp-breadcrum">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :span="24" class="warp-main">
<h2>仄仄仄仄仄仄!</h2>
</el-col>
</el-row>
</template>
<script>
export default{
data(){
return {
msg: 'hello vue'
}
}
}
</script>
device.vue
<template>
<el-row class="warp">
<el-col :span="24" class="warp-breadcrum">
<el-breadcrumb separator="/">
<!-- <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item> -->
<el-breadcrumb-item>设备类型列表</el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :span="24" class="warp-main" v-loading="loading" element-loading-text="拼命加载中">
<el-button size="medium " @click="adddevice" type="primary" round> 新增设备类型 </el-button>
<!--列表-->
<el-table :data="alldevicetype" highlight-current-row @selection-change="selsChange" style=" 100%;">
<el-table-column type="index" width="40"></el-table-column>
<el-table-column prop="dtid" width="40" v-if="false"></el-table-column>
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="[设备描述]">
<span>{{ props.row.description }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column prop="dtname" label="设备类型" width="300" sortable></el-table-column>
<el-table-column label="车型 车型操作" width="300" prop="carModels">
<!-- 数据的遍历 scope.row就代表数据的每一个对象-->
<template scope="scope" >
<p v-for="(item, index) in scope.row.carModels" :key="index" :label="item" style="font-size:16px;">
<span style="150px;display:block;float:left;">{{item.cname}}</span>
<el-button @click.native="delCarModel(item)" size="mini" type="danger" plain round>删除车型</el-button>
</p>
</template>
</el-table-column>
<el-table-column label="设备操作" width="400">
<template slot-scope="scope">
<el-button @click.native="addCarModel(scope.row)" size="mini" type="primary" plain round>新增车型</el-button>
<el-button @click.native="delDeviceType(scope.row)" size="mini" type="danger" round>删除设备类型</el-button>
</template>
</el-table-column>
</el-table>
<!--新增设备类型界面-->
<el-dialog title="新增设备类型" :visible.sync="dtvisible" :close-on-click-modal="false">
<el-form :model="devicetype" label-width="80px" :rules="rules" ref="devicetypeForm">
<el-form-item label="设备名称" prop="name">
<el-input v-model="devicetype.name" auto-complete="off" placeholder="请输入设备名称"></el-input>
</el-form-item>
<el-form-item label="描述" prop="description">
<el-input v-model="devicetype.description" auto-complete="off" placeholder="请输入设备描述"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="dtvisible = false">取消</el-button>
<el-button type="submit" @click.native="addSubmit" :loading="addLoading">提交</el-button>
</div>
</el-dialog>
<!--新增车型界面-->
<el-dialog title="新增车型" :visible.sync="cmvisible" :close-on-click-modal="false">
<el-form :model="carModel" label-width="80px" :rules="carModelrules" ref="carModelForm">
<el-form-item label="车型名称" prop="name">
<el-input v-model="carModel.name" auto-complete="off" placeholder="请输入车型名称"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="cmvisible = false">取消</el-button>
<el-button type="submit" @click.native="addSubmit1" :loading="addLoading">提交</el-button>
</div>
</el-dialog>
</el-col>
</el-row>
</template>
<script>
let id = 1000;
import util from '../../common/util'
import API from '../../api/api_device'
import { mapState, mapActions } from 'vuex'
export default {
data() {
return{
loading: false,
// devicetypes: [],
//新增设备类型
devicetype: {
name: '',
description: '',
},
dtvisible:false,
rules: {
name: [
{required: true, message: '输入设备名称', trigger: 'blur'}
],
description:[
{required: true, message: '输入设备描述', trigger: 'blur'}
],
},
sels: [], //列表勾选的列
addLoading: false, //转圈圈
//新增车型
cmvisible:false,
carModel:{
name:"",
devicetypeId:"",
},
carModelrules: {
name: [
{required: true, message: '输入车型名称', trigger: 'blur'}
],
},
}
},
methods: {
adddevice: function () {
this.dtvisible = true;
this.devicetype = {
name: '',
description: '',
};
},
//新增
addSubmit: function () {
let that = this;
this.$refs.devicetypeForm.validate((valid) => {
if (valid) {
let para = Object.assign({}, that.devicetype);//复制对象,有filelist数组对象
// console.log("para:",para);
API.add(para).then(function (result) {
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: result.mess, duration: 3000});
that.$refs['devicetypeForm'].resetFields();
that.dtvisible = false;
that.search();
} else {
that.$message.error({showClose: true, message: result.mess, duration: 3000});
that.$refs['devicetypeForm'].resetFields();
that.dtvisible = false;
that.search();
}
}).catch(function (error) {
that.loading = false;
that.search();
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}
});
},
search(){
this.loading = true;
let that = this;
API.findList().then(function (result) {
// console.log("result",result)
that.loading = false;
if (result && result.devicetypes) {
// that.devicetypes = result.devicetypes;
console.log("result.devicetypes:::",result.devicetypes);
that.dispatch_devicetypes(result.devicetypes);
// that.$store.commit('dispatch_devicetypes');
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
// that.search();
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
},
...mapActions([
'dispatch_devicetypes'
]),
addCarModel(row){
// console.log("addCarModelrow:",row);
this.cmvisible = true;
this.carModel = {
name: '',
devicetypeId: row.dtid,
};
},
selsChange: function (sels) {
this.sels = sels;
},
delCarModel(row){
// console.log("delCarModelrow:",row);
let that = this;
API.delCM(row.cmid).then(function (result) {
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: result.mess, duration: 3000});
that.search();
} else {
that.$message.error({showClose: true, message: result.mess, duration: 3000});
that.search();
}
}).catch(function (error) {
that.loading = false;
that.search();
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});;
},
addSubmit1: function () {
let that = this;
this.$refs.carModelForm.validate((valid) => {
if (valid) {
let para = Object.assign({}, that.carModel);//carModel是addCarModel方法里面的,也是表单里面的,跟表单绑定的。
// console.log("para:",para);
API.addCM(para).then(function (result) {
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: result.mess, duration: 3000});
that.$refs['carModelForm'].resetFields();
that.cmvisible = false;
that.search();
} else {
that.$message.error({showClose: true, message: result.mess, duration: 3000});
that.$refs['carModelForm'].resetFields();
that.cmvisible = false;
that.search();
}
}).catch(function (error) {
that.loading = false;
that.search();
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});;
}
});
},
delDeviceType: function(row){
// console.log("delDeviceType:",row);
let that = this;
API.delDT(row.dtid).then(function (result) {
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: result.mess, duration: 3000});
that.search();
} else {
that.$message.error({showClose: true, message: result.mess, duration: 3000});
that.search();
}
}).catch(function (error) {
that.loading = false;
that.search();
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
},
},
computed: {
alldevicetype:{
get:function(){
return this.$store.getters.getDevicetypes;
},
set:function(){
}
},
},
mounted() {
this.search();
}
};
</script>
<style>
.demo-table-expand label {
font-weight: bold;
}
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
avnlist.vue
<template>
<el-row class="warp">
<el-col :span="24" class="warp-breadcrum">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item>
<el-breadcrumb-item>升级包管理</el-breadcrumb-item>
<el-breadcrumb-item>tbox升级包列表</el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :span="24" class="warp-main" v-loading="loading" element-loading-text="拼命加载中">
<!--工具条-->
<el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
<el-form :inline="true" :model="filters">
<el-form-item>
<el-input v-model="filters.name" placeholder="tbox文件名" @keyup.enter.native="handleSearch"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" v-on:click="handleSearch">查询</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="showAddDialog">新增</el-button>
</el-form-item>
</el-form>
</el-col>
<!--列表-->
<el-table :data="books" highlight-current-row @selection-change="selsChange"
style=" 100%;">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column type="index" width="60"></el-table-column>
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="[升级包简介]">
<span>{{ props.row.description }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column prop="name" label="文件名" sortable></el-table-column>
<el-table-column prop="author" label="上传者" width="100" sortable></el-table-column>
<el-table-column prop="publishAt" label="上传日期" width="150" sortable></el-table-column>
<el-table-column label="操作" width="150">
<template slot-scope="scope">
<el-button size="small" @click="showEditDialog(scope.$index,scope.row)">编辑</el-button>
<el-button type="danger" @click="delbook(scope.$index,scope.row)" size="small">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--工具条-->
<el-col :span="24" class="toolbar">
<el-button type="danger" @click="batchDeletebook" :disabled="this.sels.length===0">批量删除</el-button>
<el-pagination layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="10" :total="total"
style="float:right;">
</el-pagination>
</el-col>
<el-dialog title="编辑" :visible.sync ="editFormVisible" :close-on-click-modal="false">
<el-form :model="editForm" label-width="100px" :rules="editFormRules" ref="editForm">
<el-form-item label="书名" prop="name">
<el-input v-model="editForm.name" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="作者" prop="author">
<el-input v-model="editForm.author" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="出版日期">
<el-date-picker type="date" placeholder="选择日期" v-model="editForm.publishAt"></el-date-picker>
</el-form-item>
<el-form-item label="简介" prop="description">
<el-input type="textarea" v-model="editForm.description" :rows="8"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="editFormVisible = false">取消</el-button>
<el-button type="primary" @click.native="editSubmit">提交</el-button>
</div>
</el-dialog>
<!--新增界面-->
<el-dialog title="新增" :visible.sync ="addFormVisible" :close-on-click-modal="false">
<el-form :model="addForm" label-width="80px" :rules="addFormRules" ref="addForm">
<el-form-item label="书名" prop="name">
<el-input v-model="addForm.name" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="作者" prop="author">
<el-input v-model="addForm.author" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="出版日期">
<el-date-picker type="date" placeholder="选择日期" v-model="addForm.publishAt"></el-date-picker>
</el-form-item>
<el-form-item label="简介" prop="description">
<el-input type="textarea" v-model="addForm.description" :rows="8"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="addFormVisible = false">取消</el-button>
<el-button type="primary" @click.native="addSubmit" :loading="addLoading">提交</el-button>
</div>
</el-dialog>
</el-col>
</el-row>
</template>
<script>
import util from '../../common/util'
import API from '../../api/api_file';
export default{
data(){
return {
filters: {
name: ''
},
books: [],
total: 0,
page: 1,
limit: 10,
loading: false,
sels: [], //列表选中列
//编辑相关数据
editFormVisible: false,//编辑界面是否显示
editFormRules: {
name: [
{required: true, message: '请输入书名', trigger: 'blur'}
],
author: [
{required: true, message: '请输入作者', trigger: 'blur'}
],
description: [
{required: true, message: '请输入简介', trigger: 'blur'}
]
},
editForm: {
id: 0,
name: '',
author: '',
publishAt: '',
description: ''
},
//新增相关数据
addFormVisible: false,//新增界面是否显示
addLoading: false,
addFormRules: {
name: [
{required: true, message: '请输入书名', trigger: 'blur'}
],
author: [
{required: true, message: '请输入作者', trigger: 'blur'}
],
description: [
{required: true, message: '请输入简介', trigger: 'blur'}
]
},
addForm: {
name: '',
author: '',
publishAt: '',
description: ''
}
}
},
methods: {
handleCurrentChange(val) {
this.page = val;
this.search();
},
handleSearch(){
this.total = 0;
this.page = 1;
this.search();
},
search(){
let that = this;
let params = {
page: that.page,
limit: 10,
name: that.filters.name
};
that.loading = true;
API.findList(params).then(function (result) {
that.loading = false;
if (result && result.books) {
that.total = result.total;
that.books = result.books;
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
},
selsChange: function (sels) {
this.sels = sels;
},
//删除
delbook: function (index, row) {
let that = this;
this.$confirm('确认删除该记录吗?', '提示', {type: 'warning'}).then(() => {
that.loading = true;
API.remove(row.id).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: '删除成功', duration: 1500});
that.search();
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}).catch(() => {
});
},
//显示编辑界面
showEditDialog: function (index, row) {
this.editFormVisible = true;
this.editForm = Object.assign({}, row);
},
//编辑
editSubmit: function () {
let that = this;
this.$refs.editForm.validate((valid) => {
if (valid) {
this.loading = true;
let para = Object.assign({}, this.editForm);
para.publishAt = (!para.publishAt || para.publishAt == '') ? '' : util.formatDate.format(new Date(para.publishAt), 'yyyy-MM-dd');
API.update(para.id, para).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: '修改成功', duration: 2000});
that.$refs['editForm'].resetFields();
that.editFormVisible = false;
that.search();
} else {
that.$message.error({showClose: true, message: '修改失败', duration: 2000});
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}
});
},
showAddDialog: function () {
this.addFormVisible = true;
this.addForm = {
name: '',
author: '',
publishAt: '',
description: ''
};
},
//新增
addSubmit: function () {
let that = this;
this.$refs.addForm.validate((valid) => {
if (valid) {
that.loading = true;
let para = Object.assign({}, this.addForm);
para.publishAt = (!para.publishAt || para.publishAt === '') ? '' : util.formatDate.format(new Date(para.publishAt), 'yyyy-MM-dd');
API.add(para).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: '新增成功', duration: 2000});
that.$refs['addForm'].resetFields();
that.addFormVisible = false;
that.search();
} else {
that.$message.error({showClose: true, message: '修改失败', duration: 2000});
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}
});
},
//批量删除
batchDeletebook: function () {
let ids = this.sels.map(item => item.id).toString();
let that = this;
this.$confirm('确认删除选中记录吗?', '提示', {
type: 'warning'
}).then(() => {
that.loading = true;
API.removeBatch(ids).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: '删除成功', duration: 1500});
that.search();
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}).catch(() => {
});
}
},
mounted() {
this.handleSearch()
}
}
</script>
<style>
.demo-table-expand label {
font-weight: bold;
}
</style>
ipclist.vue
<template>
<el-row class="warp">
<el-col :span="24" class="warp-breadcrum">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item>
<el-breadcrumb-item>升级包管理</el-breadcrumb-item>
<el-breadcrumb-item>tbox升级包列表</el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :span="24" class="warp-main" v-loading="loading" element-loading-text="拼命加载中">
<!--工具条-->
<el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
<el-form :inline="true" :model="filters">
<el-form-item>
<el-input v-model="filters.name" placeholder="tbox文件名" @keyup.enter.native="handleSearch"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" v-on:click="handleSearch">查询</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="showAddDialog">新增</el-button>
</el-form-item>
</el-form>
</el-col>
<!--列表-->
<el-table :data="books" highlight-current-row @selection-change="selsChange"
style=" 100%;">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column type="index" width="60"></el-table-column>
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="[升级包简介]">
<span>{{ props.row.description }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column prop="name" label="文件名" sortable></el-table-column>
<el-table-column prop="author" label="上传者" width="100" sortable></el-table-column>
<el-table-column prop="publishAt" label="上传日期" width="150" sortable></el-table-column>
<el-table-column label="操作" width="150">
<template slot-scope="scope">
<el-button size="small" @click="showEditDialog(scope.$index,scope.row)">编辑</el-button>
<el-button type="danger" @click="delbook(scope.$index,scope.row)" size="small">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--工具条-->
<el-col :span="24" class="toolbar">
<el-button type="danger" @click="batchDeletebook" :disabled="this.sels.length===0">批量删除</el-button>
<el-pagination layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="10" :total="total"
style="float:right;">
</el-pagination>
</el-col>
<el-dialog title="编辑" :visible.sync ="editFormVisible" :close-on-click-modal="false">
<el-form :model="editForm" label-width="100px" :rules="editFormRules" ref="editForm">
<el-form-item label="书名" prop="name">
<el-input v-model="editForm.name" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="作者" prop="author">
<el-input v-model="editForm.author" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="出版日期">
<el-date-picker type="date" placeholder="选择日期" v-model="editForm.publishAt"></el-date-picker>
</el-form-item>
<el-form-item label="简介" prop="description">
<el-input type="textarea" v-model="editForm.description" :rows="8"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="editFormVisible = false">取消</el-button>
<el-button type="primary" @click.native="editSubmit">提交</el-button>
</div>
</el-dialog>
<!--新增界面-->
<el-dialog title="新增" :visible.sync ="addFormVisible" :close-on-click-modal="false">
<el-form :model="addForm" label-width="80px" :rules="addFormRules" ref="addForm">
<el-form-item label="书名" prop="name">
<el-input v-model="addForm.name" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="作者" prop="author">
<el-input v-model="addForm.author" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="出版日期">
<el-date-picker type="date" placeholder="选择日期" v-model="addForm.publishAt"></el-date-picker>
</el-form-item>
<el-form-item label="简介" prop="description">
<el-input type="textarea" v-model="addForm.description" :rows="8"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="addFormVisible = false">取消</el-button>
<el-button type="primary" @click.native="addSubmit" :loading="addLoading">提交</el-button>
</div>
</el-dialog>
</el-col>
</el-row>
</template>
<script>
import util from '../../common/util'
import API from '../../api/api_file';
export default{
data(){
return {
filters: {
name: ''
},
books: [],
total: 0,
page: 1,
limit: 10,
loading: false,
sels: [], //列表选中列
//编辑相关数据
editFormVisible: false,//编辑界面是否显示
editFormRules: {
name: [
{required: true, message: '请输入书名', trigger: 'blur'}
],
author: [
{required: true, message: '请输入作者', trigger: 'blur'}
],
description: [
{required: true, message: '请输入简介', trigger: 'blur'}
]
},
editForm: {
id: 0,
name: '',
author: '',
publishAt: '',
description: ''
},
//新增相关数据
addFormVisible: false,//新增界面是否显示
addLoading: false,
addFormRules: {
name: [
{required: true, message: '请输入书名', trigger: 'blur'}
],
author: [
{required: true, message: '请输入作者', trigger: 'blur'}
],
description: [
{required: true, message: '请输入简介', trigger: 'blur'}
]
},
addForm: {
name: '',
author: '',
publishAt: '',
description: ''
}
}
},
methods: {
handleCurrentChange(val) {
this.page = val;
this.search();
},
handleSearch(){
this.total = 0;
this.page = 1;
this.search();
},
search(){
let that = this;
let params = {
page: that.page,
limit: 10,
name: that.filters.name
};
that.loading = true;
API.findList(params).then(function (result) {
that.loading = false;
if (result && result.books) {
that.total = result.total;
that.books = result.books;
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
},
selsChange: function (sels) {
this.sels = sels;
},
//删除
delbook: function (index, row) {
let that = this;
this.$confirm('确认删除该记录吗?', '提示', {type: 'warning'}).then(() => {
that.loading = true;
API.remove(row.id).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: '删除成功', duration: 1500});
that.search();
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}).catch(() => {
});
},
//显示编辑界面
showEditDialog: function (index, row) {
this.editFormVisible = true;
this.editForm = Object.assign({}, row);
},
//编辑
editSubmit: function () {
let that = this;
this.$refs.editForm.validate((valid) => {
if (valid) {
this.loading = true;
let para = Object.assign({}, this.editForm);
para.publishAt = (!para.publishAt || para.publishAt == '') ? '' : util.formatDate.format(new Date(para.publishAt), 'yyyy-MM-dd');
API.update(para.id, para).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: '修改成功', duration: 2000});
that.$refs['editForm'].resetFields();
that.editFormVisible = false;
that.search();
} else {
that.$message.error({showClose: true, message: '修改失败', duration: 2000});
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}
});
},
showAddDialog: function () {
this.addFormVisible = true;
this.addForm = {
name: '',
author: '',
publishAt: '',
description: ''
};
},
//新增
addSubmit: function () {
let that = this;
this.$refs.addForm.validate((valid) => {
if (valid) {
that.loading = true;
let para = Object.assign({}, this.addForm);
para.publishAt = (!para.publishAt || para.publishAt === '') ? '' : util.formatDate.format(new Date(para.publishAt), 'yyyy-MM-dd');
API.add(para).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: '新增成功', duration: 2000});
that.$refs['addForm'].resetFields();
that.addFormVisible = false;
that.search();
} else {
that.$message.error({showClose: true, message: '修改失败', duration: 2000});
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}
});
},
//批量删除
batchDeletebook: function () {
let ids = this.sels.map(item => item.id).toString();
let that = this;
this.$confirm('确认删除选中记录吗?', '提示', {
type: 'warning'
}).then(() => {
that.loading = true;
API.removeBatch(ids).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: '删除成功', duration: 1500});
that.search();
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}).catch(() => {
});
}
},
mounted() {
this.handleSearch()
}
}
</script>
<style>
.demo-table-expand label {
font-weight: bold;
}
</style>
packagelist.vue
<template>
<el-row class="warp">
<el-col :span="24" class="warp-breadcrum">
<el-breadcrumb separator="/">
<!-- <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item> -->
<el-breadcrumb-item>升级包管理</el-breadcrumb-item>
<a href="http://localhost:8086/package/download">下载</a>
<!-- <el-breadcrumb-item>tbox升级包列表</el-breadcrumb-item> -->
</el-breadcrumb>
</el-col>
<el-col :span="24" class="warp-main" v-loading="loading" element-loading-text="拼命加载中">
<!--工具条-->
<el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
<el-form :inline="true" :model="filters">
<!-- <el-form-item>
<el-input v-model="filters.name" placeholder="tbox文件名" @keyup.enter.native="handleSearch"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" v-on:click="handleSearch">查询</el-button>
</el-form-item> -->
<!-- <el-form-item>
<template>
<el-select v-model="selectvalue" placeholder="所有设备类型" v-on:change="selectchange()">
<el-option
v-for="item in devicetypes" :key="item.dtid" :label="item.dtname" :value="item.dtid">
</el-option>
</el-select>
</template>
</el-form-item> -->
<el-form-item>
<el-button type="primary" @click="showAddDialog">上传升级包</el-button>
</el-form-item>
</el-form>
</el-col>
<!--列表-->
<el-table :data="packages" highlight-current-row @selection-change="selsChange" style=" 100%;">
<!-- <el-table-column type="selection" width="55"></el-table-column> -->
<el-table-column type="index" width="40"></el-table-column>
<el-table-column prop="pid" width="40" v-if="false"></el-table-column>
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="[升级包changelog]">
<span>{{ props.row.description }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<!-- <el-table-column type="expand">
<template slot-scope="props1">
<el-form label-position="right" inline class="demo-table-expand">
<el-form-item label="[文件]">
<span>{{ props1.row.files }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column> -->
<el-table-column prop="deviceType" label="设备类型" width="100" sortable></el-table-column>
<el-table-column prop="carModel" label="车型" width="80" sortable></el-table-column>
<el-table-column prop="packageVersion" label="版本号" width="140" sortable></el-table-column>
<el-table-column prop="state" label="状态" width="110" sortable><!-- :formatter="fmtstate" -->
<template scope="scope">
<span v-if="scope.row.state=== 1" style="color: red">正在使用</span>
<span v-else >停用</span>
</template>
</el-table-column>
<el-table-column prop="updateTime" label="上传时间" width="200" sortable></el-table-column>
<el-table-column label="文件" width="480" prop="files">
<!-- 数据的遍历 scope.row就代表数据的每一个对象-->
<template scope="scope" >
<span v-for="(item, index) in scope.row.files" :key="index" :label="item">{{item.orignName}} (md5:{{item.md5}})<br></span>
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<template slot-scope="scope">
<el-button v-if="scope.row.state=== 0" @click.native="editDialog(scope.row,1)" type="primary" size="small">启用</el-button>
<el-button v-if="scope.row.state=== 1" @click.native="editDialog(scope.row,0)" type="warning" size="small">停用</el-button>
<!-- <el-button type="warning" size="small" @click="showEditDialog(scope.$index,scope.row)">修改</el-button> -->
<el-button type="danger" @click.native="editDialog(scope.row,2)" size="small">删除</el-button>
<!-- <el-button type="danger" @click="delbook(scope.$index,scope.row)" size="small">删除</el-button> -->
</template>
</el-table-column>
</el-table>
<!--工具条-->
<!-- <el-col :span="24" class="toolbar toolbartop">
<el-button type="danger" @click="batchDeletebook" :disabled="this.sels.length===0">批量删除</el-button>
<el-pagination layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="10" :total="total"
style="float:right;">
</el-pagination>
</el-col> -->
<!-- <el-dialog title="编辑" :visible.sync="editFormVisible" :close-on-click-modal="false">
<el-form :model="editForm" label-width="100px" :rules="editFormRules" ref="editForm">
<el-form-item label="文件名" prop="name">
<el-input v-model="editForm.name" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="上传者" prop="author">
<el-input v-model="editForm.author" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="上传日期">
<el-date-picker type="date" placeholder="选择日期" v-model="editForm.publishAt"></el-date-picker>
</el-form-item>
<el-form-item label="升级包说明" prop="description">
<el-input type="textarea" v-model="editForm.description" :rows="8"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="editFormVisible = false">取消</el-button>
<el-button type="primary" @click.native="editSubmit">提交</el-button>
</div>
</el-dialog> -->
<!--新增界面-->
<el-dialog title="新增" :visible.sync="addFormVisible" :close-on-click-modal="false">
<el-form :model="addForm" label-width="120px" :rules="addFormRules" ref="addForm" method="POST" id="uploadForm-tbox"><!-- id="uploadForm-tbox" enctype="multipart/form-data" -->
<!-- <el-form-item label="类型" prop="fileType" v-show="false">
<el-input v-model="addForm.fileType" auto-complete="off" value="tbox" ></el-input>
</el-form-item> -->
<el-form-item label="版本号" prop="fileVersion">
<el-input v-model="addForm.fileVersion" auto-complete="off" placeholder="请输入版本号"></el-input>
</el-form-item>
<el-form-item label="设备类型/车型" prop="selectedOptions" width="200px">
<!-- <el-input v-model="addForm.fileName" auto-complete="off"></el-input> -->
<el-cascader
expand-trigger="hover" :options="newDeviceType" v-model="addForm.selectedOptions" @change="handleChange">
</el-cascader>
</el-form-item>
<!--<el-form-item label="出版日期">
<el-date-picker type="date" placeholder="选择日期" v-model="addForm.publishAt"></el-date-picker>
</el-form-item>-->
<el-form-item label="是否启用" prop="state">
<el-radio v-model="addForm.state" label="1">是</el-radio>
<el-radio v-model="addForm.state" label="0">否</el-radio>
</el-form-item>
<el-form-item label="简介" prop="description">
<el-input type="textarea" v-model="addForm.description" :rows="8" placeholder="请输入版本修改日志"></el-input>
</el-form-item>
<el-form-item label="选择文件" >
<!-- <input type="file" @change="getFile($event)" multiple/> -->
<el-upload
class="upload"
action=""
ref="fileupload"
:on-preview="handlePreview"
:before-upload="beforeAvatarUpload"
:on-remove="handleRemove"
:auto-upload = 'false'
:on-success = 'handleSuccess'
:on-change="fileChange"
name="tboxfile"
prop="file" multiple>
<el-button size="small" type="primary">点击上传</el-button>
<!-- <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> -->
</el-upload>
<!-- <p :class="" v-if="names.length != 0">已选文件:</p> -->
<!-- <span v-for="val in names">
{{val}}
</span>
<el-button type="button" @click.native="removeFile" v-if="files.length != 0">移除</el-button> -->
</el-form-item>
<!-- <el-form-item label="files" prop="files">
<el-input v-model="addForm.fileList" auto-complete="off"></el-input>
</el-form-item> -->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="addFormVisible = false">取消</el-button>
<el-button type="submit" @click.native="addSubmit" :loading="addLoading">提交</el-button>
</div>
</el-dialog>
<!-- 提示对话框 -->
<el-dialog
title="提示"
:visible.sync="notedialogVisible"
width="30%"
:before-close="handleClose">
<span>{{notemessage}}</span>
<span slot="footer" class="dialog-footer">
<el-button @click.native="cancelldialog">取 消</el-button>
<el-button type="primary" @click.native="notedialog">确 定</el-button>
</span>
</el-dialog>
</el-col>
</el-row>
</template>
<script>
import util from '../../common/util'
import API from '../../api/api_file';
import APIdevice from '../../api/api_device';
import axios from 'axios'
import { mapState, mapActions } from 'vuex'
export default{
data(){
return {
filters: {
name: ''
},
/*file:"",
files: {},
names:{},
fileList:[],*/
// packages: [],
total: 0,
page: 1,
limit: 10,
loading: false,
sels: [], //列表选中列
radio: '',
//编辑相关数据
/*editFormVisible: false,//编辑界面是否显示
editFormRules: {
name: [
{required: true, message: '请输入文件名', trigger: 'blur'}
],
version: [
{required: true, message: '请输入版本号', trigger: 'blur'}
],
description: [
{required: true, message: '请输入简介', trigger: 'blur'}
]
},
editForm: {
id: 0,
name: '',
version: '',
publishAt: '',
description: ''
},*/
//编辑相关数据
//新增相关数据
addFormVisible: false,//新增界面是否显示
addLoading: false,
addFormRules: {
fileName: [
{required: true, message: '输入文件名', trigger: 'blur'}
],
fileVersion: [
{required: true, message: '输入版本号', trigger: 'blur'}
],
description: [
{required: true, message: '请输入升级包描述', trigger: 'blur'}
],
state: [
{required: true, message: '请输入状态', trigger: 'blur'}
],
file: [
{required: true, message: '请选择升级包', trigger: 'blur'}
],
selectedOptions:[
{required: true, message: '请选择设备类型/车型', trigger: 'blur'}
]
},
addForm: {
fileName: '',
fileVersion: '',
publishAt: '',
description: '',
fileList: [],
selectedOptions:[]
},
//新增相关数据
//启用相关数据
notedialogVisible:false,
notemessage:"",
arow:{},
filed:"",
//启用相关数据
//设备相关
// devicetypes: [],
// newDeviceType:[],
//设备相关
//下拉相关
allpackages:[],
selectvalue:"",
selectedOptions:[],
//下拉相关
}
},
methods: {
selectchange(command) {
// console.log(this.selectvalue);
},
handleChange(value){
console.log("value:",value);
console.log("this.selectedOptions:",this.selectedOptions);
},
/*fmtstate(row, column){
const arr = row[column.property];
if(arr == 1){
return "正在使用";
}else{
return "已停用";
}
},*/
handleCurrentChange(val) {
this.page = val;
this.search();
},
handleSearch(){
this.total = 0;
this.page = 1;
this.search();
},
...mapActions([
'dispatch_packages','dispatch_devicetypes'
]),
search(){
let that = this;
let params = {
page: that.page,
limit: 10,
name: that.filters.name
};
that.loading = true;
API.findTboxList(params).then(function (result) {
that.loading = false;
if (result && result.packages) {
that.dispatch_packages(result.packages);
// that.total = result.total;
// that.packages = result.packages;
// that.allpackages = result.packages;
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
APIdevice.findList().then(function (result) {
// console.log("devicetypesresult",result)
that.loading = false;
if (result && result.devicetypes) {
// console.log("result.devicetypes:",result.devicetypes);
// that.newDeviceType = result.devicetypes;
that.dispatch_devicetypes(result.devicetypes);
// console.log("newDeviceType:",newDeviceType);
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
that.search();
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
},
selsChange: function (sels) {
this.sels = sels;
},
//删除
delbook: function (index, row) {
let that = this;
this.$confirm('确认删除该记录吗?', '提示', {type: 'warning'}).then(() => {
that.loading = true;
API.remove(row.id).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: '删除成功', duration: 1500});
that.search();
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}).catch(() => {
});
},
//显示编辑界面
/*showEditDialog: function (index, row) {
this.editFormVisible = true;
this.editForm = Object.assign({}, row);
},*/
//启用相关数据
editDialog: function (row,index) {
console.log("index, row",index, row);
this.filed = index;
let type = "";
if(index == 1){
type="启用:";
}else if(index == 0){
type="停用:";
}else if(index == 2){
type="删除:";
}
this.notemessage = "确定"+type+row.deviceType+"--"+row.carModel+"--"+row.packageVersion+"的升级包吗?";
this.notedialogVisible = true;
this.arow = Object.assign({}, row);
},
handleClose(done) {
/*this.$confirm('确认关闭?')
.then(_ => {
done();
})
.catch(_ => {});*/
this.notedialogVisible = false;
this.arow={};
this.filed="";
},
cancelldialog(){
this.notedialogVisible = false;
this.arow={};
this.filed="";
},
notedialog(){
let params = {
"pid": this.arow.pid,
"deviceType": this.arow.deviceType,
"carModel": this.arow.carModel,
"state": this.filed
};
let that = this;
API.modify(params).then(function (result) {
that.loading = true;
if (result && parseInt(result.errcode) === 0) {
// alert(456);
that.$message.success({showClose: true, message: '修改成功', duration: 2000});
/*that.$refs['editForm'].resetFields();
that.editFormVisible = false;*/
that.search();
} else {
that.$message.error({showClose: true, message: result.mess, duration: 2000});
that.search();
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
that.search();
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
that.search();
});
this.notedialogVisible = false;
this.arow={};
this.filed="";
},
//启用相关数据
//编辑
/*editSubmit: function () {
let that = this;
this.$refs.editForm.validate((valid) => {
if (valid) {
this.loading = true;
let para = Object.assign({}, this.editForm);
para.publishAt = (!para.publishAt || para.publishAt == '') ? '' : util.formatDate.format(new Date(para.publishAt), 'yyyy-MM-dd');
API.update(para.id, para).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: '修改成功', duration: 2000});
that.$refs['editForm'].resetFields();
that.editFormVisible = false;
that.search();
} else {
that.$message.error({showClose: true, message: '修改失败', duration: 2000});
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}
});
},*/
showAddDialog: function () {
this.addFormVisible = true;
this.addForm = {
fileName: '',
fileVersion: '',
publishAt: '',
description: '',
fileList:[],
selectedOptions:[]
};
// alert("that.$refs['fileupload'].fileList:",this.$refs['addForm'].$refs['fileupload'].fileList);
// this.$refs['addForm'].$refs['fileupload'].fileList=[];
/*this.files = {};*/
},
//文件相关
beforeAvatarUpload(file, fileList) {
console.log("4444444444444");
/*console.log("beforeAvatarUpload")
console.log("beforeAvatarUploadfile:",file)
console.log("beforeAvatarUploadfileList:",fileList)
let Xls = file.name.split('.');
if(Xls[1] === 'xls'||Xls[1] === 'xlsx'){
return file
}else {
// this.$message.error('上传文件只能是 xls/xlsx 格式!')
return file
// return false
}*/
},
handleRemove(file, fileList) {
/*console.log("handleRemove:","file:",file,":fileList:",fileList);
for(var i=0;i<fileList.length;i++){
if(file.name == fileList[i].name){
fileList.splice(i--,1);
// break;
}
}*/
for(var i=0;i<this.addForm.fileList.length;i++){
if(file.name == this.addForm.fileList[i].name){
this.addForm.fileList.splice(i--,1);
// break;
}
}
console.log("handleRemove:","file:",file,":fileList:",fileList);
},
handlePreview(file) {
console.log("22222222222");
},
handleSuccess(res,file,fileList){
console.log("333333333333");
/*console.log("handleSuccess:",fileList)
if(res.code===20000){
this.$message({
message: '上传成功!',
type: 'success'
});
}else {
this.$message({
message: res.msg,
type: 'error'
});
}*/
},
fileChange(file, fileList){
//因为原生的选择文件标签获取的是FileList {0: File(8192), 1: File(18432), length: 2}一个object对象,
//后台需要的是File对象数组,原生的方法也要遍历这个object拼接成一个File数组
//el-upload的File对象的file.raw才是一个File对象,所以这里只截取el-upload里面的File对象,拼接成数组,后台@RequestParam("fileList[]") MultipartFile[] files接收
this.addForm.fileList.push(file.raw);//上传文件变化时将文件对象push进files数组
fileList = [];
/*this.fileList.push(file.raw);*/
},
/*getFile: function (event) {
this.files = event.target.files;
console.log('this.files:',this.files)
},
removeFile: function () {
},*/
//文件相关
//新增
addSubmit: function () {
let that = this;
this.$refs.addForm.validate((valid) => {
if (valid) {
that.loading = true;
// console.log("addForm",that.addForm)
let para = Object.assign({}, that.addForm);//复制对象,有filelist数组对象
// console.log("para",para)
para.publishAt = /*(!para.publishAt || para.publishAt === '') ? '' : */util.formatDate.format(new Date(), 'yyyy-MM-dd');
/*var form = document.getElementById("uploadForm-tbox");也可以直接提交表单
var formData = new FormData(form);*/
// console.log("para:",para);
let formData = new FormData();
for( var attr in para){ //排除文件列表属性
// console.log("attr1",attr)
if(attr != "fileList") {
// console.log("attr2",attr)
formData.append(attr, para[attr]);
}
}
for (var i = para.fileList.length - 1; i >= 0; i--) {
formData.append("fileList", para.fileList[i]); //文件列表只能这么添加,不能添加一个数组
}
let config = {
headers: {
'Content-Type': 'multipart/form-data'
}
};
API.addtboxForm(formData,config).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
alert(1);
console.log(result);
that.$message.success({showClose: true, message: result.mess, duration: 3000});
that.$refs['addForm'].resetFields();
that.addFormVisible = false;
that.$refs['fileupload'].fileList=[];
that.search();
// window.location.reload();
} else {
alert(2);
alert(result.errcode);
that.$message.error({showClose: true, message: result.mess, duration: 3000});
that.$refs['addForm'].resetFields();
that.addFormVisible = false;
that.$refs['fileupload'].fileList=[];
that.search();
// window.location.reload();
}
}, function (err) {
alert(3);
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 3000});
that.$refs['addForm'].resetFields();
that.$refs['fileupload'].fileList=[];
window.location.reload();
}).catch(function (error) {
alert(4);
that.loading = false;
// console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 3000});
that.$refs['addForm'].resetFields();
that.$refs['fileupload'].fileList=[];
window.location.reload();
});
/*let formData = new FormData();
for (var i = that.files.length - 1; i >= 0; i--) {
formData.append("fileList[]", that.files[i]);
}
*/
}
});
},
//批量删除
batchDeletebook: function () {
let ids = this.sels.map(item => item.id).toString();
let that = this;
this.$confirm('确认删除选中记录吗?', '提示', {
type: 'warning'
}).then(() => {
that.loading = true;
API.removeBatch(ids).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: '删除成功', duration: 1500});
that.search();
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
// console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}).catch(() => {
});
},
/*changeDeviceType: function(obj){
console.log("obj",obj);
for(let i in obj) {
let ob = {};
ob.label = obj[i].dtname;
ob.value = obj[i].dtname;
ob.children = [];
for(let j in obj[i].carModels){
let oc = {};
oc.label = obj[i].carModels[j].cname;
oc.value = obj[i].carModels[j].cname;
ob.children.push(oc);
}
this.newDeviceType.push(ob);
}
console.log("changeDeviceType2",this.newDeviceType);
},*/
/*searchDeviceType:function(){
let that = this;
APIdevice.findList().then(function (result) {
console.log("devicetypesresult",result)
that.loading = false;
if (result && result.devicetypes) {
console.log("result.devicetypes:",result.devicetypes);
// that.newDeviceType = result.devicetypes;
that.changeDeviceType(result.devicetypes);
console.log("newDeviceType:",newDeviceType);
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
that.search();
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
},*/
},
mounted() {
this.handleSearch();
/*console.log("this.newDeviceType.length1",this.$store.getters.getDevicetypes);
if(this.$store.getters.getDevicetypes.length == 0){
this.searchDeviceType();
console.log("this.newDeviceType.length2",this.newDeviceType.length);
}else{
this.newDeviceType = this.$store.getters.getDevicetypes;
}*/
},
computed: {
newDeviceType:{
get:function(){
return this.$store.getters.getNewDeviceType;
},
set:function(){
}
},
packages:{
get:function(){
return this.$store.getters.getPackages;
},
set:function(){
}
},
},
}
</script>
<style>
.demo-table-expand label {
font-weight: bold;
}
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
.el-table--scrollable-x .el-table__body-wrapper{
overflow-x:hidden !important;
}
</style>
changepwd.vue
<template>
<el-row class="warp">
<el-col :span="24" class="warp-breadcrum">
<el-breadcrumb separator="/">
<!-- <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item> -->
<el-breadcrumb-item>设置</el-breadcrumb-item>
<el-breadcrumb-item>修改密码</el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :span="24" class="warp-main">
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="原密码">
<el-input v-model="form.oldPwd"></el-input>
</el-form-item>
<el-form-item label="新密码">
<el-input v-model="form.newPwd"></el-input>
</el-form-item>
<el-form-item label="确认新密码">
<el-input v-model="form.confirmPwd"></el-input>
</el-form-item>
<el-form-item>
<el-button type="default" @click="handleChangepwd">提交</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</template>
<script>
export default{
data(){
return {
form: {
oldPwd: '',
newPwd: '',
confirmPwd: ''
}
}
},
methods: {
handleChangepwd() {
this.$message({message: "此功能只是让你看看,不会开发!", duration: 2000});
}
}
}
</script>
list.vue
<template>
<el-row class="warp">
<el-col :span="24" class="warp-breadcrum">
<el-breadcrumb separator="/">
<!-- <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item> -->
<el-breadcrumb-item>用户列表</el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :span="24" class="warp-main" v-loading="loading" element-loading-text="拼命加载中">
<!--工具条-->
<el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
<el-form :inline="true" :model="filters">
<!-- <el-form-item>
<el-input v-model="filters.name" placeholder="用户名/姓名/昵称" style="min- 240px;" @keyup.enter.native="handleSearch"></el-input>
</el-form-item> -->
<el-form-item>
<el-button type="primary" @click="addAccount">添加账号</el-button>
</el-form-item>
</el-form>
</el-col>
<!--列表-->
<el-table :data="accounts" highlight-current-row v-loading="loading" style=" 100%;">
<el-table-column type="index" width="60">
</el-table-column>
<el-table-column prop="username" label="账号名" width="120" sortable>
</el-table-column>
<!-- <el-table-column prop="nickname" label="角色" width="120" :formatter="formatSex" sortable>
</el-table-column> -->
<el-table-column prop="permissions" label="权限" width="300" sortable>
<!-- 数据的遍历 scope.row就代表数据的每一个对象-->
<template scope="scope" >
<p v-for="(item, index) in scope.row.permissions" :key="index" :label="item" style="font-size:16px;">
<span style="150px;display:block;float:left;">{{item.description}}</span>
<!-- <el-button @click.native="delCarModel(item)" size="mini" type="danger" plain round>删除车型</el-button> -->
</p>
</template>
</el-table-column>
<!-- <el-table-column prop="email" label="邮箱" min-width="160" sortable>
</el-table-column>
<el-table-column prop="addr" label="地址" sortable>
</el-table-column> -->
<el-table-column label="操作" width="220">
<template slot-scope="scope">
<el-button v-if="scope.row.state=== 1" @click.native="editDialog(scope.row)" type="warning" size="small">停用</el-button>
<el-button v-if="" @click.native="editPermission(scope.row)" type="primary" size="small">修改权限</el-button>
<!-- <el-button type="danger" @click.native="editDialog(scope.row,2)" size="small">删除</el-button> -->
<!-- <el-button type="danger" @click="delbook(scope.$index,scope.row)" size="small">删除</el-button> -->
</template>
</el-table-column>
</el-table>
<!--新增账号界面-->
<el-dialog title="新增账号" :visible.sync="accountvisible" :close-on-click-modal="false">
<el-form :model="account" label-width="80px" :rules="accountrules" ref="accountForm">
<el-form-item label="账号名" prop="username">
<el-input v-model="account.username" auto-complete="off" placeholder="请输入账号名"></el-input>
</el-form-item>
<el-form-item label="账号密码" prop="password">
<el-input v-model="account.password" type="password" auto-complete="off" placeholder="请输入6-10位字母、数字、下划线密码"></el-input>
</el-form-item>
<el-form-item label="重复密码" prop="password1">
<el-input v-model="account.password1" type="password" auto-complete="off" placeholder="请输入重复密码"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="accountvisible = false">取消</el-button>
<el-button type="submit" @click.native="addSubmit" :loading="addLoading">提交</el-button>
</div>
</el-dialog>
<!--修改权限界面-->
<el-dialog title="修改权限" :visible.sync="permissionvisible" :close-on-click-modal="false">
<el-form :model="account" label-width="80px" :rules="accountrules" ref="accountForm">
<template>
<el-transfer v-model="account_permission" :data="permissions"></el-transfer>
</template>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="permissionvisible = false">取消</el-button>
<el-button type="submit" @click.native="addSubmit" :loading="addLoading">提交</el-button>
</div>
</el-dialog>
</el-col>
</el-row>
</template>
<script>
import API from '../../api/api_account';
import md5 from 'js-md5';
import { mapState, mapActions } from 'vuex';
export default {
data() {
var validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'));
} else if (value !== this.account.password) {
callback(new Error('两次输入密码不一致!'));
} else {
callback();
}
};
return {
filters: {
name: ''
},
loading: false,
// accounts: [],
total: 0,
page: 1,
limit: 10,
loading: false,
accountvisible:false,
addLoading: false, //转圈圈
account: {
username: '',
password: '',
password1:''
},
accountrules: {
username: [
{required: true, message: '请输入账号名', trigger: 'blur'},
{pattern: /^(w){3,10}$/,message: '只能输入3-10个字母、数字、下划线'}
],
password:[
{required: true, message: '请输入账号密码', trigger: 'blur'},
{pattern: /^(w){6,10}$/,message: '只能输入6-10个字母、数字、下划线'}
],
password1:[
{validator: validatePass2, trigger: 'blur'}
],
},
permissionvisible:false,
// value1: [1, 4],
}
},
methods: {
editPermission(row){
console.log("row:", row);
this.permissionvisible = true;
},
addAccount(){
this.accountvisible = true;
this.account = {
username:'',
password:'',
password1: '',
};
},
//新增
addSubmit: function () {
let that = this;
this.$refs.accountForm.validate((valid) => {
if (valid) {
let para = Object.assign({}, that.account);//复制对象,有filelist数组对象
console.log("para:",para);
para.password = md5(para.password);
console.log("para:",para);
API.add(para).then(function (result) {
if (result && parseInt(result.errcode) === 0) {
that.$message.success({showClose: true, message: result.mess, duration: 3000});
that.$refs['accountForm'].resetFields();
that.accountvisible = false;
that.search();
} else {
that.$message.error({showClose: true, message: result.mess, duration: 3000});
that.$refs['accountForm'].resetFields();
that.accountvisible = false;
that.search();
}
}).catch(function (error) {
that.loading = false;
that.search();
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}
});
},
//性别显示转换
formatSex: function (row, column) {
return row.sex == 1 ? '男' : row.sex == 0 ? '女' : '未知';
},
handleCurrentChange(val) {
this.page = val;
this.search();
},
handleSearch(){
this.total = 0;
this.page = 1;
this.search();
},
//获取用户列表
search: function () {
let that = this;
let params = {
page: that.page,
limit: 10,
name: that.filters.name
};
that.loading = true;
API.findList(params).then(function (result) {
that.loading = false;
if (result && result.accounts) {
// that.total = result.total;
// that.accounts = result.accounts;
// console.log("result.accounts:",result.accounts);
that.dispatch_accounts(result.accounts);
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
API.findPermissionList().then(function (result) {
that.loading = false;
if (result && result.permissions) {
// that.total = result.total;
// that.accounts = result.accounts;
// console.log("result.permissions:",result.permissions);
that.dispatch_permission(result.permissions);
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
},
...mapActions([
'dispatch_accounts','dispatch_permission'
]),
},
computed: {
accounts:{
get:function(){
return this.$store.getters.getAccounts;
},
set:function(){
}
},
permissions:{
get:function(){
return this.$store.getters.getNewpermissions;
},
set:function(){
}
},
account_permission:{
get:function(){
return this.accounts.permissions;
},
set:function(){
}
},
},
mounted() {
this.handleSearch()
}
}
</script>
<style scoped>
</style>
profile.vue
<template>
<el-row class="warp">
<el-col :span="24" class="warp-breadcrum" :loading="loading">
<el-breadcrumb separator="/">
<!-- <el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item> -->
<el-breadcrumb-item>设置</el-breadcrumb-item>
<el-breadcrumb-item>个人信息</el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :span="24" class="warp-main">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="账号">
<el-input v-model="form.useranme" disabled></el-input>
</el-form-item>
<el-form-item prop="nickname" label="昵称">
<el-input v-model="form.nickname"></el-input>
</el-form-item>
<el-form-item prop="name" label="姓名">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item prop="email" label="邮箱">
<el-input v-model="form.email"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSaveProfile">修改并保存</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</template>
<script>
import API from '../../api/api_account';
import {bus} from '../../bus.js'
export default {
data() {
return {
loading: false,
form: {
useranme: '',
nickname: '',
name: '',
email: ''
},
rules: {
nickname: [
{required: true, message: '请输入昵称', trigger: 'blur'}
],
email: [
{required: true, message: '请输入邮箱', trigger: 'blur'},
{type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur,change'}
]
},
}
},
methods: {
handleSaveProfile() {
let that = this;
that.$refs.form.validate((valid) => {
if (valid) {
that.loading = true;
let args = {
nickname: that.form.nickname,
name: that.form.name,
email: that.form.email
};
API.changeProfile(args).then(function (result) {
that.loading = false;
if (result && parseInt(result.errcode) === 0) {
//修改成功
let user = JSON.parse(window.localStorage.getItem('access-user'));
user.nickname = that.form.nickname;
user.name = that.form.name;
user.email = that.form.email;
localStorage.setItem('access-user', JSON.stringify(user));
bus.$emit('setNickName', that.form.nickname);
that.$message.success({showClose: true, message: '修改成功', duration: 2000});
} else {
that.$message.error({showClose: true, message: result.errmsg, duration: 2000});
}
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}
});
}
},
mounted() {
let user = localStorage.getItem('access-user');
if (user) {
user = JSON.parse(user);
this.form.useranme = user.username;
this.form.nickname = user.nickname || '';
this.form.email = user.email || '';
this.form.name = user.name || '';
}
}
}
</script>
Home.vue
<template>
<el-row class="container">
<!--头部-->
<el-col :span="24" class="topbar-wrap">
<div class="topbar-logo topbar-btn">
<a href="/"><img src="../assets/logo.png" style="padding-left:8px;"></a>
</div>
<div class="topbar-logos" v-show="!collapsed">
<a href="/"><img src="../assets/logotxt.png" width="120px"></a>
</div>
<div class="topbar-title">
<span style="font-size: 18px;color: #fff;">远程升级平台后台管理系统</span>
</div>
<div class="topbar-account topbar-btn">
<el-dropdown trigger="click">
<span class="el-dropdown-link userinfo-inner"><i class="iconfont icon-user"></i> {{nickname}} <i
class="iconfont icon-down"></i></span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<div @click="jumpTo('/user/profile')"><span style="color: #555;font-size: 14px;">个人信息</span></div>
</el-dropdown-item>
<el-dropdown-item>
<div @click="jumpTo('/user/changepwd')"><span style="color: #555;font-size: 14px;">修改密码</span></div>
</el-dropdown-item>
<el-dropdown-item divided @click.native="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-col>
<!--中间-->
<el-col :span="24" class="main">
<!--左侧导航-->
<aside :class="{showSidebar:!collapsed}">
<!--展开大折叠开关-->
<div class="menu-toggle" @click.prevent="collapse">
<i class="iconfont icon-menufold" v-show="!collapsed"></i>
<i class="iconfont icon-menuunfold" v-show="collapsed"></i>
</div>
<!--导航菜单-->
<el-menu :default-active="defaultActiveIndex" router :collapse="collapsed" @select="handleSelect">
<template v-for="(item,index) in $router.options.routes" v-if="item.menuShow">
<el-submenu v-if="!item.leaf" :index="index+''">
<!--主菜单-->
<template slot="title"><i :class="item.iconCls"></i><span slot="title">{{item.name}}</span></template>
<!--子菜单-->
<el-menu-item v-for="term in item.children" :key="term.path" :index="term.path" v-if="term.menuShow"
:class="$route.path==term.path?'is-active':''">
<!--"$route.path==term.path?'is-active':''" 菜单栏高亮-->
<i :class="term.iconCls"></i><span slot="title">{{term.name}}</span>
</el-menu-item>
</el-submenu>
<el-menu-item v-else-if="item.leaf&&item.children&&item.children.length" :index="item.children[0].path"
:class="$route.path==item.children[0].path?'is-active':''">
<i :class="item.iconCls"></i><span slot="title">{{item.children[0].name}}</span>
</el-menu-item>
</template>
</el-menu>
</aside>
<!--右侧内容区-->
<section class="content-container">
<div class="grid-content bg-purple-light">
<el-col :span="24" class="content-wrapper">
<transition name="fade" mode="out-in">
<router-view></router-view>
</transition>
</el-col>
<!--<el-col :span="14" class="footbar-wrap">
<footer class="footer">
<hc-footer></hc-footer>
</footer>
</el-col>-->
</div>
</section>
</el-col>
<!-- <el-col :span="24" style="margin-down:0px;">
<HcFooter></HcFooter>
</el-col> -->
</el-row>
</template>
<script>
import {bus} from '../bus.js'
import API from '../api/api_account';
import HcFooter from '@/components/Footer'
export default {
name: 'home',
components: {HcFooter},
created(){//修改账号时触发事件
bus.$on('setNickName', (text) => {
this.nickname = text;
})
bus.$on('goto', (url) => {
if (url === "/login") {
localStorage.removeItem('access-user');
}
this.$router.push(url);
})
},
data () {
return {
defaultActiveIndex: "0",
nickname: '',
collapsed: false,
}
},
methods: {
handleSelect(index){
this.defaultActiveIndex = index;
},
//折叠导航栏
collapse: function () {
this.collapsed = !this.collapsed;
},
jumpTo(url){
this.defaultActiveIndex = url;
this.$router.push(url); //用go刷新
},
logout(){
let that = this;
this.$confirm('确认退出吗?', '提示', {
confirmButtonClass: 'el-button--warning'
}).then(() => {
//确认
that.loading = true;
API.logout().then(function (result) {
that.loading = false;
localStorage.removeItem('access-user');
that.$router.go('/login'); //用go刷新
}, function (err) {
that.loading = false;
that.$message.error({showClose: true, message: err.toString(), duration: 2000});
}).catch(function (error) {
that.loading = false;
console.log(error);
that.$message.error({showClose: true, message: '请求出现异常', duration: 2000});
});
}).catch(() => {});
}
},
mounted() {
let user = localStorage.getItem('access-user');
if (user) {
user = JSON.parse(user);
this.nickname = user.nickname || '';
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.container {
position: absolute;
top: 0px;
bottom: 0px;
100%;
.topbar-wrap {
height: 50px;
line-height: 50px;
background: #373d41;
padding: 0px;
.topbar-btn {
color: #fff;
}
/*.topbar-btn:hover {*/
/*background-color: #4A5064;*/
/*}*/
.topbar-logo {
float: left;
59px;
line-height: 26px;
}
.topbar-logos {
float: left;
120px;
line-height: 26px;
}
.topbar-logo img, .topbar-logos img {
height: 40px;
margin-top: 5px;
margin-left: 2px;
}
.topbar-title {
float: left;
text-align: left;
200px;
padding-left: 10px;
border-left: 1px solid #000;
}
.topbar-account {
float: right;
padding-right: 12px;
}
.userinfo-inner {
cursor: pointer;
color: #fff;
padding-left: 10px;
}
}
.main {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
position: absolute;
top: 50px;
bottom: 0px;
overflow: hidden;
}
aside {
min- 50px;
background: #333744;
&::-webkit-scrollbar {
display: none;
}
&.showSidebar {
overflow-x: hidden;
overflow-y: auto;
}
.el-menu {
height: 100%; /*写给不支持calc()的浏览器*/
height: -moz-calc(100% - 80px);
height: -webkit-calc(100% - 80px);
height: calc(100% - 80px);
border-radius: 0px;
background-color: #333744;
border-right: 0px;
}
.el-submenu .el-menu-item {
min- 60px;
}
.el-menu {
180px;
}
.el-menu--collapse {
60px;
}
.el-menu .el-menu-item, .el-submenu .el-submenu__title {
height: 46px;
line-height: 46px;
}
.el-menu-item:hover, .el-submenu .el-menu-item:hover, .el-submenu__title:hover {
background-color: #7ed2df;
}
}
.menu-toggle {
background: #4A5064;
text-align: center;
color: white;
height: 26px;
line-height: 30px;
}
.content-container {
background: #fff;
flex: 1;
overflow-y: auto;
padding: 10px;
padding-bottom: 1px;
.content-wrapper {
background-color: #fff;
box-sizing: border-box;
}
.footbar-wrap{
bottom: 0px;
padding-bottom: 0px;
}
}
}
</style>
Index.vue
<template>
<el-row class="warp">
<el-col :span="24" class="warp-breadcrum">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }"><b>首页</b></el-breadcrumb-item>
</el-breadcrumb>
</el-col>
<el-col :span="24" class="warp-main">
<section class="chart-container">
<el-row>
<el-col :span="8">
<el-card :body-style="{ padding: '0px' }">
<img src="../assets/images/forest.png" class="image">
<div style="padding: 14px;">
<span>行行出状元,处处有金杯</span>
<div class="bottom clearfix">
<time class="time">{{ currentDate }}</time>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card :body-style="{ padding: '0px' }">
<img src="../assets/images/sunrise.png" class="image">
<div style="padding: 14px;">
<span>华晨金杯750</span>
<div class="bottom clearfix">
<time class="time">{{ currentDate }}</time>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card :body-style="{ padding: '0px' }">
<img src="../assets/images/sunshine.png" class="image">
<div style="padding: 14px;">
<span>斯威汽车</span>
<div class="bottom clearfix">
<time class="time">{{ currentDate }}</time>
</div>
</div>
</el-card>
</el-col>
<el-col :span="12">
<div id="chartColumn" style="100%; height:400px;"></div>
</el-col>
<el-col :span="12">
<div id="chartBar" style="100%; height:400px;"></div>
</el-col>
<el-col :span="12">
<div id="chartLine" style="100%; height:400px;"></div>
</el-col>
<el-col :span="12">
<div id="chartPie" style="100%; height:400px;"></div>
</el-col>
<el-col :span="24">
<a href="http://echarts.baidu.com/examples.html" target="_blank" style="float: right;">more>></a>
</el-col>
</el-row>
</section>
</el-col>
</el-row>
</template>
<style>
.time {
font-size: 13px;
color: #999;
}
.bottom {
margin-top: 13px;
line-height: 12px;
}
.image {
100%;
display: block;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both
}
.chart-container {
100%;
}
.chart-container .el-col {
padding: 30px 20px;
}
</style>
<script>
import echarts from 'echarts'
export default {
data() {
return {
currentDate: new Date(),
chartColumn: null,
chartBar: null,
chartLine: null,
chartPie: null
};
},
mounted: function () {
var _this = this;
//基于准备好的dom,初始化echarts实例
this.chartColumn = echarts.init(document.getElementById('chartColumn'));
this.chartBar = echarts.init(document.getElementById('chartBar'));
this.chartLine = echarts.init(document.getElementById('chartLine'));
this.chartPie = echarts.init(document.getElementById('chartPie'));
this.chartColumn.setOption({
title: { text: '销量柱状图' },
tooltip: {},
xAxis: {
data: ["鑫源小海狮", "鑫源s402", "鑫源x7", "鑫源摩托", "鑫源头盔", "鑫源农机"]
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [50000, 20009, 36000, 10000, 10000, 20000]
}]
});
this.chartBar.setOption({
title: {
text: '条状图',
subtext: '数据来自网络'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['2011年', '2012年']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'value',
boundaryGap: [0, 0.01]
},
yAxis: {
type: 'category',
data: ['鑫源小海狮', '鑫源s402', '鑫源x7', '鑫源摩托', '鑫源头盔', '鑫源总数(万)']
},
series: [
{
name: '2011年',
type: 'bar',
data: [18203, 23489, 29034, 104970, 131744, 630230]
},
{
name: '2012年',
type: 'bar',
data: [19325, 23438, 31000, 121594, 134141, 681807]
}
]
});
this.chartLine.setOption({
title: {
text: '线状图'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['鑫源小海狮', '鑫源s402', '鑫源x7']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'value'
},
series: [
{
name: '鑫源小海狮',
type: 'line',
stack: '总量',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '鑫源s402',
type: 'line',
stack: '总量',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '鑫源x7',
type: 'line',
stack: '总量',
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
});
this.chartPie.setOption({
title: {
text: '饼状图',
subtext: '数据来自网络',
x: 'center'
},
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
legend: {
orient: 'vertical',
left: 'left',
data: ['鑫源小海狮', '鑫源s402', '鑫源x7', '鑫源摩托', '鑫源头盔']
},
series: [
{
name: '访问来源',
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
data: [
{ value: 335, name: '鑫源小海狮' },
{ value: 310, name: '鑫源s402' },
{ value: 234, name: '鑫源x7' },
{ value: 135, name: '鑫源摩托' },
{ value: 1548, name: '鑫源头盔' }
],
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
});
}
}
</script>
Login.vue
<template> <el-form ref="AccountFrom" :model="account" :rules="rules" label-position="left" label-width="0px" class="demo-ruleForm login-container"> <h3 class="title">管理员登录</h3> <el-form-item prop="username"> <el-input type="text" v-model="account.username" auto-complete="off" placeholder="账号"></el-input> </el-form-item> <el-form-item prop="pwd"> <el-input type="password" v-model="account.pwd" auto-complete="off" placeholder="密码"></el-input> </el-form-item> <!--<el-checkbox v-model="checked" checked class="remember">记住密码</el-checkbox>--> <el-form-item style="100%;"> <el-button type="primary" style="100%;" @click.native.prevent="handleLogin" :loading="loading">登录</el-button> </el-form-item> </el-form> </template> <script> import API from '../api/api_account'; export default { data() { return { loading: false, account: { username: 'admin', pwd: '123456' }, rules: { username: [ {required: true, message: '请输入账号', trigger: 'blur'}, //{ validator: validaePass } ], pwd: [ {required: true, message: '请输入密码', trigger: 'blur'}, //{ validator: validaePass2 } ] }, checked: true }; }, methods: { handleLogin() { let that = this; this.$refs.AccountFrom.validate((valid) => { if (valid) { this.loading = true; let loginParams = {username: this.account.username, pwd: this.account.pwd}; API.login(loginParams).then(function (result) { that.loading = false; if (result && result.id) { localStorage.setItem('access-user', JSON.stringify(result)); // that.$store.commit('SET_ROUTERS', user.permissions) // that.$router.addRoutes(that.$store.getters.addRouters); // that.$router.options.routes = that.$store.getters.routers; that.$router.push({path: '/'}); } else { that.$message.error({showClose: true, message: result.errmsg || '登录失败', duration: 2000}); } }, function (err) { that.loading = false; that.$message.error({showClose: true, message: err.toString(), duration: 2000}); }).catch(function (error) { that.loading = false; console.log(error); that.$message.error({showClose: true, message: '请求出现异常', duration: 2000}); }); } }); } } } </script> <style> body { background: #DFE9FB; } </style> <style lang="scss" scoped> .login-container { /*box-shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.06), 0 1px 0px 0 rgba(0, 0, 0, 0.02);*/ -webkit-border-radius: 5px; border-radius: 5px; -moz-border-radius: 5px; background-clip: padding-box; margin: 160px auto; width: 350px; padding: 35px 35px 15px 35px; background: #fff; border: 1px solid #eaeaea; box-shadow: 0 0 25px #cac6c6; background: -ms-linear-gradient(top, #ace, #00C1DE); /* IE 10 */ background: -moz-linear-gradient(top, #ace, #00C1DE); /*火狐*/ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ace), to(#00C1DE)); /*谷歌*/ background: -webkit-linear-gradient(top, #ace, #00C1DE); /*Safari5.1 Chrome 10+*/ background: -o-linear-gradient(top,#ace, #00C1DE); /*Opera 11.10+*/ .title { margin: 0px auto 40px auto; text-align: center; color: #505458; } .remember { margin: 0px 0px 35px 0px; } } </style>
index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import index from '@/components/Index'
import packageList from '@/components/filelist/packageList'
import avnList from '@/components/filelist/avnlist'
import ipcList from '@/components/filelist/ipclist'
import bookCategoryList from '@/components/bookcategory/list'
import UserList from '@/components/user/list'
import UserChangePwd from '@/components/user/changepwd'
import UserProbook from '@/components/user/profile'
import Device from '@/components/device/device'
import store from '@/store/'
// 懒加载方式,当路由被访问的时候才加载对应组件
//箭头函数是省略了function函数名和return,resolve是形参,require是函数体并且是return。
const Login = resolve => require(['@/components/Login'], resolve)
Vue.use(Router)
let router = new Router({
// mode: 'history',
routes: [ //根据这个遍历得到左边菜单
{
path: '/login',
name: '登录',
component: Login
},
/*{
path: '/',
name: 'home',
component: Home,
redirect: '/index', //加载右边
leaf: true, // 只有一个节点
menuShow: true,
iconCls: 'iconfont icon-home', // 图标样式class
children: [
{
path: '/index',
component: index,
name: '鑫源简介',
menuShow: true
}
]
},*/
/*{
path: '/',
component: Home,
name: '升级包管理',
menuShow: true,
iconCls: 'iconfont icon-books',
children: [
{
path: '/filelist/tboxlist',
component: tboxList,
name: 'tbox升级包列表',
menuShow: true //true则Home.vue会加载这个条目,否则不加载
},
{
path: '/filelist/avnlist',
component: avnList,
name: 'AVN升级包列表',
menuShow: true
},
{
path: '/filelist/ipclist',
component: ipcList,
name: 'IPC升级包列表',
menuShow: true
}
]
},*/
{
path: '/',
component: Home,
name: '升级包管理',
menuShow: true,
leaf: true, // 只有一个节点
redirect: '/filelist/packagelist', //加载右边
iconCls: 'iconfont icon-users', // 图标样式class
children: [
{
path: '/filelist/packagelist',
component: packageList,
name: '升级包管理',
menuShow: true
}
]
},
{
path: '/',
component: Home,
name: '设备类型管理',
menuShow: true,
leaf: true, // 只有一个节点
iconCls: 'iconfont icon-users', // 图标样式class
children: [
{
path: '/device/list',
component: Device,
name: '设备类型列表',
menuShow: true
}
]
},
{
path: '/',
component: Home,
name: '用户管理',
menuShow: true,
leaf: true, // 只有一个节点
iconCls: 'iconfont icon-users', // 图标样式class
children: [
{
path: '/user/list',
component: UserList,
name: '用户列表',
menuShow: true
}
]
},
{
path: '/',
component: Home,
name: '设置',
menuShow: true,
iconCls: 'iconfont icon-setting1',
children: [
{
path: '/user/probook',
component: UserProbook,
name: '个人信息',
menuShow: true
},
{
path: '/user/changepwd',
component: UserChangePwd,
name: '修改密码',
menuShow: true
}
]
},
]
})
router.beforeEach((to, from, next) => {//每次路由都会走
/*console.log('to:' + to.path)
console.log('from:' + from.path)
console.log('next:' + next.path)*/
/*if(to.path.startsWith('/filelist/packagelist')){
store:Store {_committing: false, _actions: {…}, _actionSubscribers:
Array(0), _mutations: {…}, _wrappedGetters: {…}, …}
if(store.getters.getDevicetypes.length = 0)
console.log("store.getters.getDevicetypes;",store.getters.getDevicetypes);
}*/
if (to.path.startsWith('/login')) {
window.localStorage.removeItem('access-user')
next()
} else {
let user = JSON.parse(window.localStorage.getItem('access-user'))
if (!user) {
next({path: '/login'})
} else {
next()
}
}
})
export default router
actions.js
// 页面调用action,action调用mutation来设置数据state
import * as types from './mutations_types';
export default {
dispatch_devicetypes:({
commit
}, obj) => {
commit(types.ALL_DEVICETYPES, obj);
},
dispatch_packages:({
commit
}, obj) => {
commit(types.ALL_PACKAGES, obj);
},
dispatch_accounts:({
commit
}, obj) => {
commit(types.ALL_ACCOUNTS, obj);
},
dispatch_permission:({
commit
}, obj) => {
commit(types.ALL_PERMISSION, obj);
},
/*update_cur_shop_status: ({
commit
}, obj) => {
commit(types.UPDATE_CUR_SHOP_STATUS, obj);
},
create_db: ({
commit
}, {
shop
}) => {
commit(types.CREATE_DB, shop);
commit(types.UPDATE_LOCAL);
},
add_db: ({
commit
}) => {
commit(types.ADD_DB);
commit(types.UPDATE_LOCAL);
},*/
};
getters.js
/*getter是state的get方法,没有get页面就获取不到数据 获取页面: import {mapGetters,mapActions} from 'vuex' <h1>{{count}}</h1> computed:mapGetters([ 'count' ]), store.js: var state = { count:6 }, var getters={ count(state){ return state.count } } 改变数据页面: <button @click="increment">增加</button> methods:mapActions([ //该 increment 来自 store.js 中导出的 actions 和 mutations 中的 increment 'increment', ]) 先发给action: const actions ={ // ({commit,state}) 这种写法是 es6 中的对象解构 increment({commit,state}){ //提交一个名为 increment 的变化,名字可自定义,可以认为是类型名,与下方 mutations 中的 increment 对应 //commit 提交变化,修改数据的唯一方式就是显式的提交 mutations commit('increment') } } 再发给mutations: const mutations ={ //与上方 commit 中的 ‘increment' 相对应 increment(state){ state.count ++; } } */ //页面调用数据的getter方法来获取数据states export default { getInfos(state) { state.cartInfos.total_price = 0; state.cartInfos.total_nums = 0; var list = state.cartList; for (var i = 0; i < list.length; i++) { var price = parseInt(list[i].price), num = parseInt(list[i].num); state.cartInfos.total_price += price * num; state.cartInfos.total_nums += num; } return state.cartInfos; }, getCartList(state) { return state.cartList; }, getDevicetypes(state) { return state.devicetypes; }, getNewDeviceType(state) { return state.newDeviceType; }, getPackages(state) { return state.packages; }, getAccounts:state=> state.accounts, getPermissions:state => state.permissions, getNewpermissions:state => state.newpermissions, /*getAccounts:state =>state.accounts, getPermissions:state => state.permissions,*/ };
index.js
import Vue from 'vue' import state from './state'; import mutations from './mutations'; import getters from './getters'; import actions from './actions'; import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state, mutations, getters, actions })
mutations.js
import * as types from './mutations_types' export default { [types.ALL_DEVICETYPES](state, obj) { state.devicetypes = obj; let newDeviceType = []; for(let i in obj) { let ob = {}; ob.label = obj[i].dtname; ob.value = obj[i].dtname; ob.children = []; for(let j in obj[i].carModels){ let oc = {}; oc.label = obj[i].carModels[j].cname; oc.value = obj[i].carModels[j].cname; ob.children.push(oc); } newDeviceType.push(ob); } state.newDeviceType = newDeviceType; }, [types.ALL_PACKAGES](state, obj) { state.packages = obj; }, [types.ALL_ACCOUNTS](state, obj) { console.log("ALL_ACCOUNTS : ",obj); state.accounts = obj; }, [types.ALL_PERMISSION](state, obj) { state.permissions = obj; console.log("state.permissions:",state.permissions); let newpermissions = []; for(let i in obj) { let ob = {}; ob.key = obj[i].pid; ob.label = obj[i].pdescription; newpermissions.push(ob); } state.newpermissions = newpermissions; console.log("state.newpermissions:",state.newpermissions); }, /*[types.CLEAR_LOCAL](state) { state.cartList.forEach(function(item) { item.num = 0; }); state.cartList = []; localStorage.removeItem('vuex_cart'); }, [types.UPDATE_LOCAL](state) { localStorage.setItem('vuex_cart', JSON.stringify(state.cartList)); }, [types.UPDATE_CUR_SHOP_STATUS](state, { index = -1 }) { state.curIndex = index; }, [types.DELETE_DB](state) { if (state.curIndex >= 0) { state.cartList[state.curIndex].num = 0; state.cartList.splice(state.curIndex, 1); } }, [types.CREATE_DB](state, shop) { // console.log('mu create'); state.cartList.push(shop); }, [types.ADD_DB](state) { // console.log('mu add id:' + state.curIndex); state.cartList[state.curIndex].num = parseInt(state.cartList[state.curIndex].num); state.cartList[state.curIndex].num++; }, [types.REDUCE_DB](state) { // console.log('mu reduce'); state.cartList[state.curIndex].num = parseInt(state.cartList[state.curIndex].num); state.cartList[state.curIndex].num--; // console.log(state.cartList[state.curIndex].num); if (state.cartList[state.curIndex].num == 0) { state.cartList.splice(state.curIndex, 1); } }, [types.CHECK_DB](state, { id }) { // console.log('mu check id :' + id); // console.log(state.cartList); state.curIndex = -1; var list = state.cartList; if (list.length) { for (var i = 0; i < list.length; i++) { if (list[i].id == id) { state.curIndex = i; break; } } } }*/ };
mutations_types.js
/*//添加菜品到购物车 export const CREATE_DB = 'CREATE_DB'; //给购物车的菜品++ export const ADD_DB = 'ADD_DB'; //给购物车的菜品-- export const REDUCE_DB = 'REDUCE_DB'; //删除购物车的索引 export const DELETE_DB = 'DELETE_DB'; //更新当前菜品在购物车的状态 export const UPDATE_CUR_SHOP_STATUS = 'UPDATE_CUR_SHOP_STATUS'; //检测购物车内是否存在某菜品 export const CHECK_DB = 'CHECK_DB'; //更新本地数据 export const UPDATE_LOCAL = 'UPDATE_LOCAL'; //清空本地数据 export const CLEAR_LOCAL = 'CLEAR_LOCAL';*/ export const ALL_DEVICETYPES = 'ALL_DEVICETYPES'; export const ALL_PACKAGES = 'ALL_PACKAGES'; export const ALL_ACCOUNTS = 'ALL_ACCOUNTS'; export const ALL_PERMISSION = 'ALL_PERMISSION';
state.js
export default { devicetypes:[], //设备类型 newDeviceType:[], packages: [],//升级包 accounts: [],//账号 permissions:[],//权限 newpermissions:[], /*//购物车列表 cartList: localStorage.getItem('vuex_cart') ? JSON.parse(localStorage.getItem('vuex_cart')) : [], //当前购物车信息 cartInfos: { total_price: 0, total_nums: 0 }, //当前菜品是否在购物车的状态。在则是对应的索引,不在则是-1 curIndex: -1*/ };
App.vue
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
<style>
body{
padding:0px;
margin:0px auto;
}
a{
text-decoration:none;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: left;
color: #2c3e50;
}
</style>
bus.js
/** * Created by jerry on 2017/4/14. */ import Vue from 'vue' export let bus = new Vue()
main.js
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import '@/assets/iconfont.css' import '@/assets/styles/main.scss' import curvejs from 'curvejs' //画线的 Object.defineProperty(Vue.prototype, '$curvejs', { value: curvejs }); Vue.config.productionTip = false Vue.use(ElementUI) /* eslint-disable no-new */ new Vue({ el: '#app', router, template: '<App/>', components: {App} })
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>远程升级服务</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
package.json
{ "name": "litadmin", "version": "1.2.1", "description": "A Vue.js project for admin", "author": "jerry9022@qq.com", "private": true, "scripts": { "server": "node server/bin/www", "dev": "node build/dev-server.js", "build": "node build/build.js" }, "dependencies": { "axios": "^0.16.2", "echarts": "^3.7.1", "element-ui": "^2.0.7", "js-md5": "^0.7.3", "lodash": "^4.17.4", "vue": "^2.5.9", "vue-router": "^2.8.1", "vue-template-compiler": "^2.5.9", "vuex": "^3.0.1" }, "devDependencies": { "autoprefixer": "^6.7.2", "babel-core": "^6.26.0", "babel-loader": "^6.2.10", "babel-plugin-transform-runtime": "^6.22.0", "babel-preset-env": "^1.6.0", "babel-preset-stage-2": "^6.24.1", "babel-register": "^6.26.0", "chalk": "^1.1.3", "connect-history-api-fallback": "^1.3.0", "copy-webpack-plugin": "^4.0.1", "css-loader": "^0.26.4", "eventsource-polyfill": "^0.9.6", "express": "^4.15.4", "extract-text-webpack-plugin": "^2.1.2", "file-loader": "^0.10.0", "friendly-errors-webpack-plugin": "^1.1.3", "function-bind": "^1.1.1", "html-webpack-plugin": "^2.30.1", "http-proxy-middleware": "^0.17.3", "node-sass": "^4.5.3", "opn": "^4.0.2", "optimize-css-assets-webpack-plugin": "^1.3.2", "ora": "^1.3.0", "rimraf": "^2.6.2", "sass-loader": "^6.0.6", "semver": "^5.4.1", "style-loader": "^0.16.1", "url-loader": "^0.5.9", "vue-loader": "^11.1.4", "vue-style-loader": "^2.0.0", "webpack": "^2.7.0", "webpack-bundle-analyzer": "^2.9.0", "webpack-dev-middleware": "^1.12.0", "webpack-hot-middleware": "^2.19.1", "webpack-merge": "^2.6.1" }, "engines": { "node": ">= 4.0.0", "npm": ">= 3.0.0" }, "browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ] }
main.js
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import '@/assets/iconfont.css' import '@/assets/styles/main.scss' import curvejs from 'curvejs' //画线的 import store from '@/store/' Object.defineProperty(Vue.prototype, '$curvejs', { value: curvejs }); Vue.config.productionTip = false Vue.use(ElementUI) /* eslint-disable no-new */ new Vue({ el: '#app', router, store, //会自动注册给子组件,在子组件中通过 this.$store 访问 template: '<App/>', components: {App} })