mirror of
https://github.com/ccmjga/zhilu-admin
synced 2026-04-08 14:37:38 +00:00
重构角色和权限相关DTO,替换RoleDto为RoleRespDto,并更新相关服务和控制器逻辑
This commit is contained in:
@@ -15,7 +15,6 @@ import com.zl.mjga.repository.UserRepository;
|
|||||||
import com.zl.mjga.service.IdentityAccessService;
|
import com.zl.mjga.service.IdentityAccessService;
|
||||||
import io.minio.MinioClient;
|
import io.minio.MinioClient;
|
||||||
import io.minio.PutObjectArgs;
|
import io.minio.PutObjectArgs;
|
||||||
import io.minio.errors.*;
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
@@ -118,7 +117,7 @@ public class IdentityAccessController {
|
|||||||
|
|
||||||
@PreAuthorize("hasAuthority(T(com.zl.mjga.model.urp.EPermission).WRITE_USER_ROLE_PERMISSION)")
|
@PreAuthorize("hasAuthority(T(com.zl.mjga.model.urp.EPermission).WRITE_USER_ROLE_PERMISSION)")
|
||||||
@GetMapping("/role")
|
@GetMapping("/role")
|
||||||
RoleDto queryRoleWithPermission(@RequestParam Long roleId) {
|
RoleRespDto queryRoleWithPermission(@RequestParam Long roleId) {
|
||||||
return identityAccessService.queryUniqueRoleWithPermission(roleId);
|
return identityAccessService.queryUniqueRoleWithPermission(roleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +144,7 @@ public class IdentityAccessController {
|
|||||||
@PreAuthorize("hasAuthority(T(com.zl.mjga.model.urp.EPermission).READ_USER_ROLE_PERMISSION)")
|
@PreAuthorize("hasAuthority(T(com.zl.mjga.model.urp.EPermission).READ_USER_ROLE_PERMISSION)")
|
||||||
@GetMapping("/roles")
|
@GetMapping("/roles")
|
||||||
@ResponseStatus(HttpStatus.OK)
|
@ResponseStatus(HttpStatus.OK)
|
||||||
PageResponseDto<List<RoleDto>> queryRoles(
|
PageResponseDto<List<RoleRespDto>> queryRoles(
|
||||||
@ModelAttribute PageRequestDto pageRequestDto, @ModelAttribute RoleQueryDto roleQueryDto) {
|
@ModelAttribute PageRequestDto pageRequestDto, @ModelAttribute RoleQueryDto roleQueryDto) {
|
||||||
return identityAccessService.pageQueryRole(pageRequestDto, roleQueryDto);
|
return identityAccessService.pageQueryRole(pageRequestDto, roleQueryDto);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.zl.mjga.dto.urp;
|
package com.zl.mjga.dto.urp;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@@ -7,8 +8,16 @@ import lombok.*;
|
|||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
public class PermissionRespDto {
|
public class PermissionRespDto {
|
||||||
|
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private Boolean isBound;
|
private Boolean isBound;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.zl.mjga.dto.urp;
|
package com.zl.mjga.dto.urp;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
@@ -8,10 +9,18 @@ import lombok.*;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
public class RoleDto {
|
public class RoleRespDto {
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private Boolean isBound;
|
private Boolean isBound;
|
||||||
|
|
||||||
@Builder.Default List<PermissionRespDto> permissions = new LinkedList<>();
|
@Builder.Default List<PermissionRespDto> permissions = new LinkedList<>();
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.zl.mjga.dto.urp;
|
package com.zl.mjga.dto.urp;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -13,7 +14,11 @@ import lombok.*;
|
|||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
public class UserRolePermissionDto {
|
public class UserRolePermissionDto {
|
||||||
|
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
||||||
@@ -21,9 +26,12 @@ public class UserRolePermissionDto {
|
|||||||
|
|
||||||
private String avatar;
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private Boolean enable;
|
private Boolean enable;
|
||||||
@Builder.Default private List<RoleDto> roles = new LinkedList<>();
|
|
||||||
|
|
||||||
|
@Builder.Default private List<RoleRespDto> roles = new LinkedList<>();
|
||||||
|
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private OffsetDateTime createTime;
|
private OffsetDateTime createTime;
|
||||||
|
|
||||||
public Set<PermissionRespDto> getPermissions() {
|
public Set<PermissionRespDto> getPermissions() {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import static org.jooq.impl.DSL.*;
|
|||||||
|
|
||||||
import com.zl.mjga.dto.PageRequestDto;
|
import com.zl.mjga.dto.PageRequestDto;
|
||||||
import com.zl.mjga.dto.urp.PermissionRespDto;
|
import com.zl.mjga.dto.urp.PermissionRespDto;
|
||||||
import com.zl.mjga.dto.urp.RoleDto;
|
import com.zl.mjga.dto.urp.RoleRespDto;
|
||||||
import com.zl.mjga.dto.urp.UserQueryDto;
|
import com.zl.mjga.dto.urp.UserQueryDto;
|
||||||
import com.zl.mjga.dto.urp.UserRolePermissionDto;
|
import com.zl.mjga.dto.urp.UserRolePermissionDto;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -102,7 +102,7 @@ public class UserRepository extends UserDao {
|
|||||||
r -> r.map((record) -> record.into(PermissionRespDto.class)))
|
r -> r.map((record) -> record.into(PermissionRespDto.class)))
|
||||||
.as("permissions"))
|
.as("permissions"))
|
||||||
.from(USER.role()))
|
.from(USER.role()))
|
||||||
.convertFrom(r -> r.map((record) -> record.into(RoleDto.class)))
|
.convertFrom(r -> r.map((record) -> record.into(RoleRespDto.class)))
|
||||||
.as("roles"))
|
.as("roles"))
|
||||||
.from(USER)
|
.from(USER)
|
||||||
.where(USER.ID.eq(userId))
|
.where(USER.ID.eq(userId))
|
||||||
|
|||||||
@@ -80,17 +80,17 @@ public class IdentityAccessService {
|
|||||||
return userRepository.fetchUniqueUserDtoWithNestedRolePermissionBy(userId);
|
return userRepository.fetchUniqueUserDtoWithNestedRolePermissionBy(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PageResponseDto<List<RoleDto>> pageQueryRole(
|
public PageResponseDto<List<RoleRespDto>> pageQueryRole(
|
||||||
PageRequestDto pageRequestDto, RoleQueryDto roleQueryDto) {
|
PageRequestDto pageRequestDto, RoleQueryDto roleQueryDto) {
|
||||||
Result<Record> roleRecords = roleRepository.pageFetchBy(pageRequestDto, roleQueryDto);
|
Result<Record> roleRecords = roleRepository.pageFetchBy(pageRequestDto, roleQueryDto);
|
||||||
if (roleRecords.isEmpty()) {
|
if (roleRecords.isEmpty()) {
|
||||||
return PageResponseDto.empty();
|
return PageResponseDto.empty();
|
||||||
}
|
}
|
||||||
List<RoleDto> roleDtoList =
|
List<RoleRespDto> roleRespDtoList =
|
||||||
roleRecords.stream()
|
roleRecords.stream()
|
||||||
.map(
|
.map(
|
||||||
record -> {
|
record -> {
|
||||||
return RoleDto.builder()
|
return RoleRespDto.builder()
|
||||||
.id(record.getValue("id", Long.class))
|
.id(record.getValue("id", Long.class))
|
||||||
.code(record.getValue("code", String.class))
|
.code(record.getValue("code", String.class))
|
||||||
.name(record.getValue("name", String.class))
|
.name(record.getValue("name", String.class))
|
||||||
@@ -103,17 +103,17 @@ public class IdentityAccessService {
|
|||||||
})
|
})
|
||||||
.toList();
|
.toList();
|
||||||
return new PageResponseDto<>(
|
return new PageResponseDto<>(
|
||||||
roleRecords.get(0).getValue("total_role", Integer.class), roleDtoList);
|
roleRecords.get(0).getValue("total_role", Integer.class), roleRespDtoList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable RoleDto queryUniqueRoleWithPermission(Long roleId) {
|
public @Nullable RoleRespDto queryUniqueRoleWithPermission(Long roleId) {
|
||||||
Result<Record> roleWithPermissionRecords = roleRepository.fetchUniqueRoleWithPermission(roleId);
|
Result<Record> roleWithPermissionRecords = roleRepository.fetchUniqueRoleWithPermission(roleId);
|
||||||
if (roleWithPermissionRecords.isEmpty()) {
|
if (roleWithPermissionRecords.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
RoleDto roleDto = createRbacDtoRolePart(roleWithPermissionRecords);
|
RoleRespDto roleRespDto = createRbacDtoRolePart(roleWithPermissionRecords);
|
||||||
setCurrentRolePermission(roleDto, roleWithPermissionRecords);
|
setCurrentRolePermission(roleRespDto, roleWithPermissionRecords);
|
||||||
return roleDto;
|
return roleRespDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PageResponseDto<List<PermissionRespDto>> pageQueryPermission(
|
public PageResponseDto<List<PermissionRespDto>> pageQueryPermission(
|
||||||
@@ -199,12 +199,12 @@ public class IdentityAccessService {
|
|||||||
.toList());
|
.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCurrentRolePermission(RoleDto roleDto, List<Record> roleResult) {
|
private void setCurrentRolePermission(RoleRespDto roleRespDto, List<Record> roleResult) {
|
||||||
if (roleResult.get(0).getValue(PERMISSION.ID) != null) {
|
if (roleResult.get(0).getValue(PERMISSION.ID) != null) {
|
||||||
roleResult.forEach(
|
roleResult.forEach(
|
||||||
(record) -> {
|
(record) -> {
|
||||||
PermissionRespDto permissionRespDto = createRbacDtoPermissionPart(record);
|
PermissionRespDto permissionRespDto = createRbacDtoPermissionPart(record);
|
||||||
roleDto.getPermissions().add(permissionRespDto);
|
roleRespDto.getPermissions().add(permissionRespDto);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,12 +217,12 @@ public class IdentityAccessService {
|
|||||||
return permissionRespDto;
|
return permissionRespDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RoleDto createRbacDtoRolePart(List<Record> roleResult) {
|
private RoleRespDto createRbacDtoRolePart(List<Record> roleResult) {
|
||||||
RoleDto roleDto = new RoleDto();
|
RoleRespDto roleRespDto = new RoleRespDto();
|
||||||
roleDto.setId(roleResult.get(0).getValue(ROLE.ID));
|
roleRespDto.setId(roleResult.get(0).getValue(ROLE.ID));
|
||||||
roleDto.setCode(roleResult.get(0).getValue(ROLE.CODE));
|
roleRespDto.setCode(roleResult.get(0).getValue(ROLE.CODE));
|
||||||
roleDto.setName(roleResult.get(0).getValue(ROLE.NAME));
|
roleRespDto.setName(roleResult.get(0).getValue(ROLE.NAME));
|
||||||
return roleDto;
|
return roleRespDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRoleDuplicate(String roleCode, String name) {
|
public boolean isRoleDuplicate(String roleCode, String name) {
|
||||||
|
|||||||
@@ -178,14 +178,14 @@ class UserRolePermissionMvcTest {
|
|||||||
stubRoleQueryDto.setRoleId(stubRoleId);
|
stubRoleQueryDto.setRoleId(stubRoleId);
|
||||||
stubRoleQueryDto.setRoleCode(stubRoleCode);
|
stubRoleQueryDto.setRoleCode(stubRoleCode);
|
||||||
stubRoleQueryDto.setRoleName(stubRoleName);
|
stubRoleQueryDto.setRoleName(stubRoleName);
|
||||||
RoleDto stubRoleDto = new RoleDto();
|
RoleRespDto stubRoleRespDto = new RoleRespDto();
|
||||||
stubRoleDto.setId(1L);
|
stubRoleRespDto.setId(1L);
|
||||||
stubRoleDto.setName(stubRoleName);
|
stubRoleRespDto.setName(stubRoleName);
|
||||||
stubRoleDto.setCode(stubRoleCode);
|
stubRoleRespDto.setCode(stubRoleCode);
|
||||||
stubRoleDto.setPermissions(
|
stubRoleRespDto.setPermissions(
|
||||||
List.of(new PermissionRespDto(1L, "9VWU1nmU89zEVH", "9VWU1nmU89zEVH", false)));
|
List.of(new PermissionRespDto(1L, "9VWU1nmU89zEVH", "9VWU1nmU89zEVH", false)));
|
||||||
when(identityAccessService.pageQueryRole(PageRequestDto.of(1, 5), stubRoleQueryDto))
|
when(identityAccessService.pageQueryRole(PageRequestDto.of(1, 5), stubRoleQueryDto))
|
||||||
.thenReturn(new PageResponseDto<>(1, List.of(stubRoleDto)));
|
.thenReturn(new PageResponseDto<>(1, List.of(stubRoleRespDto)));
|
||||||
|
|
||||||
mockMvc
|
mockMvc
|
||||||
.perform(
|
.perform(
|
||||||
|
|||||||
@@ -112,19 +112,19 @@ class UserRolePermissionUnitTest {
|
|||||||
DSL.field("total_user", Integer.class))
|
DSL.field("total_user", Integer.class))
|
||||||
.values(stubUserId2, stubUserName2, stubUserPassword2, true, null, 2));
|
.values(stubUserId2, stubUserName2, stubUserPassword2, true, null, 2));
|
||||||
UserRolePermissionDto mockUserRolePermissionDto1 = new UserRolePermissionDto();
|
UserRolePermissionDto mockUserRolePermissionDto1 = new UserRolePermissionDto();
|
||||||
RoleDto mockRoleDto = new RoleDto();
|
RoleRespDto mockRoleRespDto = new RoleRespDto();
|
||||||
mockRoleDto.setId(stubRoleId);
|
mockRoleRespDto.setId(stubRoleId);
|
||||||
mockRoleDto.setCode(stubRoleCode);
|
mockRoleRespDto.setCode(stubRoleCode);
|
||||||
mockRoleDto.setName(stubRoleName);
|
mockRoleRespDto.setName(stubRoleName);
|
||||||
PermissionRespDto permissionRespDto = new PermissionRespDto();
|
PermissionRespDto permissionRespDto = new PermissionRespDto();
|
||||||
permissionRespDto.setId(stubPermissionId);
|
permissionRespDto.setId(stubPermissionId);
|
||||||
permissionRespDto.setCode(stubPermissionCode);
|
permissionRespDto.setCode(stubPermissionCode);
|
||||||
permissionRespDto.setName(stubPermissionName);
|
permissionRespDto.setName(stubPermissionName);
|
||||||
mockRoleDto.getPermissions().add(permissionRespDto);
|
mockRoleRespDto.getPermissions().add(permissionRespDto);
|
||||||
mockUserRolePermissionDto1.setId(stubUserId1);
|
mockUserRolePermissionDto1.setId(stubUserId1);
|
||||||
mockUserRolePermissionDto1.setUsername(stubUserName1);
|
mockUserRolePermissionDto1.setUsername(stubUserName1);
|
||||||
mockUserRolePermissionDto1.setPassword(stubUserPassword1);
|
mockUserRolePermissionDto1.setPassword(stubUserPassword1);
|
||||||
mockUserRolePermissionDto1.getRoles().add(mockRoleDto);
|
mockUserRolePermissionDto1.getRoles().add(mockRoleRespDto);
|
||||||
|
|
||||||
UserRolePermissionDto mockUserRolePermissionDto2 = new UserRolePermissionDto();
|
UserRolePermissionDto mockUserRolePermissionDto2 = new UserRolePermissionDto();
|
||||||
mockUserRolePermissionDto2.setId(stubUserId2);
|
mockUserRolePermissionDto2.setId(stubUserId2);
|
||||||
@@ -202,7 +202,7 @@ class UserRolePermissionUnitTest {
|
|||||||
mockResult.setId(stubRoleId);
|
mockResult.setId(stubRoleId);
|
||||||
mockResult.setRoles(
|
mockResult.setRoles(
|
||||||
List.of(
|
List.of(
|
||||||
new RoleDto(
|
new RoleRespDto(
|
||||||
stubRoleId,
|
stubRoleId,
|
||||||
stubRoleName,
|
stubRoleName,
|
||||||
stubRoleCode,
|
stubRoleCode,
|
||||||
@@ -245,12 +245,12 @@ class UserRolePermissionUnitTest {
|
|||||||
when(roleRepository.pageFetchBy(any(PageRequestDto.class), any(RoleQueryDto.class)))
|
when(roleRepository.pageFetchBy(any(PageRequestDto.class), any(RoleQueryDto.class)))
|
||||||
.thenReturn(mockRoleResult);
|
.thenReturn(mockRoleResult);
|
||||||
RoleQueryDto roleQueryDto = new RoleQueryDto();
|
RoleQueryDto roleQueryDto = new RoleQueryDto();
|
||||||
PageResponseDto<List<RoleDto>> pageResult =
|
PageResponseDto<List<RoleRespDto>> pageResult =
|
||||||
identityAccessService.pageQueryRole(PageRequestDto.of(1, 5), roleQueryDto);
|
identityAccessService.pageQueryRole(PageRequestDto.of(1, 5), roleQueryDto);
|
||||||
assertThat(pageResult.getTotal()).isEqualTo(0L);
|
assertThat(pageResult.getTotal()).isEqualTo(0L);
|
||||||
|
|
||||||
roleQueryDto.setUserId(1L);
|
roleQueryDto.setUserId(1L);
|
||||||
PageResponseDto<List<RoleDto>> pageResult2 =
|
PageResponseDto<List<RoleRespDto>> pageResult2 =
|
||||||
identityAccessService.pageQueryRole(PageRequestDto.of(1, 5), roleQueryDto);
|
identityAccessService.pageQueryRole(PageRequestDto.of(1, 5), roleQueryDto);
|
||||||
assertThat(pageResult2.getTotal()).isEqualTo(0L);
|
assertThat(pageResult2.getTotal()).isEqualTo(0L);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,7 +289,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"*/*": {
|
"*/*": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/RoleDto"
|
"$ref": "#/components/schemas/RoleRespDto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1031,7 +1031,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"*/*": {
|
"*/*": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/PageResponseDtoListRoleDto"
|
"$ref": "#/components/schemas/PageResponseDtoListRoleRespDto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1718,6 +1718,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"PermissionRespDto": {
|
"PermissionRespDto": {
|
||||||
|
"required": [
|
||||||
|
"code",
|
||||||
|
"id",
|
||||||
|
"isBound",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -1735,7 +1741,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"RoleDto": {
|
"RoleRespDto": {
|
||||||
|
"required": [
|
||||||
|
"code",
|
||||||
|
"id",
|
||||||
|
"isBound",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -1760,6 +1772,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"UserRolePermissionDto": {
|
"UserRolePermissionDto": {
|
||||||
|
"required": [
|
||||||
|
"createTime",
|
||||||
|
"enable",
|
||||||
|
"id",
|
||||||
|
"username"
|
||||||
|
],
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -1782,7 +1800,7 @@
|
|||||||
"roles": {
|
"roles": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/components/schemas/RoleDto"
|
"$ref": "#/components/schemas/RoleRespDto"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"createTime": {
|
"createTime": {
|
||||||
@@ -1832,7 +1850,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"PageResponseDtoListRoleDto": {
|
"PageResponseDtoListRoleRespDto": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"total": {
|
"total": {
|
||||||
@@ -1842,7 +1860,7 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/components/schemas/RoleDto"
|
"$ref": "#/components/schemas/RoleRespDto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
36
frontend/src/api/types/schema.d.ts
vendored
36
frontend/src/api/types/schema.d.ts
vendored
@@ -779,29 +779,29 @@ export interface components {
|
|||||||
};
|
};
|
||||||
PermissionRespDto: {
|
PermissionRespDto: {
|
||||||
/** Format: int64 */
|
/** Format: int64 */
|
||||||
id?: number;
|
id: number;
|
||||||
code?: string;
|
code: string;
|
||||||
name?: string;
|
name: string;
|
||||||
isBound?: boolean;
|
isBound: boolean;
|
||||||
};
|
};
|
||||||
RoleDto: {
|
RoleRespDto: {
|
||||||
/** Format: int64 */
|
/** Format: int64 */
|
||||||
id?: number;
|
id: number;
|
||||||
code?: string;
|
code: string;
|
||||||
name?: string;
|
name: string;
|
||||||
isBound?: boolean;
|
isBound: boolean;
|
||||||
permissions?: components["schemas"]["PermissionRespDto"][];
|
permissions?: components["schemas"]["PermissionRespDto"][];
|
||||||
};
|
};
|
||||||
UserRolePermissionDto: {
|
UserRolePermissionDto: {
|
||||||
/** Format: int64 */
|
/** Format: int64 */
|
||||||
id?: number;
|
id: number;
|
||||||
username?: string;
|
username: string;
|
||||||
password?: string;
|
password?: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
enable?: boolean;
|
enable: boolean;
|
||||||
roles?: components["schemas"]["RoleDto"][];
|
roles?: components["schemas"]["RoleRespDto"][];
|
||||||
/** Format: date-time */
|
/** Format: date-time */
|
||||||
createTime?: string;
|
createTime: string;
|
||||||
permissions?: components["schemas"]["PermissionRespDto"][];
|
permissions?: components["schemas"]["PermissionRespDto"][];
|
||||||
};
|
};
|
||||||
RoleQueryDto: {
|
RoleQueryDto: {
|
||||||
@@ -815,10 +815,10 @@ export interface components {
|
|||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
bindState?: "BIND" | "UNBIND" | "ALL";
|
bindState?: "BIND" | "UNBIND" | "ALL";
|
||||||
};
|
};
|
||||||
PageResponseDtoListRoleDto: {
|
PageResponseDtoListRoleRespDto: {
|
||||||
/** Format: int64 */
|
/** Format: int64 */
|
||||||
total?: number;
|
total?: number;
|
||||||
data?: components["schemas"]["RoleDto"][];
|
data?: components["schemas"]["RoleRespDto"][];
|
||||||
};
|
};
|
||||||
PermissionQueryDto: {
|
PermissionQueryDto: {
|
||||||
/** Format: int64 */
|
/** Format: int64 */
|
||||||
@@ -1113,7 +1113,7 @@ export interface operations {
|
|||||||
[name: string]: unknown;
|
[name: string]: unknown;
|
||||||
};
|
};
|
||||||
content: {
|
content: {
|
||||||
"*/*": components["schemas"]["RoleDto"];
|
"*/*": components["schemas"]["RoleRespDto"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -1750,7 +1750,7 @@ export interface operations {
|
|||||||
[name: string]: unknown;
|
[name: string]: unknown;
|
||||||
};
|
};
|
||||||
content: {
|
content: {
|
||||||
"*/*": components["schemas"]["PageResponseDtoListRoleDto"];
|
"*/*": components["schemas"]["PageResponseDtoListRoleRespDto"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { computed } from "vue";
|
|||||||
const {
|
const {
|
||||||
src = "",
|
src = "",
|
||||||
alt = "用户头像",
|
alt = "用户头像",
|
||||||
size = "md"
|
size = "md",
|
||||||
} = defineProps<{
|
} = defineProps<{
|
||||||
src?: string;
|
src?: string;
|
||||||
alt?: string;
|
alt?: string;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<nav class="flex mb-4" aria-label="Breadcrumb">
|
<nav class="flex mb-4" aria-label="Breadcrumb">
|
||||||
<ol class="inline-flex items-center space-x-1 sm:space-x-2 text-sm">
|
<ol class="inline-flex items-center space-x-1 sm:space-x-2 text-sm">
|
||||||
<li class="inline-flex items-center">
|
<li class="inline-flex items-center">
|
||||||
<RouterLink :to="{ name: RouteName.HOME }"
|
<RouterLink :to="Routes.HOME.fullPath()"
|
||||||
class="inline-flex items-center font-medium text-gray-500 hover:text-blue-600">
|
class="inline-flex items-center font-medium text-gray-500 hover:text-blue-600">
|
||||||
<svg class="w-3.5 h-3.5 mr-1.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
|
<svg class="w-3.5 h-3.5 mr-1.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
|
||||||
viewBox="0 0 20 20">
|
viewBox="0 0 20 20">
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RouteName } from "@/router/constants";
|
import { Routes } from "@/router/constants";
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import type { RouteLocationRaw } from "vue-router";
|
import type { RouteLocationRaw } from "vue-router";
|
||||||
|
|
||||||
|
|||||||
@@ -53,14 +53,14 @@
|
|||||||
<li>
|
<li>
|
||||||
<button @click="() => {
|
<button @click="() => {
|
||||||
userDropDownMenu?.toggle()
|
userDropDownMenu?.toggle()
|
||||||
router.push(`${RoutePath.DASHBOARD}/${RoutePath.SETTINGS}`)
|
router.push(Routes.SETTINGS.fullPath())
|
||||||
}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 "
|
}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 "
|
||||||
role="menuitem">Settings</button>
|
role="menuitem">Settings</button>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<button @click="() => {
|
<button @click="() => {
|
||||||
userDropDownMenu?.toggle()
|
userDropDownMenu?.toggle()
|
||||||
router.push(RouteName.USERVIEW)
|
router.push(Routes.USERVIEW.withParams({}))
|
||||||
}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 "
|
}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 "
|
||||||
role="menuitem">Dashboard</button>
|
role="menuitem">Dashboard</button>
|
||||||
</li>
|
</li>
|
||||||
@@ -93,7 +93,7 @@ import { Dropdown, type DropdownInterface, initFlowbite } from "flowbite";
|
|||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import useUserAuth from "../composables/auth/useUserAuth";
|
import useUserAuth from "../composables/auth/useUserAuth";
|
||||||
import { RouteName, RoutePath } from "../router/constants";
|
import { Routes } from "../router/constants";
|
||||||
import Avatar from "./Avatar.vue";
|
import Avatar from "./Avatar.vue";
|
||||||
import AiChatIcon from "./icons/AiChatIcon.vue";
|
import AiChatIcon from "./icons/AiChatIcon.vue";
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ const { signOut } = useUserAuth();
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const handleLogoutClick = () => {
|
const handleLogoutClick = () => {
|
||||||
signOut();
|
signOut();
|
||||||
router.push(RoutePath.LOGIN);
|
router.push(Routes.LOGIN.path);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ import type { components } from "../api/types/schema";
|
|||||||
const alertStore = useAlertStore();
|
const alertStore = useAlertStore();
|
||||||
|
|
||||||
const { role, onSubmit } = defineProps<{
|
const { role, onSubmit } = defineProps<{
|
||||||
role?: components["schemas"]["RoleDto"];
|
role?: components["schemas"]["RoleRespDto"];
|
||||||
closeModal: () => void;
|
closeModal: () => void;
|
||||||
onSubmit: (data: RoleUpsertModel) => Promise<void>;
|
onSubmit: (data: RoleUpsertModel) => Promise<void>;
|
||||||
}>();
|
}>();
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RoutePath } from "@/router/constants";
|
import { Routes } from "@/router/constants";
|
||||||
import { initFlowbite } from "flowbite";
|
import { initFlowbite } from "flowbite";
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { RouterLink, useRoute } from "vue-router";
|
import { RouterLink, useRoute } from "vue-router";
|
||||||
@@ -73,42 +73,42 @@ defineExpose({
|
|||||||
const menuItems = [
|
const menuItems = [
|
||||||
{
|
{
|
||||||
title: "用户管理",
|
title: "用户管理",
|
||||||
path: `${RoutePath.DASHBOARD}/${RoutePath.USERVIEW}`,
|
path: Routes.USERVIEW.fullPath(),
|
||||||
icon: UsersIcon,
|
icon: UsersIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "角色管理",
|
title: "角色管理",
|
||||||
path: `${RoutePath.DASHBOARD}/${RoutePath.ROLEVIEW}`,
|
path: Routes.ROLEVIEW.fullPath(),
|
||||||
icon: RoleIcon,
|
icon: RoleIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "权限管理",
|
title: "权限管理",
|
||||||
path: `${RoutePath.DASHBOARD}/${RoutePath.PERMISSIONVIEW}`,
|
path: Routes.PERMISSIONVIEW.fullPath(),
|
||||||
icon: PermissionIcon,
|
icon: PermissionIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "部门管理",
|
title: "部门管理",
|
||||||
path: `${RoutePath.DASHBOARD}/${RoutePath.DEPARTMENTVIEW}`,
|
path: Routes.DEPARTMENTVIEW.fullPath(),
|
||||||
icon: DepartmentIcon,
|
icon: DepartmentIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "岗位管理",
|
title: "岗位管理",
|
||||||
path: `${RoutePath.DASHBOARD}/${RoutePath.POSITIONVIEW}`,
|
path: Routes.POSITIONVIEW.fullPath(),
|
||||||
icon: PositionIcon,
|
icon: PositionIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "个人中心",
|
title: "个人中心",
|
||||||
path: `${RoutePath.DASHBOARD}/${RoutePath.SETTINGS}`,
|
path: Routes.SETTINGS.fullPath(),
|
||||||
icon: SettingsIcon,
|
icon: SettingsIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "定时任务",
|
title: "定时任务",
|
||||||
path: `${RoutePath.DASHBOARD}/${RoutePath.SCHEDULERVIEW}`,
|
path: Routes.SCHEDULERVIEW.fullPath(),
|
||||||
icon: SchedulerIcon,
|
icon: SchedulerIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "大模型管理",
|
title: "大模型管理",
|
||||||
path: `${RoutePath.DASHBOARD}/${RoutePath.LLMCONFIGVIEW}`,
|
path: Routes.LLMCONFIGVIEW.fullPath(),
|
||||||
icon: LlmConfigIcon,
|
icon: LlmConfigIcon,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import type { components } from "../../api/types/schema";
|
|||||||
|
|
||||||
export const useRolesQuery = () => {
|
export const useRolesQuery = () => {
|
||||||
const total = ref<number>(0);
|
const total = ref<number>(0);
|
||||||
const roles = ref<components["schemas"]["RoleDto"][]>();
|
const roles = ref<components["schemas"]["RoleRespDto"][]>();
|
||||||
const roleWithDetail = ref<components["schemas"]["RoleDto"]>();
|
const roleWithDetail = ref<components["schemas"]["RoleRespDto"]>();
|
||||||
|
|
||||||
const getRoleWithDetail = async (roleId: number) => {
|
const getRoleWithDetail = async (roleId: number) => {
|
||||||
const { data } = await client.GET("/iam/role", {
|
const { data } = await client.GET("/iam/role", {
|
||||||
|
|||||||
@@ -1,56 +1,156 @@
|
|||||||
export enum RoutePath {
|
import type { RouteLocationRaw } from "vue-router";
|
||||||
HOME = "/",
|
|
||||||
LOGIN = "/login",
|
|
||||||
DASHBOARD = "/dashboard",
|
|
||||||
GLOBAL_NOTFOUND = "/:pathMatch(.*)*",
|
|
||||||
NOTFOUND = ":pathMatch(.*)*",
|
|
||||||
OVERVIEW = "overview",
|
|
||||||
USERVIEW = "users",
|
|
||||||
ROLEVIEW = "roles",
|
|
||||||
BINDROLEVIEW = "bind-roles/:userId",
|
|
||||||
BINDPERMISSIONVIEW = "bind-permissions/:roleId",
|
|
||||||
BINDDEPARTMENTVIEW = "bind-departments/:userId",
|
|
||||||
BINDPOSITIONVIEW = "bind-positions/:userId",
|
|
||||||
PERMISSIONVIEW = "permissions",
|
|
||||||
DEPARTMENTVIEW = "departments",
|
|
||||||
POSITIONVIEW = "positions",
|
|
||||||
CREATEUSERVIEW = "create-user",
|
|
||||||
LLMCONFIGVIEW = "llm/config",
|
|
||||||
SCHEDULERVIEW = "scheduler",
|
|
||||||
UPSERTUSERVIEW = "upsert-user",
|
|
||||||
UPSERTROLEVIEW = "upsert-role",
|
|
||||||
UPSERTPERMISSIONVIEW = "upsert-permission",
|
|
||||||
UPSERTDEPARTMENTVIEW = "upsert-department",
|
|
||||||
UPSERTPOSITIONVIEW = "upsert-position",
|
|
||||||
SETTINGS = "settings",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum RouteName {
|
export type RouteConfig = {
|
||||||
HOME = "home",
|
path: string;
|
||||||
LOGIN = "login",
|
name: string;
|
||||||
DASHBOARD = "dashboard",
|
fullPath: () => string;
|
||||||
OVERVIEW = "overview",
|
withParams: <T extends Record<string, string | number>>(
|
||||||
USERVIEW = "users",
|
params: T,
|
||||||
ROLEVIEW = "roles",
|
) => RouteLocationRaw;
|
||||||
BINDROLEVIEW = "bind-roles",
|
};
|
||||||
BINDPERMISSIONVIEW = "bind-permissions",
|
|
||||||
BINDDEPARTMENTVIEW = "bind-departments",
|
// 基础路由
|
||||||
BINDPOSITIONVIEW = "bind-positions",
|
export const BaseRoutes = {
|
||||||
PERMISSIONVIEW = "permissions",
|
HOME: {
|
||||||
DEPARTMENTVIEW = "departments",
|
path: "/",
|
||||||
POSITIONVIEW = "positions",
|
name: "home",
|
||||||
CREATEUSERVIEW = "create-user",
|
fullPath: () => "/",
|
||||||
LLMCONFIGVIEW = "llm/config",
|
withParams: () => ({ name: "home" }),
|
||||||
SCHEDULERVIEW = "scheduler",
|
},
|
||||||
UPSERTUSERVIEW = "upsert-user",
|
LOGIN: {
|
||||||
UPSERTROLEVIEW = "upsert-role",
|
path: "/login",
|
||||||
UPSERTPERMISSIONVIEW = "upsert-permission",
|
name: "login",
|
||||||
UPSERTDEPARTMENTVIEW = "upsert-department",
|
fullPath: () => "/login",
|
||||||
UPSERTPOSITIONVIEW = "upsert-position",
|
withParams: () => ({ name: "login" }),
|
||||||
SETTINGS = "settings",
|
},
|
||||||
NOTFOUND = "notfound",
|
DASHBOARD: {
|
||||||
GLOBAL_NOTFOUND = "global-notfound",
|
path: "/dashboard",
|
||||||
}
|
name: "dashboard",
|
||||||
|
fullPath: () => "/dashboard",
|
||||||
|
withParams: () => ({ name: "dashboard" }),
|
||||||
|
},
|
||||||
|
NOTFOUND: {
|
||||||
|
path: ":pathMatch(.*)*",
|
||||||
|
name: "notfound",
|
||||||
|
fullPath: () => "/dashboard/:pathMatch(.*)*",
|
||||||
|
withParams: () => ({ name: "notfound" }),
|
||||||
|
},
|
||||||
|
GLOBAL_NOTFOUND: {
|
||||||
|
path: "/:pathMatch(.*)*",
|
||||||
|
name: "global-notfound",
|
||||||
|
fullPath: () => "/:pathMatch(.*)*",
|
||||||
|
withParams: () => ({ name: "global-notfound" }),
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
// 仪表盘子路由
|
||||||
|
export const DashboardRoutes = {
|
||||||
|
OVERVIEW: {
|
||||||
|
path: "overview",
|
||||||
|
name: "overview",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/overview`,
|
||||||
|
withParams: () => ({ name: "overview" }),
|
||||||
|
},
|
||||||
|
SETTINGS: {
|
||||||
|
path: "settings",
|
||||||
|
name: "settings",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/settings`,
|
||||||
|
withParams: () => ({ name: "settings" }),
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
// 用户管理相关路由
|
||||||
|
export const UserRoutes = {
|
||||||
|
USERVIEW: {
|
||||||
|
path: "users",
|
||||||
|
name: "users",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/users`,
|
||||||
|
withParams: () => ({ name: "users" }),
|
||||||
|
},
|
||||||
|
ROLEVIEW: {
|
||||||
|
path: "roles",
|
||||||
|
name: "roles",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/roles`,
|
||||||
|
withParams: () => ({ name: "roles" }),
|
||||||
|
},
|
||||||
|
BINDROLEVIEW: {
|
||||||
|
path: "bind-roles/:userId",
|
||||||
|
name: "bind-roles",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/bind-roles/:userId`,
|
||||||
|
withParams: <T extends { userId: string | number }>(params: T) => ({
|
||||||
|
name: "bind-roles",
|
||||||
|
params: { userId: params.userId.toString() },
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
BINDPERMISSIONVIEW: {
|
||||||
|
path: "bind-permissions/:roleId",
|
||||||
|
name: "bind-permissions",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/bind-permissions/:roleId`,
|
||||||
|
withParams: <T extends { roleId: string | number }>(params: T) => ({
|
||||||
|
name: "bind-permissions",
|
||||||
|
params: { roleId: params.roleId.toString() },
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
BINDDEPARTMENTVIEW: {
|
||||||
|
path: "bind-departments/:userId",
|
||||||
|
name: "bind-departments",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/bind-departments/:userId`,
|
||||||
|
withParams: <T extends { userId: string | number }>(params: T) => ({
|
||||||
|
name: "bind-departments",
|
||||||
|
params: { userId: params.userId.toString() },
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
BINDPOSITIONVIEW: {
|
||||||
|
path: "bind-positions/:userId",
|
||||||
|
name: "bind-positions",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/bind-positions/:userId`,
|
||||||
|
withParams: <T extends { userId: string | number }>(params: T) => ({
|
||||||
|
name: "bind-positions",
|
||||||
|
params: { userId: params.userId.toString() },
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
PERMISSIONVIEW: {
|
||||||
|
path: "permissions",
|
||||||
|
name: "permissions",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/permissions`,
|
||||||
|
withParams: () => ({ name: "permissions" }),
|
||||||
|
},
|
||||||
|
DEPARTMENTVIEW: {
|
||||||
|
path: "departments",
|
||||||
|
name: "departments",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/departments`,
|
||||||
|
withParams: () => ({ name: "departments" }),
|
||||||
|
},
|
||||||
|
POSITIONVIEW: {
|
||||||
|
path: "positions",
|
||||||
|
name: "positions",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/positions`,
|
||||||
|
withParams: () => ({ name: "positions" }),
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
// AI相关路由
|
||||||
|
export const AiRoutes = {
|
||||||
|
LLMCONFIGVIEW: {
|
||||||
|
path: "llm/config",
|
||||||
|
name: "llm/config",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/llm/config`,
|
||||||
|
withParams: () => ({ name: "llm/config" }),
|
||||||
|
},
|
||||||
|
SCHEDULERVIEW: {
|
||||||
|
path: "scheduler",
|
||||||
|
name: "scheduler",
|
||||||
|
fullPath: () => `${BaseRoutes.DASHBOARD.path}/scheduler`,
|
||||||
|
withParams: () => ({ name: "scheduler" }),
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const Routes = {
|
||||||
|
...BaseRoutes,
|
||||||
|
...DashboardRoutes,
|
||||||
|
...UserRoutes,
|
||||||
|
...AiRoutes,
|
||||||
|
} as const;
|
||||||
|
|
||||||
export enum ERole {
|
export enum ERole {
|
||||||
ADMIN = "ADMIN",
|
ADMIN = "ADMIN",
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
import useUserStore from "@/composables/store/useUserStore";
|
import useUserStore from "@/composables/store/useUserStore";
|
||||||
import type { NavigationGuard, Router } from "vue-router";
|
import type { NavigationGuard, Router } from "vue-router";
|
||||||
import type { RouteMeta } from "../types/router";
|
import type { RouteMeta } from "../types/router";
|
||||||
import { RoutePath } from "./constants";
|
import { Routes } from "./constants";
|
||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
|
||||||
|
|
||||||
export const authGuard: NavigationGuard = (to) => {
|
export const authGuard: NavigationGuard = (to) => {
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
if (to.meta.requiresAuth && !userStore.user) {
|
if (to.meta.requiresAuth && !userStore.user) {
|
||||||
return {
|
return {
|
||||||
path: RoutePath.LOGIN,
|
path: Routes.LOGIN.path,
|
||||||
query: { redirect: to.fullPath },
|
query: { redirect: to.fullPath },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (to.path === RoutePath.LOGIN && userStore.user) {
|
if (to.path === Routes.LOGIN.path && userStore.user) {
|
||||||
return { path: `${RoutePath.DASHBOARD}/${RoutePath.USERVIEW}` };
|
return { path: `${Routes.DASHBOARD.path}/${Routes.USERVIEW.path}` };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,20 +2,20 @@ import { createRouter, createWebHistory } from "vue-router";
|
|||||||
import type { RouteRecordRaw } from "vue-router";
|
import type { RouteRecordRaw } from "vue-router";
|
||||||
import { setupGuards } from "./guards";
|
import { setupGuards } from "./guards";
|
||||||
|
|
||||||
|
import { Routes } from "./constants";
|
||||||
import authRoutes from "./modules/auth";
|
import authRoutes from "./modules/auth";
|
||||||
import dashboardRoutes from "./modules/dashboard";
|
import dashboardRoutes from "./modules/dashboard";
|
||||||
import errorRoutes from "./modules/error";
|
import errorRoutes from "./modules/error";
|
||||||
import { RouteName, RoutePath } from "./constants";
|
|
||||||
|
|
||||||
const routes: RouteRecordRaw[] = [
|
const routes: RouteRecordRaw[] = [
|
||||||
dashboardRoutes,
|
dashboardRoutes,
|
||||||
...authRoutes,
|
...authRoutes,
|
||||||
...errorRoutes,
|
...errorRoutes,
|
||||||
{
|
{
|
||||||
path: RoutePath.HOME,
|
path: Routes.HOME.path,
|
||||||
name: RouteName.HOME,
|
name: Routes.HOME.name,
|
||||||
redirect: {
|
redirect: {
|
||||||
path: `${RoutePath.DASHBOARD}/${RoutePath.USERVIEW}`,
|
path: `${Routes.DASHBOARD.path}/${Routes.USERVIEW.path}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -27,7 +27,7 @@ const router = createRouter({
|
|||||||
|
|
||||||
router.onError((err) => {
|
router.onError((err) => {
|
||||||
console.error("router err:", err);
|
console.error("router err:", err);
|
||||||
router.push(RouteName.USERVIEW);
|
router.push(Routes.USERVIEW.name);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { RouteRecordRaw } from "vue-router";
|
import type { RouteRecordRaw } from "vue-router";
|
||||||
import { EPermission, RouteName, RoutePath } from "../constants";
|
import { EPermission, Routes } from "../constants";
|
||||||
|
|
||||||
const aiRoutes: RouteRecordRaw[] = [
|
const aiRoutes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: RoutePath.LLMCONFIGVIEW,
|
path: Routes.LLMCONFIGVIEW.path,
|
||||||
name: RouteName.LLMCONFIGVIEW,
|
name: Routes.LLMCONFIGVIEW.name,
|
||||||
component: () => import("@/views/LlmConfigView.vue"),
|
component: () => import("@/views/LlmConfigView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import type { RouteRecordRaw } from "vue-router";
|
import type { RouteRecordRaw } from "vue-router";
|
||||||
import { RouteName, RoutePath } from "../constants";
|
import { Routes } from "../constants";
|
||||||
|
|
||||||
const authRoutes: RouteRecordRaw[] = [
|
const authRoutes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: RoutePath.HOME,
|
path: Routes.HOME.path,
|
||||||
name: RouteName.HOME,
|
name: Routes.HOME.name,
|
||||||
redirect: {
|
redirect: {
|
||||||
name: RouteName.LOGIN,
|
name: Routes.LOGIN.name,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: RoutePath.LOGIN,
|
path: Routes.LOGIN.path,
|
||||||
name: RouteName.LOGIN,
|
name: Routes.LOGIN.name,
|
||||||
component: () => import("../../views/LoginView.vue"),
|
component: () => import("../../views/LoginView.vue"),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
import type { RouteRecordRaw } from "vue-router";
|
import type { RouteRecordRaw } from "vue-router";
|
||||||
import Dashboard from "../../components/Dashboard.vue";
|
import Dashboard from "../../components/Dashboard.vue";
|
||||||
import { EPermission, ERole, RouteName, RoutePath } from "../constants";
|
import { EPermission, ERole, Routes } from "../constants";
|
||||||
import userManagementRoutes from "./user";
|
|
||||||
import aiRoutes from "./ai";
|
import aiRoutes from "./ai";
|
||||||
|
import userManagementRoutes from "./user";
|
||||||
|
|
||||||
const dashboardRoutes: RouteRecordRaw = {
|
const dashboardRoutes: RouteRecordRaw = {
|
||||||
path: RoutePath.DASHBOARD,
|
path: Routes.DASHBOARD.path,
|
||||||
name: RouteName.DASHBOARD,
|
name: Routes.DASHBOARD.name,
|
||||||
component: Dashboard,
|
component: Dashboard,
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: RoutePath.OVERVIEW,
|
path: Routes.OVERVIEW.path,
|
||||||
name: RouteName.OVERVIEW,
|
name: Routes.OVERVIEW.name,
|
||||||
component: () => import("@/views/OverView.vue"),
|
component: () => import("@/views/OverView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: RoutePath.SETTINGS,
|
path: Routes.SETTINGS.path,
|
||||||
name: RouteName.SETTINGS,
|
name: Routes.SETTINGS.name,
|
||||||
component: () => import("@/views/SettingsView.vue"),
|
component: () => import("@/views/SettingsView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
@@ -31,13 +31,13 @@ const dashboardRoutes: RouteRecordRaw = {
|
|||||||
...userManagementRoutes,
|
...userManagementRoutes,
|
||||||
...aiRoutes,
|
...aiRoutes,
|
||||||
{
|
{
|
||||||
path: RoutePath.NOTFOUND,
|
path: Routes.NOTFOUND.path,
|
||||||
name: RouteName.NOTFOUND,
|
name: Routes.NOTFOUND.name,
|
||||||
component: () => import("@/views/NotFound.vue"),
|
component: () => import("@/views/NotFound.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: RoutePath.SCHEDULERVIEW,
|
path: Routes.SCHEDULERVIEW.path,
|
||||||
name: RouteName.SCHEDULERVIEW,
|
name: Routes.SCHEDULERVIEW.name,
|
||||||
component: () => import("@/views/SchedulerView.vue"),
|
component: () => import("@/views/SchedulerView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
@@ -45,8 +45,8 @@ const dashboardRoutes: RouteRecordRaw = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: RoutePath.DEPARTMENTVIEW,
|
path: Routes.DEPARTMENTVIEW.path,
|
||||||
name: RouteName.DEPARTMENTVIEW,
|
name: Routes.DEPARTMENTVIEW.name,
|
||||||
component: () => import("@/views/DepartmentView.vue"),
|
component: () => import("@/views/DepartmentView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
@@ -54,8 +54,8 @@ const dashboardRoutes: RouteRecordRaw = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: RoutePath.POSITIONVIEW,
|
path: Routes.POSITIONVIEW.path,
|
||||||
name: RouteName.POSITIONVIEW,
|
name: Routes.POSITIONVIEW.name,
|
||||||
component: () => import("@/views/PositionView.vue"),
|
component: () => import("@/views/PositionView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { RouteRecordRaw } from "vue-router";
|
import type { RouteRecordRaw } from "vue-router";
|
||||||
import { RouteName, RoutePath } from "../constants";
|
import { Routes } from "../constants";
|
||||||
|
|
||||||
const errorRoutes: RouteRecordRaw[] = [
|
const errorRoutes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: RoutePath.GLOBAL_NOTFOUND,
|
path: Routes.GLOBAL_NOTFOUND.path,
|
||||||
name: RouteName.GLOBAL_NOTFOUND,
|
name: Routes.GLOBAL_NOTFOUND.name,
|
||||||
component: () => import("../../views/NotFound.vue"),
|
component: () => import("../../views/NotFound.vue"),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { RouteRecordRaw } from "vue-router";
|
import type { RouteRecordRaw } from "vue-router";
|
||||||
import { EPermission, RouteName, RoutePath } from "../constants";
|
import { EPermission, Routes } from "../constants";
|
||||||
|
|
||||||
const userManagementRoutes: RouteRecordRaw[] = [
|
const userManagementRoutes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: RoutePath.USERVIEW,
|
path: Routes.USERVIEW.path,
|
||||||
name: RouteName.USERVIEW,
|
name: Routes.USERVIEW.name,
|
||||||
component: () => import("@/views/UserView.vue"),
|
component: () => import("@/views/UserView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
@@ -12,8 +12,8 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: RoutePath.ROLEVIEW,
|
path: Routes.ROLEVIEW.path,
|
||||||
name: RouteName.ROLEVIEW,
|
name: Routes.ROLEVIEW.name,
|
||||||
component: () => import("@/views/RoleView.vue"),
|
component: () => import("@/views/RoleView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
@@ -21,8 +21,8 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: RoutePath.BINDROLEVIEW,
|
path: Routes.BINDROLEVIEW.path,
|
||||||
name: RouteName.BINDROLEVIEW,
|
name: Routes.BINDROLEVIEW.name,
|
||||||
component: () => import("@/views/BindRoleView.vue"),
|
component: () => import("@/views/BindRoleView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
@@ -30,8 +30,8 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: RoutePath.BINDDEPARTMENTVIEW,
|
path: Routes.BINDDEPARTMENTVIEW.path,
|
||||||
name: RouteName.BINDDEPARTMENTVIEW,
|
name: Routes.BINDDEPARTMENTVIEW.name,
|
||||||
component: () => import("@/views/BindDepartmentView.vue"),
|
component: () => import("@/views/BindDepartmentView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
@@ -39,8 +39,8 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: RoutePath.BINDPERMISSIONVIEW,
|
path: Routes.BINDPERMISSIONVIEW.path,
|
||||||
name: RouteName.BINDPERMISSIONVIEW,
|
name: Routes.BINDPERMISSIONVIEW.name,
|
||||||
component: () => import("@/views/BindPermissionView.vue"),
|
component: () => import("@/views/BindPermissionView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
@@ -48,8 +48,8 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: RoutePath.PERMISSIONVIEW,
|
path: Routes.PERMISSIONVIEW.path,
|
||||||
name: RouteName.PERMISSIONVIEW,
|
name: Routes.PERMISSIONVIEW.name,
|
||||||
component: () => import("@/views/PermissionView.vue"),
|
component: () => import("@/views/PermissionView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
@@ -57,8 +57,8 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: RoutePath.BINDPOSITIONVIEW,
|
path: Routes.BINDPOSITIONVIEW.path,
|
||||||
name: RouteName.BINDPOSITIONVIEW,
|
name: Routes.BINDPOSITIONVIEW.name,
|
||||||
component: () => import("@/views/BindPositionView.vue"),
|
component: () => import("@/views/BindPositionView.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { ComponentPublicInstance } from "vue";
|
import type { ComponentPublicInstance } from "vue";
|
||||||
import type { Router } from "vue-router";
|
import type { Router } from "vue-router";
|
||||||
import { RoutePath } from "../router/constants";
|
|
||||||
import {
|
import {
|
||||||
ForbiddenError,
|
ForbiddenError,
|
||||||
InternalServerError,
|
InternalServerError,
|
||||||
@@ -9,6 +8,7 @@ import {
|
|||||||
UnAuthError,
|
UnAuthError,
|
||||||
} from "../types/error";
|
} from "../types/error";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { Routes } from "../router/constants";
|
||||||
|
|
||||||
const makeErrorHandler =
|
const makeErrorHandler =
|
||||||
(
|
(
|
||||||
@@ -31,7 +31,7 @@ const makeErrorHandler =
|
|||||||
});
|
});
|
||||||
} else if (err instanceof UnAuthError) {
|
} else if (err instanceof UnAuthError) {
|
||||||
signOut();
|
signOut();
|
||||||
router.push(RoutePath.LOGIN);
|
router.push(Routes.LOGIN.path);
|
||||||
showAlert({
|
showAlert({
|
||||||
level: "error",
|
level: "error",
|
||||||
content: err.message,
|
content: err.message,
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="px-2 sm:px-4 pt-6 sm:rounded-lg">
|
<div class="px-2 sm:px-4 pt-6 sm:rounded-lg">
|
||||||
<div class="mb-4 sm:mb-6 col-span-full">
|
<div class="mb-4 sm:mb-6 col-span-full">
|
||||||
<Breadcrumbs :names="['用户管理', '绑定部门']" :routes="[{ name: RouteName.USERVIEW }]" />
|
<Breadcrumbs :names="['用户管理', '绑定部门']" :routes="[Routes.USERVIEW.fullPath()]" />
|
||||||
<h1 class="text-xl sm:text-2xl mb-4 sm:mb-6 font-semibold text-gray-900">绑定部门</h1>
|
<h1 class="text-xl sm:text-2xl mb-4 sm:mb-6 font-semibold text-gray-900">绑定部门</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
||||||
@update:values="updateFilterValues">
|
@update:values="updateFilterValues">
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<div class="flex gap-x-2">
|
<div class="flex gap-x-2">
|
||||||
<TableButton variant="primary" @click="() => {
|
<TableButton variant="primary" @click="() => {
|
||||||
if (checkedDepartmentIds.length === 0) {
|
if (checkedDepartmentIds.length === 0) {
|
||||||
alertStore.showAlert({
|
alertStore.showAlert({
|
||||||
content: '没有选择部门',
|
content: '没有选择部门',
|
||||||
@@ -19,9 +19,9 @@
|
|||||||
departmentBindModal?.show();
|
departmentBindModal?.show();
|
||||||
}
|
}
|
||||||
}">
|
}">
|
||||||
绑定
|
绑定
|
||||||
</TableButton>
|
</TableButton>
|
||||||
<TableButton variant="danger" @click="() => {
|
<TableButton variant="danger" @click="() => {
|
||||||
if (checkedDepartmentIds.length === 0) {
|
if (checkedDepartmentIds.length === 0) {
|
||||||
alertStore.showAlert({
|
alertStore.showAlert({
|
||||||
content: '没有选择部门',
|
content: '没有选择部门',
|
||||||
@@ -31,59 +31,59 @@
|
|||||||
departmentUnbindModal?.show();
|
departmentUnbindModal?.show();
|
||||||
}
|
}
|
||||||
}">
|
}">
|
||||||
解绑
|
解绑
|
||||||
</TableButton>
|
</TableButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</TableFilterForm>
|
</TableFilterForm>
|
||||||
|
|
||||||
<!-- 移动端卡片布局 -->
|
<!-- 移动端卡片布局 -->
|
||||||
<div class="md:hidden space-y-4">
|
<div class="md:hidden space-y-4">
|
||||||
<MobileCardListWithCheckbox :items="departments || []" v-model="checkedDepartmentIds">
|
<MobileCardListWithCheckbox :items="departments || []" v-model="checkedDepartmentIds">
|
||||||
<template #title="{ item }">
|
<template #title="{ item }">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</template>
|
</template>
|
||||||
<template #status="{ item }">
|
<template #status="{ item }">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
||||||
<span class="text-sm">{{ item.isBound === true ? "已绑定" : "未绑定" }}</span>
|
<span class="text-sm">{{ item.isBound === true ? "已绑定" : "未绑定" }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #content="{ item }">
|
<template #content="{ item }">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-xs font-medium text-gray-600">上级部门</p>
|
<p class="text-xs font-medium text-gray-600">上级部门</p>
|
||||||
<p class="text-sm text-gray-900 mt-0.5">{{ !item.parentName ? '无' : item.parentName }}</p>
|
<p class="text-sm text-gray-900 mt-0.5">{{ !item.parentName ? '无' : item.parentName }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</MobileCardListWithCheckbox>
|
</MobileCardListWithCheckbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- PC端表格布局 -->
|
<!-- PC端表格布局 -->
|
||||||
<div class="hidden md:block">
|
<div class="hidden md:block">
|
||||||
<TableFormLayout :items="departments || []" :columns="columns" :hasCheckbox="true" v-model="checkedDepartmentIds"
|
<TableFormLayout :items="departments || []" :columns="columns" :hasCheckbox="true" v-model="checkedDepartmentIds"
|
||||||
@all-checked-change="allChecked = $event">
|
@all-checked-change="allChecked = $event">
|
||||||
<template #parentName="{ item }">
|
<template #parentName="{ item }">
|
||||||
{{ !item.parentName ? '无' : item.parentName }}
|
{{ !item.parentName ? '无' : item.parentName }}
|
||||||
</template>
|
</template>
|
||||||
<template #name="{ item }">
|
<template #name="{ item }">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</template>
|
</template>
|
||||||
<template #bindState="{ item }">
|
<template #bindState="{ item }">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
||||||
{{ item.isBound === true ? "已绑定" : "未绑定" }}
|
{{ item.isBound === true ? "已绑定" : "未绑定" }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</TableFormLayout>
|
</TableFormLayout>
|
||||||
</div>
|
</div>
|
||||||
<TablePagination :pageChange="handlePageChange" :total="total" />
|
<TablePagination :pageChange="handlePageChange" :total="total" />
|
||||||
<BindModal :id="'department-bind-modal'" :closeModal="() => {
|
<BindModal :id="'department-bind-modal'" :closeModal="() => {
|
||||||
departmentBindModal!.hide();
|
departmentBindModal!.hide();
|
||||||
}" :onSubmit="handleBindDepartmentSubmit" title="绑定选中的部门吗"></BindModal>
|
}" :onSubmit="handleBindDepartmentSubmit" title="绑定选中的部门吗"></BindModal>
|
||||||
<UnModal :id="'department-unbind-modal'" :closeModal="() => {
|
<UnModal :id="'department-unbind-modal'" :closeModal="() => {
|
||||||
departmentUnbindModal!.hide();
|
departmentUnbindModal!.hide();
|
||||||
}" :onSubmit="handleUnbindDepartmentSubmit" title="解绑选中的部门吗"></UnModal>
|
}" :onSubmit="handleUnbindDepartmentSubmit" title="解绑选中的部门吗"></UnModal>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ import TableFormLayout from "@/components/TableFormLayout.vue";
|
|||||||
import TablePagination from "@/components/TablePagination.vue";
|
import TablePagination from "@/components/TablePagination.vue";
|
||||||
import { useDepartmentQuery } from "@/composables/department/useDepartmentQuery";
|
import { useDepartmentQuery } from "@/composables/department/useDepartmentQuery";
|
||||||
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
||||||
import { RouteName } from "@/router/constants";
|
import { Routes } from "@/router/constants";
|
||||||
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||||
import { onMounted, reactive, ref, watch } from "vue";
|
import { onMounted, reactive, ref, watch } from "vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="px-2 sm:px-4 pt-6 sm:rounded-lg">
|
<div class="px-2 sm:px-4 pt-6 sm:rounded-lg">
|
||||||
<div class="mb-4 sm:mb-6 col-span-full">
|
<div class="mb-4 sm:mb-6 col-span-full">
|
||||||
<Breadcrumbs :names="['角色管理', '绑定权限']" :routes="[{ name: RouteName.ROLEVIEW }]" />
|
<Breadcrumbs :names="['角色管理', '绑定权限']" :routes="[Routes.ROLEVIEW.fullPath()]" />
|
||||||
<h1 class="text-xl sm:text-2xl mb-4 sm:mb-6 font-semibold text-gray-900">绑定权限</h1>
|
<h1 class="text-xl sm:text-2xl mb-4 sm:mb-6 font-semibold text-gray-900">绑定权限</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
||||||
@update:values="updateFilterValues">
|
@update:values="updateFilterValues">
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<div class="flex gap-x-2">
|
<div class="flex gap-x-2">
|
||||||
<TableButton variant="primary" @click="() => {
|
<TableButton variant="primary" @click="() => {
|
||||||
if (checkedPermissionIds.length === 0) {
|
if (checkedPermissionIds.length === 0) {
|
||||||
alertStore.showAlert({
|
alertStore.showAlert({
|
||||||
content: '没有选择权限',
|
content: '没有选择权限',
|
||||||
@@ -19,9 +19,9 @@
|
|||||||
permissionBindModal?.show();
|
permissionBindModal?.show();
|
||||||
}
|
}
|
||||||
}">
|
}">
|
||||||
绑定
|
绑定
|
||||||
</TableButton>
|
</TableButton>
|
||||||
<TableButton variant="danger" @click="() => {
|
<TableButton variant="danger" @click="() => {
|
||||||
if (checkedPermissionIds.length === 0) {
|
if (checkedPermissionIds.length === 0) {
|
||||||
alertStore.showAlert({
|
alertStore.showAlert({
|
||||||
content: '没有选择权限',
|
content: '没有选择权限',
|
||||||
@@ -31,59 +31,59 @@
|
|||||||
permissionUnbindModal?.show();
|
permissionUnbindModal?.show();
|
||||||
}
|
}
|
||||||
}">
|
}">
|
||||||
解绑
|
解绑
|
||||||
</TableButton>
|
</TableButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</TableFilterForm>
|
</TableFilterForm>
|
||||||
|
|
||||||
<!-- 移动端卡片布局 -->
|
<!-- 移动端卡片布局 -->
|
||||||
<div class="md:hidden space-y-4">
|
<div class="md:hidden space-y-4">
|
||||||
<MobileCardListWithCheckbox :items="permissions || []" v-model="checkedPermissionIds">
|
<MobileCardListWithCheckbox :items="permissions || []" v-model="checkedPermissionIds">
|
||||||
<template #title="{ item }">
|
<template #title="{ item }">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</template>
|
</template>
|
||||||
<template #status="{ item }">
|
<template #status="{ item }">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
||||||
<span class="text-sm">{{ item.isBound === true ? "已绑定" : "未绑定" }}</span>
|
<span class="text-sm">{{ item.isBound === true ? "已绑定" : "未绑定" }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #content="{ item }">
|
<template #content="{ item }">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-xs font-medium text-gray-600">权限编码</p>
|
<p class="text-xs font-medium text-gray-600">权限编码</p>
|
||||||
<p class="text-sm text-gray-900 mt-0.5">{{ item.code }}</p>
|
<p class="text-sm text-gray-900 mt-0.5">{{ item.code }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</MobileCardListWithCheckbox>
|
</MobileCardListWithCheckbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- PC端表格布局 -->
|
<!-- PC端表格布局 -->
|
||||||
<div class="hidden md:block">
|
<div class="hidden md:block">
|
||||||
<TableFormLayout :items="permissions || []" :columns="columns" :hasCheckbox="true" v-model="checkedPermissionIds"
|
<TableFormLayout :items="permissions || []" :columns="columns" :hasCheckbox="true" v-model="checkedPermissionIds"
|
||||||
@all-checked-change="allChecked = $event">
|
@all-checked-change="allChecked = $event">
|
||||||
<template #code="{ item }">
|
<template #code="{ item }">
|
||||||
{{ item.code }}
|
{{ item.code }}
|
||||||
</template>
|
</template>
|
||||||
<template #name="{ item }">
|
<template #name="{ item }">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</template>
|
</template>
|
||||||
<template #bindState="{ item }">
|
<template #bindState="{ item }">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
||||||
{{ item.isBound === true ? "已绑定" : "未绑定" }}
|
{{ item.isBound === true ? "已绑定" : "未绑定" }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</TableFormLayout>
|
</TableFormLayout>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TablePagination :pageChange="handlePageChange" :total="total" />
|
<TablePagination :pageChange="handlePageChange" :total="total" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<BindModal :id="'permission-bind-modal'" :closeModal="() => {
|
<BindModal :id="'permission-bind-modal'" :closeModal="() => {
|
||||||
permissionBindModal!.hide();
|
permissionBindModal!.hide();
|
||||||
}" :onSubmit="handleBindPermissionSubmit" title="确定绑定选中的权限吗"></BindModal>
|
}" :onSubmit="handleBindPermissionSubmit" title="确定绑定选中的权限吗"></BindModal>
|
||||||
<UnModal :id="'permission-unbind-modal'" :closeModal="() => {
|
<UnModal :id="'permission-unbind-modal'" :closeModal="() => {
|
||||||
permissionUnbindModal!.hide();
|
permissionUnbindModal!.hide();
|
||||||
}" :onSubmit="handleUnbindPermissionSubmit" title="确定解绑选中的权限吗"></UnModal>
|
}" :onSubmit="handleUnbindPermissionSubmit" title="确定解绑选中的权限吗"></UnModal>
|
||||||
</template>
|
</template>
|
||||||
@@ -99,7 +99,7 @@ import type { FilterItem } from "@/components/TableFilterForm.vue";
|
|||||||
import TableFormLayout from "@/components/TableFormLayout.vue";
|
import TableFormLayout from "@/components/TableFormLayout.vue";
|
||||||
import TablePagination from "@/components/TablePagination.vue";
|
import TablePagination from "@/components/TablePagination.vue";
|
||||||
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
||||||
import { RouteName } from "@/router/constants";
|
import { Routes } from "@/router/constants";
|
||||||
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||||
import { onMounted, reactive, ref, watch } from "vue";
|
import { onMounted, reactive, ref, watch } from "vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="px-2 sm:px-4 pt-6 sm:rounded-lg">
|
<div class="px-2 sm:px-4 pt-6 sm:rounded-lg">
|
||||||
<div class="mb-4 sm:mb-6 col-span-full">
|
<div class="mb-4 sm:mb-6 col-span-full">
|
||||||
<Breadcrumbs :names="['用户管理', '绑定岗位']" :routes="[{ name: RouteName.USERVIEW }]" />
|
<Breadcrumbs :names="['用户管理', '绑定岗位']" :routes="[Routes.USERVIEW.fullPath()]" />
|
||||||
<h1 class="text-xl sm:text-2xl mb-4 sm:mb-6 font-semibold text-gray-900">绑定岗位</h1>
|
<h1 class="text-xl sm:text-2xl mb-4 sm:mb-6 font-semibold text-gray-900">绑定岗位</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
||||||
@update:values="updateFilterValues">
|
@update:values="updateFilterValues">
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<div class="flex gap-x-2">
|
<div class="flex gap-x-2">
|
||||||
<TableButton variant="primary" @click="() => {
|
<TableButton variant="primary" @click="() => {
|
||||||
if (checkedPositionIds.length === 0) {
|
if (checkedPositionIds.length === 0) {
|
||||||
alertStore.showAlert({
|
alertStore.showAlert({
|
||||||
content: '没有选择岗位',
|
content: '没有选择岗位',
|
||||||
@@ -19,9 +19,9 @@
|
|||||||
positionBindModal?.show();
|
positionBindModal?.show();
|
||||||
}
|
}
|
||||||
}">
|
}">
|
||||||
绑定
|
绑定
|
||||||
</TableButton>
|
</TableButton>
|
||||||
<TableButton variant="danger" @click="() => {
|
<TableButton variant="danger" @click="() => {
|
||||||
if (checkedPositionIds.length === 0) {
|
if (checkedPositionIds.length === 0) {
|
||||||
alertStore.showAlert({
|
alertStore.showAlert({
|
||||||
content: '没有选择岗位',
|
content: '没有选择岗位',
|
||||||
@@ -31,50 +31,50 @@
|
|||||||
positionUnbindModal?.show();
|
positionUnbindModal?.show();
|
||||||
}
|
}
|
||||||
}">
|
}">
|
||||||
解绑
|
解绑
|
||||||
</TableButton>
|
</TableButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</TableFilterForm>
|
</TableFilterForm>
|
||||||
|
|
||||||
<!-- 移动端卡片布局 -->
|
<!-- 移动端卡片布局 -->
|
||||||
<div class="md:hidden space-y-4">
|
<div class="md:hidden space-y-4">
|
||||||
<MobileCardListWithCheckbox :items="positions || []" v-model="checkedPositionIds">
|
<MobileCardListWithCheckbox :items="positions || []" v-model="checkedPositionIds">
|
||||||
<template #title="{ item }">
|
<template #title="{ item }">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</template>
|
</template>
|
||||||
<template #status="{ item }">
|
<template #status="{ item }">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
||||||
<span class="text-sm">{{ item.isBound === true ? "已绑定" : "未绑定" }}</span>
|
<span class="text-sm">{{ item.isBound === true ? "已绑定" : "未绑定" }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</MobileCardListWithCheckbox>
|
</MobileCardListWithCheckbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- PC端表格布局 -->
|
<!-- PC端表格布局 -->
|
||||||
<div class="hidden md:block">
|
<div class="hidden md:block">
|
||||||
<TableFormLayout :items="positions || []" :columns="columns" :hasCheckbox="true" v-model="checkedPositionIds"
|
<TableFormLayout :items="positions || []" :columns="columns" :hasCheckbox="true" v-model="checkedPositionIds"
|
||||||
@all-checked-change="allChecked = $event">
|
@all-checked-change="allChecked = $event">
|
||||||
<template #name="{ item }">
|
<template #name="{ item }">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</template>
|
</template>
|
||||||
<template #bindState="{ item }">
|
<template #bindState="{ item }">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
<div class="h-2.5 w-2.5 rounded-full me-2" :class="item.isBound ? 'bg-green-500' : 'bg-red-500'"></div>
|
||||||
{{ item.isBound === true ? "已绑定" : "未绑定" }}
|
{{ item.isBound === true ? "已绑定" : "未绑定" }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</TableFormLayout>
|
</TableFormLayout>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TablePagination :pageChange="handlePageChange" :total="total" />
|
<TablePagination :pageChange="handlePageChange" :total="total" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<BindModal :id="'position-bind-modal'" :closeModal="() => {
|
<BindModal :id="'position-bind-modal'" :closeModal="() => {
|
||||||
positionBindModal!.hide();
|
positionBindModal!.hide();
|
||||||
}" :onSubmit="handleBindPositionSubmit" title="绑定选中的岗位吗"></BindModal>
|
}" :onSubmit="handleBindPositionSubmit" title="绑定选中的岗位吗"></BindModal>
|
||||||
<UnModal :id="'position-unbind-modal'" :closeModal="() => {
|
<UnModal :id="'position-unbind-modal'" :closeModal="() => {
|
||||||
positionUnbindModal!.hide();
|
positionUnbindModal!.hide();
|
||||||
}" :onSubmit="handleUnbindPositionSubmit" title="解绑选中的岗位吗"></UnModal>
|
}" :onSubmit="handleUnbindPositionSubmit" title="解绑选中的岗位吗"></UnModal>
|
||||||
</template>
|
</template>
|
||||||
@@ -93,7 +93,7 @@ import { usePositionBind } from "@/composables/position/usePositionBind";
|
|||||||
import { usePositionQuery } from "@/composables/position/usePositionQuery";
|
import { usePositionQuery } from "@/composables/position/usePositionQuery";
|
||||||
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
||||||
import { useMobileStyles } from "@/composables/useMobileStyles";
|
import { useMobileStyles } from "@/composables/useMobileStyles";
|
||||||
import { RouteName } from "@/router/constants";
|
import { Routes } from "@/router/constants";
|
||||||
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||||
import { onMounted, reactive, ref, watch } from "vue";
|
import { onMounted, reactive, ref, watch } from "vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="px-2 sm:px-4 pt-6 sm:rounded-lg">
|
<div class="px-2 sm:px-4 pt-6 sm:rounded-lg">
|
||||||
<div class="mb-4 sm:mb-6 col-span-full">
|
<div class="mb-4 sm:mb-6 col-span-full">
|
||||||
<Breadcrumbs :names="['用户管理', '角色分配']" :routes="[{ name: RouteName.USERVIEW }]" />
|
<Breadcrumbs :names="['用户管理', '角色分配']" :routes="[Routes.USERVIEW.fullPath()]" />
|
||||||
<h1 class="text-xl sm:text-2xl mb-4 sm:mb-6 font-semibold text-gray-900">角色分配</h1>
|
<h1 class="text-xl sm:text-2xl mb-4 sm:mb-6 font-semibold text-gray-900">角色分配</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ import TableFormLayout from "@/components/TableFormLayout.vue";
|
|||||||
import TablePagination from "@/components/TablePagination.vue";
|
import TablePagination from "@/components/TablePagination.vue";
|
||||||
import { useRolesQuery } from "@/composables/role/useRolesQuery";
|
import { useRolesQuery } from "@/composables/role/useRolesQuery";
|
||||||
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
||||||
import { RouteName } from "@/router/constants";
|
import { Routes } from "@/router/constants";
|
||||||
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||||
import { onMounted, reactive, ref } from "vue";
|
import { onMounted, reactive, ref } from "vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import { useRoute, useRouter } from "vue-router";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import useUserAuth from "../composables/auth/useUserAuth";
|
import useUserAuth from "../composables/auth/useUserAuth";
|
||||||
import useAlertStore from "../composables/store/useAlertStore";
|
import useAlertStore from "../composables/store/useAlertStore";
|
||||||
import { RoutePath } from "../router/constants";
|
import { Routes } from "../router/constants";
|
||||||
|
|
||||||
const username = ref("admin");
|
const username = ref("admin");
|
||||||
const password = ref("admin");
|
const password = ref("admin");
|
||||||
@@ -58,8 +58,7 @@ const handleLogin = async () => {
|
|||||||
content: "登录成功",
|
content: "登录成功",
|
||||||
});
|
});
|
||||||
const redirectPath =
|
const redirectPath =
|
||||||
(route.query.redirect as string) ||
|
(route.query.redirect as string) || Routes.USERVIEW.fullPath();
|
||||||
`${RoutePath.DASHBOARD}/${RoutePath.USERVIEW}`;
|
|
||||||
router.push(redirectPath);
|
router.push(redirectPath);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RoutePath } from "../router/constants";
|
import { Routes } from "../router/constants";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -10,7 +10,7 @@ import { RoutePath } from "../router/constants";
|
|||||||
found</h1>
|
found</h1>
|
||||||
<p class="mt-6 text-base sm:text-lg font-medium text-pretty text-gray-500">您访问的资源未找到,请点击浏览器后退按钮返回</p>
|
<p class="mt-6 text-base sm:text-lg font-medium text-pretty text-gray-500">您访问的资源未找到,请点击浏览器后退按钮返回</p>
|
||||||
<div class="mt-10 flex items-center justify-center gap-x-6">
|
<div class="mt-10 flex items-center justify-center gap-x-6">
|
||||||
<RouterLink :to="`${RoutePath.DASHBOARD}/${RoutePath.OVERVIEW}`"
|
<RouterLink :to="Routes.OVERVIEW.fullPath()"
|
||||||
class="rounded-md px-3.5 py-2.5 text-sm font-semibold bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 text-white shadow-xs focus-visible:outline-2 focus-visible:outline-offset-2">
|
class="rounded-md px-3.5 py-2.5 text-sm font-semibold bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 text-white shadow-xs focus-visible:outline-2 focus-visible:outline-offset-2">
|
||||||
回到主页</RouterLink>
|
回到主页</RouterLink>
|
||||||
<a href="#" class="text-sm font-semibold text-gray-900">联系我们<span aria-hidden="true">→</span></a>
|
<a href="#" class="text-sm font-semibold text-gray-900">联系我们<span aria-hidden="true">→</span></a>
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ import PlusIcon from "@/components/icons/PlusIcon.vue";
|
|||||||
import useRoleDelete from "@/composables/role/useRoleDelete";
|
import useRoleDelete from "@/composables/role/useRoleDelete";
|
||||||
import { useRolesQuery } from "@/composables/role/useRolesQuery";
|
import { useRolesQuery } from "@/composables/role/useRolesQuery";
|
||||||
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
||||||
import { RouteName } from "@/router/constants";
|
import { Routes } from "@/router/constants";
|
||||||
import type { RoleUpsertModel } from "@/types/role";
|
import type { RoleUpsertModel } from "@/types/role";
|
||||||
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||||
import { nextTick, onMounted, reactive, ref } from "vue";
|
import { nextTick, onMounted, reactive, ref } from "vue";
|
||||||
@@ -169,7 +169,7 @@ const updateFilterValues = (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectedRole = ref<components["schemas"]["RoleDto"]>();
|
const selectedRole = ref<components["schemas"]["RoleRespDto"]>();
|
||||||
const roleUpsertModal = ref<ModalInterface>();
|
const roleUpsertModal = ref<ModalInterface>();
|
||||||
const roleDeleteModal = ref<ModalInterface>();
|
const roleDeleteModal = ref<ModalInterface>();
|
||||||
const actionExcStore = useActionExcStore();
|
const actionExcStore = useActionExcStore();
|
||||||
@@ -223,7 +223,7 @@ const handleUpsertModalSubmit = async (data: RoleUpsertModel) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleUpsertRoleClick = async (
|
const handleUpsertRoleClick = async (
|
||||||
role?: components["schemas"]["RoleDto"],
|
role?: components["schemas"]["RoleRespDto"],
|
||||||
) => {
|
) => {
|
||||||
selectedRole.value = role;
|
selectedRole.value = role;
|
||||||
await nextTick(() => {
|
await nextTick(() => {
|
||||||
@@ -232,14 +232,13 @@ const handleUpsertRoleClick = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleBindPermissionClick = async (
|
const handleBindPermissionClick = async (
|
||||||
role: components["schemas"]["RoleDto"],
|
role: components["schemas"]["RoleRespDto"],
|
||||||
) => {
|
) => {
|
||||||
router.push({
|
router.push(
|
||||||
name: RouteName.BINDPERMISSIONVIEW,
|
Routes.BINDPERMISSIONVIEW.withParams({
|
||||||
params: {
|
roleId: role.id!,
|
||||||
roleId: role.id,
|
}),
|
||||||
},
|
);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeletedModalSubmit = async () => {
|
const handleDeletedModalSubmit = async () => {
|
||||||
@@ -256,7 +255,7 @@ const handleDeletedModalSubmit = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteRoleClick = async (
|
const handleDeleteRoleClick = async (
|
||||||
role: components["schemas"]["RoleDto"],
|
role: components["schemas"]["RoleRespDto"],
|
||||||
) => {
|
) => {
|
||||||
selectedRole.value = role;
|
selectedRole.value = role;
|
||||||
await nextTick(() => {
|
await nextTick(() => {
|
||||||
|
|||||||
@@ -52,14 +52,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||||
import useUserAuth from "@/composables/auth/useUserAuth";
|
import useUserAuth from "@/composables/auth/useUserAuth";
|
||||||
import useUserStore from "@/composables/store/useUserStore";
|
import useUserStore from "@/composables/store/useUserStore";
|
||||||
import { initFlowbite } from "flowbite";
|
import { initFlowbite } from "flowbite";
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import useAlertStore from "../composables/store/useAlertStore";
|
import useAlertStore from "../composables/store/useAlertStore";
|
||||||
import { RouteName } from "../router/constants";
|
import { Routes } from "../router/constants";
|
||||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
|
||||||
|
|
||||||
const { user } = useUserStore();
|
const { user } = useUserStore();
|
||||||
const { upsertCurrentUser } = useUserAuth();
|
const { upsertCurrentUser } = useUserAuth();
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ import { useSort } from "@/composables/sort";
|
|||||||
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
||||||
import useUserDelete from "@/composables/user/useUserDelete";
|
import useUserDelete from "@/composables/user/useUserDelete";
|
||||||
import { useUserQuery } from "@/composables/user/useUserQuery";
|
import { useUserQuery } from "@/composables/user/useUserQuery";
|
||||||
import { RouteName } from "@/router/constants";
|
import { Routes } from "@/router/constants";
|
||||||
import type { UserUpsertSubmitModel } from "@/types/user";
|
import type { UserUpsertSubmitModel } from "@/types/user";
|
||||||
import { dayjs, formatDate } from "@/utils/dateUtil";
|
import { dayjs, formatDate } from "@/utils/dateUtil";
|
||||||
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||||
@@ -289,34 +289,31 @@ const handleUpsertUserClick = async (
|
|||||||
const handleBindRoleClick = async (
|
const handleBindRoleClick = async (
|
||||||
user: components["schemas"]["UserRolePermissionDto"],
|
user: components["schemas"]["UserRolePermissionDto"],
|
||||||
) => {
|
) => {
|
||||||
router.push({
|
router.push(
|
||||||
name: RouteName.BINDROLEVIEW,
|
Routes.BINDROLEVIEW.withParams({
|
||||||
params: {
|
userId: user.id!,
|
||||||
userId: user.id,
|
}),
|
||||||
},
|
);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBindDepartmentClick = async (
|
const handleBindDepartmentClick = async (
|
||||||
user: components["schemas"]["UserRolePermissionDto"],
|
user: components["schemas"]["UserRolePermissionDto"],
|
||||||
) => {
|
) => {
|
||||||
router.push({
|
router.push(
|
||||||
name: RouteName.BINDDEPARTMENTVIEW,
|
Routes.BINDDEPARTMENTVIEW.withParams({
|
||||||
params: {
|
userId: user.id!,
|
||||||
userId: user.id,
|
}),
|
||||||
},
|
);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBindPositionClick = async (
|
const handleBindPositionClick = async (
|
||||||
user: components["schemas"]["UserRolePermissionDto"],
|
user: components["schemas"]["UserRolePermissionDto"],
|
||||||
) => {
|
) => {
|
||||||
router.push({
|
router.push(
|
||||||
name: RouteName.BINDPOSITIONVIEW,
|
Routes.BINDPOSITIONVIEW.withParams({
|
||||||
params: {
|
userId: user.id!,
|
||||||
userId: user.id,
|
}),
|
||||||
},
|
);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSortClick = async (field: string) => {
|
const handleSortClick = async (field: string) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user