2025-04-13 23:40:58 +08:00

1523 lines
49 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<z-paging
ref="paging"
v-model="dataList"
:refresher-enabled="false"
:hide-no-more-inside="true"
:paging-style="{'top': '0','background': '#f2f3f7'}"
empty-view-text="没有找到对应商品看看别的吧"
empty-view-img="/static/empty-img/order-empty.png"
@query="onGetDataList"
>
<view class="Mall4j page-search-list">
<!-- 搜索框 -->
<view
class="search-top"
:class="{'search-frame-fixed':searchType===2}"
>
<view
class="search-box"
@tap="onToSearchPage(1)"
>
<view class="icon">
<image src="/static/images/search.png" />
</view>
<div
v-if="showKeyword"
class="key-tag"
>
<span class="text">{{ showKeyword }}</span>
<span
class="close"
@tap.stop="onToSearchPage(0)"
>x</span>
</div>
<div
v-if="!showKeyword"
class="text"
>
输入关键字搜索
</div>
</view>
<view
v-if="searchType!==2"
class="list-style"
@tap="onChangeListStyle"
>
<image :src="isLineProds ? '/static/images/list-line.png' : '/static/images/list-row.png'" />
</view>
</view>
<!-- 商品头部店铺 -->
<view
v-if="(state!==3 && shopInfo && isFixedHead === false)"
class="head-shop-info"
>
<view class="shop-info-box">
<view class="con">
<view class="logo">
<image
:src="shopInfo.shopLogo ? util.addDomain(shopInfo.shopLogo) : defaultShopLogo"
@error="shopInfo.shopLogo=''"
/>
</view>
<view class="text">
<view
class="name"
style="padding-right:20rpx"
>
{{ shopInfo.shopName }}
</view>
<view class="focus-box">
<view
v-if="shopInfo.type===1"
class="self"
>
自营
</view>
<view class="focus">
关注人数{{ wxs.parseCollectionNumber(shopInfo.collectionNum) }}
</view>
</view>
</view>
<view
class="btn"
@tap="onToShopPage(shopInfo.shopId)"
>
进店
</view>
</view>
</view>
</view>
<!-- 排序栏 -->
<view
v-if="searchType!==2"
class="sortbar"
>
<view
class="item"
:class="{active:state===0}"
@tap="onSwitchSearchList(0)"
>
默认
</view>
<view
class="item"
:class="{active:state===1, 'arrow-up':sort===2, 'arrow-down':sort===3}"
@tap="onSwitchSearchList(1)"
>
销量
</view>
<view
class="item"
:class="{active:state===2, 'arrow-up':sort===4, 'arrow-down':sort===5}"
@tap="onSwitchSearchList(2)"
>
价格
</view>
</view>
<!-- 筛选栏 -->
<view
v-if="((brandList && brandList.length) || (categoryList && categoryList.length) || (attrList && attrList.length)) && state!==3"
class="screen-column"
>
<view class="sc-tab">
<scroll-view
scroll-x="true"
class="sc-wrap"
>
<!-- 品牌 -->
<view
class="item"
:class="{'active-item':(openWhichConditionItem.type === 0)}"
>
<view
v-if="brandList && brandList.length"
class="item-box"
:class="{'active-item-box': onShowBrandConditonText() && selectedBrandItem && openWhichConditionItem.type!==0}"
@tap="onOpenScreenCondition(0)"
>
<text class="text">
{{ onShowBrandConditonText() || '品牌' }}
</text>
</view>
</view>
<!-- 分类 -->
<view
class="item"
:class="{'active-item':(openWhichConditionItem.type === 1)}"
>
<view
v-if="categoryList && categoryList.length"
class="item-box"
:class="{'active-item-box':onShowCategoryConditionText() && selectedCategoryItem && openWhichConditionItem.type!==1}"
@tap="onOpenScreenCondition(1)"
>
<text class="text">
{{ onShowCategoryConditionText() || '类别' }}
</text>
</view>
</view>
<!-- 属性 -->
<view
v-for="(item, index) in attrList"
:key="index"
class="item"
:class="{'active-item':(openWhichConditionItem.type === 2 && openWhichConditionItem.attrIndex === index)}"
>
<view
class="item-box"
:class="{'active-item-box':item.isActive && openWhichConditionItem.attrIndex !== index}"
@tap="onOpenScreenCondition(2, index)"
>
<text class="text">
{{ onShowAttrConditionText(index) }}
</text>
</view>
</view>
</scroll-view>
<view
class="filter-btn"
@tap="onOpenAllScreenFrame"
>
筛选<image
class="screen-icon"
src="/static/images/screen.png"
/>
</view>
</view>
<!-- 筛选条件展开框 -->
<view
v-if="openWhichConditionItem.type !== ''"
class="sc-options"
>
<view class="opt-content">
<view
v-for="(item, index) in openConditionList"
:key="index"
class="o-item"
@tap="onSelectOrCancelCondition(index)"
>
<image
v-if="item.isSelected"
class="selected-item"
src="/static/images/seleced-item.png"
/>
<text>{{ item.brandName || item.name || item.attrValueName }}</text>
</view>
</view>
<view class="opt-btns">
<view class="btn-box">
<view
class="reset-btn btn"
@tap="onResetScreenCondition()"
>
重置
</view>
</view>
<view class="btn-box">
<view
class="confirm-btn btn"
@tap="onConfirmScreenCondition()"
>
确定
</view>
</view>
</view>
</view>
</view>
<!-- 遮蔽层 -->
<view
v-if="(openWhichConditionItem.type !== '') || (isOpenAllScreenFrame)"
class="filter-mask"
@tap="onCloseScreenCondition()"
/>
<!-- 所有筛选项的框 -->
<view
class="all-screen-frame"
:class="{'show':isOpenAllScreenFrame}"
>
<view class="condition-info">
<view class="first-part part">
<view class="server-or-discount">
<view class="title">
服务/折扣
</view>
<view class="content">
<view
class="c-item"
:class="{'active-c-item':isSelfShop}"
@tap="onSelectScreenCondition(3)"
>
商城自营
</view>
<view
class="c-item"
:class="{'active-c-item':isHasStock}"
@tap="onSelectScreenCondition(4)"
>
仅看有货
</view>
</view>
</view>
<view class="price-range">
<view class="title">
价格区间
</view>
<view class="price-box">
<view class="min-price price-frame">
<input
v-model="minPriceInp"
type="number"
placeholder="最低价"
@input="onLimitPriceRange('min')"
>
</view>
<view class="line">
-
</view>
<view class="max-price price-frame">
<input
v-model="maxPriceInp"
type="number"
placeholder="最高价"
@input="onLimitPriceRange('max')"
>
</view>
</view>
</view>
</view>
<view class="second-part part">
<view
v-if="otherBrandList && otherBrandList.length"
class="brand-item"
>
<view class="title">
品牌
</view>
<view class="content">
<view
v-for="(item, index) in otherBrandList"
:key="index"
class="c-item"
:class="{'active-c-item':item.isSelected}"
@tap="onSelectScreenCondition(0, index)"
>
{{ item.brandName }}
</view>
</view>
</view>
<view class="category-item">
<view class="title">
类别
</view>
<view class="content">
<view
v-for="(item, index) in otherCategoryList"
:key="index"
class="c-item"
:class="{'active-c-item':item.isSelected}"
@tap="onSelectScreenCondition(1, index)"
>
{{ item.name }}
</view>
</view>
</view>
</view>
<view class="third-part part">
<view
v-for="(attrItem, attrIndex) in otherAttrList"
:key="attrIndex"
class="attr-item"
>
<block>
<view class="title">
{{ attrItem.attrName }}
</view>
<view class="content">
<view
v-for="(attrValueItem, attrValueIndex) in attrItem.attrValues"
:key="attrValueIndex"
class="c-item"
:class="{'active-c-item':attrValueItem.isSelected}"
@tap="onSelectScreenCondition(2, attrIndex, attrValueIndex)"
>
{{ attrValueItem.attrValueName }}
</view>
</view>
</block>
</view>
</view>
</view>
<view class="asf-btns">
<view class="btn-box">
<view
class="reset-btn btn"
@tap="onResetAllScreenCondition"
>
重置
</view>
</view>
<view class="btn-box">
<view
class="confirm-btn btn"
@tap="onConfirmAllScreenCondition"
>
确定
</view>
</view>
</view>
</view>
<!-- 商品列表 -->
<view
v-if="searchType!==2 && dataList.length > 0"
:class="[isLineProds ? 'line-prods' : 'prods']"
:style="{'margin-top':((isFixedHead || openWhichConditionItem.type || openWhichConditionItem.type===0) ? '10px' : isLineProds ? '10px' : '0')}"
>
<block v-if="isLineProds">
<block
v-for="(prodItem, prodIndex) in dataList"
:key="prodIndex"
>
<view
class="item"
@tap="onToProdDetailPage(prodItem.spuId)"
>
<view class="img">
<img-show :src="prodItem.mainImgUrl" />
</view>
<view class="text-box">
<view class="name">
{{ prodItem.spuName }}
</view>
<view
v-if="prodItem.sellingPoint"
class="sku"
>
{{ prodItem.sellingPoint }}
</view>
<view class="discount-box">
<view v-if="prodItem.shopType===1">
<view class="discount">
自营
</view>
</view>
<view
v-if="prodItem.spuActivity"
style="display: inline-block;"
>
<view v-if="prodItem.spuActivity.groupActivity">
<view class="discount">
{{ prodItem.spuActivity.groupActivity.groupNumber }}人团
</view>
</view>
</view>
<view
v-if="prodItem.spuActivity"
style="display: inline-block;"
>
<view v-if="prodItem.spuActivity.sekillActivitySpuVO">
<view class="discount">
秒杀
</view>
</view>
</view>
<view
v-if="prodItem.spuActivity"
style="display: inline-block;"
>
<view v-if="prodItem.spuActivity.discountList">
<view
v-for="(item, index) in prodItem.spuActivity.discountList.slice(0, 1)"
:key="index"
class="discount"
>
{{ onDiscountTagText(prodItem.spuActivity.discountList) }}
</view>
</view>
</view>
<view
v-if="prodItem.spuActivity"
style="display: inline-block;"
>
<view v-if="prodItem.spuActivity.couponList">
<view
v-for="(item, index) in prodItem.spuActivity.couponList.slice(0, 1)"
:key="index"
class="coupons"
>
{{ onCouponTagText(prodItem.spuActivity.couponList[0]) }}
</view>
</view>
</view>
</view>
<view class="price-box">
<view class="price">
<view class="symbol">
</view>
<view class="big">
{{ wxs.parsePrice(prodItem.priceFee)[0] }}
</view>
<view class="symbol">
.{{ wxs.parsePrice(prodItem.priceFee)[1] }}
</view>
<view
v-if="prodItem.saleNum || prodItem.saleNum === 0"
class="symbol sold-num"
>
销量 {{ prodItem.saleNum }}
</view>
</view>
</view>
</view>
</view>
</block>
</block>
<block v-if="!isLineProds">
<view
v-for="(val,idx) in getColProdList"
:key="idx"
class="col"
>
<block
v-for="(prodItem, prodIndex) in val"
:key="prodIndex"
>
<view
class="item"
@tap="onToProdDetailPage(prodItem.spuId)"
>
<view class="img">
<img-show :src="prodItem.mainImgUrl" />
</view>
<view class="text-box">
<view class="name">
{{ prodItem.spuName }}
</view>
<view
v-if="prodItem.sellingPoint"
class="sku"
>
{{ prodItem.sellingPoint }}
</view>
<view class="discount-box">
<view v-if="prodItem.shopType===1">
<view class="discount">
自营
</view>
</view>
<view
v-if="prodItem.spuActivity"
style="display: inline-block;"
>
<view v-if="prodItem.spuActivity.groupActivity">
<view class="discount">
{{ prodItem.spuActivity.groupActivity.groupNumber }}人团
</view>
</view>
</view>
<view
v-if="prodItem.spuActivity"
style="display: inline-block;"
>
<view v-if="prodItem.spuActivity.sekillActivitySpuVO">
<view class="discount">
秒杀
</view>
</view>
</view>
<view
v-if="prodItem.spuActivity"
style="display: inline-block;"
>
<view v-if="prodItem.spuActivity.discountList">
<view
v-for="(item, index) in prodItem.spuActivity.discountList.slice(0, 1)"
:key="index"
class="discount"
>
{{ onDiscountTagText(prodItem.spuActivity.discountList) }}
</view>
</view>
</view>
<view
v-if="prodItem.spuActivity"
style="display: inline-block;"
>
<view v-if="prodItem.spuActivity.couponList">
<view
v-for="(item, index) in prodItem.spuActivity.couponList.slice(0, 1)"
:key="index"
class="coupons"
>
{{ onCouponTagText(prodItem.spuActivity.couponList[0]) }}
</view>
</view>
</view>
</view>
<view class="price-box">
<view class="price">
<view class="symbol">
</view>
<view class="big">
{{ wxs.parsePrice(prodItem.priceFee)[0] }}
</view>
<view class="symbol">
.{{ wxs.parsePrice(prodItem.priceFee)[1] }}
</view>
<view
v-if="prodItem.saleNum || prodItem.saleNum === 0"
class="symbol sold-num"
>
销量 {{ prodItem.saleNum }}
</view>
</view>
</view>
</view>
</view>
</block>
</view>
</block>
</view>
<!-- 店铺列表 -->
<view
v-if="searchType===2 && dataList.length > 0"
class="shop-list"
>
<block
v-for="(item, index) in dataList"
:key="index"
>
<view class="item">
<view :class="[!item.spuList?'no-prod':'','shop-info']">
<view class="logo">
<image
:src="item.shopLogo ? util.addDomain(item.shopLogo) : defaultShopLogo"
@error="dataList[index].shopLogo=''"
/>
</view>
<view class="text">
<view class="name">
{{ item.shopName }}
</view>
<view class="focus-box">
<view
v-if="item.type===1"
class="self"
>
自营
</view>
<view class="focus">
关注人数{{ wxs.parseCollectionNumber(item.collectionNum) }}
</view>
</view>
</view>
<view
class="btn"
@tap="onToShopPage(item.shopId)"
>
进店
</view>
</view>
<view class="shop-prods">
<block v-if="item.spuList">
<block
v-for="(prodItem, prodIndex) in item.spuList.slice(0, 3)"
:key="prodIndex"
>
<view
class="p-item"
@tap="onToProdDetailPage(prodItem.spuId)"
>
<view class="img">
<img-show :src="prodItem.mainImgUrl" />
</view>
<view class="name">
{{ prodItem.spuName }}
</view>
<view class="price">
{{ wxs.parsePrice(prodItem.priceFee)[0] + '.' + wxs.parsePrice(prodItem.priceFee)[1] }}
</view>
</view>
</block>
</block>
</view>
</view>
</block>
</view>
</view>
</z-paging>
</template>
<script setup>
import defaultShopLogo from '@/static/images/default-shop-logo.png'
import util from '@/utils/util'
const wxs = number()
const isFixedHead = ref(false) // 头部是固定
const dataList = ref([]) // 商品列表/店铺列表
// 请求参数
const selfShop = ref('') // 商城是否自营
const hasStock = ref('') // 仅看有货
const minPrice = ref('') // 最小价格
const maxPrice = ref('') // 最大价格
const secondaryCategoryId = ref('') // 第二级分类ID
const categoryId = ref('') // 第三级分类ID
const sort = ref('') // 商品排序
const brandIds = ref('') // 品牌
const attrIds = ref('') // 属性
// 搜索类型
const searchType = ref(1) // 1:商品 2:店铺
// 价格
const minPriceInp = ref('')
const initMinPriceInp = ref('')
const maxPriceInp = ref('')
const initMaxPriceInp = ref('')
// 是否自营
const isSelfShop = ref(false)
const initSelfShop = ref(false)
// 仅看有货
const isHasStock = ref(false)
const initHasStock = ref(false)
// 品牌
const brandList = ref([]) // 品牌列表
const selectedBrandList = ref([]) // 选中品牌的列表
const selectedBrandItem = ref('') // 选中品牌字符串(链接里的参数格式)
const otherBrandList = ref([])
// 分类
const categoryName = ref('') // 链接传过来的值
const categoryList = ref([])
const selectedCategoryId = ref('') // 选中的id
const selectedCategoryItem = ref('') // 选中分类项(用来传递)
const otherCategoryList = ref([])
// 属性
const attrList = ref([])
const selectedAttrId = ref('') // 选中的属性id
const selectedAttrValueIdList = ref([]) // 选中的属性值id
const selectedAttrItem = ref('') // 选中的属性项
const otherAttrList = ref([])
const shopInfo = ref('') // 关键词搜索中的店铺信息
/**
* 生命周期函数--监听页面加载
* @param {Object} options 上一个页面传递的参数
*/
onLoad((options) => {
// 处理传递过来的参数
onHandleLinkParams(options)
})
const getColProdList = computed(() => {
const prodListValue = dataList.value
if (prodListValue && prodListValue.length) return [prodListValue.filter((val, idx) => idx % 2 === 0), prodListValue.filter((val, idx) => idx % 2 === 1)] // eslint-disable-line
return []
})
/**
* 处理传来的参数
* @param {Object} options 传递的参数
*/
const showKeyword = ref('') // 用来展示的关键词
const state = ref(0) // 0:商品 1:商品销量排序 2:商品价格排序 3:店铺
const keyword = ref('') // 关键词
const onHandleLinkParams = (options) => {
// 搜索类型
searchType.value = options.type ? Number(options.type) : 1
// 商城自营和仅看有货
selfShop.value = options.shop ? options.shop : ''
hasStock.value = options.stock ? options.stock : ''
isSelfShop.value = initSelfShop.value = !!options.shop
isHasStock.value = initHasStock.value = !!options.stock
// 价格
minPriceInp.value = initMinPriceInp.value = options.minPrice ? options.minPrice : ''
maxPriceInp.value = initMaxPriceInp.value = options.maxPrice ? options.maxPrice : ''
minPrice.value = options.minPrice ? util.accuracyCount(options.minPrice, 100, 2) : ''
maxPrice.value = options.maxPrice ? util.accuracyCount(options.maxPrice, 100, 2) : ''
// 品牌部分
brandIds.value = options.bids ? (options.bids).replace(/\|\|/g, ',') : '' // 请求参数
selectedBrandItem.value = options.bids ? options.bids : '' // 链接参数
selectedBrandList.value = options.bids ? options.bids.split('||') : [] // 选中的列表
// 分类部分
categoryName.value = options.cName ? options.cName : ''
secondaryCategoryId.value = options.cid2
categoryId.value = options.cid
selectedCategoryItem.value = selectedCategoryId.value = options.cid ? options.cid : ''
// 属性参数
attrIds.value = options.aids ? (options.aids).replace(/\|\|/g, ',') : '' // 请求参数
selectedAttrItem.value = options.aids ? options.aids : ''
// 关键词
let keywordValue = ''
// #ifndef MP-WEIXIN
keywordValue = options.keyword ? options.keyword : ''
// #endif
// #ifdef MP-WEIXIN
keywordValue = options.keyword ? decodeURIComponent(decodeURIComponent(options.keyword)) : ''
// #endif
// #ifdef APP-PLUS
keywordValue = options.keyword ? decodeURIComponent(options.keyword) : ''
// #endif
showKeyword.value = keywordValue
keyword.value = keywordValue
// 排序
sort.value = !(options.sort) ? '' : Number(options.sort)
if (!(options.sort)) {
state.value = 0
} else if (Number(options.sort) === 2 || Number(options.sort) === 3) {
state.value = 1
} else if (Number(options.sort) === 4 || Number(options.sort) === 5) {
state.value = 2
}
}
/**
* 获取商品列表
*/
// 展开哪项筛选条件
const openWhichConditionItem = reactive({
type: '',
attrIndex: ''
})
const isOpenAllScreenFrame = ref(false)
const onGetDataList = (pageNum, pageSize) => {
if (searchType.value !== 2) {
// 价格筛选输入框低于0.01,都按0.01的价格处理
const minPriceValue = (minPrice.value && minPrice.value < 1) ? 1 : minPrice.value
const maxPriceValue = (maxPrice.value && maxPrice.value < 1) ? 1 : maxPrice.value
if (secondaryCategoryId.value === 'undefined') {
secondaryCategoryId.value = ''
}
const params = {
url: '/tmerclub_search/ua/search/search_page',
method: 'GET',
data: {
pageSize,
pageNum,
keyword: keyword.value,
needActivity: 1,
selfShop: selfShop.value,
hasStock: hasStock.value,
minPrice: minPriceValue,
maxPrice: maxPriceValue,
sort: sort.value,
secondaryCategoryId: secondaryCategoryId.value || '',
categoryId: categoryId.value || '',
brandIds: brandIds.value,
attrIds: attrIds.value
}
}
http.request(params).then((res) => {
if (res.list[0]?.categorys[0]?.categoryId || categoryId.value) {
onHandlePordReturnResult(res)
} else {
paging.value.complete(res.list[0].spus)
}
isOpenAllScreenFrame.value = false
openWhichConditionItem.type = ''
})
} else {
const params = {
url: '/tmerclub_admin/ua/shop_detail/page',
method: 'get',
data: {
pageNum,
pageSize,
shopName: keyword.value,
spuNum: 3
}
}
http.request(params).then(res => {
paging.value.complete(res.list)
})
}
}
/**
* 处理商品搜索接口返回的结果
* @param {Object} res 商品搜索接口返回结果
*/
const paging = ref(null)
const onHandlePordReturnResult = (res) => {
const params = {
url: '/tmerclub_product/ua/category/category_search_item',
method: 'get',
data: {
categoryId: res.list && (res.list[0]?.categorys[0]?.categoryId) ? res.list[0]?.categorys[0]?.categoryId : categoryId.value
}
}
http.request(params).then(({ categoryVO }) => {
// 品牌列表
if (res.list) {
res.list[0].brands.forEach((item) => {
item.isSelected = false
})
brandList.value = res.list[0].brands
// 找出数组相同项(需优化,如果几千个品牌和选中了多个品牌项,会占不少的速度)
if (selectedBrandItem.value) {
const selectedBrandItemList = selectedBrandItem.value.split('||')
// 使用该方式赋值,不是直接赋值对象的地址,而是赋值对象的值,从而不会出现新旧对象的值同时改变
brandList.value.forEach((brandItem) => {
selectedBrandItemList.forEach((idItem) => {
if (brandItem.brandId === Number(idItem)) {
brandItem.isSelected = true
}
})
})
}
// 属性列表
res.list[0].attrs.forEach((attrItem) => {
attrItem.isActive = false
attrItem.attrValues.forEach((attrValueItem) => {
attrValueItem.isSelected = false
})
})
attrList.value = res.list[0].attrs
// 处理链接里得属性参数, 用来回显 格式attrId1_attrValueId1||attrValueId2^attrId2_attrValueId1
if (selectedAttrItem.value) {
const attrItemArr = selectedAttrItem.value.split('^')
attrList.value.forEach(attrItem => {
attrItemArr.forEach((attrStrItem) => {
if (Number(attrItem.attrId) === Number(attrStrItem.split('_')[0])) {
const attrValueArr = attrStrItem.split('_')[1].split('||')
attrItem.isActive = true
attrItem.attrValues.forEach((attrValueItem) => {
attrValueArr.forEach((attrValueId) => {
if (Number(attrValueItem.attrValueId) === Number(attrValueId)) {
attrValueItem.isSelected = true
selectedAttrValueIdList.value.push(attrValueItem.attrValueId)
}
})
})
}
})
})
}
shopInfo.value = res.list[0].shopInfo
paging.value.complete(res.list[0].spus)
} else {
paging.value.complete([])
brandList.value = []
attrList.value = []
shopInfo.value = ''
}
// 分类列表
categoryVO.forEach((item) => {
item.isSelected = false
})
categoryList.value = categoryVO
// 回显
categoryList.value.forEach((item) => {
if (item.categoryId == selectedCategoryItem.value) {
item.isSelected = true
}
})
})
}
// 展示品牌筛选条件的文字
const onShowBrandConditonText = () => {
let result = ''
if (selectedBrandItem.value === '') {
result = '品牌'
} else {
// 这里有个问题,触发了两遍
const selectedBrandItemList = selectedBrandItem.value.split('||')
const brandListValue = brandList.value
// 筛选出两个数组相同的元素
const showBrandList = brandListValue.filter(function (n) {
return selectedBrandItemList.indexOf((n.brandId + '')) != -1
})
showBrandList.forEach((item, index, list) => {
if ((index + 1) < list.length) {
result += item.brandName + ','
} else {
result += item.brandName
}
})
}
return result
}
// 展示分类筛选条件的文字
const onShowCategoryConditionText = () => {
let result = ''
if (selectedCategoryItem.value === '') {
result = '类别'
} else {
const selectedCategoryItemValue = selectedCategoryItem.value
const categoryListValue = categoryList.value
for (let i = 0; i < categoryListValue.length; i++) {
if (Number(categoryListValue[i].categoryId) === Number(selectedCategoryItemValue)) {
result = categoryListValue[i].name
break
}
}
result = result || categoryName.value
}
return result
}
// 展示属性筛选条件的文字
const onShowAttrConditionText = (index) => {
let result = ''
const isActive = attrList.value[index].isActive
if (isActive) {
attrList.value[index].attrValues.forEach((item) => {
if (item.isSelected === true) {
result += item.attrValueName + ','
}
})
result = result.slice(0, result.length - 1)
} else {
result = attrList.value[index].attrName
}
return result
}
/**
* 满减折标签文字
* @param {Number} discountRule 0 满钱减钱 3满件打折
*/
const onDiscountTagText = (discountRule) => {
if (discountRule.length === 0) return
const dis = discountRule[0].discountRule
let result = ''
if (dis === 0) {
result = '满减钱'
} else if (dis === 3) {
result = '满件折'
}
return result
}
/**
* 优惠券标签文字
* @param {Object} couponInfo 优惠券信息
*/
const onCouponTagText = (couponInfo) => {
if (!couponInfo) return ''
let result = ''
// couponType 1:代金券 2:折扣券 3:兑换券(目前没有)
const couponType = couponInfo.couponType
const cashCondition = couponInfo.cashCondition
const reduceAmount = couponInfo.reduceAmount
const couponDiscount = couponInfo.couponDiscount
if (couponType === 1) {
result = '满' + ((cashCondition / 100).toFixed(2)) + '元减' + ((reduceAmount / 100).toFixed(2))
} else if (couponType === 2) {
result = '满' + ((cashCondition / 100).toFixed(2)) + '元打' + couponDiscount + '折'
}
return result
}
/**
* 展开搜索筛选条件
* @param {Number} index 0:品牌 1:分类 2:属性
* @param {Number} attrIndex 属性索引
*/
// 展开项的列表
const openConditionList = ref([])
const onOpenScreenCondition = (index, attrIndex) => {
if ((openWhichConditionItem.type === index && index !== 2) || (index === 2 && openWhichConditionItem.attrIndex === attrIndex)) {
// 收起
onCloseScreenCondition()
} else {
// 展开
onInitScreenConditionState()
openWhichConditionItem.type = index
if (index === 0) {
openWhichConditionItem.attrIndex = ''
openConditionList.value = JSON.parse(JSON.stringify(brandList.value))
selectedBrandList.value = selectedBrandItem.value ? selectedBrandItem.value.split('||') : []
} else if (index === 1) {
openWhichConditionItem.attrIndex = ''
openConditionList.value = JSON.parse(JSON.stringify(categoryList.value))
} else if (index === 2) {
openWhichConditionItem.attrIndex = attrIndex
openConditionList.value = JSON.parse(JSON.stringify(attrList.value[attrIndex].attrValues))
selectedAttrId.value = attrList.value[attrIndex].attrId
const tempSelectedAttrValueIdList = []
// 把回显的属性id加入selectAttrValueIdList
for (let i = 0; i < openConditionList.value.length; i++) {
if (openConditionList.value[i].isSelected === true) {
tempSelectedAttrValueIdList.push(openConditionList.value[i].attrValueId)
}
}
selectedAttrValueIdList.value = tempSelectedAttrValueIdList
}
}
}
// 选择/取消筛选条件
const onSelectOrCancelCondition = (index) => {
// type 0:品牌 1:分类 2:属性
const type = openWhichConditionItem.type
switch (type) {
case 0: {
const selectedBrandId = openConditionList.value[index].brandId
openConditionList.value[index].isSelected = !openConditionList.value[index].isSelected
if (openConditionList.value[index].isSelected === true) {
selectedBrandList.value.push(selectedBrandId)
} else {
for (let i = 0; i < selectedBrandList.value.length; i++) {
if (Number(selectedBrandList.value[i]) === Number(selectedBrandId)) {
selectedBrandList.value.splice(i, 1)
return
}
}
}
break
}
case 1:{
if (openConditionList.value[index].isSelected) {
openConditionList.value[index].isSelected = false
categoryList.value[index].isSelected = false
selectedCategoryId.value = ''
return
}
openConditionList.value.forEach((item) => {
item.isSelected = false
})
const selectedCategoryIdValue = openConditionList.value[index].categoryId
selectedCategoryId.value = selectedCategoryIdValue
openConditionList.value[index].isSelected = !openConditionList.value[index].isSelected
categoryList.value = openConditionList.value
break
}
case 2: {
const attrValueId = openConditionList.value[index].attrValueId
openConditionList.value[index].isSelected = !openConditionList.value[index].isSelected
// 选中或取消选中属性值
if (openConditionList.value[index].isSelected) {
selectedAttrValueIdList.value.push(attrValueId)
} else {
for (const i in selectedAttrValueIdList.value) {
if (selectedAttrValueIdList.value[i] === attrValueId) {
selectedAttrValueIdList.value.splice(i, 1)
break
}
}
}
break
}
}
}
// 重置筛选选中项
const onResetScreenCondition = () => {
// type 0:品牌 1:分类 2:属性
const type = openWhichConditionItem.type
openConditionList.value.forEach((item) => {
item.isSelected = false
})
switch (type) {
case 0:
selectedBrandList.value = []
break
case 1:
selectedCategoryId.value = ''
break
case 2:
selectedAttrValueIdList.value = []
break
}
}
// 确定筛选条件
const onConfirmScreenCondition = () => {
// type 0:品牌 1:分类 2:属性
const type = openWhichConditionItem.type
let selectedBrandItemValue = ''
let selectedCategoryItemValue = ''
let selectedAttrItemValue = ''
switch (type) {
case 0:{
let tempSeletedBrandItem = ''
for (let i = 0; i < selectedBrandList.value.length; i++) {
if ((i + 1) < selectedBrandList.value.length) {
tempSeletedBrandItem += selectedBrandList.value[i] + '||'
} else {
tempSeletedBrandItem += selectedBrandList.value[i]
}
}
selectedBrandItemValue = tempSeletedBrandItem
break
}
case 1: {
const index = openConditionList.value.findIndex(item => Number(selectedCategoryId.value) === item.categoryId)
if (index < 0) {
selectedCategoryId.value = ''
}
selectedCategoryItemValue = selectedCategoryId.value
categoryName.value = ''
break
}
case 2:{
// 处理属性的参数
const selectedAttrIdValue = selectedAttrId.value
const selectedAttrValueIdListValue = selectedAttrValueIdList.value
if (selectedAttrIdValue && selectedAttrValueIdListValue.length > 0) {
let selectedAttrValueIdStr = ''
for (let i = 0; i < selectedAttrValueIdList.value.length; i++) {
if ((i + 1) < selectedAttrValueIdList.value.length) {
selectedAttrValueIdStr += selectedAttrValueIdList.value[i] + '||'
} else {
selectedAttrValueIdStr += selectedAttrValueIdList.value[i]
}
}
if (selectedAttrItem.value) {
const attrItemArr = selectedAttrItem.value.split('^')
let isInSelectedAttrItem = false
let tempSelectedAttrItem = ''
for (let i = 0; i < attrItemArr.length; i++) {
const attrId = attrItemArr[i].split('_')[0]
if (Number(attrId) === Number(selectedAttrIdValue)) {
attrItemArr[i] = attrItemArr[i].split('_')[0] + '_' + selectedAttrValueIdStr
isInSelectedAttrItem = true
}
if ((i + 1) < attrItemArr.length) {
tempSelectedAttrItem += attrItemArr[i] + '^'
} else {
tempSelectedAttrItem += attrItemArr[i]
}
}
selectedAttrItemValue = isInSelectedAttrItem ? tempSelectedAttrItem : tempSelectedAttrItem + '^' + selectedAttrIdValue + '_' + selectedAttrValueIdStr
} else {
selectedAttrItemValue = selectedAttrIdValue + '_' + selectedAttrValueIdStr
}
} else {
if (selectedAttrItem.value) {
const selectedAttrIdValue = selectedAttrId.value
const attrItemArr = selectedAttrItem.value.split('^')
const selectedAttrArr = []
for (let i = 0; i < attrItemArr.length; i++) {
const attrId = attrItemArr[i].split('_')[0]
if (Number(attrId) !== Number(selectedAttrIdValue)) {
selectedAttrArr.push(attrItemArr[i])
}
}
for (let i = 0; i < selectedAttrArr.length; i++) {
if ((i + 1) < selectedAttrArr.length) {
selectedAttrItemValue += selectedAttrArr[i] + '^'
} else {
selectedAttrItemValue += selectedAttrArr[i]
}
}
} else {
selectedAttrItemValue = ''
}
}
break
}
}
// 处理原本已经有筛选条件情况下的判断
selectedBrandItem.value = type !== 0 ? selectedBrandItem.value : selectedBrandItemValue // 品牌
selectedCategoryItem.value = type !== 1 ? selectedCategoryItem.value : selectedCategoryItemValue // 分类
selectedAttrItem.value = type !== 2 ? selectedAttrItem.value : selectedAttrItemValue // 属性
// 防止未点击分类关键词时弹窗要点两次弹开 已经样式不变化
onCloseScreenCondition()
onToSearchList()
}
// 关掉浮起的内容
const onCloseScreenCondition = () => {
isOpenAllScreenFrame.value = false
openWhichConditionItem.type = ''
openWhichConditionItem.attrIndex = ''
onInitScreenConditionState()
}
// 初始化筛选条件的状态
const onInitScreenConditionState = () => {
openConditionList.value = [] // 展开筛选条件的列表
selectedBrandList.value = [] // 选中品牌列表
selectedAttrId.value = '' // 选中属性id
}
// 展开筛选框(所有项)
const onOpenAllScreenFrame = () => {
onCloseScreenCondition()
isOpenAllScreenFrame.value = true
// 初始化值
isSelfShop.value = initSelfShop.value
isHasStock.value = initHasStock.value
minPriceInp.value = initMinPriceInp.value
maxPriceInp.value = initMaxPriceInp.value
otherBrandList.value = JSON.parse(JSON.stringify(brandList.value))
otherCategoryList.value = JSON.parse(JSON.stringify(categoryList.value))
otherAttrList.value = JSON.parse(JSON.stringify(attrList.value))
}
/**
* 选中/取消筛选条件
* @param {Number} type 0:品牌 1:分类 2:属性 3:商城自营 4:仅看有货
*/
const onSelectScreenCondition = (type, index, attrValueIndex) => {
switch (type) {
case 0:
otherBrandList.value[index].isSelected = !otherBrandList.value[index].isSelected
break
case 1:
if (otherCategoryList.value[index].isSelected === true) {
otherCategoryList.value[index].isSelected = false
return
}
otherCategoryList.value.forEach((item) => {
item.isSelected = false
})
otherCategoryList.value[index].isSelected = !otherCategoryList.value[index].isSelected
break
case 2:
otherAttrList[index].attrValues[attrValueIndex].isSelected = !otherAttrList.value[index].attrValues[attrValueIndex].isSelected
break
case 3:
isSelfShop.value = !isSelfShop.value
break
case 4:
isHasStock.value = !isHasStock.value
break
}
}
// 重置所有筛选条件
const onResetAllScreenCondition = () => {
// 商城自营和仅看有货
isSelfShop.value = false
isHasStock.value = false
// 价格
minPriceInp.value = ''
maxPriceInp.value = ''
// 品牌
otherBrandList.value.forEach((item) => {
item.isSelected = false
})
// 分类
otherCategoryList.value.forEach((item) => {
item.isSelected = false
})
// 属性
otherAttrList.value.forEach((attrItem) => {
attrItem.attrValues.forEach((attrValueItem) => {
attrValueItem.isSelected = false
})
})
}
// 确定所有筛选条件
const onConfirmAllScreenCondition = () => {
// 商城自营和仅看有货
selfShop.value = isSelfShop.value ? 1 : ''
hasStock.value = isHasStock.value ? 1 : ''
// 品牌
let selectedBrandItemValue = ''
otherBrandList.value.forEach((item) => {
if (item.isSelected) {
selectedBrandItemValue += item.brandId + '||'
}
})
selectedBrandItemValue = selectedBrandItemValue ? selectedBrandItemValue.substring(0, selectedBrandItemValue.length - 2) : ''
selectedBrandItem.value = selectedBrandItemValue
// 分类
let selectedCategoryItemValue = ''
for (let i = 0; i < otherCategoryList.value.length; i++) {
if (otherCategoryList.value[i].isSelected) {
selectedCategoryItemValue = otherCategoryList.value[i].categoryId
break
}
}
selectedCategoryItem.value = selectedCategoryItemValue
// 属性
const attrList = otherAttrList.value
let selectedAttrItemValue = ''
attrList.forEach((attrItem) => {
let selectedAttrValueItem = ''
let isHaveSelectedItem = false
attrItem.attrValues.forEach((attrValueItem) => {
if (attrValueItem.isSelected) {
isHaveSelectedItem = true
selectedAttrValueItem += attrValueItem.attrValueId + '||'
}
})
selectedAttrValueItem = isHaveSelectedItem ? selectedAttrValueItem.substring(0, selectedAttrValueItem.length - 2) : ''
selectedAttrItemValue += isHaveSelectedItem ? attrItem.attrId + '_' + selectedAttrValueItem + '^' : ''
})
selectedAttrItemValue = selectedAttrItemValue.substring(0, selectedAttrItemValue.length - 1)
selectedAttrItem.value = selectedAttrItemValue
onToSearchList()
}
/**
* 切换搜索条件
* @param {Number} state 0:商品(默认) 1:商品销量排序 2:商品价格排序 3:店铺
*/
const onSwitchSearchList = (state) => {
switch (state) {
case 0:
sort.value = ''
break
case 1:
sort.value = sort.value === 2 ? 3 : 2
break
case 2:
sort.value = sort.value === 4 ? 5 : 4
break
case 3:
sort.value = 9
break
}
onToSearchList()
}
/**
* 限制价格筛选输入框的范围
* @param {String} mark min:最小价格输入框 max:最大价格输入框
*/
const onLimitPriceRange = (mark) => {
let limitPrice = ''
if (mark === 'min') {
limitPrice = minPriceInp.value
} else {
limitPrice = maxPriceInp.value
}
// 获取小数点后的数量
const count = onJudgeDecimalLength(limitPrice)
if (limitPrice > 0 && limitPrice < 0.01) {
limitPrice = 0.01
} else if (count > 2) {
limitPrice = Number(limitPrice).toFixed(2)
} else if (limitPrice > 100000000) {
limitPrice = 100000000
}
setTimeout(() => {
if (mark === 'min') {
minPriceInp.value = limitPrice
} else {
maxPriceInp.value = limitPrice
}
}, 0)
}
/**
* 判断一个数是多少位小数
* @param {Number} num 数字
* @returns {Number} count 小数点后的数字长度
*/
const onJudgeDecimalLength = (num) => {
const dotSite = String(num).indexOf('.') + 1
const count = dotSite > 0 ? String(num).length - dotSite : 0
return count
}
// 切换商品列表样式
const isLineProds = ref(true) // 列表格式,默认横排展示
const onChangeListStyle = () => {
isLineProds.value = !isLineProds.value
}
// 修改搜索参数
const onToSearchList = () => {
const options = {
keyword: keyword.value, // 关键字
minPrice: minPriceInp.value, // 最小价格
maxPrice: maxPriceInp.value, // 最大价格
shop: selfShop.value, // 是否是自营店
stock: hasStock.value, // 是否有库存
sort: sort.value, // 排序
bids: selectedBrandItem.value, // 品牌
cid: selectedCategoryItem.value, // 分类
cName: categoryName.value, // 分类名称
aids: selectedAttrItem.value, // 属性
cid2: secondaryCategoryId.value
}
onHandleLinkParams(options)
paging.value.reload()
}
/**
* 跳转到搜索页
* @param {Number} type 0:删除关键词跳转 1:直接跳转
*/
const onToSearchPage = (type) => {
const url = type === 0 ? `/pages/search-page/search-page?type=${searchType.value}` : `/pages/search-page/search-page?keyword=${encodeURIComponent(keyword.value)}&type=${searchType.value}`
uni.redirectTo({ url })
}
// 跳转到店铺页
const onToShopPage = (shopId) => {
onGetShopInfo(shopId)
}
/**
* 获取店铺信息
*/
const onGetShopInfo = (shopId) => {
const params = {
url: '/tmerclub_admin/ua/shop_detail/head_info',
method: 'GET',
data: {
shopId,
imgType: 0 // 图片类型0.app(h5) 1.pc
}
}
http.request(params).then((res) => {
uni.setStorageSync('cloudShopInfo', res)
uni.redirectTo({
url: res.renovationId ? '/package-shop/shop-page/feature-index/feature-index?shopId=' + res.shopId + '&renovationId=' + res.renovationId : '/package-shop/shop-page/shop-index/shop-index?shopId=' + shopId
})
})
}
// 跳转到商品详情页
const onToProdDetailPage = (spuId) => {
uni.navigateTo({
url: '/pages/detail/detail?spuId=' + spuId
})
}
</script>
<style lang="scss" scoped>
@use './search-list.scss';
</style>