Browse Source

tijiao

master
肖正 4 months ago
parent
commit
0d504efa12
  1. 1
      .env.development
  2. 42
      src/api/m9.ts
  3. 2
      src/utils/request.ts
  4. 14
      src/views/health.vue
  5. 12
      src/views/home/index.vue
  6. BIN
      src/views/laboratory/img/AGV01.png
  7. BIN
      src/views/laboratory/img/AGV02.png
  8. BIN
      src/views/laboratory/img/M9.png
  9. BIN
      src/views/laboratory/img/SafetyCabinet.png
  10. BIN
      src/views/laboratory/img/centrifugal.png
  11. BIN
      src/views/laboratory/img/incubator.png
  12. BIN
      src/views/laboratory/img/lb.png
  13. BIN
      src/views/laboratory/img/lowerTheTemperature.png
  14. BIN
      src/views/laboratory/img/microscope.png
  15. BIN
      src/views/laboratory/img/platform.png
  16. BIN
      src/views/laboratory/img/transfer.png
  17. 29
      src/views/laboratory/index.vue
  18. 353
      src/views/laboratory/laboratory.vue
  19. 82
      src/views/m9/home.vue
  20. 237
      src/views/m9/index.vue
  21. 124
      src/views/system/mapManagement/index.vue
  22. BIN
      src/views/system/mapManagement/m9.png
  23. 3677
      yarn.lock

1
.env.development

@ -3,3 +3,4 @@ ENV = development
# 本地环境接口地址 # 本地环境接口地址
VITE_API_URL = http://localhost:5005 VITE_API_URL = http://localhost:5005
# VITE_API_URL = http://192.168.88.76:5005

42
src/api/m9.ts

@ -0,0 +1,42 @@
import request from '/@/utils/request';
export function getSummary() {
return request({
url: '/api/storage/summary',
method: 'get',
});
}
export function getModuleSummary(moduleId) {
return request({
url: `/api/storage/moduleSummary/${moduleId}`,
method: 'get',
});
}
export function getPropertyValue(params) {
return request({
url: `/api/storage/getPropertyValue/${params.moduleId}/${params.propertyName}`,
method: 'get',
});
}
export function setPropertyValue(params) {
return request({
url: `/api/storage/setPropertyValue/${params.moduleId}/${params.propertyName}`,
method: 'post',
data: params.value,
});
}
export function invokeMethod(params) {
return request({
url: `/api/storage/invokeMethod/${params.moduleId}/${params.methodName}`,
method: 'post',
data: params.value,
});
}
export function start() {
return request({
url: `/api/storage/start`,
method: 'post',
});
}

2
src/utils/request.ts

@ -5,7 +5,7 @@ import { Local, Session } from '/@/utils/storage';
// 配置新建一个 axios 实例 // 配置新建一个 axios 实例
export const service = axios.create({ export const service = axios.create({
baseURL: window.__env__.VITE_API_URL as any, baseURL: window.__env__.VITE_API_URL as any,
timeout: 50000, timeout: 1000,
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
}); });

14
src/views/health.vue

@ -0,0 +1,14 @@
<template>
<div class="home-box">
<iframe src="http://365.robot365.cn/#/monitorScreen/scada-1"
style="height: 100%;" frameborder="0"></iframe>
</div>
</template>
<script lang="ts" setup name="M9home">
</script>
<style scoped lang="scss">.home-box{
height: 100%;
}
</style>

12
src/views/home/index.vue

