sync
This commit is contained in:
parent
6bc60739f7
commit
5b6cecd2d9
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.22823.1
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Web12306", "Web12306\Web12306.csproj", "{56406C67-2B6F-4152-9EC0-E6D80E86B96D}"
|
||||
EndProject
|
||||
@ -14,8 +14,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{4C2B47
|
||||
.nuget\NuGet.targets = .nuget\NuGet.targets
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mobile12306New", "Mobile12306New\Mobile12306New.csproj", "{4B41EA5E-B7CD-4FC6-B9E3-9AE5222695F6}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildTools", "BuildTools", "{F6960416-F825-4800-8FD4-C72908A4A6CC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeployTools", "DeployTools\DeployTools.csproj", "{E958D106-A3EE-46AF-B3E5-E62FC96F2F94}"
|
||||
@ -66,10 +64,6 @@ Global
|
||||
{0C7635A7-78F5-459D-BBDE-CEEC51E546B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0C7635A7-78F5-459D-BBDE-CEEC51E546B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0C7635A7-78F5-459D-BBDE-CEEC51E546B9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4B41EA5E-B7CD-4FC6-B9E3-9AE5222695F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4B41EA5E-B7CD-4FC6-B9E3-9AE5222695F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4B41EA5E-B7CD-4FC6-B9E3-9AE5222695F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4B41EA5E-B7CD-4FC6-B9E3-9AE5222695F6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E958D106-A3EE-46AF-B3E5-E62FC96F2F94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E958D106-A3EE-46AF-B3E5-E62FC96F2F94}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E958D106-A3EE-46AF-B3E5-E62FC96F2F94}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@ -125,7 +119,6 @@ Global
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{56406C67-2B6F-4152-9EC0-E6D80E86B96D} = {5879D3F4-E7BB-4192-B4E3-9266AEB27D90}
|
||||
{0C7635A7-78F5-459D-BBDE-CEEC51E546B9} = {F6960416-F825-4800-8FD4-C72908A4A6CC}
|
||||
{4B41EA5E-B7CD-4FC6-B9E3-9AE5222695F6} = {5879D3F4-E7BB-4192-B4E3-9266AEB27D90}
|
||||
{E958D106-A3EE-46AF-B3E5-E62FC96F2F94} = {F6960416-F825-4800-8FD4-C72908A4A6CC}
|
||||
{BB9C6747-DC69-4EF1-A94C-85D8193B7105} = {F6960416-F825-4800-8FD4-C72908A4A6CC}
|
||||
{C385D043-316A-4F05-A6B9-E70BF0ED8DB6} = {89D11B10-8909-4682-A182-6FE4C1664B4E}
|
||||
|
@ -97,7 +97,27 @@ 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)
|
||||
/// <summary>
|
||||
/// 将针对指定用户的举报设置为已经处理
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <returns></returns>
|
||||
public Task<int> SetProcessedByUserNameAsync(string username)
|
||||
{
|
||||
return Database.ExecuteSqlCommandAsync("exec usp_BlockUser_ResetStatusByUserName {0}", username);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将针对指定用户的举报设置为已经处理
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<int> MarkProcessedAbuseReportAsync(string target, byte status)
|
||||
{
|
||||
return Database.ExecuteSqlCommandAsync("exec usp_MarkProcessedAbuseReport {0}, {1}", target, status);
|
||||
}
|
||||
|
||||
|
||||
public async Task<PagedData<AbuseReport>> GetAbuseReportPagedListAsync(int filter, int pageindex, int pagesize)
|
||||
{
|
||||
var totalCountParameter = new SqlParameter("totalCount", SqlDbType.BigInt) { Direction = ParameterDirection.Output, Value = 0 };
|
||||
|
||||
@ -116,7 +136,7 @@ namespace ChatRoomServer.Db
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<PagedData<MsgLog>> GetMsgLogList(string username, int pagesize, int pageindex)
|
||||
public async Task<PagedData<MsgLog>> GetMsgLogListAsync(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 };
|
||||
@ -135,7 +155,7 @@ namespace ChatRoomServer.Db
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<PagedData<BlockUser>> GetBlockUserList(string username, int pagesize, int pageindex)
|
||||
public async Task<PagedData<BlockUser>> GetBlockUserListAsync(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 };
|
||||
@ -154,7 +174,7 @@ namespace ChatRoomServer.Db
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<PagedData<User>> GetUserList(string username, int pagesize, int pageindex)
|
||||
public async Task<PagedData<User>> GetUserListAsync(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 };
|
||||
@ -173,7 +193,7 @@ namespace ChatRoomServer.Db
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<PagedData<UserConnectLog>> GetConnectionLogList(string username, int pagesize, int pageindex)
|
||||
public async Task<PagedData<UserConnectLog>> GetConnectionLogListAsync(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 };
|
||||
|
@ -46,6 +46,28 @@ namespace ChatRoomServer.Db.Entities
|
||||
|
||||
public string NickName { get; set; }
|
||||
|
||||
public int AbuseReportCount { get; set; }
|
||||
|
||||
|
||||
public int AbuseReportSuccCount { get; set; }
|
||||
|
||||
public int AbuseReportFailCount { get; set; }
|
||||
|
||||
public bool DisableAbuseReport { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 失败率
|
||||
/// </summary>
|
||||
public double AbuseReportSuccRate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (AbuseReportCount == 0)
|
||||
return 1.0;
|
||||
|
||||
return AbuseReportSuccCount * 1.0 / AbuseReportCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum UserStatus
|
||||
@ -64,6 +86,7 @@ namespace ChatRoomServer.Db.Entities
|
||||
ToTable("Chat_User");
|
||||
HasKey(m => m.UserName);
|
||||
Property(s => s.UserName).HasMaxLength(100).IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
|
||||
Ignore(s => s.AbuseReportSuccRate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,4 +33,4 @@ using System.Runtime.InteropServices;
|
||||
// 方法是按如下所示使用“*”:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5759.2")]
|
||||
|
@ -12,6 +12,10 @@
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
<UpdateAssemblyVersion>False</UpdateAssemblyVersion>
|
||||
<UpdateAssemblyFileVersion>True</UpdateAssemblyFileVersion>
|
||||
<UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
|
||||
<AssemblyFileVersionSettings>None.None.DeltaDayStamp.Increment</AssemblyFileVersionSettings>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -9,6 +9,7 @@ namespace ChatRoomServer.Main
|
||||
using ChatRoomServer.Db;
|
||||
using ChatRoomServer.Db.Entities;
|
||||
using ChatRoomServer.Main.Entities;
|
||||
using ChatRoomServer.Main.Room;
|
||||
using FSLib.Logs.Log4Net;
|
||||
using FSLib.Network.SuperSocket.Protocols.WebSocket;
|
||||
using FSLib.Network.SuperSocket.SocketBase;
|
||||
@ -35,6 +36,11 @@ namespace ChatRoomServer.Main
|
||||
|
||||
public string NickName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得或设置房间
|
||||
/// </summary>
|
||||
public RoomContainer RoomContainer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID
|
||||
/// </summary>
|
||||
@ -200,6 +206,17 @@ namespace ChatRoomServer.Main
|
||||
switch (item.UserMsgType)
|
||||
{
|
||||
case UserMessageType.Send:
|
||||
|
||||
//check username
|
||||
if (item.ToUsers != null && item.ToUsers.Length > 0)
|
||||
{
|
||||
var notOnlineUsers = item.ToUsers.Where(x => !RoomContainer.IsUserInRoom(x.UserName)).ToArray();
|
||||
if (!notOnlineUsers.IsEmpty())
|
||||
{
|
||||
item.Content += $"【系统提示:用户 {notOnlineUsers.Select(s => s.NickName).JoinAsString("、")} 已不在线。】";
|
||||
}
|
||||
}
|
||||
|
||||
//log to db
|
||||
var db = new ChatDb();
|
||||
var msg = new MsgLog()
|
||||
@ -232,30 +249,50 @@ namespace ChatRoomServer.Main
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessReport(long msgid)
|
||||
async void ProcessReport(long msgid)
|
||||
{
|
||||
if (msgid <= 0)
|
||||
return;
|
||||
|
||||
var db = new ChatDb();
|
||||
var msg = db.MsgLogs.Find(msgid);
|
||||
if (msg == null)
|
||||
//查找当前用户资料
|
||||
var currentUser = db.Users.Find(UserName);
|
||||
if (currentUser.DisableAbuseReport)
|
||||
{
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: false, content: "很抱歉,管理员已暂时关闭了您的举报权限。"));
|
||||
return;
|
||||
}
|
||||
if (currentUser.AbuseReportSuccRate < 0.1)
|
||||
{
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: false, content: "很抱歉,您当前举报成功率过低(<0.2),系统暂时不接受您新的举报。已有举报未通过审核时,请等待管理员审核。"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//此消息是否已经被举报过了?
|
||||
if (db.AbuseReports.Any(s => s.TargetId == msgid && s.ReportUser == UserName))
|
||||
{
|
||||
//重复举报
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: false, content: "这条消息您已经举报过哦。"));
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: false, content: "这条消息您已经举报过哦,请不要重复举报消息。"));
|
||||
return;
|
||||
}
|
||||
|
||||
var msg = db.MsgLogs.Find(msgid);
|
||||
if (msg == null)
|
||||
return;
|
||||
var dispName = db.Users.Find(msg.UserName)?.NickName ?? "";
|
||||
|
||||
//是否已经有屏蔽记录了?
|
||||
currentUser.AbuseReportCount++;
|
||||
|
||||
var currentRule = db.GetBlockRuleForUser(msg.UserName).LastOrDefault();
|
||||
if (currentRule != null)
|
||||
{
|
||||
|
||||
if (currentRule.UnblockTime != null)
|
||||
{
|
||||
currentUser.AbuseReportSuccCount++;
|
||||
|
||||
db.AbuseReports.Add(new AbuseReport()
|
||||
{
|
||||
ReportTime = DateTime.Now,
|
||||
@ -268,15 +305,16 @@ namespace ChatRoomServer.Main
|
||||
//如果是隔期解开的,那么将会延长十五分钟
|
||||
var extra = _isAdmin ? 300 : 15;
|
||||
currentRule.UnblockTime = currentRule.UnblockTime.Value.AddMinutes(_isAdmin ? 300 : 15);
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"已经举报成功。由于您的添砖加瓦,用户【{msg.UserName}】将会在小黑屋中多享受 {extra} 分钟的幸福时光 ♪(´ε`)"));
|
||||
OnRequireSendMessage(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"已经举报成功。由于您的添砖加瓦,用户【{msg.UserName}】将会在小黑屋中多享受 {extra} 分钟的幸福时光 ♪(´ε`)"), true);
|
||||
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"您已举报成功。由于您的添砖加瓦,用户【{dispName}({msg.UserName})】将会在小黑屋中多享受 {extra} 分钟的幸福时光。(您已举报 {currentUser.AbuseReportCount}次,成功 {currentUser.AbuseReportSuccCount}次,成功率 {currentUser.AbuseReportSuccRate:P1})"));
|
||||
|
||||
OnRequireSendMessage(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"{currentUser.NickName} 已经举报成功。由于TA的添砖加瓦,用户【{dispName}({msg.UserName})】将会在小黑屋中多享受 {extra} 分钟的幸福时光。({currentUser.NickName} 已举报 {currentUser.AbuseReportCount}次,成功 {currentUser.AbuseReportSuccCount}次,成功率 {currentUser.AbuseReportSuccRate:P1})"), true);
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
else
|
||||
{
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"无需举报,用户【{msg.UserName}】已经暂时不会从小黑屋里粗来了"));
|
||||
OnRequireSendMessage(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"无需举报,用户【{msg.UserName}】已经暂时不会从小黑屋里粗来了"), true);
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"无需举报,用户【{dispName}({msg.UserName})】已经暂时不会从小黑屋里粗来了"));
|
||||
}
|
||||
|
||||
return;
|
||||
@ -301,6 +339,8 @@ namespace ChatRoomServer.Main
|
||||
DateTime? unblockTime = null;
|
||||
if (_isAdmin)
|
||||
{
|
||||
currentUser.AbuseReportSuccCount++;
|
||||
|
||||
currentRule = new BlockUser()
|
||||
{
|
||||
BlockTime = DateTime.Now,
|
||||
@ -309,13 +349,15 @@ namespace ChatRoomServer.Main
|
||||
};
|
||||
db.BlockUsers.Add(currentRule);
|
||||
unblockTime = currentRule.UnblockTime;
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"您已将用户【{msg.UserName}】请到小黑屋里享受幸福至少五个小时。如果有更多人举报,呆的时间将会延长。"));
|
||||
OnRequireSendMessage(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"用户【{msg.UserName}】已经被管理员请到小黑屋里享受幸福至少五个小时。如果有更多人举报,呆的时间将会延长。"), true);
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"您已将用户【{dispName}({msg.UserName})】请到小黑屋里享受幸福至少五个小时。如果有更多人举报,呆的时间将会延长。(您已举报 {currentUser.AbuseReportCount}次,成功 {currentUser.AbuseReportSuccCount}次,成功率 {currentUser.AbuseReportSuccRate:P1})"));
|
||||
OnRequireSendMessage(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"用户【{dispName}({msg.UserName})】已经被管理员 {currentUser.NickName} 请到小黑屋里享受幸福至少五个小时。如果有更多人举报,呆的时间将会延长。({currentUser.NickName} 已举报 {currentUser.AbuseReportCount}次,成功 {currentUser.AbuseReportSuccCount}次,成功率 {currentUser.AbuseReportSuccRate:P1})"), true);
|
||||
|
||||
blocked = true;
|
||||
}
|
||||
else if ((currentReportCount = db.GetUserAbuseReportCountInTime(msg.UserName, 15)) > 5)
|
||||
{
|
||||
currentUser.AbuseReportSuccCount++;
|
||||
|
||||
currentRule = new BlockUser()
|
||||
{
|
||||
BlockTime = DateTime.Now,
|
||||
@ -324,21 +366,24 @@ namespace ChatRoomServer.Main
|
||||
};
|
||||
db.BlockUsers.Add(currentRule);
|
||||
unblockTime = currentRule.UnblockTime;
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"您已将用户【{msg.UserName}】请到小黑屋里享受幸福至少十五分钟。"));
|
||||
OnRequireSendMessage(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"用户【{msg.UserName}】已经被管理员请到小黑屋里享受幸福至少十五分钟。如果有更多人举报,呆的时间将会延长。"), true);
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"您的举报已经触发自动处理规则,用户【{dispName}({msg.UserName})】将被请到小黑屋里享受幸福至少十五分钟。(您已举报 {currentUser.AbuseReportCount}次,成功 {currentUser.AbuseReportSuccCount}次,成功率 {currentUser.AbuseReportSuccRate:P1})"));
|
||||
OnRequireSendMessage(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"【{currentUser.NickName}】 对【{dispName}({msg.UserName})】的举报已经满足自动处理规则,{dispName} 将会被请到小黑屋里享受幸福至少十五分钟。如果有更多人举报,呆的时间将会延长。({currentUser.NickName} 已举报 {currentUser.AbuseReportCount}次,成功 {currentUser.AbuseReportSuccCount}次,成功率 {currentUser.AbuseReportSuccRate:P1})"), true);
|
||||
|
||||
blocked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"举报成功,等待管理员审核。用户【{msg.UserName}】在过去的十五分钟时间内已经被举报 {currentReportCount} 次,如果达到五次将会被自动封禁。"));
|
||||
OnRequireSendMessage(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"用户【{msg.UserName}】在过去的十五分钟时间内已经被举报 {currentReportCount} 次,如果达到五次将会被自动封禁。"), true);
|
||||
TrySend(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"举报成功,等待管理员审核。用户【{dispName}({msg.UserName})】在过去的十五分钟时间内已经被举报 {currentReportCount} 次,如果达到五次将会被自动封禁。(您已举报 {currentUser.AbuseReportCount}次,成功 {currentUser.AbuseReportSuccCount}次,成功率 {currentUser.AbuseReportSuccRate:P1})"));
|
||||
OnRequireSendMessage(new MessageItem(SystemMessageType.ReportAbuseResult, success: true, content: $"【{currentUser.NickName}】 对【{dispName}({msg.UserName})】的举报已记录。用户【{dispName}({msg.UserName})】在过去的十五分钟时间内已经被举报 {currentReportCount} 次,如果达到五次将会被自动封禁。({currentUser.NickName} 已举报 {currentUser.AbuseReportCount}次,成功 {currentUser.AbuseReportSuccCount}次,成功率 {currentUser.AbuseReportSuccRate:P1})"), true);
|
||||
}
|
||||
db.SaveChanges();
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
//即时封锁
|
||||
if (blocked)
|
||||
{
|
||||
//自动标记之前的举报
|
||||
await db.MarkProcessedAbuseReportAsync(msg.UserName, 3);
|
||||
|
||||
(AppServer as ChatServer).AddBlockUser(msg.UserName, unblockTime);
|
||||
}
|
||||
}
|
||||
|
@ -33,4 +33,4 @@ using System.Runtime.InteropServices;
|
||||
// 方法是按如下所示使用“*”:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5759.7")]
|
||||
|
@ -12,20 +12,30 @@ namespace ChatRoomServer.Main.Room
|
||||
class RoomContainer
|
||||
{
|
||||
ConcurrentDictionary<ChatSession, RoomSessionContext> _contexts = new ConcurrentDictionary<ChatSession, RoomSessionContext>();
|
||||
|
||||
/// <summary>
|
||||
/// 获得或设置房间ID
|
||||
/// </summary>
|
||||
public string Id { get; private set; }
|
||||
ConcurrentDictionary<string, HashSet<ChatSession>> _users = new ConcurrentDictionary<string, HashSet<ChatSession>>();
|
||||
|
||||
public RoomContainer(string id)
|
||||
{
|
||||
Id = id;
|
||||
}
|
||||
|
||||
private void Session_RequireSendMessage(object sender, RequireSendMessageEventArgs e)
|
||||
{
|
||||
var enumerator = _contexts.GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (!e.ExcludeSender || sender != enumerator.Current.Key)
|
||||
enumerator.Current.Key.TrySend(e.MessageItem);
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(ChatSession session)
|
||||
{
|
||||
var ctx = _contexts.GetOrAdd(session, new RoomSessionContext());
|
||||
var list = _users.GetOrAdd(session.UserName, _ => new HashSet<ChatSession>());
|
||||
list.Add(session);
|
||||
|
||||
session.RoomContainer = this;
|
||||
|
||||
var count = _contexts.Count;
|
||||
var enumerator = _contexts.GetEnumerator();
|
||||
@ -43,14 +53,14 @@ namespace ChatRoomServer.Main.Room
|
||||
session.RequireSendMessage += Session_RequireSendMessage;
|
||||
}
|
||||
|
||||
private void Session_RequireSendMessage(object sender, RequireSendMessageEventArgs e)
|
||||
/// <summary>
|
||||
/// 判断指定的用户是否在线
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsUserInRoom(string user)
|
||||
{
|
||||
var enumerator = _contexts.GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (!e.ExcludeSender || sender != enumerator.Current.Key)
|
||||
enumerator.Current.Key.TrySend(e.MessageItem);
|
||||
}
|
||||
return _users.ContainsKey(user);
|
||||
}
|
||||
|
||||
public void Remove(ChatSession session)
|
||||
@ -59,6 +69,20 @@ namespace ChatRoomServer.Main.Room
|
||||
if (!_contexts.TryRemove(session, out context))
|
||||
return;
|
||||
|
||||
HashSet<ChatSession> sessions;
|
||||
if (_users.TryGetValue(session.UserName, out sessions))
|
||||
{
|
||||
lock (sessions)
|
||||
{
|
||||
if (sessions.Contains(session))
|
||||
sessions.Remove(session);
|
||||
|
||||
if (sessions.Count == 0)
|
||||
_users.TryRemove(session.UserName, out sessions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var count = _contexts.Count;
|
||||
var enumerator = _contexts.GetEnumerator();
|
||||
var data = count + "\t" + session.UserName + "\t" + session.NickName;
|
||||
@ -72,6 +96,11 @@ namespace ChatRoomServer.Main.Room
|
||||
session.RequireSendMessage -= Session_RequireSendMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得或设置房间ID
|
||||
/// </summary>
|
||||
public string Id { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得会话数
|
||||
/// </summary>
|
||||
|
@ -23,7 +23,7 @@ namespace ChatRoomServer.Www.Areas.Api.Controllers
|
||||
var pagesize = query.GetValue("pagesize").ToInt32(20);
|
||||
var db = new ChatDb();
|
||||
|
||||
var data = await db.GetMsgLogList(searchUser, pagesize, pageIndex);
|
||||
var data = await db.GetMsgLogListAsync(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);
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace ChatRoomServer.Www.Areas.Api.Controllers
|
||||
var pagesize = query.GetValue("pagesize").ToInt32(20);
|
||||
var db = new ChatDb();
|
||||
|
||||
var data = await db.GetBlockUserList(searchUser, pagesize, pageIndex);
|
||||
var data = await db.GetBlockUserListAsync(searchUser, pagesize, pageIndex);
|
||||
|
||||
return new
|
||||
{
|
||||
@ -43,7 +43,7 @@ namespace ChatRoomServer.Www.Areas.Api.Controllers
|
||||
var pagesize = query.GetValue("pagesize").ToInt32(20);
|
||||
var db = new ChatDb();
|
||||
|
||||
var data = await db.GetConnectionLogList(searchUser, pagesize, pageIndex);
|
||||
var data = await db.GetConnectionLogListAsync(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);
|
||||
|
||||
@ -64,7 +64,7 @@ namespace ChatRoomServer.Www.Areas.Api.Controllers
|
||||
{
|
||||
var db = new ChatDb();
|
||||
|
||||
var data = await db.GetUserList(user, pagesize, pageindex);
|
||||
var data = await db.GetUserListAsync(user, pagesize, pageindex);
|
||||
|
||||
return new
|
||||
{
|
||||
@ -82,7 +82,7 @@ namespace ChatRoomServer.Www.Areas.Api.Controllers
|
||||
var filter = query.GetValue("filter").ToInt32(-1);
|
||||
|
||||
var db = new ChatDb();
|
||||
var data = await db.GetAbuseReportPagedList(filter, pageindex, pageSize);
|
||||
var data = await db.GetAbuseReportPagedListAsync(filter, pageindex, pageSize);
|
||||
|
||||
//rooms
|
||||
var msgids = (from p in data.Data select p.TargetId).Distinct().ToArray();
|
||||
@ -115,32 +115,49 @@ namespace ChatRoomServer.Www.Areas.Api.Controllers
|
||||
var newStatus = query["status"];
|
||||
var msg = (string)null;
|
||||
var result = true;
|
||||
var user = db.Users.Find(item.ReportUser);
|
||||
|
||||
if (newStatus == 3)
|
||||
{
|
||||
//忽略
|
||||
item.Status = ReportState.Invalid;
|
||||
user.AbuseReportFailCount++;
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
else if (newStatus == 1 || newStatus == 2)
|
||||
{
|
||||
var username = newStatus == 1 ? item.TargetUser : item.ReportUser;
|
||||
DateTime? expiresTime;
|
||||
result = BanUser(username, query["bantime"], out expiresTime);
|
||||
if (newStatus == 1)
|
||||
{
|
||||
user.AbuseReportSuccCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
user.AbuseReportFailCount++;
|
||||
}
|
||||
|
||||
item.Status = ReportState.Processed;
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var username = newStatus == 1 ? item.TargetUser : item.ReportUser;
|
||||
var ret = await BanUser(username, query["bantime"], newStatus == 1);
|
||||
result = ret.Key;
|
||||
var expiresTime = ret.Value;
|
||||
|
||||
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)
|
||||
async Task<KeyValuePair<bool, DateTime?>> BanUser(string username, int banTime, bool isTargetUser)
|
||||
{
|
||||
var db = new ChatDb();
|
||||
DateTime? expiresTime;
|
||||
|
||||
//是否已经有屏蔽记录了?
|
||||
var currentRule = db.GetBlockRuleForUser(username).LastOrDefault();
|
||||
if (currentRule != null)
|
||||
@ -176,9 +193,15 @@ namespace ChatRoomServer.Www.Areas.Api.Controllers
|
||||
expiresTime = currentRule.UnblockTime;
|
||||
}
|
||||
|
||||
db.SaveChanges();
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return true;
|
||||
if (isTargetUser)
|
||||
{
|
||||
//await db.SetProcessedByUserNameAsync(username);
|
||||
await db.MarkProcessedAbuseReportAsync(username, 1);
|
||||
}
|
||||
|
||||
return new KeyValuePair<bool, DateTime?>(true, expiresTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,10 @@
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<UseGlobalApplicationHostFile />
|
||||
<UpdateAssemblyVersion>False</UpdateAssemblyVersion>
|
||||
<UpdateAssemblyFileVersion>True</UpdateAssemblyFileVersion>
|
||||
<UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
|
||||
<AssemblyFileVersionSettings>None.None.DeltaDayStamp.Increment</AssemblyFileVersionSettings>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -32,4 +32,4 @@ using System.Runtime.InteropServices;
|
||||
// 你可以指定所有值,也可以让修订版本和内部版本号采用默认值,
|
||||
// 方法是按如下所示使用 "*":
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5759.1")]
|
||||
|
@ -232,6 +232,7 @@ var app = angular.module('chat12306', ['ngCookies']);
|
||||
notify.changeStatus("danger", "fa fa-ban", "操作失败:" + data.message, null, -2);
|
||||
}
|
||||
setTimeout(notify.close, 2000);
|
||||
load();
|
||||
|
||||
$("tr[data-id=" + item.id + "] button.btn").remove();
|
||||
}).error(function () {
|
||||
|
@ -32,7 +32,7 @@
|
||||
<td colspan="7">
|
||||
<p>{{item.msg.content}}</p>
|
||||
<p>
|
||||
<img ng-src="img" ng-repeat="img in item.msg.image" />
|
||||
<img ng-src="{{item.msg.image}}" ng-if="item.msg.image" />
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -21,10 +21,12 @@ namespace TrainInfomationProviderService.StationInfo
|
||||
|
||||
private static Timer _timer;
|
||||
internal static string _cacheUrl;
|
||||
internal static string _blackHashesUrl;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
_cacheUrl = PathUtility.Combine(RunTimeContext.DataStorageRoot, "samestation.json");
|
||||
_blackHashesUrl = PathUtility.Combine(RunTimeContext.DataStorageRoot, "blocksamestation.json");
|
||||
SameStationMap = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
LoadCache();
|
||||
|
||||
@ -78,6 +80,7 @@ namespace TrainInfomationProviderService.StationInfo
|
||||
|
||||
var count = map.Count;
|
||||
var stations = StationManager.Instance.Storage.StationNameMap.Values.OrderByDescending(s => s.Name.Length).ToList();
|
||||
var blockStations = File.Exists(_blackHashesUrl) ? JsonConvert.DeserializeObject<Dictionary<string, HashSet<string>>>(File.ReadAllText(_blackHashesUrl)) : new Dictionary<string, HashSet<string>>();
|
||||
|
||||
while (stations.Count > 0)
|
||||
{
|
||||
@ -85,9 +88,10 @@ namespace TrainInfomationProviderService.StationInfo
|
||||
stations.RemoveAt(stations.Count - 1);
|
||||
|
||||
HashSet<string> collection = null;
|
||||
var blackList = blockStations.GetValue(st.Code);
|
||||
for (var i = stations.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (stations[i].Name.IndexOf(st.Name) != 0)
|
||||
if (stations[i].Name.IndexOf(st.Name) != 0 || blackList?.Contains(stations[i].Code) == true)
|
||||
continue;
|
||||
|
||||
(collection ?? (collection = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { st.Code })).Add(stations[i].Code);
|
||||
|
@ -114,16 +114,37 @@ namespace TrainInfomationProviderService.TrainInfo
|
||||
//发车经过车站
|
||||
var fromStations = GetSameStations(from);
|
||||
var toStations = GetSameStations(to);
|
||||
var fromTrains = fromStations.Select(s => infoStorage.StationLeftTrainData.GetValue(s)).ExceptNull().SelectMany(s => s).ToArray();
|
||||
var toTrains = toStations.Select(s => infoStorage.StationArriveTrainData.GetValue(s)).ExceptNull().SelectMany(s => s).ToArray();
|
||||
var fromTrains = fromStations.Select(s => infoStorage.StationLeftTrainData.GetValue(s)).ExceptNull().SelectMany(s => s).ToHashSet();
|
||||
var toTrains = toStations.Select(s => infoStorage.StationArriveTrainData.GetValue(s)).ExceptNull().SelectMany(s => s).ToHashSet();
|
||||
|
||||
//排除交集
|
||||
var exclude = fromTrains.Intersect(toTrains).ToHashSet();
|
||||
exclude.ForEach(s =>
|
||||
{
|
||||
fromTrains.Remove(s);
|
||||
toTrains.Remove(s);
|
||||
});
|
||||
|
||||
foreach (var fromTrain in fromTrains)
|
||||
{
|
||||
var startStop = FindStop(fromTrain, from);
|
||||
|
||||
//如果这车过终点站,则忽略
|
||||
if (FindStop(fromTrain, to) != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var fstop in fromTrain.TrainStops.SkipWhile(x => startStop != x).Skip(1).Where(s => s != null && !string.IsNullOrEmpty(s.Code)))
|
||||
{
|
||||
foreach (var toTrain in toTrains)
|
||||
{
|
||||
//如果这车过发车站,则忽略
|
||||
if (FindStop(toTrain, from) != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var toStop = FindStop(toTrain, to);
|
||||
foreach (var tStop in toTrain.TrainStops.TakeWhile(x => toStop != x).Where(s => s != null && !string.IsNullOrEmpty(s.Code)))
|
||||
{
|
||||
|
@ -13,6 +13,10 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
<UpdateAssemblyVersion>False</UpdateAssemblyVersion>
|
||||
<UpdateAssemblyFileVersion>True</UpdateAssemblyFileVersion>
|
||||
<UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
|
||||
<AssemblyFileVersionSettings>None.None.DeltaDayStamp.Increment</AssemblyFileVersionSettings>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
@ -102,9 +102,9 @@ namespace TrainInfomationProviderService.Web.Controllers
|
||||
[ActionName("tor")]
|
||||
public ActionResult TransitOnceRouting(string from, string to, DateTime date, int? maxAge)
|
||||
{
|
||||
if (String.IsNullOrEmpty(from))
|
||||
if (string.IsNullOrEmpty(from))
|
||||
throw new ArgumentException("from is null or empty.", "from");
|
||||
if (String.IsNullOrEmpty(to))
|
||||
if (string.IsNullOrEmpty(to))
|
||||
throw new ArgumentException("to is null or empty.", "to");
|
||||
|
||||
if (date < DateTime.Now.Date || date > DateTime.Now.Date.AddDays(59))
|
||||
|
@ -3,18 +3,43 @@
|
||||
z-index: 2;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(to bottom, #d17f2d, #C26B14);
|
||||
color: #ffffff;
|
||||
border: 1px solid #d67e29;
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
line-height: 14px;
|
||||
background: linear-gradient(to bottom, #d17f2d, #C26B14);
|
||||
transition: all ease-in-out 0.2s;
|
||||
}
|
||||
|
||||
#chat_float_tip > div:nth-child(1) {
|
||||
margin-right: 5px;
|
||||
border-right: 1px solid #FFE5CA;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding: 10px 7px 10px 7px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#chat_float_tip > div:nth-child(2) {
|
||||
height: 100%;
|
||||
padding: 10px 10px 10px 10px;
|
||||
margin-left: 20px;
|
||||
cursor: pointer;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
#chat_float_tip.off {
|
||||
right: -140px;
|
||||
}
|
||||
|
||||
#chat_float_tip span {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#chat_float_tip:hover {
|
||||
#chat_float_tip > div:hover {
|
||||
background: linear-gradient(to bottom, #e48b31, #d17519);
|
||||
}
|
||||
|
@ -1087,7 +1087,11 @@
|
||||
</article>
|
||||
<article id="chat">
|
||||
<section id="chat_float_tip">
|
||||
当前有 <span></span> 位票友正在聊天,快来加入吧!
|
||||
<div class="close"><i class="fa fa-caret-right"></i>
|
||||
</div>
|
||||
<div>
|
||||
聊天室<span></span>人在线
|
||||
</div>
|
||||
</section>
|
||||
<section id="chat_frame">
|
||||
<header>
|
||||
|
@ -57,6 +57,10 @@
|
||||
|
||||
return result;
|
||||
};
|
||||
exports.disableSameStations = {
|
||||
"NFF": ["NYF"],
|
||||
"NYF": ["NFF"]
|
||||
};
|
||||
exports.findSimilarStationInfos = function (name) {
|
||||
var extractname = null;
|
||||
//查找最接近的站点
|
||||
@ -70,9 +74,10 @@
|
||||
return code ? [{ code: code.c, name: name }] : [];
|
||||
}
|
||||
|
||||
var disableSameStations = exports.disableSameStations[exports.citynameMap[extractname].c] || [];
|
||||
var result = [];
|
||||
_.each(exports.citynameMap, function (c) {
|
||||
if (c.n.indexOf(extractname) === 0)
|
||||
if (c.n.indexOf(extractname) === 0 && $.inArray(c.c, disableSameStations) === -1)
|
||||
result.push({ code: c.c, name: c.n });
|
||||
});
|
||||
|
||||
@ -149,14 +154,14 @@
|
||||
/// <summary>获得站票的席别代码</summary>
|
||||
|
||||
for (var code in exports.emptySeatCodeArray) {
|
||||
if(!exports.emptySeatCodeArray.hasOwnProperty(code)||!ticketMap[exports.emptySeatCodeArray[code]])
|
||||
if (!exports.emptySeatCodeArray.hasOwnProperty(code) || !ticketMap[exports.emptySeatCodeArray[code]])
|
||||
continue;
|
||||
|
||||
return exports.emptySeatCodeArray[code];
|
||||
}
|
||||
};
|
||||
exports.findSeatData = function(ticketMap, code) {
|
||||
return ticketMap[code] || (function() {
|
||||
exports.findSeatData = function (ticketMap, code) {
|
||||
return ticketMap[code] || (function () {
|
||||
var codemap = exports.displayMap[code];
|
||||
if (!codemap)
|
||||
return null;
|
||||
@ -332,7 +337,7 @@
|
||||
exports.maxRecentCity = 18;
|
||||
exports.suggestRefreshInterval = 60000;
|
||||
Object.defineProperty(exports, "fastSubmitOrderSkipVc", {
|
||||
get: function() {
|
||||
get: function () {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
@ -1,103 +1,604 @@
|
||||
define(function (require, exports, module) {
|
||||
var calendarData = [
|
||||
0xA4B, 0x5164B, 0x6A5, 0x6D4, 0x415B5, 0x2B6, 0x957, 0x2092F, 0x497, 0x60C96, 0xD4A, 0xEA5, 0x50DA9, 0x5AD, 0x2B6, 0x3126E, 0x92E, 0x7192D, 0xC95, 0xD4A, 0x61B4A, 0xB55, 0x56A,
|
||||
0x4155B, 0x25D, 0x92D, 0x2192B, 0xA95, 0x71695, 0x6CA, 0xB55, 0x50AB5, 0x4DA, 0xA5B, 0x30A57, 0x52B, 0x8152A, 0xE95, 0x6AA, 0x615AA, 0xAB5, 0x4B6, 0x414AE, 0xA57, 0x526, 0x31D26,
|
||||
0xD95, 0x70B55, 0x56A, 0x96D, 0x5095D, 0x4AD, 0xA4D, 0x41A4D, 0xD25, 0x81AA5, 0xB54, 0xB6A, 0x612DA, 0x95B, 0x49B, 0x41497, 0xA4B, 0xA164B, 0x6A5, 0x6D4, 0x615B4, 0xAB6, 0x957,
|
||||
0x5092F, 0x497, 0x64B, 0x30D4A, 0xEA5, 0x80D65, 0x5AC, 0xAB6, 0x5126D, 0x92E, 0xC96, 0x41A95, 0xD4A, 0xDA5, 0x20B55, 0x56A, 0x7155B, 0x25D, 0x92D, 0x5192B, 0xA95, 0xB4A, 0x416AA,
|
||||
0xAD5, 0x90AB5, 0x4BA, 0xA5B, 0x60A57, 0x52B, 0xA93, 0x40E95
|
||||
];
|
||||
var madd = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 206, 334];
|
||||
var numString = "一二三四五六七八九十";
|
||||
var monString = "正二三四五六七八九十冬腊";
|
||||
var cYear, cMonth, cDay, theDate;
|
||||
var extend = function (o, c) {
|
||||
if (o && c && typeof c == "object") {
|
||||
for (var p in c) {
|
||||
o[p] = c[p];
|
||||
}
|
||||
}
|
||||
return o;
|
||||
};
|
||||
|
||||
var getBit = function (m, n) { return (m >> n) & 1; };
|
||||
var creatLenArr = function (year, month, len, start) {
|
||||
var arr = [];
|
||||
start = start || 0;
|
||||
if (len < 1) return arr;
|
||||
var k = start;
|
||||
for (var i = 0; i < len; i++) {
|
||||
arr.push({ year: year, month: month, day: k });
|
||||
k++;
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
var e2c = function () {
|
||||
theDate = (arguments.length != 3) ? new Date() : new Date(arguments[0], arguments[1], arguments[2]);
|
||||
var total, m, n, k;
|
||||
var isEnd = false;
|
||||
var tmp = theDate.getFullYear();
|
||||
total = (tmp - 1921) * 365 + Math.floor((tmp - 1921) / 4) + madd[theDate.getMonth()] + theDate.getDate() - 38;
|
||||
if (theDate.getYear() % 4 == 0 && theDate.getMonth() > 1) {
|
||||
total++;
|
||||
}
|
||||
for (m = 0; ; m++) {
|
||||
k = (calendarData[m] < 0xfff) ? 11 : 12;
|
||||
for (n = k; n >= 0; n--) {
|
||||
if (total <= 29 + getBit(calendarData[m], n)) {
|
||||
isEnd = true;
|
||||
break;
|
||||
}
|
||||
total = total - 29 - getBit(calendarData[m], n);
|
||||
}
|
||||
if (isEnd) break;
|
||||
}
|
||||
cYear = 1921 + m;
|
||||
cMonth = k - n + 1;
|
||||
cDay = total;
|
||||
if (k == 12) {
|
||||
if (cMonth == Math.floor(calendarData[m] / 0x10000) + 1) {
|
||||
cMonth = 1 - cMonth;
|
||||
}
|
||||
if (cMonth > Math.floor(calendarData[m] / 0x10000) + 1) {
|
||||
cMonth--;
|
||||
var errorCode = { //错误码列表
|
||||
100: '输入的年份超过了可查询范围,仅支持1891至2100年',
|
||||
101: '参数输入错误,请查阅文档'
|
||||
};
|
||||
|
||||
var cache = null; //某年相同计算进行cache,以加速计算速度
|
||||
var cacheUtil = { //cache管理工具
|
||||
current: '',
|
||||
setCurrent: function (year) {
|
||||
if (this.current != year) {
|
||||
this.current = year;
|
||||
this.clear();
|
||||
}
|
||||
},
|
||||
set: function (key, value) {
|
||||
if (!cache) cache = {};
|
||||
cache[key] = value;
|
||||
return cache[key];
|
||||
},
|
||||
get: function (key) {
|
||||
if (!cache) cache = {};
|
||||
return cache[key];
|
||||
},
|
||||
clear: function () {
|
||||
cache = null;
|
||||
}
|
||||
};
|
||||
var getcDateString = function () {
|
||||
var tmp = "";
|
||||
if (cMonth < 1) {
|
||||
tmp += "(闰)";
|
||||
tmp += monString.charAt(-cMonth - 1);
|
||||
} else {
|
||||
tmp += monString.charAt(cMonth - 1);
|
||||
}
|
||||
tmp += "月";
|
||||
tmp += getShortDateString();
|
||||
return tmp;
|
||||
|
||||
var formateDayD4 = function (month, day) {
|
||||
month = month + 1;
|
||||
month = month < 10 ? '0' + month : month;
|
||||
day = day < 10 ? '0' + day : day;
|
||||
return 'd' + month + day;
|
||||
};
|
||||
var getShortDateString = function () {
|
||||
var tmp = (cDay < 11) ? "初" : ((cDay < 20) ? "十" : ((cDay < 30) ? "廿" : "三十"));
|
||||
if (cDay % 10 != 0 || cDay == 10) {
|
||||
tmp += numString.charAt((cDay - 1) % 10);
|
||||
|
||||
var minYear = 1890;//最小年限
|
||||
var maxYear = 2100;//最大年限
|
||||
var DATA = {
|
||||
heavenlyStems: ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'], //天干
|
||||
earthlyBranches: ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'], //地支
|
||||
zodiac: ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'], //对应地支十二生肖
|
||||
solarTerm: ['小寒', '大寒', '立春', '雨水', '惊蛰', '春分', '清明', '谷雨', '立夏', '小满', '芒种', '夏至', '小暑', '大暑', '立秋', '处暑', '白露', '秋分', '寒露', '霜降', '立冬', '小雪', '大雪', '冬至'], //二十四节气
|
||||
monthCn: ['正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'],
|
||||
dateCn: ['初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十', '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十', '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十', '卅一']
|
||||
};
|
||||
|
||||
//中国节日放假安排,外部设置,0无特殊安排,1工作,2放假
|
||||
var worktime = {};
|
||||
//默认设置2013-2014年放假安排
|
||||
worktime.y2013 = { "d0101": 2, "d0102": 2, "d0103": 2, "d0105": 1, "d0106": 1, "d0209": 2, "d0210": 2, "d0211": 2, "d0212": 2, "d0213": 2, "d0214": 2, "d0215": 2, "d0216": 1, "d0217": 1, "d0404": 2, "d0405": 2, "d0406": 2, "d0407": 1, "d0427": 1, "d0428": 1, "d0429": 2, "d0430": 2, "d0501": 2, "d0608": 1, "d0609": 1, "d0610": 2, "d0611": 2, "d0612": 2, "d0919": 2, "d0920": 2, "d0921": 2, "d0922": 1, "d0929": 1, "d1001": 2, "d1002": 2, "d1003": 2, "d1004": 2, "d1005": 2, "d1006": 2, "d1007": 2, "d1012": 1 };
|
||||
worktime.y2014 = { "d0101": 2, "d0126": 1, "d0131": 2, "d0201": 2, "d0202": 2, "d0203": 2, "d0204": 2, "d0205": 2, "d0206": 2, "d0208": 1, "d0405": 2, "d0407": 2, "d0501": 2, "d0502": 2, "d0503": 2, "d0504": 1, "d0602": 2, "d0908": 2, "d0928": 1, "d1001": 2, "d1002": 2, "d1003": 2, "d1004": 2, "d1005": 2, "d1006": 2, "d1007": 2, "d1011": 1 };
|
||||
|
||||
//公历节日
|
||||
var solarFestival = {
|
||||
'd0101': '元旦节',
|
||||
'd0202': '世界湿地日',
|
||||
'd0210': '国际气象节',
|
||||
'd0214': '情人节',
|
||||
'd0301': '国际海豹日',
|
||||
'd0303': '全国爱耳日',
|
||||
'd0305': '学雷锋纪念日',
|
||||
'd0308': '妇女节',
|
||||
'd0312': '植树节 孙中山逝世纪念日',
|
||||
'd0314': '国际警察日',
|
||||
'd0315': '消费者权益日',
|
||||
'd0317': '中国国医节 国际航海日',
|
||||
'd0321': '世界森林日 消除种族歧视国际日 世界儿歌日',
|
||||
'd0322': '世界水日',
|
||||
'd0323': '世界气象日',
|
||||
'd0324': '世界防治结核病日',
|
||||
'd0325': '全国中小学生安全教育日',
|
||||
'd0330': '巴勒斯坦国土日',
|
||||
'd0401': '愚人节 全国爱国卫生运动月(四月) 税收宣传月(四月)',
|
||||
'd0407': '世界卫生日',
|
||||
'd0422': '世界地球日',
|
||||
'd0423': '世界图书和版权日',
|
||||
'd0424': '亚非新闻工作者日',
|
||||
'd0501': '劳动节',
|
||||
'd0504': '青年节',
|
||||
'd0505': '碘缺乏病防治日',
|
||||
'd0508': '世界红十字日',
|
||||
'd0512': '国际护士节',
|
||||
'd0515': '国际家庭日',
|
||||
'd0517': '世界电信日',
|
||||
'd0518': '国际博物馆日',
|
||||
'd0520': '全国学生营养日',
|
||||
'd0522': '国际生物多样性日',
|
||||
'd0523': '国际牛奶日',
|
||||
'd0531': '世界无烟日',
|
||||
'd0601': '国际儿童节',
|
||||
'd0605': '世界环境日',
|
||||
'd0606': '全国爱眼日',
|
||||
'd0617': '防治荒漠化和干旱日',
|
||||
'd0623': '国际奥林匹克日',
|
||||
'd0625': '全国土地日',
|
||||
'd0626': '国际禁毒日',
|
||||
'd0701': '香港回归纪念日 中共诞辰 世界建筑日',
|
||||
'd0702': '国际体育记者日',
|
||||
'd0707': '抗日战争纪念日',
|
||||
'd0711': '世界人口日',
|
||||
'd0730': '非洲妇女日',
|
||||
'd0801': '建军节',
|
||||
'd0808': '中国男子节(爸爸节)',
|
||||
'd0815': '抗日战争胜利纪念',
|
||||
'd0908': '国际扫盲日 国际新闻工作者日',
|
||||
'd0909': '毛泽东逝世纪念',
|
||||
'd0910': '中国教师节',
|
||||
'd0914': '世界清洁地球日',
|
||||
'd0916': '国际臭氧层保护日',
|
||||
'd0918': '九一八事变纪念日',
|
||||
'd0920': '国际爱牙日',
|
||||
'd0927': '世界旅游日',
|
||||
'd0928': '孔子诞辰',
|
||||
'd1001': '国庆节 世界音乐日 国际老人节',
|
||||
'd1002': '国际和平与民主自由斗争日',
|
||||
'd1004': '世界动物日',
|
||||
'd1006': '老人节',
|
||||
'd1008': '全国高血压日 世界视觉日',
|
||||
'd1009': '世界邮政日 万国邮联日',
|
||||
'd1010': '辛亥革命纪念日 世界精神卫生日',
|
||||
'd1013': '世界保健日 国际教师节',
|
||||
'd1014': '世界标准日',
|
||||
'd1015': '国际盲人节(白手杖节)',
|
||||
'd1016': '世界粮食日',
|
||||
'd1017': '世界消除贫困日',
|
||||
'd1022': '世界传统医药日',
|
||||
'd1024': '联合国日 世界发展信息日',
|
||||
'd1031': '世界勤俭日',
|
||||
'd1107': '十月社会主义革命纪念日',
|
||||
'd1108': '中国记者日',
|
||||
'd1109': '全国消防安全宣传教育日',
|
||||
'd1110': '世界青年节',
|
||||
'd1111': '国际科学与和平周(本日所属的一周)',
|
||||
'd1112': '孙中山诞辰纪念日',
|
||||
'd1114': '世界糖尿病日',
|
||||
'd1117': '国际大学生节 世界学生节',
|
||||
'd1121': '世界问候日 世界电视日',
|
||||
'd1129': '国际声援巴勒斯坦人民国际日',
|
||||
'd1201': '世界艾滋病日',
|
||||
'd1203': '世界残疾人日',
|
||||
'd1205': '国际经济和社会发展志愿人员日',
|
||||
'd1208': '国际儿童电视日',
|
||||
'd1209': '世界足球日',
|
||||
'd1210': '世界人权日',
|
||||
'd1212': '西安事变纪念日',
|
||||
'd1213': '南京大屠杀(1937年)纪念日!紧记血泪史!',
|
||||
'd1220': '澳门回归纪念',
|
||||
'd1221': '国际篮球日',
|
||||
'd1224': '平安夜',
|
||||
'd1225': '圣诞节',
|
||||
'd1226': '毛泽东诞辰纪念'
|
||||
};
|
||||
|
||||
//农历节日
|
||||
var lunarFestival = {
|
||||
'd0101': '春节',
|
||||
'd0115': '元宵节',
|
||||
'd0202': '龙抬头节',
|
||||
'd0323': '妈祖生辰',
|
||||
'd0505': '端午节',
|
||||
'd0707': '七夕节',
|
||||
'd0715': '中元节',
|
||||
'd0815': '中秋节',
|
||||
'd0909': '重阳节',
|
||||
'd1015': '下元节',
|
||||
'd1208': '腊八节',
|
||||
'd1223': '小年',
|
||||
'd0100': '除夕'
|
||||
}
|
||||
|
||||
return tmp;
|
||||
/**
|
||||
* 1890 - 2100 年的农历数据
|
||||
* 数据格式:[0,2,9,21936]
|
||||
* [闰月所在月,0为没有闰月; *正月初一对应公历月; *正月初一对应公历日; *农历每月的天数的数组(需转换为二进制,得到每月大小,0=小月(29日),1=大月(30日));]
|
||||
*/
|
||||
var lunarInfo = [[2, 1, 21, 22184], [0, 2, 9, 21936], [6, 1, 30, 9656], [0, 2, 17, 9584], [0, 2, 6, 21168], [5, 1, 26, 43344], [0, 2, 13, 59728], [0, 2, 2, 27296], [3, 1, 22, 44368], [0, 2, 10, 43856], [8, 1, 30, 19304], [0, 2, 19, 19168], [0, 2, 8, 42352], [5, 1, 29, 21096], [0, 2, 16, 53856], [0, 2, 4, 55632], [4, 1, 25, 27304], [0, 2, 13, 22176], [0, 2, 2, 39632], [2, 1, 22, 19176], [0, 2, 10, 19168], [6, 1, 30, 42200], [0, 2, 18, 42192], [0, 2, 6, 53840], [5, 1, 26, 54568], [0, 2, 14, 46400], [0, 2, 3, 54944], [2, 1, 23, 38608], [0, 2, 11, 38320], [7, 2, 1, 18872], [0, 2, 20, 18800], [0, 2, 8, 42160], [5, 1, 28, 45656], [0, 2, 16, 27216], [0, 2, 5, 27968], [4, 1, 24, 44456], [0, 2, 13, 11104], [0, 2, 2, 38256], [2, 1, 23, 18808], [0, 2, 10, 18800], [6, 1, 30, 25776], [0, 2, 17, 54432], [0, 2, 6, 59984], [5, 1, 26, 27976], [0, 2, 14, 23248], [0, 2, 4, 11104], [3, 1, 24, 37744], [0, 2, 11, 37600], [7, 1, 31, 51560], [0, 2, 19, 51536], [0, 2, 8, 54432], [6, 1, 27, 55888], [0, 2, 15, 46416], [0, 2, 5, 22176], [4, 1, 25, 43736], [0, 2, 13, 9680], [0, 2, 2, 37584], [2, 1, 22, 51544], [0, 2, 10, 43344], [7, 1, 29, 46248], [0, 2, 17, 27808], [0, 2, 6, 46416], [5, 1, 27, 21928], [0, 2, 14, 19872], [0, 2, 3, 42416], [3, 1, 24, 21176], [0, 2, 12, 21168], [8, 1, 31, 43344], [0, 2, 18, 59728], [0, 2, 8, 27296], [6, 1, 28, 44368], [0, 2, 15, 43856], [0, 2, 5, 19296], [4, 1, 25, 42352], [0, 2, 13, 42352], [0, 2, 2, 21088], [3, 1, 21, 59696], [0, 2, 9, 55632], [7, 1, 30, 23208], [0, 2, 17, 22176], [0, 2, 6, 38608], [5, 1, 27, 19176], [0, 2, 15, 19152], [0, 2, 3, 42192], [4, 1, 23, 53864], [0, 2, 11, 53840], [8, 1, 31, 54568], [0, 2, 18, 46400], [0, 2, 7, 46752], [6, 1, 28, 38608], [0, 2, 16, 38320], [0, 2, 5, 18864], [4, 1, 25, 42168], [0, 2, 13, 42160], [10, 2, 2, 45656], [0, 2, 20, 27216], [0, 2, 9, 27968], [6, 1, 29, 44448], [0, 2, 17, 43872], [0, 2, 6, 38256], [5, 1, 27, 18808], [0, 2, 15, 18800], [0, 2, 4, 25776], [3, 1, 23, 27216], [0, 2, 10, 59984], [8, 1, 31, 27432], [0, 2, 19, 23232], [0, 2, 7, 43872], [5, 1, 28, 37736], [0, 2, 16, 37600], [0, 2, 5, 51552], [4, 1, 24, 54440], [0, 2, 12, 54432], [0, 2, 1, 55888], [2, 1, 22, 23208], [0, 2, 9, 22176], [7, 1, 29, 43736], [0, 2, 18, 9680], [0, 2, 7, 37584], [5, 1, 26, 51544], [0, 2, 14, 43344], [0, 2, 3, 46240], [4, 1, 23, 46416], [0, 2, 10, 44368], [9, 1, 31, 21928], [0, 2, 19, 19360], [0, 2, 8, 42416], [6, 1, 28, 21176], [0, 2, 16, 21168], [0, 2, 5, 43312], [4, 1, 25, 29864], [0, 2, 12, 27296], [0, 2, 1, 44368], [2, 1, 22, 19880], [0, 2, 10, 19296], [6, 1, 29, 42352], [0, 2, 17, 42208], [0, 2, 6, 53856], [5, 1, 26, 59696], [0, 2, 13, 54576], [0, 2, 3, 23200], [3, 1, 23, 27472], [0, 2, 11, 38608], [11, 1, 31, 19176], [0, 2, 19, 19152], [0, 2, 8, 42192], [6, 1, 28, 53848], [0, 2, 15, 53840], [0, 2, 4, 54560], [5, 1, 24, 55968], [0, 2, 12, 46496], [0, 2, 1, 22224], [2, 1, 22, 19160], [0, 2, 10, 18864], [7, 1, 30, 42168], [0, 2, 17, 42160], [0, 2, 6, 43600], [5, 1, 26, 46376], [0, 2, 14, 27936], [0, 2, 2, 44448], [3, 1, 23, 21936], [0, 2, 11, 37744], [8, 2, 1, 18808], [0, 2, 19, 18800], [0, 2, 8, 25776], [6, 1, 28, 27216], [0, 2, 15, 59984], [0, 2, 4, 27424], [4, 1, 24, 43872], [0, 2, 12, 43744], [0, 2, 2, 37600], [3, 1, 21, 51568], [0, 2, 9, 51552], [7, 1, 29, 54440], [0, 2, 17, 54432], [0, 2, 5, 55888], [5, 1, 26, 23208], [0, 2, 14, 22176], [0, 2, 3, 42704], [4, 1, 23, 21224], [0, 2, 11, 21200], [8, 1, 31, 43352], [0, 2, 19, 43344], [0, 2, 7, 46240], [6, 1, 27, 46416], [0, 2, 15, 44368], [0, 2, 5, 21920], [4, 1, 24, 42448], [0, 2, 12, 42416], [0, 2, 2, 21168], [3, 1, 22, 43320], [0, 2, 9, 26928], [7, 1, 29, 29336], [0, 2, 17, 27296], [0, 2, 6, 44368], [5, 1, 26, 19880], [0, 2, 14, 19296], [0, 2, 3, 42352], [4, 1, 24, 21104], [0, 2, 10, 53856], [8, 1, 30, 59696], [0, 2, 18, 54560], [0, 2, 7, 55968], [6, 1, 27, 27472], [0, 2, 15, 22224], [0, 2, 5, 19168], [4, 1, 25, 42216], [0, 2, 12, 42192], [0, 2, 1, 53584], [2, 1, 21, 55592], [0, 2, 9, 54560]];
|
||||
|
||||
/**
|
||||
* 二十四节气数据,节气点时间(单位是分钟)
|
||||
* 从0小寒起算
|
||||
*/
|
||||
var termInfo = [0, 21208, 42467, 63836, 85337, 107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758];
|
||||
|
||||
/**
|
||||
* 判断农历年闰月数
|
||||
* @param {Number} year 农历年
|
||||
* return 闰月数 (月份从1开始)
|
||||
*/
|
||||
function getLunarLeapYear(year) {
|
||||
var yearData = lunarInfo[year - minYear];
|
||||
return yearData[0];
|
||||
};
|
||||
var getLunarDay = function (solarYear, solarMonth, solarDay) {
|
||||
if (solarYear < 1921 || solarYear > 2020) {
|
||||
return "";
|
||||
} else {
|
||||
solarMonth = (parseInt(solarMonth) > 0) ? (solarMonth - 1) : 11;
|
||||
e2c(solarYear, solarMonth, solarDay);
|
||||
return getcDateString();
|
||||
|
||||
/**
|
||||
* 获取农历年份一年的每月的天数及一年的总天数
|
||||
* @param {Number} year 农历年
|
||||
*/
|
||||
function getLunarYearDays(year) {
|
||||
var yearData = lunarInfo[year - minYear];
|
||||
var leapMonth = yearData[0]; //闰月
|
||||
var monthData = yearData[3].toString(2);
|
||||
var monthDataArr = monthData.split('');
|
||||
|
||||
//还原数据至16位,少于16位的在前面插入0(二进制存储时前面的0被忽略)
|
||||
for (var i = 0; i < 16 - monthDataArr.length; i++) {
|
||||
monthDataArr.unshift(0);
|
||||
}
|
||||
};
|
||||
var getShortLunarDay = function (solarYear, solarMonth, solarDay) {
|
||||
if (solarYear < 1921 || solarYear > 2020) {
|
||||
return "";
|
||||
|
||||
var len = leapMonth ? 13 : 12; //该年有几个月
|
||||
var yearDays = 0;
|
||||
var monthDays = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (monthDataArr[i] == 0) {
|
||||
yearDays += 29;
|
||||
monthDays.push(29);
|
||||
} else {
|
||||
solarMonth = (parseInt(solarMonth) > 0) ? (solarMonth - 1) : 11;
|
||||
e2c(solarYear, solarMonth, solarDay);
|
||||
return getShortDateString();
|
||||
yearDays += 30;
|
||||
monthDays.push(30);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
getDisplayDate: function (date) {
|
||||
var yy = date.getFullYear();
|
||||
var mm = date.getMonth() + 1;
|
||||
var dd = date.getDate();
|
||||
yearDays: yearDays,
|
||||
monthDays: monthDays
|
||||
};
|
||||
};
|
||||
|
||||
return getLunarDay(yy, mm, dd);
|
||||
},
|
||||
getShortDisplayDate: function (date) {
|
||||
var yy = date.getFullYear();
|
||||
var mm = date.getMonth() + 1;
|
||||
var dd = date.getDate();
|
||||
/**
|
||||
* 通过间隔天数查找农历日期
|
||||
* @param {Number} year,between 农历年,间隔天数
|
||||
*/
|
||||
function getLunarDateByBetween(year, between) {
|
||||
var lunarYearDays = getLunarYearDays(year);
|
||||
var end = between > 0 ? between : lunarYearDays.yearDays - Math.abs(between);
|
||||
var monthDays = lunarYearDays.monthDays;
|
||||
var tempDays = 0;
|
||||
var month = 0;
|
||||
for (var i = 0; i < monthDays.length; i++) {
|
||||
tempDays += monthDays[i];
|
||||
if (tempDays > end) {
|
||||
month = i;
|
||||
tempDays = tempDays - monthDays[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return getShortLunarDay(yy, mm, dd);
|
||||
return [year, month, end - tempDays + 1];
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据距离正月初一的天数计算农历日期
|
||||
* @param {Number} year 公历年,月,日
|
||||
*/
|
||||
function getLunarByBetween(year, month, day) {
|
||||
var yearData = lunarInfo[year - minYear];
|
||||
var zenMonth = yearData[1];
|
||||
var zenDay = yearData[2];
|
||||
var between = getDaysBetweenSolar(year, zenMonth - 1, zenDay, year, month, day);
|
||||
if (between == 0) { //正月初一
|
||||
return [year, 0, 1];
|
||||
} else {
|
||||
var lunarYear = between > 0 ? year : year - 1;
|
||||
return getLunarDateByBetween(lunarYear, between);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* 两个公历日期之间的天数
|
||||
*/
|
||||
function getDaysBetweenSolar(year, month, day, year1, month1, day1) {
|
||||
var date = new Date(year, month, day).getTime();
|
||||
var date1 = new Date(year1, month1, day1).getTime();
|
||||
return (date1 - date) / 86400000;
|
||||
};
|
||||
|
||||
/**
|
||||
* 计算农历日期离正月初一有多少天
|
||||
* @param {Number} year,month,day 农年,月(0-12,有闰月),日
|
||||
*/
|
||||
function getDaysBetweenZheng(year, month, day) {
|
||||
var lunarYearDays = getLunarYearDays(year);
|
||||
var monthDays = lunarYearDays.monthDays;
|
||||
var days = 0;
|
||||
for (var i = 0; i < monthDays.length; i++) {
|
||||
if (i < month) {
|
||||
days += monthDays[i];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
};
|
||||
return days + day - 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* 某年的第n个节气为几日
|
||||
* 31556925974.7为地球公转周期,是毫秒
|
||||
* 1890年的正小寒点:01-05 16:02:31,1890年为基准点
|
||||
* @param {Number} y 公历年
|
||||
* @param {Number} n 第几个节气,从0小寒起算
|
||||
* 由于农历24节气交节时刻采用近似算法,可能存在少量误差(30分钟内)
|
||||
*/
|
||||
function getTerm(y, n) {
|
||||
var offDate = new Date((31556925974.7 * (y - 1890) + termInfo[n] * 60000) + Date.UTC(1890, 0, 5, 16, 2, 31));
|
||||
return (offDate.getUTCDate());
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取公历年一年的二十四节气
|
||||
* 返回key:日期,value:节气中文名
|
||||
*/
|
||||
function getYearTerm(year) {
|
||||
var res = {};
|
||||
var month = 0;
|
||||
for (var i = 0; i < 24; i++) {
|
||||
var day = getTerm(year, i);
|
||||
if (i % 2 == 0) month++
|
||||
res[formateDayD4(month - 1, day)] = DATA.solarTerm[i];
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取生肖
|
||||
* @param {Number} year 干支所在年(默认以立春前的公历年作为基数)
|
||||
*/
|
||||
function getYearZodiac(year) {
|
||||
var num = year - 1890 + 25; //参考干支纪年的计算,生肖对应地支
|
||||
return DATA.zodiac[num % 12];
|
||||
};
|
||||
|
||||
/**
|
||||
* 计算天干地支
|
||||
* @param {Number} num 60进制中的位置(把60个天干地支,当成一个60进制的数)
|
||||
*/
|
||||
function cyclical(num) {
|
||||
return (DATA.heavenlyStems[num % 10] + DATA.earthlyBranches[num % 12]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取干支纪年
|
||||
* @param {Number} year 干支所在年
|
||||
* @param {Number} offset 偏移量,默认为0,便于查询一个年跨两个干支纪年(以立春为分界线)
|
||||
*/
|
||||
function getLunarYearName(year, offset) {
|
||||
offset = offset || 0;
|
||||
//1890年1月小寒(小寒一般是1月5或6日)以前为己丑年,在60进制中排25
|
||||
return cyclical(year - 1890 + 25 + offset);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取干支纪月
|
||||
* @param {Number} year,month 公历年,干支所在月
|
||||
* @param {Number} offset 偏移量,默认为0,便于查询一个月跨两个干支纪月(有立春的2月)
|
||||
*/
|
||||
function getLunarMonthName(year, month, offset) {
|
||||
offset = offset || 0;
|
||||
//1890年1月小寒以前为丙子月,在60进制中排12
|
||||
return cyclical((year - 1890) * 12 + month + 12 + offset);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取干支纪日
|
||||
* @param {Number} year,month,day 公历年,月,日
|
||||
*/
|
||||
function getLunarDayName(year, month, day) {
|
||||
//当日与1890/1/1 相差天数
|
||||
//1890/1/1与 1970/1/1 相差29219日, 1890/1/1 日柱为壬午日(60进制18)
|
||||
var dayCyclical = Date.UTC(year, month, day) / 86400000 + 29219 + 18;
|
||||
return cyclical(dayCyclical);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取公历月份的天数
|
||||
* @param {Number} year 公历年
|
||||
* @param {Number} month 公历月
|
||||
*/
|
||||
function getSolarMonthDays(year, month) {
|
||||
var monthDays = [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||||
return monthDays[month];
|
||||
};
|
||||
|
||||
/**
|
||||
* 判断公历年是否是闰年
|
||||
* @param {Number} year 公历年
|
||||
*/
|
||||
function isLeapYear(year) {
|
||||
return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
|
||||
};
|
||||
|
||||
/*
|
||||
* 统一日期输入参数(输入月份从1开始,内部月份统一从0开始)
|
||||
*/
|
||||
function formateDate(year, month, day, _minYear) {
|
||||
var argsLen = arguments.length;
|
||||
var now = new Date();
|
||||
year = argsLen ? parseInt(year, 10) : now.getFullYear();
|
||||
month = argsLen ? parseInt(month - 1, 10) : now.getMonth();
|
||||
day = argsLen ? parseInt(day, 10) || now.getDate() : now.getDate();
|
||||
if (year < (_minYear ? _minYear : minYear + 1) || year > maxYear) return { error: 100, msg: errorCode[100] };
|
||||
return {
|
||||
year: year,
|
||||
month: month,
|
||||
day: day
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 将农历转换为公历
|
||||
* @param {Number} year,month,day 农历年,月(1-13,有闰月),日
|
||||
*/
|
||||
function lunarToSolar(_year, _month, _day) {
|
||||
var inputDate = formateDate(_year, _month, _day);
|
||||
if (inputDate.error) return inputDate;
|
||||
var year = inputDate.year;
|
||||
var month = inputDate.month;
|
||||
var day = inputDate.day;
|
||||
|
||||
var between = getDaysBetweenZheng(year, month, day); //离正月初一的天数
|
||||
var yearData = lunarInfo[year - minYear];
|
||||
var zenMonth = yearData[1];
|
||||
var zenDay = yearData[2];
|
||||
|
||||
var offDate = new Date(year, zenMonth - 1, zenDay).getTime() + between * 86400000;
|
||||
offDate = new Date(offDate);
|
||||
return {
|
||||
year: offDate.getFullYear(),
|
||||
month: offDate.getMonth() + 1,
|
||||
day: offDate.getDate()
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 将公历转换为农历
|
||||
* @param {Number} year,month,day 公历年,月,日
|
||||
*/
|
||||
function solarToLunar(_year, _month, _day) {
|
||||
var inputDate = formateDate(_year, _month, _day, minYear);
|
||||
if (inputDate.error) return inputDate;
|
||||
var year = inputDate.year;
|
||||
var month = inputDate.month;
|
||||
var day = inputDate.day;
|
||||
|
||||
cacheUtil.setCurrent(year);
|
||||
//立春日期
|
||||
var term2 = cacheUtil.get('term2') ? cacheUtil.get('term2') : cacheUtil.set('term2', getTerm(year, 2));
|
||||
//二十四节气
|
||||
var termList = cacheUtil.get('termList') ? cacheUtil.get('termList') : cacheUtil.set('termList', getYearTerm(year));
|
||||
|
||||
var firstTerm = getTerm(year, month * 2); //某月第一个节气开始日期
|
||||
var GanZhiYear = (month > 1 || month == 1 && day >= term2) ? year + 1 : year;//干支所在年份
|
||||
var GanZhiMonth = day >= firstTerm ? month + 1 : month; //干支所在月份(以节气为界)
|
||||
|
||||
var lunarDate = getLunarByBetween(year, month, day);
|
||||
var lunarLeapMonth = getLunarLeapYear(lunarDate[0]);
|
||||
var lunarMonthName = '';
|
||||
if (lunarLeapMonth > 0 && lunarLeapMonth == lunarDate[1]) {
|
||||
lunarMonthName = '闰' + DATA.monthCn[lunarDate[1] - 1] + '月';
|
||||
} else if (lunarLeapMonth > 0 && lunarDate[1] > lunarLeapMonth) {
|
||||
lunarMonthName = DATA.monthCn[lunarDate[1] - 1] + '月';
|
||||
} else {
|
||||
lunarMonthName = DATA.monthCn[lunarDate[1]] + '月';
|
||||
}
|
||||
|
||||
//农历节日判断
|
||||
var lunarFtv = '';
|
||||
var lunarMonthDays = getLunarYearDays(lunarDate[0]).monthDays;
|
||||
//除夕
|
||||
if (lunarDate[1] == lunarMonthDays.length - 1 && lunarDate[2] == lunarMonthDays[lunarMonthDays.length - 1]) {
|
||||
lunarFtv = lunarFestival['d0100'];
|
||||
} else if (lunarLeapMonth > 0 && lunarDate[1] > lunarLeapMonth) {
|
||||
lunarFtv = lunarFestival[formateDayD4(lunarDate[1] - 1, lunarDate[2])];
|
||||
} else {
|
||||
lunarFtv = lunarFestival[formateDayD4(lunarDate[1], lunarDate[2])];
|
||||
}
|
||||
|
||||
var res = {
|
||||
zodiac: getYearZodiac(GanZhiYear),
|
||||
GanZhiYear: getLunarYearName(GanZhiYear),
|
||||
GanZhiMonth: getLunarMonthName(year, GanZhiMonth),
|
||||
GanZhiDay: getLunarDayName(year, month, day),
|
||||
//放假安排:0无特殊安排,1工作,2放假
|
||||
worktime: worktime['y' + year] && worktime['y' + year][formateDayD4(month, day)] ? worktime['y' + year][formateDayD4(month, day)] : 0,
|
||||
term: termList[formateDayD4(month, day)],
|
||||
|
||||
lunarYear: lunarDate[0],
|
||||
lunarMonth: lunarDate[1] + 1,
|
||||
lunarDay: lunarDate[2],
|
||||
lunarMonthName: lunarMonthName,
|
||||
lunarDayName: DATA.dateCn[lunarDate[2] - 1],
|
||||
lunarLeapMonth: lunarLeapMonth,
|
||||
|
||||
solarFestival: solarFestival[formateDayD4(month, day)],
|
||||
lunarFestival: lunarFtv
|
||||
};
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取指定公历月份的农历数据
|
||||
* return res{Object}
|
||||
* @param {Number} year,month 公历年,月
|
||||
* @param {Boolean} fill 是否用上下月数据补齐首尾空缺,首例数据从周日开始
|
||||
*/
|
||||
function calendar(_year, _month, fill) {
|
||||
var inputDate = formateDate(_year, _month);
|
||||
if (inputDate.error) return inputDate;
|
||||
var year = inputDate.year;
|
||||
var month = inputDate.month;
|
||||
|
||||
var calendarData = solarCalendar(year, month + 1, fill);
|
||||
for (var i = 0; i < calendarData.monthData.length; i++) {
|
||||
var cData = calendarData.monthData[i];
|
||||
var lunarData = solarToLunar(cData.year, cData.month, cData.day);
|
||||
extend(calendarData.monthData[i], lunarData);
|
||||
}
|
||||
return calendarData;
|
||||
};
|
||||
|
||||
/**
|
||||
* 公历某月日历
|
||||
* return res{Object}
|
||||
* @param {Number} year,month 公历年,月
|
||||
* @param {Boolean} fill 是否用上下月数据补齐首尾空缺,首例数据从周日开始 (7*6阵列)
|
||||
*/
|
||||
function solarCalendar(_year, _month, fill) {
|
||||
var inputDate = formateDate(_year, _month);
|
||||
if (inputDate.error) return inputDate;
|
||||
var year = inputDate.year;
|
||||
var month = inputDate.month;
|
||||
|
||||
var firstDate = new Date(year, month, 1);
|
||||
var preMonthDays, preMonthData, nextMonthData;
|
||||
|
||||
var res = {
|
||||
firstDay: firstDate.getDay(), //该月1号星期几
|
||||
monthDays: getSolarMonthDays(year, month), //该月天数
|
||||
monthData: []
|
||||
};
|
||||
|
||||
res.monthData = creatLenArr(year, month + 1, res.monthDays, 1);
|
||||
|
||||
if (fill) {
|
||||
if (res.firstDay > 0) { //前补
|
||||
var preYear = month - 1 < 0 ? year - 1 : year;
|
||||
var preMonth = month - 1 < 0 ? 11 : month - 1;
|
||||
preMonthDays = getSolarMonthDays(preYear, preMonth);
|
||||
preMonthData = creatLenArr(preYear, preMonth + 1, res.firstDay, preMonthDays - res.firstDay + 1);
|
||||
res.monthData = preMonthData.concat(res.monthData);
|
||||
}
|
||||
|
||||
if (7 * 6 - res.monthData.length != 0) { //后补
|
||||
var nextYear = month + 1 > 11 ? year + 1 : year;
|
||||
var nextMonth = month + 1 > 11 ? 0 : month + 1;
|
||||
var fillLen = 7 * 6 - res.monthData.length;
|
||||
nextMonthData = creatLenArr(nextYear, nextMonth + 1, fillLen, 1);
|
||||
res.monthData = res.monthData.concat(nextMonthData);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置放假安排【对外暴露接口】
|
||||
* @param {Object} workData
|
||||
*/
|
||||
function setWorktime(workData) {
|
||||
extend(worktime, workData);
|
||||
};
|
||||
|
||||
var LunarCalendar = {
|
||||
solarToLunar: solarToLunar,
|
||||
lunarToSolar: lunarToSolar,
|
||||
calendar: calendar,
|
||||
solarCalendar: solarCalendar,
|
||||
setWorktime: setWorktime,
|
||||
getSolarMonthDays: getSolarMonthDays
|
||||
};
|
||||
|
||||
module.exports = LunarCalendar;
|
||||
})
|
File diff suppressed because one or more lines are too long
@ -59,11 +59,26 @@
|
||||
}
|
||||
});
|
||||
|
||||
$("#chat_float_tip").click(showServerList);
|
||||
$("#chat_float_tip div:eq(1)").click(showServerList);
|
||||
$("#chat_float_tip div:eq(0)").click(function () {
|
||||
var cnt = $("#chat_float_tip");
|
||||
if (cnt.hasClass("off")) {
|
||||
cnt.removeClass("off");
|
||||
cnt.find(">div:eq(0)>i").removeClass("fa-caret-left").addClass("fa-caret-right");
|
||||
localStorage.removeItem("chat_hide");
|
||||
} else {
|
||||
cnt.addClass("off");
|
||||
cnt.find(">div:eq(0)>i").addClass("fa-caret-left").removeClass("fa-caret-right");
|
||||
localStorage.setItem("chat_hide", 1);
|
||||
}
|
||||
});
|
||||
if (document.body.scrollWidth < 1260 || localStorage.chat_hide) {
|
||||
$("#chat_float_tip").addClass("off").find(">div:eq(0)>i").addClass("fa-caret-left").removeClass("fa-caret-right");
|
||||
}
|
||||
|
||||
//加载服务器节点列表
|
||||
servernode.loadServers();
|
||||
setInterval(function() {
|
||||
setInterval(function () {
|
||||
servernode.loadServers();
|
||||
}, 1000 * 60 * 10);
|
||||
|
||||
|
@ -32,15 +32,10 @@
|
||||
for (var i = 0; i < 42; i++) {
|
||||
var cell = cells.eq(i);
|
||||
|
||||
var lunarDesc = lunarCalendar.getShortDisplayDate(dateTmp);
|
||||
if (dateTmp.getFullYear() === 2015 && dateTmp.getMonth() === 1) {
|
||||
var day = dateTmp.getDate();
|
||||
if (day === 18)
|
||||
lunarDesc = "除夕";
|
||||
else if (day === 19)
|
||||
lunarDesc = "春节";
|
||||
}
|
||||
cell.html(dateTmp.getDate() + "<span class='lunar'>" + lunarDesc + "</span>");
|
||||
var lunarDesc = lunarCalendar.solarToLunar(dateTmp.getFullYear(), dateTmp.getMonth()+1, dateTmp.getDate());
|
||||
var displayValue = lunarDesc.lunarFestival || lunarDesc.lunarDayName;
|
||||
|
||||
cell.html(dateTmp.getDate() + "<span class='lunar'>" + displayValue + "</span>");
|
||||
cell.removeClass();
|
||||
|
||||
if (dateTmp.getMonth() === thismonth) {
|
||||
|
Loading…
Reference in New Issue
Block a user