2014-08-19 16:07:39 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2014-08-26 21:29:58 +08:00
|
|
|
|
using System.Drawing;
|
2014-08-19 16:07:39 +08:00
|
|
|
|
using System.Linq;
|
2014-08-26 21:29:58 +08:00
|
|
|
|
using System.Text.RegularExpressions;
|
2014-08-19 16:07:39 +08:00
|
|
|
|
using System.Web;
|
2014-08-26 21:29:58 +08:00
|
|
|
|
using Newtonsoft.Json;
|
2014-08-19 16:07:39 +08:00
|
|
|
|
|
|
|
|
|
namespace Web12306
|
|
|
|
|
{
|
2014-08-26 21:29:58 +08:00
|
|
|
|
public class TrainSuggestion : IHttpHandler
|
2014-08-19 16:07:39 +08:00
|
|
|
|
{
|
2014-08-26 21:29:58 +08:00
|
|
|
|
#region Implementation of IHttpHandler
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 通过实现 <see cref="T:System.Web.IHttpHandler"/> 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="context"><see cref="T:System.Web.HttpContext"/> 对象,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session 和 Server)的引用。</param>
|
|
|
|
|
public void ProcessRequest(HttpContext context)
|
|
|
|
|
{
|
|
|
|
|
var request = context.Request;
|
|
|
|
|
var data = request.Form["data"];
|
|
|
|
|
if (string.IsNullOrEmpty(data))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var ri = JsonConvert.DeserializeObject<RequestInfo>(data);
|
|
|
|
|
var suggestion = GetSuggestionResponseContent(ri);
|
|
|
|
|
|
|
|
|
|
context.Response.ContentType = "application/json";
|
|
|
|
|
context.Response.Write(JsonConvert.SerializeObject(suggestion));
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取一个值,该值指示其他请求是否可以使用 <see cref="T:System.Web.IHttpHandler"/> 实例。
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>
|
|
|
|
|
/// 如果 <see cref="T:System.Web.IHttpHandler"/> 实例可再次使用,则为 true;否则为 false。
|
|
|
|
|
/// </returns>
|
|
|
|
|
public bool IsReusable { get { return true; } }
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 生成建议
|
|
|
|
|
|
|
|
|
|
static Dictionary<char, int> _timeRangeLimit = new Dictionary<char, int>()
|
|
|
|
|
{
|
|
|
|
|
{'D', 240},
|
|
|
|
|
{'G', 180},
|
|
|
|
|
{'*', 300}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int GetStopTime(string stopTimeStr)
|
|
|
|
|
{
|
|
|
|
|
var m = Regex.Match(stopTimeStr, @"(\d+)分钟");
|
|
|
|
|
return m.Success ? int.Parse(m.Groups[1].Value) : 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GetTimeValue(string time)
|
|
|
|
|
{
|
|
|
|
|
var m = Regex.Match(time, @"0?(\d+):0?(\d+)");
|
|
|
|
|
return m.Success ? int.Parse(m.Groups[1].Value) * 60 + int.Parse(m.Groups[2].Value) : 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GetTimeSpace(string time1, string time2)
|
|
|
|
|
{
|
|
|
|
|
var x1 = GetTimeValue(time1);
|
|
|
|
|
var x2 = GetTimeValue(time2);
|
|
|
|
|
|
|
|
|
|
return x1 <= x2 ? x2 - x1 : x2 + 24 * 60 - x1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string GetSuggestionResponseContent(RequestInfo ri)
|
|
|
|
|
{
|
|
|
|
|
if (ri.CheckIllegal())
|
|
|
|
|
return string.Empty;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2014-08-19 16:07:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
2014-08-26 21:29:58 +08:00
|
|
|
|
public class SuggestItemComparer : IComparer<SuggestItem>
|
|
|
|
|
{
|
|
|
|
|
#region Implementation of IComparer<in StopInfo>
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 比较两个对象并返回一个值,指示一个对象是小于、等于还是大于另一个对象。
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>
|
|
|
|
|
/// 一个有符号整数,指示 <paramref name="x"/> 与 <paramref name="y"/> 的相对值,如下表所示。 值 含义 小于零 <paramref name="x"/> 小于 <paramref name="y"/>。 零 <paramref name="x"/> 等于 <paramref name="y"/>。 大于零 <paramref name="x"/> 大于 <paramref name="y"/>。
|
|
|
|
|
/// </returns>
|
|
|
|
|
/// <param name="x">要比较的第一个对象。</param><param name="y">要比较的第二个对象。</param>
|
|
|
|
|
public int Compare(SuggestItem x, SuggestItem y)
|
|
|
|
|
{
|
|
|
|
|
if (x.EndPoint ^ y.EndPoint)
|
|
|
|
|
return x.EndPoint ? -1 : 1;
|
|
|
|
|
|
|
|
|
|
return x.StopTime - y.StopTime;
|
|
|
|
|
}
|
2014-08-19 16:07:39 +08:00
|
|
|
|
|
2014-08-26 21:29:58 +08:00
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class SuggestItem
|
|
|
|
|
{
|
|
|
|
|
[JsonProperty("name")]
|
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
|
|
|
|
|
[JsonProperty("code")]
|
|
|
|
|
public string Code { get; set; }
|
|
|
|
|
|
|
|
|
|
[JsonProperty("ep")]
|
|
|
|
|
public bool EndPoint { get; set; }
|
|
|
|
|
|
|
|
|
|
[JsonProperty("st")]
|
|
|
|
|
public int StopTime { get; set; }
|
|
|
|
|
}
|
2014-08-19 16:07:39 +08:00
|
|
|
|
|
|
|
|
|
public class RequestInfo
|
|
|
|
|
{
|
2014-08-26 21:29:58 +08:00
|
|
|
|
public string From { get; set; }
|
|
|
|
|
|
|
|
|
|
public string To { get; set; }
|
|
|
|
|
|
|
|
|
|
public Dictionary<string, TrainInfo> Stops { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 检测是否有非法请求,有则返回true
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool CheckIllegal()
|
|
|
|
|
{
|
|
|
|
|
if (Stops.Values.Any(s => s.from.code == s.start.code && s.to.code == s.end.code))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2014-08-19 16:07:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
2014-08-26 21:29:58 +08:00
|
|
|
|
|
|
|
|
|
public class StopInfo
|
|
|
|
|
{
|
|
|
|
|
public string start_station_name { get; set; }
|
|
|
|
|
public string arrive_time { get; set; }
|
|
|
|
|
public string station_train_code { get; set; }
|
|
|
|
|
public string station_name { get; set; }
|
|
|
|
|
public string train_class_name { get; set; }
|
|
|
|
|
public string service_type { get; set; }
|
|
|
|
|
public string start_time { get; set; }
|
|
|
|
|
public string stopover_time { get; set; }
|
|
|
|
|
public string end_station_name { get; set; }
|
|
|
|
|
public string station_no { get; set; }
|
|
|
|
|
public bool isEnabled { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class SeatTicketInfo
|
|
|
|
|
{
|
|
|
|
|
public string code { get; set; }
|
|
|
|
|
public string name { get; set; }
|
|
|
|
|
public int price { get; set; }
|
|
|
|
|
public int count { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class SimpleStationInfo
|
|
|
|
|
{
|
|
|
|
|
public string code { get; set; }
|
|
|
|
|
public string name { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class DetailStationInfo : SimpleStationInfo
|
|
|
|
|
{
|
|
|
|
|
public string fromStationNo { get; set; }
|
|
|
|
|
public bool endpoint { get; set; }
|
|
|
|
|
public string time { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class TrainInfo
|
|
|
|
|
{
|
|
|
|
|
public string id { get; set; }
|
|
|
|
|
public string code { get; set; }
|
|
|
|
|
public int available { get; set; }
|
|
|
|
|
public SimpleStationInfo start { get; set; }
|
|
|
|
|
public DetailStationInfo from { get; set; }
|
|
|
|
|
public DetailStationInfo to { get; set; }
|
|
|
|
|
public Elapsedtime elapsedTime { get; set; }
|
|
|
|
|
public SimpleStationInfo end { get; set; }
|
|
|
|
|
public string ypinfo { get; set; }
|
|
|
|
|
public string ypinfo_ex { get; set; }
|
|
|
|
|
public string locationCode { get; set; }
|
|
|
|
|
public int controlDay { get; set; }
|
|
|
|
|
public string supportCard { get; set; }
|
|
|
|
|
public string saleTime { get; set; }
|
|
|
|
|
public string secureStr { get; set; }
|
|
|
|
|
public object selltime { get; set; }
|
|
|
|
|
public string date { get; set; }
|
|
|
|
|
public object limitSellInfo { get; set; }
|
|
|
|
|
public SeatTicketInfo[] tickets { get; set; }
|
|
|
|
|
public Dictionary<char, SeatTicketInfo> ticketMap { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class Elapsedtime
|
|
|
|
|
{
|
|
|
|
|
public string days { get; set; }
|
|
|
|
|
public string total { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-08-19 16:07:39 +08:00
|
|
|
|
}
|