Conflicts:
	ChatRoomServer.Www/Scripts/bootstrap-notify.js
This commit is contained in:
iFish(木鱼) 2015-07-17 01:30:37 +08:00
commit b09231cdae
33 changed files with 2790 additions and 93 deletions

View File

@ -6,7 +6,9 @@ using System.Threading.Tasks;
namespace ChatRoomServer.Db
{
using System.Data;
using System.Data.Entity;
using System.Data.SqlClient;
using ChatRoomServer.Db.Entities;
public class ChatDb : DbContext
@ -94,5 +96,100 @@ namespace ChatRoomServer.Db
{
return Database.SqlQuery<int>("exec usp_BlockUser_GetUserReportCount {0}, {1}", username, minutes).First();
}
public async Task<PagedData<AbuseReport>> GetAbuseReportPagedList(int filter, int pageindex, int pagesize)
{
var totalCountParameter = new SqlParameter("totalCount", SqlDbType.BigInt) { Direction = ParameterDirection.Output, Value = 0 };
var list = await Database.SqlQuery<AbuseReport>(
"exec usp_AbuseReport_GetList @filter,@pagesize,@pageindex,@totalcount out",
new SqlParameter("filter", SqlDbType.Int) { Value = filter },
new SqlParameter("pagesize", SqlDbType.Int) { Value = pagesize },
new SqlParameter("pageindex", SqlDbType.Int) { Value = pageindex },
totalCountParameter
).ToListAsync();
return new PagedData<AbuseReport>()
{
Data = list,
TotalCount = (long)totalCountParameter.Value
};
}
public async Task<PagedData<MsgLog>> GetMsgLogList(string username, int pagesize, int pageindex)
{
var sp = "exec usp_MsgLog_GetList @pageindex, @pagesize, @user, @count output";
var totalCountParameter = new SqlParameter("count", SqlDbType.BigInt) { Direction = ParameterDirection.Output, Value = 0 };
var list = await Database.SqlQuery<MsgLog>(
sp,
new SqlParameter("pageindex", SqlDbType.Int) { Value = pageindex },
new SqlParameter("pagesize", SqlDbType.Int) { Value = pagesize },
new SqlParameter("user", SqlDbType.VarChar, 100) { Value = username },
totalCountParameter
).ToListAsync();
return new PagedData<MsgLog>()
{
Data = list,
TotalCount = (long)totalCountParameter.Value
};
}
public async Task<PagedData<BlockUser>> GetBlockUserList(string username, int pagesize, int pageindex)
{
var sp = "exec usp_Block_GetList @pageindex, @pagesize, @user, @count output";
var totalCountParameter = new SqlParameter("count", SqlDbType.BigInt) { Direction = ParameterDirection.Output, Value = 0 };
var list = await Database.SqlQuery<BlockUser>(
sp,
new SqlParameter("pageindex", SqlDbType.Int) { Value = pageindex },
new SqlParameter("pagesize", SqlDbType.Int) { Value = pagesize },
new SqlParameter("user", SqlDbType.VarChar, 100) { Value = username },
totalCountParameter
).ToListAsync();
return new PagedData<BlockUser>()
{
Data = list,
TotalCount = (long)totalCountParameter.Value
};
}
public async Task<PagedData<User>> GetUserList(string username, int pagesize, int pageindex)
{
var sp = "exec usp_User_GetList @pageindex, @pagesize, @user, @count output";
var totalCountParameter = new SqlParameter("count", SqlDbType.BigInt) { Direction = ParameterDirection.Output, Value = 0 };
var list = await Database.SqlQuery<User>(
sp,
new SqlParameter("pageindex", SqlDbType.Int) { Value = pageindex },
new SqlParameter("pagesize", SqlDbType.Int) { Value = pagesize },
new SqlParameter("user", SqlDbType.VarChar, 100) { Value = username ?? "" },
totalCountParameter
).ToListAsync();
return new PagedData<User>()
{
Data = list,
TotalCount = (long)totalCountParameter.Value
};
}
public async Task<PagedData<UserConnectLog>> GetConnectionLogList(string username, int pagesize, int pageindex)
{
var sp = "exec usp_ConnectionLog_GetList @pageindex, @pagesize, @user, @count output";
var totalCountParameter = new SqlParameter("count", SqlDbType.BigInt) { Direction = ParameterDirection.Output, Value = 0 };
var list = await Database.SqlQuery<UserConnectLog>(
sp,
new SqlParameter("pageindex", SqlDbType.Int) { Value = pageindex },
new SqlParameter("pagesize", SqlDbType.Int) { Value = pagesize },
new SqlParameter("user", SqlDbType.VarChar, 100) { Value = username },
totalCountParameter
).ToListAsync();
return new PagedData<UserConnectLog>()
{
Data = list,
TotalCount = (long)totalCountParameter.Value
};
}
}
}

View File

@ -56,6 +56,7 @@
<Compile Include="Entities\BlockUser.cs" />
<Compile Include="Entities\MsgLog.cs" />
<Compile Include="Entities\OnlineHistory.cs" />
<Compile Include="Entities\PagedData.cs" />
<Compile Include="Entities\Room.cs" />
<Compile Include="Entities\ServerGroup.cs" />
<Compile Include="Entities\User.cs" />

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ChatRoomServer.Db.Entities
{
public class PagedData<T>
{
public long TotalCount { get; set; }
public List<T> Data { get; set; }
}
}

View File

@ -61,8 +61,6 @@ namespace ChatRoomServer.Db.Entities
HasKey(m => m.ID);
Property(s => s.ID).HasMaxLength(50).IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Property(s => s.Name).HasMaxLength(200).IsRequired();
Ignore(s => s.OnlineCount);
}
}
}

View File

@ -43,6 +43,8 @@ namespace ChatRoomServer.Db.Entities
/// </summary>
public int? ElapsedTime { get; set; }
public string Ip { get; set; }
}
/// <summary>
@ -57,6 +59,7 @@ namespace ChatRoomServer.Db.Entities
Property(s => s.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(s => s.UserName).HasMaxLength(100).IsRequired();
Property(s => s.RoomID).HasMaxLength(100).IsRequired();
Property(s => s.Ip).IsRequired();
}
}
}

View File

@ -67,6 +67,7 @@ namespace ChatRoomServer.Main
}
});
}
_log.Info("已刷新屏蔽列表。");
//处理连接
GetAllSessions().ForEach(s =>
@ -115,13 +116,20 @@ namespace ChatRoomServer.Main
InitOnlineCountSync();
//黑名单
_blockUserReloadTimer = new Timer(1000 * 60 * 5) { AutoReset = false };
_blockUserReloadTimer = new Timer(1000 * 60 * 1) { AutoReset = false };
_blockUserReloadTimer.Elapsed += (s, e) =>
{
try
{
ReloadBlockUsers();
}
catch (Exception)
{
}
_blockUserReloadTimer.Start();
};
ReloadBlockUsers();
_blockUserReloadTimer.Start();
}
#region 线

