同步提交最新代码

This commit is contained in:
iFish 2014-07-31 21:30:48 +08:00
parent d09e5c8f44
commit 6e2ade7506
13 changed files with 390 additions and 34 deletions

View File

@ -187,6 +187,7 @@
<Content Include="js\otn\orderprocess.js" />
<Content Include="js\otn\queryticket.js" />
<Content Include="js\otn\trainfilter.js" />
<Content Include="js\otn\trainstationsuggest.js" />
<Content Include="js\platform\EventObject.js" />
<Content Include="js\platform\extensionPort.js" />
<Content Include="js\platform\media.js" />

View File

@ -67,6 +67,10 @@ a.button-primary {
line-height: 40px;
}
.button-mini {
padding: 0 15px;
}
.text {
border-radius: 4px;
border: 1px solid #b7b7b7;

View File

@ -313,3 +313,12 @@ button#btnResetOptions {
float: left;
color: #9b540b;
}
.search-traintypes li a {
color: #9b540b;
}
.search-traintypes li a:hover {
color: #7c5024;
text-decoration: underline;
}

View File

@ -167,3 +167,57 @@
.result .train-needauto td button {
margin-left: 20px;
}
/*购票建议*/
#suggestion {
display: none;
border: 1px solid #D1AB7B;
margin-top: 10px;
border-radius: 3px;
}
#suggestion > header {
line-height: 30px;
background: #D1AB7B;
font-size: 16px;
font-weight: bold;
text-indent: 20px;
color: #fff;
}
#suggestion > button {
margin: 10px auto;
display: block;
}
#suggestion > div {
padding: 20px;
}
#suggestion ul {
list-style-type: square;
}
#suggestion .train-suggestion-link-target {
font-weight: bold;
text-decoration: underline;
margin-left: 5px;
margin-right: 5px;
color: #c23825;
}
#suggestion a.train-suggestion-link-end,
#suggestion a.train-suggestion-link-start {
margin-left: 5px;
font-weight: bold;
text-decoration: underline;
color: #c23825;
}
#suggestion .train-code,
#suggestion .train-suggestion-target {
color: #8160d4;
font-weight: bold;
margin-left: 5px;
margin-right: 5px;
}

View File

