Light12306/Web12306/js/otn/trainstationsuggest.js
2015-12-03 19:35:30 +08:00

369 lines
10 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: data.trainSuggestApi + "?key=stupid360&r=" + Math.random(),
dataType: "json",
method: "POST",
data: requestData
}).done(preprocessServerResponse).fail(function () {
setTimeout(function () {
that.clearQueryResultCache();
//如果服务器出现错误则等待30分钟后再恢复状态
}, 1000*60*30);
//直接当没有响应内容处理。
preprocessServerResponse();
});
};
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 hasid = _.some(t.lines, function (l) {
return l.tid;
});
var trainFilter = new RegExp("^(" + _.map(t.lines, function (v) {
return hasid ? v.tid : v.trainCode;
}).join("|") + ")$", "i");
trainAvailable = _.filter(trainAvailable, function (x) {
return trainFilter.test(hasid ? x.id : 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;
if (_.some(seatType, function (s) {
return x.ticketMap[s] && x.ticketMap[s].count >= count;
})) {
if (hasid) {
_.each(t.lines, function (ti) {
if (ti.tid === x.id) {
ti.trainAlias = ti.trainAlias || [ti.trainCode];
ti.trainAlias.push(x.code);
ti.trainAlias = _.uniq(ti.trainAlias);
ti.trainCode = ti.trainAlias.join("/");
}
});
}
return true;
}
return false;
});
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;
//如果没有选择车次并且此时车次数量多于30趟则不予检测。
if ((!cp.selectedTrain || !cp.selectedTrain.length) && alltrains.length > 30)
return;
loadTrainStops();
};
}
TSS.prototype = Object.create(EventObject);
TSS.constructor = TSS;
//相同车站切换
var sameStation = JSON.parse(localStorage["ss_report"] || "{}");
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];
localStorage["ss_report"] = JSON.stringify(sameStation);
//upload
var rptData = [];
if (fromStations)
rptData.push(_.pluck(fromStations, "code"));
if (toStations)
rptData.push(_.pluck(toStations, "code"));
$.post(data.stationReportApi, {
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);
//改签或学生票,忽略
if (cp.resign || 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;
});