mirror of
https://github.com/ccmjga/zhilu-admin
synced 2026-03-24 11:53:41 +08:00
fix bugs
This commit is contained in:
@@ -96,7 +96,7 @@
|
||||
<td scope="row" class="px-6 py-4whitespace-nowrap font-medium text-gray-900 dark:text-white">
|
||||
{{ department.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<div class="flex items-center">
|
||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="department.isBound ? 'bg-green-500' : 'bg-red-500'">
|
||||
</div> {{
|
||||
@@ -119,6 +119,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import BindModal from "@/components/PopupModal.vue";
|
||||
import UnModal from "@/components/PopupModal.vue";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
@@ -129,7 +130,6 @@ import { onMounted, ref, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useDepartmentBind } from "../composables/department/useDepartmentBind";
|
||||
import useAlertStore from "../composables/store/useAlertStore";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
|
||||
const departmentName = ref<string>("");
|
||||
const checkedDepartmentIds = ref<number[]>([]);
|
||||
@@ -137,7 +137,7 @@ const departmentBindModal = ref<ModalInterface>();
|
||||
const departmentUnbindModal = ref<ModalInterface>();
|
||||
const allChecked = ref<boolean>(false);
|
||||
const $route = useRoute();
|
||||
const bindState = ref<"BIND" | "ALL" | "UNBIND">("BIND");
|
||||
const bindState = ref<"BIND" | "ALL" | "UNBIND">("ALL");
|
||||
|
||||
const alertStore = useAlertStore();
|
||||
|
||||
@@ -151,6 +151,7 @@ const handleBindDepartmentSubmit = async () => {
|
||||
checkedDepartmentIds.value,
|
||||
);
|
||||
clearCheckedDepartment();
|
||||
allChecked.value = false;
|
||||
departmentBindModal.value?.hide();
|
||||
alertStore.showAlert({
|
||||
content: "操作成功",
|
||||
@@ -169,6 +170,7 @@ const handleUnbindDepartmentSubmit = async () => {
|
||||
checkedDepartmentIds.value,
|
||||
);
|
||||
clearCheckedDepartment();
|
||||
allChecked.value = false;
|
||||
departmentUnbindModal.value?.hide();
|
||||
alertStore.showAlert({
|
||||
content: "操作成功",
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
<td scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||
{{ permission.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<div class="flex items-center">
|
||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="permission.isBound ? 'bg-green-500' : 'bg-red-500'">
|
||||
</div> {{
|
||||
@@ -120,6 +120,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import BindModal from "@/components/PopupModal.vue";
|
||||
import UnModal from "@/components/PopupModal.vue";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
@@ -130,7 +131,6 @@ import { useRoute } from "vue-router";
|
||||
import { usePermissionBind } from "../composables/permission/usePermissionBind";
|
||||
import usePermissionsQuery from "../composables/permission/usePermissionQuery";
|
||||
import useAlertStore from "../composables/store/useAlertStore";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
|
||||
const permissionName = ref<string>("");
|
||||
const checkedPermissionIds = ref<number[]>([]);
|
||||
@@ -138,7 +138,7 @@ const permissionBindModal = ref<ModalInterface>();
|
||||
const permissionUnbindModal = ref<ModalInterface>();
|
||||
const allChecked = ref<boolean>(false);
|
||||
const $route = useRoute();
|
||||
const bindState = ref<"BIND" | "ALL" | "UNBIND">("BIND");
|
||||
const bindState = ref<"BIND" | "ALL" | "UNBIND">("ALL");
|
||||
|
||||
const alertStore = useAlertStore();
|
||||
const { total, permissions, fetchPermissionsWith } = usePermissionsQuery();
|
||||
@@ -155,6 +155,7 @@ const handleBindPermissionSubmit = async () => {
|
||||
level: "success",
|
||||
});
|
||||
clearCheckedRoleIds();
|
||||
allChecked.value = false;
|
||||
await fetchPermissionsWith({
|
||||
name: permissionName.value,
|
||||
roleId: Number($route.params.roleId),
|
||||
@@ -173,6 +174,7 @@ const handleUnbindPermissionSubmit = async () => {
|
||||
level: "success",
|
||||
});
|
||||
clearCheckedRoleIds();
|
||||
allChecked.value = false;
|
||||
await fetchPermissionsWith({
|
||||
name: permissionName.value,
|
||||
roleId: Number($route.params.roleId),
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<td scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||
{{ position.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<div class="flex items-center">
|
||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="position.isBound ? 'bg-green-500' : 'bg-red-500'">
|
||||
</div> {{
|
||||
@@ -116,6 +116,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import BindModal from "@/components/PopupModal.vue";
|
||||
import UnModal from "@/components/PopupModal.vue";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
@@ -126,7 +127,6 @@ import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import useAlertStore from "../composables/store/useAlertStore";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
|
||||
const positionName = ref<string>("");
|
||||
const checkedPositionIds = ref<number[]>([]);
|
||||
@@ -134,7 +134,7 @@ const positionBindModal = ref<ModalInterface>();
|
||||
const positionUnbindModal = ref<ModalInterface>();
|
||||
const allChecked = ref<boolean>(false);
|
||||
const $route = useRoute();
|
||||
const bindState = ref<"BIND" | "ALL" | "UNBIND">("BIND");
|
||||
const bindState = ref<"BIND" | "ALL" | "UNBIND">("ALL");
|
||||
|
||||
const alertStore = useAlertStore();
|
||||
|
||||
@@ -155,6 +155,7 @@ const handleBindPositionSubmit = async () => {
|
||||
bindState: bindState.value,
|
||||
});
|
||||
clearCheckedPositionIds();
|
||||
allChecked.value = false;
|
||||
};
|
||||
|
||||
const handleUnbindPositionSubmit = async () => {
|
||||
@@ -170,6 +171,7 @@ const handleUnbindPositionSubmit = async () => {
|
||||
bindState: bindState.value,
|
||||
});
|
||||
clearCheckedPositionIds();
|
||||
allChecked.value = false;
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
<td scope="row" class="px-6 py-4 whitespace-nowrap dark:text-white">
|
||||
{{ role.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<div class="flex items-center">
|
||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="role.isBound ? 'bg-green-500' : 'bg-red-500'">
|
||||
</div> {{
|
||||
@@ -118,18 +118,18 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import BindModal from "@/components/PopupModal.vue";
|
||||
import UnModal from "@/components/PopupModal.vue";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
import { useRolesQuery } from "@/composables/role/useRolesQuery";
|
||||
import { RouteName } from "@/router/constants";
|
||||
import { tr } from "@faker-js/faker";
|
||||
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useRoleBind } from "../composables/role/useRoleBind";
|
||||
import useAlertStore from "../composables/store/useAlertStore";
|
||||
import { tr } from "@faker-js/faker";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
|
||||
const roleName = ref<string>("");
|
||||
const checkedRoleIds = ref<number[]>([]);
|
||||
@@ -137,7 +137,7 @@ const roleBindModal = ref<ModalInterface>();
|
||||
const roleUnbindModal = ref<ModalInterface>();
|
||||
const allChecked = ref<boolean>(false);
|
||||
const $route = useRoute();
|
||||
const bindState = ref<"BIND" | "ALL" | "UNBIND">("BIND");
|
||||
const bindState = ref<"BIND" | "ALL" | "UNBIND">("ALL");
|
||||
|
||||
const alertStore = useAlertStore();
|
||||
const { total, roles, fetchRolesWith } = useRolesQuery();
|
||||
@@ -150,6 +150,7 @@ const handleBindRoleSubmit = async () => {
|
||||
});
|
||||
roleBindModal.value?.hide();
|
||||
clearCheckedRoleIds();
|
||||
allChecked.value = false;
|
||||
alertStore.showAlert({
|
||||
content: "操作成功",
|
||||
level: "success",
|
||||
@@ -164,6 +165,7 @@ const handleBindRoleSubmit = async () => {
|
||||
const handleUnbindRoleSubmit = async () => {
|
||||
await unbindRole(Number($route.params.userId), checkedRoleIds.value);
|
||||
clearCheckedRoleIds();
|
||||
allChecked.value = false;
|
||||
roleUnbindModal.value?.hide();
|
||||
alertStore.showAlert({
|
||||
content: "操作成功",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="relative overflow-x-auto px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="mb-4 col-span-full">
|
||||
<Breadcrumbs :names="['部门管理']" />
|
||||
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">部门管理</h1>
|
||||
@@ -31,68 +31,70 @@
|
||||
新增部门
|
||||
</button>
|
||||
</div>
|
||||
<div class="relative overflow-x-auto">
|
||||
<table class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">上级部门</th>
|
||||
<th scope="col" class="px-6 py-3">部门名称</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="department in departments" :key="department.id"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + department.id" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + department.id" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
{{ !department.parentName ? '无' : department.parentName }}
|
||||
</td>
|
||||
<td class="px-6 py-4 font-medium text-gray-900 ">
|
||||
{{ department.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleUpsertDepartmentClick(department)"
|
||||
class="flex items-center justify-center min-w-25 gap-x-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 "
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span>编辑</span>
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center justify-center min-w-25 gap-x-1
|
||||
bg-red-700 hover:bg-red-800 dark:bg-red-600 dark:hover:bg-red-700
|
||||
focus:ring-red-500 text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5"
|
||||
@click="handleDeleteDepartmentClick(department)" type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span>删除</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<table class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">上级部门</th>
|
||||
<th scope="col" class="px-6 py-3">部门名称</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="department in departments" :key="department.id"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + department.id" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + department.id" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
{{ !department.parentName ? '无' : department.parentName }}
|
||||
</td>
|
||||
<td class="px-6 py-4 font-medium text-gray-900 ">
|
||||
{{ department.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleUpsertDepartmentClick(department)"
|
||||
class="flex items-center gap-x-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 "
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center block gap-x-1
|
||||
bg-red-700 hover:bg-red-800 focus:outline-none dark:bg-red-600 dark:hover:bg-red-700
|
||||
focus:ring-red-500 block text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center"
|
||||
@click="handleDeleteDepartmentClick(department)" type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<TablePagination :total="total" :pageChange="handlePageChange" />
|
||||
</div>
|
||||
|
||||
@@ -100,16 +102,18 @@
|
||||
departmentDeleteModal!.hide();
|
||||
}" :onSubmit="handleDeleteDepartmentSubmit" title="确定删除该部门吗" content="删除部门"></DepartmentDeleteModal>
|
||||
<DepartmentUpsertModal :id="'department-upsert-modal'" :onSubmit="handleUpsertDepartmentSubmit" :closeModal="() => {
|
||||
availableDepartments = undefined
|
||||
departmentUpsertModal!.hide();
|
||||
}" :department="selectedDepartment" :allDepartments="allDepartments">
|
||||
}" :department="selectedDepartment" :availableDepartments="availableDepartments">
|
||||
</DepartmentUpsertModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import DepartmentUpsertModal from "@/components/DepartmentUpsertModal.vue";
|
||||
import DepartmentDeleteModal from "@/components/PopupModal.vue";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
import DepartmentUpsertModal from "@/components/DepartmentUpsertModal.vue";
|
||||
import { RouteName } from "@/router/constants";
|
||||
import type { DepartmentUpsertModel } from "@/types/department";
|
||||
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||
import { nextTick, onMounted, ref } from "vue";
|
||||
import type { components } from "../api/types/schema";
|
||||
@@ -117,8 +121,6 @@ import useDepartmentDelete from "../composables/department/useDepartmentDelete";
|
||||
import { useDepartmentQuery } from "../composables/department/useDepartmentQuery";
|
||||
import { useDepartmentUpsert } from "../composables/department/useDepartmentUpsert";
|
||||
import useAlertStore from "../composables/store/useAlertStore";
|
||||
import type { DepartmentUpsertModel } from "@/types/department";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
|
||||
const name = ref<string>("");
|
||||
const selectedDepartment = ref<components["schemas"]["Department"]>();
|
||||
@@ -127,10 +129,10 @@ const departmentDeleteModal = ref<ModalInterface>();
|
||||
|
||||
const {
|
||||
departments,
|
||||
allDepartments,
|
||||
availableDepartments,
|
||||
fetchDepartmentWith,
|
||||
fetchAllDepartments,
|
||||
total,
|
||||
fetchAvailableDepartments,
|
||||
} = useDepartmentQuery();
|
||||
|
||||
const { deleteDepartment } = useDepartmentDelete();
|
||||
@@ -139,7 +141,6 @@ const { upsertDepartment } = useDepartmentUpsert();
|
||||
const alertStore = useAlertStore();
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchAllDepartments();
|
||||
await fetchDepartmentWith({
|
||||
name: name.value,
|
||||
});
|
||||
@@ -178,13 +179,13 @@ const handleUpsertDepartmentSubmit = async (
|
||||
await fetchDepartmentWith({
|
||||
name: name.value,
|
||||
});
|
||||
fetchAllDepartments();
|
||||
};
|
||||
|
||||
const handleUpsertDepartmentClick = async (
|
||||
department?: components["schemas"]["Department"],
|
||||
) => {
|
||||
selectedDepartment.value = department;
|
||||
await fetchAvailableDepartments(selectedDepartment.value?.id);
|
||||
await nextTick(() => {
|
||||
departmentUpsertModal.value?.show();
|
||||
});
|
||||
@@ -201,7 +202,6 @@ const handleDeleteDepartmentSubmit = async () => {
|
||||
await fetchDepartmentWith({
|
||||
name: name.value,
|
||||
});
|
||||
fetchAllDepartments();
|
||||
};
|
||||
|
||||
const handleDeleteDepartmentClick = async (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="relative overflow-x-auto px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="mb-4 col-span-full">
|
||||
<Breadcrumbs :names="['权限管理']" />
|
||||
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">权限管理</h1>
|
||||
@@ -31,66 +31,68 @@
|
||||
新增权限
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">权限名称</th>
|
||||
<th scope="col" class="px-6 py-3">权限编码</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="permission in permissions" :key="permission.id"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + permission.id" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + permission.id" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||
{{ permission.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4">{{ permission.code }}</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleUpsertPermissionClick(permission)"
|
||||
class="flex items-center block gap-x-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 "
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center block gap-x-1
|
||||
<div class="relative overflow-x-auto">
|
||||
<table class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">权限名称</th>
|
||||
<th scope="col" class="px-6 py-3">权限编码</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="permission in permissions" :key="permission.id"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + permission.id" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + permission.id" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||
{{ permission.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">{{ permission.code }}</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleUpsertPermissionClick(permission)"
|
||||
class="flex items-center justify-center min-w-25 gap-x-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 "
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span>编辑</span>
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center justify-center min-w-25 gap-x-1
|
||||
bg-red-700 hover:bg-red-800 focus:outline-none dark:bg-red-600 dark:hover:bg-red-700
|
||||
focus:ring-red-500 block text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center"
|
||||
@click="handleDeletePermissionClick(permission)" type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
focus:ring-red-500 text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 "
|
||||
@click="handleDeletePermissionClick(permission)" type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span>删除</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<TablePagination :pageChange="handlePageChange" :total="total" />
|
||||
</div>
|
||||
@@ -110,15 +112,14 @@ import PermissionDeleteModal from "@/components/PopupModal.vue";
|
||||
import usePermissionDelete from "@/composables/permission/usePermissionDelete";
|
||||
|
||||
import type { components } from "@/api/types/schema";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
import { RouteName } from "@/router/constants";
|
||||
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||
import { nextTick, onMounted, ref } from "vue";
|
||||
import usePermissionsQuery from "../composables/permission/usePermissionQuery";
|
||||
import usePermissionUpsert from "../composables/permission/usePermissionUpsert";
|
||||
import useAlertStore from "../composables/store/useAlertStore";
|
||||
import type { PermissionUpsertModel } from "../types/permission";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
|
||||
const permissionName = ref<string>("");
|
||||
const selectedPermission = ref<components["schemas"]["PermissionRespDto"]>();
|
||||
@@ -175,7 +176,7 @@ const handleUpsertPermissionClick = async (
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeleteModalSubmit = async (event: Event) => {
|
||||
const handleDeleteModalSubmit = async () => {
|
||||
if (!selectedPermission?.value?.id) return;
|
||||
await deletePermission(selectedPermission.value.id);
|
||||
permissionDeleteModal.value?.hide();
|
||||
@@ -183,6 +184,9 @@ const handleDeleteModalSubmit = async (event: Event) => {
|
||||
content: "删除成功",
|
||||
level: "success",
|
||||
});
|
||||
await fetchPermissionsWith({
|
||||
name: permissionName.value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeletePermissionClick = async (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="relative overflow-x-auto px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="mb-4 col-span-full">
|
||||
<Breadcrumbs :names="['岗位管理']" />
|
||||
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">岗位管理</h1>
|
||||
@@ -32,63 +32,65 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">岗位名称</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="position in positions" :key="position.id"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + position.id" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + position.id" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 font-medium text-gray-900 ">
|
||||
{{ position.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleUpsertPositionClick(position)"
|
||||
class="flex items-center block gap-x-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 "
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center block gap-x-1
|
||||
bg-red-700 hover:bg-red-800 focus:outline-none dark:bg-red-600 dark:hover:bg-red-700
|
||||
focus:ring-red-500 block text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center"
|
||||
@click="handleDeletePositionClick(position)" type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="relative overflow-x-auto">
|
||||
<table class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">岗位名称</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="position in positions" :key="position.id"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + position.id" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + position.id" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 font-medium text-gray-900 ">
|
||||
{{ position.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleUpsertPositionClick(position)"
|
||||
class="flex items-center justify-center min-w-25 gap-x-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 "
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span>编辑</span>
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center justify-center min-w-25 gap-x-1
|
||||
bg-red-700 hover:bg-red-800 dark:bg-red-600 dark:hover:bg-red-700
|
||||
focus:ring-red-500 text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center"
|
||||
@click="handleDeletePositionClick(position)" type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span>删除</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<TablePagination :total="total" :pageChange="handlePageChange" />
|
||||
</div>
|
||||
|
||||
@@ -103,9 +105,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import PositionDeleteModal from "@/components/PopupModal.vue";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
import PositionUpsertModal from "@/components/PositionUpsertModal.vue";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
import usePositionDelete from "@/composables/position/usePositionDelete";
|
||||
import { usePositionQuery } from "@/composables/position/usePositionQuery";
|
||||
import { usePositionUpsert } from "@/composables/position/usePositionUpsert";
|
||||
@@ -114,7 +117,6 @@ import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||
import { nextTick, onMounted, ref } from "vue";
|
||||
import type { components } from "../api/types/schema";
|
||||
import useAlertStore from "../composables/store/useAlertStore";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
|
||||
const name = ref<string>("");
|
||||
const selectedPosition = ref<components["schemas"]["Position"]>();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="relative overflow-x-auto px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="mb-4 col-span-full">
|
||||
<Breadcrumbs :names="['角色管理']" />
|
||||
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">角色管理</h1>
|
||||
@@ -31,77 +31,77 @@
|
||||
新增角色
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">角色名称</th>
|
||||
<th scope="col" class="px-6 py-3">角色编码</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
<th scope="col" class="px-6 py-3">分配</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="role in roles" :key="role.id"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + role.id" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + role.id" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||
{{ role.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4">{{ role.code }}</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleUpsertRoleClick(role)"
|
||||
class="flex items-center block gap-x-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 "
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center block gap-x-1
|
||||
<div class="relative overflow-x-auto ">
|
||||
<table class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">角色名称</th>
|
||||
<th scope="col" class="px-6 py-3">角色编码</th>
|
||||
<th scope="col" class="px-6 py-3">分配</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="role in roles" :key="role.id"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + role.id" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + role.id" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||
{{ role.name }}
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">{{ role.code }}</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<div>
|
||||
<button
|
||||
class="flex itmes-center justify-center min-w-min text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 font-medium rounded-lg text-sm px-4 py-2.5 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700"
|
||||
@click="handleBindPermissionClick(role)" type="button">
|
||||
<span>分配权限</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleUpsertRoleClick(role)"
|
||||
class="flex items-center justify-center min-w-25 gap-x-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 "
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span>编辑</span>
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center justify-center min-w-25 block gap-x-1
|
||||
bg-red-700 hover:bg-red-800 focus:outline-none dark:bg-red-600 dark:hover:bg-red-700
|
||||
focus:ring-red-500 block text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center"
|
||||
@click="handleDeleteRoleClick(role)" type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div>
|
||||
<button
|
||||
class="flex itmes-center text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 font-medium rounded-lg text-sm px-4 py-2.5 text-center dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700"
|
||||
@click="handleBindPermissionClick(role)" type="button">
|
||||
分配权限
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
focus:ring-red-500 block text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5"
|
||||
@click="handleDeleteRoleClick(role)" type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span>删除</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<TablePagination :pageChange="handlePageChange" :total="total" />
|
||||
</div>
|
||||
|
||||
@@ -115,6 +115,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import RoleDeleteModal from "@/components/PopupModal.vue";
|
||||
import RoleUpsertModal from "@/components/RoleUpsertModal.vue";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
@@ -128,7 +129,6 @@ import { useRouter } from "vue-router";
|
||||
import type { components } from "../api/types/schema";
|
||||
import { useRoleUpsert } from "../composables/role/useRoleUpsert";
|
||||
import useAlertStore from "../composables/store/useAlertStore";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
|
||||
const roleName = ref<string>("");
|
||||
const selectedRole = ref<components["schemas"]["RoleDto"]>();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="relative overflow-x-auto px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="mb-4 col-span-full">
|
||||
<Breadcrumbs :names="['任务管理']" />
|
||||
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">任务管理</h1>
|
||||
@@ -27,86 +27,97 @@
|
||||
<!-- Create Modal toggle -->
|
||||
</div>
|
||||
|
||||
<table
|
||||
class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400 overflow-x-auto">
|
||||
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">任务</th>
|
||||
<th scope="col" class="px-6 py-3">触发器</th>
|
||||
<th scope="col" class="px-6 py-3">开始</th>
|
||||
<th scope="col" class="px-6 py-3">结束</th>
|
||||
<th scope="col" class="px-6 py-3">下次执行</th>
|
||||
<th scope="col" class="px-6 py-3">上次执行</th>
|
||||
<th scope="col" class="px-6 py-3">类型</th>
|
||||
<th scope="col" class="px-6 py-3">Cron</th>
|
||||
<th scope="col" class="px-6 py-3">状态</th>
|
||||
<th scope="col" class="px-6 py-3">编辑</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="job in jobs" :key="job.triggerName"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + job.name" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + job.name" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">{{
|
||||
`${job.name}:${job.group}` }}</td>
|
||||
<td class="px-6 py-4">{{ `${job.triggerName}:${job.triggerGroup}` }}</td>
|
||||
<td class="px-6 py-4">{{ new Date(job.startTime!).toLocaleString() }}</td>
|
||||
<td class="px-6 py-4">{{ job.endTime ? new Date(job.endTime).toLocaleString() : undefined }}</td>
|
||||
<td class="px-6 py-4">{{ job.nextFireTime ? new Date(job.nextFireTime).toLocaleString() : undefined}}</td>
|
||||
<td class="px-6 py-4">{{ job.previousFireTime && job.previousFireTime > 0 ? new
|
||||
Date(job.previousFireTime).toLocaleString() :
|
||||
undefined
|
||||
}}
|
||||
</td>
|
||||
<td class="px-6 py-4">{{ job.schedulerType }}</td>
|
||||
<td class="px-6 py-4">{{ job.cronExpression }}</td>
|
||||
<td class="px-6 py-4">{{ job.triggerState }}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleCronUpdateClick(job)" :disabled="job.schedulerType !== 'CRON'"
|
||||
:class="['flex items-center gap-x-1 block text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800' , { 'opacity-50 cursor-not-allowed': job.schedulerType !== 'CRON' }]"
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
编辑
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button
|
||||
:class="['text-white bg-green-700 hover:bg-green-800 focus:ring-green-300 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-900 focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center']"
|
||||
@click="handleResumeJobClick(job)" type="button">
|
||||
恢复
|
||||
</button>
|
||||
<button
|
||||
:class="['bg-red-700 hover:bg-red-800 focus:ring-red-300 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900 text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center']"
|
||||
@click="handlePauseJobClick(job)" type="button">
|
||||
暂停
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="relative overflow-x-auto">
|
||||
<table
|
||||
class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400 overflow-x-auto">
|
||||
<thead class="text-xs uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">任务</th>
|
||||
<th scope="col" class="px-6 py-3">触发器</th>
|
||||
<th scope="col" class="px-6 py-3">开始</th>
|
||||
<th scope="col" class="px-6 py-3">结束</th>
|
||||
<th scope="col" class="px-6 py-3">下次执行</th>
|
||||
<th scope="col" class="px-6 py-3">上次执行</th>
|
||||
<th scope="col" class="px-6 py-3">类型</th>
|
||||
<th scope="col" class="px-6 py-3">Cron</th>
|
||||
<th scope="col" class="px-6 py-3">状态</th>
|
||||
<th scope="col" class="px-6 py-3">编辑</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="job in jobs" :key="job.triggerName"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + job.triggerName" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + job.triggerName" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">{{
|
||||
`${job.name}:${job.group}` }}</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">{{
|
||||
`${job.triggerName}:${job.triggerGroup}` }}
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">{{ new
|
||||
Date(job.startTime!).toLocaleString() }}
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">{{ job.endTime ? new
|
||||
Date(job.endTime).toLocaleString() : undefined }}</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">{{ job.nextFireTime ? new
|
||||
Date(job.nextFireTime).toLocaleString() : undefined}}</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">{{ job.previousFireTime &&
|
||||
job.previousFireTime
|
||||
> 0 ? new
|
||||
Date(job.previousFireTime).toLocaleString() :
|
||||
undefined
|
||||
}}
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">{{ job.schedulerType }}</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">{{ job.cronExpression }}</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">{{ job.triggerState }}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleCronUpdateClick(job)" :disabled="job.schedulerType !== 'CRON'"
|
||||
:class="['flex items-center justify-center gap-x-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800' , { 'opacity-50 cursor-not-allowed': job.schedulerType !== 'CRON' }]"
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span>编辑</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center justify-center gap-x-2">
|
||||
<button
|
||||
:class="['text-white bg-green-700 hover:bg-green-800 focus:ring-green-300 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-900 focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center']"
|
||||
@click="handleResumeJobClick(job)" type="button">
|
||||
<span>恢复</span>
|
||||
</button>
|
||||
<button
|
||||
:class="['bg-red-700 hover:bg-red-800 focus:ring-red-300 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900 text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center']"
|
||||
@click="handlePauseJobClick(job)" type="button">
|
||||
<span>暂停</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<TablePagination :pageChange="handlePageChange" :total="total" />
|
||||
</div>
|
||||
|
||||
@@ -122,18 +133,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import SchedulerUpdateModal from "@/components/SchedulerUpdateModal.vue";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import PopupModal from "@/components/PopupModal.vue";
|
||||
import SchedulerUpdateModal from "@/components/SchedulerUpdateModal.vue";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
import { useJobControl } from "@/composables/job/useJobControl";
|
||||
import { useJobsPaginationQuery } from "@/composables/job/useJobQuery";
|
||||
import { useJobUpdate } from "@/composables/job/useJobUpdate";
|
||||
import useAlertStore from "@/composables/store/useAlertStore";
|
||||
import { RouteName } from "@/router/constants";
|
||||
import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
||||
import { nextTick, onMounted, ref } from "vue";
|
||||
import type { components } from "../api/types/schema";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
|
||||
const jobName = ref<string>("");
|
||||
const jobResumeModal = ref<ModalInterface>();
|
||||
|
||||
@@ -6,33 +6,6 @@
|
||||
</div>
|
||||
<!-- Right Content -->
|
||||
<div class="col-span-full xl:col-auto">
|
||||
<div
|
||||
class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
|
||||
<div class="items-center sm:flex xl:block 2xl:flex sm:space-x-4 xl:space-x-0 2xl:space-x-4">
|
||||
<img class="mb-4 rounded-lg w-28 h-28 sm:mb-0 xl:mb-4 2xl:mb-0" src="/trump.jpg" alt="Jese picture">
|
||||
<div>
|
||||
<h3 class="mb-1 text-xl font-bold text-gray-900 dark:text-white">个人资料</h3>
|
||||
<div class="mb-4 text-sm text-gray-500 dark:text-gray-400">
|
||||
JPG, GIF or PNG. Max size of 800K
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<button type="button" disabled
|
||||
class="cursor-not-allowed inline-flex items-center px-3 py-2 text-sm font-medium text-center text-white rounded-lg bg-blue-400 dark:bg-blue-500 ">
|
||||
<svg class="w-4 h-4 mr-2 -ml-1" fill="currentColor" viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M5.5 13a3.5 3.5 0 01-.369-6.98 4 4 0 117.753-1.977A4.5 4.5 0 1113.5 13H11V9.413l1.293 1.293a1 1 0 001.414-1.414l-3-3a1 1 0 00-1.414 0l-3 3a1 1 0 001.414 1.414L9 9.414V13H5.5z">
|
||||
</path>
|
||||
<path d="M9 13h2v5a1 1 0 11-2 0v-5z"></path>
|
||||
</svg>
|
||||
Upload picture
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col-span-1 row-start-3">
|
||||
<div
|
||||
@@ -62,8 +35,9 @@
|
||||
</div>
|
||||
<div class="col-span-6 ">
|
||||
<label for="category" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">状态</label>
|
||||
<select id="category" v-model="userForm.enable"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500">
|
||||
<select id="category" disabled v-model="userForm.enable"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5
|
||||
opacity-50 cursor-not-allowed dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500">
|
||||
<option :value=true>启用</option>
|
||||
<option :value=false>禁用</option>
|
||||
</select>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="relative overflow-x-auto px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="px-4 pt-6 xl:grid-cols-3 xl:gap-4 sm:rounded-lg">
|
||||
<div class="mb-4 col-span-full">
|
||||
<Breadcrumbs :names="['用户管理']" />
|
||||
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">用户管理</h1>
|
||||
@@ -31,101 +31,98 @@
|
||||
新增用户
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">用户名</th>
|
||||
<th scope="col" class="px-6 py-3">邮箱</th>
|
||||
<th scope="col" class="px-6 py-3">创建时间</th>
|
||||
<th scope="col" class="px-6 py-3">状态</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
<th scope="col" class="px-6 py-3">分配</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="user in users" :key="user.id"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + user.id" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + user.id" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||
{{ user.username }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
{{ user.username }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
{{ user.createTime }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center">
|
||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="user.enable ? 'bg-blue-500' : 'bg-red-500'"></div> {{
|
||||
user.enable === true ? "启用" : "禁用" }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<!-- Edit Modal toggle -->
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleUpsertUserClick(user)"
|
||||
class="flex items-center block gap-x-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center block gap-x-1
|
||||
<div class="relative overflow-x-auto">
|
||||
<table class="w-full text-sm text-left rtl:text-right shadow-lg rounded-lg text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-all-search" disabled type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label for="checkbox-all-search" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">用户名</th>
|
||||
<th scope="col" class="px-6 py-3">创建时间</th>
|
||||
<th scope="col" class="px-6 py-3">状态</th>
|
||||
<th scope="col" class="px-6 py-3">分配</th>
|
||||
<th scope="col" class="px-6 py-3">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="user in users" :key="user.id"
|
||||
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
|
||||
<td class="w-4 p-4">
|
||||
<div class="flex items-center">
|
||||
<input :id="'checkbox-table-search-' + user.id" type="checkbox" disabled
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||
<label :for="'checkbox-table-search-' + user.id" class="sr-only">checkbox</label>
|
||||
</div>
|
||||
</td>
|
||||
<td scope="row"
|
||||
class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white max-w-sm overflow-hidden text-ellipsis">
|
||||
{{ user.username }}
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
{{ user.createTime }}
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<div class="flex items-center">
|
||||
<div class="h-2.5 w-2.5 rounded-full me-2" :class="user.enable ? 'bg-blue-500' : 'bg-red-500'"></div> {{
|
||||
user.enable === true ? "启用" : "禁用" }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button
|
||||
class="text-gray-900 bg-white border min-w-25 border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 font-medium rounded-lg text-sm px-4 py-2.5 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700"
|
||||
@click="handleBindRoleClick(user)" type="button">
|
||||
分配角色
|
||||
</button>
|
||||
<button
|
||||
class="text-gray-900 bg-white border min-w-25 border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 font-medium rounded-lg text-sm px-4 py-2.5 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700"
|
||||
@click="handleBindPositionClick(user)" type="button">
|
||||
分配岗位
|
||||
</button>
|
||||
<button
|
||||
class="text-gray-900 bg-white border min-w-25 border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 font-medium rounded-lg text-sm px-4 py-2.5 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700"
|
||||
@click="handleBindDepartmentClick(user)" type="button">
|
||||
分配部门
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 max-w-sm overflow-hidden text-ellipsis">
|
||||
<!-- Edit Modal toggle -->
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button @click="handleUpsertUserClick(user)"
|
||||
class="flex items-center justify-center min-w-25 gap-x-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||
type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"></path>
|
||||
<path fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span>编辑</span>
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center justify-center min-w-25 gap-x-1
|
||||
bg-red-700 hover:bg-red-800 focus:outline-none focus:ring-red-300 dark:bg-red-600 dark:hover:bg-red-700
|
||||
dark:focus:ring-red-900 block text-white focus:ring-4 focus:outline-nonefont-medium rounded-lg text-sm px-4 py-2.5 text-center"
|
||||
@click="handleDeleteUserClick(user)" type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<button
|
||||
class="flex itmes-center text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 font-medium rounded-lg text-sm px-4 py-2.5 text-center dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700"
|
||||
@click="handleBindRoleClick(user)" type="button">
|
||||
分配角色
|
||||
</button>
|
||||
<button
|
||||
class="flex itmes-center text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 font-medium rounded-lg text-sm px-4 py-2.5 text-center dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700"
|
||||
@click="handleBindPositionClick(user)" type="button">
|
||||
分配岗位
|
||||
</button>
|
||||
<button
|
||||
class="flex itmes-center text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 font-medium rounded-lg text-sm px-4 py-2.5 text-center dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700"
|
||||
@click="handleBindDepartmentClick(user)" type="button">
|
||||
分配部门
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
dark:focus:ring-red-900 text-white focus:ring-4 focus:outline-nonefont-medium rounded-lg text-sm px-4 py-2.5"
|
||||
@click="handleDeleteUserClick(user)" type="button">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span>删除</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<TablePagination :pageChange="handlePageChange" :total="total" />
|
||||
</div>
|
||||
|
||||
@@ -139,7 +136,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import UserDeleteModal from "@/components/PopupModal.vue";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
import UserUpsertModal from "@/components/UserUpsertModal.vue";
|
||||
import useUserDelete from "@/composables/user/useUserDelete";
|
||||
import { useUserQuery } from "@/composables/user/useUserQuery";
|
||||
@@ -151,8 +150,6 @@ import { useRouter } from "vue-router";
|
||||
import type { components } from "../api/types/schema";
|
||||
import useAlertStore from "../composables/store/useAlertStore";
|
||||
import { useUserUpsert } from "../composables/user/useUserUpsert";
|
||||
import TablePagination from "@/components/TablePagination.vue";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
|
||||
const username = ref<string>("");
|
||||
const selectedUser = ref<components["schemas"]["UserRolePermissionDto"]>();
|
||||
|
||||
Reference in New Issue
Block a user