Skip to content

Commit 8b09cdf

Browse files
author
piexlmax
committed
前端增加插件化示例
1 parent 04bb9bf commit 8b09cdf

File tree

10 files changed

+147
-17
lines changed

10 files changed

+147
-17
lines changed

server/source/system/menu.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ func (i *initMenu) InitializeData(ctx context.Context) (next context.Context, er
5151
}
5252
entities := []SysBaseMenu{
5353
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "dashboard", Name: "dashboard", Component: "view/dashboard/index.vue", Sort: 1, Meta: Meta{Title: "仪表盘", Icon: "odometer"}},
54-
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "about", Name: "about", Component: "view/about/index.vue", Sort: 7, Meta: Meta{Title: "关于我们", Icon: "info-filled"}},
54+
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "about", Name: "about", Component: "view/about/index.vue", Sort: 9, Meta: Meta{Title: "关于我们", Icon: "info-filled"}},
5555
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "admin", Name: "superAdmin", Component: "view/superAdmin/index.vue", Sort: 3, Meta: Meta{Title: "超级管理员", Icon: "user"}},
5656
{MenuLevel: 0, Hidden: false, ParentId: "3", Path: "authority", Name: "authority", Component: "view/superAdmin/authority/authority.vue", Sort: 1, Meta: Meta{Title: "角色管理", Icon: "avatar"}},
5757
{MenuLevel: 0, Hidden: false, ParentId: "3", Path: "menu", Name: "menu", Component: "view/superAdmin/menu/menu.vue", Sort: 2, Meta: Meta{Title: "菜单管理", Icon: "tickets", KeepAlive: true}},
5858
{MenuLevel: 0, Hidden: false, ParentId: "3", Path: "api", Name: "api", Component: "view/superAdmin/api/api.vue", Sort: 3, Meta: Meta{Title: "api管理", Icon: "platform", KeepAlive: true}},
5959
{MenuLevel: 0, Hidden: false, ParentId: "3", Path: "user", Name: "user", Component: "view/superAdmin/user/user.vue", Sort: 4, Meta: Meta{Title: "用户管理", Icon: "coordinate"}},
6060
{MenuLevel: 0, Hidden: true, ParentId: "0", Path: "person", Name: "person", Component: "view/person/person.vue", Sort: 4, Meta: Meta{Title: "个人信息", Icon: "message"}},
61-
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "example", Name: "example", Component: "view/example/index.vue", Sort: 6, Meta: Meta{Title: "示例文件", Icon: "management"}},
61+
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "example", Name: "example", Component: "view/example/index.vue", Sort: 7, Meta: Meta{Title: "示例文件", Icon: "management"}},
6262
{MenuLevel: 0, Hidden: false, ParentId: "9", Path: "excel", Name: "excel", Component: "view/example/excel/excel.vue", Sort: 4, Meta: Meta{Title: "excel导入导出", Icon: "takeaway-box"}},
6363
{MenuLevel: 0, Hidden: false, ParentId: "9", Path: "upload", Name: "upload", Component: "view/example/upload/upload.vue", Sort: 5, Meta: Meta{Title: "媒体库(上传下载)", Icon: "upload"}},
6464
{MenuLevel: 0, Hidden: false, ParentId: "9", Path: "breakpoint", Name: "breakpoint", Component: "view/example/breakpoint/breakpoint.vue", Sort: 6, Meta: Meta{Title: "断点续传", Icon: "upload-filled"}},
@@ -72,11 +72,14 @@ func (i *initMenu) InitializeData(ctx context.Context) (next context.Context, er
7272
{MenuLevel: 0, Hidden: false, ParentId: "3", Path: "operation", Name: "operation", Component: "view/superAdmin/operation/sysOperationRecord.vue", Sort: 6, Meta: Meta{Title: "操作历史", Icon: "pie-chart"}},
7373
{MenuLevel: 0, Hidden: false, ParentId: "9", Path: "simpleUploader", Name: "simpleUploader", Component: "view/example/simpleUploader/simpleUploader", Sort: 6, Meta: Meta{Title: "断点续传(插件版)", Icon: "upload"}},
7474
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "https://www.gin-vue-admin.com", Name: "https://www.gin-vue-admin.com", Component: "/", Sort: 0, Meta: Meta{Title: "官方网站", Icon: "home-filled"}},
75-
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "state", Name: "state", Component: "view/system/state.vue", Sort: 6, Meta: Meta{Title: "服务器状态", Icon: "cloudy"}},
75+
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "state", Name: "state", Component: "view/system/state.vue", Sort: 8, Meta: Meta{Title: "服务器状态", Icon: "cloudy"}},
7676
{MenuLevel: 0, Hidden: false, ParentId: "14", Path: "autoCodeAdmin", Name: "autoCodeAdmin", Component: "view/systemTools/autoCodeAdmin/index.vue", Sort: 1, Meta: Meta{Title: "自动化代码管理", Icon: "magic-stick"}},
7777
{MenuLevel: 0, Hidden: true, ParentId: "14", Path: "autoCodeEdit/:id", Name: "autoCodeEdit", Component: "view/systemTools/autoCode/index.vue", Sort: 0, Meta: Meta{Title: "自动化代码-${id}", Icon: "magic-stick"}},
7878
{MenuLevel: 0, Hidden: false, ParentId: "14", Path: "autoPkg", Name: "autoPkg", Component: "view/systemTools/autoPkg/autoPkg.vue", Sort: 0, Meta: Meta{Title: "自动化package", Icon: "folder"}},
7979
{MenuLevel: 0, Hidden: false, ParentId: "14", Path: "autoPlug", Name: "autoPlug", Component: "view/systemTools/autoPlug/autoPlug.vue", Sort: 4, Meta: Meta{Title: "自动化插件模板", Icon: "folder"}},
80+
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "plugin", Name: "plugin", Component: "view/routerHolder.vue", Sort: 6, Meta: Meta{Title: "插件系统", Icon: "cherry"}},
81+
{MenuLevel: 0, Hidden: false, ParentId: "28", Path: "plugin-email", Name: "plugin-email", Component: "plugin/email/view/index.vue", Sort: 1, Meta: Meta{Title: "邮件插件", Icon: "message"}},
82+
{MenuLevel: 0, Hidden: false, ParentId: "28", Path: "https://plugin.gin-vue-admin.com/", Name: "https://plugin.gin-vue-admin.com/", Component: "https://plugin.gin-vue-admin.com/", Sort: 0, Meta: Meta{Title: "插件市场", Icon: "shop"}},
8083
}
8184
if err = db.Create(&entities).Error; err != nil {
8285
return ctx, errors.Wrap(err, SysBaseMenu{}.TableName()+"表数据初始化失败!")

web/src/components/warningBar/warningBar.vue

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<template>
22
<div
33
class="warning-bar"
4+
:class="href&&'can-click'"
5+
@click="open"
46
>
57
<el-icon>
68
<warning-filled />
@@ -12,12 +14,22 @@
1214
</template>
1315
<script setup>
1416
import { WarningFilled } from '@element-plus/icons-vue'
15-
defineProps({
17+
const prop = defineProps({
1618
title: {
1719
type: String,
1820
default: ''
1921
},
22+
href: {
23+
type: String,
24+
default: ''
25+
}
2026
})
27+
28+
const open = () => {
29+
if (prop.href) {
30+
window.open(prop.href)
31+
}
32+
}
2133
</script>
2234
<style lang="scss" scoped>
2335
.warning-bar{
@@ -38,4 +50,7 @@ defineProps({
3850
margin-left: 8px;
3951
}
4052
}
53+
.can-click{
54+
cursor: pointer;
55+
}
4156
</style>

web/src/plugin/email/api/email.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import service from '@/utils/request'
2+
// @Tags System
3+
// @Summary 发送测试邮件
4+
// @Security ApiKeyAuth
5+
// @Produce application/json
6+
// @Success 200 {string} string "{"success":true,"data":{},"msg":"发送成功"}"
7+
// @Router /email/emailTest [post]
8+
export const emailTest = (data) => {
9+
return service({
10+
url: '/email/emailTest',
11+
method: 'post',
12+
data
13+
})
14+
}
15+
16+
// @Tags System
17+
// @Summary 发送邮件
18+
// @Security ApiKeyAuth
19+
// @Produce application/json
20+
// @Param data body email_response.Email true "发送邮件必须的参数"
21+
// @Success 200 {string} string "{"success":true,"data":{},"msg":"发送成功"}"
22+
// @Router /email/sendEmail [post]
23+
export const sendEmail = (data) => {
24+
return service({
25+
url: '/email/sendEmail',
26+
method: 'post',
27+
data
28+
})
29+
}
30+

web/src/plugin/email/view/index.vue

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<template>
2+
<div>
3+
<warning-bar title="需要提前配置email配置文件,为防止不必要的垃圾邮件,在线体验功能不开放此功能体验。" />
4+
<div class="gva-form-box">
5+
<el-form ref="emailForm" label-position="right" label-width="80px" :model="form">
6+
<el-form-item label="目标邮箱">
7+
<el-input v-model="form.to" />
8+
</el-form-item>
9+
<el-form-item label="邮件">
10+
<el-input v-model="form.subjec" />
11+
</el-form-item>
12+
<el-form-item label="邮件内容">
13+
<el-input v-model="form.body" type="textarea" />
14+
</el-form-item>
15+
<el-form-item>
16+
<el-button @click="sendTestEmail">发送测试邮件</el-button>
17+
<el-button @click="sendEmail">发送邮件</el-button>
18+
</el-form-item>
19+
</el-form>
20+
</div>
21+
</div>
22+
23+
</template>
24+
25+
<script>
26+
export default {
27+
name: 'Email',
28+
}
29+
</script>
30+
31+
<script setup>
32+
import WarningBar from '@/components/warningBar/warningBar.vue'
33+
import { emailTest } from '@/plugin/email/api/email.js'
34+
import { ElMessage } from 'element-plus'
35+
import { reactive, ref } from 'vue'
36+
const emailForm = ref(null)
37+
const form = reactive({
38+
to: '',
39+
subjec: '',
40+
body: '',
41+
})
42+
const sendTestEmail = async() => {
43+
const res = await emailTest()
44+
if (res.code === 0) {
45+
ElMessage.success('发送成功')
46+
}
47+
}
48+
49+
const sendEmail = async() => {
50+
const res = await emailTest()
51+
if (res.code === 0) {
52+
ElMessage.success('发送成功,请查收')
53+
}
54+
}
55+
</script>
56+

web/src/utils/asyncRouter.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
const modules = import.meta.glob('../view/**/*.vue')
1+
const viewModules = import.meta.glob('../view/**/*.vue')
2+
const pluginModules = import.meta.glob('../plugin/**/*.vue')
23

34
export const asyncRouterHandle = (asyncRouter) => {
45
asyncRouter.forEach(item => {
56
if (item.component) {
6-
item.component = dynamicImport(modules, item.component)
7+
if (item.component.split('/')[0] === 'view') {
8+
item.component = dynamicImport(viewModules, item.component)
9+
} else if (item.component.split('/')[0] === 'plugin') {
10+
item.component = dynamicImport(pluginModules, item.component)
11+
}
712
} else {
813
delete item['component']
914
}

web/src/view/dashboard/index.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<div class="gva-top-card-left-title">早安,管理员,请开始一天的工作吧</div>
77
<div class="gva-top-card-left-dot">{{ weatherInfo }}</div>
88
<div class="gva-top-card-left-rows">
9-
<el-row v-auth="888">
9+
<el-row v-auth="btnAuth.a">
1010
<el-col :span="8" :xs="24" :sm="8">
1111
<div class="flex-center">
1212
<el-icon class="dasboard-icon">
@@ -110,6 +110,10 @@ import dashboardTable from '@/view/dashboard/dashboardTable/dashboardTable.vue'
110110
import { ref } from 'vue'
111111
import { useRouter } from 'vue-router'
112112
import { useWeatherInfo } from '@/view/dashboard/weather.js'
113+
114+
import { useBtnAuth } from '@/utils/btnAuth'
115+
const btnAuth = useBtnAuth()
116+
113117
const weatherInfo = useWeatherInfo()
114118
115119
const toolCards = ref([

web/src/view/superAdmin/authority/authority.vue

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,36 @@
1818
<el-button
1919
icon="setting"
2020
size="small"
21-
type="primary" link
21+
type="primary"
22+
link
2223
@click="opdendrawer(scope.row)"
2324
>设置权限</el-button>
2425
<el-button
2526
icon="plus"
2627
size="small"
27-
type="primary" link
28+
type="primary"
29+
link
2830
@click="addAuthority(scope.row.authorityId)"
2931
>新增子角色</el-button>
3032
<el-button
3133
icon="copy-document"
3234
size="small"
33-
type="primary" link
35+
type="primary"
36+
link
3437
@click="copyAuthorityFunc(scope.row)"
3538
>拷贝</el-button>
3639
<el-button
3740
icon="edit"
3841
size="small"
39-
type="primary" link
42+
type="primary"
43+
link
4044
@click="editAuthority(scope.row)"
4145
>编辑</el-button>
4246
<el-button
4347
icon="delete"
4448
size="small"
45-
type="primary" link
49+
type="primary"
50+
link
4651
@click="deleteAuth(scope.row)"
4752
>删除</el-button>
4853
</template>

web/src/view/superAdmin/menu/menu.vue

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,22 @@
3737
<template #default="scope">
3838
<el-button
3939
size="small"
40-
type="primary" link
40+
type="primary"
41+
link
4142
icon="plus"
4243
@click="addMenu(scope.row.ID)"
4344
>添加子菜单</el-button>
4445
<el-button
4546
size="small"
46-
type="primary" link
47+
type="primary"
48+
link
4749
icon="edit"
4850
@click="editMenu(scope.row.ID)"
4951
>编辑</el-button>
5052
<el-button
5153
size="small"
52-
type="primary" link
54+
type="primary"
55+
link
5356
icon="delete"
5457
@click="deleteMenu(scope.row.ID)"
5558
>删除</el-button>
@@ -109,7 +112,7 @@
109112
/>
110113
</el-form-item>
111114
<el-form-item label="文件路径" prop="component" style="width:60%">
112-
<el-input v-model="form.component" autocomplete="off" />
115+
<el-input v-model="form.component" autocomplete="off" placeholder="页面:view/xxx/xx.vue 插件:plugin/xx/xx.vue" @blur="fmtComponent" />
113116
<span style="font-size:12px;margin-right:12px;">如果菜单包含子菜单,请创建router-view二级路由页面或者</span><el-button style="margin-top:4px" size="small" @click="form.component = 'view/routerHolder.vue'">点我设置</el-button>
114117
</el-form-item>
115118
<el-form-item label="展示名称" prop="meta.title" style="width:30%">
@@ -277,6 +280,11 @@ const addParameter = (form) => {
277280
value: ''
278281
})
279282
}
283+
284+
const fmtComponent = () => {
285+
form.value.component = form.value.component.replace('\\', '/')
286+
}
287+
280288
// 删除参数
281289
const deleteParameter = (parameters, index) => {
282290
parameters.splice(index, 1)

web/src/view/systemTools/autoCode/index.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<template>
22
<div>
3+
<warning-bar href="https://www.bilibili.com/video/BV1kv4y1g7nT?p=3" title="此功能为开发环境使用,不建议发布到生产,具体使用效果请看视频https://www.bilibili.com/video/BV1kv4y1g7nT?p=3" />
34
<!-- 从数据库直接获取字段 -->
45
<div class="gva-search-box">
56
<el-collapse v-model="activeNames" style="margin-bottom:12px">
@@ -198,6 +199,7 @@ import { getDict } from '@/utils/dictionary'
198199
import { ref, getCurrentInstance, reactive, watch } from 'vue'
199200
import { useRoute, useRouter } from 'vue-router'
200201
import { ElMessage } from 'element-plus'
202+
import WarningBar from '@/components/warningBar/warningBar.vue'
201203
202204
const route = useRoute()
203205
const router = useRouter()

web/src/view/systemTools/autoPkg/autoPkg.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<template>
22
<div>
3+
<warning-bar href="https://www.bilibili.com/video/BV1kv4y1g7nT?p=3" title="此功能为开发环境使用,不建议发布到生产,具体使用效果请看视频https://www.bilibili.com/video/BV1kv4y1g7nT?p=3" />
34
<div class="gva-table-box">
45
<div class="gva-btn-list">
56
<el-button size="small" type="primary" icon="plus" @click="openDialog('addApi')">新增</el-button>
@@ -15,7 +16,8 @@
1516
<el-button
1617
icon="delete"
1718
size="small"
18-
type="primary" link
19+
type="primary"
20+
link
1921
@click="deleteApiFunc(scope.row)"
2022
>删除</el-button>
2123
</template>

0 commit comments

Comments
 (0)