import BaseAlgorithm from '../core/BaseAlgorithm' import TimePeriod from '../model/TimePeriod' import Window from '../core/Window' export default class UserUsedFlowAlgorithm extends BaseAlgorithm { compute(content: any, window: Window): void { let result = window.getResult() let temp = window.getTemp() let { finished, countryZh, connEstablished, userName } = content if (finished != "true") { return } let connectSuccess = false if (connEstablished == 1) { connectSuccess = true } const localInput = parseInt(content["localInput"]) const localOutput = parseInt(content["localOutput"]) const remoteInput = parseInt(content["remoteInput"]) const remoteOutput = parseInt(content["remoteOutput"]) const connCreateTime = parseInt(content["connCreateTime"]) const connCloseTime = parseInt(content["connCloseTime"]) if (localInput + localOutput > 0 && remoteInput + remoteOutput > 0) { connectSuccess = true } // 异常数据 if (!connectSuccess || connCloseTime == 0 || connCreateTime > connCloseTime) { return } let users = temp[countryZh] if (!users) { users = {} } // 取出某个用户缓存的使用时间段 let timePeriods = users[userName] if (!timePeriods) { timePeriods = [] } const period = { begin: connCreateTime, end: connCloseTime } // 是否清除过时间段 let alreadyEmptyTimePeriods = false if (timePeriods.length != 0) { let lastTimePeriod = timePeriods[timePeriods.length - 1] // 取出所有时间段里的最后一个时间段来比较,如果已经过去五分钟,结算之前的连接时间 if ((connCloseTime - lastTimePeriod.end) > 1000 * 60 * 5) { // 清空之前的连接时间 alreadyEmptyTimePeriods = true timePeriods = [] } } timePeriods.push(period) timePeriods = this.mergePeriods(timePeriods) users[userName] = timePeriods temp[countryZh] = users let userFlowInfos = result[countryZh] if (!userFlowInfos) { userFlowInfos = {} } // 如果是清理过时间段的时间 const duration = this.getDuration(timePeriods) let userFlowInfo = userFlowInfos[userName] if (!userFlowInfo) { userFlowInfo = { duration, tx: remoteOutput, rx: remoteInput } } else { if (alreadyEmptyTimePeriods) { userFlowInfo.duration += duration } else { // 时长每次都重算 userFlowInfo.duration = duration } userFlowInfo.tx += remoteOutput userFlowInfo.rx += remoteInput } userFlowInfos[userName] = userFlowInfo result[countryZh] = userFlowInfos window.setResult(result) window.setTemp(temp) } // 合并时间段 mergePeriods(periods: TimePeriod[]): TimePeriod[] { if (!periods || periods.length == 0) { return periods } let newPeriods: TimePeriod[] = [] // 先将时间段按开始时间排序 periods.sort((period1: TimePeriod, period2: TimePeriod) => { return period1.begin - period2.begin }) let pre = periods[0] for (let i = 1; i < periods.length; i++) { let curr = periods[i] // 两个时间段有交集,临时合并 if (pre.end >= curr.begin) { pre = new TimePeriod(pre.begin, this.max(pre.end, curr.end)) } else { newPeriods.push(pre) pre = curr } } newPeriods.push(pre) return newPeriods } // 对合并完成后的时间段求时长, 返回秒数 getDuration(periods: TimePeriod[]): number { let duration = 0 for (let i = 0; i < periods.length; i++) { duration += (periods[i].end - periods[i].begin) } return Math.round(duration / 1000) } hasInterest(t1: number, t2: number, t3: number, t4: number): boolean { return (t3 < t2) && (t1 < t4) } max(t1: number, t2: number) { return t1 > t2 ? t1 : t2 } min(t1: number, t2: number) { return t1 < t2 ? t1 : t2 } }