@ -44,7 +44,7 @@
</ul>
</nav>
</header>
<section>
<article>
<!-- 搜索输入框 -->
<div class="search-box pr">
<div class="search-box-l"></div>
@ -144,6 +144,7 @@
其它
</label>
</li>
<li>[<a href="javascript:;">全选</a>]</li>
</ul>
<a class="search-more-option" href="javascript:;">
隐藏更多选项
@ -209,10 +210,10 @@
</td>
</tr>
<tr>
<td colspan="6">
<i class="fa fa-times"></i>
请先设置站点和日期信息,再重新查询。
</td>
<td colspan="6">
<i class="fa fa-times"></i>
请先设置站点和日期信息,再重新查询。
</td>
<tr>
<td colspan="6">
<i class="fa fa-times"></i>
@ -242,8 +243,8 @@
联系人正在加载中...
</div>
<div class="empty-indicator">
<i class="fa fa-question"></i>
没有可选择的联系人。是否没有登录?
没有可选择的联系人。<br />
需要登录后才可查看联系人。
</div>
<script type="text/x-dot-template">
{{~it:p:i}}
@ -348,6 +349,39 @@
</dl>
<button id="btnResetOptions" class="button button-default">重置选项</button>
</div>
<!-- 搜索结果 -->
<script type="text/x-dot-template" id="suggestion_template">
<ul>
{{for(var idx in it){}}
<li>
{{var t=it[idx];}}
您选择的车次 <span class="train-code">{{!t.code}}</span> 如果始终无票,还可以试试
{{if(t.suggestion.startAlt.length){}}
<span class="train-suggestion-target">出发城市</span>改为
{{~t.suggestion.startAlt:train:i}}
<a href="javascript:;" data-code="{{!train.code}}" class="train-suggestion-link-start">{{!train.name}}</a> {{=i<=t.suggestion.startAlt.length-2?" /":""}}
{{~}}
{{=t.suggestion.endAlt.length?" 或 ":""}}
{{}}}
{{if(t.suggestion.endAlt.length){}}
<span class="train-suggestion-target">到达城市</span>改为
{{~t.suggestion.endAlt:train:i}}
<a href="javascript:;" data-code="{{!train.code}}" class="train-suggestion-link-end">{{!train.name}}</a> {{=i<=t.suggestion.endAlt.length-2?" /":""}}
{{~}}
{{}}}
{{}}}
试试(会需要加价)。
</li>
</ul>
</script>
<section id="suggestion">
<header>购票提示</header>
<div></div>
<button class="button button-default button-mini">
<i class="fa fa-times"></i>
关闭
</button>
</section>
<!-- 月日期选择 -->
<div class="date-bar-wrap">
<div class="date-bar-prev fl">
@ -368,11 +402,9 @@
<span class="arrow-right"></span>
</div>
</div>
<!-- 搜索结果 -->
<div class="result" id="result">
</div>
</section>
</article>
</div>
<script type="text/x-dot-template" id="train_table">
<table class="{{?it.inAutoRefresh}}auto-refresh{{?}}">
@ -385,8 +417,8 @@
</tr>
</thead>
<tbody>
{{?!it.auto&&it.enableAuto&&!it.inAutoRefresh}}
<tr class="train-needauto">
{{?!it.auto&&it.enableAuto}}
<tr class="train-needauto" style='{{=it.inAutoRefresh?"display:none;":""}}'>
<td colspan="4">
没有符合要求的车次和席别
<button type="button" class="button button-primary" id="btn_start_autorefresh">
@ -626,7 +658,7 @@
</p>
</div>
<footer>
<a class="button button-primary" href="https://kyfw.12306.cn/otn/queryOrder/initNoComplete" target="_blank">
<a class="button button-primary" href="https://kyfw.12306.cn/otn/payOrder/init" target="_blank">
<i class="fa fa-credit-card"></i>
立刻付款
</a>

View File

