Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7158f6a3bf | ||
|
c3ec658ac0 | ||
|
6ddf2d8937 | ||
|
a444504225 | ||
|
6242bc5ba6 |
@ -1,4 +0,0 @@
|
||||
API=test.joylink.club
|
||||
HTTP=https://
|
||||
NS=/ncc
|
||||
WS=wss://
|
@ -1,4 +0,0 @@
|
||||
API=localhost:9081
|
||||
HTTP=http://
|
||||
NS=
|
||||
WS=ws://
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -1,3 +1,7 @@
|
||||
[submodule "xian-ncc-da-message"]
|
||||
path = xian-ncc-da-message
|
||||
url = https://git.code.tencent.com/xian-ncc-da/xian-ncc-da-message.git
|
||||
[submodule "graphic-pixi"]
|
||||
path = graphic-pixi
|
||||
url = https://git.code.tencent.com/jl-framework/graphic-pixi.git
|
||||
branch = xian-ncc-da
|
||||
|
19
EnvParse.js
19
EnvParse.js
@ -1,19 +0,0 @@
|
||||
const DotEnv = require('dotenv');
|
||||
|
||||
module.exports = function () {
|
||||
let script = process.env.npm_lifecycle_script;
|
||||
let name = 'dev';
|
||||
if (script) {
|
||||
// quasar启动没有这个
|
||||
script = script.substring(script.indexOf('NODE_ENV=') + 'NODE_ENV='.length);
|
||||
name = script.substring(0, script.indexOf('&'));
|
||||
} else {
|
||||
if (process.env.NODE_ENV == 'production') {
|
||||
name = 'prod';
|
||||
}
|
||||
}
|
||||
console.log(name);
|
||||
name = '.env.' + name;
|
||||
let parsedEnv = DotEnv.config({ path: name }).parsed;
|
||||
return parsedEnv;
|
||||
};
|
@ -1 +1 @@
|
||||
Subproject commit b5ca64750380db0ff8e4e4a56a471363db684e12
|
||||
Subproject commit 7fe73a8334f36cf917255a99d75c454abcb96d79
|
46
index.html
46
index.html
@ -3,43 +3,19 @@
|
||||
<head>
|
||||
<title><%= productName %></title>
|
||||
|
||||
<meta charset="utf-8" />
|
||||
<meta name="description" content="<%= productDescription %>" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="msapplication-tap-highlight" content="no" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>"
|
||||
/>
|
||||
<meta charset="utf-8">
|
||||
<meta name="description" content="<%= productDescription %>">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">
|
||||
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="128x128"
|
||||
href="logo/xian_favicon.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="96x96"
|
||||
href="logo/xian_favicon.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="logo/xian_favicon.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="logo/xian_favicon.png"
|
||||
/>
|
||||
<!-- <link rel="icon" type="image/ico" href="favicon.ico" /> -->
|
||||
<link rel="icon" type="image/png" href="logo/xian_favicon.png" />
|
||||
<link rel="icon" type="image/png" sizes="128x128" href="icons/favicon-128x128.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="icons/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
|
||||
<link rel="icon" type="image/ico" href="favicon.ico">
|
||||
</head>
|
||||
<body style="overflow: hidden">
|
||||
<body>
|
||||
<!-- quasar:entry-point -->
|
||||
</body>
|
||||
</html>
|
||||
|
16
package.json
16
package.json
@ -9,25 +9,23 @@
|
||||
"lint": "eslint --ext .js,.ts,.vue ./",
|
||||
"format": "prettier --write \"**/*.{js,ts,vue,scss,html,md,json}\" --ignore-path .gitignore",
|
||||
"test": "echo \"No test specified\" && exit 0",
|
||||
"dev": "set NODE_ENV=dev&&quasar dev",
|
||||
"local": "set NODE_ENV=local&&quasar dev",
|
||||
"build": "set NODE_ENV=dev&&quasar build",
|
||||
"prod": "set NODE_ENV=prod&&quasar build",
|
||||
"dev-show": "set NODE_ENV=dev-show&&quasar build",
|
||||
"dev": "quasar dev",
|
||||
"build": "quasar build",
|
||||
"protoc": "node scripts/proto.cjs",
|
||||
"sync": "node scripts/sync.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pixi/filter-outline": "^5.2.0",
|
||||
"@pixi/graphics-extras": "^7.2.4",
|
||||
"@quasar/extras": "^1.0.0",
|
||||
"@stomp/stompjs": "^7.0.0",
|
||||
"axios": "^1.2.1",
|
||||
"centrifuge": "^4.0.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"google-protobuf": "^3.21.2",
|
||||
"jl-graphic": "git+https://git.code.tencent.com/jl-framework/graphic-pixi.git#v0.1.3",
|
||||
"js-base64": "^3.7.5",
|
||||
"pinia": "^2.0.11",
|
||||
"pixi-viewport": "^5.0.1",
|
||||
"pixi.js": "^7.2.4",
|
||||
"quasar": "^2.6.0",
|
||||
"save-dev": "0.0.1-security",
|
||||
"vue": "^3.0.0",
|
||||
"vue-router": "^4.0.0"
|
||||
},
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 77 KiB |
Binary file not shown.
Before Width: | Height: | Size: 72 KiB |
Binary file not shown.
Before Width: | Height: | Size: 21 KiB |
@ -53,23 +53,10 @@ module.exports = configure(function (/* ctx */) {
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
|
||||
build: {
|
||||
target: {
|
||||
browser: ['es2020'],
|
||||
browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
|
||||
node: 'node16',
|
||||
},
|
||||
env: require('./EnvParse.js')(),
|
||||
chainWebpack(chain) {
|
||||
chain
|
||||
.plugin('eslint-webpack-plugin')
|
||||
.use(ESLintPlugin, [{ extensions: ['js', 'vue'] }]);
|
||||
|
||||
chain.plugin('define').use(require('webpack/lib/DefinePlugin'), [
|
||||
{
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
|
||||
},
|
||||
},
|
||||
]);
|
||||
},
|
||||
vueRouterMode: 'history', // available values: 'hash', 'history'
|
||||
vueRouterBase: BasePath,
|
||||
// vueDevtools,
|
||||
@ -84,16 +71,10 @@ module.exports = configure(function (/* ctx */) {
|
||||
// ignorePublicFolder: true,
|
||||
// minify: false,
|
||||
// polyfillModulePreload: true,
|
||||
distDir: 'dist/xianncc',
|
||||
// distDir
|
||||
// distDir: `dist/${BasePath}`,
|
||||
|
||||
alias: { 'protobufjs/light': 'protobufjs/dist/light/protobuf.min.js' },
|
||||
|
||||
// extendViteConf(viteConf) {
|
||||
// viteConf.resolve.alias = Object.assign({}, viteConf.resolve.alias, {
|
||||
// 'protobufjs/light': 'protobufjs/dist/light/protobuf.min.js',
|
||||
// });
|
||||
// },
|
||||
// extendViteConf (viteConf) {},
|
||||
// viteVuePluginOptions: {},
|
||||
|
||||
// vitePlugins: [
|
||||
|
70
scripts/sync.cjs
Normal file
70
scripts/sync.cjs
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 同步图形框架文件到 src/jl-graphic/
|
||||
*/
|
||||
const {
|
||||
readdirSync,
|
||||
existsSync,
|
||||
copyFileSync,
|
||||
mkdirSync,
|
||||
rmSync,
|
||||
} = require('fs');
|
||||
const { resolve } = require('path');
|
||||
|
||||
const jlGraphicSrcPath = resolve(__dirname, '../graphic-pixi/src/jlgraphic');
|
||||
const jlGraphicLibPath = resolve(__dirname, '../src/jl-graphic');
|
||||
|
||||
/**
|
||||
* 检查并初始化当前项目引入的jl-graphic库
|
||||
*/
|
||||
function checkAndInitJlGraphicLib() {
|
||||
const exist = existsSync(jlGraphicLibPath);
|
||||
if (exist) {
|
||||
console.log('jl-graphic文件夹已存在,清空');
|
||||
readdirSync(jlGraphicLibPath, {
|
||||
withFileTypes: true,
|
||||
}).forEach((file) => {
|
||||
if (file.isDirectory()) {
|
||||
rmSync(resolve(jlGraphicLibPath, file.name), { recursive: true });
|
||||
} else {
|
||||
rmSync(resolve(jlGraphicLibPath, file.name));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log('jl-graphic文件夹不存在,创建');
|
||||
// 文件夹不存在,创建
|
||||
mkdirSync(jlGraphicLibPath);
|
||||
}
|
||||
}
|
||||
|
||||
function copyJlGraphicFiles() {
|
||||
readdirSync(jlGraphicSrcPath, {
|
||||
withFileTypes: true,
|
||||
}).forEach((file) => {
|
||||
recursiveCopyFiles(file);
|
||||
});
|
||||
}
|
||||
|
||||
function recursiveCopyFiles(file, path = []) {
|
||||
if (file.isFile()) {
|
||||
const fileSrcPath = resolve(jlGraphicSrcPath, ...path, file.name);
|
||||
const fileDestPath = resolve(jlGraphicLibPath, ...path, file.name);
|
||||
console.log(`copy file ${fileSrcPath} -> ${fileDestPath}`);
|
||||
copyFileSync(fileSrcPath, fileDestPath);
|
||||
} else if (file.isDirectory()) {
|
||||
const srcDir = resolve(jlGraphicSrcPath, ...path, file.name);
|
||||
const dirPath = resolve(jlGraphicLibPath, ...path, file.name);
|
||||
mkdirSync(dirPath);
|
||||
readdirSync(srcDir, {
|
||||
withFileTypes: true,
|
||||
}).forEach((subFile) => {
|
||||
recursiveCopyFiles(subFile, [...path, file.name]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
checkAndInitJlGraphicLib();
|
||||
copyJlGraphicFiles();
|
||||
}
|
||||
|
||||
main();
|
@ -1,27 +0,0 @@
|
||||
import { api } from 'src/boot/axios';
|
||||
|
||||
const BaseUrl = '/api/config/device';
|
||||
|
||||
export interface ParamsItem {
|
||||
id?: number;
|
||||
lineId: number;
|
||||
configData: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建/修改
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function saveThreshold(data: ParamsItem) {
|
||||
return api.post(`${BaseUrl}/save`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取发布地图详细信息
|
||||
* @param lineId 线路id
|
||||
*/
|
||||
export async function getBaseDataByLineId(lineId: number): Promise<ParamsItem> {
|
||||
const response = await api.get(`${BaseUrl}/initData/${lineId}`);
|
||||
return response.data;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
import { api } from 'src/boot/axios';
|
||||
import { PageDto, PageQueryDto } from './ApiCommon';
|
||||
|
||||
const BaseUrl = '/api/alert/tip/time';
|
||||
|
||||
export interface TimeConfigItem {
|
||||
id?: number;
|
||||
timeName: string;
|
||||
startHour: string;
|
||||
endHour: string;
|
||||
timeType: string;
|
||||
publicPeak?: string;
|
||||
}
|
||||
|
||||
export enum TipTimeConfig {
|
||||
假期早高峰 = 'HOLIDAYS_MORN_PEAK',
|
||||
假期晚高峰 = 'HOLIDAYS_EVENING_PEAK',
|
||||
早高峰 = 'MORN_PEAK',
|
||||
晚高峰 = 'EVENING_PEARK',
|
||||
低峰 = 'NORMAL_UNPEARK',
|
||||
}
|
||||
export enum ShowTipTimeConfig {
|
||||
HOLIDAYS_MORN_PEAK = '假期早高峰',
|
||||
HOLIDAYS_EVENING_PEAK = '假期晚高峰',
|
||||
MORN_PEAK = '早高峰',
|
||||
EVENING_PEARK = '晚高峰',
|
||||
NORMAL_UNPEARK = '低峰',
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建/修改时间配置
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
export function creatOrEditTimeConfig(data: TimeConfigItem) {
|
||||
return api.post(`${BaseUrl}`, data);
|
||||
}
|
||||
|
||||
class PageQueryParams extends PageQueryDto {
|
||||
timeName?: string;
|
||||
timeType?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取报警提示时间配置列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export async function alarmTipTimeConfigPageQuery(
|
||||
params: PageQueryParams
|
||||
): Promise<PageDto<TimeConfigItem>> {
|
||||
const response = await api.post(`${BaseUrl}/page`, {
|
||||
params: params,
|
||||
});
|
||||
return response.data;
|
||||
}
|
@ -1,68 +1,24 @@
|
||||
import { api } from 'src/boot/axios';
|
||||
import { PageDto, PageQueryDto } from './ApiCommon';
|
||||
import { AlarmInfo } from './DecisionInfo';
|
||||
|
||||
const alertUriBase = '/api/alert/mock';
|
||||
|
||||
//故障测试
|
||||
export function mockLocalDemoTestSet(
|
||||
alertType: string,
|
||||
data: {
|
||||
lineId: number;
|
||||
deviceInfos: {
|
||||
deviceName: string;
|
||||
deviceType: string;
|
||||
status: string;
|
||||
groupId?: string;
|
||||
}[];
|
||||
}
|
||||
) {
|
||||
return api.post(`${alertUriBase}/localDemoTest/${alertType}`, data);
|
||||
}
|
||||
|
||||
//故障演示
|
||||
export function mockAlertSet(data: {
|
||||
lineId: number;
|
||||
alertType: string;
|
||||
deviceCodes: string[];
|
||||
}) {
|
||||
export function mockAlertSet(data: { lineId: number; alertType: string }) {
|
||||
return api.post(`${alertUriBase}/set`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据设置的故障类型获取需要设置的具体的故障设备
|
||||
* @param id 线路id
|
||||
* @param alertType 故障类型
|
||||
*/
|
||||
export async function getDeviceByAlarmType(
|
||||
id: number,
|
||||
alertType: string
|
||||
): Promise<DeviceConfigItem[]> {
|
||||
const response = await api.post(`${alertUriBase}/find/${id}/${alertType}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export interface DeviceConfigItem {
|
||||
name: string;
|
||||
code: string;
|
||||
}
|
||||
|
||||
export class PagingQueryParams extends PageQueryDto {
|
||||
alertType?: string;
|
||||
lineId?: number;
|
||||
beginDateTime?: string;
|
||||
endDateTime?: string;
|
||||
alertStatus?: number;
|
||||
}
|
||||
|
||||
export interface Item {
|
||||
interface Item {
|
||||
id: number;
|
||||
alertType: string;
|
||||
timeType: string;
|
||||
locationType: string;
|
||||
drivingInfo: string;
|
||||
submissionInfo: string;
|
||||
alarmStatus: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,70 +29,8 @@ export interface Item {
|
||||
export async function alarmInfoListQuery(
|
||||
params: PagingQueryParams
|
||||
): Promise<PageDto<Item>> {
|
||||
const response = await api.post('/api/alertRecord/page/detail', params);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认报警处理
|
||||
* @param id 推送的警告信息的id
|
||||
* @param tipType 故障类型
|
||||
* @param alertLocationId 故障范围对应的列表id
|
||||
*/
|
||||
export function recordConfirmAlarmInfoByTipType(
|
||||
id: number,
|
||||
tipType: string,
|
||||
alertLocationId?: number
|
||||
): Promise<AlarmInfo<Item>> {
|
||||
return api.get(`/api/alertRecord/confirm/${id}/${tipType}`, {
|
||||
params: { alertLocationId: alertLocationId },
|
||||
const response = await api.get('/api/alertRecord/page/detail', {
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 错误报警处理--误报
|
||||
* @param recordId 推送的警告信息的id
|
||||
*/
|
||||
export function recordFailAlarmInfoById(recordId: number) {
|
||||
return api.post(`/api/alertRecord/fail/${recordId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 错误报警处理--人工报警和一键确定
|
||||
* @param recordId 推送的警告信息的id
|
||||
*/
|
||||
export function recordManualAlarmInfoById(recordId: number[]) {
|
||||
return api.post('/api/alertRecord/warn', recordId);
|
||||
}
|
||||
|
||||
export interface IReportParams {
|
||||
alertTypes?: string[];
|
||||
beginDateTime?: string;
|
||||
endDateTime?: string;
|
||||
alertStatus?: number;
|
||||
}
|
||||
|
||||
interface IReportRes {
|
||||
alertType: string;
|
||||
counter: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 报警统计
|
||||
* @param lineId 线路id
|
||||
*/
|
||||
export async function recordAlarmReport(
|
||||
lineId: number,
|
||||
data: IReportParams
|
||||
): Promise<IReportRes[]> {
|
||||
const response = await api.post(`/api/alertRecord/report/${lineId}`, data);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param linId 线路的id
|
||||
*/
|
||||
export function resetApi(linId: number): Promise<string> {
|
||||
return api.get(`${alertUriBase}/reset/${linId}`);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ export class OrderItemDto {
|
||||
}
|
||||
}
|
||||
|
||||
export interface PageDto<T> {
|
||||
export interface PageDto<T = unknown> {
|
||||
records: T[];
|
||||
/**
|
||||
* 记录总数
|
||||
|
@ -1,65 +0,0 @@
|
||||
import { api } from 'src/boot/axios';
|
||||
import { PageDto, PageQueryDto } from './ApiCommon';
|
||||
|
||||
export interface IAreaConfigListItem {
|
||||
id: number;
|
||||
lineId: number;
|
||||
areaName: string;
|
||||
deviceType: string;
|
||||
}
|
||||
|
||||
export async function getDeviceAreaList({
|
||||
lineId,
|
||||
deviceType,
|
||||
current,
|
||||
size,
|
||||
areaName,
|
||||
}: {
|
||||
lineId?: string;
|
||||
deviceType?: string;
|
||||
areaName?: string;
|
||||
} & PageQueryDto) {
|
||||
const resp = await api.get<PageDto<IAreaConfigListItem>>(
|
||||
`/api/config/device/area/page/${lineId}`,
|
||||
{ params: { current, size, deviceType, areaName } }
|
||||
);
|
||||
if (resp.status === 200) {
|
||||
return resp.data;
|
||||
} else {
|
||||
throw Error(resp.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteDeviceArea(id: number) {
|
||||
const resp = await api.delete(`/api/config/device/area/${id}`);
|
||||
if (resp.status === 200) {
|
||||
return resp;
|
||||
} else {
|
||||
throw Error(resp.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
export interface IAreaConfigItem {
|
||||
id?: number;
|
||||
lineId: number;
|
||||
areaName: string;
|
||||
deviceType: string;
|
||||
alertTypes: string[];
|
||||
data: number[];
|
||||
}
|
||||
export function deviceRangeSet(data: IAreaConfigItem) {
|
||||
return api.post('/api/config/device/area/save', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id获取配置信息
|
||||
* @param id 配置列表id
|
||||
*/
|
||||
export function queryDeviceRangeById(
|
||||
id: number
|
||||
): Promise<IAreaConfig<IAreaConfigItem>> {
|
||||
return api.get(`/api/config/device/area/${id}`);
|
||||
}
|
||||
interface IAreaConfig<T = unknown> {
|
||||
data: T;
|
||||
}
|
@ -1,36 +1,29 @@
|
||||
import { api } from 'src/boot/axios';
|
||||
import { PageDto, PageQueryDto } from './ApiCommon';
|
||||
import { TimeConfigItem } from './AlarmTipTimeConfig';
|
||||
|
||||
const AlertTipUriBase = '/api/alertTip';
|
||||
const DraftUriBase = '/api/alertTip';
|
||||
|
||||
interface AlarmInfoCreateParams {
|
||||
id: number;
|
||||
export interface createParams {
|
||||
alertType: string;
|
||||
tipTimeIds: string[];
|
||||
areaConfigId: number;
|
||||
timeType: string;
|
||||
locationType: string;
|
||||
drivingInfo: string;
|
||||
submissionInfo: string;
|
||||
}
|
||||
|
||||
export interface AlarmInfoListItem {
|
||||
interface Item {
|
||||
id: number;
|
||||
alertType: string;
|
||||
timeConfigList: TimeConfigItem[];
|
||||
areaConfigId: number;
|
||||
timeType: string;
|
||||
locationType: string;
|
||||
drivingInfo: string;
|
||||
submissionInfo: string;
|
||||
areaConfigName?: string;
|
||||
}
|
||||
|
||||
export interface AlarmInfo<T = unknown> {
|
||||
data: T;
|
||||
}
|
||||
|
||||
export class PagingQueryParams extends PageQueryDto {
|
||||
alertType?: string;
|
||||
timeType?: string;
|
||||
areaConfigName?: string;
|
||||
locationType?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,8 +33,8 @@ export class PagingQueryParams extends PageQueryDto {
|
||||
*/
|
||||
export async function alarmInfoPageQuery(
|
||||
params: PagingQueryParams
|
||||
): Promise<PageDto<AlarmInfoListItem>> {
|
||||
const response = await api.get(`${AlertTipUriBase}/page`, {
|
||||
): Promise<PageDto<Item>> {
|
||||
const response = await api.get(`${DraftUriBase}/page`, {
|
||||
params: params,
|
||||
});
|
||||
return response.data;
|
||||
@ -51,29 +44,17 @@ export async function alarmInfoPageQuery(
|
||||
* 根据id获取决策信息
|
||||
* @param id 草稿id
|
||||
*/
|
||||
export function queryAlarmInfoById(
|
||||
id: number
|
||||
): Promise<AlarmInfo<AlarmInfoListItem>> {
|
||||
return api.get(`${AlertTipUriBase}/id/${id}`);
|
||||
export function queryAlarmInfoById(id: number): Promise<AlarmInfo<Item>> {
|
||||
return api.get(`${DraftUriBase}/id/${id}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据报警类型获取决策信息
|
||||
* @param type 草稿type
|
||||
*/
|
||||
export function queryAlarmInfoByType(
|
||||
type: string
|
||||
): Promise<AlarmInfo<AlarmInfoListItem>> {
|
||||
return api.get(`${AlertTipUriBase}/type/${type}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建或编辑决策信息
|
||||
* 创建决策信息
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function createAlarmInfo(draftData: AlarmInfoCreateParams) {
|
||||
return api.post(`${AlertTipUriBase}`, draftData);
|
||||
export function createAlarmInfo(draftData: createParams) {
|
||||
return api.post(`${DraftUriBase}`, draftData);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,26 +62,18 @@ export function createAlarmInfo(draftData: AlarmInfoCreateParams) {
|
||||
* @param id 草稿id
|
||||
*/
|
||||
export function deleteAlarmInfo(id: number) {
|
||||
return api.delete(`${AlertTipUriBase}/id/${id}`);
|
||||
return api.delete(`${DraftUriBase}/id/${id}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据故障类型获取对应的范围配置
|
||||
* @param id 线路id
|
||||
* @param tipType 故障类型
|
||||
* 更新决策信息
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
export async function getDeviceAreaByAlarmType(
|
||||
id: number,
|
||||
alertType: string
|
||||
): Promise<AreaConfigItem[]> {
|
||||
const response = await api.post(
|
||||
`${AlertTipUriBase}/find/type/${id}/${alertType}`,
|
||||
{}
|
||||
);
|
||||
return response.data;
|
||||
export function updataAlarmInfo(id: number, data: Item) {
|
||||
return api.put(`${DraftUriBase}/id`, data);
|
||||
}
|
||||
|
||||
export interface AreaConfigItem {
|
||||
id: number;
|
||||
areaName: string;
|
||||
export interface AlarmInfo<T = unknown> {
|
||||
data: T;
|
||||
}
|
||||
|
@ -2,9 +2,10 @@ import { api } from 'src/boot/axios';
|
||||
|
||||
const platformUriBase = '/mock/platform/status';
|
||||
const stationUriBase = '/mock/rtu/status';
|
||||
const serverUriBase = '/mock/server/send';
|
||||
|
||||
export interface mockPlatformParams {
|
||||
export function mockPlatformApi(
|
||||
lineId: number,
|
||||
data: {
|
||||
emergstop: boolean;
|
||||
trainberth: boolean;
|
||||
close: boolean;
|
||||
@ -19,22 +20,21 @@ export interface mockPlatformParams {
|
||||
upTrainSkipstop: boolean;
|
||||
downTrainSkipstop: boolean;
|
||||
id: string;
|
||||
nextSectionRunTime: number;
|
||||
nextSectionRunLevel: number;
|
||||
stopTime: number;
|
||||
}
|
||||
|
||||
export function mockPlatformApi(lineId: number, data: mockPlatformParams) {
|
||||
nextSectionRunTime: 0;
|
||||
nextSectionRunLevel: 0;
|
||||
stopTime: 0;
|
||||
}
|
||||
) {
|
||||
return api.post(`${platformUriBase}/${lineId}`, data);
|
||||
}
|
||||
|
||||
export function mockStationApi(
|
||||
lineId: number,
|
||||
data: {
|
||||
ipRtuStusDown: boolean;
|
||||
ipRtuStusInLocalCtrl: boolean;
|
||||
ipRtuStusInCentralCtrl: boolean;
|
||||
ipRtuStusInEmergencyCtrl: boolean;
|
||||
ipRtuStusDown: true;
|
||||
ipRtuStusInLocalCtrl: true;
|
||||
ipRtuStusInCentralCtrl: true;
|
||||
ipRtuStusInEmergencyCtrl: true;
|
||||
id: string;
|
||||
}
|
||||
) {
|
||||
@ -72,14 +72,3 @@ export function mockSignalApi(
|
||||
) {
|
||||
return api.post(`/mock/signal/status/${lineId}`, data);
|
||||
}
|
||||
|
||||
export function mockServerApi(data: {
|
||||
deviceType: string;
|
||||
messageId: string;
|
||||
lineId: number;
|
||||
rtuId: number;
|
||||
deviceName: string;
|
||||
deviceStatus: number;
|
||||
}) {
|
||||
return api.post(serverUriBase, data);
|
||||
}
|
||||
|
@ -44,21 +44,6 @@ export enum DevType {
|
||||
DEVICE_TYPE_GAMA = 'DEVICE_TYPE_GAMA',
|
||||
}
|
||||
|
||||
export const deviceTypeMap = {
|
||||
DEVICE_TYPE_UNKNOW: '未知设备',
|
||||
DEVICE_TYPE_RTU: '集中站',
|
||||
DEVICE_TYPE_STATION: '车站',
|
||||
DEVICE_TYPE_SIGNAL: '信号机',
|
||||
DEVICE_TYPE_SWITCH: '道岔',
|
||||
DEVICE_TYPE_TRACK: '轨道',
|
||||
DEVICE_TYPE_ENTRY: '方向设备',
|
||||
DEVICE_TYPE_PLATFORM: '站台',
|
||||
DEVICE_TYPE_SCADA: '供电区段',
|
||||
DEVICE_TYPE_WATERPROOF_DOOR: '防淹门',
|
||||
DEVICE_TYPE_WORK_AREA: '工作区',
|
||||
DEVICE_TYPE_GAMA: '区域自动驾驶',
|
||||
};
|
||||
|
||||
export function trainMockApi(
|
||||
lineId: number,
|
||||
data: {
|
||||
|
@ -1,4 +1,7 @@
|
||||
import { api } from 'src/boot/axios';
|
||||
import { ITurnoutState } from 'src/graphics/turnout/Turnout';
|
||||
|
||||
const base = '/mock/train';
|
||||
|
||||
interface State {
|
||||
id: string;
|
||||
@ -34,6 +37,9 @@ interface State {
|
||||
|
||||
export async function setSwitchStatus(lineId: string, state: State) {
|
||||
try {
|
||||
delete state._state;
|
||||
delete state._graphicType;
|
||||
state.speedLimit = 0;
|
||||
return await api.post(`/mock/switch/status/${lineId}`, state);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
@ -41,6 +47,8 @@ export async function setSwitchStatus(lineId: string, state: State) {
|
||||
}
|
||||
export async function setTrackStatus(lineId: string, state: State) {
|
||||
try {
|
||||
delete state._state;
|
||||
delete state._graphicType;
|
||||
return await api.post(`/mock/track/status/${lineId}`, state);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
@ -1,80 +0,0 @@
|
||||
<template>
|
||||
<draggable-dialog
|
||||
ref="dialogRef"
|
||||
@show="onDialogShow"
|
||||
seamless
|
||||
title="与卡斯柯连接状态信息"
|
||||
:width="300"
|
||||
:height="0"
|
||||
>
|
||||
<template v-slot:footer>
|
||||
<q-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
v-model:pagination="pagination"
|
||||
:rows="rows"
|
||||
:columns="columns"
|
||||
@request="onRequest"
|
||||
:rows-per-page-options="[10, 20, 50, 100]"
|
||||
>
|
||||
</q-table>
|
||||
</template>
|
||||
</draggable-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import DraggableDialog from './common/DraggableDialog.vue';
|
||||
import { QTable } from 'quasar';
|
||||
import { useLineNetStore } from 'src/stores/line-net-store';
|
||||
import { state } from 'src/protos/system_warn_message';
|
||||
|
||||
const lineNetStore = useLineNetStore();
|
||||
const dialogRef = ref<InstanceType<typeof DraggableDialog>>();
|
||||
const tableRef = ref<QTable>();
|
||||
const columns: QTable['columns'] = [
|
||||
{ name: 'lineId', label: '线路ID', field: 'lineId', align: 'center' },
|
||||
{
|
||||
name: 'areaName',
|
||||
label: '实时连接',
|
||||
field: (row) => (row.occRealConned ? '是' : '否'),
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'deviceType',
|
||||
label: '非实时连接',
|
||||
field: (row) => (row.occUnrealConned ? '是' : '否'),
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
const rows = ref<state.WarnMessage[]>([]);
|
||||
const pagination = ref({
|
||||
sortBy: 'desc',
|
||||
descending: false,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 10,
|
||||
});
|
||||
|
||||
watch(
|
||||
() => lineNetStore.connectInfo,
|
||||
() => {
|
||||
onDialogShow();
|
||||
}
|
||||
);
|
||||
|
||||
const onRequest: QTable['onRequest'] = async (props) => {
|
||||
const { page, rowsPerPage } = props.pagination;
|
||||
pagination.value.page = page;
|
||||
pagination.value.rowsPerPage = rowsPerPage;
|
||||
const datas = lineNetStore.connectInfo?.msgs;
|
||||
if (datas) {
|
||||
rows.value = datas.slice((page - 1) * rowsPerPage, page * rowsPerPage - 1);
|
||||
pagination.value.rowsNumber = datas.length;
|
||||
}
|
||||
};
|
||||
|
||||
const onDialogShow = () => {
|
||||
tableRef.value?.requestServerInteraction();
|
||||
};
|
||||
</script>
|
@ -1,30 +0,0 @@
|
||||
import { type GraphicDataBase } from 'src/drawApp/graphics/GraphicDataBase';
|
||||
import { IDrawApp, JlGraphic } from 'jl-graphic';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, onUnmounted, reactive } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
|
||||
export function useFormData<T extends GraphicDataBase>(
|
||||
source: T,
|
||||
app: IDrawApp
|
||||
) {
|
||||
const data = reactive<T>(source);
|
||||
|
||||
onMounted(() => {
|
||||
app.bindFormData(data);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
app.unbindFormData(data);
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
const graphic = drawStore.selectedGraphic as JlGraphic;
|
||||
if (graphic) {
|
||||
app.updateGraphicAndRecord(graphic, data);
|
||||
}
|
||||
}
|
||||
|
||||
return { data, onUpdate };
|
||||
}
|
@ -43,14 +43,16 @@ import { reactive } from 'vue';
|
||||
|
||||
const list = reactive([
|
||||
{
|
||||
path: '/monitor',
|
||||
label: '监控',
|
||||
icon: 'computer',
|
||||
},
|
||||
path: '',
|
||||
label: '系统管理',
|
||||
icon: 'dataset',
|
||||
children: [
|
||||
{
|
||||
path: '/alarmList',
|
||||
label: '报警列表',
|
||||
icon: 'access_alarm',
|
||||
path: '/sysManage/user',
|
||||
label: '用户管理',
|
||||
icon: 'manage_accounts',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
@ -65,41 +67,24 @@ const list = reactive([
|
||||
{
|
||||
path: '/dataManage/publish',
|
||||
label: '发布管理',
|
||||
icon: 'playlist_add_check',
|
||||
icon: 'app_registration',
|
||||
},
|
||||
{
|
||||
path: '/dataManage/lineInfo',
|
||||
label: '线路信息管理',
|
||||
icon: 'format_list_numbered',
|
||||
icon: 'app_registration',
|
||||
},
|
||||
{
|
||||
path: '/dataManage/decisionInfo',
|
||||
label: '决策信息管理',
|
||||
icon: 'format_align_center',
|
||||
},
|
||||
{
|
||||
path: '/dataManage/thresholdValue',
|
||||
label: '报警故障阈值配置',
|
||||
icon: 'format_indent_increase',
|
||||
},
|
||||
{
|
||||
path: '/dataManage/alarmTipTimeConfig',
|
||||
label: '报警提示时间配置',
|
||||
icon: 'access_time',
|
||||
icon: 'app_registration',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
label: '系统管理',
|
||||
icon: 'dataset',
|
||||
children: [
|
||||
{
|
||||
path: '/sysManage/user',
|
||||
label: '用户管理',
|
||||
icon: 'manage_accounts',
|
||||
},
|
||||
],
|
||||
path: '/monitor',
|
||||
label: '监控',
|
||||
icon: 'computer',
|
||||
},
|
||||
]);
|
||||
</script>
|
||||
|
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<draggable-dialog
|
||||
v-model="showDialog"
|
||||
seamless
|
||||
title="报警"
|
||||
:titleColor="`${bgColor}`"
|
||||
@ -9,7 +8,6 @@
|
||||
:width="dialogWidth"
|
||||
fontColor=""
|
||||
:height="0"
|
||||
bgBorder="solid 2px black"
|
||||
>
|
||||
<template v-slot:footer>
|
||||
<div>
|
||||
@ -19,52 +17,18 @@
|
||||
<q-separator />
|
||||
<div class="alarm-message-detail">
|
||||
<div class="left">
|
||||
<div class="text">时间:{{ alarmInfo.time }}</div>
|
||||
<div class="text">级别:{{ alarmInfo.level }}</div>
|
||||
<div class="text">线路:{{ alarmInfo.lineId }}号线</div>
|
||||
<div class="text">时间:{{ alarmInfo.time }}</div>
|
||||
<div class="text">级别:{{ alarmInfo.level }}</div>
|
||||
<div class="text">线路:{{ alarmInfo.lineId }}号线</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="text">设备:{{ alarmInfo.alertObject }}</div>
|
||||
<div class="text" v-if="!showFaultType">
|
||||
类型:{{ alarmInfo.alertType }}
|
||||
</div>
|
||||
<div class="text" v-else>类型:{{ faultType }}</div>
|
||||
<div class="text">设备:{{ alarmInfo.alertObject }}</div>
|
||||
<div class="text">类型:{{ alarmInfo.alertType }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
<div class="confirm-message" v-if="showConfirmMmessage">
|
||||
<q-card class="box-card">
|
||||
<div class="head">选择故障类型</div>
|
||||
<q-separator />
|
||||
<q-form class="detail" ref="myForm" @submit="confirmAlarm">
|
||||
<q-select
|
||||
style="width: 200px"
|
||||
dense
|
||||
outlined
|
||||
v-model="faultType"
|
||||
:options="faultTypeOptions"
|
||||
label="故障类型"
|
||||
:rules="[(val) => val.length > 0 || '请选择故障类型!']"
|
||||
/>
|
||||
<q-card-actions align="left">
|
||||
<div class="q-gutter-md">
|
||||
<q-btn color="primary" label="确认" type="submit" />
|
||||
<q-btn color="red" label="误报" @click="falseAlarm" />
|
||||
<q-btn
|
||||
color="primary"
|
||||
label="人工接警"
|
||||
@click="manualAlarm"
|
||||
/>
|
||||
</div>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</div>
|
||||
<div
|
||||
class="decision-message"
|
||||
v-if="!showConfirmMmessage && showDecisionmessage"
|
||||
>
|
||||
<div class="decision-message">
|
||||
<q-card class="box-card">
|
||||
<div class="head">行车方面</div>
|
||||
<q-separator />
|
||||
@ -87,30 +51,39 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import DraggableDialog from '../common/DraggableDialog.vue';
|
||||
import { useLineNetStore, AlarmInfo } from 'src/stores/line-net-store';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { QForm, useQuasar } from 'quasar';
|
||||
import { saveAlertTypeData, showAlertTypeData } from './alarmInfoEnum';
|
||||
import {
|
||||
recordConfirmAlarmInfoByTipType,
|
||||
recordFailAlarmInfoById,
|
||||
recordManualAlarmInfoById,
|
||||
} from 'src/api/AlertMock';
|
||||
import { useLineNetStore } from 'src/stores/line-net-store';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { queryAlarmInfoById } from 'src/api/DecisionInfo';
|
||||
|
||||
const props = defineProps<{
|
||||
alarmMeaasge?: AlarmInfo;
|
||||
waitAlarmMeaasge?: AlarmInfo;
|
||||
onHandle: (id: string) => void;
|
||||
}>();
|
||||
import { useQuasar } from 'quasar';
|
||||
|
||||
let bgColor = ref('');
|
||||
const dialogWidth = window.screen.width * 0.5;
|
||||
const lineNetStore = useLineNetStore();
|
||||
const showConfirmMmessage = ref(true);
|
||||
const faultType = ref('');
|
||||
let faultTypeOptions = [];
|
||||
const showFaultType = ref(false);
|
||||
|
||||
watch(
|
||||
() => lineNetStore.alarmInfo,
|
||||
(val) => {
|
||||
if (val.length) {
|
||||
search();
|
||||
updata();
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const mapAlarmMessage = new Map([
|
||||
['I', 'I类信息'],
|
||||
['II', 'II类信息'],
|
||||
['III', 'III类信息'],
|
||||
['IV', 'IV类信息'],
|
||||
['0', '未知'],
|
||||
['1', '蓝显'],
|
||||
['2', '列车延误2分钟'],
|
||||
['3', '列车延误10分钟'],
|
||||
['4', '整侧站台门无关闭锁紧信号'],
|
||||
['5', '整侧站台门无法打开'],
|
||||
['6', '整侧站台门无法关闭'],
|
||||
]);
|
||||
|
||||
const mapColor = new Map([
|
||||
['I', 'rgb(250,61,46)'],
|
||||
@ -127,106 +100,36 @@ const alarmInfo = ref({
|
||||
alertObject: '',
|
||||
alertType: '',
|
||||
locator_device_id: '',
|
||||
alert_location_id: '',
|
||||
});
|
||||
const drivingInfo = ref('');
|
||||
const submissionInfo = ref('');
|
||||
let messageUse: AlarmInfo;
|
||||
const showDialog = ref(true);
|
||||
const showDecisionmessage = ref(true);
|
||||
|
||||
onMounted(() => {
|
||||
if (props.alarmMeaasge == undefined && props.waitAlarmMeaasge == undefined) {
|
||||
messageUse = lineNetStore.alarmInfo[0] as AlarmInfo;
|
||||
} else if (props.waitAlarmMeaasge) {
|
||||
messageUse = props.waitAlarmMeaasge as AlarmInfo;
|
||||
} else {
|
||||
messageUse = props.alarmMeaasge as AlarmInfo;
|
||||
if (messageUse.alarmStatus == 1) {
|
||||
showConfirmMmessage.value = false;
|
||||
searchById();
|
||||
} else if (messageUse.alarmStatus == 0) {
|
||||
showConfirmMmessage.value = false;
|
||||
showDecisionmessage.value = false;
|
||||
}
|
||||
}
|
||||
search();
|
||||
updata();
|
||||
switch (alarmInfo.value.alertType) {
|
||||
case '道岔失表':
|
||||
faultTypeOptions = ['道岔均失表', '道岔定位失表', '道岔反位失表'];
|
||||
break;
|
||||
default:
|
||||
faultTypeOptions = [alarmInfo.value.alertType];
|
||||
faultType.value = alarmInfo.value.alertType;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
const myForm = ref<QForm | null>(null);
|
||||
function confirmAlarm() {
|
||||
myForm.value?.validate().then(async (res) => {
|
||||
if (res) {
|
||||
showConfirmMmessage.value = false;
|
||||
showFaultType.value = true;
|
||||
searchByTipType().then(() => {
|
||||
lineNetStore.alarmInfoListTable?.requestServerInteraction();
|
||||
props.onHandle(messageUse.id);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function falseAlarm() {
|
||||
showDialog.value = false;
|
||||
recordFailAlarmInfoById(+messageUse.id).then(() => {
|
||||
lineNetStore.alarmInfoListTable?.requestServerInteraction();
|
||||
props.onHandle(messageUse.id);
|
||||
});
|
||||
}
|
||||
|
||||
function manualAlarm() {
|
||||
showDialog.value = false;
|
||||
recordManualAlarmInfoById([+messageUse.id]).then(() => {
|
||||
lineNetStore.alarmInfoListTable?.requestServerInteraction();
|
||||
props.onHandle(messageUse.id);
|
||||
});
|
||||
}
|
||||
|
||||
function updata() {
|
||||
bgColor.value = mapColor.get(messageUse.level) as string;
|
||||
alarmInfo.value.time = messageUse.alert_time
|
||||
bgColor.value = mapColor.get(lineNetStore.alarmInfo[0].level) as string;
|
||||
alarmInfo.value.time = lineNetStore.alarmInfo[0].alert_time
|
||||
.substring(0, 19)
|
||||
.replace('T', ' ');
|
||||
alarmInfo.value.level = (showAlertTypeData as never)[messageUse.level + ''];
|
||||
alarmInfo.value.alertType = (showAlertTypeData as never)[
|
||||
messageUse.alert_type + ''
|
||||
];
|
||||
alarmInfo.value.alertObject = messageUse.alert_object.replace(/\[|]/g, '');
|
||||
alarmInfo.value.lineId = messageUse.line_id;
|
||||
}
|
||||
|
||||
async function searchByTipType() {
|
||||
try {
|
||||
const type = (saveAlertTypeData as never)[faultType.value];
|
||||
const response = await recordConfirmAlarmInfoByTipType(
|
||||
+messageUse.id,
|
||||
type,
|
||||
messageUse.alert_location_id
|
||||
alarmInfo.value.level = mapAlarmMessage.get(
|
||||
lineNetStore.alarmInfo[0].level
|
||||
) as string;
|
||||
alarmInfo.value.alertType = mapAlarmMessage.get(
|
||||
lineNetStore.alarmInfo[0].alert_type + ''
|
||||
) as string;
|
||||
alarmInfo.value.alertObject = lineNetStore.alarmInfo[0].alert_object.replace(
|
||||
/\[|]/g,
|
||||
''
|
||||
);
|
||||
drivingInfo.value = JSON.parse(response.data.drivingInfo);
|
||||
submissionInfo.value = JSON.parse(response.data.submissionInfo);
|
||||
lineNetStore.treatedAlarm(messageUse);
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: '没有此类故障的辅助决策信息',
|
||||
});
|
||||
}
|
||||
alarmInfo.value.lineId = lineNetStore.alarmInfo[0].line_id;
|
||||
}
|
||||
|
||||
async function searchById() {
|
||||
async function search() {
|
||||
try {
|
||||
const id = messageUse.alert_tip_id;
|
||||
const id = lineNetStore.alarmInfo[0].alert_tip_id;
|
||||
const response = await queryAlarmInfoById(id);
|
||||
drivingInfo.value = JSON.parse(response.data.drivingInfo);
|
||||
submissionInfo.value = JSON.parse(response.data.submissionInfo);
|
||||
@ -251,14 +154,11 @@ async function searchById() {
|
||||
}
|
||||
.alarm-message-detail {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
.left,
|
||||
.right {
|
||||
width: 50%;
|
||||
padding: 0 5px;
|
||||
.text {
|
||||
width: 450px;
|
||||
word-wrap: break-word;
|
||||
margin-bottom: 10px;
|
||||
font-size: 20px;
|
||||
}
|
||||
@ -266,26 +166,12 @@ async function searchById() {
|
||||
}
|
||||
}
|
||||
}
|
||||
.confirm-message {
|
||||
margin-top: 10px;
|
||||
.box-card {
|
||||
height: 180px;
|
||||
padding: 0 5px;
|
||||
.head {
|
||||
padding: 5px 5px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.detail {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.decision-message {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 10px;
|
||||
margin: 10px 0;
|
||||
.box-card {
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
.head {
|
||||
padding: 5px 5px;
|
||||
|
@ -1,138 +0,0 @@
|
||||
export enum showAlertTypeData {
|
||||
'未知故障',
|
||||
'蓝显',
|
||||
'列车延误2分钟',
|
||||
'列车延误10分钟',
|
||||
'整侧站台门无关闭锁紧信号',
|
||||
'整侧站台门无法打开',
|
||||
'整侧站台门无法关闭',
|
||||
'道岔失表',
|
||||
'道岔均失表',
|
||||
'道岔定位失表',
|
||||
'道岔反位失表',
|
||||
'红光带',
|
||||
'橙光带',
|
||||
'计轴红光带',
|
||||
'计轴大面积红光带',
|
||||
'计轴橙光带',
|
||||
'计轴大面积橙光带',
|
||||
'道岔大面积失表',
|
||||
'列车信号故障',
|
||||
'全线蓝显',
|
||||
'联锁区红光带',
|
||||
'联锁区橙光带',
|
||||
'联锁区失表',
|
||||
'一级联锁',
|
||||
I = 'I类信息',
|
||||
II = 'II类信息',
|
||||
III = 'III类信息',
|
||||
IV = 'IV类信息',
|
||||
TRAIN_DELAY_2 = '列车延误2分钟',
|
||||
TRAIN_DELAY_10 = '列车延误10分钟',
|
||||
BLUE_DISPLAY = '蓝显',
|
||||
PLATFORM_DOOR_WITHOUT_LOCKED_SIGNAL = '整侧站台门无关闭锁紧信号',
|
||||
PLATFORM_DOOR_CANNOT_OPEN = '整侧站台门无法打开',
|
||||
PLATFORM_DOOR_CANNOT_CLOSE = '整侧站台门无法关闭',
|
||||
QX = '全线',
|
||||
YHZ_LSQ = '鱼化寨联锁区',
|
||||
HJM_LSQ = '胡家庙联锁区',
|
||||
BCT_LSQ = '北池头联锁区',
|
||||
BSQ_LSQ = '保税区联锁区',
|
||||
SWITCH_LOST = '道岔失表',
|
||||
SWITCH_All_LOST = '道岔均失表',
|
||||
SWITCH_DW_LOST = '道岔定位失表',
|
||||
SWITCH_FW_LOST = '道岔反位失表',
|
||||
AXLE_LED_RED = '计轴红光带',
|
||||
AXLE_LED_RED_MOST = '计轴大面积红光带',
|
||||
AXLE_LED_ORANGE = '计轴橙光带',
|
||||
AXLE_LED_ORANGE_MOST = '计轴大面积橙光带',
|
||||
SWITCH_LOST_MOST = '道岔大面积失表',
|
||||
TRAIN_EB_ATP = '列车信号故障',
|
||||
ALL_LINE_BLUE_DISPLAY = '全线蓝显',
|
||||
AXLE_LED_RED_INTERLOCK_AREA = '联锁区红光带',
|
||||
AXLE_LED_ORANGE_INTERLOCK_AREA = '联锁区橙光带',
|
||||
SWITCH_LOST_INTERLOCK_AREA = '联锁区失表',
|
||||
INTERLOCK_LEVEL_ONE = '一级联锁',
|
||||
}
|
||||
|
||||
export enum saveAlertTypeData {
|
||||
列车延误2分钟 = 'TRAIN_DELAY_2',
|
||||
列车延误10分钟 = 'TRAIN_DELAY_10',
|
||||
蓝显 = 'BLUE_DISPLAY',
|
||||
整侧站台门无关闭锁紧信号 = 'PLATFORM_DOOR_WITHOUT_LOCKED_SIGNAL',
|
||||
整侧站台门无法打开 = 'PLATFORM_DOOR_CANNOT_OPEN',
|
||||
整侧站台门无法关闭 = 'PLATFORM_DOOR_CANNOT_CLOSE',
|
||||
全线 = 'QX',
|
||||
鱼化寨联锁区 = 'YHZ_LSQ',
|
||||
胡家庙联锁区 = 'HJM_LSQ',
|
||||
北池头联锁区 = 'BCT_LSQ',
|
||||
保税区联锁区 = 'BSQ_LSQ',
|
||||
道岔失表 = 'SWITCH_LOST',
|
||||
道岔均失表 = 'SWITCH_All_LOST',
|
||||
道岔定位失表 = 'SWITCH_DW_LOST',
|
||||
道岔反位失表 = 'SWITCH_FW_LOST',
|
||||
计轴红光带 = 'AXLE_LED_RED',
|
||||
计轴大面积红光带 = 'AXLE_LED_RED_MOST',
|
||||
计轴橙光带 = 'AXLE_LED_ORANGE',
|
||||
计轴大面积橙光带 = 'AXLE_LED_ORANGE_MOST',
|
||||
道岔大面积失表 = 'SWITCH_LOST_MOST',
|
||||
列车信号故障 = 'TRAIN_EB_ATP',
|
||||
全线蓝显 = 'ALL_LINE_BLUE_DISPLAY',
|
||||
联锁区红光带 = 'AXLE_LED_RED_INTERLOCK_AREA',
|
||||
联锁区橙光带 = 'AXLE_LED_ORANGE_INTERLOCK_AREA',
|
||||
联锁区失表 = 'SWITCH_LOST_INTERLOCK_AREA',
|
||||
一级联锁 = 'INTERLOCK_LEVEL_ONE',
|
||||
}
|
||||
|
||||
export const GuardConfigTypeData = {
|
||||
switchLostTimes: { label: '道岔失表', unit: '秒', deviceType: '道岔' },
|
||||
switchLostMostNums: {
|
||||
label: '道岔大面积失表',
|
||||
unit: '个',
|
||||
deviceType: '道岔',
|
||||
},
|
||||
redLedMostNums: { label: '大面积红光带', unit: '个', deviceType: '计轴区段' },
|
||||
orangeLedMostNums: {
|
||||
label: '大面积橙光带',
|
||||
unit: '个',
|
||||
deviceType: '计轴区段',
|
||||
},
|
||||
canNotOpenTimes: {
|
||||
label: '站台门无法打开',
|
||||
unit: '秒',
|
||||
deviceType: '屏蔽门',
|
||||
},
|
||||
canNotCloseTimes: {
|
||||
label: '站台门无法关闭',
|
||||
unit: '秒',
|
||||
deviceType: '屏蔽门',
|
||||
},
|
||||
trainAtpCutTimes: {
|
||||
label: '列车制动后导致atp切除的超时时间',
|
||||
unit: '秒',
|
||||
deviceType: '信号',
|
||||
},
|
||||
};
|
||||
|
||||
type findType = string | number;
|
||||
export function isArraysEqual(arr1: findType[], arr2: findType[]) {
|
||||
if (arr1.length !== arr2.length) {
|
||||
return false;
|
||||
}
|
||||
return arr1.sort().join(',') === arr2.sort().join(',');
|
||||
}
|
||||
|
||||
export enum ShowAlertStateData {
|
||||
'未处理' = -1,
|
||||
'误报',
|
||||
'确认',
|
||||
'人工接警',
|
||||
}
|
||||
|
||||
export const alertStatusOptions = [
|
||||
{ label: '全部', value: 999 },
|
||||
{ label: '未处理', value: -1 },
|
||||
{ label: '误报', value: 0 },
|
||||
{ label: '确认', value: 1 },
|
||||
{ label: '人工接警', value: 2 },
|
||||
];
|
173
src/components/alarm/alarmInfoList.vue
Normal file
173
src/components/alarm/alarmInfoList.vue
Normal file
@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<draggable-dialog
|
||||
seamless
|
||||
title="报警列表"
|
||||
:width="dialogWidth"
|
||||
:height="dialogHeight"
|
||||
>
|
||||
<q-table
|
||||
ref="tableRef"
|
||||
title="报警信息"
|
||||
:style="{ height: dialogHeight + '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-left>
|
||||
<q-input
|
||||
dense
|
||||
debounce="1000"
|
||||
v-model.number="filter.lineId"
|
||||
label="线路ID"
|
||||
type="number"
|
||||
/>
|
||||
<q-btn flat round color="primary" icon="search" />
|
||||
</template>
|
||||
<template v-slot:top-right>
|
||||
<q-input
|
||||
dense
|
||||
debounce="1000"
|
||||
v-model="filter.alertType"
|
||||
label="故障类型"
|
||||
></q-input>
|
||||
<q-btn flat round color="primary" icon="search" />
|
||||
</template>
|
||||
</q-table>
|
||||
</draggable-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DraggableDialog from '../common/DraggableDialog.vue';
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { useQuasar, type QTableColumn } from 'quasar';
|
||||
import { alarmInfoListQuery } from 'src/api/AlertMock';
|
||||
|
||||
const $q = useQuasar();
|
||||
const dialogWidth = window.screen.width * 0.5;
|
||||
const dialogHeight = window.screen.height * 0.5;
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
tableRef.value.requestServerInteraction();
|
||||
});
|
||||
});
|
||||
|
||||
const columnDefs: QTableColumn[] = [
|
||||
{
|
||||
name: 'id',
|
||||
label: '编号',
|
||||
field: 'id',
|
||||
required: true,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'alertTime',
|
||||
label: '时间',
|
||||
field: 'alertTime',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'lineId',
|
||||
label: '线路',
|
||||
field: 'lineId',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'alertObject',
|
||||
label: '设备',
|
||||
field: 'alertObject',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'level',
|
||||
label: '级别',
|
||||
field: (row) => {
|
||||
if (row.level) {
|
||||
return (showAlertTypeData as never)[row.level + ''];
|
||||
}
|
||||
},
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'alertType',
|
||||
label: '故障类型',
|
||||
field: (row) => {
|
||||
if (row.alertType) {
|
||||
return (showAlertTypeData as never)[row.alertType];
|
||||
}
|
||||
},
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
|
||||
const tableRef = ref();
|
||||
const rows = reactive([]);
|
||||
const filter = reactive({
|
||||
alertType: '',
|
||||
lineId: '',
|
||||
});
|
||||
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 alarmInfoListQuery({
|
||||
current: page,
|
||||
size: rowsPerPage,
|
||||
alertType: (saveAlertTypeData as never)[filter.alertType],
|
||||
lineId: filter.lineId,
|
||||
});
|
||||
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) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: '无法获取报警信息列表',
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
enum showAlertTypeData {
|
||||
ALERT_TYPE_UNKNOWN = '未知故障',
|
||||
BLUE_DISPLAY = '蓝显',
|
||||
TRAIN_DELAY_2 = '列车延误2分钟',
|
||||
TRAIN_DELAY_10 = '列车延误10分钟',
|
||||
PLATFORM_DOOR_WITHOUT_LOCKED_SIGNAL = '站台门无关闭且锁紧信号',
|
||||
PLATFORM_DOOR_CANNOT_OPEN = '整侧站台门无法打开',
|
||||
PLATFORM_DOOR_CANNOT_CLOSE = '整侧站台门无法关闭',
|
||||
I = 'I类信息',
|
||||
II = 'II类信息',
|
||||
III = 'III类信息',
|
||||
IV = 'IV类信息',
|
||||
}
|
||||
|
||||
enum saveAlertTypeData {
|
||||
列车延误2分钟 = 'TRAIN_DELAY_2',
|
||||
列车延误10分钟 = 'TRAIN_DELAY_10',
|
||||
蓝显 = 'BLUE_DISPLAY',
|
||||
站台门无关闭且锁紧信号 = 'PLATFORM_DOOR_WITHOUT_LOCKED_SIGNAL',
|
||||
整侧站台门无法打开 = 'PLATFORM_DOOR_CANNOT_OPEN',
|
||||
整侧站台门无法关闭 = 'PLATFORM_DOOR_CANNOT_CLOSE',
|
||||
}
|
||||
</script>
|
@ -1,363 +0,0 @@
|
||||
<template>
|
||||
<draggable-dialog
|
||||
seamless
|
||||
title="报警统计"
|
||||
:width="dialogWidth"
|
||||
:height="dialogHeight"
|
||||
>
|
||||
<q-table
|
||||
ref="tableRef"
|
||||
:style="{ height: dialogHeight + 'px' }"
|
||||
:rows="rows"
|
||||
:columns="columnDefs"
|
||||
row-key="index"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[0]"
|
||||
:loading="loading"
|
||||
:filter="filter"
|
||||
binary-state-sort
|
||||
virtual-scroll
|
||||
>
|
||||
<template v-slot:top>
|
||||
<q-form ref="myForm" @submit="onRequest" style="width: 100%">
|
||||
<div class="q-gutter-md row justify-center items-start">
|
||||
<q-select
|
||||
dense
|
||||
v-model="filter.lineId"
|
||||
:options="optionsLineId"
|
||||
emit-value
|
||||
map-options
|
||||
options-dense
|
||||
label="线路ID"
|
||||
style="width: 100px"
|
||||
/>
|
||||
<q-input
|
||||
dense
|
||||
v-model="filter.beginDateTime"
|
||||
label="开始时间"
|
||||
no-error-icon
|
||||
mask="####-##-## ##:##:##"
|
||||
hint="例如:2023-09-05 16:05:09"
|
||||
lazy-rules
|
||||
:rules="[timeRangeValidation]"
|
||||
:error="errorBeginTime"
|
||||
:error-message="errorMessageBeginTime"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-date
|
||||
v-model="filter.beginDateTime"
|
||||
mask="YYYY-MM-DD HH:mm:ss"
|
||||
landscape
|
||||
>
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn
|
||||
v-close-popup
|
||||
label="关闭"
|
||||
color="primary"
|
||||
flat
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
|
||||
<template v-slot:append>
|
||||
<q-icon name="access_time" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-time
|
||||
v-model="filter.beginDateTime"
|
||||
mask="YYYY-MM-DD HH:mm:ss"
|
||||
with-seconds
|
||||
landscape
|
||||
format24h
|
||||
>
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn
|
||||
v-close-popup
|
||||
label="关闭"
|
||||
color="primary"
|
||||
flat
|
||||
/>
|
||||
</div>
|
||||
</q-time>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-input
|
||||
dense
|
||||
v-model="filter.endDateTime"
|
||||
label="结束时间"
|
||||
no-error-icon
|
||||
mask="####-##-## ##:##:##"
|
||||
hint="例如:2023-09-05 16:05:09"
|
||||
lazy-rules
|
||||
:rules="[timeRangeValidation]"
|
||||
:error="errorEndTime"
|
||||
:error-message="errorMessageEndTime"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-date
|
||||
v-model="filter.endDateTime"
|
||||
mask="YYYY-MM-DD HH:mm:ss"
|
||||
landscape
|
||||
>
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn
|
||||
v-close-popup
|
||||
label="关闭"
|
||||
color="primary"
|
||||
flat
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
|
||||
<template v-slot:append>
|
||||
<q-icon name="access_time" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-time
|
||||
v-model="filter.endDateTime"
|
||||
mask="YYYY-MM-DD HH:mm:ss"
|
||||
with-seconds
|
||||
landscape
|
||||
format24h
|
||||
>
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn
|
||||
v-close-popup
|
||||
label="关闭"
|
||||
color="primary"
|
||||
flat
|
||||
/>
|
||||
</div>
|
||||
</q-time>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
dense
|
||||
v-model="filter.alertTypes"
|
||||
:options="typeOptions"
|
||||
multiple
|
||||
emit-value
|
||||
map-options
|
||||
options-dense
|
||||
class="ellipsis"
|
||||
label="类型"
|
||||
style="width: 200px"
|
||||
/>
|
||||
<q-select
|
||||
dense
|
||||
v-model="filter.alertStatus"
|
||||
:options="alertStatusOptions"
|
||||
emit-value
|
||||
map-options
|
||||
options-dense
|
||||
label="处理状态"
|
||||
style="width: 100px"
|
||||
/>
|
||||
<q-btn color="primary" label="查询" type="submit" />
|
||||
</div>
|
||||
</q-form>
|
||||
</template>
|
||||
<template v-slot:body-cell-index="props">
|
||||
<q-td :props="props">
|
||||
<span>{{ props.rowIndex + 1 }}</span>
|
||||
</q-td>
|
||||
</template>
|
||||
</q-table>
|
||||
</draggable-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DraggableDialog from '../common/DraggableDialog.vue';
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { useQuasar, type QTableColumn, QForm, date } from 'quasar';
|
||||
import { IReportParams, recordAlarmReport } from 'src/api/AlertMock';
|
||||
import {
|
||||
showAlertTypeData,
|
||||
saveAlertTypeData,
|
||||
alertStatusOptions,
|
||||
} from './alarmInfoEnum';
|
||||
|
||||
defineProps<{
|
||||
optionsLineId: { label: string; value: number }[];
|
||||
}>();
|
||||
|
||||
const $q = useQuasar();
|
||||
const dialogWidth = window.screen.width * 0.6;
|
||||
const dialogHeight = window.screen.height * 0.5;
|
||||
|
||||
const columnDefs: QTableColumn[] = [
|
||||
{
|
||||
name: 'index',
|
||||
label: '编号',
|
||||
field: 'index',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'alertType',
|
||||
label: '故障类型',
|
||||
field: (row) => {
|
||||
if (row.alertType) {
|
||||
return (showAlertTypeData as never)[row.alertType];
|
||||
}
|
||||
},
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'counter',
|
||||
label: '数量',
|
||||
field: 'counter',
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
|
||||
const typeOptions = computed(() => {
|
||||
const list: { label: string; value: string }[] = [];
|
||||
// list.push({ label: '全部', value: '' });
|
||||
for (let i in saveAlertTypeData) {
|
||||
const obj = {
|
||||
label: i,
|
||||
value: saveAlertTypeData[i as keyof typeof saveAlertTypeData],
|
||||
};
|
||||
list.push(obj);
|
||||
}
|
||||
return list;
|
||||
});
|
||||
|
||||
interface Ifilter extends IReportParams {
|
||||
lineId: number;
|
||||
}
|
||||
|
||||
const rows = reactive([]);
|
||||
const filter = reactive<Ifilter>({
|
||||
alertTypes: [],
|
||||
lineId: 3,
|
||||
beginDateTime: '',
|
||||
endDateTime: '',
|
||||
alertStatus: 999,
|
||||
});
|
||||
const loading = ref(false);
|
||||
const pagination = ref({
|
||||
sortBy: 'desc',
|
||||
descending: false,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 0,
|
||||
});
|
||||
|
||||
function onRequest() {
|
||||
myForm.value?.validate().then(async (res) => {
|
||||
if (res) {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params: IReportParams = {};
|
||||
if (filter.alertTypes?.length) {
|
||||
Object.assign(params, { alertTypes: filter.alertTypes });
|
||||
}
|
||||
if (filter.beginDateTime) {
|
||||
Object.assign(params, { beginDateTime: filter.beginDateTime });
|
||||
}
|
||||
if (filter.endDateTime) {
|
||||
Object.assign(params, { endDateTime: filter.endDateTime });
|
||||
}
|
||||
if (filter.alertStatus != 999) {
|
||||
Object.assign(params, { alertStatus: filter.alertStatus });
|
||||
}
|
||||
const response = await recordAlarmReport(filter.lineId, params);
|
||||
|
||||
pagination.value.rowsNumber = response.length;
|
||||
pagination.value.rowsPerPage = response.length;
|
||||
rows.splice(0, rows.length, ...(response as []));
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: '无法获取报警统计列表',
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const myForm = ref<QForm | null>(null);
|
||||
|
||||
const errorBeginTime = ref(false);
|
||||
const errorEndTime = ref(false);
|
||||
const errorMessageBeginTime = ref('');
|
||||
const errorMessageEndTime = ref('');
|
||||
function timeRangeValidation() {
|
||||
const Reg = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
|
||||
if (filter.beginDateTime) {
|
||||
if (
|
||||
!date.isValid(filter.beginDateTime) ||
|
||||
!Reg.test(filter.beginDateTime)
|
||||
) {
|
||||
errorBeginTime.value = true;
|
||||
errorMessageBeginTime.value = '请输入正确的时间!';
|
||||
return false;
|
||||
} else {
|
||||
filter.beginDateTime = date.formatDate(
|
||||
filter.beginDateTime,
|
||||
'YYYY-MM-DD HH:mm:ss'
|
||||
);
|
||||
}
|
||||
}
|
||||
if (filter.endDateTime) {
|
||||
if (!date.isValid(filter.endDateTime) || !Reg.test(filter.endDateTime)) {
|
||||
errorEndTime.value = true;
|
||||
errorMessageEndTime.value = '请输入正确的时间!';
|
||||
return false;
|
||||
} else {
|
||||
filter.endDateTime = date.formatDate(
|
||||
filter.endDateTime,
|
||||
'YYYY-MM-DD HH:mm:ss'
|
||||
);
|
||||
}
|
||||
}
|
||||
if (
|
||||
filter.beginDateTime &&
|
||||
filter.endDateTime &&
|
||||
new Date(filter.endDateTime).getTime() <
|
||||
new Date(filter.beginDateTime).getTime()
|
||||
) {
|
||||
errorBeginTime.value = true;
|
||||
errorEndTime.value = true;
|
||||
errorMessageBeginTime.value = '开始时间不能大于结束时间!';
|
||||
errorMessageEndTime.value = '结束时间不能小于开始时间!';
|
||||
return false;
|
||||
}
|
||||
errorBeginTime.value = false;
|
||||
errorEndTime.value = false;
|
||||
errorMessageBeginTime.value = '';
|
||||
errorMessageEndTime.value = '';
|
||||
return true;
|
||||
}
|
||||
</script>
|
@ -1,202 +1,64 @@
|
||||
<template>
|
||||
<div>
|
||||
<audio ref="audio">
|
||||
<source :src="audioSrc" type="audio/mpeg" />
|
||||
<source src="../../assets/buzzer.mp3" type="audio/mpeg" />
|
||||
</audio>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { watch, onUnmounted, ref, toRaw } from 'vue';
|
||||
import { AlarmInfo, useLineNetStore } from 'src/stores/line-net-store';
|
||||
import { DialogChainObject, useQuasar } from 'quasar';
|
||||
import { watch, onUnmounted, ref, onMounted } from 'vue';
|
||||
import { useLineNetStore } from 'src/stores/line-net-store';
|
||||
import { useQuasar } from 'quasar';
|
||||
import alarmInfoDialog from 'src/components/alarm/alarmInfoDialog.vue';
|
||||
import { showAlertTypeData } from './alarmInfoEnum';
|
||||
import allLineBlue from '/alarmMusic/all-line-blue.mp3';
|
||||
import atpcut from '/alarmMusic/atp-cut.mp3';
|
||||
import blue from '/alarmMusic/blue.mp3';
|
||||
import cannotClose from '/alarmMusic/cannot-close.mp3';
|
||||
import cannotOpen from '/alarmMusic/cannot-open.mp3';
|
||||
import orangeMost from '/alarmMusic/orange-most.mp3';
|
||||
import orange from '/alarmMusic/orange.mp3';
|
||||
import redMost from '/alarmMusic/red-most.mp3';
|
||||
import red from '/alarmMusic/red.mp3';
|
||||
import switchLostMost from '/alarmMusic/switch-lost-most.mp3';
|
||||
import switchLost from '/alarmMusic/switch-lost.mp3';
|
||||
import buzzer from '/alarmMusic/buzzer.mp3';
|
||||
|
||||
const lineNetStore = useLineNetStore();
|
||||
const audio = ref();
|
||||
const audioSrc = ref('');
|
||||
const $q = useQuasar();
|
||||
let waitShowDialog: AlarmInfo[] = [];
|
||||
const dialogInstance = ref();
|
||||
const playAble = ref(false);
|
||||
const watchInteract = () => {
|
||||
playAble.value = true;
|
||||
document.removeEventListener('click', watchInteract);
|
||||
document.removeEventListener('keydown', watchInteract);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => lineNetStore.alarmInfo,
|
||||
(val) => {
|
||||
if (val.length) {
|
||||
UpdataAlarmInfoList();
|
||||
const hasShow = countHasShowFiveDialog();
|
||||
if (!hasShow) {
|
||||
const alarmType = val[0].alert_type;
|
||||
alarm(alarmType, val[0].id);
|
||||
playAlarmMusic(alarmType);
|
||||
} else {
|
||||
waitShowDialog.push(toRaw(lineNetStore.alarmInfo[0]));
|
||||
}
|
||||
if (val.length && audio.value.paused) {
|
||||
playAlarmMusic();
|
||||
}
|
||||
if (val.length && !lineNetStore.alarmDialog) {
|
||||
alarm();
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
() => lineNetStore.closeAllAlarmInfoDialog,
|
||||
(val) => {
|
||||
if (val) {
|
||||
lineNetStore.closeAllAlarmInfoDialog = false;
|
||||
closeAllDialog();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function playAlarmMusic(type: number) {
|
||||
for (let i = 0; i < dialogInstance.length; i++) {
|
||||
if (dialogInstance[i].show == false) {
|
||||
dialogInstance.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (lineNetStore.playAble && audio.value.paused) {
|
||||
const alarmType = (showAlertTypeData as never)[type + ''];
|
||||
const mapAlarmMusic = new Map([
|
||||
['蓝显', blue],
|
||||
['全线蓝显', allLineBlue],
|
||||
['整侧站台门无法打开', cannotOpen],
|
||||
['整侧站台门无法关闭', cannotClose],
|
||||
['道岔失表', switchLost],
|
||||
['道岔大面积失表', switchLostMost],
|
||||
['计轴红光带', red],
|
||||
['计轴大面积红光带', redMost],
|
||||
['计轴橙光带', orange],
|
||||
['计轴大面积橙光带', orangeMost],
|
||||
['列车信号故障', atpcut],
|
||||
]);
|
||||
const music = mapAlarmMusic.get(alarmType);
|
||||
if (music !== undefined) {
|
||||
audioSrc.value = music;
|
||||
} else {
|
||||
audioSrc.value = buzzer;
|
||||
}
|
||||
audio.value.src = audioSrc.value;
|
||||
function playAlarmMusic() {
|
||||
if (playAble.value) {
|
||||
audio.value.play();
|
||||
}
|
||||
}
|
||||
|
||||
//不关闭弹框,每3分钟播放一次报警音乐
|
||||
function timingPlayAlarmMusic(dialog: DialogChainObject) {
|
||||
const timerIndex = dialogInstance.findIndex((item) => item.dialog == dialog);
|
||||
clearTimeout(dialogInstance[timerIndex].timer);
|
||||
dialogInstance[timerIndex].timer = setTimeout(() => {
|
||||
for (let i = 0; i < dialogInstance.length; i++) {
|
||||
if (
|
||||
dialogInstance[i].show &&
|
||||
!dialogInstance[i].hasHandle &&
|
||||
dialogInstance[i].dialog == dialog
|
||||
) {
|
||||
playAlarmMusic(dialogInstance[i].alarmType);
|
||||
timingPlayAlarmMusic(dialog);
|
||||
}
|
||||
}
|
||||
}, 180000);
|
||||
}
|
||||
|
||||
const dialogInstance: {
|
||||
dialog: DialogChainObject;
|
||||
show: boolean;
|
||||
alarmType: number;
|
||||
timer: string | number | NodeJS.Timeout | undefined;
|
||||
id: string;
|
||||
hasHandle: boolean;
|
||||
}[] = [];
|
||||
|
||||
function countHasShowFiveDialog(): boolean {
|
||||
let hasShow = 0;
|
||||
for (let i = 0; i < dialogInstance.length; i++) {
|
||||
if (dialogInstance[i].show) {
|
||||
hasShow++;
|
||||
if (hasShow > 4) break;
|
||||
}
|
||||
}
|
||||
return hasShow > 4 ? true : false;
|
||||
}
|
||||
|
||||
function alarm(alarmType: number, id: string, waitAlarmMeaasge?: AlarmInfo) {
|
||||
const dialogInstanceItem = $q
|
||||
.dialog({
|
||||
component: alarmInfoDialog,
|
||||
componentProps: {
|
||||
waitAlarmMeaasge: waitAlarmMeaasge,
|
||||
onHandle: (id: string) => {
|
||||
for (let i = 0; i < dialogInstance.length; i++) {
|
||||
if (dialogInstance[i].id == id) {
|
||||
dialogInstance[i].hasHandle = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
function alarm() {
|
||||
lineNetStore.alarmDialog = true;
|
||||
dialogInstance.value = $q
|
||||
.dialog({ component: alarmInfoDialog })
|
||||
.onCancel(() => {
|
||||
alarmWaitDialog();
|
||||
const index = dialogInstance.findIndex(
|
||||
(item) => item.dialog == dialogInstanceItem
|
||||
);
|
||||
dialogInstance[index].show = false;
|
||||
lineNetStore.alarmDialog = false;
|
||||
});
|
||||
let timer: string | number | NodeJS.Timeout | undefined = undefined;
|
||||
dialogInstance.push({
|
||||
dialog: dialogInstanceItem,
|
||||
show: true,
|
||||
alarmType,
|
||||
timer,
|
||||
hasHandle: false,
|
||||
id,
|
||||
});
|
||||
timingPlayAlarmMusic(dialogInstanceItem);
|
||||
}
|
||||
|
||||
function alarmWaitDialog() {
|
||||
if (countHasShowFiveDialog() && waitShowDialog.length) {
|
||||
alarm(
|
||||
waitShowDialog[0].alert_type,
|
||||
waitShowDialog[0].id,
|
||||
waitShowDialog[0]
|
||||
);
|
||||
playAlarmMusic(waitShowDialog[0].alert_type);
|
||||
waitShowDialog.shift();
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', watchInteract);
|
||||
document.addEventListener('keydown', watchInteract);
|
||||
});
|
||||
|
||||
function closeAllDialog() {
|
||||
if (dialogInstance.length) {
|
||||
dialogInstance.forEach((item) => {
|
||||
clearTimeout(item.timer);
|
||||
if (item.show) {
|
||||
item.dialog.hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
waitShowDialog = [];
|
||||
}
|
||||
|
||||
let timeout: string | number | NodeJS.Timeout | undefined;
|
||||
function UpdataAlarmInfoList() {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => {
|
||||
lineNetStore.alarmInfoListTable?.requestServerInteraction();
|
||||
}, 1000);
|
||||
}
|
||||
onUnmounted(() => {
|
||||
clearTimeout(timeout);
|
||||
closeAllDialog();
|
||||
if (dialogInstance.value && lineNetStore.alarmDialog) {
|
||||
dialogInstance.value.hide();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -1,264 +0,0 @@
|
||||
<template>
|
||||
<draggable-dialog
|
||||
v-model="showsetAlartText"
|
||||
seamless
|
||||
title="设置故障演示"
|
||||
:width="300"
|
||||
:height="0"
|
||||
>
|
||||
<template v-slot:footer>
|
||||
<div>
|
||||
<q-card class="q-gutter-sm q-px-sm q-mt-sm">
|
||||
<q-form ref="myForm" @submit="onSubmit" @reset="onReset">
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
label="线路ID"
|
||||
v-model.number="setAlartTextData.lineId"
|
||||
type="number"
|
||||
lazy-rules
|
||||
:rules="[(val) => val || '请输入线路ID!']"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
label="故障类型"
|
||||
v-model="setAlartTextData.alertType"
|
||||
:options="optionsAlertType"
|
||||
:rules="[(val) => val.length > 0 || '请选择故障类型!']"
|
||||
/>
|
||||
<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 setAlartTextData.deviceCodes"
|
||||
:key="item"
|
||||
square
|
||||
color="primary"
|
||||
text-color="white"
|
||||
removable
|
||||
@remove="removeSelect(item)"
|
||||
>
|
||||
{{ item }}
|
||||
</q-chip>
|
||||
</div>
|
||||
<q-btn
|
||||
v-show="setAlartTextData.deviceCodes.length > 0"
|
||||
style="width: 120px"
|
||||
label="清空框选的设备"
|
||||
color="red"
|
||||
@click="clearSelect"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<div class="q-gutter-sm q-pa-md row justify-center">
|
||||
<q-btn
|
||||
label="提交"
|
||||
type="submit"
|
||||
color="primary"
|
||||
class="q-mr-md"
|
||||
/>
|
||||
<q-btn label="重置" type="reset" color="primary" />
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</draggable-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DraggableDialog from '../common/DraggableDialog.vue';
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { JlGraphic } from 'jl-graphic';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
import { QForm, useQuasar } from 'quasar';
|
||||
import { ApiError } from 'src/boot/axios';
|
||||
import { mockAlertSet } from 'src/api/AlertMock';
|
||||
import { isArraysEqual, saveAlertTypeData } from './alarmInfoEnum';
|
||||
import { Section, SectionType } from 'src/graphics/section/Section';
|
||||
import { LogicSection } from 'src/graphics/logicSection/LogicSection';
|
||||
|
||||
const lineStore = useLineStore();
|
||||
const setAlartTextData = ref<{
|
||||
lineId: string;
|
||||
alertType: string;
|
||||
deviceCodes: string[];
|
||||
}>({
|
||||
lineId: '',
|
||||
alertType: '',
|
||||
deviceCodes: [],
|
||||
});
|
||||
const optionsAlertType = [
|
||||
'蓝显',
|
||||
'全线蓝显',
|
||||
'整侧站台门无法打开',
|
||||
'整侧站台门无法关闭',
|
||||
'道岔失表',
|
||||
'计轴红光带',
|
||||
'计轴大面积红光带',
|
||||
'计轴橙光带',
|
||||
'计轴大面积橙光带',
|
||||
'列车信号故障',
|
||||
];
|
||||
const mapAlertType = new Map([
|
||||
['蓝显', ['station']],
|
||||
['全线蓝显', ['station']],
|
||||
['整侧站台门无法打开', ['Platform']],
|
||||
['整侧站台门无法关闭', ['Platform']],
|
||||
['道岔失表', ['Turnout']],
|
||||
['计轴红光带', ['Section']],
|
||||
['计轴大面积红光带', ['Section']],
|
||||
['计轴橙光带', ['Section']],
|
||||
['计轴大面积橙光带', ['Section']],
|
||||
['列车信号故障', ['LogicSection', 'Turnout']],
|
||||
]);
|
||||
let selectGraphic: JlGraphic[] = [];
|
||||
|
||||
watch(
|
||||
() => lineStore.selectedGraphics,
|
||||
(val) => {
|
||||
if (val && val.length > 0 && setAlartTextData.value.alertType) {
|
||||
const selectGraphicId = selectGraphic.map((g) => g.id);
|
||||
const appSelectedGraphicsId = lineStore.selectedGraphics?.map(
|
||||
(g) => g.id
|
||||
);
|
||||
if (
|
||||
appSelectedGraphicsId !== undefined &&
|
||||
isArraysEqual(selectGraphicId, appSelectedGraphicsId)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const deviceFilter = lineStore.selectedGraphics?.filter((g) => {
|
||||
let select = false;
|
||||
if (
|
||||
g.type == Station.Type &&
|
||||
(g as Station).datas.concentrationStations &&
|
||||
setAlartTextData.value.alertType == '蓝显'
|
||||
) {
|
||||
select = true;
|
||||
}
|
||||
if (
|
||||
(g.type !== Station.Type &&
|
||||
mapAlertType
|
||||
.get(setAlartTextData.value.alertType)
|
||||
?.includes(g.type)) ||
|
||||
(g.type == Section.Type &&
|
||||
(g as Section).datas.sectionType === SectionType.TurnoutPhysical &&
|
||||
mapAlertType
|
||||
.get(setAlartTextData.value.alertType)
|
||||
?.includes(LogicSection.Type))
|
||||
) {
|
||||
select = true;
|
||||
}
|
||||
return select;
|
||||
}) as JlGraphic[];
|
||||
if (
|
||||
[
|
||||
'道岔失表',
|
||||
'计轴红光带',
|
||||
'计轴橙光带',
|
||||
'列车信号故障',
|
||||
'整侧站台门无法打开',
|
||||
'整侧站台门无法关闭',
|
||||
].includes(setAlartTextData.value.alertType)
|
||||
) {
|
||||
if (deviceFilter[0] !== undefined) {
|
||||
selectGraphic = [deviceFilter[0]];
|
||||
}
|
||||
} else {
|
||||
selectGraphic.push(...deviceFilter);
|
||||
}
|
||||
selectGraphic = Array.from(new Set(selectGraphic));
|
||||
lineStore.getLineApp().updateSelected(...selectGraphic);
|
||||
setAlartTextData.value.deviceCodes = selectGraphic.map((g) => g.code);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
lineStore.getLineApp().emit('options-update', {
|
||||
mouseToolOptions: {
|
||||
boxSelect: true,
|
||||
viewportDrag: true,
|
||||
viewportDragLeft: false,
|
||||
wheelZoom: true,
|
||||
},
|
||||
});
|
||||
clearSelect();
|
||||
onReset();
|
||||
setAlartTextData.value.lineId = lineStore.lineId as unknown as string;
|
||||
});
|
||||
|
||||
const myForm = ref<QForm | null>(null);
|
||||
const showsetAlartText = ref(true);
|
||||
const $q = useQuasar();
|
||||
|
||||
async function onSubmit() {
|
||||
myForm.value?.validate().then(async (res) => {
|
||||
if (res) {
|
||||
try {
|
||||
const params = {
|
||||
lineId: +setAlartTextData.value.lineId,
|
||||
alertType: (saveAlertTypeData as never)[
|
||||
setAlartTextData.value.alertType + ''
|
||||
],
|
||||
deviceCodes: setAlartTextData.value.deviceCodes,
|
||||
};
|
||||
await mockAlertSet(params);
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: '设置故障演示成功',
|
||||
});
|
||||
onReset();
|
||||
} catch (err) {
|
||||
const apiErr = err as ApiError;
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: apiErr.title,
|
||||
});
|
||||
} finally {
|
||||
showsetAlartText.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeSelect(code: string) {
|
||||
const removeIndex = setAlartTextData.value.deviceCodes.findIndex(
|
||||
(item) => item == code
|
||||
);
|
||||
selectGraphic.splice(removeIndex, 1);
|
||||
setAlartTextData.value.deviceCodes.splice(removeIndex, 1);
|
||||
lineStore.getLineApp().updateSelected(...selectGraphic);
|
||||
}
|
||||
|
||||
function clearSelect() {
|
||||
setAlartTextData.value.deviceCodes = [];
|
||||
selectGraphic = [];
|
||||
lineStore.getLineApp().updateSelected();
|
||||
}
|
||||
|
||||
function onReset() {
|
||||
setAlartTextData.value = {
|
||||
lineId: lineStore.lineId as unknown as string,
|
||||
alertType: '',
|
||||
deviceCodes: [],
|
||||
};
|
||||
selectGraphic = [];
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
lineStore.getLineApp().emit('options-update', {
|
||||
mouseToolOptions: {
|
||||
boxSelect: false,
|
||||
viewportDrag: true,
|
||||
viewportDragLeft: true,
|
||||
wheelZoom: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
@ -1,408 +0,0 @@
|
||||
<template>
|
||||
<draggable-dialog
|
||||
v-model="showsetAlartText"
|
||||
seamless
|
||||
title="设置故障测试"
|
||||
:width="300"
|
||||
:height="0"
|
||||
>
|
||||
<template v-slot:footer>
|
||||
<div>
|
||||
<q-card class="q-gutter-sm q-px-sm q-mt-sm">
|
||||
<q-form ref="myForm" @submit="onSubmit" @reset="onReset">
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
label="线路ID"
|
||||
v-model.number="setAlartTextData.lineId"
|
||||
type="number"
|
||||
lazy-rules
|
||||
:rules="[(val) => val || '请输入线路ID!']"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
label="故障类型"
|
||||
v-model="setAlartTextData.alertType"
|
||||
:options="optionsAlertType"
|
||||
:rules="[(val) => val.length > 0 || '请选择故障类型!']"
|
||||
@update:model-value="onChooseAlertType"
|
||||
/>
|
||||
<q-list bordered separator class="rounded-borders">
|
||||
<q-expansion-item
|
||||
bordered
|
||||
expand-separator
|
||||
v-for="(configItem, index) in setAlartTextData.groupList"
|
||||
:key="configItem"
|
||||
v-model="configItem.expanded"
|
||||
:label="configItem.groupName"
|
||||
@click="toggleItem(index)"
|
||||
>
|
||||
<q-card>
|
||||
<q-item no-wrap class="column">
|
||||
<q-input
|
||||
v-if="setAlartTextData.alertType == '列车信号故障'"
|
||||
outlined
|
||||
label="车组号"
|
||||
v-model="configItem.groupId"
|
||||
lazy-rules
|
||||
:rules="[(val) => val.length > 0 || '请输入车组号!']"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
label="故障测试状态"
|
||||
v-model="configItem.status"
|
||||
:options="optionsStatus"
|
||||
:rules="[(val) => val.length > 0 || '请选择故障类型!']"
|
||||
map-options
|
||||
emit-value
|
||||
/>
|
||||
<div class="q-gutter-sm row">
|
||||
<q-chip
|
||||
v-for="(item, selectIndex) in configItem.deviceInfos"
|
||||
:key="item"
|
||||
square
|
||||
color="primary"
|
||||
text-color="white"
|
||||
removable
|
||||
@remove="removeSelect(selectIndex)"
|
||||
clickable
|
||||
@click="clickSelectCenter(selectIndex)"
|
||||
>
|
||||
{{ item.deviceName }}
|
||||
</q-chip>
|
||||
</div>
|
||||
<div>
|
||||
<q-btn
|
||||
v-show="configItem.deviceInfos.length > 0"
|
||||
style="width: 100px"
|
||||
label="清空选择"
|
||||
color="red"
|
||||
class="q-mr-md"
|
||||
@click="clearAllSelect(index)"
|
||||
/>
|
||||
<q-btn
|
||||
v-if="setAlartTextData.alertType == '列车信号故障'"
|
||||
label="删除测试组"
|
||||
color="secondary"
|
||||
@click="deleteSelectConfig(index)"
|
||||
/>
|
||||
</div>
|
||||
</q-item>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
</q-list>
|
||||
<q-btn
|
||||
v-if="setAlartTextData.alertType == '列车信号故障'"
|
||||
class="q-mt-md"
|
||||
label="增加测试组"
|
||||
color="secondary"
|
||||
@click="addSelectConfig"
|
||||
/>
|
||||
<div class="q-gutter-sm q-pa-md row justify-center">
|
||||
<q-btn
|
||||
label="提交"
|
||||
type="submit"
|
||||
color="primary"
|
||||
class="q-mr-md"
|
||||
/>
|
||||
<q-btn label="重置" type="reset" color="primary" />
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</draggable-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DraggableDialog from '../common/DraggableDialog.vue';
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { JlGraphic } from 'jl-graphic';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
import { QForm, useQuasar } from 'quasar';
|
||||
import { ApiError } from 'src/boot/axios';
|
||||
import { mockLocalDemoTestSet } from 'src/api/AlertMock';
|
||||
import { isArraysEqual, saveAlertTypeData } from './alarmInfoEnum';
|
||||
|
||||
const lineStore = useLineStore();
|
||||
const setAlartTextData = ref<{
|
||||
lineId: string;
|
||||
alertType: string;
|
||||
groupList: {
|
||||
groupName: string;
|
||||
groupId?: string;
|
||||
status: string;
|
||||
deviceInfos: {
|
||||
deviceName: string;
|
||||
deviceType: string;
|
||||
}[];
|
||||
expanded: boolean;
|
||||
}[];
|
||||
}>({
|
||||
lineId: '',
|
||||
alertType: '',
|
||||
groupList: [
|
||||
{
|
||||
groupName: '测试组',
|
||||
groupId: '',
|
||||
status: '',
|
||||
deviceInfos: [],
|
||||
expanded: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
const optionsAlertType = [
|
||||
'蓝显',
|
||||
'道岔失表',
|
||||
'计轴红光带',
|
||||
'计轴橙光带',
|
||||
'列车信号故障',
|
||||
];
|
||||
const mapAlertType = new Map([
|
||||
['蓝显', ['station']],
|
||||
['道岔失表', ['Turnout']],
|
||||
['计轴红光带', ['LogicSection', 'Turnout']],
|
||||
['计轴橙光带', ['LogicSection', 'Turnout']],
|
||||
['列车信号故障', ['LogicSection', 'Turnout']],
|
||||
]);
|
||||
enum DeviceType {
|
||||
station = 'DEVICE_TYPE_RTU',
|
||||
Turnout = 'DEVICE_TYPE_SWITCH',
|
||||
LogicSection = 'DEVICE_TYPE_TRACK',
|
||||
}
|
||||
const optionsStatus = [
|
||||
{ label: '正常', value: 'NORMAL' },
|
||||
{ label: '设置', value: 'BEGIN' },
|
||||
{ label: '报警', value: 'ALERT' },
|
||||
];
|
||||
let selectGraphic: JlGraphic[] = [];
|
||||
|
||||
watch(
|
||||
() => lineStore.selectedGraphics,
|
||||
(val) => {
|
||||
if (
|
||||
val &&
|
||||
val.length > 0 &&
|
||||
setAlartTextData.value.alertType &&
|
||||
clickIndex !== null
|
||||
) {
|
||||
const selectGraphicId = selectGraphic.map((g) => g.id);
|
||||
const appSelectedGraphicsId = lineStore.selectedGraphics?.map(
|
||||
(g) => g.id
|
||||
);
|
||||
if (
|
||||
appSelectedGraphicsId !== undefined &&
|
||||
isArraysEqual(selectGraphicId, appSelectedGraphicsId)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const deviceFilter = lineStore.selectedGraphics?.filter((g) => {
|
||||
let select = false;
|
||||
if (
|
||||
g.type == Station.Type &&
|
||||
(g as Station).datas.concentrationStations &&
|
||||
setAlartTextData.value.alertType == '蓝显'
|
||||
) {
|
||||
select = true;
|
||||
}
|
||||
if (
|
||||
g.type !== Station.Type &&
|
||||
mapAlertType.get(setAlartTextData.value.alertType)?.includes(g.type)
|
||||
) {
|
||||
select = true;
|
||||
}
|
||||
return select;
|
||||
}) as JlGraphic[];
|
||||
if (setAlartTextData.value.alertType !== '列车信号故障') {
|
||||
selectGraphic.push(...deviceFilter);
|
||||
} else if (deviceFilter.length) {
|
||||
selectGraphic = [deviceFilter[0]];
|
||||
}
|
||||
selectGraphic = Array.from(new Set(selectGraphic));
|
||||
lineStore.getLineApp().updateSelected(...selectGraphic);
|
||||
setAlartTextData.value.groupList[clickIndex].deviceInfos = [];
|
||||
selectGraphic.forEach((g) => {
|
||||
setAlartTextData.value.groupList[clickIndex as number].deviceInfos.push(
|
||||
{
|
||||
deviceName: g.code,
|
||||
deviceType: (DeviceType as never)[g.type + ''],
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
lineStore.getLineApp().emit('options-update', {
|
||||
mouseToolOptions: {
|
||||
boxSelect: true,
|
||||
viewportDrag: true,
|
||||
viewportDragLeft: false,
|
||||
wheelZoom: true,
|
||||
},
|
||||
});
|
||||
onReset();
|
||||
setAlartTextData.value.lineId = lineStore.lineId as unknown as string;
|
||||
});
|
||||
|
||||
const myForm = ref<QForm | null>(null);
|
||||
const showsetAlartText = ref(true);
|
||||
const $q = useQuasar();
|
||||
|
||||
async function onSubmit() {
|
||||
myForm.value?.validate().then(async (res) => {
|
||||
if (res) {
|
||||
const deviceInfos = setAlartTextData.value.groupList
|
||||
.map((group) => {
|
||||
const deviceInfo = group.deviceInfos.map((deviceInfo) => {
|
||||
const status = group.status;
|
||||
const groupId = group.groupId || '';
|
||||
return {
|
||||
deviceName: deviceInfo.deviceName,
|
||||
deviceType: deviceInfo.deviceType,
|
||||
status,
|
||||
groupId,
|
||||
};
|
||||
});
|
||||
return deviceInfo;
|
||||
})
|
||||
.flat();
|
||||
try {
|
||||
const params = {
|
||||
lineId: +setAlartTextData.value.lineId,
|
||||
deviceInfos,
|
||||
};
|
||||
const alertType = (saveAlertTypeData as never)[
|
||||
setAlartTextData.value.alertType + ''
|
||||
];
|
||||
await mockLocalDemoTestSet(alertType, params);
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: '设置故障测试成功',
|
||||
});
|
||||
onReset();
|
||||
} catch (err) {
|
||||
const apiErr = err as ApiError;
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: apiErr.title,
|
||||
});
|
||||
} finally {
|
||||
showsetAlartText.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let clickIndex: null | number = null;
|
||||
function toggleItem(index: number) {
|
||||
const lineApp = lineStore.getLineApp();
|
||||
selectGraphic = [];
|
||||
lineApp.updateSelected();
|
||||
if (setAlartTextData.value.groupList[index].expanded == true) {
|
||||
clickIndex = index;
|
||||
const select: JlGraphic[] = [];
|
||||
setAlartTextData.value.groupList[index].deviceInfos.forEach(
|
||||
(deviceInfo) => {
|
||||
const deviceType = (
|
||||
Object.keys(DeviceType) as Array<keyof typeof DeviceType>
|
||||
).find((key) => DeviceType[key] === deviceInfo.deviceType) as string;
|
||||
const g = lineApp.queryStore.queryByCodeAndType(
|
||||
deviceInfo.deviceName,
|
||||
deviceType
|
||||
) as JlGraphic;
|
||||
select.push(g);
|
||||
}
|
||||
);
|
||||
lineApp.updateSelected(...select);
|
||||
} else {
|
||||
clickIndex = null;
|
||||
}
|
||||
}
|
||||
|
||||
function clickSelectCenter(index: number) {
|
||||
const lineApp = lineStore.getLineApp();
|
||||
const clickTarget = setAlartTextData.value.groupList[clickIndex as number];
|
||||
const deviceType = (
|
||||
Object.keys(DeviceType) as Array<keyof typeof DeviceType>
|
||||
).find(
|
||||
(key) => DeviceType[key] === clickTarget.deviceInfos[index].deviceType
|
||||
) as string;
|
||||
const clickGraphic = lineApp.queryStore.queryByCodeAndType(
|
||||
clickTarget.deviceInfos[index].deviceName,
|
||||
deviceType
|
||||
) as JlGraphic;
|
||||
lineApp.makeGraphicCenterShow(clickGraphic);
|
||||
}
|
||||
|
||||
function removeSelect(removeIndex: number) {
|
||||
const clickTarget = setAlartTextData.value.groupList[clickIndex as number];
|
||||
selectGraphic.splice(removeIndex, 1);
|
||||
clickTarget.deviceInfos.splice(removeIndex, 1);
|
||||
lineStore.getLineApp().updateSelected(...selectGraphic);
|
||||
}
|
||||
|
||||
function clearAllSelect(index: number) {
|
||||
setAlartTextData.value.groupList[index].deviceInfos = [];
|
||||
selectGraphic = [];
|
||||
lineStore.getLineApp().updateSelected();
|
||||
}
|
||||
|
||||
function addSelectConfig() {
|
||||
setAlartTextData.value.groupList.push({
|
||||
groupName: '测试组',
|
||||
groupId: '',
|
||||
status: '',
|
||||
deviceInfos: [],
|
||||
expanded: false,
|
||||
});
|
||||
}
|
||||
|
||||
function deleteSelectConfig(index: number) {
|
||||
setAlartTextData.value.groupList.splice(index, 1);
|
||||
selectGraphic = [];
|
||||
lineStore.getLineApp().updateSelected();
|
||||
}
|
||||
|
||||
function onChooseAlertType() {
|
||||
setAlartTextData.value.groupList = [
|
||||
{
|
||||
groupName: '测试组',
|
||||
groupId: '',
|
||||
status: '',
|
||||
deviceInfos: [],
|
||||
expanded: false,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function onReset() {
|
||||
setAlartTextData.value = {
|
||||
lineId: lineStore.lineId as unknown as string,
|
||||
alertType: '',
|
||||
groupList: [
|
||||
{
|
||||
groupName: '测试组',
|
||||
groupId: '',
|
||||
status: '',
|
||||
deviceInfos: [],
|
||||
expanded: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
selectGraphic = [];
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
lineStore.getLineApp().emit('options-update', {
|
||||
mouseToolOptions: {
|
||||
boxSelect: false,
|
||||
viewportDrag: true,
|
||||
viewportDragLeft: true,
|
||||
wheelZoom: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
@ -1,60 +1,8 @@
|
||||
<template>
|
||||
<q-dialog
|
||||
ref="dialogRef"
|
||||
@hide="onHide"
|
||||
v-bind="$attrs"
|
||||
@show="emit('show')"
|
||||
transitionShow="jump-up"
|
||||
transitionHide="jump-down"
|
||||
class="column"
|
||||
>
|
||||
<q-card
|
||||
:style="{
|
||||
transform: `translate3d(${offset.x}px, ${offset.y}px, 1px)`,
|
||||
background: `${props.bgColor}`,
|
||||
border: `${props.bgBorder}`,
|
||||
}"
|
||||
style="max-width: 2000px"
|
||||
>
|
||||
<q-bar
|
||||
ref="headerRef"
|
||||
class="non-selectable q-gutter-l"
|
||||
style="
|
||||
cursor: move;
|
||||
border-top-right-radius: 0;
|
||||
border-top-left-radius: 0;
|
||||
"
|
||||
:style="`height: ${props.titleHeight}px;background: ${props.titleColor}`"
|
||||
>
|
||||
<div
|
||||
:style="`height: 100%; line-height: ${props.titleHeight}px; color:${props.fontColor};font-size: ${props.fontSize}px;`"
|
||||
>
|
||||
{{ props.title }}
|
||||
</div>
|
||||
<q-space />
|
||||
<div style="margin-right: 10px"><slot name="titleButton"></slot></div>
|
||||
<q-btn dense flat icon="sym_o_close" v-close-popup></q-btn>
|
||||
</q-bar>
|
||||
<q-scroll-area
|
||||
:style="`width: ${props.width}px; height: ${props.height}px;`"
|
||||
>
|
||||
<slot></slot>
|
||||
</q-scroll-area>
|
||||
<div :style="`width: ${props.width}px`">
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { QBar, useDialogPluginComponent } from 'quasar';
|
||||
import { ref, onMounted, onUnmounted, reactive } from 'vue';
|
||||
import { ref, onMounted, onUnmounted, reactive, withDefaults } from 'vue';
|
||||
|
||||
const emit = defineEmits({
|
||||
...useDialogPluginComponent.emitsObject,
|
||||
show: () => true,
|
||||
});
|
||||
const emit = defineEmits([...useDialogPluginComponent.emits]);
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@ -66,7 +14,6 @@ const props = withDefaults(
|
||||
width?: number;
|
||||
height?: number;
|
||||
bgColor?: string;
|
||||
bgBorder?: string;
|
||||
}>(),
|
||||
{
|
||||
width: 500,
|
||||
@ -89,7 +36,6 @@ const offset = reactive({
|
||||
});
|
||||
|
||||
const start = { x: 0, y: 0 };
|
||||
const startOffset = { x: 0, y: 0 };
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('mousedown', onMouseDown);
|
||||
@ -100,24 +46,16 @@ onUnmounted(() => {
|
||||
});
|
||||
|
||||
function onMove(e: MouseEvent) {
|
||||
let y = e.clientY > startOffset.y ? e.clientY : startOffset.y;
|
||||
if (y > window.innerHeight - props.titleHeight + startOffset.y) {
|
||||
y = window.innerHeight - props.titleHeight + startOffset.y;
|
||||
}
|
||||
[offset.x, offset.y] = [e.clientX - start.x, y - start.y];
|
||||
[offset.x, offset.y] = [e.screenX - start.x, e.screenY - start.y];
|
||||
}
|
||||
function onMouseUp() {
|
||||
window.removeEventListener('mousemove', onMove);
|
||||
window.removeEventListener('mouseup', onMouseUp);
|
||||
startOffset.x = 0;
|
||||
startOffset.y = 0;
|
||||
}
|
||||
function onMouseDown(e: MouseEvent) {
|
||||
if (!e.target || !headerRef.value?.$el.contains(e.target)) return;
|
||||
startOffset.x = e.offsetX;
|
||||
startOffset.y = e.offsetY;
|
||||
start.x = e.clientX - offset.x;
|
||||
start.y = e.clientY - offset.y;
|
||||
if (headerRef.value?.$el !== e.target) return;
|
||||
start.x = e.screenX - offset.x;
|
||||
start.y = e.screenY - offset.y;
|
||||
window.addEventListener('mousemove', onMove);
|
||||
window.addEventListener('mouseup', onMouseUp);
|
||||
}
|
||||
@ -126,3 +64,45 @@ function onHide() {
|
||||
onDialogHide();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog
|
||||
ref="dialogRef"
|
||||
@hide="onHide"
|
||||
v-bind="$attrs"
|
||||
transitionShow="jump-up"
|
||||
transitionHide="jump-down"
|
||||
class="column"
|
||||
>
|
||||
<q-card
|
||||
:style="{
|
||||
transform: `translate3d(${offset.x}px, ${offset.y}px, 1px)`,
|
||||
background: `${props.bgColor}`,
|
||||
}"
|
||||
style="max-width: 2000px"
|
||||
>
|
||||
<q-bar
|
||||
ref="headerRef"
|
||||
class="non-selectable q-gutter-l"
|
||||
style="cursor: move"
|
||||
:style="`height: ${props.titleHeight}px;background: ${props.titleColor}`"
|
||||
>
|
||||
<div
|
||||
:style="`color:${props.fontColor};font-size: ${props.fontSize}px;`"
|
||||
>
|
||||
{{ props.title }}
|
||||
</div>
|
||||
<q-space />
|
||||
<q-btn dense flat icon="sym_o_close" v-close-popup></q-btn>
|
||||
</q-bar>
|
||||
<q-scroll-area
|
||||
:style="`width: ${props.width}px; height: ${props.height}px;`"
|
||||
>
|
||||
<slot></slot>
|
||||
</q-scroll-area>
|
||||
<div :style="`width: ${props.width}px`">
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
@ -19,6 +19,9 @@
|
||||
<template v-if="drawStore.drawGraphicType === Station.Type">
|
||||
<station-template></station-template>
|
||||
</template>
|
||||
<!-- <template v-if="drawStore.drawGraphicType === Train.Type">
|
||||
<train-template></train-template>
|
||||
</template> -->
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
@ -51,6 +54,9 @@
|
||||
<station-line-property
|
||||
v-if="drawStore.selectedGraphicType === StationLine.Type"
|
||||
></station-line-property>
|
||||
<!-- <train-property
|
||||
v-if="drawStore.selectedGraphicType === Train.Type"
|
||||
></train-property> -->
|
||||
<iscs-fan-property
|
||||
v-else-if="drawStore.selectedGraphicType === IscsFan.Type"
|
||||
></iscs-fan-property>
|
||||
@ -81,11 +87,6 @@
|
||||
<LogicSectionProperty
|
||||
v-else-if="drawStore.selectedGraphicType === LogicSection.Type"
|
||||
/>
|
||||
<concentrationDividingLine-property
|
||||
v-else-if="
|
||||
drawStore.selectedGraphicType === ConcentrationDividingLine.Type
|
||||
"
|
||||
/>
|
||||
</q-card-section>
|
||||
</template>
|
||||
</q-card>
|
||||
@ -95,8 +96,6 @@
|
||||
<script setup lang="ts">
|
||||
import LinkTemplate from './templates/LinkTemplate.vue';
|
||||
import RectTemplate from './templates/RectTemplate.vue';
|
||||
import ConcentrationDividingLineProperty from './properties/ConcentrationDividingLineProperty.vue';
|
||||
import { ConcentrationDividingLine } from 'src/graphics/concentrationDividingLine/ConcentrationDividingLine';
|
||||
import PlatformTemplate from './templates/PlatformTemplate.vue';
|
||||
import StationTemplate from './templates/StationTemplate.vue';
|
||||
// import TrainTemplate from './templates/TrainTemplate.vue';
|
||||
|
@ -1,64 +0,0 @@
|
||||
<!-- eslint-disable vue/no-mutating-props -->
|
||||
<template>
|
||||
<q-dialog ref="dialogRef" style="width 800px;">
|
||||
<q-card
|
||||
style="max-width: 900px"
|
||||
:style="{ width: `${80 * props.runLinePoints.length}px` }"
|
||||
>
|
||||
<q-card-section> <div class="text-h6">划定端点</div> </q-card-section>
|
||||
<q-card-section class="q-pt-none">
|
||||
<q-range
|
||||
class="q-mt-xl"
|
||||
v-model="model"
|
||||
color="purple"
|
||||
style="padding: 0px 30px; font-size: 10px"
|
||||
markers
|
||||
:marker-labels="objMarkerLabel"
|
||||
:min="0"
|
||||
:max="props.runLinePoints.length - 1"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right" class="text-primary">
|
||||
<q-btn flat label="取消" @click="onDialogCancel" v-close-popup />
|
||||
<q-btn flat label="确认" @click="onDialogOK(model)" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { IPointData } from 'pixi.js';
|
||||
import { useDialogPluginComponent } from 'quasar';
|
||||
import { ref, onMounted } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
runLinePoints: {
|
||||
type: Array<IPointData>,
|
||||
required: true,
|
||||
},
|
||||
garyPointIndexs: {
|
||||
type: Array<number>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const objMarkerLabel = (val: number) =>
|
||||
`P${val}[${props.runLinePoints[val].x},${props.runLinePoints[val].y}]`;
|
||||
const model = ref({
|
||||
min: 0,
|
||||
max: 0,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (props.garyPointIndexs.length) {
|
||||
model.value = {
|
||||
min: props.garyPointIndexs[0],
|
||||
max: props.garyPointIndexs[props.garyPointIndexs.length - 1],
|
||||
};
|
||||
}
|
||||
});
|
||||
defineEmits([...useDialogPluginComponent.emits]);
|
||||
|
||||
const { dialogRef, onDialogOK, onDialogCancel } = useDialogPluginComponent();
|
||||
</script>
|
||||
<style scoped></style>
|
@ -1,6 +1,12 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-input outlined readonly v-model="axleCountingModel.id" label="id" />
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
v-model="axleCountingModel.id"
|
||||
label="id"
|
||||
hint=""
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
label="计轴名称"
|
||||
@ -10,13 +16,10 @@
|
||||
lazy-rules
|
||||
autogrow
|
||||
/>
|
||||
<q-list bordered separator class="rounded-borders">
|
||||
<q-item no-wrap class="q-gutter-y-sm column">
|
||||
<div>公里标配置</div>
|
||||
<q-select
|
||||
outlined
|
||||
style="margin-top: 10px"
|
||||
v-model="axleCountingModel.kilometerSystem.coordinateSystem"
|
||||
v-model="kilometerSystem.coordinateSystem"
|
||||
:options="CoordinateSystemOptions"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@ -26,13 +29,11 @@
|
||||
<q-input
|
||||
outlined
|
||||
style="margin-top: 10px"
|
||||
v-model.number="axleCountingModel.kilometerSystem.kilometer"
|
||||
v-model.number="kilometerSystem.kilometer"
|
||||
type="number"
|
||||
@blur="onUpdate"
|
||||
label="公里标(mm):"
|
||||
/>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<q-list bordered separator class="rounded-borders">
|
||||
<q-item>
|
||||
<q-item-section no-wrap class="q-gutter-y-sm column">
|
||||
@ -71,19 +72,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { AxleCountingData } from 'src/drawApp/graphics/AxleCountingInteraction';
|
||||
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { Turnout } from 'src/graphics/turnout/Turnout';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { computed } from 'vue';
|
||||
import { computed, onMounted, reactive, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: axleCountingModel, onUpdate } = useFormData(
|
||||
new AxleCountingData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
const axleCountingModel = reactive(new AxleCountingData());
|
||||
const kilometerSystem = reactive({ coordinateSystem: '', kilometer: 0 });
|
||||
|
||||
const CoordinateSystemOptions = [
|
||||
{ label: '车辆段', value: 'DEPOT' },
|
||||
{ label: '停车场', value: 'PARKING_LOT' },
|
||||
@ -91,6 +90,46 @@ const CoordinateSystemOptions = [
|
||||
{ label: '换线', value: 'TRANSFER' },
|
||||
];
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == AxleCounting.Type) {
|
||||
axleCountingModel.copyFrom(val.saveData() as AxleCountingData);
|
||||
if (axleCountingModel.kilometerSystem) {
|
||||
kilometerSystem.coordinateSystem =
|
||||
axleCountingModel.kilometerSystem.coordinateSystem;
|
||||
kilometerSystem.kilometer = axleCountingModel.kilometerSystem.kilometer;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const axleCounting = drawStore.selectedGraphic as AxleCounting;
|
||||
if (axleCounting) {
|
||||
axleCountingModel.copyFrom(axleCounting.saveData());
|
||||
if (axleCountingModel.kilometerSystem) {
|
||||
kilometerSystem.coordinateSystem =
|
||||
axleCountingModel.kilometerSystem.coordinateSystem;
|
||||
kilometerSystem.kilometer = axleCountingModel.kilometerSystem.kilometer;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
const axleCounting = drawStore.selectedGraphic as AxleCounting;
|
||||
axleCountingModel.kilometerSystem = {
|
||||
coordinateSystem: kilometerSystem.coordinateSystem,
|
||||
kilometer: kilometerSystem.kilometer,
|
||||
};
|
||||
if (axleCounting) {
|
||||
drawStore
|
||||
.getDrawApp()
|
||||
.updateGraphicAndRecord(axleCounting, axleCountingModel);
|
||||
}
|
||||
}
|
||||
|
||||
const sectionRelations = computed(() => {
|
||||
const axleCounting = drawStore.selectedGraphic as AxleCounting;
|
||||
const sectionRelations =
|
||||
|
@ -1,126 +0,0 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
v-model="concentrationDividingLineModel.id"
|
||||
label="id"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
style="margin-top: 10px"
|
||||
v-model="concentrationDividingLineModel.refLeftStationId"
|
||||
:options="centralizedStations"
|
||||
emitValue
|
||||
mapOptions
|
||||
@update:model-value="onUpdate"
|
||||
label="左边关联的集中站"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
style="margin-top: 10px"
|
||||
v-model="concentrationDividingLineModel.refRightStationId"
|
||||
:options="centralizedStations"
|
||||
emitValue
|
||||
mapOptions
|
||||
@update:model-value="onUpdate"
|
||||
label="右边关联的集中站"
|
||||
/>
|
||||
<q-toggle
|
||||
v-model="
|
||||
concentrationDividingLineModel.isOtherLineConcentrationDividingLine
|
||||
"
|
||||
label="是否与其它线的边界处"
|
||||
emit-value
|
||||
@update:model-value="onUpdate"
|
||||
/>
|
||||
<q-list bordered separator class="rounded-borders">
|
||||
<q-item
|
||||
v-for="sectionRelation in sectionRelations"
|
||||
:key="sectionRelation.label"
|
||||
>
|
||||
<q-item-section no-wrap class="q-gutter-y-sm column">
|
||||
<q-item-label> {{ sectionRelation.label }} </q-item-label>
|
||||
<div class="q-gutter-sm row">
|
||||
<q-chip
|
||||
v-for="(item, index) in sectionRelation.refSectionInfo"
|
||||
:key="index"
|
||||
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 { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { ConcentrationDividingLineData } from 'src/drawApp/graphics/ConcentrationDividingLineInteraction';
|
||||
import { ConcentrationDividingLine } from 'src/graphics/concentrationDividingLine/ConcentrationDividingLine';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: concentrationDividingLineModel, onUpdate } = useFormData(
|
||||
new ConcentrationDividingLineData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
const centralizedStations = ref<{ label: string; value: number }[]>([]);
|
||||
|
||||
const sectionRelations = computed(() => {
|
||||
const refSectionInfo: { label: string; refSectionInfo: string[] }[] = [
|
||||
{ label: '左边关联的设备', refSectionInfo: [] },
|
||||
{ label: '右边关联的设备', refSectionInfo: [] },
|
||||
];
|
||||
enum devicePort {
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
}
|
||||
const concentrationDividingLine =
|
||||
drawStore.selectedGraphic as ConcentrationDividingLine;
|
||||
concentrationDividingLine.datas.nodeConWithSecs.forEach((nodeConWithSec) => {
|
||||
const refleftSection = nodeConWithSec.leftSection?.id
|
||||
? `${
|
||||
drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryById<Section>(nodeConWithSec.leftSection.id).datas
|
||||
.code
|
||||
}(${devicePort[nodeConWithSec.leftSection.devicePort]})`
|
||||
: '边界';
|
||||
refSectionInfo[0].refSectionInfo.push(refleftSection);
|
||||
const refRightSection = nodeConWithSec.rightSection?.id
|
||||
? `${
|
||||
drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryById<Section>(nodeConWithSec.rightSection.id).datas
|
||||
.code
|
||||
}(${devicePort[nodeConWithSec.rightSection.devicePort]})`
|
||||
: '边界';
|
||||
refSectionInfo[1].refSectionInfo.push(refRightSection);
|
||||
});
|
||||
return refSectionInfo;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
const stations = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Station>(Station.Type);
|
||||
centralizedStations.value = [{ label: '', value: 0 }];
|
||||
stations.forEach((station) => {
|
||||
if (station.datas.concentrationStations || station.datas.depots) {
|
||||
centralizedStations.value.push({
|
||||
label: station.datas.name,
|
||||
value: station.datas.id,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
@ -59,13 +59,38 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { LinkData } from 'src/drawApp/graphics/LinkInteraction';
|
||||
import { Link } from 'src/graphics/link/Link';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: linkModel, onUpdate } = useFormData(
|
||||
new LinkData(),
|
||||
drawStore.getDrawApp()
|
||||
const linkModel = reactive(new LinkData());
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Link.Type) {
|
||||
// console.log('link变更');
|
||||
linkModel.copyFrom(val.saveData() as LinkData);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
// console.log('link 属性表单 mounted');
|
||||
const link = drawStore.selectedGraphic as Link;
|
||||
if (link) {
|
||||
linkModel.copyFrom(link.saveData());
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
console.log('link 属性更新');
|
||||
const link = drawStore.selectedGraphic as Link;
|
||||
if (link) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(link, linkModel);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,15 +1,10 @@
|
||||
<template>
|
||||
<q-form>
|
||||
<q-input outlined readonly v-model="sectionModel.id" label="id" hint="" />
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
v-model="logicSectionModel.id"
|
||||
label="id"
|
||||
hint=""
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
v-model="logicSectionModel.code"
|
||||
v-model="sectionModel.code"
|
||||
@blur="onUpdate"
|
||||
label="编号"
|
||||
/>
|
||||
@ -17,13 +12,26 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { LogicSectionData } from 'src/drawApp/graphics/LogicSectionInteraction';
|
||||
import { LogicSection } from 'src/graphics/logicSection/LogicSection';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { shallowRef, watchEffect } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: logicSectionModel, onUpdate } = useFormData(
|
||||
new LogicSectionData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
|
||||
const sectionModel = shallowRef(new LogicSectionData());
|
||||
|
||||
watchEffect(() => {
|
||||
const section = drawStore.selectedGraphic;
|
||||
if (section && section instanceof LogicSection) {
|
||||
sectionModel.value = section.saveData();
|
||||
}
|
||||
});
|
||||
|
||||
const onUpdate = () => {
|
||||
const section = drawStore.selectedGraphic as LogicSection;
|
||||
if (section) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(section, sectionModel.value);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -52,18 +52,25 @@
|
||||
</q-form>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { PathLineData } from 'src/drawApp/graphics/PathLineInteraction';
|
||||
import { PathLine } from 'src/graphics/pathLine/PathLine';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { reactive, onMounted } from 'vue';
|
||||
import { reactive, onMounted, watch } from 'vue';
|
||||
import { getLineList } from 'src/api/LineInfoApi';
|
||||
const drawStore = useDrawStore();
|
||||
const { data: pathLineModel, onUpdate } = useFormData(
|
||||
new PathLineData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
const pathLineModel = reactive(new PathLineData());
|
||||
const lineList: { label: string; value: string }[] = reactive([]);
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == PathLine.Type) {
|
||||
pathLineModel.copyFrom(val.saveData() as PathLineData);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
getLineList()
|
||||
.then((res) => {
|
||||
@ -74,5 +81,16 @@ onMounted(() => {
|
||||
.catch((err) => {
|
||||
console.error('获取线路列表失败:' + err.message);
|
||||
});
|
||||
const pathLine = drawStore.selectedGraphic as PathLine;
|
||||
if (pathLine) {
|
||||
pathLineModel.copyFrom(pathLine.saveData());
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
const pathLine = drawStore.selectedGraphic as PathLine;
|
||||
if (pathLine) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(pathLine, pathLineModel);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-input outlined readonly v-model="platformModel.id" label="id" />
|
||||
<q-input outlined readonly v-model="platformModel.id" label="id" hint="" />
|
||||
<q-input
|
||||
outlined
|
||||
label="站台名称"
|
||||
@ -10,30 +10,26 @@
|
||||
lazy-rules
|
||||
autogrow
|
||||
/>
|
||||
<q-toggle
|
||||
v-model="platformModel.hasdoor"
|
||||
label="是否有屏蔽门"
|
||||
emit-value
|
||||
@update:model-value="onUpdate"
|
||||
/>
|
||||
<q-select
|
||||
v-if="platformModel.hasdoor"
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="platformModel.direction"
|
||||
v-model="hasDoor"
|
||||
:options="optionsDoor"
|
||||
label="是否有屏蔽门"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="direction"
|
||||
:options="optionsDirection"
|
||||
label="方向"
|
||||
map-options
|
||||
emit-value
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="platformModel.up"
|
||||
v-model="upAndDown"
|
||||
:options="optionsUpAndDown"
|
||||
label="上下行"
|
||||
map-options
|
||||
emit-value
|
||||
/>
|
||||
<q-list bordered separator class="rounded-borders">
|
||||
<q-item>
|
||||
@ -46,85 +42,89 @@
|
||||
</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<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 square color="primary" text-color="white">
|
||||
{{ sectionName }}
|
||||
</q-chip>
|
||||
</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="platformModel.centralizedStation"
|
||||
:options="centralizedStations"
|
||||
emitValue
|
||||
mapOptions
|
||||
@update:model-value="onUpdate"
|
||||
label="关联的集中站"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { PlatformData } from 'src/drawApp/graphics/PlatformInteraction';
|
||||
import { Platform } from 'src/graphics/platform/Platform';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: platformModel, onUpdate } = useFormData(
|
||||
new PlatformData(),
|
||||
drawStore.getDrawApp()
|
||||
const platformModel = reactive(new PlatformData());
|
||||
const hasDoor = ref('是');
|
||||
const optionsDoor = ['是', '否'];
|
||||
const direction = ref('向上');
|
||||
const upAndDown = ref('');
|
||||
const optionsDirection = ['向上', '向下'];
|
||||
const optionsUpAndDown = ['上行', '下行'];
|
||||
const stationName = ref('');
|
||||
enum showSelect {
|
||||
是 = 'true',
|
||||
否 = 'false',
|
||||
向上 = 'up',
|
||||
向下 = 'down',
|
||||
}
|
||||
enum showUp {
|
||||
上行 = 'true',
|
||||
下行 = 'false',
|
||||
}
|
||||
enum showSelectData {
|
||||
true = '是',
|
||||
false = '否',
|
||||
up = '向上',
|
||||
down = '向下',
|
||||
}
|
||||
enum showUpData {
|
||||
true = '上行',
|
||||
false = '下行',
|
||||
}
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Platform.Type) {
|
||||
platformModel.copyFrom(val.saveData() as PlatformData);
|
||||
hasDoor.value = (showSelectData as never)[platformModel.hasdoor + ''];
|
||||
direction.value = (showSelectData as never)[platformModel.direction];
|
||||
upAndDown.value = (showUpData as never)[platformModel.up + ''];
|
||||
if (platformModel.refStation) {
|
||||
const refStation = val.queryStore.queryById<Station>(
|
||||
platformModel.refStation
|
||||
) as Station;
|
||||
stationName.value = refStation.datas.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
const stationName = computed(() => {
|
||||
|
||||
onMounted(() => {
|
||||
const platform = drawStore.selectedGraphic as Platform;
|
||||
if (platform) {
|
||||
platformModel.copyFrom(platform.saveData());
|
||||
hasDoor.value = (showSelectData as never)[platformModel.hasdoor + ''];
|
||||
direction.value = (showSelectData as never)[platformModel.direction];
|
||||
upAndDown.value = (showUpData as never)[platformModel.up + ''];
|
||||
if (platformModel.refStation) {
|
||||
const refStation = platform.queryStore.queryById<Station>(
|
||||
platformModel.refStation
|
||||
);
|
||||
return refStation.datas.name;
|
||||
) as Station;
|
||||
stationName.value = refStation.datas.name;
|
||||
}
|
||||
return '';
|
||||
});
|
||||
const sectionName = computed(() => {
|
||||
const platform = drawStore.selectedGraphic as Platform;
|
||||
if (platformModel.refSectionId) {
|
||||
const refSection = platform.queryStore.queryById<Section>(
|
||||
platformModel.refSectionId
|
||||
);
|
||||
return refSection.datas.code;
|
||||
}
|
||||
return '';
|
||||
});
|
||||
const optionsDirection = [
|
||||
{ label: '向上', value: 'up' },
|
||||
{ label: '向下', value: 'down' },
|
||||
];
|
||||
const optionsUpAndDown = [
|
||||
{ label: '上行', value: true },
|
||||
{ label: '下行', value: false },
|
||||
];
|
||||
const centralizedStations = ref<{ label: string; value: number }[]>([]);
|
||||
|
||||
onMounted(() => {
|
||||
const stations = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Station>(Station.Type);
|
||||
centralizedStations.value = [{ label: '', value: 0 }];
|
||||
stations.forEach((station) => {
|
||||
if (station.datas.concentrationStations || station.datas.depots) {
|
||||
centralizedStations.value.push({
|
||||
label: station.datas.name,
|
||||
value: station.datas.id,
|
||||
});
|
||||
function onUpdate() {
|
||||
platformModel.hasdoor = JSON.parse((showSelect as never)[hasDoor.value]);
|
||||
platformModel.direction = (showSelect as never)[direction.value];
|
||||
platformModel.up = JSON.parse((showUp as never)[upAndDown.value]);
|
||||
const platform = drawStore.selectedGraphic as Platform;
|
||||
if (platform) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(platform, platformModel);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
@ -66,13 +66,35 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { RectData } from 'src/drawApp/graphics/RectInteraction';
|
||||
import { Rect } from 'src/graphics/rect/Rect';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: rectModel, onUpdate } = useFormData(
|
||||
new RectData(),
|
||||
drawStore.getDrawApp()
|
||||
const rectModel = reactive(new RectData());
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Rect.Type) {
|
||||
rectModel.copyFrom(val.saveData() as RectData);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const Rect = drawStore.selectedGraphic as Rect;
|
||||
if (Rect) {
|
||||
rectModel.copyFrom(Rect.saveData());
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
const Rect = drawStore.selectedGraphic as Rect;
|
||||
if (Rect) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(Rect, rectModel);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -68,30 +68,6 @@
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-input
|
||||
outlined
|
||||
v-model="runLineModel.lineColor"
|
||||
@blur="onUpdate"
|
||||
label="线路背景色"
|
||||
lazy-rules
|
||||
:rules="[(val) => (val && val.length > 0) || '线路背景色不能为空']"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="colorize" class="cursor-pointer">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-color
|
||||
v-model="runLineModel.lineColor"
|
||||
@change="
|
||||
(val) => {
|
||||
runLineModel.lineColor = val;
|
||||
onUpdate();
|
||||
}
|
||||
"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
<template :key="item" v-for="(item, index) in runLineModel.points">
|
||||
<div style="display: flex; margin-top: 5px">
|
||||
<q-input
|
||||
@ -142,11 +118,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { RunLineData } from 'src/drawApp/graphics/RunLineInteraction';
|
||||
import { RunLine } from 'src/graphics/runLine/RunLine';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { onMounted, reactive, watch, ref } from 'vue';
|
||||
import { Point } from 'pixi.js';
|
||||
import {
|
||||
IStationLineData,
|
||||
@ -155,13 +130,20 @@ import {
|
||||
import { getLineList } from 'src/api/LineInfoApi';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: runLineModel, onUpdate } = useFormData(
|
||||
new RunLineData(),
|
||||
useDrawStore().getDrawApp()
|
||||
);
|
||||
const runLineModel = reactive(new RunLineData());
|
||||
const stationLines: IStationLineData[] = reactive([]);
|
||||
const lineList: { label: string; value: string }[] = reactive([]);
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == RunLine.Type) {
|
||||
runLineModel.copyFrom(val.saveData() as RunLineData);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
getLineList()
|
||||
.then((res) => {
|
||||
@ -172,23 +154,31 @@ onMounted(() => {
|
||||
.catch((err) => {
|
||||
console.error('获取线路列表失败:' + err.message);
|
||||
});
|
||||
const runLine = drawStore.selectedGraphic as RunLine;
|
||||
const stations = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType(StationLine.Type) as StationLine[];
|
||||
stations.forEach((item) => stationLines.push(item.datas));
|
||||
if (runLine) {
|
||||
runLineModel.copyFrom(runLine.saveData());
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
const runLine = drawStore.selectedGraphic as RunLine;
|
||||
if (runLine) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(runLine, runLineModel);
|
||||
}
|
||||
}
|
||||
function generatePathLine() {
|
||||
const runLine = drawStore.selectedGraphic as RunLine;
|
||||
if (runLine) {
|
||||
const points = runLineModel.points;
|
||||
const points1: Point[] = [];
|
||||
runLineModel.points.forEach((p) =>
|
||||
points1.push(runLine.localToCanvasPoint(new Point(p.x, p.y)))
|
||||
);
|
||||
points.forEach((p) => points1.push(new Point(p.x, p.y)));
|
||||
runLine.generatePathLine(points1);
|
||||
}
|
||||
}
|
||||
|
||||
function generateContainSta() {
|
||||
const runLine = drawStore.selectedGraphic as RunLine;
|
||||
if (runLine) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-input outlined readonly v-model="sectionModel.id" label="id" />
|
||||
<q-form>
|
||||
<q-input outlined readonly v-model="sectionModel.id" label="id" hint="" />
|
||||
<q-input
|
||||
outlined
|
||||
v-model="sectionModel.code"
|
||||
@ -9,17 +9,14 @@
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
class="q-mt-lg"
|
||||
v-model="sectionModel.destinationCode"
|
||||
@blur="onUpdate"
|
||||
label="目的地码"
|
||||
/>
|
||||
<q-checkbox
|
||||
v-model="sectionModel.turning"
|
||||
label="是否转换轨"
|
||||
@update:model-value="onUpdate"
|
||||
></q-checkbox>
|
||||
<q-field
|
||||
v-if="!isTurnoutPhysicalSection"
|
||||
class="q-mt-lg"
|
||||
outlined
|
||||
label="关联区段"
|
||||
readonly
|
||||
@ -38,6 +35,7 @@
|
||||
</q-field>
|
||||
<q-field
|
||||
v-if="!isTurnoutPhysicalSection"
|
||||
class="q-mt-lg"
|
||||
outlined
|
||||
label="关联道岔"
|
||||
readonly
|
||||
@ -66,33 +64,20 @@
|
||||
>
|
||||
</template>
|
||||
</q-field>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="sectionModel.centralizedStation"
|
||||
:options="centralizedStations"
|
||||
emitValue
|
||||
mapOptions
|
||||
@update:model-value="onUpdate"
|
||||
label="关联的集中站"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { SectionData } from 'src/drawApp/graphics/SectionInteraction';
|
||||
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
|
||||
import { Section, SectionType } from 'src/graphics/section/Section';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { Turnout } from 'src/graphics/turnout/Turnout';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { computed, shallowRef, watchEffect } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: sectionModel, onUpdate } = useFormData(
|
||||
new SectionData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
|
||||
const sectionModel = shallowRef(new SectionData());
|
||||
|
||||
const sectionRelations = computed(() => {
|
||||
const section = drawStore.selectedGraphic as Section;
|
||||
@ -102,15 +87,12 @@ const sectionRelations = computed(() => {
|
||||
section,
|
||||
Section.Type
|
||||
);
|
||||
return sectionRelations.map((relation) => {
|
||||
if (relation.getRelationParam(section).param) {
|
||||
return `${relation.getRelationParam(section).param}: ${
|
||||
return sectionRelations.map(
|
||||
(relation) =>
|
||||
`${relation.getRelationParam(section).param}: ${
|
||||
relation.getOtherGraphic<Section>(section).datas.code
|
||||
}(${relation.getOtherRelationParam(section).param})`;
|
||||
} else {
|
||||
return relation.getOtherGraphic<Section>(section).datas.code;
|
||||
}
|
||||
});
|
||||
}(${relation.getOtherRelationParam(section).param})`
|
||||
);
|
||||
});
|
||||
|
||||
const turnoutRelations = computed(() => {
|
||||
@ -147,21 +129,17 @@ const axleCountingRelations = computed(() => {
|
||||
(relation) => relation.getOtherGraphic<AxleCounting>(section).datas.code
|
||||
);
|
||||
});
|
||||
|
||||
const centralizedStations = ref<{ label: string; value: number }[]>([]);
|
||||
|
||||
onMounted(() => {
|
||||
const stations = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Station>(Station.Type);
|
||||
centralizedStations.value = [{ label: '', value: 0 }];
|
||||
stations.forEach((station) => {
|
||||
if (station.datas.concentrationStations || station.datas.depots) {
|
||||
centralizedStations.value.push({
|
||||
label: station.datas.name,
|
||||
value: station.datas.id,
|
||||
});
|
||||
watchEffect(() => {
|
||||
const section = drawStore.selectedGraphic;
|
||||
if (section && section instanceof Section) {
|
||||
sectionModel.value = section.saveData();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const onUpdate = () => {
|
||||
const section = drawStore.selectedGraphic as Section;
|
||||
if (section) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(section, sectionModel.value);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -16,16 +16,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { SeparatorData } from 'src/drawApp/graphics/SeparatorInteraction';
|
||||
import { separatorTypeEnum } from 'src/graphics/separator/Separator';
|
||||
import { Separator, separatorTypeEnum } from 'src/graphics/separator/Separator';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: separatorModel, onUpdate } = useFormData(
|
||||
new SeparatorData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
const separatorModel = reactive(new SeparatorData());
|
||||
|
||||
const typeOptions = [
|
||||
{ label: '区段分隔符', value: separatorTypeEnum.section },
|
||||
@ -33,4 +30,28 @@ const typeOptions = [
|
||||
{ label: '左断路分隔符', value: separatorTypeEnum.endA },
|
||||
{ label: '右断路分隔符', value: separatorTypeEnum.endB },
|
||||
];
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Separator.Type) {
|
||||
separatorModel.copyFrom(val.saveData() as SeparatorData);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const Separator = drawStore.selectedGraphic as Separator;
|
||||
if (Separator) {
|
||||
separatorModel.copyFrom(Separator.saveData());
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
const Separator = drawStore.selectedGraphic as Separator;
|
||||
if (Separator) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(Separator, separatorModel);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-input outlined readonly v-model="signalModel.id" label="id" />
|
||||
<q-form>
|
||||
<q-input outlined readonly v-model="signalModel.id" label="id" hint="" />
|
||||
<q-input
|
||||
outlined
|
||||
v-model.number="signalModel.code"
|
||||
@ -9,36 +9,8 @@
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="refDevData.deviceType"
|
||||
:options="DeviceTypeOptions"
|
||||
readonly
|
||||
map-options
|
||||
emit-value
|
||||
label="关联设备类型:"
|
||||
></q-select>
|
||||
<q-input
|
||||
outlined
|
||||
v-model="refDevData.code"
|
||||
:readonly="true"
|
||||
label="关联设备:"
|
||||
></q-input>
|
||||
<q-select
|
||||
outlined
|
||||
v-if="refDevData.deviceType === graphicData.RelatedRef.DeviceType.Turnout"
|
||||
v-model="refDevData.devicePort"
|
||||
:options="DevicePortOptions"
|
||||
:readonly="true"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@update:model-value="onUpdate"
|
||||
label="关联设备端口:"
|
||||
></q-select>
|
||||
<q-list bordered separator class="rounded-borders">
|
||||
<q-item no-wrap class="q-gutter-y-sm column">
|
||||
<div>公里标配置</div>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="signalModel.kilometerSystem.coordinateSystem"
|
||||
style="margin-top: 10px"
|
||||
v-model="kilometerSystem.coordinateSystem"
|
||||
:options="CoordinateSystemOptions"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@ -47,68 +19,24 @@
|
||||
></q-select>
|
||||
<q-input
|
||||
outlined
|
||||
v-model.number="signalModel.kilometerSystem.kilometer"
|
||||
style="margin-top: 10px"
|
||||
v-model.number="kilometerSystem.kilometer"
|
||||
type="number"
|
||||
@blur="onUpdate"
|
||||
label="公里标(mm):"
|
||||
/>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="signalModel.centralizedStation"
|
||||
:options="centralizedStations"
|
||||
emitValue
|
||||
mapOptions
|
||||
@update:model-value="onUpdate"
|
||||
label="关联的集中站"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { SignalData } from 'src/drawApp/graphics/SignalInteraction';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { Turnout } from 'src/graphics/turnout/Turnout';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { Signal } from 'src/graphics/signal/Signal';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { onMounted, reactive, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: signalModel, onUpdate } = useFormData(
|
||||
new SignalData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
|
||||
const refDevData = computed(() => {
|
||||
return signalModel.refDevice
|
||||
? {
|
||||
...signalModel.refDevice.toObject(),
|
||||
code: drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryById<Section | Turnout>(signalModel.refDevice.id)
|
||||
.datas.code,
|
||||
}
|
||||
: {
|
||||
id: 0,
|
||||
deviceType: graphicData.RelatedRef.DeviceType.Section,
|
||||
devicePort: graphicData.RelatedRef.DevicePort.A,
|
||||
code: '',
|
||||
};
|
||||
});
|
||||
|
||||
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 signalModel = reactive(new SignalData());
|
||||
const kilometerSystem = reactive({ coordinateSystem: '', kilometer: 0 });
|
||||
|
||||
const CoordinateSystemOptions = [
|
||||
{ label: '车辆段', value: 'DEPOT' },
|
||||
@ -116,20 +44,42 @@ const CoordinateSystemOptions = [
|
||||
{ label: '正线', value: 'MAIN_LINE' },
|
||||
{ label: '换线', value: 'TRANSFER' },
|
||||
];
|
||||
const centralizedStations = ref<{ label: string; value: number }[]>([]);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const stations = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Station>(Station.Type);
|
||||
centralizedStations.value = [{ label: '', value: 0 }];
|
||||
stations.forEach((station) => {
|
||||
if (station.datas.concentrationStations || station.datas.depots) {
|
||||
centralizedStations.value.push({
|
||||
label: station.datas.name,
|
||||
value: station.datas.id,
|
||||
});
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
const signal = drawStore.selectedGraphic as Signal;
|
||||
signalModel.kilometerSystem = {
|
||||
coordinateSystem: kilometerSystem.coordinateSystem,
|
||||
kilometer: kilometerSystem.kilometer,
|
||||
};
|
||||
if (signal) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(signal, signalModel);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-form>
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
@ -24,42 +24,64 @@
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="stationLineModel.hasTransfer"
|
||||
v-model="hasTransfer"
|
||||
:options="optionsCircle"
|
||||
label="是否有换乘"
|
||||
map-options
|
||||
emit-value
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="stationLineModel.color"
|
||||
:options="colorOptions"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@update:model-value="onUpdate"
|
||||
label="站名颜色"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { StationLineData } from 'src/drawApp/graphics/StationLineInteraction';
|
||||
import { StationLine } from 'src/graphics/stationLine/StationLine';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: stationLineModel, onUpdate } = useFormData(
|
||||
new StationLineData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
const optionsCircle = [
|
||||
{ label: '是', value: true },
|
||||
{ label: '否', value: false },
|
||||
];
|
||||
const stationLineModel = reactive(new StationLineData());
|
||||
const hasTransfer = ref('是');
|
||||
const optionsCircle = ['是', '否'];
|
||||
enum showSelect {
|
||||
是 = 'true',
|
||||
否 = 'false',
|
||||
}
|
||||
enum showSelectData {
|
||||
true = '是',
|
||||
false = '否',
|
||||
}
|
||||
|
||||
const colorOptions = [
|
||||
{ label: '橘黄色', value: graphicData.StationLine.stationColor.orange },
|
||||
{ label: '灰色', value: graphicData.StationLine.stationColor.gray },
|
||||
];
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == StationLine.Type) {
|
||||
stationLineModel.copyFrom(val.saveData() as StationLineData);
|
||||
hasTransfer.value = (showSelectData as never)[
|
||||
stationLineModel.hasTransfer + ''
|
||||
];
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const stationLine = drawStore.selectedGraphic as StationLine;
|
||||
if (stationLine) {
|
||||
stationLineModel.copyFrom(stationLine.saveData());
|
||||
hasTransfer.value = (showSelectData as never)[
|
||||
stationLineModel.hasTransfer + ''
|
||||
];
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
stationLineModel.hasTransfer = JSON.parse(
|
||||
(showSelect as never)[hasTransfer.value]
|
||||
);
|
||||
const stationLine = drawStore.selectedGraphic as StationLine;
|
||||
if (stationLine) {
|
||||
drawStore
|
||||
.getDrawApp()
|
||||
.updateGraphicAndRecord(stationLine, stationLineModel);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -19,13 +19,10 @@
|
||||
lazy-rules
|
||||
autogrow
|
||||
/>
|
||||
<q-list bordered separator class="rounded-borders">
|
||||
<q-item no-wrap class="q-gutter-y-sm column">
|
||||
<div>公里标配置</div>
|
||||
<q-select
|
||||
outlined
|
||||
style="margin-top: 10px"
|
||||
v-model="stationModel.kilometerSystem.coordinateSystem"
|
||||
v-model="kilometerSystem.coordinateSystem"
|
||||
:options="CoordinateSystemOptions"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@ -35,58 +32,48 @@
|
||||
<q-input
|
||||
outlined
|
||||
style="margin-top: 10px"
|
||||
v-model.number="stationModel.kilometerSystem.kilometer"
|
||||
v-model.number="kilometerSystem.kilometer"
|
||||
type="number"
|
||||
@blur="onUpdate"
|
||||
label="公里标(mm):"
|
||||
/>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<q-select
|
||||
v-if="stationModel.concentrationStations"
|
||||
outlined
|
||||
v-model="stationModel.manageStations"
|
||||
label="集中站管理的车站"
|
||||
multiple
|
||||
:options="optionsStations"
|
||||
map-options
|
||||
emit-value
|
||||
@update:model-value="onUpdate"
|
||||
/>
|
||||
<q-toggle
|
||||
v-model="stationModel.hasControl"
|
||||
@blur="onUpdate"
|
||||
v-model="hasControl"
|
||||
:options="optionsControl"
|
||||
label="是否有控制"
|
||||
emit-value
|
||||
@update:model-value="onUpdate"
|
||||
/>
|
||||
<q-toggle
|
||||
v-model="stationModel.concentrationStations"
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="concentrationStations"
|
||||
:options="optionsControl"
|
||||
label="是否集中站"
|
||||
emit-value
|
||||
@update:model-value="onUpdate"
|
||||
/>
|
||||
<q-toggle
|
||||
v-model="stationModel.depots"
|
||||
label="是否车辆段"
|
||||
emit-value
|
||||
@update:model-value="onUpdate"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { StationData } from 'src/drawApp/graphics/StationInteraction';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, watchEffect } from 'vue';
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: stationModel, onUpdate } = useFormData(
|
||||
new StationData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
let optionsStations: { label: string; value: number }[] = [];
|
||||
const stationModel = reactive(new StationData());
|
||||
const hasControl = ref('是');
|
||||
const concentrationStations = ref('否');
|
||||
const optionsControl = ['是', '否'];
|
||||
enum showSelect {
|
||||
是 = 'true',
|
||||
否 = 'false',
|
||||
}
|
||||
enum showSelectData {
|
||||
true = '是',
|
||||
false = '否',
|
||||
}
|
||||
const kilometerSystem = reactive({ coordinateSystem: '', kilometer: 0 });
|
||||
|
||||
const CoordinateSystemOptions = [
|
||||
{ label: '车辆段', value: 'DEPOT' },
|
||||
@ -95,22 +82,55 @@ const CoordinateSystemOptions = [
|
||||
{ label: '换线', value: 'TRANSFER' },
|
||||
];
|
||||
|
||||
watchEffect(() => {
|
||||
if (
|
||||
stationModel.concentrationStations &&
|
||||
!stationModel.manageStations.includes(stationModel.id)
|
||||
) {
|
||||
stationModel.manageStations.push(stationModel.id);
|
||||
onUpdate();
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Station.Type) {
|
||||
stationModel.copyFrom(val.saveData() as StationData);
|
||||
hasControl.value = (showSelectData as never)[
|
||||
stationModel.hasControl + ''
|
||||
];
|
||||
concentrationStations.value = (showSelectData as never)[
|
||||
stationModel.concentrationStations + ''
|
||||
];
|
||||
if (stationModel.kilometerSystem) {
|
||||
kilometerSystem.coordinateSystem =
|
||||
stationModel.kilometerSystem.coordinateSystem;
|
||||
kilometerSystem.kilometer = stationModel.kilometerSystem.kilometer;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const station = drawStore.selectedGraphic as Station;
|
||||
if (station) {
|
||||
stationModel.copyFrom(station.saveData());
|
||||
hasControl.value = (showSelectData as never)[stationModel.hasControl + ''];
|
||||
concentrationStations.value = (showSelectData as never)[
|
||||
stationModel.concentrationStations + ''
|
||||
];
|
||||
if (stationModel.kilometerSystem) {
|
||||
kilometerSystem.coordinateSystem =
|
||||
stationModel.kilometerSystem.coordinateSystem;
|
||||
kilometerSystem.kilometer = stationModel.kilometerSystem.kilometer;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
optionsStations = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Station>(Station.Type)
|
||||
.map((g) => {
|
||||
return { label: g.datas.name, value: g.datas.id };
|
||||
});
|
||||
});
|
||||
function onUpdate() {
|
||||
stationModel.hasControl = JSON.parse((showSelect as never)[hasControl.value]);
|
||||
stationModel.concentrationStations = JSON.parse(
|
||||
(showSelect as never)[concentrationStations.value]
|
||||
);
|
||||
stationModel.kilometerSystem = {
|
||||
coordinateSystem: kilometerSystem.coordinateSystem,
|
||||
kilometer: kilometerSystem.kilometer,
|
||||
};
|
||||
const station = drawStore.selectedGraphic as Station;
|
||||
if (station) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(station, stationModel);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
84
src/components/draw-app/properties/TrainProperty.vue
Normal file
84
src/components/draw-app/properties/TrainProperty.vue
Normal file
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<q-form>
|
||||
<q-input outlined readonly v-model="trainModel.id" label="id" hint="" />
|
||||
<q-input
|
||||
outlined
|
||||
v-model="trainModel.code"
|
||||
label="车号"
|
||||
hint=""
|
||||
@blur="onUpdate"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="hasBorder"
|
||||
:options="optionsDoor"
|
||||
label="是否有边框"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="trainDirection"
|
||||
:options="optionsDirection"
|
||||
label="行驶方向"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { TrainData } from 'src/drawApp/graphics/TrainInteraction';
|
||||
import { Train } from 'src/graphics/train/Train';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const trainModel = reactive(new TrainData());
|
||||
const hasBorder = ref('是');
|
||||
const optionsDoor = ['是', '否'];
|
||||
const trainDirection = ref('向左');
|
||||
const optionsDirection = ['向左', '向右'];
|
||||
enum showSelect {
|
||||
是 = 'true',
|
||||
否 = 'false',
|
||||
向左 = 'left',
|
||||
向右 = 'right',
|
||||
}
|
||||
enum showSelectData {
|
||||
true = '是',
|
||||
false = '否',
|
||||
left = '向左',
|
||||
right = '向右',
|
||||
}
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Train.Type) {
|
||||
trainModel.copyFrom(val.saveData() as TrainData);
|
||||
hasBorder.value = (showSelectData as never)[trainModel.hasBorder + ''];
|
||||
trainDirection.value = (showSelectData as never)[
|
||||
trainModel.trainDirection
|
||||
];
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const train = drawStore.selectedGraphic as Train;
|
||||
if (train) {
|
||||
trainModel.copyFrom(train.saveData());
|
||||
hasBorder.value = (showSelectData as never)[trainModel.hasBorder + ''];
|
||||
trainDirection.value = (showSelectData as never)[trainModel.trainDirection];
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
trainModel.hasBorder = JSON.parse((showSelect as never)[hasBorder.value]);
|
||||
trainModel.trainDirection = (showSelect as never)[trainDirection.value];
|
||||
const train = drawStore.selectedGraphic as Train;
|
||||
if (train) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(train, trainModel);
|
||||
}
|
||||
}
|
||||
</script>
|
@ -36,7 +36,7 @@
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section no-wrap class="q-gutter-y-sm column">
|
||||
<q-item-label> 关联的道岔物理区段 </q-item-label>
|
||||
<q-item-label> 关联的道岔 </q-item-label>
|
||||
<div class="q-gutter-sm row">
|
||||
<q-chip
|
||||
v-for="item in relatedTurnout"
|
||||
@ -55,20 +55,42 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { TrainWindowData } from 'src/drawApp/graphics/TrainWindowInteraction';
|
||||
import { LogicSection } from 'src/graphics/logicSection/LogicSection';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { TrainWindow } from 'src/graphics/trainWindow/TrainWindow';
|
||||
import { Turnout } from 'src/graphics/turnout/Turnout';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { computed } from 'vue';
|
||||
import { computed, onMounted, reactive, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: trainWindowModel, onUpdate } = useFormData(
|
||||
new TrainWindowData(),
|
||||
drawStore.getDrawApp()
|
||||
const trainWindowModel = reactive(new TrainWindowData());
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == TrainWindow.Type) {
|
||||
trainWindowModel.copyFrom(val.saveData() as TrainWindowData);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const trainWindow = drawStore.selectedGraphic as TrainWindow;
|
||||
if (trainWindow) {
|
||||
trainWindowModel.copyFrom(trainWindow.saveData());
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
const trainWindow = drawStore.selectedGraphic as TrainWindow;
|
||||
if (trainWindow) {
|
||||
drawStore
|
||||
.getDrawApp()
|
||||
.updateGraphicAndRecord(trainWindow, trainWindowModel);
|
||||
}
|
||||
}
|
||||
|
||||
const relatedLogicSection = computed((): LogicSection[] => {
|
||||
if (
|
||||
drawStore.selectedGraphic &&
|
||||
@ -78,14 +100,12 @@ const relatedLogicSection = computed((): LogicSection[] => {
|
||||
}
|
||||
return [];
|
||||
});
|
||||
const relatedTurnout = computed((): Section[] => {
|
||||
const relatedTurnout = computed((): Turnout[] => {
|
||||
if (
|
||||
drawStore.selectedGraphic &&
|
||||
drawStore.selectedGraphic.type === 'TrainWindow'
|
||||
) {
|
||||
return (
|
||||
drawStore.selectedGraphic as TrainWindow
|
||||
).getRelatedTurnoutsSection();
|
||||
return (drawStore.selectedGraphic as TrainWindow).getRelatedTurnouts();
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
@ -1,18 +1,16 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-input outlined readonly v-model="turnoutModel.id" label="id" />
|
||||
<q-form>
|
||||
<q-input outlined readonly v-model="turnoutModel.id" label="id" hint="" />
|
||||
<q-input
|
||||
outlined
|
||||
v-model="turnoutModel.code"
|
||||
@blur="onUpdate"
|
||||
label="编号"
|
||||
/>
|
||||
<q-list bordered separator class="rounded-borders">
|
||||
<q-item no-wrap class="q-gutter-y-sm column">
|
||||
<div>公里标配置</div>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="turnoutModel.kilometerSystem[0].coordinateSystem"
|
||||
style="margin-top: 10px"
|
||||
v-model="kilometerSystem[0].coordinateSystem"
|
||||
:options="CoordinateSystemOptions"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@ -21,17 +19,16 @@
|
||||
></q-select>
|
||||
<q-input
|
||||
outlined
|
||||
v-model.number="turnoutModel.kilometerSystem[0].kilometer"
|
||||
style="margin-top: 10px"
|
||||
v-model.number="kilometerSystem[0].kilometer"
|
||||
type="number"
|
||||
@blur="onUpdate"
|
||||
label="公里标(mm):"
|
||||
/>
|
||||
</q-item>
|
||||
<q-item no-wrap class="q-gutter-y-sm column">
|
||||
<div>公里标配置</div>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="turnoutModel.kilometerSystem[1].coordinateSystem"
|
||||
style="margin-top: 10px"
|
||||
v-model="kilometerSystem[1].coordinateSystem"
|
||||
:options="CoordinateSystemOptions"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@ -40,13 +37,12 @@
|
||||
></q-select>
|
||||
<q-input
|
||||
outlined
|
||||
v-model.number="turnoutModel.kilometerSystem[1].kilometer"
|
||||
style="margin-top: 10px"
|
||||
v-model.number="kilometerSystem[1].kilometer"
|
||||
type="number"
|
||||
@blur="onUpdate"
|
||||
label="公里标(mm):"
|
||||
/>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<q-field class="q-mt-lg" outlined label="关联区段" readonly stack-label>
|
||||
<template #control>
|
||||
<q-chip
|
||||
@ -71,38 +67,28 @@
|
||||
>
|
||||
</template>
|
||||
</q-field>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="turnoutModel.centralizedStation"
|
||||
:options="centralizedStations"
|
||||
emitValue
|
||||
mapOptions
|
||||
@update:model-value="onUpdate"
|
||||
label="关联的集中站"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { TurnoutData } from 'src/drawApp/graphics/TurnoutInteraction';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { Turnout } from 'src/graphics/turnout/Turnout';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { computed, reactive, shallowRef, watchEffect } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const { data: turnoutModel, onUpdate } = useFormData(
|
||||
new TurnoutData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
const CoordinateSystemOptions = [
|
||||
{ label: '车辆段', value: 'DEPOT' },
|
||||
{ label: '停车场', value: 'PARKING_LOT' },
|
||||
{ label: '正线', value: 'MAIN_LINE' },
|
||||
{ label: '换线', value: 'TRANSFER' },
|
||||
];
|
||||
const turnoutModel = shallowRef(new TurnoutData());
|
||||
const kilometerSystem = reactive([
|
||||
{ coordinateSystem: '', kilometer: 0 },
|
||||
{ coordinateSystem: '', kilometer: 0 },
|
||||
]);
|
||||
|
||||
const sectionRelations = computed(() => {
|
||||
const turnout = drawStore.selectedGraphic as Turnout;
|
||||
@ -112,15 +98,12 @@ const sectionRelations = computed(() => {
|
||||
turnout,
|
||||
Section.Type
|
||||
);
|
||||
return sectionRelations.map((relation) => {
|
||||
if (relation.getRelationParam(turnout).param) {
|
||||
return `${relation.getRelationParam(turnout).param}: ${
|
||||
return sectionRelations.map(
|
||||
(relation) =>
|
||||
`${relation.getRelationParam(turnout).param}: ${
|
||||
relation.getOtherGraphic<Section>(turnout).datas.code
|
||||
}(${relation.getOtherRelationParam(turnout).param})`;
|
||||
} else {
|
||||
return relation.getOtherGraphic<Section>(turnout).datas.code;
|
||||
}
|
||||
});
|
||||
}(${relation.getOtherRelationParam(turnout).param})`
|
||||
);
|
||||
});
|
||||
|
||||
const turnoutRelations = computed(() => {
|
||||
@ -139,20 +122,28 @@ const turnoutRelations = computed(() => {
|
||||
);
|
||||
});
|
||||
|
||||
const centralizedStations = ref<{ label: string; value: number }[]>([]);
|
||||
|
||||
onMounted(() => {
|
||||
const stations = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Station>(Station.Type);
|
||||
centralizedStations.value = [{ label: '', value: 0 }];
|
||||
stations.forEach((station) => {
|
||||
if (station.datas.concentrationStations || station.datas.depots) {
|
||||
centralizedStations.value.push({
|
||||
label: station.datas.name,
|
||||
value: station.datas.id,
|
||||
watchEffect(() => {
|
||||
const turnout = drawStore.selectedGraphic;
|
||||
if (turnout && turnout instanceof Turnout) {
|
||||
turnoutModel.value = turnout.saveData();
|
||||
if (turnoutModel.value.kilometerSystem.length > 0) {
|
||||
kilometerSystem.forEach((ks, i) => {
|
||||
ks.coordinateSystem =
|
||||
turnoutModel.value.kilometerSystem[i].coordinateSystem;
|
||||
ks.kilometer = turnoutModel.value.kilometerSystem[i].kilometer;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const onUpdate = () => {
|
||||
const turnout = drawStore.selectedGraphic as Turnout;
|
||||
turnoutModel.value.kilometerSystem = kilometerSystem.map((ks) => ({
|
||||
coordinateSystem: ks.coordinateSystem,
|
||||
kilometer: ks.kilometer,
|
||||
}));
|
||||
if (turnout) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(turnout, turnoutModel.value);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -1,302 +0,0 @@
|
||||
<template>
|
||||
<div v-if="showRangeConfig">
|
||||
<q-card class="q-gutter-sm q-pa-sm">
|
||||
<q-card-section>
|
||||
<div class="text-h6">{{ handleState }}</div>
|
||||
</q-card-section>
|
||||
<q-separator inset></q-separator>
|
||||
<q-form ref="myForm" @submit="onSubmit" @reset="onReset">
|
||||
<q-input
|
||||
outlined
|
||||
label="名称"
|
||||
v-model="rangeConfig.areaName"
|
||||
:rules="[(val) => val.trim() != '' || '名称不能为空']"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="rangeConfig.deviceType"
|
||||
:options="optionsType"
|
||||
label="设备类型"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
:rules="[(val) => val.trim() != '' || '设备类型不能为空']"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="rangeConfig.alertTypes"
|
||||
label="故障类型"
|
||||
multiple
|
||||
:options="optionsAlertType"
|
||||
:rules="[(val) => val.length > 0 || '故障类型不能为空']"
|
||||
/>
|
||||
<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 device"
|
||||
:key="item"
|
||||
square
|
||||
color="primary"
|
||||
text-color="white"
|
||||
removable
|
||||
@remove="removeSelect(item)"
|
||||
>
|
||||
{{ item }}
|
||||
</q-chip>
|
||||
</div>
|
||||
<q-btn
|
||||
v-show="device.length > 0"
|
||||
style="width: 120px"
|
||||
label="清空框选的设备"
|
||||
color="red"
|
||||
@click="clearSelect"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<div class="q-gutter-sm q-pa-md row justify-center">
|
||||
<q-btn label="提交" type="submit" color="primary" class="q-mr-md" />
|
||||
<q-btn label="重置" type="reset" color="primary" />
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import { useLineStore } from 'src/stores/line-store';
|
||||
import { reactive, ref, watch } from 'vue';
|
||||
import { Turnout } from 'src/graphics/turnout/Turnout';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { Platform } from 'src/graphics/platform/Platform';
|
||||
import { QForm, useQuasar } from 'quasar';
|
||||
import { useRoute } from 'vue-router';
|
||||
import {
|
||||
deviceRangeSet,
|
||||
IAreaConfigItem,
|
||||
queryDeviceRangeById,
|
||||
} from 'src/api/ConfigApi';
|
||||
import { JlGraphic } from 'jl-graphic';
|
||||
import { saveAlertTypeData, showAlertTypeData } from '../alarm/alarmInfoEnum';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { useRangeConfigStore } from 'src/stores/range-config-store';
|
||||
import { getRangeConfigApp } from 'src/drawApp/rangeConfigApp';
|
||||
import { errorNotify } from 'src/utils/CommonNotify';
|
||||
|
||||
defineExpose({ searchById });
|
||||
|
||||
const route = useRoute();
|
||||
const rangeConfigStore = useRangeConfigStore();
|
||||
const $q = useQuasar();
|
||||
const showRangeConfig = ref(true);
|
||||
const rangeConfig = reactive<{
|
||||
areaName: string;
|
||||
deviceType: `${DeviceType}` | '';
|
||||
device: number[];
|
||||
alertTypes: string[];
|
||||
}>({
|
||||
areaName: '',
|
||||
deviceType: '',
|
||||
device: [],
|
||||
alertTypes: [],
|
||||
});
|
||||
const device = ref<string[]>([]);
|
||||
const handleState = ref('新建范围配置');
|
||||
|
||||
const optionsType = [
|
||||
{ label: '轨道', value: Section.Type },
|
||||
{ label: '道岔', value: Turnout.Type },
|
||||
{ label: '集中站', value: Station.Type },
|
||||
{ label: '站台', value: Platform.Type },
|
||||
];
|
||||
|
||||
const optionsAlertType = [
|
||||
'蓝显',
|
||||
'全线蓝显',
|
||||
'列车延误2分钟',
|
||||
'列车延误10分钟',
|
||||
'整侧站台门无关闭锁紧信号',
|
||||
'整侧站台门无法打开',
|
||||
'整侧站台门无法关闭',
|
||||
'道岔均失表',
|
||||
'道岔定位失表',
|
||||
'道岔反位失表',
|
||||
'计轴红光带',
|
||||
'计轴大面积红光带',
|
||||
'计轴橙光带',
|
||||
'计轴大面积橙光带',
|
||||
'道岔大面积失表',
|
||||
'列车信号故障',
|
||||
'一级联锁',
|
||||
];
|
||||
|
||||
enum DeviceType {
|
||||
station = 'DEVICE_TYPE_RTU',
|
||||
Turnout = 'DEVICE_TYPE_SWITCH',
|
||||
Section = 'DEVICE_TYPE_TRACK',
|
||||
Platform = 'DEVICE_TYPE_PLATFORM',
|
||||
}
|
||||
enum DeviceTypeShow {
|
||||
DEVICE_TYPE_RTU = 'station',
|
||||
DEVICE_TYPE_SWITCH = 'Turnout',
|
||||
DEVICE_TYPE_TRACK = 'Section',
|
||||
DEVICE_TYPE_PLATFORM = 'Platform',
|
||||
}
|
||||
|
||||
watch(
|
||||
() => rangeConfig.alertTypes,
|
||||
(alertTypes) => {
|
||||
if (alertTypes[0] == '一级联锁') {
|
||||
alertTypes.splice(1);
|
||||
}
|
||||
if (
|
||||
alertTypes[0] !== '一级联锁' &&
|
||||
alertTypes.slice(1).includes('一级联锁')
|
||||
) {
|
||||
for (let i = 0; i < alertTypes.length; i++) {
|
||||
if (alertTypes[i] == '一级联锁') {
|
||||
alertTypes.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
let selectGraphic: JlGraphic[] = [];
|
||||
watch(
|
||||
() => rangeConfigStore.selectedGraphics,
|
||||
(val) => {
|
||||
if (val && val.length > 0) {
|
||||
const deviceFilter = rangeConfigStore.selectedGraphics?.filter((g) => {
|
||||
let select = false;
|
||||
if (
|
||||
g.type == Station.Type &&
|
||||
rangeConfig.deviceType == Station.Type &&
|
||||
(g as Station).datas.concentrationStations
|
||||
) {
|
||||
select = true;
|
||||
}
|
||||
if (g.type == rangeConfig.deviceType && g.type !== Station.Type) {
|
||||
select = true;
|
||||
}
|
||||
return select;
|
||||
}) as JlGraphic[];
|
||||
selectGraphic.push(...deviceFilter);
|
||||
selectGraphic = Array.from(new Set(selectGraphic));
|
||||
getRangeConfigApp().updateSelected(...selectGraphic);
|
||||
device.value = selectGraphic.map((g) => g.code) as string[];
|
||||
rangeConfig.device = selectGraphic.map((g) => g.id) as number[];
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const myForm = ref<QForm | null>(null);
|
||||
let editId: number;
|
||||
let handle = ref('');
|
||||
let handleError = ref('');
|
||||
async function onSubmit() {
|
||||
myForm.value?.validate().then(async (res) => {
|
||||
let validataOfDevice = false;
|
||||
if (rangeConfig.device.length) {
|
||||
validataOfDevice = true;
|
||||
} else {
|
||||
errorNotify('请框选设备', '');
|
||||
}
|
||||
if (res && validataOfDevice) {
|
||||
try {
|
||||
const lineId = +route.params.id as number;
|
||||
const alertTypes = rangeConfig.alertTypes.map(
|
||||
(type) => (saveAlertTypeData as never)[type + '']
|
||||
);
|
||||
const params: IAreaConfigItem = {
|
||||
lineId: lineId,
|
||||
areaName: rangeConfig.areaName,
|
||||
deviceType: (DeviceType as never)[rangeConfig.deviceType + ''],
|
||||
alertTypes: alertTypes,
|
||||
data: rangeConfig.device,
|
||||
};
|
||||
if (handleState.value == '新建范围配置') {
|
||||
handle.value = '创建成功';
|
||||
handleError.value = '创建失败';
|
||||
await deviceRangeSet(params);
|
||||
} else {
|
||||
params.id = editId;
|
||||
handle.value = '更新成功';
|
||||
handleError.value = '更新失败';
|
||||
await deviceRangeSet(params);
|
||||
}
|
||||
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: handle.value,
|
||||
});
|
||||
onReset();
|
||||
showRangeConfig.value = false;
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: (err as { title: '' }).title,
|
||||
});
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
showRangeConfig.value = true;
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function searchById(id: number) {
|
||||
try {
|
||||
handleState.value = '编辑范围配置';
|
||||
clearSelect();
|
||||
editId = id;
|
||||
const response = await queryDeviceRangeById(id);
|
||||
rangeConfig.areaName = response.data.areaName;
|
||||
rangeConfig.deviceType = (DeviceTypeShow as never)[
|
||||
response.data.deviceType + ''
|
||||
];
|
||||
rangeConfig.alertTypes = response.data.alertTypes.map(
|
||||
(type) => (showAlertTypeData as never)[type + '']
|
||||
);
|
||||
const select: JlGraphic[] = [];
|
||||
response.data.data.forEach((id: number) => {
|
||||
const g = getRangeConfigApp().queryStore.queryById(id);
|
||||
select.push(g);
|
||||
device.value.push(g.code);
|
||||
});
|
||||
getRangeConfigApp().updateSelected(...select);
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: '没有需要编辑的详细信息',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function removeSelect(code: string) {
|
||||
const removeIndex = device.value.findIndex((item) => item == code);
|
||||
selectGraphic.splice(removeIndex, 1);
|
||||
device.value.splice(removeIndex, 1);
|
||||
rangeConfig.device.splice(removeIndex, 1);
|
||||
getRangeConfigApp().updateSelected(...selectGraphic);
|
||||
}
|
||||
|
||||
function clearSelect() {
|
||||
device.value = [];
|
||||
selectGraphic = [];
|
||||
getRangeConfigApp().updateSelected();
|
||||
}
|
||||
|
||||
function onReset() {
|
||||
handleState.value = '新建范围配置';
|
||||
rangeConfig.areaName = '';
|
||||
rangeConfig.deviceType = '';
|
||||
rangeConfig.alertTypes = [];
|
||||
rangeConfig.device = [];
|
||||
clearSelect();
|
||||
}
|
||||
</script>
|
@ -1,185 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
IAreaConfigListItem,
|
||||
getDeviceAreaList,
|
||||
deleteDeviceArea,
|
||||
} from 'src/api/ConfigApi';
|
||||
import { ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import DraggableDialog from '../common/DraggableDialog.vue';
|
||||
import { QTable, useQuasar } from 'quasar';
|
||||
import { errorNotify } from 'src/utils/CommonNotify';
|
||||
import { deviceTypeMap } from 'src/api/TrainApi';
|
||||
|
||||
const $q = useQuasar();
|
||||
const lineId = useRoute().params.id as string;
|
||||
const tableRef = ref<QTable>();
|
||||
const columns: QTable['columns'] = [
|
||||
{ name: 'id', label: 'ID', field: 'id', align: 'center' },
|
||||
{ name: 'lineId', label: '线路ID', field: 'lineId', align: 'center' },
|
||||
{
|
||||
name: 'areaName',
|
||||
label: '名称',
|
||||
field: 'areaName',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'deviceType',
|
||||
label: '设备类型',
|
||||
field: (row) => deviceTypeMap[row.deviceType as keyof typeof deviceTypeMap],
|
||||
align: 'center',
|
||||
},
|
||||
{ name: 'operations', label: '操作', field: 'operations', align: 'center' },
|
||||
];
|
||||
const rows = ref<IAreaConfigListItem[]>([]);
|
||||
const loading = ref(false);
|
||||
const pagination = ref({
|
||||
sortBy: 'desc',
|
||||
descending: false,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 10,
|
||||
});
|
||||
|
||||
const searchAreaName = ref('');
|
||||
watch(
|
||||
() => searchAreaName.value,
|
||||
() => {
|
||||
tableRef.value?.requestServerInteraction();
|
||||
}
|
||||
);
|
||||
|
||||
const onRequest: QTable['onRequest'] = async (props) => {
|
||||
const { page, rowsPerPage } = props.pagination;
|
||||
loading.value = true;
|
||||
try {
|
||||
const resp = await getDeviceAreaList({
|
||||
lineId,
|
||||
current: page,
|
||||
size: rowsPerPage,
|
||||
areaName: searchAreaName.value,
|
||||
});
|
||||
pagination.value.page = resp.current;
|
||||
pagination.value.rowsNumber = resp.total;
|
||||
pagination.value.rowsPerPage = resp.size;
|
||||
rows.value = resp.records;
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: '无法获取范围列表',
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onDialogShow = () => {
|
||||
tableRef.value?.requestServerInteraction();
|
||||
};
|
||||
|
||||
const dialogRef = ref<InstanceType<typeof DraggableDialog>>();
|
||||
const props = defineProps<{
|
||||
onEditClick: (row: IAreaConfigListItem) => void;
|
||||
}>();
|
||||
function onEdit(row: IAreaConfigListItem) {
|
||||
props.onEditClick(row);
|
||||
}
|
||||
function deleteData(row: IAreaConfigListItem) {
|
||||
$q.dialog({ message: `确定删除 "${row.areaName}" 吗?`, cancel: true }).onOk(
|
||||
async () => {
|
||||
try {
|
||||
await deleteDeviceArea(row.id);
|
||||
} catch (err) {
|
||||
errorNotify('删除失败:', err);
|
||||
} finally {
|
||||
tableRef.value?.requestServerInteraction();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<draggable-dialog
|
||||
ref="dialogRef"
|
||||
@show="onDialogShow"
|
||||
title="范围列表"
|
||||
:width="800"
|
||||
:height="0"
|
||||
>
|
||||
<template v-slot:footer>
|
||||
<q-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
v-model:pagination="pagination"
|
||||
:loading="loading"
|
||||
:rows="rows"
|
||||
:columns="columns"
|
||||
@request="onRequest"
|
||||
:rows-per-page-options="[10, 20, 50, 100]"
|
||||
>
|
||||
<template v-slot:body-cell="props">
|
||||
<q-td :props="props" class="custom-column">
|
||||
{{ props.value }}
|
||||
<q-tooltip
|
||||
anchor="bottom middle"
|
||||
v-if="props.value && props.value.length > 20"
|
||||
>
|
||||
<div class="message-tip">
|
||||
{{ props.value }}
|
||||
</div>
|
||||
</q-tooltip>
|
||||
</q-td>
|
||||
</template>
|
||||
<template v-slot:body-cell-operations="props">
|
||||
<q-td :props="props">
|
||||
<div class="q-gutter-sm row justify-center">
|
||||
<q-btn color="primary" label="编辑" @click="onEdit(props.row)" />
|
||||
<q-btn color="red" label="删除" @click="deleteData(props.row)" />
|
||||
</div>
|
||||
</q-td>
|
||||
</template>
|
||||
</q-table>
|
||||
</template>
|
||||
<template v-slot:titleButton>
|
||||
<q-btn square color="purple" style="margin-right: 10px" icon="search">
|
||||
<q-popup-edit
|
||||
ref="popupEdit"
|
||||
v-model="searchAreaName"
|
||||
:cover="false"
|
||||
:offset="[0, 10]"
|
||||
v-slot="scope"
|
||||
>
|
||||
<q-input
|
||||
color="accent"
|
||||
v-model="scope.value"
|
||||
label="区域名称"
|
||||
dense
|
||||
autofocus
|
||||
@keyup.enter="scope.set"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="search" color="accent" />
|
||||
</template>
|
||||
</q-input>
|
||||
</q-popup-edit>
|
||||
</q-btn>
|
||||
</template>
|
||||
</draggable-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.custom-column {
|
||||
max-width: 250px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.message-tip {
|
||||
width: 300px;
|
||||
overflow: auto;
|
||||
line-height: 22px;
|
||||
white-space: pre-wrap;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
@ -1,33 +0,0 @@
|
||||
<template>
|
||||
<!-- 画布或图形对象属性 -->
|
||||
<div v-if="lineStore.selectedGraphics !== null">
|
||||
<q-card flat>
|
||||
<q-card-section>
|
||||
<div class="text-h6">
|
||||
{{ lineStore.selectedGraphicType + ' 状态属性' }}
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator inset></q-separator>
|
||||
<template v-if="lineStore.selectedGraphics.length === 1">
|
||||
<q-card-section>
|
||||
<platform-property
|
||||
v-if="lineStore.selectedGraphicType === Platform.Type"
|
||||
></platform-property>
|
||||
<station-property
|
||||
v-if="lineStore.selectedGraphicType === Station.Type"
|
||||
></station-property>
|
||||
</q-card-section>
|
||||
</template>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
import { Platform } from 'src/graphics/platform/Platform';
|
||||
import PlatformProperty from './deviceStates/PlatformProperty.vue';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import StationProperty from './deviceStates/StationProperty.vue';
|
||||
|
||||
const lineStore = useLineStore();
|
||||
</script>
|
@ -1,247 +0,0 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
v-model="lineStore.selectedGraphic.id"
|
||||
label="id"
|
||||
hint=""
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
label="站台名称"
|
||||
readonly
|
||||
@blur="onUpdate"
|
||||
v-model="lineStore.selectedGraphic.datas.code"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="psdOpen"
|
||||
:options="optionsChoose"
|
||||
label="屏蔽门打开"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="psdCut"
|
||||
:options="optionsChoose"
|
||||
label="屏蔽门切除"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="emergstop"
|
||||
:options="optionsChoose"
|
||||
label="是否紧急关闭"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="trainberth"
|
||||
:options="optionsChoose"
|
||||
label="是否在站台停站"
|
||||
/>
|
||||
<q-select
|
||||
v-if="lineStore.selectedGraphic.datas.up"
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="upHold"
|
||||
:options="optionsChoose"
|
||||
label="是否上行车站扣车"
|
||||
/>
|
||||
<q-select
|
||||
v-if="lineStore.selectedGraphic.datas.up"
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="upOccHold"
|
||||
:options="optionsChoose"
|
||||
label="是否上行中心扣车"
|
||||
/>
|
||||
<q-select
|
||||
v-if="!lineStore.selectedGraphic.datas.up"
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="downHold"
|
||||
:options="optionsChoose"
|
||||
label="是否下行车站扣车"
|
||||
/>
|
||||
<q-select
|
||||
v-if="!lineStore.selectedGraphic.datas.up"
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="downOccHold"
|
||||
:options="optionsChoose"
|
||||
label="是否下行中心扣车"
|
||||
/>
|
||||
<q-select
|
||||
v-if="lineStore.selectedGraphic.datas.up"
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="upSkipstop"
|
||||
:options="optionsChoose"
|
||||
label="是否上行跳停"
|
||||
/>
|
||||
<q-select
|
||||
v-if="!lineStore.selectedGraphic.datas.up"
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="downSkipstop"
|
||||
:options="optionsChoose"
|
||||
label="是否下行跳停"
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
label="人工设置区间运行等级"
|
||||
type="textarea"
|
||||
@blur="onUpdate"
|
||||
v-model="platformModel.nextSectionRunTime"
|
||||
lazy-rules
|
||||
autogrow
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
label="人工设置停站时间"
|
||||
type="textarea"
|
||||
@blur="onUpdate"
|
||||
v-model="platformModel.stopTime"
|
||||
lazy-rules
|
||||
autogrow
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PlatformState } from 'src/drawApp/graphics/PlatformInteraction';
|
||||
import { Platform } from 'src/graphics/platform/Platform';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
import { mockPlatformApi, mockPlatformParams } from 'src/api/PlatformApi';
|
||||
|
||||
const lineStore = useLineStore();
|
||||
const platformModel = reactive(new PlatformState());
|
||||
const optionsChoose = ['是', '否'];
|
||||
|
||||
const psdOpen = ref('');
|
||||
const psdCut = ref('');
|
||||
const emergstop = ref('');
|
||||
const trainberth = ref('');
|
||||
const upHold = ref('');
|
||||
const upOccHold = ref('');
|
||||
const upSkipstop = ref('');
|
||||
const downHold = ref('');
|
||||
const downOccHold = ref('');
|
||||
const downSkipstop = ref('');
|
||||
|
||||
enum showSelect {
|
||||
是 = 'true',
|
||||
否 = 'false',
|
||||
}
|
||||
enum showSelectData {
|
||||
true = '是',
|
||||
false = '否',
|
||||
}
|
||||
|
||||
lineStore.$subscribe;
|
||||
watch(
|
||||
() => lineStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Platform.Type) {
|
||||
platformModel.copyFrom((val as Platform).states as PlatformState);
|
||||
psdOpen.value = (showSelectData as never)[platformModel.psdOpen + ''];
|
||||
psdCut.value = (showSelectData as never)[platformModel.psdCut + ''];
|
||||
emergstop.value = (showSelectData as never)[platformModel.emergstop + ''];
|
||||
trainberth.value = (showSelectData as never)[
|
||||
platformModel.trainberth + ''
|
||||
];
|
||||
upHold.value = (showSelectData as never)[platformModel.upHold + ''];
|
||||
upOccHold.value = (showSelectData as never)[platformModel.upOccHold + ''];
|
||||
upSkipstop.value = (showSelectData as never)[
|
||||
platformModel.upSkipstop + ''
|
||||
];
|
||||
downHold.value = (showSelectData as never)[platformModel.downHold + ''];
|
||||
downOccHold.value = (showSelectData as never)[
|
||||
platformModel.downOccHold + ''
|
||||
];
|
||||
downSkipstop.value = (showSelectData as never)[
|
||||
platformModel.downSkipstop + ''
|
||||
];
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const platform = lineStore.selectedGraphic as Platform;
|
||||
if (platform) {
|
||||
platformModel.copyFrom((platform as Platform).states as PlatformState);
|
||||
psdOpen.value = (showSelectData as never)[platformModel.psdOpen + ''];
|
||||
psdCut.value = (showSelectData as never)[platformModel.psdCut + ''];
|
||||
emergstop.value = (showSelectData as never)[platformModel.emergstop + ''];
|
||||
trainberth.value = (showSelectData as never)[platformModel.trainberth + ''];
|
||||
upHold.value = (showSelectData as never)[platformModel.upHold + ''];
|
||||
upOccHold.value = (showSelectData as never)[platformModel.upOccHold + ''];
|
||||
upSkipstop.value = (showSelectData as never)[platformModel.upSkipstop + ''];
|
||||
downHold.value = (showSelectData as never)[platformModel.downHold + ''];
|
||||
downOccHold.value = (showSelectData as never)[
|
||||
platformModel.downOccHold + ''
|
||||
];
|
||||
downSkipstop.value = (showSelectData as never)[
|
||||
platformModel.upSkipstop + ''
|
||||
];
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
const platform = lineStore.selectedGraphic as Platform;
|
||||
platformModel.psdOpen = JSON.parse((showSelect as never)[psdOpen.value]);
|
||||
platformModel.psdCut = JSON.parse((showSelect as never)[psdCut.value]);
|
||||
platformModel.emergstop = JSON.parse((showSelect as never)[emergstop.value]);
|
||||
platformModel.trainberth = JSON.parse(
|
||||
(showSelect as never)[trainberth.value]
|
||||
);
|
||||
platformModel.upHold = JSON.parse((showSelect as never)[upHold.value]);
|
||||
platformModel.upOccHold = JSON.parse((showSelect as never)[upOccHold.value]);
|
||||
platformModel.upSkipstop = JSON.parse(
|
||||
(showSelect as never)[upSkipstop.value]
|
||||
);
|
||||
platformModel.downHold = JSON.parse((showSelect as never)[downHold.value]);
|
||||
platformModel.downOccHold = JSON.parse(
|
||||
(showSelect as never)[downOccHold.value]
|
||||
);
|
||||
platformModel.downSkipstop = JSON.parse(
|
||||
(showSelect as never)[downSkipstop.value]
|
||||
);
|
||||
const data: { [key: string]: boolean | number | string } = {
|
||||
emergstop: false,
|
||||
trainberth: false,
|
||||
close: false,
|
||||
upHold: false,
|
||||
upOccHold: false,
|
||||
downOccHold: false,
|
||||
psdOpen: false,
|
||||
psdCut: false,
|
||||
upSkipstop: false,
|
||||
downSkipstop: false,
|
||||
upTrainSkipstop: false,
|
||||
downTrainSkipstop: false,
|
||||
downHold: false,
|
||||
id: platform.id,
|
||||
nextSectionRunTime: 0,
|
||||
nextSectionRunLevel: 0,
|
||||
stopTime: 0,
|
||||
};
|
||||
type keyData = 'emergstop' | 'trainberth';
|
||||
Object.keys(data).forEach((i) => {
|
||||
data[i] = platformModel[i as keyData] || data[i];
|
||||
});
|
||||
if (platform) {
|
||||
mockPlatformApi(3, data as unknown as mockPlatformParams)
|
||||
.then((res) => {
|
||||
console.log(res, '---res--');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err, '---err---');
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,103 +0,0 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
v-model="lineStore.selectedGraphic.id"
|
||||
label="id"
|
||||
hint=""
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
label="车站名称"
|
||||
readonly
|
||||
@blur="onUpdate"
|
||||
v-model="lineStore.selectedGraphic.datas.name"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="controlChange"
|
||||
:options="optionsChoose"
|
||||
label="车站控制模式转换"
|
||||
/>
|
||||
<q-checkbox
|
||||
v-model="stationModel.ipRtuStusDown"
|
||||
label="是否通信中断"
|
||||
@update:model-value="onUpdate"
|
||||
/>
|
||||
<q-checkbox
|
||||
v-model="stationModel.ipRtuStusInLocalCtrl"
|
||||
label="是否站控"
|
||||
@update:model-value="onUpdate"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { StationState } from 'src/drawApp/graphics/StationInteraction';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
import { mockStationApi } from 'src/api/PlatformApi';
|
||||
|
||||
const lineStore = useLineStore();
|
||||
const stationModel = reactive(new StationState());
|
||||
const optionsChoose = ['中控', '站控且允许转到中控', '站控且不允许转到中控'];
|
||||
|
||||
const controlChange = ref('');
|
||||
|
||||
lineStore.$subscribe;
|
||||
watch(
|
||||
() => lineStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Station.Type) {
|
||||
stationModel.copyFrom((val as Station).states as StationState);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const station = lineStore.selectedGraphic as Station;
|
||||
if (station) {
|
||||
stationModel.copyFrom((station as Station).states as StationState);
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
const station = lineStore.selectedGraphic as Station;
|
||||
const data = {
|
||||
ipRtuStusDown: false,
|
||||
ipRtuStusInLocalCtrl: false,
|
||||
ipRtuStusInCentralCtrl: false,
|
||||
ipRtuStusInEmergencyCtrl: false,
|
||||
id: station.id,
|
||||
};
|
||||
const lineId = lineStore.lineId as number;
|
||||
data.ipRtuStusDown = stationModel.ipRtuStusDown;
|
||||
data.ipRtuStusInLocalCtrl = stationModel.ipRtuStusInLocalCtrl;
|
||||
if (station) {
|
||||
switch (controlChange.value) {
|
||||
case '中控':
|
||||
data.ipRtuStusInLocalCtrl = false;
|
||||
data.ipRtuStusDown = false;
|
||||
break;
|
||||
case '站控且允许转到中控':
|
||||
data.ipRtuStusInLocalCtrl = true;
|
||||
data.ipRtuStusDown = false;
|
||||
break;
|
||||
case '站控且不允许转到中控':
|
||||
data.ipRtuStusInLocalCtrl = true;
|
||||
data.ipRtuStusDown = true;
|
||||
break;
|
||||
}
|
||||
mockStationApi(lineId, data)
|
||||
.then((res) => {
|
||||
console.log(res, '---res--');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err, '---err---');
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,31 +0,0 @@
|
||||
import { HandleMessage, StompMessagingClient } from 'jl-graphic';
|
||||
import { getJwtToken } from 'src/configs/TokenManage';
|
||||
import { getWebsocketUrl } from 'src/configs/UrlManage';
|
||||
|
||||
export function webSocketConnect(destination: string, handler: HandleMessage) {
|
||||
const socket = new StompMessagingClient({
|
||||
wsUrl: `${getWebsocketUrl()}`,
|
||||
token: getJwtToken() as string,
|
||||
protocol: 'protobuf',
|
||||
connectTimeout: 30 * 1000,
|
||||
heartbeat: 60,
|
||||
retryPeriod: 2 * 1000,
|
||||
retryTimes: 100,
|
||||
});
|
||||
socket.on('connected', () => {
|
||||
socket?.subscribe(destination, handler);
|
||||
});
|
||||
socket.on('disconnected', () => {
|
||||
console.log('disconnected');
|
||||
});
|
||||
return socket;
|
||||
}
|
||||
|
||||
export function closeWebSocketConnect(
|
||||
socket: StompMessagingClient | null,
|
||||
destination: string
|
||||
) {
|
||||
socket?.unsubscribe0(destination);
|
||||
socket?.close();
|
||||
socket = null;
|
||||
}
|
@ -1,23 +1,15 @@
|
||||
function getHost(): string {
|
||||
const base_api = process.env.API;
|
||||
// console.log(process.env);
|
||||
// console.log(' load env :' + process.env.NODE_ENV);
|
||||
return base_api + '';
|
||||
// return '192.168.3.7:9081';
|
||||
// return '192.168.3.47:9081';
|
||||
// return '192.168.3.37:9081';
|
||||
// return '192.168.3.15:9081';
|
||||
return '192.168.3.233:9081';
|
||||
}
|
||||
|
||||
export function getHttpBase() {
|
||||
return process.env.HTTP + `${getHost()}` + process.env.NS;
|
||||
return `http://${getHost()}`;
|
||||
}
|
||||
|
||||
export function getWebsocketUrl() {
|
||||
return process.env.WS + `${getHost()}`+ process.env.NS+'/ws-default';
|
||||
}
|
||||
|
||||
export function getShowSetAlarmTextButton() {
|
||||
let show = false;
|
||||
const host = window.location.hostname;
|
||||
if (process.env.NODE_ENV == 'development' || host == '192.168.3.233') {
|
||||
show = true;
|
||||
}
|
||||
return show;
|
||||
return `ws://${getHost()}/ws-default`;
|
||||
}
|
||||
|
@ -1,4 +1 @@
|
||||
// app global css in SCSS form
|
||||
.my-notif-class {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
@ -33,9 +33,6 @@ export class AxleCountingData
|
||||
this.data.code = v;
|
||||
}
|
||||
get kilometerSystem(): KilometerSystem {
|
||||
if (!this.data.kilometerSystem) {
|
||||
this.data.kilometerSystem = new graphicData.KilometerSystem();
|
||||
}
|
||||
return this.data.kilometerSystem;
|
||||
}
|
||||
set kilometerSystem(v: KilometerSystem) {
|
||||
|
@ -1,77 +0,0 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
import {
|
||||
IConcentrationDividingLineData,
|
||||
ConcentrationDividingLine,
|
||||
} from 'src/graphics/concentrationDividingLine/ConcentrationDividingLine';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { IPointData } from 'pixi.js';
|
||||
|
||||
export class ConcentrationDividingLineData
|
||||
extends GraphicDataBase
|
||||
implements IConcentrationDividingLineData
|
||||
{
|
||||
constructor(data?: graphicData.ConcentrationDividingLine) {
|
||||
let concentrationDividingLine;
|
||||
if (!data) {
|
||||
concentrationDividingLine = new graphicData.ConcentrationDividingLine({
|
||||
common: GraphicDataBase.defaultCommonInfo(
|
||||
ConcentrationDividingLine.Type
|
||||
),
|
||||
});
|
||||
} else {
|
||||
concentrationDividingLine = data;
|
||||
}
|
||||
super(concentrationDividingLine);
|
||||
}
|
||||
public get data(): graphicData.ConcentrationDividingLine {
|
||||
return this.getData<graphicData.ConcentrationDividingLine>();
|
||||
}
|
||||
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 refLeftStationId(): number {
|
||||
return this.data.refLeftStationId;
|
||||
}
|
||||
set refLeftStationId(v: number) {
|
||||
this.data.refLeftStationId = v;
|
||||
}
|
||||
get refRightStationId(): number {
|
||||
return this.data.refRightStationId;
|
||||
}
|
||||
set refRightStationId(v: number) {
|
||||
this.data.refRightStationId = v;
|
||||
}
|
||||
get nodeConWithSecs(): graphicData.NodeConWithSec[] {
|
||||
return this.data.nodeConWithSecs;
|
||||
}
|
||||
set nodeConWithSecs(nodes: graphicData.NodeConWithSec[]) {
|
||||
this.data.nodeConWithSecs = nodes;
|
||||
}
|
||||
get isOtherLineConcentrationDividingLine(): boolean {
|
||||
return this.data.isOtherLineConcentrationDividingLine;
|
||||
}
|
||||
set isOtherLineConcentrationDividingLine(v: boolean) {
|
||||
this.data.isOtherLineConcentrationDividingLine = v;
|
||||
}
|
||||
clone(): ConcentrationDividingLineData {
|
||||
return new ConcentrationDividingLineData(this.data.cloneMessage());
|
||||
}
|
||||
copyFrom(data: ConcentrationDividingLineData): void {
|
||||
pb_1.Message.copyInto(data.data, this.data);
|
||||
}
|
||||
eq(other: ConcentrationDividingLineData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
@ -6,13 +6,14 @@ import {
|
||||
GraphicTransform,
|
||||
IChildTransform,
|
||||
IGraphicTransform,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic';
|
||||
// import { toStorageTransform } from '..';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { IPointData, Point } from 'pixi.js';
|
||||
import { state } from 'src/protos/device_status';
|
||||
|
||||
export interface ICommonInfo {
|
||||
id: number;
|
||||
id: string;
|
||||
graphicType: string;
|
||||
transform: IGraphicTransform;
|
||||
childTransforms: IChildTransform[];
|
||||
@ -59,7 +60,7 @@ export abstract class GraphicDataBase implements GraphicData {
|
||||
|
||||
static defaultCommonInfo(graphicType: string): graphicData.CommonInfo {
|
||||
return new graphicData.CommonInfo({
|
||||
id: 0,
|
||||
id: '',
|
||||
graphicType: graphicType,
|
||||
transform: new graphicData.Transform({
|
||||
position: new graphicData.Point({ x: 0, y: 0 }),
|
||||
@ -75,10 +76,10 @@ export abstract class GraphicDataBase implements GraphicData {
|
||||
return this._data as D;
|
||||
}
|
||||
|
||||
get id(): number {
|
||||
get id(): string {
|
||||
return this._data.common.id;
|
||||
}
|
||||
set id(v: number) {
|
||||
set id(v: string) {
|
||||
this._data.common.id = v;
|
||||
}
|
||||
get graphicType(): string {
|
||||
|
@ -3,18 +3,20 @@ import { IPointData, DisplayObject, FederatedMouseEvent } from 'pixi.js';
|
||||
import { ILinkData, Link } from 'src/graphics/link/Link';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||
import {
|
||||
IGraphicApp,
|
||||
GraphicApp,
|
||||
GraphicInteractionPlugin,
|
||||
JlGraphic,
|
||||
ContextMenu,
|
||||
MenuItemOptions,
|
||||
} from 'src/jl-graphic';
|
||||
import {
|
||||
addWayPoint,
|
||||
clearWayPoint,
|
||||
getWaypointRangeIndex,
|
||||
PolylineEditPlugin,
|
||||
removeLineWayPoint,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic/plugins/GraphicEditPlugin';
|
||||
|
||||
export class LinkData extends GraphicDataBase implements ILinkData {
|
||||
constructor(data?: graphicData.Link) {
|
||||
@ -117,12 +119,12 @@ const EpEditMenu: ContextMenu = ContextMenu.init({
|
||||
|
||||
export class DrawLinkPlugin extends GraphicInteractionPlugin<Link> {
|
||||
static Name = 'link_draw_right_menu';
|
||||
constructor(app: IGraphicApp) {
|
||||
constructor(app: GraphicApp) {
|
||||
super(DrawLinkPlugin.Name, app);
|
||||
app.registerMenu(LinkEditMenu);
|
||||
app.registerMenu(EpEditMenu);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
static init(app: GraphicApp) {
|
||||
return new DrawLinkPlugin(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Link[] | undefined {
|
||||
|
@ -10,16 +10,15 @@ import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { DisplayObject, FederatedMouseEvent, IPointData } from 'pixi.js';
|
||||
import { state } from 'src/protos/device_status';
|
||||
import {
|
||||
IGraphicApp,
|
||||
GraphicApp,
|
||||
GraphicInteractionPlugin,
|
||||
JlGraphic,
|
||||
MenuItemOptions,
|
||||
ContextMenu,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic';
|
||||
import { LogicSectionGraphicHitArea } from 'src/graphics/logicSection/LogicSectionDrawAssistant';
|
||||
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
import { setTrackStatus } from 'src/api/TurnoutApi';
|
||||
import { successNotify } from 'src/utils/CommonNotify';
|
||||
|
||||
let menuItemHandler: (propName: keyof ILogicSectionState) => void;
|
||||
|
||||
@ -55,10 +54,6 @@ const blocked: MenuItemOptions = {
|
||||
name: '轨道区段封锁 - blocked',
|
||||
handler: () => menuItemHandler('blocked'),
|
||||
};
|
||||
const speedLimit: MenuItemOptions = {
|
||||
name: '限速 - speedLimit',
|
||||
handler: () => menuItemHandler('speedLimit'),
|
||||
};
|
||||
|
||||
const LogicSectionMenu = ContextMenu.init({
|
||||
name: 'LogicSection菜单',
|
||||
@ -73,7 +68,6 @@ const LogicSectionMenu = ContextMenu.init({
|
||||
atcInvalid,
|
||||
overlap,
|
||||
blocked,
|
||||
speedLimit,
|
||||
],
|
||||
},
|
||||
],
|
||||
@ -81,32 +75,25 @@ const LogicSectionMenu = ContextMenu.init({
|
||||
|
||||
export class LogicSectionOperationPlugin extends GraphicInteractionPlugin<LogicSection> {
|
||||
static Name = 'logic_section_menu';
|
||||
constructor(app: IGraphicApp) {
|
||||
constructor(app: GraphicApp) {
|
||||
super(LogicSectionOperationPlugin.Name, app);
|
||||
app.registerMenu(LogicSectionMenu);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): LogicSection[] | undefined {
|
||||
return grahpics.filter((g): g is LogicSection => g instanceof LogicSection);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
static init(app: GraphicApp) {
|
||||
return new LogicSectionOperationPlugin(app);
|
||||
}
|
||||
bind(g: LogicSection): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.lineGraphic.hitArea = new LogicSectionGraphicHitArea(g);
|
||||
g.on('_leftclick', this.onLeftClick, this);
|
||||
g.on('rightclick', this.onContextMenu, this);
|
||||
}
|
||||
unbind(g: LogicSection): void {
|
||||
g.off('_leftclick', this.onLeftClick, this);
|
||||
g.off('rightclick', this.onContextMenu);
|
||||
}
|
||||
onLeftClick(e: FederatedMouseEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const section = target.getGraphic() as LogicSection;
|
||||
this.app.updateSelected(section);
|
||||
}
|
||||
onContextMenu(e: FederatedMouseEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const section = target.getGraphic() as LogicSection;
|
||||
@ -154,16 +141,10 @@ export class LogicSectionOperationPlugin extends GraphicInteractionPlugin<LogicS
|
||||
menuItemHandler = (propName) => {
|
||||
const lineId = useLineStore().lineId?.toString();
|
||||
if (!lineId) return;
|
||||
let val: boolean | number;
|
||||
if (propName !== 'speedLimit') {
|
||||
val = !section.states[propName];
|
||||
} else {
|
||||
val = section.states[propName] > 0 ? 0 : 20;
|
||||
successNotify(`限速设为${val}`);
|
||||
}
|
||||
console.log({ ...section.states });
|
||||
setTrackStatus(lineId, {
|
||||
...state,
|
||||
[propName]: val,
|
||||
[propName]: !section.states[propName],
|
||||
});
|
||||
};
|
||||
LogicSectionMenu.open(e.global);
|
||||
@ -314,14 +295,6 @@ export class LogicSectionState
|
||||
public set limitType(value: LimitType) {
|
||||
this.states.limitType = value;
|
||||
}
|
||||
|
||||
// 集中站站号
|
||||
public get rtuId(): number {
|
||||
return this.states.rtuId;
|
||||
}
|
||||
public set rtuId(value: number) {
|
||||
this.states.rtuId = value;
|
||||
}
|
||||
clone(): LogicSectionState {
|
||||
return new LogicSectionState(this.states.cloneMessage());
|
||||
}
|
||||
|
@ -7,13 +7,13 @@ import {
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
|
||||
import { state } from 'src/protos/device_status';
|
||||
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
import {
|
||||
IGraphicApp,
|
||||
GraphicApp,
|
||||
GraphicInteractionPlugin,
|
||||
JlGraphic,
|
||||
MenuItemOptions,
|
||||
ContextMenu,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic';
|
||||
import { DisplayObject, FederatedMouseEvent } from 'pixi.js';
|
||||
import { mockPlatformApi } from 'src/api/PlatformApi';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
@ -59,24 +59,12 @@ export class PlatformData extends GraphicDataBase implements IPlatformData {
|
||||
set up(v: boolean) {
|
||||
this.data.up = v;
|
||||
}
|
||||
get refStation(): number {
|
||||
get refStation(): string {
|
||||
return this.data.refStation;
|
||||
}
|
||||
set refStation(v: number) {
|
||||
set refStation(v: string) {
|
||||
this.data.refStation = v;
|
||||
}
|
||||
get refSectionId(): number {
|
||||
return this.data.refSectionId;
|
||||
}
|
||||
set refSectionId(v: number) {
|
||||
this.data.refSectionId = v;
|
||||
}
|
||||
get centralizedStation(): number {
|
||||
return this.data.centralizedStationId;
|
||||
}
|
||||
set centralizedStation(v: number) {
|
||||
this.data.centralizedStationId = v;
|
||||
}
|
||||
|
||||
clone(): PlatformData {
|
||||
return new PlatformData(this.data.cloneMessage());
|
||||
@ -200,13 +188,6 @@ export class PlatformState extends GraphicStateBase implements IPlatformState {
|
||||
set stopTime(v: number) {
|
||||
this.states.stopTime = v;
|
||||
}
|
||||
// 集中站站号
|
||||
get rtuId(): number {
|
||||
return this.states.rtuId;
|
||||
}
|
||||
set rtuId(value: number) {
|
||||
this.states.rtuId = value;
|
||||
}
|
||||
get states(): state.Platform {
|
||||
return this.getState<state.Platform>();
|
||||
}
|
||||
@ -221,26 +202,86 @@ export class PlatformState extends GraphicStateBase implements IPlatformState {
|
||||
}
|
||||
}
|
||||
|
||||
const resetConfig: MenuItemOptions = {
|
||||
name: '重置状态',
|
||||
const holdConfig: MenuItemOptions = {
|
||||
name: '扣车',
|
||||
};
|
||||
const removeHoldrConfig: MenuItemOptions = {
|
||||
name: '取消扣车',
|
||||
};
|
||||
const batchHoldConfig: MenuItemOptions = {
|
||||
name: '批量扣车',
|
||||
};
|
||||
const removeBatchHoldConfig: MenuItemOptions = {
|
||||
name: '批量取消扣车',
|
||||
};
|
||||
const earlyDepartureConfig: MenuItemOptions = {
|
||||
name: '提前发车',
|
||||
};
|
||||
const skipStopConfig: MenuItemOptions = {
|
||||
name: '设置跳停',
|
||||
};
|
||||
const removeSkipStopConfig: MenuItemOptions = {
|
||||
name: '取消跳停',
|
||||
};
|
||||
const dockTimeConfig: MenuItemOptions = {
|
||||
name: '设置停站时间',
|
||||
};
|
||||
const operatingLevelConfig: MenuItemOptions = {
|
||||
name: '设置运行等级',
|
||||
};
|
||||
const numberOfRegionalTrainsConfig: MenuItemOptions = {
|
||||
name: '区间列车数量限制',
|
||||
};
|
||||
const removeNumberOfRegionalTrainsConfig: MenuItemOptions = {
|
||||
name: '取消区间列车数量限制',
|
||||
};
|
||||
const platformMessadeConfig: MenuItemOptions = {
|
||||
name: '站台详细信息',
|
||||
};
|
||||
|
||||
const PlatformOperateMenu: ContextMenu = ContextMenu.init({
|
||||
name: '站台操作菜单',
|
||||
groups: [
|
||||
{
|
||||
items: [resetConfig],
|
||||
items: [
|
||||
holdConfig,
|
||||
removeHoldrConfig,
|
||||
skipStopConfig,
|
||||
removeSkipStopConfig,
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const dispatchPlatformOperateMenu: ContextMenu = ContextMenu.init({
|
||||
name: '调度仿真站台操作菜单',
|
||||
groups: [
|
||||
{
|
||||
items: [
|
||||
holdConfig,
|
||||
removeHoldrConfig,
|
||||
batchHoldConfig,
|
||||
removeBatchHoldConfig,
|
||||
earlyDepartureConfig,
|
||||
skipStopConfig,
|
||||
removeSkipStopConfig,
|
||||
dockTimeConfig,
|
||||
operatingLevelConfig,
|
||||
numberOfRegionalTrainsConfig,
|
||||
removeNumberOfRegionalTrainsConfig,
|
||||
platformMessadeConfig,
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export class PlatformOperateInteraction extends GraphicInteractionPlugin<Platform> {
|
||||
static Name = 'platform_operate_menu';
|
||||
constructor(app: IGraphicApp) {
|
||||
constructor(app: GraphicApp) {
|
||||
super(PlatformOperateInteraction.Name, app);
|
||||
app.registerMenu(PlatformOperateMenu);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
static init(app: GraphicApp) {
|
||||
return new PlatformOperateInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Platform[] | undefined {
|
||||
@ -286,8 +327,70 @@ export class PlatformOperateInteraction extends GraphicInteractionPlugin<Platfor
|
||||
nextSectionRunLevel: 0,
|
||||
stopTime: 0,
|
||||
};
|
||||
resetConfig.handler = () => {
|
||||
holdConfig.handler = () => {
|
||||
const dataCopy = JSON.parse(JSON.stringify(data));
|
||||
if (platform.datas.direction == 'down') {
|
||||
//dataCopy.upHold = true; //上行方向车站扣车
|
||||
dataCopy.trainberth = true; //列车停站
|
||||
dataCopy.emergstop = true; //紧急关闭
|
||||
dataCopy.upOccHold = true; //上行方向中心扣车
|
||||
dataCopy.psdOpen = true;
|
||||
dataCopy.nextSectionRunLevel = 2;
|
||||
dataCopy.nextSectionRunTime = 10;
|
||||
dataCopy.stopTime = 5;
|
||||
} else {
|
||||
dataCopy.downHold = true; //下行方向车站扣车
|
||||
dataCopy.downOccHold = true; //下行方向中心扣车
|
||||
dataCopy.psdCut = true;
|
||||
}
|
||||
mockPlatformApi(lineId, dataCopy)
|
||||
.then((res) => {
|
||||
console.log(res, '---res--');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err, '---err---');
|
||||
});
|
||||
};
|
||||
removeHoldrConfig.handler = () => {
|
||||
const dataCopy = JSON.parse(JSON.stringify(data));
|
||||
if (platform.datas.direction == 'down') {
|
||||
dataCopy.upHold = false;
|
||||
} else {
|
||||
dataCopy.downHold = false;
|
||||
}
|
||||
mockPlatformApi(lineId, dataCopy)
|
||||
.then((res) => {
|
||||
console.log(res, '---res--');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err, '---err---');
|
||||
});
|
||||
};
|
||||
skipStopConfig.handler = () => {
|
||||
const dataCopy = JSON.parse(JSON.stringify(data));
|
||||
if (platform.datas.direction == 'down') {
|
||||
dataCopy.upSkipstop = true; //上行方向跳停
|
||||
} else {
|
||||
dataCopy.downSkipstop = true; //下行方向跳停
|
||||
dataCopy.nextSectionRunLevel = 2;
|
||||
dataCopy.nextSectionRunTime = 10;
|
||||
dataCopy.stopTime = 5;
|
||||
}
|
||||
mockPlatformApi(lineId, dataCopy)
|
||||
.then((res) => {
|
||||
console.log(res, '---res--');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err, '---err---');
|
||||
});
|
||||
};
|
||||
removeSkipStopConfig.handler = () => {
|
||||
const dataCopy = JSON.parse(JSON.stringify(data));
|
||||
if (platform.datas.direction == 'down') {
|
||||
dataCopy.upSkipstop = false;
|
||||
} else {
|
||||
dataCopy.downSkipstop = false;
|
||||
}
|
||||
mockPlatformApi(lineId, dataCopy)
|
||||
.then((res) => {
|
||||
console.log(res, '---res--');
|
||||
|
@ -4,7 +4,7 @@ import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
import { DisplayObject, FederatedMouseEvent, IPointData } from 'pixi.js';
|
||||
import {
|
||||
IGraphicApp,
|
||||
GraphicApp,
|
||||
GraphicInteractionPlugin,
|
||||
JlGraphic,
|
||||
} from 'src/jl-graphic';
|
||||
@ -128,12 +128,12 @@ const EpEditMenu: ContextMenu = ContextMenu.init({
|
||||
|
||||
export class DrawPolygonPlugin extends GraphicInteractionPlugin<Polygon> {
|
||||
static Name = 'polygon_draw_right_menu';
|
||||
constructor(app: IGraphicApp) {
|
||||
constructor(app: GraphicApp) {
|
||||
super(DrawPolygonPlugin.Name, app);
|
||||
app.registerMenu(PolygonEditMenu);
|
||||
app.registerMenu(EpEditMenu);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
static init(app: GraphicApp) {
|
||||
return new DrawPolygonPlugin(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Polygon[] | undefined {
|
||||
|
@ -8,21 +8,22 @@ import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
import {
|
||||
GraphicInteractionPlugin,
|
||||
IGraphicApp,
|
||||
GraphicApp,
|
||||
JlGraphic,
|
||||
ContextMenu,
|
||||
MenuItemOptions,
|
||||
} from 'src/jl-graphic';
|
||||
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||
import { FederatedMouseEvent, DisplayObject, IPointData } from 'pixi.js';
|
||||
import {
|
||||
addWayPoint,
|
||||
clearWayPoint,
|
||||
getWaypointRangeIndex,
|
||||
PolylineEditPlugin,
|
||||
removeLineWayPoint,
|
||||
} from 'jl-graphic';
|
||||
import { FederatedMouseEvent, DisplayObject, IPointData } from 'pixi.js';
|
||||
} from 'src/jl-graphic/plugins/GraphicEditPlugin';
|
||||
import { RunLineGraphicHitArea } from 'src/graphics/runLine/RunLineDrawAssistant';
|
||||
import { Dialog } from 'quasar';
|
||||
import SetDashLineDialog from '../../components/draw-app/dialogs/SetDashLineDialog.vue';
|
||||
import SetGaryLineDialog from '../../components/draw-app/dialogs/SetGaryLineDialog.vue';
|
||||
|
||||
export class RunLineData extends GraphicDataBase implements IRunLineData {
|
||||
constructor(data?: graphicData.RunLine) {
|
||||
@ -71,10 +72,10 @@ export class RunLineData extends GraphicDataBase implements IRunLineData {
|
||||
set containSta(v: string[]) {
|
||||
this.data.containSta = v;
|
||||
}
|
||||
get linkPathLines(): number[] {
|
||||
get linkPathLines(): string[] {
|
||||
return this.data.linkPathLines;
|
||||
}
|
||||
set linkPathLines(v: number[]) {
|
||||
set linkPathLines(v: string[]) {
|
||||
this.data.linkPathLines = v;
|
||||
}
|
||||
get lineId(): string {
|
||||
@ -89,18 +90,6 @@ export class RunLineData extends GraphicDataBase implements IRunLineData {
|
||||
set dashPointIndexs(v: number[]) {
|
||||
this.data.dashPointIndexs = v;
|
||||
}
|
||||
get grayPointIndexs(): number[] {
|
||||
return this.data.grayPointIndexs;
|
||||
}
|
||||
set grayPointIndexs(v: number[]) {
|
||||
this.data.grayPointIndexs = v;
|
||||
}
|
||||
get lineColor(): string {
|
||||
return this.data.lineColor;
|
||||
}
|
||||
set lineColor(v: string) {
|
||||
this.data.lineColor = v;
|
||||
}
|
||||
clone(): RunLineData {
|
||||
return new RunLineData(this.data.cloneMessage());
|
||||
}
|
||||
@ -124,20 +113,12 @@ export const clearWaypointsConfig: MenuItemOptions = {
|
||||
export const setDashLineConfig: MenuItemOptions = {
|
||||
name: '设置虚线段',
|
||||
};
|
||||
export const setGrayLineConfig: MenuItemOptions = {
|
||||
name: '设置灰线段',
|
||||
};
|
||||
|
||||
const RunLineEditMenu: ContextMenu = ContextMenu.init({
|
||||
name: '运行线编辑菜单',
|
||||
groups: [
|
||||
{
|
||||
items: [
|
||||
addWaypointConfig,
|
||||
clearWaypointsConfig,
|
||||
setDashLineConfig,
|
||||
setGrayLineConfig,
|
||||
],
|
||||
items: [addWaypointConfig, clearWaypointsConfig, setDashLineConfig],
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -152,12 +133,12 @@ const EpEditMenu: ContextMenu = ContextMenu.init({
|
||||
|
||||
export class DrawRunLinePlugin extends GraphicInteractionPlugin<RunLine> {
|
||||
static Name = 'runline_draw_right_menu';
|
||||
constructor(app: IGraphicApp) {
|
||||
constructor(app: GraphicApp) {
|
||||
super(DrawRunLinePlugin.Name, app);
|
||||
app.registerMenu(RunLineEditMenu);
|
||||
app.registerMenu(EpEditMenu);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
static init(app: GraphicApp) {
|
||||
return new DrawRunLinePlugin(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): RunLine[] | undefined {
|
||||
@ -214,7 +195,7 @@ export class DrawRunLinePlugin extends GraphicInteractionPlugin<RunLine> {
|
||||
};
|
||||
setDashLineConfig.handler = () => {
|
||||
Dialog.create({
|
||||
title: '设置虚线段',
|
||||
title: '创建列车',
|
||||
message: '',
|
||||
component: SetDashLineDialog,
|
||||
componentProps: {
|
||||
@ -234,40 +215,17 @@ export class DrawRunLinePlugin extends GraphicInteractionPlugin<RunLine> {
|
||||
runLine.doRepaint();
|
||||
});
|
||||
};
|
||||
setGrayLineConfig.handler = () => {
|
||||
console.log(runLine.datas, '11111');
|
||||
Dialog.create({
|
||||
title: '设置灰线段',
|
||||
message: '',
|
||||
component: SetGaryLineDialog,
|
||||
componentProps: {
|
||||
runLinePoints: runLine.datas.points,
|
||||
garyPointIndexs: runLine.datas.grayPointIndexs,
|
||||
},
|
||||
cancel: true,
|
||||
persistent: true,
|
||||
}).onOk((data: { min: number; max: number }) => {
|
||||
const indexList = [];
|
||||
if (data.min !== data.max) {
|
||||
for (let i = data.min; i <= data.max; i++) {
|
||||
indexList.push(i);
|
||||
}
|
||||
}
|
||||
runLine.datas.grayPointIndexs = indexList;
|
||||
runLine.doRepaint();
|
||||
});
|
||||
};
|
||||
RunLineEditMenu.open(e.global);
|
||||
}
|
||||
}
|
||||
|
||||
export class RunLineOperateInteraction extends GraphicInteractionPlugin<RunLine> {
|
||||
static Name = 'runLine_operate_menu';
|
||||
constructor(app: IGraphicApp) {
|
||||
constructor(app: GraphicApp) {
|
||||
super(RunLineOperateInteraction.Name, app);
|
||||
app.registerMenu(EpEditMenu);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
static init(app: GraphicApp) {
|
||||
return new RunLineOperateInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): RunLine[] | undefined {
|
||||
|
@ -2,9 +2,7 @@ import * as pb_1 from 'google-protobuf';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
import { ISectionData, Section } from 'src/graphics/section/Section';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { DisplayObject, FederatedMouseEvent, IPointData } from 'pixi.js';
|
||||
import { GraphicInteractionPlugin, IGraphicApp, JlGraphic } from 'jl-graphic';
|
||||
import { SectionGraphicHitArea } from 'src/graphics/section/SectionDrawAssistant';
|
||||
import { IPointData } from 'pixi.js';
|
||||
|
||||
export class SectionData extends GraphicDataBase implements ISectionData {
|
||||
constructor(data?: graphicData.Section) {
|
||||
@ -53,16 +51,16 @@ export class SectionData extends GraphicDataBase implements ISectionData {
|
||||
set sectionType(type: graphicData.Section.SectionType) {
|
||||
this.data.sectionType = type;
|
||||
}
|
||||
get axleCountings(): number[] {
|
||||
return this.data.axleCountings.map((a) => Number(a));
|
||||
get axleCountings(): string[] {
|
||||
return this.data.axleCountings;
|
||||
}
|
||||
set axleCountings(axleCountings: number[]) {
|
||||
this.data.axleCountings = axleCountings.map((a) => a.toString());
|
||||
set axleCountings(axleCountings: string[]) {
|
||||
this.data.axleCountings = axleCountings;
|
||||
}
|
||||
get children(): number[] {
|
||||
get children(): string[] {
|
||||
return this.data.children;
|
||||
}
|
||||
set children(children: number[]) {
|
||||
set children(children: string[]) {
|
||||
this.data.children = children;
|
||||
}
|
||||
get destinationCode(): string {
|
||||
@ -71,18 +69,6 @@ export class SectionData extends GraphicDataBase implements ISectionData {
|
||||
set destinationCode(destinationCode: string) {
|
||||
this.data.destinationCode = destinationCode;
|
||||
}
|
||||
get turning(): boolean {
|
||||
return this.data.turning;
|
||||
}
|
||||
set turning(v: boolean) {
|
||||
this.data.turning = v;
|
||||
}
|
||||
get centralizedStation(): number {
|
||||
return this.data.centralizedStationId;
|
||||
}
|
||||
set centralizedStation(v: number) {
|
||||
this.data.centralizedStationId = v;
|
||||
}
|
||||
clone(): SectionData {
|
||||
return new SectionData(this.data.cloneMessage());
|
||||
}
|
||||
@ -93,30 +79,3 @@ export class SectionData extends GraphicDataBase implements ISectionData {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
||||
|
||||
export class sectionOperationPlugin extends GraphicInteractionPlugin<Section> {
|
||||
static Name = 'logic_section_menu';
|
||||
constructor(app: IGraphicApp) {
|
||||
super(sectionOperationPlugin.Name, app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Section[] | undefined {
|
||||
return grahpics.filter((g): g is Section => g instanceof Section);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
return new sectionOperationPlugin(app);
|
||||
}
|
||||
bind(g: Section): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.lineGraphic.hitArea = new SectionGraphicHitArea(g);
|
||||
g.on('_leftclick', this.onLeftClick, this);
|
||||
}
|
||||
unbind(g: Section): void {
|
||||
g.off('_leftclick', this.onLeftClick, this);
|
||||
}
|
||||
onLeftClick(e: FederatedMouseEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const section = target.getGraphic() as Section;
|
||||
this.app.updateSelected(section);
|
||||
}
|
||||
}
|
||||
|
@ -9,16 +9,15 @@ import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
|
||||
import {
|
||||
GraphicInteractionPlugin,
|
||||
IGraphicApp,
|
||||
GraphicApp,
|
||||
JlGraphic,
|
||||
ContextMenu,
|
||||
MenuItemOptions,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic';
|
||||
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||
import { FederatedMouseEvent, DisplayObject } from 'pixi.js';
|
||||
import { state } from 'src/protos/device_status';
|
||||
import { mockSignalApi } from 'src/api/PlatformApi';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
import { SignalGraphicHitArea } from 'src/graphics/signal/SignalDrawAssistant';
|
||||
|
||||
export class SignalData extends GraphicDataBase implements ISignalData {
|
||||
constructor(data?: graphicData.Signal) {
|
||||
@ -47,27 +46,12 @@ export class SignalData extends GraphicDataBase implements ISignalData {
|
||||
set mirror(v: boolean) {
|
||||
this.data.mirror = v;
|
||||
}
|
||||
get refDevice(): graphicData.RelatedRef {
|
||||
return this.data.refDevice;
|
||||
}
|
||||
set refDevice(v: graphicData.RelatedRef) {
|
||||
this.data.refDevice = v;
|
||||
}
|
||||
get kilometerSystem(): KilometerSystem {
|
||||
if (!this.data.kilometerSystem) {
|
||||
this.data.kilometerSystem = new graphicData.KilometerSystem();
|
||||
}
|
||||
return this.data.kilometerSystem;
|
||||
}
|
||||
set kilometerSystem(v: KilometerSystem) {
|
||||
this.data.kilometerSystem = new graphicData.KilometerSystem(v);
|
||||
}
|
||||
get centralizedStation(): number {
|
||||
return this.data.centralizedStationId;
|
||||
}
|
||||
set centralizedStation(v: number) {
|
||||
this.data.centralizedStationId = v;
|
||||
}
|
||||
clone(): SignalData {
|
||||
return new SignalData(this.data.cloneMessage());
|
||||
}
|
||||
@ -231,13 +215,6 @@ export class SignalState extends GraphicStateBase implements ISignalState {
|
||||
set lampFailure(v: boolean) {
|
||||
this.states.lampFailure = v;
|
||||
}
|
||||
// 集中站站号
|
||||
get rtuId(): number {
|
||||
return this.states.rtuId;
|
||||
}
|
||||
set rtuId(value: number) {
|
||||
this.states.rtuId = value;
|
||||
}
|
||||
get states(): state.Signal {
|
||||
return this.getState<state.Signal>();
|
||||
}
|
||||
@ -298,11 +275,11 @@ const SignalOperateMenu: ContextMenu = ContextMenu.init({
|
||||
});
|
||||
export class DrawSignalInteraction extends GraphicInteractionPlugin<Signal> {
|
||||
static Name = 'signal_draw_right_menu';
|
||||
constructor(app: IGraphicApp) {
|
||||
constructor(app: GraphicApp) {
|
||||
super(DrawSignalInteraction.Name, app);
|
||||
app.registerMenu(SignalEditMenu);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
static init(app: GraphicApp) {
|
||||
return new DrawSignalInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Signal[] | undefined {
|
||||
@ -331,11 +308,11 @@ export class DrawSignalInteraction extends GraphicInteractionPlugin<Signal> {
|
||||
|
||||
export class SignalOperateInteraction extends GraphicInteractionPlugin<Signal> {
|
||||
static Name = 'signal_operate_menu';
|
||||
constructor(app: IGraphicApp) {
|
||||
constructor(app: GraphicApp) {
|
||||
super(SignalOperateInteraction.Name, app);
|
||||
app.registerMenu(SignalOperateMenu);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
static init(app: GraphicApp) {
|
||||
return new SignalOperateInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Signal[] | undefined {
|
||||
@ -347,7 +324,6 @@ export class SignalOperateInteraction extends GraphicInteractionPlugin<Signal> {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.selectable = true;
|
||||
g.lampMainBody.hitArea = new SignalGraphicHitArea(g);
|
||||
g.on('_rightclick', this.onContextMenu, this);
|
||||
}
|
||||
|
||||
|
@ -7,17 +7,17 @@ import {
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
|
||||
import { state } from 'src/protos/device_status';
|
||||
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
import {
|
||||
IGraphicApp,
|
||||
GraphicApp,
|
||||
GraphicInteractionPlugin,
|
||||
JlGraphic,
|
||||
MenuItemOptions,
|
||||
ContextMenu,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic';
|
||||
import { DisplayObject, FederatedMouseEvent } from 'pixi.js';
|
||||
import { KilometerSystem } from 'src/graphics/signal/Signal';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
import { mockServerApi, mockStationApi } from 'src/api/PlatformApi';
|
||||
import { mockStationApi } from 'src/api/PlatformApi';
|
||||
|
||||
export class StationData extends GraphicDataBase implements IStationData {
|
||||
constructor(data?: graphicData.Station) {
|
||||
@ -42,9 +42,6 @@ export class StationData extends GraphicDataBase implements IStationData {
|
||||
this.data.code = v;
|
||||
}
|
||||
get kilometerSystem(): KilometerSystem {
|
||||
if (!this.data.kilometerSystem) {
|
||||
this.data.kilometerSystem = new graphicData.KilometerSystem();
|
||||
}
|
||||
return this.data.kilometerSystem;
|
||||
}
|
||||
set kilometerSystem(v: KilometerSystem) {
|
||||
@ -68,18 +65,6 @@ export class StationData extends GraphicDataBase implements IStationData {
|
||||
set name(v: string) {
|
||||
this.data.name = v;
|
||||
}
|
||||
get manageStations(): number[] {
|
||||
return this.data.manageStations;
|
||||
}
|
||||
set manageStations(v: number[]) {
|
||||
this.data.manageStations = v;
|
||||
}
|
||||
get depots(): boolean {
|
||||
return this.data.depots;
|
||||
}
|
||||
set depots(v: boolean) {
|
||||
this.data.depots = v;
|
||||
}
|
||||
clone(): StationData {
|
||||
return new StationData(this.data.cloneMessage());
|
||||
}
|
||||
@ -103,12 +88,8 @@ export class StationState extends GraphicStateBase implements IStationState {
|
||||
}
|
||||
|
||||
get code(): string {
|
||||
if (this.states.id.length === 1) {
|
||||
return '0' + this.states.id;
|
||||
} else {
|
||||
return this.states.id;
|
||||
}
|
||||
}
|
||||
get ipRtuStusDown(): boolean {
|
||||
return this.states.ipRtuStusDown;
|
||||
}
|
||||
@ -136,13 +117,6 @@ export class StationState extends GraphicStateBase implements IStationState {
|
||||
get states(): state.Rtu {
|
||||
return this.getState<state.Rtu>();
|
||||
}
|
||||
// 集中站站号
|
||||
get rtuId(): number {
|
||||
return this.states.rtuId;
|
||||
}
|
||||
set rtuId(value: number) {
|
||||
this.states.rtuId = value;
|
||||
}
|
||||
clone(): StationState {
|
||||
return new StationState(this.states.cloneMessage());
|
||||
}
|
||||
@ -154,32 +128,32 @@ export class StationState extends GraphicStateBase implements IStationState {
|
||||
}
|
||||
}
|
||||
|
||||
const resetConfig: MenuItemOptions = {
|
||||
name: '重置状态',
|
||||
};
|
||||
const buleShow: MenuItemOptions = {
|
||||
name: '蓝显',
|
||||
};
|
||||
const cancelBuleShow: MenuItemOptions = {
|
||||
name: '取消蓝显',
|
||||
const powerUnlockConfig: MenuItemOptions = {
|
||||
name: '上电解锁',
|
||||
};
|
||||
|
||||
const chainConfig: MenuItemOptions = {
|
||||
name: '全站设置连锁自动触发',
|
||||
};
|
||||
const removeChainConfig: MenuItemOptions = {
|
||||
name: '全站取消连锁自动触发',
|
||||
};
|
||||
const StationOperateMenu: ContextMenu = ContextMenu.init({
|
||||
name: '车站操作菜单',
|
||||
groups: [
|
||||
{
|
||||
items: [resetConfig, buleShow, cancelBuleShow],
|
||||
items: [powerUnlockConfig, chainConfig, removeChainConfig],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export class StationOperateInteraction extends GraphicInteractionPlugin<Station> {
|
||||
static Name = 'station_operate_menu';
|
||||
constructor(app: IGraphicApp) {
|
||||
constructor(app: GraphicApp) {
|
||||
super(StationOperateInteraction.Name, app);
|
||||
app.registerMenu(StationOperateMenu);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
static init(app: GraphicApp) {
|
||||
return new StationOperateInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Station[] | undefined {
|
||||
@ -213,30 +187,34 @@ export class StationOperateInteraction extends GraphicInteractionPlugin<Station>
|
||||
ipRtuStusInEmergencyCtrl: false,
|
||||
id: station.id,
|
||||
};
|
||||
buleShow.handler = () => {
|
||||
const data = {
|
||||
deviceType: 'DEVICE_TYPE_RTU',
|
||||
messageId: 'DEVICE_STATUS_CHANGE',
|
||||
lineId: 3,
|
||||
rtuId: station.states.rtuId,
|
||||
deviceName: station.states.rtuId + '',
|
||||
deviceStatus: 32768,
|
||||
};
|
||||
mockServerApi(data);
|
||||
};
|
||||
cancelBuleShow.handler = () => {
|
||||
const data = {
|
||||
deviceType: 'DEVICE_TYPE_RTU',
|
||||
messageId: 'DEVICE_STATUS_CHANGE',
|
||||
lineId: 3,
|
||||
rtuId: station.states.rtuId,
|
||||
deviceName: station.states.rtuId + '',
|
||||
deviceStatus: 1,
|
||||
};
|
||||
mockServerApi(data);
|
||||
};
|
||||
resetConfig.handler = () => {
|
||||
powerUnlockConfig.handler = () => {
|
||||
/* station.states.ipRtuStusInLocalCtrl = true;
|
||||
station.doRepaint(); */
|
||||
const dataCopy = JSON.parse(JSON.stringify(data));
|
||||
dataCopy.ipRtuStusInLocalCtrl = true;
|
||||
mockStationApi(lineId, dataCopy)
|
||||
.then((res) => {
|
||||
console.log(res, '---res--');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err, '---err---');
|
||||
});
|
||||
};
|
||||
chainConfig.handler = () => {
|
||||
const dataCopy = JSON.parse(JSON.stringify(data));
|
||||
dataCopy.ipRtuStusInLocalCtrl = true;
|
||||
dataCopy.ipRtuStusDown = true;
|
||||
mockStationApi(lineId, dataCopy)
|
||||
.then((res) => {
|
||||
console.log(res, '---res--');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err, '---err---');
|
||||
});
|
||||
};
|
||||
removeChainConfig.handler = () => {
|
||||
const dataCopy = JSON.parse(JSON.stringify(data));
|
||||
dataCopy.ipRtuStusInLocalCtrl = false;
|
||||
mockStationApi(lineId, dataCopy)
|
||||
.then((res) => {
|
||||
console.log(res, '---res--');
|
||||
|
@ -43,12 +43,6 @@ export class StationLineData
|
||||
set hideName(v: boolean) {
|
||||
this.data.hideName = v;
|
||||
}
|
||||
get color(): graphicData.StationLine.stationColor {
|
||||
return this.data.codeColor;
|
||||
}
|
||||
set color(v: graphicData.StationLine.stationColor) {
|
||||
this.data.codeColor = v;
|
||||
}
|
||||
clone(): StationLineData {
|
||||
return new StationLineData(this.data.cloneMessage());
|
||||
}
|
||||
|
@ -4,14 +4,14 @@ import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
|
||||
import { state } from 'src/protos/device_status';
|
||||
import { train } from 'src/protos/train';
|
||||
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
import {
|
||||
IGraphicApp,
|
||||
GraphicApp,
|
||||
GraphicInteractionPlugin,
|
||||
JlGraphic,
|
||||
VectorText,
|
||||
MenuItemOptions,
|
||||
ContextMenu,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic';
|
||||
import {
|
||||
Color,
|
||||
Container,
|
||||
@ -69,11 +69,6 @@ export class TrainState extends GraphicStateBase implements ITrainState {
|
||||
get code(): string {
|
||||
return this.states.groupId;
|
||||
}
|
||||
get remove(): boolean {
|
||||
const rtuIdArr = [81, 82];
|
||||
const hasRtuId = rtuIdArr.includes(this.states.rtuId);
|
||||
return hasRtuId;
|
||||
}
|
||||
|
||||
get states(): train.TrainInfo {
|
||||
return this.getState<train.TrainInfo>();
|
||||
@ -199,12 +194,12 @@ export class TrainState extends GraphicStateBase implements ITrainState {
|
||||
set rate(v: number) {
|
||||
this.states.rate = v;
|
||||
}
|
||||
// get remove(): train.TrainRemove {
|
||||
// return this.states.remove;
|
||||
// }
|
||||
// set remove(v: train.TrainRemove) {
|
||||
// this.states.remove = new train.TrainRemove(v);
|
||||
// }
|
||||
get remove(): train.TrainRemove {
|
||||
return this.states.remove;
|
||||
}
|
||||
set remove(v: train.TrainRemove) {
|
||||
this.states.remove = new train.TrainRemove(v);
|
||||
}
|
||||
get block(): train.TrainBlock {
|
||||
return this.states.block;
|
||||
}
|
||||
@ -274,12 +269,13 @@ const TrainOperateMenu: ContextMenu = ContextMenu.init({
|
||||
export class TrainOperateInteraction extends GraphicInteractionPlugin<Train> {
|
||||
static Name = 'train_operate_menu';
|
||||
hoverLaber: TrainHoverLabel;
|
||||
constructor(app: IGraphicApp) {
|
||||
constructor(app: GraphicApp) {
|
||||
super(TrainOperateInteraction.Name, app);
|
||||
this.hoverLaber = new TrainHoverLabel();
|
||||
app.canvas.addChild(this.hoverLaber);
|
||||
app.registerMenu(TrainOperateMenu);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
static init(app: GraphicApp) {
|
||||
return new TrainOperateInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Train[] | undefined {
|
||||
@ -294,7 +290,7 @@ export class TrainOperateInteraction extends GraphicInteractionPlugin<Train> {
|
||||
this.onMouseHover(g);
|
||||
};
|
||||
g.trainbody.onmouseout = () => {
|
||||
this.onMouseOut(g);
|
||||
this.onMouseOut();
|
||||
};
|
||||
}
|
||||
|
||||
@ -308,15 +304,13 @@ export class TrainOperateInteraction extends GraphicInteractionPlugin<Train> {
|
||||
|
||||
onMouseHover(g: Train): void {
|
||||
if (!this.hoverLaber.isShow) {
|
||||
g.addChild(this.hoverLaber);
|
||||
this.hoverLaber.doRepaint(g.states);
|
||||
const bodyWh = g.trainbody.getBodyWH();
|
||||
this.hoverLaber.position.set(bodyWh.width / 2, bodyWh.height / 2);
|
||||
const bodyWh = g.trainbody.localBoundsToCanvasPoints();
|
||||
this.hoverLaber.position.set(bodyWh[2].x, bodyWh[2].y);
|
||||
}
|
||||
}
|
||||
onMouseOut(g: Train): void {
|
||||
onMouseOut(): void {
|
||||
if (this.hoverLaber.isShow) {
|
||||
g.removeChild(this.hoverLaber);
|
||||
this.hoverLaber.clear();
|
||||
}
|
||||
}
|
||||
@ -436,7 +430,6 @@ const labelConsts = {
|
||||
codeFontSize: 12,
|
||||
};
|
||||
class TrainHoverLabel extends Container {
|
||||
static Type = 'TrainHoverLabel';
|
||||
boxRact: Graphics = new Graphics();
|
||||
sText: VectorText = new VectorText('');
|
||||
isShow: boolean;
|
||||
@ -453,12 +446,7 @@ class TrainHoverLabel extends Container {
|
||||
fill: labelConsts.textColor,
|
||||
fontSize: labelConsts.codeFontSize,
|
||||
};
|
||||
const codeA = states.groupId;
|
||||
// const firstChar = codeA.substring(0, 1); // 获取首字符
|
||||
// if (+firstChar == states.lineId) {
|
||||
// codeA = codeA.substring(1); // 删除首字符是线路号的字符
|
||||
// }
|
||||
const text = `列车类型:计划车\n来 源:人工标记\n车 组 号:${codeA}\n表 号:${states.trainId}\n车 次 号:${states.globalId}\n线 路 号:${states.lineId}`;
|
||||
const text = `列车类型:计划车\n来 源:人工标记\n车 组 号:${states.groupId}\n表 号:${states.trainId}\n车 次 号:${states.globalId}`;
|
||||
this.sText.text = text;
|
||||
this.sText.style = style;
|
||||
const { width: codeWidth, height: codeHeight } =
|
||||
|
@ -31,10 +31,10 @@ export class TrainWindowData
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get refDeviceId(): number[] {
|
||||
get refDeviceId(): string[] {
|
||||
return this.data.refDeviceId;
|
||||
}
|
||||
set refDeviceId(v: number[]) {
|
||||
set refDeviceId(v: string[]) {
|
||||
this.data.refDeviceId = v;
|
||||
}
|
||||
clone(): TrainWindowData {
|
||||
|
@ -10,19 +10,18 @@ import { DisplayObject, FederatedMouseEvent, IPointData } from 'pixi.js';
|
||||
import { KilometerSystem } from 'src/graphics/signal/Signal';
|
||||
import { state } from 'src/protos/device_status';
|
||||
import {
|
||||
IGraphicApp,
|
||||
GraphicApp,
|
||||
GraphicInteractionPlugin,
|
||||
JlGraphic,
|
||||
ContextMenu,
|
||||
MenuItemOptions,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic';
|
||||
import {
|
||||
ForkHitArea,
|
||||
TurnoutSectionHitArea,
|
||||
} from 'src/graphics/turnout/TurnoutDrawAssistant';
|
||||
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||
import { setSwitchStatus } from 'src/api/TurnoutApi';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
import { successNotify } from 'src/utils/CommonNotify';
|
||||
|
||||
let menuItemHandler: (propName: keyof ITurnoutState) => void;
|
||||
|
||||
@ -103,10 +102,7 @@ const ipSingleSwitchStusLostIndication: MenuItemOptions = {
|
||||
name: '道岔失表示-ipSingleSwitchStusLostIndication',
|
||||
handler: () => menuItemHandler('ipSingleSwitchStusLostIndication'),
|
||||
};
|
||||
const speedLimit: MenuItemOptions = {
|
||||
name: '限速 - speedLimit',
|
||||
handler: () => menuItemHandler('speedLimit'),
|
||||
};
|
||||
|
||||
const TurnoutOperateMenu = ContextMenu.init({
|
||||
name: 'Turnout操作菜单',
|
||||
groups: [
|
||||
@ -131,7 +127,6 @@ const TurnoutOperateMenu = ContextMenu.init({
|
||||
ipSingleSwitchStusTsrBmReverse,
|
||||
ipSingleSwitchStusBlocked2,
|
||||
ipSingleSwitchStusLostIndication,
|
||||
speedLimit,
|
||||
],
|
||||
},
|
||||
],
|
||||
@ -139,14 +134,14 @@ const TurnoutOperateMenu = ContextMenu.init({
|
||||
|
||||
export class TurnoutOperationPlugin extends GraphicInteractionPlugin<Turnout> {
|
||||
static Name = 'turnout_operate_menu';
|
||||
constructor(app: IGraphicApp) {
|
||||
constructor(app: GraphicApp) {
|
||||
super(TurnoutOperationPlugin.Name, app);
|
||||
app.registerMenu(TurnoutOperateMenu);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Turnout[] | undefined {
|
||||
return grahpics.filter((g): g is Turnout => g instanceof Turnout);
|
||||
}
|
||||
static init(app: IGraphicApp) {
|
||||
static init(app: GraphicApp) {
|
||||
return new TurnoutOperationPlugin(app);
|
||||
}
|
||||
bind(g: Turnout): void {
|
||||
@ -158,7 +153,6 @@ export class TurnoutOperationPlugin extends GraphicInteractionPlugin<Turnout> {
|
||||
sectionGraphic.cursor = 'pointer';
|
||||
sectionGraphic.hitArea = new TurnoutSectionHitArea(sectionGraphic);
|
||||
});
|
||||
g.on('_leftclick', this.onLeftClick, this);
|
||||
g.on('rightclick', this.onContextMenu, this);
|
||||
}
|
||||
unbind(g: Turnout): void {
|
||||
@ -166,14 +160,8 @@ export class TurnoutOperationPlugin extends GraphicInteractionPlugin<Turnout> {
|
||||
g.graphics.sections.forEach((sectionGraphic) => {
|
||||
sectionGraphic.eventMode = 'none';
|
||||
});
|
||||
g.off('_leftclick', this.onLeftClick, this);
|
||||
g.on('rightclick', this.onContextMenu, this);
|
||||
}
|
||||
onLeftClick(e: FederatedMouseEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const section = target.getGraphic() as Turnout;
|
||||
this.app.updateSelected(section);
|
||||
}
|
||||
onContextMenu(e: FederatedMouseEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const turnout = target.getGraphic() as Turnout;
|
||||
@ -205,7 +193,6 @@ export class TurnoutOperationPlugin extends GraphicInteractionPlugin<Turnout> {
|
||||
ipSingleSwitchStusBlocked2: turnout.states.ipSingleSwitchStusBlocked2, // 道岔封锁
|
||||
ipSingleSwitchStusLostIndication:
|
||||
turnout.states.ipSingleSwitchStusLostIndication, // 道岔失表示
|
||||
speedLimit: turnout.states.speedLimit,
|
||||
};
|
||||
(Object.keys(state) as unknown as (keyof ITurnoutState)[]).forEach(
|
||||
(key: keyof ITurnoutState) => {
|
||||
@ -233,17 +220,10 @@ export class TurnoutOperationPlugin extends GraphicInteractionPlugin<Turnout> {
|
||||
menuItemHandler = (propName) => {
|
||||
const lineId = useLineStore().lineId?.toString();
|
||||
if (!lineId) return;
|
||||
let val: boolean | number;
|
||||
if (propName !== 'speedLimit') {
|
||||
val = !turnout.states[propName];
|
||||
} else {
|
||||
val = turnout.states[propName] > 0 ? 0 : 20;
|
||||
successNotify(`限速设为${val}`);
|
||||
}
|
||||
setSwitchStatus(lineId, {
|
||||
...state,
|
||||
id: turnout.datas.code,
|
||||
[propName]: val,
|
||||
[propName]: !turnout.states[propName],
|
||||
});
|
||||
};
|
||||
TurnoutOperateMenu.open(e.global);
|
||||
@ -321,24 +301,13 @@ export class TurnoutData extends GraphicDataBase implements ITurnoutData {
|
||||
this.data.pcRef = ref;
|
||||
}
|
||||
get kilometerSystem(): KilometerSystem[] {
|
||||
return this.data.kilometerSystem.length > 0
|
||||
? this.data.kilometerSystem
|
||||
: (this.data.kilometerSystem = [
|
||||
new graphicData.KilometerSystem(),
|
||||
new graphicData.KilometerSystem(),
|
||||
]);
|
||||
return this.data.kilometerSystem;
|
||||
}
|
||||
set kilometerSystem(value: KilometerSystem[]) {
|
||||
this.data.kilometerSystem = value.map(
|
||||
(v) => new graphicData.KilometerSystem(v)
|
||||
);
|
||||
}
|
||||
get centralizedStation(): number {
|
||||
return this.data.centralizedStationId;
|
||||
}
|
||||
set centralizedStation(v: number) {
|
||||
this.data.centralizedStationId = v;
|
||||
}
|
||||
clone(): TurnoutData {
|
||||
return new TurnoutData(this.data.cloneMessage());
|
||||
}
|
||||
@ -477,25 +446,8 @@ export class TurnoutStates extends GraphicStateBase implements ITurnoutState {
|
||||
public set ipSingleSwitchStusLostIndication(value: boolean) {
|
||||
this.states.ipSingleSwitchStusLostIndication = value;
|
||||
}
|
||||
public get id(): string {
|
||||
return this.states.id;
|
||||
}
|
||||
public set id(value: string) {
|
||||
this.states.id = value;
|
||||
}
|
||||
// 集中站站号
|
||||
public get rtuId(): number {
|
||||
return this.states.rtuId;
|
||||
}
|
||||
public set rtuId(value: number) {
|
||||
this.states.rtuId = value;
|
||||
}
|
||||
get speedLimit(): number {
|
||||
return this.states.speedLimit;
|
||||
}
|
||||
set speedLimit(val: number) {
|
||||
this.states.speedLimit = val;
|
||||
}
|
||||
id?: string;
|
||||
speedLimit?: number;
|
||||
get states(): state.Switch {
|
||||
return this.getState<state.Switch>();
|
||||
}
|
||||
|
@ -7,14 +7,13 @@ import { Signal, SignalTemplate } from 'src/graphics/signal/Signal';
|
||||
import { SignalDraw } from 'src/graphics/signal/SignalDrawAssistant';
|
||||
import {
|
||||
CombinationKey,
|
||||
GraphicApp,
|
||||
GraphicData,
|
||||
IDrawApp,
|
||||
JlDrawApp,
|
||||
KeyListener,
|
||||
newDrawApp,
|
||||
IGraphicStorage,
|
||||
ContextMenu,
|
||||
MenuItemOptions,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic';
|
||||
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||
import { IscsFanData } from './graphics/IscsFanInteraction';
|
||||
import { LinkData } from './graphics/LinkInteraction';
|
||||
import { TrainData, TrainState } from './graphics/TrainInteraction';
|
||||
@ -24,12 +23,6 @@ import {
|
||||
SignalState,
|
||||
} from './graphics/SignalInteraction';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import {
|
||||
ConcentrationDividingLine,
|
||||
ConcentrationDividingLineTemplate,
|
||||
} from 'src/graphics/concentrationDividingLine/ConcentrationDividingLine';
|
||||
import { ConcentrationDividingLineData } from './graphics/ConcentrationDividingLineInteraction';
|
||||
import { ConcentrationDividingLineDraw } from 'src/graphics/concentrationDividingLine/ConcentrationDividingLineDrawAssistant';
|
||||
import { Rect, RectTemplate } from 'src/graphics/rect/Rect';
|
||||
import { RectDraw } from 'src/graphics/rect/RectDrawAssistant';
|
||||
import { RectData } from './graphics/RectInteraction';
|
||||
@ -127,7 +120,7 @@ import { FederatedMouseEvent } from 'pixi.js';
|
||||
// });
|
||||
// }
|
||||
|
||||
function constructMenu(app: IDrawApp): (e: FederatedMouseEvent) => void {
|
||||
function constructMenu(app: JlDrawApp): (e: FederatedMouseEvent) => void {
|
||||
const UndoOptions: MenuItemOptions = {
|
||||
name: '撤销',
|
||||
};
|
||||
@ -210,9 +203,9 @@ function constructMenu(app: IDrawApp): (e: FederatedMouseEvent) => void {
|
||||
};
|
||||
return handleRightClick;
|
||||
}
|
||||
let drawApp: IDrawApp | null = null;
|
||||
let drawApp: JlDrawApp | null = null;
|
||||
|
||||
export function getDrawApp(): IDrawApp | null {
|
||||
export function getDrawApp(): JlDrawApp | null {
|
||||
return drawApp;
|
||||
}
|
||||
|
||||
@ -223,14 +216,31 @@ export function destroyDrawApp(): void {
|
||||
}
|
||||
}
|
||||
|
||||
export function initDrawApp(): IDrawApp {
|
||||
drawApp = newDrawApp({
|
||||
dataLoader: loadDrawDatas,
|
||||
});
|
||||
export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
drawApp = new JlDrawApp(dom);
|
||||
const app = drawApp;
|
||||
//根据草稿图类型加载绘图工具
|
||||
let drawAssistants: (
|
||||
| PlatformDraw
|
||||
| StationDraw
|
||||
| SignalDraw
|
||||
| TurnoutDraw
|
||||
| RunLineDraw
|
||||
| SectionDraw
|
||||
| LogicSectionDraw
|
||||
| StationLineDraw
|
||||
| RectDraw
|
||||
| TrainLineDraw
|
||||
| PathLineDraw
|
||||
| TrainWindowDraw
|
||||
| TrainDraw
|
||||
| OneClickGenerateDraw
|
||||
| AxleCountingDraw
|
||||
| SeparatorDraw
|
||||
)[] = [];
|
||||
const draftType = useDrawStore().$state.draftType;
|
||||
if (draftType === 'Line') {
|
||||
drawAssistants = [
|
||||
new PlatformDraw(
|
||||
app,
|
||||
new PlatformTemplate(new PlatformData(), new PlatformState())
|
||||
@ -263,14 +273,10 @@ export function initDrawApp(): IDrawApp {
|
||||
new AxleCountingTemplate(new AxleCountingData())
|
||||
),
|
||||
new SeparatorDraw(app, new SeparatorTemplate(new SeparatorData())),
|
||||
new ConcentrationDividingLineDraw(
|
||||
app,
|
||||
new ConcentrationDividingLineTemplate(
|
||||
new ConcentrationDividingLineData()
|
||||
)
|
||||
);
|
||||
];
|
||||
DrawSignalInteraction.init(app);
|
||||
} else {
|
||||
drawAssistants = [
|
||||
new StationLineDraw(app, new StationLineTemplate(new StationLineData())),
|
||||
new RectDraw(app, new RectTemplate(new RectData())),
|
||||
new RunLineDraw(app, new RunLineTemplate(new RunLineData())),
|
||||
@ -279,11 +285,14 @@ export function initDrawApp(): IDrawApp {
|
||||
new ItrainLineTemplate(new TrainLineData(), new TrainLineState())
|
||||
),
|
||||
new PathLineDraw(app, new PathLineTemplate(new PathLineData())),
|
||||
];
|
||||
DrawRunLinePlugin.init(app);
|
||||
}
|
||||
|
||||
app.setOptions({ drawAssistants: drawAssistants });
|
||||
const handleRIghtClick = constructMenu(app);
|
||||
app.canvas.on('_rightclick', (e) => {
|
||||
if (app.drawing) return;
|
||||
if (app._drawing) return;
|
||||
handleRIghtClick(e);
|
||||
});
|
||||
app.addKeyboardListener(
|
||||
@ -299,7 +308,7 @@ export function initDrawApp(): IDrawApp {
|
||||
return drawApp;
|
||||
}
|
||||
|
||||
export function saveDrawToServer(app: IDrawApp) {
|
||||
export function saveDrawToServer(app: JlDrawApp) {
|
||||
const base64 = saveDrawDatas(app);
|
||||
const drawStore = useDrawStore();
|
||||
const id = drawStore.draftId;
|
||||
@ -316,7 +325,7 @@ export function saveDrawToServer(app: IDrawApp) {
|
||||
}
|
||||
|
||||
// const StorageKey = 'graphic-storage';
|
||||
export function saveDrawDatas(app: IDrawApp) {
|
||||
export function saveDrawDatas(app: JlDrawApp) {
|
||||
const storage = new graphicData.RtssGraphicStorage();
|
||||
const canvasData = app.canvas.saveData();
|
||||
storage.canvas = new graphicData.Canvas({
|
||||
@ -376,105 +385,22 @@ export function saveDrawDatas(app: IDrawApp) {
|
||||
} else if (LogicSection.Type === g.type) {
|
||||
const logicSectionData = (g as LogicSection).saveData();
|
||||
storage.logicSections.push((logicSectionData as LogicSectionData).data);
|
||||
} else if (g instanceof ConcentrationDividingLine) {
|
||||
const concentrationDividingLineData = g.saveData();
|
||||
storage.concentrationDividingLines.push(
|
||||
(concentrationDividingLineData as ConcentrationDividingLineData).data
|
||||
);
|
||||
}
|
||||
});
|
||||
// storage.Platforms.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// item.nrefStation = +item.refStation;
|
||||
// item.nrefSectionId = +item.refSectionId;
|
||||
// });
|
||||
// storage.axleCountings.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// item.axleCountingRef = item.axleCountingRef.map((child) => {
|
||||
// child.nid = +child.id;
|
||||
// return child;
|
||||
// });
|
||||
// });
|
||||
// storage.iscsFans.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.links.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.logicSections.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.pathLines.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.polygons.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.rects.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.runLines.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// item.nlinkPathLines = item.linkPathLines.map((child) => +child);
|
||||
// });
|
||||
// storage.section.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// if (item.paRef) {
|
||||
// item.paRef.nid = +item.paRef.id;
|
||||
// }
|
||||
// if (item.pbRef) {
|
||||
// item.pbRef.nid = +item.pbRef.id;
|
||||
// }
|
||||
// item.nchildren = item.children.map((child) => +child);
|
||||
// });
|
||||
// storage.separators.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.signals.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.stationLines.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.stations.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.train.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.trainLines.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// });
|
||||
// storage.trainWindows.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// item.nrefDeviceId = item.refDeviceId.map((child) => +child);
|
||||
// });
|
||||
// storage.turnouts.forEach((item) => {
|
||||
// item.common.nid = +item.common.id;
|
||||
// if (item.paRef) {
|
||||
// item.paRef.nid = +item.paRef.id;
|
||||
// }
|
||||
// if (item.pbRef) {
|
||||
// item.pbRef.nid = +item.pbRef.id;
|
||||
// }
|
||||
// if (item.pcRef) {
|
||||
// item.pcRef.nid = +item.pcRef.id;
|
||||
// }
|
||||
// });
|
||||
const base64 = fromUint8Array(storage.serialize());
|
||||
console.log('保存数据', storage);
|
||||
// localStorage.setItem(StorageKey, base64);
|
||||
return base64;
|
||||
}
|
||||
|
||||
export async function loadDrawDatas(): Promise<IGraphicStorage> {
|
||||
export async function loadDrawDatas(app: GraphicApp) {
|
||||
// localStorage.removeItem(StorageKey);
|
||||
// const base64 = localStorage.getItem(StorageKey);
|
||||
// console.log('加载数据', base64);
|
||||
const drawStore = useDrawStore();
|
||||
const id = drawStore.draftId;
|
||||
if (!id) {
|
||||
throw new Error('获取数据异常:未获取到草稿地图ID');
|
||||
return;
|
||||
}
|
||||
const { proto: base64 } = await getDraft(id);
|
||||
if (base64) {
|
||||
@ -482,6 +408,7 @@ export async function loadDrawDatas(): Promise<IGraphicStorage> {
|
||||
toUint8Array(base64)
|
||||
);
|
||||
console.log('加载数据', storage);
|
||||
app.updateCanvas(storage.canvas);
|
||||
const datas: GraphicData[] = [];
|
||||
storage.links.forEach((link) => {
|
||||
datas.push(new LinkData(link));
|
||||
@ -534,15 +461,8 @@ export async function loadDrawDatas(): Promise<IGraphicStorage> {
|
||||
storage.trainWindows.forEach((trainWindow) => {
|
||||
datas.push(new TrainWindowData(trainWindow));
|
||||
});
|
||||
storage.concentrationDividingLines.forEach((concentrationDividingLine) => {
|
||||
datas.push(new ConcentrationDividingLineData(concentrationDividingLine));
|
||||
});
|
||||
return Promise.resolve({
|
||||
canvasProperty: storage.canvas,
|
||||
datas: datas,
|
||||
});
|
||||
app.loadGraphic(datas);
|
||||
} else {
|
||||
app.loadGraphic([]);
|
||||
}
|
||||
return Promise.resolve({
|
||||
datas: [],
|
||||
});
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {
|
||||
ClientEngine,
|
||||
GraphicApp,
|
||||
GraphicData,
|
||||
StompCli,
|
||||
AppWsMsgBroker,
|
||||
GraphicState,
|
||||
IGraphicApp,
|
||||
IGraphicStorage,
|
||||
newGraphicApp,
|
||||
} from 'jl-graphic';
|
||||
GraphicIdGenerator,
|
||||
} from 'src/jl-graphic';
|
||||
import {
|
||||
TrainData,
|
||||
TrainOperateInteraction,
|
||||
@ -36,10 +36,7 @@ import {
|
||||
TurnoutStates,
|
||||
} from './graphics/TurnoutInteraction';
|
||||
import { Turnout, TurnoutTemplate } from 'src/graphics/turnout/Turnout';
|
||||
import {
|
||||
SectionData,
|
||||
sectionOperationPlugin,
|
||||
} from './graphics/SectionInteraction';
|
||||
import { SectionData } from './graphics/SectionInteraction';
|
||||
import { SectionTemplate } from 'src/graphics/section/Section';
|
||||
import { getPublishMapInfoByLineId } from 'src/api/PublishApi';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
@ -60,7 +57,12 @@ import {
|
||||
import { TrainWindowData } from './graphics/TrainWindowInteraction';
|
||||
import { SeparatorTemplate } from 'src/graphics/separator/Separator';
|
||||
import { SeparatorData } from './graphics/SeparatorInteraction';
|
||||
import { ContextMenu, MenuItemOptions } from 'jl-graphic';
|
||||
|
||||
let lineApp: GraphicApp | null = null;
|
||||
let msgBroker: AppWsMsgBroker | null = null;
|
||||
|
||||
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||
import {
|
||||
LogicSection,
|
||||
LogicSectionTemplate,
|
||||
@ -70,13 +72,21 @@ import {
|
||||
LogicSectionOperationPlugin,
|
||||
LogicSectionState,
|
||||
} from './graphics/LogicSectionInteraction';
|
||||
import { Notify, QNotifyUpdateOptions } from 'quasar';
|
||||
import { useLineNetStore } from 'src/stores/line-net-store';
|
||||
import { alert } from 'src/protos/alertInfo';
|
||||
import { useLineNetStore } from 'src/stores/line-net-store';
|
||||
import { QNotifyUpdateOptions, Notify } from 'quasar';
|
||||
|
||||
let lineApp: IGraphicApp | null = null;
|
||||
// const QuickJumpMenu = new ContextMenu({
|
||||
// name: '快捷跳转',
|
||||
// groups: [
|
||||
// {
|
||||
// items: [],
|
||||
// },
|
||||
// ],
|
||||
// });
|
||||
// let QuickJumpMenu: ContextMenu = new ContextMenu();
|
||||
|
||||
export function getLineApp() {
|
||||
export function getLineApp(): GraphicApp | null {
|
||||
return lineApp;
|
||||
}
|
||||
|
||||
@ -85,29 +95,13 @@ export function destroyLineApp(): void {
|
||||
lineApp.destroy();
|
||||
lineApp = null;
|
||||
}
|
||||
if (msgBroker) {
|
||||
msgBroker.close();
|
||||
}
|
||||
}
|
||||
|
||||
export function initLineApp(): IGraphicApp {
|
||||
if (lineApp) return lineApp;
|
||||
|
||||
lineApp = newGraphicApp({
|
||||
interactiveGraphicTypeIncludes: [
|
||||
Signal.Type,
|
||||
Platform.Type,
|
||||
Station.Type,
|
||||
Train.Type,
|
||||
LogicSection.Type,
|
||||
Turnout.Type,
|
||||
],
|
||||
mouseToolOptions: {
|
||||
boxSelect: false,
|
||||
viewportDrag: true,
|
||||
viewportDragLeft: true,
|
||||
wheelZoom: true,
|
||||
},
|
||||
dataLoader: loadLineDatas,
|
||||
});
|
||||
|
||||
export function initLineApp(dom: HTMLElement): GraphicApp {
|
||||
lineApp = new GraphicApp(dom);
|
||||
const graphicTemplate = [
|
||||
new TrainTemplate(new TrainData(), new TrainState()),
|
||||
new SignalTemplate(new SignalData(), new SignalState()),
|
||||
@ -121,100 +115,67 @@ export function initLineApp(): IGraphicApp {
|
||||
new TrainWindowTemplate(new TrainWindowData()),
|
||||
];
|
||||
lineApp.registerGraphicTemplates(...graphicTemplate);
|
||||
lineApp.setOptions({
|
||||
mouseToolOptions: {
|
||||
boxSelect: false,
|
||||
viewportDrag: true,
|
||||
wheelZoom: true,
|
||||
},
|
||||
interactiveTypeOptions: {
|
||||
interactiveGraphicTypeIncludes: [
|
||||
Signal.Type,
|
||||
Platform.Type,
|
||||
Station.Type,
|
||||
Train.Type,
|
||||
LogicSection.Type,
|
||||
Turnout.Type,
|
||||
],
|
||||
},
|
||||
});
|
||||
SignalOperateInteraction.init(lineApp);
|
||||
PlatformOperateInteraction.init(lineApp);
|
||||
StationOperateInteraction.init(lineApp);
|
||||
TrainOperateInteraction.init(lineApp);
|
||||
TurnoutOperationPlugin.init(lineApp);
|
||||
LogicSectionOperationPlugin.init(lineApp);
|
||||
sectionOperationPlugin.init(lineApp);
|
||||
|
||||
lineApp.enableWsMassaging({
|
||||
engine: ClientEngine.Stomp,
|
||||
wsUrl: getWebsocketUrl(),
|
||||
token: getJwtToken() as string,
|
||||
});
|
||||
|
||||
let msgNotify: null | ((props?: QNotifyUpdateOptions | undefined) => void) =
|
||||
null;
|
||||
lineApp.on('websocket-connect-state-change', (connected) => {
|
||||
if (!connected && !msgNotify) {
|
||||
msgNotify = Notify.create({
|
||||
type: 'negative',
|
||||
timeout: 0,
|
||||
position: 'top-right',
|
||||
message: '与WebSocket服务连接断开!',
|
||||
classes: 'my-notif-class',
|
||||
});
|
||||
} else if (msgNotify && connected) {
|
||||
msgNotify();
|
||||
msgNotify = null;
|
||||
}
|
||||
});
|
||||
|
||||
lineApp.reload().then(() => {
|
||||
if (!lineApp) return;
|
||||
const quickJumpMenu = new ContextMenu({
|
||||
name: '快捷跳转',
|
||||
groups: [
|
||||
{
|
||||
items: lineApp.queryStore
|
||||
.queryByType<Station>(Station.Type)
|
||||
.map<MenuItemOptions>((station) => ({
|
||||
name: station.datas.name ?? '',
|
||||
handler: () => {
|
||||
lineApp?.makeGraphicCenterShow(station);
|
||||
},
|
||||
})),
|
||||
},
|
||||
],
|
||||
});
|
||||
lineApp.registerMenu(quickJumpMenu);
|
||||
lineApp.canvas.on('_rightclick', (e) => {
|
||||
quickJumpMenu.open(e.global);
|
||||
});
|
||||
|
||||
const axleCountings = lineApp.queryStore.queryByType<AxleCounting>(
|
||||
AxleCounting.Type
|
||||
);
|
||||
axleCountings.forEach((axleCounting) => {
|
||||
axleCounting.visible = false;
|
||||
});
|
||||
const trainWindows = lineApp.queryStore.queryByType<TrainWindow>(
|
||||
TrainWindow.Type
|
||||
);
|
||||
trainWindows.forEach((trainWindow) => {
|
||||
trainWindow.visible = false;
|
||||
});
|
||||
handleSubscribe(lineApp);
|
||||
});
|
||||
|
||||
return lineApp;
|
||||
}
|
||||
|
||||
export async function loadLineDatas(): Promise<IGraphicStorage> {
|
||||
export async function loadLineDatas(app: GraphicApp) {
|
||||
const lineStore = useLineStore();
|
||||
const lineId = lineStore.lineId;
|
||||
if (!lineId) {
|
||||
throw Error('请先选择线路');
|
||||
return;
|
||||
}
|
||||
const { proto: base64, name: lineName } = await getPublishMapInfoByLineId(
|
||||
lineId,
|
||||
'line'
|
||||
);
|
||||
lineStore.setLineName(lineName);
|
||||
const datas: GraphicData[] = [];
|
||||
if (base64) {
|
||||
const storage = graphicData.RtssGraphicStorage.deserialize(
|
||||
toUint8Array(base64)
|
||||
);
|
||||
console.log('加载数据', storage);
|
||||
app.updateCanvas(storage.canvas);
|
||||
const datas: GraphicData[] = [];
|
||||
storage.Platforms.forEach((platform) => {
|
||||
const g = new PlatformData(platform);
|
||||
datas.push(g);
|
||||
});
|
||||
const quickJumpMenuItem: MenuItemOptions[] = [];
|
||||
storage.stations.forEach((station) => {
|
||||
datas.push(new StationData(station));
|
||||
const item: MenuItemOptions = {
|
||||
name: station.name,
|
||||
handler: () => {
|
||||
const g = app.queryStore.queryById(station.common.id);
|
||||
if (g) {
|
||||
app.makeGraphicCenterShow(g);
|
||||
}
|
||||
},
|
||||
};
|
||||
quickJumpMenuItem.push(item);
|
||||
});
|
||||
storage.train.forEach((train) => {
|
||||
datas.push(new TrainData(train));
|
||||
@ -240,75 +201,97 @@ export async function loadLineDatas(): Promise<IGraphicStorage> {
|
||||
storage.trainWindows.forEach((trainWindow) => {
|
||||
datas.push(new TrainWindowData(trainWindow));
|
||||
});
|
||||
return Promise.resolve({
|
||||
canvasProperty: storage.canvas,
|
||||
datas: datas,
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve({
|
||||
datas: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
await app.loadGraphic(datas);
|
||||
|
||||
function handleSubscribe(lineApp: IGraphicApp) {
|
||||
const lineStore = useLineStore();
|
||||
const lineId = lineStore.lineId;
|
||||
lineApp.subscribe({
|
||||
//隐藏计轴--和车次窗
|
||||
const axleCountings = app.queryStore.queryByType<AxleCounting>(
|
||||
AxleCounting.Type
|
||||
);
|
||||
axleCountings.forEach((axleCounting) => {
|
||||
axleCounting.visible = false;
|
||||
});
|
||||
const trainWindows = app.queryStore.queryByType<TrainWindow>(
|
||||
TrainWindow.Type
|
||||
);
|
||||
trainWindows.forEach((trainWindow) => {
|
||||
trainWindow.visible = false;
|
||||
});
|
||||
const QuickJumpMenu = new ContextMenu({
|
||||
name: '快捷跳转',
|
||||
groups: [
|
||||
{
|
||||
items: quickJumpMenuItem,
|
||||
},
|
||||
],
|
||||
});
|
||||
app.registerMenu(QuickJumpMenu);
|
||||
app.canvas.on('_rightclick', (e) => {
|
||||
QuickJumpMenu.open(e.global);
|
||||
});
|
||||
|
||||
StompCli.new({
|
||||
wsUrl: `${getWebsocketUrl()}`,
|
||||
token: getJwtToken() as string,
|
||||
});
|
||||
msgBroker = new AppWsMsgBroker(app);
|
||||
msgBroker.subscribe({
|
||||
destination: `/queue/line/${lineId}/device`,
|
||||
messageConverter: (message: Uint8Array) => {
|
||||
const states: GraphicState[] = [];
|
||||
const storage = state.WsLineMessage.deserialize(message);
|
||||
storage.signal.forEach((item) => {
|
||||
if (item.rtuId !== 81 && item.rtuId !== 82 && item.rtuId) {
|
||||
states.push(new SignalState(item));
|
||||
}
|
||||
});
|
||||
storage.platform.forEach((item) => {
|
||||
if (item.rtuId !== 81 && item.rtuId !== 82 && item.rtuId) {
|
||||
states.push(new PlatformState(item));
|
||||
}
|
||||
});
|
||||
storage.rtu.forEach((item) => {
|
||||
if (item.rtuId !== 81 && item.rtuId !== 82 && item.rtuId) {
|
||||
states.push(new StationState(item));
|
||||
}
|
||||
});
|
||||
storage.switch.forEach((item) => {
|
||||
if (item.rtuId !== 81 && item.rtuId !== 82 && item.rtuId) {
|
||||
states.push(new TurnoutStates(item));
|
||||
}
|
||||
});
|
||||
storage.track.forEach((item) => {
|
||||
if (item.rtuId !== 81 && item.rtuId !== 82 && item.rtuId) {
|
||||
states.push(new LogicSectionState(item));
|
||||
}
|
||||
});
|
||||
return states;
|
||||
},
|
||||
});
|
||||
lineApp.subscribe({
|
||||
msgBroker.subscribe({
|
||||
destination: `/queue/line/${lineId}/train`,
|
||||
createOnNotFound: { graphicTypes: [Train.Type] },
|
||||
messageConverter: (message: Uint8Array) => {
|
||||
const states: GraphicState[] = [];
|
||||
const trainStorage = state.WsLineTrainMessage.deserialize(message);
|
||||
// console.log(trainStorage, '222');
|
||||
trainStorage.trainInfo.forEach((item) => {
|
||||
// if (item.rtuId !== 81 && item.rtuId !== 82 && item.rtuId) {
|
||||
if (item.rtuId) {
|
||||
states.push(new TrainState(item));
|
||||
}
|
||||
});
|
||||
return states;
|
||||
},
|
||||
});
|
||||
let msgNotify: null | ((props?: QNotifyUpdateOptions | undefined) => void) =
|
||||
null;
|
||||
app.on('websocket-connect-state-change', (connected) => {
|
||||
if (!connected && !msgNotify) {
|
||||
msgNotify = Notify.create({
|
||||
type: 'negative',
|
||||
timeout: 0,
|
||||
position: 'top-right',
|
||||
message: '通信链接已断开!',
|
||||
});
|
||||
} else if (msgNotify && connected) {
|
||||
msgNotify();
|
||||
msgNotify = null;
|
||||
}
|
||||
});
|
||||
const lineNetStore = useLineNetStore();
|
||||
lineApp.subscribe({
|
||||
msgBroker.subscribe({
|
||||
destination: '/queue/xian/ncc/alert',
|
||||
messageHandle: (message: Uint8Array) => {
|
||||
const storage = alert.NccAlertInfoMessage.deserialize(message);
|
||||
lineNetStore.setAlarmInfo(storage.messages as []);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
app.loadGraphic([]);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import {
|
||||
IGraphicApp,
|
||||
GraphicApp,
|
||||
GraphicData,
|
||||
StompCli,
|
||||
AppWsMsgBroker,
|
||||
GraphicState,
|
||||
newGraphicApp,
|
||||
IGraphicStorage,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic';
|
||||
import { getPublishLineNet } from 'src/api/PublishApi';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { state } from 'src/protos/ws_message';
|
||||
@ -34,11 +34,12 @@ import { toUint8Array } from 'js-base64';
|
||||
import { getWebsocketUrl } from 'src/configs/UrlManage';
|
||||
import { getJwtToken } from 'src/configs/TokenManage';
|
||||
import { alert } from 'src/protos/alertInfo';
|
||||
import { Notify } from 'quasar';
|
||||
import { QNotifyUpdateOptions, Notify } from 'quasar';
|
||||
|
||||
let lineNetApp: IGraphicApp | null = null;
|
||||
let lineNetApp: GraphicApp | null = null;
|
||||
let msgBroker: AppWsMsgBroker | null = null;
|
||||
|
||||
export function getLineNetApp(): IGraphicApp | null {
|
||||
export function getLineNetApp(): GraphicApp | null {
|
||||
return lineNetApp;
|
||||
}
|
||||
|
||||
@ -47,23 +48,13 @@ export function destroyLineNetApp(): void {
|
||||
lineNetApp.destroy();
|
||||
lineNetApp = null;
|
||||
}
|
||||
if (msgBroker) {
|
||||
msgBroker.close();
|
||||
}
|
||||
}
|
||||
|
||||
export function initLineNetApp(): IGraphicApp {
|
||||
lineNetApp = newGraphicApp({
|
||||
interactiveGraphicTypeIncludes: [
|
||||
RunLine.Type,
|
||||
StationLine.Type,
|
||||
TrainLine.Type,
|
||||
],
|
||||
mouseToolOptions: {
|
||||
boxSelect: false,
|
||||
viewportDrag: true,
|
||||
viewportDragLeft: true,
|
||||
wheelZoom: true,
|
||||
},
|
||||
dataLoader: loadLineNetDatas,
|
||||
});
|
||||
export function initLineNetApp(dom: HTMLElement): GraphicApp {
|
||||
lineNetApp = new GraphicApp(dom);
|
||||
const graphicTemplate = [
|
||||
new RunLineTemplate(new RunLineData()),
|
||||
new PathLineTemplate(new PathLineData()),
|
||||
@ -71,47 +62,36 @@ export function initLineNetApp(): IGraphicApp {
|
||||
new ItrainLineTemplate(new TrainLineData(), new TrainLineState()),
|
||||
new RectTemplate(new RectData()),
|
||||
];
|
||||
lineNetApp.reload().then(() => {
|
||||
if (!lineNetApp) return;
|
||||
const pathLineList = lineNetApp.queryStore.queryByType(PathLine.Type);
|
||||
pathLineList.forEach((pathLine) => {
|
||||
pathLine.visible = false;
|
||||
});
|
||||
handleSubscribe(lineNetApp);
|
||||
});
|
||||
|
||||
lineNetApp.registerGraphicTemplates(...graphicTemplate);
|
||||
|
||||
lineNetApp.setOptions({
|
||||
mouseToolOptions: {
|
||||
boxSelect: false,
|
||||
viewportDrag: true,
|
||||
wheelZoom: true,
|
||||
},
|
||||
interactiveTypeOptions: {
|
||||
interactiveGraphicTypeIncludes: [
|
||||
RunLine.Type,
|
||||
StationLine.Type,
|
||||
TrainLine.Type,
|
||||
],
|
||||
},
|
||||
});
|
||||
RunLineOperateInteraction.init(lineNetApp);
|
||||
|
||||
let msgNotify: ReturnType<Notify['create']> | null = null;
|
||||
lineNetApp.on('websocket-connect-state-change', (connected) => {
|
||||
if (!connected && !msgNotify) {
|
||||
msgNotify = Notify.create({
|
||||
type: 'negative',
|
||||
timeout: 0,
|
||||
position: 'top-right',
|
||||
message: '与WebSocket服务连接断开!',
|
||||
classes: 'my-notif-class',
|
||||
});
|
||||
} else if (msgNotify && connected) {
|
||||
msgNotify();
|
||||
msgNotify = null;
|
||||
}
|
||||
});
|
||||
return lineNetApp;
|
||||
}
|
||||
|
||||
export async function loadLineNetDatas(): Promise<IGraphicStorage> {
|
||||
export async function loadLineNetDatas(app: GraphicApp) {
|
||||
const lineNetStore = useLineNetStore();
|
||||
const { proto: base64, name: lineNetName } = await getPublishLineNet();
|
||||
lineNetStore.setLineNetName(lineNetName);
|
||||
const datas: GraphicData[] = [];
|
||||
if (base64) {
|
||||
const storage = graphicData.RtssGraphicStorage.deserialize(
|
||||
toUint8Array(base64)
|
||||
);
|
||||
console.log('加载数据', storage);
|
||||
app.updateCanvas(storage.canvas);
|
||||
const datas: GraphicData[] = [];
|
||||
storage.runLines.forEach((runLine) => {
|
||||
const g = new RunLineData(runLine);
|
||||
datas.push(g);
|
||||
@ -132,26 +112,18 @@ export async function loadLineNetDatas(): Promise<IGraphicStorage> {
|
||||
const g = new RectData(rect);
|
||||
datas.push(g);
|
||||
});
|
||||
return Promise.resolve({
|
||||
canvasProperty: storage.canvas,
|
||||
datas: datas,
|
||||
await app.loadGraphic(datas);
|
||||
const pathLineList = app.queryStore.queryByType(PathLine.Type);
|
||||
pathLineList.forEach((pathLine) => {
|
||||
pathLine.visible = false;
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve({
|
||||
datas: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function handleSubscribe(lineNetApp: IGraphicApp) {
|
||||
const lineNetStore = useLineNetStore();
|
||||
lineNetApp.enableWsMassaging({
|
||||
StompCli.new({
|
||||
wsUrl: `${getWebsocketUrl()}`,
|
||||
token: getJwtToken() as string,
|
||||
});
|
||||
lineNetApp.subscribe({
|
||||
msgBroker = new AppWsMsgBroker(app);
|
||||
msgBroker.subscribe({
|
||||
destination: '/queue/lineNet',
|
||||
createOnNotFound: { graphicTypes: [TrainLine.Type] },
|
||||
messageConverter: (message: Uint8Array) => {
|
||||
const storage = state.WsLineNetMessage.deserialize(message);
|
||||
const states: GraphicState[] = [];
|
||||
@ -161,11 +133,29 @@ function handleSubscribe(lineNetApp: IGraphicApp) {
|
||||
return states;
|
||||
},
|
||||
});
|
||||
lineNetApp.subscribe({
|
||||
msgBroker.subscribe({
|
||||
destination: '/queue/xian/ncc/alert',
|
||||
messageHandle: (message: Uint8Array) => {
|
||||
const storage = alert.NccAlertInfoMessage.deserialize(message);
|
||||
lineNetStore.setAlarmInfo(storage.messages as []);
|
||||
},
|
||||
});
|
||||
let msgNotify: null | ((props?: QNotifyUpdateOptions | undefined) => void) =
|
||||
null;
|
||||
app.on('websocket-connect-state-change', (connected) => {
|
||||
if (!connected && !msgNotify) {
|
||||
msgNotify = Notify.create({
|
||||
type: 'negative',
|
||||
timeout: 0,
|
||||
position: 'top-right',
|
||||
message: '通信链接已断开!',
|
||||
});
|
||||
} else if (msgNotify && connected) {
|
||||
msgNotify();
|
||||
msgNotify = null;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
app.loadGraphic([]);
|
||||
}
|
||||
}
|
||||
|
@ -1,210 +0,0 @@
|
||||
import {
|
||||
LogicSection,
|
||||
LogicSectionTemplate,
|
||||
} from 'src/graphics/logicSection/LogicSection';
|
||||
import { Platform, PlatformTemplate } from 'src/graphics/platform/Platform';
|
||||
import { SectionTemplate } from 'src/graphics/section/Section';
|
||||
import { Signal, SignalTemplate } from 'src/graphics/signal/Signal';
|
||||
import { Station, StationTemplate } from 'src/graphics/station/Station';
|
||||
import { Turnout, TurnoutTemplate } from 'src/graphics/turnout/Turnout';
|
||||
import {
|
||||
IGraphicApp,
|
||||
GraphicData,
|
||||
newGraphicApp,
|
||||
MenuItemOptions,
|
||||
ContextMenu,
|
||||
IGraphicStorage,
|
||||
} from 'jl-graphic';
|
||||
import {
|
||||
LogicSectionData,
|
||||
LogicSectionState,
|
||||
} from './graphics/LogicSectionInteraction';
|
||||
import { SeparatorTemplate } from 'src/graphics/separator/Separator';
|
||||
import { AxleCountingTemplate } from 'src/graphics/axleCounting/AxleCounting';
|
||||
import { SignalData, SignalState } from './graphics/SignalInteraction';
|
||||
import { PlatformData, PlatformState } from './graphics/PlatformInteraction';
|
||||
import { StationData, StationState } from './graphics/StationInteraction';
|
||||
import { TurnoutData, TurnoutStates } from './graphics/TurnoutInteraction';
|
||||
import { SectionData } from './graphics/SectionInteraction';
|
||||
import { SeparatorData } from './graphics/SeparatorInteraction';
|
||||
import { AxleCountingData } from './graphics/AxleCountingInteraction';
|
||||
import { getPublishMapInfoByLineId } from 'src/api/PublishApi';
|
||||
import { useRangeConfigStore } from 'src/stores/range-config-store';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { toUint8Array } from 'js-base64';
|
||||
|
||||
let rangeConfigApp: IGraphicApp;
|
||||
|
||||
export function getRangeConfigApp() {
|
||||
return rangeConfigApp;
|
||||
}
|
||||
|
||||
export function initRangeConfigApp(lineId: number) {
|
||||
rangeConfigApp = newGraphicApp({
|
||||
mouseToolOptions: {
|
||||
boxSelect: true,
|
||||
viewportDrag: true,
|
||||
wheelZoom: true,
|
||||
},
|
||||
interactiveGraphicTypeIncludes: [
|
||||
Signal.Type,
|
||||
Platform.Type,
|
||||
Station.Type,
|
||||
LogicSection.Type,
|
||||
Turnout.Type,
|
||||
],
|
||||
dataLoader: () => loadRangeConfigDatas(lineId),
|
||||
});
|
||||
const graphicTemplate = [
|
||||
new SignalTemplate(new SignalData(), new SignalState()),
|
||||
new PlatformTemplate(new PlatformData(), new PlatformState()),
|
||||
new StationTemplate(new StationData(), new StationState()),
|
||||
new TurnoutTemplate(new TurnoutData(), new TurnoutStates()),
|
||||
new SectionTemplate(new SectionData()),
|
||||
new LogicSectionTemplate(new LogicSectionData(), new LogicSectionState()),
|
||||
new SeparatorTemplate(new SeparatorData()),
|
||||
new AxleCountingTemplate(new AxleCountingData()),
|
||||
];
|
||||
rangeConfigApp.registerGraphicTemplates(...graphicTemplate);
|
||||
|
||||
rangeConfigApp.reload().then(() => {
|
||||
const QuickJumpMenu = new ContextMenu({
|
||||
name: '快捷跳转',
|
||||
groups: [
|
||||
{
|
||||
items: rangeConfigApp.queryStore
|
||||
.queryByType<Station>(Station.Type)
|
||||
.map<MenuItemOptions>((station) => ({
|
||||
name: station.datas.name ?? '',
|
||||
handler: () => {
|
||||
rangeConfigApp?.makeGraphicCenterShow(station);
|
||||
},
|
||||
})),
|
||||
},
|
||||
],
|
||||
});
|
||||
rangeConfigApp.registerMenu(QuickJumpMenu);
|
||||
rangeConfigApp.canvas.on('_rightclick', (e) => {
|
||||
QuickJumpMenu.open(e.global);
|
||||
});
|
||||
});
|
||||
|
||||
return rangeConfigApp;
|
||||
}
|
||||
|
||||
export async function loadRangeConfigDatas(
|
||||
lineId: number
|
||||
): Promise<IGraphicStorage> {
|
||||
if (!lineId) throw Error('请先选择线路');
|
||||
const store = useRangeConfigStore();
|
||||
|
||||
const { proto: base64, name: lineName } = await getPublishMapInfoByLineId(
|
||||
lineId,
|
||||
'line'
|
||||
);
|
||||
store.setLineName(lineName);
|
||||
const datas: GraphicData[] = [];
|
||||
if (base64) {
|
||||
const storage = graphicData.RtssGraphicStorage.deserialize(
|
||||
toUint8Array(base64)
|
||||
);
|
||||
console.log('加载数据', storage);
|
||||
storage.Platforms.forEach((platform) => {
|
||||
datas.push(new PlatformData(platform));
|
||||
});
|
||||
storage.stations.forEach((station) => {
|
||||
datas.push(new StationData(station));
|
||||
});
|
||||
storage.turnouts.forEach((turnout) => {
|
||||
datas.push(new TurnoutData(turnout));
|
||||
});
|
||||
storage.section.forEach((section) => {
|
||||
datas.push(new SectionData(section));
|
||||
});
|
||||
storage.logicSections.forEach((section) => {
|
||||
datas.push(new LogicSectionData(section));
|
||||
});
|
||||
storage.separators.forEach((separator) => {
|
||||
datas.push(new SeparatorData(separator));
|
||||
});
|
||||
storage.axleCountings.forEach((axleCounting) => {
|
||||
datas.push(new AxleCountingData(axleCounting));
|
||||
});
|
||||
return Promise.resolve({
|
||||
canvasProperty: storage.canvas,
|
||||
datas: datas,
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve({
|
||||
datas: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadLineDatas(app: IGraphicApp) {
|
||||
const store = useRangeConfigStore();
|
||||
const lineId = store.lineId;
|
||||
if (!lineId) return;
|
||||
|
||||
const { proto: base64, name: lineName } = await getPublishMapInfoByLineId(
|
||||
lineId,
|
||||
'line'
|
||||
);
|
||||
store.setLineName(lineName);
|
||||
if (base64) {
|
||||
const storage = graphicData.RtssGraphicStorage.deserialize(
|
||||
toUint8Array(base64)
|
||||
);
|
||||
const datas: GraphicData[] = [];
|
||||
storage.Platforms.forEach((platform) => {
|
||||
const g = new PlatformData(platform);
|
||||
datas.push(g);
|
||||
});
|
||||
const quickJumpMenuItem: MenuItemOptions[] = [];
|
||||
storage.stations.forEach((station) => {
|
||||
datas.push(new StationData(station));
|
||||
const item: MenuItemOptions = {
|
||||
name: station.name,
|
||||
handler: () => {
|
||||
const g = app.queryStore.queryById(station.common.id);
|
||||
if (g) {
|
||||
app.makeGraphicCenterShow(g);
|
||||
}
|
||||
},
|
||||
};
|
||||
quickJumpMenuItem.push(item);
|
||||
});
|
||||
storage.turnouts.forEach((turnout) => {
|
||||
datas.push(new TurnoutData(turnout));
|
||||
});
|
||||
storage.section.forEach((section) => {
|
||||
datas.push(new SectionData(section));
|
||||
});
|
||||
storage.logicSections.forEach((section) => {
|
||||
datas.push(new LogicSectionData(section));
|
||||
});
|
||||
storage.separators.forEach((separator) => {
|
||||
datas.push(new SeparatorData(separator));
|
||||
});
|
||||
storage.axleCountings.forEach((axleCounting) => {
|
||||
datas.push(new AxleCountingData(axleCounting));
|
||||
});
|
||||
const QuickJumpMenu = new ContextMenu({
|
||||
name: '快捷跳转',
|
||||
groups: [
|
||||
{
|
||||
items: quickJumpMenuItem,
|
||||
},
|
||||
],
|
||||
});
|
||||
app.registerMenu(QuickJumpMenu);
|
||||
app.canvas.on('_rightclick', (e) => {
|
||||
QuickJumpMenu.open(e.global);
|
||||
});
|
||||
}
|
||||
}
|
||||
export function destroyRangeConfigApp(): void {
|
||||
if (rangeConfigApp) {
|
||||
rangeConfigApp.destroy();
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { Graphics } from 'pixi.js';
|
||||
import { calculateMirrorPoint } from 'jl-graphic';
|
||||
import { calculateMirrorPoint } from 'src/jl-graphic';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { Turnout, TurnoutPort } from './turnout/Turnout';
|
||||
import { Section, SectionPort } from './section/Section';
|
||||
@ -77,7 +77,7 @@ export function drawArrow(
|
||||
|
||||
export function createRelatedRefProto(
|
||||
type: string,
|
||||
id: number,
|
||||
id: string,
|
||||
port?: TurnoutPort | SectionPort
|
||||
) {
|
||||
const typeMap = new Map([
|
||||
@ -111,6 +111,6 @@ export function protoPort2Data(port: graphicData.RelatedRef.DevicePort) {
|
||||
|
||||
export interface IRelatedRefData {
|
||||
deviceType: graphicData.RelatedRef.DeviceType; //关联的设备类型
|
||||
id: number; //关联的设备ID
|
||||
id: string; //关联的设备ID
|
||||
devicePort: graphicData.RelatedRef.DevicePort; //关联的设备端口
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
VectorText,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic';
|
||||
import { IRelatedRefData, protoPort2Data } from '../CommonGraphics';
|
||||
import { KilometerSystem } from '../signal/Signal';
|
||||
|
||||
|
@ -5,10 +5,10 @@ import {
|
||||
GraphicDrawAssistant,
|
||||
GraphicIdGenerator,
|
||||
GraphicInteractionPlugin,
|
||||
IDrawApp,
|
||||
JlDrawApp,
|
||||
JlGraphic,
|
||||
distance2,
|
||||
} from 'jl-graphic';
|
||||
} from 'src/jl-graphic';
|
||||
|
||||
import {
|
||||
IAxleCountingData,
|
||||
@ -16,7 +16,7 @@ import {
|
||||
AxleCountingTemplate,
|
||||
AxleCountingConsts,
|
||||
} from './AxleCounting';
|
||||
import { Section, SectionPort } from '../section/Section';
|
||||
import { Section, SectionPort, SectionType } from '../section/Section';
|
||||
import { Turnout, TurnoutPort } from '../turnout/Turnout';
|
||||
import { IRelatedRefData, createRelatedRefProto } from '../CommonGraphics';
|
||||
import { Signal } from '../signal/Signal';
|
||||
@ -42,8 +42,8 @@ export class AxleCountingDraw extends GraphicDrawAssistant<
|
||||
IAxleCountingData
|
||||
> {
|
||||
codeGraph: AxleCounting;
|
||||
constructor(app: IDrawApp, template: AxleCountingTemplate) {
|
||||
super(app, template, 'sym_o_circle', '计轴');
|
||||
constructor(app: JlDrawApp, template: AxleCountingTemplate) {
|
||||
super(app, template, 'sym_o_circle', '不展示');
|
||||
this.codeGraph = this.graphicTemplate.new();
|
||||
this.container.addChild(this.codeGraph);
|
||||
AxleCountingInteraction.init(app);
|
||||
@ -198,6 +198,12 @@ export class AxleCountingDraw extends GraphicDrawAssistant<
|
||||
if (axleCountingPs.y > height.y) {
|
||||
direction = -1;
|
||||
}
|
||||
if (
|
||||
section.datas.sectionType === SectionType.Logic ||
|
||||
section.datas.children.includes(refDevice.id)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (refDevice.type == Section.Type || refDevice.type == Turnout.Type)
|
||||
this.draw(
|
||||
axleCountingPs,
|
||||
@ -346,10 +352,10 @@ function buildAbsorbablePositions(
|
||||
|
||||
export class AxleCountingInteraction extends GraphicInteractionPlugin<AxleCounting> {
|
||||
static Name = 'AxleCounting_transform';
|
||||
constructor(app: IDrawApp) {
|
||||
constructor(app: JlDrawApp) {
|
||||
super(AxleCountingInteraction.Name, app);
|
||||
}
|
||||
static init(app: IDrawApp) {
|
||||
static init(app: JlDrawApp) {
|
||||
return new AxleCountingInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): AxleCounting[] | undefined {
|
||||
|
@ -1,224 +0,0 @@
|
||||
import { IPointData } from 'pixi.js';
|
||||
import {
|
||||
GraphicData,
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
calculateDistanceFromPointToLine,
|
||||
getRectangleCenter,
|
||||
ILineGraphic,
|
||||
} from 'jl-graphic';
|
||||
import { SectionGraphic } from './SectionGraphic';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { Section, SectionType } from '../section/Section';
|
||||
import { arePolylinesIntersect } from './ConcentrationDividingLineUtils';
|
||||
import { createRelatedRefProto } from '../CommonGraphics';
|
||||
import { Turnout,TurnoutPort } from '../turnout/Turnout';
|
||||
|
||||
export interface IConcentrationDividingLineData extends GraphicData {
|
||||
get code(): string; // 编号
|
||||
set code(v: string);
|
||||
get points(): IPointData[]; // 线坐标点
|
||||
set points(points: IPointData[]);
|
||||
get refLeftStationId(): number; //左边关联的集中站id
|
||||
set refLeftStationId(v: number);
|
||||
get refRightStationId(): number; //右边关联的集中站id
|
||||
set refRightStationId(v: number);
|
||||
get nodeConWithSecs(): graphicData.NodeConWithSec[]; // 集中区分割线与区段的交点
|
||||
set nodeConWithSecs(nodes: graphicData.NodeConWithSec[]);
|
||||
get isOtherLineConcentrationDividingLine(): boolean; //集中区分割线绘制在其它线的边界处
|
||||
set isOtherLineConcentrationDividingLine(v: boolean);
|
||||
clone(): IConcentrationDividingLineData;
|
||||
copyFrom(data: IConcentrationDividingLineData): void;
|
||||
eq(other: IConcentrationDividingLineData): boolean;
|
||||
}
|
||||
|
||||
export const ConcentrationDividingLineConsts = {
|
||||
lineColor: '#f00',
|
||||
lineWidth: 2,
|
||||
};
|
||||
|
||||
enum devicePort {
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
}
|
||||
|
||||
export class ConcentrationDividingLine
|
||||
extends JlGraphic
|
||||
implements ILineGraphic
|
||||
{
|
||||
static Type = 'ConcentrationDividingLine';
|
||||
lineGraphic: SectionGraphic;
|
||||
|
||||
constructor() {
|
||||
super(ConcentrationDividingLine.Type);
|
||||
this.lineGraphic = new SectionGraphic();
|
||||
this.transformSave = true;
|
||||
this.addChild(this.lineGraphic);
|
||||
}
|
||||
|
||||
get datas(): IConcentrationDividingLineData {
|
||||
return this.getDatas<IConcentrationDividingLineData>();
|
||||
}
|
||||
|
||||
get linePoints(): IPointData[] {
|
||||
return this.datas.points;
|
||||
}
|
||||
set linePoints(points: IPointData[]) {
|
||||
const old = this.datas.clone();
|
||||
old.points = points;
|
||||
this.updateData(old);
|
||||
}
|
||||
|
||||
doRepaint() {
|
||||
if (this.datas.points.length < 2) {
|
||||
throw new Error('Link坐标数据异常');
|
||||
}
|
||||
this.lineGraphic.clear();
|
||||
this.lineGraphic.points = this.datas.points;
|
||||
this.lineGraphic.lineStyle(
|
||||
ConcentrationDividingLineConsts.lineWidth,
|
||||
ConcentrationDividingLineConsts.lineColor
|
||||
);
|
||||
this.lineGraphic.paint();
|
||||
}
|
||||
buildRelation() {
|
||||
const nodeConWithSecs: graphicData.NodeConWithSec[] = [];
|
||||
const sections = this.queryStore
|
||||
.queryByType<Section>(Section.Type)
|
||||
.filter((g) => g.datas.sectionType == SectionType.Physical);
|
||||
const hasNodeSection = new Map<number, string>();
|
||||
sections.forEach((section) => {
|
||||
const changeSectionData = section.datas.points.map((point) =>
|
||||
section.localToCanvasPoint(point)
|
||||
);
|
||||
const changeConcentrationDividingLineData = this.datas.points.map(
|
||||
(point) => this.localToCanvasPoint(point)
|
||||
);
|
||||
const hasNode = arePolylinesIntersect(
|
||||
changeSectionData,
|
||||
changeConcentrationDividingLineData
|
||||
);
|
||||
if (hasNode) {
|
||||
const minA = calculateDistanceFromPointToLine(
|
||||
hasNode.segment2[0],
|
||||
hasNode.segment2[1],
|
||||
section.localToCanvasPoint(section.getStartPoint())
|
||||
);
|
||||
const minB = calculateDistanceFromPointToLine(
|
||||
hasNode.segment2[0],
|
||||
hasNode.segment2[1],
|
||||
section.localToCanvasPoint(section.getEndPoint())
|
||||
);
|
||||
const relationParam = minA > minB ? TurnoutPort.B : TurnoutPort.A;
|
||||
const portRefOtherDevice =
|
||||
relationParam == 'A' ? section.datas.paRef : section.datas.pbRef;
|
||||
if (
|
||||
portRefOtherDevice?.id &&
|
||||
!hasNodeSection.get(section.id) &&
|
||||
!hasNodeSection.get(portRefOtherDevice.id)
|
||||
) {
|
||||
const refDevice = this.queryStore.queryById<Turnout | Section>(
|
||||
portRefOtherDevice?.id
|
||||
);
|
||||
const [leftDevice, rightDevice] =
|
||||
refDevice.localToCanvasPoint(
|
||||
getRectangleCenter(refDevice.getLocalBounds())
|
||||
).x <
|
||||
section.localToCanvasPoint(
|
||||
getRectangleCenter(section.getLocalBounds())
|
||||
).x
|
||||
? [
|
||||
{
|
||||
device: refDevice,
|
||||
port: devicePort[
|
||||
portRefOtherDevice.devicePort
|
||||
] as TurnoutPort,
|
||||
},
|
||||
{ device: section, port: relationParam },
|
||||
]
|
||||
: [
|
||||
{ device: section, port: relationParam },
|
||||
{
|
||||
device: refDevice,
|
||||
port: devicePort[
|
||||
portRefOtherDevice.devicePort
|
||||
] as TurnoutPort,
|
||||
},
|
||||
];
|
||||
hasNodeSection.set(leftDevice.device.id, '1');
|
||||
hasNodeSection.set(rightDevice.device.id, '1');
|
||||
nodeConWithSecs.push(
|
||||
new graphicData.NodeConWithSec({
|
||||
leftSection: createRelatedRefProto(
|
||||
leftDevice.device.type,
|
||||
leftDevice.device.id,
|
||||
leftDevice.port
|
||||
),
|
||||
rightSection: createRelatedRefProto(
|
||||
rightDevice.device.type,
|
||||
rightDevice.device.id,
|
||||
rightDevice.port
|
||||
),
|
||||
})
|
||||
);
|
||||
} else if (!hasNodeSection.get(section.id) && !portRefOtherDevice?.id) {
|
||||
const [leftSectionId, rightSectionId] =
|
||||
relationParam === 'A'
|
||||
? [undefined, section.id]
|
||||
: [section.id, undefined];
|
||||
hasNodeSection.set(section.id, '1');
|
||||
if (leftSectionId == undefined) {
|
||||
nodeConWithSecs.push(
|
||||
new graphicData.NodeConWithSec({
|
||||
leftSection: undefined,
|
||||
rightSection: createRelatedRefProto(
|
||||
Section.Type,
|
||||
rightSectionId,
|
||||
TurnoutPort.A
|
||||
),
|
||||
})
|
||||
);
|
||||
} else {
|
||||
nodeConWithSecs.push(
|
||||
new graphicData.NodeConWithSec({
|
||||
leftSection: createRelatedRefProto(
|
||||
Section.Type,
|
||||
leftSectionId,
|
||||
TurnoutPort.B
|
||||
),
|
||||
rightSection: undefined,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
nodeConWithSecs.sort((a, b) => {
|
||||
const sectionAId = a.leftSection ? a.leftSection.id : a.rightSection.id;
|
||||
const sectionA = this.queryStore.queryById<Section | Turnout>(sectionAId);
|
||||
const sectionBId = b.leftSection ? b.leftSection.id : b.rightSection.id;
|
||||
const sectionB = this.queryStore.queryById<Section | Turnout>(sectionBId);
|
||||
return (
|
||||
sectionA.localToCanvasPoint(
|
||||
getRectangleCenter(sectionA.getLocalBounds())
|
||||
).y -
|
||||
sectionB.localToCanvasPoint(
|
||||
getRectangleCenter(sectionB.getLocalBounds())
|
||||
).y
|
||||
);
|
||||
});
|
||||
this.datas.nodeConWithSecs = nodeConWithSecs;
|
||||
}
|
||||
}
|
||||
|
||||
export class ConcentrationDividingLineTemplate extends JlGraphicTemplate<ConcentrationDividingLine> {
|
||||
constructor(dataTemplate: IConcentrationDividingLineData) {
|
||||
super(ConcentrationDividingLine.Type, { dataTemplate });
|
||||
}
|
||||
new() {
|
||||
const g = new ConcentrationDividingLine();
|
||||
g.loadData(this.datas);
|
||||
return g;
|
||||
}
|
||||
}
|
@ -1,212 +0,0 @@
|
||||
import {
|
||||
IGraphicApp,
|
||||
GraphicDrawAssistant,
|
||||
GraphicInteractionPlugin,
|
||||
IDrawApp,
|
||||
JlGraphic,
|
||||
linePoint,
|
||||
PolylineEditPlugin,
|
||||
addWayPoint,
|
||||
clearWayPoint,
|
||||
MenuItemOptions,
|
||||
ContextMenu
|
||||
} from 'jl-graphic';
|
||||
import {
|
||||
IConcentrationDividingLineData,
|
||||
ConcentrationDividingLine,
|
||||
ConcentrationDividingLineConsts,
|
||||
ConcentrationDividingLineTemplate,
|
||||
} from './ConcentrationDividingLine';
|
||||
import {
|
||||
DisplayObject,
|
||||
FederatedMouseEvent,
|
||||
Graphics,
|
||||
IHitArea,
|
||||
Point,
|
||||
} from 'pixi.js';
|
||||
import { getWayLineIndex } from '../polygon/PolygonUtils';
|
||||
|
||||
export class ConcentrationDividingLineDraw extends GraphicDrawAssistant<
|
||||
ConcentrationDividingLineTemplate,
|
||||
IConcentrationDividingLineData
|
||||
> {
|
||||
points: Point[] = [];
|
||||
graphic = new Graphics();
|
||||
|
||||
constructor(app: IDrawApp, template: ConcentrationDividingLineTemplate) {
|
||||
super(app, template, 'sym_o_timeline', '集中区分割线');
|
||||
this.container.addChild(this.graphic);
|
||||
|
||||
ConcentrationDividingLinePointEditPlugin.init(app, this);
|
||||
}
|
||||
|
||||
bind(): void {
|
||||
super.bind();
|
||||
}
|
||||
unbind(): void {
|
||||
super.unbind();
|
||||
}
|
||||
|
||||
onLeftDown(e: FederatedMouseEvent): void {
|
||||
const { x, y } = this.toCanvasCoordinates(e.global);
|
||||
const p = new Point(x, y);
|
||||
this.points.push(p);
|
||||
}
|
||||
|
||||
onRightClick(): void {
|
||||
if (this.points.length < 2) {
|
||||
this.finish();
|
||||
return;
|
||||
}
|
||||
this.createAndStore(true);
|
||||
}
|
||||
|
||||
onEsc(): void {
|
||||
if (this.points.length < 2) {
|
||||
this.finish();
|
||||
return;
|
||||
}
|
||||
this.createAndStore(true);
|
||||
}
|
||||
|
||||
redraw(p: Point): void {
|
||||
if (this.points.length < 1) return;
|
||||
this.graphic.clear();
|
||||
this.graphic.lineStyle(
|
||||
ConcentrationDividingLineConsts.lineWidth,
|
||||
ConcentrationDividingLineConsts.lineColor
|
||||
);
|
||||
|
||||
const ps = [...this.points];
|
||||
ps.push(p);
|
||||
ps.forEach((p, i) => {
|
||||
if (i !== 0) {
|
||||
this.graphic.lineTo(p.x, p.y);
|
||||
} else {
|
||||
this.graphic.moveTo(p.x, p.y);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
prepareData(data: IConcentrationDividingLineData): boolean {
|
||||
if (this.points.length < 2) {
|
||||
console.log('ConcentrationDividingLine绘制因点不够取消绘制');
|
||||
return false;
|
||||
}
|
||||
data.points = this.points;
|
||||
return true;
|
||||
}
|
||||
|
||||
clearCache(): void {
|
||||
this.points = [];
|
||||
this.graphic.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export class ConcentrationDividingLineGraphicHitArea implements IHitArea {
|
||||
concentrationDividingLine: ConcentrationDividingLine;
|
||||
constructor(concentrationDividingLine: ConcentrationDividingLine) {
|
||||
this.concentrationDividingLine = concentrationDividingLine;
|
||||
}
|
||||
contains(x: number, y: number): boolean {
|
||||
for (
|
||||
let i = 1;
|
||||
i < this.concentrationDividingLine.datas.points.length;
|
||||
i++
|
||||
) {
|
||||
const p1 = this.concentrationDividingLine.datas.points[i - 1];
|
||||
const p2 = this.concentrationDividingLine.datas.points[i];
|
||||
if (
|
||||
linePoint(p1, p2, { x, y }, ConcentrationDividingLineConsts.lineWidth)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const addWaypointConfig: MenuItemOptions = {
|
||||
name: '添加路径点',
|
||||
};
|
||||
const clearWaypointsConfig: MenuItemOptions = {
|
||||
name: '清除所有路径点',
|
||||
};
|
||||
const ConcentrationDividingLineEditMenu: ContextMenu = ContextMenu.init({
|
||||
name: '集中区分割线编辑菜单',
|
||||
groups: [
|
||||
{
|
||||
items: [addWaypointConfig, clearWaypointsConfig],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export class ConcentrationDividingLinePointEditPlugin extends GraphicInteractionPlugin<ConcentrationDividingLine> {
|
||||
static Name = 'ConcentrationDividingLinePointDrag';
|
||||
drawAssistant: ConcentrationDividingLineDraw;
|
||||
|
||||
constructor(app: IGraphicApp, da: ConcentrationDividingLineDraw) {
|
||||
super(ConcentrationDividingLinePointEditPlugin.Name, app);
|
||||
this.drawAssistant = da;
|
||||
app.registerMenu(ConcentrationDividingLineEditMenu);
|
||||
}
|
||||
static init(app: IGraphicApp, da: ConcentrationDividingLineDraw) {
|
||||
return new ConcentrationDividingLinePointEditPlugin(app, da);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): ConcentrationDividingLine[] | undefined {
|
||||
return grahpics.filter(
|
||||
(g) => g.type == ConcentrationDividingLine.Type
|
||||
) as ConcentrationDividingLine[];
|
||||
}
|
||||
bind(g: ConcentrationDividingLine): void {
|
||||
g.lineGraphic.eventMode = 'static';
|
||||
g.lineGraphic.cursor = 'pointer';
|
||||
g.lineGraphic.hitArea = new ConcentrationDividingLineGraphicHitArea(g);
|
||||
g.transformSave = true;
|
||||
g.on('selected', this.onSelected, this);
|
||||
g.on('unselected', this.onUnselected, this);
|
||||
g.on('_rightclick', this.onContextMenu, this);
|
||||
}
|
||||
unbind(g: ConcentrationDividingLine): void {
|
||||
g.off('selected', this.onSelected, this);
|
||||
g.off('unselected', this.onUnselected, this);
|
||||
g.off('_rightclick', this.onContextMenu, this);
|
||||
}
|
||||
onContextMenu(e: FederatedMouseEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const concentrationDividingLine =
|
||||
target.getGraphic() as ConcentrationDividingLine;
|
||||
this.app.updateSelected(concentrationDividingLine);
|
||||
const p = concentrationDividingLine.screenToLocalPoint(e.global);
|
||||
addWaypointConfig.handler = () => {
|
||||
const linePoints = concentrationDividingLine.linePoints;
|
||||
const { start, end } = getWayLineIndex(linePoints, p);
|
||||
addWayPoint(concentrationDividingLine, false, start, end, p);
|
||||
};
|
||||
clearWaypointsConfig.handler = () => {
|
||||
clearWayPoint(concentrationDividingLine, false);
|
||||
};
|
||||
ConcentrationDividingLineEditMenu.open(e.global);
|
||||
}
|
||||
onSelected(g: DisplayObject): void {
|
||||
const concentrationDividingLine = g as ConcentrationDividingLine;
|
||||
let lep = concentrationDividingLine.getAssistantAppend<PolylineEditPlugin>(
|
||||
PolylineEditPlugin.Name
|
||||
);
|
||||
if (!lep) {
|
||||
lep = new PolylineEditPlugin(concentrationDividingLine);
|
||||
concentrationDividingLine.addAssistantAppend(lep);
|
||||
}
|
||||
lep.showAll();
|
||||
}
|
||||
onUnselected(g: DisplayObject): void {
|
||||
const concentrationDividingLine = g as ConcentrationDividingLine;
|
||||
const lep =
|
||||
concentrationDividingLine.getAssistantAppend<PolylineEditPlugin>(
|
||||
PolylineEditPlugin.Name
|
||||
);
|
||||
if (lep) {
|
||||
lep.hideAll();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,195 +0,0 @@
|
||||
import { IPointData } from 'pixi.js';
|
||||
import { Section } from '../section/Section';
|
||||
import { Turnout } from '../turnout/Turnout';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { IDrawApp, JlGraphic } from 'jl-graphic';
|
||||
import { GraphicDataBase } from 'src/drawApp/graphics/GraphicDataBase';
|
||||
import { TurnoutData } from 'src/drawApp/graphics/TurnoutInteraction';
|
||||
import { SectionData } from 'src/drawApp/graphics/SectionInteraction';
|
||||
import { SignalData } from 'src/drawApp/graphics/SignalInteraction';
|
||||
import { Signal } from '../signal/Signal';
|
||||
import { Platform } from '../platform/Platform';
|
||||
import { PlatformData } from 'src/drawApp/graphics/PlatformInteraction';
|
||||
|
||||
//判断线段与线段有木有交点
|
||||
export function isSegmentsIntersect(
|
||||
segment1: IPointData[],
|
||||
segment2: IPointData[]
|
||||
) {
|
||||
const [p1, p2] = segment1;
|
||||
const [p3, p4] = segment2;
|
||||
// 判断包围盒是否相交
|
||||
if (
|
||||
Math.max(p1.x, p2.x) < Math.min(p3.x, p4.x) ||
|
||||
Math.min(p1.x, p2.x) > Math.max(p3.x, p4.x) ||
|
||||
Math.max(p1.y, p2.y) < Math.min(p3.y, p4.y) ||
|
||||
Math.min(p1.y, p2.y) > Math.max(p3.y, p4.y)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
// 计算向量叉积
|
||||
const cross1 = crossProduct(p3, p1, p4);
|
||||
const cross2 = crossProduct(p3, p2, p4);
|
||||
const cross3 = crossProduct(p1, p3, p2);
|
||||
const cross4 = crossProduct(p1, p4, p2);
|
||||
if (cross1 * cross2 < 0 && cross3 * cross4 < 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function crossProduct(p1: IPointData, p2: IPointData, p3: IPointData) {
|
||||
return (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);
|
||||
}
|
||||
|
||||
export function getSegmentsFromPolyline(polyline: IPointData[]) {
|
||||
const segments = [];
|
||||
|
||||
for (let i = 0; i < polyline.length - 1; i++) {
|
||||
const segment = [polyline[i], polyline[i + 1]];
|
||||
segments.push(segment);
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
//判断折线与折线有木有交点
|
||||
export function arePolylinesIntersect(
|
||||
polyline1: IPointData[],
|
||||
polyline2: IPointData[]
|
||||
) {
|
||||
const segments1 = getSegmentsFromPolyline(polyline1);
|
||||
const segments2 = getSegmentsFromPolyline(polyline2);
|
||||
|
||||
for (const segment1 of segments1) {
|
||||
for (const segment2 of segments2) {
|
||||
if (isSegmentsIntersect(segment1, segment2)) {
|
||||
return { hasnode: true, segment1, segment2 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取指定区间内的物理区段和道岔
|
||||
export function findContainDevice(
|
||||
refDevice: Section | Turnout,
|
||||
refDevicePort: graphicData.RelatedRef.DevicePort,
|
||||
containDeviceIds: number[],
|
||||
drawApp: IDrawApp
|
||||
) {
|
||||
const devicePort = graphicData.RelatedRef.DevicePort;
|
||||
containDeviceIds.push(refDevice.id);
|
||||
switch (true) {
|
||||
case refDevice instanceof Section:
|
||||
const sectionPaorbRef =
|
||||
refDevicePort == devicePort.B
|
||||
? refDevice.datas.paRef
|
||||
: refDevice.datas.pbRef;
|
||||
if (sectionPaorbRef && !containDeviceIds.includes(sectionPaorbRef.id)) {
|
||||
const pbRefDevice = drawApp.queryStore.queryById<Section | Turnout>(
|
||||
sectionPaorbRef.id
|
||||
);
|
||||
findContainDevice(
|
||||
pbRefDevice,
|
||||
sectionPaorbRef.devicePort,
|
||||
containDeviceIds,
|
||||
drawApp
|
||||
);
|
||||
}
|
||||
break;
|
||||
//道岔需要分路--实际的走向
|
||||
case refDevice instanceof Turnout:
|
||||
const otherPorts = [devicePort.A, devicePort.B, devicePort.C].filter(
|
||||
(port) => port !== refDevicePort
|
||||
);
|
||||
otherPorts.forEach((port) => {
|
||||
switch (port) {
|
||||
case devicePort.A:
|
||||
const turnoutPaRef = refDevice.datas.paRef;
|
||||
if (turnoutPaRef && !containDeviceIds.includes(turnoutPaRef.id)) {
|
||||
const paRefDevice = drawApp.queryStore.queryById<
|
||||
Section | Turnout
|
||||
>(turnoutPaRef.id);
|
||||
findContainDevice(
|
||||
paRefDevice,
|
||||
turnoutPaRef.devicePort,
|
||||
containDeviceIds,
|
||||
drawApp
|
||||
);
|
||||
}
|
||||
break;
|
||||
case devicePort.B:
|
||||
const turnoutPbRef = refDevice.datas.pbRef;
|
||||
if (turnoutPbRef && !containDeviceIds.includes(turnoutPbRef.id)) {
|
||||
const pbRefDevice = drawApp.queryStore.queryById<
|
||||
Section | Turnout
|
||||
>(turnoutPbRef.id);
|
||||
findContainDevice(
|
||||
pbRefDevice,
|
||||
turnoutPbRef.devicePort,
|
||||
containDeviceIds,
|
||||
drawApp
|
||||
);
|
||||
}
|
||||
break;
|
||||
case devicePort.C:
|
||||
const turnoutPcRef = (refDevice as Turnout).datas.pcRef;
|
||||
if (turnoutPcRef && !containDeviceIds.includes(turnoutPcRef.id)) {
|
||||
const pcRefDevice = drawApp.queryStore.queryById<
|
||||
Section | Turnout
|
||||
>(turnoutPcRef.id);
|
||||
findContainDevice(
|
||||
pcRefDevice,
|
||||
turnoutPcRef.devicePort,
|
||||
containDeviceIds,
|
||||
drawApp
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export function handleCentralizedStationsData(
|
||||
devices: JlGraphic[],
|
||||
centralizedStation: number
|
||||
) {
|
||||
interface GraphicData {
|
||||
centralizedStation: number;
|
||||
}
|
||||
const dataMap = new Map<string, GraphicDataBase>([
|
||||
[Turnout.Type, new TurnoutData()],
|
||||
[Section.Type, new SectionData()],
|
||||
[Signal.Type, new SignalData()],
|
||||
[Platform.Type, new PlatformData()],
|
||||
]);
|
||||
devices.forEach((device) => {
|
||||
const data = dataMap.get(device.type);
|
||||
if (data) {
|
||||
data.copyFrom(device.saveData());
|
||||
const dataCopy = data as GraphicDataBase & GraphicData;
|
||||
dataCopy.centralizedStation = centralizedStation;
|
||||
device.updateData(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//找到公共的元素
|
||||
type findType = string | number;
|
||||
export function findCommonElements(arrays: findType[][]) {
|
||||
if (arrays.length === 0) {
|
||||
return [];
|
||||
}
|
||||
const commonElements: findType[] = [];
|
||||
arrays[0].forEach((element) => {
|
||||
if (arrays.every((arr) => arr.includes(element))) {
|
||||
commonElements.push(element);
|
||||
}
|
||||
});
|
||||
return commonElements;
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
import { Graphics, IPointData } from 'pixi.js';
|
||||
import { assertBezierPoints, convertToBezierParams } from 'jl-graphic';
|
||||
|
||||
export enum DevicePort {
|
||||
A = 'A',
|
||||
B = 'B',
|
||||
C = 'C',
|
||||
}
|
||||
|
||||
export class SectionGraphic extends Graphics {
|
||||
static Type = 'SectionGraphic';
|
||||
private _points: IPointData[] = [];
|
||||
public get points(): IPointData[] {
|
||||
return this._points;
|
||||
}
|
||||
public set points(value: IPointData[]) {
|
||||
if (!this.isCurve) {
|
||||
if (value.length < 2) {
|
||||
throw Error('Polyline must have at least 2 points');
|
||||
}
|
||||
} else {
|
||||
assertBezierPoints(value);
|
||||
}
|
||||
this._points = value;
|
||||
}
|
||||
|
||||
private _segmentsCount = 10;
|
||||
public get segmentsCount(): number {
|
||||
return this._segmentsCount;
|
||||
}
|
||||
public set segmentsCount(value: number) {
|
||||
if (value < 1) {
|
||||
throw Error('segmentsCount must be at least 1');
|
||||
}
|
||||
this._segmentsCount = value;
|
||||
}
|
||||
|
||||
isCurve = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
paint() {
|
||||
if (this.isCurve) {
|
||||
const bps = convertToBezierParams(this.points);
|
||||
bps.forEach((bp) => {
|
||||
this.drawBezierCurve(bp.p1, bp.p2, bp.cp1, bp.cp2, this.segmentsCount);
|
||||
});
|
||||
} else {
|
||||
this.moveTo(this.points[0].x, this.points[0].y);
|
||||
for (let i = 1; i < this.points.length; i++) {
|
||||
this.lineTo(this.points[i].x, this.points[i].y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user