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; }; var sortFunc = function (x, y) { if (x.ep ^ y.ep) return x.ep ? -1 : 1; return y.st - x.st; }; 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; } var tcode, t; do { tcode = alltrains.pop(); t = _.findWhere(queryResult.original, { code: tcode }); } while (!t && alltrains.length) if (!t) { checkSuggestion(); return; } 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 = []; console.log(JSON.stringify(trainStops)); 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)) { maybeAltStart.push({ code: tinfo.start.code, name: tinfo.start.name, ep: true }); } //检查各站 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; stopStatCode = stopStatCode.c; //如果停靠时间比当前的站小,也不考虑,因为这个很可能一样限售 if (getStopTime(stop) < stopTimeFrom) continue; //如果时间过久,那么也不考虑,因为会需要太久或加价太多 if (!isSpaceTimeInRange(tinfo.code, stop.start_time, stopFrom.arrive_time)) continue; //考虑 maybeAltStart.push({ code: stopStatCode, name: stop.station_name, st: getStopTime(stop) }); } } //到站? var maybeAltEnd = []; if (!tinfo.to.endpoint) { var lastStop = tstops[tstops.length - 1]; if (isSpaceTimeInRange(tinfo.code, stopTo.start_time, lastStop.arrive_time)) { maybeAltEnd.push({ code: tinfo.end.code, name: tinfo.end.name, ep: true }); } 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; eStopStatCode = eStopStatCode.c; //如果停靠时间比当前的站小,也不考虑,因为这个很可能一样限售 if (getStopTime(eStop) < stopTimeTo) continue; //如果时间过久,那么也不考虑,因为会需要太久或加价太多 if (!isSpaceTimeInRange(tinfo.code, stopTo.start_time, eStop.arrive_time)) continue; //考虑 maybeAltEnd.push({ code: eStopStatCode, name: eStop.station_name, st: getStopTime(stop) }); } } if (maybeAltEnd.length || maybeAltStart.length) { maybeAltEnd.sort(sortFunc); maybeAltStart.sort(sortFunc); suggestion.push({ code: tinfo.code, suggestion: { startAlt: maybeAltStart, endAlt: maybeAltEnd } }); } } 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; });