|
@@ -1,252 +1,144 @@
|
|
|
<template>
|
|
|
- <div class="d-flex floatCard" :style="{ 'z-index': 999 }" @mouseleave="handleMouseLeave">
|
|
|
- <v-card class="card">
|
|
|
- <div class="leftCard">
|
|
|
- <div
|
|
|
- class="leftCardItem" :class="{'leftIndexAct': index === leftIndex}"
|
|
|
- v-for="(item, index) in items" :key="item.id"
|
|
|
- @mouseover="handleMouseOver(item, index)"
|
|
|
- >
|
|
|
- <div class="rowItem d-flex">
|
|
|
- <span class="categoryName">{{ item.name }}</span>
|
|
|
- <span class="mdi mdi-menu-right"></span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <v-card class="card rightCardBox">
|
|
|
+ <div v-if="showSelect" class="pa-3 currentSelect">
|
|
|
+ <span>已选择:</span>
|
|
|
+ <v-chip
|
|
|
+ class="mr-3"
|
|
|
+ label
|
|
|
+ size="small"
|
|
|
+ color="primary"
|
|
|
+ closable
|
|
|
+ v-for="k in currentSelect"
|
|
|
+ :key="k.id"
|
|
|
+ @click:close="handleClick(k)"
|
|
|
+ >{{ k.name }}</v-chip>
|
|
|
</div>
|
|
|
- </v-card>
|
|
|
- <v-card v-if="rightObj.show" class="card rightCardBox">
|
|
|
<div class="rightCard">
|
|
|
- <div class="categoryName">{{ rightObj.data.name }}</div>
|
|
|
- <div v-for="(item, index) in rightObj.data.children" :key="item.id">
|
|
|
- <v-divider v-if="index" class="divider"></v-divider>
|
|
|
+ <div v-for="item in items" :key="item.id">
|
|
|
<div class="rowItem d-flex">
|
|
|
<div class="categoryName2">{{ item.name }}</div>
|
|
|
<div class="rightContent">
|
|
|
<div v-if="!item.children?.length"></div>
|
|
|
- <div
|
|
|
- v-else
|
|
|
- :class="['jobItem', {'active': selectItems.includes(val.id)}]"
|
|
|
- v-for="val in item.children"
|
|
|
- :key="val.id"
|
|
|
- @click="handleAreaClick(val, item.name)"
|
|
|
- >
|
|
|
- {{ val.name }}</div>
|
|
|
+ <div
|
|
|
+ v-else
|
|
|
+ :class="['jobItem', {'active': idChecked.includes(val.id)}]"
|
|
|
+ v-for="val in item.children" :key="val.id"
|
|
|
+ @click="handleClick(val)"
|
|
|
+ >{{ val.name }}</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</v-card>
|
|
|
- </div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
+defineOptions({ name:'common-components-area'})
|
|
|
import { getDict } from '@/hooks/web/useDictionaries'
|
|
|
-import { reactive, ref } from 'vue';
|
|
|
-defineOptions({ name:'common-components-jobTypeCard'})
|
|
|
-
|
|
|
-const emits = defineEmits(['handleAreaClick'])
|
|
|
+import { ref } from 'vue'
|
|
|
+import Snackbar from '@/plugins/snackbar'
|
|
|
|
|
|
+const emits = defineEmits(['handleClick'])
|
|
|
const props = defineProps({
|
|
|
- // 是否单选(首页为单选)
|
|
|
- isSingle: {
|
|
|
+ limit: { // 限制最大可选择数量, 不限制传false或者0
|
|
|
+ type: [Number, Boolean],
|
|
|
+ default: 3
|
|
|
+ },
|
|
|
+ select: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ showSelect: {
|
|
|
type: Boolean,
|
|
|
default: false
|
|
|
},
|
|
|
- select: {
|
|
|
+ currentData: {
|
|
|
type: Array,
|
|
|
default: () => []
|
|
|
}
|
|
|
})
|
|
|
-const selectItems = ref([])
|
|
|
-// 回显
|
|
|
-if (props.select.length) {
|
|
|
- selectItems.value = props.select
|
|
|
-}
|
|
|
|
|
|
-// 点击
|
|
|
-const handleAreaClick = async (val, preName) => {
|
|
|
- const obj = selectItems.value.includes(val.id)
|
|
|
- if (props.isSingle) {
|
|
|
- selectItems.value = [val.id]
|
|
|
- } else {
|
|
|
- if (obj) {
|
|
|
- selectItems.value = selectItems.value.filter(e => e.id !== val.id)
|
|
|
- } else selectItems.value.push(val.id)
|
|
|
- }
|
|
|
- emits('handleAreaClick', selectItems.value, val.name, preName)
|
|
|
-}
|
|
|
+let items = ref()
|
|
|
+let idChecked = ref([])
|
|
|
+let currentSelect = ref([])
|
|
|
+// 回显
|
|
|
+if (props.currentData.length) currentSelect.value = props.currentData
|
|
|
+console.log(props.select, 'props')
|
|
|
+if (props.select.length) idChecked.value = props.select.map(e => e + '') // 数据中的id是字符串
|
|
|
|
|
|
-let items = ref([])
|
|
|
getDict('areaTreeData', null, 'areaTreeData').then(({ data }) => {
|
|
|
data = data?.length && data || []
|
|
|
- const chinaTreeData = data.filter(e => e.id === '1')
|
|
|
- if (!chinaTreeData.length) return
|
|
|
- items.value = chinaTreeData[0].children
|
|
|
+ const china = data.find(e => e.id === '1')
|
|
|
+ items.value = china?.children?.length ? china.children : []
|
|
|
})
|
|
|
|
|
|
-// 右侧列表信息
|
|
|
-const leftIndex = ref(null)
|
|
|
-const rightObj = reactive({ show: false, data: {} })
|
|
|
-
|
|
|
-const handleMouseOver = (val, index) => {
|
|
|
- leftIndex.value = index
|
|
|
- rightObj.data = val
|
|
|
- rightObj.show = true
|
|
|
-}
|
|
|
-const handleMouseLeave = () => {
|
|
|
- rightObj.show = false
|
|
|
- leftIndex.value = null
|
|
|
+// 设置选中ids
|
|
|
+const handleClick = (val) => {
|
|
|
+ const isExist = idChecked.value.includes(val.id)
|
|
|
+ if (!isExist) {
|
|
|
+ // 添加
|
|
|
+ if (props.limit === 1) {
|
|
|
+ currentSelect.value = [val]
|
|
|
+ idChecked.value = [val.id]
|
|
|
+ } else {
|
|
|
+ if (props.limit === idChecked.value.length) return Snackbar.warning(`最多可选${props.limit}个城市`)
|
|
|
+ currentSelect.value.push(val)
|
|
|
+ idChecked.value.push(val.id)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 删除
|
|
|
+ currentSelect.value = currentSelect.value.filter(e => e.id !== val.id)
|
|
|
+ idChecked.value = idChecked.value.filter(e => e !== val.id)
|
|
|
+ }
|
|
|
+ emits('handleClick', idChecked.value, currentSelect.value)
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.active {
|
|
|
- color: var(--v-primary-base) !important;
|
|
|
- font-weight: 700;
|
|
|
-}
|
|
|
-:deep(.v-window) {
|
|
|
- height: 392px !important;
|
|
|
+.currentSelect {
|
|
|
+ position: sticky;
|
|
|
+ background-color: var(--color-f2f4f7);
|
|
|
}
|
|
|
-.floatCard {
|
|
|
- .leftIndexAct { color: var(--v-primary-base); }
|
|
|
- .leftCard {
|
|
|
- height: 242px;
|
|
|
- width: 172px;
|
|
|
- margin: 4px 0;
|
|
|
- overflow-y: auto;
|
|
|
- .leftCardItem {
|
|
|
- height: 36px;
|
|
|
- line-height: 36px;
|
|
|
- padding: 0 16px;
|
|
|
+.card { border-radius: 12px; }
|
|
|
+.rightCard {
|
|
|
+ position: relative;
|
|
|
+ height: 384px;
|
|
|
+ width: 786px;
|
|
|
+ margin: 4px 0;
|
|
|
+ padding: 0 16px;
|
|
|
+ overflow-y: auto;
|
|
|
+ .categoryName2 { font-size: 14px; color: #000; width: 150px; margin-right: 4px;}
|
|
|
+ .jobItem { font-size: 14px; color: var(--color-333); }
|
|
|
+ .active { color: var(--v-primary-base); font-weight: 700; }
|
|
|
+ .rowItem {
|
|
|
+ padding: 8px 0;
|
|
|
+ }
|
|
|
+ .divider {
|
|
|
+ margin-left: 150px;
|
|
|
+ }
|
|
|
+ .rightContent {
|
|
|
+ flex: 1;
|
|
|
+ div {
|
|
|
+ margin: 4px 28px 2px 0;
|
|
|
+ float: left;
|
|
|
cursor: pointer;
|
|
|
&:hover {
|
|
|
color: var(--v-primary-base);
|
|
|
- background-color: var(--color-f8);
|
|
|
- }
|
|
|
- .categoryName { font-size: 14px; font-family: 微软雅黑; }
|
|
|
- }
|
|
|
- .rowItem { justify-content: space-between; }
|
|
|
- }
|
|
|
- .rightCardBox { margin-left: 4px; }
|
|
|
- .rightCard {
|
|
|
- height: 242px;
|
|
|
- width: 525px;
|
|
|
- margin: 4px 0;
|
|
|
- padding: 0 16px;
|
|
|
- overflow-y: auto;
|
|
|
- .categoryName { font-size: 16px; line-height: 28px; margin-top: 6px;}
|
|
|
- .categoryName2 { font-size: 14px; color: var(--color-666); width: 110px; margin-right: 4px;}
|
|
|
- .jobItem { font-size: 14px; color: var(--color-333); }
|
|
|
- .rowItem {
|
|
|
- padding: 8px 0;
|
|
|
- }
|
|
|
- .divider {
|
|
|
- margin-left: 110px;
|
|
|
- }
|
|
|
- .rightContent {
|
|
|
- flex: 1;
|
|
|
- div {
|
|
|
- margin: 4px 28px 2px 0;
|
|
|
- float: left;
|
|
|
- cursor: pointer;
|
|
|
- color: var(--color-333);
|
|
|
- &:hover {
|
|
|
- color: var(--v-primary-base);
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-.hasPageCard {
|
|
|
- width: 100%;
|
|
|
- .card { border-radius: 12px; }
|
|
|
- .leftIndexAct {
|
|
|
- height: 48px;
|
|
|
- margin: 0 4px;
|
|
|
- border-radius: 12px;
|
|
|
- // background-color: var(--v-primary-base);
|
|
|
- }
|
|
|
- justify-content: center; // 后面的flex会继承
|
|
|
- .leftCard {
|
|
|
- height: 384px;
|
|
|
- width: 380px;
|
|
|
- margin: 4px 0;
|
|
|
- overflow-x: hidden;
|
|
|
- overflow-y: auto;
|
|
|
- .leftCardItem {
|
|
|
- height: 42px;
|
|
|
- line-height: 42px;
|
|
|
- padding: 0 16px;
|
|
|
- .title { font-size: 14px; }
|
|
|
- .mdi-menu-right { font-size: 20px; }
|
|
|
- }
|
|
|
- .jobItemsBox {
|
|
|
- flex: 1;
|
|
|
- padding:0 8px;
|
|
|
- .outerCovering {
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap; /* 允许换行 */
|
|
|
- width: 100%; /* 设置容器宽度 */
|
|
|
- height: 42px;
|
|
|
- overflow: hidden;
|
|
|
- // border: 1px solid red; /* 可视化边界 */
|
|
|
- .jobItems {
|
|
|
- font-size: 14px;
|
|
|
- margin-left: 12px;
|
|
|
- cursor: pointer;
|
|
|
- color: var(--color-666);
|
|
|
- font-family: 微软雅黑;
|
|
|
- &:hover {
|
|
|
- color: var(--v-primary-base);
|
|
|
- // background-color: var(--color-f8);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- .rightCardBox { flex: 1; margin-left: 12px;}
|
|
|
- .rightCard {
|
|
|
- height: 384px;
|
|
|
- // min-width: 786px;
|
|
|
- margin: 4px 0;
|
|
|
- padding: 0 16px;
|
|
|
- overflow-y: auto;
|
|
|
- .categoryName { font-size: 16px; line-height: 28px; margin-top: 6px; color: var(--v-primary-base)}
|
|
|
- .categoryName2 { font-size: 14px; color: var(--color-666); width: 110px; margin-right: 4px;}
|
|
|
- .jobItem { font-size: 14px; color: var(--color-333); }
|
|
|
- .rowItem {
|
|
|
- padding: 8px 0;
|
|
|
- }
|
|
|
- .divider {
|
|
|
- margin-left: 110px;
|
|
|
- }
|
|
|
- .rightContent {
|
|
|
- flex: 1;
|
|
|
- div {
|
|
|
- margin: 4px 28px 2px 0;
|
|
|
- float: left;
|
|
|
- cursor: pointer;
|
|
|
- color: var(--color-333);
|
|
|
- &:hover {
|
|
|
- color: var(--v-primary-base);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
+::-webkit-scrollbar {
|
|
|
+ width: 4px;
|
|
|
+ height: 10px;
|
|
|
}
|
|
|
-// ::v-deep {
|
|
|
- ::-webkit-scrollbar {
|
|
|
- width: 4px;
|
|
|
- height: 10px;
|
|
|
- // display: none;
|
|
|
- }
|
|
|
- ::-webkit-scrollbar-thumb, .temporaryAdd ::-webkit-scrollbar-thumb, .details_edit ::-webkit-scrollbar-thumb {
|
|
|
- // 滚动条-颜色
|
|
|
- background: #c3c3c379;
|
|
|
- }
|
|
|
- ::-webkit-scrollbar-track, .temporaryAdd ::-webkit-scrollbar-track, .details_edit ::-webkit-scrollbar-track {
|
|
|
- // 滚动条-底色
|
|
|
- background: #e5e5e58f;
|
|
|
- }
|
|
|
-// }
|
|
|
-</style>
|
|
|
+::-webkit-scrollbar-thumb, .temporaryAdd ::-webkit-scrollbar-thumb, .details_edit ::-webkit-scrollbar-thumb {
|
|
|
+ // 滚动条-颜色
|
|
|
+ background: #c3c3c379;
|
|
|
+}
|
|
|
+::-webkit-scrollbar-track, .temporaryAdd ::-webkit-scrollbar-track, .details_edit ::-webkit-scrollbar-track {
|
|
|
+ // 滚动条-底色
|
|
|
+ background: #e5e5e58f;
|
|
|
+}
|
|
|
+</style>
|