请求`api/auth/token`接口。 如果用户不存在,创建写字楼版的用户以及用户角色中间表。在`aspnetusers`中增加一条记录,在`aspnetuserroles`增加一条记录,角色为`OfficeGuest`。 如果用户存在,会根据手机号去`projectuserroles`中找角色为`HdDg`的记录。 如果找到,说明是总部电工(办公楼版的超级管理员)。 ``` dto.ProjectId = currentUser.ProjectIds; dto.ProjectName = string.Empty; ``` 以上,可以看出,当原先的总部运营后台设置总部电工和项目关系时,实际上是保存在了`aspnetusers`表的`ProjectIds`字段中。而在新版的运营后台,与总部电工有关的项目要去`HdDgProject`中去找。 如果找不到,说明是办公楼版的其它角色用户。会去项目数据库的`CompanyUser`中去找当前用户的相关公司。 ``` var currentCompanyUsers = _companyUserRepo.GetCompanyUsersByUserIdAsync(currentUser.Id.ToString()).ToList(); ``` 也就是说,一个用户可以在不同的`Company`中。 以上,出现了`aspnetusers`, `aspnetuserroles`,``projectuserroles`,`companyuser` 这4张表。 ``` aspnetusers Id UserName ProjectIds aspnetuserroles UserId RoleId projectuserroles UserId RoleId ProjectId CompanyId companyuser CompanyId UserId RoleId RoleName IsAllowed: 是否允许新朋友加入 HasRole:是否具有角色 ``` 如果是手机端的用户:`13800000000` ``` aspnetusers Id:1 UserName:13800000000 ProjectIds aspnetuserroles UserId:1 RoleId:角色为OfficeGuest的aspnetroles的主键 ``` 如果总部运营后台添加了一个电工:13811111111 ``` aspnetusers Id:2 UserName:13811111111 ProjectIds: 9,10 aspnetuserroles UserId:2 RoleId:角色为HdDg的aspnetroles的主键 ``` 电工`13811111111`,打开`APP` ![](F:\SourceCodes\DDWiki\专题\后端\office6.png) 电工`13811111111`,点击某个项目,展示公司列表。 ![](F:\SourceCodes\DDWiki\专题\后端\office7.png) 电工`13811111111`,添加公司。 ![](F:\SourceCodes\DDWiki\专题\后端\office8.png) 对应的接口在`api/super/addUpdateCompany` ``` var newCompany = new Company(request.ProjectId, request.Name,request.LocationIds,request.IsAdmin, request.UserId); _companyRepo.Add(newCompany); await _companyRepo.UnitOfWork.SaveChangesAsync(); var myCompanyId = newCompany.Id.ToString();//新增公司ID //获取当前用户信息,并更新相应的用户权限表 var user = await _auth.GetUserByIdAsync(request.UserId); //添加用户 var rolestr = await _auth.CreatOfficeAdmin(user.Mobile, request.ProjectId, myCompanyId, user.UserName); string[] roleInfo = rolestr.Split(','); //添加公司用户 if (roleInfo.Length == 3) { CompanyUser newUser = new CompanyUser(myCompanyId, roleInfo[0], roleInfo[1], roleInfo[2]); _companyUser.Add(newUser); await _companyUser.UnitOfWork.SaveChangesAsync(); } ``` 数据库中对应的: ``` aspnetusers Id:2 UserName:13811111111 ProjectIds: 9,10 aspnetuserroles UserId:2 RoleId:角色为HdDg的aspnetroles的主键 projectuserroles UserId:2 RoleId:角色为HdDg的aspnetroles的主键 ProjectId:9 CompanyId:1 companyuser CompanyId:1 UserId:2 RoleId:角色为HdDg的aspnetroles的主键 RoleName:HdDg IsAllowed: false HasRole:true ``` 电工`13811111111`,点击"我的",点击项目管理。 ![](F:\SourceCodes\DDWiki\专题\后端\office1.png) 展示项目列表。其实对后端开发人员来说,项目列表就是`Company`列表。 ![](F:\SourceCodes\DDWiki\专题\后端\office2.png) 电工点击"邀请好友",展示二维码。目前角色为`OfficeGuest`的用户`13800000000`扫描二维码。 ![](F:\SourceCodes\DDWiki\专题\后端\office3.png) 目前角色为`OfficeGuest`的用户`13800000000`点击"加入该项目"。 ![](F:\SourceCodes\DDWiki\专题\后端\office4.png) 对应的接口在`api/mine/joinProject`中。 ``` var guestRole = await _auth.GetRoleByNameAsync(OfficeConstants.Office_Role_Guest); var ef = await _officeHelper.GetOfficeContextByProjectIdAsync(request.ProjectId); _companyUserRepo = new CompanyUserRepository(ef); //先检查这个用户是否已经在CompanyUser中有记录,因为用户可以多次扫码加入,这种情况就不在数据库中再添加记录了 if (_companyUserRepo.GetCompanyUsersByUserIdAsync(request.UserId).ToList().Any(t => t.CompanyId == request.CompanyId))//已在本公司中的用户无法再加入公司 result.Message = "用户已经加入该项目了"; else { //管理员不能扫码加入自己的项目 var AdminRole = await _auth.GetRoleByNameAsync(OfficeConstants.Office_Role_Admin); var companyAdmin = _companyUserRepo.GetUsersByCompanyId(request.CompanyId).FirstOrDefault(t => t.RoleId == AdminRole.Id); if (companyAdmin != null && companyAdmin.UserId == request.UserId) { result.Message = "管理员不能扫码加入自己管理的项目"; return await Task.FromResult(result); } //var newCompanyUser = new CompanyUser(request.CompanyId, request.UserId, guestRole.Id, guestRole.Name); var newCompanyUser = new CompanyUser(request.CompanyId, request.UserId); _companyUserRepo.Add(newCompanyUser); await _companyUserRepo.UnitOfWork.SaveChangesAsync(cancellationToken); } ``` 以上,排除了用户`13800000000`已经在`CompanyUser`中有记录,以及管理员不能扫码进入当前`Company`这两种情况,然后再`CompanyUser`中添加了一条记录。 ``` aspnetusers Id:1 UserName:13800000000 ProjectIds aspnetuserroles UserId:1 RoleId:角色为OfficeGuest的aspnetroles的主键 companyuser CompanyId:1 UserId:1 RoleId RoleName IsAllowed: HasRole:false ``` 电工`13811111111`,点击"新朋友"。 ![](F:\SourceCodes\DDWiki\专题\后端\office2.png) 展示新朋友列表。 ![](F:\SourceCodes\DDWiki\专题\后端\office5.png) 对应的接口在`api/mine/newFriends` ``` if (await _auth.IsOfficeSuperAdminAsync(request.UserId))//超级管理员 { var superAdminRole = await _auth.GetRoleByNameAsync(OfficeConstants.Office_Role_SuperAdmin); adminCompanyIds = companyUsers.Where(t => t.UserId == request.UserId && t.RoleId == superAdminRole.Id).Select(t => t.CompanyId).ToList(); } else//管理员 { //获取管理员角色的主键 var officeAdminRole = await _auth.GetRoleByNameAsync(OfficeConstants.Office_Role_Admin); //找出管理员所在的公司主键集合 adminCompanyIds = companyUsers.Where(t => t.UserId == request.UserId && t.RoleId == officeAdminRole.Id.ToString()).Select(t => t.CompanyId).ToList(); } companyUsers = companyUsers.Where(t => t.IsAllowed == false && adminCompanyIds.Any(x => x == t.CompanyId)).ToList(); foreach (var companyUser in companyUsers) { dto.Items.Add(HandleItem(companyUser, request, _companyRepo)); } dto.Items = dto.Items.OrderByDescending(t => DateTime.Parse(t.CreateTime)).ToList(); result.data = dto; ``` 点击"同意",对应的接口在:`api/mine/acceptNewFriend` ``` if (!_companyUserRepo.HasCompanyRole(request.ObjUserId, request.CompanyId, guestRole.Name))//保证多次扫码只加一次 { var companyUsers = _companyUserRepo.GetAll(); var currentCompanyUser = companyUsers.FirstOrDefault(t => t.CompanyId == request.CompanyId && t.UserId == request.ObjUserId);//肯定存在 currentCompanyUser.AcceptNewFriendNew(guestRole.Id,guestRole.Name); _companyUserRepo.Update(currentCompanyUser); await _companyUserRepo.UnitOfWork.SaveChangesAsync(cancellationToken); //TODO:需要保证事务的原子性、持久性、隔离性 //获取总部用户设置ProjectId await _auth.SetProjectIdForUserAsync(request.ObjUserId, request.ProjectId); await _auth.AddProjectUserRoleAsync(request.UserId, guestRole.Id, request.ProjectId, request.CompanyId); } ``` 数据库方面 ``` aspnetusers Id:1 UserName:13800000000 ProjectIds:9 aspnetuserroles UserId:1 RoleId:角色为OfficeGuest的aspnetroles的主键 companyuser CompanyId:1 UserId:1 RoleId:角色为OfficeGuest的aspnetuserroles主键 RoleName:OfficeGuest IsAllowed: true HasRole:true projectuserroles UserId:1 RoleId:角色为OfficeGuest的aspnetroles的主键 ProjectId:9 CompanyId:1 ``` 启用"设置为管理员" ![](F:\SourceCodes\DDWiki\专题\后端\office9.png) 点击`确定`按钮。对应的接口在:`api/mine/setUserRole`中。 ``` var ef = await _dbHelper.GetOfficeContextByProjectIdAsync(request.ProjectId); _companyUserRepo = new CompanyUserRepository(ef); var currentCompanyUser = _companyUserRepo.GetAll().FirstOrDefault(t => t.UserId == request.ObjectUserId && t.CompanyId == request.CompanyId); var currentRole = await _auth.GetRoleByNameAsync(request.RoleName); if(await _auth.IsOfficeSuperAdminAsync(request.UserId)|| request.RoleName != OfficeConstants.Office_Role_Admin)//超级管理员 { currentCompanyUser.ChangeRole(currentRole.Id, currentRole.Name); _companyUserRepo.Update(currentCompanyUser); await _companyUserRepo.UnitOfWork.SaveChangesAsync(cancellationToken); await _auth.UpdateProjectUserRoleByRoleNameAsync(currentRole.Id, request.ObjectUserId, request.ProjectId, request.CompanyId); } ``` 数据库方面 ``` aspnetusers Id:1 UserName:13800000000 ProjectIds:9 aspnetuserroles(似乎后来没用) UserId:1 RoleId:角色为OfficeGuest的aspnetroles的主键 companyuser CompanyId:1 UserId:1 RoleId:角色为OfficeAdmin的aspnetuserroles主键 RoleName:OfficeAdmin IsAllowed: true HasRole:true projectuserroles UserId:1 RoleId:角色为OfficeAdmin的aspnetuserroles主键 ProjectId:9 CompanyId:1 ``` 至此,总部电工为项目下的某个Company设置Company管理员成功。 另外还有 - Company的管理员设置新的管理员, - Company的管理员设置操作员