Browse Source

调整地图设计器数据结构

master
wangxiang 3 years ago
parent
commit
5fa79c38d6
  1. 71
      src/components/AMap/src/AMapDesigner/index.vue
  2. 53
      src/components/AMap/src/amap.data.tsx
  3. 200
      src/components/AMap/src/components/MapPointModal.vue
  4. 20
      src/components/AMap/src/components/MapTaskModal.vue
  5. 1
      src/enums/amapEnum.ts

71
src/components/AMap/src/AMapDesigner/index.vue

@ -69,7 +69,7 @@ @@ -69,7 +69,7 @@
</template>
<script lang="ts" setup>
import AMapLoader from '@amap/amap-jsapi-loader';
import { reactive, watchEffect, getCurrentInstance, onBeforeMount, onUnmounted, ref, PropType, watch, toRefs, nextTick, onMounted } from 'vue';
import { reactive, watchEffect, getCurrentInstance, onBeforeMount, onUnmounted, ref, PropType, watch, toRefs, nextTick } from 'vue';
import { operatePanelColumns, MapData, MapPointType } from '../amap.data';
import hospital from '/@/assets/images/hospital.svg';
import medicalKit from '/@/assets/images/medical-kit.svg';
@ -435,26 +435,6 @@ @@ -435,26 +435,6 @@
});
onMounted(() => {
//
mapState.mapData = defaultMapData();
setTableData(mapState.mapData.mapTask);
// ,线
if (!isEmpty(mapState.mapData.mapLogisticPoint)) {
const lngLatData = mapState.mapData.mapLogisticPoint.map(item => new AMap.LngLat(item.lng, item.lat));
const destination = lngLatData.pop();
destination && driving.search(new AMap.LngLat(mapState.mapData.courierLng, mapState.mapData.courierLat), destination, {
waypoints: lngLatData
}, function(status, result) {
if (status === 'complete') {
console.log('绘制地图路线完成');
} else {
console.error('获取地图数据失败:' + result);
}
});
}
});
onUnmounted(() => {
if (map) {
//
@ -462,7 +442,6 @@ @@ -462,7 +442,6 @@
}
});
/** 地图创建完成(动画关闭) */
function complete () {
if (map) {
@ -479,7 +458,7 @@ @@ -479,7 +458,7 @@
if (!mapProps.sidebarControl) mapState.toggleOperatePanelClass.siderWidth = 0;
if (!mapProps.toolbarControl) mapState.toggleOperatePanelClass.toolbarHeight = 0;
});
watch(toRefs(mapProps).options, (newValue)=>{
watch(toRefs(mapProps).options, (newValue) => {
setMapDataJson(newValue);
}, {
immediate: true,
@ -578,14 +557,32 @@ @@ -578,14 +557,32 @@
nextTick(() => {
mapState.mapData = cloneDeep(merge(defaultMapData(), options));
setTableData(mapState.mapData.mapTask);
if (!isEmpty(mapState.mapData.mapLogisticPoint)) {
drawMapNavigate(mapState.mapData.mapLogisticPoint);
}
});
}
/** 获取部件表单数据 */
function getMapDataJson () {
function getMapDataJson() {
return cloneDeep(mapState.mapData);
}
/** 绘制地图导航路线 */
function drawMapNavigate(points: Recordable[] = []) {
const lngLats = points.map(item => new AMap.LngLat(item.lng, item.lat));
const destination = lngLats.pop();
destination && driving.search(new AMap.LngLat(mapState.mapData.courierLng, mapState.mapData.courierLat), destination, {
waypoints: lngLats
}, function(status, result) {
if (status === 'complete') {
console.log('绘制地图路线完成');
} else {
console.error('获取地图数据失败:' + result);
}
});
}
/** 处理地图任务数据 */
async function handleMapTask() {
setTableData(mapState.mapData.mapTask);
@ -638,23 +635,15 @@ @@ -638,23 +635,15 @@
});
});
mapState.mapData.mapLogisticPoint = pointData;
const lngLatData = pointData.map(item => new AMap.LngLat(item.lng, item.lat));
const last = lngLatData.pop();
// 线
driving.search(new AMap.LngLat(mapState.mapData.courierLng, mapState.mapData.courierLat), last, {
waypoints: lngLatData
}, function(status, result) {
if (status === 'complete') {
console.log('绘制地图路线完成');
} else {
console.error('获取地图数据失败:' + result);
}
});
drawMapNavigate(pointData);
}
/** 处理地图标记点数据 */
function handleMapPoint() {
function handleMapPoint(mapLogisticPoint: Recordable[] = []) {
if (!isEmpty(mapLogisticPoint)) {
mapState.mapData.mapLogisticPoint = mapLogisticPoint;
drawMapNavigate(mapLogisticPoint);
}
}
/** 处理地图保存并发布 */
@ -686,6 +675,12 @@ @@ -686,6 +675,12 @@
});
}
/** 对外提供Api */
defineExpose({
drawMapNavigate,
getMapDataJson,
setMapDataJson
});
</script>
<style lang="less" scoped>

