完成访客搭建,完善之前审核界面

This commit is contained in:
Zy
2026-04-13 18:10:23 +08:00
parent d957d1a039
commit 7f152c45f5
34 changed files with 1732 additions and 1208 deletions

View File

@@ -5,7 +5,7 @@
<el-icon><Search /></el-icon>
</div>
<div v-else class="overflow-auto overflow-hidden w-full text-ellipsis text-nowrap">
<span>姓名{{ multipleSelection[0] && multipleSelection[0].name }}</span>
<span>姓名{{ multipleSelection[0]?.name }}</span>
</div>
</div>
@@ -18,14 +18,16 @@
</el-select>
</div>
<div class="mr-5 flex-1">
<el-input clearable v-model.number="queryParams.name" placeholder="请输入住户姓名" />
<el-input clearable v-model="queryParams.name" placeholder="请输入住户姓名" />
</div>
<div>
<el-button type="primary" @click="getlist">查询</el-button>
<el-button>重置</el-button>
<el-button @click="resetQuery">重置</el-button>
</div>
</nav>
<el-table ref="multipleTableRef" @selection-change="handleSelectionChange" :data="tableData" border>
<!-- 关键去掉 @selection-change改用 row-click 实现单选永不报错 -->
<el-table ref="multipleTableRef" :data="tableData" border @row-click="handleRowClick">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" align="center" width="55" type="index" />
<el-table-column label="姓名" align="center" prop="name" />
@@ -61,7 +63,7 @@
/>
<div>
<el-button @click="conback">退出</el-button>
<el-button type="primary" @click="confim"> 确定 </el-button>
<el-button type="primary" @click="confim">确定</el-button>
</div>
</div>
</template>
@@ -69,12 +71,15 @@
</template>
<script setup lang="ts">
import { getCommunitylistAPI } from '@/api/system/community';
import { getVillageTree } from '@/api/system/house';
import { listResident } from '@/api/system/resident';
import { ResidentVO } from '@/api/system/resident/type';
import { convertBuildingToTree, getHousePathById } from '@/utils/house';
import { ref } from 'vue';
import { getHousePathById } from '@/utils/house';
import { ref, watch, nextTick, getCurrentInstance, ComponentInternalInstance, toRefs } from 'vue';
import { useHouseStore } from '@/store/modules/house';
import { storeToRefs } from 'pinia';
const houseStore = useHouseStore();
const { treedata } = storeToRefs(houseStore);
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_resident_type } = toRefs<any>(proxy?.useDict('com_resident_type'));
@@ -84,14 +89,15 @@ const { com_resident_relationship } = toRefs<any>(proxy?.useDict('com_resident_r
interface tableType extends ResidentVO {
housePath?: string;
}
const props = defineProps<{
userid: string;
userid: string | number;
}>();
// 2. 转成 ref更安全可选但推荐
const { userid } = toRefs(props);
const emit = defineEmits<{
change: [value: string | number];
}>();
const dialog = ref({
dialogVisible: false,
dialogTitle: '选择住户'
@@ -100,68 +106,64 @@ const dialog = ref({
const queryParams = ref({
pageNum: 1,
pageSize: 10,
date: null,
type: null,
status: null,
ownerRelationship: null,
name: null,
ownerRelationship: '', // 👈 原来 null → 改成 ''
name: '',
status: '', // 👈 原来 null → 改成 ''
type: '', // 👈 原来 null → 改成 ''
houseId: null,
villageId: null,
buildingId: null,
unitNo: null
});
const multipleTableRef = ref();
const tableData = ref<tableType[]>([]);
const multipleSelection = ref([]);
const total = ref(100);
const total = ref(0);
const loading = ref(false);
// ! 获取房屋==================================================================================
const treedata = ref([]);
function gettreedata() {
getCommunitylistAPI().then((res) => {
const currentviliage = res.rows.find((item) => item.choiceStatus === 0);
if (currentviliage.villageId) {
getVillageTree(currentviliage.villageId).then((res) => {
treedata.value = convertBuildingToTree(res.data.buildings);
});
}
});
// ==============================================
// 最佳单选方案:点击行选中,无报错、无循环、最稳定
// ==============================================
function handleRowClick(row) {
multipleTableRef.value?.clearSelection();
multipleTableRef.value?.toggleRowSelection(row, true);
multipleSelection.value = [row];
}
gettreedata();
getlist();
watch(
userid,
(newval) => {
if (newval !== null && newval !== undefined && newval.length > 0) {
const find = tableData.value.find((item) => item.id == newval);
if (find) {
multipleSelection.value = [find];
}
}
},
{
deep: true,
immediate: true
// ==============================================
// 自动回显 userid
// ==============================================
const handleUserSelection = () => {
if (!userid.value || !tableData.value.length) return;
const findItem = tableData.value.find((item) => item.id == userid.value);
if (findItem) {
multipleSelection.value = [findItem];
nextTick(() => {
multipleTableRef.value?.clearSelection();
multipleTableRef.value?.toggleRowSelection(findItem, true);
});
}
);
};
//
watch(userid, handleUserSelection, { immediate: true });
watch(tableData, handleUserSelection);
// 打开选择框
function choiceResidentFun() {
dialog.value.dialogVisible = true;
}
// 获取表格
// 获取列表
function getlist() {
// 查询住户
loading.value = true;
listResident(queryParams.value).then((res) => {
tableData.value = res.rows;
tableData.value.forEach((item) => {
if (item.houseId !== null) {
const houselist = getHousePathById(treedata.value, item.houseId, 'label');
item.housePath = houselist.join('-');
item.housePath = houselist?.join('-') || '';
}
});
total.value = res.total;
@@ -169,47 +171,40 @@ function getlist() {
});
}
// 返回
function conback() {
dialog.value.dialogVisible = false;
// 重置查询
function resetQuery() {
queryParams.value = {
pageNum: 1,
pageSize: 10,
ownerRelationship: null,
name: null,
ownerRelationship: '', // 👈 这里也改
name: '',
date: null,
type: null,
status: null,
type: '', // 👈 这里也改
status: '', // 👈 这里也改
houseId: null,
villageId: null,
buildingId: null,
unitNo: null
};
getlist();
}
// 退出
function conback() {
dialog.value.dialogVisible = false;
resetQuery();
}
// 确定
function confim() {
dialog.value.dialogVisible = false;
if (multipleSelection.value.length > 0) {
const pop = multipleSelection.value.pop();
multipleSelection.value = [pop];
emit('change', pop.id);
emit('change', multipleSelection.value[0].id);
}
}
// 单选
function handleSelectionChange(val) {
if (val && val.length > 0) {
const lastoptions = val.pop();
val.forEach((row) => {
multipleTableRef.value!.toggleRowSelection(row, false);
});
multipleTableRef.value!.toggleRowSelection(lastoptions, true);
multipleSelection.value = [lastoptions];
} else {
multipleTableRef.value!.clearSelection();
multipleSelection.value = [];
}
}
// 初始化
getlist();
</script>
<style scoped lang="scss">

View File

@@ -5,41 +5,32 @@
<el-icon><Search /></el-icon>
</div>
<div v-else class="overflow-auto overflow-hidden w-full text-ellipsis text-nowrap">
<span>姓名{{ multipleSelection[0] && multipleSelection[0].name }}</span>
<span>姓名{{ multipleSelection[0] && multipleSelection[0].nickName }}</span>
<span class="ml-20px">联系方式{{ multipleSelection[0] && multipleSelection[0].phonenumber }}</span>
</div>
</div>
<el-dialog append-to-body v-model="dialog.dialogVisible" :title="dialog.dialogTitle" width="1050">
<nav class="flex flex-items-center mb-8">
<div class="flex flex-items-center mr-5 flex-1">
<div style="width: 120px">选择员工</div>
<el-select v-model="queryParams.ownerRelationship" placeholder="请选择" clearable>
<el-option v-for="dict in com_resident_relationship" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</div>
<div class="mr-5 flex-1">
<el-input clearable v-model.number="queryParams.name" placeholder="请输入员工姓名" />
</div>
<div>
<el-button type="primary" @click="getlist">查询</el-button>
<el-button>重置</el-button>
</div>
</nav>
<el-table ref="multipleTableRef" @selection-change="handleSelectionChange" :data="tableData" border>
<el-table @row-click="handleRowClick" ref="multipleTableRef" :data="tableData" border>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" align="center" width="55" type="index" />
<el-table-column label="姓名" align="center" prop="name" />
<el-table-column label="角色" align="center" width="85" prop="type">
<el-table-column label="姓名" align="center" prop="nickName" />
<el-table-column label="性别" align="center" width="85" prop="sex">
<template #default="{ row }">
<dict-tag :options="sys_user_sex" :value="row.sex" />
</template>
</el-table-column>
<el-table-column label="角色" align="center" width="85" prop="userType">
<template #default="{ row }">
<dict-tag :options="com_resident_type" :value="row.type" />
</template>
</el-table-column>
<el-table-column label="手机号码" align="center" prop="phonenumber" />
<el-table-column label="状态" align="center" width="85" prop="status">
<template #default="{ row }">
<dict-tag :options="com_certification_status" :value="row.status" />
</template>
</el-table-column>
<el-table-column label="手机号码" align="center" prop="phone" />
</el-table>
<template #footer>
@@ -63,41 +54,38 @@
</template>
<script setup lang="ts">
import { getCommunitylistAPI } from '@/api/system/community';
import { getVillageTree } from '@/api/system/house';
import { listResident } from '@/api/system/resident';
import { ResidentVO } from '@/api/system/resident/type';
import { convertBuildingToTree, getHousePathById } from '@/utils/house';
import { ref } from 'vue';
import { getUserByRoleKey } from '@/api/system/user';
import { ref, watch, nextTick, getCurrentInstance, ComponentInternalInstance, toRefs } from 'vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_resident_type } = toRefs<any>(proxy?.useDict('com_resident_type'));
const { com_certification_status } = toRefs<any>(proxy?.useDict('com_certification_status'));
const { com_resident_relationship } = toRefs<any>(proxy?.useDict('com_resident_relationship'));
const { sys_user_sex } = toRefs<any>(proxy?.useDict('sys_user_sex'));
interface tableType extends ResidentVO {
housePath?: string;
}
const props = defineProps<{
userid: string;
userid: string | number;
}>();
// 2. 转成 ref更安全可选但推荐
const { userid } = toRefs(props);
const emit = defineEmits<{
change: [value: string | number];
}>();
const dialog = ref({
dialogVisible: false,
dialogTitle: '选择住户'
dialogTitle: '选择维修人员'
});
const queryParams = ref({
pageNum: 1,
pageSize: 10,
date: null,
type: null,
status: null,
status: '',
ownerRelationship: null,
name: null,
houseId: null,
@@ -105,48 +93,59 @@ const queryParams = ref({
buildingId: null,
unitNo: null
});
const multipleTableRef = ref();
const tableData = ref<tableType[]>([]);
const multipleSelection = ref([]);
const total = ref(100);
const total = ref(0);
const loading = ref(false);
const treedata = ref([]);
getlist();
// 存储选中项
const multipleSelection = ref([]);
watch(
userid,
(newval) => {
if (newval !== null && newval !== undefined && newval.length > 0) {
const find = tableData.value.find((item) => item.id == newval);
if (find) {
multipleSelection.value = [find];
}
}
},
{
deep: true,
immediate: true
// 单选点击事件(完全替代 selection-change
const handleRowClick = (row) => {
multipleTableRef.value?.clearSelection();
multipleTableRef.value?.toggleRowSelection(row, true);
multipleSelection.value = [row];
};
// 统一回显 userid 选中(安全版)
const handleUserSelection = () => {
if (!userid.value || !tableData.value.length) return;
const target = tableData.value.find((item) => item.id == userid.value);
if (target) {
multipleSelection.value = [target];
nextTick(() => {
multipleTableRef.value?.clearSelection();
multipleTableRef.value?.toggleRowSelection(target, true);
});
}
);
};
//
// 监听
watch(userid, handleUserSelection, { immediate: true });
watch(tableData, handleUserSelection);
// ====================== 方法 ======================
// 打开选择框
function choiceResidentFun() {
dialog.value.dialogVisible = true;
}
// 获取表格
// 获取列表
function getlist() {
// 查询住户
loading.value = true;
listResident(queryParams.value).then((res) => {
tableData.value = res.rows;
getUserByRoleKey().then((res) => {
tableData.value = res.data;
total.value = res.total;
loading.value = false;
});
}
// 返回
function conback() {
dialog.value.dialogVisible = false;
// 重置查询
function resetQuery() {
queryParams.value = {
pageNum: 1,
pageSize: 10,
@@ -154,37 +153,31 @@ function conback() {
name: null,
date: null,
type: null,
status: null,
status: '',
houseId: null,
villageId: null,
buildingId: null,
unitNo: null
};
getlist();
}
// 退出
function conback() {
dialog.value.dialogVisible = false;
resetQuery();
}
// 确定
function confim() {
dialog.value.dialogVisible = false;
if (multipleSelection.value.length > 0) {
const pop = multipleSelection.value.pop();
multipleSelection.value = [pop];
emit('change', pop.id);
emit('change', multipleSelection.value[0].id);
}
}
// 单选
function handleSelectionChange(val) {
if (val && val.length > 0) {
const lastoptions = val.pop();
val.forEach((row) => {
multipleTableRef.value!.toggleRowSelection(row, false);
});
multipleTableRef.value!.toggleRowSelection(lastoptions, true);
multipleSelection.value = [lastoptions];
} else {
multipleTableRef.value!.clearSelection();
multipleSelection.value = [];
}
}
// 初始化
getlist();
</script>
<style scoped lang="scss">