Light12306/Web12306/js/ui/ui-oncetrainsitquery.js
2014-12-04 23:31:06 +08:00

425 lines
13 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 lastLoopKey = null;
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;
lastLoopKey = null;
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();
};
var clearQueryTimer = function () {
if (!queryLoopTimer)
return;
clearInterval(queryLoopTimer);
queryLoopTimer = null;
};
var startQueryTimer = function () {
if (queryLoopTimer)
return;
queryLoopTimer = setTimeout(queryLoop, loadTime);
};
var queryLoop = function () {
if (!queryKeyQueue || !queryKeyQueue.length)
return;
var key = queryKeyQueue.shift();
var trains = queryQueue[key];
queryKeyQueue.push(key);
lastLoopKey = lastLoopKey || key;
var date = trains[0].queryData[4];
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 + "']");
ele.empty();
if (!loaded) {
ele.append("<span class='remark remark-warning'>查询发生错误</span>");
} else if (result.notInSellTime) {
ele.append("<span class='remark remark-warning'>当日车次不在预售期</span>");
//从列表中移除,这个车次之后不用再查了。
delete queryQueue[key];
queryKeyQueue.pop();
} 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);
console.log("中转站查询:找不到车次 " + code + " 查询信息:" + key);
//从缓存的信息中移除。
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];
} else if (train.selltime) {
ele.append("<span class='remark remark-primary'>" + utility.formatSellDate(train.limitSellInfo) + "</span>");
} else if (train.available < 1) {
ele.append("<span class='remark remark-warning'>本车次暂无可售票</span>");
} else {
_.each(trainCodes[code], function (t) {
t.secureStr = train.secureStr;
t.rtrain = train;
});
//显示车次车票
var tickets = [];
_.each(data.seatDisplayOrder, function (seat) {
var seatinfo = train.ticketMap[seat];
//不显示无票以及没有的席别
if (!seatinfo || !seatinfo.count) return;
var selected = cp && $.inArray(seat, cp.selectedSeatType) !== -1;
tickets.push("<button class='button button-" + (selected ? "primary" : "default") + " btn-ticket-block' 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(""));
}
}
});
if (!_.keys(trainCodes).length && queryQueue[key]) {
//已经没有车次了。。移除
delete queryQueue[key];
queryKeyQueue.pop();
}
}
query.queryTicket.apply(this, trains[0].queryData)
.done(function () {
processResponse(true, this);
}).fail(function () {
processResponse(false);
}).always(function () {
if (queryKeyQueue[0] === lastLoopKey) {
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();
},
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;
});