Light12306/Web12306/js/ui/ui-oncetrainsitquery.js

463 lines
14 KiB
JavaScript
Raw Normal View History

2014-12-04 23:31:06 +08:00
define(function (require, exports, module) {
var data = require("../data.js");
var sessmgr = require("../account/sessionMgr.js");
var query = require("../otn/queryticket.js");
var utility = require("../utility.js");
var cachedSuggest = JSON.parse(localStorage['trainTransit'] || '{"key":"", "data":null}');
var loadTime = 1000;
var mp = require("./widget_message_popup.js");
//DOM
var listContainer = $("#oncetrainsit");
var listTemplate = listContainer.find(">script").doT();
var listTarget = listContainer.find(">section");
var cp = sessmgr.currentProfile;
sessmgr.on("currentProfileChanged", function () {
cp = sessmgr.currentProfile;
});
var isInQuery = false;
var startQueryLimit = data.startTrainStationSuggestQueryLimit;
var isSuggestLoopDisabled = false;
var isSuggestReported = false;
//当前查询结果
var currentResult = null;
var forceShowSuggestion = false;
var showlevel = 1;
var currentTransit;
var queryQueue, queryKeyQueue;
var queryLoopTimer = null;
2014-12-05 23:32:41 +08:00
var queuedcount = 0;
2014-12-04 23:31:06 +08:00
var calculateTimeForCompare = function (trainClass, minutes) {
var rate = 1.0;
switch (trainClass) {
case 'G':
rate = 1.0;
break;
case 'D':
rate = 0.71428;
break;
case 'Z':
rate = 0.45714;
break;
case 'T':
rate = 0.4;
break;
default:
rate = 0.28571;
break;
}
return Math.floor(rate * minutes);
};
var setQueryResult = function (result, queryCount) {
currentResult = result;
var cacheKey = cp.fromCode + cp.toCode + cp.depDate;
if (!isAutoShowTransit())
return false;
if (cachedSuggest.key === cacheKey) {
if (cachedSuggest.data === null)
return true;
//load result;
isInQuery = true;
var cdata = _.clone(cachedSuggest.data);
prepareData(cdata);
renderTransitResult(cdata);
} else {
//判断检测等级
//1-自动检测换乘要求车次在4趟以下无始发终到
//2-不建议换乘,在上述条件以外
var url = "http://12306.fishlee.net/tt/tor?date=" + cp.depDate + "&from=" + cp.fromCode + "&to=" + cp.toCode + "&maxAge=" + getCalcBasedTime();
var dlg = forceShowSuggestion ? mp.showMessagePopup("loading", "查询换乘中,请稍等...") : null;
$.get(url).done(function (resp) {
if (!resp || !resp.ret) {
dlg.setState("error", (resp && resp.msg) || "咱的服务器计算不过来了,请等等服务器...");
dlg.delayClose();
isInQuery = false;
return;
}
cachedSuggest.key = cacheKey;
cachedSuggest.data = _.clone(resp.data);
localStorage['trainTransit'] = JSON.stringify(cachedSuggest);
if (!resp.data)
return;
prepareData(resp.data);
renderTransitResult(resp.data);
if (dlg)
dlg.close();
}).fail(function () {
if (dlg) {
dlg.setState("error", "咱的服务器计算不过来了,请等等服务器...");
dlg.delayClose();
isInQuery = false;
}
});
isInQuery = true;
}
return true;
};
var prepareData = function (result) {
//城市
var corder = result.corder;
var line;
result.corderName = [];
for (var j = 0; j < corder.length; j++) {
var city = data.cities[corder[j]];
if (!city) {
corder.splice(j, 1);
j--;
} else {
result.corderName.push(city.n);
}
}
//推荐线路
result.recommandLines = _.map(result.toplines, function (index) { return result.lines[index]; });
//线路
var lines = result.lines;
for (var i = 0; i < lines.length; i++) {
line = lines[i];
line.first.fromName = data.getCityName(line.first.from);
line.first.toName = data.getCityName(line.first.to);
line.second.fromName = data.getCityName(line.second.from);
line.second.toName = data.getCityName(line.second.to);
if (!line.second.fromName || !line.second.toName || !line.first.fromName || !line.first.toName) {
lines.splice(i, 1);
i--;
continue;
}
//时间
line.first.leftShort = /\s(\d+:\d+)/.exec(line.first.left) && RegExp.$1;
line.first.arriveShort = /\s(\d+:\d+)/.exec(line.first.arrive) && RegExp.$1;
line.first.days = utility.getDaysDifference(line.first.left, line.first.arrive);
line.first.elapsedStr = utility.formatMinutesToShortStr(line.first.elapsed);
line.second.leftShort = /\s(\d+:\d+)/.exec(line.second.left) && RegExp.$1;
line.second.arriveShort = /\s(\d+:\d+)/.exec(line.second.arrive) && RegExp.$1;
line.second.leftDays = utility.getDaysDifference(line.first.left, line.second.left);
line.second.arriveDays = utility.getDaysDifference(line.first.left, line.second.arrive);
line.second.elapsedStr = utility.formatMinutesToShortStr(line.second.elapsed);
line.totalTimeStr = utility.formatMinutesToShortStr(line.total);
line.waitTimeStr = utility.formatMinutesToShortStr(line.wait);
}
//过滤推荐线路
for (var k = 0; k < result.recommandLines.length; k++) {
line = result.recommandLines[k];
if (!line.second.fromName || !line.second.toName || !line.first.fromName || !line.first.toName) {
result.recommandLines.splice(k, 1);
k--;
}
}
}
var renderTransitResult = function (result) {
if (result) {
currentTransit = result;
if (forceShowSuggestion) {
listContainer.slideDown();
}
}
if (showlevel == 1)
currentTransit.showLines = currentTransit.recommandLines;
else if (showlevel == 2) {
currentTransit.showLines = _.where(currentTransit.lines, { ne: false });
if (!currentTransit.showLines || !currentTransit.showLines.length)
currentTransit.showLines = currentTransit.lines;
}
else currentTransit.showLines = currentTransit.lines;
var html = listTemplate(currentTransit, {
u: utility,
d: data,
l: showlevel
});
listTarget.html(html);
queryQueue = _.groupBy(_.flatten(_.map(currentTransit.showLines, function (line) { return [line.first, line.second]; })), function (seg) {
seg.key = seg.from + "," + seg.fromName + "," + seg.to + "," + seg.toName + "," + seg.left.split(' ')[0];
seg.queryData = seg.key.split(',');
seg.queryData.push(false);
seg.queryData.push(false);
seg.queryData.push(true);
seg.queryData.push(true);
seg.queryData.push(false);
seg.target = null;
return seg.key;
});
queryKeyQueue = _.keys(queryQueue);
loadTime = 1000;
2014-12-05 23:32:41 +08:00
queuedcount = queryKeyQueue.length;
2014-12-04 23:31:06 +08:00
startQueryTimer();
};
var getCalcBasedTime = function () {
var times = _.map(currentResult.original, function (t) {
return calculateTimeForCompare(t.code[0], utility.parseTimeSpanToMinutes(t.elapsedTime.total));
});
return times.length ? (_.max(times) + _.min(times)) / 2 : 999999;
};
var isAutoShowTransit = function () {
if (forceShowSuggestion)
return true;
//无效数据或车次数大于4
if (!currentResult || !currentResult.original || currentResult.original.length >= 4) {
return false;
}
//如果存在始发终到车
if (_.some(currentResult.original, function (x) {
return x.from.endpoint && x.to.endpoint;
}))
return false;
return true;
};
var closeTransitSuggest = function () {
clearQueryTimer();
isSuggestLoopDisabled = true;
listContainer.slideUp();
2014-12-05 23:32:41 +08:00
//恢复按钮显示
if (!cp.studentTicket)
$(".train-list-func").parent().show();
2014-12-04 23:31:06 +08:00
};
var clearQueryTimer = function () {
if (!queryLoopTimer)
return;
clearInterval(queryLoopTimer);
queryLoopTimer = null;
};
var startQueryTimer = function () {
if (queryLoopTimer)
return;
queryLoopTimer = setTimeout(queryLoop, loadTime);
};
2014-12-05 23:32:41 +08:00
var sortTables = function () {
var table = $("#oncetrainsit table");
var trs = table.find("tr:gt(0)");
var array = [];
for (var i = 0; i < trs.length; i += 3) {
array.push([trs.get(i), trs.get(i + 1), trs.get(i + 2)]);
}
//排序
array.sort(function (x, y) {
var wx = parseInt(x[2].children[0].dataset.available) + parseInt(x[2].children[1].dataset.available);
if (isNaN(wx))
return 0;
var wy = parseInt(y[2].children[0].dataset.available) + parseInt(y[2].children[1].dataset.available);
if (isNaN(wy))
return 0;
return wy - wx;
});
var df = document.createDocumentFragment();
_.each(_.flatten(array), function (row) { df.appendChild(row); });
table.append(df);
};
2014-12-04 23:31:06 +08:00
var queryLoop = function () {
if (!queryKeyQueue || !queryKeyQueue.length)
return;
var key = queryKeyQueue.shift();
var trains = queryQueue[key];
queryKeyQueue.push(key);
var date = trains[0].queryData[4];
2014-12-05 23:32:41 +08:00
var from = trains[0].from;
var to = trains[0].to;
2014-12-04 23:31:06 +08:00
var trainCodes = _.groupBy(trains, function (x) {
return x.train.code;
});
var processResponse = function (loaded, result) {
queryLoopTimer = null;
_.each(_.keys(trainCodes), function (code) {
2014-12-05 23:32:41 +08:00
var ele = listTarget.find("tr.ticket-container td[data-date='" + date + "'][data-traincode='" + code + "'][data-fromcode='" + from + "'][data-tocode='" + to + "']");
2014-12-04 23:31:06 +08:00
ele.empty();
if (!loaded) {
ele.append("<span class='remark remark-warning'>查询发生错误</span>");
2014-12-05 23:32:41 +08:00
ele.attr("data-available", 0);
2014-12-04 23:31:06 +08:00
} else if (result.notInSellTime) {
ele.append("<span class='remark remark-warning'>当日车次不在预售期</span>");
2014-12-05 23:32:41 +08:00
ele.attr("data-available", 1);
2014-12-04 23:31:06 +08:00
} else if (result.selltime) {
ele.append("<span class='remark remark-primary'>" + utility.format + "</span>");
} else {
//显示余票信息
var train = _.findWhere(result.original, { code: code });
if (!train) {
//车次不存在,可能是过程中会自动变号的车次
ele.closest("tr").prevUntil(".header, .ticket-container").andSelf().remove();
//从列表中移除
var args = _.clone(trainCodes[code]);
args.unshift(trains);
queryQueue[key] = _.without.apply(this, args);
//从缓存的信息中移除。
var matchedLines = _.filter(currentTransit.lines, function (line) {
return _.some(trainCodes[code], function (t) { return t === line.first || t === line.second; });
});
delete trainCodes[code];
if (matchedLines && matchedLines.length) {
matchedLines.unshift(currentTransit.lines);
currentTransit.lines = _.without.apply(this, matchedLines);
matchedLines[0] = currentTransit.recommandLines;
currentTransit.recommandLines = _.without.apply(this, matchedLines);
}
} else if (train.limitSellInfo) {
//限售信息
ele.append("<span class='remark remark-warning'>" + train.limitSellInfo + "</span>");
delete trainCodes[code];
2014-12-05 23:32:41 +08:00
ele.attr("data-available", 1);
2014-12-04 23:31:06 +08:00
} else if (train.selltime) {
ele.append("<span class='remark remark-primary'>" + utility.formatSellDate(train.limitSellInfo) + "</span>");
2014-12-05 23:32:41 +08:00
ele.attr("data-available", 1);
2014-12-04 23:31:06 +08:00
} else if (train.available < 1) {
ele.append("<span class='remark remark-warning'>本车次暂无可售票</span>");
2014-12-05 23:32:41 +08:00
ele.attr("data-available", 0);
2014-12-04 23:31:06 +08:00
} else {
_.each(trainCodes[code], function (t) {
t.secureStr = train.secureStr;
t.rtrain = train;
});
//显示车次车票
var tickets = [];
2014-12-05 23:32:41 +08:00
var hasSelected = false;
2014-12-04 23:31:06 +08:00
_.each(data.seatDisplayOrder, function (seat) {
var seatinfo = train.ticketMap[seat];
//不显示无票以及没有的席别
if (!seatinfo || !seatinfo.count) return;
var selected = cp && $.inArray(seat, cp.selectedSeatType) !== -1;
2014-12-05 23:32:41 +08:00
hasSelected |= selected;
tickets.push("<a class='ticket-block ticket-block-mini " + (selected ? "ticket-block-selected" : "") + "' data-seatcode='" + seat + "' data-traincode='" + code + "' data-sec='" + train.secureStr + "' data-transmit='1'>" + seatinfo.name + " " + seatinfo.count + "张 " + (seatinfo.price > 0 ? "¥" + (seatinfo.price / 10) : "") + "</button>");
2014-12-04 23:31:06 +08:00
});
ele.append(tickets.join(""));
2014-12-05 23:32:41 +08:00
ele.attr("data-available", hasSelected ? 3 : 2);
2014-12-04 23:31:06 +08:00
}
}
});
2014-12-05 23:32:41 +08:00
if (result.notInSellTime || !_.keys(trainCodes).length && queryQueue[key]) {
//从列表中移除,这个车次之后不用再查了。
2014-12-04 23:31:06 +08:00
delete queryQueue[key];
queryKeyQueue.pop();
}
2014-12-05 23:32:41 +08:00
sortTables();
2014-12-04 23:31:06 +08:00
}
query.queryTicket.apply(this, trains[0].queryData)
.done(function () {
processResponse(true, this);
}).fail(function () {
processResponse(false);
}).always(function () {
2014-12-05 23:32:41 +08:00
if (!isInQuery || isSuggestLoopDisabled)
return;
if (--queuedcount === 0) {
2014-12-04 23:31:06 +08:00
loadTime = 5000;
if (listContainer.find("table tr").length > 1) {
listContainer.slideDown();
queryLoopTimer = setTimeout(queryLoop, loadTime);
}
} else {
queryLoopTimer = setTimeout(queryLoop, loadTime);
}
});
};
listContainer.on("change", "input[name=tt_level]", function () {
showlevel = listContainer.find("input[name=tt_level]:checked").val();
renderTransitResult();
});
listContainer.find(">header>a").click(closeTransitSuggest);
var ctx = {
setQueryResult: function (result, queryCount) {
if (cp.resign || cp.studentTicket || isSuggestLoopDisabled)
return false;
if ((queryCount < startQueryLimit && !forceShowSuggestion) || isInQuery || isSuggestLoopDisabled)
return isInQuery;
return setQueryResult(result, queryCount);
},
clearQueryResultCache: function () {
isSuggestLoopDisabled = false;
isSuggestReported = false;
isInQuery = false;
forceShowSuggestion = false;
clearQueryTimer();
2014-12-05 23:32:41 +08:00
$("#oncetrainsit .loading").remove();
2014-12-04 23:31:06 +08:00
},
findTrain: function (secstr) {
var train = _.findWhere(_.flatten(_.map(_.values(currentTransit.lines), function (t) { return [t.first, t.second]; })), { secureStr: secstr });
return train && train.rtrain;
}
};
Object.defineProperty(ctx, "isInSuggestQuery", {
get: function () {
return isInQuery;
},
set: function (value) {
isInQuery = value;
}
});
Object.defineProperty(ctx, "isSuggestLoopDisabled",
{
get: function () {
return isSuggestLoopDisabled;
},
set: function (value) {
isSuggestLoopDisabled = value;
}
});
Object.defineProperty(ctx, "forceTransit",
{
get: function () {
return forceShowSuggestion;
},
set: function (value) {
forceShowSuggestion = value;
}
});
return ctx;
});