panhui 3 лет назад
Родитель
Сommit
cc77d919ef
2 измененных файлов с 681 добавлено и 0 удалено
  1. 10 0
      src/router/index.js
  2. 671 0
      src/views/search/SearchDetail.vue

+ 10 - 0
src/router/index.js

@@ -987,6 +987,16 @@ const routes = [
             tabColor: '#000000',
             pageType: Page.Every
         }
+    },
+    {
+        path: '/searchDetail',
+        name: 'searchDetail',
+        component: () => import('../views/search/SearchDetail.vue'),
+        meta: {
+            title: '绿洲宇宙全域搜索',
+            pageType: Page.Every,
+            tabColor: '#000000'
+        }
     }
 ];
 

+ 671 - 0
src/views/search/SearchDetail.vue

@@ -0,0 +1,671 @@
+<template>
+    <div
+        class="search"
+        success-text="加载成功"
+        success-duration="500"
+        pageType="light"
+        :style="{ backgroundImage: `url(${require('@/assets/searchBg.jpg')})` }"
+    >
+        <van-sticky ref="top" class="list-top" :offset-top="bar && bar.show ? bar.height : 0">
+            <van-search
+                ref="top"
+                shape="round"
+                v-model="search"
+                placeholder="请输入"
+                show-action
+                autofocus
+                left-icon=""
+                @search="getSearch"
+            >
+                <template #action>
+                    <div v-if="!isSearch" @click="getSearch(search)">搜索</div>
+                    <div v-else @click="onCancel">取消</div>
+                </template>
+            </van-search>
+            <van-tabs
+                v-model:active="sort"
+                :ellipsis="false"
+                line-width="16"
+                line-height="2"
+                @click-tab="changeTab"
+                :class="{ trans: source == 'TRANSFER' }"
+            >
+                <van-tab
+                    :title="item.label"
+                    :name="item.value"
+                    :title-class="item.type === 'select' && sortDes ? sortDes : ''"
+                    :key="index"
+                    :lazy-render="false"
+                    v-for="(item, index) in selectOptions"
+                >
+                    <template v-if="item.type === 'select'" #title>
+                        <div class="tab">
+                            <span>{{ item.label }}</span>
+                            <van-icon size="8" name="arrow-up" />
+                            <van-icon size="8" name="arrow-down" />
+                        </div>
+                    </template>
+                </van-tab>
+            </van-tabs>
+            <!-- <van-checkbox
+                v-if="isSearch && source == 'TRANSFER' && !title"
+                @change="getData(true)"
+                class="sala"
+                v-model="salable"
+                >仅看在售</van-checkbox
+            > -->
+
+            <van-button
+                @click="changeSort"
+                v-if="isSearch && source == 'TRANSFER' && !title"
+                class="sala"
+                color="#F5F7FA"
+                type="primary"
+                size="small"
+                icon="arrow-down"
+                icon-position="right"
+                round
+                >{{ salable ? '在售中' : salable === false ? '仅展示' : '综合排序' }}</van-button
+            >
+        </van-sticky>
+
+        <van-action-sheet
+            v-model:show="showAction"
+            @select="selectAction"
+            :actions="actions"
+            cancel-text="取消"
+            close-on-click-action
+        />
+        <van-list
+            class="list"
+            v-model:loading="loading"
+            :immediate-check="false"
+            :finished="finished"
+            finished-text=""
+            @load="getData"
+            v-show="isSearch"
+        >
+            <template v-for="(item, index) in list" :key="index">
+                <product-info dark v-model:info="list[index]" @update:info="init"></product-info>
+            </template>
+            <van-empty v-if="empty" description="什么都没有搜到哦~" :image="require('@assets/kong_png_wusousuo.png')" />
+        </van-list>
+    </div>
+</template>
+
+<script>
+import ProductInfo from '../../components/product/productInfo.vue';
+import product from '../../mixins/product';
+import list from '../../mixins/list';
+import search from '../../mixins/search';
+export default {
+    name: 'productSearch',
+    components: { ProductInfo },
+    inject: ['bar', 'setKeeps', 'scrollWrapper', 'changeScroll'],
+    mixins: [product, list, search],
+    setup() {
+        let swiperRef = null;
+
+        const setSwiperRef = swiper => {
+            swiperRef = swiper;
+        };
+
+        return { swiperRef: null, setSwiperRef };
+    },
+    data() {
+        return {
+            list: [],
+            beforeSort: '',
+            empty: false,
+            search: '',
+            stiky: null,
+            type: '',
+            source: '',
+            minterId: '',
+            url: '/collection/all',
+            scrollTop: 0,
+            sort: 'id,desc',
+            sortDes: '',
+            title: '',
+            selectOptions: [
+                {
+                    label: '全部',
+                    value: 'id,desc'
+                },
+                {
+                    label: '最新',
+                    value: 'createdAt,desc'
+                },
+                {
+                    label: '最热',
+                    value: 'likes,desc'
+                },
+                {
+                    label: '价格',
+                    value: 'price',
+                    type: 'select'
+                }
+            ],
+            salable: '',
+            showAction: false,
+            showHall: false,
+            settings: [],
+            banners: []
+        };
+    },
+    watch: {
+        isSearch() {
+            this.changeScroll(0);
+        }
+    },
+    computed: {
+        actions() {
+            let list = [{ name: '综合排序' }, { name: '在售中' }, { name: '仅展示' }];
+            if (this.salable === '') {
+                list[0].color = this.$colors.prim;
+            }
+            if (this.salable === true) {
+                list[1].color = this.$colors.prim;
+            }
+            if (this.salable === false) {
+                list[2].color = this.$colors.prim;
+            }
+            return list;
+        },
+        tabs() {
+            let settings = [...this.settings];
+            let banners = [...this.banners];
+            return settings.map(item => {
+                return {
+                    ...item,
+                    children: banners.filter(banner => {
+                        return banner.settingId === item.id;
+                    })
+                };
+            });
+        }
+    },
+    mounted() {
+        this.$store.dispatch('getUsedBuy');
+        if (this.$route.query.type) {
+            this.type = this.$route.query.type;
+        }
+        if (this.$route.query.source) {
+            this.source = this.$route.query.source;
+            this.salable = true;
+            this.sort = 'createdAt,desc';
+        }
+        if (this.$route.query.minterId) {
+            this.minterId = this.$route.query.minterId;
+        }
+        if (this.$route.query.title) {
+            this.title = this.$route.query.title;
+        }
+        if (this.$route.query.search) {
+            this.search = this.$route.query.search;
+            this.getSearch(this.search);
+        }
+
+        this.$http
+            .get('/sysConfig/get/hall_show')
+            .then(res => {
+                if (res.value === true || res.value === '1') {
+                    this.showHall = true;
+                } else {
+                    return Promise.reject();
+                }
+            })
+            .catch(() => {
+                this.showHall = false;
+            });
+
+        this.$http
+            .post('/setting/byFlag', { flag: 1 })
+            .then(res => {
+                this.settings = res;
+                this.$http
+                    .post(
+                        '/banner/all',
+                        {
+                            query: {
+                                type: 'MARKET',
+                                del: false
+                            },
+                            size: 999,
+                            sort: 'sort,asc;createdAt,desc'
+                        },
+                        { body: 'json' }
+                    )
+                    .then(res => {
+                        this.banners = res.content;
+                        this.$nextTick(() => {
+                            if (this.swiperRef) {
+                                this.swiperRef.update();
+                            }
+                        });
+                    });
+            })
+            .catch(e => {
+                console.log(e);
+                this.$message.error(e.error);
+            });
+
+        this.emitter.on('updateList', info => {
+            let list = [...this.list];
+            list.forEach((item, index) => {
+                if (info.id === item.id) {
+                    list[index] = info;
+                }
+            });
+            this.list = list;
+        });
+    },
+    methods: {
+        onCancel() {
+            this.$router.back();
+        },
+        clear() {
+            this.$dialog
+                .confirm({
+                    message: '确定要清除全部搜索记录吗?'
+                })
+                .then(() => {
+                    this.clearHistory();
+                });
+        },
+        changeSort() {
+            this.showAction = true;
+        },
+        selectAction(action) {
+            if (action.name == '综合排序') {
+                this.salable = '';
+            }
+            if (action.name == '在售中') {
+                this.salable = true;
+            }
+            if (action.name == '仅展示') {
+                this.salable = false;
+            }
+            this.getData(true);
+        },
+        changeTab(info) {
+            this.$nextTick(() => {
+                if (info.name === 'price') {
+                    this.sortDes = this.sortDes == 'desc' ? 'asc' : 'desc';
+                }
+                this.getData(true);
+            });
+        },
+        beforeData() {
+            let sort = this.sort;
+            if (sort == 'price') {
+                sort = 'price,' + this.sortDes;
+            }
+            let type = this.type;
+            if (!type && !this.showHall) {
+                type = 'DEFAULT,BLIND_BOX';
+            }
+            return {
+                query: {
+                    onShelf: true,
+                    type: type,
+                    source: this.source,
+                    minterId: this.minterId,
+                    del: false,
+                    salable: this.salable
+                },
+                search: this.search,
+                sort: this.sort === 'id,desc' ? this.sortOptions[this.title] || sort : sort
+            };
+        },
+        onRefresh() {
+            if (this.isSearch) {
+                this.getData(true).then(() => {
+                    this.isLoading = false;
+                });
+            } else {
+                this.isLoading = false;
+                // this.$http.get('sysConfig/get/hot_search').then(res => {
+                //     this.hots = res.value.split(',').filter(item => {
+                //         return item !== ' ' && !!item;
+                //     });
+
+                //     this.isLoading = false;
+                // });
+                // this.getHistory();
+            }
+        },
+        isNew(info) {
+            let date1 = this.dayjs(info.createdAt).add(1, 'week');
+
+            return date1.isAfter(this.dayjs());
+        }
+    },
+    activated() {
+        this.$nextTick(() => {
+            this.changeScroll(this.scrollTop);
+
+            // setTimeout(() => {
+            //     this.sort = this.beforeSort;
+            // }, 1000);
+        });
+    },
+    beforeRouteLeave(to, from, next) {
+        if (to.name === 'productDetail') {
+            this.beforeSort = this.sort;
+            this.scrollTop = this.scrollWrapper.scrollTop;
+            this.setKeeps(['productSearch']);
+        } else {
+            this.beforeSort = '';
+            this.scrollTop = 0;
+            this.setKeeps(['productSearch'], false);
+        }
+        next();
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.search {
+    padding-bottom: 100px;
+    background-repeat: repeat-y;
+    background-size: 100% auto;
+}
+/deep/.van-search {
+    --van-search-background-color: transparent;
+    --van-search-content-background-color: linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.1) 100%);
+    --van-field-input-text-color: #00fe1e;
+    .van-field__control {
+        font-size: 16px;
+        font-family: AlimamaShuHeiTi;
+        line-height: 24px;
+    }
+
+    .van-search__content {
+        border: 1px solid #ffffff;
+    }
+
+    .van-field__left-icon {
+        display: flex;
+        align-items: center;
+    }
+    .van-icon {
+        display: flex;
+        align-items: center;
+    }
+    .van-search__action {
+        color: @text4;
+    }
+}
+
+.top {
+    background-color: @bg3;
+    padding: 0 16px;
+    height: 50px;
+    display: flex;
+    align-items: center;
+    .name {
+        font-size: 20px;
+        // font-weight: bold;
+        color: @prim;
+        line-height: 30px;
+    }
+}
+
+/deep/.trans {
+    .van-tab {
+        margin-right: 30px;
+    }
+}
+
+.list-top {
+    position: relative;
+}
+/deep/.van-tabs {
+    .van-tabs__nav {
+        padding-left: 16px;
+    }
+}
+.list {
+    padding: 8px 8px 100px;
+}
+// /deep/.van-tab {
+// flex-grow: 0;
+// padding: 0 0 0 0;
+// margin-right: 50px;
+
+.tab {
+    position: relative;
+    padding-right: 14px;
+    .van-icon {
+        position: absolute;
+        right: 0;
+
+        &.van-icon-arrow-down {
+            top: 8px;
+        }
+
+        &.van-icon-arrow-up {
+            bottom: 8px;
+        }
+    }
+}
+/deep/.van-tab--active {
+    .tab {
+        .van-icon-arrow-up {
+            color: #646566;
+        }
+    }
+    &.asc {
+        .tab {
+            .van-icon-arrow-up {
+                color: @prim;
+            }
+            .van-icon-arrow-down {
+                color: #646566;
+            }
+        }
+    }
+}
+.van-tabs {
+    background-color: @bg;
+}
+/deep/.van-tabs__nav--line.van-tabs__nav--complete {
+    border-color: @tabBorder;
+}
+
+/deep/.van-sticky--fixed {
+    background-color: #000;
+}
+
+.hot-content {
+    padding: 10px 0 6px 16px;
+
+    .title {
+        font-size: @font2;
+        color: #000000;
+        line-height: 24px;
+        font-weight: normal;
+        .flex();
+
+        img {
+            width: 18px;
+            height: 18px;
+            margin-left: 6px;
+        }
+    }
+
+    .hot-list {
+        span {
+            display: inline-block;
+            font-size: @font1;
+            color: @text4;
+            line-height: 22px;
+            padding: 0 12px;
+            margin: 6px 16px 0 0;
+            background: @bg;
+            border-radius: 12px;
+        }
+    }
+}
+
+/deep/.sala {
+    position: absolute;
+    right: 16px;
+    top: 60px;
+    color: @text3!important;
+    min-width: 92px;
+    font-size: 14px;
+    // .van-checkbox__icon {
+    //     color: #fff;
+    //     transform: scale(0.6);
+
+    //     .van-icon {
+    //         border-color: @text3;
+    //     }
+
+    //     &.van-checkbox__icon--checked {
+    //         .van-icon {
+    //             border-width: 0;
+    //             .linear();
+    //             &::before {
+    //                 color: #fff;
+    //             }
+    //         }
+    //     }
+    // }
+    // .van-checkbox__label {
+    //     color: @text3;
+    //     margin-left: 0px;
+    //     font-size: @font1;
+    // }
+}
+.mySwiper {
+    padding: 16px;
+}
+.tab-slide {
+    width: 240px;
+    background: #ffffff;
+    border-radius: 4px;
+    height: 457px;
+    overflow: auto;
+    position: relative;
+    .tab-top {
+        position: sticky;
+        top: 0;
+        z-index: 2;
+        img {
+            width: 240px;
+            height: 44px;
+        }
+        span {
+            position: absolute;
+            font-size: 14px;
+            font-weight: bold;
+            color: #3ab200;
+            line-height: 44px;
+            top: 0;
+            left: 12px;
+        }
+    }
+    .tab-item {
+        height: 37px;
+        .flex();
+        padding: 0 12px;
+        position: relative;
+        z-index: 1;
+        .text1 {
+            flex-grow: 1;
+            margin: 0 6px;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+        }
+
+        .num {
+            font-size: 12px;
+            color: #ffffff;
+            line-height: 14px;
+            background-color: #00000044;
+            width: 14px;
+            text-align: center;
+            flex-shrink: 0;
+        }
+
+        .new {
+            font-size: 10px;
+            color: #ff733c;
+            line-height: 14px;
+            width: 14px;
+            flex-shrink: 0;
+            background-color: #ff733c20;
+            text-align: center;
+        }
+        &:nth-child(1) {
+            .num {
+                background: linear-gradient(180deg, #f48753 0%, #e54f29 100%);
+            }
+        }
+        &:nth-child(2) {
+            .num {
+                background: linear-gradient(180deg, #ffa934 0%, #f16f25 100%);
+            }
+        }
+        &:nth-child(3) {
+            .num {
+                background: linear-gradient(180deg, #f8c246 0%, #ff9819 100%);
+            }
+        }
+
+        &::after {
+            content: '';
+            left: 12px;
+            right: 12px;
+            height: 1px;
+            background: #f4f5f7;
+            position: absolute;
+            bottom: 0;
+        }
+
+        &:last-child {
+            z-index: 3;
+            background-color: #fff;
+            &::after {
+                content: '';
+                height: 52px;
+                background: #fff;
+                position: absolute;
+                left: 0;
+                right: 0;
+                bottom: -52px;
+                z-index: 2;
+            }
+        }
+
+        &:nth-last-child(2) {
+            &::after {
+                content: none;
+            }
+        }
+    }
+
+    .more {
+        padding: 10px 0;
+        background-color: #fff;
+        .flex-col();
+        align-items: center;
+        img {
+            width: 16px;
+            height: 16px;
+        }
+        div {
+            font-size: 10px;
+            color: rgba(0, 0, 0, 0.2);
+            line-height: 10px;
+        }
+        position: sticky;
+        bottom: 0;
+        z-index: 2;
+    }
+}
+</style>