View File

@ -94,7 +94,8 @@ namespace ChatRoomServer.Main
{
UserName = UserName,
ConnectTime = DateTime.Now,
RoomID = Id
RoomID = Id,
Ip = RemoteEndPoint.ToString()
};
db.UserConnectLogs.Add(ucl);
db.SaveChanges();

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace ChatRoomServer.Www.Areas.Api.Controllers
{
using System.Data.Entity;
using System.Threading.Tasks;
using ChatRoomServer.Db;
[Authorize]
[RoutePrefix("api/msgs")]
public class MsgsController : ApiController
{
[Route("list")]
public async Task<object> List([FromBody] Dictionary<string, string> query)
{
var searchUser = query.GetValue("searchUser") ?? "";
var pageIndex = query.GetValue("pageIndex").ToInt32(1);
var pagesize = query.GetValue("pagesize").ToInt32(20);
var db = new ChatDb();
var data = await db.GetMsgLogList(searchUser, pagesize, pageIndex);
var rooms = data.Data.Select(s => s.RoomId).Distinct().ToArray();
var roomdata = await db.Rooms.Where(s => rooms.Contains(s.ID)).ToDictionaryAsync(s => s.ID);
return new
{
count = data.TotalCount,
list = data.Data.Select(s => new
{
msg = s,
room = roomdata.GetValue(s.RoomId)
})
};
}
}
}

View File

@ -7,33 +7,178 @@ using System.Web.Http;
namespace ChatRoomServer.Www.Areas.Api.Controllers
{
using System.Data.Entity;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web.Http.Cors;
using System.Web.Http.Results;
using ChatRoomServer.Db;
using ChatRoomServer.Db.Entities;
[RoutePrefix("api/users")]
[RoutePrefix("api/users"), Authorize]
public class UsersController : ApiController
{
[Route("blockList")]
public async Task<object> BlockUsersList([FromBody] Dictionary<string, string> query)
{
var searchUser = query.GetValue("searchUser") ?? "";
var pageIndex = query.GetValue("pageIndex").ToInt32(1);
var pagesize = query.GetValue("pagesize").ToInt32(20);
var db = new ChatDb();
var data = await db.GetBlockUserList(searchUser, pagesize, pageIndex);
return new
{
count = data.TotalCount,
list = data.Data
};
}
[Route("connectionLog")]
public async Task<object> ConnectionLog([FromBody] Dictionary<string, string> query)
{
var searchUser = query.GetValue("searchUser") ?? "";
var pageIndex = query.GetValue("pageIndex").ToInt32(1);
var pagesize = query.GetValue("pagesize").ToInt32(20);
var db = new ChatDb();
var data = await db.GetConnectionLogList(searchUser, pagesize, pageIndex);
var rooms = data.Data.Select(s => s.RoomID).Distinct().ToArray();
var roomdata = await db.Rooms.Where(s => rooms.Contains(s.ID)).ToDictionaryAsync(s => s.ID);
return new
{
count = data.TotalCount,
list = data.Data.Select(s => new
{
msg = s,
room = roomdata.GetValue(s.RoomID)
})
};
}
[Route("list"), HttpGet]
public async Task<object> UserList(int pageindex, int pagesize, string user)
{
var db = new ChatDb();
var data = await db.GetUserList(user, pagesize, pageindex);
return new
{
count = data.TotalCount,
list = data.Data
};
}
[Route("abuseList")]
public bool AbuseList([FromBody]Dictionary<string, string> query)
public async Task<object> AbuseList([FromBody]Dictionary<string, string> query)
{
var pageindex = query.GetValue("pageIndex").ToInt32(1);
var pageSize = query.GetValue("pageSize").ToInt32(20);
var filter = query.GetValue("filter").ToInt32(-1);
var db=new ChatDb();
var dbquery = db.AbuseReports.AsNoTracking().AsQueryable();
if (filter != -1)
dbquery = dbquery.Where(s => s.Status == (ReportState)filter);
var totalCount = dbquery.Count();
var items = dbquery.Skip(pageSize*(pageindex - 1)).Take();
var db = new ChatDb();
var data = await db.GetAbuseReportPagedList(filter, pageindex, pageSize);
//rooms
var msgids = (from p in data.Data select p.TargetId).Distinct().ToArray();
var msgs = await db.MsgLogs.Where(s => msgids.Contains(s.Id)).ToDictionaryAsync(s => s.Id);
var roomids = (from p in msgs select p.Value.RoomId).Distinct().ToArray();
var rooms = await db.Rooms.Where(s => roomids.Contains(s.ID)).ToDictionaryAsync(s => s.ID);
return new
{
itemsCount = data.TotalCount,
items = data.Data.Select(s =>
new
{
id = s.Id,
msg = msgs[s.TargetId],
room = rooms[msgs[s.TargetId].RoomId],
info = s
})
};
}
[Route("updateAbuseReport")]
public async Task<object> UpdateAbuseState([FromBody] Dictionary<string, int> query)
{
var db = new ChatDb();
var item = await db.AbuseReports.FindAsync(query["id"]);
if (item == null || item.Status != ReportState.Submited)
return new { success = false, message = "report not found or has been processed." };
var newStatus = query["status"];
var msg = (string)null;
var result = true;
if (newStatus == 3)
{
//忽略
item.Status = ReportState.Invalid;
}
else if (newStatus == 1 || newStatus == 2)
{
var username = newStatus == 1 ? item.TargetUser : item.ReportUser;
DateTime? expiresTime;
result = BanUser(username, query["bantime"], out expiresTime);
item.Status = ReportState.Processed;
if (result)
msg = $"已屏蔽指定用户。用户名:{username},解封时间:" + (expiresTime.HasValue ? expiresTime.Value.ToString() : "永久") + "。";
else msg = "操作失败。";
}
await db.SaveChangesAsync();
return new { success = result, message = msg ?? "更新成功。" };
}
bool BanUser(string username, int banTime, out DateTime? expiresTime)
{
var db = new ChatDb();
//是否已经有屏蔽记录了?
var currentRule = db.GetBlockRuleForUser(username).LastOrDefault();
if (currentRule != null)
{
if (currentRule.UnblockTime != null)
{
//如果是隔期解开的,那么将会延长
if (banTime == 0)
{
expiresTime = null;
currentRule.UnblockTime = null;
}
else
{
currentRule.UnblockTime = currentRule.UnblockTime.Value.AddMinutes(banTime);
expiresTime = currentRule.UnblockTime;
}
}
else
{
expiresTime = null;
}
}
else
{
currentRule = new BlockUser()
{
BlockTime = DateTime.Now,
UserName = username,
UnblockTime = banTime == 0 ? null : (DateTime?)DateTime.Now.AddMinutes(300)
};
db.BlockUsers.Add(currentRule);
expiresTime = currentRule.UnblockTime;
}
db.SaveChanges();
return true;
}
}
}

