SaaS系统 .netcore webapi

8 篇文章 0 订阅
1 篇文章 0 订阅

1.什么是SaaS

SaaS系统,软件即服务,租户系统,相对于传统软件,SaaS不需要租户购买服务器,不需要安装,也不需要花费大量的时间和成本去维护,只需要购买使用权,租用即可

2.首先要有租户表

    /// <summary>
    /// 租户
    /// </summary>
    public class SysTenant
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        /// <summary>
        /// 名字
        /// </summary>
        [MaxLength(50)]
        public string Name { get; set; }

        /// <summary>
        /// 是否删除
        /// </summary>
        [DefaultValue(false)]
        public bool IsDeleted { get; set; }

        /// <summary>
        /// 添加时间
        /// </summary>
        public DateTime CreateDate { get; set; } = DateTime.Now;

        /// <summary>
        /// 编码
        /// </summary>
        [Required]
        [MaxLength(20)]
        public string Code { get; set; }

        /// <summary>
        /// 电话
        /// </summary>
        [Required]
        [MaxLength(20)]
        public string Phone { get; set; }

        /// <summary>
        /// 租户类型(共享租户、独立租户)
        /// </summary>
        [Required]
        public ETenantType TenantType { get; set; }

        /// <summary>
        /// 所属区域
        /// </summary>
        [MaxLength(20)]
        public string Area { get; set; }

        /// <summary>
        /// 租户状态(待审核、已审核、启用、禁用、取消)
        /// </summary>
        [Required]
        public ETenantState TenantState { get; set; }

        /// <summary>
        /// Host
        /// </summary>
        [MaxLength(200)]
        public string Host { get; set; }

        /// <summary>
        /// 备注
        /// </summary>
        [MaxLength(200)]
        public string Remark { get; set; }
    }

租户类型(共享租户、独立租户)

    /// <summary>
    /// 租户类型(共享租户、独立租户)
    /// </summary>
    public enum ETenantType
    {
        /// <summary>
        /// 共享租户
        /// </summary>
        [Description("共享租户")]
        Share =1,

        /// <summary>
        /// 独立租户
        /// </summary>
        [Description("独立租户")]
        Independent =2
    }

租户状态(待审核、已审核、启用、禁用、取消)

    /// <summary>
    /// 租户状态(待审核、已审核、启用、禁用、取消)
    /// </summary>
    public enum ETenantState
    {
        /// <summary>
        /// 待审核
        /// </summary>
        [Description("待审核")]
        WaitExamine = 1,

        /// <summary>
        /// 已审核
        /// </summary>
        [Description("已审核")]
        ExamineFinish = 2,

        /// <summary>
        /// 启用
        /// </summary>
        [Description("启用")]
        Enable = 3,

        /// <summary>
        /// 禁用
        /// </summary>
        [Description("禁用")]
        Disable = 4,

        /// <summary>
        /// 取消
        /// </summary>
        [Description("取消")]
        Cancel = 5
    }

 

3.获取请求的租户Id,Host

public class TenantProvider : ITenantProvider
    {
        private readonly IHttpContextAccessor _accessor;

        public TenantProvider(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }

        public string GetTenantId()
        {
            if (_accessor.HttpContext.User.FindFirst("TenantId") != null)
            {
                return _accessor.HttpContext.User.FindFirst("TenantId").Value;
            }
            else
            {
                return "";
            }
            //return "localhost:5001";
        }

        public string GetHost()
        {
            return _accessor.HttpContext.Request.Host.ToString();
            //return "localhost:5001";
        }
    }

4.DBContext调用,并进行租户过滤

public class JKCRMDBContext : IdentityDbContext<Admins>
    {
        private readonly ITenantProvider TenantProvider;
        internal string TenantId => TenantProvider.GetTenantId();

        public JKCRMDBContext(DbContextOptions<JKCRMDBContext> options, ITenantProvider tenantProvider) : base(options)
        {
            TenantProvider = tenantProvider; 
        }


protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

#region 租户过滤器

            string tenantId = "******";
            //根据登录Token查询租户Id
            if (!string.IsNullOrEmpty(TenantProvider.GetTenantId()))
            {
                tenantId = TenantProvider.GetTenantId();
            }
            else
            {
                #region 查询租户信息

                //根据Host查询租户Id
                MySqlParameter parameter = new MySqlParameter("@Host", MySqlDbType.String);
                var originalhost = TenantProvider.GetHost();//localhost:5001
                var host = originalhost;
                if (originalhost == "localhost:8080")
                {
                    host = "localhost:5001";
                }
                parameter.Value = host;
                var MySqlDataReader = DbHelperMySQL.ExecuteReader("select * from SysTenant where Host=@Host", parameter);
                while (MySqlDataReader.Read()) //开始读数据
                {
                    //对数据进行处理
                    tenantId = MySqlDataReader["Id"].ToString();
                }
                MySqlDataReader.Close();

                #region 写入一条记录
                //根据Host查询租户Id
                MySqlParameter[] mySqlParameters = new MySqlParameter[]
                {
                    new MySqlParameter("@Name", "用户登录记录Host"),
                    new MySqlParameter("@CreateDate", DateTime.Now),
                    new MySqlParameter("@OperationType", 1007),
                    new MySqlParameter("@OperationParameters", "OriginalHost:"+originalhost+",Host:"+host),
                    new MySqlParameter("@OperationInfo", "TenantId:"+tenantId)
                 };

                var MySqlInsert = DbHelperMySQL.ExecuteSql("insert into OperationRecords (Name,CreateDate,OperationType,OperationParameters,OperationInfo) values (@Name,@CreateDate,@OperationType,@OperationParameters,@OperationInfo)", mySqlParameters);

                #endregion

                if (string.IsNullOrEmpty(tenantId) || tenantId == "******")
                {
                    throw new Exception("所属机构不存在,Host:"+ host);
                }

                #endregion
            }

            //开始过滤
            modelBuilder.Entity<Customers>().HasQueryFilter(x => x.SysTenantId == Convert.ToInt32(tenantId));
            modelBuilder.Entity<ManageMenu>().HasQueryFilter(x => x.SysTenantId == Convert.ToInt32(tenantId));
            modelBuilder.Entity<ManageMenuButton>().HasQueryFilter(x => x.SysTenantId == Convert.ToInt32(tenantId));
            #endregion

}

}

5.Startup的ConfigureServices

services.AddScoped<ITenantProvider, TenantProvider>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

6.每个涉及到业务的表都需要跟租户表加主外键关系

#region 关系

        /// <summary>
        /// 租户Id
        /// </summary>
        [Description(@"租户Id")]
        public int? SysTenantId { get; set; }
        [ForeignKey("SysTenantId")]
        public virtual SysTenant SysTenant { get; set; }

#endregion

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值