阶段保存

This commit is contained in:
szdot 2023-10-18 15:58:44 +08:00
parent a71741e0a8
commit 04a515106f
28 changed files with 1670 additions and 427 deletions

View File

@ -27,7 +27,7 @@ export default {
*/
routes () {
return this.$router.options.routes.filter(
item => item.hidden !== true && item.roles.indexOf(this.$store.state.user.power.trim()) >= 0
item => item.meta.hidden !== true && item.meta.roles.indexOf(this.$store.state.user.power.trim()) >= 0
)
},
/**

View File

@ -1,195 +1,247 @@
<template>
<div class="tab-container">
<el-button size="medium" type="primary" :class="activeIndex === index ? 'butIconGroupBG' : ''" class="butIconGroup"
v-for="(item, index) in controlItems" :key="index" @click="toggleContent(index)">
<i :class="item.icon" class="iconfont f-s-35"></i>
<div class="m-t-5 fb">{{ item.title }}</div>
</el-button>
<!-- 子内容菜单 -->
<div class="content" :class="{ 'active': activeIndex !== null }">
<!-- 订单任务 -->
<div v-if="activeIndex === 0" class="contentBox">
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-dingdanguanli f-s-22 m-r-5"></i>
<span>送餐任务</span>
<div>
<!-- 弹出框 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="30%">
<!-- 起飞设置弹出框 -->
<template v-if="dialogItem == 'takeoffBox'">
<div class="slider-container">
<span class="m-l-10 m-r-10">高度</span>
<el-slider class="w-70" v-model="takeoffValue" show-input>
</el-slider>
</div>
<!-- 内容 -->
<el-form label-position="left" ref="questForm" :model="questForm" label-width="80px">
<el-form-item label="订单任务">
<el-select v-model="questForm.id" :filterable="isMobile" placeholder="请选择,也可输入搜索" :disabled="airLock">
<el-option v-for="item in questList" :key="item.id" :label="item.id" :value="item.id">
<span class="l">{{ item.id }}</span>
<span class="l m-l-5">{{ item.name }}</span>
<span class="l m-l-5">{{ item.receive_site_name }}</span>
<span v-for="product in item.products" :key="product.id" class="l m-l-5">{{
product.name
}}-{{ product.pro_buff }}-{{ product.num }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="飞机操作">
<el-button-group>
<el-button size="mini" class="f-s-14" v-if="planeState & 1 && airLock" key="pubBut" type="info"
icon="iconfont el-icon-loading" disabled>
<font class="m-l-5">航线锁定</font>
</el-button>
<el-button size="mini" class="f-s-14" v-if="planeState & 1 && !airLock" type="primary"
icon="f-s-14 iconfont icon-chakanzhihangrizhi" @click="runQuest">
<font class="m-l-5">提交任务</font>
</el-button>
<el-button size="mini" class="f-s-14" v-if="planeState & 2" key="wirteBut" type="info"
icon="f-s-14 iconfont el-icon-loading" disabled>
<font class="m-l-5">航点写入中···</font>
</el-button>
<el-button size="mini" class="f-s-14" v-if="planeState & 4 && !(planeState & 16)" type="warning"
icon="f-s-14 iconfont icon-jiesuo"
@click="publishFun('{setPlaneState:{bit:3,state:1,count:2,param:[1,0]}}')">
<font class="m-l-5">解锁飞机</font>
</el-button>
<el-button size="mini" class="f-s-14" v-if="planeState & 16 && !(planeState & 1) && !(planeState & 2)"
type="success" icon="f-s-14 iconfont icon-yangshi_icon_tongyong_departure"
@click="publishFun('{setPlaneState:{bit:5,state:1}')">
<font class="m-l-5">执行任务</font>
</el-button>
</el-button-group>
</el-form-item>
<el-form-item label="订单操作">
<el-button-group>
<el-button size="mini" class="f-s-14" type="danger" icon="iconfont icon-meiyoudingdan-01" key="celBUt"
@click="reQuest">
<font class="m-l-5">取消</font>
</el-button>
<el-button size="mini" class="f-s-14" type="success" icon="iconfont icon-qiandai" key="bingBut"
@click="overQuest">
<font class="m-l-5">已送达</font>
</el-button>
</el-button-group>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="medium" @click="dialogVisible = false">关闭</el-button>
<el-button size="medium" type="primary"
@click="publishFun(`{setPlaneState:{bit:6,state:1,count:1,param:[${takeoffValue}]}`)">确认起飞</el-button>
</span>
</template>
<!-- 摄像头弹出框 -->
<template v-if="dialogItem == 'cameraBox'">
<div class="slider-container">
<div class="m-l-10 m-r-10"></div>
<el-slider @change="releaseCameraSlider('pitch')" @input="setCamera('pitch')" v-model="pitchValue"
:show-tooltip="false" class="w-80"></el-slider>
<div class="m-l-10 m-r-10"></div>
</div>
<div class="slider-container">
<div class="m-l-10 m-r-10"></div>
<el-slider @change="releaseCameraSlider('yaw')" @input="setCamera('yaw')" v-model="yawValue"
:show-tooltip="false" class="w-80"></el-slider>
<div class="m-l-10 m-r-10"></div>
</div>
<div class="slider-container">
<div class="m-l-10 m-r-10"></div>
<el-slider @change="releaseCameraSlider('scale')" @input="setCamera('scale')" v-model="scaleValue"
:show-tooltip="false" class="w-80"></el-slider>
<div class="m-l-10 m-r-10"></div>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="medium" @click="dialogVisible = false">关闭</el-button>
</span>
</template>
</el-dialog>
<!-- 侧边 tab -->
<div class="tab-container">
<el-button size="medium" type="primary" :class="activeIndex === index ? 'butIconGroupBG' : ''" class="butIconGroup"
v-for="(item, index) in controlItems" :key="index" @click="toggleContent(index)">
<i :class="item.icon" class="iconfont f-s-35"></i>
<div class="m-t-5 fb">{{ item.title }}</div>
</el-button>
<!-- 子内容菜单 -->
<div class="content" :class="{ 'active': activeIndex !== null }">
<!-- 订单任务 -->
<div v-if="activeIndex === 0" class="contentBox">
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-dingdanguanli f-s-22 m-r-5"></i>
<span>送餐任务</span>
</div>
<!-- 内容 -->
<el-form label-position="left" ref="questForm" :model="questForm" label-width="80px">
<el-form-item label="订单任务">
<el-select v-model="questForm.id" :filterable="isMobile" placeholder="请选择,也可输入搜索" :disabled="airLock">
<el-option v-for="item in questList" :key="item.id" :label="item.id" :value="item.id">
<span class="l">{{ item.id }}</span>
<span class="l m-l-5">{{ item.name }}</span>
<span class="l m-l-5">{{ item.receive_site_name }}</span>
<span v-for="product in item.products" :key="product.id" class="l m-l-5">{{
product.name
}}-{{ product.pro_buff }}-{{ product.num }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="飞机操作">
<el-button-group>
<el-button size="mini" class="f-s-14" v-if="planeState & 1 && airLock" key="pubBut" type="info"
icon="iconfont el-icon-loading" disabled>
<font class="m-l-5">航线锁定</font>
</el-button>
<el-button size="mini" class="f-s-14" v-if="planeState & 1 && !airLock" type="primary"
icon="f-s-14 iconfont icon-chakanzhihangrizhi" @click="runQuest">
<font class="m-l-5">提交任务</font>
</el-button>
<el-button size="mini" class="f-s-14" v-if="planeState & 2" key="wirteBut" type="info"
icon="f-s-14 iconfont el-icon-loading" disabled>
<font class="m-l-5">航点写入中···</font>
</el-button>
<el-button size="mini" class="f-s-14" v-if="planeState & 4 && !(planeState & 16)" type="warning"
icon="f-s-14 iconfont icon-jiesuo"
@click="publishFun('{setPlaneState:{bit:3,state:1,count:2,param:[1,0]}}')">
<font class="m-l-5">解锁飞机</font>
</el-button>
<el-button size="mini" class="f-s-14" v-if="planeState & 16 && !(planeState & 1) && !(planeState & 2)"
type="success" icon="f-s-14 iconfont icon-yangshi_icon_tongyong_departure"
@click="publishFun('{setPlaneState:{bit:5,state:1}')">
<font class="m-l-5">执行任务</font>
</el-button>
</el-button-group>
</el-form-item>
<el-form-item label="任务操作">
<el-button-group>
<el-button size="mini" class="f-s-14" type="danger" icon="iconfont icon-meiyoudingdan-01" key="celBUt"
@click="reQuest">
<font class="m-l-5">取消任务</font>
</el-button>
<el-button size="mini" class="f-s-14" type="success" icon="iconfont icon-qiandai" key="bingBut"
@click="overQuest">
<font class="m-l-5">已送达</font>
</el-button>
</el-button-group>
</el-form-item>
</el-form>
</div>
<!-- 飞机操作 -->
<template v-if="activeIndex === 1">
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-youxishoubing f-s-22 m-r-5"></i>
<span>飞机控制</span>
</div>
<div class="butIconBox">
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{setPlaneState:{bit:3,state:1,count:2,param:[1,0]}}')">
<i class="iconfont icon-jiesuo f-s-24"></i>
<div class="m-t-5">解锁</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="confirmation('飞机加锁,螺旋桨将停转,请谨慎操作!', '加锁操作', '{setPlaneState:{bit:3,state:0,count:2,param:[0,21196]}}')">
<i class=" iconfont icon-suoding f-s-24"></i>
<div class="m-t-5">加锁</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="dialogVisible = true; dialogTitle = '起飞参数设置'; dialogItem = 'takeoffBox'">
<i class="iconfont icon-yangshi_icon_tongyong_departure f-s-24"></i>
<div class="m-t-5">起飞</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{setPlaneState:{bit:7,state:1}')">
<i class="iconfont icon-fengzheng1 f-s-24"></i>
<div class="m-t-5">悬停</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border">
<i class="iconfont icon-duandianxufei f-s-24"></i>
<div class="m-t-5">复航</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{setPlaneState:{bit:9,state:1}')">
<i class="iconfont icon-yijianfanhang f-s-24"></i>
<div class="m-t-5">返航</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{setPlaneState:{bit:5,state:1}')">
<i class="iconfont icon-yangshi_icon_tongyong_arriving f-s-24"></i>
<div class="m-t-5">降落</div>
</el-button>
</div>
</template>
<!-- 附加模组操作 -->
<template v-if="activeIndex === 2">
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-mianxingdiaogou f-s-22 m-r-5"></i>
<span>挂载仓控制</span>
</div>
<div class="butIconBox">
<el-button size="medium" type="primary" class="butIcon border" @click="publishFun('{hookConteroller:4}')">
<i class="iconfont icon-zhongliang f-s-24"></i>
<div class="m-t-5">归零</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border" @click="publishFun('{hookConteroller:0}')">
<i class="iconfont icon-xiangshang f-s-24"></i>
<div class="m-t-5">收钩</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border" @click="publishFun('{hookConteroller:3}')">
<i class="iconfont icon-qiyong f-s-24"></i>
<div class="m-t-5">继续</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border" @click="publishFun('{hookConteroller:2}')">
<i class="iconfont icon-xuanting-zanting f-s-24"></i>
<div class="m-t-5">暂停</div>
</el-button>
</div>
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-shipinjiankong f-s-22 m-r-5"></i>
<span>摄像头控制</span>
</div>
<div class="butIconBox">
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{cameraController:{item:0,val:0}}')">
<i class="iconfont icon-icon-rotation f-s-24"></i>
<div class="m-t-5">回中</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{cameraController:{item:2,val:0,yaw:0,pitch:-50}}')">
<i class="iconfont icon-down f-s-24"></i>
<div class="m-t-5">俯视</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="dialogVisible = true; dialogTitle = '摄像头控制'; dialogItem = 'cameraBox'">
<i class="iconfont icon-chukong f-s-24"></i>
<div class="m-t-5">手动</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="dialogVisible = true; dialogTitle = '摄像头控制'; dialogItem = 'cameraBox'">
<i class="iconfont icon-fangda f-s-24"></i>
<div class="m-t-5">焦距</div>
</el-button>
</div>
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-tongzhi f-s-22 m-r-5"></i>
<span>喇叭控制</span>
</div>
<div class="butIconBox">
<el-button size="medium" type="primary" class="butIcon border">
<i class="iconfont icon-icon-test f-s-24"></i>
<div class="m-t-5">喊话</div>
</el-button>
</div>
</template>
<!-- 飞机调试 -->
<template v-if="activeIndex === 3">
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-banshou_Line f-s-22 m-r-5"></i>
<span>飞机调试</span>
</div>
<div class="butIconBox">
<el-button size="medium" type="primary" class="butIcon border" @click="publishFun('{bit:11,state:1}')">
<i class="iconfont icon-zhinanzhen f-s-24"></i>
<div class="m-t-5">磁罗盘</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border">
<i class="iconfont icon-zuobiaozhoupeizhixiang f-s-24"></i>
<div class="m-t-5">加速度计</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border">
<i class="iconfont icon-canshupeizhi f-s-24"></i>
<div class="m-t-5">写入参数</div>
</el-button>
</div>
</template>
</div>
<!-- 飞机操作 -->
<template v-if="activeIndex === 1">
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-youxishoubing f-s-22 m-r-5"></i>
<span>飞机控制</span>
</div>
<div class="butIconBox">
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{setPlaneState:{bit:3,state:1,count:2,param:[1,0]}}')">
<i class="iconfont icon-jiesuo f-s-24"></i>
<div class="m-t-5">解锁</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{setPlaneState:{bit:3,state:0,count:2,param:[0,21196]}}')">
<i class="iconfont icon-suoding f-s-24"></i>
<div class="m-t-5">加锁</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{setPlaneState:{bit:6,state:1,count:1,param:[2]}')">
<i class="iconfont icon-yangshi_icon_tongyong_departure f-s-24"></i>
<div class="m-t-5">起飞</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{setPlaneState:{bit:7,state:1}')">
<i class="iconfont icon-fengzheng1 f-s-24"></i>
<div class="m-t-5">悬停</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border">
<i class="iconfont icon-duandianxufei f-s-24"></i>
<div class="m-t-5">恢复航点</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{setPlaneState:{bit:9,state:1}')">
<i class="iconfont icon-yijianfanhang f-s-24"></i>
<div class="m-t-5">返航</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{setPlaneState:{bit:5,state:1}')">
<i class="iconfont icon-yangshi_icon_tongyong_arriving f-s-24"></i>
<div class="m-t-5">降落</div>
</el-button>
</div>
</template>
<!-- 附加模组操作 -->
<template v-if="activeIndex === 2">
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-mianxingdiaogou f-s-22 m-r-5"></i>
<span>挂载仓控制</span>
</div>
<div class="butIconBox">
<el-button size="medium" type="primary" class="butIcon border" @click="publishFun('{hookConteroller:4')">
<i class="iconfont icon-zhongliang f-s-24"></i>
<div class="m-t-5">重量归零</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border" @click="publishFun('{hookConteroller:0')">
<i class="iconfont icon-xiangshang f-s-24"></i>
<div class="m-t-5">收钩</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border" @click="publishFun('{hookConteroller:3')">
<i class="iconfont icon-qiyong f-s-24"></i>
<div class="m-t-5">继续</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border" @click="publishFun('{hookConteroller:2')">
<i class="iconfont icon-xuanting-zanting f-s-24"></i>
<div class="m-t-5">暂停</div>
</el-button>
</div>
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-shipinjiankong f-s-22 m-r-5"></i>
<span>摄像头控制</span>
</div>
<div class="butIconBox">
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{cameraController:{item:0,val:0}')">
<i class="iconfont icon-icon-rotation f-s-24"></i>
<div class="m-t-5">一键回中</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border"
@click="publishFun('{cameraController:{item:2,val:0,yaw:0,pitch:-1}}')">
<i class="iconfont icon-rotateX f-s-24"></i>
<div class="m-t-5">一键俯视</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border">
<i class="iconfont icon-rotateY f-s-24"></i>
<div class="m-t-5">旋转</div>
</el-button>
<el-button size="medium" type="primary" class="butIcon border">
<i class="iconfont icon-fangda f-s-24"></i>
<div class="m-t-5">焦距</div>
</el-button>
</div>
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-tongzhi f-s-22 m-r-5"></i>
<span>喇叭控制</span>
</div>
<div class="butIconBox">
<el-button size="medium" type="primary" class="butIcon border">
<i class="iconfont icon-icon-test f-s-24"></i>
<div class="m-t-5">喊话</div>
</el-button>
</div>
</template>
<!-- 飞机调试 -->
<template v-if="activeIndex === 3">
<!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit">
<i class="iconfont icon-tongzhi f-s-22 m-r-5"></i>
<span>飞机调试</span>
</div>
<div class="butIconBox">
<el-button size="medium" type="primary" class="butIcon border">
<i class="iconfont icon-icon-test f-s-24"></i>
<div class="m-t-5">喊话</div>
</el-button>
</div>
</template>
</div>
<!-- end 子内容菜单 -->
</div>
</template>
@ -201,6 +253,13 @@ export default {
name: 'TabController',
data () {
return {
dialogTitle: '', //
dialogItem: '', //
dialogVisible: false, //
pitchValue: 50, //
yawValue: 50, //
scaleValue: 50, //
takeoffValue: 2, //
controlItems: [//
{ title: '任务', icon: 'icon-songcanfuwu' },
{ title: '控制', icon: 'icon-youxishoubing' },
@ -264,6 +323,41 @@ export default {
},
methods: {
questAss,
/**
* @description: 摄像头 滑动条松开
* @param {string} item 项目
*/
releaseCameraSlider (item) {
if (item === 'pitch') {
this.pitchValue = 50
this.publishFun('{cameraController:{item:2,val:0,yaw:0,pitch:0}}')
} else if (item === 'yaw') {
this.yawValue = 50
this.publishFun('{cameraController:{item:2,val:0,yaw:0,pitch:0}}')
} else if (item === 'scale') {
this.publishFun('{cameraController:{item:1,val:0}}')
this.scaleValue = 50
}
},
/**
* @description: 摄像头 滑动条滚动 发送设置命令
* @param {*} item 项目
*/
setCamera (item) {
if (item === 'pitch') { // pitch
const pitchV = (this.pitchValue - 50) * 2
this.publishFun(`{cameraController:{item:2,yaw:0,pitch:${pitchV}}`)
} else if (item === 'yaw') { // yaw
const yawV = (this.yawValue - 50) * 2
this.publishFun(`{cameraController:{item:2,yaw:${yawV},pitch:0}`)
} else if (item === 'scale') {
if (this.scaleValue < 50) { //
this.publishFun('{cameraController:{item:1,val:1}}')
} else if (this.scaleValue > 50) {
this.publishFun('{cameraController:{item:1,val:255}}')
}
}
},
/**
* @description: 菜单切换 PS:UI
* @param {*} index 序号
@ -352,6 +446,23 @@ export default {
//
return replacedStr // "4513301115846"
},
/**
* @description: 确认操作
* @param {*}msg 提示的话语内容
* @param {*}tit 提示框的标题
* @param {*}instruct 需要发送的mqtt指令内容
*/
confirmation (msg, tit, instruct) {
this.$confirm(msg, tit, {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.publishFun(instruct)
}).catch(() => {
this.$message.info('取消操作!')
})
},
/**
* @description: 取消任务
*/
@ -359,7 +470,7 @@ export default {
if (!this.airLock) { // ""
return
}
this.$confirm('确认复位飞机状态,并清除航线的锁定?', '提示', {
this.$confirm('确认复位飞机状态,并清除航线的锁定?', '取消任务', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
@ -488,6 +599,12 @@ export default {
margin-bottom: 0px;
}
.slider-container {
display: flex;
align-items: center;
/* 水平垂直居中 */
}
.content {
color: $maintext-color;
border-radius: 15px;

View File

@ -97,13 +97,13 @@ export default {
style: this.GoogleRasterStyle,
center: this.defaultLnglat,
zoom: this.defaultZoom,
pitch: 45,
pitch: 0,
bearing: 0,
projection: 'globe'
})
//
this.map.addControl(new mapboxgl.ScaleControl(), 'bottom-right')
this.map.addControl(new mapboxgl.NavigationControl(), 'bottom-right')
this.map.addControl(new mapboxgl.NavigationControl(), 'bottom-left')
},
/**
* @description: 清除地图上的航线

View File

@ -1,12 +1,16 @@
<template>
<el-select v-if="adminList.length > 1" v-model="form.shop_id" filterable placeholder="所有客户" @input="updateShopId">
<el-option label="所有客户" value="">
<span class="l">All</span>
<span style="float: right; color: #8492a6; font-size: 13px">所有客户</span>
<el-select v-model="form.shop_id" filterable :placeholder="allSel === true ? '所有商铺' : '请选择,也可输入搜索'"
@input="updateShopId">
<el-option v-if="allSel === true && shopList.length > 1" label="所有商铺" value="">
<el-avatar class="vm f-s-12" shape="square" :size="25"> all </el-avatar>
<span class="rspan">所有商铺</span>
</el-option>
<el-option v-for="item in adminList" :key="item.id" :label="item.uname" :value="item.shop_id">
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.uname }}</span>
<el-option v-for="item in shopList" :key="item.id" :label="item.name" :value="item.shop_id">
<el-avatar v-if="item.logo != ''" class="vm" shape="square" :size="25"
:src="$store.state.settings.host + '/Data/UploadFiles/logo/' + item.logo">
</el-avatar>
<el-avatar v-else :size="25" class="vm" icon="iconfont icon-tuxiang"></el-avatar>
<span class="rspan">{{ item.name }}</span>
</el-option>
</el-select>
</template>
@ -15,23 +19,32 @@
export default {
name: 'Selection',
props: {
value: String // prop
value: String, // prop
allSel: Boolean //
},
data () {
return {
form: {
shop_id: ''
shop_id: this.initialShopId
}
}
},
computed: {
//
adminList () {
return this.$store.state.adminList
//
shopList () {
return this.$store.state.shopList
}
},
watch: {
adminList () {
shopList (val) {
this.form.shop_id = this.$store.state.user.shop_id
this.updateShopId()
}
},
created () {
if (this.shopList.length > 0) {
this.form.shop_id = this.$store.state.user.shop_id
this.updateShopId()
}
},
methods: {
@ -41,3 +54,17 @@ export default {
}
}
</script>
<style lang="scss" scoped>
.centered-avatar {
display: flex;
align-items: center;
justify-content: center;
}
.rspan {
float: right;
color: #8492a6;
font-size: 13px
}
</style>

View File

@ -16,7 +16,7 @@ import locale from 'element-ui/lib/locale/lang/zh-CN' // 引入中文语言包
Vue.use(ElementUI, { locale })
// 设置vue创建时 提示信息 false不提示
Vue.config.productionTip = false
Vue.config.productionTip = true
new Vue({
router,

View File

@ -15,6 +15,7 @@ router.beforeEach((to, from, next) => {
document.title = getPageTitle(to.meta.title)
// 路由
store.commit('user/initUser')// 用户信息初始化 PS:token不存在 执行且执行一次
const power = store.state.user.power
const token = store.state.user.token
if (token === null) {
if (to.path === '/login') {
@ -29,7 +30,11 @@ router.beforeEach((to, from, next) => {
next('/')
NProgress.done()
} else {
next()
if (to.meta.roles.indexOf(power) >= 0) { // 判断 roles权限 有权限打开页面 没权限跳转到首页
next()
} else {
next('/')
}
NProgress.done()
}
}

View File

@ -9,38 +9,51 @@ Vue.use(VueRouter)
const routes = [
{
path: '/login',
name: 'Login',
component: Login,
meta: { title: '登录' },
roles: ['admin', 'editor'],
hidden: true
meta: {
title: '登录',
roles: ['admin', 'editor'],
hidden: true
}
},
{
path: '/404',
name: 'Page404',
component: Page404,
meta: { title: '404' },
roles: ['admin', 'editor'],
hidden: true
meta: {
title: '404',
roles: ['admin', 'editor'],
hidden: true
}
},
{
path: '/',
redirect: '/home/index',
hidden: true
meta: {
title: '主页',
roles: ['admin', 'editor'],
hidden: true
}
},
{
path: '/home',
component: Layout,
meta: { title: '概况', icon: 'iconfont icon-fuwudiqiu' },
meta: {
title: '概况',
icon: 'iconfont icon-fuwudiqiu',
roles: ['admin', 'editor'],
tapName: 'plane'
},
redirect: '/home/index',
roles: ['admin', 'editor'],
children: [
{
path: '/home/index',
name: 'Home',
component: () => import('@/views/layout/components/main/home/index'),
meta: { title: '全图概况', icon: 'iconfont icon-fuwudiqiu' },
roles: ['admin', 'editor']
meta: {
title: '概况',
icon: 'iconfont icon-fuwudiqiu',
roles: ['admin', 'editor'],
tapName: 'plane'
}
}
]
},
@ -48,33 +61,53 @@ const routes = [
path: '/register',
component: Layout,
redirect: '/register/index',
meta: { title: '飞机管理', icon: 'el-icon-edit-outline' },
roles: ['admin', 'editor'],
meta: {
title: '飞机管理',
icon: 'el-icon-edit-outline',
roles: ['admin', 'editor'],
tapName: 'plane'
},
children: [
{
path: '/register/index',
component: () => import('@/views/layout/components/main/register/index'),
meta: { title: '飞机列表', icon: 'el-icon-tickets' },
roles: ['admin', 'editor']
meta: {
title: '飞机列表',
icon: 'el-icon-tickets',
roles: ['admin', 'editor'],
tapName: 'plane'
}
},
{
path: '/register/add/',
path: '/register/add',
component: () => import('@/views/layout/components/main/register/add'),
meta: { title: '添加飞机', icon: 'el-icon-plus' },
roles: ['admin', 'editor']
meta: {
title: '添加飞机',
icon: 'el-icon-plus',
roles: ['admin', 'editor'],
tapName: 'plane'
}
},
{
path: '/register/edit/:id',
component: () => import('@/views/layout/components/main/register/add'),
meta: { title: '更新飞机', icon: 'el-icon-edit' },
roles: ['admin', 'editor'],
hidden: true
meta: {
title: '更新飞机',
icon: 'el-icon-edit',
roles: ['admin', 'editor'],
tapName: 'plane',
hidden: true
}
},
{
path: '/register/crosFrequency',
component: () => import('@/views/layout/components/main/register/crosFrequency'),
meta: { title: '飞机对频', icon: 'el-icon-link' },
roles: ['admin', 'editor']
meta: {
title: '飞机对频',
icon: 'el-icon-link',
roles: ['admin', 'editor'],
tapName: 'plane'
}
}
]
},
@ -82,27 +115,43 @@ const routes = [
path: '/route',
component: Layout,
redirect: '/route/index',
meta: { title: '航线管理', icon: 'iconfont icon-feihangluxian' },
roles: ['admin', 'editor'],
meta: {
title: '航线管理',
icon: 'iconfont icon-feihangluxian',
roles: ['admin', 'editor'],
tapName: 'plane'
},
children: [
{
path: '/route/index',
component: () => import('@/views/layout/components/main/route/index'),
meta: { title: '航线列表', icon: 'iconfont icon-a-05-1-1jihuazhihanggenzong' },
roles: ['admin', 'editor']
meta: {
title: '航线列表',
icon: 'iconfont icon-a-05-1-1jihuazhihanggenzong',
roles: ['admin', 'editor'],
tapName: 'plane'
}
},
{
path: '/route/add/',
path: '/route/add',
component: () => import('@/views/layout/components/main/route/add'),
meta: { title: '设计航线', icon: 'iconfont icon-huizhi' },
roles: ['admin', 'editor']
meta: {
title: '设计航线',
icon: 'iconfont icon-huizhi',
roles: ['admin', 'editor'],
tapName: 'plane'
}
},
{
path: '/route/edit/:id',
component: () => import('@/views/layout/components/main/route/add'),
meta: { title: '编辑航线', icon: 'iconfont icon-huizhi' },
roles: ['admin', 'editor'],
hidden: true
meta: {
title: '编辑航线',
icon: 'iconfont icon-huizhi',
roles: ['admin', 'editor'],
tapName: 'plane',
hidden: true
}
}
]
},
@ -110,27 +159,43 @@ const routes = [
path: '/site',
component: Layout,
redirect: '/site/index',
meta: { title: '站点管理', icon: 'iconfont icon-zhandianguanli' },
roles: ['admin', 'editor'],
meta: {
title: '站点管理',
icon: 'iconfont icon-zhandianguanli',
roles: ['admin', 'editor'],
tapName: 'plane'
},
children: [
{
path: '/site/index',
component: () => import('@/views/layout/components/main/site/index'),
meta: { title: '站点列表', icon: 'el-icon-tickets' },
roles: ['admin', 'editor']
meta: {
title: '站点列表',
icon: 'el-icon-tickets',
roles: ['admin', 'editor'],
tapName: 'plane'
}
},
{
path: '/site/add/',
path: '/site/add',
component: () => import('@/views/layout/components/main/site/add'),
meta: { title: '添加站点', icon: 'el-icon-plus' },
roles: ['admin', 'editor']
meta: {
title: '添加站点',
icon: 'el-icon-plus',
roles: ['admin', 'editor'],
tapName: 'plane'
}
},
{
path: '/site/edit/:id',
component: () => import('@/views/layout/components/main/site/add'),
meta: { title: '更新站点', icon: 'el-icon-edit' },
roles: ['admin', 'editor'],
hidden: true
meta: {
title: '更新站点',
icon: 'el-icon-edit',
roles: ['admin', 'editor'],
tapName: 'plane',
hidden: true
}
}
]
},
@ -138,23 +203,177 @@ const routes = [
path: '/planes',
component: Layout,
redirect: '/planes/index',
meta: { title: '无人机', icon: 'iconfont icon-wurenji' },
roles: ['admin', 'editor'],
meta: {
title: '无人机',
icon: 'iconfont icon-wurenji',
roles: ['admin', 'editor'],
tapName: 'plane'
},
children: [
{
path: '/planes/index/:id/:name', // 动态加载路由时加ID参数
name: 'Planes',
component: () => import('@/views/layout/components/main/planes/index'),
meta: { title: '飞机加载中', icon: 'el-icon-loading' },
roles: ['admin', 'editor']
meta: {
title: '飞机加载中',
icon: 'el-icon-loading',
roles: ['admin', 'editor'],
tapName: 'plane'
}
}
]
},
{
path: '/shop',
component: Layout,
redirect: '/shop/edit',
meta: {
title: '商铺管理',
icon: 'iconfont icon-a-shanghu_choose2x1',
roles: ['admin', 'editor'],
tapName: 'admin'
},
children: [
{
path: '/shop/edit',
component: () => import('@/views/layout/components/main/shop/add'),
meta: {
title: '商铺设置',
icon: 'iconfont icon-dianpuguanli',
roles: ['admin', 'editor'],
tapName: 'admin'
}
},
{
path: '/shop/add',
component: () => import('@/views/layout/components/main/shop/add'),
meta: {
title: '添加商铺',
icon: 'iconfont icon-check',
roles: ['admin', 'editor'],
tapName: 'admin'
}
}
]
},
{
path: '/admin',
component: Layout,
redirect: '/admin/index',
meta: {
title: '管理员管理',
icon: 'iconfont icon-guanliyuan',
roles: ['admin', 'editor'],
tapName: 'admin'
},
children: [
{
path: '/admin/index',
component: () => import('@/views/layout/components/main/admin/index'),
meta: {
title: '账户列表',
icon: 'iconfont icon-yonghuguanli',
roles: ['admin', 'editor'],
tapName: 'admin'
}
},
{
path: '/admin/add',
component: () => import('@/views/layout/components/main/admin/add'),
meta: {
title: '添加账户',
icon: 'iconfont icon-xinzengguanliyuan',
roles: ['admin', 'editor'],
tapName: 'admin'
}
},
{
path: '/admin/edit/:id',
component: () => import('@/views/layout/components/main/admin/add'),
meta: {
title: '编辑账户',
icon: 'iconfont icon-huizhi',
roles: ['admin', 'editor'],
tapName: 'admin',
hidden: true
}
}
]
},
{
path: '/category',
component: Layout,
redirect: '/category/index',
meta: {
title: '分类管理',
icon: 'iconfont icon-a-ziliaocaozuoxianshifenleishu',
roles: ['admin', 'editor'],
tapName: 'admin'
},
children: [
{
path: '/category/index',
component: () => import('@/views/layout/components/main/category/index'),
meta: {
title: '分类管理',
icon: 'iconfont icon-a-ziliaocaozuoxianshifenleishu',
roles: ['admin', 'editor'],
tapName: 'admin'
}
}
]
},
{
path: '/product',
component: Layout,
redirect: '/product/index',
meta: {
title: '产品管理',
icon: 'iconfont icon-chanpin',
roles: ['admin', 'editor'],
tapName: 'admin'
},
children: [
{
path: '/product/index',
component: () => import('@/views/layout/components/main/product/index'),
meta: {
title: '产品列表',
icon: 'iconfont icon-chanpinliebiao-02',
roles: ['admin', 'editor'],
tapName: 'admin'
}
},
{
path: '/product/add',
component: () => import('@/views/layout/components/main/product/add'),
meta: {
title: '添加产品',
icon: 'iconfont icon-huoquchanpin',
roles: ['admin', 'editor'],
tapName: 'admin'
}
},
{
path: '/product/edit/:id',
component: () => import('@/views/layout/components/main/product/add'),
meta: {
title: '编辑产品',
icon: 'iconfont icon-huoquchanpin',
roles: ['admin', 'editor'],
tapName: 'admin',
hidden: true
}
}
]
},
{
path: '*',
redirect: '/404',
roles: ['admin', 'editor'],
hidden: true
meta: {
title: '404',
roles: ['admin', 'editor'],
hidden: true
}
}
]

View File

@ -9,12 +9,14 @@ module.exports = {
* @description: api服务器
* host 主站
* api接口地址
* api常规接口路径
* api飞机控制终端接口路径
* api小程序后台接口路径
* api登录接口路径
*/
host: 'https://szdot.top',
baseURL: 'https://szdot.top/flycube.php',
apiPath: '/mpApi/Index/',
apiPlanePath: '/mpApi/Plane/',
apiAdminPath: '/mpApi/Admin/',
apiLoginPath: '/mpApi/Login/',
/**
* @description: mqtt服务器

View File

@ -10,15 +10,24 @@ Vue.use(Vuex)
const store = new Vuex.Store({
state: {
shopList: [], // 商铺列表
adminList: [], // 管理员列表
airList: [], // 所有飞机列表
siteList: [], // 站点列表
routeList: [], // 航线列表
categoryList: [], // 分类列表(小程序)
productList: [], // 产品列表
questList: [], // 订单列表
logList: [], // 操作日志列表
crosFrequency: null // 对频macadd
},
mutations: {
/**
* @description: 设置商铺列表
*/
setShopList (state, list) {
state.shopList = list
},
/**
* @description: 设置管理员列表
*/
@ -43,6 +52,18 @@ const store = new Vuex.Store({
setRouteList (state, list) {
state.routeList = list
},
/**
* @description: 设置分类列表
*/
setCategoryList (state, list) {
state.categoryList = list
},
/**
* @description: 设置产品列表
*/
setProductList (state, list) {
state.productList = list
},
/**
* @description: 设置订单列表
*/
@ -64,17 +85,167 @@ const store = new Vuex.Store({
}
},
actions: {
/**
* @description: 获取商铺列表
*/
async fetchShopList ({ commit }) {
const res = await api.get('getShopList', 'Admin')
if (res.data.status === 1) {
commit('setShopList', res.data.shopList)
} else {
Message.error(res.data.msg)
}
},
/**
* @description: 添加商铺
* @param {*} 商铺信息表单
* @return {*} 服务器返回值
*/
async fetchAddShop ({ dispatch }, form) {
const params = new URLSearchParams()
params.append('name', form.name)
params.append('waiter', form.waiter)
params.append('service_wx', form.service_wx)
params.append('tel', form.tel)
params.append('email', form.email)
params.append('price_min', form.price_min)
params.append('weight_max', form.weight_max)
params.append('desc', form.desc)
params.append('upFile', form.upFile)
params.append('opening_time', form.opening_time)
params.append('closeing_time', form.closeing_time)
const res = await api.post('addShop', params, 'Admin')
if (res.data.status === 1) {
await dispatch('fetchShopList')// 刷新商铺列表
Message.success(res.data.msg)
} else {
Message.error(res.data.msg)
}
return res
},
/**
* @description: 更新管商铺信息
* @param {*} 商铺信息表单
* @return {*} 服务器返回值
*/
async fetchSaveShop ({ dispatch }, form) {
const params = new URLSearchParams()
params.append('shop_id', form.shop_id)
params.append('name', form.name)
params.append('waiter', form.waiter)
params.append('service_wx', form.service_wx)
params.append('tel', form.tel)
params.append('email', form.email)
params.append('price_min', form.price_min)
params.append('weight_max', form.weight_max)
params.append('desc', form.desc)
params.append('upFile', form.upFile)
params.append('oldFile', form.oldFile)
params.append('opening_time', form.opening_time)
params.append('closeing_time', form.closeing_time)
const res = await api.post('saveShop', params, 'Admin')
if (res.data.status === 1) {
await dispatch('fetchShopList')// 刷新商铺列表
Message.success(res.data.msg)
} else {
Message.error(res.data.msg)
}
return res
},
/**
* @description: 获取管理员列表
*/
async fetchAdminList ({ commit }) {
const res = await api.get('getAdminList')
const res = await api.get('getAdminList', 'Admin')
if (res.data.status === 1) {
res.data.adminList.forEach(item => { // 判断如果是当前登录用户 最后登录时间字段 从本地缓存中获取 PS:既登陆前缓存到本地的“最后登陆时间” 因为登录后 服务端会把当前登录的时间刷到lasttime字段
if (item.shop_id === store.state.user.shop_id) {
item.lasttime = store.state.user.lasttime
}
})
commit('setAdminList', res.data.adminList)
} else {
Message.error(res.data.msg)
}
},
/**
* @description: 添加新的管理员
* @param {*} 管理员信息表单
* @return {*} 服务器返回值
*/
async fetchAddAdmin ({ dispatch }, form) {
const params = new URLSearchParams()
params.append('name', form.name)
params.append('uname', form.uname)
params.append('pwd', form.pwd)
params.append('shop_id', form.shop_id)
if (form.upFile) {
params.append('upFile', form.upFile)
}
const res = await api.post('addAdmin', params, 'Admin')
if (res.data.status === 1) {
await dispatch('fetchAdminList')// 刷新用户列表
Message.success(res.data.msg)
} else {
Message.error(res.data.msg)
}
return res
},
/**
* @description: 更新管理员账号信息
* @param {*} 管理员信息表单
* @return {*} 服务器返回值
*/
async fetchSaveAdmin ({ dispatch }, form) {
console.log(form)
const params = new URLSearchParams()
params.append('id', form.id)
params.append('shop_id', form.shop_id)
params.append('uname', form.uname)
params.append('pwd', form.pwd)
if (form.upFile) {
params.append('upFile', form.upFile)
}
if (form.oldFile) {
params.append('oldFile', form.oldFile)
}
const res = await api.post('saveAdmin', params, 'Admin')
if (res.data.status === 1) {
await dispatch('fetchAdminList')// 刷新用户列表
Message.success(res.data.msg)
} else {
Message.error(res.data.msg)
}
return res
},
/**
* @description: 删除账号
* @param {*} 多选id组
*/
async fetchDelAdmin ({ dispatch }, idArr) {
if (idArr.length === 0) {
Message.error('未勾选记录')
} else {
MessageBox.confirm('请谨慎操作 确认删除?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const params = new URLSearchParams()
params.append('idArr', idArr)
api.post('deleteAdmin', params, 'Admin').then(res => {
if (res.data.status === 1) {
Message.success(res.data.msg)
dispatch('fetchAdminList')// 刷新管理员列表
} else {
Message.error(res.data.msg)
}
})
}).catch(() => {
Message.info('取消操作')
})
}
},
/**
* @description: 获取飞机列表
*/
@ -104,7 +275,6 @@ const store = new Vuex.Store({
if (res.data.status === 1) {
commit('setAirList', res.data.airList)
} else {
commit('setSiteList', [])
Message.warning(res.data.msg)
}
return res.data.airList
@ -119,10 +289,10 @@ const store = new Vuex.Store({
params.append('shop_id', form.shop_id)
params.append('name', form.name)
params.append('date', form.date)
if (form.state) {
params.append('state', '1')
if (form.onoff) {
params.append('onoff', '1')
} else {
params.append('state', '0')
params.append('onoff', '0')
}
params.append('desc', form.desc)
const res = await api.post('addAir', params)
@ -144,10 +314,10 @@ const store = new Vuex.Store({
params.append('shop_id', form.shop_id)
params.append('name', form.name)
params.append('date', form.date)
if (form.state) {
params.append('state', '1')
if (form.onoff) {
params.append('onoff', '1')
} else {
params.append('state', '0')
params.append('onoff', '0')
}
params.append('desc', form.desc)
params.append('id', form.id)
@ -196,7 +366,6 @@ const store = new Vuex.Store({
if (res.data.status === 1) {
commit('setSiteList', res.data.siteList)
} else {
commit('setSiteList', [])
Message.warning(res.data.msg)
}
},
@ -373,6 +542,76 @@ const store = new Vuex.Store({
})
}
},
/**
* @description: 获取分类列表
* @return {*} 列表
*/
async fetchCategoryList ({ commit }) {
const res = await api.get('getCategoryList', 'Admin')
if (res.data.status === 1) {
commit('setCategoryList', res.data.categoryList)
}
return res
},
/**
* @description: 添加分类信息
* @param {*} 分类信息表单
* @return {*} 服务器返回值
*/
async fetchAddCategory ({ dispatch }, form) {
const params = new URLSearchParams()
params.append('shop_id', form.shop_id)
params.append('id', form.id)
params.append('path', form.path)
params.append('name', form.name)
params.append('sort', form.sort)
params.append('show', form.show)
params.append('desc', form.desc)
params.append('upFile', form.upFile)
const res = await api.post('addCategory', params, 'Admin')
if (res.data.status === 1) {
await dispatch('fetchCategoryList')// 刷新商铺列表
Message.success(res.data.msg)
} else {
Message.error(res.data.msg)
}
return res
},
/**
* @description: 更新分类信息
* @param {*} 分类信息表单
* @return {*} 服务器返回值
*/
async fetchSaveCategory ({ dispatch }, form) {
const params = new URLSearchParams()
params.append('shop_id', form.shop_id)
params.append('id', form.id)
params.append('name', form.name)
params.append('sort', form.sort)
params.append('show', form.show)
params.append('desc', form.desc)
params.append('upFile', form.upFile)
params.append('oldFile', form.oldFile)
const res = await api.post('saveCategory', params, 'Admin')
if (res.data.status === 1) {
await dispatch('fetchCategoryList')// 刷新商铺列表
Message.success(res.data.msg)
} else {
Message.error(res.data.msg)
}
return res
},
/**
* @description: 获取产品列表
* @return {*} 列表
*/
async fetchProductList ({ commit }) {
const res = await api.get('getProductList', 'Admin')
if (res.data.status === 1) {
commit('setProductList', res.data.productList)
}
return res
},
/**
* @description: 获取订单列表 ps:待发货及待收货 并且不是退款成功状态
* @return {*} 列表

View File

@ -4,7 +4,8 @@ const {
title,
host,
baseURL,
apiPath,
apiPlanePath,
apiAdminPath,
apiLoginPath,
mqttHost,
mqttPort,
@ -16,7 +17,8 @@ const state = {
title: title,
host: host,
baseURL: baseURL,
apiPath: apiPath,
apiPlanePath: apiPlanePath,
apiAdminPath: apiAdminPath,
apiLoginPath: apiLoginPath,
mqttHost: mqttHost,
mqttPort: mqttPort,

View File

@ -1,3 +1,7 @@
import api from '@/utils/api'
import router from '@/router'
import { Message } from 'element-ui'
export default {
namespaced: true,
state: {
@ -6,7 +10,8 @@ export default {
uname: null,
photo: null,
shop_id: null,
power: null
power: null,
lasttime: null
},
mutations: {
// 用户信息初始化
@ -19,6 +24,7 @@ export default {
state.photo = localStorage.getItem('photo')
state.shop_id = localStorage.getItem('shop_id')
state.power = localStorage.getItem('power')
state.lasttime = localStorage.getItem('lasttime')
}
}
},
@ -30,6 +36,7 @@ export default {
state.photo = null
state.shop_id = null
state.power = null
state.lasttime = null
localStorage.removeItem('token')
}
},
@ -37,6 +44,31 @@ export default {
// 异步 清除用户信息
async destroyUserAsync (context) {
await context.commit('destroyUser')
},
/**
* @description: 登录
* @param {*} params 表单.用户登录信息
*/
async fetchLogin ({ commit }, params) {
const data = new URLSearchParams()// post对象参数 转成 字符串连接
data.append('username', params.username)
data.append('password', params.password)
api.post('login', data, 'Login').then(
res => {
if (res.data.status === 1) {
localStorage.setItem('token', res.data.token)
localStorage.setItem('name', res.data.adminInfo.name)
localStorage.setItem('uname', res.data.adminInfo.uname)
localStorage.setItem('photo', res.data.adminInfo.photo)
localStorage.setItem('shop_id', res.data.adminInfo.shop_id)
localStorage.setItem('power', res.data.adminInfo.power)
localStorage.setItem('lasttime', res.data.adminInfo.lasttime)
router.replace('/')
} else {
Message.error(res.data.msg)
}
}
)
}
}
}

View File

@ -1 +1 @@
@import 'https://at.alicdn.com/t/c/font_3703467_4teeodr1wrk.css'; //iconfont阿里巴巴
@import 'https://at.alicdn.com/t/c/font_3703467_89thn6xt9aj.css'; //iconfont阿里巴巴

View File

@ -2,9 +2,6 @@ import axios from 'axios'
import router from '@/router'
import store from '@/store'
// axios缺省设置
axios.defaults.baseURL = store.state.settings.baseURL
// axios.defaults.headers.post['Content-Type'] = 'application/json'
export default {
get,
post
@ -13,10 +10,10 @@ export default {
* @description: 异步 get方法 访问api
* @return: json.data对象
* @param {string} controller 控制器名称
* @param {bool} islogin 默认为index路径 否则访问login路径
* @param {string} prefix 根据不同的参数 调用不同路径的接口
*/
async function get (controller, islogin = false) {
const path = init(islogin)
async function get (controller, prefix = 'Plane') {
const path = init(prefix)
try {
const res = await axios.get(path + controller)
if (res.data.status === -1) { // 权限过期
@ -34,10 +31,10 @@ async function get (controller, islogin = false) {
* @return: json.data对象
* @param {string} controller 控制器名称
* @param {obj} params post参数
* @param {bool} islogin 默认为index路径 否则访问login路径
* @param {string} prefix 根据不同的参数 调用不同路径的接口
*/
async function post (controller, params, islogin = false) {
const path = init(islogin)
async function post (controller, params, prefix = 'Plane') {
const path = init(prefix)
try {
const res = await axios.post(path + controller, params)
if (res.data.status === -1) { // 权限过期
@ -53,16 +50,22 @@ async function post (controller, params, islogin = false) {
/**
* @description: 判断访问常规还是登录接口路径 设置token头文件
* @return {*} 接口路径
* @param {bool} islogin
* @param {string} prefix 根据不同的参数 调用不同路径的接口
*/
function init (islogin) {
function init (prefix) {
// axios缺省设置
axios.defaults.baseURL = store.state.settings.baseURL
// axios.defaults.headers.post['Content-Type'] = 'application/json'
let path
if (islogin) {
if (prefix === 'Plane') {
axios.defaults.headers.common.Token = store.state.user.token
path = store.state.settings.apiPlanePath
} else if (prefix === 'Admin') {
axios.defaults.headers.common.Token = store.state.user.token
path = store.state.settings.apiAdminPath
} else if (prefix === 'Login') {
axios.defaults.headers.common.Token = 'login'
path = store.state.settings.apiLoginPath
} else {
axios.defaults.headers.common.Token = store.state.user.token
path = store.state.settings.apiPath
}
return path
}

View File

@ -1,24 +0,0 @@
import api from '@/utils/api'
import router from '@/router'
import { Message } from 'element-ui'
export function login (params) {
const data = new URLSearchParams()// post对象参数 转成 字符串连接
data.append('username', params.username)
data.append('password', params.password)
api.post('login', data, true).then(
res => {
if (res.data.status === 1) {
localStorage.setItem('token', res.data.token)
localStorage.setItem('name', res.data.adminInfo.name)
localStorage.setItem('uname', res.data.adminInfo.uname)
localStorage.setItem('photo', res.data.adminInfo.photo)
localStorage.setItem('shop_id', res.data.adminInfo.shop_id)
localStorage.setItem('power', res.data.adminInfo.power)
router.replace('/')
} else {
Message.error(res.data.msg)
}
}
)
}

View File

@ -13,7 +13,9 @@
<div class="right-menu m-r-5">
<el-dropdown class="avatar-container" trigger="click">
<div class="avatar-wrapper">
<img :src="avatar + '?imageView2/1/w/80/h/80'" class="user-avatar">
<img v-if="avatar.indexOf('.jpg') !== -1 || avatar.indexOf('.gif') !== -1 || avatar.indexOf('.png') !== -1"
:src="avatar + '?imageView2/1/w/80/h/80'" class="user-avatar">
<el-avatar v-else size="medium" icon="el-icon-user-solid"></el-avatar>
<i class="el-icon-caret-bottom" />
</div>
<el-dropdown-menu slot="dropdown" class="user-dropdown">
@ -34,7 +36,8 @@
</div>
<!-- 订单信息按钮 -->
<el-badge :hidden="orderCount == 0 ? true : false" :value="orderCount" class="navbarBadge l-h-50 p-r-15 r">
<el-button @click="drawer = true" size="small" :icon="orderIcon" circle></el-button>
<el-button :type="orderCount !== 0 ? 'primary' : ''" @click="drawer = true" size="small" :icon="orderIcon"
circle></el-button>
</el-badge>
<el-drawer title="待处理订单" :visible.sync="drawer" size="40%" :append-to-body="true" :modal-append-to-body="false">
<el-tabs type="card">
@ -50,7 +53,11 @@
</el-tabs>
</el-drawer>
<!-- mqtt状态灯 -->
<div class="l-h-50 p-r-15 r">{{ mqttState === true ? "在线" : "掉线" }}</div>
<div class="l-h-50 p-r-15 r">
<el-button size="small" :type="mqttState === true ? 'success' : 'danger'"
:icon="mqttState === true ? 'iconfont icon-yaokong2' : 'iconfont icon-yaokong2-copy'" circle
@click="mqttState === true ? $message.success('指令服务器链接正常') : $message.error('未链接到指令服务器')"></el-button>
</div>
</div>
</template>

View File

@ -0,0 +1,207 @@
<template>
<div class="app-container">
<el-row class="m-t-0">
<el-col :span="24">
<el-container>
<el-header height="42px" class="l-h-42 p-l-10 p-r-10 border border-b-n">
<div class="l">
<i v-if="pageState === 'add'" class="iconfont el-icon-plus f-s-20"></i>
<i v-else class="iconfont el-icon-edit f-s-20"></i>
<font class="m-l-10 f-s-18 fb">{{ $route.meta.title }}</font>
</div>
</el-header>
<el-main class="border p-20">
<el-form ref="form" :model="form" label-width="120px">
<el-form-item v-if="pageState === 'add'" label="所属商铺">
<Selection v-model="form.shop_id" :allSel="false" />
</el-form-item>
<el-form-item label="账号">
<el-input v-model="form.name" placeholder="账号" :disabled="adminId == undefined ? false : true" />
</el-form-item>
<el-form-item label="昵称">
<el-input v-model="form.uname" placeholder="用户昵称" />
</el-form-item>
<el-form-item label="头像">
<el-upload class="avatar-uploader" drag name="file" :action="action" :headers="myheader"
:show-file-list="false" :on-success="handleUpSuccess" :on-error="handleUpErr"
:before-upload="beforeAvatarUpload">
<img v-if="form.upFile != ''"
:src="$store.state.settings.host + '/Data/UploadFiles/temp/' + form.upFile" class="avatar" />
<img v-else-if="form.oldFile != '' && form.upFile == ''"
:src="$store.state.settings.host + '/Data/UploadFiles/photo/' + form.oldFile" class="avatar" />
<template v-else>
<i class="el-icon-plus f-s-30 m-t-70 seatFontColor"></i>
<div class="el-upload__text"><em>建议100*100像素 <br> jpg png gif </em></div>
</template>
</el-upload>
</el-form-item>
<el-form-item :label="adminId == undefined ? '初始密码' : '新密码'">
<el-input show-password v-model="form.pwd" :placeholder="adminId == undefined ? '密码' : '空置则为保持原密码'" />
</el-form-item>
<el-form-item v-if="pageState == 'add' ? true : false">
<el-button type="primary" icon="el-icon-plus" @click="addAdmin">创建</el-button>
<el-button @click="setForm({})" class="iconfont icon-qingchu">
<font class="m-l-5">重填</font>
</el-button>
</el-form-item>
<el-form-item v-else>
<el-button type="primary" icon="el-icon-edit" @click="saveAdmin">更新</el-button>
</el-form-item>
</el-form>
</el-main>
</el-container>
</el-col>
</el-row>
</div>
</template>
<script>
import Selection from '@/components/Selection'
export default {
name: 'AdminAdd',
data () {
return {
action: this.$store.state.settings.baseURL + this.$store.state.settings.apiAdminPath + 'upImgFile',
myheader: { token: this.$store.state.user.token },
form: {
shop_id: '',
name: '',
uname: '',
upFile: '',
oldFile: '',
pwd: ''
},
adminId: this.$route.params.id, // get id
pageState: '', //
admin: null
}
},
components: {
Selection
},
computed: {
/**
* @description: 获取管理员列表
*/
adminList () {
return this.$store.state.adminList
}
},
methods: {
/* 文件上传表单 */
handleUpSuccess (res) {
if (res.status === 0) {
this.$message.error(res.msg)
} else {
this.form.upFile = res.data
this.$message.success(res.msg)
}
},
beforeAvatarUpload (file) {
const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif'
if (!isJPG) {
this.$message.error('上传图片只能是JPG|PNG|GIF格式!')
}
return isJPG
},
handleUpErr () {
this.$message.error('接口访问失败')
},
//
setForm (data) {
this.form.shop_id = data.shop_id
this.form.name = data.name
this.form.uname = data.uname
this.form.oldFile = data.oldFile
if (Object.keys(data).length === 0) {
this.$message.warning('清空表单')
}
},
// or
initPage () {
if (this.adminId === undefined) {
this.pageState = 'add'
} else {
this.pageState = 'edit'
this.admin = this.adminList.find((item) => item.id === this.adminId)
if (this.admin) {
const data = {
name: this.admin.name,
uname: this.admin.uname,
oldFile: this.admin.photo,
shop_id: this.admin.shop_id
}
this.setForm(data)
}
}
},
/**
* @description: 创建新账号
*/
async addAdmin () {
const res = await this.$store.dispatch('fetchAddAdmin', this.form)
if (res.data.status === 1) {
this.$router.push('/admin/index')
}
},
/**
* @description: 更新账号
*/
async saveAdmin () {
this.form.id = this.adminId
const res = await this.$store.dispatch('fetchSaveAdmin', this.form)
if (res.data.status === 1) {
this.$router.push('/admin/index')
}
}
},
watch: {
adminList () {
this.initPage()//
}
},
created () {
if (this.adminList.length > 0) {
this.initPage()//
}
}
}
</script>
<style scoped>
.line {
text-align: center;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
.el-upload__text {
line-height: 1.2em !important;
}
</style>

View File

@ -0,0 +1,130 @@
<template>
<div class="app-container">
<!-- 组合按钮 -->
<el-button-group>
<el-button type="primary" icon="el-icon-plus" @click="$router.replace('/admin/add')">添加</el-button>
<el-button type="danger" icon="el-icon-delete" @click="deleteAdmin(countSelIdArr($refs.myTable.selection))">删除
</el-button>
<el-button type="warning" icon="el-icon-edit" @click="toEditPage()">编辑</el-button>
</el-button-group>
<!-- 用户select选项 -->
<el-button-group class="m-l-20">
<Selection v-model="form.shop_id" :allSel="true" />
</el-button-group>
<!-- 管理员列表 -->
<el-table class="m-t-20 w-100" ref="myTable"
:data="adminListArr.slice((currentPage - 1) * pageSize, currentPage * pageSize)" border tooltip-effect="dark">
<el-table-column align="center" type="selection" width="40">
</el-table-column>
<el-table-column align="center" prop="id" label="id" width="50">
</el-table-column>
<el-table-column prop="name" label="账户名" width="150" min-width="150">
</el-table-column>
<el-table-column prop="uname" label="昵称" min-width="150">
</el-table-column>
<el-table-column label="最后登录时间" width="140" min-width="120">
<template slot-scope="scope">
{{ scope.row.lasttime | parseTime('{y}-{m}-{d} {h}:{i}') }}
</template>
</el-table-column>
<el-table-column label="注册时间" width="100" min-width="80">
<template slot-scope="scope">
{{ scope.row.addtime | parseTime('{y}-{m}-{d}') }}
</template>
</el-table-column>
<el-table-column prop="controler" label="操作" width="200" min-width="200">
<template slot-scope="scope">
<el-button-group>
<el-button type="warning" icon="el-icon-edit"
@click="$router.replace(`/admin/edit/${scope.row.id}`)">编辑</el-button>
<el-button type="danger" icon="el-icon-delete" @click="deleteAdmin([scope.row.id])">删除</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination class="m-t-20" layout="prev, pager, next" :current-page.sync="currentPage" :page-size="pageSize"
:total="adminListArr.length">
</el-pagination>
</div>
</template>
<script>
import { parseTime, countSelIdArr } from '@/utils'
import Selection from '@/components/Selection'
export default {
name: 'Admin',
data () {
return {
pageSize: 8, //
currentPage: 1, //
form: {
shop_id: ''
}
}
},
components: {
Selection
},
computed: {
adminList () {
return this.$store.state.adminList
},
/**
* @description: 过滤掉 不对应客户的 飞机列表
* @return: 飞机列表
*/
adminListArr () {
if (this.form.shop_id !== '') {
return this.adminList.filter((item) => item.shop_id === this.form.shop_id)
} else {
return this.adminList
}
}
},
methods: {
countSelIdArr,
/**
* @description: 跳转到编辑页面
*/
toEditPage () {
const selId = this.countSelIdArr(this.$refs.myTable.selection)
switch (selId.length) {
case 0:
this.$message.error('请选择一条需要编辑的记录')
break
case 1:
this.$router.push('/admin/edit/' + selId['0'])
break
default:
this.$message.error('只能选择一条记录')
}
},
/**
* @description: 删除用户
*/
deleteAdmin (idArr) {
this.$store.dispatch('fetchDelAdmin', idArr)
}
},
watch: {
},
created () {
},
filters: {
parseTime,
countSelIdArr
}
}
</script>
<style lang="scss" scoped>
@import "@/styles/theme.scss";
.el-tag {
i {
vertical-align: middle
}
}
</style>

View File

@ -0,0 +1,269 @@
<template>
<div class="app-container">
<el-row class="m-t-0" :gutter="10">
<!-- 分类树窗口 -->
<el-col :span="10">
<el-container>
<el-header height="42px" class="l-h-42 p-l-10 p-r-10 border border-b-n">
<div class="l">
<i class="iconfont icon-a-ziliaocaozuoxianshifenleishu f-s-20"></i>
<font class="m-l-10 f-s-18 fb">分类树</font>
</div>
</el-header>
<el-main class="border p-20">
<!-- 用户select选项 -->
<el-button-group class="m-b-10">
<Selection v-model="form.shop_id" :allSel="false" />
</el-button-group>
<!-- 分类树 -->
<div>
<el-button type="text" @click="openWin('添加根分类', { id: 0, path: '', bz_1: '' })">
添加根分类
</el-button>
</div>
<el-tree :data="categoryListData" :default-expand-all="true">
<span class="custom-tree-node" slot-scope="{ data }">
<span :class="data.show == 0 ? 'hideColor' : ''">{{ data.name }}</span>
<span>
<el-button type="text" @click.stop=""
@click="openWin(`${data.name} : 添加子分类`, { id: data.id, path: data.path, bz_1: '' })">
添加子分类
</el-button>
<el-button type="text" @click.stop="" @click="openWin(`${data.name} : 编辑`, data)">
编辑
</el-button>
<el-button type="text" @click.stop="">
删除
</el-button>
</span>
</span>
</el-tree>
<!-- END 分类树 -->
</el-main>
</el-container>
</el-col>
<!-- 分类操作窗口 -->
<el-col v-if="winIsShow" :span="14">
<el-container>
<el-header height="42px" class="l-h-42 p-l-10 p-r-10 border border-b-n">
<div class="l">
<template v-if="winTitle.indexOf('添加') > -1">
<i class=" iconfont el-icon-plus f-s-20"></i>
</template>
<template v-else>
<i class=" iconfont el-icon-edit f-s-20"></i>
</template>
<font class="m-l-10 f-s-18 fb">{{ winTitle }}</font>
</div>
</el-header>
<el-main class="border p-20">
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="分类名称">
<el-input v-model="form.name" placeholder="分类的名称" />
</el-form-item>
<el-form-item label="排序">
<el-input v-model="form.sort" placeholder="数值大排在前面,缺省值为0" />
</el-form-item>
<el-form-item :label="form.show === true ? '前台显示' : '前台隐藏'">
<el-switch v-model="form.show" />
</el-form-item>
<el-form-item label="图标上传">
<el-upload class="avatar-uploader" drag name="file" :action="action" :headers="myheader"
:show-file-list="false" :on-success="handleUpSuccess" :on-error="handleUpErr"
:before-upload="beforeAvatarUpload">
<img v-if="form.upFile != ''"
:src="$store.state.settings.host + '/Data/UploadFiles/temp/' + form.upFile" class="avatar" />
<img v-else-if="form.oldFile != '' && form.upFile == ''"
:src="$store.state.settings.host + '/Data/UploadFiles/category/' + form.oldFile" class="avatar" />
<template v-else>
<i class="el-icon-plus f-s-30 m-t-70 seatFontColor"></i>
<div class="el-upload__text"><em>建议100*100像素 <br> jpg png gif </em></div>
</template>
</el-upload>
</el-form-item>
<el-form-item label="分类描述">
<el-input v-model="form.desc" type="textarea" placeholder="非必填" />
</el-form-item>
<el-form-item v-if="winTitle.indexOf('添加') > -1 ? true : false">
<el-button type="primary" icon="el-icon-plus" @click="addCategory">创建</el-button>
<el-button @click="setForm({})" class="iconfont icon-qingchu">
<font class="m-l-5">重填</font>
</el-button>
</el-form-item>
<el-form-item v-else>
<el-button type="primary" icon="el-icon-edit" @click="saveCategory">更新</el-button>
</el-form-item>
</el-form>
</el-main>
</el-container>
</el-col>
</el-row>
</div>
</template>
<script>
import Selection from '@/components/Selection'
export default {
name: 'Category',
data () {
return {
action: this.$store.state.settings.baseURL + this.$store.state.settings.apiAdminPath + 'upImgFile',
myheader: { token: this.$store.state.user.token },
form: {
shop_id: '',
id: '',
pid: '',
path: '',
name: '',
sort: '',
show: false,
upFile: '',
oldFile: '',
desc: ''
},
categoryListData: [], //
winIsShow: false, //
winTitle: ''//
}
},
components: {
Selection
},
computed: {
shop_id () {
return this.form.shop_id
},
/**
* @description: 分类列表
*/
categoryList () {
return this.$store.state.categoryList
}
},
methods: {
/**
* @description: 构建分类树
*/
buildTree (inputArray) {
inputArray = inputArray.filter(item => item.shop_id === this.shop_id)//
const map = {}// id
const result = []//
//
inputArray.forEach(item => {
item.children = []// children
map[item.id] = item// id
})
//
inputArray.forEach(item => {
const parent = map[item.pid]//
if (parent) { // children
parent.children.push(item)
} else { //
result.push(item)
}
})
return result.filter(item => item.pid === '0')// pid'0'
},
/* 文件上传表单 */
handleUpSuccess (res) {
if (res.status === 0) {
this.$message.error(res.msg)
} else {
this.form.upFile = res.data
this.$message.success(res.msg)
}
},
beforeAvatarUpload (file) {
const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif'
if (!isJPG) {
this.$message.error('上传图片只能是JPG|PNG|GIF格式!')
}
return isJPG
},
handleUpErr () {
this.$message.error('接口访问失败')
},
//
setForm (data) {
if (data.desc == null) {
data.desc = ''
}
this.form.id = data.id
this.form.pid = data.pid
this.form.path = data.path
this.form.name = data.name
this.form.sort = data.sort
this.form.show = data.show === '1'
this.form.desc = data.desc
this.form.oldFile = data.bz_1
this.form.upFile = ''
if (Object.keys(data).length === 0) {
this.$message.warning('清空表单')
}
},
/**
* @description: 打开添加 编辑分类窗口
* @param {*} title 窗口标题
* @param {*} data 当前点击的分类属性
*/
openWin (title, data) {
this.winIsShow = true
this.winTitle = title
this.setForm(data)//
},
/**
* @description: 添加分类
*/
async addCategory () {
const res = await this.$store.dispatch('fetchAddCategory', this.form)
if (res.data.status === 1) {
this.winIsShow = false
}
},
/**
* @description: 更新分类
*/
async saveCategory () {
const res = await this.$store.dispatch('fetchSaveCategory', this.form)
if (res.data.status === 1) {
this.winIsShow = false
}
}
},
watch: {
/**
* @description: 拿到shop_id和分类列表 初始化分类树结构
*/
shop_id () {
this.categoryListData = this.buildTree(this.categoryList)
},
categoryList () {
this.categoryListData = this.buildTree(this.categoryList)
}
},
created () {
}
}
</script>
<style lang="scss" scoped>
@import "@/styles/theme.scss";
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
.hideColor {
color: $holdtext-color !important;
}
.el-upload__text {
line-height: 1.2em !important;
}
</style>

View File

@ -1,7 +1,7 @@
<template>
<div class="app-container">
<el-row class="m-t-0">
<el-col :span="24" class="p-r-5">
<el-col :span="24">
<el-container>
<el-header height="42px" class="l-h-42 p-l-10 p-r-10 border border-b-n">
<div class="l">
@ -12,14 +12,8 @@
</el-header>
<el-main class="border p-20">
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="所属客户">
<el-select v-model="form.shop_id" filterable placeholder="请选择,也可输入搜索">
<el-option v-for="item in adminList" :key="item.id" :label="item.uname" :value="item.shop_id">
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.uname
}}</span>
</el-option>
</el-select>
<el-form-item v-if="pageState === 'add'" label="所属商铺">
<Selection v-model="form.shop_id" :allSel="false" />
</el-form-item>
<el-form-item label="飞机名称">
<el-input v-model="form.name" placeholder="起名可以是中文" />
@ -56,6 +50,8 @@
</template>
<script>
import Selection from '@/components/Selection'
export default {
name: 'RegisterAdd',
data () {
@ -72,11 +68,10 @@ export default {
plane: null
}
},
components: {
Selection
},
computed: {
//
adminList () {
return this.$store.state.adminList
},
//
airList () {
return this.$store.state.airList

View File

@ -1,7 +1,7 @@
<template>
<div class="app-container">
<el-row class="m-t-0">
<el-col :span="24" class="p-r-5">
<el-col :span="24">
<el-container>
<el-header height="42px" class="l-h-42 p-l-10 p-r-10 border border-b-n">
<div class="l">
@ -14,20 +14,21 @@
<el-form-item label="物理ID">
<el-tag :type="macAdd === null ? 'danger' : ''">{{ macAdd === null ? 'NoThing' : macAdd }}</el-tag>
</el-form-item>
<el-form-item label="客户分配">
<el-form-item label="商铺分配">
<el-select v-model="shop_id" filterable placeholder="请选择" @blur="air_id = ''; disabled = true"
:disabled="macAdd === null ? true : false">
<el-option v-for="item in adminList" :key="item.id" :label="item.uname" :value="item.shop_id">
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.uname
}}</span>
<el-option v-for="item in shopList" :key="item.id" :label="item.name" :value="item.shop_id">
<el-avatar class="vm" shape="square" :size="25"
:src="$store.state.settings.host + '/Data/UploadFiles/logo/' + item.logo">
</el-avatar>
<span class="rspan">{{ item.name }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="飞机列表">
<el-radio-group v-if="airList.length != 0" v-model="air_id" @change="disabled = false;">
<el-radio class="m-b-10 m-l-0" v-for="item in airList" :key="item.id" :label="item.id" border>
<span></span>{{ item.name }}
{{ item.name }}
{{ item.macadd }}
</el-radio>
</el-radio-group>
@ -59,9 +60,9 @@ export default {
}
},
computed: {
//
adminList () {
return this.$store.state.adminList
//
shopList () {
return this.$store.state.shopList
},
//
airList () {
@ -109,4 +110,10 @@ export default {
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.rspan {
float: right;
color: #8492a6;
font-size: 13px
}
</style>

View File

@ -9,7 +9,7 @@
</el-button-group>
<!-- 用户select选项 -->
<el-button-group class="m-l-20">
<Selection v-model="form.shop_id" />
<Selection v-model="form.shop_id" :allSel="true" />
</el-button-group>
<!-- 飞机表格 -->
<el-table class="m-t-20 w-100" ref="myTable"
@ -55,7 +55,7 @@
</el-table>
<!-- 分页 -->
<el-pagination class="m-t-20" layout="prev, pager, next" :current-page.sync="currentPage" :page-size="pageSize"
:total="airList.length">
:total="airListArr.length">
</el-pagination>
</div>
</template>
@ -121,8 +121,6 @@ export default {
}
},
watch: {
airList () {
}
},
created () {
},

View File

@ -3,7 +3,7 @@
<map-box ref="mapbox">
<template #content>
<el-row class="w-40 m-t-20 m-l-20">
<el-col :span="24" class="p-r-5">
<el-col :span="24">
<el-container>
<el-header height="42px" class="l-h-42 p-l-10 p-r-10 border border-b-n">
<div class="l">
@ -14,15 +14,8 @@
</el-header>
<el-main class="border p-20 mainBox bg-white">
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="所属客户">
<el-select v-model="form.shop_id" filterable placeholder="请选择,也可输入搜索">
<el-option v-for="item in $store.state.adminList" :key="item.id" :label="item.uname"
:value="item.shop_id" :disabled="pageState == 'edit' ? true : false">
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.uname
}}</span>
</el-option>
</el-select>
<el-form-item v-if="pageState === 'add'" label="所属商铺">
<Selection v-model="form.shop_id" :allSel="false" />
</el-form-item>
<el-form-item label="航线标题">
<el-input v-model="form.name" placeholder="航线标题" />
@ -56,12 +49,13 @@
<script>
import MapBox from '@/components/MapBox'
import Selection from '@/components/Selection'
export default {
name: 'RouteAdd',
data () {
return {
action: this.$store.state.settings.baseURL + this.$store.state.settings.apiPath + 'upTxtFile',
action: this.$store.state.settings.baseURL + this.$store.state.settings.apiPlanePath + 'upTxtFile',
myheader: { token: this.$store.state.user.token },
form: {
shop_id: '',
@ -72,19 +66,15 @@ export default {
},
routeId: this.$route.params.id,
fileList: [],
pageState: ''//
pageState: '', //
route: null
}
},
components: {
MapBox
MapBox,
Selection
},
computed: {
/**
* @description: 获取管理员列表
*/
adminList () {
return this.$store.state.adminList
},
/**
* @description: 获取航线列表
*/

View File

@ -9,7 +9,7 @@
</el-button-group>
<!-- 用户select选项 -->
<el-button-group class="m-l-20">
<Selection v-model="form.shop_id" />
<Selection v-model="form.shop_id" :allSel="true" />
</el-button-group>
<!-- 航线表格 -->
<el-table class="m-t-20 w-100" ref="myTable"
@ -100,8 +100,6 @@ export default {
}
},
watch: {
routeList () {
}
},
created () {
},

View File

@ -1,27 +1,19 @@
<template>
<div class="app-container">
<el-row class="m-t-0">
<el-col :span="24" class="p-r-5">
<el-col :span="24">
<el-container>
<el-header height="42px" class="l-h-42 p-l-10 p-r-10 border border-b-n">
<div class="l">
<i v-if="pageState === 'add'" class="iconfont el-icon-plus f-s-20"></i>
<i v-else class="iconfont el-icon-edit f-s-20"></i>
<font class="m-l-10 f-s-18 fb">{{ $route.meta.title }}</font>
{{ form.bindroute }}
</div>
</el-header>
<el-main class="border p-20">
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="所属客户">
<el-select v-model="form.shop_id" filterable placeholder="请选择,也可输入搜索">
<el-option v-for="item in $store.state.adminList" :key="item.id" :label="item.uname"
:value="item.shop_id" :disabled="pageState == 'edit' ? true : false">
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.uname
}}</span>
</el-option>
</el-select>
<el-form-item v-if="pageState === 'add'" label="所属商铺">
<Selection v-model="form.shop_id" :allSel="false" />
</el-form-item>
<el-form-item label="站点名称">
<el-input v-model="form.sitename" placeholder="取餐站点的名字" />
@ -64,11 +56,13 @@
</template>
<script>
import Selection from '@/components/Selection'
export default {
name: 'SiteAdd',
data () {
return {
action: this.$store.state.settings.baseURL + this.$store.state.settings.apiPath + 'upImgFile',
action: this.$store.state.settings.baseURL + this.$store.state.settings.apiPlanePath + 'upImgFile',
myheader: { token: this.$store.state.user.token },
form: {
shop_id: '',
@ -80,9 +74,13 @@ export default {
},
siteId: this.$route.params.id,
pageState: '', //
site: null,
defaultQr: ''
}
},
components: {
Selection
},
computed: {
/**
* @description: 获取管理员列表

View File

@ -9,7 +9,7 @@
</el-button-group>
<!-- 用户select选项 -->
<el-button-group class="m-l-20">
<Selection v-model="form.shop_id" />
<Selection v-model="form.shop_id" :allSel="true" />
</el-button-group>
<!-- 站点表格 -->
<el-table class="m-t-20 w-100" ref="myTable"
@ -116,8 +116,6 @@ export default {
}
},
watch: {
siteList () {
}
},
created () {
},

View File

@ -2,36 +2,38 @@
<div>
<!-- logo -->
<div class="sidebar-logo-container" :class="{ 'collapse': isCollapse }">
<router-link v-if="isCollapse" key="isCollapse" class="sidebar-logo-link" to="/">
<img v-if="logo" src="@/assets/logo.png" class="sidebar-logo">
<h1 v-else class="sidebar-title">{{ title }}</h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo" src="@/assets/logo.png" class="sidebar-logo">
<div v-if="isCollapse" key="isCollapse" class="sidebar-logo-link" @click="isTap = !isTap">
<img :src="isTap ? require('@/assets/logo.svg') : require('@/assets/appletLogo.svg')" class="sidebar-logo">
</div>
<div v-else key="expand" class="sidebar-logo-link" @click="isTap = !isTap">
<img :src="isTap ? require('@/assets/logo.svg') : require('@/assets/appletLogo.svg')" class="sidebar-logo">
<h1 class="sidebar-title">{{ title }}</h1>
</router-link>
</div>
</div>
<!-- end logo -->
<!-- menu -->
<el-menu class="border-n" :router="true" :default-active="activeMenu" :unique-opened="true" background-color="#304156"
text-color="rgb(191, 203, 217)" active-text-color="#409EFF" :collapse-transition="false" :collapse="isCollapse">
<template v-for="(route, index) in routes">
<el-menu-item v-if="route.children.length < 2" :key="route.path" :index="route.children[0].path">
<i class="fc" :class="route.children[0].meta.icon"></i>
<span slot="title">{{ route.children[0].meta.title }}</span>
</el-menu-item>
<el-submenu v-else :key="index" :index="route.path">
<template slot="title">
<i class="fc" :class="route.meta.icon"></i>
<span>{{ route.meta.title }}</span>
</template>
<el-menu-item v-for="child in route.children" :key="child.path" :index="child.path">
<i class="fc" :class="child.meta.icon"></i>
<span>{{ child.meta.title }}</span>
<transition name="el-zoom-in-top">
<el-menu v-show="show" class="border-n" :router="true" :default-active="activeMenu" :unique-opened="true"
background-color="#304156" text-color="rgb(191, 203, 217)" active-text-color="#409EFF"
:collapse-transition="false" :collapse="isCollapse">
<template v-for="(route, index) in routes">
<el-menu-item v-if="route.children.length < 2" :key="route.path" :index="route.children[0].path">
<i class="fc" :class="route.children[0].meta.icon"></i>
<span slot="title">{{ route.children[0].meta.title }}</span>
</el-menu-item>
</el-submenu>
</template>
</el-menu>
<el-submenu v-else :key="index" :index="route.path">
<template slot="title">
<i class="fc" :class="route.meta.icon"></i>
<span>{{ route.meta.title }}</span>
</template>
<el-menu-item v-for="child in route.children" :key="child.path" :index="child.path">
<i class="fc" :class="child.meta.icon"></i>
<span>{{ child.meta.title }}</span>
</el-menu-item>
</el-submenu>
</template>
</el-menu>
</transition>
<!-- end menu -->
</div>
</template>
@ -42,7 +44,8 @@ export default {
data () {
return {
title: '无人机控制终端',
logo: '@/assets/logo.png'
isTap: true, //
show: true//
}
},
computed: {
@ -52,8 +55,10 @@ export default {
routes () {
const filterRoutes = (routes, userPower) => {
return routes.filter(item => {
const roles = item.roles || [] //
if (item.hidden === true || roles.indexOf(userPower) === -1) {
const roles = item.meta.roles || [] //
const tapName = this.isTap ? 'plane' : 'admin'
//
if (item.meta.hidden === true || roles.indexOf(userPower) === -1 || item.meta.tapName !== tapName) {
return false
}
if (item.children && item.children.length > 0) {
@ -96,15 +101,18 @@ export default {
/**
* @description: 动态加载路由
*/
loadRoute () {
loadRoute (planes) {
const arr = new Array(0)
this.airList.map((item, index) => {
planes.map((item, index) => {
arr[index] = {
path: '/planes/index/' + item.id + '/' + item.name,
name: 'Planes',
component: () => import('@/views/layout/components/main/planes/index.vue'),
meta: { title: item.name, icon: 'iconfont icon-wurenji' },
roles: ['admin', 'editor']
meta: {
title: item.name,
icon: 'iconfont icon-wurenji',
roles: ['admin', 'editor'],
tapName: 'plane'
}
}
})
this.routes.map((element) => {
@ -115,14 +123,28 @@ export default {
}
},
created () {
// tapName
this.isTap = this.$route.meta.tapName !== 'admin'
},
watch: {
/**
* @description: 监听飞机列表 个新刷新导航栏
* @description: 监听飞机列表 刷新导航栏
*/
airList () {
this.loadRoute()
airList (val) {
this.loadRoute(val)
this.$forceUpdate()//
},
isTap (val) {
if (val) {
this.title = '无人机控制终端'
} else {
this.title = '小程序后台管理'
}
//
this.show = false
setTimeout(() => {
this.show = true
}, 50)
}
}
}
@ -175,6 +197,7 @@ h1 {
& .sidebar-logo-link {
height: 100%;
width: 100%;
cursor: pointer;
& .sidebar-logo {
width: 24px;

View File

@ -49,18 +49,24 @@ export default {
},
airList () {
return this.$store.state.airList
},
shopList () {
return this.$store.state.shopList
}
},
created () {
},
mounted () {
},
created () {
/* init */
this.$store.commit('app/setIsMobile')//
this.$store.dispatch('fetchAirList')//
this.$store.dispatch('fetchShopList')//
this.$store.dispatch('fetchAdminList')//
this.$store.dispatch('fetchSiteList')//
this.$store.dispatch('fetchRouteList')// 线
this.$store.dispatch('fetchCategoryList')//
this.$store.dispatch('fetchProductList')//
this.$store.dispatch('fetchQuestList')// ps: 退
this.$store.dispatch('fetchAirList')//
},
watch: {
/**

View File

@ -30,7 +30,6 @@
</template>
<script>
import { login } from '@/utils/api/user'
export default {
name: 'Login',
data () {
@ -57,15 +56,11 @@ export default {
this.$refs.password.focus()
})
},
login,
/**
* @description:提交登陆
*/
handleLogin () {
login({
username: this.loginForm.username,
password: this.loginForm.password
})
this.$store.dispatch('user/fetchLogin', { username: this.loginForm.username, password: this.loginForm.password })
}
},
created () {