@ -19,6 +19,9 @@
exports.citydata = citydata;
exports.cities = _(_.flatten(_.map(_.values(citydata.data), function (e) { return _.values(e); }))).mapObject(function (e) { return e.c; });;
exports.citynameMap = _.mapObject(exports.cities, function (c) {
return c.n;
});
exports.identityCardTypes = {
};
@ -69,7 +72,7 @@
};
exports.translateTrain = function (array) {
/// <summary>将列车编号翻译为实际的检查序列</summary>
return array.map(function(e) {
return array.map(function (e) {
return exports.tagMap[e] || e;
});
};
@ -93,15 +96,25 @@
[new Date(2015, 1, 20), new Date(2014, 2, 18)]
];
exports.startTrainStationSuggestQueryLimit = 10;
exports.maxSuggestStationTimeRange = {
"": 240,
"G": 120,
"D": 120
}
exports.maxSellDays = 19;
exports.minDate = exports.trimToDay(new Date());
exports.maxDate = exports.addDays(exports.minDate, exports.maxSellDays);
exports.isValidDate = function(date) {
exports.isValidDate = function (date) {
date = exports.trimToDay(date);
return date >= exports.minDate;
};
exports.isAutoBookEnabled = function (profile) {
return profile.selectedTrain && profile.selectedTrain.length
&& profile.selectedSeatType && profile.selectedSeatType.length;
};
//查找默认的日期
(function() {
(function () {
var d = exports.minDate;
var day = d.getDay();
@ -118,7 +131,7 @@
get: function () {
var d = exports.minDate;
return _.any(exports.showMoreOptRange,function(v) {
return _.any(exports.showMoreOptRange, function (v) {
return v[0] <= d && d <= v[1];
});
}

View File

@ -5,6 +5,8 @@
var expdata = require("../data.js");
var query = require("./queryticket.js");
var LOG_PROCESS = false;
sessMgr.on("sessionChanged", function () {
session = sessMgr.current;
});
@ -16,12 +18,13 @@
if (!currentProfile) return;
//过滤车次列表
expdata.log("开始过滤车次");
if (LOG_PROCESS)
expdata.log("开始过滤车次");
//车次类型过滤
if (currentProfile.trainTypes && currentProfile.trainTypes.length) {
var ft = _.filter(data.available, function (t) {
var vc = t.code[0];
if('GDCKZT'.indexOf(vc)!=-1)
if ('GDCKZT'.indexOf(vc) != -1)
return _.indexOf(currentProfile.trainTypes, t.code[0]) == -1;
else if (/^[L\d]/i.test(vc)) {
return _.indexOf(currentProfile.trainTypes, '1') == -1;
@ -32,7 +35,8 @@
$.each(ft, function () {
this.reason = 1;
data.filtered.push(this);
expdata.log("车次【" + this.code + "】因为车次类型不符被过滤。");
if (LOG_PROCESS)
expdata.log("车次【" + this.code + "】因为车次类型不符被过滤。");
});
data.available = _.difference(data.available, ft);
}
@ -43,7 +47,8 @@
$.each(filtered, function () {
this.reason = 1;
data.filtered.push(this);
expdata.log("车次【" + this.code + "】因为无票被过滤。");
if (LOG_PROCESS)
expdata.log("车次【" + this.code + "】因为无票被过滤。");
});
data.available = _.difference(data.available, filtered);
}
@ -56,7 +61,8 @@
$.each(filtered1, function () {
this.reason = 2;
data.filtered.push(this);
expdata.log("车次【" + this.code + "】因为发站不一致被过滤。");
if (LOG_PROCESS)
expdata.log("车次【" + this.code + "】因为发站不一致被过滤。");
});
data.available = _.difference(data.available, filtered1);
}
@ -66,7 +72,8 @@
$.each(filtered2, function () {
this.reason = 3;
data.filtered.push(this);
expdata.log("车次【" + this.code + "】因为发站不一致被过滤。");
if (LOG_PROCESS)
expdata.log("车次【" + this.code + "】因为发站不一致被过滤。");
});
data.available = _.difference(data.available, filtered2);
}
@ -81,7 +88,8 @@
$.each(r1, function () {
this.reason = 4;
data.filtered.push(this);
expdata.log("车次【" + this.code + "】因为时间不在指定的区域中而被过滤。");
if (LOG_PROCESS)
expdata.log("车次【" + this.code + "】因为时间不在指定的区域中而被过滤。");
});
data.available = _.difference(data.available, r1);
})();
@ -95,12 +103,14 @@
$.each(filtered3, function () {
this.reason = 5;
data.filtered.push(this);
expdata.log("车次【" + this.code + "】不在自动预定列表中而被过滤。");
if (LOG_PROCESS)
expdata.log("车次【" + this.code + "】不在自动预定列表中而被过滤。");
});
data.available = data.include;
}
}
expdata.log("车次过滤结束。");
if (LOG_PROCESS)
expdata.log("车次过滤结束。");
};
return {

View File

@ -0,0 +1,193 @@
define(function (require, exports, module) {
var data = require("../data.js");
var parser = require("../platform/parser.js");
var sessmgr = require("../account/sessionMgr.js");
var EventObject = require("../platform/EventObject.js");
var cp = sessmgr.currentProfile;
var query = require("../otn/queryticket.js");
sessmgr.on("currentProfileChanged", function () {
cp = sessmgr.currentProfile;
});
var isInQuery = false;
var startQueryLimit = data.startTrainStationSuggestQueryLimit;
var isFullyQualifiedTrainCode = function (code) {
return /^[A-Z]?\d+$/.test(code);
};
var getHours = function (t1, t2) {
var x1 = /^0?(\d+):(\d)+$/.exec(t1) ? parseInt(RegExp.$1) * 60 + parseInt(RegExp.$2) : null;
var x2 = /^0?(\d+):(\d+)$/.exec(t2) ? parseInt(RegExp.$1) * 60 + parseInt(RegExp.$2) : null;
if (x1 == null || x2 == null)
return null;
//这里不考虑两个时刻之间跨度超越1天的情况。按理说应该不会一趟车跑了一天都没停过一个站吧。。
return x1 <= x2 ? x2 - x1 : x2 + 24 * 60 - x1;
};
var isSpaceTimeInRange = function (code, t1, t2) {
var limit = data.maxSuggestStationTimeRange[code[0]] || data.maxSuggestStationTimeRange[""];
var space = getHours(t1, t2);
return space != null && space <= limit;
};
function TSS() {
EventObject.apply(this);
var that = this;
var queryResult = null;
var alltrains = null;
var trainStops = null;
var loadTrainStops = function () {
if (!alltrains || !alltrains.length) {
checkSuggestion();
return;
}
var tcode = alltrains.pop();
var t = _.findWhere(queryResult.original, { code: tcode });
query.queryTrainStop(t.id, t.from.code, t.to.code, t.date)
.done(function (stopinfo) {
trainStops[t.code] = {
info: t,
stops: stopinfo
};
loadTrainStops();
}).fail(loadTrainStops);
};
var getStopTime = function (stop) {
return /^(\d+)分钟$/.exec(stop.stopover_time) && parseInt(RegExp.$1) || 0;
};
var checkSuggestion = function () {
var suggestion = [];
for (var ts in trainStops) {
var tinfo = trainStops[ts].info;
var tstops = trainStops[ts].stops;
//查找在当前站的停止时间
var stopFrom = _.findWhere(tstops, { station_name: tinfo.from.name });
var stopTo = _.findWhere(tstops, { station_name: tinfo.to.name });
var stopTimeFrom = getStopTime(stopFrom);
var stopTimeTo = getStopTime(stopTo);
//发站?
var maybeAltStart = [];
if (!tinfo.from.endpoint) {
if (isSpaceTimeInRange(tinfo.code, tstops[0].start_time, stopFrom.arrive_time)) {
maybeAltStart.push({ code: tinfo.start.code, name: tinfo.start.name });
}
//检查各站
for (var i = 1; i < tstops.length; i++) {
var stop = tstops[i];
var stopStatCode = data.citynameMap[stop.station_name];
//无法推荐当前站、过路站以及无法查到的站
if (stop.isEnabled || !stopStatCode || stop === stopFrom)
break;
//如果停靠时间比当前的站小,也不考虑,因为这个很可能一样限售
if (getStopTime(stop) < stopTimeFrom)
continue;
//如果时间过久,那么也不考虑,因为会需要太久或加价太多
if (!isSpaceTimeInRange(tinfo.code, stop.start_time, stopFrom.arrive_time))
continue;
//考虑
maybeAltStart.push({ code: stopStatCode, name: stop.station_name });
}
}
//到站?
var maybeAltEnd = [];
if (!tinfo.to.endpoint) {
var lastStop = tstops[tstops.length - 1];
if (isSpaceTimeInRange(tinfo.code, stopTo.start_time, lastStop.arrive_time)) {
maybeAltEnd.push({ code: tinfo.end.code, name: tinfo.end.name });
}
for (var j = tinfo.length - 2; j >= 0; j--) {
var eStop = tstops[i];
var eStopStatCode = data.citynameMap[eStop.station_name];
//无法推荐当前站、过路站以及无法查到的站
if (eStop.isEnabled || !eStopStatCode || eStop === stopTo)
break;
//如果停靠时间比当前的站小,也不考虑,因为这个很可能一样限售
if (getStopTime(eStop) < stopTimeTo)
continue;
//如果时间过久,那么也不考虑,因为会需要太久或加价太多
if (!isSpaceTimeInRange(tinfo.code, stopTo.start_time, eStop.arrive_time))
continue;
//考虑
maybeAltEnd.push({ code: eStopStatCode, name: eStop.station_name });
}
}
}
if (maybeAltEnd.length || maybeAltStart.length) {
suggestion.push({
code: tinfo.code,
suggestion: {
startAlt: maybeAltStart,
endAlt: maybeAltEnd
}
});
}
if (suggestion.length)
that.fireEvent("trainSuggestion", suggestion);
};
this.setQueryResult = function (result, queryCount) {
if (queryCount < startQueryLimit || isInQuery)
return;
isInQuery = true;
queryResult = result;
trainStops = {};
that.checkTrainSuggestion();
}
this.clearQueryResultCache = function () {
queryResult = null;
isInQuery = false;
trainStops = null;
alltrains = null;
};
this.checkTrainSuggestion = function () {
alltrains = _.filter(cp.selectedTrain || [], function (code) {
if (!isFullyQualifiedTrainCode(code))
return false;
var t = _.findWhere(queryResult.original, { code: code });
if (!t || (t.from.endpoint && t.to.endpoint))
return false;
return true;
});
if (!alltrains.length)
return;
loadTrainStops();
};
}
TSS.prototype = Object.create(EventObject);
TSS.constructor = TSS;
var ctx = {
TSS: new TSS(),
setQueryResult: function (result, queryCount) {
ctx.TSS.setQueryResult(result, queryCount);
},
clearQueryResultCache: function () {
ctx.TSS.clearQueryResultCache();
}
};
Object.defineProperty(ctx.TSS, "isInSuggestQuery", {
get: function () {
return isInQuery;
}
});
return ctx;
});

View File

@ -56,6 +56,8 @@
} else {
a.push({ id: 1, name: "成人票" });
a.push({ id: 2, name: "儿童票" });
if (pt === "3")
a.push({ id: 3, name: "学生票" });
}
if (pt === "4") {
a.push({ id: 4, name: "残军票" });
@ -108,4 +110,4 @@
return exports.formatDate(date, "MM月dd日 hh:mm");
}
};
});
});

