mirror of
https://gitee.com/JavaLionLi/plus-ui.git
synced 2026-09-14 16:17:31 +08:00
Compare commits
14 Commits
6.X-Vue
...
v5.6.0-v2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6bc3c618fe | ||
|
|
0076f5f6f7 | ||
|
|
ef5ea98a03 | ||
|
|
73f2374c72 | ||
|
|
9dcb392220 | ||
|
|
54636ac14f | ||
|
|
51a852caea | ||
|
|
5c9c940588 | ||
|
|
dfd1dc29d1 | ||
|
|
b411505b19 | ||
|
|
52ea8895d6 | ||
|
|
1b46739799 | ||
|
|
b000788785 | ||
|
|
2dc094c1db |
@ -1,7 +1,7 @@
|
|||||||
## 平台简介
|
## 平台简介
|
||||||
|
|
||||||
- 本仓库为前端技术栈 [Vue3](https://v3.cn.vuejs.org) + [TS](https://www.typescriptlang.org/) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 版本。
|
- 本仓库为前端技术栈 [Vue3](https://v3.cn.vuejs.org) + [TS](https://www.typescriptlang.org/) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 版本。
|
||||||
- 成员项目: 基于 vben5(ant-design-vue) 的前端项目 [ruoyi-plus-vben5](https://gitee.com/dapppp/ruoyi-plus-vben5)
|
- 成员项目: 基于 vben5(ant-design-vue) 的前端项目 [ruoyi-plus-vben5](https://github.com/imdap/ruoyi-plus-vben5)
|
||||||
- 成员项目: 基于soybean 的前端项目 [ruoyi-plus-soybean](https://gitee.com/xlsea/ruoyi-plus-soybean)
|
- 成员项目: 基于soybean 的前端项目 [ruoyi-plus-soybean](https://gitee.com/xlsea/ruoyi-plus-soybean)
|
||||||
|
|
||||||
## 配套后端代码仓库地址
|
## 配套后端代码仓库地址
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package",
|
"$schema": "https://json.schemastore.org/package",
|
||||||
"name": "ruoyi-vue-plus",
|
"name": "ruoyi-vue-plus",
|
||||||
"version": "5.5.3-2.5.3",
|
"version": "5.6.0-2.6.0",
|
||||||
"description": "RuoYi-Vue-Plus多租户管理系统",
|
"description": "RuoYi-Vue-Plus多租户管理系统",
|
||||||
"author": "LionLi",
|
"author": "LionLi",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -74,7 +74,6 @@
|
|||||||
"unplugin-vue-components": "31.0.0",
|
"unplugin-vue-components": "31.0.0",
|
||||||
"unplugin-vue-setup-extend-plus": "1.0.1",
|
"unplugin-vue-setup-extend-plus": "1.0.1",
|
||||||
"vite": "7.3.1",
|
"vite": "7.3.1",
|
||||||
"vite-plugin-compression": "0.5.1",
|
|
||||||
"vite-plugin-svg-icons-ng": "^1.5.2",
|
"vite-plugin-svg-icons-ng": "^1.5.2",
|
||||||
"vite-plugin-vue-devtools": "8.0.7",
|
"vite-plugin-vue-devtools": "8.0.7",
|
||||||
"vitest": "4.0.18",
|
"vitest": "4.0.18",
|
||||||
|
|||||||
@ -33,7 +33,7 @@
|
|||||||
* 部署方式 Docker 容器编排 一键部署业务集群<br />
|
* 部署方式 Docker 容器编排 一键部署业务集群<br />
|
||||||
* 国际化 SpringMessage Spring标准国际化方案<br />
|
* 国际化 SpringMessage Spring标准国际化方案<br />
|
||||||
</p>
|
</p>
|
||||||
<p><b>当前版本:</b> <span>v5.5.3</span></p>
|
<p><b>当前版本:</b> <span>v5.6.0</span></p>
|
||||||
<p>
|
<p>
|
||||||
<el-tag type="danger">¥免费开源</el-tag>
|
<el-tag type="danger">¥免费开源</el-tag>
|
||||||
</p>
|
</p>
|
||||||
@ -77,7 +77,7 @@
|
|||||||
* 分布式监控 Prometheus、Grafana 全方位性能监控<br />
|
* 分布式监控 Prometheus、Grafana 全方位性能监控<br />
|
||||||
* 其余与 Vue 版本一致<br />
|
* 其余与 Vue 版本一致<br />
|
||||||
</p>
|
</p>
|
||||||
<p><b>当前版本:</b> <span>v2.5.3</span></p>
|
<p><b>当前版本:</b> <span>v2.6.0</span></p>
|
||||||
<p>
|
<p>
|
||||||
<el-tag type="danger">¥免费开源</el-tag>
|
<el-tag type="danger">¥免费开源</el-tag>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -42,19 +42,19 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" icon="Plus" @click="handleAdd()">添加</el-button>
|
<el-button v-hasPermi="['workflow:definition:add']" type="primary" icon="Plus" @click="handleAdd()">添加</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="success" icon="Edit" :disabled="single" @click="handleUpdate()">修改</el-button>
|
<el-button v-hasPermi="['workflow:definition:edit']" type="success" icon="Edit" :disabled="single" @click="handleUpdate()">修改</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="danger" icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
|
<el-button v-hasPermi="['workflow:definition:remove']" type="danger" icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" icon="UploadFilled" @click="uploadDialog.visible = true">部署流程文件</el-button>
|
<el-button v-hasPermi="['workflow:definition:import']" type="primary" icon="UploadFilled" @click="uploadDialog.visible = true">部署流程文件</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="warning" icon="Download" :disabled="single" @click="handleExportDef">导出</el-button>
|
<el-button v-hasPermi="['workflow:definition:export']" type="warning" icon="Download" :disabled="single" @click="handleExportDef">导出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar v-model:show-search="showSearch" @query-table="handleQuery"></right-toolbar>
|
<right-toolbar v-model:show-search="showSearch" @query-table="handleQuery"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -74,6 +74,7 @@
|
|||||||
<el-table-column align="center" prop="activityStatus" label="激活状态" width="130">
|
<el-table-column align="center" prop="activityStatus" label="激活状态" width="130">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-switch
|
<el-switch
|
||||||
|
v-hasPermi="['workflow:definition:active']"
|
||||||
v-model="scope.row.activityStatus"
|
v-model="scope.row.activityStatus"
|
||||||
:active-value="1"
|
:active-value="1"
|
||||||
:inactive-value="0"
|
:inactive-value="0"
|
||||||
@ -92,21 +93,21 @@
|
|||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button link type="primary" size="small" icon="Delete" @click="handleDelete(scope.row)">删除流程</el-button>
|
<el-button v-hasPermi="['workflow:definition:remove']" link type="primary" size="small" icon="Delete" @click="handleDelete(scope.row)">删除流程</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button link type="primary" size="small" icon="CopyDocument" @click="handleCopyDef(scope.row)">复制流程</el-button>
|
<el-button v-hasPermi="['workflow:definition:copy']" link type="primary" size="small" icon="CopyDocument" @click="handleCopyDef(scope.row)">复制流程</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button link type="primary" v-if="scope.row.isPublish === 0" icon="Pointer" size="small" @click="design(scope.row)"
|
<el-button v-hasPermi="['workflow:definition:query']" link type="primary" v-if="scope.row.isPublish === 0" icon="Pointer" size="small" @click="design(scope.row)"
|
||||||
>流程设计</el-button
|
>流程设计</el-button
|
||||||
>
|
>
|
||||||
<el-button link type="primary" v-else icon="View" size="small" @click="designView(scope.row)">查看流程</el-button>
|
<el-button v-hasPermi="['workflow:definition:query']" link type="primary" v-else icon="View" size="small" @click="designView(scope.row)">查看流程</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-if="scope.row.isPublish !== 1" :span="1.5">
|
<el-col v-if="scope.row.isPublish !== 1" :span="1.5">
|
||||||
<el-button link type="primary" size="small" icon="CircleCheck" @click="handlePublish(scope.row)">发布流程</el-button>
|
<el-button v-hasPermi="['workflow:definition:publish']" link type="primary" size="small" icon="CircleCheck" @click="handlePublish(scope.row)">发布流程</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -50,7 +50,7 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
<el-button v-hasPermi="['workflow:instance:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar v-model:show-search="showSearch" @query-table="handleQuery"></right-toolbar>
|
<right-toolbar v-model:show-search="showSearch" @query-table="handleQuery"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -75,7 +75,7 @@
|
|||||||
<el-table-column align="center" prop="version" label="版本号" width="90">
|
<el-table-column align="center" prop="version" label="版本号" width="90">
|
||||||
<template #default="scope"> v{{ scope.row.version }}.0</template>
|
<template #default="scope"> v{{ scope.row.version }}.0</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column v-if="tab === 'running'" align="center" prop="isSuspended" label="状态" min-width="70">
|
<el-table-column v-if="tab === 'running'" v-hasPermi="['workflow:instance:active']" align="center" prop="isSuspended" label="状态" min-width="70">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-if="!scope.row.isSuspended" type="success">激活</el-tag>
|
<el-tag v-if="!scope.row.isSuspended" type="success">激活</el-tag>
|
||||||
<el-tag v-else type="danger">挂起</el-tag>
|
<el-tag v-else type="danger">挂起</el-tag>
|
||||||
@ -104,15 +104,15 @@
|
|||||||
</el-popover>
|
</el-popover>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="danger" size="small" icon="Delete" @click="handleDelete(scope.row)">删除 </el-button>
|
<el-button v-hasPermi="['workflow:instance:remove']" type="danger" size="small" icon="Delete" @click="handleDelete(scope.row)">删除 </el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" size="small" icon="View" @click="handleView(scope.row)">查看</el-button>
|
<el-button v-hasPermi="['workflow:instance:query']" type="primary" size="small" icon="View" @click="handleView(scope.row)">查看</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" size="small" icon="Document" @click="handleInstanceVariable(scope.row)"> 变量 </el-button>
|
<el-button v-hasPermi="['workflow:instance:variableQuery']" type="primary" size="small" icon="Document" @click="handleInstanceVariable(scope.row)"> 变量 </el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
@ -138,7 +138,7 @@
|
|||||||
<el-table-column align="center" prop="version" label="版本号" width="90">
|
<el-table-column align="center" prop="version" label="版本号" width="90">
|
||||||
<template #default="scope"> v{{ scope.row.version }}.0</template>
|
<template #default="scope"> v{{ scope.row.version }}.0</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" prop="suspensionState" label="状态" min-width="70">
|
<el-table-column v-hasPermi="['workflow:instance:active']" align="center" prop="suspensionState" label="状态" min-width="70">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-if="scope.row.suspensionState == 1" type="success">激活</el-tag>
|
<el-tag v-if="scope.row.suspensionState == 1" type="success">激活</el-tag>
|
||||||
<el-tag v-else type="danger">挂起</el-tag>
|
<el-tag v-else type="danger">挂起</el-tag>
|
||||||
@ -170,7 +170,7 @@
|
|||||||
<el-input v-model="form.value" placeholder="请输入变量值" />
|
<el-input v-model="form.value" placeholder="请输入变量值" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="handleVariable(ruleFormRef)">确认</el-button>
|
<el-button v-hasPermi="['workflow:instance:variable']" type="primary" @click="handleVariable(ruleFormRef)">确认</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|||||||
@ -1,28 +1,110 @@
|
|||||||
import compression from 'vite-plugin-compression';
|
import { promises as fs } from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import zlib from 'zlib';
|
||||||
|
import { promisify } from 'util';
|
||||||
|
import type { Plugin, ResolvedConfig } from 'vite';
|
||||||
|
|
||||||
export default (env: any) => {
|
const gzip = promisify(zlib.gzip);
|
||||||
const { VITE_BUILD_COMPRESS } = env;
|
const brotliCompress = promisify(zlib.brotliCompress);
|
||||||
const plugin: any[] = [];
|
const compressibleFileRE = /\.(js|mjs|json|css|html)$/i;
|
||||||
if (VITE_BUILD_COMPRESS) {
|
const defaultThreshold = 1025;
|
||||||
const compressList = VITE_BUILD_COMPRESS.split(',');
|
|
||||||
if (compressList.includes('gzip')) {
|
type CompressionKind = 'gzip' | 'brotli';
|
||||||
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
|
|
||||||
plugin.push(
|
const compressionHandlers: Record<CompressionKind, { ext: string; compress: (content: Buffer) => Promise<Buffer> }> = {
|
||||||
compression({
|
gzip: {
|
||||||
ext: '.gz',
|
ext: '.gz',
|
||||||
deleteOriginFile: false
|
compress: (content) => gzip(content, { level: zlib.constants.Z_BEST_COMPRESSION })
|
||||||
})
|
},
|
||||||
);
|
brotli: {
|
||||||
}
|
ext: '.br',
|
||||||
if (compressList.includes('brotli')) {
|
compress: (content) =>
|
||||||
plugin.push(
|
brotliCompress(content, {
|
||||||
compression({
|
params: {
|
||||||
ext: '.br',
|
[zlib.constants.BROTLI_PARAM_QUALITY]: zlib.constants.BROTLI_MAX_QUALITY,
|
||||||
algorithm: 'brotliCompress',
|
[zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT
|
||||||
deleteOriginFile: false
|
}
|
||||||
})
|
})
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return plugin;
|
};
|
||||||
|
|
||||||
|
async function collectFiles(rootDir: string): Promise<string[]> {
|
||||||
|
const entries = await fs.readdir(rootDir, { withFileTypes: true });
|
||||||
|
const files = await Promise.all(
|
||||||
|
entries.map(async (entry) => {
|
||||||
|
const fullPath = path.join(rootDir, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
return collectFiles(fullPath);
|
||||||
|
}
|
||||||
|
return compressibleFileRE.test(entry.name) ? [fullPath] : [];
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return files.flat();
|
||||||
|
}
|
||||||
|
|
||||||
|
function createCompressionPlugin(kind: CompressionKind): Plugin {
|
||||||
|
const handler = compressionHandlers[kind];
|
||||||
|
let config: ResolvedConfig | undefined;
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: `local:compression:${kind}`,
|
||||||
|
apply: 'build',
|
||||||
|
enforce: 'post',
|
||||||
|
configResolved(resolvedConfig) {
|
||||||
|
config = resolvedConfig;
|
||||||
|
},
|
||||||
|
async closeBundle() {
|
||||||
|
const outputDir = path.resolve(process.cwd(), config?.build.outDir ?? 'dist');
|
||||||
|
const files = await collectFiles(outputDir);
|
||||||
|
const compressedEntries: Array<{ file: string; originalKb: string; compressedKb: string }> = [];
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
files.map(async (filePath) => {
|
||||||
|
const stat = await fs.stat(filePath);
|
||||||
|
if (stat.size < defaultThreshold) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = await fs.readFile(filePath);
|
||||||
|
const compressed = await handler.compress(content);
|
||||||
|
const outputFile = `${filePath}${handler.ext}`;
|
||||||
|
|
||||||
|
await fs.writeFile(outputFile, compressed);
|
||||||
|
compressedEntries.push({
|
||||||
|
file: path.relative(outputDir, outputFile).replaceAll('\\', '/'),
|
||||||
|
originalKb: (stat.size / 1024).toFixed(2),
|
||||||
|
compressedKb: (compressed.byteLength / 1024).toFixed(2)
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!compressedEntries.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
compressedEntries.sort((a, b) => a.file.localeCompare(b.file));
|
||||||
|
config?.logger.info(`\n[compression:${kind}] generated ${compressedEntries.length} files`);
|
||||||
|
for (const entry of compressedEntries) {
|
||||||
|
config?.logger.info(`${path.basename(outputDir)}/${entry.file} ${entry.originalKb}kb -> ${entry.compressedKb}kb`);
|
||||||
|
}
|
||||||
|
config?.logger.info('');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (env: Record<string, string>) => {
|
||||||
|
const { VITE_BUILD_COMPRESS } = env;
|
||||||
|
const plugins: Plugin[] = [];
|
||||||
|
if (!VITE_BUILD_COMPRESS) {
|
||||||
|
return plugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
const compressionList = VITE_BUILD_COMPRESS.split(',').map((item) => item.trim()) as CompressionKind[];
|
||||||
|
if (compressionList.includes('gzip')) {
|
||||||
|
plugins.push(createCompressionPlugin('gzip'));
|
||||||
|
}
|
||||||
|
if (compressionList.includes('brotli')) {
|
||||||
|
plugins.push(createCompressionPlugin('brotli'));
|
||||||
|
}
|
||||||
|
return plugins;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user