2015-11-18 19:48:23 +08:00
|
|
|
|
define(function (require, exports, module) {
|
2015-11-17 19:55:51 +08:00
|
|
|
|
var data = require("../data.js");
|
2015-11-18 19:48:23 +08:00
|
|
|
|
var queryTicket = require("../otn/queryticket.js");
|
2015-11-19 19:44:01 +08:00
|
|
|
|
var cache = null;
|
|
|
|
|
var lastKey = null;
|
|
|
|
|
var levelDesc = [
|
|
|
|
|
{
|
|
|
|
|
color: "#66B769",
|
|
|
|
|
name: "容易",
|
|
|
|
|
star: "一星",
|
|
|
|
|
desc: "一般情况下,购买此车次可比其它车次略容易一点。"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
color: "#829CDA",
|
|
|
|
|
name: "普通",
|
|
|
|
|
star: "二星",
|
|
|
|
|
desc: "此车次购买容易程度处于中间平均的水平上。"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
color: "#DE8439",
|
|
|
|
|
name: "略难",
|
|
|
|
|
star: "三星",
|
|
|
|
|
desc: "此车次特定情况下可能会比较难买。多留意跨站信息。"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
color: "#CE5353",
|
|
|
|
|
name: "较难",
|
|
|
|
|
star: "四星",
|
|
|
|
|
desc: "高峰期可能会难以购买此次列车,如果有其它选择,可优先考虑其它车次。"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
color: "#FF0000",
|
|
|
|
|
name: "困难",
|
|
|
|
|
star: "五星",
|
|
|
|
|
desc: "买买买!买到就是赚到!建议同时考虑其它可能购买车次!!"
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
var hotLineManual = {
|
|
|
|
|
"670000T1280C": {
|
|
|
|
|
hot: 2,
|
|
|
|
|
ratio: null
|
|
|
|
|
},
|
|
|
|
|
"760000T12607": {
|
|
|
|
|
hot: 2,
|
|
|
|
|
ratio: null
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
/**
|
|
|
|
|
* 额外的难度系数,用于调整一些特定线路的难度系数
|
|
|
|
|
*/
|
|
|
|
|
var extraRatioMatrix = [
|
|
|
|
|
[/(乌鲁木齐南?|兰州)/, 2],
|
|
|
|
|
[/拉萨/, 2],
|
|
|
|
|
[/哈尔滨[东西北]?/, 1.5],
|
|
|
|
|
[/长春[西南]?/, 1.5],
|
|
|
|
|
[/成都[东南]?/, 2]
|
|
|
|
|
];
|
2015-11-18 19:48:23 +08:00
|
|
|
|
var hotLineMatrix = [
|
|
|
|
|
{
|
|
|
|
|
type: 0, //单向,节前顺向,节后逆向
|
|
|
|
|
from: [
|
2015-11-19 19:44:01 +08:00
|
|
|
|
/广州[东北南]?/,
|
|
|
|
|
/深圳[东西南]?/
|
2015-11-18 19:48:23 +08:00
|
|
|
|
],
|
|
|
|
|
to: [
|
2015-11-19 19:44:01 +08:00
|
|
|
|
/郑州东?/,
|
2015-11-18 19:48:23 +08:00
|
|
|
|
/重庆[南北]?/,
|
|
|
|
|
/(武[昌汉]|汉口)/,
|
2015-11-19 19:44:01 +08:00
|
|
|
|
/(达州|兰州|常德|乌鲁木齐南|潮汕|饶平|拉萨)/,
|
2015-11-18 19:48:23 +08:00
|
|
|
|
/成都[东南]?/,
|
|
|
|
|
/岳阳东?/,
|
|
|
|
|
/长沙南?/,
|
|
|
|
|
/衡阳东?/,
|
|
|
|
|
/襄阳东?/,
|
2015-11-19 19:44:01 +08:00
|
|
|
|
/西安[南北]?/,
|
|
|
|
|
/哈尔滨[东西北]?/,
|
|
|
|
|
/长春[西南]?/
|
2015-11-18 19:48:23 +08:00
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
type: 0, //单向,节前顺向,节后逆向
|
|
|
|
|
from: [
|
|
|
|
|
/北京[东西南北]?/
|
|
|
|
|
],
|
|
|
|
|
to: [
|
|
|
|
|
/(武[昌汉]|汉口)/,
|
|
|
|
|
/长沙南?/,
|
|
|
|
|
/宝鸡南?/,
|
|
|
|
|
/重庆[南北]?/,
|
|
|
|
|
/成都[东南]?/,
|
2015-11-19 19:44:01 +08:00
|
|
|
|
/(兰州|乌鲁木齐南|拉萨)/,
|
2015-11-18 19:48:23 +08:00
|
|
|
|
/西安[南北]?/,
|
|
|
|
|
/哈尔滨[东西北]?/,
|
|
|
|
|
/长春[西南]/
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
type: 0,
|
|
|
|
|
from: [
|
|
|
|
|
/上海([西南]|虹桥)?/
|
|
|
|
|
],
|
|
|
|
|
to: [
|
|
|
|
|
/重庆[南北]?/,
|
|
|
|
|
/成都[东南]?/,
|
|
|
|
|
/哈尔滨[东西北]?/,
|
|
|
|
|
/长春[西南]/,
|
|
|
|
|
/广州[东北南]?/,
|
|
|
|
|
/西安[南北]?/,
|
|
|
|
|
/郑州东?/,
|
|
|
|
|
/怀化南?/,
|
|
|
|
|
/(武[昌汉]|汉口)/,
|
2015-11-19 19:44:01 +08:00
|
|
|
|
/(达州|兰州|乌鲁木齐南|南充|拉萨)/
|
2015-11-18 19:48:23 +08:00
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
type: 0,
|
|
|
|
|
to: [
|
|
|
|
|
/成都[东南]?/
|
|
|
|
|
],
|
|
|
|
|
from: [
|
|
|
|
|
/上海([西南]|虹桥)?/,
|
|
|
|
|
/深圳[东西北]?/,
|
|
|
|
|
/东莞东?/,
|
|
|
|
|
/杭州东?/,
|
|
|
|
|
/北京[东西南北]?/,
|
|
|
|
|
/哈尔滨[东西北]?/,
|
|
|
|
|
/长春[西南]/,
|
|
|
|
|
/广州[东北南]?/,
|
|
|
|
|
/西安[南北]?/,
|
|
|
|
|
/宁波南?/,
|
|
|
|
|
/温州南?/,
|
|
|
|
|
/福州南?/,
|
|
|
|
|
/(武[昌汉]|汉口)/,
|
2015-11-19 19:44:01 +08:00
|
|
|
|
/(达州|兰州|乌鲁木齐南|南充|拉萨)/,
|
2015-11-18 19:48:23 +08:00
|
|
|
|
/苏州(北|新区|园区)?/
|
|
|
|
|
]
|
2015-11-19 19:44:01 +08:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
type: 1, //双向
|
|
|
|
|
from: [
|
|
|
|
|
/(武[昌汉]|汉口)/
|
|
|
|
|
],
|
|
|
|
|
to: [
|
|
|
|
|
/重庆[南北]?/,
|
|
|
|
|
/成都[东南]?/,
|
|
|
|
|
/哈尔滨[东西北]?/,
|
|
|
|
|
/长春[西南]?/
|
|
|
|
|
]
|
2015-11-18 19:48:23 +08:00
|
|
|
|
}
|
|
|
|
|
];
|
2015-11-17 19:55:51 +08:00
|
|
|
|
|
2015-11-18 19:48:23 +08:00
|
|
|
|
/**
|
2015-11-19 19:44:01 +08:00
|
|
|
|
* 判断指定的日期是否是回乡日期
|
|
|
|
|
* @param {string} 具体日期
|
|
|
|
|
* @returns {boolean} 如果是回乡日期,则返回 true,否则返回 false
|
|
|
|
|
*/
|
2015-11-18 19:48:23 +08:00
|
|
|
|
var isBackHome = function (date) {
|
|
|
|
|
if (!/(\d{4})-(0?\d+)-(0?\d+)/.exec(date || ""))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
var year = parseInt(RegExp.$1, 10);
|
|
|
|
|
var month = parseInt(RegExp.$2, 10);
|
|
|
|
|
var day = parseInt(RegExp.$3, 10);
|
|
|
|
|
|
|
|
|
|
return month < 2 || (month === 2 && day <= 8);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
2015-11-19 19:44:01 +08:00
|
|
|
|
* 计算单个车次的购票难度
|
|
|
|
|
* @param {} 车次
|
|
|
|
|
* @param {Array} 原始车次
|
|
|
|
|
*/
|
|
|
|
|
var calculateTrainDifficulty = function (train, originalTrains) {
|
|
|
|
|
train.dp = {};
|
|
|
|
|
|
|
|
|
|
//城铁
|
|
|
|
|
if (train.code[0] === 'C') {
|
|
|
|
|
train.dp.difficulty = 20;
|
|
|
|
|
train.dp.point = 2;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-18 19:48:23 +08:00
|
|
|
|
var ratio = 40;
|
|
|
|
|
//是否是热门车次以及回乡
|
|
|
|
|
var isBack = isBackHome(train.date);
|
2015-11-19 19:44:01 +08:00
|
|
|
|
var isHotLine = (function () {
|
|
|
|
|
var data = hotLineManual[train.id];
|
2015-11-18 19:48:23 +08:00
|
|
|
|
|
2015-11-19 19:44:01 +08:00
|
|
|
|
if (data) {
|
|
|
|
|
ratio = data.ratio || ratio;
|
|
|
|
|
return data.hot;
|
|
|
|
|
}
|
2015-11-18 19:48:23 +08:00
|
|
|
|
|
2015-11-19 19:44:01 +08:00
|
|
|
|
var points = _.map(hotLineMatrix, function (l) {
|
|
|
|
|
var startHot = false, endHot = false, hotRatio = 0;
|
|
|
|
|
if (l.type === 0) {
|
|
|
|
|
startHot = _.any(!isBack ? l.to : l.from, function (r) { return r.test(train.start.name) || r.test(train.from.name) }) ? 1 : 0;
|
|
|
|
|
endHot = _.any(!isBack ? l.from : l.to, function (r) { return r.test(train.end.name) || r.test(train.to.name) }) ? 1 : 0;
|
|
|
|
|
} else {
|
|
|
|
|
startHot = _.any(l.to, function (r) { return r.test(train.start.name) }) ? 1 : 0 || _.any(l.from, function (r) { return r.test(train.start.name) || r.test(train.from.name) }) ? 1 : 0;
|
|
|
|
|
endHot = _.any(l.to, function (r) { return r.test(train.end.name) }) ? 1 : 0 || _.any(l.from, function (r) { return r.test(train.end.name) || r.test(train.to.name) }) ? 1 : 0;
|
|
|
|
|
}
|
|
|
|
|
hotRatio = (startHot ? 1 : 0) + (endHot ? 1 : 0);
|
|
|
|
|
|
|
|
|
|
return [startHot, endHot, hotRatio];
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (points.length) {
|
|
|
|
|
var hr = _.max(points, function (h) {
|
|
|
|
|
return h[2];
|
|
|
|
|
});
|
|
|
|
|
train.start.isHot = hr[0] > 0;
|
|
|
|
|
train.end.isHot = hr[1] > 0;
|
|
|
|
|
train.dp.hotRatio = hr[2];
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 基础购票难度系数均为40,特殊车次直接指定
|
2015-11-18 19:48:23 +08:00
|
|
|
|
* 列车始发站、终到站如果命中任意一条规则,则难度+20
|
2015-11-19 19:44:01 +08:00
|
|
|
|
* 如果车次非始发站或非终到站,则每次难度均加10*区域额外难度系数(非热门线路)或30(热门线路)
|
|
|
|
|
* 15点后24点前发Z、T 车次,难度加60或40(热门线路)
|
2015-11-18 19:48:23 +08:00
|
|
|
|
* DG车非热门线路难度减10
|
|
|
|
|
* 非热门线路,始发终到满足任意一个条件则难度减5
|
|
|
|
|
*
|
2015-11-19 19:44:01 +08:00
|
|
|
|
* 最终难度区间:10-未知,越高越难
|
|
|
|
|
*/
|
|
|
|
|
var isHs = /^[GD]/i.test(train.code);
|
|
|
|
|
var isZt = /^[ZT]/i.test(train.code);
|
|
|
|
|
|
|
|
|
|
//额外难度系数
|
|
|
|
|
var extraRatio = Math.max(_.max(_.map(extraRatioMatrix, function (erm) {
|
|
|
|
|
return erm[0].test(train.start.name) || erm[0].test(train.end.name) ? erm[1] : 0;
|
|
|
|
|
})), 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 考虑车次数量和分布。
|
|
|
|
|
* 如果没有GD,则额外难度系数 *1.1
|
|
|
|
|
* 如果车次总数量小于3,则额外难度系数*2
|
|
|
|
|
* 如果车辆总数小于6,则额外难度系数*1.5
|
|
|
|
|
* 如果车辆总数小于10,则额外难度系数*1.1
|
2015-11-18 19:48:23 +08:00
|
|
|
|
*/
|
2015-11-19 19:44:01 +08:00
|
|
|
|
if (originalTrains) {
|
|
|
|
|
if (originalTrains.length < 10)
|
|
|
|
|
extraRatio *= 1.1;
|
|
|
|
|
else if (originalTrains.length < 6)
|
|
|
|
|
extraRatio *= 1.5;
|
|
|
|
|
else if (originalTrains.length < 3)
|
|
|
|
|
extraRatio *= 2;
|
|
|
|
|
|
|
|
|
|
if (!_.any(originalTrains, function (train) {
|
|
|
|
|
return /[GDC]/.test(train.code[0]);
|
|
|
|
|
}))
|
|
|
|
|
extraRatio *= 1.1;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-18 19:48:23 +08:00
|
|
|
|
if (isHotLine)
|
2015-11-19 19:44:01 +08:00
|
|
|
|
ratio += 20 * train.dp.hotRatio * (isZt ? 1.5 : 1) * extraRatio;
|
2015-11-18 19:48:23 +08:00
|
|
|
|
|
|
|
|
|
//非始发站
|
|
|
|
|
if (!train.from.endpoint)
|
2015-11-19 19:44:01 +08:00
|
|
|
|
ratio += (train.start.isHot ? 60 : (isZt ? 40 : 20) * extraRatio);
|
2015-11-18 19:48:23 +08:00
|
|
|
|
//非终到站
|
|
|
|
|
if (!train.to.endpoint)
|
2015-11-19 19:44:01 +08:00
|
|
|
|
ratio += (train.end.isHot ? 60 : (isZt ? 40 : 20) * extraRatio);
|
2015-11-18 19:48:23 +08:00
|
|
|
|
//15点以后的ZT
|
2015-11-19 19:44:01 +08:00
|
|
|
|
if (isZt && parseInt(/^0?(\d+)/.exec(train.from.time)[1], 10) >= 15) {
|
2015-11-18 19:48:23 +08:00
|
|
|
|
ratio += isHotLine ? 60 : 40;
|
|
|
|
|
}
|
|
|
|
|
if (!isHotLine) {
|
2015-11-19 19:44:01 +08:00
|
|
|
|
if (isHs)
|
2015-11-18 19:48:23 +08:00
|
|
|
|
ratio -= 10;
|
|
|
|
|
if (train.from.endpoint)
|
|
|
|
|
ratio -= 10;
|
|
|
|
|
if (train.to.endpoint)
|
|
|
|
|
ratio -= 10;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-19 19:44:01 +08:00
|
|
|
|
train.dp.difficulty = ratio;
|
|
|
|
|
train.dp.point = ratio / 10;
|
|
|
|
|
};
|
2015-11-18 19:48:23 +08:00
|
|
|
|
|
2015-11-19 19:44:01 +08:00
|
|
|
|
/**
|
|
|
|
|
* 设置对应车次的困难度提示信息
|
|
|
|
|
* @param {} train
|
|
|
|
|
* @returns {}
|
|
|
|
|
*/
|
|
|
|
|
var setDifficultyInfo = function (train) {
|
|
|
|
|
var dp = train.dp;
|
|
|
|
|
var level = Math.min(Math.floor(dp.point / 4), 4);
|
|
|
|
|
|
|
|
|
|
_.extend(dp, levelDesc[level]);
|
2015-11-18 19:48:23 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 计算车次购票难度。最终难度区间:10-200,指数越高,越难。
|
|
|
|
|
* @param {Array} 要计算的车次
|
|
|
|
|
*/
|
|
|
|
|
var calculateTrainsDifficulty = function (trains) {
|
2015-11-19 19:44:01 +08:00
|
|
|
|
_.each(trains, function (train) {
|
|
|
|
|
calculateTrainDifficulty(train);
|
|
|
|
|
setDifficultyInfo(train);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
cache = _.map(trains, function (t) {
|
|
|
|
|
return { id: t.id, dp: t.dp };
|
|
|
|
|
});
|
2015-11-18 19:48:23 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
queryTicket.events.on("processTrains", function (e, data) {
|
2015-11-19 19:44:01 +08:00
|
|
|
|
var key = data.query.from + data.query.to + data.query.date;
|
|
|
|
|
|
|
|
|
|
if (key === lastKey) {
|
|
|
|
|
_.each(data.available, function (train) {
|
|
|
|
|
var dpe = _.findWhere(cache, { id: train.id });
|
|
|
|
|
if (!dpe) {
|
|
|
|
|
calculateTrainDifficulty(train, data.original);
|
|
|
|
|
setDifficultyInfo(train);
|
|
|
|
|
cache[train.id] = { id: train.id, dp: train.dp };
|
|
|
|
|
} else {
|
|
|
|
|
train.dp = dpe.dp;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
lastKey = key;
|
|
|
|
|
calculateTrainsDifficulty(data.available, data.original);
|
|
|
|
|
}
|
2015-11-18 19:48:23 +08:00
|
|
|
|
});
|
2015-11-17 19:55:51 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|