2014-07-31 21:30:48 +08:00
|
|
|
|
define(function (require, exports, module) {
|
|
|
|
|
var data = require("../data.js");
|
|
|
|
|
var parser = require("../platform/parser.js");
|
|
|
|
|
var sessmgr = require("../account/sessionMgr.js");
|
|
|
|
|
var EventObject = require("../platform/EventObject.js");
|
|
|
|
|
var cp = sessmgr.currentProfile;
|
|
|
|
|
var query = require("../otn/queryticket.js");
|
|
|
|
|
|
|
|
|
|
sessmgr.on("currentProfileChanged", function () {
|
|
|
|
|
cp = sessmgr.currentProfile;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var isInQuery = false;
|
|
|
|
|
var startQueryLimit = data.startTrainStationSuggestQueryLimit;
|
|
|
|
|
var isFullyQualifiedTrainCode = function (code) {
|
|
|
|
|
return /^[A-Z]?\d+$/.test(code);
|
|
|
|
|
};
|
|
|
|
|
var getHours = function (t1, t2) {
|
|
|
|
|
var x1 = /^0?(\d+):(\d)+$/.exec(t1) ? parseInt(RegExp.$1) * 60 + parseInt(RegExp.$2) : null;
|
|
|
|
|
var x2 = /^0?(\d+):(\d+)$/.exec(t2) ? parseInt(RegExp.$1) * 60 + parseInt(RegExp.$2) : null;
|
|
|
|
|
|
|
|
|
|
if (x1 == null || x2 == null)
|
|
|
|
|
return null;
|
|
|
|
|
//这里不考虑两个时刻之间跨度超越1天的情况。按理说应该不会一趟车跑了一天都没停过一个站吧。。
|
|
|
|
|
return x1 <= x2 ? x2 - x1 : x2 + 24 * 60 - x1;
|
|
|
|
|
};
|
|
|
|
|
var isSpaceTimeInRange = function (code, t1, t2) {
|
|
|
|
|
var limit = data.maxSuggestStationTimeRange[code[0]] || data.maxSuggestStationTimeRange[""];
|
|
|
|
|
var space = getHours(t1, t2);
|
|
|
|
|
return space != null && space <= limit;
|
|
|
|
|
};
|
2014-08-05 20:54:33 +08:00
|
|
|
|
var sortFunc = function (x, y) {
|
2014-08-01 21:54:26 +08:00
|
|
|
|
if (x.ep ^ y.ep)
|
|
|
|
|
return x.ep ? -1 : 1;
|
|
|
|
|
return y.st - x.st;
|
|
|
|
|
};
|
|
|
|
|
|
2014-07-31 21:30:48 +08:00
|
|
|
|
|
|
|
|
|
function TSS() {
|
|
|
|
|
EventObject.apply(this);
|
|
|
|
|
var that = this;
|
|
|
|
|
var queryResult = null;
|
|
|
|
|
var alltrains = null;
|
|
|
|
|
var trainStops = null;
|
|
|
|
|
|
|
|
|
|
var loadTrainStops = function () {
|
|
|
|
|
if (!alltrains || !alltrains.length) {
|
|
|
|
|
checkSuggestion();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-05 20:54:33 +08:00
|
|
|
|
var tcode, t;
|
|
|
|
|
do {
|
|
|
|
|
tcode = alltrains.pop();
|
|
|
|
|
t = _.findWhere(queryResult.original, { code: tcode });
|
|
|
|
|
} while (!t && alltrains.length)
|
|
|
|
|
if (!t) {
|
|
|
|
|
checkSuggestion();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-07-31 21:30:48 +08:00
|
|
|
|
query.queryTrainStop(t.id, t.from.code, t.to.code, t.date)
|
|
|
|
|
.done(function (stopinfo) {
|
|
|
|
|
trainStops[t.code] = {
|
|
|
|
|
info: t,
|
|
|
|
|
stops: stopinfo
|
|
|
|
|
};
|
|
|
|
|
loadTrainStops();
|
|
|
|
|
}).fail(loadTrainStops);
|
|
|
|
|
};
|
|
|
|
|
var getStopTime = function (stop) {
|
|
|
|
|
return /^(\d+)分钟$/.exec(stop.stopover_time) && parseInt(RegExp.$1) || 0;
|
|
|
|
|
};
|
|
|
|
|
var checkSuggestion = function () {
|
|
|
|
|
var suggestion = [];
|
|
|
|
|
|
|
|
|
|
for (var ts in trainStops) {
|
|
|
|
|
var tinfo = trainStops[ts].info;
|
|
|
|
|
var tstops = trainStops[ts].stops;
|
|
|
|
|
|
|
|
|
|
//查找在当前站的停止时间
|
|
|
|
|
var stopFrom = _.findWhere(tstops, { station_name: tinfo.from.name });
|
|
|
|
|
var stopTo = _.findWhere(tstops, { station_name: tinfo.to.name });
|
|
|
|
|
var stopTimeFrom = getStopTime(stopFrom);
|
|
|
|
|
var stopTimeTo = getStopTime(stopTo);
|
|
|
|
|
|
|
|
|
|
//发站?
|
|
|
|
|
var maybeAltStart = [];
|
|
|
|
|
if (!tinfo.from.endpoint) {
|
|
|
|
|
if (isSpaceTimeInRange(tinfo.code, tstops[0].start_time, stopFrom.arrive_time)) {
|
2014-08-01 21:54:26 +08:00
|
|
|
|
maybeAltStart.push({ code: tinfo.start.code, name: tinfo.start.name, ep: true });
|
2014-07-31 21:30:48 +08:00
|
|
|
|
}
|
|
|
|
|
//检查各站
|
|
|
|
|
for (var i = 1; i < tstops.length; i++) {
|
|
|
|
|
var stop = tstops[i];
|
|
|
|
|
var stopStatCode = data.citynameMap[stop.station_name];
|
|
|
|
|
|
|
|
|
|
//无法推荐当前站、过路站以及无法查到的站
|
|
|
|
|
if (stop.isEnabled || !stopStatCode || stop === stopFrom)
|
|
|
|
|
break;
|
2014-08-01 21:54:26 +08:00
|
|
|
|
stopStatCode = stopStatCode.c;
|
2014-07-31 21:30:48 +08:00
|
|
|
|
|
|
|
|
|
//如果停靠时间比当前的站小,也不考虑,因为这个很可能一样限售
|
|
|
|
|
if (getStopTime(stop) < stopTimeFrom)
|
|
|
|
|
continue;
|
|
|
|
|
//如果时间过久,那么也不考虑,因为会需要太久或加价太多
|
|
|
|
|
if (!isSpaceTimeInRange(tinfo.code, stop.start_time, stopFrom.arrive_time))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
//考虑
|
2014-08-01 21:54:26 +08:00
|
|
|
|
maybeAltStart.push({ code: stopStatCode, name: stop.station_name, st: getStopTime(stop) });
|
2014-07-31 21:30:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//到站?
|
|
|
|
|
var maybeAltEnd = [];
|
|
|
|
|
if (!tinfo.to.endpoint) {
|
|
|
|
|
var lastStop = tstops[tstops.length - 1];
|
|
|
|
|
if (isSpaceTimeInRange(tinfo.code, stopTo.start_time, lastStop.arrive_time)) {
|
2014-08-01 21:54:26 +08:00
|
|
|
|
maybeAltEnd.push({ code: tinfo.end.code, name: tinfo.end.name, ep: true });
|
2014-07-31 21:30:48 +08:00
|
|
|
|
}
|
|
|
|
|
for (var j = tinfo.length - 2; j >= 0; j--) {
|
|
|
|
|
var eStop = tstops[i];
|
|
|
|
|
var eStopStatCode = data.citynameMap[eStop.station_name];
|
|
|
|
|
|
|
|
|
|
//无法推荐当前站、过路站以及无法查到的站
|
|
|
|
|
if (eStop.isEnabled || !eStopStatCode || eStop === stopTo)
|
|
|
|
|
break;
|
2014-08-01 21:54:26 +08:00
|
|
|
|
eStopStatCode = eStopStatCode.c;
|
2014-07-31 21:30:48 +08:00
|
|
|
|
|
|
|
|
|
//如果停靠时间比当前的站小,也不考虑,因为这个很可能一样限售
|
|
|
|
|
if (getStopTime(eStop) < stopTimeTo)
|
|
|
|
|
continue;
|
|
|
|
|
//如果时间过久,那么也不考虑,因为会需要太久或加价太多
|
|
|
|
|
if (!isSpaceTimeInRange(tinfo.code, stopTo.start_time, eStop.arrive_time))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
//考虑
|
2014-08-01 21:54:26 +08:00
|
|
|
|
maybeAltEnd.push({ code: eStopStatCode, name: eStop.station_name, st: getStopTime(stop) });
|
2014-07-31 21:30:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-14 21:33:47 +08:00
|
|
|
|
if (maybeAltEnd.length || maybeAltStart.length) {
|
|
|
|
|
maybeAltEnd.sort(sortFunc);
|
|
|
|
|
maybeAltStart.sort(sortFunc);
|
|
|
|
|
suggestion.push({
|
|
|
|
|
code: tinfo.code,
|
|
|
|
|
suggestion: {
|
|
|
|
|
startAlt: maybeAltStart,
|
|
|
|
|
endAlt: maybeAltEnd
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2014-07-31 21:30:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (suggestion.length)
|
|
|
|
|
that.fireEvent("trainSuggestion", suggestion);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.setQueryResult = function (result, queryCount) {
|
|
|
|
|
if (queryCount < startQueryLimit || isInQuery)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
isInQuery = true;
|
|
|
|
|
queryResult = result;
|
|
|
|
|
trainStops = {};
|
|
|
|
|
that.checkTrainSuggestion();
|
|
|
|
|
}
|
|
|
|
|
this.clearQueryResultCache = function () {
|
|
|
|
|
queryResult = null;
|
|
|
|
|
isInQuery = false;
|
|
|
|
|
trainStops = null;
|
|
|
|
|
alltrains = null;
|
|
|
|
|
};
|
|
|
|
|
this.checkTrainSuggestion = function () {
|
|
|
|
|
alltrains = _.filter(cp.selectedTrain || [], function (code) {
|
|
|
|
|
if (!isFullyQualifiedTrainCode(code))
|
|
|
|
|
return false;
|
|
|
|
|
var t = _.findWhere(queryResult.original, { code: code });
|
|
|
|
|
if (!t || (t.from.endpoint && t.to.endpoint))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
if (!alltrains.length)
|
|
|
|
|
return;
|
|
|
|
|
loadTrainStops();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSS.prototype = Object.create(EventObject);
|
|
|
|
|
TSS.constructor = TSS;
|
|
|
|
|
|
|
|
|
|
var ctx = {
|
|
|
|
|
TSS: new TSS(),
|
|
|
|
|
setQueryResult: function (result, queryCount) {
|
|
|
|
|
ctx.TSS.setQueryResult(result, queryCount);
|
|
|
|
|
},
|
|
|
|
|
clearQueryResultCache: function () {
|
|
|
|
|
ctx.TSS.clearQueryResultCache();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
Object.defineProperty(ctx.TSS, "isInSuggestQuery", {
|
|
|
|
|
get: function () {
|
|
|
|
|
return isInQuery;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return ctx;
|
2014-08-05 20:54:33 +08:00
|
|
|
|
});
|