Merge branch 'master' of git.code.tencent.com:xian-ncc-da/xian-ncc-da-client

This commit is contained in:
Yuan 2023-08-23 09:18:17 +08:00
commit c881d48145
7 changed files with 588 additions and 10 deletions

View File

@ -0,0 +1,71 @@
import { api } from 'src/boot/axios';
import { PageDto, PageQueryDto } from './ApiCommon';
const BaseUrl = '/api/config/device';
export interface Item {
id: number;
lineId: number;
configName?: string;
configType: number;
deviceType: string;
deviceOperator: string;
deviceUnit: string;
deviceConfigType: string;
val?: number;
}
export class PagingQueryParams extends PageQueryDto {
name?: string;
}
/**
*
* @param params
* @returns
*/
export async function pageQuery(
params: PagingQueryParams
): Promise<PageDto<Item>> {
const response = await api.get(`${BaseUrl}/page`, {
params: params,
});
return response.data;
}
interface createParams {
id?: number;
lineId: number;
name: string;
deviceType: string;
guardUnit: string;
operator: string;
configDeviceType: string;
val: number;
}
/**
* /
* @param params
* @returns
*/
export function saveThreshold(data: createParams) {
return api.post(`${BaseUrl}/save`, data);
}
/**
*
* @param lineId 线id
*/
export async function getBaseDataByLineId(lineId: number): Promise<Item[]> {
const response = await api.get(`${BaseUrl}/initData/${lineId}`);
return response.data;
}
/**
*
* @param id id
*/
export function deleteThresholdConfig(id: number) {
return api.delete(`${BaseUrl}/${id}`);
}

View File

@ -28,12 +28,13 @@ export async function getDeviceAreaList({
throw Error(resp.statusText); throw Error(resp.statusText);
} }
} }
export interface IAreaConfigItem {
export function deviceRangeSet(data: { id?: number;
lineId: number; lineId: number;
areaName: string; areaName: string;
deviceType: string; deviceType: string;
data: string; data: string;
}) { }
export function deviceRangeSet(data: IAreaConfigItem) {
return api.post('/api/config/device/area/save', data); return api.post('/api/config/device/area/save', data);
} }

View File

@ -67,17 +67,22 @@ const list = reactive([
{ {
path: '/dataManage/publish', path: '/dataManage/publish',
label: '发布管理', label: '发布管理',
icon: 'app_registration', icon: 'playlist_add_check',
}, },
{ {
path: '/dataManage/lineInfo', path: '/dataManage/lineInfo',
label: '线路信息管理', label: '线路信息管理',
icon: 'app_registration', icon: 'format_list_numbered',
}, },
{ {
path: '/dataManage/decisionInfo', path: '/dataManage/decisionInfo',
label: '决策信息管理', label: '决策信息管理',
icon: 'app_registration', icon: 'format_align_center',
},
{
path: '/dataManage/thresholdValue',
label: '报警故障阈值配置',
icon: 'format_indent_increase',
}, },
], ],
}, },

View File

