Browse Source

<feat>:提交部分代码

master
黄潇军 3 months ago
parent
commit
01a42a1e62
  1. 168
      packages/robot-system/src/modules/RobotSystemManage/ScreenViewManage/TaskScreenView/MapComponent copy.vue
  2. 24
      packages/robot-system/src/modules/RobotSystemManage/ScreenViewManage/TaskScreenView/MapComponent.vue
  3. 52
      packages/robot-system/src/modules/RobotSystemManage/ScreenViewManage/TaskScreenView/components/BlockTitle.vue
  4. BIN
      packages/robot-system/src/modules/RobotSystemManage/ScreenViewManage/TaskScreenView/images/block-title.png
  5. 149
      packages/robot-system/src/modules/RobotSystemManage/ScreenViewManage/TaskScreenView/index.vue

168
packages/robot-system/src/modules/RobotSystemManage/ScreenViewManage/TaskScreenView/MapComponent copy.vue

@ -0,0 +1,168 @@ @@ -0,0 +1,168 @@
<template>
<div id="map" style="height: 100%; width: 100%; overflow: hidden"></div>
</template>
<script>
import AMapLoader from '@amap/amap-jsapi-loader';
/**
* props.rectangles: Array<{ id, name, status, geomWkt }>
* - geomWkt: "POLYGON((lng lat,lng lat,...))"
* - status: 施工中 | 已施工 | 未施工 | 故障 | 运行中 | 停机
*/
const STATUS_STYLE = {
施工中: { stroke: 'rgba(41,169,253,1)', fill: 'rgba(41,169,253,0.45)' },
已施工: { stroke: 'rgba(82,196,26,1)', fill: 'rgba(82,196,26,0.45)' },
未施工: { stroke: 'rgba(250,173,20,1)', fill: 'rgba(250,173,20,0.45)' },
故障: { stroke: 'rgba(219,77,77,1)', fill: 'rgba(219,77,77,0.6)' },
运行中: { stroke: 'rgba(19,194,194,1)', fill: 'rgba(19,194,194,0.45)' },
停机: { stroke: 'rgba(99,99,99,1)', fill: 'rgba(0,0,0,0.45)' }
};
export default {
name: 'TaskMapPolygon',
props: {
rectangles: {
type: Array,
default: () => []
}
},
data() {
return {
map: null,
AMapIns: null,
polygons: [],
texts: [],
pointAll: { lng: [], lat: [] }
};
},
watch: {
rectangles: {
immediate: true,
deep: true,
handler(val) {
if (this.map && val?.length) {
this.clearLayers();
this.formatData(val);
}
}
}
},
mounted() {
this.initAMap();
},
beforeUnmount() {
this.map?.destroy();
},
methods: {
initAMap() {
const map_center = JSON.parse(this.$storage.get('map_center') || 'null');
let defaultCenterPoint = [121.5563, 32.107];
if (map_center) {
defaultCenterPoint = map_center.find((el) => el.key == 'default')?.value || defaultCenterPoint;
}
window._AMapSecurityConfig = { securityJsCode: '5869fe06ab3640b49006f4ec5e595e9f' };
AMapLoader.load({
key: '3758e4530242ba6282c77f96ea69262d',
version: '2.0',
plugins: ['AMap.MouseTool', 'AMap.Scale', 'AMap.Text']
})
.then((AMap) => {
this.AMapIns = AMap;
this.map = new AMap.Map('map', {
viewMode: '2D',
zoom: 12,
center: defaultCenterPoint
});
if (this.rectangles?.length) {
this.formatData(this.rectangles);
}
})
.catch(console.error);
},
clearLayers() {
if (!this.map) return;
this.map.remove(this.polygons);
this.map.remove(this.texts);
this.polygons = [];
this.texts = [];
this.pointAll = { lng: [], lat: [] };
},
formatData(data = []) {
// WKT -> AMap path使
const list = (data || []).map((item, index) => {
const raw = (item.geomWkt || '')
.replace(/POLYGON\(\(/i, '')
.replace(/\)\)$/i, '')
.trim();
const points = raw.split(',');
const path = [];
for (let i = 0; i < points.length; i++) {
const parts = points[i].trim().split(/\s+/);
const lng = Number(parts[0]);
const lat = Number(parts[1]);
if (isNaN(lng) || isNaN(lat)) continue;
this.pointAll.lng.push(lng);
this.pointAll.lat.push(lat);
path.push([lng, lat]);
}
return { ...item, path, index };
});
list.forEach((it) => this.createPolygon(it));
//
if (this.polygons.length) {
// padding: [top, right, bottom, left]
this.map.setFitView(this.polygons, false, [60, 60, 60, 60]);
}
},
createPolygon(item) {
const { path, status, name } = item;
const style = STATUS_STYLE[status] || STATUS_STYLE['未施工'];
const polygon = new this.AMapIns.Polygon({
path,
strokeColor: style.stroke,
strokeWeight: 2,
strokeOpacity: 1,
strokeStyle: 'solid',
fillColor: style.fill,
fillOpacity: 0.45,
cursor: 'pointer',
zIndex: 50
});
console.log(polygon, 'polygon');
this.map.add(polygon);
this.polygons.push(polygon);
//
const text = new this.AMapIns.Text({
text: name || '',
anchor: 'center',
style: { 'background-color': 'transparent', border: 'none', color: '#ffffff', 'font-size': '12px' }
});
//
const mid = path[Math.floor(path.length / 2)] || path[0];
if (mid) text.setPosition(mid);
text.setMap(this.map);
this.texts.push(text);
// hover
polygon.on('mouseover', () => {
polygon.setOptions({ fillOpacity: 0.55 });
});
polygon.on('mouseout', () => {
polygon.setOptions({ fillOpacity: 0.35 });
});
}
}
};
</script>
<style scoped lang="scss">
#map {
width: 100%;
height: 100%;
}
</style>

