mirror of
https://github.com/ccmjga/zhilu-admin
synced 2026-04-08 06:27:36 +00:00
重构错误处理逻辑,更新组件导入路径,新增多个模态框组件以支持用户、部门、角色和权限管理功能,优化分页和排序逻辑,更新类型定义以提高代码可读性和维护性
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
import createClient, { type Middleware } from "openapi-fetch";
|
import createClient, { type Middleware } from "openapi-fetch";
|
||||||
import useAuthStore from "../composables/store/useAuthStore";
|
import useAuthStore from "../composables/store/useAuthStore";
|
||||||
|
import type { paths } from "./types/schema"; // generated by openapi-typescript
|
||||||
import {
|
import {
|
||||||
ForbiddenError,
|
ForbiddenError,
|
||||||
RequestError,
|
RequestError,
|
||||||
UnAuthError,
|
UnAuthError,
|
||||||
InternalServerError,
|
InternalServerError,
|
||||||
} from "../types/error";
|
} from "@/types/ErrorTypes";
|
||||||
import type { paths } from "./types/schema"; // generated by openapi-typescript
|
|
||||||
|
|
||||||
const myMiddleware: Middleware = {
|
const myMiddleware: Middleware = {
|
||||||
onRequest({ request, options }) {
|
onRequest({ request, options }) {
|
||||||
|
|||||||
@@ -71,19 +71,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<UserUpsertModal :id="'user-upsert-modal'" :onSubmit="handleUpsertUserSubmit" :closeModal="() => {
|
<UserFormDialog :id="'user-upsert-modal'" :onSubmit="handleUpsertUserSubmit" :closeModal="() => {
|
||||||
userUpsertModal!.hide();
|
userUpsertModal!.hide();
|
||||||
}">
|
}">
|
||||||
</UserUpsertModal>
|
</UserFormDialog>
|
||||||
<UserDeleteModal :id="'user-delete-modal'" :closeModal="() => {
|
<UserDeleteModal :id="'user-delete-modal'" :closeModal="() => {
|
||||||
currentDeleteUsername = undefined
|
currentDeleteUsername = undefined
|
||||||
userDeleteModal!.hide();
|
userDeleteModal!.hide();
|
||||||
}" :onSubmit="handleDeleteUserSubmit" title="确定删除该用户吗" content="删除用户"></UserDeleteModal>
|
}" :onSubmit="handleDeleteUserSubmit" title="确定删除该用户吗" content="删除用户"></UserDeleteModal>
|
||||||
<DepartmentUpsertModal :id="'department-upsert-modal'" :onSubmit="handleUpsertDepartmentSubmit" :closeModal="() => {
|
<DepartmentFormDialog :id="'department-upsert-modal'" :onSubmit="handleUpsertDepartmentSubmit" :closeModal="() => {
|
||||||
availableDepartments = undefined
|
availableDepartments = undefined
|
||||||
departmentUpsertModal!.hide();
|
departmentUpsertModal!.hide();
|
||||||
}" :availableDepartments="availableDepartments">
|
}" :availableDepartments="availableDepartments">
|
||||||
</DepartmentUpsertModal>
|
</DepartmentFormDialog>
|
||||||
<DepartmentDeleteModal :id="'department-delete-modal'" :closeModal="() => {
|
<DepartmentDeleteModal :id="'department-delete-modal'" :closeModal="() => {
|
||||||
currentDeleteDepartmentName = undefined
|
currentDeleteDepartmentName = undefined
|
||||||
departmentDeleteModal!.hide();
|
departmentDeleteModal!.hide();
|
||||||
@@ -92,10 +92,9 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { LoadingIcon } from "@/components/icons";
|
import { LoadingIcon } from "@/components/icons";
|
||||||
import DepartmentUpsertModal from "@/components/modals/DepartmentUpsertModal.vue";
|
import UserDeleteModal from "@/components/modals/ConfirmationDialog.vue";
|
||||||
import UserDeleteModal from "@/components/modals/PopupModal.vue";
|
import DepartmentDeleteModal from "@/components/modals/ConfirmationDialog.vue";
|
||||||
import DepartmentDeleteModal from "@/components/modals/PopupModal.vue";
|
import DepartmentFormDialog from "@/components/modals/DepartmentFormDialog.vue";
|
||||||
import UserUpsertModal from "@/components/modals/UserUpsertModal.vue";
|
|
||||||
import TableButton from "@/components/tables/TableButton.vue";
|
import TableButton from "@/components/tables/TableButton.vue";
|
||||||
import Avatar from "@/components/ui/Avatar.vue";
|
import Avatar from "@/components/ui/Avatar.vue";
|
||||||
import InputButton from "@/components/ui/InputButton.vue";
|
import InputButton from "@/components/ui/InputButton.vue";
|
||||||
@@ -107,8 +106,8 @@ import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
|||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
import useUserStore from "@/composables/store/useUserStore";
|
import useUserStore from "@/composables/store/useUserStore";
|
||||||
import { useUserUpsert } from "@/composables/user/useUserUpsert";
|
import { useUserUpsert } from "@/composables/user/useUserUpsert";
|
||||||
import type { DepartmentUpsertModel } from "@/types/department";
|
import type { DepartmentUpsertModel } from "@/types/DepartmentTypes";
|
||||||
import type { UserUpsertSubmitModel } from "@/types/user";
|
import type { UserUpsertSubmitModel } from "@/types/UserTypes";
|
||||||
import DOMPurify from "dompurify";
|
import DOMPurify from "dompurify";
|
||||||
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||||
import { marked } from "marked";
|
import { marked } from "marked";
|
||||||
|
|||||||
@@ -26,19 +26,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { Modal, initFlowbite } from "flowbite";
|
||||||
import { computed, onMounted } from "vue";
|
import { computed, onMounted } from "vue";
|
||||||
import { initFlowbite, Modal } from "flowbite";
|
|
||||||
|
|
||||||
export type ModalSize = "xs" | "sm" | "md" | "lg" | "xl";
|
export type ModalSize = "xs" | "sm" | "md" | "lg" | "xl";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
/** 模态框标题 */
|
/** 对话框标题 */
|
||||||
title?: string;
|
title?: string;
|
||||||
/** 模态框大小 */
|
/** 对话框大小 */
|
||||||
size?: ModalSize;
|
size?: ModalSize;
|
||||||
/** 关闭模态框的回调函数 */
|
/** 关闭对话框的回调函数 */
|
||||||
closeModal: () => void;
|
closeModal: () => void;
|
||||||
/** 模态框ID,用于DOM选择 */
|
/** 对话框ID,用于DOM选择 */
|
||||||
id?: string;
|
id?: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseModal :id="id" :closeModal="closeModal" size="sm">
|
<BaseDialog :id="id" :closeModal="closeModal" size="sm">
|
||||||
<div class="p-5 md:p-6 text-center">
|
<div class="p-5 md:p-6 text-center">
|
||||||
<svg class="w-14 h-14 sm:w-16 sm:h-16 mx-auto text-red-600 mb-4" fill="none" stroke="currentColor"
|
<svg class="w-14 h-14 sm:w-16 sm:h-16 mx-auto text-red-600 mb-4" fill="none" stroke="currentColor"
|
||||||
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
@@ -18,11 +18,11 @@
|
|||||||
class="py-2.5 px-5 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 min-w-[80px]">否</button>
|
class="py-2.5 px-5 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 min-w-[80px]">否</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</BaseModal>
|
</BaseDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import BaseModal from "./BaseModal.vue";
|
import BaseDialog from "./BaseDialog.vue";
|
||||||
|
|
||||||
const { title, id, closeModal, onSubmit } = defineProps<{
|
const { title, id, closeModal, onSubmit } = defineProps<{
|
||||||
title: string;
|
title: string;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseModal :id="id" title="部门管理" size="md" :closeModal="closeModal">
|
<BaseDialog :id="id" title="部门管理" size="md" :closeModal="closeModal">
|
||||||
<!-- Modal body -->
|
<!-- Modal body -->
|
||||||
<div class="p-4 md:p-5">
|
<div class="p-4 md:p-5">
|
||||||
<div class="grid gap-4 mb-4 grid-cols-1">
|
<div class="grid gap-4 mb-4 grid-cols-1">
|
||||||
@@ -24,17 +24,17 @@
|
|||||||
保存
|
保存
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</BaseModal>
|
</BaseDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
import type { DepartmentUpsertModel } from "@/types/department";
|
import type { DepartmentUpsertModel } from "@/types/DepartmentTypes";
|
||||||
import { initFlowbite } from "flowbite";
|
import { initFlowbite } from "flowbite";
|
||||||
import { onMounted, ref, watch } from "vue";
|
import { onMounted, ref, watch } from "vue";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import BaseModal from "./BaseModal.vue";
|
import BaseDialog from "./BaseDialog.vue";
|
||||||
|
|
||||||
const { department, availableDepartments, onSubmit, closeModal, id } =
|
const { department, availableDepartments, onSubmit, closeModal, id } =
|
||||||
defineProps<{
|
defineProps<{
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseModal :id="id" title="大模型配置" size="md" :closeModal="closeModal">
|
<BaseDialog :id="id" title="大模型配置" size="md" :closeModal="closeModal">
|
||||||
<!-- Modal body -->
|
<!-- Modal body -->
|
||||||
<div class="p-4 md:p-5">
|
<div class="p-4 md:p-5">
|
||||||
<div class="grid gap-4 mb-4 grid-cols-1">
|
<div class="grid gap-4 mb-4 grid-cols-1">
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
保存
|
保存
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</BaseModal>
|
</BaseDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -61,7 +61,7 @@ import type { components } from "@/api/types/schema";
|
|||||||
import { initFlowbite } from "flowbite";
|
import { initFlowbite } from "flowbite";
|
||||||
import { onMounted, ref, watch } from "vue";
|
import { onMounted, ref, watch } from "vue";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import BaseModal from "./BaseModal.vue";
|
import BaseDialog from "./BaseDialog.vue";
|
||||||
|
|
||||||
const { llm, onSubmit, id } = defineProps<{
|
const { llm, onSubmit, id } = defineProps<{
|
||||||
llm?: components["schemas"]["LlmVm"];
|
llm?: components["schemas"]["LlmVm"];
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseModal :id="id" title="权限管理" size="md" :closeModal="closeModal">
|
<BaseDialog :id="id" title="权限管理" size="md" :closeModal="closeModal">
|
||||||
<!-- Modal body -->
|
<!-- Modal body -->
|
||||||
<div class="p-4 md:p-5">
|
<div class="p-4 md:p-5">
|
||||||
<div class="grid gap-4 mb-4 grid-cols-1">
|
<div class="grid gap-4 mb-4 grid-cols-1">
|
||||||
@@ -21,16 +21,16 @@
|
|||||||
保存
|
保存
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</BaseModal>
|
</BaseDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
import type { PermissionUpsertModel } from "@/types/permission";
|
import type { PermissionUpsertModel } from "@/types/PermissionTypes";
|
||||||
import { ref, watch } from "vue";
|
import { ref, watch } from "vue";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import BaseModal from "./BaseModal.vue";
|
import BaseDialog from "./BaseDialog.vue";
|
||||||
|
|
||||||
const alertStore = useAlertStore();
|
const alertStore = useAlertStore();
|
||||||
const { permission, onSubmit, closeModal, id } = defineProps<{
|
const { permission, onSubmit, closeModal, id } = defineProps<{
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseModal :id="id" title="岗位管理" size="md" :closeModal="closeModal">
|
<BaseDialog :id="id" title="岗位管理" size="md" :closeModal="closeModal">
|
||||||
<!-- Modal body -->
|
<!-- Modal body -->
|
||||||
<div class="p-4 md:p-5">
|
<div class="p-4 md:p-5">
|
||||||
<div class="grid gap-4 mb-4 grid-cols-1">
|
<div class="grid gap-4 mb-4 grid-cols-1">
|
||||||
@@ -15,16 +15,16 @@
|
|||||||
保存
|
保存
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</BaseModal>
|
</BaseDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
import type { PositionUpsertModel } from "@/types/position";
|
import type { PositionUpsertModel } from "@/types/PositionTypes";
|
||||||
import { ref, watch } from "vue";
|
import { ref, watch } from "vue";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import BaseModal from "./BaseModal.vue";
|
import BaseDialog from "./BaseDialog.vue";
|
||||||
|
|
||||||
const alertStore = useAlertStore();
|
const alertStore = useAlertStore();
|
||||||
const { position, closeModal, onSubmit, id } = defineProps<{
|
const { position, closeModal, onSubmit, id } = defineProps<{
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseModal :id="id" title="角色管理" size="md" :closeModal="closeModal">
|
<BaseDialog :id="id" title="角色管理" size="md" :closeModal="closeModal">
|
||||||
<!-- Modal body -->
|
<!-- Modal body -->
|
||||||
<div class="p-4 md:p-5">
|
<div class="p-4 md:p-5">
|
||||||
<div class="grid gap-4 mb-4 grid-cols-1">
|
<div class="grid gap-4 mb-4 grid-cols-1">
|
||||||
@@ -21,16 +21,16 @@
|
|||||||
保存
|
保存
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</BaseModal>
|
</BaseDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
import type { RoleUpsertModel } from "@/types/role";
|
import type { RoleUpsertModel } from "@/types/RoleTypes";
|
||||||
import { ref, watch } from "vue";
|
import { ref, watch } from "vue";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import BaseModal from "./BaseModal.vue";
|
import BaseDialog from "./BaseDialog.vue";
|
||||||
|
|
||||||
const alertStore = useAlertStore();
|
const alertStore = useAlertStore();
|
||||||
const { role, closeModal, onSubmit, id } = defineProps<{
|
const { role, closeModal, onSubmit, id } = defineProps<{
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseModal :id="id" title="定时任务配置" size="md" :closeModal="closeModal">
|
<BaseDialog :id="id" title="定时任务配置" size="md" :closeModal="closeModal">
|
||||||
<!-- Modal body -->
|
<!-- Modal body -->
|
||||||
<div class="p-4 md:p-5">
|
<div class="p-4 md:p-5">
|
||||||
<div class="grid gap-4 mb-4 grid-cols-1">
|
<div class="grid gap-4 mb-4 grid-cols-1">
|
||||||
@@ -15,14 +15,14 @@
|
|||||||
保存
|
保存
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</BaseModal>
|
</BaseDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
import { ref, watch } from "vue";
|
import { ref, watch } from "vue";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import BaseModal from "./BaseModal.vue";
|
import BaseDialog from "./BaseDialog.vue";
|
||||||
|
|
||||||
const { job, closeModal, onSubmit, id } = defineProps<{
|
const { job, closeModal, onSubmit, id } = defineProps<{
|
||||||
job?: components["schemas"]["JobTriggerDto"];
|
job?: components["schemas"]["JobTriggerDto"];
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseModal :id="id" title="用户管理" size="md" :closeModal="closeModal">
|
<BaseDialog :id="id" title="用户管理" size="md" :closeModal="closeModal">
|
||||||
<!-- Modal body -->
|
<!-- Modal body -->
|
||||||
<form class="p-4 md:p-5">
|
<form class="p-4 md:p-5">
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
@@ -39,19 +39,19 @@
|
|||||||
保存
|
保存
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</BaseModal>
|
</BaseDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
import { useUserUpsert } from "@/composables/user/useUserUpsert";
|
import { useUserUpsert } from "@/composables/user/useUserUpsert";
|
||||||
import { ValidationError } from "@/types/error";
|
import { ValidationError } from "@/types/ErrorTypes";
|
||||||
import type { UserUpsertSubmitModel } from "@/types/user";
|
import type { UserUpsertSubmitModel } from "@/types/UserTypes";
|
||||||
import Compressor from "compressorjs";
|
import Compressor from "compressorjs";
|
||||||
import { onMounted, ref, watch } from "vue";
|
import { ref, watch } from "vue";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import BaseModal from "./BaseModal.vue";
|
import BaseDialog from "./BaseDialog.vue";
|
||||||
|
|
||||||
const { user, onSubmit, id } = defineProps<{
|
const { user, onSubmit, id } = defineProps<{
|
||||||
user?: components["schemas"]["UserRolePermissionDto"];
|
user?: components["schemas"]["UserRolePermissionDto"];
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { usePagination } from "@/composables/page";
|
import { usePagination } from "@/composables/common/usePagination";
|
||||||
import { watch } from "vue";
|
import { watch } from "vue";
|
||||||
|
|
||||||
const { pageChange, total } = defineProps<{
|
const { pageChange, total } = defineProps<{
|
||||||
|
|||||||
@@ -35,8 +35,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, ref } from "vue";
|
|
||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
import type { AlertLevel } from "@/types/alert";
|
import type { AlertLevel } from "@/types/AlertTypes";
|
||||||
|
import { onMounted, onUnmounted, ref } from "vue";
|
||||||
const alertStore = useAlertStore();
|
const alertStore = useAlertStore();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -7,20 +7,22 @@ import {
|
|||||||
RequestError,
|
RequestError,
|
||||||
UnAuthError,
|
UnAuthError,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
} from "@/types/error";
|
} from "@/types/ErrorTypes";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 错误处理 Composable
|
* 错误处理 Composable - 提供统一的错误处理机制
|
||||||
|
* @returns 包含错误处理函数的对象
|
||||||
*/
|
*/
|
||||||
export function useErrorHandler() {
|
export function useErrorHandling() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { signOut } = useUserAuth();
|
const { signOut } = useUserAuth();
|
||||||
const alertStore = useAlertStore();
|
const alertStore = useAlertStore();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理各类错误,显示对应的提示信息
|
* 处理各类错误,显示对应的提示信息
|
||||||
|
* @param err 错误对象
|
||||||
*/
|
*/
|
||||||
const handleError = (err: unknown) => {
|
const handleError = (err: unknown) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
@@ -69,4 +71,4 @@ export function useErrorHandler() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default useErrorHandler;
|
export default useErrorHandling;
|
||||||
@@ -12,6 +12,11 @@ export interface UsePaginationOptions {
|
|||||||
initialTotal?: number;
|
initialTotal?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页逻辑Composable - 提供分页相关的状态和操作
|
||||||
|
* @param options 分页选项
|
||||||
|
* @returns 分页状态和方法
|
||||||
|
*/
|
||||||
export function usePagination(options: UsePaginationOptions = {}) {
|
export function usePagination(options: UsePaginationOptions = {}) {
|
||||||
const { initialPage = 1, initialPageSize = 10, initialTotal = 0 } = options;
|
const { initialPage = 1, initialPageSize = 10, initialTotal = 0 } = options;
|
||||||
|
|
||||||
@@ -1,23 +1,39 @@
|
|||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
|
|
||||||
export const useSort = () => {
|
export interface SortField {
|
||||||
const sortFields = ref<
|
field: string;
|
||||||
{
|
order: "asc" | "desc" | undefined;
|
||||||
field: string;
|
}
|
||||||
order: "asc" | "desc" | undefined;
|
|
||||||
}[]
|
|
||||||
>([]);
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序逻辑Composable - 提供排序相关的状态和操作
|
||||||
|
* @returns 排序状态和方法
|
||||||
|
*/
|
||||||
|
export function useSorting() {
|
||||||
|
const sortFields = ref<SortField[]>([]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定字段的排序信息
|
||||||
|
* @param field 字段名
|
||||||
|
* @returns 排序字段对象
|
||||||
|
*/
|
||||||
const getSortField = (field: string) => {
|
const getSortField = (field: string) => {
|
||||||
return sortFields.value.find((item) => item.field === field);
|
return sortFields.value.find((item) => item.field === field);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序表达式,用于API请求
|
||||||
|
*/
|
||||||
const sortBy = computed(() => {
|
const sortBy = computed(() => {
|
||||||
return sortFields.value.length
|
return sortFields.value.length
|
||||||
? sortFields.value.map((item) => `${item.field}:${item.order}`).join(",")
|
? sortFields.value.map((item) => `${item.field}:${item.order}`).join(",")
|
||||||
: undefined;
|
: undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理字段排序
|
||||||
|
* @param field 字段名
|
||||||
|
*/
|
||||||
const handleSort = async (field: string) => {
|
const handleSort = async (field: string) => {
|
||||||
if (sortFields.value?.find((item) => item.field === field)) {
|
if (sortFields.value?.find((item) => item.field === field)) {
|
||||||
sortFields.value = sortFields.value?.map((item) =>
|
sortFields.value = sortFields.value?.map((item) =>
|
||||||
@@ -39,4 +55,4 @@ export const useSort = () => {
|
|||||||
handleSort,
|
handleSort,
|
||||||
getSortField,
|
getSortField,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* 移动端样式hook,提供通用的移动端样式类
|
* 样式系统Composable - 提供统一的样式类名
|
||||||
|
* @returns 样式类名集合
|
||||||
*/
|
*/
|
||||||
export function useMobileStyles() {
|
export function useStyleSystem() {
|
||||||
// 移动端卡片容器样式
|
// 移动端卡片容器样式
|
||||||
const cardContainerClass =
|
const cardContainerClass =
|
||||||
"p-4 bg-white rounded-lg shadow border border-gray-100";
|
"p-4 bg-white rounded-lg shadow border border-gray-100";
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import client from "../../api/client";
|
import client from "../../api/client";
|
||||||
import type { DepartmentUpsertModel } from "../../types/department";
|
import type { DepartmentUpsertModel } from "../../types/DepartmentTypes";
|
||||||
|
|
||||||
export const useDepartmentUpsert = () => {
|
export const useDepartmentUpsert = () => {
|
||||||
const upsertDepartment = async (department: DepartmentUpsertModel) => {
|
const upsertDepartment = async (department: DepartmentUpsertModel) => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import client from "../../api/client";
|
import client from "../../api/client";
|
||||||
import type { PermissionUpsertModel } from "../../types/permission";
|
import type { PermissionUpsertModel } from "../../types/PermissionTypes";
|
||||||
|
|
||||||
const usePermissionUpsert = () => {
|
const usePermissionUpsert = () => {
|
||||||
const upsertPermission = async (permission: PermissionUpsertModel) => {
|
const upsertPermission = async (permission: PermissionUpsertModel) => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import client from "../../api/client";
|
import client from "../../api/client";
|
||||||
import type { UserUpsertSubmitModel } from "../../types/user";
|
import type { UserUpsertSubmitModel } from "../../types/UserTypes";
|
||||||
|
|
||||||
export const useUserUpsert = () => {
|
export const useUserUpsert = () => {
|
||||||
const uploadUserAvatar = async (file: File) => {
|
const uploadUserAvatar = async (file: File) => {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { createApp } from "vue";
|
|||||||
|
|
||||||
import VueDatePicker from "@vuepic/vue-datepicker";
|
import VueDatePicker from "@vuepic/vue-datepicker";
|
||||||
import App from "./App.vue";
|
import App from "./App.vue";
|
||||||
import useErrorHandler from "./composables/useErrorHandler";
|
import useErrorHandling from "./composables/common/useErrorHandling";
|
||||||
import router from "./router";
|
import router from "./router";
|
||||||
import "@vuepic/vue-datepicker/dist/main.css";
|
import "@vuepic/vue-datepicker/dist/main.css";
|
||||||
import "./assets/datepicker.css";
|
import "./assets/datepicker.css";
|
||||||
@@ -27,7 +27,7 @@ enableMocking().then(() => {
|
|||||||
app.use(createPinia());
|
app.use(createPinia());
|
||||||
app.use(router);
|
app.use(router);
|
||||||
|
|
||||||
const { handleError } = useErrorHandler();
|
const { handleError } = useErrorHandling();
|
||||||
app.config.errorHandler = (err, instance, info) => {
|
app.config.errorHandler = (err, instance, info) => {
|
||||||
handleError(err);
|
handleError(err);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const aiRoutes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: Routes.LLMCONFIGVIEW.path,
|
path: Routes.LLMCONFIGVIEW.path,
|
||||||
name: Routes.LLMCONFIGVIEW.name,
|
name: Routes.LLMCONFIGVIEW.name,
|
||||||
component: () => import("@/views/LlmConfigView.vue"),
|
component: () => import("@/views/LlmConfigurationPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
hasPermission: EPermission.READ_LLM_CONFIG_PERMISSION,
|
hasPermission: EPermission.READ_LLM_CONFIG_PERMISSION,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const authRoutes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: Routes.LOGIN.path,
|
path: Routes.LOGIN.path,
|
||||||
name: Routes.LOGIN.name,
|
name: Routes.LOGIN.name,
|
||||||
component: () => import("../../views/LoginView.vue"),
|
component: () => import("../../views/LoginPage.vue"),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { RouteRecordRaw } from "vue-router";
|
import type { RouteRecordRaw } from "vue-router";
|
||||||
|
import Dashboard from "../../components/layout/Dashboard.vue";
|
||||||
import { EPermission, Routes } from "../constants";
|
import { EPermission, Routes } from "../constants";
|
||||||
import aiRoutes from "./ai";
|
import aiRoutes from "./ai";
|
||||||
import userManagementRoutes from "./user";
|
import userManagementRoutes from "./user";
|
||||||
import Dashboard from "../../components/layout/Dashboard.vue";
|
|
||||||
|
|
||||||
const dashboardRoutes: RouteRecordRaw = {
|
const dashboardRoutes: RouteRecordRaw = {
|
||||||
path: Routes.DASHBOARD.path,
|
path: Routes.DASHBOARD.path,
|
||||||
@@ -15,7 +15,7 @@ const dashboardRoutes: RouteRecordRaw = {
|
|||||||
{
|
{
|
||||||
path: Routes.OVERVIEW.path,
|
path: Routes.OVERVIEW.path,
|
||||||
name: Routes.OVERVIEW.name,
|
name: Routes.OVERVIEW.name,
|
||||||
component: () => import("@/views/OverView.vue"),
|
component: () => import("@/views/DashboardPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
},
|
},
|
||||||
@@ -23,7 +23,7 @@ const dashboardRoutes: RouteRecordRaw = {
|
|||||||
{
|
{
|
||||||
path: Routes.SETTINGS.path,
|
path: Routes.SETTINGS.path,
|
||||||
name: Routes.SETTINGS.name,
|
name: Routes.SETTINGS.name,
|
||||||
component: () => import("@/views/SettingsView.vue"),
|
component: () => import("@/views/SystemSettingsPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
},
|
},
|
||||||
@@ -33,12 +33,12 @@ const dashboardRoutes: RouteRecordRaw = {
|
|||||||
{
|
{
|
||||||
path: Routes.NOTFOUND.path,
|
path: Routes.NOTFOUND.path,
|
||||||
name: Routes.NOTFOUND.name,
|
name: Routes.NOTFOUND.name,
|
||||||
component: () => import("@/views/NotFound.vue"),
|
component: () => import("@/views/NotFoundPage.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: Routes.SCHEDULERVIEW.path,
|
path: Routes.SCHEDULERVIEW.path,
|
||||||
name: Routes.SCHEDULERVIEW.name,
|
name: Routes.SCHEDULERVIEW.name,
|
||||||
component: () => import("@/views/SchedulerView.vue"),
|
component: () => import("@/views/SchedulerManagementPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
hasPermission: EPermission.READ_SCHEDULER_PERMISSION,
|
hasPermission: EPermission.READ_SCHEDULER_PERMISSION,
|
||||||
@@ -47,7 +47,7 @@ const dashboardRoutes: RouteRecordRaw = {
|
|||||||
{
|
{
|
||||||
path: Routes.DEPARTMENTVIEW.path,
|
path: Routes.DEPARTMENTVIEW.path,
|
||||||
name: Routes.DEPARTMENTVIEW.name,
|
name: Routes.DEPARTMENTVIEW.name,
|
||||||
component: () => import("@/views/DepartmentView.vue"),
|
component: () => import("@/views/DepartmentManagementPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
hasPermission: EPermission.READ_DEPARTMENT_PERMISSION,
|
hasPermission: EPermission.READ_DEPARTMENT_PERMISSION,
|
||||||
@@ -56,7 +56,7 @@ const dashboardRoutes: RouteRecordRaw = {
|
|||||||
{
|
{
|
||||||
path: Routes.POSITIONVIEW.path,
|
path: Routes.POSITIONVIEW.path,
|
||||||
name: Routes.POSITIONVIEW.name,
|
name: Routes.POSITIONVIEW.name,
|
||||||
component: () => import("@/views/PositionView.vue"),
|
component: () => import("@/views/PositionManagementPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
hasPermission: EPermission.READ_POSITION_PERMISSION,
|
hasPermission: EPermission.READ_POSITION_PERMISSION,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const errorRoutes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: Routes.GLOBAL_NOTFOUND.path,
|
path: Routes.GLOBAL_NOTFOUND.path,
|
||||||
name: Routes.GLOBAL_NOTFOUND.name,
|
name: Routes.GLOBAL_NOTFOUND.name,
|
||||||
component: () => import("../../views/NotFound.vue"),
|
component: () => import("../../views/NotFoundPage.vue"),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: Routes.USERVIEW.path,
|
path: Routes.USERVIEW.path,
|
||||||
name: Routes.USERVIEW.name,
|
name: Routes.USERVIEW.name,
|
||||||
component: () => import("@/views/UserView.vue"),
|
component: () => import("@/views/UserManagementPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
hasPermission: EPermission.READ_USER_ROLE_PERMISSION,
|
hasPermission: EPermission.READ_USER_ROLE_PERMISSION,
|
||||||
@@ -14,7 +14,7 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: Routes.ROLEVIEW.path,
|
path: Routes.ROLEVIEW.path,
|
||||||
name: Routes.ROLEVIEW.name,
|
name: Routes.ROLEVIEW.name,
|
||||||
component: () => import("@/views/RoleView.vue"),
|
component: () => import("@/views/RoleManagementPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
hasPermission: EPermission.READ_USER_ROLE_PERMISSION,
|
hasPermission: EPermission.READ_USER_ROLE_PERMISSION,
|
||||||
@@ -23,7 +23,7 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: Routes.BINDROLEVIEW.path,
|
path: Routes.BINDROLEVIEW.path,
|
||||||
name: Routes.BINDROLEVIEW.name,
|
name: Routes.BINDROLEVIEW.name,
|
||||||
component: () => import("@/views/BindRoleView.vue"),
|
component: () => import("@/views/UserRoleAssignmentPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
hasPermission: EPermission.WRITE_USER_ROLE_PERMISSION,
|
hasPermission: EPermission.WRITE_USER_ROLE_PERMISSION,
|
||||||
@@ -32,7 +32,7 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: Routes.BINDDEPARTMENTVIEW.path,
|
path: Routes.BINDDEPARTMENTVIEW.path,
|
||||||
name: Routes.BINDDEPARTMENTVIEW.name,
|
name: Routes.BINDDEPARTMENTVIEW.name,
|
||||||
component: () => import("@/views/BindDepartmentView.vue"),
|
component: () => import("@/views/UserDepartmentAssignmentPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
hasPermission: EPermission.WRITE_USER_ROLE_PERMISSION,
|
hasPermission: EPermission.WRITE_USER_ROLE_PERMISSION,
|
||||||
@@ -41,7 +41,7 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: Routes.BINDPERMISSIONVIEW.path,
|
path: Routes.BINDPERMISSIONVIEW.path,
|
||||||
name: Routes.BINDPERMISSIONVIEW.name,
|
name: Routes.BINDPERMISSIONVIEW.name,
|
||||||
component: () => import("@/views/BindPermissionView.vue"),
|
component: () => import("@/views/RolePermissionAssignmentPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
hasPermission: EPermission.WRITE_USER_ROLE_PERMISSION,
|
hasPermission: EPermission.WRITE_USER_ROLE_PERMISSION,
|
||||||
@@ -50,7 +50,7 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: Routes.PERMISSIONVIEW.path,
|
path: Routes.PERMISSIONVIEW.path,
|
||||||
name: Routes.PERMISSIONVIEW.name,
|
name: Routes.PERMISSIONVIEW.name,
|
||||||
component: () => import("@/views/PermissionView.vue"),
|
component: () => import("@/views/PermissionManagementPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
hasPermission: EPermission.READ_USER_ROLE_PERMISSION,
|
hasPermission: EPermission.READ_USER_ROLE_PERMISSION,
|
||||||
@@ -59,7 +59,7 @@ const userManagementRoutes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: Routes.BINDPOSITIONVIEW.path,
|
path: Routes.BINDPOSITIONVIEW.path,
|
||||||
name: Routes.BINDPOSITIONVIEW.name,
|
name: Routes.BINDPOSITIONVIEW.name,
|
||||||
component: () => import("@/views/BindPositionView.vue"),
|
component: () => import("@/views/UserPositionAssignmentPage.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
hasPermission: EPermission.WRITE_USER_ROLE_PERMISSION,
|
hasPermission: EPermission.WRITE_USER_ROLE_PERMISSION,
|
||||||
|
|||||||
1
frontend/src/types/AlertTypes.ts
Normal file
1
frontend/src/types/AlertTypes.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export type AlertLevel = "info" | "warning" | "success" | "error";
|
||||||
15
frontend/src/types/DepartmentTypes.ts
Normal file
15
frontend/src/types/DepartmentTypes.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
export interface DepartmentFormData {
|
||||||
|
id?: number;
|
||||||
|
name: string;
|
||||||
|
parentId?: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DepartmentUpsertModel = DepartmentFormData;
|
||||||
|
|
||||||
|
export interface DepartmentData {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
parentId?: number;
|
||||||
|
parentName?: string;
|
||||||
|
isBound?: boolean;
|
||||||
|
}
|
||||||
46
frontend/src/types/ErrorTypes.ts
Normal file
46
frontend/src/types/ErrorTypes.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
export class BaseError extends Error {
|
||||||
|
constructor(message: string) {
|
||||||
|
super(message);
|
||||||
|
this.name = this.constructor.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ValidationError extends BaseError {}
|
||||||
|
|
||||||
|
export class RequestError extends BaseError {
|
||||||
|
status: number;
|
||||||
|
|
||||||
|
constructor(status: number) {
|
||||||
|
super(`请求错误: ${status}`);
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UnAuthError extends BaseError {
|
||||||
|
status: number;
|
||||||
|
|
||||||
|
constructor(status: number) {
|
||||||
|
super(`未授权: ${status}`);
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ForbiddenError extends BaseError {
|
||||||
|
status: number;
|
||||||
|
|
||||||
|
constructor(status: number) {
|
||||||
|
super(`禁止访问: ${status}`);
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class InternalServerError extends BaseError {
|
||||||
|
detail?: string;
|
||||||
|
status: number;
|
||||||
|
|
||||||
|
constructor(status: number, detail?: string) {
|
||||||
|
super(`服务器错误: ${status}`);
|
||||||
|
this.status = status;
|
||||||
|
this.detail = detail;
|
||||||
|
}
|
||||||
|
}
|
||||||
14
frontend/src/types/PermissionTypes.ts
Normal file
14
frontend/src/types/PermissionTypes.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export interface PermissionFormData {
|
||||||
|
id?: number;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PermissionUpsertModel = PermissionFormData;
|
||||||
|
|
||||||
|
export interface PermissionData {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
isBound?: boolean;
|
||||||
|
}
|
||||||
12
frontend/src/types/PositionTypes.ts
Normal file
12
frontend/src/types/PositionTypes.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
export interface PositionFormData {
|
||||||
|
id?: number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PositionUpsertModel = PositionFormData;
|
||||||
|
|
||||||
|
export interface PositionData {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
isBound?: boolean;
|
||||||
|
}
|
||||||
20
frontend/src/types/RoleTypes.ts
Normal file
20
frontend/src/types/RoleTypes.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
export interface RoleFormData {
|
||||||
|
id?: number;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RoleUpsertModel = RoleFormData;
|
||||||
|
|
||||||
|
export interface RoleData {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
isBound?: boolean;
|
||||||
|
permissions?: Array<{
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
isBound?: boolean;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
35
frontend/src/types/UserTypes.ts
Normal file
35
frontend/src/types/UserTypes.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
export interface UserFormData {
|
||||||
|
id?: number;
|
||||||
|
username: string;
|
||||||
|
password?: string;
|
||||||
|
enable: boolean;
|
||||||
|
avatar?: string;
|
||||||
|
realName?: string;
|
||||||
|
age?: number;
|
||||||
|
gender?: number;
|
||||||
|
email?: string;
|
||||||
|
telephone?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UserUpsertSubmitModel = UserFormData;
|
||||||
|
|
||||||
|
// 用户类型,根据实际情况扩展
|
||||||
|
export interface UserData {
|
||||||
|
id: number;
|
||||||
|
username: string;
|
||||||
|
enable: boolean;
|
||||||
|
avatar?: string;
|
||||||
|
realName?: string;
|
||||||
|
age?: number;
|
||||||
|
gender?: number;
|
||||||
|
email?: string;
|
||||||
|
telephone?: string;
|
||||||
|
roles?: Array<{
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
isBound?: boolean;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type User = UserData | null;
|
||||||
5
frontend/src/types/department.d.ts
vendored
5
frontend/src/types/department.d.ts
vendored
@@ -1,5 +0,0 @@
|
|||||||
export interface DepartmentUpsertModel {
|
|
||||||
id?: number;
|
|
||||||
name: string;
|
|
||||||
parentId?: number | null;
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
class ValidationError extends Error {
|
|
||||||
constructor(message: string) {
|
|
||||||
super(message);
|
|
||||||
this.name = "ValidationError";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class HttpError extends Error {
|
|
||||||
status: number;
|
|
||||||
detail?: string;
|
|
||||||
constructor(message: string, status: number, detail?: string) {
|
|
||||||
super(message);
|
|
||||||
this.name = "HttpError";
|
|
||||||
this.status = status;
|
|
||||||
this.detail = detail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class UnAuthError extends HttpError {
|
|
||||||
constructor(status: number) {
|
|
||||||
super("当前用户身份认证异常", status);
|
|
||||||
this.name = "UnAuthError";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ForbiddenError extends HttpError {
|
|
||||||
constructor(status: number) {
|
|
||||||
super("您没有对应的权限", status);
|
|
||||||
this.name = "ForbiddenError";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RequestError extends HttpError {
|
|
||||||
constructor(status: number) {
|
|
||||||
super("请求发生异常,请检查您的输入或稍后再试", status);
|
|
||||||
this.name = "RequestError";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class InternalServerError extends HttpError {
|
|
||||||
constructor(status: number, detail: string) {
|
|
||||||
super(detail, status, detail);
|
|
||||||
this.name = "InternalServerError";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
UnAuthError,
|
|
||||||
ForbiddenError,
|
|
||||||
RequestError,
|
|
||||||
InternalServerError,
|
|
||||||
ValidationError,
|
|
||||||
};
|
|
||||||
5
frontend/src/types/permission.d.ts
vendored
5
frontend/src/types/permission.d.ts
vendored
@@ -1,5 +0,0 @@
|
|||||||
export interface PermissionUpsertModel {
|
|
||||||
id?: number;
|
|
||||||
name: string;
|
|
||||||
code: string;
|
|
||||||
}
|
|
||||||
4
frontend/src/types/position.d.ts
vendored
4
frontend/src/types/position.d.ts
vendored
@@ -1,4 +0,0 @@
|
|||||||
export interface PositionUpsertModel {
|
|
||||||
id?: number;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
5
frontend/src/types/role.d.ts
vendored
5
frontend/src/types/role.d.ts
vendored
@@ -1,5 +0,0 @@
|
|||||||
export interface RoleUpsertModel {
|
|
||||||
id?: number;
|
|
||||||
name: string;
|
|
||||||
code: string;
|
|
||||||
}
|
|
||||||
9
frontend/src/types/user.d.ts
vendored
9
frontend/src/types/user.d.ts
vendored
@@ -1,9 +0,0 @@
|
|||||||
export interface UserUpsertSubmitModel {
|
|
||||||
id?: number;
|
|
||||||
username: string;
|
|
||||||
password?: string;
|
|
||||||
enable: boolean;
|
|
||||||
avatar?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type User = UserRolePermissionModel | null;
|
|
||||||
@@ -100,31 +100,31 @@
|
|||||||
<DepartmentDeleteModal :id="'department-delete-modal'" :closeModal="() => {
|
<DepartmentDeleteModal :id="'department-delete-modal'" :closeModal="() => {
|
||||||
departmentDeleteModal!.hide();
|
departmentDeleteModal!.hide();
|
||||||
}" :onSubmit="handleDeleteDepartmentSubmit" title="确定删除该部门吗" content="删除部门"></DepartmentDeleteModal>
|
}" :onSubmit="handleDeleteDepartmentSubmit" title="确定删除该部门吗" content="删除部门"></DepartmentDeleteModal>
|
||||||
<DepartmentUpsertModal :id="'department-upsert-modal'" :onSubmit="handleUpsertDepartmentSubmit" :closeModal="() => {
|
<DepartmentFormDialog :id="'department-upsert-modal'" :onSubmit="handleUpsertDepartmentSubmit" :closeModal="() => {
|
||||||
availableDepartments = undefined
|
availableDepartments = undefined
|
||||||
departmentUpsertModal!.hide();
|
departmentFormDialog!.hide();
|
||||||
}" :department="selectedDepartment" :availableDepartments="availableDepartments">
|
}" :department="selectedDepartment" :availableDepartments="availableDepartments">
|
||||||
</DepartmentUpsertModal>
|
</DepartmentFormDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
|
import PlusIcon from "@/components/icons/PlusIcon.vue";
|
||||||
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
||||||
|
import DepartmentDeleteModal from "@/components/modals/ConfirmationDialog.vue";
|
||||||
|
import DepartmentFormDialog from "@/components/modals/DepartmentFormDialog.vue";
|
||||||
import MobileCardList from "@/components/tables/MobileCardList.vue";
|
import MobileCardList from "@/components/tables/MobileCardList.vue";
|
||||||
import TableButton from "@/components/tables/TableButton.vue";
|
import TableButton from "@/components/tables/TableButton.vue";
|
||||||
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
||||||
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
||||||
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
||||||
import TablePagination from "@/components/tables/TablePagination.vue";
|
import TablePagination from "@/components/tables/TablePagination.vue";
|
||||||
import PlusIcon from "@/components/icons/PlusIcon.vue";
|
|
||||||
import DepartmentUpsertModal from "@/components/modals/DepartmentUpsertModal.vue";
|
|
||||||
import DepartmentDeleteModal from "@/components/modals/PopupModal.vue";
|
|
||||||
import useDepartmentDelete from "@/composables/department/useDepartmentDelete";
|
import useDepartmentDelete from "@/composables/department/useDepartmentDelete";
|
||||||
import { useDepartmentQuery } from "@/composables/department/useDepartmentQuery";
|
import { useDepartmentQuery } from "@/composables/department/useDepartmentQuery";
|
||||||
import { useDepartmentUpsert } from "@/composables/department/useDepartmentUpsert";
|
import { useDepartmentUpsert } from "@/composables/department/useDepartmentUpsert";
|
||||||
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
import type { DepartmentUpsertModel } from "@/types/department";
|
import type { DepartmentUpsertModel } from "@/types/DepartmentTypes";
|
||||||
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";
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ const updateFilterValues = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selectedDepartment = ref<components["schemas"]["Department"]>();
|
const selectedDepartment = ref<components["schemas"]["Department"]>();
|
||||||
const departmentUpsertModal = ref<ModalInterface>();
|
const departmentFormDialog = ref<ModalInterface>();
|
||||||
const departmentDeleteModal = ref<ModalInterface>();
|
const departmentDeleteModal = ref<ModalInterface>();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -189,7 +189,7 @@ onMounted(async () => {
|
|||||||
"#department-delete-modal",
|
"#department-delete-modal",
|
||||||
);
|
);
|
||||||
if ($upsertModalElement) {
|
if ($upsertModalElement) {
|
||||||
departmentUpsertModal.value = new Modal($upsertModalElement, {});
|
departmentFormDialog.value = new Modal($upsertModalElement, {});
|
||||||
}
|
}
|
||||||
if ($deleteModalElement) {
|
if ($deleteModalElement) {
|
||||||
departmentDeleteModal.value = new Modal($deleteModalElement, {});
|
departmentDeleteModal.value = new Modal($deleteModalElement, {});
|
||||||
@@ -205,7 +205,7 @@ const handleUpsertDepartmentSubmit = async (
|
|||||||
department: DepartmentUpsertModel,
|
department: DepartmentUpsertModel,
|
||||||
) => {
|
) => {
|
||||||
await upsertDepartment(department);
|
await upsertDepartment(department);
|
||||||
departmentUpsertModal.value?.hide();
|
departmentFormDialog.value?.hide();
|
||||||
alertStore.showAlert({
|
alertStore.showAlert({
|
||||||
content: "操作成功",
|
content: "操作成功",
|
||||||
level: "success",
|
level: "success",
|
||||||
@@ -221,7 +221,7 @@ const handleUpsertDepartmentClick = async (
|
|||||||
selectedDepartment.value = department;
|
selectedDepartment.value = department;
|
||||||
await fetchAvailableDepartments(department?.id);
|
await fetchAvailableDepartments(department?.id);
|
||||||
await nextTick(() => {
|
await nextTick(() => {
|
||||||
departmentUpsertModal.value?.show();
|
departmentFormDialog.value?.show();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -109,20 +109,20 @@
|
|||||||
<TablePagination :pageChange="handlePageChange" :total="total" />
|
<TablePagination :pageChange="handlePageChange" :total="total" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<LlmUpdateModal :llm="selectedLlm" :id="'llm-update-modal'" :closeModal="() => {
|
<LlmFormDialog :llm="selectedLlm" :id="'llm-update-modal'" :closeModal="() => {
|
||||||
llmUpdateModal!.hide();
|
llmUpdateModal!.hide();
|
||||||
}" :onSubmit="handleUpdateModalSubmit"></LlmUpdateModal>
|
}" :onSubmit="handleUpdateModalSubmit"></LlmFormDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
||||||
|
import LlmFormDialog from "@/components/modals/LlmFormDialog.vue";
|
||||||
import MobileCardList from "@/components/tables/MobileCardList.vue";
|
import MobileCardList from "@/components/tables/MobileCardList.vue";
|
||||||
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
||||||
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
||||||
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
||||||
import TablePagination from "@/components/tables/TablePagination.vue";
|
import TablePagination from "@/components/tables/TablePagination.vue";
|
||||||
import LlmUpdateModal from "@/components/modals/LlmUpdateModal.vue";
|
|
||||||
import { useLlmQuery } from "@/composables/ai/useLlmQuery";
|
import { useLlmQuery } from "@/composables/ai/useLlmQuery";
|
||||||
import { useLlmUpdate } from "@/composables/ai/useLlmUpdate";
|
import { useLlmUpdate } from "@/composables/ai/useLlmUpdate";
|
||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
@@ -100,32 +100,32 @@
|
|||||||
<PermissionDeleteModal :id="'permission-delete-modal'" :closeModal="() => {
|
<PermissionDeleteModal :id="'permission-delete-modal'" :closeModal="() => {
|
||||||
permissionDeleteModal!.hide();
|
permissionDeleteModal!.hide();
|
||||||
}" :onSubmit="handleDeleteModalSubmit" title="确定删除该权限吗" content="删除权限"></PermissionDeleteModal>
|
}" :onSubmit="handleDeleteModalSubmit" title="确定删除该权限吗" content="删除权限"></PermissionDeleteModal>
|
||||||
<PermissionUpsertModal :id="'permission-upsert-modal'" :onSubmit="handleUpsertModalSubmit" :closeModal="() => {
|
<PermissionFormDialog :id="'permission-upsert-modal'" :onSubmit="handleUpsertModalSubmit" :closeModal="() => {
|
||||||
permissionUpsertModal!.hide();
|
permissionUpsertModal!.hide();
|
||||||
}" :permission="selectedPermission">
|
}" :permission="selectedPermission">
|
||||||
</PermissionUpsertModal>
|
</PermissionFormDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
|
import PlusIcon from "@/components/icons/PlusIcon.vue";
|
||||||
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
||||||
|
import PermissionDeleteModal from "@/components/modals/ConfirmationDialog.vue";
|
||||||
|
import PermissionFormDialog from "@/components/modals/PermissionFormDialog.vue";
|
||||||
import MobileCardList from "@/components/tables/MobileCardList.vue";
|
import MobileCardList from "@/components/tables/MobileCardList.vue";
|
||||||
import TableButton from "@/components/tables/TableButton.vue";
|
import TableButton from "@/components/tables/TableButton.vue";
|
||||||
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
||||||
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
||||||
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
||||||
import TablePagination from "@/components/tables/TablePagination.vue";
|
import TablePagination from "@/components/tables/TablePagination.vue";
|
||||||
import PlusIcon from "@/components/icons/PlusIcon.vue";
|
|
||||||
import PermissionUpsertModal from "@/components/modals/PermissionUpsertModal.vue";
|
|
||||||
import PermissionDeleteModal from "@/components/modals/PopupModal.vue";
|
|
||||||
import usePermissionDelete from "@/composables/permission/usePermissionDelete";
|
import usePermissionDelete from "@/composables/permission/usePermissionDelete";
|
||||||
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
||||||
|
import type { PermissionUpsertModel } from "@/types/PermissionTypes";
|
||||||
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";
|
||||||
import usePermissionsQuery from "../composables/permission/usePermissionQuery";
|
import usePermissionsQuery from "../composables/permission/usePermissionQuery";
|
||||||
import usePermissionUpsert from "../composables/permission/usePermissionUpsert";
|
import usePermissionUpsert from "../composables/permission/usePermissionUpsert";
|
||||||
import useAlertStore from "../composables/store/useAlertStore";
|
import useAlertStore from "../composables/store/useAlertStore";
|
||||||
import type { PermissionUpsertModel } from "../types/permission";
|
|
||||||
|
|
||||||
// 定义筛选配置
|
// 定义筛选配置
|
||||||
const filterConfig = [
|
const filterConfig = [
|
||||||
@@ -91,10 +91,10 @@
|
|||||||
positionDeleteModal!.hide();
|
positionDeleteModal!.hide();
|
||||||
}" :onSubmit="handleDeletePositionSubmit" title="确定删除该岗位吗" content="删除岗位"></PositionDeleteModal>
|
}" :onSubmit="handleDeletePositionSubmit" title="确定删除该岗位吗" content="删除岗位"></PositionDeleteModal>
|
||||||
|
|
||||||
<PositionUpsertModal :id="'position-upsert-modal'" :onSubmit="handleUpsertPositionSubmit" :closeModal="() => {
|
<PositionFormDialog :id="'position-upsert-modal'" :onSubmit="handleUpsertPositionSubmit" :closeModal="() => {
|
||||||
positionUpsertModal!.hide();
|
positionUpsertModal!.hide();
|
||||||
}" :position="selectedPosition" :allPositions="allPositions">
|
}" :position="selectedPosition" :allPositions="allPositions">
|
||||||
</PositionUpsertModal>
|
</PositionFormDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -107,8 +107,8 @@ import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
|||||||
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
||||||
import TablePagination from "@/components/tables/TablePagination.vue";
|
import TablePagination from "@/components/tables/TablePagination.vue";
|
||||||
import PlusIcon from "@/components/icons/PlusIcon.vue";
|
import PlusIcon from "@/components/icons/PlusIcon.vue";
|
||||||
import PositionDeleteModal from "@/components/modals/PopupModal.vue";
|
import PositionDeleteModal from "@/components/modals/ConfirmationDialog.vue";
|
||||||
import PositionUpsertModal from "@/components/modals/PositionUpsertModal.vue";
|
import PositionFormDialog from "@/components/modals/PositionFormDialog.vue";
|
||||||
import usePositionDelete from "@/composables/position/usePositionDelete";
|
import usePositionDelete from "@/composables/position/usePositionDelete";
|
||||||
import { usePositionQuery } from "@/composables/position/usePositionQuery";
|
import { usePositionQuery } from "@/composables/position/usePositionQuery";
|
||||||
import { usePositionUpsert } from "@/composables/position/usePositionUpsert";
|
import { usePositionUpsert } from "@/composables/position/usePositionUpsert";
|
||||||
@@ -115,31 +115,31 @@
|
|||||||
<RoleDeleteModal :id="'role-delete-modal'" :closeModal="() => {
|
<RoleDeleteModal :id="'role-delete-modal'" :closeModal="() => {
|
||||||
roleDeleteModal!.hide();
|
roleDeleteModal!.hide();
|
||||||
}" :onSubmit="handleDeletedModalSubmit" title="确定删除该角色吗" content="删除角色"></RoleDeleteModal>
|
}" :onSubmit="handleDeletedModalSubmit" title="确定删除该角色吗" content="删除角色"></RoleDeleteModal>
|
||||||
<RoleUpsertModal :id="'role-upsert-modal'" :onSubmit="handleUpsertModalSubmit" :closeModal="() => {
|
<RoleFormDialog :id="'role-upsert-modal'" :onSubmit="handleUpsertModalSubmit" :closeModal="() => {
|
||||||
roleUpsertModal!.hide();
|
roleUpsertModal!.hide();
|
||||||
}" :role="selectedRole">
|
}" :role="selectedRole">
|
||||||
</RoleUpsertModal>
|
</RoleFormDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
|
import PlusIcon from "@/components/icons/PlusIcon.vue";
|
||||||
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
||||||
|
import RoleDeleteModal from "@/components/modals/ConfirmationDialog.vue";
|
||||||
|
import RoleFormDialog from "@/components/modals/RoleFormDialog.vue";
|
||||||
import MobileCardList from "@/components/tables/MobileCardList.vue";
|
import MobileCardList from "@/components/tables/MobileCardList.vue";
|
||||||
import TableButton from "@/components/tables/TableButton.vue";
|
import TableButton from "@/components/tables/TableButton.vue";
|
||||||
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
||||||
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
||||||
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
||||||
import TablePagination from "@/components/tables/TablePagination.vue";
|
import TablePagination from "@/components/tables/TablePagination.vue";
|
||||||
import PlusIcon from "@/components/icons/PlusIcon.vue";
|
|
||||||
import RoleDeleteModal from "@/components/modals/PopupModal.vue";
|
|
||||||
import RoleUpsertModal from "@/components/modals/RoleUpsertModal.vue";
|
|
||||||
import useRoleDelete from "@/composables/role/useRoleDelete";
|
import useRoleDelete from "@/composables/role/useRoleDelete";
|
||||||
import { useRolesQuery } from "@/composables/role/useRolesQuery";
|
|
||||||
import { useRoleUpsert } from "@/composables/role/useRoleUpsert";
|
import { useRoleUpsert } from "@/composables/role/useRoleUpsert";
|
||||||
|
import { useRolesQuery } from "@/composables/role/useRolesQuery";
|
||||||
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
import { Routes } from "@/router/constants";
|
import { Routes } from "@/router/constants";
|
||||||
import type { RoleUpsertModel } from "@/types/role";
|
import type { RoleUpsertModel } from "@/types/RoleTypes";
|
||||||
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";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
@@ -91,22 +91,22 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
||||||
|
import BindModal from "@/components/modals/ConfirmationDialog.vue";
|
||||||
|
import UnModal from "@/components/modals/ConfirmationDialog.vue";
|
||||||
import MobileCardListWithCheckbox from "@/components/tables/MobileCardListWithCheckbox.vue";
|
import MobileCardListWithCheckbox from "@/components/tables/MobileCardListWithCheckbox.vue";
|
||||||
import TableButton from "@/components/tables/TableButton.vue";
|
import TableButton from "@/components/tables/TableButton.vue";
|
||||||
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
||||||
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
||||||
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
import TableFormLayout from "@/components/tables/TableFormLayout.vue";
|
||||||
import TablePagination from "@/components/tables/TablePagination.vue";
|
import TablePagination from "@/components/tables/TablePagination.vue";
|
||||||
import BindModal from "@/components/modals/PopupModal.vue";
|
|
||||||
import UnModal from "@/components/modals/PopupModal.vue";
|
|
||||||
import { usePermissionBind } from "@/composables/permission/usePermissionBind";
|
import { usePermissionBind } from "@/composables/permission/usePermissionBind";
|
||||||
|
import usePermissionsQuery from "@/composables/permission/usePermissionQuery";
|
||||||
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
import { useActionExcStore } from "@/composables/store/useActionExcStore";
|
||||||
import useAlertStore from "@/composables/store/useAlertStore";
|
import useAlertStore from "@/composables/store/useAlertStore";
|
||||||
import { Routes } 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";
|
||||||
import usePermissionsQuery from "@/composables/permission/usePermissionQuery";
|
|
||||||
|
|
||||||
// 定义筛选配置
|
// 定义筛选配置
|
||||||
const filterConfig: FilterItem[] = [
|
const filterConfig: FilterItem[] = [
|
||||||
@@ -140,15 +140,16 @@
|
|||||||
<PopupModal :id="'job-pause-modal'" :closeModal="() => {
|
<PopupModal :id="'job-pause-modal'" :closeModal="() => {
|
||||||
jobPauseModal!.hide();
|
jobPauseModal!.hide();
|
||||||
}" :onSubmit="handlePauseModalSubmit" title="确定暂停该任务吗" content="暂停任务"></PopupModal>
|
}" :onSubmit="handlePauseModalSubmit" title="确定暂停该任务吗" content="暂停任务"></PopupModal>
|
||||||
<SchedulerUpdateModal :job="selectedJob" :id="'job-update-modal'" :closeModal="() => {
|
<SchedulerFormDialog :job="selectedJob" :id="'job-update-modal'" :closeModal="() => {
|
||||||
jobUpdateModal!.hide();
|
jobUpdateModal!.hide();
|
||||||
}" :onSubmit="handleUpdateModalSubmit"></SchedulerUpdateModal>
|
}" :onSubmit="handleUpdateModalSubmit"></SchedulerFormDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
import Breadcrumbs from "@/components/layout/Breadcrumbs.vue";
|
||||||
import PopupModal from "@/components/modals/PopupModal.vue";
|
import PopupModal from "@/components/modals/ConfirmationDialog.vue";
|
||||||
import SchedulerUpdateModal from "@/components/modals/SchedulerUpdateModal.vue";
|
import SchedulerFormDialog from "@/components/modals/SchedulerFormDialog.vue";
|
||||||
|
|
||||||
import MobileCardList from "@/components/tables/MobileCardList.vue";
|
import MobileCardList from "@/components/tables/MobileCardList.vue";
|
||||||
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
import TableFilterForm from "@/components/tables/TableFilterForm.vue";
|
||||||
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
import type { FilterItem } from "@/components/tables/TableFilterForm.vue";
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user