200 lines
5.0 KiB
Vue
200 lines
5.0 KiB
Vue
<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>
|