From 7bd866831780abcf5a59c4cbb7d1be456eea7c99 Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期五, 14 八月 2026 10:13:57 +0800
Subject: [PATCH] add shop module
---
packages/vite-plugin/src/eps/index.ts | 597 +++++++++++++++++------------------------------------------
1 files changed, 172 insertions(+), 425 deletions(-)
diff --git a/packages/vite-plugin/src/eps/index.ts b/packages/vite-plugin/src/eps/index.ts
index 1ad2393..99e13e3 100644
--- a/packages/vite-plugin/src/eps/index.ts
+++ b/packages/vite-plugin/src/eps/index.ts
@@ -1,24 +1,17 @@
import { createDir, error, firstUpperCase, readFile, rootDir, toCamel } from "../utils";
import { join } from "path";
import axios from "axios";
-import { compact, isEmpty, last, uniqBy, values } from "lodash";
+import { isEmpty, last, values } from "lodash";
import { createWriteStream } from "fs";
import prettier from "prettier";
import { config } from "../config";
import type { Eps } from "../../types";
-import { flatten } from "../uniapp-x/flatten";
-import { interfaceToType } from "../uniapp-x/utils";
-// 鍏ㄥ眬 service 瀵硅薄锛岀敤浜庡瓨鍌ㄦ湇鍔$粨鏋�
const service = {};
-// eps 瀹炰綋鍒楄〃
let list: Eps.Entity[] = [];
-/**
- * 鑾峰彇 eps 璇锋眰鍦板潃
- * @returns {string} eps url
- */
-function getEpsUrl(): string {
+// 鑾峰彇璇锋眰鍦板潃
+function getEpsUrl() {
let url = config.eps.api;
if (!url) {
@@ -27,9 +20,9 @@
switch (url) {
case "app":
- case "uniapp-x":
url = "/app/base/comm/eps";
break;
+
case "admin":
url = "/admin/base/open/eps";
break;
@@ -38,122 +31,57 @@
return url;
}
-/**
- * 鑾峰彇 eps 璺緞
- * @param filename 鏂囦欢鍚�
- * @returns {string} 瀹屾暣璺緞
- */
-function getEpsPath(filename?: string): string {
+// 鑾峰彇璺緞
+function getEpsPath(filename?: string) {
return join(
config.type == "admin" ? config.eps.dist : rootDir(config.eps.dist),
filename || "",
);
}
-/**
- * 鑾峰彇瀵硅薄鏂规硶鍚嶏紙鎺掗櫎 namespace銆乸ermission 瀛楁锛�
- * @param v 瀵硅薄
- * @returns {string[]} 鏂规硶鍚嶆暟缁�
- */
-function getNames(v: any): string[] {
+// 鑾峰彇鏂规硶鍚�
+function getNames(v: any) {
return Object.keys(v).filter((e) => !["namespace", "permission"].includes(e));
}
-/**
- * 鑾峰彇瀛楁绫诲瀷
- */
-function getType({ propertyName, type }: any) {
- for (const map of config.eps.mapping) {
- if (map.custom) {
- const resType = map.custom({ propertyName, type });
- if (resType) return resType;
- }
- if (map.test) {
- if (map.test.includes(type)) return map.type;
- }
- }
- return type;
-}
-
-/**
- * 鏍煎紡鍖栨柟娉曞悕锛屽幓闄ょ壒娈婂瓧绗�
- */
-function formatName(name: string) {
- return (name || "").replace(/[:,\s,\/,-]/g, "");
-}
-
-/**
- * 妫�鏌ユ柟娉曞悕鏄惁鍚堟硶锛堜笉鍖呭惈鐗规畩瀛楃锛�
- */
-function checkName(name: string) {
- return name && !["{", "}", ":"].some((e) => name.includes(e));
-}
-
-/**
- * 涓嶆敮鎸� uniapp-x 骞冲彴鏄剧ず
- */
-function noUniappX(text: string, defaultText: string = "") {
- if (config.type == "uniapp-x") {
- return defaultText;
- } else {
- return text;
- }
-}
-
-/**
- * 鏌ユ壘瀛楁
- * @param sources 瀛楁 source 鏁扮粍
- * @param item eps 瀹炰綋
- * @returns {Eps.Column[]} 瀛楁鏁扮粍
- */
-function findColumns(sources: string[], item: Eps.Entity): Eps.Column[] {
+// 鎵惧瓧娈�
+function findColumns(sources: string[], item: Eps.Entity) {
const columns = [item.columns, item.pageColumns].flat().filter(Boolean);
return (sources || [])
.map((e) => columns.find((c) => c.source == e))
.filter(Boolean) as Eps.Column[];
}
-/**
- * 浣跨敤 prettier 鏍煎紡鍖� TypeScript 浠g爜
- * @param text 浠g爜鏂囨湰
- * @returns {Promise<string|null>} 鏍煎紡鍖栧悗鐨勪唬鐮�
- */
-async function formatCode(text: string): Promise<string | null> {
- return prettier
- .format(text, {
- parser: "typescript",
- useTabs: true,
- tabWidth: 4,
- endOfLine: "lf",
- semi: true,
- singleQuote: false,
- printWidth: 100,
- trailingComma: "none",
- })
- .catch((err) => {
- console.log(err);
- error(`[cool-eps] File format error, please try again`);
- return null;
- });
+// 鏍煎紡鍖栦唬鐮�
+async function formatCode(text: string) {
+ return prettier.format(text, {
+ parser: "typescript",
+ useTabs: true,
+ tabWidth: 4,
+ endOfLine: "lf",
+ semi: true,
+ singleQuote: false,
+ printWidth: 100,
+ trailingComma: "none",
+ });
}
-/**
- * 鑾峰彇 eps 鏁版嵁锛堟湰鍦颁紭鍏堬紝杩滅▼鍏滃簳锛�
- */
+// 鑾峰彇鏁版嵁
async function getData() {
- // 璇诲彇鏈湴 eps.json
+ // 璇诲彇鏈湴鏁版嵁
list = readFile(getEpsPath("eps.json"), true) || [];
- // 鎷兼帴璇锋眰鍦板潃
+ // 璇锋眰鍦板潃
const url = config.reqUrl + getEpsUrl();
- // 璇锋眰杩滅▼ eps 鏁版嵁
+ // 璇锋眰鏁版嵁
await axios
.get(url, {
timeout: 5000,
})
.then((res) => {
const { code, data, message } = res.data;
+
if (code === 1000) {
if (!isEmpty(data) && data) {
list = values(data).flat();
@@ -166,11 +94,18 @@
error(`[cool-eps] API service is not running 鈫� ${url}`);
});
- // 鍒濆鍖栧鐞嗭紝琛ュ叏缂虹渷瀛楁
+ // 鍒濆鍖栧鐞�
list.forEach((e) => {
- if (!e.namespace) e.namespace = "";
- if (!e.api) e.api = [];
- if (!e.columns) e.columns = [];
+ if (!e.namespace) {
+ e.namespace = "";
+ }
+ if (!e.api) {
+ e.api = [];
+ }
+ if (!e.columns) {
+ e.columns = [];
+ }
+
if (!e.search) {
e.search = {
fieldEq: findColumns(e.pageQueryOp?.fieldEq, e),
@@ -179,40 +114,29 @@
};
}
});
-
- if (config.type == "uniapp-x" || config.type == "app") {
- list = list.filter((e) => e.prefix.startsWith("/app") || e.prefix.startsWith("/admin"));
- }
}
-/**
- * 鍒涘缓 eps.json 鏂囦欢
- * @returns {boolean} 鏄惁鏈夋洿鏂�
- */
-function createJson(): boolean {
- let data: any[] = [];
+// 鍒涘缓 json 鏂囦欢
+function createJson() {
+ const arr = list.map((e) => {
+ return {
+ prefix: e.prefix,
+ name: e.name || "",
+ api: e.api.map((e) => {
+ return {
+ name: e.name,
+ method: e.method,
+ path: e.path,
+ };
+ }),
+ search: e.search,
+ };
+ });
- if (config.type != "uniapp-x") {
- data = list.map((e) => {
- return {
- prefix: e.prefix,
- name: e.name || "",
- api: e.api.map((apiItem) => ({
- name: apiItem.name,
- method: apiItem.method,
- path: apiItem.path,
- })),
- search: e.search,
- };
- });
- } else {
- data = list;
- }
-
- const content = JSON.stringify(data);
+ const content = JSON.stringify(arr);
const local_content = readFile(getEpsPath("eps.json"));
- // 鍒ゆ柇鏄惁闇�瑕佹洿鏂�
+ // 鏄惁闇�瑕佹洿鏂�
const isUpdate = content != local_content;
if (isUpdate) {
@@ -224,32 +148,51 @@
return isUpdate;
}
-/**
- * 鍒涘缓 eps 绫诲瀷鎻忚堪鏂囦欢锛坉.ts/ts锛�
- * @param param0 list: eps瀹炰綋鍒楄〃, service: service瀵硅薄
- */
+// 鍒涘缓鎻忚堪鏂囦欢
async function createDescribe({ list, service }: { list: Eps.Entity[]; service: any }) {
- /**
- * 鍒涘缓 Entity 鎺ュ彛瀹氫箟
- */
+ // 鑾峰彇绫诲瀷
+ function getType({ propertyName, type }: any) {
+ for (const map of config.eps.mapping) {
+ if (map.custom) {
+ const resType = map.custom({ propertyName, type });
+ if (resType) return resType;
+ }
+ if (map.test) {
+ if (map.test.includes(type)) return map.type;
+ }
+ }
+ return type;
+ }
+
+ // 鏍煎紡鍖栨柟娉曞悕
+ function formatName(name: string) {
+ return (name || "").replace(/[:,\s,\/,-]/g, "");
+ }
+
+ // 鍒涘缓 Entity
function createEntity() {
const ignore: string[] = [];
+
let t0 = "";
for (const item of list) {
- if (!checkName(item.name)) continue;
-
- if (formatName(item.name) == "BusinessInterface") {
- console.log(111);
- }
+ if (!item.name) continue;
let t = `interface ${formatName(item.name)} {`;
- // 鍚堝苟 columns 鍜� pageColumns锛屽幓閲�
- const columns: Eps.Column[] = uniqBy(
- compact([...(item.columns || []), ...(item.pageColumns || [])]),
- "source",
- );
+ // 鍚堝苟澶氫釜鍒�
+ const columns: Eps.Column[] = [];
+
+ [item.columns, item.pageColumns]
+ .flat()
+ .filter(Boolean)
+ .forEach((e) => {
+ const d = columns.find((c) => c.source == e.source);
+
+ if (!d) {
+ columns.push(e);
+ }
+ });
for (const col of columns || []) {
t += `
@@ -259,7 +202,7 @@
${col.propertyName}?: ${getType({
propertyName: col.propertyName,
type: col.type,
- })};
+ })}
`;
}
@@ -280,34 +223,23 @@
return t0;
}
- /**
- * 鍒涘缓 Controller 鎺ュ彛瀹氫箟
- */
- async function createController() {
+ // 鍒涘缓 Service
+ async function createDts() {
let controller = "";
let chain = "";
- let pageResponse = "";
- /**
- * 閫掑綊澶勭悊 service 鏍戯紝鐢熸垚鎺ュ彛瀹氫箟
- * @param d 褰撳墠鑺傜偣
- * @param k 鍓嶇紑
- */
+ // 澶勭悊鏁版嵁
function deep(d: any, k?: string) {
if (!k) k = "";
for (const i in d) {
const name = k + toCamel(firstUpperCase(formatName(i)));
- // 妫�鏌ユ柟娉曞悕
- if (!checkName(name)) continue;
-
if (d[i].namespace) {
// 鏌ユ壘閰嶇疆
const item = list.find((e) => (e.prefix || "") === `/${d[i].namespace}`);
if (item) {
- //
let t = `interface ${name} {`;
// 鎻掑叆鏂规硶
@@ -317,10 +249,9 @@
item.api.forEach((a) => {
// 鏂规硶鍚�
- const n = toCamel(formatName(a.name || last(a.path.split("/"))!));
-
- // 妫�鏌ユ柟娉曞悕
- if (!checkName(n)) return;
+ const n = toCamel(
+ formatName(a.name || last(a.path.split("/")) || ""),
+ );
if (n) {
// 鍙傛暟绫诲瀷
@@ -334,15 +265,14 @@
q.push(`\n/** ${p.description} */\n`);
}
- // 妫�鏌ュ弬鏁板悕
- if (!checkName(p.name)) {
+ if (p.name.includes(":")) {
return false;
}
const a = `${p.name}${p.required ? "" : "?"}`;
const b = `${p.schema.type || "string"}`;
- q.push(`${a}: ${b};`);
+ q.push(`${a}: ${b},`);
});
if (isEmpty(q)) {
@@ -360,43 +290,35 @@
switch (a.path) {
case "/page":
- res = `${name}PageResponse`;
-
- pageResponse += `
- interface ${name}PageResponse {
- pagination: PagePagination;
- list: ${en}[];
- }
- `;
-
+ res = `
+ {
+ pagination: { size: number; page: number; total: number; [key: string]: any };
+ list: ${en} [];
+ [key: string]: any;
+ }
+ `;
break;
+
case "/list":
res = `${en} []`;
break;
+
case "/info":
res = en;
break;
+
default:
res = "any";
break;
}
- // 鏂规硶鎻忚堪
- if (config.type == "uniapp-x") {
- t += `
- /**
- * ${a.summary || n}
- */
- ${n}(data${q.length == 1 ? "?" : ""}: ${q.join("")}): Promise<any>;
- `;
- } else {
- t += `
- /**
- * ${a.summary || n}
- */
- ${n}(data${q.length == 1 ? "?" : ""}: ${q.join("")}): Promise<${res}>;
- `;
- }
+ // 鎻忚堪
+ t += `
+ /**
+ * ${a.summary || n}
+ */
+ ${n}(data${q.length == 1 ? "?" : ""}: ${q.join("")}): Promise<${res}>;
+ `;
if (!permission.includes(n)) {
permission.push(n);
@@ -405,25 +327,24 @@
});
// 鏉冮檺鏍囪瘑
- t += noUniappX(`
+ t += `
/**
* 鏉冮檺鏍囪瘑
*/
permission: { ${permission.map((e) => `${e}: string;`).join("\n")} };
- `);
+ `;
// 鏉冮檺鐘舵��
- t += noUniappX(`
+ t += `
/**
* 鏉冮檺鐘舵��
*/
_permission: { ${permission.map((e) => `${e}: boolean;`).join("\n")} };
- `);
+ `;
- // 璇锋眰
- t += noUniappX(`
- request: Request;
- `);
+ t += `
+ request: Service['request']
+ `;
}
t += "}\n\n";
@@ -434,99 +355,67 @@
} else {
chain += `${formatName(i)}: {`;
deep(d[i], name);
- chain += "};";
+ chain += "},";
}
}
}
- // 閬嶅巻 service 鏍�
+ // 閬嶅巻
deep(service);
return `
type json = any;
- ${await createDict()}
-
- interface PagePagination {
- size: number;
- page: number;
- total: number;
- [key: string]: any;
- };
-
- interface PageResponse<T> {
- pagination: PagePagination;
- list: T[];
- [key: string]: any;
- };
-
- ${pageResponse}
-
${controller}
- ${noUniappX(`interface RequestOptions {
- url: string;
- method?: 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT';
- data?: any;
- params?: any;
- headers?: any;
- timeout?: number;
- [key: string]: any;
- }`)}
-
- ${noUniappX("type Request = (options: RequestOptions) => Promise<any>;")}
-
type Service = {
- ${noUniappX("request: Request;")}
+ /**
+ * 鍩虹璇锋眰
+ */
+ request(options?: {
+ url: string;
+ method?: "POST" | "GET" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS";
+ data?: any;
+ params?: any;
+ headers?: {
+ authorization?: string;
+ [key: string]: any;
+ },
+ timeout?: number;
+ proxy?: boolean;
+ [key: string]: any;
+ }): Promise<any>;
${chain}
}
+
+ ${await createDict()}
`;
}
- // 缁勮鏂囦欢鍐呭
- let text = `
- ${createEntity()}
- ${await createController()}
+ // 鏂囦欢鍐呭
+ const text = `
+ declare namespace Eps {
+ ${createEntity()}
+ ${await createDts()}
+ }
`;
- // 鏂囦欢鍚�
- let name = "eps.d.ts";
-
- if (config.type == "uniapp-x") {
- name = "eps.ts";
- text = text
- .replaceAll("interface ", "export interface ")
- .replaceAll("type ", "export type ")
- .replaceAll("[key: string]: any;", "");
-
- text = flatten(text);
- text = interfaceToType(text);
- } else {
- text = `
- declare namespace Eps {
- ${text}
- }
- `;
- }
-
- // 鏍煎紡鍖栨枃鏈唴瀹�
+ // 鏂囨湰鍐呭
const content = await formatCode(text);
- const local_content = readFile(getEpsPath(name));
+ const local_content = readFile(getEpsPath("eps.d.ts"));
// 鏄惁闇�瑕佹洿鏂�
- if (content && content != local_content && list.length > 0) {
+ if (content != local_content) {
// 鍒涘缓 eps 鎻忚堪鏂囦欢
- createWriteStream(getEpsPath(name), {
+ createWriteStream(getEpsPath("eps.d.ts"), {
flags: "w",
}).write(content);
}
}
-/**
- * 鏋勫缓 service 瀵硅薄鏍�
- */
+// 鍒涘缓 service
function createService() {
// 璺緞绗竴灞備綔涓� id 鏍囪瘑
const id = getEpsUrl().split("/")[1];
@@ -535,14 +424,10 @@
// 璇锋眰鍦板潃
const path = e.prefix[0] == "/" ? e.prefix.substring(1, e.prefix.length) : e.prefix;
- // 鍒嗛殧璺緞锛屽幓闄� id锛岃浆椹煎嘲
+ // 鍒嗛殧璺緞
const arr = path.replace(id, "").split("/").filter(Boolean).map(toCamel);
- /**
- * 閫掑綊鏋勫缓 service 鏍�
- * @param d 褰撳墠鑺傜偣
- * @param i 褰撳墠绱㈠紩
- */
+ // 閬嶅巻
function deep(d: any, i: number) {
const k = arr[i];
@@ -552,6 +437,7 @@
if (!d[k]) {
d[k] = {};
}
+
deep(d[k], i + 1);
} else {
// 涓嶅瓨鍦ㄥ垯鍒涘缓
@@ -580,6 +466,7 @@
e.api.forEach((a) => {
// 鏂规硶鍚�
const n = a.path.replace("/", "");
+
if (n && !/[-:]/g.test(n)) {
d[k][n] = a;
}
@@ -592,190 +479,50 @@
});
}
-/**
- * 鍒涘缓 service 浠g爜
- * @returns {string} service 浠g爜
- */
-function createServiceCode(): { content: string; types: string[] } {
- const types: string[] = [];
+// 鍒涘缓 dict
+async function createDict() {
+ const url = config.reqUrl + "/" + config.type + "/dict/info/types";
- let chain = "";
-
- /**
- * 閫掑綊澶勭悊 service 鏍戯紝鐢熸垚鎺ュ彛浠g爜
- * @param d 褰撳墠鑺傜偣
- * @param k 鍓嶇紑
- */
- function deep(d: any, k?: string) {
- if (!k) k = "";
-
- for (const i in d) {
- if (["swagger"].includes(i)) {
- continue;
- }
-
- const name = k + toCamel(firstUpperCase(formatName(i)));
-
- // 妫�鏌ユ柟娉曞悕
- if (!checkName(name)) continue;
-
- if (d[i].namespace) {
- // 鏌ユ壘閰嶇疆
- const item = list.find((e) => (e.prefix || "") === `/${d[i].namespace}`);
-
- if (item) {
- //
- let t = `{`;
-
- // 鎻掑叆鏂规硶
- if (item.api) {
- item.api.forEach((a) => {
- // 鏂规硶鍚�
- const n = toCamel(formatName(a.name || last(a.path.split("/"))!));
-
- // 妫�鏌ユ柟娉曞悕
- if (!checkName(n)) return;
-
- if (n) {
- // 鍙傛暟绫诲瀷
- let q: string[] = [];
-
- // 鍙傛暟鍒楄〃
- const { parameters = [] } = a.dts || {};
-
- parameters.forEach((p) => {
- if (p.description) {
- q.push(`\n/** ${p.description} */\n`);
- }
-
- // 妫�鏌ュ弬鏁板悕
- if (!checkName(p.name)) {
- return false;
- }
-
- const a = `${p.name}${p.required ? "" : "?"}`;
- const b = `${p.schema.type || "string"}`;
-
- q.push(`${a}: ${b}, `);
- });
-
- if (isEmpty(q)) {
- q = ["any"];
- } else {
- q.unshift("{");
- q.push("}");
- }
-
- if (item.name) {
- types.push(item.name);
- }
-
- // 鏂规硶鎻忚堪
- t += `
- /**
- * ${a.summary || n}
- */
- ${n}(data?: any): Promise<any> {
- return request({
- url: "/${d[i].namespace}${a.path}",
- method: "${(a.method || "get").toLocaleUpperCase()}",
- data,
- });
- },
- `;
- }
- });
- }
-
- t += `} as ${name}\n`;
-
- types.push(name);
-
- chain += `${formatName(i)}: ${t},\n`;
- }
- } else {
- chain += `${formatName(i)}: {`;
- deep(d[i], name);
- chain += `} as ${firstUpperCase(i)}Interface,`;
-
- types.push(`${firstUpperCase(i)}Interface`);
- }
- }
- }
-
- // 閬嶅巻 service 鏍�
- deep(service);
-
- return {
- content: `{ ${chain} }`,
- types,
- };
-}
-
-/**
- * 鑾峰彇瀛楀吀绫诲瀷瀹氫箟
- * @returns {Promise<string>} 瀛楀吀绫诲瀷 type 瀹氫箟
- */
-async function createDict(): Promise<string> {
- let p = "";
-
- switch (config.type) {
- case "app":
- case "uniapp-x":
- p = "/app";
- break;
- case "admin":
- p = "/admin";
- break;
- }
-
- const url = config.reqUrl + p + "/dict/info/types";
-
- const text = await axios
+ return axios
.get(url)
.then((res) => {
const { code, data } = res.data as { code: number; data: any[] };
if (code === 1000) {
let v = "string";
+
if (!isEmpty(data)) {
v = data.map((e) => `"${e.key}"`).join(" | ");
}
+
return `type DictKey = ${v}`;
}
})
.catch(() => {
error(`[cool-eps] Error锛�${url}`);
});
-
- return text || "";
}
-/**
- * 涓诲叆鍙o細鍒涘缓 eps 鐩稿叧鏂囦欢鍜� service
- */
+// 鍒涘缓 eps
export async function createEps() {
if (config.eps.enable) {
- // 鑾峰彇 eps 鏁版嵁
+ // 鑾峰彇鏁版嵁
await getData();
- // 鏋勫缓 service 瀵硅薄
+ // 鍒涘缓 service
createService();
- const serviceCode = createServiceCode();
-
- // 鍒涘缓 eps 鐩綍
+ // 鍒涘缓鐩綍
createDir(getEpsPath(), true);
- // 鍒涘缓 eps.json 鏂囦欢
+ // 鍒涘缓 json 鏂囦欢
const isUpdate = createJson();
- // 鍒涘缓绫诲瀷鎻忚堪鏂囦欢
+ // 鍒涘缓鎻忚堪鏂囦欢
createDescribe({ service, list });
return {
service,
- serviceCode,
list,
isUpdate,
};
--
Gitblit v1.9.1