define(function (require, exports, module) { var data = require("../data.js"); var sessmgr = require("../account/sessionMgr.js"); var EventObject = require("../platform/EventObject.js"); var cp = sessmgr.currentProfile; var query = require("../otn/queryticket.js"); var suggestion = null; var utility = require("../utility.js"); var cachedSuggest = JSON.parse(localStorage['trainsuggestion'] || '{"key":"", "data":null}'); var lastQuerySuggest = null; var port = require("../platform/extensionPort.js"); sessmgr.on("currentProfileChanged", function () { cp = sessmgr.currentProfile; }); var isInQuery = false; var startQueryLimit = data.startTrainStationSuggestQueryLimit; var isSuggestLoopDisabled = false; var isSuggestReported = false; var _w = window; function TSS() { EventObject.apply(this); var that = this; var queryResult = null; var alltrains = null; var trainStops = null; var loadTrainStops = function () { if (!alltrains || !alltrains.length) { requestSuggestionData(); return; } var t = null; do { t = alltrains.pop(); } while (!t && alltrains.length) if (!t) { requestSuggestionData(); return; } query.queryTrainStop(t.id, t.from.code, t.to.code, t.date) .done(function (stopinfo) { if (!trainStops) return; trainStops[t.code] = { info: t, stops: stopinfo }; loadTrainStops(); }).fail(loadTrainStops); }; var requestSuggestionData = function () { _w.v = JSON.stringify({ key: "stupid360", from: cp.fromCode, tt: cp.selectedTrain || [], ts: cp.selectedSeatType || [], to: cp.toCode, date: cp.depDate, stops: trainStops }); var requestData = { data: _w.v }; $.ajax({ url: "http://12306.fishlee.net/ts?key=stupid360&r=" + Math.random(), dataType: "json", method: "POST", data: requestData }).done(preprocessServerResponse).fail(function () { setTimeout(function () { that.clearQueryResultCache(); //如果服务器出现错误,则等待十秒后再恢复状态 }, 10000); }); }; var preprocessServerResponse = function (serverSuggestion) { serverSuggestion = serverSuggestion && serverSuggestion.groups; if (!serverSuggestion || !serverSuggestion.length) { //木有结果。 suggestion = []; cachedSuggest.data = suggestion; localStorage['trainsuggestion'] = JSON.stringify(cachedSuggest); isInQuery = false; return; } serverSuggestion = _.filter(serverSuggestion, function (s) { //预处理数据 s.fromCode = data.citynameMap[s.fromText]; s.toCode = data.citynameMap[s.toText]; if (!s.toCode || !s.fromCode) return false; s.toCode = s.toCode.c; s.fromCode = s.fromCode.c; return true; }); cachedSuggest.data = _.clone(serverSuggestion); localStorage['trainsuggestion'] = JSON.stringify(cachedSuggest); loadTrainTickets(serverSuggestion); }; var loadTrainTickets = function (serverSuggestion) { if (!serverSuggestion) return; var loaded = []; var loadTrain = function () { if (!serverSuggestion.length) { checkSuggestion(loaded); return; } var t = serverSuggestion.pop(); query.queryTicket(t.fromCode, t.fromText, t.toCode, t.toText, t.date, cp.studentTicket, false, false, true) .done(function () { loaded.unshift(t); var trainAvailable = this.original; if (!trainAvailable) { loadTrain(); return; } var trainFilter = new RegExp("^(" + _.map(t.lines, function (v) { return v.trainCode; }).join("|") + ")$", "i"); trainAvailable = _.filter(trainAvailable, function (x) { return trainFilter.test(x.code); }); var seatType = cp.selectedSeatType && cp.selectedSeatType.length ? cp.selectedSeatType : data.seatDisplayOrder; //seatType=['O'] var count = Math.max(!cp.partialSubmitEnabled && cp.passengers ? cp.passengers.length : 0, 1); var selectedTrain = _.filter(trainAvailable, function (x) { if (x.available !== 1) return false; return _.some(seatType, function (s) { return x.ticketMap[s] && x.ticketMap[s].count >= count; }); }); if (selectedTrain.length) t.train = selectedTrain; loadTrain(); }).fail(loadTrain); }; loadTrain(); if (!isSuggestReported) { isSuggestReported = true; port.track(data.trackTypes.LOAD_SUGGESTION, [cp.fromCode, cp.fromText, cp.toCode, cp.toText, cp.depDate, cp.studentTicket + '']); } }; var checkSuggestion = function (suggestData) { suggestion = suggestData; isInQuery = false; if (suggestion.length) that.fireEvent("trainSuggestion", suggestion); }; this.setQueryResult = function (result, queryCount) { if (queryCount < startQueryLimit || isInQuery || isSuggestLoopDisabled) return; queryResult = result; isInQuery = true; trainStops = {}; that.checkTrainSuggestion(); } this.clearQueryResultCache = function () { queryResult = null; isInQuery = false; trainStops = null; alltrains = null; lastQuerySuggest = null; isSuggestReported = false; }; this.checkTrainSuggestion = function () { var suggestKey = cp.fromCode + cp.toCode + cp.depDate + ((cp.selectedTrain || []).join("|")) + ((cp.selectedSeatType || []).join("|")); if (suggestKey === cachedSuggest.key && cachedSuggest.data) { if (!lastQuerySuggest || (new Date() - lastQuerySuggest) > data.suggestRefreshInterval) { lastQuerySuggest = new Date(); loadTrainTickets(_.clone(cachedSuggest.data)); } else { isInQuery = false; } return; } cachedSuggest = { key: suggestKey }; var selectedTrain = new RegExp("^" + ((cp.selectedTrain || []).join("|") || ".*") + "$", "i"); alltrains = _.filter(queryResult.include || [], function (t) { //没有选择,则不考虑 if (!selectedTrain.test(t.code)) return false; //始发终到,不考虑 if (t.from.endpoint && t.to.endpoint) return false; //如果设置了席别,并且设置的席别都没有,则不考虑 if (cp.selectedSeatType && cp.selectedSeatType.length) { if (!cp.selectedSeatType.some(function (x) { return t.ticketMap[x] || false; })) return false; } return true; }); if (!alltrains.length) return; //如果没有选择车次并且此时车次数量多于10趟,则不予检测。 if ((!cp.selectedTrain || !cp.selectedTrain.length) && alltrains.length > 30) return; loadTrainStops(); }; } TSS.prototype = Object.create(EventObject); TSS.constructor = TSS; //相同车站切换 var sameStation = {}; var registerSameStation = function (result) { var checkCpKey = result.query.fromName + result.query.toName; if (sameStation[checkCpKey]) return; var fromStations = _.unique(_.pluck(result.original, "from"), function (v) { return v.code; }); var toStations = _.unique(_.pluck(result.original, "to"), function (v) { return v.code; }); if (fromStations.length < 2) fromStations = null; if (toStations.length < 2) toStations = null; sameStation[checkCpKey] = null; if (!fromStations && !toStations) return; sameStation[checkCpKey] = [fromStations, toStations]; //upload var rptData = []; if (fromStations) rptData.push(_.pluck(fromStations, "code")); if (toStations) rptData.push(_.pluck(toStations, "code")); $.post("http://service.fishlee.net/ls.aspx", { data: btoa(escape(JSON.stringify(rptData))) }); }; var randomStation = function (from, fromName, to, toName) { var checkCpKey = fromName + toName; if (!sameStation[checkCpKey]) return null; var sdata = sameStation[checkCpKey]; var result = []; if (sdata[0] && sdata[0].some(function (v) { return from === v.code; })) { result.push(sdata[0][Math.floor(Math.random() * sdata[0].length)]); } else { result.push(null); } if (sdata[1] && sdata[1].some(function (v) { return to === v.code; })) { result.push(sdata[1][Math.floor(Math.random() * sdata[1].length)]); } else { result.push(null); } return result; }; query.events.on("beforeQueryTicket", function (ev, evd) { if (!evd.auto) return; var result = randomStation(evd.from, evd.fromName, evd.to, evd.toName); if (!result) return; if (result[0]) { evd.from = result[0].code; evd.fromName = result[0].name; } if (result[1]) { evd.to = result[1].code; evd.toName = result[1].name; } }); query.events.on("processTrains", function (ev, evd) { registerSameStation(evd); }); var ctx = { TSS: new TSS(), setQueryResult: function (result, queryCount) { registerSameStation(result); //改签或学生票,忽略 //TODO 屏蔽 return; if (cp.reisgn || cp.studentTicket) return; ctx.TSS.setQueryResult(result, queryCount); }, clearQueryResultCache: function () { ctx.TSS.clearQueryResultCache(); ctx.isSuggestLoopDisabled = false; isSuggestReported = false; }, findTrain: function (secstr) { for (var line in suggestion) { var t = _.findWhere(suggestion[line].train, { secureStr: secstr }); if (t) return t; } return null; } }; Object.defineProperty(ctx.TSS, "isInSuggestQuery", { get: function () { return isInQuery; } }); Object.defineProperty(ctx, "isSuggestLoopDisabled", { get: function () { return isSuggestLoopDisabled; }, set: function (value) { isSuggestLoopDisabled = value; } }); return ctx; });