新增车辆信息看板
This commit is contained in:
parent
e2e4c8c9b9
commit
e3ee9b3611
3
.env.dev
3
.env.dev
@ -4,8 +4,9 @@ NODE_ENV=production
|
||||
VITE_DEV=true
|
||||
|
||||
# 请求路径
|
||||
VITE_BASE_URL='http://192.168.0.74:48080'
|
||||
# VITE_BASE_URL='http://192.168.0.66:48080'
|
||||
# VITE_BASE_URL='http://192.168.0.189:48080'
|
||||
VITE_BASE_URL='http://192.168.0.74:48080'
|
||||
|
||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
||||
VITE_UPLOAD_TYPE=server
|
||||
|
@ -4,7 +4,7 @@ NODE_ENV=development
|
||||
VITE_DEV=true
|
||||
|
||||
# 请求路径
|
||||
VITE_BASE_URL='http://192.168.0.66:48080'
|
||||
VITE_BASE_URL='http://192.168.0.74:48080'
|
||||
# VITE_BASE_URL='http://192.168.0.189:48080'
|
||||
|
||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
|
||||
|
77
package-lock.json
generated
77
package-lock.json
generated
@ -51,9 +51,11 @@
|
||||
"qs": "^6.12.0",
|
||||
"sortablejs": "^1.15.3",
|
||||
"steady-xml": "^0.1.0",
|
||||
"swiper": "^8.4.7",
|
||||
"url": "^0.11.3",
|
||||
"video.js": "^7.21.5",
|
||||
"vue": "3.5.12",
|
||||
"vue-awesome-swiper": "^5.0.1",
|
||||
"vue-dompurify-html": "^4.1.4",
|
||||
"vue-i18n": "9.10.2",
|
||||
"vue-router": "4.4.5",
|
||||
@ -16573,6 +16575,42 @@
|
||||
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/swiper": {
|
||||
"version": "8.4.7",
|
||||
"resolved": "https://registry.npmmirror.com/swiper/-/swiper-8.4.7.tgz",
|
||||
"integrity": "sha512-VwO/KU3i9IV2Sf+W2NqyzwWob4yX9Qdedq6vBtS0rFqJ6Fa5iLUJwxQkuD4I38w0WDJwmFl8ojkdcRFPHWD+2g==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/swiperjs"
|
||||
},
|
||||
{
|
||||
"type": "open_collective",
|
||||
"url": "http://opencollective.com/swiper"
|
||||
}
|
||||
],
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"dom7": "^4.0.4",
|
||||
"ssr-window": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/swiper/node_modules/dom7": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/dom7/-/dom7-4.0.6.tgz",
|
||||
"integrity": "sha512-emjdpPLhpNubapLFdjNL9tP06Sr+GZkrIHEXLWvOGsytACUrkbeIdjO5g77m00BrHTznnlcNqgmn7pCN192TBA==",
|
||||
"dependencies": {
|
||||
"ssr-window": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/swiper/node_modules/ssr-window": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/ssr-window/-/ssr-window-4.0.2.tgz",
|
||||
"integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ=="
|
||||
},
|
||||
"node_modules/synckit": {
|
||||
"version": "0.8.8",
|
||||
"resolved": "https://registry.npmmirror.com/synckit/-/synckit-0.8.8.tgz",
|
||||
@ -17918,6 +17956,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vue-awesome-swiper": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/vue-awesome-swiper/-/vue-awesome-swiper-5.0.1.tgz",
|
||||
"integrity": "sha512-mWjFJzUqA4lG+DmsmibvMpoiBnl+IH2SSeiiQ3i5M0t1y9FknTxnGT0DsMb2YdJLgjYMEK3sYOWzqgLnZMH8Lg==",
|
||||
"peerDependencies": {
|
||||
"swiper": "^7.0.0 || ^8.0.0",
|
||||
"vue": "3.x"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-dompurify-html": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/vue-dompurify-html/-/vue-dompurify-html-4.1.4.tgz",
|
||||
@ -30293,6 +30340,30 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"swiper": {
|
||||
"version": "8.4.7",
|
||||
"resolved": "https://registry.npmmirror.com/swiper/-/swiper-8.4.7.tgz",
|
||||
"integrity": "sha512-VwO/KU3i9IV2Sf+W2NqyzwWob4yX9Qdedq6vBtS0rFqJ6Fa5iLUJwxQkuD4I38w0WDJwmFl8ojkdcRFPHWD+2g==",
|
||||
"requires": {
|
||||
"dom7": "^4.0.4",
|
||||
"ssr-window": "^4.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"dom7": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/dom7/-/dom7-4.0.6.tgz",
|
||||
"integrity": "sha512-emjdpPLhpNubapLFdjNL9tP06Sr+GZkrIHEXLWvOGsytACUrkbeIdjO5g77m00BrHTznnlcNqgmn7pCN192TBA==",
|
||||
"requires": {
|
||||
"ssr-window": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"ssr-window": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/ssr-window/-/ssr-window-4.0.2.tgz",
|
||||
"integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"synckit": {
|
||||
"version": "0.8.8",
|
||||
"resolved": "https://registry.npmmirror.com/synckit/-/synckit-0.8.8.tgz",
|
||||
@ -31306,6 +31377,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"vue-awesome-swiper": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/vue-awesome-swiper/-/vue-awesome-swiper-5.0.1.tgz",
|
||||
"integrity": "sha512-mWjFJzUqA4lG+DmsmibvMpoiBnl+IH2SSeiiQ3i5M0t1y9FknTxnGT0DsMb2YdJLgjYMEK3sYOWzqgLnZMH8Lg==",
|
||||
"requires": {}
|
||||
},
|
||||
"vue-dompurify-html": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/vue-dompurify-html/-/vue-dompurify-html-4.1.4.tgz",
|
||||
|
@ -67,9 +67,11 @@
|
||||
"qs": "^6.12.0",
|
||||
"sortablejs": "^1.15.3",
|
||||
"steady-xml": "^0.1.0",
|
||||
"swiper": "^8.4.7",
|
||||
"url": "^0.11.3",
|
||||
"video.js": "^7.21.5",
|
||||
"vue": "3.5.12",
|
||||
"vue-awesome-swiper": "^5.0.1",
|
||||
"vue-dompurify-html": "^4.1.4",
|
||||
"vue-i18n": "9.10.2",
|
||||
"vue-router": "4.4.5",
|
||||
|
46
src/api/car/index.ts
Normal file
46
src/api/car/index.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
//agv 下载
|
||||
export const agvDownload = async (params) => {
|
||||
return await request.download({ url: `/system/position-map/agvDownload`, params })
|
||||
}
|
||||
//点位地图列表
|
||||
export const getPositionMapList = async (params) => {
|
||||
return await request.get({ url: `/system/position-map/list`, params })
|
||||
}
|
||||
|
||||
//删除车辆信息
|
||||
export const deleteRobotInformation = async (id: number) => {
|
||||
return await request.delete({ url: `/system/robot/information/delete?id=` + id })
|
||||
}
|
||||
|
||||
//查询所有车辆
|
||||
export const getAllRobot = async (data) => {
|
||||
return await request.post({ url: `/system/robot/information/getAllRobot`, data })
|
||||
}
|
||||
|
||||
|
||||
//分页查询车辆列表 看板信息车辆目前用的是这个
|
||||
export const robotInformationPage = async (params) => {
|
||||
return await request.get({ url: `/system/robot/information/page`, params })
|
||||
}
|
||||
//统计车辆待命-任务中-离线
|
||||
export const robotInformationStatistics = async (data) => {
|
||||
return await request.post({ url: `/system/robot/information/statistics`, data })
|
||||
}
|
||||
|
||||
// 创建车辆信息
|
||||
export const robotInformationCreate = async (data) => {
|
||||
return await request.post({ url: `/system/robot/information/create`, data })
|
||||
}
|
||||
//分页查询车辆列表 看板信息车辆目前用的是这个
|
||||
export const robotGetAllModel = async (params) => {
|
||||
return await request.get({ url: `/system/robot/model/getAllModel`, params })
|
||||
}
|
||||
// 范围选择
|
||||
export const robotPositionGetMap = async (params) => {
|
||||
return await request.get({ url: `/system/position-map/getMap`, params })
|
||||
}
|
||||
|
||||
|
||||
|
BIN
src/assets/imgs/chache.jpg
Normal file
BIN
src/assets/imgs/chache.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
@ -44,10 +44,13 @@ import Logger from '@/utils/Logger'
|
||||
import VueDOMPurifyHTML from 'vue-dompurify-html' // 解决v-html 的安全隐患
|
||||
import VueDragResizeRotate from '@gausszhou/vue3-drag-resize-rotate'
|
||||
import '@gausszhou/vue3-drag-resize-rotate/lib/bundle.esm.css'
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
// 创建实例
|
||||
const setupAll = async () => {
|
||||
const app = createApp(App)
|
||||
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(key, component)
|
||||
}
|
||||
await setupI18n(app)
|
||||
|
||||
setupStore(app)
|
||||
@ -69,6 +72,7 @@ const setupAll = async () => {
|
||||
app.use(VueDOMPurifyHTML)
|
||||
app.use(VueDragResizeRotate)
|
||||
app.mount('#app')
|
||||
|
||||
}
|
||||
|
||||
setupAll()
|
||||
|
342
src/views/board/carBoard/createEditDialog.vue
Normal file
342
src/views/board/carBoard/createEditDialog.vue
Normal file
@ -0,0 +1,342 @@
|
||||
<template>
|
||||
<Dialog v-model="dialogVisible" :title="title" width="800" class="task-dialog">
|
||||
<el-form :model="formData" label-width="auto" ref="formRef" :rules="formRules">
|
||||
<el-form-item label="车辆类型" prop="robotModelId" required>
|
||||
<el-select v-model="formData.robotModelId" placeholder="请选择车辆类型" required>
|
||||
<el-option
|
||||
:label="item.robotModelNumber"
|
||||
:value="item.id"
|
||||
v-for="item in carModelList"
|
||||
:key="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item required label="车辆编号" prop="robotNo">
|
||||
<el-input v-model="formData.robotNo" :disabled="false" />
|
||||
</el-form-item>
|
||||
<el-form-item required label="自动充电电量" prop="taskNo">
|
||||
<el-input v-model="formData.taskNo" :disabled="false">
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item required label="Mac地址" prop="macAddress">
|
||||
<el-input v-model="formData.macAddress" :disabled="false" />
|
||||
</el-form-item>
|
||||
<el-form-item required label="选择范围" prop="macAddress">
|
||||
<el-cascader
|
||||
:options="options"
|
||||
:props="props"
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
import * as MapTaskAPi from '@/api/map/mapTask'
|
||||
import * as CarApi from '@/api/car/index'
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const title = ref('新建') // form表单
|
||||
const formData = ref({
|
||||
robotModelId: undefined, //车辆类型id
|
||||
robotNo: undefined, //AGV编号
|
||||
macAddress: undefined, //mac地址
|
||||
floorAreaJson: [],
|
||||
autoCharge: undefined
|
||||
})
|
||||
const carModelList = ref([])
|
||||
const floorAreaList = ref([])
|
||||
const props = { multiple: true }
|
||||
|
||||
const options = [
|
||||
{
|
||||
value: 1,
|
||||
label: 'Asia',
|
||||
children: [
|
||||
{
|
||||
value: 2,
|
||||
label: 'China',
|
||||
children: [
|
||||
{ value: 3, label: 'Beijing' },
|
||||
{ value: 4, label: 'Shanghai' },
|
||||
{ value: 5, label: 'Hangzhou' }
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 6,
|
||||
label: 'Japan',
|
||||
children: [
|
||||
{ value: 7, label: 'Tokyo' },
|
||||
{ value: 8, label: 'Osaka' },
|
||||
{ value: 9, label: 'Kyoto' }
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 10,
|
||||
label: 'Korea',
|
||||
children: [
|
||||
{ value: 11, label: 'Seoul' },
|
||||
{ value: 12, label: 'Busan' },
|
||||
{ value: 13, label: 'Taegu' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 14,
|
||||
label: 'Europe',
|
||||
children: [
|
||||
{
|
||||
value: 15,
|
||||
label: 'France',
|
||||
children: [
|
||||
{ value: 16, label: 'Paris' },
|
||||
{ value: 17, label: 'Marseille' },
|
||||
{ value: 18, label: 'Lyon' }
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 19,
|
||||
label: 'UK',
|
||||
children: [
|
||||
{ value: 20, label: 'London' },
|
||||
{ value: 21, label: 'Birmingham' },
|
||||
{ value: 22, label: 'Manchester' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 23,
|
||||
label: 'North America',
|
||||
children: [
|
||||
{
|
||||
value: 24,
|
||||
label: 'US',
|
||||
children: [
|
||||
{ value: 25, label: 'New York' },
|
||||
{ value: 26, label: 'Los Angeles' },
|
||||
{ value: 27, label: 'Washington' }
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 28,
|
||||
label: 'Canada',
|
||||
children: [
|
||||
{ value: 29, label: 'Toronto' },
|
||||
{ value: 30, label: 'Montreal' },
|
||||
{ value: 31, label: 'Ottawa' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
const getCarModelList = async () => {
|
||||
const res = await CarApi.robotGetAllModel()
|
||||
carModelList.value = res
|
||||
}
|
||||
|
||||
const getFloorArea = async () => {
|
||||
const res = await CarApi.robotPositionGetMap()
|
||||
floorAreaList.value = res
|
||||
}
|
||||
|
||||
const formRules = reactive({
|
||||
robotModelId: [{ required: true, message: '车辆类型不能为空', trigger: 'change' }],
|
||||
robotNo: [{ required: true, message: 'AGV编号不能为空', trigger: 'change' }],
|
||||
macAddress: [{ required: true, message: 'Mac地址不能为空', trigger: 'change' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type, id) => {
|
||||
getCarModelList()
|
||||
getFloorArea()
|
||||
dialogVisible.value = true
|
||||
resetForm()
|
||||
if (id) {
|
||||
title.value = '编辑'
|
||||
} else {
|
||||
title.value = '新建'
|
||||
}
|
||||
// getCanUseRobotList()
|
||||
// getTaskNo()
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
if (!formRef) return
|
||||
const valid = await formRef.value.validate()
|
||||
if (!valid) return
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
await MapTaskAPi.createTask(formData.value)
|
||||
message.success(t('common.createSuccess'))
|
||||
dialogVisible.value = false
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
//前往任务管理页面
|
||||
const { push } = useRouter()
|
||||
const taskManagement = () => {
|
||||
push({ name: 'taskManagementCreateTask' })
|
||||
}
|
||||
|
||||
//查询能用的车辆
|
||||
const robotList = ref([])
|
||||
const getCanUseRobotList = async () => {
|
||||
robotList.value = await MapTaskAPi.getCanUseRobot()
|
||||
}
|
||||
|
||||
//获取任务号
|
||||
const getTaskNo = async () => {
|
||||
formData.value.taskNo = await MapTaskAPi.getTaskNo()
|
||||
}
|
||||
|
||||
//获取取货位置可选的列表
|
||||
const getLocationList = async (type, locationNo) => {
|
||||
return await MapTaskAPi.getLocationByName({
|
||||
type, // 放货类型(1:库位、2:线库、 3:区域)
|
||||
locationNo
|
||||
})
|
||||
}
|
||||
//放货的选择列表
|
||||
const loading = ref(false)
|
||||
const releaseRemoteMethod = async (query, item) => {
|
||||
if (query) {
|
||||
loading.value = true
|
||||
item.releaseList = await getLocationList(item.releaseType, query)
|
||||
loading.value = false
|
||||
} else {
|
||||
item.releaseList = []
|
||||
}
|
||||
}
|
||||
//取货的选择列表
|
||||
const takeRemoteMethod = async (query, item) => {
|
||||
if (query) {
|
||||
item.takeList = await getLocationList(item.takeType, query)
|
||||
} else {
|
||||
item.takeList = []
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
montageTask: 0, //是否拼接任务(0:不拼接、1:拼接)
|
||||
montageNumber: 0, // 拼接任务数量
|
||||
taskDetailList: [
|
||||
{
|
||||
taskType: 1, //任务类型(1:取放货、2:停车、 3:充电、4:移动、5:仅取货、6:仅放货、7:扫描码、8:检测托盘类型)
|
||||
releaseType: 1, //放货类型 1:库位、2:线库、 3:区域
|
||||
takeType: 1, //取货类型(1:库位、2:线库、 3:区域)
|
||||
releaseId: undefined, //放货位置的id
|
||||
releaseList: [], //放货的名称的列表
|
||||
takeId: undefined, //取货位置的id
|
||||
takeList: [], //取货位置的名称列表
|
||||
robotNo: undefined, //AGV编号
|
||||
needLock: 0, //停车后锁定(0:否、1:是)
|
||||
electricity: undefined //所选车辆电量(充电模式)
|
||||
}
|
||||
], //任务列表
|
||||
skuInfo: undefined, //物料信息
|
||||
skuBatch: undefined, // 物料批次号
|
||||
skuNumber: undefined, // 物料数量
|
||||
priority: undefined, // 优先级
|
||||
otherMsg: undefined, // 其他信息
|
||||
doCycle: 0, //循环(0:不循环、1:循环)
|
||||
doMoveAll: 0, //是否搬空所选线库/区域(0:不搬空、1:搬空)
|
||||
cycleNumber: 0, // 其他信息
|
||||
remainingCycleNumber: 1, //剩余循环次数,默认1
|
||||
taskNo: undefined, // 任务号
|
||||
taskStatus: 0, //任务状态(0:未开始、1:执行中、2:已完成、3:已取消)
|
||||
taskStage: 0, //任务阶段(0:待执行、1:前往取货、2:取货中、3:运输中、4:放货中、5:结束)
|
||||
startTime: 0, //开始时间
|
||||
endTime: 0 //结束时间
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.task-dialog {
|
||||
.el-dialog__header {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
border-top: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.task-tips {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.el-select-dropdown__loading {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.circular {
|
||||
display: inline;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
animation: loading-rotate 2s linear infinite;
|
||||
}
|
||||
.path {
|
||||
animation: loading-dash 1.5s ease-in-out infinite;
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
stroke: var(--el-color-primary);
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
@keyframes loading-rotate {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes loading-dash {
|
||||
0% {
|
||||
stroke-dasharray: 1, 200;
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
50% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
}
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
@keyframes custom-spin-move {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
361
src/views/board/carBoard/index.vue
Normal file
361
src/views/board/carBoard/index.vue
Normal file
@ -0,0 +1,361 @@
|
||||
<template>
|
||||
<div class="">
|
||||
<ContentWrap>
|
||||
<div class="top-box">
|
||||
<el-button type="primary" @click="openForm('create')">新增车辆</el-button>
|
||||
<el-input v-model="queryParams.robotNo" style="width: 240px" placeholder="请输入关键字" clearable>
|
||||
<template #append> <el-button ><Icon icon="ep:search" @click="getCarList" /></el-button></template>
|
||||
</el-input>
|
||||
|
||||
</div>
|
||||
</ContentWrap>
|
||||
<ContentWrap>
|
||||
|
||||
|
||||
<div style="width: 100%">
|
||||
<!-- 大于等于4个数据 -->
|
||||
<div class="swiper-container" v-if="list.length>=4">
|
||||
<swiper
|
||||
:modules="modules"
|
||||
:loop="true"
|
||||
:slides-per-view="list.length > 4 ? 4 : list.length"
|
||||
:space-between="spaceBetween"
|
||||
:navigation="navigation"
|
||||
:pagination="{ clickable: true }"
|
||||
:scrollbar="{ draggable: true }"
|
||||
:direction="'horizontal'"
|
||||
class="swiperBox"
|
||||
>
|
||||
<!-- :autoplay="{ delay: 5000, disableOnInteraction: false }" -->
|
||||
<swiper-slide v-for="item in list" :key="item"
|
||||
>
|
||||
<div class="swiper-item-box">
|
||||
<div class="swiper-item-box-top">
|
||||
<el-button type="primary" size="small">地图定位</el-button>
|
||||
<div class="swiper-item-box-top-name"> {{ item.robotNo || '' }} </div>
|
||||
<div class="swiper-item-box-top-msg">
|
||||
<el-dropdown>
|
||||
<div style="flex-shrink: 0">
|
||||
<el-icon size="20px"><MoreFilled /></el-icon>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item>编辑</el-dropdown-item>
|
||||
<el-dropdown-item divided>解锁</el-dropdown-item>
|
||||
<el-dropdown-item>删除</el-dropdown-item>
|
||||
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="swiper-item-img-box">
|
||||
<img :src="item.url" alt="" class="swiper-item-img" />
|
||||
</div>
|
||||
|
||||
<div class="swiper-item-box-msg">
|
||||
<div class="swiper-item-box-msg-item">
|
||||
<div class="swiper-item-box-msg-item-left"> 电量 </div>
|
||||
<div class="swiper-item-box-msg-item-right" v-if="item.electricity"> {{ item.electricity || '' }} %</div>
|
||||
<div class="swiper-item-box-msg-item-right" v-else> 无电量数据</div>
|
||||
</div>
|
||||
<div class="swiper-item-box-msg-item">
|
||||
<div class="swiper-item-box-msg-item-left"> 状态 </div>
|
||||
<!-- 0:暂停且无任务、1:暂停(有处理中的任务)、2:任务中、3:待命 -->
|
||||
<div class="swiper-item-box-msg-item-right"> {{ item.status == 0? '暂停且无任务' : item.status == 1? '暂停(有处理中的任务)' : item.status == 2? '任务中' : '待命' }} </div>
|
||||
</div>
|
||||
<div class="swiper-item-box-msg-item">
|
||||
<div class="swiper-item-box-msg-item-left"> 楼层 </div>
|
||||
<div class="swiper-item-box-msg-item-right"> 1 </div>
|
||||
</div>
|
||||
<div class="swiper-item-box-msg-item">
|
||||
<div class="swiper-item-box-msg-item-left"> 区域 </div>
|
||||
<div class="swiper-item-box-msg-item-right"> A </div>
|
||||
</div>
|
||||
<div class="swiper-item-box-msg-item">
|
||||
<div class="swiper-item-box-msg-item-left"> 信息 </div>
|
||||
<div class="swiper-item-box-msg-item-right"> 车辆正在待命 </div>
|
||||
</div>
|
||||
<el-button type="primary" size="small" style="margin-top: 30px;">日志查看</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</swiper-slide>
|
||||
|
||||
<!-- 如果需要滚动条 -->
|
||||
<div class="swiper-scrollbar"></div>
|
||||
</swiper>
|
||||
<!--右箭头。如果放置在swiper外面,需要自定义样式。swiper-button-prev-->
|
||||
<div class="swiper-button-prev-custome" @click.stop="prevEl(item, index)">
|
||||
<el-icon size="40px"><CaretLeft /></el-icon>
|
||||
</div>
|
||||
<!--左箭头。如果放置在swiper外面,需要自定义样式。swiper-button-next-->
|
||||
<div class="swiper-button-next-custome" @click.stop="nextEl"> <el-icon size="40px"><CaretRight /></el-icon></div>
|
||||
</div>
|
||||
<!-- 不足四个数据的时候 -->
|
||||
<div v-else class="letter-data-box">
|
||||
<div class="letter-data-item" v-for="(item,index) in list" :key="index" :style="{marginRight: index % 4 == 3 ? '0' : '20px'}">
|
||||
<div class="swiper-item-box">
|
||||
<div class="swiper-item-box-top">
|
||||
<el-button type="primary" size="small">地图定位</el-button>
|
||||
<div class="swiper-item-box-top-name"> {{ item.robotNo || '' }} </div>
|
||||
<div class="swiper-item-box-top-msg">
|
||||
<el-dropdown>
|
||||
<div style="flex-shrink: 0">
|
||||
<el-icon size="20px"><MoreFilled /></el-icon>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item>编辑</el-dropdown-item>
|
||||
<el-dropdown-item divided>解锁</el-dropdown-item>
|
||||
<el-dropdown-item>删除</el-dropdown-item>
|
||||
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="swiper-item-img-box">
|
||||
<img :src="item.url" alt="" class="swiper-item-img" />
|
||||
</div>
|
||||
|
||||
<div class="swiper-item-box-msg">
|
||||
<div class="swiper-item-box-msg-item">
|
||||
<div class="swiper-item-box-msg-item-left"> 电量 </div>
|
||||
<div class="swiper-item-box-msg-item-right" v-if="item.electricity"> {{ item.electricity || '' }} %</div>
|
||||
<div class="swiper-item-box-msg-item-right" v-else> 无电量数据</div>
|
||||
</div>
|
||||
<div class="swiper-item-box-msg-item">
|
||||
<div class="swiper-item-box-msg-item-left"> 状态 </div>
|
||||
<!-- 0:暂停且无任务、1:暂停(有处理中的任务)、2:任务中、3:待命 -->
|
||||
<div class="swiper-item-box-msg-item-right"> {{ item.status == 0? '暂停且无任务' : item.status == 1? '暂停(有处理中的任务)' : item.status == 2? '任务中' : '待命' }} </div>
|
||||
</div>
|
||||
<div class="swiper-item-box-msg-item">
|
||||
<div class="swiper-item-box-msg-item-left"> 楼层 </div>
|
||||
<div class="swiper-item-box-msg-item-right"> {{ item.floor || '未知' }} </div>
|
||||
</div>
|
||||
<div class="swiper-item-box-msg-item">
|
||||
<div class="swiper-item-box-msg-item-left"> 区域 </div>
|
||||
<div class="swiper-item-box-msg-item-right"> {{ item.area || '未知' }} </div>
|
||||
</div>
|
||||
<div class="swiper-item-box-msg-item">
|
||||
<div class="swiper-item-box-msg-item-left"> 信息 </div>
|
||||
<div class="swiper-item-box-msg-item-right"> {{ item.msg || '' }} </div>
|
||||
</div>
|
||||
<el-button type="primary" size="small" style="margin-top: 30px;">日志查看</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 车辆统计 -->
|
||||
<div class="car-statistics-box" v-if="carStatistics">
|
||||
<!-- carStatistics -->
|
||||
<div class="car-statistics-item" style="color: #67C23A;border: 2px solid #67C23A;">
|
||||
<div class="car-statistics-item-name">
|
||||
待命中:
|
||||
</div>
|
||||
<div class="car-statistics-item-value">
|
||||
{{ carStatistics.standby || 0 }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="car-statistics-item" style="color: #E6A23C;border: 2px solid #E6A23C;">
|
||||
<div class="car-statistics-item-name">
|
||||
任务中:
|
||||
</div>
|
||||
<div class="car-statistics-item-value">
|
||||
{{ carStatistics.inTask || 0 }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="car-statistics-item" style="color: #409EFF;border: 2px solid #409EFF;">
|
||||
<div class="car-statistics-item-name">
|
||||
充电中:
|
||||
</div>
|
||||
<div class="car-statistics-item-value">
|
||||
{{ carStatistics.charge || 0 }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="car-statistics-item" style="color: #F56C6C;border: 2px solid #F56C6C;">
|
||||
<div class="car-statistics-item-name">
|
||||
离线:
|
||||
</div>
|
||||
<div class="car-statistics-item-value">
|
||||
{{ carStatistics.offline || 0 }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</ContentWrap>
|
||||
<createEditDialog ref="createEditDialogRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
defineOptions({ name: 'BoardCarBoard' })
|
||||
import * as CarApi from '@/api/car/index'
|
||||
import { Swiper, SwiperSlide } from 'swiper/vue'
|
||||
// 引入swiper样式(按需导入)
|
||||
import 'swiper/css/pagination' // 轮播图底面的小圆点
|
||||
import 'swiper/css/navigation' // 轮播图两边的左右箭头
|
||||
// import 'swiper/css/scrollbar' // 轮播图的滚动条, 轮播图里一般不怎么会使用到滚动条,如果有用到的话import导入就行
|
||||
// 引入swiper核心和所需模块
|
||||
import { Autoplay, Pagination, Navigation, Scrollbar } from 'swiper'
|
||||
import createEditDialog from './createEditDialog.vue'
|
||||
import 'swiper/css'
|
||||
const createEditDialogRef = ref(null)
|
||||
const list = ref([])
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 100,
|
||||
robotNo: undefined
|
||||
})
|
||||
const spaceBetween = ref(20)
|
||||
const navigation = ref({
|
||||
nextEl: '.swiper-button-next-custome',
|
||||
prevEl: '.swiper-button-prev-custome'
|
||||
})
|
||||
// 在modules加入要使用的模块
|
||||
const modules = [Autoplay, Navigation, Scrollbar]
|
||||
// Pagination
|
||||
const prevEl = (item, index) => {
|
||||
// console.log('上一张' + index + item)
|
||||
}
|
||||
const nextEl = () => {
|
||||
// console.log('下一张')
|
||||
}
|
||||
// 更改当前活动swiper
|
||||
const onSlideChange = (swiper) => {
|
||||
// swiper是当前轮播的对象,里面可以获取到当前swiper的所有信息,当前索引是activeIndex
|
||||
console.log(swiper.activeIndex)
|
||||
}
|
||||
//查询车辆列表
|
||||
const getCarList = async() => {
|
||||
let res = await CarApi.robotInformationPage(queryParams)
|
||||
// console.log(res.list)
|
||||
list.value = res.list
|
||||
}
|
||||
const carStatistics = ref(null)
|
||||
//查询车辆统计
|
||||
const getRobotInformationStatistics = async() => {
|
||||
let res = await CarApi.robotInformationStatistics({})
|
||||
console.log('车辆统计',res)
|
||||
carStatistics.value = res
|
||||
}
|
||||
const openForm = (type) => {
|
||||
createEditDialogRef.value.open(type)
|
||||
}
|
||||
onMounted(() => {
|
||||
getCarList()
|
||||
getRobotInformationStatistics()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.swiper-container {
|
||||
width: calc(100% - 60px);
|
||||
padding: 0 30px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
}
|
||||
.swiperBox {
|
||||
width: 100%;
|
||||
|
||||
/* background: rgba(0, 0, 0, 0.3); */
|
||||
}
|
||||
.swiper-item-box {
|
||||
width: 100%;
|
||||
padding-bottom: 30px;
|
||||
border: 1px solid #f5f5f5;
|
||||
}
|
||||
.swiper-item-img-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.swiper-item-img {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.swiper-item-box-top {
|
||||
width: calc(100% - 20px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 20px 0px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
.swiper-item-box-top-name {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.swiper-item-box-msg {
|
||||
width: calc(100% - 20px);
|
||||
padding: 0 10px;
|
||||
}
|
||||
.swiper-item-box-msg-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.swiper-item-box-msg-item-left {
|
||||
font-size: 13px;
|
||||
}
|
||||
.swiper-item-box-msg-item-right {
|
||||
font-size: 13px;
|
||||
margin-left: 40px;
|
||||
}
|
||||
:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
.swiper-button-prev-custome {
|
||||
position: absolute;
|
||||
left: -30px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
cursor: pointer;
|
||||
z-index: 999;
|
||||
}
|
||||
.swiper-button-next-custome {
|
||||
position: absolute;
|
||||
right: -30px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
cursor: pointer;
|
||||
z-index: 999;
|
||||
}
|
||||
.letter-data-box{
|
||||
width: calc(100% - 60px);
|
||||
padding: 0 30px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
.letter-data-item{
|
||||
width: calc(25% - 20px);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.car-statistics-box{
|
||||
width: 100%;
|
||||
margin-top: 40px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.car-statistics-item{
|
||||
width: calc(15% - 20px);
|
||||
padding: 0 10px;
|
||||
height: 60px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.top-box{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user