From dd1c9364c18d03c22e25a31717631450dd7ef4e8 Mon Sep 17 00:00:00 2001 From: luolan Date: Wed, 9 Jul 2025 16:05:07 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=E4=B8=AD=E7=9A=84JWT=E5=A3=B0?= =?UTF-8?q?=E6=98=8E=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGSS/Controllers/User/UserControllers.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AGSS/Controllers/User/UserControllers.cs b/AGSS/Controllers/User/UserControllers.cs index 1eb57b6..413fedd 100644 --- a/AGSS/Controllers/User/UserControllers.cs +++ b/AGSS/Controllers/User/UserControllers.cs @@ -1,3 +1,4 @@ +using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using AGSS.Models.Entities; using AGSS.Models.Template; @@ -25,7 +26,7 @@ public class UserControllers:ControllerBase [HttpGet] public async Task My() { - string userId = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value; + string userId = this.User.FindFirst(JwtRegisteredClaimNames.Sub)!.Value; if (string.IsNullOrEmpty(userId)) { return Ok(new ReturnTemplate(500,"获取用户失败(JWT解析错误)",null)); From 17c1e08d7fff74b6ee864de6361f0b96b7ef9404 Mon Sep 17 00:00:00 2001 From: luolan Date: Wed, 9 Jul 2025 16:08:20 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E5=AE=8C=E5=96=84=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=92=8C=E7=AE=A1=E7=90=86=E5=91=98=E8=A7=92=E8=89=B2=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E7=9A=84=E6=96=87=E6=A1=A3=E5=92=8C=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加用户控制器的类和方法注释 - 添加管理员角色控制器的类和方法注释 - 优化 `SearchUserFromRoleRequest` 和 `SearchUserFromRoleResponse` 的属性注释 --- .../Controllers/Admin/AdminRoleControllers.cs | 69 +++++++++++++++++-- AGSS/Controllers/User/UserControllers.cs | 21 ++++-- 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/AGSS/Controllers/Admin/AdminRoleControllers.cs b/AGSS/Controllers/Admin/AdminRoleControllers.cs index 007b861..ddcb89e 100644 --- a/AGSS/Controllers/Admin/AdminRoleControllers.cs +++ b/AGSS/Controllers/Admin/AdminRoleControllers.cs @@ -6,20 +6,42 @@ using Microsoft.AspNetCore.Mvc; namespace AGSS.Controllers.Admin; +/// +/// 控制器类,用于管理角色相关的操作,包括添加角色、分配角色给用户以及通过角色查询用户。 +/// 该控制器仅限具有"Admin"角色的用户访问。 +/// [Authorize(Roles = "Admin")] [Route("api/v1/[controller]/[action]")] public class AdminRoleControllers:ControllerBase { - + /// + /// 角色管理器,用于处理角色相关的操作,如创建、查询等。 + /// 此角色管理器实例主要用于与RoleModel类型的实体进行交互, + /// 支持添加新角色、为用户分配角色等功能。 + /// private readonly RoleManager _roleManager; + + /// + /// 用户管理器实例,用于处理用户相关的操作如添加角色、查询用户等。 + /// 此实例通过依赖注入的方式在构造函数中初始化,并在整个控制器生命周期内可用。 + /// private readonly UserManager _userManager; // Assuming UserModel is the type of user + /// + /// 管理员角色控制器,用于处理与角色相关的操作,如添加角色、分配角色给用户以及通过角色查询用户。 + /// 该控制器下的所有方法都需要管理员权限才能访问。 + /// public AdminRoleControllers(RoleManager roleManager, UserManager userManager) { _roleManager = roleManager; _userManager = userManager; } + /// + /// 添加新角色 + /// + /// 要添加的角色信息 + /// 返回操作结果,包含状态码、消息和数据 [HttpPost] public async Task AddRole([FromBody] RoleModel role) { @@ -40,6 +62,13 @@ public class AdminRoleControllers:ControllerBase return Ok(new ReturnTemplate(StatusCodes.Status500InternalServerError,"创建失败","Failed to create role: " + string.Join(", ", result.Errors.Select(e => e.Description)))); } } + + /// + /// 为指定用户分配角色 + /// + /// 用户的唯一标识符 + /// 要分配的角色名称 + /// 返回一个包含操作结果的ReturnTemplate对象,其中Code表示状态码,Msg表示消息,Data表示附加数据(如果有的话) [HttpPost] public async Task EndowRole(string userId, string roleName) { @@ -67,10 +96,11 @@ public class AdminRoleControllers:ControllerBase } -/// -/// 通过角色查询用户,支持分页 -/// -/// + /// + /// 通过角色查询用户,支持分页 + /// + /// 包含角色名称、页码和每页大小的请求对象 + /// 返回包含总用户数和当前页用户的响应对象 [HttpPost] public async Task SearchUserFromRole([FromBody] SearchUserFromRoleRequest request) { @@ -102,16 +132,45 @@ public class AdminRoleControllers:ControllerBase return Ok(new ReturnTemplate(200, "查询成功", response)); } + /// + /// 用于通过角色名称查询用户列表的请求模型。支持分页功能。 + /// public class SearchUserFromRoleRequest { + /// + /// 表示角色的名称。此属性用于指定或获取与用户管理相关的角色名称。 + /// 在进行角色分配、查询等操作时,需要提供正确的角色名称以确保操作的成功执行。 + /// public string RoleName { get; set; } + + /// + /// 表示当前请求的页码,默认为1。用于分页查询用户时指定从哪一页开始获取数据。 + /// public int Page { get; set; } = 1; + + /// + /// 每页显示的用户数量。默认值为10。 + /// 该属性用于分页查询中指定每一页应包含的用户条目数。 + /// public int PageSize { get; set; } = 10; } + /// + /// 表示通过角色查询用户后返回的响应数据。 + /// 该类用于封装查询结果,包括总用户数和分页后的用户列表。 + /// public class SearchUserFromRoleResponse { + /// + /// 表示属于特定角色的用户总数。 + /// + /// 此属性用于分页查询中,返回匹配给定角色名称的所有用户的数量。 public int TotalCount { get; set; } + + /// + /// 表示属于特定角色的用户列表。该属性用于存储和返回在给定角色下的所有用户。 + /// + /// 此列表通常作为查询结果的一部分,例如通过角色名搜索用户时返回的数据。 public List Users { get; set; } } } \ No newline at end of file diff --git a/AGSS/Controllers/User/UserControllers.cs b/AGSS/Controllers/User/UserControllers.cs index 413fedd..3e0891d 100644 --- a/AGSS/Controllers/User/UserControllers.cs +++ b/AGSS/Controllers/User/UserControllers.cs @@ -8,21 +8,34 @@ using Microsoft.AspNetCore.Mvc; namespace AGSS.Controllers.User; +/// +/// 用户控制器,提供与用户相关的API接口。 +/// +/// 此控制器需要授权才能访问其方法。 [Authorize] [Route("api/v1/[controller]/[action]")] public class UserControllers:ControllerBase -{ - +{ + /// + /// 用户服务实例,用于执行与用户相关的操作。 + /// 该服务提供了一系列方法来处理用户的查询和更新等操作, + /// 包括但不限于获取用户详细信息、修改用户资料等功能。 + /// private readonly UserService _userService; + /// + /// 用户控制器,提供用户相关操作的API接口。 + /// public UserControllers(UserService userService, UserManager userManager) { _userService = userService; } - - + /// + /// 获取当前登录用户的个人信息。 + /// + /// 返回一个包含状态码、消息和用户信息的ReturnTemplate对象。如果成功,状态码为200;如果失败,状态码为500。 [HttpGet] public async Task My() { From c8c7fcdd8fc0f3869cf1bb9a132e386590689a17 Mon Sep 17 00:00:00 2001 From: luolan Date: Wed, 9 Jul 2025 23:13:11 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E5=88=A0=E9=99=A4DBContextModelSnapshot?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0MenuRequest=20DTO=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0JWT=E7=94=9F=E6=88=90=E6=96=B9=E6=B3=95=E4=B8=BA?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=EF=BC=8C=E5=A2=9E=E5=8A=A0JWT=E8=BF=87?= =?UTF-8?q?=E6=9C=9F=E6=97=B6=E9=97=B4=E9=85=8D=E7=BD=AE=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=94=A8=E6=88=B7=E6=B3=A8=E5=86=8C=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=92=8C=E6=A8=A1=E5=9E=8B=EF=BC=8C=E6=B7=BB=E5=8A=A0=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=A7=92=E8=89=B2=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E6=9B=B4=E6=96=B0=E7=94=A8=E6=88=B7=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E7=B1=BB=E4=BB=A5=E6=94=AF=E6=8C=81=E8=8F=9C=E5=8D=95=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Identity/Pages/Account/Register.cshtml | 9 ++- .../Identity/Pages/Account/Register.cshtml.cs | 9 ++- .../Controllers/Admin/AdminRoleControllers.cs | 64 ++++++++++++++++++ .../ApplicationDbContextModelSnapshot.cs | 8 +++ AGSS/Migrations/DBContextModelSnapshot.cs | 67 ------------------- AGSS/Models/DTOs/MenuRequest.cs | 8 +++ AGSS/Models/Entities/User.cs | 4 ++ AGSS/Program.cs | 2 +- AGSS/Utilities/Jwt.cs | 2 +- AGSS/appsettings.Development.json | 1 + AGSS/appsettings.json | 1 + 11 files changed, 103 insertions(+), 72 deletions(-) delete mode 100644 AGSS/Migrations/DBContextModelSnapshot.cs create mode 100644 AGSS/Models/DTOs/MenuRequest.cs diff --git a/AGSS/Areas/Identity/Pages/Account/Register.cshtml b/AGSS/Areas/Identity/Pages/Account/Register.cshtml index 1fb3d03..cdbeffe 100644 --- a/AGSS/Areas/Identity/Pages/Account/Register.cshtml +++ b/AGSS/Areas/Identity/Pages/Account/Register.cshtml @@ -18,15 +18,20 @@
- +
- +
+
+ + + +
diff --git a/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs b/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs index 8a449c6..3884aff 100644 --- a/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs +++ b/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs @@ -104,6 +104,12 @@ namespace AGSS.Areas.Identity.Pages.Account [Display(Name = "Confirm password")] [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] public string ConfirmPassword { get; set; } + + + [MaxLength(10)] + [Display(Name = "Confirm password")] + public string Sex { get; set; } + } @@ -120,7 +126,8 @@ namespace AGSS.Areas.Identity.Pages.Account if (ModelState.IsValid) { var user = CreateUser(); - + user.Id = Guid.NewGuid().ToString(); + user.Sex = Input.Sex; await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None); await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None); var result = await _userManager.CreateAsync(user, Input.Password); diff --git a/AGSS/Controllers/Admin/AdminRoleControllers.cs b/AGSS/Controllers/Admin/AdminRoleControllers.cs index ddcb89e..95c7429 100644 --- a/AGSS/Controllers/Admin/AdminRoleControllers.cs +++ b/AGSS/Controllers/Admin/AdminRoleControllers.cs @@ -1,3 +1,4 @@ +using AGSS.Models.DTOs; using AGSS.Models.Entities; using AGSS.Models.Template; using Microsoft.AspNetCore.Authorization; @@ -96,6 +97,69 @@ public class AdminRoleControllers:ControllerBase } + /// + /// 删除指定用户。 + /// + /// 要删除的用户的唯一标识符。 + /// 返回操作结果,包含状态码、消息和数据。如果删除成功,则返回200状态码;如果用户ID为空或未找到指定用户,则分别返回400或404状态码;若删除过程中出现错误,则返回500状态码并附带错误信息。 + [HttpPost] + public async Task DelUser(string userId) + { + if (string.IsNullOrWhiteSpace(userId)) + { + return Ok(new ReturnTemplate(400, "你填写的用户ID是空的~", null)); + } + + var user = await _userManager.FindByIdAsync(userId); + if (user == null) + { + return Ok(new ReturnTemplate(404, "未找到指定用户哦·~", null)); + } + + // 删除用户 + var result = await _userManager.DeleteAsync(user); + if (result.Succeeded) + { + return Ok(new ReturnTemplate(200, "用户删除成功,不要留念这个用户哦~", null)); + } + else + { + return StatusCode(500, new ReturnTemplate(500, "发生了一些不可预料的错误,555", result.Errors)); + } + } + + + [HttpPost] + public async Task SetMenu([FromBody]MenuRequest request) + { + if (string.IsNullOrWhiteSpace(request.Id) || string.IsNullOrWhiteSpace(request.MenuName)) + { + return Ok(new ReturnTemplate(400, "请求参数无效(有的参数是空的哦~)", "")); + } + var user=await _userManager.FindByIdAsync(request.Id); + if (user==null) + { + return Ok(new ReturnTemplate(404, "Sorry,你输入的用户我们找不到!", "")); + } + user.MenuCode = request.MenuCode; + user.MenuName = request.MenuName; + var result= await _userManager.UpdateAsync(user); + if (result.Succeeded) + { + return Ok(new ReturnTemplate(200, "配置成功啦!", "")); + } + else + { + return StatusCode(500, new ReturnTemplate(500, "删除用户时发生错误", result.Errors)); + } + + + } + + + + + /// /// 通过角色查询用户,支持分页 /// diff --git a/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs b/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs index 74624bb..058cb5a 100644 --- a/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs @@ -93,6 +93,14 @@ namespace AGSS.Migrations b.Property("LockoutEnd") .HasColumnType("timestamp with time zone"); + b.Property("MenuCode") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("MenuName") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + b.Property("NormalizedEmail") .HasMaxLength(256) .HasColumnType("character varying(256)"); diff --git a/AGSS/Migrations/DBContextModelSnapshot.cs b/AGSS/Migrations/DBContextModelSnapshot.cs deleted file mode 100644 index e76171d..0000000 --- a/AGSS/Migrations/DBContextModelSnapshot.cs +++ /dev/null @@ -1,67 +0,0 @@ -// -using System; -using AGSS.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - [DbContext(typeof(DBContext))] - partial class DBContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AuthId") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Birthday") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Config") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Description") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("JobCode") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("JobName") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("Sex") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("Id"); - - b.ToTable("UserModels"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/AGSS/Models/DTOs/MenuRequest.cs b/AGSS/Models/DTOs/MenuRequest.cs new file mode 100644 index 0000000..b8a76c2 --- /dev/null +++ b/AGSS/Models/DTOs/MenuRequest.cs @@ -0,0 +1,8 @@ +namespace AGSS.Models.DTOs; + +public struct MenuRequest +{ + public string Id { get; set; } + public string MenuName { get; set; } + public string? MenuCode { get; set; } +} \ No newline at end of file diff --git a/AGSS/Models/Entities/User.cs b/AGSS/Models/Entities/User.cs index 7949e56..0ac6258 100644 --- a/AGSS/Models/Entities/User.cs +++ b/AGSS/Models/Entities/User.cs @@ -17,6 +17,10 @@ public class UserModel:IdentityUser public string? JobName { get; set; } [MaxLength(20)] public string? Birthday { get; set; } + [MaxLength(500)] + public string? MenuCode { get; set; } + [MaxLength(500)] + public string? MenuName { get; set; } } diff --git a/AGSS/Program.cs b/AGSS/Program.cs index e68de46..427490c 100644 --- a/AGSS/Program.cs +++ b/AGSS/Program.cs @@ -33,7 +33,7 @@ builder.Services.AddDbContext(opt => opt.UseNpgsql(builder.Configuration.GetConnectionString("DBContext"))); // Identity 配置 -builder.Services.AddIdentity() +builder.Services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders() .AddDefaultUI(); diff --git a/AGSS/Utilities/Jwt.cs b/AGSS/Utilities/Jwt.cs index b97fbdc..6d3c49f 100644 --- a/AGSS/Utilities/Jwt.cs +++ b/AGSS/Utilities/Jwt.cs @@ -28,7 +28,7 @@ public class Jwt return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor); } - public async Task GenerateJwtToken(UserModel user,IList roles) + public string GenerateJwtToken(UserModel user,IList roles) { var claims = new List(); claims.Add(new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString())); diff --git a/AGSS/appsettings.Development.json b/AGSS/appsettings.Development.json index f061d7b..d1c269e 100644 --- a/AGSS/appsettings.Development.json +++ b/AGSS/appsettings.Development.json @@ -15,6 +15,7 @@ }, "AllowedHosts": "*", "Jwt": { + "ExpireMinutes": "4", "Issuer": "https://api.zeronode.cn/api", "Audience": "https://api.zeronode.cn/api", "Key": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak" diff --git a/AGSS/appsettings.json b/AGSS/appsettings.json index f595462..6527a3d 100644 --- a/AGSS/appsettings.json +++ b/AGSS/appsettings.json @@ -15,6 +15,7 @@ }, "AllowedHosts": "*", "Jwt": { + "ExpireMinutes": "4", "Issuer": "https://api.zeronode.cn/api", "Audience": "https://api.zeronode.cn/api", "Key": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak" From 87d75c8743dcd844fec5e61aae81db8ba74c6b45 Mon Sep 17 00:00:00 2001 From: luolan Date: Wed, 9 Jul 2025 23:13:28 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E5=88=A0=E9=99=A4=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E6=96=87=E4=BB=B6=E5=B9=B6=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=A1=A8=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20250702100149_Initial.Designer.cs | 53 ---- AGSS/Migrations/20250702100149_Initial.cs | 36 --- .../20250702110815_usernew.Designer.cs | 45 --- AGSS/Migrations/20250702110815_usernew.cs | 40 --- .../20250705081221_newuser.Designer.cs | 70 ---- AGSS/Migrations/20250705081221_newuser.cs | 102 ------ .../20250708111442_user.Designer.cs | 300 ------------------ AGSS/Migrations/20250708111442_user.cs | 229 ------------- .../20250709054553_userrole.Designer.cs | 300 ------------------ AGSS/Migrations/20250709054553_userrole.cs | 22 -- script.sql | 151 ++++++++- 11 files changed, 150 insertions(+), 1198 deletions(-) delete mode 100644 AGSS/Migrations/20250702100149_Initial.Designer.cs delete mode 100644 AGSS/Migrations/20250702100149_Initial.cs delete mode 100644 AGSS/Migrations/20250702110815_usernew.Designer.cs delete mode 100644 AGSS/Migrations/20250702110815_usernew.cs delete mode 100644 AGSS/Migrations/20250705081221_newuser.Designer.cs delete mode 100644 AGSS/Migrations/20250705081221_newuser.cs delete mode 100644 AGSS/Migrations/20250708111442_user.Designer.cs delete mode 100644 AGSS/Migrations/20250708111442_user.cs delete mode 100644 AGSS/Migrations/20250709054553_userrole.Designer.cs delete mode 100644 AGSS/Migrations/20250709054553_userrole.cs diff --git a/AGSS/Migrations/20250702100149_Initial.Designer.cs b/AGSS/Migrations/20250702100149_Initial.Designer.cs deleted file mode 100644 index fb2159a..0000000 --- a/AGSS/Migrations/20250702100149_Initial.Designer.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -using System; -using AGSS.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - [DbContext(typeof(DBContext))] - [Migration("20250702100149_Initial")] - partial class Initial - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AuthId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("Password") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("UserModels"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/AGSS/Migrations/20250702100149_Initial.cs b/AGSS/Migrations/20250702100149_Initial.cs deleted file mode 100644 index ba17990..0000000 --- a/AGSS/Migrations/20250702100149_Initial.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace AGSS.Migrations -{ - /// - public partial class Initial : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "UserModels", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - AuthId = table.Column(type: "text", nullable: false), - Email = table.Column(type: "text", nullable: false), - Password = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_UserModels", x => x.Id); - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "UserModels"); - } - } -} diff --git a/AGSS/Migrations/20250702110815_usernew.Designer.cs b/AGSS/Migrations/20250702110815_usernew.Designer.cs deleted file mode 100644 index 4d069d8..0000000 --- a/AGSS/Migrations/20250702110815_usernew.Designer.cs +++ /dev/null @@ -1,45 +0,0 @@ -// -using System; -using AGSS.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - [DbContext(typeof(DBContext))] - [Migration("20250702110815_usernew")] - partial class usernew - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AuthId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("UserModels"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/AGSS/Migrations/20250702110815_usernew.cs b/AGSS/Migrations/20250702110815_usernew.cs deleted file mode 100644 index 31a4115..0000000 --- a/AGSS/Migrations/20250702110815_usernew.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace AGSS.Migrations -{ - /// - public partial class usernew : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Email", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "Password", - table: "UserModels"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "Email", - table: "UserModels", - type: "text", - nullable: false, - defaultValue: ""); - - migrationBuilder.AddColumn( - name: "Password", - table: "UserModels", - type: "text", - nullable: false, - defaultValue: ""); - } - } -} diff --git a/AGSS/Migrations/20250705081221_newuser.Designer.cs b/AGSS/Migrations/20250705081221_newuser.Designer.cs deleted file mode 100644 index d2c8e0b..0000000 --- a/AGSS/Migrations/20250705081221_newuser.Designer.cs +++ /dev/null @@ -1,70 +0,0 @@ -// -using System; -using AGSS.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - [DbContext(typeof(DBContext))] - [Migration("20250705081221_newuser")] - partial class newuser - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AuthId") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Birthday") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Config") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Description") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("JobCode") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("JobName") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("Sex") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("Id"); - - b.ToTable("UserModels"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/AGSS/Migrations/20250705081221_newuser.cs b/AGSS/Migrations/20250705081221_newuser.cs deleted file mode 100644 index 1dfddc2..0000000 --- a/AGSS/Migrations/20250705081221_newuser.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace AGSS.Migrations -{ - /// - public partial class newuser : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "AuthId", - table: "UserModels", - type: "character varying(50)", - maxLength: 50, - nullable: false, - oldClrType: typeof(string), - oldType: "text"); - - migrationBuilder.AddColumn( - name: "Birthday", - table: "UserModels", - type: "character varying(20)", - maxLength: 20, - nullable: true); - - migrationBuilder.AddColumn( - name: "Config", - table: "UserModels", - type: "character varying(200)", - maxLength: 200, - nullable: true); - - migrationBuilder.AddColumn( - name: "Description", - table: "UserModels", - type: "character varying(100)", - maxLength: 100, - nullable: true); - - migrationBuilder.AddColumn( - name: "JobCode", - table: "UserModels", - type: "character varying(10)", - maxLength: 10, - nullable: true); - - migrationBuilder.AddColumn( - name: "JobName", - table: "UserModels", - type: "character varying(10)", - maxLength: 10, - nullable: true); - - migrationBuilder.AddColumn( - name: "Sex", - table: "UserModels", - type: "character varying(20)", - maxLength: 20, - nullable: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Birthday", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "Config", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "Description", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "JobCode", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "JobName", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "Sex", - table: "UserModels"); - - migrationBuilder.AlterColumn( - name: "AuthId", - table: "UserModels", - type: "text", - nullable: false, - oldClrType: typeof(string), - oldType: "character varying(50)", - oldMaxLength: 50); - } - } -} diff --git a/AGSS/Migrations/20250708111442_user.Designer.cs b/AGSS/Migrations/20250708111442_user.Designer.cs deleted file mode 100644 index f618b64..0000000 --- a/AGSS/Migrations/20250708111442_user.Designer.cs +++ /dev/null @@ -1,300 +0,0 @@ -// -using System; -using AGSS.DbSet; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - [Migration("20250708111442_user")] - partial class user - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("AccessFailedCount") - .HasColumnType("integer"); - - b.Property("Birthday") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Config") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Description") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("boolean"); - - b.Property("JobCode") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("JobName") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("LockoutEnabled") - .HasColumnType("boolean"); - - b.Property("LockoutEnd") - .HasColumnType("timestamp with time zone"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("PasswordHash") - .HasColumnType("text"); - - b.Property("PhoneNumber") - .HasColumnType("text"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("boolean"); - - b.Property("SecurityStamp") - .HasColumnType("text"); - - b.Property("Sex") - .HasColumnType("text"); - - b.Property("TwoFactorEnabled") - .HasColumnType("boolean"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("ProviderKey") - .HasColumnType("text"); - - b.Property("ProviderDisplayName") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("RoleId") - .HasColumnType("text"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Value") - .HasColumnType("text"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/AGSS/Migrations/20250708111442_user.cs b/AGSS/Migrations/20250708111442_user.cs deleted file mode 100644 index bcc2e1d..0000000 --- a/AGSS/Migrations/20250708111442_user.cs +++ /dev/null @@ -1,229 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - /// - public partial class user : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "AspNetRoles", - columns: table => new - { - Id = table.Column(type: "text", nullable: false), - Name = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), - NormalizedName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), - ConcurrencyStamp = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoles", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetUsers", - columns: table => new - { - Id = table.Column(type: "text", nullable: false), - Sex = table.Column(type: "text", nullable: true), - Description = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - Config = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - JobCode = table.Column(type: "character varying(10)", maxLength: 10, nullable: true), - JobName = table.Column(type: "character varying(10)", maxLength: 10, nullable: true), - Birthday = table.Column(type: "character varying(20)", maxLength: 20, nullable: true), - UserName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), - NormalizedUserName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), - Email = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), - NormalizedEmail = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), - EmailConfirmed = table.Column(type: "boolean", nullable: false), - PasswordHash = table.Column(type: "text", nullable: true), - SecurityStamp = table.Column(type: "text", nullable: true), - ConcurrencyStamp = table.Column(type: "text", nullable: true), - PhoneNumber = table.Column(type: "text", nullable: true), - PhoneNumberConfirmed = table.Column(type: "boolean", nullable: false), - TwoFactorEnabled = table.Column(type: "boolean", nullable: false), - LockoutEnd = table.Column(type: "timestamp with time zone", nullable: true), - LockoutEnabled = table.Column(type: "boolean", nullable: false), - AccessFailedCount = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUsers", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetRoleClaims", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - RoleId = table.Column(type: "text", nullable: false), - ClaimType = table.Column(type: "text", nullable: true), - ClaimValue = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); - table.ForeignKey( - name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", - column: x => x.RoleId, - principalTable: "AspNetRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserClaims", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - UserId = table.Column(type: "text", nullable: false), - ClaimType = table.Column(type: "text", nullable: true), - ClaimValue = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); - table.ForeignKey( - name: "FK_AspNetUserClaims_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserLogins", - columns: table => new - { - LoginProvider = table.Column(type: "text", nullable: false), - ProviderKey = table.Column(type: "text", nullable: false), - ProviderDisplayName = table.Column(type: "text", nullable: true), - UserId = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); - table.ForeignKey( - name: "FK_AspNetUserLogins_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserRoles", - columns: table => new - { - UserId = table.Column(type: "text", nullable: false), - RoleId = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); - table.ForeignKey( - name: "FK_AspNetUserRoles_AspNetRoles_RoleId", - column: x => x.RoleId, - principalTable: "AspNetRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AspNetUserRoles_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserTokens", - columns: table => new - { - UserId = table.Column(type: "text", nullable: false), - LoginProvider = table.Column(type: "text", nullable: false), - Name = table.Column(type: "text", nullable: false), - Value = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); - table.ForeignKey( - name: "FK_AspNetUserTokens_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_AspNetRoleClaims_RoleId", - table: "AspNetRoleClaims", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "RoleNameIndex", - table: "AspNetRoles", - column: "NormalizedName", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserClaims_UserId", - table: "AspNetUserClaims", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserLogins_UserId", - table: "AspNetUserLogins", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserRoles_RoleId", - table: "AspNetUserRoles", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "EmailIndex", - table: "AspNetUsers", - column: "NormalizedEmail"); - - migrationBuilder.CreateIndex( - name: "UserNameIndex", - table: "AspNetUsers", - column: "NormalizedUserName", - unique: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AspNetRoleClaims"); - - migrationBuilder.DropTable( - name: "AspNetUserClaims"); - - migrationBuilder.DropTable( - name: "AspNetUserLogins"); - - migrationBuilder.DropTable( - name: "AspNetUserRoles"); - - migrationBuilder.DropTable( - name: "AspNetUserTokens"); - - migrationBuilder.DropTable( - name: "AspNetRoles"); - - migrationBuilder.DropTable( - name: "AspNetUsers"); - } - } -} diff --git a/AGSS/Migrations/20250709054553_userrole.Designer.cs b/AGSS/Migrations/20250709054553_userrole.Designer.cs deleted file mode 100644 index 47bab85..0000000 --- a/AGSS/Migrations/20250709054553_userrole.Designer.cs +++ /dev/null @@ -1,300 +0,0 @@ -// -using System; -using AGSS.DbSet; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - [Migration("20250709054553_userrole")] - partial class userrole - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("AGSS.Models.Entities.RoleModel", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("AccessFailedCount") - .HasColumnType("integer"); - - b.Property("Birthday") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Config") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Description") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("boolean"); - - b.Property("JobCode") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("JobName") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("LockoutEnabled") - .HasColumnType("boolean"); - - b.Property("LockoutEnd") - .HasColumnType("timestamp with time zone"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("PasswordHash") - .HasColumnType("text"); - - b.Property("PhoneNumber") - .HasColumnType("text"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("boolean"); - - b.Property("SecurityStamp") - .HasColumnType("text"); - - b.Property("Sex") - .HasColumnType("text"); - - b.Property("TwoFactorEnabled") - .HasColumnType("boolean"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("ProviderKey") - .HasColumnType("text"); - - b.Property("ProviderDisplayName") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("RoleId") - .HasColumnType("text"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Value") - .HasColumnType("text"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("AGSS.Models.Entities.RoleModel", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("AGSS.Models.Entities.RoleModel", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/AGSS/Migrations/20250709054553_userrole.cs b/AGSS/Migrations/20250709054553_userrole.cs deleted file mode 100644 index 47a1543..0000000 --- a/AGSS/Migrations/20250709054553_userrole.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace AGSS.Migrations -{ - /// - public partial class userrole : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - - } - } -} diff --git a/script.sql b/script.sql index df7c096..577aeff 100644 --- a/script.sql +++ b/script.sql @@ -1,6 +1,155 @@ -START TRANSACTION; +CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" ( + "MigrationId" character varying(150) NOT NULL, + "ProductVersion" character varying(32) NOT NULL, + CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId") +); + +START TRANSACTION; +CREATE TABLE "AspNetRoles" ( + "Id" text NOT NULL, + "Name" character varying(256), + "NormalizedName" character varying(256), + "ConcurrencyStamp" text, + CONSTRAINT "PK_AspNetRoles" PRIMARY KEY ("Id") +); + +CREATE TABLE "AspNetUsers" ( + "Id" text NOT NULL, + "Sex" text, + "Description" character varying(100), + "Config" character varying(200), + "JobCode" character varying(10), + "JobName" character varying(10), + "Birthday" character varying(20), + "UserName" character varying(256), + "NormalizedUserName" character varying(256), + "Email" character varying(256), + "NormalizedEmail" character varying(256), + "EmailConfirmed" boolean NOT NULL, + "PasswordHash" text, + "SecurityStamp" text, + "ConcurrencyStamp" text, + "PhoneNumber" text, + "PhoneNumberConfirmed" boolean NOT NULL, + "TwoFactorEnabled" boolean NOT NULL, + "LockoutEnd" timestamp with time zone, + "LockoutEnabled" boolean NOT NULL, + "AccessFailedCount" integer NOT NULL, + CONSTRAINT "PK_AspNetUsers" PRIMARY KEY ("Id") +); + +CREATE TABLE "AspNetRoleClaims" ( + "Id" integer GENERATED BY DEFAULT AS IDENTITY, + "RoleId" text NOT NULL, + "ClaimType" text, + "ClaimValue" text, + CONSTRAINT "PK_AspNetRoleClaims" PRIMARY KEY ("Id"), + CONSTRAINT "FK_AspNetRoleClaims_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserClaims" ( + "Id" integer GENERATED BY DEFAULT AS IDENTITY, + "UserId" text NOT NULL, + "ClaimType" text, + "ClaimValue" text, + CONSTRAINT "PK_AspNetUserClaims" PRIMARY KEY ("Id"), + CONSTRAINT "FK_AspNetUserClaims_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserLogins" ( + "LoginProvider" text NOT NULL, + "ProviderKey" text NOT NULL, + "ProviderDisplayName" text, + "UserId" text NOT NULL, + CONSTRAINT "PK_AspNetUserLogins" PRIMARY KEY ("LoginProvider", "ProviderKey"), + CONSTRAINT "FK_AspNetUserLogins_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserRoles" ( + "UserId" text NOT NULL, + "RoleId" text NOT NULL, + CONSTRAINT "PK_AspNetUserRoles" PRIMARY KEY ("UserId", "RoleId"), + CONSTRAINT "FK_AspNetUserRoles_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_AspNetUserRoles_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserTokens" ( + "UserId" text NOT NULL, + "LoginProvider" text NOT NULL, + "Name" text NOT NULL, + "Value" text, + CONSTRAINT "PK_AspNetUserTokens" PRIMARY KEY ("UserId", "LoginProvider", "Name"), + CONSTRAINT "FK_AspNetUserTokens_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE INDEX "IX_AspNetRoleClaims_RoleId" ON "AspNetRoleClaims" ("RoleId"); + +CREATE UNIQUE INDEX "RoleNameIndex" ON "AspNetRoles" ("NormalizedName"); + +CREATE INDEX "IX_AspNetUserClaims_UserId" ON "AspNetUserClaims" ("UserId"); + +CREATE INDEX "IX_AspNetUserLogins_UserId" ON "AspNetUserLogins" ("UserId"); + +CREATE INDEX "IX_AspNetUserRoles_RoleId" ON "AspNetUserRoles" ("RoleId"); + +CREATE INDEX "EmailIndex" ON "AspNetUsers" ("NormalizedEmail"); + +CREATE UNIQUE INDEX "UserNameIndex" ON "AspNetUsers" ("NormalizedUserName"); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20250708111442_user', '9.0.6'); + INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") VALUES ('20250709054553_userrole', '9.0.6'); +ALTER TABLE "AspNetUsers" ADD "MenuCode" character varying(1000); + +ALTER TABLE "AspNetUsers" ADD "MenuName" character varying(1000); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20250709141702_Menu', '9.0.6'); + +ALTER TABLE "AspNetUserTokens" ALTER COLUMN "UserId" TYPE uuid; + +ALTER TABLE "AspNetUsers" ALTER COLUMN "MenuName" TYPE character varying(500); + +ALTER TABLE "AspNetUsers" ALTER COLUMN "MenuCode" TYPE character varying(500); + +ALTER TABLE "AspNetUsers" ALTER COLUMN "Id" TYPE uuid; + +ALTER TABLE "AspNetUserRoles" ALTER COLUMN "RoleId" TYPE uuid; + +ALTER TABLE "AspNetUserRoles" ALTER COLUMN "UserId" TYPE uuid; + +ALTER TABLE "AspNetUserLogins" ALTER COLUMN "UserId" TYPE uuid; + +ALTER TABLE "AspNetUserClaims" ALTER COLUMN "UserId" TYPE uuid; + +ALTER TABLE "AspNetRoles" ALTER COLUMN "Id" TYPE uuid; + +ALTER TABLE "AspNetRoleClaims" ALTER COLUMN "RoleId" TYPE uuid; + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20250709142723_guiduser', '9.0.6'); + +ALTER TABLE "AspNetUserTokens" ALTER COLUMN "UserId" TYPE text; + +ALTER TABLE "AspNetUsers" ALTER COLUMN "Id" TYPE text; + +ALTER TABLE "AspNetUserRoles" ALTER COLUMN "RoleId" TYPE text; + +ALTER TABLE "AspNetUserRoles" ALTER COLUMN "UserId" TYPE text; + +ALTER TABLE "AspNetUserLogins" ALTER COLUMN "UserId" TYPE text; + +ALTER TABLE "AspNetUserClaims" ALTER COLUMN "UserId" TYPE text; + +ALTER TABLE "AspNetRoles" ALTER COLUMN "Id" TYPE text; + +ALTER TABLE "AspNetRoleClaims" ALTER COLUMN "RoleId" TYPE text; + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20250709144140_stringuser', '9.0.6'); + COMMIT; From 9f407c422c8b6cec9d0f9c92ff66269acaa1ae8c Mon Sep 17 00:00:00 2001 From: luolan Date: Wed, 9 Jul 2025 23:46:36 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=A1=A8=E4=B8=AD=E7=9A=84=E8=8F=9C=E5=8D=95=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=B9=B6=E4=BC=98=E5=8C=96=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E5=92=8C=E8=AE=A4=E8=AF=81=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Account/Manage/EnableAuthenticator.cshtml | 5 +- script.sql | 56 +------------------ 2 files changed, 7 insertions(+), 54 deletions(-) diff --git a/AGSS/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml b/AGSS/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml index fefa57f..62a62a3 100644 --- a/AGSS/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml +++ b/AGSS/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml @@ -49,5 +49,8 @@ @section Scripts { - + @await Html.PartialAsync("_ValidationScriptsPartial") + + + } diff --git a/script.sql b/script.sql index 577aeff..73a8d5b 100644 --- a/script.sql +++ b/script.sql @@ -21,6 +21,8 @@ CREATE TABLE "AspNetUsers" ( "JobCode" character varying(10), "JobName" character varying(10), "Birthday" character varying(20), + "MenuCode" character varying(500), + "MenuName" character varying(500), "UserName" character varying(256), "NormalizedUserName" character varying(256), "Email" character varying(256), @@ -97,59 +99,7 @@ CREATE INDEX "EmailIndex" ON "AspNetUsers" ("NormalizedEmail"); CREATE UNIQUE INDEX "UserNameIndex" ON "AspNetUsers" ("NormalizedUserName"); INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") -VALUES ('20250708111442_user', '9.0.6'); - -INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") -VALUES ('20250709054553_userrole', '9.0.6'); - -ALTER TABLE "AspNetUsers" ADD "MenuCode" character varying(1000); - -ALTER TABLE "AspNetUsers" ADD "MenuName" character varying(1000); - -INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") -VALUES ('20250709141702_Menu', '9.0.6'); - -ALTER TABLE "AspNetUserTokens" ALTER COLUMN "UserId" TYPE uuid; - -ALTER TABLE "AspNetUsers" ALTER COLUMN "MenuName" TYPE character varying(500); - -ALTER TABLE "AspNetUsers" ALTER COLUMN "MenuCode" TYPE character varying(500); - -ALTER TABLE "AspNetUsers" ALTER COLUMN "Id" TYPE uuid; - -ALTER TABLE "AspNetUserRoles" ALTER COLUMN "RoleId" TYPE uuid; - -ALTER TABLE "AspNetUserRoles" ALTER COLUMN "UserId" TYPE uuid; - -ALTER TABLE "AspNetUserLogins" ALTER COLUMN "UserId" TYPE uuid; - -ALTER TABLE "AspNetUserClaims" ALTER COLUMN "UserId" TYPE uuid; - -ALTER TABLE "AspNetRoles" ALTER COLUMN "Id" TYPE uuid; - -ALTER TABLE "AspNetRoleClaims" ALTER COLUMN "RoleId" TYPE uuid; - -INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") -VALUES ('20250709142723_guiduser', '9.0.6'); - -ALTER TABLE "AspNetUserTokens" ALTER COLUMN "UserId" TYPE text; - -ALTER TABLE "AspNetUsers" ALTER COLUMN "Id" TYPE text; - -ALTER TABLE "AspNetUserRoles" ALTER COLUMN "RoleId" TYPE text; - -ALTER TABLE "AspNetUserRoles" ALTER COLUMN "UserId" TYPE text; - -ALTER TABLE "AspNetUserLogins" ALTER COLUMN "UserId" TYPE text; - -ALTER TABLE "AspNetUserClaims" ALTER COLUMN "UserId" TYPE text; - -ALTER TABLE "AspNetRoles" ALTER COLUMN "Id" TYPE text; - -ALTER TABLE "AspNetRoleClaims" ALTER COLUMN "RoleId" TYPE text; - -INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") -VALUES ('20250709144140_stringuser', '9.0.6'); +VALUES ('20250709144855_Initial', '9.0.6'); COMMIT; From 062c5f94776995ca21ce5905b09ab6c856033fd8 Mon Sep 17 00:00:00 2001 From: luolan Date: Thu, 10 Jul 2025 23:09:03 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=E4=B8=AD=E7=9A=84JWT=E5=A3=B0?= =?UTF-8?q?=E6=98=8E=E5=90=8D=E7=A7=B0=EF=BC=8C=E5=B9=B6=E5=9C=A8=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=B5=84=E6=96=99=E4=B8=AD=E6=B7=BB=E5=8A=A0=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E4=BF=A1=E6=81=AF=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGSS/Controllers/User/UserControllers.cs | 13 ++++++------- AGSS/Models/DTOs/UserProfile.cs | 2 ++ AGSS/Services/UserService.cs | 4 +++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/AGSS/Controllers/User/UserControllers.cs b/AGSS/Controllers/User/UserControllers.cs index 3e0891d..8e16b8e 100644 --- a/AGSS/Controllers/User/UserControllers.cs +++ b/AGSS/Controllers/User/UserControllers.cs @@ -39,21 +39,20 @@ public class UserControllers:ControllerBase [HttpGet] public async Task My() { - string userId = this.User.FindFirst(JwtRegisteredClaimNames.Sub)!.Value; - if (string.IsNullOrEmpty(userId)) - { - return Ok(new ReturnTemplate(500,"获取用户失败(JWT解析错误)",null)); - } + + + + + string userId = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value; try { var userProfile = await _userService.GetUserProfileAsync(userId); - return Ok(new ReturnTemplate(200,"获取成功!",userProfile)); + return Ok(new ReturnTemplate(200, "获取成功!", userProfile)); } catch (ArgumentException ex) { return NotFound(ex.Message); } - } } \ No newline at end of file diff --git a/AGSS/Models/DTOs/UserProfile.cs b/AGSS/Models/DTOs/UserProfile.cs index 063ab64..4c47f59 100644 --- a/AGSS/Models/DTOs/UserProfile.cs +++ b/AGSS/Models/DTOs/UserProfile.cs @@ -11,4 +11,6 @@ public class UserProfile public string? JobCode { get; set; } public string? JobName { get; set; } public string? Birthday { get; set; } + public string? MenuCode { get; set; } + public string? MenuName { get; set; } } diff --git a/AGSS/Services/UserService.cs b/AGSS/Services/UserService.cs index f688a12..343c590 100644 --- a/AGSS/Services/UserService.cs +++ b/AGSS/Services/UserService.cs @@ -29,7 +29,9 @@ public class UserService Config = user.Config, JobCode = user.JobCode, JobName = user.JobName, - Birthday = user.Birthday + Birthday = user.Birthday, + MenuCode = user.MenuCode, + MenuName = user.MenuName }; } } From bd9bed1b716572ebeecf02479e4edf2462ebd29a Mon Sep 17 00:00:00 2001 From: luolan Date: Thu, 10 Jul 2025 23:15:29 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=E8=A7=92=E8=89=B2=E6=8E=A7=E5=88=B6=E5=99=A8=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF=E5=92=8C=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGSS/Controllers/Admin/AdminRoleControllers.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/AGSS/Controllers/Admin/AdminRoleControllers.cs b/AGSS/Controllers/Admin/AdminRoleControllers.cs index 95c7429..5e16ab2 100644 --- a/AGSS/Controllers/Admin/AdminRoleControllers.cs +++ b/AGSS/Controllers/Admin/AdminRoleControllers.cs @@ -88,7 +88,7 @@ public class AdminRoleControllers:ControllerBase var result = await _userManager.AddToRoleAsync(user, role.Name); if (result.Succeeded) { - return Ok(new ReturnTemplate(200, "角色分配成功", user)); + return Ok(new ReturnTemplate(200, "现在该用户已经被赋予这个角色了", user)); } else { @@ -107,13 +107,13 @@ public class AdminRoleControllers:ControllerBase { if (string.IsNullOrWhiteSpace(userId)) { - return Ok(new ReturnTemplate(400, "你填写的用户ID是空的~", null)); + return Ok(new ReturnTemplate(400, "你打算拿个空的Id来骗我吗?", null)); } var user = await _userManager.FindByIdAsync(userId); if (user == null) { - return Ok(new ReturnTemplate(404, "未找到指定用户哦·~", null)); + return Ok(new ReturnTemplate(404, "你输了个假的用户吧......", null)); } // 删除用户 @@ -150,7 +150,7 @@ public class AdminRoleControllers:ControllerBase } else { - return StatusCode(500, new ReturnTemplate(500, "删除用户时发生错误", result.Errors)); + return StatusCode(500, new ReturnTemplate(500, "删除用户时发生错误,原因请看ErrorResult", result.Errors)); } @@ -170,13 +170,13 @@ public class AdminRoleControllers:ControllerBase { if (string.IsNullOrWhiteSpace(request.RoleName)) { - return Ok(new ReturnTemplate(400, "角色名称不能为空", null)); + return Ok(new ReturnTemplate(400, "角色名称不能为空,就像凌云心里不能没有我一样", null)); } var role = await _roleManager.FindByNameAsync(request.RoleName); if (role == null) { - return Ok(new ReturnTemplate(400, "角色不存在", null)); + return Ok(new ReturnTemplate(400, "你输入的角色不存在哦!", null)); } var usersInRole = await _userManager.GetUsersInRoleAsync(role.Name); From 7bf9c2bc717c12a53a2c20f6a5c9b83bbc808262 Mon Sep 17 00:00:00 2001 From: luolan Date: Thu, 10 Jul 2025 23:22:46 +0800 Subject: [PATCH 08/11] =?UTF-8?q?[Bug]=20=E9=89=B4=E6=9D=83=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84Bug=EF=BC=88=E8=AF=88=E9=AA=97=E4=B8=80?= =?UTF-8?q?=E4=B8=8B=E6=B5=8A=E6=B3=89=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.idea.AGSS/.idea/.gitignore | 13 + .../.idea/material_theme_project_new.xml | 12 + .idea/.idea.AGSS/.idea/sqldialects.xml | 6 + .../20250709144855_Initial.Designer.cs | 308 +++++++++ AGSS/Migrations/20250709144855_Initial.cs | 231 +++++++ AGSS/wwwroot/js/qr.js | 9 + AGSS/wwwroot/lib/qrcode/.gitignore | 4 + AGSS/wwwroot/lib/qrcode/LICENSE | 14 + AGSS/wwwroot/lib/qrcode/README.md | 46 ++ AGSS/wwwroot/lib/qrcode/bower.json | 18 + AGSS/wwwroot/lib/qrcode/index-svg.html | 47 ++ AGSS/wwwroot/lib/qrcode/index.html | 44 ++ AGSS/wwwroot/lib/qrcode/index.svg | 37 ++ AGSS/wwwroot/lib/qrcode/jquery.min.js | 2 + AGSS/wwwroot/lib/qrcode/qrcode.js | 614 ++++++++++++++++++ AGSS/wwwroot/lib/qrcode/qrcode.min.js | 1 + 16 files changed, 1406 insertions(+) create mode 100644 .idea/.idea.AGSS/.idea/.gitignore create mode 100644 .idea/.idea.AGSS/.idea/material_theme_project_new.xml create mode 100644 .idea/.idea.AGSS/.idea/sqldialects.xml create mode 100644 AGSS/Migrations/20250709144855_Initial.Designer.cs create mode 100644 AGSS/Migrations/20250709144855_Initial.cs create mode 100644 AGSS/wwwroot/js/qr.js create mode 100644 AGSS/wwwroot/lib/qrcode/.gitignore create mode 100644 AGSS/wwwroot/lib/qrcode/LICENSE create mode 100644 AGSS/wwwroot/lib/qrcode/README.md create mode 100644 AGSS/wwwroot/lib/qrcode/bower.json create mode 100644 AGSS/wwwroot/lib/qrcode/index-svg.html create mode 100644 AGSS/wwwroot/lib/qrcode/index.html create mode 100644 AGSS/wwwroot/lib/qrcode/index.svg create mode 100644 AGSS/wwwroot/lib/qrcode/jquery.min.js create mode 100644 AGSS/wwwroot/lib/qrcode/qrcode.js create mode 100644 AGSS/wwwroot/lib/qrcode/qrcode.min.js diff --git a/.idea/.idea.AGSS/.idea/.gitignore b/.idea/.idea.AGSS/.idea/.gitignore new file mode 100644 index 0000000..d46111d --- /dev/null +++ b/.idea/.idea.AGSS/.idea/.gitignore @@ -0,0 +1,13 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# Rider 忽略的文件 +/projectSettingsUpdater.xml +/modules.xml +/.idea.AGSS.iml +/contentModel.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.AGSS/.idea/material_theme_project_new.xml b/.idea/.idea.AGSS/.idea/material_theme_project_new.xml new file mode 100644 index 0000000..0c66deb --- /dev/null +++ b/.idea/.idea.AGSS/.idea/material_theme_project_new.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/.idea.AGSS/.idea/sqldialects.xml b/.idea/.idea.AGSS/.idea/sqldialects.xml new file mode 100644 index 0000000..219889c --- /dev/null +++ b/.idea/.idea.AGSS/.idea/sqldialects.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/AGSS/Migrations/20250709144855_Initial.Designer.cs b/AGSS/Migrations/20250709144855_Initial.Designer.cs new file mode 100644 index 0000000..19047eb --- /dev/null +++ b/AGSS/Migrations/20250709144855_Initial.Designer.cs @@ -0,0 +1,308 @@ +// +using System; +using AGSS.DbSet; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace AGSS.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20250709144855_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.6") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AGSS.Models.Entities.RoleModel", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("Birthday") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Config") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Description") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("JobCode") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("JobName") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("MenuCode") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("MenuName") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("Sex") + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("AGSS.Models.Entities.RoleModel", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("AGSS.Models.Entities.UserModel", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("AGSS.Models.Entities.UserModel", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("AGSS.Models.Entities.RoleModel", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AGSS.Models.Entities.UserModel", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("AGSS.Models.Entities.UserModel", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/AGSS/Migrations/20250709144855_Initial.cs b/AGSS/Migrations/20250709144855_Initial.cs new file mode 100644 index 0000000..5ad0b31 --- /dev/null +++ b/AGSS/Migrations/20250709144855_Initial.cs @@ -0,0 +1,231 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace AGSS.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(type: "text", nullable: false), + Name = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + NormalizedName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(type: "text", nullable: false), + Sex = table.Column(type: "text", nullable: true), + Description = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + Config = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + JobCode = table.Column(type: "character varying(10)", maxLength: 10, nullable: true), + JobName = table.Column(type: "character varying(10)", maxLength: 10, nullable: true), + Birthday = table.Column(type: "character varying(20)", maxLength: 20, nullable: true), + MenuCode = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + MenuName = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + UserName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + NormalizedUserName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + Email = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + NormalizedEmail = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + EmailConfirmed = table.Column(type: "boolean", nullable: false), + PasswordHash = table.Column(type: "text", nullable: true), + SecurityStamp = table.Column(type: "text", nullable: true), + ConcurrencyStamp = table.Column(type: "text", nullable: true), + PhoneNumber = table.Column(type: "text", nullable: true), + PhoneNumberConfirmed = table.Column(type: "boolean", nullable: false), + TwoFactorEnabled = table.Column(type: "boolean", nullable: false), + LockoutEnd = table.Column(type: "timestamp with time zone", nullable: true), + LockoutEnabled = table.Column(type: "boolean", nullable: false), + AccessFailedCount = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + RoleId = table.Column(type: "text", nullable: false), + ClaimType = table.Column(type: "text", nullable: true), + ClaimValue = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + UserId = table.Column(type: "text", nullable: false), + ClaimType = table.Column(type: "text", nullable: true), + ClaimValue = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(type: "text", nullable: false), + ProviderKey = table.Column(type: "text", nullable: false), + ProviderDisplayName = table.Column(type: "text", nullable: true), + UserId = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(type: "text", nullable: false), + RoleId = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(type: "text", nullable: false), + LoginProvider = table.Column(type: "text", nullable: false), + Name = table.Column(type: "text", nullable: false), + Value = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + } + } +} diff --git a/AGSS/wwwroot/js/qr.js b/AGSS/wwwroot/js/qr.js new file mode 100644 index 0000000..ce04581 --- /dev/null +++ b/AGSS/wwwroot/js/qr.js @@ -0,0 +1,9 @@ +window.addEventListener("load", () => { + const uri = document.getElementById("qrCodeData").getAttribute('data-url'); + new QRCode(document.getElementById("qrCode"), + { + text: uri, + width: 150, + height: 150 + }); +}); \ No newline at end of file diff --git a/AGSS/wwwroot/lib/qrcode/.gitignore b/AGSS/wwwroot/lib/qrcode/.gitignore new file mode 100644 index 0000000..f4bd643 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/.gitignore @@ -0,0 +1,4 @@ +.DS_Store + +.idea +.project diff --git a/AGSS/wwwroot/lib/qrcode/LICENSE b/AGSS/wwwroot/lib/qrcode/LICENSE new file mode 100644 index 0000000..93c3323 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/LICENSE @@ -0,0 +1,14 @@ +The MIT License (MIT) +--------------------- +Copyright (c) 2012 davidshimjs + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/AGSS/wwwroot/lib/qrcode/README.md b/AGSS/wwwroot/lib/qrcode/README.md new file mode 100644 index 0000000..5e2d2dc --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/README.md @@ -0,0 +1,46 @@ +# QRCode.js +QRCode.js is javascript library for making QRCode. QRCode.js supports Cross-browser with HTML5 Canvas and table tag in DOM. +QRCode.js has no dependencies. + +## Basic Usages +``` +
+ +``` + +or with some options + +``` +
+ +``` + +and you can use some methods + +``` +qrcode.clear(); // clear the code. +qrcode.makeCode("http://naver.com"); // make another code. +``` + +## Browser Compatibility +IE6~10, Chrome, Firefox, Safari, Opera, Mobile Safari, Android, Windows Mobile, ETC. + +## License +MIT License + +## Contact +twitter @davidshimjs + +[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/davidshimjs/qrcodejs/trend.png)](https://bitdeli.com/free "Bitdeli Badge") + diff --git a/AGSS/wwwroot/lib/qrcode/bower.json b/AGSS/wwwroot/lib/qrcode/bower.json new file mode 100644 index 0000000..0509be6 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/bower.json @@ -0,0 +1,18 @@ +{ + "name": "qrcode.js", + "version": "0.0.1", + "homepage": "https://github.com/davidshimjs/qrcodejs", + "authors": [ + "Sangmin Shim", "Sangmin Shim (http://jaguarjs.com)" + ], + "description": "Cross-browser QRCode generator for javascript", + "main": "qrcode.js", + "ignore": [ + "bower_components", + "node_modules", + "index.html", + "index.svg", + "jquery.min.js", + "qrcode.min.js" + ] +} diff --git a/AGSS/wwwroot/lib/qrcode/index-svg.html b/AGSS/wwwroot/lib/qrcode/index-svg.html new file mode 100644 index 0000000..025a135 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/index-svg.html @@ -0,0 +1,47 @@ + + + + Cross-Browser QRCode generator for Javascript + + + + + + + + + + + + + diff --git a/AGSS/wwwroot/lib/qrcode/index.html b/AGSS/wwwroot/lib/qrcode/index.html new file mode 100644 index 0000000..fc16f3d --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/index.html @@ -0,0 +1,44 @@ + + + +Cross-Browser QRCode generator for Javascript + + + + + + +
+
+ + + \ No newline at end of file diff --git a/AGSS/wwwroot/lib/qrcode/index.svg b/AGSS/wwwroot/lib/qrcode/index.svg new file mode 100644 index 0000000..fabe56a --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/index.svg @@ -0,0 +1,37 @@ + + + + + +
+ +
+ + + +
+
diff --git a/AGSS/wwwroot/lib/qrcode/jquery.min.js b/AGSS/wwwroot/lib/qrcode/jquery.min.js new file mode 100644 index 0000000..2740cc4 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
t
",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
","
"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.ajQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/AGSS/wwwroot/lib/qrcode/qrcode.js b/AGSS/wwwroot/lib/qrcode/qrcode.js new file mode 100644 index 0000000..5507c15 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/qrcode.js @@ -0,0 +1,614 @@ +/** + * @fileoverview + * - Using the 'QRCode for Javascript library' + * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. + * - this library has no dependencies. + * + * @author davidshimjs + * @see http://www.d-project.com/ + * @see http://jeromeetienne.github.com/jquery-qrcode/ + */ +var QRCode; + +(function () { + //--------------------------------------------------------------------- + // QRCode for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word "QR Code" is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + //--------------------------------------------------------------------- + function QR8bitByte(data) { + this.mode = QRMode.MODE_8BIT_BYTE; + this.data = data; + this.parsedData = []; + + // Added to support UTF-8 Characters + for (var i = 0, l = this.data.length; i < l; i++) { + var byteArray = []; + var code = this.data.charCodeAt(i); + + if (code > 0x10000) { + byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); + byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); + byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[3] = 0x80 | (code & 0x3F); + } else if (code > 0x800) { + byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); + byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[2] = 0x80 | (code & 0x3F); + } else if (code > 0x80) { + byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); + byteArray[1] = 0x80 | (code & 0x3F); + } else { + byteArray[0] = code; + } + + this.parsedData.push(byteArray); + } + + this.parsedData = Array.prototype.concat.apply([], this.parsedData); + + if (this.parsedData.length != this.data.length) { + this.parsedData.unshift(191); + this.parsedData.unshift(187); + this.parsedData.unshift(239); + } + } + + QR8bitByte.prototype = { + getLength: function (buffer) { + return this.parsedData.length; + }, + write: function (buffer) { + for (var i = 0, l = this.parsedData.length; i < l; i++) { + buffer.put(this.parsedData[i], 8); + } + } + }; + + function QRCodeModel(typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber; + this.errorCorrectLevel = errorCorrectLevel; + this.modules = null; + this.moduleCount = 0; + this.dataCache = null; + this.dataList = []; + } + + QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);} + return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row=7){this.setupTypeNumber(test);} + if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);} + this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} + return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;} + for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}} + for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}} + this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex>>bitIndex)&1)==1);} + var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;} + this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}} + row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;itotalDataCount*8){throw new Error("code length overflow. (" + +buffer.getLengthInBits() + +">" + +totalDataCount*8 + +")");} + if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} + while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} + while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD1,8);} + return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r=0)?modPoly.get(modIndex):0;}} + var totalCodeCount=0;for(var i=0;i=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));} + return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));} + return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;} + return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i5){lostPoint+=(3+sameCount-5);}}} + for(var row=0;row=256){n-=255;} + return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);} + if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));} + this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]]; + + function _isSupportCanvas() { + return typeof CanvasRenderingContext2D != "undefined"; + } + + // android 2.x doesn't support Data-URI spec + function _getAndroid() { + var android = false; + var sAgent = navigator.userAgent; + + if (/android/i.test(sAgent)) { // android + android = true; + var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i); + + if (aMat && aMat[1]) { + android = parseFloat(aMat[1]); + } + } + + return android; + } + + var svgDrawer = (function() { + + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + + this.clear(); + + function makeSVG(tag, attrs) { + var el = document.createElementNS('http://www.w3.org/2000/svg', tag); + for (var k in attrs) + if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]); + return el; + } + + var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight}); + svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); + _el.appendChild(svg); + + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"})); + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"})); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + if (oQRCode.isDark(row, col)) { + var child = makeSVG("use", {"x": String(col), "y": String(row)}); + child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template") + svg.appendChild(child); + } + } + } + }; + Drawing.prototype.clear = function () { + while (this._el.hasChildNodes()) + this._el.removeChild(this._el.lastChild); + }; + return Drawing; + })(); + + var useSVG = document.documentElement.tagName.toLowerCase() === "svg"; + + // Drawing in DOM by using Table tag + var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () { + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + var aHTML = ['
']; + + for (var row = 0; row < nCount; row++) { + aHTML.push(''); + + for (var col = 0; col < nCount; col++) { + aHTML.push(''); + } + + aHTML.push(''); + } + + aHTML.push('
'); + _el.innerHTML = aHTML.join(''); + + // Fix the margin values as real size. + var elTable = _el.childNodes[0]; + var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2; + var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2; + + if (nLeftMarginTable > 0 && nTopMarginTable > 0) { + elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px"; + } + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._el.innerHTML = ''; + }; + + return Drawing; + })() : (function () { // Drawing in Canvas + function _onMakeImage() { + this._elImage.src = this._elCanvas.toDataURL("image/png"); + this._elImage.style.display = "block"; + this._elCanvas.style.display = "none"; + } + + // Android 2.1 bug workaround + // http://code.google.com/p/android/issues/detail?id=5141 + if (this._android && this._android <= 2.1) { + var factor = 1 / window.devicePixelRatio; + var drawImage = CanvasRenderingContext2D.prototype.drawImage; + CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) { + if (("nodeName" in image) && /img/i.test(image.nodeName)) { + for (var i = arguments.length - 1; i >= 1; i--) { + arguments[i] = arguments[i] * factor; + } + } else if (typeof dw == "undefined") { + arguments[1] *= factor; + arguments[2] *= factor; + arguments[3] *= factor; + arguments[4] *= factor; + } + + drawImage.apply(this, arguments); + }; + } + + /** + * Check whether the user's browser supports Data URI or not + * + * @private + * @param {Function} fSuccess Occurs if it supports Data URI + * @param {Function} fFail Occurs if it doesn't support Data URI + */ + function _safeSetDataURI(fSuccess, fFail) { + var self = this; + self._fFail = fFail; + self._fSuccess = fSuccess; + + // Check it just once + if (self._bSupportDataURI === null) { + var el = document.createElement("img"); + var fOnError = function() { + self._bSupportDataURI = false; + + if (self._fFail) { + self._fFail.call(self); + } + }; + var fOnSuccess = function() { + self._bSupportDataURI = true; + + if (self._fSuccess) { + self._fSuccess.call(self); + } + }; + + el.onabort = fOnError; + el.onerror = fOnError; + el.onload = fOnSuccess; + el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data. + return; + } else if (self._bSupportDataURI === true && self._fSuccess) { + self._fSuccess.call(self); + } else if (self._bSupportDataURI === false && self._fFail) { + self._fFail.call(self); + } + }; + + /** + * Drawing QRCode by using canvas + * + * @constructor + * @param {HTMLElement} el + * @param {Object} htOption QRCode Options + */ + var Drawing = function (el, htOption) { + this._bIsPainted = false; + this._android = _getAndroid(); + + this._htOption = htOption; + this._elCanvas = document.createElement("canvas"); + this._elCanvas.width = htOption.width; + this._elCanvas.height = htOption.height; + el.appendChild(this._elCanvas); + this._el = el; + this._oContext = this._elCanvas.getContext("2d"); + this._bIsPainted = false; + this._elImage = document.createElement("img"); + this._elImage.alt = "Scan me!"; + this._elImage.style.display = "none"; + this._el.appendChild(this._elImage); + this._bSupportDataURI = null; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _elImage = this._elImage; + var _oContext = this._oContext; + var _htOption = this._htOption; + + var nCount = oQRCode.getModuleCount(); + var nWidth = _htOption.width / nCount; + var nHeight = _htOption.height / nCount; + var nRoundedWidth = Math.round(nWidth); + var nRoundedHeight = Math.round(nHeight); + + _elImage.style.display = "none"; + this.clear(); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + var bIsDark = oQRCode.isDark(row, col); + var nLeft = col * nWidth; + var nTop = row * nHeight; + _oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.lineWidth = 1; + _oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.fillRect(nLeft, nTop, nWidth, nHeight); + + // 안티 앨리어싱 방지 처리 + _oContext.strokeRect( + Math.floor(nLeft) + 0.5, + Math.floor(nTop) + 0.5, + nRoundedWidth, + nRoundedHeight + ); + + _oContext.strokeRect( + Math.ceil(nLeft) - 0.5, + Math.ceil(nTop) - 0.5, + nRoundedWidth, + nRoundedHeight + ); + } + } + + this._bIsPainted = true; + }; + + /** + * Make the image from Canvas if the browser supports Data URI. + */ + Drawing.prototype.makeImage = function () { + if (this._bIsPainted) { + _safeSetDataURI.call(this, _onMakeImage); + } + }; + + /** + * Return whether the QRCode is painted or not + * + * @return {Boolean} + */ + Drawing.prototype.isPainted = function () { + return this._bIsPainted; + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height); + this._bIsPainted = false; + }; + + /** + * @private + * @param {Number} nNumber + */ + Drawing.prototype.round = function (nNumber) { + if (!nNumber) { + return nNumber; + } + + return Math.floor(nNumber * 1000) / 1000; + }; + + return Drawing; + })(); + + /** + * Get the type by string length + * + * @private + * @param {String} sText + * @param {Number} nCorrectLevel + * @return {Number} type + */ + function _getTypeNumber(sText, nCorrectLevel) { + var nType = 1; + var length = _getUTF8Length(sText); + + for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { + var nLimit = 0; + + switch (nCorrectLevel) { + case QRErrorCorrectLevel.L : + nLimit = QRCodeLimitLength[i][0]; + break; + case QRErrorCorrectLevel.M : + nLimit = QRCodeLimitLength[i][1]; + break; + case QRErrorCorrectLevel.Q : + nLimit = QRCodeLimitLength[i][2]; + break; + case QRErrorCorrectLevel.H : + nLimit = QRCodeLimitLength[i][3]; + break; + } + + if (length <= nLimit) { + break; + } else { + nType++; + } + } + + if (nType > QRCodeLimitLength.length) { + throw new Error("Too long data"); + } + + return nType; + } + + function _getUTF8Length(sText) { + var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a'); + return replacedText.length + (replacedText.length != sText ? 3 : 0); + } + + /** + * @class QRCode + * @constructor + * @example + * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie"); + * + * @example + * var oQRCode = new QRCode("test", { + * text : "http://naver.com", + * width : 128, + * height : 128 + * }); + * + * oQRCode.clear(); // Clear the QRCode. + * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode. + * + * @param {HTMLElement|String} el target element or 'id' attribute of element. + * @param {Object|String} vOption + * @param {String} vOption.text QRCode link data + * @param {Number} [vOption.width=256] + * @param {Number} [vOption.height=256] + * @param {String} [vOption.colorDark="#000000"] + * @param {String} [vOption.colorLight="#ffffff"] + * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] + */ + QRCode = function (el, vOption) { + this._htOption = { + width : 256, + height : 256, + typeNumber : 4, + colorDark : "#000000", + colorLight : "#ffffff", + correctLevel : QRErrorCorrectLevel.H + }; + + if (typeof vOption === 'string') { + vOption = { + text : vOption + }; + } + + // Overwrites options + if (vOption) { + for (var i in vOption) { + this._htOption[i] = vOption[i]; + } + } + + if (typeof el == "string") { + el = document.getElementById(el); + } + + if (this._htOption.useSVG) { + Drawing = svgDrawer; + } + + this._android = _getAndroid(); + this._el = el; + this._oQRCode = null; + this._oDrawing = new Drawing(this._el, this._htOption); + + if (this._htOption.text) { + this.makeCode(this._htOption.text); + } + }; + + /** + * Make the QRCode + * + * @param {String} sText link data + */ + QRCode.prototype.makeCode = function (sText) { + this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); + this._oQRCode.addData(sText); + this._oQRCode.make(); + this._el.title = sText; + this._oDrawing.draw(this._oQRCode); + this.makeImage(); + }; + + /** + * Make the Image from Canvas element + * - It occurs automatically + * - Android below 3 doesn't support Data-URI spec. + * + * @private + */ + QRCode.prototype.makeImage = function () { + if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) { + this._oDrawing.makeImage(); + } + }; + + /** + * Clear the QRCode + */ + QRCode.prototype.clear = function () { + this._oDrawing.clear(); + }; + + /** + * @name QRCode.CorrectLevel + */ + QRCode.CorrectLevel = QRErrorCorrectLevel; +})(); diff --git a/AGSS/wwwroot/lib/qrcode/qrcode.min.js b/AGSS/wwwroot/lib/qrcode/qrcode.min.js new file mode 100644 index 0000000..993e88f --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/qrcode.min.js @@ -0,0 +1 @@ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file From 18b2228e48d0f987c35064257a9791db0961a7e9 Mon Sep 17 00:00:00 2001 From: luolan Date: Fri, 11 Jul 2025 16:17:31 +0800 Subject: [PATCH 09/11] =?UTF-8?q?[Bug]=E6=8A=93=E8=B4=BC=EF=BC=81=E5=8E=9F?= =?UTF-8?q?=E6=9D=A5=E8=B4=BC=E6=98=AFCookies=EF=BC=81=EF=BC=81=EF=BC=81?= =?UTF-8?q?=EF=BC=81=EF=BC=81=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGSS/AGSS.http | 6 - .../Identity/Pages/Account/Login.cshtml.cs | 21 +- .../Identity/Pages/Account/Register.cshtml.cs | 18 +- .../Admin/AdminDictionaryController.cs | 203 ++++++++++++++++++ .../Controllers/Admin/AdminRoleControllers.cs | 19 +- AGSS/DbSet/UserSet.cs | 6 + .../ApplicationDbContextModelSnapshot.cs | 45 ++++ AGSS/Models/DBContext.cs | 14 -- AGSS/Models/DTOs/DictionaryDto.cs | 17 ++ AGSS/Models/Entities/DictionaryModel.cs | 18 ++ AGSS/Models/Entities/JwtModel.cs | 9 + AGSS/Program.cs | 66 +++--- AGSS/Utilities/Jwt.cs | 28 +-- AGSS/appsettings.Development.json | 2 +- AGSS/appsettings.json | 4 +- 15 files changed, 379 insertions(+), 97 deletions(-) create mode 100644 AGSS/Controllers/Admin/AdminDictionaryController.cs delete mode 100644 AGSS/Models/DBContext.cs create mode 100644 AGSS/Models/DTOs/DictionaryDto.cs create mode 100644 AGSS/Models/Entities/DictionaryModel.cs create mode 100644 AGSS/Models/Entities/JwtModel.cs diff --git a/AGSS/AGSS.http b/AGSS/AGSS.http index 7b67830..e69de29 100644 --- a/AGSS/AGSS.http +++ b/AGSS/AGSS.http @@ -1,6 +0,0 @@ -@AGSS_HostAddress = http://localhost:5200 - -GET {{AGSS_HostAddress}}/weatherforecast/ -Accept: application/json - -### diff --git a/AGSS/Areas/Identity/Pages/Account/Login.cshtml.cs b/AGSS/Areas/Identity/Pages/Account/Login.cshtml.cs index 25f1832..99034d9 100644 --- a/AGSS/Areas/Identity/Pages/Account/Login.cshtml.cs +++ b/AGSS/Areas/Identity/Pages/Account/Login.cshtml.cs @@ -6,16 +6,19 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using AGSS.Models.Entities; using AGSS.Utilities; +using asg_form; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace AGSS.Areas.Identity.Pages.Account { @@ -111,7 +114,7 @@ namespace AGSS.Areas.Identity.Pages.Account ReturnUrl = returnUrl; } - public async Task OnPostAsync(string returnUrl = null) + public async Task OnPostAsync([FromServices] IOptions jwtOptions,string returnUrl = null) { returnUrl ??= Url.Content("~/"); @@ -125,12 +128,20 @@ namespace AGSS.Areas.Identity.Pages.Account if (result.Succeeded) { _logger.LogInformation("User logged in."); - var user = await _userManager.FindByEmailAsync(Input.Email); + + var claims = new List(); + claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); + claims.Add(new Claim(ClaimTypes.Name, user.UserName)); var roles = await _userManager.GetRolesAsync(user); - var token = _jwt.GenerateJwtToken(user,roles); - - var frontendCallback = $"{Request.Query["frontendCallback"]}?token={token}"; + foreach (string role in roles) + { + claims.Add(new Claim(ClaimTypes.Role, role)); + } + string jwtToken = _jwt.BuildToken(claims, jwtOptions.Value); + + + var frontendCallback = $"{Request.Query["frontendCallback"]}?token={jwtToken}"; return Redirect(frontendCallback); } diff --git a/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs b/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs index 3884aff..59f2d3c 100644 --- a/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs +++ b/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Security.Claims; using System.Text; using System.Text.Encodings.Web; using System.Threading; @@ -14,12 +15,14 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using AGSS.Models.Entities; using AGSS.Utilities; +using asg_form; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace AGSS.Areas.Identity.Pages.Account { @@ -119,7 +122,7 @@ namespace AGSS.Areas.Identity.Pages.Account ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); } - public async Task OnPostAsync(string returnUrl = null) + public async Task OnPostAsync([FromServices] IOptions jwtOptions,string returnUrl = null) { returnUrl ??= Url.Content("~/"); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); @@ -135,10 +138,17 @@ namespace AGSS.Areas.Identity.Pages.Account if (result.Succeeded) { _logger.LogInformation("User created a new account with password."); + // var roles = await _userManager.GetRolesAsync(user); + var claims = new List(); + claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); + claims.Add(new Claim(ClaimTypes.Name, user.UserName)); var roles = await _userManager.GetRolesAsync(user); - var token = _jwt.GenerateJwtToken(user,roles); - - var frontendCallback = $"{Request.Query["frontendCallback"]}?token={token}"; + foreach (string role in roles) + { + claims.Add(new Claim(ClaimTypes.Role, role)); + } + string jwtToken = _jwt.BuildToken(claims, jwtOptions.Value); + var frontendCallback = $"{Request.Query["frontendCallback"]}?token={jwtToken}"; return Redirect(frontendCallback); } diff --git a/AGSS/Controllers/Admin/AdminDictionaryController.cs b/AGSS/Controllers/Admin/AdminDictionaryController.cs new file mode 100644 index 0000000..95758fe --- /dev/null +++ b/AGSS/Controllers/Admin/AdminDictionaryController.cs @@ -0,0 +1,203 @@ +using System; +using AGSS.Models.Entities; +using AGSS.Models.Template; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using System.Linq; +using System.Threading.Tasks; +using AGSS.DbSet; + +namespace AGSS.Controllers.Admin +{ + + [Route("api/v1/[controller]/[action]")] + public class AdminDictionaryController : ControllerBase + { + private readonly ApplicationDbContext _dbContext; + private readonly UserManager _userManager; + + public AdminDictionaryController(ApplicationDbContext dbContext, UserManager userManager) + { + _dbContext = dbContext; + _userManager = userManager; + } + + [HttpPost] + [Authorize(Roles = "Admin")] + public async Task GetParentDictionaries([FromBody] string label) + { + + + // 确保 label 不是 null + label ??= string.Empty; + + var parentDictionaries = _dbContext.Dictionaries.Where(d => d.ParentId == null && (string.IsNullOrEmpty(label) || d.Label.Contains(label))).ToList(); + return Ok(new ReturnTemplate(200, "查询成功", parentDictionaries)); + } + + [HttpPost] + [Authorize(Roles = "Admin")] + public async Task AddParentDictionary([FromBody] DictionaryModel dictionary) + { + + + if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.Label) || string.IsNullOrWhiteSpace(dictionary.Value)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Label和Value", null)); + } + + dictionary.Uuid = Guid.NewGuid().ToString(); + dictionary.CreateTime = DateTime.UtcNow; + dictionary.CreateUserId = _userManager.GetUserId(User); + + _dbContext.Dictionaries.Add(dictionary); + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "添加父级字典成功", dictionary)); + } + + [HttpPut] + [Authorize(Roles = "Admin")] + public async Task UpdateParentDictionary([FromBody] DictionaryModel dictionary) + { + + + if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.Uuid) || string.IsNullOrWhiteSpace(dictionary.Label)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid和Label", null)); + } + + var existingDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == dictionary.Uuid && d.ParentId == null); + if (existingDictionary == null) + { + return Ok(new ReturnTemplate(404, "未找到指定的父级字典", null)); + } + + existingDictionary.Label = dictionary.Label; + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "更新父级字典成功", existingDictionary)); + } + + [HttpDelete] + [Authorize(Roles = "Admin")] + public async Task DeleteParentDictionary([FromBody] string uuid) + { + + + if (string.IsNullOrWhiteSpace(uuid)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid", null)); + } + + var parentDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == uuid && d.ParentId == null); + if (parentDictionary == null) + { + return Ok(new ReturnTemplate(404, "未找到指定的父级字典", null)); + } + + _dbContext.Dictionaries.RemoveRange(_dbContext.Dictionaries.Where(d => d.ParentId == uuid)); + _dbContext.Dictionaries.Remove(parentDictionary); + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "删除父级字典成功", null)); + } + + [HttpPost] + [Authorize(Roles = "Admin")] + public async Task CreateChildDictionary([FromBody] DictionaryModel dictionary) + { + + + if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.ParentId) || string.IsNullOrWhiteSpace(dictionary.ParentValue) || string.IsNullOrWhiteSpace(dictionary.Label) || string.IsNullOrWhiteSpace(dictionary.Value)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供ParentId、ParentValue、Label和Value", null)); + } + + dictionary.Uuid = Guid.NewGuid().ToString(); + dictionary.CreateTime = DateTime.UtcNow; + dictionary.CreateUserId = _userManager.GetUserId(User); + + _dbContext.Dictionaries.Add(dictionary); + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "创建子级字典成功", dictionary)); + } + + [HttpPut] + [Authorize(Roles = "Admin")] + public async Task UpdateChildDictionary([FromBody] DictionaryModel dictionary) + { + + + if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.Uuid) || string.IsNullOrWhiteSpace(dictionary.Label) || string.IsNullOrWhiteSpace(dictionary.Value)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid、Label和Value", null)); + } + + var existingDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == dictionary.Uuid && d.ParentId != null); + if (existingDictionary == null) + { + return Ok(new ReturnTemplate(404, "未找到指定的子级字典", null)); + } + + existingDictionary.Label = dictionary.Label; + existingDictionary.LabelEn = dictionary.LabelEn; + existingDictionary.Remark = dictionary.Remark; + existingDictionary.Value = dictionary.Value; + existingDictionary.Tag = dictionary.Tag; + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "更新子级字典成功", existingDictionary)); + } + + [HttpDelete] + [Authorize(Roles = "Admin")] + public async Task DeleteChildDictionary([FromBody] string uuid) + { + + if (string.IsNullOrWhiteSpace(uuid)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid", null)); + } + + var childDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == uuid && d.ParentId != null); + if (childDictionary == null) + { + return Ok(new ReturnTemplate(404, "未找到指定的子级字典", null)); + } + + _dbContext.Dictionaries.Remove(childDictionary); + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "删除子级字典成功", null)); + } + + [HttpGet] + public IActionResult GetChildDictionaries([FromBody] ChildDictionaryRequest request) + { + if (string.IsNullOrWhiteSpace(request.Value)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Value", null)); + } + + var childDictionaries = _dbContext.Dictionaries + .Where(d => d.ParentValue == request.Value && + (request.Tag == null || (!string.IsNullOrEmpty(d.Tag) && d.Tag.Contains("," + request.Tag + ",")))) + .ToList(); + + if (request.Tag != null) + { + childDictionaries = childDictionaries.Where(d => !string.IsNullOrEmpty(d.Tag)).ToList(); + } + + return Ok(new ReturnTemplate(200, "查询成功", childDictionaries)); + } + public class ChildDictionaryRequest + { + public string Value { get; set; } + public string Tag { get; set; } + } + } +} \ No newline at end of file diff --git a/AGSS/Controllers/Admin/AdminRoleControllers.cs b/AGSS/Controllers/Admin/AdminRoleControllers.cs index 5e16ab2..d235cbe 100644 --- a/AGSS/Controllers/Admin/AdminRoleControllers.cs +++ b/AGSS/Controllers/Admin/AdminRoleControllers.cs @@ -1,7 +1,11 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using AGSS.Models.DTOs; using AGSS.Models.Entities; using AGSS.Models.Template; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; @@ -11,7 +15,7 @@ namespace AGSS.Controllers.Admin; /// 控制器类,用于管理角色相关的操作,包括添加角色、分配角色给用户以及通过角色查询用户。 /// 该控制器仅限具有"Admin"角色的用户访问。 /// -[Authorize(Roles = "Admin")] +[Authorize] [Route("api/v1/[controller]/[action]")] public class AdminRoleControllers:ControllerBase { @@ -44,18 +48,15 @@ public class AdminRoleControllers:ControllerBase /// 要添加的角色信息 /// 返回操作结果,包含状态码、消息和数据 [HttpPost] - public async Task AddRole([FromBody] RoleModel role) + public async Task AddRole(string rolename) { - if (role == null || string.IsNullOrWhiteSpace(role.Name)) - { - - return Ok(new ReturnTemplate(400,"创建失败,请提供名字","")); - } + + - var result = await _roleManager.CreateAsync(role); + var result = await _roleManager.CreateAsync(new RoleModel(){Id = new Guid().ToString(),Name = rolename,NormalizedName = rolename}); if (result.Succeeded) { - return Ok(new ReturnTemplate(200,"创建成功",role)); + return Ok(new ReturnTemplate(200,"创建成功","")); } else diff --git a/AGSS/DbSet/UserSet.cs b/AGSS/DbSet/UserSet.cs index 6d1fb54..a2dbb4d 100644 --- a/AGSS/DbSet/UserSet.cs +++ b/AGSS/DbSet/UserSet.cs @@ -9,6 +9,7 @@ namespace AGSS.DbSet public override DbSet Users { get; set; } public override DbSet Roles { get; set; } + public DbSet Dictionaries { get; set; } public ApplicationDbContext(DbContextOptions options) : base(options) @@ -20,6 +21,11 @@ namespace AGSS.DbSet { base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .HasKey(d => d.Uuid); // 假设 Id 是 DictionaryModel 的主键字段 + + // 在这里添加额外的配置,如果需要的话 // 例如: // modelBuilder.Entity().ToTable("CustomUsers"); diff --git a/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs b/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs index 058cb5a..57eb2fc 100644 --- a/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs @@ -22,6 +22,51 @@ namespace AGSS.Migrations NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + modelBuilder.Entity("AGSS.Models.Entities.DictionaryModel", b => + { + b.Property("Uuid") + .HasColumnType("text"); + + b.Property("CreateTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreateUserId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text"); + + b.Property("LabelEn") + .IsRequired() + .HasColumnType("text"); + + b.Property("ParentId") + .IsRequired() + .HasColumnType("text"); + + b.Property("ParentValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Remark") + .IsRequired() + .HasColumnType("text"); + + b.Property("Tag") + .IsRequired() + .HasColumnType("text"); + + b.Property("Value") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Uuid"); + + b.ToTable("Dictionaries"); + }); + modelBuilder.Entity("AGSS.Models.Entities.RoleModel", b => { b.Property("Id") diff --git a/AGSS/Models/DBContext.cs b/AGSS/Models/DBContext.cs deleted file mode 100644 index f49ba8b..0000000 --- a/AGSS/Models/DBContext.cs +++ /dev/null @@ -1,14 +0,0 @@ -using AGSS.Models.Entities; -using Microsoft.EntityFrameworkCore; - -namespace AGSS.Models; - -public class DBContext : DbContext -{ - public DBContext(DbContextOptions options) - : base(options) - { - } - - -} \ No newline at end of file diff --git a/AGSS/Models/DTOs/DictionaryDto.cs b/AGSS/Models/DTOs/DictionaryDto.cs new file mode 100644 index 0000000..9558932 --- /dev/null +++ b/AGSS/Models/DTOs/DictionaryDto.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; + +namespace AGSS.Models.DTOs +{ + public class DictionaryDto + { + public string Uuid { get; set; } + public string ParentId { get; set; } + public string ParentValue { get; set; } + public string Label { get; set; } + public string LabelEn { get; set; } + public string Remark { get; set; } + public string Value { get; set; } + public string Tag { get; set; } + } +} diff --git a/AGSS/Models/Entities/DictionaryModel.cs b/AGSS/Models/Entities/DictionaryModel.cs new file mode 100644 index 0000000..77269e1 --- /dev/null +++ b/AGSS/Models/Entities/DictionaryModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +namespace AGSS.Models.Entities +{ + public class DictionaryModel + { + public string Uuid { get; set; } + public string ParentId { get; set; } + public string ParentValue { get; set; } + public string Label { get; set; } + public string LabelEn { get; set; } + public string Remark { get; set; } + public string Value { get; set; } + public string Tag { get; set; } + public DateTime CreateTime { get; set; } + public string CreateUserId { get; set; } + } +} diff --git a/AGSS/Models/Entities/JwtModel.cs b/AGSS/Models/Entities/JwtModel.cs new file mode 100644 index 0000000..6882ed9 --- /dev/null +++ b/AGSS/Models/Entities/JwtModel.cs @@ -0,0 +1,9 @@ +namespace asg_form +{ + public class JWTOptions + { + public string SigningKey { get; set; } + public int ExpireSeconds { get; set; } + } + +} diff --git a/AGSS/Program.cs b/AGSS/Program.cs index 427490c..c970228 100644 --- a/AGSS/Program.cs +++ b/AGSS/Program.cs @@ -5,6 +5,7 @@ using AGSS.Models; using AGSS.Models.Entities; using AGSS.Models.Template; using AGSS.Utilities; +using asg_form; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; @@ -33,49 +34,48 @@ builder.Services.AddDbContext(opt => opt.UseNpgsql(builder.Configuration.GetConnectionString("DBContext"))); // Identity 配置 -builder.Services.AddIdentity() - .AddEntityFrameworkStores() - .AddDefaultTokenProviders() - .AddDefaultUI(); +builder.Services.AddIdentityCore(options => +{ + options.Password.RequireDigit = false; + options.Password.RequireLowercase = false; + options.Password.RequireNonAlphanumeric = false; + options.Password.RequireUppercase = false; + options.Password.RequiredLength = 6; + options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider; + options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider; +}) +.AddRoles() +.AddEntityFrameworkStores() +.AddDefaultUI() +; // 注册 UserService - builder.Services.AddScoped(); + // builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddAuthentication(options => + + + + +builder.Services.Configure(builder.Configuration.GetSection("JWT")); + +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(x => { - options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }) - .AddJwtBearer(options => - { - options.TokenValidationParameters = new TokenValidationParameters + var jwtOpt = builder.Configuration.GetSection("JWT").Get(); + byte[] keyBytes = Encoding.UTF8.GetBytes(jwtOpt.SigningKey); + var secKey = new SymmetricSecurityKey(keyBytes); + x.TokenValidationParameters = new() { - ValidateIssuer = true, - ValidateAudience = true, + ValidateIssuer = false, + ValidateAudience = false, ValidateLifetime = true, ValidateIssuerSigningKey = true, - ValidIssuer = builder.Configuration["Jwt:Issuer"], - ValidAudience = builder.Configuration["Jwt:Audience"], - IssuerSigningKey = new SymmetricSecurityKey( - Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) + IssuerSigningKey = secKey }; - options.Events = new JwtBearerEvents - { - OnChallenge = context => - { - context.HandleResponse(); - context.Response.StatusCode = 200; - context.Response.ContentType = "application/json"; - return context.Response.WriteAsJsonAsync(new ReturnTemplate(401, "你提供了一个错误的Token,所以我们无法验证你的身份,唔......", null)); - } - }; - }).AddMicrosoftAccount(microsoftOptions => - { - microsoftOptions.ClientId = configuration["Authentication:Microsoft:ClientId"]; - microsoftOptions.ClientSecret = configuration["Authentication:Microsoft:ClientSecret"]; - }); + }) + .AddCookie("Identity.External"); diff --git a/AGSS/Utilities/Jwt.cs b/AGSS/Utilities/Jwt.cs index 6d3c49f..ed86907 100644 --- a/AGSS/Utilities/Jwt.cs +++ b/AGSS/Utilities/Jwt.cs @@ -2,23 +2,19 @@ using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using AGSS.Models.Entities; +using asg_form; using Microsoft.IdentityModel.Tokens; namespace AGSS.Utilities; public class Jwt { - private readonly IConfiguration _configuration; + - public Jwt(IConfiguration configuration) + public string BuildToken(IEnumerable claims, JWTOptions options) { - _configuration = configuration; - } - - public string BuildToken(IEnumerable claims) - { - DateTime expires = DateTime.Now.AddDays(int.Parse(_configuration["Jwt:ExpireMinutes"])); - byte[] keyBytes = Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]); + DateTime expires = DateTime.Now.AddSeconds(options.ExpireSeconds); + byte[] keyBytes = Encoding.UTF8.GetBytes(options.SigningKey); var secKey = new SymmetricSecurityKey(keyBytes); var credentials = new SigningCredentials(secKey, @@ -27,18 +23,4 @@ public class Jwt signingCredentials: credentials, claims: claims); return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor); } - - public string GenerateJwtToken(UserModel user,IList roles) - { - var claims = new List(); - claims.Add(new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString())); - claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())); - // var roles = await user.GetRolesAsync(user); - foreach (string role in roles) - { - claims.Add(new Claim(ClaimTypes.Role, role)); - } - string jwtToken = BuildToken(claims); - return jwtToken; - } } \ No newline at end of file diff --git a/AGSS/appsettings.Development.json b/AGSS/appsettings.Development.json index d1c269e..021d945 100644 --- a/AGSS/appsettings.Development.json +++ b/AGSS/appsettings.Development.json @@ -18,7 +18,7 @@ "ExpireMinutes": "4", "Issuer": "https://api.zeronode.cn/api", "Audience": "https://api.zeronode.cn/api", - "Key": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak" + "SigningKey": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak" }, "ConnectionStrings": { "DBContext": "Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=luolan12323;" diff --git a/AGSS/appsettings.json b/AGSS/appsettings.json index 6527a3d..6e8922d 100644 --- a/AGSS/appsettings.json +++ b/AGSS/appsettings.json @@ -14,11 +14,11 @@ }, "AllowedHosts": "*", - "Jwt": { + "JWT": { "ExpireMinutes": "4", "Issuer": "https://api.zeronode.cn/api", "Audience": "https://api.zeronode.cn/api", - "Key": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak" + "SigningKey": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak" }, "ConnectionStrings": { "DBContext": "Host=1Panel-postgresql-auKB;Port=5432;Database=zeronode;Username=zeronode;Password=luolan12323;" From 0f859cf39e34f497e97a43e5a41335c27d64f67a Mon Sep 17 00:00:00 2001 From: luolan Date: Fri, 11 Jul 2025 22:59:29 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=B9=B6=E6=9B=B4=E6=96=B0=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=E8=A7=92=E8=89=B2=E6=8E=A7=E5=88=B6=E5=99=A8=E4=BB=A5?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=94=A8=E6=88=B7=E6=9F=A5=E8=AF=A2=E5=92=8C?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Admin/AdminRoleControllers.cs | 46 +++++++++++++------ AGSS/Controllers/User/UserControllers.cs | 3 +- AGSS/Program.cs | 5 +- AGSS/Services/UserService.cs | 37 ++++++++++++++- AGSS/Utilities/LINQ.cs | 27 +++++++++++ 5 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 AGSS/Utilities/LINQ.cs diff --git a/AGSS/Controllers/Admin/AdminRoleControllers.cs b/AGSS/Controllers/Admin/AdminRoleControllers.cs index d235cbe..e33728f 100644 --- a/AGSS/Controllers/Admin/AdminRoleControllers.cs +++ b/AGSS/Controllers/Admin/AdminRoleControllers.cs @@ -1,13 +1,16 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using AGSS.Models; using AGSS.Models.DTOs; using AGSS.Models.Entities; using AGSS.Models.Template; +using AGSS.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; namespace AGSS.Controllers.Admin; @@ -19,6 +22,20 @@ namespace AGSS.Controllers.Admin; [Route("api/v1/[controller]/[action]")] public class AdminRoleControllers:ControllerBase { + /// + /// 用户服务实例,用于执行与用户相关的操作。 + /// 该服务提供了一系列方法来处理用户的查询和更新等操作, + /// 包括但不限于获取用户详细信息、修改用户资料等功能。 + /// + private readonly UserService _userService; + + public AdminRoleControllers(UserService userService, RoleManager roleManager, UserManager userManager) + { + _userService = userService; + _roleManager = roleManager; + _userManager = userManager; + } + /// /// 角色管理器,用于处理角色相关的操作,如创建、查询等。 /// 此角色管理器实例主要用于与RoleModel类型的实体进行交互, @@ -36,11 +53,7 @@ public class AdminRoleControllers:ControllerBase /// 管理员角色控制器,用于处理与角色相关的操作,如添加角色、分配角色给用户以及通过角色查询用户。 /// 该控制器下的所有方法都需要管理员权限才能访问。 /// - public AdminRoleControllers(RoleManager roleManager, UserManager userManager) - { - _roleManager = roleManager; - _userManager = userManager; - } + /// /// 添加新角色 @@ -48,12 +61,12 @@ public class AdminRoleControllers:ControllerBase /// 要添加的角色信息 /// 返回操作结果,包含状态码、消息和数据 [HttpPost] - public async Task AddRole(string rolename) + public async Task AddRole(string rolename,string normalizedname) { - var result = await _roleManager.CreateAsync(new RoleModel(){Id = new Guid().ToString(),Name = rolename,NormalizedName = rolename}); + var result = await _roleManager.CreateAsync(new RoleModel(){Id = Guid.Empty.ToString(),Name = rolename,NormalizedName = normalizedname}); if (result.Succeeded) { return Ok(new ReturnTemplate(200,"创建成功","")); @@ -169,18 +182,21 @@ public class AdminRoleControllers:ControllerBase [HttpPost] public async Task SearchUserFromRole([FromBody] SearchUserFromRoleRequest request) { + + + + + IList usersInRole = null; if (string.IsNullOrWhiteSpace(request.RoleName)) { - return Ok(new ReturnTemplate(400, "角色名称不能为空,就像凌云心里不能没有我一样", null)); + usersInRole = _userManager.Users.ToList(); } - - var role = await _roleManager.FindByNameAsync(request.RoleName); - if (role == null) + else { - return Ok(new ReturnTemplate(400, "你输入的角色不存在哦!", null)); + usersInRole = await _userService.GetUsersProfileInRoleAsync(request.RoleName); + } - var usersInRole = await _userManager.GetUsersInRoleAsync(role.Name); var totalUsers = usersInRole.Count; var pagedUsers = usersInRole @@ -202,6 +218,8 @@ public class AdminRoleControllers:ControllerBase /// public class SearchUserFromRoleRequest { + + /// /// 表示角色的名称。此属性用于指定或获取与用户管理相关的角色名称。 /// 在进行角色分配、查询等操作时,需要提供正确的角色名称以确保操作的成功执行。 @@ -236,6 +254,6 @@ public class AdminRoleControllers:ControllerBase /// 表示属于特定角色的用户列表。该属性用于存储和返回在给定角色下的所有用户。 /// /// 此列表通常作为查询结果的一部分,例如通过角色名搜索用户时返回的数据。 - public List Users { get; set; } + public List Users { get; set; } } } \ No newline at end of file diff --git a/AGSS/Controllers/User/UserControllers.cs b/AGSS/Controllers/User/UserControllers.cs index 8e16b8e..41c9f14 100644 --- a/AGSS/Controllers/User/UserControllers.cs +++ b/AGSS/Controllers/User/UserControllers.cs @@ -2,6 +2,7 @@ using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using AGSS.Models.Entities; using AGSS.Models.Template; +using AGSS.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; @@ -29,7 +30,7 @@ public class UserControllers:ControllerBase public UserControllers(UserService userService, UserManager userManager) { _userService = userService; - } + } /// diff --git a/AGSS/Program.cs b/AGSS/Program.cs index c970228..3e306db 100644 --- a/AGSS/Program.cs +++ b/AGSS/Program.cs @@ -4,6 +4,7 @@ using AGSS.DbSet; using AGSS.Models; using AGSS.Models.Entities; using AGSS.Models.Template; +using AGSS.Services; using AGSS.Utilities; using asg_form; using Microsoft.AspNetCore.Authentication.JwtBearer; @@ -53,7 +54,7 @@ builder.Services.AddIdentityCore(options => // builder.Services.AddScoped(); builder.Services.AddScoped(); - +builder.Services.AddScoped(); @@ -75,7 +76,7 @@ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) IssuerSigningKey = secKey }; }) - .AddCookie("Identity.External"); + .AddCookie("Identity.External").AddCookie("Identity.Application"); diff --git a/AGSS/Services/UserService.cs b/AGSS/Services/UserService.cs index 343c590..29ec325 100644 --- a/AGSS/Services/UserService.cs +++ b/AGSS/Services/UserService.cs @@ -2,6 +2,8 @@ using AGSS.Models; using AGSS.Models.Entities; using Microsoft.AspNetCore.Identity; +namespace AGSS.Services; + public class UserService { private readonly UserManager _userManager; @@ -34,4 +36,37 @@ public class UserService MenuName = user.MenuName }; } -} + + + public async Task> GetUsersProfileInRoleAsync(string roleName) + { + var usersInRole = await _userManager.GetUsersInRoleAsync(roleName); + if (usersInRole == null || !usersInRole.Any()) + { + throw new ArgumentException("No users found in the specified role"); + } + + var userProfiles = new List(); + foreach (var user in usersInRole) + { + userProfiles.Add(new UserProfile + { + Id = user.Id, + UserName = user.UserName, + Email = user.Email, + Sex = user.Sex, + Description = user.Description, + Config = user.Config, + JobCode = user.JobCode, + JobName = user.JobName, + Birthday = user.Birthday, + MenuCode = user.MenuCode, + MenuName = user.MenuName + }); + } + + // Assuming you want to return a single UserProfile, you might need to adjust this logic + // For now, returning the first user's profile + return userProfiles; + } +} \ No newline at end of file diff --git a/AGSS/Utilities/LINQ.cs b/AGSS/Utilities/LINQ.cs new file mode 100644 index 0000000..467e000 --- /dev/null +++ b/AGSS/Utilities/LINQ.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace AGSS.Utilities; + +public static class LINQ +{ + /// + /// 从给定的序列中分页获取元素。 + /// + /// 序列中的元素类型。 + /// 要从中分页的源序列。 + /// 请求的页码,从0开始。 + /// 每页包含的元素数量。 + /// 返回指定页码和页大小对应的子序列。 + /// 如果source为null。 + /// 如果pageIndex是负数或者pageSize是非正数。 + public static IEnumerable Paginate(this IEnumerable source, int pageIndex, int pageSize) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex), "Page index must be non-negative."); + if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize), "Page size must be positive."); + + return source.Skip(pageIndex * pageSize).Take(pageSize); + } +} \ No newline at end of file From c21b8be5e1e6f4afef6993fd8291dbbe3930a0f4 Mon Sep 17 00:00:00 2001 From: luolan Date: Sat, 12 Jul 2025 15:00:55 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=8A=9F=E8=83=BD=E5=B9=B6=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E9=A1=B5=E9=9D=A2=E5=92=8C=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=99=A8=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Identity/Pages/Account/Register.cshtml | 5 ++ .../Identity/Pages/Account/Register.cshtml.cs | 7 ++- .../Admin/AdminDictionaryController.cs | 2 +- .../Controllers/Admin/AdminRoleControllers.cs | 15 +++-- AGSS/Models/Entities/User.cs | 3 +- AGSS/Services/UserService.cs | 57 +++++++++++++++++++ 6 files changed, 80 insertions(+), 9 deletions(-) diff --git a/AGSS/Areas/Identity/Pages/Account/Register.cshtml b/AGSS/Areas/Identity/Pages/Account/Register.cshtml index cdbeffe..eba2f18 100644 --- a/AGSS/Areas/Identity/Pages/Account/Register.cshtml +++ b/AGSS/Areas/Identity/Pages/Account/Register.cshtml @@ -12,6 +12,11 @@

创建新账户。


+
+ + + +
diff --git a/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs b/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs index 59f2d3c..a5310f8 100644 --- a/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs +++ b/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs @@ -110,9 +110,12 @@ namespace AGSS.Areas.Identity.Pages.Account [MaxLength(10)] - [Display(Name = "Confirm password")] public string Sex { get; set; } + + [MaxLength(10)] + public string UserName { get; set; } + } @@ -131,7 +134,7 @@ namespace AGSS.Areas.Identity.Pages.Account var user = CreateUser(); user.Id = Guid.NewGuid().ToString(); user.Sex = Input.Sex; - await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None); + await _userStore.SetUserNameAsync(user, Input.UserName, CancellationToken.None); await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None); var result = await _userManager.CreateAsync(user, Input.Password); diff --git a/AGSS/Controllers/Admin/AdminDictionaryController.cs b/AGSS/Controllers/Admin/AdminDictionaryController.cs index 95758fe..45bc88b 100644 --- a/AGSS/Controllers/Admin/AdminDictionaryController.cs +++ b/AGSS/Controllers/Admin/AdminDictionaryController.cs @@ -174,7 +174,7 @@ namespace AGSS.Controllers.Admin return Ok(new ReturnTemplate(200, "删除子级字典成功", null)); } - [HttpGet] + [HttpPost] public IActionResult GetChildDictionaries([FromBody] ChildDictionaryRequest request) { if (string.IsNullOrWhiteSpace(request.Value)) diff --git a/AGSS/Controllers/Admin/AdminRoleControllers.cs b/AGSS/Controllers/Admin/AdminRoleControllers.cs index e33728f..09bcf08 100644 --- a/AGSS/Controllers/Admin/AdminRoleControllers.cs +++ b/AGSS/Controllers/Admin/AdminRoleControllers.cs @@ -169,8 +169,13 @@ public class AdminRoleControllers:ControllerBase } - - + [HttpGet] + public async Task AllRole() + { + + return Ok(new ReturnTemplate(200,"查询成功啦!", _roleManager.Roles.ToList())); + + } @@ -189,11 +194,12 @@ public class AdminRoleControllers:ControllerBase IList usersInRole = null; if (string.IsNullOrWhiteSpace(request.RoleName)) { - usersInRole = _userManager.Users.ToList(); + usersInRole = await _userService.GetUsersProfileByUserNameAsync(request.UserName); } else { - usersInRole = await _userService.GetUsersProfileInRoleAsync(request.RoleName); + var usersInRole1 = await _userService.GetUsersProfileInRoleAsync(request.RoleName); + usersInRole = usersInRole1.Where(a => a.UserName.Contains(request.UserName)).ToList(); } @@ -220,6 +226,7 @@ public class AdminRoleControllers:ControllerBase { + public string UserName { get; set; } /// /// 表示角色的名称。此属性用于指定或获取与用户管理相关的角色名称。 /// 在进行角色分配、查询等操作时,需要提供正确的角色名称以确保操作的成功执行。 diff --git a/AGSS/Models/Entities/User.cs b/AGSS/Models/Entities/User.cs index 0ac6258..242326c 100644 --- a/AGSS/Models/Entities/User.cs +++ b/AGSS/Models/Entities/User.cs @@ -5,8 +5,7 @@ namespace AGSS.Models.Entities; public class UserModel:IdentityUser { - - public string? Sex { get; set; } + public string? Sex { get; set; } [MaxLength(100)] public string? Description { get; set; } [MaxLength(200)] diff --git a/AGSS/Services/UserService.cs b/AGSS/Services/UserService.cs index 29ec325..440d43b 100644 --- a/AGSS/Services/UserService.cs +++ b/AGSS/Services/UserService.cs @@ -1,6 +1,7 @@ using AGSS.Models; using AGSS.Models.Entities; using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; namespace AGSS.Services; @@ -69,4 +70,60 @@ public class UserService // For now, returning the first user's profile return userProfiles; } + + + public async Task> GetUsersProfileByUserNameAsync(string userName) + { + var users = await _userManager.Users + .Where(u => u.UserName.Contains(userName)) + .Select(u => new UserProfile + { + Id = u.Id, + UserName = u.UserName, + Email = u.Email, + Sex = u.Sex, + Description = u.Description, + Config = u.Config, + JobCode = u.JobCode, + JobName = u.JobName, + Birthday = u.Birthday, + MenuCode = u.MenuCode, + MenuName = u.MenuName + }) + .ToListAsync(); + + if (users == null || !users.Any()) + { + throw new ArgumentException("No users found with the specified username"); + } + + return users; + } + + public async Task> GetUsersProfileAllAsync() + { + var users = await _userManager.Users + .Select(u => new UserProfile + { + Id = u.Id, + UserName = u.UserName, + Email = u.Email, + Sex = u.Sex, + Description = u.Description, + Config = u.Config, + JobCode = u.JobCode, + JobName = u.JobName, + Birthday = u.Birthday, + MenuCode = u.MenuCode, + MenuName = u.MenuName + }) + .ToListAsync(); + + if (users == null || !users.Any()) + { + throw new ArgumentException("No users found"); + } + + return users; + } } \ No newline at end of file