View File

@ -6,6 +6,7 @@
var datebar = require("./widget_datebar.js");
var parser = require("../platform/parser.js");
var media = require("../platform/media.js");
var mp = require("./widget_message_popup.js");
//会话管理器事件
sessMgr.on("notValidPassengerFound", function () {
@ -87,6 +88,7 @@
$("ul.search-traintypes :checkbox").each(function () {
this.checked = !ptt.length || _.indexOf(ptt, this.value) != -1;
});
$("ul.search-traintypes a").html($("ul.search-traintypes :checkbox:not(:checked)").length ? "全选" : "全不选");
//当前日期
if (p.depDate) {
@ -103,8 +105,19 @@
sessMgr.currentProfile.trainTypes = $.makeArray($("ul.search-traintypes :checkbox:checked").map(function () {
return this.value;
}));
$("ul.search-traintypes a").html($("ul.search-traintypes :checkbox:not(:checked)").length ? "全选" : "全不选");
sessMgr.save();
});
$("ul.search-traintypes a").click(function () {
var checkbox = $("ul.search-traintypes :checkbox");
if (checkbox.filter(":not(:checked)").length) {
checkbox.prop("checked", true);
} else {
checkbox.prop("checked", false);
}
checkbox.eq(0).change();
});
$("#index-tip-body").click(function () {
$(this).next().fadeIn();
});
@ -162,7 +175,17 @@
citySelector.cityui.addCityToRecent(sessMgr.currentProfile.fromCode);
citySelector.cityui.addCityToRecent(sessMgr.currentProfile.toCode);
ui_result.load();
//检查学生票是否对应
if (sessMgr.currentProfile.studentTicket && sessMgr.currentProfile.passengers && sessMgr.currentProfile.passengers.length) {
if (_.some(sessMgr.currentProfile.passengers, function(p) { return p.passenger_type != '3'; })) {
mp.confirm("确认", "您选择的是学生票,但是添加的联系人并不全是学生,将无法提交订单,确定继续查票吗?", ui_result.load);
} else {
ui_result.load();
}
} else {
ui_result.load();
}
});

