mirror of
https://github.com/cool-team-official/cool-admin-vue.git
synced 2025-12-11 21:12:50 +00:00
解决页面刷新及代码保存未触发 eps 刷新问题
This commit is contained in:
parent
55ad9b30a6
commit
a4990fc6be
55
build/cool/base.ts
Normal file
55
build/cool/base.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { Plugin } from "vite";
|
||||
import { createSvg } from "./svg";
|
||||
import { createTag } from "./tag";
|
||||
import { createEps } from "./eps";
|
||||
import { createMenu } from "./menu";
|
||||
import { parseJson } from "./utils";
|
||||
|
||||
export function base(): Plugin {
|
||||
return {
|
||||
name: "vite-cool-base",
|
||||
enforce: "pre",
|
||||
configureServer(server) {
|
||||
server.middlewares.use(async (req, res, next) => {
|
||||
function done(data: any) {
|
||||
res.writeHead(200, { "Content-Type": "text/html;charset=UTF-8" });
|
||||
res.end(JSON.stringify(data));
|
||||
}
|
||||
|
||||
if (req.url?.includes("__cool")) {
|
||||
const body = await parseJson(req);
|
||||
|
||||
switch (req.url) {
|
||||
// 快速创建菜单
|
||||
case "/__cool_createMenu":
|
||||
await createMenu(body);
|
||||
break;
|
||||
|
||||
// 创建描述文件
|
||||
case "/__cool_eps":
|
||||
await createEps(body);
|
||||
break;
|
||||
|
||||
default:
|
||||
return done({
|
||||
code: 1001,
|
||||
message: "未知请求"
|
||||
});
|
||||
}
|
||||
|
||||
done({
|
||||
code: 1000
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
},
|
||||
transform(code, id) {
|
||||
return createTag(code, id);
|
||||
},
|
||||
transformIndexHtml(html) {
|
||||
return createSvg(html);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -6,51 +6,22 @@ import { isArray, isEmpty, last, merge } from "lodash";
|
||||
import { createWriteStream } from "fs";
|
||||
import prettier from "prettier";
|
||||
import { proxy } from "../../../src/config/proxy";
|
||||
|
||||
// 实体类型
|
||||
type Entity = {
|
||||
api: {
|
||||
dts: {
|
||||
parameters?: {
|
||||
description: string;
|
||||
name: string;
|
||||
required: boolean;
|
||||
schema: {
|
||||
type: string;
|
||||
};
|
||||
}[];
|
||||
};
|
||||
name: string;
|
||||
method: string;
|
||||
path: string;
|
||||
prefix: string;
|
||||
summary: string;
|
||||
tag: string;
|
||||
}[];
|
||||
columns: {
|
||||
comment: string;
|
||||
length: string;
|
||||
nullable: boolean;
|
||||
propertyName: string;
|
||||
type: string;
|
||||
}[];
|
||||
module: string;
|
||||
name: string;
|
||||
prefix: string;
|
||||
};
|
||||
import type { Eps } from "../types";
|
||||
|
||||
// 获取方法名
|
||||
function getNames(v: any) {
|
||||
return Object.keys(v).filter((e) => !["namespace", "permission"].includes(e));
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
async function getData(temps: any[]) {
|
||||
let list: Entity[] = [];
|
||||
// 数据
|
||||
let service = {};
|
||||
let list: Eps.Entity[] = [];
|
||||
|
||||
// 获取数据
|
||||
async function getData(temps?: Eps.Entity[]) {
|
||||
// 本地文件
|
||||
try {
|
||||
list = JSON.parse(readFile(join(DistPath, "eps.json")));
|
||||
list = JSON.parse(readFile(join(DistPath, "eps.json")) || "[]");
|
||||
} catch (err) {
|
||||
error(`[eps] ${join(DistPath, "eps.json")} 文件异常, ${err.message}`);
|
||||
}
|
||||
@ -68,18 +39,17 @@ async function getData(temps: any[]) {
|
||||
|
||||
if (code === 1000) {
|
||||
if (!isEmpty(data) && data) {
|
||||
// @ts-ignore
|
||||
list = Object.values(data).flat();
|
||||
list = Object.values(data).flat() as Eps.Entity[];
|
||||
}
|
||||
} else {
|
||||
error(`[eps] ${message}`);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
error(`[eps] 获取失败, ${url} 无法访问,请启动服务!`);
|
||||
error(`[eps] ${url} 服务未启动!!!`);
|
||||
});
|
||||
|
||||
// 判断是否重复项
|
||||
// 合并本地 service 数据
|
||||
if (isArray(temps)) {
|
||||
temps.forEach((e) => {
|
||||
const d = list.find((a) => e.prefix === a.prefix);
|
||||
@ -91,35 +61,31 @@ async function getData(temps: any[]) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
// 创建数据文件
|
||||
function createJson(eps: Entity[]) {
|
||||
createWriteStream(join(DistPath, "eps.json"), {
|
||||
flags: "w"
|
||||
}).write(
|
||||
JSON.stringify(
|
||||
eps.map((e) => {
|
||||
// 创建 json 文件
|
||||
function createJson() {
|
||||
const d = list.map((e) => {
|
||||
return {
|
||||
prefix: e.prefix,
|
||||
name: e.name || "",
|
||||
api: e.api.map((e) => {
|
||||
return {
|
||||
prefix: e.prefix,
|
||||
name: e.name || "",
|
||||
api: e.api.map((e) => {
|
||||
return {
|
||||
name: e.name,
|
||||
method: e.method,
|
||||
path: e.path
|
||||
};
|
||||
})
|
||||
name: e.name,
|
||||
method: e.method,
|
||||
path: e.path
|
||||
};
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
createWriteStream(join(DistPath, "eps.json"), {
|
||||
flags: "w"
|
||||
}).write(JSON.stringify(d));
|
||||
}
|
||||
|
||||
// 创建描述文件
|
||||
async function createDescribe({ list, service }: { list: Entity[]; service: any }) {
|
||||
async function createDescribe({ list, service }: { list: Eps.Entity[]; service: any }) {
|
||||
// 获取类型
|
||||
function getType({ propertyName, type }) {
|
||||
for (const map of Entity.mapping) {
|
||||
@ -355,7 +321,7 @@ async function createDescribe({ list, service }: { list: Entity[]; service: any
|
||||
`;
|
||||
|
||||
// 文本内容
|
||||
const content = await prettier.format(text, {
|
||||
const content = prettier.format(text, {
|
||||
parser: "typescript",
|
||||
useTabs: true,
|
||||
tabWidth: 4,
|
||||
@ -372,93 +338,82 @@ async function createDescribe({ list, service }: { list: Entity[]; service: any
|
||||
}).write(content);
|
||||
}
|
||||
|
||||
// 创建服务
|
||||
function createService(data: Entity[]) {
|
||||
const list: Entity[] = [];
|
||||
const service = {};
|
||||
const d = { data };
|
||||
// 创建 service
|
||||
function createService() {
|
||||
list.forEach((e) => {
|
||||
// 分隔路径
|
||||
const arr = e.prefix
|
||||
.replace(/\//, "")
|
||||
.replace("admin", "")
|
||||
.split("/")
|
||||
.filter(Boolean)
|
||||
.map(toCamel);
|
||||
|
||||
for (const i in d) {
|
||||
if (isArray(d[i])) {
|
||||
d[i].forEach((e: Entity) => {
|
||||
// 分隔路径
|
||||
const arr = e.prefix
|
||||
.replace(/\//, "")
|
||||
.replace("admin", "")
|
||||
.split("/")
|
||||
.filter(Boolean)
|
||||
.map(toCamel);
|
||||
// 遍历
|
||||
function deep(d: any, i: number) {
|
||||
const k = arr[i];
|
||||
|
||||
// 遍历
|
||||
function deep(d: any, i: number) {
|
||||
const k = arr[i];
|
||||
|
||||
if (k) {
|
||||
// 是否最后一个
|
||||
if (arr[i + 1]) {
|
||||
if (!d[k]) {
|
||||
d[k] = {};
|
||||
}
|
||||
|
||||
deep(d[k], i + 1);
|
||||
} else {
|
||||
// 本地不存在则创建实例
|
||||
if (!d[k]) {
|
||||
d[k] = {
|
||||
namespace: e.prefix.substring(1, e.prefix.length),
|
||||
permission: {}
|
||||
};
|
||||
}
|
||||
|
||||
// 创建方法
|
||||
e.api.forEach((a) => {
|
||||
// 方法名
|
||||
const n = a.path.replace("/", "");
|
||||
|
||||
if (n && !/[-:]/g.test(n)) {
|
||||
d[k][n] = a;
|
||||
}
|
||||
});
|
||||
|
||||
// 创建权限
|
||||
getNames(d[k]).forEach((e) => {
|
||||
d[k].permission[e] = `${d[k].namespace.replace(
|
||||
"admin/",
|
||||
""
|
||||
)}/${e}`.replace(/\//g, ":");
|
||||
});
|
||||
|
||||
list.push(e);
|
||||
}
|
||||
if (k) {
|
||||
// 是否最后一个
|
||||
if (arr[i + 1]) {
|
||||
if (!d[k]) {
|
||||
d[k] = {};
|
||||
}
|
||||
|
||||
deep(d[k], i + 1);
|
||||
} else {
|
||||
// 不存在则创建
|
||||
if (!d[k]) {
|
||||
d[k] = {
|
||||
namespace: e.prefix.substring(1, e.prefix.length),
|
||||
permission: {}
|
||||
};
|
||||
}
|
||||
|
||||
// 创建方法
|
||||
e.api.forEach((a) => {
|
||||
// 方法名
|
||||
const n = a.path.replace("/", "");
|
||||
|
||||
if (n && !/[-:]/g.test(n)) {
|
||||
d[k][n] = a;
|
||||
}
|
||||
});
|
||||
|
||||
// 创建权限
|
||||
getNames(d[k]).forEach((e) => {
|
||||
d[k].permission[e] = `${d[k].namespace.replace("admin/", "")}/${e}`.replace(
|
||||
/\//g,
|
||||
":"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
deep(service, 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { service, list };
|
||||
deep(service, 0);
|
||||
});
|
||||
}
|
||||
|
||||
// 创建 eps
|
||||
export async function createEps(query?: { list: any[] }) {
|
||||
// 获取数据
|
||||
const data = await getData(query?.list || []);
|
||||
await getData(query?.list || []);
|
||||
|
||||
// 生成数据
|
||||
const { service, list } = createService(data);
|
||||
// 创建 service
|
||||
createService();
|
||||
|
||||
// 创建临时目录
|
||||
createDir(DistPath);
|
||||
|
||||
// 创建数据文件
|
||||
createJson(data);
|
||||
// 创建 json 文件
|
||||
createJson();
|
||||
|
||||
// 创建描述文件
|
||||
createDescribe({ service, list });
|
||||
|
||||
return `
|
||||
export const eps = ${JSON.stringify({ service, list })}
|
||||
`;
|
||||
return {
|
||||
service,
|
||||
list
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,73 +1,6 @@
|
||||
import { Plugin } from "vite";
|
||||
import { createSvg } from "./svg";
|
||||
import { createTag } from "./tag";
|
||||
import { createEps } from "./eps";
|
||||
import { createModule } from "./module";
|
||||
import { createMenu } from "./menu";
|
||||
import { parseJson } from "./utils";
|
||||
import { base } from "./base";
|
||||
import { virtual } from "./virtual";
|
||||
|
||||
export function cool(): Plugin {
|
||||
// 虚拟模块
|
||||
const virtualModuleIds = ["virtual:eps", "virtual:module"];
|
||||
|
||||
return {
|
||||
name: "vite-cool",
|
||||
enforce: "pre",
|
||||
configureServer(server) {
|
||||
server.middlewares.use(async (req, res, next) => {
|
||||
function done(data: any) {
|
||||
res.writeHead(200, { "Content-Type": "text/html;charset=UTF-8" });
|
||||
res.end(JSON.stringify(data));
|
||||
}
|
||||
|
||||
if (req.url?.includes("__cool")) {
|
||||
const body = await parseJson(req);
|
||||
|
||||
switch (req.url) {
|
||||
// 快速创建菜单
|
||||
case "/__cool_createMenu":
|
||||
await createMenu(body);
|
||||
break;
|
||||
|
||||
// 创建描述文件
|
||||
case "/__cool_eps":
|
||||
await createEps(body);
|
||||
break;
|
||||
|
||||
default:
|
||||
return done({
|
||||
code: 1001,
|
||||
message: "未知请求"
|
||||
});
|
||||
}
|
||||
|
||||
done({
|
||||
code: 1000
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
},
|
||||
transform(code, id) {
|
||||
return createTag(code, id);
|
||||
},
|
||||
transformIndexHtml(html) {
|
||||
return createSvg(html);
|
||||
},
|
||||
resolveId(id) {
|
||||
if (virtualModuleIds.includes(id)) {
|
||||
return "\0" + id;
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id === "\0virtual:eps") {
|
||||
return createEps();
|
||||
}
|
||||
|
||||
if (id === "\0virtual:module") {
|
||||
return createModule();
|
||||
}
|
||||
}
|
||||
};
|
||||
export function cool() {
|
||||
return [base(), virtual()];
|
||||
}
|
||||
|
||||
@ -8,7 +8,5 @@ export function createModule() {
|
||||
dirs = dirs.filter((e) => !e.includes("."));
|
||||
} catch (err) {}
|
||||
|
||||
return `
|
||||
export const dirs = ${JSON.stringify(dirs)}
|
||||
`;
|
||||
return { dirs };
|
||||
}
|
||||
|
||||
32
build/cool/types/index.d.ts
vendored
Normal file
32
build/cool/types/index.d.ts
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
export namespace Eps {
|
||||
interface Entity {
|
||||
api: {
|
||||
dts: {
|
||||
parameters?: {
|
||||
description: string;
|
||||
name: string;
|
||||
required: boolean;
|
||||
schema: {
|
||||
type: string;
|
||||
};
|
||||
}[];
|
||||
};
|
||||
name: string;
|
||||
method: string;
|
||||
path: string;
|
||||
prefix: string;
|
||||
summary: string;
|
||||
tag: string;
|
||||
}[];
|
||||
columns: {
|
||||
comment: string;
|
||||
length: string;
|
||||
nullable: boolean;
|
||||
propertyName: string;
|
||||
type: string;
|
||||
}[];
|
||||
module: string;
|
||||
name: string;
|
||||
prefix: string;
|
||||
}
|
||||
}
|
||||
61
build/cool/virtual.ts
Normal file
61
build/cool/virtual.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import type { Plugin, ViteDevServer } from "vite";
|
||||
import { createEps } from "./eps";
|
||||
import { createModule } from "./module";
|
||||
|
||||
export function virtual(): Plugin {
|
||||
const virtualModuleIds = ["virtual:eps", "virtual:module"];
|
||||
|
||||
// 使虚拟模块失效,重新加载
|
||||
function buildEps(server: ViteDevServer) {
|
||||
virtualModuleIds.forEach((vm) => {
|
||||
const mod = server.moduleGraph.getModuleById(`\0${vm}`);
|
||||
|
||||
if (mod) {
|
||||
server.moduleGraph.invalidateModule(mod);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
name: "vite-cool-virtual",
|
||||
enforce: "pre",
|
||||
configureServer(server) {
|
||||
server.middlewares.use(async (req, res, next) => {
|
||||
// 页面刷新时触发 eps 刷新
|
||||
if (req.url == "/@vite/client") {
|
||||
buildEps(server);
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
},
|
||||
handleHotUpdate({ file, server }) {
|
||||
// 代码保存时触发 eps 刷新
|
||||
if (!file.includes("build/cool/dist")) {
|
||||
buildEps(server);
|
||||
}
|
||||
},
|
||||
resolveId(id) {
|
||||
if (virtualModuleIds.includes(id)) {
|
||||
return "\0" + id;
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id === "\0virtual:eps") {
|
||||
const { service, list } = await createEps();
|
||||
|
||||
return `
|
||||
export const eps = ${JSON.stringify({ service, list })}
|
||||
`;
|
||||
}
|
||||
|
||||
if (id === "\0virtual:module") {
|
||||
const { dirs } = createModule();
|
||||
|
||||
return `
|
||||
export const dirs = ${JSON.stringify(dirs)}
|
||||
`;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user