车位区域管理完成
This commit is contained in:
@@ -16,57 +16,63 @@
|
||||
<el-col :span="12">
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">住户姓名:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<span> {{ userInfo.name }} </span>
|
||||
</div>
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">手机号码:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<span> {{ userInfo.phone }} </span>
|
||||
</div>
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">证件类型:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<span> 身份证 </span>
|
||||
</div>
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">住户类型:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<span v-if="userInfo.type === 0"> 业主 </span>
|
||||
<span v-else-if="userInfo.type === 1"> 亲戚 </span>
|
||||
<span v-else> 租户 </span>
|
||||
</div>
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">住户来源:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<span> {{ userInfo.name }} </span>
|
||||
</div>
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">注册时间:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<span> {{ userInfo.name }} </span>
|
||||
</div>
|
||||
<div class="userinfo_item">
|
||||
<div class="userinfo_item img">
|
||||
<div class="title_item">身份证正面:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<div class="userinfo_itme_img">
|
||||
<el-image class="w-full h-full" fit="fill" :src="userInfo.cardImageFront"></el-image>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">住户编号:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<span> {{ userInfo.id }} </span>
|
||||
</div>
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">住户性别:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<span> {{ userInfo.gender === 1 ? '男' : '女' }} </span>
|
||||
</div>
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">证件号码:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<span> {{ userInfo.idCard }} </span>
|
||||
</div>
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">备注:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<span> {{ userInfo.remark ?? '无' }} </span>
|
||||
</div>
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">提交审核时间:</div>
|
||||
<span> 去丽丽 </span>
|
||||
</div>
|
||||
<div class="userinfo_item">
|
||||
<div class="title_item">身份证正面:</div>
|
||||
<span> 去丽丽 </span>
|
||||
<div class="userinfo_item img">
|
||||
<div class="title_item">身份证背面:</div>
|
||||
<div class="userinfo_itme_img">
|
||||
<el-image class="w-full h-full" fit="fill" :src="userInfo.cardImageFront"></el-image>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -83,7 +89,7 @@
|
||||
<div class="w-full h-full flex mt-2">
|
||||
<div class="title">审批意见</div>
|
||||
<div class="preivewBodybox">
|
||||
<el-input placeholder="请输入" type="textarea" :rows="5"></el-input>
|
||||
<el-input v-model="reviewInfo.propertyReviewFeedback" placeholder="请输入" type="textarea" :rows="5"></el-input>
|
||||
<div class="actions">
|
||||
<el-button type="primary">审核通过</el-button>
|
||||
<el-button type="danger">审核不通过</el-button>
|
||||
@@ -105,10 +111,31 @@
|
||||
</div>
|
||||
</template>
|
||||
<div class="w-full h-50%">
|
||||
<el-steps direction="vertical" :active="0">
|
||||
<el-step title="提交信息" description="2023/4/23 10:28:43" />
|
||||
<el-step title="物业审核" description="2023/4/23 11:10:58" />
|
||||
<el-step title="认证通过" description="2023/4/23 12:35:22" />
|
||||
<el-steps space="200px" direction="vertical" :active="activeStop">
|
||||
<el-step :description="reviewInfo.submitTime">
|
||||
<template #title>
|
||||
<span v-if="active === 0">未提交信息</span>
|
||||
<span v-if="active >= 1">已提交信息</span>
|
||||
</template>
|
||||
</el-step>
|
||||
<el-step :description="reviewInfo.propertyTime">
|
||||
<template #title>
|
||||
<span v-if="active <= 2">待审核</span>
|
||||
<span v-if="active === 3">物业审核不通过</span>
|
||||
<span v-if="active >= 4">物业审核通过</span>
|
||||
</template>
|
||||
</el-step>
|
||||
<el-step :description="reviewInfo.certificationTime">
|
||||
<template #title>
|
||||
<span v-if="active <= 5">未认证</span>
|
||||
<span v-if="active === 6">已认证</span>
|
||||
</template>
|
||||
</el-step>
|
||||
<el-step>
|
||||
<template #title>
|
||||
<span>审核完成</span>
|
||||
</template>
|
||||
</el-step>
|
||||
</el-steps>
|
||||
</div>
|
||||
</el-card>
|
||||
@@ -120,6 +147,100 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import PageHeader from '@/components/Pageheader/index.vue';
|
||||
import { getResident, getresidentReviewlistAPI } from '@/api/system/resident';
|
||||
import { ResidentVO } from '@/api/system/resident/type';
|
||||
|
||||
const userInfo = ref<ResidentVO>({
|
||||
code: null,
|
||||
villageId: '',
|
||||
buildingId: '',
|
||||
'id': null,
|
||||
'name': '',
|
||||
'type': null,
|
||||
'gender': null,
|
||||
'status': null,
|
||||
'idCard': '',
|
||||
'phone': null,
|
||||
'houseId': null,
|
||||
'remark': null,
|
||||
'cardImageFront': '',
|
||||
'cardImageBack': ''
|
||||
});
|
||||
|
||||
const reviewInfo = ref({
|
||||
'id': null,
|
||||
'residentId': null,
|
||||
'submitTime': '',
|
||||
'submitStatus': 1,
|
||||
'propertyTime': null,
|
||||
'propertyStatus': null,
|
||||
'propertyReviewFeedback': '',
|
||||
'certificationTime': null,
|
||||
'certificationStatus': null
|
||||
});
|
||||
/** 住户审核状态 */
|
||||
enum reviewStatus {
|
||||
/** 未提交 */
|
||||
unSubmit = 0,
|
||||
/** 已提交 */
|
||||
Submited = 1,
|
||||
/** 待认证 */
|
||||
awaitReview = 2,
|
||||
/** 认证不通过 */
|
||||
unReviewPass = 3,
|
||||
/** 认证通过 */
|
||||
ReviewPass = 4,
|
||||
/** 未认证 */
|
||||
uncertification = 5,
|
||||
/** 已认证 */
|
||||
Certification = 6
|
||||
}
|
||||
type activeType = reviewStatus;
|
||||
const active = ref<activeType>(6);
|
||||
const activeStop = ref(4);
|
||||
const userid = ref(null);
|
||||
const route = useRoute();
|
||||
if (route.query.id) {
|
||||
userid.value = route.query.id;
|
||||
getResident(userid.value).then((res) => {
|
||||
userInfo.value = res.data;
|
||||
getresidentReviewlistAPI(userid.value).then((res) => {
|
||||
console.log(res);
|
||||
if (res.rows[0]) {
|
||||
reviewInfo.value = res.rows[0];
|
||||
handleActivestaus(reviewInfo.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleActivestaus(rews) {
|
||||
if (rews.submitStatus === reviewStatus.unSubmit) {
|
||||
activeStop.value = 0;
|
||||
active.value = 0;
|
||||
} else if (rews.submitStatus === reviewStatus.Submited) {
|
||||
active.value = 1;
|
||||
activeStop.value = 1;
|
||||
// 待认证
|
||||
if (rews.propertyStatus === 0) {
|
||||
active.value = reviewStatus.awaitReview;
|
||||
} else if (rews.propertyStatus === 1) {
|
||||
active.value = reviewStatus.unReviewPass;
|
||||
} else if (rews.propertyStatus === 2) {
|
||||
active.value = reviewStatus.ReviewPass;
|
||||
activeStop.value = 2;
|
||||
|
||||
if (rews.certificationStatus === 0) {
|
||||
active.value = reviewStatus.uncertification;
|
||||
} else if (rews.certificationStatus === 1) {
|
||||
active.value = reviewStatus.Certification;
|
||||
activeStop.value = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(active.value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -137,15 +258,24 @@ import PageHeader from '@/components/Pageheader/index.vue';
|
||||
}
|
||||
.userinfo_item {
|
||||
margin-bottom: 20px;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
min-height: 40px;
|
||||
line-height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: peru;
|
||||
font-size: 14px;
|
||||
.title_item {
|
||||
margin-right: 10px;
|
||||
width: 100px;
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
}
|
||||
&.img {
|
||||
align-items: flex-start;
|
||||
height: 200px;
|
||||
.userinfo_itme_img {
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,6 +332,9 @@ import PageHeader from '@/components/Pageheader/index.vue';
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
&:deep(.el-step.is-vertical .el-step__line) {
|
||||
top: 20px;
|
||||
}
|
||||
&:deep(div.el-step__head.is-finish) {
|
||||
& > div.el-step__line {
|
||||
width: 0;
|
||||
|
||||
@@ -108,7 +108,7 @@ import { ref } from 'vue';
|
||||
import PageHeader from '@/components/Pageheader/index.vue';
|
||||
import { useHouseStore } from '@/store/modules/house';
|
||||
import { addHouseAPI, EditHouseApi, getHouseApi, getHouselistAPI, getVillageTree } from '@/api/system/house';
|
||||
import { convertBuildingToTree, getHousePathById, ownerRelationshiplist } from './index';
|
||||
import { convertBuildingToTree, getHousePathById, ownerRelationshiplist } from '@/utils/house';
|
||||
import { ResidentForm } from '@/api/system/resident/type';
|
||||
import { CascaderValue, UploadFiles, UploadInstance, UploadProps, UploadRawFile } from 'element-plus';
|
||||
import { genFileId } from 'element-plus';
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
interface Tree {
|
||||
label: string;
|
||||
value: number;
|
||||
type: string;
|
||||
children?: Tree[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 楼栋/单元/房屋 转 Tree 结构(跳过楼层)
|
||||
* @param buildings 原始楼栋数组
|
||||
* @returns Tree[]
|
||||
*/
|
||||
export function convertBuildingToTree(buildings: any[]): Tree[] {
|
||||
if (!buildings || !Array.isArray(buildings)) return [];
|
||||
|
||||
return buildings.map((building) => {
|
||||
// 1. 楼栋
|
||||
const buildingTree: Tree = {
|
||||
label: building.buildingName || '未知楼栋',
|
||||
type: 'buildingId',
|
||||
value: building.buildingId,
|
||||
children: []
|
||||
};
|
||||
|
||||
// 2. 单元
|
||||
const units = building.units || [];
|
||||
const unitTrees = units.map((unit: any) => {
|
||||
const unitTree: Tree = {
|
||||
label: `${unit.unitNo} 单元`,
|
||||
value: unit.unitNo,
|
||||
type: 'unitNo',
|
||||
children: []
|
||||
};
|
||||
|
||||
// ====================== 关键修改 ======================
|
||||
// 直接从 floors 里把所有 house 全部抽出来,跳过 floor 层级
|
||||
const allHouses: any[] = [];
|
||||
const floors = unit.floors || [];
|
||||
|
||||
floors.forEach((floor: any) => {
|
||||
const houses = floor.houses || [];
|
||||
allHouses.push(...houses); // 把所有房屋合并到一个数组
|
||||
});
|
||||
|
||||
// 房屋直接挂在单元下
|
||||
unitTree.children = allHouses.map((house: any) => ({
|
||||
label: house.houseNo || '未知房屋',
|
||||
value: house.houseId,
|
||||
type: 'houseId'
|
||||
}));
|
||||
// ======================================================
|
||||
|
||||
return unitTree;
|
||||
});
|
||||
|
||||
buildingTree.children = unitTrees;
|
||||
console.log(buildingTree);
|
||||
return buildingTree;
|
||||
});
|
||||
}
|
||||
|
||||
// 证件类型
|
||||
const idCardTypelist = [{}];
|
||||
|
||||
// 与业主关系
|
||||
export const ownerRelationshiplist = [
|
||||
{
|
||||
label: '业主',
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
label: '亲属',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: '租户',
|
||||
value: 2
|
||||
}
|
||||
];
|
||||
|
||||
interface Tree {
|
||||
label: string;
|
||||
value: number;
|
||||
type: string;
|
||||
children?: Tree[];
|
||||
}
|
||||
// 只允许 字符串/数字 类型的 key
|
||||
type ValidTreeKey = {
|
||||
[K in keyof Tree]: Tree[K] extends string | number ? K : never;
|
||||
}[keyof Tree];
|
||||
|
||||
/**
|
||||
* 根据 houseId 查找完整路径(楼栋 > 单元 > 楼层 > 房屋)
|
||||
* @param treeData 转换后的树形数据
|
||||
* @param houseId 目标房屋ID
|
||||
* @returns string[] 路径数组,如 ['1号楼', '1单元', '3层', '301']
|
||||
*/
|
||||
export function getHousePathById(treeData: Tree[], houseId: number, response: ValidTreeKey = 'value'): (string | number)[] {
|
||||
const path: (string | number)[] = [];
|
||||
|
||||
// 递归查找
|
||||
function findNode(nodes: Tree[]): boolean {
|
||||
for (const node of nodes) {
|
||||
path.push(node[response]); // 把当前节点加入路径
|
||||
|
||||
// 找到目标房屋
|
||||
if (node.type === 'houseId' && node.value === houseId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 递归子节点
|
||||
if (node.children && node.children.length > 0) {
|
||||
if (findNode(node.children)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
path.pop(); // 回溯,移除当前节点
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
findNode(treeData);
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证身份证号码(18位,支持尾号x/X)
|
||||
* @param idCard 身份证号
|
||||
* @return {boolean} true 符合 false 不符合
|
||||
*/
|
||||
export function validateIdCard(idCard: string): boolean {
|
||||
// 18位身份证正则
|
||||
const reg = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
|
||||
return reg.test(idCard.trim());
|
||||
}
|
||||
@@ -99,10 +99,11 @@ import { listResident, getResident, delResident, addResident, updateResident } f
|
||||
import { ResidentVO, ResidentQuery, ResidentForm } from '@/api/system/resident/type';
|
||||
import { getVillageTree } from '@/api/system/house/index';
|
||||
import { getCommunitylistAPI } from '@/api/system/community';
|
||||
import { convertBuildingToTree, getHousePathById } from './index';
|
||||
import { RootTreeType, TreeNode } from 'element-plus';
|
||||
import { convertBuildingToTree, getHousePathById } from '@/utils/house';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { com_house_rental_facilities } = toRefs<any>(proxy?.useDict('com_house_rental_facilities'));
|
||||
|
||||
const router = useRouter();
|
||||
const residentList = ref<ResidentVO[]>([]);
|
||||
const loading = ref(true);
|
||||
|
||||
Reference in New Issue
Block a user