Browse Source

增加表间关联

master
大石头 3 years ago
parent
commit
0e1efb562d
  1. 14
      GitCandy.Web/Areas/GitCandy/Controllers/RepositoryController.cs
  2. 13
      GitCandy.Web/Areas/GitCandy/Controllers/UserController.cs
  3. 501
      GitCandy/Entity/Entity/用户.Biz.cs

14
GitCandy.Web/Areas/GitCandy/Controllers/RepositoryController.cs

@ -1,4 +1,5 @@
using NewLife.Cube;
using NewLife.Cube.ViewModels;
using NewLife.GitCandy.Entity;
using NewLife.Web;
@ -14,10 +15,23 @@ public class RepositoryController : EntityController<Repository>
ListFields.RemoveCreateField();
ListFields.RemoveUpdateField();
ListFields.RemoveRemarkField();
{
var df = ListFields.AddDataField("UserRepositorys", "Commits") as ListField;
df.DisplayName = "关联团队/用户";
df.Url = "/GitCandy/UserRepository?repositoryId={ID}";
}
}
protected override IEnumerable<Repository> Search(Pager p)
{
var id = p["Id"].ToInt(-1);
if (id > 0)
{
var entity = Repository.FindByKey(id);
if (entity != null) return new[] { entity };
}
var ownerId = p["ownerId"].ToInt(-1);
var userId = p["userId"].ToInt(-1);
var enable = p["enable"]?.ToBoolean();

13
GitCandy.Web/Areas/GitCandy/Controllers/UserController.cs

@ -23,6 +23,12 @@ public class UserController : EntityController<User>
df.Url = "/GitCandy/User?ownerId={ID}";
df.DataVisible = e => (e as UserX).IsTeam;
}
{
var df = ListFields.AddDataField("userteams", null, "members") as ListField;
df.DisplayName = "关联分组";
df.Url = "/GitCandy/UserTeam?userId={ID}";
df.DataVisible = e => !(e as UserX).IsTeam;
}
{
var df = ListFields.AddDataField("repos", "IsAdmin") as ListField;
df.DisplayName = "仓库列表";
@ -38,6 +44,13 @@ public class UserController : EntityController<User>
protected override IEnumerable<User> Search(Pager p)
{
var id = p["Id"].ToInt(-1);
if (id > 0)
{
var entity = UserX.FindByKey(id);
if (entity != null) return new[] { entity };
}
var ownerId = p["ownerId"].ToInt(-1);
var enable = p["enable"]?.ToBoolean();
var isTeam = p["isTeam"]?.ToBoolean();

501
GitCandy/Entity/Entity/用户.Biz.cs

@ -8,352 +8,303 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using NewLife.Data;
using NewLife.Model;
using NewLife.Web;
using XCode;
using XCode.Membership;
namespace NewLife.GitCandy.Entity
namespace NewLife.GitCandy.Entity;
/// <summary>用户</summary>
public partial class User : LogEntity<User>, IManageUser/*, IIdentity*/
{
/// <summary>用户</summary>
public partial class User : LogEntity<User>, IManageUser/*, IIdentity*/
#region 对象操作
/// <summary>首次连接数据库时初始化数据,仅用于实体类重载,用户不应该调用该方法</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void InitData()
{
#region 对象操作
/// <summary>首次连接数据库时初始化数据,仅用于实体类重载,用户不应该调用该方法</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void InitData()
{
Meta.Modules.Add<UserModule>();
Meta.Modules.Add<TimeModule>();
Meta.Modules.Add<IPModule>();
var sc = Meta.SingleCache;
sc.FindSlaveKeyMethod = k => Find(_.Name == k);
sc.GetSlaveKeyMethod = e => e.Name;
}
protected override Int32 OnDelete()
{
Teams?.Delete(true);
UserTeam.FindAllByTeamID(ID).Delete(true);
Repositories?.Delete(true);
Repository.FindAllByOwnerID(ID).Delete();
//AuthorizationLog.FindAllByUserID(ID).Delete();
return base.OnDelete();
}
#endregion
#region 扩展属性
private IList<UserTeam> _Teams;
/// <summary>团队关系</summary>
public IList<UserTeam> Teams
{
get
{
if (_Teams == null && !Dirtys["Teams"])
{
_Teams = UserTeam.FindAllByUserID(ID);
Dirtys["Teams"] = true;
}
return _Teams;
}
set { _Teams = value; }
}
Meta.Modules.Add<UserModule>();
Meta.Modules.Add<TimeModule>();
Meta.Modules.Add<IPModule>();
public String[] TeamNames => Teams?.Select(e => e.Team?.Name).OrderBy(e => e).ToArray();
var sc = Meta.SingleCache;
sc.FindSlaveKeyMethod = k => Find(_.Name == k);
sc.GetSlaveKeyMethod = e => e.Name;
}
private IList<UserRepository> _Repositories;
/// <summary>仓库关系</summary>
public IList<UserRepository> Repositories
{
get
{
if (_Repositories == null && !Dirtys["Repositories"])
{
_Repositories = UserRepository.FindAllByUserID(ID);
protected override Int32 OnDelete()
{
Teams?.Delete(true);
UserTeam.FindAllByTeamID(ID).Delete(true);
Repositories?.Delete(true);
Repository.FindAllByOwnerID(ID).Delete();
//AuthorizationLog.FindAllByUserID(ID).Delete();
Dirtys["Repositories"] = true;
}
return _Repositories;
}
set { _Repositories = value; }
}
return base.OnDelete();
}
#endregion
public String[] RepositoryNames => Repositories?.Select(e => e.RepositoryName).ToArray();
#region 扩展属性
/// <summary>团队关系</summary>
[XmlIgnore, IgnoreDataMember]
public IList<UserTeam> Teams => Extends.Get(nameof(Teams), k => UserTeam.FindAllByUserID(ID));
///// <summary>当前登录用户</summary>
//public static User Current
//{
// get
// {
// var ss = HttpContext.Current?.Session;
// if (ss == null) return null;
[XmlIgnore, IgnoreDataMember]
public String[] TeamNames => Teams?.Select(e => e.Team?.Name).OrderBy(e => e).ToArray();
// return ss["CandyUser"] as User;
// }
// set
// {
// var ss = HttpContext.Current?.Session;
// if (ss == null) return;
/// <summary>仓库关系</summary>
[XmlIgnore, IgnoreDataMember]
public IList<UserRepository> Repositories => Extends.Get(nameof(Repositories), k => UserRepository.FindAllByUserID(ID));
// ss["CandyUser"] = value;
// }
//}
[XmlIgnore, IgnoreDataMember]
public String[] RepositoryNames => Repositories?.Select(e => e.RepositoryName).ToArray();
#endregion
//String IIdentity.AuthenticationType => "GitCandy";
#region 扩展查询
public static User FindByID(Int32 id)
{
if (id <= 0) return null;
//Boolean IIdentity.IsAuthenticated => true;
#endregion
if (Meta.Count < 1000) return Meta.Cache.Entities.FirstOrDefault(e => e.ID == id);
#region 扩展查询
public static User FindByID(Int32 id)
{
if (id <= 0) return null;
return Meta.SingleCache[id];
}
if (Meta.Count < 1000) return Meta.Cache.Entities.FirstOrDefault(e => e.ID == id);
/// <summary>根据名称。登录用户名查找</summary>
/// <param name="name">名称。登录用户名</param>
/// <returns></returns>
[DataObjectMethod(DataObjectMethodType.Select, false)]
public static User FindByName(String name)
{
if (name.IsNullOrEmpty()) return null;
return Meta.SingleCache[id];
}
if (Meta.Count < 1000) return Meta.Cache.Entities.FirstOrDefault(e => e.Name.EqualIgnoreCase(name));
/// <summary>根据名称。登录用户名查找</summary>
/// <param name="name">名称。登录用户名</param>
/// <returns></returns>
[DataObjectMethod(DataObjectMethodType.Select, false)]
public static User FindByName(String name)
{
if (name.IsNullOrEmpty()) return null;
// 单对象缓存
return Meta.SingleCache.GetItemWithSlaveKey(name) as User;
}
if (Meta.Count < 1000) return Meta.Cache.Entities.FirstOrDefault(e => e.Name.EqualIgnoreCase(name));
public static User FindByEmail(String email)
{
if (email.IsNullOrEmpty() || !email.Contains("@") || !email.Contains(".")) return null;
if (Meta.Count >= 1000)
return Find(__.Email, email);
else // 实体缓存
return Meta.Cache.Entities.FirstOrDefault(e => e.Email.EqualIgnoreCase(email));
// 单对象缓存
//return Meta.SingleCache[name];
}
#endregion
// 单对象缓存
return Meta.SingleCache.GetItemWithSlaveKey(name) as User;
}
#region 高级查询
public static IList<User> Search(Int32 ownerId, Boolean? enable, Boolean? isTeam, DateTime start, DateTime end, String key, PageParameter param)
{
// WhereExpression重载&和|运算符,作为And和Or的替代
// SearchWhereByKeys系列方法用于构建针对字符串字段的模糊搜索,第二个参数可指定要搜索的字段
var exp = SearchWhereByKeys(key, null, null);
public static User FindByEmail(String email)
{
if (email.IsNullOrEmpty() || !email.Contains("@") || !email.Contains(".")) return null;
if (Meta.Count >= 1000)
return Find(__.Email, email);
else // 实体缓存
return Meta.Cache.Entities.FirstOrDefault(e => e.Email.EqualIgnoreCase(email));
// 单对象缓存
//return Meta.SingleCache[name];
}
#endregion
if (ownerId > 0) exp &= _.ID.In(UserTeam.SearchSql(ownerId));
if (enable != null) exp &= _.Enable == enable;
if (isTeam != null) exp &= _.IsTeam == isTeam;
#region 高级查询
public static IList<User> Search(Int32 ownerId, Boolean? enable, Boolean? isTeam, DateTime start, DateTime end, String key, PageParameter param)
{
// WhereExpression重载&和|运算符,作为And和Or的替代
// SearchWhereByKeys系列方法用于构建针对字符串字段的模糊搜索,第二个参数可指定要搜索的字段
var exp = SearchWhereByKeys(key, null, null);
exp &= _.LastLogin.Between(start, end);
if (ownerId > 0) exp &= _.ID.In(UserTeam.SearchSql(ownerId));
if (enable != null) exp &= _.Enable == enable;
if (isTeam != null) exp &= _.IsTeam == isTeam;
return FindAll(exp, param);
}
exp &= _.LastLogin.Between(start, end);
public static IList<User> SearchByName(String name, PageParameter param)
{
var exp = new WhereExpression();
exp &= _.IsTeam == false;
if (!name.IsNullOrEmpty()) exp &= _.Name.Contains(name);
return FindAll(exp, param);
}
return FindAll(exp, param);
}
public static IList<User> SearchByName(String name, PageParameter param)
{
var exp = new WhereExpression();
exp &= _.IsTeam == false;
if (!name.IsNullOrEmpty()) exp &= _.Name.Contains(name);
public static IList<User> SearchTeam(String name, PageParameter param)
{
var exp = new WhereExpression();
exp &= _.IsTeam == true;
if (!name.IsNullOrEmpty()) exp &= _.Name.Contains(name);
return FindAll(exp, param);
}
return FindAll(exp, param);
}
public static IList<User> SearchTeam(String name, PageParameter param)
{
var exp = new WhereExpression();
exp &= _.IsTeam == true;
if (!name.IsNullOrEmpty()) exp &= _.Name.Contains(name);
/// <summary>搜索用户,不包含团队</summary>
/// <param name="key"></param>
/// <param name="param"></param>
/// <returns></returns>
public static IList<User> SearchUser(String key, PageParameter param)
{
var exp = new WhereExpression();
exp &= _.IsTeam == false;
if (!key.IsNullOrEmpty()) exp &= _.Name.Contains(key) | _.Email.Contains(key);
return FindAll(exp, param);
}
return FindAll(exp, param);
}
#endregion
/// <summary>搜索用户,不包含团队</summary>
/// <param name="key"></param>
/// <param name="param"></param>
/// <returns></returns>
public static IList<User> SearchUser(String key, PageParameter param)
{
var exp = new WhereExpression();
exp &= _.IsTeam == false;
if (!key.IsNullOrEmpty()) exp &= _.Name.Contains(key) | _.Email.Contains(key);
#region 扩展操作
public override String ToString() => NickName ?? Name;
#endregion
return FindAll(exp, param);
}
#endregion
#region 业务
public static User Create(String name, String nickname, String password, String email, String description)
{
var user = User.FindByName(name);
if (user != null) throw new ArgumentException(_.Name.DisplayName + "已存在", __.Name);
#region 扩展操作
public override String ToString() => NickName ?? Name;
#endregion
user = User.FindByEmail(email);
if (user != null) throw new ArgumentException(_.Email.DisplayName + "已存在", __.Email);
#region 业务
public static User Create(String name, String nickname, String password, String email, String description)
user = new User
{
var user = User.FindByName(name);
if (user != null) throw new ArgumentException(_.Name.DisplayName + "已存在", __.Name);
user = User.FindByEmail(email);
if (user != null) throw new ArgumentException(_.Email.DisplayName + "已存在", __.Email);
Name = name,
NickName = nickname,
Email = email,
Enable = true,
};
user = new User
{
Name = name,
NickName = nickname,
Email = email,
Enable = true,
};
user.Save();
user.Save();
return user;
}
return user;
}
public static User CreateTeam(String name, String nickname, String description)
{
var user = FindByName(name);
if (user != null) throw new ArgumentException(_.Name.DisplayName + "已存在", __.Name);
public static User CreateTeam(String name, String nickname, String description)
user = new User
{
var user = FindByName(name);
if (user != null) throw new ArgumentException(_.Name.DisplayName + "已存在", __.Name);
Name = name,
NickName = nickname,
Enable = false,
IsTeam = true,
};
user = new User
{
Name = name,
NickName = nickname,
Enable = false,
IsTeam = true,
};
user.Save();
user.Save();
return user;
}
return user;
}
//public Boolean Login(String password)
//{
// var user = this;
// if (!user.Enable) return false;
//public Boolean Login(String password)
//{
// var user = this;
// if (!user.Enable) return false;
// // 清空密码后,任意密码可以登录,并成为新密码
// if (user.Password.IsNullOrEmpty())
// user.Password = password.MD5();
// else
// {
// if (user.Password != password.MD5()) return false;
// }
// // 清空密码后,任意密码可以登录,并成为新密码
// if (user.Password.IsNullOrEmpty())
// user.Password = password.MD5();
// else
// {
// if (user.Password != password.MD5()) return false;
// }
// user.Logins++;
// user.LastLogin = DateTime.Now;
// user.LastLoginIP = WebHelper.UserHost;
// user.Save();
// user.Logins++;
// user.LastLogin = DateTime.Now;
// user.LastLoginIP = WebHelper.UserHost;
// user.Save();
// return true;
//}
// return true;
//}
//public static User Check(String name, String pass)
//{
// var user = FindByName(name) ?? FindByEmail(name);
// if (user == null) return null;
//public static User Check(String name, String pass)
//{
// var user = FindByName(name) ?? FindByEmail(name);
// if (user == null) return null;
// if (!user.Enable) return null;
// if (user.Password != pass.MD5()) return null;
// if (!user.Enable) return null;
// if (user.Password != pass.MD5()) return null;
// return user;
//}
// return user;
//}
public static User GetOrAdd(Int32 linkid, String name, String mail)
{
var user = Find(_.LinkID == linkid);
user ??= FindByName(name);
user ??= FindByEmail(mail);
if (user != null)
{
if (user.LinkID > 0 && user.LinkID != linkid) throw new InvalidOperationException($"账号[{name}]被[{user.LinkID}]和[{linkid}]共用,请联系管理员");
public static User GetOrAdd(Int32 linkid, String name, String mail)
user.LinkID = linkid;
user.SaveAsync();
}
else
{
var user = Find(_.LinkID == linkid);
user ??= FindByName(name);
user ??= FindByEmail(mail);
if (user != null)
{
if (user.LinkID > 0 && user.LinkID != linkid) throw new InvalidOperationException($"账号[{name}]被[{user.LinkID}]和[{linkid}]共用,请联系管理员");
user = new User { LinkID = linkid, Name = name, Enable = true };
user.Insert();
}
user.LinkID = linkid;
user.SaveAsync();
}
else
{
user = new User { LinkID = linkid, Name = name, Enable = true };
user.Insert();
}
//user.Logins++;
//user.LastLogin = DateTime.Now;
//user.LastLoginIP = WebHelper.UserHost;
user.Save();
//user.Logins++;
//user.LastLogin = DateTime.Now;
//user.LastLoginIP = WebHelper.UserHost;
user.Save();
return user;
}
return user;
}
public static User GetOrAdd(IManageUser user)
{
if (user == null) return null;
public static User GetOrAdd(IManageUser user)
var mail = (user as IUser)?.Mail;
var u = GetOrAdd(user.ID, user.Name, mail);
if (u != null)
{
if (user == null) return null;
var mail = (user as IUser)?.Mail;
var u = GetOrAdd(user.ID, user.Name, mail);
if (u != null)
// 使用SSO资料覆盖本地资料
if (!user.NickName.IsNullOrEmpty()) u.NickName = user.NickName;
if (user is IUser au)
{
// 使用SSO资料覆盖本地资料
if (!user.NickName.IsNullOrEmpty()) u.NickName = user.NickName;
if (user is IUser au)
{
u.Email = au.Mail;
u.Email = au.Mail;
// 同步管理员
if (!u.IsAdmin && au.Roles.Any(e => e.Enable && e.IsSystem)) u.IsAdmin = true;
// 同步管理员
if (!u.IsAdmin && au.Roles.Any(e => e.Enable && e.IsSystem)) u.IsAdmin = true;
// 同步密码,使用魔方用户表作为唯一的密码保存地
if (!u.Password.IsNullOrEmpty())
{
au.Password = u.Password;
u.Password = null;
// 同步密码,使用魔方用户表作为唯一的密码保存地
if (!u.Password.IsNullOrEmpty())
{
au.Password = u.Password;
u.Password = null;
(au as IEntity).Update();
}
(au as IEntity).Update();
}
if (u.RegisterTime.Year < 1000) u.RegisterTime = u.CreateTime;
u.SaveAsync();
}
return u;
if (u.RegisterTime.Year < 1000) u.RegisterTime = u.CreateTime;
u.SaveAsync();
}
public Boolean Login(String ip)
{
var user = this;
return u;
}
user.Logins++;
user.LastLogin = DateTime.Now;
user.LastLoginIP = ip;
user.Save();
public Boolean Login(String ip)
{
var user = this;
return true;
}
user.Logins++;
user.LastLogin = DateTime.Now;
user.LastLoginIP = ip;
user.Save();
public static User Check(String name)
{
var user = FindByName(name) ?? FindByEmail(name);
if (user == null) return null;
return true;
}
if (!user.Enable) return null;
//if (user.Password != pass.MD5()) return null;
public static User Check(String name)
{
var user = FindByName(name) ?? FindByEmail(name);
if (user == null) return null;
return user;
}
#endregion
if (!user.Enable) return null;
//if (user.Password != pass.MD5()) return null;
return user;
}
#endregion
}
Loading…
Cancel
Save