Light12306/Web12306/js/ui/ui-oncetrainsitquery.js
2014-12-14 23:17:15 +08:00

482 lines
14 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 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;
var queuedcount = 0;
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 = data.onceTransitApi + "?date=" + cp.depDate + "&from=" + cp.fromCode + "&to=" + cp.toCode + "&maxAge=" + getCalcBasedTime();
var dlg = forceShowSuggestion ? mp.showMessagePopup("loading", "查询换乘中,请稍等...", { closeAfter: null }) : 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();
}
}
var cp1 = cp || {};
port.track(data.trackTypes.TRANSIT_SHOWTRANSIT, [cp1.fromCode || "", cp1.toCode || "", cp1.depDate || ""]);
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;
queuedcount = queryKeyQueue.length;
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 || currentResult.noAction) {
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();
//恢复按钮显示
if (!cp.studentTicket)
$(".train-list-func").parent().show();
};
var clearQueryTimer = function () {
if (!queryLoopTimer)
return;
clearInterval(queryLoopTimer);
queryLoopTimer = null;
};
var startQueryTimer = function () {
if (queryLoopTimer)
return;
queryLoopTimer = setTimeout(queryLoop, loadTime);
};
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) {
var subArray = [trs.get(i), trs.get(i + 1), trs.get(i + 2)];
subArray.originalIndex = i;
array.push(subArray);
}
//排序
array.sort(function (x, y) {
var offset = x.originalIndex - y.originalIndex;
var wx = parseInt(x[2].children[0].dataset.available) + parseInt(x[2].children[1].dataset.available);
if (isNaN(wx))
return offset;
var wy = parseInt(y[2].children[0].dataset.available) + parseInt(y[2].children[1].dataset.available);
if (isNaN(wy))
return offset;
if (wy !== wx)
return wy - wx;
return offset;
});
var df = document.createDocumentFragment();
_.each(_.flatten(array), function (row) { df.appendChild(row); });
table.append(df);
};
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];
var from = trains[0].from;
var to = trains[0].to;
var trainCodes = _.groupBy(trains, function (x) {
return x.train.code;
});
var processResponse = function (loaded, result) {
queryLoopTimer = null;
_.each(_.keys(trainCodes), function (code) {
var ele = listTarget.find("tr.ticket-container td[data-date='" + date + "'][data-traincode='" + code + "'][data-fromcode='" + from + "'][data-tocode='" + to + "']");
ele.empty();
if (!loaded) {
ele.append("<span class='remark remark-warning'>查询发生错误</span>");
ele.attr("data-available", 0);
} else if (result.notInSellTime) {
ele.append("<span class='remark remark-warning'>当日车次不在预售期</span>");
ele.attr("data-available", 1);
} 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];
ele.attr("data-available", 1);
} else if (train.selltime) {
ele.append("<span class='remark remark-primary'>" + utility.formatSellDate(train.selltime) + "起售</span>");
ele.attr("data-available", 1);
} else if (train.available < 1) {
ele.append("<span class='remark remark-warning'>本车次暂无可售票</span>");
ele.attr("data-available", 0);
} else {
_.each(trainCodes[code], function (t) {
t.secureStr = train.secureStr;
t.rtrain = train;
});
//显示车次车票
var tickets = [];
var hasSelected = false;
_.each(data.seatDisplayOrder, function (seat) {
var seatinfo = train.ticketMap[seat];
//不显示无票以及没有的席别
if (!seatinfo || !seatinfo.count) return;
var selected = cp && $.inArray(seat, cp.selectedSeatType) !== -1;
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>");
});
ele.append(tickets.join(""));
ele.attr("data-available", hasSelected ? 3 : 2);
}
}
});
if (result.notInSellTime || !_.keys(trainCodes).length && queryQueue[key]) {
//从列表中移除,这个车次之后不用再查了。
delete queryQueue[key];
queryKeyQueue.pop();
}
sortTables();
}
query.queryTicket.apply(this, trains[0].queryData)
.done(function () {
processResponse(true, this);
}).fail(function () {
processResponse(false);
}).always(function () {
if (!isInQuery || isSuggestLoopDisabled)
return;
if (--queuedcount === 0) {
loadTime = 5000;
if (listContainer.find("table tr").length > 1) {
listContainer.slideDown();
//自动滚屏一下下
setTimeout(function () {
var pos = $("#oncetrainsit").position();
if (pos && pos.top) {
window.scrollTo(0, pos.top);
}
}, 1000);
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();
$("#oncetrainsit .loading").remove();
},
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;
});