53
src/components/AMap/src/amap.data.ts → src/components/AMap/src/amap.data.tsx

@ -4,6 +4,7 @@ import { listOrg } from '/@/api/platform/common/controller/org'; @@ -4,6 +4,7 @@ import { listOrg } from '/@/api/platform/common/controller/org';
import { commonUpload } from '/@/api/platform/core/controller/upload';
import { h } from 'vue';
import { Tag } from 'ant-design-vue';
import { VxeTableDefines } from 'vxe-table/types/table';
/**
* @program: kicc-ui
@ -190,8 +191,7 @@ export const taskPresetColumns: BasicColumn[] = [ @@ -190,8 +191,7 @@ export const taskPresetColumns: BasicColumn[] = [
}*/
];
/** 子任务预设表格列 */
export const taskPresetChildColumns: BasicColumn[] = [
{
title: '任务名称',
@ -246,3 +246,52 @@ export const taskPresetChildColumns: BasicColumn[] = [ @@ -246,3 +246,52 @@ export const taskPresetChildColumns: BasicColumn[] = [
}
}*/
];
/** 子任务预设表格列 */
export const mapPointColumns: VxeTableDefines.ColumnOptions[] = [
{
width: '50px',
align: 'center',
slots: {
default ({ row }) {
return [
<span class="drag-btn">
<i class="vxe-icon--menu"/>
</span>
];
},
header ({ column }) {
return [
<vxe-tooltip content="按住后可以上下拖动排序!">
<i class="vxe-icon--question"/>
</vxe-tooltip>
];
}
}
},
{ field: 'lng', title: '经度值' },
{ field: 'lat', title: '纬度值' },
{ field: 'type',
title: '医院类型',
slots: {
default ({ row }) {
const type = row.type;
let text = '', color = '';
switch (type) {
case '0':
text = '普通任务';
color = 'green';
break;
case '1':
text = '交接任务';
color = 'red';
break;
}
return [
<Tag color={color}>{text}</Tag>
];
}
}
},
{ field: 'hospitalName', title: '医院名称' }
];

200
src/components/AMap/src/components/MapPointModal.vue

@ -1,124 +1,138 @@ @@ -1,124 +1,138 @@
<template>
<BasicModal v-bind="$attrs"
defaultFullscreen
@register="registerModal"
@ok="handleSubmit"
>
<div class="pointBody">
<div class="leftLayout">
<AMapDesigner ref="AMapDesignerEl"
:options="state.mapData"
:sidebarControl="false"
:toolbarControl="false"
/>
</div>
<div class="rightLayout">
<vxe-grid ref="VxeGridEl" v-bind="state.gridOptions"/>
</div>
</div>
</BasicModal>
</template>
<script lang="tsx" setup>
import { reactive, nextTick, ref, h } from 'vue';
import { reactive, nextTick, ref } from 'vue';
import { BasicModal, ModalProps, useModalInner } from '/@/components/Modal';
import { Form, Select, Row, Col } from 'ant-design-vue';
import { AMapDesigner } from '/@/components/AMap';
import Sortable from 'sortablejs';
import { VxeGridProps } from 'vxe-table';
import { MapData, mapPointColumns } from '../amap.data';
import { defaultMapData } from '/@/enums/amapEnum';
import { cloneDeep } from 'lodash-es';
/** 类型规范统一声明定义区域 */
interface WindowState {
sortable: Nullable<object>;
gridOptions: VxeGridProps;
mapData: MapData;
}
/** 通用变量统一声明区域 */
const VxeGridEl = ref();
const mapSettingsState = reactive({
sortable: {}
});
const gridOptions = reactive({
data: [
{
id: 10001,
name: 'Test1'
},
{
id: 10002,
name: 'Test2'
},
{
id: 10003,
name: 'Test3'
}
],
columns: [
{
width: '50px',
align: 'center',
slots: {
default ({ row }) {
return (
<span class="drag-btn">
<i class="vxe-icon--menu"/>
</span>
);
},
header ({ row }) {
return (
<vxe-tooltip content="按住后可以上下拖动排序!">
<i class="vxe-icon--question"/>
</vxe-tooltip>
);
}
}
const AMapDesignerEl = ref();
const state = reactive<WindowState>({
sortable: null,
gridOptions: {
columns: mapPointColumns,
rowConfig: {
useKey: true,
isHover: true,
keyField: 'id'
},
{ field: 'name', title: '名称' }
],
rowConfig: {
useKey: true,
isHover: true
border: true,
height: 'auto',
stripe: true
},
border: true,
height: 'auto',
stripe: true
} as VxeGridProps);
const AForm = Form;
const AFormItem = Form.Item;
const ASelect = Select;
const ARow = Row;
const ACol = Col;
mapData: defaultMapData()
});
const emit = defineEmits(['success', 'register']);
const [registerModal, { setModalProps, closeModal }] = useModalInner(data => {
//
state.mapData = cloneDeep(data.mapData);
const props: Partial<ModalProps> = { confirmLoading: false };
props.title = '标记点配置';
nextTick(() => {
mapSettingsState.sortable = Sortable.create(VxeGridEl.value!.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
nextTick(()=> {
state.sortable = Sortable.create(VxeGridEl.value!.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
handle: '.drag-btn',
onEnd: ({ newIndex, oldIndex }) => {
const currRow = gridOptions.data?.splice(oldIndex!, 1)[0];
gridOptions.data?.splice(newIndex!, 0, currRow);
const currRow = state.mapData.mapLogisticPoint?.splice(oldIndex!, 1)[0];
state.mapData.mapLogisticPoint?.splice(newIndex!, 0, currRow);
AMapDesignerEl.value?.drawMapNavigate(state.mapData.mapLogisticPoint);
},
ghostClass: 'ghostGrid'
});
});
VxeGridEl.value.reloadData(state.mapData.mapLogisticPoint);
// :
setModalProps(props);
});
/** 处理弹出框提交 */
function handleSubmit() {
try {
//
setModalProps({ confirmLoading: true });
//
const mapLogisticPoint = state.mapData.mapLogisticPoint.map((item, index)=> ({ sort: index, ...item }));
//
closeModal();
emit('success', mapLogisticPoint);
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<template>
<BasicModal v-bind="$attrs"
defaultFullscreen
@register="registerModal"
@ok="handleSubmit"
>
<ARow>
<ACol :span="12">
<AMapDesigner :sidebarControl="false"/>
</ACol>
<ACol :span="12">
<vxe-grid ref="VxeGridEl" v-bind="gridOptions"/>
</ACol>
</ARow>
</BasicModal>
</template>
<style>
.ghostGrid {
background: white;
border: 2px solid #67C23A;
box-sizing: border-box;
font-size: 0;
content: "";
overflow: hidden;
padding: 0 !important;
position: relative;
outline: none 0;
height: 100% !important;
width: 0 !important;
float: left;
margin: 0 2px 0 2px;
<style lang="less" scoped>
//
.pointBody {
//
:deep(.ghostGrid) {
background: white;
border: 2px solid #67C23A;
box-sizing: border-box;
font-size: 0;
content: "";
overflow: hidden;
padding: 0 !important;
position: relative;
outline: none 0;
height: 100% !important;
width: 0 !important;
float: left;
margin: 0 2px 0 2px;
}
.leftLayout {
position: absolute;
top: 0;
left: 0;
right: 50%;
bottom: 0;
}
.rightLayout {
position: absolute;
top: 0;
left: 50%;
right: 0;
bottom: 0;
}
}
</style>

20
src/components/AMap/src/components/MapTaskModal.vue

@ -66,6 +66,7 @@ @@ -66,6 +66,7 @@
import { buildUUID } from '/@/utils/uuid';
import { useMessage } from '/@/hooks/web/useMessage';
import { cloneDeep } from 'lodash-es';
import { defaultMapData } from '/@/enums/amapEnum';
/** 类型规范统一声明定义区域 */
interface WindowState {
@ -78,24 +79,7 @@ @@ -78,24 +79,7 @@
const state = reactive<WindowState>({
taskOrdinaryCurrentEditRowRef: null,
taskPresetCurrentEditRowRef: null,
mapData: {
name: '',
courierUserId: '',
courierUserName: '',
courierLng: undefined,
courierLat: undefined,
sendOrderId: '',
sendOrderName: '',
sendOrderLng: undefined,
sendOrderLat: undefined,
fileId: [],
estimateTime: '',
requireTime: '',
/** 地图任务数据 */
mapTask: [],
/** 地图预览点数据 */
mapLogisticPoint: [],
}
mapData: defaultMapData()
});
const emit = defineEmits(['success', 'register']);
const [registerModal, { setModalProps, closeModal }] = useModalInner(async data => {

1
src/enums/amapEnum.ts

@ -23,6 +23,7 @@ export const defaultMapData: ()=> MapData = ()=> cloneDeep({ @@ -23,6 +23,7 @@ export const defaultMapData: ()=> MapData = ()=> cloneDeep({
requireTime: '',
/** 地图任务数据 */
mapTask: [{
id: '001',
name: '宇宙任务',
taskType: '0',
mapTaskPreset: []

Loading…
Cancel
Save