物资管理

This commit is contained in:
2025-11-19 09:27:30 +08:00
parent 53281cfaae
commit 25d0ea0e7c
5 changed files with 510 additions and 12 deletions

View File

@ -483,6 +483,7 @@ const importProject = () => {
console.log(arr, 'arrarr') console.log(arr, 'arrarr')
arr.pop() arr.pop()
// let path: any = 'C:/Users/Administrator/AppData/Roaming/yjearth' // let path: any = 'C:/Users/Administrator/AppData/Roaming/yjearth'
console.log(paths[0], arr.join('/'), 'pathpath')
unzip_file(paths[0], arr.join('/')) unzip_file(paths[0], arr.join('/'))
.then((res) => { .then((res) => {
// loadingInstance.close() // loadingInstance.close()

View File

@ -58,7 +58,7 @@
<el-table-column prop="password" label="密码" width="120" /> <el-table-column prop="password" label="密码" width="120" />
<el-table-column prop="channel" label="通道号" width="120" /> <el-table-column prop="channel" label="通道号" width="120" />
<el-table-column prop="flvUrl" label="flv地址" width="300" /> <el-table-column prop="flvUrl" label="flv地址" width="300" />
<el-table-column fixed="right" label="操作" min-width="140"> <el-table-column fixed="right" label="操作" min-width="160">
<template #default="scope"> <template #default="scope">
<el-button type="primary" size="small" @click="edit('编辑设备', scope.row)"> <el-button type="primary" size="small" @click="edit('编辑设备', scope.row)">
编辑 编辑

View File

@ -0,0 +1,463 @@
<template>
<Dialog
ref="baseDialog"
class="RoutePlanning"
title="路径规划"
left="180px"
top="100px"
width="527px"
:closeCallback="closeCallBack"
>
<template #content>
<div class="row">
<div class="col" style="flex: 0 0 66px">
<span class="label" style="color: rgba(var(--color-base1), 1)">起点</span>
</div>
<div class="col">
<span class="label">经度</span>
<input
class="input"
id="startLng"
type="number"
title=""
min="-180"
max="180"
@model="startLng"
v-model="startLng"
@change="changeStartLng"
@input="inputStartLng"
/>
</div>
<div class="col">
<span class="label">纬度</span>
<input
class="input"
id="startLat"
type="number"
title=""
min="-90"
max="90"
@model="startLat"
v-model="startLat"
@change="changeStartLat"
@input="inputStartLat"
/>
</div>
<div class="col" style="flex: 0 0 95px">
<button class="end-pick-btn" @click="pickStartPos" style="margin-left: 10px">拾取</button>
<svg-icon
name="posiFly"
class="icon"
:size="18"
style="margin: 5px"
title="定位"
></svg-icon>
</div>
</div>
<!-- 避让区域 -->
<div class="row" v-for="i in yieldNum" :key="i">
<div class="col" style="flex: 0 0 66px">
<span class="label">避让区域</span>
</div>
<div class="col">
<span style="font-size: 12px; color: rgba(204, 204, 204, 1)">请绘制避让区域范围</span>
</div>
<div class="col" style="flex: 0 0 95px">
<button class="end-pick-btn" style="margin-left: 10px">绘制</button>
<svg-icon name="posiFly" class="icon" :size="18" style="margin: 5px"></svg-icon>
<svg-icon
name="close"
class="icon"
style="margin-right: -12px"
:size="12"
@click="deleteYieldArea()"
></svg-icon>
</div>
</div>
<!-- 途径点 -->
<div class="row" v-for="i in crossNum" :key="i">
<div class="col" style="flex: 0 0 66px">
<svg-icon
name="crossPoint"
class="icon"
style="margin-left: -18px"
:size="12"
@click="deleteYieldArea()"
></svg-icon>
<span class="label">{{ '途径点' + i }}</span>
</div>
<div class="col">
<span class="label">经度</span>
<input
class="input"
id="endLng"
type="number"
title=""
min="-180"
max="180"
@model="endLng"
v-model="endLng"
@change="changeEndLng"
@input="inputEndLng"
/>
</div>
<div class="col">
<span class="label">纬度</span>
<input
class="input"
id="endLat"
type="number"
title=""
min="-180"
max="180"
@model="endLat"
v-model="endLat"
@change="changeEndLat"
@input="inputEndLat"
/>
</div>
<div class="col" style="flex: 0 0 95px">
<button class="end-pick-btn" @click="pickEndPos" style="margin-left: 10px">拾取</button>
<svg-icon name="posiFly" class="icon" :size="18" style="margin: 5px"></svg-icon>
<svg-icon
name="close"
class="icon"
style="margin-right: -12px"
:size="12"
@click="deleteCrossPoint()"
></svg-icon>
</div>
</div>
<div class="row">
<div class="col" style="flex: 0 0 66px">
<span class="label" style="color: rgba(var(--color-base1), 1)">终点</span>
</div>
<div class="col">
<span class="label">经度</span>
<input
class="input"
id="endLng"
type="number"
title=""
min="-180"
max="180"
@model="endLng"
v-model="endLng"
@change="changeEndLng"
@input="inputEndLng"
/>
</div>
<div class="col">
<span class="label">纬度</span>
<input
class="input"
id="endLat"
type="number"
title=""
min="-180"
max="180"
@model="endLat"
v-model="endLat"
@change="changeEndLat"
@input="inputEndLat"
/>
</div>
<div class="col" style="flex: 0 0 95px">
<button class="end-pick-btn" @click="pickEndPos" style="margin-left: 10px">拾取</button>
<svg-icon name="posiFly" class="icon" :size="18" style="margin: 5px"></svg-icon>
</div>
</div>
<div
class="row"
style="align-items: flex-start; display: flex; justify-content: space-between"
>
<div class="col start-col">
<button
class="crossPoint"
@mouseenter="svgHover[0] = true"
@mouseleave="svgHover[0] = false"
@click="addCrossPoint()"
>
<svg-icon
name="add"
:size="12"
:color="svgHover[0] ? 'rgba(0, 255, 255, 1)' : 'rgba(255, 255, 255, 1)'"
></svg-icon>
途径点
</button>
<button
class="crossPoint"
@mouseenter="svgHover[1] = true"
@mouseleave="svgHover[1] = false"
@click="addYieldArea()"
style="margin-left: 10px"
>
<svg-icon
name="add"
:size="12"
:color="svgHover[1] ? 'rgba(0, 255, 255, 1)' : 'rgba(255, 255, 255, 1)'"
></svg-icon
>避让区域
</button>
</div>
<button @clik="routeQuery">
<svg class="icon-query"><use xlink:href="#yj-icon-query"></use></svg>查询
</button>
</div>
<span class="custom-divider"></span>
<div class="row" style="margin-top: 20px">
<p class="lable-left-line">路径规划</p>
</div>
<!-- 路线 -->
<div class="row">
<div class="col">
<span class="label">{{ '路线' }}</span>
</div>
<div class="col">
<span class="label">{{ '52分钟' }}</span>
</div>
<div class="col">
<span class="label">{{ '50公里' }}</span>
</div>
<div class="col">
<span class="label">{{ '中间有路段维修' }}</span>
</div>
<div class="col">
<button class="end-pick-btn">保存</button>
</div>
</div>
</template>
<!-- <template #footer>
<button id="routeQuery" @clik="routeQuery">
<svg class="icon-query"><use xlink:href="#yj-icon-query"></use></svg>查询
</button>
<button id="clearRoute" @click="clearRoute">
<svg class="icon-route"><use xlink:href="#yj-icon-route"></use></svg>清除路线
</button>
<button @click="close">取消</button>
</template> -->
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive, onBeforeUnmount } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
import { RouteApi } from '@/api/route/index'
import { add } from 'date-fns'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
//避让区域
var yieldNum: any = ref(0)
const addYieldArea = () => {
console.log('addYieldArea')
yieldNum.value++
}
const deleteYieldArea = () => {
yieldNum.value > 0 ? yieldNum.value-- : (yieldNum.value = 0)
}
//途径点
var crossNum: any = ref(0)
const addCrossPoint = () => {
crossNum.value++
}
const deleteCrossPoint = () => {
crossNum.value > 0 ? crossNum.value-- : (crossNum.value = 0)
}
//属性
var startLng: any = ref(null)
var startLat: any = ref(null)
var endLng: any = ref(null)
var endLat: any = ref(null)
var routePlanning: any = reactive([])
var svgHover: any = reactive([false, false])
eventBus.on('routePlanningDialog', () => {
baseDialog.value?.open()
setTimeout(() => {
//加载路网数据
let host = 'http://192.168.110.25:8848'
routePlanning = new YJ.Obj.RoutePlanning(window.earth, {
gps: false,
host
})
routePlanning.Dialog.queryCallBack = async (v) => {
// await queryRoute(params, (response) => {
// if (response) {
// routePlanning.createRoute(response.list[0].positions)
// }
// })
let res = await RouteApi.queryRoute({
startLng: startLng.value,
startLat: startLat.value,
endLng: endLng.value,
endLat: endLat.value,
waypoints: []
})
if (res.code === 200) {
routePlanning.createRoute(res.data.pathPoints)
}
}
}, 100)
})
const open = () => {
baseDialog.value?.open()
setTimeout(() => {
//加载路网数据
let host = 'http://192.168.110.25:8848'
routePlanning = new YJ.Obj.RoutePlanning(window.earth, {
gps: false,
host
})
routePlanning.Dialog.queryCallBack = async (v) => {
// await queryRoute(params, (response) => {
// if (response) {
// routePlanning.createRoute(response.list[0].positions)
// }
// })
let res = await RouteApi.queryRoute({
startLng: startLng.value,
startLat: startLat.value,
endLng: endLng.value,
endLat: endLat.value,
waypoints: []
})
if (res.code === 200) {
routePlanning.createRoute(res.data.pathPoints)
}
}
}, 100)
}
//加载路网数据
const addRoute = async (fileId) => {
let res = await RouteApi.loadRoute({ fileId })
}
const getList = async () => {
let list = await RouteApi.getRouteList()
if (list.data.length > 0) {
let file = list.data[list.data.length - 1]
addRoute(file.id)
}
}
const closeCallBack = (e) => {
startLng.value = null
startLat.value = null
endLng.value = null
endLat.value = null
}
onBeforeUnmount(() => {
closeCallBack('')
})
const routeQuery = async (e) => {
let res = await RouteApi.queryRoute({
startLng: startLng.value,
startLat: startLat.value,
endLng: endLng.value,
endLat: endLat.value,
waypoints: []
})
}
const clearRoute = (e) => {}
const pickStartPos = () => {
routePlanning.pickStartPos((position) => {
startLng.value = position.lng
startLat.value = position.lat
})
}
const pickEndPos = () => {
routePlanning.pickEndPos((position) => {
endLng.value = position.lng
endLat.value = position.lat
})
}
const close = (e) => {
baseDialog.value?.close()
}
const changeStartLng = () => {
routePlanning.startLng = startLng.value
}
const inputStartLng = () => {
let dom: any = document.getElementById('startLng')
if (startLng.value < dom.min * 1) {
startLng.value = dom.min * 1
} else if (startLng.value > dom.max * 1) {
startLng.value = dom.max * 1
}
}
const changeStartLat = () => {
routePlanning.startLat = startLat.value
}
const inputStartLat = () => {
let dom: any = document.getElementById('startLat')
if (startLat.value < dom.min * 1) {
startLat.value = dom.min * 1
} else if (startLat.value > dom.max * 1) {
startLat.value = dom.max * 1
}
}
const changeEndLng = () => {
routePlanning.endLng = endLng.value
}
const inputEndLng = () => {
let dom: any = document.getElementById('endLng')
if (endLng.value < dom.min * 1) {
endLng.value = dom.min * 1
} else if (endLng.value > dom.max * 1) {
endLng.value = dom.max * 1
}
}
const changeEndLat = () => {
routePlanning.endLat = endLat.value
}
const inputEndLat = () => {
let dom: any = document.getElementById('endLat')
if (endLat.value < dom.min * 1) {
endLat.value = dom.min * 1
} else if (endLat.value > dom.max * 1) {
endLat.value = dom.max * 1
}
}
defineExpose({
open
})
</script>
<style scoped lang="scss">
#routeQuery {
position: absolute;
left: 10px;
display: flex;
}
#clearRoute {
position: absolute;
left: 95px;
display: flex;
}
.YJ-custom-base-dialog > .content .row > .col {
margin: 0 5px !important;
}
.crossPoint:hover {
color: rgba(var(--color-base1), 1);
}
.icon {
cursor: pointer;
}
</style>

View File

@ -10,32 +10,36 @@
<template #content> <template #content>
<el-form label-width="100px" :model="addForm" :rules="peopleRules" ref="peopleFormRef"> <el-form label-width="100px" :model="addForm" :rules="peopleRules" ref="peopleFormRef">
<el-form-item label="名称" prop="cameraName"> <el-form-item label="名称" prop="cameraName">
<el-input v-model="addForm.cameraName" clearable placeholder="请输入设备名称" /> <el-input v-model.trim="addForm.cameraName" clearable placeholder="请输入设备名称" />
</el-form-item> </el-form-item>
<el-form-item label="设备IP" prop="ip"> <el-form-item label="设备IP" prop="ip">
<el-input v-model="addForm.ip" clearable placeholder="请输入设备IP地址"></el-input> <el-input v-model.trim="addForm.ip" clearable placeholder="请输入设备IP地址"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="设备端口" prop="port"> <el-form-item label="设备端口" prop="port">
<el-input v-model="addForm.port" clearable placeholder="请输入设备端口"></el-input> <el-input v-model.trim="addForm.port" clearable placeholder="请输入设备端口"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="用户名" prop="username"> <el-form-item label="用户名" prop="username">
<el-input v-model="addForm.username" clearable placeholder="请输入用户名"></el-input> <el-input v-model.trim="addForm.username" clearable placeholder="请输入用户名"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="密码" prop="password"> <el-form-item label="密码" prop="password">
<el-input v-model="addForm.password" clearable placeholder="请输入密码"></el-input> <el-input v-model.trim="addForm.password" clearable placeholder="请输入密码"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="设备类型" prop="type"> <el-form-item label="设备类型" prop="type">
<el-select v-model="addForm.type" filterable placeholder="请选择设备类型"> <el-select v-model.trim="addForm.type" filterable placeholder="请选择设备类型">
<el-option label="海康" value="海康"> </el-option> <el-option label="海康" value="海康"> </el-option>
<el-option label="大华" value="大华"> </el-option> <el-option label="大华" value="大华"> </el-option>
<!-- <el-option label="手动录入" value="3"> </el-option> --> <!-- <el-option label="手动录入" value="3"> </el-option> -->
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item v-if="addForm.type === '3'" label="视频流地址" prop="flvUrl"> <el-form-item v-if="addForm.type === '3'" label="视频流地址" prop="flvUrl">
<el-input v-model="addForm.flvUrl" clearable placeholder="请输入视频流地址"></el-input> <el-input
v-model.trim="addForm.flvUrl"
clearable
placeholder="请输入视频流地址"
></el-input>
</el-form-item> </el-form-item>
<el-form-item label="通道号" prop="channel"> <el-form-item label="通道号" prop="channel">
<el-input v-model="addForm.channel" clearable placeholder="请输入通道号"></el-input> <el-input v-model.trim="addForm.channel" clearable placeholder="请输入通道号"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
@ -77,9 +81,38 @@ var addForm: any = ref({
const peopleRules: any = reactive({ const peopleRules: any = reactive({
cameraName: [{ required: true, message: '请输入名称', trigger: 'blur' }], cameraName: [{ required: true, message: '请输入名称', trigger: 'blur' }],
ip: [{ required: true, message: '请输入ip', trigger: 'blur' }], ip: [{ required: true, message: '请输入ip', trigger: 'blur' }],
port: [{ required: true, message: '请输入设备端口号', trigger: 'blur' }], port: [
{ required: true, message: '请输入设备端口号', trigger: 'blur' },
{
validator: (rule, value, callback) => {
if (!value) {
callback(new Error('请输入设备端口'))
return
}
const portNum = Number(value)
if (isNaN(portNum)) {
callback(new Error('端口号必须为数字'))
return
}
if (portNum < 1 || portNum > 65535) {
callback(new Error('端口号范围必须在1-65535之间'))
return
}
if (!Number.isInteger(portNum)) {
callback(new Error('端口号必须为整数'))
return
}
callback()
},
trigger: 'blur'
}
],
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }], username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
password: [{ required: true, message: '请channel', trigger: 'blur' }], password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
type: [{ required: true, message: '请选择设备类型', trigger: 'blur' }], type: [{ required: true, message: '请选择设备类型', trigger: 'blur' }],
channel: [{ required: true, message: '请输入通道号', trigger: 'blur' }] channel: [{ required: true, message: '请输入通道号', trigger: 'blur' }]
}) })

View File

@ -16,7 +16,7 @@
ref="peopleFormRef" ref="peopleFormRef"
> >
<el-form-item label="" prop="name"> <el-form-item label="" prop="name">
<el-input v-model="addForm.name" placeholder="请输入物资名称" clearable /> <el-input v-model.trim="addForm.name" placeholder="请输入物资名称" clearable />
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
@ -86,6 +86,7 @@ var submitProtal = () => {
}) })
} }
eventBus.on('openAddMaterial', (params) => { eventBus.on('openAddMaterial', (params) => {
console.log(params, 'iuiuuiuiu')
addTitle.value = params.title addTitle.value = params.title
if (addTitle.value != '添加物资') { if (addTitle.value != '添加物资') {
addForm.value.name = params.data.name addForm.value.name = params.data.name