Compare commits
No commits in common. "4f2f9256a24411f2f8ac5b709f4be283c7cdda35" and "458564ba1a662d14bc2220b9462662a0c755d11c" have entirely different histories.
4f2f9256a2
...
458564ba1a
@ -30,11 +30,6 @@ export const updateTask = (data) => {
|
|||||||
return request.put({ url: '/system/robot/task/close', data })
|
return request.put({ url: '/system/robot/task/close', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
//更新优先级
|
|
||||||
export const updateRobotTask = (data) => {
|
|
||||||
return request.put({ url: '/system/robot/task/update', data })
|
|
||||||
}
|
|
||||||
|
|
||||||
//获得机器人任务主表分页
|
//获得机器人任务主表分页
|
||||||
export const getTaskPageList = async (data) => {
|
export const getTaskPageList = async (data) => {
|
||||||
return await request.post({ url: `/system/robot/task/page`, data })
|
return await request.post({ url: `/system/robot/task/page`, data })
|
||||||
|
@ -44,7 +44,7 @@ import VueDOMPurifyHTML from 'vue-dompurify-html' // 解决v-html 的安全隐
|
|||||||
import VueDragResizeRotate from '@gausszhou/vue3-drag-resize-rotate'
|
import VueDragResizeRotate from '@gausszhou/vue3-drag-resize-rotate'
|
||||||
import '@gausszhou/vue3-drag-resize-rotate/lib/bundle.esm.css'
|
import '@gausszhou/vue3-drag-resize-rotate/lib/bundle.esm.css'
|
||||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||||
import { vDrag } from './utils/drag'
|
import { vDrag } from './utils/drag';
|
||||||
// 创建实例
|
// 创建实例
|
||||||
const setupAll = async () => {
|
const setupAll = async () => {
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
@ -69,10 +69,11 @@ const setupAll = async () => {
|
|||||||
|
|
||||||
await router.isReady()
|
await router.isReady()
|
||||||
// 注册全局指令
|
// 注册全局指令
|
||||||
app.directive('drag', vDrag)
|
app.directive('drag', vDrag);
|
||||||
app.use(VueDOMPurifyHTML)
|
app.use(VueDOMPurifyHTML)
|
||||||
app.use(VueDragResizeRotate)
|
app.use(VueDragResizeRotate)
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setupAll()
|
setupAll()
|
||||||
|
@ -333,6 +333,7 @@
|
|||||||
>
|
>
|
||||||
<!-- 1 路径点 -->
|
<!-- 1 路径点 -->
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
|
class="box-item"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
:content="item.sortNum || '节点未保存'"
|
:content="item.sortNum || '节点未保存'"
|
||||||
placement="top"
|
placement="top"
|
||||||
@ -460,26 +461,18 @@
|
|||||||
:x2="Number(curve.endPointX)"
|
:x2="Number(curve.endPointX)"
|
||||||
:y2="Number(curve.endPointY)"
|
:y2="Number(curve.endPointY)"
|
||||||
:stroke="curve.isSelected ? '#f48924' : '#00329F'"
|
:stroke="curve.isSelected ? '#f48924' : '#00329F'"
|
||||||
stroke-width="3"
|
:marker-start="curve.direction === 2 ? 'url(#double-arrow-start)' : ''"
|
||||||
|
marker-end="url(#single-arrow)"
|
||||||
|
stroke-width="4"
|
||||||
@click="handleChooseRoute(curve, index)"
|
@click="handleChooseRoute(curve, index)"
|
||||||
@dblclick="handleEditRoute(curve, index)"
|
@dblclick="handleEditRoute(curve, index)"
|
||||||
/>
|
/>
|
||||||
<text
|
|
||||||
:x="(Number(curve.startPointX) + Number(curve.endPointX)) / 2"
|
|
||||||
:y="(Number(curve.startPointY) + Number(curve.endPointY) - 18) / 2"
|
|
||||||
font-size="11"
|
|
||||||
text-anchor="middle"
|
|
||||||
fill="black"
|
|
||||||
v-if="curve.isSelected"
|
|
||||||
>
|
|
||||||
{{ calculateRouteLength(curve) }}米
|
|
||||||
</text>
|
|
||||||
<path
|
<path
|
||||||
v-if="curve.isSelected"
|
v-if="curve.isSelected"
|
||||||
:d="getLineMidArrowPath(curve)"
|
:d="getLineMidArrowPath(curve)"
|
||||||
stroke="none"
|
stroke="none"
|
||||||
fill="black"
|
fill="black"
|
||||||
stroke-width="3"
|
stroke-width="4"
|
||||||
:marker-start="curve.direction === 2 ? 'url(#backward-arrow)' : ''"
|
:marker-start="curve.direction === 2 ? 'url(#backward-arrow)' : ''"
|
||||||
:marker-end="
|
:marker-end="
|
||||||
curve.direction === 2 ? 'url(#forward-arrow)' : 'url(#forward-arrow)'
|
curve.direction === 2 ? 'url(#forward-arrow)' : 'url(#forward-arrow)'
|
||||||
@ -489,31 +482,21 @@
|
|||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<path
|
<path
|
||||||
id="curvePath"
|
|
||||||
:d="getCurvePath(curve)"
|
:d="getCurvePath(curve)"
|
||||||
:stroke="curve.isSelected ? '#f48924' : '#00329F'"
|
:stroke="curve.isSelected ? '#f48924' : '#00329F'"
|
||||||
stroke-width="3"
|
stroke-width="4"
|
||||||
fill="none"
|
fill="none"
|
||||||
|
:marker-start="curve.direction === 2 ? 'url(#double-arrow-start)' : ''"
|
||||||
|
marker-end="url(#single-arrow)"
|
||||||
@click="handleChooseRoute(curve, index)"
|
@click="handleChooseRoute(curve, index)"
|
||||||
@dblclick="handleEditRoute(curve, index)"
|
@dblclick="handleEditRoute(curve, index)"
|
||||||
/>
|
/>
|
||||||
<!-- <text
|
|
||||||
:x="computedCurveTextX(curve)"
|
|
||||||
:y="computedCurveTextY(curve)"
|
|
||||||
font-size="12"
|
|
||||||
text-anchor="middle"
|
|
||||||
fill="black"
|
|
||||||
v-if="curve.isSelected"
|
|
||||||
>
|
|
||||||
{{ calculateRouteLength(curve) }}米
|
|
||||||
</text> -->
|
|
||||||
|
|
||||||
<path
|
<path
|
||||||
v-if="curve.isSelected"
|
v-if="curve.isSelected"
|
||||||
:d="getBezierMidArrowPath(curve)"
|
:d="getBezierMidArrowPath(curve)"
|
||||||
stroke="none"
|
stroke="none"
|
||||||
fill="black"
|
fill="black"
|
||||||
stroke-width="3"
|
stroke-width="4"
|
||||||
:marker-start="curve.direction === 2 ? 'url(#backward-arrow)' : ''"
|
:marker-start="curve.direction === 2 ? 'url(#backward-arrow)' : ''"
|
||||||
:marker-end="
|
:marker-end="
|
||||||
curve.direction === 2 ? 'url(#forward-arrow)' : 'url(#forward-arrow)'
|
curve.direction === 2 ? 'url(#forward-arrow)' : 'url(#forward-arrow)'
|
||||||
@ -928,7 +911,6 @@ const mapClick = (e) => {
|
|||||||
rotatable: false,
|
rotatable: false,
|
||||||
lockAspectRatio: false, //横纵比
|
lockAspectRatio: false, //横纵比
|
||||||
mapImageUrl: '',
|
mapImageUrl: '',
|
||||||
locationYaw: 0, //弧度
|
|
||||||
type: 1, //默认类型1 路径节点
|
type: 1, //默认类型1 路径节点
|
||||||
dataList: [], //存库位的
|
dataList: [], //存库位的
|
||||||
dataObj: {} //存 设备点 停车点 文字
|
dataObj: {} //存 设备点 停车点 文字
|
||||||
@ -1542,7 +1524,6 @@ const replicationNode = () => {
|
|||||||
lockAspectRatio: copyMapItem.lockAspectRatio,
|
lockAspectRatio: copyMapItem.lockAspectRatio,
|
||||||
layerSelectionShow: copyMapItem.layerSelectionShow,
|
layerSelectionShow: copyMapItem.layerSelectionShow,
|
||||||
mapImageUrl: copyMapItem.mapImageUrl,
|
mapImageUrl: copyMapItem.mapImageUrl,
|
||||||
locationYaw: copyMapItem.locationYaw,
|
|
||||||
areaId: null,
|
areaId: null,
|
||||||
locationNumber: copyMapItem.locationNumber || null
|
locationNumber: copyMapItem.locationNumber || null
|
||||||
}
|
}
|
||||||
@ -1663,8 +1644,7 @@ const markFormSubmit = async () => {
|
|||||||
mapImageUrl: '',
|
mapImageUrl: '',
|
||||||
type: 1, //默认类型1 路径节点
|
type: 1, //默认类型1 路径节点
|
||||||
dataList: [], //存库位的
|
dataList: [], //存库位的
|
||||||
dataObj: {}, //存 设备点 停车点 文字
|
dataObj: {} //存 设备点 停车点 文字
|
||||||
locationYaw: 0 //弧度
|
|
||||||
})
|
})
|
||||||
addEditHistory()
|
addEditHistory()
|
||||||
}
|
}
|
||||||
@ -2019,6 +1999,7 @@ const clickDrawSelectionArea = () => {
|
|||||||
item.actualLocationY = actualPoint.actualLocationY
|
item.actualLocationY = actualPoint.actualLocationY
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
console.log(state.allMapPointInfo)
|
||||||
state.mapRouteList.forEach((item) => {
|
state.mapRouteList.forEach((item) => {
|
||||||
if (idNameMap[item.startingPointId]) {
|
if (idNameMap[item.startingPointId]) {
|
||||||
let actualPoint = disposeEventPoint(
|
let actualPoint = disposeEventPoint(
|
||||||
@ -2046,54 +2027,41 @@ const clickDrawSelectionArea = () => {
|
|||||||
}
|
}
|
||||||
//将一个数组中的点位 按照第一个和最后一个排成一条直线
|
//将一个数组中的点位 按照第一个和最后一个排成一条直线
|
||||||
const mapPointsToLine = (points) => {
|
const mapPointsToLine = (points) => {
|
||||||
// 找出 locationX 最大和最小的项
|
if (points.length < 2) {
|
||||||
// let minXPoint = points[0]
|
return points
|
||||||
// let maxXPoint = points[0]
|
|
||||||
// points.forEach((point) => {
|
|
||||||
// if (point.locationX < minXPoint.locationX) {
|
|
||||||
// minXPoint = point
|
|
||||||
// }
|
|
||||||
// if (point.locationX > maxXPoint.locationX) {
|
|
||||||
// maxXPoint = point
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// 找出sortNum最小和最大的点
|
|
||||||
let minXPoint = points[0]
|
|
||||||
let maxXPoint = points[0]
|
|
||||||
for (let i = 1; i < points.length; i++) {
|
|
||||||
if (points[i].sortNum < minXPoint.sortNum) {
|
|
||||||
minXPoint = points[i]
|
|
||||||
}
|
|
||||||
if (points[i].sortNum > maxXPoint.sortNum) {
|
|
||||||
maxXPoint = points[i]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// 取数组的第一项和最后一项
|
||||||
|
const firstPoint = points[0]
|
||||||
|
const lastPoint = points[points.length - 1]
|
||||||
|
|
||||||
const dx = maxXPoint.locationX - minXPoint.locationX
|
// 计算直线的斜率
|
||||||
const dy = maxXPoint.locationY - minXPoint.locationY
|
const dx = lastPoint.locationX - firstPoint.locationX
|
||||||
|
const dy = lastPoint.locationY - firstPoint.locationY
|
||||||
|
|
||||||
// 处理垂直直线的情况
|
|
||||||
if (dx === 0) {
|
if (dx === 0) {
|
||||||
return points.map((point) => {
|
// 垂直直线的情况
|
||||||
if (point === minXPoint || point === maxXPoint) {
|
return points.map((point, index) => {
|
||||||
|
if (index === 0 || index === points.length - 1) {
|
||||||
return point
|
return point
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...point,
|
...point,
|
||||||
locationX: minXPoint.locationX
|
locationX: firstPoint.locationX,
|
||||||
|
locationY: point.locationY
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const slope = dy / dx
|
const slope = dy / dx
|
||||||
const intercept = minXPoint.locationY - slope * minXPoint.locationX
|
// 计算直线的截距
|
||||||
|
const intercept = firstPoint.locationY - slope * firstPoint.locationX
|
||||||
|
|
||||||
return points.map((point) => {
|
// 映射其他点到直线上
|
||||||
if (point === minXPoint || point === maxXPoint) {
|
return points.map((point, index) => {
|
||||||
|
if (index === 0 || index === points.length - 1) {
|
||||||
return point
|
return point
|
||||||
}
|
}
|
||||||
const newY = slope * point.locationX + intercept
|
const newY = slope * point.locationX + intercept
|
||||||
|
// 考虑精度问题,这里保留三位小数
|
||||||
return {
|
return {
|
||||||
...point,
|
...point,
|
||||||
locationY: newY
|
locationY: newY
|
||||||
@ -2280,14 +2248,6 @@ const computedLineWidth = computed(() => {
|
|||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
|
|
||||||
//计算路线的距离
|
|
||||||
const calculateRouteLength = (item) => {
|
|
||||||
const dx = item.startPointX - item.endPointX
|
|
||||||
const dy = item.startPointY - item.endPointY
|
|
||||||
const length = Math.sqrt(dx * dx + dy * dy) * Number(imgBgObj.resolution)
|
|
||||||
return length.toFixed(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理点击事件
|
// 处理点击事件
|
||||||
const measureDistancesClick = (event) => {
|
const measureDistancesClick = (event) => {
|
||||||
// 获取点击点相对于整个页面的坐标
|
// 获取点击点相对于整个页面的坐标
|
||||||
@ -2311,7 +2271,7 @@ const measureDistancesClick = (event) => {
|
|||||||
state.measureDistancesPoints[0],
|
state.measureDistancesPoints[0],
|
||||||
state.measureDistancesPoints[1]
|
state.measureDistancesPoints[1]
|
||||||
)
|
)
|
||||||
state.measureDistancesNum = distancesNum * Number(imgBgObj.resolution)
|
state.measureDistancesNum = distancesNum * 0.05
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2592,28 +2552,6 @@ const getBezierMidArrowPath = (item) => {
|
|||||||
return `M ${prevPoint.x} ${prevPoint.y} L ${midPoint.x} ${midPoint.y}`
|
return `M ${prevPoint.x} ${prevPoint.y} L ${midPoint.x} ${midPoint.y}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算贝塞尔曲线中间文字的 x 坐标
|
|
||||||
const computedCurveTextX = (item) => {
|
|
||||||
return (
|
|
||||||
(Number(item.startPointX) +
|
|
||||||
Number(item.beginControlX) +
|
|
||||||
Number(item.endControlX) +
|
|
||||||
Number(item.endPointX)) /
|
|
||||||
4
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算贝塞尔曲线中间文字的 y 坐标
|
|
||||||
const computedCurveTextY = (item) => {
|
|
||||||
return (
|
|
||||||
(Number(item.startPointY) +
|
|
||||||
Number(item.beginControlY) +
|
|
||||||
Number(item.endControlY) +
|
|
||||||
Number(item.endPointY)) /
|
|
||||||
4
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
document.onmousedown = function (e) {
|
document.onmousedown = function (e) {
|
||||||
//左击
|
//左击
|
||||||
if (e.button == 2) {
|
if (e.button == 2) {
|
||||||
|
@ -95,7 +95,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="方向" prop="direction" required>
|
<el-form-item label="方向" prop="direction" required>
|
||||||
<el-select v-model="form.direction" placeholder="请选择方向" @change="directionChange">
|
<el-select v-model="form.direction" placeholder="请选择方向">
|
||||||
<el-option label="单向" :value="1" />
|
<el-option label="单向" :value="1" />
|
||||||
<el-option label="双向" :value="2" />
|
<el-option label="双向" :value="2" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@ -174,12 +174,10 @@
|
|||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="车头朝向" prop="toward" required>
|
<el-form-item label="车头朝向" prop="toward" required>
|
||||||
<el-select v-model="form.toward" placeholder="请选择车头朝向">
|
<el-select v-model="form.toward" placeholder="请选择车头朝向">
|
||||||
<el-option
|
<el-option label="正正" :value="0" />
|
||||||
v-for="(item, index) in towardList"
|
<el-option label="正反" :value="1" />
|
||||||
:key="index"
|
<el-option label="反正" :value="2" />
|
||||||
:label="item.label"
|
<el-option label="反反" :value="3" />
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select> </el-form-item
|
</el-select> </el-form-item
|
||||||
></el-col>
|
></el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -235,13 +233,6 @@ const form = ref({
|
|||||||
const open = (item) => {
|
const open = (item) => {
|
||||||
dialogFormVisible.value = true
|
dialogFormVisible.value = true
|
||||||
form.value = item
|
form.value = item
|
||||||
if (form.value.direction == 1) {
|
|
||||||
//单向
|
|
||||||
towardList.value = unidirectional
|
|
||||||
} else {
|
|
||||||
//双向
|
|
||||||
towardList.value = bidirectional
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialogClose = () => {
|
const dialogClose = () => {
|
||||||
@ -301,47 +292,6 @@ const methodChange = (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//方向改变
|
|
||||||
const towardList = ref([])
|
|
||||||
const unidirectional = [
|
|
||||||
{
|
|
||||||
value: 0,
|
|
||||||
label: '正'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 1,
|
|
||||||
label: '反'
|
|
||||||
}
|
|
||||||
] //单向
|
|
||||||
const bidirectional = [
|
|
||||||
{
|
|
||||||
value: 0,
|
|
||||||
label: '正正'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 1,
|
|
||||||
label: '正反'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 2,
|
|
||||||
label: '反正'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 3,
|
|
||||||
label: '反反'
|
|
||||||
}
|
|
||||||
] //双向
|
|
||||||
const directionChange = (e) => {
|
|
||||||
form.value.toward = 0
|
|
||||||
if (e == 1) {
|
|
||||||
//单向
|
|
||||||
towardList.value = unidirectional
|
|
||||||
} else {
|
|
||||||
//双向
|
|
||||||
towardList.value = bidirectional
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//传入x y轴坐标
|
//传入x y轴坐标
|
||||||
const disposeEventPoint = (x, y) => {
|
const disposeEventPoint = (x, y) => {
|
||||||
const actualLocationX =
|
const actualLocationX =
|
||||||
|
@ -324,7 +324,6 @@
|
|||||||
:resizable="!state.prohibitedOperation && item.resizable"
|
:resizable="!state.prohibitedOperation && item.resizable"
|
||||||
:rotatable="!state.prohibitedOperation && item.rotatable"
|
:rotatable="!state.prohibitedOperation && item.rotatable"
|
||||||
:lock-aspect-ratio="item.lockAspectRatio"
|
:lock-aspect-ratio="item.lockAspectRatio"
|
||||||
:scaleRatio="state.imageChangeMultiple"
|
|
||||||
style="border: none; z-index: 999"
|
style="border: none; z-index: 999"
|
||||||
>
|
>
|
||||||
<!-- 节点合集 -->
|
<!-- 节点合集 -->
|
||||||
@ -422,7 +421,7 @@
|
|||||||
:x2="Number(state.currentDrawX)"
|
:x2="Number(state.currentDrawX)"
|
||||||
:y2="Number(state.currentDrawY)"
|
:y2="Number(state.currentDrawY)"
|
||||||
stroke="#00329F"
|
stroke="#00329F"
|
||||||
stroke-width="3"
|
stroke-width="4"
|
||||||
/>
|
/>
|
||||||
<template v-if="state.mapRouteList.length > 0">
|
<template v-if="state.mapRouteList.length > 0">
|
||||||
<template v-for="(curve, index) in state.mapRouteList" :key="index">
|
<template v-for="(curve, index) in state.mapRouteList" :key="index">
|
||||||
@ -461,26 +460,18 @@
|
|||||||
:x2="Number(curve.endPointX)"
|
:x2="Number(curve.endPointX)"
|
||||||
:y2="Number(curve.endPointY)"
|
:y2="Number(curve.endPointY)"
|
||||||
:stroke="curve.isSelected ? '#f48924' : '#00329F'"
|
:stroke="curve.isSelected ? '#f48924' : '#00329F'"
|
||||||
stroke-width="3"
|
:marker-start="curve.direction === 2 ? 'url(#double-arrow-start)' : ''"
|
||||||
|
marker-end="url(#single-arrow)"
|
||||||
|
stroke-width="4"
|
||||||
@click="handleChooseRoute(curve, index)"
|
@click="handleChooseRoute(curve, index)"
|
||||||
@dblclick="handleEditRoute(curve, index)"
|
@dblclick="handleEditRoute(curve, index)"
|
||||||
/>
|
/>
|
||||||
<text
|
|
||||||
:x="(Number(curve.startPointX) + Number(curve.endPointX)) / 2"
|
|
||||||
:y="(Number(curve.startPointY) + Number(curve.endPointY) - 18) / 2"
|
|
||||||
font-size="12"
|
|
||||||
text-anchor="middle"
|
|
||||||
fill="black"
|
|
||||||
v-if="curve.isSelected"
|
|
||||||
>
|
|
||||||
{{ calculateRouteLength(curve) }}米
|
|
||||||
</text>
|
|
||||||
<path
|
<path
|
||||||
v-if="curve.isSelected"
|
v-if="curve.isSelected"
|
||||||
:d="getLineMidArrowPath(curve)"
|
:d="getLineMidArrowPath(curve)"
|
||||||
stroke="none"
|
stroke="none"
|
||||||
fill="black"
|
fill="black"
|
||||||
stroke-width="3"
|
stroke-width="4"
|
||||||
:marker-start="curve.direction === 2 ? 'url(#backward-arrow)' : ''"
|
:marker-start="curve.direction === 2 ? 'url(#backward-arrow)' : ''"
|
||||||
:marker-end="
|
:marker-end="
|
||||||
curve.direction === 2 ? 'url(#forward-arrow)' : 'url(#forward-arrow)'
|
curve.direction === 2 ? 'url(#forward-arrow)' : 'url(#forward-arrow)'
|
||||||
@ -490,31 +481,21 @@
|
|||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<path
|
<path
|
||||||
id="curvePath"
|
|
||||||
:d="getCurvePath(curve)"
|
:d="getCurvePath(curve)"
|
||||||
:stroke="curve.isSelected ? '#f48924' : '#00329F'"
|
:stroke="curve.isSelected ? '#f48924' : '#00329F'"
|
||||||
stroke-width="3"
|
stroke-width="4"
|
||||||
fill="none"
|
fill="none"
|
||||||
|
:marker-start="curve.direction === 2 ? 'url(#double-arrow-start)' : ''"
|
||||||
|
marker-end="url(#single-arrow)"
|
||||||
@click="handleChooseRoute(curve, index)"
|
@click="handleChooseRoute(curve, index)"
|
||||||
@dblclick="handleEditRoute(curve, index)"
|
@dblclick="handleEditRoute(curve, index)"
|
||||||
/>
|
/>
|
||||||
<!-- <text
|
|
||||||
:x="computedCurveTextX(curve)"
|
|
||||||
:y="computedCurveTextY(curve)"
|
|
||||||
font-size="12"
|
|
||||||
text-anchor="middle"
|
|
||||||
fill="black"
|
|
||||||
v-if="curve.isSelected"
|
|
||||||
>
|
|
||||||
{{ calculateRouteLength(curve) }}米
|
|
||||||
</text> -->
|
|
||||||
|
|
||||||
<path
|
<path
|
||||||
v-if="curve.isSelected"
|
v-if="curve.isSelected"
|
||||||
:d="getBezierMidArrowPath(curve)"
|
:d="getBezierMidArrowPath(curve)"
|
||||||
stroke="none"
|
stroke="none"
|
||||||
fill="black"
|
fill="black"
|
||||||
stroke-width="3"
|
stroke-width="4"
|
||||||
:marker-start="curve.direction === 2 ? 'url(#backward-arrow)' : ''"
|
:marker-start="curve.direction === 2 ? 'url(#backward-arrow)' : ''"
|
||||||
:marker-end="
|
:marker-end="
|
||||||
curve.direction === 2 ? 'url(#forward-arrow)' : 'url(#forward-arrow)'
|
curve.direction === 2 ? 'url(#forward-arrow)' : 'url(#forward-arrow)'
|
||||||
@ -2281,14 +2262,6 @@ const computedLineWidth = computed(() => {
|
|||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
|
|
||||||
//计算路线的距离
|
|
||||||
const calculateRouteLength = (item) => {
|
|
||||||
const dx = item.startPointX - item.endPointX
|
|
||||||
const dy = item.startPointY - item.endPointY
|
|
||||||
const length = Math.sqrt(dx * dx + dy * dy) * Number(imgBgObj.resolution)
|
|
||||||
return length.toFixed(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理点击事件
|
// 处理点击事件
|
||||||
const measureDistancesClick = (event) => {
|
const measureDistancesClick = (event) => {
|
||||||
// 获取点击点相对于整个页面的坐标
|
// 获取点击点相对于整个页面的坐标
|
||||||
@ -2312,7 +2285,7 @@ const measureDistancesClick = (event) => {
|
|||||||
state.measureDistancesPoints[0],
|
state.measureDistancesPoints[0],
|
||||||
state.measureDistancesPoints[1]
|
state.measureDistancesPoints[1]
|
||||||
)
|
)
|
||||||
state.measureDistancesNum = distancesNum * Number(imgBgObj.resolution)
|
state.measureDistancesNum = distancesNum * 0.05
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2593,28 +2566,6 @@ const getBezierMidArrowPath = (item) => {
|
|||||||
return `M ${prevPoint.x} ${prevPoint.y} L ${midPoint.x} ${midPoint.y}`
|
return `M ${prevPoint.x} ${prevPoint.y} L ${midPoint.x} ${midPoint.y}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算贝塞尔曲线中间文字的 x 坐标
|
|
||||||
const computedCurveTextX = (item) => {
|
|
||||||
return (
|
|
||||||
(Number(item.startPointX) +
|
|
||||||
Number(item.beginControlX) +
|
|
||||||
Number(item.endControlX) +
|
|
||||||
Number(item.endPointX)) /
|
|
||||||
4
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算贝塞尔曲线中间文字的 y 坐标
|
|
||||||
const computedCurveTextY = (item) => {
|
|
||||||
return (
|
|
||||||
(Number(item.startPointY) +
|
|
||||||
Number(item.beginControlY) +
|
|
||||||
Number(item.endControlY) +
|
|
||||||
Number(item.endPointY)) /
|
|
||||||
4
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
document.onmousedown = function (e) {
|
document.onmousedown = function (e) {
|
||||||
//左击
|
//左击
|
||||||
if (e.button == 2) {
|
if (e.button == 2) {
|
||||||
|
@ -1,60 +1,130 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div
|
||||||
<button @click="scale *= 1.1">放大</button>
|
@mousedown="startSelection"
|
||||||
<button @click="scale /= 1.1">缩小</button>
|
@mousemove="updateSelection"
|
||||||
|
@mouseup="endSelection"
|
||||||
|
style="position: relative; width: 100vw; height: 100vh"
|
||||||
|
>
|
||||||
|
<!-- 绘制所有框选区域 -->
|
||||||
<div
|
<div
|
||||||
ref="containerRef"
|
v-for="(rect, index) in selectionRects"
|
||||||
:style="{ transform: `scale(${scale})` }"
|
:key="index"
|
||||||
@mousemove="handleMouseMove"
|
:style="{
|
||||||
class="scalable-container"
|
position: 'absolute',
|
||||||
>
|
left: `${rect.left}px`,
|
||||||
<div :style="{ left: `${mouseX}px`, top: `${mouseY}px` }" class="cursor"></div>
|
top: `${rect.top}px`,
|
||||||
</div>
|
width: `${rect.width}px`,
|
||||||
|
height: `${rect.height}px`,
|
||||||
|
backgroundColor: 'rgba(0, 0, 255, 0.2)',
|
||||||
|
border: '1px solid blue'
|
||||||
|
}"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<!-- 绘制点位 -->
|
||||||
|
<div
|
||||||
|
v-for="(point, index) in points"
|
||||||
|
:key="index"
|
||||||
|
:style="{
|
||||||
|
position: 'absolute',
|
||||||
|
left: `${point.x}px`,
|
||||||
|
top: `${point.y}px`,
|
||||||
|
width: '10px',
|
||||||
|
height: '10px',
|
||||||
|
backgroundColor: selectedPoints.includes(point) ? 'red' : 'green',
|
||||||
|
borderRadius: '50%'
|
||||||
|
}"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<!-- 确认按钮 -->
|
||||||
|
<button @click="confirmSelection" style="position: fixed; bottom: 20px; right: 20px">
|
||||||
|
确认
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const containerRef = ref(null)
|
export default {
|
||||||
const scale = ref(1)
|
setup() {
|
||||||
const mouseX = ref(0)
|
const points = ref([
|
||||||
const mouseY = ref(0)
|
{ x: 10, y: 10 },
|
||||||
|
{ x: 30, y: 100 },
|
||||||
|
{ x: 40, y: 40 },
|
||||||
|
{ x: 230, y: 400 },
|
||||||
|
{ x: 750, y: 640 }
|
||||||
|
])
|
||||||
|
|
||||||
const handleMouseMove = (event) => {
|
const isSelecting = ref(false)
|
||||||
const rect = containerRef.value.getBoundingClientRect()
|
const startPos = ref({ x: 0, y: 0 })
|
||||||
const offsetX = event.clientX - rect.left
|
const currentRect = ref({ left: 0, top: 0, width: 0, height: 0 })
|
||||||
const offsetY = event.clientY - rect.top
|
const selectionRects = ref([]) // 存储所有框选区域
|
||||||
|
const selectedPoints = ref([]) // 存储选中的点位
|
||||||
|
const selectedPointsInOrder = ref([]) // 按照框选顺序存储选中的点位
|
||||||
|
|
||||||
// 转换鼠标坐标
|
// 开始框选
|
||||||
mouseX.value = offsetX / scale.value
|
const startSelection = (event) => {
|
||||||
mouseY.value = offsetY / scale.value
|
isSelecting.value = true
|
||||||
|
startPos.value = { x: event.clientX, y: event.clientY }
|
||||||
|
currentRect.value = { left: event.clientX, top: event.clientY, width: 0, height: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新框选区域
|
||||||
|
const updateSelection = (event) => {
|
||||||
|
if (isSelecting.value) {
|
||||||
|
currentRect.value = {
|
||||||
|
left: Math.min(startPos.value.x, event.clientX),
|
||||||
|
top: Math.min(startPos.value.y, event.clientY),
|
||||||
|
width: Math.abs(event.clientX - startPos.value.x),
|
||||||
|
height: Math.abs(event.clientY - startPos.value.y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束框选
|
||||||
|
const endSelection = () => {
|
||||||
|
if (isSelecting.value) {
|
||||||
|
isSelecting.value = false
|
||||||
|
selectionRects.value.push({ ...currentRect.value }) // 保存当前框选区域
|
||||||
|
checkPointsInSelection(currentRect.value) // 检查当前框选区域内的点位
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查点位是否在框选区域内
|
||||||
|
const checkPointsInSelection = (rect) => {
|
||||||
|
points.value.forEach((point) => {
|
||||||
|
if (
|
||||||
|
point.x >= rect.left &&
|
||||||
|
point.x <= rect.left + rect.width &&
|
||||||
|
point.y >= rect.top &&
|
||||||
|
point.y <= rect.top + rect.height &&
|
||||||
|
!selectedPoints.value.includes(point) // 避免重复添加
|
||||||
|
) {
|
||||||
|
selectedPoints.value.push(point)
|
||||||
|
selectedPointsInOrder.value.push(point) // 按照框选顺序添加
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认选择
|
||||||
|
const confirmSelection = () => {
|
||||||
|
console.log('Selected Points in Order:', selectedPointsInOrder.value)
|
||||||
|
// 清除框选区域和选中的点位
|
||||||
|
selectionRects.value = []
|
||||||
|
selectedPoints.value = []
|
||||||
|
selectedPointsInOrder.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
points,
|
||||||
|
isSelecting,
|
||||||
|
selectionRects,
|
||||||
|
selectedPoints,
|
||||||
|
startSelection,
|
||||||
|
updateSelection,
|
||||||
|
endSelection,
|
||||||
|
confirmSelection
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 初始化鼠标位置
|
|
||||||
const rect = containerRef.value.getBoundingClientRect()
|
|
||||||
mouseX.value = rect.width / 2
|
|
||||||
mouseY.value = rect.height / 2
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.scalable-container {
|
|
||||||
position: relative;
|
|
||||||
width: 200px;
|
|
||||||
height: 200px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
margin-top: 20px;
|
|
||||||
transform-origin: top left;
|
|
||||||
transition: transform 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cursor {
|
|
||||||
position: absolute;
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
background-color: red;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@ -216,7 +216,7 @@ const message = useMessage() // 消息弹窗
|
|||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
const { push } = useRouter()
|
const { push } = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute();
|
||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const total = ref(0) // 列表的总页数
|
const total = ref(0) // 列表的总页数
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref([]) // 列表的数据
|
||||||
@ -309,7 +309,7 @@ const modifyPriority = (mainItem, item) => {
|
|||||||
}
|
}
|
||||||
const priorityNumChange = async (mainItem, item) => {
|
const priorityNumChange = async (mainItem, item) => {
|
||||||
try {
|
try {
|
||||||
await MapTaskAPi.updateRobotTask({
|
await MapTaskAPi.updateTask({
|
||||||
id: mainItem.id,
|
id: mainItem.id,
|
||||||
priority: priorityNum.value,
|
priority: priorityNum.value,
|
||||||
montageTask: mainItem.montageTask,
|
montageTask: mainItem.montageTask,
|
||||||
@ -338,19 +338,20 @@ const getCanUseRobotList = async () => {
|
|||||||
robotList.value = await MapTaskAPi.getCanUseRobot()
|
robotList.value = await MapTaskAPi.getCanUseRobot()
|
||||||
}
|
}
|
||||||
// 匹配对应的值
|
// 匹配对应的值
|
||||||
const findPropertyValue = (arr, targetValue, compareProp, returnProp) => {
|
const findPropertyValue = (arr, targetValue, compareProp, returnProp) =>{
|
||||||
for (let i = 0; i < arr.length; i++) {
|
for (let i = 0; i < arr.length; i++) {
|
||||||
if (arr[i][compareProp] === targetValue) {
|
if (arr[i][compareProp] === targetValue) {
|
||||||
return arr[i][returnProp]
|
return arr[i][returnProp];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return undefined;
|
||||||
return undefined
|
|
||||||
}
|
}
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (route.query.type) {
|
if(route.query.type){
|
||||||
let data = getIntDictOptions(DICT_TYPE.ROBOT_TASK_STATUS)
|
let data = getIntDictOptions(DICT_TYPE.ROBOT_TASK_STATUS)
|
||||||
queryParams.taskStatus = findPropertyValue(data, route.query.type, 'label', 'value')
|
queryParams.taskStatus = findPropertyValue(data, route.query.type, 'label', 'value')
|
||||||
|
|
||||||
}
|
}
|
||||||
getList()
|
getList()
|
||||||
getCanUseRobotList()
|
getCanUseRobotList()
|
||||||
|
Loading…
Reference in New Issue
Block a user