24
packages/robot-system/src/modules/RobotSystemManage/ScreenViewManage/TaskScreenView/MapComponent.vue

@ -1,5 +1,8 @@ @@ -1,5 +1,8 @@
<template>
<div id="map" style="height: 100%; width: 100%; overflow: hidden"></div>
<div style="position: relative; height: 100%; width: 100%; overflow: hidden">
<div id="map" style="height: 100%; width: 100%; overflow: hidden"></div>
<div v-if="darkMask" class="dark-mask"></div>
</div>
</template>
<script>
@ -25,6 +28,11 @@ export default { @@ -25,6 +28,11 @@ export default {
rectangles: {
type: Array,
default: () => []
},
//
darkMask: {
type: Boolean,
default: true
}
},
data() {
@ -70,10 +78,13 @@ export default { @@ -70,10 +78,13 @@ export default {
})
.then((AMap) => {
this.AMapIns = AMap;
// 使线
const satellite = new AMap.TileLayer.Satellite();
this.map = new AMap.Map('map', {
viewMode: '2D',
zoom: 12,
center: defaultCenterPoint
center: defaultCenterPoint,
layers: [satellite]
});
if (this.rectangles?.length) {
this.formatData(this.rectangles);
@ -165,4 +176,13 @@ export default { @@ -165,4 +176,13 @@ export default {
width: 100%;
height: 100%;
}
.dark-mask {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: rgba(0, 10, 26, 0.25);
pointer-events: none;
}
</style>

52
packages/robot-system/src/modules/RobotSystemManage/ScreenViewManage/TaskScreenView/components/BlockTitle.vue

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
<template>
<div class="block-title">
<div class="title-left">
<img src="../images/block-title.png" alt="logo" />
<div class="title-text">{{ title }}</div>
</div>
<div class="title-more">
<slot name="more"> </slot>
</div>
</div>
</template>
<script>
export default {
name: 'BlockTitle',
props: {
title: {
type: String,
default: ''
}
}
};
</script>
<style lang="scss" scoped>
.block-title {
display: flex;
justify-content: space-between;
align-items: center;
height: 28px;
img {
height: 26px;
width: auto;
margin-right: 8px;
}
.title-left {
display: flex;
align-items: center;
}
.title-text {
font-family: PingFang SC, PingFang SC;
font-weight: 600;
font-size: 20px;
color: #333333;
}
.title-more {
font-family: PingFang SC, PingFang SC;
font-weight: 400;
font-size: 14px;
color: #4886e0;
}
}
</style>

BIN
packages/robot-system/src/modules/RobotSystemManage/ScreenViewManage/TaskScreenView/images/block-title.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

149
packages/robot-system/src/modules/RobotSystemManage/ScreenViewManage/TaskScreenView/index.vue

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
<template>
<div class="task-screen">
<div class="map-wrap">
<!-- <div class="map-wrap">
<MapComponent :rectangles="rectangles" />
<div class="legend">
<div class="legend-item" v-for="(item, i) in legends" :key="i">
@ -8,22 +8,20 @@ @@ -8,22 +8,20 @@
<span class="text">{{ item.label }}</span>
</div>
</div>
</div>
</div> -->
<div class="side left">
<div class="panel">
<div class="panel-title">
<img class="titleIcon" :src="titleIcon" />
<span>工区统计</span>
<span class="more">更多</span>
</div>
<BlockTitle title="工区统计">
<template #right>
<span>更多</span>
</template>
</BlockTitle>
<div class="progress-group">
<div class="progress-row">
<div class="label">工区总进度</div>
<div class="value">{{ areaProgress }}%</div>
</div>
<fks-progress :percentage="areaProgress" :stroke-width="8" color="#4dabf7" />
<div class="progress-sub">
<div class="sub-row" v-for="(p, pi) in subProgress" :key="pi">
<div class="name">{{ p.name }}</div>
@ -33,24 +31,21 @@ @@ -33,24 +31,21 @@
<div class="num">{{ p.value }}</div>
</div>
</div>
<fks-table :data="areaTable" border height="220">
<fks-table-column prop="name" label="工区名称" min-width="74" />
<fks-table-column prop="pile" label="桩条安装进度(%)" width="90" />
<fks-table-column prop="module" label="组件安装进度(%)" width="90" />
<fks-table-column prop="year" label="10号车" width="74" />
</fks-table>
</div>
<fks-table :data="areaTable" border height="280">
<fks-table-column type="index" label="#" width="50" />
<fks-table-column prop="name" label="工区名称" min-width="90" />
<fks-table-column prop="pile" label="桩条安装进度(%)" width="140" />
<fks-table-column prop="module" label="组件安装进度(%)" width="140" />
<fks-table-column prop="owner" label="负责安环" width="90" />
<fks-table-column prop="year" label="10号车" width="80" />
</fks-table>
</div>
<div class="panel">
<div class="panel-title">
<img class="titleIcon" :src="titleIcon" />
<span>材料统计</span>
<span class="more">更多</span>
</div>
<BlockTitle title="材料统计">
<template #right>
<span>更多</span>
</template>
</BlockTitle>
<fks-table :data="materialTable" border height="300">
<fks-table-column prop="name" label="材料名称" min-width="100" />
<fks-table-column prop="used" label="当日消耗量" width="120" />
@ -61,12 +56,11 @@ @@ -61,12 +56,11 @@
<div class="side right">
<div class="panel">
<div class="panel-title">
<img class="titleIcon" :src="titleIcon" />
<span>设备信息</span>
<span class="more">更多</span>
</div>
<BlockTitle title="设备信息">
<template #right>
<span>更多</span>
</template>
</BlockTitle>
<div class="kpibox">
<div class="kpi">
<div class="kpi-label">当前设备在线数量</div>
@ -115,11 +109,12 @@ @@ -115,11 +109,12 @@
<script>
import Mix from '@/mixins/module';
import MapComponent from './MapComponent.vue';
import BlockTitle from './components/BlockTitle.vue';
export default {
name: 'TaskScreenView',
mixins: [Mix],
components: { MapComponent },
components: { MapComponent, BlockTitle },
data() {
return {
titleIcon: require('@/assets/img/Automated/titleIcon1.png'),
@ -165,17 +160,17 @@ export default { @@ -165,17 +160,17 @@ export default {
],
rectangles: [
// 西
{ id: '1', name: '西湖区', status: '施工中', geomWkt: 'POLYGON((120.0000 30.1500,120.2500 30.1500,120.2500 30.3700,120.0000 30.3700,120.0000 30.1500))' },
{ id: '1', name: '西湖区', status: '施工中', geomWkt: 'POLYGON((120.0000 30.1500,120.2500 30.1500,120.2500 30.3700,120.0000 30.3700,120.0000 30.1500))' }
//
{ id: '2', name: '拱墅区', status: '已施工', geomWkt: 'POLYGON((120.0900 30.3000,120.2300 30.3000,120.2300 30.4200,120.0900 30.4200,120.0900 30.3000))' },
//
{ id: '3', name: '上城区', status: '未施工', geomWkt: 'POLYGON((120.1400 30.2000,120.2600 30.2000,120.2600 30.3100,120.1400 30.3100,120.1400 30.2000))' },
//
{ id: '4', name: '滨江区', status: '故障', geomWkt: 'POLYGON((120.0900 30.1400,120.2700 30.1400,120.2700 30.2400,120.0900 30.2400,120.0900 30.1400))' },
//
{ id: '5', name: '萧山区', status: '运行中', geomWkt: 'POLYGON((120.1800 30.0200,120.5300 30.0200,120.5300 30.3300,120.1800 30.3300,120.1800 30.0200))' },
//
{ id: '6', name: '余杭区', status: '停机', geomWkt: 'POLYGON((119.8000 30.1800,120.1000 30.1800,120.1000 30.5000,119.8000 30.5000,119.8000 30.1800))' }
// { id: '2', name: '', status: '', geomWkt: 'POLYGON((120.0900 30.3000,120.2300 30.3000,120.2300 30.4200,120.0900 30.4200,120.0900 30.3000))' },
// //
// { id: '3', name: '', status: '', geomWkt: 'POLYGON((120.1400 30.2000,120.2600 30.2000,120.2600 30.3100,120.1400 30.3100,120.1400 30.2000))' },
// //
// { id: '4', name: '', status: '', geomWkt: 'POLYGON((120.0900 30.1400,120.2700 30.1400,120.2700 30.2400,120.0900 30.2400,120.0900 30.1400))' },
// //
// { id: '5', name: '', status: '', geomWkt: 'POLYGON((120.1800 30.0200,120.5300 30.0200,120.5300 30.3300,120.1800 30.3300,120.1800 30.0200))' },
// //
// { id: '6', name: '', status: '', geomWkt: 'POLYGON((119.8000 30.1800,120.1000 30.1800,120.1000 30.5000,119.8000 30.5000,119.8000 30.1800))' }
],
legends: [
{ label: '施工中', color: '#3fa7ff' },
@ -191,12 +186,27 @@ export default { @@ -191,12 +186,27 @@ export default {
</script>
<style scoped lang="scss">
//
* {
box-sizing: border-box;
color: #333333;
}
::v-deep .fks-table {
table {
th {
font-size: 12px !important;
padding: 4px 0 !important;
color: #999 !important;
background: #f9f9f9 !important;
}
}
}
//
.task-screen {
position: relative;
display: flex;
height: 100%;
width: 100%;
background: #0b1535;
}
.map-wrap {
position: relative;
@ -225,18 +235,19 @@ export default { @@ -225,18 +235,19 @@ export default {
margin-right: 6px;
}
.text {
color: #cfe6ff;
font-size: 12px;
}
}
}
.side {
width: 360px;
padding: 12px;
width: 392px;
padding: 24px;
box-sizing: border-box;
box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.1);
border-radius: 4px;
.panel + .panel {
margin-top: 12px;
margin-top: 20px;
}
}
.left {
@ -255,15 +266,13 @@ export default { @@ -255,15 +266,13 @@ export default {
}
.panel {
background: rgba(0, 12, 32, 0.7);
border: 1px solid rgba(91, 166, 255, 0.35);
border-radius: 8px;
padding: 12px;
.block-title {
margin-bottom: 10px;
}
.panel-title {
display: flex;
align-items: center;
justify-content: space-between;
color: #cfe6ff;
font-size: 14px;
margin-bottom: 10px;
.titleIcon {
@ -275,44 +284,52 @@ export default { @@ -275,44 +284,52 @@ export default {
display: inline-flex;
align-items: center;
}
.more {
color: #6bb1ff;
cursor: pointer;
font-size: 12px;
}
}
}
.progress-group {
margin-bottom: 12px;
background: linear-gradient(180deg, #ffffff 0%, rgba(242, 249, 255, 0.5) 100%);
border-radius: 8px 8px 8px 8px;
border: 1px solid #dcedff;
.progress-row {
height: 34px;
background: linear-gradient(90deg, #e6f5ff 0%, #d3eeff 100%), linear-gradient(90deg, #e6f5ff 0%, #d8efff 75%, rgba(214, 238, 255, 0.89) 79%, rgba(211, 238, 255, 0.58) 100%);
margin-bottom: 12px;
display: flex;
justify-content: space-between;
color: #cfe6ff;
margin-bottom: 6px;
align-items: center;
justify-content: center;
gap: 0 8px;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
font-size: 14px;
.label {
font-size: 13px;
color: #333333;
}
.value {
font-size: 13px;
color: #4886e0;
}
}
.progress-sub {
margin-top: 8px;
padding: 12px;
.sub-row {
display: grid;
grid-template-columns: 120px 1fr 36px;
grid-template-columns: 92px 1fr 18px;
align-items: center;
color: #cfe6ff;
font-size: 12px;
margin-bottom: 6px;
gap: 0 16px;
.name {
opacity: 0.85;
font-size: 12px;
color: #999;
}
.bar {
padding: 0 8px;
}
.num {
font-family: DIN, DIN;
font-weight: bold;
font-size: 16px;
color: #4886e0;
text-align: right;
}
}
@ -330,7 +347,6 @@ export default { @@ -330,7 +347,6 @@ export default {
border-radius: 6px;
padding: 10px 8px;
.kpi-label {
color: #94b8ff;
font-size: 12px;
margin-bottom: 4px;
white-space: nowrap;
@ -338,7 +354,6 @@ export default { @@ -338,7 +354,6 @@ export default {
text-overflow: ellipsis;
}
.kpi-value {
color: #e8f3ff;
font-weight: 600;
font-size: 18px;
line-height: 1.2;

Loading…
Cancel
Save