Commit 710a4e27 by Leo Zheng

使用策略模式处理接口请求

parent cd158fc6
/**寿州古城智慧调度事件态势感知 */ /**寿州古城智慧调度事件态势感知 */
import { DataExtractor } from "../util/dataExtractor"; import { DataExtractor } from "../util/dataExtractor";
import { strategyFactory } from "./strategies/strategyFactory";
/** /**
* 主界面 * 主界面
...@@ -7,15 +8,9 @@ import { DataExtractor } from "../util/dataExtractor"; ...@@ -7,15 +8,9 @@ import { DataExtractor } from "../util/dataExtractor";
* @param res * @param res
*/ */
export function getData(req, res) { export function getData(req, res) {
// TODO: 和前端讨论具体数据需求
/**填充数据格式处理 */ /**填充数据格式处理 */
const dataExtractor = DataExtractor.getInstance(); const strategy = strategyFactory.createStrategy(req.query.content)
const ret = dataExtractor.getData(req.query.fileName, req.query.sheetName); let ret = strategy.execute(req);
res.send(ret); res.send(ret);
} }
......
import { DataExtractor } from "../../util/dataExtractor";
export interface dataStrategy {
execute(params?: any): any;
}
\ No newline at end of file
import { dataStrategy } from "./dataStrategy";
import { DataExtractor } from "../../util/dataExtractor";
export class allEventDataStrategy implements dataStrategy {
extractor = DataExtractor.getInstance();
static readonly fileName = '寿州古城.xlsx';
static readonly sheetName = '指挥调度系统';
execute(): any {
return this.extractor.getData(allEventDataStrategy.fileName, allEventDataStrategy.sheetName);
}
}
\ No newline at end of file
import { dataStrategy } from "./dataStrategy";
import { DataExtractor } from "../../util/dataExtractor";
import { randomStatusGenerator } from "../../util/randomStatusGenerator";
import excelSerialToJSDate from "../../util/excelDateToJSDate";
export class sightVisitorFlowByDayStrategy implements dataStrategy {
extractor = DataExtractor.getInstance();
static readonly fileName = '票务系统.xlsx';
static readonly sheetName = '票务系统-订单主表';
execute(params?: any): any {
if (!params || !params.query || !params.query.date) {
throw new Error("Data parameter is required.")
}
let sightData = this.extractor.getData(sightVisitorFlowByDayStrategy.fileName, sightVisitorFlowByDayStrategy.sheetName);
return this.getVisitorFlowByDay(sightData, params.query.date);
}
private getVisitorFlowByDay(data: any, date: string) {
const visitorCount: { [sight: string]: { count: number, status: string } } = {};
data.forEach(row => {
const rowDate = excelSerialToJSDate(row['游玩时间']);
const rowDateString = rowDate.toISOString().split('T')[0];
const sight = row['景点名称'];
if (rowDateString == date) {
if (!visitorCount[sight]) {
visitorCount[sight] = {count: 0, status: randomStatusGenerator.getRandomStatus()};
}
visitorCount[sight].count++;
}
});
return visitorCount;
}
}
import { dataStrategy } from "./dataStrategy";
import { DataExtractor } from "../../util/dataExtractor";
import excelDateToJSDate from "../../util/excelDateToJSDate";
import excelSerialToJSDate from "../../util/excelDateToJSDate";
import mapToObj from "../../util/mapToObj";
export class sightVisitorFlowByHourStrategy implements dataStrategy {
extractor = DataExtractor.getInstance();
static readonly fileName = '票务系统.xlsx';
static readonly sheetName = '票务系统-订单主表';
execute(params?: any): any {
if (!params || !params.query || !params.query.date || !params.query.sight) {
throw new Error('Date and sight parameters are required');
}
let sightData = this.extractor.getData(sightVisitorFlowByHourStrategy.fileName, sightVisitorFlowByHourStrategy.sheetName);
return mapToObj(this.getVisitorFlowByHour(sightData, params.query.sight, params.query.date));
}
private getVisitorFlowByHour(data: any, sight: string, date: string) {
const visitorCount: Map<number, number> = new Map();
for (let hour = 0; hour < 24; hour++) {
visitorCount.set(hour, 0);
}
data.forEach(row => {
const rowDate = excelSerialToJSDate(row['游玩时间']);
const rowHour = rowDate.getHours();
let rowDateString = '';
try {
rowDateString = rowDate.toISOString().split('T')[0];
}
catch (e) {
rowDateString = 'invalid time'
}
const rowSight = row['景点名称'];
rowDate.setHours(rowDate.getHours() - 8);
if (rowDateString == date && rowSight == sight) {
if (visitorCount.has(rowHour - 8)) {
visitorCount.set(rowHour - 8, (visitorCount.get(rowHour) || 0) + 1);
console.log("rowdate", rowDate);
// console.log()
}
}
});
return visitorCount;
}
}
import { dataStrategy } from "./dataStrategy";
import { allEventDataStrategy } from "./eventDataStrategy";
import { sightVisitorFlowByDayStrategy } from "./sightVisitorFlowByDayStrategy";
import { gateStatusStrategy } from "./gateStatusStrategy";
import { sightVisitorFlowByHourStrategy } from "./sightVisitorFlowPerHourStrategy";
export class strategyFactory {
private static strategies: { [key: string]: new () => dataStrategy } = {
'allEvents': allEventDataStrategy,
'sightVisitorFlowByDay': sightVisitorFlowByDayStrategy,
'gateStatus': gateStatusStrategy,
'sightVisitorFlowPerHour': sightVisitorFlowByHourStrategy
};
static createStrategy(type: string): dataStrategy {
const StrategyClass = this.strategies[type];
if (!StrategyClass) {
throw new Error('Invalid strategy type');
}
return new StrategyClass();
}
static registerStrategy(type: string, strategy: new () => dataStrategy) {
this.strategies[type] = strategy;
}
}
\ No newline at end of file
import { httpServer } from "./net/http_server"; import { httpServer } from "./net/http_server";
import { initConfig, systemConfig } from "./config/serverConfig"; import { initConfig, systemConfig } from "./config/serverConfig";
import { DataExtractor } from "./util/dataExtractor";
let fs = require('fs'); let fs = require('fs');
async function lanuch() { async function lanuch() {
/**初始化xml文件配置 */ /**初始化xml文件配置 */
await initConfig(); await initConfig();
const de = DataExtractor.getInstance();
httpServer.createServer( systemConfig.port ); httpServer.createServer( systemConfig.port );
console.log('This indicates that the server is started successfully.'); console.log('This indicates that the server is started successfully.');
} }
......
...@@ -11,6 +11,14 @@ export function httpErrorHandler(err, req, res, next) { ...@@ -11,6 +11,14 @@ export function httpErrorHandler(err, req, res, next) {
res.success({success: false, msg: err.message, code: 502}); res.success({success: false, msg: err.message, code: 502});
next(); next();
} }
else if (err.message == "Data parameter is required.") {
res.success({success: false, msg: err.message, code: 503});
next();
}
else if (err.message == "Date and sight parameters are required.") {
res.success({success: false, msg: err.message, code: 504});
next();
}
else { else {
res.success({success:false, msg: err.message, code: 500}); res.success({success:false, msg: err.message, code: 500});
next(); next();
......
...@@ -6,7 +6,7 @@ import * as fallback from 'express-history-api-fallback'; ...@@ -6,7 +6,7 @@ import * as fallback from 'express-history-api-fallback';
import * as path from "path"; import * as path from "path";
import { watch } from '../middleware/watch'; import { watch } from '../middleware/watch';
import { httpErrorHandler } from '../middleware/httpErrorHandler'; import { httpErrorHandler } from '../middleware/httpErrorHandler';
import { DataExtractor } from "../util/dataExtractor";
export class httpServer { export class httpServer {
static createServer(port:number) { static createServer(port:number) {
...@@ -48,6 +48,7 @@ export class httpServer { ...@@ -48,6 +48,7 @@ export class httpServer {
httpServer.listen(port); httpServer.listen(port);
console.log('server listen on port:'+port); console.log('server listen on port:'+port);
DataExtractor.getInstance();
return httpServer; return httpServer;
} }
......
export default function excelSerialToJSDate(serial: number): Date {
const EXCEL_EPOCH = 25569;
const MS_PER_DAY = 86400000;
// Split the excelDate into integer and fractional parts
const days = Math.floor(serial);
const fractionalDay = serial - days;
// Convert to milliseconds
const jsDateMilliseconds = (days - EXCEL_EPOCH) * MS_PER_DAY + fractionalDay * MS_PER_DAY;
return new Date(jsDateMilliseconds);
}
\ No newline at end of file
export default function mapToObj(map) {
let Obj: { [key: string]: string } = {};
map.forEach((value, key) => {
Obj[key] = value;
});
return Obj;
}
\ No newline at end of file
export class randomStatusGenerator {
private static statuses: string[] = ['正常', '拥挤', '通畅'];
static getRandomStatus(): string {
const randomIndex = Math.floor(Math.random() * randomStatusGenerator.statuses.length);
return this.statuses[randomIndex];
}
}
\ 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