添加项目文件。
This commit is contained in:
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 前端表格特性
|
||||
/// </summary>
|
||||
public class AntTableAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否是日期格式
|
||||
/// </summary>
|
||||
public bool IsDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否自动省略
|
||||
/// </summary>
|
||||
public bool Ellipsis { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 宽度
|
||||
/// </summary>
|
||||
public int Width { get; set; } = 100;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 批量更新
|
||||
/// </summary>
|
||||
public class BatchEditAttribute : Attribute
|
||||
{
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 验证值是否在字典中,大数据慎用
|
||||
/// </summary>
|
||||
public class InDictAttribute : ValidationAttribute
|
||||
{
|
||||
public InDictAttribute(string dictValue)
|
||||
{
|
||||
DictValue = dictValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字典值
|
||||
/// </summary>
|
||||
public string DictValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取错误信息
|
||||
/// </summary>
|
||||
/// <param name="value">值</param>
|
||||
/// <returns></returns>
|
||||
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<IDictService>();
|
||||
var values = dictService.GetValuesByDictValue(DictValue).Result;
|
||||
if (!values.Contains(value))
|
||||
{
|
||||
return new ValidationResult(GetErrorMessage(value.ToString()), new[] { validationContext.MemberName });
|
||||
}
|
||||
}
|
||||
return ValidationResult.Success;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 分类常量
|
||||
/// </summary>
|
||||
public class CateGoryConst
|
||||
{
|
||||
#region 系统配置
|
||||
|
||||
/// <summary>
|
||||
/// 系统基础
|
||||
/// </summary>
|
||||
public const string CONFIG_SYS_BASE = "SYS_BASE";
|
||||
|
||||
/// <summary>
|
||||
/// 登录策略
|
||||
/// </summary>
|
||||
public const string CONFIG_LOGIN_POLICY = "LOGIN_POLICY";
|
||||
|
||||
/// <summary>
|
||||
/// 密码策略
|
||||
/// </summary>
|
||||
public const string CONFIG_PWD_POLICY = "PWD_POLICY";
|
||||
|
||||
/// <summary>
|
||||
/// 业务定义
|
||||
/// </summary>
|
||||
public const string CONFIG_BIZ_DEFINE = "BIZ_DEFINE";
|
||||
|
||||
/// <summary>
|
||||
/// 文件-本地
|
||||
/// </summary>
|
||||
public const string CONFIG_FILE_LOCAL = "FILE_LOCAL";
|
||||
|
||||
/// <summary>
|
||||
/// 文件-MINIO
|
||||
/// </summary>
|
||||
public const string CONFIG_FILE_MINIO = "FILE_MINIO";
|
||||
|
||||
#endregion 系统配置
|
||||
|
||||
#region Mqtt配置
|
||||
|
||||
/// <summary>
|
||||
/// MQTT配置
|
||||
/// </summary>
|
||||
public const string CONFIG_MQTT_BASE = "MQTT_BASE";
|
||||
|
||||
#endregion Mqtt配置
|
||||
|
||||
#region 关系表
|
||||
|
||||
/// <summary>
|
||||
/// 用户有哪些角色
|
||||
/// </summary>
|
||||
public const string RELATION_SYS_USER_HAS_ROLE = "SYS_USER_HAS_ROLE";
|
||||
|
||||
/// <summary>
|
||||
/// 角色有哪些资源
|
||||
/// </summary>
|
||||
public const string RELATION_SYS_ROLE_HAS_RESOURCE = "SYS_ROLE_HAS_RESOURCE";
|
||||
|
||||
/// <summary>
|
||||
/// 角色有哪些模块
|
||||
/// </summary>
|
||||
public const string RELATION_SYS_ROLE_HAS_MODULE = "SYS_ROLE_HAS_MODULE";
|
||||
|
||||
/// <summary>
|
||||
/// 用户有哪些模块
|
||||
/// </summary>
|
||||
public const string RELATION_SYS_USER_HAS_MODULE = "SYS_USER_HAS_MODULE";
|
||||
|
||||
/// <summary>
|
||||
///用户有哪些资源
|
||||
/// </summary>
|
||||
public const string RELATION_SYS_USER_HAS_RESOURCE = "SYS_USER_HAS_RESOURCE";
|
||||
|
||||
/// <summary>
|
||||
/// 角色有哪些权限
|
||||
/// </summary>
|
||||
public const string RELATION_SYS_ROLE_HAS_PERMISSION = "SYS_ROLE_HAS_PERMISSION";
|
||||
|
||||
/// <summary>
|
||||
/// 用户有哪些权限
|
||||
/// </summary>
|
||||
public const string RELATION_SYS_USER_HAS_PERMISSION = "SYS_USER_HAS_PERMISSION";
|
||||
|
||||
/// <summary>
|
||||
/// 用户工作台数据
|
||||
/// </summary>
|
||||
public const string RELATION_SYS_USER_WORKBENCH_DATA = "SYS_USER_WORKBENCH_DATA";
|
||||
|
||||
/// <summary>
|
||||
/// 用户日程数据
|
||||
/// </summary>
|
||||
public const string RELATION_SYS_USER_SCHEDULE_DATA = "SYS_USER_SCHEDULE_DATA";
|
||||
|
||||
/// <summary>
|
||||
/// 站内信与接收用户
|
||||
/// </summary>
|
||||
public const string RELATION_MSG_TO_USER = "MSG_TO_USER";
|
||||
|
||||
#endregion 关系表
|
||||
|
||||
#region 数据范围
|
||||
|
||||
/// <summary>
|
||||
/// 本人
|
||||
/// </summary>
|
||||
public const string SCOPE_SELF = "SCOPE_SELF";
|
||||
|
||||
/// <summary>
|
||||
/// 所有
|
||||
/// </summary>
|
||||
public const string SCOPE_ALL = "SCOPE_ALL";
|
||||
|
||||
/// <summary>
|
||||
/// 仅所属组织
|
||||
/// </summary>
|
||||
public const string SCOPE_ORG = "SCOPE_ORG";
|
||||
|
||||
/// <summary>
|
||||
/// 所属组织及以下
|
||||
/// </summary>
|
||||
public const string SCOPE_ORG_CHILD = "SCOPE_ORG_CHILD";
|
||||
|
||||
/// <summary>
|
||||
/// 自定义
|
||||
/// </summary>
|
||||
public const string SCOPE_ORG_DEFINE = "SCOPE_ORG_DEFINE";
|
||||
|
||||
#endregion 数据范围
|
||||
|
||||
#region 资源表
|
||||
|
||||
/// <summary>
|
||||
/// 模块
|
||||
/// </summary>
|
||||
public const string RESOURCE_MODULE = "MODULE";
|
||||
|
||||
/// <summary>
|
||||
/// 菜单
|
||||
/// </summary>
|
||||
public const string RESOURCE_MENU = "MENU";
|
||||
|
||||
/// <summary>
|
||||
/// 单页
|
||||
/// </summary>
|
||||
public const string RESOURCE_SPA = "SPA";
|
||||
|
||||
/// <summary>
|
||||
/// 按钮
|
||||
/// </summary>
|
||||
public const string RESOURCE_BUTTON = "BUTTON";
|
||||
|
||||
#endregion 资源表
|
||||
|
||||
#region 日志表
|
||||
|
||||
/// <summary>
|
||||
/// 登录
|
||||
/// </summary>
|
||||
public const string LOG_LOGIN = "LOGIN";
|
||||
|
||||
/// <summary>
|
||||
/// 登出
|
||||
/// </summary>
|
||||
public const string LOG_LOGOUT = "LOGOUT";
|
||||
|
||||
/// <summary>
|
||||
/// 操作
|
||||
/// </summary>
|
||||
public const string LOG_OPERATE = "OPERATE";
|
||||
|
||||
/// <summary>
|
||||
/// 异常
|
||||
/// </summary>
|
||||
public const string LOG_EXCEPTION = "EXCEPTION";
|
||||
|
||||
#endregion 日志表
|
||||
|
||||
#region 字典表
|
||||
|
||||
/// <summary>
|
||||
/// 框架
|
||||
/// </summary>
|
||||
public const string DICT_FRM = "FRM";
|
||||
|
||||
/// <summary>
|
||||
/// 业务
|
||||
/// </summary>
|
||||
public const string DICT_BIZ = "BIZ";
|
||||
|
||||
#endregion 字典表
|
||||
|
||||
#region 组织表
|
||||
|
||||
/// <summary>
|
||||
/// 部门
|
||||
/// </summary>
|
||||
public const string ORG_DEPT = "DEPT";
|
||||
|
||||
/// <summary>
|
||||
/// 公司
|
||||
/// </summary>
|
||||
public const string ORG_COMPANY = "COMPANY";
|
||||
|
||||
#endregion 组织表
|
||||
|
||||
#region 职位表
|
||||
|
||||
/// <summary>
|
||||
/// 高层
|
||||
/// </summary>
|
||||
public const string POSITION_HIGH = "HIGH";
|
||||
|
||||
/// <summary>
|
||||
/// 中层
|
||||
/// </summary>
|
||||
public const string POSITION_MIDDLE = "MIDDLE";
|
||||
|
||||
/// <summary>
|
||||
/// 基层
|
||||
/// </summary>
|
||||
public const string POSITION_LOW = "LOW";
|
||||
|
||||
#endregion 职位表
|
||||
|
||||
#region 角色表
|
||||
|
||||
/// <summary>
|
||||
/// 全局
|
||||
/// </summary>
|
||||
public const string ROLE_GLOBAL = "GLOBAL";
|
||||
|
||||
/// <summary>
|
||||
/// 机构
|
||||
/// </summary>
|
||||
public const string ROLE_ORG = "ORG";
|
||||
|
||||
#endregion 角色表
|
||||
|
||||
#region 站内信表
|
||||
|
||||
/// <summary>
|
||||
/// 通知
|
||||
/// </summary>
|
||||
public const string MESSAGE_INFORM = "INFORM";
|
||||
|
||||
/// <summary>
|
||||
/// 公告
|
||||
/// </summary>
|
||||
public const string MESSAGE_NOTICE = "NOTICE";
|
||||
|
||||
#endregion 站内信表
|
||||
}
|
||||
@@ -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 是否
|
||||
|
||||
/// <summary>
|
||||
/// 是
|
||||
/// </summary>
|
||||
public const string Yes = "Y";
|
||||
|
||||
/// <summary>
|
||||
/// 否
|
||||
/// </summary>
|
||||
public const string No = "N";
|
||||
|
||||
#endregion 是否
|
||||
|
||||
/// <summary>
|
||||
/// 压缩包
|
||||
/// </summary>
|
||||
public const string Zip = "ZIP";
|
||||
|
||||
/// <summary>
|
||||
/// 项目中
|
||||
/// </summary>
|
||||
public const string Pro = "PRO";
|
||||
|
||||
/// <summary>
|
||||
/// 全部
|
||||
/// </summary>
|
||||
public const string ExecAll = "ALL";
|
||||
|
||||
/// <summary>
|
||||
/// 前端
|
||||
/// </summary>
|
||||
public const string ExecFrontend = "FRONTEND";
|
||||
|
||||
/// <summary>
|
||||
/// 后端
|
||||
/// </summary>
|
||||
public const string ExecBackend = "BACKEND";
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 系统配置常量
|
||||
/// </summary>
|
||||
public class SysConfigConst
|
||||
{
|
||||
#region MyRegion
|
||||
|
||||
/// <summary>
|
||||
/// 系统名称
|
||||
/// </summary>
|
||||
public const string SYS_NAME = "SYS_NAME";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ico图标
|
||||
/// </summary>
|
||||
public const string SYS_ICO = "SYS_ICO";
|
||||
|
||||
/// <summary>
|
||||
/// 网站开启访问
|
||||
/// </summary>
|
||||
public const string SYS_WEB_STATUS = "SYS_WEB_STATUS";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 网站关闭提示
|
||||
/// </summary>
|
||||
public const string SYS_WEB_CLOSE_PROMPT = "SYS_WEB_CLOSE_PROMPT";
|
||||
|
||||
/// <summary>
|
||||
/// 系统logo
|
||||
/// </summary>
|
||||
public const string SYS_LOGO = "SYS_LOGO";
|
||||
|
||||
/// <summary>
|
||||
/// 系统版本
|
||||
/// </summary>
|
||||
public const string SYS_VERSION = "SYS_VERSION";
|
||||
|
||||
/// <summary>
|
||||
/// 多租户开关
|
||||
/// </summary>
|
||||
public const string SYS_TENANT_OPTIONS = "SYS_TENANT_OPTIONS";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 系统默认工作台
|
||||
/// </summary>
|
||||
public const string SYS_DEFAULT_WORKBENCH_DATA = "SYS_DEFAULT_WORKBENCH_DATA";
|
||||
|
||||
#endregion
|
||||
|
||||
#region 登录策略
|
||||
|
||||
/// <summary>
|
||||
/// 登录验证码开关
|
||||
/// </summary>
|
||||
public const string LOGIN_CAPTCHA_OPEN = "LOGIN_CAPTCHA_OPEN";
|
||||
|
||||
/// <summary>
|
||||
/// 登录验证码开关
|
||||
/// </summary>
|
||||
public const string LOGIN_CAPTCHA_TYPE = "LOGIN_CAPTCHA_TYPE";
|
||||
|
||||
/// <summary>
|
||||
/// 单用户登录开关
|
||||
/// </summary>
|
||||
public const string LOGIN_SINGLE_OPEN = "LOGIN_SINGLE_OPEN";
|
||||
|
||||
/// <summary>
|
||||
/// 登录错误锁定时长
|
||||
/// </summary>
|
||||
public const string LOGIN_ERROR_LOCK = "LOGIN_ERROR_LOCK";
|
||||
|
||||
/// <summary>
|
||||
/// 登录错误锁定时长
|
||||
/// </summary>
|
||||
public const string LOGIN_ERROR_RESET_TIME = "LOGIN_ERROR_RESET_TIME";
|
||||
|
||||
/// <summary>
|
||||
/// 登录错误次数
|
||||
/// </summary>
|
||||
public const string LOGIN_ERROR_COUNT = "LOGIN_ERROR_COUNT";
|
||||
|
||||
#endregion 登录策略
|
||||
|
||||
#region 密码策略
|
||||
|
||||
/// <summary>
|
||||
/// 默认用户密码
|
||||
/// </summary>
|
||||
public const string PWD_DEFAULT_PASSWORD = "PWD_DEFAULT_PASSWORD";
|
||||
|
||||
/// <summary>
|
||||
/// 密码定期提醒更新
|
||||
/// </summary>
|
||||
public const string PWD_REMIND = "PWD_REMIND";
|
||||
|
||||
/// <summary>
|
||||
/// 密码定期提醒更新时间
|
||||
/// </summary>
|
||||
public const string PWD_REMIND_DAY = "PWD_REMIND_DAY";
|
||||
|
||||
/// <summary>
|
||||
/// 修改初始密码提醒
|
||||
/// </summary>
|
||||
public const string PWD_UPDATE_DEFAULT = "PWD_UPDATE_DEFAULT";
|
||||
|
||||
/// <summary>
|
||||
/// 密码最小长度
|
||||
/// </summary>
|
||||
public const string PWD_MIN_LENGTH = "PWD_MIN_LENGTH";
|
||||
|
||||
/// <summary>
|
||||
/// 包含数字
|
||||
/// </summary>
|
||||
public const string PWD_CONTAIN_NUM = "PWD_CONTAIN_NUM";
|
||||
|
||||
/// <summary>
|
||||
/// 包含小写字母
|
||||
/// </summary>
|
||||
public const string PWD_CONTAIN_LOWER = "PWD_CONTAIN_LOWER";
|
||||
|
||||
/// <summary>
|
||||
/// 包含大写字母
|
||||
/// </summary>
|
||||
public const string PWD_CONTAIN_UPPER = "PWD_CONTAIN_UPPER";
|
||||
|
||||
/// <summary>
|
||||
/// 包含特殊字符
|
||||
/// </summary>
|
||||
public const string PWD_CONTAIN_CHARACTER = "PWD_CONTAIN_UPPER";
|
||||
|
||||
#endregion 密码策略
|
||||
|
||||
#region 存储引擎
|
||||
|
||||
/// <summary>
|
||||
/// windows系统本地目录
|
||||
/// </summary>
|
||||
public const string FILE_LOCAL_FOLDER_FOR_WINDOWS = "FILE_LOCAL_FOLDER_FOR_WINDOWS";
|
||||
|
||||
/// <summary>
|
||||
/// Unix系统本地目录
|
||||
/// </summary>
|
||||
public const string FILE_LOCAL_FOLDER_FOR_UNIX = "FILE_LOCAL_FOLDER_FOR_UNIX";
|
||||
|
||||
/// <summary>
|
||||
/// MINIO文件AccessKey
|
||||
/// </summary>
|
||||
public const string FILE_MINIO_ACCESS_KEY = "FILE_MINIO_ACCESS_KEY";
|
||||
|
||||
/// <summary>
|
||||
/// MINIO文件SecretKey
|
||||
/// </summary>
|
||||
public const string FILE_MINIO_SECRET_KEY = "FILE_MINIO_SECRET_KEY";
|
||||
|
||||
/// <summary>
|
||||
/// MINIO文件EndPoint
|
||||
/// </summary>
|
||||
public const string FILE_MINIO_END_POINT = "FILE_MINIO_END_POINT";
|
||||
|
||||
/// <summary>
|
||||
/// MINIO文件默认存储桶
|
||||
/// </summary>
|
||||
public const string FILE_MINIO_DEFAULT_BUCKET_NAME = "FILE_MINIO_DEFAULT_BUCKET_NAME";
|
||||
|
||||
#endregion 存储引擎
|
||||
|
||||
#region MQTT
|
||||
|
||||
/// <summary>
|
||||
/// mqtt连接地址
|
||||
/// </summary>
|
||||
public const string MQTT_PARAM_URL = "MQTT_PARAM_URL";
|
||||
|
||||
/// <summary>
|
||||
/// mqtt连接用户名
|
||||
/// </summary>
|
||||
public const string MQTT_PARAM_USERNAME = "MQTT_PARAM_USERNAME";
|
||||
|
||||
/// <summary>
|
||||
/// mqtt连接密码
|
||||
/// </summary>
|
||||
public const string MQTT_PARAM_PASSWORD = "MQTT_PARAM_PASSWORD";
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 字典常量
|
||||
/// </summary>
|
||||
public class SysDictConst
|
||||
{
|
||||
#region 系统字典
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
/// </summary>
|
||||
public const string GENDER = "GENDER";
|
||||
|
||||
/// <summary>
|
||||
/// 名族
|
||||
/// </summary>
|
||||
public const string NATION = "NATION";
|
||||
|
||||
/// <summary>
|
||||
/// 用户证件类型
|
||||
/// </summary>
|
||||
public const string ID_CARD_TYPE = "ID_CARD_TYPE";
|
||||
|
||||
/// <summary>
|
||||
/// 通用文化程度
|
||||
/// </summary>
|
||||
public const string CULTURE_LEVEL = "CULTURE_LEVEL";
|
||||
|
||||
/// <summary>
|
||||
/// 系统职位分类
|
||||
/// </summary>
|
||||
public const string POSITION_CATEGORY = "POSITION_CATEGORY";
|
||||
|
||||
#region 在线用户状态
|
||||
|
||||
/// <summary>
|
||||
/// 在线
|
||||
/// </summary>
|
||||
public const string ONLINE_STATUS_ONLINE = "ONLINE";
|
||||
|
||||
/// <summary>
|
||||
/// 离线
|
||||
/// </summary>
|
||||
public const string ONLINE_STATUS_OFFLINE = "OFFLINE";
|
||||
|
||||
#endregion 在线用户状态
|
||||
|
||||
#region 上传文件引擎
|
||||
|
||||
/// <summary>
|
||||
/// 本地
|
||||
/// </summary>
|
||||
public const string FILE_ENGINE_LOCAL = "LOCAL";
|
||||
|
||||
/// <summary>
|
||||
/// MINIO
|
||||
/// </summary>
|
||||
public const string FILE_ENGINE_MINIO = "MINIO";
|
||||
|
||||
#endregion 上传文件引擎
|
||||
|
||||
#region 系统字典分类
|
||||
|
||||
/// <summary>
|
||||
/// 系统
|
||||
/// </summary>
|
||||
public const string DICT_CATEGORY_FRM = "FRM";
|
||||
|
||||
/// <summary>
|
||||
/// 业务
|
||||
/// </summary>
|
||||
public const string DICT_CATEGORY_BIZ = "BIZ";
|
||||
|
||||
#endregion 系统字典分类
|
||||
|
||||
#region 多租户选项
|
||||
|
||||
/// <summary>
|
||||
/// 关闭
|
||||
/// </summary>
|
||||
public const string TENANT_OPTIONS_CLOSE = "CLOSE";
|
||||
|
||||
/// <summary>
|
||||
/// 手动选择
|
||||
/// </summary>
|
||||
public const string TENANT_OPTIONS_CHOSE = "CHOSE";
|
||||
|
||||
/// <summary>
|
||||
/// 根据域名
|
||||
/// </summary>
|
||||
public const string TENANT_OPTIONS_DOMAIN = "DOMAIN";
|
||||
|
||||
#endregion
|
||||
|
||||
#region 站内信
|
||||
|
||||
/// <summary>
|
||||
/// 消息分类
|
||||
/// </summary>
|
||||
public const string MESSAGE_CATEGORY = "MESSAGE_CATEGORY";
|
||||
|
||||
/// <summary>
|
||||
/// 接受者类型
|
||||
/// </summary>
|
||||
public const string RECEIVER_TYPE = "RECEIVER_TYPE";
|
||||
|
||||
/// <summary>
|
||||
/// 发送方式
|
||||
/// </summary>
|
||||
public const string MESSAGE_WAY = "MESSAGE_WAY";
|
||||
|
||||
/// <summary>
|
||||
/// 立即发送
|
||||
/// </summary>
|
||||
public const string SEND_WAY_NOW = "NOW";
|
||||
|
||||
/// <summary>
|
||||
/// 延迟发送
|
||||
/// </summary>
|
||||
public const string SEND_WAY_DELAY = "DELAY";
|
||||
|
||||
/// <summary>
|
||||
/// 指定时间
|
||||
/// </summary>
|
||||
public const string SEND_WAY_SCHEDULE = "SCHEDULE";
|
||||
|
||||
/// <summary>
|
||||
/// 待发送
|
||||
/// </summary>
|
||||
public const string MESSAGE_STATUS_READY = "READY";
|
||||
|
||||
/// <summary>
|
||||
/// 已发送
|
||||
/// </summary>
|
||||
public const string MESSAGE_STATUS_ALREADY = "ALREADY";
|
||||
|
||||
/// <summary>
|
||||
/// 所有
|
||||
/// </summary>
|
||||
public const string RECEIVER_TYPE_ALL = "ALL";
|
||||
|
||||
/// <summary>
|
||||
/// 角色
|
||||
/// </summary>
|
||||
public const string RECEIVER_TYPE_ROLE = "ROLE";
|
||||
|
||||
/// <summary>
|
||||
/// 指定
|
||||
/// </summary>
|
||||
public const string RECEIVER_TYPE_APPOINT = "APPOINT";
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion 系统字典
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 日志常量
|
||||
/// </summary>
|
||||
public class SysLogConst
|
||||
{
|
||||
/// <summary>
|
||||
/// 成功
|
||||
/// </summary>
|
||||
public const string SUCCESS = "SUCCESS";
|
||||
|
||||
/// <summary>
|
||||
/// 成功
|
||||
/// </summary>
|
||||
public const string FAIL = "FAIL";
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 资源表常量
|
||||
/// </summary>
|
||||
public class SysResourceConst
|
||||
{
|
||||
/// <summary>
|
||||
/// 目录
|
||||
/// </summary>
|
||||
public const string CATALOG = "CATALOG";
|
||||
|
||||
/// <summary>
|
||||
/// 菜单
|
||||
/// </summary>
|
||||
public const string MENU = "MENU";
|
||||
|
||||
/// <summary>
|
||||
/// 内链
|
||||
/// </summary>
|
||||
public const string IFRAME = "IFRAME";
|
||||
|
||||
/// <summary>
|
||||
/// 子页
|
||||
/// </summary>
|
||||
public const string SUBSET = "SUBSET";
|
||||
|
||||
/// <summary>
|
||||
/// 外链
|
||||
/// </summary>
|
||||
public const string LINK = "LINK";
|
||||
|
||||
/// <summary>
|
||||
/// 单页
|
||||
/// </summary>
|
||||
public const string SPA = "SPA";
|
||||
|
||||
/// <summary>
|
||||
/// 系统内置单页面编码
|
||||
/// </summary>
|
||||
public const string SYSTEM = "system";
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 角色常量
|
||||
/// </summary>
|
||||
public class SysRoleConst
|
||||
{
|
||||
/// <summary>
|
||||
/// 超级管理员
|
||||
/// </summary>
|
||||
public const string SUPER_ADMIN = "superAdmin";
|
||||
|
||||
/// <summary>
|
||||
/// 业务管理员
|
||||
/// </summary>
|
||||
public const string BIZ_ADMIN = "bizAdmin";
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 系统层常量
|
||||
/// </summary>
|
||||
public class SystemConst
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统配置表缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_DEV_CONFIG = CacheConst.CACHE_PREFIX_WEB + "SysConfig:";
|
||||
|
||||
/// <summary>
|
||||
/// 登录验证码缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_CAPTCHA = CacheConst.CACHE_PREFIX_WEB + "Captcha:";
|
||||
|
||||
/// <summary>
|
||||
/// 用户表缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_SYS_USER = CacheConst.CACHE_PREFIX_WEB + "SysUser";
|
||||
|
||||
/// <summary>
|
||||
/// 用户头像缓存关系Key
|
||||
/// </summary>
|
||||
public const string CACHE_SYS_USER_AVATAR = CacheConst.CACHE_PREFIX_WEB + "SysUserAvatar";
|
||||
|
||||
/// <summary>
|
||||
/// 用户手机号关系缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_SYS_USER_PHONE = CacheConst.CACHE_PREFIX_WEB + "SysUserPhone";
|
||||
|
||||
/// <summary>
|
||||
/// 用户手机号关系缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_SYS_USER_ACCOUNT = CacheConst.CACHE_PREFIX_WEB + "SysUserAccount";
|
||||
|
||||
/// <summary>
|
||||
/// 资源表缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_SYS_RESOURCE = CacheConst.CACHE_PREFIX_WEB + "SysResource:";
|
||||
|
||||
/// <summary>
|
||||
/// 字典表缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_DEV_DICT = CacheConst.CACHE_PREFIX_WEB + "SysDict";
|
||||
|
||||
/// <summary>
|
||||
/// 关系表缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_SYS_RELATION = CacheConst.CACHE_PREFIX_WEB + "SysRelation:";
|
||||
|
||||
/// <summary>
|
||||
/// 机构表缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_SYS_ORG = CacheConst.CACHE_PREFIX_WEB + "SysOrg";
|
||||
|
||||
/// <summary>
|
||||
/// 机构对应租户关系缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_SYS_ORG_TENANT = CacheConst.CACHE_PREFIX_WEB + "SysOrgTenant";
|
||||
|
||||
/// <summary>
|
||||
/// 租户列表缓存
|
||||
/// </summary>
|
||||
public const string CACHE_SYS_TENANT = CacheConst.CACHE_PREFIX_WEB + "Tenant";
|
||||
|
||||
/// <summary>
|
||||
/// 角色表缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_SYS_ROLE = CacheConst.CACHE_PREFIX_WEB + "SysRole";
|
||||
|
||||
/// <summary>
|
||||
/// 职位表缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_SYS_POSITION = CacheConst.CACHE_PREFIX_WEB + "SysPosition";
|
||||
|
||||
#region 登录错误次数
|
||||
|
||||
/// <summary>
|
||||
/// 登录错误次数缓存Key
|
||||
/// </summary>
|
||||
public const string CACHE_LOGIN_ERROR_COUNT = CacheConst.CACHE_PREFIX_WEB + "LoginErrorCount:";
|
||||
|
||||
#endregion 登录错误次数
|
||||
|
||||
#region 操作
|
||||
|
||||
/// <summary>
|
||||
/// 添加操作
|
||||
/// </summary>
|
||||
public const string ADD = "添加";
|
||||
|
||||
/// <summary>
|
||||
/// 编辑操作
|
||||
/// </summary>
|
||||
public const string EDIT = "编辑";
|
||||
|
||||
/// <summary>
|
||||
/// 启用操作
|
||||
/// </summary>
|
||||
public const string ENABLE = "启用";
|
||||
|
||||
/// <summary>
|
||||
/// 禁用操作
|
||||
/// </summary>
|
||||
public const string DISABLE = "禁用";
|
||||
|
||||
/// <summary>
|
||||
/// 重置密码操作
|
||||
/// </summary>
|
||||
public const string RESET_PWD = "重置密码";
|
||||
|
||||
/// <summary>
|
||||
/// 用户授权操作
|
||||
/// </summary>
|
||||
public const string GRANT_ROLE = "授权";
|
||||
|
||||
#endregion 操作
|
||||
|
||||
#region 别称
|
||||
|
||||
/// <summary>
|
||||
/// 组织
|
||||
/// </summary>
|
||||
public const string SYS_ORG = "组织";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 职位
|
||||
/// </summary>
|
||||
public const string SYS_POS = "职位";
|
||||
|
||||
#endregion 别称
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 批量修改
|
||||
///</summary>
|
||||
[SugarTable("batch_edit", TableDescription = "批量修改")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
[CodeGen]
|
||||
public class BatchEdit : PrimaryKeyEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 唯一编码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Code", ColumnDescription = "唯一编码", Length = 100, IsNullable = false)]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属库
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ConfigId", ColumnDescription = "所属库", Length = 100, IsNullable = false)]
|
||||
public string ConfigId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实体名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EntityName", ColumnDescription = "实体名", Length = 100, IsNullable = false)]
|
||||
public string EntityName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "TableName", ColumnDescription = "表名", Length = 100, IsNullable = false)]
|
||||
public string TableName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表描述
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "TableDescription", ColumnDescription = "表描述", Length = 100, IsNullable = false)]
|
||||
public string TableDescription { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 批量修改配置表
|
||||
///</summary>
|
||||
[SugarTable("batch_edit_config", TableDescription = "批量修改配置表")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class BatchEditConfig : PrimaryKeyEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 批量配置Id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "UId", ColumnDescription = "批量配置Id", IsNullable = false)]
|
||||
public long UId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字段名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ColumnName", ColumnDescription = "字段名", Length = 100, IsNullable = false)]
|
||||
public string ColumnName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字段描述
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ColumnComment", ColumnDescription = "字段描述", Length = 100, IsNullable = false)]
|
||||
public string ColumnComment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 作用类型
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DataType", ColumnDescription = "作用类型", Length = 100, IsNullable = false)]
|
||||
public string DataType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字典值
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DictTypeCode", ColumnDescription = "字典值", Length = 100, IsNullable = true)]
|
||||
public string DictTypeCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库类型
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "NetType", ColumnDescription = "数据库类型", Length = 100, IsNullable = true)]
|
||||
public string NetType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接口名称
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "RequestUrl", ColumnDescription = "接口名称", Length = 100, IsNullable = true)]
|
||||
public string RequestUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接口类型
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "RequestType", ColumnDescription = "接口类型", Length = 100, IsNullable = true)]
|
||||
public string RequestType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接口结果标签
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "RequestLabel", ColumnDescription = "接口结果标签", Length = 100, IsNullable = true)]
|
||||
public string RequestLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接口结果值
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "RequestValue", ColumnDescription = "接口结果值", Length = 100, IsNullable = true)]
|
||||
public string RequestValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 启用状态
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Status", ColumnDescription = "状态", Length = 100, IsNullable = false)]
|
||||
public string Status { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// C端用户关系
|
||||
/// </summary>
|
||||
[SugarTable("client_relation", TableDescription = "关系")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class ClientRelation : PrimaryKeyEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 对象ID
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ObjectId", ColumnDescription = "对象ID", IsNullable = false)]
|
||||
public long ObjectId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "TargetId", ColumnDescription = "目标ID", IsNullable = true)]
|
||||
public string TargetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200, IsNullable = true)]
|
||||
public string Category { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// C端用户
|
||||
///</summary>
|
||||
[SugarTable("client_user", TableDescription = "C端用户")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class ClientUser : DataEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 头像
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Avatar", ColumnDescription = "头像", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 签名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Signature", ColumnDescription = "签名", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public string Signature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账号
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Account", ColumnDescription = "账号", Length = 200, IsNullable = false)]
|
||||
public string Account { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Password", ColumnDescription = "密码", Length = 200, IsNullable = false)]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 姓名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Name", ColumnDescription = "姓名", Length = 200, IsNullable = true)]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 昵称
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Nickname", ColumnDescription = "昵称", Length = 200, IsNullable = true)]
|
||||
public string Nickname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Gender", ColumnDescription = "性别", Length = 200, IsNullable = true)]
|
||||
public string Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 年龄
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Age", ColumnDescription = "年龄", Length = 200, IsNullable = true)]
|
||||
public string Age { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 出生日期
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Birthday", ColumnDescription = "出生日期", Length = 200, IsNullable = true)]
|
||||
public string Birthday { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 民族
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Nation", ColumnDescription = "民族", Length = 200, IsNullable = true)]
|
||||
public string Nation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 籍贯
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "NativePlace", ColumnDescription = "籍贯", Length = 200, IsNullable = true)]
|
||||
public string NativePlace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 家庭住址
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "HomeAddress", ColumnDescription = "家庭住址", IsNullable = true)]
|
||||
public string HomeAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通信地址
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "MailingAddress", ColumnDescription = "通信地址", IsNullable = true)]
|
||||
public string MailingAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 证件类型
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "IdCardType", ColumnDescription = "证件类型", Length = 200, IsNullable = true)]
|
||||
public string IdCardType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 证件号码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "IdCardNumber", ColumnDescription = "证件号码", Length = 200, IsNullable = true)]
|
||||
public string IdCardNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文化程度
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "CultureLevel", ColumnDescription = "文化程度", Length = 200, IsNullable = true)]
|
||||
public string CultureLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 政治面貌
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "PoliticalOutlook", ColumnDescription = "政治面貌", Length = 200, IsNullable = true)]
|
||||
public string PoliticalOutlook { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 毕业院校
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "College", ColumnDescription = "毕业院校", Length = 200, IsNullable = true)]
|
||||
public string College { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 学历
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Education", ColumnDescription = "学历", Length = 200, IsNullable = true)]
|
||||
public string Education { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 学制
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EduLength", ColumnDescription = "学制", Length = 200, IsNullable = true)]
|
||||
public string EduLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 学位
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Degree", ColumnDescription = "学位", Length = 200, IsNullable = true)]
|
||||
public string Degree { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手机
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Phone", ColumnDescription = "手机", Length = 200, IsNullable = true)]
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 邮箱
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Email", ColumnDescription = "邮箱", Length = 200, IsNullable = true)]
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 家庭电话
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "HomeTel", ColumnDescription = "家庭电话", Length = 200, IsNullable = true)]
|
||||
public string HomeTel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 办公电话
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OfficeTel", ColumnDescription = "办公电话", Length = 200, IsNullable = true)]
|
||||
public string OfficeTel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 紧急联系人
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EmergencyContact", ColumnDescription = "紧急联系人", Length = 200, IsNullable = true)]
|
||||
public string EmergencyContact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 紧急联系人电话
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EmergencyPhone", ColumnDescription = "紧急联系人电话", Length = 200, IsNullable = true)]
|
||||
public string EmergencyPhone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 紧急联系人地址
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EmergencyAddress", ColumnDescription = "紧急联系人地址", IsNullable = true)]
|
||||
public string EmergencyAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 员工编号
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EmpNo", ColumnDescription = "员工编号", Length = 200, IsNullable = true)]
|
||||
public string EmpNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 入职日期
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EntryDate", ColumnDescription = "入职日期", Length = 200, IsNullable = true)]
|
||||
public string EntryDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OrgId", ColumnDescription = "机构id")]
|
||||
public long OrgId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 职位id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "PositionId", ColumnDescription = "职位id")]
|
||||
public long PositionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 职级
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "PositionLevel", ColumnDescription = "职级", Length = 200, IsNullable = true)]
|
||||
public string PositionLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主管id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DirectorId", ColumnDescription = "主管id", IsNullable = true)]
|
||||
public long DirectorId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兼任信息
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "PositionJson", ColumnDescription = "兼任信息", Length = 100, IsNullable = true)]
|
||||
public string PositionJson { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上次登录ip
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LastLoginIp", ColumnDescription = "上次登录ip", Length = 200, IsNullable = true)]
|
||||
public string LastLoginIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上次登录地点
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LastLoginAddress", ColumnDescription = "上次登录地点", Length = 200, IsNullable = true)]
|
||||
public string LastLoginAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上次登录时间
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LastLoginTime", ColumnDescription = "上次登录时间", IsNullable = true)]
|
||||
public DateTime? LastLoginTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上次登录设备
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LastLoginDevice", ColumnDescription = "上次登录设备", IsNullable = true)]
|
||||
public string LastLoginDevice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录ip
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LatestLoginIp", ColumnDescription = "最新登录ip", Length = 200, IsNullable = true)]
|
||||
public string LatestLoginIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录地点
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LatestLoginAddress", ColumnDescription = "最新登录地点", Length = 200, IsNullable = true)]
|
||||
public string LatestLoginAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录时间
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LatestLoginTime", ColumnDescription = "最新登录时间", IsNullable = true)]
|
||||
public DateTime? LatestLoginTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录设备
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LatestLoginDevice", ColumnDescription = "最新登录设备", IsNullable = true)]
|
||||
public string LatestLoginDevice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户状态
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Status", ColumnDescription = "用户状态", Length = 200, IsNullable = true)]
|
||||
public string Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)]
|
||||
public int? SortCode { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成基础
|
||||
///</summary>
|
||||
[SugarTable("gen_basic", TableDescription = "代码生成基础")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class GenBasic : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 所属库
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ConfigId", ColumnDescription = "库名", Length = 200)]
|
||||
public virtual string ConfigId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主表
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DbTable", ColumnDescription = "主表", Length = 200)]
|
||||
public virtual string DbTable { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 表实体名称
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "EntityName", ColumnDescription = "表实体名称", Length = 200)]
|
||||
public virtual string EntityName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能列表
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Functions", ColumnDescription = "功能列表", Length = 200, IsNullable = false)]
|
||||
public virtual string Functions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据权限
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DataPermission", ColumnDescription = "数据权限", Length = 200, IsNullable = false)]
|
||||
public virtual string DataPermission { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生成模版
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ModuleType", ColumnDescription = "生成模版", Length = 200, IsNullable = false)]
|
||||
public virtual string ModuleType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 树Id字段
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "TreeId", ColumnDescription = "树Id字段", Length = 200, IsNullable = true)]
|
||||
public virtual string TreeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 树父Id字段
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "TreePid", ColumnDescription = "树父Id字段", Length = 200, IsNullable = true)]
|
||||
public virtual string TreePid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 树名称字段
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "TreeName", ColumnDescription = "树名称字段", Length = 200, IsNullable = true)]
|
||||
public virtual string TreeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联子表名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ChildTable", ColumnDescription = "关联子表名", Length = 200, IsNullable = true)]
|
||||
public virtual string ChildTable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联子表外键
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ChildFk", ColumnDescription = "关联子表外键", Length = 200, IsNullable = true)]
|
||||
public virtual string ChildFk { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 移除表前缀
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "TablePrefix", ColumnDescription = "移除表前缀", Length = 200)]
|
||||
public virtual string TablePrefix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生成方式
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "GenerateType", ColumnDescription = "生成方式", Length = 200)]
|
||||
public virtual string GenerateType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属模块
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Module", ColumnDescription = "所属模块")]
|
||||
public virtual long Module { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上级目录
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "MenuPid", ColumnDescription = "上级目录")]
|
||||
public virtual long MenuPid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 业务名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "RouteName", ColumnDescription = "路由名", Length = 200)]
|
||||
public virtual string RouteName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 图标
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Icon", ColumnDescription = "图标", Length = 200)]
|
||||
public virtual string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "FunctionName", ColumnDescription = "功能名", Length = 200)]
|
||||
public virtual string FunctionName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能名后缀
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "FunctionNameSuffix", ColumnDescription = "功能名后缀", Length = 200, IsNullable = true)]
|
||||
public virtual string FunctionNameSuffix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 业务名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "BusName", ColumnDescription = "业务名", Length = 200)]
|
||||
public virtual string BusName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ClassName", ColumnDescription = "类名", Length = 200)]
|
||||
public virtual string ClassName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表单布局
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "FormLayout", ColumnDescription = "表单布局", Length = 200)]
|
||||
public virtual string FormLayout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用栅格
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "GridWhether", ColumnDescription = "使用栅格", Length = 200)]
|
||||
public virtual string GridWhether { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 左侧树
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LeftTree", ColumnDescription = "使用左侧树", Length = 200)]
|
||||
public virtual string LeftTree { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 前端项目路径
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "FrontedPath", ColumnDescription = "前端项目路径", IsNullable = true, Length = 200)]
|
||||
public virtual string FrontedPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 服务代码存放项目
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ServicePosition", ColumnDescription = "服务代码存放项目", IsNullable = true, Length = 200)]
|
||||
public virtual string ServicePosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 服务代码存放文件夹
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ServiceDictionary", ColumnDescription = "服务代码存放文件夹", IsNullable = true, Length = 200)]
|
||||
public virtual string ServiceDictionary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 控制器代码存放位置
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ControllerPosition", ColumnDescription = "控制器代码存放位置", IsNullable = true, Length = 200)]
|
||||
public virtual string ControllerPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 控制器代码存放文件夹
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ControllerDictionary", ColumnDescription = "控制器代码存放文件夹", IsNullable = true, Length = 200)]
|
||||
public virtual string ControllerDictionary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 作者
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "AuthorName", ColumnDescription = "作者", Length = 200)]
|
||||
public virtual string AuthorName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序")]
|
||||
public virtual int SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能列表
|
||||
///</summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public virtual List<string> FuncList { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成配置
|
||||
///</summary>
|
||||
[SugarTable("gen_config", TableDescription = "代码生成配置")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class GenConfig : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础ID
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "BasicId", ColumnDescription = "基础配置ID")]
|
||||
public long BasicId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字段排序
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "FieldIndex", ColumnDescription = "字段排序", IsNullable = true)]
|
||||
public int FieldIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否主键
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "IsPrimaryKey", ColumnDescription = "是否主键", Length = 200)]
|
||||
public string IsPrimaryKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字段
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "FieldName", ColumnDescription = "字段", Length = 200)]
|
||||
public string FieldName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "FieldRemark", ColumnDescription = "名称", Length = 200)]
|
||||
public string FieldRemark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "FieldType", ColumnDescription = "类型", Length = 200)]
|
||||
public string FieldType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实体类型
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "FieldNetType", ColumnDescription = "实体类型", Length = 200)]
|
||||
public string FieldNetType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 作用类型
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EffectType", ColumnDescription = "作用类型", Length = 200)]
|
||||
public string EffectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 外键显示字段
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "FkEntityName", ColumnDescription = "外键实体名称", Length = 200, IsNullable = true)]
|
||||
public string FkEntityName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 外键ID
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "FkColumnId", ColumnDescription = "外键ID", Length = 200, IsNullable = true)]
|
||||
public string FkColumnId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 外键显示字段
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "FkColumnName", ColumnDescription = "外键显示字段", Length = 200, IsNullable = true)]
|
||||
public string FkColumnName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字典
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DictTypeCode", ColumnDescription = "字典", Length = 200, IsNullable = true)]
|
||||
public string DictTypeCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 列宽度
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Width", ColumnDescription = "列宽度")]
|
||||
public int Width { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 列表显示
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "WhetherTable", ColumnDescription = "列表显示", Length = 200)]
|
||||
public string WhetherTable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 列省略
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "WhetherRetract", ColumnDescription = "列省略", Length = 200)]
|
||||
public string WhetherRetract { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可伸缩列
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "WhetherResizable", ColumnDescription = "可伸缩列", Length = 200)]
|
||||
public string WhetherResizable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否增改
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "WhetherAddUpdate", ColumnDescription = "是否增改", Length = 200)]
|
||||
public string WhetherAddUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否导入导出
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "WhetherImportExport", ColumnDescription = "是否导入导出", Length = 200)]
|
||||
public string WhetherImportExport { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 必填
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "WhetherRequired", ColumnDescription = "必填", Length = 200)]
|
||||
public string WhetherRequired { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 查询
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "QueryWhether", ColumnDescription = "查询", Length = 200)]
|
||||
public string QueryWhether { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 查询方式
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "QueryType", ColumnDescription = "查询方式", Length = 200, IsNullable = true)]
|
||||
public string QueryType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序")]
|
||||
public int SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字段名首字母小写
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public string FieldNameFirstLower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字段名首字母大写
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public string FieldNameFirstUpper { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 配置
|
||||
///</summary>
|
||||
[SugarTable("sys_config", TableDescription = "配置")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class SysConfig : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置键
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ConfigKey", ColumnDescription = "配置键", Length = 200)]
|
||||
public virtual string ConfigKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 配置值
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ConfigValue", ColumnDescription = "配置值", ColumnDataType = StaticConfig.CodeFirst_BigString)]
|
||||
public virtual string ConfigValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)]
|
||||
public string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Remark", ColumnDescription = "备注", Length = 200, IsNullable = true)]
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)]
|
||||
public int SortCode { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 字典
|
||||
///</summary>
|
||||
[SugarTable("sys_dict", TableDescription = "字典表")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class SysDict : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 父id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ParentId", ColumnDescription = "父id")]
|
||||
public virtual long ParentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字典文字
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DictLabel", ColumnDescription = "字典文字", Length = 200)]
|
||||
public virtual string DictLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字典值
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DictValue", ColumnDescription = "字典值", Length = 200)]
|
||||
public virtual string DictValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)]
|
||||
public virtual string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码")]
|
||||
public int SortCode { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 子节点
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<SysDict> Children { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 文件表
|
||||
///</summary>
|
||||
[SugarTable("sys_file", TableDescription = "文件表")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class SysFile : DataEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 存储引擎
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Engine", ColumnDescription = "存储引擎", Length = 200)]
|
||||
public string Engine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 存储桶
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Bucket", ColumnDescription = "存储桶", Length = 200)]
|
||||
public string Bucket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件名称
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Name", ColumnDescription = "文件名称")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件后缀
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Suffix", ColumnDescription = "文件后缀", Length = 200)]
|
||||
public string Suffix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件大小kb
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SizeKb", ColumnDescription = "文件大小kb")]
|
||||
public long SizeKb { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件大小(格式化后)
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SizeInfo", ColumnDescription = "文件大小(格式化后)", Length = 200)]
|
||||
public string SizeInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件的对象名(唯一名称)
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ObjName", ColumnDescription = "文件的对象名(唯一名称)")]
|
||||
public string ObjName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件存储路径
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "StoragePath", ColumnDescription = "文件存储路径")]
|
||||
public string StoragePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件下载路径
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DownloadPath", ColumnDescription = "文件下载路径", IsNullable = true)]
|
||||
public string DownloadPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 图片缩略图
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Thumbnail", ColumnDescription = "图片缩略图", IsNullable = true, ColumnDataType = StaticConfig.CodeFirst_BigString)]
|
||||
public string Thumbnail { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 操作日志表
|
||||
///</summary>
|
||||
[SugarTable("sys_log_operate_{year}{month}{day}", TableDescription = "操作日志表")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class SysLogOperate : SysLogVisit
|
||||
{
|
||||
/// <summary>
|
||||
/// 具体消息
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ExeMessage", ColumnDescription = "具体消息", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public string ExeMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类名称
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ClassName", ColumnDescription = "类名称", Length = 200)]
|
||||
public string ClassName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 方法名称
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "MethodName", ColumnDescription = "方法名称", Length = 200)]
|
||||
public string MethodName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求方式
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ReqMethod", ColumnDescription = "请求方式", Length = 200, IsNullable = true)]
|
||||
public string ReqMethod { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求地址
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ReqUrl", ColumnDescription = "请求地址", ColumnDataType = StaticConfig.CodeFirst_BigString)]
|
||||
public string ReqUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求参数
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ParamJson", ColumnDescription = "请求参数", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public string ParamJson { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回结果
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ResultJson", ColumnDescription = "返回结果", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public string ResultJson { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 访问日志表
|
||||
///</summary>
|
||||
[SugarTable("sys_log_visit_{year}{month}{day}", TableDescription = "访问日志表")]
|
||||
[SplitTable(SplitType.Year)]//按年分表 (自带分表支持 年、季、月、周、日)
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class SysLogVisit : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 日志分类
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Category", ColumnDescription = "日志分类", Length = 200)]
|
||||
public string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 日志名称
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Name", ColumnDescription = "日志名称", Length = 200)]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 执行状态
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ExeStatus", ColumnDescription = "执行状态", Length = 200)]
|
||||
public string ExeStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作ip
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OpIp", ColumnDescription = "操作ip", Length = 200)]
|
||||
public string OpIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作地址
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OpAddress", ColumnDescription = "操作地址", Length = 200)]
|
||||
public string OpAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作浏览器
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OpBrowser", ColumnDescription = "操作浏览器", Length = 200)]
|
||||
public string OpBrowser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作系统
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OpOs", ColumnDescription = "操作系统", Length = 200)]
|
||||
public string OpOs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作时间
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OpTime", ColumnDescription = "操作时间")]
|
||||
[SplitField]//分表字段 在插入的时候会根据这个字段插入哪个表,在更新删除的时候用这个字段找出相关表
|
||||
public DateTime OpTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作人姓名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OpUser", ColumnDescription = "操作人姓名", Length = 200, IsNullable = true)]
|
||||
public string OpUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作人姓名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OpAccount", ColumnDescription = "操作人账号", Length = 200, IsNullable = true)]
|
||||
public string OpAccount { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 站内信
|
||||
///</summary>
|
||||
[SugarTable("sys_message", TableDescription = "站内信")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class SysMessage : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 分类
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)]
|
||||
public virtual string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主题
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Subject", ColumnDescription = "主题")]
|
||||
public virtual string Subject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接收人类型
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "ReceiverType", ColumnDescription = "接收人类型")]
|
||||
public virtual string ReceiverType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接收人列表
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "ReceiverInfo", ColumnDescription = "接收人列表", IsJson = true)]
|
||||
public virtual List<ReceiverInfo> ReceiverInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送方式
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "SendWay", ColumnDescription = "发送方式")]
|
||||
public virtual string SendWay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "发送时间")]
|
||||
public virtual DateTime SendTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 正文
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Content", ColumnDescription = "正文", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public virtual string Content { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 延迟时间(秒)
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public int DelayTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 已读情况
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<ReceiverDetail> ReceiverDetail { get; set; } = new List<ReceiverDetail>();
|
||||
|
||||
/// <summary>
|
||||
/// 发送时间格式化
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public string SendTimeFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分组查询用
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public int Index2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否已读
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public bool Read { get; set; }
|
||||
}
|
||||
|
||||
public class ReceiverInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// ID
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public class ReceiverDetail
|
||||
{
|
||||
/// <summary>
|
||||
/// ID
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否已读
|
||||
/// </summary>
|
||||
public bool Read { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 用户消息表
|
||||
///</summary>
|
||||
[SugarTable("sys_message_user", TableDescription = "用户消息表")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class SysMessageUser : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息Id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "MessageId", ColumnDescription = "消息Id", IsNullable = false)]
|
||||
public long MessageId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户Id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "UserId", ColumnDescription = "用户Id", IsNullable = false)]
|
||||
public long UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 已读未读
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Read", ColumnDescription = "已读未读", IsNullable = false)]
|
||||
public bool Read { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 组织
|
||||
///</summary>
|
||||
[SugarTable("sys_org", TableDescription = "组织")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
[CodeGen]
|
||||
public class SysOrg : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 父id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ParentId", ColumnDescription = "父id")]
|
||||
public long ParentId { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "ParentIdList", ColumnDescription = "父id列表", IsNullable = true, IsJson = true)]
|
||||
public List<long> ParentIdList { get; set; } = new List<long>();
|
||||
|
||||
/// <summary>
|
||||
/// 主管ID
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DirectorId", ColumnDescription = "主管ID", IsNullable = true)]
|
||||
public long? DirectorId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Name", ColumnDescription = "名称", Length = 200)]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 全称
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Names", ColumnDescription = "全称", Length = 500)]
|
||||
public string Names { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Code", ColumnDescription = "编码", Length = 200)]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)]
|
||||
public string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)]
|
||||
public int? SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主管信息
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public UserSelectorOutPut DirectorInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子节点
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<SysOrg> Children { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置为叶子节点(设置了loadData时有效)
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public bool? Leaf { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 职位表
|
||||
///</summary>
|
||||
[SugarTable("sys_position", TableDescription = "职位表")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
[CodeGen]
|
||||
public class SysPosition : DataEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 组织id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OrgId", ColumnDescription = "组织id")]
|
||||
public virtual long OrgId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Name", ColumnDescription = "名称", Length = 200)]
|
||||
public virtual string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Code", ColumnDescription = "编码", Length = 200)]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)]
|
||||
public virtual string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)]
|
||||
public int? SortCode { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 系统关系表
|
||||
///</summary>
|
||||
[SugarTable("sys_relation", TableDescription = "系统关系表")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class SysRelation : PrimaryKeyEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 对象ID
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ObjectId", ColumnDescription = "对象ID", IsNullable = false)]
|
||||
public long ObjectId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "TargetId", ColumnDescription = "目标ID", IsNullable = true)]
|
||||
public string TargetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200, IsNullable = false)]
|
||||
public string Category { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 资源
|
||||
///</summary>
|
||||
[SugarTable("sys_resource", TableDescription = "资源")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class SysResource : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 父id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ParentId", ColumnDescription = "父id", IsNullable = true)]
|
||||
public virtual long? ParentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标题
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Title", ColumnDescription = "标题", Length = 200)]
|
||||
public virtual string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 别名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Name", ColumnDescription = "别名", Length = 200, IsNullable = true)]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 描述
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Description", ColumnDescription = "描述", Length = 200, IsNullable = true)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Code", ColumnDescription = "编码", Length = 200, IsNullable = true)]
|
||||
public virtual string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200)]
|
||||
public string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模块
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Module", ColumnDescription = "所属模块Id", IsNullable = true)]
|
||||
public virtual long? Module { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜单类型
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "MenuType", ColumnDescription = "菜单类型", Length = 200, IsNullable = true)]
|
||||
public virtual string MenuType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 路径
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Path", ColumnDescription = "路径", IsNullable = true)]
|
||||
public virtual string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 组件
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Component", ColumnDescription = "组件", Length = 200, IsNullable = true)]
|
||||
public string Component { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 图标
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Icon", ColumnDescription = "图标", Length = 200, IsNullable = true)]
|
||||
public virtual string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否在菜单中隐藏, 需要高亮的 path (通常用作详情页高亮父级菜单)
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "ActiveMenu", ColumnDescription = "需要高亮的 path (通常用作详情页高亮父级菜单)", Length = 200, IsNullable = true)]
|
||||
public string ActiveMenu { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否在菜单中隐藏 (通常列表详情页需要隐藏)
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "IsHide", ColumnDescription = "是否在菜单中隐藏 (通常列表详情页需要隐藏) ", IsNullable = true)]
|
||||
public bool IsHide { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否在菜单中隐藏 (通常列表详情页需要隐藏)
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "IsFull", ColumnDescription = "菜单是否全屏 (示例:数据大屏页面)", IsNullable = true)]
|
||||
public bool IsFull { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜单是否固定在标签页中 (首页通常是固定项)
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "IsAffix", ColumnDescription = "菜单是否固定在标签页中 (首页通常是固定项)", IsNullable = true)]
|
||||
public bool IsAffix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜单是否固定在标签页中 (首页通常是固定项)
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "IsKeepAlive", ColumnDescription = " 当前路由是否缓存", IsNullable = true)]
|
||||
public bool IsKeepAlive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否为首页
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "IsHome", ColumnDescription = " 是否为首页", IsNullable = true)]
|
||||
public bool IsHome { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)]
|
||||
public int? SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 外链地址
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "IsLink", ColumnDescription = "外链地址", IsNullable = true)]
|
||||
public string IsLink { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜单元标签
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public Meta Meta { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子节点
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<SysResource> Children { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 菜单元标签
|
||||
/// </summary>
|
||||
public class Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// 图标
|
||||
/// </summary>
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标题
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否在菜单中隐藏, 需要高亮的 path (通常用作详情页高亮父级菜单)
|
||||
///</summary>
|
||||
public string ActiveMenu { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否在菜单中隐藏 (通常列表详情页需要隐藏)
|
||||
///</summary>
|
||||
public bool IsHide { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 路由外链时填写的访问地址
|
||||
/// </summary>
|
||||
public string IsLink { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 是否在菜单中隐藏 (通常列表详情页需要隐藏)
|
||||
///</summary>
|
||||
public bool IsFull { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜单是否固定在标签页中 (首页通常是固定项)
|
||||
///</summary>
|
||||
public bool IsAffix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜单是否固定在标签页中 (首页通常是固定项)
|
||||
///</summary>
|
||||
public bool IsKeepAlive { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 角色
|
||||
///</summary>
|
||||
[SugarTable("sys_role", TableDescription = "角色")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class SysRole : DataEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 组织id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OrgId", ColumnDescription = "组织id", IsNullable = true)]
|
||||
public long? OrgId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Name", ColumnDescription = "名称", Length = 200, IsNullable = false)]
|
||||
public virtual string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Code", ColumnDescription = "编码", Length = 200, IsNullable = false)]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Category", ColumnDescription = "分类", Length = 200, IsNullable = false)]
|
||||
public virtual string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认数据范围
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DefaultDataScope", ColumnDescription = "默认数据范围", IsJson = true, ColumnDataType = StaticConfig.CodeFirst_BigString,
|
||||
IsNullable = false)]
|
||||
public virtual DefaultDataScope DefaultDataScope { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)]
|
||||
public int? SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户列表
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<UserSelectorOutPut> UserList { get; set; } = new List<UserSelectorOutPut>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 默认数据范围
|
||||
/// </summary>
|
||||
public class DefaultDataScope
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据范围等级
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据范围
|
||||
/// </summary>
|
||||
public string ScopeCategory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义机构范围列表
|
||||
/// </summary>
|
||||
public List<long> ScopeDefineOrgIdList { get; set; } = new List<long>();
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 用户信息表
|
||||
///</summary>
|
||||
[SugarTable("sys_user", TableDescription = "用户信息表")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
[BatchEdit]
|
||||
[CodeGen]
|
||||
public class SysUser : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 头像
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Avatar", ColumnDescription = "头像", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public virtual string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 签名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Signature", ColumnDescription = "签名", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public string Signature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账号
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Account", ColumnDescription = "账号", Length = 200, IsNullable = false)]
|
||||
public virtual string Account { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Password", ColumnDescription = "密码", Length = 200, IsNullable = false)]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 姓名
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Name", ColumnDescription = "姓名", Length = 200, IsNullable = true)]
|
||||
public virtual string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 昵称
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Nickname", ColumnDescription = "昵称", Length = 200, IsNullable = true)]
|
||||
public string Nickname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Gender", ColumnDescription = "性别", Length = 200, IsNullable = true)]
|
||||
public string Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 出生日期
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Birthday", ColumnDescription = "出生日期", Length = 200, IsNullable = true)]
|
||||
public string Birthday { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 民族
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Nation", ColumnDescription = "民族", Length = 200, IsNullable = true)]
|
||||
public string Nation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 籍贯
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "NativePlace", ColumnDescription = "籍贯", Length = 200, IsNullable = true)]
|
||||
public string NativePlace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 家庭住址
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "HomeAddress", ColumnDescription = "家庭住址", IsNullable = true)]
|
||||
public string HomeAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通信地址
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "MailingAddress", ColumnDescription = "通信地址", IsNullable = true)]
|
||||
public string MailingAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 证件类型
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "IdCardType", ColumnDescription = "证件类型", Length = 200, IsNullable = true)]
|
||||
public string IdCardType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 证件号码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "IdCardNumber", ColumnDescription = "证件号码", Length = 200, IsNullable = true)]
|
||||
public string IdCardNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文化程度
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "CultureLevel", ColumnDescription = "文化程度", Length = 200, IsNullable = true)]
|
||||
public string CultureLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 政治面貌
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "PoliticalOutlook", ColumnDescription = "政治面貌", Length = 200, IsNullable = true)]
|
||||
public string PoliticalOutlook { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 毕业院校
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "College", ColumnDescription = "毕业院校", Length = 200, IsNullable = true)]
|
||||
public string College { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 学历
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Education", ColumnDescription = "学历", Length = 200, IsNullable = true)]
|
||||
public string Education { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 学制
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EduLength", ColumnDescription = "学制", Length = 200, IsNullable = true)]
|
||||
public string EduLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 学位
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Degree", ColumnDescription = "学位", Length = 200, IsNullable = true)]
|
||||
public string Degree { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手机
|
||||
/// 这里使用了SM4自动加密解密
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Phone", ColumnDescription = "手机", Length = 200, IsNullable = true)]
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 邮箱
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "Email", ColumnDescription = "邮箱", Length = 200, IsNullable = true)]
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 家庭电话
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "HomeTel", ColumnDescription = "家庭电话", Length = 200, IsNullable = true)]
|
||||
public string HomeTel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 办公电话
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OfficeTel", ColumnDescription = "办公电话", Length = 200, IsNullable = true)]
|
||||
public string OfficeTel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 紧急联系人
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EmergencyContact", ColumnDescription = "紧急联系人", Length = 200, IsNullable = true)]
|
||||
public string EmergencyContact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 紧急联系人电话
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EmergencyPhone", ColumnDescription = "紧急联系人电话", Length = 200, IsNullable = true)]
|
||||
public string EmergencyPhone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 紧急联系人地址
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EmergencyAddress", ColumnDescription = "紧急联系人地址", IsNullable = true)]
|
||||
public string EmergencyAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 员工编号
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EmpNo", ColumnDescription = "员工编号", Length = 200, IsNullable = true)]
|
||||
public string EmpNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 入职日期
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "EntryDate", ColumnDescription = "入职日期", Length = 200, IsNullable = true)]
|
||||
public string EntryDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "OrgId", ColumnDescription = "机构id", IsNullable = false)]
|
||||
public virtual long OrgId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 职位id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "PositionId", ColumnDescription = "职位id", IsNullable = false)]
|
||||
public virtual long PositionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 职级
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "PositionLevel", ColumnDescription = "职级", Length = 200, IsNullable = true)]
|
||||
public string PositionLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主管id
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DirectorId", ColumnDescription = "主管id", IsNullable = true)]
|
||||
public long? DirectorId { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 上次修改密码时间
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "PwdRemindUpdateTime", ColumnDescription = "密码提醒修改时间", IsNullable = true)]
|
||||
public DateTime? PwdRemindUpdateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上次登录ip
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LastLoginIp", ColumnDescription = "上次登录ip", Length = 200, IsNullable = true)]
|
||||
public string LastLoginIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上次登录地点
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LastLoginAddress", ColumnDescription = "上次登录地点", Length = 200, IsNullable = true)]
|
||||
public string LastLoginAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上次登录时间
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LastLoginTime", ColumnDescription = "上次登录时间", IsNullable = true)]
|
||||
public DateTime? LastLoginTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上次登录设备
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LastLoginDevice", ColumnDescription = "上次登录设备", IsNullable = true)]
|
||||
public string LastLoginDevice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录ip
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LatestLoginIp", ColumnDescription = "最新登录ip", Length = 200, IsNullable = true)]
|
||||
public string LatestLoginIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录地点
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LatestLoginAddress", ColumnDescription = "最新登录地点", Length = 200, IsNullable = true)]
|
||||
public string LatestLoginAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录时间
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LatestLoginTime", ColumnDescription = "最新登录时间", IsNullable = true)]
|
||||
public DateTime? LatestLoginTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录设备
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "LatestLoginDevice", ColumnDescription = "最新登录设备", IsNullable = true)]
|
||||
public string LatestLoginDevice { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 排序码
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码", IsNullable = true)]
|
||||
public int? SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认模块
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "DefaultModule", ColumnDescription = "默认模块", IsNullable = true)]
|
||||
public long? DefaultModule { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构信息
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public string OrgName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构信息全称
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public string OrgNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 职位信息
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public string PositionName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 组织和机构ID列表,组织ID从上到下最后是职位
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true, IsJson = true)]
|
||||
public List<long> OrgAndPosIdList { get; set; } = new List<long>();
|
||||
|
||||
/// <summary>
|
||||
/// 主管信息
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public UserSelectorOutPut DirectorInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 按钮码集合
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<string> ButtonCodeList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 权限码集合
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<string> PermissionCodeList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色码集合
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<string> RoleCodeList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色ID集合
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<long> RoleIdList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据范围集合
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<DataScope> DataScopeList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认数据范围
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public DefaultDataScope DefaultDataScope { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构及以下机构ID集合
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<long> ScopeOrgChildList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构及以下机构ID集合
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<SysResource> ModuleList { get; set; } = new List<SysResource>();
|
||||
|
||||
/// <summary>
|
||||
/// 租户Id
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public long? TenantId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据范围类
|
||||
/// </summary>
|
||||
public class DataScope
|
||||
{
|
||||
/// <summary>
|
||||
/// API接口
|
||||
/// </summary>
|
||||
public string ApiUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据范围分类
|
||||
/// </summary>
|
||||
public string ScopeCategory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据范围的机构ID列表
|
||||
/// </summary>
|
||||
public List<long>? DataScopes { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 认证模块事件总线
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录事件
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
[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<IConfigService>();
|
||||
var messageService = scope.ServiceProvider.GetRequiredService<IMessageService>();
|
||||
var pwdRemindUpdateTime = sysUser.PwdRemindUpdateTime;//获取上次提醒修改密码时间
|
||||
var loginPolicy = await configService.GetConfigsByCategory(CateGoryConst.CONFIG_PWD_POLICY);//获取密码策略
|
||||
//获取用户token列表
|
||||
var tokenInfos = _simpleCacheService.HashGetOne<List<TokenInfo>>(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<long> { sysUser.Id },
|
||||
SendWay = SysDictConst.SEND_WAY_NOW,
|
||||
ReceiverType = SysDictConst.RECEIVER_TYPE_APPOINT,
|
||||
ReceiverInfo = new List<ReceiverInfo> { 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<ReceiverInfo> { 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登出事件
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
[EventSubscribe(EventSubscriberConst.LOGIN_OUT_B)]
|
||||
public async Task LoginOut(EventHandlerExecutingContext context)
|
||||
{
|
||||
_ = (LoginEvent)context.Source.Payload;//获取参数
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析IP地址
|
||||
/// </summary>
|
||||
/// <param name="ip">ip地址</param>
|
||||
/// <returns></returns>
|
||||
private string GetLoginAddress(string ip)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ipInfo = _searcher.Search(ip).Replace("0|", "");//解析ip并格式化
|
||||
return ipInfo;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "未知";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 事件总线常量
|
||||
/// </summary>
|
||||
public class EventSubscriberConst
|
||||
{
|
||||
#region AuthEventSubscriber
|
||||
|
||||
/// <summary>
|
||||
/// B端登录
|
||||
/// </summary>
|
||||
public const string LOGIN_B = "B端登录";
|
||||
|
||||
/// <summary>
|
||||
/// B端登录
|
||||
/// </summary>
|
||||
public const string LOGIN_OUT_B = "B端登出";
|
||||
|
||||
#endregion AuthEventSubscriber
|
||||
|
||||
#region UserEventSubscriber
|
||||
|
||||
/// <summary>
|
||||
/// 清除用户缓存
|
||||
/// </summary>
|
||||
public const string CLEAR_USER_CACHE = "清除用户缓存";
|
||||
|
||||
/// <summary>
|
||||
/// 清除组织下用户Token
|
||||
/// </summary>
|
||||
public const string CLEAR_ORG_TOKEN = "清除组织下用户Token";
|
||||
|
||||
/// <summary>
|
||||
/// 清除模块下用户Token
|
||||
/// </summary>
|
||||
public const string CLEAR_MODULE_TOKEN = "清除模块下用户Token";
|
||||
|
||||
#endregion UserEventSubscriber
|
||||
|
||||
#region NoticeEventSubscriber
|
||||
|
||||
/// <summary>
|
||||
/// 通知用户下线
|
||||
/// </summary>
|
||||
public const string USER_LOGIN_OUT = "通知用户下线";
|
||||
|
||||
/// <summary>
|
||||
/// 新消息
|
||||
/// </summary>
|
||||
public const string NEW_MESSAGE = "新消息";
|
||||
|
||||
#endregion NoticeEventSubscriber
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 登录事件参数
|
||||
/// </summary>
|
||||
public class LoginEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 请求上下文
|
||||
/// </summary>
|
||||
public ClientInfo ClientInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户信息
|
||||
/// </summary>
|
||||
public SysUser SysUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ip地址
|
||||
/// </summary>
|
||||
public string Ip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登录设备
|
||||
/// </summary>
|
||||
public AuthDeviceTypeEnum Device { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tokens
|
||||
/// </summary>
|
||||
public string Token { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 过期时间
|
||||
/// </summary>
|
||||
public int Expire { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时间
|
||||
/// </summary>
|
||||
public DateTime DateTime = DateTime.Now;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 用户登出事件
|
||||
/// </summary>
|
||||
public class UserLoginOutEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户Id
|
||||
/// </summary>
|
||||
public string UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// token信息
|
||||
/// </summary>
|
||||
|
||||
public List<TokenInfo> TokenInfos { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 内容
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新消息事件
|
||||
/// </summary>
|
||||
public class NewMessageEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息Id
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送方式
|
||||
/// </summary>
|
||||
public string SendWay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送时间
|
||||
/// </summary>
|
||||
public DateTime SendTime { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 通知事件总线
|
||||
/// </summary>
|
||||
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<SystemSettingsOptions> options)
|
||||
{
|
||||
_db = DbContext.DB;
|
||||
_simpleCacheService = simpleCacheService;
|
||||
_scopeFactory = scopeFactory;
|
||||
_useMessageCenter = options.CurrentValue.UseMessageCenter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通知用户下线事件
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
[EventSubscribe(EventSubscriberConst.USER_LOGIN_OUT)]
|
||||
public async Task UserLoginOut(EventHandlerExecutingContext context)
|
||||
{
|
||||
var loginEvent = (UserLoginOutEvent)context.Source.Payload;//获取参数
|
||||
//客户端ID列表
|
||||
var clientIds = new List<string>();
|
||||
//遍历token列表获取客户端ID列表
|
||||
loginEvent.TokenInfos.ForEach(it =>
|
||||
{
|
||||
clientIds.AddRange(it.ClientIds);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有新的消息
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
[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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
/// <param name="messageId">消息id</param>
|
||||
/// <param name="delay">延迟</param>
|
||||
private async Task SendMessage(long messageId, int delay = 0)
|
||||
{
|
||||
_simpleCacheService.AddDelayQueue(CacheConst.CACHE_NOTIFICATION, messageId, delay);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
private T GetService<T>() where T : class, new()
|
||||
{
|
||||
// 创建新的作用域
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
return scope.ServiceProvider.GetRequiredService<T>();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 用户模块事件总线
|
||||
/// </summary>
|
||||
public class UserEventSubscriber : IEventSubscriber, ISingleton
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly ISimpleCacheService _simpleCacheService;
|
||||
|
||||
|
||||
public UserEventSubscriber(IServiceProvider services, ISimpleCacheService simpleCacheService)
|
||||
{
|
||||
_services = services;
|
||||
_simpleCacheService = simpleCacheService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据角色ID列表清除用户缓存
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
[EventSubscribe(EventSubscriberConst.CLEAR_USER_CACHE)]
|
||||
public async Task DeleteUserCacheByRoleIds(EventHandlerExecutingContext context)
|
||||
{
|
||||
var roleIds = (List<long>)context.Source.Payload;//获取角色ID
|
||||
|
||||
// 创建新的作用域
|
||||
using var scope = _services.CreateScope();
|
||||
// 解析角色服务
|
||||
var relationService = scope.ServiceProvider.GetRequiredService<IRelationService>();
|
||||
//获取用户和角色关系
|
||||
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<ISysUserService>();
|
||||
//从redis中删除
|
||||
userService.DeleteUserFromRedis(userIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据机构ID列表清除用户token
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
[EventSubscribe(EventSubscriberConst.CLEAR_ORG_TOKEN)]
|
||||
public async Task DeleteUserTokenByOrgIds(EventHandlerExecutingContext context)
|
||||
{
|
||||
var orgIds = (List<long>)context.Source.Payload;//获取机构ID
|
||||
// 创建新的作用域
|
||||
using var scope = _services.CreateScope();
|
||||
// 获取用户ID列表
|
||||
var userIds = await DbContext.DB.QueryableWithAttr<SysUser>().Where(it => orgIds.Contains(it.OrgId)).Select(it => it.Id).ToListAsync();
|
||||
//从redis中删除所属机构的用户token
|
||||
_simpleCacheService.HashDel<List<Token>>(CacheConst.CACHE_USER_TOKEN, userIds.Select(it => it.ToString()).ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据模块ID列表清除用户token
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
[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<IRelationService>();
|
||||
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<ISysUserService>();
|
||||
if (userIds.Count > 0)
|
||||
{
|
||||
//从redis中删除用户信息
|
||||
userService.DeleteUserFromRedis(userIds);
|
||||
//从redis中删除用户token
|
||||
_simpleCacheService.HashDel<List<Token>>(CacheConst.CACHE_USER_TOKEN, userIds.Select(it => it.ToString()).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 站内信与接收用户拓展
|
||||
/// MSG_TO_USER
|
||||
/// </summary>
|
||||
public class RelationMsgUser
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否已读
|
||||
/// </summary>
|
||||
public bool Read { get; set; } = false;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// SYS_ROLE_HAS_PERMISSION
|
||||
/// 角色权限关系扩展
|
||||
/// </summary>
|
||||
public class RelationRolePermission
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据范围
|
||||
/// </summary>
|
||||
public string ScopeCategory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义机构范围列表
|
||||
/// </summary>
|
||||
public List<long> ScopeDefineOrgIdList { get; set; } = new List<long>();
|
||||
|
||||
/// <summary>
|
||||
/// 接口Url
|
||||
/// </summary>
|
||||
public string ApiUrl { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// SYS_ROLE_HAS_RESOURCE
|
||||
/// 角色有哪些资源扩展
|
||||
/// </summary>
|
||||
public class RelationRoleResource
|
||||
{
|
||||
/// <summary>
|
||||
/// 菜单ID
|
||||
/// </summary>
|
||||
public long MenuId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 按钮信息
|
||||
/// </summary>
|
||||
public List<long> ButtonInfo { get; set; } = new List<long>();
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// SYS_USER_SCHEDULE_DATA
|
||||
/// 用户日程扩展
|
||||
/// </summary>
|
||||
public class RelationUserSchedule
|
||||
{
|
||||
/// <summary>
|
||||
/// 日程日期
|
||||
/// </summary>
|
||||
public virtual string ScheduleDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 日程时间
|
||||
/// </summary>
|
||||
public virtual string ScheduleTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 日程内容
|
||||
/// </summary>
|
||||
public virtual string ScheduleContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户id
|
||||
/// </summary>
|
||||
public long ScheduleUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户姓名
|
||||
/// </summary>
|
||||
public string ScheduleUserName { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// SYS_USER_WORKBENCH_DATA
|
||||
/// 用户工作台扩展
|
||||
/// </summary>
|
||||
public class RelationUserWorkBench
|
||||
{
|
||||
/// <summary>
|
||||
/// 快捷方式列表
|
||||
/// </summary>
|
||||
public List<WorkBenchShortcut> Shortcut { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 工作台快捷方式信息
|
||||
/// </summary>
|
||||
public class WorkBenchShortcut
|
||||
{
|
||||
/// <summary>
|
||||
/// id
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标题
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 图标
|
||||
/// </summary>
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 路由地址
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 对象映射
|
||||
/// </summary>
|
||||
public class Mapper : IRegister
|
||||
{
|
||||
public void Register(TypeAdapterConfig config)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 系统配置
|
||||
/// </summary>
|
||||
public class SystemSettingsOptions : BaseOptions, IConfigurableOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 超级管理员可以看到全部数据
|
||||
/// </summary>
|
||||
public bool SuperAdminViewAllData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 启用通知中心
|
||||
/// </summary>
|
||||
public bool UseMessageCenter { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Minio功能类
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化操作
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传文件 - 返回Minio文件完整Url
|
||||
/// </summary>
|
||||
/// <param name="objectName">存储桶里的对象名称,例:/mnt/photos/island.jpg</param>
|
||||
/// <param name="file">文件</param>
|
||||
/// <param name="contentType">文件的Content type,默认是"application/octet-stream"</param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> 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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载文件
|
||||
/// </summary>
|
||||
/// <param name="objectName"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<MemoryStream> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
/// 系统配置种子数据
|
||||
/// </summary>
|
||||
public class GenBaseSeedData : ISqlSugarEntitySeedData<GenBasic>
|
||||
{
|
||||
public IEnumerable<GenBasic> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<GenBasic>("seed_gen_basic.json");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
/// 系统配置种子数据
|
||||
/// </summary>
|
||||
public class GenConfigSeedData : ISqlSugarEntitySeedData<GenConfig>
|
||||
{
|
||||
public IEnumerable<GenConfig> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<GenConfig>("seed_gen_config.json");
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -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]"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 系统配置种子数据
|
||||
/// </summary>
|
||||
public class SysConfigSeedData : ISqlSugarEntitySeedData<SysConfig>
|
||||
{
|
||||
public IEnumerable<SysConfig> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<SysConfig>("seed_sys_config.json");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 字典表种子数据
|
||||
/// </summary>
|
||||
public class SysDictSeedData : ISqlSugarEntitySeedData<SysDict>
|
||||
{
|
||||
public IEnumerable<SysDict> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<SysDict>("seed_sys_dict.json");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 机构种子数据
|
||||
/// </summary>
|
||||
public class SysOrgSeedData : ISqlSugarEntitySeedData<SysOrg>
|
||||
{
|
||||
public IEnumerable<SysOrg> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<SysOrg>("seed_sys_org.json");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 职位表种子数据
|
||||
/// </summary>
|
||||
public class SysPositionSeedData : ISqlSugarEntitySeedData<SysPosition>
|
||||
{
|
||||
public IEnumerable<SysPosition> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<SysPosition>("seed_sys_position.json");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 关系表种子数据
|
||||
/// </summary>
|
||||
public class SysRelationSeedData : ISqlSugarEntitySeedData<SysRelation>
|
||||
{
|
||||
public IEnumerable<SysRelation> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<SysRelation>("seed_sys_relation.json");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 资源表种子数据
|
||||
/// </summary>
|
||||
public class SysResourceSeedData : ISqlSugarEntitySeedData<SysResource>
|
||||
{
|
||||
public IEnumerable<SysResource> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<SysResource>("seed_sys_resource.json");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 角色种子数据
|
||||
/// </summary>
|
||||
public class SysRoleSeedData : ISqlSugarEntitySeedData<SysRole>
|
||||
{
|
||||
public IEnumerable<SysRole> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<SysRole>("seed_sys_role.json");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 用户表种子数据
|
||||
/// </summary>
|
||||
public class SysUserSeedData : ISqlSugarEntitySeedData<SysUser>
|
||||
{
|
||||
public IEnumerable<SysUser> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<SysUser>("seed_sys_user.json");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <inheritdoc cref="IAuthService"/>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<PicValidCodeOutPut> 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
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<string> 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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<LoginOutPut> 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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<LoginOutPut> 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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<LoginUserOutput> GetLoginUser()
|
||||
{
|
||||
var userInfo = await _userService.GetUserByAccount(UserManager.UserAccount, UserManager.TenantId);//根据账号获取用户信息
|
||||
if (userInfo != null)
|
||||
{
|
||||
userInfo.Avatar = await _userService.GetUserAvatar(userInfo.Id);//获取头像
|
||||
return userInfo.Adapt<LoginUserOutput>();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#region 方法
|
||||
|
||||
/// <summary>
|
||||
/// 检查验证码
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <exception cref="AppFriendlyException"></exception>
|
||||
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);//校验验证码
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查网站是否开启
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <exception cref="AppFriendlyException"></exception>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录之前执行的方法
|
||||
/// </summary>
|
||||
/// <param name="loginPolicy"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="isTenant"></param>
|
||||
public async Task BeforeLogin(List<SysConfig> 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<int>(key);//获取登录错误次数
|
||||
if (errorCountCache >= errorCount)
|
||||
{
|
||||
_simpleCacheService.SetExpire(key, TimeSpan.FromMinutes(lockTime));//设置缓存
|
||||
throw Oops.Bah($"密码错误次数过多,请{lockTime}分钟后再试");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录错误操作
|
||||
/// </summary>
|
||||
/// <param name="loginPolicy"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="isTenant"></param>
|
||||
public void LoginError(List<SysConfig> 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));//设置过期时间
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验验证码方法
|
||||
/// </summary>
|
||||
/// <param name="validCode">验证码</param>
|
||||
/// <param name="validCodeReqNo">请求号</param>
|
||||
/// <param name="isDelete">是否从Redis删除</param>
|
||||
public void ValidValidCode(string validCode, string validCodeReqNo, bool isDelete = true)
|
||||
{
|
||||
var key = SystemConst.CACHE_CAPTCHA + validCodeReqNo;//获取验证码Key值
|
||||
var code = _simpleCacheService.Get<string>(key);//从缓存拿数据
|
||||
if (isDelete) RemoveValidCodeFromRedis(validCodeReqNo);//如果需要删除验证码
|
||||
if (code != null && validCode != null)//如果有
|
||||
{
|
||||
//验证码如果不匹配直接抛错误,这里忽略大小写
|
||||
if (validCode.ToLower() != code.ToLower()) throw Oops.Bah("验证码错误");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Oops.Bah("验证码不能为空");//抛出验证码不能为空
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从Redis中删除验证码
|
||||
/// </summary>
|
||||
/// <param name="validCodeReqNo"></param>
|
||||
public void RemoveValidCodeFromRedis(string validCodeReqNo)
|
||||
{
|
||||
var key = SystemConst.CACHE_CAPTCHA + validCodeReqNo;//获取验证码Key值
|
||||
_simpleCacheService.Remove(key);//删除验证码
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验手机验证码
|
||||
/// </summary>
|
||||
/// <param name="input">输入参数</param>
|
||||
/// <param name="loginClientType">登录端类型</param>
|
||||
/// <param name="isDelete">是否删除</param>
|
||||
/// <returns></returns>
|
||||
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("手机号不存在");//手机号不存在
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加验证码到缓存
|
||||
/// </summary>
|
||||
/// <param name="code">验证码</param>
|
||||
/// <param name="expire">过期时间</param>
|
||||
/// <returns>验证码请求号</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行B端登录
|
||||
/// </summary>
|
||||
/// <param name="sysUser">用户信息</param>
|
||||
/// <param name="device">登录设备</param>
|
||||
/// <param name="loginClientType">登录类型</param>
|
||||
/// <param name="tenantId">租户id</param>
|
||||
/// <returns></returns>
|
||||
public async Task<LoginOutPut> 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<string, object>
|
||||
{
|
||||
{
|
||||
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<int>("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
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入用户token到缓存
|
||||
/// </summary>
|
||||
/// <param name="loginEvent">登录事件参数</param>
|
||||
/// <param name="loginClientType">登录类型</param>
|
||||
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>
|
||||
{
|
||||
tokenInfo
|
||||
};//直接就一个
|
||||
}
|
||||
|
||||
//添加到token列表
|
||||
_simpleCacheService.HashAdd(CacheConst.CACHE_USER_TOKEN, loginEvent.SysUser.Id.ToString(), tokenInfos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缓存删除用户token
|
||||
/// </summary>
|
||||
/// <param name="loginEvent">登录事件参数</param>
|
||||
/// <param name="loginClientType">登录类型</param>
|
||||
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<List<TokenInfo>>(CacheConst.CACHE_USER_TOKEN, loginEvent.SysUser.Id.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户token列表
|
||||
/// </summary>
|
||||
/// <param name="userId">用户ID</param>
|
||||
/// <returns>token列表</returns>
|
||||
private List<TokenInfo> GetTokenInfos(long userId)
|
||||
{
|
||||
//缓存获取用户token列表
|
||||
var tokenInfos = _simpleCacheService.HashGetOne<List<TokenInfo>>(CacheConst.CACHE_USER_TOKEN, userId.ToString());
|
||||
if (tokenInfos != null)
|
||||
{
|
||||
tokenInfos = tokenInfos.Where(it => it.TokenTimeout > DateTime.Now).ToList();//去掉登录超时的
|
||||
}
|
||||
return tokenInfos;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单用户登录通知用户下线
|
||||
/// </summary>
|
||||
/// <param name="userId">用户ID</param>
|
||||
/// <param name="tokenInfos">Token列表</param>
|
||||
private async Task SingleLogin(string userId, List<TokenInfo> tokenInfos)
|
||||
{
|
||||
await _eventPublisher.PublishAsync(EventSubscriberConst.USER_LOGIN_OUT, new UserLoginOutEvent
|
||||
{
|
||||
Message = "您的账号已在别处登录!",
|
||||
TokenInfos = tokenInfos,
|
||||
UserId = userId
|
||||
});//通知用户下线
|
||||
}
|
||||
|
||||
#endregion 方法
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 权限认证输入
|
||||
/// </summary>
|
||||
public class AuthInput
|
||||
{
|
||||
}
|
||||
|
||||
public class ValidCodeInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证码
|
||||
/// </summary>
|
||||
public string ValidCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求号
|
||||
/// </summary>
|
||||
public string ValidCodeReqNo { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录输入参数
|
||||
/// </summary>
|
||||
public class LoginInput : ValidCodeInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 账号
|
||||
///</summary>
|
||||
/// <example>superAdmin</example>
|
||||
[Required(ErrorMessage = "账号不能为空")]
|
||||
public string Account { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码
|
||||
///</summary>
|
||||
///<example>04fc514b346f14b23d7cf5e6f64663b030512aa380a9e7d311288ed1e8be7b863ae5ee0bb570df2405fc9daff2b2d1ac627a0fbbd49ef2c6b8fac4fd5e4b9a1b7120999bdc0a8e425aa37abab3aec6f9f3570775ff901f2845e957b0c2d0542e21fbf1bbb65c04</example>
|
||||
[Required(ErrorMessage = "密码不能为空")]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备类型,默认PC
|
||||
/// </summary>
|
||||
/// <example>0</example>
|
||||
public AuthDeviceTypeEnum Device { get; set; } = AuthDeviceTypeEnum.PC;
|
||||
|
||||
/// <summary>
|
||||
/// 租户ID
|
||||
/// </summary>
|
||||
public long? TenantId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登出输入参数
|
||||
/// </summary>
|
||||
public class LoginOutInput
|
||||
{
|
||||
/// <summary>
|
||||
/// token
|
||||
/// </summary>
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取短信验证码输入
|
||||
/// </summary>
|
||||
public class GetPhoneValidCodeInput : ValidCodeInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "手机号不能为空")]
|
||||
[Phone(ErrorMessage = "手机号格式不对")]
|
||||
public string Phone { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 手机号登录输入
|
||||
/// </summary>
|
||||
public class LoginByPhoneInput : GetPhoneValidCodeInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备类型,默认PC
|
||||
/// </summary>
|
||||
/// <example>0</example>
|
||||
public AuthDeviceTypeEnum Device { get; set; } = AuthDeviceTypeEnum.PC;
|
||||
|
||||
/// <summary>
|
||||
/// 租户ID
|
||||
/// </summary>
|
||||
public long? TenantId { get; set; }
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证码返回
|
||||
/// </summary>
|
||||
public class PicValidCodeOutPut
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证码图片,Base64
|
||||
/// </summary>
|
||||
public string ValidCodeBase64 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证码请求号
|
||||
/// </summary>
|
||||
public string ValidCodeReqNo { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录返回参数
|
||||
/// </summary>
|
||||
public class LoginOutPut
|
||||
{
|
||||
/// <summary>
|
||||
/// 令牌Token
|
||||
/// </summary>
|
||||
public string Token { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账号
|
||||
/// </summary>
|
||||
public string Account { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 姓名
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认模块
|
||||
/// </summary>
|
||||
public long? DefaultModule { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模块列表
|
||||
/// </summary>
|
||||
public List<SysResource> ModuleList { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录用互信息
|
||||
/// </summary>
|
||||
public class LoginUserOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 头像
|
||||
///</summary>
|
||||
public string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 签名
|
||||
///</summary>
|
||||
public string Signature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账号
|
||||
///</summary>
|
||||
public string Account { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 姓名
|
||||
///</summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 昵称
|
||||
///</summary>
|
||||
public string Nickname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生日
|
||||
/// </summary>
|
||||
public string Birthday { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 邮箱
|
||||
/// </summary>
|
||||
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
///</summary>
|
||||
public string Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 家庭住址
|
||||
///</summary>
|
||||
public string HomeAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构信息
|
||||
/// </summary>
|
||||
public string OrgName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构信息全称
|
||||
/// </summary>
|
||||
public string OrgNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 职位信息
|
||||
/// </summary>
|
||||
public string PositionName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色码集合
|
||||
/// </summary>
|
||||
public List<string> RoleCodeList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 按钮码集合
|
||||
/// </summary>
|
||||
public List<string> ButtonCodeList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构及以下机构ID集合
|
||||
/// </summary>
|
||||
public List<SysResource> ModuleList { get; set; } = new List<SysResource>();
|
||||
|
||||
/// <summary>
|
||||
/// 默认模块
|
||||
///</summary>
|
||||
public long? DefaultModule { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 权限校验服务
|
||||
/// </summary>
|
||||
public interface IAuthService : ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取图形验证码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<PicValidCodeOutPut> GetCaptchaInfo();
|
||||
|
||||
/// <summary>
|
||||
/// 获取登录用户信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<LoginUserOutput> GetLoginUser();
|
||||
|
||||
/// <summary>
|
||||
/// 获取手机短信验证码
|
||||
/// </summary>
|
||||
/// <param name="input">验证码参数</param>
|
||||
/// <param name="loginClientType">登录类型</param>
|
||||
/// <returns></returns>
|
||||
Task<string> GetPhoneValidCode(GetPhoneValidCodeInput input, LoginClientTypeEnum loginClientType);
|
||||
|
||||
/// <summary>
|
||||
/// 登录
|
||||
/// </summary>
|
||||
/// <param name="input">登录参数</param>
|
||||
/// <param name="loginClientType">登录类型</param>
|
||||
/// <returns>Token信息</returns>
|
||||
Task<LoginOutPut> Login(LoginInput input, LoginClientTypeEnum loginClientType);
|
||||
|
||||
/// <summary>
|
||||
/// 手机号登录
|
||||
/// </summary>
|
||||
/// <param name="input">登录参数</param>
|
||||
/// <param name="loginClientType">登录端类型</param>
|
||||
/// <returns>Token信息</returns>
|
||||
Task<LoginOutPut> LoginByPhone(LoginByPhoneInput input, LoginClientTypeEnum loginClientType);
|
||||
|
||||
/// <summary>
|
||||
/// 退出登录
|
||||
/// </summary>
|
||||
/// <param name="token">token</param>
|
||||
/// <param name="loginClientType">登出类型</param>
|
||||
/// <returns></returns>
|
||||
Task LoginOut(string token, LoginClientTypeEnum loginClientType);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 会话分页查询
|
||||
/// </summary>
|
||||
public class SessionPageInput : BasePageInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 账号
|
||||
///</summary>
|
||||
public virtual string Account { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 姓名
|
||||
///</summary>
|
||||
|
||||
public virtual string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录ip
|
||||
///</summary>
|
||||
public string LatestLoginIp { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Token退出参数
|
||||
/// </summary>
|
||||
public class ExitTokenInput : BaseIdInput
|
||||
{
|
||||
/// <summary>
|
||||
/// token
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "Tokens不能为空")]
|
||||
public List<string> Tokens { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 会话输出
|
||||
/// </summary>
|
||||
public class SessionOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键Id
|
||||
/// </summary>
|
||||
public virtual long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像
|
||||
///</summary>
|
||||
public string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账号
|
||||
///</summary>
|
||||
public virtual string Account { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 姓名
|
||||
///</summary>
|
||||
|
||||
public virtual string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 在线状态
|
||||
/// </summary>
|
||||
public string OnlineStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录ip
|
||||
///</summary>
|
||||
public string LatestLoginIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录地点
|
||||
///</summary>
|
||||
public string LatestLoginAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录时间
|
||||
///</summary>
|
||||
public DateTime? LatestLoginTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 令牌数量
|
||||
/// </summary>
|
||||
public int TokenCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 令牌信息集合
|
||||
/// </summary>
|
||||
public List<TokenInfo> TokenSignList { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 会话统计结果
|
||||
/// </summary>
|
||||
public class SessionAnalysisOutPut
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前会话总数量
|
||||
/// </summary>
|
||||
public int CurrentSessionTotalCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大签发令牌数
|
||||
/// </summary>
|
||||
public int MaxTokenCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 在线用户数
|
||||
/// </summary>
|
||||
public int OnLineCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// BC端会话比例
|
||||
/// </summary>
|
||||
public string ProportionOfBAndC { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 会话管理服务
|
||||
/// </summary>
|
||||
public interface ISessionService : ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 会话统计
|
||||
/// </summary>
|
||||
/// <returns>统计结果</returns>
|
||||
SessionAnalysisOutPut Analysis();
|
||||
|
||||
/// <summary>
|
||||
/// 强退会话
|
||||
/// </summary>
|
||||
/// <param name="input">用户ID</param>
|
||||
Task ExitSession(BaseIdInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 强退token
|
||||
/// </summary>
|
||||
/// <param name="input">token列表</param>
|
||||
Task ExitToken(ExitTokenInput input);
|
||||
|
||||
/// <summary>
|
||||
/// B端会话分页查询
|
||||
/// </summary>
|
||||
/// <param name="input">查询参数</param>
|
||||
/// <returns>B端会话列表</returns>
|
||||
Task<SqlSugarPagedList<SessionOutput>> PageB(SessionPageInput input);
|
||||
|
||||
/// <summary>
|
||||
/// C端会话分页查询
|
||||
/// </summary>
|
||||
/// <param name="input">查询参数</param>
|
||||
/// <returns>C端会话列表</returns>
|
||||
Task<SqlSugarPagedList<SessionOutput>> PageC(SessionPageInput input);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="ISessionService"/>
|
||||
/// </summary>
|
||||
public class SessionService : DbRepository<SysUser>, ISessionService
|
||||
{
|
||||
private readonly ISimpleCacheService _simpleCacheService;
|
||||
private readonly IEventPublisher _eventPublisher;
|
||||
|
||||
public SessionService(ISimpleCacheService simpleCacheService, IEventPublisher eventPublisher)
|
||||
{
|
||||
_simpleCacheService = simpleCacheService;
|
||||
_eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<SqlSugarPagedList<SessionOutput>> PageB(SessionPageInput input)
|
||||
{
|
||||
//获取b端token列表
|
||||
var bTokenInfoDic = GetTokenDicFromRedis();
|
||||
|
||||
//获取用户ID列表
|
||||
var userIds = bTokenInfoDic.Keys.Select(it => it.ToLong()).ToList();
|
||||
var query = Context.Queryable<SysUser>().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<SessionOutput>().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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<SqlSugarPagedList<SessionOutput>> PageC(SessionPageInput input)
|
||||
{
|
||||
return new SqlSugarPagedList<SessionOutput> { PageNum = 1, PageSize = 20, Total = 0, Pages = 1, HasNextPages = false };
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SessionAnalysisOutPut Analysis()
|
||||
{
|
||||
var tokenDic = GetTokenDicFromRedis();//redisToken会话字典信息
|
||||
var tokenInfosList = tokenDic.Values.ToList();//端token列表
|
||||
var dicB = new Dictionary<string, List<TokenInfo>>();
|
||||
var dicC = new Dictionary<string, List<TokenInfo>>();
|
||||
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}"
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task ExitSession(BaseIdInput input)
|
||||
{
|
||||
var userId = input.Id.ToString();
|
||||
//token列表
|
||||
var tokenInfos = _simpleCacheService.HashGetOne<List<TokenInfo>>(CacheConst.CACHE_USER_TOKEN, userId);
|
||||
//从列表中删除
|
||||
_simpleCacheService.HashDel<List<TokenInfo>>(CacheConst.CACHE_USER_TOKEN, userId);
|
||||
await NoticeUserLoginOut(userId, tokenInfos);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task ExitToken(ExitTokenInput input)
|
||||
{
|
||||
var userId = input.Id.ToString();
|
||||
//获取该用户的token信息
|
||||
var tokenInfos = _simpleCacheService.HashGetOne<List<TokenInfo>>(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<List<TokenInfo>>(CacheConst.CACHE_USER_TOKEN, userId);//否则直接删除key
|
||||
await NoticeUserLoginOut(userId, deleteTokens);
|
||||
}
|
||||
|
||||
#region 方法
|
||||
|
||||
/// <summary>
|
||||
/// 获取redis中token信息列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Dictionary<string, List<TokenInfo>> GetTokenDicFromRedis()
|
||||
{
|
||||
var clockSkew = App.GetConfig<int>("JWTSettings:ClockSkew");//获取过期时间容错值(秒)
|
||||
//redis获取token信息hash集合,并转成字典
|
||||
var bTokenDic = _simpleCacheService.HashGetAll<List<TokenInfo>>(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<string, List<TokenInfo>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取token剩余时间信息
|
||||
/// </summary>
|
||||
/// <param name="tokenInfos">token列表</param>
|
||||
/// <param name="loginClientType">登录类型</param>
|
||||
public void GetTokenInfos(ref List<TokenInfo> 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;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通知用户下线
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task NoticeUserLoginOut(string userId, List<TokenInfo> tokenInfos)
|
||||
{
|
||||
await _eventPublisher.PublishAsync(EventSubscriberConst.USER_LOGIN_OUT, new UserLoginOutEvent
|
||||
{
|
||||
Message = "您已被强制下线!",
|
||||
TokenInfos = tokenInfos,
|
||||
UserId = userId
|
||||
});//通知用户下线
|
||||
}
|
||||
|
||||
#endregion 方法
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="IBatchEditService"/>
|
||||
/// </summary>
|
||||
public class BatchEditService : DbRepository<BatchEdit>, IBatchEditService
|
||||
{
|
||||
private readonly ILogger<BatchEditService> _logger;
|
||||
|
||||
public BatchEditService(ILogger<BatchEditService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<SqlSugarPagedList<BatchEdit>> Page(BatchEditPageInput input)
|
||||
{
|
||||
var query = Context.Queryable<BatchEdit>()
|
||||
.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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task Add(BatchEditAddInput input)
|
||||
{
|
||||
var entity = input.Adapt<BatchEdit>();//实体转换
|
||||
await CheckInput(entity);//检查参数
|
||||
var tableColumns = SqlSugarUtils.GetTableColumns(input.ConfigId, input.TableName);//获取表的字段信息
|
||||
var batchEdiConfig = new List<BatchEditConfig>();//代码生成配置字段集合
|
||||
|
||||
//遍历字段
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task Config(List<BatchEditConfigInput> input)
|
||||
{
|
||||
var updateBatch = input.Adapt<List<BatchEditConfig>>();//实体转换
|
||||
var configRep = ChangeRepository<DbRepository<BatchEditConfig>>();
|
||||
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();//更新数据
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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<object>().ToArray());//删除数据
|
||||
await Context.Deleteable<BatchEditConfig>().Where(it => ids.Contains(it.UId)).ExecuteCommandAsync();
|
||||
});
|
||||
if (!result.IsSuccess)//如果失败了
|
||||
{
|
||||
//写日志
|
||||
_logger.LogError(result.ErrorMessage, result.ErrorException);
|
||||
throw Oops.Oh(ErrorCodeEnum.A0003);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task SyncColumns(BaseIdInput input)
|
||||
{
|
||||
var config = await GetFirstAsync(it => it.Id == input.Id);
|
||||
if (config != null)
|
||||
{
|
||||
var newColumns = new List<BatchEditConfig>();
|
||||
//获取表的字段信息
|
||||
var tableColumns = SqlSugarUtils.GetTableColumns(config.ConfigId, config.TableName);
|
||||
//找到当前配置字段列表
|
||||
var batchEdiConfig = await Context.Queryable<BatchEditConfig>().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();//插入新的字段数据
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<BatchEditConfig>> Columns(string code)
|
||||
{
|
||||
var batchEdiConfig = new List<BatchEditConfig>();
|
||||
var updateBatch = await GetFirstAsync(it => it.Code == code);//根据code获取配置
|
||||
if (updateBatch != null)
|
||||
{
|
||||
//找到对应字段
|
||||
batchEdiConfig = await Context.Queryable<BatchEditConfig>().Where(it => it.UId == updateBatch.Id && it.Status == CommonStatusConst.ENABLE)
|
||||
.ToListAsync();
|
||||
}
|
||||
return batchEdiConfig;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public List<SqlSugarTableInfo> GetTables()
|
||||
{
|
||||
return SqlSugarUtils.GetTablesByAttribute<BatchEditAttribute>();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<BatchEditConfig>> ConfigList(BaseIdInput input)
|
||||
{
|
||||
return await Context.Queryable<BatchEditConfig>().Where(u => u.UId == input.Id).OrderByDescending(it => it.Status).ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<Dictionary<string, object>> GetUpdateBatchConfigDict(string code, List<BatchEditColumn> columns)
|
||||
{
|
||||
var dic = new Dictionary<string, object>();
|
||||
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 方法
|
||||
|
||||
/// <summary>
|
||||
/// 获取配置
|
||||
/// </summary>
|
||||
/// <param name="columnInfo"></param>
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查输入参数
|
||||
/// </summary>
|
||||
/// <param name="updateBatch"></param>
|
||||
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 方法
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 批量分页查询参数
|
||||
/// </summary>
|
||||
public class BatchEditPageInput : BasePageInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 唯一编码
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属库
|
||||
/// </summary>
|
||||
public string ConfigId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实体名
|
||||
/// </summary>
|
||||
public string EntityName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表名
|
||||
/// </summary>
|
||||
public string TableName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加批量参数
|
||||
/// </summary>
|
||||
public class BatchEditAddInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 唯一编码
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "Code必填")]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属库
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "ConfigId必填")]
|
||||
public string ConfigId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实体名
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "EntityName必填")]
|
||||
public string EntityName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表名
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "TableName必填")]
|
||||
public string TableName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表描述
|
||||
/// </summary>
|
||||
public string TableDescription { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改批量参数
|
||||
/// </summary>
|
||||
public class BatchEditConfigInput : BatchEditConfig, IValidatableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
[IdNotNull(ErrorMessage = "Id不能为空")]
|
||||
public override long Id { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> 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) });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量修改输入
|
||||
/// </summary>
|
||||
public class BatchEditInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 批量编辑Code
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "Code不能为空")]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id列表
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "Ids不能为空")]
|
||||
public List<long>? Ids { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字段列表
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "Columns不能为空")]
|
||||
public List<BatchEditColumn>? Columns { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量修改DTO
|
||||
/// </summary>
|
||||
public class BatchEditColumn
|
||||
{
|
||||
[Required(ErrorMessage = "字段名必填")]
|
||||
public string TableColumn { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "字段值必填")]
|
||||
public object ColumnValue { get; set; }
|
||||
}
|
||||
@@ -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.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 批量服务
|
||||
/// </summary>
|
||||
public interface IBatchEditService : ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 批量分页查询
|
||||
/// </summary>
|
||||
/// <param name="input">查询参数</param>
|
||||
/// <returns>分页结果</returns>
|
||||
Task<SqlSugarPagedList<BatchEdit>> Page(BatchEditPageInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 添加批量
|
||||
/// </summary>
|
||||
/// <param name="input">添加参数</param>
|
||||
/// <returns></returns>
|
||||
Task Add(BatchEditAddInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 删除批量
|
||||
/// </summary>
|
||||
/// <param name="input">删除参数</param>
|
||||
/// <returns></returns>
|
||||
Task Delete(BaseIdListInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 获取需要批量修改的表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<SqlSugarTableInfo> GetTables();
|
||||
|
||||
/// <summary>
|
||||
/// 获取批量修改配置
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<BatchEditConfig>> ConfigList(BaseIdInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 配置字段
|
||||
/// </summary>
|
||||
/// <param name="input">字段信息</param>
|
||||
/// <returns></returns>
|
||||
Task Config(List<BatchEditConfigInput> input);
|
||||
|
||||
/// <summary>
|
||||
/// 批量配置字段列表
|
||||
/// </summary>
|
||||
/// <param name="code">唯一编码</param>
|
||||
/// <returns>列表</returns>
|
||||
Task<List<BatchEditConfig>> Columns(string code);
|
||||
|
||||
/// <summary>
|
||||
/// 获取字典配置
|
||||
/// </summary>
|
||||
/// <param name="code">唯一编码</param>
|
||||
/// <param name="columns">字段信息</param>
|
||||
/// <returns>SqlSugar对应字典</returns>
|
||||
Task<Dictionary<string, object>> GetUpdateBatchConfigDict(string code, List<BatchEditColumn> columns);
|
||||
|
||||
/// <summary>
|
||||
/// 同步字段
|
||||
/// </summary>
|
||||
/// <param name="input">id</param>
|
||||
/// <returns></returns>
|
||||
Task SyncColumns(BaseIdInput input);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 文件分页输出
|
||||
/// </summary>
|
||||
public class FilePageInput : BasePageInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件引擎
|
||||
/// </summary>
|
||||
public string Engine { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="IFileService"/>
|
||||
/// </summary>
|
||||
public class FileService : DbRepository<SysFile>, IFileService
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
|
||||
public FileService(IConfigService configService)
|
||||
{
|
||||
_configService = configService;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<SqlSugarPagedList<SysFile>> Page(FilePageInput input)
|
||||
{
|
||||
var query = Context.Queryable<SysFile>().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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<long> UploadFile(string engine, IFormFile file)
|
||||
{
|
||||
return await StorageFile(engine, file);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task Delete(BaseIdListInput input)
|
||||
{
|
||||
var ids = input.Ids;//获取ID
|
||||
await DeleteByIdsAsync(ids.Cast<object>().ToArray());//根据ID删除数据库
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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<FileStreamResult> GetFileStreamResultFromMinio(string objectName, string fileName)
|
||||
{
|
||||
var minioService = App.GetService<MinioUtils>();
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<FileStreamResult> 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 方法
|
||||
|
||||
/// <summary>
|
||||
/// 存储文件
|
||||
/// </summary>
|
||||
/// <param name="engine"></param>
|
||||
/// <param name="file"></param>
|
||||
private async Task<long> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 存储本地文件
|
||||
/// </summary>
|
||||
/// <param name="fileId"></param>
|
||||
/// <param name="file"></param>
|
||||
private async Task<string> 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("文件存储路径未配置");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 存储到minio
|
||||
/// </summary>
|
||||
/// <param name="fileId"></param>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<(string objName, string downloadUrl)> StorageMinio(long fileId, IFormFile file)
|
||||
{
|
||||
var minioService = App.GetService<MinioUtils>();
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件大小
|
||||
/// </summary>
|
||||
/// <param name="fileSizeKb"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否是图片
|
||||
/// </summary>
|
||||
/// <param name="suffix">后缀名</param>
|
||||
/// <returns></returns>
|
||||
private bool IsPic(string suffix)
|
||||
{
|
||||
//图片后缀名列表
|
||||
var pics = new[]
|
||||
{
|
||||
".png", ".bmp", ".gif", ".jpg", ".jpeg", ".psd"
|
||||
};
|
||||
if (pics.Contains(suffix))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion 方法
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 文件管理服务
|
||||
/// </summary>
|
||||
public interface IFileService : ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 删除文件
|
||||
/// </summary>
|
||||
/// <param name="input">ID列表</param>
|
||||
/// <returns></returns>
|
||||
Task Delete(BaseIdListInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 文件下载
|
||||
/// </summary>
|
||||
/// <param name="input">文件iD</param>
|
||||
/// <returns>文件流</returns>
|
||||
Task<FileStreamResult> Download(BaseIdInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 获取FileStreamResult文件流
|
||||
/// </summary>
|
||||
/// <param name="path">路径</param>
|
||||
/// <param name="fileName">文件名</param>
|
||||
/// <param name="isPathFolder">路径是否是文件夹</param>
|
||||
/// <returns></returns>
|
||||
FileStreamResult GetFileStreamResult(string path, string fileName, bool isPathFolder = false);
|
||||
|
||||
/// <summary>
|
||||
/// 获取FileStreamResult文件流
|
||||
/// </summary>
|
||||
/// <param name="byteArray">文件数组</param>
|
||||
/// <param name="fileName">文件名</param>
|
||||
/// <returns></returns>
|
||||
FileStreamResult GetFileStreamResult(byte[] byteArray, string fileName);
|
||||
|
||||
/// <summary>
|
||||
/// 文件分页查询
|
||||
/// </summary>
|
||||
/// <param name="input">查询参数</param>
|
||||
/// <returns>文件列表</returns>
|
||||
Task<SqlSugarPagedList<SysFile>> Page(FilePageInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 上传文件到本地返回下载url
|
||||
/// </summary>
|
||||
/// <param name="engine">文件引擎</param>
|
||||
/// <param name="file">文件</param>
|
||||
/// <returns></returns>
|
||||
Task<long> UploadFile(string engine, IFormFile file);
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 站内信分类
|
||||
/// </summary>
|
||||
public string Category { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送参数
|
||||
/// </summary>
|
||||
public class MessageSendInput : SysMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// 主题
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "Subject不能为空")]
|
||||
public override string Subject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "Category不能为空")]
|
||||
public override string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接收人Id
|
||||
/// </summary>
|
||||
public List<long> ReceiverIdList { get; set; }
|
||||
|
||||
public override string Status { get; set; } = SysDictConst.MESSAGE_STATUS_READY;
|
||||
}
|
||||
|
||||
public class MessageSendUpdateInput : MessageSendInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息Id
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "Id不能为空")]
|
||||
public override long Id { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 消息详情输入参数
|
||||
/// </summary>
|
||||
public class MessageDetailInput : BaseIdInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否显示接收信息
|
||||
/// </summary>
|
||||
public bool ShowReceiveInfo { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否已读
|
||||
/// </summary>
|
||||
public bool Read { get; set; } = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 已读输入参数
|
||||
/// </summary>
|
||||
public class MessageReadInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 分类
|
||||
/// </summary>
|
||||
public string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户Id
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息Id
|
||||
/// </summary>
|
||||
public List<long> Ids { get; set; } = new List<long>();
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 消息详情
|
||||
/// </summary>
|
||||
public class MessageDetailOutPut : SysMessage
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 未读消息数量输出
|
||||
/// </summary>
|
||||
public class MessageUnReadOutPut
|
||||
{
|
||||
/// <summary>
|
||||
/// 未读消息数量
|
||||
/// </summary>
|
||||
public int UnReadCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类
|
||||
/// </summary>
|
||||
public string Category { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 站内信服务
|
||||
/// </summary>
|
||||
public interface IMessageService : ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 删除消息
|
||||
/// </summary>
|
||||
/// <param name="input">id列表</param>
|
||||
/// <returns></returns>
|
||||
Task Delete(BaseIdListInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 删除我的消息
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <returns></returns>
|
||||
Task DeleteMyMessage(BaseIdInput input, long userId);
|
||||
|
||||
/// <summary>
|
||||
/// 获取消息详情
|
||||
/// </summary>
|
||||
/// <param name="input">输入参数</param>
|
||||
/// <returns>消息详情</returns>
|
||||
Task<SysMessage> Detail(MessageDetailInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 我的消息列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <returns></returns>
|
||||
Task<SqlSugarPagedList<SysMessage>> MyMessagePage(MessagePageInput input, long userId);
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
/// <param name="input">查询参数</param>
|
||||
/// <returns></returns>
|
||||
Task<SqlSugarPagedList<SysMessage>> Page(MessagePageInput input);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取未读消息数
|
||||
/// </summary>
|
||||
/// <param name="userId">用户Id</param>
|
||||
/// <returns></returns>
|
||||
Task<List<MessageUnReadOutPut>> UnReadCount(long userId);
|
||||
|
||||
/// <summary>
|
||||
/// 最新未读
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<SysMessage>> NewUnRead(long userId);
|
||||
|
||||
/// <summary>
|
||||
/// 标记已读
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> SetRead(MessageReadInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 删除消息
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> SetDelete(MessageReadInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 新增
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task Add(MessageSendInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 编辑
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task Edit(MessageSendUpdateInput input);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="IMessageService"/>
|
||||
/// </summary>
|
||||
public class MessageService : DbRepository<SysMessage>, IMessageService
|
||||
{
|
||||
private readonly ILogger<MessageService> _logger;
|
||||
private readonly ISimpleCacheService _simpleCacheService;
|
||||
private readonly IRelationService _relationService;
|
||||
private readonly IEventPublisher _eventPublisher;
|
||||
|
||||
public MessageService(ILogger<MessageService> logger, ISimpleCacheService simpleCacheService, IRelationService relationService,
|
||||
IEventPublisher eventPublisher)
|
||||
{
|
||||
_logger = logger;
|
||||
_simpleCacheService = simpleCacheService;
|
||||
_relationService = relationService;
|
||||
_eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<SqlSugarPagedList<SysMessage>> Page(MessagePageInput input)
|
||||
{
|
||||
var query = Context.Queryable<SysMessage>().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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<SqlSugarPagedList<SysMessage>> MyMessagePage(MessagePageInput input, long userId)
|
||||
{
|
||||
var query = Context.Queryable<SysMessageUser>().LeftJoin<SysMessage>((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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task Add(MessageSendInput input)
|
||||
{
|
||||
CheckInput(input);
|
||||
var sysMessage = input.Adapt<SysMessage>();//实体转换
|
||||
sysMessage.Id = CommonUtils.GetSingleId();
|
||||
//如果是立即发送的直接修改状态
|
||||
if (sysMessage.SendWay == SysDictConst.SEND_WAY_NOW)
|
||||
sysMessage.Status = SysDictConst.MESSAGE_STATUS_ALREADY;//已发送
|
||||
var messageUsers = new List<SysMessageUser>();
|
||||
var userIds = new List<long>();
|
||||
//根据接收人获取需要发送的用户id
|
||||
switch (sysMessage.ReceiverType)
|
||||
{
|
||||
case SysDictConst.RECEIVER_TYPE_ALL:
|
||||
userIds = await Context.Queryable<SysUser>().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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task Edit(MessageSendUpdateInput input)
|
||||
{
|
||||
CheckInput(input);
|
||||
var sysMessage = input.Adapt<SysMessage>();//实体转换
|
||||
await UpdateAsync(sysMessage);//更新数据
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<SysMessage> 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<DbRepository<SysMessageUser>>();//切换仓储
|
||||
var messageUsers = await messageUserRep.GetListAsync(it => it.MessageId == message.Id);
|
||||
|
||||
var userIds = messageUsers.Select(it => it.UserId).ToList();//获取用户ID列表
|
||||
var userInfos = await Context.Queryable<SysUser>().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<SysMessageUser>()
|
||||
.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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
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<SysMessageUser>().Where(it => ids.Contains(it.MessageId)).ExecuteCommandAsync();
|
||||
});
|
||||
if (!result.IsSuccess)//如果失败了
|
||||
{
|
||||
//写日志
|
||||
_logger.LogError(result.ErrorMessage, result.ErrorException);
|
||||
throw Oops.Oh(ErrorCodeEnum.A0002);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task DeleteMyMessage(BaseIdInput input, long userId)
|
||||
{
|
||||
var messageUserRep = ChangeRepository<DbRepository<SysMessageUser>>();//切换仓储
|
||||
await Context.Deleteable<SysMessageUser>().Where(it => it.UserId == userId && it.MessageId == input.Id).IsLogic().ExecuteCommandAsync();//逻辑删除
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<MessageUnReadOutPut>> UnReadCount(long userId)
|
||||
{
|
||||
// 连表查询未读
|
||||
var unReadList = await Context.Queryable<SysMessage>().LeftJoin<SysMessageUser>((m, u) => u.MessageId == m.Id)
|
||||
.Where((m, u) => u.UserId == userId && u.Read == false && u.IsDelete == false)
|
||||
.Select<SysMessage>().ToListAsync();
|
||||
//根据消息分类分组
|
||||
var groupList = unReadList.GroupBy(it => it.Category).Select(it => new MessageUnReadOutPut
|
||||
{
|
||||
Category = it.Key,
|
||||
UnReadCount = it.Count()
|
||||
}).ToList();
|
||||
return groupList;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<SysMessage>> NewUnRead(long userId)
|
||||
{
|
||||
//根据消息分类分组,获取每组未读前五条
|
||||
var result = await Context.Queryable<SysMessage>().LeftJoin<SysMessageUser>((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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<int> SetRead(MessageReadInput input)
|
||||
{
|
||||
//如果ID列表为空,就是全部已读
|
||||
if (input.Ids.Count == 0 && input.Category != null)
|
||||
{
|
||||
var result = await Context.Updateable<SysMessageUser>()
|
||||
.SetColumns(it => it.Read == true)
|
||||
.SetColumns(it => it.UpdateTime == DateTime.Now)
|
||||
.Where(it => it.UserId == UserManager.UserId && it.Read == false)
|
||||
.Where(it => SqlFunc.Subqueryable<SysMessage>().Where(s => s.Id == it.MessageId && s.Category == input.Category).Any())
|
||||
.ExecuteCommandAsync();
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return await Context.Updateable<SysMessageUser>()
|
||||
.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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<int> SetDelete(MessageReadInput input)
|
||||
{
|
||||
//如果ID列表为空,就是全部删除
|
||||
if (input.Ids.Count == 0 && input.Category != null)
|
||||
{
|
||||
var result = await Context.Updateable<SysMessageUser>()
|
||||
.SetColumns(it => it.IsDelete == true)
|
||||
.SetColumns(it => it.UpdateTime == DateTime.Now)
|
||||
.Where(it => it.UserId == UserManager.UserId && it.IsDelete == false)
|
||||
.Where(it => SqlFunc.Subqueryable<SysMessage>().Where(s => s.Id == it.MessageId && s.Category == input.Category).Any())
|
||||
.ExecuteCommandAsync();
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return await Context.Updateable<SysMessageUser>()
|
||||
.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 方法
|
||||
|
||||
/// <summary>
|
||||
/// 检查输入
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成基础添加参数
|
||||
/// </summary>
|
||||
public class GenBasicAddInput : GenBasic, IValidatableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 所属库名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "ConfigId不能为空")]
|
||||
public override string ConfigId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主表名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "BbTable不能为空")]
|
||||
public override string DbTable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能列表
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "FuncList不能为空")]
|
||||
public override List<string>? FuncList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生成模版
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "ModuleType不能为空")]
|
||||
public override string ModuleType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据权限
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "DataPermission不能为空")]
|
||||
public override string DataPermission { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实体名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "EntityName不能为空")]
|
||||
public override string EntityName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表前缀移除
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "TablePrefix不能为空")]
|
||||
public override string TablePrefix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生成方式
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "GenerateType不能为空")]
|
||||
public override string GenerateType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属模块
|
||||
/// </summary>
|
||||
[IdNotNull(ErrorMessage = "Module不能为空")]
|
||||
public override long Module { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 路由名
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "RouteName不能为空")]
|
||||
public override string RouteName { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 图标
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "Icon不能为空")]
|
||||
public override string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能名
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "FunctionName不能为空")]
|
||||
public override string FunctionName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 业务名
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "BusName不能为空")]
|
||||
public override string BusName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类名
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "ClassName不能为空")]
|
||||
public override string ClassName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表单布局
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "FormLayout不能为空")]
|
||||
public override string FormLayout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用栅格
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "GridWhether不能为空")]
|
||||
public override string GridWhether { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 左侧树
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "LeftTree不能为空")]
|
||||
public override string LeftTree { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 前端路径
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "FrontedPath不能为空")]
|
||||
public override string FrontedPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 服务层
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "ServicePosition不能为空")]
|
||||
public override string ServicePosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 控制器层
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "ControllerPosition不能为空")]
|
||||
public override string ControllerPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "SortCode不能为空")]
|
||||
public override int SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 作者名
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "AuthorName不能为空")]
|
||||
public override string AuthorName { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> 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) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成基础编辑参数
|
||||
/// </summary>
|
||||
public class GenBasicEditInput : GenBasicAddInput
|
||||
{
|
||||
[IdNotNull(ErrorMessage = "Id不能为空")]
|
||||
public override long Id { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行代码生成参数
|
||||
/// </summary>
|
||||
public class ExecGenInput : BaseIdInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 生成类型
|
||||
/// </summary>
|
||||
public string ExecType { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
/// 表字段信息输出
|
||||
/// </summary>
|
||||
public class GenBasicColumnOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 字段名称
|
||||
/// </summary>
|
||||
public string ColumnName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否主键
|
||||
/// </summary>
|
||||
public bool IsPrimarykey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字段类型
|
||||
/// </summary>
|
||||
public string TypeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 字段注释
|
||||
/// </summary>
|
||||
public string ColumnRemark { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预览代码生成结果
|
||||
/// </summary>
|
||||
public class GenBasePreviewOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// SQL代码结果集
|
||||
/// </summary>
|
||||
public List<GenBaseCodeResult> SqlResults { get; set; } = new List<GenBaseCodeResult>();
|
||||
|
||||
/// <summary>
|
||||
/// 前端代码结果集
|
||||
/// </summary>
|
||||
public List<GenBaseCodeResult> CodeFrontendResults { get; set; } = new List<GenBaseCodeResult>();
|
||||
|
||||
/// <summary>
|
||||
/// 后端代码结果集
|
||||
/// </summary>
|
||||
|
||||
public List<GenBaseCodeResult> CodeBackendResults { get; set; } = new List<GenBaseCodeResult>();
|
||||
|
||||
public class GenBaseCodeResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 代码文件名称
|
||||
/// </summary>
|
||||
public string CodeFileName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件路径
|
||||
/// </summary>
|
||||
public string FilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 代码文件内容
|
||||
/// </summary>
|
||||
public string CodeFileContent { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
using StringHelper = SimpleTool.StringHelper;
|
||||
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成绑定视图
|
||||
/// </summary>
|
||||
public class GenViewModel : GenBasic
|
||||
{
|
||||
#region 基础
|
||||
|
||||
/// <summary>
|
||||
/// 生成时间
|
||||
/// </summary>
|
||||
public string GenTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
/// <summary>
|
||||
/// 表字段
|
||||
/// </summary>
|
||||
public List<GenConfig> TableFields { get; set; }
|
||||
|
||||
#endregion 基础
|
||||
|
||||
#region 菜单
|
||||
|
||||
/// <summary>
|
||||
/// 菜单ID
|
||||
/// </summary>
|
||||
public long MenuId { get; set; } = CommonUtils.GetSingleId();
|
||||
|
||||
/// <summary>
|
||||
/// 菜单编码
|
||||
/// </summary>
|
||||
public string MenuCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// /菜单路径
|
||||
/// </summary>
|
||||
public string MenuPath
|
||||
{
|
||||
get { return $"/{RouteName}/{BusName}"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// /菜单路径
|
||||
/// </summary>
|
||||
public string MenuComponent
|
||||
{
|
||||
get { return $"{RouteName}/{BusName}/index"; }
|
||||
}
|
||||
|
||||
#endregion 菜单
|
||||
|
||||
#region 按钮
|
||||
|
||||
/// <summary>
|
||||
/// 添加按钮ID
|
||||
/// </summary>
|
||||
public long AddButtonId { get; set; } = CommonUtils.GetSingleId();
|
||||
|
||||
/// <summary>
|
||||
/// 批量删除按钮ID
|
||||
/// </summary>
|
||||
public long BatchDeleteButtonId { get; set; } = CommonUtils.GetSingleId();
|
||||
|
||||
/// <summary>
|
||||
/// 编辑按钮ID
|
||||
/// </summary>
|
||||
public long EditButtonId { get; set; } = CommonUtils.GetSingleId();
|
||||
|
||||
/// <summary>
|
||||
/// 删除按钮ID
|
||||
/// </summary>
|
||||
public long DeleteButtonId { get; set; } = CommonUtils.GetSingleId();
|
||||
|
||||
#endregion 按钮
|
||||
|
||||
|
||||
#region 后端
|
||||
|
||||
/// <summary>
|
||||
/// 类名首字母小写
|
||||
/// </summary>
|
||||
public string ClassNameFirstLower
|
||||
{
|
||||
get { return StringHelper.FirstCharToLower(ClassName); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// swagger分组名称
|
||||
/// </summary>
|
||||
public string ApiGroup
|
||||
{
|
||||
get
|
||||
{
|
||||
return ServicePosition.Split(".").Last();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 服务名
|
||||
/// </summary>
|
||||
public string ServiceName
|
||||
{
|
||||
get { return ClassName + "Service"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 服务名开头首字母小写
|
||||
/// </summary>
|
||||
public string ServiceFirstLower
|
||||
{
|
||||
get { return ClassNameFirstLower + "Service"; }
|
||||
}
|
||||
|
||||
#endregion 后端
|
||||
|
||||
#region 注释描述
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
public string DescriptionPage
|
||||
{
|
||||
get { return FunctionName + "分页查询"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 列表查询
|
||||
/// </summary>
|
||||
public string DescriptionList
|
||||
{
|
||||
get { return FunctionName + "列表查询"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加
|
||||
/// </summary>
|
||||
public string DescriptionAdd
|
||||
{
|
||||
get { return "添加" + FunctionName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改
|
||||
/// </summary>
|
||||
public string DescriptionEdit
|
||||
{
|
||||
get { return "修改" + FunctionName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改
|
||||
/// </summary>
|
||||
public string DescriptionDelete
|
||||
{
|
||||
get { return "删除" + FunctionName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 详情
|
||||
/// </summary>
|
||||
public string DescriptionDetail
|
||||
{
|
||||
get { return FunctionName + "详情"; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 导入
|
||||
/// </summary>
|
||||
public string DescriptionImport
|
||||
{
|
||||
get { return FunctionName + "导入"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入模板下载
|
||||
/// </summary>
|
||||
public string DescriptionTemplate
|
||||
{
|
||||
get { return FunctionName + "导入模板下载"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入预览
|
||||
/// </summary>
|
||||
public string DescriptionPreview
|
||||
{
|
||||
get { return FunctionName + "导入预览"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入
|
||||
/// </summary>
|
||||
public string DescriptionExport
|
||||
{
|
||||
get { return FunctionName + "导出"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量编辑
|
||||
/// </summary>
|
||||
public string DescriptionEdits
|
||||
{
|
||||
get { return FunctionName + "批量编辑"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 树查询
|
||||
/// </summary>
|
||||
public string DescriptionTree
|
||||
{
|
||||
get { return FunctionName + "树"; }
|
||||
}
|
||||
|
||||
#endregion 注释描述
|
||||
|
||||
#region 参数
|
||||
|
||||
/// <summary>
|
||||
/// 分页参数
|
||||
/// </summary>
|
||||
public string PageInput
|
||||
{
|
||||
get { return ClassName + "PageInput"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加参数
|
||||
/// </summary>
|
||||
public string AddInput
|
||||
{
|
||||
get { return ClassName + "AddInput"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑参数
|
||||
/// </summary>
|
||||
public string EditInput
|
||||
{
|
||||
get { return ClassName + "EditInput"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 树查询参数
|
||||
/// </summary>
|
||||
public string TreeInput
|
||||
{
|
||||
get { return ClassName + "TreeInput"; }
|
||||
}
|
||||
|
||||
#endregion 参数
|
||||
}
|
||||
@@ -0,0 +1,808 @@
|
||||
using StringHelper = SimpleTool.StringHelper;
|
||||
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="IGenbasicService"/>
|
||||
/// </summary>
|
||||
public class GenBasicService : DbRepository<GenBasic>, IGenbasicService
|
||||
{
|
||||
private readonly ILogger<GenBasicService> _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<GenBasicService> logger,
|
||||
IViewEngine viewEngine,
|
||||
IGenConfigService genConfigService,
|
||||
IMenuService menuService,
|
||||
IButtonService buttonService, ISysRoleService roleService)
|
||||
{
|
||||
_logger = logger;
|
||||
_viewEngine = viewEngine;
|
||||
_genConfigService = genConfigService;
|
||||
_menuService = menuService;
|
||||
_buttonService = buttonService;
|
||||
_roleService = roleService;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<SqlSugarPagedList<GenBasic>> Page(BasePageInput input)
|
||||
{
|
||||
var query = Context.Queryable<GenBasic>()
|
||||
.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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public List<SqlSugarTableInfo> GetTables(bool isAll = false)
|
||||
{
|
||||
if (isAll)
|
||||
return SqlSugarUtils.GetTablesByAttribute<SugarTable>();
|
||||
return SqlSugarUtils.GetTablesByAttribute<CodeGenAttribute>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public List<string> GetAssemblies()
|
||||
{
|
||||
var names = new List<string>();//结果集
|
||||
var excludeList = new List<string>
|
||||
{
|
||||
"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;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<GenBasic> Add(GenBasicAddInput input)
|
||||
{
|
||||
var entity = input.Adapt<GenBasic>();//输入参数转实体
|
||||
entity.Functions = string.Join(",", input.FuncList);//功能集合
|
||||
var tableColumns = SqlSugarUtils.GetTableColumns(input.ConfigId, input.DbTable);//获取表的字段信息
|
||||
var genConfigs = new List<GenConfig>();//代码生成配置字段集合
|
||||
//遍历字段
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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<object>().ToArray());//删除基础表
|
||||
await Context.Deleteable<GenConfig>().Where(it => ids.Contains(it.BasicId))
|
||||
.ExecuteCommandAsync();//删除配置表
|
||||
});
|
||||
if (!result.IsSuccess)//如果失败了
|
||||
{
|
||||
//写日志
|
||||
_logger.LogError(result.ErrorMessage, result.ErrorException);
|
||||
throw Oops.Oh(ErrorCodeEnum.A0002);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<GenBasic> Edit(GenBasicEditInput input)
|
||||
{
|
||||
var entity = input.Adapt<GenBasic>();//输入参数转实体
|
||||
entity.Functions = string.Join(",", input.FuncList);//功能集合
|
||||
await UpdateAsync(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<GenBasePreviewOutput> PreviewGen(BaseIdInput input)
|
||||
{
|
||||
var genBasic = await GetGenBasic(input.Id);//获取代码生成基础
|
||||
return await PreviewGen(genBasic);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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("代码生成失败");
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<FileStreamResult> 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 方法
|
||||
|
||||
/// <summary>
|
||||
/// 生成后端代码文件
|
||||
/// </summary>
|
||||
/// <param name="baseCodeResults">后端代码模板</param>
|
||||
/// <param name="genBasic">代码基础</param>
|
||||
/// <param name="backendPath">后端生成路径</param>
|
||||
/// <param name="isZip">是否是zip方式</param>
|
||||
// public void ExecBackend(List<GenBasePreviewOutput.GenBaseCodeResult> baseCodeResults, GenBasic genBasic,
|
||||
// string backendPath, bool isZip = false)
|
||||
// {
|
||||
// var serviceDir = "Services";//服务代码文件夹
|
||||
// var controllerDir = "Controllers";//服务代码文件夹
|
||||
// var tempDicName = "";//临时文件夹名称
|
||||
// var dirList = new HashSet<string> { };//文件夹列表
|
||||
// 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<GenBasePreviewOutput.GenBaseCodeResult> 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);//写入文件
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成前端代码文件
|
||||
/// </summary>
|
||||
/// <param name="baseCodeResults">前端代码模板</param>
|
||||
/// <param name="frontedPath">前端生成路径</param>
|
||||
public void ExecFronted(List<GenBasePreviewOutput.GenBaseCodeResult> 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);//写入文件
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成sql代码文件
|
||||
/// </summary>
|
||||
/// <param name="baseCodeResults">后端代码模板</param>
|
||||
/// <param name="execPath">生成路径</param>
|
||||
public void ExecSql(List<GenBasePreviewOutput.GenBaseCodeResult> 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);//写入文件
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取sql代码预览结果
|
||||
/// </summary>
|
||||
/// <param name="genViewModel">视图</param>
|
||||
/// <param name="templatePath">模板路径</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<GenBasePreviewOutput.GenBaseCodeResult>> GetSqlCodeResult(GenViewModel genViewModel,
|
||||
string templatePath)
|
||||
{
|
||||
var sqlCodeResults = new List<GenBasePreviewOutput.GenBaseCodeResult>();//结果集
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取后端代码预览结果
|
||||
/// </summary>
|
||||
/// <param name="genViewModel">视图</param>
|
||||
/// <param name="templatePath">模板路径</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<GenBasePreviewOutput.GenBaseCodeResult>> GetBackendCodeResult(GenViewModel genViewModel,
|
||||
string templatePath)
|
||||
{
|
||||
var backendCodeResults = new List<GenBasePreviewOutput.GenBaseCodeResult>();//结果集
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取前端代码预览结果
|
||||
/// </summary>
|
||||
/// <param name="genViewModel">视图</param>
|
||||
/// <param name="templatePath">模板路径</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<GenBasePreviewOutput.GenBaseCodeResult>> GetForntCodeResult(GenViewModel genViewModel,
|
||||
string templatePath)
|
||||
{
|
||||
var frontCodeResults = new List<GenBasePreviewOutput.GenBaseCodeResult>();//结果集
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取代码生成视图
|
||||
/// </summary>
|
||||
/// <param name="genBasic"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<GenViewModel> GetGenViewModel(GenBasic genBasic)
|
||||
{
|
||||
//实体转视图
|
||||
var genViewEngine = genBasic.Adapt<GenViewModel>();
|
||||
//获取字段信息
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 视图渲染
|
||||
/// </summary>
|
||||
/// <param name="tContent">模板内容</param>
|
||||
/// <param name="genViewModel">参数</param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得文件夹下所有的文件
|
||||
/// </summary>
|
||||
/// <param name="path">文件夹路径</param>
|
||||
/// <returns></returns>
|
||||
private FileInfo[] GetAllFileInfo(string path)
|
||||
{
|
||||
var dir = new DirectoryInfo(path);
|
||||
return dir.GetFiles(".", SearchOption.AllDirectories);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成预览
|
||||
/// </summary>
|
||||
/// <param name="genBasic">基础配置</param>
|
||||
/// <returns></returns>
|
||||
public async Task<GenBasePreviewOutput> 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
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取代码生成基础
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<GenBasic> GetGenBasic(long id)
|
||||
{
|
||||
var genBasic = await GetByIdAsync(id);
|
||||
if (genBasic == null)
|
||||
throw Oops.Bah("代码生成配置不存在");
|
||||
genBasic.FuncList = genBasic.Functions.Split(',').ToList();
|
||||
return genBasic;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建代码生成相关的菜单按钮和授权关系
|
||||
/// </summary>
|
||||
/// <param name="genBasic"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> CreateMenuButtonAndRelation(GenBasic genBasic)
|
||||
{
|
||||
try
|
||||
{
|
||||
#region 菜单
|
||||
|
||||
var title = genBasic.FunctionName + genBasic.FunctionNameSuffix;
|
||||
var menuRep = ChangeRepository<DbRepository<SysResource>>();//切换仓储
|
||||
//获取已经存在的旧菜单
|
||||
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<long>()
|
||||
{
|
||||
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<DbRepository<SysRole>>();//切换仓储
|
||||
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<RelationRoleResource>
|
||||
{ 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 方法
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成基础服务
|
||||
/// </summary>
|
||||
public interface IGenbasicService : ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加代码生成器基础
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<GenBasic> Add(GenBasicAddInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 删除代码生成配置
|
||||
/// </summary>
|
||||
/// <param name="input">ID列表</param>
|
||||
/// <returns></returns>
|
||||
Task Delete(BaseIdListInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 编辑代码生成基础配置
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns>代码生产基础</returns>
|
||||
Task<GenBasic> Edit(GenBasicEditInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 执行代码生成:本地
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task ExecGenPro(ExecGenInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 执行代码生成:压缩包
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<FileStreamResult> ExecGenZip(ExecGenInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目所有程序集
|
||||
/// </summary>
|
||||
/// <returns>程序集列表</returns>
|
||||
List<string> GetAssemblies();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取表信息
|
||||
/// </summary>
|
||||
/// <param name="isAll">是否所有表</param>
|
||||
/// <returns>实体表列表</returns>
|
||||
List<SqlSugarTableInfo> GetTables(bool isAll = false);
|
||||
|
||||
/// <summary>
|
||||
/// 获取代码生成基础分页
|
||||
/// </summary>
|
||||
/// <param name="input">查询参数</param>
|
||||
/// <returns>代码生成基础分页列表</returns>
|
||||
Task<SqlSugarPagedList<GenBasic>> Page(BasePageInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成预览
|
||||
/// </summary>
|
||||
/// <param name="input">代码生成基础Id</param>
|
||||
/// <returns>预览结果</returns>
|
||||
Task<GenBasePreviewOutput> PreviewGen(BaseIdInput input);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
public class GenConfigInput
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="IGenConfigService"/>
|
||||
/// </summary>
|
||||
public class GenConfigService : DbRepository<GenConfig>, IGenConfigService
|
||||
{
|
||||
private readonly ILogger<GenConfigService> logger;
|
||||
|
||||
public GenConfigService(ILogger<GenConfigService> logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<GenConfig>> List(long basicId)
|
||||
{
|
||||
var configs = await GetListAsync(it => it.BasicId == basicId);//获取配置表相关配置
|
||||
configs = configs.OrderBy(it => it.FieldIndex).ToList();//排序一下
|
||||
return configs;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task EditBatch(List<GenConfig> configs)
|
||||
{
|
||||
await UpdateRangeAsync(configs);//批量更新
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成详细配置服务
|
||||
/// </summary>
|
||||
public interface IGenConfigService : ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 批量更新
|
||||
/// </summary>
|
||||
/// <param name="configs"></param>
|
||||
/// <returns></returns>
|
||||
Task EditBatch(List<GenConfig> configs);
|
||||
|
||||
/// <summary>
|
||||
/// 查询代码生成详细配置列表
|
||||
/// </summary>
|
||||
/// <param name="basicId"></param>
|
||||
/// <returns>配置列表</returns>
|
||||
Task<List<GenConfig>> List(long basicId);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 导入预览输入
|
||||
/// </summary>
|
||||
public class ImportPreviewInput : BaseFileInput
|
||||
{
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 文件导入通用输出
|
||||
/// </summary>
|
||||
public class ImportPreviewOutput<T> where T : class
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否有错误
|
||||
/// </summary>
|
||||
public bool HasError { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 动态表头
|
||||
/// </summary>
|
||||
public List<TableColumns> TableColumns { get; set; } = new List<TableColumns>();
|
||||
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
public List<T> Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态表头
|
||||
/// </summary>
|
||||
public class TableColumns
|
||||
{
|
||||
/// <summary>
|
||||
/// 标题
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据源
|
||||
/// </summary>
|
||||
public string DataIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 宽度
|
||||
/// </summary>
|
||||
public int Width { get; set; } = 120;
|
||||
|
||||
/// <summary>
|
||||
/// 超过宽度将自动省略
|
||||
/// </summary>
|
||||
public bool Ellipsis { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否是日期格式
|
||||
/// </summary>
|
||||
public bool Date { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 批量导入结果输入
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class ImportResultInput<T> where T : class
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
public List<T> Data { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 导入结果输出
|
||||
/// </summary>
|
||||
public class ImportResultOutPut<T> where T : class
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否成功
|
||||
/// </summary>
|
||||
|
||||
public bool Success { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 总数
|
||||
/// </summary>
|
||||
public int Total { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导入数量
|
||||
/// </summary>
|
||||
public int ImportCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误数
|
||||
/// </summary>
|
||||
public int FailCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
|
||||
public List<T> Data { get; set; } = new List<T>();
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 导入基础输入
|
||||
/// </summary>
|
||||
[ExcelImporter(IsLabelingError = true)]
|
||||
public class ImportTemplateInput
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
[ImporterHeader(IsIgnore = true)]
|
||||
public long Id { get; set; } = CommonUtils.GetSingleId();
|
||||
|
||||
/// <summary>
|
||||
/// 是否有错误
|
||||
/// </summary>
|
||||
[ImporterHeader(IsIgnore = true)]
|
||||
public bool HasError { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误详情
|
||||
/// </summary>
|
||||
[ImporterHeader(IsIgnore = true)]
|
||||
public IDictionary<string, string> ErrorInfo { get; set; } = new Dictionary<string, string>();
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 导入服务
|
||||
/// </summary>
|
||||
public interface IImportExportService : ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 导出数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="data">数据</param>
|
||||
/// <param name="fileName">文件名</param>
|
||||
/// <returns>文件流</returns>
|
||||
Task<FileStreamResult> Export<T>(List<T> data, string fileName) where T : class, new();
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地模板
|
||||
/// </summary>
|
||||
/// <param name="fileName">文件名</param>
|
||||
/// <param name="templateFolder">模板文件夹路径:默认wwwroot下的Template</param>
|
||||
/// <returns>文件流</returns>
|
||||
FileStreamResult GenerateLocalTemplate(string fileName, string templateFolder = "Template");
|
||||
|
||||
/// <summary>
|
||||
/// 生成模板
|
||||
/// </summary>
|
||||
/// <typeparam name="T">实体类</typeparam>
|
||||
/// <param name="fileName">文件名</param>
|
||||
/// <returns>文件流</returns>
|
||||
Task<FileStreamResult> GenerateTemplate<T>(string fileName) where T : class, new();
|
||||
|
||||
/// <summary>
|
||||
/// 获取导入预览
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="file">文件</param>
|
||||
/// <returns>导入预览结果</returns>
|
||||
Task<ImportPreviewOutput<T>> GetImportPreview<T>(IFormFile file) where T : ImportTemplateInput, new();
|
||||
|
||||
/// <summary>
|
||||
/// 获取预计导入结果
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="data">数据</param>
|
||||
/// <param name="importData">成功导入数据</param>
|
||||
/// <returns>预计导入结果</returns>
|
||||
ImportResultOutPut<T> GetImportResultPreview<T>(List<T> data, out List<T> importData) where T : ImportTemplateInput;
|
||||
|
||||
/// <summary>
|
||||
/// 导入文件验证
|
||||
/// </summary>
|
||||
/// <param name="file">文件</param>
|
||||
/// <param name="maxSize">文件最大体积(M)</param>
|
||||
/// <param name="allowTypes">允许的格式</param>
|
||||
void ImportVerification(IFormFile file, int maxSize = 30, string[] allowTypes = null);
|
||||
|
||||
/// <summary>
|
||||
/// 模板数据验证
|
||||
/// </summary>
|
||||
/// <typeparam name="T">模板类实体</typeparam>
|
||||
/// <param name="importResult">结果</param>
|
||||
/// <returns>导入预览数据</returns>
|
||||
ImportPreviewOutput<T> TemplateDataVerification<T>(ImportResult<T> importResult) where T : ImportTemplateInput;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="IImportExportService"/>
|
||||
/// </summary>
|
||||
public class ImportExportService : IImportExportService
|
||||
{
|
||||
#region 导入
|
||||
|
||||
/// <inheritdoc/>
|
||||
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: "文件格式错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ImportPreviewOutput<T> TemplateDataVerification<T>(ImportResult<T> 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<T> { HasError = importResult.HasError };
|
||||
var headerMap = new Dictionary<string, string>();
|
||||
//遍历导入的表头列表信息
|
||||
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<AntTableAttribute>();//获取表格特性
|
||||
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<string, string> fieldErrors = new Dictionary<string, string>();//定义字典
|
||||
//遍历错误列,赋值给新的字典
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<FileStreamResult> GenerateTemplate<T>(string fileName) where T : class, new()
|
||||
{
|
||||
IImporter importer = new ExcelImporter();
|
||||
var byteArray = await importer.GenerateTemplateBytes<T>();
|
||||
var result = GetFileStreamResult(byteArray, fileName);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public FileStreamResult GenerateLocalTemplate(string fileName, string templateFolder = "Template")
|
||||
{
|
||||
var folder = App.WebHostEnvironment.WebRootPath.CombinePath(templateFolder);
|
||||
return GetFileStreamResult(folder, fileName, true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<ImportPreviewOutput<T>> GetImportPreview<T>(IFormFile file) where T : ImportTemplateInput, new()
|
||||
{
|
||||
ImportVerification(file);//验证文件
|
||||
IImporter importer = new ExcelImporter();
|
||||
using var fileStream = file.OpenReadStream();//获取文件流
|
||||
var import = await importer.Import<T>(fileStream);//导入的文件转化为带入结果
|
||||
var importPreview = TemplateDataVerification(import);//验证数据完整度
|
||||
return importPreview;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ImportResultOutPut<T> GetImportResultPreview<T>(List<T> data, out List<T> importData) where T : ImportTemplateInput
|
||||
{
|
||||
//定义结果
|
||||
var result = new ImportResultOutPut<T> { 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<FileStreamResult> Export<T>(List<T> 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 方法
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件流
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="isPathFolder"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件流
|
||||
/// </summary>
|
||||
/// <param name="byteArray"></param>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
public FileStreamResult GetFileStreamResult(byte[] byteArray, string fileName)
|
||||
{
|
||||
fileName = GetFileName(fileName);
|
||||
//文件转流
|
||||
var result = new FileStreamResult(new MemoryStream(byteArray), "application/octet-stream") { FileDownloadName = fileName };
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件名
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
public string GetFileName(string fileName)
|
||||
{
|
||||
if (!fileName.Contains("."))
|
||||
fileName = fileName + ".xlsx";
|
||||
fileName = HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));//文件名转utf8不然前端下载会乱码
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地模板路径
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetTemplateFolder()
|
||||
{
|
||||
var folder = App.WebHostEnvironment.WebRootPath.CombinePath("Template");
|
||||
return folder;
|
||||
}
|
||||
|
||||
#endregion 方法
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 日程列表查询参数
|
||||
/// </summary>
|
||||
public class ScheduleListInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 日程日期
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "ScheduleDate不能为空")]
|
||||
public string ScheduleDate { get; set; }
|
||||
}
|
||||
|
||||
public class ScheduleAddInput : RelationUserSchedule
|
||||
{
|
||||
/// <summary>
|
||||
/// 日程日期
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "scheduleDate不能为空")]
|
||||
public override string ScheduleDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 日程内容
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "ScheduleContent不能为空")]
|
||||
public override string ScheduleContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 日程时间
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "ScheduleTime 不能为空")]
|
||||
public override string ScheduleTime { get; set; }
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// ID
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 首页服务
|
||||
/// </summary>
|
||||
public interface IIndexService : ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加日程
|
||||
/// </summary>
|
||||
/// <param name="input">日程参数</param>
|
||||
/// <returns></returns>
|
||||
Task AddSchedule(ScheduleAddInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 删除日程
|
||||
/// </summary>
|
||||
/// <param name="input">id列表</param>
|
||||
/// <returns></returns>
|
||||
Task DeleteSchedule(BaseIdListInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 获取日程列表
|
||||
/// </summary>
|
||||
/// <param name="input">查询参数</param>
|
||||
/// <returns>日程列表</returns>
|
||||
Task<List<ScheduleListOutput>> ScheduleList(ScheduleListInput input);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user