zsysview 0.0.6 → 0.0.8
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.md +3 -1
- package/assets/default_avatar.png +0 -0
- package/assets/default_logo.png +0 -0
- package/assets/default_logo_40.png +0 -0
- package/assets/login_bg.jpg +0 -0
- package/components/export/export_dialog.vue +150 -0
- package/components/export/export_progress.vue +62 -0
- package/components/list/zsyslist.vue +2 -2
- package/components/list/zsyslist_header.vue +1 -1
- package/components/zsys_delbutton.vue +60 -0
- package/core/app.ts +21 -2
- package/core/common/common.ts +29 -0
- package/core/common/zsys_eventBus.ts +45 -0
- package/core/common/zsys_time.ts +26 -0
- package/core/httpapi/http_api_return_data.ts +43 -0
- package/core/httpapi/http_api_v1.ts +151 -0
- package/core/httpapi/http_axios.ts +54 -0
- package/core/router copy.ts +148 -0
- package/core/router.ts +149 -0
- package/core/runtime.ts +14 -0
- package/core/user_token.ts +17 -0
- package/css/common.css +16 -0
- package/package.json +9 -2
- package/view/app.vue +0 -1
- package/view/backup/backup.vue +308 -0
- package/view/building.vue +22 -0
- package/view/department/department.vue +111 -0
- package/view/department/department_edit_dialog.vue +267 -0
- package/view/desktop/desktop.vue +11 -0
- package/view/log/log.vue +60 -0
- package/view/log/log_setting.vue +41 -0
- package/view/login.vue +5 -5
- package/view/main/breadcrumb.vue +41 -0
- package/view/main/main.vue +60 -0
- package/view/main/userHeader.vue +73 -0
- package/view/main/userMenu.vue +132 -0
- package/view/main/userMenuItem.vue +49 -0
- package/view/position/position.vue +58 -0
- package/view/position/position_edit_dialog.vue +203 -0
- package/view/role/role.vue +72 -0
- package/view/role/role_edit_dialog.vue +271 -0
- package/view/self/change_password.vue +97 -0
- package/view/self/self.vue +62 -0
- package/view/sys/sys.vue +19 -0
- package/view/user/change_user_password_dialog.vue +155 -0
- package/view/user/user.vue +110 -0
- package/view/user/user_edit_dialog.vue +283 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
<!-- ReusableDialog.vue -->
|
|
2
|
+
<template>
|
|
3
|
+
<el-dialog v-model="visible" title="角色权限" :align-center="true" :before-close="handleBeforeClose" @open="open"
|
|
4
|
+
width="800" :draggable="true" :overflow="true" @opened="focus" destroy-on-close :close-on-click-modal="false">
|
|
5
|
+
<!-- 默认插槽放主要内容 -->
|
|
6
|
+
<el-form @submit.prevent ref="ruleFormRef" :model="form" :rules="rules"
|
|
7
|
+
style="padding-left: 10px;padding-right: 10px;" label-width="auto" v-loading="view.loading"
|
|
8
|
+
:disabled="view.saving">
|
|
9
|
+
<el-form-item label="角色名称" prop="role_title">
|
|
10
|
+
<el-input ref="inputRef" v-model="form.role_title" style="width: 300px;" />
|
|
11
|
+
<el-switch v-model="form.role_is_enable" inline-prompt active-text="已启用" inactive-text="已禁用"
|
|
12
|
+
style="margin-left: 10px;" />
|
|
13
|
+
</el-form-item>
|
|
14
|
+
<el-form-item label="备注" prop="role_notes">
|
|
15
|
+
<el-input v-model="form.role_notes" type="textarea" :rows="2" />
|
|
16
|
+
</el-form-item>
|
|
17
|
+
<el-form-item label="权限">
|
|
18
|
+
<el-transfer v-model="form.permission_value" :data="permission_option" :titles="['可选', '已选']" :props="{
|
|
19
|
+
key: 'permission_key',
|
|
20
|
+
label: 'permission_title',
|
|
21
|
+
}">
|
|
22
|
+
<template #left-empty>
|
|
23
|
+
<el-empty :image-size="60" description="无可选项" />
|
|
24
|
+
</template>
|
|
25
|
+
<template #right-empty>
|
|
26
|
+
<el-empty :image-size="60" description="请从左侧选择" />
|
|
27
|
+
</template>
|
|
28
|
+
</el-transfer>
|
|
29
|
+
</el-form-item>
|
|
30
|
+
</el-form>
|
|
31
|
+
|
|
32
|
+
<!-- 底部按钮区插槽 -->
|
|
33
|
+
<template #footer>
|
|
34
|
+
<div style="display: flex;justify-content: right;">
|
|
35
|
+
<el-tooltip content="保存成功后不关闭窗口">
|
|
36
|
+
<el-checkbox v-if="view.isnew" v-model="view.donotClose" label="连续录入" style="margin-right: 10px;" />
|
|
37
|
+
</el-tooltip>
|
|
38
|
+
|
|
39
|
+
<el-tooltip content="快捷键 Alt+S" :show-after="800">
|
|
40
|
+
<el-button type="primary" @click="submitForm(ruleFormRef)" :disabled="view.loading"
|
|
41
|
+
:loading="view.saving">保存(<el-text tag="ins" style="color: white;">S</el-text>)</el-button>
|
|
42
|
+
</el-tooltip>
|
|
43
|
+
|
|
44
|
+
<el-button @click="close">取消</el-button>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
</template>
|
|
48
|
+
</el-dialog>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<script setup lang="ts">
|
|
52
|
+
import { ref, watch, reactive, type PropType } from 'vue';
|
|
53
|
+
import { HttpApiV1 as http } from '../../core/httpapi/http_api_v1';
|
|
54
|
+
import { ZSYSMessage } from '../../components/message';
|
|
55
|
+
import type { FormInstance, FormRules, ElInput } from 'element-plus'
|
|
56
|
+
import { useMagicKeys, whenever } from '@vueuse/core'
|
|
57
|
+
import type { HttpApiReturnData } from '../../core/httpapi/http_api_return_data';
|
|
58
|
+
import { zsysEventBus } from '../../core/common/zsys_eventBus';
|
|
59
|
+
const eventBus = zsysEventBus()
|
|
60
|
+
const inputRef = ref<InstanceType<typeof ElInput> | null>(null)
|
|
61
|
+
const props = defineProps({
|
|
62
|
+
modelValue: { type: Boolean, required: true }, // 控制显示隐藏
|
|
63
|
+
id: { type: BigInt as unknown as PropType<bigint>, required: true }
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const emit = defineEmits<{
|
|
67
|
+
(e: 'update:modelValue', value: boolean): void;
|
|
68
|
+
// (e: 'confirm'): void;
|
|
69
|
+
// (e: 'close'): void;
|
|
70
|
+
}>();
|
|
71
|
+
|
|
72
|
+
const visible = ref(false);
|
|
73
|
+
|
|
74
|
+
// 同步外部 v-model 变化
|
|
75
|
+
watch(
|
|
76
|
+
() => props.modelValue,
|
|
77
|
+
(val) => {
|
|
78
|
+
visible.value = val;
|
|
79
|
+
},
|
|
80
|
+
{ immediate: true }
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// 内部状态变化通知外部
|
|
84
|
+
watch(visible, (val) => {
|
|
85
|
+
emit('update:modelValue', val);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
//弹窗显示时的处理
|
|
89
|
+
const open = () => {
|
|
90
|
+
view.isnew = (props.id == 0n ? true : false)
|
|
91
|
+
getData()
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const close = () => {
|
|
95
|
+
visible.value = false;
|
|
96
|
+
// emit('close');
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const handleBeforeClose = (done: () => void) => {
|
|
100
|
+
ruleFormRef.value?.clearValidate();
|
|
101
|
+
// 可以在这里添加关闭前的拦截逻辑
|
|
102
|
+
done();
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const view = reactive({
|
|
106
|
+
loading: true,
|
|
107
|
+
saving: false,
|
|
108
|
+
donotClose: false,
|
|
109
|
+
isnew: true
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
if (props.id == 0n) { view.isnew = true }
|
|
114
|
+
//^^^^^^^^^^^^^^^上方为对话框功能^^^^^^^^^^^^^^^
|
|
115
|
+
|
|
116
|
+
//===============下方为数据部分===============
|
|
117
|
+
interface PermissionOption {
|
|
118
|
+
permission_key: string,
|
|
119
|
+
permission_title: string
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
//列表数据返回值
|
|
123
|
+
interface ListData {
|
|
124
|
+
listdata: PermissionOption[]
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const getPermissionOption = async () => {
|
|
128
|
+
let res = await http.Post(http.url_syspermission_list, {})
|
|
129
|
+
if (res.IsSuccess) {
|
|
130
|
+
let data = res.data as ListData
|
|
131
|
+
return data.listdata
|
|
132
|
+
}
|
|
133
|
+
return []
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const permission_option = ref<PermissionOption[]>([])
|
|
137
|
+
|
|
138
|
+
//=================表单
|
|
139
|
+
const ruleFormRef = ref<FormInstance>()
|
|
140
|
+
const form = ref({
|
|
141
|
+
role_id: props.id as bigint,
|
|
142
|
+
role_is_enable: true,
|
|
143
|
+
set role_enable(v: number) {
|
|
144
|
+
this.role_is_enable = (v == 1 ? true : false)
|
|
145
|
+
},
|
|
146
|
+
get role_enable(): number {
|
|
147
|
+
return (this.role_is_enable ? 1 : 0)
|
|
148
|
+
},
|
|
149
|
+
role_title: '',
|
|
150
|
+
role_notes: '',
|
|
151
|
+
permission_value: [],
|
|
152
|
+
set role_permission(v: string) {
|
|
153
|
+
this.permission_value = v.split(',') as never[]
|
|
154
|
+
},
|
|
155
|
+
})
|
|
156
|
+
const rules = reactive<FormRules<typeof form>>({
|
|
157
|
+
role_title: [
|
|
158
|
+
{ required: true, message: '请输入角色名称', trigger: 'blur' },
|
|
159
|
+
],
|
|
160
|
+
})
|
|
161
|
+
//=================
|
|
162
|
+
|
|
163
|
+
//获取修改数据
|
|
164
|
+
const getData = async () => {
|
|
165
|
+
view.loading = true
|
|
166
|
+
//获取可以用的权限值
|
|
167
|
+
permission_option.value = await getPermissionOption()
|
|
168
|
+
form.value.role_id = props.id
|
|
169
|
+
if (props.id != 0n) {
|
|
170
|
+
view.donotClose=false
|
|
171
|
+
try {
|
|
172
|
+
let res = await http.Post(http.url_sysrole_detail, { id: props.id })
|
|
173
|
+
if (res.IsSuccess) {
|
|
174
|
+
let data = res.data as {
|
|
175
|
+
role_id: bigint
|
|
176
|
+
role_name: string
|
|
177
|
+
role_notes: string
|
|
178
|
+
role_enable: number
|
|
179
|
+
role_is_enable: boolean
|
|
180
|
+
role_permission: string
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
form.value.role_title = data.role_name
|
|
184
|
+
form.value.role_notes = data.role_notes
|
|
185
|
+
form.value.role_enable = data.role_enable
|
|
186
|
+
form.value.role_permission = data.role_permission
|
|
187
|
+
}
|
|
188
|
+
} catch (e) {
|
|
189
|
+
console.log(e);
|
|
190
|
+
} finally {
|
|
191
|
+
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
form.value.role_title = ''
|
|
195
|
+
form.value.role_notes = ''
|
|
196
|
+
}
|
|
197
|
+
view.loading = false
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
//保存
|
|
201
|
+
const saveData = async (): Promise<HttpApiReturnData> => {
|
|
202
|
+
let pv = ''
|
|
203
|
+
for (let i = 0; i < form.value.permission_value.length; i++) {
|
|
204
|
+
if (pv != '') { pv += ',' }
|
|
205
|
+
pv += form.value.permission_value[i]
|
|
206
|
+
}
|
|
207
|
+
return await http.Post(http.url_sysrole_save, {
|
|
208
|
+
role_id: form.value.role_id,
|
|
209
|
+
role_name: form.value.role_title,
|
|
210
|
+
role_permission: pv,
|
|
211
|
+
role_notes: form.value.role_notes,
|
|
212
|
+
role_enable: form.value.role_enable
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
//验证表单处理界面并保存
|
|
217
|
+
const submitForm = (formEl: FormInstance | undefined) => {
|
|
218
|
+
if (!formEl) return
|
|
219
|
+
formEl.validate(async (valid) => {
|
|
220
|
+
if (valid) {
|
|
221
|
+
view.saving = true
|
|
222
|
+
try {
|
|
223
|
+
let res = await saveData()
|
|
224
|
+
if (res.IsSuccess) {
|
|
225
|
+
// emit('confirm');
|
|
226
|
+
if (view.donotClose) {
|
|
227
|
+
form.value.role_id = 0n
|
|
228
|
+
setTimeout(() => { focus() }, 200);
|
|
229
|
+
} else {
|
|
230
|
+
close();
|
|
231
|
+
}
|
|
232
|
+
ZSYSMessage.ShowSuccess("保存成功")
|
|
233
|
+
eventBus.emit('aud', {module:'role', id: form.value.role_id })
|
|
234
|
+
} else {
|
|
235
|
+
ZSYSMessage.ShowError(res.message)
|
|
236
|
+
}
|
|
237
|
+
} catch (e) {
|
|
238
|
+
|
|
239
|
+
} finally {
|
|
240
|
+
// emit('confirm');
|
|
241
|
+
// close();
|
|
242
|
+
view.saving = false
|
|
243
|
+
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const focus = () => {
|
|
250
|
+
inputRef.value?.focus()
|
|
251
|
+
inputRef.value?.select()
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
//==========快捷键
|
|
255
|
+
const keys = useMagicKeys()
|
|
256
|
+
|
|
257
|
+
whenever(keys.alt_s, () => {
|
|
258
|
+
if (visible.value) {
|
|
259
|
+
console.log('Alt+S提交')
|
|
260
|
+
submitForm(ruleFormRef.value)
|
|
261
|
+
}
|
|
262
|
+
// 在这里执行你的业务逻辑
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
</script>
|
|
266
|
+
|
|
267
|
+
<style scoped>
|
|
268
|
+
.el-transfer /deep/ .el-transfer-panel {
|
|
269
|
+
width: 240px;
|
|
270
|
+
}
|
|
271
|
+
</style>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<breadcrumb />
|
|
3
|
+
<div style="padding: 0px 20px; margin-top: 20px;">
|
|
4
|
+
<el-form ref="ruleFormRef"
|
|
5
|
+
label-width="auto"
|
|
6
|
+
style="max-width: 400px; margin-left:80px;"
|
|
7
|
+
:rules="rules"
|
|
8
|
+
:model="form_data"
|
|
9
|
+
status-icon>
|
|
10
|
+
<el-form-item label="旧密码" prop="old_p">
|
|
11
|
+
<el-input v-model="form_data.old_p" size="large" show-password/>
|
|
12
|
+
</el-form-item>
|
|
13
|
+
<el-form-item label="新密码" prop="new_p1">
|
|
14
|
+
<el-input v-model="form_data.new_p1" size="large" show-password/>
|
|
15
|
+
</el-form-item>
|
|
16
|
+
<el-form-item label="再次输入新密码" prop="new_p2">
|
|
17
|
+
<el-input v-model="form_data.new_p2" size="large" show-password/>
|
|
18
|
+
</el-form-item>
|
|
19
|
+
<el-form-item style="margin-left:120px;">
|
|
20
|
+
<el-button type="primary" @click="submitForm(ruleFormRef)" :loading="view.isloading">确认修改</el-button>
|
|
21
|
+
<el-button @click="goBack" :disabled="view.isloading">返回</el-button>
|
|
22
|
+
</el-form-item>
|
|
23
|
+
</el-form>
|
|
24
|
+
</div>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<script setup lang="ts">
|
|
28
|
+
import breadcrumb from '../breadcrumb.vue';
|
|
29
|
+
import { HttpApiV1 as http } from '../../../httpapi/http_api_v1';
|
|
30
|
+
import { reactive,ref } from 'vue';
|
|
31
|
+
import { useRouter} from "vue-router";
|
|
32
|
+
import { ZSYSMessage } from '../../../utils/zsys_message';
|
|
33
|
+
import type { FormInstance, FormRules } from 'element-plus'
|
|
34
|
+
import { Md5 } from 'ts-md5'
|
|
35
|
+
const ruleFormRef = ref<FormInstance>()
|
|
36
|
+
const r=useRouter()
|
|
37
|
+
const goBack = () => {
|
|
38
|
+
r.back()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const view=reactive({
|
|
42
|
+
isloading:false,
|
|
43
|
+
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const form_data=reactive({
|
|
47
|
+
old_p:'',
|
|
48
|
+
new_p1:'',
|
|
49
|
+
new_p2:'',
|
|
50
|
+
})
|
|
51
|
+
//校验
|
|
52
|
+
const rules=reactive<FormRules<typeof form_data>>({
|
|
53
|
+
old_p:[
|
|
54
|
+
{required: true, message:'请输入旧密码',trigger:'blur'},
|
|
55
|
+
],
|
|
56
|
+
new_p1:[
|
|
57
|
+
{required: true, message:'请输入新密码',trigger:'blur'},
|
|
58
|
+
{min: 6,max:18, message:'密码长度为6-18位',trigger:'blur'},
|
|
59
|
+
],
|
|
60
|
+
new_p2:[
|
|
61
|
+
{required: true, message:'请输入新密码',trigger:'blur'},
|
|
62
|
+
{min: 6,max:18, message:'密码长度为6-18位',trigger:'blur'},
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
const submitForm = (formEl: FormInstance | undefined) => {
|
|
68
|
+
if (!formEl) return
|
|
69
|
+
formEl.validate((valid) => {
|
|
70
|
+
if (valid) {
|
|
71
|
+
view.isloading=true
|
|
72
|
+
http.Post(http.url_change_password,{
|
|
73
|
+
old_p:Md5.hashStr(form_data.old_p),
|
|
74
|
+
new_p:Md5.hashStr(form_data.new_p1)
|
|
75
|
+
}).then((res)=>{
|
|
76
|
+
if(res.IsSuccess){
|
|
77
|
+
ZSYSMessage.ShowSuccess('密码修改成功')
|
|
78
|
+
r.back()
|
|
79
|
+
}else{
|
|
80
|
+
ZSYSMessage.ShowError('密码修改失败')
|
|
81
|
+
}
|
|
82
|
+
}).catch((err)=>{
|
|
83
|
+
console.log(err);
|
|
84
|
+
}).finally(()=>{
|
|
85
|
+
view.isloading=false
|
|
86
|
+
})
|
|
87
|
+
} else {
|
|
88
|
+
console.log('error submit!')
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
<style scoped>
|
|
96
|
+
|
|
97
|
+
</style>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<breadcrumb />
|
|
3
|
+
<div style="padding: 0px 20px; margin-top: 20px;">
|
|
4
|
+
<el-row>
|
|
5
|
+
<el-col :span="6" style="justify-content: center;align-items: center;display: flex;">
|
|
6
|
+
<el-image style="width: 160px; height: 160px;" fit="cover" />
|
|
7
|
+
<!-- :src="default_avatar" -->
|
|
8
|
+
<!-- <el-avatar :size="160" shape="square" /> -->
|
|
9
|
+
</el-col>
|
|
10
|
+
<el-col :span="18">
|
|
11
|
+
<el-descriptions title="您的信息">
|
|
12
|
+
<el-descriptions-item label="UID">{{user.uid}}</el-descriptions-item>
|
|
13
|
+
<el-descriptions-item label="用户名">{{user.user_name}}</el-descriptions-item>
|
|
14
|
+
<el-descriptions-item label="姓名">{{user.uname}}</el-descriptions-item>
|
|
15
|
+
<el-descriptions-item label="岗位">安环部,部长</el-descriptions-item>
|
|
16
|
+
<el-descriptions-item label="手机号码">{{user.phone}}</el-descriptions-item>
|
|
17
|
+
</el-descriptions>
|
|
18
|
+
<router-link to="/password"><el-button>修改密码</el-button></router-link>
|
|
19
|
+
</el-col>
|
|
20
|
+
</el-row>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script setup lang="ts">
|
|
25
|
+
// import default_avatar from '../../../assets/zsys/default_avatar.png'
|
|
26
|
+
import breadcrumb from '../main/breadcrumb.vue';
|
|
27
|
+
import { HttpApiV1 as http } from '../../core/httpapi/http_api_v1';
|
|
28
|
+
import { onMounted, ref} from 'vue';
|
|
29
|
+
|
|
30
|
+
const user=ref({
|
|
31
|
+
uid:0,
|
|
32
|
+
uname:'',
|
|
33
|
+
user_name:'',
|
|
34
|
+
phone:''
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
onMounted(()=>{
|
|
38
|
+
http.Post(http.url_usercenter,{}).then((res)=>{
|
|
39
|
+
if(res.IsSuccess){
|
|
40
|
+
let d=res.data as {
|
|
41
|
+
uid:number
|
|
42
|
+
uname:string
|
|
43
|
+
user_name:string
|
|
44
|
+
phone:string
|
|
45
|
+
}
|
|
46
|
+
user.value=d
|
|
47
|
+
// user.uid=d.uid
|
|
48
|
+
// user.phone=d.phone
|
|
49
|
+
// user.uname=d.uname
|
|
50
|
+
// user.user_name=d.user_name
|
|
51
|
+
}
|
|
52
|
+
}).catch((err)=>{
|
|
53
|
+
console.log(err);
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
<style scoped>
|
|
61
|
+
|
|
62
|
+
</style>
|
package/view/sys/sys.vue
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<breadcrumb />
|
|
3
|
+
<div style="padding: 0px 20px; margin-top: 20px">
|
|
4
|
+
<el-tabs v-model="tab">
|
|
5
|
+
<el-tab-pane label="基础" name="base">
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
</el-tab-pane>
|
|
9
|
+
</el-tabs>
|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
import { ref } from 'vue';
|
|
16
|
+
const tab = ref('base')
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<style scoped></style>
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
<!-- ReusableDialog.vue -->
|
|
2
|
+
<template>
|
|
3
|
+
<el-dialog v-model="visible" title="修改密码" :align-center="true" :before-close="handleBeforeClose" width="450"
|
|
4
|
+
:draggable="true" :overflow="true" @open="open" @opened="focus" destroy-on-close :close-on-click-modal="false">
|
|
5
|
+
<!-- 默认插槽放主要内容 -->
|
|
6
|
+
<el-alert title="请为这个账号输入一个新密码" type="info" show-icon :closable="false" />
|
|
7
|
+
<el-form @submit.prevent ref="ruleFormRef" :model="form" :rules="rules"
|
|
8
|
+
style="padding-left: 10px;padding-right: 10px; margin-top: 10px;" label-width="auto"
|
|
9
|
+
v-loading="view.loading" :disabled="view.saving">
|
|
10
|
+
<el-form-item label="新密码" prop="new_p">
|
|
11
|
+
<el-input ref="inputRef" v-model="form.new_p" style="width: 300px;" />
|
|
12
|
+
</el-form-item>
|
|
13
|
+
</el-form>
|
|
14
|
+
|
|
15
|
+
<!-- 底部按钮区插槽 -->
|
|
16
|
+
<template #footer>
|
|
17
|
+
<div style="display: flex;justify-content: right;">
|
|
18
|
+
<el-tooltip content="快捷键 Alt+S" :show-after="800">
|
|
19
|
+
<el-button type="primary" @click="submitForm(ruleFormRef)" :disabled="view.loading"
|
|
20
|
+
:loading="view.saving">确认修改(<el-text tag="ins" style="color: white;">S</el-text>)</el-button>
|
|
21
|
+
</el-tooltip>
|
|
22
|
+
|
|
23
|
+
<el-button @click="close">取消</el-button>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
</template>
|
|
27
|
+
</el-dialog>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script setup lang="ts">
|
|
31
|
+
import { ref, watch, reactive, type PropType } from 'vue';
|
|
32
|
+
import { HttpApiV1 as http } from '../../core/httpapi/http_api_v1';
|
|
33
|
+
import { ZSYSMessage } from '../../components/message';
|
|
34
|
+
import type { FormInstance, FormRules, ElInput } from 'element-plus'
|
|
35
|
+
import { useMagicKeys, whenever } from '@vueuse/core'
|
|
36
|
+
import type { HttpApiReturnData } from '../../core/httpapi/http_api_return_data';
|
|
37
|
+
import { Md5 } from 'ts-md5';
|
|
38
|
+
|
|
39
|
+
const inputRef = ref<InstanceType<typeof ElInput> | null>(null)
|
|
40
|
+
const props = defineProps({
|
|
41
|
+
modelValue: { type: Boolean, required: true }, // 控制显示隐藏
|
|
42
|
+
id: { type: BigInt as unknown as PropType<bigint>, required: true }
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const emit = defineEmits<{
|
|
46
|
+
(e: 'update:modelValue', value: boolean): void;
|
|
47
|
+
// (e: 'confirm'): void;
|
|
48
|
+
// (e: 'close'): void;
|
|
49
|
+
}>();
|
|
50
|
+
|
|
51
|
+
const visible = ref(false);
|
|
52
|
+
|
|
53
|
+
// 同步外部 v-model 变化
|
|
54
|
+
watch(
|
|
55
|
+
() => props.modelValue,
|
|
56
|
+
(val) => {
|
|
57
|
+
visible.value = val;
|
|
58
|
+
},
|
|
59
|
+
{ immediate: true }
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// 内部状态变化通知外部
|
|
63
|
+
watch(visible, (val) => {
|
|
64
|
+
emit('update:modelValue', val);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
//弹窗显示时的处理
|
|
68
|
+
const open = () => {
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
const close = () => {
|
|
74
|
+
visible.value = false;
|
|
75
|
+
// emit('close');
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const handleBeforeClose = (done: () => void) => {
|
|
79
|
+
ruleFormRef.value?.clearValidate();
|
|
80
|
+
// 可以在这里添加关闭前的拦截逻辑
|
|
81
|
+
done();
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const view = reactive({
|
|
85
|
+
loading: false,
|
|
86
|
+
saving: false,
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
//^^^^^^^^^^^^^^^上方为对话框功能^^^^^^^^^^^^^^^
|
|
90
|
+
|
|
91
|
+
//===============下方为数据部分===============
|
|
92
|
+
|
|
93
|
+
//=================表单
|
|
94
|
+
const ruleFormRef = ref<FormInstance>()
|
|
95
|
+
const form = ref({
|
|
96
|
+
uid: props.id as bigint,
|
|
97
|
+
new_p: "",
|
|
98
|
+
})
|
|
99
|
+
const rules = reactive<FormRules<typeof form>>({
|
|
100
|
+
new_p: [
|
|
101
|
+
{ required: true, message: '请输入新密码', trigger: 'blur' },
|
|
102
|
+
],
|
|
103
|
+
})
|
|
104
|
+
//=================
|
|
105
|
+
|
|
106
|
+
//保存
|
|
107
|
+
const saveData = async (): Promise<HttpApiReturnData> => {
|
|
108
|
+
return await http.Post(http.url_user_change_pwd, { uid: form.value.uid, new_p: Md5.hashStr(form.value.new_p) })
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
//验证表单处理界面并保存
|
|
112
|
+
const submitForm = (formEl: FormInstance | undefined) => {
|
|
113
|
+
if (!formEl) return
|
|
114
|
+
formEl.validate(async (valid) => {
|
|
115
|
+
if (valid) {
|
|
116
|
+
view.saving = true
|
|
117
|
+
try {
|
|
118
|
+
let res = await saveData()
|
|
119
|
+
if (res.IsSuccess) {
|
|
120
|
+
// emit('confirm');
|
|
121
|
+
close();
|
|
122
|
+
ZSYSMessage.ShowSuccess("修改成功")
|
|
123
|
+
} else {
|
|
124
|
+
ZSYSMessage.ShowError(res.message)
|
|
125
|
+
}
|
|
126
|
+
} catch (e) {
|
|
127
|
+
|
|
128
|
+
} finally {
|
|
129
|
+
// emit('confirm');
|
|
130
|
+
// close();
|
|
131
|
+
view.saving = false
|
|
132
|
+
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const focus = () => {
|
|
139
|
+
inputRef.value?.focus()
|
|
140
|
+
inputRef.value?.select()
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
//==========快捷键
|
|
144
|
+
const keys = useMagicKeys()
|
|
145
|
+
|
|
146
|
+
whenever(keys.alt_s, () => {
|
|
147
|
+
if (visible.value) {
|
|
148
|
+
console.log('Alt+S提交')
|
|
149
|
+
submitForm(ruleFormRef.value)
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
</script>
|
|
154
|
+
|
|
155
|
+
<style scoped></style>
|