orgManager/src/components/CheckboxSelect/index.vue

195 lines
5.1 KiB
Vue
Raw Normal View History

2025-08-14 10:38:42 +08:00
<!-- 下拉多选框组件支持传入option组件内接口返回option -->
<template>
<el-select :disabled="needOptions.length === 0 || disabled" v-model="checkedValues" multiple clearable :placeholder="t('请选择')"
popper-class="custom-select-box">
<template #header>
<el-checkbox :disabled="disabledOptions.length > 0" class="checkbox-all" :indeterminate="indeterminate" v-model="checkAll" @change="handleCheckAll">
{{ t('全选') }}
</el-checkbox>
</template>
<el-option class="select-option" :disabled="disabledOptions.indexOf(item.value) !== -1" v-for="item in needOptions" :key="item.value" :value="item.value"
:label="item.label">
<el-checkbox class="so-checkbox" :model-value="isChecked(item.value)" :disabled="disabledOptions.indexOf(item.value) !== -1">
{{ item.label }}
</el-checkbox>
</el-option>
</el-select>
</template>
<script setup>
import { getLocalStorage } from "@/utils/auth";
// import { listChannel } from '@/api/finance/recharge';
// import { listLevel } from "@/api/member/level"; // 会员层级接口
// import { listLabel } from "@/api/member/label"; // 会员层级接口
import { superCommonCurrencySelect } from "@/api/super/tenant";
import { getSuperTenantSelectList,getSuperPlatformSelectList } from "@/api/home";
// 以下参数请选择一种传入
const props = defineProps({
disabled: {
type: Boolean,
default: false
},
options: {
type: Array,
default: []
},
dataType: { // 如果需要组件内获取options传入类型
type: String,
default: ''
},
dictKey: { // 传入字典key多选
type: String,
default: ''
},
disabledOptions: {
type: Array,
default: []
}
});
const checkedValues = defineModel(), // 多选选中的值
needOptions = ref([]), // 多选项
checkAll = ref(false), // 是否全选
indeterminate = ref(false); // 全选框标识
// 当前值是否选中
const isChecked = (value) => {
return checkedValues.value.includes(value);
};
// 全选
const emit = defineEmits(['allSelect']);
const handleCheckAll = (checked) => {
indeterminate.value = false;
if (checked) {
checkedValues.value = needOptions.value.map(_ => _.value);
} else {
checkedValues.value = [];
}
// 沃特玛也不知道为什么值不能及时更新,只能这么写了
setTimeout(() => {
emit('allSelect', checkedValues.value);
});
};
// 币种选择
const getCurrencyTypeList = () => {
const localList = getLocalStorage('currencyList')?.filter(v => v.status == 0) || []; // 本地缓存
if (localList.length) {
needOptions.value = localList.map(item => {
return {
label: item.currencyCode,
value: item.currencyCode
}
})
} else {
superCommonCurrencySelect({}).then(res => {
needOptions.value = res.data.map(item => {
return {
label: item.currencyCode,
value: item.currencyCode
}
});
}).catch(() => {
});
}
}
// 商户
const getListChannel = async () => {
const { data } = await getSuperTenantSelectList({ })
needOptions.value = data.map(item => {
return {
label: item.tenantKey,
value: item.tenantKey
}
});
}
// 平台
const getListLevel = async () => {
const { data } = await getSuperPlatformSelectList({ })
needOptions.value = data.map(item => {
return {
label: item.platformName,
value: item.platformCode
}
});
}
// 会员标签
const getListLabel = async () => {
const { rows } = await listLabel({ pageNumber: 1, pageSize: 50 })
needOptions.value = rows.map(item => {
return {
label: item.labelName,
value: item.id
}
});
}
// 根据传入类型获取需要options
switch (props.dataType) {
case 'currency':
getCurrencyTypeList();
break
case 'tenantSelectList':
getListChannel();
break
case 'platformSelectList':
getListLevel();
break
// case 'label':
// getListLabel();
// break
}
// 传入字典key获取需要的options
const { proxy } = getCurrentInstance();
const _dictKey = props.dictKey;
if (_dictKey) needOptions.value = proxy.useDict(_dictKey)[_dictKey];
// 监听父组件传入options和当前勾选值
watch(() => [checkedValues.value, props.options], (newVal, oldVal) => {
// 传入的options
if (newVal[1].length > 0) {
needOptions.value = newVal[1];
}
// 选中值,确全选按钮状态
if (newVal[0].length === 0) {
checkAll.value = false;
indeterminate.value = false;
} else if (newVal[0].length === needOptions.value.length) {
checkAll.value = true;
indeterminate.value = false;
} else {
indeterminate.value = true;
}
}, { immediate: true, deep: true });
</script>
<style scoped lang='scss'>
.select-option {
width: 100%;
position: relative;
.so-checkbox {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
padding: 0 20px;
box-sizing: border-box;
}
}
</style>