diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..07608a4 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,41 @@ +[*.cs] +#### Naming styles #### +# Naming rules +dotnet_naming_rule.const_should_be_all_upper.severity = suggestion +dotnet_naming_rule.const_should_be_all_upper.symbols = const +dotnet_naming_rule.const_should_be_all_upper.style = all_upper + +dotnet_naming_rule.static_readonly_field_should_be_all_upper.severity = suggestion +dotnet_naming_rule.static_readonly_field_should_be_all_upper.symbols = static_readonly_field +dotnet_naming_rule.static_readonly_field_should_be_all_upper.style = all_upper + +dotnet_naming_rule.private_or_internal_field_should_be_private_field.severity = suggestion +dotnet_naming_rule.private_or_internal_field_should_be_private_field.symbols = private_or_internal_field +dotnet_naming_rule.private_or_internal_field_should_be_private_field.style = private_field + +# Symbol specifications +dotnet_naming_symbols.const.applicable_kinds = field +dotnet_naming_symbols.const.applicable_accessibilities = * +dotnet_naming_symbols.const.required_modifiers = const + +dotnet_naming_symbols.static_readonly_field.applicable_kinds = field +dotnet_naming_symbols.static_readonly_field.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.static_readonly_field.required_modifiers = readonly, static + +dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field +dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected +dotnet_naming_symbols.private_or_internal_field.required_modifiers = + +# Naming styles +dotnet_naming_style.private_field.required_prefix = _ +dotnet_naming_style.private_field.required_suffix = +dotnet_naming_style.private_field.word_separator = +dotnet_naming_style.private_field.capitalization = camel_case + +dotnet_naming_style.all_upper.required_prefix = +dotnet_naming_style.all_upper.required_suffix = +dotnet_naming_style.all_upper.word_separator = _ +dotnet_naming_style.all_upper.capitalization = all_upper + +# Add copyright file header +file_header_template = Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛\n\nSimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:\n1.请不要删除和修改根目录下的LICENSE文件。\n2.请不要删除和修改SimpleAdmin源码头部的版权声明。\n3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin\n4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。\n5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。\n6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 diff --git a/.template.config/template.json b/.template.config/template.json new file mode 100644 index 0000000..09e1d1f --- /dev/null +++ b/.template.config/template.json @@ -0,0 +1,13 @@ +{ + "author": "huguodong", //必须 + "classifications": [ "Web/ASP.NET" ], //必须,这个对应模板的Tags + "name": "SimpleAdmin", //必须,这个对应模板的Templates + "identity": "SimpleAdmin", //可选,模板的唯一名称 + "shortName": "simpleadmin", //必须,这个对应模板的Short Name + "tags": { + "language": "C#" , + "type":"project" + }, + "sourceName": "SimpleAdmin", // 可选,要替换的名字 + "preferNameDirectory": true // 可选,添加目录 +} \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..527e357 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,13 @@ + + + net6.0;net7.0;net8.0; + 1701;1702;8616;1591;8618;8619;8629;8602;8603;8604;8625;8765 + 3.0.0 + enable + en-US + + + + $(MSBuildProjectName).xml + + \ No newline at end of file diff --git a/SimpleAdmin.Application/Application.Development.json b/SimpleAdmin.Application/Application.Development.json new file mode 100644 index 0000000..6affcb7 --- /dev/null +++ b/SimpleAdmin.Application/Application.Development.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://gitee.com/dotnetmoyu/MoYu/raw/v4/schemas/v4/MoYu-schema.json", + //swagger分组设置 + "[openapi:Application]": { + "Order": 90, //分组排序,int 类型,数字越大排前面,默认 0 + "Title": "业务模块" //配置分组标题,string 类型 + }, + //系统层设置 + "ApplicationSettings": { + "InitTable": false, //是否初始化表结构 + "InitSeedData": false //是否初始化种子数据 + } +} \ No newline at end of file diff --git a/SimpleAdmin.Application/Application.Production.json b/SimpleAdmin.Application/Application.Production.json new file mode 100644 index 0000000..3f68a37 --- /dev/null +++ b/SimpleAdmin.Application/Application.Production.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://gitee.com/dotnetmoyu/MoYu/raw/v4/schemas/v4/MoYu-schema.json", + //swagger分组设置 + "[openapi:Application]": { + "Order": 90, //分组排序,int 类型,数字越大排前面,默认 0 + "Title": "业务模块" //配置分组标题,string 类型 + }, + //系统层设置 + "ApplicationSettings": { + "InitTable": false, //是否初始化表结构 + "InitSeedData": false, //是否初始化种子数据0 + } +} \ No newline at end of file diff --git a/SimpleAdmin.Application/Const/ApplicationConst.cs b/SimpleAdmin.Application/Const/ApplicationConst.cs new file mode 100644 index 0000000..6e31e38 --- /dev/null +++ b/SimpleAdmin.Application/Const/ApplicationConst.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +public class ApplicationConst +{ + #region 别称 + + /// + /// 机构 + /// + public const string BIZ_ORG = "机构"; + + + /// + /// 岗位 + /// + public const string BIZ_POS = "岗位"; + + #endregion 别称 +} diff --git a/SimpleAdmin.Application/Entity/GenTest.cs b/SimpleAdmin.Application/Entity/GenTest.cs new file mode 100644 index 0000000..86efa85 --- /dev/null +++ b/SimpleAdmin.Application/Entity/GenTest.cs @@ -0,0 +1,56 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +/// +/// 代码生成基础 +/// +[SugarTable("gen_test", TableDescription = "代码生成测试")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +[CodeGen] +public class GenTest : DataEntityBase +{ + /// + /// 姓名 + /// + public string Name { get; set; } + + /// + /// 性别 + /// + public string Sex { get; set; } + + /// + /// 民族 + /// + public string Nation { get; set; } + + /// + /// 年龄 + /// + + public int Age { get; set; } + + /// + /// 生日 + /// + public DateTime Bir { get; set; } + + /// + /// 存款 + /// + public decimal Money { get; set; } + + /// + /// 排序码 + /// + public int SortCode { get; set; } +} diff --git a/SimpleAdmin.Application/Entity/Medicinal.cs b/SimpleAdmin.Application/Entity/Medicinal.cs new file mode 100644 index 0000000..c4512e2 --- /dev/null +++ b/SimpleAdmin.Application/Entity/Medicinal.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SimpleAdmin.Application.Entity +{ + [SugarTable("WeiBingJu_Medicinal", TableDescription = "药材管理")] + [Tenant(SqlSugarConst.DB_DEFAULT)] + [CodeGen] + public class Medicinal : DataEntityBase + { + /// + /// 药材 + /// + [SugarColumn(ColumnDescription = "药材")] + public string MedicinalName { get; set; } + /// + /// 数量(g) + /// + [SugarColumn(ColumnDescription = "数量(g)")] + public decimal Number { get; set; } + + } +} diff --git a/SimpleAdmin.Application/Entity/MedicinalAddLog.cs b/SimpleAdmin.Application/Entity/MedicinalAddLog.cs new file mode 100644 index 0000000..b7d979a --- /dev/null +++ b/SimpleAdmin.Application/Entity/MedicinalAddLog.cs @@ -0,0 +1,48 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SimpleAdmin.Application.Entity +{ + [SugarTable("WeiBingJu_MedicinalAddLog", TableDescription = "药材添加记录")] + [Tenant(SqlSugarConst.DB_DEFAULT)] + [CodeGen] + public class MedicinalAddLog : DataEntityBase + { + /// + /// 药材关联id + /// + [SugarColumn(ColumnDescription = "药材关联id")] + public long MedicinalId { get; set; } + /// + /// 添加重量(g) + /// + [SugarColumn(ColumnDescription = "添加重量(g)")] + public decimal AddWeight { get; set; } + + /// + /// 药材单价 + /// + [SugarColumn(ColumnDescription = "药材单价")] + public decimal UnitPrice { get; set; } + + /// + /// 总价 + /// + [SugarColumn(ColumnDescription = "总价")] + public decimal TotalPrice { get; set; } + + } +} diff --git a/SimpleAdmin.Application/Entity/Person.cs b/SimpleAdmin.Application/Entity/Person.cs new file mode 100644 index 0000000..a98c0e0 --- /dev/null +++ b/SimpleAdmin.Application/Entity/Person.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SimpleAdmin.Application.Entity +{ + [SugarTable("WeiBingJu_Person", TableDescription = "人员表(员工和员工亲戚)")] + [Tenant(SqlSugarConst.DB_DEFAULT)] + [CodeGen] + public class Person : DataEntityBase + { + [SugarColumn(Length = 128, ColumnDescription = "姓名")] + public string Name { get; set; } + + /// + /// 若非空,表示此 person 是某员工的家属 + /// + [SugarColumn(ColumnDescription = "关联员工Id", IsNullable = true)] + public long? EmployeeId { get; set; } + + [SugarColumn(ColumnDescription = "关系配置id", IsNullable = true)] + public long? RelationShip { get; set; } + + [SugarColumn(ColumnDescription = "出生日期", IsNullable = true)] + public string Birthday { get; set; } + + /// 单位 cm,保留两位小数 + [SugarColumn(ColumnDescription = "身高(cm)", IsNullable = true)] + public decimal? Height { get; set; } + } +} diff --git a/SimpleAdmin.Application/Entity/Prescription.cs b/SimpleAdmin.Application/Entity/Prescription.cs new file mode 100644 index 0000000..6e337a7 --- /dev/null +++ b/SimpleAdmin.Application/Entity/Prescription.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SimpleAdmin.Application.Entity +{ + [SugarTable("WeiBingJu_Prescription", TableDescription = "处方管理")] + [Tenant(SqlSugarConst.DB_DEFAULT)] + [CodeGen] + public class Prescription : DataEntityBase + { + [SugarColumn(ColumnDescription = "处方对象 PersonId")] + public long PersonId { get; set; } + + [SugarColumn(ColumnDescription = "诊断结果", ColumnDataType = StaticConfig.CodeFirst_BigString)] + public string DiagnosisResult { get; set; } + + [SugarColumn(ColumnDescription = "用药建议", ColumnDataType = StaticConfig.CodeFirst_BigString)] + public string UserMedicinaAdvice { get; set; } + + [SugarColumn(ColumnDescription = "就诊时间")] + public DateTime? VisitDate { get; set; } + + + /// 单位 kg,保留两位小数 + [SugarColumn(ColumnDescription = "体重(kg)", IsNullable = true)] + public decimal? Weight { get; set; } + } + +} + diff --git a/SimpleAdmin.Application/Entity/PrescriptionHerb.cs b/SimpleAdmin.Application/Entity/PrescriptionHerb.cs new file mode 100644 index 0000000..24ca4b7 --- /dev/null +++ b/SimpleAdmin.Application/Entity/PrescriptionHerb.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SimpleAdmin.Application.Entity +{ + [SugarTable("WeiBingJu_PrescriptionHerb", TableDescription = "处方消耗药材表")] + [Tenant(SqlSugarConst.DB_DEFAULT)] + [CodeGen] + public class PrescriptionHerb : DataEntityBase + { + [SugarColumn(ColumnDescription = "处方Id")] + public long PrescriptionId { get; set; } + + [SugarColumn(ColumnDescription = "药材Id")] + public long MedicinalId { get; set; } + + /// 消耗克数,单位 g + [SugarColumn(ColumnDescription = "消耗(g)")] + public decimal AmountG { get; set; } + + [SugarColumn(Length = 500, IsNullable = true, ColumnDescription = "用量说明/备注")] + public string Note { get; set; } + } +} diff --git a/SimpleAdmin.Application/GlobalUsings.cs b/SimpleAdmin.Application/GlobalUsings.cs new file mode 100644 index 0000000..5f1ff20 --- /dev/null +++ b/SimpleAdmin.Application/GlobalUsings.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +global using MoYu; +global using MoYu.DependencyInjection; +global using MoYu.FriendlyException; +global using Mapster; +global using Microsoft.AspNetCore.Builder; +global using Microsoft.AspNetCore.Hosting; +global using Microsoft.AspNetCore.Mvc; +global using Microsoft.Extensions.DependencyInjection; +global using SimpleAdmin.Cache; +global using SimpleAdmin.Core; +global using SimpleAdmin.Core.Extension; +global using SimpleAdmin.SqlSugar; +global using SimpleAdmin.System; +global using SqlSugar; +global using System.Reflection; +global using SimpleAdmin.Application.Services.Medicinal; +global using SimpleAdmin.Application.Services.Medicinal.Dto; +global using SimpleAdmin.Application.Services.Prescription; +global using SimpleAdmin.Application.Services.Prescription.Dto; diff --git a/SimpleAdmin.Application/Options/ApplicationSettingsOptions.cs b/SimpleAdmin.Application/Options/ApplicationSettingsOptions.cs new file mode 100644 index 0000000..2b64f6b --- /dev/null +++ b/SimpleAdmin.Application/Options/ApplicationSettingsOptions.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using MoYu.ConfigurableOptions; + +namespace SimpleAdmin.Application; + +/// +/// 系统配置 +/// +public class ApplicationSettingsOptions : BaseOptions, IConfigurableOptions +{ +} diff --git a/SimpleAdmin.Application/Services/Medicinal/Dto/MedicinalDto.cs b/SimpleAdmin.Application/Services/Medicinal/Dto/MedicinalDto.cs new file mode 100644 index 0000000..b11e594 --- /dev/null +++ b/SimpleAdmin.Application/Services/Medicinal/Dto/MedicinalDto.cs @@ -0,0 +1,93 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SimpleAdmin.Application.Services.Medicinal.Dto +{ + // 药材列表DTO + public class MedicinalDto + { + public long Id { get; set; } + public string MedicinalName { get; set; } + public decimal Stock { get; set; } + public decimal UsedCost { get; set; } + public decimal RemainingValue { get; set; } + public decimal TotalUsedWeight { get; set; } + } + + // 药材消耗记录DTO + public class MedicinalConsumptionRecordDto + { + public decimal AmountG { get; set; } + public string PersonName { get; set; } + public bool IsRelative { get; set; } + public string EmployeeName { get; set; } + public DateTime? UseTime { get; set; } + } + + // 药材添加记录DTO + public class MedicinalAddLogDto + { + public long Id { get; set; } + public decimal AddWeight { get; set; } + public decimal UnitPrice { get; set; } + public DateTime AddTime { get; set; } + public string AddUserName { get; set; } + public decimal TotalPrice { get; set; } + + public bool CanEdit { get; set; } + } + + // 添加药材输入DTO + public class AddMedicinalInput + { + public long? Id { get; set; } + public decimal AddWeight { get; set; } + public decimal TotalPrice { get; set; } + /// + /// 未找到下拉框的时候传这个值代表添加新的药材 + /// + public string MedicinalName { get; set; } + } + + // 修改药材添加记录输入DTO + public class UpdateMedicinalAddLogInput + { + public long Id { get; set; } + public decimal AddWeight { get; set; } + public decimal TotalPrice { get; set; } + } + + // 药材类型DTO + public class MedicinalTypeDto + { + public long Id { get; set; } + public string Name { get; set; } + } + + // 添加药材类型输入DTO + public class AddMedicinalTypeInput + { + [Required(ErrorMessage = "药材名称不能为空")] + public string Name { get; set; } + } + + public class DeleteMedicinalLog + { + public long Id { get; set; } + } + +} diff --git a/SimpleAdmin.Application/Services/Medicinal/IMedicinalService.cs b/SimpleAdmin.Application/Services/Medicinal/IMedicinalService.cs new file mode 100644 index 0000000..44325fb --- /dev/null +++ b/SimpleAdmin.Application/Services/Medicinal/IMedicinalService.cs @@ -0,0 +1,72 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Text; +using System.Threading.Tasks; + +namespace SimpleAdmin.Application.Services.Medicinal +{ + public interface IMedicinalService : ITransient + { + /// + /// 获取药材列表,带筛选 + /// + /// 药材名称筛选 + /// 页码 + /// 页大小 + /// + Task> GetMedicinalList(string medicinalName, int page, int size); + + /// + /// 获取药材消耗记录 + /// + /// 药材ID + /// + Task> GetConsumptionRecords(long medicinalId, int page, int size); + /// + /// 获取药材下拉 + /// + /// + Task> GetMedicinalDictList(); + + /// + /// 获取药材添加记录 + /// + /// 药材ID + /// + Task> GetAdditionRecords(long medicinalId, int page, int size); + + /// + /// 添加药材 + /// + /// 添加信息 + /// + Task AddMedicinal(AddMedicinalInput input); + + /// + /// 修改药材添加记录(仅当天可修改) + /// + /// 记录ID + /// 修改信息 + /// + Task UpdateAdditionRecord(UpdateMedicinalAddLogInput input); + + /// + /// 删除药材添加记录(仅当天可删除) + /// + /// 记录ID + /// + Task DeleteAdditionRecord(long id); + } +} diff --git a/SimpleAdmin.Application/Services/Medicinal/MedicinalService.cs b/SimpleAdmin.Application/Services/Medicinal/MedicinalService.cs new file mode 100644 index 0000000..acfd831 --- /dev/null +++ b/SimpleAdmin.Application/Services/Medicinal/MedicinalService.cs @@ -0,0 +1,412 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System.Linq.Dynamic.Core; +using SimpleAdmin.Application.Entity; +using Yitter.IdGenerator; + +public class MedicinalService : DbRepository, IMedicinalService +{ + private readonly ISysUserService _sysUserService; + private readonly IDictService _dictService; + public MedicinalService(ISysUserService sysUserService, IDictService dictService) + { + _sysUserService = sysUserService; + _dictService = dictService; + } + public async Task> GetMedicinalList(string medicinalName, int page, int size) + { + // 1. 获取数据范围(原有逻辑不变) + //var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + //dataScope?.Remove(UserManager.OrgId); + + // 2. 分页查询药材基本信息(1次查询,原有逻辑不变) + var query = this.AsQueryable() + //.WhereIF(dataScope.Any(), m => dataScope.Contains(m.Id)) + .WhereIF(!string.IsNullOrEmpty(medicinalName), m => m.MedicinalName.Contains(medicinalName)) + .OrderBy(p => p.Number) + .Select(m => new MedicinalDto + { + Id = m.Id, + MedicinalName = m.MedicinalName, + Stock = m.Number, // 当前库存 + }); + + var pageInfo = await query.ToPagedListAsync(page, size); + if (!pageInfo.List.Any()) return pageInfo; + + // 3. 批量计算:成本、剩余价值、总使用量(仅2次查询,无循环查询) + var medicinalIds = pageInfo.List.Select(dto => dto.Id).ToList(); + var costAndUsageDict = await BatchCalculateCostAndValue(medicinalIds); + + // 4. 内存中赋值所有指标(无数据库查询) + foreach (var item in pageInfo.List) + { + if (costAndUsageDict.TryGetValue(item.Id, out var metrics)) + { + item.UsedCost = metrics.usedCost; // 使用成本 + item.RemainingValue = metrics.remainingValue; // 剩余价值 + item.TotalUsedWeight = metrics.totalUsedWeight; // 新增:总使用量 + } + else + { + // 无数据时默认值 + item.UsedCost = 0; + item.RemainingValue = 0; + item.TotalUsedWeight = 0; + } + } + + return pageInfo; + } + + /// + /// 获取药材下拉 + /// + /// + public async Task> GetMedicinalDictList() + { + ////获取数据范围 + //var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + //dataScope?.Remove(UserManager.OrgId); + //药材查询 + return await this.AsQueryable() + //.WhereIF(dataScope.Any(), m => dataScope.Contains(m.Id)) //机构ID查询 + .OrderBy(p => p.Number) + .Select(m => new MedicinalDto + { + Id = m.Id, + MedicinalName = m.MedicinalName, + Stock = m.Number, + }).ToListAsync(); + } + /// + /// 获取药材消耗记录 + /// + /// + /// + /// + public async Task> GetConsumptionRecords(long medicinalId, int page, int size) + { + return await Context.Queryable() + // 先关联处方 + .LeftJoin((ph, p) => ph.PrescriptionId == p.Id) + // 再关联就诊人 + .LeftJoin((ph, p, pe) => p.PersonId == pe.Id) + // 再关联员工 + .LeftJoin((ph, p, pe, emp) => pe.EmployeeId != null && pe.EmployeeId == emp.Id) + // 条件也使用多参数 + .Where((ph, p, pe, emp) => ph.MedicinalId == medicinalId) + .OrderByDescending((ph, p, pe, emp) => p.VisitDate) + // 投影使用所有表别名 + .Select((ph, p, pe, emp) => new MedicinalConsumptionRecordDto + { + AmountG = ph.AmountG, + PersonName = pe.Name, + IsRelative = pe.EmployeeId != null, + EmployeeName = emp == null ? null : emp.Name, + UseTime = p.VisitDate + }) + // 分页 + .ToPagedListAsync(page, size); + } + + /// + /// 获取药材添加记录 + /// + /// + /// + public async Task> GetAdditionRecords(long medicinalId, int page, int size) + { + var returnList = await Context.Queryable() + .Where(log => log.MedicinalId == medicinalId) + .OrderByDescending(dto => dto.CreateTime) + .Select(log => new MedicinalAddLogDto + { + Id = log.Id, + AddWeight = log.AddWeight, + UnitPrice = log.UnitPrice, + AddTime = log.CreateTime.Value, + AddUserName = log.CreateUser, + TotalPrice = log.TotalPrice, + CanEdit = false + }) + .ToPagedListAsync(page, size); + + foreach (var item in returnList.List) + { + if (item.AddTime.Date == DateTime.Now.Date) + { + item.CanEdit = true; + } + } + return returnList; + } + /// + /// 添加药材 + /// + /// + /// + public async Task AddMedicinal(AddMedicinalInput input) + { + if (input.TotalPrice <= 0 || input.AddWeight <= 0) throw Oops.Bah("请填写正确的金额或者重量!"); + // 开启事务 + await Context.Ado.BeginTranAsync(); + try + { + // 检查药材是否已存在 + var existing = await Context.Queryable() + .Where(m => m.Id == input.Id) + .FirstAsync(); + + if (existing != null) + { + // 更新库存 + existing.Number += input.AddWeight; + await Context.Updateable(existing).ExecuteCommandAsync(); + } + else + { + var medicinalModel = await Context.Queryable() + .Where(m => m.MedicinalName == input.MedicinalName) + .FirstAsync(); + if (medicinalModel != null) throw Oops.Bah("已存在该药材,请在下拉框选择!"); + input.Id = YitIdHelper.NextId(); + // 新增药材记录 + await Context.Insertable(new Medicinal + { + Id = input.Id.Value, + Number = input.AddWeight, + MedicinalName = input.MedicinalName, + }).ExecuteCommandAsync(); + } + decimal unitPrice = 0m; + if (input.AddWeight > 0) + { + unitPrice = Decimal.Round(input.TotalPrice / input.AddWeight, 2, MidpointRounding.AwayFromZero); + } + // 添加记录 + await Context.Insertable(new MedicinalAddLog + { + MedicinalId = input.Id.Value, + AddWeight = input.AddWeight, + UnitPrice = unitPrice, + TotalPrice = input.TotalPrice + }).ExecuteCommandAsync(); + + await Context.Ado.CommitTranAsync(); + } + catch + { + await Context.Ado.RollbackTranAsync(); + throw; + } + return true; + } + /// + /// 修改药材添加记录 + /// + /// + /// + /// + /// + public async Task UpdateAdditionRecord(UpdateMedicinalAddLogInput input) + { + if(input.TotalPrice<=0 || input.AddWeight<=0) throw Oops.Bah("请填写正确的金额或者重量!"); + var log = await Context.Queryable().Where(l => l.Id == input.Id).FirstAsync(); + if (log == null) + { + throw Oops.Bah("记录不存在!"); + } + + // 检查是否是当天记录 + if (log.CreateTime.Value.Date != DateTime.Now.Date) + { + throw Oops.Bah("只能修改当天的记录!"); + } + + // 计算重量变化 + var weightDiff = input.AddWeight - log.AddWeight; + + // 开启事务 + await Context.Ado.BeginTranAsync(); + + try + { + // 更新记录 + log.AddWeight = input.AddWeight; + log.TotalPrice = input.TotalPrice; + log.UnitPrice = Decimal.Round(input.TotalPrice / input.AddWeight, 2, MidpointRounding.AwayFromZero); + await Context.Updateable(log).ExecuteCommandAsync(); + + // 更新药材库存 + var medicinal = await Context.Queryable() + .Where(m => m.Id == log.MedicinalId) + .FirstAsync(); + + if (medicinal != null) + { + medicinal.Number += weightDiff; + if(medicinal.Number<0) throw Oops.Bah("无法修改,库存不足!"); + await Context.Updateable(medicinal).ExecuteCommandAsync(); + } + + await Context.Ado.CommitTranAsync(); + } + catch + { + await Context.Ado.RollbackTranAsync(); + throw; + } + + return true; + } + /// + /// 删除药材添加记录 + /// + /// + /// + /// + public async Task DeleteAdditionRecord(long id) + { + var log = await Context.Queryable().Where(l => l.Id == id).FirstAsync(); + if (log == null) + { + throw Oops.Bah("记录不存在!"); + } + + // 检查是否是当天记录 + if (log.CreateTime.Value.Date != DateTime.Now.Date) + { + throw Oops.Bah("只能删除当天的记录!"); + } + + // 开启事务 + await Context.Ado.BeginTranAsync(); + + try + { + // 删除记录 + log.IsDelete = true; + await Context.Updateable(log).ExecuteCommandAsync(); + + + // 更新药材库存 + var medicinal = await Context.Queryable() + .Where(m => m.Id == log.MedicinalId) + .FirstAsync(); + + if (medicinal != null) + { + medicinal.Number -= log.AddWeight; + if(medicinal.Number<0) throw Oops.Bah("无法删除,库存不足!"); + await Context.Updateable(medicinal).ExecuteCommandAsync(); + } + + await Context.Ado.CommitTranAsync(); + } + catch + { + await Context.Ado.RollbackTranAsync(); + throw; + } + + return true; + } + + /// + /// 批量计算:使用成本、剩余价值、总使用量(先进先出法) + /// + /// 需要计算的药材ID列表 + private async Task> BatchCalculateCostAndValue(List medicinalIds) + { + var result = new Dictionary(); + if (!medicinalIds.Any()) return result; + + // 1. 批量查询所有药材的【当前库存】(1次查询) + var medicinals = await Context.Queryable() + .Where(m => medicinalIds.Contains(m.Id)) + .Select(m => new { m.Id, m.Number }) // Number = 当前库存 + .ToListAsync(); + + // 2. 批量查询所有药材的【入库记录】(1次查询,仅查需要的字段) + var allAddLogs = await Context.Queryable() + .Where(l => medicinalIds.Contains(l.MedicinalId)) + .OrderBy(l => l.CreateTime) // 先进先出:按入库时间排序 + .Select(l => new { + l.MedicinalId, + l.AddWeight, // 入库量 + l.UnitPrice, // 单价(用于计算成本) + l.TotalPrice // 总成本(用于计算成本) + }) + .ToListAsync(); + + // 3. 按【药材ID】分组入库记录(内存处理,无数据库查询) + var groupedLogs = allAddLogs + .GroupBy(l => l.MedicinalId) + .ToDictionary(g => g.Key, g => g.ToList()); + + // 4. 遍历每个药材,内存中计算所有指标 + foreach (var med in medicinals) + { + // 初始化默认值(无入库记录时) + decimal totalIn = 0; // 总入库量(AddWeight 总和) + decimal totalCost = 0; // 总入库成本 + decimal totalUsedWeight = 0; // 总使用量 + decimal usedCost = 0; // 使用成本 + decimal remainingValue = 0;// 剩余价值 + + // 若有入库记录,计算总入库量、总成本 + if (groupedLogs.TryGetValue(med.Id, out var addLogs) && addLogs.Any()) + { + totalIn = addLogs.Sum(l => l.AddWeight); // 总入库量 = 所有 AddWeight 求和 + totalCost = addLogs.Sum(l => l.TotalPrice); // 总入库成本 + } + + // 计算总使用量:总入库量 - 当前库存(若结果为负,说明数据异常,按0处理) + totalUsedWeight = Math.Max(0, totalIn - med.Number); + + // 若有使用量,继续用先进先出法计算使用成本 + if (totalUsedWeight > 0 && groupedLogs.TryGetValue(med.Id, out var validLogs)) + { + decimal remainingToCalculate = totalUsedWeight; + foreach (var log in validLogs) + { + if (remainingToCalculate <= 0) break; + + // 当前入库记录的量 <= 剩余未计算的使用量:全部计入成本 + if (log.AddWeight <= remainingToCalculate) + { + usedCost += log.AddWeight * log.UnitPrice; + remainingToCalculate -= log.AddWeight; + } + // 当前入库记录的量 > 剩余未计算的使用量:仅计算剩余部分 + else + { + usedCost += remainingToCalculate * log.UnitPrice; + remainingToCalculate = 0; + } + } + } + + // 剩余价值 = 总入库成本 - 使用成本(若为负,按0处理) + remainingValue = Math.Max(0, totalCost - usedCost); + + // 存入结果字典 + result[med.Id] = (usedCost, remainingValue, totalUsedWeight); + } + + return result; + } +} diff --git a/SimpleAdmin.Application/Services/Organization/Org/IOrgService.cs b/SimpleAdmin.Application/Services/Organization/Org/IOrgService.cs new file mode 100644 index 0000000..0415f9a --- /dev/null +++ b/SimpleAdmin.Application/Services/Organization/Org/IOrgService.cs @@ -0,0 +1,66 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +/// +/// 机构服务 +/// +public interface IOrgService : ITransient +{ + /// + /// 添加机构 + /// + /// 添加参数 + /// + Task Add(SysOrgAddInput input); + + /// + /// 复制机构 + /// + /// 机构复制参数 + /// + Task Copy(SysOrgCopyInput input); + + /// + /// 删除机构 + /// + /// 删除参数 + /// + Task Delete(BaseIdListInput input); + + /// + /// 编辑机构 + /// + /// 编辑参数 + /// + Task Edit(SysOrgEditInput input); + + /// + /// 机构分页查询 + /// + /// 查询参数 + /// 分页信息 + Task> Page(SysOrgPageInput input); + + /// + /// 机构树结构 + /// + /// 机构选择器 + /// + Task> Tree(SysOrgTreeInput input = null); + + /// + /// 机构详情 + /// + /// + /// + Task Detail(BaseIdInput input); +} diff --git a/SimpleAdmin.Application/Services/Organization/Org/OrgService.cs b/SimpleAdmin.Application/Services/Organization/Org/OrgService.cs new file mode 100644 index 0000000..3425542 --- /dev/null +++ b/SimpleAdmin.Application/Services/Organization/Org/OrgService.cs @@ -0,0 +1,149 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +/// +public class OrgService : DbRepository, IOrgService +{ + private readonly ISysOrgService _sysOrgService; + private readonly ISysUserService _sysUserService; + + public OrgService(ISysOrgService sysOrgService, ISysUserService sysUserService) + { + _sysOrgService = sysOrgService; + _sysUserService = sysUserService; + } + + /// + public async Task> Page(SysOrgPageInput input) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + dataScope?.Remove(UserManager.OrgId); + //构建查询 + var query = Context.Queryable() + .WhereIF(dataScope != null, it => dataScope.Contains(it.Id))//机构ID查询 + .WhereIF(input.ParentId > 0, + it => it.ParentId == input.ParentId || SqlFunc.JsonLike(it.ParentIdList, input.ParentId.ToString()))//父级 + .WhereIF(!string.IsNullOrEmpty(input.Name), it => it.Name.Contains(input.Name))//根据名称查询 + .WhereIF(!string.IsNullOrEmpty(input.Code), it => it.Code.Contains(input.Code))//根据编码查询 + .WhereIF(!string.IsNullOrEmpty(input.Status), it => it.Status == input.Status)//根据状态查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}").OrderBy(it => it.SortCode) + .OrderBy(it => it.CreateTime);//排序 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task> Tree(SysOrgTreeInput input = null) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + //构建机构树 + var result = await _sysOrgService.Tree(dataScope, input); + return result; + } + + /// + public async Task Add(SysOrgAddInput input) + { + await CheckInput(input, SystemConst.ADD);//检查参数 + await _sysOrgService.Add(input, ApplicationConst.BIZ_ORG); + } + + /// + public async Task Edit(SysOrgEditInput input) + { + await CheckInput(input, SystemConst.EDIT);//检查参数 + await _sysOrgService.Edit(input, ApplicationConst.BIZ_ORG); + } + + /// + public async Task Copy(SysOrgCopyInput input) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + if (dataScope == null || dataScope.Count > 0)//如果有机构 + { + if (dataScope is { Count: > 0 } && (!dataScope.ContainsAll(input.Ids) || !dataScope.Contains(input.TargetId)))//判断目标机构和需要复制的机构是否都在数据范围里面 + throw Oops.Bah("您没有权限复制这些机构"); + await _sysOrgService.Copy(input);//复制操作 + } + } + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + //获取要删除的机构列表 + var orgList = (await _sysOrgService.GetListAsync()).Where(it => ids.Contains(it.Id)).ToList(); + if (orgList.Any(it => it.Category == CateGoryConst.ORG_COMPANY))//如果有公司{ + throw Oops.Bah("不能删除根机构"); + //检查数据范围 + var orgIds = orgList.Select(it => it.Id).ToList(); + var createUserIds = orgList.Select(it => it.CreateUserId.GetValueOrDefault()).ToList(); + await _sysUserService.CheckApiDataScope(orgIds, createUserIds, "您没有权限删除这些机构"); + await _sysOrgService.Delete(input, ApplicationConst.BIZ_ORG);//删除操作 + } + + /// + public async Task Detail(BaseIdInput input) + { + var org = await _sysOrgService.GetSysOrgById(input.Id);//获取机构 + var errorMessage = "您没有权限查看该机构"; + //判断数据范围 + await _sysUserService.CheckApiDataScope(org.Id, org.CreateUserId.GetValueOrDefault(), errorMessage); + return org; + } + + #region 方法 + + /// + /// 检查输入参数 + /// + /// 参数 + /// 操作名称 + private async Task CheckInput(SysOrg sysOrg, string operate) + { + sysOrg.Category = CateGoryConst.ORG_DEPT;//设置分类为部门,业务只能操作部门 + if (sysOrg.ParentId == SimpleAdminConst.ZERO) + { + throw Oops.Bah($"不能{operate}根机构"); + } + var errorMessage = $"您没有权限{operate}该机构"; + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + if (dataScope is { Count: > 0 })//如果有机构 + { + if (sysOrg.Id > 0 && !dataScope.Contains(sysOrg.Id))//如果id不为0判断是否在数据范围 + throw Oops.Bah(errorMessage); + if (!dataScope.Contains(sysOrg.ParentId))//判断父ID是否在数据范围 + throw Oops.Bah($"{errorMessage}下的机构"); + } + else if (dataScope is { Count: 0 }) + { + //如果id大于0表示编辑 + if (sysOrg.Id > 0) + { + var org = await _sysOrgService.GetSysOrgById(sysOrg.Id);//获取机构 + if (org.CreateUserId != UserManager.UserId) + throw Oops.Bah(errorMessage);//机构的创建人不是自己则报错 + } + else + { + throw Oops.Bah(errorMessage); + } + } + } + + #endregion 方法 +} diff --git a/SimpleAdmin.Application/Services/Organization/Position/IPositionService.cs b/SimpleAdmin.Application/Services/Organization/Position/IPositionService.cs new file mode 100644 index 0000000..4ffa68d --- /dev/null +++ b/SimpleAdmin.Application/Services/Organization/Position/IPositionService.cs @@ -0,0 +1,66 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +/// +/// 岗位管理 +/// +public interface IPositionService : ITransient +{ + /// + /// 添加岗位 + /// + /// 添加参数 + /// + Task Add(PositionAddInput input); + + /// + /// 删除岗位 + /// + /// id列表 + /// + Task Delete(BaseIdListInput input); + + /// + /// 编辑岗位 + /// + /// 编辑参数 + /// + Task Edit(PositionEditInput input); + + /// + /// 岗位分页查询 + /// + /// 查询参数 + /// 分页列表 + Task> Page(PositionPageInput input); + + /// + /// 岗位选择器 + /// + /// + /// + Task> Selector(PositionSelectorInput input); + + /// + /// 岗位详情 + /// + /// + /// + Task Detail(BaseIdInput input); + + /// + /// 岗位树形结构 + /// + /// + /// + Task> Tree(PositionTreeInput input); +} diff --git a/SimpleAdmin.Application/Services/Organization/Position/PositionService.cs b/SimpleAdmin.Application/Services/Organization/Position/PositionService.cs new file mode 100644 index 0000000..a619a98 --- /dev/null +++ b/SimpleAdmin.Application/Services/Organization/Position/PositionService.cs @@ -0,0 +1,131 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +/// +/// +/// +public class PositionService : DbRepository, IPositionService +{ + private readonly ISysUserService _sysUserService; + private readonly ISysPositionService _sysPositionService; + + public PositionService(ISysUserService sysUserService, ISysPositionService sysPositionService) + { + _sysUserService = sysUserService; + _sysPositionService = sysPositionService; + } + + #region 查询 + + /// + public async Task> Page(PositionPageInput input) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + input.OrgIds = dataScope; + //分页查询 + var pageInfo = await _sysPositionService.Page(input); + return pageInfo; + } + + /// + public async Task> Tree(PositionTreeInput input) + { + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + input.OrgIds = dataScope; + var result = await _sysPositionService.Tree(input); + return result; + } + + #endregion + + #region 新增 + + /// + public async Task Add(PositionAddInput input) + { + await CheckInput(input, SystemConst.ADD);//检查参数 + await _sysPositionService.Add(input, ApplicationConst.BIZ_POS);//添加岗位 + } + + /// + public async Task> Selector(PositionSelectorInput input) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + input.OrgIds = dataScope;//赋值机构列表 + var result = await _sysPositionService.Selector(input);//查询 + return result; + } + + /// + public async Task Detail(BaseIdInput input) + { + var position = await _sysPositionService.GetSysPositionById(input.Id); + //判断数据范围 + await _sysUserService.CheckApiDataScope(position.OrgId, position.CreateUserId.GetValueOrDefault(), "您没有权限查看该机构"); + return position; + } + + #endregion + + #region 编辑 + + /// + public async Task Edit(PositionEditInput input) + { + await CheckInput(input, SystemConst.EDIT);//检查参数 + await _sysPositionService.Edit(input, ApplicationConst.BIZ_POS);//编辑 + } + + #endregion + + + #region 删除 + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + //获取要删除的岗位列表 + var positions = (await _sysPositionService.GetListAsync()).Where(it => ids.Contains(it.Id)).ToList(); + //检查数据范围 + var orgIds = positions.Select(it => it.OrgId).ToList(); + var createUserIds = positions.Select(it => it.CreateUserId.GetValueOrDefault()).ToList(); + await _sysUserService.CheckApiDataScope(orgIds, createUserIds, "您没有权限删除该机构"); + await _sysPositionService.Delete(input, ApplicationConst.BIZ_ORG);//删除岗位 + } + + #endregion + + #region 方法 + + /// + /// 检查输入参数 + /// + /// 参数 + /// 操作名称 + private async Task CheckInput(SysPosition sysPosition, string operate) + { + var errorMessage = $"您没有权限在该机构下{operate}岗位"; + //如果id大于0表示编辑 + if (sysPosition.Id > 0) + { + var position = await _sysPositionService.GetSysPositionById(sysPosition.Id);//获取机构 + sysPosition.CreateUserId = position.CreateUserId; + } + await _sysUserService.CheckApiDataScope(sysPosition.OrgId, sysPosition.CreateUserId.GetValueOrDefault(), errorMessage); + } + + #endregion 方法 +} diff --git a/SimpleAdmin.Application/Services/Organization/Role/IRoleService.cs b/SimpleAdmin.Application/Services/Organization/Role/IRoleService.cs new file mode 100644 index 0000000..39bd737 --- /dev/null +++ b/SimpleAdmin.Application/Services/Organization/Role/IRoleService.cs @@ -0,0 +1,115 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +public interface IRoleService : ITransient +{ + #region 查询 + + /// + /// 角色拥有资源 + /// + /// 角色id + /// 资源类型 + /// 角色拥有资源信息 + Task OwnResource(BaseIdInput input, string category); + + /// + /// 获取角色下的用户 + /// + /// 角色ID + /// + Task> OwnUser(BaseIdInput input); + + /// + /// 分页查询角色 + /// + /// 查询参数 + /// + Task> Page(RolePageInput input); + + /// + /// 角色选择器 + /// + /// + /// + Task> RoleSelector(RoleSelectorInput input); + + /// + /// 获取角色树 + /// + /// 角色树 + /// + Task> Tree(RoleTreeInput input); + + /// + /// 角色详情 + /// + /// 角色Id + /// + Task Detail(BaseIdInput input); + + /// + /// 资源树选择器 + /// + /// + Task> ResourceTreeSelector(); + + #endregion + + #region 新增 + + /// + /// 添加角色 + /// + /// 添加参数 + /// + Task Add(RoleAddInput input); + + #endregion + + #region 编辑 + + /// + /// 编辑角色 + /// + /// 编辑参数 + /// + Task Edit(RoleEditInput input); + + + /// + /// 给角色授权 + /// + /// 授权参数 + /// + Task GrantResource(GrantResourceInput input); + + /// + /// 给角色授权用户 + /// + /// 授权信息 + /// + Task GrantUser(GrantUserInput input); + + #endregion + + #region 删除 + + /// + /// 删除角色 + /// + /// 删除参数 + /// + Task Delete(BaseIdListInput input); + + #endregion +} diff --git a/SimpleAdmin.Application/Services/Organization/Role/RoleService.cs b/SimpleAdmin.Application/Services/Organization/Role/RoleService.cs new file mode 100644 index 0000000..9ddeb97 --- /dev/null +++ b/SimpleAdmin.Application/Services/Organization/Role/RoleService.cs @@ -0,0 +1,286 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using Microsoft.Extensions.Logging; +using NewLife.Serialization; + +namespace SimpleAdmin.Application; + +/// +public class RoleService : IRoleService +{ + private readonly ILogger _logger; + private readonly ISysUserService _sysUserService; + private readonly ISysRoleService _sysRoleService; + private readonly IResourceService _resourceService; + private readonly IRelationService _relationService; + + public RoleService(ILogger logger, ISysUserService sysUserService, ISysRoleService sysRoleService, + IResourceService resourceService, IRelationService relationService) + { + _logger = logger; + _sysUserService = sysUserService; + _sysRoleService = sysRoleService; + _resourceService = resourceService; + _relationService = relationService; + } + + #region 查询 + + /// + public async Task OwnResource(BaseIdInput input, string category) + { + return await _sysRoleService.OwnResource(input, category); + } + + /// + public async Task> OwnUser(BaseIdInput input) + { + return await _sysRoleService.OwnUser(input); + } + + /// + public async Task> Page(RolePageInput input) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + input.OrgIds = dataScope; + input.Category = CateGoryConst.ROLE_ORG;//只查询机构角色 + //分页查询 + var pageInfo = await _sysRoleService.Page(input); + return pageInfo; + } + + + /// + public async Task> RoleSelector(RoleSelectorInput input) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + input.OrgIds = dataScope; + return await _sysRoleService.RoleSelector(input); + } + + /// + public async Task> Tree(RoleTreeInput input) + { + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + input.OrgIds = dataScope; + return await _sysRoleService.Tree(input); + } + + /// + public async Task Detail(BaseIdInput input) + { + var role = await _sysRoleService.Detail(input); + var errorMessage = "您没有权限查看该角色"; + await _sysUserService.CheckApiDataScope(role.OrgId, role.CreateUserId, errorMessage); + return role; + } + + /// + public async Task> ResourceTreeSelector() + { + var resourceTreeSelectors = new List();//定义结果 + var user = await _sysUserService.GetUserById(UserManager.UserId);//获取用户 + //获取角色资源关系 + var relations = + await _relationService.GetRelationListByObjectIdListAndCategory(user.RoleIdList, CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE); + var menuIds = new HashSet();//菜单ID集合 + var buttonIds = new HashSet();//按钮ID集合 + relations.ForEach(it => + { + var resources = it.ExtJson.ToJsonEntity();//转换为对象获取资源 + menuIds.Add(resources.MenuId);//添加菜单ID + resources.ButtonInfo.ForEach(b => buttonIds.Add(b));//添加按钮ID + }); + var menuList = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MENU);//获取所有菜单 + var buttonList = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_BUTTON);//获取所有按钮 + var moduleList = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MODULE);//获取所有模块 + var ownMenuList = menuList.Where(it => menuIds.Contains(it.Id)).ToList();//已拥有的菜单 + var parentMenuList = menuList.Where(it => ownMenuList.Select(m => m.ParentId).Contains(it.Id)).ToList();//获取所有父级菜单 + ownMenuList.AddRange(parentMenuList);//将父级菜单加入到拥有菜单列表 + var ownButtonList = buttonList.Where(it => buttonIds.Contains(it.Id)).ToList();//已拥有的按钮 + var moduleIds = ownMenuList.Select(it => it.Module.GetValueOrDefault()).Distinct().ToList();//模块ID集合 + var ownModuleList = moduleList.Where(it => moduleIds.Contains(it.Id)).ToList();//已拥有的模块 + //遍历模块 + foreach (var module in ownModuleList) + { + //将实体转换为ResourceTreeSelectorOutPut获取基本信息 + var resourceTreeSelector = module.Adapt(); + resourceTreeSelector.Menu = await GetRoleGrantResourceMenus(module.Id, ownMenuList, ownButtonList);//获取授权菜单 + resourceTreeSelectors.Add(resourceTreeSelector); + } + return resourceTreeSelectors; + } + + #endregion + + #region 增加 + + /// + public async Task Add(RoleAddInput input) + { + await CheckInput(input);//检查参数 + await _sysRoleService.Add(input); + } + + #endregion + + #region 编辑 + + /// + public async Task Edit(RoleEditInput input) + { + await CheckInput(input);//检查参数 + await _sysRoleService.Edit(input); + } + + /// + public async Task GrantResource(GrantResourceInput input) + { + await _sysRoleService.GrantResource(input); + } + + /// + public async Task GrantUser(GrantUserInput input) + { + await _sysRoleService.GrantUser(input); + } + + #endregion + + #region 删除 + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + //获取要删除的机构列表 + var roleList = (await _sysRoleService.GetListAsync()).Where(it => ids.Contains(it.Id)).ToList(); + if (roleList.Any(it => it.Category == CateGoryConst.ROLE_GLOBAL))//如果有全局角色 + throw Oops.Bah("不能删除全局角色"); + //检查数据范围 + var orgIds = roleList.Select(it => it.OrgId.GetValueOrDefault()).ToList(); + var createUserIds = roleList.Select(it => it.CreateUserId.GetValueOrDefault()).ToList(); + await _sysUserService.CheckApiDataScope(orgIds, createUserIds, "您没有权限删除这些角色"); + await _sysRoleService.Delete(input); + } + + #endregion + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(SysRole sysRole) + { + sysRole.Category = CateGoryConst.ROLE_ORG; + if (sysRole.DefaultDataScope.ScopeCategory == CateGoryConst.SCOPE_ALL) + throw Oops.Bah("不能添加全局数据范围的角色"); + await _sysUserService.CheckApiDataScope(sysRole.OrgId, sysRole.CreateUserId.GetValueOrDefault(), "您没有权限添加该角色"); + } + + /// + /// 获取授权菜单 + /// + /// 模块Id + /// 拥有菜单列表 + /// 拥有权限按钮列表 + /// + public async Task> GetRoleGrantResourceMenus(long moduleId, List ownMenuList, + List ownButtonList) + { + var roleGrantResourceMenus = new List();//定义结果 + var parentMenuList = ownMenuList.Where(it => it.ParentId == SimpleAdminConst.ZERO).ToList();//获取一级目录 + //遍历一级目录 + foreach (var parent in parentMenuList) + { + //如果是目录则去遍历下级 + if (parent.MenuType == SysResourceConst.CATALOG) + { + //获取所有下级菜单 + var menuList = _resourceService.GetChildListById(ownMenuList, parent.Id, false); + if (menuList.Count > 0)//如果有菜单 + { + //遍历下级菜单 + foreach (var menu in menuList) + { + //如果菜单类型是菜单 + if (menu.MenuType is SysResourceConst.MENU or SysResourceConst.SUBSET) + { + //获取菜单下按钮集合并转换成对应实体 + var buttonList = ownButtonList.Where(it => it.ParentId == menu.Id).ToList(); + var buttons = buttonList.Adapt>(); + roleGrantResourceMenus.Add(new ResTreeSelector.RoleGrantResourceMenu + { + Id = menu.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId, + Title = _resourceService.GetRoleGrantResourceMenuTitle(menuList, menu),//菜单名称需要特殊处理因为有二级菜单 + Button = buttons + }); + } + else if (menu.MenuType == SysResourceConst.LINK || menu.MenuType == SysResourceConst.IFRAME)//如果是内链或者外链 + { + //直接加到资源列表 + roleGrantResourceMenus.Add(new ResTreeSelector.RoleGrantResourceMenu + { + Id = menu.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId, + Title = menu.Title + }); + } + } + } + else + { + //否则就将自己加到一级目录里面 + roleGrantResourceMenus.Add(new ResTreeSelector.RoleGrantResourceMenu + { + Id = parent.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId + }); + } + } + else + { + //就将自己加到一级目录里面 + var roleGrantResourcesButtons = new ResTreeSelector.RoleGrantResourceMenu + { + Id = parent.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId, + Title = parent.Title + }; + //如果菜单类型是菜单 + if (parent.MenuType == SysResourceConst.MENU) + { + //获取菜单下按钮集合并转换成对应实体 + var buttonList = ownButtonList.Where(it => it.ParentId == parent.Id).ToList(); + roleGrantResourcesButtons.Button = buttonList.Adapt>(); + } + roleGrantResourceMenus.Add(roleGrantResourcesButtons); + } + } + return roleGrantResourceMenus; + } + + #endregion +} diff --git a/SimpleAdmin.Application/Services/Organization/User/Dto/UserInput.cs b/SimpleAdmin.Application/Services/Organization/User/Dto/UserInput.cs new file mode 100644 index 0000000..d3dd86e --- /dev/null +++ b/SimpleAdmin.Application/Services/Organization/User/Dto/UserInput.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +/// +/// 业务用户导入 +/// +public class BizUserImportInput : SysUserImportInput +{ +} diff --git a/SimpleAdmin.Application/Services/Organization/User/Dto/UserOutput.cs b/SimpleAdmin.Application/Services/Organization/User/Dto/UserOutput.cs new file mode 100644 index 0000000..81562dd --- /dev/null +++ b/SimpleAdmin.Application/Services/Organization/User/Dto/UserOutput.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +/// +/// 业务用户导出 +/// +public class BizUserExportOutput : SysUserExportOutput +{ +} diff --git a/SimpleAdmin.Application/Services/Organization/User/IUserService.cs b/SimpleAdmin.Application/Services/Organization/User/IUserService.cs new file mode 100644 index 0000000..57b11e6 --- /dev/null +++ b/SimpleAdmin.Application/Services/Organization/User/IUserService.cs @@ -0,0 +1,155 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +/// +/// 人员管理服务 +/// +public interface IUserService : ITransient +{ + #region 查询 + + /// + /// 人员选择器 + /// + /// 查询参数 + /// 人员列表 + Task> Selector(UserSelectorInput input); + + /// + /// 用户分页查询 + /// + /// 查询参数 + /// 用户分页列表 + Task> Page(UserPageInput input); + + /// + /// 获取用户拥有角色 + /// + /// 用户ID + /// + Task> OwnRole(BaseIdInput input); + + /// + /// 角色选择器 + /// + /// + /// + Task> RoleSelector(RoleSelectorInput input); + + /// + /// 人员详情 + /// + /// + /// + Task Detail(BaseIdInput input); + + #endregion 查询 + + #region 添加 + + /// + /// 添加用户 + /// + /// 添加参数 + /// + Task Add(UserAddInput input); + + #endregion 添加 + + #region 编辑 + + /// + /// 编辑 + /// + /// 编辑参数 + /// + Task Edit(UserEditInput input); + + /// + /// 禁用用户 + /// + /// 用户Id + /// + Task DisableUser(BaseIdInput input); + + /// + /// 启用用户 + /// + /// 用户Id + /// + Task EnableUser(BaseIdInput input); + + /// + /// 重置密码 + /// + /// 用户Id + /// + Task ResetPassword(BaseIdInput input); + + /// + /// 给用户授权角色 + /// + /// 授权参数 + /// + Task GrantRole(UserGrantRoleInput input); + + #endregion 编辑 + + #region 删除 + + /// + /// 删除用户 + /// + /// Id列表 + /// + Task Delete(BaseIdListInput input); + + #endregion 删除 + + #region 导入导出 + + /// + /// 导入预览 + /// + /// 导入参数 + /// + Task Preview(ImportPreviewInput input); + + /// + /// 获取导入模板 + /// + /// + Task Template(); + + /// + /// 导出 + /// + /// 查询参数 + /// + Task Export(UserPageInput input); + + /// + /// 导入数据 + /// + /// 数据 + /// 导入结果 + Task> Import(ImportResultInput input); + + /// + /// 批量编辑 + /// + /// 编辑字段信息 + /// + Task Edits(BatchEditInput input); + + #endregion 导入导出 +} diff --git a/SimpleAdmin.Application/Services/Organization/User/UserService.cs b/SimpleAdmin.Application/Services/Organization/User/UserService.cs new file mode 100644 index 0000000..7ca05da --- /dev/null +++ b/SimpleAdmin.Application/Services/Organization/User/UserService.cs @@ -0,0 +1,332 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +/// +/// +/// +public class UserService : DbRepository, IUserService +{ + private readonly ISysUserService _sysUserService; + private readonly ISysRoleService _sysRoleService; + private readonly IImportExportService _importExportService; + + public UserService(ISysUserService sysUserService, ISysRoleService sysRoleService, IImportExportService importExportService) + { + _sysUserService = sysUserService; + _sysRoleService = sysRoleService; + _importExportService = importExportService; + } + + #region 查询 + + /// + public async Task> Page(UserPageInput input) + { + var query = await GetQuery(input); + //分页查询 + var pageInfo = await _sysUserService.Page(query); + return pageInfo; + } + + /// + public async Task> OwnRole(BaseIdInput input) + { + return await _sysUserService.OwnRole(input);//获取角色 + } + + /// + public async Task> Selector(UserSelectorInput input) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + if (dataScope == null) + return await _sysUserService.Selector(input);//查询 + if (dataScope.Count > 0) + { + input.OrgIds = dataScope;//赋值机构列表 + return await _sysUserService.Selector(input);//查询 + } + //返回自己 + return new SqlSugarPagedList + { + Total = 1, + Pages = 1, + HasPrevPages = false, + HasNextPages = false, + List = new[] + { + new UserSelectorOutPut + { + Account = UserManager.UserAccount, Id = UserManager.UserId, + Name = UserManager.Name, OrgId = UserManager.OrgId + } + } + }; + } + + /// + public async Task> RoleSelector(RoleSelectorInput input) + { + var sysRoles = new SqlSugarPagedList + { + Total = 1, + Pages = 1, + HasPrevPages = false, + HasNextPages = false, + List = new List() + }; + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + if (dataScope == null) + sysRoles = await _sysRoleService.RoleSelector(input);//获取角色选择器列表 + else if (dataScope.Count > 0)//如果有机构 + { + input.OrgIds = dataScope;//将数据范传进去 + sysRoles = await _sysRoleService.RoleSelector(input);//获取角色选择器列表 + } + return sysRoles; + } + + /// + public async Task Detail(BaseIdInput input) + { + var user = await _sysUserService.Detail(input); + var errorMessage = "您没有权限查看该人员"; + //判断数据范围 + await _sysUserService.CheckApiDataScope(user.OrgId, user.CreateUserId, errorMessage); + return user; + } + + #endregion 查询 + + #region 新增 + + /// + public async Task Add(UserAddInput input) + { + await CheckInput(input, SystemConst.ADD);//检查参数 + await _sysUserService.Add(input);//添加 + } + + #endregion 新增 + + #region 编辑 + + /// + public async Task Edit(UserEditInput input) + { + await CheckInput(input, SystemConst.EDIT);//检查参数 + await _sysUserService.Edit(input);//编辑 + } + + /// + public async Task Edits(BatchEditInput input) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + var ids = input.Ids; + var sysUsers = await GetListAsync(it => ids.Contains(it.Id), + it => new SysUser { OrgId = it.OrgId, CreateUserId = it.CreateUserId });//根据用户ID获取机构id、 + sysUsers.ForEach(it => + { + if (dataScope != null && !dataScope.Contains(it.OrgId) && it.CreateUserId != UserManager.UserId) + throw Oops.Bah(ErrorCodeEnum.A0004);//如果不包含机构id并且不是自己创建的 + }); + await _sysUserService.Edits(input); + } + + /// + public async Task DisableUser(BaseIdInput input) + { + await CheckInput(input.Id, SystemConst.DISABLE);//检查权限 + await _sysUserService.DisableUser(input);//禁用 + } + + /// + public async Task EnableUser(BaseIdInput input) + { + await CheckInput(input.Id, SystemConst.ENABLE);//检查权限 + await _sysUserService.EnableUser(input);//启用 + } + + /// + public async Task GrantRole(UserGrantRoleInput input) + { + await CheckInput(input.Id, SystemConst.DISABLE);//检查权限 + await _sysUserService.GrantRole(input);//授权 + } + + /// + public async Task ResetPassword(BaseIdInput input) + { + await CheckInput(input.Id, SystemConst.RESET_PWD);//检查权限 + await _sysUserService.ResetPassword(input);//重置密码 + } + + #endregion 编辑 + + #region 删除 + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + + //获取用户下信息 + var users = await GetListAsync(it => ids.Contains(it.Id), it => new SysUser { OrgId = it.OrgId, Id = it.Id }); + //检查数据范围 + var orgIds = users.Select(it => it.OrgId).ToList(); + var createUserIds = users.Select(it => it.CreateUserId.GetValueOrDefault()).ToList(); + await _sysUserService.CheckApiDataScope(orgIds, createUserIds, "您没有权限删除这些人员"); + await _sysUserService.Delete(input);//删除 + } + + #endregion 删除 + + #region 导入导出 + + /// + public async Task Template() + { + var templateName = "人员信息.xlsx"; + //var result = _importExportService.GenerateLocalTemplate(templateName); + var result = await _importExportService.GenerateTemplate(templateName); + return result; + } + + /// + public async Task Preview(ImportPreviewInput input) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + if (dataScope == null || dataScope.Count > 0) + { + var importPreview = await _importExportService.GetImportPreview(input.File); + importPreview.Data = await CheckImport(importPreview.Data, dataScope);//检查导入数据 + return importPreview; + } + throw Oops.Bah("您无权导入用户"); + } + + /// + public async Task Export(UserPageInput input) + { + var query = await GetQuery(input); + var users = await _sysUserService.List(query); + var data = users.Adapt>();//转为Dto + var result = await _importExportService.Export(data, "人员信息"); + return result; + } + + /// + public async Task> Import(ImportResultInput input) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + if (dataScope.Count > 0) + { + var data = await CheckImport(input.Data, dataScope, true);//检查数据格式 + var result = _importExportService.GetImportResultPreview(data, out var importData); + var sysUsers = importData.Adapt>();//转实体 + await _sysUserService.SetUserDefault(sysUsers);//设置用户默认值 + await InsertOrBulkCopy(sysUsers);// 数据导入 + return result; + } + throw Oops.Bah("您无权导入用户"); + } + + #endregion 导入导出 + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + /// 操作类型 + private async Task CheckInput(SysUser sysUser, string operate) + { + var errorMessage = $"您没有权限{operate}该机构下的人员"; + if (sysUser.Id != SimpleAdminConst.ZERO) + { + var user = await _sysUserService.GetUserById(sysUser.Id); + sysUser.CreateUserId = user.CreateUserId; + } + //检查数据范围 + await _sysUserService.CheckApiDataScope(sysUser.OrgId, sysUser.CreateUserId.GetValueOrDefault(), errorMessage); + } + + /// + /// 检查输入参数 + /// + /// 用户ID + /// 操作 + private async Task CheckInput(long userId, string operate) + { + var errorMessage = $"您没有权限{operate}该机构下的人员"; + var sysUser = await _sysUserService.GetUserById(userId); + //检查数据范围 + await _sysUserService.CheckApiDataScope(sysUser.OrgId, sysUser.CreateUserId.GetValueOrDefault(), errorMessage); + } + + /// + /// 检查导入数据 + /// + /// 数据 + /// 数据范围ID数组 + /// 是否初始化错误 + /// + public async Task> CheckImport(List data, List dataScope, bool clearError = false) + { + var errorMessage = "没有权限"; + //先经过系统用户检查 + var bizUsers = await _sysUserService.CheckImport(data, clearError); + bizUsers.ForEach(it => + { + //如果机构没有错误 + if (!it.ErrorInfo.ContainsKey(nameof(it.OrgName))) + { + //判断是否包含数据范围,如果不包含 + if (dataScope != null && !dataScope.Contains(it.OrgId)) + { + it.ErrorInfo.Add(nameof(it.OrgName), errorMessage); + if (!it.ErrorInfo.ContainsKey(nameof(it.PositionName)))//如果机构没错 + it.ErrorInfo.Add(nameof(it.PositionName), errorMessage); + } + } + if (it.ErrorInfo.Count > 0) it.HasError = true;//如果错误信息数量大于0则表示有错误 + }); + bizUsers = bizUsers.OrderByDescending(it => it.HasError).ToList();//排序 + return bizUsers; + } + + /// + /// 获取查询条件 + /// + /// + /// + public async Task GetQuery(UserPageInput input) + { + //获取数据范围 + var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + //动态查询条件 + var exp = Expressionable.Create(); + exp.And(u => u.Account != SysRoleConst.SUPER_ADMIN); + exp.AndIF(dataScope is { Count: > 0 }, u => dataScope.Contains(u.OrgId));//用户机构在数据范围内 + exp.AndIF(dataScope is { Count: 0 }, u => u.Id == UserManager.UserId);//用户ID等于自己 + input.Expression = exp; + return input; + } + + #endregion 方法 +} diff --git a/SimpleAdmin.Application/Services/Prescription/Dto/PrescriptionDtos.cs b/SimpleAdmin.Application/Services/Prescription/Dto/PrescriptionDtos.cs new file mode 100644 index 0000000..fee9868 --- /dev/null +++ b/SimpleAdmin.Application/Services/Prescription/Dto/PrescriptionDtos.cs @@ -0,0 +1,162 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SimpleAdmin.Application.Services.Prescription.Dto +{ + // 人员类型枚举 + public enum PersonType + { + [Description("员工")] + Employee = 1, + [Description("家属")] + Relative = 2 + } + + // 处方列表DTO + public class PrescriptionDto + { + public long Id { get; set; } + public long PersonId { get; set; } + public string PersonName { get; set; } + public PersonType PersonType { get; set; } + /// + /// 关联的员工名称 + /// + public string EmployeeName { get; set; } + public DateTime? VisitDate { get; set; } + public bool CanEdit { get; set; } + + public DateTime CreateTime { get; set; } + + public decimal TotalMedicineCost { get; set; } + + } + // 辅助类:存储FIFO计算所需的入库记录信息 + public class MedicinalFifoRecord + { + public long MedicinalId { get; set; } + public decimal AddWeight { get; set; } + public decimal UnitPrice { get; set; } + } + // 处方查询输入DTO + public class PrescriptionQueryInput: BasePageInput + { + public DateTime? VisitDate { get; set; } + public long? MedicinalId { get; set; } + public PersonType? PersonType { get; set; } + public long? EmployeeId { get; set; } + + public string PersonName { get; set; } + } + + // 处方详情DTO + public class PrescriptionDetailDto + { + public long Id { get; set; } + public PersonDetailDto Person { get; set; } + public string DiagnosisResult { get; set; } + public string UserMedicinaAdvice { get; set; } + public DateTime? VisitDate { get; set; } + public List Herbs { get; set; } + public bool CanEdit { get; set; } + } + + // 人员详情DTO + public class PersonDetailDto + { + public long? Id { get; set; } + public string Name { get; set; } + public string Birthday { get; set; } + public decimal? Weight { get; set; } + public decimal? Height { get; set; } + public bool IsEmployee { get; set; } + public long? EmployeeId { get; set; } + public string EmployeeName { get; set; } + public long? RelationShip { get; set; } + public string RelationShipName { get; set; } + } + + // 处方药材DTO + public class PrescriptionHerbDto + { + public long MedicinalId { get; set; } + public string MedicinalName { get; set; } + public decimal AmountG { get; set; } + public string Note { get; set; } + } + + // DTOs(替换/合并到你的 DTO 定义处) + public class SavePrescriptionInput + { + public long? Id { get; set; } + public PersonInputDto Person { get; set; } + public string DiagnosisResult { get; set; } + public string UserMedicinaAdvice { get; set; } + public DateTime? VisitDate { get; set; } + public List Herbs { get; set; } + } + + // 人员输入 DTO(新增字段以支持前端发送临时员工信息) + public class PersonInputDto + { + public long? Id { get; set; } // 可能的已存在人员ID + public string TempId { get; set; } // 可选:前端临时 id(兼容旧流程) + public string Name { get; set; } + public string Birthday { get; set; } + public decimal? Weight { get; set; } + public decimal? Height { get; set; } + public bool IsEmployee { get; set; } + public long? RelationShip { get; set; } // 亲属关系 id(若为家属) + public long? EmployeeId { get; set; } // 关联员工 id(如果是家属) + /// + /// 当前关联的员工是否是前端临时新增(需要后端创建) + /// + public bool EmployeeIsTemp { get; set; } + /// + /// 当 EmployeeIsTemp 为 true 或者前端直接传了员工名字时,后端可用此字段创建员工 + /// + public string EmployeeName { get; set; } + } + // 处方药材输入DTO + public class PrescriptionHerbInputDto + { + public long Id { get; set; } + public decimal AmountG { get; set; } + public string Note { get; set; } + } + + // 人员DTO + public class PersonDto + { + public long Id { get; set; } + public string Name { get; set; } + public string Birthday { get; set; } + + public decimal? Height { get; set; } + + public long? RelationShip { get; set; } + } + + // 关系类型DTO + public class RelationTypeDto + { + public long Id { get; set; } + public string Name { get; set; } + } + +} diff --git a/SimpleAdmin.Application/Services/Prescription/IPrescriptionService.cs b/SimpleAdmin.Application/Services/Prescription/IPrescriptionService.cs new file mode 100644 index 0000000..2191722 --- /dev/null +++ b/SimpleAdmin.Application/Services/Prescription/IPrescriptionService.cs @@ -0,0 +1,58 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Text; +using System.Threading.Tasks; + +namespace SimpleAdmin.Application.Services.Prescription +{ + public interface IPrescriptionService : ITransient + { + /// + /// 获取处方列表,带筛选 + /// + /// 筛选条件 + /// + Task> GetPrescriptionList(PrescriptionQueryInput input); + + /// + /// 获取处方详情 + /// + /// 处方ID + /// + Task GetPrescriptionDetail(long id); + + /// + /// 保存处方(新增或编辑) + /// + /// 处方信息 + /// + Task SavePrescription(SavePrescriptionInput input); + + /// + /// 获取人员列表(员工和家属) + /// + /// 人员类型 + /// 员工ID(用于获取家属) + /// + Task> GetPersonList(PersonType? type, long? employeeId); + + + /// + /// 获取所有关系类型(写死在代码中) + /// + /// + Task> GetRelationTypes(); + } +} diff --git a/SimpleAdmin.Application/Services/Prescription/PrescriptionService.cs b/SimpleAdmin.Application/Services/Prescription/PrescriptionService.cs new file mode 100644 index 0000000..310771a --- /dev/null +++ b/SimpleAdmin.Application/Services/Prescription/PrescriptionService.cs @@ -0,0 +1,551 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + + +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using SimpleAdmin.Application.Entity; +using SimpleAdmin.Application.Services.Prescription; +using Yitter.IdGenerator; + +public class PrescriptionService : DbRepository, IPrescriptionService +{ + public async Task> GetPrescriptionList(PrescriptionQueryInput input) + { + // 原有查询逻辑保持不变 + var query = Context.Queryable() + .LeftJoin((p, pe) => p.PersonId == pe.Id) + .LeftJoin((p, pe, emp) => pe.EmployeeId != null && pe.EmployeeId == emp.Id) + .WhereIF(!string.IsNullOrEmpty(input.PersonName), (p, pe, emp) => + input.PersonName.Contains(pe.Name) || pe.Name.Contains(input.PersonName) || + input.PersonName.Contains(emp.Name) || emp.Name.Contains(input.PersonName)) + .WhereIF(input.PersonType.HasValue && input.PersonType == PersonType.Employee, (p, pe) => + pe.EmployeeId == null) + .WhereIF(input.PersonType.HasValue && input.PersonType != PersonType.Employee, (p, pe) => + pe.EmployeeId != null); + + try + { + // 获取处方基础信息(添加总成本属性) + var prescriptionPage = await query.OrderByDescending((p, pe, emp) => p.CreateTime) + .Select((p, pe, emp) => new PrescriptionDto + { + Id = p.Id, + PersonId = p.PersonId, + PersonName = pe.Name, + PersonType = pe.EmployeeId != null ? PersonType.Relative : PersonType.Employee, + VisitDate = p.VisitDate, + CreateTime = p.CreateTime.Value, + EmployeeName = emp.Name, + CanEdit = false, + TotalMedicineCost = 0 // 初始化总成本 + }).ToPagedListAsync(input.PageNum, input.PageSize); + + // 设置可编辑状态 + foreach (var item in prescriptionPage.List) + { + item.CanEdit = item.CreateTime.Date == DateTime.Now.Date; + } + + // 获取当前页所有处方的药材明细 + var pidList = prescriptionPage.List.Select(a => a.Id).ToList(); + var prescriptionHerbList = await Context.Queryable() + .Where(a => pidList.Contains(a.PrescriptionId)) + .ToListAsync(); + + if (prescriptionHerbList.Any()) + { + // 1. 按【处方ID+药材ID】分组,统计每个处方中每种药材的总使用量 + var prescriptionMedicinalUsage = prescriptionHerbList + .GroupBy(h => new { h.PrescriptionId, h.MedicinalId }) + .Select(g => new + { + PrescriptionId = g.Key.PrescriptionId, + MedicinalId = g.Key.MedicinalId, + TotalUsedWeight = g.Sum(h => h.AmountG) // 同一处方中同一药材的总用量 + }) + .ToList(); + + // 2. 收集所有涉及的药材ID,批量获取FIFO计算所需数据 + var medicinalIds = prescriptionMedicinalUsage.Select(u => u.MedicinalId).Distinct().ToList(); + var fifoData = await GetMedicinalFifoData(medicinalIds); + + // 3. 按处方ID分组,计算每个处方的总成本 + var groupedByPrescription = prescriptionMedicinalUsage + .GroupBy(u => u.PrescriptionId) + .ToDictionary(g => g.Key, g => g.ToList()); + + // 4. 遍历处方,计算总成本 + foreach (var prescription in prescriptionPage.List) + { + if (groupedByPrescription.TryGetValue(prescription.Id, out var usages)) + { + foreach (var usage in usages) + { + // 基于FIFO计算当前药材的使用成本 + var herbCost = CalculateHerbCostByFifo( + fifoData, + usage.MedicinalId, + usage.TotalUsedWeight + ); + + // 累加到处方总成本 + prescription.TotalMedicineCost += herbCost; + } + } + } + } + + return prescriptionPage; + } + catch (Exception ex) + { + Console.WriteLine($"错误: {ex.Message}"); + throw; + } + } + + /// + /// 获取药材FIFO计算所需的基础数据(入库记录) + /// + private async Task>> GetMedicinalFifoData(List medicinalIds) + { + if (!medicinalIds.Any()) + return new Dictionary>(); + + // 批量查询所有涉及药材的入库记录(按时间排序) + var addLogs = await Context.Queryable() + .Where(l => medicinalIds.Contains(l.MedicinalId)) + .OrderBy(l => l.CreateTime) // FIFO核心:按入库时间排序 + .Select(l => new MedicinalFifoRecord + { + MedicinalId = l.MedicinalId, + AddWeight = l.AddWeight, + UnitPrice = l.UnitPrice + }) + .ToListAsync(); + + // 按药材ID分组 + return addLogs.GroupBy(l => l.MedicinalId) + .ToDictionary(g => g.Key, g => g.ToList()); + } + + /// + /// 按FIFO规则计算单种药材的使用成本 + /// + private decimal CalculateHerbCostByFifo( + Dictionary> fifoData, + long medicinalId, + decimal usedWeight) + { + if (usedWeight <= 0 || !fifoData.TryGetValue(medicinalId, out var records) || !records.Any()) + return 0; + + decimal remainingToCalculate = usedWeight; + decimal totalCost = 0; + + // 按入库顺序依次消耗 + foreach (var record in records) + { + if (remainingToCalculate <= 0) + break; + + if (record.AddWeight <= remainingToCalculate) + { + // 当前批次全部消耗 + totalCost += record.AddWeight * record.UnitPrice; + remainingToCalculate -= record.AddWeight; + } + else + { + // 消耗当前批次的部分量 + totalCost += remainingToCalculate * record.UnitPrice; + remainingToCalculate = 0; + } + } + + return totalCost; + } + + + /// + /// 获取处方详情 + /// + /// + /// + /// + public async Task GetPrescriptionDetail(long id) + { + var prescription = await Context.Queryable() + .Where(p => p.Id == id) + .FirstAsync(); + + if (prescription == null) + { + throw Oops.Bah("处方不存在"); + } + + var person = await Context.Queryable() + .Where(pe => pe.Id == prescription.PersonId) + .FirstAsync(); + + var herbs = await Context.Queryable((ph, mt) => ph.MedicinalId == mt.Id) + .Where(ph => ph.PrescriptionId == id) + .Select((ph, mt) => new PrescriptionHerbDto + { + MedicinalId = mt.Id, + MedicinalName = mt.MedicinalName, + AmountG = ph.AmountG, + Note = ph.Note + }) + .ToListAsync(); + + // 判断是否是员工还是家属 + PersonDto employee = null; + if (person.EmployeeId.HasValue) + { + var empPerson = await Context.Queryable() + .Where(pe => pe.Id == person.EmployeeId) + .Select(pe => new PersonDto + { + Id = pe.Id, + Name = pe.Name + }) + .FirstAsync(); + + employee = empPerson; + } + var RelationShipName = await GetRelationTypes(); + return new PrescriptionDetailDto + { + Id = prescription.Id, + Person = new PersonDetailDto + { + Id = person.Id, + Name = person.Name, + Birthday = person.Birthday, + Weight = prescription.Weight, + Height = person.Height, + IsEmployee = !person.EmployeeId.HasValue, + EmployeeId = person.EmployeeId, + EmployeeName = employee?.Name, + RelationShip = person.RelationShip, + RelationShipName = RelationShipName.FirstOrDefault(t => t.Id == person.RelationShip)?.Name + }, + DiagnosisResult = prescription.DiagnosisResult, + UserMedicinaAdvice = prescription.UserMedicinaAdvice, + VisitDate = prescription.VisitDate, + Herbs = herbs, + CanEdit = prescription.CreateTime.Value.Date == DateTime.Now.Date + }; + } + /// + /// 添加编辑处方记录 + /// + /// + /// + public async Task SavePrescription(SavePrescriptionInput input) + { + // 基础参数验证 + if (input == null) + throw Oops.Bah("输入参数不能为空"); + + if (input.Herbs == null || !input.Herbs.Any()) + throw Oops.Bah("处方药材不能为空"); + + await Context.Ado.BeginTranAsync(); + try + { + // 用于在方法内记录新创建的员工 id(如果需要) + long? createdEmployeeId = null; + + // ---------- 1. 处理前端在 person 中携带的“临时员工”(如果存在) ---------- + if (input.Person == null) + throw Oops.Bah("人员信息不能为空"); + + // 场景 A: 病人是家属(IsEmployee == false),但关联的员工是前端临时新增 + if (!input.Person.IsEmployee) + { + // 如果前端明确标记关联员工为临时新增(EmployeeIsTemp),需要先创建员工 + if (input.Person.EmployeeIsTemp) + { + if (string.IsNullOrWhiteSpace(input.Person.EmployeeName)) + throw Oops.Bah("标记了临时关联员工,但未提供员工姓名"); + + // 创建新员工记录(作为 Person 表的一条记录,RelationShip=null, EmployeeId=null) + var newEmp = new Person + { + Id = YitIdHelper.NextId(), + Name = input.Person.EmployeeName?.Trim(), + }; + await Context.Insertable(newEmp).ExecuteCommandAsync(); + createdEmployeeId = newEmp.Id; + } + else if (input.Person.EmployeeId.HasValue && input.Person.EmployeeId.Value > 0) + { + // 如果前端传的是已有员工 ID,校验该员工是否存在 + var exists = await Context.Queryable() + .AnyAsync(p => p.Id == input.Person.EmployeeId.Value); + if (!exists) + throw Oops.Bah($"关联的员工 ID={input.Person.EmployeeId.Value} 不存在"); + } + else if (!string.IsNullOrWhiteSpace(input.Person.EmployeeName)) + { + // 兼容:即便没有显式 EmployeeIsTemp,前端传了 EmployeeName,我们也可以选择创建员工 + var newEmp = new Person + { + Id = YitIdHelper.NextId(), + Name = input.Person.EmployeeName.Trim(), + }; + await Context.Insertable(newEmp).ExecuteCommandAsync(); + createdEmployeeId = newEmp.Id; + } + else + { + // 没有绑定员工信息(既不是 temp,也没有 employeeId),则无法继续 + if (input.Person.Id == null || input.Person.Id <= 0) + throw Oops.Bah("家属未关联员工,请选择或新增关联员工"); + } + } + else + { + // 病人是公司员工(IsEmployee == true) + // 如果没有 Id,但前端同时将该员工标记为临时新增,或者传了 Name 而无 Id,则创建员工 + if ((!input.Person.Id.HasValue || input.Person.Id.Value <= 0) && + (!string.IsNullOrWhiteSpace(input.Person.Name) || input.Person.EmployeeIsTemp)) + { + // 如果前端对员工也标记了 EmployeeIsTemp 且提供了 EmployeeName,则优先使用 EmployeeName(兼容性) + string empNameForCreate = !string.IsNullOrWhiteSpace(input.Person.Name) ? input.Person.Name.Trim() : input.Person.EmployeeName?.Trim(); + if (string.IsNullOrWhiteSpace(empNameForCreate)) + throw Oops.Bah("新增员工时姓名不能为空"); + + var newEmp = new Person + { + Id = YitIdHelper.NextId(), + Name = empNameForCreate, + Birthday = input.Person.Birthday, + Height = input.Person.Height, + }; + await Context.Insertable(newEmp).ExecuteCommandAsync(); + // 将新创建的员工 id 作为主 person id(病人本身) + input.Person.Id = newEmp.Id; + } + else if (input.Person.Id.HasValue && input.Person.Id.Value > 0) + { + // 校验存在性 + var exists = await Context.Queryable().AnyAsync(p => p.Id == input.Person.Id.Value); + if (!exists) + throw Oops.Bah($"指定的人员 ID={input.Person.Id.Value} 不存在"); + } + } + + // ---------- 2. 确定主 personId(如果是临时创建的员工, input.Person.Id 已在上一步设置) ---------- + long personId; + if (input.Person.Id.HasValue && input.Person.Id.Value > 0) + { + personId = input.Person.Id.Value; + // 已存在的人员(或上一步创建的员工),我们仍然可以继续使用 Storageable 更新信息 + } + else + { + // 没有 Id,需新建主人员(可能是家属或员工) + if (string.IsNullOrWhiteSpace(input.Person.Name)) + throw Oops.Bah("新增人员信息不完整,姓名为必填项"); + + personId = YitIdHelper.NextId(); + } + + // ---------- 3. 保存/更新主人员信息(使用 Storageable,兼容插入或更新) ---------- + var mappedEmployeeId = input.Person.EmployeeId; + + // 如果之前创建了员工(createdEmployeeId),优先使用该 id 作为家属的 EmployeeId + if (createdEmployeeId.HasValue) + mappedEmployeeId = createdEmployeeId.Value; + + // 如果 person.IsEmployee == true,则 person.EmployeeId 应为 null(员工不需要关联员工) + if (input.Person.IsEmployee) + mappedEmployeeId = null; + + var person = new Person + { + Id = personId, + Name = input.Person?.Name, + Birthday = input.Person?.Birthday, + Height = input.Person?.Height, + RelationShip = input.Person?.RelationShip, + EmployeeId = mappedEmployeeId + }; + await Context.Storageable(person).ExecuteCommandAsync(); + + // ---------- 4. 处方保存/编辑逻辑(沿用原逻辑) ---------- + Prescription prescription; + if (input.Id.HasValue) // 编辑 + { + prescription = await Context.Queryable() + .FirstAsync(p => p.Id == input.Id.Value); + + if (prescription == null) + throw Oops.Bah("处方不存在"); + + if (prescription.CreateTime.Value.Date != DateTime.Now.Date) + throw Oops.Bah("只能编辑当天的处方"); + + // 查询原有消耗记录并恢复库存 + var oldHerbs = await Context.Queryable() + .Where(ph => ph.PrescriptionId == input.Id.Value) + .ToListAsync(); + + if (oldHerbs.Count > 0) + { + foreach (var g in oldHerbs.GroupBy(x => x.MedicinalId)) + { + // 恢复库存(加回已消耗) + // 注意:使用 Updateable 批量操作替换为 SetColumns 表达式累加数值 + await Context.Updateable() + .SetColumns(m => new Medicinal { Number = m.Number + g.Sum(x => x.AmountG) }) + .Where(m => m.Id == g.Key) + .ExecuteCommandAsync(); + } + } + + // 删除原有处方药材(物理删除或软删按你系统策略) + await Context.Deleteable() + .Where(ph => ph.PrescriptionId == input.Id.Value) + .ExecuteCommandAsync(); + + // 更新处方 + prescription.PersonId = personId; + prescription.Weight = input.Person.Weight; + prescription.DiagnosisResult = input.DiagnosisResult; + prescription.UserMedicinaAdvice = input.UserMedicinaAdvice; + prescription.VisitDate = input.VisitDate ?? DateTime.Now; + await Context.Updateable(prescription).ExecuteCommandAsync(); + } + else // 新增 + { + var prescripId = YitIdHelper.NextId(); + prescription = new Prescription + { + Id = prescripId, + Weight = input.Person.Weight, + PersonId = personId, + DiagnosisResult = input.DiagnosisResult, + UserMedicinaAdvice = input.UserMedicinaAdvice, + VisitDate = input.VisitDate ?? DateTime.Now, + CreateTime = DateTime.Now // 新增时设置创建时间 + }; + await Context.Insertable(prescription).ExecuteCommandAsync(); + input.Id = prescripId; + } + + // ---------- 5. 校验库存 & 扣减 & 插入消耗记录 ---------- + var herbIds = input.Herbs.Select(h => h.Id).ToList(); + var medicinalList = await Context.Queryable() + .Where(m => herbIds.Contains(m.Id)) + .ToListAsync(); + List HerbsId = new List(); + foreach (var herb in input.Herbs) + { + var medicinal = medicinalList.FirstOrDefault(m => m.Id == herb.Id); + if (medicinal == null) + throw Oops.Bah($"药材[{herb.Id}]不存在"); + if (herb.AmountG<=0) + throw Oops.Bah($"请填写正确的消耗量,药材[{medicinal.MedicinalName}]"); + if (medicinal.Number < herb.AmountG) + throw Oops.Bah($"药材[{medicinal.MedicinalName}]库存不足,当前库存: {medicinal.Number}g,需要: {herb.AmountG}g"); + if(HerbsId.Contains(herb.Id)) throw Oops.Bah($"请勿重复添加同一个药材【{medicinal.MedicinalName}】"); + HerbsId.Add(herb.Id); + medicinal.Number -= herb.AmountG; + } + + // 批量更新药材库存 + await Context.Updateable(medicinalList).ExecuteCommandAsync(); + + // 批量插入处方药材 + var prescriptionHerbs = input.Herbs.Select(h => new PrescriptionHerb + { + PrescriptionId = input.Id.Value, + MedicinalId = h.Id, + AmountG = h.AmountG, + Note = h.Note + }).ToList(); + await Context.Insertable(prescriptionHerbs).ExecuteCommandAsync(); + + await Context.Ado.CommitTranAsync(); + return input.Id.Value; + } + catch + { + await Context.Ado.RollbackTranAsync(); + throw; + } + } + + /// + /// 获取 人员下拉 + /// + /// + /// + /// + public async Task> GetPersonList(PersonType? type, long? employeeId) + { + var query = Context.Queryable(); + + // 筛选员工或家属 + if (type.HasValue) + { + if (type == PersonType.Employee) + { + query = query.Where(pe => pe.EmployeeId == null); + } + else if (type == PersonType.Relative && employeeId.HasValue) + { + query = query.Where(pe => pe.EmployeeId == employeeId); + } + } + + return await query.Select(pe => new PersonDto + { + Id = pe.Id, + Name = pe.Name, + Birthday = pe.Birthday, + Height = pe.Height, + RelationShip = pe.RelationShip + }).ToListAsync(); + } + /// + /// 获取关系下拉 + /// + /// + public async Task> GetRelationTypes() + { + var sysmodel = await Context.Queryable().FirstAsync(a => a.DictValue == "Relation"); + if (sysmodel != null) + { + return await Context.Queryable().Where(a => a.ParentId == sysmodel.Id).Select(pe => new RelationTypeDto + { + Id = int.Parse(pe.DictValue), + Name = pe.DictLabel, + }).ToListAsync(); + } + else + { + return new List + { + new RelationTypeDto { Id = 1, Name = "配偶" }, + new RelationTypeDto { Id = 2, Name = "子女" }, + new RelationTypeDto { Id = 3, Name = "父母" }, + new RelationTypeDto { Id = 4, Name = "兄弟姐妹" }, + new RelationTypeDto { Id = 5, Name = "其他" } + }; + } + } +} diff --git a/SimpleAdmin.Application/SimpleAdmin.Application.csproj b/SimpleAdmin.Application/SimpleAdmin.Application.csproj new file mode 100644 index 0000000..d7bd53a --- /dev/null +++ b/SimpleAdmin.Application/SimpleAdmin.Application.csproj @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/SimpleAdmin.Application/SimpleAdmin.Application.xml b/SimpleAdmin.Application/SimpleAdmin.Application.xml new file mode 100644 index 0000000..7a5bfee --- /dev/null +++ b/SimpleAdmin.Application/SimpleAdmin.Application.xml @@ -0,0 +1,838 @@ + + + + SimpleAdmin.Application + + + + + 机构 + + + + + 岗位 + + + + + 代码生成基础 + + + + + 姓名 + + + + + 性别 + + + + + 民族 + + + + + 年龄 + + + + + 生日 + + + + + 存款 + + + + + 排序码 + + + + + 药材 + + + + + 数量(g) + + + + + 药材关联id + + + + + 添加重量(g) + + + + + 药材单价 + + + + + 总价 + + + + + 若非空,表示此 person 是某员工的家属 + + + + 单位 cm,保留两位小数 + + + 单位 kg,保留两位小数 + + + 消耗克数,单位 g + + + + 系统配置 + + + + + 未找到下拉框的时候传这个值代表添加新的药材 + + + + + 获取药材列表,带筛选 + + 药材名称筛选 + 页码 + 页大小 + + + + + 获取药材消耗记录 + + 药材ID + + + + + 获取药材下拉 + + + + + + 获取药材添加记录 + + 药材ID + + + + + 添加药材 + + 添加信息 + + + + + 修改药材添加记录(仅当天可修改) + + 记录ID + 修改信息 + + + + + 删除药材添加记录(仅当天可删除) + + 记录ID + + + + + 关联的员工名称 + + + + + 当前关联的员工是否是前端临时新增(需要后端创建) + + + + + 当 EmployeeIsTemp 为 true 或者前端直接传了员工名字时,后端可用此字段创建员工 + + + + + 获取处方列表,带筛选 + + 筛选条件 + + + + + 获取处方详情 + + 处方ID + + + + + 保存处方(新增或编辑) + + 处方信息 + + + + + 获取人员列表(员工和家属) + + 人员类型 + 员工ID(用于获取家属) + + + + + 获取所有关系类型(写死在代码中) + + + + + + 机构服务 + + + + + 添加机构 + + 添加参数 + + + + + 复制机构 + + 机构复制参数 + + + + + 删除机构 + + 删除参数 + + + + + 编辑机构 + + 编辑参数 + + + + + 机构分页查询 + + 查询参数 + 分页信息 + + + + 机构树结构 + + 机构选择器 + + + + + 机构详情 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + 参数 + 操作名称 + + + + 岗位管理 + + + + + 添加岗位 + + 添加参数 + + + + + 删除岗位 + + id列表 + + + + + 编辑岗位 + + 编辑参数 + + + + + 岗位分页查询 + + 查询参数 + 分页列表 + + + + 岗位选择器 + + + + + + + 岗位详情 + + + + + + + 岗位树形结构 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + 参数 + 操作名称 + + + + 角色拥有资源 + + 角色id + 资源类型 + 角色拥有资源信息 + + + + 获取角色下的用户 + + 角色ID + + + + + 分页查询角色 + + 查询参数 + + + + + 角色选择器 + + + + + + + 获取角色树 + + 角色树 + + + + + 角色详情 + + 角色Id + + + + + 资源树选择器 + + + + + + 添加角色 + + 添加参数 + + + + + 编辑角色 + + 编辑参数 + + + + + 给角色授权 + + 授权参数 + + + + + 给角色授权用户 + + 授权信息 + + + + + 删除角色 + + 删除参数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + + + + 获取授权菜单 + + 模块Id + 拥有菜单列表 + 拥有权限按钮列表 + + + + + 业务用户导入 + + + + + 业务用户导出 + + + + + 人员管理服务 + + + + + 人员选择器 + + 查询参数 + 人员列表 + + + + 用户分页查询 + + 查询参数 + 用户分页列表 + + + + 获取用户拥有角色 + + 用户ID + + + + + 角色选择器 + + + + + + + 人员详情 + + + + + + + 添加用户 + + 添加参数 + + + + + 编辑 + + 编辑参数 + + + + + 禁用用户 + + 用户Id + + + + + 启用用户 + + 用户Id + + + + + 重置密码 + + 用户Id + + + + + 给用户授权角色 + + 授权参数 + + + + + 删除用户 + + Id列表 + + + + + 导入预览 + + 导入参数 + + + + + 获取导入模板 + + + + + + 导出 + + 查询参数 + + + + + 导入数据 + + 数据 + 导入结果 + + + + 批量编辑 + + 编辑字段信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + 操作类型 + + + + 检查输入参数 + + 用户ID + 操作 + + + + 检查导入数据 + + 数据 + 数据范围ID数组 + 是否初始化错误 + + + + + 获取查询条件 + + + + + + + AppStartup启动类 + + + + + ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行 + 服务都还没初始化完成,会导致内存中存在多份 IOC 容器!! + 正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了 + + + + + + 获取药材下拉 + + + + + + + 获取药材添加记录 + + + + + + + 添加药材 + + + + + + + 修改药材添加记录 + + + + + + + + + 删除药材添加记录 + + + + + + + + 批量计算:使用成本、剩余价值、总使用量(先进先出法) + + 需要计算的药材ID列表 + + + + 获取药材FIFO计算所需的基础数据(入库记录) + + + + + 按FIFO规则计算单种药材的使用成本 + + + + + 获取处方详情 + + + + + + + + 添加编辑处方记录 + + + + + + + 获取 人员下拉 + + + + + + + + 获取关系下拉 + + + + + diff --git a/SimpleAdmin.Application/Startup.cs b/SimpleAdmin.Application/Startup.cs new file mode 100644 index 0000000..f20b884 --- /dev/null +++ b/SimpleAdmin.Application/Startup.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Application; + +/// +/// AppStartup启动类 +/// +public class Startup : AppStartup +{ + /// + /// ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行 + /// 服务都还没初始化完成,会导致内存中存在多份 IOC 容器!! + /// 正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了 + /// + /// + public void ConfigureServices(IServiceCollection services) + { + //业务配置转实体 + services.AddConfigurableOptions(); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + var fullName = Assembly.GetExecutingAssembly().FullName;//获取程序集全名 + //通过 App.GetOptions 获取选项 + var settings = App.GetOptions(); + CodeFirstUtils.CodeFirst(settings, fullName);//CodeFirst + } +} diff --git a/SimpleAdmin.Cache/Cache.Development.json b/SimpleAdmin.Cache/Cache.Development.json new file mode 100644 index 0000000..a136f90 --- /dev/null +++ b/SimpleAdmin.Cache/Cache.Development.json @@ -0,0 +1,12 @@ +{ + //缓存设置 + "CacheSettings": { + "UseRedis": false, //启用redis + "RedisSettings": { + "Address": "127.0.0.1:6379", //地址 + "Password": "123456", //Redis服务密码 + "Db": 9, //默认库 + "ClearRedis": true //是否每次启动都清除Redis缓存 + } + } +} \ No newline at end of file diff --git a/SimpleAdmin.Cache/Cache.Production.json b/SimpleAdmin.Cache/Cache.Production.json new file mode 100644 index 0000000..a136f90 --- /dev/null +++ b/SimpleAdmin.Cache/Cache.Production.json @@ -0,0 +1,12 @@ +{ + //缓存设置 + "CacheSettings": { + "UseRedis": false, //启用redis + "RedisSettings": { + "Address": "127.0.0.1:6379", //地址 + "Password": "123456", //Redis服务密码 + "Db": 9, //默认库 + "ClearRedis": true //是否每次启动都清除Redis缓存 + } + } +} \ No newline at end of file diff --git a/SimpleAdmin.Cache/GlobalUsing.cs b/SimpleAdmin.Cache/GlobalUsing.cs new file mode 100644 index 0000000..0b4bbe1 --- /dev/null +++ b/SimpleAdmin.Cache/GlobalUsing.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +global using MoYu; +global using Masuit.Tools; +global using Microsoft.AspNetCore.Builder; +global using Microsoft.AspNetCore.Hosting; +global using Microsoft.Extensions.DependencyInjection; +global using NewLife.Caching; +global using NewLife.Serialization; +global using SimpleAdmin.Core; +global using SimpleRedis; diff --git a/SimpleAdmin.Cache/Interface/ISimpleCacheHashService.cs b/SimpleAdmin.Cache/Interface/ISimpleCacheHashService.cs new file mode 100644 index 0000000..5b3452c --- /dev/null +++ b/SimpleAdmin.Cache/Interface/ISimpleCacheHashService.cs @@ -0,0 +1,70 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Cache; + +/// +/// 缓存服务 +/// +public partial interface ISimpleCacheService +{ + /// + /// 添加一条数据到HashMap + /// + /// + /// 键 + /// hash列表里的Key + /// 值 + void HashAdd(string key, string hashKey, T value); + + /// + /// 添加多条数据到HashMap + /// + /// + /// 键 + /// 键值对字典 + /// + bool HashSet(string key, Dictionary dic); + + /// + /// 从HashMap中删除数据 + /// + /// + /// 键 + /// hash键列表 + /// 执行结果 + int HashDel(string key, params string[] fields); + + /// + /// 根据键获取hash列表中的值 + /// + /// + /// 键 + /// hash键列表 + /// 数据列表 + List HashGet(string key, params string[] fields); + + /// + /// 根据键获取hash列表中的值 + /// + /// + /// 键 + /// hash键 + /// + T HashGetOne(string key, string field); + + /// + /// 获取所有键值对 + /// + /// + /// 键 + /// 数据字典 + IDictionary HashGetAll(string key); +} diff --git a/SimpleAdmin.Cache/Interface/ISimpleCacheQueueService.cs b/SimpleAdmin.Cache/Interface/ISimpleCacheQueueService.cs new file mode 100644 index 0000000..de157c7 --- /dev/null +++ b/SimpleAdmin.Cache/Interface/ISimpleCacheQueueService.cs @@ -0,0 +1,108 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using NewLife.Caching.Queues; + +namespace SimpleAdmin.Cache; + +/// +/// 缓存服务 +/// +public partial interface ISimpleCacheService +{ + #region 普通队列 + + /// + /// 添加到队列 + /// + /// + /// 键 + /// 值数组 + /// 添加数量 + int AddQueue(string key, T[] value); + + /// + /// 添加到队列 + /// + /// + /// 键 + /// 值 + /// 添加数量 + int AddQueue(string key, T value); + + /// + /// 获取队列实例 + /// + /// + /// 键 + /// 队列实例 + RedisQueue GetRedisQueue(string key); + + /// + /// 从队列中获取数据 + /// + /// + /// 键 + /// 数量 + /// 数据列表 + List GetQueue(string key, int Count = 1); + + /// + /// 取一条数据 + /// + /// + /// 键 + /// 阻塞时间 + /// 数据 + T GetQueueOne(string key, int timeout = 1); + + /// + /// 异步取一条数据 + /// + /// + /// 键 + /// 阻塞时间 + /// 数据 + Task GetQueueOneAsync(string key, int timeout = 1); + + #endregion + + #region 延迟队列 + + /// + /// 添加一条数据到延迟队列 + /// + /// + /// 键 + /// 值 + /// 延迟时间 + /// 添加成功数量 + int AddDelayQueue(string key, T value, int delay); + + /// + /// 批量添加数据到延迟队列 + /// + /// + /// 键 + /// 值 + /// 延迟时间 + /// 添加成功数量 + int AddDelayQueue(string key, List value, int delay); + + /// + /// 获取延迟队列实例 + /// + /// + /// 键 + /// + RedisDelayQueue GetDelayQueue(string key); + + #endregion +} diff --git a/SimpleAdmin.Cache/Interface/ISimpleCacheService.cs b/SimpleAdmin.Cache/Interface/ISimpleCacheService.cs new file mode 100644 index 0000000..7299aed --- /dev/null +++ b/SimpleAdmin.Cache/Interface/ISimpleCacheService.cs @@ -0,0 +1,191 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Cache; + +/// +/// 缓存服务 +/// +public partial interface ISimpleCacheService +{ + #region 基础操作 + + /// 是否包含缓存项 + /// + /// + bool ContainsKey(string key); + + /// 设置缓存项 + /// 键 + /// 值 + /// 过期时间,秒。小于0时采用默认缓存时间 + /// + bool Set(string key, T value, int expire = -1); + + /// 设置缓存项 + /// 键 + /// 值 + /// 过期时间 + /// + bool Set(string key, T value, TimeSpan expire); + + /// 获取缓存项 + /// 键 + /// + T Get(string key); + + /// 批量移除缓存项 + /// 键集合 + /// + int Remove(params string[] keys); + + /// 清空所有缓存项 + void Clear(); + + /// 设置缓存项有效期 + /// 键 + /// 过期时间 + bool SetExpire(string key, TimeSpan expire); + + /// 获取缓存项有效期 + /// 键 + /// + TimeSpan GetExpire(string key); + + /// + /// 模糊删除 + /// + /// 匹配关键字 + void DelByPattern(string pattern); + + #endregion 基础操作 + + #region 集合操作 + + /// 批量获取缓存项 + /// + /// + /// + IDictionary GetAll(IEnumerable keys); + + /// 批量设置缓存项 + /// + /// + /// 过期时间,秒。小于0时采用默认缓存时间 + void SetAll(IDictionary values, int expire = -1); + + /// 获取列表 + /// 元素类型 + /// 键 + /// + IList GetList(string key); + + /// 获取哈希 + /// 元素类型 + /// 键 + /// + IDictionary GetDictionary(string key); + + /// 获取队列 + /// 元素类型 + /// 键 + /// + IProducerConsumer GetQueue(string key); + + /// 获取栈 + /// 元素类型 + /// 键 + /// + IProducerConsumer GetStack(string key); + + /// 获取Set + /// + /// + /// + ICollection GetSet(string key); + + #endregion 集合操作 + + #region 高级操作 + + /// 添加,已存在时不更新 + /// 值类型 + /// 键 + /// 值 + /// 过期时间,秒。小于0时采用默认缓存时间 + /// + bool Add(string key, T value, int expire = -1); + + /// 设置新值并获取旧值,原子操作 + /// + /// 常常配合Increment使用,用于累加到一定数后重置归零,又避免多线程冲突。 + /// + /// 值类型 + /// 键 + /// 值 + /// + T Replace(string key, T value); + + /// 尝试获取指定键,返回是否包含值。有可能缓存项刚好是默认值,或者只是反序列化失败,解决缓存穿透问题 + /// 值类型 + /// 键 + /// 值。即使有值也不一定能够返回,可能缓存项刚好是默认值,或者只是反序列化失败 + /// 返回是否包含值,即使反序列化失败 + bool TryGetValue(string key, out T value); + + /// 累加,原子操作 + /// 键 + /// 变化量 + /// + long Increment(string key, long value); + + /// 累加,原子操作 + /// 键 + /// 变化量 + /// + double Increment(string key, double value); + + /// 递减,原子操作 + /// 键 + /// 变化量 + /// + long Decrement(string key, long value); + + /// 递减,原子操作 + /// 键 + /// 变化量 + /// + double Decrement(string key, double value); + + #endregion 高级操作 + + #region 事务 + + /// 提交变更。部分提供者需要刷盘 + /// + int Commit(); + + /// 申请分布式锁 + /// 要锁定的key + /// 锁等待时间,单位毫秒 + /// + IDisposable AcquireLock(string key, int msTimeout); + + /// 申请分布式锁 + /// 要锁定的key + /// 锁等待时间,申请加锁时如果遇到冲突则等待的最大时间,单位毫秒 + /// 锁过期时间,超过该时间如果没有主动释放则自动释放锁,必须整数秒,单位毫秒 + /// 失败时是否抛出异常,如果不抛出异常,可通过返回null得知申请锁失败 + /// + IDisposable AcquireLock(string key, int msTimeout, int msExpire, + bool throwOnFailure); + + #endregion 事务 +} diff --git a/SimpleAdmin.Cache/Options/CacheSettingsOptions.cs b/SimpleAdmin.Cache/Options/CacheSettingsOptions.cs new file mode 100644 index 0000000..380d26c --- /dev/null +++ b/SimpleAdmin.Cache/Options/CacheSettingsOptions.cs @@ -0,0 +1,55 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using MoYu.ConfigurableOptions; + +namespace SimpleAdmin.Cache; + +/// +/// 缓存设置 +/// +public class CacheSettingsOptions : IConfigurableOptions +{ + /// + /// 使用Redis + /// + public bool UseRedis { get; set; } + + /// + /// Redis设置 + /// + public RedisSettings RedisSettings { get; set; } +} + +/// +/// Redis设置 +/// +public class RedisSettings +{ + /// + /// 连接地址 + /// + public string Address { get; set; } + + /// + /// 密码 + /// + public string Password { get; set; } + + /// + /// 数据库 + /// + public int Db { get; set; } = 0; + + /// + /// 是否每次启动都清空 + /// + public bool ClearRedis { get; set; } = false; +} diff --git a/SimpleAdmin.Cache/Service/MemoryCacheHashService.cs b/SimpleAdmin.Cache/Service/MemoryCacheHashService.cs new file mode 100644 index 0000000..0b2f8fe --- /dev/null +++ b/SimpleAdmin.Cache/Service/MemoryCacheHashService.cs @@ -0,0 +1,98 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Cache; + +/// +/// +/// 内存缓存 +/// +public partial class MemoryCacheService +{ + /// + public void HashAdd(string key, string hashKey, T value) + { + //获取字典 + var exist = _memoryCache.GetDictionary(key); + if (exist.ContainsKey(hashKey))//如果包含Key + exist[hashKey] = value;//重新赋值 + else exist.TryAdd(hashKey, value);//加上新的值 + _memoryCache.Set(key, exist); + } + + //private IDictionary GetDictionary(string key,string) + + /// + public bool HashSet(string key, Dictionary dic) + { + //获取字典 + var exist = _memoryCache.GetDictionary(key); + dic.ForEach(it => + { + if (exist.ContainsKey(it.Key))//如果包含Key + exist[it.Key] = it.Value;//重新赋值 + else exist.Add(it.Key, it.Value);//加上新的值 + }); + + return true; + } + + /// + public int HashDel(string key, params string[] fields) + { + var result = 0; + //获取字典 + var exist = _memoryCache.GetDictionary(key); + foreach (var field in fields) + { + if (field != null && exist.ContainsKey(field))//如果包含Key + { + exist.Remove(field);//删除 + result++; + } + } + return result; + } + + /// + public List HashGet(string key, params string[] fields) + { + var list = new List(); + //获取字典 + var exist = _memoryCache.GetDictionary(key); + foreach (var field in fields) + { + if (exist.TryGetValue(field, out var value))//如果包含Key + { + list.Add(value); + } + else { list.Add(default); } + } + return list; + } + + /// + public T HashGetOne(string key, string field) + { + //获取字典 + var exist = _memoryCache.GetDictionary(key); + + exist.TryGetValue(field, out var result); + var data = result.DeepClone(); + return data; + } + + /// + public IDictionary HashGetAll(string key) + { + var data = _memoryCache.GetDictionary(key); + return data; + } +} diff --git a/SimpleAdmin.Cache/Service/MemoryCacheQueueService.cs b/SimpleAdmin.Cache/Service/MemoryCacheQueueService.cs new file mode 100644 index 0000000..a1eff51 --- /dev/null +++ b/SimpleAdmin.Cache/Service/MemoryCacheQueueService.cs @@ -0,0 +1,74 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using NewLife.Caching.Queues; + +namespace SimpleAdmin.Cache; + +/// +/// +/// 内存缓存 +/// +public partial class MemoryCacheService +{ + /// + public int AddQueue(string key, T[] value) + { + throw new NotImplementedException(); + } + + /// + public int AddQueue(string key, T value) + { + throw new NotImplementedException(); + } + + /// + public RedisQueue GetRedisQueue(string key) + { + throw new NotImplementedException(); + } + + /// + public List GetQueue(string key, int Count = 1) + { + throw new NotImplementedException(); + } + + /// + public T GetQueueOne(string key, int timeout = 1) + { + throw new NotImplementedException(); + } + + /// + public async Task GetQueueOneAsync(string key, int timeout = 1) + { + throw new NotImplementedException(); + } + + /// + public int AddDelayQueue(string key, T value, int delay) + { + throw new NotImplementedException(); + } + + /// + public int AddDelayQueue(string key, List value, int delay) + { + throw new NotImplementedException(); + } + + /// + public RedisDelayQueue GetDelayQueue(string key) + { + throw new NotImplementedException(); + } +} diff --git a/SimpleAdmin.Cache/Service/MemoryCacheService.cs b/SimpleAdmin.Cache/Service/MemoryCacheService.cs new file mode 100644 index 0000000..40d9074 --- /dev/null +++ b/SimpleAdmin.Cache/Service/MemoryCacheService.cs @@ -0,0 +1,229 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Cache; + +/// +/// +/// 内存缓存 +/// +public partial class MemoryCacheService : ISimpleCacheService +{ + private readonly MemoryCache _memoryCache; + + public MemoryCacheService() + { + _memoryCache = new MemoryCache(); + } + + #region 普通操作 + + /// + public T Get(string key) + { + var data = _memoryCache.Get(key); + return data.ToObject(); + } + + /// + public int Remove(params string[] keys) + { + return _memoryCache.Remove(keys); + } + + /// + public bool Set(string key, T value, int expire = -1) + { + return _memoryCache.Set(key, value.ToJson(), expire); + } + + /// + public bool Set(string key, T value, TimeSpan expire) + { + return _memoryCache.Set(key, value.ToJson(), expire); + } + + /// + public bool SetExpire(string key, TimeSpan expire) + { + return _memoryCache.SetExpire(key, expire); + } + + /// + public TimeSpan GetExpire(string key) + { + return _memoryCache.GetExpire(key); + } + + /// + public bool ContainsKey(string key) + { + return _memoryCache.ContainsKey(key); + } + + /// + public void Clear() + { + _memoryCache.Clear(); + } + + /// + public void DelByPattern(string pattern) + { + var keys = _memoryCache.Keys.ToList();//获取所有key + keys.ForEach(it => + { + if (it.Contains(pattern))//如果匹配 + _memoryCache.Remove(pattern); + }); + } + + #endregion 普通操作 + + #region 集合操作 + + /// + public IDictionary GetAll(IEnumerable keys) + { + IDictionary? result = default;//定义集合 + var data = _memoryCache.GetAll(keys);//获取数据 + data.ForEach(it => + { + result.Add(it.Key, it.Value.ToObject());//遍历数据,格式化并加到新的数据集合 + }); + return result; + } + + /// + public void SetAll(IDictionary values, int expire = -1) + { + IDictionary? result = default;//定义集合 + values.ForEach(it => + { + result.Add(it.Key, it.Value.ToJson());//遍历数据,格式化并加到新的数据集合 + }); + _memoryCache.SetAll(values, expire); + } + + /// + public IDictionary GetDictionary(string key) + { + IDictionary? result = default;//定义集合 + var data = _memoryCache.GetDictionary(key); + data.ForEach(it => + { + result.Add(it.Key, it.Value.ToObject());//遍历数据,格式化并加到新的数据集合 + }); + return result; + } + + /// + public IProducerConsumer GetQueue(string key) + { + return _memoryCache.GetQueue(key); + } + + /// + public IProducerConsumer GetStack(string key) + { + return _memoryCache.GetStack(key); + } + + /// + public ICollection GetSet(string key) + { + return _memoryCache.GetSet(key); + } + + #endregion 集合操作 + + #region 高级操作 + + /// + public bool Add(string key, T value, int expire = -1) + { + return _memoryCache.Add(key, value.ToJson(), expire); + } + + /// + public IList GetList(string key) + { + IList result = default;//定义集合 + var data = _memoryCache.GetList(key); + data.ForEach(it => + { + result.Add(it.ToObject());//遍历数据,格式化并加到新的数据集合 + }); + return result; + } + + /// + public T Replace(string key, T value) + { + return _memoryCache.Replace(key, value); + } + + /// + public bool TryGetValue(string key, out T value) + { + _ = _memoryCache.TryGetValue(key, out var result); + value = result.ToObject(); + return value == null; + } + + /// + public long Decrement(string key, long value) + { + return _memoryCache.Decrement(key, value); + } + + /// + public double Decrement(string key, double value) + { + return _memoryCache.Decrement(key, value); + } + + /// + public long Increment(string key, long value) + { + return _memoryCache.Increment(key, value); + } + + /// + public double Increment(string key, double value) + { + return _memoryCache.Increment(key, value); + } + + #endregion 高级操作 + + #region 事务 + + /// + public int Commit() + { + return _memoryCache.Commit(); + } + + /// + public IDisposable AcquireLock(string key, int msTimeout) + { + return _memoryCache.AcquireLock(key, msTimeout); + } + + /// + public IDisposable AcquireLock(string key, int msTimeout, int msExpire, + bool throwOnFailure) + { + return _memoryCache.AcquireLock(key, msTimeout, msExpire, throwOnFailure); + } + + #endregion 事务 +} diff --git a/SimpleAdmin.Cache/Service/RedisCacheHashService.cs b/SimpleAdmin.Cache/Service/RedisCacheHashService.cs new file mode 100644 index 0000000..9b2d7c2 --- /dev/null +++ b/SimpleAdmin.Cache/Service/RedisCacheHashService.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Cache; + +/// +/// +/// Redis缓存 +/// +public partial class RedisCacheService +{ + /// + public void HashAdd(string key, string hashKey, T value) + { + _simpleRedis.HashAdd(key, hashKey, value); + } + + /// + public bool HashSet(string key, Dictionary dic) + { + return _simpleRedis.HashSet(key, dic); + } + + /// + public int HashDel(string key, params string[] fields) + { + return _simpleRedis.HashDel(key, fields); + } + + /// + public List HashGet(string key, params string[] fields) + { + return _simpleRedis.HashGet(key, fields); + } + + /// + public T HashGetOne(string key, string field) + { + return _simpleRedis.HashGetOne(key, field); + } + + /// + public IDictionary HashGetAll(string key) + { + return _simpleRedis.HashGetAll(key); + } +} diff --git a/SimpleAdmin.Cache/Service/RedisCacheQueueService.cs b/SimpleAdmin.Cache/Service/RedisCacheQueueService.cs new file mode 100644 index 0000000..116569c --- /dev/null +++ b/SimpleAdmin.Cache/Service/RedisCacheQueueService.cs @@ -0,0 +1,74 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using NewLife.Caching.Queues; + +namespace SimpleAdmin.Cache; + +/// +/// +/// Redis缓存 +/// +public partial class RedisCacheService +{ + /// + public int AddQueue(string key, T[] value) + { + return _simpleRedis.AddQueue(key, value); + } + + /// + public int AddQueue(string key, T value) + { + return _simpleRedis.AddQueue(key, value); + } + + /// + public RedisQueue GetRedisQueue(string key) + { + return _simpleRedis.GetRedisQueue(key); + } + + /// + public List GetQueue(string key, int Count = 1) + { + return _simpleRedis.GetQueue(key, Count); + } + + /// + public T GetQueueOne(string key, int timeout = 1) + { + return _simpleRedis.GetQueueOne(key, timeout); + } + + /// + public async Task GetQueueOneAsync(string key, int timeout = 1) + { + return await _simpleRedis.GetQueueOneAsync(key, timeout); + } + + /// + public int AddDelayQueue(string key, T value, int delay) + { + return _simpleRedis.AddDelayQueue(key, value, delay); + } + + /// + public int AddDelayQueue(string key, List value, int delay) + { + return _simpleRedis.AddDelayQueue(key, value, delay); + } + + /// + public RedisDelayQueue GetDelayQueue(string key) + { + return _simpleRedis.GetDelayQueue(key); + } +} diff --git a/SimpleAdmin.Cache/Service/RedisCacheService.cs b/SimpleAdmin.Cache/Service/RedisCacheService.cs new file mode 100644 index 0000000..efd873b --- /dev/null +++ b/SimpleAdmin.Cache/Service/RedisCacheService.cs @@ -0,0 +1,201 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using NewLife.Caching.Queues; + +namespace SimpleAdmin.Cache; + +/// +/// +/// Redis缓存 +/// +public partial class RedisCacheService : ISimpleCacheService +{ + private readonly ISimpleRedis _simpleRedis; + + public RedisCacheService(ISimpleRedis simpleRedis) + { + _simpleRedis = simpleRedis; + } + + #region 普通操作 + + /// + public T Get(string key) + { + return _simpleRedis.Get(key); + } + + /// + public int Remove(params string[] keys) + { + return _simpleRedis.GetFullRedis().Remove(keys); + } + + /// + public bool Set(string key, T value, int expire = -1) + { + return _simpleRedis.Set(key, value, expire); + } + + /// + public bool Set(string key, T value, TimeSpan expire) + { + return _simpleRedis.Set(key, value, expire); + } + + /// + public bool SetExpire(string key, TimeSpan expire) + { + return _simpleRedis.GetFullRedis().SetExpire(key, expire); + } + + /// + public TimeSpan GetExpire(string key) + { + return _simpleRedis.GetFullRedis().GetExpire(key); + } + + + /// + public bool ContainsKey(string key) + { + return _simpleRedis.ContainsKey(key); + } + + /// + public void Clear() + { + _simpleRedis.Clear(); + } + + /// + public void DelByPattern(string pattern) + { + _simpleRedis.DelByPattern(pattern); + } + + #endregion 普通操作 + + #region 集合操作 + + /// + public IDictionary GetAll(IEnumerable keys) + { + return _simpleRedis.GetFullRedis().GetAll(keys); + } + + /// + public void SetAll(IDictionary values, int expire = -1) + { + _simpleRedis.GetFullRedis().SetAll(values, expire); + } + + /// + public IDictionary GetDictionary(string key) + { + return _simpleRedis.GetFullRedis().GetDictionary(key); + } + + /// + public IProducerConsumer GetQueue(string key) + { + return _simpleRedis.GetFullRedis().GetQueue(key); + } + + /// + public IProducerConsumer GetStack(string key) + { + return _simpleRedis.GetFullRedis().GetStack(key); + } + + /// + public ICollection GetSet(string key) + { + return _simpleRedis.GetFullRedis().GetSet(key); + } + + #endregion 集合操作 + + #region 高级操作 + + /// + public bool Add(string key, T value, int expire = -1) + { + return _simpleRedis.GetFullRedis().Add(key, value, expire); + } + + /// + public IList GetList(string key) + { + return _simpleRedis.GetFullRedis().GetList(key); + } + + /// + public T Replace(string key, T value) + { + return _simpleRedis.GetFullRedis().Replace(key, value); + } + + /// + public bool TryGetValue(string key, out T value) + { + return _simpleRedis.GetFullRedis().TryGetValue(key, out value); + } + + /// + public long Decrement(string key, long value) + { + return _simpleRedis.GetFullRedis().Decrement(key, value); + } + + /// + public double Decrement(string key, double value) + { + return _simpleRedis.GetFullRedis().Decrement(key, value); + } + + /// + public long Increment(string key, long value) + { + return _simpleRedis.GetFullRedis().Increment(key, value); + } + + /// + public double Increment(string key, double value) + { + return _simpleRedis.GetFullRedis().Increment(key, value); + } + + #endregion 高级操作 + + #region 事务 + + /// + public int Commit() + { + return _simpleRedis.GetFullRedis().Commit(); + } + + /// + public IDisposable AcquireLock(string key, int msTimeout) + { + return _simpleRedis.GetFullRedis().AcquireLock(key, msTimeout); + } + + /// + public IDisposable AcquireLock(string key, int msTimeout, int msExpire, + bool throwOnFailure) + { + return _simpleRedis.GetFullRedis().AcquireLock(key, msTimeout, msExpire, throwOnFailure); + } + + #endregion 事务 +} diff --git a/SimpleAdmin.Cache/SimpleAdmin.Cache.csproj b/SimpleAdmin.Cache/SimpleAdmin.Cache.csproj new file mode 100644 index 0000000..8c6e206 --- /dev/null +++ b/SimpleAdmin.Cache/SimpleAdmin.Cache.csproj @@ -0,0 +1,24 @@ + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + + + + + diff --git a/SimpleAdmin.Cache/SimpleAdmin.Cache.xml b/SimpleAdmin.Cache/SimpleAdmin.Cache.xml new file mode 100644 index 0000000..8a0fa49 --- /dev/null +++ b/SimpleAdmin.Cache/SimpleAdmin.Cache.xml @@ -0,0 +1,637 @@ + + + + SimpleAdmin.Cache + + + + + 缓存服务 + + + 缓存服务 + + + 缓存服务 + + + + + 添加一条数据到HashMap + + + 键 + hash列表里的Key + 值 + + + + 添加多条数据到HashMap + + + 键 + 键值对字典 + + + + + 从HashMap中删除数据 + + + 键 + hash键列表 + 执行结果 + + + + 根据键获取hash列表中的值 + + + 键 + hash键列表 + 数据列表 + + + + 根据键获取hash列表中的值 + + + 键 + hash键 + + + + + 获取所有键值对 + + + 键 + 数据字典 + + + + 添加到队列 + + + 键 + 值数组 + 添加数量 + + + + 添加到队列 + + + 键 + 值 + 添加数量 + + + + 获取队列实例 + + + 键 + 队列实例 + + + + 从队列中获取数据 + + + 键 + 数量 + 数据列表 + + + + 取一条数据 + + + 键 + 阻塞时间 + 数据 + + + + 异步取一条数据 + + + 键 + 阻塞时间 + 数据 + + + + 添加一条数据到延迟队列 + + + 键 + 值 + 延迟时间 + 添加成功数量 + + + + 批量添加数据到延迟队列 + + + 键 + 值 + 延迟时间 + 添加成功数量 + + + + 获取延迟队列实例 + + + 键 + + + + 是否包含缓存项 + + + + + 设置缓存项 + 键 + 值 + 过期时间,秒。小于0时采用默认缓存时间 + + + + 设置缓存项 + 键 + 值 + 过期时间 + + + + 获取缓存项 + 键 + + + + 批量移除缓存项 + 键集合 + + + + 清空所有缓存项 + + + 设置缓存项有效期 + 键 + 过期时间 + + + 获取缓存项有效期 + 键 + + + + + 模糊删除 + + 匹配关键字 + + + 批量获取缓存项 + + + + + + 批量设置缓存项 + + + 过期时间,秒。小于0时采用默认缓存时间 + + + 获取列表 + 元素类型 + 键 + + + + 获取哈希 + 元素类型 + 键 + + + + 获取队列 + 元素类型 + 键 + + + + 获取栈 + 元素类型 + 键 + + + + 获取Set + + + + + + 添加,已存在时不更新 + 值类型 + 键 + 值 + 过期时间,秒。小于0时采用默认缓存时间 + + + + 设置新值并获取旧值,原子操作 + + 常常配合Increment使用,用于累加到一定数后重置归零,又避免多线程冲突。 + + 值类型 + 键 + 值 + + + + 尝试获取指定键,返回是否包含值。有可能缓存项刚好是默认值,或者只是反序列化失败,解决缓存穿透问题 + 值类型 + 键 + 值。即使有值也不一定能够返回,可能缓存项刚好是默认值,或者只是反序列化失败 + 返回是否包含值,即使反序列化失败 + + + 累加,原子操作 + 键 + 变化量 + + + + 累加,原子操作 + 键 + 变化量 + + + + 递减,原子操作 + 键 + 变化量 + + + + 递减,原子操作 + 键 + 变化量 + + + + 提交变更。部分提供者需要刷盘 + + + + 申请分布式锁 + 要锁定的key + 锁等待时间,单位毫秒 + + + + 申请分布式锁 + 要锁定的key + 锁等待时间,申请加锁时如果遇到冲突则等待的最大时间,单位毫秒 + 锁过期时间,超过该时间如果没有主动释放则自动释放锁,必须整数秒,单位毫秒 + 失败时是否抛出异常,如果不抛出异常,可通过返回null得知申请锁失败 + + + + + 缓存设置 + + + + + 使用Redis + + + + + Redis设置 + + + + + Redis设置 + + + + + 连接地址 + + + + + 密码 + + + + + 数据库 + + + + + 是否每次启动都清空 + + + + + + 内存缓存 + + + + 内存缓存 + + + + 内存缓存 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Redis缓存 + + + + Redis缓存 + + + + Redis缓存 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AppStartup启动类 + + + + + ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行 + 服务都还没初始化完成,会导致内存中存在多份 IOC 容器!! + 正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了 + + + + + diff --git a/SimpleAdmin.Cache/Startup.cs b/SimpleAdmin.Cache/Startup.cs new file mode 100644 index 0000000..0b20d43 --- /dev/null +++ b/SimpleAdmin.Cache/Startup.cs @@ -0,0 +1,58 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Cache; + +/// +/// AppStartup启动类 +/// +[AppStartup(97)] +public class Startup : AppStartup +{ + /// + /// ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行 + /// 服务都还没初始化完成,会导致内存中存在多份 IOC 容器!! + /// 正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了 + /// + /// + public void ConfigureServices(IServiceCollection services) + { + //缓存设置配置转实体 + services.AddConfigurableOptions(); + //禁止在主机启动时通过 App.GetOptions 获取选项,如需获取配置选项理应通过 App.GetConfig("配置节点", true)。 + var cacheSettings = App.GetConfig("CacheSettings", true); + //如果有redis连接字符串 + if (cacheSettings.UseRedis) + { + var connectionString = + $"server={cacheSettings.RedisSettings.Address};password={cacheSettings.RedisSettings.Password};db={cacheSettings.RedisSettings.Db}"; + //注入redis + services.AddSimpleRedis(connectionString); + services.AddSingleton(); + } + else + { + services.AddSingleton(); + } + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + //通过 App.GetOptions 获取选项 + var cacheSettings = App.GetOptions(); + //如果需要清除缓存 + if (cacheSettings.UseRedis && cacheSettings.RedisSettings.ClearRedis) + { + var redis = App.GetService();//获取redis服务 + //删除redis的key + redis.DelByPattern(CacheConst.CACHE_PREFIX_WEB); + } + } +} diff --git a/SimpleAdmin.Core/Attributes/CodeGenAttribute.cs b/SimpleAdmin.Core/Attributes/CodeGenAttribute.cs new file mode 100644 index 0000000..687d18b --- /dev/null +++ b/SimpleAdmin.Core/Attributes/CodeGenAttribute.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 代码生成 +/// +public class CodeGenAttribute : Attribute +{ +} diff --git a/SimpleAdmin.Core/Attributes/IgnoreInitTableAttribute.cs b/SimpleAdmin.Core/Attributes/IgnoreInitTableAttribute.cs new file mode 100644 index 0000000..be494f4 --- /dev/null +++ b/SimpleAdmin.Core/Attributes/IgnoreInitTableAttribute.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 忽略初始化表 +/// +public class IgnoreInitTableAttribute : Attribute +{ +} diff --git a/SimpleAdmin.Core/Attributes/IgnoreSeedDataAttribute.cs b/SimpleAdmin.Core/Attributes/IgnoreSeedDataAttribute.cs new file mode 100644 index 0000000..5935b0f --- /dev/null +++ b/SimpleAdmin.Core/Attributes/IgnoreSeedDataAttribute.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 种子数据忽略新增 +/// +public class IgnoreSeedDataAddAttribute : Attribute +{ +} + +/// +/// 种子数据忽略修改 +/// +public class IgnoreSeedDataUpdateAttribute : Attribute +{ +} diff --git a/SimpleAdmin.Core/Attributes/RolePermissionAttribute.cs b/SimpleAdmin.Core/Attributes/RolePermissionAttribute.cs new file mode 100644 index 0000000..c9d3cad --- /dev/null +++ b/SimpleAdmin.Core/Attributes/RolePermissionAttribute.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 需要角色授权权限 +/// +public class RolePermissionAttribute : Attribute +{ +} + +/// +/// 忽略角色授权权限 +/// +public class IgnoreRolePermissionAttribute : Attribute +{ +} diff --git a/SimpleAdmin.Core/Attributes/SuperAdminAttribute.cs b/SimpleAdmin.Core/Attributes/SuperAdminAttribute.cs new file mode 100644 index 0000000..9e4f6cc --- /dev/null +++ b/SimpleAdmin.Core/Attributes/SuperAdminAttribute.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 管理员才能访问特性 +/// +public class SuperAdminAttribute : Attribute +{ +} + +/// +/// 忽略超级管理员才能访问特性 +/// +public class IgnoreSuperAdminAttribute : Attribute +{ +} diff --git a/SimpleAdmin.Core/Attributes/ValidationAttribute/IdNotNull.cs b/SimpleAdmin.Core/Attributes/ValidationAttribute/IdNotNull.cs new file mode 100644 index 0000000..bd56891 --- /dev/null +++ b/SimpleAdmin.Core/Attributes/ValidationAttribute/IdNotNull.cs @@ -0,0 +1,39 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + + + +namespace SimpleAdmin.Core; + +/// +/// 验证Id不能为 空 +/// +public class IdNotNull : ValidationAttribute +{ + public override bool IsValid(object value) + { + if (value.ToLong() > 0 || !string.IsNullOrEmpty(value.ToString())) + return true; + return false; + } +} + +/// +/// 验证Id列表不能为空 +/// +public class IdsNotNull : ValidationAttribute +{ + public override bool IsValid(object value) + { + if (value is List { Count: 0 }) + return false; + return true; + } +} diff --git a/SimpleAdmin.Core/BaseInput/BaseFileInput.cs b/SimpleAdmin.Core/BaseInput/BaseFileInput.cs new file mode 100644 index 0000000..e597667 --- /dev/null +++ b/SimpleAdmin.Core/BaseInput/BaseFileInput.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 文件上传输入参数 +/// +public class BaseFileInput +{ + /// + /// 文件 + /// + [Required(ErrorMessage = "文件不能为空")] + public IFormFile? File { get; set; } +} diff --git a/SimpleAdmin.Core/BaseInput/BaseIdInput.cs b/SimpleAdmin.Core/BaseInput/BaseIdInput.cs new file mode 100644 index 0000000..a47dab8 --- /dev/null +++ b/SimpleAdmin.Core/BaseInput/BaseIdInput.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 主键Id输入参数 +/// +public class BaseIdInput +{ + /// + /// 主键Id + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + [DataValidation(ValidationTypes.Numeric)] + public virtual long Id { get; set; } +} + +public class BaseIdListInput +{ + /// + /// 主键Id列表 + /// + [IdsNotNull(ErrorMessage = "IdList不能为空")] + public List Ids { get; set; } = new List(); +} + +/// +/// Id列表输入 +/// +public class IdListInput +{ + [Required(ErrorMessage = "IdList不能为空")] + public List? IdList { get; set; } +} diff --git a/SimpleAdmin.Core/BaseInput/BasePageInput.cs b/SimpleAdmin.Core/BaseInput/BasePageInput.cs new file mode 100644 index 0000000..8eb2057 --- /dev/null +++ b/SimpleAdmin.Core/BaseInput/BasePageInput.cs @@ -0,0 +1,70 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 全局分页查询输入参数 +/// +public class BasePageInput : IValidatableObject +{ + /// + /// 当前页码 + /// + [DataValidation(ValidationTypes.Numeric)] + public virtual int PageNum { get; set; } = 1; + + /// + /// 每页条数 + /// + [Range(1, 100, ErrorMessage = "页码容量超过最大限制")] + [DataValidation(ValidationTypes.Numeric)] + public virtual int PageSize { get; set; } = 10; + + /// + /// 排序字段 + /// + public virtual string SortField { get; set; } + + /// + /// 排序方式,升序:ascend;降序:descend" + /// + public virtual string SortOrder { get; set; } = "desc"; + + /// + /// 关键字 + /// + public virtual string SearchKey { get; set; } + + public IEnumerable Validate(ValidationContext validationContext) + { + //配合小诺排序参数 + if (SortOrder == "descend") + { + SortOrder = "desc"; + } + else if (SortOrder == "ascend") + { + SortOrder = "asc"; + } + if (!string.IsNullOrEmpty(SortField)) + { + //分割排序字段 + var fields = SortField.Split(" "); + if (fields.Length > 1) + { + yield return new ValidationResult("排序字段错误", new[] + { + nameof(SortField) + }); + } + } + } +} diff --git a/SimpleAdmin.Core/BaseOutput/BaseSelectorOutput.cs b/SimpleAdmin.Core/BaseOutput/BaseSelectorOutput.cs new file mode 100644 index 0000000..ad0bf49 --- /dev/null +++ b/SimpleAdmin.Core/BaseOutput/BaseSelectorOutput.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 基础选择器输出 +/// +public class BaseSelectorOutput +{ + /// + /// 值 + /// + public dynamic Value { get; set; } + + /// + /// 显示文本 + /// + public string Label { get; set; } +} diff --git a/SimpleAdmin.Core/Components/GzipCompressionComponent.cs b/SimpleAdmin.Core/Components/GzipCompressionComponent.cs new file mode 100644 index 0000000..0366d6f --- /dev/null +++ b/SimpleAdmin.Core/Components/GzipCompressionComponent.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// Gzip压缩组件 +/// +public sealed class GzipCompressionComponent : IServiceComponent +{ + public void Load(IServiceCollection services, ComponentContext componentContext) + { + services.Configure(options => { options.Level = CompressionLevel.Optimal; }); + services.Configure(options => { options.Level = CompressionLevel.Optimal; }); + services.AddResponseCompression(options => + { + options.EnableForHttps = true; + options.Providers.Add(); + options.Providers.Add(); + options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] + { + "text/html; charset=utf-8", "application/xhtml+xml", "application/atom+xml", "image/svg+xml" + }); + }); + } +} diff --git a/SimpleAdmin.Core/Components/LoggingConsoleComponent.cs b/SimpleAdmin.Core/Components/LoggingConsoleComponent.cs new file mode 100644 index 0000000..bdc2bdf --- /dev/null +++ b/SimpleAdmin.Core/Components/LoggingConsoleComponent.cs @@ -0,0 +1,147 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 日志写入文件的组件 +/// +public sealed class LoggingConsoleComponent : IServiceComponent +{ + private readonly LoggingSetting _loggingSetting = App.GetConfig("Logging", true); + private readonly string _monitorName = "System.Logging.LoggingMonitor"; + + public void Load(IServiceCollection services, ComponentContext componentContext) + { + services.AddConsoleFormatter(options => + { + options.MessageFormat = logMsg => + { + //如果不是LoggingMonitor日志或者开启了格式化才格式化 + if (logMsg.LogName != _monitorName && _loggingSetting.MessageFormat) + { + var stringBuilder = new StringBuilder(); + stringBuilder.AppendLine("【日志级别】:" + logMsg.LogLevel); + stringBuilder.AppendLine("【日志类名】:" + logMsg.LogName); + stringBuilder.AppendLine("【日志时间】:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); + stringBuilder.AppendLine("【日志内容】:" + logMsg.Message); + if (logMsg.Exception != null) + { + stringBuilder.AppendLine("【异常信息】:" + logMsg.Exception); + } + return stringBuilder.ToString(); + } + return logMsg.Message; + }; + options.WriteHandler = (logMsg, scopeProvider, writer, + fmtMsg, opt) => + { + if (logMsg.LogName == _monitorName && !_loggingSetting.Monitor.Console) return; + var consoleColor = ConsoleColor.White; + switch (logMsg.LogLevel) + { + case LogLevel.Information: + consoleColor = ConsoleColor.DarkGreen; + break; + + case LogLevel.Warning: + consoleColor = ConsoleColor.DarkYellow; + break; + + case LogLevel.Error: + consoleColor = ConsoleColor.DarkRed; + break; + } + writer.WriteWithColor(fmtMsg, ConsoleColor.Black, consoleColor); + }; + }); + } +} + +public static class TextWriterExtensions +{ + private const string DEFAULT_FOREGROUND_COLOR = "\x1B[39m\x1B[22m"; + private const string DEFAULT_BACKGROUND_COLOR = "\x1B[49m"; + + public static void WriteWithColor(this TextWriter textWriter, string message, ConsoleColor? background, + ConsoleColor? foreground) + { + // Order: + // 1. background color + // 2. foreground color + // 3. message + // 4. reset foreground color + // 5. reset background color + + var backgroundColor = background.HasValue ? GetBackgroundColorEscapeCode(background.Value) : null; + var foregroundColor = foreground.HasValue ? GetForegroundColorEscapeCode(foreground.Value) : null; + + if (backgroundColor != null) + { + textWriter.Write(backgroundColor); + } + if (foregroundColor != null) + { + textWriter.Write(foregroundColor); + } + + textWriter.WriteLine(message); + + if (foregroundColor != null) + { + textWriter.Write(DEFAULT_FOREGROUND_COLOR); + } + if (backgroundColor != null) + { + textWriter.Write(DEFAULT_BACKGROUND_COLOR); + } + } + + private static string GetForegroundColorEscapeCode(ConsoleColor color) + { + return color switch + { + ConsoleColor.Black => "\x1B[30m", + ConsoleColor.DarkRed => "\x1B[31m", + ConsoleColor.DarkGreen => "\x1B[32m", + ConsoleColor.DarkYellow => "\x1B[33m", + ConsoleColor.DarkBlue => "\x1B[34m", + ConsoleColor.DarkMagenta => "\x1B[35m", + ConsoleColor.DarkCyan => "\x1B[36m", + ConsoleColor.Gray => "\x1B[37m", + ConsoleColor.Red => "\x1B[1m\x1B[31m", + ConsoleColor.Green => "\x1B[1m\x1B[32m", + ConsoleColor.Yellow => "\x1B[1m\x1B[33m", + ConsoleColor.Blue => "\x1B[1m\x1B[34m", + ConsoleColor.Magenta => "\x1B[1m\x1B[35m", + ConsoleColor.Cyan => "\x1B[1m\x1B[36m", + ConsoleColor.White => "\x1B[1m\x1B[37m", + + _ => DEFAULT_FOREGROUND_COLOR + }; + } + + private static string GetBackgroundColorEscapeCode(ConsoleColor color) + { + return color switch + { + ConsoleColor.Black => "\x1B[40m", + ConsoleColor.DarkRed => "\x1B[41m", + ConsoleColor.DarkGreen => "\x1B[42m", + ConsoleColor.DarkYellow => "\x1B[43m", + ConsoleColor.DarkBlue => "\x1B[44m", + ConsoleColor.DarkMagenta => "\x1B[45m", + ConsoleColor.DarkCyan => "\x1B[46m", + ConsoleColor.Gray => "\x1B[47m", + + _ => DEFAULT_BACKGROUND_COLOR + }; + } +} diff --git a/SimpleAdmin.Core/Components/LoggingFileComponent.cs b/SimpleAdmin.Core/Components/LoggingFileComponent.cs new file mode 100644 index 0000000..990d0b3 --- /dev/null +++ b/SimpleAdmin.Core/Components/LoggingFileComponent.cs @@ -0,0 +1,99 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System.Runtime.InteropServices; + +namespace SimpleAdmin.Core; + +/// +/// 日志写入文件的组件 +/// +public sealed class LoggingFileComponent : IServiceComponent +{ + private readonly LoggingSetting _loggingSetting = App.GetConfig("Logging", true); + private readonly string _monitorName = "System.Logging.LoggingMonitor"; + + public void Load(IServiceCollection services, ComponentContext componentContext) + { + //获取默认日志等级 + var defaultLevel = (LogLevel)Enum.Parse(typeof(LogLevel), _loggingSetting.LogLevel.Default); + //获取最大日志等级,默认Error + var maxLevel = (LogLevel)Enum.Parse(typeof(LogLevel), _loggingSetting.LogLevel.MaxLevel); + //获取程序根目录 + // var rootPath = App.HostEnvironment.ContentRootPath; + //遍历日志等级 + foreach (LogLevel level in Enum.GetValues(typeof(LogLevel))) + { + //如果日志等级是默认等级和最大等级之间 + if (level >= defaultLevel && level != LogLevel.None && level <= maxLevel) + { + //每天创建一个日志文件 + services.AddLogging(builder => + { + var fileName = "logs/" + level + "/{0:yyyy}-{0:MM}-{0:dd}.log"; + builder.AddFile(fileName, options => + { + SetLogOptions(options, level);//日志格式化 + }); + }); + } + } + } + + /// + /// 日志格式化 + /// + /// + /// + private void SetLogOptions(FileLoggerOptions options, LogLevel? logLevel) + { + //每天创建一个日志文件 + var rootPath = App.HostEnvironment.ContentRootPath; + if (logLevel != null)//如果日志等级不为空 + { + //过滤日志等级 + options.WriteFilter = logMsg => + { + //如果配置不写入monitor日志和日志名称为System.Logging.LoggingMonitor + if (!_loggingSetting.Monitor.Write && logMsg.LogName == _monitorName) + return false; + return logMsg.LogLevel == logLevel; + }; + } + //定义日志文件名 + options.FileNameRule = fileName => + { + var pathSeparator = @"\"; + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + pathSeparator = "/";//为linux或bsd时修改路径 + return rootPath + pathSeparator + string.Format(fileName, DateTime.UtcNow); + }; + options.FileSizeLimitBytes = 500000 * 1024;//日志最大500M + if (_loggingSetting.MessageFormat) + { + //日志内容格式化 + options.MessageFormat = logMsg => + { + var stringBuilder = new StringBuilder(); + stringBuilder.AppendLine("【日志级别】:" + logMsg.LogLevel); + stringBuilder.AppendLine("【日志类名】:" + logMsg.LogName); + stringBuilder.AppendLine("【日志时间】:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); + stringBuilder.AppendLine("【日志内容】:" + logMsg.Message); + if (logMsg.Exception != null) + { + stringBuilder.AppendLine("【异常信息】:" + logMsg.Exception); + } + return stringBuilder.ToString(); + }; + } + } +} diff --git a/SimpleAdmin.Core/Const/CacheConst.cs b/SimpleAdmin.Core/Const/CacheConst.cs new file mode 100644 index 0000000..cf526af --- /dev/null +++ b/SimpleAdmin.Core/Const/CacheConst.cs @@ -0,0 +1,47 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// Redis常量 +/// +public class CacheConst +{ + /// + /// Redis Key前缀(可删除) + /// + public const string CACHE_PREFIX_WEB = "SimpleAdminWeb:"; + + /// + /// Redis Key前缀(需要持久化,不随系统重启删除) + /// + public const string CACHE_PREFIX = "SimpleAdmin:"; + + /// + /// Redis Hash类型 + /// + public const string CACHE_HASH = "Hash"; + + /// + /// 用户Token缓存Key + /// + public const string CACHE_USER_TOKEN = CACHE_PREFIX + "UserToken"; + + + #region 消息中心队列key + + /// + /// 通知消息队列 + /// + public const string CACHE_NOTIFICATION = CACHE_PREFIX + "MsgNotification"; + + #endregion +} diff --git a/SimpleAdmin.Core/Const/ClaimConst.cs b/SimpleAdmin.Core/Const/ClaimConst.cs new file mode 100644 index 0000000..2a05cd0 --- /dev/null +++ b/SimpleAdmin.Core/Const/ClaimConst.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 授权用户常量 +/// +public class ClaimConst +{ + /// + /// 用户Id + /// + public const string USER_ID = "USER_ID"; + + /// + /// 账号 + /// + public const string ACCOUNT = "ACCOUNT"; + + /// + /// 名称 + /// + public const string NAME = "NAME"; + + /// + /// 账号类型 + /// + public const string IS_SUPER_ADMIN = "IS_SUPER_ADMIN"; + + /// + /// 组织机构Id + /// + public const string ORG_ID = "ORG_ID"; + + public const string TENANT_ID = "TENANT_ID"; +} diff --git a/SimpleAdmin.Core/Const/MqttConst.cs b/SimpleAdmin.Core/Const/MqttConst.cs new file mode 100644 index 0000000..e30a351 --- /dev/null +++ b/SimpleAdmin.Core/Const/MqttConst.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +public class MqttConst +{ + /// + /// mqtt认证登录信息key + /// + public const string CACHE_MQTT_CLIENT_USER = CacheConst.CACHE_PREFIX_WEB + "MqttClientUser:"; + + /// + /// mqtt主题前缀 + /// + public const string MQTT_TOPIC_PREFIX = "SimpleAdmin/"; + + + /// + /// 登出 + /// + public const string MQTT_MESSAGE_LOGIN_OUT = "LoginOut"; + + /// + /// 新消息 + /// + public const string MQTT_MESSAGE_NEW = "NewMessage"; + + /// + /// 修改密码 + /// + public const string MQTT_MESSAGE_UPDATE_PASSWORD = "UpdatePassword"; +} diff --git a/SimpleAdmin.Core/Const/SimpleAdminConst.cs b/SimpleAdmin.Core/Const/SimpleAdminConst.cs new file mode 100644 index 0000000..74e3e7d --- /dev/null +++ b/SimpleAdmin.Core/Const/SimpleAdminConst.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +public class SimpleAdminConst +{ + /// + /// 0 + /// + public const int ZERO = 0; +} diff --git a/SimpleAdmin.Core/Core.Development.json b/SimpleAdmin.Core/Core.Development.json new file mode 100644 index 0000000..da69914 --- /dev/null +++ b/SimpleAdmin.Core/Core.Development.json @@ -0,0 +1,25 @@ +{ + //秘钥配置 + "Cryptogram": { + //SM2国密配置 + "SM2": { + "PublicKey": "04BD62406DF6789B1FBE8C457AECAE6D7C806CDB39316F190519905C24DF395E8952C47798D76ADECF8CA28C935702AFCDD9B17DE77121FA6448F0EDEFBD8365D6", //公钥 + "PrivateKey": "00F908E5ED9C2059A960E3A58056F69E0CF75299182CEB93B74CD1FDC633FCA0E5" //私钥 + } + }, + //日志配置 + "Logging": { + "Monitor": { + "Write": false, //是否文件写入LoggingMonitor日志 + "Console": false, //是否控制台输出LoggingMonitor日志 + }, + "MessageFormat": true, //是否格式化日志 + "LogLevel": { + "Default": "Debug", //默认日志级别 + "Max": "Error", //最大日志级别 + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information" + } + } +} \ No newline at end of file diff --git a/SimpleAdmin.Core/Core.Production.json b/SimpleAdmin.Core/Core.Production.json new file mode 100644 index 0000000..33595b5 --- /dev/null +++ b/SimpleAdmin.Core/Core.Production.json @@ -0,0 +1,25 @@ +{ + //秘钥配置 + "Cryptogram": { + //SM2国密配置 + "SM2": { + "PublicKey": "04BD62406DF6789B1FBE8C457AECAE6D7C806CDB39316F190519905C24DF395E8952C47798D76ADECF8CA28C935702AFCDD9B17DE77121FA6448F0EDEFBD8365D6", //公钥 + "PrivateKey": "00F908E5ED9C2059A960E3A58056F69E0CF75299182CEB93B74CD1FDC633FCA0E5" //私钥 + } + }, + //日志配置 + "Logging": { + "Monitor": { + "Write": false, //是否文件写入LoggingMonitor日志 + "Console": false, //是否控制台输出LoggingMonitor日志 + }, + "MessageFormat": true, //是否格式化日志 + "LogLevel": { + "Default": "Information", //默认日志级别 + "Max": "Error", //最大日志级别 + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information" + } + } +} \ No newline at end of file diff --git a/SimpleAdmin.Core/Dto/MqttMessage.cs b/SimpleAdmin.Core/Dto/MqttMessage.cs new file mode 100644 index 0000000..7ef5b18 --- /dev/null +++ b/SimpleAdmin.Core/Dto/MqttMessage.cs @@ -0,0 +1,48 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// mqtt消息 +/// +public class MqttMessage +{ + /// + /// 消息分类 + /// + public string MsgType { get; set; } + + /// + /// 消息内容 + /// + public MessageData Data { get; set; } + + /// + /// 时间 + /// + public DateTime DetTime { get; set; } = DateTime.Now; +} + +/// +/// 消息格式 +/// +public class MessageData +{ + /// + /// 主题 + /// + public string Subject { get; set; } + + /// + /// 内容 + /// + public string Content { get; set; } +} diff --git a/SimpleAdmin.Core/Dto/TokenInfo.cs b/SimpleAdmin.Core/Dto/TokenInfo.cs new file mode 100644 index 0000000..caabfae --- /dev/null +++ b/SimpleAdmin.Core/Dto/TokenInfo.cs @@ -0,0 +1,57 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// Token信息 +/// +public class TokenInfo +{ + /// + /// MQTT客户端ID列表 + /// + public List ClientIds { get; set; } = new List(); + + /// + /// 设备 + /// + public string Device { get; set; } + + /// + /// 登录端 + /// + public LoginClientTypeEnum LoginClientType { get; set; } + + /// + /// 过期时间 + /// + public int Expire { get; set; } + + /// + /// Token + /// + public string Token { get; set; } + + /// + /// 超时时间 + /// + public DateTime TokenTimeout { get; set; } + + /// + /// token剩余有效期 + /// + public string TokenRemain { get; set; } + + /// + /// token剩余有效期百分比 + /// + public double TokenRemainPercent { get; set; } +} diff --git a/SimpleAdmin.Core/Enum/Auth/AuthDeviceTypeEnum.cs b/SimpleAdmin.Core/Enum/Auth/AuthDeviceTypeEnum.cs new file mode 100644 index 0000000..a3de0ec --- /dev/null +++ b/SimpleAdmin.Core/Enum/Auth/AuthDeviceTypeEnum.cs @@ -0,0 +1,35 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 登录设备类型枚举 +/// +public enum AuthDeviceTypeEnum +{ + /// + /// PC端 + /// + [Description("PC端")] + PC, + + /// + /// 移动端 + /// + [Description("移动端")] + APP, + + /// + /// 小程序 + /// + [Description("小程序")] + MINI +} diff --git a/SimpleAdmin.Core/Enum/Auth/LoginClientTypeEnum.cs b/SimpleAdmin.Core/Enum/Auth/LoginClientTypeEnum.cs new file mode 100644 index 0000000..b24ac3e --- /dev/null +++ b/SimpleAdmin.Core/Enum/Auth/LoginClientTypeEnum.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 登录端类型枚举 +/// +public enum LoginClientTypeEnum +{ + /// + /// B端 + /// + [Description("B端")] + B, + + /// + /// C端 + /// + [Description("C端")] + C +} diff --git a/SimpleAdmin.Core/Enum/ErrorCodeEnum.cs b/SimpleAdmin.Core/Enum/ErrorCodeEnum.cs new file mode 100644 index 0000000..7000797 --- /dev/null +++ b/SimpleAdmin.Core/Enum/ErrorCodeEnum.cs @@ -0,0 +1,48 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 通用错误码 +/// +[ErrorCodeType] +public enum ErrorCodeEnum +{ + /// + /// 系统异常 + /// + [ErrorCodeItemMetadata("系统异常")] + A0000, + + /// + /// 数据不存在 + /// + [ErrorCodeItemMetadata("数据不存在")] + A0001, + + /// + /// 删除失败 + /// + [ErrorCodeItemMetadata("删除失败")] + A0002, + + /// + /// 操作失败 + /// + [ErrorCodeItemMetadata("操作失败")] + A0003, + + /// + /// 没有权限 + /// + [ErrorCodeItemMetadata("没有权限")] + A0004 +} diff --git a/SimpleAdmin.Core/Extension/LinqExtension.cs b/SimpleAdmin.Core/Extension/LinqExtension.cs new file mode 100644 index 0000000..59aa4c8 --- /dev/null +++ b/SimpleAdmin.Core/Extension/LinqExtension.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Extension; + +/// +/// Linq扩展 +/// +[SuppressSniffer] +public static class LinqExtension +{ + /// + /// 是否都包含 + /// + /// + /// 第一个列表 + /// 第二个列表 + /// + public static bool ContainsAll(this List first, List? second) + { + return second.All(s => first.Any(f => f.Equals(s))); + } +} diff --git a/SimpleAdmin.Core/Extension/ObjectExtension.cs b/SimpleAdmin.Core/Extension/ObjectExtension.cs new file mode 100644 index 0000000..01123e8 --- /dev/null +++ b/SimpleAdmin.Core/Extension/ObjectExtension.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// object拓展 +/// +public static class ObjectExtension +{ + /// + /// json字符串序列化 + /// + /// + /// + public static object ToObject(this string json) + { + return string.IsNullOrEmpty(json) ? null : JsonConvert.DeserializeObject(json); + } + + /// + /// json字符串序列化 + /// + /// + /// + /// + public static T ToObject(this string json) + { + if (json != null) + { + json = json.Replace(" ", ""); + return JsonConvert.DeserializeObject(json); + } + return default; + } + + /// + /// json字符串序列化 + /// + /// + /// + public static JObject ToJObject(this string json) + { + return json == null ? JObject.Parse("{}") : JObject.Parse(json.Replace(" ", "")); + } +} diff --git a/SimpleAdmin.Core/GlobalUsings.cs b/SimpleAdmin.Core/GlobalUsings.cs new file mode 100644 index 0000000..aa2fa71 --- /dev/null +++ b/SimpleAdmin.Core/GlobalUsings.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +global using MoYu; +global using MoYu.DataValidation; +global using MoYu.DependencyInjection; +global using MoYu.FriendlyException; +global using MoYu.Logging; +global using Microsoft.AspNetCore.Builder; +global using Microsoft.AspNetCore.Hosting; +global using Microsoft.AspNetCore.Http; +global using Microsoft.AspNetCore.Mvc; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Logging; +global using System; +global using System.Collections.Generic; +global using System.ComponentModel; +global using System.ComponentModel.DataAnnotations; +global using System.IO; +global using System.Linq; +global using System.Text; +global using System.Threading.Tasks; +global using Yitter.IdGenerator; +global using Microsoft.AspNetCore.ResponseCompression; +global using System.IO.Compression; +global using Newtonsoft.Json; +global using Newtonsoft.Json.Linq; +global using MoYu.UnifyResult; +global using Microsoft.AspNetCore.Mvc.Filters; +global using Lazy.Captcha.Core; +global using Lazy.Captcha.Core.Generator.Image; +global using Lazy.Captcha.Core.Generator.Image.Option; +global using Org.BouncyCastle.Utilities.Encoders; +global using Org.BouncyCastle.Crypto.Digests; +global using Org.BouncyCastle.Crypto.Generators; +global using Org.BouncyCastle.Crypto.Parameters; +global using Org.BouncyCastle.Math; +global using Org.BouncyCastle.Math.EC; +global using Org.BouncyCastle.Security; +global using SkiaSharp; +global using System.Drawing; +global using System.Drawing.Drawing2D; +global using ICSharpCode.SharpZipLib.Checksum; +global using ICSharpCode.SharpZipLib.Zip; +global using System.Net; +global using NewLife; diff --git a/SimpleAdmin.Core/Options/BaseOptions.cs b/SimpleAdmin.Core/Options/BaseOptions.cs new file mode 100644 index 0000000..2ab4988 --- /dev/null +++ b/SimpleAdmin.Core/Options/BaseOptions.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 默认业务配置 +/// +public class BaseOptions +{ + /// + /// 初始化表 + /// + public bool InitTable { get; set; } = false; + + /// + /// 初始化数据 + /// + public bool InitSeedData { get; set; } = false; +} diff --git a/SimpleAdmin.Core/Options/LoggingSetting.cs b/SimpleAdmin.Core/Options/LoggingSetting.cs new file mode 100644 index 0000000..5165f2f --- /dev/null +++ b/SimpleAdmin.Core/Options/LoggingSetting.cs @@ -0,0 +1,64 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 日志配置 +/// +public class LoggingSetting +{ + /// + /// LoggingMonitor配置 + /// + public MonitorOptions Monitor { get; set; } + + /// + /// 是否日志消息格式化 + /// + public bool MessageFormat { get; set; } + + /// + /// 日志等级 + /// + public LogLevelOptions LogLevel { get; set; } + + /// + /// LoggingMonitor配置 + /// + public class MonitorOptions + { + /// + /// 写入文件 + /// + public bool Write { get; set; } + + /// + /// 写入控制台 + /// + public bool Console { get; set; } + } + + /// + /// 日志等级 + /// + public class LogLevelOptions + { + /// + /// 默认日志等级 + /// + public string Default { get; set; } + + /// + /// 最大日志等级 + /// + public string MaxLevel { get; set; } = "Error"; + } +} diff --git a/SimpleAdmin.Core/SimpleAdmin.Core.csproj b/SimpleAdmin.Core/SimpleAdmin.Core.csproj new file mode 100644 index 0000000..131498a --- /dev/null +++ b/SimpleAdmin.Core/SimpleAdmin.Core.csproj @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + \ No newline at end of file diff --git a/SimpleAdmin.Core/SimpleAdmin.Core.xml b/SimpleAdmin.Core/SimpleAdmin.Core.xml new file mode 100644 index 0000000..fa27763 --- /dev/null +++ b/SimpleAdmin.Core/SimpleAdmin.Core.xml @@ -0,0 +1,1294 @@ + + + + SimpleAdmin.Core + + + + + 代码生成 + + + + + 忽略初始化表 + + + + + 种子数据忽略新增 + + + + + 种子数据忽略修改 + + + + + 需要角色授权权限 + + + + + 忽略角色授权权限 + + + + + 管理员才能访问特性 + + + + + 忽略超级管理员才能访问特性 + + + + + 验证Id不能为 空 + + + + + 验证Id列表不能为空 + + + + + 文件上传输入参数 + + + + + 文件 + + + + + 主键Id输入参数 + + + + + 主键Id + + + + + 主键Id列表 + + + + + Id列表输入 + + + + + 全局分页查询输入参数 + + + + + 当前页码 + + + + + 每页条数 + + + + + 排序字段 + + + + + 排序方式,升序:ascend;降序:descend" + + + + + 关键字 + + + + + 基础选择器输出 + + + + + 值 + + + + + 显示文本 + + + + + Gzip压缩组件 + + + + + 日志写入文件的组件 + + + + + 日志写入文件的组件 + + + + + 日志格式化 + + + + + + + Redis常量 + + + + + Redis Key前缀(可删除) + + + + + Redis Key前缀(需要持久化,不随系统重启删除) + + + + + Redis Hash类型 + + + + + 用户Token缓存Key + + + + + 通知消息队列 + + + + + 授权用户常量 + + + + + 用户Id + + + + + 账号 + + + + + 名称 + + + + + 账号类型 + + + + + 组织机构Id + + + + + mqtt认证登录信息key + + + + + mqtt主题前缀 + + + + + 登出 + + + + + 新消息 + + + + + 修改密码 + + + + + 0 + + + + + mqtt消息 + + + + + 消息分类 + + + + + 消息内容 + + + + + 时间 + + + + + 消息格式 + + + + + 主题 + + + + + 内容 + + + + + Token信息 + + + + + MQTT客户端ID列表 + + + + + 设备 + + + + + 登录端 + + + + + 过期时间 + + + + + Token + + + + + 超时时间 + + + + + token剩余有效期 + + + + + token剩余有效期百分比 + + + + + 登录设备类型枚举 + + + + + PC端 + + + + + 移动端 + + + + + 小程序 + + + + + 登录端类型枚举 + + + + + B端 + + + + + C端 + + + + + 通用错误码 + + + + + 系统异常 + + + + + 数据不存在 + + + + + 删除失败 + + + + + 操作失败 + + + + + 没有权限 + + + + + Linq扩展 + + + + + 是否都包含 + + + 第一个列表 + 第二个列表 + + + + + object拓展 + + + + + json字符串序列化 + + + + + + + json字符串序列化 + + + + + + + + json字符串序列化 + + + + + + + 默认业务配置 + + + + + 初始化表 + + + + + 初始化数据 + + + + + 日志配置 + + + + + LoggingMonitor配置 + + + + + 是否日志消息格式化 + + + + + 日志等级 + + + + + LoggingMonitor配置 + + + + + 写入文件 + + + + + 写入控制台 + + + + + 日志等级 + + + + + 默认日志等级 + + + + + 最大日志等级 + + + + + AppStartup启动类 + + + + + 全局返回结果 + + + + + + 状态码 + + + + + 错误信息 + + + + + 数据 + + + + + 附加数据 + + + + + 时间 + + + + + 规范化RESTful风格返回值 + + + + + 异常返回 + + + + + + + + 成功返回 + + + + + + + + 验证失败返回 + + + + + + + + 状态码响应拦截 + + + + + + + + + 返回 RESTful 风格结果集 + + 状态码 + 是否成功 + 数据 + 错误信息 + + + + + 验证码信息 + + + + + 验证码 + + + + + 验证码数据流 + + + + + base64 + + + + + 验证码类型 + + + + + 纯数字验证码 + + + + + 数字加字母验证码 + + + + + 数字运算验证码 + + + + + 生成验证码功能 + + + + + 获取验证码 + + 验证码数 + 长度 + 高度 + 字体大小 + 类型 0:数字 1:字符 2:计算 + + + + + 获取数字验证码 + + 验证码数 + + + + + 获取字符验证码 + + 验证码数 + + + + + 获取运算符验证码 + + + + + + 公共功能 + + + + + 获取唯一Id + + + + + + 加解密功能 + + + + + SM2解密 + + 密文 + 明文 + + + + SM2加密 + + 明文 + 密文 + + + + SM4解密 + + 密文 + 明文 + + + + SM4加密 + + 明文 + 密文 + + + + SM2加密解密 + + + + + 公钥 + + + + + 私钥 + + + + + 公钥加密明文 + + 明文 + 密文 + + + + 私钥解密密文 + + 密文 + 明文 + + + + Sm4算法 + 对标国际DES算法 + + + + + 数据 + + + + + 秘钥 + + + + + 向量 + + + + + 明文是否是十六进制 + + + + + 加密模式(默认ECB) + 统一改为ECB模式 + + + + + ECB加密 + + + + + + + CBC加密 + + + + + + + 解密 + + + + + + + ECB解密 + + + + + + + CBC解密 + + + + + + + 加密类型 + + + + + ECB(电码本模式) + + + + + CBC(密码分组链接模式) + + + + + SM2工具类 + + + + + 获取公钥私钥 + + + + + + 加密 + + 公钥 + 需要加密的值 + 加密结果 + + + + 加密 + + 公钥 + 需要加密的值 + + + + + + + + + + + + + 解密 + + + + + + + + 公钥 + + + + + 私钥 + + + + + SM4工具类 + + + + + 加密 非线性τ函数B=τ(A) + + + + + + + + 解密 非线性τ函数B=τ(A) + + + + + + + + 循环移位,为32位的x循环左移n位 + + + + + + + + 将密钥逆序 + + + + + + + S盒 + + + + + 系统参数FK + + + + + 固定参数CK + + + + + Sm4的S盒取值 + + + + + + + 线性变换 L + + + + + + + 轮函数 F + + + + + + + + + + + 轮密钥rk + + + + + + + 加密密钥 + + + + + + + 解密函数 + + 轮密钥 + 输入分组的密文 + 输出的对应的分组明文 + + + + 补足 16 进制字符串的 0 字符,返回不带 0x 的16进制字符串 + + + 1表示加密,0表示解密 + + + + + 设置加密的key + + + + + + + 设置解密的key + + + + + + + ECB + + + + + + + + CBC + + + + + + + + + SM4处理中心 + + + + + 1表示加密,0表示解密 + + + + + 密钥 + + + + + 是否补足16进制字符串 + + + + + 头像功能 + + + + + 获取姓名对应的颜色值 + + + + + + + 获取姓名对应的图片 + + + + + + + + + 获取图片base64格式 + + 名称 + 宽 + 高 + + + + + 用 正则表达式 判断字符是不是汉字 + + 待判断字符或字符串 + 真:是汉字;假:不是 + + + + 图片转换成base64 + + + + + + + 图片转换成base64 + + + + + + + base64转bitmap + + + + + + + base64转bitmap + + + + + + + base64转image格式 + + + + + + + 重新修改尺寸 + + 图片 + 尺寸 + + + + + Resize图片 + + 原始Bitmap + 新的宽度 + 新的高度 + 处理以后的图片 + + + + Resize图片 + + 原始Bitmap + 新的宽度 + 新的高度 + 处理以后的图片 + + + + 获取缩略图 + + + 宽 + 高 + + + + + 获取缩略图 + + + 宽 + 高 + + + + + 密码相关通用类 + + + + + 密码相似度 + + + + + + + + 计算莱文斯坦距离算法 + + + + + + + + 压缩单个文件 + + 要压缩的文件 + 压缩后的文件 + 压缩等级 + 每次写入大小 + + + + 压缩单个文件 + + 要进行压缩的文件名 + 压缩后生成的压缩文件名 + + + + 压缩多个文件到指定路径 + + 压缩到哪个路径 + 压缩文件名称 + + + + 压缩多层目录 + + 待压缩目录 + 压缩后生成的压缩文件名,绝对路径 + + + + 压缩多层目录 + + 待压缩目录 + 压缩后生成的压缩文件名,绝对路径 + 指定要压缩的文件列表(完全路径) + + + + 递归遍历目录 + + 需遍历的目录 + 压缩输出流对象 + The parent path. + 需要压缩的文件 + + + + 解压缩一个 zip 文件。 + + 压缩文件 + 解压目录 + zip 文件的密码。 + 是否覆盖已存在的文件。 + + + + 解压缩一个 zip 文件。 + + 压缩文件 + 解压目录 + 是否覆盖已存在的文件。 + + + + 解压缩一个 zip 文件。 + 覆盖已存在的文件。 + + 压缩文件 + 解压目录 + + + + 获取压缩文件中指定类型的文件 + + 压缩文件 + 文件类型(.txt|.exe) + 文件名称列表(包含子目录) + + + + 获取压缩文件中的所有文件 + + 压缩文件 + 文件名称列表(包含子目录) + + + + 打包线上线下文件 + + 压缩文件名称 + 文件列表 + 保存路径 + 是否本地 + + + 压缩文件夹 + 要打包的文件夹 + 是否删除原文件夹 + + + + 获取所有文件 + + + + + + 获取一个文件夹下的所有文件夹里的文件 + + + + + + + 获取一个文件夹下的文件 + + 目录名称 + 文件列表HastTable + + + + 文件对象 + + + + + 文件名称 + + + + + 文件路径 + + + + diff --git a/SimpleAdmin.Core/Startup.cs b/SimpleAdmin.Core/Startup.cs new file mode 100644 index 0000000..32b127f --- /dev/null +++ b/SimpleAdmin.Core/Startup.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using SimpleAdmin.Core.Utils; + +namespace SimpleAdmin.Core; + +/// +/// AppStartup启动类 +/// +[AppStartup(99)] +public class Startup : AppStartup +{ + public void ConfigureServices(IServiceCollection services) + { + services.AddComponent();//启动控制台日志格式化组件 + services.AddComponent();//启动日志写入文件组件 + + // 配置雪花Id算法机器码 + YitIdHelper.SetIdGenerator(new IdGeneratorOptions + { + WorkerId = 1// 取值范围0~63,默认1 + }); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + } +} diff --git a/SimpleAdmin.Core/UnifyResult/SimpleAdminResult.cs b/SimpleAdmin.Core/UnifyResult/SimpleAdminResult.cs new file mode 100644 index 0000000..9ac82d5 --- /dev/null +++ b/SimpleAdmin.Core/UnifyResult/SimpleAdminResult.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 全局返回结果 +/// +/// +public class SimpleAdminResult +{ + /// + /// 状态码 + /// + public int Code { get; set; } + + /// + /// 错误信息 + /// + public object Msg { get; set; } + + /// + /// 数据 + /// + public T Data { get; set; } + + /// + /// 附加数据 + /// + public object Extras { get; set; } + + /// + /// 时间 + /// + public DateTime Time { get; set; } +} diff --git a/SimpleAdmin.Core/UnifyResult/SimpleAdminResultProvider.cs b/SimpleAdmin.Core/UnifyResult/SimpleAdminResultProvider.cs new file mode 100644 index 0000000..ca38d35 --- /dev/null +++ b/SimpleAdmin.Core/UnifyResult/SimpleAdminResultProvider.cs @@ -0,0 +1,107 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core; + +/// +/// 规范化RESTful风格返回值 +/// +[SuppressSniffer] +[UnifyModel(typeof(SimpleAdminResult<>))] +public class SimpleAdminResultProvider : IUnifyResultProvider +{ + public IActionResult OnAuthorizeException(DefaultHttpContext context, ExceptionMetadata metadata) + { + return new JsonResult(ResTfulResult(metadata.StatusCode, data: metadata.Data, errors: metadata.Errors), + UnifyContext.GetSerializerSettings(context)); + } + + /// + /// 异常返回 + /// + /// + /// + /// + public IActionResult OnException(ExceptionContext context, ExceptionMetadata metadata) + { + return new JsonResult(ResTfulResult(metadata.StatusCode, data: metadata.Data, errors: metadata.Errors)); + } + + /// + /// 成功返回 + /// + /// + /// + /// + public IActionResult OnSucceeded(ActionExecutedContext context, object data) + { + return new JsonResult(ResTfulResult(StatusCodes.Status200OK, true, data)); + } + + /// + /// 验证失败返回 + /// + /// + /// + /// + public IActionResult OnValidateFailed(ActionExecutingContext context, ValidationMetadata metadata) + { + return new JsonResult(ResTfulResult(metadata.StatusCode ?? StatusCodes.Status400BadRequest, data: metadata.Data, + errors: metadata.FirstErrorMessage ?? metadata.Message)); + } + + /// + /// 状态码响应拦截 + /// + /// + /// + /// + /// + public async Task OnResponseStatusCodes(HttpContext context, int statusCode, UnifyResultSettingsOptions unifyResultSettings = null) + { + // 设置响应状态码 + UnifyContext.SetResponseStatusCodes(context, statusCode, unifyResultSettings); + + switch (statusCode) + { + // 处理 401 状态码 + case StatusCodes.Status401Unauthorized: + await context.Response.WriteAsJsonAsync(ResTfulResult(statusCode, errors: "登录已过期,请重新登录"), + App.GetOptions()?.JsonSerializerOptions); + break; + // 处理 403 状态码 + case StatusCodes.Status403Forbidden: + await context.Response.WriteAsJsonAsync(ResTfulResult(statusCode, errors: "禁止访问,没有权限", data: context.Request.Path), + App.GetOptions()?.JsonSerializerOptions); + break; + } + } + + /// + /// 返回 RESTful 风格结果集 + /// + /// 状态码 + /// 是否成功 + /// 数据 + /// 错误信息 + /// + private static SimpleAdminResult ResTfulResult(int statusCode, bool succeeded = default, object data = default, + object errors = default) + { + return new SimpleAdminResult + { + Code = statusCode, + Msg = statusCode == StatusCodes.Status200OK ? "请求成功" : errors, + Data = data, + Extras = UnifyContext.Take(), + Time = DateTime.Now + }; + } +} diff --git a/SimpleAdmin.Core/Utils/Captcha/CaptchaInfo.cs b/SimpleAdmin.Core/Utils/Captcha/CaptchaInfo.cs new file mode 100644 index 0000000..575fdb2 --- /dev/null +++ b/SimpleAdmin.Core/Utils/Captcha/CaptchaInfo.cs @@ -0,0 +1,35 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +/// +/// 验证码信息 +/// +public class CaptchaInfo +{ + /// + /// 验证码 + /// + public string Code { get; set; } + + /// + /// 验证码数据流 + /// + public byte[] Image { get; set; } + + /// + /// base64 + /// + public string Base64Str + { + get { return "data:image/png;base64," + Convert.ToBase64String(Image); } + } +} diff --git a/SimpleAdmin.Core/Utils/Captcha/CaptchaType.cs b/SimpleAdmin.Core/Utils/Captcha/CaptchaType.cs new file mode 100644 index 0000000..e08d7aa --- /dev/null +++ b/SimpleAdmin.Core/Utils/Captcha/CaptchaType.cs @@ -0,0 +1,35 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +/// +/// 验证码类型 +/// +public enum CaptchaType +{ + /// + /// 纯数字验证码 + /// + [Description("纯数字验证码")] + NUM = 0, + + /// + /// 数字加字母验证码 + /// + [Description("数字加字母验证码")] + CHAR = 1, + + /// + /// 数字运算验证码 + /// + [Description("数字运算验证码")] + ARITH = 2 +} diff --git a/SimpleAdmin.Core/Utils/Captcha/CaptchaUtil.cs b/SimpleAdmin.Core/Utils/Captcha/CaptchaUtil.cs new file mode 100644 index 0000000..48c0021 --- /dev/null +++ b/SimpleAdmin.Core/Utils/Captcha/CaptchaUtil.cs @@ -0,0 +1,142 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +/// +/// 生成验证码功能 +/// +public static class CaptchaUtil +{ + /// + /// 获取验证码 + /// + /// 验证码数 + /// 长度 + /// 高度 + /// 字体大小 + /// 类型 0:数字 1:字符 2:计算 + /// + public static CaptchaInfo CreateCaptcha(CaptchaType type = CaptchaType.CHAR, int length = 4, int width = 170, + int height = 50, int fontSize = 20) + { + //初始化验证码 + string charCode; + var resultCode = ""; + switch (type.ToString()) + { + case "NUM": + charCode = CreateNumCode(length); + break; + + case "ARITH": + charCode = CreateArithCode(out resultCode); + break; + + default: + charCode = CreateCharCode(length); + break; + } + var imageGenerator = new DefaultCaptchaImageGenerator(); + var imageGeneratorOption = new CaptchaImageGeneratorOption + { + // 必须设置 + ForegroundColors = DefaultColors.Instance.Colors, + Width = width, + Height = height, + FontSize = fontSize, + TextBold = true, + BubbleCount = 1, + FontFamily = DefaultFontFamilys.Instance.Actionj + }; + + var bytes = imageGenerator.Generate(charCode, imageGeneratorOption); + + var captchaInfo = new CaptchaInfo + { + Code = type.ToString() == "ARITH" ? resultCode : charCode, + Image = bytes + }; + return captchaInfo; + } + + /// + /// 获取数字验证码 + /// + /// 验证码数 + /// + public static string CreateNumCode(int n) + { + char[] numChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + var charCode = string.Empty; + var random = new Random(); + for (var i = 0; i < n; i++) + { + charCode += numChar[random.Next(numChar.Length)]; + } + return charCode; + } + + /// + /// 获取字符验证码 + /// + /// 验证码数 + /// + public static string CreateCharCode(int n) + { + char[] strChar = + { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' + }; + + var charCode = string.Empty; + var random = new Random(); + for (var i = 0; i < n; i++) + { + charCode += strChar[random.Next(strChar.Length)]; + } + return charCode; + } + + /// + /// 获取运算符验证码 + /// + /// + public static string CreateArithCode(out string resultCode) + { + string checkCode; + var random = new Random(); + var intFirst = random.Next(1, 10);//生成第一个数字 + var intSec = random.Next(1, 10);//生成第二个数字 + int intTemp; + switch (random.Next(1, 3).ToString()) + { + case "2": + if (intFirst < intSec) + { + intTemp = intFirst; + intFirst = intSec; + intSec = intTemp; + } + checkCode = intFirst + "-" + intSec + "="; + resultCode = (intFirst - intSec).ToString(); + break; + + default: + checkCode = intFirst + "+" + intSec + "="; + resultCode = (intFirst + intSec).ToString(); + break; + } + return checkCode; + } +} diff --git a/SimpleAdmin.Core/Utils/CommonUtils.cs b/SimpleAdmin.Core/Utils/CommonUtils.cs new file mode 100644 index 0000000..f57597b --- /dev/null +++ b/SimpleAdmin.Core/Utils/CommonUtils.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +/// +/// 公共功能 +/// +public static class CommonUtils +{ + /// + /// 获取唯一Id + /// + /// + public static long GetSingleId() + { + return YitIdHelper.NextId(); + } +} diff --git a/SimpleAdmin.Core/Utils/Cryptogram/CryptogramUtil.cs b/SimpleAdmin.Core/Utils/Cryptogram/CryptogramUtil.cs new file mode 100644 index 0000000..2c1420b --- /dev/null +++ b/SimpleAdmin.Core/Utils/Cryptogram/CryptogramUtil.cs @@ -0,0 +1,92 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +/// +/// 加解密功能 +/// +public class CryptogramUtil +{ + #region SM2 + + /// + /// SM2解密 + /// + /// 密文 + /// 明文 + public static string Sm2Decrypt(string str) + { + // 解密 + if (!string.IsNullOrWhiteSpace(str)) + return SM2Util.Decrypt(str); + try + { + // // 解密 + // if (!string.IsNullOrWhiteSpace(str)) + // return SM2Util.Decrypt(str); + } + catch + { + return ""; + } + return ""; + } + + /// + /// SM2加密 + /// + /// 明文 + /// 密文 + public static string Sm2Encrypt(string str) + { + try + { + // 加密 + if (!string.IsNullOrWhiteSpace(str)) + return SM2Util.Encrypt(str); + } + catch + { + return ""; + } + return ""; + } + + #endregion SM2 + + #region Sm4 + + /// + /// SM4解密 + /// + /// 密文 + /// 明文 + public static string Sm4Decrypt(string str) + { + if (!string.IsNullOrWhiteSpace(str))// 解密 + return SM4Util.Decrypt(new SM4Util { Data = str }); + return ""; + } + + /// + /// SM4加密 + /// + /// 明文 + /// 密文 + public static string Sm4Encrypt(string str) + { + if (!string.IsNullOrWhiteSpace(str))// 加密 + return SM4Util.Encrypt(new SM4Util { Data = str }); + return ""; + } + + #endregion Sm4 +} diff --git a/SimpleAdmin.Core/Utils/Cryptogram/SM2Util.cs b/SimpleAdmin.Core/Utils/Cryptogram/SM2Util.cs new file mode 100644 index 0000000..cad81cf --- /dev/null +++ b/SimpleAdmin.Core/Utils/Cryptogram/SM2Util.cs @@ -0,0 +1,48 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +/// +/// SM2加密解密 +/// +public class SM2Util +{ + /// + /// 公钥 + /// + public static string PublicKey = App.GetConfig("Cryptogram:SM2:PublicKey"); + + /// + /// 私钥 + /// + public static string PrivateKey = App.GetConfig("Cryptogram:SM2:PrivateKey"); + + /// + /// 公钥加密明文 + /// + /// 明文 + /// 密文 + public static string Encrypt(string plainText) + { + return SM2CryptoUtil.Encrypt(PublicKey, plainText); + } + + /// + /// 私钥解密密文 + /// + /// 密文 + /// 明文 + public static string Decrypt(string cipherText) + { + if (!cipherText.StartsWith("04")) cipherText = "04" + cipherText;//如果不是04开头加上04 + return SM2CryptoUtil.Decrypt(PrivateKey, cipherText); + } +} diff --git a/SimpleAdmin.Core/Utils/Cryptogram/SM4Util.cs b/SimpleAdmin.Core/Utils/Cryptogram/SM4Util.cs new file mode 100644 index 0000000..8103f81 --- /dev/null +++ b/SimpleAdmin.Core/Utils/Cryptogram/SM4Util.cs @@ -0,0 +1,170 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +//加密和解密结构相同,只不过,解密密钥是加密密钥的逆序 +/// +/// Sm4算法 +/// 对标国际DES算法 +/// +public class SM4Util +{ + public SM4Util() + { + Key = "1814546261730461";//密钥长度必须为16字节。 + Iv = "0000000000000000"; + HexString = false; + CryptoMode = Sm4CryptoEnum.ECB; + } + + /// + /// 数据 + /// + public string Data { get; set; } + + /// + /// 秘钥 + /// + public string Key { get; }//不同的key,加密出来的数据不一样,所以此处设定好key以后,禁止修改 + + /// + /// 向量 + /// + public string Iv { get; set; } + + /// + /// 明文是否是十六进制 + /// + public bool HexString { get; }//set; + + /// + /// 加密模式(默认ECB) + /// 统一改为ECB模式 + /// + public Sm4CryptoEnum CryptoMode { get; } + + #region 加密 + + public static string Encrypt(SM4Util entity) + { + return entity.CryptoMode == Sm4CryptoEnum.CBC ? EncryptCBC(entity) : EncryptECB(entity); + } + + /// + /// ECB加密 + /// + /// + /// + public static string EncryptECB(SM4Util entity) + { + var ctx = new Sm4Context + { + IsPadding = true + }; + var keyBytes = entity.HexString ? Hex.Decode(entity.Key) : Encoding.Default.GetBytes(entity.Key); + var sm4 = new SM4CryptoUtil(); + sm4.SetKeyEnc(ctx, keyBytes); + var encrypted = sm4.Sm4CryptEcb(ctx, Encoding.Default.GetBytes(entity.Data)); + return Encoding.Default.GetString(Hex.Encode(encrypted)); + } + + /// + /// CBC加密 + /// + /// + /// + public static string EncryptCBC(SM4Util entity) + { + var ctx = new Sm4Context + { + IsPadding = true + }; + var keyBytes = entity.HexString ? Hex.Decode(entity.Key) : Encoding.Default.GetBytes(entity.Key); + var ivBytes = entity.HexString ? Hex.Decode(entity.Iv) : Encoding.Default.GetBytes(entity.Iv); + var sm4 = new SM4CryptoUtil(); + sm4.SetKeyEnc(ctx, keyBytes); + var encrypted = sm4.Sm4CryptCbc(ctx, ivBytes, Encoding.Default.GetBytes(entity.Data)); + return Convert.ToBase64String(encrypted); + } + + #endregion 加密 + + #region 解密 + + /// + /// 解密 + /// + /// + /// + public static string Decrypt(SM4Util entity) + { + return entity.CryptoMode == Sm4CryptoEnum.CBC ? DecryptCBC(entity) : DecryptECB(entity); + } + + /// + /// ECB解密 + /// + /// + /// + public static string DecryptECB(SM4Util entity) + { + var ctx = new Sm4Context + { + IsPadding = true, + Mode = 0 + }; + var keyBytes = entity.HexString ? Hex.Decode(entity.Key) : Encoding.Default.GetBytes(entity.Key); + var sm4 = new SM4CryptoUtil(); + sm4.Sm4SetKeyDec(ctx, keyBytes); + var decrypted = sm4.Sm4CryptEcb(ctx, Hex.Decode(entity.Data)); + return Encoding.Default.GetString(decrypted); + } + + /// + /// CBC解密 + /// + /// + /// + public static string DecryptCBC(SM4Util entity) + { + var ctx = new Sm4Context + { + IsPadding = true, + Mode = 0 + }; + var keyBytes = entity.HexString ? Hex.Decode(entity.Key) : Encoding.Default.GetBytes(entity.Key); + var ivBytes = entity.HexString ? Hex.Decode(entity.Iv) : Encoding.Default.GetBytes(entity.Iv); + var sm4 = new SM4CryptoUtil(); + sm4.Sm4SetKeyDec(ctx, keyBytes); + var decrypted = sm4.Sm4CryptCbc(ctx, ivBytes, Convert.FromBase64String(entity.Data)); + return Encoding.Default.GetString(decrypted); + } + + #endregion 解密 + + /// + /// 加密类型 + /// + public enum Sm4CryptoEnum + { + /// + /// ECB(电码本模式) + /// + [Description("ECB模式")] + ECB = 0, + + /// + /// CBC(密码分组链接模式) + /// + [Description("CBC模式")] + CBC = 1 + } +} diff --git a/SimpleAdmin.Core/Utils/Cryptogram/Sm/SM2CryptoUtil.cs b/SimpleAdmin.Core/Utils/Cryptogram/Sm/SM2CryptoUtil.cs new file mode 100644 index 0000000..d8f6d2a --- /dev/null +++ b/SimpleAdmin.Core/Utils/Cryptogram/Sm/SM2CryptoUtil.cs @@ -0,0 +1,399 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +/// +/// SM2工具类 +/// +public class SM2CryptoUtil +{ + #region 获取公钥私钥 + + /// + /// 获取公钥私钥 + /// + /// + public static SM2Model GetKey() + { + var sm2 = SM2.Instance; + var key = sm2.ecc_key_pair_generator.GenerateKeyPair(); + var ecpriv = (ECPrivateKeyParameters)key.Private; + var ecpub = (ECPublicKeyParameters)key.Public; + var privateKey = ecpriv.D; + var publicKey = ecpub.Q; + var sM2Model = new SM2Model(); + sM2Model.PrivateKey = Encoding.UTF8.GetString(Hex.Encode(privateKey.ToByteArray())).ToUpper(); + sM2Model.PublicKey = Encoding.UTF8.GetString(Hex.Encode(publicKey.GetEncoded())).ToUpper(); + return sM2Model; + } + + #endregion 获取公钥私钥 + + #region 加密 + + /// + /// 加密 + /// + /// 公钥 + /// 需要加密的值 + /// 加密结果 + public static string Encrypt(string publickey, string sourceData) + { + var data = Encrypt(Hex.Decode(publickey), Encoding.UTF8.GetBytes(sourceData)); + return data; + } + + /// + /// 加密 + /// + /// 公钥 + /// 需要加密的值 + /// + public static string Encrypt(byte[] publicKey, byte[] data) + { + if (null == publicKey || publicKey.Length == 0) + { + return null; + } + if (data == null || data.Length == 0) + { + return null; + } + + var source = new byte[data.Length]; + Array.Copy(data, 0, source, 0, + data.Length); + + var cipher = new Cipher(); + var sm2 = SM2.Instance; + + var userKey = sm2.ecc_curve.DecodePoint(publicKey); + + var c1 = cipher.Init_enc(sm2, userKey); + cipher.Encrypt(source); + + var c3 = new byte[32]; + cipher.Dofinal(c3); + + var sc1 = Encoding.UTF8.GetString(Hex.Encode(c1.GetEncoded())); + var sc2 = Encoding.UTF8.GetString(Hex.Encode(source)); + var sc3 = Encoding.UTF8.GetString(Hex.Encode(c3)); + + return (sc1 + sc2 + sc3).ToUpper(); + } + + #endregion 加密 + + #region 解密 + + /// + /// + /// + /// + /// + /// + public static string Decrypt(string privateKey, string encryptedData) + { + var data = Encoding.UTF8.GetString(Decrypt(Hex.Decode(privateKey), Hex.Decode(encryptedData))); + return data; + } + + /// + /// 解密 + /// + /// + /// + /// + public static byte[] Decrypt(byte[] privateKey, byte[] encryptedData) + { + if (null == privateKey || privateKey.Length == 0) + { + return null; + } + if (encryptedData == null || encryptedData.Length == 0) + { + return null; + } + + var data = Encoding.UTF8.GetString(Hex.Encode(encryptedData)); + + var c1Bytes = Hex.Decode(Encoding.UTF8.GetBytes(data.Substring(0, 130))); + var c2Len = encryptedData.Length - 97; + var c2 = Hex.Decode(Encoding.UTF8.GetBytes(data.Substring(130, 2 * c2Len))); + var c3 = Hex.Decode(Encoding.UTF8.GetBytes(data.Substring(130 + 2 * c2Len, 64))); + + var sm2 = SM2.Instance; + var userD = new BigInteger(1, privateKey); + + //ECPoint c1 = sm2.ecc_curve.DecodePoint(c1Bytes); + + var c1 = sm2.ecc_curve.DecodePoint(c1Bytes); + var cipher = new Cipher(); + cipher.Init_dec(userD, c1); + cipher.Decrypt(c2); + cipher.Dofinal(c3); + + return c2; + } + + #endregion 解密 + + private class Cipher + { + private int ct; + private ECPoint p2; + private SM3Digest sm3keybase; + private SM3Digest sm3c3; + private byte[] key; + private byte keyOff; + + public Cipher() + { + ct = 1; + key = new byte[32]; + keyOff = 0; + } + + public static byte[] byteConvert32Bytes(BigInteger n) + { + byte[] tmpd; + if (n == null) + { + return null; + } + + if (n.ToByteArray().Length == 33) + { + tmpd = new byte[32]; + Array.Copy(n.ToByteArray(), 1, tmpd, 0, + 32); + } + else if (n.ToByteArray().Length == 32) + { + tmpd = n.ToByteArray(); + } + else + { + tmpd = new byte[32]; + for (var i = 0; i < 32 - n.ToByteArray().Length; i++) + { + tmpd[i] = 0; + } + Array.Copy(n.ToByteArray(), 0, tmpd, 32 - n.ToByteArray().Length, + n.ToByteArray().Length); + } + return tmpd; + } + + private void Reset() + { + sm3keybase = new SM3Digest(); + sm3c3 = new SM3Digest(); + + var p = byteConvert32Bytes(p2.Normalize().XCoord.ToBigInteger()); + sm3keybase.BlockUpdate(p, 0, p.Length); + sm3c3.BlockUpdate(p, 0, p.Length); + + p = byteConvert32Bytes(p2.Normalize().YCoord.ToBigInteger()); + sm3keybase.BlockUpdate(p, 0, p.Length); + ct = 1; + NextKey(); + } + + private void NextKey() + { + var sm3keycur = new SM3Digest(sm3keybase); + sm3keycur.Update((byte)(ct >> 24 & 0xff)); + sm3keycur.Update((byte)(ct >> 16 & 0xff)); + sm3keycur.Update((byte)(ct >> 8 & 0xff)); + sm3keycur.Update((byte)(ct & 0xff)); + sm3keycur.DoFinal(key, 0); + keyOff = 0; + ct++; + } + + public ECPoint Init_enc(SM2 sm2, ECPoint userKey) + { + var key = sm2.ecc_key_pair_generator.GenerateKeyPair(); + var ecpriv = (ECPrivateKeyParameters)key.Private; + var ecpub = (ECPublicKeyParameters)key.Public; + var k = ecpriv.D; + var c1 = ecpub.Q; + p2 = userKey.Multiply(k); + Reset(); + return c1; + } + + public void Encrypt(byte[] data) + { + sm3c3.BlockUpdate(data, 0, data.Length); + for (var i = 0; i < data.Length; i++) + { + if (keyOff == key.Length) + { + NextKey(); + } + data[i] ^= key[keyOff++]; + } + } + + public void Init_dec(BigInteger userD, ECPoint c1) + { + p2 = c1.Multiply(userD); + Reset(); + } + + public void Decrypt(byte[] data) + { + for (var i = 0; i < data.Length; i++) + { + if (keyOff == key.Length) + { + NextKey(); + } + data[i] ^= key[keyOff++]; + } + + sm3c3.BlockUpdate(data, 0, data.Length); + } + + public void Dofinal(byte[] c3) + { + var p = byteConvert32Bytes(p2.Normalize().YCoord.ToBigInteger()); + sm3c3.BlockUpdate(p, 0, p.Length); + sm3c3.DoFinal(c3, 0); + Reset(); + } + } + + private class SM2 + { + public static SM2 Instance + { + get + { + return new SM2(); + } + } + + public static SM2 InstanceTest + { + get + { + return new SM2(); + } + } + + public static readonly string[] sm2_param = + { + "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",// p,0 + "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",// a,1 + "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",// b,2 + "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",// n,3 + "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",// gx,4 + "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"// gy,5 + }; + + public string[] ecc_param = sm2_param; + + public readonly BigInteger ecc_p; + public readonly BigInteger ecc_a; + public readonly BigInteger ecc_b; + public readonly BigInteger ecc_n; + public readonly BigInteger ecc_gx; + public readonly BigInteger ecc_gy; + + public readonly ECCurve ecc_curve; + public readonly ECPoint ecc_point_g; + + public readonly ECDomainParameters ecc_bc_spec; + + public readonly ECKeyPairGenerator ecc_key_pair_generator; + + private SM2() + { + ecc_param = sm2_param; + + ECFieldElement ecc_gx_fieldelement; + ECFieldElement ecc_gy_fieldelement; + + ecc_p = new BigInteger(ecc_param[0], 16); + ecc_a = new BigInteger(ecc_param[1], 16); + ecc_b = new BigInteger(ecc_param[2], 16); + ecc_n = new BigInteger(ecc_param[3], 16); + ecc_gx = new BigInteger(ecc_param[4], 16); + ecc_gy = new BigInteger(ecc_param[5], 16); + + ecc_gx_fieldelement = new FpFieldElement(ecc_p, ecc_gx); + ecc_gy_fieldelement = new FpFieldElement(ecc_p, ecc_gy); + + ecc_curve = new FpCurve(ecc_p, ecc_a, ecc_b); + ecc_point_g = new FpPoint(ecc_curve, ecc_gx_fieldelement, ecc_gy_fieldelement); + + ecc_bc_spec = new ECDomainParameters(ecc_curve, ecc_point_g, ecc_n); + + ECKeyGenerationParameters ecc_ecgenparam; + ecc_ecgenparam = new ECKeyGenerationParameters(ecc_bc_spec, new SecureRandom()); + + ecc_key_pair_generator = new ECKeyPairGenerator(); + ecc_key_pair_generator.Init(ecc_ecgenparam); + } + + public virtual byte[] Sm2GetZ(byte[] userId, ECPoint userKey) + { + var sm3 = new SM3Digest(); + byte[] p; + // userId length + var len = userId.Length * 8; + sm3.Update((byte)(len >> 8 & 0x00ff)); + sm3.Update((byte)(len & 0x00ff)); + + // userId + sm3.BlockUpdate(userId, 0, userId.Length); + + // a,b + p = ecc_a.ToByteArray(); + sm3.BlockUpdate(p, 0, p.Length); + p = ecc_b.ToByteArray(); + sm3.BlockUpdate(p, 0, p.Length); + // gx,gy + p = ecc_gx.ToByteArray(); + sm3.BlockUpdate(p, 0, p.Length); + p = ecc_gy.ToByteArray(); + sm3.BlockUpdate(p, 0, p.Length); + + // x,y + p = userKey.AffineXCoord.ToBigInteger().ToByteArray(); + sm3.BlockUpdate(p, 0, p.Length); + p = userKey.AffineYCoord.ToBigInteger().ToByteArray(); + sm3.BlockUpdate(p, 0, p.Length); + + // Z + var md = new byte[sm3.GetDigestSize()]; + sm3.DoFinal(md, 0); + + return md; + } + } + + public class SM2Model + { + /// + /// 公钥 + /// + public string PublicKey { get; set; } + + /// + /// 私钥 + /// + public string PrivateKey { get; set; } + } +} diff --git a/SimpleAdmin.Core/Utils/Cryptogram/Sm/SM4CryptoUtil.cs b/SimpleAdmin.Core/Utils/Cryptogram/Sm/SM4CryptoUtil.cs new file mode 100644 index 0000000..0da6070 --- /dev/null +++ b/SimpleAdmin.Core/Utils/Cryptogram/Sm/SM4CryptoUtil.cs @@ -0,0 +1,425 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +/// +/// SM4工具类 +/// +public class SM4CryptoUtil +{ + /// + /// 加密 非线性τ函数B=τ(A) + /// + /// + /// + /// + private static long GetULongByBe(byte[] b, int i) + { + var n = (long)(b[i] & 0xff) << 24 | (uint)((b[i + 1] & 0xff) << 16) | (uint)((b[i + 2] & 0xff) << 8) | b[i + 3] & 0xff & 0xffffffffL; + return n; + } + + /// + /// 解密 非线性τ函数B=τ(A) + /// + /// + /// + /// + private static void PutULongToBe(long n, byte[] b, int i) + { + b[i] = (byte)(int)(0xFF & n >> 24); + b[i + 1] = (byte)(int)(0xFF & n >> 16); + b[i + 2] = (byte)(int)(0xFF & n >> 8); + b[i + 3] = (byte)(int)(0xFF & n); + } + + /// + /// 循环移位,为32位的x循环左移n位 + /// + /// + /// + /// + private static long Rotl(long x, int n) + { + return (x & 0xFFFFFFFF) << n | x >> 32 - n; + } + + /// + /// 将密钥逆序 + /// + /// + /// + private static void Swap(long[] sk, int i) + { + var t = sk[i]; + sk[i] = sk[31 - i]; + sk[31 - i] = t; + } + + /// + /// S盒 + /// + public byte[] SboxTable = new byte[] + { + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, + 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, + 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, + 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, + 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, + 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, + 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, + 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, + 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, + 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, + 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, + 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, + 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, + 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, + 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, + 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48 + }; + + /// + /// 系统参数FK + /// + public uint[] FK = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc }; + + /// + /// 固定参数CK + /// + public uint[] CK = + { + 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, + 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, + 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, + 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, + 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, + 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, + 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, + 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 + }; + + /// + /// Sm4的S盒取值 + /// + /// + /// + private byte Sm4Sbox(byte inch) + { + var i = inch & 0xFF; + var retVal = SboxTable[i]; + return retVal; + } + + /// + /// 线性变换 L + /// + /// + /// + private long Sm4Lt(long ka) + { + var a = new byte[4]; + var b = new byte[4]; + PutULongToBe(ka, a, 0); + b[0] = Sm4Sbox(a[0]); + b[1] = Sm4Sbox(a[1]); + b[2] = Sm4Sbox(a[2]); + b[3] = Sm4Sbox(a[3]); + var bb = GetULongByBe(b, 0); + var c = bb ^ Rotl(bb, 2) ^ Rotl(bb, 10) ^ Rotl(bb, 18) ^ Rotl(bb, 24); + return c; + } + + /// + /// 轮函数 F + /// + /// + /// + /// + /// + /// + /// + private long Sm4F(long x0, long x1, long x2, + long x3, long rk) + { + return x0 ^ Sm4Lt(x1 ^ x2 ^ x3 ^ rk); + } + + /// + /// 轮密钥rk + /// + /// + /// + private long Sm4CalciRk(long ka) + { + var a = new byte[4]; + var b = new byte[4]; + PutULongToBe(ka, a, 0); + b[0] = Sm4Sbox(a[0]); + b[1] = Sm4Sbox(a[1]); + b[2] = Sm4Sbox(a[2]); + b[3] = Sm4Sbox(a[3]); + var bb = GetULongByBe(b, 0); + var rk = bb ^ Rotl(bb, 13) ^ Rotl(bb, 23); + return rk; + } + + /// + /// 加密密钥 + /// + /// + /// + private void SetKey(long[] SK, byte[] key) + { + //加密密钥长度为 128 比特 + var MK = new long[4]; + var i = 0; + MK[0] = GetULongByBe(key, 0); + MK[1] = GetULongByBe(key, 4); + MK[2] = GetULongByBe(key, 8); + MK[3] = GetULongByBe(key, 12); + var k = new long[36]; + //轮密钥生成方法 + k[0] = MK[0] ^ FK[0]; + k[1] = MK[1] ^ FK[1]; + k[2] = MK[2] ^ FK[2]; + k[3] = MK[3] ^ FK[3]; + for (; i < 32; i++) + { + k[i + 4] = k[i] ^ Sm4CalciRk(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ CK[i]); + SK[i] = k[i + 4]; + } + } + + /// + /// 解密函数 + /// + /// 轮密钥 + /// 输入分组的密文 + /// 输出的对应的分组明文 + private void Sm4OneRound(long[] sk, byte[] input, byte[] output) + { + var i = 0; + var ulbuf = new long[36]; + ulbuf[0] = GetULongByBe(input, 0); + ulbuf[1] = GetULongByBe(input, 4); + ulbuf[2] = GetULongByBe(input, 8); + ulbuf[3] = GetULongByBe(input, 12); + while (i < 32)//开始32轮解密 ,一次进行4轮,共计八次 + { + ulbuf[i + 4] = Sm4F(ulbuf[i], ulbuf[i + 1], ulbuf[i + 2], ulbuf[i + 3], + sk[i]); + i++; + } + PutULongToBe(ulbuf[35], output, 0); + PutULongToBe(ulbuf[34], output, 4); + PutULongToBe(ulbuf[33], output, 8); + PutULongToBe(ulbuf[32], output, 12); + } + + /// + /// 补足 16 进制字符串的 0 字符,返回不带 0x 的16进制字符串 + /// + /// + /// 1表示加密,0表示解密 + /// + private static byte[] Padding(byte[] input, int mode) + { + if (input == null) + { + return null; + } + byte[] ret; + if (mode == 1) + { + var p = 16 - input.Length % 16; + ret = new byte[input.Length + p]; + Array.Copy(input, 0, ret, 0, + input.Length); + for (var i = 0; i < p; i++) + { + ret[input.Length + i] = (byte)p; + } + } + else + { + int p = input[input.Length - 1]; + ret = new byte[input.Length - p]; + Array.Copy(input, 0, ret, 0, + input.Length - p); + } + return ret; + } + + /// + /// 设置加密的key + /// + /// + /// + public void SetKeyEnc(Sm4Context ctx, byte[] key) + { + ctx.Mode = 1; + SetKey(ctx.Key, key); + } + + /// + /// 设置解密的key + /// + /// + /// + public void Sm4SetKeyDec(Sm4Context ctx, byte[] key) + { + ctx.Mode = 0; + SetKey(ctx.Key, key); + int i; + for (i = 0; i < 16; i++) + { + Swap(ctx.Key, i); + } + } + + /// + /// ECB + /// + /// + /// + /// + public byte[] Sm4CryptEcb(Sm4Context ctx, byte[] input) + { + if (ctx.IsPadding && ctx.Mode == 1) + { + input = Padding(input, 1); + } + var length = input.Length; + var bins = new byte[length]; + Array.Copy(input, 0, bins, 0, + length); + var bous = new byte[length]; + for (var i = 0; length > 0; length -= 16, i++) + { + var inBytes = new byte[16]; + var outBytes = new byte[16]; + Array.Copy(bins, i * 16, inBytes, 0, + length > 16 ? 16 : length); + Sm4OneRound(ctx.Key, inBytes, outBytes); + Array.Copy(outBytes, 0, bous, i * 16, + length > 16 ? 16 : length); + } + if (ctx.IsPadding && ctx.Mode == 0) + { + bous = Padding(bous, 0); + } + return bous; + } + + /// + /// CBC + /// + /// + /// + /// + /// + public byte[] Sm4CryptCbc(Sm4Context ctx, byte[] iv, byte[] input) + { + if (ctx.IsPadding && ctx.Mode == 1) + { + input = Padding(input, 1); + } + var length = input.Length; + var bins = new byte[length]; + Array.Copy(input, 0, bins, 0, + length); + var bousList = new List(); + int i; + if (ctx.Mode == 1) + { + for (var j = 0; length > 0; length -= 16, j++) + { + var inBytes = new byte[16]; + var outBytes = new byte[16]; + var out1 = new byte[16]; + Array.Copy(bins, j * 16, inBytes, 0, + length > 16 ? 16 : length); + for (i = 0; i < 16; i++) + { + outBytes[i] = (byte)(inBytes[i] ^ iv[i]); + } + Sm4OneRound(ctx.Key, outBytes, out1); + Array.Copy(out1, 0, iv, 0, + 16); + for (var k = 0; k < 16; k++) + { + bousList.Add(out1[k]); + } + } + } + else + { + var temp = new byte[16]; + for (var j = 0; length > 0; length -= 16, j++) + { + var inBytes = new byte[16]; + var outBytes = new byte[16]; + var out1 = new byte[16]; + Array.Copy(bins, j * 16, inBytes, 0, + length > 16 ? 16 : length); + Array.Copy(inBytes, 0, temp, 0, + 16); + Sm4OneRound(ctx.Key, inBytes, outBytes); + for (i = 0; i < 16; i++) + { + out1[i] = (byte)(outBytes[i] ^ iv[i]); + } + Array.Copy(temp, 0, iv, 0, + 16); + for (var k = 0; k < 16; k++) + { + bousList.Add(out1[k]); + } + } + } + if (ctx.IsPadding && ctx.Mode == 0) + { + var bous = Padding(bousList.ToArray(), 0); + return bous; + } + return bousList.ToArray(); + } +} + +/// +/// SM4处理中心 +/// +public class Sm4Context +{ + public Sm4Context() + { + Mode = 1; + IsPadding = true; + Key = new long[32]; + } + + /// + /// 1表示加密,0表示解密 + /// + public int Mode; + + /// + /// 密钥 + /// + public long[] Key; + + /// + /// 是否补足16进制字符串 + /// + public bool IsPadding; +} diff --git a/SimpleAdmin.Core/Utils/Image/AvatarUtil.cs b/SimpleAdmin.Core/Utils/Image/AvatarUtil.cs new file mode 100644 index 0000000..f69fa7e --- /dev/null +++ b/SimpleAdmin.Core/Utils/Image/AvatarUtil.cs @@ -0,0 +1,116 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +/// +/// 头像功能 +/// +public static class AvatarUtil +{ + #region 姓名生成图片处理 + + /// + /// 获取姓名对应的颜色值 + /// + /// + /// + public static string GetNameColor(string name) + { + if (string.IsNullOrEmpty(name) || name.Length <= 0) + throw new Exception("name不能为空"); + //获取名字第一个字,转换成 16进制 图片 + var str = ""; + foreach (var item in name) + { + str += Convert.ToUInt16(item); + } + if (str.Length < 4) + { + str += new Random().Next(100, 1000); + } + var color = "#" + str.Substring(1, 3); + return color; + } + + /// + /// 获取姓名对应的图片 + /// + /// + /// + /// + /// + public static SKBitmap GetNameImage(string name, int width = 100, int height = 100) + { + var color = GetNameColor(name);//获取颜色 + var nameLength = name.Length;//获取姓名长度 + var nameWritten = name;//需要绘制的文字 + if (nameLength > 2)//如果名字长度超过2个 + { + // 如果用户输入的姓名大于等于3个字符,截取后面两位 + var firstName = name.Substring(0, 1); + if (IsChinese(firstName)) + { + // 截取倒数两位汉字 + nameWritten = name.Substring(name.Length - 2); + } + else + { + // 截取前面的两个英文字母 + nameWritten = name.Substring(0, 2).ToUpper(); + } + } + var bmp = new SKBitmap(width, height); + using (var canvas = new SKCanvas(bmp)) + { + canvas.DrawColor(SKColor.Parse(color)); + using (var sKPaint = new SKPaint()) + { + sKPaint.Color = SKColors.White;//字体颜色 + sKPaint.TextSize = 25;//字体大小 + sKPaint.IsAntialias = true;//开启抗锯齿 + sKPaint.Typeface = SKTypeface.FromFamilyName("微软雅黑");//字体 + var size = new SKRect(); + sKPaint.MeasureText(nameWritten, ref size);//计算文字宽度以及高度 + var temp = (bmp.Width - size.Size.Width) / 2; + var temp1 = (bmp.Height - size.Size.Height) / 2; + canvas.DrawText(nameWritten, temp, temp1 - size.Top, sKPaint);//画文字 + } + } + + return bmp; + } + + /// + /// 获取图片base64格式 + /// + /// 名称 + /// 宽 + /// 高 + /// + public static string GetNameImageBase64(string name, int width = 100, int height = 100) + { + var img = GetNameImage(name, width, height); + var imgByte = img.ImgToBase64String(); + return "data:image/png;base64," + imgByte; + } + + /// + /// 用 正则表达式 判断字符是不是汉字 + /// + /// 待判断字符或字符串 + /// 真:是汉字;假:不是 + private static bool IsChinese(string text) + { + return System.Text.RegularExpressions.Regex.IsMatch(text, @"[\u4e00-\u9fbb]"); + } + + #endregion 姓名生成图片处理 +} diff --git a/SimpleAdmin.Core/Utils/Image/ImageUtil.cs b/SimpleAdmin.Core/Utils/Image/ImageUtil.cs new file mode 100644 index 0000000..2a04a50 --- /dev/null +++ b/SimpleAdmin.Core/Utils/Image/ImageUtil.cs @@ -0,0 +1,223 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +public static class ImageUtil +{ + /// + /// 图片转换成base64 + /// + /// + /// + public static string ImgToBase64String(SKImage img) + { + try + { + var p = img.Encode(SKEncodedImageFormat.Png, 100); + var arr = p.ToArray(); + return Convert.ToBase64String(arr); + } + catch + { + return string.Empty; + } + } + + /// + /// 图片转换成base64 + /// + /// + /// + public static string ImgToBase64String(this SKBitmap bmp) + { + try + { + var img = SKImage.FromBitmap(bmp); + var p = img.Encode(SKEncodedImageFormat.Png, 100); + var arr = p.ToArray(); + return Convert.ToBase64String(arr); + } + catch + { + return string.Empty; + } + } + + /// + /// base64转bitmap + /// + /// + /// + public static Bitmap GetBitmapFromBase64(this string base64String) + { + var b = Convert.FromBase64String(base64String); + var ms = new MemoryStream(b); + var bitmap = new Bitmap(ms); + ms.Close(); + return bitmap; + } + + /// + /// base64转bitmap + /// + /// + /// + public static SKBitmap GetSkBitmapFromBase64(this string base64String) + { + var b = Convert.FromBase64String(base64String); + var bitmap = SKBitmap.Decode(b); + return bitmap; + } + + /// + /// base64转image格式 + /// + /// + /// + public static string ToImageBase64(this string base64String) + { + return "data:image/png;base64," + base64String; + } + + /// + /// 重新修改尺寸 + /// + /// 图片 + /// 尺寸 + /// + public static Bitmap ResizeImage(Image imgToResize, Size size) + { + //获取图片宽度 + var sourceWidth = imgToResize.Width; + //获取图片高度 + var sourceHeight = imgToResize.Height; + + float nPercent; + //计算宽度的缩放比例 + var nPercentW = size.Width / (float)sourceWidth; + //计算高度的缩放比例 + var nPercentH = size.Height / (float)sourceHeight; + + if (nPercentH < nPercentW) + nPercent = nPercentH; + else + nPercent = nPercentW; + //期望的宽度 + var destWidth = (int)(sourceWidth * nPercent); + //期望的高度 + var destHeight = (int)(sourceHeight * nPercent); + + var b = new Bitmap(destWidth, destHeight); + var g = Graphics.FromImage(b); + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + //绘制图像 + g.DrawImage(imgToResize, 0, 0, destWidth, + destHeight); + g.Dispose(); + return b; + } + + /// + /// Resize图片 + /// + /// 原始Bitmap + /// 新的宽度 + /// 新的高度 + /// 处理以后的图片 + public static Bitmap ResizeImage(this Bitmap bmp, int newW, int newH) + { + try + { + var b = new Bitmap(newW, newH); + var g = Graphics.FromImage(b); + // 插值算法的质量 + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel); + g.Dispose(); + return b; + } + catch + { + return null; + } + } + + /// + /// Resize图片 + /// + /// 原始Bitmap + /// 新的宽度 + /// 新的高度 + /// 处理以后的图片 + public static SKBitmap ResizeImage(this SKBitmap bmp, int newW, int newH) + { + try + { + var b = new SKBitmap(newW, newH); + var resized = b.Resize(new SKImageInfo(newW, newH), SKFilterQuality.High); + if (resized is null) + { + return null; + } + var image = SKImage.FromBitmap(resized); + return b; + } + catch + { + return null; + } + } + + /// + /// 获取缩略图 + /// + /// + /// 宽 + /// 高 + /// + public static Image GetPicThumbnail(this Bitmap bmp, int w, int h) + { + try + { + var thumbnail = bmp.GetThumbnailImage(w, h, () => false, IntPtr.Zero); + return thumbnail; + } + catch (Exception ex) + { + return null; + } + } + + /// + /// 获取缩略图 + /// + /// + /// 宽 + /// 高 + /// + public static SKImage GetPicThumbnail(this SKBitmap bmp, int w, int h) + { + try + { + var resized = bmp.Resize(new SKImageInfo(w, h), SKFilterQuality.Medium); + if (resized is null) + { + return null; + } + var image = SKImage.FromBitmap(resized); + return image; + } + catch (Exception) + { + return null; + } + } +} diff --git a/SimpleAdmin.Core/Utils/Pwd/PwdUtil.cs b/SimpleAdmin.Core/Utils/Pwd/PwdUtil.cs new file mode 100644 index 0000000..fada582 --- /dev/null +++ b/SimpleAdmin.Core/Utils/Pwd/PwdUtil.cs @@ -0,0 +1,62 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +/// +/// 密码相关通用类 +/// +public class PwdUtil +{ + /// + /// 密码相似度 + /// + /// + /// + /// + public static double Similarity(string oldPassword, string newPassword) + { + var editDistance = LevenshteinDistance(oldPassword, newPassword); + var similarity = 1.0 - editDistance / (double)Math.Max(oldPassword.Length, newPassword.Length); + return similarity * 100; + } + + /// + /// 计算莱文斯坦距离算法 + /// + /// + /// + /// + public static int LevenshteinDistance(string s1, string s2) + { + var distance = new int[s1.Length + 1, s2.Length + 1]; + + for (var i = 0; i <= s1.Length; i++) + { + distance[i, 0] = i; + } + + for (var j = 0; j <= s2.Length; j++) + { + distance[0, j] = j; + } + + for (var i = 1; i <= s1.Length; i++) + { + for (var j = 1; j <= s2.Length; j++) + { + var cost = s1[i - 1] == s2[j - 1] ? 0 : 1; + + distance[i, j] = Math.Min(Math.Min(distance[i - 1, j] + 1, distance[i, j - 1] + 1), distance[i - 1, j - 1] + cost); + } + } + return distance[s1.Length, s2.Length]; + } +} diff --git a/SimpleAdmin.Core/Utils/Zip/ZipUtils.cs b/SimpleAdmin.Core/Utils/Zip/ZipUtils.cs new file mode 100644 index 0000000..0222ebc --- /dev/null +++ b/SimpleAdmin.Core/Utils/Zip/ZipUtils.cs @@ -0,0 +1,533 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Utils; + +public class ZipUtils +{ + /// + /// 压缩单个文件 + /// + /// 要压缩的文件 + /// 压缩后的文件 + /// 压缩等级 + /// 每次写入大小 + public static void ZipFile(string fileToZip, string zipedFile, int compressionLevel, + int blockSize) + { + //如果文件没有找到,则报错 + if (!File.Exists(fileToZip)) + { + throw new FileNotFoundException("指定要压缩的文件: " + fileToZip + " 不存在!"); + } + + using (var zipFile = File.Create(zipedFile)) + { + using (var zipStream = new ZipOutputStream(zipFile)) + { + using (var streamToZip = new FileStream(fileToZip, FileMode.Open, FileAccess.Read)) + { + var fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\", StringComparison.Ordinal) + 1); + + var zipEntry = new ZipEntry(fileName); + + zipStream.PutNextEntry(zipEntry); + + zipStream.SetLevel(compressionLevel); + + var buffer = new byte[blockSize]; + + try + { + var sizeRead = 0; + do + { + sizeRead = streamToZip.Read(buffer, 0, buffer.Length); + zipStream.Write(buffer, 0, sizeRead); + } while (sizeRead > 0); + } + catch (Exception ex) + { + throw ex; + } + + streamToZip.Close(); + } + + zipStream.Finish(); + zipStream.Close(); + } + + zipFile.Close(); + } + } + + /// + /// 压缩单个文件 + /// + /// 要进行压缩的文件名 + /// 压缩后生成的压缩文件名 + public static void ZipFile(string fileToZip, string zipedFile) + { + //如果文件没有找到,则报错 + if (!File.Exists(fileToZip)) + { + throw new FileNotFoundException("指定要压缩的文件: " + fileToZip + " 不存在!"); + } + + using (var fs = File.OpenRead(fileToZip)) + { + var buffer = new byte[fs.Length]; + fs.Read(buffer, 0, buffer.Length); + fs.Close(); + + using (var zipFile = File.Create(zipedFile)) + { + using (var zipStream = new ZipOutputStream(zipFile)) + { + var fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\") + 1); + var zipEntry = new ZipEntry(fileName); + zipStream.PutNextEntry(zipEntry); + zipStream.SetLevel(5); + + zipStream.Write(buffer, 0, buffer.Length); + zipStream.Finish(); + zipStream.Close(); + } + } + } + } + + /// + /// 压缩多个文件到指定路径 + /// + /// 压缩到哪个路径 + /// 压缩文件名称 + public static void ZipFile(List sourceFileNames, string zipFileName) + { + //压缩文件打包 + using (var s = new ZipOutputStream(File.Create(zipFileName))) + { + s.SetLevel(9); + var buffer = new byte[4096]; + foreach (var file in sourceFileNames) + { + if (Directory.Exists(file))// 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件 + { + var pPath = ""; + pPath += Path.GetFileName(file); + pPath += "\\"; + ZipSetp(file, s, pPath, sourceFileNames); + } + else// 否则直接压缩文件 + { + var entry = new ZipEntry(Path.GetFileName(file)); + entry.DateTime = DateTime.Now; + s.PutNextEntry(entry); + using (var fs = File.OpenRead(file)) + { + int sourceBytes; + do + { + sourceBytes = fs.Read(buffer, 0, buffer.Length); + s.Write(buffer, 0, sourceBytes); + } while (sourceBytes > 0); + } + } + } + s.Finish(); + s.Close(); + } + } + + /// + /// 压缩多层目录 + /// + /// 待压缩目录 + /// 压缩后生成的压缩文件名,绝对路径 + public static void ZipFileDirectory(string strDirectory, string zipedFile) + { + using (var zipFile = File.Create(zipedFile)) + { + using (var s = new ZipOutputStream(zipFile)) + { + s.SetLevel(9); + ZipSetp(strDirectory, s, ""); + } + } + } + + /// + /// 压缩多层目录 + /// + /// 待压缩目录 + /// 压缩后生成的压缩文件名,绝对路径 + /// 指定要压缩的文件列表(完全路径) + public static void ZipFileDirectory(string strDirectory, string zipedFile, List files) + { + using (var zipFile = File.Create(zipedFile)) + { + using (var s = new ZipOutputStream(zipFile)) + { + s.SetLevel(9); + ZipSetp(strDirectory, s, "", files); + } + } + } + + /// + /// 递归遍历目录 + /// + /// 需遍历的目录 + /// 压缩输出流对象 + /// The parent path. + /// 需要压缩的文件 + private static void ZipSetp(string strDirectory, ZipOutputStream s, string parentPath, + List files = null) + { + if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar) + { + strDirectory += Path.DirectorySeparatorChar; + } + + var filenames = Directory.GetFileSystemEntries(strDirectory); + + var buffer = new byte[4096]; + foreach (var file in filenames)// 遍历所有的文件和目录 + { + if (files != null && !files.Contains(file)) + { + continue; + } + if (Directory.Exists(file))// 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件 + { + var pPath = parentPath; + pPath += Path.GetFileName(file); + pPath += "\\"; + ZipSetp(file, s, pPath, files); + } + else// 否则直接压缩文件 + { + //打开压缩文件 + var fileName = parentPath + Path.GetFileName(file); + var entry = new ZipEntry(fileName); + + entry.DateTime = DateTime.Now; + + s.PutNextEntry(entry); + using (var fs = File.OpenRead(file)) + { + int sourceBytes; + do + { + sourceBytes = fs.Read(buffer, 0, buffer.Length); + s.Write(buffer, 0, sourceBytes); + } while (sourceBytes > 0); + } + } + } + } + + /// + /// 解压缩一个 zip 文件。 + /// + /// 压缩文件 + /// 解压目录 + /// zip 文件的密码。 + /// 是否覆盖已存在的文件。 + public static void UnZip(string zipedFile, string strDirectory, bool overWrite, + string password) + { + if (strDirectory == "") + strDirectory = Directory.GetCurrentDirectory(); + if (!strDirectory.EndsWith("\\")) + strDirectory = strDirectory + "\\"; + + using (var s = new ZipInputStream(File.OpenRead(zipedFile))) + { + if (password != null) + { + s.Password = password; + } + ZipEntry theEntry; + + while ((theEntry = s.GetNextEntry()) != null) + { + var directoryName = ""; + var pathToZip = ""; + pathToZip = theEntry.Name; + + if (pathToZip != "") + directoryName = Path.GetDirectoryName(pathToZip) + "\\"; + + var fileName = Path.GetFileName(pathToZip); + + Directory.CreateDirectory(strDirectory + directoryName); + + if (fileName != "") + { + if (File.Exists(strDirectory + directoryName + fileName) && overWrite || !File.Exists(strDirectory + directoryName + fileName)) + { + using (var streamWriter = File.Create(strDirectory + directoryName + fileName)) + { + var size = 2048; + var data = new byte[2048]; + while (true) + { + size = s.Read(data, 0, data.Length); + + if (size > 0) + streamWriter.Write(data, 0, size); + else + break; + } + streamWriter.Close(); + } + } + } + } + + s.Close(); + } + } + + /// + /// 解压缩一个 zip 文件。 + /// + /// 压缩文件 + /// 解压目录 + /// 是否覆盖已存在的文件。 + public static void UnZip(string zipedFile, string strDirectory, bool overWrite) + { + UnZip(zipedFile, strDirectory, overWrite, null); + } + + /// + /// 解压缩一个 zip 文件。 + /// 覆盖已存在的文件。 + /// + /// 压缩文件 + /// 解压目录 + public static void UnZip(string zipedFile, string strDirectory) + { + UnZip(zipedFile, strDirectory, true); + } + + /// + /// 获取压缩文件中指定类型的文件 + /// + /// 压缩文件 + /// 文件类型(.txt|.exe) + /// 文件名称列表(包含子目录) + public static List GetFiles(string zipedFile, List fileExtension) + { + var files = new List(); + if (!File.Exists(zipedFile)) + { + //return files; + throw new FileNotFoundException(zipedFile); + } + + using (var s = new ZipInputStream(File.OpenRead(zipedFile))) + { + ZipEntry theEntry; + while ((theEntry = s.GetNextEntry()) != null) + { + if (theEntry.IsFile) + { + //Console.WriteLine("Name : {0}", theEntry.Name); + if (fileExtension != null) + { + if (fileExtension.Contains(Path.GetExtension(theEntry.Name))) + { + files.Add(theEntry.Name); + } + } + else + { + files.Add(theEntry.Name); + } + } + } + s.Close(); + } + + return files; + } + + /// + /// 获取压缩文件中的所有文件 + /// + /// 压缩文件 + /// 文件名称列表(包含子目录) + public static List GetFiles(string zipedFile) + { + return GetFiles(zipedFile, null); + } + + /// + /// 打包线上线下文件 + /// + /// 压缩文件名称 + /// 文件列表 + /// 保存路径 + /// 是否本地 + public static string ZipFiles(string zipName, List fileList, out string error, + bool isLocal = true) + { + error = string.Empty; + + var path = string.Format("/ZipFiles/{0}/{1}/{2}/", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); + //文件保存目录 + var directory = App.WebHostEnvironment.WebRootPath + path; + + var url = App.Configuration["FileHostUrl"].TrimEnd('/') + path + zipName; + var savePath = directory + zipName; + try + { + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + using (var zipStream = new ZipOutputStream(File.Create(savePath))) + { + zipStream.SetLevel(9);//压缩级别0-9 + + foreach (var item in fileList) + { + byte[] buffer = null; + if (isLocal) + { + var stream = new FileInfo(item.FilePath).OpenRead(); + buffer = new byte[stream.Length]; + stream.Read(buffer, 0, Convert.ToInt32(stream.Length)); + } + else + { + buffer = new WebClient().DownloadData(item.FilePath);//取消 + } + var entry = new ZipEntry(item.FileName); + entry.DateTime = DateTime.Now; + entry.Size = buffer.Length; + zipStream.PutNextEntry(entry); + zipStream.Write(buffer, 0, buffer.Length); + } + } + } + catch (Exception ex) + { + error = "文件打包失败:" + ex.Message; + } + return url; + } + + /// 压缩文件夹 + /// 要打包的文件夹 + /// 是否删除原文件夹 + public static string CompressDirectory(string dirPath, bool deleteDir) + { + //压缩文件路径 + var pCompressPath = dirPath + ".zip"; + if (File.Exists(pCompressPath)) + File.Delete(pCompressPath); + //创建压缩文件 + var pCompressFile = new FileStream(pCompressPath, FileMode.Create); + using (var zipoutputstream = new ZipOutputStream(pCompressFile)) + { + var crc = new Crc32(); + var fileList = GetAllFies(dirPath); + foreach (var item in fileList) + { + var fs = new FileStream(item.Key, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + // FileStream fs = File.OpenRead(item.Key.ToString()); + var buffer = new byte[fs.Length]; + fs.Read(buffer, 0, buffer.Length); + var entry = new ZipEntry(item.Key.Substring(dirPath.Length)); + entry.DateTime = item.Value; + entry.Size = fs.Length; + fs.Close(); + crc.Reset(); + crc.Update(buffer); + entry.Crc = crc.Value; + zipoutputstream.PutNextEntry(entry); + zipoutputstream.Write(buffer, 0, buffer.Length); + } + } + if (deleteDir) + { + Directory.Delete(dirPath, true); + } + return pCompressPath; + } + + /// + /// 获取所有文件 + /// + /// + private static Dictionary GetAllFies(string dir) + { + var filesList = new Dictionary(); + var fileDire = new DirectoryInfo(dir); + if (!fileDire.Exists) + { + throw new FileNotFoundException("目录:" + fileDire.FullName + "没有找到!"); + } + GetAllDirFiles(fileDire, filesList); + GetAllDirsFiles(fileDire.GetDirectories(), filesList); + return filesList; + } + + /// + /// 获取一个文件夹下的所有文件夹里的文件 + /// + /// + /// + private static void GetAllDirsFiles(DirectoryInfo[] dirs, Dictionary filesList) + { + foreach (var dir in dirs) + { + foreach (var file in dir.GetFiles(".")) + { + filesList.Add(file.FullName, file.LastWriteTime); + } + GetAllDirsFiles(dir.GetDirectories(), filesList); + } + } + + /// + /// 获取一个文件夹下的文件 + /// + /// 目录名称 + /// 文件列表HastTable + private static void GetAllDirFiles(DirectoryInfo dir, Dictionary filesList) + { + foreach (var file in dir.GetFiles()) + { + filesList.Add(file.FullName, file.LastWriteTime); + } + } +} + +/// +/// 文件对象 +/// +public class FileItem +{ + /// + /// 文件名称 + /// + public string FileName { get; set; } + + /// + /// 文件路径 + /// + public string FilePath { get; set; } +} diff --git a/SimpleAdmin.MessageCenter/GlobalUsing.cs b/SimpleAdmin.MessageCenter/GlobalUsing.cs new file mode 100644 index 0000000..7d5051f --- /dev/null +++ b/SimpleAdmin.MessageCenter/GlobalUsing.cs @@ -0,0 +1 @@ +global using SimpleMQTT; diff --git a/SimpleAdmin.MessageCenter/MessageWorker.cs b/SimpleAdmin.MessageCenter/MessageWorker.cs new file mode 100644 index 0000000..55fbacb --- /dev/null +++ b/SimpleAdmin.MessageCenter/MessageWorker.cs @@ -0,0 +1,91 @@ +using NewLife.MQTT; +using SimpleAdmin.Cache; +using SimpleAdmin.Core; +using SimpleAdmin.SqlSugar; +using SimpleAdmin.System; + +namespace SimpleAdmin.MessageCenter; + +public class MessageWorker : BackgroundService +{ + private readonly ILogger _logger; + private readonly ISimpleCacheService _simpleCacheService; + private readonly IMqttClientManager _mqttClientManager; + private readonly MqttClient _mqttClient; + + public MessageWorker(ILogger logger, ISimpleCacheService simpleCacheService, IMqttClientManager mqttClientManager) + { + _logger = logger; + _simpleCacheService = simpleCacheService; + _mqttClientManager = mqttClientManager; + _mqttClient = mqttClientManager.GetClient(); + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + //»ñȡÑӳٶÓÁÐ + var queue = _simpleCacheService.GetDelayQueue(CacheConst.CACHE_NOTIFICATION); + while (!stoppingToken.IsCancellationRequested) + { + //һ´ÎÄÃʮÌõ£¬Èç¹ûÄÃһÌõ¾ÍÓÃqueue.TakeOneAsync(-1);-1Êdz¬ʱʱ¼䣬ĬÈÏ0ÃëÓÀԶ×èÈû£»¸ºÊý±íʾֱ½ӷµ»أ¬²»×èÈû¡£ + var data = await queue.TakeOneAsync(-1); + if (data != 0) + { + _logger.LogDebug($"Ïû·ÑÕßÊյ½ÏûϢ,ÏûϢID:{data},ʱ¼䣺{DateTime.Now}"); + var db = DbContext.DB.CopyNew(); + //»ñȡÏûϢ + var message = await db.Queryable().InSingleAsync(data); + if (message != null) + { + message.Status = SysDictConst.MESSAGE_STATUS_ALREADY; + //»ñȡ´ý·¢Ë͵ÄÏûϢ + var messageUsers = await db.Queryable() + .Where(it => it.MessageId == message.Id && it.Status == SysDictConst.MESSAGE_STATUS_READY).ToListAsync(); + var hasError = false; + //¿ªÆôÊÂÎñ + var result = await db.UseTranAsync(async () => + { + messageUsers.ForEach(it => + { + try + { + //·¢ËÍÏûϢ + _mqttClient.PublishAsync(MqttConst.MQTT_TOPIC_PREFIX + it.UserId, new MqttMessage() + { + MsgType = MqttConst.MQTT_MESSAGE_NEW, + Data = new MessageData() + { + Subject = message.Subject, + Content = message.Content + } + }); + it.Status = SysDictConst.MESSAGE_STATUS_ALREADY; + it.UpdateTime = DateTime.Now; + } + catch (Exception e) + { + hasError = true; + _logger.LogError($"·¢ËÍÏûϢʧ°Ü:{e.Message}"); + } + }); + await db.Updateable(messageUsers).ExecuteCommandAsync(); + await db.Updateable(message).ExecuteCommandAsync(); + }); + //Èç¹ûÓÐʧ°ܵģ¬ÖØд·¢µ½ÑӳٶÓÁÐ + if (hasError) + { + _logger.LogDebug($"ÓÐʧ°ܵÄÏûϢ£¬ÖØÐ·¢µ½ÑӳٶÓÁÐ"); + queue.Add(message.Id, 5); + } + } + queue.Acknowledge(data);//¸æË߶ÓÁÐÒѾ­Ïû·ÑÁ˵ÄÊý¾Ý + _logger.LogDebug("Ïû·ѳɹ¦"); + } + else + { + _logger.LogDebug("Ïû·ÑÕߴӶÓÁÐÖÐûÓÐÄõ½Êý¾Ý:" + DateTime.Now); + await Task.Delay(1000, stoppingToken); + } + } + } +} diff --git a/SimpleAdmin.MessageCenter/Program.cs b/SimpleAdmin.MessageCenter/Program.cs new file mode 100644 index 0000000..f5909fa --- /dev/null +++ b/SimpleAdmin.MessageCenter/Program.cs @@ -0,0 +1,19 @@ +try +{ + Console.Title = "SimpleAdminÏûϢÖÐÐķþÎñ"; +} +catch +{ + // ignored +}//ע²á·þÎñ»ᱨ´íËùÒÔҪcatch +Serve.Run(GenericRunOptions.Default + .ConfigureBuilder(hostBuilder => + { + hostBuilder.UseWindowsService();//֧³Öע²á³ɷþÎñ + hostBuilder.ConfigureServices((hostContext, services) => + { + services.AddMqttClientManager();//mqtt + }); + return hostBuilder; + }) + ); diff --git a/SimpleAdmin.MessageCenter/Properties/launchSettings.json b/SimpleAdmin.MessageCenter/Properties/launchSettings.json new file mode 100644 index 0000000..5a4aa9d --- /dev/null +++ b/SimpleAdmin.MessageCenter/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "SimpleAdmin.MessageCenter": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + } + } + } +} diff --git a/SimpleAdmin.MessageCenter/SimpleAdmin.MessageCenter.csproj b/SimpleAdmin.MessageCenter/SimpleAdmin.MessageCenter.csproj new file mode 100644 index 0000000..39e92c4 --- /dev/null +++ b/SimpleAdmin.MessageCenter/SimpleAdmin.MessageCenter.csproj @@ -0,0 +1,31 @@ + + + + net6.0;net7.0;net8.0 + enable + enable + dotnet-SimpleAdmin.MessageCenter-031b40d7-f6af-456f-a00c-48f5a3e234de + en-US + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SimpleAdmin.MessageCenter/SimpleAdmin.MessageCenter.xml b/SimpleAdmin.MessageCenter/SimpleAdmin.MessageCenter.xml new file mode 100644 index 0000000..3426b38 --- /dev/null +++ b/SimpleAdmin.MessageCenter/SimpleAdmin.MessageCenter.xml @@ -0,0 +1,8 @@ + + + + SimpleAdmin.MessageCenter + + + + diff --git a/SimpleAdmin.MessageCenter/appsettings.Development.json b/SimpleAdmin.MessageCenter/appsettings.Development.json new file mode 100644 index 0000000..686b932 --- /dev/null +++ b/SimpleAdmin.MessageCenter/appsettings.Development.json @@ -0,0 +1,10 @@ +{ + //mqttÉèÖà + "MqttSettings": { + "Host": "127.0.0.1", + "Port": 1883, + "UserName": "admin", + "SecretKey": "admin", + "ClientId": "SimpleAdminMessageCenter_Dev" + } +} \ No newline at end of file diff --git a/SimpleAdmin.MessageCenter/appsettings.Production.json b/SimpleAdmin.MessageCenter/appsettings.Production.json new file mode 100644 index 0000000..391f3bf --- /dev/null +++ b/SimpleAdmin.MessageCenter/appsettings.Production.json @@ -0,0 +1,10 @@ +{ + //mqttÉèÖà + "MqttSettings": { + "Host": "127.0.0.1", + "Port": 1883, + "UserName": "admin", + "SecretKey": "admin", + "ClientId": "SimpleAdminMessageCenter_Pro" + } +} \ No newline at end of file diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/Aop/GlobalDispatchProxy.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/Aop/GlobalDispatchProxy.cs new file mode 100644 index 0000000..9258675 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/Aop/GlobalDispatchProxy.cs @@ -0,0 +1,423 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using SimpleAdmin.Core; + +namespace SimpleAdmin.Plugin.Aop; + +/// +/// Aop +/// 这里没有继承IGlobalDispatchProxy是因为IGlobalDispatchProxy会把一些没有必要的方法也aop了 +/// +public class GlobalDispatchProxy : AspectDispatchProxy, IDispatchProxy +{ + /// + /// 当前服务实例 + /// + public object Target { get; set; } + + /// + /// 服务提供器,可以用来解析服务,如:Services.GetService() + /// + public IServiceProvider Services { get; set; } + + /// + /// 方法 + /// + /// + /// + /// + /// + public override object Invoke(MethodInfo method, object[] args) + { + //如果不带返回值 + if (method.ReturnType == typeof(void)) + { + After(method, null, args); + return method.Invoke(Target, args);//直接返回 + } + var result = Before(method, args);//方法执行之前判断是否有缓存的数据 + if (result == null) result = method.Invoke(Target, args);//如果没有缓存就执行方法返回数据 + After(method, result, args);//方法执行之后干的事 + return result;//返回结果 + } + + /// + /// 异步无返回值 + /// + /// + /// + /// + /// + public override async Task InvokeAsync(MethodInfo method, object[] args) + { + var task = method.Invoke(Target, args) as Task; + await task; + After(method, null, args); + } + + /// + /// 异步带返回值 + /// + /// + /// + /// + /// + /// + public override async Task InvokeAsyncT(MethodInfo method, object[] args) + { + var result = Before(method, args);//方法执行之前判断是否有缓存的数据 + if (result == null) + { + var taskT = method.Invoke(Target, args) as Task; + result = await taskT;//如果没有缓存就执行方法返回数据 + } + After(method, result, args);//方法执行之后干的事 + return result;//返回结果 + } + + /// + /// 方法执行之后 + /// + /// 方法 + /// 返回值 + /// 参数列表 + private void After(MethodInfo method, object returnValue, object[] args) + { + RecordCache(method, args, returnValue);//记录返回值到缓存 + } + + /// + /// 方法执行之前 + /// + /// 方法 + /// 参数列表 + /// + private dynamic Before(MethodInfo method, object[] args) + { + var cacheData = CheckCache(method, args);//检查缓存 + if (cacheData != null) { return cacheData; }//如果缓存有数据直接返回 + return null;//默认返回空 + } + + /// + /// 检查缓存里是否有数据 + /// + /// 方法 + /// 参数列表 + private dynamic CheckCache(MethodInfo method, object[] args) + { + var cacheAttribute = method.GetActualCustomAttribute(Target);//读取缓存特性 + //判断需不需要读取缓存 + if (cacheAttribute != null) + { + var redisManager = Services.GetService();// 获取redis服务 + var cacheKey = cacheAttribute.CustomKeyValue + ?? CustomCacheKey(cacheAttribute.KeyPrefix, method, args);//如果redisKey值,如果有自定义值就用自定义Key,否则以前缀+系统自动生成的Key + string cacheValue; + if (cacheAttribute.StoreType == CacheConst.CACHE_HASH)//如果存的是Hash值 + { + cacheValue = redisManager.HashGet(cacheKey, args[0].ToString())[0];//从redis获取Hash数据取第一个,注意是 string 类型 + } + else + { + cacheValue = redisManager.Get(cacheKey);//注意是 string 类型,方法GetValue + } + if (!string.IsNullOrEmpty(cacheValue))//如果返回值不是空 + { + //if (cacheAttribute.IsDelete)//判断是否是删除操作 + //{ + // if (cacheAttribute.StoreType == RedisConst.Cache_Hash)//如果是Hash + // { + // _redisManager.HashDel(cacheKey, new string[] { args[0].ToString() }); + // } + // else + // { + // //删除Redis整个KEY + // _redisManager.Remove(cacheKey); + // } + + //} + //将当前获取到的缓存值,赋值给当前执行方法 + Type returnType; + if (typeof(Task).IsAssignableFrom(method.ReturnType)) + { + returnType = method.ReturnType.GenericTypeArguments.FirstOrDefault(); + } + else + { + returnType = method.ReturnType; + } + if (!returnType.IsPrimitive && returnType != typeof(string))//判断返回类型是否原生类型并且不是string + { + dynamic result = JsonConvert.DeserializeObject(cacheValue, returnType);//序列化数据 + return result; + } + return cacheValue; + } + } + return null; + } + + /// + /// 写数据到缓存 + /// + /// 方法 + /// 参数列表 + /// 返回值 + private void RecordCache(MethodInfo method, object[] args, object returnValue) + { + var cacheAttribute = method.GetActualCustomAttribute(Target); + if (cacheAttribute != null) + { + //获取自定义缓存键 + var cacheKey = cacheAttribute.CustomKeyValue ?? CustomCacheKey(cacheAttribute.KeyPrefix, method, args); + if (!string.IsNullOrWhiteSpace(cacheKey))//如果有key + { + var redisManager = Services.GetService();// 获取redis服务 + if (cacheAttribute.IsDelete)//判断是否是删除操作 + { + //删除Redis整个KEY + redisManager.Remove(cacheKey); + } + else + { + if (returnValue == null) { return; } + if (cacheAttribute.StoreType == CacheConst.CACHE_HASH)//如果是hash类型的 + { + //插入到hash,这里规定是方法的第一个参数 + redisManager.HashAdd(cacheKey, args[0].ToString(), returnValue); + } + else + { + if (cacheAttribute.AbsoluteExpiration != null)//如果有超时时间 + { + redisManager.Set(cacheKey, returnValue, cacheAttribute.AbsoluteExpiration.Value);//插入redis + } + else + { + redisManager.Set(cacheKey, returnValue);//插入redis + } + } + } + } + } + } + + /// + /// 自定义缓存Key + /// + /// 前缀 + /// 方法 + /// 参数 + /// + protected string CustomCacheKey(string prefix, MethodInfo method, object[] args) + { + var key = prefix;//前缀 + var methodArguments = args.Select(GetCacheKey.GetArgumentValue).Take(3).ToList();//获取参数列表,最多三个 + if (!string.IsNullOrEmpty(key))//如果制定了前缀 + { + foreach (var param in methodArguments)//遍历参数列表 + { + key = $"{key}{param}:";//生成KEY + } + } + else + { + var typeName = Target.GetType().Name;//获取实例名 + var methodName = method.Name;//获取方法名 + key = $"{CacheConst.CACHE_PREFIX_WEB}{typeName}:{methodName}:";//生成Key + foreach (var param in methodArguments)//遍历参数列表 + { + key = $"{key}{param}:";//生成加上参数的KEY + } + } + return key.TrimEnd(':'); + } +} + +/// +/// 获取缓存Key +/// +internal static class GetCacheKey +{ + /// + /// object 转 string + /// + /// + /// + public static string GetArgumentValue(object arg) + { + if (arg is DateTime || arg is DateTime) + return ((DateTime)arg).ToString("yyyyMMddHHmmss"); + + if (arg is string || arg is ValueType || arg is Nullable) + return arg.ToString(); + + if (arg != null) + { + if (arg is Expression) + { + var obj = arg as Expression; + var result = Resolve(obj); + return MD5Encryption.Encrypt(result); + } + if (arg.GetType().IsClass) + { + return MD5Encryption.Encrypt(JsonConvert.SerializeObject(arg)); + } + } + return string.Empty; + } + + private static string Resolve(Expression expression) + { + if (expression is LambdaExpression) + { + var lambda = expression as LambdaExpression; + expression = lambda.Body; + return Resolve(expression); + } + if (expression is BinaryExpression) + { + var binary = expression as BinaryExpression; + if (binary.Left is MemberExpression && binary.Right is ConstantExpression)//解析x=>x.Name=="123" x.Age==123这类 + return ResolveFunc(binary.Left, binary.Right, binary.NodeType); + if (binary.Left is MethodCallExpression && binary.Right is ConstantExpression)//解析x=>x.Name.Contains("xxx")==false这类的 + { + var value = (binary.Right as ConstantExpression).Value; + return ResolveLinqToObject(binary.Left, value, binary.NodeType); + } + if (binary.Left is MemberExpression && binary.Right is MemberExpression + || binary.Left is MemberExpression && binary.Right is UnaryExpression)//解析x=>x.Date==DateTime.Now这种 + { + var lambda = Expression.Lambda(binary.Right); + var fn = lambda.Compile(); + var value = Expression.Constant(fn.DynamicInvoke(null), binary.Right.Type); + return ResolveFunc(binary.Left, value, binary.NodeType); + } + } + if (expression is UnaryExpression) + { + var unary = expression as UnaryExpression; + if (unary.Operand is MethodCallExpression)//解析!x=>x.Name.Contains("xxx")或!array.Contains(x.Name)这类 + return ResolveLinqToObject(unary.Operand, false); + if (unary.Operand is MemberExpression && unary.NodeType == ExpressionType.Not)//解析x=>!x.isDeletion这样的 + { + var constant = Expression.Constant(false); + return ResolveFunc(unary.Operand, constant, ExpressionType.Equal); + } + } + if (expression is MemberExpression && expression.NodeType == ExpressionType.MemberAccess)//解析x=>x.isDeletion这样的 + { + var member = expression as MemberExpression; + var constant = Expression.Constant(true); + return ResolveFunc(member, constant, ExpressionType.Equal); + } + if (expression is MethodCallExpression)//x=>x.Name.Contains("xxx")或array.Contains(x.Name)这类 + { + var methodcall = expression as MethodCallExpression; + return ResolveLinqToObject(methodcall, true); + } + //已经修改过代码body应该不会是null值了 + if (!(expression is BinaryExpression body)) + return string.Empty; + var @operator = GetOperator(body.NodeType); + var left = Resolve(body.Left); + var right = Resolve(body.Right); + var result = string.Format("({0} {1} {2})", left, @operator, right); + return result; + } + + private static string ResolveFunc(Expression left, Expression right, ExpressionType expressiontype) + { + var name = (left as MemberExpression).Member.Name; + var value = (right as ConstantExpression).Value; + var @operator = GetOperator(expressiontype); + return name + @operator + value; + } + + private static string ResolveLinqToObject(Expression expression, object value, ExpressionType? expressiontype = null) + { + var methodCall = expression as MethodCallExpression; + var methodName = methodCall.Method.Name; + switch (methodName) + { + case "Contains": + return methodCall.Object != null ? Like(methodCall) : In(methodCall, value); + + case "Count": + return Len(methodCall, value, expressiontype.Value); + + case "LongCount": + return Len(methodCall, value, expressiontype.Value); + + default: + throw new Exception(string.Format("不支持{0}方法的查找!", methodName)); + } + } + + private static string GetOperator(ExpressionType expressiontype) + { + return expressiontype switch + { + ExpressionType.And => "and", + ExpressionType.AndAlso => "and", + ExpressionType.Or => "or", + ExpressionType.OrElse => "or", + ExpressionType.Equal => "=", + ExpressionType.NotEqual => "<>", + ExpressionType.LessThan => "<", + ExpressionType.LessThanOrEqual => "<=", + ExpressionType.GreaterThan => ">", + ExpressionType.GreaterThanOrEqual => ">=", + _ => throw new Exception(string.Format("不支持{0}此种运算符查找!" + expressiontype)) + }; + } + + private static string In(MethodCallExpression expression, object isTrue) + { + var argument1 = (expression.Arguments[0] as MemberExpression).Expression as ConstantExpression; + var argument2 = expression.Arguments[1] as MemberExpression; + var fieldArray = argument1.Value.GetType().GetFields().First(); + var array = fieldArray.GetValue(argument1.Value) as object[]; + var setInPara = new List(); + for (var i = 0; i < array.Length; i++) + { + var value = array[i].ToString(); + setInPara.Add(value); + } + var name = argument2.Member.Name; + var @operator = Convert.ToBoolean(isTrue) ? "in" : " not in"; + var compName = string.Join(",", setInPara); + var result = string.Format("{0} {1} ({2})", name, @operator, compName); + return result; + } + + private static string Like(MethodCallExpression expression) + { + var temp = expression.Arguments[0]; + var lambda = Expression.Lambda(temp); + var fn = lambda.Compile(); + var tempValue = Expression.Constant(fn.DynamicInvoke(null), temp.Type); + var value = string.Format("%{0}%", tempValue); + var name = (expression.Object as MemberExpression).Member.Name; + var result = string.Format("{0} like {1}", name, value); + return result; + } + + private static string Len(MethodCallExpression expression, object value, ExpressionType expressiontype) + { + object name = (expression.Arguments[0] as MemberExpression).Member.Name; + var @operator = GetOperator(expressiontype); + var result = string.Format("len({0}){1}{2}", name, @operator, value); + return result; + } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/Attributes/CacheAttribute.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/Attributes/CacheAttribute.cs new file mode 100644 index 0000000..ad9014a --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/Attributes/CacheAttribute.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Aop; + +/// +/// 缓存结果特性 +/// +public class CacheAttribute : Attribute +{ + /// + /// RedisKey前缀 + /// + public string KeyPrefix { get; set; } + + /// + /// 过期时间 + /// + public TimeSpan? AbsoluteExpiration { get; set; } + + /// + /// 自定义KEY + /// + public string CustomKeyValue { get; set; } + + /// + /// 是否删除 + /// + public bool IsDelete { get; set; } = false; + + /// + /// 存储类型 + /// + public string StoreType { get; set; } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/GlobalUsing.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/GlobalUsing.cs new file mode 100644 index 0000000..58094d4 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/GlobalUsing.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +global using MoYu.DataEncryption; +global using MoYu.Reflection; +global using MoYu.Reflection.Extensions; +global using Microsoft.Extensions.DependencyInjection; +global using Newtonsoft.Json; +global using SimpleAdmin.Cache; +global using System.Linq.Expressions; +global using System.Reflection; diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/SimpleAdmin.Plugin.Aop.csproj b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/SimpleAdmin.Plugin.Aop.csproj new file mode 100644 index 0000000..99705fb --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/SimpleAdmin.Plugin.Aop.csproj @@ -0,0 +1,7 @@ + + + + + + + diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/SimpleAdmin.Plugin.Aop.xml b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/SimpleAdmin.Plugin.Aop.xml new file mode 100644 index 0000000..0e63c4a --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Aop/SimpleAdmin.Plugin.Aop.xml @@ -0,0 +1,134 @@ + + + + SimpleAdmin.Plugin.Aop + + + + + Aop + 这里没有继承IGlobalDispatchProxy是因为IGlobalDispatchProxy会把一些没有必要的方法也aop了 + + + + + 当前服务实例 + + + + + 服务提供器,可以用来解析服务,如:Services.GetService() + + + + + 方法 + + + + + + + + + 异步无返回值 + + + + + + + + + 异步带返回值 + + + + + + + + + + 方法执行之后 + + 方法 + 返回值 + 参数列表 + + + + 方法执行之前 + + 方法 + 参数列表 + + + + + 检查缓存里是否有数据 + + 方法 + 参数列表 + + + + 写数据到缓存 + + 方法 + 参数列表 + 返回值 + + + + 自定义缓存Key + + 前缀 + 方法 + 参数 + + + + + 获取缓存Key + + + + + object 转 string + + + + + + + 缓存结果特性 + + + + + RedisKey前缀 + + + + + 过期时间 + + + + + 自定义KEY + + + + + 是否删除 + + + + + 存储类型 + + + + diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Const/MobileConst.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Const/MobileConst.cs new file mode 100644 index 0000000..6a7722e --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Const/MobileConst.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 移动端常量 +/// +public class MobileConst +{ + /// + /// 资源表缓存Key + /// + public const string CACHE_MOBILE_RESOURCE = CacheConst.CACHE_PREFIX_WEB + "MobileResource:"; + + /// + /// 用户有哪些移动端资源 + /// + public const string RELATION_SYS_USER_HAS_MOBILE_RESOURCE = "SYS_USER_HAS_MOBILE_RESOURCE"; + + /// + /// 角色有哪些移动端资源 + /// + public const string RELATION_SYS_ROLE_HAS_MOBILE_RESOURCE = "SYS_ROLE_HAS_MOBILE_RESOURCE"; +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileButtonController.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileButtonController.cs new file mode 100644 index 0000000..bafe7b4 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileButtonController.cs @@ -0,0 +1,86 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 移动端权限按钮控制器 +/// +[ApiDescriptionSettings("Mobile", Tag = "移动端权限按钮")] +[Route("sys/mobile/Button")] +[SuperAdmin] +public class MobileButtonController : IDynamicApiController +{ + private readonly IMobileButtonService _mobileButtonService; + + public MobileButtonController(IMobileButtonService mobileButtonService) + { + _mobileButtonService = mobileButtonService; + } + + /// + /// 按钮分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] ButtonPageInput input) + { + return await _mobileButtonService.Page(input); + } + + /// + /// 添加按钮 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加按钮")] + public async Task Add([FromBody] MobileButtonAddInput input) + { + await _mobileButtonService.Add(input); + } + + /// + /// 修改按钮 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改按钮")] + public async Task Edit([FromBody] MobileButtonEditInput input) + { + await _mobileButtonService.Edit(input); + } + + /// + /// 删除按钮 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除按钮")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _mobileButtonService.Delete(input); + } + + /// + /// 批量新增 + /// + /// + /// + [HttpPost("batch")] + [DisplayName("新增按钮")] + public async Task Batch([FromBody] MobileButtonAddInput input) + { + await _mobileButtonService.AddBatch(input); + } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileMenuController.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileMenuController.cs new file mode 100644 index 0000000..7559ea4 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileMenuController.cs @@ -0,0 +1,158 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 移动端菜单管理控制器 +/// +[ApiDescriptionSettings("Mobile", Tag = "移动端菜单管理")] +[Route("sys/mobile/Menu")] +[SuperAdmin] +public class MobileMenuController : IDynamicApiController +{ + private readonly IMobileMenuService _mobileMenuService; + private readonly IMobileResourceService _resourceService; + private readonly ISysRoleService _roleService; + + public MobileMenuController(IMobileMenuService mobileMenuService, IMobileResourceService resourceService, ISysRoleService roleService) + { + _mobileMenuService = mobileMenuService; + _resourceService = resourceService; + _roleService = roleService; + } + + /// + /// 模块选择 + /// + /// + [HttpGet("moduleSelector")] + public async Task ModuleSelector() + { + return await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MODULE); + } + + /// + /// 获取菜单树 + /// + /// + [HttpGet("tree")] + public async Task Tree([FromQuery] MenuTreeInput input) + { + return await _mobileMenuService.Tree(input); + ; + } + + /// + /// 获取角色授权资源树 + /// + /// + [HttpGet("resourceTreeSelector")] + public async Task ResourceTreeSelector() + { + return await _resourceService.ResourceTreeSelector(); + } + + /// + /// 获取角色拥有移动端资源 + /// + /// + /// + [HttpGet("roleOwnMobileMenu")] + public async Task RoleOwnMobileMenu([FromQuery] BaseIdInput input) + { + return await _roleService.OwnResource(input, MobileConst.RELATION_SYS_ROLE_HAS_MOBILE_RESOURCE); + } + + + + /// + /// 获取菜单树选择器 + /// + /// + [HttpGet("menuTreeSelector")] + public async Task MenuTreeSelector([FromQuery] MenuTreeInput input) + { + return await _mobileMenuService.Tree(input); + } + + /// + /// 给角色授权移动端资源 + /// + /// + /// + [HttpPost("grantRoleMobileResource")] + [DisplayName("角色授权移动端资源")] + public async Task GrantRoleMobileResource([FromBody] GrantResourceInput input) + { + await _mobileMenuService.GrantRoleMobileResource(input); + } + + + + /// + /// 添加菜单 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加菜单")] + public async Task Add([FromBody] MobileMenuAddInput input) + { + await _mobileMenuService.Add(input); + } + + /// + /// 编辑菜单 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("编辑菜单")] + public async Task Edit([FromBody] MobileMenuEditInput input) + { + await _mobileMenuService.Edit(input); + } + + /// + /// 获取菜单详情 + /// + /// + [HttpGet("detail")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _mobileMenuService.Detail(input); + ; + } + + /// + /// 删除菜单 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除菜单")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _mobileMenuService.Delete(input); + } + + /// + /// 更改模块 + /// + /// + /// + [HttpPost("changeModule")] + [DisplayName("更改模块")] + public async Task ChangeModule([FromBody] MenuChangeModuleInput input) + { + await _mobileMenuService.ChangeModule(input); + } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileModuleController.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileModuleController.cs new file mode 100644 index 0000000..1bd96e0 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileModuleController.cs @@ -0,0 +1,86 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 移动端模块管理 +/// +[ApiDescriptionSettings("Mobile", Tag = "移动端模块管理")] +[Route("sys/mobile/Module")] +[SuperAdmin] +public class MobileModuleController : IDynamicApiController +{ + private readonly IMobileModuleService _moduleService; + + public MobileModuleController(IMobileModuleService moduleService) + { + _moduleService = moduleService; + } + + /// + /// 模块分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] ModulePageInput input) + { + return await _moduleService.Page(input); + } + + /// + /// 添加模块 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加模块")] + public async Task Add([FromBody] MobileModuleAddInput input) + { + await _moduleService.Add(input); + } + + /// + /// 修改模块 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改模块")] + public async Task Edit([FromBody] MobileModuleEditInput input) + { + await _moduleService.Edit(input); + } + + /// + /// 获取模块详情 + /// + /// + /// + [HttpGet("detail")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _moduleService.Detail(input); + } + + + /// + /// 删除模块 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除模块")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _moduleService.Delete(input); + } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileUserCenterController.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileUserCenterController.cs new file mode 100644 index 0000000..fea8d00 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Controllers/MobileUserCenterController.cs @@ -0,0 +1,96 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 用户个人信息控制器 +/// +[ApiDescriptionSettings("Mobile", Tag = "移动端用户个人信息控制器")] +[Route("mobile/UserCenter")] +public class MobileUserCenterController : IDynamicApiController +{ + private readonly IMobileUserCenterService _mobileUserCenterService; + private readonly IUserCenterService _userCenterService; + + public MobileUserCenterController(IUserCenterService userCenterService, IMobileUserCenterService mobileUserCenterService) + { + _mobileUserCenterService = mobileUserCenterService; + _userCenterService = userCenterService; + } + + /// + /// 获取个人菜单 + /// + /// + [HttpGet("loginMobileMenu")] + public async Task LoginMobileMenu() + { + return await _mobileUserCenterService.GetOwnMobileMenu(); + } + + + /// + /// 获取用户信息 + /// + /// + [HttpGet("getLoginUser")] + public async Task GetLoginUser() + { + return await _mobileUserCenterService.GetLoginUser(); + } + + + /// + /// 编辑个人信息 + /// + /// + /// + [HttpPost("updateUserInfo")] + [DisplayName("编辑个人信息")] + public async Task UpdateUserInfo([FromBody] UpdateInfoInput input) + { + await _userCenterService.UpdateUserInfo(input); + } + + /// + /// 修改密码 + /// + /// + /// + [HttpPost("updatePassword")] + [DisplayName("修改密码")] + public async Task UpdatePassword([FromBody] UpdatePasswordInput input) + { + await _userCenterService.UpdatePassword(input); + } + + /// + /// 获取登录用户的站内信分页 + /// + /// + /// + [HttpGet("loginUnreadMessagePage")] + public async Task LoginUnreadMessagePage([FromQuery] MessagePageInput input) + { + return await _userCenterService.LoginMessagePage(input); + } + + /// + /// 读取登录用户站内信详情 + /// + /// + /// + [HttpGet("loginUnreadMessageDetail")] + public async Task LoginUnreadMessageDetail([FromQuery] MessageDetailInput input) + { + return await _userCenterService.LoginMessageDetail(input); + } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Entity/MobileResource.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Entity/MobileResource.cs new file mode 100644 index 0000000..378e8e1 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Entity/MobileResource.cs @@ -0,0 +1,112 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 资源 +/// +[SugarTable("mobile_resource", TableDescription = "移动资源")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +[CodeGen] +public class MobileResource : BaseEntity +{ + /// + /// 父id + /// + [SugarColumn(ColumnName = "ParentId", ColumnDescription = "父id", IsNullable = true)] + public virtual long? ParentId { get; set; } + + /// + /// 标题 + /// + [SugarColumn(ColumnName = "Title", ColumnDescription = "标题", Length = 200)] + public virtual string Title { get; set; } + + /// + /// 别名 + /// + [SugarColumn(ColumnName = "Name", ColumnDescription = "别名", Length = 200, IsNullable = true)] + public string Name { get; set; } + + /// + /// 描述 + /// + [SugarColumn(ColumnName = "Description", ColumnDescription = "描述", Length = 200, IsNullable = true)] + public string Description { get; set; } + + + /// + /// 编码 + /// + [SugarColumn(ColumnName = "Code", ColumnDescription = "编码", Length = 200, IsNullable = true)] + public virtual string Code { get; set; } + + /// + /// 分类 + /// + [SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)] + public string Category { get; set; } + + /// + /// 模块 + /// + [SugarColumn(ColumnName = "Module", ColumnDescription = "所属模块Id", IsNullable = true)] + public virtual long? Module { get; set; } + + /// + /// 菜单类型 + /// + [SugarColumn(ColumnName = "MenuType", ColumnDescription = "菜单类型", Length = 200, IsNullable = true)] + public virtual string MenuType { get; set; } + + /// + /// 路径 + /// + [SugarColumn(ColumnName = "Path", ColumnDescription = "路径", IsNullable = true)] + public virtual string Path { get; set; } + + + /// + /// 图标 + /// + [SugarColumn(ColumnName = "Icon", ColumnDescription = "图标", Length = 200, IsNullable = true)] + public virtual string Icon { get; set; } + + /// + /// 颜色 + /// + [SugarColumn(ColumnName = "Color", ColumnDescription = "颜色", Length = 200, IsNullable = true)] + public string Color { get; set; } + + /// + /// 排序码 + /// + [SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)] + public int? SortCode { get; set; } + + /// + /// 颜色 + /// + [SugarColumn(ColumnName = "RegType", ColumnDescription = "规则类型", Length = 200, IsNullable = true)] + public string RegType { get; set; } + + /// + /// 菜单元标签 + /// + [SugarColumn(IsIgnore = true)] + public MobleMeta Meta { get; set; } + + /// + /// 字节点 + /// + [SugarColumn(IsIgnore = true)] + public List Children { get; set; } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/GlobalUsing.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/GlobalUsing.cs new file mode 100644 index 0000000..6116762 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/GlobalUsing.cs @@ -0,0 +1,35 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +global using MoYu; +global using MoYu.DependencyInjection; +global using MoYu.FriendlyException; +global using MoYu.ViewEngine; +global using Mapster; +global using Microsoft.AspNetCore.Builder; +global using Microsoft.AspNetCore.Hosting; +global using Microsoft.AspNetCore.Mvc; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Logging; +global using SimpleAdmin.Core; +global using SimpleAdmin.Core.Utils; +global using SimpleTool; +global using System.ComponentModel.DataAnnotations; +global using System.Text; +global using MoYu.DynamicApiController; +global using System.ComponentModel; +global using SimpleAdmin.SqlSugar; +global using SqlSugar; +global using SimpleAdmin.System; +global using SimpleAdmin.Cache; +global using System.Reflection; +global using Masuit.Tools; +global using NewLife.Serialization; +global using NewLife; diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Mobile.Development.json b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Mobile.Development.json new file mode 100644 index 0000000..046b78f --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Mobile.Development.json @@ -0,0 +1,12 @@ +{ + //swagger分组设置 + "[openapi:Mobile]": { + "Order": 89, //分组排序,int 类型,数字越大排前面,默认 0 + "Title": "移动端" //配置分组标题,string 类型 + }, + //代码生成器设置 + "MobileSettings": { + "InitTable": false, //是否初始化表结构 + "InitSeedData": false, //是否初始化种子数据 + } +} \ No newline at end of file diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Mobile.Production.json b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Mobile.Production.json new file mode 100644 index 0000000..046b78f --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Mobile.Production.json @@ -0,0 +1,12 @@ +{ + //swagger分组设置 + "[openapi:Mobile]": { + "Order": 89, //分组排序,int 类型,数字越大排前面,默认 0 + "Title": "移动端" //配置分组标题,string 类型 + }, + //代码生成器设置 + "MobileSettings": { + "InitTable": false, //是否初始化表结构 + "InitSeedData": false, //是否初始化种子数据 + } +} \ No newline at end of file diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Options/MobileSettingsOptions.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Options/MobileSettingsOptions.cs new file mode 100644 index 0000000..f7fd87f --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Options/MobileSettingsOptions.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using MoYu.ConfigurableOptions; + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 代码生成器配置 +/// +public class MobileSettingsOptions : BaseOptions, IConfigurableOptions +{ +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/Json/seed_mobile_resource.json b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/Json/seed_mobile_resource.json new file mode 100644 index 0000000..8640870 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/Json/seed_mobile_resource.json @@ -0,0 +1,604 @@ +{ + "RECORDS": [ + { + "Id": "425458771095621", + "ParentId": "", + "Title": "业务", + "Name": "", + "Description": "业务", + "Code": "system", + "Category": "MODULE", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "zondicons:news-paper", + "Color": "#1890ff", + "SortCode": "99", + "RegType": "", + "Status": "ENABLE", + "CreateTime": "2025-6-25 13:28:20.987", + "UpdateTime": "2025-6-25 15:29:21.703", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425458936266821", + "ParentId": "", + "Title": "移动办公", + "Name": "", + "Description": "移动办公", + "Code": "", + "Category": "MODULE", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "zondicons:dashboard", + "Color": "#05a045", + "SortCode": "99", + "RegType": "", + "Status": "ENABLE", + "CreateTime": "2025-6-25 13:28:20.993", + "UpdateTime": "2025-6-26 16:04:46.897", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425472310554693", + "ParentId": "0", + "Title": "机构管理", + "Name": "", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "425458771095621", + "MenuType": "MENU", + "Path": "/pages/biz/org/index", + "Icon": "ep:data-board", + "Color": "#f5511e", + "SortCode": "1", + "RegType": "true", + "Status": "ENABLE", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-30 10:42:19.273", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425472601616453", + "ParentId": "0", + "Title": "岗位管理", + "Name": "", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "425458936266821", + "MenuType": "MENU", + "Path": "/pages/biz/position/index", + "Icon": "zondicons:store-front", + "Color": "#9c28b1", + "SortCode": "6", + "RegType": "true", + "Status": "ENABLE", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-7-2 14:28:09.923", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425472851824709", + "ParentId": "0", + "Title": "人员管理", + "Name": "", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "425458771095621", + "MenuType": "MENU", + "Path": "/pages/biz/user/index", + "Icon": "zondicons:location-restroom", + "Color": "#26a59a", + "SortCode": "9", + "RegType": "true", + "Status": "ENABLE", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-30 10:43:23.757", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425474847338565", + "ParentId": "0", + "Title": "更多", + "Name": "", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "425458771095621", + "MenuType": "CATALOG", + "Path": "", + "Icon": "zondicons:navigation-more", + "Color": "#f1627e", + "SortCode": "14", + "RegType": "true", + "Status": "ENABLE", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-30 11:32:11.547", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425476704763973", + "ParentId": "0", + "Title": "审批", + "Name": "", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "425458936266821", + "MenuType": "MENU", + "Path": "/pages/flw/task/index", + "Icon": "uiw:mobile", + "Color": "#fcc02e", + "SortCode": "18", + "RegType": "true", + "Status": "ENABLE", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-30 11:32:51.867", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425710965174341", + "ParentId": "425472310554693", + "Title": "新增机构", + "Name": "", + "Description": "", + "Code": "mobileBizOrgAdd", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "99", + "RegType": "", + "Status": "", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-25 14:20:51.037", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425711012839493", + "ParentId": "425472310554693", + "Title": "编辑机构", + "Name": "", + "Description": "", + "Code": "mobileBizOrgEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "99", + "RegType": "", + "Status": "", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-25 14:20:51.037", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425711060901957", + "ParentId": "425472310554693", + "Title": "删除机构", + "Name": "", + "Description": "", + "Code": "mobileBizOrgDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "99", + "RegType": "", + "Status": "", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-25 14:20:51.037", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425711343288389", + "ParentId": "425472601616453", + "Title": "新增岗位", + "Name": "", + "Description": "", + "Code": "mobileBizPositionAdd", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "99", + "RegType": "", + "Status": "", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-25 14:20:51.037", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425711397343301", + "ParentId": "425472601616453", + "Title": "编辑岗位", + "Name": "", + "Description": "", + "Code": "mobileBizPositionEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "99", + "RegType": "", + "Status": "", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-25 14:20:51.037", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425711457501253", + "ParentId": "425472601616453", + "Title": "删除岗位", + "Name": "", + "Description": "", + "Code": "mobileBizPositionDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "99", + "RegType": "", + "Status": "", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-25 14:20:51.037", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425711559307333", + "ParentId": "425472851824709", + "Title": "新增人员", + "Name": "", + "Description": "", + "Code": "mobileBizUserAdd", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "99", + "RegType": "", + "Status": "", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-25 14:20:51.037", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425711600533573", + "ParentId": "425472851824709", + "Title": "编辑人员", + "Name": "", + "Description": "", + "Code": "mobileBizUserEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "99", + "RegType": "", + "Status": "", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-25 14:20:51.037", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425711647805509", + "ParentId": "425472851824709", + "Title": "删除人员", + "Name": "", + "Description": "", + "Code": "mobileBizUserDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "99", + "RegType": "", + "Status": "", + "CreateTime": "2025-6-25 13:28:20.997", + "UpdateTime": "2025-6-25 14:20:51.037", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "693329840169029", + "ParentId": "425474847338565", + "Title": "文件管理", + "Name": "", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "425458771095621", + "MenuType": "MENU", + "Path": "/pages/file/index", + "Icon": "ep:files", + "Color": "#ffb74e", + "SortCode": "99", + "RegType": "true", + "Status": "ENABLE", + "CreateTime": "2025-7-2 13:46:22.527", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "693342308134981", + "ParentId": "693329840169029", + "Title": "新增文件", + "Name": "", + "Description": "", + "Code": "bizFileAdd", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "1", + "RegType": "", + "Status": "", + "CreateTime": "2025-7-2 14:37:10.51", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "693342308134982", + "ParentId": "693329840169029", + "Title": "编辑文件", + "Name": "", + "Description": "", + "Code": "bizFileEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "2", + "RegType": "", + "Status": "", + "CreateTime": "2025-7-2 14:37:10.51", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "693342308134983", + "ParentId": "693329840169029", + "Title": "删除文件", + "Name": "", + "Description": "", + "Code": "bizFileDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "3", + "RegType": "", + "Status": "", + "CreateTime": "2025-7-2 14:37:10.51", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "693342308134984", + "ParentId": "693329840169029", + "Title": "批量删除文件", + "Name": "", + "Description": "", + "Code": "bizFileBatchDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "4", + "RegType": "", + "Status": "", + "CreateTime": "2025-7-2 14:37:10.51", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "693342308134985", + "ParentId": "693329840169029", + "Title": "导入文件", + "Name": "", + "Description": "", + "Code": "bizFileImport", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "5", + "RegType": "", + "Status": "", + "CreateTime": "2025-7-2 14:37:10.51", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "693342308134986", + "ParentId": "693329840169029", + "Title": "导出文件", + "Name": "", + "Description": "", + "Code": "bizFileExport", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "6", + "RegType": "", + "Status": "", + "CreateTime": "2025-7-2 14:37:10.51", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "693342308134987", + "ParentId": "693329840169029", + "Title": "批量编辑文件", + "Name": "", + "Description": "", + "Code": "bizFileBatchEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Icon": "", + "Color": "", + "SortCode": "7", + "RegType": "", + "Status": "", + "CreateTime": "2025-7-2 14:37:10.51", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + } + ] +} \ No newline at end of file diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/Json/seed_sys_relation_mobile.json b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/Json/seed_sys_relation_mobile.json new file mode 100644 index 0000000..01da12a --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/Json/seed_sys_relation_mobile.json @@ -0,0 +1,39 @@ +{ + "RECORDS": [ + { + "Id": "425798456791109", + "ObjectId": "212725263001001", + "TargetId": "425472310554693", + "Category": "SYS_ROLE_HAS_MOBILE_RESOURCE", + "ExtJson": "{\"MenuId\":425472310554693,\"ButtonInfo\":[425710965174341,425711012839493,425711060901957]}" + }, + { + "Id": "425798456791110", + "ObjectId": "212725263001001", + "TargetId": "425472601616453", + "Category": "SYS_ROLE_HAS_MOBILE_RESOURCE", + "ExtJson": "{\"MenuId\":425472601616453,\"ButtonInfo\":[425711343288389,425711397343301,425711457501253]}" + }, + { + "Id": "425798456791111", + "ObjectId": "212725263001001", + "TargetId": "425472851824709", + "Category": "SYS_ROLE_HAS_MOBILE_RESOURCE", + "ExtJson": "{\"MenuId\":425472851824709,\"ButtonInfo\":[425711559307333,425711600533573,425711647805509]}" + }, + { + "Id": "425798456791112", + "ObjectId": "212725263001001", + "TargetId": "425474847338565", + "Category": "SYS_ROLE_HAS_MOBILE_RESOURCE", + "ExtJson": "{\"MenuId\":425474847338565,\"ButtonInfo\":[]}" + }, + { + "Id": "425798456791113", + "ObjectId": "212725263001001", + "TargetId": "425476704763973", + "Category": "SYS_ROLE_HAS_MOBILE_RESOURCE", + "ExtJson": "{\"MenuId\":425476704763973,\"ButtonInfo\":[]}" + } + ] +} \ No newline at end of file diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/Json/seed_sys_resource_mobile.json b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/Json/seed_sys_resource_mobile.json new file mode 100644 index 0000000..f0d376b --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/Json/seed_sys_resource_mobile.json @@ -0,0 +1,73 @@ +{ + "RECORDS": [ + { + "Id": "425378309881925", + "ParentId": "0", + "Title": "移动端管理", + "Name": "", + "Code": "", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "CATALOG", + "Path": "/7071669224309002240", + "Component": "", + "Icon": "mobile-outlined", + "Color": "", + "SortCode": "50", + "CreateTime": "2023-6-6 10:08:48.457", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425378520674373", + "ParentId": "425378309881925", + "Title": "模块管理", + "Name": "mobileModuleIndex", + "Code": "", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/mobile/module/index", + "Component": "mobile/resource/module/index", + "Icon": "build-outlined", + "Color": "", + "SortCode": "51", + "CreateTime": "2023-6-6 10:09:39.92", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + }, + { + "Id": "425378933755973", + "ParentId": "425378309881925", + "Title": "菜单管理", + "Name": "mobileMenuIndex", + "Code": "", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/mobile/menu/index", + "Component": "mobile/resource/menu/index", + "Icon": "appstore-add-outlined", + "Color": "", + "SortCode": "52", + "CreateTime": "2023-6-6 10:11:20.77", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "" + } + ] +} \ No newline at end of file diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/MobileResourceSeedData.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/MobileResourceSeedData.cs new file mode 100644 index 0000000..bca8770 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/MobileResourceSeedData.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 移动端资源表 +/// +public class MobileResourceSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_mobile_resource.json"); + } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/SysRelationSeedData.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/SysRelationSeedData.cs new file mode 100644 index 0000000..1fbe707 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/SysRelationSeedData.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 关系表种子数据 +/// +public class SysRelationSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_sys_relation_mobile.json"); + } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/SysResourceSeedData.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/SysResourceSeedData.cs new file mode 100644 index 0000000..8e3fef0 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SeedData/SysResourceSeedData.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 资源表种子数据 +/// +public class SysResourceSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_sys_resource_mobile.json"); + } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Button/Dto/ButtonInput.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Button/Dto/ButtonInput.cs new file mode 100644 index 0000000..a0c9eac --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Button/Dto/ButtonInput.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 添加按钮参数 +/// +public class MobileButtonAddInput : MobileResource +{ + /// + /// 父ID + /// + [Required(ErrorMessage = "ParentId不能为空")] + public override long? ParentId { get; set; } + + /// + /// 标题 + /// + [Required(ErrorMessage = "Title不能为空")] + public override string Title { get; set; } + + /// + /// 编码 + /// + [Required(ErrorMessage = "Code不能为空")] + public override string Code { get; set; } +} + +public class MobileButtonEditInput : MobileButtonAddInput +{ + /// + /// ID + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Button/IMobileButtonService.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Button/IMobileButtonService.cs new file mode 100644 index 0000000..6117451 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Button/IMobileButtonService.cs @@ -0,0 +1,52 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 权限按钮服务 +/// +public interface IMobileButtonService : ITransient +{ + /// + /// 添加按钮 + /// + /// 添加参数 + /// + Task Add(MobileButtonAddInput input); + + /// + /// 批量添加 + /// + /// + /// + Task> AddBatch(MobileButtonAddInput input); + + /// + /// 删除按钮 + /// + /// 删除参数 + /// + Task Delete(BaseIdListInput input); + + /// + /// 编辑按钮 + /// + /// 编辑参数 + /// + Task Edit(MobileButtonEditInput input); + + /// + /// 按钮分页查询 + /// + /// 查询条件 + /// 按钮分页列表 + Task> Page(ButtonPageInput input); +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Button/MobileMobileButtonService.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Button/MobileMobileButtonService.cs new file mode 100644 index 0000000..9378f26 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Button/MobileMobileButtonService.cs @@ -0,0 +1,187 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// +/// +public class MobileMobileButtonService : DbRepository, IMobileButtonService +{ + private readonly ILogger _logger; + private readonly IMobileResourceService _resourceService; + private readonly IRelationService _relationService; + + public MobileMobileButtonService(ILogger logger, IMobileResourceService resourceService, + IRelationService relationService) + { + _logger = logger; + _resourceService = resourceService; + _relationService = relationService; + } + + /// + public async Task> Page(ButtonPageInput input) + { + var query = Context.Queryable() + .Where(it => it.ParentId == input.ParentId && it.Category == CateGoryConst.RESOURCE_BUTTON) + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Title.Contains(input.SearchKey) || it.Path.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}") + .OrderBy(it => it.SortCode);//排序 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task Add(MobileButtonAddInput input) + { + await CheckInput(input);//检查参数 + var MobileResource = input.Adapt();//实体转换 + if (await InsertAsync(MobileResource))//插入数据 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_BUTTON);//刷新缓存 + } + + /// + public async Task> AddBatch(MobileButtonAddInput input) + { + var MobileResources = new List();//按钮列表 + var codeList = new List { "Add", "Edit", "Delete", "BatchDelete", "Import", "Export", "BatchEdit" };//code后缀 + var titleList = new List { "新增", "编辑", "删除", "批量删除", "导入", "导出", "批量编辑" };//title前缀 + var idList = new List();//Id列表 + for (var i = 0; i < codeList.Count; i++) + { + var id = CommonUtils.GetSingleId(); + MobileResources.Add(new MobileResource + { + Id = id, + Title = titleList[i] + input.Title,//标题等于前缀输入的值 + Code = input.Code + codeList[i],//code等于输入的值加后缀 + ParentId = input.ParentId, + SortCode = i + 1 + }); + idList.Add(id); + } + //遍历列表 + foreach (var MobileResource in MobileResources) + { + await CheckInput(MobileResource);//检查按钮参数 + } + //添加到数据库 + if (await InsertRangeAsync(MobileResources))//插入数据 + { + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_BUTTON);//刷新缓存 + return MobileResources.Select(it => it.Id).ToList(); + } + else + { + return new List(); + } + } + + /// + public async Task Edit(MobileButtonEditInput input) + { + await CheckInput(input);//检查参数 + var MobileResource = input.Adapt();//实体转换 + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await UpdateAsync(MobileResource);//更新按钮 + }); + if (result.IsSuccess)//如果成功了 + { + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_BUTTON);//资源表按钮刷新缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + //获取所有按钮集合 + var buttonList = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_BUTTON); + + #region 处理关系表角色资源信息 + + //获取所有菜单集合 + var menuList = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MENU); + //获取按钮的父菜单id集合 + var parentIds = buttonList.Where(it => ids.Contains(it.Id)).Select(it => it.ParentId.Value.ToString()).ToList(); + //获取关系表分类为SYS_ROLE_HAS_RESOURCE数据 + var roleResources = await _relationService.GetRelationByCategory(CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE); + //获取相关关系表数据 + var relationList = roleResources + .Where(it => parentIds.Contains(it.TargetId))//目标ID是父ID中 + .Where(it => it.ExtJson != null).ToList();//扩展信息不为空 + //遍历关系表 + relationList.ForEach(it => + { + var relationRoleResuorce = it.ExtJson.ToJsonEntity();//拓展信息转实体 + var buttonInfo = relationRoleResuorce.ButtonInfo;//获取按钮信息 + if (buttonInfo.Count > 0) + { + var diffArr = buttonInfo.Where(it => !buttonInfo.Contains(it)).ToList();//找出不同的元素(即交集的补集) + relationRoleResuorce.ButtonInfo = diffArr;//重新赋值按钮信息 + it.ExtJson = relationRoleResuorce.ToJson();//重新赋值拓展信息 + } + }); + + #endregion 处理关系表角色资源信息 + + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await DeleteByIdsAsync(ids.Cast().ToArray());//删除按钮 + if (relationList.Count > 0) + { + await Context.Updateable(relationList).UpdateColumns(it => it.ExtJson).ExecuteCommandAsync();//修改拓展信息 + } + }); + if (result.IsSuccess)//如果成功了 + { + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_BUTTON);//资源表按钮刷新缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE);//关系表刷新角色资源缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(MobileResource MobileResource) + { + //获取所有按钮和菜单 + var buttonList = await _resourceService.GetListAsync(new List { CateGoryConst.RESOURCE_BUTTON, CateGoryConst.RESOURCE_MENU }); + //判断code是否重复 + if (buttonList.Any(it => it.Code == MobileResource.Code && it.Id != MobileResource.Id)) + throw Oops.Bah($"存在重复的按钮编码:{MobileResource.Code}"); + //判断菜单是否存在 + if (!buttonList.Any(it => it.Id == MobileResource.ParentId)) + throw Oops.Bah($"不存在的父级菜单:{MobileResource.ParentId}"); + MobileResource.Category = CateGoryConst.RESOURCE_BUTTON;//设置分类为按钮 + } + + #endregion 方法 +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Menu/Dto/MobileMenuInput.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Menu/Dto/MobileMenuInput.cs new file mode 100644 index 0000000..1d7f257 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Menu/Dto/MobileMenuInput.cs @@ -0,0 +1,59 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 添加菜单参数 +/// +public class MobileMenuAddInput : MobileResource +{ + /// + /// 父ID + /// + [Required(ErrorMessage = "ParentId不能为空")] + public override long? ParentId { get; set; } + + /// + /// 标题 + /// + [Required(ErrorMessage = "Title不能为空")] + public override string Title { get; set; } + + /// + /// 菜单类型 + /// + public override string MenuType { get; set; } = SysResourceConst.MENU; + + /// + /// 模块 + /// + [Required(ErrorMessage = "Module不能为空")] + public override long? Module { get; set; } + + + /// + /// 图标 + /// + [Required(ErrorMessage = "Icon不能为空")] + public override string Icon { get; set; } +} + +/// +/// 编辑菜单输入参数 +/// +public class MobileMenuEditInput : MobileMenuAddInput +{ + /// + /// ID + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Menu/IMobileMenuService.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Menu/IMobileMenuService.cs new file mode 100644 index 0000000..b3a0879 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Menu/IMobileMenuService.cs @@ -0,0 +1,74 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 菜单服务 +/// +public interface IMobileMenuService : ITransient +{ + /// + /// 添加菜单 + /// + /// 添加参数 + /// + Task Add(MobileMenuAddInput input); + + /// + /// 详情 + /// + /// id + /// 详细信息 + Task Detail(BaseIdInput input); + + /// + /// 构建菜单树形结构 + /// + /// 菜单列表 + /// 父ID + /// 菜单形结构 + List ConstructMenuTrees(List resourceList, long parentId = 0); + + /// + /// 获取菜单树 + /// + /// 菜单树查询参数 + /// 菜单树列表 + Task> Tree(MenuTreeInput input); + + /// + /// 编辑菜单 + /// + /// 菜单编辑参数 + /// + Task Edit(MobileMenuEditInput input); + + /// + /// 删除菜单 + /// + /// 删除菜单参数 + /// + Task Delete(BaseIdListInput input); + + /// + /// 改变菜单模块 + /// + /// 改变菜单模块参数 + /// + Task ChangeModule(MenuChangeModuleInput input); + + /// + /// 角色授权移动端资源 + /// + /// + /// + Task GrantRoleMobileResource(GrantResourceInput input); +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Menu/MobileMenuService.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Menu/MobileMenuService.cs new file mode 100644 index 0000000..88f14ef --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Menu/MobileMenuService.cs @@ -0,0 +1,250 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using MoYu.EventBus; + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// +/// +public class MobileMenuService : DbRepository, IMobileMenuService +{ + private readonly ILogger _logger; + private readonly IMobileResourceService _resourceService; + private readonly IRelationService _relationService; + private readonly IEventPublisher _eventPublisher; + private readonly ISysRoleService _roleService; + + public MobileMenuService(ILogger logger, IMobileResourceService resourceService, IRelationService relationService, + IEventPublisher eventPublisher, ISysRoleService roleService) + { + _logger = logger; + _resourceService = resourceService; + _relationService = relationService; + _eventPublisher = eventPublisher; + _roleService = roleService; + } + + /// + public List ConstructMenuTrees(List resourceList, long parentId = 0) + { + //找下级资源ID列表 + var resources = resourceList.Where(it => it.ParentId == parentId).OrderBy(it => it.SortCode).ToList(); + if (resources.Count > 0)//如果数量大于0 + { + var data = new List(); + foreach (var item in resources)//遍历资源 + { + item.Children = ConstructMenuTrees(resourceList, item.Id);//添加子节点 + data.Add(item);//添加到列表 + } + return data;//返回结果 + } + return new List(); + } + + /// + public async Task> Tree(MenuTreeInput input) + { + //获取所有菜单 + var mobileResources = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MENU); + mobileResources = mobileResources.WhereIF(input.Module != null, it => it.Module.Value == input.Module.Value)//根据模块查找 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Title == input.SearchKey)//根据关键字查找 + .ToList(); + //构建菜单树 + var tree = ConstructMenuTrees(mobileResources); + return tree; + } + + /// + public async Task Add(MobileMenuAddInput input) + { + await CheckInput(input);//检查参数 + var mobileResource = input.Adapt();//实体转换 + + if (await InsertAsync(mobileResource))//插入数据 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_MENU);//刷新菜单缓存 + } + + /// + public async Task Edit(MobileMenuEditInput input) + { + await CheckInput(input);//检查参数 + var mobileResource = input.Adapt();//实体转换 + if (await UpdateAsync(mobileResource))//更新数据 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_MENU);//刷新菜单缓存 + } + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + //获取所有菜单和按钮 + var resourceList = await _resourceService.GetListAsync(new List { CateGoryConst.RESOURCE_MENU, CateGoryConst.RESOURCE_BUTTON }); + //找到要删除的菜单 + var mobileResources = resourceList.Where(it => ids.Contains(it.Id)).ToList(); + //查找内置菜单 + var system = mobileResources.Where(it => it.Code == SysResourceConst.SYSTEM).FirstOrDefault(); + if (system != null) + throw Oops.Bah($"不可删除系统菜单:{system.Title}"); + //需要删除的资源ID列表 + var resourceIds = new List(); + //遍历菜单列表 + mobileResources.ForEach(it => + { + //获取菜单所有子节点 + var child = _resourceService.GetChildListById(resourceList, it.Id, false); + //将子节点ID添加到删除资源ID列表 + resourceIds.AddRange(child.Select(it => it.Id).ToList()); + resourceIds.Add(it.Id);//添加到删除资源ID列表 + }); + ids.AddRange(resourceIds);//添加到删除ID列表 + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await DeleteByIdsAsync(ids.Cast().ToArray());//删除菜单和按钮 + await Context.Deleteable()//关系表删除对应SYS_ROLE_HAS_RESOURCE + .Where(it => it.Category == MobileConst.RELATION_SYS_ROLE_HAS_MOBILE_RESOURCE + && resourceIds.Contains(SqlFunc.ToInt64(it.TargetId))).ExecuteCommandAsync(); + }); + if (result.IsSuccess)//如果成功了 + { + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_MENU);//资源表菜单刷新缓存 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_BUTTON);//资源表按钮刷新缓存 + await _relationService.RefreshCache(MobileConst.RELATION_SYS_ROLE_HAS_MOBILE_RESOURCE);//关系表刷新缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + } + + /// + public async Task Detail(BaseIdInput input) + { + var mobileResources = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MENU); + var resource = mobileResources.Where(it => it.Id == input.Id).FirstOrDefault(); + return resource; + } + + /// + public async Task ChangeModule(MenuChangeModuleInput input) + { + var mobileResource = await Detail(new BaseIdInput { Id = input.Id }); + if (mobileResource != null) + { + if (mobileResource.Module == input.Module)//如果模块ID没变直接返回 + return; + if (mobileResource.ParentId != 0) + throw Oops.Bah($"非顶级菜单不可修改所属模块"); + //获取所有菜单和模块 + var resourceList = await _resourceService.GetListAsync(new List { CateGoryConst.RESOURCE_MENU, CateGoryConst.RESOURCE_MODULE }); + if (!resourceList.Any(it => it.Category == CateGoryConst.RESOURCE_MODULE && it.Id == input.Module.Value)) + throw Oops.Bah($"不存在的模块"); + //获取所有菜单 + var menuList = resourceList.Where(it => it.Category == CateGoryConst.RESOURCE_MENU).ToList(); + //获取需要改变模块菜单的所有子菜单 + var childList = _resourceService.GetChildListById(menuList, input.Id); + childList.ForEach(it => it.Module = input.Module); + //更新数据 + await UpdateRangeAsync(childList); + //刷新菜单缓存 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_MENU); + } + } + + /// + public async Task GrantRoleMobileResource(GrantResourceInput input) + { + var menuIds = input.GrantInfoList.Select(it => it.MenuId).ToList();//菜单ID + var extJsons = input.GrantInfoList.Select(it => it.ToJson()).ToList();//拓展信息 + var relationRoles = new List();//要添加的角色资源和授权关系表 + var sysRole = (await _roleService.GetListAsync()).Where(it => it.Id == input.Id).FirstOrDefault();//获取角色 + if (sysRole != null) + { + //遍历菜单列表 + for (var i = 0; i < menuIds.Count; i++) + { + //将角色资源添加到列表 + relationRoles.Add(new SysRelation + { + ObjectId = sysRole.Id, + TargetId = menuIds[i].ToString(), + Category = MobileConst.RELATION_SYS_ROLE_HAS_MOBILE_RESOURCE, + ExtJson = extJsons?[i] + }); + } + //事务 + var result = await Tenant.UseTranAsync(async () => + { + var relatioRep = ChangeRepository>();//切换仓储 + //如果不是代码生成,就删除老的 + if (!input.IsCodeGen) + await relatioRep.DeleteAsync(it => + it.ObjectId == sysRole.Id && (it.Category == MobileConst.RELATION_SYS_ROLE_HAS_MOBILE_RESOURCE + || it.Category == MobileConst.RELATION_SYS_USER_HAS_MOBILE_RESOURCE)); + await relatioRep.InsertRangeAsync(relationRoles);//添加新的 + }); + if (result.IsSuccess)//如果成功了 + { + await _relationService.RefreshCache(MobileConst.RELATION_SYS_ROLE_HAS_MOBILE_RESOURCE);//刷新关系缓存 + await _relationService.RefreshCache(MobileConst.RELATION_SYS_USER_HAS_MOBILE_RESOURCE);//刷新关系缓存 + await _eventPublisher.PublishAsync(EventSubscriberConst.CLEAR_USER_CACHE, new List { input.Id });//发送事件清除角色下用户缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0003); + } + } + } + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(MobileResource mobileResource) + { + mobileResource.Category = mobileResource.MenuType;//设置为菜单 + //获取所有菜单列表 + var menList = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MENU); + //判断是否有同级且同名的菜单 + if (menList.Any(it => it.ParentId == mobileResource.ParentId && it.Title == mobileResource.Title && it.Id != mobileResource.Id)) + throw Oops.Bah($"存在重复的菜单名称:{mobileResource.Title}"); + if (mobileResource.ParentId != 0) + { + //获取父级,判断父级ID正不正确 + var parent = menList.Where(it => it.Id == mobileResource.ParentId).FirstOrDefault(); + if (parent != null) + { + if (parent.Module != mobileResource.Module)//如果父级的模块和当前模块不一样 + throw Oops.Bah($"模块与上级菜单不一致"); + if (parent.Id == mobileResource.Id) + throw Oops.Bah($"上级菜单不能选择自己"); + } + else + { + throw Oops.Bah($"上级菜单不存在:{mobileResource.ParentId}"); + } + } + } + + #endregion 方法 +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Module/Dto/MobileModuleInput.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Module/Dto/MobileModuleInput.cs new file mode 100644 index 0000000..81577e5 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Module/Dto/MobileModuleInput.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 添加模块输入 +/// +public class MobileModuleAddInput : MobileResource +{ +} + +/// +/// 编辑模块输入 +/// +public class MobileModuleEditInput : MobileModuleAddInput +{ + /// + /// ID + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Module/IMobileModuleService.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Module/IMobileModuleService.cs new file mode 100644 index 0000000..5b2cc88 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Module/IMobileModuleService.cs @@ -0,0 +1,52 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 模块管理服务 +/// +public interface IMobileModuleService : ITransient +{ + /// + /// 添加模块 + /// + /// 添加参数 + /// + Task Add(MobileModuleAddInput input); + + /// + /// 删除模块 + /// + /// 删除参数 + /// + Task Delete(BaseIdListInput input); + + /// + /// 编辑模块 + /// + /// 编辑参数 + /// + Task Edit(MobileModuleEditInput input); + + /// + /// 分页查询 + /// + /// 分页参数 + /// + Task> Page(ModulePageInput input); + + /// + /// 详情 + /// + /// + /// + Task Detail(BaseIdInput input); +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Module/MobileModuleService.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Module/MobileModuleService.cs new file mode 100644 index 0000000..ccf10bd --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Module/MobileModuleService.cs @@ -0,0 +1,142 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// +/// +public class MobileModuleService : DbRepository, IMobileModuleService +{ + private readonly ILogger _logger; + private readonly ISimpleCacheService _simpleCacheService; + private readonly IMobileResourceService _mobileResourceService; + private readonly IRelationService _relationService; + + public MobileModuleService(ILogger logger, ISimpleCacheService simpleCacheService, + IMobileResourceService mobileResourceService, + IRelationService relationService) + { + _logger = logger; + _simpleCacheService = simpleCacheService; + _mobileResourceService = mobileResourceService; + _relationService = relationService; + } + + /// + public async Task> Page(ModulePageInput input) + { + var query = Context.Queryable() + .Where(it => it.Category == CateGoryConst.RESOURCE_MODULE)//模块 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Title.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}") + .OrderBy(it => it.SortCode);//排序 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task Add(MobileModuleAddInput input) + { + await CheckInput(input);//检查参数 + var sysResource = input.Adapt();//实体转换 + if (await InsertAsync(sysResource))//插入数据 + await _mobileResourceService.RefreshCache(CateGoryConst.RESOURCE_MODULE);//刷新缓存 + } + + /// + public async Task Edit(MobileModuleEditInput input) + { + await CheckInput(input);//检查参数 + var sysResource = input.Adapt();//实体转换 + if (await UpdateAsync(sysResource))//更新数据 + await _mobileResourceService.RefreshCache(CateGoryConst.RESOURCE_MODULE);//刷新缓存 + } + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + //获取所有 + var resourceList = await _mobileResourceService.GetListAsync(); + //找到要删除的模块 + var sysresources = resourceList.Where(it => ids.Contains(it.Id)).ToList(); + //查找内置模块 + var system = sysresources.Where(it => it.Code == SysResourceConst.SYSTEM).FirstOrDefault(); + if (system != null) + throw Oops.Bah($"不可删除系统内置模块:{system.Title}"); + //获取模块下的所有菜单Id列表 + var menuIds = resourceList.Where(it => ids.Contains(it.Module.ToLong()) && it.ParentId.ToLong() == SimpleAdminConst.ZERO) + .Select(it => it.Id).ToList(); + //需要删除的资源ID列表 + var resourceIds = new List(); + //遍历列表 + menuIds.ForEach(it => + { + //获取菜单所有子节点 + var child = _mobileResourceService.GetChildListById(resourceList, it, false); + //将子节点ID添加到删除ID列表 + resourceIds.AddRange(child.Select(it => it.Id).ToList()); + resourceIds.Add(it);//添加到删除ID列表 + }); + ids.AddRange(resourceIds); + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await DeleteByIdsAsync(ids.Cast().ToArray());//删除菜单和按钮 + await Context.Deleteable()//关系表删除对应SYS_ROLE_HAS_MOBILE_RESOURCE + .Where(it => it.Category == MobileConst.RELATION_SYS_ROLE_HAS_MOBILE_RESOURCE + && resourceIds.Contains(SqlFunc.ToInt64(it.TargetId))).ExecuteCommandAsync(); + }); + if (result.IsSuccess)//如果成功了 + { + await _mobileResourceService.RefreshCache();//资源表刷新缓存 + await _relationService.RefreshCache(MobileConst.RELATION_SYS_ROLE_HAS_MOBILE_RESOURCE);//关系表刷新缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + } + + /// + public async Task Detail(BaseIdInput input) + { + var mobileResource = await GetFirstAsync(it => it.Id == input.Id); + return mobileResource; + } + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(MobileResource sysResource) + { + var sysResourceList = await _mobileResourceService.GetListByCategory(CateGoryConst.RESOURCE_MODULE); + //判断是否从存在重复模块 + var hasSameName = sysResourceList.Any(it => it.Title == sysResource.Title && it.Id != sysResource.Id); + if (hasSameName) + { + throw Oops.Bah($"存在重复的模块:{sysResource.Title}"); + } + //设置为模块 + sysResource.Category = CateGoryConst.RESOURCE_MODULE; + } + + #endregion 方法 +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Resource/IMobileResourceService.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Resource/IMobileResourceService.cs new file mode 100644 index 0000000..06d4df9 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Resource/IMobileResourceService.cs @@ -0,0 +1,89 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 资源服务 +/// +public interface IMobileResourceService : ITransient +{ + /// + /// 获取所有的菜单和模块以及单页面列表,并按分类和排序码排序 + /// + /// 所有的菜单和模块以及单页面列表 + Task> GetaModuleAndMenuAndSpaList(); + + /// + /// 根据资源ID获取所有下级资源 + /// + /// 资源ID + /// 是否包含自己 + /// 资源列表 + Task> GetChildListById(long resId, bool isContainOneself = true); + + /// + /// 根据资源ID获取所有下级资源 + /// + /// 资源列表 + /// 资源ID + /// 是否包含自己 + /// 资源列表 + List GetChildListById(List sysResources, long resId, bool isContainOneself = true); + + /// + /// 获取ID获取Code列表 + /// + /// id列表 + /// 分类 + /// Code列表 + Task> GetCodeByIds(List ids, string category); + + /// + /// 获取资源列表 + /// + /// 资源分类列表 + /// + Task> GetListAsync(List? categorys = null); + + /// + /// 根据分类获取资源列表 + /// + /// 分类名称 + /// 资源列表 + Task> GetListByCategory(string category); + + /// + /// 根据菜单ID获取菜单 + /// + /// 菜单id列表 + /// 菜单列表 + Task> GetMenuByMenuIds(List menuIds); + + /// + /// 获取权限授权树 + /// + /// 路由列表 + /// + List PermissionTreeSelector(List routes); + + /// + /// 刷新缓存 + /// + /// 分类名称 + /// + Task RefreshCache(string category = null); + + /// + /// 角色授权资源树 + /// + /// + Task> ResourceTreeSelector(); +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Resource/MobileResourceService.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Resource/MobileResourceService.cs new file mode 100644 index 0000000..2ad6736 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/Resource/Resource/MobileResourceService.cs @@ -0,0 +1,410 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using StringHelper = SimpleTool.StringHelper; + +namespace SimpleAdmin.Plugin.Mobile; + +/// +public class MobileResourceService : DbRepository, IMobileResourceService +{ + private readonly ISimpleCacheService _simpleCacheService; + + public MobileResourceService(ISimpleCacheService simpleCacheService) + { + _simpleCacheService = simpleCacheService; + } + + /// + public async Task> GetCodeByIds(List ids, string category) + { + //根据分类获取所有 + var mobileResources = await GetListByCategory(category); + //条件查询 + var result = mobileResources.Where(it => ids.Contains(it.Id)).Select(it => it.Code).ToList(); + return result; + } + + /// + public async Task> GetListAsync(List? categoryList = null) + { + //定义结果 + var mobileResources = new List(); + + //定义资源分类列表,如果是空的则获取全部资源 + categoryList = categoryList != null + ? categoryList + : new List + { CateGoryConst.RESOURCE_MENU, CateGoryConst.RESOURCE_BUTTON, CateGoryConst.RESOURCE_SPA, CateGoryConst.RESOURCE_MODULE }; + //遍历列表 + foreach (var category in categoryList) + { + //根据分类获取到资源列表 + var data = await GetListByCategory(category); + //添加到结果集 + mobileResources.AddRange(data); + } + return mobileResources; + } + + /// + public async Task> GetaModuleAndMenuAndSpaList() + { + //获取所有的菜单和模块以及单页面列表, + var mobileResources = await GetListAsync(new List + { CateGoryConst.RESOURCE_MODULE, CateGoryConst.RESOURCE_MENU, CateGoryConst.RESOURCE_SPA }); + if (mobileResources != null) + { + //并按分类和排序码排序 + mobileResources = mobileResources.OrderBy(it => it.Category).ThenBy(it => it.SortCode).ToList(); + } + return mobileResources; + } + + /// + public async Task RefreshCache(string category = null) + { + //如果分类是空的 + if (category == null) + { + //删除全部key + _simpleCacheService.DelByPattern(MobileConst.CACHE_MOBILE_RESOURCE); + await GetListAsync(); + } + else + { + //否则只删除一个Key + _simpleCacheService.Remove(MobileConst.CACHE_MOBILE_RESOURCE + category); + await GetListByCategory(category); + } + } + + /// + public async Task> GetChildListById(long resId, bool isContainOneself = true) + { + //获取所有机构 + var mobileResources = await GetListAsync(); + //查找下级 + var childLsit = GetResourceChilden(mobileResources, resId); + if (isContainOneself)//如果包含自己 + { + //获取自己的机构信息 + var self = mobileResources.Where(it => it.Id == resId).FirstOrDefault(); + if (self != null) childLsit.Insert(0, self);//如果机构不为空就插到第一个 + } + return childLsit; + } + + /// + public List GetChildListById(List mobileResources, long resId, bool isContainOneself = true) + { + //查找下级 + var childLsit = GetResourceChilden(mobileResources, resId); + if (isContainOneself)//如果包含自己 + { + //获取自己的机构信息 + var self = mobileResources.Where(it => it.Id == resId).FirstOrDefault(); + if (self != null) childLsit.Insert(0, self);//如果机构不为空就插到第一个 + } + return childLsit; + } + + /// + public async Task> GetListByCategory(string category) + { + //先从Redis拿 + var mobileResources = _simpleCacheService.Get>(MobileConst.CACHE_MOBILE_RESOURCE + category); + if (mobileResources == null) + { + //redis没有就去数据库拿 + mobileResources = await base.GetListAsync(it => it.Category == category); + if (mobileResources.Count > 0) + { + //插入Redis + _simpleCacheService.Set(MobileConst.CACHE_MOBILE_RESOURCE + category, mobileResources); + } + } + return mobileResources; + } + + /// + public async Task> ResourceTreeSelector() + { + var resourceTreeSelectors = new List();//定义结果 + //获取模块列表 + var moduleList = await GetListByCategory(CateGoryConst.RESOURCE_MODULE); + //遍历模块 + foreach (var module in moduleList) + { + //将实体转换为ResourceTreeSelectorOutPut获取基本信息 + var resourceTreeSelector = module.Adapt(); + resourceTreeSelector.Menu = await GetRoleGrantResourceMenus(module.Id); + resourceTreeSelectors.Add(resourceTreeSelector); + } + return resourceTreeSelectors; + } + + /// + public List PermissionTreeSelector(List routes) + { + var permissions = new List();//权限列表 + + // 获取所有需要数据权限的控制器 + var controllerTypes = + App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(RolePermissionAttribute), false)); + foreach (var controller in controllerTypes) + { + //获取数据权限特性 + var routeAttributes = controller.GetCustomAttributes().ToList(); + if (routeAttributes == null) + continue; + var route = routeAttributes[0];//取第一个值 + var routeName = GetRouteName(controller.Name, route.Template);//赋值路由名称 + //如果路由包含在路由列表中 + if (routes.Contains(routeName)) + { + //获取所有方法 + var menthods = controller.GetMethods(); + //遍历方法 + foreach (var menthod in menthods) + { + //获取忽略数据权限特性 + var ignoreRolePermission = menthod.GetCustomAttribute(); + if (ignoreRolePermission == null)//如果是空的代表需要数据权限 + { + //获取接口描述 + var displayName = menthod.GetCustomAttribute(); + if (displayName != null) + { + //默认路由名称 + var apiRoute = StringHelper.FirstCharToLower(menthod.Name); + //获取get特性 + var requestGet = menthod.GetCustomAttribute(); + if (requestGet != null)//如果是get方法 + apiRoute = requestGet.Template; + else + { + //获取post特性 + var requestPost = menthod.GetCustomAttribute(); + if (requestPost != null)//如果是post方法 + apiRoute = requestPost.Template; + } + apiRoute = route.Template + $"/{apiRoute}"; + var apiName = displayName.DisplayName;//如果描述不为空则接口名称用描述的名称 + //合并 + var permissionName = apiRoute + $"[{apiName}]"; + //添加到权限列表 + permissions.Add(new PermissionTreeSelector + { + ApiName = apiName, + ApiRoute = apiRoute, + PermissionName = permissionName + }); + } + } + } + } + } + return permissions; + } + + /// + public async Task> GetMenuByMenuIds(List menuIds) + { + //获取所有菜单 + var menuList = await GetListByCategory(CateGoryConst.RESOURCE_MENU); + //获取菜单信息 + var menus = menuList.Where(it => menuIds.Contains(it.Id)).ToList(); + return menus; + } + + #region 方法 + + /// + /// 获取路由地址名称 + /// + /// 控制器地址 + /// 路由名称 + /// + private string GetRouteName(string controllerName, string template) + { + if (!template.StartsWith("/")) + template = "/" + template;//如果路由名称不是/开头则加上/防止控制器没写 + if (template.Contains("[controller]")) + { + controllerName = controllerName.Replace("Controller", "");//去掉Controller + controllerName = StringHelper.FirstCharToLower(controllerName);//转首字母小写写 + template = template.Replace("[controller]", controllerName);//替换[controller] + } + + return template; + } + + /// + /// 获取资源所有下级 + /// + /// 资源列表 + /// 父ID + /// + public List GetResourceChilden(List resourceList, long parentId) + { + //找下级资源ID列表 + var resources = resourceList.Where(it => it.ParentId == parentId).ToList(); + if (resources.Count > 0)//如果数量大于0 + { + var data = new List(); + foreach (var item in resources)//遍历资源 + { + var res = GetResourceChilden(resourceList, item.Id); + data.AddRange(res);//添加子节点; + data.Add(item);//添加到列表 + } + return data;//返回结果 + } + return new List(); + } + + /// + /// 获取上级 + /// + /// + /// + /// + public List GetResourceParent(List resourceList, long parentId) + { + //找上级资源ID列表 + var resources = resourceList.Where(it => it.Id == parentId).FirstOrDefault(); + if (resources != null)//如果数量大于0 + { + var data = new List(); + var parents = GetResourceParent(resourceList, resources.ParentId.Value); + data.AddRange(parents);//添加子节点; + data.Add(resources);//添加到列表 + return data;//返回结果 + } + return new List(); + } + + /// + /// 获取授权菜单 + /// + /// 模块ID + /// + public async Task> GetRoleGrantResourceMenus(long moduleId) + { + var roleGrantResourceMenus = new List();//定义结果 + var allMenuList = (await GetListByCategory(CateGoryConst.RESOURCE_MENU)).Where(it => it.Module == moduleId).ToList();//获取所有菜单列表 + var allButtonList = await GetListByCategory(CateGoryConst.RESOURCE_BUTTON);//获取所有按钮列表 + var parentMenuList = allMenuList.Where(it => it.ParentId == SimpleAdminConst.ZERO).ToList();//获取一级目录 + + //遍历一级目录 + foreach (var parent in parentMenuList) + { + //如果是目录则去遍历下级 + if (parent.MenuType == SysResourceConst.CATALOG) + { + //获取所有下级菜单 + var menuList = GetChildListById(allMenuList, parent.Id, false); + if (menuList.Count > 0)//如果有菜单 + { + //遍历下级菜单 + foreach (var menu in menuList) + { + //如果菜单类型是菜单 + if (menu.MenuType == SysResourceConst.MENU) + { + //获取菜单下按钮集合并转换成对应实体 + var buttonList = allButtonList.Where(it => it.ParentId == menu.Id).ToList(); + var buttons = buttonList.Adapt>(); + roleGrantResourceMenus.Add(new ResTreeSelector.RoleGrantResourceMenu + { + Id = menu.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId, + Title = GetRoleGrantResourceMenuTitle(menuList, menu),//菜单名称需要特殊处理因为有二级菜单 + Button = buttons + }); + } + else if (menu.MenuType == SysResourceConst.LINK || menu.MenuType == SysResourceConst.IFRAME)//如果是内链或者外链 + { + //直接加到资源列表 + roleGrantResourceMenus.Add(new ResTreeSelector.RoleGrantResourceMenu + { + Id = menu.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId, + Title = menu.Title + }); + } + } + } + else + { + //否则就将自己加到一级目录里面 + roleGrantResourceMenus.Add(new ResTreeSelector.RoleGrantResourceMenu + { + Id = parent.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId + }); + } + } + else + { + //就将自己加到一级目录里面 + var roleGrantResourcesButtons = new ResTreeSelector.RoleGrantResourceMenu + { + Id = parent.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId, + Title = parent.Title + }; + //如果菜单类型是菜单 + if (parent.MenuType == SysResourceConst.MENU) + { + //获取菜单下按钮集合并转换成对应实体 + var buttonList = allButtonList.Where(it => it.ParentId == parent.Id).ToList(); + roleGrantResourcesButtons.Button = buttonList.Adapt>(); + } + roleGrantResourceMenus.Add(roleGrantResourcesButtons); + } + } + return roleGrantResourceMenus; + } + + /// + /// 获取授权菜单类菜单名称 + /// + /// 菜单列表 + /// 当前菜单 + /// + private string GetRoleGrantResourceMenuTitle(List menuList, MobileResource menu) + { + //查找菜单上级 + var parentList = GetResourceParent(menuList, menu.ParentId.Value); + //如果有父级菜单 + if (parentList.Count > 0) + { + var titles = parentList.Select(it => it.Title).ToList();//提取出父级的name + var title = string.Join("- ", titles) + $"-{menu.Title}";//根据-分割,转换成字符串并在最后加上菜单的title + return title; + } + else + { + return menu.Title;//原路返回 + } + } + + #endregion 方法 +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/Dto/MobileUserCenterInput.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/Dto/MobileUserCenterInput.cs new file mode 100644 index 0000000..2151c40 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/Dto/MobileUserCenterInput.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/Dto/MobileUserCenterOutput.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/Dto/MobileUserCenterOutput.cs new file mode 100644 index 0000000..e9860f7 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/Dto/MobileUserCenterOutput.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 手机端登录用户信息 +/// +public class MobileLoginUserOutput : LoginUserOutput +{ + /// + /// 移动端按钮码集合 + /// + public List MobileButtonCodeList { get; set; } +} + +/// +/// 手机端 +/// +public class MobleMeta : Meta +{ + public string Type { get; set; } +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/IMobileUserCenterService.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/IMobileUserCenterService.cs new file mode 100644 index 0000000..9e0b2a2 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/IMobileUserCenterService.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// 移动端用户个人信息服务 +/// +public interface IMobileUserCenterService : ITransient +{ + /// + /// 获取个人移动端菜单 + /// + /// + Task> GetOwnMobileMenu(); + + /// + /// 获取登录用户信息 + /// + /// + Task GetLoginUser(); +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/MobileUserCenterService.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/MobileUserCenterService.cs new file mode 100644 index 0000000..52b4196 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Services/UserCenter/MobileUserCenterService.cs @@ -0,0 +1,233 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +public class MobileUserCenterService : IMobileUserCenterService +{ + private readonly IMobileMenuService _menuService; + private readonly IAuthService _authService; + private readonly ISimpleCacheService _simpleCacheService; + private readonly IRelationService _relationService; + private readonly IMobileResourceService _resourceService; + private readonly ISysUserService _userService; + + public MobileUserCenterService(IRelationService relationService, IMobileResourceService resourceService, ISysUserService userService, + IMobileMenuService menuService, IAuthService authService, ISimpleCacheService simpleCacheService) + { + _relationService = relationService; + _resourceService = resourceService; + _userService = userService; + _menuService = menuService; + _authService = authService; + _simpleCacheService = simpleCacheService; + } + + /// + public async Task> GetOwnMobileMenu() + { + var result = new List(); + //获取用户信息 + var userInfo = await _userService.GetUserByAccount(UserManager.UserAccount); + if (userInfo != null) + { + //获取用户所拥有的资源集合 + var resourceList = + await _relationService.GetRelationListByObjectIdAndCategory(userInfo.Id, MobileConst.RELATION_SYS_USER_HAS_MOBILE_RESOURCE); + if (resourceList.Count == 0)//如果没有就获取角色的 + //获取角色所拥有的资源集合 + resourceList = await _relationService.GetRelationListByObjectIdListAndCategory(userInfo.RoleIdList, + MobileConst.RELATION_SYS_ROLE_HAS_MOBILE_RESOURCE); + //定义菜单ID列表 + var menuIdList = new HashSet(); + //获取菜单集合 + menuIdList.AddRange(resourceList.Select(r => r.TargetId.ToLong()).ToList()); + //获取所有的菜单和模块以及单页面列表,并按分类和排序码排序 + var allModuleAndMenuAndSpaList = await _resourceService.GetaModuleAndMenuAndSpaList(); + var allModuleList = new List();//模块列表 + var allMenuList = new List();//菜单列表 + //遍历菜单集合 + allModuleAndMenuAndSpaList.ForEach(it => + { + switch (it.Category) + { + case CateGoryConst.RESOURCE_MODULE://模块 + allModuleList.Add(it);//添加到模块列表 + break; + case CateGoryConst.RESOURCE_MENU://菜单 + allMenuList.Add(it);//添加到菜单列表 + break; + } + }); + //获取我的菜单列表 + var myMenus = allMenuList.Where(it => menuIdList.Contains(it.Id)).ToList(); + // 对获取到的角色对应的菜单列表进行处理,获取父列表 + var parentList = GetMyParentMenus(allMenuList, myMenus); + myMenus.AddRange(parentList);//合并列表 + //获取我的模块信息Id列表 + var moduleIds = myMenus.Select(it => it.Module.Value).Distinct().ToList(); + //获取我的模块集合 + var myModules = GetMyModules(allModuleList, moduleIds, 0); + myMenus.AddRange(myModules);//模块添加到菜单列表 + //构建meta + ConstructMeta(myMenus); + //构建菜单树 + result = _menuService.ConstructMenuTrees(myMenus); + } + return result; + } + + /// + public async Task GetLoginUser() + { + var user = await _userService.GetUserById(UserManager.UserId); + if (user != null) + user.Avatar = await _userService.GetUserAvatar(user.Id);//获取头像 + var loginUser = user.Adapt(); + loginUser.MobileButtonCodeList = await GetButtonCodeList(UserManager.UserId);//获取移动端按钮码集合 + return loginUser; + } + + + + #region 方法 + + public async Task> GetButtonCodeList(long userId) + { + var buttonCodeList = new List();//按钮ID集合 + //获取用户移动资源集合 + var resourceList = await _relationService.GetRelationListByObjectIdAndCategory(userId, MobileConst.RELATION_SYS_USER_HAS_MOBILE_RESOURCE); + var buttonIdList = new List();//按钮ID集合 + if (resourceList.Count == 0)//如果有表示用户单独授权了不走用户角色 + { + //获取用户角色关系集合 + var roleList = await _relationService.GetRelationListByObjectIdAndCategory(userId, CateGoryConst.RELATION_SYS_USER_HAS_ROLE); + var roleIdList = roleList.Select(x => x.TargetId.ToLong()).ToList();//角色ID列表 + if (roleIdList.Count > 0)//如果该用户有角色 + { + resourceList = await _relationService.GetRelationListByObjectIdListAndCategory(roleIdList, + MobileConst.RELATION_SYS_ROLE_HAS_MOBILE_RESOURCE);//获取移动端资源集合 + } + } + resourceList.ForEach(it => + { + if (!string.IsNullOrEmpty(it.ExtJson)) + buttonIdList.AddRange(it.ExtJson.ToJsonEntity().ButtonInfo);//如果有按钮权限,将按钮ID放到buttonIdList + }); + if (buttonIdList.Count > 0) + { + buttonCodeList = await _resourceService.GetCodeByIds(buttonIdList, CateGoryConst.RESOURCE_BUTTON); + } + return buttonCodeList; + } + + + /// + /// 获取父菜单集合 + /// + /// 所有菜单列表 + /// 我的菜单列表 + /// + private List GetMyParentMenus(List allMenuList, List myMenus) + { + var parentList = new List(); + myMenus.ForEach(it => + { + //找到父ID对应的菜单 + var parent = allMenuList.Where(r => r.Id == it.ParentId.Value).FirstOrDefault(); + if (parent != null && !parentList.Contains(parent) && !myMenus.Contains(parent))//如果不为空且两个列表里没有 + { + parentList.Add(parent);//添加到父列表 + } + }); + return parentList; + } + + /// + /// 获取我的模块集合 + /// + /// + /// + /// + /// + private List GetMyModules(List allModuleList, List moduleIds, int spaCount) + { + //获取我的模块信息 + var myModules = allModuleList.Where(it => moduleIds.Contains(it.Id)).ToList(); + // 如果一个模块都没拥有 + if (myModules.Count == 0) + { + // 如果系统中无模块(极端情况) + if (allModuleList.Count == 0) + { + if (spaCount == 0)// 如果系统中无单页面,则返回空列表 + { + return new List(); + } + else + { + // 否则构造一个模块,并添加到拥有模块 + var mobileResource = new MobileResource(); + mobileResource.Id = CommonUtils.GetSingleId(); + mobileResource.Path = "/" + RandomHelper.CreateRandomString(10); + mobileResource.Category = CateGoryConst.RESOURCE_MODULE; + allModuleList.Add(mobileResource); + myModules.Add(mobileResource); + } + } + else + { + // 否则将系统中第一个模块作为拥有的模块 + myModules.Add(allModuleList[0]); + } + } + return myModules; + } + + /// + /// 构建Meta + /// + /// 我的菜单集合 + private void ConstructMeta(List myMenus) + { + // 遍历myMenus列表 + myMenus.ForEach(it => + { + // 将模块的父id设置为0,设置随机path + if (it.Category == CateGoryConst.RESOURCE_MODULE) + { + it.ParentId = 0; + it.Path = "/" + RandomHelper.CreateRandomString(10); + } + // 将根菜单的父id设置为模块的id + if (it.Category == CateGoryConst.RESOURCE_MENU) + { + if (it.ParentId == SimpleAdminConst.ZERO) + { + it.ParentId = it.Module; + } + } + //定义meta + var meta = new MobleMeta { Icon = it.Icon, Title = it.Title, Type = it.Category.ToLower() }; + // 如果是菜单,则设置type菜单类型为小写 + if (it.Category == CateGoryConst.RESOURCE_MENU) + { + if (it.MenuType != SysResourceConst.CATALOG)//菜单类型不是目录 + { + meta.Type = it.MenuType.ToLower(); + } + } + it.Meta = meta; + }); + } + + #endregion +} diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SimpleAdmin.Plugin.Mobile.csproj b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SimpleAdmin.Plugin.Mobile.csproj new file mode 100644 index 0000000..fb0a39b --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SimpleAdmin.Plugin.Mobile.csproj @@ -0,0 +1,25 @@ + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + + diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SimpleAdmin.Plugin.Mobile.xml b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SimpleAdmin.Plugin.Mobile.xml new file mode 100644 index 0000000..3403238 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/SimpleAdmin.Plugin.Mobile.xml @@ -0,0 +1,865 @@ + + + + SimpleAdmin.Plugin.Mobile + + + + + 移动端常量 + + + + + 资源表缓存Key + + + + + 用户有哪些移动端资源 + + + + + 角色有哪些移动端资源 + + + + + 移动端权限按钮控制器 + + + + + 按钮分页查询 + + + + + + + 添加按钮 + + + + + + + 修改按钮 + + + + + + + 删除按钮 + + + + + + + 批量新增 + + + + + + + 移动端菜单管理控制器 + + + + + 模块选择 + + + + + + 获取菜单树 + + + + + + 获取角色授权资源树 + + + + + + 获取角色拥有移动端资源 + + + + + + + 获取菜单树选择器 + + + + + + 给角色授权移动端资源 + + + + + + + 添加菜单 + + + + + + + 编辑菜单 + + + + + + + 获取菜单详情 + + + + + + 删除菜单 + + + + + + + 更改模块 + + + + + + + 移动端模块管理 + + + + + 模块分页查询 + + + + + + + 添加模块 + + + + + + + 修改模块 + + + + + + + 获取模块详情 + + + + + + + 删除模块 + + + + + + + 用户个人信息控制器 + + + + + 获取个人菜单 + + + + + + 获取用户信息 + + + + + + 编辑个人信息 + + + + + + + 修改密码 + + + + + + + 获取登录用户的站内信分页 + + + + + + + 读取登录用户站内信详情 + + + + + + + 资源 + + + + + 父id + + + + + 标题 + + + + + 别名 + + + + + 描述 + + + + + 编码 + + + + + 分类 + + + + + 模块 + + + + + 菜单类型 + + + + + 路径 + + + + + 图标 + + + + + 颜色 + + + + + 排序码 + + + + + 颜色 + + + + + 菜单元标签 + + + + + 字节点 + + + + + 代码生成器配置 + + + + + 移动端资源表 + + + + + 关系表种子数据 + + + + + 资源表种子数据 + + + + + 添加按钮参数 + + + + + 父ID + + + + + 标题 + + + + + 编码 + + + + + ID + + + + + 权限按钮服务 + + + + + 添加按钮 + + 添加参数 + + + + + 批量添加 + + + + + + + 删除按钮 + + 删除参数 + + + + + 编辑按钮 + + 编辑参数 + + + + + 按钮分页查询 + + 查询条件 + 按钮分页列表 + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + + + + 添加菜单参数 + + + + + 父ID + + + + + 标题 + + + + + 菜单类型 + + + + + 模块 + + + + + 图标 + + + + + 编辑菜单输入参数 + + + + + ID + + + + + 菜单服务 + + + + + 添加菜单 + + 添加参数 + + + + + 详情 + + id + 详细信息 + + + + 构建菜单树形结构 + + 菜单列表 + 父ID + 菜单形结构 + + + + 获取菜单树 + + 菜单树查询参数 + 菜单树列表 + + + + 编辑菜单 + + 菜单编辑参数 + + + + + 删除菜单 + + 删除菜单参数 + + + + + 改变菜单模块 + + 改变菜单模块参数 + + + + + 角色授权移动端资源 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + + + + 添加模块输入 + + + + + 编辑模块输入 + + + + + ID + + + + + 模块管理服务 + + + + + 添加模块 + + 添加参数 + + + + + 删除模块 + + 删除参数 + + + + + 编辑模块 + + 编辑参数 + + + + + 分页查询 + + 分页参数 + + + + + 详情 + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + + + + 资源服务 + + + + + 获取所有的菜单和模块以及单页面列表,并按分类和排序码排序 + + 所有的菜单和模块以及单页面列表 + + + + 根据资源ID获取所有下级资源 + + 资源ID + 是否包含自己 + 资源列表 + + + + 根据资源ID获取所有下级资源 + + 资源列表 + 资源ID + 是否包含自己 + 资源列表 + + + + 获取ID获取Code列表 + + id列表 + 分类 + Code列表 + + + + 获取资源列表 + + 资源分类列表 + + + + + 根据分类获取资源列表 + + 分类名称 + 资源列表 + + + + 根据菜单ID获取菜单 + + 菜单id列表 + 菜单列表 + + + + 获取权限授权树 + + 路由列表 + + + + + 刷新缓存 + + 分类名称 + + + + + 角色授权资源树 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 获取路由地址名称 + + 控制器地址 + 路由名称 + + + + + 获取资源所有下级 + + 资源列表 + 父ID + + + + + 获取上级 + + + + + + + + 获取授权菜单 + + 模块ID + + + + + 获取授权菜单类菜单名称 + + 菜单列表 + 当前菜单 + + + + + 手机端登录用户信息 + + + + + 移动端按钮码集合 + + + + + 手机端 + + + + + 移动端用户个人信息服务 + + + + + 获取个人移动端菜单 + + + + + + 获取登录用户信息 + + + + + + + + + + + + + + + 获取父菜单集合 + + 所有菜单列表 + 我的菜单列表 + + + + + 获取我的模块集合 + + + + + + + + + 构建Meta + + 我的菜单集合 + + + + AppStartup启动类 + + + + + ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行 + 服务都还没初始化完成,会导致内存中存在多份 IOC 容器!! + 正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了 + + + + + diff --git a/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Startup.cs b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Startup.cs new file mode 100644 index 0000000..7cdc4e7 --- /dev/null +++ b/SimpleAdmin.Plugin/SimpleAdmin.Plugin.Mobile/Startup.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Plugin.Mobile; + +/// +/// AppStartup启动类 +/// +public class Startup : AppStartup +{ + /// + /// ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行 + /// 服务都还没初始化完成,会导致内存中存在多份 IOC 容器!! + /// 正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了 + /// + /// + public void ConfigureServices(IServiceCollection services) + { + //移动端配置转实体 + services.AddConfigurableOptions(); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + var fullName = Assembly.GetExecutingAssembly().FullName;//获取程序集全名 + //通过 App.GetOptions 获取选项 + var settings = App.GetOptions(); + CodeFirstUtils.CodeFirst(settings, fullName);//CodeFirst + } +} diff --git a/SimpleAdmin.SqlSugar/Const/CommonStatusConst.cs b/SimpleAdmin.SqlSugar/Const/CommonStatusConst.cs new file mode 100644 index 0000000..b8aa376 --- /dev/null +++ b/SimpleAdmin.SqlSugar/Const/CommonStatusConst.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// 通用状态常量 +/// +public class CommonStatusConst +{ + /// + /// 启用 + /// + public const string ENABLE = "ENABLE"; + + /// + /// 停用 + /// + public const string DISABLED = "DISABLED"; +} diff --git a/SimpleAdmin.SqlSugar/Const/EffTypeConst.cs b/SimpleAdmin.SqlSugar/Const/EffTypeConst.cs new file mode 100644 index 0000000..a886470 --- /dev/null +++ b/SimpleAdmin.SqlSugar/Const/EffTypeConst.cs @@ -0,0 +1,67 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// 前端控件作用类型常量 +/// +public class EffTypeConst +{ + /// + /// 输入框 + /// + public const string INPUT = "input"; + + /// + /// 文本框 + /// + public const string TEXTAREA = "textarea"; + + /// + /// 下拉框 + /// + public const string SELECT = "select"; + + /// + /// 单选框 + /// + public const string RADIO = "radio"; + + /// + /// 复选框 + /// + public const string CHECKBOX = "checkbox"; + + /// + /// 日期选择器 + /// + public const string DATEPICKER = "datepicker"; + + /// + /// 时间选择器 + /// + public const string TIMEPICKER = "timepicker"; + + /// + /// 数字输入框 + /// + public const string INPUT_NUMBER = "inputNumber"; + + /// + /// 滑动数字条 + /// + public const string SLIDER = "slider"; + + /// + /// 下拉框 + /// + public const string SWITCH = "switch"; +} diff --git a/SimpleAdmin.SqlSugar/Const/SqlsugarConst.cs b/SimpleAdmin.SqlSugar/Const/SqlsugarConst.cs new file mode 100644 index 0000000..373ffc2 --- /dev/null +++ b/SimpleAdmin.SqlSugar/Const/SqlsugarConst.cs @@ -0,0 +1,56 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// SqlSugar系统常量类 +/// +public class SqlSugarConst +{ + /// + /// 默认库ConfigId + /// + public const string DB_DEFAULT = "SimpleAdmin"; + + /// + /// 默认表主键 + /// + public const string DB_PRIMARY_KEY = "Id"; + + #region 数据库字段类型 + + /// + /// varchar(max) + /// + public const string N_VAR_CHAR_MAX = "nvarchar(max)"; + + /// + /// varchar(4000) + /// + public const string N_VAR_CHAR_4000 = "nvarchar(4000)"; + + /// + /// varchar(20) + /// + public const string N_VAR_CHAR_20 = "nvarchar(20)"; + + /// + /// mysql的longtext + /// + public const string LONG_TEXT = "longtext"; + + /// + /// sqlite的text + /// + public const string TEXT = "text"; + + #endregion 数据库字段类型 +} diff --git a/SimpleAdmin.SqlSugar/Db/DbContext.cs b/SimpleAdmin.SqlSugar/Db/DbContext.cs new file mode 100644 index 0000000..2b6f293 --- /dev/null +++ b/SimpleAdmin.SqlSugar/Db/DbContext.cs @@ -0,0 +1,216 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using SimpleAdmin.SqlSugar.Filter; +using DbType = SqlSugar.DbType; + +namespace SimpleAdmin.SqlSugar; + +/// +/// 数据库上下文对象 +/// +public static class DbContext +{ + /// + /// 读取配置文件中的 ConnectionStrings:SqlSugar 配置节点 + /// + public static readonly List DB_CONFIGS = App.GetConfig>("SqlSugarSettings:ConnectionStrings"); + + /// + /// SqlSugar 数据库实例 + /// + public static readonly SqlSugarScope DB = new SqlSugarScope(DB_CONFIGS.Adapt>(), db => + { + //遍历配置的数据库 + DB_CONFIGS.ForEach(it => + { + var sqlSugarScope = db.GetConnectionScope(it.ConfigId);//获取当前库 + MoreSetting(sqlSugarScope, it.DbType);//更多设置 + ExternalServicesSetting(sqlSugarScope, it);//实体拓展配置 + AopSetting(sqlSugarScope);//aop配置 + FilterSetting(sqlSugarScope);//过滤器配置 + }); + }); + + /// + /// 实体拓展配置,自定义类型多库兼容 + /// + /// + /// + private static void ExternalServicesSetting(SqlSugarScopeProvider db, SqlSugarConfig config) + { + db.CurrentConnectionConfig.ConfigureExternalServices = new ConfigureExternalServices + { + // 处理表 + EntityNameService = (type, entity) => + { + if (config.IsUnderLine && !entity.DbTableName.Contains('_')) + entity.DbTableName = UtilMethods.ToUnderLine(entity.DbTableName);// 驼峰转下划线 + }, + //自定义类型多库兼容 + EntityService = (c, p) => + { + //如果是mysql并且是varchar(max) 已弃用 + //if (config.DbType == SqlSugar.DbType.MySql && (p.DataType == SqlSugarConst.NVarCharMax)) + //{ + // p.DataType = SqlSugarConst.LongText;//转成mysql的longtext + //} + //else if (config.DbType == SqlSugar.DbType.Sqlite && (p.DataType == SqlSugarConst.NVarCharMax)) + //{ + // p.DataType = SqlSugarConst.Text;//转成sqlite的text + //} + //默认不写IsNullable为非必填 + //if (new NullabilityInfoContext().Create(c).WriteState is NullabilityState.Nullable) + // p.IsNullable = true; + if (config.IsUnderLine && !p.IsIgnore && !p.DbColumnName.Contains('_') && p.DbColumnName != "ColumnName") + p.DbColumnName = UtilMethods.ToUnderLine(p.DbColumnName);// 驼峰转下划线 + } + }; + } + + /// + /// Aop设置 + /// + /// + public static void AopSetting(SqlSugarScopeProvider db) + { + var config = db.CurrentConnectionConfig; + + // 设置超时时间 + db.Ado.CommandTimeOut = 30; + + // 打印SQL语句 + db.Aop.OnLogExecuting = (sql, pars) => + { + //如果不是开发环境就打印sql + if (App.HostEnvironment.IsDevelopment()) + { + if (sql.StartsWith("SELECT")) + { + Console.ForegroundColor = ConsoleColor.Green; + WriteSqlLog($"查询{config.ConfigId}库操作"); + } + if (sql.StartsWith("UPDATE") || sql.StartsWith("INSERT")) + { + Console.ForegroundColor = ConsoleColor.Blue; + WriteSqlLog($"修改{config.ConfigId}库操作"); + } + if (sql.StartsWith("DELETE")) + { + Console.ForegroundColor = ConsoleColor.Red; + WriteSqlLog($"删除{config.ConfigId}库操作"); + } + Console.WriteLine(UtilMethods.GetSqlString(config.DbType, sql, pars)); + WriteSqlLog($"{config.ConfigId}库操作结束"); + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine(); + } + }; + //异常 + db.Aop.OnError = ex => + { + //如果不是开发环境就打印日志 + if (App.WebHostEnvironment.IsDevelopment()) + { + if (ex.Parametres == null) return; + Console.ForegroundColor = ConsoleColor.Red; + var pars = db.Utilities.SerializeObject(((SugarParameter[])ex.Parametres).ToDictionary(it => it.ParameterName, it => it.Value)); + WriteSqlLog($"{config.ConfigId}库操作异常"); + Console.WriteLine(UtilMethods.GetSqlString(config.DbType, ex.Sql, (SugarParameter[])ex.Parametres) + "\r\n"); + Console.ForegroundColor = ConsoleColor.White; + } + }; + //插入和更新过滤器 + db.Aop.DataExecuting = (oldValue, entityInfo) => + { + // 新增操作 + if (entityInfo.OperationType == DataFilterType.InsertByObject) + { + // 主键(long类型)且没有值的---赋值雪花Id + if (entityInfo.EntityColumnInfo.IsPrimarykey && entityInfo.EntityColumnInfo.PropertyInfo.PropertyType == typeof(long)) + { + var id = entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue); + if (id == null || (long)id == 0) + entityInfo.SetValue(CommonUtils.GetSingleId()); + } + if (entityInfo.PropertyName == nameof(BaseEntity.CreateTime)) + entityInfo.SetValue(DateTime.Now); + + if (App.User != null) + { + //创建人和创建机构ID + if (entityInfo.PropertyName == nameof(BaseEntity.CreateUserId)) + entityInfo.SetValue(App.User.FindFirst(ClaimConst.USER_ID)?.Value); + if (entityInfo.PropertyName == nameof(BaseEntity.CreateUser)) + entityInfo.SetValue(App.User.FindFirst(ClaimConst.ACCOUNT)?.Value); + if (entityInfo.PropertyName == nameof(DataEntityBase.CreateOrgId)) + entityInfo.SetValue(App.User.FindFirst(ClaimConst.ORG_ID)?.Value); + } + } + // 更新操作 + if (entityInfo.OperationType == DataFilterType.UpdateByObject) + { + //更新时间 + if (entityInfo.PropertyName == nameof(BaseEntity.UpdateTime)) + entityInfo.SetValue(DateTime.Now); + //更新人 + if (App.User != null) + { + if (entityInfo.PropertyName == nameof(BaseEntity.UpdateUserId)) + entityInfo.SetValue(App.User?.FindFirst(ClaimConst.USER_ID)?.Value); + if (entityInfo.PropertyName == nameof(BaseEntity.UpdateUser)) + entityInfo.SetValue(App.User?.FindFirst(ClaimConst.ACCOUNT)?.Value); + } + } + }; + //查询数据转换 + db.Aop.DataExecuted = (value, entity) => + { + }; + + } + /// + /// 实体更多配置 + /// + /// db + /// 数据库类型 + private static void MoreSetting(SqlSugarScopeProvider db, DbType dbType) + { + db.CurrentConnectionConfig.MoreSettings = new ConnMoreSettings + { + SqlServerCodeFirstNvarchar = dbType == DbType.SqlServer//设置默认nvarchar + }; + } + + /// + /// 过滤器设置 + /// + /// + public static void FilterSetting(SqlSugarScopeProvider db) + { + // 假删除过滤器 + LogicDeletedEntityFilter(db); + } + + /// + /// 假删除过滤器 + /// + /// + private static void LogicDeletedEntityFilter(SqlSugarScopeProvider db) + { + // 对实现了IDeletedFilter接口的实体添加过滤条件:只查询未删除的数据 + db.QueryFilter.AddTableFilter(u => u.IsDelete == false); + } + + private static void WriteSqlLog(string msg) + { + Console.WriteLine($"=============={msg}=============="); + } +} diff --git a/SimpleAdmin.SqlSugar/Db/DbRepository.cs b/SimpleAdmin.SqlSugar/Db/DbRepository.cs new file mode 100644 index 0000000..6f18a07 --- /dev/null +++ b/SimpleAdmin.SqlSugar/Db/DbRepository.cs @@ -0,0 +1,134 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// 仓储模式对象 +/// +[SuppressSniffer] +public class DbRepository : SimpleClient where T : class, new() +{ + protected ITenant Tenant;//多租户事务、GetConnection、IsAnyConnection等功能 + + public DbRepository(ISqlSugarClient context = null) : base(context)//注意这里要有默认值等于null + { + Context = DbContext.DB.GetConnectionScopeWithAttr();//ioc注入的对象 + Tenant = DbContext.DB; + } + + #region 仓储方法拓展 + + #region 插入 + + /// + /// 批量插入判断走普通导入还是大数据 + /// + /// 数据 + /// 阈值 + /// + public virtual async Task InsertOrBulkCopy(List data, int threshold = 10000) + { + if (data.Count > threshold) + return await Context.Fastest().BulkCopyAsync(data);//大数据导入 + return await Context.Insertable(data).ExecuteCommandAsync();//普通导入 + } + + #endregion 插入 + + #region 列表 + + /// + /// 获取列表指定多个字段 + /// + /// 查询条件 + /// 查询字段 + /// + public virtual Task> GetListAsync(Expression> whereExpression, Expression> selectExpression) + { + return Context.Queryable().Where(whereExpression).Select(selectExpression).ToListAsync(); + } + + /// + /// 获取列表指定单个字段 + /// + /// 查询条件 + /// 查询字段 + /// + public virtual Task> GetListAsync(Expression> whereExpression, Expression> selectExpression) + { + return Context.Queryable().Where(whereExpression).Select(selectExpression).ToListAsync(); + } + + /// + /// 获取列表指定单个字段 + /// + /// 查询条件 + /// 查询字段 + /// + public virtual Task> GetListAsync(Expression> whereExpression, Expression> selectExpression) + { + return Context.Queryable().Where(whereExpression).Select(selectExpression).ToListAsync(); + } + + #endregion 列表 + + #region 单查 + + /// + /// 获取指定表的单个字段 + /// + /// 查询条件 + /// 查询字段 + /// + public virtual Task GetFirstAsync(Expression> whereExpression, Expression> selectExpression) + { + return Context.Queryable().Where(whereExpression).Select(selectExpression).FirstAsync(); + } + + /// + /// 获取指定表的单个字段 + /// + /// 查询条件 + /// 查询字段 + /// + protected virtual Task GetFirstAsync(Expression> whereExpression, Expression> selectExpression) + { + return Context.Queryable().Where(whereExpression).Select(selectExpression).FirstAsync(); + } + + /// + /// 根据条件查询获取自动分表的单个数据 + /// + /// 条件表达式 + /// 开始时间 + /// 结束时间 + /// 实体 + public virtual Task GetFirstSplitTableAsync(Expression> whereExpression, DateTime startTime, DateTime endTime) + { + return Context.Queryable().Where(whereExpression).SplitTable(startTime, endTime).FirstAsync(); + } + + /// + /// 根据条件查询获取自动分表的单个数据 + /// + /// 条件表达式 + /// 分表查询表达式 + /// 实体 + public virtual Task GetFirstSplitTableAsync(Expression> whereExpression, + Func, IEnumerable> getTableNamesFunc) + { + return Context.Queryable().Where(whereExpression).SplitTable(getTableNamesFunc).FirstAsync(); + } + + #endregion 单查 + + #endregion 仓储方法拓展 +} diff --git a/SimpleAdmin.SqlSugar/Db/SqlsugarConfig.cs b/SimpleAdmin.SqlSugar/Db/SqlsugarConfig.cs new file mode 100644 index 0000000..f1cc31c --- /dev/null +++ b/SimpleAdmin.SqlSugar/Db/SqlsugarConfig.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// SqlSugar数据库配置 +/// +public sealed class SqlSugarConfig : ConnectionConfig +{ + /// + /// 是否驼峰转下划线 + /// + public bool IsUnderLine { get; set; } +} diff --git a/SimpleAdmin.SqlSugar/Dto/LinqPagedList.cs b/SimpleAdmin.SqlSugar/Dto/LinqPagedList.cs new file mode 100644 index 0000000..2425b3b --- /dev/null +++ b/SimpleAdmin.SqlSugar/Dto/LinqPagedList.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// Linq分页泛型集合 +/// +/// +public class LinqPagedList : SqlSugarPagedList +{ +} diff --git a/SimpleAdmin.SqlSugar/Entity/BaseEntity.cs b/SimpleAdmin.SqlSugar/Entity/BaseEntity.cs new file mode 100644 index 0000000..d406fcc --- /dev/null +++ b/SimpleAdmin.SqlSugar/Entity/BaseEntity.cs @@ -0,0 +1,95 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using SimpleAdmin.SqlSugar.Filter; + +namespace SimpleAdmin.SqlSugar; + +/// +/// 主键实体基类 +/// +public abstract class PrimaryKeyEntity +{ + /// + /// 主键Id + /// + [SugarColumn(ColumnDescription = "Id", IsPrimaryKey = true)] + public virtual long Id { get; set; } + + /// + /// 拓展信息 + /// + [SugarColumn(ColumnName = "ExtJson", ColumnDescription = "扩展信息", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)] + public virtual string ExtJson { get; set; } +} + +/// +/// 框架实体基类 +/// +public class BaseEntity : PrimaryKeyEntity,IDeletedFilter +{ + [SugarColumn(ColumnName = "Status", ColumnDescription = "状态", Length = 20, DefaultValue = CommonStatusConst.ENABLE, + IsNullable = true)] + public virtual string Status { get; set; } + + /// + /// 创建时间 + /// + [SugarColumn(ColumnDescription = "创建时间", IsOnlyIgnoreUpdate = true, IsNullable = true)] + public virtual DateTime? CreateTime { get; set; } + + /// + /// 更新时间 + /// + [SugarColumn(ColumnDescription = "更新时间", IsOnlyIgnoreInsert = true, IsNullable = true)] + public virtual DateTime? UpdateTime { get; set; } + + /// + /// 创建者Id + /// + [SugarColumn(ColumnDescription = "创建者Id", IsOnlyIgnoreUpdate = true, IsNullable = true)] + public virtual long? CreateUserId { get; set; } + + /// + /// 修改者Id + /// + [SugarColumn(ColumnDescription = "修改者Id", IsOnlyIgnoreInsert = true, IsNullable = true)] + public virtual long? UpdateUserId { get; set; } + + /// + /// 创建人 + /// + [SugarColumn(ColumnDescription = "创建人", IsOnlyIgnoreUpdate = true, IsNullable = true)] + public virtual string CreateUser { get; set; } + + /// + /// 更新人 + /// + [SugarColumn(ColumnDescription = "更新人", IsOnlyIgnoreInsert = true, IsNullable = true)] + public virtual string UpdateUser { get; set; } + + /// + /// 软删除 + /// + [SugarColumn(ColumnDescription = "软删除", IsNullable = true)] + public virtual bool IsDelete { get; set; } +} + +/// +/// 业务数据实体基类(数据权限) +/// +public abstract class DataEntityBase : BaseEntity +{ + /// + /// 创建者部门Id + /// + [SugarColumn(ColumnDescription = "创建者部门Id", IsOnlyIgnoreUpdate = true, IsNullable = true)] + public virtual long CreateOrgId { get; set; } +} diff --git a/SimpleAdmin.SqlSugar/Extension/ISqlSugarEntitySeedData.cs b/SimpleAdmin.SqlSugar/Extension/ISqlSugarEntitySeedData.cs new file mode 100644 index 0000000..12e090b --- /dev/null +++ b/SimpleAdmin.SqlSugar/Extension/ISqlSugarEntitySeedData.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// 实体种子数据接口 +/// +/// +public interface ISqlSugarEntitySeedData where TEntity : class, new() +{ + /// + /// 种子数据 + /// + /// + IEnumerable SeedData(); +} diff --git a/SimpleAdmin.SqlSugar/Extension/SqlSugarPageExtension.cs b/SimpleAdmin.SqlSugar/Extension/SqlSugarPageExtension.cs new file mode 100644 index 0000000..0e00dcc --- /dev/null +++ b/SimpleAdmin.SqlSugar/Extension/SqlSugarPageExtension.cs @@ -0,0 +1,190 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// SqlSugar分页拓展类 +/// +public static class SqlSugarPageExtension +{ + /// + /// SqlSugar分页扩展 + /// + /// + /// + /// + /// + /// + public static SqlSugarPagedList ToPagedList(this ISugarQueryable queryable, int pageNum, int pageSize) + { + var total = 0; + var list = queryable.ToPageList(pageSize, pageNum, ref total); + var pages = (int)Math.Ceiling(total / (double)pageSize); + return new SqlSugarPagedList + { + PageNum = pageSize, + PageSize = pageNum, + List = list, + Total = total, + Pages = pages, + HasNextPages = pageSize < pages, + HasPrevPages = pageSize - 1 > 0 + }; + } + + /// + /// SqlSugar分页扩展 + /// + /// + /// + /// + /// + /// + public static async Task> ToPagedListAsync(this ISugarQueryable queryable, int pageNum, int pageSize) + { + RefAsync totalCount = 0; + var list = await queryable.ToPageListAsync(pageNum, pageSize, totalCount); + var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize); + return new SqlSugarPagedList + { + PageNum = pageNum, + PageSize = pageSize, + List = list, + Total = (int)totalCount, + Pages = totalPages, + HasNextPages = pageNum < totalPages, + HasPrevPages = pageNum - 1 > 0 + }; + } + + /// + /// SqlSugar分页扩展 + /// + /// + /// + /// + /// + /// + /// + /// + public static SqlSugarPagedList ToPagedList(this ISugarQueryable queryable, int pageNum, int pageSize, + Expression> expression) + { + var totalCount = 0; + var items = queryable.ToPageList(pageNum, pageSize, ref totalCount, expression); + var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize); + return new SqlSugarPagedList + { + PageNum = pageNum, + PageSize = pageSize, + List = items, + Total = totalCount, + Pages = totalPages, + HasNextPages = pageNum < totalPages, + HasPrevPages = pageNum - 1 > 0 + }; + } + + /// + /// SqlSugar分页扩展 + /// + /// + /// + /// + /// + /// + /// + /// + public static async Task> ToPagedListAsync(this ISugarQueryable queryable, int pageNum, + int pageSize, + Expression> expression) + { + RefAsync totalCount = 0; + var items = await queryable.ToPageListAsync(pageNum, pageSize, totalCount, expression); + var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize); + return new SqlSugarPagedList + { + PageNum = pageNum, + PageSize = pageSize, + List = items, + Total = (int)totalCount, + Pages = totalPages, + HasNextPages = pageNum < totalPages, + HasPrevPages = pageNum - 1 > 0 + }; + } + + /// + /// 分页查询 + /// + /// + /// 数据列表 + /// 当前页 + /// 每页数量 + /// 分页集合 + public static LinqPagedList LinqPagedList(this List list, int pageNum, int pageSize) + { + var result = list.ToPagedList(pageNum, pageSize);//获取分页 + //格式化 + return new LinqPagedList + { + PageNum = pageNum, + PageSize = result.PageSize, + List = result.Data, + Total = result.TotalCount, + Pages = result.TotalPages, + HasNextPages = result.HasNext, + HasPrevPages = result.HasPrev + }; + } +} + +/// +/// SqlSugar 分页泛型集合 +/// +/// +public class SqlSugarPagedList +{ + /// + /// 页码 + /// + public int PageNum { get; set; } + + /// + /// 数量 + /// + public int PageSize { get; set; } + + /// + /// 总条数 + /// + public int Total { get; set; } + + /// + /// 总页数 + /// + public int Pages { get; set; } + + /// + /// 当前页集合 + /// + public IEnumerable List { get; set; } + + /// + /// 是否有上一页 + /// + public bool HasPrevPages { get; set; } + + /// + /// 是否有下一页 + /// + public bool HasNextPages { get; set; } +} diff --git a/SimpleAdmin.SqlSugar/Extension/SqlSugarUnitOfWork.cs b/SimpleAdmin.SqlSugar/Extension/SqlSugarUnitOfWork.cs new file mode 100644 index 0000000..d085315 --- /dev/null +++ b/SimpleAdmin.SqlSugar/Extension/SqlSugarUnitOfWork.cs @@ -0,0 +1,79 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// SqlSugar 事务和工作单元 +/// +public sealed class SqlSugarUnitOfWork : IUnitOfWork +{ + /// + /// SqlSugar 对象 + /// + private readonly ISqlSugarClient _sqlSugarClient; + + private readonly ILogger _logger; + + /// + /// 构造函数 + /// + /// + /// + public SqlSugarUnitOfWork(ISqlSugarClient sqlSugarClient, ILogger logger) + { + _sqlSugarClient = sqlSugarClient; + _logger = logger; + } + + /// + /// 开启工作单元处理 + /// + /// + /// + /// + public void BeginTransaction(FilterContext context, UnitOfWorkAttribute unitOfWork) + { + _sqlSugarClient.AsTenant().BeginTran(); + } + + /// + /// 提交工作单元处理 + /// + /// + /// + /// + public void CommitTransaction(FilterContext resultContext, UnitOfWorkAttribute unitOfWork) + { + _sqlSugarClient.AsTenant().CommitTran(); + } + + /// + /// 回滚工作单元处理 + /// + /// + /// + /// + public void RollbackTransaction(FilterContext resultContext, UnitOfWorkAttribute unitOfWork) + { + _sqlSugarClient.AsTenant().RollbackTran(); + } + + /// + /// 执行完毕(无论成功失败) + /// + /// + /// + /// + public void OnCompleted(FilterContext context, FilterContext resultContext) + { + _sqlSugarClient.Dispose(); + } +} diff --git a/SimpleAdmin.SqlSugar/Filter/IEntityFilter.cs b/SimpleAdmin.SqlSugar/Filter/IEntityFilter.cs new file mode 100644 index 0000000..f678b98 --- /dev/null +++ b/SimpleAdmin.SqlSugar/Filter/IEntityFilter.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SimpleAdmin.SqlSugar.Filter +{ + /// + /// 假删除接口过滤器 + /// + public interface IDeletedFilter + { + /// + /// 软删除 + /// + bool IsDelete { get; set; } + } +} diff --git a/SimpleAdmin.SqlSugar/GlobalUsing.cs b/SimpleAdmin.SqlSugar/GlobalUsing.cs new file mode 100644 index 0000000..97f859c --- /dev/null +++ b/SimpleAdmin.SqlSugar/GlobalUsing.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +global using MoYu; +global using MoYu.DependencyInjection; +global using MoYu.FriendlyException; +global using Mapster; +global using Masuit.Tools; +global using Microsoft.AspNetCore.Builder; +global using Microsoft.AspNetCore.Hosting; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Hosting; +global using Microsoft.Extensions.Logging; +global using NewLife.Serialization; +global using SimpleAdmin.Core; +global using SimpleAdmin.Core.Utils; +global using SimpleTool; +global using SqlSugar; +global using System.Data; +global using System.Linq.Expressions; +global using System.Reflection; +global using Masuit.Tools.Models; +global using MoYu.DatabaseAccessor; +global using Microsoft.AspNetCore.Mvc.Filters; diff --git a/SimpleAdmin.SqlSugar/SimpleAdmin.SqlSugar.csproj b/SimpleAdmin.SqlSugar/SimpleAdmin.SqlSugar.csproj new file mode 100644 index 0000000..d436469 --- /dev/null +++ b/SimpleAdmin.SqlSugar/SimpleAdmin.SqlSugar.csproj @@ -0,0 +1,25 @@ + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + + + + + + + + diff --git a/SimpleAdmin.SqlSugar/SimpleAdmin.SqlSugar.xml b/SimpleAdmin.SqlSugar/SimpleAdmin.SqlSugar.xml new file mode 100644 index 0000000..0af5291 --- /dev/null +++ b/SimpleAdmin.SqlSugar/SimpleAdmin.SqlSugar.xml @@ -0,0 +1,665 @@ + + + + SimpleAdmin.SqlSugar + + + + + 通用状态常量 + + + + + 启用 + + + + + 停用 + + + + + 前端控件作用类型常量 + + + + + 输入框 + + + + + 文本框 + + + + + 下拉框 + + + + + 单选框 + + + + + 复选框 + + + + + 日期选择器 + + + + + 时间选择器 + + + + + 数字输入框 + + + + + 滑动数字条 + + + + + 下拉框 + + + + + SqlSugar系统常量类 + + + + + 默认库ConfigId + + + + + 默认表主键 + + + + + varchar(max) + + + + + varchar(4000) + + + + + varchar(20) + + + + + mysql的longtext + + + + + sqlite的text + + + + + 数据库上下文对象 + + + + + 读取配置文件中的 ConnectionStrings:SqlSugar 配置节点 + + + + + SqlSugar 数据库实例 + + + + + 实体拓展配置,自定义类型多库兼容 + + + + + + + Aop设置 + + + + + + 实体更多配置 + + db + 数据库类型 + + + + 过滤器设置 + + + + + + 假删除过滤器 + + + + + + 仓储模式对象 + + + + + 批量插入判断走普通导入还是大数据 + + 数据 + 阈值 + + + + + 获取列表指定多个字段 + + 查询条件 + 查询字段 + + + + + 获取列表指定单个字段 + + 查询条件 + 查询字段 + + + + + 获取列表指定单个字段 + + 查询条件 + 查询字段 + + + + + 获取指定表的单个字段 + + 查询条件 + 查询字段 + + + + + 获取指定表的单个字段 + + 查询条件 + 查询字段 + + + + + 根据条件查询获取自动分表的单个数据 + + 条件表达式 + 开始时间 + 结束时间 + 实体 + + + + 根据条件查询获取自动分表的单个数据 + + 条件表达式 + 分表查询表达式 + 实体 + + + + SqlSugar数据库配置 + + + + + 是否驼峰转下划线 + + + + + Linq分页泛型集合 + + + + + + 主键实体基类 + + + + + 主键Id + + + + + 拓展信息 + + + + + 框架实体基类 + + + + + 创建时间 + + + + + 更新时间 + + + + + 创建者Id + + + + + 修改者Id + + + + + 创建人 + + + + + 更新人 + + + + + 软删除 + + + + + 业务数据实体基类(数据权限) + + + + + 创建者部门Id + + + + + 实体种子数据接口 + + + + + + 种子数据 + + + + + + SqlSugar分页拓展类 + + + + + SqlSugar分页扩展 + + + + + + + + + + SqlSugar分页扩展 + + + + + + + + + + SqlSugar分页扩展 + + + + + + + + + + + + SqlSugar分页扩展 + + + + + + + + + + + + 分页查询 + + + 数据列表 + 当前页 + 每页数量 + 分页集合 + + + + SqlSugar 分页泛型集合 + + + + + + 页码 + + + + + 数量 + + + + + 总条数 + + + + + 总页数 + + + + + 当前页集合 + + + + + 是否有上一页 + + + + + 是否有下一页 + + + + + SqlSugar 事务和工作单元 + + + + + SqlSugar 对象 + + + + + 构造函数 + + + + + + + 开启工作单元处理 + + + + + + + + 提交工作单元处理 + + + + + + + + 回滚工作单元处理 + + + + + + + + 执行完毕(无论成功失败) + + + + + + + + 假删除接口过滤器 + + + + + 软删除 + + + + + AppStartup启动类 + + + + + ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行 + 服务都还没初始化完成,会导致内存中存在多份 IOC 容器!! + 正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了 + + + + + + 检查是否有相同的ConfigId + + + + + + CodeFirst功能类 + + + + + CodeFirst生成数据库表结构和种子数据 + + codefirst选项 + 程序集名称 + + + + 初始化数据库表结构 + + 程序集名称 + + + + 初始化种子数据 + + 程序集名称 + + + + 判断类型是否实现某个泛型 + + 类型 + 泛型类型 + bool + + + + List转DataTable + + + + + + + + 排除SqlSugar忽略的列 + + + + + + + SqlSugar字段信息 + + + + + 字段名称 + + + + + 是否主键 + + + + + 字段类型 + + + + + 字段注释 + + + + + SqlSugar表信息 + + + + + 所属库 + + + + + 表名称 + + + + + 实体名 + + + + + 表注释 + + + + + 表字段 + + + + + 种子数据工具类 + + + + + 种子数据格式实体类,遵循Navicat导出json格式 + + + + + + 数据 + + + + + SqlSugar通用功能 + + + + + 根据特性获取所有表信息 + + + + + + + 获取字段信息 + + + + + + + + 数据库字段类型转.NET类型 + + 字段类型 + + + + + 数据类型转显示类型 + + + + + + + 是否通用字段 + + 字段名 + + + + diff --git a/SimpleAdmin.SqlSugar/SqlSugar.Development.json b/SimpleAdmin.SqlSugar/SqlSugar.Development.json new file mode 100644 index 0000000..02f697e --- /dev/null +++ b/SimpleAdmin.SqlSugar/SqlSugar.Development.json @@ -0,0 +1,21 @@ +{ + //sqlSugar设置 + "SqlSugarSettings": { + //SqlSugar连接字符串配置 + "ConnectionStrings": [ + { + "ConfigId": "SimpleAdmin", //租户ID + "ConnectionString": "AllowLoadLocalInfile=true;Server=58.17.132.2;User ID=admin;Password=so^867z$4S;Port=16306;Database=weibingjutest;CharSet=utf8mb4;pooling=true;SslMode=None;min pool size=1;Connection Timeout=30;Pooling=false", //连接字符串 + "DbType": "MySql", //数据库类型 + "IsAutoCloseConnection": true //是否自动释放 + } + // { + // "ConfigId": "SimpleAdmin", //租户ID + // "ConnectionString": "Server=192.168.1.16;Database=SimpleAdmin;User=sa;Password=123456;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=True;", //连接字符串 + // "DbType": "SqlServer", //数据库类型 + // "IsAutoCloseConnection": true, //是否自动释放 + // "IsUnderLine": false //是否驼峰转下划线 + // } + ] + } +} \ No newline at end of file diff --git a/SimpleAdmin.SqlSugar/SqlSugar.Production.json b/SimpleAdmin.SqlSugar/SqlSugar.Production.json new file mode 100644 index 0000000..90b9151 --- /dev/null +++ b/SimpleAdmin.SqlSugar/SqlSugar.Production.json @@ -0,0 +1,20 @@ +{ + //sqlsugar设置 + "SqlSugarSettings": { + //SqlSugar连接字符串配置 + "ConnectionStrings": [ + { + "ConfigId": "SimpleAdmin", //租户ID + "ConnectionString": "AllowLoadLocalInfile=true;Server=58.17.132.2;User ID=admin;Password=so^867z$4S;Port=16306;Database=WeiBingJu;CharSet=utf8mb4;pooling=true;SslMode=None;min pool size=1;Connection Timeout=30;Pooling=false", //连接字符串 + "DbType": "MySql", //数据库类型 + "IsAutoCloseConnection": true //是否自动释放 + } + // { + // "ConfigId": "SimpleAdmin", //租户ID + // "ConnectionString": "Server=192.168.1.16;Database=SimpleAdmin;User=sa;Password=123456;MultipleActiveResultSets=True;", //连接字符串 + // "DbType": "SqlServer", //数据库类型 + // "IsAutoCloseConnection": true, //是否自动释放 + // } + ] + } +} \ No newline at end of file diff --git a/SimpleAdmin.SqlSugar/Startup.cs b/SimpleAdmin.SqlSugar/Startup.cs new file mode 100644 index 0000000..8104cee --- /dev/null +++ b/SimpleAdmin.SqlSugar/Startup.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// AppStartup启动类 +/// +[AppStartup(98)] +public class Startup : AppStartup +{ + /// + /// ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行 + /// 服务都还没初始化完成,会导致内存中存在多份 IOC 容器!! + /// 正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了 + /// + /// + public void ConfigureServices(IServiceCollection services) + { + //检查ConfigId + CheckSameConfigId(); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + //遍历配置 + DbContext.DB_CONFIGS.ForEach(it => + { + var connection = DbContext.DB.GetConnection(it.ConfigId);//获取数据库连接对象 + connection.DbMaintenance.CreateDatabase();//创建数据库,如果存在则不创建 + }); + } + + /// + /// 检查是否有相同的ConfigId + /// + /// + private static void CheckSameConfigId() + { + var configIdGroup = DbContext.DB_CONFIGS.GroupBy(it => it.ConfigId).ToList(); + foreach (var configId in configIdGroup) + { + if (configId.ToList().Count > 1) throw Oops.Oh($"SqlSugar连接配置ConfigId:{configId.Key}重复了"); + } + } +} diff --git a/SimpleAdmin.SqlSugar/Utils/CodeFirstUtils.cs b/SimpleAdmin.SqlSugar/Utils/CodeFirstUtils.cs new file mode 100644 index 0000000..5a58f85 --- /dev/null +++ b/SimpleAdmin.SqlSugar/Utils/CodeFirstUtils.cs @@ -0,0 +1,199 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System.Collections; + +namespace SimpleAdmin.SqlSugar; + +/// +/// CodeFirst功能类 +/// +[SuppressSniffer] +public static class CodeFirstUtils +{ + /// + /// CodeFirst生成数据库表结构和种子数据 + /// + /// codefirst选项 + /// 程序集名称 + public static void CodeFirst(BaseOptions options, string assemblyName) + { + var appName = assemblyName.Split(",")[0]; + if (options.InitTable)//如果需要初始化表结构 + { + Console.WriteLine($"开始初始化{appName}数据库表结构"); + InitTable(assemblyName); + } + if (options.InitSeedData) + { + Console.WriteLine($"开始初始化{appName}数据库种子数据"); + InitSeedData(assemblyName); + } + } + + /// + /// 初始化数据库表结构 + /// + /// 程序集名称 + private static void InitTable(string assemblyName) + { + // 获取所有实体表-初始化表结构 + var entityTypes = App.EffectiveTypes.Where(u => + !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(SugarTable), false) && u.Assembly.FullName == assemblyName); + if (!entityTypes.Any()) return;//没有就退出 + foreach (var entityType in entityTypes) + { + var tenantAtt = entityType.GetCustomAttribute();//获取SqlSugar多租户特性 + var ignoreInit = entityType.GetCustomAttribute();//获取忽略初始化特性 + if (ignoreInit != null) continue;//如果有忽略初始化特性 + if (tenantAtt == null) continue;//如果没有租户特性就下一个 + var db = DbContext.DB.GetConnectionScope(tenantAtt.configId.ToString());//获取数据库对象 + var splitTable = entityType.GetCustomAttribute();//获取自动分表特性 + if (splitTable == null)//如果特性是空 + db.CodeFirst.InitTables(entityType);//普通创建 + else + db.CodeFirst.SplitTables().InitTables(entityType);//自动分表创建 + } + } + + /// + /// 初始化种子数据 + /// + /// 程序集名称 + private static void InitSeedData(string assemblyName) + { + // 获取所有种子配置-初始化数据 + var seedDataTypes = App.EffectiveTypes.Where(u => !u.IsInterface && u is { IsAbstract: false, IsClass: true } + && u.GetInterfaces().Any(i => i.HasImplementedRawGeneric(typeof(ISqlSugarEntitySeedData<>))) && u.Assembly.FullName == assemblyName); + if (!seedDataTypes.Any()) return; + foreach (var seedType in seedDataTypes)//遍历种子类 + { + //使用与指定参数匹配程度最高的构造函数来创建指定类型的实例。 + var instance = Activator.CreateInstance(seedType); + //获取SeedData方法 + var hasDataMethod = seedType.GetMethod("SeedData"); + //判断是否有种子数据 + var seedData = ((IEnumerable)hasDataMethod?.Invoke(instance, null))?.Cast(); + if (seedData == null) continue;//没有种子数据就下一个 + var entityType = seedType.GetInterfaces().First().GetGenericArguments().First();//获取实体类型 + var tenantAtt = entityType.GetCustomAttribute();//获取SqlSugar租户特性 + if (tenantAtt == null) continue;//如果没有租户特性就下一个 + var db = DbContext.DB.GetConnectionScope(tenantAtt.configId.ToString());//获取数据库对象 + var config = DbContext.DB_CONFIGS.FirstOrDefault(u => u.ConfigId == tenantAtt.configId.ToString());//获取数据库配置 + // var seedDataTable = seedData.ToList().ToDataTable();//获取种子数据:已弃用 + var entityInfo = db.EntityMaintenance.GetEntityInfo(entityType); + // seedDataTable.TableName = db.EntityMaintenance.GetEntityInfo(entityType).DbTableName;//获取表名 + var ignoreAdd = hasDataMethod.GetCustomAttribute();//读取忽略插入特性 + var ignoreUpdate = hasDataMethod.GetCustomAttribute();//读取忽略更新特性 + if (entityInfo.Columns.Any(u => u.IsPrimarykey))//判断种子数据是否有主键 + { + // 按主键进行批量增加和更新 + var storage = db.StorageableByObject(seedData.ToList()).ToStorage(); + if (ignoreAdd == null) storage.AsInsertable.ExecuteCommand();//执行插入 + if (ignoreUpdate == null) storage.AsUpdateable.ExecuteCommand();//只有没有忽略更新的特性才执行更新 + } + else// 没有主键或者不是预定义的主键(有重复的可能) + { + //全量插入 + // 无主键则只进行插入 + if (!db.Queryable(entityInfo.DbTableName, entityInfo.DbTableName).Any() && ignoreAdd == null) + db.InsertableByObject(seedData.ToList()).ExecuteCommand(); + } + } + } + + /// + /// 判断类型是否实现某个泛型 + /// + /// 类型 + /// 泛型类型 + /// bool + public static bool HasImplementedRawGeneric(this Type type, Type generic) + { + // 检查接口类型 + var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType); + if (isTheRawGenericType) return true; + + // 检查类型 + while (type != null && type != typeof(object)) + { + isTheRawGenericType = IsTheRawGenericType(type); + if (isTheRawGenericType) return true; + type = type.BaseType ?? default; + } + + return false; + + // 判断逻辑 + bool IsTheRawGenericType(Type type) => generic == (type.IsGenericType ? type.GetGenericTypeDefinition() : type); + } + + /// + /// List转DataTable + /// + /// + /// + /// + public static DataTable ToDataTable(this List list) + { + var result = new DataTable(); + if (list.Count > 0) + { + // result.TableName = list[0].GetType().Name; // 表名赋值 + var propertys = list[0].GetType().GetProperties(); + foreach (var pi in propertys) + { + var colType = pi.PropertyType; + if (colType.IsGenericType && colType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + colType = colType.GetGenericArguments()[0]; + } + if (IsIgnoreColumn(pi)) + continue; + if (IsJsonColumn(pi))//如果是json特性就是sting类型 + colType = typeof(string); + result.Columns.Add(pi.Name, colType); + } + for (var i = 0; i < list.Count; i++) + { + var tempList = new ArrayList(); + foreach (var pi in propertys) + { + if (IsIgnoreColumn(pi)) + continue; + var obj = pi.GetValue(list[i], null); + if (IsJsonColumn(pi))//如果是json特性就是转化为json格式 + obj = obj?.ToJson();//如果json字符串是空就传null + tempList.Add(obj); + } + var array = tempList.ToArray(); + result.LoadDataRow(array, true); + } + } + return result; + } + + /// + /// 排除SqlSugar忽略的列 + /// + /// + /// + private static bool IsIgnoreColumn(PropertyInfo pi) + { + var sc = pi.GetCustomAttributes(false).FirstOrDefault(u => u.IsIgnore); + return sc != null; + } + + private static bool IsJsonColumn(PropertyInfo pi) + { + var sc = pi.GetCustomAttributes(false).FirstOrDefault(u => u.IsJson); + return sc != null; + } +} diff --git a/SimpleAdmin.SqlSugar/Utils/Dto/SqlSugarTableInfo.cs b/SimpleAdmin.SqlSugar/Utils/Dto/SqlSugarTableInfo.cs new file mode 100644 index 0000000..12ec97a --- /dev/null +++ b/SimpleAdmin.SqlSugar/Utils/Dto/SqlSugarTableInfo.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// SqlSugar表信息 +/// +public class SqlSugarTableInfo +{ + /// + /// 所属库 + /// + public virtual string ConfigId { get; set; } + + /// + /// 表名称 + /// + public string TableName { get; set; } + + /// + /// 实体名 + /// + public string EntityName { get; set; } + + /// + /// 表注释 + /// + public string TableDescription { get; set; } + + /// + /// 表字段 + /// + public List Columns { get; set; } +} diff --git a/SimpleAdmin.SqlSugar/Utils/Dto/SqlsugarColumnInfo.cs b/SimpleAdmin.SqlSugar/Utils/Dto/SqlsugarColumnInfo.cs new file mode 100644 index 0000000..ed4ab96 --- /dev/null +++ b/SimpleAdmin.SqlSugar/Utils/Dto/SqlsugarColumnInfo.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// SqlSugar字段信息 +/// +public class SqlSugarColumnInfo +{ + /// + /// 字段名称 + /// + public string ColumnName { get; set; } + + /// + /// 是否主键 + /// + public bool IsPrimaryKey { get; set; } + + /// + /// 字段类型 + /// + public string DataType { get; set; } + + /// + /// 字段注释 + /// + public string ColumnDescription { get; set; } +} diff --git a/SimpleAdmin.SqlSugar/Utils/SeedDataUtil.cs b/SimpleAdmin.SqlSugar/Utils/SeedDataUtil.cs new file mode 100644 index 0000000..7244ed8 --- /dev/null +++ b/SimpleAdmin.SqlSugar/Utils/SeedDataUtil.cs @@ -0,0 +1,154 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System.Text.RegularExpressions; + +namespace SimpleAdmin.SqlSugar; + +/// +/// 种子数据工具类 +/// +public class SeedDataUtil +{ + public static List GetSeedData(string jsonName) + { + var seedData = new List();//种子数据结果 + var basePath = AppContext.BaseDirectory;//获取项目目录 + var json = basePath.CombinePath("SeedData", "Json", jsonName);//获取文件路径 + var dataString = FileHelper.ReadFile(json);//读取文件 + if (!string.IsNullOrEmpty(dataString))//如果有内容 + { + //字段没有数据的替换成null + dataString = dataString.Replace("\"\"", "null"); + + #region 针对导出的json字符串嵌套json字符串如 "DefaultDataScope": "{\"Level\":5,\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[]}" + + //正则匹配"ConfigValue": "[{开头的字符串以]"结尾 + var matcheDefaultDataScope = Regex.Matches(dataString, "\"DefaultDataScope\": \"\\{.*?\\}\""); + foreach (Match match in matcheDefaultDataScope) + { + //获取匹配的值 + var value = match.Value; + //将匹配的值替换成"ConfigValue": "{XXX}" + //字符串是\"的替换成" + var newValue = value.Replace("\\\"", "\""); + //字符串是\{替换成{ + newValue = newValue.Replace("\"{", "{"); + //字符串是}"的替换成} + newValue = newValue.Replace("}\"", "}"); + dataString = dataString.Replace(value, newValue); + } + + #endregion 针对导出的json字符串嵌套json字符串如 "DefaultDataScope": "{\"Level\":5,\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[]}" + + #region Sys_Org + + //如果T是Sys_Org + var nameofT = typeof(T).Name;//获取类型名称 + if (nameofT == "SysOrg") + { + //字段是"[的替换成[ + dataString = dataString.Replace("\"[", "["); + //字段是]"的替换成] + dataString = dataString.Replace("]\"", "]"); + } + + #endregion + + //将json字符串转为实体,这里ExtJson可以正常转换为字符串 + var seedDataRecord1 = dataString.ToJsonEntity>(); + + + //正则匹配"ConfigValue": "[{开头的字符串以]"结尾 + var matches = Regex.Matches(dataString, "\"ConfigValue\": \"\\[\\{.*?\\}\\]\""); + foreach (Match match in matches) + { + //获取匹配的值 + var value = match.Value; + //将匹配的值替换成"ConfigValue": "null" + dataString = dataString.Replace(value, "\"ConfigValue\": \"null\""); + } + + #region 针对导出的json字符串嵌套json字符串如 "DefaultDataScope": "{\"Level\":5,\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[]}" + + //字符串是\"的替换成" + dataString = dataString.Replace("\\\"", "\""); + //字符串是\{替换成{ + dataString = dataString.Replace("\"{", "{"); + //字符串是}"的替换成} + dataString = dataString.Replace("}\"", "}"); + //将json字符串转为实体,这里ExtJson会转为null,替换字符串把ExtJson值变为实体类型而实体类是string类型 + var seedDataRecord2 = dataString.ToJsonEntity>(); + + #endregion 针对导出的json字符串嵌套json字符串如 "DefaultDataScope": "{\"Level\":5,\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[]}" + + + //遍历seedDataRecord2 + for (var i = 0; i < seedDataRecord2.Records.Count; i++) + { + #region 处理ExtJosn + + //获取ExtJson属性 + var propertyExtJson = typeof(T).GetProperty(nameof(PrimaryKeyEntity.ExtJson)); + if (propertyExtJson != null) + { + //获取ExtJson的值 + var extJson = propertyExtJson.GetValue(seedDataRecord2.Records[i])?.ToString(); + // 如果ExtJson不为空并且包含NullableDictionary表示序列化失败了 + if (!string.IsNullOrEmpty(extJson) && extJson.Contains("NullableDictionary")) + { + //设置ExtJson为seedDataRecord1对应的值 + extJson = propertyExtJson.GetValue(seedDataRecord1.Records[i])?.ToString(); + //seedDataRecord2赋值seedDataRecord1的ExtJson + propertyExtJson.SetValue(seedDataRecord2.Records[i], extJson); + } + } + + #endregion 处理ExtJosn + + #region 处理ConfigValue + + //获取ExtJson属性 + var propertyConfigValue = typeof(T).GetProperty("ConfigValue"); + if (propertyConfigValue != null) + { + //获取configValue的值 + var configValue = propertyConfigValue.GetValue(seedDataRecord2.Records[i])?.ToString(); + // 如果configValue不为空并且包含NullableDictionary表示序列化失败了 + if (!string.IsNullOrEmpty(configValue) && (configValue.Contains("NullableDictionary") || configValue == "null")) + { + //设置ExtJson为seedDataRecord1对应的值 + configValue = propertyConfigValue.GetValue(seedDataRecord1.Records[i])?.ToString(); + //seedDataRecord2赋值seedDataRecord1的ExtJson + propertyConfigValue.SetValue(seedDataRecord2.Records[i], configValue); + } + } + + #endregion 处理ConfigValue + } + //种子数据赋值 + seedData = seedDataRecord2.Records; + } + + return seedData; + } +} + +/// +/// 种子数据格式实体类,遵循Navicat导出json格式 +/// +/// +public class SeedDataRecords +{ + /// + /// 数据 + /// + public List Records { get; set; } +} diff --git a/SimpleAdmin.SqlSugar/Utils/SqlSugarUtils.cs b/SimpleAdmin.SqlSugar/Utils/SqlSugarUtils.cs new file mode 100644 index 0000000..f67c691 --- /dev/null +++ b/SimpleAdmin.SqlSugar/Utils/SqlSugarUtils.cs @@ -0,0 +1,206 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.SqlSugar; + +/// +/// SqlSugar通用功能 +/// +public static class SqlSugarUtils +{ + /// + /// 根据特性获取所有表信息 + /// + /// + /// + public static List GetTablesByAttribute() + { + var tables = new List();//结果集 + + // 获取实体表 + var entityTypes = App.EffectiveTypes + .Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(SugarTable), false))//有SugarTable特性 + .Where(u => u.IsDefined(typeof(T), false));//具有指定特性 + + foreach (var entityType in entityTypes) + { + var tenantAttr = entityType.GetCustomAttribute();//获取多租户特性 + var configId = tenantAttr.configId.ToString();//获取租户Id + var connection = DbContext.DB.GetConnection(tenantAttr.configId.ToString());//根据租户ID获取连接信息 + var entityInfo = connection.EntityMaintenance.GetEntityInfo(entityType);//获取实体信息 + if (entityInfo != null) + { + var columns = GetTableColumns(configId, entityInfo.DbTableName);//获取字段信息 + tables.Add(new SqlSugarTableInfo + { + TableName = entityInfo.DbTableName, + EntityName = entityInfo.EntityName, + TableDescription = entityInfo.TableDescription, + ConfigId = configId, + Columns = columns + }); + } + } + return tables; + } + + /// + /// 获取字段信息 + /// + /// + /// + /// + public static List GetTableColumns(string configId, string tableName) + { + var columns = new List();//结果集 + var connection = DbContext.DB.GetConnection(configId); + var dbColumnInfos = connection.DbMaintenance.GetColumnInfosByTableName(tableName);//根据表名获取表信息 + if (dbColumnInfos != null) + { + //遍历字段获取信息 + dbColumnInfos.ForEach(it => + { + if (it.DbColumnName.Contains("_"))//如果有下划线,转换一下 + { + var column = "";//新的字段值 + var columnList = it.DbColumnName.Split('_');//根据下划线分割 + columnList.ForEach(it => + { + column += StringHelper.FirstCharToUpper(it);//首字母大写 + }); + it.DbColumnName = column;//赋值给数据库字段 + } + else + { + it.DbColumnName = StringHelper.FirstCharToUpper(it.DbColumnName);//首字母大写 + } + columns.Add(new SqlSugarColumnInfo + { + ColumnName = it.DbColumnName, + IsPrimaryKey = it.IsPrimarykey, + ColumnDescription = it.ColumnDescription, + DataType = it.DataType + }); + }); + } + return columns; + } + + /// + /// 数据库字段类型转.NET类型 + /// + /// 字段类型 + /// + public static string ConvertDataType(string dataType) + { + switch (dataType) + { + case "text": + case "varchar": + case "char": + case "nvarchar": + case "nchar": + case "blob": + case "longtext": + case "nclob": + return "string"; + + case "int": + case "mediumint": + return "int"; + + case "smallint": + return "Int16"; + + case "tinyint": + return "byte"; + + case "bigint": + case "integer"://sqlite数据库 + return "long"; + + case "bit": + case "boolean": + return "bool"; + + case "money": + case "smallmoney": + case "numeric": + case "decimal": + return "decimal"; + + case "real": + return "Single"; + + case "datetime": + case "smalldatetime": + case "timestamp": + case "date": + case "year": + case "time": + return "DateTime"; + + case "float": + case "double": + return "double"; + + case "image": + case "binary": + case "varbinary": + return "byte[]"; + + case "uniqueidentifier": + return "Guid"; + + default: + return "string"; + } + } + + /// + /// 数据类型转显示类型 + /// + /// + /// + public static string DataTypeToEff(string dataType) + { + return dataType switch + { + "string" => EffTypeConst.INPUT, + "int" => EffTypeConst.INPUT_NUMBER, + "long" => EffTypeConst.INPUT, + "float" => EffTypeConst.INPUT, + "double" => EffTypeConst.INPUT, + "decimal" => EffTypeConst.INPUT, + "bool" => EffTypeConst.SWITCH, + "Guid" => EffTypeConst.INPUT, + "DateTime" => EffTypeConst.DATEPICKER, + _ => EffTypeConst.INPUT + }; + } + + /// + /// 是否通用字段 + /// + /// 字段名 + /// + public static bool IsCommonColumn(string columnName) + { + var columnList = new List + { + nameof(BaseEntity.CreateTime), nameof(BaseEntity.UpdateTime), + nameof(BaseEntity.CreateUserId), nameof(BaseEntity.CreateUser), + nameof(BaseEntity.UpdateUserId), nameof(BaseEntity.UpdateUser), + nameof(BaseEntity.IsDelete), nameof(DataEntityBase.CreateOrgId), + nameof(PrimaryKeyEntity.ExtJson) + }; + return columnList.Contains(columnName); + } +} diff --git a/SimpleAdmin.System/Attributes/AntTableAttribute.cs b/SimpleAdmin.System/Attributes/AntTableAttribute.cs new file mode 100644 index 0000000..4bfc2a8 --- /dev/null +++ b/SimpleAdmin.System/Attributes/AntTableAttribute.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 前端表格特性 +/// +public class AntTableAttribute : Attribute +{ + /// + /// 是否是日期格式 + /// + public bool IsDate { get; set; } + + /// + /// 是否自动省略 + /// + public bool Ellipsis { get; set; } = false; + + /// + /// 宽度 + /// + public int Width { get; set; } = 100; +} diff --git a/SimpleAdmin.System/Attributes/BatchEditAttribute.cs b/SimpleAdmin.System/Attributes/BatchEditAttribute.cs new file mode 100644 index 0000000..be55b15 --- /dev/null +++ b/SimpleAdmin.System/Attributes/BatchEditAttribute.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 批量更新 +/// +public class BatchEditAttribute : Attribute +{ +} diff --git a/SimpleAdmin.System/Attributes/InDictAttribute.cs b/SimpleAdmin.System/Attributes/InDictAttribute.cs new file mode 100644 index 0000000..beb5ae9 --- /dev/null +++ b/SimpleAdmin.System/Attributes/InDictAttribute.cs @@ -0,0 +1,65 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 验证值是否在字典中,大数据慎用 +/// +public class InDictAttribute : ValidationAttribute +{ + public InDictAttribute(string dictValue) + { + DictValue = dictValue; + } + + /// + /// 字典值 + /// + public string DictValue { get; set; } + + /// + /// 获取错误信息 + /// + /// 值 + /// + public string GetErrorMessage(string value) + { + if (string.IsNullOrEmpty(ErrorMessage)) + { + switch (DictValue) + { + case SysDictConst.GENDER: + return "性别只能是男和女"; + + case SysDictConst.NATION: + return "不存在的民族"; + + default: + return $"字典中不存在{value}"; + } + } + return ErrorMessage; + } + + protected override ValidationResult IsValid(object value, ValidationContext validationContext) + { + if (value != null) + { + var dictService = App.GetService(); + var values = dictService.GetValuesByDictValue(DictValue).Result; + if (!values.Contains(value)) + { + return new ValidationResult(GetErrorMessage(value.ToString()), new[] { validationContext.MemberName }); + } + } + return ValidationResult.Success; + } +} diff --git a/SimpleAdmin.System/Const/CateGoryConst.cs b/SimpleAdmin.System/Const/CateGoryConst.cs new file mode 100644 index 0000000..4d24d65 --- /dev/null +++ b/SimpleAdmin.System/Const/CateGoryConst.cs @@ -0,0 +1,266 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 分类常量 +/// +public class CateGoryConst +{ + #region 系统配置 + + /// + /// 系统基础 + /// + public const string CONFIG_SYS_BASE = "SYS_BASE"; + + /// + /// 登录策略 + /// + public const string CONFIG_LOGIN_POLICY = "LOGIN_POLICY"; + + /// + /// 密码策略 + /// + public const string CONFIG_PWD_POLICY = "PWD_POLICY"; + + /// + /// 业务定义 + /// + public const string CONFIG_BIZ_DEFINE = "BIZ_DEFINE"; + + /// + /// 文件-本地 + /// + public const string CONFIG_FILE_LOCAL = "FILE_LOCAL"; + + /// + /// 文件-MINIO + /// + public const string CONFIG_FILE_MINIO = "FILE_MINIO"; + + #endregion 系统配置 + + #region Mqtt配置 + + /// + /// MQTT配置 + /// + public const string CONFIG_MQTT_BASE = "MQTT_BASE"; + + #endregion Mqtt配置 + + #region 关系表 + + /// + /// 用户有哪些角色 + /// + public const string RELATION_SYS_USER_HAS_ROLE = "SYS_USER_HAS_ROLE"; + + /// + /// 角色有哪些资源 + /// + public const string RELATION_SYS_ROLE_HAS_RESOURCE = "SYS_ROLE_HAS_RESOURCE"; + + /// + /// 角色有哪些模块 + /// + public const string RELATION_SYS_ROLE_HAS_MODULE = "SYS_ROLE_HAS_MODULE"; + + /// + /// 用户有哪些模块 + /// + public const string RELATION_SYS_USER_HAS_MODULE = "SYS_USER_HAS_MODULE"; + + /// + ///用户有哪些资源 + /// + public const string RELATION_SYS_USER_HAS_RESOURCE = "SYS_USER_HAS_RESOURCE"; + + /// + /// 角色有哪些权限 + /// + public const string RELATION_SYS_ROLE_HAS_PERMISSION = "SYS_ROLE_HAS_PERMISSION"; + + /// + /// 用户有哪些权限 + /// + public const string RELATION_SYS_USER_HAS_PERMISSION = "SYS_USER_HAS_PERMISSION"; + + /// + /// 用户工作台数据 + /// + public const string RELATION_SYS_USER_WORKBENCH_DATA = "SYS_USER_WORKBENCH_DATA"; + + /// + /// 用户日程数据 + /// + public const string RELATION_SYS_USER_SCHEDULE_DATA = "SYS_USER_SCHEDULE_DATA"; + + /// + /// 站内信与接收用户 + /// + public const string RELATION_MSG_TO_USER = "MSG_TO_USER"; + + #endregion 关系表 + + #region 数据范围 + + /// + /// 本人 + /// + public const string SCOPE_SELF = "SCOPE_SELF"; + + /// + /// 所有 + /// + public const string SCOPE_ALL = "SCOPE_ALL"; + + /// + /// 仅所属组织 + /// + public const string SCOPE_ORG = "SCOPE_ORG"; + + /// + /// 所属组织及以下 + /// + public const string SCOPE_ORG_CHILD = "SCOPE_ORG_CHILD"; + + /// + /// 自定义 + /// + public const string SCOPE_ORG_DEFINE = "SCOPE_ORG_DEFINE"; + + #endregion 数据范围 + + #region 资源表 + + /// + /// 模块 + /// + public const string RESOURCE_MODULE = "MODULE"; + + /// + /// 菜单 + /// + public const string RESOURCE_MENU = "MENU"; + + /// + /// 单页 + /// + public const string RESOURCE_SPA = "SPA"; + + /// + /// 按钮 + /// + public const string RESOURCE_BUTTON = "BUTTON"; + + #endregion 资源表 + + #region 日志表 + + /// + /// 登录 + /// + public const string LOG_LOGIN = "LOGIN"; + + /// + /// 登出 + /// + public const string LOG_LOGOUT = "LOGOUT"; + + /// + /// 操作 + /// + public const string LOG_OPERATE = "OPERATE"; + + /// + /// 异常 + /// + public const string LOG_EXCEPTION = "EXCEPTION"; + + #endregion 日志表 + + #region 字典表 + + /// + /// 框架 + /// + public const string DICT_FRM = "FRM"; + + /// + /// 业务 + /// + public const string DICT_BIZ = "BIZ"; + + #endregion 字典表 + + #region 组织表 + + /// + /// 部门 + /// + public const string ORG_DEPT = "DEPT"; + + /// + /// 公司 + /// + public const string ORG_COMPANY = "COMPANY"; + + #endregion 组织表 + + #region 职位表 + + /// + /// 高层 + /// + public const string POSITION_HIGH = "HIGH"; + + /// + /// 中层 + /// + public const string POSITION_MIDDLE = "MIDDLE"; + + /// + /// 基层 + /// + public const string POSITION_LOW = "LOW"; + + #endregion 职位表 + + #region 角色表 + + /// + /// 全局 + /// + public const string ROLE_GLOBAL = "GLOBAL"; + + /// + /// 机构 + /// + public const string ROLE_ORG = "ORG"; + + #endregion 角色表 + + #region 站内信表 + + /// + /// 通知 + /// + public const string MESSAGE_INFORM = "INFORM"; + + /// + /// 公告 + /// + public const string MESSAGE_NOTICE = "NOTICE"; + + #endregion 站内信表 +} diff --git a/SimpleAdmin.System/Const/GenConst.cs b/SimpleAdmin.System/Const/GenConst.cs new file mode 100644 index 0000000..ff716cc --- /dev/null +++ b/SimpleAdmin.System/Const/GenConst.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +public class GenConst +{ + #region 是否 + + /// + /// 是 + /// + public const string Yes = "Y"; + + /// + /// 否 + /// + public const string No = "N"; + + #endregion 是否 + + /// + /// 压缩包 + /// + public const string Zip = "ZIP"; + + /// + /// 项目中 + /// + public const string Pro = "PRO"; + + /// + /// 全部 + /// + public const string ExecAll = "ALL"; + + /// + /// 前端 + /// + public const string ExecFrontend = "FRONTEND"; + + /// + /// 后端 + /// + public const string ExecBackend = "BACKEND"; +} diff --git a/SimpleAdmin.System/Const/SysConfigConst.cs b/SimpleAdmin.System/Const/SysConfigConst.cs new file mode 100644 index 0000000..d364b82 --- /dev/null +++ b/SimpleAdmin.System/Const/SysConfigConst.cs @@ -0,0 +1,200 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 系统配置常量 +/// +public class SysConfigConst +{ + #region MyRegion + + /// + /// 系统名称 + /// + public const string SYS_NAME = "SYS_NAME"; + + + /// + /// ico图标 + /// + public const string SYS_ICO = "SYS_ICO"; + + /// + /// 网站开启访问 + /// + public const string SYS_WEB_STATUS = "SYS_WEB_STATUS"; + + + /// + /// 网站关闭提示 + /// + public const string SYS_WEB_CLOSE_PROMPT = "SYS_WEB_CLOSE_PROMPT"; + + /// + /// 系统logo + /// + public const string SYS_LOGO = "SYS_LOGO"; + + /// + /// 系统版本 + /// + public const string SYS_VERSION = "SYS_VERSION"; + + /// + /// 多租户开关 + /// + public const string SYS_TENANT_OPTIONS = "SYS_TENANT_OPTIONS"; + + + /// + /// 系统默认工作台 + /// + public const string SYS_DEFAULT_WORKBENCH_DATA = "SYS_DEFAULT_WORKBENCH_DATA"; + + #endregion + + #region 登录策略 + + /// + /// 登录验证码开关 + /// + public const string LOGIN_CAPTCHA_OPEN = "LOGIN_CAPTCHA_OPEN"; + + /// + /// 登录验证码开关 + /// + public const string LOGIN_CAPTCHA_TYPE = "LOGIN_CAPTCHA_TYPE"; + + /// + /// 单用户登录开关 + /// + public const string LOGIN_SINGLE_OPEN = "LOGIN_SINGLE_OPEN"; + + /// + /// 登录错误锁定时长 + /// + public const string LOGIN_ERROR_LOCK = "LOGIN_ERROR_LOCK"; + + /// + /// 登录错误锁定时长 + /// + public const string LOGIN_ERROR_RESET_TIME = "LOGIN_ERROR_RESET_TIME"; + + /// + /// 登录错误次数 + /// + public const string LOGIN_ERROR_COUNT = "LOGIN_ERROR_COUNT"; + + #endregion 登录策略 + + #region 密码策略 + + /// + /// 默认用户密码 + /// + public const string PWD_DEFAULT_PASSWORD = "PWD_DEFAULT_PASSWORD"; + + /// + /// 密码定期提醒更新 + /// + public const string PWD_REMIND = "PWD_REMIND"; + + /// + /// 密码定期提醒更新时间 + /// + public const string PWD_REMIND_DAY = "PWD_REMIND_DAY"; + + /// + /// 修改初始密码提醒 + /// + public const string PWD_UPDATE_DEFAULT = "PWD_UPDATE_DEFAULT"; + + /// + /// 密码最小长度 + /// + public const string PWD_MIN_LENGTH = "PWD_MIN_LENGTH"; + + /// + /// 包含数字 + /// + public const string PWD_CONTAIN_NUM = "PWD_CONTAIN_NUM"; + + /// + /// 包含小写字母 + /// + public const string PWD_CONTAIN_LOWER = "PWD_CONTAIN_LOWER"; + + /// + /// 包含大写字母 + /// + public const string PWD_CONTAIN_UPPER = "PWD_CONTAIN_UPPER"; + + /// + /// 包含特殊字符 + /// + public const string PWD_CONTAIN_CHARACTER = "PWD_CONTAIN_UPPER"; + + #endregion 密码策略 + + #region 存储引擎 + + /// + /// windows系统本地目录 + /// + public const string FILE_LOCAL_FOLDER_FOR_WINDOWS = "FILE_LOCAL_FOLDER_FOR_WINDOWS"; + + /// + /// Unix系统本地目录 + /// + public const string FILE_LOCAL_FOLDER_FOR_UNIX = "FILE_LOCAL_FOLDER_FOR_UNIX"; + + /// + /// MINIO文件AccessKey + /// + public const string FILE_MINIO_ACCESS_KEY = "FILE_MINIO_ACCESS_KEY"; + + /// + /// MINIO文件SecretKey + /// + public const string FILE_MINIO_SECRET_KEY = "FILE_MINIO_SECRET_KEY"; + + /// + /// MINIO文件EndPoint + /// + public const string FILE_MINIO_END_POINT = "FILE_MINIO_END_POINT"; + + /// + /// MINIO文件默认存储桶 + /// + public const string FILE_MINIO_DEFAULT_BUCKET_NAME = "FILE_MINIO_DEFAULT_BUCKET_NAME"; + + #endregion 存储引擎 + + #region MQTT + + /// + /// mqtt连接地址 + /// + public const string MQTT_PARAM_URL = "MQTT_PARAM_URL"; + + /// + /// mqtt连接用户名 + /// + public const string MQTT_PARAM_USERNAME = "MQTT_PARAM_USERNAME"; + + /// + /// mqtt连接密码 + /// + public const string MQTT_PARAM_PASSWORD = "MQTT_PARAM_PASSWORD"; + + #endregion +} diff --git a/SimpleAdmin.System/Const/SysDictConst.cs b/SimpleAdmin.System/Const/SysDictConst.cs new file mode 100644 index 0000000..bc789cb --- /dev/null +++ b/SimpleAdmin.System/Const/SysDictConst.cs @@ -0,0 +1,166 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 字典常量 +/// +public class SysDictConst +{ + #region 系统字典 + + /// + /// 性别 + /// + public const string GENDER = "GENDER"; + + /// + /// 名族 + /// + public const string NATION = "NATION"; + + /// + /// 用户证件类型 + /// + public const string ID_CARD_TYPE = "ID_CARD_TYPE"; + + /// + /// 通用文化程度 + /// + public const string CULTURE_LEVEL = "CULTURE_LEVEL"; + + /// + /// 系统职位分类 + /// + public const string POSITION_CATEGORY = "POSITION_CATEGORY"; + + #region 在线用户状态 + + /// + /// 在线 + /// + public const string ONLINE_STATUS_ONLINE = "ONLINE"; + + /// + /// 离线 + /// + public const string ONLINE_STATUS_OFFLINE = "OFFLINE"; + + #endregion 在线用户状态 + + #region 上传文件引擎 + + /// + /// 本地 + /// + public const string FILE_ENGINE_LOCAL = "LOCAL"; + + /// + /// MINIO + /// + public const string FILE_ENGINE_MINIO = "MINIO"; + + #endregion 上传文件引擎 + + #region 系统字典分类 + + /// + /// 系统 + /// + public const string DICT_CATEGORY_FRM = "FRM"; + + /// + /// 业务 + /// + public const string DICT_CATEGORY_BIZ = "BIZ"; + + #endregion 系统字典分类 + + #region 多租户选项 + + /// + /// 关闭 + /// + public const string TENANT_OPTIONS_CLOSE = "CLOSE"; + + /// + /// 手动选择 + /// + public const string TENANT_OPTIONS_CHOSE = "CHOSE"; + + /// + /// 根据域名 + /// + public const string TENANT_OPTIONS_DOMAIN = "DOMAIN"; + + #endregion + + #region 站内信 + + /// + /// 消息分类 + /// + public const string MESSAGE_CATEGORY = "MESSAGE_CATEGORY"; + + /// + /// 接受者类型 + /// + public const string RECEIVER_TYPE = "RECEIVER_TYPE"; + + /// + /// 发送方式 + /// + public const string MESSAGE_WAY = "MESSAGE_WAY"; + + /// + /// 立即发送 + /// + public const string SEND_WAY_NOW = "NOW"; + + /// + /// 延迟发送 + /// + public const string SEND_WAY_DELAY = "DELAY"; + + /// + /// 指定时间 + /// + public const string SEND_WAY_SCHEDULE = "SCHEDULE"; + + /// + /// 待发送 + /// + public const string MESSAGE_STATUS_READY = "READY"; + + /// + /// 已发送 + /// + public const string MESSAGE_STATUS_ALREADY = "ALREADY"; + + /// + /// 所有 + /// + public const string RECEIVER_TYPE_ALL = "ALL"; + + /// + /// 角色 + /// + public const string RECEIVER_TYPE_ROLE = "ROLE"; + + /// + /// 指定 + /// + public const string RECEIVER_TYPE_APPOINT = "APPOINT"; + + #endregion + + #endregion 系统字典 +} diff --git a/SimpleAdmin.System/Const/SysLogConst.cs b/SimpleAdmin.System/Const/SysLogConst.cs new file mode 100644 index 0000000..093cd9b --- /dev/null +++ b/SimpleAdmin.System/Const/SysLogConst.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 日志常量 +/// +public class SysLogConst +{ + /// + /// 成功 + /// + public const string SUCCESS = "SUCCESS"; + + /// + /// 成功 + /// + public const string FAIL = "FAIL"; +} diff --git a/SimpleAdmin.System/Const/SysResourceConst.cs b/SimpleAdmin.System/Const/SysResourceConst.cs new file mode 100644 index 0000000..ed032df --- /dev/null +++ b/SimpleAdmin.System/Const/SysResourceConst.cs @@ -0,0 +1,52 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 资源表常量 +/// +public class SysResourceConst +{ + /// + /// 目录 + /// + public const string CATALOG = "CATALOG"; + + /// + /// 菜单 + /// + public const string MENU = "MENU"; + + /// + /// 内链 + /// + public const string IFRAME = "IFRAME"; + + /// + /// 子页 + /// + public const string SUBSET = "SUBSET"; + + /// + /// 外链 + /// + public const string LINK = "LINK"; + + /// + /// 单页 + /// + public const string SPA = "SPA"; + + /// + /// 系统内置单页面编码 + /// + public const string SYSTEM = "system"; +} diff --git a/SimpleAdmin.System/Const/SysRoleConst.cs b/SimpleAdmin.System/Const/SysRoleConst.cs new file mode 100644 index 0000000..d03ad5a --- /dev/null +++ b/SimpleAdmin.System/Const/SysRoleConst.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 角色常量 +/// +public class SysRoleConst +{ + /// + /// 超级管理员 + /// + public const string SUPER_ADMIN = "superAdmin"; + + /// + /// 业务管理员 + /// + public const string BIZ_ADMIN = "bizAdmin"; +} diff --git a/SimpleAdmin.System/Const/SystemConst.cs b/SimpleAdmin.System/Const/SystemConst.cs new file mode 100644 index 0000000..e3595dc --- /dev/null +++ b/SimpleAdmin.System/Const/SystemConst.cs @@ -0,0 +1,145 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 系统层常量 +/// +public class SystemConst +{ + /// + /// 系统配置表缓存Key + /// + public const string CACHE_DEV_CONFIG = CacheConst.CACHE_PREFIX_WEB + "SysConfig:"; + + /// + /// 登录验证码缓存Key + /// + public const string CACHE_CAPTCHA = CacheConst.CACHE_PREFIX_WEB + "Captcha:"; + + /// + /// 用户表缓存Key + /// + public const string CACHE_SYS_USER = CacheConst.CACHE_PREFIX_WEB + "SysUser"; + + /// + /// 用户头像缓存关系Key + /// + public const string CACHE_SYS_USER_AVATAR = CacheConst.CACHE_PREFIX_WEB + "SysUserAvatar"; + + /// + /// 用户手机号关系缓存Key + /// + public const string CACHE_SYS_USER_PHONE = CacheConst.CACHE_PREFIX_WEB + "SysUserPhone"; + + /// + /// 用户手机号关系缓存Key + /// + public const string CACHE_SYS_USER_ACCOUNT = CacheConst.CACHE_PREFIX_WEB + "SysUserAccount"; + + /// + /// 资源表缓存Key + /// + public const string CACHE_SYS_RESOURCE = CacheConst.CACHE_PREFIX_WEB + "SysResource:"; + + /// + /// 字典表缓存Key + /// + public const string CACHE_DEV_DICT = CacheConst.CACHE_PREFIX_WEB + "SysDict"; + + /// + /// 关系表缓存Key + /// + public const string CACHE_SYS_RELATION = CacheConst.CACHE_PREFIX_WEB + "SysRelation:"; + + /// + /// 机构表缓存Key + /// + public const string CACHE_SYS_ORG = CacheConst.CACHE_PREFIX_WEB + "SysOrg"; + + /// + /// 机构对应租户关系缓存Key + /// + public const string CACHE_SYS_ORG_TENANT = CacheConst.CACHE_PREFIX_WEB + "SysOrgTenant"; + + /// + /// 租户列表缓存 + /// + public const string CACHE_SYS_TENANT = CacheConst.CACHE_PREFIX_WEB + "Tenant"; + + /// + /// 角色表缓存Key + /// + public const string CACHE_SYS_ROLE = CacheConst.CACHE_PREFIX_WEB + "SysRole"; + + /// + /// 职位表缓存Key + /// + public const string CACHE_SYS_POSITION = CacheConst.CACHE_PREFIX_WEB + "SysPosition"; + + #region 登录错误次数 + + /// + /// 登录错误次数缓存Key + /// + public const string CACHE_LOGIN_ERROR_COUNT = CacheConst.CACHE_PREFIX_WEB + "LoginErrorCount:"; + + #endregion 登录错误次数 + + #region 操作 + + /// + /// 添加操作 + /// + public const string ADD = "添加"; + + /// + /// 编辑操作 + /// + public const string EDIT = "编辑"; + + /// + /// 启用操作 + /// + public const string ENABLE = "启用"; + + /// + /// 禁用操作 + /// + public const string DISABLE = "禁用"; + + /// + /// 重置密码操作 + /// + public const string RESET_PWD = "重置密码"; + + /// + /// 用户授权操作 + /// + public const string GRANT_ROLE = "授权"; + + #endregion 操作 + + #region 别称 + + /// + /// 组织 + /// + public const string SYS_ORG = "组织"; + + + /// + /// 职位 + /// + public const string SYS_POS = "职位"; + + #endregion 别称 +} diff --git a/SimpleAdmin.System/Entity/BatchEdit.cs b/SimpleAdmin.System/Entity/BatchEdit.cs new file mode 100644 index 0000000..0648d67 --- /dev/null +++ b/SimpleAdmin.System/Entity/BatchEdit.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 批量修改 +/// +[SugarTable("batch_edit", TableDescription = "批量修改")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +[CodeGen] +public class BatchEdit : PrimaryKeyEntity +{ + /// + /// 唯一编码 + /// + [SugarColumn(ColumnName = "Code", ColumnDescription = "唯一编码", Length = 100, IsNullable = false)] + public string Code { get; set; } + + /// + /// 所属库 + /// + [SugarColumn(ColumnName = "ConfigId", ColumnDescription = "所属库", Length = 100, IsNullable = false)] + public string ConfigId { get; set; } + + /// + /// 实体名 + /// + [SugarColumn(ColumnName = "EntityName", ColumnDescription = "实体名", Length = 100, IsNullable = false)] + public string EntityName { get; set; } + + /// + /// 表名 + /// + [SugarColumn(ColumnName = "TableName", ColumnDescription = "表名", Length = 100, IsNullable = false)] + public string TableName { get; set; } + + /// + /// 表描述 + /// + [SugarColumn(ColumnName = "TableDescription", ColumnDescription = "表描述", Length = 100, IsNullable = false)] + public string TableDescription { get; set; } +} diff --git a/SimpleAdmin.System/Entity/BatchEditConfig.cs b/SimpleAdmin.System/Entity/BatchEditConfig.cs new file mode 100644 index 0000000..cb7ec2e --- /dev/null +++ b/SimpleAdmin.System/Entity/BatchEditConfig.cs @@ -0,0 +1,85 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 批量修改配置表 +/// +[SugarTable("batch_edit_config", TableDescription = "批量修改配置表")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class BatchEditConfig : PrimaryKeyEntity +{ + /// + /// 批量配置Id + /// + [SugarColumn(ColumnName = "UId", ColumnDescription = "批量配置Id", IsNullable = false)] + public long UId { get; set; } + + /// + /// 字段名 + /// + [SugarColumn(ColumnName = "ColumnName", ColumnDescription = "字段名", Length = 100, IsNullable = false)] + public string ColumnName { get; set; } + + /// + /// 字段描述 + /// + [SugarColumn(ColumnName = "ColumnComment", ColumnDescription = "字段描述", Length = 100, IsNullable = false)] + public string ColumnComment { get; set; } + + /// + /// 作用类型 + /// + [SugarColumn(ColumnName = "DataType", ColumnDescription = "作用类型", Length = 100, IsNullable = false)] + public string DataType { get; set; } + + /// + /// 字典值 + /// + [SugarColumn(ColumnName = "DictTypeCode", ColumnDescription = "字典值", Length = 100, IsNullable = true)] + public string DictTypeCode { get; set; } + + /// + /// 数据库类型 + /// + [SugarColumn(ColumnName = "NetType", ColumnDescription = "数据库类型", Length = 100, IsNullable = true)] + public string NetType { get; set; } + + /// + /// 接口名称 + /// + [SugarColumn(ColumnName = "RequestUrl", ColumnDescription = "接口名称", Length = 100, IsNullable = true)] + public string RequestUrl { get; set; } + + /// + /// 接口类型 + /// + [SugarColumn(ColumnName = "RequestType", ColumnDescription = "接口类型", Length = 100, IsNullable = true)] + public string RequestType { get; set; } + + /// + /// 接口结果标签 + /// + [SugarColumn(ColumnName = "RequestLabel", ColumnDescription = "接口结果标签", Length = 100, IsNullable = true)] + public string RequestLabel { get; set; } + + /// + /// 接口结果值 + /// + [SugarColumn(ColumnName = "RequestValue", ColumnDescription = "接口结果值", Length = 100, IsNullable = true)] + public string RequestValue { get; set; } + + /// + /// 启用状态 + /// + [SugarColumn(ColumnName = "Status", ColumnDescription = "状态", Length = 100, IsNullable = false)] + public string Status { get; set; } +} diff --git a/SimpleAdmin.System/Entity/ClientRelation.cs b/SimpleAdmin.System/Entity/ClientRelation.cs new file mode 100644 index 0000000..b0c4921 --- /dev/null +++ b/SimpleAdmin.System/Entity/ClientRelation.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Core.Entity.System; + +/// +/// C端用户关系 +/// +[SugarTable("client_relation", TableDescription = "关系")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class ClientRelation : PrimaryKeyEntity +{ + /// + /// 对象ID + /// + [SugarColumn(ColumnName = "ObjectId", ColumnDescription = "对象ID", IsNullable = false)] + public long ObjectId { get; set; } + + /// + /// 目标ID + /// + [SugarColumn(ColumnName = "TargetId", ColumnDescription = "目标ID", IsNullable = true)] + public string TargetId { get; set; } + + /// + /// 分类 + /// + [SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200, IsNullable = true)] + public string Category { get; set; } +} diff --git a/SimpleAdmin.System/Entity/ClientUser.cs b/SimpleAdmin.System/Entity/ClientUser.cs new file mode 100644 index 0000000..eaf348f --- /dev/null +++ b/SimpleAdmin.System/Entity/ClientUser.cs @@ -0,0 +1,289 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// C端用户 +/// +[SugarTable("client_user", TableDescription = "C端用户")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class ClientUser : DataEntityBase +{ + /// + /// 头像 + /// + [SugarColumn(ColumnName = "Avatar", ColumnDescription = "头像", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)] + public string Avatar { get; set; } + + /// + /// 签名 + /// + [SugarColumn(ColumnName = "Signature", ColumnDescription = "签名", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)] + public string Signature { get; set; } + + /// + /// 账号 + /// + [SugarColumn(ColumnName = "Account", ColumnDescription = "账号", Length = 200, IsNullable = false)] + public string Account { get; set; } + + /// + /// 密码 + /// + [SugarColumn(ColumnName = "Password", ColumnDescription = "密码", Length = 200, IsNullable = false)] + public string Password { get; set; } + + /// + /// 姓名 + /// + [SugarColumn(ColumnName = "Name", ColumnDescription = "姓名", Length = 200, IsNullable = true)] + public string Name { get; set; } + + /// + /// 昵称 + /// + [SugarColumn(ColumnName = "Nickname", ColumnDescription = "昵称", Length = 200, IsNullable = true)] + public string Nickname { get; set; } + + /// + /// 性别 + /// + [SugarColumn(ColumnName = "Gender", ColumnDescription = "性别", Length = 200, IsNullable = true)] + public string Gender { get; set; } + + /// + /// 年龄 + /// + [SugarColumn(ColumnName = "Age", ColumnDescription = "年龄", Length = 200, IsNullable = true)] + public string Age { get; set; } + + /// + /// 出生日期 + /// + [SugarColumn(ColumnName = "Birthday", ColumnDescription = "出生日期", Length = 200, IsNullable = true)] + public string Birthday { get; set; } + + /// + /// 民族 + /// + [SugarColumn(ColumnName = "Nation", ColumnDescription = "民族", Length = 200, IsNullable = true)] + public string Nation { get; set; } + + /// + /// 籍贯 + /// + [SugarColumn(ColumnName = "NativePlace", ColumnDescription = "籍贯", Length = 200, IsNullable = true)] + public string NativePlace { get; set; } + + /// + /// 家庭住址 + /// + [SugarColumn(ColumnName = "HomeAddress", ColumnDescription = "家庭住址", IsNullable = true)] + public string HomeAddress { get; set; } + + /// + /// 通信地址 + /// + [SugarColumn(ColumnName = "MailingAddress", ColumnDescription = "通信地址", IsNullable = true)] + public string MailingAddress { get; set; } + + /// + /// 证件类型 + /// + [SugarColumn(ColumnName = "IdCardType", ColumnDescription = "证件类型", Length = 200, IsNullable = true)] + public string IdCardType { get; set; } + + /// + /// 证件号码 + /// + [SugarColumn(ColumnName = "IdCardNumber", ColumnDescription = "证件号码", Length = 200, IsNullable = true)] + public string IdCardNumber { get; set; } + + /// + /// 文化程度 + /// + [SugarColumn(ColumnName = "CultureLevel", ColumnDescription = "文化程度", Length = 200, IsNullable = true)] + public string CultureLevel { get; set; } + + /// + /// 政治面貌 + /// + [SugarColumn(ColumnName = "PoliticalOutlook", ColumnDescription = "政治面貌", Length = 200, IsNullable = true)] + public string PoliticalOutlook { get; set; } + + /// + /// 毕业院校 + /// + [SugarColumn(ColumnName = "College", ColumnDescription = "毕业院校", Length = 200, IsNullable = true)] + public string College { get; set; } + + /// + /// 学历 + /// + [SugarColumn(ColumnName = "Education", ColumnDescription = "学历", Length = 200, IsNullable = true)] + public string Education { get; set; } + + /// + /// 学制 + /// + [SugarColumn(ColumnName = "EduLength", ColumnDescription = "学制", Length = 200, IsNullable = true)] + public string EduLength { get; set; } + + /// + /// 学位 + /// + [SugarColumn(ColumnName = "Degree", ColumnDescription = "学位", Length = 200, IsNullable = true)] + public string Degree { get; set; } + + /// + /// 手机 + /// + [SugarColumn(ColumnName = "Phone", ColumnDescription = "手机", Length = 200, IsNullable = true)] + public string Phone { get; set; } + + /// + /// 邮箱 + /// + [SugarColumn(ColumnName = "Email", ColumnDescription = "邮箱", Length = 200, IsNullable = true)] + public string Email { get; set; } + + /// + /// 家庭电话 + /// + [SugarColumn(ColumnName = "HomeTel", ColumnDescription = "家庭电话", Length = 200, IsNullable = true)] + public string HomeTel { get; set; } + + /// + /// 办公电话 + /// + [SugarColumn(ColumnName = "OfficeTel", ColumnDescription = "办公电话", Length = 200, IsNullable = true)] + public string OfficeTel { get; set; } + + /// + /// 紧急联系人 + /// + [SugarColumn(ColumnName = "EmergencyContact", ColumnDescription = "紧急联系人", Length = 200, IsNullable = true)] + public string EmergencyContact { get; set; } + + /// + /// 紧急联系人电话 + /// + [SugarColumn(ColumnName = "EmergencyPhone", ColumnDescription = "紧急联系人电话", Length = 200, IsNullable = true)] + public string EmergencyPhone { get; set; } + + /// + /// 紧急联系人地址 + /// + [SugarColumn(ColumnName = "EmergencyAddress", ColumnDescription = "紧急联系人地址", IsNullable = true)] + public string EmergencyAddress { get; set; } + + /// + /// 员工编号 + /// + [SugarColumn(ColumnName = "EmpNo", ColumnDescription = "员工编号", Length = 200, IsNullable = true)] + public string EmpNo { get; set; } + + /// + /// 入职日期 + /// + [SugarColumn(ColumnName = "EntryDate", ColumnDescription = "入职日期", Length = 200, IsNullable = true)] + public string EntryDate { get; set; } + + /// + /// 机构id + /// + [SugarColumn(ColumnName = "OrgId", ColumnDescription = "机构id")] + public long OrgId { get; set; } + + /// + /// 职位id + /// + [SugarColumn(ColumnName = "PositionId", ColumnDescription = "职位id")] + public long PositionId { get; set; } + + /// + /// 职级 + /// + [SugarColumn(ColumnName = "PositionLevel", ColumnDescription = "职级", Length = 200, IsNullable = true)] + public string PositionLevel { get; set; } + + /// + /// 主管id + /// + [SugarColumn(ColumnName = "DirectorId", ColumnDescription = "主管id", IsNullable = true)] + public long DirectorId { get; set; } + + /// + /// 兼任信息 + /// + [SugarColumn(ColumnName = "PositionJson", ColumnDescription = "兼任信息", Length = 100, IsNullable = true)] + public string PositionJson { get; set; } + + /// + /// 上次登录ip + /// + [SugarColumn(ColumnName = "LastLoginIp", ColumnDescription = "上次登录ip", Length = 200, IsNullable = true)] + public string LastLoginIp { get; set; } + + /// + /// 上次登录地点 + /// + [SugarColumn(ColumnName = "LastLoginAddress", ColumnDescription = "上次登录地点", Length = 200, IsNullable = true)] + public string LastLoginAddress { get; set; } + + /// + /// 上次登录时间 + /// + [SugarColumn(ColumnName = "LastLoginTime", ColumnDescription = "上次登录时间", IsNullable = true)] + public DateTime? LastLoginTime { get; set; } + + /// + /// 上次登录设备 + /// + [SugarColumn(ColumnName = "LastLoginDevice", ColumnDescription = "上次登录设备", IsNullable = true)] + public string LastLoginDevice { get; set; } + + /// + /// 最新登录ip + /// + [SugarColumn(ColumnName = "LatestLoginIp", ColumnDescription = "最新登录ip", Length = 200, IsNullable = true)] + public string LatestLoginIp { get; set; } + + /// + /// 最新登录地点 + /// + [SugarColumn(ColumnName = "LatestLoginAddress", ColumnDescription = "最新登录地点", Length = 200, IsNullable = true)] + public string LatestLoginAddress { get; set; } + + /// + /// 最新登录时间 + /// + [SugarColumn(ColumnName = "LatestLoginTime", ColumnDescription = "最新登录时间", IsNullable = true)] + public DateTime? LatestLoginTime { get; set; } + + /// + /// 最新登录设备 + /// + [SugarColumn(ColumnName = "LatestLoginDevice", ColumnDescription = "最新登录设备", IsNullable = true)] + public string LatestLoginDevice { get; set; } + + /// + /// 用户状态 + /// + [SugarColumn(ColumnName = "Status", ColumnDescription = "用户状态", Length = 200, IsNullable = true)] + public string Status { get; set; } + + /// + /// 排序码 + /// + [SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)] + public int? SortCode { get; set; } +} diff --git a/SimpleAdmin.System/Entity/GenBasic.cs b/SimpleAdmin.System/Entity/GenBasic.cs new file mode 100644 index 0000000..2a400c3 --- /dev/null +++ b/SimpleAdmin.System/Entity/GenBasic.cs @@ -0,0 +1,202 @@ +namespace SimpleAdmin.System; + +/// +/// 代码生成基础 +/// +[SugarTable("gen_basic", TableDescription = "代码生成基础")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class GenBasic : BaseEntity +{ + /// + /// 所属库 + /// + [SugarColumn(ColumnName = "ConfigId", ColumnDescription = "库名", Length = 200)] + public virtual string ConfigId { get; set; } + + /// + /// 主表 + /// + [SugarColumn(ColumnName = "DbTable", ColumnDescription = "主表", Length = 200)] + public virtual string DbTable { get; set; } + + + /// + /// 表实体名称 + /// + [SugarColumn(ColumnName = "EntityName", ColumnDescription = "表实体名称", Length = 200)] + public virtual string EntityName { get; set; } + + /// + /// 功能列表 + /// + [SugarColumn(ColumnName = "Functions", ColumnDescription = "功能列表", Length = 200, IsNullable = false)] + public virtual string Functions { get; set; } + + /// + /// 数据权限 + /// + [SugarColumn(ColumnName = "DataPermission", ColumnDescription = "数据权限", Length = 200, IsNullable = false)] + public virtual string DataPermission { get; set; } + + /// + /// 生成模版 + /// + [SugarColumn(ColumnName = "ModuleType", ColumnDescription = "生成模版", Length = 200, IsNullable = false)] + public virtual string ModuleType { get; set; } + + /// + /// 树Id字段 + /// + [SugarColumn(ColumnName = "TreeId", ColumnDescription = "树Id字段", Length = 200, IsNullable = true)] + public virtual string TreeId { get; set; } + + /// + /// 树父Id字段 + /// + [SugarColumn(ColumnName = "TreePid", ColumnDescription = "树父Id字段", Length = 200, IsNullable = true)] + public virtual string TreePid { get; set; } + + /// + /// 树名称字段 + /// + [SugarColumn(ColumnName = "TreeName", ColumnDescription = "树名称字段", Length = 200, IsNullable = true)] + public virtual string TreeName { get; set; } + + /// + /// 关联子表名 + /// + [SugarColumn(ColumnName = "ChildTable", ColumnDescription = "关联子表名", Length = 200, IsNullable = true)] + public virtual string ChildTable { get; set; } + + /// + /// 关联子表外键 + /// + [SugarColumn(ColumnName = "ChildFk", ColumnDescription = "关联子表外键", Length = 200, IsNullable = true)] + public virtual string ChildFk { get; set; } + + /// + /// 移除表前缀 + /// + [SugarColumn(ColumnName = "TablePrefix", ColumnDescription = "移除表前缀", Length = 200)] + public virtual string TablePrefix { get; set; } + + /// + /// 生成方式 + /// + [SugarColumn(ColumnName = "GenerateType", ColumnDescription = "生成方式", Length = 200)] + public virtual string GenerateType { get; set; } + + /// + /// 所属模块 + /// + [SugarColumn(ColumnName = "Module", ColumnDescription = "所属模块")] + public virtual long Module { get; set; } + + /// + /// 上级目录 + /// + [SugarColumn(ColumnName = "MenuPid", ColumnDescription = "上级目录")] + public virtual long MenuPid { get; set; } + + /// + /// 业务名 + /// + [SugarColumn(ColumnName = "RouteName", ColumnDescription = "路由名", Length = 200)] + public virtual string RouteName { get; set; } + + /// + /// 图标 + /// + [SugarColumn(ColumnName = "Icon", ColumnDescription = "图标", Length = 200)] + public virtual string Icon { get; set; } + + /// + /// 功能名 + /// + [SugarColumn(ColumnName = "FunctionName", ColumnDescription = "功能名", Length = 200)] + public virtual string FunctionName { get; set; } + + /// + /// 功能名后缀 + /// + [SugarColumn(ColumnName = "FunctionNameSuffix", ColumnDescription = "功能名后缀", Length = 200, IsNullable = true)] + public virtual string FunctionNameSuffix { get; set; } + + /// + /// 业务名 + /// + [SugarColumn(ColumnName = "BusName", ColumnDescription = "业务名", Length = 200)] + public virtual string BusName { get; set; } + + /// + /// 类名 + /// + [SugarColumn(ColumnName = "ClassName", ColumnDescription = "类名", Length = 200)] + public virtual string ClassName { get; set; } + + /// + /// 表单布局 + /// + [SugarColumn(ColumnName = "FormLayout", ColumnDescription = "表单布局", Length = 200)] + public virtual string FormLayout { get; set; } + + /// + /// 使用栅格 + /// + [SugarColumn(ColumnName = "GridWhether", ColumnDescription = "使用栅格", Length = 200)] + public virtual string GridWhether { get; set; } + + /// + /// 左侧树 + /// + [SugarColumn(ColumnName = "LeftTree", ColumnDescription = "使用左侧树", Length = 200)] + public virtual string LeftTree { get; set; } + + /// + /// 前端项目路径 + /// + [SugarColumn(ColumnName = "FrontedPath", ColumnDescription = "前端项目路径", IsNullable = true, Length = 200)] + public virtual string FrontedPath { get; set; } + + /// + /// 服务代码存放项目 + /// + [SugarColumn(ColumnName = "ServicePosition", ColumnDescription = "服务代码存放项目", IsNullable = true, Length = 200)] + public virtual string ServicePosition { get; set; } + + /// + /// 服务代码存放文件夹 + /// + [SugarColumn(ColumnName = "ServiceDictionary", ColumnDescription = "服务代码存放文件夹", IsNullable = true, Length = 200)] + public virtual string ServiceDictionary { get; set; } + + /// + /// 控制器代码存放位置 + /// + [SugarColumn(ColumnName = "ControllerPosition", ColumnDescription = "控制器代码存放位置", IsNullable = true, Length = 200)] + public virtual string ControllerPosition { get; set; } + + /// + /// 控制器代码存放文件夹 + /// + [SugarColumn(ColumnName = "ControllerDictionary", ColumnDescription = "控制器代码存放文件夹", IsNullable = true, Length = 200)] + public virtual string ControllerDictionary { get; set; } + + /// + /// 作者 + /// + [SugarColumn(ColumnName = "AuthorName", ColumnDescription = "作者", Length = 200)] + public virtual string AuthorName { get; set; } + + /// + /// 排序 + /// + [SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序")] + public virtual int SortCode { get; set; } + + /// + /// 功能列表 + /// + [SugarColumn(IsIgnore = true)] + public virtual List FuncList { get; set; } +} diff --git a/SimpleAdmin.System/Entity/GenConfig.cs b/SimpleAdmin.System/Entity/GenConfig.cs new file mode 100644 index 0000000..3145872 --- /dev/null +++ b/SimpleAdmin.System/Entity/GenConfig.cs @@ -0,0 +1,154 @@ +namespace SimpleAdmin.System; + +/// +/// 代码生成配置 +/// +[SugarTable("gen_config", TableDescription = "代码生成配置")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class GenConfig : BaseEntity +{ + /// + /// 基础ID + /// + [SugarColumn(ColumnName = "BasicId", ColumnDescription = "基础配置ID")] + public long BasicId { get; set; } + + /// + /// 字段排序 + /// + [SugarColumn(ColumnName = "FieldIndex", ColumnDescription = "字段排序", IsNullable = true)] + public int FieldIndex { get; set; } + + /// + /// 是否主键 + /// + [SugarColumn(ColumnName = "IsPrimaryKey", ColumnDescription = "是否主键", Length = 200)] + public string IsPrimaryKey { get; set; } + + /// + /// 字段 + /// + [SugarColumn(ColumnName = "FieldName", ColumnDescription = "字段", Length = 200)] + public string FieldName { get; set; } + + /// + /// 名称 + /// + [SugarColumn(ColumnName = "FieldRemark", ColumnDescription = "名称", Length = 200)] + public string FieldRemark { get; set; } + + /// + /// 类型 + /// + [SugarColumn(ColumnName = "FieldType", ColumnDescription = "类型", Length = 200)] + public string FieldType { get; set; } + + /// + /// 实体类型 + /// + [SugarColumn(ColumnName = "FieldNetType", ColumnDescription = "实体类型", Length = 200)] + public string FieldNetType { get; set; } + + /// + /// 作用类型 + /// + [SugarColumn(ColumnName = "EffectType", ColumnDescription = "作用类型", Length = 200)] + public string EffectType { get; set; } + + /// + /// 外键显示字段 + /// + [SugarColumn(ColumnName = "FkEntityName", ColumnDescription = "外键实体名称", Length = 200, IsNullable = true)] + public string FkEntityName { get; set; } + + /// + /// 外键ID + /// + [SugarColumn(ColumnName = "FkColumnId", ColumnDescription = "外键ID", Length = 200, IsNullable = true)] + public string FkColumnId { get; set; } + + /// + /// 外键显示字段 + /// + [SugarColumn(ColumnName = "FkColumnName", ColumnDescription = "外键显示字段", Length = 200, IsNullable = true)] + public string FkColumnName { get; set; } + + /// + /// 字典 + /// + [SugarColumn(ColumnName = "DictTypeCode", ColumnDescription = "字典", Length = 200, IsNullable = true)] + public string DictTypeCode { get; set; } + + /// + /// 列宽度 + /// + [SugarColumn(ColumnName = "Width", ColumnDescription = "列宽度")] + public int Width { get; set; } + + + /// + /// 列表显示 + /// + [SugarColumn(ColumnName = "WhetherTable", ColumnDescription = "列表显示", Length = 200)] + public string WhetherTable { get; set; } + + /// + /// 列省略 + /// + [SugarColumn(ColumnName = "WhetherRetract", ColumnDescription = "列省略", Length = 200)] + public string WhetherRetract { get; set; } + + /// + /// 可伸缩列 + /// + [SugarColumn(ColumnName = "WhetherResizable", ColumnDescription = "可伸缩列", Length = 200)] + public string WhetherResizable { get; set; } + + /// + /// 是否增改 + /// + [SugarColumn(ColumnName = "WhetherAddUpdate", ColumnDescription = "是否增改", Length = 200)] + public string WhetherAddUpdate { get; set; } + + /// + /// 是否导入导出 + /// + [SugarColumn(ColumnName = "WhetherImportExport", ColumnDescription = "是否导入导出", Length = 200)] + public string WhetherImportExport { get; set; } + + /// + /// 必填 + /// + [SugarColumn(ColumnName = "WhetherRequired", ColumnDescription = "必填", Length = 200)] + public string WhetherRequired { get; set; } + + /// + /// 查询 + /// + [SugarColumn(ColumnName = "QueryWhether", ColumnDescription = "查询", Length = 200)] + public string QueryWhether { get; set; } + + /// + /// 查询方式 + /// + [SugarColumn(ColumnName = "QueryType", ColumnDescription = "查询方式", Length = 200, IsNullable = true)] + public string QueryType { get; set; } + + /// + /// 排序 + /// + [SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序")] + public int SortCode { get; set; } + + /// + /// 字段名首字母小写 + /// + [SugarColumn(IsIgnore = true)] + public string FieldNameFirstLower { get; set; } + + /// + /// 字段名首字母大写 + /// + [SugarColumn(IsIgnore = true)] + public string FieldNameFirstUpper { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysConfig.cs b/SimpleAdmin.System/Entity/SysConfig.cs new file mode 100644 index 0000000..28f5f40 --- /dev/null +++ b/SimpleAdmin.System/Entity/SysConfig.cs @@ -0,0 +1,49 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 配置 +/// +[SugarTable("sys_config", TableDescription = "配置")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class SysConfig : BaseEntity +{ + /// + /// 配置键 + /// + [SugarColumn(ColumnName = "ConfigKey", ColumnDescription = "配置键", Length = 200)] + public virtual string ConfigKey { get; set; } + + /// + /// 配置值 + /// + [SugarColumn(ColumnName = "ConfigValue", ColumnDescription = "配置值", ColumnDataType = StaticConfig.CodeFirst_BigString)] + public virtual string ConfigValue { get; set; } + + /// + /// 分类 + /// + [SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)] + public string Category { get; set; } + + /// + /// 备注 + /// + [SugarColumn(ColumnName = "Remark", ColumnDescription = "备注", Length = 200, IsNullable = true)] + public string Remark { get; set; } + + /// + /// 排序码 + /// + [SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)] + public int SortCode { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysDict.cs b/SimpleAdmin.System/Entity/SysDict.cs new file mode 100644 index 0000000..3f4fb50 --- /dev/null +++ b/SimpleAdmin.System/Entity/SysDict.cs @@ -0,0 +1,56 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 字典 +/// +[SugarTable("sys_dict", TableDescription = "字典表")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class SysDict : BaseEntity +{ + /// + /// 父id + /// + [SugarColumn(ColumnName = "ParentId", ColumnDescription = "父id")] + public virtual long ParentId { get; set; } + + /// + /// 字典文字 + /// + [SugarColumn(ColumnName = "DictLabel", ColumnDescription = "字典文字", Length = 200)] + public virtual string DictLabel { get; set; } + + /// + /// 字典值 + /// + [SugarColumn(ColumnName = "DictValue", ColumnDescription = "字典值", Length = 200)] + public virtual string DictValue { get; set; } + + /// + /// 分类 + /// + [SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)] + public virtual string Category { get; set; } + + /// + /// 排序码 + /// + [SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码")] + public int SortCode { get; set; } + + + /// + /// 子节点 + /// + [SugarColumn(IsIgnore = true)] + public List Children { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysFile.cs b/SimpleAdmin.System/Entity/SysFile.cs new file mode 100644 index 0000000..0d6c250 --- /dev/null +++ b/SimpleAdmin.System/Entity/SysFile.cs @@ -0,0 +1,79 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 文件表 +/// +[SugarTable("sys_file", TableDescription = "文件表")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class SysFile : DataEntityBase +{ + /// + /// 存储引擎 + /// + [SugarColumn(ColumnName = "Engine", ColumnDescription = "存储引擎", Length = 200)] + public string Engine { get; set; } + + /// + /// 存储桶 + /// + [SugarColumn(ColumnName = "Bucket", ColumnDescription = "存储桶", Length = 200)] + public string Bucket { get; set; } + + /// + /// 文件名称 + /// + [SugarColumn(ColumnName = "Name", ColumnDescription = "文件名称")] + public string Name { get; set; } + + /// + /// 文件后缀 + /// + [SugarColumn(ColumnName = "Suffix", ColumnDescription = "文件后缀", Length = 200)] + public string Suffix { get; set; } + + /// + /// 文件大小kb + /// + [SugarColumn(ColumnName = "SizeKb", ColumnDescription = "文件大小kb")] + public long SizeKb { get; set; } + + /// + /// 文件大小(格式化后) + /// + [SugarColumn(ColumnName = "SizeInfo", ColumnDescription = "文件大小(格式化后)", Length = 200)] + public string SizeInfo { get; set; } + + /// + /// 文件的对象名(唯一名称) + /// + [SugarColumn(ColumnName = "ObjName", ColumnDescription = "文件的对象名(唯一名称)")] + public string ObjName { get; set; } + + /// + /// 文件存储路径 + /// + [SugarColumn(ColumnName = "StoragePath", ColumnDescription = "文件存储路径")] + public string StoragePath { get; set; } + + /// + /// 文件下载路径 + /// + [SugarColumn(ColumnName = "DownloadPath", ColumnDescription = "文件下载路径", IsNullable = true)] + public string DownloadPath { get; set; } + + /// + /// 图片缩略图 + /// + [SugarColumn(ColumnName = "Thumbnail", ColumnDescription = "图片缩略图", IsNullable = true, ColumnDataType = StaticConfig.CodeFirst_BigString)] + public string Thumbnail { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysLogOperate.cs b/SimpleAdmin.System/Entity/SysLogOperate.cs new file mode 100644 index 0000000..bae5e10 --- /dev/null +++ b/SimpleAdmin.System/Entity/SysLogOperate.cs @@ -0,0 +1,61 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 操作日志表 +/// +[SugarTable("sys_log_operate_{year}{month}{day}", TableDescription = "操作日志表")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class SysLogOperate : SysLogVisit +{ + /// + /// 具体消息 + /// + [SugarColumn(ColumnName = "ExeMessage", ColumnDescription = "具体消息", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)] + public string ExeMessage { get; set; } + + /// + /// 类名称 + /// + [SugarColumn(ColumnName = "ClassName", ColumnDescription = "类名称", Length = 200)] + public string ClassName { get; set; } + + /// + /// 方法名称 + /// + [SugarColumn(ColumnName = "MethodName", ColumnDescription = "方法名称", Length = 200)] + public string MethodName { get; set; } + + /// + /// 请求方式 + /// + [SugarColumn(ColumnName = "ReqMethod", ColumnDescription = "请求方式", Length = 200, IsNullable = true)] + public string ReqMethod { get; set; } + + /// + /// 请求地址 + /// + [SugarColumn(ColumnName = "ReqUrl", ColumnDescription = "请求地址", ColumnDataType = StaticConfig.CodeFirst_BigString)] + public string ReqUrl { get; set; } + + /// + /// 请求参数 + /// + [SugarColumn(ColumnName = "ParamJson", ColumnDescription = "请求参数", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)] + public string ParamJson { get; set; } + + /// + /// 返回结果 + /// + [SugarColumn(ColumnName = "ResultJson", ColumnDescription = "返回结果", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)] + public string ResultJson { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysLogVisit.cs b/SimpleAdmin.System/Entity/SysLogVisit.cs new file mode 100644 index 0000000..e085d4f --- /dev/null +++ b/SimpleAdmin.System/Entity/SysLogVisit.cs @@ -0,0 +1,81 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 访问日志表 +/// +[SugarTable("sys_log_visit_{year}{month}{day}", TableDescription = "访问日志表")] +[SplitTable(SplitType.Year)]//按年分表 (自带分表支持 年、季、月、周、日) +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class SysLogVisit : BaseEntity +{ + /// + /// 日志分类 + /// + [SugarColumn(ColumnName = "Category", ColumnDescription = "日志分类", Length = 200)] + public string Category { get; set; } + + /// + /// 日志名称 + /// + [SugarColumn(ColumnName = "Name", ColumnDescription = "日志名称", Length = 200)] + public string Name { get; set; } + + /// + /// 执行状态 + /// + [SugarColumn(ColumnName = "ExeStatus", ColumnDescription = "执行状态", Length = 200)] + public string ExeStatus { get; set; } + + /// + /// 操作ip + /// + [SugarColumn(ColumnName = "OpIp", ColumnDescription = "操作ip", Length = 200)] + public string OpIp { get; set; } + + /// + /// 操作地址 + /// + [SugarColumn(ColumnName = "OpAddress", ColumnDescription = "操作地址", Length = 200)] + public string OpAddress { get; set; } + + /// + /// 操作浏览器 + /// + [SugarColumn(ColumnName = "OpBrowser", ColumnDescription = "操作浏览器", Length = 200)] + public string OpBrowser { get; set; } + + /// + /// 操作系统 + /// + [SugarColumn(ColumnName = "OpOs", ColumnDescription = "操作系统", Length = 200)] + public string OpOs { get; set; } + + /// + /// 操作时间 + /// + [SugarColumn(ColumnName = "OpTime", ColumnDescription = "操作时间")] + [SplitField]//分表字段 在插入的时候会根据这个字段插入哪个表,在更新删除的时候用这个字段找出相关表 + public DateTime OpTime { get; set; } + + /// + /// 操作人姓名 + /// + [SugarColumn(ColumnName = "OpUser", ColumnDescription = "操作人姓名", Length = 200, IsNullable = true)] + public string OpUser { get; set; } + + /// + /// 操作人姓名 + /// + [SugarColumn(ColumnName = "OpAccount", ColumnDescription = "操作人账号", Length = 200, IsNullable = true)] + public string OpAccount { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysMessage.cs b/SimpleAdmin.System/Entity/SysMessage.cs new file mode 100644 index 0000000..4d01fd0 --- /dev/null +++ b/SimpleAdmin.System/Entity/SysMessage.cs @@ -0,0 +1,123 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 站内信 +/// +[SugarTable("sys_message", TableDescription = "站内信")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class SysMessage : BaseEntity +{ + /// + /// 分类 + /// + [SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)] + public virtual string Category { get; set; } + + /// + /// 主题 + /// + [SugarColumn(ColumnName = "Subject", ColumnDescription = "主题")] + public virtual string Subject { get; set; } + + /// + /// 接收人类型 + /// + [SugarColumn(ColumnName = "ReceiverType", ColumnDescription = "接收人类型")] + public virtual string ReceiverType { get; set; } + + /// + /// 接收人列表 + /// + [SugarColumn(ColumnName = "ReceiverInfo", ColumnDescription = "接收人列表", IsJson = true)] + public virtual List ReceiverInfo { get; set; } + + /// + /// 发送方式 + /// + [SugarColumn(ColumnName = "SendWay", ColumnDescription = "发送方式")] + public virtual string SendWay { get; set; } + + /// + /// 发送时间 + /// + [SugarColumn(ColumnDescription = "发送时间")] + public virtual DateTime SendTime { get; set; } + + /// + /// 正文 + /// + [SugarColumn(ColumnName = "Content", ColumnDescription = "正文", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)] + public virtual string Content { get; set; } + + + /// + /// 延迟时间(秒) + /// + [SugarColumn(IsIgnore = true)] + public int DelayTime { get; set; } + + /// + /// 已读情况 + /// + [SugarColumn(IsIgnore = true)] + public List ReceiverDetail { get; set; } = new List(); + + /// + /// 发送时间格式化 + /// + [SugarColumn(IsIgnore = true)] + public string SendTimeFormat { get; set; } + + /// + /// 分组查询用 + /// + [SugarColumn(IsIgnore = true)] + public int Index2 { get; set; } + + /// + /// 是否已读 + /// + [SugarColumn(IsIgnore = true)] + public bool Read { get; set; } +} + +public class ReceiverInfo +{ + /// + /// ID + /// + public long Id { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } +} + +public class ReceiverDetail +{ + /// + /// ID + /// + public long Id { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 是否已读 + /// + public bool Read { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysMessageUser.cs b/SimpleAdmin.System/Entity/SysMessageUser.cs new file mode 100644 index 0000000..73a7b79 --- /dev/null +++ b/SimpleAdmin.System/Entity/SysMessageUser.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 用户消息表 +/// +[SugarTable("sys_message_user", TableDescription = "用户消息表")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class SysMessageUser : BaseEntity +{ + /// + /// 消息Id + /// + [SugarColumn(ColumnName = "MessageId", ColumnDescription = "消息Id", IsNullable = false)] + public long MessageId { get; set; } + + /// + /// 用户Id + /// + [SugarColumn(ColumnName = "UserId", ColumnDescription = "用户Id", IsNullable = false)] + public long UserId { get; set; } + + /// + /// 已读未读 + /// + [SugarColumn(ColumnName = "Read", ColumnDescription = "已读未读", IsNullable = false)] + public bool Read { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysOrg.cs b/SimpleAdmin.System/Entity/SysOrg.cs new file mode 100644 index 0000000..cb0e3a8 --- /dev/null +++ b/SimpleAdmin.System/Entity/SysOrg.cs @@ -0,0 +1,83 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 组织 +/// +[SugarTable("sys_org", TableDescription = "组织")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +[CodeGen] +public class SysOrg : BaseEntity +{ + /// + /// 父id + /// + [SugarColumn(ColumnName = "ParentId", ColumnDescription = "父id")] + public long ParentId { get; set; } + + [SugarColumn(ColumnName = "ParentIdList", ColumnDescription = "父id列表", IsNullable = true, IsJson = true)] + public List ParentIdList { get; set; } = new List(); + + /// + /// 主管ID + /// + [SugarColumn(ColumnName = "DirectorId", ColumnDescription = "主管ID", IsNullable = true)] + public long? DirectorId { get; set; } + + /// + /// 名称 + /// + [SugarColumn(ColumnName = "Name", ColumnDescription = "名称", Length = 200)] + public string Name { get; set; } + + /// + /// 全称 + /// + [SugarColumn(ColumnName = "Names", ColumnDescription = "全称", Length = 500)] + public string Names { get; set; } + + /// + /// 编码 + /// + [SugarColumn(ColumnName = "Code", ColumnDescription = "编码", Length = 200)] + public string Code { get; set; } + + /// + /// 分类 + /// + [SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)] + public string Category { get; set; } + + /// + /// 排序码 + /// + [SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)] + public int? SortCode { get; set; } + + /// + /// 主管信息 + /// + [SugarColumn(IsIgnore = true)] + public UserSelectorOutPut DirectorInfo { get; set; } + + /// + /// 子节点 + /// + [SugarColumn(IsIgnore = true)] + public List Children { get; set; } + + /// + /// 设置为叶子节点(设置了loadData时有效) + /// + [SugarColumn(IsIgnore = true)] + public bool? Leaf { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysPosition.cs b/SimpleAdmin.System/Entity/SysPosition.cs new file mode 100644 index 0000000..16af01f --- /dev/null +++ b/SimpleAdmin.System/Entity/SysPosition.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 职位表 +/// +[SugarTable("sys_position", TableDescription = "职位表")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +[CodeGen] +public class SysPosition : DataEntityBase +{ + /// + /// 组织id + /// + [SugarColumn(ColumnName = "OrgId", ColumnDescription = "组织id")] + public virtual long OrgId { get; set; } + + /// + /// 名称 + /// + [SugarColumn(ColumnName = "Name", ColumnDescription = "名称", Length = 200)] + public virtual string Name { get; set; } + + /// + /// 编码 + /// + [SugarColumn(ColumnName = "Code", ColumnDescription = "编码", Length = 200)] + public string Code { get; set; } + + /// + /// 分类 + /// + [SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)] + public virtual string Category { get; set; } + + /// + /// 排序码 + /// + [SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)] + public int? SortCode { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysRelation.cs b/SimpleAdmin.System/Entity/SysRelation.cs new file mode 100644 index 0000000..b7e514e --- /dev/null +++ b/SimpleAdmin.System/Entity/SysRelation.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 系统关系表 +/// +[SugarTable("sys_relation", TableDescription = "系统关系表")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class SysRelation : PrimaryKeyEntity +{ + /// + /// 对象ID + /// + [SugarColumn(ColumnName = "ObjectId", ColumnDescription = "对象ID", IsNullable = false)] + public long ObjectId { get; set; } + + /// + /// 目标ID + /// + [SugarColumn(ColumnName = "TargetId", ColumnDescription = "目标ID", IsNullable = true)] + public string TargetId { get; set; } + + /// + /// 分类 + /// + [SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200, IsNullable = false)] + public string Category { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysResource.cs b/SimpleAdmin.System/Entity/SysResource.cs new file mode 100644 index 0000000..9323889 --- /dev/null +++ b/SimpleAdmin.System/Entity/SysResource.cs @@ -0,0 +1,191 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 资源 +/// +[SugarTable("sys_resource", TableDescription = "资源")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class SysResource : BaseEntity +{ + /// + /// 父id + /// + [SugarColumn(ColumnName = "ParentId", ColumnDescription = "父id", IsNullable = true)] + public virtual long? ParentId { get; set; } + + /// + /// 标题 + /// + [SugarColumn(ColumnName = "Title", ColumnDescription = "标题", Length = 200)] + public virtual string Title { get; set; } + + /// + /// 别名 + /// + [SugarColumn(ColumnName = "Name", ColumnDescription = "别名", Length = 200, IsNullable = true)] + public string Name { get; set; } + + /// + /// 描述 + /// + [SugarColumn(ColumnName = "Description", ColumnDescription = "描述", Length = 200, IsNullable = true)] + public string Description { get; set; } + + /// + /// 编码 + /// + [SugarColumn(ColumnName = "Code", ColumnDescription = "编码", Length = 200, IsNullable = true)] + public virtual string Code { get; set; } + + /// + /// 分类 + /// + [SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)] + public string Category { get; set; } + + /// + /// 模块 + /// + [SugarColumn(ColumnName = "Module", ColumnDescription = "所属模块Id", IsNullable = true)] + public virtual long? Module { get; set; } + + /// + /// 菜单类型 + /// + [SugarColumn(ColumnName = "MenuType", ColumnDescription = "菜单类型", Length = 200, IsNullable = true)] + public virtual string MenuType { get; set; } + + /// + /// 路径 + /// + [SugarColumn(ColumnName = "Path", ColumnDescription = "路径", IsNullable = true)] + public virtual string Path { get; set; } + + /// + /// 组件 + /// + [SugarColumn(ColumnName = "Component", ColumnDescription = "组件", Length = 200, IsNullable = true)] + public string Component { get; set; } + + /// + /// 图标 + /// + [SugarColumn(ColumnName = "Icon", ColumnDescription = "图标", Length = 200, IsNullable = true)] + public virtual string Icon { get; set; } + + /// + /// 是否在菜单中隐藏, 需要高亮的 path (通常用作详情页高亮父级菜单) + /// + [SugarColumn(ColumnName = "ActiveMenu", ColumnDescription = "需要高亮的 path (通常用作详情页高亮父级菜单)", Length = 200, IsNullable = true)] + public string ActiveMenu { get; set; } + + /// + /// 是否在菜单中隐藏 (通常列表详情页需要隐藏) + /// + [SugarColumn(ColumnName = "IsHide", ColumnDescription = "是否在菜单中隐藏 (通常列表详情页需要隐藏) ", IsNullable = true)] + public bool IsHide { get; set; } + + /// + /// 是否在菜单中隐藏 (通常列表详情页需要隐藏) + /// + [SugarColumn(ColumnName = "IsFull", ColumnDescription = "菜单是否全屏 (示例:数据大屏页面)", IsNullable = true)] + public bool IsFull { get; set; } + + /// + /// 菜单是否固定在标签页中 (首页通常是固定项) + /// + [SugarColumn(ColumnName = "IsAffix", ColumnDescription = "菜单是否固定在标签页中 (首页通常是固定项)", IsNullable = true)] + public bool IsAffix { get; set; } + + /// + /// 菜单是否固定在标签页中 (首页通常是固定项) + /// + [SugarColumn(ColumnName = "IsKeepAlive", ColumnDescription = " 当前路由是否缓存", IsNullable = true)] + public bool IsKeepAlive { get; set; } + + /// + /// 是否为首页 + /// + [SugarColumn(ColumnName = "IsHome", ColumnDescription = " 是否为首页", IsNullable = true)] + public bool IsHome { get; set; } + + /// + /// 排序码 + /// + [SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)] + public int? SortCode { get; set; } + + /// + /// 外链地址 + /// + [SugarColumn(ColumnName = "IsLink", ColumnDescription = "外链地址", IsNullable = true)] + public string IsLink { get; set; } + + /// + /// 菜单元标签 + /// + [SugarColumn(IsIgnore = true)] + public Meta Meta { get; set; } + + /// + /// 子节点 + /// + [SugarColumn(IsIgnore = true)] + public List Children { get; set; } +} + +/// +/// 菜单元标签 +/// +public class Meta +{ + /// + /// 图标 + /// + public string Icon { get; set; } + + /// + /// 标题 + /// + public string Title { get; set; } + + /// + /// 是否在菜单中隐藏, 需要高亮的 path (通常用作详情页高亮父级菜单) + /// + public string ActiveMenu { get; set; } + + /// + /// 是否在菜单中隐藏 (通常列表详情页需要隐藏) + /// + public bool IsHide { get; set; } + + /// + /// 路由外链时填写的访问地址 + /// + public string IsLink { get; set; } = ""; + + /// + /// 是否在菜单中隐藏 (通常列表详情页需要隐藏) + /// + public bool IsFull { get; set; } + + /// + /// 菜单是否固定在标签页中 (首页通常是固定项) + /// + public bool IsAffix { get; set; } + + /// + /// 菜单是否固定在标签页中 (首页通常是固定项) + /// + public bool IsKeepAlive { get; set; } +} diff --git a/SimpleAdmin.System/Entity/SysRole.cs b/SimpleAdmin.System/Entity/SysRole.cs new file mode 100644 index 0000000..1fde492 --- /dev/null +++ b/SimpleAdmin.System/Entity/SysRole.cs @@ -0,0 +1,83 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 角色 +/// +[SugarTable("sys_role", TableDescription = "角色")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +public class SysRole : DataEntityBase +{ + /// + /// 组织id + /// + [SugarColumn(ColumnName = "OrgId", ColumnDescription = "组织id", IsNullable = true)] + public long? OrgId { get; set; } + + /// + /// 名称 + /// + [SugarColumn(ColumnName = "Name", ColumnDescription = "名称", Length = 200, IsNullable = false)] + public virtual string Name { get; set; } + + /// + /// 编码 + /// + [SugarColumn(ColumnName = "Code", ColumnDescription = "编码", Length = 200, IsNullable = false)] + public string Code { get; set; } + + /// + /// 分类 + /// + [SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200, IsNullable = false)] + public virtual string Category { get; set; } + + /// + /// 默认数据范围 + /// + [SugarColumn(ColumnName = "DefaultDataScope", ColumnDescription = "默认数据范围", IsJson = true, ColumnDataType = StaticConfig.CodeFirst_BigString, + IsNullable = false)] + public virtual DefaultDataScope DefaultDataScope { get; set; } + + /// + /// 排序码 + /// + [SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)] + public int? SortCode { get; set; } + + /// + /// 用户列表 + /// + [SugarColumn(IsIgnore = true)] + public List UserList { get; set; } = new List(); +} + +/// +/// 默认数据范围 +/// +public class DefaultDataScope +{ + /// + /// 数据范围等级 + /// + public int Level { get; set; } + + /// + /// 数据范围 + /// + public string ScopeCategory { get; set; } + + /// + /// 自定义机构范围列表 + /// + public List ScopeDefineOrgIdList { get; set; } = new List(); +} diff --git a/SimpleAdmin.System/Entity/SysUser.cs b/SimpleAdmin.System/Entity/SysUser.cs new file mode 100644 index 0000000..b1a7628 --- /dev/null +++ b/SimpleAdmin.System/Entity/SysUser.cs @@ -0,0 +1,393 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 用户信息表 +/// +[SugarTable("sys_user", TableDescription = "用户信息表")] +[Tenant(SqlSugarConst.DB_DEFAULT)] +[BatchEdit] +[CodeGen] +public class SysUser : BaseEntity +{ + /// + /// 头像 + /// + [SugarColumn(ColumnName = "Avatar", ColumnDescription = "头像", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)] + public virtual string Avatar { get; set; } + + /// + /// 签名 + /// + [SugarColumn(ColumnName = "Signature", ColumnDescription = "签名", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)] + public string Signature { get; set; } + + /// + /// 账号 + /// + [SugarColumn(ColumnName = "Account", ColumnDescription = "账号", Length = 200, IsNullable = false)] + public virtual string Account { get; set; } + + /// + /// 密码 + /// + [SugarColumn(ColumnName = "Password", ColumnDescription = "密码", Length = 200, IsNullable = false)] + public string Password { get; set; } + + /// + /// 姓名 + /// + [SugarColumn(ColumnName = "Name", ColumnDescription = "姓名", Length = 200, IsNullable = true)] + public virtual string Name { get; set; } + + /// + /// 昵称 + /// + [SugarColumn(ColumnName = "Nickname", ColumnDescription = "昵称", Length = 200, IsNullable = true)] + public string Nickname { get; set; } + + /// + /// 性别 + /// + [SugarColumn(ColumnName = "Gender", ColumnDescription = "性别", Length = 200, IsNullable = true)] + public string Gender { get; set; } + + /// + /// 出生日期 + /// + [SugarColumn(ColumnName = "Birthday", ColumnDescription = "出生日期", Length = 200, IsNullable = true)] + public string Birthday { get; set; } + + /// + /// 民族 + /// + [SugarColumn(ColumnName = "Nation", ColumnDescription = "民族", Length = 200, IsNullable = true)] + public string Nation { get; set; } + + /// + /// 籍贯 + /// + [SugarColumn(ColumnName = "NativePlace", ColumnDescription = "籍贯", Length = 200, IsNullable = true)] + public string NativePlace { get; set; } + + /// + /// 家庭住址 + /// + [SugarColumn(ColumnName = "HomeAddress", ColumnDescription = "家庭住址", IsNullable = true)] + public string HomeAddress { get; set; } + + /// + /// 通信地址 + /// + [SugarColumn(ColumnName = "MailingAddress", ColumnDescription = "通信地址", IsNullable = true)] + public string MailingAddress { get; set; } + + /// + /// 证件类型 + /// + [SugarColumn(ColumnName = "IdCardType", ColumnDescription = "证件类型", Length = 200, IsNullable = true)] + public string IdCardType { get; set; } + + /// + /// 证件号码 + /// + [SugarColumn(ColumnName = "IdCardNumber", ColumnDescription = "证件号码", Length = 200, IsNullable = true)] + public string IdCardNumber { get; set; } + + /// + /// 文化程度 + /// + [SugarColumn(ColumnName = "CultureLevel", ColumnDescription = "文化程度", Length = 200, IsNullable = true)] + public string CultureLevel { get; set; } + + /// + /// 政治面貌 + /// + [SugarColumn(ColumnName = "PoliticalOutlook", ColumnDescription = "政治面貌", Length = 200, IsNullable = true)] + public string PoliticalOutlook { get; set; } + + /// + /// 毕业院校 + /// + [SugarColumn(ColumnName = "College", ColumnDescription = "毕业院校", Length = 200, IsNullable = true)] + public string College { get; set; } + + /// + /// 学历 + /// + [SugarColumn(ColumnName = "Education", ColumnDescription = "学历", Length = 200, IsNullable = true)] + public string Education { get; set; } + + /// + /// 学制 + /// + [SugarColumn(ColumnName = "EduLength", ColumnDescription = "学制", Length = 200, IsNullable = true)] + public string EduLength { get; set; } + + /// + /// 学位 + /// + [SugarColumn(ColumnName = "Degree", ColumnDescription = "学位", Length = 200, IsNullable = true)] + public string Degree { get; set; } + + /// + /// 手机 + /// 这里使用了SM4自动加密解密 + /// + [SugarColumn(ColumnName = "Phone", ColumnDescription = "手机", Length = 200, IsNullable = true)] + public string Phone { get; set; } + + /// + /// 邮箱 + /// + [SugarColumn(ColumnName = "Email", ColumnDescription = "邮箱", Length = 200, IsNullable = true)] + public string Email { get; set; } + + /// + /// 家庭电话 + /// + [SugarColumn(ColumnName = "HomeTel", ColumnDescription = "家庭电话", Length = 200, IsNullable = true)] + public string HomeTel { get; set; } + + /// + /// 办公电话 + /// + [SugarColumn(ColumnName = "OfficeTel", ColumnDescription = "办公电话", Length = 200, IsNullable = true)] + public string OfficeTel { get; set; } + + /// + /// 紧急联系人 + /// + [SugarColumn(ColumnName = "EmergencyContact", ColumnDescription = "紧急联系人", Length = 200, IsNullable = true)] + public string EmergencyContact { get; set; } + + /// + /// 紧急联系人电话 + /// + [SugarColumn(ColumnName = "EmergencyPhone", ColumnDescription = "紧急联系人电话", Length = 200, IsNullable = true)] + public string EmergencyPhone { get; set; } + + /// + /// 紧急联系人地址 + /// + [SugarColumn(ColumnName = "EmergencyAddress", ColumnDescription = "紧急联系人地址", IsNullable = true)] + public string EmergencyAddress { get; set; } + + /// + /// 员工编号 + /// + [SugarColumn(ColumnName = "EmpNo", ColumnDescription = "员工编号", Length = 200, IsNullable = true)] + public string EmpNo { get; set; } + + /// + /// 入职日期 + /// + [SugarColumn(ColumnName = "EntryDate", ColumnDescription = "入职日期", Length = 200, IsNullable = true)] + public string EntryDate { get; set; } + + /// + /// 机构id + /// + [SugarColumn(ColumnName = "OrgId", ColumnDescription = "机构id", IsNullable = false)] + public virtual long OrgId { get; set; } + + /// + /// 职位id + /// + [SugarColumn(ColumnName = "PositionId", ColumnDescription = "职位id", IsNullable = false)] + public virtual long PositionId { get; set; } + + /// + /// 职级 + /// + [SugarColumn(ColumnName = "PositionLevel", ColumnDescription = "职级", Length = 200, IsNullable = true)] + public string PositionLevel { get; set; } + + /// + /// 主管id + /// + [SugarColumn(ColumnName = "DirectorId", ColumnDescription = "主管id", IsNullable = true)] + public long? DirectorId { get; set; } + + + /// + /// 上次修改密码时间 + /// + [SugarColumn(ColumnName = "PwdRemindUpdateTime", ColumnDescription = "密码提醒修改时间", IsNullable = true)] + public DateTime? PwdRemindUpdateTime { get; set; } + + /// + /// 上次登录ip + /// + [SugarColumn(ColumnName = "LastLoginIp", ColumnDescription = "上次登录ip", Length = 200, IsNullable = true)] + public string LastLoginIp { get; set; } + + /// + /// 上次登录地点 + /// + [SugarColumn(ColumnName = "LastLoginAddress", ColumnDescription = "上次登录地点", Length = 200, IsNullable = true)] + public string LastLoginAddress { get; set; } + + /// + /// 上次登录时间 + /// + [SugarColumn(ColumnName = "LastLoginTime", ColumnDescription = "上次登录时间", IsNullable = true)] + public DateTime? LastLoginTime { get; set; } + + /// + /// 上次登录设备 + /// + [SugarColumn(ColumnName = "LastLoginDevice", ColumnDescription = "上次登录设备", IsNullable = true)] + public string LastLoginDevice { get; set; } + + /// + /// 最新登录ip + /// + [SugarColumn(ColumnName = "LatestLoginIp", ColumnDescription = "最新登录ip", Length = 200, IsNullable = true)] + public string LatestLoginIp { get; set; } + + /// + /// 最新登录地点 + /// + [SugarColumn(ColumnName = "LatestLoginAddress", ColumnDescription = "最新登录地点", Length = 200, IsNullable = true)] + public string LatestLoginAddress { get; set; } + + /// + /// 最新登录时间 + /// + [SugarColumn(ColumnName = "LatestLoginTime", ColumnDescription = "最新登录时间", IsNullable = true)] + public DateTime? LatestLoginTime { get; set; } + + /// + /// 最新登录设备 + /// + [SugarColumn(ColumnName = "LatestLoginDevice", ColumnDescription = "最新登录设备", IsNullable = true)] + public string LatestLoginDevice { get; set; } + + + /// + /// 排序码 + /// + [SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)] + public int? SortCode { get; set; } + + /// + /// 默认模块 + /// + [SugarColumn(ColumnName = "DefaultModule", ColumnDescription = "默认模块", IsNullable = true)] + public long? DefaultModule { get; set; } + + /// + /// 机构信息 + /// + [SugarColumn(IsIgnore = true)] + public string OrgName { get; set; } + + /// + /// 机构信息全称 + /// + [SugarColumn(IsIgnore = true)] + public string OrgNames { get; set; } + + /// + /// 职位信息 + /// + [SugarColumn(IsIgnore = true)] + public string PositionName { get; set; } + + /// + /// 组织和机构ID列表,组织ID从上到下最后是职位 + /// + [SugarColumn(IsIgnore = true, IsJson = true)] + public List OrgAndPosIdList { get; set; } = new List(); + + /// + /// 主管信息 + /// + [SugarColumn(IsIgnore = true)] + public UserSelectorOutPut DirectorInfo { get; set; } + + /// + /// 按钮码集合 + /// + [SugarColumn(IsIgnore = true)] + public List ButtonCodeList { get; set; } + + /// + /// 权限码集合 + /// + [SugarColumn(IsIgnore = true)] + public List PermissionCodeList { get; set; } + + /// + /// 角色码集合 + /// + [SugarColumn(IsIgnore = true)] + public List RoleCodeList { get; set; } + + /// + /// 角色ID集合 + /// + [SugarColumn(IsIgnore = true)] + public List RoleIdList { get; set; } + + /// + /// 数据范围集合 + /// + [SugarColumn(IsIgnore = true)] + public List DataScopeList { get; set; } + + /// + /// 默认数据范围 + /// + [SugarColumn(IsIgnore = true)] + public DefaultDataScope DefaultDataScope { get; set; } + + /// + /// 机构及以下机构ID集合 + /// + [SugarColumn(IsIgnore = true)] + public List ScopeOrgChildList { get; set; } + + /// + /// 机构及以下机构ID集合 + /// + [SugarColumn(IsIgnore = true)] + public List ModuleList { get; set; } = new List(); + + /// + /// 租户Id + /// + [SugarColumn(IsIgnore = true)] + public long? TenantId { get; set; } +} + +/// +/// 数据范围类 +/// +public class DataScope +{ + /// + /// API接口 + /// + public string ApiUrl { get; set; } + + /// + /// 数据范围分类 + /// + public string ScopeCategory { get; set; } + + /// + /// 数据范围的机构ID列表 + /// + public List? DataScopes { get; set; } +} diff --git a/SimpleAdmin.System/EventSubscriber/AuthEventSubscriber.cs b/SimpleAdmin.System/EventSubscriber/AuthEventSubscriber.cs new file mode 100644 index 0000000..ebd008a --- /dev/null +++ b/SimpleAdmin.System/EventSubscriber/AuthEventSubscriber.cs @@ -0,0 +1,169 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + + +using IP2Region.Net.Abstractions; + +namespace SimpleAdmin.System; + +/// +/// 认证模块事件总线 +/// +public class AuthEventSubscriber : IEventSubscriber, ISingleton +{ + private readonly ISimpleCacheService _simpleCacheService; + private readonly ISearcher _searcher; + + public IServiceProvider Services { get; } + private readonly SqlSugarScope _db; + + public AuthEventSubscriber(ISimpleCacheService simpleCacheService, IServiceProvider services, ISearcher searcher) + { + _db = DbContext.DB; + _simpleCacheService = simpleCacheService; + _searcher = searcher; + Services = services; + } + + /// + /// 登录事件 + /// + /// + /// + [EventSubscribe(EventSubscriberConst.LOGIN_B)] + public async Task Login(EventHandlerExecutingContext context) + { + var loginEvent = (LoginEvent)context.Source.Payload;//获取参数 + var loginAddress = GetLoginAddress(loginEvent.Ip); + var sysUser = loginEvent.SysUser; + + #region 登录/密码策略 + + var key = SystemConst.CACHE_LOGIN_ERROR_COUNT + sysUser.Account;//获取登录错误次数Key值 + _simpleCacheService.Remove(key);//移除登录错误次数 + + // 创建新的作用域 + using var scope = Services.CreateScope(); + // 解析服务 + var configService = scope.ServiceProvider.GetRequiredService(); + var messageService = scope.ServiceProvider.GetRequiredService(); + var pwdRemindUpdateTime = sysUser.PwdRemindUpdateTime;//获取上次提醒修改密码时间 + var loginPolicy = await configService.GetConfigsByCategory(CateGoryConst.CONFIG_PWD_POLICY);//获取密码策略 + //获取用户token列表 + var tokenInfos = _simpleCacheService.HashGetOne>(CacheConst.CACHE_USER_TOKEN, sysUser.Id.ToString()); + var userToken = tokenInfos.Where(it => it.Token == loginEvent.Token).FirstOrDefault(); + if (userToken != null) + { + var subject = "请及时修改密码"; + //如果上次修改密码时间为空 + if (pwdRemindUpdateTime == null) + { + var pwdUpdateDefault = loginPolicy.First(x => x.ConfigKey == SysConfigConst.PWD_UPDATE_DEFAULT).ConfigValue.ToBoolean();//获取初始化提醒 + //如果密码初始化提醒为true + if (pwdUpdateDefault) + { + await messageService.Add(new MessageSendInput + { + Subject = subject, + Content = "请及时修改初始密码", + Category = CateGoryConst.MESSAGE_INFORM, + ReceiverIdList = new List { sysUser.Id }, + SendWay = SysDictConst.SEND_WAY_NOW, + ReceiverType = SysDictConst.RECEIVER_TYPE_APPOINT, + ReceiverInfo = new List { new ReceiverInfo { Id = sysUser.Id, Name = sysUser.Name } } + }); + } + sysUser.PwdRemindUpdateTime = DateTime.Now;//设置提醒时密码时间为当前时间 + } + else + { + var pwdRemind = loginPolicy.First(x => x.ConfigKey == SysConfigConst.PWD_REMIND).ConfigValue.ToBoolean();//获取密码提醒天数 + if (pwdRemind) + { + var pwdRemindDay = loginPolicy.First(x => x.ConfigKey == SysConfigConst.PWD_REMIND_DAY).ConfigValue.ToInt();//获取密码提醒时间 + if (DateTime.Now - pwdRemindUpdateTime > TimeSpan.FromDays(pwdRemindDay)) + { + await messageService.Add(new MessageSendInput + { + Subject = subject, + Content = $"已超过{pwdRemindDay}天未修改密码,请及时修改密码", + Category = CateGoryConst.MESSAGE_INFORM, + SendWay = SysDictConst.SEND_WAY_NOW, + ReceiverType = SysDictConst.RECEIVER_TYPE_APPOINT, + ReceiverInfo = new List { new ReceiverInfo { Id = sysUser.Id, Name = sysUser.Name } } + }); + } + sysUser.PwdRemindUpdateTime = DateTime.Now;//设置提醒时密码时间为当前时间,避免重复提醒 + } + } + } + + #endregion 登录/密码策略 + + #region 重新赋值属性,设置本次登录信息为最新的信息 + + sysUser.LastLoginAddress = sysUser.LatestLoginAddress; + sysUser.LastLoginDevice = sysUser.LatestLoginDevice; + sysUser.LastLoginIp = sysUser.LatestLoginIp; + sysUser.LastLoginTime = sysUser.LatestLoginTime; + sysUser.LatestLoginAddress = loginAddress; + sysUser.LatestLoginDevice = loginEvent.Device.ToString(); + sysUser.LatestLoginIp = loginEvent.Ip; + sysUser.LatestLoginTime = loginEvent.DateTime; + + #endregion 重新赋值属性,设置本次登录信息为最新的信息 + + //更新用户登录信息 + if (await _db.UpdateableWithAttr(sysUser).UpdateColumns(it => new + { + it.LastLoginAddress, + it.LastLoginDevice, + it.LastLoginIp, + it.LastLoginTime, + it.LatestLoginAddress, + it.LatestLoginDevice, + it.LatestLoginIp, + it.LatestLoginTime, + LastUpdatePwdTime = it.PwdRemindUpdateTime + }).ExecuteCommandAsync() > 0) + _simpleCacheService.HashAdd(SystemConst.CACHE_SYS_USER, sysUser.Id.ToString(), sysUser);//更新Redis信息 + + await Task.CompletedTask; + } + + /// + /// 登出事件 + /// + /// + /// + [EventSubscribe(EventSubscriberConst.LOGIN_OUT_B)] + public async Task LoginOut(EventHandlerExecutingContext context) + { + _ = (LoginEvent)context.Source.Payload;//获取参数 + } + + /// + /// 解析IP地址 + /// + /// ip地址 + /// + private string GetLoginAddress(string ip) + { + try + { + var ipInfo = _searcher.Search(ip).Replace("0|", "");//解析ip并格式化 + return ipInfo; + } + catch + { + return "未知"; + } + } +} diff --git a/SimpleAdmin.System/EventSubscriber/Const/EventSubscriberConst.cs b/SimpleAdmin.System/EventSubscriber/Const/EventSubscriberConst.cs new file mode 100644 index 0000000..514b70e --- /dev/null +++ b/SimpleAdmin.System/EventSubscriber/Const/EventSubscriberConst.cs @@ -0,0 +1,64 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 事件总线常量 +/// +public class EventSubscriberConst +{ + #region AuthEventSubscriber + + /// + /// B端登录 + /// + public const string LOGIN_B = "B端登录"; + + /// + /// B端登录 + /// + public const string LOGIN_OUT_B = "B端登出"; + + #endregion AuthEventSubscriber + + #region UserEventSubscriber + + /// + /// 清除用户缓存 + /// + public const string CLEAR_USER_CACHE = "清除用户缓存"; + + /// + /// 清除组织下用户Token + /// + public const string CLEAR_ORG_TOKEN = "清除组织下用户Token"; + + /// + /// 清除模块下用户Token + /// + public const string CLEAR_MODULE_TOKEN = "清除模块下用户Token"; + + #endregion UserEventSubscriber + + #region NoticeEventSubscriber + + /// + /// 通知用户下线 + /// + public const string USER_LOGIN_OUT = "通知用户下线"; + + /// + /// 新消息 + /// + public const string NEW_MESSAGE = "新消息"; + + #endregion NoticeEventSubscriber +} diff --git a/SimpleAdmin.System/EventSubscriber/Dto/LoginEvent.cs b/SimpleAdmin.System/EventSubscriber/Dto/LoginEvent.cs new file mode 100644 index 0000000..7781fa2 --- /dev/null +++ b/SimpleAdmin.System/EventSubscriber/Dto/LoginEvent.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using UAParser; + +namespace SimpleAdmin.System; + +/// +/// 登录事件参数 +/// +public class LoginEvent +{ + /// + /// 请求上下文 + /// + public ClientInfo ClientInfo { get; set; } + + /// + /// 用户信息 + /// + public SysUser SysUser { get; set; } + + /// + /// Ip地址 + /// + public string Ip { get; set; } + + /// + /// 登录设备 + /// + public AuthDeviceTypeEnum Device { get; set; } + + /// + /// Tokens + /// + public string Token { get; set; } + + /// + /// 过期时间 + /// + public int Expire { get; set; } + + /// + /// 时间 + /// + public DateTime DateTime = DateTime.Now; +} diff --git a/SimpleAdmin.System/EventSubscriber/Dto/NoticeEvent.cs b/SimpleAdmin.System/EventSubscriber/Dto/NoticeEvent.cs new file mode 100644 index 0000000..dbf2f56 --- /dev/null +++ b/SimpleAdmin.System/EventSubscriber/Dto/NoticeEvent.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 用户登出事件 +/// +public class UserLoginOutEvent +{ + /// + /// 用户Id + /// + public string UserId { get; set; } + + /// + /// token信息 + /// + + public List TokenInfos { get; set; } + + /// + /// 内容 + /// + public string Message { get; set; } +} + +/// +/// 新消息事件 +/// +public class NewMessageEvent +{ + /// + /// 消息Id + /// + public long Id { get; set; } + + /// + /// 发送方式 + /// + public string SendWay { get; set; } + + /// + /// 发送时间 + /// + public DateTime SendTime { get; set; } +} diff --git a/SimpleAdmin.System/EventSubscriber/NoticeEventSubscriber.cs b/SimpleAdmin.System/EventSubscriber/NoticeEventSubscriber.cs new file mode 100644 index 0000000..9f3b839 --- /dev/null +++ b/SimpleAdmin.System/EventSubscriber/NoticeEventSubscriber.cs @@ -0,0 +1,110 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using Microsoft.Extensions.Options; + +namespace SimpleAdmin.System; + +/// +/// 通知事件总线 +/// +public class NoticeEventSubscriber : IEventSubscriber, ISingleton +{ + private readonly ISimpleCacheService _simpleCacheService; + + private readonly IServiceScopeFactory _scopeFactory; + private readonly bool _useMessageCenter; + private readonly SqlSugarScope _db; + + public NoticeEventSubscriber(ISimpleCacheService simpleCacheService, IServiceScopeFactory scopeFactory, + IOptionsMonitor options) + { + _db = DbContext.DB; + _simpleCacheService = simpleCacheService; + _scopeFactory = scopeFactory; + _useMessageCenter = options.CurrentValue.UseMessageCenter; + } + + /// + /// 通知用户下线事件 + /// + /// + /// + [EventSubscribe(EventSubscriberConst.USER_LOGIN_OUT)] + public async Task UserLoginOut(EventHandlerExecutingContext context) + { + var loginEvent = (UserLoginOutEvent)context.Source.Payload;//获取参数 + //客户端ID列表 + var clientIds = new List(); + //遍历token列表获取客户端ID列表 + loginEvent.TokenInfos.ForEach(it => + { + clientIds.AddRange(it.ClientIds); + }); + } + + /// + /// 有新的消息 + /// + /// + /// + [EventSubscribe(EventSubscriberConst.NEW_MESSAGE)] + public async Task NewMessage(EventHandlerExecutingContext context) + { + var newMessageEvent = (NewMessageEvent)context.Source.Payload;//获取参数 + var messageId = newMessageEvent.Id; + //如果启用了通知中心 + if (_useMessageCenter) + { + if (newMessageEvent.SendWay == SysDictConst.SEND_WAY_NOW) + { + //立即发送 + await SendMessage(messageId); + } + else + { + //延迟发送 + var sendTime = newMessageEvent.SendTime; + //计算延迟时间 + var delay = (int)(sendTime - DateTime.Now).TotalSeconds; + if (delay > 0) + { + await SendMessage(messageId, delay); + } + else + { + await SendMessage(messageId); + } + } + } + } + + /// + /// 发送消息 + /// + /// 消息id + /// 延迟 + private async Task SendMessage(long messageId, int delay = 0) + { + _simpleCacheService.AddDelayQueue(CacheConst.CACHE_NOTIFICATION, messageId, delay); + } + + /// + /// 获取服务 + /// + /// + /// + private T GetService() where T : class, new() + { + // 创建新的作用域 + using var scope = _scopeFactory.CreateScope(); + return scope.ServiceProvider.GetRequiredService(); + } +} diff --git a/SimpleAdmin.System/EventSubscriber/UserEventSubscriber.cs b/SimpleAdmin.System/EventSubscriber/UserEventSubscriber.cs new file mode 100644 index 0000000..4a0d693 --- /dev/null +++ b/SimpleAdmin.System/EventSubscriber/UserEventSubscriber.cs @@ -0,0 +1,108 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using NetTaste; +using SimpleRedis; + +namespace SimpleAdmin.System; + +/// +/// 用户模块事件总线 +/// +public class UserEventSubscriber : IEventSubscriber, ISingleton +{ + private readonly IServiceProvider _services; + private readonly ISimpleCacheService _simpleCacheService; + + + public UserEventSubscriber(IServiceProvider services, ISimpleCacheService simpleCacheService) + { + _services = services; + _simpleCacheService = simpleCacheService; + } + + /// + /// 根据角色ID列表清除用户缓存 + /// + /// + /// + [EventSubscribe(EventSubscriberConst.CLEAR_USER_CACHE)] + public async Task DeleteUserCacheByRoleIds(EventHandlerExecutingContext context) + { + var roleIds = (List)context.Source.Payload;//获取角色ID + + // 创建新的作用域 + using var scope = _services.CreateScope(); + // 解析角色服务 + var relationService = scope.ServiceProvider.GetRequiredService(); + //获取用户和角色关系 + var relations = await relationService.GetRelationListByTargetIdListAndCategory(roleIds.Select(it => it.ToString()).ToList(), + CateGoryConst.RELATION_SYS_USER_HAS_ROLE); + if (relations.Count > 0) + { + var userIds = relations.Select(it => it.ObjectId).ToList();//用户ID列表 + if (userIds.Count > 0) + { + // 解析用户服务 + var userService = scope.ServiceProvider.GetRequiredService(); + //从redis中删除 + userService.DeleteUserFromRedis(userIds); + } + } + } + + /// + /// 根据机构ID列表清除用户token + /// + /// + [EventSubscribe(EventSubscriberConst.CLEAR_ORG_TOKEN)] + public async Task DeleteUserTokenByOrgIds(EventHandlerExecutingContext context) + { + var orgIds = (List)context.Source.Payload;//获取机构ID + // 创建新的作用域 + using var scope = _services.CreateScope(); + // 获取用户ID列表 + var userIds = await DbContext.DB.QueryableWithAttr().Where(it => orgIds.Contains(it.OrgId)).Select(it => it.Id).ToListAsync(); + //从redis中删除所属机构的用户token + _simpleCacheService.HashDel>(CacheConst.CACHE_USER_TOKEN, userIds.Select(it => it.ToString()).ToArray()); + } + + /// + /// 根据模块ID列表清除用户token + /// + /// + [EventSubscribe(EventSubscriberConst.CLEAR_MODULE_TOKEN)] + public async Task DeleteUserTokenByModuleId(EventHandlerExecutingContext context) + { + var moduleId = (long)context.Source.Payload;//获取机构ID + // 创建新的作用域 + using var scope = _services.CreateScope(); + // 解析关系服务 + var relationService = scope.ServiceProvider.GetRequiredService(); + var roleModuleRelations = + await relationService.GetRelationListByTargetIdAndCategory(moduleId.ToString(), CateGoryConst.RELATION_SYS_ROLE_HAS_MODULE);//角色模块关系 + var userModuleRelations = + await relationService.GetRelationListByTargetIdAndCategory(moduleId.ToString(), CateGoryConst.RELATION_SYS_USER_HAS_MODULE);//用户模块关系 + var userIds = userModuleRelations.Select(it => it.ObjectId).ToList();//用户ID列表 + var roleIds = roleModuleRelations.Select(it => it.ObjectId).ToList();//角色ID列表 + var userRoleRelations = await relationService.GetRelationListByTargetIdListAndCategory(roleIds.Select(it => it.ToString()).ToList(), + CateGoryConst.RELATION_SYS_USER_HAS_ROLE);//用户角色关系 + userIds.AddRange(userRoleRelations.Select(it => it.ObjectId).ToList());//添加用户ID列表 + // 解析用户服务 + var userService = scope.ServiceProvider.GetRequiredService(); + if (userIds.Count > 0) + { + //从redis中删除用户信息 + userService.DeleteUserFromRedis(userIds); + //从redis中删除用户token + _simpleCacheService.HashDel>(CacheConst.CACHE_USER_TOKEN, userIds.Select(it => it.ToString()).ToArray()); + } + } +} diff --git a/SimpleAdmin.System/ExtJson/RelationMsgUser.cs b/SimpleAdmin.System/ExtJson/RelationMsgUser.cs new file mode 100644 index 0000000..c09f45f --- /dev/null +++ b/SimpleAdmin.System/ExtJson/RelationMsgUser.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 站内信与接收用户拓展 +/// MSG_TO_USER +/// +public class RelationMsgUser +{ + /// + /// 是否已读 + /// + public bool Read { get; set; } = false; +} diff --git a/SimpleAdmin.System/ExtJson/RelationRolePermission.cs b/SimpleAdmin.System/ExtJson/RelationRolePermission.cs new file mode 100644 index 0000000..993d93a --- /dev/null +++ b/SimpleAdmin.System/ExtJson/RelationRolePermission.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// SYS_ROLE_HAS_PERMISSION +/// 角色权限关系扩展 +/// +public class RelationRolePermission +{ + /// + /// 数据范围 + /// + public string ScopeCategory { get; set; } + + /// + /// 自定义机构范围列表 + /// + public List ScopeDefineOrgIdList { get; set; } = new List(); + + /// + /// 接口Url + /// + public string ApiUrl { get; set; } +} diff --git a/SimpleAdmin.System/ExtJson/RelationRoleResource.cs b/SimpleAdmin.System/ExtJson/RelationRoleResource.cs new file mode 100644 index 0000000..bd1899c --- /dev/null +++ b/SimpleAdmin.System/ExtJson/RelationRoleResource.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// SYS_ROLE_HAS_RESOURCE +/// 角色有哪些资源扩展 +/// +public class RelationRoleResource +{ + /// + /// 菜单ID + /// + public long MenuId { get; set; } + + /// + /// 按钮信息 + /// + public List ButtonInfo { get; set; } = new List(); +} diff --git a/SimpleAdmin.System/ExtJson/RelationUserSchedule.cs b/SimpleAdmin.System/ExtJson/RelationUserSchedule.cs new file mode 100644 index 0000000..d95de94 --- /dev/null +++ b/SimpleAdmin.System/ExtJson/RelationUserSchedule.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// SYS_USER_SCHEDULE_DATA +/// 用户日程扩展 +/// +public class RelationUserSchedule +{ + /// + /// 日程日期 + /// + public virtual string ScheduleDate { get; set; } + + /// + /// 日程时间 + /// + public virtual string ScheduleTime { get; set; } + + /// + /// 日程内容 + /// + public virtual string ScheduleContent { get; set; } + + /// + /// 用户id + /// + public long ScheduleUserId { get; set; } + + /// + /// 用户姓名 + /// + public string ScheduleUserName { get; set; } +} diff --git a/SimpleAdmin.System/ExtJson/RelationUserWorkBench.cs b/SimpleAdmin.System/ExtJson/RelationUserWorkBench.cs new file mode 100644 index 0000000..ef615c1 --- /dev/null +++ b/SimpleAdmin.System/ExtJson/RelationUserWorkBench.cs @@ -0,0 +1,49 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// SYS_USER_WORKBENCH_DATA +/// 用户工作台扩展 +/// +public class RelationUserWorkBench +{ + /// + /// 快捷方式列表 + /// + public List Shortcut { get; set; } +} + +/// +/// 工作台快捷方式信息 +/// +public class WorkBenchShortcut +{ + /// + /// id + /// + public long Id { get; set; } + + /// + /// 标题 + /// + public string Title { get; set; } + + /// + /// 图标 + /// + public string Icon { get; set; } + + /// + /// 路由地址 + /// + public string Path { get; set; } +} diff --git a/SimpleAdmin.System/GlobalUsings.cs b/SimpleAdmin.System/GlobalUsings.cs new file mode 100644 index 0000000..461f2fc --- /dev/null +++ b/SimpleAdmin.System/GlobalUsings.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +global using MoYu; +global using MoYu.DataEncryption; +global using MoYu.DependencyInjection; +global using MoYu.EventBus; +global using MoYu.FriendlyException; +global using MoYu.ViewEngine; +global using Magicodes.ExporterAndImporter.Core; +global using Magicodes.ExporterAndImporter.Core.Models; +global using Magicodes.ExporterAndImporter.Excel; +global using Mapster; +global using Masuit.Tools; +global using Microsoft.AspNetCore.Http; +global using Microsoft.AspNetCore.Mvc; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Logging; +global using NewLife.Serialization; +global using OfficeOpenXml.Table; +global using SimpleAdmin.Cache; +global using SimpleAdmin.Core; +global using SimpleAdmin.Core.Utils; +global using SimpleAdmin.SqlSugar; +global using SimpleTool; +global using SqlSugar; +global using System.ComponentModel.DataAnnotations; +global using System.Reflection; +global using System.Text; +global using System.Web; +global using SkiaSharp; +global using System.Runtime.InteropServices; +global using Microsoft.AspNetCore.Builder; +global using Microsoft.AspNetCore.Hosting; +global using Newtonsoft.Json.Linq; +global using NewLife; diff --git a/SimpleAdmin.System/Mapper.cs b/SimpleAdmin.System/Mapper.cs new file mode 100644 index 0000000..7f4c027 --- /dev/null +++ b/SimpleAdmin.System/Mapper.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 对象映射 +/// +public class Mapper : IRegister +{ + public void Register(TypeAdapterConfig config) + { + } +} diff --git a/SimpleAdmin.System/Options/SystemSettingsOptions.cs b/SimpleAdmin.System/Options/SystemSettingsOptions.cs new file mode 100644 index 0000000..2586f37 --- /dev/null +++ b/SimpleAdmin.System/Options/SystemSettingsOptions.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using MoYu.ConfigurableOptions; + +namespace SimpleAdmin.System; + +/// +/// 系统配置 +/// +public class SystemSettingsOptions : BaseOptions, IConfigurableOptions +{ + /// + /// 超级管理员可以看到全部数据 + /// + public bool SuperAdminViewAllData { get; set; } + + /// + /// 启用通知中心 + /// + public bool UseMessageCenter { get; set; } +} diff --git a/SimpleAdmin.System/Oss/MinioUtils.cs b/SimpleAdmin.System/Oss/MinioUtils.cs new file mode 100644 index 0000000..7560815 --- /dev/null +++ b/SimpleAdmin.System/Oss/MinioUtils.cs @@ -0,0 +1,128 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using Minio; +using Minio.Exceptions; + +namespace SimpleAdmin.System; + +/// +/// Minio功能类 +/// +public class MinioUtils : ITransient +{ + public MinioClient MinioClient; + private string _defaultBucketName; + private string _defaultEndPoint; + private string _defaultPrefix = "http://"; + private readonly IConfigService _configService; + + public MinioUtils(IConfigService configService) + { + _configService = configService; + InitClient(); + } + + /// + /// 初始化操作 + /// + /// + private async void InitClient() + { + var configs = await _configService.GetConfigsByCategory(CateGoryConst.CONFIG_FILE_MINIO);//获取minio配置 + var accessKey = configs.Where(it => it.ConfigKey == SysConfigConst.FILE_MINIO_ACCESS_KEY).FirstOrDefault();//MINIO文件AccessKey + var secretKey = configs.Where(it => it.ConfigKey == SysConfigConst.FILE_MINIO_SECRET_KEY).FirstOrDefault();//MINIO文件SecretKey + var endPoint = configs.Where(it => it.ConfigKey == SysConfigConst.FILE_MINIO_END_POINT).FirstOrDefault();//MINIO文件EndPoint + var bucketName = configs.Where(it => it.ConfigKey == SysConfigConst.FILE_MINIO_DEFAULT_BUCKET_NAME).FirstOrDefault();//MINIO文件默认存储桶 + if (accessKey == null || secretKey == null || endPoint == null || bucketName == null) + { + throw Oops.Oh("MINIO客户端未正确配置"); + } + try + { + //默认值赋值 + _defaultBucketName = bucketName.ConfigValue; + _defaultEndPoint = endPoint.ConfigValue; + if (_defaultEndPoint.ToLower().StartsWith("http")) + { + var point = _defaultEndPoint.Split("//").ToList();//分割、 + _defaultPrefix = $"{point[0]}//"; + _defaultEndPoint = point[1]; + } + MinioClient = new MinioClient().WithEndpoint(_defaultEndPoint).WithCredentials(accessKey.ConfigValue, secretKey.ConfigValue) + .Build();//初始化minio对象 + MinioClient.WithTimeout(5000);//超时时间 + } + catch (Exception ex) + { + throw Oops.Oh("MINIO客户端启动失败", ex); + } + } + + /// + /// 上传文件 - 返回Minio文件完整Url + /// + /// 存储桶里的对象名称,例:/mnt/photos/island.jpg + /// 文件 + /// 文件的Content type,默认是"application/octet-stream" + /// + public async Task PutObjectAsync(string objectName, IFormFile file, string contentType = "application/octet-stream") + { + try + { + using var fileStream = file.OpenReadStream();//获取文件流 + var putObjectArgs = new PutObjectArgs().WithBucket(_defaultBucketName).WithObject(objectName).WithStreamData(fileStream) + .WithObjectSize(file.Length).WithContentType(contentType); + await MinioClient.PutObjectAsync(putObjectArgs); + return $"{_defaultPrefix}{_defaultEndPoint}/{_defaultBucketName}/{objectName}";//默认http + } + catch (MinioException e) + { + throw Oops.Oh("上传文件失败!", e); + } + catch (Exception e) + { + throw Oops.Oh("上传文件失败!", e); + } + } + + /// + /// 下载文件 + /// + /// + /// + public async Task DownloadFileAsync(string objectName) + { + var stream = new MemoryStream(); + try + { + var getObjectArgs = new GetObjectArgs().WithBucket(_defaultBucketName).WithObject(objectName).WithCallbackStream(cb => + { + cb.CopyTo(stream); + }); + await MinioClient.GetObjectAsync(getObjectArgs); + + //UserCenter.InvalidOperationException: Response Content-Length mismatch: too few bytes written (0 of 30788) + if (stream.CanSeek) + { + stream.Seek(0, SeekOrigin.Begin); + } + return stream; + } + catch (MinioException e) + { + throw Oops.Oh("下载文件失败!", e); + } + catch (Exception e) + { + throw Oops.Oh("下载文件失败!", e); + } + } +} diff --git a/SimpleAdmin.System/SeedData/GenBaseSeedData.cs b/SimpleAdmin.System/SeedData/GenBaseSeedData.cs new file mode 100644 index 0000000..2640dc8 --- /dev/null +++ b/SimpleAdmin.System/SeedData/GenBaseSeedData.cs @@ -0,0 +1,12 @@ +namespace SimpleAdmin.System; + +/// +/// 系统配置种子数据 +/// +public class GenBaseSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_gen_basic.json"); + } +} diff --git a/SimpleAdmin.System/SeedData/GenConfigSeedData.cs b/SimpleAdmin.System/SeedData/GenConfigSeedData.cs new file mode 100644 index 0000000..2ea60f1 --- /dev/null +++ b/SimpleAdmin.System/SeedData/GenConfigSeedData.cs @@ -0,0 +1,12 @@ +namespace SimpleAdmin.System; + +/// +/// 系统配置种子数据 +/// +public class GenConfigSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_gen_config.json"); + } +} diff --git a/SimpleAdmin.System/SeedData/Json/seed_sys_config.json b/SimpleAdmin.System/SeedData/Json/seed_sys_config.json new file mode 100644 index 0000000..28448e0 --- /dev/null +++ b/SimpleAdmin.System/SeedData/Json/seed_sys_config.json @@ -0,0 +1,616 @@ +{ + "RECORDS": [ + { + "Id": "252875233003720", + "ConfigKey": "SYS_FOOTER_LINKS", + "ConfigValue": "[{\"name\":\"苏ICP备2023040827号\",\"url\":\"https://beian.miit.gov.cn/\",\"sortCode\":1}]", + "Category": "SYS_BASE", + "Remark": "底部超链接", + "SortCode": "1", + "CreateTime": "2024-1-24 10:32:12.58", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875262003737", + "ConfigKey": "SYS_TENANT_OPTIONS", + "ConfigValue": "CHOSE", + "Category": "SYS_BASE", + "Remark": "多租户配置", + "SortCode": "1", + "CreateTime": "2024-1-24 10:32:12.587", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263002722", + "ConfigKey": "SYS_ICO", + "ConfigValue": "data:image/x-icon;base64,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", + "Category": "SYS_BASE", + "Remark": "系统ICO文件", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263002737", + "ConfigKey": "SYS_WEB_STATUS", + "ConfigValue": "ENABLE", + "Category": "SYS_BASE", + "Remark": "网站开启访问", + "SortCode": "1", + "CreateTime": "2024-1-24 10:32:12.587", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263003710", + "ConfigKey": "SYS_WEB_CLOSE_PROMPT", + "ConfigValue": "网站维护中,暂时无法访问!本网站正在进行系统维护和技术升级,网站暂时无法访问,敬请谅解!", + "Category": "SYS_BASE", + "Remark": "网站关闭提示", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263003720", + "ConfigKey": "SYS_DEFAULT_WORKBENCH_DATA", + "ConfigValue": "{\"shortcut\":[212725263003723,212725263003722]}", + "Category": "SYS_BASE", + "Remark": "系统默认工作台数据", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263003721", + "ConfigKey": "SYS_LOGO", + "ConfigValue": "data:image/png;base64,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Y2nSZn5+IU8//VTaNKnTy9KxpQyHw24UPtWtHcsh3XG0SerROHMLC7n9zG1ZPrHc3bqwvd1tC1ct5b7mngznBrlj6UyuXr2a48eXUk/HpgeDQa5cuZxe3UubpN8f7E/1PrrM/ks5XdPF2fZGEFavX09d1zl1+mS3lkDTpKra1L1eLl26lPFk1O1/Pn1JdV1nMBhkMBjMprT/kc7V9P3r9wdZmF/I1tZW2rQZVHWur17JIw9/8O0/+Ia//vzG5na6xQCrVN1iDB/9IzwrAP+dqm5t6xgAAADgvyVT3AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAAIdAAAACiDQAQAAoAACHQAAAAog0AEAAKAAAh0AAAAKINABAACgAP8/yC9dvn6AMp8AAAAASUVORK5CYII=", + "Category": "SYS_BASE", + "Remark": "系统LOGO", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263003722", + "ConfigKey": "SYS_NAME", + "ConfigValue": "SimpleAdmin", + "Category": "SYS_BASE", + "Remark": "系统名称", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263003723", + "ConfigKey": "SYS_VERSION", + "ConfigValue": "V3.0.0", + "Category": "SYS_BASE", + "Remark": "系统版本", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263003724", + "ConfigKey": "SYS_COPYRIGHT", + "ConfigValue": "SimpleAdmin ©2022 Created by 少林寺驻北固山办事处大神父王喇嘛", + "Category": "SYS_BASE", + "Remark": "系统版权", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263003725", + "ConfigKey": "SYS_COPYRIGHT_URL", + "ConfigValue": "https://gitee.com/dotnetmoyu/SimpleAdmin", + "Category": "SYS_BASE", + "Remark": "系统版权链接地址", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263003726", + "ConfigKey": "LOGIN_CAPTCHA_OPEN", + "ConfigValue": "true", + "Category": "LOGIN_POLICY", + "Remark": "登录验证码开关", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2025-6-24 10:10:19.457", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263003727", + "ConfigKey": "SYS_DEFAULT_FILE_ENGINE", + "ConfigValue": "LOCAL", + "Category": "SYS_BASE", + "Remark": "默认文件存储引擎", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "252875263003728", + "ConfigKey": "PWD_DEFAULT_PASSWORD", + "ConfigValue": "123456", + "Category": "PWD_POLICY", + "Remark": "默认用户密码", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "364564896825413", + "ConfigKey": "LOGIN_SINGLE_OPEN", + "ConfigValue": "false", + "Category": "LOGIN_POLICY", + "Remark": "单用户登录开关", + "SortCode": "1", + "CreateTime": "2022-12-16 13:58:23.783", + "UpdateTime": "2025-6-24 10:10:19.467", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "364564896825414", + "ConfigKey": "MQTT_PARAM_URL", + "ConfigValue": "ws://127.0.0.1:8083/mqtt", + "Category": "MQTT_BASE", + "Remark": "MQTT服务端地址", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-11-7 14:39:38.423", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "364564896825415", + "ConfigKey": "MQTT_PARAM_USERNAME", + "ConfigValue": "admin", + "Category": "MQTT_BASE", + "Remark": "MQTT用户名", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-11-7 14:39:38.42", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "364564896825416", + "ConfigKey": "MQTT_PARAM_PASSWORD", + "ConfigValue": "admin", + "Category": "MQTT_BASE", + "Remark": "MQTT密码", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-11-7 14:39:38.42", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "364564896825417", + "ConfigKey": "FILE_LOCAL_FOLDER_FOR_WINDOWS", + "ConfigValue": "C:/defaultUploadFolder", + "Category": "FILE_LOCAL", + "Remark": "本地文件Windows存储位置", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "364564896825418", + "ConfigKey": "FILE_LOCAL_FOLDER_FOR_UNIX", + "ConfigValue": "/defaultUploadFolder", + "Category": "FILE_LOCAL", + "Remark": "本地文件Linux存储位置", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "364564896825419", + "ConfigKey": "FILE_MINIO_ACCESS_KEY", + "ConfigValue": "MINIO文件AccessKey", + "Category": "FILE_MINIO", + "Remark": "MINIO文件AccessKey", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "364564896825420", + "ConfigKey": "FILE_MINIO_SECRET_KEY", + "ConfigValue": "MINIO文件SecetKey", + "Category": "FILE_MINIO", + "Remark": "MINIO文件SecetKey", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "364564896825421", + "ConfigKey": "FILE_MINIO_END_POINT", + "ConfigValue": "MINIO文件EndPoint", + "Category": "FILE_MINIO", + "Remark": "MINIO文件EndPoint", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "364564896825422", + "ConfigKey": "FILE_MINIO_DEFAULT_BUCKET_NAME", + "ConfigValue": "defaultbucket", + "Category": "FILE_MINIO", + "Remark": "MINIO文件默认存储桶", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432079395405893", + "ConfigKey": "LOGIN_CAPTCHA_TYPE", + "ConfigValue": "ARITH", + "Category": "LOGIN_POLICY", + "Remark": "验证码类型", + "SortCode": "99", + "CreateTime": "2023-6-25 08:35:35.663", + "UpdateTime": "2025-6-24 10:10:19.467", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432079540875333", + "ConfigKey": "LOGIN_ERROR_COUNT", + "ConfigValue": "6", + "Category": "LOGIN_POLICY", + "Remark": "登录错误次数", + "SortCode": "99", + "CreateTime": "2023-6-25 08:36:11.18", + "UpdateTime": "2025-6-24 10:10:19.467", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432079718375493", + "ConfigKey": "LOGIN_ERROR_RESET_TIME", + "ConfigValue": "5", + "Category": "LOGIN_POLICY", + "Remark": "错误重置时间", + "SortCode": "99", + "CreateTime": "2023-6-25 08:36:54.513", + "UpdateTime": "2025-6-24 10:10:19.467", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432079850803269", + "ConfigKey": "LOGIN_ERROR_LOCK", + "ConfigValue": "30", + "Category": "LOGIN_POLICY", + "Remark": "登录错误锁定时长", + "SortCode": "99", + "CreateTime": "2023-6-25 08:37:26.847", + "UpdateTime": "2025-6-24 10:10:19.467", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432110816800837", + "ConfigKey": "PWD_REMIND", + "ConfigValue": "false", + "Category": "PWD_POLICY", + "Remark": "密码定期提醒更新", + "SortCode": "99", + "CreateTime": "2023-6-25 10:43:26.903", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432110956560453", + "ConfigKey": "PWD_REMIND_DAY", + "ConfigValue": "1", + "Category": "PWD_POLICY", + "Remark": "密码定期提醒更新时间", + "SortCode": "99", + "CreateTime": "2023-6-25 10:44:01.023", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432111166894149", + "ConfigKey": "PWD_UPDATE_DEFAULT", + "ConfigValue": "true", + "Category": "PWD_POLICY", + "Remark": "修改初始密码提醒", + "SortCode": "99", + "CreateTime": "2023-6-25 10:44:52.377", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432111701160005", + "ConfigKey": "PWD_MIN_LENGTH", + "ConfigValue": "6", + "Category": "PWD_POLICY", + "Remark": "密码最小长度", + "SortCode": "99", + "CreateTime": "2023-6-25 10:47:02.81", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432112135159877", + "ConfigKey": "PWD_CONTAIN_NUM", + "ConfigValue": "false", + "Category": "PWD_POLICY", + "Remark": "包含数字", + "SortCode": "99", + "CreateTime": "2023-6-25 10:48:48.77", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432112321953861", + "ConfigKey": "PWD_CONTAIN_LOWER", + "ConfigValue": "false", + "Category": "PWD_POLICY", + "Remark": "包含小写字母", + "SortCode": "99", + "CreateTime": "2023-6-25 10:49:34.373", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432112380907589", + "ConfigKey": "PWD_CONTAIN_UPPER", + "ConfigValue": "false", + "Category": "PWD_POLICY", + "Remark": "包含大写字母", + "SortCode": "99", + "CreateTime": "2023-6-25 10:49:48.767", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + }, + { + "Id": "432112495247429", + "ConfigKey": "PWD_CONTAIN_CHARACTER", + "ConfigValue": "false", + "Category": "PWD_POLICY", + "Remark": "包含特殊字符", + "SortCode": "99", + "CreateTime": "2023-6-25 10:50:16.68", + "UpdateTime": "2024-7-23 09:09:40.207", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "" + } + ] +} \ No newline at end of file diff --git a/SimpleAdmin.System/SeedData/Json/seed_sys_dict.json b/SimpleAdmin.System/SeedData/Json/seed_sys_dict.json new file mode 100644 index 0000000..b96d4a1 --- /dev/null +++ b/SimpleAdmin.System/SeedData/Json/seed_sys_dict.json @@ -0,0 +1,1449 @@ +{ + "RECORDS": [ + { + "Id": "252875263003701", + "ParentId": "0", + "DictLabel": "用户性别类型", + "DictValue": "GENDER", + "Category": "FRM", + "SortCode": "1", + "CreateTime": "", + "UpdateTime": "2025-4-10 15:58:41.71", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003702", + "ParentId": "252875263003701", + "DictLabel": "男", + "DictValue": "男", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003703", + "ParentId": "252875263003701", + "DictLabel": "女", + "DictValue": "女", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003704", + "ParentId": "0", + "DictLabel": "系统菜单类型", + "DictValue": "MENU_TYPE", + "Category": "FRM", + "SortCode": "2", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003705", + "ParentId": "252875263003704", + "DictLabel": "目录", + "DictValue": "CATALOG", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003706", + "ParentId": "252875263003704", + "DictLabel": "菜单", + "DictValue": "MENU", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003707", + "ParentId": "252875263003704", + "DictLabel": "子页", + "DictValue": "SUBSET", + "Category": "FRM", + "SortCode": "30", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003708", + "ParentId": "252875263003704", + "DictLabel": "外链", + "DictValue": "LINK", + "Category": "FRM", + "SortCode": "40", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003711", + "ParentId": "0", + "DictLabel": "系统通用状态", + "DictValue": "COMMON_STATUS", + "Category": "FRM", + "SortCode": "3", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003712", + "ParentId": "252875263003711", + "DictLabel": "启用", + "DictValue": "ENABLE", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003713", + "ParentId": "252875263003711", + "DictLabel": "停用", + "DictValue": "DISABLED", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003714", + "ParentId": "0", + "DictLabel": "系统角色分类", + "DictValue": "ROLE_CATEGORY", + "Category": "FRM", + "SortCode": "4", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003715", + "ParentId": "252875263003714", + "DictLabel": "全局", + "DictValue": "GLOBAL", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003716", + "ParentId": "252875263003714", + "DictLabel": "机构", + "DictValue": "ORG", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003717", + "ParentId": "0", + "DictLabel": "系统机构分类", + "DictValue": "ORG_CATEGORY", + "Category": "FRM", + "SortCode": "5", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003718", + "ParentId": "252875263003717", + "DictLabel": "部门", + "DictValue": "DEPT", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003719", + "ParentId": "252875263003717", + "DictLabel": "公司", + "DictValue": "COMPANY", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003720", + "ParentId": "0", + "DictLabel": "系统职位分类", + "DictValue": "POSITION_CATEGORY", + "Category": "FRM", + "SortCode": "6", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003721", + "ParentId": "252875263003720", + "DictLabel": "高层", + "DictValue": "HIGH", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003722", + "ParentId": "252875263003720", + "DictLabel": "中层", + "DictValue": "MIDDLE", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003723", + "ParentId": "252875263003720", + "DictLabel": "基层", + "DictValue": "LOW", + "Category": "FRM", + "SortCode": "30", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003724", + "ParentId": "0", + "DictLabel": "用户民族类型", + "DictValue": "NATION", + "Category": "FRM", + "SortCode": "7", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003725", + "ParentId": "252875263003724", + "DictLabel": "汉族", + "DictValue": "汉族", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003726", + "ParentId": "252875263003724", + "DictLabel": "壮族", + "DictValue": "壮族", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003727", + "ParentId": "252875263003724", + "DictLabel": "回族", + "DictValue": "回族", + "Category": "FRM", + "SortCode": "30", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003728", + "ParentId": "252875263003724", + "DictLabel": "满族", + "DictValue": "满族", + "Category": "FRM", + "SortCode": "40", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003730", + "ParentId": "0", + "DictLabel": "登录设备类型", + "DictValue": "AUTH_DEVICE_TYPE", + "Category": "FRM", + "SortCode": "8", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003731", + "ParentId": "252875263003730", + "DictLabel": "PC端", + "DictValue": "PC", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003732", + "ParentId": "252875263003730", + "DictLabel": "移动端", + "DictValue": "APP", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003733", + "ParentId": "252875263003730", + "DictLabel": "小程序", + "DictValue": "MINI", + "Category": "FRM", + "SortCode": "30", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003734", + "ParentId": "0", + "DictLabel": "系统字典分类", + "DictValue": "DICT_CATEGORY", + "Category": "FRM", + "SortCode": "9", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003735", + "ParentId": "252875263003734", + "DictLabel": "系统", + "DictValue": "FRM", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003736", + "ParentId": "252875263003734", + "DictLabel": "业务", + "DictValue": "BIZ", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003737", + "ParentId": "0", + "DictLabel": "文件上传引擎", + "DictValue": "FILE_ENGINE", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003738", + "ParentId": "252875263003737", + "DictLabel": "本地", + "DictValue": "LOCAL", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003739", + "ParentId": "252875263003737", + "DictLabel": "MINIO", + "DictValue": "MINIO", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003741", + "ParentId": "0", + "DictLabel": "系统通用开关", + "DictValue": "COMMON_SWITCH", + "Category": "FRM", + "SortCode": "11", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003742", + "ParentId": "252875263003741", + "DictLabel": "开", + "DictValue": "true", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003743", + "ParentId": "252875263003741", + "DictLabel": "关", + "DictValue": "false", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003744", + "ParentId": "0", + "DictLabel": "用户证件类型", + "DictValue": "IDCARD_TYPE", + "Category": "FRM", + "SortCode": "12", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003745", + "ParentId": "252875263003744", + "DictLabel": "身份证", + "DictValue": "身份证", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003746", + "ParentId": "252875263003744", + "DictLabel": "出生证", + "DictValue": "出生证", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003747", + "ParentId": "252875263003744", + "DictLabel": "军官证", + "DictValue": "军官证", + "Category": "FRM", + "SortCode": "30", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003748", + "ParentId": "252875263003744", + "DictLabel": "护照", + "DictValue": "护照", + "Category": "FRM", + "SortCode": "40", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003749", + "ParentId": "0", + "DictLabel": "通用文化程度", + "DictValue": "CULTURE_LEVEL", + "Category": "FRM", + "SortCode": "13", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003750", + "ParentId": "252875263003749", + "DictLabel": "小学", + "DictValue": "小学", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003751", + "ParentId": "252875263003749", + "DictLabel": "中学", + "DictValue": "中学", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003752", + "ParentId": "252875263003749", + "DictLabel": "高中", + "DictValue": "高中", + "Category": "FRM", + "SortCode": "30", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003753", + "ParentId": "252875263003749", + "DictLabel": "中专", + "DictValue": "中专", + "Category": "FRM", + "SortCode": "40", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003754", + "ParentId": "252875263003749", + "DictLabel": "大专", + "DictValue": "大专", + "Category": "FRM", + "SortCode": "50", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003755", + "ParentId": "252875263003749", + "DictLabel": "本科", + "DictValue": "本科", + "Category": "FRM", + "SortCode": "60", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003756", + "ParentId": "252875263003749", + "DictLabel": "硕士研究生", + "DictValue": "硕士研究生", + "Category": "FRM", + "SortCode": "70", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003757", + "ParentId": "252875263003749", + "DictLabel": "博士研究生", + "DictValue": "博士研究生", + "Category": "FRM", + "SortCode": "80", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003758", + "ParentId": "0", + "DictLabel": "定时任务分类", + "DictValue": "JOB_CATEGORY", + "Category": "FRM", + "SortCode": "14", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003759", + "ParentId": "252875263003758", + "DictLabel": "框架", + "DictValue": "FRM", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003760", + "ParentId": "252875263003758", + "DictLabel": "业务", + "DictValue": "BIZ", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003764", + "ParentId": "0", + "DictLabel": "系统消息类型", + "DictValue": "MESSAGE_CATEGORY", + "Category": "FRM", + "SortCode": "14", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003765", + "ParentId": "252875263003764", + "DictLabel": "通知", + "DictValue": "INFORM", + "Category": "FRM", + "SortCode": "10", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "252875263003766", + "ParentId": "252875263003764", + "DictLabel": "公告", + "DictValue": "NOTICE", + "Category": "FRM", + "SortCode": "20", + "CreateTime": "", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "367777942233157", + "ParentId": "0", + "DictLabel": "用户在线状态", + "DictValue": "ONLINE_STATUS", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2022-12-25 15:52:18.697", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "367778072543301", + "ParentId": "367777942233157", + "DictLabel": "在线", + "DictValue": "ONLINE", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2022-12-25 15:52:50.513", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "367778141515845", + "ParentId": "367777942233157", + "DictLabel": "离线", + "DictValue": "OFFLINE", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2022-12-25 15:53:07.35", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "382969159073861", + "ParentId": "0", + "DictLabel": "是否", + "DictValue": "YES_NO", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2023-2-6 14:05:31.87", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "382969320693829", + "ParentId": "382969159073861", + "DictLabel": "是", + "DictValue": "true", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2023-2-6 14:06:11.33", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "382969486618693", + "ParentId": "382969159073861", + "DictLabel": "否", + "DictValue": "false", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2023-2-6 14:06:51.84", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "507475491864645", + "ParentId": "0", + "DictLabel": "多租户选项", + "DictValue": "TENANT_OPTIONS", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-1-24 09:43:05.773", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "507482950717509", + "ParentId": "507475491864645", + "DictLabel": "关闭", + "DictValue": "CLOSE", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-1-24 10:13:26.787", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "507483171848261", + "ParentId": "507475491864645", + "DictLabel": "手动选择", + "DictValue": "CHOSE", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-1-24 10:14:20.77", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "507483274203205", + "ParentId": "507475491864645", + "DictLabel": "根据域名", + "DictValue": "DOMAIN", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-1-24 10:14:45.763", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "510326350884933", + "ParentId": "0", + "DictLabel": "登录验证码类型", + "DictValue": "CAPTCHA_TYPE", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-2-1 11:03:16.28", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "510326446264389", + "ParentId": "510326350884933", + "DictLabel": "纯数字验证码", + "DictValue": "NUM", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-2-1 11:03:39.567", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "510326482235461", + "ParentId": "510326350884933", + "DictLabel": "数字加字母验证码", + "DictValue": "CHAR", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-2-1 11:03:48.347", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "510326508625989", + "ParentId": "510326350884933", + "DictLabel": "数字运算验证码", + "DictValue": "ARITH", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-2-1 11:03:54.79", + "UpdateTime": "2024-7-23 09:09:40.697", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "610820365340741", + "ParentId": "252875263003764", + "DictLabel": "消息", + "DictValue": "MESSAGE", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-11 10:14:27.777", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "610871373713477", + "ParentId": "0", + "DictLabel": "系统消息接受者类型", + "DictValue": "RECEIVER_TYPE", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-11 13:42:00.993", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "610871459205189", + "ParentId": "610871373713477", + "DictLabel": "所有人", + "DictValue": "ALL", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-11 13:42:21.863", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "610871525576773", + "ParentId": "610871373713477", + "DictLabel": "指定角色", + "DictValue": "ROLE", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-11 13:42:38.07", + "UpdateTime": "2024-11-11 15:58:34.453", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "610871552700485", + "ParentId": "610871373713477", + "DictLabel": "指定用户", + "DictValue": "APPOINT", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-11 13:42:44.69", + "UpdateTime": "2024-11-11 15:58:39.39", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "611939803328581", + "ParentId": "0", + "DictLabel": "系统消息发送方式", + "DictValue": "MESSAGE_WAY", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-14 14:09:28.067", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "611940036890693", + "ParentId": "611939803328581", + "DictLabel": "立即发送", + "DictValue": "NOW", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-14 14:10:25.087", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "611940097024069", + "ParentId": "611939803328581", + "DictLabel": "延迟发送", + "DictValue": "DELAY", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-14 14:10:39.77", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "611940248596549", + "ParentId": "611939803328581", + "DictLabel": "指定时间", + "DictValue": "SCHEDULE", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-14 14:11:16.777", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "611940407885893", + "ParentId": "0", + "DictLabel": "消息发送状态", + "DictValue": "MESSAGE_STATUS", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-14 14:11:55.663", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "611940509208645", + "ParentId": "611940407885893", + "DictLabel": "待发送", + "DictValue": "READY", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-14 14:12:20.4", + "UpdateTime": "2024-11-15 10:06:49.79", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "611940679856197", + "ParentId": "611940407885893", + "DictLabel": "已发送", + "DictValue": "ALREADY", + "Category": "FRM", + "SortCode": "99", + "CreateTime": "2024-11-14 14:13:02.063", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + } + ] +} \ No newline at end of file diff --git a/SimpleAdmin.System/SeedData/Json/seed_sys_org.json b/SimpleAdmin.System/SeedData/Json/seed_sys_org.json new file mode 100644 index 0000000..eb1850f --- /dev/null +++ b/SimpleAdmin.System/SeedData/Json/seed_sys_org.json @@ -0,0 +1,764 @@ +{ + "RECORDS": [ + { + "Id": "252885263003720", + "ParentId": "0", + "DirectorId": "212725263002001", + "Name": "果冻科技有限公司", + "Names": "果冻科技有限公司", + "Code": "4fuFapeKGy", + "Category": "COMPANY", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.15", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[]" + }, + { + "Id": "252885263003721", + "ParentId": "252885263003720", + "DirectorId": "", + "Name": "科技部", + "Names": "果冻科技有限公司/科技部", + "Code": "5JOEG44G62", + "Category": "DEPT", + "SortCode": "2", + "CreateTime": "2023-8-14 16:19:29.15", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[252885263003720]" + }, + { + "Id": "252885263003722", + "ParentId": "252885263003720", + "DirectorId": "359177888051269", + "Name": "生产部", + "Names": "果冻科技有限公司/生产部", + "Code": "aln9y4tno6", + "Category": "DEPT", + "SortCode": "3", + "CreateTime": "2023-8-14 16:19:29.15", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[252885263003720]" + }, + { + "Id": "359569393872965", + "ParentId": "0", + "DirectorId": "", + "Name": "萝卜科技有限公司", + "Names": "萝卜科技有限公司", + "Code": "l77v30V3yG", + "Category": "COMPANY", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.153", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[]" + }, + { + "Id": "360642028625989", + "ParentId": "252885263003720", + "DirectorId": "", + "Name": "销售部", + "Names": "果冻科技有限公司/销售部", + "Code": "dihhtLuWG1", + "Category": "DEPT", + "SortCode": "4", + "CreateTime": "2023-8-14 16:19:29.153", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[252885263003720]" + }, + { + "Id": "361404296994885", + "ParentId": "359569393872965", + "DirectorId": "", + "Name": "研发部", + "Names": "萝卜科技有限公司/研发部", + "Code": "fLOhh7s091", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2023-8-14 16:19:29.153", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[359569393872965]" + }, + { + "Id": "361404346445893", + "ParentId": "359569393872965", + "DirectorId": "", + "Name": "财务部", + "Names": "萝卜科技有限公司/财务部", + "Code": "tmDWFRfXuQ", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2023-8-14 16:19:29.153", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[359569393872965]" + }, + { + "Id": "464837351616581", + "ParentId": "252885263003721", + "DirectorId": "", + "Name": "科技一部", + "Names": "果冻科技有限公司/科技部/科技一部", + "Code": "Mzv2sj1MEo", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2023-9-25 22:08:03.567", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[252885263003720,252885263003721]" + }, + { + "Id": "464837557956677", + "ParentId": "464837351616581", + "DirectorId": "", + "Name": "科技一部1组", + "Names": "果冻科技有限公司/科技部/科技一部/科技一部1组", + "Code": "g6R7zuMMk4", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2023-9-25 22:08:53.943", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[252885263003720,252885263003721,464837351616581]" + }, + { + "Id": "479974472933445", + "ParentId": "359569393872965", + "DirectorId": "", + "Name": "销售部", + "Names": "萝卜科技有限公司/销售部", + "Code": "jjQ1i8btel", + "Category": "DEPT", + "SortCode": "4", + "CreateTime": "2023-11-7 16:41:09.83", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[359569393872965]" + }, + { + "Id": "485978445475909", + "ParentId": "252885263003722", + "DirectorId": "", + "Name": "生产一部", + "Names": "果冻科技有限公司/生产部/生产一部", + "Code": "fHsgj48J0D", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2023-11-24 15:51:23.437", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[252885263003720,252885263003722]" + }, + { + "Id": "487320043610181", + "ParentId": "359569393872965", + "DirectorId": "", + "Name": "科技部", + "Names": "萝卜科技有限公司/科技部", + "Code": "1QWox5893Q", + "Category": "DEPT", + "SortCode": "2", + "CreateTime": "2023-11-28 10:50:49.177", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[359569393872965]" + }, + { + "Id": "487320070803525", + "ParentId": "487320043610181", + "DirectorId": "", + "Name": "科技一部", + "Names": "萝卜科技有限公司/科技部/科技一部", + "Code": "fIaBZ15osx", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2023-11-28 10:50:49.18", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[359569393872965,487320043610181]" + }, + { + "Id": "510752889880645", + "ParentId": "0", + "DirectorId": "", + "Name": "旺仔科技有限公司", + "Names": "旺仔科技有限公司", + "Code": "wz", + "Category": "COMPANY", + "SortCode": "99", + "CreateTime": "2024-2-2 15:58:51.777", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[]" + }, + { + "Id": "510753093025861", + "ParentId": "0", + "DirectorId": "", + "Name": "达达科技有限公司", + "Names": "达达科技有限公司", + "Code": "dd", + "Category": "COMPANY", + "SortCode": "99", + "CreateTime": "2024-2-2 15:59:41.373", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[]" + }, + { + "Id": "510753219502149", + "ParentId": "0", + "DirectorId": "", + "Name": "杰尼科技有限公司", + "Names": "杰尼科技有限公司", + "Code": "jn", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-2 16:00:12.25", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[]" + }, + { + "Id": "510753479417925", + "ParentId": "510752889880645", + "DirectorId": "", + "Name": "科技部", + "Names": "旺仔科技有限公司/科技部", + "Code": "oNSxenwpqn", + "Category": "DEPT", + "SortCode": "2", + "CreateTime": "2024-2-2 16:01:15.713", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510752889880645]" + }, + { + "Id": "510753479422021", + "ParentId": "510753479417925", + "DirectorId": "", + "Name": "科技一部", + "Names": "旺仔科技有限公司/科技部/科技一部", + "Code": "j83kVrfVD0", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-2 16:01:15.713", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510752889880645,510753479417925]" + }, + { + "Id": "510753479422022", + "ParentId": "510753479422021", + "DirectorId": "", + "Name": "科技一部1组", + "Names": "旺仔科技有限公司/科技部/科技一部/科技一部1组", + "Code": "93BGNo5HXE", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-2 16:01:15.713", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510752889880645,510753479417925,510753479422021]" + }, + { + "Id": "510753479422023", + "ParentId": "510752889880645", + "DirectorId": "359177888051269", + "Name": "生产部", + "Names": "旺仔科技有限公司/生产部", + "Code": "2l3276Q5Tg", + "Category": "DEPT", + "SortCode": "3", + "CreateTime": "2024-2-2 16:01:15.713", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510752889880645]" + }, + { + "Id": "510753479426117", + "ParentId": "510753479422023", + "DirectorId": "", + "Name": "生产一部", + "Names": "旺仔科技有限公司/生产部/生产一部", + "Code": "298gdc2Oy6", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-2 16:01:15.713", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510752889880645,510753479422023]" + }, + { + "Id": "510753479430213", + "ParentId": "510752889880645", + "DirectorId": "", + "Name": "销售部", + "Names": "旺仔科技有限公司/销售部", + "Code": "qEB7a8wtP3", + "Category": "DEPT", + "SortCode": "4", + "CreateTime": "2024-2-2 16:01:15.713", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510752889880645]" + }, + { + "Id": "510753515745349", + "ParentId": "510753093025861", + "DirectorId": "", + "Name": "科技部", + "Names": "达达科技有限公司/科技部", + "Code": "LMB0GjrOM8", + "Category": "DEPT", + "SortCode": "2", + "CreateTime": "2024-2-2 16:01:24.577", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753093025861]" + }, + { + "Id": "510753515745350", + "ParentId": "510753515745349", + "DirectorId": "", + "Name": "科技一部", + "Names": "达达科技有限公司/科技部/科技一部", + "Code": "mgd2SJ35jH", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-2 16:01:24.577", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753093025861,510753515745349]" + }, + { + "Id": "510753515745351", + "ParentId": "510753515745350", + "DirectorId": "", + "Name": "科技一部1组", + "Names": "达达科技有限公司/科技部/科技一部/科技一部1组", + "Code": "jQ5ymWaxz1", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-2 16:01:24.577", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753093025861,510753515745349,510753515745350]" + }, + { + "Id": "510753515749445", + "ParentId": "510753093025861", + "DirectorId": "359177888051269", + "Name": "生产部", + "Names": "达达科技有限公司/生产部", + "Code": "nNmBAfO2dG", + "Category": "DEPT", + "SortCode": "3", + "CreateTime": "2024-2-2 16:01:24.577", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753093025861]" + }, + { + "Id": "510753515749446", + "ParentId": "510753515749445", + "DirectorId": "", + "Name": "生产一部", + "Names": "达达科技有限公司/生产部/生产一部", + "Code": "D37d9K1QMn", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-2 16:01:24.577", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753093025861,510753515749445]" + }, + { + "Id": "510753515749447", + "ParentId": "510753093025861", + "DirectorId": "", + "Name": "销售部", + "Names": "达达科技有限公司/销售部", + "Code": "Jt6ZJfT4g2", + "Category": "DEPT", + "SortCode": "4", + "CreateTime": "2024-2-2 16:01:24.577", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753093025861]" + }, + { + "Id": "510753541705799", + "ParentId": "510753219502149", + "DirectorId": "359177888051269", + "Name": "生产部", + "Names": "杰尼科技有限公司/生产部", + "Code": "LuOvsCpXL9", + "Category": "DEPT", + "SortCode": "3", + "CreateTime": "2024-2-2 16:01:30.917", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753219502149]" + }, + { + "Id": "510753541709893", + "ParentId": "510753541705799", + "DirectorId": "", + "Name": "生产一部", + "Names": "杰尼科技有限公司/生产部/生产一部", + "Code": "3jz7oH2YdB", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-2 16:01:30.92", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753219502149,510753541705799]" + }, + { + "Id": "510753541709894", + "ParentId": "510753219502149", + "DirectorId": "", + "Name": "销售部", + "Names": "杰尼科技有限公司/销售部", + "Code": "1175P8fpKj", + "Category": "DEPT", + "SortCode": "4", + "CreateTime": "2024-2-2 16:01:30.92", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753219502149]" + }, + { + "Id": "516762847445061", + "ParentId": "510753219502149", + "DirectorId": "", + "Name": "科技部", + "Names": "杰尼科技有限公司/科技部", + "Code": "aixpW3fg7h", + "Category": "DEPT", + "SortCode": "2", + "CreateTime": "2024-2-19 15:33:26.577", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753219502149]" + }, + { + "Id": "516762847465541", + "ParentId": "516762847445061", + "DirectorId": "", + "Name": "科技一部", + "Names": "杰尼科技有限公司/科技部/科技一部", + "Code": "8IGvu1YbVv", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-19 15:33:26.58", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753219502149,516762847445061]" + }, + { + "Id": "516762847465542", + "ParentId": "516762847465541", + "DirectorId": "", + "Name": "科技一部1组", + "Names": "杰尼科技有限公司/科技部/科技一部/科技一部1组", + "Code": "7i2xo2x63S", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-19 15:33:26.58", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753219502149,516762847445061,516762847465541]" + }, + { + "Id": "517088662995013", + "ParentId": "510752889880645", + "DirectorId": "", + "Name": "研发部", + "Names": "旺仔科技有限公司/研发部", + "Code": "28s3SaDA24", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-20 13:39:11.383", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "511724553736261", + "UpdateUserId": "", + "CreateUser": "旺仔科技管理员", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510752889880645]" + }, + { + "Id": "517125532377157", + "ParentId": "510753219502149", + "DirectorId": "212725263002001", + "Name": "果冻科技有限公司", + "Names": "杰尼科技有限公司/果冻科技有限公司", + "Code": "1wfUJ6288S", + "Category": "COMPANY", + "SortCode": "1", + "CreateTime": "2024-2-20 16:09:12.727", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753219502149]" + }, + { + "Id": "517129906487365", + "ParentId": "510753219502149", + "DirectorId": "", + "Name": "研发部", + "Names": "杰尼科技有限公司/研发部", + "Code": "OMkYEanrD3", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-20 16:27:02.277", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[510753219502149]" + }, + { + "Id": "517130541625413", + "ParentId": "252885263003720", + "DirectorId": "", + "Name": "研发部", + "Names": "果冻科技有限公司/研发部", + "Code": "Ql894KJrdb", + "Category": "DEPT", + "SortCode": "99", + "CreateTime": "2024-2-20 16:29:35.677", + "UpdateTime": "2024-7-23 09:09:40.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE", + "ParentIdList": "[252885263003720]" + } + ] +} \ No newline at end of file diff --git a/SimpleAdmin.System/SeedData/Json/seed_sys_position.json b/SimpleAdmin.System/SeedData/Json/seed_sys_position.json new file mode 100644 index 0000000..4b5ff16 --- /dev/null +++ b/SimpleAdmin.System/SeedData/Json/seed_sys_position.json @@ -0,0 +1,328 @@ +{ + "RECORDS": [ + { + "Id": "212725263003001", + "OrgId": "252885263003720", + "Name": "董事长", + "Code": "rsz5dmh762", + "Category": "HIGH", + "SortCode": "1", + "CreateOrgId": "252885263003720", + "CreateTime": "2023-8-14 16:19:29.213", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "212725263003002", + "OrgId": "252885263003720", + "Name": "总经理", + "Code": "wo1araqs2z", + "Category": "HIGH", + "SortCode": "2", + "CreateOrgId": "252885263003720", + "CreateTime": "2023-8-14 16:19:29.217", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "212725263003003", + "OrgId": "252885263003720", + "Name": "副总经理", + "Code": "asqvwbsc16", + "Category": "HIGH", + "SortCode": "3", + "CreateOrgId": "252885263003720", + "CreateTime": "2023-8-14 16:19:29.217", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "212725263003004", + "OrgId": "252885263003720", + "Name": "总经理助理", + "Code": "aln9y4tno6", + "Category": "HIGH", + "SortCode": "4", + "CreateOrgId": "252885263003720", + "CreateTime": "2023-8-14 16:19:29.217", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "212725263003005", + "OrgId": "252885263003720", + "Name": "部门经理", + "Code": "krq0kj7oio", + "Category": "MIDDLE", + "SortCode": "5", + "CreateOrgId": "252885263003720", + "CreateTime": "2023-8-14 16:19:29.217", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "359569658515525", + "OrgId": "359569393872965", + "Name": "总经理", + "Code": "4fuFapeKGy", + "Category": "MIDDLE", + "SortCode": "99", + "CreateOrgId": "0", + "CreateTime": "2023-8-14 16:19:29.217", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "360728646910021", + "OrgId": "360642028625989", + "Name": "销售主管", + "Code": "Zq1KvX44WN", + "Category": "MIDDLE", + "SortCode": "99", + "CreateOrgId": "0", + "CreateTime": "2023-8-14 16:19:29.217", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "361407055544389", + "OrgId": "252885263003720", + "Name": "普通员工", + "Code": "1Cy6JUDzeL", + "Category": "LOW", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2023-8-14 16:19:29.217", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "361414036955205", + "OrgId": "361404296994885", + "Name": "研发人员", + "Code": "AImZqb6j2X", + "Category": "LOW", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2023-8-14 16:19:29.217", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "361414093332549", + "OrgId": "361404346445893", + "Name": "财务总监", + "Code": "5JOEG44G62", + "Category": "HIGH", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2023-8-14 16:19:29.217", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "361415094177861", + "OrgId": "361404296994885", + "Name": "项目经理", + "Code": "AmOE17p37x", + "Category": "MIDDLE", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2023-8-14 16:19:29.217", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "485593012985925", + "OrgId": "464837557956677", + "Name": "组长", + "Code": "YWUz4Fc794", + "Category": "HIGH", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2023-11-23 13:43:03.707", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "511723823370309", + "OrgId": "510752889880645", + "Name": "职工", + "Code": "2KVZ6Uz3ne", + "Category": "LOW", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2024-2-5 09:49:36.083", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "511723919061061", + "OrgId": "510753093025861", + "Name": "董事长", + "Code": "4RbqYeVTG7", + "Category": "HIGH", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2024-2-5 09:49:59.447", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "511723963043909", + "OrgId": "510753219502149", + "Name": "董事长", + "Code": "50wshEGBxd", + "Category": "HIGH", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2024-2-5 09:50:10.187", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "517095081300037", + "OrgId": "517088662995013", + "Name": "研发部经理", + "Code": "KXs5l2W2v9", + "Category": "HIGH", + "SortCode": "99", + "CreateOrgId": "510752889880645", + "CreateTime": "2024-2-20 14:05:18.353", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "511724553736261", + "UpdateUserId": "", + "CreateUser": "旺仔科技管理员", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "517129906495557", + "OrgId": "517129906487365", + "Name": "研发部经理", + "Code": "KXs5A2W3v9", + "Category": "HIGH", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2024-2-20 16:27:02.323", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "517130541629509", + "OrgId": "517130541625413", + "Name": "研发部经理", + "Code": "0EyfLIDRJC", + "Category": "HIGH", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2024-2-20 16:29:35.687", + "UpdateTime": "2024-7-23 09:09:41.073", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + } + ] +} \ No newline at end of file diff --git a/SimpleAdmin.System/SeedData/Json/seed_sys_relation.json b/SimpleAdmin.System/SeedData/Json/seed_sys_relation.json new file mode 100644 index 0000000..f1ad4df --- /dev/null +++ b/SimpleAdmin.System/SeedData/Json/seed_sys_relation.json @@ -0,0 +1,3322 @@ +{ + "RECORDS": [ + { + "Id": "212725263003112", + "ObjectId": "212725263002001", + "TargetId": "212725263001001", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "361376304689221", + "ObjectId": "359177888051269", + "TargetId": "360646662586437", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "361406212943941", + "ObjectId": "361405857865797", + "TargetId": "359567292014661", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "361406234341445", + "ObjectId": "361405930270789", + "TargetId": "360645671104581", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "361424325550149", + "ObjectId": "361406147739717", + "TargetId": "360646281904197", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "391885190627397", + "ObjectId": "361405857865797", + "TargetId": "", + "Category": "SYS_USER_WORKBENCH_DATA", + "ExtJson": "{\"shortcut\":[{\"id\":212725263003722,\"title\":\"系统首页\",\"icon\":\"home-outlined\",\"path\":\"/index\"},{\"id\":212725263003723,\"title\":\"个人中心\",\"icon\":\"appstore-outlined\",\"path\":\"/usercenter\"}]}" + }, + { + "Id": "396380690288709", + "ObjectId": "381871212765253", + "TargetId": "212755263003745", + "Category": "SYS_USER_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003745,\"ButtonInfo\":[212825263004728,212825263004729,212825263004730,212825263004731,383020955254853,383022400483397]}" + }, + { + "Id": "396380690300997", + "ObjectId": "381871212765253", + "TargetId": "/biz/organization/org/tree", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/tree\"}" + }, + { + "Id": "396380690300998", + "ObjectId": "381871212765253", + "TargetId": "/biz/organization/org/page", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/page\"}" + }, + { + "Id": "396380690300999", + "ObjectId": "381871212765253", + "TargetId": "/biz/organization/org/add", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/add\"}" + }, + { + "Id": "396380690301000", + "ObjectId": "381871212765253", + "TargetId": "/biz/organization/org/edit", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/edit\"}" + }, + { + "Id": "396380690301001", + "ObjectId": "381871212765253", + "TargetId": "/biz/organization/org/copy", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/copy\"}" + }, + { + "Id": "396380690301002", + "ObjectId": "381871212765253", + "TargetId": "/biz/organization/org/delete", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/delete\"}" + }, + { + "Id": "396380690301003", + "ObjectId": "381871212765253", + "TargetId": "/biz/organization/org/orgTreeSelector", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/orgTreeSelector\"}" + }, + { + "Id": "396380690301004", + "ObjectId": "381871212765253", + "TargetId": "/biz/organization/org/userSelector", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/userSelector\"}" + }, + { + "Id": "425798456791109", + "ObjectId": "212725263001001", + "TargetId": "425472310554693", + "Category": "SYS_ROLE_HAS_MOBILE_RESOURCE", + "ExtJson": "{\"MenuId\":425472310554693,\"ButtonInfo\":[425710965174341,425711012839493,425711060901957]}" + }, + { + "Id": "425798456791110", + "ObjectId": "212725263001001", + "TargetId": "425472601616453", + "Category": "SYS_ROLE_HAS_MOBILE_RESOURCE", + "ExtJson": "{\"MenuId\":425472601616453,\"ButtonInfo\":[425711343288389,425711397343301,425711457501253]}" + }, + { + "Id": "425798456791111", + "ObjectId": "212725263001001", + "TargetId": "425472851824709", + "Category": "SYS_ROLE_HAS_MOBILE_RESOURCE", + "ExtJson": "{\"MenuId\":425472851824709,\"ButtonInfo\":[425711559307333,425711600533573,425711647805509]}" + }, + { + "Id": "425798456791112", + "ObjectId": "212725263001001", + "TargetId": "425474847338565", + "Category": "SYS_ROLE_HAS_MOBILE_RESOURCE", + "ExtJson": "{\"MenuId\":425474847338565,\"ButtonInfo\":[]}" + }, + { + "Id": "425798456791113", + "ObjectId": "212725263001001", + "TargetId": "425476704763973", + "Category": "SYS_ROLE_HAS_MOBILE_RESOURCE", + "ExtJson": "{\"MenuId\":425476704763973,\"ButtonInfo\":[]}" + }, + { + "Id": "428982141747269", + "ObjectId": "361405857865797", + "TargetId": "359567292014661", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "428982141751365", + "ObjectId": "212725263002001", + "TargetId": "359567292014661", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "493059010035781", + "ObjectId": "212725263002001", + "TargetId": "212725263001001", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "493420102176837", + "ObjectId": "363085233066053", + "TargetId": "212755263003745", + "Category": "SYS_USER_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003745,\"ButtonInfo\":[212825263004728,212825263004729,212825263004730,212825263004731,383020955254853,383022400483397]}" + }, + { + "Id": "493420102176838", + "ObjectId": "363085233066053", + "TargetId": "212755263003743", + "Category": "SYS_USER_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "493420102176839", + "ObjectId": "363085233066053", + "TargetId": "/biz/organization/org/tree", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/tree\"}" + }, + { + "Id": "493420102176840", + "ObjectId": "363085233066053", + "TargetId": "/biz/organization/org/page", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/page\"}" + }, + { + "Id": "493420102176841", + "ObjectId": "363085233066053", + "TargetId": "/biz/organization/org/add", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/add\"}" + }, + { + "Id": "493420102176842", + "ObjectId": "363085233066053", + "TargetId": "/biz/organization/org/edit", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/edit\"}" + }, + { + "Id": "493420102176843", + "ObjectId": "363085233066053", + "TargetId": "/biz/organization/org/copy", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/copy\"}" + }, + { + "Id": "493420102176844", + "ObjectId": "363085233066053", + "TargetId": "/biz/organization/org/delete", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/delete\"}" + }, + { + "Id": "493420102176845", + "ObjectId": "363085233066053", + "TargetId": "/biz/organization/org/orgTreeSelector", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/orgTreeSelector\"}" + }, + { + "Id": "493420102176846", + "ObjectId": "363085233066053", + "TargetId": "/biz/organization/org/userSelector", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/userSelector\"}" + }, + { + "Id": "493420102176847", + "ObjectId": "363085233066053", + "TargetId": "/biz/organization/org/detail", + "Category": "SYS_USER_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/org/detail\"}" + }, + { + "Id": "511793721868357", + "ObjectId": "511724755705925", + "TargetId": "511793641513029", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "511793721868358", + "ObjectId": "511724553736261", + "TargetId": "511793641513029", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "511793721868359", + "ObjectId": "511724397056069", + "TargetId": "511793641513029", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "511793721868360", + "ObjectId": "511724668047429", + "TargetId": "511793641513029", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "511793776644165", + "ObjectId": "212725263002002", + "TargetId": "212725263001002", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "516759017201733", + "ObjectId": "359567292014661", + "TargetId": "212755263003743", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "516759017201734", + "ObjectId": "359567292014661", + "TargetId": "212755263003745", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003745,\"ButtonInfo\":[212825263004728,212825263004729,212825263004730,212825263004731,383020955254853,383022400483397]}" + }, + { + "Id": "516759017201735", + "ObjectId": "359567292014661", + "TargetId": "212755263003746", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003746,\"ButtonInfo\":[212825263005734,212825263005735,212825263005736,212825263005737,212825263005738,212825263005739,212825263005740,391869166551109,391869250662469,395712751292485]}" + }, + { + "Id": "516759017201736", + "ObjectId": "359567292014661", + "TargetId": "212755263003747", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003747,\"ButtonInfo\":[212825263006739,212825263006749,212825263006750,212825263006751]}" + }, + { + "Id": "516759017201737", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/org/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/tree\"}" + }, + { + "Id": "516759017201738", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/org/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/page\"}" + }, + { + "Id": "516759017201739", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/org/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/add\"}" + }, + { + "Id": "516759017201740", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/org/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/edit\"}" + }, + { + "Id": "516759017201741", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/org/copy", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/copy\"}" + }, + { + "Id": "516759017201742", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/org/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/delete\"}" + }, + { + "Id": "516759017201743", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/org/orgTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/orgTreeSelector\"}" + }, + { + "Id": "516759017201744", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/org/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/userSelector\"}" + }, + { + "Id": "516759017201745", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/org/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/detail\"}" + }, + { + "Id": "516759017201746", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/position/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/page\"}" + }, + { + "Id": "516759017201747", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/position/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/add\"}" + }, + { + "Id": "516759017205829", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/position/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/edit\"}" + }, + { + "Id": "516759017205830", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/position/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/delete\"}" + }, + { + "Id": "516759017205831", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/position/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/detail\"}" + }, + { + "Id": "516759017205832", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/position/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/selector\"}" + }, + { + "Id": "516759017205833", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/preview", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/preview\"}" + }, + { + "Id": "516759017205834", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/page\"}" + }, + { + "Id": "516759017205835", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/userSelector\"}" + }, + { + "Id": "516759017205836", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/ownRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/ownRole\"}" + }, + { + "Id": "516759017205837", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/detail\"}" + }, + { + "Id": "516759017205838", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/add\"}" + }, + { + "Id": "516759017205839", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edit\"}" + }, + { + "Id": "516759017205840", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/edits", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edits\"}" + }, + { + "Id": "516759017205841", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/delete\"}" + }, + { + "Id": "516759017205842", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/disableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/disableUser\"}" + }, + { + "Id": "516759017205843", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/enableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/enableUser\"}" + }, + { + "Id": "516759017205844", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/resetPassword", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/resetPassword\"}" + }, + { + "Id": "516759017205845", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/grantRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/grantRole\"}" + }, + { + "Id": "516759017205846", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/import", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/import\"}" + }, + { + "Id": "516759017205847", + "ObjectId": "359567292014661", + "TargetId": "/biz/organization/user/export", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/export\"}" + }, + { + "Id": "516759017205848", + "ObjectId": "359567292014661", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "516759017205849", + "ObjectId": "359567292014661", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "516759017205850", + "ObjectId": "359567292014661", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "516759017205851", + "ObjectId": "359567292014661", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "516759017205852", + "ObjectId": "359567292014661", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "516759017205853", + "ObjectId": "359567292014661", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "516759049244741", + "ObjectId": "360645671104581", + "TargetId": "212755263003743", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "516759049244742", + "ObjectId": "360645671104581", + "TargetId": "212755263003745", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003745,\"ButtonInfo\":[212825263004728,212825263004729,212825263004730,212825263004731,383020955254853,383022400483397]}" + }, + { + "Id": "516759049244743", + "ObjectId": "360645671104581", + "TargetId": "212755263003746", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003746,\"ButtonInfo\":[212825263005734,212825263005735,212825263005736,212825263005737,212825263005738,212825263005739,212825263005740,391869166551109,391869250662469,395712751292485]}" + }, + { + "Id": "516759049244744", + "ObjectId": "360645671104581", + "TargetId": "212755263003747", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003747,\"ButtonInfo\":[212825263006739,212825263006749,212825263006750,212825263006751]}" + }, + { + "Id": "516759049244745", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/org/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/org/tree\"}" + }, + { + "Id": "516759049244746", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/org/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/org/page\"}" + }, + { + "Id": "516759049244747", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/org/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/org/add\"}" + }, + { + "Id": "516759049244748", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/org/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/org/edit\"}" + }, + { + "Id": "516759049244749", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/org/copy", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/org/copy\"}" + }, + { + "Id": "516759049244750", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/org/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/org/delete\"}" + }, + { + "Id": "516759049244751", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/org/orgTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/org/orgTreeSelector\"}" + }, + { + "Id": "516759049244752", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/org/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/org/userSelector\"}" + }, + { + "Id": "516759049244753", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/org/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/org/detail\"}" + }, + { + "Id": "516759049244754", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/position/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/position/page\"}" + }, + { + "Id": "516759049244755", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/position/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/position/add\"}" + }, + { + "Id": "516759049244756", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/position/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/position/edit\"}" + }, + { + "Id": "516759049244757", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/position/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/position/delete\"}" + }, + { + "Id": "516759049244758", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/position/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/position/detail\"}" + }, + { + "Id": "516759049244759", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/position/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/position/selector\"}" + }, + { + "Id": "516759049244760", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/preview", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/preview\"}" + }, + { + "Id": "516759049244761", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/page\"}" + }, + { + "Id": "516759049244762", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/userSelector\"}" + }, + { + "Id": "516759049244763", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/ownRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/ownRole\"}" + }, + { + "Id": "516759049244764", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/detail\"}" + }, + { + "Id": "516759049244765", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/add\"}" + }, + { + "Id": "516759049244766", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/edit\"}" + }, + { + "Id": "516759049248837", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/edits", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/edits\"}" + }, + { + "Id": "516759049248838", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/delete\"}" + }, + { + "Id": "516759049248839", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/disableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/disableUser\"}" + }, + { + "Id": "516759049248840", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/enableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/enableUser\"}" + }, + { + "Id": "516759049248841", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/resetPassword", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/resetPassword\"}" + }, + { + "Id": "516759049248842", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/grantRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/grantRole\"}" + }, + { + "Id": "516759049248843", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/import", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/import\"}" + }, + { + "Id": "516759049248844", + "ObjectId": "360645671104581", + "TargetId": "/biz/organization/user/export", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/biz/organization/user/export\"}" + }, + { + "Id": "516759049248845", + "ObjectId": "360645671104581", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "516759049248846", + "ObjectId": "360645671104581", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "516759049248847", + "ObjectId": "360645671104581", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "516759049248848", + "ObjectId": "360645671104581", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "516759049248849", + "ObjectId": "360645671104581", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "516759049248850", + "ObjectId": "360645671104581", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "516759084105797", + "ObjectId": "360646281904197", + "TargetId": "212755263003743", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "516759084105798", + "ObjectId": "360646281904197", + "TargetId": "212755263003745", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003745,\"ButtonInfo\":[212825263004728,212825263004729,212825263004730,212825263004731,383020955254853,383022400483397]}" + }, + { + "Id": "516759084105799", + "ObjectId": "360646281904197", + "TargetId": "212755263003746", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003746,\"ButtonInfo\":[212825263005734,212825263005735,212825263005736,212825263005737,212825263005738,212825263005739,212825263005740,391869166551109,391869250662469,395712751292485]}" + }, + { + "Id": "516759084105800", + "ObjectId": "360646281904197", + "TargetId": "212755263003747", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003747,\"ButtonInfo\":[212825263006739,212825263006749,212825263006750,212825263006751]}" + }, + { + "Id": "516759084105801", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/org/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/org/tree\"}" + }, + { + "Id": "516759084105802", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/org/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/org/page\"}" + }, + { + "Id": "516759084105803", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/org/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/org/add\"}" + }, + { + "Id": "516759084105804", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/org/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/org/edit\"}" + }, + { + "Id": "516759084109893", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/org/copy", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/org/copy\"}" + }, + { + "Id": "516759084109894", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/org/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/org/delete\"}" + }, + { + "Id": "516759084109895", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/org/orgTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/org/orgTreeSelector\"}" + }, + { + "Id": "516759084109896", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/org/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/org/userSelector\"}" + }, + { + "Id": "516759084109897", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/org/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/org/detail\"}" + }, + { + "Id": "516759084109898", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/position/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/position/page\"}" + }, + { + "Id": "516759084109899", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/position/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/position/add\"}" + }, + { + "Id": "516759084109900", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/position/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/position/edit\"}" + }, + { + "Id": "516759084109901", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/position/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/position/delete\"}" + }, + { + "Id": "516759084109902", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/position/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/position/detail\"}" + }, + { + "Id": "516759084109903", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/position/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/position/selector\"}" + }, + { + "Id": "516759084109904", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/preview", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/preview\"}" + }, + { + "Id": "516759084109905", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/page\"}" + }, + { + "Id": "516759084109906", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/userSelector\"}" + }, + { + "Id": "516759084109907", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/ownRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/ownRole\"}" + }, + { + "Id": "516759084109908", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/detail\"}" + }, + { + "Id": "516759084109909", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/add\"}" + }, + { + "Id": "516759084109910", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/edit\"}" + }, + { + "Id": "516759084109911", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/edits", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/edits\"}" + }, + { + "Id": "516759084109912", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/delete\"}" + }, + { + "Id": "516759084109913", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/disableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/disableUser\"}" + }, + { + "Id": "516759084109914", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/enableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/enableUser\"}" + }, + { + "Id": "516759084109915", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/resetPassword", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/resetPassword\"}" + }, + { + "Id": "516759084109916", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/grantRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/grantRole\"}" + }, + { + "Id": "516759084109917", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/import", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/import\"}" + }, + { + "Id": "516759084109918", + "ObjectId": "360646281904197", + "TargetId": "/biz/organization/user/export", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/biz/organization/user/export\"}" + }, + { + "Id": "516759084109919", + "ObjectId": "360646281904197", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "516759084109920", + "ObjectId": "360646281904197", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "516759084109921", + "ObjectId": "360646281904197", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "516759084109922", + "ObjectId": "360646281904197", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "516759084109923", + "ObjectId": "360646281904197", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "516759084109924", + "ObjectId": "360646281904197", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[252885263003721,464837351616581,464837557956677],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "516759117541445", + "ObjectId": "360646662586437", + "TargetId": "212755263003743", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "516759117541446", + "ObjectId": "360646662586437", + "TargetId": "212755263003746", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003746,\"ButtonInfo\":[212825263005734,212825263005735,212825263005736,212825263005737,212825263005738,212825263005739,212825263005740,391869166551109,391869250662469,395712751292485]}" + }, + { + "Id": "516759117541447", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/preview", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/preview\"}" + }, + { + "Id": "516759117541448", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/page\"}" + }, + { + "Id": "516759117541449", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/userSelector\"}" + }, + { + "Id": "516759117541450", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/ownRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/ownRole\"}" + }, + { + "Id": "516759117541451", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/detail\"}" + }, + { + "Id": "516759117541452", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/add\"}" + }, + { + "Id": "516759117541453", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edit\"}" + }, + { + "Id": "516759117541454", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/edits", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edits\"}" + }, + { + "Id": "516759117541455", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/delete\"}" + }, + { + "Id": "516759117541456", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/disableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/disableUser\"}" + }, + { + "Id": "516759117541457", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/enableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/enableUser\"}" + }, + { + "Id": "516759117541458", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/resetPassword", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/resetPassword\"}" + }, + { + "Id": "516759117541459", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/grantRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/grantRole\"}" + }, + { + "Id": "516759117541460", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/import", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/import\"}" + }, + { + "Id": "516759117541461", + "ObjectId": "360646662586437", + "TargetId": "/biz/organization/user/export", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/export\"}" + }, + { + "Id": "516759117541462", + "ObjectId": "360646662586437", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "516759117541463", + "ObjectId": "360646662586437", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "516759117541464", + "ObjectId": "360646662586437", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "516759117541465", + "ObjectId": "360646662586437", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "516759117541466", + "ObjectId": "360646662586437", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "516759117541467", + "ObjectId": "360646662586437", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "516759156367429", + "ObjectId": "363084914917445", + "TargetId": "212755263003743", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "516759156367430", + "ObjectId": "363084914917445", + "TargetId": "212755263003745", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003745,\"ButtonInfo\":[212825263004728,212825263004729,212825263004730,212825263004731,383020955254853,383022400483397]}" + }, + { + "Id": "516759156367431", + "ObjectId": "363084914917445", + "TargetId": "/biz/organization/org/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/tree\"}" + }, + { + "Id": "516759156367432", + "ObjectId": "363084914917445", + "TargetId": "/biz/organization/org/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/page\"}" + }, + { + "Id": "516759156367433", + "ObjectId": "363084914917445", + "TargetId": "/biz/organization/org/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/add\"}" + }, + { + "Id": "516759156367434", + "ObjectId": "363084914917445", + "TargetId": "/biz/organization/org/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/edit\"}" + }, + { + "Id": "516759156367435", + "ObjectId": "363084914917445", + "TargetId": "/biz/organization/org/copy", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/copy\"}" + }, + { + "Id": "516759156367436", + "ObjectId": "363084914917445", + "TargetId": "/biz/organization/org/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/delete\"}" + }, + { + "Id": "516759156367437", + "ObjectId": "363084914917445", + "TargetId": "/biz/organization/org/orgTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/orgTreeSelector\"}" + }, + { + "Id": "516759156367438", + "ObjectId": "363084914917445", + "TargetId": "/biz/organization/org/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/userSelector\"}" + }, + { + "Id": "516759156367439", + "ObjectId": "363084914917445", + "TargetId": "/biz/organization/org/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/detail\"}" + }, + { + "Id": "516759156367440", + "ObjectId": "363084914917445", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "516759156367441", + "ObjectId": "363084914917445", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "516759156367442", + "ObjectId": "363084914917445", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "516759156367443", + "ObjectId": "363084914917445", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "516759156367444", + "ObjectId": "363084914917445", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "516759156367445", + "ObjectId": "363084914917445", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "517480282214469", + "ObjectId": "511793641513029", + "TargetId": "212755263003743", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "517480282214470", + "ObjectId": "511793641513029", + "TargetId": "212755263003745", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003745,\"ButtonInfo\":[212825263004728,212825263004729,212825263004730,212825263004731,383020955254853,383022400483397]}" + }, + { + "Id": "517480282214471", + "ObjectId": "511793641513029", + "TargetId": "212755263003746", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003746,\"ButtonInfo\":[212825263005734,212825263005735,212825263005736,212825263005737,212825263005738,212825263005739,212825263005740,391869166551109,391869250662469,395712751292485]}" + }, + { + "Id": "517480282214472", + "ObjectId": "511793641513029", + "TargetId": "212755263003747", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003747,\"ButtonInfo\":[212825263006739,212825263006749,212825263006750,212825263006751]}" + }, + { + "Id": "517480282214473", + "ObjectId": "511793641513029", + "TargetId": "517412647174213", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":517412647174213,\"ButtonInfo\":[517470837813317,517470837813318,517470837813319,517470837813320,517480163758149,517480218902597]}" + }, + { + "Id": "517480282214474", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/org/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/tree\"}" + }, + { + "Id": "517480282214475", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/org/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/page\"}" + }, + { + "Id": "517480282214476", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/org/orgTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/orgTreeSelector\"}" + }, + { + "Id": "517480282214477", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/org/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/userSelector\"}" + }, + { + "Id": "517480282214478", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/org/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/detail\"}" + }, + { + "Id": "517480282214479", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/org/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/add\"}" + }, + { + "Id": "517480282214480", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/org/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/edit\"}" + }, + { + "Id": "517480282214481", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/org/copy", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/copy\"}" + }, + { + "Id": "517480282214482", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/org/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/delete\"}" + }, + { + "Id": "517480282214483", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/position/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/tree\"}" + }, + { + "Id": "517480282214484", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/position/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/page\"}" + }, + { + "Id": "517480282214485", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/position/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/detail\"}" + }, + { + "Id": "517480282214486", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/position/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/selector\"}" + }, + { + "Id": "517480282214487", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/position/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/add\"}" + }, + { + "Id": "517480282214488", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/position/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/edit\"}" + }, + { + "Id": "517480282214489", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/position/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/delete\"}" + }, + { + "Id": "517480282214490", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/page\"}" + }, + { + "Id": "517480282214491", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/add\"}" + }, + { + "Id": "517480282214492", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/edit\"}" + }, + { + "Id": "517480282214493", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/delete\"}" + }, + { + "Id": "517480282214494", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/resourceTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/resourceTreeSelector\"}" + }, + { + "Id": "517480282214495", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/ownResource", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/ownResource\"}" + }, + { + "Id": "517480282214496", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/grantResource", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/grantResource\"}" + }, + { + "Id": "517480282214497", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/permissionTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/permissionTreeSelector\"}" + }, + { + "Id": "517480282214498", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/ownPermission", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/ownPermission\"}" + }, + { + "Id": "517480282214499", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/grantPermission", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/grantPermission\"}" + }, + { + "Id": "517480282214500", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/ownUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/ownUser\"}" + }, + { + "Id": "517480282218565", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/grantUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/grantUser\"}" + }, + { + "Id": "517480282218566", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/tree\"}" + }, + { + "Id": "517480282218567", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/detail\"}" + }, + { + "Id": "517480282218568", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/role/roleSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/roleSelector\"}" + }, + { + "Id": "517480282218569", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/preview", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/preview\"}" + }, + { + "Id": "517480282218570", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/page\"}" + }, + { + "Id": "517480282218571", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/selector\"}" + }, + { + "Id": "517480282218572", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/ownRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/ownRole\"}" + }, + { + "Id": "517480282218573", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/detail\"}" + }, + { + "Id": "517480282218574", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/add\"}" + }, + { + "Id": "517480282218575", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edit\"}" + }, + { + "Id": "517480282218576", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/edits", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edits\"}" + }, + { + "Id": "517480282218577", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/delete\"}" + }, + { + "Id": "517480282218578", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/disableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/disableUser\"}" + }, + { + "Id": "517480282218579", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/enableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/enableUser\"}" + }, + { + "Id": "517480282218580", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/resetPassword", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/resetPassword\"}" + }, + { + "Id": "517480282218581", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/grantRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/grantRole\"}" + }, + { + "Id": "517480282218582", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/import", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/import\"}" + }, + { + "Id": "517480282218583", + "ObjectId": "511793641513029", + "TargetId": "/biz/organization/user/export", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/export\"}" + }, + { + "Id": "517480282218584", + "ObjectId": "511793641513029", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "517480282218585", + "ObjectId": "511793641513029", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "517480282218586", + "ObjectId": "511793641513029", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "517480282218587", + "ObjectId": "511793641513029", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "517480282218588", + "ObjectId": "511793641513029", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "517480282218589", + "ObjectId": "511793641513029", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "518179745652805", + "ObjectId": "517794467639365", + "TargetId": "212755263003743", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "518179745652806", + "ObjectId": "517794467639365", + "TargetId": "212755263003745", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003745,\"ButtonInfo\":[212825263004728,212825263004729,212825263004730,212825263004731,383020955254853,383022400483397]}" + }, + { + "Id": "518179745652807", + "ObjectId": "517794467639365", + "TargetId": "212755263003746", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003746,\"ButtonInfo\":[212825263005734,212825263005736,212825263005737,212825263005738,212825263005739,212825263005740,391869166551109,391869250662469]}" + }, + { + "Id": "518179745652808", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/tree\"}" + }, + { + "Id": "518179745652809", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/page\"}" + }, + { + "Id": "518179745652810", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/orgTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/orgTreeSelector\"}" + }, + { + "Id": "518179745652811", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/userSelector\"}" + }, + { + "Id": "518179745652812", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/detail\"}" + }, + { + "Id": "518179745652813", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/add\"}" + }, + { + "Id": "518179745652814", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/edit\"}" + }, + { + "Id": "518179745652815", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/copy", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/copy\"}" + }, + { + "Id": "518179745652816", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/delete\"}" + }, + { + "Id": "518179745652817", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/preview", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/preview\"}" + }, + { + "Id": "518179745652818", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/page\"}" + }, + { + "Id": "518179745652819", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/selector\"}" + }, + { + "Id": "518179745652820", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/ownRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/ownRole\"}" + }, + { + "Id": "518179745652821", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/detail\"}" + }, + { + "Id": "518179745652822", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/add\"}" + }, + { + "Id": "518179745652823", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edit\"}" + }, + { + "Id": "518179745652824", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/edits", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edits\"}" + }, + { + "Id": "518179745652825", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/delete\"}" + }, + { + "Id": "518179745652826", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/disableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/disableUser\"}" + }, + { + "Id": "518179745652827", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/enableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/enableUser\"}" + }, + { + "Id": "518179745652828", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/resetPassword", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/resetPassword\"}" + }, + { + "Id": "518179745652829", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/grantRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/grantRole\"}" + }, + { + "Id": "518179745652830", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/import", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/import\"}" + }, + { + "Id": "518179745652831", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/export", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/export\"}" + }, + { + "Id": "518179745652832", + "ObjectId": "517794467639365", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "518179745652833", + "ObjectId": "517794467639365", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "518179745652834", + "ObjectId": "517794467639365", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "518179745652835", + "ObjectId": "517794467639365", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "518179745652836", + "ObjectId": "517794467639365", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "518179745652837", + "ObjectId": "517794467639365", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "518189837262917", + "ObjectId": "518189781848133", + "TargetId": "517794467639365", + "Category": "SYS_USER_HAS_ROLE", + "ExtJson": "" + }, + { + "Id": "518190547849285", + "ObjectId": "517794467639365", + "TargetId": "212755263003743", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "518190547849286", + "ObjectId": "517794467639365", + "TargetId": "212755263003745", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003745,\"ButtonInfo\":[212825263004728,212825263004729,212825263004730,212825263004731,383020955254853,383022400483397]}" + }, + { + "Id": "518190547849287", + "ObjectId": "517794467639365", + "TargetId": "212755263003746", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003746,\"ButtonInfo\":[212825263005734,212825263005736,212825263005737,212825263005738,212825263005739,212825263005740,391869166551109,391869250662469]}" + }, + { + "Id": "518190547849288", + "ObjectId": "517794467639365", + "TargetId": "212755263003747", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003747,\"ButtonInfo\":[212825263006739,212825263006749,212825263006750,212825263006751]}" + }, + { + "Id": "518190547849289", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/tree\"}" + }, + { + "Id": "518190547849290", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/page\"}" + }, + { + "Id": "518190547849291", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/orgTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/orgTreeSelector\"}" + }, + { + "Id": "518190547849292", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/userSelector\"}" + }, + { + "Id": "518190547849293", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/detail\"}" + }, + { + "Id": "518190547849294", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/add\"}" + }, + { + "Id": "518190547849295", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/edit\"}" + }, + { + "Id": "518190547849296", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/copy", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/copy\"}" + }, + { + "Id": "518190547849297", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/org/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/delete\"}" + }, + { + "Id": "518190547849298", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/position/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/tree\"}" + }, + { + "Id": "518190547849299", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/position/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/page\"}" + }, + { + "Id": "518190547849300", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/position/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/detail\"}" + }, + { + "Id": "518190547849301", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/position/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/selector\"}" + }, + { + "Id": "518190547849302", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/position/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/add\"}" + }, + { + "Id": "518190547849303", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/position/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/edit\"}" + }, + { + "Id": "518190547849304", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/position/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/delete\"}" + }, + { + "Id": "518190547849305", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/preview", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/preview\"}" + }, + { + "Id": "518190547849306", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/page\"}" + }, + { + "Id": "518190547849307", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/selector\"}" + }, + { + "Id": "518190547849308", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/ownRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/ownRole\"}" + }, + { + "Id": "518190547849309", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/detail\"}" + }, + { + "Id": "518190547849310", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/add\"}" + }, + { + "Id": "518190547849311", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edit\"}" + }, + { + "Id": "518190547849312", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/edits", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edits\"}" + }, + { + "Id": "518190547849313", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/delete\"}" + }, + { + "Id": "518190547849314", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/disableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/disableUser\"}" + }, + { + "Id": "518190547849315", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/enableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/enableUser\"}" + }, + { + "Id": "518190547849316", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/resetPassword", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/resetPassword\"}" + }, + { + "Id": "518190547849317", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/grantRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/grantRole\"}" + }, + { + "Id": "518190547849318", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/import", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/import\"}" + }, + { + "Id": "518190547849319", + "ObjectId": "517794467639365", + "TargetId": "/biz/organization/user/export", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/export\"}" + }, + { + "Id": "518190547849320", + "ObjectId": "517794467639365", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "518190547849321", + "ObjectId": "517794467639365", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "518190547849322", + "ObjectId": "517794467639365", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "518190547849323", + "ObjectId": "517794467639365", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "518190547849324", + "ObjectId": "517794467639365", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "518190547849325", + "ObjectId": "517794467639365", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "614733361340485", + "ObjectId": "212725263002002", + "TargetId": "", + "Category": "SYS_USER_WORKBENCH_DATA", + "ExtJson": "{\"shortcut\":[212725263003723,212725263003722]}" + }, + { + "Id": "622206493061189", + "ObjectId": "212725263001002", + "TargetId": "212755263003743", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "622206493061190", + "ObjectId": "212725263001002", + "TargetId": "212755263003745", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003745,\"ButtonInfo\":[212825263004728,212825263004729,212825263004730,212825263004731,383020955254853,383022400483397]}" + }, + { + "Id": "622206493065285", + "ObjectId": "212725263001002", + "TargetId": "212755263003746", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003746,\"ButtonInfo\":[212825263005734,212825263005735,212825263005736,212825263005737,212825263005738,212825263005739,212825263005740,391869166551109,391869250662469,395712751292485]}" + }, + { + "Id": "622206493065286", + "ObjectId": "212725263001002", + "TargetId": "212755263003747", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003747,\"ButtonInfo\":[212825263006739,212825263006749,212825263006750,212825263006751]}" + }, + { + "Id": "622206493065287", + "ObjectId": "212725263001002", + "TargetId": "517412647174213", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":517412647174213,\"ButtonInfo\":[517470837813317,517470837813318,517470837813319,517470837813320,517480163758149,517480218902597]}" + }, + { + "Id": "622206493065288", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/org/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/tree\"}" + }, + { + "Id": "622206493065289", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/org/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/page\"}" + }, + { + "Id": "622206493065290", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/org/orgTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/orgTreeSelector\"}" + }, + { + "Id": "622206493065291", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/org/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/userSelector\"}" + }, + { + "Id": "622206493065292", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/org/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/detail\"}" + }, + { + "Id": "622206493065293", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/org/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/add\"}" + }, + { + "Id": "622206493065294", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/org/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/edit\"}" + }, + { + "Id": "622206493065295", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/org/copy", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/copy\"}" + }, + { + "Id": "622206493065296", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/org/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/delete\"}" + }, + { + "Id": "622206493065297", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/position/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/tree\"}" + }, + { + "Id": "622206493065298", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/position/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/page\"}" + }, + { + "Id": "622206493065299", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/position/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/detail\"}" + }, + { + "Id": "622206493065300", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/position/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/selector\"}" + }, + { + "Id": "622206493065301", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/position/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/add\"}" + }, + { + "Id": "622206493065302", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/position/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/edit\"}" + }, + { + "Id": "622206493065303", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/position/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/delete\"}" + }, + { + "Id": "622206493065304", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/page\"}" + }, + { + "Id": "622206493065305", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/add\"}" + }, + { + "Id": "622206493065306", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/edit\"}" + }, + { + "Id": "622206493065307", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/delete\"}" + }, + { + "Id": "622206493065308", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/resourceTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/resourceTreeSelector\"}" + }, + { + "Id": "622206493065309", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/ownResource", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/ownResource\"}" + }, + { + "Id": "622206493065310", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/grantResource", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/grantResource\"}" + }, + { + "Id": "622206493065311", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/ownUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/ownUser\"}" + }, + { + "Id": "622206493065312", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/grantUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/grantUser\"}" + }, + { + "Id": "622206493065313", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/tree\"}" + }, + { + "Id": "622206493065314", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/detail\"}" + }, + { + "Id": "622206493065315", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/role/roleSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/role/roleSelector\"}" + }, + { + "Id": "622206493065316", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/preview", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/preview\"}" + }, + { + "Id": "622206493065317", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/page\"}" + }, + { + "Id": "622206493065318", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/selector\"}" + }, + { + "Id": "622206493065319", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/ownRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/ownRole\"}" + }, + { + "Id": "622206493065320", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/detail\"}" + }, + { + "Id": "622206493065321", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/add\"}" + }, + { + "Id": "622206493065322", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edit\"}" + }, + { + "Id": "622206493065323", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/edits", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edits\"}" + }, + { + "Id": "622206493065324", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/delete\"}" + }, + { + "Id": "622206493065325", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/disableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/disableUser\"}" + }, + { + "Id": "622206493065326", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/enableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/enableUser\"}" + }, + { + "Id": "622206493065327", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/resetPassword", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/resetPassword\"}" + }, + { + "Id": "622206493065328", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/grantRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/grantRole\"}" + }, + { + "Id": "622206493065329", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/import", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/import\"}" + }, + { + "Id": "622206493065330", + "ObjectId": "212725263001002", + "TargetId": "/biz/organization/user/export", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/export\"}" + }, + { + "Id": "622206493065331", + "ObjectId": "212725263001002", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "622206493065332", + "ObjectId": "212725263001002", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "622206493065333", + "ObjectId": "212725263001002", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "622206493065334", + "ObjectId": "212725263001002", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "622206493065335", + "ObjectId": "212725263001002", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "622206493065336", + "ObjectId": "212725263001002", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "661489164984389", + "ObjectId": "212725263001001", + "TargetId": "212725263003721", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "661489165000773", + "ObjectId": "212725263001001", + "TargetId": "212755263003743", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "661489165000774", + "ObjectId": "212725263001001", + "TargetId": "212725263003725", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212725263003725,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000775", + "ObjectId": "212725263001001", + "TargetId": "212725263003726", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212725263003726,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000776", + "ObjectId": "212725263001001", + "TargetId": "212725263003727", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212725263003727,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000777", + "ObjectId": "212725263001001", + "TargetId": "212725263003729", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212725263003729,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000778", + "ObjectId": "212725263001001", + "TargetId": "212725263003730", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212725263003730,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000779", + "ObjectId": "212725263001001", + "TargetId": "212725263003731", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212725263003731,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000780", + "ObjectId": "212725263001001", + "TargetId": "212725263003732", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212725263003732,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000781", + "ObjectId": "212725263001001", + "TargetId": "212735263003734", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212735263003734,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000782", + "ObjectId": "212725263001001", + "TargetId": "369089951367237", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":369089951367237,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000783", + "ObjectId": "212725263001001", + "TargetId": "212745263003736", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212745263003736,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000784", + "ObjectId": "212725263001001", + "TargetId": "212745263003737", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212745263003737,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000785", + "ObjectId": "212725263001001", + "TargetId": "363798244282437", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":363798244282437,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000786", + "ObjectId": "212725263001001", + "TargetId": "212755263003739", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003739,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000787", + "ObjectId": "212725263001001", + "TargetId": "212755263003740", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003740,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000788", + "ObjectId": "212725263001001", + "TargetId": "630698364239941", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":630698364239941,\"ButtonInfo\":[]}" + }, + { + "Id": "661489165000789", + "ObjectId": "212725263001001", + "TargetId": "212755263003745", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003745,\"ButtonInfo\":[212825263004728,212825263004729,212825263004730,212825263004731,383020955254853,383022400483397]}" + }, + { + "Id": "661489165000790", + "ObjectId": "212725263001001", + "TargetId": "212755263003746", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003746,\"ButtonInfo\":[212825263005734,212825263005735,212825263005736,212825263005737,212825263005738,212825263005739,212825263005740,391869166551109,391869250662469,395712751292485]}" + }, + { + "Id": "661489165000791", + "ObjectId": "212725263001001", + "TargetId": "212755263003747", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":212755263003747,\"ButtonInfo\":[212825263006739,212825263006749,212825263006750,212825263006751]}" + }, + { + "Id": "661489165000793", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/org/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/tree\"}" + }, + { + "Id": "661489165000794", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/org/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/page\"}" + }, + { + "Id": "661489165000795", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/org/orgTreeSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/orgTreeSelector\"}" + }, + { + "Id": "661489165000796", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/org/userSelector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/userSelector\"}" + }, + { + "Id": "661489165000797", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/org/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/detail\"}" + }, + { + "Id": "661489165000798", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/org/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/add\"}" + }, + { + "Id": "661489165000799", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/org/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/edit\"}" + }, + { + "Id": "661489165000800", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/org/copy", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/copy\"}" + }, + { + "Id": "661489165000801", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/org/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/org/delete\"}" + }, + { + "Id": "661489165004869", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/position/tree", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/tree\"}" + }, + { + "Id": "661489165004870", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/position/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/page\"}" + }, + { + "Id": "661489165004871", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/position/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/detail\"}" + }, + { + "Id": "661489165004872", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/position/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/selector\"}" + }, + { + "Id": "661489165004873", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/position/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/add\"}" + }, + { + "Id": "661489165004874", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/position/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/edit\"}" + }, + { + "Id": "661489165004875", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/position/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/position/delete\"}" + }, + { + "Id": "661489165004876", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/preview", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/preview\"}" + }, + { + "Id": "661489165004877", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/page", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/page\"}" + }, + { + "Id": "661489165004878", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/selector", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/selector\"}" + }, + { + "Id": "661489165004879", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/ownRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/ownRole\"}" + }, + { + "Id": "661489165004880", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/detail", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/detail\"}" + }, + { + "Id": "661489165004881", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/add\"}" + }, + { + "Id": "661489165004882", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/edit", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edit\"}" + }, + { + "Id": "661489165004883", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/edits", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/edits\"}" + }, + { + "Id": "661489165004884", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/delete", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/delete\"}" + }, + { + "Id": "661489165004885", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/disableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/disableUser\"}" + }, + { + "Id": "661489165004886", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/enableUser", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/enableUser\"}" + }, + { + "Id": "661489165004887", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/resetPassword", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/resetPassword\"}" + }, + { + "Id": "661489165004888", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/grantRole", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/grantRole\"}" + }, + { + "Id": "661489165004889", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/import", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/import\"}" + }, + { + "Id": "661489165004890", + "ObjectId": "212725263001001", + "TargetId": "/biz/organization/user/export", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/biz/organization/user/export\"}" + }, + { + "Id": "661489165004891", + "ObjectId": "212725263001001", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "661489165004892", + "ObjectId": "212725263001001", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "661489165004893", + "ObjectId": "212725263001001", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "661489165004894", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "661489165004895", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "661489165004896", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "662576488869957", + "ObjectId": "212725263002001", + "TargetId": "", + "Category": "SYS_USER_WORKBENCH_DATA", + "ExtJson": "{\"shortcut\":[212725263003723,212745263003737,212725263003725]}" + }, + { + "Id": "690856735096901", + "ObjectId": "212725263001001", + "TargetId": "212725263003721", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "690856735100998", + "ObjectId": "212725263001001", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "690856735100999", + "ObjectId": "212725263001001", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "690856735101000", + "ObjectId": "212725263001001", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "690856735101001", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "690856735101002", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "690856735101003", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "690861765922885", + "ObjectId": "212725263001001", + "TargetId": "212725263003721", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "690861765926982", + "ObjectId": "212725263001001", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "690861765926983", + "ObjectId": "212725263001001", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "690861765926984", + "ObjectId": "212725263001001", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "690861765926985", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "690861765926986", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "690861765926987", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "690865236963397", + "ObjectId": "212725263001001", + "TargetId": "212725263003721", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "690865236963398", + "ObjectId": "212725263001001", + "TargetId": "690865236455493", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":690865236455493,\"ButtonInfo\":[690865236590661,690865236590662,690865236590663,690865236590664,690865236590665,690865236590666,690865236590667]}" + }, + { + "Id": "690865236963399", + "ObjectId": "212725263001001", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "690865236963400", + "ObjectId": "212725263001001", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "690865236963401", + "ObjectId": "212725263001001", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "690865236963402", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "690865236963403", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "690865236963404", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + }, + { + "Id": "691249630502981", + "ObjectId": "212725263001001", + "TargetId": "212725263003721", + "Category": "SYS_ROLE_HAS_MODULE", + "ExtJson": "" + }, + { + "Id": "691249630507077", + "ObjectId": "212725263001001", + "TargetId": "691249628061765", + "Category": "SYS_ROLE_HAS_RESOURCE", + "ExtJson": "{\"MenuId\":691249628061765,\"ButtonInfo\":[691249628725317,691249628725318,691249628725319,691249628725320,691249628725321,691249628725322,691249628725323]}" + }, + { + "Id": "691249630507078", + "ObjectId": "212725263001001", + "TargetId": "/home/index/visLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/visLog/list\"}" + }, + { + "Id": "691249630507079", + "ObjectId": "212725263001001", + "TargetId": "/home/index/opLog/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/opLog/list\"}" + }, + { + "Id": "691249630507080", + "ObjectId": "212725263001001", + "TargetId": "/home/index/message/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/message/list\"}" + }, + { + "Id": "691249630507081", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/list", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/list\"}" + }, + { + "Id": "691249630507082", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/add", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/add\"}" + }, + { + "Id": "691249630507083", + "ObjectId": "212725263001001", + "TargetId": "/home/index/schedule/deleteSchedule", + "Category": "SYS_ROLE_HAS_PERMISSION", + "ExtJson": "{\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[],\"ApiUrl\":\"/home/index/schedule/deleteSchedule\"}" + } + ] +} \ No newline at end of file diff --git a/SimpleAdmin.System/SeedData/Json/seed_sys_resource.json b/SimpleAdmin.System/SeedData/Json/seed_sys_resource.json new file mode 100644 index 0000000..2016edb --- /dev/null +++ b/SimpleAdmin.System/SeedData/Json/seed_sys_resource.json @@ -0,0 +1,2298 @@ +{ + "RECORDS": [ + { + "Id": "212725263003721", + "ParentId": "", + "Title": "系统管理", + "Name": "", + "Description": "管理平台的用户、权限、菜单等", + "Code": "system", + "Category": "MODULE", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "ep:setting", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.633", + "UpdateTime": "2025-4-9 17:02:47.837", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212725263003722", + "ParentId": "", + "Title": "系统首页", + "Name": "index", + "Description": "系统首页", + "Code": "system", + "Category": "SPA", + "Module": "", + "MenuType": "MENU", + "Path": "/home/index", + "Component": "home/index", + "Icon": "ant-design:home-outlined", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.633", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "1", + "IsKeepAlive": "0", + "IsHome": "1", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212725263003723", + "ParentId": "", + "Title": "个人中心", + "Name": "userCenter", + "Description": "个人中心", + "Code": "system", + "Category": "SPA", + "Module": "", + "MenuType": "MENU", + "Path": "/usercenter", + "Component": "userCenter/index", + "Icon": "ep:user", + "SortCode": "99", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-9-20 08:35:15.35", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "1", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212725263003724", + "ParentId": "0", + "Title": "组织架构", + "Name": "", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "CATALOG", + "Path": "/sys/organization", + "Component": "", + "Icon": "ep:office-building", + "SortCode": "55", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2025-4-8 11:00:14.283", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212725263003725", + "ParentId": "212725263003724", + "Title": "组织管理", + "Name": "sysOrg", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/organization/org", + "Component": "sys/organization/org/index", + "Icon": "ant-design:apartment-outlined", + "SortCode": "5", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212725263003726", + "ParentId": "212725263003724", + "Title": "用户管理", + "Name": "sysUser", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/organization/user", + "Component": "sys/organization/user/index", + "Icon": "eva:people-outline", + "SortCode": "6", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212725263003727", + "ParentId": "212725263003724", + "Title": "职位管理", + "Name": "sysPosition", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/organization/position", + "Component": "sys/organization/position/index", + "Icon": "ep:postcard", + "SortCode": "7", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212725263003728", + "ParentId": "0", + "Title": "权限管理", + "Name": "", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "CATALOG", + "Path": "/sys/limit", + "Component": "", + "Icon": "eva:shield-outline", + "SortCode": "8", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212725263003729", + "ParentId": "212725263003728", + "Title": "角色管理", + "Name": "sysRole", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/limit/role", + "Component": "sys/limit/role/index", + "Icon": "ep:user", + "SortCode": "9", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212725263003730", + "ParentId": "212725263003728", + "Title": "模块管理", + "Name": "sysModule", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/limit/module", + "Component": "sys/limit/module/index", + "Icon": "eva:grid-outline", + "SortCode": "10", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212725263003731", + "ParentId": "212725263003728", + "Title": "菜单管理", + "Name": "sysMenu", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/limit/menu", + "Component": "sys/limit/menu/index", + "Icon": "ep:menu", + "SortCode": "11", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212725263003732", + "ParentId": "212725263003728", + "Title": "单页管理", + "Name": "sysSpa", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/limit/spa", + "Component": "sys/limit/spa/index", + "Icon": "eva:book-open-outline", + "SortCode": "12", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212735263003733", + "ParentId": "0", + "Title": "基础工具", + "Name": "", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "CATALOG", + "Path": "/sys/dev", + "Component": "", + "Icon": "ant-design:tool-outlined", + "SortCode": "13", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-11-11 08:42:34.04", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212735263003734", + "ParentId": "212735263003733", + "Title": "站内信息", + "Name": "devMessage", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/dev/message", + "Component": "sys/dev/message/index", + "Icon": "ep:message", + "SortCode": "14", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-11-11 08:43:10.76", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212745263003735", + "ParentId": "0", + "Title": "系统运维", + "Name": "", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "CATALOG", + "Path": "/sys/ops", + "Component": "", + "Icon": "zondicons:servers", + "SortCode": "15", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212745263003736", + "ParentId": "212745263003735", + "Title": "数据字典", + "Name": "sysDict", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/ops/dict", + "Component": "sys/ops/dict/index", + "Icon": "ep:notebook", + "SortCode": "16", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212745263003737", + "ParentId": "212745263003735", + "Title": "系统配置", + "Name": "sysConfig", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/ops/config", + "Component": "sys/ops/config/index", + "Icon": "eva:settings-2-outline", + "SortCode": "17", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212745263003738", + "ParentId": "0", + "Title": "日志审计", + "Name": "", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "CATALOG", + "Path": "/sys/audit", + "Component": "", + "Icon": "line-md:clipboard-list", + "SortCode": "14", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "undefined/:id", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212755263003739", + "ParentId": "212745263003738", + "Title": "访问日志", + "Name": "sysVisLog", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/audit/vislog", + "Component": "sys/audit/vislog/index", + "Icon": "ant-design:read-outlined", + "SortCode": "18", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.823", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212755263003740", + "ParentId": "212745263003738", + "Title": "操作日志", + "Name": "sysOpLog", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/audit/oplog", + "Component": "sys/audit/oplog/index", + "Icon": "ant-design:solution-outlined", + "SortCode": "19", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212755263003743", + "ParentId": "", + "Title": "业务管理", + "Name": "", + "Description": "用户自己的业务模块", + "Code": "biz", + "Category": "MODULE", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "local:ikun", + "SortCode": "2", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212755263003744", + "ParentId": "0", + "Title": "公司架构", + "Name": "", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212755263003743", + "MenuType": "CATALOG", + "Path": "/biz/organization", + "Component": "", + "Icon": "ep:school", + "SortCode": "22", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212755263003745", + "ParentId": "212755263003744", + "Title": "机构管理", + "Name": "bizOrg", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212755263003743", + "MenuType": "MENU", + "Path": "/biz/organization/org", + "Component": "biz/organization/org/index", + "Icon": "ant-design:group-outlined", + "SortCode": "23", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212755263003746", + "ParentId": "212755263003744", + "Title": "人员管理", + "Name": "bizUser", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212755263003743", + "MenuType": "MENU", + "Path": "/biz/organization/user", + "Component": "biz/organization/user/index", + "Icon": "ep:user", + "SortCode": "24", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212755263003747", + "ParentId": "212755263003744", + "Title": "岗位管理", + "Name": "bizPosition", + "Description": "", + "Code": "system", + "Category": "MENU", + "Module": "212755263003743", + "MenuType": "MENU", + "Path": "/biz/organization/position", + "Component": "biz/organization/position/index", + "Icon": "ant-design:idcard-outlined", + "SortCode": "25", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263004728", + "ParentId": "212755263003745", + "Title": "新增机构", + "Name": "", + "Description": "", + "Code": "bizOrgAdd", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263004729", + "ParentId": "212755263003745", + "Title": "查询机构", + "Name": "", + "Description": "", + "Code": "bizOrgPage", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263004730", + "ParentId": "212755263003745", + "Title": "编辑机构", + "Name": "", + "Description": "", + "Code": "bizOrgEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263004731", + "ParentId": "212755263003745", + "Title": "删除机构", + "Name": "", + "Description": "", + "Code": "bizOrgDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263005734", + "ParentId": "212755263003746", + "Title": "新增人员", + "Name": "", + "Description": "", + "Code": "bizUserAdd", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263005735", + "ParentId": "212755263003746", + "Title": "批量删除", + "Name": "", + "Description": "", + "Code": "bizUserBatchDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263005736", + "ParentId": "212755263003746", + "Title": "编辑人员", + "Name": "", + "Description": "", + "Code": "bizUserEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263005737", + "ParentId": "212755263003746", + "Title": "授权角色", + "Name": "", + "Description": "", + "Code": "bizUserGrantRole", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263005738", + "ParentId": "212755263003746", + "Title": "重置密码", + "Name": "", + "Description": "", + "Code": "bizUserPwdReset", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263005739", + "ParentId": "212755263003746", + "Title": "删除人员", + "Name": "", + "Description": "", + "Code": "bizUserDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263005740", + "ParentId": "212755263003746", + "Title": "启用禁用", + "Name": "", + "Description": "", + "Code": "bizUserUpdateStatus", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263006739", + "ParentId": "212755263003747", + "Title": "新增岗位", + "Name": "", + "Description": "", + "Code": "bizPositionAdd", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263006749", + "ParentId": "212755263003747", + "Title": "批量删除", + "Name": "", + "Description": "", + "Code": "bizPositionBatchDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263006750", + "ParentId": "212755263003747", + "Title": "编辑岗位", + "Name": "", + "Description": "", + "Code": "bizPositionEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "212825263006751", + "ParentId": "212755263003747", + "Title": "删除岗位", + "Name": "", + "Description": "", + "Code": "bizPositionDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "363798244282437", + "ParentId": "212745263003735", + "Title": "会话管理", + "Name": "authMonitor", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/ops/monitor", + "Component": "sys/ops/monitor/index", + "Icon": "ep:refrigerator", + "SortCode": "23", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-9-24 10:56:44.767", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "369089951367237", + "ParentId": "212735263003733", + "Title": "文件管理", + "Name": "devFile", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/dev/file/index", + "Component": "dev/file/index", + "Icon": "ep:home-filled", + "SortCode": "99", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "383020955254853", + "ParentId": "212755263003745", + "Title": "复制机构", + "Name": "", + "Description": "", + "Code": "bizOrgCopy", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "99", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "383022400483397", + "ParentId": "212755263003745", + "Title": "批量删除机构", + "Name": "", + "Description": "", + "Code": "bizOrgBatchDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "99", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "391869166551109", + "ParentId": "212755263003746", + "Title": "导入人员", + "Name": "", + "Description": "", + "Code": "bizUserImport", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "99", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "391869250662469", + "ParentId": "212755263003746", + "Title": "导出人员", + "Name": "", + "Description": "", + "Code": "bizUserExport", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "99", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "395712751292485", + "ParentId": "212755263003746", + "Title": "批量编辑", + "Name": "", + "Description": "", + "Code": "bizUserBatchEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "99", + "CreateTime": "2023-8-14 16:19:29.637", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "517412647174213", + "ParentId": "212755263003744", + "Title": "角色管理", + "Name": "bizRole", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "212755263003743", + "MenuType": "MENU", + "Path": "/biz/organization/role", + "Component": "biz/organization/role/index", + "Icon": "ant-design:team-outlined", + "SortCode": "99", + "CreateTime": "2024-2-21 11:37:29.083", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "517470837813317", + "ParentId": "517412647174213", + "Title": "新增角色", + "Name": "", + "Description": "", + "Code": "bizRoleAdd", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2024-2-21 15:34:15.803", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "517470837813318", + "ParentId": "517412647174213", + "Title": "编辑角色", + "Name": "", + "Description": "", + "Code": "bizRoleEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "2", + "CreateTime": "2024-2-21 15:34:15.807", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "517470837813319", + "ParentId": "517412647174213", + "Title": "删除角色", + "Name": "", + "Description": "", + "Code": "bizRoleDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "3", + "CreateTime": "2024-2-21 15:34:15.81", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "517470837813320", + "ParentId": "517412647174213", + "Title": "批量删除角色", + "Name": "", + "Description": "", + "Code": "bizRoleBatchDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "4", + "CreateTime": "2024-2-21 15:34:15.81", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "517480163758149", + "ParentId": "517412647174213", + "Title": "授权资源", + "Name": "", + "Description": "", + "Code": "bizRoleGrantResource", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "99", + "CreateTime": "2024-2-21 16:12:12.627", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "517480218902597", + "ParentId": "517412647174213", + "Title": "授权用户", + "Name": "", + "Description": "", + "Code": "bizRoleGrantUser", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "99", + "CreateTime": "2024-2-21 16:12:26.087", + "UpdateTime": "2024-7-23 09:09:41.827", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "630693367205957", + "ParentId": "0", + "Title": "在线开发", + "Name": "", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "CATALOG", + "Path": "/sys/curd", + "Component": "", + "Icon": "line-md:computer", + "SortCode": "99", + "CreateTime": "2025-1-6 13:57:54.873", + "UpdateTime": "2025-1-6 14:17:00.817", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "630698364239941", + "ParentId": "630693367205957", + "Title": "代码生成", + "Name": "/sys/curd/gen", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/curd", + "Component": "sys/curd/gen/index", + "Icon": "ant-design:rocket-outlined", + "SortCode": "99", + "CreateTime": "2025-1-6 14:18:14.853", + "UpdateTime": "2025-1-6 14:18:36.963", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "663908456329285", + "ParentId": "212725263003729", + "Title": "新增", + "Name": "", + "Description": "", + "Code": "001", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "99", + "CreateTime": "2025-4-10 10:30:27.49", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "690820254830661", + "ParentId": "0", + "Title": "移动端管理", + "Name": "", + "Description": "", + "Code": "", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "CATALOG", + "Path": "/sys/mobile", + "Component": "", + "Icon": "zondicons:mobile-devices", + "SortCode": "99", + "CreateTime": "2025-6-25 11:34:50.797", + "UpdateTime": "2025-6-25 14:31:29.59", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "690865236455493", + "ParentId": "690820254830661", + "Title": "模块管理", + "Name": "module", + "Description": "", + "Code": "A1oh71KcnD", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/mobile/module", + "Component": "sys/mobile/module/index", + "Icon": "eva:grid-outline", + "SortCode": "99", + "CreateTime": "2025-6-25 14:37:52.643", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "690865236590661", + "ParentId": "690865236455493", + "Title": "新增模块", + "Name": "", + "Description": "", + "Code": "mobileResourceAdd", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2025-6-25 14:37:52.697", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "690865236590662", + "ParentId": "690865236455493", + "Title": "编辑模块", + "Name": "", + "Description": "", + "Code": "mobileResourceEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "2", + "CreateTime": "2025-6-25 14:37:52.697", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "690865236590663", + "ParentId": "690865236455493", + "Title": "删除模块", + "Name": "", + "Description": "", + "Code": "mobileResourceDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "3", + "CreateTime": "2025-6-25 14:37:52.697", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "690865236590664", + "ParentId": "690865236455493", + "Title": "批量删除模块", + "Name": "", + "Description": "", + "Code": "mobileResourceBatchDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "4", + "CreateTime": "2025-6-25 14:37:52.697", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "690865236590665", + "ParentId": "690865236455493", + "Title": "导入模块", + "Name": "", + "Description": "", + "Code": "mobileResourceImport", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "5", + "CreateTime": "2025-6-25 14:37:52.697", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "690865236590666", + "ParentId": "690865236455493", + "Title": "导出模块", + "Name": "", + "Description": "", + "Code": "mobileResourceExport", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "6", + "CreateTime": "2025-6-25 14:37:52.697", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "690865236590667", + "ParentId": "690865236455493", + "Title": "批量编辑模块", + "Name": "", + "Description": "", + "Code": "mobileResourceBatchEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "7", + "CreateTime": "2025-6-25 14:37:52.697", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "691249628061765", + "ParentId": "690820254830661", + "Title": "菜单管理", + "Name": "menu", + "Description": "", + "Code": "za6tl3zaYB", + "Category": "MENU", + "Module": "212725263003721", + "MenuType": "MENU", + "Path": "/sys/mobile/menu", + "Component": "sys/mobile/menu/index", + "Icon": "ep:menu", + "SortCode": "99", + "CreateTime": "2025-6-26 16:41:58.293", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "1", + "IsHome": "0", + "Status": "ENABLE", + "IsLink": "" + }, + { + "Id": "691249628725317", + "ParentId": "691249628061765", + "Title": "新增菜单", + "Name": "", + "Description": "", + "Code": "mobileMenuAdd", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "1", + "CreateTime": "2025-6-26 16:41:58.437", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "691249628725318", + "ParentId": "691249628061765", + "Title": "编辑菜单", + "Name": "", + "Description": "", + "Code": "mobileMenuEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "2", + "CreateTime": "2025-6-26 16:41:58.437", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "691249628725319", + "ParentId": "691249628061765", + "Title": "删除菜单", + "Name": "", + "Description": "", + "Code": "mobileMenuDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "3", + "CreateTime": "2025-6-26 16:41:58.437", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "691249628725320", + "ParentId": "691249628061765", + "Title": "批量删除菜单", + "Name": "", + "Description": "", + "Code": "mobileMenuBatchDelete", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "4", + "CreateTime": "2025-6-26 16:41:58.437", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "691249628725321", + "ParentId": "691249628061765", + "Title": "导入菜单", + "Name": "", + "Description": "", + "Code": "mobileMenuImport", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "5", + "CreateTime": "2025-6-26 16:41:58.437", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "691249628725322", + "ParentId": "691249628061765", + "Title": "导出菜单", + "Name": "", + "Description": "", + "Code": "mobileMenuExport", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "6", + "CreateTime": "2025-6-26 16:41:58.437", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + }, + { + "Id": "691249628725323", + "ParentId": "691249628061765", + "Title": "批量编辑菜单", + "Name": "", + "Description": "", + "Code": "mobileMenuBatchEdit", + "Category": "BUTTON", + "Module": "", + "MenuType": "", + "Path": "", + "Component": "", + "Icon": "", + "SortCode": "7", + "CreateTime": "2025-6-26 16:41:58.437", + "UpdateTime": "", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "ActiveMenu": "", + "IsHide": "0", + "IsFull": "0", + "IsAffix": "0", + "IsKeepAlive": "0", + "IsHome": "0", + "Status": "", + "IsLink": "" + } + ] +} \ No newline at end of file diff --git a/SimpleAdmin.System/SeedData/Json/seed_sys_role.json b/SimpleAdmin.System/SeedData/Json/seed_sys_role.json new file mode 100644 index 0000000..7637fa0 --- /dev/null +++ b/SimpleAdmin.System/SeedData/Json/seed_sys_role.json @@ -0,0 +1,175 @@ +{ + "RECORDS": [ + { + "Id": "212725263001001", + "OrgId": "", + "Name": "超级管理员", + "Code": "superAdmin", + "Category": "GLOBAL", + "DefaultDataScope": "{\"Level\":5,\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[]}", + "SortCode": "1", + "CreateOrgId": "0", + "CreateTime": "2023-8-14 16:19:29.82", + "UpdateTime": "2024-7-23 09:09:42.077", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "212725263001002", + "OrgId": "", + "Name": "业务管理员", + "Code": "bizAdmin", + "Category": "GLOBAL", + "DefaultDataScope": "{\"Level\":5,\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[]}", + "SortCode": "1", + "CreateOrgId": "0", + "CreateTime": "2023-8-14 16:19:29.9", + "UpdateTime": "2024-7-23 09:09:42.077", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "359567292014661", + "OrgId": "", + "Name": "所属组织及以下角色", + "Code": "41fP9R7YZI", + "Category": "GLOBAL", + "DefaultDataScope": "{\"Level\":4,\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[]}", + "SortCode": "99", + "CreateOrgId": "0", + "CreateTime": "2023-8-14 16:19:29.9", + "UpdateTime": "2024-7-23 09:09:42.077", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "360645671104581", + "OrgId": "", + "Name": "所属组织角色", + "Code": "KtIpet8uq0", + "Category": "GLOBAL", + "DefaultDataScope": "{\"Level\":2,\"ScopeCategory\":\"SCOPE_ORG\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885]}", + "SortCode": "99", + "CreateOrgId": "0", + "CreateTime": "2023-8-14 16:19:29.9", + "UpdateTime": "2024-7-23 09:09:42.077", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "360646281904197", + "OrgId": "", + "Name": "自定义组织角色", + "Code": "9b774qzY92", + "Category": "GLOBAL", + "DefaultDataScope": "{\"Level\":3,\"ScopeCategory\":\"SCOPE_ORG_DEFINE\",\"ScopeDefineOrgIdList\":[360642028625989,361404296994885,360642028625989,361404296994885]}", + "SortCode": "99", + "CreateOrgId": "0", + "CreateTime": "2023-8-14 16:19:29.903", + "UpdateTime": "2024-7-23 09:09:42.077", + "CreateUserId": "", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "360646662586437", + "OrgId": "", + "Name": "仅自己角色", + "Code": "182293I1ZC", + "Category": "GLOBAL", + "DefaultDataScope": "{\"Level\":1,\"ScopeCategory\":\"SCOPE_SELF\",\"ScopeDefineOrgIdList\":[]}", + "SortCode": "99", + "CreateOrgId": "0", + "CreateTime": "2023-8-14 16:19:29.903", + "UpdateTime": "2024-7-23 09:09:42.077", + "CreateUserId": "", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "363084914917445", + "OrgId": "361404296994885", + "Name": "研发部管理员", + "Code": "sfEg40KhpZ", + "Category": "ORG", + "DefaultDataScope": "{\"Level\":4,\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[]}", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2023-8-14 16:19:29.903", + "UpdateTime": "2024-7-23 09:09:42.077", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "511793641513029", + "OrgId": "", + "Name": "租户管理员", + "Code": "1q8bMS9rgF", + "Category": "GLOBAL", + "DefaultDataScope": "{\"Level\":4,\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[]}", + "SortCode": "99", + "CreateOrgId": "252885263003720", + "CreateTime": "2024-2-5 14:33:41.53", + "UpdateTime": "2024-7-23 09:09:42.077", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "517794467639365", + "OrgId": "510752889880645", + "Name": "测试", + "Code": "pwrxO3v8X5", + "Category": "ORG", + "DefaultDataScope": "{\"Level\":4,\"ScopeCategory\":\"SCOPE_ORG_CHILD\",\"ScopeDefineOrgIdList\":[]}", + "SortCode": "99", + "CreateOrgId": "510752889880645", + "CreateTime": "2024-2-22 13:31:06.97", + "UpdateTime": "2024-7-23 09:09:42.077", + "CreateUserId": "511724553736261", + "UpdateUserId": "511724553736261", + "CreateUser": "旺仔科技管理员", + "UpdateUser": "旺仔科技管理员", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + } + ] +} \ No newline at end of file diff --git a/SimpleAdmin.System/SeedData/Json/seed_sys_user.json b/SimpleAdmin.System/SeedData/Json/seed_sys_user.json new file mode 100644 index 0000000..a7596b1 --- /dev/null +++ b/SimpleAdmin.System/SeedData/Json/seed_sys_user.json @@ -0,0 +1,844 @@ +{ + "RECORDS": [ + { + "Id": "212725263002001", + "Avatar": "data:image/png;base64,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", + "Signature": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAEsCAYAAAA7Ldc6AAAAAXNSR0IArs4c6QAAIABJREFUeF7t3Qe0fVldH/CvM5Sh9w4qOAMRqQMICIIEgUWRGiBUKQOCgKFZQFSEABIgGJOhdw1tAkNHIiGCEUTaAGYy9C6hCAy9Dt7f8kwyPu9975377j1v330/e61ZrGHOPvu3P7+z/v/3e+fsvX8iGgECBAgQIECAAAECBCYS+ImJxjEMAQIECBAgQIAAAQIEogDxEBAgQIAAAQIECBAgMJmAAmQyagMRIECAAAECBAgQIKAA8QwQIECAAAECBAgQIDCZgAJkMmoDESBAgAABAgQIECCgAPEMECBAgAABAgQIECAwmYACZDJqAxEgQIAAAQIECBAgoADxDBAgQIAAAQIECBAgMJmAAmQyagMRIECAAAECBAgQIKAA8QwQIECAAAECBAgQIDCZgAJkMmoDESBAgAABAgQIECCgAPEMECBAgAABAgQIECAwmYACZDJqAxEgQIAAAQIECBAgoADxDBAgQIAAAQIECBAgMJmAAmQyagMRIECAAAECBAgQIKAA8QwQIECAAAECBAgQIDCZgAJkMmoDESBAgAABAgQIECCgAPEMECBAgAABAgQIECAwmYACZDJqAxEgQIAAAQIECBAgoADxDBAgQIAAAQIECBAgMJmAAmQyagMRIECAAAECBAgQIKAA8QwQIECAAAECBAgQIDCZgAJkMmoDESBAgAABAgQIECCgAPEMECBAgAABAgQIECAwmYACZDJqAxEgQIAAAQIECBAgoADxDBAgQIAAAQIECBAgMJmAAmQyagMRIECAAAECBAgQIKAA8QwQIECAAAECBAgQIDCZgAJkMmoDESBAgAABAgQIECCgAPEMECBAgAABAgQIECAwmYACZDJqAxEgQIAAAQIECBAgoADxDBAgQIAAAQIECBAgMJmAAmQyagMRIECAAAECBAgQIKAA8QwQIECAAAECBAgQIDCZgAJkMmoDESBAgAABAgQIECCgAPEMECBAgAABAgQIECAwmYACZDJqAxEgQIAAAQIECBAgoADxDBAgQIAAAQIECBAgMJmAAmQyagMRIECAAAECBAgQIKAA8QwQIECAAAECBAgQIDCZgAJkMmoDESBAgAABAgQIECCgAPEMECBAgAABAgQIECAwmYACZDJqAxEg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", + "Account": "superAdmin", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "超管", + "Nickname": "", + "Gender": "男", + "Birthday": "1990-01-01", + "Nation": "汉", + "NativePlace": "", + "HomeAddress": "少林寺驻北固山办事处", + "MailingAddress": "", + "IdCardType": "身份证", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "ab28db67b2dac7fc180b860990033b75", + "Email": "superAdmin@foxmail.com", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "0001", + "EntryDate": "2022-07-04", + "OrgId": "252885263003720", + "PositionId": "212725263003001", + "PositionLevel": "C1", + "DirectorId": "", + "PwdRemindUpdateTime": "2023-9-1 09:47:18", + "LastLoginIp": "192.168.0.25", + "LastLoginAddress": "内网IP|内网IP", + "LastLoginTime": "2025-4-2 10:43:07", + "LastLoginDevice": "PC", + "LatestLoginIp": "192.168.0.25", + "LatestLoginAddress": "内网IP|内网IP", + "LatestLoginTime": "2025-4-2 10:45:54.89", + "LatestLoginDevice": "PC", + "SortCode": "1", + "DefaultModule": "", + "CreateTime": "2023-8-14 16:19:30.043", + "UpdateTime": "2024-9-20 08:46:32.93", + "CreateUserId": "0", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "212725263002002", + "Avatar": "data:image/jpg;base64,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", + "Signature": "", + "Account": "bizAdmin", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "业管", + "Nickname": "", + "Gender": "男", + "Birthday": "1990-01-01", + "Nation": "汉", + "NativePlace": "", + "HomeAddress": "少林寺驻武当山办事处", + "MailingAddress": "", + "IdCardType": "身份证", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "9a2e417b82b2d061763f8d0c0d775cc8", + "Email": "bizAdmin@foxmail.com", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "0002", + "EntryDate": "2022-07-04", + "OrgId": "252885263003720", + "PositionId": "212725263003001", + "PositionLevel": "C1", + "DirectorId": "212725263002001", + "PwdRemindUpdateTime": "2023-8-17 09:45:29", + "LastLoginIp": "192.168.0.25", + "LastLoginAddress": "内网IP|内网IP", + "LastLoginTime": "2025-3-22 11:23:28", + "LastLoginDevice": "PC", + "LatestLoginIp": "192.168.0.25", + "LatestLoginAddress": "内网IP|内网IP", + "LatestLoginTime": "2025-3-24 16:17:08.037", + "LatestLoginDevice": "PC", + "SortCode": "1", + "DefaultModule": "", + "CreateTime": "2023-8-14 16:19:30.047", + "UpdateTime": "2024-7-23 09:09:42.963", + "CreateUserId": "0", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "359177888051269", + "Avatar": "data:image/png;base64,Qk12nAAAAAAAADYAAAAoAAAAZAAAAGQAAAABACAAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAAZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/nxEA////v///////hZ7g/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP/onkj//////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/58RAP///7///////4We4P9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/6J5I///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+fEQD///+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP/SeAD//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////2Z4v/9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/nxEA////v////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP//wHT/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////n8D//2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/58RAP///7///////4We4P9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/6J5I///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP/SeAD///////////+54f//ZhFI/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/58RAP///7////////////9meL//ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+fEQD///+///////+FnuD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/+ieSP//////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD//8B0///////o////Zk2c/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/uU0A////4P//////n8D//2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/nxEA////v///////hZ7g/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP/onkj//////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA///AdP//////ueH//2YRSP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/4URAP//4Zz//////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/58RAP///7///////4We4P9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/6J5I///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/4URAP//4Zz//////7nh//9mEUj/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD//8B0///////o////Zk2c/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+fEQD///+///////+FnuD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/+ieSP//////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+FEQD//+Gc//////+54f//ZhFI/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/+ieSP///////////2Z4v/9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/nxEA////v///////hZ7g/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP/onkj//////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/hREA///hnP//////ueH//2YRSP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP/SeAD///////////+FnuD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/58RAP///7/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/4URAP//4Zz//////7nh//9mEUj/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/0ngA/9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+fEQD///+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+FEQD//+Gc//////+54f//ZhFI/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/nxEA////v///////hZ7g/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP/onkj//////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/hREA///hnP//////ueH//2YRSP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/58RAP///7///////4We4P9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/6J5I///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/4URAP//4Zz//////7nh//9mEUj/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+fEQD///+///////+FnuD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/+ieSP//////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+FEQD//+Gc//////+54f//ZhFI/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/nxEA////v///////hZ7g/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP/onkj//////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/hREA///hnP//////ueH//2YRSP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP//wHT//////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/58RAP///7///////4We4P9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/6J5I///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/4URAP//4Zz//////7nh//9mEUj/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD//8B0///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+fEQD///+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+FEQD//+Gc////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/nxEA////v////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/hREA///hnP///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/58RAP///7///////4We4P9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/6J5I///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD//8B0///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+fEQD///+///////+FnuD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/+ieSP//////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA///AdP//////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/nxEA////v///////hZ7g/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP/onkj//////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP//wHT//////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/58RAP///7///////4We4P9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/6J5I///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD//8B0///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+fEQD///+///////+FnuD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/+ieSP//////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA///AdP//////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/nxEA////v///////hZ7g/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP/onkj//////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP//wHT//////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/58RAP///7/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD//8B0///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+fEQD///+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA///AdP//////0v///2YRdP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD//8B0///////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/0ngA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9L///9mEXT/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/9J4AP///////////4We4P9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/9J4AP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////S////ZhF0/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP+fEQD///+////////o////Zk2c/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/+ieSP//////Zni//2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/2YRAP9mEQD/ZhEA/w==", + "Signature": "", + "Account": "仅自己", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "仅自己", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "35c3903e43e3e355a5d1b12f1831a352", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "252885263003720", + "PositionId": "360728646910021", + "PositionLevel": "", + "DirectorId": "212725263002001", + "PwdRemindUpdateTime": "", + "LastLoginIp": "127.0.0.1", + "LastLoginAddress": "内网IP|内网IP", + "LastLoginTime": "2022-12-7 13:08:56", + "LastLoginDevice": "PC", + "LatestLoginIp": "127.0.0.1", + "LatestLoginAddress": "内网IP|内网IP", + "LatestLoginTime": "2022-12-7 13:10:34", + "LatestLoginDevice": "PC", + "SortCode": "0", + "DefaultModule": "", + "CreateTime": "2023-8-14 16:19:30.05", + "UpdateTime": "2024-7-23 09:09:42.963", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "361405857865797", + "Avatar": "data:image/png;base64,Qk12nAAAAAAAADYAAAAoAAAAZAAAAGQAAAABACAAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAAVRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV///Al//N////VRGX/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf///////////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs//////////////////n////VU2z/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nwJf/VU2z/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553////////////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+XEVX/zf/N/1URl/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/zXhV///////////////////////N////VRGX/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf//wJf//////+f///+Xnuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+zTVX////n////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/zXhV//////////////////////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf/////////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf///////////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV///Al/////////////////+z4f//VRF3/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX//8CX/////////////////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf/////////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553////////////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+zTVX////n//////////////////////9VeM3/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+zTVX////n////////////s+H//1URd/9VEVX/VRFV/1URVf/NeFX/////////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////5+H/////5////////////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP///////////+z4f//VRF3/1URVf/NeFX/////////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf///////////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////7Ph//9VEXf/zXhV/////////////////1V4zf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs////////////5fA///NeFX/////////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553////////////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+z4f//VRF3/1URVf9VEVX//8CX////////////s+H//1URd/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz////////////////////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////s+H//1URd/9VEVX/VRFV/1URVf+zTVX////n////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/7NNVf///+f/////////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf///////////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf//////+f///9VTbP/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553////////////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+zTVX/zf/n/1URl/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+z4f//VRF3/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf/N4bP/VRGX/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/5cRVf///83//////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf////////////n////VU2z/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////s+H//1URd/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553///////n////VU2z/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf///////////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP/////////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/7NNVf///+f//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553////////////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/814Vf/////////////////N////VRGX/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+z4f//VRF3/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+XEVX////N//////+z4f//VRF3/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV///Al/////////////////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////s+H//1URd/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV///Al///////zf///1URl/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf///////////93nuf/VRFV/1URVf9VEVX/s01V////5////////////+f///9VTbP/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf//////+f///9VTbP/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553////////////d57n/1URVf9VEVX//8CX/////////////////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+z4f//VRF3/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/zXhV////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////3ee5//NeFX/////////////////5////1VNs/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////s+H//1URd/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/7NNVf///+f//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf/////////////////////////////////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+zTVX////n//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553////////////d57n///Al//n////VU2z/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+z4f//VRF3/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/lxFV////zf//////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////s+H//1URd/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/7NNVf/N/+f/VRGX/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/5cRVf///83//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf///////////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf//wJf///////////9VeM3/VRFV/1URVf9VEVX/VRFV/1URVf+XEVX////N//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553////////////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+z4f//VRF3/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/NeFX///////////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/lxFV////zf//////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////s+H//1URd/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz///////n////VU2z/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/5cRVf///83//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf///////////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553////////////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+XEVX////N//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553////////////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+z4f//VRF3/1URVf9VEVX/VRFV/1URVf9VEVX/s01V////5///////s+H//1URd/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/lxFV////zf//////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/s01V////5////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+f///9VTbP/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////s+H//1URd/9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////5////1VNs/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/5cRVf///83//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/7NNVf///+f////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////n////VU2z/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/+eed////////////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+XEVX////N//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/zXhV/7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/w==", + "Signature": "", + "Account": "所属组织及以下", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "所属组织及以下", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "252885263003720", + "PositionId": "212725263003002", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "2024-9-13 15:59:32", + "LastLoginIp": "192.168.0.25", + "LastLoginAddress": "内网IP|内网IP", + "LastLoginTime": "2025-1-20 23:50:28.567", + "LastLoginDevice": "PC", + "LatestLoginIp": "192.168.0.25", + "LatestLoginAddress": "内网IP|内网IP", + "LatestLoginTime": "2025-1-21 01:43:24.98", + "LatestLoginDevice": "PC", + "SortCode": "", + "DefaultModule": "", + "CreateTime": "2023-8-14 16:19:30.05", + "UpdateTime": "2024-7-23 09:09:42.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "361405930270789", + "Avatar": "data:image/png;base64,Qk12nAAAAAAAADYAAAAoAAAAZAAAAGQAAAABACAAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAAVRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+XEVX/5//N/1VNs/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV///Al/9VeM3/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX//8CX/////////////////////////////////////////////////////////////////////////////////////////////////////////////////3ee5/93EVX//+Gz/3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+zTVX////n////////////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV///Al////////////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV///Al/////////////////////////////////////////////////////////////////////////////////////////////////////////////////93nuf/zXhV/////////////////83///9VEZf/VRFV/1URVf9VEVX/VRFV/814Vf////////////////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////+f///9VTbP/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/nnnf//////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////l8D//1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////////////////////+XwP//VRFV/1URVf9VEVX/lxFV////zf///////////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////+f///9VTbP/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz/////////////////////////////////1V4zf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/lxFV////zf//////////////////////d57n/1URVf93EVX//+Gz////////////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////+f///9VTbP/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/zXhV///////////////////////////////////////N////VRGX/3cRVf//4bP//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/7NNVf///+f//////+f///9VTbP/VRFV/3cRVf//4bP///////////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////+f///9VTbP/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/zXhV////////////5////1VNs/93EVX//+Gz//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+zeFX/VU2z/1URVf9VEVX/dxFV///hs////////////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////+f///9VTbP/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz////////////l8D//1URVf9VEVX/VRFV/+eed////////////83///9VEZf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/814Vf//////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/5cRVf///83/VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/s01V/83/5/9VEZf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz////////////////////////////////////////////////////////////////////////////l8D//1URVf9VEVX/VRFV/1URVf//wJf///////////////////////////+z4f//VRF3/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/lxFV////zf///////////7Ph//9VEXf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs////////////////////////////////////////////////////////////////////////////5fA//9VEVX/VRFV/1URVf9VEVX/zXhV////////////////////////////////////////////zf///1URl/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/814Vf////////////////////////////////////////////////+XwP//VRFV/3cRVf//4bP//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf/nnnf//////5fA//9VEVX/5553/////////////////+f///9VTbP/dxFV///hs///////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz///////N4f///+HN////////////////////////////s+H//1URd/93EVX//+Gz//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////////////////////////////////////////////////////////////////////////////////////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+zTVX////n/+f///9VTbP/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////////////////////////////////////////////////////////////////////////////////////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/lxFV////zf//////VXjN/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV///Al///////s+H//1URd/9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf/NeFX//////+f///9VTbP/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+XEVX////N//////93nuf/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed///////zf///1URl/9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed///////5////1VNs/9VEVX/VRFV/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/dxFV///hs/////////////////////////////////+z4f//VRF3/1URVf9VEVX/dxFV///hs///////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////////////////////////////////////1V4zf9VEVX/VRFV/1URVf93EVX//+Gz////////////////////////////////////////////////////////////////////////////l8D//1URVf9VEVX/VRFV/7NNVf///+f//////////////////////////////////////3ee5/9VEVX/VRFV/3cRVf//4bP//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+zTVX////n///////////////////////////////////////N////VRGX/1URVf9VEVX/dxFV///hs////////////////////////////////////////////////////////////////////////////5fA//9VEVX/VRFV/1URVf+XEVX////N//////93nuf/VRFV/1URVf9VEVX/5553///////n////VU2z/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/lxFV////zf//////l8D//1URVf9VEVX/VRFV/5cRVf///83//////7Ph//9VEXf/VRFV/3cRVf//4bP//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/814Vf//////5////1VNs/9VEVX/VRFV/5cRVf///83//////5fA//9VEVX/dxFV///hs///////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+zTVX////n//////9VeM3/VRFV/1URVf9VEVX/zXhV////////////d57n/1URVf93EVX//+Gz//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////l8D//1URVf9VEVX/VRFV/1URVf9VEVX//8CX//////+z4f//VRF3/1URVf9VEVX/5553////////////VXjN/3cRVf//4bP//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed///////s+H//1URd/9VEVX/VRFV/3cRVf//4bP//////+f///9VTbP/dxFV///hs///////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/5cRVf///83//////3ee5/9VEVX/VRFV/5cRVf///83//////+f///93TbP//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+XEVX////N//////93nuf/VRFV/1URVf9VEVX/s01V////5///////s+H//3cRd///4bP//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553///////N////VRGX/1URVf9VEVX/5553/83///9VEZf/dxFV///hs///////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/814Vf//////5////1VNs/9VEVX/VRFV/1URVf//wJf/l8D//1URVf93EVX//+Gz//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/5cRVf///83//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/dxFV///hs///////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/zXhV///////n////VU2z/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////93nuf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/814Vf///////////1V4zf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP///////////////////////////////////////////////////////////////////////////+XwP//VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/3cRVf//4bP//////7Ph//9VEXf/VRFV/1URVf9VEVX/dxFV///hs///////////////////////////////////////////////////////////////////////////////////////d57n/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf93EVX//+Gz//////+z4f//VRF3/1URVf9VEVX/VRFV/1URVf93EVX//+Gz////////////////////////////////////////////////////////////////////////////l8D//1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/zXhV////////////VXjN/1URVf9VEVX/VRFV/3cRVf//4bP//////////////////////////////////////////////////////////////////////////////////////3ee5/9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/+eed////////////5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/5cRVf///83//////83///9VEZf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf+XEVX////N/5fA//9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/5553/83///9VEZf/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/1URVf9VEVX/VRFV/w==", + "Signature": "", + "Account": "所属组织", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "所属组织", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "361404296994885", + "PositionId": "361415094177861", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "", + "LastLoginIp": "127.0.0.1", + "LastLoginAddress": "内网IP|内网IP", + "LastLoginTime": "2022-12-7 17:45:07.437", + "LastLoginDevice": "PC", + "LatestLoginIp": "127.0.0.1", + "LatestLoginAddress": "内网IP|内网IP", + "LatestLoginTime": "2022-12-12 10:17:14.463", + "LatestLoginDevice": "PC", + "SortCode": "", + "DefaultModule": "", + "CreateTime": "2023-8-14 16:19:30.05", + "UpdateTime": "2024-7-23 09:09:42.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "361406147739717", + "Avatar": "data:image/png;base64,Qk12nAAAAAAAADYAAAAoAAAAZAAAAGQAAAABACAAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAAVSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM//NfjP/l8P//1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/+zVTP////j/7Pi//9VImD/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM//NfjP//////83///9VIoX/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM//NfjP///////////+Xw///VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/lyIz////xv//////////////////////////////////////////////////////////////////////////////////////l8P//1UiM//NfjP///////////////////////////+z4v//VSJg/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/s1Uz////4////////////////////////////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz///Dhf///////////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM///w4X///////////////////////////////////////////////////////////////////////////////////////////////////////////9Vfsb/VSIz/1UiM/+XIjP////G////////////////////////////VX7G/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM///w4X///////////////////////////93ouP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/93IjP//+Kn////////////VX7G/1UiM/9VIjP/VSIz/81+M///////////////////////d6Lj/7NVM////+P//////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/s1Uz////4///////////////////////l8P//1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/lyIz////xv//////////////////////VX7G/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/5ciM////8b//////83///9VIoX/VSIz/81+M////////////+f///9VVaf/VSIz/1UiM/+zVTP////j//////93ouP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz///Dhf//////////////////////l8P//1UiM/9VIjP/VSIz/1UiM/93IjP//+Kn/////////////////7Pi//9VImD/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/zX4z////////////d6Lj/81+M////////////7Pi//9VImD/VSIz/1UiM/9VIjP/s1Uz////4///////d6Lj/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/+eiYP//////////////////////d6Lj/1UiM//nomD/////////////////s+L//1UiYP9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/3ciM///4qf//////////////////////7Pi//9VImD/VSIz/1UiM/9VIjP/VSIz/7NVM////+P//////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz///Dhf/////////////////////////////////N////VSKF/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/zX4z/////////////////+f///9VVaf/VSIz/1UiM/9VIjP/VSIz/1UiM/+zVTP////j//////93ouP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/s1Uz////4/////////////////+Xw///VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/5ciM////8b///////////93ouP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/s1Uz////4///////d6Lj/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/3ciM///4qf//////////////////////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP//8OF///////N////VSKF/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/7NVM////+P//////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/3ciM///4qf////////////Nw8b/////////////////VX7G/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/81+M////////////1V+xv9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/+zVTP////j/////////////////////////////////////////////////////////////////5fD//9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM///w4X///////////9Vfsb/VSIz/81+M////////////+f///9VVaf/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/+XIjP////G//////+Xw///VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/s1Uz////4/////////////////////////////////////////////////////////////////+Xw///VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM//nomD///////////93ouP/VSIz/1UiM/9VIjP/56Jg////////////zf///1Uihf9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/dyIz///ip///////s+L//1UiYP9VIjP/VSIz/1UiM/9VIjP/VSIz/7NVM////+P//////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/+zVTP////j//////+Xw///VSIz/1UiM/9VIjP/VSIz/1UiM///w4X///////////+Xw///VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM///w4X//////83///9VIoX/VSIz/1UiM/9VIjP/VSIz/1UiM/+zVTP////j//////93ouP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/93IjP//+Kn///////N////VSKF/1UiM/9VIjP/VSIz/1UiM/9VIjP/lyIz////xv//////5////1VVp/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/56Jg///////n////VVWn/1UiM/9VIjP/VSIz/1UiM/9VIjP/s1Uz////4///////d6Lj/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/56Jg////////////VX7G/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM//NfjP///////////+z4v//VSJg/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/7NVM////+P//////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/lyIz////xv//////s+L//1UiYP9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz///Dhf///////////1V+xv9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/+zVTP////j//////93ouP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/+eiYP//////5////1VVp/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/+zVTP////j//////+z4v//VSJg/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/dyIz///ip////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////5fD//9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/5ciM////8b//////5fD//9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz///Dhf//////5////1VVp/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/3ciM///4qf///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+Xw///VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM//nomD//////+f///9VVaf/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/+zVTP////j//////+Xw///VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/+XIjP////G//////+z4v//VSJg/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/dyIz///ip///////zf///1Uihf9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM///w4X//////7Pi//9VImD/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz///Dhf//////s+L//1UiYP9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/zX4z////////////VX7G/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM//NfjP///////////9Vfsb/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP//8OF//////+z4v//VSJg/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM///w4X//////7Pi//9VImD/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz///Dhf//////zf///1Uihf9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/+zVTP/zf/j/1Uihf9VIjP/VSIz/1UiM/9VIjP/s1Uz////4///////l8P//1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz///Dhf//////s+L//1UiYP9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP//8OF//////+z4v//VSJg/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/5ciM////8b//////5fD//9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP//8OF///////n////VVWn/1UiM/9VIjP/VSIz/3ciM///4qf//////83///9VIoX/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM///w4X//////7Pi//9VImD/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz///Dhf//////s+L//1UiYP9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM//NfjP///////////9Vfsb/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/zX4z////////////l8P//1UiM/9VIjP/VSIz/1UiM/9VIjP/56Jg///////n////VVWn/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP//8OF/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7Pi//9VImD/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP//8OF///////N////VSKF/1UiM/9VIjP/VSIz/1UiM/9VIjP/dyIz///ip///////5////1VVp/9VIjP/VSIz/1UiM/9VIjP/VSIz/81+M////////////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz///Dhf////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+z4v//VSJg/1UiM/9VIjP/VSIz/1UiM/9VIjP/lyIz////xv//////s+L//1UiYP9VIjP/VSIz/1UiM/9VIjP/VSIz/+eiYP///////////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/+zVTP////j//////+Xw///VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/56Jg////////////s+L//1UiYP9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/93IjP//+Kn/3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/7NVM////+P//////83///9VIoX/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/lyIz////xv//////s+L//1UiYP9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/s1Uz////4////////////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/3ciM///4qf///////////9Vfsb/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/dyIz///ip////////////3ei4/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz///Dhf+Xw///VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP//8OF/5fD//9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/1UiM/9VIjP/VSIz/w==", + "Signature": "", + "Account": "自定义", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "自定义", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "252885263003720", + "PositionId": "212725263003005", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "", + "LastLoginIp": "127.0.0.1", + "LastLoginAddress": "内网IP|内网IP", + "LastLoginTime": "2022-12-7 17:26:06.2", + "LastLoginDevice": "PC", + "LatestLoginIp": "127.0.0.1", + "LatestLoginAddress": "内网IP|内网IP", + "LatestLoginTime": "2022-12-7 17:45:53.667", + "LatestLoginDevice": "PC", + "SortCode": "", + "DefaultModule": "", + "CreateTime": "2023-8-14 16:19:30.05", + "UpdateTime": "2024-7-23 09:09:42.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "361414413160517", + "Avatar": "data:image/png;base64,Qk12nAAAAAAAADYAAAAoAAAAZAAAAGQAAAABACAAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAARHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT//////2vA4P9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/JqgD//////63r//9Ed0j/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA/47W//9EdwD/RHcA/453AP///7////////////////////////////+O1v//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////////////////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI////////////jtb//0R3AP9EdwD/RHcA/0R3AP/lwEj////////////////////////////l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g/////////////////+X///9EkZz/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z///////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA////////////////////////////a8Dg/0R3AP9EdwD/RHcA/453AP///7//////////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////2vA4P9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP//////////////////////jsDg///rnP///////////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z///////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA///WdP//////////////////////5f///0SRnP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/453AP///7///////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI//////////////////////+t6///RHdI/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA////////////jtb//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0///////l////a5Gc///rnP///////////63r//9Ed0j/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z///////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT///////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0///////J////RHd0/0R3AP9EdwD//9Z0////////////jtb//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v///////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/yaoA///////J////RHd0/0R3AP9EdwD/RHcA/2t3AP//65z///////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/JqgD///////////9rwOD/RHcA/0R3AP9EdwD/rZEA////4P/l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v///////5f///0SRnP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z///////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP//////yf///0R3dP9EdwD/RHcA///WdP//////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////+t6///RHdI/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9rwOD/RHcA/8mqAP//////rev//0R3SP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA///WdP//////yf///0R3dP//1nT//////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+OdwD///+///////+t6///RHdI/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z///////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/JqgD////////////J1uD////g/8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP////////////////////////////////////////////////////////////////////////////////////////////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj/////////////////////////////////////////////////////////////////////////////////////////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z///////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v///////jtb//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z///////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D//////47W//9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0Sqv/9EdwD/RHcA/0R3AP/lwEj/yf///0R3dP9EdwD/RHcA/2t3AP//65z///////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT//////+X///9EkZz/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI////////////5f///0SRnP9rdwD//+uc////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/rZEA////4P//////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v///////rev//0R3SP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD/revg/0R3SP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////////////////////rdb////rnP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj////////////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v/////////////////////////////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z/////////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP//////////////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/453AP///7///////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/8mqAP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D////////////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v////////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0//////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9rwOD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D///////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI//////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v///////jtb//0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA/8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/w==", + "Signature": "", + "Account": "研发1", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "研发1", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "361404296994885", + "PositionId": "361414036955205", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "", + "LastLoginIp": "", + "LastLoginAddress": "", + "LastLoginTime": "", + "LastLoginDevice": "", + "LatestLoginIp": "", + "LatestLoginAddress": "", + "LatestLoginTime": "", + "LatestLoginDevice": "", + "SortCode": "", + "DefaultModule": "", + "CreateTime": "2023-8-14 16:19:30.05", + "UpdateTime": "2024-7-23 09:09:42.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "361414486462533", + "Avatar": "data:image/png;base64,Qk12nAAAAAAAADYAAAAoAAAAZAAAAGQAAAABACAAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAARHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT//////2vA4P9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/JqgD//////63r//9Ed0j/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA/47W//9EdwD/RHcA/453AP///7////////////////////////////+O1v//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////////////////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI////////////jtb//0R3AP9EdwD/RHcA/0R3AP/lwEj////////////////////////////l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g/////////////////+X///9EkZz/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z///////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA////////////////////////////a8Dg/0R3AP9EdwD/RHcA/453AP///7//////////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////2vA4P9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP//////////////////////jsDg///rnP///////////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v////////////////////////////////////////////////////////////////////////////47W//9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA///WdP//////////////////////5f///0SRnP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/453AP///7////////////////////////////////////////////////////////////////////////////+O1v//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/453AP///7///////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI//////////////////////+t6///RHdI/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+OdwD///+/////////////////////////////////////////////////////////////////////////////jtb//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA////////////jtb//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0///////l////a5Gc///rnP///////////63r//9Ed0j/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP//////5f///0SRnP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT///////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0///////J////RHd0/0R3AP9EdwD//9Z0////////////jtb//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT///////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v///////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/yaoA///////J////RHd0/0R3AP9EdwD/RHcA/2t3AP//65z///////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/rZEA////4P//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/JqgD///////////9rwOD/RHcA/0R3AP9EdwD/rZEA////4P/l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v///////5f///0SRnP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj///////////+t6///RHdI/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP//////yf///0R3dP9EdwD/RHcA///WdP//////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////+t6///RHdI/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA///WdP///////////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9rwOD/RHcA/8mqAP//////rev//0R3SP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0/////////////////2vA4P9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA///WdP//////yf///0R3dP//1nT//////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+OdwD///+///////+t6///RHdI/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj/////////////////rev//0R3SP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/JqgD////////////J1uD////g/8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D/////////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP////////////////////////////////////////////////////////////////////////////////////////////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA///WdP////////////////+O1v//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj/////////////////////////////////////////////////////////////////////////////////////////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI/////////////////47W//9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v///////jtb//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/JqgD/////////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP///////////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D//////47W//9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP///////////47W//9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/JqgD///////////+t6///RHdI/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA////////////rev//0R3SP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT//////+X///9EkZz/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+OdwD/a8Cc/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP///////////63r//9Ed0j/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/rZEA////4P//////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v///////rev//0R3SP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD/revg/0R3SP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v/+O1v//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/453AP///7////////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj////////////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/453AP///7////////////9rwOD/RHcA/0R3AP9EdwD/RHcA/8mqAP/////////////////l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z/////////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0////////////////////////////////////////////////////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/453AP///7///////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/8mqAP///////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D////////////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj/////////////////////////////////////////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0//////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9rwOD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D///////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT///////////////////////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v///////jtb//0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA/8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/w==", + "Signature": "", + "Account": "研发2", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "研发2", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "361404296994885", + "PositionId": "361414036955205", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "", + "LastLoginIp": "", + "LastLoginAddress": "", + "LastLoginTime": "", + "LastLoginDevice": "", + "LatestLoginIp": "", + "LatestLoginAddress": "", + "LatestLoginTime": "", + "LatestLoginDevice": "", + "SortCode": "", + "DefaultModule": "", + "CreateTime": "2023-8-14 16:19:30.05", + "UpdateTime": "2024-7-23 09:09:42.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "361406147739717", + "CreateUser": "", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "363085233066053", + "Avatar": "data:image/png;base64,Qk12nAAAAAAAADYAAAAoAAAAZAAAAGQAAAABACAAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAARHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0/0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/8mqAP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI/////////////////////////////////////////////////////////////////////////////////////////////////////////////////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT//////47W//9EdwD/RHcA/0R3AP9EdwD/RHcA/8mqAP///////////+X///9EkZz/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0//////+O1v//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI////////////rev//0R3SP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/8mqAP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA///WdP//////jtb//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT///////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/JqgD//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT//////////////////////////////////////47W//9EdwD/jncA////v///////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0//////////////////////////////////////+O1v//RHcA/0R3AP/JqgD///////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj/////////////////////////////////////////////////////////////////////////////////////////////////////////////////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA///WdP//////jtb//0R3AP9EdwD/RHcA/+XASP//////jtb//0R3AP9EdwD/a3cA///rnP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI/////////////////////////////////////////////////////////////////////////////////////////////////////////////////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT//////47W//9EdwD/RHcA/0R3AP/lwEj//////47W//9EdwD/RHcA/0R3AP/lwEj///////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0//////+O1v//RHcA/0R3AP9EdwD/5cBI//////+O1v//RHcA/0R3AP9EdwD/jncA////v///////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA///WdP//////jtb//0R3AP9EdwD/RHcA/+XASP//////jtb//0R3AP9EdwD/RHcA/2t3AP//65z//////63r//9Ed0j/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT//////47W//9EdwD/RHcA/0R3AP/lwEj//////47W//9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////////////////////////////////////////////////////////////////////////////////////////////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/8mqAP9Eqr///9Z0//////+O1v//RHcA/0R3AP9EdwD/5cBI//////+O1v//RHcA/0R3AP9EdwD/RHcA/8mqAP//////5f///0SRnP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////////////////////////////////////////////////////////////////////////////////////////////////////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/8mqAP//////yf/////Wv///////jtb//0R3AP9EdwD/RHcA/+XASP//////jtb//0R3AP9EdwD/RHcA/0R3AP/JqgD//////+X///9EkZz/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+OdwD///+//////////////////47W//9EdwD/RHcA/0R3AP/lwEj//////47W//9EdwD/RHcA/0R3AP9EdwD/rZEA////4P/l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/rZEA////4P//////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/8mqAP////////////////+O1v//RHcA/0R3AP9EdwD/5cBI//////+O1v//jncA////v/////////////////////////////////////////////////////////////////////////////////////////////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D//////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc////////////jtb//0R3AP9EdwD/RHcA/+XASP//////jtb//453AP///7//////////////////////////////////////////////////////////////////////////////////////////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI//////////////////////////////////////////////////////////////////////////////////////////////////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D//////47W//9EdwD/RHcA/0R3AP/lwEj//////47W//9EdwD/RHcA/0R3AP9EdwD/rZEA////4P//////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/rZEA////4P//////RKq//+XASP//////////////////////////////////////////////////////////////////////////////////////////////////////RKq//0R3AP9EdwD/yaoA///////l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD//9Z0//////////////////////////////////////+O1v//RHcA/0R3AP9EdwD/RHcA/62RAP///+D//////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D//////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/8mqAP//////5f///0SRnP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/8mqAP//////////////////////////////////////jtb//0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/JqgD//////+X///9EkZz/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9rdwD//+uc//////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/rZEA////4P//////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/rZEA////4P/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////rev//0R3SP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D//////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////5f///0SRnP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+OdwD///+//+X///9EkZz/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/8mqAP///////////2vA4P9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP//////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/rZEA////4P//////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/yaoA/63r//9Ed0j/RHcA/0R3AP9EdwD/RHcA/0R3AP+OdwD/yf+//0R3dP9EdwD/RHcA/2t3AP//65z//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP//1nT/a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////63r//9Ed0j/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D//////0Sqv/9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP//////yf///0R3dP9EdwD/RHcA/0R3AP9EdwD/yaoA////////////yf///0R3dP9EdwD/RHcA/0R3AP+OdwD///+////////J////RHd0/0R3AP//1nT///////////9Eqr//5dZ0/0SRnP9EdwD/RHcA/0R3AP/lwEj///////////+t6///RHdI/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/rZEA////4P/l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP+tkQD////g//////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj//////8n///9Ed3T/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj////////////J////RHd0/0R3AP/lwEj////////////J////RHd0/0R3AP9EdwD/RHcA///WdP/J6////+u///////+t6///RHdI/0R3AP//1nT///////////+t6///RHdI/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/453AP///7///////2vA4P9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/rZEA////4P//////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////J////RHd0/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/+XASP///////////8n///9Ed3T/RHcA///WdP+t6///RHdI/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/62RAP///+D//////2vA4P9EdwD/rZEA////4P+O1v//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/a3cA///rnP//////////////////////////////////////////////////////5f///0SRnP//1nT//////////////////////////////////////////////////////////////////////////////////////0Sqv/9EdwD/RHcA/0R3AP9EdwD//9Z0//////////////////////////////////////////////////////////////////////9rwOD/5cBI//////////////////////////////////////////////////////////////////////9rwOD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/2t3AP//65z//////////////////////////////////////////////////////+X///9EkZz//9Z0//////////////////////////////////////////////////////////////////////////////////////9Eqr//RHcA/0R3AP9EdwD/RHcA/2t3AP//65z/////////////////////////////////////////////////////////////////a8Dg/453AP///7//////////////////////////////////////////////////////////////////a8Dg/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/rZEA////4P//////jtb//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI///////l////RJGc/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP/lwEj///////////9Eqr//RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/453AP///7///////47W//9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/jncA////v///////5f///0SRnP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/5cBI////////////RKq//0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/0R3AP9EdwD/RHcA/w==", + "Signature": "", + "Account": "研发部管理员", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "研管", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "e126a5a340f0b9f7bf372f5f212ca0e4", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "361404296994885", + "PositionId": "361415094177861", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "2024-2-4 16:27:36", + "LastLoginIp": "127.0.0.1", + "LastLoginAddress": "内网IP|内网IP", + "LastLoginTime": "2024-2-5 14:37:14", + "LastLoginDevice": "PC", + "LatestLoginIp": "192.168.0.25", + "LatestLoginAddress": "内网IP|内网IP", + "LatestLoginTime": "2024-11-11 15:19:05.53", + "LatestLoginDevice": "PC", + "SortCode": "", + "DefaultModule": "", + "CreateTime": "2023-8-14 16:19:30.05", + "UpdateTime": "2024-7-23 09:09:42.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "511717041197125", + "Avatar": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAABFlJREFUeJzt3E1MFGcAxvGHRoIoLaxa1lDqtOGjVi8QtyHBA4lghGjS9kRNTS9sUps22hPbHtpLDwVOjYeWAyY90AZujTZRW23gYLXJEq1JMUHauAYIS5EFWYObJbEHswPLMrs77Ozsk/r8TjrAzGz+M/O+75BQhEDbUwiNFwp9ApJMQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEzLZCn0C+3A8MwvB4t/zz1yZvoW2g28Ezyo4rQa76+9Ba25j2e/pGh9Hd0ml7332jwwhcGrD8+lx0ESvxWNb7Ky0uQWVZhe3zcIorQcLRCEKRMIC1DxxbjWN2eSHlezdurygtQ/n2nVh68hiLK1Fz+94Xd6FkW3HGY38/diVtsI16O/xbujCc4kqQ94e+Nv+d+MCzywt4rfdU0nYAKdsTd1dwaiLpEZLrI4mVBnUy/9tBPaG7pbOgjyC76IIYHi+e9vyasr21tnHT7ZloUM/R0pPHCE5NmP+v3V0Fw+NFKBLG5MMZc7uvuh7l23dm3J8G9RwtrkSTBu+r/j4YHi8mH86kDOrpgqyfGNgRuDRgK6DTXAmy2VW3/tEUioQxfGfEseNt5dFmpeizo47tKxuuBImsRNOuQ6YfzTt+TKt1TrYKNaV2JUjPyBB6RoYAZF6HODWob9z/eom1TbrXI07eZXbQjSFOr9Q3s3vHSwCevUFgQxPEajC1WqnnwlNaBgCYWvrXkf056blcqZcWlxT6FCzR3CGZ3k1ZjSGhSNjWFPdYna+gC79MChqky9eOkw1HUF2+x3KmZTWGJNidoX3Zthavu6UTHzadwOg/f+LbGxdx5V7Q3gfIgyK3/26v1UrYar6fzYwoW9c/+gbNxkEAwIXx37GvwouGqhrz67dn/sbwnRFzRlgIrtwhx+p8+ODQURx6pQ5vvPyquX0uuoibD8ZxYfxGXo//w3uf4/j+JnNl/+Pt38xfCSTuUl91PRqqatBQVYPTTSdwPfRX0q8N3OLOOqTDb16JsdU4xqYncPHuzbxdiV2+dhypbcSBSgNvVu4zp8ehSBj9f/ycdNzzwcs4H7wM4Fm4w8ZBGB4vDI8Xx/c3uf44c+WR1f/uWbTXv2V51eW6CAtFwvjq2iC+aD2Vsj6JrcZxd+4BfrkXzPodVW+HH28faDbv5thqHB//dM4Ml0+ujyGbuR8YzOnnpx/N4/B3n+LWmX68vmsvZpcXMLU0j7HpiZxeFHb52vFJ8zsAgMZzp3M6x2xRBJE1z+XCkJmCkFEQMgpCRkHIKAgZBSGjIGQUhIyCkFEQMgpCRkHIKAgZBSGjIGQUhIyCkFEQMgpCRkHIKAgZBSGjIGQUhIyCkFEQMgpCRkHIKAgZBSGjIGQUhIyCkFEQMgpCRkHIKAiZ/wCVVIG9+MF24QAAAABJRU5ErkJggg==", + "Signature": "", + "Account": "研发部管理员", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "研发部管理员", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "身份证", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "e126a5a340f0b9f7bf372f5f212ca0e4", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "464837557956677", + "PositionId": "485593012985925", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "", + "LastLoginIp": "", + "LastLoginAddress": "", + "LastLoginTime": "", + "LastLoginDevice": "", + "LatestLoginIp": "", + "LatestLoginAddress": "", + "LatestLoginTime": "", + "LatestLoginDevice": "", + "SortCode": "99", + "DefaultModule": "", + "CreateTime": "2024-2-5 09:22:00.28", + "UpdateTime": "2024-7-23 09:09:42.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "511724397056069", + "Avatar": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAABFxJREFUeJzt3FFoG3UAx/HftCxV13SuWhLjqG0nlbB1SnUd3ea2B9mLteDoGHOzDJUyoQ++TATxRR/cXnwozA0UNzZFrD7MKMgcMlsmrTjKFmgRK6XOkKxdOrhbxxIs+jBya5pekmsulx/u93nqru3dhe/d/f//K2xF24dN/0Jo3FfpE5BsCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZKoqfQLlEjk0iKA/tOzf/3XqF7z55QEXz6g4ngQ5tvc0NjV05P2ZUyMn0NPe63jfp0ZOoP/CUdvvz95KIvXP7aL356uqxpoH6xyfh1s8CTI7dx1xIwbg7gdOz6eRnJvJ+dnF22t8fqzy1eBmyoSZMqztdQ89ipX3ryx47Ej067zBFuvbcXhZF4ZbPAnybuQt6+vMB07OzaDz4+eztgPI2Z65u8YS0axHSKmPJFYa1Mn8bwf1jJ723oo+gpyiCxL0h/Db23/mbN/U0LHk9kI0qJfoZsrEWCJq/Xvtww0I+kOIGzFcvTFlbQ8HNmCVr6bg/jSol8hMGVmD97G9pxH0h3D1xlTOoJ4vyMKJgRP9F446Cug2T4IsddUtfDTFjRjOjX/n2vGW82iz8+yRZtf2VQxPgpi3jbzrkGkz4fox7dY5xarUlNqTICeHj+Pk8HEAhdchbg3qi/e/UGZtk+/1iJt3mRN0Y4jbK/Wl1D6wGsCdNwhsaILYDaZ2K/VS+KtrAQDXzLgr+3PTPblS91VVV/oUbNHcIYXeTdmNIXEj5miKu7lxW0UXfoVUNEhXazd2hV9CfU3AdqZlN4ZkOJ2hvbGlz/q6p70Xu5/eh0t/jWBg9AyGJ4ecfYAyWOH1/9trtxK2m+8XMyMq1qf7v8LGUBsA4Oc/ziNQ+xha6sPW93+fHsOP499bM8JK8OQO2dy4DS+ufxlPBdbjiTVN1vbZW0lEY6MYnDhf1uN/0PkRtjbvtFb2P4x9a/1JIHOXhgMb0FIfRkt9GLuf2YfLf1/K+rOBVzxbqWeuxPR8GuOJKIYmfirbldjV2o3nGjrQ+Mg6NNats6bHcSOGb0a/yDru2SsDOHtlAMCdcBsfb0PQH0IwHMLW5p2eP848eWS9s+t9dDRtt73qSl2ExY0YPrnYj9e39OWsT9LzaUwmJzA8OVT0O6q+HYex/ckXrLs5PZ/GkXPvWeHKyfMxZCmRQ4Ml/f60mcBrZ/bg84MRhGrX4vrcDKbNBMYT0ZJeFHa1dmNP26sAgFc+6yzpHItFEUTuuicXhswUhIyCkFEQMgpCRkHIKAgZBSGjIGQUhIyCkFEQMgpCRkHIKAgZBSGjIGQUhIyCkFEQMgpCRkHIKAgZBSGjIGQUhIyCkFEQMgpCRkHIKAgZBSGjIGQUhIyCkFEQMgpCRkHI/AdcyoGMDQFIagAAAABJRU5ErkJggg==", + "Signature": "", + "Account": "萝卜科技管理员", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "萝卜科技管理员", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "身份证", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "359569393872965", + "PositionId": "359569658515525", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "", + "LastLoginIp": "", + "LastLoginAddress": "", + "LastLoginTime": "", + "LastLoginDevice": "", + "LatestLoginIp": "", + "LatestLoginAddress": "", + "LatestLoginTime": "", + "LatestLoginDevice": "", + "SortCode": "99", + "DefaultModule": "", + "CreateTime": "2024-2-5 09:51:56.147", + "UpdateTime": "2024-7-23 09:09:42.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "511724553736261", + "Avatar": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAABF1JREFUeJzt3FFoG3UAx/FfZWzrxLVr3Nhk2alTVyuhLQ6HBlrsxqJWEOeLsiKM4iYolD20A1HHUEZXEbcXmULRh1kYSAsT6SpzWCHiRkZbhSljlh1Za9cQl3TQGinow8itaXpJrrlcfrjf56m9pncXvnf3v/8FUrF/Hf6F0Lin3DsgmRSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcisKPcOlMrRsWvw+Y1l///vw9/jk5d3ubhHhfEkyMGBc6ht3pnzNUMnehDq6HK87qETPeg/csj277di0/jn77mC17dydSXuW7/B8X64xZMgM7EbiEdNAHfe8HwqheT0VNZrFy9fU1WNyrVVmJtJYjaZsJZXbdiIFatW5d32T31f5gy22J7Dx5Z1YLjFkyC9+/daP6ffcHJ6Cu/UP5ixHEDW8vTZZY5EMi4hxV6SWGlQJ/O/HdTTQh1dZb0EOUUXxOc38Nlf2d+HU9u8c8nl+WhQL9LcTBLmSMT6ff3Dj8DnNxCPmoiNX7WWG43bUbm2Ku/6NKgXaTaZyBi8Dw6cg89vIDZ+NWtQzxVk4Y2BE/1HDjkK6DZPgix11C28NMWjJiL9p13b3nIubXYO1FS4tq5CeBJkNnkz5zwkMTnh+jbt5jmFKtcttSdBzh7vxtnj3QDyz0PcGtQXr3+h9Nwm1+MRN88yJ+jGELdn6ku5t8YH4PYTBDY0QewGU7uZejHWVK8DANycuO7K+tx0V87UV66uLPcu2KI5Q/I9m7IbQ+JR09Etbl1LqKwTv3zKGiTY1o6nXnkN1Q9str3TshtD0pzeob3Y+b71c6ijC037DuBKeBg/9H6Ky+eHnL2BEqjw+nt77WbCdvf7hdwRFaprMIytO54BAIwNnkHN5i3wBxqsv0d/HUVk4LR1R1gOnpwhdS0hPP3q69hS/yQ2PrrNWn4rNo3xyM8YGzxT0u23f/4VArtbrZn9xa/7rI8E0mep0bgd/kAD/IEGNO17E39cCGd8bOAVj2bq3daROJ9KwRy9hF+GvinZkRhsa0dtUws2bavDpscet26P41ETP35xMmO74VO9CJ/qBXA73NYdQfj8Bnx+A4HdrZ5fzjy5ZO39+CSe2PWc7VFX7CQsHjXx7UcfoLXzvaz5yXwqhT+v/IbL578r+BnVnsPHUP/CS9bZPJ9Koa/zLStcKXk+hizl6Ni1ov4/MTmBnueDeHd4BPcbDyF5YwqJyeswRy8V9aAw2NaOZ994GwDwYXNjUftYKIogcsddOTFkpiBkFISMgpBREDIKQkZByCgIGQUhoyBkFISMgpBREDIKQkZByCgIGQUhoyBkFISMgpBREDIKQkZByCgIGQUhoyBkFISMgpBREDIKQkZByCgIGQUhoyBkFISMgpBREDIKQuY/u06CTgWqX4UAAAAASUVORK5CYII=", + "Signature": "", + "Account": "旺仔科技管理员", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "旺仔科技管理员", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "身份证", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "510752889880645", + "PositionId": "511723823370309", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "2024-2-19 15:53:43", + "LastLoginIp": "127.0.0.1", + "LastLoginAddress": "内网IP|内网IP", + "LastLoginTime": "2024-2-23 10:50:42", + "LastLoginDevice": "PC", + "LatestLoginIp": "127.0.0.1", + "LatestLoginAddress": "内网IP|内网IP", + "LatestLoginTime": "2024-2-23 15:47:54.05", + "LatestLoginDevice": "PC", + "SortCode": "99", + "DefaultModule": "", + "CreateTime": "2024-2-5 09:52:34.397", + "UpdateTime": "2024-7-23 09:09:42.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "511724668047429", + "Avatar": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAABE1JREFUeJzt3O9vE3UAx/EPMuo6SrZyDmG/+oDC6oTMZIuLLLKgJguZiYFHRh9KMDzkiRj/AKOPfIzRhxIfoU8I8EAz1GlmSrItsTpgxOomhq3punY7qG3wAem5rru2116vn8jn9Wi7bndt3nf3/X5vyXacvXDxEYTGU81+A1JMQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSETEuz30CjfHjhLRjBQM2//9udJXzy2RUX31F1PAly/swEIuHusj9z/cYsxscGHe/7+o1ZXL46bft6OmMi+0++6v35du3EnoDf8ftwiydB1jImEskMgP8+cC6XRyptlvzs1u1tfh/8rT6YD7LYMLPW9vY9frS07Kx47B9v3iobbKvTJ0dqOjHc4kmQz7/81vq68IFTaRMffHypaDuAku2Fqyu+uFx0C6n3lsRKgzqZ/+2gXjA+NtjUW5BTdEGMYAAXPzpbsj0S7t52eyUa1OtkPsgivrhsfd9ptMMIBpBIZrCcSFnbQz2d8Lf6Ku5Pg3qdNsxs0eB9/swEjGAAy4lUyaBeLsjmiYETl69OOwroNk+CbHfWbb41JZIZROcWXDteLbc2O+++/6lr+6qGJ0E2zIdl1yGra+uuH9NunVOtZk2pPQlybXIG1yZnAFReh7g1qG/d/2aFtU25xyNuXmVO0I0hbq/Ut7O7rRXA4ycIbGiC2A2mdiv1erT5nwYAJFPu3yrr9USu1H27aruyvEBzhVR6NmU3hiSSGUdT3IFDPU1d+FXS1CCjw/148YUwOtp328607MaQAqcztNdfG7K+Hh8bxPGR53Dr7j1M/vQLYrcXnX2ABtjh9f/ttVsJ2833q5kRVeu9c2/gYOhZAMBsLI69HQH0dhnW63/+lUB0bsGaETaDJ1fIwKEevDR0GH3dz2B/Z4e1PZ0xcfeP+5iN/d7Q47/z5is4GumzVvY/z9yx/iRQuEpDPZ3o7TLQ22Xg+MgAFuJ/F/3ZwCuerdQLZ2Iul0d8aQVzv8YbdiaODvcjEu7GgX1BHNjXYU2PE8kMvpuOFR13KjqPqeg8gMfhDob2wwgGYATDOBrp8/x25skt6+1TL+P5w722Z129i7BEMoMr39zExKtDJeuTXC6Pe/dXEbu9WPUzqtMnRzA4ELKu5lwuj0tf/2CFayRPrpAvvvq+7OuFxyq1Wl1bx1R0HieOHUGb34eVZBqrqXXEl1ZqelBYWBONDvfjxLEjAOBJDKAJg7qU90QuDJkpCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQ+RdFsYZDcg+0XAAAAABJRU5ErkJggg==", + "Signature": "", + "Account": "达达科技管理员", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "达达科技管理员", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "身份证", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "510753093025861", + "PositionId": "511723919061061", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "2024-9-11 23:55:59.987", + "LastLoginIp": "", + "LastLoginAddress": "", + "LastLoginTime": "", + "LastLoginDevice": "", + "LatestLoginIp": "192.168.0.25", + "LatestLoginAddress": "内网IP|内网IP", + "LatestLoginTime": "2024-9-11 23:55:59.913", + "LatestLoginDevice": "PC", + "SortCode": "99", + "DefaultModule": "", + "CreateTime": "2024-2-5 09:53:02.307", + "UpdateTime": "2024-7-23 09:09:42.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "511724755705925", + "Avatar": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAABFZJREFUeJzt3O9rG3UAx/HPtC72x7LZzKZTuzDDRmldtWwaNDA2cbRghbEnHdhnDsVHsicT/QP8sSf+eCLCfDale7InU0gVJAidnRRKK3aSbY5MnYlt1jRpMmNT9MG4s2l6+Xm5fHCf16P00t5deN/d974X6JZXX3jvHwiN+5q9A1JIQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSEjIKQURAyCkJGQcgoCBkFIaMgZBSETEuzd6BR3jn3Ojxed81///NMFB+cHrdxjyrjSJBTZ06gd9BX8ncmzl/G0Gig6nVPnL+MC2fDlu+nk1n8nctXvL6trhZs29FW9X7YxZEgqaUMEvEUgP8+cH51Dcu3M0W/u3F5W4cLre0u3MnkkF3Jmcu3d7aj5YH7y2770sSPJYNtdPzk4ZoODLs4EuSzdy+ar40PvHw7g7fHPilYDqBouXF2RSOxgktIvZckVhrUyfxvB3XD0GigqZegatEF8Xjd+PSbN4uW9w76Nl1ejgb1Ot3J5BCNxMyfH37kIXi8biTiKSzcWjKX+/Z1o7XdVXZ9GtTrlF3JFQzep86cgMfrxsKtpaJBvVSQ9TcG1bhwNlxVQLs5EmSzo279pSkRT2E6fMW27dVyabPy2tH3bVtXJRwJkl35q+Q8JLmYtn2bVvOcSjXrltqRIKHxKYTGpwCUn4fYNahvXP96xtym1OMRO8+yatCNIXbP1DfT7m4FcPcJAhuaIFaDqdVMvR5tHQ8CAJYW7L9U1uuenKlvddEch0Vo9qzcsymrMSQRT1V1i9t3cE9TJ37lNDVIcHgAzzzfhx07t1neaVmNIYZq79BGxoLm66HRAA6NPIXI7E2EL85gfvpGdR+gAbY4/X97rWbCVvf7ldwRVer0h2Pw9z8KAJi9dBWd3u3o8XeZ7/96/U9Mh6+Yd4TN4MgZ0ndwD549+gR27+1Gd0+nuTydzOKX+d8x+/21hm7/lbdewv6A35zZ//DtvPmVgHGW+vZ1o8ffhR5/Fw6NDOL6T78VfG3gFMdm6saRmF9dQzQSw9zUtYYdicHhAfQO+rDLtxO7dnvM2+NEPIXvvpwp2O5kaA6ToTkAd8P5+x+Dx+uGx9uH/QG/45czRy5ZL78xhP6nH7c86uqdhCXiKXx1bhIvjgWL5if51TX8cTOB+ekbFT+jOn7yMJ58bq95NudX1/DFx1+b4RrJkTPk848mSr5vPFapVXIxjcnQHI4cO4C2DhcWY8tILqYRjcRqelBozImCwwM4cuwAADgSA2jCoC6l3ZMTQ2YKQkZByCgIGQUhoyBkFISMgpBREDIKQkZByCgIGQUhoyBkFISMgpBREDIKQkZByCgIGQUhoyBkFISMgpBREDIKQkZByCgIGQUhoyBkFISMgpBREDIKQkZByCgIGQUhoyBk/gX5tIZuRn97CgAAAABJRU5ErkJggg==", + "Signature": "", + "Account": "杰尼科技管理员", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "杰尼科技管理员", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "身份证", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "510753219502149", + "PositionId": "511723963043909", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "", + "LastLoginIp": "", + "LastLoginAddress": "", + "LastLoginTime": "", + "LastLoginDevice": "", + "LatestLoginIp": "", + "LatestLoginAddress": "", + "LatestLoginTime": "", + "LatestLoginDevice": "", + "SortCode": "99", + "DefaultModule": "", + "CreateTime": "2024-2-5 09:53:23.707", + "UpdateTime": "2024-7-23 09:09:42.967", + "CreateUserId": "212725263002001", + "UpdateUserId": "", + "CreateUser": "superAdmin", + "UpdateUser": "", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + }, + { + "Id": "518189781848133", + "Avatar": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAABJJJREFUeJzt3G9oG3Ucx/FPJXorsr9hY2wL0QdztaO04lAwsGBblo7hyoIgNHngFlyHKFuQdUWUtiDDOEcV17o6gjLaqeAaXBk1I+2MkEnHcCvBtg4Ki3G26+ifi5DuIDAflMbGJTXdkt4n8n09S+9y9+u9e73fXSBFB9fiPgSNx/QegEglQchIEDIShIwEISNByEgQMhKEjAQhI0HISBAyEoSMBCEjQchIEDIShIwEISNByEgQMhKEjAQhI0HISBAyEoSMBCEjQchIEDIShIwEISNByEgQMhKEjAQhI0HISBAyEoSMBCEjQcjQBbE3edAxdR/HB28taX23L5DfgS0TuiB6sDd50DZ2jyKqQe8B6MnidGHX20exces2vYeSVDBBjg/egtFkzri8xFqFjqn0X0rh//QjdLccS752nDyNp3e8CFNZRc7H+agogrh9AZRYq1J+ZjSZkwd4JNiHmT9vp33vEyuKsXL9BszGVMTVmbTrxNXpjPsaCfY9sG89UQSJ3b2DyWgEwD8HOKFpUCfGk8u9Bx1p32tv8sB2uAGR69fQuq86631Gwzdw+cwphDq9Gc8sPVAEWXiw5w+wOjGOd8ufyvm+rp7/Gv7PTmCo35/zbecCRZDlFOr06j2ERRXEtLe00qb3EJYN9Rni+qILZbv24KcvO+Bs7VjyLGsyGsnLv718oguydvMWAHOzLKPJjISmIa5OY3QghPjMNExlFfjr7gRuD4UzbmPNpi1U9xZLQRHE4nShfPdePGOxonjVagBAQtPwa78fP3rbUy7AbWP3YFCURWdU7wWvAwBGB0L5HXgeUFxDXn7jLZTv3ovHlRXJ6a86MY52R+0Ds6Gxm8MoXrUa9iZP2m3VHGmEqawCszE141SZGUWQqT9+x0iwD22OWlzr/nbRdS+fOQUA2GF/Le3ynfsPAQDCly7mdpDLhCJIu6MWrfuqs7o3CHV6EQ3fgNFkxptd36csc/sCMJrMmIxGCvLsAEiCLFV3SyMSmobtlTbUHGkEMDcjK7FWIaFp6HTX6zzCh1eQQYb6/fil5zwMioJXjjXD7QvghVfrkNA09Hiaae/Cs1GQQYC5xy2jA1dgUJTkmdHjacYPn3yo99AeScEGsThdeHKdMfnaoCh41pr9w0VWBRektNIGty+AuhNt2Lh1GyajEQz2XkBC01BircLHv93JOCUuBBQ3hgvN3xj+m8XpgsVxAOaK52FQFMzGVFw59xW63jmUXL7n6PswmsywHW7AS3WvYzgYwM/fnP3Pa0r9uqKc/x4Pq4jhu9/nH7kvNNh7Ae2OWpRW2nDg87NYuX4DAGA2piJ86eKin4/s3F+fEvbqd+cKZhpMEQRA8sFgQtMwdnMY3S2Nyb/sht4Q1mzajNGBUNYH1nHyNLZX1yA+M40PrM/lbdy5RhNEzCm4i/r/nQQhI0HISBAyEoSMBCEjQchIEDIShIwEISNByEgQMhKEjAQhI0HISBAyEoSMBCEjQchIEDIShIwEISNByEgQMhKEjAQhI0HISBAyEoSMBCEjQchIEDIShIwEISNByEgQMhKEzN96BFLRl5sEoAAAAABJRU5ErkJggg==", + "Signature": "", + "Account": "旺仔科技1", + "Password": "c1c4766b4aa8340df0efa38ff9b50011", + "Name": "旺仔科技1", + "Nickname": "", + "Gender": "男", + "Birthday": "", + "Nation": "", + "NativePlace": "", + "HomeAddress": "", + "MailingAddress": "", + "IdCardType": "身份证", + "IdCardNumber": "", + "CultureLevel": "", + "PoliticalOutlook": "", + "College": "", + "Education": "", + "EduLength": "", + "Degree": "", + "Phone": "", + "Email": "", + "HomeTel": "", + "OfficeTel": "", + "EmergencyContact": "", + "EmergencyPhone": "", + "EmergencyAddress": "", + "EmpNo": "", + "EntryDate": "", + "OrgId": "517088662995013", + "PositionId": "517095081300037", + "PositionLevel": "", + "DirectorId": "", + "PwdRemindUpdateTime": "2024-2-23 16:19:56", + "LastLoginIp": "127.0.0.1", + "LastLoginAddress": "内网IP|内网IP", + "LastLoginTime": "2024-2-23 16:19:56.733", + "LastLoginDevice": "PC", + "LatestLoginIp": "127.0.0.1", + "LatestLoginAddress": "内网IP|内网IP", + "LatestLoginTime": "2024-2-23 16:20:34.887", + "LatestLoginDevice": "PC", + "SortCode": "99", + "DefaultModule": "", + "CreateTime": "2024-2-23 16:19:39.23", + "UpdateTime": "2024-2-23 16:20:26.987", + "CreateUserId": "212725263002001", + "UpdateUserId": "212725263002001", + "CreateUser": "superAdmin", + "UpdateUser": "superAdmin", + "IsDelete": "0", + "ExtJson": "", + "Status": "ENABLE" + } + ] +} \ No newline at end of file diff --git a/SimpleAdmin.System/SeedData/SysConfigSeedData.cs b/SimpleAdmin.System/SeedData/SysConfigSeedData.cs new file mode 100644 index 0000000..ae061cd --- /dev/null +++ b/SimpleAdmin.System/SeedData/SysConfigSeedData.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 系统配置种子数据 +/// +public class SysConfigSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_sys_config.json"); + } +} diff --git a/SimpleAdmin.System/SeedData/SysDictSeedData.cs b/SimpleAdmin.System/SeedData/SysDictSeedData.cs new file mode 100644 index 0000000..165310f --- /dev/null +++ b/SimpleAdmin.System/SeedData/SysDictSeedData.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 字典表种子数据 +/// +public class SysDictSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_sys_dict.json"); + } +} diff --git a/SimpleAdmin.System/SeedData/SysOrgSeedData.cs b/SimpleAdmin.System/SeedData/SysOrgSeedData.cs new file mode 100644 index 0000000..ce90ef7 --- /dev/null +++ b/SimpleAdmin.System/SeedData/SysOrgSeedData.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 机构种子数据 +/// +public class SysOrgSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_sys_org.json"); + } +} diff --git a/SimpleAdmin.System/SeedData/SysPositionSeedData.cs b/SimpleAdmin.System/SeedData/SysPositionSeedData.cs new file mode 100644 index 0000000..7aecffe --- /dev/null +++ b/SimpleAdmin.System/SeedData/SysPositionSeedData.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 职位表种子数据 +/// +public class SysPositionSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_sys_position.json"); + } +} diff --git a/SimpleAdmin.System/SeedData/SysRelationSeedData.cs b/SimpleAdmin.System/SeedData/SysRelationSeedData.cs new file mode 100644 index 0000000..35187ea --- /dev/null +++ b/SimpleAdmin.System/SeedData/SysRelationSeedData.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 关系表种子数据 +/// +public class SysRelationSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_sys_relation.json"); + } +} diff --git a/SimpleAdmin.System/SeedData/SysResourceSeedData.cs b/SimpleAdmin.System/SeedData/SysResourceSeedData.cs new file mode 100644 index 0000000..d2178e4 --- /dev/null +++ b/SimpleAdmin.System/SeedData/SysResourceSeedData.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 资源表种子数据 +/// +public class SysResourceSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_sys_resource.json"); + } +} diff --git a/SimpleAdmin.System/SeedData/SysRoleSeedData.cs b/SimpleAdmin.System/SeedData/SysRoleSeedData.cs new file mode 100644 index 0000000..67b932f --- /dev/null +++ b/SimpleAdmin.System/SeedData/SysRoleSeedData.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 角色种子数据 +/// +public class SysRoleSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_sys_role.json"); + } +} diff --git a/SimpleAdmin.System/SeedData/SysUserSeedData.cs b/SimpleAdmin.System/SeedData/SysUserSeedData.cs new file mode 100644 index 0000000..8890f1e --- /dev/null +++ b/SimpleAdmin.System/SeedData/SysUserSeedData.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 用户表种子数据 +/// +public class SysUserSeedData : ISqlSugarEntitySeedData +{ + public IEnumerable SeedData() + { + return SeedDataUtil.GetSeedData("seed_sys_user.json"); + } +} diff --git a/SimpleAdmin.System/Services/Auth/Auth/AuthService.cs b/SimpleAdmin.System/Services/Auth/Auth/AuthService.cs new file mode 100644 index 0000000..8757982 --- /dev/null +++ b/SimpleAdmin.System/Services/Auth/Auth/AuthService.cs @@ -0,0 +1,502 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System.Services.Auth; + +/// +public class AuthService : IAuthService +{ + private readonly ISimpleCacheService _simpleCacheService; + private readonly IEventPublisher _eventPublisher; + private readonly IConfigService _configService; + private readonly ISysUserService _userService; + private readonly ISysOrgService _sysOrgService; + + public AuthService(ISimpleCacheService simpleCacheService, IEventPublisher eventPublisher, IConfigService configService, + ISysUserService userService, ISysOrgService sysOrgService) + { + _simpleCacheService = simpleCacheService; + _eventPublisher = eventPublisher; + _configService = configService; + _userService = userService; + _sysOrgService = sysOrgService; + } + + /// + public async Task GetCaptchaInfo() + { + var config = await _configService.GetByConfigKey(CateGoryConst.CONFIG_LOGIN_POLICY, SysConfigConst.LOGIN_CAPTCHA_TYPE); + var captchaType = (CaptchaType)Enum.Parse(typeof(CaptchaType), config.ConfigValue); + //生成验证码 + var captchaInfo = CaptchaUtil.CreateCaptcha(captchaType, 4, 100, 38); + //生成请求号,并将验证码放入缓存 + var reqNo = AddValidCodeToRedis(captchaInfo.Code); + //返回验证码和请求号 + return new PicValidCodeOutPut + { + ValidCodeBase64 = captchaInfo.Base64Str, + ValidCodeReqNo = reqNo + }; + } + + /// + public async Task GetPhoneValidCode(GetPhoneValidCodeInput input, LoginClientTypeEnum loginClientType) + { + await ValidPhoneValidCode(input, loginClientType);//校验手机号验证码 + var phoneValidCode = RandomHelper.CreateNum(6);//生产随机数字; + + + #region 发送短信和记录数据库等操作 + + //这里为什么不封装阿里云或者腾讯云短信接口,是因为短信发送是一个通用功能,一般每个公司都有自己封装好的短信组件来适配各种项目,这里再封装一次显得多余了。 + //这里不建议在该系统中封装短信发送接口,当然后续如果确实有需要也会增加 + //这里执行发送短信验证码代码,这里先默认就是年月日 + phoneValidCode = DateTime.Now.ToString("yyMMdd"); + + #endregion 发送短信和记录数据库等操作 + + //生成请求号,并将验证码放入缓存 + var reqNo = AddValidCodeToRedis(phoneValidCode); + return reqNo; + } + + /// + public async Task Login(LoginInput input, LoginClientTypeEnum loginClientType) + { + await CheckCaptcha(input);//检查验证码 + await CheckWebOpen(input);//检查网站是否开启 + var password = CryptogramUtil.Sm2Decrypt(input.Password);//SM2解密 + //获取多租户配置 + var isTenant = await _configService.IsTenant(); + //获取登录策略 + var loginPolicy = await _configService.GetConfigsByCategory(CateGoryConst.CONFIG_LOGIN_POLICY); + await BeforeLogin(loginPolicy, input, isTenant);//登录前校验 + // 根据账号获取用户信息,根据B端或C端判断 + if (loginClientType == LoginClientTypeEnum.B)//如果是B端 + { + var userInfo = await _userService.GetUserByAccount(input.Account, input.TenantId);//获取用户信息 + if (userInfo == null) throw Oops.Bah("用户不存在");//用户不存在 + if (userInfo.Password != password) + { + LoginError(loginPolicy, input, isTenant);//登录错误操作 + throw Oops.Bah("账号密码错误");//账号密码错误 + } + var result = await ExecLoginB(userInfo, input.Device, loginClientType, input.TenantId);// 执行B端登录 + return result; + } + //执行c端登录 + return null; + } + + /// + public async Task LoginByPhone(LoginByPhoneInput input, LoginClientTypeEnum loginClientType) + { + await ValidPhoneValidCode(input, loginClientType, false);//校验手机号和验证码,这里不删除Redis,防止输入错误又要重新输入验证码 + // 根据手机号获取用户信息,根据B端或C端判断 + if (loginClientType == LoginClientTypeEnum.B)//如果是B端 + { + var userInfo = await _userService.GetUserByPhone(input.Phone);//获取信息 + if (userInfo == null) throw Oops.Bah("用户不存在");//用户不存在 + var result = await ExecLoginB(userInfo, input.Device, loginClientType, input.TenantId);// 执行B端登录 + RemoveValidCodeFromRedis(input.ValidCodeReqNo);//删除验证码 + return result; + } + //执行c端登录 + return null; + } + + /// + public async Task LoginOut(string token, LoginClientTypeEnum loginClientType) + { + //获取用户信息 + var userinfo = await _userService.GetUserByAccount(UserManager.UserAccount, UserManager.TenantId); + if (userinfo != null) + { + var loginEvent = new LoginEvent + { + Ip = App.HttpContext.GetRemoteIpAddressToIPv4(), + SysUser = userinfo, + Token = token + }; + RemoveTokenFromRedis(loginEvent, loginClientType);//移除token + //发布登出事件总线 + await _eventPublisher.PublishAsync(EventSubscriberConst.LOGIN_OUT_B, loginEvent); + } + } + + /// + public async Task GetLoginUser() + { + var userInfo = await _userService.GetUserByAccount(UserManager.UserAccount, UserManager.TenantId);//根据账号获取用户信息 + if (userInfo != null) + { + userInfo.Avatar = await _userService.GetUserAvatar(userInfo.Id);//获取头像 + return userInfo.Adapt(); + } + return null; + } + + #region 方法 + + /// + /// 检查验证码 + /// + /// + /// + public async Task CheckCaptcha(LoginInput input) + { + //判断是否有验证码 + var sysBase = await _configService.GetByConfigKey(CateGoryConst.CONFIG_LOGIN_POLICY, SysConfigConst.LOGIN_CAPTCHA_OPEN); + if (sysBase != null)//如果有这个配置项 + { + if (sysBase.ConfigValue.ToBoolean())//如果需要验证码 + { + //如果没填验证码,提示验证码不能为空 + if (string.IsNullOrEmpty(input.ValidCode) || string.IsNullOrEmpty(input.ValidCodeReqNo)) + throw Oops.Bah("验证码不能为空").StatusCode(410); + ValidValidCode(input.ValidCode, input.ValidCodeReqNo);//校验验证码 + } + } + } + + /// + /// 检查网站是否开启 + /// + /// + /// + public async Task CheckWebOpen(LoginInput input) + { + //判断是否开启web访问 + var webStatus = await _configService.GetByConfigKey(CateGoryConst.CONFIG_SYS_BASE, SysConfigConst.SYS_WEB_STATUS); + if (webStatus != null && webStatus.ConfigValue == CommonStatusConst.DISABLED + && input.Account.ToLower() != SysRoleConst.SUPER_ADMIN.ToLower())//如果禁用了网站并且不是超级管理员 + { + var closePrompt = await _configService.GetByConfigKey(CateGoryConst.CONFIG_SYS_BASE, SysConfigConst.SYS_WEB_CLOSE_PROMPT); + throw Oops.Bah(closePrompt.ConfigValue); + } + } + + /// + /// 登录之前执行的方法 + /// + /// + /// + /// + public async Task BeforeLogin(List loginPolicy, LoginInput input, bool isTenant) + { + var lockTime = loginPolicy.First(x => x.ConfigKey == SysConfigConst.LOGIN_ERROR_LOCK).ConfigValue.ToInt();//获取锁定时间 + var errorCount = loginPolicy.First(x => x.ConfigKey == SysConfigConst.LOGIN_ERROR_COUNT).ConfigValue.ToInt();//获取错误次数 + var key = SystemConst.CACHE_LOGIN_ERROR_COUNT;//获取登录错误次数Key值 + //如果是关闭多租户则直接用账号 + if (!isTenant) + key += input.Account; + else + { + //如果租户ID为空表示用域名登录 + if (input.TenantId == null) + { + //获取域名 + var origin = App.HttpContext.Request.Headers["Origin"].ToString(); + // 如果Origin头不存在,可以尝试使用Referer头作为备选 + if (string.IsNullOrEmpty(origin)) + origin = App.HttpContext.Request.Headers["Referer"].ToString(); + //根据域名获取二级域名 + var domain = origin.Split("//")[1].Split(".")[0]; + //根据二级域名获取租户 + var tenantList = await _sysOrgService.GetTenantList(); + var tenant = tenantList.FirstOrDefault(x => x.Code.ToLower() == domain);//获取租户默认是机构编码 + if (tenant != null) + input.TenantId = tenant.Id; + else + throw Oops.Bah("租户不存在"); + } + //如果是手动选择多租户则用账号+租户 + key += $"{input.TenantId}:{input.Account}"; + } + var errorCountCache = _simpleCacheService.Get(key);//获取登录错误次数 + if (errorCountCache >= errorCount) + { + _simpleCacheService.SetExpire(key, TimeSpan.FromMinutes(lockTime));//设置缓存 + throw Oops.Bah($"密码错误次数过多,请{lockTime}分钟后再试"); + } + } + + /// + /// 登录错误操作 + /// + /// + /// + /// + public void LoginError(List loginPolicy, LoginInput input, bool isTenant) + { + var resetTime = loginPolicy.First(x => x.ConfigKey == SysConfigConst.LOGIN_ERROR_RESET_TIME).ConfigValue.ToInt();//获取重置时间 + var key = SystemConst.CACHE_LOGIN_ERROR_COUNT;//获取登录错误次数Key值 + //如果是关闭多租户则直接用账号 + if (!isTenant) + key += input.Account; + else + { + //如果是手动选择多租户则用账号+租户 + key += $"{input.TenantId}:{input.Account}"; + } + _simpleCacheService.Increment(key, 1);// 登录错误次数+1 + _simpleCacheService.SetExpire(key, TimeSpan.FromMinutes(resetTime));//设置过期时间 + } + + /// + /// 校验验证码方法 + /// + /// 验证码 + /// 请求号 + /// 是否从Redis删除 + public void ValidValidCode(string validCode, string validCodeReqNo, bool isDelete = true) + { + var key = SystemConst.CACHE_CAPTCHA + validCodeReqNo;//获取验证码Key值 + var code = _simpleCacheService.Get(key);//从缓存拿数据 + if (isDelete) RemoveValidCodeFromRedis(validCodeReqNo);//如果需要删除验证码 + if (code != null && validCode != null)//如果有 + { + //验证码如果不匹配直接抛错误,这里忽略大小写 + if (validCode.ToLower() != code.ToLower()) throw Oops.Bah("验证码错误"); + } + else + { + throw Oops.Bah("验证码不能为空");//抛出验证码不能为空 + } + } + + /// + /// 从Redis中删除验证码 + /// + /// + public void RemoveValidCodeFromRedis(string validCodeReqNo) + { + var key = SystemConst.CACHE_CAPTCHA + validCodeReqNo;//获取验证码Key值 + _simpleCacheService.Remove(key);//删除验证码 + } + + /// + /// 校验手机验证码 + /// + /// 输入参数 + /// 登录端类型 + /// 是否删除 + /// + public async Task ValidPhoneValidCode(GetPhoneValidCodeInput input, LoginClientTypeEnum loginClientType, bool isDelete = true) + { + ValidValidCode(input.ValidCode, input.ValidCodeReqNo, isDelete);//校验验证码 + if (loginClientType == LoginClientTypeEnum.B)//B端登录 + { + var userId = await _userService.GetIdByPhone(input.Phone);//获取用户名 + if (userId == 0) + { + throw Oops.Bah("手机号不存在");//手机号不存在 + } + } + else + { + //校验C段用户手机号 + throw Oops.Bah("手机号不存在");//手机号不存在 + } + } + + /// + /// 添加验证码到缓存 + /// + /// 验证码 + /// 过期时间 + /// 验证码请求号 + public string AddValidCodeToRedis(string code, int expire = 5) + { + //生成请求号 + var reqNo = CommonUtils.GetSingleId().ToString(); + //插入缓存 + _simpleCacheService.Set(SystemConst.CACHE_CAPTCHA + reqNo, code, TimeSpan.FromMinutes(expire)); + return reqNo; + } + + /// + /// 执行B端登录 + /// + /// 用户信息 + /// 登录设备 + /// 登录类型 + /// 租户id + /// + public async Task ExecLoginB(SysUser sysUser, AuthDeviceTypeEnum device, LoginClientTypeEnum loginClientType, + long? tenantId) + { + if (sysUser.Status == CommonStatusConst.DISABLED) + throw Oops.Bah("账号已停用");//账号冻结 + if (sysUser.ModuleList.Count == 0) throw Oops.Bah("该账号未分配模块,请联系管理员");//没有分配菜单权限 + var org = await _sysOrgService.GetSysOrgById(sysUser.OrgId);//获取机构 + if (org.Status == CommonStatusConst.DISABLED) throw Oops.Bah("所属公司/部门已停用,请联系管理员");//机构冻结 + //生成Token + var accessToken = JWTEncryption.Encrypt(new Dictionary + { + { + ClaimConst.USER_ID, sysUser.Id + }, + { + ClaimConst.ACCOUNT, sysUser.Account + }, + { + ClaimConst.NAME, sysUser.Name + }, + { + ClaimConst.IS_SUPER_ADMIN, sysUser.RoleCodeList.Contains(SysRoleConst.SUPER_ADMIN) + }, + { + ClaimConst.ORG_ID, sysUser.OrgId + }, + { + ClaimConst.TENANT_ID, tenantId + } + }); + var expire = App.GetConfig("JWTSettings:ExpiredTime");//获取过期时间(分钟) + // 生成刷新Token令牌 + var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, expire * 2); + // 设置Swagger自动登录 + App.HttpContext.SigninToSwagger(accessToken); + // 设置响应报文头 + App.HttpContext.SetTokensOfResponseHeaders(accessToken, refreshToken); + //登录事件参数 + var loginEvent = new LoginEvent + { + Ip = App.HttpContext.GetRemoteIpAddressToIPv4(), + Device = device, + Expire = expire, + SysUser = sysUser, + Token = accessToken + }; + await WriteTokenToRedis(loginEvent, loginClientType);//写入token到缓存 + await _eventPublisher.PublishAsync(EventSubscriberConst.LOGIN_B, loginEvent);//发布登录事件总线 + //返回结果 + return new LoginOutPut + { + Token = accessToken, + Account = sysUser.Account, + Name = sysUser.Name, + DefaultModule = sysUser.DefaultModule, + ModuleList = sysUser.ModuleList + }; + } + + /// + /// 写入用户token到缓存 + /// + /// 登录事件参数 + /// 登录类型 + private async Task WriteTokenToRedis(LoginEvent loginEvent, LoginClientTypeEnum loginClientType) + { + //获取token列表 + var tokenInfos = GetTokenInfos(loginEvent.SysUser.Id); + var tokenTimeout = loginEvent.DateTime.AddMinutes(loginEvent.Expire); + //生成token信息 + var tokenInfo = new TokenInfo + { + Device = loginEvent.Device.ToString(), + Expire = loginEvent.Expire, + TokenTimeout = tokenTimeout, + LoginClientType = loginClientType, + Token = loginEvent.Token + }; + //如果缓存有数据 + if (tokenInfos != null) + { + var isSingle = false;//默认不开启单用户登录 + var singleConfig = await _configService.GetByConfigKey(CateGoryConst.CONFIG_LOGIN_POLICY, SysConfigConst.LOGIN_SINGLE_OPEN);//获取系统单用户登录选项 + if (singleConfig != null) + isSingle = singleConfig.ConfigValue.ToBoolean();//如果配置不为空则设置单用户登录选项为系统配置的值 + //判断是否单用户登录 + if (isSingle) + { + await SingleLogin(loginEvent.SysUser.Id.ToString(), tokenInfos.Where(it => it.LoginClientType == loginClientType).ToList());//单用户登录方法 + tokenInfos = tokenInfos.Where(it => it.LoginClientType != loginClientType).ToList();//去掉当前登录类型的token + tokenInfos.Add(tokenInfo);//添加到列表 + } + else + { + tokenInfos.Add(tokenInfo); + } + } + else + { + tokenInfos = new List + { + tokenInfo + };//直接就一个 + } + + //添加到token列表 + _simpleCacheService.HashAdd(CacheConst.CACHE_USER_TOKEN, loginEvent.SysUser.Id.ToString(), tokenInfos); + } + + /// + /// 缓存删除用户token + /// + /// 登录事件参数 + /// 登录类型 + private void RemoveTokenFromRedis(LoginEvent loginEvent, LoginClientTypeEnum loginClientType) + { + //获取token列表 + var tokenInfos = GetTokenInfos(loginEvent.SysUser.Id); + if (tokenInfos != null) + { + //获取当前用户的token + var token = tokenInfos.Where(it => it.Token == loginEvent.Token && it.LoginClientType == loginClientType).FirstOrDefault(); + if (token != null) + tokenInfos.Remove(token); + if (tokenInfos.Count > 0) + { + //更新token列表 + _simpleCacheService.HashAdd(CacheConst.CACHE_USER_TOKEN, loginEvent.SysUser.Id.ToString(), tokenInfos); + } + else + { + //从列表中删除 + _simpleCacheService.HashDel>(CacheConst.CACHE_USER_TOKEN, loginEvent.SysUser.Id.ToString()); + } + } + } + + /// + /// 获取用户token列表 + /// + /// 用户ID + /// token列表 + private List GetTokenInfos(long userId) + { + //缓存获取用户token列表 + var tokenInfos = _simpleCacheService.HashGetOne>(CacheConst.CACHE_USER_TOKEN, userId.ToString()); + if (tokenInfos != null) + { + tokenInfos = tokenInfos.Where(it => it.TokenTimeout > DateTime.Now).ToList();//去掉登录超时的 + } + return tokenInfos; + } + + /// + /// 单用户登录通知用户下线 + /// + /// 用户ID + /// Token列表 + private async Task SingleLogin(string userId, List tokenInfos) + { + await _eventPublisher.PublishAsync(EventSubscriberConst.USER_LOGIN_OUT, new UserLoginOutEvent + { + Message = "您的账号已在别处登录!", + TokenInfos = tokenInfos, + UserId = userId + });//通知用户下线 + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Auth/Auth/Dto/AuthInput.cs b/SimpleAdmin.System/Services/Auth/Auth/Dto/AuthInput.cs new file mode 100644 index 0000000..2f44162 --- /dev/null +++ b/SimpleAdmin.System/Services/Auth/Auth/Dto/AuthInput.cs @@ -0,0 +1,103 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 权限认证输入 +/// +public class AuthInput +{ +} + +public class ValidCodeInput +{ + /// + /// 验证码 + /// + public string ValidCode { get; set; } + + /// + /// 请求号 + /// + public string ValidCodeReqNo { get; set; } +} + +/// +/// 登录输入参数 +/// +public class LoginInput : ValidCodeInput +{ + /// + /// 账号 + /// + /// superAdmin + [Required(ErrorMessage = "账号不能为空")] + public string Account { get; set; } + + /// + /// 密码 + /// + ///04fc514b346f14b23d7cf5e6f64663b030512aa380a9e7d311288ed1e8be7b863ae5ee0bb570df2405fc9daff2b2d1ac627a0fbbd49ef2c6b8fac4fd5e4b9a1b7120999bdc0a8e425aa37abab3aec6f9f3570775ff901f2845e957b0c2d0542e21fbf1bbb65c04 + [Required(ErrorMessage = "密码不能为空")] + public string Password { get; set; } + + /// + /// 设备类型,默认PC + /// + /// 0 + public AuthDeviceTypeEnum Device { get; set; } = AuthDeviceTypeEnum.PC; + + /// + /// 租户ID + /// + public long? TenantId { get; set; } +} + +/// +/// 登出输入参数 +/// +public class LoginOutInput +{ + /// + /// token + /// + public string Token { get; set; } +} + +/// +/// 获取短信验证码输入 +/// +public class GetPhoneValidCodeInput : ValidCodeInput +{ + /// + /// 手机号 + /// + [Required(ErrorMessage = "手机号不能为空")] + [Phone(ErrorMessage = "手机号格式不对")] + public string Phone { get; set; } +} + +/// +/// 手机号登录输入 +/// +public class LoginByPhoneInput : GetPhoneValidCodeInput +{ + /// + /// 设备类型,默认PC + /// + /// 0 + public AuthDeviceTypeEnum Device { get; set; } = AuthDeviceTypeEnum.PC; + + /// + /// 租户ID + /// + public long? TenantId { get; set; } +} diff --git a/SimpleAdmin.System/Services/Auth/Auth/Dto/AuthOutPut.cs b/SimpleAdmin.System/Services/Auth/Auth/Dto/AuthOutPut.cs new file mode 100644 index 0000000..65eafbe --- /dev/null +++ b/SimpleAdmin.System/Services/Auth/Auth/Dto/AuthOutPut.cs @@ -0,0 +1,154 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +public class AuthOutPut +{ +} + +/// +/// 验证码返回 +/// +public class PicValidCodeOutPut +{ + /// + /// 验证码图片,Base64 + /// + public string ValidCodeBase64 { get; set; } + + /// + /// 验证码请求号 + /// + public string ValidCodeReqNo { get; set; } +} + +/// +/// 登录返回参数 +/// +public class LoginOutPut +{ + /// + /// 令牌Token + /// + public string Token { get; set; } + + /// + /// 账号 + /// + public string Account { get; set; } + + /// + /// 姓名 + /// + public string Name { get; set; } + + /// + /// 默认模块 + /// + public long? DefaultModule { get; set; } + + /// + /// 模块列表 + /// + public List ModuleList { get; set; } +} + +/// +/// 登录用互信息 +/// +public class LoginUserOutput +{ + /// + /// 头像 + /// + public string Avatar { get; set; } + + /// + /// 签名 + /// + public string Signature { get; set; } + + /// + /// 账号 + /// + public string Account { get; set; } + + /// + /// 姓名 + /// + public string Name { get; set; } + + /// + /// 昵称 + /// + public string Nickname { get; set; } + + /// + /// 手机号 + /// + public string Phone { get; set; } + + /// + /// 生日 + /// + public string Birthday { get; set; } + + /// + /// 邮箱 + /// + + public string Email { get; set; } + + /// + /// 性别 + /// + public string Gender { get; set; } + + /// + /// 家庭住址 + /// + public string HomeAddress { get; set; } + + /// + /// 机构信息 + /// + public string OrgName { get; set; } + + /// + /// 机构信息全称 + /// + public string OrgNames { get; set; } + + /// + /// 职位信息 + /// + public string PositionName { get; set; } + + /// + /// 角色码集合 + /// + public List RoleCodeList { get; set; } + + /// + /// 按钮码集合 + /// + public List ButtonCodeList { get; set; } + + /// + /// 机构及以下机构ID集合 + /// + public List ModuleList { get; set; } = new List(); + + /// + /// 默认模块 + /// + public long? DefaultModule { get; set; } +} diff --git a/SimpleAdmin.System/Services/Auth/Auth/IAuthService.cs b/SimpleAdmin.System/Services/Auth/Auth/IAuthService.cs new file mode 100644 index 0000000..8bcb72c --- /dev/null +++ b/SimpleAdmin.System/Services/Auth/Auth/IAuthService.cs @@ -0,0 +1,61 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 权限校验服务 +/// +public interface IAuthService : ITransient +{ + /// + /// 获取图形验证码 + /// + /// + Task GetCaptchaInfo(); + + /// + /// 获取登录用户信息 + /// + /// + Task GetLoginUser(); + + /// + /// 获取手机短信验证码 + /// + /// 验证码参数 + /// 登录类型 + /// + Task GetPhoneValidCode(GetPhoneValidCodeInput input, LoginClientTypeEnum loginClientType); + + /// + /// 登录 + /// + /// 登录参数 + /// 登录类型 + /// Token信息 + Task Login(LoginInput input, LoginClientTypeEnum loginClientType); + + /// + /// 手机号登录 + /// + /// 登录参数 + /// 登录端类型 + /// Token信息 + Task LoginByPhone(LoginByPhoneInput input, LoginClientTypeEnum loginClientType); + + /// + /// 退出登录 + /// + /// token + /// 登出类型 + /// + Task LoginOut(string token, LoginClientTypeEnum loginClientType); +} diff --git a/SimpleAdmin.System/Services/Auth/Session/Dto/SessionInput.cs b/SimpleAdmin.System/Services/Auth/Session/Dto/SessionInput.cs new file mode 100644 index 0000000..aa67a12 --- /dev/null +++ b/SimpleAdmin.System/Services/Auth/Session/Dto/SessionInput.cs @@ -0,0 +1,45 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 会话分页查询 +/// +public class SessionPageInput : BasePageInput +{ + /// + /// 账号 + /// + public virtual string Account { get; set; } + + /// + /// 姓名 + /// + + public virtual string Name { get; set; } + + /// + /// 最新登录ip + /// + public string LatestLoginIp { get; set; } +} + +/// +/// Token退出参数 +/// +public class ExitTokenInput : BaseIdInput +{ + /// + /// token + /// + [Required(ErrorMessage = "Tokens不能为空")] + public List Tokens { get; set; } +} diff --git a/SimpleAdmin.System/Services/Auth/Session/Dto/SessionOutput.cs b/SimpleAdmin.System/Services/Auth/Session/Dto/SessionOutput.cs new file mode 100644 index 0000000..0d2f619 --- /dev/null +++ b/SimpleAdmin.System/Services/Auth/Session/Dto/SessionOutput.cs @@ -0,0 +1,94 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 会话输出 +/// +public class SessionOutput +{ + /// + /// 主键Id + /// + public virtual long Id { get; set; } + + /// + /// 头像 + /// + public string Avatar { get; set; } + + /// + /// 账号 + /// + public virtual string Account { get; set; } + + /// + /// 姓名 + /// + + public virtual string Name { get; set; } + + /// + /// 在线状态 + /// + public string OnlineStatus { get; set; } + + /// + /// 最新登录ip + /// + public string LatestLoginIp { get; set; } + + /// + /// 最新登录地点 + /// + public string LatestLoginAddress { get; set; } + + /// + /// 最新登录时间 + /// + public DateTime? LatestLoginTime { get; set; } + + /// + /// 令牌数量 + /// + public int TokenCount { get; set; } + + /// + /// 令牌信息集合 + /// + public List TokenSignList { get; set; } +} + +/// +/// 会话统计结果 +/// +public class SessionAnalysisOutPut +{ + /// + /// 当前会话总数量 + /// + public int CurrentSessionTotalCount { get; set; } + + /// + /// 最大签发令牌数 + /// + public int MaxTokenCount { get; set; } + + /// + /// 在线用户数 + /// + public int OnLineCount { get; set; } + + /// + /// BC端会话比例 + /// + public string ProportionOfBAndC { get; set; } +} diff --git a/SimpleAdmin.System/Services/Auth/Session/ISessionService.cs b/SimpleAdmin.System/Services/Auth/Session/ISessionService.cs new file mode 100644 index 0000000..47af0e3 --- /dev/null +++ b/SimpleAdmin.System/Services/Auth/Session/ISessionService.cs @@ -0,0 +1,49 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 会话管理服务 +/// +public interface ISessionService : ITransient +{ + /// + /// 会话统计 + /// + /// 统计结果 + SessionAnalysisOutPut Analysis(); + + /// + /// 强退会话 + /// + /// 用户ID + Task ExitSession(BaseIdInput input); + + /// + /// 强退token + /// + /// token列表 + Task ExitToken(ExitTokenInput input); + + /// + /// B端会话分页查询 + /// + /// 查询参数 + /// B端会话列表 + Task> PageB(SessionPageInput input); + + /// + /// C端会话分页查询 + /// + /// 查询参数 + /// C端会话列表 + Task> PageC(SessionPageInput input); +} diff --git a/SimpleAdmin.System/Services/Auth/Session/SessionService.cs b/SimpleAdmin.System/Services/Auth/Session/SessionService.cs new file mode 100644 index 0000000..e7a7607 --- /dev/null +++ b/SimpleAdmin.System/Services/Auth/Session/SessionService.cs @@ -0,0 +1,202 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using Masuit.Tools.DateTimeExt; + +namespace SimpleAdmin.System; + +/// +/// +/// +public class SessionService : DbRepository, ISessionService +{ + private readonly ISimpleCacheService _simpleCacheService; + private readonly IEventPublisher _eventPublisher; + + public SessionService(ISimpleCacheService simpleCacheService, IEventPublisher eventPublisher) + { + _simpleCacheService = simpleCacheService; + _eventPublisher = eventPublisher; + } + + /// + public async Task> PageB(SessionPageInput input) + { + //获取b端token列表 + var bTokenInfoDic = GetTokenDicFromRedis(); + + //获取用户ID列表 + var userIds = bTokenInfoDic.Keys.Select(it => it.ToLong()).ToList(); + var query = Context.Queryable().Where(it => userIds.Contains(it.Id))//根据ID查询 + .WhereIF(!string.IsNullOrEmpty(input.Name), it => it.Name.Contains(input.Name))//根据姓名查询 + .WhereIF(!string.IsNullOrEmpty(input.Account), it => it.Account.Contains(input.Account))//根据账号查询 + .WhereIF(!string.IsNullOrEmpty(input.LatestLoginIp), it => it.LatestLoginIp.Contains(input.LatestLoginIp))//根据IP查询 + .OrderBy(it => it.LatestLoginTime, OrderByType.Desc).Select().Mapper(it => + { + var tokenInfos = bTokenInfoDic[it.Id.ToString()];//获取用户token信息 + GetTokenInfos(ref tokenInfos, LoginClientTypeEnum.B);//获取剩余时间 + it.TokenCount = tokenInfos.Count;//令牌数量 + it.TokenSignList = tokenInfos;//令牌列表 + //如果有mqtt客户端ID就是在线 + it.OnlineStatus = tokenInfos.Any(it => it.ClientIds.Count > 0) + ? SysDictConst.ONLINE_STATUS_ONLINE + : SysDictConst.ONLINE_STATUS_OFFLINE; + }); + + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + pageInfo.List.OrderByDescending(it => it.TokenCount); + return pageInfo; + } + + /// + public async Task> PageC(SessionPageInput input) + { + return new SqlSugarPagedList { PageNum = 1, PageSize = 20, Total = 0, Pages = 1, HasNextPages = false }; + } + + /// + public SessionAnalysisOutPut Analysis() + { + var tokenDic = GetTokenDicFromRedis();//redisToken会话字典信息 + var tokenInfosList = tokenDic.Values.ToList();//端token列表 + var dicB = new Dictionary>(); + var dicC = new Dictionary>(); + var onLineCount = 0; + foreach (var token in tokenDic) + { + var b = token.Value.Where(it => it.LoginClientType == LoginClientTypeEnum.B).ToList();//获取该用户B端token + var c = token.Value.Where(it => it.LoginClientType == LoginClientTypeEnum.C).ToList();//获取该用户C端token + if (b.Count > 0) + dicB.Add(token.Key, b); + if (c.Count > 0) + dicC.Add(token.Key, c); + var count = token.Value.Count(it => it.ClientIds.Count > 0);//计算在线用户 + onLineCount += count; + } + var tokenB = dicB.Values.ToList();//b端token列表 + var tokenC = dicC.Values.ToList();//c端token列表 + int maxCountB = 0, maxCountC = 0; + if (tokenB.Count > 0) + maxCountB = tokenB.OrderByDescending(it => it.Count).Take(1).First().Count;//b端最大会话数 + + if (tokenC.Count > 0) + maxCountC = tokenC.OrderByDescending(it => it.Count).Take(1).First().Count;//C端最大会话数 + return new SessionAnalysisOutPut + { + OnLineCount = onLineCount, + CurrentSessionTotalCount = tokenB.Count + tokenC.Count, + MaxTokenCount = maxCountB > maxCountC ? maxCountB : maxCountC, + ProportionOfBAndC = $"{tokenB.Count}/{tokenC.Count}" + }; + } + + /// + public async Task ExitSession(BaseIdInput input) + { + var userId = input.Id.ToString(); + //token列表 + var tokenInfos = _simpleCacheService.HashGetOne>(CacheConst.CACHE_USER_TOKEN, userId); + //从列表中删除 + _simpleCacheService.HashDel>(CacheConst.CACHE_USER_TOKEN, userId); + await NoticeUserLoginOut(userId, tokenInfos); + } + + /// + public async Task ExitToken(ExitTokenInput input) + { + var userId = input.Id.ToString(); + //获取该用户的token信息 + var tokenInfos = _simpleCacheService.HashGetOne>(CacheConst.CACHE_USER_TOKEN, userId); + //当前需要踢掉用户的token + var deleteTokens = tokenInfos.Where(it => input.Tokens.Contains(it.Token)).ToList(); + //踢掉包含token列表的token信息 + tokenInfos = tokenInfos.Where(it => !input.Tokens.Contains(it.Token)).ToList(); + if (tokenInfos.Count > 0) + _simpleCacheService.HashAdd(CacheConst.CACHE_USER_TOKEN, userId, tokenInfos);//如果还有token则更新token + else + _simpleCacheService.HashDel>(CacheConst.CACHE_USER_TOKEN, userId);//否则直接删除key + await NoticeUserLoginOut(userId, deleteTokens); + } + + #region 方法 + + /// + /// 获取redis中token信息列表 + /// + /// + public Dictionary> GetTokenDicFromRedis() + { + var clockSkew = App.GetConfig("JWTSettings:ClockSkew");//获取过期时间容错值(秒) + //redis获取token信息hash集合,并转成字典 + var bTokenDic = _simpleCacheService.HashGetAll>(CacheConst.CACHE_USER_TOKEN).ToDictionary(u => u.Key, u => u.Value); + if (bTokenDic != null) + { + bTokenDic.ForEach(it => + { + var tokens = it.Value.Where(it => it.TokenTimeout.AddSeconds(clockSkew) > DateTime.Now).ToList();//去掉登录超时的 + if (tokens.Count == 0) + { + //表示都过期了 + bTokenDic.Remove(it.Key); + } + else + { + bTokenDic[it.Key] = tokens;//重新赋值token + } + }); + if (bTokenDic.Count > 0) + { + _simpleCacheService.HashSet(CacheConst.CACHE_USER_TOKEN, bTokenDic);//如果还有token则更新token + } + else + { + _simpleCacheService.Remove(CacheConst.CACHE_USER_TOKEN);//否则直接删除key + } + return bTokenDic; + } + return new Dictionary>(); + } + + /// + /// 获取token剩余时间信息 + /// + /// token列表 + /// 登录类型 + public void GetTokenInfos(ref List tokenInfos, LoginClientTypeEnum loginClientType) + { + tokenInfos = tokenInfos.Where(it => it.LoginClientType == loginClientType).ToList(); + tokenInfos.ForEach(it => + { + var now = DateTime.Now; + it.TokenRemain = now.GetDiffTime(it.TokenTimeout);//获取时间差 + var tokenSecond = it.TokenTimeout.AddMinutes(-it.Expire).ConvertDateTimeToLong();//颁发时间转为时间戳 + var timeoutSecond = it.TokenTimeout.ConvertDateTimeToLong();//过期时间转为时间戳 + var tokenRemainPercent = + 1 - (now.ConvertDateTimeToLong() - tokenSecond) * 1.0 / (timeoutSecond - tokenSecond);//求百分比,用现在时间-token颁布时间除以超时时间-token颁布时间 + it.TokenRemainPercent = tokenRemainPercent; + }); + } + + /// + /// 通知用户下线 + /// + /// + private async Task NoticeUserLoginOut(string userId, List tokenInfos) + { + await _eventPublisher.PublishAsync(EventSubscriberConst.USER_LOGIN_OUT, new UserLoginOutEvent + { + Message = "您已被强制下线!", + TokenInfos = tokenInfos, + UserId = userId + });//通知用户下线 + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/BatchEdit/BatchEditService.cs b/SimpleAdmin.System/Services/BatchEdit/BatchEditService.cs new file mode 100644 index 0000000..858075b --- /dev/null +++ b/SimpleAdmin.System/Services/BatchEdit/BatchEditService.cs @@ -0,0 +1,214 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class BatchEditService : DbRepository, IBatchEditService +{ + private readonly ILogger _logger; + + public BatchEditService(ILogger logger) + { + _logger = logger; + } + + /// + public async Task> Page(BatchEditPageInput input) + { + var query = Context.Queryable() + .WhereIF(!string.IsNullOrWhiteSpace(input.ConfigId), it => it.ConfigId.Contains(input.ConfigId.Trim())) + .WhereIF(!string.IsNullOrWhiteSpace(input.EntityName), it => it.EntityName.Contains(input.EntityName.Trim())) + .WhereIF(!string.IsNullOrWhiteSpace(input.TableName), it => it.TableName.Contains(input.TableName.Trim())) + //.WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Name.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}"); + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task Add(BatchEditAddInput input) + { + var entity = input.Adapt();//实体转换 + await CheckInput(entity);//检查参数 + var tableColumns = SqlSugarUtils.GetTableColumns(input.ConfigId, input.TableName);//获取表的字段信息 + var batchEdiConfig = new List();//代码生成配置字段集合 + + //遍历字段 + tableColumns.ForEach(it => + { + //判断是否是主键或者通用字段 + var isPkOrCommon = it.IsPrimaryKey || SqlSugarUtils.IsCommonColumn(it.ColumnName); + if (!isPkOrCommon) + { + //添加到字段集合 + batchEdiConfig.Add(GetUpdateBatchConfig(it)); + } + }); + //事务 + var result = await Tenant.UseTranAsync(async () => + { + entity = await InsertReturnEntityAsync(entity);//输入参数转实体并插入 + batchEdiConfig.ForEach(it => { it.UId = entity.Id; });//遍历字段赋值基础Id + await Context.Insertable(batchEdiConfig).ExecuteCommandAsync(); + }); + if (!result.IsSuccess)//如果失败了 + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0003); + } + } + + /// + public async Task Config(List input) + { + var updateBatch = input.Adapt>();//实体转换 + var configRep = ChangeRepository>(); + var ids = input.Select(it => it.Id).ToList();//获取当前配置Id + if (ids.Any()) + { + await configRep.DeleteAsync(it => !ids.Contains(it.Id) && it.UId == input.First().UId);//删除没有的 + await Context.Updateable(updateBatch).ExecuteCommandAsync();//更新数据 + } + } + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await DeleteByIdsAsync(ids.Cast().ToArray());//删除数据 + await Context.Deleteable().Where(it => ids.Contains(it.UId)).ExecuteCommandAsync(); + }); + if (!result.IsSuccess)//如果失败了 + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0003); + } + } + } + + /// + public async Task SyncColumns(BaseIdInput input) + { + var config = await GetFirstAsync(it => it.Id == input.Id); + if (config != null) + { + var newColumns = new List(); + //获取表的字段信息 + var tableColumns = SqlSugarUtils.GetTableColumns(config.ConfigId, config.TableName); + //找到当前配置字段列表 + var batchEdiConfig = await Context.Queryable().Where(it => it.UId == config.Id).ToListAsync(); + foreach (var tableColumn in tableColumns) + { + //判断是否是主键或者通用字段 + var isPkOrCommon = tableColumn.IsPrimaryKey || SqlSugarUtils.IsCommonColumn(tableColumn.ColumnName); + if (!isPkOrCommon) + { + //如果当前配置没有 + if (!batchEdiConfig.Any(it => it.ColumnName == tableColumn.ColumnName)) + { + var netType = SqlSugarUtils.ConvertDataType(tableColumn.DataType); + //添加到字段集合 + newColumns.Add(GetUpdateBatchConfig(tableColumn)); + } + } + } + if (newColumns.Count > 0) + { + newColumns.ForEach(it => it.UId = config.Id); + await Context.Insertable(newColumns).ExecuteCommandAsync();//插入新的字段数据 + } + } + } + + /// + public async Task> Columns(string code) + { + var batchEdiConfig = new List(); + var updateBatch = await GetFirstAsync(it => it.Code == code);//根据code获取配置 + if (updateBatch != null) + { + //找到对应字段 + batchEdiConfig = await Context.Queryable().Where(it => it.UId == updateBatch.Id && it.Status == CommonStatusConst.ENABLE) + .ToListAsync(); + } + return batchEdiConfig; + } + + /// + public List GetTables() + { + return SqlSugarUtils.GetTablesByAttribute(); + } + + /// + public async Task> ConfigList(BaseIdInput input) + { + return await Context.Queryable().Where(u => u.UId == input.Id).OrderByDescending(it => it.Status).ToListAsync(); + } + + /// + public async Task> GetUpdateBatchConfigDict(string code, List columns) + { + var dic = new Dictionary(); + var configs = await Columns(code); + foreach (var item in columns) + { + var config = configs.Where(it => it.ColumnName == item.TableColumn).FirstOrDefault(); + if (config == null) throw Oops.Bah("不存在的列"); + dic.Add(item.TableColumn, item.ColumnValue.ToString()); + } + return dic; + } + + #region 方法 + + /// + /// 获取配置 + /// + /// + private BatchEditConfig GetUpdateBatchConfig(SqlSugarColumnInfo columnInfo) + { + var netType = SqlSugarUtils.ConvertDataType(columnInfo.DataType); + return new BatchEditConfig + { + ColumnName = columnInfo.ColumnName, + ColumnComment = string.IsNullOrWhiteSpace(columnInfo.ColumnDescription) ? columnInfo.ColumnName : columnInfo.ColumnDescription, + NetType = netType, + DataType = SqlSugarUtils.DataTypeToEff(netType), + Status = CommonStatusConst.DISABLED + }; + } + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(BatchEdit updateBatch) + { + if (updateBatch.Id == 0) + { + var isExist = await IsAnyAsync(it => it.Code == updateBatch.Code); + if (isExist) throw Oops.Bah("唯一编码不能重复"); + } + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/BatchEdit/Dto/BatchEditInput.cs b/SimpleAdmin.System/Services/BatchEdit/Dto/BatchEditInput.cs new file mode 100644 index 0000000..98ed51f --- /dev/null +++ b/SimpleAdmin.System/Services/BatchEdit/Dto/BatchEditInput.cs @@ -0,0 +1,138 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 批量分页查询参数 +/// +public class BatchEditPageInput : BasePageInput +{ + /// + /// 唯一编码 + /// + public string Code { get; set; } + + /// + /// 所属库 + /// + public string ConfigId { get; set; } + + /// + /// 实体名 + /// + public string EntityName { get; set; } + + /// + /// 表名 + /// + public string TableName { get; set; } +} + +/// +/// 添加批量参数 +/// +public class BatchEditAddInput +{ + /// + /// 唯一编码 + /// + [Required(ErrorMessage = "Code必填")] + public string Code { get; set; } + + /// + /// 所属库 + /// + [Required(ErrorMessage = "ConfigId必填")] + public string ConfigId { get; set; } + + /// + /// 实体名 + /// + [Required(ErrorMessage = "EntityName必填")] + public string EntityName { get; set; } + + /// + /// 表名 + /// + [Required(ErrorMessage = "TableName必填")] + public string TableName { get; set; } + + /// + /// 表描述 + /// + public string TableDescription { get; set; } +} + +/// +/// 修改批量参数 +/// +public class BatchEditConfigInput : BatchEditConfig, IValidatableObject +{ + /// + /// Id + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } + + public IEnumerable Validate(ValidationContext validationContext) + { + if (Status == CommonStatusConst.ENABLE) + { + //如果是api请求并且必填参数有空的 + if (DataType.Contains("api") && (string.IsNullOrEmpty(RequestUrl) || string.IsNullOrEmpty(RequestType) + || string.IsNullOrEmpty(RequestLabel) || string.IsNullOrEmpty(RequestValue))) + { + yield return new ValidationResult($"字段{ColumnName}接口信息必填", new[] { nameof(DataType) }); + } + //如果是字典数据并且字典值为空 + if (DataType.Contains("dict") && string.IsNullOrEmpty(DictTypeCode)) + { + yield return new ValidationResult($"字段{ColumnName}字典值必填", new[] { nameof(DictTypeCode) }); + } + } + } +} + +/// +/// 批量修改输入 +/// +public class BatchEditInput +{ + /// + /// 批量编辑Code + /// + [Required(ErrorMessage = "Code不能为空")] + public string Code { get; set; } + + /// + /// Id列表 + /// + [Required(ErrorMessage = "Ids不能为空")] + public List? Ids { get; set; } + + /// + /// 字段列表 + /// + [Required(ErrorMessage = "Columns不能为空")] + public List? Columns { get; set; } +} + +/// +/// 批量修改DTO +/// +public class BatchEditColumn +{ + [Required(ErrorMessage = "字段名必填")] + public string TableColumn { get; set; } + + [Required(ErrorMessage = "字段值必填")] + public object ColumnValue { get; set; } +} diff --git a/SimpleAdmin.System/Services/BatchEdit/Dto/BatchEditOutput.cs b/SimpleAdmin.System/Services/BatchEdit/Dto/BatchEditOutput.cs new file mode 100644 index 0000000..cfde937 --- /dev/null +++ b/SimpleAdmin.System/Services/BatchEdit/Dto/BatchEditOutput.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + + + + + diff --git a/SimpleAdmin.System/Services/BatchEdit/IBatchEditService.cs b/SimpleAdmin.System/Services/BatchEdit/IBatchEditService.cs new file mode 100644 index 0000000..1ad6910 --- /dev/null +++ b/SimpleAdmin.System/Services/BatchEdit/IBatchEditService.cs @@ -0,0 +1,80 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 批量服务 +/// +public interface IBatchEditService : ITransient +{ + /// + /// 批量分页查询 + /// + /// 查询参数 + /// 分页结果 + Task> Page(BatchEditPageInput input); + + /// + /// 添加批量 + /// + /// 添加参数 + /// + Task Add(BatchEditAddInput input); + + /// + /// 删除批量 + /// + /// 删除参数 + /// + Task Delete(BaseIdListInput input); + + /// + /// 获取需要批量修改的表 + /// + /// + List GetTables(); + + /// + /// 获取批量修改配置 + /// + /// + /// + Task> ConfigList(BaseIdInput input); + + /// + /// 配置字段 + /// + /// 字段信息 + /// + Task Config(List input); + + /// + /// 批量配置字段列表 + /// + /// 唯一编码 + /// 列表 + Task> Columns(string code); + + /// + /// 获取字典配置 + /// + /// 唯一编码 + /// 字段信息 + /// SqlSugar对应字典 + Task> GetUpdateBatchConfigDict(string code, List columns); + + /// + /// 同步字段 + /// + /// id + /// + Task SyncColumns(BaseIdInput input); +} diff --git a/SimpleAdmin.System/Services/Dev/File/Dto/FileInput.cs b/SimpleAdmin.System/Services/Dev/File/Dto/FileInput.cs new file mode 100644 index 0000000..df413f6 --- /dev/null +++ b/SimpleAdmin.System/Services/Dev/File/Dto/FileInput.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 文件分页输出 +/// +public class FilePageInput : BasePageInput +{ + /// + /// 文件引擎 + /// + public string Engine { get; set; } +} diff --git a/SimpleAdmin.System/Services/Dev/File/FileService.cs b/SimpleAdmin.System/Services/Dev/File/FileService.cs new file mode 100644 index 0000000..621457d --- /dev/null +++ b/SimpleAdmin.System/Services/Dev/File/FileService.cs @@ -0,0 +1,273 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class FileService : DbRepository, IFileService +{ + private readonly IConfigService _configService; + + public FileService(IConfigService configService) + { + _configService = configService; + } + + /// + public async Task> Page(FilePageInput input) + { + var query = Context.Queryable().WhereIF(!string.IsNullOrEmpty(input.Engine), it => it.Engine == input.Engine)//根据关键字查询 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Name.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}")//排序 + .OrderBy(it => it.Id); + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task UploadFile(string engine, IFormFile file) + { + return await StorageFile(engine, file); + } + + /// + public async Task Delete(BaseIdListInput input) + { + var ids = input.Ids;//获取ID + await DeleteByIdsAsync(ids.Cast().ToArray());//根据ID删除数据库 + } + + /// + public FileStreamResult GetFileStreamResult(string path, string fileName, bool isPathFolder = false) + { + if (isPathFolder) path = path.CombinePath(fileName); + fileName = HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));//文件名转utf8不然前端下载会乱码 + //文件转流 + var result = new FileStreamResult(new FileStream(path, FileMode.Open), "application/octet-stream") + { + FileDownloadName = fileName + }; + return result; + } + + public async Task GetFileStreamResultFromMinio(string objectName, string fileName) + { + var minioService = App.GetService(); + var stream = await minioService.DownloadFileAsync(objectName); + + fileName = HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));//文件名转utf8不然前端下载会乱码 + //文件转流 + var result = new FileStreamResult(stream, "application/octet-stream") + { + FileDownloadName = fileName + }; + return result; + } + + /// + public FileStreamResult GetFileStreamResult(byte[] byteArray, string fileName) + { + fileName = HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));//文件名转utf8不然前端下载会乱码 + //文件转流 + var result = new FileStreamResult(new MemoryStream(byteArray), "application/octet-stream") + { + FileDownloadName = fileName + }; + return result; + } + + /// + public async Task Download(BaseIdInput input) + { + var devFile = await GetByIdAsync(input.Id); + if (devFile != null) + { + if (devFile.Engine == SysDictConst.FILE_ENGINE_LOCAL) + return GetFileStreamResult(devFile.StoragePath, devFile.Name); + if (devFile.Engine == SysDictConst.FILE_ENGINE_MINIO) + return await GetFileStreamResultFromMinio(devFile.ObjName, devFile.Name); + return null; + } + return null; + } + + #region 方法 + + /// + /// 存储文件 + /// + /// + /// + private async Task StorageFile(string engine, IFormFile file) + { + var bucketName = string.Empty;// 存储桶名称 + var storageUrl = string.Empty;// 定义存储的url,本地文件返回文件实际路径,其他引擎返回网络地址 + var objName = string.Empty;// 定义存储的url,本地文件返回文件实际路径,其他引擎返回网络地址 + + var objectId = CommonUtils.GetSingleId();//生成id + + switch (engine) + { + //存储本地 + case SysDictConst.FILE_ENGINE_LOCAL: + bucketName = "defaultBucketName";// 存储桶名称 + storageUrl = await StorageLocal(objectId, file); + break; + //存储本地 + case SysDictConst.FILE_ENGINE_MINIO: + var config = await _configService.GetByConfigKey(CateGoryConst.CONFIG_FILE_MINIO, SysConfigConst.FILE_MINIO_DEFAULT_BUCKET_NAME); + if (config != null) + { + bucketName = config.ConfigValue;// 存储桶名称 + (objName, storageUrl) = await StorageMinio(objectId, file); + } + break; + + default: + + throw Oops.Bah("不支持的文件引擎"); + } + var fileSizeKb = (long)(file.Length / 1024.0);// 文件大小KB + var fileSuffix = Path.GetExtension(file.FileName).ToLower();// 文件后缀 + var devFile = new SysFile + { + Id = objectId, + Engine = engine, + Bucket = bucketName, + Name = file.FileName, + Suffix = fileSuffix.Split(".")[1], + ObjName = objName, + SizeKb = fileSizeKb, + SizeInfo = GetSizeInfo(fileSizeKb), + StoragePath = storageUrl + }; + if (engine != CateGoryConst.CONFIG_FILE_LOCAL)//如果不是本地,设置下载地址 + { + devFile.DownloadPath = storageUrl; + } + //如果是图片,生成缩略图 + if (IsPic(fileSuffix)) + { + //$"data:image/png;base64," + imgByte; + await using var fileStream = file.OpenReadStream();//获取文件流 + var image = SKImage.FromEncodedData(fileStream);//获取图片 + var bmp = SKBitmap.FromImage(image); + var thubnail = bmp.GetPicThumbnail(100, 100);//压缩图片 + var thubnailBase64 = ImageUtil.ImgToBase64String(thubnail);//转base64 + devFile.Thumbnail = "data:image/png;base64," + thubnailBase64; + } + await InsertAsync(devFile); + return objectId; + } + + /// + /// 存储本地文件 + /// + /// + /// + private async Task StorageLocal(long fileId, IFormFile file) + { + string uploadFileFolder; + var configKey = string.Empty; + //判断是windows还是linux + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + configKey = SysConfigConst.FILE_LOCAL_FOLDER_FOR_UNIX;//Linux + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + configKey = SysConfigConst.FILE_LOCAL_FOLDER_FOR_WINDOWS;//Windows + } + //获取路径配置 + var config = await _configService.GetByConfigKey(CateGoryConst.CONFIG_FILE_LOCAL, configKey); + if (config != null) + { + uploadFileFolder = config.ConfigValue;//赋值路径 + var now = DateTime.Now.ToString("d"); + var filePath = Path.Combine(uploadFileFolder, now); + if (!Directory.Exists(filePath))//如果不存在就创建文件夹 + Directory.CreateDirectory(filePath); + var fileSuffix = Path.GetExtension(file.FileName).ToLower();// 文件后缀 + var fileObjectName = $"{fileId}{fileSuffix}";//存储后的文件名 + var fileName = Path.Combine(filePath, fileObjectName);//获取文件全路局 + fileName = fileName.Replace("\\", "/");//格式化一系 + //存储文件 + using (var stream = File.Create(Path.Combine(filePath, fileObjectName))) + { + await file.CopyToAsync(stream); + } + return fileName; + } + throw Oops.Oh("文件存储路径未配置"); + } + + /// + /// 存储到minio + /// + /// + /// + /// + private async Task<(string objName, string downloadUrl)> StorageMinio(long fileId, IFormFile file) + { + var minioService = App.GetService(); + var now = DateTime.Now.ToString("d"); + var fileSuffix = Path.GetExtension(file.FileName).ToLower();// 文件后缀 + var fileObjectName = $"{now}/{fileId}{fileSuffix}";//存储后的文件名 + var downloadUrl = await minioService.PutObjectAsync(fileObjectName, file); + return (fileObjectName, downloadUrl); + } + + /// + /// 获取文件大小 + /// + /// + /// + private string GetSizeInfo(long fileSizeKb) + { + var b = fileSizeKb * 1024; + const int mb = 1024 * 1024; + const int kb = 1024; + if (b / mb >= 1) + { + return Math.Round(b / (float)mb, 2) + "MB"; + } + + if (b / kb >= 1) + { + return Math.Round(b / (float)kb, 2) + "KB"; + } + if (b == 0) + { + return "0B"; + } + return null; + } + + /// + /// 判断是否是图片 + /// + /// 后缀名 + /// + private bool IsPic(string suffix) + { + //图片后缀名列表 + var pics = new[] + { + ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".psd" + }; + if (pics.Contains(suffix)) + return true; + return false; + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Dev/File/IFileService.cs b/SimpleAdmin.System/Services/Dev/File/IFileService.cs new file mode 100644 index 0000000..1a57632 --- /dev/null +++ b/SimpleAdmin.System/Services/Dev/File/IFileService.cs @@ -0,0 +1,63 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 文件管理服务 +/// +public interface IFileService : ITransient +{ + /// + /// 删除文件 + /// + /// ID列表 + /// + Task Delete(BaseIdListInput input); + + /// + /// 文件下载 + /// + /// 文件iD + /// 文件流 + Task Download(BaseIdInput input); + + /// + /// 获取FileStreamResult文件流 + /// + /// 路径 + /// 文件名 + /// 路径是否是文件夹 + /// + FileStreamResult GetFileStreamResult(string path, string fileName, bool isPathFolder = false); + + /// + /// 获取FileStreamResult文件流 + /// + /// 文件数组 + /// 文件名 + /// + FileStreamResult GetFileStreamResult(byte[] byteArray, string fileName); + + /// + /// 文件分页查询 + /// + /// 查询参数 + /// 文件列表 + Task> Page(FilePageInput input); + + /// + /// 上传文件到本地返回下载url + /// + /// 文件引擎 + /// 文件 + /// + Task UploadFile(string engine, IFormFile file); +} diff --git a/SimpleAdmin.System/Services/Dev/Message/Dto/MessageInput.cs b/SimpleAdmin.System/Services/Dev/Message/Dto/MessageInput.cs new file mode 100644 index 0000000..9aeab15 --- /dev/null +++ b/SimpleAdmin.System/Services/Dev/Message/Dto/MessageInput.cs @@ -0,0 +1,90 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +public class MessagePageInput : BasePageInput +{ + /// + /// 站内信分类 + /// + public string Category { get; set; } +} + +/// +/// 发送参数 +/// +public class MessageSendInput : SysMessage +{ + /// + /// 主题 + /// + [Required(ErrorMessage = "Subject不能为空")] + public override string Subject { get; set; } + + /// + /// 分类 + /// + [Required(ErrorMessage = "Category不能为空")] + public override string Category { get; set; } + + /// + /// 接收人Id + /// + public List ReceiverIdList { get; set; } + + public override string Status { get; set; } = SysDictConst.MESSAGE_STATUS_READY; +} + +public class MessageSendUpdateInput : MessageSendInput +{ + /// + /// 消息Id + /// + [Required(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} + +/// +/// 消息详情输入参数 +/// +public class MessageDetailInput : BaseIdInput +{ + /// + /// 是否显示接收信息 + /// + public bool ShowReceiveInfo { get; set; } = false; + + /// + /// 是否已读 + /// + public bool Read { get; set; } = false; +} + +/// +/// 已读输入参数 +/// +public class MessageReadInput +{ + /// + /// 分类 + /// + public string Category { get; set; } + + /// + /// 用户Id + /// + public long Id { get; set; } + + /// + /// 消息Id + /// + public List Ids { get; set; } = new List(); +} diff --git a/SimpleAdmin.System/Services/Dev/Message/Dto/MessageOutPut.cs b/SimpleAdmin.System/Services/Dev/Message/Dto/MessageOutPut.cs new file mode 100644 index 0000000..66d02c3 --- /dev/null +++ b/SimpleAdmin.System/Services/Dev/Message/Dto/MessageOutPut.cs @@ -0,0 +1,34 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 消息详情 +/// +public class MessageDetailOutPut : SysMessage +{ +} + +/// +/// 未读消息数量输出 +/// +public class MessageUnReadOutPut +{ + /// + /// 未读消息数量 + /// + public int UnReadCount { get; set; } + + /// + /// 分类 + /// + public string Category { get; set; } +} diff --git a/SimpleAdmin.System/Services/Dev/Message/IMessageService.cs b/SimpleAdmin.System/Services/Dev/Message/IMessageService.cs new file mode 100644 index 0000000..0ecb7c4 --- /dev/null +++ b/SimpleAdmin.System/Services/Dev/Message/IMessageService.cs @@ -0,0 +1,97 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 站内信服务 +/// +public interface IMessageService : ITransient +{ + /// + /// 删除消息 + /// + /// id列表 + /// + Task Delete(BaseIdListInput input); + + /// + /// 删除我的消息 + /// + /// + /// + /// + Task DeleteMyMessage(BaseIdInput input, long userId); + + /// + /// 获取消息详情 + /// + /// 输入参数 + /// 消息详情 + Task Detail(MessageDetailInput input); + + /// + /// 我的消息列表 + /// + /// + /// + /// + Task> MyMessagePage(MessagePageInput input, long userId); + + /// + /// 分页查询 + /// + /// 查询参数 + /// + Task> Page(MessagePageInput input); + + + /// + /// 获取未读消息数 + /// + /// 用户Id + /// + Task> UnReadCount(long userId); + + /// + /// 最新未读 + /// + /// + /// + Task> NewUnRead(long userId); + + /// + /// 标记已读 + /// + /// + /// + Task SetRead(MessageReadInput input); + + /// + /// 删除消息 + /// + /// + /// + Task SetDelete(MessageReadInput input); + + /// + /// 新增 + /// + /// + /// + Task Add(MessageSendInput input); + + /// + /// 编辑 + /// + /// + /// + Task Edit(MessageSendUpdateInput input); +} diff --git a/SimpleAdmin.System/Services/Dev/Message/MessageService.cs b/SimpleAdmin.System/Services/Dev/Message/MessageService.cs new file mode 100644 index 0000000..d0d3117 --- /dev/null +++ b/SimpleAdmin.System/Services/Dev/Message/MessageService.cs @@ -0,0 +1,339 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using Masuit.Tools.DateTimeExt; + +namespace SimpleAdmin.System; + +/// +/// +/// +public class MessageService : DbRepository, IMessageService +{ + private readonly ILogger _logger; + private readonly ISimpleCacheService _simpleCacheService; + private readonly IRelationService _relationService; + private readonly IEventPublisher _eventPublisher; + + public MessageService(ILogger logger, ISimpleCacheService simpleCacheService, IRelationService relationService, + IEventPublisher eventPublisher) + { + _logger = logger; + _simpleCacheService = simpleCacheService; + _relationService = relationService; + _eventPublisher = eventPublisher; + } + + /// + public async Task> Page(MessagePageInput input) + { + var query = Context.Queryable().WhereIF(!string.IsNullOrEmpty(input.Category), it => it.Category == input.Category)//根据分类查询 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), + it => it.Subject.Contains(input.SearchKey) || it.Content.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}")//排序 + .OrderBy(it => it.CreateTime, OrderByType.Desc); + + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task> MyMessagePage(MessagePageInput input, long userId) + { + var query = Context.Queryable().LeftJoin((u, m) => u.MessageId == m.Id) + .Where((u, m) => u.IsDelete == false && u.UserId == userId && u.Status == SysDictConst.MESSAGE_STATUS_ALREADY) + .WhereIF(!string.IsNullOrEmpty(input.Category), (u, m) => m.Category == input.Category)//根据分类查询 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), + (u, m) => m.Subject.Contains(input.SearchKey) || m.Content.Contains(input.SearchKey))//根据关键字查询 + .OrderBy((u, m) => u.Read).OrderBy((u, m) => u.CreateTime, OrderByType.Desc).Select((u, m) => new SysMessage + { + Id = m.Id.SelectAll(), + Read = u.Read + }); + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task Add(MessageSendInput input) + { + CheckInput(input); + var sysMessage = input.Adapt();//实体转换 + sysMessage.Id = CommonUtils.GetSingleId(); + //如果是立即发送的直接修改状态 + if (sysMessage.SendWay == SysDictConst.SEND_WAY_NOW) + sysMessage.Status = SysDictConst.MESSAGE_STATUS_ALREADY;//已发送 + var messageUsers = new List(); + var userIds = new List(); + //根据接收人获取需要发送的用户id + switch (sysMessage.ReceiverType) + { + case SysDictConst.RECEIVER_TYPE_ALL: + userIds = await Context.Queryable().Select(it => it.Id).ToListAsync(); + break; + case SysDictConst.RECEIVER_TYPE_ROLE: + var roleIds = sysMessage.ReceiverInfo.Select(it => it.Id.ToString()).ToList();//获取角色ID列表 + var roleUsers = + await _relationService.GetRelationListByTargetIdListAndCategory(roleIds, CateGoryConst.RELATION_SYS_USER_HAS_ROLE);//获取角色用户列表 + userIds = roleUsers.Select(it => it.ObjectId).ToList();//获取用户ID列表 + break; + case SysDictConst.RECEIVER_TYPE_APPOINT: + userIds = sysMessage.ReceiverInfo.Select(it => it.Id).ToList(); + break; + } + //去掉自己 + userIds = userIds.Where(it => it != UserManager.UserId).ToList(); + + //遍历用户ID + userIds.ForEach(userId => + { + messageUsers.Add(new SysMessageUser + { + MessageId = sysMessage.Id, + UserId = userId, + Read = false, + IsDelete = false, + Status = sysMessage.SendWay == SysDictConst.SEND_WAY_NOW ? SysDictConst.MESSAGE_STATUS_ALREADY : SysDictConst.MESSAGE_STATUS_READY + }); + }); + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await InsertAsync(sysMessage);//添加消息 + await Context.Insertable(messageUsers).ExecuteCommandAsync(); + }); + if (result.IsSuccess)//如果成功了 + { + await _eventPublisher.PublishAsync(EventSubscriberConst.NEW_MESSAGE, new NewMessageEvent + { + Id = sysMessage.Id, + SendWay = sysMessage.SendWay, + SendTime = sysMessage.SendTime + });//通知用户有新的消息 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0003); + } + } + + /// + public async Task Edit(MessageSendUpdateInput input) + { + CheckInput(input); + var sysMessage = input.Adapt();//实体转换 + await UpdateAsync(sysMessage);//更新数据 + } + + + + + /// + public async Task Detail(MessageDetailInput input) + { + //获取消息 + var message = await GetFirstAsync(it => it.Id == input.Id); + if (message != null && message.SendWay == SysDictConst.SEND_WAY_DELAY) + { + //delayTime等于发送时间减掉创建时间 + message.DelayTime = (int)(message.SendTime.GetTotalSeconds() - message.CreateTime.Value.GetTotalSeconds()); + } + if (message != null && input.ShowReceiveInfo) + { + var messageUserRep = ChangeRepository>();//切换仓储 + var messageUsers = await messageUserRep.GetListAsync(it => it.MessageId == message.Id); + + var userIds = messageUsers.Select(it => it.UserId).ToList();//获取用户ID列表 + var userInfos = await Context.Queryable().Where(it => userIds.Contains(it.Id)).Select(it => new { it.Id, it.Name }) + .ToListAsync();//获取用户姓名信息列表 + //遍历关系 + messageUsers.ForEach(messageUser => + { + var user = userInfos.Where(u => u.Id == messageUser.UserId).FirstOrDefault();//获取用户信息 + if (user != null) + { + //添加到已读列表 + message.ReceiverDetail.Add(new ReceiverDetail + { + Id = user.Id, + Name = user.Name, + Read = messageUser.Read + }); + } + }); + } + //设置已读 + if (input.Read) + { + await Context.Updateable() + .SetColumns(it => it.Read == true) + .SetColumns(it => it.UpdateTime == DateTime.Now) + .Where(it => it.MessageId == input.Id && it.Read == false && it.UserId == UserManager.UserId).ExecuteCommandAsync(); + } + return message; + } + + + + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await DeleteAsync(it => ids.Contains(it.Id)); + await Context.Deleteable().Where(it => ids.Contains(it.MessageId)).ExecuteCommandAsync(); + }); + if (!result.IsSuccess)//如果失败了 + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + } + + /// + public async Task DeleteMyMessage(BaseIdInput input, long userId) + { + var messageUserRep = ChangeRepository>();//切换仓储 + await Context.Deleteable().Where(it => it.UserId == userId && it.MessageId == input.Id).IsLogic().ExecuteCommandAsync();//逻辑删除 + } + + /// + public async Task> UnReadCount(long userId) + { + // 连表查询未读 + var unReadList = await Context.Queryable().LeftJoin((m, u) => u.MessageId == m.Id) + .Where((m, u) => u.UserId == userId && u.Read == false && u.IsDelete == false) + .Select().ToListAsync(); + //根据消息分类分组 + var groupList = unReadList.GroupBy(it => it.Category).Select(it => new MessageUnReadOutPut + { + Category = it.Key, + UnReadCount = it.Count() + }).ToList(); + return groupList; + } + + /// + public async Task> NewUnRead(long userId) + { + //根据消息分类分组,获取每组未读前五条 + var result = await Context.Queryable().LeftJoin((m, u) => u.MessageId == m.Id) + .Where((m, u) => u.UserId == userId && u.IsDelete == false && u.Status == SysDictConst.MESSAGE_STATUS_ALREADY) + .Select((m, u) => new SysMessage + { + Index2 = SqlFunc.RowNumber($"{m.Id} desc", + m.Category),//order by id partition by name,参考sqlsugar分组查询https://www.donet5.com/Doc/1/2243 + Subject = m.Subject, + CreateTime = m.CreateTime, + SendTime = m.SendTime, + Category = m.Category, + Read = u.Read + }) + .MergeTable()//将结果合并成一个表 + .Where(it => it.Index2 <= 5)//取第五条 + .Mapper(it => + { + it.SendTimeFormat = TimeHelper.FormatTimeAgo(it.SendTime); + }) + .ToListAsync(); + return result; + } + + /// + public async Task SetRead(MessageReadInput input) + { + //如果ID列表为空,就是全部已读 + if (input.Ids.Count == 0 && input.Category != null) + { + var result = await Context.Updateable() + .SetColumns(it => it.Read == true) + .SetColumns(it => it.UpdateTime == DateTime.Now) + .Where(it => it.UserId == UserManager.UserId && it.Read == false) + .Where(it => SqlFunc.Subqueryable().Where(s => s.Id == it.MessageId && s.Category == input.Category).Any()) + .ExecuteCommandAsync(); + return result; + } + else + { + return await Context.Updateable() + .SetColumns(it => it.Read == true) + .SetColumns(it => it.UpdateTime == DateTime.Now) + .Where(it => it.UserId == UserManager.UserId && input.Ids.Contains(it.MessageId)) + .Where(it => it.Read == false) + .ExecuteCommandAsync(); + } + } + + /// + public async Task SetDelete(MessageReadInput input) + { + //如果ID列表为空,就是全部删除 + if (input.Ids.Count == 0 && input.Category != null) + { + var result = await Context.Updateable() + .SetColumns(it => it.IsDelete == true) + .SetColumns(it => it.UpdateTime == DateTime.Now) + .Where(it => it.UserId == UserManager.UserId && it.IsDelete == false) + .Where(it => SqlFunc.Subqueryable().Where(s => s.Id == it.MessageId && s.Category == input.Category).Any()) + .ExecuteCommandAsync(); + return result; + } + else + { + return await Context.Updateable() + .SetColumns(it => it.IsDelete == true) + .SetColumns(it => it.UpdateTime == DateTime.Now) + .Where(it => it.UserId == UserManager.UserId && input.Ids.Contains(it.MessageId)) + .Where(it => it.IsDelete == false) + .ExecuteCommandAsync(); + } + } + + #region 方法 + + /// + /// 检查输入 + /// + /// + private void CheckInput(MessageSendInput input) + { + if (input.Status == SysDictConst.MESSAGE_STATUS_ALREADY) + throw Oops.Oh("已发送的消息不能修改"); + switch (input.SendWay) + { + case SysDictConst.SEND_WAY_NOW: + input.SendTime = DateTime.Now; + break; + case SysDictConst.SEND_WAY_DELAY: + if (input.CreateTime != null) + input.SendTime = input.CreateTime.Value.AddSeconds(input.DelayTime); + else + input.SendTime = DateTime.Now.AddSeconds(input.DelayTime); + break; + case SysDictConst.SEND_WAY_SCHEDULE: + if (input.SendTime < DateTime.Now) + throw Oops.Oh("发送时间不能小于当前时间"); + input.SendTime = input.SendTime; + break; + } + } + + #endregion +} diff --git a/SimpleAdmin.System/Services/Gen/Basic/Dto/GenBasicInput.cs b/SimpleAdmin.System/Services/Gen/Basic/Dto/GenBasicInput.cs new file mode 100644 index 0000000..399e8b9 --- /dev/null +++ b/SimpleAdmin.System/Services/Gen/Basic/Dto/GenBasicInput.cs @@ -0,0 +1,180 @@ +namespace SimpleAdmin.System; + +/// +/// 代码生成基础添加参数 +/// +public class GenBasicAddInput : GenBasic, IValidatableObject +{ + /// + /// 所属库名称 + /// + [Required(ErrorMessage = "ConfigId不能为空")] + public override string ConfigId { get; set; } + + /// + /// 主表名称 + /// + [Required(ErrorMessage = "BbTable不能为空")] + public override string DbTable { get; set; } + + /// + /// 功能列表 + /// + [Required(ErrorMessage = "FuncList不能为空")] + public override List? FuncList { get; set; } + + /// + /// 生成模版 + /// + [Required(ErrorMessage = "ModuleType不能为空")] + public override string ModuleType { get; set; } + + /// + /// 数据权限 + /// + [Required(ErrorMessage = "DataPermission不能为空")] + public override string DataPermission { get; set; } + + /// + /// 实体名称 + /// + [Required(ErrorMessage = "EntityName不能为空")] + public override string EntityName { get; set; } + + /// + /// 表前缀移除 + /// + [Required(ErrorMessage = "TablePrefix不能为空")] + public override string TablePrefix { get; set; } + + /// + /// 生成方式 + /// + [Required(ErrorMessage = "GenerateType不能为空")] + public override string GenerateType { get; set; } + + /// + /// 所属模块 + /// + [IdNotNull(ErrorMessage = "Module不能为空")] + public override long Module { get; set; } + + /// + /// 路由名 + /// + [Required(ErrorMessage = "RouteName不能为空")] + public override string RouteName { get; set; } + + + /// + /// 图标 + /// + [Required(ErrorMessage = "Icon不能为空")] + public override string Icon { get; set; } + + /// + /// 功能名 + /// + [Required(ErrorMessage = "FunctionName不能为空")] + public override string FunctionName { get; set; } + + /// + /// 业务名 + /// + [Required(ErrorMessage = "BusName不能为空")] + public override string BusName { get; set; } + + /// + /// 类名 + /// + [Required(ErrorMessage = "ClassName不能为空")] + public override string ClassName { get; set; } + + /// + /// 表单布局 + /// + [Required(ErrorMessage = "FormLayout不能为空")] + public override string FormLayout { get; set; } + + /// + /// 使用栅格 + /// + [Required(ErrorMessage = "GridWhether不能为空")] + public override string GridWhether { get; set; } + + /// + /// 左侧树 + /// + [Required(ErrorMessage = "LeftTree不能为空")] + public override string LeftTree { get; set; } + + /// + /// 前端路径 + /// + [Required(ErrorMessage = "FrontedPath不能为空")] + public override string FrontedPath { get; set; } + + /// + /// 服务层 + /// + [Required(ErrorMessage = "ServicePosition不能为空")] + public override string ServicePosition { get; set; } + + /// + /// 控制器层 + /// + [Required(ErrorMessage = "ControllerPosition不能为空")] + public override string ControllerPosition { get; set; } + + /// + /// 排序 + /// + [Required(ErrorMessage = "SortCode不能为空")] + public override int SortCode { get; set; } + + /// + /// 作者名 + /// + [Required(ErrorMessage = "AuthorName不能为空")] + public override string AuthorName { get; set; } + + public IEnumerable Validate(ValidationContext validationContext) + { + //如果是树形结构 + if (ModuleType.Contains("tree")) + { + if (string.IsNullOrEmpty(TreeId) || string.IsNullOrEmpty(TreeName) || string.IsNullOrEmpty(TreePid)) + yield return new ValidationResult($"必须配置树表相关信息", new[] { nameof(TreeId), nameof(TreeName), nameof(TreePid) }); + } + //如果是树形结构 + if (ModuleType.Contains("master")) + { + if (string.IsNullOrEmpty(ChildFk) || string.IsNullOrEmpty(ChildTable)) + yield return new ValidationResult($"必须配置主子表相关信息", new[] { nameof(ChildTable), nameof(ChildFk) }); + } + if (!FuncList.Contains("curd")) + { + yield return new ValidationResult($"必须包含基础的增删改查功能", new[] { nameof(FuncList) }); + } + } +} + +/// +/// 代码生成基础编辑参数 +/// +public class GenBasicEditInput : GenBasicAddInput +{ + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} + +/// +/// 执行代码生成参数 +/// +public class ExecGenInput : BaseIdInput +{ + /// + /// 生成类型 + /// + public string ExecType { get; set; } +} diff --git a/SimpleAdmin.System/Services/Gen/Basic/Dto/GenBasicOutput.cs b/SimpleAdmin.System/Services/Gen/Basic/Dto/GenBasicOutput.cs new file mode 100644 index 0000000..b20b3bb --- /dev/null +++ b/SimpleAdmin.System/Services/Gen/Basic/Dto/GenBasicOutput.cs @@ -0,0 +1,67 @@ +namespace SimpleAdmin.System; + +/// +/// 表字段信息输出 +/// +public class GenBasicColumnOutput +{ + /// + /// 字段名称 + /// + public string ColumnName { get; set; } + + /// + /// 是否主键 + /// + public bool IsPrimarykey { get; set; } + + /// + /// 字段类型 + /// + public string TypeName { get; set; } + + /// + /// 字段注释 + /// + public string ColumnRemark { get; set; } +} + +/// +/// 预览代码生成结果 +/// +public class GenBasePreviewOutput +{ + /// + /// SQL代码结果集 + /// + public List SqlResults { get; set; } = new List(); + + /// + /// 前端代码结果集 + /// + public List CodeFrontendResults { get; set; } = new List(); + + /// + /// 后端代码结果集 + /// + + public List CodeBackendResults { get; set; } = new List(); + + public class GenBaseCodeResult + { + /// + /// 代码文件名称 + /// + public string CodeFileName { get; set; } + + /// + /// 文件路径 + /// + public string FilePath { get; set; } + + /// + /// 代码文件内容 + /// + public string CodeFileContent { get; set; } + } +} diff --git a/SimpleAdmin.System/Services/Gen/Basic/Dto/GenViewModel.cs b/SimpleAdmin.System/Services/Gen/Basic/Dto/GenViewModel.cs new file mode 100644 index 0000000..d4853bf --- /dev/null +++ b/SimpleAdmin.System/Services/Gen/Basic/Dto/GenViewModel.cs @@ -0,0 +1,254 @@ +using StringHelper = SimpleTool.StringHelper; + +namespace SimpleAdmin.System; + +/// +/// 代码生成绑定视图 +/// +public class GenViewModel : GenBasic +{ + #region 基础 + + /// + /// 生成时间 + /// + public string GenTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + + /// + /// 表字段 + /// + public List TableFields { get; set; } + + #endregion 基础 + + #region 菜单 + + /// + /// 菜单ID + /// + public long MenuId { get; set; } = CommonUtils.GetSingleId(); + + /// + /// 菜单编码 + /// + public string MenuCode { get; set; } + + /// + /// /菜单路径 + /// + public string MenuPath + { + get { return $"/{RouteName}/{BusName}"; } + } + + /// + /// /菜单路径 + /// + public string MenuComponent + { + get { return $"{RouteName}/{BusName}/index"; } + } + + #endregion 菜单 + + #region 按钮 + + /// + /// 添加按钮ID + /// + public long AddButtonId { get; set; } = CommonUtils.GetSingleId(); + + /// + /// 批量删除按钮ID + /// + public long BatchDeleteButtonId { get; set; } = CommonUtils.GetSingleId(); + + /// + /// 编辑按钮ID + /// + public long EditButtonId { get; set; } = CommonUtils.GetSingleId(); + + /// + /// 删除按钮ID + /// + public long DeleteButtonId { get; set; } = CommonUtils.GetSingleId(); + + #endregion 按钮 + + + #region 后端 + + /// + /// 类名首字母小写 + /// + public string ClassNameFirstLower + { + get { return StringHelper.FirstCharToLower(ClassName); } + } + + /// + /// swagger分组名称 + /// + public string ApiGroup + { + get + { + return ServicePosition.Split(".").Last(); + } + } + + /// + /// 服务名 + /// + public string ServiceName + { + get { return ClassName + "Service"; } + } + + /// + /// 服务名开头首字母小写 + /// + public string ServiceFirstLower + { + get { return ClassNameFirstLower + "Service"; } + } + + #endregion 后端 + + #region 注释描述 + + /// + /// 分页查询 + /// + public string DescriptionPage + { + get { return FunctionName + "分页查询"; } + } + + /// + /// 列表查询 + /// + public string DescriptionList + { + get { return FunctionName + "列表查询"; } + } + + /// + /// 添加 + /// + public string DescriptionAdd + { + get { return "添加" + FunctionName; } + } + + /// + /// 修改 + /// + public string DescriptionEdit + { + get { return "修改" + FunctionName; } + } + + /// + /// 修改 + /// + public string DescriptionDelete + { + get { return "删除" + FunctionName; } + } + + /// + /// 详情 + /// + public string DescriptionDetail + { + get { return FunctionName + "详情"; } + } + + + /// + /// 导入 + /// + public string DescriptionImport + { + get { return FunctionName + "导入"; } + } + + /// + /// 导入模板下载 + /// + public string DescriptionTemplate + { + get { return FunctionName + "导入模板下载"; } + } + + /// + /// 导入预览 + /// + public string DescriptionPreview + { + get { return FunctionName + "导入预览"; } + } + + /// + /// 导入 + /// + public string DescriptionExport + { + get { return FunctionName + "导出"; } + } + + /// + /// 批量编辑 + /// + public string DescriptionEdits + { + get { return FunctionName + "批量编辑"; } + } + + /// + /// 树查询 + /// + public string DescriptionTree + { + get { return FunctionName + "树"; } + } + + #endregion 注释描述 + + #region 参数 + + /// + /// 分页参数 + /// + public string PageInput + { + get { return ClassName + "PageInput"; } + } + + /// + /// 添加参数 + /// + public string AddInput + { + get { return ClassName + "AddInput"; } + } + + /// + /// 编辑参数 + /// + public string EditInput + { + get { return ClassName + "EditInput"; } + } + + /// + /// 树查询参数 + /// + public string TreeInput + { + get { return ClassName + "TreeInput"; } + } + + #endregion 参数 +} diff --git a/SimpleAdmin.System/Services/Gen/Basic/GenBasicService.cs b/SimpleAdmin.System/Services/Gen/Basic/GenBasicService.cs new file mode 100644 index 0000000..b63dd2b --- /dev/null +++ b/SimpleAdmin.System/Services/Gen/Basic/GenBasicService.cs @@ -0,0 +1,808 @@ +using StringHelper = SimpleTool.StringHelper; + +namespace SimpleAdmin.System; + +/// +/// +/// +public class GenBasicService : DbRepository, IGenbasicService +{ + private readonly ILogger _logger; + private readonly IViewEngine _viewEngine; + private readonly IGenConfigService _genConfigService; + private readonly IMenuService _menuService; + private readonly IButtonService _buttonService; + private readonly ISysRoleService _roleService; + private readonly string _sqlDir = "Sql"; + private readonly string _backendDir = "Backend"; + private readonly string _frontDir = "Frontend"; + private const string _interfaceDir = "interface"; + private const string _modulesDir = "modules"; + private const string _indexTs = "index.ts"; + + public GenBasicService(ILogger logger, + IViewEngine viewEngine, + IGenConfigService genConfigService, + IMenuService menuService, + IButtonService buttonService, ISysRoleService roleService) + { + _logger = logger; + _viewEngine = viewEngine; + _genConfigService = genConfigService; + _menuService = menuService; + _buttonService = buttonService; + _roleService = roleService; + } + + /// + public async Task> Page(BasePageInput input) + { + var query = Context.Queryable() + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}")//排序 + .OrderBy(it => it.SortCode, OrderByType.Desc)//默认排序 + .OrderBy(it => it.CreateTime, OrderByType.Desc)//默认排序 + .Mapper(it => + { + it.FuncList = it.Functions.Split(",", StringSplitOptions.RemoveEmptyEntries).ToList();//功能集合转为列表 + }); + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public List GetTables(bool isAll = false) + { + if (isAll) + return SqlSugarUtils.GetTablesByAttribute(); + return SqlSugarUtils.GetTablesByAttribute(); + } + + + + /// + public List GetAssemblies() + { + var names = new List();//结果集 + var excludeList = new List + { + "Web.Entry", "Core", "Cache", "SqlSugar", "Plugin.Core", "Plugin.Aop" + };//排除的程序集 + //获取所有程序集名称 + var assemblies = App.Assemblies + .Where(it => !it.FullName.StartsWith("MoYu")) + .Select(it => it.FullName).ToList(); + assemblies.ForEach(it => + { + var name = it.Split(",")[0];//根据逗号分割取第一个 + //根据.分割获取最后两个 + + + var projectName = string.Join(".", name.Split(".").Skip(1).ToList()); + if (!excludeList.Contains(projectName))//去掉排除的程序集 + { + names.Add(name); + } + }); + return names; + } + + + /// + public async Task Add(GenBasicAddInput input) + { + var entity = input.Adapt();//输入参数转实体 + entity.Functions = string.Join(",", input.FuncList);//功能集合 + var tableColumns = SqlSugarUtils.GetTableColumns(input.ConfigId, input.DbTable);//获取表的字段信息 + var genConfigs = new List();//代码生成配置字段集合 + //遍历字段 + var sortCode = 0; + //遍历字段 + tableColumns.ForEach(it => + { + #region 判断是否想显示 + + var yesOrNo = GenConst.Yes; + if (it.IsPrimaryKey || SqlSugarUtils.IsCommonColumn(it.ColumnName))//如果是主键或者是公共字段则不显示 + yesOrNo = GenConst.No; + else + yesOrNo = GenConst.Yes; + + #endregion 判断是否想显示 + + //添加到字段集合 + genConfigs.Add(new GenConfig + { + IsPrimaryKey = it.IsPrimaryKey ? GenConst.Yes : GenConst.No, + FieldName = it.ColumnName, + FieldType = it.DataType, + FieldNetType = SqlSugarUtils.ConvertDataType(it.DataType), + FieldRemark = it.ColumnDescription ?? it.ColumnName, + EffectType = EffTypeConst.INPUT, + Width = 100, + WhetherTable = yesOrNo, + WhetherAddUpdate = yesOrNo, + WhetherImportExport = yesOrNo, + WhetherResizable = GenConst.No, + WhetherRequired = GenConst.No, + WhetherRetract = GenConst.No, + QueryWhether = GenConst.No, + SortCode = yesOrNo == GenConst.No ? 99 : sortCode//如果是公共字段就排最后 + }); + sortCode++; + }); + var index = 0; + genConfigs = genConfigs.OrderBy(it => it.SortCode).ToList();//排序 + genConfigs.ForEach(it => + { + it.FieldIndex = index; + index++; + }); + if (!genConfigs.Any(it => it.IsPrimaryKey == GenConst.Yes))//判断是否有主键 + { + throw Oops.Bah("要生成的表必须有主键"); + } + + //事务 + var result = await Tenant.UseTranAsync(async () => + { + entity = await InsertReturnEntityAsync(entity);//输入参数转实体并插入 + genConfigs.ForEach(it => { it.BasicId = entity.Id; });//遍历字段赋值基础Id + await Context.Insertable(genConfigs).ExecuteCommandAsync(); + }); + if (!result.IsSuccess)//如果失败了 + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0003); + } + + return entity; + } + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids.ToList(); + if (ids.Count > 0) + { + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await DeleteByIdsAsync(ids.Cast().ToArray());//删除基础表 + await Context.Deleteable().Where(it => ids.Contains(it.BasicId)) + .ExecuteCommandAsync();//删除配置表 + }); + if (!result.IsSuccess)//如果失败了 + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + } + + /// + public async Task Edit(GenBasicEditInput input) + { + var entity = input.Adapt();//输入参数转实体 + entity.Functions = string.Join(",", input.FuncList);//功能集合 + await UpdateAsync(entity); + return entity; + } + + /// + public async Task PreviewGen(BaseIdInput input) + { + var genBasic = await GetGenBasic(input.Id);//获取代码生成基础 + return await PreviewGen(genBasic); + } + + /// + public async Task ExecGenPro(ExecGenInput input) + { + var genBasic = await GetGenBasic(input.Id);//获取代码生成基础 + if (genBasic.GenerateType != GenConst.Pro) throw Oops.Bah("当前配置生成方式为:项目中"); + var backendPath = + Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.FullName);//获取主工程目录 + if (await CreateMenuButtonAndRelation(genBasic)) + { + var previewCode = await PreviewGen(genBasic);//获取代码生成预览 + if (input.ExecType != GenConst.ExecAll)//如果不是全部执行 + { + if (input.ExecType == GenConst.ExecBackend) + ExecBackend(previewCode.CodeBackendResults);//执行后端代码生成 + else if (input.ExecType == GenConst.ExecFrontend) + ExecFronted(previewCode.CodeFrontendResults);//执行前端代码生成 + } + else + { + ExecBackend(previewCode.CodeBackendResults);//执行后端代码生成 + + ExecFronted(previewCode.CodeFrontendResults);//执行前端代码生成 + } + } + else + { + throw Oops.Bah("代码生成失败"); + } + } + + /// + public async Task ExecGenZip(ExecGenInput input) + { + var genBasic = await GetGenBasic(input.Id);//获取代码生成基础 + // if (genBasic.GenerateType != GenConst.Zip) throw Oops.Bah("当前配置生成方式为:压缩包"); + var temDir = Path.GetTempPath().CombinePath(genBasic.ClassName);//获取临时目录并用类名做存放代码文件文件夹 + File.Delete(temDir + ".zip");// 先删除压缩包 + var previewCode = await PreviewGen(genBasic);//获取代码生成预览 + if (input.ExecType != GenConst.ExecAll)//如果不是全部执行 + { + if (input.ExecType == GenConst.ExecBackend) + { + ExecBackend(previewCode.CodeBackendResults, temDir.CombinePath(_backendDir), true);//执行后端代码生成 + ExecSql(previewCode.SqlResults, temDir);//执行sql生成 + } + else if (input.ExecType == GenConst.ExecFrontend) + ExecFronted(previewCode.CodeFrontendResults, temDir.CombinePath(_frontDir));//执行前端生成 + } + else + { + ExecBackend(previewCode.CodeBackendResults, temDir.CombinePath(_backendDir), true);//执行后端代码生成 + ExecFronted(previewCode.CodeFrontendResults, temDir.CombinePath(_frontDir));//执行前端生成 + ExecSql(previewCode.SqlResults, temDir);//执行sql生成 + } + var zipPath = ZipUtils.CompressDirectory(temDir, true);//压缩文件夹 + var result = new FileStreamResult(new FileStream(zipPath, FileMode.Open), "application/octet-stream") + { FileDownloadName = $"{genBasic.ClassName}.zip" }; + return result; + } + + #region 方法 + + /// + /// 生成后端代码文件 + /// + /// 后端代码模板 + /// 代码基础 + /// 后端生成路径 + /// 是否是zip方式 + // public void ExecBackend(List baseCodeResults, GenBasic genBasic, + // string backendPath, bool isZip = false) + // { + // var serviceDir = "Services";//服务代码文件夹 + // var controllerDir = "Controllers";//服务代码文件夹 + // var tempDicName = "";//临时文件夹名称 + // var dirList = new HashSet { };//文件夹列表 + // var postion = "";//文件夹位置 + // var parentDir = _backendDir;//父文件文件夹名称 + // var serviceName = genBasic.ServicePosition.Split(".").Last();//取服务层最后一个单词命名为接口层控制器下的文件夹 + // baseCodeResults.ForEach(it => + // { + // var fileInfo = new FileInfo(it.FilePath);//获取文件信息 + // var dirName = fileInfo.Directory.Name;//获取文件文件夹名称 + // var parentName = fileInfo.Directory.Parent.Name;//获取父文件文件夹名称 + // if (dirName == controllerDir)//如果是控制器 + // { + // dirList.Add(dirName);//添加到当前文件夹到文件夹列表 + // dirList.Add(serviceName);//添加服务层目录名到文件夹列表 + // postion = genBasic.ControllerPosition;//设置文件夹创建位置为Api层 + // } + // else if (dirName == serviceDir)//如果是服务 + // { + // dirList.Remove(controllerDir);//删除接口文件夹 + // dirList.Remove(serviceName);//删除服务层目录 + // dirList.Add(genBasic.ClassName);//添加ClassName到文件夹列表 + // dirList.Add(dirName);//添加到当前文件夹到文件夹列表 + // postion = genBasic.ServicePosition;//设置文件夹创建位置为服务层 + // } + // + // if (parentDir != parentName)//如果当前文件的父文件夹不等于partDir表示层级有变动 + // { + // dirList.Add(dirName);//添加到文件夹列表 + // parentDir = parentName;//重新赋值父文件夹 + // } + // else + // { + // if (tempDicName != dirName)//如果临时文件夹不是当前文件夹表示同级目录下的另一个文件夹 + // { + // dirList.Remove(tempDicName);//删除上一个文件夹 + // dirList.Add(dirName);//添加当前文件夹到文件夹列表 + // } + // } + // + // tempDicName = dirName;//给临时文件夹赋值 + // var path = backendPath;//后端文件目录 + // if (!isZip) path = backendPath.CombinePath(postion);//如果不是zip方式就加上命名空间 + // path = path.CombinePath(dirList.ToArray()); + // if (!Directory.Exists(path))//如果文件夹不存在就创建文件夹 + // Directory.CreateDirectory(path); + // //var fileName = genBasic.ClassName + it.CodeFileName;//文件名等于类名加代码文件名 + // //if (it.CodeFileName.StartsWith("IService")) + // // fileName = $"I{genBasic.ClassName}Service.cs";//对IService接口要特殊处理 + // //path = path.CombinePath(fileName);//最终生成文件地址 + // File.WriteAllText(path.CombinePath(it.CodeFileName), it.CodeFileContent, Encoding.UTF8);//写入文件 + // }); + // } + public void ExecBackend(List baseCodeResults, string backendPath = null, bool isZip = false) + { + //遍历baseCodeResults + baseCodeResults.ForEach(it => + { + var path = it.FilePath; + //判断path所属的文件夹 + var dir = Path.GetDirectoryName(path); + //如果backendPath不为空,则将path设置为backendPath.CombinePath($"{it.CodeFileName}") + if (backendPath != null) + { + path = backendPath.CombinePath($"{it.CodeFileName}"); + //重新获取path所属的文件夹 + dir = Path.GetDirectoryName(path); + } + //如果不存在就创建文件夹 + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(dir); + } + File.WriteAllText(path, it.CodeFileContent, Encoding.UTF8);//写入文件 + }); + } + + /// + /// 生成前端代码文件 + /// + /// 前端代码模板 + /// 前端生成路径 + public void ExecFronted(List baseCodeResults, string frontedPath = null) + { + baseCodeResults.ForEach(it => + { + var path = it.FilePath; + //判断path所属的文件夹 + var dir = Path.GetDirectoryName(path); + if (frontedPath != null) + { + path = frontedPath.CombinePath($"{it.CodeFileName}"); + dir = Path.GetDirectoryName(path); + } + + //如果不存在就创建文件夹 + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(dir); + } + File.WriteAllText(path, it.CodeFileContent, Encoding.UTF8);//写入文件 + }); + } + + /// + /// 生成sql代码文件 + /// + /// 后端代码模板 + /// 生成路径 + public void ExecSql(List baseCodeResults, string execPath) + { + execPath = execPath.CombinePath(_sqlDir);//写在sql目录里面 + if (!Directory.Exists(execPath))//如果文件夹不存在就创建文件夹 + Directory.CreateDirectory(execPath); + baseCodeResults.ForEach(it => + { + File.WriteAllText(execPath.CombinePath(it.CodeFileName), it.CodeFileContent, Encoding.UTF8);//写入文件 + }); + } + + /// + /// 获取sql代码预览结果 + /// + /// 视图 + /// 模板路径 + /// + public async Task> GetSqlCodeResult(GenViewModel genViewModel, + string templatePath) + { + var sqlCodeResults = new List();//结果集 + var sqlTemplatePath = Path.Combine(templatePath, _sqlDir);//获取sql模板文件路径 + + var files = GetAllFileInfo(sqlTemplatePath); + foreach (var fileInfo in files) + { + var fileName = fileInfo.Name;//文件名 + var fileNoPrefix = fileName.Split(fileInfo.Extension)[0];//不带模板后缀的文件名 + var tContent = File.ReadAllText(fileInfo.FullName);//读取文件 + var tResult = await GetViewEngine(tContent, genViewModel);//渲染 + //将渲染结果添加到结果集 + sqlCodeResults.Add(new GenBasePreviewOutput.GenBaseCodeResult + { + CodeFileContent = tResult, + CodeFileName = fileNoPrefix, + FilePath = fileInfo.FullName + }); + } + + return sqlCodeResults; + } + + /// + /// 获取后端代码预览结果 + /// + /// 视图 + /// 模板路径 + /// + public async Task> GetBackendCodeResult(GenViewModel genViewModel, + string templatePath) + { + var backendCodeResults = new List();//结果集 + var backendTemplatePath = Path.Combine(templatePath, _backendDir);//获取后端模板文件路径 + var serviceDir = new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.FullName.CombinePath(genViewModel.ServicePosition);//服务文件夹 + var serviceDicList = genViewModel.ServiceDictionary.Split("/").Where(it => !string.IsNullOrWhiteSpace(it)).ToList();//获取文件夹 + foreach (var item in serviceDicList) + { + serviceDir = serviceDir.CombinePath(item); + } + serviceDir = serviceDir.CombinePath(genViewModel.ClassName); + //获取控制器文件夹和后面的路径 + var controllerDir = new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.FullName.CombinePath(genViewModel.ControllerPosition); + var controllerDicList = genViewModel.ControllerDictionary.Split("/").Where(it => !string.IsNullOrWhiteSpace(it)).ToList(); + foreach (var item in controllerDicList) + { + controllerDir = controllerDir.CombinePath(item); + } + controllerDir = controllerDir.CombinePath(genViewModel.ClassName); + var files = GetAllFileInfo(backendTemplatePath); + // files = files.Where(it => it.Name == "Service.cs.vm").ToArray();//测试用 + var serviceFiles = files.Where(it => it.FullName.Contains("Service.cs")).ToList(); + var controllerFiles = files.Where(it => it.FullName.Contains("Controller.cs")).ToList(); + var dtoDir = files.Where(it => it.FullName.Contains("Dto")).ToList(); + foreach (var fileInfo in serviceFiles) + { + var nameWithPrefix = fileInfo.Name;//文件名 + var fileNoPrefix = nameWithPrefix.Split(fileInfo.Extension)[0];//不带模板后缀的文件名 + var tContent = File.ReadAllText(fileInfo.FullName);//读取文件 + var fileName = genViewModel.ClassName + fileNoPrefix;//文件名等于类名加代码文件名 + if (fileNoPrefix.StartsWith("IService")) + fileName = $"I{genViewModel.ClassName}Service.cs";//对IService接口要特殊处理 + var tResult = await GetViewEngine(tContent, genViewModel);//渲染 + //将渲染结果添加到结果集 + backendCodeResults.Add(new GenBasePreviewOutput.GenBaseCodeResult + { + CodeFileContent = tResult, + CodeFileName = $"{genViewModel.ClassName}{fileNoPrefix}", + FilePath = serviceDir.CombinePath(fileName) + }); + } + foreach (var fileInfo in controllerFiles) + { + var nameWithPrefix = fileInfo.Name;//文件名 + var fileNoPrefix = nameWithPrefix.Split(fileInfo.Extension)[0];//不带模板后缀的文件名 + var tContent = File.ReadAllText(fileInfo.FullName);//读取文件 + var fileName = genViewModel.ClassName + fileNoPrefix;//文件名等于类名加代码文件名 + var tResult = await GetViewEngine(tContent, genViewModel);//渲染 + //将渲染结果添加到结果集 + backendCodeResults.Add(new GenBasePreviewOutput.GenBaseCodeResult + { + CodeFileContent = tResult, + CodeFileName = $"{genViewModel.ClassName}{fileNoPrefix}", + FilePath = controllerDir.CombinePath(fileName) + }); + } + foreach (var fileInfo in dtoDir) + { + var nameWithPrefix = fileInfo.Name;//文件名 + var fileNoPrefix = nameWithPrefix.Split(fileInfo.Extension)[0];//不带模板后缀的文件名 + var tContent = File.ReadAllText(fileInfo.FullName);//读取文件 + var fileName = genViewModel.ClassName + fileNoPrefix;//文件名等于类名加代码文件名 + var tResult = await GetViewEngine(tContent, genViewModel);//渲染 + //将渲染结果添加到结果集 + backendCodeResults.Add(new GenBasePreviewOutput.GenBaseCodeResult + { + CodeFileContent = tResult, + CodeFileName = $"{genViewModel.ClassName}{fileNoPrefix}", + FilePath = serviceDir.CombinePath("Dto").CombinePath(fileName) + }); + } + return backendCodeResults; + } + + + /// + /// 获取前端代码预览结果 + /// + /// 视图 + /// 模板路径 + /// + public async Task> GetForntCodeResult(GenViewModel genViewModel, + string templatePath) + { + var frontCodeResults = new List();//结果集 + var frontTemplatePath = Path.Combine(templatePath, _frontDir);//获取前端模板文件路径 + var files = GetAllFileInfo(frontTemplatePath); + var srcDir = genViewModel.FrontedPath.CombinePath("src");//src文件夹 + var templateVm = "template.vm";//模板文件 + var view = "views";//视图文件夹 + var api = "api";//接口文件夹 + var componentsDir = "components";//组件文件夹 + var apiDir = srcDir.CombinePath(api); + var viewsDir = srcDir.CombinePath(view); + var template = files.Where(it => it.Name == templateVm).FirstOrDefault(); + if (templatePath == null) throw Oops.Bah($"{templateVm}文件不存在"); + var dirs = genViewModel.RouteName.Split("/").Where(it => !string.IsNullOrWhiteSpace(it)).ToList();// 根据路/分隔,获取文件夹名字 + //读取模板文件内容,utf-8编码 + var templateContent = File.ReadAllText(template.FullName, Encoding.UTF8); + var apiFiles = files.Where(it => it.FullName.Contains(api)).ToList(); + var viewFiles = files.Where(it => it.FullName.Contains(view)).ToList(); + foreach (var fileInfo in apiFiles) + { + var fileName = fileInfo.Name;//文件名 + //获取文件所在文件夹名字 + var dirName = fileInfo.Directory.Name; + var fileWhich = fileName.Split(".")[0];//获取是接口还是实现 + if (fileName == templateVm) continue; + var fileNoPrefix = $"{fileWhich}{genViewModel.RouteName}/{genViewModel.BusName}.ts";//不带模板后缀的文件名 + var filePath = apiDir.CombinePath(fileWhich);//生成文件路径 + //以["biz","ops"]为例,先去找api/interface文件夹下的index.ts文件 + //如果有就在index.ts文件中添加export * from "./biz",然后interfacePath路径就变成了api/interface/biz + //如果不存在这个文件夹,就表示需要创建这个文件夹,然后在这个文件夹下创建index.ts文件,导入下一层的文件也就是ops + for (var i = 0; i < dirs.Count; i++) + { + var it = dirs[i];//获取文件夹名 + var indexPath = filePath.CombinePath(_indexTs); + // 判断interfacePath路径下是否有index.ts文件,这里因为是typescript,所以需要引入 + if (File.Exists(indexPath)) + { + //读取文件内容 + var indexContent = File.ReadAllText(indexPath); + var content = $"export * from \"./{it}\";";//需要添加的内容 + //判断content是否存在 + if (!indexContent.Contains(content)) + { + indexContent += content; + } + var pathSplit = indexPath.Split($"{fileWhich}")[1]; + //先通过\分隔再用/合并字符串 + var codeFileName = $"{fileWhich}{pathSplit}".Split("\\").Aggregate((a, b) => a + "/" + b); + //加到结果集 + frontCodeResults.Add(new GenBasePreviewOutput.GenBaseCodeResult + { + CodeFileContent = indexContent, + CodeFileName = codeFileName, + FilePath = indexPath + }); + } + filePath = filePath.CombinePath(it);//拼接文件夹路径 + + if (!Directory.Exists(filePath))//如果文件夹不存在 + { + var index = filePath.CombinePath(_indexTs); + var pathSplit = index.Split($"{fileWhich}")[1]; + var indexContent = i + 1 == dirs.Count ? genViewModel.BusName : dirs[i + 1];//如果是最后一个就是busName + // 在当前内容下添加内容 + var content = templateContent + $"\n\nexport * from \"./{indexContent}\";"; + //加到结果集 + frontCodeResults.Add(new GenBasePreviewOutput.GenBaseCodeResult + { + CodeFileContent = content, + CodeFileName = $"{fileWhich}{pathSplit}", + FilePath = index + }); + } + } + var tContent = File.ReadAllText(fileInfo.FullName);//读取文件 + var tResult = await GetViewEngine(tContent, genViewModel);//渲染 + //将渲染结果添加到结果集 + frontCodeResults.Add(new GenBasePreviewOutput.GenBaseCodeResult + { + CodeFileContent = tResult, + CodeFileName = fileNoPrefix, + FilePath = filePath.CombinePath($"{genViewModel.BusName}.ts") + }); + } + //遍历视图文件 + foreach (var fileInfo in viewFiles) + { + var fileName = fileInfo.Name;//文件名 + //获取文件所在文件夹名字 + var dirName = fileInfo.Directory.Name; + var name = fileName.Split(".vm")[0];//不带模板后缀的文件名 + var fileNoPrefix = $"{dirName}/{name}";//不带模板后缀的文件名 + var filePath = viewsDir; + foreach (var dir in dirs) + { + filePath = filePath.CombinePath(dir); + } + filePath = filePath.CombinePath(genViewModel.BusName); + if (dirName == componentsDir)//如果是组件文件夹 + { + fileNoPrefix = $"{view}/{dirName}/{name}";//不带模板后缀的文件名 + filePath = filePath.CombinePath(componentsDir).CombinePath(name);//生成文件路径 + } + else + filePath = filePath.CombinePath(name);//生成文件路径 + var tContent = File.ReadAllText(fileInfo.FullName);//读取文件 + var tResult = await GetViewEngine(tContent, genViewModel);//渲染 + //将渲染结果添加到结果集 + frontCodeResults.Add(new GenBasePreviewOutput.GenBaseCodeResult + { + CodeFileContent = tResult, + CodeFileName = fileNoPrefix, + FilePath = filePath + }); + } + return frontCodeResults; + } + + + /// + /// 获取代码生成视图 + /// + /// + /// + public async Task GetGenViewModel(GenBasic genBasic) + { + //实体转视图 + var genViewEngine = genBasic.Adapt(); + //获取字段信息 + var tableFieldList = await _genConfigService.List(genBasic.Id); + tableFieldList.ForEach(it => + { + it.FieldNameFirstLower = StringHelper.FirstCharToLower(it.FieldName);//首字母小写 + it.FieldNameFirstUpper = StringHelper.FirstCharToUpper(it.FieldName);//首字母大写 + }); + genViewEngine.TableFields = tableFieldList;//赋值表字段信息 + + return genViewEngine; + } + + /// + /// 视图渲染 + /// + /// 模板内容 + /// 参数 + /// + public async Task GetViewEngine(string tContent, GenViewModel genViewModel) + { + //视图引擎渲染 + var tResult = await _viewEngine.RunCompileFromCachedAsync(tContent, genViewModel, builderAction: builder => + { + builder.AddAssemblyReference(typeof(GenBasic));//添加程序集 + builder.AddAssemblyReferenceByName("System.Collections");//添加程序集 + builder.AddAssemblyReferenceByName("SimpleTool");//添加程序集 + }); + return tResult; + } + + /// + /// 获得文件夹下所有的文件 + /// + /// 文件夹路径 + /// + private FileInfo[] GetAllFileInfo(string path) + { + var dir = new DirectoryInfo(path); + return dir.GetFiles(".", SearchOption.AllDirectories); + } + + /// + /// 代码生成预览 + /// + /// 基础配置 + /// + public async Task PreviewGen(GenBasic genBasic) + { + var basePath = AppContext.BaseDirectory;//获取项目目录 + var templatePath = basePath.CombinePath("ViewEngine").CombinePath("CodeGen");//获取文件路径 + templatePath = "D:\\胡国东\\SimpleAdmin.Net\\SimpleAdmin\\SimpleAdmin.System\\ViewEngine\\CodeGen";//测试用 + var genViewModel = await GetGenViewModel(genBasic); + var frontendResult = await GetForntCodeResult(genViewModel, templatePath); + var backendResult = await GetBackendCodeResult(genViewModel, templatePath); + var sqlResult = await GetSqlCodeResult(genViewModel, templatePath); + return new GenBasePreviewOutput + { + CodeBackendResults = backendResult, + SqlResults = sqlResult, + CodeFrontendResults = frontendResult + }; + } + + /// + /// 获取代码生成基础 + /// + /// + /// + private async Task GetGenBasic(long id) + { + var genBasic = await GetByIdAsync(id); + if (genBasic == null) + throw Oops.Bah("代码生成配置不存在"); + genBasic.FuncList = genBasic.Functions.Split(',').ToList(); + return genBasic; + } + + /// + /// 创建代码生成相关的菜单按钮和授权关系 + /// + /// + /// + private async Task CreateMenuButtonAndRelation(GenBasic genBasic) + { + try + { + #region 菜单 + + var title = genBasic.FunctionName + genBasic.FunctionNameSuffix; + var menuRep = ChangeRepository>();//切换仓储 + //获取已经存在的旧菜单 + var oldMenu = await menuRep.GetFirstAsync(it => it.Title == title + && it.Category == CateGoryConst.RESOURCE_MENU + && it.MenuType == SysResourceConst.MENU && + it.Code != SysResourceConst.SYSTEM); + if (oldMenu != null)//如果存在就直接和删除(同时删除其下面的菜单、按钮,清除对应的角色与资源信息) + await _menuService.Delete(new BaseIdListInput() + { + Ids = new List() + { + oldMenu.Id + } + }); + //添加菜单参数 + var menu = new MenuAddInput + { + Id = CommonUtils.GetSingleId(), + ParentId = genBasic.MenuPid, + Title = title, + Category = CateGoryConst.RESOURCE_MENU, + Module = genBasic.Module, + Icon = genBasic.Icon, + Name = genBasic.BusName, + Code = RandomHelper.CreateRandomString(10), + Path = $"{genBasic.RouteName}/{genBasic.BusName}", + Component = $"{genBasic.RouteName}/{genBasic.BusName}/index".TrimStart('/'), + SortCode = 99, + Status = CommonStatusConst.ENABLE, + IsKeepAlive = true + }; + await _menuService.Add(menu);//添加菜单 + + #endregion 菜单 + + #region 按钮 + + //添加按钮参数 + var button = new ButtonAddInput + { + Title = genBasic.FunctionName, + ParentId = menu.Id, + Code = StringHelper.FirstCharToLower(genBasic.ClassName), + Status = CommonStatusConst.ENABLE + }; + var buttonIds = await _buttonService.AddBatch(button);//添加按钮 + + #endregion 按钮 + + #region 角色授权 + + var roleRep = ChangeRepository>();//切换仓储 + var superAdmin = await roleRep.GetFirstAsync(it => + it.Code == SysRoleConst.SUPER_ADMIN && it.Category == CateGoryConst.ROLE_GLOBAL);//获取超级管理员 + //授权菜单参数 + var grantResource = new GrantResourceInput + { + Id = superAdmin.Id, + GrantInfoList = new List + { new RelationRoleResource { MenuId = menu.Id, ButtonInfo = buttonIds } }, + IsCodeGen = true + }; + await _roleService.GrantResource(grantResource);//授权菜单 + + #endregion 角色授权 + + return true; + } + catch (Exception ex) + { + _logger.LogError($"代码生成创建菜单和授权报错{ex.Message}", ex.InnerException); + return false; + } + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Gen/Basic/IGenbasicService.cs b/SimpleAdmin.System/Services/Gen/Basic/IGenbasicService.cs new file mode 100644 index 0000000..6befcb7 --- /dev/null +++ b/SimpleAdmin.System/Services/Gen/Basic/IGenbasicService.cs @@ -0,0 +1,70 @@ +namespace SimpleAdmin.System; + +/// +/// 代码生成基础服务 +/// +public interface IGenbasicService : ITransient +{ + /// + /// 添加代码生成器基础 + /// + /// + /// + Task Add(GenBasicAddInput input); + + /// + /// 删除代码生成配置 + /// + /// ID列表 + /// + Task Delete(BaseIdListInput input); + + /// + /// 编辑代码生成基础配置 + /// + /// + /// 代码生产基础 + Task Edit(GenBasicEditInput input); + + /// + /// 执行代码生成:本地 + /// + /// + /// + Task ExecGenPro(ExecGenInput input); + + /// + /// 执行代码生成:压缩包 + /// + /// + /// + Task ExecGenZip(ExecGenInput input); + + /// + /// 获取项目所有程序集 + /// + /// 程序集列表 + List GetAssemblies(); + + + /// + /// 获取表信息 + /// + /// 是否所有表 + /// 实体表列表 + List GetTables(bool isAll = false); + + /// + /// 获取代码生成基础分页 + /// + /// 查询参数 + /// 代码生成基础分页列表 + Task> Page(BasePageInput input); + + /// + /// 代码生成预览 + /// + /// 代码生成基础Id + /// 预览结果 + Task PreviewGen(BaseIdInput input); +} diff --git a/SimpleAdmin.System/Services/Gen/Config/Dto/GenConfigInput.cs b/SimpleAdmin.System/Services/Gen/Config/Dto/GenConfigInput.cs new file mode 100644 index 0000000..6667b9d --- /dev/null +++ b/SimpleAdmin.System/Services/Gen/Config/Dto/GenConfigInput.cs @@ -0,0 +1,5 @@ +namespace SimpleAdmin.System; + +public class GenConfigInput +{ +} diff --git a/SimpleAdmin.System/Services/Gen/Config/GenConfigService.cs b/SimpleAdmin.System/Services/Gen/Config/GenConfigService.cs new file mode 100644 index 0000000..e47147d --- /dev/null +++ b/SimpleAdmin.System/Services/Gen/Config/GenConfigService.cs @@ -0,0 +1,28 @@ +namespace SimpleAdmin.System; + +/// +/// +/// +public class GenConfigService : DbRepository, IGenConfigService +{ + private readonly ILogger logger; + + public GenConfigService(ILogger logger) + { + this.logger = logger; + } + + /// + public async Task> List(long basicId) + { + var configs = await GetListAsync(it => it.BasicId == basicId);//获取配置表相关配置 + configs = configs.OrderBy(it => it.FieldIndex).ToList();//排序一下 + return configs; + } + + /// + public async Task EditBatch(List configs) + { + await UpdateRangeAsync(configs);//批量更新 + } +} diff --git a/SimpleAdmin.System/Services/Gen/Config/IGenConfigService.cs b/SimpleAdmin.System/Services/Gen/Config/IGenConfigService.cs new file mode 100644 index 0000000..d356630 --- /dev/null +++ b/SimpleAdmin.System/Services/Gen/Config/IGenConfigService.cs @@ -0,0 +1,21 @@ +namespace SimpleAdmin.System; + +/// +/// 代码生成详细配置服务 +/// +public interface IGenConfigService : ITransient +{ + /// + /// 批量更新 + /// + /// + /// + Task EditBatch(List configs); + + /// + /// 查询代码生成详细配置列表 + /// + /// + /// 配置列表 + Task> List(long basicId); +} diff --git a/SimpleAdmin.System/Services/ImportExport/Dto/ImportPreviewInput.cs b/SimpleAdmin.System/Services/ImportExport/Dto/ImportPreviewInput.cs new file mode 100644 index 0000000..2eca9b7 --- /dev/null +++ b/SimpleAdmin.System/Services/ImportExport/Dto/ImportPreviewInput.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 导入预览输入 +/// +public class ImportPreviewInput : BaseFileInput +{ +} diff --git a/SimpleAdmin.System/Services/ImportExport/Dto/ImportPreviewOutput.cs b/SimpleAdmin.System/Services/ImportExport/Dto/ImportPreviewOutput.cs new file mode 100644 index 0000000..4c49d16 --- /dev/null +++ b/SimpleAdmin.System/Services/ImportExport/Dto/ImportPreviewOutput.cs @@ -0,0 +1,63 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 文件导入通用输出 +/// +public class ImportPreviewOutput where T : class +{ + /// + /// 是否有错误 + /// + public bool HasError { get; set; } + + /// + /// 动态表头 + /// + public List TableColumns { get; set; } = new List(); + + /// + /// 数据 + /// + public List Data { get; set; } +} + +/// +/// 动态表头 +/// +public class TableColumns +{ + /// + /// 标题 + /// + public string Title { get; set; } + + /// + /// 数据源 + /// + public string DataIndex { get; set; } + + /// + /// 宽度 + /// + public int Width { get; set; } = 120; + + /// + /// 超过宽度将自动省略 + /// + public bool Ellipsis { get; set; } + + /// + /// 是否是日期格式 + /// + public bool Date { get; set; } +} diff --git a/SimpleAdmin.System/Services/ImportExport/Dto/ImportResultInput.cs b/SimpleAdmin.System/Services/ImportExport/Dto/ImportResultInput.cs new file mode 100644 index 0000000..d17bd07 --- /dev/null +++ b/SimpleAdmin.System/Services/ImportExport/Dto/ImportResultInput.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 批量导入结果输入 +/// +/// +public class ImportResultInput where T : class +{ + /// + /// 数据 + /// + public List Data { get; set; } +} diff --git a/SimpleAdmin.System/Services/ImportExport/Dto/ImportResultOutPut.cs b/SimpleAdmin.System/Services/ImportExport/Dto/ImportResultOutPut.cs new file mode 100644 index 0000000..2d679d2 --- /dev/null +++ b/SimpleAdmin.System/Services/ImportExport/Dto/ImportResultOutPut.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 导入结果输出 +/// +public class ImportResultOutPut where T : class +{ + /// + /// 是否成功 + /// + + public bool Success { get; set; } = true; + + /// + /// 总数 + /// + public int Total { get; set; } + + /// + /// 导入数量 + /// + public int ImportCount { get; set; } + + /// + /// 错误数 + /// + public int FailCount { get; set; } + + /// + /// 数据 + /// + + public List Data { get; set; } = new List(); +} diff --git a/SimpleAdmin.System/Services/ImportExport/Dto/ImportTemplateInput.cs b/SimpleAdmin.System/Services/ImportExport/Dto/ImportTemplateInput.cs new file mode 100644 index 0000000..803f33c --- /dev/null +++ b/SimpleAdmin.System/Services/ImportExport/Dto/ImportTemplateInput.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 导入基础输入 +/// +[ExcelImporter(IsLabelingError = true)] +public class ImportTemplateInput +{ + /// + /// Id + /// + [ImporterHeader(IsIgnore = true)] + public long Id { get; set; } = CommonUtils.GetSingleId(); + + /// + /// 是否有错误 + /// + [ImporterHeader(IsIgnore = true)] + public bool HasError { get; set; } + + /// + /// 错误详情 + /// + [ImporterHeader(IsIgnore = true)] + public IDictionary ErrorInfo { get; set; } = new Dictionary(); +} diff --git a/SimpleAdmin.System/Services/ImportExport/IImportExportService.cs b/SimpleAdmin.System/Services/ImportExport/IImportExportService.cs new file mode 100644 index 0000000..596e54c --- /dev/null +++ b/SimpleAdmin.System/Services/ImportExport/IImportExportService.cs @@ -0,0 +1,75 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 导入服务 +/// +public interface IImportExportService : ITransient +{ + /// + /// 导出数据 + /// + /// + /// 数据 + /// 文件名 + /// 文件流 + Task Export(List data, string fileName) where T : class, new(); + + /// + /// 获取本地模板 + /// + /// 文件名 + /// 模板文件夹路径:默认wwwroot下的Template + /// 文件流 + FileStreamResult GenerateLocalTemplate(string fileName, string templateFolder = "Template"); + + /// + /// 生成模板 + /// + /// 实体类 + /// 文件名 + /// 文件流 + Task GenerateTemplate(string fileName) where T : class, new(); + + /// + /// 获取导入预览 + /// + /// + /// 文件 + /// 导入预览结果 + Task> GetImportPreview(IFormFile file) where T : ImportTemplateInput, new(); + + /// + /// 获取预计导入结果 + /// + /// + /// 数据 + /// 成功导入数据 + /// 预计导入结果 + ImportResultOutPut GetImportResultPreview(List data, out List importData) where T : ImportTemplateInput; + + /// + /// 导入文件验证 + /// + /// 文件 + /// 文件最大体积(M) + /// 允许的格式 + void ImportVerification(IFormFile file, int maxSize = 30, string[] allowTypes = null); + + /// + /// 模板数据验证 + /// + /// 模板类实体 + /// 结果 + /// 导入预览数据 + ImportPreviewOutput TemplateDataVerification(ImportResult importResult) where T : ImportTemplateInput; +} diff --git a/SimpleAdmin.System/Services/ImportExport/ImportExportService.cs b/SimpleAdmin.System/Services/ImportExport/ImportExportService.cs new file mode 100644 index 0000000..f48ef45 --- /dev/null +++ b/SimpleAdmin.System/Services/ImportExport/ImportExportService.cs @@ -0,0 +1,204 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class ImportExportService : IImportExportService +{ + #region 导入 + + /// + public void ImportVerification(IFormFile file, int maxSize = 30, string[] allowTypes = null) + { + if (file == null) throw Oops.Bah("文件不能为空"); + if (file.Length > maxSize * 1024 * 1024) throw Oops.Bah($"文件大小不允许超过{maxSize}M"); + var fileSuffix = Path.GetExtension(file.FileName).ToLower().Split(".")[1];// 文件后缀 + var allowTypeS = allowTypes == null ? new[] { "xlsx" } : allowTypes;//允许上传的文件类型 + if (!allowTypeS.Contains(fileSuffix)) throw Oops.Bah(errorMessage: "文件格式错误"); + } + + /// + public ImportPreviewOutput TemplateDataVerification(ImportResult importResult) where T : ImportTemplateInput + { + if (importResult.Exception != null) throw Oops.Bah("导入异常,请检查文件格式!"); + ////遍历模板错误 + importResult.TemplateErrors.ForEach(error => + { + if (error.Message.Contains("not found")) throw Oops.Bah($"列[{error.RequireColumnName}]未找到"); + throw Oops.Bah($"列[{error.RequireColumnName}]:{error.Message}"); + }); + if (importResult.Data == null) + throw Oops.Bah("文件数据格式有误,请重新导入!"); + + //导入结果输出 + var importPreview = new ImportPreviewOutput { HasError = importResult.HasError }; + var headerMap = new Dictionary(); + //遍历导入的表头列表信息 + importResult.ImporterHeaderInfos.ForEach(it => + { + headerMap.Add(it.Header.Name, it.PropertyName); + var tableColumns = new TableColumns + { Title = it.Header.Name.Split("(")[0], DataIndex = it.PropertyName.FirstCharToLower() };//定义表头,部分表头有说明用(分组去掉说明 + var antTableAttribute = it.PropertyInfo.GetCustomAttribute();//获取表格特性 + if (antTableAttribute != null) + { + tableColumns.Date = antTableAttribute.IsDate; + tableColumns.Ellipsis = antTableAttribute.Ellipsis; + tableColumns.Width = antTableAttribute.Width; + } + importPreview.TableColumns.Add(tableColumns);//添加到表头 + }); + + //导入的数据转集合 + var data = importResult.Data.ToList(); + var systemError = new string[] { };//系统错误提示 + //遍历错误列,将错误字典中的中文改成英文跟实体对应 + importResult.RowErrors.ForEach(row => + { + IDictionary fieldErrors = new Dictionary();//定义字典 + //遍历错误列,赋值给新的字典 + row.FieldErrors.ForEach(it => + { + var errrVaule = it.Value; + //value xx Invalid, please fill in the correct integer value! + //value xx Invalid, please fill in the correct date and time format! + if (it.Value.Contains("Invalid"))//如果错误信息有Invalid就提示格式错误 + errrVaule = $"{it.Key}格式错误"; + fieldErrors.Add(headerMap[it.Key], errrVaule); + }); + row.FieldErrors = fieldErrors;//替换新的字典 + row.RowIndex -= 2;//下表与列表中的下标一致 + data[row.RowIndex].HasError = true;//错误的行HasError = true + data[row.RowIndex].ErrorInfo = fieldErrors;//替换新的字典 + }); + data = data.OrderByDescending(it => it.HasError).ToList();//排序 + importPreview.Data = data;//重新赋值data + return importPreview; + } + + /// + public async Task GenerateTemplate(string fileName) where T : class, new() + { + IImporter importer = new ExcelImporter(); + var byteArray = await importer.GenerateTemplateBytes(); + var result = GetFileStreamResult(byteArray, fileName); + return result; + } + + /// + public FileStreamResult GenerateLocalTemplate(string fileName, string templateFolder = "Template") + { + var folder = App.WebHostEnvironment.WebRootPath.CombinePath(templateFolder); + return GetFileStreamResult(folder, fileName, true); + } + + /// + public async Task> GetImportPreview(IFormFile file) where T : ImportTemplateInput, new() + { + ImportVerification(file);//验证文件 + IImporter importer = new ExcelImporter(); + using var fileStream = file.OpenReadStream();//获取文件流 + var import = await importer.Import(fileStream);//导入的文件转化为带入结果 + var importPreview = TemplateDataVerification(import);//验证数据完整度 + return importPreview; + } + + /// + public ImportResultOutPut GetImportResultPreview(List data, out List importData) where T : ImportTemplateInput + { + //定义结果 + var result = new ImportResultOutPut { Total = data.Count }; + //可以导入的数据 + importData = data.Where(it => it.HasError == false).ToList(); + //如果有错误 + if (importData.Count != data.Count) + { + result.Success = false; + result.Data = data.Where(it => it.HasError).ToList(); + result.FailCount = data.Count - importData.Count; + } + result.ImportCount = importData.Count; + return result; + } + + #endregion 导入 + + #region 导出 + + public async Task Export(List data, string fileName) where T : class, new() + { + IExporter exporter = new ExcelExporter(); + var byteArray = await exporter.ExportAsByteArray(data); + var result = GetFileStreamResult(byteArray, fileName); + return result; + } + + #endregion 导出 + + #region 方法 + + /// + /// 获取文件流 + /// + /// + /// + /// + /// + public FileStreamResult GetFileStreamResult(string path, string fileName, bool isPathFolder = false) + { + fileName = GetFileName(fileName); + if (isPathFolder) path = path.CombinePath(fileName); + //文件转流 + var result = new FileStreamResult(new FileStream(path, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName }; + return result; + } + + /// + /// 获取文件流 + /// + /// + /// + /// + public FileStreamResult GetFileStreamResult(byte[] byteArray, string fileName) + { + fileName = GetFileName(fileName); + //文件转流 + var result = new FileStreamResult(new MemoryStream(byteArray), "application/octet-stream") { FileDownloadName = fileName }; + return result; + } + + /// + /// 获取文件名 + /// + /// + /// + public string GetFileName(string fileName) + { + if (!fileName.Contains(".")) + fileName = fileName + ".xlsx"; + fileName = HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));//文件名转utf8不然前端下载会乱码 + return fileName; + } + + /// + /// 获取本地模板路径 + /// + /// + public string GetTemplateFolder() + { + var folder = App.WebHostEnvironment.WebRootPath.CombinePath("Template"); + return folder; + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Index/Dto/IndexInput.cs b/SimpleAdmin.System/Services/Index/Dto/IndexInput.cs new file mode 100644 index 0000000..20551f7 --- /dev/null +++ b/SimpleAdmin.System/Services/Index/Dto/IndexInput.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 日程列表查询参数 +/// +public class ScheduleListInput +{ + /// + /// 日程日期 + /// + [Required(ErrorMessage = "ScheduleDate不能为空")] + public string ScheduleDate { get; set; } +} + +public class ScheduleAddInput : RelationUserSchedule +{ + /// + /// 日程日期 + /// + [Required(ErrorMessage = "scheduleDate不能为空")] + public override string ScheduleDate { get; set; } + + /// + /// 日程内容 + /// + [Required(ErrorMessage = "ScheduleContent不能为空")] + public override string ScheduleContent { get; set; } + + /// + /// 日程时间 + /// + [Required(ErrorMessage = "ScheduleTime 不能为空")] + public override string ScheduleTime { get; set; } +} diff --git a/SimpleAdmin.System/Services/Index/Dto/IndexOutput.cs b/SimpleAdmin.System/Services/Index/Dto/IndexOutput.cs new file mode 100644 index 0000000..3a162a3 --- /dev/null +++ b/SimpleAdmin.System/Services/Index/Dto/IndexOutput.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +public class ScheduleListOutput : RelationUserSchedule +{ + /// + /// ID + /// + public long Id { get; set; } +} diff --git a/SimpleAdmin.System/Services/Index/IIndexService.cs b/SimpleAdmin.System/Services/Index/IIndexService.cs new file mode 100644 index 0000000..bf861aa --- /dev/null +++ b/SimpleAdmin.System/Services/Index/IIndexService.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 首页服务 +/// +public interface IIndexService : ITransient +{ + /// + /// 添加日程 + /// + /// 日程参数 + /// + Task AddSchedule(ScheduleAddInput input); + + /// + /// 删除日程 + /// + /// id列表 + /// + Task DeleteSchedule(BaseIdListInput input); + + /// + /// 获取日程列表 + /// + /// 查询参数 + /// 日程列表 + Task> ScheduleList(ScheduleListInput input); +} diff --git a/SimpleAdmin.System/Services/Index/IndexService.cs b/SimpleAdmin.System/Services/Index/IndexService.cs new file mode 100644 index 0000000..1fd684c --- /dev/null +++ b/SimpleAdmin.System/Services/Index/IndexService.cs @@ -0,0 +1,60 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class IndexService : DbRepository, IIndexService +{ + private readonly IRelationService _relationService; + + public IndexService(IRelationService relationService) + { + _relationService = relationService; + } + + /// + public async Task> ScheduleList(ScheduleListInput input) + { + var relations = await GetListAsync( + it => it.Category == CateGoryConst.RELATION_SYS_USER_SCHEDULE_DATA && it.ObjectId == UserManager.UserId + && it.TargetId == input.ScheduleDate, + it => new SysRelation { ExtJson = it.ExtJson, Id = it.Id });//获取当前用户的日程列表 + var userSchedules = new List();//结果集 + relations.ForEach(it => + { + var extJson = it.ExtJson.ToJsonEntity();//转成实体 + var userSchedule = extJson.Adapt();//格式化 + userSchedule.Id = it.Id;//赋值ID + userSchedules.Add(userSchedule);//添加到结果集 + }); + return userSchedules; + } + + /// + public async Task AddSchedule(ScheduleAddInput input) + { + input.ScheduleUserId = UserManager.UserId; + input.ScheduleUserName = UserManager.Name; + //添加日程 + await _relationService.SaveRelation(CateGoryConst.RELATION_SYS_USER_SCHEDULE_DATA, UserManager.UserId, input.ScheduleDate, input.ToJson(), + false, false); + } + + /// + public async Task DeleteSchedule(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + await DeleteAsync(it => ids.Contains(it.Id) && it.ObjectId == UserManager.UserId); + } +} diff --git a/SimpleAdmin.System/Services/Limit/Button/ButtonService.cs b/SimpleAdmin.System/Services/Limit/Button/ButtonService.cs new file mode 100644 index 0000000..d98179d --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Button/ButtonService.cs @@ -0,0 +1,190 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class ButtonService : DbRepository, IButtonService +{ + private readonly ILogger _logger; + private readonly IResourceService _resourceService; + private readonly IRelationService _relationService; + + public ButtonService(ILogger logger, IResourceService resourceService, IRelationService relationService) + { + _logger = logger; + _resourceService = resourceService; + _relationService = relationService; + } + + /// + public async Task> Page(ButtonPageInput input) + { + var query = Context.Queryable().Where(it => it.ParentId == input.ParentId && it.Category == CateGoryConst.RESOURCE_BUTTON) + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Title.Contains(input.SearchKey) || it.Path.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}").OrderBy(it => it.SortCode);//排序 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task Add(ButtonAddInput input) + { + await CheckInput(input);//检查参数 + var sysResource = input.Adapt();//实体转换 + if (await InsertAsync(sysResource))//插入数据 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_BUTTON);//刷新缓存 + } + + /// + public async Task> AddBatch(ButtonAddInput input) + { + var sysResources = new List();//按钮列表 + var codeList = new List { "Add", "Edit", "Delete", "BatchDelete", "Import", "Export", "BatchEdit" };//code后缀 + var titleList = new List { "新增", "编辑", "删除", "批量删除", "导入", "导出", "批量编辑" };//title前缀 + var idList = new List();//Id列表 + for (var i = 0; i < codeList.Count; i++) + { + var id = CommonUtils.GetSingleId(); + sysResources.Add(new SysResource + { + Id = id, + Title = titleList[i] + input.Title,//标题等于前缀输入的值 + Code = input.Code + codeList[i],//code等于输入的值加后缀 + ParentId = input.ParentId, + SortCode = i + 1 + }); + idList.Add(id); + } + //遍历列表 + foreach (var sysResource in sysResources) + { + await CheckInput(sysResource);//检查按钮参数 + } + //添加到数据库 + if (await InsertRangeAsync(sysResources))//插入数据 + { + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_BUTTON);//刷新缓存 + return sysResources.Select(it => it.Id).ToList(); + } + return new List(); + } + + /// + public async Task Edit(ButtonEditInput input) + { + await CheckInput(input);//检查参数 + var sysResource = input.Adapt();//实体转换 + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await UpdateAsync(sysResource);//更新按钮 + }); + if (result.IsSuccess)//如果成功了 + { + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_BUTTON);//资源表按钮刷新缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + //获取所有按钮集合 + var buttonList = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_BUTTON); + + #region 处理关系表角色资源信息 + + //获取所有菜单集合 + var menuList = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MENU); + //获取按钮的父菜单id集合 + var parentIds = buttonList.Where(it => ids.Contains(it.Id)).Select(it => it.ParentId.Value.ToString()).ToList(); + //获取关系表分类为SYS_ROLE_HAS_RESOURCE数据 + var roleResources = await _relationService.GetRelationByCategory(CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE); + //获取相关关系表数据 + var relationList = roleResources.Where(it => parentIds.Contains(it.TargetId))//目标ID是父ID中 + .Where(it => it.ExtJson != null).ToList();//扩展信息不为空 + //遍历关系表 + relationList.ForEach(it => + { + var relationRoleResuorce = it.ExtJson.ToJsonEntity();//拓展信息转实体 + var buttonInfo = relationRoleResuorce.ButtonInfo;//获取按钮信息 + if (buttonInfo.Count > 0) + { + // 使用 LINQ 查询找出交集的补集(即不同元素) + var diffArr = buttonInfo.Except(ids).Union(ids.Except(buttonInfo)).ToList(); + relationRoleResuorce.ButtonInfo = diffArr;//重新赋值按钮信息 + it.ExtJson = relationRoleResuorce.ToJson();//重新赋值拓展信息 + } + }); + + #endregion 处理关系表角色资源信息 + + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await DeleteByIdsAsync(ids.Cast().ToArray());//删除按钮 + if (relationList.Count > 0) + { + await Context.Updateable(relationList).UpdateColumns(it => it.ExtJson).ExecuteCommandAsync();//修改拓展信息 + } + }); + if (result.IsSuccess)//如果成功了 + { + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_BUTTON);//资源表按钮刷新缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE);//关系表刷新角色资源缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + + /// + public async Task Detail(BaseIdInput input) + { + var sysResources = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_BUTTON); + var resource = sysResources.Where(it => it.Id == input.Id).FirstOrDefault(); + return resource; + } + + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(SysResource sysResource) + { + //获取所有按钮和菜单 + var buttonList = await _resourceService.GetListAsync(new List { CateGoryConst.RESOURCE_BUTTON, CateGoryConst.RESOURCE_MENU }); + //判断code是否重复 + if (buttonList.Any(it => it.Code == sysResource.Code && it.Id != sysResource.Id)) + throw Oops.Bah($"存在重复的按钮编码:{sysResource.Code}"); + //判断菜单是否存在 + if (!buttonList.Any(it => it.Id == sysResource.ParentId)) + throw Oops.Bah($"不存在的父级菜单:{sysResource.ParentId}"); + sysResource.Category = CateGoryConst.RESOURCE_BUTTON;//设置分类为按钮 + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Limit/Button/Dto/ButtonInput.cs b/SimpleAdmin.System/Services/Limit/Button/Dto/ButtonInput.cs new file mode 100644 index 0000000..1d5b734 --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Button/Dto/ButtonInput.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +public class ButtonPageInput : BasePageInput +{ + /// + /// 父ID + /// + [Required(ErrorMessage = "ParentId不能为空")] + public long? ParentId { get; set; } +} + +/// +/// 添加按钮参数 +/// +public class ButtonAddInput : SysResource +{ + /// + /// 父ID + /// + [Required(ErrorMessage = "ParentId不能为空")] + public override long? ParentId { get; set; } + + /// + /// 标题 + /// + [Required(ErrorMessage = "Title不能为空")] + public override string Title { get; set; } + + /// + /// 编码 + /// + [Required(ErrorMessage = "Code不能为空")] + public override string Code { get; set; } +} + +public class ButtonEditInput : ButtonAddInput +{ + /// + /// ID + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} diff --git a/SimpleAdmin.System/Services/Limit/Button/IButtonService.cs b/SimpleAdmin.System/Services/Limit/Button/IButtonService.cs new file mode 100644 index 0000000..a1b03fe --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Button/IButtonService.cs @@ -0,0 +1,59 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 权限按钮服务 +/// +public interface IButtonService : ITransient +{ + /// + /// 添加按钮 + /// + /// 添加参数 + /// + Task Add(ButtonAddInput input); + + /// + /// 批量添加 + /// + /// + /// + Task> AddBatch(ButtonAddInput input); + + /// + /// 删除按钮 + /// + /// 删除参数 + /// + Task Delete(BaseIdListInput input); + + /// + /// 编辑按钮 + /// + /// 编辑参数 + /// + Task Edit(ButtonEditInput input); + + /// + /// 按钮分页查询 + /// + /// 查询条件 + /// 按钮分页列表 + Task> Page(ButtonPageInput input); + + /// + /// 按钮详情 + /// + /// + /// + Task Detail(BaseIdInput input); +} diff --git a/SimpleAdmin.System/Services/Limit/Menu/Dto/MenuInput.cs b/SimpleAdmin.System/Services/Limit/Menu/Dto/MenuInput.cs new file mode 100644 index 0000000..29b774c --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Menu/Dto/MenuInput.cs @@ -0,0 +1,127 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 菜单树查询参数 +/// +public class MenuTreeInput +{ + /// + /// 模块 + /// + public long? Module { get; set; } + + /// + /// 关键字 + /// + public string SearchKey { get; set; } +} + +/// +/// 添加菜单参数 +/// +public class MenuAddInput : SysResource, IValidatableObject +{ + /// + /// 父ID + /// + [Required(ErrorMessage = "ParentId不能为空")] + public override long? ParentId { get; set; } + + /// + /// 标题 + /// + [Required(ErrorMessage = "Title不能为空")] + public override string Title { get; set; } + + /// + /// 菜单类型 + /// + public override string MenuType { get; set; } = SysResourceConst.MENU; + + /// + /// 模块 + /// + [Required(ErrorMessage = "Module不能为空")] + public override long? Module { get; set; } + + /// + /// 路径 + /// + [Required(ErrorMessage = "Path不能为空")] + public override string Path { get; set; } + + /// + /// 图标 + /// + [Required(ErrorMessage = "Icon不能为空")] + public override string Icon { get; set; } + + /// + /// 特殊验证 + /// + /// + /// + /// + public IEnumerable Validate(ValidationContext validationContext) + { + //如果菜单类型是菜单 + if (MenuType is SysResourceConst.MENU or SysResourceConst.SUBSET or SysResourceConst.LINK) + { + if (string.IsNullOrEmpty(Name)) + yield return new ValidationResult("Name不能为空", new[] { nameof(Name) }); + if (string.IsNullOrEmpty(Component)) + yield return new ValidationResult("Component不能为空", new[] { nameof(Name) }); + if (MenuType is SysResourceConst.SUBSET)//如果是子集 + { + if (string.IsNullOrEmpty(ActiveMenu)) + yield return new ValidationResult("ActiveMenu不能为空", new[] { nameof(Name) }); + IsHome = false; + IsHide = true; + IsFull = false; + IsAffix = false; + IsKeepAlive = true; + } + } + else + { + Name = null;//设置name为空 + Component = null;//设置组件为空 + } + //设置分类为菜单 + Category = CateGoryConst.RESOURCE_MENU; + } +} + +/// +/// 编辑菜单输入参数 +/// +public class MenuEditInput : MenuAddInput +{ + /// + /// ID + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} + +/// +/// 改变模块输入参数 +/// +public class MenuChangeModuleInput : BaseIdInput +{ + /// + /// 模块ID + /// + [Required(ErrorMessage = "Module不能为空")] + public long? Module { get; set; } +} diff --git a/SimpleAdmin.System/Services/Limit/Menu/IMenuService.cs b/SimpleAdmin.System/Services/Limit/Menu/IMenuService.cs new file mode 100644 index 0000000..b81e067 --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Menu/IMenuService.cs @@ -0,0 +1,75 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 菜单服务 +/// +public interface IMenuService : ITransient +{ + /// + /// 添加菜单 + /// + /// 添加参数 + /// + Task Add(MenuAddInput input); + + /// + /// 详情 + /// + /// id + /// 详细信息 + Task Detail(BaseIdInput input); + + /// + /// 构建菜单树形结构 + /// + /// 菜单列表 + /// 父ID + /// 菜单形结构 + List ConstructMenuTrees(List resourceList, long? parentId = 0); + + /// + /// 获取菜单树 + /// + /// 菜单树查询参数 + /// 是否显示禁用的 + /// 菜单树列表 + Task> Tree(MenuTreeInput input, bool showDisabled = true); + + /// + /// 编辑菜单 + /// + /// 菜单编辑参数 + /// + Task Edit(MenuEditInput input); + + /// + /// 删除菜单 + /// + /// 删除菜单参数 + /// + Task Delete(BaseIdListInput input); + + /// + /// 改变菜单模块 + /// + /// 改变菜单模块参数 + /// + Task ChangeModule(MenuChangeModuleInput input); + + /// + /// 快捷方式菜单树 + /// + /// 资源列表 + /// + Task> ShortcutTree(List sysResources = null); +} diff --git a/SimpleAdmin.System/Services/Limit/Menu/MenuService.cs b/SimpleAdmin.System/Services/Limit/Menu/MenuService.cs new file mode 100644 index 0000000..fa69ca7 --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Menu/MenuService.cs @@ -0,0 +1,264 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class MenuService : DbRepository, IMenuService +{ + private readonly ILogger _logger; + private readonly IResourceService _resourceService; + private readonly IRelationService _relationService; + + public MenuService(ILogger logger, IResourceService resourceService, IRelationService relationService) + { + _logger = logger; + _resourceService = resourceService; + _relationService = relationService; + } + + /// + public List ConstructMenuTrees(List resourceList, long? parentId = 0) + { + //找下级资源ID列表 + var resources = resourceList.Where(it => it.ParentId == parentId).OrderBy(it => it.SortCode).ToList(); + if (resources.Count > 0)//如果数量大于0 + { + var data = new List(); + foreach (var item in resources)//遍历资源 + { + item.Children = ConstructMenuTrees(resourceList, item.Id);//添加子节点 + data.Add(item);//添加到列表 + } + return data;//返回结果 + } + return new List(); + } + + /// + public async Task> Tree(MenuTreeInput input, bool showDisabled = true) + { + //获取所有菜单 + var sysResources = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MENU); + sysResources = sysResources.WhereIF(input.Module != null, it => it.Module.Value == input.Module.Value)//根据模块查找 + .WhereIF(!showDisabled, it => it.Status == CommonStatusConst.ENABLE)//是否显示禁用的 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Title == input.SearchKey)//根据关键字查找 + .ToList(); + //构建菜单树 + var tree = ConstructMenuTrees(sysResources); + return tree; + } + + /// + public async Task> ShortcutTree(List sysResources = null) + { + if (sysResources == null) + //获取所有菜单 + sysResources = (await _resourceService.GetAllModuleAndMenuAndSpaList()) + .Where(it => it.Status == CommonStatusConst.ENABLE).ToList(); + // //获取所有单页 + // var sysSpas = (await _resourceService.GetConfigsByCategory(CateGoryConst.RESOURCE_SPA)) + // .Where(it => it.Status == CommonStatusConst.ENABLE).ToList(); + sysResources.ForEach(it => + { + if (it.MenuType == SysResourceConst.CATALOG) + it.ParentId = it.Module.Value;//目录的父级ID设置为模块ID + }); + + //构建菜单树 + var tree = ConstructMenuTrees(sysResources, null); + //将单页的排前面根据排序码排序 + tree = tree.OrderByDescending(it => it.Category == CateGoryConst.RESOURCE_SPA).ThenBy(it => it.SortCode).ToList(); + return tree; + } + + /// + public async Task Add(MenuAddInput input) + { + await CheckInput(input);//检查参数 + var sysResource = input.Adapt();//实体转换 + + if (await InsertAsync(sysResource))//插入数据 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_MENU);//刷新菜单缓存 + } + + /// + public async Task Edit(MenuEditInput input) + { + var resource = await CheckInput(input, true);//检查参数 + var sysResource = input.Adapt();//实体转换 + var updatePath = resource.Path != input.Path;//是否更新路径 + var permissions = new List(); + if (updatePath) + { + //获取所有角色和用户的权限关系 + var rolePermissions = await _relationService.GetRelationByCategory(CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION); + var userPermissions = await _relationService.GetRelationByCategory(CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION); + //找到所有匹配的权限 + rolePermissions = rolePermissions.Where(it => it.TargetId.Contains(resource.Path)).ToList(); + userPermissions = userPermissions.Where(it => it.TargetId.Contains(resource.Path)).ToList(); + //更新路径 + rolePermissions.ForEach(it => it.TargetId = it.TargetId.Replace(resource.Path, input.Path)); + userPermissions.ForEach(it => it.TargetId = it.TargetId.Replace(resource.Path, input.Path)); + //添加到权限列表 + permissions.AddRange(rolePermissions); + permissions.AddRange(userPermissions); + } + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await UpdateAsync(sysResource);//更新数据 + if (permissions.Count > 0)//如果权限列表大于0就更新 + { + await Context.Updateable(permissions) + .ExecuteCommandAsync();//更新关系表 + } + }); + if (result.IsSuccess)//如果成功了 + { + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_MENU);//刷新菜单缓存 + //刷新关系表缓存 + if (updatePath) + { + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION); + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION); + } + } + } + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + //获取所有菜单和按钮 + var resourceList = await _resourceService.GetListAsync(new List { CateGoryConst.RESOURCE_MENU, CateGoryConst.RESOURCE_BUTTON }); + //找到要删除的菜单 + var sysResources = resourceList.Where(it => ids.Contains(it.Id)).ToList(); + //查找内置菜单 + var system = sysResources.Where(it => it.Code == SysResourceConst.SYSTEM).FirstOrDefault(); + if (system != null) + throw Oops.Bah($"不可删除系统菜单:{system.Title}"); + //需要删除的资源ID列表 + var resourceIds = new List(); + //遍历菜单列表 + sysResources.ForEach(it => + { + //获取菜单所有子节点 + var child = _resourceService.GetChildListById(resourceList, it.Id, false); + //将子节点ID添加到删除资源ID列表 + resourceIds.AddRange(child.Select(it => it.Id).ToList()); + resourceIds.Add(it.Id);//添加到删除资源ID列表 + }); + ids.AddRange(resourceIds);//添加到删除ID列表 + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await DeleteByIdsAsync(ids.Cast().ToArray());//删除菜单和按钮 + await Context.Deleteable()//关系表删除对应SYS_ROLE_HAS_RESOURCE + .Where(it => it.Category == CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE && resourceIds.Contains(SqlFunc.ToInt64(it.TargetId))) + .ExecuteCommandAsync(); + }); + if (result.IsSuccess)//如果成功了 + { + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_MENU);//资源表菜单刷新缓存 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_BUTTON);//资源表按钮刷新缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE);//关系表刷新缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + } + + /// + public async Task Detail(BaseIdInput input) + { + var sysResources = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MENU); + var resource = sysResources.Where(it => it.Id == input.Id).FirstOrDefault(); + return resource; + } + + /// + public async Task ChangeModule(MenuChangeModuleInput input) + { + var sysResource = await Detail(new BaseIdInput { Id = input.Id }); + if (sysResource != null) + { + if (sysResource.Module == input.Module)//如果模块ID没变直接返回 + return; + if (sysResource.ParentId != 0) + throw Oops.Bah("非顶级菜单不可修改所属模块"); + //获取所有菜单和模块 + var resourceList = await _resourceService.GetListAsync(new List { CateGoryConst.RESOURCE_MENU, CateGoryConst.RESOURCE_MODULE }); + if (!resourceList.Any(it => it.Category == CateGoryConst.RESOURCE_MODULE && it.Id == input.Module.Value)) + throw Oops.Bah("不存在的模块"); + //获取所有菜单 + var menuList = resourceList.Where(it => it.Category == CateGoryConst.RESOURCE_MENU).ToList(); + //获取需要改变模块菜单的所有子菜单 + var childList = _resourceService.GetChildListById(menuList, input.Id); + childList.ForEach(it => it.Module = input.Module); + //更新数据 + await UpdateRangeAsync(childList); + //刷新菜单缓存 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_MENU); + } + } + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + /// + private async Task CheckInput(SysResource sysResource, bool update = false) + { + //获取所有菜单列表 + var menList = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MENU); + //判断是否有同级且同名的菜单 + if (menList.Any(it => it.ParentId == sysResource.ParentId && it.Title == sysResource.Title && it.Id != sysResource.Id)) + throw Oops.Bah($"存在重复的菜单名称:{sysResource.Title}"); + if (sysResource.ParentId != 0) + { + //获取父级,判断父级ID正不正确 + var parent = menList.Where(it => it.Id == sysResource.ParentId).FirstOrDefault(); + if (parent != null) + { + if (parent.Module != sysResource.Module)//如果父级的模块和当前模块不一样 + throw Oops.Bah("模块与上级菜单不一致"); + if (parent.Id == sysResource.Id) + throw Oops.Bah("上级菜单不能选择自己"); + } + else + { + throw Oops.Bah($"上级菜单不存在:{sysResource.ParentId}"); + } + } + //如果ID大于0表示编辑 + if (sysResource.Id > 0 && update) + { + var resource = menList.Where(it => it.Id == sysResource.Id).FirstOrDefault(); + if (resource == null) + throw Oops.Bah($"菜单不存在:{sysResource.Id}"); + return resource; + } + return null; + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Limit/Module/Dto/ModuleInput.cs b/SimpleAdmin.System/Services/Limit/Module/Dto/ModuleInput.cs new file mode 100644 index 0000000..6154fe7 --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Module/Dto/ModuleInput.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 模块分页输入 +/// +public class ModulePageInput : BasePageInput +{ +} + +/// +/// 添加模块输入 +/// +public class ModuleAddInput : SysResource +{ +} + +/// +/// 编辑模块输入 +/// +public class ModuleEditInput : ModuleAddInput +{ + /// + /// ID + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} diff --git a/SimpleAdmin.System/Services/Limit/Module/IModuleService.cs b/SimpleAdmin.System/Services/Limit/Module/IModuleService.cs new file mode 100644 index 0000000..2407f0a --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Module/IModuleService.cs @@ -0,0 +1,58 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 模块管理服务 +/// +public interface IModuleService : ITransient +{ + /// + /// 添加模块 + /// + /// 添加参数 + /// + Task Add(ModuleAddInput input); + + /// + /// 删除模块 + /// + /// 删除参数 + /// + Task Delete(BaseIdListInput input); + + /// + /// 编辑模块 + /// + /// 编辑参数 + /// + Task Edit(ModuleEditInput input); + + /// + /// 分页查询 + /// + /// 分页参数 + /// + Task> Page(ModulePageInput input); + + /// + /// 模块详情 + /// + /// + /// + Task Detail(BaseIdInput input); + + /// + /// 模块列表 + /// + /// + Task> List(); +} diff --git a/SimpleAdmin.System/Services/Limit/Module/ModuleService.cs b/SimpleAdmin.System/Services/Limit/Module/ModuleService.cs new file mode 100644 index 0000000..d3ac21a --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Module/ModuleService.cs @@ -0,0 +1,161 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class ModuleService : DbRepository, IModuleService +{ + private readonly ILogger _logger; + private readonly IResourceService _resourceService; + private readonly IRelationService _relationService; + private readonly IEventPublisher _eventPublisher; + private readonly ISysUserService _sysUserService; + + public ModuleService(ILogger logger, IResourceService resourceService, IRelationService relationService, + IEventPublisher eventPublisher, ISysUserService sysUserService) + { + _logger = logger; + _resourceService = resourceService; + _relationService = relationService; + _eventPublisher = eventPublisher; + _sysUserService = sysUserService; + } + + /// + public async Task> Page(ModulePageInput input) + { + var query = Context.Queryable().Where(it => it.Category == CateGoryConst.RESOURCE_MODULE)//模块 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Title.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}").OrderBy(it => it.SortCode);//排序 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task Add(ModuleAddInput input) + { + await CheckInput(input);//检查参数 + var sysResource = input.Adapt();//实体转换 + if (await InsertAsync(sysResource))//插入数据 + { + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_MODULE);//刷新缓存 + _sysUserService.DeleteUserFromRedis(UserManager.UserId); + } + } + + /// + public async Task Edit(ModuleEditInput input) + { + await CheckInput(input);//检查参数 + var sysResource = input.Adapt();//实体转换 + if (await UpdateAsync(sysResource))//更新数据 + { + if (sysResource.Status == CommonStatusConst.DISABLED)//如果禁用 + await _eventPublisher.PublishAsync(EventSubscriberConst.CLEAR_MODULE_TOKEN, sysResource.Id);//清除角色下用户缓存 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_MODULE);//刷新缓存 + } + } + + /// + public async Task Detail(BaseIdInput input) + { + var sysResources = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MODULE); + var resource = sysResources.Where(it => it.Id == input.Id).FirstOrDefault(); + return resource; + } + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + //获取所有 + var resourceList = await _resourceService.GetListAsync(); + //找到要删除的模块 + var sysResources = resourceList.Where(it => ids.Contains(it.Id)).ToList(); + //查找内置模块 + var system = sysResources.Where(it => it.Code == SysResourceConst.SYSTEM).FirstOrDefault(); + if (system != null) + throw Oops.Bah($"不可删除系统内置模块:{system.Title}"); + if (sysResources.Any(it => it.Status == CommonStatusConst.ENABLE))//如果有启用的模块 + throw Oops.Bah($"请先禁用模块再删除"); + //获取模块下的所有菜单Id列表 + var menuIds = resourceList.Where(it => ids.Contains(it.Module.ToLong()) && it.ParentId.ToLong() == SimpleAdminConst.ZERO) + .Select(it => it.Id).ToList(); + //需要删除的资源ID列表 + var resourceIds = new List(); + //遍历列表 + menuIds.ForEach(it => + { + //获取菜单所有子节点 + var child = _resourceService.GetChildListById(resourceList, it, false); + //将子节点ID添加到删除ID列表 + resourceIds.AddRange(child.Select(it => it.Id).ToList()); + resourceIds.Add(it);//添加到删除ID列表 + }); + ids.AddRange(resourceIds); + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await DeleteByIdsAsync(ids.Cast().ToArray());//删除菜单和按钮 + await Context.Deleteable()//关系表删除对应SYS_ROLE_HAS_RESOURCE + .Where(it => it.Category == CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE && resourceIds.Contains(SqlFunc.ToInt64(it.TargetId))) + .ExecuteCommandAsync(); + }); + if (result.IsSuccess)//如果成功了 + { + await _resourceService.RefreshCache();//资源表刷新缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE);//关系表刷新缓存 + _sysUserService.DeleteUserFromRedis(UserManager.UserId); + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + } + + /// + public async Task> List() + { + var sysResources = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MODULE); + return sysResources; + } + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(SysResource sysResource) + { + var sysResourceList = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MODULE); + //判断是否从存在重复模块 + var hasSameName = sysResourceList.Any(it => it.Title == sysResource.Title && it.Id != sysResource.Id); + if (hasSameName) + { + throw Oops.Bah($"存在重复的模块:{sysResource.Title}"); + } + if (sysResource.Status == CommonStatusConst.DISABLED)//如果禁用 + await _eventPublisher.PublishAsync(EventSubscriberConst.CLEAR_MODULE_TOKEN, sysResource.Id);//清除角色下用户缓存 + //设置为模块 + sysResource.Category = CateGoryConst.RESOURCE_MODULE; + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Limit/Role/Dto/RoleInput.cs b/SimpleAdmin.System/Services/Limit/Role/Dto/RoleInput.cs new file mode 100644 index 0000000..fb539aa --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Role/Dto/RoleInput.cs @@ -0,0 +1,130 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 角色查询参数 +/// +public class RolePageInput : PositionPageInput +{ +} + +/// +/// 角色添加参数 +/// +public class RoleAddInput : SysRole +{ + /// + /// 名称 + /// + [Required(ErrorMessage = "Name不能为空")] + public override string Name { get; set; } +} + +/// +/// 角色编辑参数 +/// +public class RoleEditInput : RoleAddInput +{ + /// + /// Id + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} + +/// +/// 角色授权资源参数 +/// +public class GrantResourceInput : RoleOwnResourceOutput +{ + /// + /// 角色Id + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } + + /// + /// 授权资源信息 + /// + [Required(ErrorMessage = "GrantInfoList不能为空")] + public override List GrantInfoList { get; set; } + + /// + /// 是否代码生成 + /// + public bool IsCodeGen { get; set; } +} + +/// +/// 角色授权资源参数 +/// +public class GrantPermissionInput : RoleOwnPermissionOutput +{ + /// + /// 角色Id + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } + + /// + /// 授权权限信息 + /// + [Required(ErrorMessage = "GrantInfoList不能为空")] + public override List GrantInfoList { get; set; } +} + +/// +/// 角色授权用户参数 +/// +public class GrantUserInput +{ + /// + /// Id + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public long Id { get; set; } + + /// + /// 授权权限信息 + /// + [Required(ErrorMessage = "GrantInfoList不能为空")] + public List GrantInfoList { get; set; } +} + +/// +/// 角色选择器参数 +/// +public class RoleSelectorInput : BasePageInput +{ + /// + /// 组织ID + /// + public long OrgId { get; set; } + + /// + /// 机构ID列表 + /// + public List OrgIds { get; set; } + + /// + /// 角色名称 + /// + public string Name { get; set; } +} + +public class RoleTreeInput +{ + /// + /// 机构ID列表 + /// + public List OrgIds { get; set; } +} diff --git a/SimpleAdmin.System/Services/Limit/Role/Dto/RoleOutput.cs b/SimpleAdmin.System/Services/Limit/Role/Dto/RoleOutput.cs new file mode 100644 index 0000000..3db084e --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Role/Dto/RoleOutput.cs @@ -0,0 +1,69 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 角色拥有的资源输出 +/// +public class RoleOwnResourceOutput +{ + /// + /// Id + /// + public virtual long Id { get; set; } + + /// + /// 已授权资源信息 + /// + public virtual List GrantInfoList { get; set; } +} + +/// +/// 角色拥有权限输出 +/// +public class RoleOwnPermissionOutput +{ + /// + /// 角色Id + /// + public virtual long Id { get; set; } + + /// + /// 已授权资源信息 + /// + public virtual List GrantInfoList { get; set; } +} + +/// +/// 角色树输出参数 +/// +public class RoleTreeOutput +{ + /// + /// 职位Id + /// + public long Id { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 是否是职位 + /// + public bool IsRole { get; set; } + + /// + /// 子项 + /// + public List Children { get; set; } = new List(); +} diff --git a/SimpleAdmin.System/Services/Limit/Role/ISysRoleService.cs b/SimpleAdmin.System/Services/Limit/Role/ISysRoleService.cs new file mode 100644 index 0000000..c784bba --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Role/ISysRoleService.cs @@ -0,0 +1,159 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 角色服务 +/// +public interface ISysRoleService : ITransient +{ + #region 查询 + + /// + /// 获取所有角色 + /// + /// + Task> GetListAsync(); + + /// + /// 根据用户ID获取用户角色集合 + /// + /// 用户ID + /// + Task> GetRoleListByUserId(long userId); + + + /// + /// 获取角色拥有权限 + /// + /// 角色ID + /// + Task OwnPermission(BaseIdInput input); + + /// + /// 角色拥有资源 + /// + /// 角色id + /// 资源类型 + /// 角色拥有资源信息 + Task OwnResource(BaseIdInput input, string category); + + /// + /// 获取角色下的用户 + /// + /// 角色ID + /// + Task> OwnUser(BaseIdInput input); + + /// + /// 分页查询角色 + /// + /// 查询参数 + /// + Task> Page(RolePageInput input); + + /// + /// 获取角色授权权限选择器 + /// + /// 角色ID + /// + Task> RolePermissionTreeSelector(BaseIdInput input); + + /// + /// 角色选择器 + /// + /// + /// + Task> RoleSelector(RoleSelectorInput input); + + /// + /// 根据id集合获取角色集合 + /// + /// + /// + Task> GetRoleListByIdList(IdListInput input); + + /// + /// 获取角色树 + /// + /// 角色树 + /// + Task> Tree(RoleTreeInput input); + + /// + /// 角色详情 + /// + /// 角色Id + /// + Task Detail(BaseIdInput input); + + #endregion + + #region 新增 + + /// + /// 添加角色 + /// + /// 添加参数 + /// + Task Add(RoleAddInput input); + + #endregion + + #region 编辑 + + /// + /// 编辑角色 + /// + /// 编辑参数 + /// + Task Edit(RoleEditInput input); + + /// + /// 给角色授权权限 + /// + /// 授权信息 + /// + Task GrantPermission(GrantPermissionInput input); + + /// + /// 给角色授权 + /// + /// 授权参数 + /// + Task GrantResource(GrantResourceInput input); + + /// + /// 给角色授权用户 + /// + /// 授权信息 + /// + Task GrantUser(GrantUserInput input); + + #endregion + + #region 删除 + + /// + /// 刷新缓存 + /// + /// + Task RefreshCache(); + + /// + /// 删除角色 + /// + /// 删除参数 + /// + Task Delete(BaseIdListInput input); + + #endregion +} diff --git a/SimpleAdmin.System/Services/Limit/Role/SysRoleService.cs b/SimpleAdmin.System/Services/Limit/Role/SysRoleService.cs new file mode 100644 index 0000000..b0bb62b --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Role/SysRoleService.cs @@ -0,0 +1,589 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +//[Injection(Proxy = typeof(GlobalDispatchProxy))] +public class SysRoleService : DbRepository, ISysRoleService +{ + private readonly ILogger _logger; + private readonly ISimpleCacheService _simpleCacheService; + private readonly IRelationService _relationService; + private readonly ISysOrgService _sysOrgService; + private readonly IResourceService _resourceService; + private readonly IEventPublisher _eventPublisher; + + public SysRoleService(ILogger logger, ISimpleCacheService simpleCacheService, IRelationService relationService, + ISysOrgService sysOrgService, IResourceService resourceService, IEventPublisher eventPublisher) + { + _logger = logger; + _simpleCacheService = simpleCacheService; + _relationService = relationService; + _sysOrgService = sysOrgService; + _resourceService = resourceService; + _eventPublisher = eventPublisher; + } + + #region 查询 + + /// + /// 获取所有 + /// + /// + public override async Task> GetListAsync() + { + //先从Redis拿 + var sysRoles = _simpleCacheService.Get>(SystemConst.CACHE_SYS_ROLE); + if (sysRoles == null) + { + //redis没有就去数据库拿 + sysRoles = await base.GetListAsync(); + if (sysRoles.Count > 0) + { + //插入Redis + _simpleCacheService.Set(SystemConst.CACHE_SYS_ROLE, sysRoles); + } + } + return sysRoles; + } + + /// + public async Task> GetRoleListByUserId(long userId) + { + var cods = new List();//角色代码集合 + var roleList = await _relationService.GetRelationListByObjectIdAndCategory(userId, CateGoryConst.RELATION_SYS_USER_HAS_ROLE);//根据用户ID获取角色ID + var roleIdList = roleList.Select(x => x.TargetId.ToLong()).ToList();//角色ID列表 + if (roleIdList.Count > 0) + { + cods = await GetListAsync(it => roleIdList.Contains(it.Id)); + } + return cods; + } + + /// + public async Task> Page(RolePageInput input) + { + var orgIds = await _sysOrgService.GetOrgChildIds(input.OrgId);//获取下级机构 + var query = Context.Queryable() + .WhereIF(input.OrgId > 0, it => orgIds.Contains(it.OrgId.Value))//根据组织 + .WhereIF(input.OrgIds != null, it => input.OrgIds.Contains(it.OrgId.Value))//数据权限 + .WhereIF(!string.IsNullOrEmpty(input.Status), it => it.Status == input.Status)//根据分类 + .WhereIF(!string.IsNullOrEmpty(input.Category), it => it.Category == input.Category)//根据分类 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Name.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}").OrderBy(it => it.SortCode);//排序 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task> Tree(RoleTreeInput input) + { + var result = new List();//返回结果 + var sysOrgList = await _sysOrgService.GetListAsync(false);//获取所有机构 + var sysRoles = await GetListAsync();//获取所有角色 + sysRoles = sysRoles.Where(it => it.Code != SysRoleConst.SUPER_ADMIN).ToList();//排除超管 + if (input.OrgIds != null)//根据数据范围查 + { + sysOrgList = sysOrgList.Where(it => input.OrgIds.Contains(it.Id)).ToList();//在指定组织列表查询 + sysRoles = sysRoles.Where(it => input.OrgIds.Contains(it.OrgId.GetValueOrDefault())).ToList();//在指定职位列表查询 + } + var topOrgList = sysOrgList.Where(it => it.ParentId == 0).ToList();//获取顶级机构 + var globalRole = sysRoles.Where(it => it.Category == CateGoryConst.ROLE_GLOBAL).ToList();//获取全局角色 + if (globalRole.Count > 0) + { + result.Add(new RoleTreeOutput() + { + Id = CommonUtils.GetSingleId(), + Name = "全局角色", + Children = globalRole.Select(it => new RoleTreeOutput + { + Id = it.Id, + Name = it.Name, + IsRole = true + }).ToList() + });//添加全局角色 + } + //遍历顶级机构 + foreach (var org in topOrgList) + { + var childIds = await _sysOrgService.GetOrgChildIds(org.Id, true, sysOrgList);//获取机构下的所有子级ID + var childRoles = sysRoles.Where(it => it.OrgId != null && childIds.Contains(it.OrgId.Value)).ToList();//获取机构下的所有角色 + if (childRoles.Count == 0) + continue; + var roleTreeOutput = new RoleTreeOutput + { + Id = org.Id, + Name = org.Name, + IsRole = false + };//实例化角色树 + childRoles.ForEach(it => + { + roleTreeOutput.Children.Add(new RoleTreeOutput() + { + Id = it.Id, + Name = it.Name, + IsRole = true + }); + }); + result.Add(roleTreeOutput); + } + return result; + } + + /// + public async Task OwnResource(BaseIdInput input, string category) + { + var roleOwnResource = new RoleOwnResourceOutput { Id = input.Id };//定义结果集 + var grantInfoList = new List();//已授权信息集合 + //获取关系列表 + var relations = await _relationService.GetRelationListByObjectIdAndCategory(input.Id, category); + //遍历关系表 + relations.ForEach(it => + { + //将扩展信息转为实体 + var relationRole = it.ExtJson.ToJsonEntity(); + grantInfoList.Add(relationRole);//添加到已授权信息 + }); + roleOwnResource.GrantInfoList = grantInfoList;//赋值已授权信息 + return roleOwnResource; + } + + /// + public async Task OwnPermission(BaseIdInput input) + { + var roleOwnPermission = new RoleOwnPermissionOutput { Id = input.Id };//定义结果集 + var grantInfoList = new List();//已授权信息集合 + //获取关系列表 + var relations = await _relationService.GetRelationListByObjectIdAndCategory(input.Id, CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION); + //遍历关系表 + relations.ForEach(it => + { + //将扩展信息转为实体 + var relationPermission = it.ExtJson.ToJsonEntity(); + grantInfoList.Add(relationPermission);//添加到已授权信息 + }); + roleOwnPermission.GrantInfoList = grantInfoList;//赋值已授权信息 + return roleOwnPermission; + } + + /// + public async Task> OwnUser(BaseIdInput input) + { + //获取关系列表 + var relations = await _relationService.GetRelationListByTargetIdAndCategory(input.Id.ToString(), CateGoryConst.RELATION_SYS_USER_HAS_ROLE); + var userIds = relations.Select(it => it.ObjectId).ToList(); + var userList = await Context.Queryable().Where(it => userIds.Contains(it.Id)).Select().ToListAsync(); + return userList; + } + + /// + public async Task> RoleSelector(RoleSelectorInput input) + { + var orgIds = await _sysOrgService.GetOrgChildIds(input.OrgId);//获取下级组织 + //如果机构ID列表不为空 + if (input.OrgIds != null) + { + orgIds = orgIds.Where(it => input.OrgIds.Contains(it)).ToList();//包含在机构ID列表中的组织ID + } + var result = await Context.Queryable() + .Where(it => it.Code != SysRoleConst.SUPER_ADMIN) + .WhereIF(input.OrgId == 0, it => it.Category == CateGoryConst.ROLE_GLOBAL)//不传机构ID就是全局角色 + .WhereIF(orgIds.Count > 0, it => orgIds.Contains(it.OrgId.Value))//组织ID + .WhereIF(!string.IsNullOrEmpty(input.Name), it => it.Name.Contains(input.Name))//根据关键字查询 + .Select() + .ToPagedListAsync(input.PageNum, input.PageSize); + return result; + } + + /// + public async Task> RolePermissionTreeSelector(BaseIdInput input) + { + var permissionTreeSelectors = new List();//授权树结果集 + //获取单页信息 + var spa = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_SPA); + var spaIds = spa.Select(it => it.Id).ToList(); + if (spaIds.Any()) + { + //获取权限授权树 + var permissions = _resourceService.PermissionTreeSelector(spa.Select(it => it.Path).ToList()); + if (permissions.Count > 0) + permissionTreeSelectors.AddRange(permissions.Select(it => it.PermissionName).ToList());//返回授权树权限名称列表 + } + //获取角色资源关系 + var relationsRes = await _relationService.GetRelationByCategory(CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE); + var menuIds = relationsRes.Where(it => it.ObjectId == input.Id).Select(it => it.TargetId.ToLong()).ToList(); + if (menuIds.Any()) + { + //获取菜单信息 + var menus = await _resourceService.GetResourcesByIds(menuIds, CateGoryConst.RESOURCE_MENU); + //获取权限授权树 + var permissions = _resourceService.PermissionTreeSelector(menus.Select(it => it.Path).ToList()); + if (permissions.Count > 0) + permissionTreeSelectors.AddRange(permissions.Select(it => it.PermissionName).ToList());//返回授权树权限名称列表 + } + return permissionTreeSelectors; + } + + + /// + public async Task> GetRoleListByIdList(IdListInput input) + { + var roles = await GetListAsync(); + var roleList = roles.Where(it => input.IdList.Contains(it.Id)).ToList();// 获取指定ID的岗位列表 + return roleList; + } + + /// + public async Task Detail(BaseIdInput input) + { + var roles = await GetListAsync(); + var role = roles.Where(it => it.Id == input.Id).FirstOrDefault(); + return role; + } + + #endregion + + #region 新增 + + /// + public async Task Add(RoleAddInput input) + { + await CheckInput(input);//检查参数 + var sysRole = input.Adapt();//实体转换 + if (await InsertAsync(sysRole))//插入数据 + await RefreshCache();//刷新缓存 + } + + #endregion + + #region 编辑 + + /// + public async Task Edit(RoleEditInput input) + { + //判断是否超管 + if (input.Code == SysRoleConst.SUPER_ADMIN) + throw Oops.Bah("不可编辑超管角色"); + await CheckInput(input);//检查参数 + var role = await GetFirstAsync(it => it.Id == input.Id);//获取角色 + if (role != null) + { + var permissions = new List(); + //如果改了默认数据权限 + if (role.DefaultDataScope.ScopeCategory != input.DefaultDataScope.ScopeCategory) + { + //获取角色授权列表 + var relations = await _relationService.GetRelationByCategory(CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION); + //找到当前角色的 + permissions = relations.Where(it => it.ObjectId == input.Id).ToList(); + permissions.ForEach(it => + { + var rolePermission = it.ExtJson.ToJsonEntity();//扩展信息转实体 + //如果表里的数据范围是默认数据范围才更新,已经自定义了的数据范围不更新 + if (rolePermission.ScopeCategory == role.DefaultDataScope.ScopeCategory + && Enumerable.SequenceEqual(rolePermission.ScopeDefineOrgIdList, role.DefaultDataScope.ScopeDefineOrgIdList)) + { + //重新赋值数据范围 + rolePermission.ScopeCategory = input.DefaultDataScope.ScopeCategory; + rolePermission.ScopeDefineOrgIdList = input.DefaultDataScope.ScopeDefineOrgIdList; + it.ExtJson = rolePermission.ToJson(); + } + }); + } + var sysRole = input.Adapt();//实体转换 + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await UpdateAsync(sysRole);//更新角色 + if (permissions.Any())//如果有授权权限就更新 + await Context.Updateable(permissions).ExecuteCommandAsync(); + }); + if (result.IsSuccess)//如果成功了 + { + await RefreshCache();//刷新缓存 + if (permissions.Any())//如果有授权 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION);//关系表刷新SYS_ROLE_HAS_PERMISSION缓存 + await _eventPublisher.PublishAsync(EventSubscriberConst.CLEAR_USER_CACHE, new List { input.Id });//清除角色下用户缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + } + + + /// + public async Task GrantResource(GrantResourceInput input) + { + var allMenus = await _resourceService.GetListByCategory(SysResourceConst.MENU);//获取所有菜单 + var spas = await _resourceService.GetListByCategory(SysResourceConst.SPA); + var menuIds = input.GrantInfoList.Select(it => it.MenuId).ToList();//菜单ID + var extJsons = input.GrantInfoList.Select(it => it.ToJson()).ToList();//拓展信息 + var relationRoles = new List();//要添加的角色资源和授权关系表 + var sysRole = (await GetListAsync()).Where(it => it.Id == input.Id).FirstOrDefault();//获取角色 + if (sysRole != null) + { + #region 角色模块处理 + + var menusList = allMenus.Where(it => menuIds.Contains(it.Id)).ToList();//获取菜单信息 + //获取我的模块信息Id列表 + var moduleIds = menusList.Select(it => it.Module.Value).Distinct().ToList(); + moduleIds.ForEach(it => + { + //将角色资源添加到列表 + relationRoles.Add(new SysRelation + { + ObjectId = sysRole.Id, + TargetId = it.ToString(), + Category = CateGoryConst.RELATION_SYS_ROLE_HAS_MODULE + }); + }); + + #endregion 角色模块处理 + + #region 角色资源处理 + + //遍历菜单列表 + for (var i = 0; i < menuIds.Count; i++) + { + //将角色资源添加到列表 + relationRoles.Add(new SysRelation + { + ObjectId = sysRole.Id, + TargetId = menuIds[i].ToString(), + Category = CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE, + ExtJson = extJsons?[i] + }); + } + + #endregion 角色资源处理 + + #region 角色权限处理. + + var relationRolePer = new List();//要添加的角色有哪些权限列表 + var defaultDataScope = sysRole.DefaultDataScope;//获取默认数据范围 + + //获取菜单信息 + var menus = allMenus.Where(it => menuIds.Contains(it.Id)).ToList(); + menus.AddRange(spas);//单页id添加到列表 + if (menus.Count > 0) + { + //获取权限授权树 + var permissions = _resourceService.PermissionTreeSelector(menus.Select(it => it.Path).ToList()); + permissions.ForEach(it => + { + //新建角色权限关系 + relationRolePer.Add(new SysRelation + { + ObjectId = sysRole.Id, + TargetId = it.ApiRoute, + Category = CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION, + ExtJson = new RelationRolePermission + { + ApiUrl = it.ApiRoute, + ScopeCategory = defaultDataScope.ScopeCategory, + ScopeDefineOrgIdList = defaultDataScope.ScopeDefineOrgIdList + }.ToJson() + }); + }); + } + relationRoles.AddRange(relationRolePer);//合并列表 + + #endregion 角色权限处理. + + #region 保存数据库 + + //事务 + var result = await Tenant.UseTranAsync(async () => + { + var relationRep = ChangeRepository>();//切换仓储 + //如果不是代码生成,就删除老的 + if (!input.IsCodeGen) + await relationRep.DeleteAsync(it => it.ObjectId == sysRole.Id && (it.Category == CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION + || it.Category == CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE + || it.Category == CateGoryConst.RELATION_SYS_ROLE_HAS_MODULE)); + await relationRep.InsertRangeAsync(relationRoles);//添加新的 + }); + if (result.IsSuccess)//如果成功了 + { + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE);//刷新关系缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION);//刷新关系缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_MODULE);//刷新关系缓存 + await _eventPublisher.PublishAsync(EventSubscriberConst.CLEAR_USER_CACHE, new List { input.Id });//发送事件清除角色下用户缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0003); + } + + #endregion 保存数据库 + } + } + + + /// + public async Task GrantPermission(GrantPermissionInput input) + { + var sysRole = (await GetListAsync()).Where(it => it.Id == input.Id).FirstOrDefault();//获取角色 + if (sysRole != null) + { + var apiUrls = input.GrantInfoList.Select(it => it.ApiUrl).ToList();//apiUrl列表 + var extJsons = input.GrantInfoList.Select(it => it.ToJson()).ToList();//拓展信息 + await _relationService.SaveRelationBatch(CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION, input.Id, apiUrls, extJsons, + true);//添加到数据库 + await _eventPublisher.PublishAsync(EventSubscriberConst.CLEAR_USER_CACHE, new List { input.Id });//清除角色下用户缓存 + } + } + + + /// + public async Task GrantUser(GrantUserInput input) + { + var sysRelations = new List();//关系列表 + //遍历用户ID + input.GrantInfoList.ForEach(it => + { + sysRelations.Add(new SysRelation + { + ObjectId = it, + TargetId = input.Id.ToString(), + Category = CateGoryConst.RELATION_SYS_USER_HAS_ROLE + }); + }); + + //事务 + var result = await Tenant.UseTranAsync(async () => + { + var relationRep = ChangeRepository>();//切换仓储 + var targetId = input.Id.ToString();//目标ID转string + await relationRep.DeleteAsync(it => it.TargetId == targetId && it.Category == CateGoryConst.RELATION_SYS_USER_HAS_ROLE);//删除老的 + await relationRep.InsertRangeAsync(sysRelations);//添加新的 + }); + if (result.IsSuccess)//如果成功了 + { + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_ROLE);//刷新关系表SYS_USER_HAS_ROLE缓存 + await _eventPublisher.PublishAsync(EventSubscriberConst.CLEAR_USER_CACHE, new List { input.Id });//清除角色下用户缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0003); + } + } + + #endregion + + #region 删除 + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + var sysRoles = await GetListAsync();//获取所有角色 + var hasSuperAdmin = sysRoles.Any(it => it.Code == SysRoleConst.SUPER_ADMIN && ids.Contains(it.Id));//判断是否有超级管理员 + if (hasSuperAdmin) throw Oops.Bah("不可删除系统内置超管角色"); + + //数据库是string所以这里转下 + var targetIds = ids.Select(it => it.ToString()).ToList(); + //定义删除的关系 + var delRelations = new List + { + CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE, + CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION, + CateGoryConst.RELATION_SYS_ROLE_HAS_MODULE + }; + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await DeleteByIdsAsync(ids.Cast().ToArray());//删除按钮 + var relationRep = ChangeRepository>();//切换仓储 + //删除关系表角色与资源关系,角色与权限关系 + await relationRep.DeleteAsync(it => ids.Contains(it.ObjectId) && delRelations.Contains(it.Category)); + //删除关系表角色与用户关系 + await relationRep.DeleteAsync(it => targetIds.Contains(it.TargetId) && it.Category == CateGoryConst.RELATION_SYS_USER_HAS_ROLE); + }); + if (result.IsSuccess)//如果成功了 + { + await RefreshCache();//刷新缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_ROLE);//关系表刷新SYS_USER_HAS_ROLE缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE);//关系表刷新Relation_SYS_ROLE_HAS_RESOURCE缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION);//关系表刷新Relation_SYS_ROLE_HAS_PERMISSION缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_ROLE_HAS_MODULE);//关系表刷新RELATION_SYS_ROLE_HAS_MODULE缓存 + await _eventPublisher.PublishAsync(EventSubscriberConst.CLEAR_USER_CACHE, ids);//清除角色下用户缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + } + + + /// + public async Task RefreshCache() + { + _simpleCacheService.Remove(SystemConst.CACHE_SYS_ROLE);//删除KEY + await GetListAsync();//重新缓存 + } + + #endregion + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(SysRole sysRole) + { + //判断分类 + if (sysRole.Category != CateGoryConst.ROLE_GLOBAL && sysRole.Category != CateGoryConst.ROLE_ORG) + throw Oops.Bah($"角色所属分类错误:{sysRole.Category}"); + //如果是机构角色orgId不能为空 + if (sysRole is { Category: CateGoryConst.ROLE_ORG, OrgId: null }) + throw Oops.Bah("orgId不能为空"); + if (sysRole.Category == CateGoryConst.ROLE_GLOBAL)//如果是全局 + sysRole.OrgId = null;//机构id设null + + var sysRoles = await GetListAsync();//获取所有 + var repeatName = sysRoles.Any(it => it.OrgId == sysRole.OrgId && it.Name == sysRole.Name && it.Id != sysRole.Id);//是否有重复角色名称 + if (repeatName)//如果有 + { + if (sysRole.OrgId == null) + throw Oops.Bah($"存在重复的全局角色:{sysRole.Name}"); + throw Oops.Bah($"同组织下存在重复的角色:{sysRole.Name}"); + } + //如果code没填 + if (string.IsNullOrEmpty(sysRole.Code)) + { + sysRole.Code = RandomHelper.CreateRandomString(10);//赋值Code + } + else + { + //判断是否有相同的Code + if (sysRoles.Any(it => it.Code == sysRole.Code && it.Id != sysRole.Id)) + throw Oops.Bah($"存在重复的编码:{sysRole.Code}"); + } + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Limit/Spa/Dto/SpaInput.cs b/SimpleAdmin.System/Services/Limit/Spa/Dto/SpaInput.cs new file mode 100644 index 0000000..b208dd1 --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Spa/Dto/SpaInput.cs @@ -0,0 +1,64 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 单页输入参数 +/// +public class SpaPageInput : BasePageInput +{ + /// + /// 菜单类型 + /// + public string MenuType { get; set; } +} + +/// +/// 单页输入参数 +/// +public class SpaAddInput : SysResource +{ + /// + /// 标题 + /// + [Required(ErrorMessage = "Title不能为空")] + public override string Title { get; set; } + + /// + /// 菜单类型 + /// + [Required(ErrorMessage = "Title不能为空")] + public override string MenuType { get; set; } + + /// + /// 路径 + /// + [Required(ErrorMessage = "Path不能为空")] + public override string Path { get; set; } + + /// + /// 图标 + /// + [Required(ErrorMessage = "Icon不能为空")] + public override string Icon { get; set; } +} + +/// +/// 单页修改参数 +/// +public class SpaEditInput : SpaAddInput +{ + /// + /// ID + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} diff --git a/SimpleAdmin.System/Services/Limit/Spa/ISpaService.cs b/SimpleAdmin.System/Services/Limit/Spa/ISpaService.cs new file mode 100644 index 0000000..b3fe419 --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Spa/ISpaService.cs @@ -0,0 +1,52 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 单页服务 +/// +public interface ISpaService : ITransient +{ + /// + /// 添加单页 + /// + /// 添加参数 + /// + Task Add(SpaAddInput input); + + /// + /// 删除单页 + /// + /// 删除参数 + /// + Task Delete(BaseIdListInput input); + + /// + /// 编辑单页 + /// + /// 编辑参数 + /// + Task Edit(SpaEditInput input); + + /// + /// 分页查询 + /// + /// + /// + Task> Page(SpaPageInput input); + + /// + /// 详情 + /// + /// + /// + Task Detail(BaseIdInput input); +} diff --git a/SimpleAdmin.System/Services/Limit/Spa/SpaService.cs b/SimpleAdmin.System/Services/Limit/Spa/SpaService.cs new file mode 100644 index 0000000..4806e96 --- /dev/null +++ b/SimpleAdmin.System/Services/Limit/Spa/SpaService.cs @@ -0,0 +1,130 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class SpaService : DbRepository, ISpaService +{ + private readonly IResourceService _resourceService; + + public SpaService(IResourceService resourceService) + { + _resourceService = resourceService; + } + + /// + public async Task> Page(SpaPageInput input) + { + var query = Context.Queryable().Where(it => it.Category == CateGoryConst.RESOURCE_SPA)//单页 + .WhereIF(!string.IsNullOrEmpty(input.MenuType), it => it.MenuType == input.MenuType)//根据菜单类型查询 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Title.Contains(input.SearchKey) || it.Path.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}").OrderBy(it => it.SortCode);//排序 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task Add(SpaAddInput input) + { + await CheckInput(input);//检查参数 + input.Code = RandomHelper.CreateRandomString(10);//code取随机值 + var sysResource = input.Adapt();//实体转换 + if (await InsertAsync(sysResource))//插入数据 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_SPA);//刷新缓存 + } + + /// + public async Task Edit(SpaEditInput input) + { + await CheckInput(input);//检查参数 + var sysResource = input.Adapt();//实体转换 + if (await UpdateAsync(sysResource))//更新数据 + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_SPA);//刷新缓存 + } + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + //获取所有 + var resourceList = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_SPA); + //找到要删除的 + var sysresources = resourceList.Where(it => ids.Contains(it.Id)).ToList(); + //查找内置单页面 + var system = sysresources.Where(it => it.Code == SysResourceConst.SYSTEM).FirstOrDefault(); + if (system != null) + throw Oops.Bah($"不可删除系统内置单页面:{system.Title}"); + //删除菜单 + await DeleteAsync(sysresources); + await _resourceService.RefreshCache(CateGoryConst.RESOURCE_SPA);//刷新缓存 + } + } + + /// + public async Task Detail(BaseIdInput input) + { + var sysResources = await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_SPA); + var resource = sysResources.Where(it => it.Id == input.Id).FirstOrDefault(); + return resource; + } + + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(SysResource sysResource) + { + //判断菜单类型 + if (sysResource.MenuType == SysResourceConst.MENU)//如果是菜单 + { + if (string.IsNullOrEmpty(sysResource.Name)) + { + throw Oops.Bah("单页名称不能为空"); + } + if (string.IsNullOrEmpty(sysResource.Component)) + { + throw Oops.Bah("组件地址不能为空"); + } + } + else if (sysResource.MenuType == SysResourceConst.IFRAME || sysResource.MenuType == SysResourceConst.LINK)//如果是内链或者外链 + { + // sysResource.Name = RandomHelper.CreateNum(10);//设置name为随机数 + sysResource.Name = null;//设置name为标题 + sysResource.Component = null; + } + else + { + throw Oops.Bah($"单页类型错误:{sysResource.MenuType}");//都不是 + } + if (sysResource.IsHome) + { + var spas = await _resourceService.GetListByCategory(SysResourceConst.SPA);//获取所有单页 + if (spas.Any(it => it.IsHome && it.Id != sysResource.Id))//如果有多个主页 + { + throw Oops.Bah("已存在首页,请取消其他主页后再试"); + } + sysResource.IsHide = false;//如果是主页,则不隐藏 + sysResource.IsAffix = true;//如果是主页,则固定 + } + //设置为单页 + sysResource.Category = CateGoryConst.RESOURCE_SPA; + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/LogAudit/OperateLog/Dto/OperateLogInput.cs b/SimpleAdmin.System/Services/LogAudit/OperateLog/Dto/OperateLogInput.cs new file mode 100644 index 0000000..32cd174 --- /dev/null +++ b/SimpleAdmin.System/Services/LogAudit/OperateLog/Dto/OperateLogInput.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 操作日志分页输入 +/// +public class OperateLogPageInput : VisitLogPageInput +{ +} + +/// +/// 操作日志日志删除输入 +/// +public class OperateLogDeleteInput : VisitLogDeleteInput +{ +} diff --git a/SimpleAdmin.System/Services/LogAudit/OperateLog/Dto/OperateLogOutput.cs b/SimpleAdmin.System/Services/LogAudit/OperateLog/Dto/OperateLogOutput.cs new file mode 100644 index 0000000..78e8179 --- /dev/null +++ b/SimpleAdmin.System/Services/LogAudit/OperateLog/Dto/OperateLogOutput.cs @@ -0,0 +1,39 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 操作日志周统计输出 +/// +public class OperateLogDayStatisticsOutput +{ + /// + /// 日期 + /// + public string Date { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 数量 + /// + public int Count { get; set; } +} + +/// +/// 操作日志统计 +/// +public class OperateLogTotalCountOutput : VisitLogTotalCountOutput +{ +} diff --git a/SimpleAdmin.System/Services/LogAudit/OperateLog/IOperateLogService.cs b/SimpleAdmin.System/Services/LogAudit/OperateLog/IOperateLogService.cs new file mode 100644 index 0000000..c44d516 --- /dev/null +++ b/SimpleAdmin.System/Services/LogAudit/OperateLog/IOperateLogService.cs @@ -0,0 +1,51 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 操作日志服务 +/// +public interface IOperateLogService : ITransient +{ + /// + /// 根据分类删除操作日志 + /// + /// 分类名称 + /// + Task Delete(string category); + + /// + /// 日志详情 + /// + /// id + /// 日志详情 + Task Detail(BaseIdInput input); + + /// + /// 操作日志分页查询 + /// + /// 查询参数 + /// 分页列表 + Task> Page(OperateLogPageInput input); + + /// + /// 操作日志周统计 + /// + /// 天数 + /// 统计结果 + Task> StatisticsByDay(int day); + + /// + /// 操作日志总览 + /// + /// 异常日志和操作日志的数量 + Task> TotalCount(); +} diff --git a/SimpleAdmin.System/Services/LogAudit/OperateLog/OperateLogService.cs b/SimpleAdmin.System/Services/LogAudit/OperateLog/OperateLogService.cs new file mode 100644 index 0000000..0ad47ec --- /dev/null +++ b/SimpleAdmin.System/Services/LogAudit/OperateLog/OperateLogService.cs @@ -0,0 +1,118 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class OperateLogService : DbRepository, IOperateLogService +{ + /// + /// 操作日志中文名称 + /// + private readonly string _nameOperate = "操作日志"; + + /// + /// 异常日志中文名称 + /// + private readonly string _nameException = "异常日志"; + + /// + /// 分表最多查近多少年的数据 + /// + private readonly int _maxTabs = 100; + + /// + public async Task> Page(OperateLogPageInput input) + { + var query = Context.Queryable().WhereIF(!string.IsNullOrEmpty(input.Account), it => it.OpAccount == input.Account)//根据账号查询 + .WhereIF(!string.IsNullOrEmpty(input.Category), it => it.Category == input.Category)//根据分类查询 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Name.Contains(input.SearchKey) || it.OpIp.Contains(input.SearchKey))//根据关键字查询 + .IgnoreColumns(it => new { it.ParamJson, it.ResultJson }).SplitTable(tabs => tabs.Take(_maxTabs)) + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}")//排序 + .OrderBy(it => it.CreateTime, OrderByType.Desc); + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task> StatisticsByDay(int day) + { + //取最近七天 + var dayArray = Enumerable.Range(0, day).Select(it => DateTime.Now.Date.AddDays(it * -1)).ToList(); + //生成时间表 + var queryableLeft = Context.Reportable(dayArray).ToQueryable(); + //ReportableDateType.MonthsInLast1yea 表式近一年月份 并且queryable之后还能在where过滤 + var queryableRight = Context.Queryable().SplitTable(tabs => tabs.Take(_maxTabs));//声名表 + //报表查询 + var list = await Context + .Queryable(queryableLeft, queryableRight, JoinType.Left, + (x1, x2) => x2.CreateTime.Value.ToString("yyyy-MM-dd") == x1.ColumnName.ToString("yyyy-MM-dd")) + .GroupBy((x1, x2) => x1.ColumnName)//根据时间分组 + .OrderBy((x1, x2) => x1.ColumnName)//根据时间升序排序 + .Select((x1, x2) => new + { + OperateCount = SqlFunc.AggregateSum(SqlFunc.IIF(x2.Category == CateGoryConst.LOG_OPERATE, 1, 0)),//null的数据要为0所以不能用count + ExceptionCount = SqlFunc.AggregateSum(SqlFunc.IIF(x2.Category == CateGoryConst.LOG_EXCEPTION, 1, 0)),//null的数据要为0所以不能用count + Date = x1.ColumnName.ToString("yyyy-MM-dd") + }).ToListAsync(); + //定义返回结果 + var result = new List(); + //遍历结果 + list.ForEach(it => + { + result.Add(new OperateLogDayStatisticsOutput { Date = it.Date, Name = _nameOperate, Count = it.OperateCount });//添加访问日志 + result.Add(new OperateLogDayStatisticsOutput { Date = it.Date, Name = _nameException, Count = it.ExceptionCount });//添加异常日志 + }); + return result; + } + + /// + public async Task> TotalCount() + { + var data = await Context.Queryable().SplitTable(tabs => tabs.Take(_maxTabs)).GroupBy(it => it.Category)//根据分类分组 + .Select(it => new + { + it.Category,//分类 + Count = SqlFunc.AggregateCount(it.Category)//数量 + }).ToListAsync(); + //定义结果数组 + var operateLogTotalCounts = new List + { + //添加操作日志数据 + new OperateLogTotalCountOutput + { + Type = _nameOperate, + Value = data.Where(it => it.Category == CateGoryConst.LOG_OPERATE).Select(it => it.Count).FirstOrDefault() + }, + //添加异常日志数据 + new OperateLogTotalCountOutput + { + Type = _nameException, + Value = data.Where(it => it.Category == CateGoryConst.LOG_EXCEPTION).Select(it => it.Count).FirstOrDefault() + } + }; + return operateLogTotalCounts; + } + + /// + public async Task Delete(string category) + { + await Context.Deleteable().Where(it => it.Category == category).SplitTable(tabs => tabs.Take(_maxTabs)) + .ExecuteCommandAsync();//删除对应分类日志 + } + + /// + public async Task Detail(BaseIdInput input) + { + return await GetFirstSplitTableAsync(it => it.Id == input.Id, tabs => tabs.Take(_maxTabs)); + } +} diff --git a/SimpleAdmin.System/Services/LogAudit/VisitLog/Dto/VisitLogInput.cs b/SimpleAdmin.System/Services/LogAudit/VisitLog/Dto/VisitLogInput.cs new file mode 100644 index 0000000..c4c64d9 --- /dev/null +++ b/SimpleAdmin.System/Services/LogAudit/VisitLog/Dto/VisitLogInput.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 访问日志分页输入 +/// +public class VisitLogPageInput : BasePageInput +{ + /// + /// 分类 + /// + public string Category { get; set; } + + /// + /// 账号 + /// + public string Account { get; set; } +} + +/// +/// 访问日志删除输入 +/// +public class VisitLogDeleteInput +{ + /// + /// 分类 + /// + public string Category { get; set; } +} diff --git a/SimpleAdmin.System/Services/LogAudit/VisitLog/Dto/VisitLogOutput.cs b/SimpleAdmin.System/Services/LogAudit/VisitLog/Dto/VisitLogOutput.cs new file mode 100644 index 0000000..ace9a8f --- /dev/null +++ b/SimpleAdmin.System/Services/LogAudit/VisitLog/Dto/VisitLogOutput.cs @@ -0,0 +1,48 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 周统计输出 +/// +public class VisitLogDayStatisticsOutput +{ + /// + /// 日期 + /// + public string Date { get; set; } + + /// + /// 登录次数 + /// + public int LoginCount { get; set; } + + /// + /// 登出次数 + /// + public int LogoutCount { get; set; } +} + +/// +/// 访问日志总数输出 +/// +public class VisitLogTotalCountOutput +{ + /// + /// 类型 + /// + public string Type { get; set; } + + /// + /// 数量 + /// + public int Value { get; set; } +} diff --git a/SimpleAdmin.System/Services/LogAudit/VisitLog/IVisitLogService.cs b/SimpleAdmin.System/Services/LogAudit/VisitLog/IVisitLogService.cs new file mode 100644 index 0000000..7829618 --- /dev/null +++ b/SimpleAdmin.System/Services/LogAudit/VisitLog/IVisitLogService.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 访问日志服务 +/// +public interface IVisitLogService : ITransient +{ + /// + /// 根据分类删除 + /// + /// 分类名称 + /// + Task Delete(string category); + + /// + /// 访问日志分页查询 + /// + /// 查询参数 + /// 日志列表 + Task> Page(VisitLogPageInput input); + + /// + /// 根统计N天来登录和登出数量 + /// + /// 天使 + /// 统计信息 + Task> StatisticsByDay(int day); + + /// + /// 统计登录登出总览 + /// + /// 登录和登出的数量 + Task> TotalCount(); +} diff --git a/SimpleAdmin.System/Services/LogAudit/VisitLog/VisitLogService.cs b/SimpleAdmin.System/Services/LogAudit/VisitLog/VisitLogService.cs new file mode 100644 index 0000000..7770edd --- /dev/null +++ b/SimpleAdmin.System/Services/LogAudit/VisitLog/VisitLogService.cs @@ -0,0 +1,93 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class VisitLogService : DbRepository, IVisitLogService +{ + /// + /// 分表最多查近多少年的数据 + /// + private readonly int _maxTabs = 100; + + /// + public async Task> Page(VisitLogPageInput input) + { + var query = Context.Queryable().WhereIF(!string.IsNullOrEmpty(input.Account), it => it.OpAccount == input.Account)//根据账号查询 + .WhereIF(!string.IsNullOrEmpty(input.Category), it => it.Category == input.Category)//根据分类查询 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Name.Contains(input.SearchKey) || it.OpIp.Contains(input.SearchKey))//根据关键字查询 + .SplitTable(tabs => tabs.Take(_maxTabs)).OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}")//排序 + .OrderBy(it => it.CreateTime, OrderByType.Desc); + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task> StatisticsByDay(int day) + { + //取最近七天 + var dayArray = Enumerable.Range(0, day).Select(it => DateTime.Now.Date.AddDays(it * -1)).ToList(); + //生成时间表 + var queryableLeft = Context.Reportable(dayArray).ToQueryable(); + //ReportableDateType.MonthsInLast1yea 表式近一年月份 并且queryable之后还能在where过滤 + var queryableRight = Context.Queryable().SplitTable(tabs => tabs.Take(_maxTabs));//声名表 + //报表查询 + var list = await Context + .Queryable(queryableLeft, queryableRight, JoinType.Left, + (x1, x2) => x2.CreateTime.Value.ToString("yyyy-MM-dd") == x1.ColumnName.ToString("yyyy-MM-dd")) + .GroupBy((x1, x2) => x1.ColumnName)//根据时间分组 + .OrderBy((x1, x2) => x1.ColumnName)//根据时间升序排序 + .Select((x1, x2) => new VisitLogDayStatisticsOutput + { + LoginCount = SqlFunc.AggregateSum(SqlFunc.IIF(x2.Category == CateGoryConst.LOG_LOGIN, 1, 0)),//null的数据要为0所以不能用count + LogoutCount = SqlFunc.AggregateSum(SqlFunc.IIF(x2.Category == CateGoryConst.LOG_LOGOUT, 1, 0)),//null的数据要为0所以不能用count + Date = x1.ColumnName.ToString("yyyy-MM-dd") + }).ToListAsync(); + return list; + } + + /// + public async Task> TotalCount() + { + var data = await Context.Queryable().SplitTable(tabs => tabs.Take(_maxTabs)).GroupBy(it => it.Category)//根据分类分组 + .Select(it => new + { + it.Category,//分类 + Count = SqlFunc.AggregateCount(it.Category)//数量 + }).ToListAsync(); + //定义结果数组 + var visitLogTotalCounts = new List + { + //添加登录数据 + new VisitLogTotalCountOutput + { + Type = EventSubscriberConst.LOGIN_B, + Value = data.Where(it => it.Category == CateGoryConst.LOG_LOGIN).Select(it => it.Count).FirstOrDefault() + }, + //添加登出数据 + new VisitLogTotalCountOutput + { + Type = EventSubscriberConst.LOGIN_OUT_B, + Value = data.Where(it => it.Category == CateGoryConst.LOG_LOGOUT).Select(it => it.Count).FirstOrDefault() + } + }; + return visitLogTotalCounts; + } + + /// + public async Task Delete(string category) + { + await Context.Deleteable().Where(it => it.Category == category).SplitTable(tabs => tabs.Take(_maxTabs)) + .ExecuteCommandAsync();//删除对应分类日志 + } +} diff --git a/SimpleAdmin.System/Services/Mqtt/Dto/MqttInput.cs b/SimpleAdmin.System/Services/Mqtt/Dto/MqttInput.cs new file mode 100644 index 0000000..328cfc7 --- /dev/null +++ b/SimpleAdmin.System/Services/Mqtt/Dto/MqttInput.cs @@ -0,0 +1,27 @@ +namespace SimpleAdmin.System; + +/// +/// mqtt认证参数 +/// +public class MqttAuthInput +{ + /// + /// 用户ID + /// + public string UserId { get; set; } + + /// + /// 账号 + /// + public string Username { get; set; } + + /// + /// 密码 + /// + public string Password { get; set; } + + /// + /// 客户端ID + /// + public string ClientId { get; set; } +} diff --git a/SimpleAdmin.System/Services/Mqtt/Dto/MqttOutput.cs b/SimpleAdmin.System/Services/Mqtt/Dto/MqttOutput.cs new file mode 100644 index 0000000..62b2477 --- /dev/null +++ b/SimpleAdmin.System/Services/Mqtt/Dto/MqttOutput.cs @@ -0,0 +1,49 @@ +namespace SimpleAdmin.System; + +/// +/// mqtt登录参数输出 +/// +public class MqttParameterOutput +{ + /// + /// 地址 + /// + public string Url { get; set; } + + /// + /// 用户名 + /// + public string UserName { get; set; } + + /// + /// 密码 + /// + + public string Password { get; set; } + + /// + /// 客户端ID + /// + public string ClientId { get; set; } + + /// + /// 主题列表 + /// + public List Topics { get; set; } +} + +/// +/// mqtt认证输出 +/// +public class MqttAuthOutput +{ + /// + /// 结果 "allow" | "deny" | "ignore", // Default `"ignore"` + /// + public string Result { get; set; } = "deny"; + + /// + /// 是否超级管理员 + /// + public bool Is_superuser { get; set; } = false; +} diff --git a/SimpleAdmin.System/Services/Mqtt/IMqttService.cs b/SimpleAdmin.System/Services/Mqtt/IMqttService.cs new file mode 100644 index 0000000..9aecf5f --- /dev/null +++ b/SimpleAdmin.System/Services/Mqtt/IMqttService.cs @@ -0,0 +1,21 @@ +namespace SimpleAdmin.System; + +/// +///Mqtt服务 +/// +public interface IMqttService : ITransient +{ + /// + /// mqtt登录http认证 + /// + /// 认证参数 + /// 用户Id + /// 认证结果 + Task Auth(MqttAuthInput input); + + /// + /// 获取mqtt登录web端参数 + /// + /// 登录参数 + Task GetWebLoginParameter(); +} diff --git a/SimpleAdmin.System/Services/Mqtt/MqttService.cs b/SimpleAdmin.System/Services/Mqtt/MqttService.cs new file mode 100644 index 0000000..daa4788 --- /dev/null +++ b/SimpleAdmin.System/Services/Mqtt/MqttService.cs @@ -0,0 +1,76 @@ +namespace SimpleAdmin.System; + +/// +/// +/// +public class MqttService : IMqttService +{ + private readonly ISimpleCacheService _simpleCacheService; + private readonly ISysUserService _sysUserService; + private readonly IConfigService _configService; + + public MqttService(ISimpleCacheService simpleCacheService, ISysUserService sysUserService, IConfigService configService) + { + _simpleCacheService = simpleCacheService; + _sysUserService = sysUserService; + _configService = configService; + } + + /// + public async Task GetWebLoginParameter() + { + var user = await _sysUserService.GetUserById(UserManager.UserId);//获取用户信息 + var token = JWTEncryption.GetJwtBearerToken((DefaultHttpContext)App.HttpContext);// 获取当前token + //获取mqtt配置 + var mqttconfig = await _configService.GetConfigsByCategory(CateGoryConst.CONFIG_MQTT_BASE); + //地址 + var url = mqttconfig.Where(it => it.ConfigKey == SysConfigConst.MQTT_PARAM_URL).Select(it => it.ConfigValue).FirstOrDefault(); + //用户名 + var userName = mqttconfig.Where(it => it.ConfigKey == SysConfigConst.MQTT_PARAM_USERNAME).Select(it => it.ConfigValue).FirstOrDefault(); + //密码 + var password = mqttconfig.Where(it => it.ConfigKey == SysConfigConst.MQTT_PARAM_PASSWORD).Select(it => it.ConfigValue).FirstOrDefault(); + + #region 用户名特殊处理 + + if (userName.ToLower() == "$username") + userName = user.Account; + else if (userName.ToLower() == "$userid") + userName = user.Id.ToString(); + + #endregion 用户名特殊处理 + + #region 密码特殊处理 + + if (password.ToLower() == "$username") + password = token;// 当前token作为mqtt密码 + + #endregion 密码特殊处理 + + var clientId = $"{user.Id}_{RandomHelper.CreateLetterAndNumber(5)}";//客户端ID + _simpleCacheService.Set(MqttConst.CACHE_MQTT_CLIENT_USER + clientId, token, + TimeSpan.FromMinutes(1));//将该客户端ID对应的token插入redis后面可以根据这个判断是哪个token登录的 + return new MqttParameterOutput + { + ClientId = clientId, + Password = password, + Url = url, + UserName = userName, + Topics = new List { MqttConst.MQTT_TOPIC_PREFIX + user.Id }//默认监听自己 + }; + } + + /// + public async Task Auth(MqttAuthInput input) + { + var user = await _sysUserService.GetUserByAccount(input.Username); + var mqttAuthOutput = new MqttAuthOutput { Is_superuser = false, Result = "deny" }; + //获取用户token + var tokens = _simpleCacheService.HashGetOne>(CacheConst.CACHE_USER_TOKEN, user.Id.ToString()); + if (tokens != null) + { + if (tokens.Any(it => it.Token == input.Password))//判断是否有token + mqttAuthOutput.Result = "allow";//允许登录 + } + return mqttAuthOutput; + } +} diff --git a/SimpleAdmin.System/Services/Ops/Config/ConfigService.cs b/SimpleAdmin.System/Services/Ops/Config/ConfigService.cs new file mode 100644 index 0000000..46e0698 --- /dev/null +++ b/SimpleAdmin.System/Services/Ops/Config/ConfigService.cs @@ -0,0 +1,206 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +public class ConfigService : DbRepository, IConfigService +{ + private readonly ISimpleCacheService _simpleCacheService; + + public ConfigService(ISimpleCacheService simpleCacheService) + { + _simpleCacheService = simpleCacheService; + } + + #region 查询 + + /// + public async Task> GetConfigsByCategory(string category) + { + var key = SystemConst.CACHE_DEV_CONFIG + category;//系统配置key + //先从redis拿配置 + var configList = _simpleCacheService.HashGetAll(key).Values.ToList(); + if (configList.Count == 0) + { + //redis没有再去数据可拿 + var configs = await GetListAsync(it => it.Category == category);//获取系统配置列表 + if (configs.Count > 0) + { + configList = configs; + _simpleCacheService.HashSet(key, configList.ToDictionary(it => it.ConfigKey));//如果不为空,插入redis + } + } + return configList.ToList(); + } + + /// + public async Task> GetSysConfigList() + { + //这里不返回系统配置 + return await GetListAsync(it => it.Category != CateGoryConst.CONFIG_BIZ_DEFINE); + } + + /// + public async Task GetByConfigKey(string category, string configKey) + { + var key = SystemConst.CACHE_DEV_CONFIG + category;//系统配置key + //先从redis拿配置 + var config = _simpleCacheService.HashGetOne(key, configKey); + if (config == null) + { + //redis没有再去数据可拿 + config = await GetFirstAsync(it => it.Category == category && it.ConfigKey == configKey);//获取系统配置 + if (config != null) + { + await GetConfigsByCategory(category);//获取全部字典,并插入redis + } + } + return config; + } + + /// + public async Task> Page(ConfigPageInput input) + { + var query = Context.Queryable().Where(it => it.Category == CateGoryConst.CONFIG_BIZ_DEFINE)//自定义配置 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), + it => it.ConfigKey.Contains(input.SearchKey) || it.ConfigValue.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}")//排序 + .OrderBy(it => it.SortCode) + .OrderBy(it => it.CreateTime);//排序 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task GetIco() + { + var config = await GetByConfigKey(CateGoryConst.CONFIG_SYS_BASE, SysConfigConst.SYS_ICO);//获取系统配置 ico + var icoBase64 = config.ConfigValue.Split(",")[1];//获取ico的base64 + //转为byte数组 + var bytes = Convert.FromBase64String(icoBase64); + //将byte数组转为流 + var stream = new MemoryStream(bytes); + return new FileStreamResult(stream, "image/x-icon"); + } + + /// + public async Task IsTenant() + { + var tenantOption = await GetByConfigKey(CateGoryConst.CONFIG_SYS_BASE, SysConfigConst.SYS_TENANT_OPTIONS); + var isTenant = tenantOption.ConfigValue != SysDictConst.TENANT_OPTIONS_CLOSE;//是否开启多租户 + return isTenant; + } + + #endregion + + #region 添加 + + /// + public async Task Add(ConfigAddInput input) + { + await CheckInput(input); + var devConfig = input.Adapt();//实体转换 + if (await InsertAsync(devConfig))//插入数据) + await RefreshCache(CateGoryConst.CONFIG_BIZ_DEFINE);//刷新缓存 + } + + #endregion + + #region 编辑 + + /// + public async Task Edit(ConfigEditInput input) + { + await CheckInput(input); + var devConfig = input.Adapt();//实体转换 + if (await UpdateAsync(devConfig))//更新数据 + await RefreshCache(CateGoryConst.CONFIG_BIZ_DEFINE);//刷新缓存 + } + + /// + public async Task EditBatch(List devConfigs) + { + if (devConfigs.Count > 0) + { + //根据分类分组 + var configGroups = devConfigs.GroupBy(it => it.Category).ToList(); + //遍历分组 + foreach (var item in configGroups) + { + var configList = await GetConfigsByCategory(item.Key);//获取系统配置 + var configs = item.ToList();//获取分组完的配置列表 + var keys = configs.Select(it => it.ConfigKey).ToList();//获取key列表 + configList = configList.Where(it => keys.Contains(it.ConfigKey)).ToList();//获取要修改的列表 + //遍历配置列表 + configList.ForEach(it => + { + //赋值ConfigValue + it.ConfigValue = configs.Where(c => c.ConfigKey == it.ConfigKey).First().ConfigValue; + }); + //更新数据 + if (await UpdateRangeAsync(configList)) + await RefreshCache(item.Key);//刷新缓存 + } + } + } + + #endregion + + #region 删除 + + /// + public async Task Delete(ConfigDeleteInput input) + { + //获取所有业务配置 + var configs = await GetConfigsByCategory(CateGoryConst.CONFIG_BIZ_DEFINE); + if (configs.Any(it => it.Id == input.Id))//如果有当前配置 + { + if (await DeleteByIdAsync(input.Id))//删除配置 + await RefreshCache(CateGoryConst.CONFIG_BIZ_DEFINE);//刷新缓存 + } + } + + #endregion + + + + #region 方法 + + /// + /// 刷新缓存 + /// + /// 分类 + /// + private async Task RefreshCache(string category) + { + _simpleCacheService.Remove(SystemConst.CACHE_DEV_CONFIG + category);//redis删除 + await GetConfigsByCategory(category);//重新获取 + } + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(SysConfig sysConfig) + { + var configs = await GetConfigsByCategory(CateGoryConst.CONFIG_BIZ_DEFINE);//获取全部字典 + //判断是否从存在重复字典名 + var hasSameKey = configs.Any(it => it.ConfigKey == sysConfig.ConfigKey && it.Id != sysConfig.Id); + if (hasSameKey) + { + throw Oops.Bah($"存在重复的配置键:{sysConfig.ConfigKey}"); + } + //设置分类为业务 + sysConfig.Category = CateGoryConst.CONFIG_BIZ_DEFINE; + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Ops/Config/Dto/ConfigInput.cs b/SimpleAdmin.System/Services/Ops/Config/Dto/ConfigInput.cs new file mode 100644 index 0000000..42a02db --- /dev/null +++ b/SimpleAdmin.System/Services/Ops/Config/Dto/ConfigInput.cs @@ -0,0 +1,69 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 配置分页参数 +/// +public class ConfigPageInput : BasePageInput +{ +} + +/// +/// 添加配置参数 +/// +public class ConfigAddInput : SysConfig +{ + /// + /// 配置键 + /// + [Required(ErrorMessage = "configKey不能为空")] + public override string ConfigKey { get; set; } + + /// + /// 配置值 + /// + + [Required(ErrorMessage = "ConfigValue不能为空")] + public override string ConfigValue { get; set; } +} + +/// +/// 编辑配置参数 +/// +public class ConfigEditInput : ConfigAddInput +{ + /// + /// ID + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} + +/// +/// 删除配置参数 +/// +public class ConfigDeleteInput : BaseIdInput +{ +} + +/// +/// 批量修改输入参数 +/// +public class ConfigEditBatchInput +{ + /// + /// 分类 + /// + public string CateGory { get; set; } + + public List DevConfigs { get; set; } +} diff --git a/SimpleAdmin.System/Services/Ops/Config/IConfigService.cs b/SimpleAdmin.System/Services/Ops/Config/IConfigService.cs new file mode 100644 index 0000000..a629fe8 --- /dev/null +++ b/SimpleAdmin.System/Services/Ops/Config/IConfigService.cs @@ -0,0 +1,97 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 系统配置服务 +/// +public interface IConfigService : ITransient +{ + #region 查询 + + /// + /// 根据分类和配置键获配置 + /// + /// 分类 + /// 配置键 + /// 配置信息 + Task GetByConfigKey(string category, string configKey); + + /// + /// 根据分类获取配置列表 + /// + /// 分类名称 + /// 配置列表 + Task> GetConfigsByCategory(string category); + + /// + /// 分页查询其他配置 + /// + /// 查询参数 + /// 其他配置列表 + Task> Page(ConfigPageInput input); + + Task GetIco(); + + /// + /// 获取系统配置列表,不包含业务的 + /// + /// + Task> GetSysConfigList(); + + /// + /// 是否是多租户模式 + /// + /// + Task IsTenant(); + + #endregion + + #region 新增 + + /// + /// 新增配置 + /// + /// 新增参数 + /// + Task Add(ConfigAddInput input); + + #endregion + + #region 编辑 + + /// + /// 修改配置 + /// + /// 修改参数 + /// + Task Edit(ConfigEditInput input); + + /// + /// 批量编辑 + /// + /// 配置列表 + /// + Task EditBatch(List devConfigs); + + #endregion + + #region 删除 + + /// + /// 删除配置 + /// + /// 删除 + /// + Task Delete(ConfigDeleteInput input); + + #endregion +} diff --git a/SimpleAdmin.System/Services/Ops/Dict/DictService.cs b/SimpleAdmin.System/Services/Ops/Dict/DictService.cs new file mode 100644 index 0000000..ba949fb --- /dev/null +++ b/SimpleAdmin.System/Services/Ops/Dict/DictService.cs @@ -0,0 +1,237 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class DictService : DbRepository, IDictService +{ + private readonly ISimpleCacheService _simpleCacheService; + + public DictService(ISimpleCacheService simpleCacheService) + { + _simpleCacheService = simpleCacheService; + } + + /// + public async Task> Page(DictPageInput input) + { + var query = Context.Queryable().Where(it => it.Category == input.Category)//根据分类查询 + .Where(it => it.ParentId == input.ParentId)//根据父ID查询 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), + it => it.DictLabel.Contains(input.SearchKey) || it.DictValue.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}") + .OrderBy(it => it.SortCode)//排序 + .OrderBy(it => it.CreateTime);//排序 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task Add(DictAddInput input) + { + await CheckInput(input);//检查参数 + var devDict = input.Adapt();//实体转换 + if (await InsertAsync(devDict))//插入数据 + await RefreshCache();//刷新缓存 + } + + /// + public async Task Edit(DictAddInput input) + { + await CheckInput(input);//检查参数 + var devDict = input.Adapt();//实体转换 + if (await UpdateAsync(devDict))//更新数据 + await RefreshCache();//刷新缓存 + } + + /// + public async Task Delete(DictDeleteInput input) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + //获取所有字典 + var dictList = await GetListAsync(); + //判断是否有系统字典 + var frm = dictList.Any(it => ids.Contains(it.Id) && it.Category == CateGoryConst.DICT_FRM); + + //如果是系统字典提示不可删除 + if (frm) throw Oops.Bah("不可删除系统内置字典"); + var deleteIds = new List();//要删除的id列表 + deleteIds.AddRange(ids);// + ids.ForEach(it => + { + //获取子节点 + var children = GetDevDictChildren(dictList, it); + //提取ID + var childrenIds = children.Select(c => c.Id).ToList(); + deleteIds.AddRange(childrenIds); + }); + //删除数据 + if (await DeleteByIdsAsync(deleteIds.Cast().ToArray())) + await RefreshCache();//刷新缓存 + } + } + + /// + /// 获取全部 + /// + /// + public override async Task> GetListAsync() + { + //先从redis拿 + var sysDictList = _simpleCacheService.Get>(SystemConst.CACHE_DEV_DICT); + if (sysDictList == null) + { + sysDictList = await base.GetListAsync();//去数据库拿 + if (sysDictList.Count > 0) + { + _simpleCacheService.Set(SystemConst.CACHE_DEV_DICT, sysDictList);//如果数据库有数,更新redis + return sysDictList; + } + } + return sysDictList; + } + + /// + public async Task GetDict(string dictValue) + { + var sysDictList = await GetListAsync(); + var devDict = sysDictList.Where(it => it.DictValue == dictValue).FirstOrDefault(); + return devDict; + } + + /// + public async Task> GetChildrenByDictValue(string dictValue) + { + var sysDictList = await GetListAsync(); + var devDict = sysDictList.Where(it => it.DictValue == dictValue).FirstOrDefault(); + if (devDict != null) + { + var children = GetDevDictChildren(sysDictList, devDict.Id); + return children; + } + return new List(); + } + + /// + public async Task> GetValuesByDictValue(string dictValue, List devDictList = null) + { + var sysDictList = devDictList == null ? await GetListAsync() : devDictList;//获取全部 + var id = sysDictList.Where(it => it.DictValue == dictValue).Select(it => it.Id).FirstOrDefault();//根据value找到父节点 + if (id > 0) + return sysDictList.Where(it => it.ParentId == id).Select(it => it.DictValue).ToList();//拿到字典值 + return new List(); + } + + /// + public async Task>> GetValuesByDictValue(string[] dictValues) + { + var result = new Dictionary>(); + var sysDictList = await GetListAsync();//获取全部 + foreach (var dictValue in dictValues) + { + var data = await GetValuesByDictValue(dictValue, sysDictList); + result.Add(dictValue, data); + } + return result; + } + + /// + public async Task> Tree(DictTreeInput input) + { + var devList= await Context.Queryable() + .WhereIF(!string.IsNullOrEmpty(input.Category), it => it.Category == input.Category) + .WhereIF(!string.IsNullOrEmpty(input.DictValue), it => it.DictValue == input.DictValue) + .OrderBy(it => it.SortCode) + .ToListAsync(); + return ConstructResourceTrees(devList); + } + /// + public List ConstructResourceTrees(List dictList, long parentId = 0) + { + //找下级字典ID列表 + var resources = dictList.Where(it => it.ParentId == parentId).OrderBy(it => it.SortCode).ToList(); + if (resources.Count > 0)//如果数量大于0 + { + var data = new List(); + foreach (var item in resources)//遍历字典 + { + item.Children = ConstructResourceTrees(dictList, item.Id);//添加子节点 + data.Add(item);//添加到列表 + } + return data;//返回结果 + } + return new List(); + } + + #region 方法 + + /// + /// 刷新缓存 + /// + private async Task RefreshCache() + { + _simpleCacheService.Remove(SystemConst.CACHE_DEV_DICT); + await GetListAsync(); + } + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(SysDict sysDict) + { + var dictList = await GetListAsync();//获取全部字典 + //判断是否从存在重复字典名 + var hasSameLabel = dictList.Any(it => + it.ParentId == sysDict.ParentId && it.Category == sysDict.Category && it.DictLabel == sysDict.DictLabel && it.Id != sysDict.Id); + if (hasSameLabel) + { + throw Oops.Bah($"存在重复的字典名称:{sysDict.DictLabel}"); + } + //判断是否存在重复字典值 + var hasSameValue = dictList.Any(it => it.ParentId == sysDict.ParentId && it.DictValue == sysDict.DictValue && it.Id != sysDict.Id); + if (hasSameValue) + { + throw Oops.Bah($"存在重复的字典值:{sysDict.DictValue}"); + } + } + + /// + /// 获取字典所有下级 + /// + /// 字典列表 + /// 父ID + /// + public List GetDevDictChildren(List dictList, long parentId) + { + //找下级ID列表 + var dicts = dictList.Where(it => it.ParentId == parentId).ToList(); + if (dicts.Count > 0)//如果数量大于0 + { + var data = new List(); + foreach (var item in dicts)//遍历机构 + { + var devDictChildren = GetDevDictChildren(dictList, item.Id); + data.AddRange(devDictChildren);//添加子节点); + data.Add(item);////添加到列表 + } + return data;//返回结果 + } + return new List(); + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Ops/Dict/Dto/DictInput.cs b/SimpleAdmin.System/Services/Ops/Dict/Dto/DictInput.cs new file mode 100644 index 0000000..37cb41e --- /dev/null +++ b/SimpleAdmin.System/Services/Ops/Dict/Dto/DictInput.cs @@ -0,0 +1,90 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 字典查询参数 +/// +public class DictInput +{ +} + +/// +/// 字典树参数 +/// +public class DictTreeInput +{ + /// + /// 字典分类 + /// + public string Category { get; set; } + + public string DictValue { get; set; } +} + +/// +/// 字典查询参数 +/// +public class DictPageInput : BasePageInput +{ + /// + /// 父id + /// + public long ParentId { get; set; } + + /// + /// 分类 + /// + public string Category { get; set; } = SysDictConst.DICT_CATEGORY_FRM; +} + +/// +/// 添加字典参数 +/// +public class DictAddInput : SysDict +{ + /// + /// 父ID + /// + public override long ParentId { get; set; } = 0; + + /// + /// 字典名称 + /// + [Required(ErrorMessage = "DictLabel不能为空")] + public override string DictLabel { get; set; } + + /// + /// 字典值 + /// + + [Required(ErrorMessage = "DictValue不能为空")] + public override string DictValue { get; set; } +} + +/// +/// 编辑字典参数 +/// +public class DictEditInput : DictAddInput +{ + /// + /// ID + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} + +/// +/// 删除字典参数 +/// +public class DictDeleteInput : BaseIdListInput +{ +} diff --git a/SimpleAdmin.System/Services/Ops/Dict/IDictService.cs b/SimpleAdmin.System/Services/Ops/Dict/IDictService.cs new file mode 100644 index 0000000..6ba922b --- /dev/null +++ b/SimpleAdmin.System/Services/Ops/Dict/IDictService.cs @@ -0,0 +1,95 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 字典服务 +/// +public interface IDictService : ITransient +{ + /// + /// 添加字典 + /// + /// 输入参数 + /// + Task Add(DictAddInput input); + + /// + /// 构建字典树形结构 + /// + /// 字典列表 + /// 父ID + /// 字典树形结构 + List ConstructResourceTrees(List dictList, long parentId = 0); + + /// + /// 删除字典 + /// + /// 删除参数 + /// + Task Delete(DictDeleteInput input); + + /// + /// 编辑字典 + /// + /// 输入参数 + /// + Task Edit(DictAddInput input); + + /// + /// 获取字典 + /// + /// 字典 + /// + Task GetDict(string dictValue); + + /// + /// 获取所有 + /// + /// 字典列表 + Task> GetListAsync(); + + /// + /// 根据字典DictValue获取字典值列表 + /// + /// 字典值 + /// 字典列表 + /// 字典值列表 + Task> GetValuesByDictValue(string dictValue, List devDictList = null); + + /// + /// 根据字典DictValue列表获取对应字典值列表 + /// + /// 字典值列表 + /// + Task>> GetValuesByDictValue(string[] dictValues); + + /// + /// 字典分页查询 + /// + /// 查询参数 + /// 字典分页列表 + Task> Page(DictPageInput input); + + /// + /// 获取字典树形结构 + /// + /// 查询参数 + /// 字典树形结构 + Task> Tree(DictTreeInput input); + + /// + /// 根据字典值获取子级字典 + /// + /// 字典值 + /// + Task> GetChildrenByDictValue(string dictValue); +} diff --git a/SimpleAdmin.System/Services/Organization/Org/Dto/SysOrgInput.cs b/SimpleAdmin.System/Services/Organization/Org/Dto/SysOrgInput.cs new file mode 100644 index 0000000..7ac2b30 --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/Org/Dto/SysOrgInput.cs @@ -0,0 +1,140 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 组织分页查询参数 +/// +public class SysOrgPageInput : BasePageInput +{ + /// + /// 父ID + /// + public long ParentId { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 编码 + /// + public string Code { get; set; } + + /// + /// 分类 + /// + public string Category { get; set; } + + /// + /// 状态 + /// + public string Status { get; set; } +} + +/// +/// 组织添加参数 +/// +public class SysOrgAddInput : SysOrg +{ +} + +/// +/// 组织修改参数 +/// +public class SysOrgEditInput : SysOrgAddInput +{ + /// + /// Id + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} + +/// +/// 组织复制参数 +/// +public class SysOrgCopyInput +{ + /// + /// 目标ID + /// + public long TargetId { get; set; } + + /// + /// 组织Id列表 + /// + [Required(ErrorMessage = "Ids列表不能为空")] + public List? Ids { get; set; } + + /// + /// 是否包含下级 + /// + public bool ContainsChild { get; set; } = false; + + /// + /// 是否包含职位 + /// + public bool ContainsPosition { get; set; } = false; +} + +/// +/// 组织导入 +/// +public class SysOrgImportInput : ImportTemplateInput +{ + /// + /// 名称 + /// + [ImporterHeader(Name = "名称")] + [Required(ErrorMessage = "名称不能为空")] + public string Name { get; set; } + + /// + /// 上级组织 + /// + [ImporterHeader(Name = "上级组织")] + [Required(ErrorMessage = "上级组织不能为空")] + public string Names { get; set; } + + /// + /// 分类 + /// + [ImporterHeader(Name = "分类")] + [Required(ErrorMessage = "分类不能为空")] + public string Category { get; set; } + + /// + /// 排序码 + /// + [ImporterHeader(Name = "排序码")] + public int SortCode { get; set; } = 1; + + /// + /// 主管账号 + /// + [ImporterHeader(Name = "主管账号")] + [Required(ErrorMessage = "主管账号不能为空")] + public string Director { get; set; } +} + +/// +/// 组织树查询参数 +/// 懒加载用 +/// +public class SysOrgTreeInput +{ + /// + /// 父Id + /// + public long? ParentId { get; set; } +} diff --git a/SimpleAdmin.System/Services/Organization/Org/Dto/SysOrgOutput.cs b/SimpleAdmin.System/Services/Organization/Org/Dto/SysOrgOutput.cs new file mode 100644 index 0000000..cfde937 --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/Org/Dto/SysOrgOutput.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + + + + + diff --git a/SimpleAdmin.System/Services/Organization/Org/ISysOrgService.cs b/SimpleAdmin.System/Services/Organization/Org/ISysOrgService.cs new file mode 100644 index 0000000..be05e09 --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/Org/ISysOrgService.cs @@ -0,0 +1,178 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 组织架构服务 +/// +public interface ISysOrgService : ITransient +{ + #region 查询 + + /// + /// 检查组织是否存在 + /// + /// 组织列表 + /// 组织名称 + /// 父Id + /// 组织Id + /// 是否存在,存在返回组织ID + bool IsExistOrgByName(List sysOrgList, string orgName, long parentId, + out long orgId); + + /// + /// 组织详情 + /// + /// id参数 + /// 组织信息 + Task Detail(BaseIdInput input); + + /// + /// 根据组织ID获取 下级 + /// + /// 组织ID + /// 是否包含自己 + /// 组织列表 + /// + Task> GetChildListById(long orgId, bool isContainOneself = true, List sysOrgList = null); + + + /// + /// 获取所有组织 + /// + /// 是否显示禁用的 + /// + Task> GetListAsync(bool showDisabled = true); + + /// + /// 获取机构及下级ID列表 + /// + /// + /// + /// 组织列表 + /// + Task> GetOrgChildIds(long orgId, bool isContainOneself = true, List sysOrgList = null); + + /// + /// 根据组织Id递归获取上级 + /// + /// 组织列表 + /// 组织Id + /// 是否包含自己 + /// + List GetOrgParents(List allOrgList, long orgId, bool includeSelf = true); + + /// + /// 获取组织信息 + /// + /// 组织id + /// 组织信息 + Task GetSysOrgById(long id); + + /// + /// 组织分页查询 + /// + /// 查询参数 + /// 分页信息 + Task> Page(SysOrgPageInput input); + + /// + /// 根据ID列表获取组织列表 + /// + /// + /// + Task> GetOrgListByIdList(IdListInput input); + + /// + /// 获取租户列表 + /// + /// + Task> GetTenantList(); + + /// + /// 根据组织ID获取租户ID + /// + /// 组织id + /// 租户id + /// + Task GetTenantIdByOrgId(long orgId, List sysOrgList = null); + + #endregion 查询 + + #region 新增 + + /// + /// 添加组织 + /// + /// 添加参数 + /// 名称 + /// + Task Add(SysOrgAddInput input, string name = SystemConst.SYS_ORG); + + /// + /// 复制组织 + /// + /// 机构复制参数 + /// + Task Copy(SysOrgCopyInput input); + + #endregion 新增 + + #region 编辑 + + /// + /// 编辑组织 + /// + /// 编辑参数 + /// 名称 + /// + Task Edit(SysOrgEditInput input, string name = SystemConst.SYS_ORG); + + #endregion 编辑 + + #region 删除 + + /// + /// 删除组织 + /// + /// 删除参数 + /// 名称 + /// + Task Delete(BaseIdListInput input, string name = SystemConst.SYS_ORG); + + #endregion 删除 + + #region 其他 + + /// + /// 构建组织树形结构 + /// + /// 组织列表 + /// 父ID + /// 树型结构 + List ConstructOrgTrees(List orgList, long parentId = SimpleAdminConst.ZERO); + + /// + /// 刷新缓存 + /// + /// + Task RefreshCache(); + + /// + /// 获取组织树型结构 + /// + /// 机构ID列表 + /// 组织选择器(懒加载用) + /// 组织树列表 + Task> Tree(List orgIds = null, SysOrgTreeInput treeInput = null); + + #endregion 其他 +} diff --git a/SimpleAdmin.System/Services/Organization/Org/SysOrgService.cs b/SimpleAdmin.System/Services/Organization/Org/SysOrgService.cs new file mode 100644 index 0000000..77e92ff --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/Org/SysOrgService.cs @@ -0,0 +1,643 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System.Diagnostics; + +namespace SimpleAdmin.System; + +/// +public class SysOrgService : DbRepository, ISysOrgService +{ + private readonly ILogger _logger; + private readonly ISimpleCacheService _simpleCacheService; + private readonly IEventPublisher _eventPublisher; + + public SysOrgService(ILogger logger, ISimpleCacheService simpleCacheService, IEventPublisher eventPublisher) + { + _logger = logger; + _simpleCacheService = simpleCacheService; + _eventPublisher = eventPublisher; + } + + #region 查询 + + /// + public async Task> GetListAsync(bool showDisabled = true) + { + var sysOrgList = _simpleCacheService.Get>(SystemConst.CACHE_SYS_ORG); + if (sysOrgList == null) + { + //redis没有就去数据库拿 + sysOrgList = await base.GetListAsync(); + if (sysOrgList.Count > 0) + { + //插入Redis + _simpleCacheService.Set(SystemConst.CACHE_SYS_ORG, sysOrgList); + } + } + if (!showDisabled) + { + sysOrgList = sysOrgList.Where(it => it.Status == CommonStatusConst.ENABLE).ToList(); + } + return sysOrgList; + } + + /// + public async Task GetSysOrgById(long id) + { + var sysOrg = await GetListAsync(); + var result = sysOrg.Where(it => it.Id == id).FirstOrDefault(); + return result; + } + + /// + public async Task> GetChildListById(long orgId, bool isContainOneself = true, List sysOrgList = null) + { + //获取所有组织 + sysOrgList ??= await GetListAsync(); + //查找下级 + var childList = GetSysOrgChildren(sysOrgList, orgId); + if (isContainOneself)//如果包含自己 + { + //获取自己的组织信息 + var self = sysOrgList.Where(it => it.Id == orgId).FirstOrDefault(); + if (self != null) childList.Insert(0, self);//如果组织不为空就插到第一个 + } + return childList; + } + + /// + public async Task> GetOrgChildIds(long orgId, bool isContainOneself = true, List sysOrgList = null) + { + var orgIds = new List();//组织列表 + if (orgId > 0)//如果orgId有值 + { + //获取所有子集 + var childList = await GetChildListById(orgId, isContainOneself, sysOrgList); + orgIds = childList.Select(x => x.Id).ToList();//提取ID列表 + } + return orgIds; + } + + /// + public async Task> Page(SysOrgPageInput input) + { + var query = Context.Queryable() + .WhereIF(input.ParentId > 0, + it => it.ParentId == input.ParentId || it.Id == input.ParentId || SqlFunc.JsonLike(it.ParentIdList, input.ParentId.ToString()))//父级 + .WhereIF(!string.IsNullOrEmpty(input.Name), it => it.Name.Contains(input.Name))//根据名称查询 + .WhereIF(!string.IsNullOrEmpty(input.Category), it => it.Category == input.Category)//根据分类查询 + .WhereIF(!string.IsNullOrEmpty(input.Code), it => it.Code.Contains(input.Code))//根据编码查询 + .WhereIF(!string.IsNullOrEmpty(input.Status), it => it.Status == input.Status)//根据状态查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}").OrderBy(it => it.SortCode) + .OrderBy(it => it.CreateTime);//排序 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task> Tree(List orgIds = null, SysOrgTreeInput treeInput = null) + { + long parentId = SimpleAdminConst.ZERO;//父级ID + //获取所有组织 + var sysOrgList = await GetListAsync(false); + if (orgIds != null) + sysOrgList = GetParentListByIds(sysOrgList, orgIds);//如果组织ID不为空则获取组织ID列表的所有父节点 + //如果选择器ID不为空则表示是懒加载,只加载子节点 + if (treeInput != null && treeInput.ParentId != null) + { + parentId = treeInput.ParentId.Value; + sysOrgList = GetSysOrgChildrenLazy(sysOrgList, treeInput.ParentId.Value);//获取懒加载下级 + } + sysOrgList = sysOrgList.OrderBy(it => it.SortCode).ToList();//排序 + //构建组织树 + var result = ConstructOrgTrees(sysOrgList, parentId); + return result; + } + + /// + public async Task Detail(BaseIdInput input) + { + var sysOrgList = await GetListAsync(); + var orgDetail = sysOrgList.Where(it => it.Id == input.Id).FirstOrDefault(); + if (orgDetail.DirectorId != null) + { + //获取主管信息 + orgDetail.DirectorInfo = await Tenant.QueryableWithAttr().Where(it => it.Id == orgDetail.DirectorId).Select(it => + new UserSelectorOutPut + { + Id = it.Id, + Name = it.Name, + Account = it.Account + }).FirstAsync(); + } + return orgDetail; + } + + /// + public List GetOrgParents(List allOrgList, long orgId, bool includeSelf = true) + { + //找到组织 + var sysOrgList = allOrgList.Where(it => it.Id == orgId).FirstOrDefault(); + if (sysOrgList != null)//如果组织不为空 + { + var data = new List(); + var parents = GetOrgParents(allOrgList, sysOrgList.ParentId, includeSelf);//递归获取父节点 + data.AddRange(parents);//添加父节点; + if (includeSelf) + data.Add(sysOrgList);//添加到列表 + return data;//返回结果 + } + return new List(); + } + + /// + public bool IsExistOrgByName(List sysOrgList, string orgName, long parentId, + out long orgId) + { + orgId = 0; + var sysOrg = sysOrgList.Where(it => it.ParentId == parentId && it.Name == orgName).FirstOrDefault(); + if (sysOrg != null) + { + orgId = sysOrg.Id; + return true; + } + return false; + } + + /// + public async Task> GetOrgListByIdList(IdListInput input) + { + var sysOrgList = await GetListAsync(); + var orgList = sysOrgList.Where(it => input.IdList.Contains(it.Id)).ToList();// 获取指定ID的组织列表 + return orgList; + } + + + /// + public async Task> GetTenantList() + { + var tenantList = _simpleCacheService.Get>(SystemConst.CACHE_SYS_TENANT); + if (tenantList == null) + { + var orgList = await GetListAsync(false); + tenantList = orgList.Where(it => it.Category == CateGoryConst.ORG_COMPANY).ToList(); + if (tenantList.Count > 0) + { + //插入Redis + _simpleCacheService.Set(SystemConst.CACHE_SYS_TENANT, tenantList); + } + } + return tenantList; + } + + /// + public async Task GetTenantIdByOrgId(long orgId, List sysOrgList = null) + { + //先从缓存拿租户Id + var tenantId = _simpleCacheService.HashGetOne(SystemConst.CACHE_SYS_ORG_TENANT, orgId.ToString()); + if (tenantId == null) + { + //获取所有组织 + sysOrgList ??= await GetListAsync(); + var userOrg = sysOrgList.FirstOrDefault(it => it.Id == orgId); + if (userOrg != null) + { + //如果是公司直接返回 + if (userOrg.Category == CateGoryConst.ORG_COMPANY) + { + tenantId = userOrg.Id; + } + else + { + var parentIds = userOrg.ParentIdList;//获取父级ID列表 + //从最后一个往前遍历,取第一个公司ID为租户ID + for (var i = parentIds.Count - 1; i >= 0; i--) + { + var parentId = parentIds[i]; + var org = sysOrgList.FirstOrDefault(it => it.Id == parentId); + if (org.Category == CateGoryConst.ORG_COMPANY) + { + tenantId = org.Id;//租户ID + break; + } + } + } + if (tenantId != null) + _simpleCacheService.HashAdd(SystemConst.CACHE_SYS_ORG_TENANT, orgId.ToString(), tenantId);//插入缓存 + } + } + return tenantId; + } + + #endregion 查询 + + #region 新增 + + /// + public async Task Add(SysOrgAddInput input, string name = SystemConst.SYS_ORG) + { + await CheckInput(input, name);//检查参数 + var sysOrg = input.Adapt();//实体转换 + if (await InsertAsync(sysOrg))//插入数据 + await RefreshCache();//刷新缓存 + } + + /// + public async Task Copy(SysOrgCopyInput input) + { + var orgList = await GetListAsync();//获取所有 + var positionList = await Context.Queryable().ToListAsync();//获取所有职位 + var ids = new HashSet();//定义不重复Id集合 + var addOrgList = new List();//添加机构列表 + var addPositionList = new List();//添加职位列表 + var alreadyIds = new HashSet();//定义已经复制过得组织Id + ids.AddRange(input.Ids);//加到集合 + if (ids.Contains(input.TargetId)) + throw Oops.Bah("不能包含自己"); + //获取目标组织 + var target = orgList.Where(it => it.Id == input.TargetId).FirstOrDefault(); + if (target != null) + { + //需要复制的组织名称列表 + var orgNames = orgList.Where(it => ids.Contains(it.Id)).Select(it => it.Name).ToList(); + //目标组织的一级子组织名称列表 + var targetChildNames = orgList.Where(it => it.ParentId == input.TargetId).Select(it => it.Name).ToList(); + orgNames.ForEach(it => + { + if (targetChildNames.Contains(it)) throw Oops.Bah($"已存在{it}"); + }); + foreach (var id in input.Ids) + { + var org = orgList.Where(o => o.Id == id).FirstOrDefault();//获取组织 + if (org != null && !alreadyIds.Contains(id)) + { + alreadyIds.Add(id);//添加到已复制列表 + RedirectOrg(org);//生成新的实体 + org.ParentId = input.TargetId;//父id为目标Id + addOrgList.Add(org); + //是否包含职位 + if (input.ContainsPosition) + { + var positions = positionList.Where(p => p.OrgId == id).ToList();//获取机构下的职位 + positions.ForEach(p => + { + p.OrgId = org.Id;//赋值新的机构ID + p.Id = CommonUtils.GetSingleId();//生成新的ID + p.Code = RandomHelper.CreateRandomString(10);//生成新的Code + addPositionList.Add(p);//添加到职位列表 + }); + } + //是否包含下级 + if (input.ContainsChild) + { + var childIds = await GetOrgChildIds(id, false);//获取下级id列表 + alreadyIds.AddRange(childIds);//添加到已复制id + var childList = orgList.Where(c => childIds.Contains(c.Id)).ToList();//获取下级 + var sysOrgChildren = CopySysOrgChildren(childList, id, org.Id, input.ContainsPosition, + positionList);//赋值下级组织 + addOrgList.AddRange(sysOrgChildren.Item1);//添加到组织列表 + addPositionList.AddRange(sysOrgChildren.Item2);//添加到职位列表 + } + } + } + orgList.AddRange(addOrgList);//要添加的组织添加到组织列表 + //遍历机构重新赋值全称和父Id列表 + addOrgList.ForEach(it => + { + it.Names = it.Name; + if (it.ParentId != SimpleAdminConst.ZERO) + { + GetNames(orgList, it.ParentId, it.Name, out var names, + out var parentIdList); + it.Names = names; + it.ParentIdList = parentIdList; + } + }); + + //事务 + var result = await Tenant.UseTranAsync(async () => + { + await InsertRangeAsync(addOrgList);//插入组织 + if (addPositionList.Count > 0) + { + await Context.Insertable(addPositionList).ExecuteCommandAsync(); + } + }); + if (result.IsSuccess)//如果成功了 + { + await RefreshCache();//刷新缓存 + if (addPositionList.Count > 0) _simpleCacheService.Remove(SystemConst.CACHE_SYS_POSITION);//删除机构缓存 + } + else + { + _logger.LogError(result.ErrorException, result.ErrorMessage); + throw Oops.Oh($"复制失败"); + } + } + } + + #endregion 新增 + + #region 编辑 + + /// + public async Task Edit(SysOrgEditInput input, string name = SystemConst.SYS_ORG) + { + await CheckInput(input, name);//检查参数 + var sysOrg = input.Adapt();//实体转换 + if (await UpdateAsync(sysOrg))//更新数据 + { + //如果状态为禁用 + if (sysOrg.Status == CommonStatusConst.DISABLED) + { + var orgIds = await GetOrgChildIds(sysOrg.Id, true);//获取所有下级 + await _eventPublisher.PublishAsync(EventSubscriberConst.CLEAR_ORG_TOKEN, orgIds);//清除角色下用户缓存 + } + await RefreshCache();//刷新缓存 + } + } + + #endregion 编辑 + + #region 删除 + + /// + public async Task Delete(BaseIdListInput input, string name = SystemConst.SYS_ORG) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + var sysOrgList = await GetListAsync();//获取所有组织 + var sysDeleteOrgList = new List();//需要删除的组织ID集合 + ids.ForEach(it => + { + var children = GetSysOrgChildren(sysOrgList, it);//查找下级组织 + sysDeleteOrgList.AddRange(children.Select(it => it.Id).ToList()); + sysDeleteOrgList.Add(it); + }); + //如果组织下有用户则不能删除 + if (await Context.Queryable().AnyAsync(it => sysDeleteOrgList.Contains(it.OrgId))) + { + throw Oops.Bah($"请先删除{name}下的用户"); + } + //判断组织下是否有角色 + var hasRole = await Context.Queryable().Where(it => sysDeleteOrgList.Contains(it.OrgId.Value)).CountAsync() > 0; + if (hasRole) throw Oops.Bah($"请先删除{name}下的角色"); + // 判断组织下是否有职位 + var hasPosition = await Context.Queryable().Where(it => sysDeleteOrgList.Contains(it.OrgId)).CountAsync() > 0; + if (hasPosition) throw Oops.Bah($"请先删除{name}下的职位"); + //删除组织 + if (await DeleteByIdsAsync(sysDeleteOrgList.Cast().ToArray())) + await RefreshCache();//刷新缓存 + } + } + + #endregion 删除 + + #region 其他 + + /// + public async Task RefreshCache() + { + _simpleCacheService.Remove(SystemConst.CACHE_SYS_ORG);//从redis删除 + _simpleCacheService.Remove(SystemConst.CACHE_SYS_TENANT);//从redis删除 + _simpleCacheService.Remove(SystemConst.CACHE_SYS_USER);//清空redis所有的用户信息 + await GetListAsync();//刷新缓存 + } + + /// + public List ConstructOrgTrees(List orgList, long parentId = SimpleAdminConst.ZERO) + { + //找下级ID列表 + var orgInfos = orgList.Where(it => it.ParentId == parentId).OrderBy(it => it.SortCode).ToList(); + if (orgInfos.Count > 0)//如果数量大于0 + { + var data = new List(); + foreach (var item in orgInfos)//遍历组织 + { + item.Children = ConstructOrgTrees(orgList, item.Id);//添加子节点 + data.Add(item);//添加到列表 + } + return data;//返回结果 + } + return new List(); + } + + #endregion 其他 + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + /// + private async Task CheckInput(SysOrg sysOrg, string name) + { + //判断分类是否正确 + if (sysOrg.Category != CateGoryConst.ORG_COMPANY && sysOrg.Category != CateGoryConst.ORG_DEPT) + throw Oops.Bah($"{name}所属分类错误:{sysOrg.Category}"); + + var sysOrgList = await GetListAsync();//获取全部 + if (sysOrgList.Any(it => it.ParentId == sysOrg.ParentId && it.Name == sysOrg.Name && it.Id != sysOrg.Id))//判断同级是否有名称重复的 + throw Oops.Bah($"存在重复的同级{name}:{sysOrg.Name}"); + sysOrg.Names = sysOrg.Name;//全称默认自己 + if (sysOrg.ParentId != 0) + { + //获取父级,判断父级ID正不正确 + var parent = sysOrgList.Where(it => it.Id == sysOrg.ParentId).FirstOrDefault(); + if (parent != null) + { + if (parent.Id == sysOrg.Id) + throw Oops.Bah($"上级{name}不能选择自己"); + } + else + { + throw Oops.Bah($"上级{name}不存在:{sysOrg.ParentId}"); + } + GetNames(sysOrgList, sysOrg.ParentId, sysOrg.Name, out var names, + out var parentIdList); + sysOrg.Names = names; + sysOrg.ParentIdList = parentIdList; + } + //如果code没填 + if (string.IsNullOrEmpty(sysOrg.Code)) + { + sysOrg.Code = RandomHelper.CreateRandomString(10);//赋值Code + } + else + { + //判断是否有相同的Code + if (sysOrgList.Any(it => it.Code == sysOrg.Code && it.Id != sysOrg.Id)) + throw Oops.Bah($"存在重复的编码:{sysOrg.Code}"); + } + } + + /// + /// 根据组织Id列表获取所有父级组织 + /// + /// + /// + /// + public List GetParentListByIds(List allOrgList, List orgIds) + { + var sysOrgList = new HashSet();//结果列表 + //遍历组织ID + orgIds.ForEach(it => + { + //获取该组织ID的所有父级 + var parents = GetOrgParents(allOrgList, it); + sysOrgList.AddRange(parents);//添加到结果 + }); + return sysOrgList.ToList(); + } + + /// + /// 获取组织所有下级 + /// + /// + /// + /// + public List GetSysOrgChildren(List orgList, long parentId) + { + //找下级组织ID列表 + var orgInfos = orgList.Where(it => it.ParentId == parentId).ToList(); + if (orgInfos.Count > 0)//如果数量大于0 + { + var data = new List(); + foreach (var item in orgInfos)//遍历组织 + { + var children = GetSysOrgChildren(orgList, item.Id);//获取子节点 + data.AddRange(children);//添加子节点); + data.Add(item);//添加到列表 + } + return data;//返回结果 + } + return new List(); + } + + /// + /// 获取组织下级(懒加载) + /// + /// + /// + /// + public List GetSysOrgChildrenLazy(List orgList, long parentId) + { + //找下级组织ID列表 + var orgInfos = orgList.Where(it => it.ParentId == parentId).ToList(); + if (orgInfos.Count > 0)//如果数量大于0 + { + var data = new List(); + foreach (var item in orgInfos)//遍历组织 + { + var children = orgList.Where(it => it.ParentId == item.Id).ToList();//获取子节点 + //遍历子节点 + children.ForEach(it => + { + if (!orgList.Any(org => org.ParentId == it.Id)) + it.Leaf = true;//如果没有下级,则设置为叶子节点 + }); + data.AddRange(children);//添加子节点); + data.Add(item);//添加到列表 + } + return data;//返回结果 + } + return new List(); + } + + /// + /// 赋值组织的所有下级 + /// + /// 组织列表 + /// 父Id + /// 新父Id + /// + /// + /// + public Tuple, List> CopySysOrgChildren(List orgList, long parentId, long newParentId, + bool isCopyPosition, + List positions) + { + //找下级组织列表 + var orgInfos = orgList.Where(it => it.ParentId == parentId).ToList(); + if (orgInfos.Count > 0)//如果数量大于0 + { + var result = new Tuple, List>( + new List(), new List() + ); + foreach (var item in orgInfos)//遍历组织 + { + var oldId = item.Id;//获取旧Id + RedirectOrg(item);//实体重新赋值 + var children = CopySysOrgChildren(orgList, oldId, item.Id, isCopyPosition, + positions);//获取子节点 + item.ParentId = newParentId;//赋值新的父Id + result.Item1.AddRange(children.Item1);//添加下级组织; + if (isCopyPosition)//如果包含职位 + { + var positionList = positions.Where(it => it.OrgId == oldId).ToList();//获取职位列表 + positionList.ForEach(it => + { + it.OrgId = item.Id;//赋值新的机构ID + it.Id = CommonUtils.GetSingleId();//生成新的ID + it.Code = RandomHelper.CreateRandomString(10);//生成新的Code + }); + result.Item2.AddRange(positionList);//添加职位列表 + } + } + return result;//返回结果 + } + return new Tuple, List>( + new List(), new List() + ); + } + + /// + /// 重新生成组织实体 + /// + /// + private void RedirectOrg(SysOrg org) + { + //重新生成ID并赋值 + var newId = CommonUtils.GetSingleId(); + org.Id = newId; + org.Code = RandomHelper.CreateRandomString(10); + org.CreateTime = DateTime.Now; + org.CreateUser = UserManager.UserAccount; + org.CreateUserId = UserManager.UserId; + } + + /// + /// 获取全称 + /// + /// 组织列表 + /// 父Id + /// 组织名称 + /// 组织全称 + /// 组织父Id列表 + public void GetNames(List sysOrgList, long parentId, string orgName, + out string names, out List parentIdList) + { + names = ""; + //获取父级菜单 + var parents = GetOrgParents(sysOrgList, parentId); + foreach (var item in parents) + { + names += $"{item.Name}/"; + } + names += orgName;//赋值全称 + parentIdList = parents.Select(it => it.Id).ToList();//赋值父Id列表 + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Organization/Position/Dto/PositionInput.cs b/SimpleAdmin.System/Services/Organization/Position/Dto/PositionInput.cs new file mode 100644 index 0000000..0bbc402 --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/Position/Dto/PositionInput.cs @@ -0,0 +1,91 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 职位分页查询 +/// +public class PositionPageInput : BasePageInput +{ + /// + /// 组织ID + /// + public long OrgId { get; set; } + + /// + /// 职位列表 + /// + public List OrgIds { get; set; } + + /// + /// 分类 + /// + public string Category { get; set; } + + /// + /// 状态 + /// + public string Status { get; set; } +} + +/// +/// 职位新增参数 +/// +public class PositionAddInput : SysPosition +{ + /// + /// 组织ID + /// + [IdNotNull(ErrorMessage = "OrgId不能为空")] + public override long OrgId { get; set; } + + /// + /// 名称 + /// + [Required(ErrorMessage = "Name不能为空")] + public override string Name { get; set; } + + /// + /// 分类 + /// + [Required(ErrorMessage = "Category不能为空")] + public override string Category { get; set; } +} + +/// +/// 机构编辑参数 +/// +public class PositionEditInput : PositionAddInput +{ + /// + /// Id + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} + +/// +/// 机构选择器参数 +/// +public class PositionSelectorInput : UserSelectorInput +{ +} + +/// +/// 机构树形选择器参数 +/// +public class PositionTreeInput +{ + /// + /// 机构ID列表 + /// + public List OrgIds { get; set; } +} diff --git a/SimpleAdmin.System/Services/Organization/Position/Dto/PositionOutput.cs b/SimpleAdmin.System/Services/Organization/Position/Dto/PositionOutput.cs new file mode 100644 index 0000000..4daa993 --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/Position/Dto/PositionOutput.cs @@ -0,0 +1,58 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 组织树输出参数 +/// +public class PositionTreeOutput +{ + /// + /// 职位Id + /// + public long Id { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 是否是职位 + /// + public bool IsPosition { get; set; } + + /// + /// 子项 + /// + public List Children { get; set; } = new List(); +} + +/// +/// 组织选择器输出参数 +/// +public class PositionSelectorOutput +{ + /// + /// 组织Id或者职位Id + /// + public long Id { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 子项 + /// + public List Children { get; set; } = new List(); +} diff --git a/SimpleAdmin.System/Services/Organization/Position/ISysPositionService.cs b/SimpleAdmin.System/Services/Organization/Position/ISysPositionService.cs new file mode 100644 index 0000000..3c5d7e0 --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/Position/ISysPositionService.cs @@ -0,0 +1,114 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 职位服务 +/// +public interface ISysPositionService : ITransient +{ + #region 查询 + + /// + /// 获取职位列表 + /// + /// 职位列表 + Task> GetListAsync(); + + /// + /// 获取职位信息 + /// + /// 职位ID + /// 职位信息 + Task GetSysPositionById(long id); + + /// + /// 职位分页查询 + /// + /// 查询参数 + /// 分页列表 + Task> Page(PositionPageInput input); + + /// + /// 职位选择器 + /// + /// 查询参数 + /// + Task> Selector(PositionSelectorInput input); + + + + /// + /// 根据id集合获取职位集合 + /// + /// + /// + Task> GetPositionListByIdList(IdListInput input); + + /// + /// 职位树形结构 + /// + /// + /// + Task> Tree(PositionTreeInput input); + + /// + /// 职位详情 + /// + /// + /// + Task Detail(BaseIdInput input); + + #endregion + + #region 编辑 + + /// + /// 编辑职位 + /// + /// 编辑参数 + /// 名称 + /// + Task Edit(PositionEditInput input, string name = SystemConst.SYS_POS); + + + /// + /// 刷新缓存 + /// + /// + Task RefreshCache(); + + #endregion + + #region 新增 + + /// + /// 添加职位 + /// + /// 添加参数 + /// 名称 + /// + Task Add(PositionAddInput input, string name = SystemConst.SYS_POS); + + #endregion + + #region 删除 + + /// + /// 删除职位 + /// + /// id列表 + /// 名称 + /// + Task Delete(BaseIdListInput input, string name = SystemConst.SYS_POS); + + #endregion +} diff --git a/SimpleAdmin.System/Services/Organization/Position/SysPositionService.cs b/SimpleAdmin.System/Services/Organization/Position/SysPositionService.cs new file mode 100644 index 0000000..66cc15d --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/Position/SysPositionService.cs @@ -0,0 +1,307 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// +/// +public class SysPositionService : DbRepository, ISysPositionService +{ + private readonly ISimpleCacheService _simpleCacheService; + private readonly ISysOrgService _sysOrgService; + private readonly IDictService _dictService; + + public SysPositionService(ISimpleCacheService simpleCacheService, ISysOrgService sysOrgService, IDictService dictService) + { + _simpleCacheService = simpleCacheService; + _sysOrgService = sysOrgService; + _dictService = dictService; + } + + #region 查询 + + /// + /// 获取全部 + /// + /// + public override async Task> GetListAsync() + { + //先从Redis拿 + var sysPositions = _simpleCacheService.Get>(SystemConst.CACHE_SYS_POSITION); + if (sysPositions == null) + { + //redis没有就去数据库拿 + sysPositions = await base.GetListAsync(); + if (sysPositions.Count > 0) + { + //插入Redis + _simpleCacheService.Set(SystemConst.CACHE_SYS_POSITION, sysPositions); + } + } + return sysPositions; + } + + /// + public async Task> GetPositionListByIdList(IdListInput input) + { + var positions = await GetListAsync(); + var positionList = positions.Where(it => input.IdList.Contains(it.Id)).ToList();// 获取指定ID的岗位列表 + return positionList; + } + + /// + public async Task> Selector(PositionSelectorInput input) + { + var sysOrgList = await _sysOrgService.GetListAsync(false);//获取所有组织 + var sysPositions = await GetListAsync();//获取所有职位 + if (input.OrgIds != null)//根据数据范围查 + { + sysOrgList = sysOrgList.Where(it => input.OrgIds.Contains(it.Id)).ToList();//在指定组织列表查询 + sysPositions = sysPositions.Where(it => input.OrgIds.Contains(it.OrgId)).ToList();//在指定职位列表查询 + } + var result = await ConstructPositionSelector(sysOrgList, sysPositions);//构造树 + return result; + } + + + + /// + public async Task GetSysPositionById(long id) + { + var sysPositions = await GetListAsync(); + var result = sysPositions.Where(it => it.Id == id).FirstOrDefault(); + return result; + } + + /// + public async Task> Page(PositionPageInput input) + { + var orgIds = await _sysOrgService.GetOrgChildIds(input.OrgId);//获取下级组织 + var query = Context.Queryable().WhereIF(input.OrgId > 0, it => orgIds.Contains(it.OrgId))//根据组织ID查询 + .WhereIF(input.OrgIds != null, it => input.OrgIds.Contains(it.OrgId))//在指定组织列表查询 + .WhereIF(!string.IsNullOrEmpty(input.Category), it => it.Category == input.Category)//根据分类 + .WhereIF(!string.IsNullOrEmpty(input.Status), it => it.Status == input.Status)//根据状态 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Name.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}") + .OrderBy(it => it.SortCode)//排序 + .OrderBy(it => it.CreateTime);//排序 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + + + /// + public async Task> Tree(PositionTreeInput input) + { + var result = new List();//返回结果 + var sysOrgList = await _sysOrgService.GetListAsync(false);//获取所有组织 + var sysPositions = await GetListAsync();//获取所有职位 + if (input.OrgIds != null)//根据数据范围查 + { + sysOrgList = sysOrgList.Where(it => input.OrgIds.Contains(it.Id)).ToList();//在指定组织列表查询 + sysPositions = sysPositions.Where(it => input.OrgIds.Contains(it.OrgId)).ToList();//在指定职位列表查询 + } + var posCategory = await _dictService.GetChildrenByDictValue(SysDictConst.POSITION_CATEGORY);//获取职位分类 + var topOrgList = sysOrgList.Where(it => it.ParentId == 0).ToList();//获取顶级组织 + //遍历顶级组织 + foreach (var org in topOrgList) + { + var childIds = await _sysOrgService.GetOrgChildIds(org.Id, true, sysOrgList);//获取组织下的所有子级ID + var orgPositions = sysPositions.Where(it => childIds.Contains(it.OrgId)).ToList();//获取组织下的职位 + if (orgPositions.Count == 0) continue; + var positionTreeOutput = new PositionTreeOutput + { + Id = org.Id, + Name = org.Name, + IsPosition = false + };//实例化组织树 + //获取组织下的职位职位分类 + foreach (var category in posCategory) + { + var id = CommonUtils.GetSingleId();//生成唯一ID临时用,因为前端需要ID + var categoryTreeOutput = new PositionTreeOutput + { + Id = id, + Name = category.DictLabel, + IsPosition = false + };//实例化职位分类树 + var positions = orgPositions.Where(it => it.Category == category.DictValue).ToList();//获取职位分类下的职位 + //遍历职位,实例化职位树 + positions.ForEach(it => + { + categoryTreeOutput.Children.Add(new PositionTreeOutput() + { + Id = it.Id, + Name = it.Name, + IsPosition = true + });//添加职位 + }); + positionTreeOutput.Children.Add(categoryTreeOutput); + } + result.Add(positionTreeOutput); + } + + return result; + } + + /// + public async Task Detail(BaseIdInput input) + { + return await GetSysPositionById(input.Id); + } + + #endregion + + #region 编辑 + + /// + public async Task Edit(PositionEditInput input, string name = SystemConst.SYS_POS) + { + await CheckInput(input, name);//检查参数 + var sysPosition = input.Adapt();//实体转换 + if (await UpdateAsync(sysPosition))//更新数据 + await RefreshCache();//刷新缓存 + } + + + + /// + public async Task RefreshCache() + { + _simpleCacheService.Remove(SystemConst.CACHE_SYS_POSITION);//删除缓存 + await GetListAsync();//重新写入缓存 + } + + #endregion + + #region 新增 + + /// + public async Task Add(PositionAddInput input, string name = SystemConst.SYS_POS) + { + await CheckInput(input, name);//检查参数 + var sysPosition = input.Adapt();//实体转换 + if (await InsertAsync(sysPosition))//插入数据 + await RefreshCache();//刷新缓存 + } + + #endregion + + #region 删除 + + /// + public async Task Delete(BaseIdListInput input, string name = SystemConst.SYS_POS) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + //如果组织下有用户则不能删除 + if (await Context.Queryable().AnyAsync(it => ids.Contains(it.PositionId))) + { + throw Oops.Bah($"请先删除{name}下的用户"); + } + //删除职位 + if (await DeleteByIdsAsync(ids.Cast().ToArray())) + await RefreshCache();//刷新缓存 + } + } + + #endregion + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + /// 名称 + private async Task CheckInput(SysPosition sysPosition, string name) + { + //所有分类放一个列表 + var posCategoryList = new List + { + CateGoryConst.POSITION_HIGH, CateGoryConst.POSITION_LOW, CateGoryConst.POSITION_MIDDLE + }; + if (!posCategoryList.Contains(sysPosition.Category)) + throw Oops.Bah($"{name}所属分类错误:{sysPosition.Category}"); + var sysPositions = await GetListAsync();//获取全部 + if (sysPositions.Any(it => it.OrgId == sysPosition.OrgId && it.Name == sysPosition.Name && it.Id != sysPosition.Id))//判断同级是否有名称重复的 + throw Oops.Bah($"存在重复的{name}:{sysPosition.Name}"); + if (sysPosition.Id > 0)//如果ID大于0表示编辑 + { + var position = sysPositions.Where(it => it.Id == sysPosition.Id).FirstOrDefault();//获取当前职位 + if (position == null) + throw Oops.Bah($"{name}不存在"); + } + //如果code没填 + if (string.IsNullOrEmpty(sysPosition.Code)) + { + sysPosition.Code = RandomHelper.CreateRandomString(10);//赋值Code + } + else + { + //判断是否有相同的Code + if (sysPositions.Any(it => it.Code == sysPosition.Code && it.Id != sysPosition.Id)) + throw Oops.Bah($"存在重复的编码:{sysPosition.Code}"); + } + } + + /// + /// 构建职位选择器 + /// + /// 组织列表 + /// 职位列表 + /// 父Id + /// + public async Task> ConstructPositionSelector(List orgList, List sysPositions, + long parentId = SimpleAdminConst.ZERO) + { + //找下级组织列表 + var orgInfos = orgList.Where(it => it.ParentId == parentId).OrderBy(it => it.SortCode).ToList(); + var data = new List(); + if (orgInfos.Count > 0)//如果数量大于0 + { + foreach (var item in orgInfos)//遍历组织 + { + var childIds = await _sysOrgService.GetOrgChildIds(item.Id, true, orgList);//获取组织下的所有子级ID + var orgPositions = sysPositions.Where(it => childIds.Contains(it.OrgId)).ToList();//获取组织下的职位 + if (orgPositions.Count > 0)//如果组织和组织下级有职位 + { + var positionSelectorOutput = new PositionSelectorOutput + { + Id = item.Id, + Name = item.Name, + Children = await ConstructPositionSelector(orgList, sysPositions, item.Id)//递归 + };//实例化职位树 + var positions = orgPositions.Where(it => it.OrgId == item.Id).ToList();//获取组织下的职位 + if (positions.Count > 0)//如果数量大于0 + { + foreach (var position in positions) + { + positionSelectorOutput.Children.Add(new PositionSelectorOutput + { + Id = position.Id, + Name = position.Name + });//添加职位 + } + } + data.Add(positionSelectorOutput);//添加到列表 + } + } + return data;//返回结果 + } + return new List(); + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Organization/User/Dto/UserInput.cs b/SimpleAdmin.System/Services/Organization/User/Dto/UserInput.cs new file mode 100644 index 0000000..e933776 --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/User/Dto/UserInput.cs @@ -0,0 +1,330 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 用户选择器参数 +/// +public class UserSelectorInput : BasePageInput +{ + /// + /// 组织ID + /// + public long OrgId { get; set; } + + /// + /// 机构ID列表 + /// + public List OrgIds { get; set; } + + /// + /// 机构ID + /// + public long PositionId { get; set; } + + /// + /// 角色ID + /// + public long RoleId { get; set; } + + /// + /// 关键字 + /// + public string Account { get; set; } +} + +/// +/// 用户分页查询参数 +/// +public class UserPageInput : BasePageInput +{ + /// + /// 所属组织 + /// + public long OrgId { get; set; } + + /// + /// 动态查询条件 + /// + public Expressionable Expression { get; set; } + + /// + /// 用户状态 + /// + + public string Status { get; set; } +} + +/// +/// 添加用户参数 +/// +public class UserAddInput : SysUser +{ + /// + /// 账号 + /// + [Required(ErrorMessage = "Account不能为空")] + public override string Account { get; set; } + + /// + /// 姓名 + /// + [Required(ErrorMessage = "Name不能为空")] + public override string Name { get; set; } + + /// + /// 组织id + /// + [IdNotNull(ErrorMessage = "OrgId不能为空")] + public override long OrgId { get; set; } + + /// + /// 职位id + /// + [IdNotNull(ErrorMessage = "PositionId不能为空")] + public override long PositionId { get; set; } +} + +/// +/// 编辑用户参数 +/// +public class UserEditInput : UserAddInput +{ + /// + /// Id + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public override long Id { get; set; } +} + +/// +/// 用户授权角色参数 +/// +public class UserGrantRoleInput +{ + /// + /// Id + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public long Id { get; set; } + + /// + /// 授权权限信息 + /// + [Required(ErrorMessage = "RoleIdList不能为空")] + public List RoleIdList { get; set; } +} + +public class UserGrantResourceInput : GrantResourceInput +{ + /// + /// 默认数据权限 + /// + [Required(ErrorMessage = "DefaultDataScope不能为空")] + public DefaultDataScope DefaultDataScope { get; set; } +} + +/// +/// 用户导入 +/// +public class SysUserImportInput : ImportTemplateInput +{ + /// + /// 账号 + /// + [ImporterHeader(Name = "账号")] + [Required(ErrorMessage = "账号不能为空")] + public string Account { get; set; } + + /// + /// 姓名 + /// + [ImporterHeader(Name = "姓名")] + [Required(ErrorMessage = "姓名不能为空")] + public virtual string Name { get; set; } + + /// + /// 性别 + /// + [ImporterHeader(Name = "性别")] + [Required(ErrorMessage = "性别不能为空")] + public string Gender { get; set; } + + /// + /// 昵称 + /// + [ImporterHeader(Name = "昵称")] + public string Nickname { get; set; } + + /// + /// 手机 + /// 这里使用了SM4自动加密解密 + /// + [ImporterHeader(Name = "手机号")] + public string Phone { get; set; } + + /// + /// 邮箱 + /// + [ImporterHeader(Name = "邮箱")] + [EmailAddress(ErrorMessage = "邮箱格式错误")] + public string Email { get; set; } + + /// + /// 所属机构 + /// + [ImporterHeader(Name = "所属机构(子机构用/隔开)")] + [Required(ErrorMessage = "所属部门不能为空")] + [AntTable(Width = 200)] + public string OrgName { get; set; } + + /// + /// 职位 + /// + [ImporterHeader(Name = "职位")] + [Required(ErrorMessage = "职位不能为空")] + public string PositionName { get; set; } + + /// + /// 出生日期 + /// + [ImporterHeader(Name = "出生日期")] + [AntTable(IsDate = true)] + public DateTime? Birthday { get; set; } + + /// + /// 民族 + /// + [ImporterHeader(Name = "民族")] + public string Nation { get; set; } + + /// + /// 籍贯 + /// + [ImporterHeader(Name = "籍贯")] + public string NativePlace { get; set; } + + /// + /// 家庭住址 + /// + [ImporterHeader(Name = "家庭住址")] + public string HomeAddress { get; set; } + + /// + /// 通信地址 + /// + [ImporterHeader(Name = "通信地址")] + public string MailingAddress { get; set; } + + /// + /// 证件类型 + /// + [ImporterHeader(Name = "证件类型")] + public string IdCardType { get; set; } + + /// + /// 证件号码 + /// + [ImporterHeader(Name = "证件号码")] + public string IdCardNumber { get; set; } + + /// + /// 文化程度 + /// + [ImporterHeader(Name = "文化程度")] + public string CultureLevel { get; set; } + + /// + /// 政治面貌 + /// + [ImporterHeader(Name = "政治面貌")] + public string PoliticalOutlook { get; set; } + + /// + /// 毕业院校 + /// + [ImporterHeader(Name = "毕业院校")] + public string College { get; set; } + + /// + /// 学历 + /// + [ImporterHeader(Name = "学历")] + public string Education { get; set; } + + /// + /// 学制 + /// + [ImporterHeader(Name = "学制")] + public string EduLength { get; set; } + + /// + /// 学位 + /// + [ImporterHeader(Name = "学位")] + public string Degree { get; set; } + + /// + /// 家庭电话 + /// + [ImporterHeader(Name = "家庭电话")] + public string HomeTel { get; set; } + + /// + /// 办公电话 + /// + [ImporterHeader(Name = "办公电话")] + public string OfficeTel { get; set; } + + /// + /// 紧急联系人 + /// + [ImporterHeader(Name = "紧急联系人")] + public string EmergencyContact { get; set; } + + /// + /// 紧急联系人电话 + /// + [ImporterHeader(Name = "紧急联系人电话")] + [Phone(ErrorMessage = "电话号码格式错误")] + public string EmergencyPhone { get; set; } + + /// + /// 紧急联系人地址 + /// + [ImporterHeader(Name = "紧急联系人地址")] + public string EmergencyAddress { get; set; } + + /// + /// 员工编号 + /// + [ImporterHeader(Name = "员工编号")] + public string EmpNo { get; set; } + + /// + /// 入职日期 + /// + [ImporterHeader(Name = "入职日期")] + [AntTable(IsDate = true)] + public DateTime? EntryDate { get; set; } + + /// + /// 部门Id + /// + [ImporterHeader(IsIgnore = true)] + public long OrgId { get; set; } + + /// + /// 职位Id + /// + [ImporterHeader(IsIgnore = true)] + public long PositionId { get; set; } +} diff --git a/SimpleAdmin.System/Services/Organization/User/Dto/UserOutPut.cs b/SimpleAdmin.System/Services/Organization/User/Dto/UserOutPut.cs new file mode 100644 index 0000000..52a81c6 --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/User/Dto/UserOutPut.cs @@ -0,0 +1,254 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 选择用户输出参数 +/// +public class UserSelectorOutPut +{ + /// + /// Id + /// + public long Id { get; set; } + + /// + /// 组织ID + /// + public long OrgId { get; set; } + + /// + /// 账号 + /// + public string Account { get; set; } + + /// + /// 姓名 + /// + public string Name { get; set; } + + /// + /// 性别 + /// + public string Gender { get; set; } +} + +/// +/// 用户信息输出 +/// +public class UserInfoOutPut : SysUser +{ +} + +/// +/// 用户信息 +/// +[ExcelExporter(Name = "用户信息", TableStyle = TableStyles.Light10, AutoFitAllColumn = true)] +public class SysUserExportOutput +{ + /// + /// 账号 + /// + [ExporterHeader(DisplayName = "账号")] + public virtual string Account { get; set; } + + /// + /// 姓名 + /// + [ExporterHeader(DisplayName = "姓名")] + public virtual string Name { get; set; } + + /// + /// 昵称 + /// + [ExporterHeader(DisplayName = "昵称")] + public string Nickname { get; set; } + + /// + /// 性别 + /// + [ExporterHeader(DisplayName = "性别")] + public string Gender { get; set; } + + /// + /// 手机 + /// 这里使用了SM4自动加密解密 + /// + [ExporterHeader(DisplayName = "手机号")] + public string Phone { get; set; } + + /// + /// 邮箱 + /// + [ExporterHeader(DisplayName = "邮箱")] + public string Email { get; set; } + + /// + /// 所属机构 + /// + [ExporterHeader(DisplayName = "所属机构(子机构用/隔开)")] + public string OrgNames { get; set; } + + /// + /// 职位 + /// + [ExporterHeader(DisplayName = "职位")] + public string PositionName { get; set; } + + /// + /// 出生日期 + /// + [ExporterHeader(DisplayName = "出生日期")] + public string Birthday { get; set; } + + /// + /// 民族 + /// + [ExporterHeader(DisplayName = "民族")] + public string Nation { get; set; } + + /// + /// 籍贯 + /// + [ExporterHeader(DisplayName = "籍贯")] + public string NativePlace { get; set; } + + /// + /// 家庭住址 + /// + [ExporterHeader(DisplayName = "家庭住址")] + public string HomeAddress { get; set; } + + /// + /// 通信地址 + /// + [ExporterHeader(DisplayName = "通信地址")] + public string MailingAddress { get; set; } + + /// + /// 证件类型 + /// + [ExporterHeader(DisplayName = "证件类型")] + public string IdCardType { get; set; } + + /// + /// 证件号码 + /// + [ExporterHeader(DisplayName = "证件号码")] + public string IdCardNumber { get; set; } + + /// + /// 文化程度 + /// + [ExporterHeader(DisplayName = "文化程度")] + public string CultureLevel { get; set; } + + /// + /// 政治面貌 + /// + [ExporterHeader(DisplayName = "政治面貌")] + public string PoliticalOutlook { get; set; } + + /// + /// 毕业院校 + /// + [ExporterHeader(DisplayName = "毕业院校")] + public string College { get; set; } + + /// + /// 学历 + /// + [ExporterHeader(DisplayName = "学历")] + public string Education { get; set; } + + /// + /// 学制 + /// + [ExporterHeader(DisplayName = "学制")] + public string EduLength { get; set; } + + /// + /// 学位 + /// + [ExporterHeader(DisplayName = "学位")] + public string Degree { get; set; } + + /// + /// 家庭电话 + /// + [ExporterHeader(DisplayName = "家庭电话")] + public string HomeTel { get; set; } + + /// + /// 办公电话 + /// + [ExporterHeader(DisplayName = "办公电话")] + public string OfficeTel { get; set; } + + /// + /// 紧急联系人 + /// + [ExporterHeader(DisplayName = "紧急联系人")] + public string EmergencyContact { get; set; } + + /// + /// 紧急联系人电话 + /// + [ExporterHeader(DisplayName = "紧急联系人电话")] + public string EmergencyPhone { get; set; } + + /// + /// 紧急联系人地址 + /// + [ExporterHeader(DisplayName = "紧急联系人地址")] + public string EmergencyAddress { get; set; } + + /// + /// 员工编号 + /// + [ExporterHeader(DisplayName = "员工编号")] + public string EmpNo { get; set; } + + /// + /// 入职日期 + /// + [ExporterHeader(DisplayName = "入职日期")] + public string EntryDate { get; set; } + + /// + /// 职级 + /// + [ExporterHeader(DisplayName = "职级")] + public string PositionLevel { get; set; } +} + +public class RoleSelectorOutPut +{ + /// + /// Id + /// + public long Id { get; set; } + + /// + /// 组织ID + /// + public long OrgId { get; set; } + + /// + /// 角色名称 + /// + public string Name { get; set; } + + /// + /// 角色编码 + /// + public string Code { get; set; } +} diff --git a/SimpleAdmin.System/Services/Organization/User/ISysUserService.cs b/SimpleAdmin.System/Services/Organization/User/ISysUserService.cs new file mode 100644 index 0000000..43ed838 --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/User/ISysUserService.cs @@ -0,0 +1,324 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 用户服务 +/// +public interface ISysUserService : ITransient +{ + #region 查询 + + /// + /// 根据用户ID获取按钮ID集合 + /// + /// + /// + Task> GetButtonCodeList(long userId); + + /// + /// 根据账号获取用户信息 + /// + /// 用户名 + /// 租户ID + /// 用户信息 + Task GetUserByAccount(string account, long? tenantId = null); + + /// + /// 根据用户ID和机构ID获取角色权限 + /// + /// + /// + /// + Task> GetPermissionListByUserId(long userId, long orgId); + + /// + /// 根据手机号获取用户账号 + /// + /// 手机号 + /// 租户ID + /// 用户账号名称 + Task GetIdByPhone(string phone, long? tenantId = null); + + /// + /// 用户选择器 + /// + /// 查询参数 + /// + Task> Selector(UserSelectorInput input); + + /// + /// 用户分页查询 + /// + /// 查询参数 + /// 用户分页列表 + Task> Page(UserPageInput input); + + /// + /// 用户列表 + /// + /// 查询 + /// + Task> List(UserPageInput input); + + /// + /// 根据用户Id获取用户信息 + /// + /// 用户ID + /// 用户信息 + Task GetUserById(long userId); + + /// + /// 根据用户Id获取用户信息 + /// + /// 用户ID + /// 转换的实体 + /// + Task GetUserById(long userId); + + /// + /// 根据用户账号获取用户ID + /// + /// 用户账号 + /// 租户id + /// + Task GetIdByAccount(string account, long? tenantId = null); + + /// + /// 根据用户手机获取用户信息 + /// + /// 手机号 + /// 租户Id + /// 用户信息 + Task GetUserByPhone(string phone, long? tenantId = null); + + /// + /// 获取用户拥有角色 + /// + /// 用户ID + /// + Task> OwnRole(BaseIdInput input); + + /// + /// 获取用户拥有的资源 + /// + /// 用户id + /// 资源列表 + Task OwnResource(BaseIdInput input); + + /// + /// 获取用户拥有的权限 + /// + /// 用户id + /// 权限列表 + Task OwnPermission(BaseIdInput input); + + /// + /// 用户权限树选择 + /// + /// 用户id + /// 权限列表 + Task> UserPermissionTreeSelector(BaseIdInput input); + + /// + /// 根据id集合获取用户集合 + /// + /// Id集合 + /// + Task> GetUserListByIdList(IdListInput input); + + /// + /// 用户详情 + /// + /// + /// + Task Detail(BaseIdInput input); + + /// + /// 获取用户头像 + /// + /// 用户id + /// base64头像 + Task GetUserAvatar(long userId); + + #endregion 查询 + + #region 数据范围相关 + + /// + /// 获取当前API用户的数据范围 + /// null:代表拥有全部数据权限 + /// [xx,xx]:代表拥有部分机构的权限 + /// []:代表仅自己权限 + /// + /// 机构列表 + Task?> GetLoginUserApiDataScope(); + + /// + /// 检查用户是否有机构的数据权限 + /// + /// 机构id + /// 创建者id + /// 错误提示:不为空则直接抛出异常 + /// 是否有权限 + Task CheckApiDataScope(long? orgId, long? createUerId, string errMsg = ""); + + /// + /// 检查用户是否有机构的数据权限 + /// + /// 机构id列表 + /// 创建者id列表 + /// 错误提示:不为空则直接抛出异常 + /// + Task CheckApiDataScope(List orgIds, List createUerIds, string errMsg = ""); + + #endregion + + #region 新增 + + /// + /// 添加用户 + /// + /// 添加参数 + /// + Task Add(UserAddInput input); + + #endregion 新增 + + #region 编辑 + + /// + /// 编辑 + /// + /// 编辑参数 + /// + Task Edit(UserEditInput input); + + /// + /// 启用用户 + /// + /// 用户Id + /// + Task EnableUser(BaseIdInput input); + + /// + /// 禁用用户 + /// + /// 用户Id + /// + Task DisableUser(BaseIdInput input); + + /// + /// 重置密码 + /// + /// 用户Id + /// + Task ResetPassword(BaseIdInput input); + + /// + /// 给用户授权角色 + /// + /// 授权参数 + /// + Task GrantRole(UserGrantRoleInput input); + + /// + /// 给用户授权资源 + /// + /// 授权参数 + /// + Task GrantResource(UserGrantResourceInput input); + + /// + /// 给用户授权权限 + /// + /// + /// + Task GrantPermission(GrantPermissionInput input); + + /// + /// 设置用户默认值 + /// + /// + /// + Task SetUserDefault(List sysUsers); + + /// + /// 批量编辑 + /// + /// 批量编辑信息 + /// + Task Edits(BatchEditInput input); + + #endregion 编辑 + + #region 删除 + + /// + /// 删除用户 + /// + /// Id列表 + /// + Task Delete(BaseIdListInput input); + + /// + /// 从redis中删除用户信息 + /// + /// 用户ID列表 + void DeleteUserFromRedis(List ids); + + /// + /// 从redis中删除用户信息 + /// + /// 用户ID + void DeleteUserFromRedis(long userId); + + #endregion 删除 + + #region 导入导出 + + /// + /// 导出用户 + /// + /// + /// + Task Export(UserPageInput input); + + /// + /// 导入模板下载 + /// + /// 模板 + Task Template(); + + /// + /// 导入预览 + /// + /// 预览参数 + /// 预览结果 + Task> Preview(ImportPreviewInput input); + + /// + /// 用户导入 + /// + /// + /// + Task> Import(ImportResultInput input); + + /// + /// 检查导入数据 + /// + /// 数据 + /// 是否初始化错误 + /// + Task> CheckImport(List data, bool clearError = false) where T : SysUserImportInput; + + #endregion 导入导出 +} diff --git a/SimpleAdmin.System/Services/Organization/User/SysUserService.cs b/SimpleAdmin.System/Services/Organization/User/SysUserService.cs new file mode 100644 index 0000000..c5d6b5a --- /dev/null +++ b/SimpleAdmin.System/Services/Organization/User/SysUserService.cs @@ -0,0 +1,1165 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using SimpleAdmin.Core.Extension; + +namespace SimpleAdmin.System; + +/// +/// +/// +public class SysUserService : DbRepository, ISysUserService +{ + private readonly ILogger _logger; + private readonly ISimpleCacheService _simpleCacheService; + private readonly IRelationService _relationService; + private readonly IResourceService _resourceService; + private readonly ISysOrgService _sysOrgService; + private readonly ISysRoleService _sysRoleService; + private readonly IImportExportService _importExportService; + private readonly ISysPositionService _sysPositionService; + private readonly IDictService _dictService; + private readonly IConfigService _configService; + private readonly IBatchEditService _batchEditService; + + public SysUserService(ILogger logger, ISimpleCacheService simpleCacheService, IRelationService relationService, + IResourceService resourceService, ISysOrgService orgService, ISysRoleService sysRoleService, + IImportExportService importExportService, ISysPositionService sysPositionService, IDictService dictService, + IConfigService configService, IBatchEditService updateBatchService) + { + _logger = logger; + _simpleCacheService = simpleCacheService; + _relationService = relationService; + _resourceService = resourceService; + _sysOrgService = orgService; + _sysRoleService = sysRoleService; + _importExportService = importExportService; + _sysPositionService = sysPositionService; + _dictService = dictService; + _configService = configService; + _batchEditService = updateBatchService; + } + + #region 查询 + + /// + public async Task GetUserAvatar(long userId) + { + //先从缓存拿 + var avatar = _simpleCacheService.HashGetOne(SystemConst.CACHE_SYS_USER_AVATAR, userId.ToString()); + if (string.IsNullOrEmpty(avatar)) + { + //单查获取用户头像 + avatar = await GetFirstAsync(it => it.Id == userId, it => it.Avatar); + if (!string.IsNullOrEmpty(avatar)) + { + //插入缓存 + _simpleCacheService.HashAdd(SystemConst.CACHE_SYS_USER_AVATAR, userId.ToString(), avatar); + } + } + return avatar; + } + + /// + public async Task GetUserByAccount(string account, long? tenantId = null) + { + var userId = await GetIdByAccount(account, tenantId);//获取用户ID + if (userId != SimpleAdminConst.ZERO) + { + var sysUser = await GetUserById(userId);//获取用户信息 + if (sysUser.Account == account)//这里做了比较用来限制大小写 + return sysUser; + return null; + } + return null; + } + + /// + public async Task GetUserByPhone(string phone, long? tenantId = null) + { + var userId = await GetIdByPhone(phone, tenantId);//获取用户ID + if (userId > 0) + { + return await GetUserById(userId);//获取用户信息 + } + return null; + } + + /// + public async Task GetIdByPhone(string phone, long? tenantId = null) + { + var orgIds = new List(); + var key = SystemConst.CACHE_SYS_USER_PHONE; + if (tenantId != null) + { + key += $":{tenantId}"; + orgIds = await _sysOrgService.GetOrgChildIds(tenantId.Value);//获取下级机构 + } + //先从缓存拿 + var userId = _simpleCacheService.HashGetOne(key, phone); + if (userId == 0) + { + var sm4Phone = CryptogramUtil.Sm4Encrypt(phone);//SM4加密一下 + //单查获取用户手机号对应的账号 + userId = await Context.Queryable() + .Where(it => it.Phone == sm4Phone) + .WhereIF(orgIds.Count > 0, it => orgIds.Contains(it.OrgId)) + .Select(it => it.Id) + .FirstAsync(); + if (userId > 0) + { + //插入缓存 + _simpleCacheService.HashAdd(key, phone, userId); + } + } + return userId; + } + + /// + public async Task GetUserById(long userId) + { + //先从缓存拿 + //var sysUser = _simpleCacheService.HashGetOne(SystemConst.CACHE_SYS_USER, userId.ToString()); + //if (sysUser == null) + //{ + // sysUser = await GetUserFromDb(userId);//从数据库拿用户信息 + //} + var sysUser = await GetUserFromDb(userId);//从数据库拿用户信息 + return sysUser; + } + + /// + public async Task GetUserById(long userId) + { + var user = await GetUserById(userId); + return user.Adapt(); + } + + /// + public async Task GetIdByAccount(string account, long? tenantId = null) + { + var orgIds = new List(); + var key = SystemConst.CACHE_SYS_USER_ACCOUNT; + if (tenantId != null) + { + key += $":{tenantId}"; + orgIds = await _sysOrgService.GetOrgChildIds(tenantId.Value);//获取下级机构 + } + //先从缓存拿 + var userId = _simpleCacheService.HashGetOne(key, account); + if (userId == 0) + { + //单查获取用户账号对应ID + userId = await Context.Queryable() + .Where(it => it.Account == account) + .WhereIF(orgIds.Count > 0, it => orgIds.Contains(it.OrgId)) + .Select(it => it.Id) + .FirstAsync(); + if (userId != 0) + { + //插入缓存 + _simpleCacheService.HashAdd(key, account, userId); + } + } + return userId; + } + + /// + public async Task> GetButtonCodeList(long userId) + { + var buttonCodeList = new List();//按钮ID集合 + //获取用户资源集合 + var resourceList = await _relationService.GetRelationListByObjectIdAndCategory(userId, CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE); + var buttonIdList = new List();//按钮ID集合 + if (resourceList.Count == 0)//如果有表示用户单独授权了不走用户角色 + { + //获取用户角色关系集合 + var roleList = await _relationService.GetRelationListByObjectIdAndCategory(userId, CateGoryConst.RELATION_SYS_USER_HAS_ROLE); + var roleIdList = roleList.Select(x => x.TargetId.ToLong()).ToList();//角色ID列表 + if (roleIdList.Count > 0)//如果该用户有角色 + { + resourceList = await _relationService.GetRelationListByObjectIdListAndCategory(roleIdList, + CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE);//获取资源集合 + } + } + resourceList.ForEach(it => + { + if (!string.IsNullOrEmpty(it.ExtJson)) + buttonIdList.AddRange(it.ExtJson.ToJsonEntity().ButtonInfo);//如果有按钮权限,将按钮ID放到buttonIdList + }); + if (buttonIdList.Count > 0) + { + buttonCodeList = await _resourceService.GetCodeByIds(buttonIdList, CateGoryConst.RESOURCE_BUTTON); + } + return buttonCodeList; + } + + /// + public async Task> GetPermissionListByUserId(long userId, long orgId) + { + var permissions = new List();//权限集合 + var sysRelations = + await _relationService.GetRelationListByObjectIdAndCategory(userId, CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION);//根据用户ID获取用户权限 + if (sysRelations.Count == 0)//如果有表示用户单独授权了不走用户角色 + { + var roleIdList = + await _relationService.GetRelationListByObjectIdAndCategory(userId, CateGoryConst.RELATION_SYS_USER_HAS_ROLE);//根据用户ID获取角色ID + if (roleIdList.Count > 0)//如果角色ID不为空 + { + //获取角色权限信息 + sysRelations = await _relationService.GetRelationListByObjectIdListAndCategory(roleIdList.Select(it => it.TargetId.ToLong()).ToList(), + CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION); + } + } + var relationGroup = sysRelations.GroupBy(it => it.TargetId).ToList();//根据目标ID,也就是接口名分组,因为存在一个用户多个角色 + //遍历分组 + foreach (var it in relationGroup) + { + var scopeSet = new HashSet();//定义不可重复列表 + var relationList = it.ToList();//关系列表 + var scopeCategory = CateGoryConst.SCOPE_SELF;//数据权限分类,默认为仅自己 + //获取角色权限信息列表 + var rolePermissions = relationList.Select(it => it.ExtJson.ToJsonEntity()).ToList(); + if (rolePermissions.Any(role => role.ScopeCategory == CateGoryConst.SCOPE_ALL))//如果有全部 + scopeCategory = CateGoryConst.SCOPE_ALL;//标记为全部 + else if (rolePermissions.Any(role => role.ScopeCategory == CateGoryConst.SCOPE_ORG_CHILD))//如果有机构及以下机构 + scopeCategory = CateGoryConst.SCOPE_ORG_CHILD;//标记为机构及以下机构 + else if (rolePermissions.Any(role => role.ScopeCategory == CateGoryConst.SCOPE_ORG))//如果有仅自己机构 + scopeCategory = CateGoryConst.SCOPE_ORG;//标记为仅自己机构 + else if (rolePermissions.Any(role => role.ScopeCategory == CateGoryConst.SCOPE_ORG_DEFINE))//如果有自定义机构 + { + scopeCategory = CateGoryConst.SCOPE_ORG_DEFINE;//标记为仅自己 + rolePermissions.ForEach(s => + { + scopeSet.AddRange(s.ScopeDefineOrgIdList);//添加自定义范围的机构ID + }); + } + var dataScopes = scopeSet.ToList();//获取范围列表转列表 + permissions.Add(new DataScope + { + ApiUrl = it.Key, + ScopeCategory = scopeCategory, + DataScopes = dataScopes + });//将改URL的权限集合加入权限集合列表 + } + return permissions; + } + + + /// + public async Task> Selector(UserSelectorInput input) + { + var orgIds = await _sysOrgService.GetOrgChildIds(input.OrgId);//获取下级机构 + var result = await Context.Queryable() + .WhereIF(input.OrgId > 0, u => orgIds.Contains(u.OrgId))//指定机构 + .WhereIF(input.OrgIds != null, u => input.OrgIds.Contains(u.OrgId))//在指定机构列表查询 + .WhereIF(input.PositionId > 0, u => u.PositionId == input.PositionId)//指定职位 + .WhereIF(input.RoleId > 0, + u => SqlFunc.Subqueryable() + .Where(r => r.TargetId == input.RoleId.ToString() && r.ObjectId == u.Id && r.Category == CateGoryConst.RELATION_SYS_USER_HAS_ROLE) + .Any())//指定角色 + .WhereIF(!string.IsNullOrEmpty(input.Account), u => u.Account.Contains(input.Account))//根据关键字查询 + .Select().ToPagedListAsync(input.PageNum, input.PageSize); + return result; + } + + /// + public async Task> Page(UserPageInput input) + { + var query = await GetQuery(input);//获取查询条件 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task> List(UserPageInput input) + { + var query = await GetQuery(input);//获取查询条件 + var list = await query.ToListAsync(); + return list; + } + + /// + public async Task> OwnRole(BaseIdInput input) + { + var relations = await _relationService.GetRelationListByObjectIdAndCategory(input.Id, CateGoryConst.RELATION_SYS_USER_HAS_ROLE); + var roleIds = relations.Select(it => it.TargetId.ToLong()).ToList(); + var roleList = await Context.Queryable().Where(it => roleIds.Contains(it.Id)).Select().ToListAsync(); + return roleList; + } + + /// + public async Task OwnResource(BaseIdInput input) + { + return await _sysRoleService.OwnResource(input, CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE); + } + + /// + public async Task OwnPermission(BaseIdInput input) + { + var roleOwnPermission = new RoleOwnPermissionOutput + { + Id = input.Id + };//定义结果集 + var grantInfoList = new List();//已授权信息集合 + //获取关系列表 + var relations = await _relationService.GetRelationListByObjectIdAndCategory(input.Id, CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION); + //遍历关系表 + relations.ForEach(it => + { + //将扩展信息转为实体 + var relationPermission = it.ExtJson.ToJsonEntity(); + grantInfoList.Add(relationPermission);//添加到已授权信息 + }); + roleOwnPermission.GrantInfoList = grantInfoList;//赋值已授权信息 + return roleOwnPermission; + } + + /// + public async Task> UserPermissionTreeSelector(BaseIdInput input) + { + var permissionTreeSelectors = new List();//授权树结果集 + //获取用户资源关系 + var relationsRes = await _relationService.GetRelationByCategory(CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE); + var menuIds = relationsRes.Where(it => it.ObjectId == input.Id).Select(it => it.TargetId.ToLong()).ToList(); + if (menuIds.Any()) + { + //获取菜单信息 + var menus = await _resourceService.GetResourcesByIds(menuIds, CateGoryConst.RESOURCE_MENU); + //获取权限授权树 + var permissions = _resourceService.PermissionTreeSelector(menus.Select(it => it.Path).ToList()); + if (permissions.Count > 0) + { + permissionTreeSelectors = permissions.Select(it => it.PermissionName).ToList();//返回授权树权限名称列表 + } + } + return permissionTreeSelectors; + } + + /// + public async Task> GetUserListByIdList(IdListInput input) + { + var userList = await Context.Queryable().Where(it => input.IdList.Contains(it.Id)).Select().ToListAsync(); + return userList; + } + + /// + public async Task Detail(BaseIdInput input) + { + var user = await GetUserById(input.Id); + if (user != null) + { + user.Password = null;//清空密码 + } + return user; + } + + #endregion 查询 + + #region 数据范围相关 + + /// + public async Task?> GetLoginUserApiDataScope() + { + var userInfo = await GetUserById(UserManager.UserId);//获取用户信息 + // 路由名称 + var routeName = App.HttpContext.Request.Path.Value; + //获取当前url的数据范围 + var dataScope = userInfo.DataScopeList.Where(it => it.ApiUrl == routeName).FirstOrDefault(); + if (dataScope != null) + { + //根据数据范围分类获取数据范围 + //null:代表拥有全部数据权限 + //[xx,xx]:代表拥有部分机构的权限 + //[]:代表仅自己权限 + switch (dataScope.ScopeCategory) + { + case CateGoryConst.SCOPE_ALL: + return null; + + case CateGoryConst.SCOPE_ORG_CHILD: + return userInfo.ScopeOrgChildList; + + case CateGoryConst.SCOPE_ORG: + return new List { userInfo.OrgId }; + + case CateGoryConst.SCOPE_ORG_DEFINE: + return dataScope.DataScopes; + + case CateGoryConst.SCOPE_SELF: + return new List(); + } + } + return new List(); + } + + /// + public async Task CheckApiDataScope(long? orgId, long? createUerId, string errMsg = "") + { + var hasPermission = true; + //判断数据范围 + var dataScope = await GetLoginUserApiDataScope(); + if (dataScope is { Count: > 0 })//如果有机构 + { + if (orgId == null || !dataScope.Contains(orgId.Value))//判断机构id是否在数据范围 + hasPermission = false; + } + else if (dataScope is { Count: 0 })// 表示仅自己 + { + if (createUerId != UserManager.UserId) + hasPermission = false;//机构的创建人不是自己则报错 + } + //如果传了错误信息,直接抛出异常 + if (!hasPermission && !string.IsNullOrEmpty(errMsg)) + throw Oops.Bah(errMsg); + return hasPermission; + } + + public async Task CheckApiDataScope(List orgIds, List createUerIds, string errMsg = "") + { + var hasPermission = true; + //判断数据范围 + var dataScope = await GetLoginUserApiDataScope(); + if (dataScope is { Count: > 0 })//如果有机构 + { + if (orgIds == null || !dataScope.ContainsAll(orgIds))//判断机构id列表是否全在数据范围 + hasPermission = false; + } + else if (dataScope is { Count: 0 })// 表示仅自己 + { + if (createUerIds.Any(it => it != UserManager.UserId))//如果创建者id里有任何不是自己创建的机构 + hasPermission = false; + } + //如果传了错误信息,直接抛出异常 + if (!hasPermission && !string.IsNullOrEmpty(errMsg)) + throw Oops.Bah(errMsg); + return hasPermission; + } + + #endregion + + #region 新增 + + /// + public async Task Add(UserAddInput input) + { + await CheckInput(input);//检查参数 + var sysUser = input.Adapt();//实体转换 + //默认头像 + sysUser.Avatar = AvatarUtil.GetNameImageBase64(sysUser.Name); + //获取默认密码 + sysUser.Password = await GetDefaultPassWord(true);//设置密码 + sysUser.Status = CommonStatusConst.ENABLE;//默认状态 + await InsertAsync(sysUser);//添加数据 + } + + #endregion 新增 + + #region 编辑 + + /// + public async Task Edit(UserEditInput input) + { + await CheckInput(input);//检查参数 + var exist = await GetUserById(input.Id);//获取用户信息 + if (exist != null) + { + var isSuperAdmin = exist.Account == SysRoleConst.SUPER_ADMIN;//判断是否有超管 + if (isSuperAdmin && !UserManager.SuperAdmin) + throw Oops.Bah("不可修改系统内置超管用户账号"); + var name = exist.Name;//姓名 + var sysUser = input.Adapt();//实体转换 + if (name != input.Name) + sysUser.Avatar = AvatarUtil.GetNameImageBase64(input.Name);//如果姓名改变了,重新生成头像 + if (await Context.Updateable(sysUser).IgnoreColumns(it => new + { + //忽略更新字段 + it.Password, + it.LastLoginAddress, + it.LastLoginDevice, + it.LastLoginIp, + it.LastLoginTime, + it.LatestLoginAddress, + it.LatestLoginDevice, + it.LatestLoginIp, + it.LatestLoginTime + }).IgnoreColumnsIF(name == input.Name, it => it.Avatar).ExecuteCommandAsync() > 0 + )//修改数据 + { + DeleteUserFromRedis(sysUser.Id);//删除用户缓存 + //删除用户token缓存 + _simpleCacheService.HashDel>(CacheConst.CACHE_USER_TOKEN, sysUser.Id.ToString()); + } + } + } + + /// + public async Task Edits(BatchEditInput input) + { + //获取参数字典 + var data = await _batchEditService.GetUpdateBatchConfigDict(input.Code, input.Columns); + if (data.Count > 0) + { + await Context.Updateable(data).Where(it => input.Ids.Contains(it.Id)).ExecuteCommandAsync(); + } + } + + /// + public async Task DisableUser(BaseIdInput input) + { + var sysUser = await GetUserById(input.Id);//获取用户信息 + if (sysUser != null) + { + var isSuperAdmin = sysUser.Account == SysRoleConst.SUPER_ADMIN;//判断是否有超管 + if (isSuperAdmin) + throw Oops.Bah("不可禁用系统内置超管用户账号"); + CheckSelf(input.Id, SystemConst.DISABLE);//判断是不是自己 + //设置状态为禁用 + if (await UpdateSetColumnsTrueAsync(it => new SysUser + { + Status = CommonStatusConst.DISABLED + }, it => it.Id == input.Id)) + DeleteUserFromRedis(input.Id);//从缓存删除用户信息 + } + } + + /// + public async Task EnableUser(BaseIdInput input) + { + CheckSelf(input.Id, SystemConst.ENABLE);//判断是不是自己 + //设置状态为启用 + if (await UpdateSetColumnsTrueAsync(it => new SysUser + { + Status = CommonStatusConst.ENABLE + }, it => it.Id == input.Id)) + DeleteUserFromRedis(input.Id);//从缓存删除用户信息 + } + + /// + public async Task ResetPassword(BaseIdInput input) + { + var password = await GetDefaultPassWord(true);//获取默认密码,这里不走Aop所以需要加密一下 + //重置密码 + if (await UpdateSetColumnsTrueAsync(it => new SysUser + { + Password = password + }, it => it.Id == input.Id)) + DeleteUserFromRedis(input.Id);//从缓存删除用户信息 + } + + /// + public async Task GrantRole(UserGrantRoleInput input) + { + var sysUser = await GetUserById(input.Id);//获取用户信息 + if (sysUser != null) + { + var isSuperAdmin = sysUser.Account == SysRoleConst.SUPER_ADMIN;//判断是否有超管 + if (isSuperAdmin) + throw Oops.Bah("不能给超管分配角色"); + CheckSelf(input.Id, SystemConst.GRANT_ROLE);//判断是不是自己 + //给用户赋角色 + await _relationService.SaveRelationBatch(CateGoryConst.RELATION_SYS_USER_HAS_ROLE, input.Id, + input.RoleIdList.Select(it => it.ToString()).ToList(), null, true); + DeleteUserFromRedis(input.Id);//从缓存删除用户信息 + } + } + + /// + public async Task GrantResource(UserGrantResourceInput input) + { + var menuIds = input.GrantInfoList.Select(it => it.MenuId).ToList();//菜单ID + var extJsons = input.GrantInfoList.Select(it => it.ToJson()).ToList();//拓展信息 + var relationRoles = new List();//要添加的用户资源和授权关系表 + var sysUser = await GetUserById(input.Id);//获取用户 + if (sysUser != null) + { + #region 用户资源处理 + + //遍历角色列表 + for (var i = 0; i < menuIds.Count; i++) + { + //将用户资源添加到列表 + relationRoles.Add(new SysRelation + { + ObjectId = sysUser.Id, + TargetId = menuIds[i].ToString(), + Category = CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE, + ExtJson = extJsons == null ? null : extJsons[i] + }); + } + + #endregion 用户资源处理 + + #region 用户权限处理. + + var relationRolePer = new List();//要添加的用户有哪些权限列表 + var defaultDataScope = input.DefaultDataScope;//获取默认数据范围 + + //获取菜单信息 + var menus = await _resourceService.GetResourcesByIds(menuIds, CateGoryConst.RESOURCE_MENU); + if (menus.Count > 0) + { + #region 用户模块关系 + + //获取我的模块信息Id列表 + var moduleIds = menus.Select(it => it.Module.Value).Distinct().ToList(); + moduleIds.ForEach(it => + { + //将角色资源添加到列表 + relationRoles.Add(new SysRelation + { + ObjectId = sysUser.Id, + TargetId = it.ToString(), + Category = CateGoryConst.RELATION_SYS_USER_HAS_MODULE + }); + }); + + #endregion + + //获取权限授权树 + var permissions = _resourceService.PermissionTreeSelector(menus.Select(it => it.Path).ToList()); + permissions.ForEach(it => + { + //新建角色权限关系 + relationRolePer.Add(new SysRelation + { + ObjectId = sysUser.Id, + TargetId = it.ApiRoute, + Category = CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION, + ExtJson = new RelationRolePermission + { + ApiUrl = it.ApiRoute, + ScopeCategory = defaultDataScope.ScopeCategory, + ScopeDefineOrgIdList = defaultDataScope.ScopeDefineOrgIdList + }.ToJson() + }); + }); + } + relationRoles.AddRange(relationRolePer);//合并列表 + + #endregion 用户权限处理. + + #region 保存数据库 + + //事务 + var result = await Tenant.UseTranAsync(async () => + { + var relationRep = ChangeRepository>();//切换仓储 + await relationRep.DeleteAsync(it => it.ObjectId == sysUser.Id && (it.Category == CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION + || it.Category == CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE) || it.Category == CateGoryConst.RELATION_SYS_USER_HAS_MODULE); + await relationRep.InsertRangeAsync(relationRoles);//添加新的 + }); + if (result.IsSuccess)//如果成功了 + { + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION);//刷新关系缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE);//刷新关系缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_MODULE);//刷新关系缓存 + DeleteUserFromRedis(input.Id);//删除该用户缓存 + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0003); + } + + #endregion 保存数据库 + } + } + + /// + public async Task GrantPermission(GrantPermissionInput input) + { + var sysUser = await GetUserById(input.Id);//获取用户 + if (sysUser != null) + { + var apiUrls = input.GrantInfoList.Select(it => it.ApiUrl).ToList();//apiurl列表 + var extJsons = input.GrantInfoList.Select(it => it.ToJson()).ToList();//拓展信息 + await _relationService.SaveRelationBatch(CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION, input.Id, apiUrls, extJsons, + true);//添加到数据库 + DeleteUserFromRedis(input.Id); + } + } + + #endregion 编辑 + + #region 删除 + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids; + if (ids.Count > 0) + { + var containsSuperAdmin = await IsAnyAsync(it => it.Account == SysRoleConst.SUPER_ADMIN && ids.Contains(it.Id));//判断是否有超管 + if (containsSuperAdmin) + throw Oops.Bah("不可删除系统内置超管用户"); + if (ids.Contains(UserManager.UserId)) + throw Oops.Bah("不可删除自己"); + + //定义删除的关系 + var delRelations = new List + { + CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE, + CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION, + CateGoryConst.RELATION_SYS_USER_HAS_ROLE, + CateGoryConst.RELATION_SYS_USER_HAS_MODULE, + CateGoryConst.RELATION_SYS_USER_SCHEDULE_DATA, + CateGoryConst.RELATION_SYS_USER_WORKBENCH_DATA + }; + //事务 + var result = await Tenant.UseTranAsync(async () => + { + //清除该用户作为主管信息 + await UpdateAsync(it => new SysUser + { + DirectorId = null + }, it => ids.Contains(it.DirectorId.Value)); + + //删除用户 + await DeleteByIdsAsync(ids.Cast().ToArray()); + var relationRep = ChangeRepository>();//切换仓储 + //删除关系表用户与资源关系,用户与权限关系,用户与角色关系 + await relationRep.DeleteAsync(it => ids.Contains(it.ObjectId) && delRelations.Contains(it.Category)); + var orgRep = ChangeRepository>();//切换仓储 + //删除组织表主管信息 + await orgRep.DeleteAsync(it => ids.Contains(it.DirectorId.Value)); + }); + if (result.IsSuccess)//如果成功了 + { + DeleteUserFromRedis(ids);//缓存删除用户 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_ROLE);//关系表刷新SYS_USER_HAS_ROLE缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE);//关系表刷新SYS_USER_HAS_ROLE缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION);//关系表刷新SYS_USER_HAS_ROLE缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_MODULE);//关系表刷新RELATION_SYS_USER_HAS_MODULE缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_SCHEDULE_DATA);//关系表刷新RELATION_SYS_USER_SCHEDULE_DATA缓存 + await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_WORKBENCH_DATA);//关系表刷新RELATION_SYS_USER_WORKBENCH_DATA缓存 + // TODO 此处需要将这些用户踢下线,并永久注销这些用户 + var idArray = ids.Select(it => it.ToString()).ToArray(); + //从列表中删除 + _simpleCacheService.HashDel>(CacheConst.CACHE_USER_TOKEN, idArray); + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0002); + } + } + } + + /// + public void DeleteUserFromRedis(long userId) + { + DeleteUserFromRedis(new List + { + userId + }); + } + + /// + public void DeleteUserFromRedis(List ids) + { + var userIds = ids.Select(it => it.ToString()).ToArray();//id转string列表 + var sysUsers = _simpleCacheService.HashGet(SystemConst.CACHE_SYS_USER, userIds);//获取用户列表 + sysUsers = sysUsers.Where(it => it != null).ToList();//过滤掉不存在的 + if (sysUsers.Count > 0) + { + var accounts = sysUsers.Select(it => it.Account).ToArray();//账号集合 + var phones = sysUsers.Select(it => it.Phone).ToArray();//手机号集合 + //删除用户信息 + _simpleCacheService.HashDel(SystemConst.CACHE_SYS_USER, userIds); + //删除用户头像信息 + _simpleCacheService.HashDel(SystemConst.CACHE_SYS_USER_AVATAR, userIds); + var userAccountKey = SystemConst.CACHE_SYS_USER_ACCOUNT; + var userPhoneKey = SystemConst.CACHE_SYS_USER_PHONE; + if (sysUsers.Any(it => it.TenantId != null))//如果有租户id不是空的表示是多租户模式 + { + var tenantIds = sysUsers.Where(it => it.TenantId != null).Select(it => it.TenantId.Value).Distinct().ToArray();//租户id列表 + foreach (var tenantId in tenantIds) + { + userAccountKey = $"{userAccountKey}:{tenantId}"; + userPhoneKey = $"{userPhoneKey}:{tenantId}"; + //删除账号 + _simpleCacheService.HashDel(userAccountKey, accounts); + //删除手机 + if (phones != null) + _simpleCacheService.HashDel(userPhoneKey, phones); + } + } + else + { + //删除账号 + _simpleCacheService.HashDel(userAccountKey, accounts); + //删除手机 + if (phones != null) + _simpleCacheService.HashDel(userPhoneKey, phones); + } + } + } + + #endregion 删除 + + #region 导入导出 + + /// + public async Task Template() + { + var templateName = "用户信息"; + //var result = _importExportService.GenerateLocalTemplate(templateName); + var result = await _importExportService.GenerateTemplate(templateName); + return result; + } + + /// + public async Task> Preview(ImportPreviewInput input) + { + var importPreview = await _importExportService.GetImportPreview(input.File); + importPreview.Data = await CheckImport(importPreview.Data);//检查导入数据 + return importPreview; + } + + /// + public async Task> Import(ImportResultInput input) + { + var data = await CheckImport(input.Data, true);//检查数据格式 + var result = _importExportService.GetImportResultPreview(data, out var importData); + var sysUsers = importData.Adapt>();//转实体 + await SetUserDefault(sysUsers);//设置默认值 + await InsertOrBulkCopy(sysUsers);// 数据导入 + return result; + } + + /// + public async Task Export(UserPageInput input) + { + var genTests = await List(input); + var data = genTests.Adapt>();//转为Dto + var result = await _importExportService.Export(data, "用户信息"); + return result; + } + + /// + public async Task> CheckImport(List data, bool clearError = false) where T : SysUserImportInput + { + #region 校验要用到的数据 + + var accounts = data.Select(it => it.Account).ToList();//当前导入数据账号列表 + var phones = data.Where(it => !string.IsNullOrEmpty(it.Phone)).Select(it => it.Phone).ToList();//当前导入数据手机号列表 + var emails = data.Where(it => !string.IsNullOrEmpty(it.Email)).Select(it => it.Email).ToList();//当前导入数据邮箱列表 + var sysUsers = await GetListAsync(it => true, it => new SysUser + { + Account = it.Account, + Phone = it.Phone, + Email = it.Email + });//获取数据用户信息 + var dbAccounts = sysUsers.Select(it => it.Account).ToList();//数据库账号列表 + var dbPhones = sysUsers.Where(it => !string.IsNullOrEmpty(it.Phone)).Select(it => it.Phone).ToList();//数据库手机号列表 + var dbEmails = sysUsers.Where(it => !string.IsNullOrEmpty(it.Email)).Select(it => it.Email).ToList();//邮箱账号列表 + var sysOrgList = await _sysOrgService.GetListAsync(); + var sysPositions = await _sysPositionService.GetListAsync(); + var dictList = await _dictService.GetListAsync(); + + #endregion 校验要用到的数据 + + foreach (var item in data) + { + if (clearError)//如果需要清除错误 + { + item.ErrorInfo = new Dictionary(); + item.HasError = false; + } + + #region 校验账号 + + if (dbAccounts.Contains(item.Account)) + item.ErrorInfo.Add(nameof(item.Account), $"系统已存在账号{item.Account}"); + if (accounts.Where(u => u == item.Account).Count() > 1) + item.ErrorInfo.Add(nameof(item.Account), "账号重复"); + + #endregion 校验账号 + + #region 校验手机号 + + if (!string.IsNullOrEmpty(item.Phone)) + { + if (dbPhones.Contains(item.Phone)) + item.ErrorInfo.Add(nameof(item.Phone), $"系统已存在手机号{item.Phone}的用户"); + if (phones.Where(u => u == item.Phone).Count() > 1) + item.ErrorInfo.Add(nameof(item.Phone), "手机号重复"); + } + + #endregion 校验手机号 + + #region 校验邮箱 + + if (!string.IsNullOrEmpty(item.Email)) + { + if (dbEmails.Contains(item.Email)) + item.ErrorInfo.Add(nameof(item.Email), $"系统已存在邮箱{item.Email}"); + if (emails.Where(u => u == item.Email).Count() > 1) + item.ErrorInfo.Add(nameof(item.Email), "邮箱重复"); + } + + #endregion 校验邮箱 + + #region 校验部门和职位 + + if (!string.IsNullOrEmpty(item.OrgName)) + { + var org = sysOrgList.Where(u => u.Names == item.OrgName).FirstOrDefault(); + if (org != null) item.OrgId = org.Id;//赋值组织Id + else item.ErrorInfo.Add(nameof(item.OrgName), $"部门{org}不存在"); + } + //校验职位 + if (!string.IsNullOrEmpty(item.PositionName)) + { + if (string.IsNullOrEmpty(item.OrgName)) + item.ErrorInfo.Add(nameof(item.PositionName), "请填写部门"); + else + { + //根据部门ID和职位名判断是否有职位 + var position = sysPositions.FirstOrDefault(u => u.OrgId == item.OrgId && u.Name == item.PositionName); + if (position != null) item.PositionId = position.Id; + else item.ErrorInfo.Add(nameof(item.PositionName), $"职位{item.PositionName}不存在"); + } + } + + #endregion 校验部门和职位 + + #region 校验性别等字典 + + var genders = await _dictService.GetValuesByDictValue(SysDictConst.GENDER, dictList); + if (!genders.Contains(item.Gender)) + item.ErrorInfo.Add(nameof(item.Gender), "性别只能是男和女"); + if (!string.IsNullOrEmpty(item.Nation)) + { + var nations = await _dictService.GetValuesByDictValue(SysDictConst.NATION, dictList); + if (!nations.Contains(item.Nation)) + item.ErrorInfo.Add(nameof(item.Nation), "不存在的民族"); + } + if (!string.IsNullOrEmpty(item.IdCardType)) + { + var idCarTypes = await _dictService.GetValuesByDictValue(SysDictConst.ID_CARD_TYPE, dictList); + if (!idCarTypes.Contains(item.IdCardType)) + item.ErrorInfo.Add(nameof(item.IdCardType), "证件类型错误"); + } + if (!string.IsNullOrEmpty(item.CultureLevel)) + { + var cultureLevels = await _dictService.GetValuesByDictValue(SysDictConst.CULTURE_LEVEL, dictList); + if (!cultureLevels.Contains(item.CultureLevel)) + item.ErrorInfo.Add(nameof(item.CultureLevel), "文化程度有误"); + } + + #endregion 校验性别等字典 + + if (item.ErrorInfo.Count > 0) item.HasError = true;//如果错误信息数量大于0则表示有错误 + } + data = data.OrderByDescending(it => it.HasError).ToList();//排序 + return data; + } + + /// + public async Task SetUserDefault(List sysUsers) + { + var defaultPassword = await GetDefaultPassWord(true);//默认密码 + + //默认值赋值 + sysUsers.ForEach(user => + { + user.Status = CommonStatusConst.ENABLE;//状态 + user.Phone = CryptogramUtil.Sm4Encrypt(user.Phone);//手机号 + user.Password = defaultPassword;//默认密码 + user.Avatar = AvatarUtil.GetNameImageBase64(user.Name);//默认头像 + }); + } + + #endregion 导入导出 + + #region 方法 + + /// + /// 获取默认密码 + /// + /// + private async Task GetDefaultPassWord(bool isSm4 = false) + { + //获取默认密码 + var defaultPassword = (await _configService.GetByConfigKey(CateGoryConst.CONFIG_PWD_POLICY, SysConfigConst.PWD_DEFAULT_PASSWORD)).ConfigValue; + return isSm4 ? CryptogramUtil.Sm4Encrypt(defaultPassword) : defaultPassword;//判断是否需要加密 + } + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(SysUser sysUser) + { + var sysOrgList = await _sysOrgService.GetListAsync();//获取组织列表 + var userOrg = sysOrgList.FirstOrDefault(it => it.Id == sysUser.OrgId); + if (userOrg == null) + throw Oops.Bah($"组织机构不存在"); + //获取多租户配置 + var isTenant = await _configService.IsTenant(); + long? tenantId = null; + if (isTenant) + tenantId = await _sysOrgService.GetTenantIdByOrgId(sysUser.OrgId, sysOrgList); + //判断账号重复,直接从缓存拿 + var accountId = await GetIdByAccount(sysUser.Account, tenantId); + if (accountId > 0 && accountId != sysUser.Id) + throw Oops.Bah($"存在重复的账号:{sysUser.Account}"); + //如果手机号不是空 + if (!string.IsNullOrEmpty(sysUser.Phone)) + { + if (!sysUser.Phone.MatchPhoneNumber())//验证手机格式 + throw Oops.Bah($"手机号码:{sysUser.Phone} 格式错误"); + var phoneId = await GetIdByPhone(sysUser.Phone, tenantId); + if (phoneId > 0 && sysUser.Id != phoneId)//判断重复 + throw Oops.Bah($"存在重复的手机号:{sysUser.Phone}"); + sysUser.Phone = CryptogramUtil.Sm4Encrypt(sysUser.Phone); + } + //如果邮箱不是空 + if (!string.IsNullOrEmpty(sysUser.Email)) + { + var (isMatch, match) = sysUser.Email.MatchEmail();//验证邮箱格式 + if (!isMatch) + throw Oops.Bah($"邮箱:{sysUser.Email} 格式错误"); + if (await IsAnyAsync(it => it.Email == sysUser.Email && it.Id != sysUser.Id)) + throw Oops.Bah($"存在重复的邮箱:{sysUser.Email}"); + } + if (sysUser.DirectorId != null) + { + if (sysUser.DirectorId.Value == UserManager.UserId) throw Oops.Bah($"不能设置自己为主管"); + } + } + + /// + /// 检查是否为自己 + /// + /// + /// 操作名称 + private void CheckSelf(long id, string operate) + { + if (id == UserManager.UserId)//如果是自己 + { + throw Oops.Bah($"禁止{operate}自己"); + } + } + + /// + /// 根据日期计算年龄 + /// + /// + /// + public int GetAgeByBirthdate(DateTime birthdate) + { + var now = DateTime.Now; + var age = now.Year - birthdate.Year; + if (now.Month < birthdate.Month || now.Month == birthdate.Month && now.Day < birthdate.Day) + { + age--; + } + return age < 0 ? 0 : age; + } + + /// + /// 获取SqlSugar的ISugarQueryable + /// + /// + /// + private async Task> GetQuery(UserPageInput input) + { + var orgIds = await _sysOrgService.GetOrgChildIds(input.OrgId);//获取下级机构 + var query = Context.Queryable().LeftJoin((u, o) => u.OrgId == o.Id).LeftJoin((u, o, p) => u.PositionId == p.Id) + .WhereIF(input.OrgId > 0, u => orgIds.Contains(u.OrgId))//根据组织 + .WhereIF(input.Expression != null, input.Expression?.ToExpression())//动态查询 + .WhereIF(!string.IsNullOrEmpty(input.Status), u => u.Status == input.Status)//根据状态查询 + .WhereIF(!string.IsNullOrEmpty(input.SearchKey), u => u.Name.Contains(input.SearchKey) || u.Account.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"u.{input.SortField} {input.SortOrder}").OrderBy(u => u.Id)//排序 + .OrderBy((u, o) => u.CreateTime)//排序 + .Select((u, o, p) => new SysUser + { + Id = u.Id.SelectAll(), + OrgName = o.Name, + PositionName = p.Name, + OrgNames = o.Names + }).Mapper(u => + { + u.Password = null;//密码清空 + u.Phone = CryptogramUtil.Sm4Decrypt(u.Phone);//手机号解密 + }); + return query; + } + + /// + /// 数据库获取用户信息 + /// + /// 用户ID + /// + private async Task GetUserFromDb(long userId) + { + var sysUser = await Context.Queryable().LeftJoin((u, o) => u.OrgId == o.Id)//连表 + .LeftJoin((u, o, p) => u.PositionId == p.Id)//连表 + .Where(u => u.Id == userId) + .Select((u, o, p) => new SysUser + { + Id = u.Id.SelectAll(), + OrgName = o.Name, + OrgNames = o.Names, + PositionName = p.Name, + OrgAndPosIdList = o.ParentIdList + }).FirstAsync(); + if (sysUser != null) + { + sysUser.Password = CryptogramUtil.Sm4Decrypt(sysUser.Password);//解密密码 + sysUser.Phone = CryptogramUtil.Sm4Decrypt(sysUser.Phone);//解密手机号 + sysUser.OrgAndPosIdList.AddRange(sysUser.OrgId, sysUser.PositionId);//添加组织和职位Id + if (sysUser.DirectorId != null) + { + sysUser.DirectorInfo = await GetUserById(sysUser.DirectorId.Value);//获取主管信息 + } + //获取按钮码 + var buttonCodeList = await GetButtonCodeList(sysUser.Id); + //获取数据权限 + var dataScopeList = await GetPermissionListByUserId(sysUser.Id, sysUser.OrgId); + //获取权限码 + var permissionCodeList = dataScopeList.Select(it => it.ApiUrl).ToList(); + //获取角色码 + var roleCodeList = await _sysRoleService.GetRoleListByUserId(sysUser.Id); + //权限码赋值 + sysUser.ButtonCodeList = buttonCodeList; + sysUser.RoleCodeList = roleCodeList.Select(it => it.Code).ToList(); + sysUser.RoleIdList = roleCodeList.Select(it => it.Id).ToList(); + sysUser.PermissionCodeList = permissionCodeList; + sysUser.DataScopeList = dataScopeList; + var sysOrgList = await _sysOrgService.GetListAsync(); + var scopeOrgChildList = + (await _sysOrgService.GetChildListById(sysUser.OrgId, true, sysOrgList)).Select(it => it.Id).ToList();//获取所属机构的下级机构Id列表 + sysUser.ScopeOrgChildList = scopeOrgChildList; + if (await _configService.IsTenant())//如果是多租户就获取用户的租户Id + { + var tenantId = await _sysOrgService.GetTenantIdByOrgId(sysUser.OrgId, sysOrgList); + sysUser.TenantId = tenantId; + } + var moduleIds = await _relationService.GetUserModuleId(sysUser.RoleIdList, sysUser.Id);//获取模块ID列表 + var modules = await _resourceService.GetResourcesByIds(moduleIds, CateGoryConst.RESOURCE_MODULE);//获取模块列表 + sysUser.ModuleList = modules;//模块列表赋值给用户 + //插入缓存 + _simpleCacheService.HashAdd(SystemConst.CACHE_SYS_USER_AVATAR, sysUser.Id.ToString(), sysUser.Avatar); + sysUser.Avatar = null;//头像清空,减少CACHE_SYS_USER的大小 + _simpleCacheService.HashAdd(SystemConst.CACHE_SYS_USER, sysUser.Id.ToString(), sysUser); + return sysUser; + } + return null; + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/System/Relation/Dto/RelationInput.cs b/SimpleAdmin.System/Services/System/Relation/Dto/RelationInput.cs new file mode 100644 index 0000000..cfde937 --- /dev/null +++ b/SimpleAdmin.System/Services/System/Relation/Dto/RelationInput.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + + + + + diff --git a/SimpleAdmin.System/Services/System/Relation/Dto/RelationOutput.cs b/SimpleAdmin.System/Services/System/Relation/Dto/RelationOutput.cs new file mode 100644 index 0000000..8836584 --- /dev/null +++ b/SimpleAdmin.System/Services/System/Relation/Dto/RelationOutput.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System.Services.System.Relation.Dto; + +public class RelationOutput +{ +} diff --git a/SimpleAdmin.System/Services/System/Relation/IRelationService.cs b/SimpleAdmin.System/Services/System/Relation/IRelationService.cs new file mode 100644 index 0000000..edb4c1c --- /dev/null +++ b/SimpleAdmin.System/Services/System/Relation/IRelationService.cs @@ -0,0 +1,103 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 关系服务 +/// +public interface IRelationService : ITransient +{ + /// + /// 根据分类获取关系表信息 + /// + /// 分类名称 + /// 关系表 + Task> GetRelationByCategory(string category); + + /// + /// 通过对象ID和分类获取关系列表 + /// + /// 对象ID + /// 分类 + /// + Task> GetRelationListByObjectIdAndCategory(long objectId, string category); + + /// + /// 通过对象ID列表和分类获取关系列表 + /// + /// 对象ID + /// 分类 + /// + Task> GetRelationListByObjectIdListAndCategory(List objectIds, string category); + + /// + /// 通过目标ID和分类获取关系列表 + /// + /// 目标ID + /// 分类 + /// + Task> GetRelationListByTargetIdAndCategory(string targetId, string category); + + /// + /// 通过目标ID列表和分类获取关系列表 + /// + /// + /// + /// + Task> GetRelationListByTargetIdListAndCategory(List targetIds, string category); + + /// + /// 获取关系表用户工作台 + /// + /// 用户ID + /// 关系表数据 + Task GetWorkbench(long userId); + + /// + /// 更新缓存 + /// + /// 分类 + /// + Task RefreshCache(string category); + + /// + /// 保存关系 + /// + /// 分类 + /// 对象ID + /// 目标ID + /// 拓展信息 + /// 是否清除老的数据 + /// 是否刷新缓存 + /// + Task SaveRelation(string category, long objectId, string targetId, + string extJson, bool clear, bool refreshCache = true); + + /// + /// 批量保存关系 + /// + /// 分类 + /// 对象ID + /// 目标ID列表 + /// 拓展信息列表 + /// 是否清除老的数据 + /// + Task SaveRelationBatch(string category, long objectId, List targetIds, + List extJsons, bool clear); + + /// + /// 获取用户模块ID + /// + /// + /// + /// + Task> GetUserModuleId(List roleIdList, long userId); +} diff --git a/SimpleAdmin.System/Services/System/Relation/RelationService.cs b/SimpleAdmin.System/Services/System/Relation/RelationService.cs new file mode 100644 index 0000000..66fe096 --- /dev/null +++ b/SimpleAdmin.System/Services/System/Relation/RelationService.cs @@ -0,0 +1,174 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +public class RelationService : DbRepository, IRelationService +{ + private readonly ILogger _logger; + private readonly ISimpleCacheService _simpleCacheService; + + public RelationService(ILogger logger, ISimpleCacheService simpleCacheService) + { + _logger = logger; + _simpleCacheService = simpleCacheService; + } + + /// + public async Task> GetRelationByCategory(string category) + { + var key = SystemConst.CACHE_SYS_RELATION + category; + //先从Redis拿 + var sysRelations = _simpleCacheService.Get>(key); + if (sysRelations == null) + { + //redis没有就去数据库拿 + sysRelations = await base.GetListAsync(it => it.Category == category); + if (sysRelations.Count > 0) + { + //插入Redis + _simpleCacheService.Set(key, sysRelations); + } + } + return sysRelations; + } + + /// + public async Task> GetRelationListByObjectIdAndCategory(long objectId, string category) + { + var sysRelations = await GetRelationByCategory(category); + var result = sysRelations.Where(it => it.ObjectId == objectId).ToList();//获取关系集合 + return result; + } + + /// + public async Task GetWorkbench(long userId) + { + var sysRelations = await GetRelationByCategory(CateGoryConst.RELATION_SYS_USER_WORKBENCH_DATA); + var result = sysRelations.Where(it => it.ObjectId == userId).FirstOrDefault();//获取个人工作台 + return result; + } + + /// + public async Task> GetRelationListByObjectIdListAndCategory(List objectIds, string category) + { + var sysRelations = await GetRelationByCategory(category); + var result = sysRelations.Where(it => objectIds.Contains(it.ObjectId)).ToList();//获取关系集合 + return result; + } + + /// + public async Task> GetRelationListByTargetIdAndCategory(string targetId, string category) + { + var sysRelations = await GetRelationByCategory(category); + var result = sysRelations.Where(it => it.TargetId == targetId).ToList();//获取关系集合 + return result; + } + + /// + public async Task> GetRelationListByTargetIdListAndCategory(List targetIds, string category) + { + var sysRelations = await GetRelationByCategory(category); + var result = sysRelations.Where(it => targetIds.Contains(it.TargetId)).ToList();//获取关系集合 + return result; + } + + /// + public async Task RefreshCache(string category) + { + var key = SystemConst.CACHE_SYS_RELATION + category;//key + _simpleCacheService.Remove(key);//删除redis + await GetRelationByCategory(category);//更新缓存 + } + + /// + public async Task SaveRelationBatch(string category, long objectId, List targetIds, + List extJsons, bool clear) + { + var sysRelations = new List();//要添加的列表 + for (var i = 0; i < targetIds.Count; i++) + { + sysRelations.Add(new SysRelation + { + ObjectId = objectId, + TargetId = targetIds[i], + Category = category, + ExtJson = extJsons == null ? null : extJsons[i] + }); + } + //事务 + var result = await Tenant.UseTranAsync(async () => + { + if (clear) + await DeleteAsync(it => it.ObjectId == objectId && it.Category == category);//删除老的 + await InsertRangeAsync(sysRelations);//添加新的 + }); + if (result.IsSuccess)//如果成功了 + { + await RefreshCache(category); + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0003); + } + } + + /// + public async Task SaveRelation(string category, long objectId, string targetId, + string extJson, bool clear, bool refreshCache = true) + { + var sysRelation = new SysRelation + { + ObjectId = objectId, + TargetId = targetId, + Category = category, + ExtJson = extJson + }; + //事务 + var result = await Tenant.UseTranAsync(async () => + { + if (clear) + await DeleteAsync(it => it.ObjectId == objectId && it.Category == category);//删除老的 + await InsertAsync(sysRelation);//添加新的 + }); + if (result.IsSuccess)//如果成功了 + { + if (refreshCache) + await RefreshCache(category); + } + else + { + //写日志 + _logger.LogError(result.ErrorMessage, result.ErrorException); + throw Oops.Oh(ErrorCodeEnum.A0003); + } + } + + /// + public async Task> GetUserModuleId(List roleIdList, long userId) + { + var moduleIds = new List(); + var roleRelation = await GetRelationByCategory(CateGoryConst.RELATION_SYS_ROLE_HAS_MODULE);//获取角色模块关系集合 + if (roleRelation != null && roleRelation.Count > 0) + { + moduleIds = roleRelation.Where(it => roleIdList.Contains(it.ObjectId)).Select(it => it.TargetId.ToLong()).ToList(); + } + var userRelation = await GetRelationByCategory(CateGoryConst.RELATION_SYS_USER_HAS_MODULE);//获取用户模块关系集合 + if (userRelation != null && userRelation.Count > 0) + { + var userModuleIds = userRelation.Where(it => it.ObjectId == userId).Select(it => it.TargetId.ToLong()).ToList(); + moduleIds.AddRange(userModuleIds); + } + return moduleIds; + } +} diff --git a/SimpleAdmin.System/Services/System/Resource/Dto/ResourceInput.cs b/SimpleAdmin.System/Services/System/Resource/Dto/ResourceInput.cs new file mode 100644 index 0000000..a8d4563 --- /dev/null +++ b/SimpleAdmin.System/Services/System/Resource/Dto/ResourceInput.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 资源输入 +/// +public class ResTreeSelectorInput +{ + /// + /// 资源分类 + /// + public string ShowSystem { get; set; } + + /// + /// 是否包含按钮 + /// + public bool IsContainButton { get; set; } +} diff --git a/SimpleAdmin.System/Services/System/Resource/Dto/ResourceOutPut.cs b/SimpleAdmin.System/Services/System/Resource/Dto/ResourceOutPut.cs new file mode 100644 index 0000000..38871d1 --- /dev/null +++ b/SimpleAdmin.System/Services/System/Resource/Dto/ResourceOutPut.cs @@ -0,0 +1,110 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 角色授权资源树输出 +/// +public class ResTreeSelector +{ + /// + /// 模块id + /// + public long Id { get; set; } + + /// + /// 模块名称 + /// + public string Title { get; set; } + + /// + /// 模块图标 + /// + public string Icon { get; set; } + + /// + /// 模块下菜单集合 + /// + public List Menu { get; set; } + + /// + /// 授权菜单类 + /// + public class RoleGrantResourceMenu + { + /// + /// 菜单id + /// + public long Id { get; set; } + + /// + /// 父id + /// + public long ParentId { get; set; } + + /// + /// 父名称 + /// + public string ParentName { get; set; } + + /// + /// 模块名称 + /// + public string Title { get; set; } + + /// + /// 模块id + /// + public long Module { get; set; } + + /// + /// 菜单下按钮集合 + /// + public List Button { get; set; } = new List(); + } + + /// + /// 角色授权资源按钮信息 + /// + public class RoleGrantResourceButton + { + /// + /// 按钮id + /// + public long Id { get; set; } + + /// + /// 标题 + /// + public string Title { get; set; } + } +} + +/// +/// 权限树选择器输出 +/// +public class PermissionTreeSelector +{ + /// + /// 接口描述 + /// + public string ApiName { get; set; } + + /// + /// 路由名称 + /// + public string ApiRoute { get; set; } + + /// + /// 权限名称 + /// + public string PermissionName { get; set; } +} diff --git a/SimpleAdmin.System/Services/System/Resource/IResourceService.cs b/SimpleAdmin.System/Services/System/Resource/IResourceService.cs new file mode 100644 index 0000000..209a3fd --- /dev/null +++ b/SimpleAdmin.System/Services/System/Resource/IResourceService.cs @@ -0,0 +1,113 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 资源服务 +/// +public interface IResourceService : ITransient +{ + /// + /// 获取所有的菜单和模块以及单页面列表,并按分类和排序码排序 + /// + /// 所有的菜单和模块以及单页面列表 + Task> GetAllModuleAndMenuAndSpaList(); + + /// + /// 根据模块ID获取菜单和单页面列表 + /// + /// + /// + Task> GetMenuAndSpaListByModuleId(long id); + + /// + /// 根据资源ID获取所有下级资源 + /// + /// 资源ID + /// 是否包含自己 + /// 资源列表 + Task> GetChildListById(long resId, bool isContainOneself = true); + + /// + /// 根据资源ID获取所有下级资源 + /// + /// 资源列表 + /// 资源ID + /// 是否包含自己 + /// 资源列表 + List GetChildListById(List sysResources, long resId, bool isContainOneself = true); + + /// + /// 获取ID获取Code列表 + /// + /// id列表 + /// 分类 + /// Code列表 + Task> GetCodeByIds(List ids, string category); + + /// + /// 获取资源列表 + /// + /// 资源分类列表 + /// + Task> GetListAsync(List? categoryList = null); + + /// + /// 根据分类获取资源列表 + /// + /// 分类名称 + /// 资源列表 + Task> GetListByCategory(string category); + + /// + /// 根据菜单ID获取菜单 + /// + /// id列表 + /// 分类 + /// + Task> GetResourcesByIds(List ids, string category); + + /// + /// 获取权限授权树 + /// + /// 路由列表 + /// + List PermissionTreeSelector(List routes); + + /// + /// 刷新缓存 + /// + /// 分类名称 + /// + Task RefreshCache(string category = null); + + /// + /// 角色授权资源树 + /// + /// + Task> ResourceTreeSelector(); + + /// + /// 获取上级 + /// + /// + /// + /// + List GetResourceParent(List resourceList, long parentId); + + /// + /// 获取授权菜单类菜单名称 + /// + /// 菜单列表 + /// 当前菜单 + /// + string GetRoleGrantResourceMenuTitle(List menuList, SysResource menu); +} diff --git a/SimpleAdmin.System/Services/System/Resource/ResourceService.cs b/SimpleAdmin.System/Services/System/Resource/ResourceService.cs new file mode 100644 index 0000000..ccaf7b3 --- /dev/null +++ b/SimpleAdmin.System/Services/System/Resource/ResourceService.cs @@ -0,0 +1,427 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System.ComponentModel; +using StringHelper = SimpleTool.StringHelper; + +namespace SimpleAdmin.System; + +/// +public class ResourceService : DbRepository, IResourceService +{ + private readonly ISimpleCacheService _simpleCacheService; + private readonly IRelationService _relationService; + + public ResourceService(ISimpleCacheService simpleCacheService, IRelationService relationService) + { + _simpleCacheService = simpleCacheService; + _relationService = relationService; + } + + /// + public async Task> GetCodeByIds(List ids, string category) + { + //根据分类获取所有 + var sysResources = await GetListByCategory(category); + //条件查询 + var result = sysResources.Where(it => ids.Contains(it.Id)).Select(it => it.Code).ToList(); + return result; + } + + /// + public async Task> GetListAsync(List? categoryList = null) + { + //定义结果 + var sysResources = new List(); + + //定义资源分类列表,如果是空的则获取全部资源 + categoryList = categoryList != null + ? categoryList + : new List + { + CateGoryConst.RESOURCE_MENU, CateGoryConst.RESOURCE_BUTTON, + CateGoryConst.RESOURCE_SPA, CateGoryConst.RESOURCE_MODULE + }; + //遍历列表 + foreach (var category in categoryList) + { + //根据分类获取到资源列表 + var data = await GetListByCategory(category); + //添加到结果集 + sysResources.AddRange(data); + } + return sysResources; + } + + /// + public async Task> GetAllModuleAndMenuAndSpaList() + { + //获取所有的菜单和模块以及单页面列表, + var sysResources = await GetListAsync(new List + { + CateGoryConst.RESOURCE_MODULE, CateGoryConst.RESOURCE_MENU, CateGoryConst.RESOURCE_SPA + }); + if (sysResources != null) + { + //并按分类和排序码排序 + sysResources = sysResources.OrderBy(it => it.Category).ThenBy(it => it.SortCode).ToList(); + } + return sysResources; + } + + /// + public async Task> GetMenuAndSpaListByModuleId(long id) + { + //获取所有的菜单和模块以及单页面列表, + var sysResources = await GetListAsync(new List { CateGoryConst.RESOURCE_MENU, CateGoryConst.RESOURCE_SPA }); + if (sysResources != null) + { + //并按分类和排序码排序 + sysResources = sysResources.Where(it => it.Category == CateGoryConst.RESOURCE_SPA || it.Module == id)//根据模块ID获取菜单 + .OrderBy(it => it.Category).ThenBy(it => it.SortCode).ToList();//排序 + } + return sysResources; + } + + /// + public async Task RefreshCache(string category = null) + { + //如果分类是空的 + if (category == null) + { + //删除全部key + _simpleCacheService.DelByPattern(SystemConst.CACHE_SYS_RESOURCE); + await GetListAsync(); + } + else + { + //否则只删除一个Key + _simpleCacheService.Remove(SystemConst.CACHE_SYS_RESOURCE + category); + await GetListByCategory(category); + } + } + + /// + public async Task> GetChildListById(long resId, bool isContainOneself = true) + { + //获取所有机构 + var sysResources = await GetListAsync(); + //查找下级 + var childList = GetResourceChildren(sysResources, resId); + if (isContainOneself)//如果包含自己 + { + //获取自己的机构信息 + var self = sysResources.Where(it => it.Id == resId).FirstOrDefault(); + if (self != null) childList.Insert(0, self);//如果机构不为空就插到第一个 + } + return childList; + } + + /// + public List GetChildListById(List sysResources, long resId, bool isContainOneself = true) + { + //查找下级 + var childList = GetResourceChildren(sysResources, resId); + if (isContainOneself)//如果包含自己 + { + //获取自己的机构信息 + var self = sysResources.Where(it => it.Id == resId).FirstOrDefault(); + if (self != null) childList.Insert(0, self);//如果机构不为空就插到第一个 + } + return childList; + } + + /// + public async Task> GetListByCategory(string category) + { + //先从Redis拿 + var sysResources = _simpleCacheService.Get>(SystemConst.CACHE_SYS_RESOURCE + category); + if (sysResources == null) + { + //redis没有就去数据库拿 + sysResources = await base.GetListAsync(it => it.Category == category); + if (sysResources.Count > 0) + { + //插入Redis + _simpleCacheService.Set(SystemConst.CACHE_SYS_RESOURCE + category, sysResources); + } + } + return sysResources; + } + + /// + public async Task> ResourceTreeSelector() + { + var resourceTreeSelectors = new List();//定义结果 + //获取模块列表 + var moduleList = await GetListByCategory(CateGoryConst.RESOURCE_MODULE); + //遍历模块 + foreach (var module in moduleList) + { + //将实体转换为ResourceTreeSelectorOutPut获取基本信息 + var resourceTreeSelector = module.Adapt(); + resourceTreeSelector.Menu = await GetRoleGrantResourceMenus(module.Id); + resourceTreeSelectors.Add(resourceTreeSelector); + } + return resourceTreeSelectors; + } + + /// + public List PermissionTreeSelector(List routes) + { + var permissions = new List();//权限列表 + var controllerTypes = + App.EffectiveTypes.Where(u => + !u.IsInterface && !u.IsAbstract && u.IsDefined(typeof(RolePermissionAttribute), false)); + foreach (var controller in controllerTypes) + { + var apiAttribute = controller.GetCustomAttribute();//获取接口描述特性 + var tag = apiAttribute.Tag;//获取标签 + //获取数据权限特性 + var routeAttributes = controller.GetCustomAttributes().ToList(); + if (routeAttributes == null) + continue; + var route = routeAttributes[0];//取第一个值 + var routeName = GetRouteName(controller.Name, route.Template);//赋值路由名称 + //如果路由包含在路由列表中 + if (routes.Contains(routeName)) + { + //获取所有方法 + var methods = controller.GetMethods(); + //遍历方法 + foreach (var method in methods) + { + //获取忽略数据权限特性 + var ignoreRolePermission = method.GetCustomAttribute(); + if (ignoreRolePermission == null)//如果是空的代表需要数据权限 + { + //获取接口描述 + var displayName = method.GetCustomAttribute(); + if (displayName != null) + { + //默认路由名称 + var apiRoute = StringHelper.FirstCharToLower(method.Name); + //获取get特性 + var requestGet = method.GetCustomAttribute(); + if (requestGet != null)//如果是get方法 + apiRoute = requestGet.Template; + else + { + //获取post特性 + var requestPost = method.GetCustomAttribute(); + if (requestPost != null)//如果是post方法 + apiRoute = requestPost.Template; + } + apiRoute = route.Template + $"/{apiRoute}"; + if (!apiRoute.StartsWith("/")) + apiRoute = "/" + apiRoute;//如果路由地址不是/开头则加上/防止控制器没写 + var apiName = displayName.DisplayName;//如果描述不为空则接口名称用描述的名称 + //合并 + var permissionName = apiRoute + $"[{tag}-{apiName}]"; + //添加到权限列表 + permissions.Add(new PermissionTreeSelector + { + ApiName = apiName, + ApiRoute = apiRoute, + PermissionName = permissionName + }); + } + } + } + } + } + return permissions; + } + + /// + public async Task> GetResourcesByIds(List ids, string category) + { + //获取所有菜单 + var menus = await GetListByCategory(category); + if (!UserManager.SuperAdmin)//超级管理员获取所有 + { + //获取菜单信息 + menus = menus.Where(it => ids.Contains(it.Id)).ToList(); + } + return menus; + } + + + /// + public List GetResourceParent(List resourceList, long parentId) + { + //找上级资源ID列表 + var resources = resourceList.Where(it => it.Id == parentId).FirstOrDefault(); + if (resources != null)//如果数量大于0 + { + var data = new List(); + var parents = GetResourceParent(resourceList, resources.ParentId.Value); + data.AddRange(parents);//添加子节点; + data.Add(resources);//添加到列表 + return data;//返回结果 + } + return new List(); + } + + #region 方法 + + /// + /// 获取路由地址名称 + /// + /// 控制器地址 + /// 路由名称 + /// + private string GetRouteName(string controllerName, string template) + { + if (!template.StartsWith("/")) + template = "/" + template;//如果路由名称不是/开头则加上/防止控制器没写 + if (template.Contains("[controller]")) + { + controllerName = controllerName.Replace("Controller", "");//去掉Controller + controllerName = StringHelper.FirstCharToLower(controllerName);//转首字母小写写 + template = template.Replace("[controller]", controllerName);//替换[controller] + } + + return template; + } + + /// + /// 获取资源所有下级 + /// + /// 资源列表 + /// 父ID + /// + public List GetResourceChildren(List resourceList, long parentId) + { + //找下级资源ID列表 + var resources = resourceList.Where(it => it.ParentId == parentId).ToList(); + if (resources.Count > 0)//如果数量大于0 + { + var data = new List(); + foreach (var item in resources)//遍历资源 + { + var res = GetResourceChildren(resourceList, item.Id); + data.AddRange(res);//添加子节点; + data.Add(item);//添加到列表 + } + return data;//返回结果 + } + return new List(); + } + + /// + /// 获取授权菜单 + /// + /// 模块ID + /// + public async Task> GetRoleGrantResourceMenus(long moduleId) + { + var roleGrantResourceMenus = new List();//定义结果 + var allMenuList = (await GetListByCategory(CateGoryConst.RESOURCE_MENU)).Where(it => it.Module == moduleId).ToList();//获取所有菜单列表 + var allButtonList = await GetListByCategory(CateGoryConst.RESOURCE_BUTTON);//获取所有按钮列表 + var parentMenuList = allMenuList.Where(it => it.ParentId == SimpleAdminConst.ZERO).ToList();//获取一级目录 + + //遍历一级目录 + foreach (var parent in parentMenuList) + { + //如果是目录则去遍历下级 + if (parent.MenuType == SysResourceConst.CATALOG) + { + //获取所有下级菜单 + var menuList = GetChildListById(allMenuList, parent.Id, false); + if (menuList.Count > 0)//如果有菜单 + { + //遍历下级菜单 + foreach (var menu in menuList) + { + //如果菜单类型是菜单 + if (menu.MenuType is SysResourceConst.MENU or SysResourceConst.SUBSET) + { + //获取菜单下按钮集合并转换成对应实体 + var buttonList = allButtonList.Where(it => it.ParentId == menu.Id).ToList(); + var buttons = buttonList.Adapt>(); + roleGrantResourceMenus.Add(new ResTreeSelector.RoleGrantResourceMenu + { + Id = menu.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId, + Title = GetRoleGrantResourceMenuTitle(menuList, menu),//菜单名称需要特殊处理因为有二级菜单 + Button = buttons + }); + } + else if (menu.MenuType == SysResourceConst.LINK || menu.MenuType == SysResourceConst.IFRAME)//如果是内链或者外链 + { + //直接加到资源列表 + roleGrantResourceMenus.Add(new ResTreeSelector.RoleGrantResourceMenu + { + Id = menu.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId, + Title = menu.Title + }); + } + } + } + else + { + //否则就将自己加到一级目录里面 + roleGrantResourceMenus.Add(new ResTreeSelector.RoleGrantResourceMenu + { + Id = parent.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId + }); + } + } + else + { + //就将自己加到一级目录里面 + var roleGrantResourcesButtons = new ResTreeSelector.RoleGrantResourceMenu + { + Id = parent.Id, + ParentId = parent.Id, + ParentName = parent.Title, + Module = moduleId, + Title = parent.Title + }; + //如果菜单类型是菜单 + if (parent.MenuType == SysResourceConst.MENU) + { + //获取菜单下按钮集合并转换成对应实体 + var buttonList = allButtonList.Where(it => it.ParentId == parent.Id).ToList(); + roleGrantResourcesButtons.Button = buttonList.Adapt>(); + } + roleGrantResourceMenus.Add(roleGrantResourcesButtons); + } + } + return roleGrantResourceMenus; + } + + + /// + public string GetRoleGrantResourceMenuTitle(List menuList, SysResource menu) + { + //查找菜单上级 + var parentList = GetResourceParent(menuList, menu.ParentId.Value); + //如果有父级菜单 + if (parentList.Count > 0) + { + var titles = parentList.Select(it => it.Title).ToList();//提取出父级的name + var title = string.Join("- ", titles) + $"-{menu.Title}";//根据-分割,转换成字符串并在最后加上菜单的title + return title; + } + return menu.Title;//原路返回 + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/System/UserCenter/Dto/UserCenterInput.cs b/SimpleAdmin.System/Services/System/UserCenter/Dto/UserCenterInput.cs new file mode 100644 index 0000000..de4b0b1 --- /dev/null +++ b/SimpleAdmin.System/Services/System/UserCenter/Dto/UserCenterInput.cs @@ -0,0 +1,80 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 编辑个人信息参数 +/// +public class UpdateInfoInput : SysUser +{ + /// + /// 姓名 + /// + [Required(ErrorMessage = "Name不能为空")] + public override string Name { get; set; } +} + +public class UpdateSignatureInput +{ + /// + /// 签名图片 + /// + [Required(ErrorMessage = "Signature签名图片不能为空")] + public string Signature { get; set; } +} + +/// +/// 更新个人工作台 +/// +public class UpdateWorkbenchInput +{ + /// + /// 工作台数据 + /// + [Required(ErrorMessage = "WorkbenchData不能为空")] + public string WorkbenchData { get; set; } +} + +/// +/// 更新个人密码 +/// +public class UpdatePasswordInput +{ + /// + /// 密码 + /// + [Required(ErrorMessage = "Password不能为空")] + public string Password { get; set; } + + /// + /// 新密码 + /// + [Required(ErrorMessage = "NewPassword不能为空")] + public string NewPassword { get; set; } +} + +/// +/// 设置默认模块输入 +/// +public class SetDefaultModuleInput +{ + /// + /// 模块Id + /// + [Required(ErrorMessage = "Id不能为空")] + public long Id { get; set; } + + /// + /// 是否默认 + /// + [Required(ErrorMessage = "IfDefault不能为空")] + public bool IfDefault { get; set; } +} diff --git a/SimpleAdmin.System/Services/System/UserCenter/Dto/UserCenterOutput.cs b/SimpleAdmin.System/Services/System/UserCenter/Dto/UserCenterOutput.cs new file mode 100644 index 0000000..fb56f36 --- /dev/null +++ b/SimpleAdmin.System/Services/System/UserCenter/Dto/UserCenterOutput.cs @@ -0,0 +1,58 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 我的机构数样式 +/// +public class LoginOrgTreeOutput +{ + /// + /// Id + /// + public long Id { get; set; } + + /// + /// 名称 + /// + public string Label { get; set; } + + /// + /// 父ID + /// + public long Pid { get; set; } + + /// + /// 子节点 + /// + public List Children { get; set; } + + /// + /// 样式 + /// + public MyStyle? Style { get; set; } + + /// + /// 我的机构样式 + /// + public class MyStyle + { + /// + /// 背景色 + /// + public string Background { get; set; } = "var(--primary-color)"; + + /// + /// 字体颜色 + /// + public string Color { get; set; } = "#FFF"; + } +} diff --git a/SimpleAdmin.System/Services/System/UserCenter/IUserCenterService.cs b/SimpleAdmin.System/Services/System/UserCenter/IUserCenterService.cs new file mode 100644 index 0000000..d2123d6 --- /dev/null +++ b/SimpleAdmin.System/Services/System/UserCenter/IUserCenterService.cs @@ -0,0 +1,157 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System; + +/// +/// 个人信息中心服务 +/// +public interface IUserCenterService : ITransient +{ + #region 查询 + + /// + /// 获取登录用户菜单 + /// + /// + /// + Task> GetLoginMenu(BaseIdInput input); + + /// + /// 获取个人工作台 + /// + /// + Task GetLoginWorkbench(); + + /// + /// 获取组织架构 + /// + /// 组织架构 + Task> LoginOrgTree(); + + /// + /// 获取快捷菜单树 + /// + /// + Task> ShortcutTree(); + + /// + /// 读取登录用户站内信详情 + /// + /// + /// + Task LoginMessageDetail(MessageDetailInput input); + + /// + /// 获取登录用户的站内信分页 + /// + /// + /// + Task> LoginMessagePage(MessagePageInput input); + + #endregion 查询 + + #region 编辑 + + /// + /// 更新个人信息 + /// + /// 信息参数 + /// + Task UpdateUserInfo(UpdateInfoInput input); + + /// + /// 更新签名 + /// + /// 签名图片 + /// + Task UpdateSignature(UpdateSignatureInput input); + + /// + /// 编辑个人工作台 + /// + /// 工作台字符串 + /// + Task UpdateWorkbench(UpdateWorkbenchInput input); + + /// + /// 删除我的消息 + /// + /// 消息Id + /// + Task DeleteMyMessage(BaseIdInput input); + + /// + /// 修改个人密码 + /// + /// 密码信息 + /// + Task UpdatePassword(UpdatePasswordInput input); + + /// + /// 修改头像 + /// + /// 头像文件 + /// + Task UpdateAvatar(BaseFileInput input); + + /// + /// 修改默认模块 + /// + /// 默认模块输入参数 + /// + Task SetDefaultModule(SetDefaultModuleInput input); + + #endregion 编辑 + + #region 我的消息 + + /// + /// 获取登录用户的站内信分页 + /// + /// 查询参数 + /// 站内信列表 + Task> MyMessagePage(MessagePageInput input); + + /// + /// 读取登录用户站内信详情 + /// + /// 消息ID + /// 消息详情 + Task MyMessageDetail(BaseIdInput input); + + /// + /// 获取未读消息数量 + /// + /// 未读消息数量 + Task> UnReadCount(); + + /// + /// 最新未读消息 + /// + /// + Task> NewUnRead(); + + /// + /// 设置已读 + /// + /// + /// + Task SetRead(MessageReadInput input); + + /// + /// 删除我的消息 + /// + /// + /// + Task SetDelete(MessageReadInput input); + + #endregion +} diff --git a/SimpleAdmin.System/Services/System/UserCenter/UserCenterService.cs b/SimpleAdmin.System/Services/System/UserCenter/UserCenterService.cs new file mode 100644 index 0000000..f2e2c25 --- /dev/null +++ b/SimpleAdmin.System/Services/System/UserCenter/UserCenterService.cs @@ -0,0 +1,461 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using NewLife; +using System.Text.RegularExpressions; + +namespace SimpleAdmin.System; + +/// +public class UserCenterService : DbRepository, IUserCenterService +{ + private readonly ISysUserService _userService; + private readonly IRelationService _relationService; + private readonly IResourceService _resourceService; + private readonly IMenuService _menuService; + private readonly IConfigService _configService; + private readonly ISysOrgService _sysOrgService; + private readonly IMessageService _messageService; + + public UserCenterService(ISysUserService userService, IRelationService relationService, IResourceService resourceService, + IMenuService menuService, IConfigService configService, ISysOrgService sysOrgService, + IMessageService messageService) + { + _userService = userService; + _relationService = relationService; + _resourceService = resourceService; + _menuService = menuService; + _configService = configService; + _sysOrgService = sysOrgService; + _messageService = messageService; + } + + #region 查询 + + /// + public async Task> GetLoginMenu(BaseIdInput input) + { + var result = new List(); + //获取用户信息 + var userInfo = await _userService.GetUserByAccount(UserManager.UserAccount, UserManager.TenantId); + if (userInfo != null) + { + //定义菜单ID列表 + var menuIdList = new HashSet();//获取所有的菜单和模块以及单页面列表,并按分类和排序码排序 + var allModuleAndMenuAndSpaList = await _resourceService.GetMenuAndSpaListByModuleId(input.Id); + //通过 App.GetOptions 获取选项 + var settings = App.GetOptions(); + //如果设置了超级管理员可以看到全部 + if (settings.SuperAdminViewAllData && UserManager.SuperAdmin) + { + menuIdList = allModuleAndMenuAndSpaList.Select(it => it.Id).ToHashSet(); + } + else + { + //获取用户所拥有的资源集合 + var resourceList = + await _relationService.GetRelationListByObjectIdAndCategory(userInfo.Id, CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE); + if (resourceList.Count == 0)//如果没有就获取角色的 + //获取角色所拥有的资源集合 + resourceList = await _relationService.GetRelationListByObjectIdListAndCategory(userInfo.RoleIdList, + CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE); + //获取菜单Id集合 + menuIdList.AddRange(resourceList.Select(r => r.TargetId.ToLong()).ToList()); + } + var allMenuList = new List();//菜单列表 + var allSpaList = new List();//单页列表 + //遍历菜单集合 + allModuleAndMenuAndSpaList.ForEach(it => + { + switch (it.Category) + { + case CateGoryConst.RESOURCE_MENU://菜单 + allMenuList.Add(it);//添加到菜单列表 + break; + + case CateGoryConst.RESOURCE_SPA://单页 + allSpaList.Add(it);//添加到单页列表 + break; + } + }); + //获取我的菜单列表,只显示启用的 + var myMenus = allMenuList.Where(it => menuIdList.Contains(it.Id) && it.Status == CommonStatusConst.ENABLE).ToList(); + // 对获取到的角色对应的菜单列表进行处理,获取父列表 + var parentList = GetMyParentMenus(allMenuList, myMenus); + myMenus.AddRange(parentList);//合并列表 + // 遍历单页列表 + allSpaList.ForEach(it => + { + it.ParentId = SimpleAdminConst.ZERO; + }); + myMenus.AddRange(allSpaList);//单页添加到菜单 + //构建meta + ConstructMeta(myMenus); + //构建菜单树 + result = _menuService.ConstructMenuTrees(myMenus); + } + return result; + } + + /// + public async Task GetLoginWorkbench() + { + //获取个人工作台信息 + var sysRelation = await _relationService.GetWorkbench(UserManager.UserId); + if (sysRelation != null) + { + //如果有数据直接返回个人工作台 + return sysRelation.ExtJson.ToLower(); + } + //如果没数据去系统配置里取默认的工作台 + var devConfig = await _configService.GetByConfigKey(CateGoryConst.CONFIG_SYS_BASE, SysConfigConst.SYS_DEFAULT_WORKBENCH_DATA); + if (devConfig != null) + { + return devConfig.ConfigValue.ToLower();//返回工作台信息 + } + return ""; + } + + /// + public async Task> LoginOrgTree() + { + var orgList = await _sysOrgService.GetListAsync();//获取全部机构 + var parentOrgList = _sysOrgService.GetOrgParents(orgList, UserManager.OrgId);//获取父节点列表 + var topOrg = parentOrgList.Where(it => it.ParentId == SimpleAdminConst.ZERO).FirstOrDefault();//获取顶级节点 + if (topOrg != null) + { + var orgChildList = await _sysOrgService.GetChildListById(topOrg.Id);//获取下级 + var orgTree = ConstrucOrgTrees(orgChildList, 0, UserManager.OrgId);//获取组织架构 + return orgTree; + } + return new List(); + } + + + /// + public async Task> ShortcutTree() + { + var sysResourceList = await _resourceService.GetAllModuleAndMenuAndSpaList();//获取模块和菜单和单页列表 + var userInfo = await _userService.GetUserById(UserManager.UserId); + var hasResourcesList = new HashSet();//拥有的资源列表 + var hasModuleList = new HashSet();//拥有的资源列表 + var userResourceList = + (await _relationService.GetRelationListByObjectIdAndCategory(UserManager.UserId, CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE)) + .Select(it => it.TargetId.ToLong()).ToList();//获取用户资源id列表 + var userModuleList = + (await _relationService.GetRelationListByObjectIdAndCategory(UserManager.UserId, CateGoryConst.RELATION_SYS_USER_HAS_MODULE)) + .Select(it => it.TargetId.ToLong()).ToList();//获取用户模块id列表 + if (userResourceList.Count > 0)//如果用户资源列表大于0就以用户为主 + { + hasResourcesList.AddRange(userResourceList); + hasResourcesList.AddRange(userModuleList); + } + else + { + var roleIds = userInfo.RoleIdList;//获取角色ID列表 + var roleResourceList = + (await _relationService.GetRelationListByObjectIdListAndCategory(roleIds, CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE)) + .Select(it => it.TargetId.ToLong()).ToList();//获取角色资源id列表 + var roleModuleList = + (await _relationService.GetRelationListByObjectIdListAndCategory(roleIds, CateGoryConst.RELATION_SYS_ROLE_HAS_MODULE)) + .Select(it => it.TargetId.ToLong()).ToList();//获取角色模块id列表 + hasResourcesList.AddRange(roleResourceList); + hasResourcesList.AddRange(roleModuleList); + } + + // 获取目录 + var catalogList = sysResourceList.Where(it => it.MenuType == SysResourceConst.CATALOG).ToList(); + //过滤出拥有的资源列表 + sysResourceList = + sysResourceList.Where(it => + hasResourcesList.Contains(it.Id) || it.Category == CateGoryConst.RESOURCE_SPA) + .ToList();//获取拥有的资源列表 + var parentIds = sysResourceList.Select(it => it.ParentId).Distinct().ToList();//获取父ID列表 + var parentList = catalogList.Where(it => parentIds.Contains(it.Id)).ToList();//获取所拥有的父级目录 + sysResourceList.AddRange(parentList);//添加到列表 + return await _menuService.ShortcutTree(sysResourceList); + } + + /// + public async Task> LoginMessagePage(MessagePageInput input) + { + var messages = await _messageService.MyMessagePage(input, UserManager.UserId);//分页查询 + return messages; + } + + /// + public async Task LoginMessageDetail(MessageDetailInput input) + { + return await _messageService.Detail(input);//返回详情,不带用户列表 + } + + #endregion 查询 + + #region 编辑 + + /// + public async Task UpdateUserInfo(UpdateInfoInput input) + { + //如果手机号不是空 + if (!string.IsNullOrEmpty(input.Phone)) + { + if (!input.Phone.MatchPhoneNumber())//判断是否是手机号格式 + throw Oops.Bah("手机号码格式错误"); + input.Phone = CryptogramUtil.Sm4Encrypt(input.Phone); + var any = await IsAnyAsync(it => it.Phone == input.Phone && it.Id != UserManager.UserId);//判断是否有重复的 + if (any) + throw Oops.Bah("系统已存在该手机号"); + } + if (!string.IsNullOrEmpty(input.Email)) + { + var match = input.Email.MatchEmail(); + if (!match.isMatch) + throw Oops.Bah("邮箱格式错误"); + } + + //更新指定字段 + var result = await UpdateSetColumnsTrueAsync(it => new SysUser + { + Name = input.Name, + Email = input.Email, + Phone = input.Phone, + Nickname = input.Nickname, + Gender = input.Gender, + Birthday = input.Birthday + }, it => it.Id == UserManager.UserId); + if (result) + _userService.DeleteUserFromRedis(UserManager.UserId);//redis删除用户数据 + } + + /// + public async Task UpdateSignature(UpdateSignatureInput input) + { + var signatureArray = input.Signature.Split(",");//分割 + // var base64String = signatureArray[1];//根据逗号分割取到base64字符串 + // var image = base64String.GetSkBitmapFromBase64();//转成图片 + // var resizeImage = image.ResizeImage(100, 50);//重新裁剪 + // var newBase64String = resizeImage.ImgToBase64String();//重新转为base64 + // var newSignature = signatureArray[0] + "," + newBase64String;//赋值新的签名 + + //更新签名 + var result = await UpdateSetColumnsTrueAsync(it => new SysUser + { + Signature = input.Signature + }, it => it.Id == UserManager.UserId); + if (result) + _userService.DeleteUserFromRedis(UserManager.UserId);//redis删除用户数据 + } + + /// + public async Task UpdateWorkbench(UpdateWorkbenchInput input) + { + //关系表保存个人工作台 + await _relationService.SaveRelation(CateGoryConst.RELATION_SYS_USER_WORKBENCH_DATA, UserManager.UserId, null, input.WorkbenchData, + true); + } + + /// + public async Task DeleteMyMessage(BaseIdInput input) + { + await _messageService.DeleteMyMessage(input, UserManager.UserId); + } + + /// + public async Task UpdatePassword(UpdatePasswordInput input) + { + //获取用户信息 + var userInfo = await _userService.GetUserById(UserManager.UserId); + var password = CryptogramUtil.Sm2Decrypt(input.Password);//SM2解密 + if (userInfo.Password != password) throw Oops.Bah("原密码错误"); + var newPassword = CryptogramUtil.Sm2Decrypt(input.NewPassword);//sm2解密 + var loginPolicy = await _configService.GetConfigsByCategory(CateGoryConst.CONFIG_PWD_POLICY);//获取密码策略 + var containNumber = loginPolicy.First(it => it.ConfigKey == SysConfigConst.PWD_CONTAIN_NUM).ConfigValue.ToBoolean();//是否包含数字 + var containLower = loginPolicy.First(it => it.ConfigKey == SysConfigConst.PWD_CONTAIN_LOWER).ConfigValue.ToBoolean();//是否包含小写 + var containUpper = loginPolicy.First(it => it.ConfigKey == SysConfigConst.PWD_CONTAIN_UPPER).ConfigValue.ToBoolean();//是否包含大写 + var containChar = loginPolicy.First(it => it.ConfigKey == SysConfigConst.PWD_CONTAIN_CHARACTER).ConfigValue.ToBoolean();//是否包含特殊字符 + var minLength = loginPolicy.First(it => it.ConfigKey == SysConfigConst.PWD_MIN_LENGTH).ConfigValue.ToInt();//最小长度 + if (minLength > newPassword.Length) + throw Oops.Bah($"密码长度不能小于{minLength}"); + if (containNumber && !Regex.IsMatch(newPassword, "[0-9]")) + throw Oops.Bah("密码必须包含数字"); + if (containLower && !Regex.IsMatch(newPassword, "[a-z]")) + throw Oops.Bah("密码必须包含小写字母"); + if (containUpper && !Regex.IsMatch(newPassword, "[A-Z]")) + throw Oops.Bah("密码必须包含大写字母"); + if (containChar && !Regex.IsMatch(newPassword, "[~!@#$%^&*()_+`\\-={}|\\[\\]:\";'<>?,./]")) + throw Oops.Bah("密码必须包含特殊字符"); + // var similarity = PwdUtil.Similarity(password, newPassword); + // if (similarity > 80) + // throw Oops.Bah($"新密码请勿与旧密码过于相似"); + newPassword = CryptogramUtil.Sm4Encrypt(newPassword);//SM4加密 + userInfo.Password = newPassword; + await UpdateSetColumnsTrueAsync(it => new SysUser { Password = newPassword }, it => it.Id == userInfo.Id);//更新密码 + _userService.DeleteUserFromRedis(UserManager.UserId);//redis删除用户数据 + } + + /// + public async Task UpdateAvatar(BaseFileInput input) + { + var userInfo = await _userService.GetUserById(UserManager.UserId); + + var file = input.File; + using var fileStream = file.OpenReadStream();//获取文件流 + var bytes = new byte[fileStream.Length]; + fileStream.Read(bytes, 0, bytes.Length); + fileStream.Close(); + var base64String = Convert.ToBase64String(bytes);//转base64 + var avatar = base64String.ToImageBase64();//转图片 + await UpdateSetColumnsTrueAsync(it => new SysUser { Avatar = avatar }, it => it.Id == userInfo.Id);// 更新头像 + _userService.DeleteUserFromRedis(UserManager.UserId);//redis删除用户数据 + return avatar; + } + + /// + public async Task SetDefaultModule(SetDefaultModuleInput input) + { + //获取用户信息 + var userInfo = await _userService.GetUserById(UserManager.UserId); + //如果是默认模块 + if (input.IfDefault) + userInfo.DefaultModule = input.Id; + else + userInfo.DefaultModule = null; + await Context.Updateable(userInfo).UpdateColumns(it => new { it.DefaultModule }).ExecuteCommandAsync();//修改默认模块 + _userService.DeleteUserFromRedis(UserManager.UserId);//redis删除用户数据 + } + + #endregion 编辑 + + #region 我的消息 + + /// + public async Task> MyMessagePage(MessagePageInput input) + { + var messages = await _messageService.MyMessagePage(input, UserManager.UserId);//分页查询 + return messages; + } + + /// + public async Task MyMessageDetail(BaseIdInput input) + { + return await _messageService.Detail(new MessageDetailInput { Id = input.Id, Read = true });//返回详情,不带用户列表 + } + + /// + public async Task> UnReadCount() + { + return await _messageService.UnReadCount(UserManager.UserId); + } + + /// + public async Task> NewUnRead() + { + return await _messageService.NewUnRead(UserManager.UserId); + } + + + /// + public async Task SetRead(MessageReadInput input) + { + return await _messageService.SetRead(input); + } + + /// + public async Task SetDelete(MessageReadInput input) + { + return await _messageService.SetDelete(input); + } + + #endregion + + #region 方法 + + /// + /// 获取父菜单集合 + /// + /// 所有菜单列表 + /// 我的菜单列表 + /// + private List GetMyParentMenus(List allMenuList, List myMenus) + { + var parentList = new List(); + myMenus.ForEach(it => + { + var parents = _resourceService.GetResourceParent(allMenuList, it.ParentId.Value);//获取父级 + parents.ForEach(parent => + { + // 如果父级菜单存在,并且父级菜单状态为启用,并不在父级列表中,则添加到父级列表 + if (parent != null && parent.Status == CommonStatusConst.ENABLE && !parentList.Contains(parent) + && !myMenus.Contains(parent)) + { + parentList.Add(parent);//添加到父列表 + } + }); + }); + return parentList; + } + + /// + /// 构建Meta + /// + /// 我的菜单集合 + private void ConstructMeta(List myMenus) + { + myMenus.ForEach(it => + { + //定义meta + var meta = new Meta + { + Icon = it.Icon, + Title = it.Title, + IsAffix = it.IsAffix, + IsHide = it.IsHide, + IsKeepAlive = it.IsKeepAlive, + IsFull = it.IsFull, + ActiveMenu = it.ActiveMenu, + IsLink = it.IsLink + }; + it.Meta = meta; + }); + } + + /// + /// 构建机构树 + /// + /// 机构列表 + /// 父ID + /// 用户ID + /// + public List ConstrucOrgTrees(List orgList, long parentId, long orgId) + { + //找下级字典ID列表 + var orgParents = orgList.Where(it => it.ParentId == parentId).OrderBy(it => it.SortCode).ToList(); + if (orgParents.Count > 0)//如果数量大于0 + { + var data = new List(); + foreach (var item in orgParents)//遍历字典 + { + var loginOrg = new LoginOrgTreeOutput + { + Children = ConstrucOrgTrees(orgList, item.Id, orgId),//添加子节点 + Id = item.Id, + Label = item.Name, + Pid = item.ParentId, + Style = orgId != item.Id ? null : new LoginOrgTreeOutput.MyStyle() + }; + data.Add(loginOrg);//添加到列表 + } + return data;//返回结果 + } + return new List(); + } + + #endregion 方法 +} diff --git a/SimpleAdmin.System/Services/Upload/IUploadService.cs b/SimpleAdmin.System/Services/Upload/IUploadService.cs new file mode 100644 index 0000000..6aaf277 --- /dev/null +++ b/SimpleAdmin.System/Services/Upload/IUploadService.cs @@ -0,0 +1,16 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System.Services.Upload; + +public class IUploadService +{ + +} diff --git a/SimpleAdmin.System/Services/Upload/UploadService.cs b/SimpleAdmin.System/Services/Upload/UploadService.cs new file mode 100644 index 0000000..b6ed87d --- /dev/null +++ b/SimpleAdmin.System/Services/Upload/UploadService.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.System.Services.Upload; + +public class UploadService : IUploadService +{ +} diff --git a/SimpleAdmin.System/SimpleAdmin.System.csproj b/SimpleAdmin.System/SimpleAdmin.System.csproj new file mode 100644 index 0000000..3e50797 --- /dev/null +++ b/SimpleAdmin.System/SimpleAdmin.System.csproj @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + + + + diff --git a/SimpleAdmin.System/SimpleAdmin.System.xml b/SimpleAdmin.System/SimpleAdmin.System.xml new file mode 100644 index 0000000..a1c6113 --- /dev/null +++ b/SimpleAdmin.System/SimpleAdmin.System.xml @@ -0,0 +1,8581 @@ + + + + SimpleAdmin.System + + + + + 前端表格特性 + + + + + 是否是日期格式 + + + + + 是否自动省略 + + + + + 宽度 + + + + + 批量更新 + + + + + 验证值是否在字典中,大数据慎用 + + + + + 字典值 + + + + + 获取错误信息 + + 值 + + + + + 分类常量 + + + + + 系统基础 + + + + + 登录策略 + + + + + 密码策略 + + + + + 业务定义 + + + + + 文件-本地 + + + + + 文件-MINIO + + + + + MQTT配置 + + + + + 用户有哪些角色 + + + + + 角色有哪些资源 + + + + + 角色有哪些模块 + + + + + 用户有哪些模块 + + + + + 用户有哪些资源 + + + + + 角色有哪些权限 + + + + + 用户有哪些权限 + + + + + 用户工作台数据 + + + + + 用户日程数据 + + + + + 站内信与接收用户 + + + + + 本人 + + + + + 所有 + + + + + 仅所属组织 + + + + + 所属组织及以下 + + + + + 自定义 + + + + + 模块 + + + + + 菜单 + + + + + 单页 + + + + + 按钮 + + + + + 登录 + + + + + 登出 + + + + + 操作 + + + + + 异常 + + + + + 框架 + + + + + 业务 + + + + + 部门 + + + + + 公司 + + + + + 高层 + + + + + 中层 + + + + + 基层 + + + + + 全局 + + + + + 机构 + + + + + 通知 + + + + + 公告 + + + + + 是 + + + + + 否 + + + + + 压缩包 + + + + + 项目中 + + + + + 全部 + + + + + 前端 + + + + + 后端 + + + + + 系统配置常量 + + + + + 系统名称 + + + + + ico图标 + + + + + 网站开启访问 + + + + + 网站关闭提示 + + + + + 系统logo + + + + + 系统版本 + + + + + 多租户开关 + + + + + 系统默认工作台 + + + + + 登录验证码开关 + + + + + 登录验证码开关 + + + + + 单用户登录开关 + + + + + 登录错误锁定时长 + + + + + 登录错误锁定时长 + + + + + 登录错误次数 + + + + + 默认用户密码 + + + + + 密码定期提醒更新 + + + + + 密码定期提醒更新时间 + + + + + 修改初始密码提醒 + + + + + 密码最小长度 + + + + + 包含数字 + + + + + 包含小写字母 + + + + + 包含大写字母 + + + + + 包含特殊字符 + + + + + windows系统本地目录 + + + + + Unix系统本地目录 + + + + + MINIO文件AccessKey + + + + + MINIO文件SecretKey + + + + + MINIO文件EndPoint + + + + + MINIO文件默认存储桶 + + + + + mqtt连接地址 + + + + + mqtt连接用户名 + + + + + mqtt连接密码 + + + + + 字典常量 + + + + + 性别 + + + + + 名族 + + + + + 用户证件类型 + + + + + 通用文化程度 + + + + + 系统职位分类 + + + + + 在线 + + + + + 离线 + + + + + 本地 + + + + + MINIO + + + + + 系统 + + + + + 业务 + + + + + 关闭 + + + + + 手动选择 + + + + + 根据域名 + + + + + 消息分类 + + + + + 接受者类型 + + + + + 发送方式 + + + + + 立即发送 + + + + + 延迟发送 + + + + + 指定时间 + + + + + 待发送 + + + + + 已发送 + + + + + 所有 + + + + + 角色 + + + + + 指定 + + + + + 日志常量 + + + + + 成功 + + + + + 成功 + + + + + 资源表常量 + + + + + 目录 + + + + + 菜单 + + + + + 内链 + + + + + 子页 + + + + + 外链 + + + + + 单页 + + + + + 系统内置单页面编码 + + + + + 角色常量 + + + + + 超级管理员 + + + + + 业务管理员 + + + + + 系统层常量 + + + + + 系统配置表缓存Key + + + + + 登录验证码缓存Key + + + + + 用户表缓存Key + + + + + 用户头像缓存关系Key + + + + + 用户手机号关系缓存Key + + + + + 用户手机号关系缓存Key + + + + + 资源表缓存Key + + + + + 字典表缓存Key + + + + + 关系表缓存Key + + + + + 机构表缓存Key + + + + + 机构对应租户关系缓存Key + + + + + 租户列表缓存 + + + + + 角色表缓存Key + + + + + 职位表缓存Key + + + + + 登录错误次数缓存Key + + + + + 添加操作 + + + + + 编辑操作 + + + + + 启用操作 + + + + + 禁用操作 + + + + + 重置密码操作 + + + + + 用户授权操作 + + + + + 组织 + + + + + 职位 + + + + + 批量修改 + + + + + 唯一编码 + + + + + 所属库 + + + + + 实体名 + + + + + 表名 + + + + + 表描述 + + + + + 批量修改配置表 + + + + + 批量配置Id + + + + + 字段名 + + + + + 字段描述 + + + + + 作用类型 + + + + + 字典值 + + + + + 数据库类型 + + + + + 接口名称 + + + + + 接口类型 + + + + + 接口结果标签 + + + + + 接口结果值 + + + + + 启用状态 + + + + + C端用户 + + + + + 头像 + + + + + 签名 + + + + + 账号 + + + + + 密码 + + + + + 姓名 + + + + + 昵称 + + + + + 性别 + + + + + 年龄 + + + + + 出生日期 + + + + + 民族 + + + + + 籍贯 + + + + + 家庭住址 + + + + + 通信地址 + + + + + 证件类型 + + + + + 证件号码 + + + + + 文化程度 + + + + + 政治面貌 + + + + + 毕业院校 + + + + + 学历 + + + + + 学制 + + + + + 学位 + + + + + 手机 + + + + + 邮箱 + + + + + 家庭电话 + + + + + 办公电话 + + + + + 紧急联系人 + + + + + 紧急联系人电话 + + + + + 紧急联系人地址 + + + + + 员工编号 + + + + + 入职日期 + + + + + 机构id + + + + + 职位id + + + + + 职级 + + + + + 主管id + + + + + 兼任信息 + + + + + 上次登录ip + + + + + 上次登录地点 + + + + + 上次登录时间 + + + + + 上次登录设备 + + + + + 最新登录ip + + + + + 最新登录地点 + + + + + 最新登录时间 + + + + + 最新登录设备 + + + + + 用户状态 + + + + + 排序码 + + + + + 代码生成基础 + + + + + 所属库 + + + + + 主表 + + + + + 表实体名称 + + + + + 功能列表 + + + + + 数据权限 + + + + + 生成模版 + + + + + 树Id字段 + + + + + 树父Id字段 + + + + + 树名称字段 + + + + + 关联子表名 + + + + + 关联子表外键 + + + + + 移除表前缀 + + + + + 生成方式 + + + + + 所属模块 + + + + + 上级目录 + + + + + 业务名 + + + + + 图标 + + + + + 功能名 + + + + + 功能名后缀 + + + + + 业务名 + + + + + 类名 + + + + + 表单布局 + + + + + 使用栅格 + + + + + 左侧树 + + + + + 前端项目路径 + + + + + 服务代码存放项目 + + + + + 服务代码存放文件夹 + + + + + 控制器代码存放位置 + + + + + 控制器代码存放文件夹 + + + + + 作者 + + + + + 排序 + + + + + 功能列表 + + + + + 代码生成配置 + + + + + 基础ID + + + + + 字段排序 + + + + + 是否主键 + + + + + 字段 + + + + + 名称 + + + + + 类型 + + + + + 实体类型 + + + + + 作用类型 + + + + + 外键显示字段 + + + + + 外键ID + + + + + 外键显示字段 + + + + + 字典 + + + + + 列宽度 + + + + + 列表显示 + + + + + 列省略 + + + + + 可伸缩列 + + + + + 是否增改 + + + + + 是否导入导出 + + + + + 必填 + + + + + 查询 + + + + + 查询方式 + + + + + 排序 + + + + + 字段名首字母小写 + + + + + 字段名首字母大写 + + + + + 配置 + + + + + 配置键 + + + + + 配置值 + + + + + 分类 + + + + + 备注 + + + + + 排序码 + + + + + 字典 + + + + + 父id + + + + + 字典文字 + + + + + 字典值 + + + + + 分类 + + + + + 排序码 + + + + + 子节点 + + + + + 文件表 + + + + + 存储引擎 + + + + + 存储桶 + + + + + 文件名称 + + + + + 文件后缀 + + + + + 文件大小kb + + + + + 文件大小(格式化后) + + + + + 文件的对象名(唯一名称) + + + + + 文件存储路径 + + + + + 文件下载路径 + + + + + 图片缩略图 + + + + + 操作日志表 + + + + + 具体消息 + + + + + 类名称 + + + + + 方法名称 + + + + + 请求方式 + + + + + 请求地址 + + + + + 请求参数 + + + + + 返回结果 + + + + + 访问日志表 + + + + + 日志分类 + + + + + 日志名称 + + + + + 执行状态 + + + + + 操作ip + + + + + 操作地址 + + + + + 操作浏览器 + + + + + 操作系统 + + + + + 操作时间 + + + + + 操作人姓名 + + + + + 操作人姓名 + + + + + 站内信 + + + + + 分类 + + + + + 主题 + + + + + 接收人类型 + + + + + 接收人列表 + + + + + 发送方式 + + + + + 发送时间 + + + + + 正文 + + + + + 延迟时间(秒) + + + + + 已读情况 + + + + + 发送时间格式化 + + + + + 分组查询用 + + + + + 是否已读 + + + + + ID + + + + + 名称 + + + + + ID + + + + + 名称 + + + + + 是否已读 + + + + + 用户消息表 + + + + + 消息Id + + + + + 用户Id + + + + + 已读未读 + + + + + 组织 + + + + + 父id + + + + + 主管ID + + + + + 名称 + + + + + 全称 + + + + + 编码 + + + + + 分类 + + + + + 排序码 + + + + + 主管信息 + + + + + 子节点 + + + + + 设置为叶子节点(设置了loadData时有效) + + + + + 职位表 + + + + + 组织id + + + + + 名称 + + + + + 编码 + + + + + 分类 + + + + + 排序码 + + + + + 系统关系表 + + + + + 对象ID + + + + + 目标ID + + + + + 分类 + + + + + 资源 + + + + + 父id + + + + + 标题 + + + + + 别名 + + + + + 描述 + + + + + 编码 + + + + + 分类 + + + + + 模块 + + + + + 菜单类型 + + + + + 路径 + + + + + 组件 + + + + + 图标 + + + + + 是否在菜单中隐藏, 需要高亮的 path (通常用作详情页高亮父级菜单) + + + + + 是否在菜单中隐藏 (通常列表详情页需要隐藏) + + + + + 是否在菜单中隐藏 (通常列表详情页需要隐藏) + + + + + 菜单是否固定在标签页中 (首页通常是固定项) + + + + + 菜单是否固定在标签页中 (首页通常是固定项) + + + + + 是否为首页 + + + + + 排序码 + + + + + 外链地址 + + + + + 菜单元标签 + + + + + 子节点 + + + + + 菜单元标签 + + + + + 图标 + + + + + 标题 + + + + + 是否在菜单中隐藏, 需要高亮的 path (通常用作详情页高亮父级菜单) + + + + + 是否在菜单中隐藏 (通常列表详情页需要隐藏) + + + + + 路由外链时填写的访问地址 + + + + + 是否在菜单中隐藏 (通常列表详情页需要隐藏) + + + + + 菜单是否固定在标签页中 (首页通常是固定项) + + + + + 菜单是否固定在标签页中 (首页通常是固定项) + + + + + 角色 + + + + + 组织id + + + + + 名称 + + + + + 编码 + + + + + 分类 + + + + + 默认数据范围 + + + + + 排序码 + + + + + 用户列表 + + + + + 默认数据范围 + + + + + 数据范围等级 + + + + + 数据范围 + + + + + 自定义机构范围列表 + + + + + 用户信息表 + + + + + 头像 + + + + + 签名 + + + + + 账号 + + + + + 密码 + + + + + 姓名 + + + + + 昵称 + + + + + 性别 + + + + + 出生日期 + + + + + 民族 + + + + + 籍贯 + + + + + 家庭住址 + + + + + 通信地址 + + + + + 证件类型 + + + + + 证件号码 + + + + + 文化程度 + + + + + 政治面貌 + + + + + 毕业院校 + + + + + 学历 + + + + + 学制 + + + + + 学位 + + + + + 手机 + 这里使用了SM4自动加密解密 + + + + + 邮箱 + + + + + 家庭电话 + + + + + 办公电话 + + + + + 紧急联系人 + + + + + 紧急联系人电话 + + + + + 紧急联系人地址 + + + + + 员工编号 + + + + + 入职日期 + + + + + 机构id + + + + + 职位id + + + + + 职级 + + + + + 主管id + + + + + 上次修改密码时间 + + + + + 上次登录ip + + + + + 上次登录地点 + + + + + 上次登录时间 + + + + + 上次登录设备 + + + + + 最新登录ip + + + + + 最新登录地点 + + + + + 最新登录时间 + + + + + 最新登录设备 + + + + + 排序码 + + + + + 默认模块 + + + + + 机构信息 + + + + + 机构信息全称 + + + + + 职位信息 + + + + + 组织和机构ID列表,组织ID从上到下最后是职位 + + + + + 主管信息 + + + + + 按钮码集合 + + + + + 权限码集合 + + + + + 角色码集合 + + + + + 角色ID集合 + + + + + 数据范围集合 + + + + + 默认数据范围 + + + + + 机构及以下机构ID集合 + + + + + 机构及以下机构ID集合 + + + + + 租户Id + + + + + 数据范围类 + + + + + API接口 + + + + + 数据范围分类 + + + + + 数据范围的机构ID列表 + + + + + 认证模块事件总线 + + + + + 登录事件 + + + + + + + 登出事件 + + + + + + + 解析IP地址 + + ip地址 + + + + + 事件总线常量 + + + + + B端登录 + + + + + B端登录 + + + + + 清除用户缓存 + + + + + 清除组织下用户Token + + + + + 清除模块下用户Token + + + + + 通知用户下线 + + + + + 新消息 + + + + + 登录事件参数 + + + + + 请求上下文 + + + + + 用户信息 + + + + + Ip地址 + + + + + 登录设备 + + + + + Tokens + + + + + 过期时间 + + + + + 时间 + + + + + 用户登出事件 + + + + + 用户Id + + + + + token信息 + + + + + 内容 + + + + + 新消息事件 + + + + + 消息Id + + + + + 发送方式 + + + + + 发送时间 + + + + + 通知事件总线 + + + + + 通知用户下线事件 + + + + + + + 有新的消息 + + + + + + + 发送消息 + + 消息id + 延迟 + + + + 获取服务 + + + + + + + 用户模块事件总线 + + + + + 根据角色ID列表清除用户缓存 + + + + + + + 根据机构ID列表清除用户token + + + + + + 根据模块ID列表清除用户token + + + + + + 站内信与接收用户拓展 + MSG_TO_USER + + + + + 是否已读 + + + + + SYS_ROLE_HAS_PERMISSION + 角色权限关系扩展 + + + + + 数据范围 + + + + + 自定义机构范围列表 + + + + + 接口Url + + + + + SYS_ROLE_HAS_RESOURCE + 角色有哪些资源扩展 + + + + + 菜单ID + + + + + 按钮信息 + + + + + SYS_USER_SCHEDULE_DATA + 用户日程扩展 + + + + + 日程日期 + + + + + 日程时间 + + + + + 日程内容 + + + + + 用户id + + + + + 用户姓名 + + + + + SYS_USER_WORKBENCH_DATA + 用户工作台扩展 + + + + + 快捷方式列表 + + + + + 工作台快捷方式信息 + + + + + id + + + + + 标题 + + + + + 图标 + + + + + 路由地址 + + + + + 对象映射 + + + + + 系统配置 + + + + + 超级管理员可以看到全部数据 + + + + + 启用通知中心 + + + + + Minio功能类 + + + + + 初始化操作 + + + + + + 上传文件 - 返回Minio文件完整Url + + 存储桶里的对象名称,例:/mnt/photos/island.jpg + 文件 + 文件的Content type,默认是"application/octet-stream" + + + + + 下载文件 + + + + + + + 系统配置种子数据 + + + + + 系统配置种子数据 + + + + + 系统配置种子数据 + + + + + 字典表种子数据 + + + + + 机构种子数据 + + + + + 职位表种子数据 + + + + + 关系表种子数据 + + + + + 资源表种子数据 + + + + + 角色种子数据 + + + + + 用户表种子数据 + + + + + + + + + + + + + + + + + + + + + + + + + + 检查验证码 + + + + + + + 检查网站是否开启 + + + + + + + 登录之前执行的方法 + + + + + + + + 登录错误操作 + + + + + + + + 校验验证码方法 + + 验证码 + 请求号 + 是否从Redis删除 + + + + 从Redis中删除验证码 + + + + + + 校验手机验证码 + + 输入参数 + 登录端类型 + 是否删除 + + + + + 添加验证码到缓存 + + 验证码 + 过期时间 + 验证码请求号 + + + + 执行B端登录 + + 用户信息 + 登录设备 + 登录类型 + 租户id + + + + + 写入用户token到缓存 + + 登录事件参数 + 登录类型 + + + + 缓存删除用户token + + 登录事件参数 + 登录类型 + + + + 获取用户token列表 + + 用户ID + token列表 + + + + 单用户登录通知用户下线 + + 用户ID + Token列表 + + + + 权限认证输入 + + + + + 验证码 + + + + + 请求号 + + + + + 登录输入参数 + + + + + 账号 + + superAdmin + + + + 密码 + + 04fc514b346f14b23d7cf5e6f64663b030512aa380a9e7d311288ed1e8be7b863ae5ee0bb570df2405fc9daff2b2d1ac627a0fbbd49ef2c6b8fac4fd5e4b9a1b7120999bdc0a8e425aa37abab3aec6f9f3570775ff901f2845e957b0c2d0542e21fbf1bbb65c04 + + + + 设备类型,默认PC + + 0 + + + + 租户ID + + + + + 登出输入参数 + + + + + token + + + + + 获取短信验证码输入 + + + + + 手机号 + + + + + 手机号登录输入 + + + + + 设备类型,默认PC + + 0 + + + + 租户ID + + + + + 验证码返回 + + + + + 验证码图片,Base64 + + + + + 验证码请求号 + + + + + 登录返回参数 + + + + + 令牌Token + + + + + 账号 + + + + + 姓名 + + + + + 默认模块 + + + + + 模块列表 + + + + + 登录用互信息 + + + + + 头像 + + + + + 签名 + + + + + 账号 + + + + + 姓名 + + + + + 昵称 + + + + + 手机号 + + + + + 生日 + + + + + 邮箱 + + + + + 性别 + + + + + 家庭住址 + + + + + 机构信息 + + + + + 机构信息全称 + + + + + 职位信息 + + + + + 角色码集合 + + + + + 按钮码集合 + + + + + 机构及以下机构ID集合 + + + + + 默认模块 + + + + + 权限校验服务 + + + + + 获取图形验证码 + + + + + + 获取登录用户信息 + + + + + + 获取手机短信验证码 + + 验证码参数 + 登录类型 + + + + + 登录 + + 登录参数 + 登录类型 + Token信息 + + + + 手机号登录 + + 登录参数 + 登录端类型 + Token信息 + + + + 退出登录 + + token + 登出类型 + + + + + 会话分页查询 + + + + + 账号 + + + + + 姓名 + + + + + 最新登录ip + + + + + Token退出参数 + + + + + token + + + + + 会话输出 + + + + + 主键Id + + + + + 头像 + + + + + 账号 + + + + + 姓名 + + + + + 在线状态 + + + + + 最新登录ip + + + + + 最新登录地点 + + + + + 最新登录时间 + + + + + 令牌数量 + + + + + 令牌信息集合 + + + + + 会话统计结果 + + + + + 当前会话总数量 + + + + + 最大签发令牌数 + + + + + 在线用户数 + + + + + BC端会话比例 + + + + + 会话管理服务 + + + + + 会话统计 + + 统计结果 + + + + 强退会话 + + 用户ID + + + + 强退token + + token列表 + + + + B端会话分页查询 + + 查询参数 + B端会话列表 + + + + C端会话分页查询 + + 查询参数 + C端会话列表 + + + + + + + + + + + + + + + + + + + + + + + + 获取redis中token信息列表 + + + + + + 获取token剩余时间信息 + + token列表 + 登录类型 + + + + 通知用户下线 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 获取配置 + + + + + + 检查输入参数 + + + + + + 批量分页查询参数 + + + + + 唯一编码 + + + + + 所属库 + + + + + 实体名 + + + + + 表名 + + + + + 添加批量参数 + + + + + 唯一编码 + + + + + 所属库 + + + + + 实体名 + + + + + 表名 + + + + + 表描述 + + + + + 修改批量参数 + + + + + Id + + + + + 批量修改输入 + + + + + 批量编辑Code + + + + + Id列表 + + + + + 字段列表 + + + + + 批量修改DTO + + + + + 批量服务 + + + + + 批量分页查询 + + 查询参数 + 分页结果 + + + + 添加批量 + + 添加参数 + + + + + 删除批量 + + 删除参数 + + + + + 获取需要批量修改的表 + + + + + + 获取批量修改配置 + + + + + + + 配置字段 + + 字段信息 + + + + + 批量配置字段列表 + + 唯一编码 + 列表 + + + + 获取字典配置 + + 唯一编码 + 字段信息 + SqlSugar对应字典 + + + + 同步字段 + + id + + + + + 文件分页输出 + + + + + 文件引擎 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 存储文件 + + + + + + + 存储本地文件 + + + + + + + 存储到minio + + + + + + + + 获取文件大小 + + + + + + + 判断是否是图片 + + 后缀名 + + + + + 文件管理服务 + + + + + 删除文件 + + ID列表 + + + + + 文件下载 + + 文件iD + 文件流 + + + + 获取FileStreamResult文件流 + + 路径 + 文件名 + 路径是否是文件夹 + + + + + 获取FileStreamResult文件流 + + 文件数组 + 文件名 + + + + + 文件分页查询 + + 查询参数 + 文件列表 + + + + 上传文件到本地返回下载url + + 文件引擎 + 文件 + + + + + 站内信分类 + + + + + 发送参数 + + + + + 主题 + + + + + 分类 + + + + + 接收人Id + + + + + 消息Id + + + + + 消息详情输入参数 + + + + + 是否显示接收信息 + + + + + 是否已读 + + + + + 已读输入参数 + + + + + 分类 + + + + + 用户Id + + + + + 消息Id + + + + + 消息详情 + + + + + 未读消息数量输出 + + + + + 未读消息数量 + + + + + 分类 + + + + + 站内信服务 + + + + + 删除消息 + + id列表 + + + + + 删除我的消息 + + + + + + + + 获取消息详情 + + 输入参数 + 消息详情 + + + + 我的消息列表 + + + + + + + + 分页查询 + + 查询参数 + + + + + 获取未读消息数 + + 用户Id + + + + + 最新未读 + + + + + + + 标记已读 + + + + + + + 删除消息 + + + + + + + 新增 + + + + + + + 编辑 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入 + + + + + + 代码生成基础添加参数 + + + + + 所属库名称 + + + + + 主表名称 + + + + + 功能列表 + + + + + 生成模版 + + + + + 数据权限 + + + + + 实体名称 + + + + + 表前缀移除 + + + + + 生成方式 + + + + + 所属模块 + + + + + 路由名 + + + + + 图标 + + + + + 功能名 + + + + + 业务名 + + + + + 类名 + + + + + 表单布局 + + + + + 使用栅格 + + + + + 左侧树 + + + + + 前端路径 + + + + + 服务层 + + + + + 控制器层 + + + + + 排序 + + + + + 作者名 + + + + + 代码生成基础编辑参数 + + + + + 执行代码生成参数 + + + + + 生成类型 + + + + + 表字段信息输出 + + + + + 字段名称 + + + + + 是否主键 + + + + + 字段类型 + + + + + 字段注释 + + + + + 预览代码生成结果 + + + + + SQL代码结果集 + + + + + 前端代码结果集 + + + + + 后端代码结果集 + + + + + 代码文件名称 + + + + + 文件路径 + + + + + 代码文件内容 + + + + + 代码生成绑定视图 + + + + + 生成时间 + + + + + 表字段 + + + + + 菜单ID + + + + + 菜单编码 + + + + + /菜单路径 + + + + + /菜单路径 + + + + + 添加按钮ID + + + + + 批量删除按钮ID + + + + + 编辑按钮ID + + + + + 删除按钮ID + + + + + 类名首字母小写 + + + + + swagger分组名称 + + + + + 服务名 + + + + + 服务名开头首字母小写 + + + + + 分页查询 + + + + + 列表查询 + + + + + 添加 + + + + + 修改 + + + + + 修改 + + + + + 详情 + + + + + 导入 + + + + + 导入模板下载 + + + + + 导入预览 + + + + + 导入 + + + + + 批量编辑 + + + + + 树查询 + + + + + 分页参数 + + + + + 添加参数 + + + + + 编辑参数 + + + + + 树查询参数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 生成后端代码文件 + + 后端代码模板 + 代码基础 + 后端生成路径 + 是否是zip方式 + + + + 生成前端代码文件 + + 前端代码模板 + 前端生成路径 + + + + 生成sql代码文件 + + 后端代码模板 + 生成路径 + + + + 获取sql代码预览结果 + + 视图 + 模板路径 + + + + + 获取后端代码预览结果 + + 视图 + 模板路径 + + + + + 获取前端代码预览结果 + + 视图 + 模板路径 + + + + + 获取代码生成视图 + + + + + + + 视图渲染 + + 模板内容 + 参数 + + + + + 获得文件夹下所有的文件 + + 文件夹路径 + + + + + 代码生成预览 + + 基础配置 + + + + + 获取代码生成基础 + + + + + + + 创建代码生成相关的菜单按钮和授权关系 + + + + + + + 代码生成基础服务 + + + + + 添加代码生成器基础 + + + + + + + 删除代码生成配置 + + ID列表 + + + + + 编辑代码生成基础配置 + + + 代码生产基础 + + + + 执行代码生成:本地 + + + + + + + 执行代码生成:压缩包 + + + + + + + 获取项目所有程序集 + + 程序集列表 + + + + 获取表信息 + + 是否所有表 + 实体表列表 + + + + 获取代码生成基础分页 + + 查询参数 + 代码生成基础分页列表 + + + + 代码生成预览 + + 代码生成基础Id + 预览结果 + + + + + + + + + + + + + + + 代码生成详细配置服务 + + + + + 批量更新 + + + + + + + 查询代码生成详细配置列表 + + + 配置列表 + + + + 导入预览输入 + + + + + 文件导入通用输出 + + + + + 是否有错误 + + + + + 动态表头 + + + + + 数据 + + + + + 动态表头 + + + + + 标题 + + + + + 数据源 + + + + + 宽度 + + + + + 超过宽度将自动省略 + + + + + 是否是日期格式 + + + + + 批量导入结果输入 + + + + + + 数据 + + + + + 导入结果输出 + + + + + 是否成功 + + + + + 总数 + + + + + 导入数量 + + + + + 错误数 + + + + + 数据 + + + + + 导入基础输入 + + + + + Id + + + + + 是否有错误 + + + + + 错误详情 + + + + + 导入服务 + + + + + 导出数据 + + + 数据 + 文件名 + 文件流 + + + + 获取本地模板 + + 文件名 + 模板文件夹路径:默认wwwroot下的Template + 文件流 + + + + 生成模板 + + 实体类 + 文件名 + 文件流 + + + + 获取导入预览 + + + 文件 + 导入预览结果 + + + + 获取预计导入结果 + + + 数据 + 成功导入数据 + 预计导入结果 + + + + 导入文件验证 + + 文件 + 文件最大体积(M) + 允许的格式 + + + + 模板数据验证 + + 模板类实体 + 结果 + 导入预览数据 + + + + + + + + + + + + + + + + + + + + + + + + + + + 获取文件流 + + + + + + + + + 获取文件流 + + + + + + + + 获取文件名 + + + + + + + 获取本地模板路径 + + + + + + 日程列表查询参数 + + + + + 日程日期 + + + + + 日程日期 + + + + + 日程内容 + + + + + 日程时间 + + + + + ID + + + + + 首页服务 + + + + + 添加日程 + + 日程参数 + + + + + 删除日程 + + id列表 + + + + + 获取日程列表 + + 查询参数 + 日程列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + + + + 父ID + + + + + 添加按钮参数 + + + + + 父ID + + + + + 标题 + + + + + 编码 + + + + + ID + + + + + 权限按钮服务 + + + + + 添加按钮 + + 添加参数 + + + + + 批量添加 + + + + + + + 删除按钮 + + 删除参数 + + + + + 编辑按钮 + + 编辑参数 + + + + + 按钮分页查询 + + 查询条件 + 按钮分页列表 + + + + 按钮详情 + + + + + + + 菜单树查询参数 + + + + + 模块 + + + + + 关键字 + + + + + 添加菜单参数 + + + + + 父ID + + + + + 标题 + + + + + 菜单类型 + + + + + 模块 + + + + + 路径 + + + + + 图标 + + + + + 特殊验证 + + + + + + + + 编辑菜单输入参数 + + + + + ID + + + + + 改变模块输入参数 + + + + + 模块ID + + + + + 菜单服务 + + + + + 添加菜单 + + 添加参数 + + + + + 详情 + + id + 详细信息 + + + + 构建菜单树形结构 + + 菜单列表 + 父ID + 菜单形结构 + + + + 获取菜单树 + + 菜单树查询参数 + 是否显示禁用的 + 菜单树列表 + + + + 编辑菜单 + + 菜单编辑参数 + + + + + 删除菜单 + + 删除菜单参数 + + + + + 改变菜单模块 + + 改变菜单模块参数 + + + + + 快捷方式菜单树 + + 资源列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + + + + + 模块分页输入 + + + + + 添加模块输入 + + + + + 编辑模块输入 + + + + + ID + + + + + 模块管理服务 + + + + + 添加模块 + + 添加参数 + + + + + 删除模块 + + 删除参数 + + + + + 编辑模块 + + 编辑参数 + + + + + 分页查询 + + 分页参数 + + + + + 模块详情 + + + + + + + 模块列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + + + + 角色查询参数 + + + + + 角色添加参数 + + + + + 名称 + + + + + 角色编辑参数 + + + + + Id + + + + + 角色授权资源参数 + + + + + 角色Id + + + + + 授权资源信息 + + + + + 是否代码生成 + + + + + 角色授权资源参数 + + + + + 角色Id + + + + + 授权权限信息 + + + + + 角色授权用户参数 + + + + + Id + + + + + 授权权限信息 + + + + + 角色选择器参数 + + + + + 组织ID + + + + + 机构ID列表 + + + + + 角色名称 + + + + + 机构ID列表 + + + + + 角色拥有的资源输出 + + + + + Id + + + + + 已授权资源信息 + + + + + 角色拥有权限输出 + + + + + 角色Id + + + + + 已授权资源信息 + + + + + 角色树输出参数 + + + + + 职位Id + + + + + 名称 + + + + + 是否是职位 + + + + + 子项 + + + + + 角色服务 + + + + + 获取所有角色 + + + + + + 根据用户ID获取用户角色集合 + + 用户ID + + + + + 获取角色拥有权限 + + 角色ID + + + + + 角色拥有资源 + + 角色id + 资源类型 + 角色拥有资源信息 + + + + 获取角色下的用户 + + 角色ID + + + + + 分页查询角色 + + 查询参数 + + + + + 获取角色授权权限选择器 + + 角色ID + + + + + 角色选择器 + + + + + + + 根据id集合获取角色集合 + + + + + + + 获取角色树 + + 角色树 + + + + + 角色详情 + + 角色Id + + + + + 添加角色 + + 添加参数 + + + + + 编辑角色 + + 编辑参数 + + + + + 给角色授权权限 + + 授权信息 + + + + + 给角色授权 + + 授权参数 + + + + + 给角色授权用户 + + 授权信息 + + + + + 刷新缓存 + + + + + + 删除角色 + + 删除参数 + + + + + + + + 获取所有 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + + + + 单页输入参数 + + + + + 菜单类型 + + + + + 单页输入参数 + + + + + 标题 + + + + + 菜单类型 + + + + + 路径 + + + + + 图标 + + + + + 单页修改参数 + + + + + ID + + + + + 单页服务 + + + + + 添加单页 + + 添加参数 + + + + + 删除单页 + + 删除参数 + + + + + 编辑单页 + + 编辑参数 + + + + + 分页查询 + + + + + + + 详情 + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + + + + 操作日志分页输入 + + + + + 操作日志日志删除输入 + + + + + 操作日志周统计输出 + + + + + 日期 + + + + + 名称 + + + + + 数量 + + + + + 操作日志统计 + + + + + 操作日志服务 + + + + + 根据分类删除操作日志 + + 分类名称 + + + + + 日志详情 + + id + 日志详情 + + + + 操作日志分页查询 + + 查询参数 + 分页列表 + + + + 操作日志周统计 + + 天数 + 统计结果 + + + + 操作日志总览 + + 异常日志和操作日志的数量 + + + + + + + + + 操作日志中文名称 + + + + + 异常日志中文名称 + + + + + 分表最多查近多少年的数据 + + + + + + + + + + + + + + + + + + + + 访问日志分页输入 + + + + + 分类 + + + + + 账号 + + + + + 访问日志删除输入 + + + + + 分类 + + + + + 周统计输出 + + + + + 日期 + + + + + 登录次数 + + + + + 登出次数 + + + + + 访问日志总数输出 + + + + + 类型 + + + + + 数量 + + + + + 访问日志服务 + + + + + 根据分类删除 + + 分类名称 + + + + + 访问日志分页查询 + + 查询参数 + 日志列表 + + + + 根统计N天来登录和登出数量 + + 天使 + 统计信息 + + + + 统计登录登出总览 + + 登录和登出的数量 + + + + + + + + + 分表最多查近多少年的数据 + + + + + + + + + + + + + + + + + mqtt认证参数 + + + + + 用户ID + + + + + 账号 + + + + + 密码 + + + + + 客户端ID + + + + + mqtt登录参数输出 + + + + + 地址 + + + + + 用户名 + + + + + 密码 + + + + + 客户端ID + + + + + 主题列表 + + + + + mqtt认证输出 + + + + + 结果 "allow" | "deny" | "ignore", // Default `"ignore"` + + + + + 是否超级管理员 + + + + + Mqtt服务 + + + + + mqtt登录http认证 + + 认证参数 + 用户Id + 认证结果 + + + + 获取mqtt登录web端参数 + + 登录参数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 刷新缓存 + + 分类 + + + + + 检查输入参数 + + + + + + 配置分页参数 + + + + + 添加配置参数 + + + + + 配置键 + + + + + 配置值 + + + + + 编辑配置参数 + + + + + ID + + + + + 删除配置参数 + + + + + 批量修改输入参数 + + + + + 分类 + + + + + 系统配置服务 + + + + + 根据分类和配置键获配置 + + 分类 + 配置键 + 配置信息 + + + + 根据分类获取配置列表 + + 分类名称 + 配置列表 + + + + 分页查询其他配置 + + 查询参数 + 其他配置列表 + + + + 获取系统配置列表,不包含业务的 + + + + + + 是否是多租户模式 + + + + + + 新增配置 + + 新增参数 + + + + + 修改配置 + + 修改参数 + + + + + 批量编辑 + + 配置列表 + + + + + 删除配置 + + 删除 + + + + + + + + + + + + + + + + + + + + + + 获取全部 + + + + + + + + + + + + + + + + + + + + + + + + 刷新缓存 + + + + + 检查输入参数 + + + + + + 获取字典所有下级 + + 字典列表 + 父ID + + + + + 字典查询参数 + + + + + 字典树参数 + + + + + 字典分类 + + + + + 字典查询参数 + + + + + 父id + + + + + 分类 + + + + + 添加字典参数 + + + + + 父ID + + + + + 字典名称 + + + + + 字典值 + + + + + 编辑字典参数 + + + + + ID + + + + + 删除字典参数 + + + + + 字典服务 + + + + + 添加字典 + + 输入参数 + + + + + 构建字典树形结构 + + 字典列表 + 父ID + 字典树形结构 + + + + 删除字典 + + 删除参数 + + + + + 编辑字典 + + 输入参数 + + + + + 获取字典 + + 字典 + + + + + 获取所有 + + 字典列表 + + + + 根据字典DictValue获取字典值列表 + + 字典值 + 字典列表 + 字典值列表 + + + + 根据字典DictValue列表获取对应字典值列表 + + 字典值列表 + + + + + 字典分页查询 + + 查询参数 + 字典分页列表 + + + + 获取字典树形结构 + + 查询参数 + 字典树形结构 + + + + 根据字典值获取子级字典 + + 字典值 + + + + + 组织分页查询参数 + + + + + 父ID + + + + + 名称 + + + + + 编码 + + + + + 分类 + + + + + 状态 + + + + + 组织添加参数 + + + + + 组织修改参数 + + + + + Id + + + + + 组织复制参数 + + + + + 目标ID + + + + + 组织Id列表 + + + + + 是否包含下级 + + + + + 是否包含职位 + + + + + 组织导入 + + + + + 名称 + + + + + 上级组织 + + + + + 分类 + + + + + 排序码 + + + + + 主管账号 + + + + + 组织树查询参数 + 懒加载用 + + + + + 父Id + + + + + 组织架构服务 + + + + + 检查组织是否存在 + + 组织列表 + 组织名称 + 父Id + 组织Id + 是否存在,存在返回组织ID + + + + 组织详情 + + id参数 + 组织信息 + + + + 根据组织ID获取 下级 + + 组织ID + 是否包含自己 + 组织列表 + + + + + 获取所有组织 + + 是否显示禁用的 + + + + + 获取机构及下级ID列表 + + + + 组织列表 + + + + + 根据组织Id递归获取上级 + + 组织列表 + 组织Id + 是否包含自己 + + + + + 获取组织信息 + + 组织id + 组织信息 + + + + 组织分页查询 + + 查询参数 + 分页信息 + + + + 根据ID列表获取组织列表 + + + + + + + 获取租户列表 + + + + + + 根据组织ID获取租户ID + + 组织id + 租户id + + + + + 添加组织 + + 添加参数 + 名称 + + + + + 复制组织 + + 机构复制参数 + + + + + 编辑组织 + + 编辑参数 + 名称 + + + + + 删除组织 + + 删除参数 + 名称 + + + + + 构建组织树形结构 + + 组织列表 + 父ID + 树型结构 + + + + 刷新缓存 + + + + + + 获取组织树型结构 + + 机构ID列表 + 组织选择器(懒加载用) + 组织树列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + + + + + 根据组织Id列表获取所有父级组织 + + + + + + + + 获取组织所有下级 + + + + + + + + 获取组织下级(懒加载) + + + + + + + + 赋值组织的所有下级 + + 组织列表 + 父Id + 新父Id + + + + + + + 重新生成组织实体 + + + + + + 获取全称 + + 组织列表 + 父Id + 组织名称 + 组织全称 + 组织父Id列表 + + + + 职位分页查询 + + + + + 组织ID + + + + + 职位列表 + + + + + 分类 + + + + + 状态 + + + + + 职位新增参数 + + + + + 组织ID + + + + + 名称 + + + + + 分类 + + + + + 机构编辑参数 + + + + + Id + + + + + 机构选择器参数 + + + + + 机构树形选择器参数 + + + + + 机构ID列表 + + + + + 组织树输出参数 + + + + + 职位Id + + + + + 名称 + + + + + 是否是职位 + + + + + 子项 + + + + + 组织选择器输出参数 + + + + + 组织Id或者职位Id + + + + + 名称 + + + + + 子项 + + + + + 职位服务 + + + + + 获取职位列表 + + 职位列表 + + + + 获取职位信息 + + 职位ID + 职位信息 + + + + 职位分页查询 + + 查询参数 + 分页列表 + + + + 职位选择器 + + 查询参数 + + + + + 根据id集合获取职位集合 + + + + + + + 职位树形结构 + + + + + + + 职位详情 + + + + + + + 编辑职位 + + 编辑参数 + 名称 + + + + + 刷新缓存 + + + + + + 添加职位 + + 添加参数 + 名称 + + + + + 删除职位 + + id列表 + 名称 + + + + + + + + + + 获取全部 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 检查输入参数 + + + 名称 + + + + 构建职位选择器 + + 组织列表 + 职位列表 + 父Id + + + + + 用户选择器参数 + + + + + 组织ID + + + + + 机构ID列表 + + + + + 机构ID + + + + + 角色ID + + + + + 关键字 + + + + + 用户分页查询参数 + + + + + 所属组织 + + + + + 动态查询条件 + + + + + 用户状态 + + + + + 添加用户参数 + + + + + 账号 + + + + + 姓名 + + + + + 组织id + + + + + 职位id + + + + + 编辑用户参数 + + + + + Id + + + + + 用户授权角色参数 + + + + + Id + + + + + 授权权限信息 + + + + + 默认数据权限 + + + + + 用户导入 + + + + + 账号 + + + + + 姓名 + + + + + 性别 + + + + + 昵称 + + + + + 手机 + 这里使用了SM4自动加密解密 + + + + + 邮箱 + + + + + 所属机构 + + + + + 职位 + + + + + 出生日期 + + + + + 民族 + + + + + 籍贯 + + + + + 家庭住址 + + + + + 通信地址 + + + + + 证件类型 + + + + + 证件号码 + + + + + 文化程度 + + + + + 政治面貌 + + + + + 毕业院校 + + + + + 学历 + + + + + 学制 + + + + + 学位 + + + + + 家庭电话 + + + + + 办公电话 + + + + + 紧急联系人 + + + + + 紧急联系人电话 + + + + + 紧急联系人地址 + + + + + 员工编号 + + + + + 入职日期 + + + + + 部门Id + + + + + 职位Id + + + + + 选择用户输出参数 + + + + + Id + + + + + 组织ID + + + + + 账号 + + + + + 姓名 + + + + + 性别 + + + + + 用户信息输出 + + + + + 用户信息 + + + + + 账号 + + + + + 姓名 + + + + + 昵称 + + + + + 性别 + + + + + 手机 + 这里使用了SM4自动加密解密 + + + + + 邮箱 + + + + + 所属机构 + + + + + 职位 + + + + + 出生日期 + + + + + 民族 + + + + + 籍贯 + + + + + 家庭住址 + + + + + 通信地址 + + + + + 证件类型 + + + + + 证件号码 + + + + + 文化程度 + + + + + 政治面貌 + + + + + 毕业院校 + + + + + 学历 + + + + + 学制 + + + + + 学位 + + + + + 家庭电话 + + + + + 办公电话 + + + + + 紧急联系人 + + + + + 紧急联系人电话 + + + + + 紧急联系人地址 + + + + + 员工编号 + + + + + 入职日期 + + + + + 职级 + + + + + Id + + + + + 组织ID + + + + + 角色名称 + + + + + 角色编码 + + + + + 用户服务 + + + + + 根据用户ID获取按钮ID集合 + + + + + + + 根据账号获取用户信息 + + 用户名 + 租户ID + 用户信息 + + + + 根据用户ID和机构ID获取角色权限 + + + + + + + + 根据手机号获取用户账号 + + 手机号 + 租户ID + 用户账号名称 + + + + 用户选择器 + + 查询参数 + + + + + 用户分页查询 + + 查询参数 + 用户分页列表 + + + + 用户列表 + + 查询 + + + + + 根据用户Id获取用户信息 + + 用户ID + 用户信息 + + + + 根据用户Id获取用户信息 + + 用户ID + 转换的实体 + + + + + 根据用户账号获取用户ID + + 用户账号 + 租户id + + + + + 根据用户手机获取用户信息 + + 手机号 + 租户Id + 用户信息 + + + + 获取用户拥有角色 + + 用户ID + + + + + 获取用户拥有的资源 + + 用户id + 资源列表 + + + + 获取用户拥有的权限 + + 用户id + 权限列表 + + + + 用户权限树选择 + + 用户id + 权限列表 + + + + 根据id集合获取用户集合 + + Id集合 + + + + + 用户详情 + + + + + + + 获取用户头像 + + 用户id + base64头像 + + + + 获取当前API用户的数据范围 + null:代表拥有全部数据权限 + [xx,xx]:代表拥有部分机构的权限 + []:代表仅自己权限 + + 机构列表 + + + + 检查用户是否有机构的数据权限 + + 机构id + 创建者id + 错误提示:不为空则直接抛出异常 + 是否有权限 + + + + 检查用户是否有机构的数据权限 + + 机构id列表 + 创建者id列表 + 错误提示:不为空则直接抛出异常 + + + + + 添加用户 + + 添加参数 + + + + + 编辑 + + 编辑参数 + + + + + 启用用户 + + 用户Id + + + + + 禁用用户 + + 用户Id + + + + + 重置密码 + + 用户Id + + + + + 给用户授权角色 + + 授权参数 + + + + + 给用户授权资源 + + 授权参数 + + + + + 给用户授权权限 + + + + + + + 设置用户默认值 + + + + + + + 批量编辑 + + 批量编辑信息 + + + + + 删除用户 + + Id列表 + + + + + 从redis中删除用户信息 + + 用户ID列表 + + + + 从redis中删除用户信息 + + 用户ID + + + + 导出用户 + + + + + + + 导入模板下载 + + 模板 + + + + 导入预览 + + 预览参数 + 预览结果 + + + + 用户导入 + + + + + + + 检查导入数据 + + 数据 + 是否初始化错误 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 获取默认密码 + + + + + + 检查输入参数 + + + + + + 检查是否为自己 + + + 操作名称 + + + + 根据日期计算年龄 + + + + + + + 获取SqlSugar的ISugarQueryable + + + + + + + 数据库获取用户信息 + + 用户ID + + + + + 关系服务 + + + + + 根据分类获取关系表信息 + + 分类名称 + 关系表 + + + + 通过对象ID和分类获取关系列表 + + 对象ID + 分类 + + + + + 通过对象ID列表和分类获取关系列表 + + 对象ID + 分类 + + + + + 通过目标ID和分类获取关系列表 + + 目标ID + 分类 + + + + + 通过目标ID列表和分类获取关系列表 + + + + + + + + 获取关系表用户工作台 + + 用户ID + 关系表数据 + + + + 更新缓存 + + 分类 + + + + + 保存关系 + + 分类 + 对象ID + 目标ID + 拓展信息 + 是否清除老的数据 + 是否刷新缓存 + + + + + 批量保存关系 + + 分类 + 对象ID + 目标ID列表 + 拓展信息列表 + 是否清除老的数据 + + + + + 获取用户模块ID + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 资源输入 + + + + + 资源分类 + + + + + 是否包含按钮 + + + + + 角色授权资源树输出 + + + + + 模块id + + + + + 模块名称 + + + + + 模块图标 + + + + + 模块下菜单集合 + + + + + 授权菜单类 + + + + + 菜单id + + + + + 父id + + + + + 父名称 + + + + + 模块名称 + + + + + 模块id + + + + + 菜单下按钮集合 + + + + + 角色授权资源按钮信息 + + + + + 按钮id + + + + + 标题 + + + + + 权限树选择器输出 + + + + + 接口描述 + + + + + 路由名称 + + + + + 权限名称 + + + + + 资源服务 + + + + + 获取所有的菜单和模块以及单页面列表,并按分类和排序码排序 + + 所有的菜单和模块以及单页面列表 + + + + 根据模块ID获取菜单和单页面列表 + + + + + + + 根据资源ID获取所有下级资源 + + 资源ID + 是否包含自己 + 资源列表 + + + + 根据资源ID获取所有下级资源 + + 资源列表 + 资源ID + 是否包含自己 + 资源列表 + + + + 获取ID获取Code列表 + + id列表 + 分类 + Code列表 + + + + 获取资源列表 + + 资源分类列表 + + + + + 根据分类获取资源列表 + + 分类名称 + 资源列表 + + + + 根据菜单ID获取菜单 + + id列表 + 分类 + + + + + 获取权限授权树 + + 路由列表 + + + + + 刷新缓存 + + 分类名称 + + + + + 角色授权资源树 + + + + + + 获取上级 + + + + + + + + 获取授权菜单类菜单名称 + + 菜单列表 + 当前菜单 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 获取路由地址名称 + + 控制器地址 + 路由名称 + + + + + 获取资源所有下级 + + 资源列表 + 父ID + + + + + 获取授权菜单 + + 模块ID + + + + + + + + 编辑个人信息参数 + + + + + 姓名 + + + + + 签名图片 + + + + + 更新个人工作台 + + + + + 工作台数据 + + + + + 更新个人密码 + + + + + 密码 + + + + + 新密码 + + + + + 设置默认模块输入 + + + + + 模块Id + + + + + 是否默认 + + + + + 我的机构数样式 + + + + + Id + + + + + 名称 + + + + + 父ID + + + + + 子节点 + + + + + 样式 + + + + + 我的机构样式 + + + + + 背景色 + + + + + 字体颜色 + + + + + 个人信息中心服务 + + + + + 获取登录用户菜单 + + + + + + + 获取个人工作台 + + + + + + 获取组织架构 + + 组织架构 + + + + 获取快捷菜单树 + + + + + + 读取登录用户站内信详情 + + + + + + + 获取登录用户的站内信分页 + + + + + + + 更新个人信息 + + 信息参数 + + + + + 更新签名 + + 签名图片 + + + + + 编辑个人工作台 + + 工作台字符串 + + + + + 删除我的消息 + + 消息Id + + + + + 修改个人密码 + + 密码信息 + + + + + 修改头像 + + 头像文件 + + + + + 修改默认模块 + + 默认模块输入参数 + + + + + 获取登录用户的站内信分页 + + 查询参数 + 站内信列表 + + + + 读取登录用户站内信详情 + + 消息ID + 消息详情 + + + + 获取未读消息数量 + + 未读消息数量 + + + + 最新未读消息 + + + + + + 设置已读 + + + + + + + 删除我的消息 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 获取父菜单集合 + + 所有菜单列表 + 我的菜单列表 + + + + + 构建Meta + + 我的菜单集合 + + + + 构建机构树 + + 机构列表 + 父ID + 用户ID + + + + + AppStartup启动类 + + + + + ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行 + 服务都还没初始化完成,会导致内存中存在多份 IOC 容器!! + 正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了 + + + + + + 当前登录用户信息 + + + + + 当前用户Id + + + + + 当前用户账号 + + + + + 当前用户昵称 + + + + + 是否超级管理员 + + + + + 机构ID + + + + + C端用户关系 + + + + + 对象ID + + + + + 目标ID + + + + + 分类 + + + + diff --git a/SimpleAdmin.System/Startup.cs b/SimpleAdmin.System/Startup.cs new file mode 100644 index 0000000..49b28bc --- /dev/null +++ b/SimpleAdmin.System/Startup.cs @@ -0,0 +1,59 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using IP2Region.Net.Abstractions; +using IP2Region.Net.XDB; + +namespace SimpleAdmin.System; + +/// +/// AppStartup启动类 +/// +[AppStartup(99)] +public class Startup : AppStartup +{ + /// + /// ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行 + /// 服务都还没初始化完成,会导致内存中存在多份 IOC 容器!! + /// 正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了 + /// + /// + public void ConfigureServices(IServiceCollection services) + { + // 配置ip2region + services.AddSingleton(new Searcher(CachePolicy.Content, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ip2region.xdb"))); + + //系统配置转实体 + services.AddConfigurableOptions(); + //事件总线 + services.AddEventBus(); + //配置验证码 + services.AddCaptcha(App.Configuration); + //配置视图引擎 + services.AddViewEngine(); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + var fullName = Assembly.GetExecutingAssembly().FullName;//获取程序集全名 + //通过 App.GetOptions 获取选项 + var settings = App.GetOptions(); + if (settings.UseMessageCenter) + { + //通过 App.GetOptions 获取选项 + var cacheSettings = App.GetOptions(); + if (!cacheSettings.UseRedis) + { + throw Oops.Oh("启用通知中心必须使用Redis缓存,如不需要,在SimpleAdmin.System项目中设置UseMessageCenter为false即可"); + } + } + CodeFirstUtils.CodeFirst(settings, fullName);//CodeFirst + } +} diff --git a/SimpleAdmin.System/System.Development.json b/SimpleAdmin.System/System.Development.json new file mode 100644 index 0000000..1fd9f00 --- /dev/null +++ b/SimpleAdmin.System/System.Development.json @@ -0,0 +1,28 @@ +{ + //swagger分组设置 + "[openapi:Default]": { + "Order": 99, //分组排序,int 类型,数字越大排前面,默认 0 + "Title": "RBAC权限模块", //配置分组标题,string 类型 + "Description": "让 .NET 开发更简单,更通用,更流行。", + "Version": "1.0.0", //配置分组版本,默认 1.0 + "TermsOfService": "https://www.cnblogs.com/huguodong/", //配置相关链接地址,Uri 类型 + "Contact": { + //配置联系方式 + "Name": "少林寺驻北固山办事处大神父王喇嘛", + "Url": "https://gitee.com/huguodong520", + "Email": "531035580@qq.com" + }, + "License": { + //配置协议,OpenApiLicense 类型 + "Name": "Apache-2.0", + "Url": "https://gitee.com/huguodong520/SimpleAdmin/blob/master/LICENSE" + } + }, + //系统层设置 + "SystemSettings": { + "InitTable": false, //是否初始化表结构 + "InitSeedData": false, //是否初始化种子数据 + "SuperAdminViewAllData": true, //是否超级管理员可以查看所有数据 + "UseMessageCenter": false //是否启用通知中心 + } +} \ No newline at end of file diff --git a/SimpleAdmin.System/System.Production.json b/SimpleAdmin.System/System.Production.json new file mode 100644 index 0000000..1fd9f00 --- /dev/null +++ b/SimpleAdmin.System/System.Production.json @@ -0,0 +1,28 @@ +{ + //swagger分组设置 + "[openapi:Default]": { + "Order": 99, //分组排序,int 类型,数字越大排前面,默认 0 + "Title": "RBAC权限模块", //配置分组标题,string 类型 + "Description": "让 .NET 开发更简单,更通用,更流行。", + "Version": "1.0.0", //配置分组版本,默认 1.0 + "TermsOfService": "https://www.cnblogs.com/huguodong/", //配置相关链接地址,Uri 类型 + "Contact": { + //配置联系方式 + "Name": "少林寺驻北固山办事处大神父王喇嘛", + "Url": "https://gitee.com/huguodong520", + "Email": "531035580@qq.com" + }, + "License": { + //配置协议,OpenApiLicense 类型 + "Name": "Apache-2.0", + "Url": "https://gitee.com/huguodong520/SimpleAdmin/blob/master/LICENSE" + } + }, + //系统层设置 + "SystemSettings": { + "InitTable": false, //是否初始化表结构 + "InitSeedData": false, //是否初始化种子数据 + "SuperAdminViewAllData": true, //是否超级管理员可以查看所有数据 + "UseMessageCenter": false //是否启用通知中心 + } +} \ No newline at end of file diff --git a/SimpleAdmin.System/UserManager/UserManager.cs b/SimpleAdmin.System/UserManager/UserManager.cs new file mode 100644 index 0000000..3020c08 --- /dev/null +++ b/SimpleAdmin.System/UserManager/UserManager.cs @@ -0,0 +1,83 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using NewLife; + +namespace SimpleAdmin.System; + +/// +/// 当前登录用户信息 +/// +public class UserManager +{ + /// + /// 当前用户Id + /// + public static long UserId + { + get + { + return (App.User?.FindFirst(ClaimConst.USER_ID)?.Value).ToLong(); + } + } + + /// + /// 当前用户账号 + /// + public static string UserAccount + { + get + { + return App.User?.FindFirst(ClaimConst.ACCOUNT)?.Value; + } + } + + /// + /// 当前用户昵称 + /// + public static string Name + { + get + { + return App.User?.FindFirst(ClaimConst.NAME)?.Value; + } + } + + /// + /// 是否超级管理员 + /// + public static bool SuperAdmin + { + get + { + return (App.User?.FindFirst(ClaimConst.IS_SUPER_ADMIN)?.Value).ToBoolean(); + } + } + + /// + /// 机构ID + /// + public static long OrgId + { + get + { + return (App.User?.FindFirst(ClaimConst.ORG_ID)?.Value).ToLong(); + } + } + + public static long? TenantId + { + get + { + //如果有租户ID则返回租户ID,否则返回null + return (App.User?.FindFirst(ClaimConst.TENANT_ID)?.Value).ToLong(); + } + } +} diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Controllers/Controller.cs.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Controllers/Controller.cs.vm new file mode 100644 index 0000000..8701c7a --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Controllers/Controller.cs.vm @@ -0,0 +1,299 @@ +@{ +var dataPermission=@Model.DataPermission=="Y";//是否启用数据权限 +var isOrgTree=@Model.LeftTree=="org";//是否启用组织树 +var funcList=@Model.FuncList;//获取功能列表 +var isTreeList = @Model.ModuleType=="treeList";//是否是树表-列表 +var isTreeTree = @Model.ModuleType=="treeTree"; //是否是树-树 +var tableFieIds=@Model.TableFields;//获取字段 +} +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel; +using MoYu.DynamicApiController; +using @(@Model.ServicePosition); + +namespace @(@Model.ControllerPosition); + +/// +/// @(@Model.FunctionName)控制器 +/// +[ApiDescriptionSettings("@(@Model.ApiGroup)", Tag = "@(@Model.FunctionName)")] +[Route("@(@Model.RouteName)/@(@Model.BusName)")] +@if(dataPermission) @:[RolePermission] +public class @(@Model.ClassName)Controller: IDynamicApiController +{ + private readonly I@(@Model.ServiceName) _@(@Model.ServiceFirstLower); + @if(isOrgTree){ + @if(dataPermission){ + @:private readonly IOrgService _orgService; + } + else{ + @:private readonly ISysOrgService _sysOrgService; + } + } + public @(@Model.ClassName)Controller(I@(@Model.ServiceName) @(@Model.ServiceFirstLower) + @if(isOrgTree){ + @if(dataPermission){ + @:,IOrgService orgService + } + else{ + @:,ISysOrgService sysOrgService + } + } + ) + { + this._@(@Model.ServiceFirstLower) = @(@Model.ServiceFirstLower); + @if(isOrgTree){ + @if(dataPermission){ + @:_orgService = orgService; + } + else{ + @:_sysOrgService = sysOrgService; + } + } + } + #region Get请求 + + /// + /// @(@Model.DescriptionPage) + /// + /// + /// + [HttpGet("page")] + [DisplayName("@(@Model.DescriptionPage)")] + public async Task Page([FromQuery] @Model.PageInput input) + { + return await _@(@Model.ServiceFirstLower).Page(input); + } + + /// + /// @(@Model.DescriptionList) + /// + /// + /// + [HttpGet("list")] + [DisplayName("@(@Model.DescriptionList)")] + public async Task List([FromQuery] @Model.PageInput input) + { + return await _@(@Model.ServiceFirstLower).List(input); + } + + /// + /// @(@Model.DescriptionDetail) + /// + /// + /// + [HttpGet("detail")] + [DisplayName("@(@Model.DescriptionDetail)")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _@(@Model.ServiceFirstLower).Detail(input); + } + + @{Fk();} + + @{Tree();} + + @{OtherGet();} + + #endregion + + + #region Post请求 + + /// + /// @(@Model.DescriptionAdd) + /// + /// + /// + [HttpPost("add")] + [DisplayName("@(@Model.DescriptionAdd)")] + public async Task Add([FromBody] @(@Model.ClassName)AddInput input) + { + await _@(@Model.ServiceFirstLower).Add(input); + } + + /// + /// @(@Model.DescriptionEdit) + /// + /// + /// + [HttpPost("edit")] + [DisplayName("@(@Model.DescriptionEdit)")] + public async Task Edit([FromBody] @(@Model.ClassName)EditInput input) + { + await _@(@Model.ServiceFirstLower).Edit(input); + } + + /// + /// @(@Model.DescriptionDelete) + /// + /// + /// + [HttpPost("delete")] + [DisplayName("@(@Model.DescriptionDelete)")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _@(@Model.ServiceFirstLower).Delete(input); + } + + @{OtherPost();} + #endregion +} + +@{ + +void Fk(){ +foreach (var column in tableFieIds){//遍历字段 +if(column.EffectType=="fk"){//如果是外键 + @:/// + @:/// @(column.FieldRemark)选择器 + @:/// + @:/// + @:[HttpGet("fk@(column.FkEntityName)Selector")] + @:[DisplayName("@(column.FieldRemark)选择器")] + @:public async Task Fk@(column.FkEntityName)Selector() + @:{ + @:return await _@(@Model.ServiceFirstLower).Fk@(column.FkEntityName)Selector(); + @:} + @: +} +} +} + +void OtherGet(){ +foreach(var func in funcList){ +switch (func)//根据类型生成不同请求 +{ +//导入 +case "import": + @:/// + @:/// @(@Model.DescriptionPreview) + @:/// + @:/// + @:/// + @:[HttpPost("preview")] + @:[DisableRequestSizeLimit] + @:[SuppressMonitor] + @:[DisplayName("@(@Model.DescriptionPreview)")] + @:public async Task Preview([FromForm] ImportPreviewInput input) + @:{ + @:return await _@(@Model.ServiceFirstLower).Preview(input); + @:} + @: + @:/// + @:/// @(@Model.DescriptionTemplate) + @:/// + @:/// + @:[HttpGet("template")] + @:[SuppressMonitor] + @:public async Task Template() + @:{ + @:return await _@(@Model.ServiceFirstLower).Template(); + @:} + @: +break; +} +} +} + +//左侧树接口 +void Tree(){ +if(isOrgTree){ + @:/// + @:/// 获取组织树选择器 + @:/// + @:/// + @:[HttpGet("orgTreeSelector")] + @:[DisplayName("组织树查询")] + @:public async Task OrgTreeSelector() + @:{ + @if(dataPermission){ + @:return await _orgService.Tree(); + } + else{ + @:return await _sysOrgService.Tree(); + } + @:} +} +else if(isTreeList){ + @:/// + @:/// @(@Model.DescriptionTree) + @:/// + @:/// + @:[HttpGet("tree")] + @:[DisplayName("@(@Model.DescriptionTree)")] + @:public async Task Tree() + @:{ + @:return await _@(@Model.ServiceFirstLower).Tree(); + @:} +} +else if(isTreeTree){ + @:/// + @:/// @(@Model.DescriptionTree) + @:/// + @:/// + @:[HttpGet("tree")] + @:[DisplayName("@(@Model.DescriptionTree)")] + @:public async Task Tree([FromQuery] @Model.TreeInput input) + @:{ + @:return await _@(@Model.ServiceFirstLower).Tree(input); + @:} +} + +} + +void OtherPost(){ +foreach(var func in funcList){ +switch (func)//根据类型生成不同请求 +{ +//导入 +case "import": + @:/// + @:/// @(@Model.DescriptionImport) + @:/// + @:/// + @:/// + @:[HttpPost("import")] + @:[DisplayName("@(@Model.DescriptionImport)")] + @:public async Task Import([SuppressMonitor][FromBody] ImportResultInput<@(@Model.ClassName)ImportInput> input) + @:{ + @:return await _@(@Model.ServiceFirstLower).Import(input); + @:} + @: +break; +//导出 +case "export": + @:/// + @:/// @(@Model.DescriptionExport) + @:/// + @:/// + @:/// + @:[HttpPost("export")] + @:[DisplayName("@(@Model.DescriptionExport)")] + @:public async Task Export([FromBody] @Model.PageInput input) + @:{ + @:return await _@(@Model.ServiceFirstLower).Export(input); + @:} + @: +break; +//批量编辑 +case "batchEdit": + @:/// + @:/// @(@Model.DescriptionEdits) + @:/// + @:/// + @:/// + @:[HttpPost("edits")] + @:[DisplayName("@(@Model.DescriptionEdits)")] + @:public async Task Edits([FromBody] BatchEditInput input) + @:{ + @:await _@(@Model.ServiceFirstLower).Edits(input); + @:} + @: +break; +} +} +} + + +} diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/Dto/Input.cs.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/Dto/Input.cs.vm new file mode 100644 index 0000000..151cbaf --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/Dto/Input.cs.vm @@ -0,0 +1,180 @@ +@{ + var tableFieIds=@Model.TableFields;//获取字段 + var isTreeList = @Model.ModuleType=="treeList";//是否是树表-列表 + var isTreeTree = @Model.ModuleType=="treeTree"; //是否是树-树 +} +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using System; +using System.ComponentModel.DataAnnotations; +using Masuit.Tools.Core.Validator; +namespace @(@Model.ServicePosition); + +/// +/// @(@Model.DescriptionPage)参数 +/// +public class @Model.PageInput : BasePageInput +{ + @{PageInput();} + @if(@Model.LeftTree=="org"){ + @:/// + @:/// 组织机构Id + @:/// + @:public long OrgId { get; set; } + } + @if(isTreeList){ + @:/// + @:/// 父Id + @:/// + @:public long @Model.TreePid { get; set; } + } +} + + +/// +/// @(@Model.DescriptionAdd)参数 +/// +public class @Model.AddInput +{ + @{AddInput();} +} + +/// +/// @(@Model.DescriptionEdit)参数 +/// +public class @Model.EditInput : @Model.AddInput +{ + /// + /// Id + /// + [IdNotNull(ErrorMessage = "Id不能为空")] + public long Id { get; set; } +} + +@if(isTreeTree){ +@{TreeTree();} +} + +@{OtherInput();} + +@{ + +void TreeTree(){ +@:/// +@:/// @(@Model.DescriptionTree)参数 +@:/// +@:public class @Model.TreeInput +@:{ + @{PageInput();} +@:} +} + +void OtherInput(){ +var funcList=@Model.FuncList;//获取功能列表 +foreach(var func in funcList){ +switch (func)//根据类型生成不同请求 +{ +//导入 +case "import": +@:/// +@:/// @(@Model.DescriptionImport) +@:/// +@:public class @(@Model.ClassName)ImportInput : ImportTemplateInput +@:{ + ImportInput(); +@:} +break; +}} + +} + +//生成导入字段 +void ImportInput(){ + foreach (var column in tableFieIds){ + if(column.WhetherImportExport=="Y")//判断是否新增 + { + @:/// + @:/// @column.FieldRemark + @:/// + @:[ImporterHeader(Name = "@column.FieldRemark")] + if(column.WhetherImportExport=="Y")//判断是否必填 + { + @:[Required(ErrorMessage = "@(@column.FieldRemark)不能为空")] + } + if(column.FieldNetType!="string")//如果不是string类型后面要加?号 + { + @:public @(@column.FieldNetType)? @column.FieldName { get; set; } + }else{ + @:public @column.FieldNetType @column.FieldName { get; set; } + } + @: + } + } +} + +//生成分页字段 +void PageInput() +{ + foreach (var column in tableFieIds){ + if(column.QueryWhether=="Y")//判断是否查询 + { + if(column.EffectType=="datepicker"){//如果是时间类型 + @:/// + @:/// @column.FieldRemark + @:/// + @:public @column.FieldNetType? Start@(@column.FieldName) { get; set; } + @: + @:/// + @:/// @column.FieldRemark + @:/// + @:public @column.FieldNetType? End@(@column.FieldName) { get; set; } + @: + } + else{ + @:/// + @:/// @column.FieldRemark + @:/// + if(column.FieldNetType!="string")//如果不是string类型后面要加?号 + { + @:public @(@column.FieldNetType)? @column.FieldName { get; set; } + }else{ + @:public @column.FieldNetType @column.FieldName { get; set; } + } + @: + }}}} +} + +@{ +//生成新增字段 +void AddInput() +{ + foreach (var column in tableFieIds){//遍历字段 + if(column.WhetherAddUpdate=="Y")//判断是否新增 + { + @:/// + @:/// @column.FieldRemark + @:/// + if(column.WhetherRequired=="Y")//判断是否必填 + { + @:[Required(ErrorMessage = "@(@column.FieldName)不能为空")] + } + if(column.FieldNetType!="string")//如果不是string类型后面要加?号 + { + @:public @(@column.FieldNetType)? @column.FieldName { get; set; } + }else{ + @:public @column.FieldNetType @column.FieldName { get; set; } + } + @: + } + } +} +} + diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/Dto/Output.cs.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/Dto/Output.cs.vm new file mode 100644 index 0000000..9b53446 --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/Dto/Output.cs.vm @@ -0,0 +1,53 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 +namespace @(@Model.ServicePosition); + +@{OtherOutput();} + + + +@{ + +void OtherOutput(){ +var funcList=@Model.FuncList;//获取功能列表 +foreach(var func in funcList){ +switch (func)//根据类型生成不同请求 +{ +//导入 +case "export": +@:/// +@:/// @(@Model.DescriptionExport) +@:/// +@:[ExcelExporter(Name = "@(@Model.FunctionName)信息", TableStyle = TableStyles.Light10, AutoFitAllColumn = true)] +@:public class @(@Model.ClassName)ExportOutput +@:{ + ExportOutput(); +@:} +break; +}} + +} + +void ExportOutput(){ + var tableFieIds=@Model.TableFields;//获取字段 + foreach (var column in tableFieIds){ + if(column.WhetherImportExport=="Y")//判断是否新增 + { + @:/// + @:/// @column.FieldRemark + @:/// + @:[ExporterHeader(DisplayName = "@column.FieldRemark")] + @:public string @column.FieldName { get; set; } + @: + } + } +} + +} diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/IService.cs.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/IService.cs.vm new file mode 100644 index 0000000..204af83 --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/IService.cs.vm @@ -0,0 +1,174 @@ +@{ +var isTreeList = @Model.ModuleType=="treeList";//是否是树表-列表 +var isTreeTree = @Model.ModuleType=="treeTree"; //是否是树-树 +var tableFieIds=@Model.TableFields;//获取字段 +} +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using MoYu.DependencyInjection; +using SimpleAdmin.Core; + +namespace @(@Model.ServicePosition); + +/// +/// @(@Model.FunctionName)服务 +/// +public interface I@(@Model.ServiceName) : ITransient +{ + #region 查询 + + /// + /// @Model.DescriptionPage + /// + /// 查询参数 + /// @(@Model.FunctionName)分页 + Task> Page(@Model.PageInput input); + + /// + /// @Model.DescriptionList + /// + /// 查询参数 + /// @(@Model.FunctionName)列表 + Task> List(@Model.PageInput input); + + /// + /// @Model.DescriptionDetail + /// + /// Id参数 + /// 详细信息 + Task<@(@Model.EntityName)> Detail(BaseIdInput input); + + @if(isTreeList){ + @:/// + @:/// @Model.DescriptionTree + @:/// + @:/// @(@Model.FunctionName)树 + @:Task> Tree(); + } + @if(isTreeTree){ + @:/// + @:/// @Model.DescriptionTree + @:/// + @:/// @(@Model.FunctionName)树 + @:Task> Tree(@Model.TreeInput input); + } + + @{Fk();} + #endregion + + #region 新增 + + /// + /// @Model.DescriptionAdd + /// + /// 添加参数 + /// + Task Add(@Model.AddInput input); + + #endregion + + #region 编辑 + /// + /// @Model.DescriptionEdit + /// + /// 编辑参数 + /// + Task Edit(@Model.EditInput input); + + @if(@Model.FuncList.Contains("batchEdit")){ + @:/// + @:/// @(@Model.DescriptionEdits) + @:/// + @:/// 批量编辑信息 + @:/// + @:Task Edits(BatchEditInput input); + } + #endregion + + #region 删除 + + /// + /// @Model.DescriptionDelete + /// + /// 删除参数 + /// + Task Delete(BaseIdListInput input); + + #endregion + + #region 导入导出 + + @{ImportExport();} + + #endregion +} + +@{ + +void Fk(){ +foreach (var column in tableFieIds){//遍历字段 +if(column.EffectType=="fk"){//如果是外键 + @:/// + @:/// @(column.FieldRemark)选择器 + @:/// + @:/// + @:Task> Fk@(column.FkEntityName)Selector(); + +} +} +} + +void ImportExport(){ + +var funcList=@Model.FuncList;//获取功能列表 +foreach(var func in funcList){ +switch (func)//根据类型生成不同请求 +{ +//导入 +case "import": + @:/// + @:/// @(@Model.DescriptionTemplate) + @:/// + @:/// 模板 + @:Task Template(); + @: + @:/// + @:/// @(@Model.DescriptionPreview) + @:/// + @:/// 预览参数 + @:/// 预览结果 + @:Task> Preview(ImportPreviewInput input); + @: + @:/// + @:/// @(@Model.DescriptionImport) + @:/// + @:/// + @:/// + @:Task> Import(ImportResultInput<@(@Model.ClassName)ImportInput> input); + @: +break; +//导出 +case "export": + @:/// + @:/// @(@Model.DescriptionExport) + @:/// + @:/// + @:/// + @:Task Export(@Model.PageInput input); +break; +} +} + +} + + + +} diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/Service.cs.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/Service.cs.vm new file mode 100644 index 0000000..b6d84fd --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Backend/Services/Service.cs.vm @@ -0,0 +1,461 @@ +@{ +var orgField=@Model.TableFields.Any(it=>it.FieldName=="OrgId")?"OrgId":"CreateOrgId";//机构字段 +var dataPermission=@Model.DataPermission=="Y";//是否有数据权限 +var tableFieIds=@Model.TableFields;//获取字段 +var isTreeList = @Model.ModuleType=="treeList";//是否是树表-列表 +var isTreeTree = @Model.ModuleType=="treeTree"; //是否是树-树 +var isMasterChild = @Model.ModuleType=="masterChild"; //是否是主子表 +} + +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using MoYu.FriendlyException; +using Mapster; +using SimpleAdmin.Core; +using Microsoft.Extensions.Logging; +using Microsoft.AspNetCore.Mvc; +using SqlSugar; + +namespace @(@Model.ServicePosition); + +/// +/// +/// +public class @(@Model.ServiceName) : DbRepository<@(@Model.EntityName)>, I@(@Model.ServiceName) +{ + private readonly ILogger<@(@Model.ServiceName)> _logger; + private readonly ISysUserService _sysUserService; + @if(@Model.FuncList.Contains("import")||@Model.FuncList.Contains("export")){ + @:private readonly IImportExportService _importExportService; + } + @if(@Model.FuncList.Contains("batchEdit")){ + @:private readonly IBatchEditService _batchEditService; + } + @if(@Model.LeftTree=="org"){ + @:private readonly ISysOrgService _sysOrgService; + } + + public @(@Model.ServiceName)(ILogger<@(@Model.ServiceName)> logger,ISysUserService sysUserService + @if(@Model.FuncList.Contains("import")||@Model.FuncList.Contains("export")){ + @:,IImportExportService importExportService + } + @if(@Model.FuncList.Contains("batchEdit")){ + @:,IBatchEditService updateBatchService + } + @if(@Model.LeftTree=="org"){ + @:,ISysOrgService sysOrgService + } + ) + { + _sysUserService = sysUserService; + _logger = logger; + @if(@Model.FuncList.Contains("import")||@Model.FuncList.Contains("export")){ + @:_importExportService = importExportService; + } + @if(@Model.FuncList.Contains("batchEdit")){ + @: _batchEditService = updateBatchService; + } + @if(@Model.LeftTree=="org"){ + @: _sysOrgService = sysOrgService; + } + + } + + #region 查询 + + /// + public async Task> Page(@Model.PageInput input) + { + var query = await GetQuery(input);//获取查询条件 + var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 + return pageInfo; + } + + /// + public async Task> List(@Model.PageInput input) + { + var query = await GetQuery(input);//获取查询条件 + var list = await query.ToListAsync(); + return list; + } + + /// + public async Task<@(@Model.EntityName)> Detail(BaseIdInput input) + { + var @Model.ClassNameFirstLower = await GetFirstAsync(it => it.Id == input.Id); + @if(dataPermission){ + @:var errorMessage = $"您没有权限查看该数据"; + @://获取数据范围 + @:var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + @:if (dataScope!=null&&(!dataScope.Contains(@(@Model.ClassNameFirstLower).@(orgField)) || @(@Model.ClassNameFirstLower).CreateUserId != UserManager.UserId))//判断机构ID是否在数据范围或者创建人是否为当前登录人 + @:throw Oops.Bah(errorMessage); + } + @if(isMasterChild){ + @:var child=await Context.Queryable<@Model.ChildTable>().Where(it => it.@(Model.ChildFk) == @(@Model.ClassNameFirstLower).Id).ToListAsync(); + } + return @Model.ClassNameFirstLower ; + + } + @if(isTreeList){ + @:/// + @:public async Task> Tree() + @:{ + @://第三个参数为0 表示 : parentid为 0 设置成根目录, 正常情况下最顶层的parentid不是0就是null + @:var tree = Context.Queryable<@(@Model.EntityName)>().ToTree(it => it.Children, it => it.ParentId, 0); + @:return tree; + @:} + } + @if(isTreeTree){ + @:/// + @:public async Task> Tree(@Model.TreeInput input) + @:{ + @://第三个参数为0 表示 : parentid为 0 设置成根目录, 正常情况下最顶层的parentid不是0就是null + @:var tree = Context.Queryable<@(@Model.EntityName)>() + @if(isTreeTree){ + @{PageWhereIf();}//查询条件 + } + @:.ToTree(it => it.Children, it => it.ParentId, 0); + @:return tree; + @:} + } + + @{Fk();}//外键查询 + #endregion + + #region 新增 + + /// + public async Task Add(@Model.AddInput input) + { + var @Model.ClassNameFirstLower = input.Adapt<@(@Model.EntityName)>();//实体转换 + await CheckInput(@Model.ClassNameFirstLower);//检查参数 + @if(dataPermission){ + @://获取数据范围 + @:var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + @://判断机构ID是否在数据范围,这里只是简单示例,根据实际情况判断 + @://if (dataScope!=null&&(!dataScope.Contains(@(@Model.ClassNameFirstLower).OrgId))) + @://throw Oops.Bah("您没有权限添加该数据"); + } + await InsertAsync(@Model.ClassNameFirstLower);//插入数据 + } + + #endregion + + #region 编辑 + + /// + public async Task Edit(@Model.EditInput input) + { + var @Model.ClassNameFirstLower = input.Adapt<@(@Model.EntityName)>();//实体转换 + await CheckInput(@Model.ClassNameFirstLower);//检查参数 + @if(dataPermission){ + @://判断机构ID是否在数据范围并且创建者是自己,这里只是简单示例,根据实际情况判断 + @://if (dataScope!=null&&(!dataScope.Contains(@(@Model.ClassNameFirstLower).@(orgField)) || @(@Model.ClassNameFirstLower).CreateUserId != UserManager.UserId)) + @://throw Oops.Bah("您没有权限编辑该数据"); + } + await UpdateAsync(@Model.ClassNameFirstLower);//更新数据 + } + + @if(@Model.FuncList.Contains("batchEdit")){ + @:/// + @:public async Task Edits(BatchEditInput input) + @:{ + Edits(); + @:} + } + + #endregion + + #region 删除 + + /// + public async Task Delete(BaseIdListInput input) + { + //获取所有ID + var ids = input.Ids.ToList(); + if (ids.Count > 0) + { + @if(dataPermission){ + @://获取数据范围 + @:var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + @:var @(@Model.ClassNameFirstLower)s = await GetListAsync(it => ids.Contains(it.Id), it =>new @(@Model.EntityName){ @(orgField)=it.@(orgField),CreateUserId=it.CreateUserId });//根据ID获取机构ID和创建者ID + @:@(@Model.ClassNameFirstLower)s.ForEach(it => + @:{ + @: if (dataScope!=null&&!dataScope.Contains(it.@(orgField))&&it.CreateUserId != UserManager.UserId) throw Oops.Bah(ErrorCodeEnum.A0004);//如果不包含机构id并且不是自己创建的 + @:}); + } + @if(isMasterChild){ + @://如果@(Model.FunctionName)下有下级数据则不允许删除 + @:if (await Context.Queryable<@(@Model.ChildTable)>().AnyAsync(it => ids.Contains(it.@(Model.ChildFk)))) + @:{ + @:throw Oops.Bah($"有数据依赖@(Model.FunctionName),无法删除"); + @:} + } + await DeleteByIdsAsync(ids.Cast().ToArray());//删除数据 + ////事务 + //var result = await itenant.UseTranAsync(async () => + //{ + //await DeleteByIdsAsync(ids.Cast().ToArray());//删除数据 + @if(isMasterChild){ + @://Context.Deleteable<@(@Model.ChildTable)>().Where(it => ids.Contains(it.@(Model.ChildFk))).ExecuteCommandAsync();//删除子表数据 + } + //}); + //if (!result.IsSuccess)//如果成功了 + //{ + ////写日志 + //_logger.LogError(result.ErrorMessage, result.ErrorException); + //throw Oops.Oh(ErrorCodeEnum.A0002); + //} + } + } + + #endregion + + #region 导入导出 + + @{ImportExport();} + + #endregion + + #region 方法 + + /// + /// 检查输入参数 + /// + /// + private async Task CheckInput(@Model.EntityName @Model.ClassNameFirstLower) + { + @{CheckInput();} + } + + /// + /// 获取Sqlsugar的ISugarQueryable + /// + /// + /// + private async Task> GetQuery(@Model.PageInput input) + { + + @if(dataPermission){ + @://获取数据范围 + @:var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + @://动态查询条件,如果是连表查询,里面的it要改成连表里对应的别名 + @:var exp = Expressionable.Create<@(@Model.EntityName)>(); + @:exp.AndIF(dataScope is { Count: > 0 }, it => dataScope.Contains(it.@(orgField)));//用户机构在数据范围内 + @:exp.AndIF(dataScope is { Count: 0 }, it => it.CreateUserId == UserManager.UserId);//默认创建者ID等于自己,根据实际情况修改条件 + } + @if(@Model.LeftTree=="org"){ + @:var orgIds = await _sysOrgService.GetOrgChildIds(input.OrgId);//获取下级机构 + } + var query = Context.Queryable<@(@Model.EntityName)>() + @{PageWhereIf();} + @if(dataPermission){ + @:.Where(exp.ToExpression()) + } + @if(@Model.LeftTree=="org"){ + @:.WhereIF(input.OrgId > 0, it => orgIds.Contains(it.@(orgField)))//根据机构ID查询 + } + @if(isTreeList){ + @:.WhereIF(input.@(@Model.TreePid) > 0, it => it.@(@Model.TreePid) ==input.@(@Model.TreePid))//父级 + } + //.WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Name.Contains(input.SearchKey))//根据关键字查询 + .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}") + @{PageSortCode();} + return query; + } + + /// + public async Task> CheckImport<@(@Model.ClassName)ImportInput>(List<@(@Model.ClassName)ImportInput> data, bool clearError = false) + { + return data; + } + #endregion + +} + +@{ + +void Fk(){ +foreach (var column in tableFieIds){//遍历字段 +if(column.EffectType=="fk"){//如果是外键 + @:/// + @:/// @(column.FieldRemark)选择器 + @:/// + @:/// + @:public async Task> Fk@(column.FkEntityName)Selector() + @:{ + @if(dataPermission){ + @://获取数据范围 + @:var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + } + @:return await Context.Queryable<@(column.FkEntityName)>() + @if(dataPermission){ + @://.WhereIf(dataScope!=null,it => it.CreateOrgId == UserManager.OrgId || (dataScope.Contains(it.Id))) + } + @:.Select(it => new BaseSelectorOutput { Value = it.@(column.FkColumnId), Label = it.@(column.FkColumnName) }).ToListAsync(); + @:} + +} +} +} + +//删除 +void Delete(){ + +} + +//批量编辑 +void Edits(){ + @if(dataPermission){ + @://获取数据范围 + @:var dataScope = await _sysUserService.GetLoginUserApiDataScope(); + @:var ids = input.Ids;//获取id列表 + @:var @(@Model.ClassNameFirstLower)s = await GetListAsync(it => ids.Contains(it.Id), it =>new @(@Model.EntityName){ @(orgField)=it.@(orgField),CreateUserId=it.CreateUserId });//根据ID获取机构ID和创建者ID + @:@(@Model.ClassNameFirstLower)s.ForEach(it => + @:{ + @: if (dataScope!=null&&!dataScope.Contains(it.@(orgField))&&it.CreateUserId != UserManager.UserId) throw Oops.Bah(ErrorCodeEnum.A0004);//如果不包含机构id并且不是自己创建的 + @:}); + } + @://获取参数字典 + @:var data = await _batchEditService.GetUpdateBatchConfigDict(input.Code, input.Columns); + @:if (data.Count > 0) + @:{ + @:await Context.Updateable<@(@Model.EntityName)>(data).Where(it => input.Ids.Contains(it.Id)).ExecuteCommandAsync(); + @:} +} + +//检查输入 +void CheckInput(){ + @:var errorMessage = $"您没有权限操作该数据"; + @:if(@(@Model.ClassNameFirstLower).Id==SimpleAdminConst.ZERO){ + @://表示新增 + @:} + @:else{ + @://表示编辑 + @:} +} + +//导入导出 +void ImportExport() +{ +if(@Model.FuncList.Contains("import")) +{ + @:/// + @:public async Task Template() + @:{ + @:var templateName = "@(@Model.FunctionName)信息"; + @://var result = _importExportService.GenerateLocalTemplate(templateName); + @:var result = await _importExportService.GenerateTemplate<@(@Model.ClassName)ImportInput>(templateName); + @:return result; + @:} + @: + @:/// + @:public async Task> Preview(ImportPreviewInput input) + @:{ + @:var importPreview = await _importExportService.GetImportPreview<@(@Model.ClassName)ImportInput>(input.File); + @:importPreview.Data = await CheckImport(importPreview.Data);//检查导入数据 + @:return importPreview; + @:} + @: + @:/// + @:public async Task> Import(ImportResultInput<@(@Model.ClassName)ImportInput> input) + @:{ + @:var data = await CheckImport(input.Data, true);//检查数据格式 + @:var result = _importExportService.GetImportResultPreview(data, out var importData); + @:var @Model.ClassNameFirstLower = importData.Adapt>();//转实体 + @:await InsertOrBulkCopy(@Model.ClassNameFirstLower);// 数据导入 + @:return result; + @:} + @: +} +if(@Model.FuncList.Contains("export")) +{ + @:/// + @:public async Task Export(@Model.PageInput input) + @:{ + @:var genTests = await List(input); + @:var data = genTests.Adapt>();//转为Dto + @:var result = await _importExportService.Export(data, "@(@Model.FunctionName)信息"); + @:return result; + @:} +} +} +} + + +@{ +//生成查询条件 +void PageWhereIf() +{ + foreach (var column in tableFieIds){//遍历字段 + if(column.QueryWhether=="Y")//判断是否查询 + { + if(@column.FieldNetType.ToLower() == "string")//判断是否是字符串类型 + { + switch (@column.QueryType)//遍历查询方式 + { + case "eq"://等于 + @:.WhereIF(!string.IsNullOrWhiteSpace(input.@column.FieldName), it => it.@(@column.FieldName) == input.@(@column.FieldName)) + break; + case "like"://包含 + @:.WhereIF(!string.IsNullOrWhiteSpace(input.@column.FieldName), it => it.@(@column.FieldName).Contains(input.@(@column.FieldName).Trim())) + break; + case "notlike"://不包含 + @:.WhereIF(!string.IsNullOrWhiteSpace(input.@column.FieldName), it => !it.@(@column.FieldName).Contains(input.@(@column.FieldName).Trim())) + break; + case "ne"://不等于 + @:.WhereIF(!string.IsNullOrWhiteSpace(input.@column.FieldName), it => it.@(@column.FieldName) != input.@(@column.FieldName)) + break; + } + } + else if(@column.EffectType=="datepicker"){//如果是时间类型则生成时间戳 + @:.WhereIF(input.Start@(@column.FieldName)!=null||input.End@(@column.FieldName)!=null, it=> SqlFunc.Between(it.@column.FieldName, input.Start@(@column.FieldName), input.End@(@column.FieldName))) + } + else{//其他 + switch (@column.QueryType)//遍历查询方式 + { + case "eq"://等于 + @:.WhereIF(input.@column.FieldName!=null, it => it.@(@column.FieldName) == input.@(@column.FieldName)) + break; + case "ne"://不等于 + @:.WhereIF(input.@column.FieldName!=null, it => it.@(@column.FieldName) != input.@(@column.FieldName)) + break; + case "gt"://大于 + @:.WhereIF(input.@column.FieldName!=null, it => it.@(@column.FieldName) > input.@(@column.FieldName)) + break; + case "ge"://大于等于 + @:.WhereIF(input.@column.FieldName!=null, it => it.@(@column.FieldName) >= input.@(@column.FieldName)) + break; + case "lt"://小于 + @:.WhereIF(input.@column.FieldName!=null, it => it.@(@column.FieldName) < input.@(@column.FieldName)) + break; + case "le"://小于等于 + @:.WhereIF(input.@column.FieldName!=null, it => it.@(@column.FieldName) <= input.@(@column.FieldName)) + break; + } + } + } + } +} +} + +@{ +//生成根据SortCode排序 +void PageSortCode() +{ + var hasSortCode= tableFieIds.Any(it => it.FieldName == "SortCode"); + if(hasSortCode){//如果有sortcode字段 + @:.OrderBy(it => it.SortCode);//排序 + }else{ + @:; + } +} +} diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/api/interface/interface.ts.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/api/interface/interface.ts.vm new file mode 100644 index 0000000..04b9222 --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/api/interface/interface.ts.vm @@ -0,0 +1,85 @@ +/** + * @@description @(@Model.FunctionName+@Model.FunctionNameSuffix)接口 + * @@license Apache License Version 2.0 + * @@Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 + * @@remarks + * SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 + * 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin + * 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 + * 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。 + * 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关 + */ + +@{ +var busName= @Model.BusName;//业务名称 +var author= @Model.AuthorName;//作者 +var currentTime =@Model.GenTime; +var name=@Model.FunctionName+@Model.FunctionNameSuffix;//接口名称 +var tableFieIds=@Model.TableFields;//获取字段 +} + +import { ReqPage } from "@@/api/interface"; + +/** + * @@Description: @(@Model.FunctionName+@Model.FunctionNameSuffix)接口 + * @@Author: @author + * @@Date: @currentTime + */ +export namespace @Model.EntityName { + + /**@(@Model.FunctionName)分页查询 */ + export interface Page extends ReqPage { + @{PageQueryParams();} + } + + /** @(@Model.FunctionName)信息 */ + export interface @(@Model.EntityName)Info { + @{EntityToInterfaceParams();} + } +} + + +@{ +//生成查询条件 +void PageQueryParams() +{ + var queryParams = tableFieIds.Where(x => x.QueryWhether=="Y").ToList(); + //遍历字段 + foreach (var column in queryParams){ + @:/** @column.FieldRemark */ + if(@column.FieldNetType.ToLower() == "string")//判断是否是字符串类型 + { + @:@column.FieldNameFirstLower: string; + } + if(@column.FieldNetType.ToLower() == "int"||@column.FieldNetType.ToLower() == "long")//判断是否是数字类型 + { + @:@column.FieldNameFirstLower: number; + } + + } +} +//实体字段转接口参数 +void EntityToInterfaceParams(){ + var numberParams =new string[]{"int","long","decimal","double"};//数字类型 + var tableParams = tableFieIds.Where(x => x.WhetherTable=="Y"||x.IsPrimaryKey=="Y"||x.SortCode<99).ToList(); + //遍历字段 + foreach (var column in tableParams){ + @:/** @column.FieldRemark */ + if(numberParams.Contains(@column.FieldNetType.ToLower()))//判断是否是数字类型 + { + @:@column.FieldNameFirstLower: number; + } + else if(@column.FieldNetType.ToLower() == "bool")//判断是否是数字类型 + { + @:@column.FieldNameFirstLower: boolean; + } + else + { + @:@column.FieldNameFirstLower: string; + } +} + +} + diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/api/modules/modules.ts.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/api/modules/modules.ts.vm new file mode 100644 index 0000000..2bbf5c9 --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/api/modules/modules.ts.vm @@ -0,0 +1,50 @@ +/** + * @@description @(@Model.FunctionName+@Model.FunctionNameSuffix)Api + * @@license Apache License Version 2.0 + * @@Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 + * @@remarks + * SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 + * 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin + * 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 + * 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。 + * 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关 + */ + +@{ +var busName= @Model.BusName;//业务名称 +var author= @Model.AuthorName;//作者 +var currentTime =@Model.GenTime; +var name=@Model.FunctionName+@Model.FunctionNameSuffix;//接口名称 +var tableFieIds=@Model.TableFields;//获取字段 +} + +import { ReqId, ResPage,@Model.EntityName,moduleRequest } from "@@/api"; +const http = moduleRequest("@(@Model.RouteName)/@Model.BusName/"); + +/** + * @@Description: @name + * @@Author: @author + * @@Date: @currentTime + */ +const @(@Model.ClassNameFirstLower)Api = { + /** 获取@(@Model.FunctionName)分页 */ + page(params: @(@Model.EntityName).Page) { + return http.get>("page", params); + }, + /** 获取@(@Model.FunctionName)详情 */ + detail(params: ReqId) { + return http.get<@Model.EntityName.@(@Model.EntityName)Info>("detail", params); + }, + /** 提交表单 edit为true时为编辑,默认为新增 */ + submitForm(params = {}, edit: boolean = false) { + return http.post(edit ? "edit" : "add", params); + }, + /** 删除@(@Model.FunctionName) */ + delete(params: ReqId[]) { + return http.post("delete", params); + }, +}; + +export { @(@Model.ClassNameFirstLower)Api }; \ No newline at end of file diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/template.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/template.vm new file mode 100644 index 0000000..1f59df2 --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/template.vm @@ -0,0 +1,14 @@ +/** +* @description 接口 +* @license Apache License Version 2.0 +* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +* @remarks +* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +* 1.请不要删除和修改根目录下的LICENSE文件。 +* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。 +* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关 +* @see https://gitee.com/dotnetmoyu/SimpleAdmin +*/ \ No newline at end of file diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/views/components/form.vue.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/views/components/form.vue.vm new file mode 100644 index 0000000..8f23240 --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/views/components/form.vue.vm @@ -0,0 +1,191 @@ +@{ +var name=@Model.FunctionName+@Model.FunctionNameSuffix;//接口名称 +var author= @Model.AuthorName;//作者 +var tableFieIds=@Model.TableFields;//获取字段 +var currentTime =@Model.GenTime; +var funcName= @Model.FunctionName;//获取功能名称 +var busName= @Model.BusName;//获取业务名称 +var props=@Model.BusName+"Props"; +var updateColumns= tableFieIds.Where(it => it.WhetherAddUpdate == "Y").ToList();//获取需要显示的字段 +var dictTypes= tableFieIds.Where(it => !string.IsNullOrEmpty(it.DictTypeCode)).ToList();//获取需要显示的字段 +} + + + + +@{ + +void FormItem(){ +foreach(var column in updateColumns){ + @: + @switch (@column.EffectType) { + case "input": + + break; + case "inputNumber": + + break; + case "radio": + + break; + case "select": + + break; + case "textarea": + + break; + case "checkbox": + + break; + case "datepicker": + + break; + case "fk": + + break; + + } + +} +} +} + + + +@{ + +//字典生成 +void DictStore(){ +if(dictTypes.Count>0){ +@:const dictStore = useDictStore(); +@foreach(var column in dictTypes){ +@:const @(@column.FieldNameFirstLower)Options = dictStore.getDictList("@column.DictTypeCode"); //@(@column.FieldRemark)选项 +} +} +} + +void Rules(){ +// 表单验证规则 +@:const rules = reactive({ +@foreach(var column in updateColumns){ +@if(column.WhetherRequired=="Y"){ +@switch (column.EffectType){ +case "input": +@:@(@column.FieldNameFirstLower): [required("请输入@(@column.FieldRemark)")], +break; +case "select": +case "radio": +@:@(@column.FieldNameFirstLower): [required("请选择@(@column.FieldRemark)")], +break; +deault: +@:@(@column.FieldNameFirstLower): [required("请输入@(@column.FieldRemark)")], +break; +} +} +} +@:}); +} +} \ No newline at end of file diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/views/index.vue.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/views/index.vue.vm new file mode 100644 index 0000000..5214a84 --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Frontend/views/index.vue.vm @@ -0,0 +1,192 @@ +@{ +var busName= @Model.BusName;//获取业务名称 +var funcName= @Model.FunctionName;//获取功能名称 +var author= @Model.AuthorName;//作者 +var currentTime =@Model.GenTime; +var name=@Model.FunctionName+@Model.FunctionNameSuffix;//接口名称 +var tableFieIds=@Model.TableFields;//获取字段 +var dataPermission=@Model.DataPermission=="Y";//是否需要数据权限 +var isLeftTree=@Model.LeftTree!="null";//是否有左侧树 +var isTreeList = @Model.ModuleType=="treeList";//是否是树表-列表 +var isTreeTree = @Model.ModuleType=="treeTree"; //是否是树-树 +var isMasterChild = @Model.ModuleType=="masterChild";//是否是主子表 +var treeId=@SimpleTool.StringHelper.FirstCharToLower(@Model.TreeId);//获取树的id +var treeName=@SimpleTool.StringHelper.FirstCharToLower(@Model.TreeName);//获取树的名称 +var treePid=@SimpleTool.StringHelper.FirstCharToLower(@Model.TreePid);//获取树的父级id +var showColumns= tableFieIds.Where(it => it.WhetherTable == "Y").ToList();//获取需要显示的字段 +var resizeColumn=showColumns.Any(it => it.WhetherResizable == "Y");//获取需要显示的字段 +var dictTypes= tableFieIds.Where(it => !string.IsNullOrEmpty(it.DictTypeCode)).ToList();//获取需要显示的字段 +} + + + +@{ +//Template部分 +void Template() +{ + ProTable(); +} + +//表格部分 +void ProTable() +{ +
+ + + + @{Solt();} + @{Operation();} + + @{Form();} +
+} + +//表格自定义字段 +void Solt(){ + foreach(var column in showColumns){ + @switch (@column.EffectType) { + case "image"://图片 + + + break; + case "datepicker"://日期 + @if(@column.FieldNetType.ToLower()=="date") + { + + + } + break; + } + } +} + +//表格操作 +void Operation(){ + + +} + +//表单 +void Form(){ + +
+} + +} + + + +@{ + +//字典生成 +void DictStore(){ +if(dictTypes.Count>0){ +@:const dictStore = useDictStore(); +@foreach(var column in dictTypes){ +@:const @(@column.FieldNameFirstLower)Options = dictStore.getDictList("@column.DictTypeCode"); //@(@column.FieldRemark)选项 +} +} +} + +// 表格配置项 +void Colums(){ +// 表格配置项 +@:const columns: ColumnProps<@(@Model.EntityName).@(@Model.EntityName)Info>[] = [ + @:{ type: "selection", fixed: "left", width: 80 }, + @foreach(var column in showColumns){ + @:{ prop: "@column.FieldNameFirstLower", label: "@column.FieldRemark" @{GetEnum(@column);} @{GetSearch(@column);} }, + } + @:{ prop: "operation", label: "操作", width: 230, fixed: "right" } +@:]; +} + +//判断需要添加emum属性 +void GetEnum(SimpleAdmin.System.GenConfig column){ +@if(!string.IsNullOrEmpty(column.DictTypeCode)){//如果字典不为空 +@:,enum: @(@column.FieldNameFirstLower)Options +} +} + +void GetSearch(SimpleAdmin.System.GenConfig column){ +@if(column.QueryWhether=="Y"){//如果字典不为空 +@switch (column.EffectType){ +case "input": +@:, search: { el: "input" } +break; +case "select": +case "radio": +@:, search: { el: "select" } +break; +} +} +} +} + + \ No newline at end of file diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Sql/MySql.sql.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Sql/MySql.sql.vm new file mode 100644 index 0000000..2675685 --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Sql/MySql.sql.vm @@ -0,0 +1,19 @@ +/* + Source Server Type: Mysql + Date: @Model.GenTime +*/ + +/*添加菜单*/ +INSERT INTO `sys_resource` VALUES (@Model.MenuId, 0, '@(@Model.FunctionName)管理', '@Model.BusName', '@Model.MenuCode','', 'MENU', @Model.Module, 'MENU', '@Model.MenuPath', '@Model.MenuComponent', '@Model.Icon',99, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,1,0,'ENABLE',NULL); + +/*添加按钮*/ +INSERT INTO `sys_resource` VALUES (@Model.AddButtonId, @Model.MenuId, '新增@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Add', '','BUTTON', NULL, NULL, NULL, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*批量删除*/ +INSERT INTO `sys_resource` VALUES (@Model.BatchDeleteButtonId, @Model.MenuId, '批量删除@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)BatchDelete', '','BUTTON', NULL, NULL, NULL, NULL, NULL, 2, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*编辑按钮*/ +INSERT INTO `sys_resource` VALUES (@Model.EditButtonId, @Model.MenuId, '编辑@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Edit','', 'BUTTON', NULL, NULL, NULL, NULL, NULL, 3, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*删除删除*/ +INSERT INTO `sys_resource` VALUES (@Model.DeleteButtonId, @Model.MenuId, '删除@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Delete', '','BUTTON', NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Sql/Oracle.sql.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Sql/Oracle.sql.vm new file mode 100644 index 0000000..9d96b46 --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Sql/Oracle.sql.vm @@ -0,0 +1,19 @@ +/* + Source Server Type: Oracle + Date: @Model.GenTime +*/ + +/*添加菜单*/ +INSERT INTO "sys_resource" VALUES (@Model.MenuId, 0, '@(@Model.FunctionName)管理', '@Model.BusName', '@Model.MenuCode', '', 'MENU', @Model.Module, 'MENU', '@Model.MenuPath', '@Model.MenuComponent', '@Model.Icon', 99, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,1,0,'ENABLE',NULL); + +/*添加按钮*/ +INSERT INTO "sys_resource" VALUES (@Model.AddButtonId, @Model.MenuId, '新增@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Add','', 'BUTTON', NULL, NULL, NULL, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*批量删除*/ +INSERT INTO "sys_resource" VALUES (@Model.BatchDeleteButtonId, @Model.MenuId, '批量删除@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)BatchDelete','', 'BUTTON', NULL, NULL, NULL, NULL, NULL, 2, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*编辑按钮*/ +INSERT INTO "sys_resource" VALUES (@Model.EditButtonId, @Model.MenuId, '编辑@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Edit','', 'BUTTON', NULL, NULL, NULL, NULL, NULL, 3, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*删除删除*/ +INSERT INTO "sys_resource" VALUES (@Model.DeleteButtonId, @Model.MenuId, '删除@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Delete', '', 'BUTTON', NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Sql/SqlServer.sql.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Sql/SqlServer.sql.vm new file mode 100644 index 0000000..0c537ad --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Sql/SqlServer.sql.vm @@ -0,0 +1,19 @@ +/* + Source Server Type: SqlServer + Date: @Model.GenTime +*/ + +/*添加菜单*/ +INSERT INTO [dbo].[sys_resource] VALUES (@Model.MenuId, 0, '@(@Model.FunctionName)管理', '@Model.BusName', '@Model.MenuCode','', 'MENU', @Model.Module, 'MENU', '@Model.MenuPath', '@Model.MenuComponent', '@Model.Icon', 99, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,1,0,'ENABLE',NULL); + +/*添加按钮*/ +INSERT INTO [dbo].[sys_resource] VALUES (@Model.AddButtonId, @Model.MenuId, '新增@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Add','', 'BUTTON', NULL, NULL, NULL, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*批量删除*/ +INSERT INTO [dbo].[sys_resource] VALUES (@Model.BatchDeleteButtonId, @Model.MenuId, '批量删除@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)BatchDelete', '','BUTTON', NULL, NULL, NULL, NULL, NULL, 2, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*编辑按钮*/ +INSERT INTO [dbo].[sys_resource] VALUES (@Model.EditButtonId, @Model.MenuId, '编辑@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Edit','', 'BUTTON', NULL, NULL, NULL, NULL, NULL, 3, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*删除删除*/ +INSERT INTO [dbo].[sys_resource] VALUES (@Model.DeleteButtonId, @Model.MenuId, '删除@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Delete','', 'BUTTON', NULL, NULL, NULL, NULL, NULL,4, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); diff --git a/SimpleAdmin.System/ViewEngine/CodeGen/Sql/Sqlite.sql.vm b/SimpleAdmin.System/ViewEngine/CodeGen/Sql/Sqlite.sql.vm new file mode 100644 index 0000000..4b4be9d --- /dev/null +++ b/SimpleAdmin.System/ViewEngine/CodeGen/Sql/Sqlite.sql.vm @@ -0,0 +1,19 @@ +/* + Source Server Type: Sqlite + Date: @Model.GenTime +*/ + +/*添加菜单*/ +INSERT INTO "sys_resource" VALUES (@Model.MenuId, 0, '@(@Model.FunctionName)管理', '@Model.BusName', '@Model.MenuCode', '', 'MENU', @Model.Module, 'MENU', '@Model.MenuPath', '@Model.MenuComponent', '@Model.Icon', 99, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*添加按钮*/ +INSERT INTO "sys_resource" VALUES (@Model.AddButtonId, @Model.MenuId, '新增@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Add','', 'BUTTON', NULL, NULL, NULL, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*批量删除*/ +INSERT INTO "sys_resource" VALUES (@Model.BatchDeleteButtonId, @Model.MenuId, '批量删除@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)BatchDelete','', 'BUTTON', NULL, NULL, NULL, NULL, NULL, 2, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*编辑按钮*/ +INSERT INTO "sys_resource" VALUES (@Model.EditButtonId, @Model.MenuId, '编辑@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Edit','', 'BUTTON', NULL, NULL, NULL, NULL, NULL, 3, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); + +/*删除删除*/ +INSERT INTO "sys_resource" VALUES (@Model.DeleteButtonId, @Model.MenuId, '删除@(@Model.FunctionName)', NULL, '@(@Model.ClassNameFirstLower)Delete','', 'BUTTON', NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL,NULL,0,0,0,0,0,'ENABLE',NULL); diff --git a/SimpleAdmin.System/ip2region.xdb b/SimpleAdmin.System/ip2region.xdb new file mode 100644 index 0000000..c78b792 Binary files /dev/null and b/SimpleAdmin.System/ip2region.xdb differ diff --git a/SimpleAdmin.Web.Core/Components/AuthComponent.cs b/SimpleAdmin.Web.Core/Components/AuthComponent.cs new file mode 100644 index 0000000..23fe9c0 --- /dev/null +++ b/SimpleAdmin.Web.Core/Components/AuthComponent.cs @@ -0,0 +1,49 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using Microsoft.AspNetCore.Authentication.JwtBearer; + +namespace SimpleAdmin.Web.Core; + +/// +/// 认证相关组件 +/// +public sealed class AuthComponent : IServiceComponent +{ + public void Load(IServiceCollection services, ComponentContext componentContext) + { + // JWT配置 + services.AddJwt(enableGlobalAuthorize: true, jwtBearerConfigure: options => + { + //signalr jwt配置 + options.Events = new JwtBearerEvents + { + OnMessageReceived = context => + { + var accessToken = context.Request.Query["access_token"]; + + // If the request is for our hub... + var path = context.HttpContext.Request.Path; + if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/hubs")) + { + // Read the token out of the query string + context.Token = accessToken; + } + return Task.CompletedTask; + } + }; + }); + // 允许跨域 + services.AddCorsAccessor(); + + //注册自定义授权筛选器 + services.AddMvcFilter(); + } +} diff --git a/SimpleAdmin.Web.Core/Components/LoggingMonitorComponent.cs b/SimpleAdmin.Web.Core/Components/LoggingMonitorComponent.cs new file mode 100644 index 0000000..c2119e4 --- /dev/null +++ b/SimpleAdmin.Web.Core/Components/LoggingMonitorComponent.cs @@ -0,0 +1,58 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using UAParser; + +namespace SimpleAdmin.Web.Core; + +/// +/// LoggingMonitor操作日志写入数据库插件 +/// +public sealed class LoggingMonitorComponent : IServiceComponent +{ + public void Load(IServiceCollection services, ComponentContext componentContext) + { + //Monitor日志配置 + services.AddMonitorLogging(options => + { + options.JsonIndented = true;// 是否美化 JSON + options.GlobalEnabled = true;//全局启用 + options.ConfigureLogger((logger, logContext, context) => + { + var httpContext = context.HttpContext;//获取httpContext + //获取头 + var userAgent = httpContext.Request.Headers["User-Agent"]; + if (string.IsNullOrEmpty(userAgent)) userAgent = "Other";//如果没有这个头就指定一个 + //获取客户端信息 + var client = Parser.GetDefault().Parse(userAgent); + // 获取控制器/操作描述器 + // var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; + //操作名称默认是控制器名加方法名,自定义操作名称要在action上加Description特性 + //var option = $"{controllerActionDescriptor.ControllerName}/{controllerActionDescriptor.ActionName}"; + ////获取特性 + //var monitor = controllerActionDescriptor.MethodInfo.GetCustomAttribute(); + //if (monitor != null)//如果有LoggingMonitor特性 + // option = monitor.Description;//则将操作名称赋值为控制器上写的title + //logContext.Set(LoggingConst.Operation, option);//传操作名称 + logContext.Set(LoggingConst.CLIENT, client);//客户端信息 + logContext.Set(LoggingConst.PATH, httpContext.Request.Path.Value);//请求地址 + logContext.Set(LoggingConst.METHOD, httpContext.Request.Method);//请求方法 + }); + }); + //日志写入数据库配置 + services.AddDatabaseLogging(options => + { + options.WriteFilter = logMsg => + { + return logMsg.LogName == "System.Logging.LoggingMonitor";//只写入LoggingMonitor日志 + }; + }); + } +} diff --git a/SimpleAdmin.Web.Core/Components/WebSettingsComponent.cs b/SimpleAdmin.Web.Core/Components/WebSettingsComponent.cs new file mode 100644 index 0000000..0ed245a --- /dev/null +++ b/SimpleAdmin.Web.Core/Components/WebSettingsComponent.cs @@ -0,0 +1,41 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// Web设置组件 +/// 模拟 ConfigureService +/// +public sealed class WebSettingsComponent : IServiceComponent +{ + public void Load(IServiceCollection services, ComponentContext componentContext) + { + //web设置配置转实体 + services.AddConfigurableOptions(); + + //禁止在主机启动时通过 App.GetOptions 获取选项,如需获取配置选项理应通过 App.GetConfig("配置节点", true)。 + var appSettings = App.GetConfig("WebSettings", true); + //如果是演示环境,加上操作筛选器,禁止操作数据库 + if (appSettings.EnvPoc) + services.AddMvcFilter(); + } +} + +/// +/// Web设置组件 +/// 模拟 Configure +/// +public sealed class WebSettingsApplicationComponent : IApplicationComponent +{ + public void Load(IApplicationBuilder app, IWebHostEnvironment env, ComponentContext componentContext) + { + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizOrgController.cs b/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizOrgController.cs new file mode 100644 index 0000000..ca72ece --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizOrgController.cs @@ -0,0 +1,142 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 机构管理控制器 +/// +[ApiDescriptionSettings("Application", Tag = "机构管理")] +[Route("biz/organization/org")] +[RolePermission] +public class BizOrgController : IDynamicApiController +{ + private readonly IOrgService _orgService; + private readonly IUserService _userService; + + public BizOrgController(IOrgService orgService, IUserService userService) + { + _orgService = orgService; + _userService = userService; + } + + #region Get请求 + + /// + /// 获取机构树 + /// + /// + [HttpGet("tree")] + [DisplayName("机构树查询")] + public async Task Tree() + { + return await _orgService.Tree(); + } + + /// + /// 机构分页查询 + /// + /// + /// + [HttpGet("page")] + [DisplayName("机构分页查询")] + public async Task Page([FromQuery] SysOrgPageInput input) + { + return await _orgService.Page(input); + } + + /// + /// 获取机构树选择器 + /// + /// + [HttpGet("orgTreeSelector")] + [DisplayName("机构树选择器")] + public async Task OrgTreeSelector() + { + return await _orgService.Tree(); + } + + /// + /// 获取人员选择器 + /// + /// + [HttpGet("userSelector")] + [DisplayName("人员选择器")] + public async Task UserSelector([FromQuery] UserSelectorInput input) + { + return await _userService.Selector(input); + } + + /// + /// 机构详情 + /// + /// + /// + [HttpGet("detail")] + [DisplayName("机构详情")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _orgService.Detail(input); + } + + #endregion + + #region Post请求 + + /// + /// 添加机构 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加机构")] + public async Task Add([FromBody] SysOrgAddInput input) + { + await _orgService.Add(input); + } + + /// + /// 修改机构 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改机构")] + public async Task Edit([FromBody] SysOrgEditInput input) + { + await _orgService.Edit(input); + } + + /// + /// 复制组织 + /// + /// + /// + [HttpPost("copy")] + [DisplayName("复制组织")] + public async Task Copy(SysOrgCopyInput input) + { + await _orgService.Copy(input); + } + + /// + /// 删除机构 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除机构")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _orgService.Delete(input); + } + + #endregion +} diff --git a/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizPositionController.cs b/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizPositionController.cs new file mode 100644 index 0000000..7885515 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizPositionController.cs @@ -0,0 +1,118 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 岗位管理控制器 +/// +[ApiDescriptionSettings("Application", Tag = "岗位管理")] +[Route("biz/organization/position")] +[RolePermission] +public class BizPositionController +{ + private readonly IPositionService _positionService; + + public BizPositionController(IPositionService positionService) + { + _positionService = positionService; + } + + #region Get请求 + + /// + /// 获取职位树 + /// + /// + [HttpGet("tree")] + [DisplayName("获取职位树")] + public async Task Tree([FromQuery] PositionTreeInput input) + { + return await _positionService.Tree(input); + } + + /// + /// 岗位分页查询 + /// + /// + /// + [HttpGet("page")] + [DisplayName("岗位分页查询")] + public async Task Page([FromQuery] PositionPageInput input) + { + return await _positionService.Page(input); + } + + /// + /// 岗位详情 + /// + /// + /// + [HttpGet("detail")] + [DisplayName("岗位详情")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _positionService.Detail(input); + } + + /// + /// 岗位选择器 + /// + /// + /// + [HttpGet("selector")] + [DisplayName("岗位选择器")] + public async Task Selector([FromQuery] PositionSelectorInput input) + { + return await _positionService.Selector(input); + } + + #endregion + + #region Post请求 + + /// + /// 添加岗位 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加岗位")] + public async Task Add([FromBody] PositionAddInput input) + { + await _positionService.Add(input); + } + + /// + /// 修改岗位 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改岗位")] + public async Task Edit([FromBody] PositionEditInput input) + { + await _positionService.Edit(input); + } + + /// + /// 删除岗位 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除岗位")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _positionService.Delete(input); + } + + #endregion +} diff --git a/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizRoleController.cs b/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizRoleController.cs new file mode 100644 index 0000000..9ddca12 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizRoleController.cs @@ -0,0 +1,173 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 业务角色管理控制器 +/// +[ApiDescriptionSettings(Tag = "角色管理")] +[Route("biz/organization/role")] +[RolePermission] +public class BizRoleController : IDynamicApiController +{ + private readonly IResourceService _resourceService; + private readonly IRoleService _roleService; + private readonly ISysUserService _sysUserService; + + public BizRoleController(IResourceService resourceService, IRoleService roleService, ISysUserService sysUserService) + { + _resourceService = resourceService; + _roleService = roleService; + _sysUserService = sysUserService; + } + + /// + /// 角色分页查询 + /// + /// + /// + [HttpGet("page")] + [DisplayName("角色分页查询")] + public async Task Page([FromQuery] RolePageInput input) + { + return await _roleService.Page(input); + } + + /// + /// 添加角色 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加角色")] + public async Task Add([FromBody] RoleAddInput input) + { + await _roleService.Add(input); + } + + /// + /// 修改角色 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改角色")] + public async Task Edit([FromBody] RoleEditInput input) + { + await _roleService.Edit(input); + } + + /// + /// 删除角色 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除角色")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _roleService.Delete(input); + } + + /// + /// 获取角色授权资源树 + /// + /// + [HttpGet("resourceTreeSelector")] + [DisplayName("获取角色授权资源树")] + public async Task ResourceTreeSelector() + { + return await _roleService.ResourceTreeSelector(); + } + + /// + /// 获取角色拥有资源 + /// + /// + /// + [HttpGet("ownResource")] + [DisplayName("获取角色拥有资源")] + public async Task OwnResource([FromQuery] BaseIdInput input) + { + return await _roleService.OwnResource(input, CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE); + } + + /// + /// 给角色授权资源 + /// + /// + /// + [HttpPost("grantResource")] + [DisplayName("角色授权资源")] + public async Task GrantResource([FromBody] GrantResourceInput input) + { + await _roleService.GrantResource(input); + } + + /// + /// 获取角色下的用户 + /// + /// + /// + [HttpGet("ownUser")] + [DisplayName("获取角色下的用户")] + public async Task OwnUser([FromQuery] BaseIdInput input) + { + return await _roleService.OwnUser(input); + } + + /// + /// 给角色授权用户 + /// + /// + /// + [HttpPost("grantUser")] + [DisplayName("角色授权")] + public async Task GrantUser([FromBody] GrantUserInput input) + { + await _roleService.GrantUser(input); + } + + /// + /// 获取角色树 + /// + /// + [HttpGet("tree")] + [DisplayName("获取角色树")] + public async Task Tree([FromQuery] RoleTreeInput input) + { + return await _roleService.Tree(input); + } + + + /// + /// 获取角色详情 + /// + /// + /// + [HttpGet("detail")] + [DisplayName("获取角色详情")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _roleService.Detail(input); + } + + /// + /// 获取角色选择器 + /// + /// + [HttpGet("roleSelector")] + [DisplayName("获取角色选择器")] + public async Task RoleSelector([FromQuery] RoleSelectorInput input) + { + return await _roleService.RoleSelector(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizUserController.cs b/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizUserController.cs new file mode 100644 index 0000000..cfbe283 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/Application/Organization/BizUserController.cs @@ -0,0 +1,232 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 人员管理控制器 +/// +[ApiDescriptionSettings("Application", Tag = "人员管理")] +[Route("biz/organization/user")] +[RolePermission] +public class BizUserController : IDynamicApiController +{ + private readonly IUserService _userService; + private readonly IOrgService _orgService; + private readonly IPositionService _positionService; + + public BizUserController(IUserService userService, IOrgService orgService, IPositionService positionService) + { + _userService = userService; + _orgService = orgService; + _positionService = positionService; + } + + #region Get请求 + + /// + /// 导入预览 + /// + /// + /// + [HttpPost("preview")] + [DisableRequestSizeLimit] + [SuppressMonitor] + [DisplayName("导入预览")] + public async Task Preview([FromForm] ImportPreviewInput input) + { + return await _userService.Preview(input); + } + + /// + /// 模板下载 + /// + /// + [HttpGet(template: "template")] + [SuppressMonitor] + public async Task Template() + { + return await _userService.Template(); + } + + + /// + /// 人员分页查询 + /// + /// + /// + [HttpGet("page")] + [DisplayName("人员分页查询")] + public async Task Page([FromQuery] UserPageInput input) + { + return await _userService.Page(input); + } + + /// + /// 获取人员选择器 + /// + /// + [HttpGet("selector")] + [DisplayName("人员选择器")] + public async Task Selector([FromQuery] UserSelectorInput input) + { + return await _userService.Selector(input); + } + + /// + /// 获取人员拥有角色 + /// + /// + /// + [HttpGet("ownRole")] + [DisplayName("获取人员拥有角色")] + public async Task OwnRole([FromQuery] BaseIdInput input) + { + return await _userService.OwnRole(input); + } + + /// + /// 人员详情 + /// + /// + /// + [HttpGet("detail")] + [DisplayName("人员详情")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _userService.Detail(input); + } + + #endregion Get请求 + + #region Post请求 + + /// + /// 添加人员 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加人员")] + public async Task Add([FromBody] UserAddInput input) + { + await _userService.Add(input); + } + + /// + /// 修改人员 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改人员")] + public async Task Edit([FromBody] UserEditInput input) + { + await _userService.Edit(input); + } + + /// + /// 批量修改人员 + /// + /// + /// + [HttpPost("edits")] + [DisplayName("批量修改人员")] + public async Task Edits([FromBody] BatchEditInput input) + { + await _userService.Edits(input); + } + + /// + /// 删除人员 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除人员")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _userService.Delete(input); + } + + /// + /// 禁用人员 + /// + /// + /// + [HttpPost("disableUser")] + [DisplayName("禁用人员")] + public async Task DisableUser([FromBody] BaseIdInput input) + { + await _userService.DisableUser(input); + } + + /// + /// 启用人员 + /// + /// + /// + [HttpPost("enableUser")] + [DisplayName("启用人员")] + public async Task EnableUser([FromBody] BaseIdInput input) + { + await _userService.EnableUser(input); + } + + /// + /// 重置密码 + /// + /// + /// + [HttpPost("resetPassword")] + [DisplayName("重置密码")] + public async Task ResetPassword([FromBody] BaseIdInput input) + { + await _userService.ResetPassword(input); + } + + /// + /// 给人员授权角色 + /// + /// + /// + [HttpPost("grantRole")] + [DisplayName("授权角色")] + public async Task GrantRole([FromBody] UserGrantRoleInput input) + { + await _userService.GrantRole(input); + } + + /// + /// 人员导入 + /// + /// + /// + [HttpPost("import")] + [DisplayName("人员导入")] + public async Task Import([SuppressMonitor][FromBody] ImportResultInput input) + { + return await _userService.Import(input); + } + + /// + /// 人员导出 + /// + /// + /// + [HttpPost("export")] + [DisplayName("人员导出")] + public async Task Export([FromBody] UserPageInput input) + { + return await _userService.Export(input); + } + + #endregion Post请求 +} diff --git a/SimpleAdmin.Web.Core/Controllers/Application/WeiBingJu/MedicinalController.cs b/SimpleAdmin.Web.Core/Controllers/Application/WeiBingJu/MedicinalController.cs new file mode 100644 index 0000000..6033c42 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/Application/WeiBingJu/MedicinalController.cs @@ -0,0 +1,88 @@ + +namespace SimpleAdmin.Web.Core; + +/// +/// 药材管理 +/// +[ApiDescriptionSettings("Application", Tag = "药材管理")] +[Route("biz/weibingju/medicinal")] +[RolePermission] +public class MedicinalController : IDynamicApiController +{ + private readonly IMedicinalService _medicinalService; + + public MedicinalController(IMedicinalService medicinalService) + { + _medicinalService = medicinalService; + } + + /// + /// 获取药材列表 + /// + [HttpGet("list")] + [DisplayName("获取药材列表")] + public async Task GetList([FromQuery] string medicinalName, [FromQuery] int pageNum = 1, [FromQuery] int pageSize = 10) + { + return await _medicinalService.GetMedicinalList(medicinalName, pageNum, pageSize); + } + + /// + /// 获取药材消耗记录 + /// + [HttpGet("consumption-records")] + [DisplayName("获取药材消耗记录")] + public async Task GetConsumptionRecords([FromQuery] long id, [FromQuery] int pageNum = 1, [FromQuery] int pageSize = 10) + { + return await _medicinalService.GetConsumptionRecords(id, pageNum, pageSize); + } + + /// + /// 获取药材下拉 + /// + [HttpGet("getmedicinaldictlist")] + [DisplayName("获取药材下拉")] + public async Task GetMedicinalDictList() + { + return await _medicinalService.GetMedicinalDictList(); + } + + /// + /// 获取药材添加记录 + /// + [HttpGet("addition-records")] + [DisplayName("获取药材添加记录")] + public async Task GetAdditionRecords(long id, [FromQuery] int pageNum = 1, [FromQuery] int pageSize = 10) + { + return await _medicinalService.GetAdditionRecords(id, pageNum, pageSize); + } + + /// + /// 添加药材 + /// + [HttpPost("add")] + [DisplayName("添加药材")] + public async Task AddMedicinal([FromBody] AddMedicinalInput input) + { + return await _medicinalService.AddMedicinal(input); + } + + /// + /// 修改药材添加记录 + /// + [HttpPost("addition-records")] + [DisplayName("修改药材添加记录")] + public async Task UpdateAdditionRecord([FromBody] UpdateMedicinalAddLogInput input) + { + return await _medicinalService.UpdateAdditionRecord(input); + } + + /// + /// 删除药材添加记录 + /// + [HttpPost("addition-delete")] + [DisplayName("删除药材添加记录")] + public async Task DeleteAdditionRecord(DeleteMedicinalLog input) + { + return await _medicinalService.DeleteAdditionRecord(input.Id); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/Application/WeiBingJu/PrescriptionController.cs b/SimpleAdmin.Web.Core/Controllers/Application/WeiBingJu/PrescriptionController.cs new file mode 100644 index 0000000..ef1d839 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/Application/WeiBingJu/PrescriptionController.cs @@ -0,0 +1,77 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 药材管理 +/// +[ApiDescriptionSettings("Application", Tag = "处方管理")] +[Route("biz/weibingju/prescription")] +[RolePermission] +public class PrescriptionController : IDynamicApiController +{ + private readonly IPrescriptionService _service; + + public PrescriptionController(IPrescriptionService service) + { + _service = service; + } + + /// + /// 获取处方列表 + /// + [HttpGet("list")] + [DisplayName("获取处方列表")] + public async Task GetList([FromQuery] PrescriptionQueryInput input) + { + return await _service.GetPrescriptionList(input); + } + + /// + /// 获取处方详情 + /// + [HttpGet("getprescriptiondetile")] + [DisplayName("获取处方详情")] + public async Task GetDetail(long id) + { + return await _service.GetPrescriptionDetail(id); + } + + /// + /// 保存处方(新增或编辑) + /// + [HttpPost("add")] + [DisplayName("保存处方(新增或编辑)")] + public async Task SavePrescription([FromBody] SavePrescriptionInput input) + { + return await _service.SavePrescription(input); + } + + /// + /// 获取人员列表 + /// + [HttpGet("persons")] + [DisplayName("获取人员列表")] + public async Task GetPersonList([FromQuery] PersonType? type, [FromQuery] long? employeeId) + { + return await _service.GetPersonList(type, employeeId); + } + + /// + /// 获取关系类型 + /// + [HttpGet("relation-types")] + [DisplayName("获取关系类型")] + public async Task GetRelationTypes() + { + return await _service.GetRelationTypes(); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Auth/AuthBController.cs b/SimpleAdmin.Web.Core/Controllers/System/Auth/AuthBController.cs new file mode 100644 index 0000000..2e5ee05 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Auth/AuthBController.cs @@ -0,0 +1,95 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// B端登录控制器 +/// +[ApiDescriptionSettings(Tag = "B端权限校验")] +[Route("sys/auth/b")] +public class AuthBController : BaseController +{ + private readonly IAuthService _authService; + + public AuthBController(IAuthService authService) + { + _authService = authService; + } + + /// + /// B端获取图片验证码 + /// + /// + [HttpGet("getPicCaptcha")] + [AllowAnonymous] + public async Task GetPicCaptcha() + { + return await _authService.GetCaptchaInfo(); + } + + /// + /// B端获取手机验证码 + /// + /// + /// + [HttpGet("getPhoneValidCode")] + [AllowAnonymous] + public async Task GetPhoneValidCode([FromQuery] GetPhoneValidCodeInput input) + { + return await _authService.GetPhoneValidCode(input, LoginClientTypeEnum.B); + } + + /// + /// B端登录 + /// + /// + /// + [AllowAnonymous] + [HttpPost("login")] + [DisplayName(EventSubscriberConst.LOGIN_B)] + public async Task Login(LoginInput input) + { + return await _authService.Login(input, LoginClientTypeEnum.B); + } + + /// + /// B端手机号登录 + /// + /// + /// + [AllowAnonymous] + [HttpPost("loginByPhone")] + public async Task LoginByPhone(LoginByPhoneInput input) + { + return await _authService.LoginByPhone(input, LoginClientTypeEnum.B); + } + + /// + /// 登出 + /// + /// + [HttpPost("logout")] + [DisplayName(EventSubscriberConst.LOGIN_OUT_B)] + public async Task LoginOut([FromBody] LoginOutInput input) + { + await _authService.LoginOut(input.Token, LoginClientTypeEnum.B); + } + + /// + /// 获取用户信息 + /// + /// + [HttpGet("getLoginUser")] + public async Task GetLoginUser() + { + return await _authService.GetLoginUser(); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Auth/SessionController.cs b/SimpleAdmin.Web.Core/Controllers/System/Auth/SessionController.cs new file mode 100644 index 0000000..a196813 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Auth/SessionController.cs @@ -0,0 +1,103 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 会话管理控制器 +/// +[ApiDescriptionSettings(Tag = "会话管理")] +[Route("sys/auth/[controller]")] +[SuperAdmin] +public class SessionController : BaseController +{ + private readonly ISessionService _sessionService; + + public SessionController(ISessionService sessionService) + { + _sessionService = sessionService; + } + + /// + /// B端会话分页 + /// + /// + /// + [HttpGet("b/page")] + public async Task PageB([FromQuery] SessionPageInput input) + { + return await _sessionService.PageB(input); + } + + /// + /// C端会话分页 + /// + /// + /// + [HttpGet("c/page")] + public async Task PageC([FromQuery] SessionPageInput input) + { + return await _sessionService.PageC(input); + } + + /// + /// 会话统计 + /// + /// + [HttpGet("analysis")] + public dynamic Analysis() + { + return _sessionService.Analysis(); + } + + /// + /// 强退B端会话 + /// + /// + [HttpPost("b/exitSession")] + [DisplayName("强退B端会话")] + public async Task ExitSessionForB([FromBody] BaseIdInput input) + { + await _sessionService.ExitSession(input); + } + + /// + /// 强退C端会话 + /// + /// + [HttpPost("c/exitSession")] + [DisplayName("强退C端会话")] + public async Task ExitSessionForC([FromBody] BaseIdInput input) + { + await _sessionService.ExitSession(input); + } + + /// + /// 强退B端Token + /// + /// + [HttpPost("b/ExitToken")] + [DisplayName("强退B端Token")] + public async Task ExitTokenForB([FromBody] ExitTokenInput input) + { + await _sessionService.ExitToken(input); + } + + /// + /// 强退C端Token + /// + /// + [HttpPost("c/ExitToken")] + [DisplayName("强退C端Token")] + public async Task ExitTokenForC([FromBody] ExitTokenInput input) + { + await _sessionService.ExitToken(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/BaseController.cs b/SimpleAdmin.Web.Core/Controllers/System/BaseController.cs new file mode 100644 index 0000000..35de4ed --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/BaseController.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 基础控制器 +/// +[Route("sys/[controller]")] +public class BaseController : IDynamicApiController +{ +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/BatchEdit/BatchEditController.cs b/SimpleAdmin.Web.Core/Controllers/System/BatchEdit/BatchEditController.cs new file mode 100644 index 0000000..3b9ff7d --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/BatchEdit/BatchEditController.cs @@ -0,0 +1,124 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 批量控制器 +/// +[ApiDescriptionSettings(Tag = "批量修改")] +[Route("/sys/batch")] +public class BatchEditController : BaseController +{ + private readonly IBatchEditService _batchEditService; + + public BatchEditController(IBatchEditService updateBatchService) + { + _batchEditService = updateBatchService; + } + + #region Get请求 + + /// + /// 批量分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] BatchEditPageInput input) + { + return await _batchEditService.Page(input); + } + + /// + /// 获取表信息 + /// + /// + [HttpGet("tables")] + public dynamic Tables() + { + return _batchEditService.GetTables(); + } + + /// + /// 获取批量配置信息 + /// + /// + [HttpGet("configs")] + public async Task ConfigList([FromQuery] BaseIdInput input) + { + return await _batchEditService.ConfigList(input); + } + + /// + /// 获取批量配置信息 + /// + /// + [HttpGet("columns")] + [IgnoreSuperAdmin] + public async Task Columns([FromQuery] string code) + { + return await _batchEditService.Columns(code); + } + + #endregion Get请求 + + #region Post请求 + + /// + /// 添加批量 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加批量更新")] + public async Task Add([FromBody] BatchEditAddInput input) + { + await _batchEditService.Add(input); + } + + /// + /// 配置修改批量 + /// + /// + /// + [HttpPost("config")] + [DisplayName("配置批量更新")] + public async Task Config([FromBody] List input) + { + await _batchEditService.Config(input); + } + + /// + /// 删除批量 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除批量更新")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _batchEditService.Delete(input); + } + + /// + /// 批量更新同步 + /// + /// + /// + [HttpPost("sync")] + [DisplayName("批量更新同步")] + public async Task Sync([FromBody] BaseIdInput input) + { + await _batchEditService.SyncColumns(input); + } + + #endregion Post请求 +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/CommonController.cs b/SimpleAdmin.Web.Core/Controllers/System/CommonController.cs new file mode 100644 index 0000000..3517b9c --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/CommonController.cs @@ -0,0 +1,84 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 系统通用控制器,一般是一些公共的接口 +/// +[Route("sys")] +public class CommonController : BaseController +{ + private readonly ISysOrgService _sysOrgService; + private readonly IConfigService _configService; + + public CommonController(IConfigService configService, ISysOrgService sysOrgService) + { + _sysOrgService = sysOrgService; + _configService = configService; + } + + + /// + /// 获取系统基础配置 + /// + /// + [HttpGet("ico")] + [AllowAnonymous] + [NonUnify] + public async Task Ico() + { + return await _configService.GetIco(); + } + + /// + /// 获取系统基础配置 + /// + /// + [HttpGet("sysInfo")] + [AllowAnonymous] + public async Task SysInfo() + { + var sysBase = await _configService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_BASE); + //排除掉一些不需要的配置 + var configKeys = new List() + { + SysConfigConst.SYS_ICO, + SysConfigConst.SYS_WEB_STATUS, + SysConfigConst.SYS_WEB_CLOSE_PROMPT, + SysConfigConst.SYS_DEFAULT_WORKBENCH_DATA + }; + sysBase = sysBase.Where(x => !configKeys.Contains(x.ConfigKey)).ToList(); + return sysBase; + } + + /// + /// 获取系统基础配置 + /// + /// + [HttpGet("loginPolicy")] + [AllowAnonymous] + public async Task LoginPolicy() + { + var loginPolicy = await _configService.GetConfigsByCategory(CateGoryConst.CONFIG_LOGIN_POLICY);//登录策略 + return loginPolicy; + } + + /// + /// 获取租户列表 + /// + /// + [HttpGet("tenantList")] + [AllowAnonymous] + public async Task TenantList() + { + return await _sysOrgService.GetTenantList(); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Dev/FileController.cs b/SimpleAdmin.Web.Core/Controllers/System/Dev/FileController.cs new file mode 100644 index 0000000..dfc62f1 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Dev/FileController.cs @@ -0,0 +1,89 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 文件管理控制器 +/// +[ApiDescriptionSettings(Tag = "文件管理")] +[Route("sys/dev/[controller]")] +public class FileController : BaseController +{ + private readonly IFileService _fileService; + + public FileController(IFileService fileService) + { + _fileService = fileService; + } + + /// + /// 文件查询分页 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] FilePageInput input) + { + return await _fileService.Page(input); + } + + /// + /// 上传本地文件 + /// + /// + /// + [HttpPost("uploadLocal")] + [DisplayName("上传本地文件")] + [Consumes("multipart/form-data")] + [DisableRequestSizeLimit] + public async Task UploadLocal(IFormFile file) + { + return await _fileService.UploadFile(SysDictConst.FILE_ENGINE_LOCAL, file); + } + + /// + /// 上传MINIO文件 + /// + /// + /// + [HttpPost("uploadMinio")] + [DisplayName("上传MINIO文件")] + [DisableRequestSizeLimit] + [Consumes("multipart/form-data")] + public async Task UploadMinio(IFormFile file) + { + return await _fileService.UploadFile(SysDictConst.FILE_ENGINE_MINIO, file); + } + + /// + /// 删除文件 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除文件")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _fileService.Delete(input); + } + + /// + /// 下载文件 + /// + /// + /// + [HttpGet("download")] + [DisplayName("下载文件")] + public async Task DownLoad([FromQuery] BaseIdInput input) + { + return await _fileService.Download(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Dev/MessageController.cs b/SimpleAdmin.Web.Core/Controllers/System/Dev/MessageController.cs new file mode 100644 index 0000000..8966e4b --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Dev/MessageController.cs @@ -0,0 +1,83 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 站内信控制器 +/// +[ApiDescriptionSettings(Tag = "站内信")] +[Route("sys/dev/[controller]")] +public class MessageController : BaseController +{ + private readonly IMessageService _messageService; + + public MessageController(IMessageService messageService) + { + _messageService = messageService; + } + + /// + /// 分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] MessagePageInput input) + { + return await _messageService.Page(input); + } + + + /// + /// 添加站内信 + /// + /// + [HttpPost("add")] + [DisplayName("添加站内信")] + public async Task Add([FromBody] MessageSendInput input) + { + await _messageService.Add(input); + } + + /// + /// 编辑站内信 + /// + /// + [HttpPost("edit")] + [DisplayName("编辑站内信")] + public async Task Edit([FromBody] MessageSendUpdateInput input) + { + await _messageService.Edit(input); + } + + /// + /// 消息详情 + /// + /// + /// + [HttpGet("detail")] + public async Task Detail([FromQuery] MessageDetailInput input) + { + return await _messageService.Detail(input); + } + + /// + /// 删除站内信 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除站内信")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _messageService.Delete(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Gen/GenBasicController.cs b/SimpleAdmin.Web.Core/Controllers/System/Gen/GenBasicController.cs new file mode 100644 index 0000000..4396eaa --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Gen/GenBasicController.cs @@ -0,0 +1,119 @@ +namespace SimpleAdmin.Web.Core; + +/// +/// 代码生成基础控制器 +/// +[ApiDescriptionSettings(Tag = "代码生成基础")] +[Route("sys/curd/gen/basic")] +[SuperAdmin] +public class GenBasicController : IDynamicApiController +{ + private readonly IGenbasicService _genbasicService; + + public GenBasicController(IGenbasicService genbasicService) + { + _genbasicService = genbasicService; + } + + /// + /// 代码生成基础分页 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] BasePageInput input) + { + return await _genbasicService.Page(input); + } + + /// + /// 获取所有表信息 + /// + /// + [HttpGet("tables")] + public dynamic Tables(bool isAll = false) + { + return _genbasicService.GetTables(isAll); + } + + /// + /// 获取项目所有程序集 + /// + /// + [HttpGet("assemblies")] + public dynamic GetAssemblies() + { + return _genbasicService.GetAssemblies(); + } + + /// + /// 添加代码生成器 + /// + /// + /// + [DisplayName("添加代码生成")] + [HttpPost("add")] + public async Task Add([FromBody] GenBasicAddInput input) + { + return await _genbasicService.Add(input); + } + + /// + /// 编辑代码生成器 + /// + /// + /// + [DisplayName("编辑代码生成基础")] + [HttpPost("edit")] + public async Task Edit([FromBody] GenBasicEditInput input) + { + return await _genbasicService.Edit(input); + } + + /// + /// 删除代码生成配置 + /// + /// + /// + [DisplayName("删除代码生成基础")] + [HttpPost("delete")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _genbasicService.Delete(input); + } + + /// + /// 代码生成预览 + /// + /// + /// + [HttpGet("previewGen")] + public async Task PreviewGen([FromQuery] BaseIdInput input) + { + return await _genbasicService.PreviewGen(input); + } + + /// + /// 执行代码生成(本地)" + /// + /// + /// + [DisplayName("执行代码生成(本地)")] + [HttpPost("execGenPro")] + public async Task ExecGenPro([FromBody] ExecGenInput input) + { + await _genbasicService.ExecGenPro(input); + } + + /// + /// 执行代码生成(压缩包) + /// + /// + /// + [DisplayName("执行代码生成(压缩包)")] + [HttpGet("execGenZip")] + public async Task ExecGenZip([FromQuery] ExecGenInput input) + { + return await _genbasicService.ExecGenZip(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Gen/GenConfigController.cs b/SimpleAdmin.Web.Core/Controllers/System/Gen/GenConfigController.cs new file mode 100644 index 0000000..5e6f1ac --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Gen/GenConfigController.cs @@ -0,0 +1,41 @@ +namespace SimpleAdmin.Web.Core; + +/// +/// 代码生成配置控制器 +/// +[ApiDescriptionSettings(Tag = "代码生成配置")] +[Route("sys/curd/gen/config")] +[SuperAdmin] +public class GenConfigController : IDynamicApiController +{ + private readonly IGenConfigService _genConfigService; + + public GenConfigController(IGenConfigService genConfigService) + { + _genConfigService = genConfigService; + } + + /// + /// 查询代码生成详细配置列表 + /// + /// + /// + [HttpGet("list")] + [QueryParameters] + public async Task List(string basicId) + { + return await _genConfigService.List(basicId.ToLong()); + } + + /// + /// 编辑代码生成详细 + /// + /// + /// + [DisplayName("编辑代码生成详细")] + [HttpPost("editBatch")] + public async Task EditBatch([FromBody] List input) + { + await _genConfigService.EditBatch(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Index/IndexController.cs b/SimpleAdmin.Web.Core/Controllers/System/Index/IndexController.cs new file mode 100644 index 0000000..661969d --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Index/IndexController.cs @@ -0,0 +1,99 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 系统首页控制器 +/// +[ApiDescriptionSettings(Tag = "系统首页")] +[Route("home/index")] +[RolePermission] +public class IndexController : BaseController +{ + private readonly IVisitLogService _visitLogService; + private readonly IOperateLogService _operateLogService; + private readonly IIndexService _indexService; + + public IndexController(IVisitLogService visitLogService, IOperateLogService operateLogService, IIndexService indexService) + { + _visitLogService = visitLogService; + _operateLogService = operateLogService; + _indexService = indexService; + } + + /// + /// 获取当前用户访问日志列表 + /// + /// + [HttpGet("visLog/list")] + [DisplayName("访问日志")] + public async Task VisLogList() + { + return await _visitLogService.Page(new VisitLogPageInput { Account = UserManager.UserAccount }); + } + + /// + /// 获取当前用户操作日志列表 + /// + /// + [HttpGet("opLog/list")] + [DisplayName("操作日志")] + public async Task OpLogList() + { + return await _operateLogService.Page(new OperateLogPageInput { Account = UserManager.UserAccount }); + } + + /// + /// 获取当前用户站内信列表 + /// + /// + [HttpGet("message/list")] + [DisplayName("站内信列表")] + public async Task MessageList() + { + return new string[] { }; + } + + /// + /// 获取当前用户日程列表 + /// + /// + [HttpGet("schedule/list")] + [DisplayName("日程列表")] + public async Task ScheduleList([FromQuery] ScheduleListInput input) + { + return await _indexService.ScheduleList(input); + } + + /// + /// 添加日程 + /// + /// + /// + [HttpPost("schedule/add")] + [DisplayName("添加日程")] + public async Task AddSchedule([FromBody] ScheduleAddInput input) + { + await _indexService.AddSchedule(input); + } + + /// + /// 删除日程 + /// + /// + /// + [HttpPost("schedule/deleteSchedule")] + [DisplayName("删除日程")] + public async Task DeleteSchedule([FromBody] BaseIdListInput input) + { + await _indexService.DeleteSchedule(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Limit/ButtonController.cs b/SimpleAdmin.Web.Core/Controllers/System/Limit/ButtonController.cs new file mode 100644 index 0000000..65ce668 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Limit/ButtonController.cs @@ -0,0 +1,97 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 权限按钮控制器 +/// +[ApiDescriptionSettings(Tag = "权限按钮")] +[Route("sys/limit/[controller]")] +[SuperAdmin] +public class ButtonController : BaseController +{ + private readonly IButtonService _buttonService; + + public ButtonController(IButtonService buttonService) + { + _buttonService = buttonService; + } + + /// + /// 按钮分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] ButtonPageInput input) + { + return await _buttonService.Page(input); + } + + /// + /// 添加按钮 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加按钮")] + public async Task Add([FromBody] ButtonAddInput input) + { + await _buttonService.Add(input); + } + + /// + /// 修改按钮 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改按钮")] + public async Task Edit([FromBody] ButtonEditInput input) + { + await _buttonService.Edit(input); + } + + /// + /// 删除按钮 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除按钮")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _buttonService.Delete(input); + } + + /// + /// 批量新增 + /// + /// + /// + [HttpPost("batch")] + [DisplayName("新增按钮")] + public async Task Batch([FromBody] ButtonAddInput input) + { + await _buttonService.AddBatch(input); + } + + /// + /// 获取按钮详情 + /// + /// + /// + [HttpGet("detail")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _buttonService.Detail(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Limit/MenuController.cs b/SimpleAdmin.Web.Core/Controllers/System/Limit/MenuController.cs new file mode 100644 index 0000000..033e262 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Limit/MenuController.cs @@ -0,0 +1,125 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 菜单管理控制器 +/// +[ApiDescriptionSettings(Tag = "菜单管理")] +[Route("sys/limit/[controller]")] +[SuperAdmin] +public class MenuController : BaseController +{ + private readonly IMenuService _menuService; + private readonly IResourceService _resourceService; + + public MenuController(IMenuService menuService, IResourceService resourceService) + { + _menuService = menuService; + _resourceService = resourceService; + } + + /// + /// 模块选择 + /// + /// + [HttpGet("moduleSelector")] + public async Task ModuleSelector() + { + return await _resourceService.GetListByCategory(CateGoryConst.RESOURCE_MODULE); + } + + /// + /// 获取菜单树 + /// + /// + [HttpGet("tree")] + public async Task Tree([FromQuery] MenuTreeInput input) + { + return await _menuService.Tree(input); + } + + /// + /// 获取菜单树选择器 + /// + /// + [HttpGet("menuTreeSelector")] + public async Task MenuTreeSelector([FromQuery] MenuTreeInput input) + { + if (input.Module != null) + { + return await _menuService.Tree(input, false); + } + else + { + return await _menuService.ShortcutTree(); + } + } + + /// + /// 添加菜单 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加菜单")] + public async Task Add([FromBody] MenuAddInput input) + { + await _menuService.Add(input); + } + + /// + /// 编辑菜单 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("编辑菜单")] + public async Task Edit([FromBody] MenuEditInput input) + { + await _menuService.Edit(input); + } + + /// + /// 获取菜单详情 + /// + /// + [HttpGet("detail")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _menuService.Detail(input); + ; + } + + /// + /// 删除菜单 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除菜单")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _menuService.Delete(input); + } + + /// + /// 更改模块 + /// + /// + /// + [HttpPost("changeModule")] + [DisplayName("更改模块")] + public async Task ChangeModule([FromBody] MenuChangeModuleInput input) + { + await _menuService.ChangeModule(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Limit/ModuleController.cs b/SimpleAdmin.Web.Core/Controllers/System/Limit/ModuleController.cs new file mode 100644 index 0000000..ac53c7f --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Limit/ModuleController.cs @@ -0,0 +1,95 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 模块管理控制器 +/// +[ApiDescriptionSettings(Tag = "模块管理")] +[Route("sys/limit/[controller]")] +[SuperAdmin] +public class ModuleController : BaseController +{ + private readonly IModuleService _moduleService; + + public ModuleController(IModuleService moduleService) + { + _moduleService = moduleService; + } + + /// + /// 模块分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] ModulePageInput input) + { + return await _moduleService.Page(input); + } + + /// + /// 添加模块 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加模块")] + public async Task Add([FromBody] ModuleAddInput input) + { + await _moduleService.Add(input); + } + + /// + /// 修改模块 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改模块")] + public async Task Edit([FromBody] ModuleEditInput input) + { + await _moduleService.Edit(input); + } + + /// + /// 删除模块 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除模块")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _moduleService.Delete(input); + } + + /// + /// 获取模块详情 + /// + /// + /// + [HttpGet("detail")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _moduleService.Detail(input); + } + + /// + /// 模块列表 + /// + /// + [HttpGet("list")] + public async Task List() + { + return await _moduleService.List(); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Limit/RoleController.cs b/SimpleAdmin.Web.Core/Controllers/System/Limit/RoleController.cs new file mode 100644 index 0000000..c8c3ceb --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Limit/RoleController.cs @@ -0,0 +1,199 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 角色管理控制器 +/// +[ApiDescriptionSettings(Tag = "角色管理")] +[Route("sys/limit/[controller]")] +[SuperAdmin] +public class RoleController : BaseController +{ + private readonly ISysRoleService _sysRoleService; + private readonly IResourceService _resourceService; + + public RoleController(ISysRoleService sysRoleService, IResourceService resourceService) + { + _sysRoleService = sysRoleService; + _resourceService = resourceService; + } + + /// + /// 角色分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] RolePageInput input) + { + return await _sysRoleService.Page(input); + } + + /// + /// 添加角色 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加角色")] + public async Task Add([FromBody] RoleAddInput input) + { + await _sysRoleService.Add(input); + } + + /// + /// 修改角色 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改角色")] + public async Task Edit([FromBody] RoleEditInput input) + { + await _sysRoleService.Edit(input); + } + + /// + /// 删除角色 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除角色")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _sysRoleService.Delete(input); + } + + /// + /// 获取角色授权资源树 + /// + /// + [HttpGet("resourceTreeSelector")] + public async Task ResourceTreeSelector() + { + return await _resourceService.ResourceTreeSelector(); + } + + /// + /// 获取角色拥有资源 + /// + /// + /// + [HttpGet("ownResource")] + public async Task OwnResource([FromQuery] BaseIdInput input) + { + return await _sysRoleService.OwnResource(input, CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE); + } + + /// + /// 给角色授权资源 + /// + /// + /// + [HttpPost("grantResource")] + [DisplayName("角色授权资源")] + public async Task GrantResource([FromBody] GrantResourceInput input) + { + await _sysRoleService.GrantResource(input); + } + + /// + /// 获取权限授权树 + /// + /// + [HttpGet("permissionTreeSelector")] + public async Task PermissionTreeSelector([FromQuery] BaseIdInput input) + { + return await _sysRoleService.RolePermissionTreeSelector(input); + } + + /// + /// 获取角色拥有权限 + /// + /// + /// + [HttpGet("ownPermission")] + public async Task OwnPermission([FromQuery] BaseIdInput input) + { + return await _sysRoleService.OwnPermission(input); + } + + /// + /// 给角色授权权限 + /// + /// + /// + [HttpPost("grantPermission")] + [DisplayName("角色授权权限")] + public async Task GrantPermission([FromBody] GrantPermissionInput input) + { + await _sysRoleService.GrantPermission(input); + } + + + /// + /// 获取角色下的用户 + /// + /// + /// + [HttpGet("ownUser")] + public async Task OwnUser([FromQuery] BaseIdInput input) + { + return await _sysRoleService.OwnUser(input); + } + + /// + /// 给角色授权用户 + /// + /// + /// + [HttpPost("grantUser")] + [DisplayName("角色授权")] + public async Task GrantUser([FromBody] GrantUserInput input) + { + await _sysRoleService.GrantUser(input); + } + + /// + /// 获取角色树 + /// + /// + [HttpGet("tree")] + [DisplayName("获取角色树")] + public async Task Tree([FromQuery] RoleTreeInput input) + { + return await _sysRoleService.Tree(input); + } + + + /// + /// 获取角色详情 + /// + /// + /// + [HttpGet("detail")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _sysRoleService.Detail(input); + } + + /// + /// 获取角色选择器 + /// + /// + [HttpGet("roleSelector")] + public async Task RoleSelector([FromQuery] RoleSelectorInput input) + { + return await _sysRoleService.RoleSelector(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Limit/SpaController.cs b/SimpleAdmin.Web.Core/Controllers/System/Limit/SpaController.cs new file mode 100644 index 0000000..9051a3b --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Limit/SpaController.cs @@ -0,0 +1,85 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 单页管理控制器 +/// +[ApiDescriptionSettings(Tag = "单页管理")] +[Route("sys/limit/[controller]")] +[SuperAdmin] +public class SpaController : BaseController +{ + private readonly ISpaService _spaService; + + public SpaController(ISpaService spaService) + { + _spaService = spaService; + } + + /// + /// 单页分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] SpaPageInput input) + { + return await _spaService.Page(input); + } + + /// + /// 添加单页 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加单页")] + public async Task Add([FromBody] SpaAddInput input) + { + await _spaService.Add(input); + } + + /// + /// 修改单页 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改单页")] + public async Task Edit([FromBody] SpaEditInput input) + { + await _spaService.Edit(input); + } + + /// + /// 删除单页 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除单页")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _spaService.Delete(input); + } + + /// + /// 获取单页详情 + /// + /// + /// + [HttpGet("detail")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _spaService.Detail(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/LogAudit/LogOperateController.cs b/SimpleAdmin.Web.Core/Controllers/System/LogAudit/LogOperateController.cs new file mode 100644 index 0000000..d9e38aa --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/LogAudit/LogOperateController.cs @@ -0,0 +1,80 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 操作日志控制器 +/// +[ApiDescriptionSettings(Tag = "操作日志")] +[Route("sys/audit/[controller]")] +[SuperAdmin] +public class LogOperateController : BaseController +{ + private readonly IOperateLogService _operateLogService; + + public LogOperateController(IOperateLogService operateLogService) + { + _operateLogService = operateLogService; + } + + /// + /// 操作日志分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] OperateLogPageInput input) + { + return await _operateLogService.Page(input); + } + + /// + /// 操作日志周统计柱状图图 + /// + /// + [HttpGet("columnChartData")] + public async Task BarChartData() + { + return await _operateLogService.StatisticsByDay(7); + } + + /// + /// 操作日志数量总览饼图 + /// + /// + [HttpGet("pieChartData")] + public async Task PieChartData() + { + return await _operateLogService.TotalCount(); + } + + /// + /// 清空日志 + /// + /// + /// + [HttpPost("delete")] + public async Task Delete([FromBody] OperateLogDeleteInput input) + { + await _operateLogService.Delete(input.Category); + } + + /// + /// 日志详情 + /// + /// + /// + [HttpGet("detail")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _operateLogService.Detail(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/LogAudit/LogVisitController.cs b/SimpleAdmin.Web.Core/Controllers/System/LogAudit/LogVisitController.cs new file mode 100644 index 0000000..b15b6a7 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/LogAudit/LogVisitController.cs @@ -0,0 +1,69 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 访问日志控制器 +/// +[ApiDescriptionSettings(Tag = "访问日志")] +[Route("sys/audit/[controller]")] +[SuperAdmin] +public class LogVisitController : BaseController +{ + private readonly IVisitLogService _visitLogService; + + public LogVisitController(IVisitLogService visitLogService) + { + _visitLogService = visitLogService; + } + + /// + /// 访问日志分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] VisitLogPageInput input) + { + return await _visitLogService.Page(input); + } + + /// + /// 访问日志周统计折线图 + /// + /// + [HttpGet("lineChartData")] + public async Task LineChartData() + { + return await _visitLogService.StatisticsByDay(7); + } + + /// + /// 访问日志总览饼图 + /// + /// + [HttpGet("pieChartData")] + public async Task PieChartData() + { + return await _visitLogService.TotalCount(); + } + + /// + /// 清空日志 + /// + /// + /// + [HttpPost("delete")] + public async Task Delete([FromBody] VisitLogDeleteInput input) + { + await _visitLogService.Delete(input.Category); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Mqtt/MqttController.cs b/SimpleAdmin.Web.Core/Controllers/System/Mqtt/MqttController.cs new file mode 100644 index 0000000..eae03a4 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Mqtt/MqttController.cs @@ -0,0 +1,39 @@ +namespace SimpleAdmin.Web.Core; + +/// +/// mqtt服务控制器 +/// +[ApiDescriptionSettings(Tag = "mqtt服务")] +[Route("mqtt")] +public class MqttController : IDynamicApiController +{ + private readonly IMqttService _mqttService; + + public MqttController(IMqttService mqttService) + { + _mqttService = mqttService; + } + + /// + /// 获取mqtt登录参数 + /// + /// + [HttpGet("getParameter")] + public async Task GetParameter() + { + return await _mqttService.GetWebLoginParameter(); + } + + /// + /// mqtt认证 + /// + /// + /// + [HttpPost("auth")] + [AllowAnonymous] + [NonUnify] + public async Task Auth([FromBody] MqttAuthInput input) + { + return await _mqttService.Auth(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Ops/ConfigController.cs b/SimpleAdmin.Web.Core/Controllers/System/Ops/ConfigController.cs new file mode 100644 index 0000000..5ec1dee --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Ops/ConfigController.cs @@ -0,0 +1,109 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 系统配置控制器 +/// +[ApiDescriptionSettings(Tag = "系统配置")] +[Route("sys/ops/[controller]")] +[SuperAdmin] +public class ConfigController : BaseController +{ + private readonly IConfigService _configService;//系统配置服务 + + public ConfigController(IConfigService configService) + { + _configService = configService; + } + + + /// + /// 获取系统基础配置 + /// + /// + [HttpGet("sysBaseList")] + public async Task SysBaseList() + { + var sysBase = await _configService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_BASE);//系统基础 + var loginPolicy = await _configService.GetConfigsByCategory(CateGoryConst.CONFIG_LOGIN_POLICY);//登录策略 + sysBase.AddRange(loginPolicy);//合并登录策略 + return sysBase; + } + + /// + /// 获取系统配置列表 + /// + /// + [HttpGet("list")] + public async Task List() + { + return await _configService.GetSysConfigList(); + } + + /// + /// 配置分页 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] ConfigPageInput input) + { + return await _configService.Page(input); + } + + /// + /// 添加配置 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加配置")] + public async Task Add([FromBody] ConfigAddInput input) + { + await _configService.Add(input); + } + + /// + /// 修改配置 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改配置")] + public async Task Edit([FromBody] ConfigEditInput input) + { + await _configService.Edit(input); + } + + /// + /// 删除配置 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除配置")] + public async Task Delete([FromBody] ConfigDeleteInput input) + { + await _configService.Delete(input); + } + + /// + /// 配置批量更新 + /// + /// + [HttpPost("editBatch")] + [DisplayName("修改配置")] + public async Task EditBatch([FromBody] List devConfigs) + { + await _configService.EditBatch(devConfigs); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Ops/DictController.cs b/SimpleAdmin.Web.Core/Controllers/System/Ops/DictController.cs new file mode 100644 index 0000000..35d55f7 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Ops/DictController.cs @@ -0,0 +1,85 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 系统字典控制器 +/// +[ApiDescriptionSettings(Tag = "系统字典")] +[Route("sys/ops/[controller]")] +[SuperAdmin] +public class DictController : BaseController +{ + private readonly IDictService _dictService; + + public DictController(IDictService dictService) + { + _dictService = dictService; + } + + /// + /// 获取字典树 + /// + /// + [HttpGet("tree")] + [IgnoreSuperAdmin] + public async Task Tree([FromQuery] DictTreeInput input) + { + return await _dictService.Tree(input); + } + + /// + /// 字典分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] DictPageInput input) + { + return await _dictService.Page(input); + } + + /// + /// 添加字典 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加字典")] + public async Task Add([FromBody] DictAddInput input) + { + await _dictService.Add(input); + } + + /// + /// 修改字典 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改字典")] + public async Task Edit([FromBody] DictEditInput input) + { + await _dictService.Edit(input); + } + + /// + /// 删除字典 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除字典")] + public async Task Delete([FromBody] DictDeleteInput input) + { + await _dictService.Delete(input); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Organization/OrgController.cs b/SimpleAdmin.Web.Core/Controllers/System/Organization/OrgController.cs new file mode 100644 index 0000000..8a8bd09 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Organization/OrgController.cs @@ -0,0 +1,137 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 组织管理控制器 +/// +[ApiDescriptionSettings(Tag = "组织管理")] +[Route("sys/organization/[controller]")] +[SuperAdmin] +public class OrgController : BaseController +{ + private readonly ISysOrgService _sysOrgService; + private readonly ISysUserService _sysUserService; + + public OrgController(ISysOrgService sysOrgService, ISysUserService sysUserService) + { + _sysOrgService = sysOrgService; + _sysUserService = sysUserService; + } + + #region Get + + /// + /// 获取组织树 + /// + /// + [HttpGet("tree")] + public async Task Tree() + { + return await _sysOrgService.Tree(); + } + + /// + /// 获取组织树选择器 + /// + /// + [HttpGet("orgTreeSelector")] + public async Task OrgTreeSelector() + { + return await _sysOrgService.Tree(); + } + + /// + /// 组织分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] SysOrgPageInput input) + { + return await _sysOrgService.Page(input); + } + + /// + /// 获取用户选择器 + /// + /// + [HttpGet("selector")] + public async Task UserSelector([FromQuery] UserSelectorInput input) + { + return await _sysUserService.Selector(input); + } + + /// + /// 获取组织详情 + /// + /// + /// + [HttpGet("detail")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _sysOrgService.Detail(input); + } + + #endregion Get + + #region Post + + /// + /// 复制组织 + /// + /// + /// + [HttpPost("copy")] + [DisplayName("复制组织")] + public async Task Copy([FromBody] SysOrgCopyInput input) + { + await _sysOrgService.Copy(input); + } + + /// + /// 添加组织 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加组织")] + public async Task Add([FromBody] SysOrgAddInput input) + { + await _sysOrgService.Add(input); + } + + /// + /// 修改组织 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改组织")] + public async Task Edit([FromBody] SysOrgEditInput input) + { + await _sysOrgService.Edit(input); + } + + /// + /// 删除组织 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除组织")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _sysOrgService.Delete(input); + } + + #endregion Post +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Organization/PositionController.cs b/SimpleAdmin.Web.Core/Controllers/System/Organization/PositionController.cs new file mode 100644 index 0000000..a043982 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Organization/PositionController.cs @@ -0,0 +1,117 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 职位管理控制器 +/// +[ApiDescriptionSettings(Tag = "职位管理")] +[Route("sys/organization/[controller]")] +[SuperAdmin] +public class PositionController : BaseController +{ + private readonly ISysPositionService _sysPositionService; + + public PositionController(ISysPositionService sysPositionService) + { + _sysPositionService = sysPositionService; + } + + #region Get + + /// + /// 职位分页查询 + /// + /// + /// + [HttpGet("page")] + [DisplayName("职位分页查询")] + public async Task Page([FromQuery] PositionPageInput input) + { + return await _sysPositionService.Page(input); + } + + /// + /// 获取职位树 + /// + /// + [HttpGet("tree")] + [DisplayName("获取职位树")] + public async Task Tree([FromQuery] PositionTreeInput input) + { + return await _sysPositionService.Tree(input); + } + + /// + /// 职位选择器 + /// + /// + /// + [HttpGet("selector")] + public async Task Selector([FromQuery] PositionSelectorInput input) + { + return await _sysPositionService.Selector(input); + } + + /// + /// 获取职位详情 + /// + /// + /// + [HttpGet("detail")] + [DisplayName("获取职位详情")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _sysPositionService.Detail(input); + } + + #endregion + + #region Post + + /// + /// 添加职位 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加职位")] + public async Task Add([FromBody] PositionAddInput input) + { + await _sysPositionService.Add(input); + } + + /// + /// 修改职位 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改职位")] + public async Task Edit([FromBody] PositionEditInput input) + { + await _sysPositionService.Edit(input); + } + + /// + /// 删除职位 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除职位")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _sysPositionService.Delete(input); + } + + #endregion +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Organization/UserController.cs b/SimpleAdmin.Web.Core/Controllers/System/Organization/UserController.cs new file mode 100644 index 0000000..57da598 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Organization/UserController.cs @@ -0,0 +1,287 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 用户管理控制器 +/// +[ApiDescriptionSettings(Tag = "用户管理")] +[Route("sys/organization/[controller]")] +[SuperAdmin] +public class UserController : BaseController +{ + private readonly ISysUserService _sysUserService; + private readonly ISysOrgService _sysOrgService; + private readonly ISysPositionService _sysPositionService; + private readonly ISysRoleService _sysRoleService; + + public UserController(ISysUserService sysUserService, ISysOrgService sysOrgService, ISysPositionService sysPositionService, + ISysRoleService sysRoleService) + { + _sysUserService = sysUserService; + _sysOrgService = sysOrgService; + _sysPositionService = sysPositionService; + _sysRoleService = sysRoleService; + } + + #region Get请求 + + /// + /// 用户分页查询 + /// + /// + /// + [HttpGet("page")] + public async Task Page([FromQuery] UserPageInput input) + { + return await _sysUserService.Page(input); + } + + /// + /// 获取用户选择器 + /// + /// + /// + [HttpGet("selector")] + public async Task Selector([FromQuery] UserSelectorInput input) + { + return await _sysUserService.Selector(input); + } + + /// + /// 获取用户拥有角色 + /// + /// + /// + [HttpGet("ownRole")] + public async Task OwnRole([FromQuery] BaseIdInput input) + { + return await _sysUserService.OwnRole(input); + } + + /// + /// 获取用户拥有资源 + /// + /// + /// + [HttpGet("ownResource")] + public async Task OwnResource([FromQuery] BaseIdInput input) + { + return await _sysUserService.OwnResource(input); + } + + /// + /// 获取用户拥有权限 + /// + /// + /// + [HttpGet("ownPermission")] + public async Task OwnPermission([FromQuery] BaseIdInput input) + { + return await _sysUserService.OwnPermission(input); + } + + /// + /// 获取权限授权树 + /// + /// + [HttpGet("permissionTreeSelector")] + public async Task PermissionTreeSelector([FromQuery] BaseIdInput input) + { + return await _sysUserService.UserPermissionTreeSelector(input); + } + + /// + /// 导入预览 + /// + /// + /// + [HttpPost("preview")] + [DisableRequestSizeLimit] + [SuppressMonitor] + public async Task Preview([FromForm] ImportPreviewInput input) + { + return await _sysUserService.Preview(input); + } + + /// + /// 模板下载 + /// + /// + [HttpGet(template: "template")] + [SuppressMonitor] + public async Task Template() + { + return await _sysUserService.Template(); + } + + /// + /// 用户详情 + /// + /// + /// + [HttpGet("detail")] + [DisplayName("用户详情")] + public async Task Detail([FromQuery] BaseIdInput input) + { + return await _sysUserService.Detail(input); + } + + #endregion Get请求 + + #region Post请求 + + /// + /// 添加用户 + /// + /// + /// + [HttpPost("add")] + [DisplayName("添加用户")] + public async Task Add([FromBody] UserAddInput input) + { + await _sysUserService.Add(input); + } + + /// + /// 修改用户 + /// + /// + /// + [HttpPost("edit")] + [DisplayName("修改用户")] + public async Task Edit([FromBody] UserEditInput input) + { + await _sysUserService.Edit(input); + } + + /// + /// 批量修改用户 + /// + /// + /// + [HttpPost("edits")] + [DisplayName("批量修改用户")] + public async Task Edits([FromBody] BatchEditInput input) + { + await _sysUserService.Edits(input); + } + + /// + /// 删除用户 + /// + /// + /// + [HttpPost("delete")] + [DisplayName("删除用户")] + public async Task Delete([FromBody] BaseIdListInput input) + { + await _sysUserService.Delete(input); + } + + /// + /// 禁用用户 + /// + /// + /// + [HttpPost("disableUser")] + [DisplayName("禁用用户")] + public async Task DisableUser([FromBody] BaseIdInput input) + { + await _sysUserService.DisableUser(input); + } + + /// + /// 启用用户 + /// + /// + /// + [HttpPost("enableUser")] + [DisplayName("启用用户")] + public async Task EnableUser([FromBody] BaseIdInput input) + { + await _sysUserService.EnableUser(input); + } + + /// + /// 重置密码 + /// + /// + /// + [HttpPost("resetPassword")] + [DisplayName("重置密码")] + public async Task ResetPassword([FromBody] BaseIdInput input) + { + await _sysUserService.ResetPassword(input); + } + + /// + /// 给用户授权角色 + /// + /// + /// + [HttpPost("grantRole")] + [DisplayName("授权角色")] + public async Task GrantRole([FromBody] UserGrantRoleInput input) + { + await _sysUserService.GrantRole(input); + } + + /// + /// 给用户授权资源 + /// + /// + /// + [HttpPost("grantResource")] + [DisplayName("用户授权资源")] + public async Task GrantResource([FromBody] UserGrantResourceInput input) + { + await _sysUserService.GrantResource(input); + } + + /// + /// 给用户授权权限 + /// + /// + /// + [HttpPost("grantPermission")] + [DisplayName("用户授权权限")] + public async Task GrantPermission([FromBody] GrantPermissionInput input) + { + await _sysUserService.GrantPermission(input); + } + + /// + /// 用户导入 + /// + /// + /// + [HttpPost("import")] + [DisplayName("用户导入")] + public async Task Import([SuppressMonitor][FromBody] ImportResultInput input) + { + return await _sysUserService.Import(input); + } + + /// + /// 用户导出 + /// + /// + /// + [HttpPost("export")] + [DisplayName("用户导出")] + public async Task Export([FromBody] UserPageInput input) + { + return await _sysUserService.Export(input); + } + + #endregion Post请求 +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/Upload/UploadController.cs b/SimpleAdmin.Web.Core/Controllers/System/Upload/UploadController.cs new file mode 100644 index 0000000..b497e9a --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/Upload/UploadController.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +[ApiDescriptionSettings(Tag = "文件上传控制器")] +public class UploadController : BaseController +{ + private readonly IFileService _fileService; + + public UploadController(IFileService fileService) + { + _fileService = fileService; + } + + /// 1 + /// 上传图片 + /// + /// + /// + [HttpPost("uploadImg")] + [DisplayName("上传图片")] + [DisableRequestSizeLimit] + [Consumes("multipart/form-data")] + public async Task UploadImg(IFormFile file) + { + //先上传到本地,后面优化 + return await _fileService.UploadFile(SysDictConst.FILE_ENGINE_LOCAL, file); + } +} diff --git a/SimpleAdmin.Web.Core/Controllers/System/UserCenter/UserCenterController.cs b/SimpleAdmin.Web.Core/Controllers/System/UserCenter/UserCenterController.cs new file mode 100644 index 0000000..acf9f22 --- /dev/null +++ b/SimpleAdmin.Web.Core/Controllers/System/UserCenter/UserCenterController.cs @@ -0,0 +1,234 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 用户个人信息控制器 +/// +[ApiDescriptionSettings(Tag = "用户个人信息控制器")] +[Route("userCenter")] +public class UserCenterController : BaseController +{ + private readonly IUserCenterService _userCenterService; + + public UserCenterController(IUserCenterService userCenterService) + { + _userCenterService = userCenterService; + } + + + + #region Get + + /// + /// 获取个人菜单 + /// + /// + [HttpGet("loginMenu")] + public async Task LoginMenu([FromQuery] BaseIdInput input) + { + return await _userCenterService.GetLoginMenu(input); + } + + /// + /// 获取个人工作台 + /// + /// + [HttpGet("loginWorkbench")] + public async Task LoginWorkbench() + { + return await _userCenterService.GetLoginWorkbench(); + } + + + /// + /// 获取组织架构 + /// + /// + [HttpGet("loginOrgTree")] + public async Task LoginOrgTree() + { + return await _userCenterService.LoginOrgTree(); + } + + + /// + /// 修改密码 + /// + /// + /// + [HttpPost("updatePassword")] + [DisplayName("修改密码")] + public async Task UpdatePassword([FromBody] UpdatePasswordInput input) + { + await _userCenterService.UpdatePassword(input); + } + + /// + /// 修改头像 + /// + /// + /// + [HttpPost("updateAvatar")] + [DisplayName("修改头像")] + public async Task UpdateAvatar([FromForm] BaseFileInput input) + { + return await _userCenterService.UpdateAvatar(input); + } + + + /// + /// 修改默认模块 + /// + /// + [HttpPost("setDefaultModule")] + public async Task SetDefaultModule([FromBody] SetDefaultModuleInput input) + { + await _userCenterService.SetDefaultModule(input); + } + + + /// + /// 快捷方式菜单树 + /// + /// + /// + [HttpGet("shortcutTree")] + public async Task ShortcutTree() + { + return await _userCenterService.ShortcutTree(); + } + + #endregion + + #region Post + + /// + /// 编辑个人信息 + /// + /// + /// + [HttpPost("updateUserInfo")] + [DisplayName("编辑个人信息")] + public async Task UpdateUserInfo([FromBody] UpdateInfoInput input) + { + await _userCenterService.UpdateUserInfo(input); + } + + /// + /// 更新签名 + /// + /// + /// + [HttpPost("updateSignature")] + [DisplayName("更新签名")] + public async Task UpdateSignature([FromBody] UpdateSignatureInput input) + { + await _userCenterService.UpdateSignature(input); + } + + + + /// + /// 编辑工作台 + /// + /// + /// + [HttpPost("updateUserWorkbench")] + [DisplayName("编辑工作台")] + public async Task UpdateUserWorkbench([FromBody] UpdateWorkbenchInput input) + { + await _userCenterService.UpdateWorkbench(input); + } + + #endregion + + #region 我的消息 + + /// + /// 获取登录用户的站内信分页 + /// + /// + /// + [HttpGet("myMessagePage")] + public async Task MyMessagePage([FromQuery] MessagePageInput input) + { + return await _userCenterService.MyMessagePage(input); + } + + /// + /// 读取登录用户站内信详情 + /// + /// + /// + [HttpGet("myMessageDetail")] + public async Task MyMessageDetail([FromQuery] BaseIdInput input) + { + return await _userCenterService.MyMessageDetail(input); + } + + /// + /// 未读消息数 + /// + /// + [HttpGet("UnReadCount")] + public async Task UnReadCount() + { + return await _userCenterService.UnReadCount(); + } + + /// + /// 最新未读消息 + /// + /// + [HttpGet("newUnRead")] + public async Task NewUnRead() + { + return await _userCenterService.NewUnRead(); + } + + /// + /// 删除我的消息 + /// + /// + /// + [HttpPost("deleteMessage")] + [DisplayName("删除个人消息")] + public async Task DeleteMessage([FromBody] BaseIdInput input) + { + await _userCenterService.DeleteMyMessage(input); + } + + /// + /// 设置已读 + /// + /// + [HttpPost("setRead")] + public async Task SetRead([FromBody] MessageReadInput input) + { + input.Id = UserManager.UserId; + return await _userCenterService.SetRead(input); + } + + /// + /// 设置未读 + /// + /// + /// + [HttpPost("setDelete")] + public async Task SetDelete([FromBody] MessageReadInput input) + { + input.Id = UserManager.UserId; + return await _userCenterService.SetDelete(input); + } + + #endregion +} diff --git a/SimpleAdmin.Web.Core/Filter/MyActionFilter.cs b/SimpleAdmin.Web.Core/Filter/MyActionFilter.cs new file mode 100644 index 0000000..21934e3 --- /dev/null +++ b/SimpleAdmin.Web.Core/Filter/MyActionFilter.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using MoYu.FriendlyException; + +namespace SimpleAdmin.Web.Core; + +/// +/// 操作筛选器 +/// +public class MyActionFilter : IAsyncActionFilter +{ + public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) + { + // 获取控制器、路由信息 + var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; + + // 获取控制器类型 + var controllerType = actionDescriptor!.ControllerTypeInfo; + + // 获取请求的方法 + var method = actionDescriptor!.MethodInfo; + + // 获取 HttpContext 和 HttpRequest 对象 + var httpContext = context.HttpContext; + var httpRequest = httpContext.Request; + //拦截白名单 + var whiteAction = new[] { "loginOut", "auth", "preview" }; + //只拦截post方法并且不是 + if (httpRequest.Method == "POST" && !whiteAction.Contains(actionDescriptor.ActionName)) + { + // 是否匿名访问 + var allowAnonymous = context.Filters.Any(u => u is IAllowAnonymousFilter) + || controllerType.IsDefined(typeof(AllowAnonymousAttribute), true) || method.IsDefined(typeof(AllowAnonymousAttribute), true); + if (!allowAnonymous) + { + //如果不是匿名访问,抛出 + throw Oops.Bah("演示环境,禁止操作"); + } + } + await next(); + } +} diff --git a/SimpleAdmin.Web.Core/Filter/MyAuthorizationFilter.cs b/SimpleAdmin.Web.Core/Filter/MyAuthorizationFilter.cs new file mode 100644 index 0000000..af8dcde --- /dev/null +++ b/SimpleAdmin.Web.Core/Filter/MyAuthorizationFilter.cs @@ -0,0 +1,45 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 自定义授权筛选器 +/// +public class MyAuthorizationFilter : IAsyncAuthorizationFilter +{ + public async Task OnAuthorizationAsync(AuthorizationFilterContext context) + { + // 获取控制器信息 + var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; + + // 获取控制器类型 + var controllerType = actionDescriptor!.ControllerTypeInfo; + + // 获取 Action 类型 + var methodType = actionDescriptor.MethodInfo; + // 是否匿名访问 + var allowAnonymous = context.Filters.Any(u => u is IAllowAnonymousFilter) || controllerType.IsDefined(typeof(AllowAnonymousAttribute), true) + || methodType.IsDefined(typeof(AllowAnonymousAttribute), true); + + // 不是匿名才处理权限检查 + if (!allowAnonymous) + { + // 获取 HttpContext 和 HttpRequest 对象 + var httpContext = context.HttpContext; + if (httpContext.Response.StatusCode == 401) + { + // 返回未授权 + context.Result = new UnauthorizedResult(); + } + } + else await Task.CompletedTask;// 否则直接跳过处理 + } +} diff --git a/SimpleAdmin.Web.Core/GlobalUsing.cs b/SimpleAdmin.Web.Core/GlobalUsing.cs new file mode 100644 index 0000000..4ef2f44 --- /dev/null +++ b/SimpleAdmin.Web.Core/GlobalUsing.cs @@ -0,0 +1,46 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +global using MoYu; +global using MoYu.DynamicApiController; +global using MoYu.Logging; +global using Microsoft.AspNetCore.Authorization; +global using Microsoft.AspNetCore.Builder; +global using Microsoft.AspNetCore.Hosting; +global using Microsoft.AspNetCore.Http; +global using Microsoft.AspNetCore.Mvc; +global using Microsoft.AspNetCore.Mvc.Authorization; +global using Microsoft.AspNetCore.Mvc.Controllers; +global using Microsoft.AspNetCore.Mvc.Filters; +global using Microsoft.Extensions.DependencyInjection; +global using SimpleAdmin.Application; +global using SimpleAdmin.Cache; +global using SimpleAdmin.Core; +global using SimpleAdmin.SqlSugar; +global using SimpleAdmin.System; +global using System; +global using System.Collections.Generic; +global using System.ComponentModel; +global using System.Linq; +global using System.Threading.Tasks; +global using Microsoft.AspNetCore.HttpOverrides; +global using Microsoft.Extensions.FileProviders; +global using Microsoft.Extensions.Hosting; +global using Newtonsoft.Json; +global using Newtonsoft.Json.Serialization; +global using Microsoft.AspNetCore.Builder; +global using Microsoft.AspNetCore.Hosting; +global using IP2Region.Net.Abstractions; +global using IP2Region.Net.XDB; +global using NewLife; +global using SimpleAdmin.Application.Services.Medicinal; +global using SimpleAdmin.Application.Services.Medicinal.Dto; +global using SimpleAdmin.Application.Services.Prescription; +global using SimpleAdmin.Application.Services.Prescription.Dto; diff --git a/SimpleAdmin.Web.Core/Handlers/JwtHandler.cs b/SimpleAdmin.Web.Core/Handlers/JwtHandler.cs new file mode 100644 index 0000000..f9b2db8 --- /dev/null +++ b/SimpleAdmin.Web.Core/Handlers/JwtHandler.cs @@ -0,0 +1,142 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using MoYu.Authorization; +using MoYu.DataEncryption; +using MoYu.Logging.Extensions; +using System.Security.Claims; + +namespace SimpleAdmin.Web.Core; + +public class JwtHandler : AppAuthorizeHandler +{ + /// + /// 重写 Handler 添加自动刷新 + /// + /// + /// + /// + public override async Task HandleAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext) + { + var expire = App.GetConfig("JWTSettings:ExpiredTime");//获取过期时间(分钟) + var currentHttpContext = context.GetCurrentHttpContext(); + //自动刷新Token + if (JWTEncryption.AutoRefreshToken(context, currentHttpContext, expire, expire * 2)) + { + //判断token是否有效 + if (CheckTokenFromRedis(currentHttpContext, expire)) + { + await AuthorizeHandleAsync(context); + } + else + { + currentHttpContext.Response.StatusCode = 401;//返回401给授权筛选器用 + } + } + else + { + context.Fail();// 授权失败 + if (currentHttpContext == null) + return; + currentHttpContext.SignoutToSwagger(); + } + } + + /// + /// 检查token有效性 + /// + /// DefaultHttpContext + /// token有效期/分钟 + /// + private bool CheckTokenFromRedis(DefaultHttpContext context, int expire) + { + var token = JWTEncryption.GetJwtBearerToken(context);//获取当前token + var userId = App.User?.FindFirstValue(ClaimConst.USER_ID);//获取用户ID + var simpleCacheService = App.GetService();//获取redis实例 + var tokenInfos = simpleCacheService.HashGetOne>(CacheConst.CACHE_USER_TOKEN, userId);//获取token信息 + if (tokenInfos == null)//如果还是空 + { + return false; + } + + var tokenInfo = tokenInfos.Where(it => it.Token == token).FirstOrDefault();//获取redis中token值是当前token的对象 + if (tokenInfo != null) + { + // 自动刷新token返回新的Token + var accessToken = context.Response.Headers["access-token"].ToString(); + if (!string.IsNullOrEmpty(accessToken))//如果有新的刷新token + { + "返回新的刷新token".LogDebug(); + tokenInfo.Token = accessToken;//新的token + tokenInfo.TokenTimeout = DateTime.Now.AddMinutes(expire);//新的过期时间 + simpleCacheService.HashAdd(CacheConst.CACHE_USER_TOKEN, userId, tokenInfos);//更新token信息到redis + } + } + else + { + return false; + } + + return true; + } + + /// + /// 授权判断逻辑,授权通过返回 true,否则返回 false + /// + /// + /// + /// + public override async Task PipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext) + { + // 这里写您的授权判断逻辑,授权通过返回 true,否则返回 false + + // 此处已经自动验证 Jwt Token的有效性了,无需手动验证 + return await CheckAuthorizationAsync(httpContext); + } + + /// + /// 检查权限 + /// + /// + /// + private static async Task CheckAuthorizationAsync(DefaultHttpContext httpContext) + { + //超级管理员都能访问 + if (UserManager.SuperAdmin) return true; + // 获取超级管理员特性 + var isSuperAdmin = httpContext.GetMetadata(); + if (isSuperAdmin != null)//如果是超级管理员才能访问的接口 + { + //获取忽略超级管理员特性 + var ignoreSuperAdmin = httpContext.GetMetadata(); + if (ignoreSuperAdmin == null && !UserManager.SuperAdmin)//如果只能超级管理员访问并且用户不是超级管理员 + return false;//直接没权限 + } + + //获取角色授权特性 + var isRolePermission = httpContext.GetMetadata(); + if (isRolePermission != null) + { + //获取忽略角色授权特性 + var ignoreRolePermission = httpContext.GetMetadata(); + if (ignoreRolePermission == null) + { + // 路由名称 + var routeName = httpContext.Request.Path.Value; + //获取用户信息 + var userInfo = await App.GetService().GetUserById(UserManager.UserId); + if (!userInfo.PermissionCodeList.Contains(routeName))//如果当前路由信息不包含在角色授权路由列表中则认证失败 + return false; + } + } + + return true; + } +} diff --git a/SimpleAdmin.Web.Core/Handlers/LogExceptionHandler.cs b/SimpleAdmin.Web.Core/Handlers/LogExceptionHandler.cs new file mode 100644 index 0000000..449f4b4 --- /dev/null +++ b/SimpleAdmin.Web.Core/Handlers/LogExceptionHandler.cs @@ -0,0 +1,41 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using MoYu.DependencyInjection; +using MoYu.FriendlyException; +using Microsoft.Extensions.Logging; + +namespace SimpleAdmin.Web.Core; + +/// +/// 全局异常处理提供器 +/// +public class LogExceptionHandler : IGlobalExceptionHandler, ISingleton +{ + private readonly ILogger _logger; + + public LogExceptionHandler(ILogger logger) + { + _logger = logger; + } + + public async Task OnExceptionAsync(ExceptionContext context) + { + var exception = context.Exception;//获取异常 + //如果异常类型不是友好异常 + if (exception.GetType() != typeof(AppFriendlyException)) + { + _logger.LogError(exception, exception.Message); + //重新定义异常 + context.Exception = new AppFriendlyException("系统异常,请联系管理员", ErrorCodeEnum.A0000); + } + await Task.CompletedTask; + } +} diff --git a/SimpleAdmin.Web.Core/Logging/DatabaseLoggingWriter.cs b/SimpleAdmin.Web.Core/Logging/DatabaseLoggingWriter.cs new file mode 100644 index 0000000..ce895e1 --- /dev/null +++ b/SimpleAdmin.Web.Core/Logging/DatabaseLoggingWriter.cs @@ -0,0 +1,205 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using Masuit.Tools; +using Microsoft.Extensions.Logging; +using NewLife.Serialization; +using SqlSugar; +using System.Globalization; +using UAParser; + +namespace SimpleAdmin.Web.Core; + +/// +/// 数据库写入器 +/// +public class DatabaseLoggingWriter : IDatabaseLoggingWriter +{ + private readonly ISearcher _searcher; + private readonly SqlSugarScope _db; + private readonly ILogger _logger; + + public DatabaseLoggingWriter(ILogger logger, ISearcher searcher) + { + _db = DbContext.DB; + _logger = logger; + _searcher = searcher; + } + + public async Task WriteAsync(LogMessage logMsg, bool flush) + { + //获取请求json字符串 + var jsonString = logMsg.Context.Get("loggingMonitor").ToString(); + //转成实体 + var loggingMonitor = jsonString.ToJsonEntity(); + //日志时间赋值 + loggingMonitor.LogDateTime = logMsg.LogDateTime; + // loggingMonitor.ReturnInformation.Value + //验证失败和没有DisplayTitle之类的不记录日志 + if (loggingMonitor.Validation == null && loggingMonitor.DisplayTitle != null) + { + //获取操作名称 + var operation = loggingMonitor.DisplayTitle; + var client = (ClientInfo)logMsg.Context.Get(LoggingConst.CLIENT);//获取客户端信息 + var path = logMsg.Context.Get(LoggingConst.PATH).ToString();//获取操作名称 + var method = logMsg.Context.Get(LoggingConst.METHOD).ToString();//获取方法 + //表示访问日志 + if (operation == EventSubscriberConst.LOGIN_B || operation == EventSubscriberConst.LOGIN_OUT_B) + { + //如果没有异常信息 + if (loggingMonitor.Exception == null) + { + await CreateVisitLog(operation, loggingMonitor, client);//添加到访问日志 + } + else + { + //添加到异常日志 + await CreateOperationLog(operation, path, loggingMonitor, client); + } + } + else + { + //只有定义了Title的POST方法才记录日志 + if (!operation.Contains("/") && method == "POST") + { + //添加到操作日志 + await CreateOperationLog(operation, path, loggingMonitor, client); + } + } + } + } + + /// + /// 创建访问日志 + /// + /// 访问类型 + /// loggingMonitor + /// 客户端信息 + private async Task CreateVisitLog(string operation, LoggingMonitorJson loggingMonitor, ClientInfo clientInfo) + { + string name;//用户姓名 + string opAccount;//用户账号 + if (operation == EventSubscriberConst.LOGIN_B) + { + //如果是登录,用户信息就从返回值里拿 + var result = loggingMonitor.ReturnInformation.Value.ToJson();//返回值转json + var userInfo = result.ToJsonEntity>();//格式化成user表 + name = userInfo.Data.Name;//赋值姓名 + opAccount = userInfo.Data.Account;//赋值账号 + } + else + { + //如果是登录出,用户信息就从AuthorizationClaims里拿 + name = loggingMonitor.AuthorizationClaims.Where(it => it.Type == ClaimConst.NAME).Select(it => it.Value).FirstOrDefault(); + opAccount = loggingMonitor.AuthorizationClaims.Where(it => it.Type == ClaimConst.ACCOUNT).Select(it => it.Value).FirstOrDefault(); + } + //日志表实体 + var devLogVisit = new SysLogVisit + { + Name = operation, + Category = operation == EventSubscriberConst.LOGIN_B ? CateGoryConst.LOG_LOGIN : CateGoryConst.LOG_LOGOUT, + ExeStatus = SysLogConst.SUCCESS, + OpAddress = GetLoginAddress(loggingMonitor.RemoteIPv4), + OpIp = loggingMonitor.RemoteIPv4, + OpBrowser = clientInfo.UA.Family + clientInfo.UA.Major, + OpOs = clientInfo.OS.Family + clientInfo.OS.Major, + OpTime = loggingMonitor.LogDateTime, + OpUser = name, + OpAccount = opAccount + }; + await _db.CopyNew().InsertableWithAttr(devLogVisit).IgnoreColumns(true).SplitTable().ExecuteCommandAsync();//入库 + } + + /// + /// 创建操作日志 + /// + /// 操作名称 + /// 请求地址 + /// loggingMonitor + /// 客户端信息 + /// + private async Task CreateOperationLog(string operation, string path, LoggingMonitorJson loggingMonitor, + ClientInfo clientInfo) + { + //用户名称 + var name = loggingMonitor.AuthorizationClaims?.Where(it => it.Type == ClaimConst.NAME).Select(it => it.Value).FirstOrDefault(); + //账号 + var opAccount = loggingMonitor.AuthorizationClaims?.Where(it => it.Type == ClaimConst.ACCOUNT).Select(it => it.Value).FirstOrDefault(); + + //获取参数json字符串, + var paramJson = loggingMonitor.Parameters == null || loggingMonitor.Parameters.Count == 0 + ? null + : loggingMonitor.Parameters[0].Value.ToJsonString(); + + //获取结果json字符串 + var resultJson = string.Empty; + if (loggingMonitor.ReturnInformation != null)//如果有返回值 + { + if (loggingMonitor.ReturnInformation.Value != null)//如果返回值不为空 + { + var time = loggingMonitor.ReturnInformation.Value.Time != null + ? DateTime.Parse(loggingMonitor.ReturnInformation.Value.Time) + : DateTime.Now;//转成时间 + loggingMonitor.ReturnInformation.Value.Time = time.ToString(CultureInfo.CurrentCulture);//转成字符串 + resultJson = loggingMonitor.ReturnInformation.Value.ToJsonString(); + } + } + + //操作日志表实体 + var devLogOperate = new SysLogOperate + { + Name = operation, + Category = CateGoryConst.LOG_OPERATE, + ExeStatus = SysLogConst.SUCCESS, + OpAddress = GetLoginAddress(loggingMonitor.RemoteIPv4), + OpIp = loggingMonitor.RemoteIPv4, + OpBrowser = clientInfo.UA.Family + clientInfo.UA.Major, + OpOs = clientInfo.OS.Family + clientInfo.OS.Major, + OpTime = loggingMonitor.LogDateTime, + OpUser = name, + OpAccount = opAccount, + ReqMethod = loggingMonitor.HttpMethod, + ReqUrl = path, + ResultJson = resultJson, + ClassName = loggingMonitor.DisplayName, + MethodName = loggingMonitor.ActionName, + ParamJson = paramJson + }; + //如果异常不为空 + if (loggingMonitor.Exception != null) + { + devLogOperate.Category = CateGoryConst.LOG_EXCEPTION;//操作类型为异常 + devLogOperate.ExeStatus = SysLogConst.FAIL;//操作状态为失败 + devLogOperate.ExeMessage = loggingMonitor.Exception.Type + ":" + loggingMonitor.Exception.Message + "\n" + + loggingMonitor.Exception.StackTrace; + } + await _db.CopyNew().InsertableWithAttr(devLogOperate).IgnoreColumns(true).SplitTable().ExecuteCommandAsync();//入库 + } + + /// + /// 解析IP地址 + /// + /// + /// + private string GetLoginAddress(string ip) + { + var loginAddress = "未知"; + try + { + var ipInfo = _searcher.Search(ip);//解析ip + loginAddress = ipInfo?.Replace("0|", "");//去掉前面的0| + } + catch (global::System.Exception ex) + { + _logger.LogError("IP解析错误" + ex, ex); + } + return loginAddress; + } +} diff --git a/SimpleAdmin.Web.Core/Logging/LoggingConst.cs b/SimpleAdmin.Web.Core/Logging/LoggingConst.cs new file mode 100644 index 0000000..2880308 --- /dev/null +++ b/SimpleAdmin.Web.Core/Logging/LoggingConst.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 日志常量 +/// +public class LoggingConst +{ + /// + /// 操作名称 + /// + public const string OPERATION = "Operation"; + + /// + /// 客户端信息 + /// + public const string CLIENT = "Client"; + + /// + /// 请求地址 + /// + public const string PATH = "Path"; + + /// + /// 请求方法:POST/GET + /// + public const string METHOD = "Method"; +} diff --git a/SimpleAdmin.Web.Core/Logging/LoggingMonitorJson.cs b/SimpleAdmin.Web.Core/Logging/LoggingMonitorJson.cs new file mode 100644 index 0000000..c5eac18 --- /dev/null +++ b/SimpleAdmin.Web.Core/Logging/LoggingMonitorJson.cs @@ -0,0 +1,225 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 请求信息格式化 +/// +public class LoggingMonitorJson +{ + /// + /// 标题 + /// + public string Title { get; set; } + + /// + /// 操作名称 + /// + public string DisplayTitle { get; set; } + + /// + /// 控制器名 + /// + public string ControllerName { get; set; } + + /// + /// 方法名称 + /// + public string ActionName { get; set; } + + /// + /// 类名称 + /// + public string DisplayName { get; set; } + + /// + /// 服务端 + /// + public string LocalIPv4 { get; set; } + + /// + /// 客户端IPV4地址 + /// + public string RemoteIPv4 { get; set; } + + /// + /// 请求方法 + /// + public string HttpMethod { get; set; } + + /// + /// 请求地址 + /// + public string RequestUrl { get; set; } + + /// + /// 浏览器标识 + /// + public string UserAgent { get; set; } + + /// + /// 系统名称 + /// + public string OsDescription { get; set; } + + /// + /// 系统架构 + /// + public string OsArchitecture { get; set; } + + /// + /// 环境 + /// + public string Environment { get; set; } + + /// + /// 认证信息 + /// + public List AuthorizationClaims { get; set; } + + /// + /// 参数列表 + /// + public List Parameters { get; set; } + + /// + /// 返回信息 + /// + public ReturnInformation ReturnInformation { get; set; } + + /// + /// 异常信息 + /// + public Exception Exception { get; set; } + + /// + /// 验证错误信息 + /// + public Validation Validation { get; set; } + + /// + /// 日志时间 + /// + public DateTime LogDateTime { get; set; } +} + +/// +/// 认证信息 +/// +public class AuthorizationClaims +{ + /// + /// 类型 + /// + public string Type { get; set; } + + /// + /// 值 + /// + public string Value { get; set; } +} + +/// +/// 请求参数 +/// +public class Parameters +{ + /// + /// 参数名 + /// + public string Name { get; set; } + + /// + /// 值 + /// + public object Value { get; set; } +} + +/// +/// 返回信息 +/// +public class ReturnInformation +{ + /// + /// 返回值 + /// + public ReturnValue Value { get; set; } + + public class ReturnValue + { + /// + /// 返回码 + /// + public int Code { get; set; } + + /// + /// 消息 + /// + public string Msg { get; set; } + + /// + /// 额外信息 + /// + public object Extras { get; set; } + + /// + /// 内如 + /// + public object Data { get; set; } + + /// + /// 时间 + /// + public string Time { get; set; } + } +} + +/// +/// 异常信息 +/// +public class Exception +{ + /// + /// 异常类型 + /// + public string Type { get; set; } + + /// + /// 异常内容 + /// + public string Message { get; set; } + + /// + /// 堆栈信息 + /// + public string StackTrace { get; set; } +} + +/// +/// 验证失败信息 +/// +public class Validation +{ + ///// + ///// 错误码 + ///// + //public string ErrorCode { get; set; } + + ///// + ///// 错误码 + ///// + //public string OriginErrorCode { get; set; } + + /// + /// 错误详情 + /// + public string Message { get; set; } +} diff --git a/SimpleAdmin.Web.Core/Middleware/WebStatusMiddleware.cs b/SimpleAdmin.Web.Core/Middleware/WebStatusMiddleware.cs new file mode 100644 index 0000000..e2f4bb5 --- /dev/null +++ b/SimpleAdmin.Web.Core/Middleware/WebStatusMiddleware.cs @@ -0,0 +1,55 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// 网站开启状态 状态中间件 +/// +public class WebStatusMiddleware +{ + private readonly RequestDelegate _next; + + public WebStatusMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task InvokeAsync(HttpContext context) + { + var path = context.Request.Path.Value;//获取请求路径 + // 检查请求路径是否以 "/biz" 开头 + if (path.Length > 1 && !path.Contains('.') && !path.StartsWith("/sys", StringComparison.OrdinalIgnoreCase)) + { + // 通过 context.RequestServices 解析 + var configService = context.RequestServices.GetService(); + // 获取网站状态 + var webStatus = await configService.GetByConfigKey(CateGoryConst.CONFIG_SYS_BASE, SysConfigConst.SYS_WEB_STATUS); + // 如果网站状态为禁用,则返回 443 状态码 + if (webStatus.ConfigValue == CommonStatusConst.DISABLED) + { + context.Response.StatusCode = 423; + return; + } + } + await _next(context); + } +} + +/// +/// 中间件拓展类 +/// +public static class WebStatusMiddlewareExtensions +{ + public static IApplicationBuilder UseWebStatus(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } +} diff --git a/SimpleAdmin.Web.Core/Options/WebSettingsOptions.cs b/SimpleAdmin.Web.Core/Options/WebSettingsOptions.cs new file mode 100644 index 0000000..315798b --- /dev/null +++ b/SimpleAdmin.Web.Core/Options/WebSettingsOptions.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +using MoYu.ConfigurableOptions; + +namespace SimpleAdmin.Web.Core; + +/// +/// 系统配置选项 +/// +public class WebSettingsOptions : IConfigurableOptions +{ + /// + /// 是否演示环境 + /// + public bool EnvPoc { get; set; } = false; + + /// + /// 是否清除Redis缓存 + /// + public bool ClearRedis { get; set; } = false; +} diff --git a/SimpleAdmin.Web.Core/SimpleAdmin.Web.Core.csproj b/SimpleAdmin.Web.Core/SimpleAdmin.Web.Core.csproj new file mode 100644 index 0000000..787f22f --- /dev/null +++ b/SimpleAdmin.Web.Core/SimpleAdmin.Web.Core.csproj @@ -0,0 +1,17 @@ + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + + diff --git a/SimpleAdmin.Web.Core/SimpleAdmin.Web.Core.xml b/SimpleAdmin.Web.Core/SimpleAdmin.Web.Core.xml new file mode 100644 index 0000000..a103e0e --- /dev/null +++ b/SimpleAdmin.Web.Core/SimpleAdmin.Web.Core.xml @@ -0,0 +1,2001 @@ + + + + SimpleAdmin.Web.Core + + + + + 认证相关组件 + + + + + LoggingMonitor操作日志写入数据库插件 + + + + + Web设置组件 + 模拟 ConfigureService + + + + + Web设置组件 + 模拟 Configure + + + + + 机构管理控制器 + + + + + 获取机构树 + + + + + + 机构分页查询 + + + + + + + 获取机构树选择器 + + + + + + 获取人员选择器 + + + + + + 机构详情 + + + + + + + 添加机构 + + + + + + + 修改机构 + + + + + + + 复制组织 + + + + + + + 删除机构 + + + + + + + 岗位管理控制器 + + + + + 获取职位树 + + + + + + 岗位分页查询 + + + + + + + 岗位详情 + + + + + + + 岗位选择器 + + + + + + + 添加岗位 + + + + + + + 修改岗位 + + + + + + + 删除岗位 + + + + + + + 业务角色管理控制器 + + + + + 角色分页查询 + + + + + + + 添加角色 + + + + + + + 修改角色 + + + + + + + 删除角色 + + + + + + + 获取角色授权资源树 + + + + + + 获取角色拥有资源 + + + + + + + 给角色授权资源 + + + + + + + 获取角色下的用户 + + + + + + + 给角色授权用户 + + + + + + + 获取角色树 + + + + + + 获取角色详情 + + + + + + + 获取角色选择器 + + + + + + 人员管理控制器 + + + + + 导入预览 + + + + + + + 模板下载 + + + + + + 人员分页查询 + + + + + + + 获取人员选择器 + + + + + + 获取人员拥有角色 + + + + + + + 人员详情 + + + + + + + 添加人员 + + + + + + + 修改人员 + + + + + + + 批量修改人员 + + + + + + + 删除人员 + + + + + + + 禁用人员 + + + + + + + 启用人员 + + + + + + + 重置密码 + + + + + + + 给人员授权角色 + + + + + + + 人员导入 + + + + + + + 人员导出 + + + + + + + 药材管理 + + + + + 获取药材列表 + + + + + 获取药材消耗记录 + + + + + 获取药材下拉 + + + + + 获取药材添加记录 + + + + + 添加药材 + + + + + 修改药材添加记录 + + + + + 删除药材添加记录 + + + + + 药材管理 + + + + + 获取处方列表 + + + + + 获取处方详情 + + + + + 保存处方(新增或编辑) + + + + + 获取人员列表 + + + + + 获取关系类型 + + + + + B端登录控制器 + + + + + B端获取图片验证码 + + + + + + B端获取手机验证码 + + + + + + + B端登录 + + + + + + + B端手机号登录 + + + + + + + 登出 + + + + + + 获取用户信息 + + + + + + 会话管理控制器 + + + + + B端会话分页 + + + + + + + C端会话分页 + + + + + + + 会话统计 + + + + + + 强退B端会话 + + + + + + 强退C端会话 + + + + + + 强退B端Token + + + + + + 强退C端Token + + + + + + 基础控制器 + + + + + 批量控制器 + + + + + 批量分页查询 + + + + + + + 获取表信息 + + + + + + 获取批量配置信息 + + + + + + 获取批量配置信息 + + + + + + 添加批量 + + + + + + + 配置修改批量 + + + + + + + 删除批量 + + + + + + + 批量更新同步 + + + + + + + 系统通用控制器,一般是一些公共的接口 + + + + + 获取系统基础配置 + + + + + + 获取系统基础配置 + + + + + + 获取系统基础配置 + + + + + + 获取租户列表 + + + + + + 文件管理控制器 + + + + + 文件查询分页 + + + + + + + 上传本地文件 + + + + + + + 上传MINIO文件 + + + + + + + 删除文件 + + + + + + + 下载文件 + + + + + + + 站内信控制器 + + + + + 分页查询 + + + + + + + 添加站内信 + + + + + + 编辑站内信 + + + + + + 消息详情 + + + + + + + 删除站内信 + + + + + + + 代码生成基础控制器 + + + + + 代码生成基础分页 + + + + + + + 获取所有表信息 + + + + + + 获取项目所有程序集 + + + + + + 添加代码生成器 + + + + + + + 编辑代码生成器 + + + + + + + 删除代码生成配置 + + + + + + + 代码生成预览 + + + + + + + 执行代码生成(本地)" + + + + + + + 执行代码生成(压缩包) + + + + + + + 代码生成配置控制器 + + + + + 查询代码生成详细配置列表 + + + + + + + 编辑代码生成详细 + + + + + + + 系统首页控制器 + + + + + 获取当前用户访问日志列表 + + + + + + 获取当前用户操作日志列表 + + + + + + 获取当前用户站内信列表 + + + + + + 获取当前用户日程列表 + + + + + + 添加日程 + + + + + + + 删除日程 + + + + + + + 权限按钮控制器 + + + + + 按钮分页查询 + + + + + + + 添加按钮 + + + + + + + 修改按钮 + + + + + + + 删除按钮 + + + + + + + 批量新增 + + + + + + + 获取按钮详情 + + + + + + + 菜单管理控制器 + + + + + 模块选择 + + + + + + 获取菜单树 + + + + + + 获取菜单树选择器 + + + + + + 添加菜单 + + + + + + + 编辑菜单 + + + + + + + 获取菜单详情 + + + + + + 删除菜单 + + + + + + + 更改模块 + + + + + + + 模块管理控制器 + + + + + 模块分页查询 + + + + + + + 添加模块 + + + + + + + 修改模块 + + + + + + + 删除模块 + + + + + + + 获取模块详情 + + + + + + + 模块列表 + + + + + + 角色管理控制器 + + + + + 角色分页查询 + + + + + + + 添加角色 + + + + + + + 修改角色 + + + + + + + 删除角色 + + + + + + + 获取角色授权资源树 + + + + + + 获取角色拥有资源 + + + + + + + 给角色授权资源 + + + + + + + 获取权限授权树 + + + + + + 获取角色拥有权限 + + + + + + + 给角色授权权限 + + + + + + + 获取角色下的用户 + + + + + + + 给角色授权用户 + + + + + + + 获取角色树 + + + + + + 获取角色详情 + + + + + + + 获取角色选择器 + + + + + + 单页管理控制器 + + + + + 单页分页查询 + + + + + + + 添加单页 + + + + + + + 修改单页 + + + + + + + 删除单页 + + + + + + + 获取单页详情 + + + + + + + 操作日志控制器 + + + + + 操作日志分页查询 + + + + + + + 操作日志周统计柱状图图 + + + + + + 操作日志数量总览饼图 + + + + + + 清空日志 + + + + + + + 日志详情 + + + + + + + 访问日志控制器 + + + + + 访问日志分页查询 + + + + + + + 访问日志周统计折线图 + + + + + + 访问日志总览饼图 + + + + + + 清空日志 + + + + + + + mqtt服务控制器 + + + + + 获取mqtt登录参数 + + + + + + mqtt认证 + + + + + + + 系统配置控制器 + + + + + 获取系统基础配置 + + + + + + 获取系统配置列表 + + + + + + 配置分页 + + + + + + + 添加配置 + + + + + + + 修改配置 + + + + + + + 删除配置 + + + + + + + 配置批量更新 + + + + + + 系统字典控制器 + + + + + 获取字典树 + + + + + + 字典分页查询 + + + + + + + 添加字典 + + + + + + + 修改字典 + + + + + + + 删除字典 + + + + + + + 组织管理控制器 + + + + + 获取组织树 + + + + + + 获取组织树选择器 + + + + + + 组织分页查询 + + + + + + + 获取用户选择器 + + + + + + 获取组织详情 + + + + + + + 复制组织 + + + + + + + 添加组织 + + + + + + + 修改组织 + + + + + + + 删除组织 + + + + + + + 职位管理控制器 + + + + + 职位分页查询 + + + + + + + 获取职位树 + + + + + + 职位选择器 + + + + + + + 获取职位详情 + + + + + + + 添加职位 + + + + + + + 修改职位 + + + + + + + 删除职位 + + + + + + + 用户管理控制器 + + + + + 用户分页查询 + + + + + + + 获取用户选择器 + + + + + + + 获取用户拥有角色 + + + + + + + 获取用户拥有资源 + + + + + + + 获取用户拥有权限 + + + + + + + 获取权限授权树 + + + + + + 导入预览 + + + + + + + 模板下载 + + + + + + 用户详情 + + + + + + + 添加用户 + + + + + + + 修改用户 + + + + + + + 批量修改用户 + + + + + + + 删除用户 + + + + + + + 禁用用户 + + + + + + + 启用用户 + + + + + + + 重置密码 + + + + + + + 给用户授权角色 + + + + + + + 给用户授权资源 + + + + + + + 给用户授权权限 + + + + + + + 用户导入 + + + + + + + 用户导出 + + + + + + 1 + 上传图片 + + + + + + + 用户个人信息控制器 + + + + + 获取个人菜单 + + + + + + 获取个人工作台 + + + + + + 获取组织架构 + + + + + + 修改密码 + + + + + + + 修改头像 + + + + + + + 修改默认模块 + + + + + + 快捷方式菜单树 + + + + + + + 编辑个人信息 + + + + + + + 更新签名 + + + + + + + 编辑工作台 + + + + + + + 获取登录用户的站内信分页 + + + + + + + 读取登录用户站内信详情 + + + + + + + 未读消息数 + + + + + + 最新未读消息 + + + + + + 删除我的消息 + + + + + + + 设置已读 + + + + + + 设置未读 + + + + + + + 操作筛选器 + + + + + 自定义授权筛选器 + + + + + 重写 Handler 添加自动刷新 + + + + + + + + 检查token有效性 + + DefaultHttpContext + token有效期/分钟 + + + + + 授权判断逻辑,授权通过返回 true,否则返回 false + + + + + + + + 检查权限 + + + + + + + 全局异常处理提供器 + + + + + 数据库写入器 + + + + + 创建访问日志 + + 访问类型 + loggingMonitor + 客户端信息 + + + + 创建操作日志 + + 操作名称 + 请求地址 + loggingMonitor + 客户端信息 + + + + + 解析IP地址 + + + + + + + 日志常量 + + + + + 操作名称 + + + + + 客户端信息 + + + + + 请求地址 + + + + + 请求方法:POST/GET + + + + + 请求信息格式化 + + + + + 标题 + + + + + 操作名称 + + + + + 控制器名 + + + + + 方法名称 + + + + + 类名称 + + + + + 服务端 + + + + + 客户端IPV4地址 + + + + + 请求方法 + + + + + 请求地址 + + + + + 浏览器标识 + + + + + 系统名称 + + + + + 系统架构 + + + + + 环境 + + + + + 认证信息 + + + + + 参数列表 + + + + + 返回信息 + + + + + 异常信息 + + + + + 验证错误信息 + + + + + 日志时间 + + + + + 认证信息 + + + + + 类型 + + + + + 值 + + + + + 请求参数 + + + + + 参数名 + + + + + 值 + + + + + 返回信息 + + + + + 返回值 + + + + + 返回码 + + + + + 消息 + + + + + 额外信息 + + + + + 内如 + + + + + 时间 + + + + + 异常信息 + + + + + 异常类型 + + + + + 异常内容 + + + + + 堆栈信息 + + + + + 验证失败信息 + + + + + 错误详情 + + + + + 网站开启状态 状态中间件 + + + + + 中间件拓展类 + + + + + 系统配置选项 + + + + + 是否演示环境 + + + + + 是否清除Redis缓存 + + + + + Web启动项配置 + + + + diff --git a/SimpleAdmin.Web.Core/Startup.cs b/SimpleAdmin.Web.Core/Startup.cs new file mode 100644 index 0000000..bd53542 --- /dev/null +++ b/SimpleAdmin.Web.Core/Startup.cs @@ -0,0 +1,97 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +namespace SimpleAdmin.Web.Core; + +/// +/// Web启动项配置 +/// +[AppStartup(99)] +public class Startup : AppStartup +{ + public void ConfigureServices(IServiceCollection services) + { + //启动LoggingMonitor操作日志写入数据库组件 + services.AddComponent(); + + //认证组件 + services.AddComponent(); + //启动Web设置ConfigureServices组件 + services.AddComponent(); + //gip压缩 + services.AddComponent(); + //定时任务 + //services.AddSchedule(); + //添加控制器相关 + services.AddControllers().AddNewtonsoftJson(options => //配置json + { + options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();// 首字母小写(驼峰样式) + options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";// 时间格式化 + options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;// 忽略循环引用 + }).AddInjectWithUnifyResult()//配置统一返回模型 + ; + + //Nginx代理的话获取真实IP + services.Configure(options => + { + options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; + //新增如下两行 + options.KnownNetworks.Clear(); + options.KnownProxies.Clear(); + }); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + //启动Web设置Configure组件 + app.UseComponent(env); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + //启用gzip压缩 + app.UseResponseCompression(); + } + // 启用HTTPS + app.UseHttpsRedirection(); + + // 添加状态码拦截中间件 + app.UseUnifyResultStatusCodes(); + + app.UseStaticFiles();//静态文件访问配置 + + //静态文件访问配置,暂时不开启 + // app.UseStaticFiles(new StaticFileOptions + // { + // ServeUnknownFileTypes = true, + // FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")),//wwwroot相当于真实目录 + // OnPrepareResponse = c => + // { + // c.Context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); + // c.Context.Response.Headers.Append("Cache-Control", "public, max-age=604800"); + // }, + // RequestPath = new PathString("/files")//src相当于别名,为了安全 + // }); + app.UseRouting();//路由配置 + app.UseCorsAccessor();//跨域配置 + app.UseWebStatus();//网站开启状态 + app.UseAuthentication();//认证 + app.UseAuthorization();//授权 + app.UseInject(string.Empty); + app.UseForwardedHeaders();//Nginx代理的话获取真实IP + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } +} diff --git a/SimpleAdmin.Web.Core/Web.Development.json b/SimpleAdmin.Web.Core/Web.Development.json new file mode 100644 index 0000000..3948bcf --- /dev/null +++ b/SimpleAdmin.Web.Core/Web.Development.json @@ -0,0 +1,19 @@ +{ + //web设置 + "WebSettings": { + "EnvPoc": false, //是否演示环境 + }, + //jwt设置 + "JWTSettings": { + "ValidateIssuerSigningKey": true, // 是否验证密钥,bool 类型,默认true + "IssuerSigningKey": "3c1cbc3f546eda35168c3aa3cb91780fbe703f0996c1d133ea96dc85c70bbc0a", // 密钥,string 类型,必须是复杂密钥,长度大于16 + "ValidateIssuer": true, // 是否验证签发方,bool 类型,默认true + "ValidIssuer": "SimpleAdmin", // 签发方,string 类型 + "ValidateAudience": true, // 是否验证签收方,bool 类型,默认true + "ValidAudience": "SimpleAdmin", // 签收方,string 类型 + "ValidateLifetime": true, // 是否验证过期时间,bool 类型,默认true,建议true + "ExpiredTime": 50000, // 过期时间,long 类型,单位分钟,默认20分钟 + "ClockSkew": 10, // 过期时间容错值,long 类型,单位秒,默认5秒 + "Algorithm": "HS256" // 加密算法,string 类型,默认 HS256 + }, +} \ No newline at end of file diff --git a/SimpleAdmin.Web.Core/Web.Production.json b/SimpleAdmin.Web.Core/Web.Production.json new file mode 100644 index 0000000..3948bcf --- /dev/null +++ b/SimpleAdmin.Web.Core/Web.Production.json @@ -0,0 +1,19 @@ +{ + //web设置 + "WebSettings": { + "EnvPoc": false, //是否演示环境 + }, + //jwt设置 + "JWTSettings": { + "ValidateIssuerSigningKey": true, // 是否验证密钥,bool 类型,默认true + "IssuerSigningKey": "3c1cbc3f546eda35168c3aa3cb91780fbe703f0996c1d133ea96dc85c70bbc0a", // 密钥,string 类型,必须是复杂密钥,长度大于16 + "ValidateIssuer": true, // 是否验证签发方,bool 类型,默认true + "ValidIssuer": "SimpleAdmin", // 签发方,string 类型 + "ValidateAudience": true, // 是否验证签收方,bool 类型,默认true + "ValidAudience": "SimpleAdmin", // 签收方,string 类型 + "ValidateLifetime": true, // 是否验证过期时间,bool 类型,默认true,建议true + "ExpiredTime": 50000, // 过期时间,long 类型,单位分钟,默认20分钟 + "ClockSkew": 10, // 过期时间容错值,long 类型,单位秒,默认5秒 + "Algorithm": "HS256" // 加密算法,string 类型,默认 HS256 + }, +} \ No newline at end of file diff --git a/SimpleAdmin.Web.Entry/.config/dotnet-tools.json b/SimpleAdmin.Web.Entry/.config/dotnet-tools.json new file mode 100644 index 0000000..43a4368 --- /dev/null +++ b/SimpleAdmin.Web.Entry/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "7.0.1", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/SimpleAdmin.Web.Entry/AntDeploy.json b/SimpleAdmin.Web.Entry/AntDeploy.json new file mode 100644 index 0000000..f46bc36 --- /dev/null +++ b/SimpleAdmin.Web.Entry/AntDeploy.json @@ -0,0 +1,116 @@ +{ + "Env": [ + { + "Name": "10楼liunx未病局测试环境", + "ServerList": [], + "LinuxServerList": [ + { + "UserName": "root", + "Pwd": "DA9C12691417F47DE6F7FED4AC9DC2B0BFFAA5D2C8E3609D29A2595461736381", + "Host": "58.17.132.2:12005", + "NickName": "10楼liunx未病局测试环境", + "IIsFireUrl": null, + "DockerFireUrl": "", + "WindowsServiceFireUrl": null, + "LinuxServiceFireUrl": null + } + ], + "IgnoreList": [], + "WindowsBackUpIgnoreList": [] + } + ], + "IIsConfig": { + "SdkType": null, + "WebSiteName": "", + "LastEnvName": null, + "EnvPairList": [ + { + "EnvName": "10楼liunx未病局测试环境", + "ConfigName": "", + "LinuxEnvParam": null, + "DockerPort": null, + "DockerEnvName": null, + "DockerVolume": null, + "DockerOther": null + } + ] + }, + "WindowsServiveConfig": { + "ServiceName": "", + "SdkType": null, + "LastEnvName": null, + "EnvPairList": [ + { + "EnvName": "10楼liunx未病局测试环境", + "ConfigName": "", + "LinuxEnvParam": null, + "DockerPort": null, + "DockerEnvName": null, + "DockerVolume": null, + "DockerOther": null + } + ] + }, + "LinuxServiveConfig": { + "ServiceName": "", + "EnvParam": "", + "LastEnvName": null, + "EnvPairList": [ + { + "EnvName": "10楼liunx未病局测试环境", + "ConfigName": "", + "LinuxEnvParam": null, + "DockerPort": null, + "DockerEnvName": null, + "DockerVolume": null, + "DockerOther": null + } + ] + }, + "DockerConfig": { + "Prot": "5566:5566", + "AspNetCoreEnv": "", + "LastEnvName": "10楼liunx未病局测试环境", + "RemoveDaysFromPublished": "10", + "WorkDir": "/data/publish/medical.api", + "Volume": "/etc/localtime:/etc/localtime;/data/docker_volume/medical/api/appsettings.json:/publish/appsettings.json", + "Other": "--name medical.api --restart=always -e TZ=Asia/Shanghai", + "EnvPairList": [ + { + "EnvName": "10楼liunx未病局测试环境", + "ConfigName": null, + "LinuxEnvParam": null, + "DockerPort": "5566:5566", + "DockerEnvName": "", + "DockerVolume": "/etc/localtime:/etc/localtime;/data/docker_volume/medical/api/appsettings.json:/publish/appsettings.json", + "DockerOther": "--name medical.api --restart=always -e TZ=Asia/Shanghai" + } + ] + }, + "DockerImageConfig": { + "BaseHttpProxy": "", + "BaseImage": "", + "BaseImageCredential": { + "UserName": "", + "Password": "" + }, + "TargetImage": "", + "TargetHttpProxy": "", + "TargetTags": [ + "" + ], + "TargetImageCredential": { + "UserName": "", + "Password": "" + }, + "ImageFormat": "Docker", + "Entrypoint": [ + "" + ], + "Cmd": [ + "" + ], + "IgnoreList": [], + "SkipExistingImages": false + } +} \ No newline at end of file diff --git a/SimpleAdmin.Web.Entry/Program.cs b/SimpleAdmin.Web.Entry/Program.cs new file mode 100644 index 0000000..f167648 --- /dev/null +++ b/SimpleAdmin.Web.Entry/Program.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛 +// +// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款: +// 1.请不要删除和修改根目录下的LICENSE文件。 +// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。 +// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin +// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。 +// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。 +// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。 + +Console.WriteLine("源码地址: https://gitee.com/dotnetmoyu/SimpleAdmin"); +Console.WriteLine("ts演示地址: http://153.101.199.83:12802/login"); +Console.WriteLine("js演示地址: http://153.101.199.83:12801/login"); +Console.WriteLine("QQ:531035580"); +Console.WriteLine("简单之名,非凡之质——稳定、灵活、高效,实力不需夸耀。"); +Serve.Run(RunOptions.Default.ConfigureBuilder(builder => +{ + builder.WebHost.UseUrls(builder.Configuration["AppSettings:Urls"]); +})); diff --git a/SimpleAdmin.Web.Entry/Properties/launchSettings.json b/SimpleAdmin.Web.Entry/Properties/launchSettings.json new file mode 100644 index 0000000..ccbfd92 --- /dev/null +++ b/SimpleAdmin.Web.Entry/Properties/launchSettings.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "SimpleAdmin.Web.Entry": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "http://localhost:5566", + "applicationUrl": "http://localhost:5566", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/SimpleAdmin.Web.Entry/SimpleAdmin.Web.Entry.csproj b/SimpleAdmin.Web.Entry/SimpleAdmin.Web.Entry.csproj new file mode 100644 index 0000000..51ac635 --- /dev/null +++ b/SimpleAdmin.Web.Entry/SimpleAdmin.Web.Entry.csproj @@ -0,0 +1,24 @@ + + + net6.0 + enable + enable + + + + PreserveNewest + + + + + + + + + + + + + + + diff --git a/SimpleAdmin.Web.Entry/SimpleAdmin.Web.Entry.xml b/SimpleAdmin.Web.Entry/SimpleAdmin.Web.Entry.xml new file mode 100644 index 0000000..d3fd2c1 --- /dev/null +++ b/SimpleAdmin.Web.Entry/SimpleAdmin.Web.Entry.xml @@ -0,0 +1,8 @@ + + + + SimpleAdmin.Web.Entry + + + + diff --git a/SimpleAdmin.Web.Entry/SimpleAdmin.db b/SimpleAdmin.Web.Entry/SimpleAdmin.db new file mode 100644 index 0000000..4e76478 Binary files /dev/null and b/SimpleAdmin.Web.Entry/SimpleAdmin.db differ diff --git a/SimpleAdmin.Web.Entry/appsettings.json b/SimpleAdmin.Web.Entry/appsettings.json new file mode 100644 index 0000000..87c6c64 --- /dev/null +++ b/SimpleAdmin.Web.Entry/appsettings.json @@ -0,0 +1,37 @@ +{ + "AppSettings": { + "InjectSpecificationDocument": true, //是否开启swagger + "Urls": "http://0.0.0.0:5566" //监听地址 + }, + "AllowedHosts": "*", + //友好异常处理 + "FriendlyExceptionSettings": { + "DefaultErrorMessage": "系统异常,请联系管理员", + "HideErrorCode": true + }, + //动态API设备 + "DynamicApiControllerSettings": { + "LowercaseRoute": false, //是否采用小写路由,bool 类型,默认 true + "KeepName": true, //是否保持原有名称不处理,bool,默认 false + "AsLowerCamelCase": true //启用小驼峰命名(首字母小写),默认 false + }, + + //swagger设置 + "SpecificationDocumentSettings": { + "DocumentTitle": "未病局后台管理系统", + "DocExpansionState": "None", + "GroupOpenApiInfos": [] + }, + "CorsAccessorSettings": { + "WithExposedHeaders": [ + "access-token", + "x-access-token", + "environment" + ], + "SignalRSupport": true + }, + //排除特定配置文件 + "IgnoreConfigurationFiles": [ + "seed_*.json", + ] +} \ No newline at end of file diff --git a/SimpleAdmin.sln b/SimpleAdmin.sln new file mode 100644 index 0000000..1a11f43 --- /dev/null +++ b/SimpleAdmin.sln @@ -0,0 +1,111 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32929.385 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleAdmin.Application", "SimpleAdmin.Application\SimpleAdmin.Application.csproj", "{80E93EBF-7E84-410D-877E-165804DCCB09}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleAdmin.Core", "SimpleAdmin.Core\SimpleAdmin.Core.csproj", "{ED7F9D0D-6DCA-40B3-AC26-FA1FC35A35D6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleAdmin.Web.Core", "SimpleAdmin.Web.Core\SimpleAdmin.Web.Core.csproj", "{01642438-048E-4CF2-AD62-6232043E41DA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleAdmin.Web.Entry", "SimpleAdmin.Web.Entry\SimpleAdmin.Web.Entry.csproj", "{8469DE55-A79F-4F63-A11A-AC193B69B81C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleAdmin.System", "SimpleAdmin.System\SimpleAdmin.System.csproj", "{CB1C48E3-78AA-488E-8DA5-724804C53A6D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "架构核心", "架构核心", "{88EF0885-575A-4E7A-BBC7-77F762E31A0E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "业务模块", "业务模块", "{7F48AE48-DFA2-4B69-BD0F-8D961FD294D0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "应用服务", "应用服务", "{9C44B2B9-3FA1-4723-AF75-C4883B0D03A7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{006F2845-2905-4EDD-8492-86C6E31282EE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "后台服务", "后台服务", "{C6B98084-8431-4073-9311-A3508C31DF7F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "系统插件", "系统插件", "{D3630025-B2A9-4B83-99CF-2DD99289D628}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "核心插件", "核心插件", "{9EB00985-8989-4020-B0BA-536C90BEDEBC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "系统模块", "系统模块", "{3B049767-E6E3-4E89-B45B-9066448E0573}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleAdmin.Plugin.Aop", "SimpleAdmin.Plugin\SimpleAdmin.Plugin.Aop\SimpleAdmin.Plugin.Aop.csproj", "{8D130807-5AD8-4894-A694-6EBECBF89A5A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleAdmin.SqlSugar", "SimpleAdmin.SqlSugar\SimpleAdmin.SqlSugar.csproj", "{AA783B66-6F91-4164-86D4-6D053E5A549C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleAdmin.Cache", "SimpleAdmin.Cache\SimpleAdmin.Cache.csproj", "{B34C3A3E-EE0E-4D4F-9A3C-AADA575FA977}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleAdmin.MessageCenter", "SimpleAdmin.MessageCenter\SimpleAdmin.MessageCenter.csproj", "{DD0E936C-958B-4203-8566-1A17C1FAA477}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleAdmin.Plugin.Mobile", "SimpleAdmin.Plugin\SimpleAdmin.Plugin.Mobile\SimpleAdmin.Plugin.Mobile.csproj", "{FBB6EC43-9918-4477-92B5-1CAE3E039445}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {80E93EBF-7E84-410D-877E-165804DCCB09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {80E93EBF-7E84-410D-877E-165804DCCB09}.Debug|Any CPU.Build.0 = Debug|Any CPU + {80E93EBF-7E84-410D-877E-165804DCCB09}.Release|Any CPU.ActiveCfg = Release|Any CPU + {80E93EBF-7E84-410D-877E-165804DCCB09}.Release|Any CPU.Build.0 = Release|Any CPU + {ED7F9D0D-6DCA-40B3-AC26-FA1FC35A35D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED7F9D0D-6DCA-40B3-AC26-FA1FC35A35D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED7F9D0D-6DCA-40B3-AC26-FA1FC35A35D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED7F9D0D-6DCA-40B3-AC26-FA1FC35A35D6}.Release|Any CPU.Build.0 = Release|Any CPU + {01642438-048E-4CF2-AD62-6232043E41DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {01642438-048E-4CF2-AD62-6232043E41DA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {01642438-048E-4CF2-AD62-6232043E41DA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {01642438-048E-4CF2-AD62-6232043E41DA}.Release|Any CPU.Build.0 = Release|Any CPU + {8469DE55-A79F-4F63-A11A-AC193B69B81C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8469DE55-A79F-4F63-A11A-AC193B69B81C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8469DE55-A79F-4F63-A11A-AC193B69B81C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8469DE55-A79F-4F63-A11A-AC193B69B81C}.Release|Any CPU.Build.0 = Release|Any CPU + {CB1C48E3-78AA-488E-8DA5-724804C53A6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB1C48E3-78AA-488E-8DA5-724804C53A6D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB1C48E3-78AA-488E-8DA5-724804C53A6D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB1C48E3-78AA-488E-8DA5-724804C53A6D}.Release|Any CPU.Build.0 = Release|Any CPU + {8D130807-5AD8-4894-A694-6EBECBF89A5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D130807-5AD8-4894-A694-6EBECBF89A5A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D130807-5AD8-4894-A694-6EBECBF89A5A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D130807-5AD8-4894-A694-6EBECBF89A5A}.Release|Any CPU.Build.0 = Release|Any CPU + {AA783B66-6F91-4164-86D4-6D053E5A549C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AA783B66-6F91-4164-86D4-6D053E5A549C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AA783B66-6F91-4164-86D4-6D053E5A549C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AA783B66-6F91-4164-86D4-6D053E5A549C}.Release|Any CPU.Build.0 = Release|Any CPU + {B34C3A3E-EE0E-4D4F-9A3C-AADA575FA977}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B34C3A3E-EE0E-4D4F-9A3C-AADA575FA977}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B34C3A3E-EE0E-4D4F-9A3C-AADA575FA977}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B34C3A3E-EE0E-4D4F-9A3C-AADA575FA977}.Release|Any CPU.Build.0 = Release|Any CPU + {DD0E936C-958B-4203-8566-1A17C1FAA477}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DD0E936C-958B-4203-8566-1A17C1FAA477}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DD0E936C-958B-4203-8566-1A17C1FAA477}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DD0E936C-958B-4203-8566-1A17C1FAA477}.Release|Any CPU.Build.0 = Release|Any CPU + {FBB6EC43-9918-4477-92B5-1CAE3E039445}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FBB6EC43-9918-4477-92B5-1CAE3E039445}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FBB6EC43-9918-4477-92B5-1CAE3E039445}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FBB6EC43-9918-4477-92B5-1CAE3E039445}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {80E93EBF-7E84-410D-877E-165804DCCB09} = {7F48AE48-DFA2-4B69-BD0F-8D961FD294D0} + {ED7F9D0D-6DCA-40B3-AC26-FA1FC35A35D6} = {88EF0885-575A-4E7A-BBC7-77F762E31A0E} + {01642438-048E-4CF2-AD62-6232043E41DA} = {006F2845-2905-4EDD-8492-86C6E31282EE} + {8469DE55-A79F-4F63-A11A-AC193B69B81C} = {006F2845-2905-4EDD-8492-86C6E31282EE} + {CB1C48E3-78AA-488E-8DA5-724804C53A6D} = {7F48AE48-DFA2-4B69-BD0F-8D961FD294D0} + {006F2845-2905-4EDD-8492-86C6E31282EE} = {9C44B2B9-3FA1-4723-AF75-C4883B0D03A7} + {C6B98084-8431-4073-9311-A3508C31DF7F} = {9C44B2B9-3FA1-4723-AF75-C4883B0D03A7} + {9EB00985-8989-4020-B0BA-536C90BEDEBC} = {D3630025-B2A9-4B83-99CF-2DD99289D628} + {3B049767-E6E3-4E89-B45B-9066448E0573} = {D3630025-B2A9-4B83-99CF-2DD99289D628} + {8D130807-5AD8-4894-A694-6EBECBF89A5A} = {9EB00985-8989-4020-B0BA-536C90BEDEBC} + {AA783B66-6F91-4164-86D4-6D053E5A549C} = {88EF0885-575A-4E7A-BBC7-77F762E31A0E} + {B34C3A3E-EE0E-4D4F-9A3C-AADA575FA977} = {88EF0885-575A-4E7A-BBC7-77F762E31A0E} + {DD0E936C-958B-4203-8566-1A17C1FAA477} = {C6B98084-8431-4073-9311-A3508C31DF7F} + {FBB6EC43-9918-4477-92B5-1CAE3E039445} = {3B049767-E6E3-4E89-B45B-9066448E0573} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {409A4605-C03F-4838-9B22-C8C2AA82EB23} + EndGlobalSection +EndGlobal diff --git a/global.json b/global.json new file mode 100644 index 0000000..7cd6a1f --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "7.0.0", + "rollForward": "latestMajor", + "allowPrerelease": true + } +} \ No newline at end of file