mirror of
https://github.com/cool-team-official/cool-admin-vue.git
synced 2025-12-12 21:52:48 +00:00
优化
This commit is contained in:
commit
c1b837a0bb
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,4 +3,4 @@ node_modules
|
|||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
55
build/cool/base.ts
Normal file
55
build/cool/base.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import type { 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -2,56 +2,27 @@ import { createDir, error, firstUpperCase, readFile, toCamel } from "../utils";
|
|||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { Entity, DistPath } from "./config";
|
import { Entity, DistPath } from "./config";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { isArray, isEmpty, last } from "lodash";
|
import { isArray, isEmpty, last, merge } from "lodash";
|
||||||
import { createWriteStream } from "fs";
|
import { createWriteStream } from "fs";
|
||||||
import prettier from "prettier";
|
import prettier from "prettier";
|
||||||
import { proxy } from "../../../src/config/proxy";
|
import { proxy } from "../../../src/config/proxy";
|
||||||
|
import type { Eps } from "../types";
|
||||||
// 实体类型
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取方法名
|
// 获取方法名
|
||||||
function getNames(v: any) {
|
function getNames(v: any) {
|
||||||
return Object.keys(v).filter((e) => !["namespace", "permission"].includes(e));
|
return Object.keys(v).filter((e) => !["namespace", "permission"].includes(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取数据
|
// 数据
|
||||||
async function getData(temps: any[]) {
|
let service = {};
|
||||||
let list: Entity[] = [];
|
let list: Eps.Entity[] = [];
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
async function getData(temps?: Eps.Entity[]) {
|
||||||
// 本地文件
|
// 本地文件
|
||||||
try {
|
try {
|
||||||
list = JSON.parse(readFile(join(DistPath, "eps.json")) || "[]");
|
list = JSON.parse(readFile(join(DistPath, "eps.json")) || "[]");
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
error(`[eps] ${join(DistPath, "eps.json")} 文件异常, ${err.message}`);
|
error(`[eps] ${join(DistPath, "eps.json")} 文件异常, ${err.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,60 +39,55 @@ async function getData(temps: any[]) {
|
|||||||
|
|
||||||
if (code === 1000) {
|
if (code === 1000) {
|
||||||
if (!isEmpty(data) && data) {
|
if (!isEmpty(data) && data) {
|
||||||
// @ts-ignore
|
list = Object.values(data).flat() as Eps.Entity[];
|
||||||
list = Object.values(data).flat();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error(`[eps] ${message}`);
|
error(`[eps] ${message}`);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
error(`[eps] 获取失败, ${url} 无法访问!`);
|
error(`[eps] ${url} 服务未启动!!!`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 判断是否重复项
|
// 合并本地 service 数据
|
||||||
if (isArray(temps)) {
|
if (isArray(temps)) {
|
||||||
temps.forEach((e) => {
|
temps.forEach((e) => {
|
||||||
const d = list.find((a) => e.prefix === a.prefix);
|
const d = list.find((a) => e.prefix === a.prefix);
|
||||||
|
|
||||||
if (d) {
|
if (d) {
|
||||||
Object.assign(d, e);
|
merge(d, e);
|
||||||
} else {
|
} else {
|
||||||
list.push(e);
|
list.push(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建数据文件
|
// 创建 json 文件
|
||||||
function createJson(eps: Entity[]) {
|
function createJson() {
|
||||||
createWriteStream(join(DistPath, "eps.json"), {
|
const d = list.map((e) => {
|
||||||
flags: "w"
|
return {
|
||||||
}).write(
|
prefix: e.prefix,
|
||||||
JSON.stringify(
|
name: e.name || "",
|
||||||
eps.map((e) => {
|
api: e.api.map((e) => {
|
||||||
return {
|
return {
|
||||||
prefix: e.prefix,
|
name: e.name,
|
||||||
name: e.name || "",
|
method: e.method,
|
||||||
api: e.api.map((e) => {
|
path: e.path
|
||||||
return {
|
|
||||||
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 }) {
|
function getType({ propertyName, type }: any) {
|
||||||
for (const map of Entity.mapping) {
|
for (const map of Entity.mapping) {
|
||||||
if (map.custom) {
|
if (map.custom) {
|
||||||
const resType = map.custom({ propertyName, type });
|
const resType = map.custom({ propertyName, type });
|
||||||
@ -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",
|
parser: "typescript",
|
||||||
useTabs: true,
|
useTabs: true,
|
||||||
tabWidth: 4,
|
tabWidth: 4,
|
||||||
@ -372,93 +338,82 @@ async function createDescribe({ list, service }: { list: Entity[]; service: any
|
|||||||
}).write(content);
|
}).write(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建服务
|
// 创建 service
|
||||||
function createService(data: Entity[]) {
|
function createService() {
|
||||||
const list: Entity[] = [];
|
list.forEach((e) => {
|
||||||
const service = {};
|
// 分隔路径
|
||||||
const d = { data };
|
const arr = e.prefix
|
||||||
|
.replace(/\//, "")
|
||||||
|
.replace("admin", "")
|
||||||
|
.split("/")
|
||||||
|
.filter(Boolean)
|
||||||
|
.map(toCamel);
|
||||||
|
|
||||||
for (const i in d) {
|
// 遍历
|
||||||
if (isArray(d[i])) {
|
function deep(d: any, i: number) {
|
||||||
d[i].forEach((e: Entity) => {
|
const k = arr[i];
|
||||||
// 分隔路径
|
|
||||||
const arr = e.prefix
|
|
||||||
.replace(/\//, "")
|
|
||||||
.replace("admin", "")
|
|
||||||
.split("/")
|
|
||||||
.filter(Boolean)
|
|
||||||
.map(toCamel);
|
|
||||||
|
|
||||||
// 遍历
|
if (k) {
|
||||||
function deep(d: any, i: number) {
|
// 是否最后一个
|
||||||
const k = arr[i];
|
if (arr[i + 1]) {
|
||||||
|
if (!d[k]) {
|
||||||
if (k) {
|
d[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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// 创建 eps
|
||||||
export async function createEps(query?: { list: any[] }) {
|
export async function createEps(query?: { list: any[] }) {
|
||||||
// 获取数据
|
// 获取数据
|
||||||
const data = await getData(query?.list || []);
|
await getData(query?.list || []);
|
||||||
|
|
||||||
// 生成数据
|
// 创建 service
|
||||||
const { service, list } = createService(data);
|
createService();
|
||||||
|
|
||||||
// 创建临时目录
|
// 创建临时目录
|
||||||
createDir(DistPath);
|
createDir(DistPath);
|
||||||
|
|
||||||
// 创建数据文件
|
// 创建 json 文件
|
||||||
createJson(data);
|
createJson();
|
||||||
|
|
||||||
// 创建描述文件
|
// 创建描述文件
|
||||||
createDescribe({ service, list });
|
createDescribe({ service, list });
|
||||||
|
|
||||||
return `
|
return {
|
||||||
export const eps = ${JSON.stringify({ service, list })}
|
service,
|
||||||
`;
|
list
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,73 +1,6 @@
|
|||||||
import { Plugin } from "vite";
|
import { base } from "./base";
|
||||||
import { createSvg } from "./svg";
|
import { virtual } from "./virtual";
|
||||||
import { createTag } from "./tag";
|
|
||||||
import { createEps } from "./eps";
|
|
||||||
import { createModule } from "./module";
|
|
||||||
import { createMenu } from "./menu";
|
|
||||||
import { parseJson } from "./utils";
|
|
||||||
|
|
||||||
export function cool(): Plugin {
|
export function cool() {
|
||||||
// 虚拟模块
|
return [base(), virtual()];
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,5 @@ export function createModule() {
|
|||||||
dirs = dirs.filter((e) => !e.includes("."));
|
dirs = dirs.filter((e) => !e.includes("."));
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
|
|
||||||
return `
|
return { dirs };
|
||||||
export const dirs = ${JSON.stringify(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)}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -9,7 +9,7 @@
|
|||||||
"lint:eslint": "eslint \"{src}/**/*.{vue,ts,tsx}\" --fix"
|
"lint:eslint": "eslint \"{src}/**/*.{vue,ts,tsx}\" --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cool-vue/crud": "^7.0.1-beta2",
|
"@cool-vue/crud": "^7.0.1-beta9",
|
||||||
"@element-plus/icons-vue": "^2.1.0",
|
"@element-plus/icons-vue": "^2.1.0",
|
||||||
"@vueuse/core": "^10.4.0",
|
"@vueuse/core": "^10.4.0",
|
||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
|
|||||||
6
packages/crud/index.d.ts
vendored
6
packages/crud/index.d.ts
vendored
@ -56,8 +56,8 @@ declare type List<T> = Array<DeepPartial<T> | (() => DeepPartial<T>)>;
|
|||||||
|
|
||||||
// 字典选项
|
// 字典选项
|
||||||
declare type DictOptions = {
|
declare type DictOptions = {
|
||||||
label: string;
|
label?: string;
|
||||||
value: any;
|
value?: any;
|
||||||
color?: string;
|
color?: string;
|
||||||
type?: string;
|
type?: string;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
@ -703,7 +703,7 @@ declare interface Config {
|
|||||||
size: ElementPlus.Size;
|
size: ElementPlus.Size;
|
||||||
colors: string[];
|
colors: string[];
|
||||||
form: {
|
form: {
|
||||||
labelPostion: ElementPlus.FormProps["labelPosition"];
|
labelPosition: ElementPlus.FormProps["labelPosition"];
|
||||||
labelWidth: ElementPlus.FormProps["labelWidth"];
|
labelWidth: ElementPlus.FormProps["labelWidth"];
|
||||||
span: number;
|
span: number;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@cool-vue/crud",
|
"name": "@cool-vue/crud",
|
||||||
"version": "7.0.1-beta2",
|
"version": "7.0.1-beta9",
|
||||||
"private": false,
|
"private": false,
|
||||||
"main": "./dist/index.umd.min.js",
|
"main": "./dist/index.umd.min.js",
|
||||||
"typings": "types/index.d.ts",
|
"typings": "types/index.d.ts",
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { ElMessageBox, ElMessage } from "element-plus";
|
import { ElMessageBox, ElMessage } from "element-plus";
|
||||||
import { Mitt } from "../../utils/mitt";
|
import { Mitt } from "../../utils/mitt";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { isArray, isFunction, merge } from "lodash-es";
|
import { isArray, isFunction } from "lodash-es";
|
||||||
|
import { merge } from "../../utils";
|
||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
mitt: Mitt;
|
mitt: Mitt;
|
||||||
|
|||||||
@ -463,9 +463,6 @@ export default defineComponent({
|
|||||||
<el-form
|
<el-form
|
||||||
ref={Form}
|
ref={Form}
|
||||||
size={style.size}
|
size={style.size}
|
||||||
label-position={
|
|
||||||
browser.isMini && !props.inline ? "top" : style.form.labelPostion
|
|
||||||
}
|
|
||||||
label-width={style.form.labelWidth}
|
label-width={style.form.labelWidth}
|
||||||
inline={props.inline}
|
inline={props.inline}
|
||||||
disabled={saving.value}
|
disabled={saving.value}
|
||||||
@ -476,7 +473,13 @@ export default defineComponent({
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}}
|
}}
|
||||||
/>,
|
/>,
|
||||||
config.props,
|
{
|
||||||
|
...config.props,
|
||||||
|
labelPosition:
|
||||||
|
browser.isMini && !props.inline
|
||||||
|
? "top"
|
||||||
|
: config.props.labelPosition || style.form.labelPosition
|
||||||
|
},
|
||||||
{
|
{
|
||||||
default: () => {
|
default: () => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export function useHeight({ config, Table }: { Table: Vue.Ref<any>; config: ClTa
|
|||||||
let vm = Table.value;
|
let vm = Table.value;
|
||||||
|
|
||||||
if (vm) {
|
if (vm) {
|
||||||
while (!vm.$parent?.$el.className.includes("cl-crud")) {
|
while (!vm.$parent?.$el.className?.includes("cl-crud")) {
|
||||||
vm = vm.$parent;
|
vm = vm.$parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -405,7 +405,7 @@
|
|||||||
grid-template-rows: 0fr;
|
grid-template-rows: 0fr;
|
||||||
|
|
||||||
> .cl-form-item__children {
|
> .cl-form-item__children {
|
||||||
margin: 10px 10px 10px 0px;
|
margin: 10px;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,15 +29,16 @@ export function parseTableDict(value: any, item: ClTable.Column) {
|
|||||||
// 设置颜色
|
// 设置颜色
|
||||||
if (item.dictColor) {
|
if (item.dictColor) {
|
||||||
options.forEach((e, i) => {
|
options.forEach((e, i) => {
|
||||||
e.color = style.colors[i];
|
if (!e.color) {
|
||||||
|
e.color = style.colors[i];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格式化方法
|
// 绑定值
|
||||||
const formatter = item.dictFormatter;
|
const values = (isArray(value) ? value : [value]).filter(
|
||||||
|
(e) => e !== undefined && e !== null && e !== ""
|
||||||
// 多个值
|
);
|
||||||
const values = isArray(value) ? value : [value];
|
|
||||||
|
|
||||||
// 返回值
|
// 返回值
|
||||||
const list = values.map((v) => {
|
const list = values.map((v) => {
|
||||||
@ -48,8 +49,8 @@ export function parseTableDict(value: any, item: ClTable.Column) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 是否格式化
|
// 是否格式化
|
||||||
if (formatter) {
|
if (item.dictFormatter) {
|
||||||
return formatter(list);
|
return item.dictFormatter(list);
|
||||||
} else {
|
} else {
|
||||||
return list.map((e) => {
|
return list.map((e) => {
|
||||||
return h(
|
return h(
|
||||||
@ -66,14 +67,14 @@ export function parseTableDict(value: any, item: ClTable.Column) {
|
|||||||
/**
|
/**
|
||||||
* 解析 table.op.buttons
|
* 解析 table.op.buttons
|
||||||
*/
|
*/
|
||||||
export function parseTableOpButtons(buttons: any, { scope }: any) {
|
export function parseTableOpButtons(buttons: any[], { scope }: any) {
|
||||||
const { crud } = useCore();
|
const { crud } = useCore();
|
||||||
const { style } = useConfig();
|
const { style } = useConfig();
|
||||||
const slots = useSlots();
|
const slots = useSlots();
|
||||||
|
|
||||||
const list = getValue(buttons, { scope }) || ["edit", "delete"];
|
const list: any[] = getValue(buttons, { scope }) || ["edit", "delete"];
|
||||||
|
|
||||||
return list.map((vnode: any) => {
|
return list.map((vnode) => {
|
||||||
if (vnode === "info") {
|
if (vnode === "info") {
|
||||||
return (
|
return (
|
||||||
<el-button
|
<el-button
|
||||||
|
|||||||
@ -7,7 +7,7 @@ declare const _default: import("vue").DefineComponent<{
|
|||||||
};
|
};
|
||||||
title: StringConstructor;
|
title: StringConstructor;
|
||||||
size: {
|
size: {
|
||||||
type: (StringConstructor | NumberConstructor)[];
|
type: (NumberConstructor | StringConstructor)[];
|
||||||
default: string;
|
default: string;
|
||||||
};
|
};
|
||||||
op: {
|
op: {
|
||||||
@ -22,7 +22,7 @@ declare const _default: import("vue").DefineComponent<{
|
|||||||
};
|
};
|
||||||
title: StringConstructor;
|
title: StringConstructor;
|
||||||
size: {
|
size: {
|
||||||
type: (StringConstructor | NumberConstructor)[];
|
type: (NumberConstructor | StringConstructor)[];
|
||||||
default: string;
|
default: string;
|
||||||
};
|
};
|
||||||
op: {
|
op: {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { PropType } from "vue";
|
import { PropType } from "vue";
|
||||||
declare const _default: import("vue").DefineComponent<{
|
declare const _default: import("vue").DefineComponent<{
|
||||||
modelValue: (StringConstructor | NumberConstructor)[];
|
modelValue: (NumberConstructor | StringConstructor)[];
|
||||||
labels: {
|
labels: {
|
||||||
type: ArrayConstructor;
|
type: ArrayConstructor;
|
||||||
default: () => never[];
|
default: () => never[];
|
||||||
@ -14,7 +14,7 @@ declare const _default: import("vue").DefineComponent<{
|
|||||||
default: string;
|
default: string;
|
||||||
};
|
};
|
||||||
}, () => JSX.Element, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("change" | "update:modelValue")[], "change" | "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
}, () => JSX.Element, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("change" | "update:modelValue")[], "change" | "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
||||||
modelValue: (StringConstructor | NumberConstructor)[];
|
modelValue: (NumberConstructor | StringConstructor)[];
|
||||||
labels: {
|
labels: {
|
||||||
type: ArrayConstructor;
|
type: ArrayConstructor;
|
||||||
default: () => never[];
|
default: () => never[];
|
||||||
|
|||||||
@ -74,15 +74,15 @@ export declare function useForm(): {
|
|||||||
name?: string | undefined;
|
name?: string | undefined;
|
||||||
options?: {
|
options?: {
|
||||||
[x: string]: any;
|
[x: string]: any;
|
||||||
label: string;
|
label?: string | undefined;
|
||||||
value: any;
|
value?: any;
|
||||||
color?: string | undefined;
|
color?: string | undefined;
|
||||||
type?: string | undefined;
|
type?: string | undefined;
|
||||||
}[] | {
|
}[] | {
|
||||||
value: {
|
value: {
|
||||||
[x: string]: any;
|
[x: string]: any;
|
||||||
label: string;
|
label?: string | undefined;
|
||||||
value: any;
|
value?: any;
|
||||||
color?: string | undefined;
|
color?: string | undefined;
|
||||||
type?: string | undefined;
|
type?: string | undefined;
|
||||||
}[];
|
}[];
|
||||||
@ -105,15 +105,15 @@ export declare function useForm(): {
|
|||||||
name?: string | undefined;
|
name?: string | undefined;
|
||||||
options?: {
|
options?: {
|
||||||
[x: string]: any;
|
[x: string]: any;
|
||||||
label: string;
|
label?: string | undefined;
|
||||||
value: any;
|
value?: any;
|
||||||
color?: string | undefined;
|
color?: string | undefined;
|
||||||
type?: string | undefined;
|
type?: string | undefined;
|
||||||
}[] | {
|
}[] | {
|
||||||
value: {
|
value: {
|
||||||
[x: string]: any;
|
[x: string]: any;
|
||||||
label: string;
|
label?: string | undefined;
|
||||||
value: any;
|
value?: any;
|
||||||
color?: string | undefined;
|
color?: string | undefined;
|
||||||
type?: string | undefined;
|
type?: string | undefined;
|
||||||
}[];
|
}[];
|
||||||
@ -136,15 +136,15 @@ export declare function useForm(): {
|
|||||||
name?: string | undefined;
|
name?: string | undefined;
|
||||||
options?: {
|
options?: {
|
||||||
[x: string]: any;
|
[x: string]: any;
|
||||||
label: string;
|
label?: string | undefined;
|
||||||
value: any;
|
value?: any;
|
||||||
color?: string | undefined;
|
color?: string | undefined;
|
||||||
type?: string | undefined;
|
type?: string | undefined;
|
||||||
}[] | {
|
}[] | {
|
||||||
value: {
|
value: {
|
||||||
[x: string]: any;
|
[x: string]: any;
|
||||||
label: string;
|
label?: string | undefined;
|
||||||
value: any;
|
value?: any;
|
||||||
color?: string | undefined;
|
color?: string | undefined;
|
||||||
type?: string | undefined;
|
type?: string | undefined;
|
||||||
}[];
|
}[];
|
||||||
|
|||||||
@ -15,7 +15,7 @@ declare const _default: import("vue").DefineComponent<{
|
|||||||
onSearch: FunctionConstructor;
|
onSearch: FunctionConstructor;
|
||||||
placeholder: StringConstructor;
|
placeholder: StringConstructor;
|
||||||
width: {
|
width: {
|
||||||
type: (StringConstructor | NumberConstructor)[];
|
type: (NumberConstructor | StringConstructor)[];
|
||||||
default: number;
|
default: number;
|
||||||
};
|
};
|
||||||
}, () => JSX.Element, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("change" | "update:modelValue" | "field-change")[], "change" | "update:modelValue" | "field-change", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
}, () => JSX.Element, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("change" | "update:modelValue" | "field-change")[], "change" | "update:modelValue" | "field-change", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
||||||
@ -34,7 +34,7 @@ declare const _default: import("vue").DefineComponent<{
|
|||||||
onSearch: FunctionConstructor;
|
onSearch: FunctionConstructor;
|
||||||
placeholder: StringConstructor;
|
placeholder: StringConstructor;
|
||||||
width: {
|
width: {
|
||||||
type: (StringConstructor | NumberConstructor)[];
|
type: (NumberConstructor | StringConstructor)[];
|
||||||
default: number;
|
default: number;
|
||||||
};
|
};
|
||||||
}>> & {
|
}>> & {
|
||||||
|
|||||||
@ -13,15 +13,15 @@ export declare function useTable(props: any): {
|
|||||||
name?: string | undefined;
|
name?: string | undefined;
|
||||||
options?: {
|
options?: {
|
||||||
[x: string]: any;
|
[x: string]: any;
|
||||||
label: string;
|
label?: string | undefined;
|
||||||
value: any;
|
value?: any;
|
||||||
color?: string | undefined;
|
color?: string | undefined;
|
||||||
type?: string | undefined;
|
type?: string | undefined;
|
||||||
}[] | {
|
}[] | {
|
||||||
value: {
|
value: {
|
||||||
[x: string]: any;
|
[x: string]: any;
|
||||||
label: string;
|
label?: string | undefined;
|
||||||
value: any;
|
value?: any;
|
||||||
color?: string | undefined;
|
color?: string | undefined;
|
||||||
type?: string | undefined;
|
type?: string | undefined;
|
||||||
}[];
|
}[];
|
||||||
@ -41,15 +41,15 @@ export declare function useTable(props: any): {
|
|||||||
};
|
};
|
||||||
dict: {
|
dict: {
|
||||||
[x: string]: any;
|
[x: string]: any;
|
||||||
label: string;
|
label?: string | undefined;
|
||||||
value: any;
|
value?: any;
|
||||||
color?: string | undefined;
|
color?: string | undefined;
|
||||||
type?: string | undefined;
|
type?: string | undefined;
|
||||||
}[] | {
|
}[] | {
|
||||||
value: {
|
value: {
|
||||||
[x: string]: any;
|
[x: string]: any;
|
||||||
label: string;
|
label?: string | undefined;
|
||||||
value: any;
|
value?: any;
|
||||||
color?: string | undefined;
|
color?: string | undefined;
|
||||||
type?: string | undefined;
|
type?: string | undefined;
|
||||||
}[];
|
}[];
|
||||||
|
|||||||
2
packages/crud/types/utils/parse.d.ts
vendored
2
packages/crud/types/utils/parse.d.ts
vendored
@ -12,7 +12,7 @@ export declare function parseTableDict(value: any, item: ClTable.Column): string
|
|||||||
/**
|
/**
|
||||||
* 解析 table.op.buttons
|
* 解析 table.op.buttons
|
||||||
*/
|
*/
|
||||||
export declare function parseTableOpButtons(buttons: any, { scope }: any): any;
|
export declare function parseTableOpButtons(buttons: any[], { scope }: any): any[];
|
||||||
/**
|
/**
|
||||||
* 解析扩展组件
|
* 解析扩展组件
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -200,34 +200,26 @@ export function deepPaths(paths: string[], splitor?: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 列表转树形
|
// 列表转树形
|
||||||
export function deepTree(list: any[], order?: "asc" | "desc"): any[] {
|
export function deepTree(list: any[], sort?: "desc" | "asc"): any[] {
|
||||||
const newList: any[] = [];
|
const newList: any[] = [];
|
||||||
const map: any = {};
|
const map: any = {};
|
||||||
|
|
||||||
list.forEach((e) => (map[e.id] = e));
|
orderBy(list, "orderNum", sort)
|
||||||
|
.map((e) => {
|
||||||
|
map[e.id] = e;
|
||||||
|
return e;
|
||||||
|
})
|
||||||
|
.forEach((e) => {
|
||||||
|
const parent = map[e.parentId];
|
||||||
|
|
||||||
list.forEach((e) => {
|
if (parent) {
|
||||||
const parent = map[e.parentId];
|
(parent.children || (parent.children = [])).push(e);
|
||||||
|
} else {
|
||||||
if (parent) {
|
newList.push(e);
|
||||||
(parent.children || (parent.children = [])).push(e);
|
|
||||||
} else {
|
|
||||||
newList.push(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const fn = (list: Array<any>) => {
|
|
||||||
list.map((e) => {
|
|
||||||
if (isArray(e.children)) {
|
|
||||||
e.children = orderBy(e.children, "orderNum", order);
|
|
||||||
fn(e.children);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
fn(newList);
|
return newList;
|
||||||
|
|
||||||
return orderBy(newList, "orderNum", order);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 树形转列表
|
// 树形转列表
|
||||||
|
|||||||
@ -78,8 +78,8 @@ export default defineComponent({
|
|||||||
) : (
|
) : (
|
||||||
<el-option
|
<el-option
|
||||||
disabled={e.disabled}
|
disabled={e.disabled}
|
||||||
label={e[props.labelKey] || ""}
|
label={e[props.labelKey]}
|
||||||
value={e[props.valueKey] || ""}
|
value={e[props.valueKey]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
52
src/modules/base/components/view/head/index.vue
Normal file
52
src/modules/base/components/view/head/index.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<div class="cl-view-head">
|
||||||
|
<el-icon class="cl-view-head__back" @click="router.back()">
|
||||||
|
<ArrowLeft />
|
||||||
|
</el-icon>
|
||||||
|
|
||||||
|
<span class="cl-view-head__title">{{ title }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="cl-view-head">
|
||||||
|
import { computed } from "vue";
|
||||||
|
import { useCool } from "/@/cool";
|
||||||
|
import { ArrowLeft } from "@element-plus/icons-vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
title: String
|
||||||
|
});
|
||||||
|
|
||||||
|
const { route, router } = useCool();
|
||||||
|
|
||||||
|
// 标题
|
||||||
|
const title = computed(() => props.title || route.query.title);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.cl-view-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
height: 30px;
|
||||||
|
|
||||||
|
&__back {
|
||||||
|
cursor: pointer;
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-right: 10px;
|
||||||
|
background-color: var(--el-fill-color-lighter);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -68,9 +68,7 @@
|
|||||||
<cl-svg name="bg"></cl-svg>
|
<cl-svg name="bg"></cl-svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="https://beian.miit.gov.cn" class="copyright">
|
<a href="https://cool-js.com" class="copyright"> Copyright © COOL </a>
|
||||||
Copyright © 2023 COOL | 粤 ICP 备 2022012608 号
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@ -143,12 +143,7 @@ export const useMenuStore = defineStore("menu", function () {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// 动态菜单
|
// 动态菜单
|
||||||
await service.base.comm
|
await service.base.comm.permmenu().then(next);
|
||||||
.permmenu()
|
|
||||||
.then(next)
|
|
||||||
.catch(() => {
|
|
||||||
ElMessage.error("菜单加载异常!");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,13 +9,7 @@
|
|||||||
</cl-row>
|
</cl-row>
|
||||||
|
|
||||||
<cl-row>
|
<cl-row>
|
||||||
<cl-table
|
<cl-table ref="Table" />
|
||||||
ref="Table"
|
|
||||||
:default-sort="{
|
|
||||||
prop: 'createTime',
|
|
||||||
order: 'descending'
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</cl-row>
|
</cl-row>
|
||||||
|
|
||||||
<cl-row>
|
<cl-row>
|
||||||
@ -154,7 +148,7 @@ const Table = useTable({
|
|||||||
{
|
{
|
||||||
prop: "createTime",
|
prop: "createTime",
|
||||||
label: "创建时间",
|
label: "创建时间",
|
||||||
sortable: "custom",
|
sortable: "desc",
|
||||||
minWidth: 160
|
minWidth: 160
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -129,6 +129,9 @@ function open() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
op: {
|
||||||
|
// buttons: ["save"]
|
||||||
|
},
|
||||||
on: {
|
on: {
|
||||||
open() {
|
open() {
|
||||||
refs.name.focus();
|
refs.name.focus();
|
||||||
|
|||||||
@ -13,7 +13,7 @@ const useDictStore = defineStore("dict", () => {
|
|||||||
|
|
||||||
// 获取
|
// 获取
|
||||||
function get(name: string) {
|
function get(name: string) {
|
||||||
return computed(() => data[name]);
|
return computed(() => data[name] || []);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找
|
// 查找
|
||||||
|
|||||||
7
src/modules/dict/types/index.d.ts
vendored
7
src/modules/dict/types/index.d.ts
vendored
@ -1,12 +1,13 @@
|
|||||||
export namespace Dict {
|
export namespace Dict {
|
||||||
type List = {
|
interface Item {
|
||||||
id: string;
|
id: string;
|
||||||
label: string;
|
label: string;
|
||||||
value: any;
|
value: any;
|
||||||
|
children?: Item[];
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}[];
|
}
|
||||||
|
|
||||||
interface Data {
|
interface Data {
|
||||||
[key: string]: List;
|
[key: string]: Item[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import { useFormat } from "./format";
|
|||||||
import { parsePx } from "/@/cool/utils";
|
import { parsePx } from "/@/cool/utils";
|
||||||
import { useTypes } from "./types";
|
import { useTypes } from "./types";
|
||||||
import { useCool } from "/@/cool";
|
import { useCool } from "/@/cool";
|
||||||
import { merge } from "lodash-es";
|
import { isObject, merge } from "lodash-es";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: String,
|
modelValue: String,
|
||||||
@ -61,9 +61,15 @@ function getContent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 设置内容
|
// 设置内容
|
||||||
function setContent(value?: string) {
|
function setContent(value: string = "") {
|
||||||
|
if (isObject(value)) {
|
||||||
|
value = JSON.stringify(value);
|
||||||
|
} else {
|
||||||
|
value = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (value != getContent()) {
|
if (value != getContent()) {
|
||||||
editor?.setValue(value || "");
|
editor?.setValue(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +80,7 @@ async function formatCode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建编辑器
|
// 创建编辑器
|
||||||
function init() {
|
function create() {
|
||||||
const options = merge(
|
const options = merge(
|
||||||
{
|
{
|
||||||
theme: "default",
|
theme: "default",
|
||||||
@ -148,7 +154,7 @@ watch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
init();
|
create();
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<slot>
|
||||||
|
<el-button @click="open()">{{ text }}</el-button>
|
||||||
|
</slot>
|
||||||
|
|
||||||
<cl-dialog width="1000px" :title="title" append-to-body v-model="visible">
|
<cl-dialog width="1000px" :title="title" append-to-body v-model="visible">
|
||||||
<cl-editor
|
<cl-editor
|
||||||
:name="`cl-editor-${name}`"
|
:name="`cl-editor-${name}`"
|
||||||
:ref="setRefs('editor')"
|
:ref="setRefs('editor')"
|
||||||
:height="600"
|
:height="600"
|
||||||
|
preview
|
||||||
v-bind="props.props"
|
v-bind="props.props"
|
||||||
v-model="text"
|
v-model="text"
|
||||||
/>
|
/>
|
||||||
@ -25,6 +30,7 @@ import { nextTick, PropType, ref } from "vue";
|
|||||||
import { useCool } from "/@/cool";
|
import { useCool } from "/@/cool";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
modelValue: String,
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "文本预览"
|
default: "文本预览"
|
||||||
@ -33,6 +39,10 @@ const props = defineProps({
|
|||||||
type: String as PropType<"monaco" | "quill" | "wang">,
|
type: String as PropType<"monaco" | "quill" | "wang">,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: "点击查看"
|
||||||
|
},
|
||||||
props: Object
|
props: Object
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -45,7 +55,11 @@ const visible = ref(false);
|
|||||||
// 文本
|
// 文本
|
||||||
const text = ref("");
|
const text = ref("");
|
||||||
|
|
||||||
async function open(data: string) {
|
async function open(data?: string) {
|
||||||
|
if (!data) {
|
||||||
|
data = props.modelValue;
|
||||||
|
}
|
||||||
|
|
||||||
if (isString(data)) {
|
if (isString(data)) {
|
||||||
text.value = data;
|
text.value = data;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="cl-editor-wang" :class="{ disabled }" :ref="setRefs('editor')">
|
<div class="cl-editor-wang" :class="{ disabled }" :ref="setRefs('editor')">
|
||||||
<!-- 工具栏 -->
|
<!-- 工具栏 -->
|
||||||
<toolbar :editor="Editor" :mode="mode" />
|
<toolbar :editor="Editor" :mode="mode" v-if="!preview" />
|
||||||
|
|
||||||
<!-- 编辑框 -->
|
<!-- 编辑框 -->
|
||||||
<editor
|
<editor
|
||||||
v-model="value"
|
v-model="value"
|
||||||
:defaultConfig="editorConfig"
|
:defaultConfig="editorConfig"
|
||||||
:mode="mode"
|
:mode="mode"
|
||||||
|
:style="{
|
||||||
|
height: parsePx(height)
|
||||||
|
}"
|
||||||
@onCreated="onCreated"
|
@onCreated="onCreated"
|
||||||
@onFocus="onFocus"
|
@onFocus="onFocus"
|
||||||
@onBlur="onBlur"
|
@onBlur="onBlur"
|
||||||
@ -58,8 +61,8 @@ export default defineComponent({
|
|||||||
type: [String, Number],
|
type: [String, Number],
|
||||||
default: 400
|
default: 400
|
||||||
},
|
},
|
||||||
maxHeight: [String, Number],
|
disabled: Boolean,
|
||||||
disabled: Boolean
|
preview: Boolean
|
||||||
},
|
},
|
||||||
|
|
||||||
emits: ["update:modelValue", "change", "focus", "blur"],
|
emits: ["update:modelValue", "change", "focus", "blur"],
|
||||||
@ -106,20 +109,23 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 创建后
|
||||||
function onCreated(editor: any) {
|
function onCreated(editor: any) {
|
||||||
Editor.value = editor;
|
Editor.value = editor;
|
||||||
onDisabled();
|
onDisabled();
|
||||||
onHeight();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 聚焦
|
||||||
function onFocus(editor: any) {
|
function onFocus(editor: any) {
|
||||||
emit("focus", editor);
|
emit("focus", editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 失焦
|
||||||
function onBlur(editor: any) {
|
function onBlur(editor: any) {
|
||||||
emit("blur", editor);
|
emit("blur", editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 值改变
|
||||||
function onChange() {
|
function onChange() {
|
||||||
if (value.value == "<p><br></p>") {
|
if (value.value == "<p><br></p>") {
|
||||||
value.value = "";
|
value.value = "";
|
||||||
@ -129,6 +135,7 @@ export default defineComponent({
|
|||||||
emit("change", value.value);
|
emit("change", value.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 文件选择
|
||||||
function onFileConfirm(files: any[]) {
|
function onFileConfirm(files: any[]) {
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
@ -141,30 +148,14 @@ export default defineComponent({
|
|||||||
|
|
||||||
// 禁用
|
// 禁用
|
||||||
function onDisabled() {
|
function onDisabled() {
|
||||||
if (props.disabled) {
|
if (props.disabled || props.preview) {
|
||||||
Editor.value?.disable();
|
Editor.value?.disable();
|
||||||
} else {
|
} else {
|
||||||
Editor.value?.enable();
|
Editor.value?.enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => props.disabled, onDisabled);
|
watch(() => [props.disabled, props.preview], onDisabled);
|
||||||
|
|
||||||
// 设置高度
|
|
||||||
function onHeight() {
|
|
||||||
const scroll = refs.editor.querySelector(".w-e-scroll");
|
|
||||||
scroll.style.maxHeight = parsePx(props.maxHeight || "auto");
|
|
||||||
scroll.style.height = parsePx(props.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => {
|
|
||||||
return [props.height, props.maxHeight];
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
onHeight();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
const editor = Editor.value;
|
const editor = Editor.value;
|
||||||
@ -182,7 +173,8 @@ export default defineComponent({
|
|||||||
onBlur,
|
onBlur,
|
||||||
onChange,
|
onChange,
|
||||||
editorConfig,
|
editorConfig,
|
||||||
onFileConfirm
|
onFileConfirm,
|
||||||
|
parsePx
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -71,7 +71,6 @@ export function useCode() {
|
|||||||
|
|
||||||
// 编辑器处理
|
// 编辑器处理
|
||||||
if (item.component?.name?.includes("cl-editor-")) {
|
if (item.component?.name?.includes("cl-editor-")) {
|
||||||
table.columns.push(column);
|
|
||||||
column.component = {
|
column.component = {
|
||||||
name: "cl-editor-preview",
|
name: "cl-editor-preview",
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@ -92,7 +92,7 @@
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-icon @click.stop="remove">
|
<el-icon @click.stop="remove" v-if="!disabled">
|
||||||
<delete />
|
<delete />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
@ -125,7 +125,8 @@ const props = defineProps({
|
|||||||
list: {
|
list: {
|
||||||
type: Array as PropType<Upload.Item[]>,
|
type: Array as PropType<Upload.Item[]>,
|
||||||
default: () => []
|
default: () => []
|
||||||
}
|
},
|
||||||
|
disabled: Boolean
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["remove"]);
|
const emit = defineEmits(["remove"]);
|
||||||
|
|||||||
@ -111,7 +111,12 @@
|
|||||||
>
|
>
|
||||||
<slot name="item" :item="item" :index="index">
|
<slot name="item" :item="item" :index="index">
|
||||||
<div class="cl-upload__item">
|
<div class="cl-upload__item">
|
||||||
<upload-item :item="item" :list="list" @remove="remove(index)" />
|
<upload-item
|
||||||
|
:item="item"
|
||||||
|
:list="list"
|
||||||
|
:disabled="disabled"
|
||||||
|
@remove="remove(index)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
|
|||||||
@ -282,10 +282,10 @@
|
|||||||
"@babel/helper-validator-identifier" "^7.22.20"
|
"@babel/helper-validator-identifier" "^7.22.20"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@cool-vue/crud@^7.0.1-beta2":
|
"@cool-vue/crud@^7.0.1-beta9":
|
||||||
version "7.0.1-beta2"
|
version "7.0.1-beta9"
|
||||||
resolved "https://registry.yarnpkg.com/@cool-vue/crud/-/crud-7.0.1-beta2.tgz#1c43ad0d5af3fe009bfcfa312c71d8b99a676213"
|
resolved "https://registry.yarnpkg.com/@cool-vue/crud/-/crud-7.0.1-beta9.tgz#caacb1eab03f48bc6789209242b198ebd06435f5"
|
||||||
integrity sha512-CN9hlfsWKOU/qf7E1COjgLqEqJBOd3v8v8bHeivFt7BHdDmwxrgqGZWXvZ6zp4LXSBq7dacF7dqn1FOe7TYzCQ==
|
integrity sha512-PnukV6Q1sPsXZS2li2BrmCDmYKJdqFumE/wA2kaSTOcrIgmjYmrS/oa2c3C5BKXrwDD9561kq0q8vsKBTpGQxQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
array.prototype.flat "^1.2.4"
|
array.prototype.flat "^1.2.4"
|
||||||
core-js "^3.21.1"
|
core-js "^3.21.1"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user