263 lines
6.6 KiB
Vue
263 lines
6.6 KiB
Vue
<template>
|
||
<el-drawer
|
||
v-model="visible"
|
||
title="添加成员"
|
||
size="600px"
|
||
:destroy-on-close="true"
|
||
>
|
||
<div class="drawer-content">
|
||
<div class="search-box">
|
||
<el-input v-model="queryParams.name" placeholder="请输入姓名" clearable style="width: 180px; margin-right: 10px;" />
|
||
<el-input v-model="queryParams.mobile" placeholder="请输入手机号码" clearable style="width: 180px; margin-right: 10px;" />
|
||
<el-button type="primary" @click="handleQuery">
|
||
<Icon icon="ep:search" class="mr-5px" /> 搜索
|
||
</el-button>
|
||
<el-button @click="resetQuery">
|
||
<Icon icon="ep:refresh" class="mr-5px" /> 重置
|
||
</el-button>
|
||
</div>
|
||
<div class="table-container">
|
||
<el-table
|
||
:data="list"
|
||
style="width: 100%"
|
||
@selection-change="handleSelectionChange"
|
||
v-loading="loading"
|
||
>
|
||
<el-table-column type="selection" width="55" />
|
||
<el-table-column label="编号" prop="id" />
|
||
<el-table-column label="姓名" prop="name" />
|
||
<el-table-column label="手机号码" prop="mobile" />
|
||
<el-table-column label="关系" width="150">
|
||
<template #default="{ row }">
|
||
<!-- 只有勾选时才显示下拉框,relation 值会自动同步到 selectedMembers 中对应成员对象的 relation 字段 -->
|
||
<el-select
|
||
v-if="selectedMembers.some(member => member.id === row.id)"
|
||
v-model="row.relation"
|
||
placeholder="请选择关系"
|
||
style="width: 100%"
|
||
>
|
||
<el-option label="兄弟" :value=2 />
|
||
<el-option label="父亲" :value=3 />
|
||
<el-option label="母亲" :value=4 />
|
||
<el-option label="子女" :value=5 />
|
||
<el-option label="其他" :value=6 />
|
||
</el-select>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<!-- 分页控件 -->
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
v-model:current-page="queryParams.pageNo"
|
||
v-model:page-size="queryParams.pageSize"
|
||
:total="total"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
@size-change="handleSizeChange"
|
||
@current-change="handleCurrentChange"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div class="drawer-footer">
|
||
<el-button @click="handleCancel">取 消</el-button>
|
||
<el-button type="primary" @click="handleConfirm" :disabled="selectedMembers.length === 0">
|
||
确 定
|
||
</el-button>
|
||
</div>
|
||
</div>
|
||
</el-drawer>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { ref, computed, watch, onMounted } from 'vue'
|
||
import { PersonApi, type PersonVO } from '@/api/person'
|
||
import { Icon } from '@/components/Icon'
|
||
import { getUserProfile } from '@/api/system/user/profile'
|
||
|
||
interface FamilyMember {
|
||
id: number
|
||
name: string
|
||
mobile: string
|
||
age: number
|
||
gender: string
|
||
relation: number
|
||
address: string
|
||
createTime: string
|
||
}
|
||
|
||
const props = defineProps<{
|
||
modelValue: boolean
|
||
}>()
|
||
|
||
const emit = defineEmits<{
|
||
(e: 'update:modelValue', value: boolean): void
|
||
(e: 'confirm', members: FamilyMember[]): void
|
||
}>()
|
||
|
||
const visible = ref(props.modelValue)
|
||
// 选中的成员数组,relation 字段即为下拉框选择的关系值
|
||
const selectedMembers = ref<FamilyMember[]>([])
|
||
const list = ref<FamilyMember[]>([])
|
||
const loading = ref(false)
|
||
const total = ref(0)
|
||
const queryParams = reactive({
|
||
pageNo: 1,
|
||
pageSize: 10,
|
||
name: '',
|
||
mobile: '',
|
||
orgid: undefined,
|
||
})
|
||
|
||
// 获取成员数据
|
||
const getList = async () => {
|
||
try {
|
||
loading.value = true
|
||
const userProfile = await getUserProfile()
|
||
queryParams.orgid = userProfile.dept.orgid
|
||
const res = await PersonApi.getPersonNoFamilyid(queryParams)
|
||
if (res.list) {
|
||
list.value = res.list.map((item: PersonVO) => ({
|
||
id: item.id,
|
||
name: item.name,
|
||
mobile: item.phone,
|
||
relation: getFamilyRelation(item.familyrelation),
|
||
address: item.address || '',
|
||
createTime: item.createtime,
|
||
familyid: item.familyid,
|
||
familyrelation: item.familyrelation,
|
||
orgid: item.orgid,
|
||
}))
|
||
total.value = res.total
|
||
}
|
||
} catch (error) {
|
||
console.error('获取成员数据失败:', error)
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
// 获取家庭关系文本
|
||
const getFamilyRelation = (relation: number): string => {
|
||
const relationMap: Record<number, string> = {
|
||
2: '兄弟',
|
||
3: '父亲',
|
||
4: '母亲',
|
||
5: '子女',
|
||
6: '其他'
|
||
}
|
||
return relationMap[relation] || '其他'
|
||
}
|
||
|
||
// 搜索按钮操作
|
||
const handleQuery = () => {
|
||
queryParams.pageNo = 1
|
||
getList()
|
||
}
|
||
|
||
// 重置按钮操作
|
||
const resetQuery = () => {
|
||
queryParams.pageNo = 1
|
||
queryParams.name = ''
|
||
queryParams.mobile = ''
|
||
getList()
|
||
}
|
||
|
||
// 处理每页显示数量变化
|
||
const handleSizeChange = (val: number) => {
|
||
queryParams.pageSize = val
|
||
getList()
|
||
}
|
||
|
||
// 处理页码变化
|
||
const handleCurrentChange = (val: number) => {
|
||
queryParams.pageNo = val
|
||
getList()
|
||
}
|
||
|
||
// 监听visible变化
|
||
watch(() => props.modelValue, (val) => {
|
||
visible.value = val
|
||
if (val) {
|
||
getList()
|
||
}
|
||
})
|
||
|
||
// 监听visible变化并同步到父组件
|
||
watch(visible, (val) => {
|
||
emit('update:modelValue', val)
|
||
})
|
||
|
||
// 处理选择变化
|
||
const handleSelectionChange = (selection: FamilyMember[]) => {
|
||
selectedMembers.value = selection
|
||
// 确保每个选中的成员都有 relation 属性,relation 值即为下拉框选择的关系
|
||
selection.forEach(member => {
|
||
if (!member.relation) {
|
||
member.relation = 6 // 默认设置为"其他"
|
||
}
|
||
})
|
||
}
|
||
|
||
// 取消
|
||
const handleCancel = () => {
|
||
visible.value = false
|
||
selectedMembers.value = []
|
||
}
|
||
|
||
// 确认
|
||
const handleConfirm = () => {
|
||
emit('confirm', selectedMembers.value)
|
||
handleCancel()
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.drawer-content {
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.search-box {
|
||
padding: 16px;
|
||
border-bottom: 1px solid #e4e7ed;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.table-container {
|
||
flex: 1;
|
||
overflow: auto;
|
||
height: calc(100vh - 250px);
|
||
margin: 0 16px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
:deep(.el-table) {
|
||
flex: 1;
|
||
}
|
||
|
||
:deep(.el-table__header-wrapper) {
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 1;
|
||
}
|
||
|
||
:deep(.el-table__body-wrapper) {
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.pagination-container {
|
||
padding: 16px 0;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.drawer-footer {
|
||
padding: 16px;
|
||
text-align: right;
|
||
border-top: 1px solid #e4e7ed;
|
||
}
|
||
</style>
|