From e9283ffe6822b12ec5dd2ccf4dc13a369b227a61 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期一, 30 三月 2026 08:32:06 +0800
Subject: [PATCH] chore: sync rsf-design from isolated worktree
---
rsf-design/src/views/system/user/modules/user-dialog.vue | 355 +++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 275 insertions(+), 80 deletions(-)
diff --git a/rsf-design/src/views/system/user/modules/user-dialog.vue b/rsf-design/src/views/system/user/modules/user-dialog.vue
index 706c5c3..72725a3 100644
--- a/rsf-design/src/views/system/user/modules/user-dialog.vue
+++ b/rsf-design/src/views/system/user/modules/user-dialog.vue
@@ -1,106 +1,301 @@
<template>
<ElDialog
- v-model="dialogVisible"
- :title="dialogType === 'add' ? '娣诲姞鐢ㄦ埛' : '缂栬緫鐢ㄦ埛'"
- width="30%"
+ :title="dialogTitle"
+ :model-value="visible"
+ @update:model-value="handleCancel"
+ width="960px"
align-center
+ class="user-dialog"
+ @closed="handleClosed"
>
- <ElForm ref="formRef" :model="formData" :rules="rules" label-width="80px">
- <ElFormItem label="鐢ㄦ埛鍚�" prop="username">
- <ElInput v-model="formData.username" placeholder="璇疯緭鍏ョ敤鎴峰悕" />
- </ElFormItem>
- <ElFormItem label="鎵嬫満鍙�" prop="phone">
- <ElInput v-model="formData.phone" placeholder="璇疯緭鍏ユ墜鏈哄彿" />
- </ElFormItem>
- <ElFormItem label="鎬у埆" prop="gender">
- <ElSelect v-model="formData.gender">
- <ElOption label="鐢�" value="鐢�" />
- <ElOption label="濂�" value="濂�" />
- </ElSelect>
- </ElFormItem>
- <ElFormItem label="瑙掕壊" prop="role">
- <ElSelect v-model="formData.role" multiple>
- <ElOption
- v-for="role in roleList"
- :key="role.roleCode"
- :value="role.roleCode"
- :label="role.roleName"
- />
- </ElSelect>
- </ElFormItem>
- </ElForm>
+ <ArtForm
+ ref="formRef"
+ v-model="form"
+ :items="formItems"
+ :rules="rules"
+ :span="12"
+ :gutter="20"
+ label-width="110px"
+ :show-reset="false"
+ :show-submit="false"
+ />
+
<template #footer>
- <div class="dialog-footer">
- <ElButton @click="dialogVisible = false">鍙栨秷</ElButton>
- <ElButton type="primary" @click="handleSubmit">鎻愪氦</ElButton>
- </div>
+ <span class="dialog-footer">
+ <ElButton @click="handleCancel">鍙栨秷</ElButton>
+ <ElButton type="primary" @click="handleSubmit">纭畾</ElButton>
+ </span>
</template>
</ElDialog>
</template>
<script setup>
- import { ROLE_LIST_DATA } from '@/mock/temp/formData'
+ import ArtForm from '@/components/core/forms/art-form/index.vue'
+ import { buildUserDialogModel, createUserFormState } from '../userPage.helpers'
+
const props = defineProps({
- visible: { required: true },
- type: { required: true },
- userData: { required: false }
+ visible: { required: false, default: false },
+ type: { required: false, default: 'add' },
+ userData: { required: false, default: () => ({}) },
+ roleOptions: { required: false, default: () => [] },
+ deptTreeOptions: { required: false, default: () => [] }
})
+
const emit = defineEmits(['update:visible', 'submit'])
- const roleList = ref(ROLE_LIST_DATA)
- const dialogVisible = computed({
- get: () => props.visible,
- set: (value) => emit('update:visible', value)
- })
- const dialogType = computed(() => props.type)
const formRef = ref()
- const formData = reactive({
- username: '',
- phone: '',
- gender: '鐢�',
- role: []
- })
- const rules = {
- username: [
- { required: true, message: '璇疯緭鍏ョ敤鎴峰悕', trigger: 'blur' },
- { min: 2, max: 20, message: '闀垮害鍦� 2 鍒� 20 涓瓧绗�', trigger: 'blur' }
- ],
- phone: [
- { required: true, message: '璇疯緭鍏ユ墜鏈哄彿', trigger: 'blur' },
- { pattern: /^1[3-9]\d{9}$/, message: '璇疯緭鍏ユ纭殑鎵嬫満鍙锋牸寮�', trigger: 'blur' }
- ],
- gender: [{ required: true, message: '璇烽�夋嫨鎬у埆', trigger: 'blur' }],
- role: [{ required: true, message: '璇烽�夋嫨瑙掕壊', trigger: 'blur' }]
+ const form = reactive(createUserFormState())
+
+ const isEdit = computed(() => props.type === 'edit')
+ const dialogTitle = computed(() => (isEdit.value ? '缂栬緫鐢ㄦ埛' : '鏂板鐢ㄦ埛'))
+
+ const validatePassword = (_rule, value, callback) => {
+ if (!isEdit.value && !value) {
+ callback(new Error('璇疯緭鍏ュ瘑鐮�'))
+ return
+ }
+ if (value && String(value).length < 6) {
+ callback(new Error('瀵嗙爜闀垮害鑷冲皯 6 浣�'))
+ return
+ }
+ callback()
}
- const initFormData = () => {
- const isEdit = props.type === 'edit' && props.userData
- const row = props.userData
- Object.assign(formData, {
- username: isEdit && row ? row.userName || '' : '',
- phone: isEdit && row ? row.userPhone || '' : '',
- gender: isEdit && row ? row.userGender || '鐢�' : '鐢�',
- role: isEdit && row ? (Array.isArray(row.userRoles) ? row.userRoles : []) : []
- })
+
+ const validateConfirmPassword = (_rule, value, callback) => {
+ if (!form.password && !value && isEdit.value) {
+ callback()
+ return
+ }
+ if (!value) {
+ callback(new Error('璇峰啀娆¤緭鍏ュ瘑鐮�'))
+ return
+ }
+ if (value !== form.password) {
+ callback(new Error('涓ゆ杈撳叆鐨勫瘑鐮佷笉涓�鑷�'))
+ return
+ }
+ callback()
}
+
+ const rules = computed(() => ({
+ username: [{ required: true, message: '璇疯緭鍏ョ敤鎴峰悕', trigger: 'blur' }],
+ nickname: [{ required: true, message: '璇疯緭鍏ユ樀绉�', trigger: 'blur' }],
+ roleIds: [{ type: 'array', required: true, message: '璇烽�夋嫨瑙掕壊', trigger: 'change' }],
+ password: [{ validator: validatePassword, trigger: 'blur' }],
+ confirmPassword: [{ validator: validateConfirmPassword, trigger: 'blur' }]
+ }))
+
+ const formItems = computed(() => [
+ {
+ label: '鐢ㄦ埛鍚�',
+ key: 'username',
+ type: 'input',
+ props: {
+ placeholder: '璇疯緭鍏ョ敤鎴峰悕',
+ clearable: true
+ }
+ },
+ {
+ label: '鏄电О',
+ key: 'nickname',
+ type: 'input',
+ props: {
+ placeholder: '璇疯緭鍏ユ樀绉�',
+ clearable: true
+ }
+ },
+ {
+ label: '閮ㄩ棬',
+ key: 'deptId',
+ type: 'treeselect',
+ props: {
+ data: props.deptTreeOptions,
+ props: {
+ label: 'label',
+ value: 'value',
+ children: 'children'
+ },
+ placeholder: '璇烽�夋嫨閮ㄩ棬',
+ clearable: true,
+ checkStrictly: true
+ }
+ },
+ {
+ label: '瑙掕壊',
+ key: 'roleIds',
+ type: 'select',
+ props: {
+ placeholder: '璇烽�夋嫨瑙掕壊',
+ clearable: true,
+ multiple: true,
+ collapseTags: true,
+ filterable: true,
+ options: props.roleOptions
+ }
+ },
+ {
+ label: '瀵嗙爜',
+ key: 'password',
+ type: 'input',
+ props: {
+ type: 'password',
+ showPassword: true,
+ placeholder: isEdit.value ? '涓嶄慨鏀瑰垯鐣欑┖' : '璇疯緭鍏ュ瘑鐮�',
+ clearable: true
+ }
+ },
+ {
+ label: '纭瀵嗙爜',
+ key: 'confirmPassword',
+ type: 'input',
+ props: {
+ type: 'password',
+ showPassword: true,
+ placeholder: '璇峰啀娆¤緭鍏ュ瘑鐮�',
+ clearable: true
+ }
+ },
+ {
+ label: '鎬у埆',
+ key: 'sex',
+ type: 'select',
+ props: {
+ placeholder: '璇烽�夋嫨鎬у埆',
+ clearable: true,
+ options: [
+ { label: '鏈煡', value: 0 },
+ { label: '鐢�', value: 1 },
+ { label: '濂�', value: 2 }
+ ]
+ }
+ },
+ {
+ label: '宸ュ彿',
+ key: 'code',
+ type: 'input',
+ props: {
+ placeholder: '璇疯緭鍏ュ伐鍙�',
+ clearable: true
+ }
+ },
+ {
+ label: '鎵嬫満鍙�',
+ key: 'phone',
+ type: 'input',
+ props: {
+ placeholder: '璇疯緭鍏ユ墜鏈哄彿',
+ clearable: true
+ }
+ },
+ {
+ label: '閭',
+ key: 'email',
+ type: 'input',
+ props: {
+ placeholder: '璇疯緭鍏ラ偖绠�',
+ clearable: true
+ }
+ },
+ {
+ label: '鐪熷疄濮撳悕',
+ key: 'realName',
+ type: 'input',
+ props: {
+ placeholder: '璇疯緭鍏ョ湡瀹炲鍚�',
+ clearable: true
+ }
+ },
+ {
+ label: '韬唤璇佸彿',
+ key: 'idCard',
+ type: 'input',
+ props: {
+ placeholder: '璇疯緭鍏ヨ韩浠借瘉鍙�',
+ clearable: true
+ }
+ },
+ {
+ label: '鐘舵��',
+ key: 'status',
+ type: 'select',
+ props: {
+ placeholder: '璇烽�夋嫨鐘舵��',
+ clearable: true,
+ options: [
+ { label: '姝e父', value: 1 },
+ { label: '绂佺敤', value: 0 }
+ ]
+ }
+ },
+ {
+ label: '澶囨敞',
+ key: 'memo',
+ type: 'input',
+ props: {
+ type: 'textarea',
+ rows: 3,
+ placeholder: '璇疯緭鍏ュ娉�',
+ clearable: true
+ },
+ span: 24
+ }
+ ])
+
+ const resetForm = () => {
+ Object.assign(form, createUserFormState())
+ formRef.value?.clearValidate?.()
+ }
+
+ const loadFormData = () => {
+ Object.assign(form, buildUserDialogModel(props.userData))
+ }
+
+ const handleSubmit = async () => {
+ if (!formRef.value) return
+ try {
+ await formRef.value.validate()
+ emit('submit', { ...form })
+ } catch {
+ return
+ }
+ }
+
+ const handleCancel = () => {
+ emit('update:visible', false)
+ }
+
+ const handleClosed = () => {
+ resetForm()
+ }
+
watch(
- () => [props.visible, props.type, props.userData],
- ([visible]) => {
+ () => props.visible,
+ (visible) => {
if (visible) {
- initFormData()
+ loadFormData()
nextTick(() => {
- formRef.value?.clearValidate()
+ formRef.value?.clearValidate?.()
})
}
},
{ immediate: true }
)
- const handleSubmit = async () => {
- if (!formRef.value) return
- await formRef.value.validate((valid) => {
- if (valid) {
- ElMessage.success(dialogType.value === 'add' ? '娣诲姞鎴愬姛' : '鏇存柊鎴愬姛')
- dialogVisible.value = false
- emit('submit')
+
+ watch(
+ () => props.userData,
+ () => {
+ if (props.visible) {
+ loadFormData()
}
- })
- }
+ },
+ { deep: true }
+ )
+
+ watch(
+ () => props.type,
+ () => {
+ if (props.visible) {
+ loadFormData()
+ }
+ }
+ )
</script>
--
Gitblit v1.9.1