@ -17,7 +17,7 @@
</el-col> </el-col>
</el-row> --> </el-row> -->
<el-row :gutter="15" class="home-card-two mb15"> <el-row :gutter="15" class="home-card-two mb15">
<el-col :xs="24" :sm="14" :md="14" :lg="16" :xl="12"> <el-col :xs="24" :sm="13" :md="13" :lg="13" :xl="12">
<div class="home-card-item" style="height: 300px;"> <div class="home-card-item" style="height: 300px;">
<el-row style="height: 100%"> <el-row style="height: 100%">
<el-col :span="8"> <el-col :span="8">
@ -97,7 +97,7 @@
</el-carousel> </el-carousel>
</div> </div>
</el-col> </el-col>
<el-col :xs="24" :sm="10" :md="10" :lg="8" :xl="12" class="home-media"> <el-col :xs="24" :sm="11" :md="11" :lg="11" :xl="12" class="home-media">
<div class="home-card-item" style="height: 500px;"> <div class="home-card-item" style="height: 500px;">
<div class="home-card-item-title">机器人20</div> <div class="home-card-item-title">机器人20</div>
<div class="home-monitor" style="height: 60px;"> <div class="home-monitor" style="height: 60px;">
@ -114,11 +114,11 @@
</div> </div>
</div> </div>
<div class="agv"> <div class="agv">
<div class="item" style="width: 150px; height: 70px; top: -1px; left: 35%">原代培养平台</div> <!-- <div class="item" style="width: 150px; height: 70px; top: -1px; left: 35%">原代培养平台</div>
<div class="item" style="width: 80px; height: 60px; top: 20px; left: -1px">培养箱</div> <div class="item" style="width: 80px; height: 60px; top: 20px; left: -1px">培养箱</div>
<div class="item" style="width: 80px; height: 60px; top: 79px; left: -1px">安全柜</div> <div class="item" style="width: 80px; height: 60px; top: 79px; left: -1px">安全柜</div>
<div class="item" style="width: 80px; height: 60px; top: 138px; left: -1px">离心机</div> <div class="item" style="width: 80px; height: 60px; top: 138px; left: -1px">离心机</div>
<div class="item" style="width: 560px; height: 80px; bottom: -1px; left: -1px">接待区</div> <div class="item" style="width: 70%; height: 80px; bottom: -1px; left: -1px">接待区</div>
<div class="item" style="width: 80px; height: 40px; bottom: 50%; left: 45%">交接区</div> <div class="item" style="width: 80px; height: 40px; bottom: 50%; left: 45%">交接区</div>
<div class="item" style="width: 80px; height: 50px; right: -1px; top: 30px">标本库</div> <div class="item" style="width: 80px; height: 50px; right: -1px; top: 30px">标本库</div>
<div class="item" style="width: 80px; height: 50px; right: -1px; top: 79px"></div> <div class="item" style="width: 80px; height: 50px; right: -1px; top: 79px"></div>
@ -127,7 +127,8 @@
<div class="item" style="width: 80px; height: 50px; right: -1px; top: 226px"></div> <div class="item" style="width: 80px; height: 50px; right: -1px; top: 226px"></div>
<div class="item" style="width: 80px; height: 50px; right: -1px; top: 275px"></div> <div class="item" style="width: 80px; height: 50px; right: -1px; top: 275px"></div>
<img :src="carYellow" alt="" width="50px" height="50px" style="position: absolute; right: 85px; top: 48%"> <img :src="carYellow" alt="" width="50px" height="50px" style="position: absolute; right: 85px; top: 48%">
<img :src="carGreen" alt="" width="50px" height="50px" style="position: absolute; left: 85px; top: 40%"> <img :src="carGreen" alt="" width="50px" height="50px" style="position: absolute; left: 85px; top: 40%"> -->
<laboratory />
</div> </div>
<!-- <div style="height: 100%" ref="homePieRef"></div> --> <!-- <div style="height: 100%" ref="homePieRef"></div> -->
</div> </div>
@ -199,6 +200,7 @@ import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig'; import { useThemeConfig } from '/@/stores/themeConfig';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes'; import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { getAddInfo } from '/@/api/user'; import { getAddInfo } from '/@/api/user';
import laboratory from '../laboratory/laboratory.vue';
import imgUrl from '/@/assets/M9.png' import imgUrl from '/@/assets/M9.png'
import carYellow from '/@/assets/car_yellow.png' import carYellow from '/@/assets/car_yellow.png'
import carGreen from '/@/assets/car_green.png' import carGreen from '/@/assets/car_green.png'

BIN
src/views/laboratory/img/AGV01.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
src/views/laboratory/img/AGV02.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

BIN
src/views/laboratory/img/M9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
src/views/laboratory/img/SafetyCabinet.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

BIN
src/views/laboratory/img/centrifugal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

BIN
src/views/laboratory/img/incubator.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 KiB

BIN
src/views/laboratory/img/lb.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 MiB

BIN
src/views/laboratory/img/lowerTheTemperature.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1009 KiB

BIN
src/views/laboratory/img/microscope.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 KiB

BIN
src/views/laboratory/img/platform.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 KiB

BIN
src/views/laboratory/img/transfer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

29
src/views/laboratory/index.vue

