Light12306/Web12306/js/otn/trainstationsuggest.js

367 lines
9.9 KiB
JavaScript
Raw Normal View History

2014-07-31 21:30:48 +08:00
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");
2014-08-27 23:05:50 +08:00
var suggestion = null;
var utility = require("../utility.js");
2014-08-30 01:32:27 +08:00
var cachedSuggest = JSON.parse(localStorage['trainsuggestion'] || '{"key":"", "data":null}');
var lastQuerySuggest = null;
2014-09-02 23:15:40 +08:00
var port = require("../platform/extensionPort.js");
2014-07-31 21:30:48 +08:00
sessmgr.on("currentProfileChanged", function () {
cp = sessmgr.currentProfile;
});
var isInQuery = false;
var startQueryLimit = data.startTrainStationSuggestQueryLimit;
2014-08-30 01:32:27 +08:00
var isSuggestLoopDisabled = false;
2014-09-11 22:19:33 +08:00
var isSuggestReported = false;
2014-09-01 20:24:57 +08:00
var _w = window;
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) {
2014-08-27 23:05:50 +08:00
requestSuggestionData();
2014-07-31 21:30:48 +08:00
return;
}
2014-08-30 01:32:27 +08:00
var t = null;
2014-08-05 20:54:33 +08:00
do {
2014-08-30 01:32:27 +08:00
t = alltrains.pop();
2014-08-05 20:54:33 +08:00
} while (!t && alltrains.length)
if (!t) {
2014-08-27 23:05:50 +08:00
requestSuggestionData();
2014-08-05 20:54:33 +08:00
return;
}
2014-07-31 21:30:48 +08:00
query.queryTrainStop(t.id, t.from.code, t.to.code, t.date)
.done(function (stopinfo) {
2014-08-30 01:32:27 +08:00
if (!trainStops)
return;
2014-07-31 21:30:48 +08:00
trainStops[t.code] = {
info: t,
stops: stopinfo
};
loadTrainStops();
}).fail(loadTrainStops);
};
2014-08-27 23:05:50 +08:00
var requestSuggestionData = function () {
2014-09-01 20:24:57 +08:00
_w.v = JSON.stringify({
2014-08-30 23:22:48 +08:00
key: "stupid360",
from: cp.fromCode,
2015-02-08 23:31:05 +08:00
tt: cp.selectedTrain || [],
ts: cp.selectedSeatType || [],
2014-08-30 23:22:48 +08:00
to: cp.toCode,
date: cp.depDate,
stops: trainStops
});
2014-08-26 21:29:58 +08:00
var requestData = {
2014-09-01 20:24:57 +08:00
data: _w.v
2014-08-26 21:29:58 +08:00
};
2014-08-27 23:05:50 +08:00
$.ajax({
2014-12-14 23:17:15 +08:00
url: data.trainSuggestApi + "?key=stupid360&r=" + Math.random(),
2014-08-27 23:05:50 +08:00
dataType: "json",
method: "POST",
data: requestData
2014-08-30 01:32:27 +08:00
}).done(preprocessServerResponse).fail(function () {
2014-08-27 23:05:50 +08:00
setTimeout(function () {
that.clearQueryResultCache();
//如果服务器出现错误,则等待十秒后再恢复状态
}, 10000);
});
};
2014-08-30 01:32:27 +08:00
var preprocessServerResponse = function (serverSuggestion) {
serverSuggestion = serverSuggestion && serverSuggestion.groups;
2014-08-27 23:05:50 +08:00
if (!serverSuggestion || !serverSuggestion.length) {
//木有结果。
2014-08-30 01:32:27 +08:00
suggestion = [];
2014-09-01 20:24:57 +08:00
cachedSuggest.data = suggestion;
2014-09-09 14:55:30 +08:00
localStorage['trainsuggestion'] = JSON.stringify(cachedSuggest);
2014-08-27 23:05:50 +08:00
isInQuery = false;
2014-08-30 01:32:27 +08:00
return;
2014-08-27 23:05:50 +08:00
}
2014-08-30 01:32:27 +08:00
2014-08-27 23:05:50 +08:00
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;
});
2014-08-30 01:32:27 +08:00
cachedSuggest.data = _.clone(serverSuggestion);
localStorage['trainsuggestion'] = JSON.stringify(cachedSuggest);
loadTrainTickets(serverSuggestion);
};
var loadTrainTickets = function (serverSuggestion) {
if (!serverSuggestion)
return;
2014-09-11 22:19:33 +08:00
2014-08-27 23:05:50 +08:00
var loaded = [];
var loadTrain = function () {
if (!serverSuggestion.length) {
checkSuggestion(loaded);
return;
2014-07-31 21:30:48 +08:00
}
2014-08-27 23:05:50 +08:00
var t = serverSuggestion.pop();
2014-09-13 15:58:20 +08:00
query.queryTicket(t.fromCode, t.fromText, t.toCode, t.toText, t.date, cp.studentTicket, false, false, true)
2014-08-27 23:05:50 +08:00
.done(function () {
loaded.unshift(t);
var trainAvailable = this.original;
if (!trainAvailable) {
loadTrain();
return;
2014-08-14 21:33:47 +08:00
}
2014-08-27 23:05:50 +08:00
2015-03-13 19:25:08 +08:00
var hasid = _.some(t.lines, function (l) {
return l.tid;
});
2014-08-30 01:32:27 +08:00
var trainFilter = new RegExp("^(" + _.map(t.lines, function (v) {
2015-03-13 19:25:08 +08:00
return hasid ? v.tid : v.trainCode;
2014-08-27 23:05:50 +08:00
}).join("|") + ")$", "i");
trainAvailable = _.filter(trainAvailable, function (x) {
2015-03-13 19:25:08 +08:00
return trainFilter.test(hasid ? x.id : x.code);
2014-08-27 23:05:50 +08:00
});
2014-08-30 01:32:27 +08:00
var seatType = cp.selectedSeatType && cp.selectedSeatType.length ? cp.selectedSeatType : data.seatDisplayOrder;
2014-08-27 23:05:50 +08:00
//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;
2015-03-13 19:25:08 +08:00
if (_.some(seatType, function (s) {
2014-08-27 23:05:50 +08:00
return x.ticketMap[s] && x.ticketMap[s].count >= count;
2015-03-13 19:25:08 +08:00
})) {
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;
2014-08-27 23:05:50 +08:00
});
if (selectedTrain.length)
t.train = selectedTrain;
loadTrain();
}).fail(loadTrain);
};
loadTrain();
2014-09-11 22:19:33 +08:00
if (!isSuggestReported) {
isSuggestReported = true;
port.track(data.trackTypes.LOAD_SUGGESTION, [cp.fromCode, cp.fromText, cp.toCode, cp.toText, cp.depDate, cp.studentTicket + '']);
}
2014-08-27 23:05:50 +08:00
};
var checkSuggestion = function (suggestData) {
suggestion = suggestData;
2014-08-30 01:32:27 +08:00
isInQuery = false;
2014-07-31 21:30:48 +08:00
if (suggestion.length)
that.fireEvent("trainSuggestion", suggestion);
};
this.setQueryResult = function (result, queryCount) {
2014-08-30 01:32:27 +08:00
if (queryCount < startQueryLimit || isInQuery || isSuggestLoopDisabled)
2014-07-31 21:30:48 +08:00
return;
queryResult = result;
2014-08-30 01:32:27 +08:00
isInQuery = true;
2014-07-31 21:30:48 +08:00
trainStops = {};
that.checkTrainSuggestion();
}
this.clearQueryResultCache = function () {
queryResult = null;
isInQuery = false;
trainStops = null;
alltrains = null;
2014-08-30 01:32:27 +08:00
lastQuerySuggest = null;
2014-09-11 22:19:33 +08:00
isSuggestReported = false;
2014-07-31 21:30:48 +08:00
};
this.checkTrainSuggestion = function () {
2014-09-09 14:55:30 +08:00
var suggestKey = cp.fromCode + cp.toCode + cp.depDate + ((cp.selectedTrain || []).join("|")) + ((cp.selectedSeatType || []).join("|"));
2014-08-30 01:32:27 +08:00
2015-02-08 23:31:05 +08:00
if (suggestKey === cachedSuggest.key && cachedSuggest.data) {
2014-08-30 01:32:27 +08:00
if (!lastQuerySuggest || (new Date() - lastQuerySuggest) > data.suggestRefreshInterval) {
lastQuerySuggest = new Date();
loadTrainTickets(_.clone(cachedSuggest.data));
} else {
isInQuery = false;
}
return;
}
2014-09-02 21:41:17 +08:00
cachedSuggest = { key: suggestKey };
2014-08-30 01:32:27 +08:00
var selectedTrain = new RegExp("^" + ((cp.selectedTrain || []).join("|") || ".*") + "$", "i");
alltrains = _.filter(queryResult.include || [], function (t) {
//没有选择,则不考虑
if (!selectedTrain.test(t.code))
2014-07-31 21:30:48 +08:00
return false;
2014-09-05 12:37:07 +08:00
//始发终到,不考虑
if (t.from.endpoint && t.to.endpoint)
2014-07-31 21:30:48 +08:00
return false;
2014-09-03 23:20:12 +08:00
//如果设置了席别,并且设置的席别都没有,则不考虑
if (cp.selectedSeatType && cp.selectedSeatType.length) {
2015-02-08 23:31:05 +08:00
if (!cp.selectedSeatType.some(function (x) { return t.ticketMap[x] || false; }))
2014-09-03 23:20:12 +08:00
return false;
}
2014-07-31 21:30:48 +08:00
return true;
});
if (!alltrains.length)
return;
2014-08-30 01:32:27 +08:00
//如果没有选择车次并且此时车次数量多于10趟则不予检测。
2015-02-08 23:31:05 +08:00
if ((!cp.selectedTrain || !cp.selectedTrain.length) && alltrains.length > 30)
2014-08-30 01:32:27 +08:00
return;
2014-07-31 21:30:48 +08:00
loadTrainStops();
};
}
TSS.prototype = Object.create(EventObject);
TSS.constructor = TSS;
//相同车站切换
2014-12-14 23:17:15 +08:00
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];
2014-12-14 23:17:15 +08:00
localStorage["ss_report"] = JSON.stringify(sameStation);
//upload
var rptData = [];
if (fromStations)
rptData.push(_.pluck(fromStations, "code"));
if (toStations)
rptData.push(_.pluck(toStations, "code"));
2014-12-14 23:17:15 +08:00
$.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);
});
2014-07-31 21:30:48 +08:00
var ctx = {
TSS: new TSS(),
setQueryResult: function (result, queryCount) {
registerSameStation(result);
2014-09-13 15:58:20 +08:00
//改签或学生票,忽略
2014-12-04 23:31:06 +08:00
if (cp.resign || cp.studentTicket)
2014-09-13 15:58:20 +08:00
return;
2014-07-31 21:30:48 +08:00
ctx.TSS.setQueryResult(result, queryCount);
},
clearQueryResultCache: function () {
ctx.TSS.clearQueryResultCache();
2014-08-30 01:32:27 +08:00
ctx.isSuggestLoopDisabled = false;
2014-09-11 22:19:33 +08:00
isSuggestReported = false;
2014-08-30 01:32:27 +08:00
},
findTrain: function (secstr) {
for (var line in suggestion) {
var t = _.findWhere(suggestion[line].train, { secureStr: secstr });
if (t)
return t;
}
return null;
2014-07-31 21:30:48 +08:00
}
};
Object.defineProperty(ctx.TSS, "isInSuggestQuery", {
get: function () {
return isInQuery;
}
});
2014-08-30 01:32:27 +08:00
Object.defineProperty(ctx, "isSuggestLoopDisabled",
{
get: function () {
return isSuggestLoopDisabled;
},
set: function (value) {
isSuggestLoopDisabled = value;
}
});
2014-07-31 21:30:48 +08:00
return ctx;
2014-08-05 20:54:33 +08:00
});