create-jnrs-template-vue 1.1.5 → 1.1.6
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/jnrs-template-vue/.prettierrc.json +1 -1
- package/jnrs-template-vue/auto-imports.d.ts +1 -0
- package/jnrs-template-vue/components.d.ts +10 -0
- package/jnrs-template-vue/package.json +1 -1
- package/jnrs-template-vue/public/system/menu.json +29 -9
- package/jnrs-template-vue/src/App.vue +2 -2
- package/jnrs-template-vue/src/api/{base → system}/index.ts +30 -6
- package/jnrs-template-vue/src/layout/RouterTabs.vue +1 -1
- package/jnrs-template-vue/src/layout/SideMenuItem.vue +1 -1
- package/jnrs-template-vue/src/layout/TopHeader.vue +11 -23
- package/jnrs-template-vue/src/layout/index.vue +35 -5
- package/jnrs-template-vue/src/main.ts +0 -2
- package/jnrs-template-vue/src/router/index.ts +10 -4
- package/jnrs-template-vue/src/types/index.d.ts +6 -0
- package/jnrs-template-vue/src/views/common/403.vue +2 -2
- package/jnrs-template-vue/src/views/common/404.vue +2 -2
- package/jnrs-template-vue/src/views/home/index.vue +2 -2
- package/jnrs-template-vue/src/views/login/index.vue +12 -17
- package/jnrs-template-vue/src/views/system/dict/index.vue +176 -0
- package/jnrs-template-vue/src/views/system/menu/index.vue +67 -0
- package/jnrs-template-vue/src/views/system/mine/baseInfo.vue +38 -30
- package/jnrs-template-vue/src/views/system/mine/securitySettings.vue +11 -19
- package/jnrs-template-vue/src/views/system/role/editDialog.vue +94 -0
- package/jnrs-template-vue/src/views/system/role/index.vue +30 -3
- package/jnrs-template-vue/vite.config.ts +2 -1
- package/jnrs-template-vue/viteMockServe/dictItemRes.json +27 -0
- package/jnrs-template-vue/viteMockServe/dictRes.json +141 -0
- package/jnrs-template-vue/viteMockServe/fail.ts +26 -0
- package/jnrs-template-vue/viteMockServe/index.ts +18 -25
- package/jnrs-template-vue/viteMockServe/{login.json → loginRes.json} +1 -0
- package/jnrs-template-vue/viteMockServe/success.ts +31 -0
- package/package.json +1 -1
- package/jnrs-template-vue/src/types/index.ts +0 -2
- package/jnrs-template-vue/src/views/system/user/index.vue +0 -9
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ElMessage } from 'element-plus'
|
|
3
|
+
import { ref, onActivated } from 'vue'
|
|
4
|
+
import { DictApi, DictDetailApi, DictChangeApi } from '@/api/system'
|
|
5
|
+
import { useAsyncTableHeight } from '@jnrs/vue-core/composables'
|
|
6
|
+
import type { DictItem } from '@jnrs/shared'
|
|
7
|
+
|
|
8
|
+
const { maxHeight } = useAsyncTableHeight('el_table_dict', 0)
|
|
9
|
+
const loading = ref(false)
|
|
10
|
+
const tableData = ref<DictItem[]>()
|
|
11
|
+
const predefineColors = ref([
|
|
12
|
+
'#000000',
|
|
13
|
+
'#999999',
|
|
14
|
+
'#f2f2f2',
|
|
15
|
+
'#ffffff',
|
|
16
|
+
'#65DC79',
|
|
17
|
+
'#5887F7',
|
|
18
|
+
'#E43634',
|
|
19
|
+
'#FEA822',
|
|
20
|
+
'#C9512C'
|
|
21
|
+
])
|
|
22
|
+
|
|
23
|
+
onActivated(() => {
|
|
24
|
+
getList()
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const getList = () => {
|
|
28
|
+
loading.value = true
|
|
29
|
+
DictApi()
|
|
30
|
+
.then((res) => {
|
|
31
|
+
tableData.value = res
|
|
32
|
+
})
|
|
33
|
+
.finally(() => {
|
|
34
|
+
loading.value = false
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const handleExpandChange = (row: DictItem) => {
|
|
39
|
+
loading.value = true
|
|
40
|
+
DictDetailApi(String(row.id))
|
|
41
|
+
.then((res) => {
|
|
42
|
+
row.options = res
|
|
43
|
+
})
|
|
44
|
+
.finally(() => {
|
|
45
|
+
loading.value = false
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 保存键值对
|
|
50
|
+
const editKeyValue = (row: DictItem) => {
|
|
51
|
+
if (!row.label) {
|
|
52
|
+
ElMessage({
|
|
53
|
+
type: 'warning',
|
|
54
|
+
message: 'label 不能为空'
|
|
55
|
+
})
|
|
56
|
+
return false
|
|
57
|
+
}
|
|
58
|
+
loading.value = true
|
|
59
|
+
DictChangeApi(row)
|
|
60
|
+
.then(() => {
|
|
61
|
+
ElMessage({
|
|
62
|
+
type: 'success',
|
|
63
|
+
message: '修改成功',
|
|
64
|
+
grouping: true
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
.finally(() => {
|
|
68
|
+
loading.value = false
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
<template>
|
|
74
|
+
<div class="main">
|
|
75
|
+
<el-card shadow="never">
|
|
76
|
+
<template #header>
|
|
77
|
+
<div class="card_header">
|
|
78
|
+
<h3>字典管理</h3>
|
|
79
|
+
</div>
|
|
80
|
+
</template>
|
|
81
|
+
<el-table
|
|
82
|
+
class="el_table_dict"
|
|
83
|
+
:data="tableData"
|
|
84
|
+
:height="maxHeight"
|
|
85
|
+
scrollbar-always-on
|
|
86
|
+
border
|
|
87
|
+
v-loading="loading"
|
|
88
|
+
row-key="id"
|
|
89
|
+
@expand-change="handleExpandChange"
|
|
90
|
+
>
|
|
91
|
+
<el-table-column prop="dictName" label="字典名" />
|
|
92
|
+
<el-table-column prop="describe" label="说明" />
|
|
93
|
+
<el-table-column type="expand" fixed="right" label="字典值" width="100">
|
|
94
|
+
<template #default="scope">
|
|
95
|
+
<div
|
|
96
|
+
class="table_expand animation15"
|
|
97
|
+
style="animation-duration: 0.5s; animation-delay: 0s"
|
|
98
|
+
>
|
|
99
|
+
<div class="table_expand_top">
|
|
100
|
+
<h5>字典值列表</h5>
|
|
101
|
+
</div>
|
|
102
|
+
<el-table :data="scope.row.options" :border="true" size="small" row-key="value">
|
|
103
|
+
<el-table-column
|
|
104
|
+
label="value"
|
|
105
|
+
prop="value"
|
|
106
|
+
width="100"
|
|
107
|
+
align="center"
|
|
108
|
+
></el-table-column>
|
|
109
|
+
<el-table-column label="label" prop="label">
|
|
110
|
+
<template #default="optionScope">
|
|
111
|
+
<el-input v-model="optionScope.row.label" maxlength="20" />
|
|
112
|
+
</template>
|
|
113
|
+
</el-table-column>
|
|
114
|
+
<el-table-column label="颜色" prop="displayColor">
|
|
115
|
+
<template #default="optionScope">
|
|
116
|
+
<el-color-picker
|
|
117
|
+
v-model="optionScope.row.displayColor"
|
|
118
|
+
:predefine="predefineColors"
|
|
119
|
+
/>
|
|
120
|
+
<span style="margin-left: 10px">
|
|
121
|
+
{{ optionScope.row.displayColor || '无' }}
|
|
122
|
+
</span>
|
|
123
|
+
</template>
|
|
124
|
+
</el-table-column>
|
|
125
|
+
<el-table-column prop="sequence" label="排序" width="180" align="center">
|
|
126
|
+
<template #default="optionScope">
|
|
127
|
+
<el-input-number
|
|
128
|
+
v-model="optionScope.row.sequence"
|
|
129
|
+
:min="1"
|
|
130
|
+
:max="999"
|
|
131
|
+
:step="1"
|
|
132
|
+
controls-position="right"
|
|
133
|
+
step-strictly
|
|
134
|
+
style="width: 140px"
|
|
135
|
+
/>
|
|
136
|
+
</template>
|
|
137
|
+
</el-table-column>
|
|
138
|
+
<el-table-column label="操作" width="100" align="center" fixed="right">
|
|
139
|
+
<template #default="optionScope">
|
|
140
|
+
<el-button type="success" size="small" @click="editKeyValue(optionScope.row)">
|
|
141
|
+
确认修改
|
|
142
|
+
</el-button>
|
|
143
|
+
</template>
|
|
144
|
+
</el-table-column>
|
|
145
|
+
</el-table>
|
|
146
|
+
</div>
|
|
147
|
+
</template>
|
|
148
|
+
</el-table-column>
|
|
149
|
+
</el-table>
|
|
150
|
+
</el-card>
|
|
151
|
+
</div>
|
|
152
|
+
</template>
|
|
153
|
+
|
|
154
|
+
<style scoped lang="scss">
|
|
155
|
+
.table_expand {
|
|
156
|
+
padding: 10px;
|
|
157
|
+
color: var(--jnrs-font-primary);
|
|
158
|
+
background: var(--jnrs-background-primary);
|
|
159
|
+
|
|
160
|
+
.table_expand_top {
|
|
161
|
+
position: relative;
|
|
162
|
+
|
|
163
|
+
h5 {
|
|
164
|
+
font-size: 14px;
|
|
165
|
+
margin-bottom: 10px;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.table_expand_top_btn {
|
|
169
|
+
position: absolute;
|
|
170
|
+
right: 0;
|
|
171
|
+
top: 0;
|
|
172
|
+
z-index: 1;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
</style>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import { useMenuStore } from '@/stores'
|
|
4
|
+
import { getDictLabel } from '@/utils/common'
|
|
5
|
+
import { useAsyncTableHeight } from '@jnrs/vue-core/composables'
|
|
6
|
+
|
|
7
|
+
const { maxHeight } = useAsyncTableHeight('el_table_menu', 0)
|
|
8
|
+
const loading = ref(false)
|
|
9
|
+
|
|
10
|
+
const { menus } = useMenuStore()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<div>
|
|
15
|
+
<el-card shadow="never">
|
|
16
|
+
<template #header>
|
|
17
|
+
<div class="card_header">
|
|
18
|
+
<h3>菜单管理</h3>
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
21
|
+
<el-table
|
|
22
|
+
class="el_table_menu"
|
|
23
|
+
:data="menus"
|
|
24
|
+
:height="maxHeight"
|
|
25
|
+
scrollbar-always-on
|
|
26
|
+
row-key="meta.uuid"
|
|
27
|
+
border
|
|
28
|
+
v-loading="loading"
|
|
29
|
+
>
|
|
30
|
+
<el-table-column prop="meta.title" label="名称" min-width="120" />
|
|
31
|
+
<el-table-column prop="path" label="路由地址" min-width="120" />
|
|
32
|
+
<el-table-column prop="role" label="权限" min-width="120">
|
|
33
|
+
<template #default="{ row }">
|
|
34
|
+
<span v-if="!row.meta.role" style="color: #999">auto</span>
|
|
35
|
+
<template v-else>
|
|
36
|
+
{{ row.meta.role.map((d: string | number) => getDictLabel('role', d)) }}
|
|
37
|
+
</template>
|
|
38
|
+
</template>
|
|
39
|
+
</el-table-column>
|
|
40
|
+
<el-table-column prop="editRole" label="操作权限" min-width="120">
|
|
41
|
+
<template #default="scope">
|
|
42
|
+
<template v-if="!scope.row.editRole">
|
|
43
|
+
<span style="color: #999" v-if="!scope.row.role">auto</span>
|
|
44
|
+
<!-- <template v-else>
|
|
45
|
+
{{ scope.row.role.map((d) => getDictLabel('role', d.split('Role')[1])) }}
|
|
46
|
+
</template> -->
|
|
47
|
+
</template>
|
|
48
|
+
<!-- <template v-else>
|
|
49
|
+
{{ scope.row.editRole.map((d) => getDictLabel('role', d.split('Role')[1])) }}
|
|
50
|
+
</template> -->
|
|
51
|
+
</template>
|
|
52
|
+
</el-table-column>
|
|
53
|
+
<el-table-column prop="type" label="类型" width="80" align="center">
|
|
54
|
+
<template #default="scope">
|
|
55
|
+
<el-tag type="primary" v-if="scope.row.path">菜单</el-tag>
|
|
56
|
+
<el-tag type="success" v-else>目录</el-tag>
|
|
57
|
+
</template>
|
|
58
|
+
</el-table-column>
|
|
59
|
+
<el-table-column prop="activate" label="图标" width="80" align="center">
|
|
60
|
+
<template #default="scope">
|
|
61
|
+
<el-icon v-if="scope.row.icon"><component :is="scope.row.icon" /></el-icon>
|
|
62
|
+
</template>
|
|
63
|
+
</el-table-column>
|
|
64
|
+
</el-table>
|
|
65
|
+
</el-card>
|
|
66
|
+
</div>
|
|
67
|
+
</template>
|
|
@@ -1,41 +1,32 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { ref } from 'vue'
|
|
2
|
+
import { ref, onMounted } from 'vue'
|
|
3
|
+
import { storeToRefs } from 'pinia'
|
|
3
4
|
import { ElMessage } from 'element-plus'
|
|
4
5
|
import type { UploadProps } from 'element-plus'
|
|
5
6
|
import { useAuthStore } from '@/stores'
|
|
6
7
|
import { useAvatar } from '@/composables/common/useAvatar'
|
|
8
|
+
import { getOneDictList } from '@/utils/common'
|
|
9
|
+
import type { User } from '@jnrs/shared'
|
|
7
10
|
|
|
8
|
-
const { userInfo, token } = useAuthStore()
|
|
11
|
+
const { userInfo, token } = storeToRefs(useAuthStore())
|
|
9
12
|
const { avatar } = useAvatar()
|
|
10
13
|
const loading = ref(false)
|
|
11
14
|
const ruleFormRef = ref()
|
|
12
|
-
const ruleForm = ref({
|
|
15
|
+
const ruleForm = ref<User>({
|
|
16
|
+
id: 0,
|
|
13
17
|
account: '',
|
|
14
18
|
name: '',
|
|
15
19
|
workNo: '',
|
|
16
|
-
jobTitle:
|
|
20
|
+
jobTitle: 0,
|
|
17
21
|
workgroup: '',
|
|
18
|
-
role:
|
|
22
|
+
role: 0,
|
|
23
|
+
avatarFileName: ''
|
|
19
24
|
})
|
|
20
25
|
const rules = ref({
|
|
21
26
|
// account: { required: true, message: '请输入', trigger: 'change' },
|
|
22
27
|
// role: { required: true, message: '请输入', trigger: 'change' },
|
|
23
28
|
// name: { required: true, message: '请输入', trigger: 'change' },
|
|
24
29
|
// workNo: { required: true, message: '请输入', trigger: 'change' },
|
|
25
|
-
// email: [
|
|
26
|
-
// { required: false, message: '请输入', trigger: 'change' },
|
|
27
|
-
// {
|
|
28
|
-
// validator: (rule, value, callback) => {
|
|
29
|
-
// if (value && !isEmail(value)) {
|
|
30
|
-
// callback(new Error('请输入有效的邮箱!'))
|
|
31
|
-
// } else {
|
|
32
|
-
// callback()
|
|
33
|
-
// }
|
|
34
|
-
// },
|
|
35
|
-
// required: false,
|
|
36
|
-
// trigger: 'blur'
|
|
37
|
-
// }
|
|
38
|
-
// ]
|
|
39
30
|
})
|
|
40
31
|
|
|
41
32
|
interface ApiResponse {
|
|
@@ -44,9 +35,15 @@ interface ApiResponse {
|
|
|
44
35
|
data: string
|
|
45
36
|
}
|
|
46
37
|
|
|
38
|
+
onMounted(() => {
|
|
39
|
+
if (userInfo.value) {
|
|
40
|
+
ruleForm.value = userInfo.value
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
47
44
|
const handleAvatarSuccess: UploadProps['onSuccess'] = (response: ApiResponse) => {
|
|
48
45
|
loading.value = false
|
|
49
|
-
if (response.code === 0) {
|
|
46
|
+
if (userInfo.value && response.code === 0) {
|
|
50
47
|
userInfo.value.avatarFileName = response.data
|
|
51
48
|
ElMessage.success({ message: '头像上传成功' })
|
|
52
49
|
}
|
|
@@ -69,28 +66,39 @@ const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
|
|
69
66
|
</script>
|
|
70
67
|
|
|
71
68
|
<template>
|
|
72
|
-
<el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="auto">
|
|
69
|
+
<el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="auto" disabled>
|
|
73
70
|
<el-form-item label="登录账号" prop="account">
|
|
74
|
-
<el-input v-model.trim="ruleForm.account" style="width: 200px"
|
|
71
|
+
<el-input v-model.trim="ruleForm.account" style="width: 200px" />
|
|
75
72
|
</el-form-item>
|
|
76
73
|
<el-form-item label="名称" prop="name">
|
|
77
|
-
<el-input v-model.trim="ruleForm.name" style="width: 200px"
|
|
74
|
+
<el-input v-model.trim="ruleForm.name" style="width: 200px" />
|
|
78
75
|
</el-form-item>
|
|
79
76
|
<el-form-item label="工号" prop="workNo">
|
|
80
|
-
<el-input v-model.trim="ruleForm.workNo" style="width: 200px"
|
|
77
|
+
<el-input v-model.trim="ruleForm.workNo" style="width: 200px" />
|
|
81
78
|
</el-form-item>
|
|
82
79
|
<el-form-item label="职称" prop="jobTitle">
|
|
83
|
-
<el-
|
|
80
|
+
<el-select v-model="ruleForm.jobTitle" style="width: 200px">
|
|
81
|
+
<el-option
|
|
82
|
+
:label="item.label"
|
|
83
|
+
:value="item.value"
|
|
84
|
+
v-for="(item, index) in getOneDictList('jobTitle')"
|
|
85
|
+
:key="index"
|
|
86
|
+
/>
|
|
87
|
+
</el-select>
|
|
84
88
|
</el-form-item>
|
|
85
89
|
<el-form-item label="部门/班组" prop="workgroup">
|
|
86
|
-
<el-input v-model.trim="ruleForm.workgroup" style="width: 200px"
|
|
90
|
+
<el-input v-model.trim="ruleForm.workgroup" style="width: 200px" />
|
|
87
91
|
</el-form-item>
|
|
88
92
|
<el-form-item label="职位/账号权限" prop="role">
|
|
89
|
-
<el-
|
|
93
|
+
<el-select v-model="ruleForm.role" style="width: 200px">
|
|
94
|
+
<el-option
|
|
95
|
+
:label="item.label"
|
|
96
|
+
:value="item.value"
|
|
97
|
+
v-for="(item, index) in getOneDictList('role')"
|
|
98
|
+
:key="index"
|
|
99
|
+
/>
|
|
100
|
+
</el-select>
|
|
90
101
|
</el-form-item>
|
|
91
|
-
<!-- <el-form-item label="邮箱" prop="email">
|
|
92
|
-
<el-input v-model.trim="ruleForm.email" style="width: 200px" />
|
|
93
|
-
</el-form-item> -->
|
|
94
102
|
<el-form-item label="头像" prop="avatarFileName" class="uploader_item">
|
|
95
103
|
<el-upload
|
|
96
104
|
action="/api/user/avatar"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { reactive, ref } from 'vue'
|
|
3
|
-
import {
|
|
3
|
+
import { PasswordChangeApi } from '@/api/system'
|
|
4
4
|
import { useAuthStore } from '@/stores'
|
|
5
5
|
import { handleRouter } from '@jnrs/vue-core/router'
|
|
6
6
|
import { isWeakPwd } from '@jnrs/shared/validator'
|
|
7
7
|
import type { FormInstance, FormItemRule } from 'element-plus'
|
|
8
8
|
import { ElMessage } from 'element-plus'
|
|
9
|
-
import { LogoutApi } from '@/api/
|
|
9
|
+
import { LogoutApi } from '@/api/system'
|
|
10
10
|
|
|
11
11
|
const { userInfo, asyncClearAuth } = useAuthStore()
|
|
12
12
|
const loading = ref(false)
|
|
@@ -45,22 +45,16 @@ const submitForm = async (formEl: FormInstance | undefined) => {
|
|
|
45
45
|
if (!formEl) return
|
|
46
46
|
try {
|
|
47
47
|
const valid = await formEl.validate()
|
|
48
|
-
if (valid) {
|
|
48
|
+
if (valid && userInfo?.id) {
|
|
49
49
|
loading.value = true
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
password: ruleForm.value.
|
|
50
|
+
await PasswordChangeApi({
|
|
51
|
+
userId: userInfo.id,
|
|
52
|
+
password: ruleForm.value.password
|
|
53
53
|
})
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
})
|
|
59
|
-
ElMessage.success('密码修改成功,请重新登录系统')
|
|
60
|
-
await LogoutApi()
|
|
61
|
-
await asyncClearAuth()
|
|
62
|
-
handleRouter({ name: 'Login' }, 'replace')
|
|
63
|
-
}
|
|
54
|
+
ElMessage.success('密码修改成功,请重新登录系统')
|
|
55
|
+
await LogoutApi()
|
|
56
|
+
await asyncClearAuth()
|
|
57
|
+
handleRouter({ name: 'Login' }, 'replace')
|
|
64
58
|
}
|
|
65
59
|
} catch {
|
|
66
60
|
} finally {
|
|
@@ -99,9 +93,7 @@ const submitForm = async (formEl: FormInstance | undefined) => {
|
|
|
99
93
|
/>
|
|
100
94
|
</el-form-item>
|
|
101
95
|
<el-form-item>
|
|
102
|
-
<el-button class="form_submit" type="primary" @click="submitForm(formRef)">
|
|
103
|
-
保存修改
|
|
104
|
-
</el-button>
|
|
96
|
+
<el-button class="form_submit" type="primary" @click="submitForm(formRef)">保存修改</el-button>
|
|
105
97
|
</el-form-item>
|
|
106
98
|
</el-form>
|
|
107
99
|
</template>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { FormInstance } from 'element-plus'
|
|
3
|
+
import { ref, nextTick } from 'vue'
|
|
4
|
+
defineOptions({
|
|
5
|
+
name: 'editDialog'
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
const loading = ref(false)
|
|
9
|
+
const dialogVisible = ref(false)
|
|
10
|
+
const ruleFormRef = ref<FormInstance>()
|
|
11
|
+
const ruleForm = ref({
|
|
12
|
+
id: '',
|
|
13
|
+
name: '',
|
|
14
|
+
enname: '',
|
|
15
|
+
remark: '',
|
|
16
|
+
usable: '1'
|
|
17
|
+
})
|
|
18
|
+
const rules = ref({
|
|
19
|
+
name: { required: true, message: '请输入角色名称', trigger: 'change' },
|
|
20
|
+
enname: { required: true, message: '请输入英文名称', trigger: 'change' },
|
|
21
|
+
usable: { required: true, message: '请选择是否可用', trigger: 'change' }
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const toggleVisible = () => {
|
|
25
|
+
dialogVisible.value = !dialogVisible.value
|
|
26
|
+
nextTick(() => {
|
|
27
|
+
ruleFormRef.value?.resetFields()
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const submitForm = () => {
|
|
32
|
+
if (!ruleFormRef.value) return
|
|
33
|
+
ruleFormRef.value.validate(async (valid) => {
|
|
34
|
+
if (!valid) return
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
defineExpose({
|
|
39
|
+
toggleVisible
|
|
40
|
+
})
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<template>
|
|
44
|
+
<el-dialog
|
|
45
|
+
v-model="dialogVisible"
|
|
46
|
+
width="600"
|
|
47
|
+
:append-to-body="true"
|
|
48
|
+
:close-on-click-modal="true"
|
|
49
|
+
:close-on-press-escape="true"
|
|
50
|
+
>
|
|
51
|
+
<template #header>
|
|
52
|
+
<h3>{{ ruleForm.id ? '修改' : '添加' }}角色</h3>
|
|
53
|
+
</template>
|
|
54
|
+
<el-form
|
|
55
|
+
ref="ruleFormRef"
|
|
56
|
+
:model="ruleForm"
|
|
57
|
+
:rules="rules"
|
|
58
|
+
label-width="auto"
|
|
59
|
+
v-loading="loading"
|
|
60
|
+
style="width: 80%; margin: 0 auto"
|
|
61
|
+
>
|
|
62
|
+
<el-form-item prop="id" v-show="false">
|
|
63
|
+
<el-input v-model="ruleForm.id" />
|
|
64
|
+
</el-form-item>
|
|
65
|
+
<el-form-item label="角色名称" prop="name">
|
|
66
|
+
<el-input v-model="ruleForm.name" maxlength="20" />
|
|
67
|
+
</el-form-item>
|
|
68
|
+
<el-form-item label="英文名称" prop="enname">
|
|
69
|
+
<el-input v-model="ruleForm.enname" maxlength="20" />
|
|
70
|
+
</el-form-item>
|
|
71
|
+
<el-form-item label="说明" prop="remark">
|
|
72
|
+
<el-input v-model="ruleForm.remark" maxlength="200" type="textarea" :rows="5" />
|
|
73
|
+
</el-form-item>
|
|
74
|
+
<el-form-item label="是否可用" prop="usable">
|
|
75
|
+
<el-switch
|
|
76
|
+
v-model="ruleForm.usable"
|
|
77
|
+
inline-prompt
|
|
78
|
+
active-text="是"
|
|
79
|
+
inactive-text="否"
|
|
80
|
+
:active-value="true"
|
|
81
|
+
:inactive-value="false"
|
|
82
|
+
width="50"
|
|
83
|
+
style="--el-switch-on-color: #67c23a; --el-switch-off-color: #f56c6c"
|
|
84
|
+
/>
|
|
85
|
+
</el-form-item>
|
|
86
|
+
</el-form>
|
|
87
|
+
<template #footer>
|
|
88
|
+
<div class="dialog-footer">
|
|
89
|
+
<el-button @click="toggleVisible()" :loading="loading">取消</el-button>
|
|
90
|
+
<el-button type="primary" @click="submitForm()" :loading="loading">提交</el-button>
|
|
91
|
+
</div>
|
|
92
|
+
</template>
|
|
93
|
+
</el-dialog>
|
|
94
|
+
</template>
|
|
@@ -1,9 +1,36 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref } from 'vue'
|
|
3
|
+
import { useAuthStore } from '@/stores'
|
|
4
|
+
|
|
5
|
+
const { dict } = useAuthStore()
|
|
6
|
+
const loading = ref(false)
|
|
7
|
+
const tableData = ref(dict?.role)
|
|
3
8
|
</script>
|
|
4
9
|
|
|
5
10
|
<template>
|
|
6
|
-
<div>
|
|
11
|
+
<div class="main">
|
|
12
|
+
<el-card shadow="never">
|
|
13
|
+
<template #header>
|
|
14
|
+
<div class="card_header">
|
|
15
|
+
<h3>角色管理</h3>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
<el-table
|
|
19
|
+
class="el_table_role"
|
|
20
|
+
header-cell-class-name="tableData_header_cell"
|
|
21
|
+
:data="tableData"
|
|
22
|
+
scrollbar-always-on
|
|
23
|
+
border
|
|
24
|
+
v-loading="loading"
|
|
25
|
+
>
|
|
26
|
+
<el-table-column prop="label" label="角色名称" align="center" />
|
|
27
|
+
<!-- <el-table-column prop="codeValue" label="系统权限" align="center" /> -->
|
|
28
|
+
<el-table-column prop="value" label="值" align="center">
|
|
29
|
+
<template #default="scope">
|
|
30
|
+
{{ scope.row.value + '[' + typeof scope.row.value + ']' }}
|
|
31
|
+
</template>
|
|
32
|
+
</el-table-column>
|
|
33
|
+
</el-table>
|
|
34
|
+
</el-card>
|
|
35
|
+
</div>
|
|
7
36
|
</template>
|
|
8
|
-
|
|
9
|
-
<style lang="scss" scoped></style>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": [
|
|
3
|
+
{
|
|
4
|
+
"id": 7,
|
|
5
|
+
"value": 0,
|
|
6
|
+
"label": "未审批",
|
|
7
|
+
"displayColor": "#FEA822",
|
|
8
|
+
"sequence": 1
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": 8,
|
|
12
|
+
"value": 1,
|
|
13
|
+
"label": "未通过",
|
|
14
|
+
"displayColor": "#E43634",
|
|
15
|
+
"sequence": 2
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": 9,
|
|
19
|
+
"value": 2,
|
|
20
|
+
"label": "已通过",
|
|
21
|
+
"displayColor": "#65DC79",
|
|
22
|
+
"sequence": 3
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"code": 0,
|
|
26
|
+
"msg": "操作成功"
|
|
27
|
+
}
|