|
@@ -1,15 +1,294 @@
|
|
|
<template>
|
|
|
- <div>
|
|
|
- <h1>这是智搜列表页</h1>
|
|
|
+ <div class="list">
|
|
|
+ <div class="list-head">
|
|
|
+ <div class="list-head-search">
|
|
|
+ <div class="left-select __hover" @click.stop="ref_area.togglePopperVisible(true)">
|
|
|
+ 搜索范围<SvgIcon name="arrow_1" rotate="90" size="14" color="var(--cus-text-color-3)"/>
|
|
|
+ <el-cascader ref="ref_area" class="area-cascader" v-model="state.cascaderParams.value" :props="state.cascaderParams.props" :options="state.cascaderParams.options"/>
|
|
|
+ </div>
|
|
|
+ <el-input v-model="state.searchText" placeholder="请输入关键字进行查询" @keyup.enter="onSearch"/>
|
|
|
+ <div class="right-icon __hover" @click="onSearch">
|
|
|
+ <SvgIcon name="search_1" color="var(--cus-main-color)" size="40"/>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="list-head-user">
|
|
|
+ <div class="avatar">
|
|
|
+ <img src="@/assets/images/web/web-list_avatar.png"/>
|
|
|
+ </div>
|
|
|
+ 用户名
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="list-content">
|
|
|
+ <div class="list-filter">
|
|
|
+ <div class="label">检索条件:</div>
|
|
|
+ <div class="value">
|
|
|
+ <template v-if="isSelectAllCpt || !state.cascaderParams.value.length">
|
|
|
+ <div class="filter-item">全部</div>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <template v-for="(item, index) in state.cascaderParams.value">
|
|
|
+ <div class="filter-item">
|
|
|
+ {{ WebStore.searchAreaIndexMap.get(item) }}
|
|
|
+ <SvgIcon class="__hover" name="close_1" size="10" color="var(--cus-text-color-3)" @click="onDelFilter(index)"/>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="list-tab">
|
|
|
+ <template v-for="item in state.resultParams.tree">
|
|
|
+ <div class="list-tab-item __hover" :class="{active: item.treeId === state.resultParams.activeTab}">{{item.treeName}}<span class="total">(898989898989)</span></div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <div class="list-result">
|
|
|
+ <div class="list-result-tree"></div>
|
|
|
+ <div class="list-result-table"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import {getCurrentInstance, reactive} from "vue";
|
|
|
+import {computed, getCurrentInstance, onMounted, reactive, ref} from "vue";
|
|
|
+import {useRoute, useRouter} from "vue-router";
|
|
|
+import {useWebStore} from "@/stores";
|
|
|
|
|
|
const {proxy} = getCurrentInstance()
|
|
|
-const state: any = reactive({})
|
|
|
+const WebStore = useWebStore()
|
|
|
+const route = useRoute()
|
|
|
+const router = useRouter()
|
|
|
+const state: any = reactive({
|
|
|
+ searchText: '',
|
|
|
+ cascaderParams: {
|
|
|
+ value: [],
|
|
|
+ props: {
|
|
|
+ label: 'treeName',
|
|
|
+ value: 'treeId',
|
|
|
+ multiple: true,
|
|
|
+ emitPath: false
|
|
|
+ },
|
|
|
+ show: false,
|
|
|
+ options: []
|
|
|
+ },
|
|
|
+ searchParams: {
|
|
|
+ text: '',
|
|
|
+ indexKey: []
|
|
|
+ },
|
|
|
+ resultParams: {
|
|
|
+ tree: [],
|
|
|
+ activeTab: '',
|
|
|
+ activeIndex: '',
|
|
|
+ }
|
|
|
+})
|
|
|
+const ref_area = ref()
|
|
|
+const isSelectAllCpt = computed(() => {
|
|
|
+ return WebStore.searchAreaIndexTotal === state.cascaderParams.value.length
|
|
|
+})
|
|
|
+const initArea = () => {
|
|
|
+ WebStore.getSearchAreaTree().then(res => {
|
|
|
+ state.cascaderParams.options = res
|
|
|
+ onSearch()
|
|
|
+ })
|
|
|
+}
|
|
|
+const onDelFilter = (index) => {
|
|
|
+ const temp = JSON.parse(JSON.stringify(state.cascaderParams.value))
|
|
|
+ temp.splice(index, 1)
|
|
|
+ state.cascaderParams.value = temp
|
|
|
+}
|
|
|
+const onSearch = () => {
|
|
|
+ state.searchParams = JSON.parse(JSON.stringify({
|
|
|
+ text: state.searchText,
|
|
|
+ indexKey: state.cascaderParams.value
|
|
|
+ }))
|
|
|
+ initResultTree()
|
|
|
+}
|
|
|
+const initResultTree = () => {
|
|
|
+ const arr = []
|
|
|
+ WebStore.searchAreaTree.forEach(v => {
|
|
|
+ const t = {
|
|
|
+ ...v,
|
|
|
+ children: []
|
|
|
+ }
|
|
|
+ v.children?.forEach(c => {
|
|
|
+ if (state.searchParams.indexKey.includes(c.treeId)) {
|
|
|
+ t.children.push(c)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (t.children.length > 0) {
|
|
|
+ arr.push(t)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (arr.length > 0) {
|
|
|
+ state.resultParams.tree = arr
|
|
|
+ } else {
|
|
|
+ state.resultParams.tree = JSON.parse(JSON.stringify(WebStore.searchAreaTree))
|
|
|
+ }
|
|
|
+ state.resultParams.activeTab = state.resultParams.tree[0].treeId
|
|
|
+ state.resultParams.activeIndex = state.resultParams.tree[0].children[0].treeId
|
|
|
+}
|
|
|
+onMounted(() => {
|
|
|
+ initArea()
|
|
|
+ const {text, index} = route.query
|
|
|
+ if (!text) {
|
|
|
+ router.replace({
|
|
|
+ name: '71305311-abcc-4d13-8531-f966b49839c5'
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ state.searchText = text
|
|
|
+ if (index) {
|
|
|
+ state.cascaderParams.value = index.split(',')
|
|
|
+ }
|
|
|
+ }
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+.list {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background-color: #F6F7FB;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ .list-head {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ width: 100%;
|
|
|
+ height: 72px;
|
|
|
+ background-color: #FFFFFF;
|
|
|
+ .list-head-search {
|
|
|
+ margin-left: auto;
|
|
|
+ width: 800px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ height: 48px;
|
|
|
+ background: rgba(255,255,255,0.9);
|
|
|
+ box-shadow: 0px 0px 2px 0px rgba(167,220,255,0.5);
|
|
|
+ border-radius: 60px;
|
|
|
+ border: 1px solid var(--cus-text-color-4);
|
|
|
+ .left-select {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 184px;
|
|
|
+ gap: 17px;
|
|
|
+ color: var(--cus-text-color-4);
|
|
|
+ font-size: 18px;
|
|
|
+ position: relative;
|
|
|
+ &:after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ height: 40px;
|
|
|
+ width: 1px;
|
|
|
+ background-color: var(--cus-text-color-4);
|
|
|
+ }
|
|
|
+ :deep(.area-cascader) {
|
|
|
+ position: absolute;
|
|
|
+ z-index: -1;
|
|
|
+ opacity: 0;
|
|
|
+ height: 50px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ :deep(.el-input) {
|
|
|
+ font-size: 18px;
|
|
|
+ color: var(--cus-text-color-2);
|
|
|
+ .el-input__wrapper {
|
|
|
+ box-shadow: none;
|
|
|
+ background-color: transparent;
|
|
|
+ .el-input__inner {
|
|
|
+ &::placeholder {
|
|
|
+ color: var(--cus-text-color-4);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .right-icon {
|
|
|
+ margin-right: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .list-head-user {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ color: var(--cus-main-color);
|
|
|
+ margin: 0 24px;
|
|
|
+ .avatar {
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .list-content {
|
|
|
+ flex: 1;
|
|
|
+ padding: 24px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ $filterLineHeight: 26px;
|
|
|
+ .list-filter {
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 14px;
|
|
|
+ color: var(--cus-text-color-2);
|
|
|
+ display: flex;
|
|
|
+ .label {
|
|
|
+ margin-right: 20px;
|
|
|
+ line-height: $filterLineHeight;
|
|
|
+ }
|
|
|
+ .value {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 10px 10px;
|
|
|
+ .filter-item {
|
|
|
+ height: $filterLineHeight;
|
|
|
+ padding: 0 16px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 45px;
|
|
|
+ font-size: 12px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ .svg-icon {
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .list-tab {
|
|
|
+ height: 45px;
|
|
|
+ margin-top: 19px;
|
|
|
+ display: flex;
|
|
|
+ .list-tab-item {
|
|
|
+ height: 100%;
|
|
|
+ padding: 0 16px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ color: var(--cus-text-color-2);
|
|
|
+ border-radius: 8px 8px 0 0;
|
|
|
+ .total {
|
|
|
+ font-size: 12px;
|
|
|
+ margin-left: 4px;
|
|
|
+ color: var(--cus-text-color-2);
|
|
|
+ font-weight: 400;
|
|
|
+ }
|
|
|
+ &.active {
|
|
|
+ background-color: #ffffff;
|
|
|
+ box-shadow: 0px -4px 10px 0px rgba(62,123,250,0.1);
|
|
|
+ color: var(--cus-main-color);
|
|
|
+ font-weight: 500;
|
|
|
+ position: relative;
|
|
|
+ &:after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ width: calc(100% - 16px * 2);
|
|
|
+ height: 3px;
|
|
|
+ background-color: var(--cus-main-color);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .list-result {
|
|
|
+ flex: 1;
|
|
|
+ background-color: #ffffff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|