fjrcloud-community-ui/src/views/community/memberhouse/MemberHouseForm.vue

487 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="800px">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="小区名称" prop="communityId">
<el-select
v-model="formData.communityId"
placeholder="请选择小区"
clearable
filterable
style="width: 100%"
@change="handleCommunityChange"
>
<el-option
v-for="item in communityOptions"
:key="item.id"
:label="item.communityName"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="房号" prop="roomNo">
<div style="display: flex; gap: 15px;">
<el-select
v-model="formData.buildingNo"
placeholder="请选择楼号"
clearable
filterable
style="flex: 2"
@change="handleBuildingChange"
>
<el-option
v-for="item in buildingOptions"
:key="item.value"
:label="item.label"
:value="item.label"
/>
</el-select>
<el-select
v-model="formData.unitNo"
placeholder="请选择单元"
clearable
filterable
style="flex: 2"
@change="handleUnitChange"
>
<el-option
v-for="item in unitOptions"
:key="item.value"
:label="item.label"
:value="item.label"
/>
</el-select>
<el-select
v-model="formData.roomNo"
placeholder="请选择门牌号"
clearable
filterable
style="flex: 2"
@change="handleRoomChange"
>
<el-option
v-for="item in roomOptions"
:key="item.value"
:label="item.label"
:value="item.label"
/>
</el-select>
</div>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="是否产权人" prop="isOwner">
<el-radio-group v-model="formData.isOwner">
<el-radio
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="与业主关系" prop="relationType">
<el-select v-model="formData.relationType" placeholder="请选择与业主关系" style="width: 100%">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.COMM_RELATION_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name" placeholder="请输入姓名" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系方式" prop="mobile">
<el-input v-model="formData.mobile" placeholder="请输入手机号" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="证件类型" prop="idType">
<el-select v-model="formData.idType" placeholder="请选择证件类型" style="width: 100%">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.COMM_ID_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="证件号码" prop="idNumber">
<el-input v-model="formData.idNumber" placeholder="请输入证件号" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="formData.sex">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出生日期" prop="birthday">
<el-date-picker
v-model="formData.birthday"
type="date"
value-format="YYYY-MM-DD"
placeholder="选择出生日期"
style="width: 100%"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="人脸照片" prop="attachmentUrl">
<UploadImg v-model="formData.attachmentUrl" :limit="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="附件" prop="attachmentUrls">
<UploadImgs v-model="formData.attachmentUrls" :limit="3" />
</el-form-item>
</el-col>
</el-row>
<el-divider content-position="left">
<el-icon><DocumentChecked /></el-icon> 审核
</el-divider>
<el-form-item label="审核意见" prop="auditStatus">
<el-select v-model="formData.auditStatus" placeholder="请选择审核意见" style="width: 100%">
<el-option label="通过" :value="1" />
<el-option label="驳回" :value="2" />
</el-select>
</el-form-item>
<el-form-item label="审核描述" prop="rejectReason">
<el-input
v-model="formData.rejectReason"
type="textarea"
:rows="4"
placeholder="请输入审核描述"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { DocumentChecked } from '@element-plus/icons-vue'
import { MemberHouseApi, MemberHouse } from '@/api/community/memberhouse'
import { CommunityApi, CommunitySimpleVO } from '@/api/community/community'
import { HouseApi, HouseTreeNode } from '@/api/community/house'
import { DICT_TYPE, getBoolDictOptions, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
import UploadImg from '@/components/UploadFile/src/UploadImg.vue'
import UploadImgs from '@/components/UploadFile/src/UploadImgs.vue'
/** 业主认证信息 表单 */
defineOptions({ name: 'MemberHouseForm' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formType = ref('') // 表单的类型create - 新增update - 修改
const formData = ref({
id: undefined,
memberId: undefined,
communityId: undefined,
communityName: '',
houseId: undefined,
buildingNo: '',
unitNo: '',
roomNo: '',
isOwner: 1,
relationType: '',
name: '',
mobile: '',
idType: '',
idNumber: '',
sex: undefined,
birthday: '',
attachmentUrl: '',
attachmentUrls: [],
status: 0,
rejectReason: '',
auditStatus: undefined,
auditUser: '',
auditTime: ''
})
const formRules = reactive({
communityId: [{ required: true, message: '小区不能为空', trigger: 'change' }],
buildingNo: [{ required: true, message: '楼号不能为空', trigger: 'change' }],
unitNo: [{ required: true, message: '单元号不能为空', trigger: 'change' }],
roomNo: [{ required: true, message: '门牌号不能为空', trigger: 'change' }],
isOwner: [{ required: true, message: '请选择是否产权人', trigger: 'change' }],
relationType: [{ required: true, message: '请选择与业主关系', trigger: 'change' }],
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
mobile: [
{ required: true, message: '手机号不能为空', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
],
idType: [{ required: true, message: '请选择证件类型', trigger: 'change' }],
idNumber: [{ required: true, message: '证件号码不能为空', trigger: 'blur' }],
sex: [{ required: true, message: '请选择性别', trigger: 'change' }],
birthday: [{ required: true, message: '出生日期不能为空', trigger: 'change' }],
auditStatus: [{ required: true, message: '请选择审核意见', trigger: 'change' }]
})
const formRef = ref() // 表单 Ref
const communityOptions = ref<CommunitySimpleVO[]>([]) // 小区选项列表
const houseTreeOptions = ref<HouseTreeNode[]>([]) // 房屋树选项
const buildingOptions = ref<HouseTreeNode[]>([]) // 楼号选项
const unitOptions = ref<HouseTreeNode[]>([]) // 单元选项
const roomOptions = ref<HouseTreeNode[]>([]) // 房间选项
/** 加载小区列表 */
const loadCommunityList = async () => {
try {
communityOptions.value = await CommunityApi.getCommunitySimpleList()
// 默认选中第一个小区
if (communityOptions.value.length > 0 && !formData.value.communityId) {
formData.value.communityId = communityOptions.value[0].id
handleCommunityChange(communityOptions.value[0].id)
}
} catch (error) {
console.error('加载小区列表失败:', error)
}
}
/** 小区选择变化 */
const handleCommunityChange = async (communityId: number | undefined) => {
// 清空房屋相关数据
buildingOptions.value = []
unitOptions.value = []
roomOptions.value = []
formData.value.buildingNo = ''
formData.value.unitNo = ''
formData.value.roomNo = ''
formData.value.houseId = undefined
if (communityId) {
// 设置小区名称
const community = communityOptions.value.find(item => item.id === communityId)
if (community) {
formData.value.communityName = community.communityName
}
// 加载房屋树
try {
houseTreeOptions.value = await HouseApi.getHouseTree(communityId)
// 提取楼号选项
buildingOptions.value = houseTreeOptions.value || []
} catch (error) {
console.error('加载房屋树失败:', error)
}
} else {
formData.value.communityName = ''
}
}
/** 楼号选择变化 */
const handleBuildingChange = (buildingLabel: string) => {
// 清空下级数据
unitOptions.value = []
roomOptions.value = []
formData.value.unitNo = ''
formData.value.roomNo = ''
formData.value.houseId = undefined
if (buildingLabel) {
const buildingNode = houseTreeOptions.value.find(n => n.label === buildingLabel)
if (buildingNode?.children) {
unitOptions.value = buildingNode.children
}
}
}
/** 单元号选择变化 */
const handleUnitChange = (unitLabel: string) => {
// 清空下级数据
roomOptions.value = []
formData.value.roomNo = ''
formData.value.houseId = undefined
if (unitLabel) {
const unitNode = unitOptions.value.find(n => n.label === unitLabel)
if (unitNode?.children) {
roomOptions.value = unitNode.children
}
}
}
/** 门牌号选择变化 */
const handleRoomChange = (roomLabel: string) => {
if (roomLabel) {
const roomNode = roomOptions.value.find(n => n.label === roomLabel)
if (roomNode) {
formData.value.houseId = roomNode.value
}
} else {
formData.value.houseId = undefined
}
}
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
// 加载小区列表
await loadCommunityList()
// 修改时,设置数据
if (id) {
formLoading.value = true
try {
const data = await MemberHouseApi.getMemberHouse(id)
formData.value = {
...formData.value,
...data
}
// 回显房屋下拉选项
if (data.communityId) {
try {
houseTreeOptions.value = await HouseApi.getHouseTree(data.communityId)
buildingOptions.value = houseTreeOptions.value || []
// 回显楼号
if (data.buildingNo) {
const buildingNode = houseTreeOptions.value.find(n => n.label === data.buildingNo)
if (buildingNode?.children) {
unitOptions.value = buildingNode.children
// 回显单元
if (data.unitNo) {
const unitNode = buildingNode.children.find(n => n.label === data.unitNo)
if (unitNode?.children) {
roomOptions.value = unitNode.children
// 回显房间
if (data.roomNo) {
const roomNode = unitNode.children.find(n => n.label === data.roomNo)
if (roomNode) {
formData.value.houseId = roomNode.value
}
}
}
}
}
}
} catch (error) {
console.error('加载房屋树失败:', error)
}
}
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
// 校验表单
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as MemberHouse
if (formType.value === 'create') {
await MemberHouseApi.createMemberHouse(data)
message.success(t('common.createSuccess'))
} else {
await MemberHouseApi.updateMemberHouse(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
// 发送操作成功的事件
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
memberId: undefined,
communityId: undefined,
communityName: '',
houseId: undefined,
buildingNo: '',
unitNo: '',
roomNo: '',
isOwner: 1,
relationType: '',
name: '',
mobile: '',
idType: '',
idNumber: '',
sex: undefined,
birthday: '',
attachmentUrl: '',
attachmentUrls: [],
status: 0,
rejectReason: '',
auditStatus: undefined,
auditUser: '',
auditTime: ''
}
buildingOptions.value = []
unitOptions.value = []
roomOptions.value = []
formRef.value?.resetFields()
}
</script>