|
@@ -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>
|