|
@ -12,29 +12,56 @@ |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="menu" v-show="isOpen"> |
|
|
<div class="menu" v-show="isOpen"> |
|
|
<div class="coin"> |
|
|
|
|
|
<div class="coinselect"> |
|
|
|
|
|
coin1 |
|
|
|
|
|
|
|
|
<div class="coinselect" @click="coinhandelMenu" :class="{ 'active': coinisOpen }"> |
|
|
|
|
|
<div class="cointxt"> |
|
|
|
|
|
金币产品 |
|
|
|
|
|
</div> |
|
|
|
|
|
<span class="coin-arrow"> |
|
|
|
|
|
<el-icon> |
|
|
|
|
|
<ArrowDown /> |
|
|
|
|
|
</el-icon> |
|
|
|
|
|
</span> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="coinoption" v-show="coinisOpen"> |
|
|
|
|
|
<el-checkbox v-model="isCoinRechargeChecked" label="金币充值" size="large" /> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="product"> |
|
|
|
|
|
<div class="coinselect" @click="producthandelMenu" :class="{ 'active': productisOpen }"> |
|
|
|
|
|
<div class="cointxt"> |
|
|
|
|
|
软件产品 |
|
|
|
|
|
</div> |
|
|
<span class="coin-arrow"> |
|
|
<span class="coin-arrow"> |
|
|
<el-icon> |
|
|
<el-icon> |
|
|
<ArrowDown /> |
|
|
<ArrowDown /> |
|
|
</el-icon> |
|
|
</el-icon> |
|
|
</span> |
|
|
</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="coinoption"> |
|
|
|
|
|
coIn2 |
|
|
|
|
|
|
|
|
<div class="productOption"> |
|
|
|
|
|
<div class="productOption" v-show="productisOpen"> |
|
|
|
|
|
<div class="checktxt">AI机构探测神器</div> |
|
|
|
|
|
<!-- 全选框 --> |
|
|
|
|
|
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange"> |
|
|
|
|
|
全选 |
|
|
|
|
|
</el-checkbox> |
|
|
|
|
|
<el-checkbox-group v-model="selectedSoftwareItems" @change="handleCheckedItemsChange"> |
|
|
|
|
|
<el-checkbox label="软件A" size="large" /> |
|
|
|
|
|
<el-checkbox label="软件B" size="large" /> |
|
|
|
|
|
<el-checkbox label="软件C" size="large" /> |
|
|
|
|
|
</el-checkbox-group> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="product"> |
|
|
|
|
|
22 |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</template> |
|
|
</template> |
|
|
<script setup> |
|
|
<script setup> |
|
|
import { ref, computed, watchEffect, onMounted } from 'vue'; |
|
|
|
|
|
|
|
|
import { ref, watch } from 'vue'; |
|
|
|
|
|
import { ArrowDown } from '@element-plus/icons-vue'; |
|
|
|
|
|
|
|
|
const searchData = ref('') |
|
|
const searchData = ref('') |
|
|
const isOpen = ref(false) |
|
|
const isOpen = ref(false) |
|
|
|
|
|
const coinisOpen = ref(false) |
|
|
|
|
|
const productisOpen = ref(false) |
|
|
const selectedItem = ref('') |
|
|
const selectedItem = ref('') |
|
|
const dropdownRef = ref(null) |
|
|
const dropdownRef = ref(null) |
|
|
const placeholder = ref('请选择产品') |
|
|
const placeholder = ref('请选择产品') |
|
@ -42,6 +69,67 @@ const placeholder = ref('请选择产品') |
|
|
const handelMenu = () => { |
|
|
const handelMenu = () => { |
|
|
isOpen.value = !isOpen.value |
|
|
isOpen.value = !isOpen.value |
|
|
} |
|
|
} |
|
|
|
|
|
const coinhandelMenu = () => { |
|
|
|
|
|
coinisOpen.value = !coinisOpen.value |
|
|
|
|
|
} |
|
|
|
|
|
const producthandelMenu = () => { |
|
|
|
|
|
productisOpen.value = !productisOpen.value |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 接收父组件通过 v-model 传入的值 |
|
|
|
|
|
const props = defineProps({ |
|
|
|
|
|
modelValue: { |
|
|
|
|
|
type: Array, |
|
|
|
|
|
default: () => [] |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits(['update:modelValue']) |
|
|
|
|
|
|
|
|
|
|
|
const isCoinRechargeChecked = ref(false) |
|
|
|
|
|
const selectedSoftwareItems = ref([]) |
|
|
|
|
|
const selectedValue = ref([]) |
|
|
|
|
|
|
|
|
|
|
|
// 全选相关 |
|
|
|
|
|
const checkAll = ref(false) |
|
|
|
|
|
const isIndeterminate = ref(false) |
|
|
|
|
|
const softwareItems = ['软件A', '软件B', '软件C'] |
|
|
|
|
|
|
|
|
|
|
|
// 监听金币充值选中状态变化 |
|
|
|
|
|
watch(isCoinRechargeChecked, (newVal) => { |
|
|
|
|
|
if (newVal) { |
|
|
|
|
|
selectedSoftwareItems.value = []; |
|
|
|
|
|
selectedValue.value = newVal ? ['金币充值'] : []; |
|
|
|
|
|
// 重置全选相关状态 |
|
|
|
|
|
checkAll.value = false; |
|
|
|
|
|
isIndeterminate.value = false; |
|
|
|
|
|
} else { |
|
|
|
|
|
selectedValue.value = selectedSoftwareItems.value.length > 0 ? selectedSoftwareItems.value : []; |
|
|
|
|
|
} |
|
|
|
|
|
emit('update:modelValue', selectedValue.value); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 监听软件选中项变化 |
|
|
|
|
|
watch(selectedSoftwareItems, (newVals) => { |
|
|
|
|
|
if (newVals.length > 0) { |
|
|
|
|
|
isCoinRechargeChecked.value = false; |
|
|
|
|
|
selectedValue.value = newVals; |
|
|
|
|
|
} else { |
|
|
|
|
|
selectedValue.value = isCoinRechargeChecked.value ? ['金币充值'] : []; |
|
|
|
|
|
} |
|
|
|
|
|
emit('update:modelValue', selectedValue.value); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 全选逻辑 |
|
|
|
|
|
const handleCheckAllChange = (val) => { |
|
|
|
|
|
selectedSoftwareItems.value = val ? softwareItems : [] |
|
|
|
|
|
isIndeterminate.value = false |
|
|
|
|
|
} |
|
|
|
|
|
const handleCheckedItemsChange = (value) => { |
|
|
|
|
|
const checkedCount = value.length |
|
|
|
|
|
checkAll.value = checkedCount === softwareItems.length |
|
|
|
|
|
isIndeterminate.value = checkedCount > 0 && checkedCount < softwareItems.length |
|
|
|
|
|
} |
|
|
</script> |
|
|
</script> |
|
|
<style scoped lang="scss"> |
|
|
<style scoped lang="scss"> |
|
|
.productContent { |
|
|
.productContent { |
|
@ -53,9 +141,7 @@ const handelMenu = () => { |
|
|
.selectBox { |
|
|
.selectBox { |
|
|
border: 1px solid #e5e7eb; |
|
|
border: 1px solid #e5e7eb; |
|
|
padding: 4px 12px; |
|
|
padding: 4px 12px; |
|
|
/* 调整内边距以匹配按钮高度 */ |
|
|
|
|
|
height: 23px; |
|
|
height: 23px; |
|
|
/* 调整高度以匹配按钮 */ |
|
|
|
|
|
cursor: pointer; |
|
|
cursor: pointer; |
|
|
display: flex; |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
justify-content: space-between; |
|
@ -72,7 +158,6 @@ const handelMenu = () => { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 箭头图标:展开时旋转 |
|
|
|
|
|
.arrow { |
|
|
.arrow { |
|
|
margin-left: 8px; |
|
|
margin-left: 8px; |
|
|
color: #999; |
|
|
color: #999; |
|
@ -85,10 +170,11 @@ const handelMenu = () => { |
|
|
|
|
|
|
|
|
.menu { |
|
|
.menu { |
|
|
position: absolute; |
|
|
position: absolute; |
|
|
top: 100%; // 紧贴触发器下方 |
|
|
|
|
|
|
|
|
top: 100%; |
|
|
left: 0; |
|
|
left: 0; |
|
|
width: 130%; |
|
|
width: 130%; |
|
|
max-height: 600px; |
|
|
max-height: 600px; |
|
|
|
|
|
min-height: 200px; |
|
|
display: flex; |
|
|
display: flex; |
|
|
padding: 10px; |
|
|
padding: 10px; |
|
|
flex-direction: column; |
|
|
flex-direction: column; |
|
@ -100,22 +186,40 @@ const handelMenu = () => { |
|
|
box-shadow: 0 0 4px 0 #00000040; |
|
|
box-shadow: 0 0 4px 0 #00000040; |
|
|
z-index: 100; |
|
|
z-index: 100; |
|
|
|
|
|
|
|
|
|
|
|
.coinselect { |
|
|
|
|
|
width: 100px; |
|
|
|
|
|
height: 20px; |
|
|
|
|
|
border: 1px solid #175BE5; |
|
|
|
|
|
padding: 5px 0 5px 12px; |
|
|
|
|
|
display: flex; |
|
|
|
|
|
border-radius: 5px; |
|
|
|
|
|
|
|
|
.coin { |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
|
|
|
|
|
|
.coinselect { |
|
|
|
|
|
width: 100px; |
|
|
|
|
|
height: 30px; |
|
|
|
|
|
border: 1px solid #175BE5; |
|
|
|
|
|
padding: 5px 0 5px 12px; |
|
|
|
|
|
|
|
|
.cointxt { |
|
|
|
|
|
width: 70px; |
|
|
|
|
|
height: 100%; |
|
|
display: flex; |
|
|
display: flex; |
|
|
|
|
|
|
|
|
.coin-arrow { |
|
|
|
|
|
margin-top: 8px; |
|
|
|
|
|
color: #111; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
color: #175be5; |
|
|
|
|
|
text-align: center; |
|
|
|
|
|
font-family: "PingFang SC"; |
|
|
|
|
|
font-size: 14px; |
|
|
|
|
|
font-style: normal; |
|
|
|
|
|
font-weight: 700; |
|
|
|
|
|
line-height: 20px; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.coin-arrow { |
|
|
|
|
|
flex: 1; |
|
|
|
|
|
display: flex; |
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
color: #175BE5; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.coinselect.active .coin-arrow { |
|
|
|
|
|
transform: rotate(-90deg); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
</style> |
|
|
</style> |