This commit is contained in:
Chuck1sn
2025-05-14 10:16:48 +08:00
commit 3cd59337e7
220 changed files with 23768 additions and 0 deletions

View 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;

View 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;
}),
];

View 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();
}),
];

View 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();
}),
];

View 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();
}),
];

View 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();
}),
];

View 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();
}),
];

View 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,
);

View 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();
}),
];

File diff suppressed because it is too large Load Diff

1512
frontend/src/api/types/schema.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff