Light12306/Web12306/js/otn/trainstationsuggest.js
2014-12-02 21:13:25 +08:00

352 lines
9.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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://12306.fishlee.net/tt/ls2", {
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;
});