Browse Source

关键词库修改上提审

yuwenjun1997 2 years ago
parent
commit
5aef0a7059

+ 273 - 0
pages/search/components/product-full-list.vue

@@ -0,0 +1,273 @@
+<template>
+    <view class="product-wrapper">
+        <!-- 文章搜索筛选 -->
+        <view class="search-sort">
+            <template v-for="item in sortItems">
+                <view
+                    class="sort-item"
+                    :key="item.id"
+                    :class="{ active: item.id === currentSortItem }"
+                    @click="onSortItemClick(item)"
+                >
+                    <text v-text="item.name"></text>
+                    <text :class="[item.icon, item.sortType]"></text>
+                </view>
+            </template>
+        </view>
+        <!-- 文章搜索列表 -->
+        <view class="product-list">
+            <view class="product" v-for="product in list" :key="product.productId" @click="onToDetail(product)">
+                <view class="cover"><image :src="product.image"></image></view>
+                <view class="content">
+                    <view class="title" v-text="product.name"></view>
+                    <view class="unit">
+                        <text class="label">规格:</text>
+                        <text class="value" v-text="product.unit"></text>
+                    </view>
+                    <view class="code">
+                        <text class="label">商品编码:</text>
+                        <text class="value" v-text="product.code"></text>
+                    </view>
+                    <view class="foot">
+                        <view class="price">
+                            <view class="real-price">¥{{ makePrice(product) }}</view>
+                            <!-- <view class="old-price">¥480.00</view> -->
+                        </view>
+                        <view class="tag-list">
+                            <view class="tag coupon" v-if="product.couponsLogo">优惠券</view>
+                            <view class="tag svip" v-if="product.svipProductFlag == 1">svip</view>
+                            <template v-if="product.actStatus == 1">
+                                <template v-if="isPromotion(product.promotions)">
+                                    <view class="tag other">
+                                        {{ product.promotions.name }}
+                                        <text>:¥{{ product.price | priceFormat }}</text>
+                                    </view>
+                                </template>
+                                <template v-else>
+                                    <view class="tag other">{{ product.promotions.name }}</view>
+                                </template>
+                            </template>
+                            <!-- <view class="tag reduce">活动价</view> -->
+                        </view>
+                    </view>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+import { debounce } from '@/common/config/common'
+const myDebounce = fn => debounce(fn, 200, false)
+
+export default {
+    filters: {
+        priceFormat(price) {
+            if (!price) return ''
+            return Number(text).toFixed(2)
+        }
+    },
+    props: {
+        list: {
+            type: Array,
+            default: () => []
+        }
+    },
+    data() {
+        const sortItems = [
+            { id: 1, name: '综合', icon: '', sortType: '' },
+            { id: 2, name: '销量', icon: 'sort', sortType: 'asc' }, // asc 升序  desc 降序
+            { id: 3, name: '人气', icon: 'sort', sortType: 'asc' }, // asc 升序  desc 降序
+            { id: 4, name: '价格', icon: 'sort', sortType: 'asc' }, // asc 升序  desc 降序
+            { id: 5, name: '筛选', icon: 'iconfont icon-shaixuan', sortType: '' }
+        ]
+        return {
+            sortItems: sortItems,
+            currentSortItem: 1
+        }
+    },
+    methods: {
+        // 跳转产品详情
+        onToDetail: myDebounce(function(product) {
+            this.$api.navigateTo(`/pages/goods/product?id=${product.productId}`)
+        }),
+
+        // 是否有促销价
+        isPromotion(promo) {
+            if (!promo) return false
+            return promo.type == 1 && promo.mode == 1
+        },
+
+        // 返回产品价格
+        makePrice(product) {
+            const price = this.isPromotion(product.promotions) ? product.originalPrice : product.price
+            return Number(price).toFixed(2)
+        },
+
+        // sort item click
+        onSortItemClick(item) {
+            if (item.id === 5) {
+                console.log('filter')
+            } else if (item.id === this.currentSortItem) {
+                item.sortType = item.sortType === 'asc' ? 'desc' : 'asc'
+            } else {
+                const lastCurrent = this.sortItems.find(a => a.id === this.currentSortItem)
+                this.currentSortItem = item.id
+                lastCurrent.sortType = 'asc'
+            }
+            this.$emit('change', item)
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+/* scss中可以用mixin来扩展 */
+@mixin ellipsis($line: 1) {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-line-clamp: $line;
+    -webkit-box-orient: vertical;
+}
+
+.product-wrapper {
+    .search-sort {
+        background: #fff;
+        display: flex;
+        justify-content: space-evenly;
+        align-items: center;
+        line-height: 90rpx;
+        .sort-item {
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            flex: 1;
+            font-size: 26rpx;
+            color: #999999;
+
+            text:first-child {
+                margin-right: 4rpx;
+            }
+
+            &.active,
+            &.active .sort.desc::after,
+            &.active .sort.asc::before,
+            &.active .icon-shaixuan {
+                color: #e15616;
+            }
+
+            .icon-shaixuan {
+                font-size: 24rpx;
+                color: #999999;
+            }
+
+            .sort {
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                line-height: 0.9;
+                font-size: 14rpx;
+                color: #aaa;
+                transform: scale(0.7);
+                &::after {
+                    content: '▼';
+                }
+                &::before {
+                    content: '▲';
+                }
+            }
+        }
+    }
+
+    .product {
+        display: flex;
+        padding: 32rpx;
+        border-top: 1rpx solid #e1e1e1;
+        .cover {
+            flex-shrink: 0;
+            width: 220rpx;
+            height: 220rpx;
+            image {
+                display: block;
+                width: 100%;
+                height: 100%;
+            }
+        }
+        .content {
+            flex: 1;
+            margin-left: 24rpx;
+            .title {
+                font-size: 26rpx;
+                color: #333333;
+                line-height: 36rpx;
+                height: 72rpx;
+                @include ellipsis(2);
+            }
+            .unit,
+            .code {
+                font-size: 20rpx;
+                color: #666666;
+                margin-top: 8rpx;
+                height: 28rpx;
+                @include ellipsis(1);
+
+                .value {
+                    color: #999;
+                }
+            }
+
+            .foot {
+                margin-top: 34rpx;
+                display: flex;
+                justify-content: space-between;
+                align-items: flex-end;
+                .price {
+                    display: flex;
+                    align-items: flex-end;
+                    .real-price {
+                        color: #e15616;
+                        font-size: 24rpx;
+                    }
+                    .old-price {
+                        text-decoration: line-through;
+                        font-size: 20rpx;
+                        color: #999;
+                        margin-left: 8rpx;
+                    }
+                }
+                .tag-list {
+                    display: flex;
+                    .tag {
+                        height: 32rpx;
+                        font-size: 22rpx;
+                        flex-shrink: 0;
+                        box-sizing: border-box;
+                        padding: 0 8rpx;
+                        margin-right: 8rpx;
+                        border-radius: 6rpx;
+
+                        &:last-child {
+                            margin-right: 0;
+                        }
+
+                        &.coupon,
+                        &.reduce,
+                        &.other {
+                            border: 1rpx solid rgba(225, 86, 22, 0.2);
+                            line-height: 30rpx;
+                            color: #e15616;
+                        }
+                        &.svip {
+                            line-height: 32rpx;
+                            color: #f0cb72;
+                            background: #333333;
+                            text-transform: uppercase;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+</style>

+ 1 - 0
pages/search/components/search-header.vue

@@ -15,6 +15,7 @@
                     @confirm="$emit('search', value)"
                     @input="event => $emit('input', event.detail.value)"
                     @blur="$emit('blur')"
+                    @focus="$emit('focus')"
                 />
                 <text class="iconfont icon-shanchu1" v-show="showClearBtn" @click="$emit('clear')"></text>
             </view>

+ 20 - 4
pages/search/search-library.vue

@@ -122,6 +122,7 @@ export default {
             showLibaray: false,
             libraryWordList: [],
             isLoading: true,
+            searchType: 'library',
             // 用户信息
             userInfo: {
                 userId: 0,
@@ -147,7 +148,9 @@ export default {
                 actiType: 1,
                 brandIds: '', // 品牌Id
                 newFlag: 0, // 查询新品标记,默认0,新品1
-                promotionFlag: 0 // 查询促销标记,默认0,促销1
+                promotionFlag: 0, // 查询促销标记,默认0,促销1
+                productFlag: 1, // 是否统计关键词 1 统计 0 不统计
+                linkageFlag: 1 // 关键词来源是否为用户搜索 0 是 1 不是
             },
             brandListQuery: {
                 keyword: '',
@@ -163,7 +166,9 @@ export default {
                 keyword: '', //查询关键词
                 productType: 0, //商品类型 0 全部 1 仪器 2 产品
                 pageNum: 1,
-                pageSize: 10
+                pageSize: 10,
+                productFlag: 1, // 是否统计关键词 1 统计 0 不统计
+                linkageFlag: 1 // 关键词来源是否为用户搜索 0 是 1 不是
             },
             // 采美文章
             articleList: [],
@@ -173,7 +178,9 @@ export default {
                 keyword: '',
                 pageSize: 10,
                 pageNum: 1,
-                status: 1
+                status: 1,
+                productFlag: 1, // 是否统计关键词 1 统计 0 不统计
+                linkageFlag: 1 // 关键词来源是否为用户搜索 0 是 1 不是
             },
             // 采美百科
             encyclopediaList: [],
@@ -182,7 +189,9 @@ export default {
             encyclopediaListQuery: {
                 keyword: '',
                 pageSize: 10,
-                pageNum: 1
+                pageNum: 1,
+                productFlag: 1, // 是否统计关键词 1 统计 0 不统计
+                linkageFlag: 1 // 关键词来源是否为用户搜索 0 是 1 不是
             }
         }
     },
@@ -258,6 +267,7 @@ export default {
             this.encyclopediaList = []
             this.encyclopediaListQuery.keyword = this.keyword
             this.encyclopediaListQuery.pageNum = 1
+            this.encyclopediaListQuery.linkageFlag = this.searchType === 'library' ? 1 : 0
             this.fetchEncyclopediaList()
         },
 
@@ -282,6 +292,7 @@ export default {
             this.articleList = []
             this.articleListQuery.keyword = this.keyword
             this.articleListQuery.pageNum = 1
+            this.articleListQuery.linkageFlag = this.searchType === 'library' ? 1 : 0
             this.fetchArticleList()
         },
 
@@ -310,6 +321,7 @@ export default {
             this.articleListQuery.keyword = this.keyword
             this.articleListQuery.pageNum = 1
             this.articleListQuery.status = filterData.status
+            this.articleListQuery.linkageFlag = this.searchType === 'library' ? 1 : 0
             this.fetchArticleList()
         },
 
@@ -346,6 +358,7 @@ export default {
             this.productListQuery.identity = this.userInfo.userIdentity
             this.productListQuery.sortType = 1
             this.productListQuery.sortField = ''
+            this.productListQuery.linkageFlag = this.searchType === 'library' ? 1 : 0
             this.fetchProductList()
             this.fetchBrandList()
         },
@@ -473,6 +486,7 @@ export default {
         // 关键词点击
         onLibraryClick(item) {
             this.keyword = item.keyword
+            this.searchType = 'library'
             this.initList()
         },
 
@@ -484,12 +498,14 @@ export default {
         // tab 切换
         onTabChange(current) {
             this.currentTab = current.index
+            this.searchType = 'search'
             this.initList()
         },
 
         // 搜索
         onSearch: myDebounce(function() {
             if (this.currentMenu === 0) {
+                this.searchType = 'keyword'
                 return this.initList()
             }
             this.$api.navigateTo(`/pages/search/search-supplier?keyWord=${this.keyword}`)

+ 6 - 1
pages/search/search.vue

@@ -558,7 +558,9 @@ export default {
                 actiType: 1,
                 brandIds: '', // 品牌Id
                 newFlag: 0, // 查询新品标记,默认0,新品1
-                promotionFlag: 0 // 查询促销标记,默认0,促销1
+                promotionFlag: 0, // 查询促销标记,默认0,促销1
+                productFlag: 1, // 是否统计关键词 1 统计 0 不统计
+                linkageFlag: 0 // 关键词来源是否为用户搜索 0 是 1 不是
             },
             brandParam: {
                 keyword: '',
@@ -686,6 +688,9 @@ export default {
         },
         subMitSearch() {
             this.showLibaray = false
+            this.listQuery.productFlag = 1
+            this.listQuery.linkageFlag = 0
+            
             //搜索
             if (this.listQuery.keyword == '') {
                 this.$util.msg('请输入搜索关键词', 2000)

+ 404 - 0
pages/search/search_new.vue

@@ -0,0 +1,404 @@
+<template>
+    <view class="cm-search-container">
+        <!-- 搜索框 -->
+        <SearchHeader
+            :menuList="menuItemList"
+            :currentMenu="currentMenu"
+            v-model="keyword"
+            @clear="onClear"
+            @search="onSearch"
+            @input="onInput"
+            @menuClick="onMenuItemClick"
+        />
+        <!-- 搜索历史记录 -->
+        <view class="display-wrapper" v-show="showDisplay">
+            <!-- 搜索历史 -->
+            <view class="history" v-if="showHistory">
+                <text class="iconfont icon-shanchu" @click="onClearHistory"></text>
+                <view class="label">搜索历史</view>
+                <view class="content">
+                    <template v-for="(item, index) in historyList">
+                        <view class="word" v-text="item.searchWord" :key="index"></view>
+                    </template>
+                </view>
+            </view>
+            <!-- 热门搜索 -->
+            <view class="hot" v-if="showHotPorduct || showHotInstrument">
+                <view class="label">热门搜索</view>
+                <view class="content">
+                    <!-- 产品 -->
+                    <template v-if="showHotPorduct">
+                        <view class="type-name">产品</view>
+                        <view class="type-content">
+                            <template v-for="(item, index) in hotProducts">
+                                <view class="word" :class="{ light: item.isHot === '1' }" :key="index">
+                                    <text v-text="item.name"></text>
+                                    <text class="iconfont icon-resou"></text>
+                                </view>
+                            </template>
+                        </view>
+                    </template>
+                    <!-- 仪器 -->
+                    <template v-if="showHotInstrument">
+                        <view class="type-name">仪器</view>
+                        <view class="type-content">
+                            <template v-for="(item, index) in hotInstruments">
+                                <view class="word" :class="{ light: item.isHot === '1' }" :key="index">
+                                    <text v-text="item.name"></text>
+                                    <text class="iconfont icon-resou"></text>
+                                </view>
+                            </template>
+                        </view>
+                    </template>
+                </view>
+            </view>
+        </view>
+        <!-- 搜索列表 -->
+        <view class="list-wrapper" v-show="showProduct">
+            <ProductFullList :list="productList" @change="onProductFilterItemChange" />
+        </view>
+
+        <!-- 列表为空 -->
+        <view class="empty-box" v-if="!isLoading && isEmpty">
+            <image
+                class="empty-image"
+                src="https://img.caimei365.com/group1/M00/03/8D/Cmis215XHXWAHCoqAAELHadZ9Xg365.png"
+            ></image>
+            <text class="empty-text">抱歉,没有相关商品!</text>
+        </view>
+
+        <!-- 加载 loading -->
+        <template v-if="!isEmpty">
+            <tui-loadmore :index="2" :visible="isLoading"></tui-loadmore>
+            <tui-nomore
+                :text="hasMore ? '上拉加载更多' : '没有更多了'"
+                :visible="!isLoading"
+                backgroundColor="#f5f5f5"
+            ></tui-nomore>
+        </template>
+
+        <!-- 商品筛选框 -->
+        <tui-drawer mode="right" :visible="showDrawer" @close="showDrawer = false">
+            <product-filter :brandList="brandList" @confirm="onDrawerConfirm" @reset="onDrawerConfirm"></product-filter>
+        </tui-drawer>
+    </view>
+</template>
+
+<script>
+import SearchHeader from './components/search-header.vue'
+import ProductFilter from './components/product-filter.vue'
+import ProductFullList from './components/product-full-list.vue'
+import { debounce } from '@/common/config/common'
+import { mapGetters } from 'vuex'
+const myDebounce = fn => debounce(fn, 200, false)
+
+export default {
+    components: {
+        SearchHeader,
+        ProductFilter,
+        ProductFullList
+    },
+    data() {
+        const menuItemList = [{ id: 1, name: '产品' }, { id: 2, name: '供应商' }]
+        return {
+            isLoading: false,
+            // 用户信息
+            userInfo: {
+                userId: 0,
+                userIdentity: 1,
+                vipFlag: 0,
+                firstClubType: 0
+            },
+            menuItemList: menuItemList,
+            currentMenu: 0,
+            keyword: '',
+            // 产品相关
+            showProduct: false,
+            showDrawer: false,
+            currentSortItem: {},
+            brandList: [],
+            productList: [],
+            total: 0,
+            hasMore: true,
+            listQuery: {
+                identity: 1,
+                keyword: '',
+                pageNum: 1,
+                pageSize: 10,
+                sortField: '',
+                sortType: 1,
+                newType: 1,
+                actiType: 1,
+                brandIds: '', // 品牌Id
+                newFlag: 0, // 查询新品标记,默认0,新品1
+                promotionFlag: 0 // 查询促销标记,默认0,促销1
+            },
+            // 历史记录相关
+            showDisplay: true,
+            historyList: [], // 热搜词
+            hotProducts: [], // 热搜产品
+            hotInstruments: [] // 热搜仪器
+        }
+    },
+    computed: {
+        showHistory() {
+            return this.historyList.length > 0
+        },
+        showHotPorduct() {
+            return this.hotProducts.length > 0
+        },
+        showHotInstrument() {
+            return this.hotInstruments.length > 0
+        },
+        isEmpty() {
+            return this.productList.length === 0
+        }
+    },
+
+    onLoad() {
+        this.initStorage()
+    },
+    onReachBottom() {},
+
+    methods: {
+        initDisplay() {
+            this.fetchhistoryList()
+            this.fetchHotItemList()
+        },
+
+        //查询搜索历史记录
+        async fetchhistoryList() {
+            try {
+                const res = await this.ProductService.GetProductSearchHistory({ userId: this.userInfo.userId })
+                this.historyList = res.data
+            } catch (e) {
+                this.$util.msg(e.msg, 2000)
+            }
+        },
+
+        // 清空搜索历史
+        onClearHistory() {
+            //清空历史记录
+            this.$util.modal('提示', '确定删除历史记录?', '确定', '取消', true, async () => {
+                try {
+                    await this.ProductService.GetDeleteProductSearchHistory({ userId: this.userInfo.userId })
+                    this.$util.msg('删除成功', 2000, true, 'success')
+                    this.historyList = []
+                } catch (e) {
+                    this.$util.msg(e.msg, 2000)
+                }
+            })
+        },
+
+        // 获取热搜
+        async fetchHotItemList() {
+            try {
+                const res = await this.CommonService.GetHomeHotSearchTerms({})
+                this.hotInstruments = res.data.instrumentHotSearch
+                this.hotProducts = res.data.productHotSearch
+            } catch (e) {
+                this.$util.msg(e.msg, 2000)
+            }
+        },
+
+        // 获取用户信息
+        async initStorage(option) {
+            const userInfo = await this.$api.getStorage()
+            if (!userInfo) return
+            this.userInfo = { ...this.userInfo, ...userInfo }
+            this.initDisplay()
+        },
+
+        // 初始化产品列表
+        initProductList() {
+            this.productList = []
+            this.listQuery.pageNum = 1
+            this.listQuery.keyword = this.keyword
+            this.listQuery.identity = this.userInfo.userIdentity
+            this.listQuery.sortType = 1
+            this.listQuery.sortField = ''
+            this.fetchProductList()
+            this.fetchBrandList()
+        },
+
+        // 获取产品列表
+        fetchProductList: myDebounce(async function() {
+            try {
+                this.isLoading = true
+                const { data } = await this.ProductService.GetProductSearchList(this.productListQuery)
+                if (!data) return
+                const result = JSON.parse(data)
+                this.productTotal = result.total
+                this.fetchProductPrice(result.items)
+                this.productListQuery.pageNum++
+            } catch (e) {
+                this.isLoading = false
+            }
+        }),
+
+        // 产品筛选
+        productFilter() {
+            this.isLoading = true
+            this.productList = []
+            this.productListQuery.pageNum = 1
+            const sortType = { asc: 0, desc: 1 }
+            const currentSortItem = this.currentSortItem
+            switch (currentSortItem.id) {
+                case 1:
+                    this.productListQuery.sortField = ''
+                    this.productListQuery.sortType = 1
+                    break
+                case 2:
+                    this.productListQuery.sortField = 'sales'
+                    this.productListQuery.sortType = sortType[currentSortItem.sortType]
+                    break
+                case 3:
+                    this.productListQuery.sortField = 'favorite'
+                    this.productListQuery.sortType = sortType[currentSortItem.sortType]
+                    break
+                case 4:
+                    this.productListQuery.sortField = 'price'
+                    this.productListQuery.sortType = sortType[currentSortItem.sortType]
+                    break
+            }
+            this.fetchProductList()
+        },
+
+        // 产品筛选切换
+        onProductFilterItemChange(item) {
+            if (item.id === 5) {
+                this.showDrawer = true
+                return
+            }
+            this.currentSortItem = item
+            this.productFilter()
+        },
+
+        // 获取品牌列表
+        async fetchBrandList() {
+            try {
+                this.brandListQuery.keyword = this.keyword
+                const { data } = await this.ProductService.getCommoditySearchQUeryBrand(this.brandListQuery)
+                if (!data) return
+                this.brandList = data.map(brand => {
+                    brand.checked = false
+                    return brand
+                })
+            } catch (e) {
+                console.log(e)
+            }
+        },
+
+        // drawer reset or confirm
+        onDrawerConfirm(e) {
+            this.showDrawer = false
+            this.productListQuery.brandIds = e.brandList.map(brand => brand.id).join(',')
+            this.productListQuery.promotionFlag = e.promotionFlag
+            this.productListQuery.newFlag = e.newFlag
+            this.productFilter()
+        },
+
+        // 搜索
+        onSearch() {},
+
+        // 清空搜索框
+        onClear() {
+            this.keyword = ''
+        },
+
+        // 用户输入
+        onInput() {
+            this.fetchLibraryWordList()
+        },
+
+        // menu-item 点击事件
+        onMenuItemClick(index) {
+            this.currentMenu = index
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.cm-search-container {
+    min-height: 100vh;
+    background: #f5f5f5;
+}
+
+.display-wrapper {
+    padding: 32rpx 24rpx;
+    background: #fff;
+    // max-height: calc(100vh - 86rpx);
+    box-sizing: border-box;
+
+    .label {
+        font-size: 30rpx;
+        font-weight: bold;
+    }
+
+    .history {
+        position: relative;
+        .icon-shanchu {
+            position: absolute;
+            right: 24rpx;
+            top: 0;
+            font-size: 36rpx;
+            color: #333333;
+        }
+
+        .content {
+            display: flex;
+            flex-wrap: wrap;
+        }
+    }
+
+    .hot {
+        margin-top: 64rpx;
+
+        .type-name {
+            font-size: 26rpx;
+            color: #333;
+            margin-top: 32rpx;
+        }
+        .type-content {
+            display: flex;
+            flex-wrap: wrap;
+        }
+    }
+
+    .history,
+    .hot {
+        .word {
+            display: flex;
+            max-width: 200rpx;
+            font-size: 24rpx;
+            color: #8a8a8a;
+            background: #f3f3f3;
+            line-height: 48rpx;
+            padding: 0 20rpx;
+            border-radius: 24rpx;
+            margin-right: 24rpx;
+            margin-top: 24rpx;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            overflow: hidden;
+
+            .icon-resou {
+                display: none;
+                font-size: 30rpx;
+                color: #e15616;
+                margin-left: 12rpx;
+            }
+
+            &.light {
+                background: #fef6f3;
+                color: #e15616;
+
+                .icon-resou {
+                    display: block;
+                }
+            }
+        }
+    }
+}
+</style>