Merge branch 'example' into feat/global-search

This commit is contained in:
Ben1111 2024-08-06 14:12:25 +08:00
commit 10be0a3760
No known key found for this signature in database
GPG Key ID: CE7CBC6B0B53C40F
22 changed files with 1074 additions and 1832 deletions

View File

@ -1,6 +1,24 @@
# Changelog # Changelog
## [v1.3.4](https://github.com/honghuangdc/soybean-admin/compare/v1.3.3...v1.3.4) (2024-08-01)
###    🚨 Breaking Changes
- **projects**: don't reset active menu of vertical-mix layout when it is mixSiderFixed &nbsp;-&nbsp; by @honghuangdc [<samp>(939c5)</samp>](https://github.com/honghuangdc/soybean-admin/commit/939c512)
### &nbsp;&nbsp;&nbsp;🛠 Optimizations
- **projects**: optimize code &nbsp;-&nbsp; by @honghuangdc [<samp>(cb1d4)</samp>](https://github.com/honghuangdc/soybean-admin/commit/cb1d445)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **projects**: update deps & fix vue-router type &nbsp;-&nbsp; by @honghuangdc [<samp>(96837)</samp>](https://github.com/honghuangdc/soybean-admin/commit/968370b)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
## [v1.3.3](https://github.com/honghuangdc/soybean-admin/compare/v1.3.2...v1.3.3) (2024-07-30) ## [v1.3.3](https://github.com/honghuangdc/soybean-admin/compare/v1.3.2...v1.3.3) (2024-07-30)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes ### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes

View File

@ -1,7 +1,7 @@
{ {
"name": "soybean-admin", "name": "soybean-admin",
"type": "module", "type": "module",
"version": "1.3.3", "version": "1.3.4",
"description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。", "description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。",
"author": { "author": {
"name": "Soybean", "name": "Soybean",
@ -59,10 +59,10 @@
"@vueuse/core": "10.11.0", "@vueuse/core": "10.11.0",
"clipboard": "2.0.11", "clipboard": "2.0.11",
"dayjs": "1.11.12", "dayjs": "1.11.12",
"dhtmlx-gantt": "8.0.9",
"dompurify": "3.1.6", "dompurify": "3.1.6",
"echarts": "5.5.1", "echarts": "5.5.1",
"jsbarcode": "3.11.6", "jsbarcode": "3.11.6",
"lodash-es": "4.17.21",
"naive-ui": "2.39.0", "naive-ui": "2.39.0",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"pinia": "2.2.0", "pinia": "2.2.0",
@ -70,33 +70,32 @@
"swiper": "11.1.5", "swiper": "11.1.5",
"tailwind-merge": "2.4.0", "tailwind-merge": "2.4.0",
"vditor": "3.10.4", "vditor": "3.10.4",
"vue": "3.4.34", "vue": "3.4.35",
"vue-draggable-plus": "0.5.2", "vue-draggable-plus": "0.5.2",
"vue-i18n": "9.13.1", "vue-i18n": "9.13.1",
"vue-pdf-embed": "2.1.0", "vue-pdf-embed": "2.1.0",
"vue-router": "4.4.0", "vue-router": "4.4.1",
"wangeditor": "4.7.15", "wangeditor": "4.7.15",
"xgplayer": "3.0.19", "xgplayer": "3.0.19",
"xlsx": "0.18.5" "xlsx": "0.18.5"
}, },
"devDependencies": { "devDependencies": {
"@amap/amap-jsapi-types": "0.0.15", "@amap/amap-jsapi-types": "0.0.15",
"@elegant-router/vue": "0.3.7", "@elegant-router/vue": "0.3.8",
"@iconify/json": "2.2.232", "@iconify/json": "2.2.232",
"@sa/scripts": "workspace:*", "@sa/scripts": "workspace:*",
"@sa/uno-preset": "workspace:*", "@sa/uno-preset": "workspace:*",
"@soybeanjs/eslint-config": "1.3.7", "@soybeanjs/eslint-config": "1.4.0",
"@types/bmapgl": "0.0.7", "@types/bmapgl": "0.0.7",
"@types/dompurify": "3.0.5", "@types/dompurify": "3.0.5",
"@types/lodash-es": "4.17.12", "@types/node": "22.0.1",
"@types/node": "22.0.0",
"@types/nprogress": "0.2.3", "@types/nprogress": "0.2.3",
"@unocss/eslint-config": "0.61.7", "@unocss/eslint-config": "0.61.9",
"@unocss/preset-icons": "0.61.7", "@unocss/preset-icons": "0.61.9",
"@unocss/preset-uno": "0.61.7", "@unocss/preset-uno": "0.61.9",
"@unocss/transformer-directives": "0.61.7", "@unocss/transformer-directives": "0.61.9",
"@unocss/transformer-variant-group": "0.61.7", "@unocss/transformer-variant-group": "0.61.9",
"@unocss/vite": "0.61.7", "@unocss/vite": "0.61.9",
"@vitejs/plugin-vue": "5.1.1", "@vitejs/plugin-vue": "5.1.1",
"@vitejs/plugin-vue-jsx": "4.0.0", "@vitejs/plugin-vue-jsx": "4.0.0",
"eslint": "9.8.0", "eslint": "9.8.0",
@ -105,7 +104,7 @@
"pinyin-pro": "3.23.1", "pinyin-pro": "3.23.1",
"sass": "1.77.8", "sass": "1.77.8",
"simple-git-hooks": "2.11.1", "simple-git-hooks": "2.11.1",
"tsx": "4.16.2", "tsx": "4.16.3",
"typescript": "5.5.4", "typescript": "5.5.4",
"unplugin-icons": "0.19.1", "unplugin-icons": "0.19.1",
"unplugin-vue-components": "0.27.3", "unplugin-vue-components": "0.27.3",

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/axios", "name": "@sa/axios",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/color", "name": "@sa/color",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/hooks", "name": "@sa/hooks",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/materials", "name": "@sa/materials",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/fetch", "name": "@sa/fetch",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/scripts", "name": "@sa/scripts",
"version": "1.3.3", "version": "1.3.4",
"bin": { "bin": {
"sa": "./bin.ts" "sa": "./bin.ts"
}, },
@ -21,7 +21,7 @@
"enquirer": "2.4.1", "enquirer": "2.4.1",
"execa": "9.3.0", "execa": "9.3.0",
"kolorist": "1.8.0", "kolorist": "1.8.0",
"npm-check-updates": "16.14.20", "npm-check-updates": "17.0.0",
"rimraf": "6.0.1" "rimraf": "6.0.1"
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/uno-preset", "name": "@sa/uno-preset",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/utils", "name": "@sa/utils",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

File diff suppressed because it is too large Load Diff

View File

@ -56,9 +56,7 @@ function handleSelectMixMenu(menu: App.Global.Menu) {
:theme-color="themeStore.themeColor" :theme-color="themeStore.themeColor"
@select="handleSelectMixMenu" @select="handleSelectMixMenu"
@toggle-sider-collapse="appStore.toggleSiderCollapse" @toggle-sider-collapse="appStore.toggleSiderCollapse"
> />
<slot></slot>
</FirstLevelMenu>
</Teleport> </Teleport>
</template> </template>

View File

@ -49,8 +49,11 @@ function handleSelectMixMenu(menu: App.Global.Menu) {
} }
function handleResetActiveMenu() { function handleResetActiveMenu() {
getActiveFirstLevelMenuKey();
setDrawerVisible(false); setDrawerVisible(false);
if (!appStore.mixSiderFixed) {
getActiveFirstLevelMenuKey();
}
} }
const selectedKey = computed(() => { const selectedKey = computed(() => {

View File

@ -205,7 +205,8 @@ const local: App.I18n.Schema = {
plugin_barcode: 'Barcode', plugin_barcode: 'Barcode',
plugin_pinyin: 'pinyin', plugin_pinyin: 'pinyin',
plugin_excel: 'Excel', plugin_excel: 'Excel',
plugin_pdf: 'PDF preview' plugin_pdf: 'PDF preview',
plugin_gantt: 'Gantt Chart'
}, },
page: { page: {
login: { login: {

View File

@ -205,7 +205,8 @@ const local: App.I18n.Schema = {
plugin_barcode: '条形码', plugin_barcode: '条形码',
plugin_pinyin: '拼音', plugin_pinyin: '拼音',
plugin_excel: 'Excel', plugin_excel: 'Excel',
plugin_pdf: 'PDF 预览' plugin_pdf: 'PDF 预览',
plugin_gantt: '甘特图'
}, },
page: { page: {
login: { login: {

View File

@ -42,6 +42,7 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
plugin_editor_markdown: () => import("@/views/plugin/editor/markdown/index.vue"), plugin_editor_markdown: () => import("@/views/plugin/editor/markdown/index.vue"),
plugin_editor_quill: () => import("@/views/plugin/editor/quill/index.vue"), plugin_editor_quill: () => import("@/views/plugin/editor/quill/index.vue"),
plugin_excel: () => import("@/views/plugin/excel/index.vue"), plugin_excel: () => import("@/views/plugin/excel/index.vue"),
plugin_gantt: () => import("@/views/plugin/gantt/index.vue"),
plugin_icon: () => import("@/views/plugin/icon/index.vue"), plugin_icon: () => import("@/views/plugin/icon/index.vue"),
plugin_map: () => import("@/views/plugin/map/index.vue"), plugin_map: () => import("@/views/plugin/map/index.vue"),
plugin_pdf: () => import("@/views/plugin/pdf/index.vue"), plugin_pdf: () => import("@/views/plugin/pdf/index.vue"),

View File

@ -424,6 +424,16 @@ export const generatedRoutes: GeneratedRoute[] = [
keepAlive: true keepAlive: true
} }
}, },
{
name: 'plugin_gantt',
path: '/plugin/gantt',
component: 'view.plugin_gantt',
meta: {
title: 'plugin_gantt',
i18nKey: 'route.plugin_gantt',
icon: 'ant-design:bar-chart-outlined'
}
},
{ {
name: 'plugin_icon', name: 'plugin_icon',
path: '/plugin/icon', path: '/plugin/icon',

View File

@ -101,6 +101,9 @@ function transformElegantRouteToVueRoute(
const singleLevelRoute: RouteRecordRaw = { const singleLevelRoute: RouteRecordRaw = {
path, path,
component: layouts[layout], component: layouts[layout],
meta: {
title: route.meta?.title || ''
},
children: [ children: [
{ {
name, name,
@ -132,7 +135,6 @@ function transformElegantRouteToVueRoute(
return []; return [];
} }
// add redirect to child // add redirect to child
if (children?.length && !vueRoute.redirect) { if (children?.length && !vueRoute.redirect) {
vueRoute.redirect = { vueRoute.redirect = {
@ -210,6 +212,7 @@ const routeMap: RouteMap = {
"plugin_editor_markdown": "/plugin/editor/markdown", "plugin_editor_markdown": "/plugin/editor/markdown",
"plugin_editor_quill": "/plugin/editor/quill", "plugin_editor_quill": "/plugin/editor/quill",
"plugin_excel": "/plugin/excel", "plugin_excel": "/plugin/excel",
"plugin_gantt": "/plugin/gantt",
"plugin_icon": "/plugin/icon", "plugin_icon": "/plugin/icon",
"plugin_map": "/plugin/map", "plugin_map": "/plugin/map",
"plugin_pdf": "/plugin/pdf", "plugin_pdf": "/plugin/pdf",

View File

@ -46,7 +46,6 @@ declare module 'vue' {
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default'] LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
LookForward: typeof import('./../components/custom/look-forward.vue')['default'] LookForward: typeof import('./../components/custom/look-forward.vue')['default']
MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default'] MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default']
NAlert: typeof import('naive-ui')['NAlert']
NBreadcrumb: typeof import('naive-ui')['NBreadcrumb'] NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem'] NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
NButton: typeof import('naive-ui')['NButton'] NButton: typeof import('naive-ui')['NButton']
@ -70,7 +69,6 @@ declare module 'vue' {
NFormItemGi: typeof import('naive-ui')['NFormItemGi'] NFormItemGi: typeof import('naive-ui')['NFormItemGi']
NGi: typeof import('naive-ui')['NGi'] NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid'] NGrid: typeof import('naive-ui')['NGrid']
NGridItem: typeof import('naive-ui')['NGridItem']
NInput: typeof import('naive-ui')['NInput'] NInput: typeof import('naive-ui')['NInput']
NInputGroup: typeof import('naive-ui')['NInputGroup'] NInputGroup: typeof import('naive-ui')['NInputGroup']
NInputNumber: typeof import('naive-ui')['NInputNumber'] NInputNumber: typeof import('naive-ui')['NInputNumber']

View File

@ -66,6 +66,7 @@ declare module "@elegant-router/types" {
"plugin_editor_markdown": "/plugin/editor/markdown"; "plugin_editor_markdown": "/plugin/editor/markdown";
"plugin_editor_quill": "/plugin/editor/quill"; "plugin_editor_quill": "/plugin/editor/quill";
"plugin_excel": "/plugin/excel"; "plugin_excel": "/plugin/excel";
"plugin_gantt": "/plugin/gantt";
"plugin_icon": "/plugin/icon"; "plugin_icon": "/plugin/icon";
"plugin_map": "/plugin/map"; "plugin_map": "/plugin/map";
"plugin_pdf": "/plugin/pdf"; "plugin_pdf": "/plugin/pdf";
@ -174,6 +175,7 @@ declare module "@elegant-router/types" {
| "plugin_editor_markdown" | "plugin_editor_markdown"
| "plugin_editor_quill" | "plugin_editor_quill"
| "plugin_excel" | "plugin_excel"
| "plugin_gantt"
| "plugin_icon" | "plugin_icon"
| "plugin_map" | "plugin_map"
| "plugin_pdf" | "plugin_pdf"

View File

@ -0,0 +1,173 @@
import type { Task } from 'dhtmlx-gantt';
export const ganttTasks: Task[] = [
{
id: 11,
text: 'Soybean 架构设计',
type: 'project',
progress: 0,
open: true,
start_date: new Date('2024-01-10 00:00'),
duration: 12,
parent: 0
},
{
id: 12,
text: '测试版本',
start_date: new Date('2024-03-20 00:00'),
type: 'project',
duration: 5,
render: 'split',
parent: '11',
progress: 0,
open: true
},
{
id: 99,
text: '测试版本1 发布',
start_date: new Date('2024-03-20 00:00'),
end_date: new Date('2024-03-25 00:00'),
parent: '12',
progress: 0,
open: true
},
{
id: 98,
text: '测试版本2 发布',
start_date: new Date('2024-03-26 00:00'),
duration: 4,
parent: '12',
progress: 0,
open: true
},
{
id: 97,
text: '测试版本3 发布',
start_date: new Date('2024-03-31 00:00'),
duration: 10,
parent: '12',
progress: 0,
open: true
},
{
id: 13,
text: '1.0 版本',
start_date: new Date('2024-03-31 00:00'),
type: 'project',
render: 'split',
parent: '11',
progress: 0.5,
open: false,
duration: 11
},
{
id: 17,
text: '1.0正式发布',
start_date: new Date('2024-03-31 00:00'),
end_date: new Date('2024-04-03 00:00'),
parent: '13',
progress: 0,
open: true
},
{
id: 18,
text: '1.0.1 版本',
start_date: new Date('2024-04-03 00:00'),
duration: 5,
parent: '13',
progress: 0,
open: true
},
{
id: 19,
text: '1.0.2 版本',
start_date: new Date('2024-04-08 00:00'),
duration: 6,
parent: '13',
progress: 0,
open: true
},
{
id: 20,
text: '1.0.3 版本',
start_date: new Date('2024-04-16 00:00'),
duration: 8,
parent: '13',
progress: 0,
open: true
},
{
id: 31,
text: '1.0.4 版本',
start_date: new Date('2024-04-17 00:00'),
duration: 8,
parent: '13',
progress: 0,
open: true
},
{
id: 32,
text: '1.0.5 版本',
start_date: new Date('2024-04-26 00:00'),
duration: 9,
parent: '13',
progress: 0,
open: true
},
{
id: 33,
text: '1.0.9 版本',
start_date: new Date('2024-05-05 00:00'),
duration: 2,
parent: '13',
progress: 0,
open: true
},
{
id: 14,
text: '1.1 版本',
start_date: new Date('2024-05-07 00:00'),
duration: 30,
parent: '11',
progress: 0,
open: true
},
{
id: 15,
text: '1.2 版本',
start_date: new Date('2024-06-06 00:00'),
duration: 46,
parent: '11',
progress: 0,
open: true
},
{
id: 16,
text: '1.3版本',
type: 'project',
render: 'split',
parent: '11',
progress: 0,
open: true,
start_date: new Date('2024-07-22 00:00'),
duration: 11
},
{
id: 21,
text: '1.3.1版本',
start_date: new Date('2024-07-22 00:00'),
duration: 7,
parent: '16',
progress: 0,
open: true
},
{
id: 22,
text: '1.3.2版本',
start_date: new Date('2024-07-29 00:00'),
duration: 7,
parent: '16',
progress: 0,
open: true
}
];

View File

@ -0,0 +1,208 @@
<script setup lang="tsx">
import { onMounted, shallowRef } from 'vue';
import { gantt } from 'dhtmlx-gantt';
import type { GanttConfigOptions, ZoomLevels } from 'dhtmlx-gantt';
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';
import { ganttTasks } from './data';
const ganttRef = shallowRef<HTMLElement>();
type TimeType = 'day' | 'week' | 'month' | 'quarter' | 'year';
const timeType = shallowRef<TimeType>('quarter');
interface TimeData {
name: string;
code: TimeType;
}
const data: TimeData[] = [
{
name: '天',
code: 'day'
},
{
name: '周',
code: 'week'
},
{
name: '月',
code: 'month'
},
{
name: '季',
code: 'quarter'
},
{
name: '年',
code: 'year'
}
];
function initGantt() {
if (!ganttRef.value) return;
const config: Partial<GanttConfigOptions> = {
grid_width: 350,
add_column: false,
autofit: false,
row_height: 60,
bar_height: 34,
auto_types: true,
xml_date: '%Y-%m-%d',
columns: [
{
name: 'text',
label: '项目名称',
tree: true,
width: '*'
},
{
name: 'start_date',
label: '开始时间',
align: 'center',
width: 150
}
]
};
Object.assign(gantt.config, config);
gantt.i18n.setLocale('cn');
gantt.init(ganttRef.value);
gantt.parse({ data: ganttTasks });
const zoomLevels: ZoomLevels[] = [
{
name: 'day',
scale_height: 60,
scales: [{ unit: 'day', step: 1, format: '%d %M' }]
},
{
name: 'week',
scale_height: 60,
scales: [
{
unit: 'week',
step: 1,
format(date: Date) {
const dateToStr = gantt.date.date_to_str('%m-%d');
const endDate = gantt.date.add(date, -6, 'day'); //
return `${dateToStr(endDate)}${dateToStr(date)}`;
}
},
{
unit: 'day',
step: 1,
format: '%d',
css(date: Date) {
if (date.getDay() === 0 || date.getDay() === 6) {
return 'day-item weekend weekend-border-bottom';
}
return 'day-item';
}
}
]
},
{
name: 'month',
scale_height: 60,
min_column_width: 18,
scales: [
{ unit: 'month', format: '%Y-%m' },
{
unit: 'day',
step: 1,
format: '%d',
css(date: Date) {
if (date.getDay() === 0 || date.getDay() === 6) {
return 'day-item weekend weekend-border-bottom';
}
return 'day-item';
}
}
]
},
{
name: 'quarter',
height: 60,
min_column_width: 110,
scales: [
{
unit: 'quarter',
step: 1,
format(date: Date) {
const yearStr = `${new Date(date).getFullYear()}`;
const dateToStr = gantt.date.date_to_str('%M');
const endDate = gantt.date.add(gantt.date.add(date, 3, 'month'), -1, 'day');
return `${yearStr + dateToStr(date)} - ${dateToStr(endDate)}`;
}
},
{
unit: 'week',
step: 1,
format(date: Date) {
const dateToStr = gantt.date.date_to_str('%m-%d');
const endDate = gantt.date.add(date, 6, 'day');
return `${dateToStr(date)}${dateToStr(endDate)}`;
}
}
]
},
{
name: 'year',
scale_height: 50,
min_column_width: 150,
scales: [
{ unit: 'year', step: 1, format: '%Y年' },
{ unit: 'month', format: '%Y-%m' }
]
}
];
gantt.ext.zoom.init({
levels: zoomLevels
});
gantt.ext.zoom.setLevel(timeType.value);
}
function changeTime(value: TimeType) {
timeType.value = value;
gantt.ext.zoom.setLevel(value);
}
onMounted(() => {
initGantt();
});
</script>
<template>
<div class="overflow-hidden lt-sm:overflow-auto">
<NCard
title="甘特图演示"
:bordered="false"
size="small"
content-class="overflow-y-hidden overflow-x-auto"
class="h-full card-wrapper"
>
<template #header-extra>
<NTabs
:value="timeType"
type="segment"
animated
size="small"
class="relative w-320px"
@update:value="changeTime"
>
<NTab v-for="item in data" :key="item.code" :name="item.code">
{{ item.name }}
</NTab>
</NTabs>
</template>
<div ref="ganttRef" class="size-full min-w-800px"></div>
</NCard>
</div>
</template>
<style scoped lang="scss"></style>