@ -39,6 +39,7 @@ export enum showAlertTypeData {
AXLE_LED_RED_MOST = '计轴大面积红光带', AXLE_LED_RED_MOST = '计轴大面积红光带',
AXLE_LED_ORANGE = '计轴橙光带', AXLE_LED_ORANGE = '计轴橙光带',
AXLE_LED_ORANGE_MOST = '计轴大面积橙光带', AXLE_LED_ORANGE_MOST = '计轴大面积橙光带',
SWITCH_LOST_MOST = '道岔大面积失表',
} }
export enum saveAlertTypeData { export enum saveAlertTypeData {

View File

@ -2,7 +2,7 @@
<div v-if="lineStore.selectedGraphics !== null"> <div v-if="lineStore.selectedGraphics !== null">
<q-card class="q-gutter-sm q-pa-sm"> <q-card class="q-gutter-sm q-pa-sm">
<q-card-section> <q-card-section>
<div class="text-h6">范围配置</div> <div class="text-h6">{{ handleState }}</div>
</q-card-section> </q-card-section>
<q-separator inset></q-separator> <q-separator inset></q-separator>
<q-form ref="myForm" @submit="onSubmit" @reset="onReset"> <q-form ref="myForm" @submit="onSubmit" @reset="onReset">
@ -57,7 +57,7 @@ import { Station } from 'src/graphics/station/Station';
import { Platform } from 'src/graphics/platform/Platform'; import { Platform } from 'src/graphics/platform/Platform';
import { QForm, useQuasar } from 'quasar'; import { QForm, useQuasar } from 'quasar';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { deviceRangeSet } from 'src/api/ConfigApi'; import { deviceRangeSet, IAreaConfigItem } from 'src/api/ConfigApi';
import { fromUint8Array } from 'js-base64'; import { fromUint8Array } from 'js-base64';
import { LogicSectionData } from 'src/drawApp/graphics/LogicSectionInteraction'; import { LogicSectionData } from 'src/drawApp/graphics/LogicSectionInteraction';
import { StationData } from 'src/drawApp/graphics/StationInteraction'; import { StationData } from 'src/drawApp/graphics/StationInteraction';
@ -85,6 +85,7 @@ const rangeConfig = reactive<{
device: '', device: '',
}); });
const device = ref<string[]>([]); const device = ref<string[]>([]);
const handleState = ref('新建范围配置');
const optionsType = [ const optionsType = [
{ label: '逻辑区段', value: LogicSection.Type }, { label: '逻辑区段', value: LogicSection.Type },
@ -101,12 +102,16 @@ enum DeviceType {
} }
watch(props, () => { watch(props, () => {
handleState.value = '编辑范围配置';
rangeConfig.areaName = props.rangeConfigEdit?.areaName; rangeConfig.areaName = props.rangeConfigEdit?.areaName;
rangeConfig.deviceType = props.rangeConfigEdit?.deviceType; rangeConfig.deviceType = props.rangeConfigEdit?.deviceType;
const select: JlGraphic[] = [];
props.rangeConfigEdit?.device.forEach((id: string) => { props.rangeConfigEdit?.device.forEach((id: string) => {
const g = lineStore.getLineApp().queryStore.queryById(id); const g = lineStore.getLineApp().queryStore.queryById(id);
select.push(g);
device.value.push(g.code); device.value.push(g.code);
}); });
lineStore.getLineApp().updateSelected(...select);
}); });
watch( watch(
@ -149,12 +154,19 @@ async function onSubmit() {
if (res) { if (res) {
try { try {
const lineId = +route.params.id as number; const lineId = +route.params.id as number;
await deviceRangeSet({ const params: IAreaConfigItem = {
lineId: lineId, lineId: lineId,
areaName: rangeConfig.areaName, areaName: rangeConfig.areaName,
deviceType: (DeviceType as never)[rangeConfig.deviceType + ''], deviceType: (DeviceType as never)[rangeConfig.deviceType + ''],
data: rangeConfig.device, data: rangeConfig.device,
}); };
if (handleState.value == '新建范围配置') {
await deviceRangeSet(params);
} else {
params.id = props.rangeConfigEdit?.id;
await deviceRangeSet(params);
}
$q.notify({ $q.notify({
type: 'positive', type: 'positive',
message: '创建成功', message: '创建成功',

View File

@ -0,0 +1,483 @@
<template>
<div class="q-pa-md">
<q-table
ref="tableRef"
title="报警故障阈值配置"
:style="{ height: tableHeight + 'px' }"
:rows="rows"
:columns="columnDefs"
row-key="id"
v-model:pagination="pagination"
:rows-per-page-options="[10, 20, 50, 100]"
:loading="loading"
:filter="filter"
binary-state-sort
@request="onRequest"
>
<template v-slot:top-right>
<q-input
dense
debounce="1000"
v-model="filter.name"
label="名称"
></q-input>
<q-btn flat round color="primary" icon="search" />
<q-btn color="primary" label="新建" @click="createConfig" />
</template>
<template v-slot:body-cell-operations="props">
<q-td :props="props">
<div class="q-gutter-sm row justify-center">
<q-btn
color="primary"
:disable="operateDisabled"
label="编辑"
@click="editThresholdValue(props.row)"
/>
<q-btn
color="red"
:disable="operateDisabled"
label="删除"
@click="deleteData(props.row)"
/>
</div>
</q-td>
</template>
</q-table>
<q-dialog
v-model="thresholdFormShow"
persistent
transition-show="scale"
transition-hide="scale"
>
<q-card style="width: 400px">
<q-card-section>
<q-form ref="myForm" @submit="onSubmit" class="q-gutter-md">
<div class="text-h6">
{{ thresholdForm.id ? '编辑' : '新建' }}
</div>
<q-input
outlined
label="名称 * "
v-model="thresholdForm.name"
lazy-rules
:rules="[(val) => val.length > 0 || '请输入名称!']"
/>
<q-select
outlined
v-model="thresholdForm.lineId"
:options="lineOptions"
@update:model-value="changeLineId"
emit-value
map-options
label="线路 * "
lazy-rules
:rules="[(val) => val.length > 0 || '请选择线路!']"
/>
<q-select
outlined
v-model="thresholdForm.deviceType"
:options="typeOptions"
@update:model-value="changeDeviceType"
emit-value
map-options
label="设备类型 * "
lazy-rules
:rules="[(val) => val.length > 0 || '请选择设备类型!']"
/>
<q-select
outlined
v-model="thresholdForm.configDeviceType"
:options="operatorOptions"
@update:model-value="changeConfigDeviceType"
emit-value
map-options
:option-label="
(row) =>
showAlertTypeData[row.deviceConfigType] ||
row.deviceConfigType
"
option-value="deviceConfigType"
label="配置类型 * "
lazy-rules
:rules="[(val) => val.length > 0 || '请选择配置类型!']"
/>
<q-card flat bordered>
<q-card-section style="height: 113px">
<div class="text-grey-7">配置数据 *</div>
<div
class="q-gutter-sm row justify-center items-baseline"
v-show="thresholdForm.configDeviceType"
>
<div>
{{
unitObj[thresholdForm.operator as keyof typeof unitObj] ||
''
}}
</div>
<q-input
v-model.number="thresholdForm.val"
type="number"
outlined
dense
lazy-rules
:rules="[(val) => val > 0 || '请输入大于0的值']"
></q-input>
<div>
{{
unitObj[
thresholdForm.guardUnit as keyof typeof unitObj
] || ''
}}
</div>
</div>
</q-card-section>
</q-card>
<q-card-actions align="right">
<q-btn color="primary" label="保存" type="submit" />
<q-btn label="取消" v-close-popup />
</q-card-actions>
</q-form>
</q-card-section>
</q-card>
</q-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue';
import { useQuasar, type QTableColumn, QForm } from 'quasar';
import {
pageQuery,
saveThreshold,
getBaseDataByLineId,
deleteThresholdConfig,
Item,
} from '../api/AlarmThresholdApi';
import { getLineList } from '../api/LineInfoApi';
import { ApiError } from 'src/boot/axios';
import { showAlertTypeData } from 'src/components/alarm/alarmInfoEnum';
const $q = useQuasar();
const props = withDefaults(
defineProps<{
sizeHeight: number;
}>(),
{ sizeHeight: 500 }
);
const tableHeight = computed(() => {
return props.sizeHeight - 32;
});
const typeOptions = [
{ label: '道岔', value: 'DEVICE_TYPE_SWITCH' },
{ label: '计轴区段', value: 'DEVICE_TYPE_TRACK' },
{ label: '屏蔽门', value: 'DEVICE_TYPE_PLATFORM' },
];
const unitObj = {
TIMES: '秒',
NUMS: '个',
LT: '小于等于',
GE: '大于等于',
};
const operatorOptions = computed(() => {
return operatorList.value.filter((item) => {
return (
item.deviceType == thresholdForm.deviceType &&
item.lineId == +thresholdForm.lineId
);
});
});
const operatorList = computed(() => {
let arr: Item[] = [];
const data = configDataMap[+thresholdForm.lineId];
if (data) {
arr = data;
}
return arr;
});
type DataConfig = {
[key: number]: Item[];
};
const configDataMap = reactive<DataConfig>({});
function getConfigDataByLineId(val: number) {
getBaseDataByLineId(val)
.then((res) => {
configDataMap[val] = res;
})
.catch((err) => {
console.log(err, '---err---');
});
}
let lineOptions: Array<{ label: string; value: string }> = [];
function getAllLineList() {
lineOptions = [];
getLineList()
.then((res) => {
res.forEach((item) => {
const obj = {
label: item.name,
value: item.lineId + '',
};
lineOptions.push(obj);
});
})
.catch((err) => {
console.log(err, '---err--');
});
}
const lineOptionsMap = computed(() => {
const obj: { [k: string]: string } = {};
lineOptions.forEach((item: { value: string; label: string }) => {
obj[item.value] = item.label;
});
return obj;
});
const typeOptionsMap = computed(() => {
const obj: { [k: string]: string } = {};
typeOptions.forEach((item: { value: string; label: string }) => {
obj[item.value] = item.label;
});
return obj;
});
onMounted(() => {
tableRef.value.requestServerInteraction();
getAllLineList();
});
const columnDefs: QTableColumn[] = [
{
name: 'configName',
label: '名称',
field: 'configName',
required: true,
align: 'center',
},
{
name: 'lineId',
label: '线路',
field: (row) => {
return lineOptionsMap.value[row.lineId] || '';
},
align: 'center',
},
{
name: 'deviceType',
label: '设备类型',
field: (row) => {
return typeOptionsMap.value[row.deviceType] || '';
},
align: 'center',
},
{
name: 'deviceConfigType',
label: '配置类型',
field: (row) => {
return showAlertTypeData[row.deviceConfigType] || row.deviceConfigType;
},
align: 'center',
},
{
name: 'deviceOperator',
label: '符号',
field: (row) => {
return unitObj[row.deviceOperator as keyof typeof unitObj] || '';
},
align: 'center',
},
{
name: 'val',
label: '值',
field: 'val',
align: 'center',
},
{
name: 'deviceUnit',
label: '单位',
field: (row) => {
return unitObj[row.deviceUnit as keyof typeof unitObj] || '';
},
align: 'center',
},
{ name: 'operations', label: '操作', field: 'operations', align: 'center' },
];
const operateDisabled = ref(false);
const tableRef = ref();
const rows = reactive([]);
const filter = reactive({
name: '',
});
const loading = ref(false);
const pagination = ref({
sortBy: 'desc',
descending: false,
page: 1,
rowsPerPage: 10,
rowsNumber: 10,
});
async function onRequest(props: any) {
const { page, rowsPerPage, sortBy, descending } = props.pagination;
const filter = props.filter;
loading.value = true;
try {
let response = await pageQuery({
current: page,
size: rowsPerPage,
name: filter.name,
});
const pageData = response;
pagination.value.rowsNumber = pageData.total;
pagination.value.page = page;
pagination.value.rowsPerPage = rowsPerPage;
pagination.value.sortBy = sortBy;
pagination.value.descending = descending;
rows.splice(0, rows.length, ...(pageData.records as []));
} catch (err) {
const error = err as ApiError;
$q.notify({
type: 'negative',
message: error.title,
});
} finally {
loading.value = false;
}
}
const thresholdFormShow = ref(false);
function createConfig() {
initFormData();
thresholdFormShow.value = true;
}
const myForm = ref<QForm | null>(null);
function onSubmit() {
myForm.value?.validate().then(async (res) => {
if (res) {
operateDisabled.value = true;
try {
const params = {
lineId: +thresholdForm.lineId,
name: thresholdForm.name,
deviceType: thresholdForm.deviceType,
configDeviceType: thresholdForm.configDeviceType,
guardUnit: thresholdForm.guardUnit,
operator: thresholdForm.operator,
val: thresholdForm.val,
};
if (thresholdForm.id) {
Object.assign(params, { id: +thresholdForm.id });
}
await saveThreshold(params);
thresholdFormShow.value = false;
tableRef.value.requestServerInteraction(); //
} catch (err) {
const error = err as ApiError;
$q.notify({
type: 'negative',
message: error.title,
});
} finally {
operateDisabled.value = false;
}
}
});
}
const thresholdForm = reactive({
id: 0,
name: '',
lineId: '',
deviceType: '',
configDeviceType: '',
guardUnit: '',
operator: '',
val: 0,
});
function initFormData() {
thresholdForm.id = 0;
thresholdForm.name = '';
thresholdForm.lineId = '';
thresholdForm.deviceType = '';
thresholdForm.configDeviceType = '';
thresholdForm.guardUnit = '';
thresholdForm.operator = '';
thresholdForm.val = 0;
}
function changeLineId(val: string) {
thresholdForm.configDeviceType = '';
if (val && !configDataMap[+val]) {
getConfigDataByLineId(+val);
}
}
function changeDeviceType() {
thresholdForm.configDeviceType = '';
}
function changeConfigDeviceType(val: string) {
const find = operatorOptions.value.find((item) => {
return item.deviceConfigType == val;
});
if (find) {
thresholdForm.guardUnit = find.deviceUnit;
thresholdForm.operator = find.deviceOperator;
} else {
thresholdForm.guardUnit = '';
thresholdForm.operator = '';
thresholdForm.val = 0;
}
}
function editThresholdValue(row: Item) {
thresholdFormShow.value = true;
thresholdForm.id = row.id;
thresholdForm.name = row.configName || '';
thresholdForm.lineId = row.lineId + '';
thresholdForm.deviceType = row.deviceType;
thresholdForm.guardUnit = row.deviceUnit;
thresholdForm.operator = row.deviceOperator;
thresholdForm.configDeviceType = row.deviceConfigType;
thresholdForm.val = row.val || 0;
if (!configDataMap[row.lineId]) {
getConfigDataByLineId(row.lineId);
}
}
async function deleteData(row: Item) {
operateDisabled.value = true;
$q.dialog({
title: '确认',
message: `确认删除配置 "${row.configName}" 吗?`,
cancel: true,
})
.onOk(async () => {
try {
await deleteThresholdConfig(row.id);
tableRef.value.requestServerInteraction(); //
} catch (err) {
const error = err as ApiError;
$q.notify({
type: 'negative',
message: error.title,
});
}
})
.onDismiss(() => {
operateDisabled.value = false;
});
}
</script>

View File

@ -45,6 +45,11 @@ const routes: RouteRecordRaw[] = [
name: 'decisionInfo', name: 'decisionInfo',
component: () => import('pages/DecisionInfoManage.vue'), component: () => import('pages/DecisionInfoManage.vue'),
}, },
{
path: 'thresholdValue',
name: 'thresholdValue',
component: () => import('pages/AlarmThresholdValue.vue'),
},
], ],
}, },
{ {