zant-admin 1.0.0
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/README.en.md +36 -0
- package/README.md +248 -0
- package/SCAFFOLD_README.md +215 -0
- package/bin/cli.js +99 -0
- package/bin/generator.js +503 -0
- package/bin/prompts.js +159 -0
- package/bin/utils.js +134 -0
- package/package.json +74 -0
- package/public/logo.png +0 -0
- package/src/App.vue +16 -0
- package/src/api/methods/logError.js +8 -0
- package/src/api/methods/logOperation.js +8 -0
- package/src/api/methods/login.js +6 -0
- package/src/api/methods/quartz.js +36 -0
- package/src/api/methods/region.js +16 -0
- package/src/api/methods/sysAccount.js +30 -0
- package/src/api/methods/sysDict.js +29 -0
- package/src/api/methods/sysDictItem.js +26 -0
- package/src/api/methods/sysMenu.js +42 -0
- package/src/api/methods/sysRole.js +35 -0
- package/src/api/methods/sysUser.js +25 -0
- package/src/api/methods/system.js +16 -0
- package/src/api/request.js +225 -0
- package/src/assets/css/style.css +70 -0
- package/src/assets/css/zcui.css +340 -0
- package/src/assets/imgs/loginbackground.svg +69 -0
- package/src/assets/imgs/logo.png +0 -0
- package/src/assets/imgs/md/1.png +0 -0
- package/src/assets/imgs/md/10.png +0 -0
- package/src/assets/imgs/md/11.png +0 -0
- package/src/assets/imgs/md/2.png +0 -0
- package/src/assets/imgs/md/3.png +0 -0
- package/src/assets/imgs/md/4.png +0 -0
- package/src/assets/imgs/md/5.png +0 -0
- package/src/assets/imgs/md/6.png +0 -0
- package/src/assets/imgs/md/7.png +0 -0
- package/src/assets/imgs/md/8.png +0 -0
- package/src/assets/imgs/md/9.png +0 -0
- package/src/components/FormTable.vue +875 -0
- package/src/components/IconPicker.vue +344 -0
- package/src/components/MainPage.vue +957 -0
- package/src/components/details/logErrorDetails.vue +58 -0
- package/src/components/details/logOperationDetails.vue +76 -0
- package/src/components/edit/QuartzEdit.vue +221 -0
- package/src/components/edit/SysAccountEdit.vue +178 -0
- package/src/components/edit/SysDictEdit.vue +114 -0
- package/src/components/edit/SysDictItemEdit.vue +134 -0
- package/src/components/edit/SysRoleEdit.vue +109 -0
- package/src/components/edit/sysMenuEdit.vue +305 -0
- package/src/config/index.js +74 -0
- package/src/directives/permission.js +45 -0
- package/src/main.js +38 -0
- package/src/router/index.js +270 -0
- package/src/stores/config.js +37 -0
- package/src/stores/dict.js +33 -0
- package/src/stores/menu.js +57 -0
- package/src/stores/user.js +21 -0
- package/src/utils/baseEcharts.js +661 -0
- package/src/utils/dictTemplate.js +26 -0
- package/src/utils/regionUtils.js +169 -0
- package/src/utils/useFormCRUD.js +60 -0
- package/src/views/baiscstatis/center.vue +463 -0
- package/src/views/baiscstatis/iframePage.vue +31 -0
- package/src/views/baiscstatis/notFound.vue +192 -0
- package/src/views/console.vue +771 -0
- package/src/views/demo/importexport.vue +123 -0
- package/src/views/demo/region.vue +240 -0
- package/src/views/demo/statistics.vue +195 -0
- package/src/views/home.vue +7 -0
- package/src/views/login.vue +272 -0
- package/src/views/operations/log/logError.vue +78 -0
- package/src/views/operations/log/logLogin.vue +66 -0
- package/src/views/operations/log/logOperation.vue +103 -0
- package/src/views/operations/log/logQuartz.vue +57 -0
- package/src/views/operations/quartz.vue +181 -0
- package/src/views/operations/serviceMonitoring.vue +134 -0
- package/src/views/system/sysAccount.vue +123 -0
- package/src/views/system/sysDict.vue +156 -0
- package/src/views/system/sysDictItem.vue +118 -0
- package/src/views/system/sysMenu.vue +223 -0
- package/src/views/system/sysRole.vue +184 -0
- package/templates/env.production +2 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<a-modal
|
|
3
|
+
:open="open"
|
|
4
|
+
title="详情"
|
|
5
|
+
width="60%"
|
|
6
|
+
wrap-class-name="full-modal"
|
|
7
|
+
@cancel="onClose"
|
|
8
|
+
>
|
|
9
|
+
<a-descriptions title="" bordered :column="2">
|
|
10
|
+
<a-descriptions-item label="ID">
|
|
11
|
+
{{ info.id }}
|
|
12
|
+
</a-descriptions-item>
|
|
13
|
+
<a-descriptions-item label="方法">
|
|
14
|
+
{{ info.actionName }}
|
|
15
|
+
</a-descriptions-item>
|
|
16
|
+
<a-descriptions-item label="异常码">
|
|
17
|
+
{{ info.code }}
|
|
18
|
+
</a-descriptions-item>
|
|
19
|
+
<a-descriptions-item label="异常内容"
|
|
20
|
+
>{{ info.message }}
|
|
21
|
+
</a-descriptions-item>
|
|
22
|
+
<a-descriptions-item label="异常时间">
|
|
23
|
+
{{ info.createTime }}
|
|
24
|
+
</a-descriptions-item>
|
|
25
|
+
<a-descriptions-item label="备注">
|
|
26
|
+
{{ info.remark }}
|
|
27
|
+
</a-descriptions-item>
|
|
28
|
+
</a-descriptions>
|
|
29
|
+
<a-divider orientation="left" plain="true"></a-divider>
|
|
30
|
+
<a-descriptions title="" :column="1" bordered>
|
|
31
|
+
<a-descriptions-item label="异常完整内容">
|
|
32
|
+
{{ info.exception }}
|
|
33
|
+
</a-descriptions-item>
|
|
34
|
+
</a-descriptions>
|
|
35
|
+
<template #footer>
|
|
36
|
+
<a-button key="submit" type="primary" @click="onClose">关闭</a-button>
|
|
37
|
+
</template>
|
|
38
|
+
</a-modal>
|
|
39
|
+
</template>
|
|
40
|
+
<script setup>
|
|
41
|
+
import { defineProps, defineEmits } from 'vue'
|
|
42
|
+
|
|
43
|
+
const props = defineProps({
|
|
44
|
+
open: {
|
|
45
|
+
type: Boolean,
|
|
46
|
+
required: true,
|
|
47
|
+
},
|
|
48
|
+
info: {
|
|
49
|
+
type: Object,
|
|
50
|
+
required: true,
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
// 定义 emits,用于触发关闭事件
|
|
54
|
+
const emit = defineEmits(['close'])
|
|
55
|
+
const onClose = () => {
|
|
56
|
+
emit('close')
|
|
57
|
+
}
|
|
58
|
+
</script>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<a-modal
|
|
3
|
+
:open="open"
|
|
4
|
+
title="详情"
|
|
5
|
+
width="60%"
|
|
6
|
+
wrap-class-name="full-modal"
|
|
7
|
+
@cancel="onClose"
|
|
8
|
+
>
|
|
9
|
+
<a-descriptions title="" bordered :column="2">
|
|
10
|
+
<a-descriptions-item label="控制器名称">
|
|
11
|
+
{{ info.controllerName }}
|
|
12
|
+
</a-descriptions-item>
|
|
13
|
+
<a-descriptions-item label="请求Ip">
|
|
14
|
+
{{ info.operationIp }}
|
|
15
|
+
</a-descriptions-item>
|
|
16
|
+
<a-descriptions-item label="操作方法">
|
|
17
|
+
{{ info.operationMethod }}
|
|
18
|
+
</a-descriptions-item>
|
|
19
|
+
<a-descriptions-item label="请求端源"
|
|
20
|
+
>{{ info.requestFrom }}
|
|
21
|
+
</a-descriptions-item>
|
|
22
|
+
<a-descriptions-item label="请求地址">
|
|
23
|
+
{{ info.requestAddress }}
|
|
24
|
+
</a-descriptions-item>
|
|
25
|
+
<a-descriptions-item label="请求方式">
|
|
26
|
+
{{ info.requestMethod }}
|
|
27
|
+
</a-descriptions-item>
|
|
28
|
+
<a-descriptions-item label="执行耗时">
|
|
29
|
+
{{ info.elapsedMilliseconds }}
|
|
30
|
+
</a-descriptions-item>
|
|
31
|
+
<a-descriptions-item label="请求时间">
|
|
32
|
+
{{ info.createTime }}
|
|
33
|
+
</a-descriptions-item>
|
|
34
|
+
<a-descriptions-item label="操作人员">
|
|
35
|
+
{{ info.operationPersonnel }}
|
|
36
|
+
</a-descriptions-item>
|
|
37
|
+
</a-descriptions>
|
|
38
|
+
<a-divider orientation="left" plain="true"></a-divider>
|
|
39
|
+
<a-descriptions title="" :column="1" bordered>
|
|
40
|
+
<a-descriptions-item label="userAgent">
|
|
41
|
+
{{ info.userAgent }}
|
|
42
|
+
</a-descriptions-item>
|
|
43
|
+
<a-descriptions-item label="授权信息">
|
|
44
|
+
{{ info.asccessToken }}
|
|
45
|
+
</a-descriptions-item>
|
|
46
|
+
<a-descriptions-item label="请求参数">
|
|
47
|
+
{{ info.requestParameters }}
|
|
48
|
+
</a-descriptions-item>
|
|
49
|
+
<a-descriptions-item label="返回参数">
|
|
50
|
+
{{ info.returnParameters }}
|
|
51
|
+
</a-descriptions-item>
|
|
52
|
+
</a-descriptions>
|
|
53
|
+
<template #footer>
|
|
54
|
+
<a-button key="submit" type="primary" @click="onClose">关闭</a-button>
|
|
55
|
+
</template>
|
|
56
|
+
</a-modal>
|
|
57
|
+
</template>
|
|
58
|
+
<script setup>
|
|
59
|
+
import { defineProps, defineEmits } from 'vue'
|
|
60
|
+
|
|
61
|
+
const props = defineProps({
|
|
62
|
+
open: {
|
|
63
|
+
type: Boolean,
|
|
64
|
+
required: true,
|
|
65
|
+
},
|
|
66
|
+
info: {
|
|
67
|
+
type: Object,
|
|
68
|
+
required: true,
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
// 定义 emits,用于触发关闭事件
|
|
72
|
+
const emit = defineEmits(['close'])
|
|
73
|
+
const onClose = () => {
|
|
74
|
+
emit('close')
|
|
75
|
+
}
|
|
76
|
+
</script>
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<a-drawer
|
|
3
|
+
:title="editTitle"
|
|
4
|
+
:width="540"
|
|
5
|
+
:open="open"
|
|
6
|
+
:body-style="{ paddingBottom: '80px' }"
|
|
7
|
+
:footer-style="{ textAlign: 'right' }"
|
|
8
|
+
@close="onClose"
|
|
9
|
+
:destroyOnClose="true"
|
|
10
|
+
>
|
|
11
|
+
<a-form :model="formInfo" ref="formRef" layout="vertical" :rules="rules">
|
|
12
|
+
<a-row :gutter="16">
|
|
13
|
+
<a-col :span="12">
|
|
14
|
+
<a-form-item
|
|
15
|
+
label="任务名称"
|
|
16
|
+
name="name"
|
|
17
|
+
:rules="[{ required: true, message: '任务名称不能为空' }]"
|
|
18
|
+
>
|
|
19
|
+
<a-input v-model:value="formInfo.name" placeholder="请输入" />
|
|
20
|
+
</a-form-item>
|
|
21
|
+
<a-form-item
|
|
22
|
+
label="触发器名称"
|
|
23
|
+
name="triggerName"
|
|
24
|
+
:rules="[{ required: true, message: '触发器名称不能为空' }]"
|
|
25
|
+
>
|
|
26
|
+
<a-input
|
|
27
|
+
v-model:value="formInfo.triggerName"
|
|
28
|
+
placeholder="请输入"
|
|
29
|
+
/>
|
|
30
|
+
</a-form-item>
|
|
31
|
+
|
|
32
|
+
<a-form-item label="任务类型" name="taskType">
|
|
33
|
+
<a-select v-model:value="formInfo.taskType" placeholder="请选择">
|
|
34
|
+
<a-select-option value="0">DLL</a-select-option>
|
|
35
|
+
<a-select-option value="1">API</a-select-option>
|
|
36
|
+
</a-select>
|
|
37
|
+
</a-form-item>
|
|
38
|
+
</a-col>
|
|
39
|
+
<a-col :span="12">
|
|
40
|
+
<a-form-item
|
|
41
|
+
label="任务分组"
|
|
42
|
+
name="jobGroup"
|
|
43
|
+
:rules="[{ required: true, message: '任务分组不能为空' }]"
|
|
44
|
+
>
|
|
45
|
+
<a-input v-model:value="formInfo.jobGroup" placeholder="请输入" />
|
|
46
|
+
</a-form-item>
|
|
47
|
+
<a-form-item
|
|
48
|
+
label="运行时间表达式Cron"
|
|
49
|
+
name="cron"
|
|
50
|
+
:rules="[{ required: true, message: 'cron不能为空' }]"
|
|
51
|
+
>
|
|
52
|
+
<a-input v-model:value="formInfo.cron" placeholder="请输入" />
|
|
53
|
+
</a-form-item>
|
|
54
|
+
<a target="_blank" href="https://cron.ciding.cc/">在线表达式Cron</a>
|
|
55
|
+
</a-col>
|
|
56
|
+
</a-row>
|
|
57
|
+
<a-form-item
|
|
58
|
+
v-if="formInfo.taskType == 0"
|
|
59
|
+
label="程序集名称"
|
|
60
|
+
name="assemblyName"
|
|
61
|
+
>
|
|
62
|
+
<a-input
|
|
63
|
+
v-model:value="formInfo.assemblyName"
|
|
64
|
+
disabled="true"
|
|
65
|
+
placeholder="请输入"
|
|
66
|
+
/>
|
|
67
|
+
</a-form-item>
|
|
68
|
+
<a-form-item
|
|
69
|
+
v-if="formInfo.taskType == 0"
|
|
70
|
+
label="任务类名"
|
|
71
|
+
name="className"
|
|
72
|
+
>
|
|
73
|
+
<a-select
|
|
74
|
+
v-model:value="formInfo.className"
|
|
75
|
+
placeholder="请选择"
|
|
76
|
+
:options="classNameList"
|
|
77
|
+
>
|
|
78
|
+
</a-select>
|
|
79
|
+
</a-form-item>
|
|
80
|
+
<a-form-item v-if="formInfo.taskType == 1" label="apiUrl" name="apiUrl">
|
|
81
|
+
<a-input v-model:value="formInfo.apiUrl" placeholder="请输入" />
|
|
82
|
+
</a-form-item>
|
|
83
|
+
<a-form-item
|
|
84
|
+
v-if="formInfo.taskType == 1"
|
|
85
|
+
label="APi访问类型"
|
|
86
|
+
name="apiRequestType"
|
|
87
|
+
>
|
|
88
|
+
<a-select v-model:value="formInfo.apiRequestType" placeholder="请选择">
|
|
89
|
+
<a-select-option value="POST">POST</a-select-option>
|
|
90
|
+
<a-select-option value="GET">GET</a-select-option>
|
|
91
|
+
</a-select>
|
|
92
|
+
</a-form-item>
|
|
93
|
+
<a-form-item label="参数" name="apiParameter">
|
|
94
|
+
<a-input v-model:value="formInfo.apiParameter" placeholder="请输入" />
|
|
95
|
+
</a-form-item>
|
|
96
|
+
<a-form-item label="是否开启日志" name="isLog">
|
|
97
|
+
<a-switch v-model:checked="formInfo.isLog" />
|
|
98
|
+
</a-form-item>
|
|
99
|
+
<a-form-item label="备注" name="remark">
|
|
100
|
+
<a-textarea v-model:value="formInfo.remark" />
|
|
101
|
+
</a-form-item>
|
|
102
|
+
</a-form>
|
|
103
|
+
<template #extra>
|
|
104
|
+
<a-space>
|
|
105
|
+
<a-button type="primary" @click="onSave" :loading="loading"
|
|
106
|
+
>保存</a-button
|
|
107
|
+
>
|
|
108
|
+
<a-button @click="resetForm">重置</a-button>
|
|
109
|
+
</a-space>
|
|
110
|
+
</template>
|
|
111
|
+
</a-drawer>
|
|
112
|
+
</template>
|
|
113
|
+
<script setup>
|
|
114
|
+
import { defineProps, defineEmits, ref, reactive, onMounted } from 'vue'
|
|
115
|
+
import { message } from 'ant-design-vue'
|
|
116
|
+
import quartz from '@/api/methods/quartz'
|
|
117
|
+
import useFormCRUD from '@/utils/useFormCRUD'
|
|
118
|
+
const props = defineProps({
|
|
119
|
+
open: {
|
|
120
|
+
type: Boolean,
|
|
121
|
+
required: true,
|
|
122
|
+
},
|
|
123
|
+
})
|
|
124
|
+
// 表单字段的默认值
|
|
125
|
+
const defaultformInfo = {
|
|
126
|
+
id: null,
|
|
127
|
+
name: '',
|
|
128
|
+
triggerName: '',
|
|
129
|
+
jobGroup: '',
|
|
130
|
+
cron: '',
|
|
131
|
+
taskType: '0',
|
|
132
|
+
assemblyName: '',
|
|
133
|
+
className: null,
|
|
134
|
+
apiUrl: '',
|
|
135
|
+
apiRequestType: 'POST',
|
|
136
|
+
apiParameter: '',
|
|
137
|
+
isLog: true,
|
|
138
|
+
remark: '',
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 响应式数据
|
|
142
|
+
const formInfo = reactive({ ...defaultformInfo })
|
|
143
|
+
const editTitle = ref('新增')
|
|
144
|
+
const formRef = ref(null)
|
|
145
|
+
const classNameList = ref([])
|
|
146
|
+
|
|
147
|
+
// 定义 emits,用于触发关闭事件
|
|
148
|
+
const emit = defineEmits(['close', 'updateData'])
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* 重置表单到默认值
|
|
152
|
+
*/
|
|
153
|
+
const resetForm = () => {
|
|
154
|
+
Object.assign(formInfo, defaultformInfo)
|
|
155
|
+
formRef.value?.resetFields()
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const { loading, save } = useFormCRUD(quartz)
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* 初始化任务编辑表单
|
|
162
|
+
* @param {string} id - 任务ID,如果为空或默认UUID则表示新增任务
|
|
163
|
+
*/
|
|
164
|
+
const init = async id => {
|
|
165
|
+
const isEdit = !!id
|
|
166
|
+
editTitle.value = isEdit ? '修改' : '新增'
|
|
167
|
+
|
|
168
|
+
let assemblyData = null
|
|
169
|
+
try {
|
|
170
|
+
// 获取程序集信息
|
|
171
|
+
const res = await quartz.getAssembly()
|
|
172
|
+
assemblyData = res.data
|
|
173
|
+
classNameList.value = assemblyData.classJobs.map(x => ({
|
|
174
|
+
label: x,
|
|
175
|
+
value: x,
|
|
176
|
+
}))
|
|
177
|
+
} catch (error) {
|
|
178
|
+
message.error('获取程序集信息失败,请重试')
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (isEdit) {
|
|
182
|
+
try {
|
|
183
|
+
const res = await quartz.get({ id })
|
|
184
|
+
Object.assign(formInfo, res.data)
|
|
185
|
+
} catch (error) {
|
|
186
|
+
message.error('获取任务信息失败,请重试')
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
resetForm()
|
|
190
|
+
// 在新增模式下,设置程序集名称
|
|
191
|
+
if (assemblyData) {
|
|
192
|
+
formInfo.assemblyName = assemblyData.assemblyName
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* 保存任务信息
|
|
199
|
+
* 处理表单验证和任务新增/修改操作
|
|
200
|
+
*/
|
|
201
|
+
const onSave = async () => {
|
|
202
|
+
await save(formRef.value, formInfo, {
|
|
203
|
+
onSuccess: () => {
|
|
204
|
+
emit('updateData')
|
|
205
|
+
onClose()
|
|
206
|
+
},
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* 关闭抽屉组件
|
|
212
|
+
* 触发关闭事件并通知父组件
|
|
213
|
+
*/
|
|
214
|
+
const onClose = () => {
|
|
215
|
+
resetForm()
|
|
216
|
+
emit('close')
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// 使用 defineExpose 暴露方法
|
|
220
|
+
defineExpose({ init })
|
|
221
|
+
</script>
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<a-drawer
|
|
3
|
+
:title="editTitle"
|
|
4
|
+
:width="540"
|
|
5
|
+
:open="open"
|
|
6
|
+
:body-style="{ paddingBottom: '80px' }"
|
|
7
|
+
:footer-style="{ textAlign: 'right' }"
|
|
8
|
+
@close="onClose"
|
|
9
|
+
:destroyOnClose="true"
|
|
10
|
+
>
|
|
11
|
+
<a-form :model="formInfo" ref="formRef" layout="vertical">
|
|
12
|
+
<a-form-item
|
|
13
|
+
label="账号名称"
|
|
14
|
+
name="name"
|
|
15
|
+
:rules="[{ required: true, message: '账号名称不能为空' }]"
|
|
16
|
+
>
|
|
17
|
+
<a-input v-model:value="formInfo.name" placeholder="请输入" />
|
|
18
|
+
</a-form-item>
|
|
19
|
+
<a-form-item
|
|
20
|
+
label="手机号"
|
|
21
|
+
name="mobile"
|
|
22
|
+
:rules="[{ required: true, message: '手机号不能为空' }]"
|
|
23
|
+
>
|
|
24
|
+
<a-input-number v-model:value="formInfo.mobile" placeholder="请输入" style="width: 100%" />
|
|
25
|
+
</a-form-item>
|
|
26
|
+
<a-form-item
|
|
27
|
+
label="密码"
|
|
28
|
+
name="password"
|
|
29
|
+
v-if="formInfo.id == 0"
|
|
30
|
+
:rules="[{ required: true, message: '密码不能为空' }]" >
|
|
31
|
+
<a-input-password
|
|
32
|
+
v-model:value="formInfo.password"
|
|
33
|
+
placeholder="请输入"
|
|
34
|
+
/>
|
|
35
|
+
</a-form-item>
|
|
36
|
+
<a-form-item
|
|
37
|
+
label="角色"
|
|
38
|
+
name="roleId"
|
|
39
|
+
:rules="[{ required: true, message: '请选择角色' }]"
|
|
40
|
+
>
|
|
41
|
+
<a-select
|
|
42
|
+
v-model:value="formInfo.roleId"
|
|
43
|
+
placeholder="请选择"
|
|
44
|
+
:options="roleList"
|
|
45
|
+
>
|
|
46
|
+
</a-select>
|
|
47
|
+
</a-form-item>
|
|
48
|
+
<a-form-item label="邮件" name="email">
|
|
49
|
+
<a-input v-model:value="formInfo.email" placeholder="请输入" />
|
|
50
|
+
</a-form-item>
|
|
51
|
+
|
|
52
|
+
<a-form-item label="是否启用" name="isEnable">
|
|
53
|
+
<a-switch v-model:checked="formInfo.isEnable" />
|
|
54
|
+
</a-form-item>
|
|
55
|
+
<a-form-item label="备注" name="remark">
|
|
56
|
+
<a-textarea v-model:value="formInfo.remark" />
|
|
57
|
+
</a-form-item>
|
|
58
|
+
</a-form>
|
|
59
|
+
|
|
60
|
+
<template #extra>
|
|
61
|
+
<a-space>
|
|
62
|
+
<a-button type="primary" @click="onSave" :loading="loading">保存</a-button>
|
|
63
|
+
<a-button @click="resetForm">重置</a-button>
|
|
64
|
+
</a-space>
|
|
65
|
+
</template>
|
|
66
|
+
</a-drawer>
|
|
67
|
+
</template>
|
|
68
|
+
|
|
69
|
+
<script setup>
|
|
70
|
+
import { defineProps, defineEmits, ref, reactive, onMounted } from 'vue'
|
|
71
|
+
import { message } from 'ant-design-vue'
|
|
72
|
+
import sysRole from '@/api/methods/sysRole'
|
|
73
|
+
import sysAccount from '@/api/methods/sysAccount'
|
|
74
|
+
import useFormCRUD from '@/utils/useFormCRUD'
|
|
75
|
+
|
|
76
|
+
const props = defineProps({
|
|
77
|
+
open: {
|
|
78
|
+
type: Boolean,
|
|
79
|
+
required: true,
|
|
80
|
+
},
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
// 表单字段的默认值
|
|
84
|
+
const defaultformInfo = {
|
|
85
|
+
id: null,
|
|
86
|
+
name: '',
|
|
87
|
+
mobile: '',
|
|
88
|
+
password: '',
|
|
89
|
+
email: '',
|
|
90
|
+
roleId: null,
|
|
91
|
+
isEnable: true,
|
|
92
|
+
remark: '',
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 响应式数据
|
|
96
|
+
const formInfo = reactive({ ...defaultformInfo })
|
|
97
|
+
const editTitle = ref('新增')
|
|
98
|
+
const formRef = ref(null)
|
|
99
|
+
const roleList = ref([])
|
|
100
|
+
|
|
101
|
+
// 定义 emits,用于触发关闭事件
|
|
102
|
+
const emit = defineEmits(['close', 'updateData'])
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 重置表单到默认值
|
|
106
|
+
*/
|
|
107
|
+
const resetForm = () => {
|
|
108
|
+
Object.assign(formInfo, defaultformInfo)
|
|
109
|
+
formRef.value?.resetFields()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const { loading, save } = useFormCRUD(sysAccount)
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 初始化账号编辑表单
|
|
116
|
+
* @param {number} id - 账号ID,如果为0或空则表示新增账号
|
|
117
|
+
*/
|
|
118
|
+
const init = async id => {
|
|
119
|
+
const isEdit = !!id
|
|
120
|
+
editTitle.value = isEdit ? '修改' : '新增'
|
|
121
|
+
|
|
122
|
+
if (isEdit) {
|
|
123
|
+
try {
|
|
124
|
+
const res = await sysAccount.get({ id })
|
|
125
|
+
Object.assign(formInfo, res.data)
|
|
126
|
+
} catch (error) {
|
|
127
|
+
message.error('获取信息失败,请重试')
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
resetForm()
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 加载角色列表
|
|
136
|
+
*/
|
|
137
|
+
const loadRoleList = async () => {
|
|
138
|
+
try {
|
|
139
|
+
const res = await sysRole.getList()
|
|
140
|
+
roleList.value = res.data.map(x => ({
|
|
141
|
+
label: x.name,
|
|
142
|
+
value: x.id,
|
|
143
|
+
}))
|
|
144
|
+
} catch (error) {
|
|
145
|
+
message.error('加载角色列表失败,请重试')
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* 保存账号信息
|
|
151
|
+
* 处理表单验证账号新增/修改操作
|
|
152
|
+
*/
|
|
153
|
+
const onSave = async () => {
|
|
154
|
+
await save(formRef.value, formInfo, {
|
|
155
|
+
onSuccess: () => {
|
|
156
|
+
emit('updateData')
|
|
157
|
+
onClose()
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* 关闭抽屉组件
|
|
164
|
+
* 触发关闭事件并通知父组件
|
|
165
|
+
*/
|
|
166
|
+
const onClose = () => {
|
|
167
|
+
resetForm()
|
|
168
|
+
emit('close')
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 组件挂载时加载角色列表
|
|
172
|
+
onMounted(() => {
|
|
173
|
+
loadRoleList()
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
// 使用 defineExpose 暴露方法
|
|
177
|
+
defineExpose({ init })
|
|
178
|
+
</script>
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<a-drawer
|
|
3
|
+
:title="editTitle"
|
|
4
|
+
:width="540"
|
|
5
|
+
:open="open"
|
|
6
|
+
:body-style="{ paddingBottom: '80px' }"
|
|
7
|
+
:footer-style="{ textAlign: 'right' }"
|
|
8
|
+
@close="onClose"
|
|
9
|
+
:destroyOnClose="true"
|
|
10
|
+
>
|
|
11
|
+
<a-form :model="formInfo" ref="formRef" layout="vertical">
|
|
12
|
+
<a-form-item
|
|
13
|
+
label="字典名称"
|
|
14
|
+
name="name"
|
|
15
|
+
:rules="[{ required: true, message: '字典名称不能为空' }]"
|
|
16
|
+
>
|
|
17
|
+
<a-input v-model:value="formInfo.name" placeholder="请输入" />
|
|
18
|
+
</a-form-item>
|
|
19
|
+
<a-form-item
|
|
20
|
+
label="字典类型"
|
|
21
|
+
name="type"
|
|
22
|
+
:rules="[{ required: true, message: '字典类型不能为空' }]"
|
|
23
|
+
>
|
|
24
|
+
<a-input v-model:value="formInfo.type" placeholder="请输入" />
|
|
25
|
+
</a-form-item>
|
|
26
|
+
<a-form-item label="是否启用" name="isEnable">
|
|
27
|
+
<a-switch v-model:checked="formInfo.isEnable" />
|
|
28
|
+
</a-form-item>
|
|
29
|
+
<a-form-item label="备注" name="remark">
|
|
30
|
+
<a-textarea v-model:value="formInfo.remark" />
|
|
31
|
+
</a-form-item>
|
|
32
|
+
</a-form>
|
|
33
|
+
<template #extra>
|
|
34
|
+
<a-space>
|
|
35
|
+
<a-button type="primary" @click="onSave" :loading="loading">保存</a-button>
|
|
36
|
+
<a-button @click="resetForm">重置</a-button>
|
|
37
|
+
</a-space>
|
|
38
|
+
</template>
|
|
39
|
+
</a-drawer>
|
|
40
|
+
</template>
|
|
41
|
+
<script setup>
|
|
42
|
+
import { defineProps, defineEmits, ref, reactive } from 'vue'
|
|
43
|
+
import { message } from 'ant-design-vue'
|
|
44
|
+
import sysDict from '@/api/methods/sysDict'
|
|
45
|
+
import useFormCRUD from '@/utils/useFormCRUD'
|
|
46
|
+
const props = defineProps({
|
|
47
|
+
open: {
|
|
48
|
+
type: Boolean,
|
|
49
|
+
required: true,
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
const defaultformInfo = {
|
|
53
|
+
id: null,
|
|
54
|
+
name: '',
|
|
55
|
+
type: '',
|
|
56
|
+
isEnable: true,
|
|
57
|
+
remark: '',
|
|
58
|
+
}
|
|
59
|
+
// 使用 reactive 定义表单状态
|
|
60
|
+
const formInfo = reactive({ ...defaultformInfo })
|
|
61
|
+
const editTitle = ref('新增')
|
|
62
|
+
const formRef = ref(null)
|
|
63
|
+
// 定义 emits,用于触发关闭事件
|
|
64
|
+
const emit = defineEmits(['close', 'updateData'])
|
|
65
|
+
/**
|
|
66
|
+
* 重置表单到默认值
|
|
67
|
+
*/
|
|
68
|
+
const resetForm = () => {
|
|
69
|
+
Object.assign(formInfo, defaultformInfo)
|
|
70
|
+
formRef.value?.resetFields()
|
|
71
|
+
}
|
|
72
|
+
const { loading, save } = useFormCRUD(sysDict)
|
|
73
|
+
/**
|
|
74
|
+
* 初始化角色编辑表单
|
|
75
|
+
* @param {number} id - 角色ID,如果为0或空则表示新增角色
|
|
76
|
+
*/
|
|
77
|
+
const init = async id => {
|
|
78
|
+
const isEdit = !!id
|
|
79
|
+
editTitle.value = isEdit ? '修改' : '新增'
|
|
80
|
+
|
|
81
|
+
if (isEdit) {
|
|
82
|
+
try {
|
|
83
|
+
const res = await sysDict.get({ id })
|
|
84
|
+
Object.assign(formInfo, res.data)
|
|
85
|
+
} catch (error) {
|
|
86
|
+
message.error('获取信息失败,请重试')
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
resetForm()
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 保存
|
|
94
|
+
* 处理表单验证和角色新增/修改操作
|
|
95
|
+
*/
|
|
96
|
+
const onSave = async() => {
|
|
97
|
+
await save(formRef.value, formInfo, {
|
|
98
|
+
onSuccess: () => {
|
|
99
|
+
emit('updateData')
|
|
100
|
+
onClose()
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* 关闭抽屉组件
|
|
106
|
+
* 触发关闭事件并通知父组件
|
|
107
|
+
*/
|
|
108
|
+
const onClose = () => {
|
|
109
|
+
resetForm()
|
|
110
|
+
emit('close')
|
|
111
|
+
}
|
|
112
|
+
// 使用 defineExpose 暴露方法
|
|
113
|
+
defineExpose({ init })
|
|
114
|
+
</script>
|