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