@befly-addon/admin 1.0.37 → 1.0.38
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/apis/admin/del.ts +1 -5
- package/apis/admin/ins.ts +2 -6
- package/apis/admin/list.ts +5 -0
- package/apis/admin/roleDetail.ts +1 -5
- package/apis/admin/roleSave.ts +1 -5
- package/apis/admin/upd.ts +1 -6
- package/apis/api/all.ts +1 -6
- package/apis/auth/login.ts +1 -5
- package/apis/auth/logout.ts +1 -5
- package/apis/auth/register.ts +1 -5
- package/apis/auth/sendSmsCode.ts +1 -5
- package/apis/dashboard/changelog.ts +1 -5
- package/apis/dashboard/configStatus.ts +1 -5
- package/apis/dashboard/environmentInfo.ts +1 -5
- package/apis/dashboard/performanceMetrics.ts +1 -5
- package/apis/dashboard/permissionStats.ts +1 -5
- package/apis/dashboard/serviceStatus.ts +1 -5
- package/apis/dashboard/systemInfo.ts +1 -5
- package/apis/dashboard/systemOverview.ts +1 -5
- package/apis/dashboard/systemResources.ts +1 -5
- package/apis/dict/all.ts +0 -3
- package/apis/menu/del.ts +1 -5
- package/apis/role/all.ts +18 -0
- package/apis/role/apiDetail.ts +1 -5
- package/apis/role/apiSave.ts +1 -5
- package/apis/role/del.ts +1 -5
- package/apis/role/detail.ts +1 -5
- package/apis/role/ins.ts +0 -3
- package/apis/role/list.ts +5 -0
- package/apis/role/menuDetail.ts +1 -5
- package/apis/role/menuSave.ts +1 -5
- package/apis/role/save.ts +1 -5
- package/package.json +5 -3
- package/styles/variables.scss +87 -0
- package/tables/admin.json +2 -8
- package/views/403/index.vue +20 -30
- package/views/admin/components/edit.vue +73 -48
- package/views/admin/index.vue +128 -48
- package/views/dict/index.vue +0 -2
- package/views/index/components/addonList.vue +20 -14
- package/views/index/components/environmentInfo.vue +6 -6
- package/views/index/components/operationLogs.vue +9 -9
- package/views/index/components/performanceMetrics.vue +22 -32
- package/views/index/components/serviceStatus.vue +14 -14
- package/views/index/components/systemNotifications.vue +21 -21
- package/views/index/components/systemOverview.vue +24 -24
- package/views/index/components/systemResources.vue +4 -4
- package/views/index/components/userInfo.vue +7 -7
- package/views/index/index.vue +0 -2
- package/views/login/components/emailLoginForm.vue +46 -46
- package/views/login/index_1.vue +158 -121
- package/views/role/components/api.vue +11 -9
- package/views/role/components/edit.vue +13 -2
- package/views/role/index.vue +0 -2
- package/utils/scanBeflyAddonViews.js +0 -43
- package/views/admin/components/role.vue +0 -138
- /package/apis/admin/{info.ts → detail.ts} +0 -0
package/views/login/index_1.vue
CHANGED
|
@@ -1,189 +1,226 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="
|
|
3
|
-
<!--
|
|
4
|
-
<div class="left-
|
|
5
|
-
<
|
|
2
|
+
<div class="login-container">
|
|
3
|
+
<!-- 左侧装饰区域 -->
|
|
4
|
+
<div class="left-section">
|
|
5
|
+
<div class="bg-decoration">
|
|
6
|
+
<div class="circle circle-1"></div>
|
|
7
|
+
<div class="circle circle-2"></div>
|
|
8
|
+
<div class="circle circle-3"></div>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="welcome-content">
|
|
11
|
+
<h1 class="brand-title">Befly</h1>
|
|
12
|
+
<p class="brand-subtitle">轻量级业务快速开发框架</p>
|
|
13
|
+
</div>
|
|
6
14
|
</div>
|
|
7
15
|
|
|
8
|
-
<!--
|
|
9
|
-
<div class="right-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
<!-- 右侧登录区域 -->
|
|
17
|
+
<div class="right-section">
|
|
18
|
+
<div class="login-box">
|
|
19
|
+
<div class="login-header">
|
|
20
|
+
<h2 class="login-title">欢迎回来</h2>
|
|
21
|
+
<p class="login-subtitle">请登录您的账户</p>
|
|
22
|
+
</div>
|
|
13
23
|
|
|
14
|
-
<!-- 邮箱登录 -->
|
|
15
24
|
<EmailLoginForm />
|
|
16
|
-
</div>
|
|
17
|
-
|
|
18
|
-
<!-- 注册表单 -->
|
|
19
|
-
<div class="form-container sign-up-form" :class="{ active: $Data.isSignUp }">
|
|
20
|
-
<h2 class="form-title">注册账号</h2>
|
|
21
25
|
|
|
22
|
-
<
|
|
26
|
+
<div class="login-footer">
|
|
27
|
+
<p class="copyright">© 2024 Befly. All rights reserved.</p>
|
|
28
|
+
</div>
|
|
23
29
|
</div>
|
|
24
30
|
</div>
|
|
25
31
|
</div>
|
|
26
32
|
</template>
|
|
27
33
|
|
|
28
34
|
<script setup>
|
|
29
|
-
import WelcomePanel from './components/welcomePanel.vue';
|
|
30
35
|
import EmailLoginForm from './components/emailLoginForm.vue';
|
|
31
|
-
import RegisterForm from './components/registerForm.vue';
|
|
32
|
-
|
|
33
|
-
// 数据定义
|
|
34
|
-
const $Data = $ref({
|
|
35
|
-
isSignUp: false
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// 方法定义
|
|
39
|
-
const $Method = {
|
|
40
|
-
// 切换登录/注册模式
|
|
41
|
-
toggleMode() {
|
|
42
|
-
$Data.isSignUp = !$Data.isSignUp;
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
// 注册成功后切换到登录模式
|
|
46
|
-
handleRegisterSuccess() {
|
|
47
|
-
$Data.isSignUp = false;
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
36
|
</script>
|
|
51
37
|
|
|
52
38
|
<style scoped lang="scss">
|
|
53
|
-
.
|
|
39
|
+
.login-container {
|
|
54
40
|
display: flex;
|
|
55
41
|
width: 100%;
|
|
56
42
|
min-height: 100vh;
|
|
57
|
-
|
|
58
|
-
position: relative;
|
|
59
|
-
background: #fff;
|
|
43
|
+
background: var(--login-bg);
|
|
60
44
|
}
|
|
61
45
|
|
|
62
|
-
//
|
|
63
|
-
.left-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
left: 0;
|
|
67
|
-
width: 50%;
|
|
68
|
-
height: 100%;
|
|
46
|
+
// 左侧装饰区域
|
|
47
|
+
.left-section {
|
|
48
|
+
flex: 1;
|
|
49
|
+
position: relative;
|
|
69
50
|
display: flex;
|
|
70
51
|
align-items: center;
|
|
71
52
|
justify-content: center;
|
|
72
|
-
background: linear-gradient(135deg,
|
|
73
|
-
|
|
74
|
-
z-index: 5;
|
|
75
|
-
transition: transform 0.5s ease-in-out;
|
|
53
|
+
background: linear-gradient(135deg, var(--login-left-gradient-start) 0%, var(--login-left-gradient-end) 100%);
|
|
54
|
+
overflow: hidden;
|
|
76
55
|
}
|
|
77
56
|
|
|
78
|
-
|
|
79
|
-
.right-panel {
|
|
57
|
+
.bg-decoration {
|
|
80
58
|
position: absolute;
|
|
81
59
|
width: 100%;
|
|
82
60
|
height: 100%;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
61
|
+
overflow: hidden;
|
|
62
|
+
|
|
63
|
+
.circle {
|
|
64
|
+
position: absolute;
|
|
65
|
+
border-radius: 50%;
|
|
66
|
+
background: var(--login-circle-bg);
|
|
67
|
+
animation: float 20s infinite ease-in-out;
|
|
68
|
+
|
|
69
|
+
&.circle-1 {
|
|
70
|
+
width: 400px;
|
|
71
|
+
height: 400px;
|
|
72
|
+
top: -100px;
|
|
73
|
+
left: -100px;
|
|
74
|
+
animation-delay: 0s;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
&.circle-2 {
|
|
78
|
+
width: 300px;
|
|
79
|
+
height: 300px;
|
|
80
|
+
bottom: -50px;
|
|
81
|
+
right: -50px;
|
|
82
|
+
animation-delay: 7s;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
&.circle-3 {
|
|
86
|
+
width: 200px;
|
|
87
|
+
height: 200px;
|
|
88
|
+
top: 50%;
|
|
89
|
+
right: 10%;
|
|
90
|
+
animation-delay: 14s;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
86
93
|
}
|
|
87
94
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
transform:
|
|
95
|
+
@keyframes float {
|
|
96
|
+
0%,
|
|
97
|
+
100% {
|
|
98
|
+
transform: translateY(0) scale(1);
|
|
99
|
+
}
|
|
100
|
+
50% {
|
|
101
|
+
transform: translateY(-20px) scale(1.05);
|
|
92
102
|
}
|
|
93
103
|
}
|
|
94
104
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
105
|
+
.welcome-content {
|
|
106
|
+
position: relative;
|
|
107
|
+
z-index: 1;
|
|
108
|
+
color: #fff;
|
|
109
|
+
text-align: center;
|
|
110
|
+
padding: 2rem;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.brand-title {
|
|
114
|
+
font-size: 4rem;
|
|
115
|
+
font-weight: 700;
|
|
116
|
+
margin-bottom: 1rem;
|
|
117
|
+
letter-spacing: 2px;
|
|
118
|
+
color: var(--login-brand-title);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.brand-subtitle {
|
|
122
|
+
font-size: 1.25rem;
|
|
123
|
+
margin-bottom: 3rem;
|
|
124
|
+
color: var(--login-brand-subtitle);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 右侧登录区域
|
|
128
|
+
.right-section {
|
|
129
|
+
flex: 1;
|
|
101
130
|
display: flex;
|
|
102
|
-
flex-direction: column;
|
|
103
131
|
align-items: center;
|
|
104
132
|
justify-content: center;
|
|
105
|
-
padding:
|
|
106
|
-
opacity: 0;
|
|
107
|
-
pointer-events: none;
|
|
108
|
-
transition: all 0.5s ease-in-out;
|
|
109
|
-
|
|
110
|
-
&.active {
|
|
111
|
-
opacity: 1;
|
|
112
|
-
pointer-events: all;
|
|
113
|
-
}
|
|
133
|
+
padding: 2rem;
|
|
114
134
|
}
|
|
115
135
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
136
|
+
.login-box {
|
|
137
|
+
width: 100%;
|
|
138
|
+
max-width: 440px;
|
|
139
|
+
background: var(--login-card-bg);
|
|
140
|
+
border: 1px solid var(--login-card-border);
|
|
141
|
+
border-radius: 16px;
|
|
142
|
+
box-shadow: 0 10px 40px var(--login-card-shadow);
|
|
143
|
+
padding: 3rem 2.5rem;
|
|
144
|
+
}
|
|
121
145
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
146
|
+
.login-header {
|
|
147
|
+
text-align: center;
|
|
148
|
+
margin-bottom: 2.5rem;
|
|
125
149
|
}
|
|
126
150
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
151
|
+
.login-title {
|
|
152
|
+
font-size: 2rem;
|
|
153
|
+
font-weight: 600;
|
|
154
|
+
color: var(--login-title);
|
|
155
|
+
margin-bottom: 0.5rem;
|
|
156
|
+
}
|
|
132
157
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
158
|
+
.login-subtitle {
|
|
159
|
+
font-size: 1rem;
|
|
160
|
+
color: var(--login-subtitle);
|
|
136
161
|
}
|
|
137
162
|
|
|
138
|
-
.
|
|
139
|
-
|
|
140
|
-
color: #333;
|
|
141
|
-
margin-bottom: 1.5rem;
|
|
142
|
-
font-weight: 600;
|
|
163
|
+
.login-footer {
|
|
164
|
+
margin-top: 2rem;
|
|
143
165
|
text-align: center;
|
|
144
|
-
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.copyright {
|
|
169
|
+
font-size: 0.875rem;
|
|
170
|
+
color: var(--login-subtitle);
|
|
145
171
|
}
|
|
146
172
|
|
|
147
173
|
// 响应式设计
|
|
148
|
-
@media (max-width:
|
|
149
|
-
.
|
|
174
|
+
@media (max-width: 1024px) {
|
|
175
|
+
.login-container {
|
|
150
176
|
flex-direction: column;
|
|
151
177
|
}
|
|
152
178
|
|
|
153
|
-
.left-
|
|
154
|
-
|
|
179
|
+
.left-section {
|
|
180
|
+
min-height: 300px;
|
|
155
181
|
flex: none;
|
|
156
|
-
width: 100%;
|
|
157
182
|
}
|
|
158
183
|
|
|
159
|
-
.
|
|
160
|
-
|
|
161
|
-
|
|
184
|
+
.brand-title {
|
|
185
|
+
font-size: 3rem;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.right-section {
|
|
189
|
+
flex: 1;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@media (max-width: 768px) {
|
|
194
|
+
.left-section {
|
|
162
195
|
min-height: 200px;
|
|
163
196
|
}
|
|
164
197
|
|
|
165
|
-
.
|
|
166
|
-
|
|
167
|
-
min-height: 500px;
|
|
198
|
+
.brand-title {
|
|
199
|
+
font-size: 2.5rem;
|
|
168
200
|
}
|
|
169
201
|
|
|
170
|
-
.
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
position: static;
|
|
202
|
+
.brand-subtitle {
|
|
203
|
+
font-size: 1rem;
|
|
204
|
+
margin-bottom: 2rem;
|
|
174
205
|
}
|
|
175
206
|
|
|
176
|
-
.
|
|
177
|
-
.
|
|
178
|
-
|
|
179
|
-
|
|
207
|
+
.login-box {
|
|
208
|
+
padding: 2rem 1.5rem;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.login-title {
|
|
212
|
+
font-size: 1.75rem;
|
|
180
213
|
}
|
|
181
214
|
}
|
|
182
215
|
|
|
183
|
-
@media (max-width:
|
|
184
|
-
.
|
|
185
|
-
|
|
186
|
-
|
|
216
|
+
@media (max-width: 480px) {
|
|
217
|
+
.right-section {
|
|
218
|
+
padding: 1rem;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.login-box {
|
|
222
|
+
padding: 1.5rem 1rem;
|
|
223
|
+
border-radius: 12px;
|
|
187
224
|
}
|
|
188
225
|
}
|
|
189
226
|
</style>
|
|
@@ -214,8 +214,8 @@ $Method.initData();
|
|
|
214
214
|
|
|
215
215
|
.api-group {
|
|
216
216
|
margin-bottom: 16px;
|
|
217
|
-
border: 1px solid
|
|
218
|
-
border-radius:
|
|
217
|
+
border: 1px solid var(--border-color);
|
|
218
|
+
border-radius: var(--border-radius-small);
|
|
219
219
|
overflow: hidden;
|
|
220
220
|
|
|
221
221
|
&:last-child {
|
|
@@ -224,10 +224,10 @@ $Method.initData();
|
|
|
224
224
|
|
|
225
225
|
.group-header {
|
|
226
226
|
padding: 12px 16px;
|
|
227
|
-
background-color:
|
|
227
|
+
background-color: var(--bg-color-hover);
|
|
228
228
|
font-weight: 500;
|
|
229
|
-
font-size:
|
|
230
|
-
color:
|
|
229
|
+
font-size: var(--font-size-sm);
|
|
230
|
+
color: var(--text-primary);
|
|
231
231
|
display: flex;
|
|
232
232
|
align-items: center;
|
|
233
233
|
gap: 8px;
|
|
@@ -237,15 +237,17 @@ $Method.initData();
|
|
|
237
237
|
width: 8px;
|
|
238
238
|
height: 8px;
|
|
239
239
|
border-radius: 50%;
|
|
240
|
-
background-color:
|
|
240
|
+
background-color: var(--primary-color);
|
|
241
241
|
opacity: 0.3;
|
|
242
242
|
flex-shrink: 0;
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
.api-
|
|
247
|
-
padding: 16px;
|
|
248
|
-
|
|
246
|
+
.api-item {
|
|
247
|
+
padding: 8px 16px;
|
|
248
|
+
cursor: pointer;
|
|
249
|
+
transition: background-color 0.2s;
|
|
250
|
+
background-color: var(--bg-color-container);
|
|
249
251
|
|
|
250
252
|
:deep(.t-checkbox-group) {
|
|
251
253
|
display: flex;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<TDialog v-model:visible="$Data.visible" :
|
|
2
|
+
<TDialog v-model:visible="$Data.visible" :header="$Prop.actionType === 'upd' ? '更新角色' : '添加角色'" width="600px" :append-to-body="true" :show-footer="true" :esc-closable="false" top="10vh" @close="$Method.onClose">
|
|
3
3
|
<div class="comp-role-edit">
|
|
4
4
|
<TForm :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" :ref="(el) => ($From.form = el)">
|
|
5
5
|
<TFormItem label="角色名称" prop="name">
|
|
@@ -30,7 +30,18 @@
|
|
|
30
30
|
</template>
|
|
31
31
|
|
|
32
32
|
<script setup>
|
|
33
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
//
|
|
35
|
+
Dialog as TDialog,
|
|
36
|
+
Form as TForm,
|
|
37
|
+
FormItem as TFormItem,
|
|
38
|
+
Input as TInput,
|
|
39
|
+
InputNumber as TInputNumber,
|
|
40
|
+
RadioGroup as TRadioGroup,
|
|
41
|
+
Radio as TRadio,
|
|
42
|
+
Button as TButton,
|
|
43
|
+
MessagePlugin
|
|
44
|
+
} from 'tdesign-vue-next';
|
|
34
45
|
import { $Http } from '@/plugins/http';
|
|
35
46
|
|
|
36
47
|
const $Prop = defineProps({
|
package/views/role/index.vue
CHANGED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { readdirSync, existsSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 扫描所有 @befly-addon 包的 views 目录
|
|
6
|
-
* 用于 unplugin-vue-router 的 routesFolder 配置
|
|
7
|
-
* 注意:此函数只能在 vite.config.ts 中使用(Node.js 环境),不能在浏览器中使用
|
|
8
|
-
* @returns 路由文件夹配置数组
|
|
9
|
-
*/
|
|
10
|
-
export function scanBeflyAddonViews() {
|
|
11
|
-
// 使用绝对路径:基于项目根目录(process.cwd())
|
|
12
|
-
const projectRoot = process.cwd();
|
|
13
|
-
const addonBasePath = join(projectRoot, 'node_modules', '@befly-addon');
|
|
14
|
-
const routesFolders = [];
|
|
15
|
-
|
|
16
|
-
if (!existsSync(addonBasePath)) {
|
|
17
|
-
return routesFolders;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
const addonDirs = readdirSync(addonBasePath);
|
|
22
|
-
|
|
23
|
-
for (const addonName of addonDirs) {
|
|
24
|
-
const addonPath = join(addonBasePath, addonName);
|
|
25
|
-
|
|
26
|
-
// 检查是否为目录(包括符号链接)
|
|
27
|
-
if (!existsSync(addonPath)) continue;
|
|
28
|
-
|
|
29
|
-
const viewsPath = join(addonPath, 'views');
|
|
30
|
-
|
|
31
|
-
if (existsSync(viewsPath)) {
|
|
32
|
-
routesFolders.push({
|
|
33
|
-
src: viewsPath,
|
|
34
|
-
path: `addon/${addonName}/`
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
} catch (error) {
|
|
39
|
-
console.error('扫描 @befly-addon 目录失败:', error);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return routesFolders;
|
|
43
|
-
}
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<TDialog v-model:visible="$Data.visible" title="分配角色" width="600px" :append-to-body="true" :show-footer="true" :esc-closable="false" top="20vh" @close="$Method.onClose">
|
|
3
|
-
<div class="role-dialog">
|
|
4
|
-
<div class="user-info">
|
|
5
|
-
<TTag type="info">{{ $Prop.rowData.username }}</TTag>
|
|
6
|
-
<span class="user-email">{{ $Prop.rowData.email }}</span>
|
|
7
|
-
</div>
|
|
8
|
-
<TDivider />
|
|
9
|
-
<TSelect v-model="$Data.checkedRoleCode" :options="$Data.roleOptions" placeholder="请选择角色" />
|
|
10
|
-
</div>
|
|
11
|
-
<template #footer>
|
|
12
|
-
<TButton @click="$Method.onClose">取消</TButton>
|
|
13
|
-
<TButton theme="primary" @click="$Method.onSubmit">确定</TButton>
|
|
14
|
-
</template>
|
|
15
|
-
</TDialog>
|
|
16
|
-
</template>
|
|
17
|
-
|
|
18
|
-
<script setup>
|
|
19
|
-
import { Dialog as TDialog, Tag as TTag, Divider as TDivider, Select as TSelect, Button as TButton, MessagePlugin } from 'tdesign-vue-next';
|
|
20
|
-
import { $Http } from '@/plugins/http';
|
|
21
|
-
|
|
22
|
-
const $Prop = defineProps({
|
|
23
|
-
modelValue: {
|
|
24
|
-
type: Boolean,
|
|
25
|
-
default: false
|
|
26
|
-
},
|
|
27
|
-
rowData: {
|
|
28
|
-
type: Object,
|
|
29
|
-
default: {}
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const $Emit = defineEmits(['update:modelValue', 'success']);
|
|
34
|
-
|
|
35
|
-
const $Data = $ref({
|
|
36
|
-
visible: false,
|
|
37
|
-
roleOptions: [],
|
|
38
|
-
checkedRoleCode: ''
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
// 方法集合
|
|
42
|
-
const $Method = {
|
|
43
|
-
async initData() {
|
|
44
|
-
$Method.onShow();
|
|
45
|
-
await Promise.all([$Method.apiRoleList(), $Method.apiAdminRoleDetail()]);
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
onShow() {
|
|
49
|
-
setTimeout(() => {
|
|
50
|
-
$Data.visible = $Prop.modelValue;
|
|
51
|
-
}, 100);
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
onClose() {
|
|
55
|
-
$Data.visible = false;
|
|
56
|
-
setTimeout(() => {
|
|
57
|
-
$Emit('update:modelValue', false);
|
|
58
|
-
}, 300);
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
// 加载角色列表
|
|
62
|
-
async apiRoleList() {
|
|
63
|
-
try {
|
|
64
|
-
const res = await $Http('/addon/admin/role/list', {
|
|
65
|
-
page: 1,
|
|
66
|
-
limit: 1000
|
|
67
|
-
});
|
|
68
|
-
const roleList = res.data.lists || [];
|
|
69
|
-
$Data.roleOptions = roleList
|
|
70
|
-
.filter((role) => role.state === 1)
|
|
71
|
-
.map((role) => ({
|
|
72
|
-
label: role.name,
|
|
73
|
-
value: role.code
|
|
74
|
-
}));
|
|
75
|
-
} catch (error) {
|
|
76
|
-
console.error('加载角色列表失败:', error);
|
|
77
|
-
MessagePlugin.info({ message: '加载角色列表失败', status: 'error' });
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
// 加载管理员角色
|
|
82
|
-
async apiAdminRoleDetail() {
|
|
83
|
-
if (!$Prop.rowData.id) return;
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
const res = await $Http('/addon/admin/admin/roleDetail', {
|
|
87
|
-
adminId: $Prop.rowData.id
|
|
88
|
-
});
|
|
89
|
-
$Data.checkedRoleCode = res.data.roleCode || '';
|
|
90
|
-
} catch (error) {
|
|
91
|
-
console.error('加载用户角色失败:', error);
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
|
|
95
|
-
// 提交角色分配
|
|
96
|
-
async onSubmit() {
|
|
97
|
-
if (!$Data.checkedRoleCode) {
|
|
98
|
-
MessagePlugin.info({ message: '请选择角色', status: 'warning' });
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
try {
|
|
103
|
-
const res = await $Http('/addon/admin/admin/roleSave', {
|
|
104
|
-
adminId: $Prop.rowData.id,
|
|
105
|
-
roleCode: $Data.checkedRoleCode
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
if (res.code === 0) {
|
|
109
|
-
MessagePlugin.info({ message: '角色分配成功', status: 'success' });
|
|
110
|
-
$Method.onClose();
|
|
111
|
-
$Emit('success');
|
|
112
|
-
} else {
|
|
113
|
-
MessagePlugin.info({ message: res.msg || '分配失败', status: 'error' });
|
|
114
|
-
}
|
|
115
|
-
} catch (error) {
|
|
116
|
-
console.error('分配失败:', error);
|
|
117
|
-
MessagePlugin.info({ message: '分配失败', status: 'error' });
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
$Method.initData();
|
|
123
|
-
</script>
|
|
124
|
-
|
|
125
|
-
<style scoped lang="scss">
|
|
126
|
-
.role-dialog {
|
|
127
|
-
.user-info {
|
|
128
|
-
display: flex;
|
|
129
|
-
align-items: center;
|
|
130
|
-
gap: 12px;
|
|
131
|
-
margin-bottom: 16px;
|
|
132
|
-
|
|
133
|
-
.user-email {
|
|
134
|
-
color: $text-secondary;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
</style>
|
|
File without changes
|