zhzf/client/src/components/SimpleEnterpriseSelector.vue

200 lines
5.0 KiB
Vue
Raw Normal View History

2025-02-21 11:25:09 +08:00
<template>
<BaseSelector
v-model="cvalue"
:config="{
filterable: true,
remote: false,
multiple: multiple
}"
:option-props="{
key: 'enterpriseId',
label: 'unitName',
value: 'enterpriseId'
}"
:data="filteredEnterprises"
:filter-method="filterMethod"
:placeholder="placeholder"
@change="handleChange"
@select-load-option="loadEnterprises">
<template v-slot:loadMore>
<div class="left-info-bar" @click="loadMore"><span>还有条 {{leftTotal}} 记录</span></div>
</template>
</BaseSelector>
</template>
<script setup>
// 引入组件和API
import { ref, computed, watch, onMounted } from 'vue'
import enterpriseApi from '@/api/lawenforcement/Enterprise'
import BaseSelector from './BaseSelector.vue'
// 定义props
const props = defineProps({
// 是否多选
multiple: {
type: Boolean,
default: false
},
// 占位符文本
placeholder: {
type: String,
default: '请选择企业'
},
// v-model绑定值
modelValue: {
type: [Array, String, Number],
default: () => []
},
// 执法机构Id用于过滤企业
agencyId: {
type: [String, Number],
default: ''
},
// 执法机构code用于过滤企业
agencyCode: {
type: [String],
default: ''
},
// defaultEnterpriseIds用于过滤企业
defaultEnterpriseIds: {
type: [Array, String, Number],
default: () => []
},
// 是否显示所有数据
isShowAll: {
type: Boolean,
default: true
}
})
// 定义emit
const emit = defineEmits(['update:modelValue', 'change'])
// 定义响应式数据
const query = ref({
page: 1,
pagesize: 20
})
const enterprises = ref([])
const leftTotal = ref(0)
const loading = ref(false)
// 内部值的计算属性
const cvalue = computed({
get: () => props.modelValue,
set: (val) => {
// 处理内部值变化并发送到外部
let formattedValue = val
// 如果是单选模式且值为数组,取第一个元素
if (!props.multiple && Array.isArray(formattedValue) && formattedValue.length > 0) {
formattedValue = formattedValue[0]
}
// 如果是多选模式但值不是数组,转换为数组
if (props.multiple && !Array.isArray(formattedValue)) {
formattedValue = formattedValue ? [formattedValue] : []
}
emit('update:modelValue', formattedValue)
}
})
// 过滤后的企业列表
const filteredEnterprises = computed(() => {return enterprises.value})
// 加载企业数据
const loadEnterprises = async () => {
loading.value = true
try {
if (!props.agencyId && !props.agencyCode && !props.isShowAll) {
return
}
query.value.agencyId = props.agencyId || '1'
query.value.agencyCode = props.agencyCode || '1'
query.value.enterpriseIds = props.defaultEnterpriseIds || []
const res = await enterpriseApi.findEnterprisesByAgencyId(query.value)
if (res.success) {
enterprises.value = mergeAndDeduplicate(enterprises.value, res.data)
leftTotal.value = res.total - enterprises.value.length
}
loading.value = false
} catch (error) {
console.error('获取企业数据失败:', error)
loading.value = false
}
}
function mergeAndDeduplicate(existing, newItems) {
let idMap = new Map()
existing.forEach(item => idMap.set(item.enterpriseId, item))
newItems.forEach(item => { if (!idMap.has(item.enterpriseId)) idMap.set(item.enterpriseId, item) })
return Array.from(idMap.values())
}
// 处理选择变更
const handleChange = (val) => {
// 找到选中的企业完整信息
let selectedEnterprises
if (Array.isArray(val)) {
selectedEnterprises = enterprises.value.filter(enterprise => val.includes(enterprise.enterpriseId))
} else {
const selectedEnterprise = enterprises.value.find(enterprise => enterprise.enterpriseId === val)
selectedEnterprises = selectedEnterprise ? [selectedEnterprise] : []
}
// 触发change事件传递完整的企业信息
emit('change', props.multiple ? selectedEnterprises : (selectedEnterprises[0] || null))
}
// 加载更多
const loadMore = () => {
query.value.page += 1
loadEnterprises()
}
// 过滤信息
const filterMethod = (val) => {
if (val) {
if (props.defaultEnterpriseIds.length > 0) {
let enterpriseMap = new Map(enterprises.value.map(item => [item.enterpriseId, item]))
let filteredEnterprises = props.defaultEnterpriseIds.map(enterpriseId => enterpriseMap.get(enterpriseId))
enterprises.value = filteredEnterprises
} else {
enterprises.value = []
}
query.value.page = 1
query.value.unitName = val
loadEnterprises()
}
}
// 监听agencyId变化
watch(() => [props.agencyId, props.defaultEnterpriseIds], () => {
enterprises.value = []
query.value.page = 1
query.value.unitName = ''
loadEnterprises()
},{ deep: true })
// 生命周期钩子
onMounted(() => {
// 组件挂载时加载企业数据
// 实际上在select-load-option事件中已经处理了
})
</script>
<style lang="scss" scoped>
.left-info-bar {
color: #0D88FC;
}
</style>