mirror of
https://github.com/ccmjga/zhilu-admin
synced 2026-03-17 23:33:42 +08:00
init
This commit is contained in:
69
frontend/src/api/client.ts
Normal file
69
frontend/src/api/client.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import createClient, { type Middleware } from "openapi-fetch";
|
||||
import useAuthStore from "../composables/store/useAuthStore";
|
||||
import {
|
||||
ForbiddenError,
|
||||
SystemError,
|
||||
UnAuthError,
|
||||
InternalServerError,
|
||||
} from "../types/error";
|
||||
import type { paths } from "./types/schema"; // generated by openapi-typescript
|
||||
|
||||
const myMiddleware: Middleware = {
|
||||
onRequest({ request, options }) {
|
||||
const authStore = useAuthStore();
|
||||
request.headers.set("Authorization", authStore.get());
|
||||
return request;
|
||||
},
|
||||
async onResponse({ request, response, options }) {
|
||||
const { body, ...resOptions } = response;
|
||||
if (response.status >= 400 && response.status < 500) {
|
||||
if (response.status === 401) {
|
||||
handleAuthError(response);
|
||||
} else if (response.status === 403) {
|
||||
handleForbiddenError(response);
|
||||
} else {
|
||||
handleSystemError(response);
|
||||
}
|
||||
} else if (response.status >= 500) {
|
||||
await handleBusinessError(response);
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
},
|
||||
async onError({ error }) {
|
||||
// wrap errors thrown by fetch
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
const client = createClient<paths>({
|
||||
baseUrl: `${import.meta.env.VITE_BASE_URL}`,
|
||||
querySerializer: {
|
||||
object: {
|
||||
style: "form",
|
||||
explode: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// register middleware
|
||||
client.use(myMiddleware);
|
||||
|
||||
const handleAuthError = (response: Response) => {
|
||||
throw new UnAuthError(response.status);
|
||||
};
|
||||
|
||||
const handleForbiddenError = (response: Response) => {
|
||||
throw new ForbiddenError(response.status);
|
||||
};
|
||||
|
||||
const handleSystemError = (response: Response) => {
|
||||
throw new SystemError(response.status);
|
||||
};
|
||||
|
||||
const handleBusinessError = async (response: Response) => {
|
||||
const data = await response.json();
|
||||
throw new InternalServerError(response.status, data.detail);
|
||||
};
|
||||
|
||||
export default client;
|
||||
10
frontend/src/api/mocks/authHandlers.ts
Normal file
10
frontend/src/api/mocks/authHandlers.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { http, HttpResponse } from "msw";
|
||||
|
||||
export default [
|
||||
http.post("/auth/sign-in", () => {
|
||||
const response = HttpResponse.json();
|
||||
response.headers.set("Authorization", faker.string.alpha(16));
|
||||
return response;
|
||||
}),
|
||||
];
|
||||
39
frontend/src/api/mocks/departmentHandlers.ts
Normal file
39
frontend/src/api/mocks/departmentHandlers.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { http, HttpResponse } from "msw";
|
||||
|
||||
export default [
|
||||
http.get("/department/page-query", () => {
|
||||
const generateDepartment = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
name: faker.company.name(),
|
||||
parentId: faker.number.int({ min: 1, max: 100 }),
|
||||
isBound: faker.datatype.boolean(),
|
||||
parentName: faker.company.name(),
|
||||
});
|
||||
const mockData = {
|
||||
data: faker.helpers.multiple(generateDepartment, { count: 10 }),
|
||||
total: 30,
|
||||
};
|
||||
return HttpResponse.json(mockData);
|
||||
}),
|
||||
http.get("/department/query", () => {
|
||||
const generateDepartment = () => ({
|
||||
id: faker.number.int({ min: 1, max: 30 }),
|
||||
name: faker.company.name(),
|
||||
parentId: faker.number.int({ min: 1, max: 30 }),
|
||||
parentName: faker.company.name(),
|
||||
});
|
||||
const mockData = faker.helpers.multiple(generateDepartment, { count: 30 });
|
||||
|
||||
return HttpResponse.json(mockData);
|
||||
}),
|
||||
|
||||
http.post("/department", () => {
|
||||
console.log("Captured department upsert");
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.delete("/department", () => {
|
||||
console.log("Captured department delete");
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
];
|
||||
43
frontend/src/api/mocks/permissionHandlers.ts
Normal file
43
frontend/src/api/mocks/permissionHandlers.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { http, HttpResponse } from "msw";
|
||||
|
||||
export default [
|
||||
http.get("/iam/permissions", () => {
|
||||
const generatePermission = () => ({
|
||||
id: faker.number.int({ min: 1, max: 20 }),
|
||||
code: `perm_${faker.lorem.words({ min: 1, max: 1 })}`,
|
||||
name: faker.lorem.words({ min: 1, max: 1 }),
|
||||
isBound: faker.datatype.boolean(),
|
||||
});
|
||||
|
||||
const mockData = {
|
||||
data: faker.helpers.multiple(generatePermission, { count: 10 }),
|
||||
total: 20,
|
||||
};
|
||||
return HttpResponse.json(mockData);
|
||||
}),
|
||||
|
||||
http.post("/iam/permission", async ({ request }) => {
|
||||
console.log('Captured a "POST /posts" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
|
||||
http.delete("/iam/permission", ({ params }) => {
|
||||
console.log(`Captured a "DELETE /posts/${params.id}" request`);
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
|
||||
http.post("/iam/roles/:roleId/bind-permission", ({ params, request }) => {
|
||||
console.log(
|
||||
`Captured a "POST /urp/roles/${params.roleId}/bind-permission" request`,
|
||||
);
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
|
||||
http.post("/iam/roles/:roleId/unbind-permission", ({ params, request }) => {
|
||||
console.log(
|
||||
`Captured a "POST /urp/roles/${params.roleId}/unbind-permission" request`,
|
||||
);
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
];
|
||||
35
frontend/src/api/mocks/positionHandlers.ts
Normal file
35
frontend/src/api/mocks/positionHandlers.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { http, HttpResponse } from "msw";
|
||||
|
||||
export default [
|
||||
http.get("/position/page-query", () => {
|
||||
const generatePosition = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
name: faker.person.jobTitle(),
|
||||
isBound: faker.datatype.boolean(),
|
||||
});
|
||||
const mockData = {
|
||||
data: faker.helpers.multiple(generatePosition, { count: 10 }),
|
||||
total: 30,
|
||||
};
|
||||
return HttpResponse.json(mockData);
|
||||
}),
|
||||
http.get("/position/query", () => {
|
||||
const generatePosition = () => ({
|
||||
id: faker.number.int({ min: 1, max: 30 }),
|
||||
name: faker.person.jobTitle(),
|
||||
});
|
||||
const mockData = faker.helpers.multiple(generatePosition, { count: 30 });
|
||||
|
||||
return HttpResponse.json(mockData);
|
||||
}),
|
||||
|
||||
http.post("/position", () => {
|
||||
console.log("Captured position upsert");
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.delete("/position", () => {
|
||||
console.log("Captured position delete");
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
];
|
||||
77
frontend/src/api/mocks/roleHandlers.ts
Normal file
77
frontend/src/api/mocks/roleHandlers.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { http, HttpResponse } from "msw";
|
||||
|
||||
export default [
|
||||
http.get("/iam/roles", () => {
|
||||
const generatePermission = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
code: `perm_${faker.lorem.word()}`,
|
||||
name: faker.lorem.words({ min: 1, max: 3 }),
|
||||
});
|
||||
|
||||
const generateRole = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
code: faker.helpers.arrayElement([
|
||||
"admin",
|
||||
"editor",
|
||||
"viewer",
|
||||
"manager",
|
||||
]),
|
||||
name: faker.person.jobTitle(),
|
||||
isBound: faker.datatype.boolean(),
|
||||
permissions: faker.helpers.multiple(generatePermission, {
|
||||
count: { min: 1, max: 5 },
|
||||
}),
|
||||
});
|
||||
|
||||
const mockData = {
|
||||
data: faker.helpers.multiple(generateRole, { count: 10 }),
|
||||
total: 20,
|
||||
};
|
||||
|
||||
return HttpResponse.json(mockData);
|
||||
}),
|
||||
http.get("/iam/role", ({ params }) => {
|
||||
const generatePermission = () => ({
|
||||
id: faker.number.int({ min: 1, max: 10 }),
|
||||
code: `perm_${faker.lorem.word()}`,
|
||||
name: faker.lorem.words({ min: 1, max: 3 }),
|
||||
});
|
||||
|
||||
const generateRole = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
code: faker.helpers.arrayElement([
|
||||
"admin",
|
||||
"editor",
|
||||
"viewer",
|
||||
"manager",
|
||||
]),
|
||||
name: faker.person.jobTitle(),
|
||||
permissions: faker.helpers.multiple(generatePermission, {
|
||||
count: { min: 1, max: 5 },
|
||||
}),
|
||||
});
|
||||
|
||||
return HttpResponse.json(generateRole());
|
||||
}),
|
||||
|
||||
http.post("/iam/role", async ({ request }) => {
|
||||
console.log('Captured a "POST /urp/role" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
|
||||
http.post("/iam/permission/bind", async ({ request }) => {
|
||||
console.log('Captured a "POST /iam/permission/bind" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
|
||||
http.post("/iam/permission/unbind", async ({ request }) => {
|
||||
console.log('Captured a "POST /iam/permission/unbind" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
|
||||
http.delete("/iam/role", ({ params }) => {
|
||||
console.log(`Captured a "DELETE /urp/role ${params.id}" request`);
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
];
|
||||
53
frontend/src/api/mocks/schedulerHandlers.ts
Normal file
53
frontend/src/api/mocks/schedulerHandlers.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { http, HttpResponse } from "msw";
|
||||
|
||||
export default [
|
||||
http.get("/scheduler/page-query", () => {
|
||||
const generateJobs = () => ({
|
||||
name: faker.word.sample(),
|
||||
group: faker.helpers.arrayElement(["default", "system", "custom"]),
|
||||
className: `com.example.jobs.${faker.word.sample()}Job`,
|
||||
jobDataMap: {
|
||||
dirty: faker.datatype.boolean(),
|
||||
allowsTransientData: faker.datatype.boolean(),
|
||||
keys: faker.helpers.multiple(() => faker.word.sample(), { count: 3 }),
|
||||
empty: false,
|
||||
wrappedMap: {},
|
||||
},
|
||||
triggerName: faker.word.sample(),
|
||||
triggerGroup: faker.helpers.arrayElement(["DEFAULT", "SYSTEM"]),
|
||||
schedulerType: faker.helpers.arrayElement(["CRON", "SIMPLE"]),
|
||||
triggerState: faker.helpers.arrayElement(["PAUSE", "WAITING"]),
|
||||
cronExpression: "0 0/30 * * * ?",
|
||||
startTime: faker.date.past().getTime(),
|
||||
endTime: faker.date.future().getTime(),
|
||||
nextFireTime: faker.date.soon().getTime(),
|
||||
previousFireTime: faker.date.recent().getTime(),
|
||||
triggerJobDataMap: {
|
||||
dirty: faker.datatype.boolean(),
|
||||
allowsTransientData: true,
|
||||
keys: [],
|
||||
empty: true,
|
||||
wrappedMap: {},
|
||||
},
|
||||
});
|
||||
|
||||
const mockData = {
|
||||
data: faker.helpers.multiple(generateJobs, { count: 20 }),
|
||||
total: 20,
|
||||
};
|
||||
return HttpResponse.json(mockData);
|
||||
}),
|
||||
http.post("/scheduler/trigger/resume", () => {
|
||||
console.log('Captured a "POST /scheduler/trigger/resume" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.post("/scheduler/trigger/pause", () => {
|
||||
console.log('Captured a "POST /scheduler/trigger/pause" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.put("/scheduler/job/update", () => {
|
||||
console.log('Captured a "POST /scheduler/job/update" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
];
|
||||
17
frontend/src/api/mocks/setup.ts
Normal file
17
frontend/src/api/mocks/setup.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { setupWorker } from "msw/browser";
|
||||
import authHandlers from "./authHandlers";
|
||||
import jobHandlers from "./schedulerHandlers";
|
||||
import permissionHandlers from "./permissionHandlers";
|
||||
import roleHandlers from "./roleHandlers";
|
||||
import userHandlers from "./userHandlers";
|
||||
import departmentHandlers from "./departmentHandlers";
|
||||
import positionHandlers from "./positionHandlers";
|
||||
export const worker = setupWorker(
|
||||
...userHandlers,
|
||||
...authHandlers,
|
||||
...roleHandlers,
|
||||
...permissionHandlers,
|
||||
...jobHandlers,
|
||||
...departmentHandlers,
|
||||
...positionHandlers,
|
||||
);
|
||||
188
frontend/src/api/mocks/userHandlers.ts
Normal file
188
frontend/src/api/mocks/userHandlers.ts
Normal file
@@ -0,0 +1,188 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { http, HttpResponse } from "msw";
|
||||
import { ROLE } from "../../router/constants";
|
||||
|
||||
export default [
|
||||
http.get("/iam/user", () => {
|
||||
const generatePermission = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
code: `perm_${faker.lorem.words({ min: 1, max: 1 })}`,
|
||||
name: faker.lorem.words({ min: 1, max: 1 }),
|
||||
});
|
||||
|
||||
const generateRole = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
code: faker.helpers.arrayElement([
|
||||
ROLE.ADMIN,
|
||||
"editor",
|
||||
"viewer",
|
||||
"manager",
|
||||
]),
|
||||
name: faker.person.jobTitle(),
|
||||
permissions: faker.helpers.multiple(generatePermission, {
|
||||
count: { min: 1, max: 5 },
|
||||
}),
|
||||
});
|
||||
|
||||
const generateDepartment = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
code: `dept_${faker.lorem.word()}`,
|
||||
name: faker.company.name(),
|
||||
parentId: faker.number.int({ min: 1, max: 30 }),
|
||||
enable: faker.datatype.boolean(),
|
||||
});
|
||||
|
||||
const generateUser = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
username: faker.internet.email(),
|
||||
password: faker.internet.password(),
|
||||
enable: faker.datatype.boolean(),
|
||||
roles: faker.helpers.multiple(generateRole, {
|
||||
count: { min: 1, max: 3 },
|
||||
}),
|
||||
createTime: faker.date.recent({ days: 30 }).toISOString(),
|
||||
permissions: faker.helpers.multiple(generatePermission, {
|
||||
count: { min: 1, max: 5 },
|
||||
}),
|
||||
departments: faker.helpers.multiple(generateDepartment, {
|
||||
count: { min: 0, max: 3 },
|
||||
}),
|
||||
});
|
||||
|
||||
return HttpResponse.json(generateUser());
|
||||
}),
|
||||
http.get("/iam/users", () => {
|
||||
const generatePermission = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
code: `perm_${faker.lorem.word()}`,
|
||||
name: faker.lorem.words({ min: 1, max: 3 }),
|
||||
});
|
||||
|
||||
const generateRole = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
code: [ROLE.ADMIN, "editor", "viewer", "manager"],
|
||||
name: faker.person.jobTitle(),
|
||||
permissions: faker.helpers.multiple(generatePermission, {
|
||||
count: { min: 1, max: 5 },
|
||||
}),
|
||||
});
|
||||
|
||||
const generateDepartment = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
code: `dept_${faker.lorem.word()}`,
|
||||
name: faker.company.name(),
|
||||
parentId: faker.number.int({ min: 1, max: 30 }),
|
||||
enable: faker.datatype.boolean(),
|
||||
});
|
||||
|
||||
const generateUser = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
username: faker.internet.email(),
|
||||
password: faker.internet.password(),
|
||||
enable: faker.datatype.boolean(),
|
||||
roles: faker.helpers.multiple(generateRole, {
|
||||
count: { min: 1, max: 3 },
|
||||
}),
|
||||
createTime: faker.date.recent({ days: 30 }).toISOString(),
|
||||
permissions: faker.helpers.multiple(generatePermission, {
|
||||
count: { min: 1, max: 5 },
|
||||
}),
|
||||
departments: faker.helpers.multiple(generateDepartment, {
|
||||
count: { min: 0, max: 3 },
|
||||
}),
|
||||
});
|
||||
|
||||
const mockData = {
|
||||
data: faker.helpers.multiple(generateUser, { count: 10 }),
|
||||
total: 30,
|
||||
};
|
||||
return HttpResponse.json(mockData);
|
||||
}),
|
||||
http.post("/api/users/:userId/departments", () => {
|
||||
console.log('Captured a "POST /api/users/:userId/departments" request');
|
||||
return HttpResponse.json({ success: true });
|
||||
}),
|
||||
http.delete("/api/users/:userId/departments", () => {
|
||||
console.log('Captured a "DELETE /api/users/:userId/departments" request');
|
||||
return HttpResponse.json({ success: true });
|
||||
}),
|
||||
http.post("/iam/user", () => {
|
||||
console.log('Captured a "POST /posts" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.delete("/iam/user", ({ params }) => {
|
||||
console.log(`Captured a "DELETE /posts/${params.id}" request`);
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.post("/iam/me", () => {
|
||||
console.log('Captured a "POST /posts" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.post("/iam/role/bind", () => {
|
||||
console.log('Captured a "POST /posts" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.post("/iam/role/unbind", () => {
|
||||
console.log('Captured a "POST /posts" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.get("/iam/me", () => {
|
||||
const generatePermission = () => ({
|
||||
id: faker.number.int({ min: 1, max: 1000 }),
|
||||
code: `perm_${faker.lorem.word()}`,
|
||||
name: faker.lorem.words({ min: 1, max: 3 }),
|
||||
});
|
||||
|
||||
const generateRole = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
code: [ROLE.ADMIN, "editor", "viewer", "manager"],
|
||||
name: faker.person.jobTitle(),
|
||||
permissions: faker.helpers.multiple(generatePermission, {
|
||||
count: { min: 1, max: 5 },
|
||||
}),
|
||||
});
|
||||
|
||||
const generateDepartment = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
code: `dept_${faker.lorem.word()}`,
|
||||
name: faker.company.name(),
|
||||
parentId: faker.number.int({ min: 1, max: 30 }),
|
||||
enable: faker.datatype.boolean(),
|
||||
});
|
||||
|
||||
const generateUser = () => ({
|
||||
id: faker.number.int({ min: 1, max: 100 }),
|
||||
username: faker.internet.email(),
|
||||
password: faker.internet.password(),
|
||||
enable: faker.datatype.boolean(),
|
||||
roles: faker.helpers.multiple(generateRole, {
|
||||
count: { min: 1, max: 3 },
|
||||
}),
|
||||
createTime: faker.date.recent({ days: 30 }).toISOString(),
|
||||
permissions: faker.helpers.multiple(generatePermission, {
|
||||
count: { min: 1, max: 5 },
|
||||
}),
|
||||
departments: faker.helpers.multiple(generateDepartment, {
|
||||
count: { min: 0, max: 3 },
|
||||
}),
|
||||
});
|
||||
const mockData = generateUser();
|
||||
return HttpResponse.json(mockData);
|
||||
}),
|
||||
http.post("/department/unbind", () => {
|
||||
console.log("Captured a 'POST /department/unbind' request");
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.post("/department/bind", () => {
|
||||
console.log("Captured a 'POST /department/bind' request");
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.post("/iam/position/bind", () => {
|
||||
console.log('Captured a "POST /posts" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
http.post("/iam/position/unbind", () => {
|
||||
console.log('Captured a "POST /posts" request');
|
||||
return HttpResponse.json();
|
||||
}),
|
||||
];
|
||||
1651
frontend/src/api/schema/openapi.json
Normal file
1651
frontend/src/api/schema/openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
1512
frontend/src/api/types/schema.d.ts
vendored
Normal file
1512
frontend/src/api/types/schema.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user