发布5.7.0
@ -56,6 +56,7 @@ module.exports = {
|
|||||||
"vue/html-closing-bracket-newline": "off",
|
"vue/html-closing-bracket-newline": "off",
|
||||||
"vue/max-attributes-per-line": "off",
|
"vue/max-attributes-per-line": "off",
|
||||||
"vue/multiline-html-element-content-newline": "off",
|
"vue/multiline-html-element-content-newline": "off",
|
||||||
|
"vue/multi-word-component-names": "off",
|
||||||
"vue/singleline-html-element-content-newline": "off",
|
"vue/singleline-html-element-content-newline": "off",
|
||||||
"vue/attribute-hyphenation": "off",
|
"vue/attribute-hyphenation": "off",
|
||||||
"vue/html-self-closing": "off",
|
"vue/html-self-closing": "off",
|
||||||
|
|||||||
15
.vscode/config.code-snippets
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"module-config": {
|
||||||
|
"prefix": "module-config",
|
||||||
|
"scope": "typescript",
|
||||||
|
"body": [
|
||||||
|
"import { ModuleConfig } from \"/@/cool\";",
|
||||||
|
"",
|
||||||
|
"export default (): ModuleConfig => {",
|
||||||
|
" return {};",
|
||||||
|
"};",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"description": "module config snippets"
|
||||||
|
}
|
||||||
|
}
|
||||||
7
.vscode/crud.code-snippets
vendored
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"cl-crud": {
|
"cl-crud": {
|
||||||
"prefix": "cl-crud",
|
"prefix": "cl-crud",
|
||||||
|
"scope": "vue",
|
||||||
"body": [
|
"body": [
|
||||||
"<template>",
|
"<template>",
|
||||||
" <cl-crud ref=\"Crud\">",
|
" <cl-crud ref=\"Crud\">",
|
||||||
@ -32,13 +33,11 @@
|
|||||||
" </cl-crud>",
|
" </cl-crud>",
|
||||||
"</template>",
|
"</template>",
|
||||||
"",
|
"",
|
||||||
"<script lang=\"ts\" setup>",
|
"<script lang=\"ts\" name=\"菜单名称\" setup>",
|
||||||
"import { useCrud, useTable, useUpsert } from \"@cool-vue/crud\";",
|
"import { useCrud, useTable, useUpsert } from \"@cool-vue/crud\";",
|
||||||
"import { useCool } from \"/@/cool\";",
|
"import { useCool } from \"/@/cool\";",
|
||||||
"",
|
"",
|
||||||
"const { service, named } = useCool();",
|
"const { service } = useCool();",
|
||||||
"",
|
|
||||||
"named(\"菜单名称\");",
|
|
||||||
"",
|
"",
|
||||||
"// cl-upsert 配置",
|
"// cl-upsert 配置",
|
||||||
"const Upsert = useUpsert({",
|
"const Upsert = useUpsert({",
|
||||||
|
|||||||
3
.vscode/settings.json
vendored
@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"editor.cursorSmoothCaretAnimation": true
|
"editor.cursorSmoothCaretAnimation": true,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
import { Plugin } from "vite";
|
import { Plugin } from "vite";
|
||||||
import { parseJson } from "./utils";
|
import { parseJson } from "./utils";
|
||||||
import { getModules } from "./lib/modules";
|
import { createEps, createMenu, createSvg, createTag, getEps, getModules } from "./lib";
|
||||||
import { createEps, getEps } from "./lib/eps";
|
|
||||||
import { createMenu } from "./lib/menu";
|
|
||||||
|
|
||||||
export const cool = (): Plugin | null => {
|
export function cool(): Plugin {
|
||||||
return {
|
return {
|
||||||
name: "vite-cool",
|
name: "vite-cool",
|
||||||
|
enforce: "pre",
|
||||||
configureServer(server) {
|
configureServer(server) {
|
||||||
server.middlewares.use(async (req, res, next) => {
|
server.middlewares.use(async (req, res, next) => {
|
||||||
function done(data: any) {
|
function done(data: any) {
|
||||||
@ -14,10 +13,9 @@ export const cool = (): Plugin | null => {
|
|||||||
res.end(JSON.stringify(data));
|
res.end(JSON.stringify(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自定义
|
if (req.url?.includes("__cool")) {
|
||||||
if (req.url.includes("__cool")) {
|
|
||||||
const body = await parseJson(req);
|
const body = await parseJson(req);
|
||||||
let next: any = null;
|
let next: any;
|
||||||
|
|
||||||
switch (req.url) {
|
switch (req.url) {
|
||||||
// 快速创建菜单
|
// 快速创建菜单
|
||||||
@ -54,6 +52,12 @@ export const cool = (): Plugin | null => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
transform(code, id) {
|
||||||
|
return createTag(code, id);
|
||||||
|
},
|
||||||
|
transformIndexHtml(html) {
|
||||||
|
return createSvg(html);
|
||||||
|
},
|
||||||
config() {
|
config() {
|
||||||
return {
|
return {
|
||||||
define: {
|
define: {
|
||||||
@ -62,4 +66,4 @@ export const cool = (): Plugin | null => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
// 实体生成
|
|
||||||
entity: {
|
entity: {
|
||||||
// 是否生成
|
|
||||||
enable: true,
|
|
||||||
mapping: [
|
mapping: [
|
||||||
{
|
{
|
||||||
// 自定义匹配
|
// 自定义匹配
|
||||||
@ -14,9 +11,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// 返回类型
|
|
||||||
type: "string",
|
type: "string",
|
||||||
// 匹配列类型
|
|
||||||
includes: ["varchar", "text"]
|
includes: ["varchar", "text"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,73 +3,73 @@ import { isEmpty, last } from "lodash";
|
|||||||
import { createDir, firstUpperCase, readFile, toCamel } from "../../utils";
|
import { createDir, firstUpperCase, readFile, toCamel } from "../../utils";
|
||||||
import { createWriteStream } from "fs";
|
import { createWriteStream } from "fs";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
// import * as config from "/@/cool/config";
|
|
||||||
import config from "./config";
|
import config from "./config";
|
||||||
|
|
||||||
// 临时目录路径
|
// 临时目录路径
|
||||||
const tempPath = join(__dirname, "../../temp");
|
const tempPath = join(__dirname, "../../temp");
|
||||||
|
|
||||||
// 创建描述文件
|
// 获取类型
|
||||||
export async function createEps({ list, service }: any) {
|
function getType({ entityName, propertyName, type }) {
|
||||||
const t0 = [
|
for (const map of config.entity.mapping) {
|
||||||
[
|
if (map.custom) {
|
||||||
`
|
const resType = map.custom({ entityName, propertyName, type });
|
||||||
declare interface Crud {
|
if (resType) return resType;
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data: { ids?: number[] | string[]; [key: string]: any }): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data: { id?: number | string; [key: string]: any }): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 详情
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data: { id?: number | string; [key: string]: any }): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 全部
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: { page?: number | string; size?: number | string; [key: string]: any }): Promise<PageResponse>;
|
|
||||||
}
|
}
|
||||||
`,
|
if (map.includes?.includes(type)) return map.type;
|
||||||
|
}
|
||||||
`
|
return type;
|
||||||
declare interface PageResponse {
|
|
||||||
list: any[];
|
|
||||||
pagination: { size: number; page: number; total: number };
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
}
|
||||||
`,
|
|
||||||
|
|
||||||
`
|
// 创建 Entity
|
||||||
declare interface RequestOptions {
|
function createEntity({ list }: any) {
|
||||||
params?: any;
|
const t0: any[] = [];
|
||||||
data?: any;
|
|
||||||
|
for (const item of list) {
|
||||||
|
if (!item.name) continue;
|
||||||
|
const t = [`interface ${item.name} {`];
|
||||||
|
for (const col of item.columns) {
|
||||||
|
// 描述
|
||||||
|
t.push("\n");
|
||||||
|
t.push("/**\n");
|
||||||
|
t.push(` * ${col.comment}\n`);
|
||||||
|
t.push(" */\n");
|
||||||
|
t.push(
|
||||||
|
`${col.propertyName}?: ${getType({
|
||||||
|
entityName: item.name,
|
||||||
|
propertyName: col.propertyName,
|
||||||
|
type: col.type
|
||||||
|
})};`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
t.push("\n");
|
||||||
|
t.push("/**\n");
|
||||||
|
t.push(` * 任意键值\n`);
|
||||||
|
t.push(" */\n");
|
||||||
|
t.push(`[key: string]: any;`);
|
||||||
|
t.push("}");
|
||||||
|
t0.push(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return t0.map((e) => e.join("")).join("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建 Service
|
||||||
|
function createService({ list, service }: any) {
|
||||||
|
const t0: any[] = [];
|
||||||
|
|
||||||
|
const t1 = [
|
||||||
|
`type Service = {
|
||||||
|
request(options: {
|
||||||
url: string;
|
url: string;
|
||||||
method?: "GET" | "get" | "POST" | "post" | string;
|
method?: 'POST' | 'GET' | string;
|
||||||
|
data?: any;
|
||||||
|
params?: any;
|
||||||
|
proxy?: boolean;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}): Promise<any>;
|
||||||
`
|
`
|
||||||
]
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const t1 = [`declare type Service = {`, `request(data: RequestOptions): Promise<any>;`];
|
|
||||||
|
|
||||||
// 处理数据
|
// 处理数据
|
||||||
function deep(d: any, k?: string) {
|
function deep(d: any, k?: string) {
|
||||||
if (!k) k = "";
|
if (!k) k = "";
|
||||||
@ -82,9 +82,7 @@ export async function createEps({ list, service }: any) {
|
|||||||
const item = list.find((e: any) => (e.prefix || "").includes(d[i].namespace));
|
const item = list.find((e: any) => (e.prefix || "").includes(d[i].namespace));
|
||||||
|
|
||||||
if (item) {
|
if (item) {
|
||||||
const t = [
|
const t = [`interface ${name} {`];
|
||||||
`declare interface ${name} ${item.extendCrud ? " extends Crud" : ""} {`
|
|
||||||
];
|
|
||||||
|
|
||||||
t1.push(`${i}: ${name};`);
|
t1.push(`${i}: ${name};`);
|
||||||
|
|
||||||
@ -132,10 +130,28 @@ export async function createEps({ list, service }: any) {
|
|||||||
// 返回类型
|
// 返回类型
|
||||||
let res = "";
|
let res = "";
|
||||||
|
|
||||||
|
// 实体名
|
||||||
|
const en = item.name || "any";
|
||||||
|
|
||||||
switch (a.path) {
|
switch (a.path) {
|
||||||
case "/page":
|
case "/page":
|
||||||
res = "PageResponse";
|
res = `
|
||||||
|
{
|
||||||
|
pagination: { size: number; page: number; total: number };
|
||||||
|
list: ${en} [];
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
`;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "/list":
|
||||||
|
res = `${en} []`;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "/info":
|
||||||
|
res = en;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
res = "any";
|
res = "any";
|
||||||
break;
|
break;
|
||||||
@ -145,7 +161,6 @@ export async function createEps({ list, service }: any) {
|
|||||||
t.push("\n");
|
t.push("\n");
|
||||||
t.push("/**\n");
|
t.push("/**\n");
|
||||||
t.push(` * ${a.summary || n}\n`);
|
t.push(` * ${a.summary || n}\n`);
|
||||||
t.push(` * @returns Promise<${res}>\n`);
|
|
||||||
t.push(" */\n");
|
t.push(" */\n");
|
||||||
|
|
||||||
t.push(
|
t.push(
|
||||||
@ -155,15 +170,28 @@ export async function createEps({ list, service }: any) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
permission.push(`${n}: string;`);
|
permission.push(n);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加权限
|
// 权限标识
|
||||||
t.push("\n");
|
t.push("\n");
|
||||||
t.push("/**\n");
|
t.push("/**\n");
|
||||||
t.push(" * 权限\n");
|
t.push(" * 权限标识\n");
|
||||||
t.push(" */\n");
|
t.push(" */\n");
|
||||||
t.push(`permission: { ${permission.join("\n")} }`);
|
t.push(
|
||||||
|
`permission: { ${permission.map((e) => `${e}: string;`).join("\n")} };`
|
||||||
|
);
|
||||||
|
|
||||||
|
// 权限状态
|
||||||
|
t.push("\n");
|
||||||
|
t.push("/**\n");
|
||||||
|
t.push(" * 权限状态\n");
|
||||||
|
t.push(" */\n");
|
||||||
|
t.push(
|
||||||
|
`_permission: { ${permission
|
||||||
|
.map((e) => `${e}: boolean;`)
|
||||||
|
.join("\n")} };`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
t.push("}");
|
t.push("}");
|
||||||
@ -177,14 +205,30 @@ export async function createEps({ list, service }: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 深度
|
||||||
deep(service);
|
deep(service);
|
||||||
|
|
||||||
|
// 结束
|
||||||
t1.push("}");
|
t1.push("}");
|
||||||
|
|
||||||
// 追加
|
// 追加
|
||||||
t0.push(t1);
|
t0.push(t1);
|
||||||
|
|
||||||
|
return t0.map((e) => e.join("")).join("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建描述文件
|
||||||
|
export async function createEps({ list, service }: any) {
|
||||||
|
// 文件内容
|
||||||
|
const text = `
|
||||||
|
declare namespace Eps {
|
||||||
|
${createEntity({ list })}
|
||||||
|
${createService({ list, service })}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
// 文本内容
|
// 文本内容
|
||||||
const content = prettier.format(t0.map((e) => e.join("")).join("\n\n"), {
|
const content = prettier.format(text, {
|
||||||
parser: "typescript",
|
parser: "typescript",
|
||||||
useTabs: true,
|
useTabs: true,
|
||||||
tabWidth: 4,
|
tabWidth: 4,
|
||||||
@ -198,12 +242,12 @@ export async function createEps({ list, service }: any) {
|
|||||||
// 创建 temp 目录
|
// 创建 temp 目录
|
||||||
createDir(tempPath);
|
createDir(tempPath);
|
||||||
|
|
||||||
// 创建 service 描述文件
|
// 创建 eps 描述文件
|
||||||
createWriteStream(join(tempPath, "service.d.ts"), {
|
createWriteStream(join(tempPath, "eps.d.ts"), {
|
||||||
flags: "w"
|
flags: "w"
|
||||||
}).write(content);
|
}).write(content);
|
||||||
|
|
||||||
// 创建 eps 文件
|
// 创建 eps 数据文件
|
||||||
createWriteStream(join(tempPath, "eps.json"), {
|
createWriteStream(join(tempPath, "eps.json"), {
|
||||||
flags: "w"
|
flags: "w"
|
||||||
}).write(
|
}).write(
|
||||||
@ -213,71 +257,9 @@ export async function createEps({ list, service }: any) {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (config.entity.enable) createEntity(list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取描述
|
// 获取描述
|
||||||
export function getEps() {
|
export function getEps() {
|
||||||
return JSON.stringify(readFile(join(tempPath, "eps.json")));
|
return JSON.stringify(readFile(join(tempPath, "eps.json")));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取类型
|
|
||||||
function getType({ entityName, propertyName, type }) {
|
|
||||||
for (const map of config.entity.mapping) {
|
|
||||||
if (map.custom) {
|
|
||||||
const resType = map.custom({ entityName, propertyName, type });
|
|
||||||
if (resType) return resType;
|
|
||||||
}
|
|
||||||
if (map.includes?.includes(type)) return map.type;
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建Entity描述文件
|
|
||||||
export function createEntity(list: any[]) {
|
|
||||||
const t2: any[] = [];
|
|
||||||
|
|
||||||
for (const item of list) {
|
|
||||||
if (!item.name) continue;
|
|
||||||
const t = [`declare interface ${item.name} {`];
|
|
||||||
for (const col of item.columns) {
|
|
||||||
// 描述
|
|
||||||
t.push("\n");
|
|
||||||
t.push("/**\n");
|
|
||||||
t.push(` * ${col.comment}\n`);
|
|
||||||
t.push(" */\n");
|
|
||||||
t.push(
|
|
||||||
`${col.propertyName}?: ${getType({
|
|
||||||
entityName: item.name,
|
|
||||||
propertyName: col.propertyName,
|
|
||||||
type: col.type
|
|
||||||
})};`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
t.push("\n");
|
|
||||||
t.push("/**\n");
|
|
||||||
t.push(` * 任意键值\n`);
|
|
||||||
t.push(" */\n");
|
|
||||||
t.push(`[key: string]: any;`);
|
|
||||||
t.push("}");
|
|
||||||
t2.push(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 文本内容
|
|
||||||
const content = prettier.format(t2.map((e) => e.join("")).join("\n\n"), {
|
|
||||||
parser: "typescript",
|
|
||||||
useTabs: true,
|
|
||||||
tabWidth: 4,
|
|
||||||
endOfLine: "lf",
|
|
||||||
semi: true,
|
|
||||||
singleQuote: false,
|
|
||||||
printWidth: 100,
|
|
||||||
trailingComma: "none"
|
|
||||||
});
|
|
||||||
|
|
||||||
// 创建 entity 描述文件
|
|
||||||
createWriteStream(join(tempPath, "entity.d.ts"), {
|
|
||||||
flags: "w"
|
|
||||||
}).write(content);
|
|
||||||
}
|
|
||||||
|
|||||||
5
build/cool/lib/index.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export * from "./eps";
|
||||||
|
export * from "./menu";
|
||||||
|
export * from "./module";
|
||||||
|
export * from "./svg";
|
||||||
|
export * from "./tag";
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { createWriteStream } from "fs";
|
import { createWriteStream } from "fs";
|
||||||
import prettier from "prettier";
|
import prettier from "prettier";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { createDir } from "../../utils";
|
import { mkdirs } from "../../utils";
|
||||||
import rules from "./rules";
|
import rules from "./rules";
|
||||||
import { isFunction, isRegExp, isString } from "lodash";
|
import { isFunction, isRegExp, isString } from "lodash";
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ const handler = {
|
|||||||
function createComponent(item: any) {
|
function createComponent(item: any) {
|
||||||
const { propertyName: prop, comment: label } = item;
|
const { propertyName: prop, comment: label } = item;
|
||||||
|
|
||||||
let d = null;
|
let d: any = null;
|
||||||
|
|
||||||
rules.forEach((r: any) => {
|
rules.forEach((r: any) => {
|
||||||
const s = r.test.find((e: any) => {
|
const s = r.test.find((e: any) => {
|
||||||
@ -172,7 +172,7 @@ function getPageName(router: string) {
|
|||||||
router = router.substr(1, router.length);
|
router = router.substr(1, router.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return router ? router.replace("/", "-") : "";
|
return router ? router.replace(/\//g, "-") : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 时间合并
|
// 时间合并
|
||||||
@ -198,7 +198,7 @@ function datetimeMerge({ columns, item }: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建文件
|
// 创建文件
|
||||||
export async function createMenu({ router, columns, prefix, api, module, filename }: any): void {
|
export async function createMenu({ router, columns, prefix, api, filePath }: any) {
|
||||||
const upsert: any = {
|
const upsert: any = {
|
||||||
items: []
|
items: []
|
||||||
};
|
};
|
||||||
@ -310,13 +310,11 @@ export async function createMenu({ router, columns, prefix, api, module, filenam
|
|||||||
</cl-crud>
|
</cl-crud>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" name="${getPageName(router)}" setup>
|
||||||
import { useCrud, useTable, useUpsert } from "@cool-vue/crud";
|
import { useCrud, useTable, useUpsert } from "@cool-vue/crud";
|
||||||
import { useCool } from "/@/cool";
|
import { useCool } from "/@/cool";
|
||||||
|
|
||||||
const { service, named } = useCool();
|
const { service } = useCool();
|
||||||
|
|
||||||
named("${getPageName(router)}");
|
|
||||||
|
|
||||||
// cl-upsert 配置
|
// cl-upsert 配置
|
||||||
const Upsert = useUpsert(${JSON.stringify(upsert)});
|
const Upsert = useUpsert(${JSON.stringify(upsert)});
|
||||||
@ -335,6 +333,7 @@ const Crud = useCrud(
|
|||||||
);
|
);
|
||||||
</script>`;
|
</script>`;
|
||||||
|
|
||||||
|
// 文件内容
|
||||||
const content = prettier.format(temp, {
|
const content = prettier.format(temp, {
|
||||||
parser: "vue",
|
parser: "vue",
|
||||||
useTabs: true,
|
useTabs: true,
|
||||||
@ -347,14 +346,17 @@ const Crud = useCrud(
|
|||||||
trailingComma: "none"
|
trailingComma: "none"
|
||||||
});
|
});
|
||||||
|
|
||||||
// views 目录是否存在
|
// 目录路径
|
||||||
const dir = join(__dirname, `../../../../src/modules/${module}/views`);
|
const dir = filePath.split("/");
|
||||||
|
|
||||||
|
// 文件名
|
||||||
|
const fname = dir.pop();
|
||||||
|
|
||||||
// 创建目录
|
// 创建目录
|
||||||
createDir(dir);
|
const path = mkdirs(`./src/modules/${dir.join("/")}`);
|
||||||
|
|
||||||
// 创建文件
|
// 创建文件
|
||||||
createWriteStream(join(dir, `${filename}.vue`), {
|
createWriteStream(join(path, fname), {
|
||||||
flags: "w"
|
flags: "w"
|
||||||
}).write(content);
|
}).write(content);
|
||||||
}
|
}
|
||||||
|
|||||||
12
build/cool/lib/module/index.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import fs from "fs";
|
||||||
|
|
||||||
|
export function getModules() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const dirs = fs.readdirSync("./src/modules");
|
||||||
|
resolve(dirs.filter((e) => !e.includes(".")));
|
||||||
|
} catch (e) {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import fs from "fs";
|
|
||||||
import { join } from "path";
|
|
||||||
|
|
||||||
export function getModules() {
|
|
||||||
try {
|
|
||||||
const dirs = fs.readdirSync(join(__dirname, "../../../../src/modules"));
|
|
||||||
return Promise.resolve(dirs.filter((e) => !e.includes(".")));
|
|
||||||
} catch (e) {
|
|
||||||
return Promise.reject(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
54
build/cool/lib/svg/index.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { readFileSync, readdirSync } from "fs";
|
||||||
|
import { extname } from "path";
|
||||||
|
|
||||||
|
function findFiles(dir: string): string[] {
|
||||||
|
const res: string[] = [];
|
||||||
|
const dirs = readdirSync(dir, {
|
||||||
|
withFileTypes: true
|
||||||
|
});
|
||||||
|
for (const d of dirs) {
|
||||||
|
if (d.isDirectory()) {
|
||||||
|
res.push(...findFiles(dir + d.name + "/"));
|
||||||
|
} else {
|
||||||
|
if (extname(d.name) == ".svg") {
|
||||||
|
const svg = readFileSync(dir + d.name)
|
||||||
|
.toString()
|
||||||
|
.replace(/(\r)|(\n)/g, "")
|
||||||
|
.replace(/<svg([^>+].*?)>/, (_: any, $2: any) => {
|
||||||
|
let width = 0;
|
||||||
|
let height = 0;
|
||||||
|
let content = $2.replace(
|
||||||
|
/(width|height)="([^>+].*?)"/g,
|
||||||
|
(_: any, s2: any, s3: any) => {
|
||||||
|
if (s2 === "width") {
|
||||||
|
width = s3;
|
||||||
|
} else if (s2 === "height") {
|
||||||
|
height = s3;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!/(viewBox="[^>+].*?")/g.test($2)) {
|
||||||
|
content += `viewBox="0 0 ${width} ${height}"`;
|
||||||
|
}
|
||||||
|
return `<symbol id="icon-${d.name.replace(".svg", "")}" ${content}>`;
|
||||||
|
})
|
||||||
|
.replace("</svg>", "</symbol>");
|
||||||
|
res.push(svg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createSvg(html: string) {
|
||||||
|
const res = findFiles("./src/modules/");
|
||||||
|
|
||||||
|
return html.replace(
|
||||||
|
"<body>",
|
||||||
|
`<body>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
|
||||||
|
${res.join("")}
|
||||||
|
</svg>`
|
||||||
|
);
|
||||||
|
}
|
||||||
32
build/cool/lib/tag/index.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { parse, compileScript } from "@vue/compiler-sfc";
|
||||||
|
import magicString from "magic-string";
|
||||||
|
|
||||||
|
export function createTag(code: string, id: string) {
|
||||||
|
if (/\.vue$/.test(id)) {
|
||||||
|
let s: any;
|
||||||
|
const str = () => s || (s = new magicString(code));
|
||||||
|
const { descriptor } = parse(code);
|
||||||
|
|
||||||
|
if (!descriptor.script && descriptor.scriptSetup) {
|
||||||
|
const res = compileScript(descriptor, { id });
|
||||||
|
const { name, lang }: any = res.attrs;
|
||||||
|
|
||||||
|
str().appendLeft(
|
||||||
|
0,
|
||||||
|
`<script lang="${lang}">
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
export default defineComponent({
|
||||||
|
name: "${name}"
|
||||||
|
})
|
||||||
|
<\/script>`
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
map: str().generateMap(),
|
||||||
|
code: str().toString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
507
build/cool/temp/entity.d.ts
vendored
@ -1,507 +0,0 @@
|
|||||||
declare interface BaseSysDepartmentEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 部门名称
|
|
||||||
*/
|
|
||||||
name?: string;
|
|
||||||
/**
|
|
||||||
* 上级部门ID
|
|
||||||
*/
|
|
||||||
parentId?: BigInt;
|
|
||||||
/**
|
|
||||||
* 排序
|
|
||||||
*/
|
|
||||||
orderNum?: number;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseSysLogEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 用户ID
|
|
||||||
*/
|
|
||||||
userId?: BigInt;
|
|
||||||
/**
|
|
||||||
* 行为
|
|
||||||
*/
|
|
||||||
action?: string;
|
|
||||||
/**
|
|
||||||
* ip
|
|
||||||
*/
|
|
||||||
ip?: string;
|
|
||||||
/**
|
|
||||||
* ip地址
|
|
||||||
*/
|
|
||||||
ipAddr?: string;
|
|
||||||
/**
|
|
||||||
* 参数
|
|
||||||
*/
|
|
||||||
params?: string;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseSysMenuEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 父菜单ID
|
|
||||||
*/
|
|
||||||
parentId?: BigInt;
|
|
||||||
/**
|
|
||||||
* 菜单名称
|
|
||||||
*/
|
|
||||||
name?: string;
|
|
||||||
/**
|
|
||||||
* 菜单地址
|
|
||||||
*/
|
|
||||||
router?: string;
|
|
||||||
/**
|
|
||||||
* 权限标识
|
|
||||||
*/
|
|
||||||
perms?: string;
|
|
||||||
/**
|
|
||||||
* 类型 0:目录 1:菜单 2:按钮
|
|
||||||
*/
|
|
||||||
type?: number;
|
|
||||||
/**
|
|
||||||
* 图标
|
|
||||||
*/
|
|
||||||
icon?: string;
|
|
||||||
/**
|
|
||||||
* 排序
|
|
||||||
*/
|
|
||||||
orderNum?: number;
|
|
||||||
/**
|
|
||||||
* 视图地址
|
|
||||||
*/
|
|
||||||
viewPath?: string;
|
|
||||||
/**
|
|
||||||
* 路由缓存
|
|
||||||
*/
|
|
||||||
keepAlive?: boolean;
|
|
||||||
/**
|
|
||||||
* 是否显示
|
|
||||||
*/
|
|
||||||
isShow?: boolean;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseSysParamEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 键位
|
|
||||||
*/
|
|
||||||
keyName?: string;
|
|
||||||
/**
|
|
||||||
* 名称
|
|
||||||
*/
|
|
||||||
name?: string;
|
|
||||||
/**
|
|
||||||
* 数据
|
|
||||||
*/
|
|
||||||
data?: string;
|
|
||||||
/**
|
|
||||||
* 数据类型 0:字符串 1:数组 2:键值对
|
|
||||||
*/
|
|
||||||
dataType?: number;
|
|
||||||
/**
|
|
||||||
* 备注
|
|
||||||
*/
|
|
||||||
remark?: string;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseSysRoleEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 用户ID
|
|
||||||
*/
|
|
||||||
userId?: string;
|
|
||||||
/**
|
|
||||||
* 名称
|
|
||||||
*/
|
|
||||||
name?: string;
|
|
||||||
/**
|
|
||||||
* 角色标签
|
|
||||||
*/
|
|
||||||
label?: string;
|
|
||||||
/**
|
|
||||||
* 备注
|
|
||||||
*/
|
|
||||||
remark?: string;
|
|
||||||
/**
|
|
||||||
* 数据权限是否关联上下级
|
|
||||||
*/
|
|
||||||
relevance?: number;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseSysUserEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 部门ID
|
|
||||||
*/
|
|
||||||
departmentId?: BigInt;
|
|
||||||
/**
|
|
||||||
* 姓名
|
|
||||||
*/
|
|
||||||
name?: string;
|
|
||||||
/**
|
|
||||||
* 用户名
|
|
||||||
*/
|
|
||||||
username?: string;
|
|
||||||
/**
|
|
||||||
* 密码
|
|
||||||
*/
|
|
||||||
password?: string;
|
|
||||||
/**
|
|
||||||
* 密码版本, 作用是改完密码,让原来的token失效
|
|
||||||
*/
|
|
||||||
passwordV?: number;
|
|
||||||
/**
|
|
||||||
* 昵称
|
|
||||||
*/
|
|
||||||
nickName?: string;
|
|
||||||
/**
|
|
||||||
* 头像
|
|
||||||
*/
|
|
||||||
headImg?: string;
|
|
||||||
/**
|
|
||||||
* 手机
|
|
||||||
*/
|
|
||||||
phone?: string;
|
|
||||||
/**
|
|
||||||
* 邮箱
|
|
||||||
*/
|
|
||||||
email?: string;
|
|
||||||
/**
|
|
||||||
* 备注
|
|
||||||
*/
|
|
||||||
remark?: string;
|
|
||||||
/**
|
|
||||||
* 状态 0:禁用 1:启用
|
|
||||||
*/
|
|
||||||
status?: boolean;
|
|
||||||
/**
|
|
||||||
* socketId
|
|
||||||
*/
|
|
||||||
socketId?: string;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface DemoGoodsEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 标题
|
|
||||||
*/
|
|
||||||
title?: string;
|
|
||||||
/**
|
|
||||||
* 图片
|
|
||||||
*/
|
|
||||||
pic?: string;
|
|
||||||
/**
|
|
||||||
* 价格
|
|
||||||
*/
|
|
||||||
price?: number;
|
|
||||||
/**
|
|
||||||
* 分类
|
|
||||||
*/
|
|
||||||
type?: number;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface DictInfoEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 类型ID
|
|
||||||
*/
|
|
||||||
typeId?: number;
|
|
||||||
/**
|
|
||||||
* 名称
|
|
||||||
*/
|
|
||||||
name?: string;
|
|
||||||
/**
|
|
||||||
* 排序
|
|
||||||
*/
|
|
||||||
orderNum?: number;
|
|
||||||
/**
|
|
||||||
* 备注
|
|
||||||
*/
|
|
||||||
remark?: string;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface DictTypeEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 名称
|
|
||||||
*/
|
|
||||||
name?: string;
|
|
||||||
/**
|
|
||||||
* 标识
|
|
||||||
*/
|
|
||||||
key?: string;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface SpaceInfoEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 地址
|
|
||||||
*/
|
|
||||||
url?: string;
|
|
||||||
/**
|
|
||||||
* 类型
|
|
||||||
*/
|
|
||||||
type?: string;
|
|
||||||
/**
|
|
||||||
* 分类ID
|
|
||||||
*/
|
|
||||||
classifyId?: BigInt;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface SpaceTypeEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 类别名称
|
|
||||||
*/
|
|
||||||
name?: string;
|
|
||||||
/**
|
|
||||||
* 父分类ID
|
|
||||||
*/
|
|
||||||
parentId?: number;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface TaskInfoEntity {
|
|
||||||
/**
|
|
||||||
* ID
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
* 任务ID
|
|
||||||
*/
|
|
||||||
jobId?: string;
|
|
||||||
/**
|
|
||||||
* 任务配置
|
|
||||||
*/
|
|
||||||
repeatConf?: string;
|
|
||||||
/**
|
|
||||||
* 名称
|
|
||||||
*/
|
|
||||||
name?: string;
|
|
||||||
/**
|
|
||||||
* cron
|
|
||||||
*/
|
|
||||||
cron?: string;
|
|
||||||
/**
|
|
||||||
* 最大执行次数 不传为无限次
|
|
||||||
*/
|
|
||||||
limit?: number;
|
|
||||||
/**
|
|
||||||
* 每间隔多少毫秒执行一次 如果cron设置了 这项设置就无效
|
|
||||||
*/
|
|
||||||
every?: number;
|
|
||||||
/**
|
|
||||||
* 备注
|
|
||||||
*/
|
|
||||||
remark?: string;
|
|
||||||
/**
|
|
||||||
* 状态 0:停止 1:运行
|
|
||||||
*/
|
|
||||||
status?: boolean;
|
|
||||||
/**
|
|
||||||
* 开始时间
|
|
||||||
*/
|
|
||||||
startDate?: Date;
|
|
||||||
/**
|
|
||||||
* 结束时间
|
|
||||||
*/
|
|
||||||
endDate?: Date;
|
|
||||||
/**
|
|
||||||
* 数据
|
|
||||||
*/
|
|
||||||
data?: string;
|
|
||||||
/**
|
|
||||||
* 执行的service实例ID
|
|
||||||
*/
|
|
||||||
service?: string;
|
|
||||||
/**
|
|
||||||
* 状态 0:系统 1:用户
|
|
||||||
*/
|
|
||||||
type?: number;
|
|
||||||
/**
|
|
||||||
* 下一次执行时间
|
|
||||||
*/
|
|
||||||
nextRunTime?: Date;
|
|
||||||
/**
|
|
||||||
* 状态 0:cron 1:时间间隔
|
|
||||||
*/
|
|
||||||
taskType?: number;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
createTime?: Date;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
updateTime?: Date;
|
|
||||||
/**
|
|
||||||
* 任意键值
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
1574
build/cool/temp/eps.d.ts
vendored
Normal file
952
build/cool/temp/service.d.ts
vendored
@ -1,952 +0,0 @@
|
|||||||
declare interface Crud {
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data: { ids?: number[] | string[]; [key: string]: any }): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data: { id?: number | string; [key: string]: any }): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 详情
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data: { id?: number | string; [key: string]: any }): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 全部
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: {
|
|
||||||
page?: number | string;
|
|
||||||
size?: number | string;
|
|
||||||
[key: string]: any;
|
|
||||||
}): Promise<PageResponse>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface PageResponse {
|
|
||||||
list: any[];
|
|
||||||
pagination: { size: number; page: number; total: number };
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface RequestOptions {
|
|
||||||
params?: any;
|
|
||||||
data?: any;
|
|
||||||
url: string;
|
|
||||||
method?: "GET" | "get" | "POST" | "post" | string;
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseComm {
|
|
||||||
/**
|
|
||||||
* 修改个人信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
personUpdate(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 文件上传模式
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
uploadMode(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限与菜单
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
permmenu(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 个人信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
person(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 文件上传
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
upload(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 退出
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
logout(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* list
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* page
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* info
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* update
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* delete
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* add
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
personUpdate: string;
|
|
||||||
uploadMode: string;
|
|
||||||
permmenu: string;
|
|
||||||
person: string;
|
|
||||||
upload: string;
|
|
||||||
logout: string;
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
info: string;
|
|
||||||
update: string;
|
|
||||||
delete: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseOpen {
|
|
||||||
/**
|
|
||||||
* 刷新token
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
refreshToken(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 验证码
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
captcha(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 登录
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
login(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 获得网页内容的参数值
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
html(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 实体信息与路径
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
eps(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* list
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* page
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* info
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* update
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* delete
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* add
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
refreshToken: string;
|
|
||||||
captcha: string;
|
|
||||||
login: string;
|
|
||||||
html: string;
|
|
||||||
eps: string;
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
info: string;
|
|
||||||
update: string;
|
|
||||||
delete: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseSysDepartment {
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 排序
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
order(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 列表查询
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* page
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* info
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
delete: string;
|
|
||||||
update: string;
|
|
||||||
order: string;
|
|
||||||
list: string;
|
|
||||||
add: string;
|
|
||||||
page: string;
|
|
||||||
info: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseSysLog {
|
|
||||||
/**
|
|
||||||
* 日志保存时间
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
setKeep(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 获得日志保存时间
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
getKeep(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 清理
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
clear(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* list
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* info
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* update
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* delete
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* add
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
setKeep: string;
|
|
||||||
getKeep: string;
|
|
||||||
clear: string;
|
|
||||||
page: string;
|
|
||||||
list: string;
|
|
||||||
info: string;
|
|
||||||
update: string;
|
|
||||||
delete: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseSysMenu {
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 单个信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 列表查询
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
delete: string;
|
|
||||||
update: string;
|
|
||||||
info: string;
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseSysParam {
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 获得网页内容的参数值
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
html(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 单个信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* list
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
delete: string;
|
|
||||||
update: string;
|
|
||||||
html: string;
|
|
||||||
info: string;
|
|
||||||
page: string;
|
|
||||||
add: string;
|
|
||||||
list: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseSysRole {
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 单个信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 列表查询
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
delete: string;
|
|
||||||
update: string;
|
|
||||||
info: string;
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface BaseSysUser {
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 移动部门
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
move(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 单个信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 列表查询
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
delete: string;
|
|
||||||
update: string;
|
|
||||||
move: string;
|
|
||||||
info: string;
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface DemoGoods {
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 单个信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* 列表查询
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
delete: string;
|
|
||||||
update: string;
|
|
||||||
info: string;
|
|
||||||
page: string;
|
|
||||||
list: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface DictInfo {
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 获得字典数据
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
data(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 单个信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 列表查询
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
delete: string;
|
|
||||||
update: string;
|
|
||||||
data: string;
|
|
||||||
info: string;
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface DictType {
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 单个信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 列表查询
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
delete: string;
|
|
||||||
update: string;
|
|
||||||
info: string;
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface SpaceInfo {
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 单个信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 列表查询
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
delete: string;
|
|
||||||
update: string;
|
|
||||||
info: string;
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface SpaceType {
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 单个信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 列表查询
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
delete: string;
|
|
||||||
update: string;
|
|
||||||
info: string;
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface TaskInfo {
|
|
||||||
/**
|
|
||||||
* 删除
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 修改
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 开始
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
start(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 执行一次
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
once(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 停止
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
stop(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 单个信息
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* 日志
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
log(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* list
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
delete: string;
|
|
||||||
update: string;
|
|
||||||
start: string;
|
|
||||||
once: string;
|
|
||||||
stop: string;
|
|
||||||
info: string;
|
|
||||||
page: string;
|
|
||||||
log: string;
|
|
||||||
add: string;
|
|
||||||
list: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface ChatMessage {
|
|
||||||
/**
|
|
||||||
* list
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* page
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* info
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* update
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* delete
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* add
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
info: string;
|
|
||||||
update: string;
|
|
||||||
delete: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface ChatSession {
|
|
||||||
/**
|
|
||||||
* list
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* page
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* info
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* update
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* delete
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* add
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
info: string;
|
|
||||||
update: string;
|
|
||||||
delete: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface Test {
|
|
||||||
/**
|
|
||||||
* list
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
list(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* page
|
|
||||||
* @returns Promise<PageResponse>
|
|
||||||
*/
|
|
||||||
page(data?: any): Promise<PageResponse>;
|
|
||||||
/**
|
|
||||||
* info
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
info(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* update
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
update(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* delete
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
delete(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* add
|
|
||||||
* @returns Promise<any>
|
|
||||||
*/
|
|
||||||
add(data?: any): Promise<any>;
|
|
||||||
/**
|
|
||||||
* 权限
|
|
||||||
*/
|
|
||||||
permission: {
|
|
||||||
list: string;
|
|
||||||
page: string;
|
|
||||||
info: string;
|
|
||||||
update: string;
|
|
||||||
delete: string;
|
|
||||||
add: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare type Service = {
|
|
||||||
request(data: RequestOptions): Promise<any>;
|
|
||||||
base: {
|
|
||||||
comm: BaseComm;
|
|
||||||
open: BaseOpen;
|
|
||||||
sys: {
|
|
||||||
department: BaseSysDepartment;
|
|
||||||
log: BaseSysLog;
|
|
||||||
menu: BaseSysMenu;
|
|
||||||
param: BaseSysParam;
|
|
||||||
role: BaseSysRole;
|
|
||||||
user: BaseSysUser;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
demo: { goods: DemoGoods };
|
|
||||||
dict: { info: DictInfo; type: DictType };
|
|
||||||
space: { info: SpaceInfo; type: SpaceType };
|
|
||||||
task: { info: TaskInfo };
|
|
||||||
chat: { message: ChatMessage; session: ChatSession };
|
|
||||||
test: Test;
|
|
||||||
};
|
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
import { isAbsolute, join, relative, sep } from "path";
|
||||||
|
|
||||||
// 首字母大写
|
// 首字母大写
|
||||||
export function firstUpperCase(value: string): string {
|
export function firstUpperCase(value: string): string {
|
||||||
@ -44,3 +45,24 @@ export function parseJson(req: any) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 深度创建目录
|
||||||
|
export function mkdirs(path: string) {
|
||||||
|
const arr = path.split(sep);
|
||||||
|
let p = "";
|
||||||
|
|
||||||
|
arr.forEach((e) => {
|
||||||
|
try {
|
||||||
|
fs.statSync(join(p, e));
|
||||||
|
} catch (err) {
|
||||||
|
try {
|
||||||
|
fs.mkdirSync(join(p, e));
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p = join(p, e);
|
||||||
|
});
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,106 +0,0 @@
|
|||||||
import { Plugin } from "vite";
|
|
||||||
import { readFileSync, readdirSync, accessSync } from "fs";
|
|
||||||
import path from "path";
|
|
||||||
import { isArray } from "lodash";
|
|
||||||
|
|
||||||
let idPerfix = "";
|
|
||||||
const svgTitle = /<svg([^>+].*?)>/;
|
|
||||||
const clearHeightWidth = /(width|height)="([^>+].*?)"/g;
|
|
||||||
|
|
||||||
const hasViewBox = /(viewBox="[^>+].*?")/g;
|
|
||||||
|
|
||||||
const clearReturn = /(\r)|(\n)/g;
|
|
||||||
|
|
||||||
function findSvgFile(dir: string, uniqueNames: Record<string, boolean>): string[] {
|
|
||||||
const svgRes = [];
|
|
||||||
const dirents = readdirSync(dir, {
|
|
||||||
withFileTypes: true
|
|
||||||
});
|
|
||||||
for (const dirent of dirents) {
|
|
||||||
if (dirent.isDirectory()) {
|
|
||||||
svgRes.push(...findSvgFile(path.join(dir, dirent.name), uniqueNames));
|
|
||||||
} else if (uniqueNames[dirent.name]) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
uniqueNames[dirent.name] = true;
|
|
||||||
const svg = readFileSync(path.join(dir, dirent.name))
|
|
||||||
.toString()
|
|
||||||
.replace(clearReturn, "")
|
|
||||||
.replace(svgTitle, (_: any, $2: any) => {
|
|
||||||
let width = 0;
|
|
||||||
let height = 0;
|
|
||||||
let content = $2.replace(clearHeightWidth, (_: any, s2: any, s3: any) => {
|
|
||||||
if (s2 === "width") {
|
|
||||||
width = s3;
|
|
||||||
} else if (s2 === "height") {
|
|
||||||
height = s3;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
});
|
|
||||||
if (!hasViewBox.test($2)) {
|
|
||||||
content += `viewBox="0 0 ${width} ${height}"`;
|
|
||||||
}
|
|
||||||
return `<symbol id="${idPerfix}-${dirent.name.replace(
|
|
||||||
".svg",
|
|
||||||
""
|
|
||||||
)}" ${content}>`;
|
|
||||||
})
|
|
||||||
.replace("</svg>", "</symbol>");
|
|
||||||
svgRes.push(svg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return svgRes;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const svgBuilder = (paths: string | string[], perfix = "icon"): Plugin | null => {
|
|
||||||
if (paths) {
|
|
||||||
idPerfix = perfix;
|
|
||||||
paths = isArray(paths) ? paths : [paths];
|
|
||||||
const uniqueNames: Record<string, boolean> = {};
|
|
||||||
const res = paths.reduce(
|
|
||||||
(previousValue, currentValue) =>
|
|
||||||
previousValue.concat(findSvgFile(currentValue, uniqueNames)),
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
name: "svg-transform",
|
|
||||||
transformIndexHtml(html): string {
|
|
||||||
return html.replace(
|
|
||||||
"<body>",
|
|
||||||
`
|
|
||||||
<body>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
|
|
||||||
${res.join("")}
|
|
||||||
</svg>
|
|
||||||
`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const findSvgFolders = (dir: string): string[] => {
|
|
||||||
const svgFolders = [];
|
|
||||||
const dirents = readdirSync(dir, {
|
|
||||||
withFileTypes: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// 找到结构为icons/svg的文件夹
|
|
||||||
for (const dirent of dirents) {
|
|
||||||
if (dirent.isDirectory()) {
|
|
||||||
const testPath =
|
|
||||||
dirent.name === "icons"
|
|
||||||
? path.join(dir, "icons/svg")
|
|
||||||
: path.join(dir, dirent.name, "icons/svg");
|
|
||||||
try {
|
|
||||||
accessSync(testPath);
|
|
||||||
svgFolders.push(testPath);
|
|
||||||
} catch (e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return svgFolders;
|
|
||||||
};
|
|
||||||
@ -9,7 +9,7 @@
|
|||||||
name="viewport"
|
name="viewport"
|
||||||
content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0"
|
content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0"
|
||||||
/>
|
/>
|
||||||
<title>COOL-ADMIN</title>
|
<title></title>
|
||||||
<link rel="icon" href="favicon.ico" />
|
<link rel="icon" href="favicon.ico" />
|
||||||
<style>
|
<style>
|
||||||
html,
|
html,
|
||||||
@ -144,8 +144,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<div class="preload__wrap" id="Loading">
|
||||||
<div class="preload__wrap">
|
|
||||||
<div class="preload__container">
|
<div class="preload__container">
|
||||||
<p class="preload__name">COOL-ADMIN</p>
|
<p class="preload__name">COOL-ADMIN</p>
|
||||||
<div class="preload__loading"></div>
|
<div class="preload__loading"></div>
|
||||||
@ -157,7 +156,8 @@
|
|||||||
<a href="https://cool-js.com/" target="_blank"> https://cool-js.com </a>
|
<a href="https://cool-js.com/" target="_blank"> https://cool-js.com </a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<div id="app"></div>
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
9274
package-lock.json
generated
81
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "front-next",
|
"name": "front-next",
|
||||||
"version": "5.6.2",
|
"version": "5.7.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --host",
|
"dev": "vite --host",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
@ -9,63 +9,60 @@
|
|||||||
"lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix"
|
"lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cool-vue/crud": "^5.2.10",
|
"@codemirror/lang-javascript": "^6.0.1",
|
||||||
"@element-plus/icons-vue": "^1.1.3",
|
"@codemirror/theme-one-dark": "^6.0.0",
|
||||||
"@vueuse/core": "^8.2.5",
|
"@cool-vue/crud": "^5.3.0",
|
||||||
|
"@element-plus/icons-vue": "^2.0.6",
|
||||||
|
"@vueuse/core": "^8.9.4",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"codemirror": "^5.62.0",
|
"codemirror": "^6.0.1",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.23.5",
|
||||||
"echarts": "^5.0.2",
|
"echarts": "^5.3.3",
|
||||||
"element-plus": "^2.2.5",
|
"element-plus": "^2.2.9",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"js-beautify": "^1.13.5",
|
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mitt": "^3.0.0",
|
"mitt": "^3.0.0",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^2.0.12",
|
"pinia": "^2.0.16",
|
||||||
"quill": "^1.3.7",
|
"quill": "^1.3.7",
|
||||||
"socket.io-client": "^4.5.1",
|
"socket.io-client": "^4.5.1",
|
||||||
"store": "^2.0.12",
|
"store": "^2.0.12",
|
||||||
"unocss": "^0.31.0",
|
"unocss": "^0.44.3",
|
||||||
"vue": "^3.2.32",
|
"vue": "^3.2.37",
|
||||||
"vue-echarts": "^6.0.2",
|
"vue-codemirror": "^6.0.0",
|
||||||
"vue-router": "^4.0.14",
|
"vue-echarts": "^6.2.3",
|
||||||
|
"vue-router": "^4.1.2",
|
||||||
"vuedraggable": "^4.1.0",
|
"vuedraggable": "^4.1.0",
|
||||||
"xlsx": "^0.16.9"
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash": "^4.14.168",
|
"@types/lodash": "^4.14.182",
|
||||||
"@types/node": "^16.10.2",
|
"@types/mockjs": "^1.0.6",
|
||||||
|
"@types/node": "^18.0.6",
|
||||||
"@types/nprogress": "^0.2.0",
|
"@types/nprogress": "^0.2.0",
|
||||||
"@types/quill": "^2.0.9",
|
"@types/quill": "^2.0.9",
|
||||||
"@types/store": "^2.0.2",
|
"@types/store": "^2.0.2",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.20.0",
|
"@typescript-eslint/eslint-plugin": "^5.30.6",
|
||||||
"@typescript-eslint/parser": "^4.20.0",
|
"@typescript-eslint/parser": "^5.30.6",
|
||||||
"@unocss/preset-uno": "^0.31.0",
|
"@unocss/preset-uno": "^0.44.3",
|
||||||
"@vitejs/plugin-vue": "^2.3.1",
|
"@vitejs/plugin-vue": "^3.0.1",
|
||||||
"@vitejs/plugin-vue-jsx": "^1.3.9",
|
"@vitejs/plugin-vue-jsx": "^2.0.0",
|
||||||
"@vue/cli-plugin-babel": "^5.0.1",
|
"@vue/cli-plugin-babel": "^5.0.8",
|
||||||
"@vue/cli-plugin-typescript": "^5.0.1",
|
"@vue/cli-plugin-typescript": "^5.0.8",
|
||||||
"@vue/compiler-sfc": "^3.2.31",
|
"@vue/compiler-sfc": "^3.2.37",
|
||||||
"@vue/composition-api": "^1.4.9",
|
"@vue/composition-api": "^1.7.0",
|
||||||
"eslint": "^7.23.0",
|
"eslint": "^8.20.0",
|
||||||
"eslint-config-prettier": "^8.1.0",
|
"eslint-config-prettier": "^8.1.0",
|
||||||
"eslint-plugin-prettier": "^3.3.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-vue": "^7.13.0",
|
"eslint-plugin-vue": "^9.2.0",
|
||||||
"iconv-lite": "^0.6.3",
|
"magic-string": "^0.26.2",
|
||||||
"prettier": "^2.4.1",
|
"prettier": "^2.7.1",
|
||||||
"sass": "^1.49.9",
|
"sass": "^1.53.0",
|
||||||
"sass-loader": "^11.1.1",
|
"sass-loader": "^13.0.2",
|
||||||
"svg-sprite-loader": "^6.0.2",
|
"typescript": "^4.7.4",
|
||||||
"typescript": "^4.6.2",
|
"vite": "^3.0.2",
|
||||||
"unplugin-vue-components": "^0.17.21",
|
"vite-plugin-compression": "^0.5.1"
|
||||||
"vite": "^2.9.8",
|
|
||||||
"vite-plugin-compression": "^0.5.1",
|
|
||||||
"vite-plugin-dts": "^0.9.9",
|
|
||||||
"vite-plugin-mock": "^2.9.6",
|
|
||||||
"vite-plugin-style-import": "^1.0.1",
|
|
||||||
"vite-svg-loader": "^2.1.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
18
src/App.vue
@ -1,18 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-config-provider :locale="zhCn">
|
<el-config-provider :locale="zhCn">
|
||||||
<div class="preload__wrap" v-if="app.loading">
|
|
||||||
<div class="preload__container">
|
|
||||||
<p class="preload__name">{{ app.info.name }}</p>
|
|
||||||
<div class="preload__loading"></div>
|
|
||||||
<p class="preload__title">正在加载菜单...</p>
|
|
||||||
<p class="preload__sub-title">初次加载资源可能需要较多时间 请耐心等待</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="preload__footer">
|
|
||||||
<a href="https://cool-js.com" target="_blank"> https://cool-js.com </a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<router-view />
|
<router-view />
|
||||||
</el-config-provider>
|
</el-config-provider>
|
||||||
</template>
|
</template>
|
||||||
@ -20,9 +7,4 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ElConfigProvider } from "element-plus";
|
import { ElConfigProvider } from "element-plus";
|
||||||
import zhCn from "element-plus/lib/locale/lang/zh-cn";
|
import zhCn from "element-plus/lib/locale/lang/zh-cn";
|
||||||
import { useBase } from "/$/base";
|
|
||||||
|
|
||||||
const { app } = useBase();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" src="./assets/css/index.scss"></style>
|
|
||||||
|
|||||||
@ -1,44 +0,0 @@
|
|||||||
* {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
|
|
||||||
"微软雅黑", Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
*::-webkit-scrollbar {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
*::-webkit-scrollbar-thumb {
|
|
||||||
background-color: rgba(144, 147, 153, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
*::-webkit-scrollbar-track {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--view-bg-color: #f7f7f7;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
button {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
&:-webkit-autofill {
|
|
||||||
box-shadow: 0 0 0px 1000px white inset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 4.4 KiB |
@ -1,56 +1,36 @@
|
|||||||
import { createPinia } from "pinia";
|
import { createPinia } from "pinia";
|
||||||
import { App } from "vue";
|
import { App } from "vue";
|
||||||
import { useModule } from "./module";
|
import { modular } from "./module";
|
||||||
import { router, viewer } from "./router";
|
import { router } from "./router";
|
||||||
import { useBase } from "/$/base";
|
import { useBase } from "/$/base";
|
||||||
import mitt from "mitt";
|
import mitt from "mitt";
|
||||||
import VueECharts from "vue-echarts";
|
import VueECharts from "vue-echarts";
|
||||||
import ElementPlus from "element-plus";
|
import ElementPlus from "element-plus";
|
||||||
import "element-plus/theme-chalk/src/index.scss";
|
import "element-plus/theme-chalk/src/index.scss";
|
||||||
import "uno.css";
|
import "uno.css";
|
||||||
import { useDict } from "/$/dict";
|
|
||||||
|
|
||||||
export async function bootstrap(Vue: App) {
|
export async function bootstrap(Vue: App) {
|
||||||
// 缓存
|
// pinia
|
||||||
Vue.use(createPinia());
|
Vue.use(createPinia());
|
||||||
|
|
||||||
// ui库
|
// element-plus
|
||||||
Vue.use(ElementPlus);
|
Vue.use(ElementPlus);
|
||||||
|
|
||||||
// 事件通讯
|
// mitt
|
||||||
Vue.provide("mitt", mitt());
|
Vue.provide("mitt", mitt());
|
||||||
|
|
||||||
// 可视图表
|
// charts
|
||||||
Vue.component("v-chart", VueECharts);
|
Vue.component("v-chart", VueECharts);
|
||||||
|
|
||||||
// 基础
|
|
||||||
const { app, user, menu } = useBase();
|
|
||||||
|
|
||||||
// 加载模块
|
|
||||||
useModule(Vue);
|
|
||||||
|
|
||||||
// 取缓存视图
|
|
||||||
viewer.add(menu.routes);
|
|
||||||
|
|
||||||
// 路由
|
// 路由
|
||||||
Vue.use(router);
|
Vue.use(router);
|
||||||
|
|
||||||
// 开启
|
// 模块
|
||||||
app.showLoading();
|
Vue.use(modular);
|
||||||
|
|
||||||
if (user.token) {
|
// 数据
|
||||||
// 字典
|
const { app } = useBase();
|
||||||
const { dict } = useDict();
|
|
||||||
|
|
||||||
// 获取字典数据
|
// 事件加载
|
||||||
dict.refresh();
|
app.req = modular.emit("onLoad");
|
||||||
|
|
||||||
// 获取用户信息
|
|
||||||
user.get();
|
|
||||||
|
|
||||||
// 获取菜单权限
|
|
||||||
await menu.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
app.hideLoading();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,10 +22,8 @@ export const config = {
|
|||||||
router: {
|
router: {
|
||||||
// 模式
|
// 模式
|
||||||
mode: "history",
|
mode: "history",
|
||||||
// 页面
|
// 首页组件
|
||||||
pages: [],
|
home: import("/$/demo/views/home/index.vue")
|
||||||
// 视图 / 路由下的 children
|
|
||||||
views: []
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 字体图标库
|
// 字体图标库
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import { onBeforeUpdate, ref, inject, getCurrentInstance } from "vue";
|
import { Emitter } from "mitt";
|
||||||
|
import { onBeforeUpdate, ref, inject } from "vue";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
import { useService } from "../service";
|
import { useService } from "../service";
|
||||||
|
|
||||||
|
const service = useService();
|
||||||
|
|
||||||
export function useRefs() {
|
export function useRefs() {
|
||||||
const refs: any = ref<any[]>([]);
|
const refs: any = ref<any[]>([]);
|
||||||
|
|
||||||
@ -16,34 +19,12 @@ export function useRefs() {
|
|||||||
return { refs, setRefs };
|
return { refs, setRefs };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 服务
|
|
||||||
const service = useService();
|
|
||||||
|
|
||||||
// 组件命名
|
|
||||||
function named(name: string) {
|
|
||||||
const { proxy }: any = getCurrentInstance();
|
|
||||||
proxy.$.type.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useCool() {
|
export function useCool() {
|
||||||
const { refs, setRefs } = useRefs();
|
|
||||||
|
|
||||||
// 通信
|
|
||||||
const mitt = inject<any>("mitt");
|
|
||||||
|
|
||||||
// 路由
|
|
||||||
const route = useRoute();
|
|
||||||
|
|
||||||
// 路由器
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
route,
|
|
||||||
router,
|
|
||||||
refs,
|
|
||||||
setRefs,
|
|
||||||
service,
|
service,
|
||||||
mitt,
|
route: useRoute(),
|
||||||
named
|
router: useRouter(),
|
||||||
|
mitt: inject("mitt") as Emitter<any>,
|
||||||
|
...useRefs()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,4 +3,6 @@ export * from "./bootstrap";
|
|||||||
export * from "./hook";
|
export * from "./hook";
|
||||||
export * from "./router";
|
export * from "./router";
|
||||||
export * from "./config";
|
export * from "./config";
|
||||||
export { storage, module } from "./utils";
|
export * from "./module";
|
||||||
|
export * from "./types/index.d";
|
||||||
|
export { storage, hideLoading } from "./utils";
|
||||||
|
|||||||
@ -1,162 +1,121 @@
|
|||||||
import { App } from "vue";
|
import { App } from "vue";
|
||||||
import modules from "/@/modules";
|
import { isFunction, orderBy } from "lodash";
|
||||||
import { router, viewer } from "../router";
|
import { Module } from "../types";
|
||||||
import { filename, module } from "../utils";
|
import { filename } from "../utils";
|
||||||
import { isFunction, isObject } from "lodash";
|
|
||||||
|
|
||||||
// 扫描文件
|
// 扫描文件
|
||||||
const files = import.meta.globEager("/src/modules/**/*");
|
const files: any = import.meta.glob("/src/modules/*/{config.ts,service/**,directives/**}", {
|
||||||
|
eager: true
|
||||||
|
});
|
||||||
|
|
||||||
// 模块列表
|
// @ts-ignore
|
||||||
const list: any[] = [...modules];
|
const list: Module[] = window.__modules__ || (window.__modules__ = []);
|
||||||
|
|
||||||
function main() {
|
// 模块
|
||||||
|
const module = {
|
||||||
|
list,
|
||||||
|
|
||||||
|
get(name: string): Module {
|
||||||
|
// @ts-ignore
|
||||||
|
return this.list.find((e) => e.name == name);
|
||||||
|
},
|
||||||
|
|
||||||
|
add(data: Module) {
|
||||||
|
this.list.push(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 解析
|
||||||
for (const i in files) {
|
for (const i in files) {
|
||||||
// 模块名
|
// 分割
|
||||||
const [, , , name, action] = i.split("/");
|
const [, , , name, action] = i.split("/");
|
||||||
|
|
||||||
// 文件内容
|
|
||||||
let value: any = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
value = files[i].default;
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err, i);
|
|
||||||
value = files[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!value) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 文件名
|
// 文件名
|
||||||
const fname: string = filename(i);
|
const fname = filename(i);
|
||||||
|
|
||||||
// 配置参数
|
// 文件内容
|
||||||
function next(d: any) {
|
const v = files[i]?.default;
|
||||||
// 配置参数入口
|
|
||||||
if (action == "config.ts") {
|
|
||||||
d.options = value || {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 模块入口
|
// 模块是否存在
|
||||||
if (action == "index.ts") {
|
const m = module.get(name);
|
||||||
d.value = value || {};
|
|
||||||
}
|
// 数据
|
||||||
|
const d = m || {
|
||||||
|
name,
|
||||||
|
value: null,
|
||||||
|
services: [],
|
||||||
|
directives: []
|
||||||
|
};
|
||||||
|
|
||||||
// 其他功能
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "service":
|
// 配置参数
|
||||||
const s = new value();
|
case "config.ts":
|
||||||
|
d.value = v;
|
||||||
|
break;
|
||||||
|
|
||||||
d.service.push({
|
// 请求服务
|
||||||
|
case "service":
|
||||||
|
const s = new v();
|
||||||
|
|
||||||
|
if (s) {
|
||||||
|
d.services?.push({
|
||||||
path: s.namespace,
|
path: s.namespace,
|
||||||
value: s
|
value: s
|
||||||
});
|
});
|
||||||
break;
|
|
||||||
|
|
||||||
case "pages":
|
|
||||||
case "views":
|
|
||||||
if (value.cool) {
|
|
||||||
d[action].push({
|
|
||||||
...value.cool.route,
|
|
||||||
component: value
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "components":
|
// 指令
|
||||||
d.components[value.name] = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "directives":
|
case "directives":
|
||||||
d.directives[fname] = value;
|
d.directives?.push({ name: fname, value: v });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return d;
|
if (!m) {
|
||||||
}
|
module.add(d);
|
||||||
|
|
||||||
// 是否存在
|
|
||||||
const item: any = list.find((e) => e.name === name);
|
|
||||||
|
|
||||||
if (item) {
|
|
||||||
if (!item.isLoaded) {
|
|
||||||
next(item);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
list.push(
|
|
||||||
next({
|
|
||||||
name,
|
|
||||||
options: {},
|
|
||||||
directives: {},
|
|
||||||
components: {},
|
|
||||||
pages: [],
|
|
||||||
views: [],
|
|
||||||
service: []
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.set(list);
|
// 模块处理器
|
||||||
}
|
const modular = {
|
||||||
|
install(app: App) {
|
||||||
|
module.list.forEach((e) => {
|
||||||
|
const d = isFunction(e.value) ? e.value(app) : e.value;
|
||||||
|
|
||||||
main();
|
if (d) {
|
||||||
|
Object.assign(e, d);
|
||||||
|
|
||||||
export function useModule(app: App) {
|
|
||||||
// 模块安装
|
|
||||||
list.forEach((e: any) => {
|
|
||||||
if (isObject(e.value)) {
|
|
||||||
if (isFunction(e.value.install)) {
|
|
||||||
Object.assign(e, e.value.install(app, e.options));
|
|
||||||
} else {
|
|
||||||
Object.assign(e, e.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 注册组件
|
// 注册组件
|
||||||
if (e.components) {
|
e.components?.forEach(async (c: any) => {
|
||||||
for (const i in e.components) {
|
const v = await (isFunction(c) ? c() : c);
|
||||||
if (e.components[i]) {
|
const n = v.default || v;
|
||||||
if (e.components[i].cool?.global || i.indexOf("cl-") === 0) {
|
app.component(n.name, n);
|
||||||
app.component(e.components[i].name, e.components[i]);
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册指令
|
// 注册指令
|
||||||
if (e.directives) {
|
e.directives?.forEach((v) => {
|
||||||
for (const i in e.directives) {
|
app.directive(v.name, v.value);
|
||||||
app.directive(i, e.directives[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册页面
|
|
||||||
if (e.pages) {
|
|
||||||
e.pages.forEach((e: any) => {
|
|
||||||
router.addRoute(e);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// 注册视图
|
// 安装事件
|
||||||
if (e.views) {
|
if (d.install) {
|
||||||
e.views.forEach((e: any) => {
|
d.install(app, d.options);
|
||||||
if (!e.meta) {
|
|
||||||
e.meta = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.path) {
|
|
||||||
viewer.add([e]);
|
|
||||||
} else {
|
|
||||||
console.error(`[${name}-views]:缺少 path 参数`);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
async emit(name: "onLoad") {
|
||||||
|
const list = orderBy(module.list, "order");
|
||||||
|
const events = {};
|
||||||
|
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
if (list[i][name]) {
|
||||||
|
// @ts-ignore
|
||||||
|
const e = await list[i][name](events);
|
||||||
|
Object.assign(events, e);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
console.error(`模块 ${name} 异常`, err);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { module, modular };
|
||||||
|
|||||||
@ -1,82 +1,41 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import {
|
import { createRouter, createWebHashHistory, createWebHistory, RouteRecordRaw } from "vue-router";
|
||||||
createRouter,
|
import { config, Router, storage, module, hideLoading } from "/@/cool";
|
||||||
createWebHashHistory,
|
import { isArray } from "lodash";
|
||||||
createWebHistory,
|
|
||||||
NavigationGuardNext,
|
|
||||||
RouteRecordRaw
|
|
||||||
} from "vue-router";
|
|
||||||
import { storage, config } from "/@/cool";
|
|
||||||
import { useBase } from "/$/base";
|
import { useBase } from "/$/base";
|
||||||
import { cloneDeep, isArray } from "lodash";
|
|
||||||
|
|
||||||
// 视图文件
|
// 扫描文件
|
||||||
const views = import.meta.globEager("/src/**/views/**/*.vue");
|
const files = import.meta.glob(["/src/modules/*/{views,pages}/**/*", "!**/components"]);
|
||||||
|
|
||||||
for (const i in views) {
|
|
||||||
views[i.slice(5)] = views[i];
|
|
||||||
delete views[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 默认路由
|
// 默认路由
|
||||||
const routes: RouteRecordRaw[] = [
|
const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
name: "index",
|
name: "index",
|
||||||
component: () => import("/$/base/pages/layout/index.vue"),
|
component: () => import("/$/base/layout/index.vue"),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "",
|
||||||
name: "数据统计",
|
name: "home",
|
||||||
component: () => import("/@/views/home/index.vue")
|
component: config.app.router.home
|
||||||
},
|
}
|
||||||
...config.app.router.views
|
|
||||||
]
|
]
|
||||||
},
|
|
||||||
...config.app.router.pages,
|
|
||||||
{
|
|
||||||
path: "/:catchAll(.*)",
|
|
||||||
name: "404",
|
|
||||||
redirect: "/404"
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// 创建
|
// 创建路由器
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: config.app.router.mode == "history" ? createWebHistory() : createWebHashHistory(),
|
history: config.app.router.mode == "history" ? createWebHistory() : createWebHashHistory(),
|
||||||
routes
|
routes
|
||||||
}) as CoolRouter;
|
}) as Router;
|
||||||
|
|
||||||
// 路由守卫
|
// 组件加载后
|
||||||
router.beforeEach((to: any, _: any, next: NavigationGuardNext) => {
|
router.beforeResolve(() => {
|
||||||
const { user, process } = useBase();
|
hideLoading();
|
||||||
|
|
||||||
if (user.token) {
|
|
||||||
if (to.path.includes("/login")) {
|
|
||||||
// 登录成功且 token 未过期,回到首页
|
|
||||||
if (!storage.isExpired("token")) {
|
|
||||||
return next("/");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 添加路由进程
|
|
||||||
process.add({
|
|
||||||
keepAlive: to.meta?.keepAlive,
|
|
||||||
label: to.meta?.label || to.name,
|
|
||||||
value: to.fullPath
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!config.ignore.token.find((e: string) => to.path == e)) {
|
|
||||||
return next("/login");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
next();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 自定义
|
// 跳转
|
||||||
router.href = function (path: string) {
|
router.href = function (path) {
|
||||||
const url = import.meta.env.BASE_URL + path;
|
const url = import.meta.env.BASE_URL + path;
|
||||||
|
|
||||||
if (url != location.pathname) {
|
if (url != location.pathname) {
|
||||||
@ -84,6 +43,44 @@ router.href = function (path: string) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 添加试图,页面路由
|
||||||
|
router.append = function (data) {
|
||||||
|
const list = isArray(data) ? data : [data];
|
||||||
|
|
||||||
|
list.forEach((e) => {
|
||||||
|
const d = { ...e };
|
||||||
|
|
||||||
|
if (!d.name) {
|
||||||
|
d.name = d.path.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.isPage) {
|
||||||
|
router.addRoute(d);
|
||||||
|
} else {
|
||||||
|
if (!d.component) {
|
||||||
|
const url = d.viewPath;
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
if (url.indexOf("http") == 0) {
|
||||||
|
if (d.meta) {
|
||||||
|
d.meta.iframeUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
d.component = () => import(`/$/base/views/iframe/index.vue`);
|
||||||
|
} else {
|
||||||
|
d.component = files["/src/" + url.replace("cool/", "")];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
d.redirect = "/404";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
router.addRoute("index", d);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
let lock = false;
|
let lock = false;
|
||||||
|
|
||||||
// 错误监听
|
// 错误监听
|
||||||
@ -100,45 +97,93 @@ router.onError((err: any) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 视图
|
// 注册
|
||||||
const viewer = {
|
async function register(path: string) {
|
||||||
add(data: any[] | any) {
|
// 当前路由是否存在
|
||||||
// 列表
|
const d = router.getRoutes().find((e) => e.path == path);
|
||||||
const list = isArray(data) ? data : [data];
|
|
||||||
|
|
||||||
list.forEach((e: any) => {
|
if (!d) {
|
||||||
const d: any = cloneDeep(e);
|
const { app, menu } = useBase();
|
||||||
|
|
||||||
// 命名
|
// 等待加载
|
||||||
d.name = d.router;
|
await app.req;
|
||||||
|
|
||||||
if (!d.component) {
|
// 待注册列表
|
||||||
const url = d.viewPath;
|
const list: any[] = [];
|
||||||
|
|
||||||
if (url) {
|
// 菜单数据
|
||||||
if (
|
menu.routes.find((e) => {
|
||||||
/^(http[s]?:\/\/)([0-9a-z.]+)(:[0-9]+)?([/0-9a-z.]+)?(\?[0-9a-z&=]+)?(#[0-9-a-z]+)?/i.test(
|
list.push({
|
||||||
url
|
...e,
|
||||||
)
|
isPage: e.viewPath?.includes("/pages")
|
||||||
) {
|
});
|
||||||
d.meta.iframeUrl = url;
|
|
||||||
d.component = () => import(`/$/base/pages/iframe/index.vue`);
|
|
||||||
} else {
|
|
||||||
d.component = () => Promise.resolve(views[url.replace("cool/", "")]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
d.redirect = "/404";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 批量添加
|
|
||||||
router.addRoute("index", d);
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
get() {
|
// 模块数据
|
||||||
return router.getRoutes().find((e) => e.name == "index")?.children;
|
module.list.forEach((e) => {
|
||||||
|
if (e.views) {
|
||||||
|
list.push(...e.views);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
export { router, viewer };
|
if (e.pages) {
|
||||||
|
list.push(
|
||||||
|
...e.pages.map((d) => {
|
||||||
|
return {
|
||||||
|
...d,
|
||||||
|
isPage: true
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 需要注册的路由
|
||||||
|
const r = list.find((e) => e.path == path);
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
router.append(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r?.path || "/404";
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 路由守卫
|
||||||
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
// 注册路由
|
||||||
|
const path = await register(to.path);
|
||||||
|
|
||||||
|
if (path) {
|
||||||
|
// 重定向
|
||||||
|
next({ ...to, path });
|
||||||
|
} else {
|
||||||
|
// 数据缓存
|
||||||
|
const { user, process } = useBase();
|
||||||
|
|
||||||
|
// 登录成功
|
||||||
|
if (user.token) {
|
||||||
|
// 在登录页
|
||||||
|
if (to.path.includes("/login")) {
|
||||||
|
// Token 未过期
|
||||||
|
if (!storage.isExpired("token")) {
|
||||||
|
// 回到首页
|
||||||
|
return next("/");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 添加路由进程
|
||||||
|
process.add(to);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 忽略部分 Token 验证
|
||||||
|
if (!config.ignore.token.find((e) => to.path == e)) {
|
||||||
|
return next("/login");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export { router };
|
||||||
|
|||||||
@ -46,15 +46,7 @@ export class BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
request(
|
request(options: any = {}) {
|
||||||
options = {} as {
|
|
||||||
params?: any;
|
|
||||||
data?: any;
|
|
||||||
url: string;
|
|
||||||
method?: "GET" | "get" | "POST" | "post" | string;
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
if (!options.params) options.params = {};
|
if (!options.params) options.params = {};
|
||||||
|
|
||||||
let ns = "";
|
let ns = "";
|
||||||
@ -91,7 +83,7 @@ export class BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
page(data: { page?: number; size?: number; [key: string]: any }) {
|
page(data: any) {
|
||||||
return this.request({
|
return this.request({
|
||||||
url: "/page",
|
url: "/page",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@ -99,14 +91,14 @@ export class BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
info(params: { id?: number | string; [key: string]: any }) {
|
info(params: any) {
|
||||||
return this.request({
|
return this.request({
|
||||||
url: "/info",
|
url: "/info",
|
||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
update(data: { id?: number | string; [key: string]: any }) {
|
update(data: any) {
|
||||||
return this.request({
|
return this.request({
|
||||||
url: "/update",
|
url: "/update",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@ -114,7 +106,7 @@ export class BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(data: { ids?: number[] | string[]; [key: string]: any }) {
|
delete(data: any) {
|
||||||
return this.request({
|
return this.request({
|
||||||
url: "/delete",
|
url: "/delete",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
|||||||
@ -13,7 +13,7 @@ function getNames(v: any) {
|
|||||||
// 标签名
|
// 标签名
|
||||||
const names = getNames(new BaseService());
|
const names = getNames(new BaseService());
|
||||||
|
|
||||||
export function useEps(service: Service) {
|
export function useEps(service: Eps.Service) {
|
||||||
// 创建描述文件
|
// 创建描述文件
|
||||||
function createDts(list: any[]) {
|
function createDts(list: any[]) {
|
||||||
function deep(v: any) {
|
function deep(v: any) {
|
||||||
|
|||||||
@ -1,9 +1,35 @@
|
|||||||
import { deepFiles, deepMerge, module } from "../utils";
|
import { deepMerge, basename } from "../utils";
|
||||||
import { BaseService } from "./base";
|
import { BaseService } from "./base";
|
||||||
import { useEps } from "./eps";
|
import { useEps } from "./eps";
|
||||||
|
import { module } from "../module";
|
||||||
|
|
||||||
|
// 路径转对象
|
||||||
|
function deepFiles(list: any[]) {
|
||||||
|
const data: any = {};
|
||||||
|
|
||||||
|
list.forEach(({ path, value }) => {
|
||||||
|
const arr: string[] = path.split("/");
|
||||||
|
const parents = arr.slice(0, arr.length - 1);
|
||||||
|
const name = basename(path).replace(".ts", "");
|
||||||
|
|
||||||
|
let curr = data;
|
||||||
|
|
||||||
|
parents.forEach((k) => {
|
||||||
|
if (!curr[k]) {
|
||||||
|
curr[k] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
curr = curr[k];
|
||||||
|
});
|
||||||
|
|
||||||
|
curr[name] = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
// 基础服务
|
// 基础服务
|
||||||
export const service: Service = {
|
export const service: Eps.Service = {
|
||||||
request: new BaseService().request
|
request: new BaseService().request
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -13,7 +39,7 @@ export function useService() {
|
|||||||
|
|
||||||
// 模块内容
|
// 模块内容
|
||||||
module.list.forEach((e) => {
|
module.list.forEach((e) => {
|
||||||
deepMerge(service, deepFiles(e.service || []));
|
deepMerge(service, deepFiles(e.services || []));
|
||||||
});
|
});
|
||||||
|
|
||||||
return service;
|
return service;
|
||||||
|
|||||||
@ -15,22 +15,22 @@ NProgress.configure({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 请求队列
|
// 请求队列
|
||||||
let requests: Array<Function> = [];
|
let requests: Array<(token: string) => void> = [];
|
||||||
|
|
||||||
// Token 是否刷新中
|
// 是否刷新中
|
||||||
let isRefreshing = false;
|
let isRefreshing = false;
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore 避免热更新后多次执行
|
||||||
axios.interceptors.request.eject(axios._req);
|
axios.interceptors.request.eject(axios._req);
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore 请求
|
||||||
axios._req = axios.interceptors.request.use(
|
axios._req = axios.interceptors.request.use(
|
||||||
(req: any) => {
|
(req) => {
|
||||||
const { user } = useBase();
|
const { user } = useBase();
|
||||||
|
|
||||||
if (req.url) {
|
if (req.url) {
|
||||||
// 请求进度条
|
// 请求进度条
|
||||||
if (!config.ignore.NProgress.some((e: string) => req.url.includes(e))) {
|
if (!config.ignore.NProgress.some((e) => req.url?.includes(e))) {
|
||||||
NProgress.start();
|
NProgress.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,9 +46,11 @@ axios._req = axios.interceptors.request.use(
|
|||||||
// 验证 token
|
// 验证 token
|
||||||
if (user.token) {
|
if (user.token) {
|
||||||
// 请求标识
|
// 请求标识
|
||||||
|
if (req.headers) {
|
||||||
req.headers["Authorization"] = user.token;
|
req.headers["Authorization"] = user.token;
|
||||||
|
}
|
||||||
|
|
||||||
if (req.url.includes("refreshToken")) {
|
if (req.url?.includes("refreshToken")) {
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +66,7 @@ axios._req = axios.interceptors.request.use(
|
|||||||
isRefreshing = true;
|
isRefreshing = true;
|
||||||
|
|
||||||
user.refreshToken()
|
user.refreshToken()
|
||||||
.then((token: string) => {
|
.then((token) => {
|
||||||
requests.forEach((cb) => cb(token));
|
requests.forEach((cb) => cb(token));
|
||||||
requests = [];
|
requests = [];
|
||||||
isRefreshing = false;
|
isRefreshing = false;
|
||||||
@ -76,9 +78,11 @@ axios._req = axios.interceptors.request.use(
|
|||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
// 继续请求
|
// 继续请求
|
||||||
requests.push((token: string) => {
|
requests.push((token) => {
|
||||||
// 重新设置 token
|
// 重新设置 token
|
||||||
|
if (req.headers) {
|
||||||
req.headers["Authorization"] = token;
|
req.headers["Authorization"] = token;
|
||||||
|
}
|
||||||
resolve(req);
|
resolve(req);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
33
src/cool/types/index.d.ts
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { App, Component, Directive } from "vue";
|
||||||
|
import { Router as VueRouter, RouteRecordRaw } from "vue-router";
|
||||||
|
|
||||||
|
export declare interface ModuleConfig {
|
||||||
|
order?: number;
|
||||||
|
options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
components?: Component[];
|
||||||
|
views?: RouteRecordRaw[];
|
||||||
|
pages?: RouteRecordRaw[];
|
||||||
|
install?(app: App, options?: { [key: string]: any }): void;
|
||||||
|
onLoad?(events: {
|
||||||
|
hasToken: (cb: () => Promise<any> | void) => Promise<any> | void;
|
||||||
|
[key: string]: any;
|
||||||
|
}): Promise<{ [key: string]: any }> | void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare interface Module extends ModuleConfig {
|
||||||
|
name: string;
|
||||||
|
options: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
value?: any;
|
||||||
|
services?: { path: string; value: any }[];
|
||||||
|
directives?: { name: string; value: Directive }[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare interface Router extends VueRouter {
|
||||||
|
href(path: string): void;
|
||||||
|
append(data: any[] | any): void;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
import { isArray, orderBy } from "lodash";
|
import { isArray, orderBy } from "lodash";
|
||||||
import storage from "./storage";
|
import storage from "./storage";
|
||||||
import module from "./module";
|
|
||||||
|
|
||||||
// 首字母大写
|
// 首字母大写
|
||||||
export function firstUpperCase(value: string): string {
|
export function firstUpperCase(value: string): string {
|
||||||
@ -32,37 +31,35 @@ export function getUrlParam(name: string): string | null {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文件路径转对象
|
// 路径转数组
|
||||||
export function deepFiles(list: any[]) {
|
export function deepPaths(paths: string[], splitor?: string) {
|
||||||
const modules: any = {};
|
const list: any[] = [];
|
||||||
|
|
||||||
list.forEach((e) => {
|
paths.forEach((e) => {
|
||||||
const arr = e.path.split("/");
|
const arr: string[] = e.split(splitor || "/").filter(Boolean);
|
||||||
const parents = arr.slice(0, arr.length - 1);
|
|
||||||
const name = basename(e.path).replace(".ts", "");
|
|
||||||
|
|
||||||
let curr: any = modules;
|
let c = list;
|
||||||
let prev: any = null;
|
|
||||||
let key: any = null;
|
|
||||||
|
|
||||||
parents.forEach((k: string) => {
|
arr.forEach((a, i) => {
|
||||||
if (!curr[k]) {
|
let d = c.find((e) => e.label == a);
|
||||||
curr[k] = {};
|
|
||||||
|
if (!d) {
|
||||||
|
d = {
|
||||||
|
label: a,
|
||||||
|
value: a,
|
||||||
|
children: arr[i + 1] ? [] : null
|
||||||
|
};
|
||||||
|
|
||||||
|
c.push(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = curr;
|
if (d.children) {
|
||||||
curr = curr[k];
|
c = d.children;
|
||||||
key = k;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (name == "index") {
|
|
||||||
prev[key] = e.value;
|
|
||||||
} else {
|
|
||||||
curr[name] = e.value;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return modules;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文件名
|
// 文件名
|
||||||
@ -213,7 +210,7 @@ export function getBrowser() {
|
|||||||
|
|
||||||
// 列表转树形
|
// 列表转树形
|
||||||
export function deepTree(list: any[]): any[] {
|
export function deepTree(list: any[]): any[] {
|
||||||
const newList: Array<any> = [];
|
const newList: any[] = [];
|
||||||
const map: any = {};
|
const map: any = {};
|
||||||
|
|
||||||
list.forEach((e) => (map[e.id] = e));
|
list.forEach((e) => (map[e.id] = e));
|
||||||
@ -230,9 +227,8 @@ export function deepTree(list: any[]): any[] {
|
|||||||
|
|
||||||
const fn = (list: Array<any>) => {
|
const fn = (list: Array<any>) => {
|
||||||
list.map((e) => {
|
list.map((e) => {
|
||||||
if (e.children instanceof Array) {
|
if (isArray(e.children)) {
|
||||||
e.children = orderBy(e.children, "orderNum");
|
e.children = orderBy(e.children, "orderNum");
|
||||||
|
|
||||||
fn(e.children);
|
fn(e.children);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -240,15 +236,15 @@ export function deepTree(list: any[]): any[] {
|
|||||||
|
|
||||||
fn(newList);
|
fn(newList);
|
||||||
|
|
||||||
return orderBy(newList, "orderNum");
|
return orderBy(newList, "orderNum").filter((e) => !e.parentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 树形转列表
|
// 树形转列表
|
||||||
export function revDeepTree(list: Array<any> = []) {
|
export function revDeepTree(list: any[]) {
|
||||||
const d: Array<any> = [];
|
const arr: any[] = [];
|
||||||
let id = 0;
|
let id = 0;
|
||||||
|
|
||||||
const deep = (list: Array<any>, parentId: any) => {
|
function deep(list: any[], parentId: any) {
|
||||||
list.forEach((e) => {
|
list.forEach((e) => {
|
||||||
if (!e.id) {
|
if (!e.id) {
|
||||||
e.id = id++;
|
e.id = id++;
|
||||||
@ -256,17 +252,25 @@ export function revDeepTree(list: Array<any> = []) {
|
|||||||
|
|
||||||
e.parentId = parentId;
|
e.parentId = parentId;
|
||||||
|
|
||||||
d.push(e);
|
arr.push(e);
|
||||||
|
|
||||||
if (e.children && isArray(e.children)) {
|
if (e.children && isArray(e.children)) {
|
||||||
deep(e.children, e.id);
|
deep(e.children, e.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
deep(list || [], null);
|
deep(list || [], null);
|
||||||
|
|
||||||
return d;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { storage, module };
|
export function hideLoading() {
|
||||||
|
const el = document.getElementById("Loading");
|
||||||
|
|
||||||
|
if (el) {
|
||||||
|
el.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { storage };
|
||||||
|
|||||||
@ -1,31 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
|
|
||||||
interface Item {
|
|
||||||
name: string;
|
|
||||||
options: {
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
value: any;
|
|
||||||
service?: any[];
|
|
||||||
pages?: any[];
|
|
||||||
views?: any[];
|
|
||||||
components?: {
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const module = {
|
|
||||||
get list(): Item[] {
|
|
||||||
return window.__modules__ || [];
|
|
||||||
},
|
|
||||||
|
|
||||||
set(list: Item[]) {
|
|
||||||
window.__modules__ = list;
|
|
||||||
},
|
|
||||||
|
|
||||||
get(name: string) {
|
|
||||||
return name ? window.__modules__.find((e) => e.name == name) : window.__modules__;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default module;
|
|
||||||
3
src/env.d.ts
vendored
@ -1,5 +1,4 @@
|
|||||||
/// <reference types="@cool-vue/crud" />
|
/// <reference types="@cool-vue/crud" />
|
||||||
/// <reference types="../build/cool/temp/service" />
|
/// <reference types="../build/cool/temp/eps" />
|
||||||
/// <reference types="../build/cool/temp/entity" />
|
|
||||||
|
|
||||||
declare const __EPS__: string;
|
declare const __EPS__: string;
|
||||||
|
|||||||
@ -2,9 +2,6 @@ import { createApp } from "vue";
|
|||||||
import App from "./App.vue";
|
import App from "./App.vue";
|
||||||
import { bootstrap } from "./cool";
|
import { bootstrap } from "./cool";
|
||||||
|
|
||||||
// mock
|
|
||||||
// import "./mock";
|
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
// 启动
|
// 启动
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
const xhr = new window._XMLHttpRequest();
|
|
||||||
window.XMLHttpRequest.prototype.upload = xhr.upload;
|
|
||||||
@ -1,4 +1,8 @@
|
|||||||
import "./resize";
|
import { resize } from "./resize";
|
||||||
|
|
||||||
|
window.onload = function () {
|
||||||
|
resize();
|
||||||
|
};
|
||||||
|
|
||||||
export * from "./theme";
|
export * from "./theme";
|
||||||
export * from "./permission";
|
export * from "./permission";
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useStore } from "../store";
|
import { useStore } from "../store";
|
||||||
import { isArray, isObject } from "lodash";
|
import { isObject } from "lodash";
|
||||||
|
|
||||||
function parse(value: any) {
|
function parse(value: any) {
|
||||||
const { menu } = useStore();
|
const { menu } = useStore();
|
||||||
@ -11,7 +11,7 @@ function parse(value: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkPerm(value: any) {
|
export function checkPerm(value: string | { or?: string[]; and?: string[] }) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -28,15 +28,3 @@ export function checkPerm(value: any) {
|
|||||||
|
|
||||||
return parse(value);
|
return parse(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPerm(service: any, names: string[] | string) {
|
|
||||||
if (!service._permission) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isArray(names)) {
|
|
||||||
names = [names];
|
|
||||||
}
|
|
||||||
|
|
||||||
return !names.find((e) => !service._permission[e]);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { useEventListener } from "@vueuse/core";
|
import { useEventListener } from "@vueuse/core";
|
||||||
import { useStore } from "../store";
|
import { useStore } from "../store";
|
||||||
|
|
||||||
function resize() {
|
function update() {
|
||||||
const { app } = useStore();
|
const { app } = useStore();
|
||||||
app.setBrowser();
|
app.setBrowser();
|
||||||
app.isFold = app.browser.isMini;
|
app.isFold = app.browser.isMini;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = function () {
|
export function resize() {
|
||||||
useEventListener(window, "resize", resize);
|
useEventListener(window, "resize", update);
|
||||||
resize();
|
update();
|
||||||
};
|
}
|
||||||
|
|||||||
@ -13,7 +13,9 @@ if (config.app.iconfont) {
|
|||||||
createLink("//at.alicdn.com/t/font_3254019_60a2xxj8uus.css");
|
createLink("//at.alicdn.com/t/font_3254019_60a2xxj8uus.css");
|
||||||
|
|
||||||
// svg 图标加载
|
// svg 图标加载
|
||||||
const svgFiles = import.meta.globEager("/src/icons/svg/**/*.svg");
|
const svgFiles = import.meta.glob("/src/modules/*/static/**/*.svg", {
|
||||||
|
eager: true
|
||||||
|
});
|
||||||
|
|
||||||
function iconList() {
|
function iconList() {
|
||||||
const list: string[] = [];
|
const list: string[] = [];
|
||||||
|
|||||||
@ -1,142 +1,86 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="editorRef" class="cl-codemirror">
|
<div class="cl-codemirror">
|
||||||
<textarea id="editor" class="cl-code" :height="height" :width="width"></textarea>
|
<codemirror
|
||||||
|
v-model="content"
|
||||||
<div class="cl-codemirror__tools">
|
:placeholder="placeholder"
|
||||||
<el-button @click="formatCode">格式化</el-button>
|
:style="{ height, fontSize }"
|
||||||
</div>
|
autofocus
|
||||||
|
indent-with-tab
|
||||||
|
:tab-size="4"
|
||||||
|
:extensions="extensions"
|
||||||
|
@change="onChange"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" name="cl-codemirror" setup>
|
||||||
import { defineComponent, nextTick, onMounted, ref, watch } from "vue";
|
import { Codemirror } from "vue-codemirror";
|
||||||
import CodeMirror from "codemirror";
|
import { javascript } from "@codemirror/lang-javascript";
|
||||||
import beautifyJs from "js-beautify";
|
import { oneDark } from "@codemirror/theme-one-dark";
|
||||||
import "codemirror/lib/codemirror.css";
|
import { ref, watch } from "vue";
|
||||||
import "codemirror/addon/hint/show-hint.css";
|
import { useDark } from "@vueuse/core";
|
||||||
import "codemirror/theme/hopscotch.css";
|
|
||||||
import "codemirror/addon/hint/javascript-hint";
|
|
||||||
import "codemirror/mode/javascript/javascript";
|
|
||||||
import { deepMerge } from "/@/cool/utils";
|
|
||||||
|
|
||||||
export default defineComponent({
|
const props = defineProps({
|
||||||
name: "cl-codemirror",
|
modelValue: {
|
||||||
|
type: String,
|
||||||
props: {
|
required: true
|
||||||
modelValue: null,
|
|
||||||
height: String,
|
|
||||||
width: String,
|
|
||||||
options: Object
|
|
||||||
},
|
},
|
||||||
|
placeholder: {
|
||||||
emits: ["update:modelValue", "load"],
|
type: String,
|
||||||
|
default: "请输入"
|
||||||
setup(props, { emit }) {
|
},
|
||||||
const editorRef = ref<any>(null);
|
height: {
|
||||||
|
type: String,
|
||||||
let editor: any = null;
|
default: "400px"
|
||||||
|
},
|
||||||
// 获取内容
|
fontSize: {
|
||||||
function getValue() {
|
type: String,
|
||||||
if (editor) {
|
default: "14px"
|
||||||
return editor.getValue();
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modelValue", "change"]);
|
||||||
|
|
||||||
|
// 是否暗黑模式
|
||||||
|
const isDark = ref(useDark());
|
||||||
|
|
||||||
|
// 插件
|
||||||
|
const extensions: any[] = [javascript(), isDark.value && oneDark];
|
||||||
|
|
||||||
|
// 内容
|
||||||
|
const content = ref("");
|
||||||
|
|
||||||
|
// 值改变
|
||||||
|
function onChange(value: string) {
|
||||||
|
emit("update:modelValue", value);
|
||||||
|
emit("change", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置内容
|
|
||||||
function setValue(val?: string) {
|
|
||||||
if (editor) {
|
|
||||||
editor.setValue(val || "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 格式化
|
|
||||||
function formatCode() {
|
|
||||||
if (editor) {
|
|
||||||
editor.setValue(beautifyJs(getValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听内容变化
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(val: string) => {
|
(val) => {
|
||||||
if (editor && val != getValue()) {
|
content.value = val;
|
||||||
setValue(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
onMounted(function () {
|
|
||||||
nextTick(() => {
|
|
||||||
// 实例化
|
|
||||||
editor = CodeMirror.fromTextArea(
|
|
||||||
editorRef.value.querySelector("#editor"),
|
|
||||||
deepMerge(
|
|
||||||
{
|
|
||||||
mode: "javascript",
|
|
||||||
theme: "hopscotch",
|
|
||||||
styleActiveLine: true,
|
|
||||||
lineNumbers: true,
|
|
||||||
lineWrapping: true,
|
|
||||||
indentWithTabs: true,
|
|
||||||
indentUnit: 4,
|
|
||||||
extraKeys: { Ctrl: "autocomplete" },
|
|
||||||
foldGutter: true,
|
|
||||||
autofocus: true,
|
|
||||||
matchBrackets: true,
|
|
||||||
autoCloseBrackets: true,
|
|
||||||
gutters: [
|
|
||||||
"CodeMirror-linenumbers",
|
|
||||||
"CodeMirror-foldgutter",
|
|
||||||
"CodeMirror-lint-markers"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
props.options
|
{
|
||||||
)
|
immediate: true
|
||||||
);
|
|
||||||
|
|
||||||
// 输入监听
|
|
||||||
editor.on("change", (e: any) => {
|
|
||||||
emit("update:modelValue", e.getValue());
|
|
||||||
});
|
|
||||||
|
|
||||||
// 设置内容
|
|
||||||
setValue(props.modelValue);
|
|
||||||
|
|
||||||
// 格式化
|
|
||||||
formatCode();
|
|
||||||
|
|
||||||
// 加载回调
|
|
||||||
emit("load", editor);
|
|
||||||
|
|
||||||
// 设置编辑框大小
|
|
||||||
editor.setSize(props.width || "auto", props.height || "auto");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
editorRef,
|
|
||||||
formatCode
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.cl-codemirror {
|
.cl-codemirror {
|
||||||
border-radius: 3px;
|
border: 1px solid var(--el-border-color);
|
||||||
border: 1px solid #dcdfe6;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-radius: 3px;
|
|
||||||
line-height: 150%;
|
|
||||||
|
|
||||||
&__tools {
|
:deep(.cm-editor) {
|
||||||
background-color: #322931;
|
.cm-foldGutter {
|
||||||
padding: 10px;
|
width: 12px;
|
||||||
border-top: 1px solid #444;
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.cm-focused {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -4,18 +4,11 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" name="cl-svg" setup>
|
||||||
import { computed, defineComponent, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import { isNumber } from "lodash";
|
import { isNumber } from "lodash";
|
||||||
|
|
||||||
export default defineComponent({
|
const props = defineProps({
|
||||||
name: "icon-svg",
|
|
||||||
|
|
||||||
cool: {
|
|
||||||
global: true
|
|
||||||
},
|
|
||||||
|
|
||||||
props: {
|
|
||||||
name: {
|
name: {
|
||||||
type: String
|
type: String
|
||||||
},
|
},
|
||||||
@ -25,29 +18,20 @@ export default defineComponent({
|
|||||||
size: {
|
size: {
|
||||||
type: [String, Number]
|
type: [String, Number]
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
setup(props) {
|
const style = ref({
|
||||||
const style = ref<any>({
|
|
||||||
fontSize: isNumber(props.size) ? props.size + "px" : props.size
|
fontSize: isNumber(props.size) ? props.size + "px" : props.size
|
||||||
});
|
});
|
||||||
|
|
||||||
const iconName = computed<string>(() => `#icon-${props.name}`);
|
const iconName = computed(() => `#icon-${props.name}`);
|
||||||
const svgClass = computed<Array<string>>(() => {
|
const svgClass = computed(() => {
|
||||||
return ["icon-svg", `icon-svg__${props.name}`, String(props.className || "")];
|
return ["cl-svg", `cl-svg__${props.name}`, String(props.className || "")];
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
style,
|
|
||||||
iconName,
|
|
||||||
svgClass
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.icon-svg {
|
.cl-svg {
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
vertical-align: -0.15em;
|
vertical-align: -0.15em;
|
||||||
|
|||||||
@ -45,10 +45,7 @@ export default defineComponent({
|
|||||||
type: [Number, Array],
|
type: [Number, Array],
|
||||||
default: 100
|
default: 100
|
||||||
},
|
},
|
||||||
lazy: {
|
lazy: Boolean,
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
fit: {
|
fit: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "cover"
|
default: "cover"
|
||||||
|
|||||||
@ -25,21 +25,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" name="cl-view-group" setup>
|
||||||
import { defineComponent, ref, watch } from "vue";
|
import { ref, watch } from "vue";
|
||||||
import { ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
|
import { ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
|
||||||
import { useBase } from "/$/base";
|
import { useBase } from "/$/base";
|
||||||
|
|
||||||
export default defineComponent({
|
defineProps({
|
||||||
name: "cl-view-group",
|
|
||||||
components: {
|
|
||||||
ArrowLeft,
|
|
||||||
ArrowRight
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
title: String
|
title: String
|
||||||
},
|
});
|
||||||
setup() {
|
|
||||||
const { app } = useBase();
|
const { app } = useBase();
|
||||||
|
|
||||||
// 是否展开
|
// 是否展开
|
||||||
@ -68,13 +62,8 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
defineExpose({
|
||||||
isExpand,
|
checkExpand
|
||||||
toExpand,
|
|
||||||
checkExpand,
|
|
||||||
app
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -88,17 +77,18 @@ export default defineComponent({
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
background-color: var(--el-bg-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
&__left {
|
&__left {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
max-width: calc(100% - 50px);
|
max-width: calc(100% - 50px);
|
||||||
background-color: #fff;
|
|
||||||
transition: width 0.3s;
|
transition: width 0.3s;
|
||||||
margin-right: 10px;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
border-right: 1px solid var(--el-border-color);
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
&._collapse {
|
&._collapse {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
@ -117,7 +107,6 @@ export default defineComponent({
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: #fff;
|
|
||||||
|
|
||||||
span {
|
span {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@ -133,7 +122,6 @@ export default defineComponent({
|
|||||||
top: 0;
|
top: 0;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #fff;
|
|
||||||
height: 40px;
|
height: 40px;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
|
|||||||
82
src/modules/base/config.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import { ModuleConfig, config } from "/@/cool";
|
||||||
|
import { useStore } from "./store";
|
||||||
|
import "./static/css/index.scss";
|
||||||
|
|
||||||
|
export default (): ModuleConfig => {
|
||||||
|
return {
|
||||||
|
order: 99,
|
||||||
|
components: Object.values(import.meta.glob("./components/**/*")),
|
||||||
|
views: [
|
||||||
|
{
|
||||||
|
path: "/my/info",
|
||||||
|
meta: {
|
||||||
|
label: "个人中心"
|
||||||
|
},
|
||||||
|
component: () => import("./views/info.vue")
|
||||||
|
}
|
||||||
|
],
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
path: "/login",
|
||||||
|
component: () => import("./pages/login/index.vue")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/401",
|
||||||
|
meta: {
|
||||||
|
process: false
|
||||||
|
},
|
||||||
|
component: () => import("./pages/error-page/401.vue")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/403",
|
||||||
|
meta: {
|
||||||
|
process: false
|
||||||
|
},
|
||||||
|
component: () => import("./pages/error-page/403.vue")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/404",
|
||||||
|
meta: {
|
||||||
|
process: false
|
||||||
|
},
|
||||||
|
component: () => import("./pages/error-page/404.vue")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/500",
|
||||||
|
meta: {
|
||||||
|
process: false
|
||||||
|
},
|
||||||
|
component: () => import("./pages/error-page/500.vue")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/502",
|
||||||
|
meta: {
|
||||||
|
process: false
|
||||||
|
},
|
||||||
|
component: () => import("./pages/error-page/502.vue")
|
||||||
|
}
|
||||||
|
],
|
||||||
|
install() {
|
||||||
|
// 设置标题
|
||||||
|
document.title = config.app.name;
|
||||||
|
},
|
||||||
|
async onLoad() {
|
||||||
|
const { user, menu } = useStore();
|
||||||
|
|
||||||
|
if (user.token) {
|
||||||
|
// 获取用户信息
|
||||||
|
user.get();
|
||||||
|
// 获取菜单权限
|
||||||
|
await menu.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
async hasToken(cb: () => Promise<any> | void) {
|
||||||
|
if (user.token) {
|
||||||
|
if (cb) await cb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -5,7 +5,7 @@ function change(el: any, binding: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
beforeMount(el: any, binding: any) {
|
created(el: any, binding: any) {
|
||||||
el.setAttribute("_display", el.style.display || "");
|
el.setAttribute("_display", el.style.display || "");
|
||||||
change(el, binding);
|
change(el, binding);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { useStore } from "./store";
|
import { useStore } from "./store";
|
||||||
import "./static/css/index.scss";
|
|
||||||
|
|
||||||
export function useBase() {
|
export function useBase() {
|
||||||
return {
|
return {
|
||||||
@ -8,3 +7,4 @@ export function useBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export * from "./common";
|
export * from "./common";
|
||||||
|
export * from "./types/index.d";
|
||||||
|
|||||||
@ -7,20 +7,19 @@
|
|||||||
@select="select"
|
@select="select"
|
||||||
>
|
>
|
||||||
<el-menu-item v-for="(item, index) in menu.group" :key="index" :index="`${index}`">
|
<el-menu-item v-for="(item, index) in menu.group" :key="index" :index="`${index}`">
|
||||||
<icon-svg v-if="item.icon" :name="item.icon" :size="18" />
|
<cl-svg v-if="item.icon" :name="item.icon" :size="18" />
|
||||||
<span class="a-menu__name">{{ item.name }}</span>
|
<span class="a-menu__name">{{ item.name }}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" name="a-menu" setup>
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { useBase } from "/$/base";
|
import { useBase } from "/$/base";
|
||||||
import { useCool } from "/@/cool";
|
import { useCool } from "/@/cool";
|
||||||
|
|
||||||
const { router, route } = useCool();
|
const { router, route } = useCool();
|
||||||
|
|
||||||
const { menu } = useBase();
|
const { menu } = useBase();
|
||||||
|
|
||||||
// 选中标识
|
// 选中标识
|
||||||
@ -101,7 +100,7 @@ onMounted(function () {
|
|||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-svg {
|
.cl-svg {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
118
src/modules/base/layout/components/bmenu.tsx
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import { h, ref, watch } from "vue";
|
||||||
|
import { useStore } from "../../store";
|
||||||
|
import { Menu } from "../../types";
|
||||||
|
import { useCool } from "/@/cool";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "b-menu",
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
const { router, route } = useCool();
|
||||||
|
const { menu } = useStore();
|
||||||
|
|
||||||
|
// 是否可见
|
||||||
|
const visible = ref(true);
|
||||||
|
|
||||||
|
// 页面跳转
|
||||||
|
function toView(url: string) {
|
||||||
|
if (url != route.path) {
|
||||||
|
router.push(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新菜单
|
||||||
|
function refresh() {
|
||||||
|
visible.value = false;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
visible.value = true;
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听菜单变化
|
||||||
|
watch(menu.list, refresh);
|
||||||
|
|
||||||
|
return {
|
||||||
|
route,
|
||||||
|
visible,
|
||||||
|
toView,
|
||||||
|
refresh,
|
||||||
|
menu
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
render(ctx: any) {
|
||||||
|
const { app } = useStore();
|
||||||
|
|
||||||
|
// 设置子菜单
|
||||||
|
function deep(list: Menu.Item[], index: number) {
|
||||||
|
return list
|
||||||
|
.filter((e) => e.isShow)
|
||||||
|
.map((e) => {
|
||||||
|
let html = null;
|
||||||
|
|
||||||
|
if (e.type == 0) {
|
||||||
|
html = h(
|
||||||
|
<el-sub-menu></el-sub-menu>,
|
||||||
|
{
|
||||||
|
index: String(e.id),
|
||||||
|
key: e.id,
|
||||||
|
popperClass: "app-slider__menu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title() {
|
||||||
|
return (
|
||||||
|
<div class="wrap">
|
||||||
|
<cl-svg name={e.icon} />
|
||||||
|
<span v-show={!app.isFold || index != 1}>{e.name}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
default() {
|
||||||
|
return deep(e.children || [], index + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
html = h(
|
||||||
|
<el-menu-item />,
|
||||||
|
{
|
||||||
|
index: e.path,
|
||||||
|
key: e.id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default() {
|
||||||
|
return (
|
||||||
|
<div class="wrap">
|
||||||
|
<cl-svg name={e.icon} />
|
||||||
|
<span v-show={!app.isFold || index != 1}>{e.name}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const children = deep(ctx.menu.list, 1);
|
||||||
|
|
||||||
|
return (
|
||||||
|
ctx.visible && (
|
||||||
|
<div class="app-slider__menu">
|
||||||
|
<el-menu
|
||||||
|
default-active={ctx.route.path}
|
||||||
|
background-color="transparent"
|
||||||
|
collapse-transition={false}
|
||||||
|
collapse={app.browser.isMini ? false : app.isFold}
|
||||||
|
onSelect={ctx.toView}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</el-menu>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -2,7 +2,7 @@
|
|||||||
<div class="app-process">
|
<div class="app-process">
|
||||||
<div class="app-process__back" @click="router.back">
|
<div class="app-process__back" @click="router.back">
|
||||||
<el-icon :size="15"><arrow-left /></el-icon>
|
<el-icon :size="15"><arrow-left /></el-icon>
|
||||||
<span>返回</span>
|
<span>后退</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :ref="setRefs('scroller')" class="app-process__scroller">
|
<div :ref="setRefs('scroller')" class="app-process__scroller">
|
||||||
@ -16,9 +16,9 @@
|
|||||||
@click="onTap(item, Number(index))"
|
@click="onTap(item, Number(index))"
|
||||||
@contextmenu.stop.prevent="openCM($event, item)"
|
@contextmenu.stop.prevent="openCM($event, item)"
|
||||||
>
|
>
|
||||||
<span>{{ item.label }}</span>
|
<span>{{ item.meta?.label || item.name || item.path }}</span>
|
||||||
<el-icon v-if="index > 0" @mousedown.stop="onDel(Number(index))">
|
<el-icon @mousedown.stop="onDel(Number(index))">
|
||||||
<close />
|
<Close />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -32,17 +32,18 @@ import { useCool } from "/@/cool";
|
|||||||
import { ArrowLeft, Close } from "@element-plus/icons-vue";
|
import { ArrowLeft, Close } from "@element-plus/icons-vue";
|
||||||
import { ContextMenu } from "@cool-vue/crud";
|
import { ContextMenu } from "@cool-vue/crud";
|
||||||
import { useBase } from "/$/base";
|
import { useBase } from "/$/base";
|
||||||
|
import { Process } from "/$/base/types";
|
||||||
|
|
||||||
const { refs, setRefs, route, router } = useCool();
|
const { refs, setRefs, route, router } = useCool();
|
||||||
const { process } = useBase();
|
const { process } = useBase();
|
||||||
|
|
||||||
// 跳转
|
// 跳转
|
||||||
function toPath() {
|
function toPath() {
|
||||||
const active = process.list.find((e: any) => e.active);
|
const d = process.list.find((e) => e.active);
|
||||||
|
|
||||||
if (!active) {
|
if (!d) {
|
||||||
const next = last(process.list);
|
const next = last(process.list);
|
||||||
router.push(next ? next.value : "/");
|
router.push(next ? next.fullPath : "/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,9 +65,9 @@ function adScroll(index: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 选择
|
// 选择
|
||||||
function onTap(item: any, index: number) {
|
function onTap(item: Process.Item, index: number) {
|
||||||
adScroll(index);
|
adScroll(index);
|
||||||
router.push(item.value);
|
router.push(item.fullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
@ -76,14 +77,14 @@ function onDel(index: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 右键菜单
|
// 右键菜单
|
||||||
function openCM(e: any, item: any) {
|
function openCM(e: any, item: Process.Item) {
|
||||||
ContextMenu.open(e, {
|
ContextMenu.open(e, {
|
||||||
list: [
|
list: [
|
||||||
{
|
{
|
||||||
label: "关闭当前",
|
label: "关闭当前",
|
||||||
hidden: item.value !== route.path,
|
hidden: item.fullPath !== route.path,
|
||||||
callback(done) {
|
callback(done) {
|
||||||
onDel(process.list.findIndex((e: any) => e.value == item.value));
|
onDel(process.list.findIndex((e) => e.fullPath == item.fullPath));
|
||||||
done();
|
done();
|
||||||
toPath();
|
toPath();
|
||||||
}
|
}
|
||||||
@ -91,9 +92,7 @@ function openCM(e: any, item: any) {
|
|||||||
{
|
{
|
||||||
label: "关闭其他",
|
label: "关闭其他",
|
||||||
callback(done) {
|
callback(done) {
|
||||||
process.set(
|
process.set(process.list.filter((e) => e.fullPath == item.fullPath));
|
||||||
process.list.filter((e: any) => e.value == item.value || e.value == "/")
|
|
||||||
);
|
|
||||||
done();
|
done();
|
||||||
toPath();
|
toPath();
|
||||||
}
|
}
|
||||||
@ -101,7 +100,7 @@ function openCM(e: any, item: any) {
|
|||||||
{
|
{
|
||||||
label: "关闭所有",
|
label: "关闭所有",
|
||||||
callback(done) {
|
callback(done) {
|
||||||
process.set(process.list.filter((e: any) => e.value == "/"));
|
process.clear();
|
||||||
done();
|
done();
|
||||||
toPath();
|
toPath();
|
||||||
}
|
}
|
||||||
@ -113,7 +112,7 @@ function openCM(e: any, item: any) {
|
|||||||
watch(
|
watch(
|
||||||
() => route.path,
|
() => route.path,
|
||||||
function (val) {
|
function (val) {
|
||||||
adScroll(process.list.findIndex((e: any) => e.value === val) || 0);
|
adScroll(process.list.findIndex((e) => e.fullPath === val) || 0);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
@ -138,6 +137,7 @@ watch(
|
|||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
color: #000;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
79
src/modules/base/layout/components/route-nav.vue
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<div class="route-nav">
|
||||||
|
<p v-if="app.browser.isMini" class="title">
|
||||||
|
{{ lastName }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<el-breadcrumb>
|
||||||
|
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
|
||||||
|
<el-breadcrumb-item v-for="(item, index) in list" :key="index">{{
|
||||||
|
item.meta?.label || item.name
|
||||||
|
}}</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" name="route-nav" setup>
|
||||||
|
import { computed } from "vue";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { useCool } from "/@/cool";
|
||||||
|
import { useBase } from "/$/base";
|
||||||
|
|
||||||
|
const { route } = useCool();
|
||||||
|
const { app, menu } = useBase();
|
||||||
|
|
||||||
|
// 数据列表
|
||||||
|
const list = computed(() => {
|
||||||
|
function deep(item: any) {
|
||||||
|
if (route.path === "/") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.path == route.path) {
|
||||||
|
return item;
|
||||||
|
} else {
|
||||||
|
if (item.children) {
|
||||||
|
const ret = item.children.map(deep).find(Boolean);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
return [item, ret];
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _(menu.group).map(deep).filter(Boolean).flattenDeep().value();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 最后一个节点名称
|
||||||
|
const lastName = computed(() => _.last(list.value).name);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.route-nav {
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
.el-breadcrumb {
|
||||||
|
margin: 0 10px;
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 0 10px;
|
||||||
|
font-weight: normal;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
131
src/modules/base/layout/components/slider.vue
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-slider">
|
||||||
|
<div class="app-slider__logo" @click="toHome">
|
||||||
|
<img src="/logo.png" />
|
||||||
|
<span v-if="!app.isFold || app.browser.isMini">{{ app.info.name }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="app-slider__container">
|
||||||
|
<b-menu />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useBase } from "/$/base";
|
||||||
|
import BMenu from "./bmenu";
|
||||||
|
|
||||||
|
const { app } = useBase();
|
||||||
|
|
||||||
|
function toHome() {
|
||||||
|
location.href = "https://cool-js.com";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.app-slider {
|
||||||
|
height: 100%;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||||
|
background-color: #2f3447;
|
||||||
|
|
||||||
|
&__logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 80px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 26px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-family: inherit;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__container {
|
||||||
|
height: calc(100% - 80px);
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__menu {
|
||||||
|
&.el-popper {
|
||||||
|
&.is-light {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-menu {
|
||||||
|
border-right: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
&--popup {
|
||||||
|
.cl-svg,
|
||||||
|
span {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-sub-menu__title,
|
||||||
|
&-item {
|
||||||
|
&.is-active,
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--color-primary) !important;
|
||||||
|
|
||||||
|
.cl-svg,
|
||||||
|
span {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-sub-menu__title,
|
||||||
|
&-item,
|
||||||
|
&__title {
|
||||||
|
color: #eee;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cl-svg {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 12px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
margin-left: 10px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--collapse {
|
||||||
|
.wrap {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.cl-svg {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
<!-- 用户信息 -->
|
<!-- 用户信息 -->
|
||||||
<div class="app-topbar__user" v-if="user.info">
|
<div class="app-topbar__user" v-if="user.info">
|
||||||
<el-dropdown trigger="click" :hide-on-click="false" @command="onCommand">
|
<el-dropdown trigger="click" hide-on-click @command="onCommand">
|
||||||
<span class="el-dropdown-link">
|
<span class="el-dropdown-link">
|
||||||
<span class="name">{{ user.info.nickName }}</span>
|
<span class="name">{{ user.info.nickName }}</span>
|
||||||
<img class="avatar" :src="user.info.headImg" />
|
<img class="avatar" :src="user.info.headImg" />
|
||||||
@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" name="topbar" setup>
|
||||||
import { useBase } from "/$/base";
|
import { useBase } from "/$/base";
|
||||||
import { useCool } from "/@/cool";
|
import { useCool } from "/@/cool";
|
||||||
import RouteNav from "./route-nav.vue";
|
import RouteNav from "./route-nav.vue";
|
||||||
@ -117,7 +117,7 @@ function onCommand(name: string) {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
height: 45px;
|
height: 45px;
|
||||||
width: 45px;
|
min-width: 45px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-views" v-if="!app.loading">
|
<div class="app-views">
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<keep-alive :include="caches">
|
<keep-alive :include="caches">
|
||||||
<component :is="Component" />
|
<component :is="Component" />
|
||||||
@ -12,14 +12,14 @@
|
|||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import { useBase } from "/$/base";
|
import { useBase } from "/$/base";
|
||||||
|
|
||||||
const { app, process } = useBase();
|
const { process } = useBase();
|
||||||
|
|
||||||
// 缓存列表
|
// 缓存列表
|
||||||
const caches = computed(() => {
|
const caches = computed(() => {
|
||||||
return process.list
|
return process.list
|
||||||
.filter((e: any) => e.keepAlive)
|
.filter((e) => e.meta?.keepAlive)
|
||||||
.map((e: any) => {
|
.map((e) => {
|
||||||
return e.value.substring(1, e.value.length).replace(/\//g, "-");
|
return e.path.substring(1, e.path.length).replace(/\//g, "-");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -28,10 +28,10 @@ const caches = computed(() => {
|
|||||||
.app-views {
|
.app-views {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 0 10px;
|
margin: 0 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: calc(100% - 20px);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page-layout" :class="{ collapse: app.isFold }">
|
<div class="app-layout" :class="{ collapse: app.isFold }">
|
||||||
<div class="page-layout__mask" @click="app.fold(true)"></div>
|
<div class="app-layout__mask" @click="app.fold(true)"></div>
|
||||||
|
|
||||||
<div class="page-layout__left">
|
<div class="app-layout__left">
|
||||||
<slider />
|
<slider />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page-layout__right">
|
<div class="app-layout__right">
|
||||||
<topbar />
|
<topbar />
|
||||||
<process />
|
<process />
|
||||||
<views />
|
<views />
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import Topbar from "./components/topbar.vue";
|
import Topbar from "./components/topbar.vue";
|
||||||
import Slider from "./components/slider.vue";
|
import Slider from "./components/slider.vue";
|
||||||
import Process from "./components/process.vue";
|
import process from "./components/process.vue";
|
||||||
import Views from "./components/views.vue";
|
import Views from "./components/views.vue";
|
||||||
import { useBase } from "/$/base";
|
import { useBase } from "/$/base";
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ const { app } = useBase();
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.page-layout {
|
.app-layout {
|
||||||
display: flex;
|
display: flex;
|
||||||
background-color: #f7f7f7;
|
background-color: #f7f7f7;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -57,7 +57,7 @@ const { app } = useBase();
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 768px) {
|
@media only screen and (max-width: 768px) {
|
||||||
.page-layout__left {
|
.app-layout__left {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
@ -65,37 +65,37 @@ const { app } = useBase();
|
|||||||
box-shadow 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
|
box-shadow 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-layout__right {
|
.app-layout__right {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.collapse {
|
&.collapse {
|
||||||
.page-layout__left {
|
.app-layout__left {
|
||||||
transform: translateX(-100%);
|
transform: translateX(-100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-layout__mask {
|
.app-layout__mask {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: 768px) {
|
@media only screen and (min-width: 768px) {
|
||||||
.page-layout__left,
|
.app-layout__left,
|
||||||
.page-layout__right {
|
.app-layout__right {
|
||||||
transition: width 0.2s ease-in-out;
|
transition: width 0.2s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-layout__mask {
|
.app-layout__mask {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.collapse {
|
&.collapse {
|
||||||
.page-layout__left {
|
.app-layout__left {
|
||||||
width: 64px;
|
width: 64px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-layout__right {
|
.app-layout__right {
|
||||||
width: calc(100% - 64px);
|
width: calc(100% - 64px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,18 +2,6 @@
|
|||||||
<error-page :code="401" desc="认证失败,请重新登录!" />
|
<error-page :code="401" desc="认证失败,请重新登录!" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" name="401" setup>
|
||||||
import ErrorPage from "./components/error-page.vue";
|
import ErrorPage from "./components/error-page.vue";
|
||||||
|
|
||||||
export default {
|
|
||||||
cool: {
|
|
||||||
route: {
|
|
||||||
path: "/401"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
ErrorPage
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -2,18 +2,6 @@
|
|||||||
<error-page :code="403" desc="您无权访问此页面" />
|
<error-page :code="403" desc="您无权访问此页面" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" name="403" setup>
|
||||||
import ErrorPage from "./components/error-page.vue";
|
import ErrorPage from "./components/error-page.vue";
|
||||||
|
|
||||||
export default {
|
|
||||||
cool: {
|
|
||||||
route: {
|
|
||||||
path: "/403"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
ErrorPage
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -2,18 +2,6 @@
|
|||||||
<error-page :code="404" desc="找不到您要查找的页面" />
|
<error-page :code="404" desc="找不到您要查找的页面" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" name="404" setup>
|
||||||
import ErrorPage from "./components/error-page.vue";
|
import ErrorPage from "./components/error-page.vue";
|
||||||
|
|
||||||
export default {
|
|
||||||
cool: {
|
|
||||||
route: {
|
|
||||||
path: "/404"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
ErrorPage
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -2,18 +2,6 @@
|
|||||||
<error-page :code="500" desc="糟糕,出了点问题" />
|
<error-page :code="500" desc="糟糕,出了点问题" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" name="500" setup>
|
||||||
import ErrorPage from "./components/error-page.vue";
|
import ErrorPage from "./components/error-page.vue";
|
||||||
|
|
||||||
export default {
|
|
||||||
cool: {
|
|
||||||
route: {
|
|
||||||
path: "/500"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
ErrorPage
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -2,18 +2,6 @@
|
|||||||
<error-page :code="502" desc="马上回来" />
|
<error-page :code="502" desc="马上回来" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" name="502" setup>
|
||||||
import ErrorPage from "./components/error-page.vue";
|
import ErrorPage from "./components/error-page.vue";
|
||||||
|
|
||||||
export default {
|
|
||||||
cool: {
|
|
||||||
route: {
|
|
||||||
path: "/502"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
ErrorPage
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
<el-button round @click="navTo">跳转</el-button>
|
<el-button type="primary" round @click="navTo">跳转</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="link">
|
<ul class="link">
|
||||||
@ -27,23 +27,19 @@
|
|||||||
<el-button round @click="toLogin">返回登录页</el-button>
|
<el-button round @click="toLogin">返回登录页</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<p class="copyright">Copyright © cool-admin-next 2023</p>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent, ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { useCool } from "/@/cool";
|
import { useCool } from "/@/cool";
|
||||||
import { useBase } from "/$/base";
|
import { useBase } from "/$/base";
|
||||||
|
|
||||||
export default defineComponent({
|
defineProps({
|
||||||
props: {
|
|
||||||
code: Number,
|
code: Number,
|
||||||
desc: String
|
desc: String
|
||||||
},
|
});
|
||||||
|
|
||||||
setup() {
|
|
||||||
const { router } = useCool();
|
const { router } = useCool();
|
||||||
const { user, menu } = useBase();
|
const { user, menu } = useBase();
|
||||||
|
|
||||||
@ -70,20 +66,6 @@ export default defineComponent({
|
|||||||
function home() {
|
function home() {
|
||||||
router.push("/");
|
router.push("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
|
||||||
user,
|
|
||||||
menu,
|
|
||||||
url,
|
|
||||||
isLogout,
|
|
||||||
navTo,
|
|
||||||
toLogin,
|
|
||||||
reLogin,
|
|
||||||
back,
|
|
||||||
home
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -123,13 +105,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
.el-button {
|
.el-button {
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
background-color: var(--color-primary);
|
|
||||||
border-color: var(--color-primary);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0 30px;
|
padding: 0 30px;
|
||||||
letter-spacing: 1px;
|
|
||||||
height: 36px;
|
|
||||||
line-height: 36px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,105 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="route-nav">
|
|
||||||
<p v-if="app.browser.isMini" class="title">
|
|
||||||
{{ lastName }}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<template v-else>
|
|
||||||
<el-breadcrumb>
|
|
||||||
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
|
|
||||||
<el-breadcrumb-item v-for="(item, index) in list" :key="index">{{
|
|
||||||
(item.meta && item.meta.label) || item.name
|
|
||||||
}}</el-breadcrumb-item>
|
|
||||||
</el-breadcrumb>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { computed, defineComponent, ref, watch } from "vue";
|
|
||||||
import _ from "lodash";
|
|
||||||
import { useCool } from "/@/cool";
|
|
||||||
import { useBase } from "/$/base";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "route-nav",
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
const { route } = useCool();
|
|
||||||
const { app, menu } = useBase();
|
|
||||||
|
|
||||||
// 数据列表
|
|
||||||
const list = ref<any[]>([]);
|
|
||||||
|
|
||||||
// 监听路由变化
|
|
||||||
watch(
|
|
||||||
() => route,
|
|
||||||
(val: any) => {
|
|
||||||
function deep(item: any) {
|
|
||||||
if (route.path === "/") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.path == route.path) {
|
|
||||||
return item;
|
|
||||||
} else {
|
|
||||||
if (item.children) {
|
|
||||||
const ret = item.children.map(deep).find(Boolean);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
return [item, ret];
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list.value = _(menu.group).map(deep).filter(Boolean).flattenDeep().value();
|
|
||||||
|
|
||||||
if (_.isEmpty(list.value)) {
|
|
||||||
list.value.push(val);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
immediate: true,
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// 最后一个节点名称
|
|
||||||
const lastName = computed(() => _.last(list.value).name);
|
|
||||||
|
|
||||||
return {
|
|
||||||
list,
|
|
||||||
lastName,
|
|
||||||
app
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.route-nav {
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
.el-breadcrumb {
|
|
||||||
margin: 0 10px;
|
|
||||||
|
|
||||||
&__inner {
|
|
||||||
font-size: 13px;
|
|
||||||
padding: 0 10px;
|
|
||||||
font-weight: normal;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: 500;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,259 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="app-slider">
|
|
||||||
<div class="app-slider__logo" @click="toHome">
|
|
||||||
<img :src="Logo" />
|
|
||||||
<span v-if="!app.isFold || app.browser.isMini">{{ app.info.name }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="app-slider__container">
|
|
||||||
<menu-nav />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="tsx">
|
|
||||||
import { defineComponent, ref, watch, h } from "vue";
|
|
||||||
import { useBase } from "/$/base";
|
|
||||||
import { useCool } from "/@/cool";
|
|
||||||
import Logo from "/@/assets/logo.png";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "app-slider",
|
|
||||||
|
|
||||||
components: {
|
|
||||||
MenuNav: {
|
|
||||||
setup() {
|
|
||||||
const { router, route } = useCool();
|
|
||||||
const { menu } = useBase();
|
|
||||||
|
|
||||||
// 是否可见
|
|
||||||
const visible = ref<boolean>(true);
|
|
||||||
|
|
||||||
// 页面跳转
|
|
||||||
function toView(url: string) {
|
|
||||||
if (url != route.path) {
|
|
||||||
router.push(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 刷新菜单
|
|
||||||
function refresh() {
|
|
||||||
visible.value = false;
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
visible.value = true;
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听菜单变化
|
|
||||||
watch(menu.list, refresh);
|
|
||||||
|
|
||||||
return {
|
|
||||||
route,
|
|
||||||
visible,
|
|
||||||
toView,
|
|
||||||
refresh,
|
|
||||||
menu
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
render(ctx: any) {
|
|
||||||
const { app } = useBase();
|
|
||||||
|
|
||||||
function deepMenu(list: any[], index: number) {
|
|
||||||
return list
|
|
||||||
.filter((e: any) => e.isShow)
|
|
||||||
.map((e: any) => {
|
|
||||||
let html = null;
|
|
||||||
|
|
||||||
if (e.type == 0) {
|
|
||||||
html = h(
|
|
||||||
<el-sub-menu></el-sub-menu>,
|
|
||||||
{
|
|
||||||
index: String(e.id),
|
|
||||||
key: e.id,
|
|
||||||
popperClass: "app-slider__menu"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title() {
|
|
||||||
return (
|
|
||||||
<div class="wrap">
|
|
||||||
<icon-svg name={e.icon}></icon-svg>
|
|
||||||
<span v-show={!app.isFold || index != 1}>
|
|
||||||
{e.name}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
default() {
|
|
||||||
return deepMenu(e.children, index + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
html = h(
|
|
||||||
<el-menu-item></el-menu-item>,
|
|
||||||
{
|
|
||||||
index: e.path,
|
|
||||||
key: e.id
|
|
||||||
},
|
|
||||||
{
|
|
||||||
default() {
|
|
||||||
return (
|
|
||||||
<div class="wrap">
|
|
||||||
<icon-svg name={e.icon}></icon-svg>
|
|
||||||
<span v-show={!app.isFold || index != 1}>
|
|
||||||
{e.name}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return html;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const children = deepMenu(ctx.menu.list, 1);
|
|
||||||
|
|
||||||
return (
|
|
||||||
ctx.visible && (
|
|
||||||
<div class="app-slider__menu">
|
|
||||||
<el-menu
|
|
||||||
default-active={ctx.route.path}
|
|
||||||
background-color="transparent"
|
|
||||||
collapse-transition={false}
|
|
||||||
collapse={app.browser.isMini ? false : app.isFold}
|
|
||||||
onSelect={ctx.toView}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</el-menu>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
function toHome() {
|
|
||||||
location.href = "https://cool-js.com";
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
toHome,
|
|
||||||
Logo,
|
|
||||||
...useBase()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.app-slider {
|
|
||||||
height: 100%;
|
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
|
||||||
background-color: #2f3447;
|
|
||||||
|
|
||||||
&__logo {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 80px;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
img {
|
|
||||||
height: 30px;
|
|
||||||
width: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: #fff;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 26px;
|
|
||||||
margin-left: 10px;
|
|
||||||
font-family: inherit;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__container {
|
|
||||||
height: calc(100% - 80px);
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__menu {
|
|
||||||
&.el-popper {
|
|
||||||
&.is-light {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-menu {
|
|
||||||
border-right: 0;
|
|
||||||
background-color: transparent;
|
|
||||||
|
|
||||||
&--popup {
|
|
||||||
.icon-svg,
|
|
||||||
span {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-sub-menu__title,
|
|
||||||
&-item {
|
|
||||||
&.is-active,
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--color-primary) !important;
|
|
||||||
|
|
||||||
.icon-svg,
|
|
||||||
span {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-sub-menu__title,
|
|
||||||
&-item,
|
|
||||||
&__title {
|
|
||||||
color: #eee;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
height: 50px;
|
|
||||||
line-height: 50px;
|
|
||||||
|
|
||||||
.wrap {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-svg {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 12px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--collapse {
|
|
||||||
.wrap {
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.icon-svg {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -5,15 +5,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent, onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { useCool } from "/@/cool";
|
import { useCool } from "/@/cool";
|
||||||
|
|
||||||
export default defineComponent({
|
const emit = defineEmits(["update:modelValue", "change"]);
|
||||||
emits: ["update:modelValue", "change"],
|
|
||||||
|
|
||||||
setup(_, { emit }) {
|
|
||||||
const { service } = useCool();
|
const { service } = useCool();
|
||||||
|
|
||||||
// base64
|
// base64
|
||||||
@ -51,12 +49,8 @@ export default defineComponent({
|
|||||||
refresh();
|
refresh();
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
defineExpose({
|
||||||
base64,
|
|
||||||
svg,
|
|
||||||
refresh
|
refresh
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page-login">
|
<div class="page-login">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<img class="logo" :src="Logo" alt="Logo" />
|
<div class="logo">
|
||||||
|
<img src="/logo.png" alt="Logo" />
|
||||||
|
<span>{{ app.info.name }}</span>
|
||||||
|
</div>
|
||||||
<p class="desc">一款快速开发后台权限管理系统</p>
|
<p class="desc">一款快速开发后台权限管理系统</p>
|
||||||
|
|
||||||
<el-form label-position="top" class="form" :disabled="saving" size="large">
|
<el-form label-position="top" class="form" :disabled="saving" size="large">
|
||||||
@ -54,28 +57,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" name="login" setup>
|
||||||
import { defineComponent, reactive, ref } from "vue";
|
import { reactive, ref } from "vue";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { useCool } from "/@/cool";
|
import { useCool } from "/@/cool";
|
||||||
import { useBase } from "/$/base";
|
import { useBase } from "/$/base";
|
||||||
import Captcha from "./components/captcha.vue";
|
import Captcha from "./components/captcha.vue";
|
||||||
import Logo from "/@/assets/logo-text.png";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
cool: {
|
|
||||||
route: {
|
|
||||||
path: "/login"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
Captcha
|
|
||||||
},
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
const { refs, setRefs, router, service } = useCool();
|
const { refs, setRefs, router, service } = useCool();
|
||||||
const { user, menu } = useBase();
|
const { user, menu, app } = useBase();
|
||||||
|
|
||||||
// 状态1
|
// 状态1
|
||||||
const saving = ref(false);
|
const saving = ref(false);
|
||||||
@ -111,14 +101,12 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 用户信息
|
// 用户信息
|
||||||
await user.get();
|
user.get();
|
||||||
|
|
||||||
// 权限菜单
|
// 权限菜单
|
||||||
await menu.get();
|
await menu.get();
|
||||||
|
|
||||||
// 跳转地址
|
// 跳转
|
||||||
menu.getPath();
|
|
||||||
|
|
||||||
router.push("/");
|
router.push("/");
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
refs.value.captcha.refresh();
|
refs.value.captcha.refresh();
|
||||||
@ -127,23 +115,15 @@ export default defineComponent({
|
|||||||
|
|
||||||
saving.value = false;
|
saving.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
|
||||||
refs,
|
|
||||||
setRefs,
|
|
||||||
form,
|
|
||||||
saving,
|
|
||||||
toLogin,
|
|
||||||
Logo
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.page-login {
|
.page-login {
|
||||||
height: 100vh;
|
display: flex;
|
||||||
width: 100vw;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: #2f3447;
|
background-color: #2f3447;
|
||||||
|
|
||||||
@ -152,15 +132,24 @@ export default defineComponent({
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 500px;
|
|
||||||
width: 500px;
|
|
||||||
position: absolute;
|
|
||||||
left: calc(50% - 250px);
|
|
||||||
top: calc(50% - 250px);
|
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 38px;
|
||||||
|
margin-left: 10px;
|
||||||
|
letter-spacing: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.desc {
|
.desc {
|
||||||
|
|||||||
@ -1 +1,46 @@
|
|||||||
|
* {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
|
||||||
|
"微软雅黑", Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-thumb {
|
||||||
|
background-color: rgba(144, 147, 153, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--view-bg-color: #f7f7f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
&:-webkit-autofill {
|
||||||
|
box-shadow: 0 0 0px 1000px white inset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@import "./theme.scss";
|
@import "./theme.scss";
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 853 B After Width: | Height: | Size: 853 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 859 B After Width: | Height: | Size: 859 B |
|
Before Width: | Height: | Size: 763 B After Width: | Height: | Size: 763 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 675 B After Width: | Height: | Size: 675 B |
|
Before Width: | Height: | Size: 917 B After Width: | Height: | Size: 917 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 753 B After Width: | Height: | Size: 753 B |
|
Before Width: | Height: | Size: 965 B After Width: | Height: | Size: 965 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 747 B After Width: | Height: | Size: 747 B |
|
Before Width: | Height: | Size: 797 B After Width: | Height: | Size: 797 B |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 740 B After Width: | Height: | Size: 740 B |
|
Before Width: | Height: | Size: 826 B After Width: | Height: | Size: 826 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 800 B After Width: | Height: | Size: 800 B |
|
Before Width: | Height: | Size: 984 B After Width: | Height: | Size: 984 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 910 B After Width: | Height: | Size: 910 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |