调整依赖,调整目录,优化细节

This commit is contained in:
神仙都没用 2024-07-22 20:24:18 +08:00
parent a975a1d91a
commit d380613ba1
38 changed files with 1332 additions and 931 deletions

View File

@ -1 +1,3 @@
vite.config.ts packages/
dist/
node_modules/

View File

@ -1,27 +1,17 @@
/* eslint-env node */
require("@rushstack/eslint-patch/modern-module-resolution");
module.exports = { module.exports = {
root: true, root: true,
env: {
browser: true,
node: true,
es6: true
},
parser: "vue-eslint-parser",
parserOptions: {
parser: "@typescript-eslint/parser",
ecmaVersion: 2020,
sourceType: "module",
jsxPragma: "React",
ecmaFeatures: {
jsx: true,
tsx: true
}
},
extends: [ extends: [
"plugin:vue/vue3-recommended", "plugin:vue/vue3-essential",
"plugin:@typescript-eslint/recommended", "eslint:recommended",
"prettier", "@vue/eslint-config-typescript",
"plugin:prettier/recommended" "@vue/eslint-config-prettier/skip-formatting"
], ],
parserOptions: {
ecmaVersion: "latest"
},
rules: { rules: {
"@typescript-eslint/ban-ts-ignore": "off", "@typescript-eslint/ban-ts-ignore": "off",
"@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-function-return-type": "off",
@ -51,6 +41,7 @@ module.exports = {
"vue/attribute-hyphenation": "off", "vue/attribute-hyphenation": "off",
"vue/html-self-closing": "off", "vue/html-self-closing": "off",
"vue/require-default-prop": "off", "vue/require-default-prop": "off",
"vue/v-on-event-hyphenation": "off" "vue/v-on-event-hyphenation": "off",
"no-self-assign": "off"
} }
}; };

View File

@ -1,5 +1,6 @@
/// <reference types="@cool-vue/crud/index.d.ts" /> /// <reference types="@cool-vue/crud/index.d.ts" />
/// <reference types="../build/cool/eps.d.ts" /> /// <reference types="./build/cool/eps.d.ts" />
/// <reference types="vite/client" />
interface ImportMetaEnv { interface ImportMetaEnv {
readonly VITE_NAME: string; readonly VITE_NAME: string;

View File

@ -1,74 +1,72 @@
user nginx; user nginx;
worker_processes 1; worker_processes 1;
error_log /var/log/nginx/error.log warn; error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid; pid /var/run/nginx.pid;
events { events {
worker_connections 1024; worker_connections 1024;
} }
http { http {
include /etc/nginx/mime.types; include /etc/nginx/mime.types;
default_type application/octet-stream; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" ' '$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; access_log /var/log/nginx/access.log main;
sendfile on; sendfile on;
keepalive_timeout 65; keepalive_timeout 65;
upstream cool { upstream cool {
server midway:8001; server midway:8001;
} }
server { server {
listen 80; listen 80;
server_name localhost; server_name localhost;
location / { location / {
root /app; root /app;
index index.html; index index.html;
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }
location /api/ location /api/ {
{ proxy_pass http://cool/;
proxy_pass http://cool/; proxy_set_header Host $host;
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
#缓存相关配置 #缓存相关配置
#proxy_cache cache_one; #proxy_cache cache_one;
#proxy_cache_key $host$request_uri$is_args$args; #proxy_cache_key $host$request_uri$is_args$args;
#proxy_cache_valid 200 304 301 302 1h; #proxy_cache_valid 200 304 301 302 1h;
#持久化连接相关配置 #持久化连接相关配置
proxy_connect_timeout 3000s; proxy_connect_timeout 3000s;
proxy_read_timeout 86400s; proxy_read_timeout 86400s;
proxy_send_timeout 3000s; proxy_send_timeout 3000s;
#proxy_http_version 1.1; #proxy_http_version 1.1;
#proxy_set_header Upgrade $http_upgrade; #proxy_set_header Upgrade $http_upgrade;
#proxy_set_header Connection "upgrade"; #proxy_set_header Connection "upgrade";
add_header X-Cache $upstream_cache_status; add_header X-Cache $upstream_cache_status;
#expires 12h; #expires 12h;
} }
# socket需额外配置 # socket需额外配置
location /socket { location /socket {
proxy_pass http://cool/socket; proxy_pass http://cool/socket;
proxy_connect_timeout 3600s; #配置点1 proxy_connect_timeout 3600s; #配置点1
proxy_read_timeout 3600s; #配置点2,如果没效,可以考虑这个时间配置长一点 proxy_read_timeout 3600s; #配置点2,如果没效,可以考虑这个时间配置长一点
proxy_send_timeout 3600s; #配置点3 proxy_send_timeout 3600s; #配置点3
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header REMOTE-HOST $remote_addr;
#proxy_bind $remote_addr transparent; #proxy_bind $remote_addr transparent;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
rewrite /socket/(.*) /$1 break; rewrite /socket/(.*) /$1 break;
proxy_redirect off; proxy_redirect off;
} }
} }
} }

View File

@ -1,12 +1,12 @@
{ {
"name": "cool-admin", "name": "cool-admin",
"version": "7.1.1", "version": "7.1.2",
"scripts": { "scripts": {
"dev": "vite --host", "dev": "vite --host",
"build": "vite build", "build": "vite build",
"serve": "vite preview", "preview": "vite preview",
"lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"", "format": "prettier --write src/",
"lint:eslint": "eslint \"./src/**/*.{vue,ts,tsx}\" --fix" "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .eslintignore"
}, },
"dependencies": { "dependencies": {
"@cool-vue/crud": "^7.1.26", "@cool-vue/crud": "^7.1.26",
@ -14,12 +14,12 @@
"@vueuse/core": "^10.4.0", "@vueuse/core": "^10.4.0",
"@wangeditor/editor": "^5.1.23", "@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12", "@wangeditor/editor-for-vue": "^5.1.12",
"axios": "^1.6.7", "axios": "^1.7.2",
"chardet": "^2.0.0", "chardet": "^2.0.0",
"core-js": "^3.32.1", "core-js": "^3.32.1",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"echarts": "^5.4.3", "echarts": "^5.4.3",
"element-plus": "^2.7.3", "element-plus": "^2.7.7",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"marked": "^11.1.1", "marked": "^11.1.1",
@ -32,33 +32,33 @@
"store": "^2.0.12", "store": "^2.0.12",
"vue": "^3.4.15", "vue": "^3.4.15",
"vue-echarts": "^6.6.1", "vue-echarts": "^6.6.1",
"vue-router": "^4.3.2", "vue-router": "^4.4.0",
"vuedraggable": "^4.1.0", "vuedraggable": "^4.1.0",
"xlsx": "^0.18.5" "xlsx": "^0.18.5"
}, },
"devDependencies": { "devDependencies": {
"@cool-vue/vite-plugin": "^7.1.4", "@rushstack/eslint-patch": "^1.8.0",
"@cool-vue/vite-plugin": "^7.1.5",
"@types/file-saver": "^2.0.7", "@types/file-saver": "^2.0.7",
"@types/lodash-es": "^4.17.8", "@types/lodash-es": "^4.17.8",
"@types/mockjs": "^1.0.7", "@types/mockjs": "^1.0.7",
"@types/node": "^20.5.6", "@types/node": "^20.14.5",
"@types/nprogress": "^0.2.0", "@types/nprogress": "^0.2.0",
"@types/store": "^2.0.2", "@types/store": "^2.0.2",
"@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.4.1",
"@vitejs/plugin-vue": "^5.0.3", "@vitejs/plugin-vue": "^5.0.3",
"@vitejs/plugin-vue-jsx": "^3.1.0", "@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/compiler-sfc": "^3.4.15", "@vue/compiler-sfc": "^3.4.15",
"eslint": "^8.48.0", "@vue/eslint-config-prettier": "^9.0.0",
"eslint-config-prettier": "^9.0.0", "@vue/eslint-config-typescript": "^13.0.0",
"eslint-plugin-prettier": "^5.0.0", "eslint": "^8.57.0",
"eslint-plugin-vue": "^9.17.0", "eslint-plugin-vue": "^9.23.0",
"prettier": "^3.1.0", "prettier": "^3.3.3",
"rollup-plugin-visualizer": "^5.9.2", "rollup-plugin-visualizer": "^5.9.2",
"sass": "^1.66.1", "sass": "^1.53.0",
"terser": "^5.27.0", "terser": "^5.27.0",
"typescript": "^5.2.2", "typescript": "^5.4.0",
"vite": "^5.0.12", "vite": "^5.3.4",
"vite-plugin-compression": "^0.5.1" "vite-plugin-compression": "^0.5.1",
"vite-plugin-vue-devtools": "^7.3.1"
} }
} }

View File

@ -245,6 +245,7 @@
// 创建 Entity // 创建 Entity
function createEntity() { function createEntity() {
const t0 = []; const t0 = [];
const arr = [];
for (const item of list) { for (const item of list) {
if (!item.name) if (!item.name)
continue; continue;
@ -266,7 +267,10 @@
t.push(" */\n"); t.push(" */\n");
t.push(`[key: string]: any;`); t.push(`[key: string]: any;`);
t.push("}"); t.push("}");
t0.push(t); if (!arr.includes(item.name)) {
arr.push(item.name);
t0.push(t);
}
} }
return t0.map((e) => e.join("")).join("\n\n"); return t0.map((e) => e.join("")).join("\n\n");
} }
@ -364,7 +368,9 @@
t.push(` * ${a.summary || n}\n`); t.push(` * ${a.summary || n}\n`);
t.push(" */\n"); t.push(" */\n");
t.push(`${n}(data${q.length == 1 ? "?" : ""}: ${q.join("")}): Promise<${res}>;`); t.push(`${n}(data${q.length == 1 ? "?" : ""}: ${q.join("")}): Promise<${res}>;`);
permission.push(n); if (!permission.includes(n)) {
permission.push(n);
}
} }
}); });
// 权限标识 // 权限标识

View File

@ -1,6 +1,6 @@
{ {
"name": "@cool-vue/vite-plugin", "name": "@cool-vue/vite-plugin",
"version": "7.1.4", "version": "7.1.5",
"description": "cool-admin/cool-uni builder", "description": "cool-admin/cool-uni builder",
"main": "/dist/index.js", "main": "/dist/index.js",
"scripts": { "scripts": {

View File

@ -164,6 +164,7 @@ async function createDescribe({ list, service }: { list: Eps.Entity[]; service:
// 创建 Entity // 创建 Entity
function createEntity() { function createEntity() {
const t0: string[][] = []; const t0: string[][] = [];
const arr: string[] = [];
for (const item of list) { for (const item of list) {
if (!item.name) continue; if (!item.name) continue;
@ -187,7 +188,11 @@ async function createDescribe({ list, service }: { list: Eps.Entity[]; service:
t.push(" */\n"); t.push(" */\n");
t.push(`[key: string]: any;`); t.push(`[key: string]: any;`);
t.push("}"); t.push("}");
t0.push(t);
if (!arr.includes(item.name)) {
arr.push(item.name);
t0.push(t);
}
} }
return t0.map((e) => e.join("")).join("\n\n"); return t0.map((e) => e.join("")).join("\n\n");
@ -316,7 +321,9 @@ async function createDescribe({ list, service }: { list: Eps.Entity[]; service:
)}): Promise<${res}>;`, )}): Promise<${res}>;`,
); );
permission.push(n); if (!permission.includes(n)) {
permission.push(n);
}
} }
}); });

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,14 @@
import { App } from "vue"; import { type App, type Directive } from "vue";
import { isFunction, orderBy, chain } from "lodash-es"; import { assign, chain, isFunction } from "lodash-es";
import { filename } from "../utils"; import { filename } from "../utils";
import { module } from "../module"; import { module } from "../module";
import { hmr } from "../hooks"; import { hmr } from "../hooks";
// 扫描文件 // 扫描文件
const files: any = import.meta.glob( const files = import.meta.glob("/src/{modules,plugins}/*/{config.ts,service/**,directives/**}", {
"/src/{modules,plugins}/*/{config.ts,service/**,directives/**}", eager: true,
{ import: "default"
eager: true });
}
);
// 模块列表 // 模块列表
module.list = hmr.getData("modules", []); module.list = hmr.getData("modules", []);
@ -21,10 +19,10 @@ for (const i in files) {
const [, , type, name, action] = i.split("/"); const [, , type, name, action] = i.split("/");
// 文件名 // 文件名
const fname = filename(i); const n = filename(i);
// 文件内容 // 文件内容
const v = files[i]?.default; const v = files[i];
// 模块是否存在 // 模块是否存在
const m = module.get(name); const m = module.get(name);
@ -38,28 +36,24 @@ for (const i in files) {
directives: [] directives: []
}; };
switch (action) { // 配置
// 配置参数 if (action == "config.ts") {
case "config.ts": d.value = v;
d.value = v; }
break; // 服务
else if (action == "service") {
const s = new (v as any)();
// 请求服务 if (s) {
case "service": d.services?.push({
const s = new v(); path: s.namespace,
value: s
if (s) { });
d.services?.push({ }
path: s.namespace, }
value: s // 指令
}); else if (action == "directives") {
} d.directives?.push({ name: n, value: v as Directive });
break;
// 指令
case "directives":
d.directives?.push({ name: fname, value: v });
break;
} }
if (!m) { if (!m) {
@ -69,34 +63,44 @@ for (const i in files) {
// 创建 // 创建
export function createModule(app: App) { export function createModule(app: App) {
// 模块加载 const list = chain(module.list)
const list = orderBy(module.list, "order").map((e) => { .map((e) => {
const d = isFunction(e.value) ? e.value(app) : e.value; const d = isFunction(e.value) ? e.value(app) : e.value;
if (d) { if (d) {
Object.assign(e, d); assign(e, d);
}
// 安装事件
e.install?.(app, d.options);
// 注册组件
e.components?.forEach(async (c: any) => {
const v = await (isFunction(c) ? c() : c);
const n = v.default || v;
if (n.name) {
app.component(n.name, n);
} }
});
// 注册指令 if (!d.order) {
e.directives?.forEach((v: any) => { e.order = 0;
app.directive(v.name, v.value); }
});
return e; return e;
}); })
.orderBy("order", "desc")
.map((e) => {
// 初始化
e.install?.(app, e.options);
// 注册组件
e.components?.forEach(async (c) => {
// @ts-ignore
const v = await (isFunction(c) ? c() : c);
const n = v.default || v;
if (n.name) {
app.component(n.name, n);
}
});
// 注册指令
e.directives?.forEach((v) => {
app.directive(v.name, v.value);
});
return e;
})
.value();
return { return {
// 模块列表 // 模块列表
@ -107,7 +111,7 @@ export function createModule(app: App) {
for (let i = 0; i < list.length; i++) { for (let i = 0; i < list.length; i++) {
if (list[i].onLoad) { if (list[i].onLoad) {
Object.assign(events, await list[i]?.onLoad?.(events)); assign(events, await list[i]?.onLoad?.(events));
} }
} }
} }

View File

@ -140,9 +140,6 @@ export function getBrowser() {
// 是否 ios // 是否 ios
const isIOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); const isIOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
// 浏览器版本
const version = (ua.match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1];
// 是否 PC 端 // 是否 PC 端
const isPC = tag === "pc"; const isPC = tag === "pc";
@ -155,7 +152,6 @@ export function getBrowser() {
return { return {
height: clientHeight, height: clientHeight,
width: clientWidth, width: clientWidth,
version,
type, type,
plat, plat,
tag, tag,

View File

@ -5,7 +5,10 @@ export const Loading = {
async set(list: Promise<any>[]) { async set(list: Promise<any>[]) {
try { try {
await Promise.all(list); await Promise.all(list);
} catch (e) {} } catch (e) {
console.error("[Loading] Error: ", e);
}
if (this.resolve) { if (this.resolve) {
this.resolve(); this.resolve();
} }

View File

@ -1,6 +1,11 @@
<template v-if="text"> <template v-if="text">
<div class="cl-code-json__wrap" v-if="popover"> <div class="cl-code-json__wrap" v-if="popover">
<el-popover width="auto" placement="right" popper-class="cl-code-json__popper"> <el-popover
width="auto"
placement="right"
popper-class="cl-code-json__popper"
effect="dark"
>
<template #reference> <template #reference>
<span class="text">{{ text }}</span> <span class="text">{{ text }}</span>
</template> </template>
@ -87,10 +92,10 @@ const viewer = defineComponent({
<style lang="scss"> <style lang="scss">
.cl-code-json { .cl-code-json {
background-color: var(--el-fill-color-lighter);
border-radius: 6px; border-radius: 6px;
position: relative; position: relative;
min-width: 200px; min-width: 200px;
max-width: 500px;
.op { .op {
position: absolute; position: absolute;
@ -123,7 +128,7 @@ const viewer = defineComponent({
} }
&__popper { &__popper {
padding: 5px !important; padding: 0 !important;
} }
} }
</style> </style>

View File

@ -1,9 +1,6 @@
import VueECharts from "vue-echarts"; import type { ModuleConfig } from "/@/cool";
import ElementPlus from "element-plus";
import { useStore } from "./store"; import { useStore } from "./store";
import { config } from "/@/config"; import { config } from "/@/config";
import type { ModuleConfig } from "/@/cool";
import "element-plus/theme-chalk/src/index.scss";
import "./static/css/index.scss"; import "./static/css/index.scss";
export default (): ModuleConfig => { export default (): ModuleConfig => {
@ -60,13 +57,7 @@ export default (): ModuleConfig => {
component: () => import("./pages/error/502.vue") component: () => import("./pages/error/502.vue")
} }
], ],
install(app) { install() {
// element-plus
app.use(ElementPlus);
// charts
app.component("v-chart", VueECharts);
// 设置标题 // 设置标题
document.title = config.app.name; document.title = config.app.name;
}, },

View File

@ -1,4 +1,4 @@
import { defineComponent, h } from "vue"; import { defineComponent, h, VNode } from "vue";
import { useBase, Menu } from "/$/base"; import { useBase, Menu } from "/$/base";
import { useCool } from "/@/cool"; import { useCool } from "/@/cool";
@ -27,8 +27,6 @@ export default defineComponent({
return list return list
.filter((e) => e.isShow) .filter((e) => e.isShow)
.map((e) => { .map((e) => {
let html = null;
const item = (e: Menu.Item) => { const item = (e: Menu.Item) => {
return ( return (
<div class="wrap"> <div class="wrap">
@ -39,7 +37,7 @@ export default defineComponent({
}; };
if (e.type == 0) { if (e.type == 0) {
html = h( return h(
<el-sub-menu />, <el-sub-menu />,
{ {
index: String(e.id), index: String(e.id),
@ -56,7 +54,7 @@ export default defineComponent({
} }
); );
} else { } else {
html = h( return h(
<el-menu-item />, <el-menu-item />,
{ {
index: index:
@ -75,7 +73,6 @@ export default defineComponent({
); );
} }
return html;
}); });
} }

View File

@ -144,7 +144,7 @@ watch(
onMounted(() => { onMounted(() => {
// //
refs.scroller.wrapRef.addEventListener("wheel", function (event: WheelEvent) { refs.scroller.wrapRef?.addEventListener("wheel", function (event: WheelEvent) {
// //
event.preventDefault(); event.preventDefault();

View File

@ -23,5 +23,4 @@ input {
} }
} }
@import "./theme.scss";
@import "./animation.scss"; @import "./animation.scss";

View File

@ -71,8 +71,9 @@
and: [service.base.sys.menu.permission.add, scope.row.type != 2] and: [service.base.sys.menu.permission.add, scope.row.type != 2]
}" }"
@click="append(scope.row)" @click="append(scope.row)"
>新增</el-button
> >
新增
</el-button>
</template> </template>
</cl-table> </cl-table>
</cl-row> </cl-row>
@ -209,7 +210,7 @@ const Table = useTable({
prop: "updateTime", prop: "updateTime",
label: "更新时间", label: "更新时间",
sortable: "custom", sortable: "custom",
width: 160 width: 170
}, },
{ {
label: "操作", label: "操作",

View File

@ -899,7 +899,7 @@ const desc = reactive({
const val = desc.list[n]; const val = desc.list[n];
if (val) { if (val) {
function next2(n2: number) { const next2 = (n2: number) => {
const v = val[n2]; const v = val[n2];
if (v) { if (v) {
@ -921,7 +921,7 @@ const desc = reactive({
} }
}, 1500); }, 1500);
} }
} };
next2(0); next2(0);
} else { } else {

View File

@ -127,7 +127,7 @@ const tab = reactive({
if (val == "shop") { if (val == "shop") {
nextTick(() => { nextTick(() => {
tab.active = "installed"; tab.active = "installed";
window.open("https://cool-js.com/"); window.open("https://cool-js.com/plugin");
}); });
} }
} }

View File

@ -88,7 +88,7 @@ const tab = reactive({
if (val == "shop") { if (val == "shop") {
nextTick(() => { nextTick(() => {
tab.active = "installed"; tab.active = "installed";
window.open("https://cool-js.com/"); window.open("https://cool-js.com/plugin");
}); });
} }
} }

View File

@ -152,12 +152,12 @@ const Table = useTable({
type: "selection", type: "selection",
width: 60, width: 60,
reserveSelection: true reserveSelection: true
} }
: { : {
label: "操作", label: "操作",
prop: "check", prop: "check",
width: 100 width: 100
}, },
{ {
prop: "avatarUrl", prop: "avatarUrl",
label: "头像", label: "头像",

View File

@ -52,7 +52,7 @@ export default defineComponent({
const ids: any[] = []; const ids: any[] = [];
// 获取所有的值 // 获取所有的值
function deep(arr: Dict.Item[], f: boolean) { const deep = (arr: Dict.Item[], f: boolean) => {
arr.forEach((e) => { arr.forEach((e) => {
const f2 = e[props.valueKey] == val; const f2 = e[props.valueKey] == val;

View File

@ -10,6 +10,7 @@ import "@cool-vue/crud/dist/index.css";
export default (): Merge<ModuleConfig, CrudOptions> => { export default (): Merge<ModuleConfig, CrudOptions> => {
return { return {
order: 100,
label: "CRUD", label: "CRUD",
description: "快速增删改查及一系列辅助组件", description: "快速增删改查及一系列辅助组件",
author: "COOL", author: "COOL",

View File

@ -0,0 +1,16 @@
import type { ModuleConfig } from "/@/cool";
import VueECharts from "vue-echarts";
export default (): ModuleConfig => {
return {
order: 100,
label: "ECharts 图表",
description: "echarts、vue-echarts 配置",
author: "COOL",
version: "1.0.0",
updateTime: "2024-07-22",
install(app) {
app.component("v-chart", VueECharts);
}
};
};

View File

@ -44,7 +44,9 @@ export function useFormat() {
singleQuote: true, singleQuote: true,
trailingComma: "none" trailingComma: "none"
}); });
} catch (err) {} } catch (err) {
// ...
}
return [ return [
{ {

View File

@ -0,0 +1,17 @@
import type { ModuleConfig } from "/@/cool";
import ElementPlus from "element-plus";
import "./css/index.scss";
export default (): ModuleConfig => {
return {
order: 100,
label: "Element Ui",
description: "Element Plus 变量、样式配置",
author: "COOL",
version: "1.0.0",
updateTime: "2024-07-22",
install(app) {
app.use(ElementPlus);
}
};
};

View File

@ -1,3 +1,9 @@
@forward "element-plus/theme-chalk/src/common/var.scss" with (
$scrollbar: ()
);
@use "element-plus/theme-chalk/src/index.scss" as *;
// Element-plus // Element-plus
.el-input-number { .el-input-number {
&__decrease, &__decrease,

View File

@ -122,6 +122,7 @@ import { reactive, type PropType, computed } from "vue";
import * as XLSX from "xlsx"; import * as XLSX from "xlsx";
import chardet from "chardet"; import chardet from "chardet";
import { extname } from "/@/cool/utils"; import { extname } from "/@/cool/utils";
import { has } from "lodash-es";
const props = defineProps({ const props = defineProps({
onConfig: Function, onConfig: Function,
@ -286,7 +287,7 @@ function onUpload(raw: File, _: any, { next }: any) {
let json: any[] = []; let json: any[] = [];
for (const sheet in workbook.Sheets) { for (const sheet in workbook.Sheets) {
if (workbook.Sheets.hasOwnProperty(sheet)) { if (has(workbook.Sheets, sheet)) {
json = json.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet])); json = json.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
} }
} }

View File

@ -1,12 +1,17 @@
import { setTheme } from "./utils"; import { setTheme } from "./utils";
import { config } from "/@/config"; import { config } from "/@/config";
import { storage, type ModuleConfig } from "/@/cool"; import { storage, type ModuleConfig } from "/@/cool";
import "element-plus/theme-chalk/dark/css-vars.css"; import "element-plus/theme-chalk/dark/css-vars.css";
import "./static/css/index.scss"; import "./static/css/index.scss";
export default (): ModuleConfig => { export default (): ModuleConfig => {
return { return {
label: "主题",
description: "自定义主色、菜单分组、暗黑模式",
author: "COOL",
version: "1.0.0",
updateTime: "2024-07-22",
toolbar: { toolbar: {
component: import("./components/theme.vue") component: import("./components/theme.vue")
}, },

View File

@ -49,7 +49,7 @@
<div <div
class="cl-upload-item__progress" class="cl-upload-item__progress"
:class="{ :class="{
'is-show': item.progress >= 0 && item.progress < 100, 'is-show': item.progress! >= 0 && item.progress! < 100,
'is-hide': item.progress == 100 'is-hide': item.progress == 100
}" }"
> >

View File

@ -12,168 +12,156 @@ export function useUpload() {
const { user } = useBase(); const { user } = useBase();
// 上传 // 上传
async function toUpload( async function toUpload(file: File, opts: Upload.Options = {}): Upload.Respose {
file: File, return new Promise((resolve, reject) => {
opts: Upload.Options = {} const executor = async () => {
): Promise<{ // 合并配置
key: string; const { prefixPath, onProgress } = merge(options, opts);
url: string;
fileId: string;
}> {
return new Promise(async (resolve, reject) => {
// 合并配置
const { prefixPath, onProgress } = merge(options, opts);
// 文件id // 文件id
const fileId = uuid(""); const fileId = uuid("");
try { try {
// 上传模式、类型 // 上传模式、类型
const { mode, type } = await service.base.comm.uploadMode(); const { mode, type } = await service.base.comm.uploadMode();
// 本地上传 // 本地上传
const isLocal = mode == "local"; const isLocal = mode == "local";
// 文件名 // 文件名
const fileName = fileId + "_" + file.name; const fileName = fileId + "_" + file.name;
// Key // Key
let key = isLocal ? fileName : pathJoin(prefixPath!, fileName); let key = isLocal ? fileName : pathJoin(prefixPath!, fileName);
// 多种上传请求 // 多种上传请求
// 上传到云端 const next = async ({ host, preview, data }: Upload.Request) => {
async function next({ const fd = new FormData();
host,
preview,
data
}: {
host: string;
preview?: string;
data?: any;
}) {
const fd = new FormData();
// key // key
fd.append("key", key); fd.append("key", key);
// 签名数据 // 签名数据
for (const i in data) { for (const i in data) {
if (!fd.has(i)) { if (!fd.has(i)) {
fd.append(i, data[i]); fd.append(i, data[i]);
}
} }
}
// 文件 // 文件
fd.append("file", file); fd.append("file", file);
// 上传进度 // 上传进度
let progress = 0; let progress = 0;
// 上传 // 上传
await service await service
.request({ .request({
url: host, url: host,
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "multipart/form-data", "Content-Type": "multipart/form-data",
Authorization: isLocal ? user.token : null Authorization: isLocal ? user.token : null
}, },
timeout: 600000, timeout: 600000,
data: fd, data: fd,
onUploadProgress(e: AxiosProgressEvent) { onUploadProgress(e: AxiosProgressEvent) {
progress = e.total ? Math.floor((e.loaded / e.total) * 100) : 0; progress = e.total ? Math.floor((e.loaded / e.total) * 100) : 0;
onProgress?.(progress); onProgress?.(progress);
}, },
proxy: isLocal, proxy: isLocal,
NProgress: false NProgress: false
}) })
.then((res) => { .then((res) => {
if (progress != 100) { if (progress != 100) {
onProgress?.(100); onProgress?.(100);
} }
key = encodeURIComponent(key); key = encodeURIComponent(key);
let url = ""; let url = "";
if (isLocal) { if (isLocal) {
url = res; url = res;
} else { } else {
url = pathJoin(preview || host, key); url = pathJoin(preview || host, key);
} }
resolve({ resolve({
key, key,
url, url,
fileId fileId
});
})
.catch((err) => {
ElMessage.error(err.message);
reject(err);
}); });
}) };
.catch((err) => {
ElMessage.error(err.message);
reject(err);
});
}
if (isLocal) { if (isLocal) {
next({ next({
host: "/admin/base/comm/upload" host: "/admin/base/comm/upload"
}); });
} else { } else {
service.base.comm service.base.comm
.upload( .upload(
type == "aws" type == "aws"
? { ? {
key key
}
: {}
)
.then((res) => {
switch (type) {
// 腾讯
case "cos":
next({
host: res.url,
data: res.credentials
});
break;
// 阿里
case "oss":
next({
host: res.host,
preview: res.publicDomain,
data: {
OSSAccessKeyId: res.OSSAccessKeyId,
policy: res.policy,
signature: res.signature
} }
}); : {}
break; )
// 七牛 .then((res) => {
case "qiniu": switch (type) {
next({ // 腾讯
host: res.uploadUrl, case "cos":
preview: res.publicDomain, next({
data: { host: res.url,
token: res.token data: res.credentials
} });
}); break;
break; // 阿里
// aws case "oss":
case "aws": next({
next({ host: res.host,
host: res.url, preview: res.publicDomain,
data: res.fields data: {
}); OSSAccessKeyId: res.OSSAccessKeyId,
break; policy: res.policy,
} signature: res.signature
}) }
.catch(reject); });
break;
// 七牛
case "qiniu":
next({
host: res.uploadUrl,
preview: res.publicDomain,
data: {
token: res.token
}
});
break;
// aws
case "aws":
next({
host: res.url,
data: res.fields
});
break;
}
})
.catch(reject);
}
} catch (err) {
ElMessage.error("文件上传失败");
console.error("[upload]", err);
reject(err);
} }
} catch (err) { };
ElMessage.error("文件上传失败");
console.error("[upload]", err); executor();
reject(err);
}
}); });
} }

View File

@ -8,8 +8,8 @@ export declare namespace Upload {
interface Item { interface Item {
url?: string; url?: string;
uid: string; uid?: string;
progress: number; progress?: number;
preload?: string; preload?: string;
error?: string; error?: string;
isPlay?: boolean; isPlay?: boolean;
@ -21,4 +21,16 @@ export declare namespace Upload {
onProgress?(progress: number): void; onProgress?(progress: number): void;
[key: string]: any; [key: string]: any;
} }
type Respose = Promise<{
key: string;
url: string;
fileId: string;
}>;
interface Request {
host: string;
preview?: string;
data?: any;
}
} }

View File

@ -1,27 +1,27 @@
import path from "path"; import { fileURLToPath, URL } from "node:url";
import { ConfigEnv, UserConfig } from "vite"; import { ConfigEnv, UserConfig } from "vite";
import vue from "@vitejs/plugin-vue"; import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx"; import vueJsx from "@vitejs/plugin-vue-jsx";
import vueDevTools from "vite-plugin-vue-devtools";
import compression from "vite-plugin-compression"; import compression from "vite-plugin-compression";
import { visualizer } from "rollup-plugin-visualizer"; import { visualizer } from "rollup-plugin-visualizer";
import { proxy } from "./src/config/proxy"; import { proxy } from "./src/config/proxy";
import { cool } from "@cool-vue/vite-plugin"; import { cool } from "@cool-vue/vite-plugin";
function resolve(dir: string) { function toPath(dir: string) {
return path.resolve(__dirname, ".", dir); return fileURLToPath(new URL(dir, import.meta.url));
}
function isDev(mode: string | undefined): boolean {
return mode === "development";
} }
// https://vitejs.dev/config // https://vitejs.dev/config
export default ({ mode }: ConfigEnv): UserConfig => { export default ({ mode }: ConfigEnv): UserConfig => {
const isDev = mode === "development";
return { return {
plugins: [ plugins: [
vue(), vue(),
compression(), compression(),
vueJsx(), vueJsx(),
// vueDevTools(),
cool({ cool({
type: "admin", type: "admin",
proxy proxy
@ -49,14 +49,14 @@ export default ({ mode }: ConfigEnv): UserConfig => {
}, },
resolve: { resolve: {
alias: { alias: {
"/@": resolve("src"), "/@": toPath("./src"),
"/$": resolve("src/modules"), "/$": toPath("./src/modules"),
"/#": resolve("src/plugins"), "/#": toPath("./src/plugins"),
"/~": resolve("packages") "/~": toPath("./packages")
} }
}, },
esbuild: { esbuild: {
drop: isDev(mode) ? [] : ["console", "debugger"] drop: isDev ? [] : ["console", "debugger"]
}, },
build: { build: {
@ -67,7 +67,7 @@ export default ({ mode }: ConfigEnv): UserConfig => {
// drop_debugger: true // drop_debugger: true
// } // }
// }, // },
sourcemap: isDev(mode), sourcemap: isDev,
rollupOptions: { rollupOptions: {
output: { output: {
chunkFileNames: "static/js/[name]-[hash].js", chunkFileNames: "static/js/[name]-[hash].js",