@befly-addon/admin 1.0.19 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/views/403/index.vue +5 -3
- package/views/admin/components/edit.vue +32 -31
- package/views/admin/components/role.vue +8 -7
- package/views/admin/index.vue +43 -39
- package/views/dict/components/edit.vue +32 -31
- package/views/dict/index.vue +40 -35
- package/views/index/components/addonList.vue +6 -4
- package/views/index/components/environmentInfo.vue +2 -2
- package/views/index/components/operationLogs.vue +5 -4
- package/views/index/components/performanceMetrics.vue +11 -7
- package/views/index/components/quickActions.vue +6 -3
- package/views/index/components/serviceStatus.vue +22 -12
- package/views/index/components/systemNotifications.vue +15 -8
- package/views/index/components/systemOverview.vue +9 -5
- package/views/index/components/systemResources.vue +12 -8
- package/views/index/components/userInfo.vue +13 -8
- package/views/login/components/emailLoginForm.vue +18 -16
- package/views/login/components/registerForm.vue +29 -24
- package/views/login/index_1.vue +0 -2
- package/views/menu/components/edit.vue +26 -26
- package/views/menu/index.vue +39 -35
- package/views/news/index.vue +2 -0
- package/views/role/components/api.vue +11 -12
- package/views/role/components/edit.vue +26 -26
- package/views/role/components/menu.vue +7 -7
- package/views/role/index.vue +44 -37
- package/views/user/index.vue +11 -8
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
3
|
<div class="section-content">
|
|
4
|
-
<
|
|
4
|
+
<TinyButton type="primary" size="large" @click="handleClearCache">
|
|
5
5
|
<template #prefix>
|
|
6
|
-
<
|
|
6
|
+
<IconLucideRotateCw />
|
|
7
7
|
</template>
|
|
8
8
|
刷新缓存
|
|
9
|
-
</
|
|
9
|
+
</TinyButton>
|
|
10
10
|
</div>
|
|
11
11
|
</div>
|
|
12
12
|
</template>
|
|
13
13
|
|
|
14
14
|
<script setup>
|
|
15
|
+
import { useRouter, useRoute } from 'vue-router';
|
|
16
|
+
import { Button as TinyButton } from '@opentiny/vue';
|
|
17
|
+
import IconLucideRotateCw from '~icons/lucide/rotate-cw';
|
|
15
18
|
const handleClearCache = () => {
|
|
16
19
|
console.log('刷新缓存');
|
|
17
20
|
};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
3
|
<div class="section-header flex items-center gap-2">
|
|
4
|
-
<
|
|
4
|
+
<IconLucideCheckCircle />
|
|
5
5
|
<h2>服务状态</h2>
|
|
6
6
|
</div>
|
|
7
7
|
<div class="section-content">
|
|
8
8
|
<div class="config-grid">
|
|
9
9
|
<div v-for="service in services" :key="service.name" class="config-card" :class="`config-${service.status}`">
|
|
10
10
|
<div class="config-icon">
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
<
|
|
11
|
+
<IconLucideDatabase v-if="service.name === '数据库'" style="width: 20px; height: 20px" />
|
|
12
|
+
<IconLucideZap v-else-if="service.name === 'Redis'" style="width: 20px; height: 20px" />
|
|
13
|
+
<IconLucideHardDrive v-else-if="service.name === '文件系统'" style="width: 20px; height: 20px" />
|
|
14
|
+
<IconLucideMail v-else-if="service.name === '邮件服务'" style="width: 20px; height: 20px" />
|
|
15
|
+
<IconLucideCloud v-else-if="service.name === 'OSS存储'" style="width: 20px; height: 20px" />
|
|
16
|
+
<IconLucideCircle v-else style="width: 20px; height: 20px" />
|
|
17
17
|
</div>
|
|
18
18
|
<div class="config-info">
|
|
19
19
|
<div class="config-name">{{ service.name }}</div>
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
</div>
|
|
24
24
|
</div>
|
|
25
25
|
<div class="config-badge">
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
<
|
|
26
|
+
<IconLucideCheckCircle v-if="service.status === 'running'" style="width: 32px; height: 32px" />
|
|
27
|
+
<IconLucideXCircle v-else-if="service.status === 'stopped'" style="width: 32px; height: 32px" />
|
|
28
|
+
<IconLucideAlertCircle v-else-if="service.status === 'unconfigured'" style="width: 32px; height: 32px" />
|
|
29
|
+
<IconLucideCircle v-else style="width: 32px; height: 32px" />
|
|
30
30
|
</div>
|
|
31
31
|
</div>
|
|
32
32
|
</div>
|
|
@@ -35,7 +35,17 @@
|
|
|
35
35
|
</template>
|
|
36
36
|
|
|
37
37
|
<script setup>
|
|
38
|
-
import
|
|
38
|
+
import IconLucideCheckCircle from '~icons/lucide/check-circle';
|
|
39
|
+
import IconLucideZap from '~icons/lucide/zap';
|
|
40
|
+
import IconLucideCloud from '~icons/lucide/cloud';
|
|
41
|
+
import IconLucideCircle from '~icons/lucide/circle';
|
|
42
|
+
import IconLucideXCircle from '~icons/lucide/x-circle';
|
|
43
|
+
import IconLucideCheck from '~icons/lucide/check';
|
|
44
|
+
import IconLucideX from '~icons/lucide/x';
|
|
45
|
+
import IconLucideAlertCircle from '~icons/lucide/alert-circle';
|
|
46
|
+
import IconLucideDatabase from '~icons/lucide/database';
|
|
47
|
+
import IconLucideMail from '~icons/lucide/mail';
|
|
48
|
+
import IconLucideHardDrive from '~icons/lucide/hard-drive';
|
|
39
49
|
|
|
40
50
|
// 组件内部数据
|
|
41
51
|
const services = $ref([]);
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
3
|
<div class="section-header flex items-center gap-2">
|
|
4
|
-
<
|
|
4
|
+
<IconLucideBell />
|
|
5
5
|
<h2>系统通知</h2>
|
|
6
6
|
</div>
|
|
7
7
|
<div class="section-content">
|
|
8
8
|
<div class="notification-compact-list">
|
|
9
9
|
<div v-for="notification in notifications" :key="notification.id" class="notification-compact-item">
|
|
10
10
|
<div class="notification-icon" :class="`type-${notification.type}`">
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
<
|
|
15
|
-
<
|
|
11
|
+
<IconLucideInfo v-if="notification.type === 'info'" />
|
|
12
|
+
<IconLucideCheckCircle v-else-if="notification.type === 'success'" />
|
|
13
|
+
<IconLucideAlertTriangle v-else-if="notification.type === 'warning'" />
|
|
14
|
+
<IconLucideXCircle v-else-if="notification.type === 'error'" />
|
|
15
|
+
<IconLucideBell v-else />
|
|
16
16
|
</div>
|
|
17
17
|
<div class="notification-content">
|
|
18
18
|
<span class="notification-title">{{ notification.title }}</span>
|
|
19
19
|
<span class="notification-time">{{ formatTime(notification.createdAt) }}</span>
|
|
20
20
|
</div>
|
|
21
|
-
<
|
|
21
|
+
<TinyTag v-if="!notification.isRead" type="primary" size="small">新</TinyTag>
|
|
22
22
|
</div>
|
|
23
23
|
</div>
|
|
24
24
|
</div>
|
|
@@ -26,7 +26,14 @@
|
|
|
26
26
|
</template>
|
|
27
27
|
|
|
28
28
|
<script setup>
|
|
29
|
-
import
|
|
29
|
+
import IconLucideBell from '~icons/lucide/bell';
|
|
30
|
+
import IconLucideCheckCircle from '~icons/lucide/check-circle';
|
|
31
|
+
import IconLucideAlertTriangle from '~icons/lucide/alert-triangle';
|
|
32
|
+
import IconLucideXCircle from '~icons/lucide/x-circle';
|
|
33
|
+
import { Tag as TinyTag } from '@opentiny/vue';
|
|
34
|
+
import IconLucideInfo from '~icons/lucide/info';
|
|
35
|
+
import IconLucideCheck from '~icons/lucide/check';
|
|
36
|
+
import IconLucideX from '~icons/lucide/x';
|
|
30
37
|
|
|
31
38
|
// 组件内部数据
|
|
32
39
|
const notifications = $ref([
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
3
|
<div class="section-header flex items-center gap-2">
|
|
4
|
-
<
|
|
4
|
+
<IconLucideInfo />
|
|
5
5
|
<h2>系统概览</h2>
|
|
6
6
|
</div>
|
|
7
7
|
<div class="section-content">
|
|
@@ -10,21 +10,21 @@
|
|
|
10
10
|
<div class="info-block">
|
|
11
11
|
<div class="stats-grid">
|
|
12
12
|
<div class="stat-box stat-primary">
|
|
13
|
-
<
|
|
13
|
+
<IconLucideMenu />
|
|
14
14
|
<div class="stat-content">
|
|
15
15
|
<div class="stat-value">{{ permissionStats.menuCount }}</div>
|
|
16
16
|
<div class="stat-label">菜单总数</div>
|
|
17
17
|
</div>
|
|
18
18
|
</div>
|
|
19
19
|
<div class="stat-box stat-success">
|
|
20
|
-
<
|
|
20
|
+
<IconLucideWebhook />
|
|
21
21
|
<div class="stat-content">
|
|
22
22
|
<div class="stat-value">{{ permissionStats.apiCount }}</div>
|
|
23
23
|
<div class="stat-label">接口总数</div>
|
|
24
24
|
</div>
|
|
25
25
|
</div>
|
|
26
26
|
<div class="stat-box stat-warning">
|
|
27
|
-
<
|
|
27
|
+
<IconLucideUsers />
|
|
28
28
|
<div class="stat-content">
|
|
29
29
|
<div class="stat-value">{{ permissionStats.roleCount }}</div>
|
|
30
30
|
<div class="stat-label">角色总数</div>
|
|
@@ -39,7 +39,11 @@
|
|
|
39
39
|
</template>
|
|
40
40
|
|
|
41
41
|
<script setup>
|
|
42
|
-
import
|
|
42
|
+
import IconLucideWebhook from '~icons/lucide/webhook';
|
|
43
|
+
import IconLucideUsers from '~icons/lucide/users';
|
|
44
|
+
import IconLucideUser from '~icons/lucide/user';
|
|
45
|
+
import IconLucideMenu from '~icons/lucide/menu';
|
|
46
|
+
import IconLucideInfo from '~icons/lucide/info';
|
|
43
47
|
|
|
44
48
|
// 组件内部数据
|
|
45
49
|
const permissionStats = $ref({
|
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
3
|
<div class="section-header flex items-center gap-2">
|
|
4
|
-
<
|
|
4
|
+
<IconLucideActivity />
|
|
5
5
|
<h2>系统资源</h2>
|
|
6
6
|
</div>
|
|
7
7
|
<div class="section-content">
|
|
8
8
|
<div class="resource-compact-list">
|
|
9
9
|
<div class="resource-compact-item">
|
|
10
10
|
<div class="resource-compact-header">
|
|
11
|
-
<
|
|
11
|
+
<IconLucideCpu />
|
|
12
12
|
<span class="resource-label">CPU</span>
|
|
13
13
|
<span class="resource-value">{{ systemResources.cpu.usage }}%</span>
|
|
14
14
|
<span class="resource-desc">{{ systemResources.cpu.cores }}核心</span>
|
|
15
15
|
</div>
|
|
16
|
-
<
|
|
16
|
+
<TinyProgress :percentage="systemResources.cpu.usage" :status="getProgressColor(systemResources.cpu.usage)" />
|
|
17
17
|
</div>
|
|
18
18
|
<div class="resource-compact-item">
|
|
19
19
|
<div class="resource-compact-header">
|
|
20
|
-
<
|
|
20
|
+
<IconLucideHardDrive />
|
|
21
21
|
<span class="resource-label">内存</span>
|
|
22
22
|
<span class="resource-value">{{ systemResources.memory.percentage }}%</span>
|
|
23
23
|
<span class="resource-desc">{{ systemResources.memory.used }}GB / {{ systemResources.memory.total }}GB</span>
|
|
24
24
|
</div>
|
|
25
|
-
<
|
|
25
|
+
<TinyProgress :percentage="systemResources.memory.percentage" :status="getProgressColor(systemResources.memory.percentage)" />
|
|
26
26
|
</div>
|
|
27
27
|
<div class="resource-compact-item">
|
|
28
28
|
<div class="resource-compact-header">
|
|
29
|
-
<
|
|
29
|
+
<IconLucideDisc />
|
|
30
30
|
<span class="resource-label">磁盘</span>
|
|
31
31
|
<span class="resource-value">{{ systemResources.disk.percentage }}%</span>
|
|
32
32
|
<span class="resource-desc">{{ systemResources.disk.used }}GB / {{ systemResources.disk.total }}GB</span>
|
|
33
33
|
</div>
|
|
34
|
-
<
|
|
34
|
+
<TinyProgress :percentage="systemResources.disk.percentage" :status="getProgressColor(systemResources.disk.percentage)" />
|
|
35
35
|
</div>
|
|
36
36
|
</div>
|
|
37
37
|
</div>
|
|
@@ -39,7 +39,11 @@
|
|
|
39
39
|
</template>
|
|
40
40
|
|
|
41
41
|
<script setup>
|
|
42
|
-
import
|
|
42
|
+
import IconLucideDisc from '~icons/lucide/disc';
|
|
43
|
+
import { Progress as TinyProgress } from '@opentiny/vue';
|
|
44
|
+
import IconLucideCpu from '~icons/lucide/cpu';
|
|
45
|
+
import IconLucideHardDrive from '~icons/lucide/hard-drive';
|
|
46
|
+
import IconLucideActivity from '~icons/lucide/activity';
|
|
43
47
|
|
|
44
48
|
// 组件内部数据
|
|
45
49
|
const systemResources = $ref({
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="section-block user-info-card">
|
|
3
3
|
<div class="user-header">
|
|
4
4
|
<div class="user-avatar">
|
|
5
|
-
<
|
|
5
|
+
<IconLucideUser />
|
|
6
6
|
</div>
|
|
7
7
|
<div class="user-basic">
|
|
8
8
|
<div class="user-name">{{ $Data.userInfo.nickname || $Data.userInfo.name || $Data.userInfo.username || '未设置' }}</div>
|
|
@@ -11,33 +11,38 @@
|
|
|
11
11
|
</div>
|
|
12
12
|
<div class="user-details">
|
|
13
13
|
<div class="detail-item">
|
|
14
|
-
<
|
|
14
|
+
<IconLucideMail />
|
|
15
15
|
<span>{{ $Data.userInfo.email || '未设置' }}</span>
|
|
16
16
|
</div>
|
|
17
17
|
<div v-if="$Data.userInfo.phone" class="detail-item">
|
|
18
|
-
<
|
|
18
|
+
<IconLucidePhone />
|
|
19
19
|
<span>{{ $Data.userInfo.phone }}</span>
|
|
20
20
|
</div>
|
|
21
21
|
<div v-if="$Data.userInfo.lastLoginTime" class="detail-item">
|
|
22
|
-
<
|
|
22
|
+
<IconLucideClock />
|
|
23
23
|
<span>{{ $Method.formatTime($Data.userInfo.lastLoginTime) }}</span>
|
|
24
24
|
</div>
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
27
|
<!-- 仅 dev 角色显示刷新缓存按钮 -->
|
|
28
28
|
<div v-if="$Data.userInfo.roleCode === 'dev'" class="user-actions">
|
|
29
|
-
<
|
|
29
|
+
<TinyButton type="primary" size="mini" :loading="$Data.refreshing" @click="$Method.handleRefreshCache">
|
|
30
30
|
<template #icon>
|
|
31
|
-
<
|
|
31
|
+
<IconLucideRotateCw />
|
|
32
32
|
</template>
|
|
33
33
|
刷新缓存
|
|
34
|
-
</
|
|
34
|
+
</TinyButton>
|
|
35
35
|
</div>
|
|
36
36
|
</div>
|
|
37
37
|
</template>
|
|
38
38
|
|
|
39
39
|
<script setup>
|
|
40
|
-
import
|
|
40
|
+
import IconLucidePhone from '~icons/lucide/phone';
|
|
41
|
+
import IconLucideClock from '~icons/lucide/clock';
|
|
42
|
+
import { Button as TinyButton } from '@opentiny/vue';
|
|
43
|
+
import IconLucideUser from '~icons/lucide/user';
|
|
44
|
+
import IconLucideMail from '~icons/lucide/mail';
|
|
45
|
+
import IconLucideRotateCw from '~icons/lucide/rotate-cw';
|
|
41
46
|
|
|
42
47
|
// 响应式数据
|
|
43
48
|
const $Data = $ref({
|
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<
|
|
2
|
+
<TinyForm :model="$Data.formData" :rules="$Data2.formRules" :ref="(el) => ($From.form = el)" class="login-form" label-width="90px" label-position="left" :show-message="false">
|
|
3
|
+
<TinyFormItem prop="account" label="账号">
|
|
4
|
+
<TinyInput v-model="$Data.formData.account" placeholder="请输入用户名或邮箱" size="large" clearable>
|
|
5
5
|
<template #prefix-icon>
|
|
6
|
-
<
|
|
6
|
+
<IconLucideUser />
|
|
7
7
|
</template>
|
|
8
|
-
</
|
|
9
|
-
</
|
|
8
|
+
</TinyInput>
|
|
9
|
+
</TinyFormItem>
|
|
10
10
|
|
|
11
|
-
<
|
|
12
|
-
<
|
|
11
|
+
<TinyFormItem prop="password" label="密码">
|
|
12
|
+
<TinyInput v-model="$Data.formData.password" type="password" placeholder="请输入密码" size="large" clearable>
|
|
13
13
|
<template #prefix-icon>
|
|
14
|
-
<
|
|
14
|
+
<IconLucideLock />
|
|
15
15
|
</template>
|
|
16
|
-
</
|
|
17
|
-
</
|
|
16
|
+
</TinyInput>
|
|
17
|
+
</TinyFormItem>
|
|
18
18
|
|
|
19
19
|
<div class="form-footer">
|
|
20
20
|
<a href="#" class="forgot-password">忘记密码?</a>
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
|
-
<
|
|
24
|
-
</
|
|
23
|
+
<TinyButton theme="primary" class="auth-btn" size="large" :loading="$Data.loading" @click="$Method.apiLogin"> 登录 </TinyButton>
|
|
24
|
+
</TinyForm>
|
|
25
25
|
</template>
|
|
26
26
|
|
|
27
27
|
<script setup lang="ts">
|
|
28
|
-
import {
|
|
29
|
-
import { useRouter } from 'vue-router';
|
|
30
|
-
import { Modal } from '@opentiny/vue';
|
|
28
|
+
import { shallowRef } from 'vue';
|
|
29
|
+
import { useRouter, useRoute } from 'vue-router';
|
|
30
|
+
import { Button as TinyButton, Form as TinyForm, FormItem as TinyFormItem, Input as TinyInput, Modal } from '@opentiny/vue';
|
|
31
|
+
import IconLucideUser from '~icons/lucide/user';
|
|
32
|
+
import IconLucideLock from '~icons/lucide/lock';
|
|
31
33
|
|
|
32
34
|
const router = useRouter();
|
|
33
35
|
|
|
@@ -1,43 +1,48 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<
|
|
2
|
+
<TinyForm :model="$Data.formData" :rules="$Data2.formRules" :ref="(el) => ($From.form = el)" class="login-form" label-width="70px" label-position="left">
|
|
3
|
+
<TinyFormItem prop="username" label="用户名">
|
|
4
|
+
<TinyInput v-model="$Data.formData.username" placeholder="请输入用户名" size="large" clearable>
|
|
5
5
|
<template #prefix-icon>
|
|
6
|
-
<
|
|
6
|
+
<IconLucideUser />
|
|
7
7
|
</template>
|
|
8
|
-
</
|
|
9
|
-
</
|
|
8
|
+
</TinyInput>
|
|
9
|
+
</TinyFormItem>
|
|
10
10
|
|
|
11
|
-
<
|
|
12
|
-
<
|
|
11
|
+
<TinyFormItem prop="email" label="邮箱">
|
|
12
|
+
<TinyInput v-model="$Data.formData.email" placeholder="请输入邮箱" size="large" clearable>
|
|
13
13
|
<template #prefix-icon>
|
|
14
|
-
<
|
|
14
|
+
<IconLucideMail />
|
|
15
15
|
</template>
|
|
16
|
-
</
|
|
17
|
-
</
|
|
16
|
+
</TinyInput>
|
|
17
|
+
</TinyFormItem>
|
|
18
18
|
|
|
19
|
-
<
|
|
20
|
-
<
|
|
19
|
+
<TinyFormItem prop="password" label="密码">
|
|
20
|
+
<TinyInput v-model="$Data.formData.password" type="password" placeholder="请输入密码" size="large" clearable>
|
|
21
21
|
<template #prefix-icon>
|
|
22
|
-
<
|
|
22
|
+
<IconLucideLock />
|
|
23
23
|
</template>
|
|
24
|
-
</
|
|
25
|
-
</
|
|
24
|
+
</TinyInput>
|
|
25
|
+
</TinyFormItem>
|
|
26
26
|
|
|
27
|
-
<
|
|
28
|
-
<
|
|
27
|
+
<TinyFormItem prop="nickname" label="昵称">
|
|
28
|
+
<TinyInput v-model="$Data.formData.nickname" placeholder="请输入昵称(选填)" size="large" clearable>
|
|
29
29
|
<template #prefix-icon>
|
|
30
|
-
<
|
|
30
|
+
<IconLucideSmile />
|
|
31
31
|
</template>
|
|
32
|
-
</
|
|
33
|
-
</
|
|
32
|
+
</TinyInput>
|
|
33
|
+
</TinyFormItem>
|
|
34
34
|
|
|
35
|
-
<
|
|
36
|
-
</
|
|
35
|
+
<TinyButton theme="primary" class="auth-btn" size="large" :loading="$Data.loading" @click="$Method.handleSubmit"> 注册 </TinyButton>
|
|
36
|
+
</TinyForm>
|
|
37
37
|
</template>
|
|
38
38
|
|
|
39
39
|
<script setup>
|
|
40
|
-
import {
|
|
40
|
+
import { shallowRef } from 'vue';
|
|
41
|
+
import { Button as TinyButton, Form as TinyForm, FormItem as TinyFormItem, Input as TinyInput } from '@opentiny/vue';
|
|
42
|
+
import IconLucideUser from '~icons/lucide/user';
|
|
43
|
+
import IconLucideMail from '~icons/lucide/mail';
|
|
44
|
+
import IconLucideLock from '~icons/lucide/lock';
|
|
45
|
+
import IconLucideSmile from '~icons/lucide/smile';
|
|
41
46
|
|
|
42
47
|
const emit = defineEmits(['success']);
|
|
43
48
|
|
package/views/login/index_1.vue
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
</
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
</
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
</
|
|
13
|
-
<
|
|
14
|
-
<
|
|
15
|
-
</
|
|
16
|
-
<
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
</
|
|
21
|
-
</
|
|
22
|
-
</
|
|
2
|
+
<TinyDialogBox v-model:visible="$Data.visible" :title="$Prop.actionType === 'add' ? '添加菜单' : '编辑菜单'" width="600px" :append-to-body="true" :show-footer="true" top="10vh">
|
|
3
|
+
<TinyForm :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" :ref="(el) => ($From.form = el)">
|
|
4
|
+
<TinyFormItem label="菜单名称" prop="name">
|
|
5
|
+
<TinyInput v-model="$Data.formData.name" placeholder="请输入菜单名称" />
|
|
6
|
+
</TinyFormItem>
|
|
7
|
+
<TinyFormItem label="菜单路径" prop="path">
|
|
8
|
+
<TinyInput v-model="$Data.formData.path" placeholder="请输入菜单路径,如:/user" />
|
|
9
|
+
</TinyFormItem>
|
|
10
|
+
<TinyFormItem label="图标" prop="icon">
|
|
11
|
+
<TinyInput v-model="$Data.formData.icon" placeholder="请输入图标名称,如:User" />
|
|
12
|
+
</TinyFormItem>
|
|
13
|
+
<TinyFormItem label="排序" prop="sort">
|
|
14
|
+
<TinyNumeric v-model="$Data.formData.sort" :min="0" :max="9999" />
|
|
15
|
+
</TinyFormItem>
|
|
16
|
+
<TinyFormItem label="状态" prop="state">
|
|
17
|
+
<TinyRadioGroup v-model="$Data.formData.state">
|
|
18
|
+
<TinyRadio :label="1">正常</TinyRadio>
|
|
19
|
+
<TinyRadio :label="2">禁用</TinyRadio>
|
|
20
|
+
</TinyRadioGroup>
|
|
21
|
+
</TinyFormItem>
|
|
22
|
+
</TinyForm>
|
|
23
23
|
<template #footer>
|
|
24
|
-
<
|
|
25
|
-
<
|
|
24
|
+
<TinyButton @click="$Method.onClose">取消</TinyButton>
|
|
25
|
+
<TinyButton type="primary" @click="$Method.onSubmit">确定</TinyButton>
|
|
26
26
|
</template>
|
|
27
|
-
</
|
|
27
|
+
</TinyDialogBox>
|
|
28
28
|
</template>
|
|
29
29
|
|
|
30
30
|
<script setup>
|
|
31
|
-
import {
|
|
32
|
-
import { Modal } from '@opentiny/vue';
|
|
31
|
+
import { watch, shallowRef } from 'vue';
|
|
32
|
+
import { Button as TinyButton, DialogBox as TinyDialogBox, Form as TinyForm, FormItem as TinyFormItem, Input as TinyInput, Numeric as TinyNumeric, Radio as TinyRadio, RadioGroup as TinyRadioGroup, Modal } from '@opentiny/vue';
|
|
33
33
|
|
|
34
34
|
const $Prop = defineProps({
|
|
35
35
|
modelValue: {
|
package/views/menu/index.vue
CHANGED
|
@@ -2,64 +2,64 @@
|
|
|
2
2
|
<div class="page-menu page-table">
|
|
3
3
|
<div class="main-tool">
|
|
4
4
|
<div class="left">
|
|
5
|
-
<
|
|
5
|
+
<TinyButton type="primary" @click="$Method.onAction('add', {})">
|
|
6
6
|
<template #icon>
|
|
7
|
-
<
|
|
7
|
+
<IconLucidePlus />
|
|
8
8
|
</template>
|
|
9
9
|
添加菜单
|
|
10
|
-
</
|
|
10
|
+
</TinyButton>
|
|
11
11
|
</div>
|
|
12
12
|
<div class="right">
|
|
13
|
-
<
|
|
13
|
+
<TinyButton @click="$Method.handleRefresh">
|
|
14
14
|
<template #icon>
|
|
15
|
-
<
|
|
15
|
+
<IconLucideRotateCw />
|
|
16
16
|
</template>
|
|
17
17
|
刷新
|
|
18
|
-
</
|
|
18
|
+
</TinyButton>
|
|
19
19
|
</div>
|
|
20
20
|
</div>
|
|
21
21
|
<div class="main-table">
|
|
22
|
-
<
|
|
23
|
-
<
|
|
24
|
-
<
|
|
25
|
-
<
|
|
26
|
-
<
|
|
22
|
+
<TinyGrid :data="$Data.menuList" header-cell-class-name="custom-table-cell-class" size="small" height="100%" seq-serial>
|
|
23
|
+
<TinyGridColumn type="index" title="序号" :width="60" />
|
|
24
|
+
<TinyGridColumn field="name" title="菜单名称" />
|
|
25
|
+
<TinyGridColumn field="path" title="路径" :width="200" />
|
|
26
|
+
<TinyGridColumn field="icon" title="图标" :width="100">
|
|
27
27
|
<template #default="{ row }">
|
|
28
|
-
<
|
|
28
|
+
<IconLucideSquare v-if="row.icon" />
|
|
29
29
|
<span v-else>-</span>
|
|
30
30
|
</template>
|
|
31
|
-
</
|
|
32
|
-
<
|
|
33
|
-
<
|
|
31
|
+
</TinyGridColumn>
|
|
32
|
+
<TinyGridColumn field="sort" title="排序" :width="80" />
|
|
33
|
+
<TinyGridColumn field="state" title="状态" :width="100">
|
|
34
34
|
<template #default="{ row }">
|
|
35
|
-
<
|
|
36
|
-
<
|
|
37
|
-
<
|
|
35
|
+
<TinyTag v-if="row.state === 1" type="success">正常</TinyTag>
|
|
36
|
+
<TinyTag v-else-if="row.state === 2" type="warning">禁用</TinyTag>
|
|
37
|
+
<TinyTag v-else type="danger">已删除</TinyTag>
|
|
38
38
|
</template>
|
|
39
|
-
</
|
|
40
|
-
<
|
|
39
|
+
</TinyGridColumn>
|
|
40
|
+
<TinyGridColumn title="操作" :width="120" align="right">
|
|
41
41
|
<template #default="{ row }">
|
|
42
|
-
<
|
|
42
|
+
<TinyDropdown title="操作" trigger="click" size="small" border visible-arrow @item-click="(data) => $Method.onAction(data.itemData.command, row)">
|
|
43
43
|
<template #dropdown>
|
|
44
|
-
<
|
|
45
|
-
<
|
|
46
|
-
<
|
|
44
|
+
<TinyDropdownMenu>
|
|
45
|
+
<TinyDropdownItem :item-data="{ command: 'upd' }">
|
|
46
|
+
<IconLucidePencil />
|
|
47
47
|
编辑
|
|
48
|
-
</
|
|
49
|
-
<
|
|
50
|
-
<
|
|
48
|
+
</TinyDropdownItem>
|
|
49
|
+
<TinyDropdownItem :item-data="{ command: 'del' }" divided>
|
|
50
|
+
<IconLucideTrash2 style="width: 14px; height: 14px; margin-right: 6px" />
|
|
51
51
|
删除
|
|
52
|
-
</
|
|
53
|
-
</
|
|
52
|
+
</TinyDropdownItem>
|
|
53
|
+
</TinyDropdownMenu>
|
|
54
54
|
</template>
|
|
55
|
-
</
|
|
55
|
+
</TinyDropdown>
|
|
56
56
|
</template>
|
|
57
|
-
</
|
|
58
|
-
</
|
|
57
|
+
</TinyGridColumn>
|
|
58
|
+
</TinyGrid>
|
|
59
59
|
</div>
|
|
60
60
|
|
|
61
61
|
<div class="main-page">
|
|
62
|
-
<
|
|
62
|
+
<TinyPager :current-page="$Data.pagerConfig.currentPage" :page-size="$Data.pagerConfig.pageSize" :total="$Data.pagerConfig.total" @current-change="$Method.onPageChange" @size-change="$Method.handleSizeChange" />
|
|
63
63
|
</div>
|
|
64
64
|
|
|
65
65
|
<!-- 编辑对话框组件 -->
|
|
@@ -68,8 +68,12 @@
|
|
|
68
68
|
</template>
|
|
69
69
|
|
|
70
70
|
<script setup>
|
|
71
|
-
import {
|
|
72
|
-
import
|
|
71
|
+
import { Button as TinyButton, Grid as TinyGrid, GridColumn as TinyGridColumn, Tag as TinyTag, Dropdown as TinyDropdown, DropdownMenu as TinyDropdownMenu, DropdownItem as TinyDropdownItem, Pager as TinyPager, Modal } from '@opentiny/vue';
|
|
72
|
+
import IconLucidePlus from '~icons/lucide/plus';
|
|
73
|
+
import IconLucideRotateCw from '~icons/lucide/rotate-cw';
|
|
74
|
+
import IconLucideSquare from '~icons/lucide/square';
|
|
75
|
+
import IconLucidePencil from '~icons/lucide/pencil';
|
|
76
|
+
import IconLucideTrash2 from '~icons/lucide/trash-2';
|
|
73
77
|
|
|
74
78
|
import EditDialog from './components/edit.vue';
|
|
75
79
|
|