diff --git a/RwTicketAssistantV2/app/background.js b/RwTicketAssistantV2/app/background.js index e36566f..fde7a36 100644 --- a/RwTicketAssistantV2/app/background.js +++ b/RwTicketAssistantV2/app/background.js @@ -1366,6 +1366,93 @@ window.cbl = function (u, h) { //#endregion +//#region 定时提醒 + +(function TimerAlerm() { + var tasks = JSON.parse(localStorage["alarm"] || "[]"); + var buttonImgUrl = "/infobar/theme/plus_16.png"; + var iconLeft = "/icons/icon_n.png"; + var checkTimer = null; + var alarmData = {}; + + var saveAlarm = function() { + localStorage["alarm"] = JSON.stringify(tasks); + }; + + var buttonClickCallback = function (btnId, index) { + if (!alarmData[btnId]) + return; + + var task = alarmData[btnId]; + var data = task.data; + + chrome.tabs.create({ + active: true, + url: "http://12306.liebao.cn/#" + encodeURIComponent(JSON.stringify(data)) + }); + }; + chrome.notifications.onButtonClicked.addListener(buttonClickCallback); + + var checkForAlarm = function () { + checkTimer = null; + var hasChange = false; + while (tasks.length > 0 && tasks[0].time <= new Date().getTime()) { + (function (task) { + var id = "ALARM-" + task.data.fromCode + "-" + task.data.toCode + new Date().getTime(); + + chrome.notifications.create(id, { + type: "basic", + iconUrl: iconLeft, + title: task.group, + message: task.text, + buttons: [ + { title: "立刻打开订票页面", iconUrl: buttonImgUrl } + ] + }, function (_id) { + id = _id; + alarmData[id] = task; + setTimeout(function () { + delete alarmData[_id]; + chrome.notifications.clear(_id, function () { }); + }, 10000); + }); + })(tasks.shift()); + hasChange = true; + } + + if (tasks.length) + checkTimer = setTimeout(checkForAlarm, 30000); + if (hasChange) + saveAlarm(); + }; + + + chrome.runtime.onMessageExternal.addListener(function (m, s, r) { + if (!m || !m.action || m.action !== 'setAlarmTask') + return; + + var newtasks = m.detail; + _.each(newtasks, function(t) { + tasks.push(t); + }); + tasks.sort(function (x, y) { + return x.time - y.time; + }); + + if (!checkTimer) + checkForAlarm(); + }); + + checkForAlarm(); +})(); + + + +//#endregion + + + + ////#region conflict extension //(function () { diff --git a/RwTicketAssistantV2/app/icons/icon_n.png b/RwTicketAssistantV2/app/icons/icon_n.png new file mode 100644 index 0000000..3c78261 Binary files /dev/null and b/RwTicketAssistantV2/app/icons/icon_n.png differ diff --git a/RwTicketAssistantV2/app/manifest.json b/RwTicketAssistantV2/app/manifest.json index d52f3b8..e953fe1 100644 --- a/RwTicketAssistantV2/app/manifest.json +++ b/RwTicketAssistantV2/app/manifest.json @@ -35,7 +35,7 @@ "exclude_matches": [ ], "include_globs": [ ], "js": [ "libs/jquery.js", "12306/mobileproxy.js" ], - "matches": [ "http://test.fishlee.net/*", "http://app.fishlee.net/*" ], + "matches": [ "http://test.fishlee.net/*", "http://app.fishlee.net/*", "http://12306.liebao.cn/*" ], "run_at": "document_end" }, { diff --git a/Web12306/TrainSuggestion.cs b/Web12306/TrainSuggestion.cs index f5c7fcf..014cba4 100644 --- a/Web12306/TrainSuggestion.cs +++ b/Web12306/TrainSuggestion.cs @@ -1,19 +1,226 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; +using System.Text.RegularExpressions; using System.Web; +using Newtonsoft.Json; namespace Web12306 { - public class TrainSuggestion + public class TrainSuggestion : IHttpHandler { + #region Implementation of IHttpHandler + + /// + /// 通过实现 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。 + /// + /// 对象,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session 和 Server)的引用。 + public void ProcessRequest(HttpContext context) + { + var request = context.Request; + var data = request.Form["data"]; + if (string.IsNullOrEmpty(data)) + return; + + try + { + var ri = JsonConvert.DeserializeObject(data); + var suggestion = GetSuggestionResponseContent(ri); + + context.Response.ContentType = "application/json"; + context.Response.Write(JsonConvert.SerializeObject(suggestion)); + } + catch (Exception ex) + { + return; + } + } + + /// + /// 获取一个值,该值指示其他请求是否可以使用 实例。 + /// + /// + /// 如果 实例可再次使用,则为 true;否则为 false。 + /// + public bool IsReusable { get { return true; } } + + #endregion + + #region 生成建议 + + static Dictionary _timeRangeLimit = new Dictionary() + { + {'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 + } + public class SuggestItemComparer : IComparer + { + #region Implementation of IComparer + /// + /// 比较两个对象并返回一个值,指示一个对象是小于、等于还是大于另一个对象。 + /// + /// + /// 一个有符号整数,指示 的相对值,如下表所示。 值 含义 小于零 小于 。 零 等于 。 大于零 大于 。 + /// + /// 要比较的第一个对象。要比较的第二个对象。 + public int Compare(SuggestItem x, SuggestItem y) + { + if (x.EndPoint ^ y.EndPoint) + return x.EndPoint ? -1 : 1; + + return x.StopTime - y.StopTime; + } + + #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; } + } public class RequestInfo { - + public string From { get; set; } + + public string To { get; set; } + + public Dictionary Stops { get; set; } + + /// + /// 检测是否有非法请求,有则返回true + /// + /// + public bool CheckIllegal() + { + if (Stops.Values.Any(s => s.from.code == s.start.code && s.to.code == s.end.code)) + return true; + + return false; + } } + + 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 ticketMap { get; set; } + } + + + public class Elapsedtime + { + public string days { get; set; } + public string total { get; set; } + } + + } \ No newline at end of file diff --git a/Web12306/Web12306.csproj b/Web12306/Web12306.csproj index 8266c94..298d169 100644 --- a/Web12306/Web12306.csproj +++ b/Web12306/Web12306.csproj @@ -151,6 +151,7 @@ + @@ -229,6 +230,7 @@ + diff --git a/Web12306/css/buttons.css b/Web12306/css/buttons.css index d706bdd..8a13bcc 100644 --- a/Web12306/css/buttons.css +++ b/Web12306/css/buttons.css @@ -46,15 +46,15 @@ a.button-primary { color: #fff; } - .button-primary:hover { - background: linear-gradient(to top, #ff912d, #ffb72e); - color: #ffffff; - } +.button-primary:hover { + background: linear-gradient(to top, #ff912d, #ffb72e); + color: #ffffff; +} - .button-primary:active { - background: linear-gradient(to top, #ee7609, #ff9712); - color: #ffffff; - } +.button-primary:active { + background: linear-gradient(to top, #ee7609, #ff9712); + color: #ffffff; +} .button-block { @@ -68,7 +68,7 @@ a.button-primary { } .button-mini { - padding: 5px 15px; + padding: 0 15px; } .text { @@ -93,11 +93,28 @@ select.normal { border: 1px solid #b5b5b5; color: #737373; } -select.normal:disabled { - color: #bbbbbb; - background-color: #f6f6f6; - border-color: #d9d9d9; + + select.normal:disabled { + color: #bbbbbb; + background-color: #f6f6f6; + border-color: #d9d9d9; + } + + select.normal:focus { + outline: none; + } + + +.txt-input { + border: 1px solid #b7b7b7; + border-radius: 2px; + line-height: 16px; + background-image: linear-gradient(to bottom, #e7e7e7 0, #fff 20%); + font-size: 14px; + padding: 4px; } -select.normal:focus { - outline: none; +.txt-input-block { + display: block; + box-sizing: border-box; + width: 100%; } \ No newline at end of file diff --git a/Web12306/css/index.css b/Web12306/css/index.css index b30a818..3418a5e 100644 --- a/Web12306/css/index.css +++ b/Web12306/css/index.css @@ -17,6 +17,7 @@ @import url('ui/ui-autorefresh.css'); @import url('ui/chat.css'); @import url('ui/widget-selltime-notification.css'); +@import url('ui/dialogs.css'); .icon { background: url(../images/icon.png) no-repeat; diff --git a/Web12306/css/ui/dialogs.css b/Web12306/css/ui/dialogs.css new file mode 100644 index 0000000..387e97c --- /dev/null +++ b/Web12306/css/ui/dialogs.css @@ -0,0 +1,50 @@ +#passenger_editor { + display: none; +} + + #passenger_editor > header { + font-size: 16px; + font-weight: bold; + } + + #passenger_editor > header > span { + font-weight: normal; + font-size: 12px; + color: #999; + } + + #passenger_editor > dl { + margin-top: 10px; + margin-bottom: 10px; + line-height: 30px; + } + + #passenger_editor > dl > dt { + float: left; + clear: left; + width: 100px; + text-align: right; + vertical-align: middle; + font-weight: bold; + } + + #passenger_editor > dl > dd { + overflow: hidden; + } + + #passenger_editor input, + #passenger_editor select { + width: 60%; + box-sizing: border-box; + } + + #passenger_editor input.txt-input-block { + width: 80%; + } + +#selltip_selection { + display: none; +} + #selltip_selection li { + line-height: 170%; + } diff --git a/Web12306/css/ui/options-param.css b/Web12306/css/ui/options-param.css index 1b49c21..527e5d2 100644 --- a/Web12306/css/ui/options-param.css +++ b/Web12306/css/ui/options-param.css @@ -173,12 +173,10 @@ .passenger-selector .passenger-selector-editor { float: left; - margin-top: 12px; color: #8b8b8b; } .passenger-selector .passenger-selector-editor a { - display: none; } .passenger-selector .passenger-selector-editor a:hover { diff --git a/Web12306/css/ui/passenger-selector.css b/Web12306/css/ui/passenger-selector.css index 0f22d7e..ce00c1f 100644 --- a/Web12306/css/ui/passenger-selector.css +++ b/Web12306/css/ui/passenger-selector.css @@ -28,7 +28,7 @@ border-radius: 0 5px 5px 5px; border: 1px solid #c7c7c7; background-color: #ffffff; - padding: 12px; + padding: 6px; display: none; } @@ -43,9 +43,8 @@ display: none; } - .passenger-selector .passenger-selector-add { + .passenger-selector button { color: #616161; - width: 26px; height: 26px; background: linear-gradient(180deg, #f4f4f4, #e9e8e9); border: 1px solid #d1d1d1; @@ -53,23 +52,16 @@ cursor: pointer; } - .passenger-selector .passenger-selector-add:hover { + .passenger-selector button:hover { background: linear-gradient(180deg, #fefefe, #f3f3f3); border: 1px solid #e1e1e1; } - .passenger-selector .passenger-selector-add:active { + .passenger-selector button:active { background: linear-gradient(180deg, #e9e8e9, #f4f4f4); border: 1px solid #d1d1d1; } - .passenger-selector .passenger-selector-add:before { - left: 7px; - top: 7px; - position: relative; - color: #616161; - } - .passenger-selector .passenger-search div.fr:before { position: absolute; right: 6px; @@ -88,7 +80,7 @@ .passenger-selector ul { width: 300px; - margin-top: 12px; + margin-top: 6px; } .passenger-selector ul li { @@ -160,7 +152,6 @@ } .passenger-selector .passenger-pager { - margin-top: 12px; text-align: center; width: 100%; } diff --git a/Web12306/css/ui/widget-message-popup.css b/Web12306/css/ui/widget-message-popup.css index 88670c0..3f40dd2 100644 --- a/Web12306/css/ui/widget-message-popup.css +++ b/Web12306/css/ui/widget-message-popup.css @@ -1,49 +1,102 @@ .message-popup { - border: 5px solid #ccc; position: fixed; z-index: 100001; left: 50%; top: 50%; opacity: 0; - box-shadow: 3px 3px 6px rgba(200,200,200,0.6); + background: linear-gradient(to bottom, #f7f7f7,#eaebeb); + border-radius: 5px; + border: 1px solid #DFDFDF; + color: #333333; + box-shadow: 3px 3px 7px rgba(170, 170, 170, 0.5); + font-size: 120%; + line-height: 140%; } .message-popup .message-popup-inner { padding: 15px 20px; - border: 1px solid #aaa; } .message-popup-warn { - border-color: #fadfbc; + /*border-color: #fadfbc;*/ } .message-popup-warn .message-popup-inner { - border-color: #BD8D51; + /*border-color: #BD8D51; background: linear-gradient(to bottom, #fff0cf, #fee7c4); - color: #b2632b; + color: #b2632b;*/ } + .message-popup-warn .message-popup-inner .fa { + color: rgb(255, 106, 0); + } + .message-popup-error { - border-color: rgb(233, 202, 202); + /*border-color: rgb(233, 202, 202);*/ } .message-popup-error .message-popup-inner { - border-color: rgb(175, 94, 94); + /*border-color: rgb(175, 94, 94); background: #FFF7F7; - color: rgb(134, 77, 77); + color: rgb(134, 77, 77);*/ } + + .message-popup-error .message-popup-inner .fa { + color: rgb(165, 110, 110); + } + .message-popup-ok { - border-color: #DCF1DE; + /*border-color: #DCF1DE;*/ } .message-popup-ok .message-popup-inner { - border-color: #8FC08D; + /*border-color: #8FC08D; background: #F2FFF3; - color: #3d6d3d; + color: #3d6d3d;*/ } + .message-popup-ok .message-popup-inner .fa { + color: rgb(85, 102, 183); + } + + .message-popup-loading { - background: linear-gradient(to bottom, #fff, #fafafa); + /*background: linear-gradient(to bottom, #fff, #fafafa); border-color: #cccccc; - color: #444; + color: #444;*/ } + + + .message-popup-loading .message-popup-inner .fa { + color: rgb(119, 85, 183); + } + + +/*浮动框*/ +.modal-dialog { + position: fixed; + width: 550px; + z-index: 1100; + background-color: #fdfbf2; + border-radius: 5px; + color: #444; + box-shadow: 0 0 15px rgba(150,150,150,0.7); + display: none; +} + + .modal-dialog > header { + border-bottom: 1px solid #e3e1d9; + font-size: 18px; + font-weight: bold; + padding: 10px 10px 10px 10px; + color: #444444; + } + + .modal-dialog > div { + padding: 20px 50px 25px 50px; + } + + .modal-dialog footer { + padding-bottom: 20px; + text-align: center; + } diff --git a/Web12306/css/ui/widget-ticketsubmit.css b/Web12306/css/ui/widget-ticketsubmit.css index 3068050..e707dad 100644 --- a/Web12306/css/ui/widget-ticketsubmit.css +++ b/Web12306/css/ui/widget-ticketsubmit.css @@ -137,13 +137,52 @@ } #ticket-submit-info header { - text-align: center; - font-weight: bold; + line-height: 32px; font-size: 24px; - color: #8d5000; - text-indent: 0; + border-bottom: 1px solid #c6c6c6; + color: #333333; + text-indent: 30px; + font-weight: bold; + position: relative; + padding: 10px; } + #ticket-submit-info header .fa { + color: #999; + position: absolute; + right: 20px; + top: 50%; + margin-top: -8px; + cursor: pointer; + font-size: 16px; + } + + #ticket-submit-info header .fa:hover { + color: #444; + } + + + #ticket-submit-info > section { + padding: 10px 20px 5px 20px; + } + + #ticket-submit-info > footer { + padding: 0 30px 20px 30px; + text-align: center; + } + + #ticket-submit-info footer button, + #ticket-submit-info footer a { + margin-right: 10px; + width: 150px; + } + + #ticket-submit-info footer button:last-child, + #ticket-submit-info footer a:last-child { + margin-right: 0; + } + + #ticket-submit-info .ticket-submit-vc { width: 300px; margin: 20px auto 20px auto; @@ -229,10 +268,6 @@ display: inline-block; } - #ticket-submit-info header .fa { - top: 0; - } - /**/ #ticket-submit-info .ticket-submit-info-status-failed, #ticket-submit-info .ticket-submit-info-status-ok { @@ -244,7 +279,6 @@ color: rgb(180, 76, 50); line-height: 130%; padding-top: 10px; - line-height: 130%; font-size: 12px; margin-top: 5px; text-shadow: 0 0 1px rgba(200, 50, 50, 0.4); diff --git a/Web12306/css/ui/widget.css b/Web12306/css/ui/widget.css index 03a9565..0d48bd2 100644 --- a/Web12306/css/ui/widget.css +++ b/Web12306/css/ui/widget.css @@ -27,47 +27,48 @@ background-color: #f6f6f6; } - .float-dialog header { - line-height: 52px; + .float-dialog > header { + line-height: 32px; font-size: 16px; border-bottom: 1px solid #c6c6c6; color: #333333; text-indent: 30px; font-weight: bold; position: relative; + padding: 10px; } - .float-dialog header .fa { + .float-dialog > header .fa { color: #999; position: absolute; right: 20px; top: 50%; - margin-top: -5px; + margin-top: -8px; cursor: pointer; font-size: 16px; } - .float-dialog header .fa:hover { + .float-dialog > header .fa:hover { color: #444; } - .float-dialog section { + .float-dialog > section { padding: 20px 30px 15px 30px; } - .float-dialog footer { + .float-dialog > footer { padding: 0 30px 20px 30px; text-align: center; } - .float-dialog footer button, - .float-dialog footer a { + .float-dialog > footer button, + .float-dialog > footer a { margin-right: 10px; width: 150px; } - .float-dialog footer button:last-child, - .float-dialog footer a:last-child { + .float-dialog > footer button:last-child, + .float-dialog > footer a:last-child { margin-right: 0; } diff --git a/Web12306/index.html b/Web12306/index.html index 86388e1..f44563f 100644 --- a/Web12306/index.html +++ b/Web12306/index.html @@ -193,7 +193,7 @@ 需要在起售前提醒您吗?