View File

@ -141,6 +141,7 @@
<Compile Include="App_Start\WebApiConfig.cs" />
<Compile Include="Areas\Api\Controllers\AccountController.cs" />
<Compile Include="Areas\Api\Controllers\AnnouncementController.cs" />
<Compile Include="Areas\Api\Controllers\MsgsController.cs" />
<Compile Include="Areas\Api\Controllers\PicController.cs" />
<Compile Include="Areas\Api\Controllers\RoomController.cs" />
<Compile Include="Areas\Api\Controllers\StatController.cs" />
@ -149,6 +150,7 @@
<Compile Include="Controllers\AccountController.cs" />
<Compile Include="Controllers\AnnouncementController.cs" />
<Compile Include="Controllers\IndexController.cs" />
<Compile Include="Controllers\MsgsController.cs" />
<Compile Include="Controllers\RoomController.cs" />
<Compile Include="Controllers\UsersController.cs" />
<Compile Include="Global.asax.cs">
@ -165,6 +167,7 @@
<Content Include="Scripts\controller.js" />
<Content Include="Scripts\angularjs\angular.js" />
<Content Include="Scripts\bootstrap-notify.js" />
<Content Include="Scripts\underscore.js" />
<Content Include="Scripts\_references.js" />
<Content Include="Web.config" />
<Content Include="Web.Debug.config">
@ -190,6 +193,10 @@
<Content Include="Views\Account\Login.cshtml" />
<Content Include="Views\Index\Index.cshtml" />
<Content Include="Views\Users\AbuseList.cshtml" />
<Content Include="Views\Msgs\LogList.cshtml" />
<Content Include="Views\Users\ConnectionLog.cshtml" />
<Content Include="Views\Users\BlockList.cshtml" />
<Content Include="Views\Users\UserList.cshtml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Private\iFishOs\FSLib.Extension\src\FSLib.Extension.csproj">

View File

@ -2,9 +2,21 @@
padding-top: 70px;
}
table.table-topspace {
margin-top: 15px;
}
h1.divider, h2.divider, h3.divider, h4.divider, h5.divider, h6.divider {
border-bottom: 1px solid #eee;
padding-top: 15px;
padding-bottom: 15px;
margin-bottom: 15px;
}
.pagination select.form-control {
height: 18px;
padding: 0;
vertical-align: middle;
font-size: 12px;
display: inline-block;
width: auto;
}

View File

@ -13,5 +13,20 @@ namespace ChatRoomServer.Www.Controllers
{
return View();
}
public ActionResult ConnectionLog()
{
return View();
}
public ActionResult UserList()
{
return View();
}
public ActionResult BlockList()
{
return View();
}
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace ChatRoomServer.Www.Controllers
{
public class MsgsController : Controller
{
// GET: msgs
public ActionResult LogList()
{
return View();
}
}
}

View File

