merge
This commit is contained in:
commit
f882c8dfb1
79
src/api/CategoryInfoApi.ts
Normal file
79
src/api/CategoryInfoApi.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import { api } from 'src/boot/axios';
|
||||
import { PageDto, PageQueryDto } from './ApiCommon';
|
||||
|
||||
const UriBase = '/api/v1/category';
|
||||
|
||||
export interface createParams {
|
||||
name: string;
|
||||
id?: number;
|
||||
config?: string;
|
||||
}
|
||||
|
||||
export interface CategoryItem extends createParams {
|
||||
id: number;
|
||||
created_at: string;
|
||||
update_at: string;
|
||||
}
|
||||
|
||||
export class PagingQueryParams extends PageQueryDto {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export async function pageQuery(
|
||||
params: PagingQueryParams
|
||||
): Promise<PageDto<CategoryItem>> {
|
||||
const response = await api.get(`${UriBase}/paging`, {
|
||||
params: params,
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建厂家
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function createCategory(data: createParams) {
|
||||
return api.post(`${UriBase}`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除厂家
|
||||
* @param id 厂家id
|
||||
*/
|
||||
export function deleteCategory(id: number) {
|
||||
return api.delete(`${UriBase}/${id}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改厂家数据
|
||||
* @param id 草稿id
|
||||
*/
|
||||
export function saveCategoryData(id: number, data: createParams) {
|
||||
return api.put(`${UriBase}/${id}`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取厂家数据详情
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export async function getCategoryInfo(id: number): Promise<CategoryItem> {
|
||||
const response = await api.get(`${UriBase}/${id}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取厂家信息列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export async function getCategoryList(): Promise<Array<CategoryItem>> {
|
||||
const response = await api.get(`${UriBase}/list`);
|
||||
return response.data;
|
||||
}
|
@ -3,14 +3,15 @@ import { PageDto, PageQueryDto } from './ApiCommon';
|
||||
|
||||
const DraftUriBase = '/api/v1/drafting';
|
||||
|
||||
interface Item {
|
||||
export interface DraftItem {
|
||||
id: number;
|
||||
name: string;
|
||||
proto: string;
|
||||
type: string;
|
||||
createdAt: string;
|
||||
updateAt: string;
|
||||
created_at: string;
|
||||
update_at: string;
|
||||
creatorId?: number;
|
||||
category?: number;
|
||||
}
|
||||
|
||||
export class PagingQueryParams extends PageQueryDto {
|
||||
@ -24,7 +25,7 @@ export class PagingQueryParams extends PageQueryDto {
|
||||
*/
|
||||
export async function pageQuery(
|
||||
params: PagingQueryParams
|
||||
): Promise<PageDto<Item>> {
|
||||
): Promise<PageDto<DraftItem>> {
|
||||
const response = await api.get(`${DraftUriBase}/paging`, {
|
||||
params: params,
|
||||
});
|
||||
@ -36,7 +37,7 @@ export async function pageQuery(
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function createDraft(draftData: { name: string; type: string }) {
|
||||
export function createDraft(draftData: { name: string; category: number }) {
|
||||
return api.post(`${DraftUriBase}`, draftData);
|
||||
}
|
||||
|
||||
@ -53,7 +54,7 @@ export function deleteDraft(id: number) {
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export async function getDraft(id: number): Promise<Item> {
|
||||
export async function getDraft(id: number): Promise<DraftItem> {
|
||||
const response = await api.get(`${DraftUriBase}/${id}`);
|
||||
return response.data;
|
||||
}
|
||||
@ -80,7 +81,7 @@ export function saveDraft(
|
||||
export async function saveAsDraft(
|
||||
id: number,
|
||||
data: { name: string; proto: string }
|
||||
): Promise<Item> {
|
||||
): Promise<DraftItem> {
|
||||
const response = await api.post(`${DraftUriBase}/${id}/saveAs`, data);
|
||||
return response.data;
|
||||
}
|
||||
|
@ -3,13 +3,13 @@ import { PageDto, PageQueryDto } from './ApiCommon';
|
||||
|
||||
const PublishUriBase = '/api/v1/publishedGi';
|
||||
|
||||
interface Item {
|
||||
export interface PublishItem {
|
||||
id: number;
|
||||
name: string;
|
||||
proto: string;
|
||||
createdAt: string;
|
||||
updateAt: string;
|
||||
creatorId?: number;
|
||||
note: string;
|
||||
publishAt: string;
|
||||
userID: number;
|
||||
}
|
||||
|
||||
export class PagingQueryParams extends PageQueryDto {
|
||||
@ -18,11 +18,12 @@ export class PagingQueryParams extends PageQueryDto {
|
||||
|
||||
/**
|
||||
* 草稿图发布
|
||||
* @param id 草稿id
|
||||
* @param draftId 草稿id
|
||||
* @param note 备注
|
||||
*/
|
||||
export function publishDraft(data: {
|
||||
name: string;
|
||||
lineId?: number;
|
||||
note: string;
|
||||
draftId: number;
|
||||
}) {
|
||||
return api.post(`${PublishUriBase}/publish`, data);
|
||||
@ -33,7 +34,7 @@ export function publishDraft(data: {
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export async function getDraft(): Promise<Item> {
|
||||
export async function getDraft(): Promise<PublishItem> {
|
||||
const response = await api.get(`${PublishUriBase}/list`);
|
||||
return response.data;
|
||||
}
|
||||
@ -45,7 +46,7 @@ export async function getDraft(): Promise<Item> {
|
||||
*/
|
||||
export async function pageQuery(
|
||||
params: PagingQueryParams
|
||||
): Promise<PageDto<Item>> {
|
||||
): Promise<PageDto<PublishItem>> {
|
||||
const response = await api.get(`${PublishUriBase}/paging`, {
|
||||
params: params,
|
||||
});
|
||||
@ -54,7 +55,7 @@ export async function pageQuery(
|
||||
|
||||
/**
|
||||
* 删除发布图
|
||||
* @param id 草稿id
|
||||
* @param id 发布id
|
||||
*/
|
||||
export function deletePublish(id: number) {
|
||||
return api.delete(`${PublishUriBase}/${id}`);
|
||||
@ -63,14 +64,14 @@ export function deletePublish(id: number) {
|
||||
* 获取发布地图详细信息
|
||||
* @param id 发布地图id
|
||||
*/
|
||||
export async function getPublishMapInfoById(id: number): Promise<Item> {
|
||||
export async function getPublishMapInfoById(id: number): Promise<PublishItem> {
|
||||
const response = await api.get(`${PublishUriBase}/${id}`);
|
||||
return response.data;
|
||||
}
|
||||
/**
|
||||
* 获取已发布的线路地图数据
|
||||
*/
|
||||
export async function getPublishLineNet(): Promise<Item> {
|
||||
export async function getPublishLineNet(): Promise<PublishItem> {
|
||||
const response = await api.get(`${PublishUriBase}/publish/lineNetwork/info`);
|
||||
return response.data;
|
||||
}
|
||||
@ -79,7 +80,22 @@ export async function getPublishLineNet(): Promise<Item> {
|
||||
* 获取发布地图详细信息
|
||||
* @param id 发布地图线路ID
|
||||
*/
|
||||
export async function getPublishMapInfoByLineId(lineId: string): Promise<Item> {
|
||||
export async function getPublishMapInfoByLineId(
|
||||
lineId: string
|
||||
): Promise<PublishItem> {
|
||||
const response = await api.get(`${PublishUriBase}/${lineId}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 另存到草稿
|
||||
* @param id 发布id
|
||||
*/
|
||||
export function saveToDraft(
|
||||
id: number,
|
||||
data: {
|
||||
name: string;
|
||||
}
|
||||
) {
|
||||
return api.post(`${PublishUriBase}/saveAsDrafting/${id}`, data);
|
||||
}
|
||||
|
@ -69,11 +69,11 @@ const list = reactive([
|
||||
label: '发布管理',
|
||||
icon: 'app_registration',
|
||||
},
|
||||
// {
|
||||
// path: '/dataManage/lineInfo',
|
||||
// label: '线路信息管理',
|
||||
// icon: 'app_registration',
|
||||
// },
|
||||
{
|
||||
path: '/dataManage/categoryInfo',
|
||||
label: '厂家信息管理',
|
||||
icon: 'app_registration',
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
@ -99,6 +99,9 @@
|
||||
<KiloMarkerProperty
|
||||
v-else-if="drawStore.selectedGraphicType === SlopeKiloMarker.Type"
|
||||
/>
|
||||
<slope-property
|
||||
v-else-if="drawStore.selectedGraphicType === Slope.Type"
|
||||
></slope-property>
|
||||
</q-card-section>
|
||||
</template>
|
||||
</q-card>
|
||||
@ -148,6 +151,8 @@ import EsbButtonProperty from './properties/EsbButtonProperty.vue';
|
||||
import { EsbButton } from 'src/graphics/esbButton/EsbButton';
|
||||
import KiloMarkerProperty from './properties/KiloMarkerProperty.vue';
|
||||
import { SlopeKiloMarker } from 'src/graphics/slopeKiloMarker/SlopeKiloMarker';
|
||||
import { Slope } from 'src/graphics/slope/Slope';
|
||||
import SlopeProperty from './properties/SlopeProperty.vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
</script>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!-- eslint-disable vue/no-mutating-props -->
|
||||
<template>
|
||||
<q-dialog v-model="lineStore.showLayerDialog">
|
||||
<q-dialog v-model="show" @hide="onDialogCancel">
|
||||
<q-card class="q-pa-md">
|
||||
<q-card-section> <div class="text-h6">显示控制</div> </q-card-section>
|
||||
<q-card-section>
|
||||
@ -16,7 +16,7 @@
|
||||
<div class="row">
|
||||
<q-checkbox
|
||||
class="col-4"
|
||||
v-for="(item, index) in layerList"
|
||||
v-for="(item, index) in props.layerList"
|
||||
:key="index"
|
||||
v-model="list"
|
||||
:label="item.label"
|
||||
@ -34,17 +34,29 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import { layerList } from 'src/drawApp/lineApp';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
|
||||
interface ItemData {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
const lineStore = useLineStore();
|
||||
|
||||
const list = ref<string[]>([]);
|
||||
const allList = ref(false);
|
||||
const show = ref(false);
|
||||
|
||||
const props = defineProps<{
|
||||
showDialog: boolean;
|
||||
layerList: ItemData[];
|
||||
showLayer: string[];
|
||||
}>();
|
||||
|
||||
function allListFn() {
|
||||
const arr: string[] = [];
|
||||
if (allList.value) {
|
||||
layerList.forEach((item) => {
|
||||
props.layerList.forEach((item) => {
|
||||
arr.push(item.value);
|
||||
});
|
||||
list.value = arr;
|
||||
@ -54,34 +66,29 @@ function allListFn() {
|
||||
}
|
||||
|
||||
watch(
|
||||
() => lineStore.showLayerDialog,
|
||||
() => props.showDialog,
|
||||
(val) => {
|
||||
show.value = val;
|
||||
if (val) {
|
||||
list.value = lineStore.showLayer;
|
||||
allList.value = layerList.length == lineStore.showLayer.length;
|
||||
list.value = props.showLayer;
|
||||
allList.value = props.layerList.length == props.showLayer.length;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const emits = defineEmits(['setShowLayer', 'onDialogClose']);
|
||||
|
||||
watch(
|
||||
() => list.value,
|
||||
(val) => {
|
||||
lineStore.setShowLayer(val);
|
||||
allList.value = layerList.length == val.length;
|
||||
const lineApp = lineStore.getLineApp();
|
||||
const alllGraphic = lineApp.queryStore.getAllGraphics();
|
||||
alllGraphic.forEach((g) => {
|
||||
if (val.includes(g.type)) {
|
||||
g.visible = true;
|
||||
} else {
|
||||
g.visible = false;
|
||||
}
|
||||
});
|
||||
allList.value = props.layerList.length == val.length;
|
||||
emits('setShowLayer', val);
|
||||
}
|
||||
);
|
||||
|
||||
function onDialogCancel() {
|
||||
lineStore.setShowLayerDialog(false);
|
||||
emits('onDialogClose');
|
||||
}
|
||||
</script>
|
||||
<style scoped></style>
|
||||
|
@ -32,37 +32,125 @@
|
||||
@blur="onUpdate"
|
||||
label="公里标(mm):"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
style="margin-top: 10px"
|
||||
v-model="refDevData.deviceType"
|
||||
:options="DeviceTypeOptions"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@update:model-value="onUpdate"
|
||||
label="关联设备类型:"
|
||||
></q-select>
|
||||
<q-select
|
||||
outlined
|
||||
v-if="refDevData.deviceType === graphicData.RelatedRef.DeviceType.Section"
|
||||
style="margin-top: 10px"
|
||||
v-model="refDevData.id"
|
||||
:options="sectionList"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@update:model-value="onUpdate"
|
||||
label="关联设备:"
|
||||
></q-select>
|
||||
<q-select
|
||||
outlined
|
||||
v-if="refDevData.deviceType === graphicData.RelatedRef.DeviceType.Turnout"
|
||||
style="margin-top: 10px"
|
||||
v-model="refDevData.id"
|
||||
:options="turnoutList"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@update:model-value="onUpdate"
|
||||
label="关联设备:"
|
||||
></q-select>
|
||||
<q-select
|
||||
outlined
|
||||
v-if="refDevData.deviceType === graphicData.RelatedRef.DeviceType.Turnout"
|
||||
style="margin-top: 10px"
|
||||
v-model="refDevData.devicePort"
|
||||
:options="DevicePortOptions"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@update:model-value="onUpdate"
|
||||
label="关联设备端口:"
|
||||
></q-select>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SignalData } from 'src/drawApp/graphics/SignalInteraction';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { Signal } from 'src/graphics/signal/Signal';
|
||||
import { Turnout } from 'src/graphics/turnout/Turnout';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const signalModel = reactive(new SignalData());
|
||||
const kilometerSystem = reactive({ coordinateSystem: '', kilometer: 0 });
|
||||
|
||||
const sectionList: { label: string; value: string }[] = reactive([]);
|
||||
const turnoutList: { label: string; value: string }[] = reactive([]);
|
||||
const refDevData = reactive({
|
||||
id: '',
|
||||
deviceType: graphicData.RelatedRef.DeviceType.Section,
|
||||
devicePort: graphicData.RelatedRef.DevicePort.A,
|
||||
});
|
||||
const DeviceTypeOptions = [
|
||||
{ label: '区段', value: graphicData.RelatedRef.DeviceType.Section },
|
||||
{ label: '道岔', value: graphicData.RelatedRef.DeviceType.Turnout },
|
||||
];
|
||||
const DevicePortOptions = [
|
||||
{ label: 'A端', value: graphicData.RelatedRef.DevicePort.A },
|
||||
{ label: 'B端', value: graphicData.RelatedRef.DevicePort.B },
|
||||
{ label: 'C端', value: graphicData.RelatedRef.DevicePort.C },
|
||||
];
|
||||
const CoordinateSystemOptions = [
|
||||
{ label: '车辆段', value: 'DEPOT' },
|
||||
{ label: '停车场', value: 'PARKING_LOT' },
|
||||
{ label: '正线', value: 'MAIN_LINE' },
|
||||
{ label: '换线', value: 'TRANSFER' },
|
||||
];
|
||||
|
||||
function initRefData(signal: Signal) {
|
||||
signalModel.copyFrom(signal.saveData());
|
||||
if (signalModel.kilometerSystem) {
|
||||
kilometerSystem.coordinateSystem =
|
||||
signalModel.kilometerSystem.coordinateSystem;
|
||||
kilometerSystem.kilometer = signalModel.kilometerSystem.kilometer;
|
||||
}
|
||||
if (signalModel.refDev) {
|
||||
refDevData.id = signalModel.refDev.id;
|
||||
refDevData.devicePort = signalModel.refDev.devicePort;
|
||||
refDevData.deviceType = signalModel.refDev.deviceType;
|
||||
}
|
||||
}
|
||||
function initDeviceList() {
|
||||
const sections = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Section>(Section.Type);
|
||||
sections.forEach((sec) => {
|
||||
sectionList.push({
|
||||
label: `${sec.datas.code}[${sec.datas.index}]`,
|
||||
value: sec.datas.id,
|
||||
});
|
||||
});
|
||||
const trunouts = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Turnout>(Turnout.Type);
|
||||
trunouts.forEach((tur) => {
|
||||
turnoutList.push({
|
||||
label: `${tur.datas.code}[${tur.datas.index}]`,
|
||||
value: tur.datas.id,
|
||||
});
|
||||
});
|
||||
}
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Signal.Type) {
|
||||
signalModel.copyFrom(val.saveData() as SignalData);
|
||||
if (signalModel.kilometerSystem) {
|
||||
kilometerSystem.coordinateSystem =
|
||||
signalModel.kilometerSystem.coordinateSystem;
|
||||
kilometerSystem.kilometer = signalModel.kilometerSystem.kilometer;
|
||||
}
|
||||
initRefData(val as Signal);
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -70,12 +158,8 @@ watch(
|
||||
onMounted(() => {
|
||||
const signal = drawStore.selectedGraphic as Signal;
|
||||
if (signal) {
|
||||
signalModel.copyFrom(signal.saveData());
|
||||
if (signalModel.kilometerSystem) {
|
||||
kilometerSystem.coordinateSystem =
|
||||
signalModel.kilometerSystem.coordinateSystem;
|
||||
kilometerSystem.kilometer = signalModel.kilometerSystem.kilometer;
|
||||
}
|
||||
initDeviceList();
|
||||
initRefData(signal);
|
||||
}
|
||||
});
|
||||
|
||||
@ -85,6 +169,16 @@ function onUpdate() {
|
||||
coordinateSystem: kilometerSystem.coordinateSystem,
|
||||
kilometer: kilometerSystem.kilometer,
|
||||
};
|
||||
if (refDevData.id) {
|
||||
signalModel.refDev = new graphicData.RelatedRef({
|
||||
id: refDevData.id,
|
||||
deviceType: refDevData.deviceType,
|
||||
devicePort:
|
||||
refDevData.deviceType === graphicData.RelatedRef.DeviceType.Section
|
||||
? graphicData.RelatedRef.DevicePort.A
|
||||
: refDevData.devicePort,
|
||||
});
|
||||
}
|
||||
if (signal) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(signal, signalModel);
|
||||
}
|
||||
|
112
src/components/draw-app/properties/SlopeProperty.vue
Normal file
112
src/components/draw-app/properties/SlopeProperty.vue
Normal file
@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-input outlined readonly v-model="slopeModel.id" label="id" hint="" />
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
label="坡度长度"
|
||||
type="textarea"
|
||||
@blur="onUpdate"
|
||||
v-model="slopeModel.slopeLong"
|
||||
lazy-rules
|
||||
autogrow
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
label="坡度值"
|
||||
type="textarea"
|
||||
@blur="onUpdate"
|
||||
v-model="slopeModel.slopeNumber"
|
||||
lazy-rules
|
||||
autogrow
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="direction"
|
||||
:options="optionsDirection"
|
||||
label="坡度方向"
|
||||
/>
|
||||
<q-list bordered separator class="rounded-borders">
|
||||
<q-item>
|
||||
<q-item-section no-wrap class="q-gutter-y-sm column">
|
||||
<q-item-label> 关联的设备 </q-item-label>
|
||||
<div class="q-gutter-sm row">
|
||||
<q-chip
|
||||
v-for="item in axleCountingRelations"
|
||||
:key="item"
|
||||
square
|
||||
color="primary"
|
||||
text-color="white"
|
||||
>
|
||||
{{ item }}
|
||||
</q-chip>
|
||||
</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SlopeData } from 'src/drawApp/graphics/SlopeInteraction';
|
||||
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
|
||||
import { Slope } from 'src/graphics/slope/Slope';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const slopeModel = reactive(new SlopeData());
|
||||
const direction = ref('');
|
||||
const optionsDirection = ['上坡', '下坡', '无坡度'];
|
||||
enum showSelect {
|
||||
上坡 = 'up',
|
||||
下坡 = 'down',
|
||||
无坡度 = 'none',
|
||||
}
|
||||
enum showSelectData {
|
||||
up = '上坡',
|
||||
down = '下坡',
|
||||
none = '无坡度',
|
||||
}
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Slope.Type) {
|
||||
slopeModel.copyFrom(val.saveData() as SlopeData);
|
||||
direction.value = (showSelectData as never)[slopeModel.slopeDirection];
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const slope = drawStore.selectedGraphic as Slope;
|
||||
if (slope) {
|
||||
slopeModel.copyFrom(slope.saveData());
|
||||
direction.value = (showSelectData as never)[slopeModel.slopeDirection];
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
slopeModel.slopeDirection = (showSelect as never)[direction.value];
|
||||
const slope = drawStore.selectedGraphic as Slope;
|
||||
if (slope) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(slope, slopeModel);
|
||||
}
|
||||
}
|
||||
|
||||
const axleCountingRelations = computed(() => {
|
||||
const slope = drawStore.selectedGraphic as Slope;
|
||||
const sectionRelations =
|
||||
slope?.relationManage.getRelationsOfGraphicAndOtherType(
|
||||
slope,
|
||||
AxleCounting.Type
|
||||
);
|
||||
const ref = sectionRelations.map(
|
||||
(relation) => `${relation.getOtherGraphic<AxleCounting>(slope).datas.code}`
|
||||
);
|
||||
return Array.from(new Set(ref));
|
||||
});
|
||||
</script>
|
@ -42,25 +42,42 @@
|
||||
@blur="onUpdate"
|
||||
label="公里标(mm):"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
style="margin-top: 10px"
|
||||
v-model="refDevData.id"
|
||||
:options="sectionList"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@update:model-value="onUpdate"
|
||||
label="关联设备"
|
||||
></q-select>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { StopPositionData } from 'src/drawApp/graphics/StopPositionInteraction';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { StopPosition, CoachNum } from 'src/graphics/stopPosition/StopPosition';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const stopPositionModel = reactive(new StopPositionData());
|
||||
const kilometerSystem = reactive({ coordinateSystem: '', kilometer: 0 });
|
||||
|
||||
const refDevData = reactive({
|
||||
id: '',
|
||||
deviceType: graphicData.RelatedRef.DeviceType.Section,
|
||||
devicePort: graphicData.RelatedRef.DevicePort.A,
|
||||
});
|
||||
const CoordinateSystemOptions = [
|
||||
{ label: '车辆段', value: 'DEPOT' },
|
||||
{ label: '停车场', value: 'PARKING_LOT' },
|
||||
{ label: '正线', value: 'MAIN_LINE' },
|
||||
{ label: '换线', value: 'TRANSFER' },
|
||||
];
|
||||
const sectionList: { label: string; value: string }[] = reactive([]);
|
||||
const optionsCoachNum = [
|
||||
{
|
||||
label: 4,
|
||||
@ -73,12 +90,7 @@ watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == StopPosition.Type) {
|
||||
stopPositionModel.copyFrom(val.saveData() as StopPositionData);
|
||||
if (stopPositionModel.kilometerSystem) {
|
||||
kilometerSystem.coordinateSystem =
|
||||
stopPositionModel.kilometerSystem.coordinateSystem;
|
||||
kilometerSystem.kilometer = stopPositionModel.kilometerSystem.kilometer;
|
||||
}
|
||||
initRefData(val as StopPosition);
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -86,21 +98,44 @@ watch(
|
||||
onMounted(() => {
|
||||
const stopPosition = drawStore.selectedGraphic as StopPosition;
|
||||
if (stopPosition) {
|
||||
stopPositionModel.copyFrom(stopPosition.saveData());
|
||||
if (stopPositionModel.kilometerSystem) {
|
||||
kilometerSystem.coordinateSystem =
|
||||
stopPositionModel.kilometerSystem.coordinateSystem;
|
||||
kilometerSystem.kilometer = stopPositionModel.kilometerSystem.kilometer;
|
||||
}
|
||||
const sections = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Section>(Section.Type);
|
||||
sections.forEach((sec) => {
|
||||
sectionList.push({
|
||||
label: `${sec.datas.code}[${sec.datas.index}]`,
|
||||
value: sec.datas.id,
|
||||
});
|
||||
});
|
||||
initRefData(stopPosition);
|
||||
}
|
||||
});
|
||||
|
||||
function initRefData(stopPosition: StopPosition) {
|
||||
stopPositionModel.copyFrom(stopPosition.saveData());
|
||||
if (stopPositionModel.kilometerSystem) {
|
||||
kilometerSystem.coordinateSystem =
|
||||
stopPositionModel.kilometerSystem.coordinateSystem;
|
||||
kilometerSystem.kilometer = stopPositionModel.kilometerSystem.kilometer;
|
||||
}
|
||||
if (stopPositionModel.refDev) {
|
||||
refDevData.id = stopPositionModel.refDev.id;
|
||||
}
|
||||
}
|
||||
|
||||
function onUpdate() {
|
||||
const stopPosition = drawStore.selectedGraphic as StopPosition;
|
||||
stopPositionModel.kilometerSystem = {
|
||||
coordinateSystem: kilometerSystem.coordinateSystem,
|
||||
kilometer: kilometerSystem.kilometer,
|
||||
};
|
||||
if (refDevData.id) {
|
||||
stopPositionModel.refDev = new graphicData.RelatedRef({
|
||||
id: refDevData.id,
|
||||
deviceType: refDevData.deviceType,
|
||||
devicePort: refDevData.devicePort,
|
||||
});
|
||||
}
|
||||
if (stopPosition) {
|
||||
drawStore
|
||||
.getDrawApp()
|
||||
|
@ -57,6 +57,12 @@ export class SignalData extends GraphicDataBase implements ISignalData {
|
||||
set index(v: number) {
|
||||
this.data.index = v;
|
||||
}
|
||||
get refDev(): graphicData.RelatedRef {
|
||||
return this.data.refDev;
|
||||
}
|
||||
set refDev(v: graphicData.RelatedRef) {
|
||||
this.data.refDev = v;
|
||||
}
|
||||
clone(): SignalData {
|
||||
return new SignalData(this.data.cloneMessage());
|
||||
}
|
||||
|
70
src/drawApp/graphics/SlopeInteraction.ts
Normal file
70
src/drawApp/graphics/SlopeInteraction.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
import { ISlopeData, Slope } from 'src/graphics/slope/Slope';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { IPointData } from 'pixi.js';
|
||||
|
||||
export class SlopeData extends GraphicDataBase implements ISlopeData {
|
||||
constructor(data?: graphicData.Slope) {
|
||||
let slope;
|
||||
if (!data) {
|
||||
slope = new graphicData.Slope({
|
||||
common: GraphicDataBase.defaultCommonInfo(Slope.Type),
|
||||
});
|
||||
} else {
|
||||
slope = data;
|
||||
}
|
||||
super(slope);
|
||||
}
|
||||
public get data(): graphicData.Slope {
|
||||
return this.getData<graphicData.Slope>();
|
||||
}
|
||||
get code(): string {
|
||||
return this.data.code;
|
||||
}
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get points(): IPointData[] {
|
||||
return this.data.points;
|
||||
}
|
||||
set points(points: IPointData[]) {
|
||||
this.data.points = points.map(
|
||||
(p) => new graphicData.Point({ x: p.x, y: p.y })
|
||||
);
|
||||
}
|
||||
get slopeNumber(): string {
|
||||
return this.data.slopeNumber;
|
||||
}
|
||||
set slopeNumber(v: string) {
|
||||
this.data.slopeNumber = v;
|
||||
}
|
||||
get slopeDirection(): string {
|
||||
return this.data.slopeDirection;
|
||||
}
|
||||
set slopeDirection(v: string) {
|
||||
this.data.slopeDirection = v;
|
||||
}
|
||||
get slopeLong(): number {
|
||||
return this.data.slopeLong;
|
||||
}
|
||||
set slopeLong(v: number) {
|
||||
this.data.slopeLong = v;
|
||||
}
|
||||
get refDeviceId(): string[] {
|
||||
return this.data.refDeviceId;
|
||||
}
|
||||
set refDeviceId(v: string[]) {
|
||||
this.data.refDeviceId = v;
|
||||
}
|
||||
|
||||
clone(): SlopeData {
|
||||
return new SlopeData(this.data.cloneMessage());
|
||||
}
|
||||
copyFrom(data: SlopeData): void {
|
||||
pb_1.Message.copyInto(data.data, this.data);
|
||||
}
|
||||
eq(other: SlopeData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
@ -62,6 +62,12 @@ export class StopPositionData extends GraphicDataBase implements IStopPosition {
|
||||
set kilometerSystem(v: KilometerSystem) {
|
||||
this.data.kilometerSystem = new graphicData.KilometerSystem(v);
|
||||
}
|
||||
get refDev(): graphicData.RelatedRef {
|
||||
return this.data.refDev;
|
||||
}
|
||||
set refDev(v: graphicData.RelatedRef) {
|
||||
this.data.refDev = v;
|
||||
}
|
||||
clone(): StopPositionData {
|
||||
return new StopPositionData(this.data.cloneMessage());
|
||||
}
|
||||
|
@ -117,6 +117,10 @@ import {
|
||||
SlopeKiloMarkerTemplate,
|
||||
} from 'src/graphics/slopeKiloMarker/SlopeKiloMarker';
|
||||
import { SlopeKiloMarkerData } from './graphics/SlopeKiloMarkerInteraction';
|
||||
import { SlopeDraw } from 'src/graphics/slope/SlopeAssistant';
|
||||
import { SlopeData } from './graphics/SlopeInteraction';
|
||||
import { Slope, SlopeTemplate } from 'src/graphics/slope/Slope';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
|
||||
// export function fromStoragePoint(p: graphicData.Point): Point {
|
||||
// return new Point(p.x, p.y);
|
||||
@ -157,49 +161,8 @@ const RedoOptions: MenuItemOptions = {
|
||||
const SelectAllOptions: MenuItemOptions = {
|
||||
name: '全选',
|
||||
};
|
||||
const AllOptions: MenuItemOptions = {
|
||||
name: '全部图层',
|
||||
};
|
||||
const physicalSection: MenuItemOptions = {
|
||||
name: '图层-物理区段',
|
||||
};
|
||||
const linkOptions: MenuItemOptions = {
|
||||
name: '图层-Link',
|
||||
};
|
||||
const axleCountingSectionOptions: MenuItemOptions = {
|
||||
name: '图层-计轴区段',
|
||||
};
|
||||
const LogicSectionOptions: MenuItemOptions = {
|
||||
name: '图层-逻辑区段',
|
||||
};
|
||||
// [
|
||||
// {
|
||||
// name: '图层菜单',
|
||||
// items: [
|
||||
// AllOptions,
|
||||
// linkOptions,
|
||||
// axleCountingSectionOptions,
|
||||
// LogicSectionOptions,
|
||||
// ],
|
||||
// },
|
||||
// ]
|
||||
const layerOptions: MenuItemOptions = {
|
||||
name: '图层',
|
||||
subMenu: {
|
||||
name: '图层菜单',
|
||||
groups: [
|
||||
{
|
||||
name: '图层菜单',
|
||||
items: [
|
||||
AllOptions,
|
||||
physicalSection,
|
||||
linkOptions,
|
||||
axleCountingSectionOptions,
|
||||
LogicSectionOptions,
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
name: '显示控制',
|
||||
};
|
||||
|
||||
export const DefaultCanvasMenu = new ContextMenu({
|
||||
@ -230,6 +193,43 @@ export function destroyDrawApp(): void {
|
||||
}
|
||||
}
|
||||
|
||||
const showType = [
|
||||
// 默认显示的图层
|
||||
Section.Type,
|
||||
AxleCounting.Type,
|
||||
Platform.Type,
|
||||
Station.Type,
|
||||
Turnout.Type,
|
||||
Signal.Type,
|
||||
Separator.Type,
|
||||
StopPosition.Type,
|
||||
SpksSwitch.Type,
|
||||
GatedBox.Type,
|
||||
EsbButton.Type,
|
||||
Transponder.Type,
|
||||
TrainWindow.Type,
|
||||
Slope.Type,
|
||||
];
|
||||
export const drawLayerList = [
|
||||
// 图层列表
|
||||
{ label: '区段', value: Section.Type },
|
||||
{ label: 'link', value: SectionLink.Type },
|
||||
{ label: '计轴', value: AxleCounting.Type },
|
||||
{ label: '站台', value: Platform.Type },
|
||||
{ label: '车站', value: Station.Type },
|
||||
{ label: '道岔', value: Turnout.Type },
|
||||
{ label: '信号机', value: Signal.Type },
|
||||
{ label: '分隔符', value: Separator.Type },
|
||||
{ label: '停车位置标', value: StopPosition.Type },
|
||||
{ label: 'Spks开关', value: SpksSwitch.Type },
|
||||
{ label: '门控箱', value: GatedBox.Type },
|
||||
{ label: '紧急关闭按钮', value: EsbButton.Type },
|
||||
{ label: '应答器', value: Transponder.Type },
|
||||
{ label: '车次窗', value: TrainWindow.Type },
|
||||
{ label: '计轴区段', value: AxleCountingSection.Type },
|
||||
{ label: '逻辑区段', value: LogicSection.Type },
|
||||
];
|
||||
|
||||
export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
drawApp = new JlDrawApp(dom);
|
||||
const app = drawApp;
|
||||
@ -255,6 +255,7 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
| EsbButtonDraw
|
||||
| TransponderDraw
|
||||
| SlopeKiloMarkerDrawAssistant
|
||||
| SlopeDraw
|
||||
)[] = [];
|
||||
if (draftType === 'Line') {
|
||||
drawAssistants = [
|
||||
@ -304,6 +305,7 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
app,
|
||||
new SlopeKiloMarkerTemplate(new SlopeKiloMarkerData())
|
||||
),
|
||||
new SlopeDraw(app, new SlopeTemplate(new SlopeData())),
|
||||
];
|
||||
DrawSignalInteraction.init(app);
|
||||
DrawStopPositionInteraction.init(app);
|
||||
@ -330,23 +332,7 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
if (app._drawing) return;
|
||||
UndoOptions.disabled = !app.opRecord.hasUndo;
|
||||
RedoOptions.disabled = !app.opRecord.hasRedo;
|
||||
const axleCountingSections =
|
||||
app.queryStore.queryByType<AxleCountingSection>(AxleCountingSection.Type);
|
||||
const logicSections = app.queryStore.queryByType<LogicSection>(
|
||||
LogicSection.Type
|
||||
);
|
||||
const sections = app.queryStore.queryByType<Section>(Section.Type);
|
||||
const sectionLinks = app.queryStore.queryByType<SectionLink>(
|
||||
SectionLink.Type
|
||||
);
|
||||
const turnouts = app.queryStore.queryByType<Turnout>(Turnout.Type);
|
||||
const disvisibleGraphics = [
|
||||
...sections,
|
||||
...turnouts,
|
||||
...sectionLinks,
|
||||
...axleCountingSections,
|
||||
...logicSections,
|
||||
];
|
||||
|
||||
UndoOptions.handler = () => {
|
||||
app.opRecord.undo();
|
||||
};
|
||||
@ -356,45 +342,9 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
SelectAllOptions.handler = () => {
|
||||
app.selectAllGraphics();
|
||||
};
|
||||
AllOptions.handler = () => {
|
||||
disvisibleGraphics.forEach((g) => {
|
||||
g.visible = true;
|
||||
});
|
||||
};
|
||||
physicalSection.handler = () => {
|
||||
disvisibleGraphics.forEach((g) => {
|
||||
g.visible = false;
|
||||
});
|
||||
sections.forEach((axleCountingSection) => {
|
||||
axleCountingSection.visible = true;
|
||||
});
|
||||
turnouts.forEach((axleCountingSection) => {
|
||||
axleCountingSection.visible = true;
|
||||
});
|
||||
};
|
||||
linkOptions.handler = () => {
|
||||
disvisibleGraphics.forEach((g) => {
|
||||
g.visible = false;
|
||||
});
|
||||
sectionLinks.forEach((axleCountingSection) => {
|
||||
axleCountingSection.visible = true;
|
||||
});
|
||||
};
|
||||
axleCountingSectionOptions.handler = () => {
|
||||
disvisibleGraphics.forEach((g) => {
|
||||
g.visible = false;
|
||||
});
|
||||
axleCountingSections.forEach((axleCountingSection) => {
|
||||
axleCountingSection.visible = true;
|
||||
});
|
||||
};
|
||||
LogicSectionOptions.handler = () => {
|
||||
disvisibleGraphics.forEach((g) => {
|
||||
g.visible = false;
|
||||
});
|
||||
logicSections.forEach((logicSection) => {
|
||||
logicSection.visible = true;
|
||||
});
|
||||
const lineStore = useLineStore();
|
||||
layerOptions.handler = () => {
|
||||
lineStore.setShowLayerDialog(true);
|
||||
};
|
||||
DefaultCanvasMenu.open(e.global);
|
||||
});
|
||||
@ -521,6 +471,9 @@ export function saveDrawDatas(app: JlDrawApp) {
|
||||
storage.slopeKiloMarker.push(
|
||||
(slopeKiloMarkerData as SlopeKiloMarkerData).data
|
||||
);
|
||||
} else if (Slope.Type === g.type) {
|
||||
const slopeData = (g as Slope).saveData();
|
||||
storage.slopes.push((slopeData as SlopeData).data);
|
||||
}
|
||||
});
|
||||
const base64 = fromUint8Array(storage.serialize());
|
||||
@ -607,27 +560,21 @@ export async function loadDrawDatas(app: GraphicApp) {
|
||||
storage.slopeKiloMarker.forEach((slopeKiloMarker) => {
|
||||
datas.push(new SlopeKiloMarkerData(slopeKiloMarker));
|
||||
});
|
||||
storage.slopes.forEach((slope) => {
|
||||
datas.push(new SlopeData(slope));
|
||||
});
|
||||
await app.loadGraphic(datas);
|
||||
} else {
|
||||
app.loadGraphic([]);
|
||||
}
|
||||
//隐藏计轴区段--Link
|
||||
const axleCountingSections = app.queryStore.queryByType<AxleCountingSection>(
|
||||
AxleCountingSection.Type
|
||||
);
|
||||
axleCountingSections.forEach((axleCountingSection) => {
|
||||
axleCountingSection.visible = false;
|
||||
});
|
||||
const sectionLinks = app.queryStore.queryByType<SectionLink>(
|
||||
SectionLink.Type
|
||||
);
|
||||
sectionLinks.forEach((sectionLink) => {
|
||||
sectionLink.visible = false;
|
||||
});
|
||||
const logicSections = app.queryStore.queryByType<LogicSection>(
|
||||
LogicSection.Type
|
||||
);
|
||||
logicSections.forEach((logicSection) => {
|
||||
logicSection.visible = false;
|
||||
const lineStore = useLineStore();
|
||||
const alllGraphic = app.queryStore.getAllGraphics();
|
||||
alllGraphic.forEach((g) => {
|
||||
if (showType.includes(g.type)) {
|
||||
g.visible = true;
|
||||
} else {
|
||||
g.visible = false;
|
||||
}
|
||||
});
|
||||
lineStore.setShowLayer(showType);
|
||||
}
|
||||
|
@ -116,6 +116,8 @@ const DefaultCanvasMenu = new ContextMenu({
|
||||
],
|
||||
});
|
||||
const showType = [
|
||||
// 默认显示的图层
|
||||
Section.Type,
|
||||
Platform.Type,
|
||||
Station.Type,
|
||||
Turnout.Type,
|
||||
@ -128,9 +130,9 @@ const showType = [
|
||||
EsbButton.Type,
|
||||
Transponder.Type,
|
||||
];
|
||||
const physicShowType = [...showType, Section.Type];
|
||||
|
||||
export const layerList = [
|
||||
// 图层列表
|
||||
{ label: '区段', value: Section.Type },
|
||||
{ label: 'link', value: SectionLink.Type },
|
||||
{ label: '计轴', value: AxleCounting.Type },
|
||||
@ -280,7 +282,7 @@ export async function loadLineDatas(app: GraphicApp) {
|
||||
|
||||
const alllGraphic = (lineApp as GraphicApp).queryStore.getAllGraphics();
|
||||
alllGraphic.forEach((g) => {
|
||||
if (physicShowType.includes(g.type)) {
|
||||
if (showType.includes(g.type)) {
|
||||
g.visible = true;
|
||||
} else {
|
||||
g.visible = false;
|
||||
@ -290,7 +292,7 @@ export async function loadLineDatas(app: GraphicApp) {
|
||||
(g as Transponder).labelGraphic.visible = false;
|
||||
}
|
||||
});
|
||||
lineStore.setShowLayer(physicShowType);
|
||||
lineStore.setShowLayer(showType);
|
||||
app.enableWsMassaging({
|
||||
engine: ClientEngine.Centrifugo,
|
||||
wsUrl: `${getWebsocketUrl()}`,
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
} from 'src/jl-graphic';
|
||||
import { calculateMirrorPoint } from 'src/jl-graphic';
|
||||
import { LampMainBody } from './LampMainBody';
|
||||
import { drawArrow } from '../CommonGraphics';
|
||||
import { drawArrow, IRelatedRefData } from '../CommonGraphics';
|
||||
import { SignalCode } from './SignalCode';
|
||||
|
||||
export interface KilometerSystem {
|
||||
@ -16,7 +16,6 @@ export interface KilometerSystem {
|
||||
get kilometer(): number;
|
||||
set kilometer(v: number);
|
||||
}
|
||||
|
||||
export interface ISignalData extends GraphicData {
|
||||
get code(): string; // 编号
|
||||
set code(v: string);
|
||||
@ -26,6 +25,8 @@ export interface ISignalData extends GraphicData {
|
||||
set kilometerSystem(v: KilometerSystem);
|
||||
get index(): number;
|
||||
set index(v: number);
|
||||
get refDev(): IRelatedRefData;
|
||||
set refDev(v: IRelatedRefData);
|
||||
clone(): ISignalData;
|
||||
copyFrom(data: ISignalData): void;
|
||||
eq(other: ISignalData): boolean;
|
||||
|
152
src/graphics/slope/Slope.ts
Normal file
152
src/graphics/slope/Slope.ts
Normal file
@ -0,0 +1,152 @@
|
||||
import { Graphics, IPointData } from 'pixi.js';
|
||||
import {
|
||||
GraphicData,
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
VectorText,
|
||||
calculateLineMidpoint,
|
||||
} from 'src/jl-graphic';
|
||||
|
||||
export interface ITurnoutPosRefData {
|
||||
get id(): string; //道岔的ID
|
||||
set id(v: string);
|
||||
get position(): number; //道岔的正反为,0是正位,1是反位
|
||||
set position(v: number);
|
||||
}
|
||||
|
||||
export interface ISlopeData extends GraphicData {
|
||||
get code(): string; // 名称
|
||||
set code(v: string);
|
||||
get points(): IPointData[]; // 线坐标点
|
||||
set points(points: IPointData[]);
|
||||
get slopeNumber(): string; // 坡度的值
|
||||
set slopeNumber(v: string);
|
||||
get slopeDirection(): string; //坡度方向 有三种,无坡度--上坡--下坡
|
||||
set slopeDirection(v: string);
|
||||
get slopeLong(): number; //该坡度的长度--两端公里标的差值
|
||||
set slopeLong(v: number);
|
||||
get refDeviceId(): string[]; // 坡度关联的设备id
|
||||
set refDeviceId(v: string[]);
|
||||
clone(): ISlopeData;
|
||||
copyFrom(data: ISlopeData): void;
|
||||
eq(other: ISlopeData): boolean;
|
||||
}
|
||||
|
||||
export const SlopeConsts = {
|
||||
lineColor: '0xffffff',
|
||||
lineWidth: 2,
|
||||
height: 40,
|
||||
};
|
||||
|
||||
export class Slope extends JlGraphic {
|
||||
static Type = 'Slope';
|
||||
lineGraphic: Graphics;
|
||||
slopeNumber: VectorText;
|
||||
slopeLong: VectorText;
|
||||
constructor() {
|
||||
super(Slope.Type);
|
||||
this.lineGraphic = new Graphics();
|
||||
this.slopeNumber = new VectorText();
|
||||
this.slopeNumber.name = 'slopeNumber';
|
||||
this.slopeLong = new VectorText();
|
||||
this.slopeLong.name = 'slopeLong';
|
||||
const vectorTexts = [this.slopeNumber, this.slopeLong];
|
||||
vectorTexts.forEach((vectorText) => {
|
||||
vectorText.setVectorFontSize(14);
|
||||
vectorText.anchor.set(0.5);
|
||||
vectorText.style.fill = '0xffffff';
|
||||
vectorText.transformSave = true;
|
||||
});
|
||||
this.transformSave = true;
|
||||
this.addChild(this.lineGraphic);
|
||||
this.addChild(this.slopeNumber);
|
||||
this.addChild(this.slopeLong);
|
||||
}
|
||||
|
||||
get datas(): ISlopeData {
|
||||
return this.getDatas<ISlopeData>();
|
||||
}
|
||||
doRepaint(): void {
|
||||
if (this.datas.points.length < 2) {
|
||||
throw new Error('Slope坐标数据异常');
|
||||
}
|
||||
this.lineGraphic.clear();
|
||||
this.lineGraphic.lineStyle(SlopeConsts.lineWidth, SlopeConsts.lineColor);
|
||||
let distanceY = 0;
|
||||
switch (this.datas.slopeDirection) {
|
||||
case 'up':
|
||||
distanceY = -SlopeConsts.height / 2;
|
||||
break;
|
||||
case 'down':
|
||||
distanceY = SlopeConsts.height / 2;
|
||||
break;
|
||||
}
|
||||
this.datas.points.forEach((p, i) => {
|
||||
if (i !== 0) {
|
||||
this.lineGraphic.lineTo(p.x, p.y + distanceY);
|
||||
} else {
|
||||
this.lineGraphic.moveTo(p.x, p.y - distanceY);
|
||||
}
|
||||
});
|
||||
//坡度值
|
||||
this.slopeNumber.text = this.datas.slopeNumber;
|
||||
const slopeNumberPosition = this.datas.childTransforms?.find(
|
||||
(t) => t.name === this.slopeNumber.name
|
||||
)?.transform.position;
|
||||
if (slopeNumberPosition) {
|
||||
this.slopeNumber.position.set(
|
||||
slopeNumberPosition.x,
|
||||
slopeNumberPosition.y
|
||||
);
|
||||
} else {
|
||||
const centerPos = calculateLineMidpoint(
|
||||
this.datas.points[0],
|
||||
this.datas.points[this.datas.points.length - 1]
|
||||
);
|
||||
this.slopeNumber.position.set(centerPos.x, centerPos.y - 15);
|
||||
}
|
||||
//坡度长度
|
||||
this.slopeLong.text = this.datas.slopeLong;
|
||||
const slopeLongPosition = this.datas.childTransforms?.find(
|
||||
(t) => t.name === this.slopeLong.name
|
||||
)?.transform.position;
|
||||
if (slopeLongPosition) {
|
||||
this.slopeLong.position.set(slopeLongPosition.x, slopeLongPosition.y);
|
||||
} else {
|
||||
const centerPos = calculateLineMidpoint(
|
||||
this.datas.points[0],
|
||||
this.datas.points[this.datas.points.length - 1]
|
||||
);
|
||||
this.slopeLong.position.set(centerPos.x, centerPos.y + 15);
|
||||
}
|
||||
}
|
||||
get linePoints(): IPointData[] {
|
||||
return this.datas.points;
|
||||
}
|
||||
set linePoints(points: IPointData[]) {
|
||||
const old = this.datas.clone();
|
||||
old.points = points;
|
||||
this.updateData(old);
|
||||
}
|
||||
loadRelations() {
|
||||
if (this.datas.refDeviceId.length) {
|
||||
this.datas.refDeviceId.forEach((id) => {
|
||||
const section = this.queryStore.queryById(id);
|
||||
this.relationManage.addRelation(this, section);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SlopeTemplate extends JlGraphicTemplate<Slope> {
|
||||
constructor(dataTemplate: ISlopeData) {
|
||||
super(Slope.Type, {
|
||||
dataTemplate,
|
||||
});
|
||||
}
|
||||
new(): Slope {
|
||||
const slope = new Slope();
|
||||
slope.loadData(this.datas);
|
||||
return slope;
|
||||
}
|
||||
}
|
134
src/graphics/slope/SlopeAssistant.ts
Normal file
134
src/graphics/slope/SlopeAssistant.ts
Normal file
@ -0,0 +1,134 @@
|
||||
import { FederatedPointerEvent, IHitArea, Point } from 'pixi.js';
|
||||
import {
|
||||
GraphicDrawAssistant,
|
||||
GraphicIdGenerator,
|
||||
GraphicInteractionPlugin,
|
||||
JlDrawApp,
|
||||
JlGraphic,
|
||||
linePoint,
|
||||
} from 'src/jl-graphic';
|
||||
|
||||
import { ISlopeData, Slope, SlopeTemplate, SlopeConsts } from './Slope';
|
||||
import { AxleCounting } from '../axleCounting/AxleCounting';
|
||||
|
||||
export interface ISlopeDrawOptions {
|
||||
newData: () => ISlopeData;
|
||||
}
|
||||
export class SlopeDraw extends GraphicDrawAssistant<SlopeTemplate, ISlopeData> {
|
||||
codeGraph: Slope;
|
||||
constructor(app: JlDrawApp, template: SlopeTemplate) {
|
||||
super(app, template, 'sym_o_circle', '不展示');
|
||||
this.codeGraph = this.graphicTemplate.new();
|
||||
this.container.addChild(this.codeGraph);
|
||||
SlopeInteraction.init(app);
|
||||
}
|
||||
|
||||
bind(): void {
|
||||
super.bind();
|
||||
this.codeGraph.loadData(this.graphicTemplate.datas);
|
||||
this.codeGraph.doRepaint();
|
||||
}
|
||||
|
||||
clearCache(): void {
|
||||
//this.codeGraph.destroy();
|
||||
}
|
||||
onLeftDown(e: FederatedPointerEvent): void {
|
||||
this.container.position.copyFrom(this.toCanvasCoordinates(e.global));
|
||||
this.createAndStore(true);
|
||||
}
|
||||
|
||||
redraw(p: Point): void {
|
||||
this.container.position.copyFrom(p);
|
||||
}
|
||||
prepareData(data: ISlopeData): boolean {
|
||||
data.transform = this.container.saveTransform();
|
||||
return true;
|
||||
}
|
||||
draw(graphics: AxleCounting[], map: Map<string, number>) {
|
||||
if (
|
||||
map.has(`${graphics[0].id}+${graphics[1].id}`) ||
|
||||
map.has(`${graphics[1].id}+${graphics[0].id}`)
|
||||
)
|
||||
return;
|
||||
map.set(`${graphics[0].id}+${graphics[1].id}`, 1);
|
||||
const slope = new Slope();
|
||||
slope.loadData(this.graphicTemplate.datas);
|
||||
slope.datas.points = [graphics[0].position, graphics[1].position];
|
||||
slope.id = GraphicIdGenerator.next();
|
||||
slope.datas.refDeviceId = [graphics[0].id, graphics[1].id];
|
||||
this.storeGraphic(slope);
|
||||
slope.loadRelations();
|
||||
}
|
||||
oneGenerates() {
|
||||
const map = new Map();
|
||||
const slopes = this.app.queryStore.queryByType<Slope>(Slope.Type);
|
||||
const axleCountings = this.app.queryStore.queryByType<AxleCounting>(
|
||||
AxleCounting.Type
|
||||
);
|
||||
axleCountings.sort((a, b) => a.position.x - b.position.x);
|
||||
const axleCountingsPos = axleCountings.map((g) => g.position.x);
|
||||
//检验坡度有效性--是否有增加和删除
|
||||
slopes.forEach((slope) => {
|
||||
const pS = slope.datas.points[0].x;
|
||||
const mapS = axleCountingsPos.findIndex((x) => x == pS);
|
||||
const pE = slope.datas.points[1].x;
|
||||
const mapE = axleCountingsPos.findIndex((x) => x == pE);
|
||||
if (mapS !== -1 && mapE !== -1 && mapE - mapS == 1) {
|
||||
map.set(
|
||||
`${slope.datas.refDeviceId[0]}+${slope.datas.refDeviceId[1]}`,
|
||||
1
|
||||
);
|
||||
} else {
|
||||
this.app.deleteGraphics(slope);
|
||||
}
|
||||
});
|
||||
for (let i = 0; i < axleCountings.length - 1; i++) {
|
||||
this.draw([axleCountings[i], axleCountings[i + 1]], map);
|
||||
}
|
||||
}
|
||||
}
|
||||
class SlopeGraphicHitArea implements IHitArea {
|
||||
slope: Slope;
|
||||
constructor(slope: Slope) {
|
||||
this.slope = slope;
|
||||
}
|
||||
contains(x: number, y: number): boolean {
|
||||
for (let i = 1; i < this.slope.datas.points.length; i++) {
|
||||
const p1 = this.slope.datas.points[i - 1];
|
||||
const p2 = this.slope.datas.points[i];
|
||||
if (linePoint(p1, p2, { x, y }, SlopeConsts.lineWidth)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class SlopeInteraction extends GraphicInteractionPlugin<Slope> {
|
||||
static Name = 'Slope_transform';
|
||||
constructor(app: JlDrawApp) {
|
||||
super(SlopeInteraction.Name, app);
|
||||
}
|
||||
static init(app: JlDrawApp) {
|
||||
return new SlopeInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Slope[] | undefined {
|
||||
return grahpics.filter((g) => g.type === Slope.Type).map((g) => g as Slope);
|
||||
}
|
||||
bind(g: Slope): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.scalable = true;
|
||||
g.transformSave = true;
|
||||
g.lineGraphic.eventMode = 'static';
|
||||
g.lineGraphic.cursor = 'pointer';
|
||||
g.lineGraphic.hitArea = new SlopeGraphicHitArea(g);
|
||||
}
|
||||
unbind(g: Slope): void {
|
||||
g.eventMode = 'none';
|
||||
g.lineGraphic.eventMode = 'none';
|
||||
g.lineGraphic.draggable = false;
|
||||
g.lineGraphic.selectable = false;
|
||||
g.lineGraphic.transformSave = false;
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import {
|
||||
JlGraphicTemplate,
|
||||
VectorText,
|
||||
} from 'src/jl-graphic';
|
||||
import { IRelatedRefData } from '../CommonGraphics';
|
||||
|
||||
export enum CoachNum {
|
||||
Four = 0,
|
||||
@ -17,7 +18,6 @@ export interface KilometerSystem {
|
||||
get kilometer(): number;
|
||||
set kilometer(v: number);
|
||||
}
|
||||
|
||||
export interface IStopPosition extends GraphicData {
|
||||
get code(): string;
|
||||
set code(v: string);
|
||||
@ -29,6 +29,8 @@ export interface IStopPosition extends GraphicData {
|
||||
set index(v: number);
|
||||
get kilometerSystem(): KilometerSystem;
|
||||
set kilometerSystem(v: KilometerSystem);
|
||||
get refDev(): IRelatedRefData;
|
||||
set refDev(v: IRelatedRefData);
|
||||
clone(): IStopPosition;
|
||||
copyFrom(data: IStopPosition): void;
|
||||
eq(other: IStopPosition): boolean;
|
||||
|
@ -43,6 +43,9 @@
|
||||
<q-item clickable v-close-popup @click="oneClickLogicSection">
|
||||
<q-item-section>一键生成逻辑区段</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="oneClickSlope">
|
||||
<q-item-section>一键生成坡度</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
@ -206,6 +209,13 @@
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
<LayerControlDialog
|
||||
:showLayer="lineStore.showLayer"
|
||||
:layerList="drawLayerList"
|
||||
:showDialog="lineStore.showLayerDialog"
|
||||
@setShowLayer="setShowLayer"
|
||||
@onDialogClose="onDialogClose"
|
||||
></LayerControlDialog>
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
@ -236,7 +246,12 @@ import { SectionDraw } from 'src/graphics/section/SectionDrawAssistant';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { LogicSection } from 'src/graphics/logicSection/LogicSection';
|
||||
import { LogicSectionDraw } from 'src/graphics/logicSection/LogicSectionDrawAssistant';
|
||||
import { Slope } from 'src/graphics/slope/Slope';
|
||||
import { SlopeDraw } from 'src/graphics/slope/SlopeAssistant';
|
||||
import { useQuasar } from 'quasar';
|
||||
import LayerControlDialog from 'src/components/draw-app/dialogs/LayerControlDialog.vue';
|
||||
import { drawLayerList } from 'src/drawApp/index';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
@ -244,6 +259,7 @@ const router = useRouter();
|
||||
const searchId = ref('');
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const lineStore = useLineStore();
|
||||
|
||||
watch(
|
||||
() => drawStore.drawMode,
|
||||
@ -419,6 +435,13 @@ function oneClickLogicSection() {
|
||||
.getDrawAssistant(LogicSection.Type) as LogicSectionDraw;
|
||||
logicSectionDraw.oneGenerates();
|
||||
}
|
||||
function oneClickSlope() {
|
||||
//一键生成坡度
|
||||
const slopeDraw = drawStore
|
||||
.getDrawApp()
|
||||
.getDrawAssistant(Slope.Type) as SlopeDraw;
|
||||
slopeDraw.oneGenerates();
|
||||
}
|
||||
function oneClickLink() {
|
||||
drawStore.oneClickType = 'SectionLink';
|
||||
const draw = drawStore
|
||||
@ -462,4 +485,20 @@ async function saveAs(name: string) {
|
||||
onUnmounted(() => {
|
||||
drawStore.destroy();
|
||||
});
|
||||
|
||||
function setShowLayer(val: string[]) {
|
||||
lineStore.setShowLayer(val);
|
||||
const drawApp = drawStore.getDrawApp();
|
||||
const alllGraphic = drawApp.queryStore.getAllGraphics();
|
||||
alllGraphic.forEach((g) => {
|
||||
if (val.includes(g.type)) {
|
||||
g.visible = true;
|
||||
} else {
|
||||
g.visible = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
function onDialogClose() {
|
||||
lineStore.setShowLayerDialog(false);
|
||||
}
|
||||
</script>
|
||||
|
@ -21,7 +21,13 @@
|
||||
<q-page-container>
|
||||
<div id="line-app-container"></div>
|
||||
</q-page-container>
|
||||
<LayerControlDialog></LayerControlDialog>
|
||||
<LayerControlDialog
|
||||
:showLayer="lineStore.showLayer"
|
||||
:layerList="layerList"
|
||||
:showDialog="lineStore.showLayerDialog"
|
||||
@setShowLayer="setShowLayer"
|
||||
@onDialogClose="onDialogClose"
|
||||
></LayerControlDialog>
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
@ -35,6 +41,7 @@ import StateProperties from 'src/components/line-app/StateProperties.vue';
|
||||
// import { Train } from 'src/graphics/train/Train';
|
||||
// import { Turnout } from 'src/graphics/turnout/Turnout';
|
||||
import LayerControlDialog from 'src/components/draw-app/dialogs/LayerControlDialog.vue';
|
||||
import { layerList } from 'src/drawApp/lineApp';
|
||||
|
||||
const canvasWidth = ref(0);
|
||||
const canvasHeight = ref(0);
|
||||
@ -103,4 +110,20 @@ watch(
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function setShowLayer(val: string[]) {
|
||||
lineStore.setShowLayer(val);
|
||||
const lineApp = lineStore.getLineApp();
|
||||
const alllGraphic = lineApp.queryStore.getAllGraphics();
|
||||
alllGraphic.forEach((g) => {
|
||||
if (val.includes(g.type)) {
|
||||
g.visible = true;
|
||||
} else {
|
||||
g.visible = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
function onDialogClose() {
|
||||
lineStore.setShowLayerDialog(false);
|
||||
}
|
||||
</script>
|
||||
|
271
src/pages/CategoryManage.vue
Normal file
271
src/pages/CategoryManage.vue
Normal file
@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<div class="q-pa-md">
|
||||
<q-table
|
||||
ref="tableRef"
|
||||
title="厂家信息"
|
||||
:style="{ height: tableHeight + 'px' }"
|
||||
:rows="rows"
|
||||
:columns="columnDefs"
|
||||
row-key="id"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[10, 20, 50, 100]"
|
||||
:loading="loading"
|
||||
:filter="filter"
|
||||
binary-state-sort
|
||||
@request="onRequest"
|
||||
>
|
||||
<template v-slot:top-right>
|
||||
<q-input
|
||||
dense
|
||||
debounce="1000"
|
||||
v-model="filter.name"
|
||||
label="名称"
|
||||
></q-input>
|
||||
<q-btn flat round color="primary" icon="search" />
|
||||
<q-btn color="primary" label="新建" @click="createFormShow = true" />
|
||||
</template>
|
||||
|
||||
<template v-slot:body-cell-operations="props">
|
||||
<q-td :props="props">
|
||||
<div class="q-gutter-sm row justify-center">
|
||||
<q-btn
|
||||
color="primary"
|
||||
:disable="operateDisabled"
|
||||
label="编辑"
|
||||
@click="editData(props.row)"
|
||||
/>
|
||||
<q-btn
|
||||
color="red"
|
||||
:disable="operateDisabled"
|
||||
label="删除"
|
||||
@click="deleteData(props.row)"
|
||||
/>
|
||||
</div>
|
||||
</q-td>
|
||||
</template>
|
||||
</q-table>
|
||||
|
||||
<q-dialog
|
||||
v-model="createFormShow"
|
||||
persistent
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-card style="width: 300px">
|
||||
<q-card-section>
|
||||
<q-form
|
||||
ref="myForm"
|
||||
@submit="onCreate"
|
||||
@reset="onReset"
|
||||
class="q-gutter-md"
|
||||
>
|
||||
<div class="text-h6">
|
||||
{{ editInfo.id ? '编辑厂家信息' : '新建厂家信息' }}
|
||||
</div>
|
||||
<q-input
|
||||
outlined
|
||||
label="名称"
|
||||
v-model="editInfo.categoryName"
|
||||
lazy-rules
|
||||
:rules="[(val) => val.length > 0 || '请输入名称!']"
|
||||
/>
|
||||
<q-input outlined label="配置" v-model="editInfo.config" />
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
color="primary"
|
||||
:label="editInfo.id ? '修改' : '创建'"
|
||||
type="submit"
|
||||
/>
|
||||
<q-btn label="取消" type="reset" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { useQuasar, type QTableColumn, QForm } from 'quasar';
|
||||
import {
|
||||
pageQuery,
|
||||
createCategory,
|
||||
deleteCategory,
|
||||
saveCategoryData,
|
||||
createParams,
|
||||
CategoryItem,
|
||||
getCategoryInfo,
|
||||
} from '../api/CategoryInfoApi';
|
||||
import { ApiError } from 'src/boot/axios';
|
||||
|
||||
const $q = useQuasar();
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
sizeHeight: number;
|
||||
}>(),
|
||||
{ sizeHeight: 500 }
|
||||
);
|
||||
|
||||
const tableHeight = computed(() => {
|
||||
return props.sizeHeight - 32;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
tableRef.value.requestServerInteraction();
|
||||
});
|
||||
|
||||
const columnDefs: QTableColumn[] = [
|
||||
{
|
||||
name: 'name',
|
||||
label: '名称',
|
||||
field: 'name',
|
||||
required: true,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'created_at',
|
||||
label: '创建时间',
|
||||
field: 'created_at',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'update_at',
|
||||
label: '更新时间',
|
||||
field: 'update_at',
|
||||
align: 'center',
|
||||
},
|
||||
{ name: 'operations', label: '操作', field: 'operations', align: 'center' },
|
||||
];
|
||||
|
||||
const operateDisabled = ref(false);
|
||||
const tableRef = ref();
|
||||
const rows = reactive([]);
|
||||
const filter = reactive({
|
||||
name: '',
|
||||
});
|
||||
const loading = ref(false);
|
||||
const pagination = ref({
|
||||
sortBy: 'desc',
|
||||
descending: false,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 10,
|
||||
});
|
||||
|
||||
async function onRequest(props: any) {
|
||||
const { page, rowsPerPage, sortBy, descending } = props.pagination;
|
||||
const filter = props.filter;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
let response = await pageQuery({
|
||||
current: page,
|
||||
size: rowsPerPage,
|
||||
name: filter.name,
|
||||
});
|
||||
const pageData = response;
|
||||
pagination.value.rowsNumber = pageData.total;
|
||||
pagination.value.page = page;
|
||||
pagination.value.rowsPerPage = rowsPerPage;
|
||||
pagination.value.sortBy = sortBy;
|
||||
pagination.value.descending = descending;
|
||||
rows.splice(0, rows.length, ...(pageData.records as []));
|
||||
} catch (err) {
|
||||
const error = err as ApiError;
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: error.title,
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
const createFormShow = ref(false);
|
||||
const myForm = ref<QForm | null>(null);
|
||||
function onCreate() {
|
||||
myForm.value?.validate().then(async (res) => {
|
||||
if (res) {
|
||||
operateDisabled.value = true;
|
||||
try {
|
||||
const params: createParams = {
|
||||
name: editInfo.categoryName,
|
||||
config: JSON.stringify(editInfo.config),
|
||||
};
|
||||
if (editInfo.id) {
|
||||
await saveCategoryData(+editInfo.id, params);
|
||||
} else {
|
||||
await createCategory(params);
|
||||
}
|
||||
onReset();
|
||||
createFormShow.value = false;
|
||||
tableRef.value.requestServerInteraction(); // 刷新列表
|
||||
} catch (err) {
|
||||
const error = err as ApiError;
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: error.title,
|
||||
});
|
||||
} finally {
|
||||
operateDisabled.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onReset() {
|
||||
editInfo.id = '';
|
||||
editInfo.categoryName = '';
|
||||
editInfo.config = '';
|
||||
myForm.value?.resetValidation();
|
||||
}
|
||||
|
||||
async function deleteData(row: CategoryItem) {
|
||||
operateDisabled.value = true;
|
||||
$q.dialog({
|
||||
title: '确认',
|
||||
message: `确认删除厂家 "${row.name}" 吗?`,
|
||||
cancel: true,
|
||||
})
|
||||
.onOk(async () => {
|
||||
try {
|
||||
await deleteCategory(row.id);
|
||||
tableRef.value.requestServerInteraction(); // 刷新列表
|
||||
} catch (err) {
|
||||
const error = err as ApiError;
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: error.title,
|
||||
});
|
||||
}
|
||||
})
|
||||
.onDismiss(() => {
|
||||
operateDisabled.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
const editInfo = reactive({
|
||||
id: '',
|
||||
categoryName: '',
|
||||
config: '',
|
||||
});
|
||||
function editData(row: CategoryItem) {
|
||||
getCategoryInfo(row.id)
|
||||
.then((res: CategoryItem) => {
|
||||
editInfo.id = res.id + '';
|
||||
editInfo.categoryName = res.name;
|
||||
editInfo.config = res.config ? JSON.parse(res.config) : '';
|
||||
createFormShow.value = true;
|
||||
})
|
||||
.catch((err) => {
|
||||
const error = err as ApiError;
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: error.title,
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
@ -58,30 +58,32 @@
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-card style="width: 300px">
|
||||
<q-form ref="myForm" @submit="onCreate" class="q-gutter-md">
|
||||
<q-card-section>
|
||||
<q-card-section>
|
||||
<q-form ref="myForm" @submit="onCreate" class="q-gutter-md">
|
||||
<div class="text-h6">新建草稿图</div>
|
||||
<q-input
|
||||
outlined
|
||||
label="名称"
|
||||
label="名称 * "
|
||||
v-model="draftName"
|
||||
lazy-rules
|
||||
:rules="[(val) => val.length > 0 || '请输入名称!']"
|
||||
/>
|
||||
<q-select
|
||||
v-model="createType"
|
||||
:options="typeOptions"
|
||||
v-model="categoryId"
|
||||
:options="categoryOptions"
|
||||
emit-value
|
||||
map-options
|
||||
label="类型 * "
|
||||
label="厂家 * "
|
||||
lazy-rules
|
||||
:rules="[(val) => val.length > 0 || '请选择厂家!']"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn color="primary" label="创建" type="submit" />
|
||||
<q-btn label="取消" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
<q-card-actions align="right">
|
||||
<q-btn color="primary" label="创建" type="submit" />
|
||||
<q-btn label="取消" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
@ -93,11 +95,8 @@
|
||||
>
|
||||
<q-card style="width: 300px">
|
||||
<q-card-section>
|
||||
<div class="text-h6">草稿发布</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-form ref="pubForm" @submit="publishGraphics" class="q-gutter-md">
|
||||
<q-card-section>
|
||||
<q-form ref="pubForm" @submit="publishGraphics" class="q-gutter-md">
|
||||
<div class="text-h6">草稿发布</div>
|
||||
<q-input
|
||||
outlined
|
||||
disable
|
||||
@ -111,23 +110,20 @@
|
||||
lazy-rules
|
||||
:rules="[(val) => val.length > 0 || '请输入名称!']"
|
||||
/>
|
||||
<!-- <q-select
|
||||
v-if="publishForm.type == 'Line'"
|
||||
v-model="publishForm.lineId"
|
||||
:options="lineOptions"
|
||||
emit-value
|
||||
map-options
|
||||
label="线路 * "
|
||||
<q-input
|
||||
outlined
|
||||
label="备注 * "
|
||||
v-model="publishForm.note"
|
||||
lazy-rules
|
||||
:rules="[(val) => val || '请选择线路!']"
|
||||
/> -->
|
||||
</q-card-section>
|
||||
:rules="[(val) => val.length > 0 || '请输入备注!']"
|
||||
/>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn color="primary" label="发布" type="submit" />
|
||||
<q-btn label="取消" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
<q-card-actions align="right">
|
||||
<q-btn color="primary" label="发布" type="submit" />
|
||||
<q-btn label="取消" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
@ -136,10 +132,20 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { useQuasar, type QTableColumn, QForm } from 'quasar';
|
||||
import { pageQuery, createDraft, deleteDraft } from '../api/DraftApi';
|
||||
import {
|
||||
pageQuery,
|
||||
createDraft,
|
||||
deleteDraft,
|
||||
DraftItem,
|
||||
} from '../api/DraftApi';
|
||||
import { publishDraft } from '../api/PublishApi';
|
||||
// import { getLineList } from '../api/LineInfoApi';
|
||||
import { ApiError } from 'src/boot/axios';
|
||||
import { CategoryItem, getCategoryList } from 'src/api/CategoryInfoApi';
|
||||
|
||||
interface OptionsItem {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
const $q = useQuasar();
|
||||
|
||||
@ -154,41 +160,9 @@ const tableHeight = computed(() => {
|
||||
return props.sizeHeight - 32;
|
||||
});
|
||||
|
||||
const typeOptions = [
|
||||
{ label: '线路', value: 'Line' },
|
||||
// { label: '线网', value: 'LineNetwork' },
|
||||
];
|
||||
const createType = ref('Line');
|
||||
|
||||
// let lineOptions: Array<{ label: string; value: number }> = [];
|
||||
// function getAllLineList() {
|
||||
// lineOptions = [];
|
||||
// getLineList()
|
||||
// .then((res) => {
|
||||
// res.forEach((item) => {
|
||||
// const obj = {
|
||||
// label: item.name,
|
||||
// value: item.lineId,
|
||||
// };
|
||||
// lineOptions.push(obj);
|
||||
// });
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log(err, '---err--');
|
||||
// });
|
||||
// }
|
||||
|
||||
// const typeOptionsMap = computed(() => {
|
||||
// const obj: { [k: string]: string } = {};
|
||||
// typeOptions.forEach((item: { value: string; label: string }) => {
|
||||
// obj[item.value] = item.label;
|
||||
// });
|
||||
// return obj;
|
||||
// });
|
||||
|
||||
onMounted(() => {
|
||||
tableRef.value.requestServerInteraction();
|
||||
// getAllLineList();
|
||||
getCategoryListFn();
|
||||
});
|
||||
|
||||
const columnDefs: QTableColumn[] = [
|
||||
@ -200,14 +174,14 @@ const columnDefs: QTableColumn[] = [
|
||||
align: 'center',
|
||||
},
|
||||
// { name: 'creator', label: '创建人', field: 'creator', align: 'center' },
|
||||
// {
|
||||
// name: 'type',
|
||||
// label: '类型',
|
||||
// field: (row) => {
|
||||
// return typeOptionsMap.value[row.type];
|
||||
// },
|
||||
// align: 'center',
|
||||
// },
|
||||
{
|
||||
name: 'category',
|
||||
label: '厂家',
|
||||
field: (row) => {
|
||||
return categoryName(row.category);
|
||||
},
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'created_at',
|
||||
label: '创建时间',
|
||||
@ -277,7 +251,7 @@ function onCreate() {
|
||||
try {
|
||||
await createDraft({
|
||||
name: draftName.value,
|
||||
type: createType.value,
|
||||
category: +categoryId.value,
|
||||
});
|
||||
createFormShow.value = false;
|
||||
tableRef.value.requestServerInteraction(); // 刷新列表
|
||||
@ -299,25 +273,23 @@ const publishForm = reactive({
|
||||
id: '',
|
||||
draftName: '',
|
||||
pubName: '',
|
||||
// lineId: '',
|
||||
type: 'Line',
|
||||
note: '',
|
||||
});
|
||||
function prePublish(row: any) {
|
||||
function prePublish(row: DraftItem) {
|
||||
publishFormShow.value = true;
|
||||
publishForm.id = row.id;
|
||||
publishForm.id = row.id + '';
|
||||
publishForm.draftName = row.name;
|
||||
publishForm.pubName = row.name;
|
||||
// publishForm.lineId = '';
|
||||
publishForm.type = row.type || 'Line';
|
||||
}
|
||||
|
||||
async function publishGraphics() {
|
||||
pubForm.value?.validate().then(async (res) => {
|
||||
if (res) {
|
||||
try {
|
||||
const params: { draftId: number; name: string; lineId?: number } = {
|
||||
const params: { draftId: number; name: string; note: string } = {
|
||||
draftId: +publishForm.id,
|
||||
name: publishForm.pubName,
|
||||
note: publishForm.note,
|
||||
};
|
||||
await publishDraft(params);
|
||||
publishFormShow.value = false;
|
||||
@ -336,7 +308,7 @@ async function publishGraphics() {
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteData(row: any) {
|
||||
async function deleteData(row: DraftItem) {
|
||||
operateDisabled.value = true;
|
||||
$q.dialog({
|
||||
title: '确认',
|
||||
@ -359,4 +331,28 @@ async function deleteData(row: any) {
|
||||
operateDisabled.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
const categoryOptions: OptionsItem[] = [];
|
||||
const categoryId = ref('');
|
||||
function categoryName(val?: number) {
|
||||
let n = '';
|
||||
if (val) {
|
||||
const find = categoryOptions.find((item) => {
|
||||
return item.value == val + '';
|
||||
});
|
||||
n = find ? find.label : '';
|
||||
}
|
||||
return n;
|
||||
}
|
||||
function getCategoryListFn() {
|
||||
getCategoryList()
|
||||
.then((res: CategoryItem[]) => {
|
||||
res.forEach((item) => {
|
||||
categoryOptions.push({ label: item.name, value: item.id + '' });
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err, '获取厂家列表失败!');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
@ -32,6 +32,11 @@
|
||||
label="创建仿真"
|
||||
@click="create(props.row)"
|
||||
/>
|
||||
<q-btn
|
||||
color="primary"
|
||||
label="另存到草稿"
|
||||
@click="showSaveToDraftFn(props.row)"
|
||||
/>
|
||||
<q-btn
|
||||
color="red"
|
||||
:disable="operateDisabled"
|
||||
@ -42,13 +47,50 @@
|
||||
</q-td>
|
||||
</template>
|
||||
</q-table>
|
||||
<q-dialog
|
||||
v-model="showDialog"
|
||||
persistent
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-card style="width: 300px">
|
||||
<q-card-section>
|
||||
<q-form ref="pubForm" @submit="saveToDraftFn" class="q-gutter-md">
|
||||
<div class="text-h6">另存到草稿</div>
|
||||
<q-input
|
||||
outlined
|
||||
disable
|
||||
label="发布图名称"
|
||||
v-model="toDraftForm.name"
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
label="草稿名称"
|
||||
v-model="toDraftForm.draftName"
|
||||
lazy-rules
|
||||
:rules="[(val) => val.length > 0 || '请输入草稿名称!']"
|
||||
/>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn color="primary" label="确定" type="submit" />
|
||||
<q-btn label="取消" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { useQuasar, type QTableColumn } from 'quasar';
|
||||
import { pageQuery, deletePublish } from '../api/PublishApi';
|
||||
import {
|
||||
pageQuery,
|
||||
deletePublish,
|
||||
saveToDraft,
|
||||
PublishItem,
|
||||
} from '../api/PublishApi';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { createSimulation } from 'src/api/Simulation';
|
||||
import { ApiError } from 'src/boot/axios';
|
||||
@ -79,6 +121,13 @@ const columnDefs: QTableColumn[] = [
|
||||
required: true,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'note',
|
||||
label: '备注',
|
||||
field: 'note',
|
||||
required: true,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'publishAt',
|
||||
label: '发布时间',
|
||||
@ -133,7 +182,7 @@ async function onRequest(props: any) {
|
||||
}
|
||||
}
|
||||
|
||||
async function create(row: any) {
|
||||
async function create(row: PublishItem) {
|
||||
createSimulation({ mapId: row.id })
|
||||
.then((res) => {
|
||||
const query = {
|
||||
@ -152,7 +201,7 @@ async function create(row: any) {
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteData(row: any) {
|
||||
async function deleteData(row: PublishItem) {
|
||||
operateDisabled.value = true;
|
||||
$q.dialog({
|
||||
title: '确认',
|
||||
@ -175,4 +224,30 @@ async function deleteData(row: any) {
|
||||
operateDisabled.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
const showDialog = ref(false);
|
||||
const toDraftForm = reactive({
|
||||
id: '',
|
||||
name: '',
|
||||
draftName: '',
|
||||
});
|
||||
function showSaveToDraftFn(row: PublishItem) {
|
||||
toDraftForm.id = row.id + '';
|
||||
toDraftForm.name = row.name;
|
||||
showDialog.value = true;
|
||||
}
|
||||
function saveToDraftFn() {
|
||||
saveToDraft(+toDraftForm.id, { name: toDraftForm.draftName })
|
||||
.then((res) => {
|
||||
console.log(res, 'res');
|
||||
showDialog.value = false;
|
||||
})
|
||||
.catch((err) => {
|
||||
const error = err as ApiError;
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: error.title,
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
@ -35,9 +35,9 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('pages/PublishManage.vue'),
|
||||
},
|
||||
{
|
||||
path: 'lineInfo',
|
||||
name: 'lineInfo',
|
||||
component: () => import('pages/LineInfoManage.vue'),
|
||||
path: 'categoryInfo',
|
||||
name: 'categoryInfo',
|
||||
component: () => import('pages/CategoryManage.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -10,8 +10,8 @@ export const useLineStore = defineStore('line', {
|
||||
simulationId: null as string | null,
|
||||
socketStates: null as GraphicState[] | null,
|
||||
stateProCount: 0,
|
||||
showLayer: [] as string[], // 显示的图层
|
||||
showLayerDialog: false, // 显示图层控制弹窗
|
||||
showLayer: [] as string[], // 显示的图层(草稿和发布图公用)
|
||||
showLayerDialog: false, // 显示图层控制弹窗(草稿和发布图公用)
|
||||
}),
|
||||
getters: {
|
||||
selectedGraphicType: (state) => {
|
||||
|
Loading…
Reference in New Issue
Block a user