482 lines
14 KiB
JavaScript
482 lines
14 KiB
JavaScript
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);
|
||
line.transitWarning = line.ne && line.wait < 150;
|
||
}
|
||
|
||
//过滤推荐线路
|
||
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 trainIds = _.groupBy(trains, function (x) {
|
||
return x.train.id;
|
||
});
|
||
|
||
var processResponse = function (loaded, result) {
|
||
queryLoopTimer = null;
|
||
|
||
_.each(_.keys(trainIds), function (tid) {
|
||
var ele = listTarget.find("tr.ticket-container td[data-date='" + date + "'][data-trainid='" + tid + "'][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, { id: tid });
|
||
if (!train) {
|
||
//车次不存在,可能是过程中会自动变号的车次
|
||
ele.closest("tr").prevUntil(".header, .ticket-container").andSelf().remove();
|
||
|
||
//从列表中移除
|
||
var args = _.clone(trainIds[tid]);
|
||
args.unshift(trains);
|
||
queryQueue[key] = _.without.apply(this, args);
|
||
|
||
//从缓存的信息中移除。
|
||
var matchedLines = _.filter(currentTransit.lines, function (line) {
|
||
return _.some(trainIds[tid], function (t) { return t === line.first || t === line.second; });
|
||
});
|
||
delete trainIds[tid];
|
||
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 trainIds[tid];
|
||
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(trainIds[tid], 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='" + tid + "' 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(trainIds).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;
|
||
});
|