feat: 完成租户前端对接

This commit is contained in:
橙子
2024-02-08 19:48:35 +08:00
parent 39d472bdc8
commit 36f72c857d
12 changed files with 92 additions and 15 deletions

View File

@@ -100,9 +100,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AuditLogging.D
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AuditLogging.Domain.Shared", "module\audit-logging\Yi.Framework.AuditLogging.Domain.Shared\Yi.Framework.AuditLogging.Domain.Shared.csproj", "{9C8C3C53-3DCE-4516-867E-228858E61B26}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AuditLogging.Domain.Shared", "module\audit-logging\Yi.Framework.AuditLogging.Domain.Shared\Yi.Framework.AuditLogging.Domain.Shared.csproj", "{9C8C3C53-3DCE-4516-867E-228858E61B26}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.TenantManagement.Application", "module\tenant-management\Yi.Framework.TenantManagement.Application\Yi.Framework.TenantManagement.Application.csproj", "{17816837-E53B-486B-B796-53C601FE6CD9}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.TenantManagement.Application", "module\tenant-management\Yi.Framework.TenantManagement.Application\Yi.Framework.TenantManagement.Application.csproj", "{17816837-E53B-486B-B796-53C601FE6CD9}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.TenantManagement.Application.Contracts", "module\tenant-management\Yi.Framework.TenantManagement.Application.Contracts\Yi.Framework.TenantManagement.Application.Contracts.csproj", "{FA735055-CBDD-4EFD-B84B-85810DA1425E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.TenantManagement.Application.Contracts", "module\tenant-management\Yi.Framework.TenantManagement.Application.Contracts\Yi.Framework.TenantManagement.Application.Contracts.csproj", "{FA735055-CBDD-4EFD-B84B-85810DA1425E}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@@ -104,6 +104,7 @@ namespace Yi.Framework.Rbac.Application.Services
return new { Token = accessToken, RefreshToken = refreshToken }; return new { Token = accessToken, RefreshToken = refreshToken };
} }
/// <summary> /// <summary>
/// 刷新token /// 刷新token
/// </summary> /// </summary>

View File

