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 { ...@@ -29,33 +29,9 @@ export class allEventDataStrategy extends abstractDataStrategyMid {
* @returns 事件的数据。 * @returns 事件的数据。
*/ */
execute(): any { execute(): any {
let eventData = this.extractor.getData(allEventDataStrategy.fileName, allEventDataStrategy.sheetName); const eventData = this.extractor.getData(allEventDataStrategy.fileName, allEventDataStrategy.sheetName);
this.removeUnusedColumns(eventData); const formattedData = this.formatDataForFrontend(eventData);
return this.formatDataForFrontend(eventData); return formattedData;
}
/**
* 移除数据中前端不使用的列
* @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]);
}
});
});
} }
/** /**
...@@ -66,22 +42,20 @@ export class allEventDataStrategy extends abstractDataStrategyMid { ...@@ -66,22 +42,20 @@ export class allEventDataStrategy extends abstractDataStrategyMid {
private formatDataForFrontend(data: any): any { private formatDataForFrontend(data: any): any {
return data.map(row => { return data.map(row => {
let formattedRow: { [key: string]: any } = {}; let formattedRow: { [key: string]: any } = {};
Object.keys(row).forEach(key => {
allEventDataStrategy.RELEVANTINFO.forEach(key => {
const translatedKey = allEventDataStrategy.KEY_MAP[key]; const translatedKey = allEventDataStrategy.KEY_MAP[key];
let value = row[key]; let value = row[key];
// Format date if key is one of the date fields if (['创建时间', '处置时间', '处置完成时间', '办结时间'].includes(key) && value) {
if (['creationTime', 'dispositionTime', 'dispositionCompletionTime', 'closureTime'].includes(translatedKey) && value) { const date = excelSerialToJSDate(value);
value = new Date(value).toLocaleString('zh-CN', { hour12: false }).replace(/\//g, '-').replace(',', ''); const datePart = date.toISOString().split('T')[0].replace(/-/g, '/');
} const timePart = date.toTimeString().split(' ')[0].substring(0, 8);
value = `${datePart} ${timePart}`;
// Only add non-null values to the formatted row
if (value !== null) {
formattedRow[translatedKey] = value;
} }
formattedRow[translatedKey] = value !== undefined ? value : null;
}); });
// Add detail section with all time fields and their corresponding statuses
formattedRow.detail = this.constructDetailSection(formattedRow); formattedRow.detail = this.constructDetailSection(formattedRow);
return formattedRow; return formattedRow;
...@@ -94,43 +68,36 @@ export class allEventDataStrategy extends abstractDataStrategyMid { ...@@ -94,43 +68,36 @@ export class allEventDataStrategy extends abstractDataStrategyMid {
* @returns 详细信息部分 * @returns 详细信息部分
*/ */
private constructDetailSection(row: { [key: string]: any }): any { private constructDetailSection(row: { [key: string]: any }): any {
const details: any = {}; const details: any = [];
if (row.creationTime) { if (row.creationTime) {
details.creationTime = { details.push({
time: row.creationTime, time: row.creationTime,
status: '待调度' status: '待调度'
}; });
} }
if (row.dispositionTime) { if (row.dispositionTime) {
details.dispositionTime = { details.push({
time: row.dispositionTime, time: row.dispositionTime,
status: '处置中' status: '处置中'
}; });
} }
if (row.dispositionCompletionTime) { if (row.dispositionCompletionTime) {
details.dispositionCompletionTime = { details.push({
time: row.dispositionCompletionTime, time: row.dispositionCompletionTime,
status: '已处置' status: '已处置'
}; });
} }
if (row.closureTime) { if (row.closureTime) {
details.closureTime = { details.push({
time: row.closureTime, time: row.closureTime,
status: '已办结' status: '已办结'
}; });
} }
// Remove any null detail fields return details;
Object.keys(details).forEach(key => {
if (details[key].time === null) {
delete details[key];
}
});
return Object.values(details);
} }
} }
...@@ -66,16 +66,13 @@ export abstract class abstractDataStrategyRight implements dataStrategy { ...@@ -66,16 +66,13 @@ export abstract class abstractDataStrategyRight implements dataStrategy {
return eventCount; 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) { protected getListCount(list: string[], target: string, data: any, year: string) {
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear();
...@@ -83,16 +80,7 @@ protected getListCount(list: string[], target: string, data: any, year: string) ...@@ -83,16 +80,7 @@ protected getListCount(list: string[], target: string, data: any, year: string)
const count = this.registerItems(list); const count = this.registerItems(list);
data.forEach(row => { data.forEach(row => {
// const rowDate = excelSerialToJSDate(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 rowYear = rowDate.getFullYear(); const rowYear = rowDate.getFullYear();
if (rowYear == targetYear) { if (rowYear == targetYear) {
count.set(row[target], (count.get(row[target]) || 0) + 1); count.set(row[target], (count.get(row[target]) || 0) + 1);
...@@ -112,9 +100,38 @@ protected getListCount(list: string[], target: string, data: any, year: string) ...@@ -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 count.set(key, Math.floor(Math.random() * 10) + 1); // Random number between 1 and 10
}); });
} }
console.log(allCountsZero ? "randomly generating" : "excel data");
return count; 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 { ...@@ -42,13 +42,8 @@ export class eventMonthDistributionStrategy extends abstractDataStrategyRight {
} }
data.forEach(row => { data.forEach(row => {
let rowDate: any = 0;
if (typeof (row['创建时间']) == "number") { const rowDate = excelSerialToJSDate(row['创建时间']);
rowDate = excelSerialToJSDate(row['创建时间']);
}
else {
rowDate = row['创建时间'];
}
rowDate.setHours(rowDate.getHours() - eventMonthDistributionStrategy.TIMEDIFFERENCE); rowDate.setHours(rowDate.getHours() - eventMonthDistributionStrategy.TIMEDIFFERENCE);
const rowYear = rowDate.getFullYear(); const rowYear = rowDate.getFullYear();
const rowMonth = rowDate.getMonth() + 1; // getMonth() returns 0-11 const rowMonth = rowDate.getMonth() + 1; // getMonth() returns 0-11
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
import { abstractDataStrategyRight } from "./abstractDataStrategyRight"; import { abstractDataStrategyRight } from "./abstractDataStrategyRight";
import excelSerialToJSDate from "../../../util/excelDateToJSDate"; import excelSerialToJSDate from "../../../util/excelDateToJSDate";
import getRandomNumber from "../../../util/randomNumberGenerator"; import getRandomNumber from "../../../util/randomNumberGenerator";
import mapToObj from "../../../util/mapToObj";
/** /**
* 事件处理时间策略类,继承自 abstractDataStrategyRight。 * 事件处理时间策略类,继承自 abstractDataStrategyRight。
...@@ -22,7 +21,7 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight { ...@@ -22,7 +21,7 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
this.paramsCheck(params); 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 { ...@@ -37,6 +36,9 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
const statusList = ['调度时长', '处置等待', '处置时长', '办结时长'] const statusList = ['调度时长', '处置等待', '处置时长', '办结时长']
const timeMap = this.registerItems(statusList); const timeMap = this.registerItems(statusList);
const detailMap = this.registerItems(statusList, true);
let assignCount = 0, waitCount = 0, processCount = 0, finishingCount = 0; let assignCount = 0, waitCount = 0, processCount = 0, finishingCount = 0;
data.forEach(row => { data.forEach(row => {
...@@ -48,6 +50,7 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight { ...@@ -48,6 +50,7 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
case '待调度': case '待调度':
const time = getRandomNumber(0.5, 1.7, 1); const time = getRandomNumber(0.5, 1.7, 1);
timeMap.set('调度时长', (timeMap.get('调度时长') || 0) + time); timeMap.set('调度时长', (timeMap.get('调度时长') || 0) + time);
detailMap.get('调度时长').push(this.createChartDetail(row, '待调度', time));
assignCount++; assignCount++;
break; break;
case '处置中': case '处置中':
...@@ -57,6 +60,7 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight { ...@@ -57,6 +60,7 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
waitCount--; waitCount--;
} }
timeMap.set('处置等待', (timeMap.get('处置等待') || 0) + waitTime); timeMap.set('处置等待', (timeMap.get('处置等待') || 0) + waitTime);
detailMap.get('处置等待').push(this.createChartDetail(row, '处置中', waitTime));
waitCount++; waitCount++;
break; break;
case '已处置': case '已处置':
...@@ -72,6 +76,8 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight { ...@@ -72,6 +76,8 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
} }
timeMap.set('处置等待', (timeMap.get('处置等待') || 0) + waitTime); timeMap.set('处置等待', (timeMap.get('处置等待') || 0) + waitTime);
timeMap.set('处置时长', (timeMap.get('处置时长') || 0) + processTime); timeMap.set('处置时长', (timeMap.get('处置时长') || 0) + processTime);
detailMap.get('处置等待').push(this.createChartDetail(row, '处置中', waitTime));
detailMap.get('处置时长').push(this.createChartDetail(row, '已处置', processTime));
waitCount++; waitCount++;
processCount++; processCount++;
break; break;
...@@ -94,6 +100,9 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight { ...@@ -94,6 +100,9 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
timeMap.set('处置等待', (timeMap.get('处置等待') || 0) + waitTime); timeMap.set('处置等待', (timeMap.get('处置等待') || 0) + waitTime);
timeMap.set('处置时长', (timeMap.get('处置时长') || 0) + processTime); timeMap.set('处置时长', (timeMap.get('处置时长') || 0) + processTime);
timeMap.set('办结时长', (timeMap.get('办结时长') || 0) + closeTime); 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++; waitCount++;
processCount++; processCount++;
finishingCount++; finishingCount++;
...@@ -102,11 +111,11 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight { ...@@ -102,11 +111,11 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
} }
}); });
timeMap.set('调度时长', assignCount ? timeMap.get('调度时长') / assignCount : 0); timeMap.set('调度时长', assignCount ? Math.ceil(timeMap.get('调度时长') / assignCount) : 0);
timeMap.set('处置等待', waitCount ? timeMap.get('处置等待') / waitCount : 0); timeMap.set('处置等待', waitCount ? Math.ceil(timeMap.get('处置等待') / waitCount) : 0);
timeMap.set('处置时长', processCount ? timeMap.get('处置时长') / processCount : 0); timeMap.set('处置时长', processCount ? Math.ceil(timeMap.get('处置时长') / processCount) : 0);
timeMap.set('办结时长', finishingCount ? timeMap.get('办结时长') / finishingCount : 0); timeMap.set('办结时长', finishingCount ? Math.ceil(timeMap.get('办结时长') / finishingCount) : 0);
return timeMap; return { timeMap, detailMap };
} }
/** /**
...@@ -119,4 +128,72 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight { ...@@ -119,4 +128,72 @@ export class eventProcessingTimeStrategy extends abstractDataStrategyRight {
const time = excelSerialToJSDate(start).getTime() - excelSerialToJSDate(end).getTime(); const time = excelSerialToJSDate(start).getTime() - excelSerialToJSDate(end).getTime();
return time / (1000 * 60); 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 { ...@@ -27,6 +27,6 @@ export class eventSrcStrategy extends abstractDataStrategyRight {
const target = '事件来源'; 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 { ...@@ -41,25 +41,17 @@ export class getEventCountByYearStrategy extends abstractDataStrategyRight {
let finishedEventCount = 0; let finishedEventCount = 0;
data.forEach(row => { data.forEach(row => {
let rowDate: any = 0; // const rawDate = row['创建时间'];
if (typeof (row['创建时间']) == "number") {
rowDate = excelSerialToJSDate(row['创建时间']); const rowDate = excelSerialToJSDate(row['创建时间']);
console.log("from if", row['创建时间']);
}
else {
rowDate = row['创建时间'];
console.log(rowDate);
}
let rowYear = 0; let rowYear = 0;
if (!isNaN(rowDate.getTime())) { if (!isNaN(rowDate.getTime())) {
try { try {
rowYear = rowDate.getFullYear(); rowYear = rowDate.getFullYear();
} catch (e) { } catch (e) {
rowYear = 0; rowYear = 0;
console.log('Error getting year:', e);
} }
} else {
// console.log('Invalid Date:', rawDate.getTime());
} }
if (rowYear == targetYear) { if (rowYear == targetYear) {
......
...@@ -27,6 +27,6 @@ export class gridEventCountStrategy extends abstractDataStrategyRight { ...@@ -27,6 +27,6 @@ export class gridEventCountStrategy extends abstractDataStrategyRight {
const target = '网格名称'; 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