@ -0,0 +1,29 @@
<template>
<el-card class="laboratory-container" title="实验室">
<template #header>
<div class="card-header">
<span>实验室</span>
</div>
</template>
<laboratory />
</el-card>
</template>
<script lang="ts" setup>
import laboratory from './laboratory.vue';
</script>
<style>
.laboratory-container .el-card__body {
height: 100%;
}
.el-popper.is-customized {
/* Set padding to ensure the height is 32px */
padding: 6px 12px;
background: linear-gradient(90deg, rgb(159, 229, 151), rgb(204, 229, 129));
}
.el-popper.is-customized .el-popper__arrow::before {
background: linear-gradient(45deg, #b2e68d, #bce689);
right: 0;
}
</style>

353
src/views/laboratory/laboratory.vue

@ -0,0 +1,353 @@
<template>
<div class="svg-box">
<!-- <img href="./img/m9.png" width="100%" height="100%" /> -->
<svg ref="svg" :width="width" :height="height">
<image
:x="0"
:y="0"
href="./img/lb.png"
:width="width"
/>
<!-- 定义椭圆轨道 -->
<!-- <ellipse
:cx="cx"
:cy="cy"
:rx="rx"
:ry="ry"
fill="none"
stroke="black"
/> -->
<!-- 定义图片 -->
<!-- <image
:x="position.x"
:y="position.y"
:transform="`rotate(${angle}, ${position.x + 20}, ${position.y + 20})`"
href="./img/AGV01.png"
width="40"
height="40"
/> -->
<polyline
:points="computedPoints1"
stroke="black"
fill="none"
stroke-dasharray="5,5"
/>
<polyline
:points="computedPoints2"
stroke="black"
fill="none"
stroke-dasharray="5,5"
/>
<polyline
:points="computedPoints3"
stroke="black"
fill="none"
stroke-dasharray="5,5"
/>
<polyline
:points="coAGVPoints1"
stroke="black"
fill="none"
stroke-dasharray="5,5"
/>
<polyline
:points="coAGVPoints2"
stroke="black"
fill="none"
stroke-dasharray="5,5"
/>
<polyline
:points="coAGVPoints3"
stroke="black"
fill="none"
stroke-dasharray="5,5"
/>
<polyline
:points="coAGVPoints4"
stroke="black"
fill="none"
stroke-dasharray="5,5"
/>
<polyline
:points="coAGVPoints5"
stroke="black"
fill="none"
stroke-dasharray="5,5"
/>
<polyline
:points="coAGVPoints6"
stroke="black"
fill="none"
stroke-dasharray="5,5"
/>
<polyline
:points="coAGVPoints7"
stroke="black"
fill="none"
stroke-dasharray="5,5"
/>
<image
ref="image"
href="./img/AGV02.png"
:x="imagePosition.x - 50"
:y="imagePosition.y - 50"
:width="100"
:height="100"
:transform="`rotate(${imageRotation}, ${imagePosition.x}, ${imagePosition.y})`"
/>
<image
ref="image"
href="./img/AGV01.png"
:x="imagePosition2.x - 50"
:y="imagePosition2.y - 50"
:width="100"
:height="100"
:transform="`rotate(${imageRotation2}, ${imagePosition2.x}, ${imagePosition2.y})`"
/>
</svg>
</div>
</template>
<script lang="ts" setup name="laboratory">
import { onMounted, reactive, computed, ref, onBeforeUnmount } from 'vue';
// import EditUser from '/@/views/system/user/component/editUser.vue';
import { ElMessage } from 'element-plus';
const width = ref(800);
const height = ref(600);
const svg = ref(null);
const deviceMsg = ref([
{name: 'M9_001', value: [
{name: '温度',}
]}
]);
const originalPoints1 = [
{ x: 200, y: 2700 },
{ x: 1500, y: 2700 },
{ x: 1500, y: 2000 },
{ x: 3000, y: 2000 }
];
const originalPoints2 = [
{ x: 3000, y: 2000 },
{ x: 1600, y: 2000 },
{ x: 1600, y: 1000 },
];
const originalPoints3 = [
{ x: 1600, y: 1000 },
{ x: 1600, y: 2700 },
{ x: 200, y: 2700 },
];
const originalPoints4 = [
{ x: 4040, y: 4300 },
{ x: 4040, y: 2000 },
{ x: 3400, y: 2000 }
];
const originalPoints5 = [
{ x: 4040, y: 4300 },
{ x: 4040, y: 3600 },
{ x: 5400, y: 3600 },
{ x: 5400, y: 3800 },
];
const originalPoints6 = [
{ x: 5400, y: 3800 },
{ x: 5400, y: 3600 },
{ x: 6000, y: 3600 },
{ x: 6000, y: 3900 },
];
const originalPoints7 = [
{ x: 6000, y: 3900 },
{ x: 6000, y: 3100 },
];
const originalPoints8 = [
{ x: 6000, y: 3100 },
{ x: 5500, y: 3100 },
{ x: 5500, y: 1600 },
{ x: 5700, y: 1600 },
];
const originalPoints9 = [
{ x: 5700, y: 1600 },
{ x: 4300, y: 1600 },
{ x: 4300, y: 2000 },
{ x: 3400, y: 2000 }
];
const originalPoints10 = [
{ x: 3400, y: 2000 },
{ x: 4040, y: 2000 },
{ x: 4040, y: 4300 },
];
const imagePosition = ref({ x: 0, y: 2700 });
const imageRotation = ref(0);
const imagePosition2 = ref({ x: 0, y: 2700 });
const imageRotation2 = ref(0);
// const pathIndex = ref(0);
// const paths = [originalPoints1, originalPoints2, originalPoints3];
const state = reactive({
loading: false,
angle: 0,
proportion: 4613/6921,
imgWidth: 6921,
imgHeight: 4613,
start1X: 0,
start1Y: 0,
end1X: 0,
end1Y: 0,
start2X: 0,
start2Y: 0,
end2X: 0,
end2Y: 0,
editUserTitle: '',
});
onBeforeUnmount(() => {
window.removeEventListener('resize', updateDimensions);
});
onMounted(async () => {
window.addEventListener('resize', updateDimensions);
updateDimensions(); // Initial resize to fit the container
init();
});
const updateDimensions = () => {
if (svg.value && svg.value.parentElement) {
width.value = svg.value.parentElement.clientWidth;
height.value = width.value* state.proportion;
}
};
const computedPoints1 = computed(() => {
return originalPoints1
.map(point => `${point.x * width.value / state.imgWidth},${point.y * height.value / state.imgHeight}`)
.join(' ');
});
const computedPoints2 = computed(() => {
return originalPoints2
.map(point => `${point.x * width.value / state.imgWidth},${point.y * height.value / state.imgHeight}`)
.join(' ');
});
const computedPoints3 = computed(() => {
return originalPoints3
.map(point => `${point.x * width.value / state.imgWidth},${point.y * height.value / state.imgHeight}`)
.join(' ');
});
const coAGVPoints1 = computed(() => {
return originalPoints4
.map(point => `${point.x * width.value / state.imgWidth},${point.y * height.value / state.imgHeight}`)
.join(' ');
});
const coAGVPoints2 = computed(() => {
return originalPoints5
.map(point => `${point.x * width.value / state.imgWidth},${point.y * height.value / state.imgHeight}`)
.join(' ');
});
const coAGVPoints3 = computed(() => {
return originalPoints6
.map(point => `${point.x * width.value / state.imgWidth},${point.y * height.value / state.imgHeight}`)
.join(' ');
});
const coAGVPoints4 = computed(() => {
return originalPoints7
.map(point => `${point.x * width.value / state.imgWidth},${point.y * height.value / state.imgHeight}`)
.join(' ');
});
const coAGVPoints5 = computed(() => {
return originalPoints8
.map(point => `${point.x * width.value / state.imgWidth},${point.y * height.value / state.imgHeight}`)
.join(' ');
});
const coAGVPoints6 = computed(() => {
return originalPoints9
.map(point => `${point.x * width.value / state.imgWidth},${point.y * height.value / state.imgHeight}`)
.join(' ');
});
const coAGVPoints7 = computed(() => {
return originalPoints10
.map(point => `${point.x * width.value / state.imgWidth},${point.y * height.value / state.imgHeight}`)
.join(' ');
});
// const coordinateTransformation = () => {}
const init = async () => {
animate(originalPoints1, 1);
animate(originalPoints4, 2);
await new Promise(resolve => setTimeout(resolve, 22000));
await animate(originalPoints2, 1);
await animate(originalPoints3, 1);
};
const animate = async (currentPath, type) => {
// const currentPath = paths[pathIndex.value];
const totalPoints = currentPath.length;
const AGV = type === 2 ? imagePosition2 : imagePosition;
const Rotation = type === 2 ? imageRotation2 : imageRotation;
var startX = type === 1 ? state.start1X : state.start2X;
let startY = type === 1 ? state.start1Y : state.start2Y;
let endX = type === 1 ? state.end1X : state.end2X;
let endY = type === 1 ? state.end1Y : state.end2Y
for (let i = 0; i < totalPoints - 1; i++) {
const startPoint = currentPath[i];
const endPoint = currentPath[i + 1];
startX = startPoint.x * width.value / state.imgWidth;
endX = endPoint.x * width.value / state.imgWidth;
startY = startPoint.y * height.value / state.imgHeight;
endY = endPoint.y * height.value / state.imgHeight;
if (i == 0) {
AGV.value.x = startX;
AGV.value.y = startY;
} else {
if (Math.abs(endX - startX) < 1) {
Rotation.value = startY > endY ? -90 : 90;
} else {
Rotation.value = startX > endX ? 180 : 0;
}
// await new Promise(resolve => setTimeout(resolve, 1000));
}
// const distance = Math.sqrt(
// Math.pow(endX - startX, 2) +
// Math.pow(endY - startY, 2)
// );
// const duration = distance / 100; // Adjust speed here
// const deltaX = (endX - startX) / duration;
// const deltaY = (endY - startY) / duration;
// const angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);
// console.log(999, duration)
// debugger
await animateItem(AGV, endX, endY, startX);
}
// await new Promise(resolve => setTimeout(resolve, 3000));
// pathIndex.value = (pathIndex.value + 1) % paths.length;
// animate();
};
const animateItem = async (AGV, endX, endY, startX) => {
let add = 0;
// debugger
if (Math.abs(endX - startX) < 1) {
add = AGV.value.y > endY ? -0.5 : 0.5;
// debugger;
if (Math.abs(AGV.value.y - endY) > 1) {
AGV.value.y+= add;
// requestAnimationFrame(animateItem)
await new Promise(resolve => setTimeout(resolve, 10));
await animateItem(AGV, endX, endY, startX);
}
} else {
add = AGV.value.x > endX ? -0.5 : 0.5;
if (Math.abs(AGV.value.x - endX) > 1) {
AGV.value.x+= add;
await new Promise(resolve => setTimeout(resolve, 10));
await animateItem(AGV, endX, endY, startX);
}
}
}
</script>
<style scoped lang="scss">
.svg-box {
height: 100%;
}
svg {
width: 100%;
height: 100%;
}
</style>

82
src/views/m9/home.vue

@ -0,0 +1,82 @@
<template>
<div class="home-box">
<el-form
ref="ruleFormRef"
label-width="auto"
class="demo-ruleForm"
style="max-width: 1000px;"
inline
status-icon
>
<el-divider content-position="left">状态</el-divider>
<el-form-item v-for="(item, i) in props.summary?.properties" :key="i" v-show="item.type !== 7"
:label="item.summary" style="width: 40%">
<div v-if="item.type === 1" style="width: 120px;">
<el-switch v-model="item.value" :disabled="!item.canWrite" /></div>
<el-input-number v-model="item.value" v-else :disabled="!item.canWrite"/>
</el-form-item>
<el-empty v-if="!props.summary?.properties?.length" image-size="80" description="暂无属性" />
<!-- <div v-if="!props.summary?.properties?.length" style="color: #909399;margin-left: 100px;">暂无属性</div> -->
<el-form-item>
<el-button type="primary" @click="onSubmit">提交修改</el-button>
</el-form-item>
</el-form>
<el-form
ref="ruleFormRef"
label-width="auto"
class="demo-ruleForm"
style="max-width: 1000px;"
inline
status-icon
>
<el-divider content-position="left">控制</el-divider>
<el-empty v-if="!props.summary?.properties?.length" image-size="80" description="暂无方法" />
<!-- <div v-if="!props.summary?.properties?.length" style="color: #909399;margin-left: 100px;">暂无方法</div> -->
<el-form-item v-for="(item, i) in props.summary?.methods" style="width: 40%;"
:label="item.summary + ': '" :key="i">
<el-button v-model="item.value" @click="clickMethod(item)"
v-if="!item.parameters || !item.parameters.length" type="primary">调用</el-button>
<el-switch v-model="item.value" @change="clickMethod(item)" v-else-if="item.type === 1" />
<el-input-number v-model="item.value" @change="clickMethod(item)" v-else />
</el-form-item>
</el-form>
</div>
</template>
<script lang="ts" setup name="M9home">
// import { setPropertyValue } from '/@/api/m9';
// import { ElMessage } from 'element-plus';
const props = defineProps({
title: String,
summary: {} as any,
});
const emits = defineEmits(['clickMethod', 'setProperty']);
const clickMethod = async (item) => {
emits('clickMethod', item);
}
function onSubmit() {
emits('setProperty');
console.log(props.summary?.properties)
}
</script>
<style scoped lang="scss">
.m9-home {
display: flex;
justify-content: space-between;
.home-box {
flex: 1;
}
.home-item {
width: 50%;
text-align: center;
&-title {
font-size: 16px;
color: #666;
}
&-value {
font-size: 20px;
}
}
}
</style>

237
src/views/m9/index.vue

@ -0,0 +1,237 @@
<template>
<div class="sys-user-container">
<el-row :gutter="5" style="width: 100%; flex: 1">
<el-col :span="4" :xs="24">
<el-card class="box-card" shadow="hover" style="height: 100%" body-style="height:100%; overflow:auto">
<div v-for="(item, i) in state.modules" :key="i" :class="current == i ? 'is-current':''"
class="el-tree-node__content" @click="nodeClick(i)">{{item?.description}}</div>
</el-card>
<!-- <OrgTree ref="orgTreeRef" @node-click="nodeClick" /> -->
</el-col>
<el-col :span="20" :xs="24" style="display: flex; flex-direction: column">
<el-card class="full-table" shadow="hover">
<template #header>
<div class="card-header">
<b>{{state.modules[current]?.description}}</b>
</div>
</template>
<div v-if="current === 0" class="m9-home">
<div style="flex: 1">
<img :src="imgUrl" alt="" style="margin-top: 5%;" width="90%">
</div>
<Home :summary="state.summary" @clickMethod="clickMethod" @setProperty="setProperty"></Home>
</div>
<Home v-else :summary="state.summary" @clickMethod="clickMethod" @setProperty="setProperty"></Home>
<!-- <div class="slider-demo-block" v-else>
<div style="width: 100%;position: relative;">
<el-slider v-model="value" :min="-10" @input="handleSliderInput" />
<div class="el-slider__marks">
<el-tooltip v-for="(item, i) in mark" :key="i" effect="customized" trigger="click">
<template #content>
<div>设置当前位置</div>
<el-input-number v-model="item.name" :min="-10" @change="inputChange"/>
<br/>
<el-button type="primary" style="margin-top: 5px;" size="small" @click="move(item.name)">移动到当前位置</el-button>
</template>
<div :style="{left: item.value}" class="el-slider__marks-text" >{{item.name}}</div>
</el-tooltip>
</div>
</div>
<el-input-number v-model="value" style="margin-left: 40px; width: 150px;" :min="-10" />
</div> -->
</el-card>
</el-col>
</el-row>
<!-- <EditUser ref="editUserRef" :title="state.editUserTitle" :orgData="state.orgTreeData" @handleQuery="handleQuery" /> -->
</div>
</template>
<script lang="ts" setup name="sysUser">
import { onMounted, reactive, ref } from 'vue';
// import EditUser from '/@/views/system/user/component/editUser.vue';
import Home from './home.vue';
import { ElMessage } from 'element-plus';
import { SysUser, SysOrg } from '/@/api-services/models';
import { getSummary, getPropertyValue, setPropertyValue, invokeMethod, getModuleSummary } from '/@/api/m9';
// import { Session } from '/@/utils/storage';
// import type { CSSProperties } from 'vue';
import imgUrl from '/@/assets/M9.png'
const current = ref<number>(0);
const state = reactive({
loading: false,
userData: [] as Array<SysUser>,
orgTreeData: [] as Array<SysOrg>,
modules: [],
queryParams: {
orgId: -1,
account: undefined,
realName: undefined,
phone: undefined,
},
summary: {
properties: []
},
tableParams: {
page: 1,
pageSize: 20,
total: 0 as any,
},
editUserTitle: '',
});
onMounted(async () => {
init()
});
const init = async () => {
state.loading = true;
// handleQuery();
// Bool = 1,
// Float = 2,
// UShort = 3,
// Int = 4,
// Double = 5,
// String = 6,
state.modules = [
{name: '', id: 0, description: '仪表盘'}
]
let res = await getSummary();
if (res.data.result && res.data.result.modules) {
state.modules = state.modules.concat(res.data.result.modules);
}
// if (res.data.result && res.data.result.summary) {
// state.summary = res.data.result.summary;
// }
await getSummaryValue(res.data.result?.summary);
state.loading = false;
}
const clickMethod = async (item) => {
state.loading = true;
await invokeMethod({moduleId: state.modules[current.value].id, methodName: item.name, value: item.value})
state.loading = false;
}
const setProperty = async () => {
let canSubmit = false;
for(let val of state.summary.properties || []) {
if (val.canWrite) {
canSubmit = true;
if (!val.value || val.value === 0)
continue;
setPropertyValue({moduleId: state.modules[current.value].id, propertyName: val.name, value: val.value})
}
}
if (!canSubmit) {
ElMessage.error("当前无可编辑的状态");
return
}
}
const getSummaryValue = async (summary) => {
// state.summary = [];
for (let val of summary.properties || []) {
try {
let res = await getPropertyValue({moduleId: state.modules[current.value].id, propertyName: val.name});
val.value = res.data.result;
} catch (e) {
console.log(e)
}
// state.summary.push(val);
}
console.log(888, summary)
state.summary = summary;
}
// const handleSliderInput = (value) => {
// if (marks.hasOwnProperty(value)) {
// handleMarkClick(value);
// } else {
// return false;
// }
// }
// const handleMarkClick = (value) => {
// console.log(`Mark at ${value}% clicked`);
// // marks
// // this.performAction(value);
// }
// //
// const handleQuery = async () => {
// state.loading = true;
// let params = Object.assign(state.queryParams, state.tableParams);
// var res = await getAPI(SysUserApi).apiSysUserPagePost(params);
// state.userData = res.data.result?.items ?? [];
// state.tableParams.total = res.data.result?.total;
// state.loading = false;
// };
// const inputChange = () => {
// };
// const move = (val) => {
// value.value = val;
// };
//
const nodeClick = async (i: number) => {
current.value = i;
if (i === 0) {
init();
return;
}
let res = await getModuleSummary(state.modules[i].id);
await getSummaryValue(res.data.result);
};
</script>
<style>
.el-popper.is-customized {
/* Set padding to ensure the height is 32px */
padding: 6px 12px;
background: linear-gradient(90deg, rgb(159, 229, 151), rgb(204, 229, 129));
}
.el-popper.is-customized .el-popper__arrow::before {
background: linear-gradient(45deg, #b2e68d, #bce689);
right: 0;
}
</style>
<style scoped lang="scss">
.m9-home {
display: flex;
justify-content: space-between;
}
.el-tree-node__content {
padding: 3px 10px;
}
.el-tree-node__content.is-current {
background: var(--el-color-primary-light-9);
font-weight: bold;
}
.slider-demo-block {
max-width: 600px;
display: flex;
align-items: center;
}
.el-slider__marks-text {
top: 9px;
cursor: pointer;
&:before {
display: block;
content: '';
width: 6px;
height: 6px;
border-radius: 50%;
background: red;
position: absolute;
top: -15px;
left: 50%;
transform: translateX(-3px);
}
}
</style>

124
src/views/system/mapManagement/index.vue

@ -21,17 +21,27 @@ import { onMounted, reactive, ref } from 'vue';
import Konva from 'konva'; import Konva from 'konva';
import { ElMessageBox, ElMessage } from 'element-plus'; import { ElMessageBox, ElMessage } from 'element-plus';
import mapData from './map/lab0522xiezuo(1).json'; import mapData from './map/lab0522xiezuo(1).json';
import agv from '../../laboratory/img/AGV01.png'
import m9 from './m9.png'
const state = reactive({ const state = reactive({
loading: false, loading: false,
advancedPointObj: {},
queryParams: { queryParams: {
name: undefined, name: undefined,
code: undefined, code: undefined,
}, },
m9: {
x: -6.037,
y: 10,
width: 11,
height: 3,
src: m9
},
}); });
const mapCanvas = reactive<Record<string, any>>({ const mapCanvas = reactive<Record<string, any>>({
// JSON // JSON
mapData: {}, mapData: {} as any,
// agvImg: require('@/assets/agv.png'), agvImg: agv,
// //
circle: null, circle: null,
allGroup: [], allGroup: [],
@ -72,13 +82,24 @@ const draw = () => {
for (let i = 0; i < normalPosList.length; i += 3) { for (let i = 0; i < normalPosList.length; i += 3) {
const x = normalPosList[i].x * mapCanvas.widthScale; const x = normalPosList[i].x * mapCanvas.widthScale;
const y = normalPosList[i].y * mapCanvas.heightScale; const y = normalPosList[i].y * mapCanvas.heightScale;
const circle = drawCircle(x, y, 2, '#D5D8DC'); const circle = drawCircle(x, y, 1, 'red');
mapCanvas.layer.add(circle); mapCanvas.layer.add(circle);
} }
} }
// var image = new Konva.Image({
// x: 200,
// y: 50,
// image: mapCanvas.agvImg,
// width: 100,
// height: 100
// });
// mapCanvas.layer.add(image);
// //
// console.log(888, advancedPointList)
state.advancedPointObj = {};
for (let i = 0; i < advancedPointList.length; i++) { for (let i = 0; i < advancedPointList.length; i++) {
const list = advancedPointList[i]; const list = advancedPointList[i];
state.advancedPointObj[list.instanceName] = list;
// mapCanvas.tableData[0].Interference.push({ name: list.instanceName, type: 'allGroup', i }); // mapCanvas.tableData[0].Interference.push({ name: list.instanceName, type: 'allGroup', i });
const x = list.pos.x * mapCanvas.widthScale; const x = list.pos.x * mapCanvas.widthScale;
const y = list.pos.y * mapCanvas.heightScale; const y = list.pos.y * mapCanvas.heightScale;
@ -87,7 +108,7 @@ const draw = () => {
if (list.dir) list.dir = parseFloat(list.dir).toFixed(3); if (list.dir) list.dir = parseFloat(list.dir).toFixed(3);
let rotation = (list.dir / Math.PI) * 180; let rotation = (list.dir / Math.PI) * 180;
rotation = isNaN(rotation) ? 0 : rotation; rotation = isNaN(rotation) ? 0 : rotation;
const color = list?.enable ? '#c5b8af' : '#1ABC9C'; const color = list?.enable ? 'blue' : '#303133';
const width = 50; const width = 50;
const height = 37; const height = 37;
mapCanvas.rect = new Konva.Rect({ mapCanvas.rect = new Konva.Rect({
@ -123,11 +144,97 @@ const draw = () => {
mapCanvas.allGroup.push(group); mapCanvas.allGroup.push(group);
mapCanvas.layer.add(group); mapCanvas.layer.add(group);
} }
console.log(888, state.advancedPointObj)
var coAgv = new Image();
coAgv.src = mapCanvas.agvImg;
coAgv.onload = function () {
let list = state.advancedPointObj.LM7;
if (list.dir) list.dir = parseFloat(list.dir).toFixed(3);
console.log(9999, list.pos?.x * mapCanvas.widthScale, list.pos?.y * mapCanvas.heightScale)
let rotation = (list.dir / Math.PI) * 180;
var kImage = new Konva.Image({
image:coAgv,
x: list.pos?.x * mapCanvas.widthScale,
y: list.pos?.y * mapCanvas.heightScale,
width: 100,
height: 100,
rotation,
offset: { x: 50, y: 50},
});
console.log(999, kImage)
//
mapCanvas.layer.add(kImage);
var velocity = 5;
var arr = ['LM13', 'LM12', 'LM15'];
let i = 0;
var anim = new Konva.Animation(function (frame) {
// ms -->s
var timeDiff = frame.timeDiff /1000;//
let now = state.advancedPointObj[arr[i]];
if (!now) return false;
let distX = now.pos.x - kImage.getAttr('x');
let distY = now.pos.y - kImage.getAttr('y');
if (Math.abs(distX) < 0.5 && Math.abs(distY) < 0.5) {
i++;
if (i >= arr.length) i = 0;
}
var dist = timeDiff * velocity;
console.log(9999, kImage.getAttr('x'))
kImage.move({x: distX > 0 ? dist : (dist * -1), y: distY > 0 ? dist : (dist * -1)});
}, mapCanvas.layer);
//
anim.start();
}
// Konva.Image.fromURL(mapCanvas.agvImg, function(darthNode) {
// let list = state.advancedPointObj.LM1;
// if (list.dir) list.dir = parseFloat(list.dir).toFixed(3);
// let rotation = (list.dir / Math.PI) * 180;
// darthNode.setAttrs({
// x: list.pos?.x * mapCanvas.widthScale,
// y: list.pos?.y * mapCanvas.heightScale,
// width: 100,
// height: 100,
// rotation,
// offset: { x: 50, y: 50},
// });
// mapCanvas.layer.add(darthNode);
// mapCanvas.layer.batchDraw();
// });
var img = new Image();
img.src = state.m9.src;
img.onload = function () {
var kImage = new Konva.Image({
image:img,
x: state.m9.x * mapCanvas.widthScale,
y: state.m9.y * mapCanvas.heightScale,
width: state.m9.width * mapCanvas.widthScale,
height: state.m9.height * mapCanvas.heightScale,
scale: {x:1, y: -1}
});
//
mapCanvas.layer.add(kImage);
}
// Konva.Image.fromURL(state.m9.src, function(darthNode) {
// mapCanvas.layer.add(darthNode);
// darthNode.setAttrs({
// x: state.m9.x * mapCanvas.widthScale,
// y: state.m9.y * mapCanvas.heightScale,
// width: state.m9.width,
// height: state.m9.height,
// // rotation: 180,
// // offset: { x: 50, y: 50},
// });
// mapCanvas.layer.add(darthNode);
// mapCanvas.layer.draw();
// });
// 线 线 // 线 线
for (let i = 0; i < advancedCurveList.length; i += 2) { for (let i = 0; i < advancedCurveList.length; i += 2) {
const list = advancedCurveList[i]; const list = advancedCurveList[i];
const color = list?.enable ? '#c5b8af' : '#2C3E50'; const color = list?.enable ? '#c5b8af' : '#E6A23C';
// mapCanvas.tableData[1].Interference.push({ name: list.instanceName, type: 'bezier', i: i / 2 }); // mapCanvas.tableData[1].Interference.push({ name: list.instanceName, type: 'bezier', i: i / 2 });
let arr = []; let arr = [];
arr[i] = {}; arr[i] = {};
@ -452,10 +559,13 @@ const resetMap = () => {
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: #faf9f6; background-color: #000;
background-image: linear-gradient(to right, #222 1px, transparent 1px),
linear-gradient(to bottom, #222 1px, transparent 1px);
background-size: 20px 20px; /* 网格的大小,根据需要调整 */
overflow: hidden; overflow: hidden;
z-index: 99; z-index: 99;
border: 2px solid #ded9e1; border: 1px solid #666;
border-radius: 15px; border-radius: 15px;
} }
} }

BIN
src/views/system/mapManagement/m9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 KiB

3677
yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save