Commit 12e6427b by zhengyoujia

Merge branch 'frontend' into 'master'

Frontend

See merge request !12
parents e87d7277 85956a77
......@@ -29,33 +29,9 @@ export class allEventDataStrategy extends abstractDataStrategyMid {
* @returns 事件的数据。
*/
execute(): any {
let eventData = this.extractor.getData(allEventDataStrategy.fileName, allEventDataStrategy.sheetName);
this.removeUnusedColumns(eventData);
return this.formatDataForFrontend(eventData);
}
/**
* 移除数据中前端不使用的列
* @param data - 从数据源提取的数据
*/
private removeUnusedColumns(data: any) {
data.forEach(row => {
// Initialize missing relevant columns with a default value
allEventDataStrategy.RELEVANTINFO.forEach(key => {
if (!(key in row)) {
row[key] = null; // You can set this to any default value you prefer
}
});
Object.keys(row).forEach(key => {
if (!allEventDataStrategy.RELEVANTINFO.includes(key)) {
delete row[key];
}
if (typeof row[key] === 'number') {
row[key] = excelSerialToJSDate(row[key]);
}
});
});
const eventData = this.extractor.getData(allEventDataStrategy.fileName, allEventDataStrategy.sheetName);
const formattedData = this.formatDataForFrontend(eventData);
return formattedData;
}
/**
......@@ -66,22 +42,20 @@ export class allEventDataStrategy extends abstractDataStrategyMid {
private formatDataForFrontend(data: any): any {
return data.map(row => {
let formattedRow: { [key: string]: any } = {};
Object.keys(row).forEach(key => {
allEventDataStrategy.RELEVANTINFO.forEach(key => {
const translatedKey = allEventDataStrategy.KEY_MAP[key];
let value = row[key];
// Format date if key is one of the date fields
if (['creationTime', 'dispositionTime', 'dispositionCompletionTime', 'closureTime'].includes(translatedKey) && value) {
value = new Date(value).toLocaleString('zh-CN', { hour12: false }).replace(/\//g, '-').replace(',', '');
}
// Only add non-null values to the formatted row
if (value !== null) {
formattedRow[translatedKey] = value;
if (['创建时间', '处置时间', '处置完成时间', '办结时间'].includes(key) && value) {
const date = excelSerialToJSDate(value);
const datePart = date.toISOString().split('T')[0].replace(/-/g, '/');
const timePart = date.toTimeString().split(' ')[0].substring(0, 8);
value = `${datePart} ${timePart}`;
}
formattedRow[translatedKey] = value !== undefined ? value : null;
});
// Add detail section with all time fields and their corresponding statuses
formattedRow.detail = this.constructDetailSection(formattedRow);
return formattedRow;
......@@ -94,43 +68,36 @@ export class allEventDataStrategy extends abstractDataStrategyMid {
* @returns 详细信息部分
*/
private constructDetailSection(row: { [key: string]: any }): any {
const details: any = {};
const details: any = [];
if (row.creationTime) {
details.creationTime = {
details.push({
time: row.creationTime,
status: '待调度'
};
});
}
if (row.dispositionTime) {
details.dispositionTime = {
details.push({
time: row.dispositionTime,
status: '处置中'
};
});
}
if (row.dispositionCompletionTime) {
details.dispositionCompletionTime = {
details.push({
time: row.dispositionCompletionTime,
status: '已处置'
};
});
}
if (row.closureTime) {
details.closureTime = {
details.push({
time: row.closureTime,
status: '已办结'
};
});
}
// Remove any null detail fields
Object.keys(details).forEach(key => {
if (details[key].time === null) {
delete details[key];
}
});
return Object.values(details);
return details;
}
}
......@@ -66,16 +66,13 @@ export abstract class abstractDataStrategyRight implements dataStrategy {
return eventCount;
}
/**
* 统计事件列表中每个事件的数量。
* @param list - 事件名称列表。
* @param target - 目标事件名称。
* @param data - 数据源。
* @param year - 指定年份 ("thisyear" or "lastyear").
* @returns 事件计数映射。
*/
/**
* getListCount 方法的更新版本,添加了零替换逻辑
* 统计事件列表中每个事件的数量。
* @param list - 事件名称列表。
* @param target - 目标事件名称。
* @param data - 数据源。
* @param year - 指定年份 ("thisyear" or "lastyear").
* @returns 事件计数映射。
*/
protected getListCount(list: string[], target: string, data: any, year: string) {
const currentYear = new Date().getFullYear();
......@@ -83,16 +80,7 @@ protected getListCount(list: string[], target: string, data: any, year: string)
const count = this.registerItems(list);
data.forEach(row => {
// const rowDate = excelSerialToJSDate(row['创建时间']);
let rowDate: any = 0;
if (typeof (row['创建时间']) == "number") {
rowDate = excelSerialToJSDate(row['创建时间']);
// console.log("from if", row['创建时间']);
}
else {
rowDate = row['创建时间'];
// console.log(rowDate);
}
const rowDate = excelSerialToJSDate(row['创建时间']);
const rowYear = rowDate.getFullYear();
if (rowYear == targetYear) {
count.set(row[target], (count.get(row[target]) || 0) + 1);
......@@ -112,9 +100,38 @@ protected getListCount(list: string[], target: string, data: any, year: string)
count.set(key, Math.floor(Math.random() * 10) + 1); // Random number between 1 and 10
});
}
console.log(allCountsZero ? "randomly generating" : "excel data");
return count;
}
/**
* 统计事件列表中每个事件的数量。
* @param list - 事件名称列表。
* @param target - 目标事件名称。
* @param data - 数据源。
* @param year - 指定年份 ("thisyear" or "lastyear").
* @returns 事件计数映射。
*/
protected getListCountSorted(list: string[], target: string, data: any, year: string) {
// data = data.slice(0, 5);
const currentYear = new Date().getFullYear();
const targetYear = year === 'thisyear' ? currentYear : currentYear - 1;
const count = this.registerItems(list);
data.forEach(row => {
const rowDate = excelSerialToJSDate(row['创建时间']);
const rowYear = rowDate.getFullYear();
if (rowYear == targetYear) {
count.set(row[target], (count.get(row[target]) || 0) + 1);
}
});
const sortedCount = Array.from(count.entries()).sort((a, b) => b[1] - a[1]);
const sortedCountMap = new Map(sortedCount);
return sortedCountMap;
}
}
......@@ -42,13 +42,8 @@ export class eventMonthDistributionStrategy extends abstractDataStrategyRight {
}
data.forEach(row => {
let rowDate: any = 0;
if (typeof (row['创建时间']) == "number") {
rowDate = excelSerialToJSDate(row['创建时间']);
}
else {
rowDate = row['创建时间'];
}
const rowDate = excelSerialToJSDate(row['创建时间']);
rowDate.setHours(rowDate.getHours() - eventMonthDistributionStrategy.TIMEDIFFERENCE);
const rowYear = rowDate.getFullYear();
const rowMonth = rowDate.getMonth() + 1; // getMonth() returns 0-11
......
......@@ -6,7 +6,6 @@
import { abstractDataStrategyRight } from "./abstractDataStrategyRight";
import excelSerialToJSDate from "../../../util/excelDateToJSDate";
import getRandomNumber from "../../../util/randomNumberGenerator";
import mapToObj from "../../../util/mapToObj";
/**
* 事件处理时间策略类,继承自 abstractDataStrategyRight。
......@@ -22,7 +21,7 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
this.paramsCheck(params);
// 获取指定年份的事件处理时间,并转换为对象
return mapToObj(this.getEventProcessingTime(this.eventData, params.query.year), "type", "duration");
return this.formatOutput(this.getEventProcessingTime(this.eventData, params.query.year));
}
/**
......@@ -37,6 +36,9 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
const statusList = ['调度时长', '处置等待', '处置时长', '办结时长']
const timeMap = this.registerItems(statusList);
const detailMap = this.registerItems(statusList, true);
let assignCount = 0, waitCount = 0, processCount = 0, finishingCount = 0;
data.forEach(row => {
......@@ -48,6 +50,7 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
case '待调度':
const time = getRandomNumber(0.5, 1.7, 1);
timeMap.set('调度时长', (timeMap.get('调度时长') || 0) + time);
detailMap.get('调度时长').push(this.createChartDetail(row, '待调度', time));
assignCount++;
break;
case '处置中':
......@@ -57,6 +60,7 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
waitCount--;
}
timeMap.set('处置等待', (timeMap.get('处置等待') || 0) + waitTime);
detailMap.get('处置等待').push(this.createChartDetail(row, '处置中', waitTime));
waitCount++;
break;
case '已处置':
......@@ -72,6 +76,8 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
}
timeMap.set('处置等待', (timeMap.get('处置等待') || 0) + waitTime);
timeMap.set('处置时长', (timeMap.get('处置时长') || 0) + processTime);
detailMap.get('处置等待').push(this.createChartDetail(row, '处置中', waitTime));
detailMap.get('处置时长').push(this.createChartDetail(row, '已处置', processTime));
waitCount++;
processCount++;
break;
......@@ -94,6 +100,9 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
timeMap.set('处置等待', (timeMap.get('处置等待') || 0) + waitTime);
timeMap.set('处置时长', (timeMap.get('处置时长') || 0) + processTime);
timeMap.set('办结时长', (timeMap.get('办结时长') || 0) + closeTime);
detailMap.get('处置等待').push(this.createChartDetail(row, '处置中', waitTime));
detailMap.get('处置时长').push(this.createChartDetail(row, '已处置', processTime));
detailMap.get('办结时长').push(this.createChartDetail(row, '已办结', closeTime));
waitCount++;
processCount++;
finishingCount++;
......@@ -102,11 +111,11 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
}
});
timeMap.set('调度时长', assignCount ? timeMap.get('调度时长') / assignCount : 0);
timeMap.set('处置等待', waitCount ? timeMap.get('处置等待') / waitCount : 0);
timeMap.set('处置时长', processCount ? timeMap.get('处置时长') / processCount : 0);
timeMap.set('办结时长', finishingCount ? timeMap.get('办结时长') / finishingCount : 0);
return timeMap;
timeMap.set('调度时长', assignCount ? Math.ceil(timeMap.get('调度时长') / assignCount) : 0);
timeMap.set('处置等待', waitCount ? Math.ceil(timeMap.get('处置等待') / waitCount) : 0);
timeMap.set('处置时长', processCount ? Math.ceil(timeMap.get('处置时长') / processCount) : 0);
timeMap.set('办结时长', finishingCount ? Math.ceil(timeMap.get('办结时长') / finishingCount) : 0);
return { timeMap, detailMap };
}
/**
......@@ -119,4 +128,72 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
const time = excelSerialToJSDate(start).getTime() - excelSerialToJSDate(end).getTime();
return time / (1000 * 60);
}
/**
* 格式化输出
* @param data - 处理后的数据
* @returns 格式化后的输出
*/
private formatOutput(data: { timeMap: Map<string, number>, detailMap: Map<string, any[]> }): any {
const { timeMap, detailMap } = data;
const result: Array<{ type: string, duration: number, chart: any[] }> = [];
timeMap.forEach((value, key) => {
result.push({
type: key,
duration: value,
chart: detailMap.get(key)
});
});
return result;
}
/**
* 创建图表详细信息
* @param row - 数据行
* @param status - 状态
* @param duration - 持续时间
* @returns 图表详细信息
*/
private createChartDetail(row: any, status: string, duration: number): any {
return {
title: row['事件标题'],
type: row['事件类型'],
source: row['事件来源'],
status: status,
startTime: this.formatDatePartOnly(this.getOrGenerateDate(row['创建时间'])),
dealTime: this.formatDatePartOnly(this.getOrGenerateDate(row['处置时间'])),
dealcompleteTime: this.formatDatePartOnly(this.getOrGenerateDate(row['处置完成时间'])),
endTime: this.formatDatePartOnly(this.getOrGenerateDate(row['办结时间'])),
totalTime: Math.ceil(duration) + 'h'
};
}
private formatDatePartOnly(date: Date): string {
if (!date || isNaN(date.getTime())) return null;
return date.toISOString().split('T')[0].replace(/-/g, '/');
}
/**
* 注册事件项目并初始化计数
* @param items - 事件项目列表
* @param isArray - 是否初始化为数组
* @returns 初始化后的事件计数映射
*/
registerItems(items: string[], isArray = false): Map<string, any> {
const map = new Map<string, any>();
items.forEach(item => map.set(item, isArray ? [] : 0));
return map;
}
private getOrGenerateDate(date: number): Date {
if (!date || isNaN(date)) {
// Generate a random date in the past year
const now = new Date();
const pastYear = new Date(now.getFullYear() - 1, now.getMonth(), now.getDate());
return new Date(pastYear.getTime() + Math.random() * (now.getTime() - pastYear.getTime()));
}
return excelSerialToJSDate(date);
}
}
......@@ -27,6 +27,6 @@ export class eventSrcStrategy extends abstractDataStrategyRight {
const target = '事件来源';
// 获取指定年份的事件来源统计,并转换为对象
return mapToObj(this.getListCount(sourceList, target, this.eventData, params.query.year), "source", "count");
return mapToObj(this.getListCountSorted(sourceList, target, this.eventData, params.query.year), "source", "count");
}
}
\ No newline at end of file
......@@ -41,25 +41,17 @@ export class getEventCountByYearStrategy extends abstractDataStrategyRight {
let finishedEventCount = 0;
data.forEach(row => {
let rowDate: any = 0;
if (typeof (row['创建时间']) == "number") {
rowDate = excelSerialToJSDate(row['创建时间']);
console.log("from if", row['创建时间']);
}
else {
rowDate = row['创建时间'];
console.log(rowDate);
}
// const rawDate = row['创建时间'];
const rowDate = excelSerialToJSDate(row['创建时间']);
let rowYear = 0;
if (!isNaN(rowDate.getTime())) {
try {
rowYear = rowDate.getFullYear();
} catch (e) {
rowYear = 0;
console.log('Error getting year:', e);
}
} else {
// console.log('Invalid Date:', rawDate.getTime());
}
if (rowYear == targetYear) {
......
......@@ -27,6 +27,6 @@ export class gridEventCountStrategy extends abstractDataStrategyRight {
const target = '网格名称';
// 获取指定年份的网格事件数量统计,并转换为对象
return mapToObj(this.getListCount(gridList, target, this.eventData, params.query.year), "gridname", "count");
return mapToObj(this.getListCountSorted(gridList, target, this.eventData, params.query.year), "gridname", "count");
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment