237 lines
7.7 KiB
Vue
237 lines
7.7 KiB
Vue
<script setup lang="ts">
|
|
import {
|
|
MAP_ROUTE_PASS_TYPES,
|
|
MAP_ROUTE_TYPES,
|
|
type MapPen,
|
|
type MapRouteInfo,
|
|
MapRoutePassType,
|
|
MapRouteType,
|
|
} from '@api/map';
|
|
import type { EditorService } from '@core/editor.service';
|
|
import sTheme from '@core/theme.service';
|
|
import { computed, inject, type InjectionKey, type ShallowRef } from 'vue';
|
|
|
|
type Props = {
|
|
token: InjectionKey<ShallowRef<EditorService>>;
|
|
id?: string;
|
|
};
|
|
const props = defineProps<Props>();
|
|
const editor = inject(props.token)!;
|
|
|
|
const pen = computed<MapPen | null>(() => {
|
|
const v = editor.value.current.value;
|
|
if (v?.id !== props.id) return null;
|
|
return v!;
|
|
});
|
|
const route = computed<MapRouteInfo | null>(() => {
|
|
const v = pen.value?.route;
|
|
if (!v?.type) return null;
|
|
return v;
|
|
});
|
|
|
|
// 双向路线管理
|
|
const connectedRoutes = computed<MapPen[]>(() => {
|
|
if (!pen.value) return [];
|
|
const [a1, a2] = pen.value.anchors ?? [];
|
|
if (!a1?.connectTo || !a2?.connectTo) return [];
|
|
return editor.value.getRoutesBetweenPoints(a1.connectTo, a2.connectTo);
|
|
});
|
|
|
|
const currentRoute = computed<MapPen | null>(() => {
|
|
return pen.value;
|
|
});
|
|
|
|
const oppositeRoute = computed<MapPen | null>(() => {
|
|
if (!currentRoute.value) return null;
|
|
const [a1, a2] = currentRoute.value.anchors ?? [];
|
|
if (!a1?.connectTo || !a2?.connectTo) return null;
|
|
|
|
return connectedRoutes.value.find(r => r.id !== currentRoute.value?.id) || null;
|
|
});
|
|
|
|
const isBidirectional = computed<boolean>(() => {
|
|
return connectedRoutes.value.length >= 2;
|
|
});
|
|
|
|
|
|
// 处理路线方向变化
|
|
function handleDirectionChange(direction: any) {
|
|
if (!props.id) return;
|
|
editor.value.updateRoute(props.id, { direction: Number(direction) as -1 | 1 });
|
|
}
|
|
|
|
// 处理路线类型变化
|
|
function handleRouteTypeChange(type: any) {
|
|
if (!props.id) return;
|
|
editor.value.changeRouteType(props.id, Number(type) as unknown as MapRouteType);
|
|
}
|
|
|
|
// 处理反向路线方向变化
|
|
function handleOppositeDirectionChange(direction: any) {
|
|
if (!oppositeRoute.value?.id) return;
|
|
editor.value.updateRoute(oppositeRoute.value.id, { direction: Number(direction) as -1 | 1 });
|
|
}
|
|
|
|
// 处理通行类型变化
|
|
function handlePassChange(pass: any) {
|
|
if (!props.id) return;
|
|
editor.value.updateRoute(props.id, { pass: Number(pass) as MapRoutePassType });
|
|
}
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<a-card class="full" :title="$t('属性')" :bordered="false">
|
|
<a-flex v-if="id && pen && route" :gap="24" vertical>
|
|
<a-row :gutter="[8, 8]">
|
|
<a-col :span="24">
|
|
<a-select
|
|
:value="route.pass ?? MapRoutePassType.无"
|
|
@change="handlePassChange($event)"
|
|
>
|
|
<a-select-option v-for="[l, v] in MAP_ROUTE_PASS_TYPES" :key="v">{{ $t(l) }}</a-select-option>
|
|
</a-select>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<a-row :gutter="[8, 8]">
|
|
<a-col :span="24">
|
|
<a-typography-text>{{ $t('描述') }}:</a-typography-text>
|
|
</a-col>
|
|
<a-col :span="24">
|
|
<a-textarea
|
|
class="prop"
|
|
:placeholder="$t('请输入描述内容')"
|
|
:maxlength="100"
|
|
:autoSize="{ minRows: 3, maxRows: 3 }"
|
|
:value="pen?.desc"
|
|
@change="editor.updatePen(id, { desc: $event.target.value }, false)"
|
|
/>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<a-row align="middle" :gutter="10" :wrap="false">
|
|
<a-col flex="none">
|
|
<a-typography-text>{{ $t('路段长度') }}:</a-typography-text>
|
|
</a-col>
|
|
<a-col flex="auto">
|
|
<a-input :value="pen.length?.toFixed()" disabled />
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<a-row align="middle" :gutter="10" :wrap="false">
|
|
<a-col flex="none">
|
|
<a-typography-text>{{ $t('路段方向') }}:</a-typography-text>
|
|
</a-col>
|
|
<a-col flex="auto">
|
|
<a-select
|
|
:value="route.direction || 1"
|
|
@change="handleDirectionChange($event)"
|
|
>
|
|
<a-select-option :value="1">{{ editor.getRouteLabel(id, 1) }}</a-select-option>
|
|
<a-select-option :value="-1">{{ editor.getRouteLabel(id, -1) }}</a-select-option>
|
|
</a-select>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<!-- 反向路线方向(如果存在双向路线) -->
|
|
<a-row v-if="isBidirectional && oppositeRoute" align="middle" :gutter="10" :wrap="false">
|
|
<a-col flex="none">
|
|
<a-typography-text>{{ $t('反向路线方向') }}:</a-typography-text>
|
|
</a-col>
|
|
<a-col flex="auto">
|
|
<a-select
|
|
:value="oppositeRoute.route?.direction || -1"
|
|
@change="handleOppositeDirectionChange($event)"
|
|
>
|
|
<a-select-option :value="1">{{ editor.getRouteLabel(oppositeRoute.id, 1) }}</a-select-option>
|
|
<a-select-option :value="-1">{{ editor.getRouteLabel(oppositeRoute.id, -1) }}</a-select-option>
|
|
</a-select>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
|
|
|
|
<a-row align="middle" :gutter="10" :wrap="false">
|
|
<a-col flex="none">
|
|
<a-typography-text>{{ $t('路段类型') }}:</a-typography-text>
|
|
</a-col>
|
|
<a-col flex="auto">
|
|
<a-select :value="route.type" @change="handleRouteTypeChange($event)">
|
|
<a-select-option v-for="[l, v] in MAP_ROUTE_TYPES" :key="v">{{ $t(l) }}</a-select-option>
|
|
</a-select>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<a-row
|
|
v-if="[MapRouteType.二阶贝塞尔曲线, MapRouteType.三阶贝塞尔曲线].includes(route.type)"
|
|
align="middle"
|
|
:gutter="8"
|
|
>
|
|
<a-col flex="auto">
|
|
<a-typography-text>{{ $t('控制点1') }}:</a-typography-text>
|
|
</a-col>
|
|
<a-col flex="none">
|
|
<a-space :size="8">
|
|
<a-typography-text code>X:</a-typography-text>
|
|
<a-input-number
|
|
style="width: 80px"
|
|
:placeholder="$t('请输入')"
|
|
:precision="0"
|
|
:controls="false"
|
|
:value="route?.c1?.x.toFixed()"
|
|
@change="editor.updateRoute(id, { c1: { x: +$event, y: route?.c1?.y ?? 0 } })"
|
|
/>
|
|
</a-space>
|
|
</a-col>
|
|
<a-col flex="none">
|
|
<a-space :size="8">
|
|
<a-typography-text code>Y:</a-typography-text>
|
|
<a-input-number
|
|
style="width: 80px"
|
|
:placeholder="$t('请输入')"
|
|
:precision="0"
|
|
:controls="false"
|
|
:value="route?.c1?.y.toFixed()"
|
|
@change="editor.updateRoute(id, { c1: { x: route?.c1?.x ?? 0, y: +$event } })"
|
|
/>
|
|
</a-space>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<a-row v-if="MapRouteType.三阶贝塞尔曲线 === route.type" align="middle" :gutter="8">
|
|
<a-col flex="auto">
|
|
<a-typography-text>{{ $t('控制点2') }}:</a-typography-text>
|
|
</a-col>
|
|
<a-col flex="none">
|
|
<a-space :size="8">
|
|
<a-typography-text code>X:</a-typography-text>
|
|
<a-input-number
|
|
style="width: 80px"
|
|
:placeholder="$t('请输入')"
|
|
:precision="0"
|
|
:controls="false"
|
|
:value="route?.c2?.x.toFixed()"
|
|
@change="editor.updateRoute(id, { c2: { x: +$event, y: route?.c2?.y ?? 0 } })"
|
|
/>
|
|
</a-space>
|
|
</a-col>
|
|
<a-col flex="none">
|
|
<a-space :size="8">
|
|
<a-typography-text code>Y:</a-typography-text>
|
|
<a-input-number
|
|
style="width: 80px"
|
|
:placeholder="$t('请输入')"
|
|
:precision="0"
|
|
:controls="false"
|
|
:value="route?.c2?.y.toFixed()"
|
|
@change="editor.updateRoute(id, { c2: { x: route?.c2?.x ?? 0, y: +$event } })"
|
|
/>
|
|
</a-space>
|
|
</a-col>
|
|
</a-row>
|
|
</a-flex>
|
|
<a-empty v-else :image="sTheme.empty" />
|
|
</a-card>
|
|
</template>
|