zhzf/client/src/components/SimpleEnterpriseSelector.vue

200 lines
5.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>