View File

@ -6,6 +6,7 @@
var inAutoRefresh = false;
var media = require("../platform/media.js");
var query = require("../otn/queryticket.js");
var trainSuggest = require("../otn/trainstationsuggest.js");
sessMgr.on("sessionChanged", function () {
session = sessMgr.current;
@ -22,14 +23,14 @@
data.enableAuto = session.options.showMoreOpt;
data.inAuto = inAutoRefresh;
var count = Math.max(currentProfile.partialSubmitEnabled && currentProfile.passengers ? currentProfile.passengers.length : 0, 1);
var count = Math.max(!currentProfile.partialSubmitEnabled && currentProfile.passengers ? currentProfile.passengers.length : 0, 1);
var seat = null, train = null, entry = null;
if (data.original.length && !data.include.length && currentProfile.selectedTrain && currentProfile.selectedTrain.length && !currentProfile.byAuto) {
//TODO 没有查到任何车次
}
var trainRegCache = _.map(expdata.translateTrain(currentProfile.selectedTrain), function (s) { return new RegExp("^" + s + "$", "i"); });
var trainRegCache = _.map(expdata.translateTrain(currentProfile.selectedTrain || []), function (s) { return new RegExp("^" + s + "$", "i"); });
if (!trainRegCache || !trainRegCache.length) {
trainRegCache = [/.*/];
}
@ -89,7 +90,7 @@
media.play();
media.notify("可以订票了!", "终于等到可以订的 " + data.auto.train + "次列车" + expdata.toSeatTypeName(data.auto.seat) + "");
}
if (currentProfile.autoSubmitEnabled && data.enableAuto) {
if (currentProfile.autoSubmitEnabled && data.enableAuto && expdata.isAutoBookEnabled(currentProfile)) {
auto.fireEvent("performAutoSubmit", data.auto);
}
} else {
@ -108,7 +109,6 @@
data.nextTime = currentProfile.autoRefreshDelay;
}
}
console.log(data.auto);
};
var ev = require("../platform/EventObject.js");
@ -129,6 +129,8 @@
this.init = function () {
query.events.on("processTrains", function (e, d) {
processTrains(d);
if (inAutoRefresh)
trainSuggest.setQueryResult(d, refreshCount);
if (!d.auto && (d.nextTime && inAutoRefresh)) {
countdownTime = d.nextTime;
@ -157,6 +159,7 @@
that.updateDisplay();
$("#result>table").addClass("auto-refresh");
location.hash = "#result";
trainSuggest.clearQueryResultCache();
}
inAutoRefresh = true;
@ -181,6 +184,9 @@
currentDateLoopIndex = -1;
currentSelectedDate && (sessMgr.currentProfile.depDate = currentSelectedDate);
currentSelectedDate = null;
trainSuggest.clearQueryResultCache();
$("tr.train-needauto").show();
};
this.updateDisplay = function () {
refreshInfoSpan.eq(0).html(refreshCount);

View File

@ -68,7 +68,7 @@
else if (currentPageIndex < 1)
currentPageIndex = 1;
var renderList = currentList.slice((currentPageIndex - 1) * pagesize, pagesize);
var renderList = currentList.slice((currentPageIndex - 1) * pagesize, currentPageIndex * pagesize);
uiDlgList.html(uiDlgTpl(renderList, {
isSelected: function (p) {
return sessmgr.currentProfile && sessmgr.currentProfile && _.findWhere(sessmgr.currentProfile.passengers, { key: p.key }) || false;
@ -76,7 +76,7 @@
}));
uiDlg.find("button.passenger-pager-prev").prop("disabled", currentPageIndex < 2);
uiDlg.find("button.passenger-pager-next").prop("disabled", totalpage - 1 <= currentPageIndex);
uiDlg.find("button.passenger-pager-next").prop("disabled", totalpage - 1 < currentPageIndex);
};
uiDlg.find("button.passenger-pager-prev").click(function () {
currentPageIndex--;

View File

@ -10,6 +10,8 @@
var datebar = require("./widget_datebar.js");
var parser = require("../platform/parser.js");
var autorefresh = require("./ui-autorefresh.js");
var trainSuggest = require("../otn/trainstationsuggest.js");
var suggestionTemplate = $("#suggestion_template").doT();
//引入过滤
require("../otn/trainfilter.js").init();
@ -64,6 +66,13 @@
tsquery.init();
datebar.init();
trainSuggest.TSS.on("trainSuggestion", function (e, d) {
$("#suggestion div").html(suggestionTemplate(d)).parent().show();
});
$("#suggestion button").click(function() {
$("#suggestion").hide();
});
datebar.on("requireChangeDate", function (e, d) {
autorefresh.stop();
//请求切换时间