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