@ -9,6 +9,9 @@ using System.Web.Routing;
namespace ChatRoomServer.Www
{
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
@ -18,6 +21,14 @@ namespace ChatRoomServer.Www
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//set json naming method
var cfg = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
cfg.Formatting = Formatting.None;
cfg.ContractResolver = new CamelCasePropertyNamesContractResolver();
RouteTable.Routes.RouteExistingFiles = false;
RouteTable.Routes.AppendTrailingSlash = true;
RouteTable.Routes.LowercaseUrls = true;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Project: Bootstrap Notify = v3.1.3
* Project: Bootstrap Notify = v3.1.3 [mod]
* Description: Turns standard Bootstrap alerts into "Growl-like" notifications.
* Author: Mouse0270 aka Robert McIntosh
* License: MIT License
@ -147,9 +147,9 @@
}
break;
case "showProgressbar":
if(commands[command]===true){
if (commands[command] === true) {
this.$ele.find('[data-notify="progressbar"]').show();
}else{
} else {
this.$ele.find('[data-notify="progressbar"]').hide();
}
break;
@ -168,12 +168,70 @@
},
close: function () {
self.close();
return self;
},
delayClose: function (timeout) {
timeout = timeout || 2000;
setTimeout(function () {
self.close();
}, timeout);
return self;
},
hideProgress: function () {
self.notify.update('showProgressbar', false);
return self.notify;
},
showProgress: function () {
self.notify.update('showProgressbar', true);
return self.notify;
},
setProgress: function (progress) {
progress = progress || -1;
self.notify.update('progress', progress);
return self.notify;
},
setMessage: function (text) {
self.notify.update('message', text);
return self.notify;
},
setTitle: function (text) {
self.notify.update('title', text);
return self.notify;
},
setIcon: function (icon) {
self.notify.update('icon', icon);
return self.notify;
},
setType: function (type) {
self.notify.update('type', type);
return self.notify;
},
changeStatus:function(type, icon, title, message, progress) {
var notify = self.notify;
if (type)
notify.setType(type);
if (icon)
notify.setIcon(icon);
if (title)
notify.setTitle(title);
if (message)
notify.setMessage(message);
if (typeof (progress) !== 'undefined') {
if (progress === -2)
notify.hideProgress();
else {
notify.showProgress();
notify.setProgress(progress);
}
}
return notify;
}
};
},
buildNotify: function () {
var content = this.settings.content;
this.$ele = $(String.format(this.settings.template, this.settings.type, content.title, content.message, content.url, content.target, this.settings.size));
this.$ele = $(String.format(this.settings.template, this.settings.type, content.title || "", content.message || "", content.url, content.target, this.settings.size));
this.$ele.attr('data-notify-position', this.settings.placement.from + '-' + this.settings.placement.align);
if (!this.settings.allow_dismiss) {
this.$ele.find('[data-notify="dismiss"]').css('display', 'none');

View File

@ -10,6 +10,17 @@ var app = angular.module('chat12306', ['ngCookies']);
return input;
};
});
app.filter('jsonDate', function () {
return function (input) {
var data = /^(\d{4}-\d{2}-\d{2})T([\d\:]+)/i.exec(input || "");
return data && String.format("{0} {1}", data[1], data[2]) || input;
};
});
app.filter('abuseStatusDesc', function () {
return function (input) {
return ["未处理", "已处理", "已忽略", "已自动处理"][parseInt(input)];
};
});
app.filter('pagelist', function () {
return function (current, max, pagePerSide) {
max = parseInt(max);
@ -17,8 +28,7 @@ var app = angular.module('chat12306', ['ngCookies']);
pagePerSide = parseInt(pagePerSide) || 4;
var result = [];
for (var i = 1; i <= pagePerSide + 1; i++) {
if (i < max)
for (var i = 1; i <= pagePerSide + 1 && i <= max; i++) {
result.push(i);
}
if (current - pagePerSide > pagePerSide + 1 + 1) {
@ -31,7 +41,7 @@ var app = angular.module('chat12306', ['ngCookies']);
}
if (max - pagePerSide > current + pagePerSide + 1)
result.push(-2);
for (var k = max - pagePerSide; k <= max; k++) {
for (var k = max - pagePerSide; k >= 1 && k <= max; k++) {
result.push(k);
}
@ -110,10 +120,12 @@ var app = angular.module('chat12306', ['ngCookies']);
function abuseListController($scope, $http) {
abuseListController.$inject = ['$scope', '$http'];
var controlApi = "/api/users/updateAbuseReport";
$scope.filters = [{ typeid: -1, title: "所有" }, { typeid: 0, title: "未处理" }, { typeid: 1, title: "已处理" }, { typeid: 2, title: "已忽略" }, { typeid: 3, title: "已自动处理" }];
$scope.filterid = -1;
$scope.items = [{ title: "test" }];
$scope.pages = 20;
$scope.pages = 0;
$scope.pageSize = 50;
$scope.itemsCount = 0;
$scope.pageIndex = 1;
@ -137,7 +149,7 @@ var app = angular.module('chat12306', ['ngCookies']);
}, {
delay: 0,
progress: -1,
showProgressbar: false,
showProgressbar: true,
allow_dismiss: false,
placement: {
from: "top",
@ -152,7 +164,7 @@ var app = angular.module('chat12306', ['ngCookies']);
icon: "fa fa-check",
showProgressbar: false
});
setTimeout(notify.close, 2000);
notify.close();
$scope.items = data.items;
$scope.itemsCount = data.itemsCount || 0;
@ -161,9 +173,8 @@ var app = angular.module('chat12306', ['ngCookies']);
notify.update({
"title": "加载失败,请重试。服务器错误啦....",
type: "danger",
icon:"fa fa-ban",
showProgressbar: false,
placement: ""
icon: "fa fa-ban",
showProgressbar: false
});
setTimeout(notify.close, 2000);
$scope.items = [];
@ -184,9 +195,305 @@ var app = angular.module('chat12306', ['ngCookies']);
$scope.go = function (pageOffset) {
$scope.pageIndex = Math.max(1, Math.min($scope.pageIndex + pageOffset, $scope.pages));
};
$scope.reload = function () {
load();
};
//操作
$scope.op = function (index, status) {
var item = $scope.items[index];
if (!confirm("确认操作?"))
return;
var notify = $.notify({
title: "操作中,请稍等...",
"icon": "fa-spin fa fa-spinner",
type: "info"
}, {
delay: 0,
progress: -1,
showProgressbar: true,
allow_dismiss: false,
placement: {
from: "top",
align: "center"
}
});
$http.post(controlApi, { id: item.id, status: status, bantime: item.bantime || "0" })
.success(function (data) {
if (data.success) {
notify.update({
"title": "操作成功...",
type: "success",
icon: "fa fa-check",
showProgressbar: false
});
} else {
notify.changeStatus("danger", "fa fa-ban", "操作失败:" + data.message, null, -2);
}
setTimeout(notify.close, 2000);
$("tr[data-id=" + item.id + "] button.btn").remove();
}).error(function () {
notify.setTitle("操作失败,请重试。服务器错误啦....").setType("danger").setIcon("fa fa-ban").hideProgress().delayClose();
});
};
$scope.$watch("filterid+pageIndex", function () {
load();
});
}
})();
(function chatMessageListControllerContainer() {
function chatMessageListController($scope, $http) {
var listApi = "/api/msgs/list";
$scope.filter = {
searchUser: "",
pageIndex: 1,
pagesize: "20"
};
$scope.pages = 0;
$scope.itemsCount = 0;
$scope.items = [];
//加载
$scope.reload = function () {
var notify = $.notify({
title: "数据加载中...",
"icon": "fa-spin fa fa-spinner",
type: "info"
}, {
delay: 0,
progress: -1,
showProgressbar: true,
allow_dismiss: false,
placement: {
from: "top",
align: "center"
}
});
$http.post(listApi, $scope.filter)
.success(function (data) {
notify.update({
"title": "加载成功...",
type: "success",
icon: "fa fa-check",
showProgressbar: false
});
$scope.items = data.list;
$scope.itemsCount = data.count;
$scope.pages = Math.ceil($scope.itemsCount / parseInt($scope.filter.pagesize, 10));
setTimeout(notify.close, 2000);
}).error(function () {
notify.setTitle("加载失败,请重试。服务器错误啦....").setType("danger").setIcon("fa fa-ban").hideProgress().delayClose();
});
};
$scope.goPage = function (page) {
if (page <= 0)
return;
$scope.filter.pageIndex = page;
};
$scope.go = function (pageOffset) {
$scope.filter.pageIndex = Math.max(1, Math.min($scope.filter.pageIndex + pageOffset, $scope.pages));
};
$scope.$watch("filter", function (newvalue, oldvalue) {
$scope.reload();
}, true);
}
app.controller("ChatMessageListController", ['$scope', '$http', chatMessageListController]);
})();
(function ConnectionLogControllerContainer() {
function connectionLogController($scope, $http) {
var listApi = "/api/users/connectionlog";
$scope.filter = {
searchUser: "",
pageIndex: 1,
pagesize: "20"
};
$scope.pages = 0;
$scope.itemsCount = 0;
$scope.items = [];
//加载
$scope.reload = function () {
var notify = $.notify({
title: "数据加载中...",
"icon": "fa-spin fa fa-spinner",
type: "info"
}, {
delay: 0,
progress: -1,
showProgressbar: true,
allow_dismiss: false,
placement: {
from: "top",
align: "center"
}
});
$http.post(listApi, $scope.filter)
.success(function (data) {
notify.update({
"title": "加载成功...",
type: "success",
icon: "fa fa-check",
showProgressbar: false
});
$scope.items = data.list;
$scope.itemsCount = data.count;
$scope.pages = Math.ceil($scope.itemsCount / parseInt($scope.filter.pagesize, 10));
setTimeout(notify.close, 2000);
}).error(function () {
notify.setTitle("加载失败,请重试。服务器错误啦....").setType("danger").setIcon("fa fa-ban").hideProgress().delayClose();
});
};
$scope.goPage = function (page) {
if (page <= 0)
return;
$scope.filter.pageIndex = page;
};
$scope.go = function (pageOffset) {
$scope.filter.pageIndex = Math.max(1, Math.min($scope.filter.pageIndex + pageOffset, $scope.pages));
};
$scope.$watch("filter", function (newvalue, oldvalue) {
$scope.reload();
}, true);
}
app.controller("ConnectionLogController", ['$scope', '$http', connectionLogController]);
})();
//-------------------------------------------------------------
(function blockUserListControllerContainer() {
function blockUserListController($scope, $http) {
var listApi = "/api/users/blockList";
$scope.filter = {
searchUser: "",
pageIndex: 1,
pagesize: "20"
};
$scope.pages = 0;
$scope.itemsCount = 0;
$scope.items = [];
//加载
$scope.reload = function () {
var notify = $.notify({
title: "数据加载中...",
"icon": "fa-spin fa fa-spinner",
type: "info"
}, {
delay: 0,
progress: -1,
showProgressbar: true,
allow_dismiss: false,
placement: {
from: "top",
align: "center"
}
});
$http.post(listApi, $scope.filter)
.success(function (data) {
notify.update({
"title": "加载成功...",
type: "success",
icon: "fa fa-check",
showProgressbar: false
});
$scope.items = data.list;
$scope.itemsCount = data.count;
$scope.pages = Math.ceil($scope.itemsCount / parseInt($scope.filter.pagesize, 10));
setTimeout(notify.close, 2000);
}).error(function () {
notify.setTitle("加载失败,请重试。服务器错误啦....").setType("danger").setIcon("fa fa-ban").hideProgress().delayClose();
});
};
$scope.goPage = function (page) {
if (page <= 0)
return;
$scope.filter.pageIndex = page;
};
$scope.go = function (pageOffset) {
$scope.filter.pageIndex = Math.max(1, Math.min($scope.filter.pageIndex + pageOffset, $scope.pages));
};
$scope.$watch("filter", function (newvalue, oldvalue) {
$scope.reload();
}, true);
}
app.controller("BlockUserListController", ['$scope', '$http', blockUserListController]);
})();
//-------------------------------------------------------------
(function userListControllerContainer() {
function userListController($scope, $http) {
var listApi = "/api/users/list";
$scope.filter = {
user: "",
pageIndex: 1,
pagesize: "20"
};
$scope.pages = 0;
$scope.itemsCount = 0;
$scope.items = [];
//加载
$scope.reload = function () {
var notify = $.notify({
title: "数据加载中...",
"icon": "fa-spin fa fa-spinner",
type: "info"
}, {
delay: 0,
progress: -1,
showProgressbar: true,
allow_dismiss: false,
placement: {
from: "top",
align: "center"
}
});
$http.get(listApi, {
params: $scope.filter
})
.success(function (data) {
notify.update({
"title": "加载成功...",
type: "success",
icon: "fa fa-check",
showProgressbar: false
});
$scope.items = data.list;
$scope.itemsCount = data.count;
$scope.pages = Math.ceil($scope.itemsCount / parseInt($scope.filter.pagesize, 10));
setTimeout(notify.close, 2000);
}).error(function () {
notify.setTitle("加载失败,请重试。服务器错误啦....").setType("danger").setIcon("fa fa-ban").hideProgress().delayClose();
});
};
$scope.goPage = function (page) {
if (page <= 0)
return;
$scope.filter.pageIndex = page;
};
$scope.go = function (pageOffset) {
$scope.filter.pageIndex = Math.max(1, Math.min($scope.filter.pageIndex + pageOffset, $scope.pages));
};
$scope.$watch("filter", function (newvalue, oldvalue) {
$scope.reload();
}, true);
}
app.controller("UserListController", ['$scope', '$http', userListController]);
})();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
@{
ViewBag.Title = "聊天记录列表";
}
<div class="container" ng-app="chat12306" ng-controller="ChatMessageListController">
<div class="row">
<div class="col-sm-3">
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">搜索</div>
<input type="text" ng-change="filter.pageIndex=1" class="form-control" ng-model="filter.searchUser" id="" placeholder="按用户名搜索..." />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="filter.searchUser=''" ng-disabled="!filter.searchUser">
<i class="fa fa-times"></i>
</button>
</span>
</div>
</div>
</form>
</div>
</div>
<table class="table table-topspace table-bordered table-striped table-hover">
<tr>
<th>ID</th>
<th>房间</th>
<th>发送人</th>
<th>发送时间</th>
<th>发送IP</th>
<th>发送给</th>
</tr>
<tr ng-repeat-start="item in items">
<th>{{item.msg.id}}</th>
<th>{{item.room.name}}</th>
<th><a href="javascript:;" ng-click="filter.searchUser=item.msg.userName;">{{item.msg.userName}}</a></th>
<th>{{item.msg.sendTime|jsonDate}}</th>
<th>{{item.msg.ip}}</th>
<th>{{item.msg.atUser}}</th>
</tr>
<tr ng-repeat-end>
<td colspan="6">
<p>{{item.msg.content}}</p>
<p>
<img ng-src="img" ng-repeat="img in item.msg.image" />
</p>
</td>
</tr>
</table>
<nav>
<ul class="pagination">
<li>
<span>共 {{itemsCount}} 条记录,每页 {{filter.pagesize}} 条,共 {{ pages }} 页</span>
</li>
<li>
<span>
每页记录数
<select ng-model="filter.pagesize" class="form-control">
<option ng-repeat="ps in [10,20,30,40,50,100]" ng-value="ps">{{ps}}</option>
</select>
</span>
</li>
<li ng-class="filter.pageIndex>1?'':'disabled'">
<a href="javascript:;" ng-click="go(-1)" ng-disabled="filter.pageIndex<=1" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
<li ng-repeat="index in filter.pageIndex | pagelist:pages" ng-class="[index===filter.pageIndex?'active':'', index<0?'disabled':'']"><a href="javascript:;" ng-click="goPage(index)" ng-bind="index<0?'...':index"></a></li>
<li ng-class="filter.pageIndex<pages?'':'disabled'">
<a href="javascript:;" ng-click="go(1)" ng-disabled="filter.pageIndex<pages" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
<li>
<a href="javascript:;" ng-click="reload();">
<i class="glyphicon glyphicon-refresh"></i>
刷新数据
</a>
</li>
</ul>
</nav>
</div>

View File

@ -19,7 +19,7 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("12306聊天室管理", "Index", "Index", new { area = "" }, new { @class = "navbar-brand" })
@Html.ActionLink("12306聊天室管理", "Index", "Index", new {area = ""}, new {@class = "navbar-brand"})
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
@ -27,6 +27,17 @@
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">用户管理 <i class="caret"></i></a>
<ul class="dropdown-menu">
<li>@Html.ActionLink("举报管理", "AbuseList", "Users")</li>
<li>@Html.ActionLink("屏蔽列表", "BlockList", "Users")</li>
<li>@Html.ActionLink("连接日志", "ConnectionLog", "Users")</li>
<li>@Html.ActionLink("用户列表", "UserList", "Users")</li>
</ul>
</li>
<li class="dropdown">
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">聊天记录 <i class="caret"></i></a>
<ul class="dropdown-menu">
<li>
@Html.ActionLink("记录列表", "LogList", "Msgs")
</li>
</ul>
</li>
</ul>
@ -41,6 +52,7 @@
@Scripts.Render("~/scripts/bootstrap-notify.js")
@Scripts.Render("~/scripts/angularjs/angular.js")
@Scripts.Render("~/scripts/angularjs/angular-cookies.js")
@Scripts.Render("~/scripts/underscore.js")
@Scripts.Render("~/scripts/controller.js")
@RenderSection("scripts", required: false)
</body>

View File

@ -3,46 +3,64 @@
}
<div class="container" ng-app="chat12306" ng-controller="AbuseListController">
<div class="row">
<ul class="nav nav-pills">
<li ng-repeat="exp in filters" ng-class="[exp.typeid===filterid?'active':'']"><a href="javascript:;" ng-click="resetFilter(exp.typeid)">{{exp.title}}</a></li>
</ul>
<table id="rlist" class="table table-bordered table-striped table-hover margin-top-xs">
</div>
<div class="row">
<table id="rlist" class="table table-topspace table-bordered table-striped table-hover">
<tr>
<th>ID</th>
<th>房间</th>
<th>举报人</th>
<th>被举报人</th>
<th>举报时间</th>
<th>被举报人</th>
<th>消息时间</th>
<th>消息IP</th>
</tr>
<tr ng-repeat-start="item in items" data-id="{{item.id}}">
<th>{{item.id}}</th>
<th>{{item.room}}</th>
<th>{{item.username}}</th>
<th>{{item.targetuser}}</th>
<th>{{item.time}}</th>
<th>{{item.info.id}}</th>
<th>{{item.room.name}}</th>
<th>{{item.info.reportUser}}</th>
<th>{{item.msg.sendTime|jsonDate}}</th>
<th>{{item.info.targetUser}}</th>
<th>{{item.info.reportTime|jsonDate}}</th>
<th>{{item.msg.ip}}</th>
</tr>
<tr>
<td colspan="5">
{{item.content}}
<tr data-id="{{item.id}}">
<td colspan="7">
<p>{{item.msg.content}}</p>
<p>
<img ng-src="img" ng-repeat="img in item.msg.image" />
</p>
</td>
</tr>
<tr ng-repeat-end>
<td colspan="5" class="" style="text-align: right;">
<button type="button" class="btn btn-sm btn-primary" ng-click="blockTarget($index)">
<tr ng-repeat-end data-id="{{item.id}}">
<td>
<span class="label" ng-class="[item.info.status===0?'label-primary':'',item.info.status===1?'label-success':'',item.info.status===2?'label-default':'',item.info.status===3?'label-info':'']"><span ng-bind="item.info.status|abuseStatusDesc"></span></span>
</td>
<td colspan="6" class="text-right">
<select ng-show="item.info.status===0" ng-model="item.bantime">
<option value="">封锁时间</option>
<option ng-value="time" ng-repeat="time in [0, 30, 60, 90, 120, 150, 300, 600]">{{time==0?"永久":time+"分钟"}}</option>
</select>
<button ng-show="item.info.status===0" type="button" class="btn btn-sm btn-primary" ng-click="op($index, 1)">
<i class="glyphicon glyphicon-ok"></i>
封被举报人
</button>
<button type="button" class="btn btn-sm btn-danger" ng-click="blockSource($index)">
<button ng-show="item.info.status===0" type="button" class="btn btn-sm btn-danger" ng-click="op($index, 2)">
<i class="glyphicon glyphicon-user"></i>
封举报人
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="ignore($index)">
<button ng-show="item.info.status===0" type="button" class="btn btn-sm btn-default" ng-click="op($index, 3)">
<i class="glyphicon glyphicon-remove-sign"></i>
忽略
</button>
</td>
</tr>
</table>
</div>
<nav>
<ul class="pagination">
<li>
@ -59,6 +77,12 @@
<span aria-hidden="true">&raquo;</span>
</a>
</li>
<li>
<a href="javascript:;" ng-click="reload();">
<i class="glyphicon glyphicon-refresh"></i>
刷新数据
</a>
</li>
</ul>
</nav>
</div>

View File

@ -0,0 +1,70 @@
@{
ViewBag.Title = "用户连接日志";
}
<div class="container" ng-app="chat12306" ng-controller="BlockUserListController">
<div class="row">
<div class="col-sm-3">
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">搜索</div>
<input type="text" ng-change="filter.pageIndex=1" class="form-control" ng-model="filter.searchUser" id="" placeholder="按用户名搜索..." />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="filter.searchUser=''" ng-disabled="!filter.searchUser">
<i class="fa fa-times"></i>
</button>
</span>
</div>
</div>
</form>
</div>
</div>
<table class="table table-topspace table-bordered table-striped table-hover">
<tr>
<th>ID</th>
<th>用户名</th>
<th>屏蔽时间</th>
<th>解除时间</th>
</tr>
<tr ng-repeat="item in items">
<td>{{item.id}}</td>
<td><a href="javascript:;" ng-click="filter.searchUser=item.userName;">{{item.userName}}</a></td>
<td>{{item.blockTime|jsonDate}}</td>
<td>{{item.unblockTime||'永久' | jsonDate}}</td>
</tr>
</table>
<nav>
<ul class="pagination">
<li>
<span>共 {{itemsCount}} 条记录,每页 {{filter.pagesize}} 条,共 {{ pages }} 页</span>
</li>
<li>
<span>
每页记录数
<select ng-model="filter.pagesize" class="form-control">
<option ng-repeat="ps in [10,20,30,40,50,100]" ng-value="ps">{{ps}}</option>
</select>
</span>
</li>
<li ng-class="filter.pageIndex>1?'':'disabled'">
<a href="javascript:;" ng-click="go(-1)" ng-disabled="filter.pageIndex<=1" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
<li ng-repeat="index in filter.pageIndex | pagelist:pages" ng-class="[index===filter.pageIndex?'active':'', index<0?'disabled':'']"><a href="javascript:;" ng-click="goPage(index)" ng-bind="index<0?'...':index"></a></li>
<li ng-class="filter.pageIndex<pages?'':'disabled'">
<a href="javascript:;" ng-click="go(1)" ng-disabled="filter.pageIndex<pages" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
<li>
<a href="javascript:;" ng-click="reload();">
<i class="glyphicon glyphicon-refresh"></i>
刷新数据
</a>
</li>
</ul>
</nav>
</div>

View File

@ -0,0 +1,76 @@
@{
ViewBag.Title = "用户连接日志";
}
<div class="container" ng-app="chat12306" ng-controller="ConnectionLogController">
<div class="row">
<div class="col-sm-3">
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">搜索</div>
<input type="text" ng-change="filter.pageIndex=1" class="form-control" ng-model="filter.searchUser" id="" placeholder="按用户名搜索..." />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="filter.searchUser=''" ng-disabled="!filter.searchUser">
<i class="fa fa-times"></i>
</button>
</span>
</div>
</div>
</form>
</div>
</div>
<table class="table table-topspace table-bordered table-striped table-hover">
<tr>
<th>ID</th>
<th>用户名</th>
<th>房间</th>
<th>连接时间</th>
<th>断开时间</th>
<th>持续时间</th>
<th>IP</th>
</tr>
<tr ng-repeat="item in items">
<td>{{item.msg.id}}</td>
<td><a href="javascript:;" ng-click="filter.searchUser=item.msg.userName;">{{item.msg.userName}}</a></td>
<td>{{item.room.name}}</td>
<td>{{item.msg.connectTime|jsonDate}}</td>
<td>{{item.msg.disconnectTime|jsonDate}}</td>
<td>{{item.msg.elapsedTime/60|number:0}}分钟/{{item.msg.elapsedTime/3600 | number:2}}小时</td>
<td>{{item.msg.ip}}</td>
</tr>
</table>
<nav>
<ul class="pagination">
<li>
<span>共 {{itemsCount}} 条记录,每页 {{filter.pagesize}} 条,共 {{ pages }} 页</span>
</li>
<li>
<span>
每页记录数
<select ng-model="filter.pagesize" class="form-control">
<option ng-repeat="ps in [10,20,30,40,50,100]" ng-value="ps">{{ps}}</option>
</select>
</span>
</li>
<li ng-class="filter.pageIndex>1?'':'disabled'">
<a href="javascript:;" ng-click="go(-1)" ng-disabled="filter.pageIndex<=1" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
<li ng-repeat="index in filter.pageIndex | pagelist:pages" ng-class="[index===filter.pageIndex?'active':'', index<0?'disabled':'']"><a href="javascript:;" ng-click="goPage(index)" ng-bind="index<0?'...':index"></a></li>
<li ng-class="filter.pageIndex<pages?'':'disabled'">
<a href="javascript:;" ng-click="go(1)" ng-disabled="filter.pageIndex<pages" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
<li>
<a href="javascript:;" ng-click="reload();">
<i class="glyphicon glyphicon-refresh"></i>
刷新数据
</a>
</li>
</ul>
</nav>
</div>

View File

@ -0,0 +1,78 @@
@{
ViewBag.Title = "用户列表";
}
<div class="container" ng-app="chat12306" ng-controller="UserListController">
<div class="row">
<div class="col-sm-3">
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">搜索</div>
<input type="text" ng-change="filter.pageIndex=1" class="form-control" ng-model="filter.user" id="" placeholder="按用户名搜索..." />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="filter.user=''" ng-disabled="!filter.user">
<i class="fa fa-times"></i>
</button>
</span>
</div>
</div>
</form>
</div>
</div>
<table class="table table-topspace table-bordered table-striped table-hover">
<tr>
<th>用户名</th>
<th>显示名称</th>
<th>首次连接时间</th>
<th>最后连接时间</th>
<th>首次发言时间</th>
<th>最后发言时间</th>
<th>发言次数</th>
<th>在线时间</th>
</tr>
<tr ng-repeat="item in items">
<td><a href="javascript:;" ng-click="filter.user=item.userName;">{{item.userName}}</a></td>
<td>{{item.nickName}}</td>
<td>{{item.firstConnect|jsonDate}}</td>
<td>{{item.lastConnect|jsonDate}}</td>
<td>{{item.firstSend||'永久' | jsonDate}}</td>
<td>{{item.lastSend||'永久' | jsonDate}}</td>
<td>{{item.sendTimes}}</td>
<td>{{item.onlineTime/60|number:0}}分钟/{{item.onlineTime/3600 | number:2}}小时</td>
</tr>
</table>
<nav>
<ul class="pagination">
<li>
<span>共 {{itemsCount}} 条记录,每页 {{filter.pagesize}} 条,共 {{ pages }} 页</span>
</li>
<li>
<span>
每页记录数
<select ng-model="filter.pagesize" class="form-control">
<option ng-repeat="ps in [10,20,30,40,50,100]" ng-value="ps">{{ps}}</option>
</select>
</span>
</li>
<li ng-class="filter.pageIndex>1?'':'disabled'">
<a href="javascript:;" ng-click="go(-1)" ng-disabled="filter.pageIndex<=1" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
<li ng-repeat="index in filter.pageIndex | pagelist:pages" ng-class="[index===filter.pageIndex?'active':'', index<0?'disabled':'']"><a href="javascript:;" ng-click="goPage(index)" ng-bind="index<0?'...':index"></a></li>
<li ng-class="filter.pageIndex<pages?'':'disabled'">
<a href="javascript:;" ng-click="go(1)" ng-disabled="filter.pageIndex<pages" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
<li>
<a href="javascript:;" ng-click="reload();">
<i class="glyphicon glyphicon-refresh"></i>
刷新数据
</a>
</li>
</ul>
</nav>
</div>

View File

@ -1460,7 +1460,7 @@ var CFG_MANGER = (function () {
if (!callback)
return;
if (isServerLoaded && (!lastLoad || (new Date() - lastLoad) < 1000 * 60 * 10))
if (isServerLoaded && lastLoad && (new Date() - lastLoad) < 1000 * 60 * 10)
callback(servers);
else {
callbackQueue.push(callback);
@ -1476,6 +1476,8 @@ var CFG_MANGER = (function () {
servers = null;
isInServerLoading = false;
execCallback();
}).always(function () {
lastLoad = new Date();
});
}
}

View File

@ -13,6 +13,8 @@ using Newtonsoft.Json;
namespace TrainInfomationProviderService.StationInfo
{
using TrainInfomationProviderService.Web;
class SameStationManager
{
public static Dictionary<string, HashSet<string>> SameStationMap { get; private set; }
@ -117,7 +119,7 @@ namespace TrainInfomationProviderService.StationInfo
static bool GrabberFromWeb()
{
var ctx = new HttpClient().Create<string>(HttpMethod.Get, _url).Send();
var ctx = new HttpWebClient().Create<string>(HttpMethod.Get, _url).Send();
if (!ctx.IsValid())
return false;

View File

@ -16,6 +16,8 @@ using TrainInfomationProviderService.StationInfo.Entities;
namespace TrainInfomationProviderService.StationInfo
{
using TrainInfomationProviderService.Web;
/// <summary>
/// </summary>
public class StationManager
@ -156,7 +158,7 @@ namespace TrainInfomationProviderService.StationInfo
void RefreshStationInfo(int version)
{
Trace.TraceInformation("[STATION] 正在获得最新车站信息");
var html = new HttpClient().Create(HttpMethod.Get, "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js", null, null, "").Send();
var html = new HttpWebClient().Create(HttpMethod.Get, "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js", null, null, "").Send();
if (!html.IsValid())
{
Trace.TraceError("[STATION] 车站信息获得失败。错误:{0}", html.Exception);
@ -203,7 +205,7 @@ namespace TrainInfomationProviderService.StationInfo
/// <returns></returns>
public int GetLatestVersionFromWeb()
{
var ctx = new HttpClient().Create<string>(HttpMethod.Get, "https://kyfw.12306.cn/otn/leftTicket/init", "https://kyfw.12306.cn/otn/leftTicket/init").Send();
var ctx = new HttpWebClient().Create<string>(HttpMethod.Get, "https://kyfw.12306.cn/otn/leftTicket/init", "https://kyfw.12306.cn/otn/leftTicket/init").Send();
if (!ctx.IsValid())
return 0;

View File

@ -16,6 +16,8 @@ using TrainInfomationProviderService.TrainInfo.Entities;
namespace TrainInfomationProviderService.TrainInfo
{
using TrainInfomationProviderService.Web;
public class TrainInfoManager
{
private static readonly object _lockObject = new object();
@ -229,7 +231,7 @@ namespace TrainInfomationProviderService.TrainInfo
/// <returns></returns>
public int GetLatestVersionFromWeb()
{
var ctx = new HttpClient().Create<string>(HttpMethod.Get, "https://kyfw.12306.cn/otn/queryTrainInfo/init", "https://kyfw.12306.cn/otn/queryTrainInfo/init").Send();
var ctx = new HttpWebClient().Create<string>(HttpMethod.Get, "https://kyfw.12306.cn/otn/queryTrainInfo/init", "https://kyfw.12306.cn/otn/queryTrainInfo/init").Send();
if (!ctx.IsValid())
return 0;

View File

@ -16,6 +16,7 @@ using TrainInfomationProviderService.TrainInfo.Entities;
namespace TrainInfomationProviderService.TrainInfo
{
using System.Runtime.Serialization;
using TrainInfomationProviderService.Web;
class WebDataProvider
{
@ -101,7 +102,7 @@ namespace TrainInfomationProviderService.TrainInfo
public void LoadTrainInfo(IndexStorage indexStorage, Action saveCallback)
{
Trace.TraceInformation("[TRAIN_DATA_WEB_PROVIDER] 正在获得最新车次信息");
var html = new HttpClient().Create(HttpMethod.Get, "https://kyfw.12306.cn/otn/resources/js/query/train_list.js?scriptVersion=" + (new Random().NextDouble() + 1).ToString("#0.00000"), null, null, "").Send();
var html = new HttpWebClient().Create(HttpMethod.Get, "https://kyfw.12306.cn/otn/resources/js/query/train_list.js?scriptVersion=" + (new Random().NextDouble() + 1).ToString("#0.00000"), null, null, "").Send();
if (!html.IsValid())
{
Trace.TraceError("[TRAIN_DATA_WEB_PROVIDER] 车次信息获得失败。错误:{0}", html.Exception);
@ -171,9 +172,8 @@ namespace TrainInfomationProviderService.TrainInfo
}
//加载车次停靠站信息
LoadTrainStopInfo(++index, alltrains.Length, date, train);
if (curStorage.HashStore.Contains(train.TrainHash))
if (!LoadTrainStopInfo(++index, alltrains.Length, date, train) || curStorage.HashStore.Contains(train.TrainHash))
continue;
train.Init();
@ -224,14 +224,14 @@ namespace TrainInfomationProviderService.TrainInfo
return null;
}
internal void LoadTrainStopInfo(int index, int totalcount, string date, Train train)
internal bool LoadTrainStopInfo(int index, int totalcount, string date, Train train)
{
Trace.TraceInformation("[TRAIN_STOP_INFO_LOAER] [{2:#0}/{3:#0}] 正在加载车次 {1}/{0} 信息", train.Code, date, index, totalcount);
var tryCount = 0;
while (tryCount++ < 50)
{
var ctx = new HttpClient().Create(
var ctx = new HttpWebClient().Create(
HttpMethod.Get,
string.Format("https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no={0}&from_station_telecode={1}&to_station_telecode={2}&depart_date={3}", train.Id, train.From, train.To, date),
null,
@ -255,6 +255,7 @@ namespace TrainInfomationProviderService.TrainInfo
}
Trace.TraceInformation("[TRAIN_STOP_INFO_LOAER] 车次 {1}/{0} 信息加载过程结束", train.Code, date);
return train.TrainStops != null && train.TrainStops.Count > 0;
}
}

View File

@ -112,6 +112,7 @@
<Compile Include="Utility.cs" />
<Compile Include="Web\Controllers\TransitController.cs" />
<Compile Include="Web\Models\Dto\Station.cs" />
<Compile Include="Web\WebClient.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />

View File

@ -0,0 +1,53 @@
namespace TrainInfomationProviderService.Web
{
using System;
using System.Net;
using FSLib.Network.Http;
class HttpWebClient : HttpClient
{
public HttpWebClient()
: base(null, new WebHandler())
{
}
}
class WebHandler : HttpHandler
{
public WebHandler()
{
var proxy = System.Configuration.ConfigurationManager.AppSettings["web_proxy"];
if (!proxy.IsNullOrEmpty())
{
_proxy = new WebProxy(new Uri(proxy));
var username = System.Configuration.ConfigurationManager.AppSettings["web_proxy_username"];
if (!proxy.IsNullOrEmpty())
{
_proxy.UseDefaultCredentials = false;
_proxy.Credentials = new NetworkCredential(username, System.Configuration.ConfigurationManager.AppSettings["web_proxy_password"]);
}
}
}
WebProxy _proxy;
/// <summary>
/// 获得用于发送请求的Request对象
/// </summary>
/// <param name="uri"></param>
/// <param name="method"></param>
/// <returns></returns>
public override HttpWebRequest GetRequest(Uri uri, HttpMethod method, HttpContext context)
{
var request = base.GetRequest(uri, method, context);
if (_proxy != null)
request.Proxy = _proxy;
return request;
}
}
}

View File

@ -37,6 +37,11 @@
<add key="12306_keepaliveurl" value="http://test.fishlee.net/tt/keepalive" />
<add key="local_disable_train_provider" value="0" />
<add key="FSLib.MvcWeb.CsrfDefender.Disabled" value="1" />
<add key="web_proxy" value="http://connect.fishlee.net:51100/" />
<add key="web_proxy_username" value="fish" />
<add key="web_proxy_password" value="fish" />
</appSettings>
<connectionStrings>
<add name="chatroom" connectionString="Server=114.112.68.93;port=11119;Database=gopush;Uid=gopush;Pwd=c8488f421866b23758d52045429437c45;CharSet=utf8;" providerName="MySql.Data.MySqlClient" />

View File

@ -63,9 +63,9 @@
//加载服务器节点列表
servernode.loadServers();
setTimeout(function() {
setInterval(function() {
servernode.loadServers();
}, 1000 * 60 * 11);
}, 1000 * 60 * 10);
servernode.on("roomSelectHide", function () {
hideChatFrameUI();