@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using SqlSugar; using SqlSugar;
using TencentCloud.Tcr.V20190924.Models;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.EventBus.Local; using Volo.Abp.EventBus.Local;
@@ -85,6 +86,11 @@ namespace Yi.Framework.Rbac.Application.Services.System
[Permission("system:user:add")] [Permission("system:user:add")]
public async override Task<UserGetOutputDto> CreateAsync(UserCreateInputVo input) public async override Task<UserGetOutputDto> CreateAsync(UserCreateInputVo input)
{ {
if (input.UserName == UserConst.Admin || input.UserName == UserConst.TenantAdmin)
{
throw new UserFriendlyException(UserConst.Name_Not_Allowed);
}
if (string.IsNullOrEmpty(input.Password)) if (string.IsNullOrEmpty(input.Password))
{ {
throw new UserFriendlyException(UserConst.Login_Passworld_Error); throw new UserFriendlyException(UserConst.Login_Passworld_Error);
@@ -134,6 +140,10 @@ namespace Yi.Framework.Rbac.Application.Services.System
[Permission("system:user:update")] [Permission("system:user:update")]
public async override Task<UserGetOutputDto> UpdateAsync(Guid id, UserUpdateInputVo input) public async override Task<UserGetOutputDto> UpdateAsync(Guid id, UserUpdateInputVo input)
{ {
if (input.UserName == UserConst.Admin || input.UserName == UserConst.TenantAdmin)
{
throw new UserFriendlyException(UserConst.Name_Not_Allowed);
}
if (await _repository.IsAnyAsync(u => input.UserName!.Equals(u.UserName) && !id.Equals(u.Id))) if (await _repository.IsAnyAsync(u => input.UserName!.Equals(u.UserName) && !id.Equals(u.Id)))
{ {
throw new UserFriendlyException("用户已经存在,更新失败"); throw new UserFriendlyException("用户已经存在,更新失败");

View File

@@ -19,6 +19,7 @@ namespace Yi.Framework.Rbac.Domain.Shared.Consts
public const string State_Is_State = "该用户已被禁用,请联系管理员进行恢复"; public const string State_Is_State = "该用户已被禁用,请联系管理员进行恢复";
public const string No_Permission = "登录禁用!该用户分配无任何权限,无意义登录!"; public const string No_Permission = "登录禁用!该用户分配无任何权限,无意义登录!";
public const string No_Role = "登录禁用!该用户分配无任何角色,无意义登录!"; public const string No_Role = "登录禁用!该用户分配无任何角色,无意义登录!";
public const string Name_Not_Allowed = "用户名被禁止";
//子租户管理员 //子租户管理员
public const string Admin = "cc"; public const string Admin = "cc";

View File

@@ -13,6 +13,11 @@ namespace Yi.Framework.Rbac.Domain.Shared.Options
/// </summary> /// </summary>
public string AdminPassword { get; set; } = "123456"; public string AdminPassword { get; set; } = "123456";
/// <summary>
/// 租户超级管理员默认密码
/// </summary>
public string TenantAdminPassword { get; set; } = "123456";
/// <summary> /// <summary>
/// 是否开启登录验证码 /// 是否开启登录验证码
/// </summary> /// </summary>

View File

@@ -11,6 +11,7 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Services; using Volo.Abp.Domain.Services;
using Volo.Abp.EventBus.Local; using Volo.Abp.EventBus.Local;
using Volo.Abp.Security.Claims; using Volo.Abp.Security.Claims;
using Volo.Abp.Users;
using Yi.Framework.Core.Helper; using Yi.Framework.Core.Helper;
using Yi.Framework.Rbac.Domain.Entities; using Yi.Framework.Rbac.Domain.Entities;
using Yi.Framework.Rbac.Domain.Repositories; using Yi.Framework.Rbac.Domain.Repositories;
@@ -32,6 +33,7 @@ namespace Yi.Framework.Rbac.Domain.Managers
private readonly IUserRepository _repository; private readonly IUserRepository _repository;
private readonly ILocalEventBus _localEventBus; private readonly ILocalEventBus _localEventBus;
private readonly JwtOptions _jwtOptions; private readonly JwtOptions _jwtOptions;
private readonly RbacOptions _options;
private IHttpContextAccessor _httpContextAccessor; private IHttpContextAccessor _httpContextAccessor;
private UserManager _userManager; private UserManager _userManager;
private ISqlSugarRepository<RoleEntity> _roleRepository; private ISqlSugarRepository<RoleEntity> _roleRepository;
@@ -42,7 +44,8 @@ namespace Yi.Framework.Rbac.Domain.Managers
, ILocalEventBus localEventBus , ILocalEventBus localEventBus
, UserManager userManager , UserManager userManager
, IOptions<RefreshJwtOptions> refreshJwtOptions , IOptions<RefreshJwtOptions> refreshJwtOptions
, ISqlSugarRepository<RoleEntity> roleRepository) , ISqlSugarRepository<RoleEntity> roleRepository
, IOptions<RbacOptions> options)
{ {
_repository = repository; _repository = repository;
_httpContextAccessor = httpContextAccessor; _httpContextAccessor = httpContextAccessor;
@@ -51,6 +54,7 @@ namespace Yi.Framework.Rbac.Domain.Managers
_userManager = userManager; _userManager = userManager;
_roleRepository = roleRepository; _roleRepository = roleRepository;
_refreshJwtOptions = refreshJwtOptions.Value; _refreshJwtOptions = refreshJwtOptions.Value;
_options = options.Value;
} }
/// <summary> /// <summary>
@@ -215,7 +219,7 @@ namespace Yi.Framework.Rbac.Domain.Managers
dto.PermissionCodes?.ForEach(per => AddToClaim(claims, TokenTypeConst.Permission, per)); dto.PermissionCodes?.ForEach(per => AddToClaim(claims, TokenTypeConst.Permission, per));
dto.RoleCodes?.ForEach(role => AddToClaim(claims, AbpClaimTypes.Role, role)); dto.RoleCodes?.ForEach(role => AddToClaim(claims, AbpClaimTypes.Role, role));
} }
return claims; return claims;
} }

View File

@@ -25,6 +25,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.Repositories
/// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentNullException"></exception>
public async Task<UserRoleMenuDto> GetUserAllInfoAsync(Guid userId) public async Task<UserRoleMenuDto> GetUserAllInfoAsync(Guid userId)
{ {
var userRoleMenu = new UserRoleMenuDto(); var userRoleMenu = new UserRoleMenuDto();
//首先获取到该用户全部信息,导航到角色、菜单,(菜单需要去重,完全交给Set来处理即可) //首先获取到该用户全部信息,导航到角色、菜单,(菜单需要去重,完全交给Set来处理即可)

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
namespace Yi.Framework.TenantManagement.Application.Contracts.Dtos
{
public class TenantSelectOutputDto : EntityDto<Guid>
{
public string Name { get; set; }
}
}

View File

@@ -1,19 +1,11 @@
using System; using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using SqlSugar; using SqlSugar;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Uow;
using Yi.Framework.Ddd.Application; using Yi.Framework.Ddd.Application;
using Yi.Framework.SqlSugarCore.Abstractions; using Yi.Framework.SqlSugarCore.Abstractions;
using Yi.Framework.TenantManagement.Application.Contracts; using Yi.Framework.TenantManagement.Application.Contracts;
@@ -60,6 +52,17 @@ namespace Yi.Framework.TenantManagement.Application
return new PagedResultDto<TenantGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities)); return new PagedResultDto<TenantGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
} }
/// <summary>
/// 租户选项
/// </summary>
/// <returns></returns>
public async Task<List<TenantSelectOutputDto>> GetSelectAsync()
{
var entites = await _repository._DbQueryable.ToListAsync();
return entites.Select(x => new TenantSelectOutputDto { Id = x.Id, Name = x.Name }).ToList();
}
/// <summary> /// <summary>
/// 创建租户 /// 创建租户
/// </summary> /// </summary>
@@ -108,11 +111,11 @@ namespace Yi.Framework.TenantManagement.Application
/// <param name="id"></param> /// <param name="id"></param>
/// <returns></returns> /// <returns></returns>
[HttpPut("tenant/init/{id}")] [HttpPut("tenant/init/{id}")]
public async Task InitAsync([FromRoute]Guid id) public async Task InitAsync([FromRoute] Guid id)
{ {
using (CurrentTenant.Change(id)) using (CurrentTenant.Change(id))
{ {
await CodeFirst(this.LazyServiceProvider); await CodeFirst(this.LazyServiceProvider);
await _dataSeeder.SeedAsync(id); await _dataSeeder.SeedAsync(id);
} }

View File

@@ -10,6 +10,13 @@ export function listData(query) {
params: query params: query
}) })
} }
export function SelectData() {
return request({
url: '/tenant/select',
method: 'get'
})
}
// id查询 // id查询
export function getData(id) { export function getData(id) {

View File

@@ -40,6 +40,25 @@
<img :src="codeUrl" @click="getCode" class="login-code-img"/> <img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item>
<span>当前租户</span>
<el-select
v-model="tenantSelectedId"
class="m-2"
placeholder="租户选择"
style="width: 80%"
>
<el-option
v-for="item in tenantList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox> <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
<el-form-item style="width:100%;"> <el-form-item style="width:100%;">
<el-button <el-button
@@ -69,11 +88,14 @@ import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt"; import { encrypt, decrypt } from "@/utils/jsencrypt";
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import {SelectData as getTenantList} from '@/api/system/tenant'
import { ref } from "vue";
const userStore = useUserStore() const userStore = useUserStore()
const router = useRouter(); const router = useRouter();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const tenantSelectedId=ref('defalut');
const loginForm = ref({ const loginForm = ref({
username: "", username: "",
password: "", password: "",
@@ -95,6 +117,9 @@ const captchaEnabled = ref(true);
// 注册开关 // 注册开关
const register = ref(false); const register = ref(false);
const redirect = ref(undefined); const redirect = ref(undefined);
const tenantList=ref([]);
function handleLogin() { function handleLogin() {
proxy.$refs.loginRef.validate(valid => { proxy.$refs.loginRef.validate(valid => {
@@ -148,8 +173,14 @@ function getCookie() {
}; };
} }
async function getTenant()
{
const {data} =await getTenantList();
tenantList.value= [{name:"defalut"}, ...data];
}
getCode(); getCode();
getCookie(); getCookie();
getTenant();
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>