<template>
|
<view class="search_root">
|
<!-- 首页搜索(保留原逻辑) -->
|
<view class="search search--legacy" v-if="show && status === 0" @click="close">
|
<view class="search_box" @click.stop="test">
|
<view class="search_box_item" :style="searchBarBgStyle">
|
<view class="icon">
|
<image src="@/static/ic_search@2x.png" mode="widthFix"></image>
|
</view>
|
<view class="search_box_item_right">
|
<text v-if="name1">{{ name1 }}</text>
|
<input type="text" class="search_box_item_right_ipt" :focus="focus" v-model="category" @input="inputCategory(name1 ? 2 : 1)" placeholder-class="placeholder" placeholder="搜索" />
|
</view>
|
</view>
|
<view class="search_box_item_xl" v-if="searchData && searchData.length > 0">
|
<view class="search_box_item_xl_head">
|
<text class="search_box_item_xl_head_label">搜索结果</text>
|
<text class="search_box_item_xl_head_count">{{ searchData.length }} 条</text>
|
</view>
|
<view class="search_box_item_xl_body">
|
<view class="search_box_item_xl_item" v-for="(item, i) in searchData" :key="i">
|
<view :class="index === i ? 'search_box_item_xl_item_name active' : 'search_box_item_xl_item_name'" @click="clickItem(item, i)" @mouseenter="aaa(i)" @mouseleave="bbb">
|
<span :style="{ color: fontColorIndex === i ? fontColor : '' }">{{ item.name }}</span>
|
</view>
|
<span class="search_box_item_xl_price" v-if="item.price">¥{{ item.price }}</span>
|
</view>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<!-- PK / 商品列表 选择商品 -->
|
<view class="pk_search" v-if="show && status !== 0" @click="close">
|
<view class="pk_search_panel" @click.stop="test">
|
<view class="pk_search_head" :style="pkSearchHeadStyle">
|
<view class="pk_search_head_left">
|
<text class="pk_search_title">选择商品</text>
|
<text class="pk_search_badge" v-if="pkSideText">{{ pkSideText }}</text>
|
</view>
|
<view class="pk_search_close" @click.stop="close">
|
<image src="@/static/ic_close@2x.png" mode="widthFix"></image>
|
</view>
|
</view>
|
|
<view class="pk_search_body">
|
<view class="pk_search_cat" v-if="categoryName">
|
<text class="pk_search_cat_label">品类</text>
|
<text class="pk_search_cat_name">{{ categoryName }}</text>
|
</view>
|
|
<view class="pk_search_bar" :style="searchBarBgStyle">
|
<image class="pk_search_bar_icon" src="@/static/ic_search@2x.png" mode="widthFix"></image>
|
<view class="pk_search_bar_divider"></view>
|
<input
|
type="text"
|
class="pk_search_bar_input"
|
:focus="focus"
|
v-model="category"
|
@input="inputCategory(1)"
|
placeholder-class="pk_search_placeholder"
|
placeholder="搜索型号" />
|
</view>
|
|
<view class="pk_search_table_head" v-if="searchData.length">
|
<text class="col col_name">商品型号</text>
|
<text class="col col_price">指导价</text>
|
</view>
|
|
<view class="pk_search_list" v-if="searchData.length">
|
<view
|
class="pk_search_item"
|
v-for="(item, i) in searchData"
|
:key="i"
|
:class="{ 'pk_search_item--active': index === i }"
|
@click="clickItem(item, i)"
|
@mouseenter="aaa(i)"
|
@mouseleave="bbb">
|
<text class="pk_search_item_name">{{ item.name }}</text>
|
<text class="pk_search_item_price" v-if="item.price">¥{{ item.price }}</text>
|
</view>
|
</view>
|
|
<view class="pk_search_empty" v-else>
|
<text>{{ category ? '未找到匹配商品' : '该品类下暂无商品' }}</text>
|
</view>
|
|
<view class="pk_search_footer" v-if="searchData.length">
|
<text>共 {{ searchData.length }} 件商品</text>
|
</view>
|
</view>
|
</view>
|
</view>
|
</view>
|
</template>
|
|
<script>
|
import { listForH5 } from '@/apis/index.js'
|
import { filterGoods, matchKeyword } from '@/utils/goodsFilter.js'
|
|
const DEFAULT_THEME_BG = '#4A3728'
|
const DEFAULT_THEME_COLOR = '#FFFFFF'
|
|
export default {
|
data() {
|
return {
|
category: '',
|
categoryId: '',
|
name: '',
|
show: false,
|
type: '',
|
typeName: '',
|
searchData: [],
|
name1: '',
|
name2: '',
|
index: 0,
|
focus: true,
|
fontColorIndex: ''
|
}
|
},
|
props: {
|
categoryList: {
|
type: Array,
|
default: () => []
|
},
|
shopList: {
|
type: Array,
|
default: () => []
|
},
|
allGoods: {
|
type: Array,
|
default: () => []
|
},
|
status: {
|
type: Number
|
},
|
search: {
|
type: Object,
|
default: null
|
},
|
conMark: {
|
type: Object,
|
default: null
|
},
|
categoryName: {
|
type: [Number, String]
|
},
|
categoryid: {
|
type: [Number, String]
|
},
|
fontColor: {
|
type: [Number, String]
|
},
|
excludeGoodsId: {
|
type: [Number, String],
|
default: ''
|
}
|
},
|
computed: {
|
pkSideText() {
|
if (this.typeName === 'left') return 'PK 左侧'
|
if (this.typeName === 'right') return 'PK 右侧'
|
return ''
|
},
|
searchBarBgStyle() {
|
const s = this.search || {}
|
const defaultBg = 'rgba(255, 255, 255, 0.92)'
|
if (!s || Number(s.bgType) !== 1) {
|
return { background: defaultBg }
|
}
|
return {
|
background: this.percentage(s.bgColor || '#FFFFFF', s.bgAlpha || 100)
|
}
|
},
|
pkSearchHeadStyle() {
|
const theme = this.resolveThemeConfig()
|
return {
|
background: Number(theme.bgType) === 1 ? (theme.bgColor || DEFAULT_THEME_BG) : DEFAULT_THEME_BG,
|
color: Number(theme.colorType) === 1 ? (theme.color || DEFAULT_THEME_COLOR) : DEFAULT_THEME_COLOR
|
}
|
}
|
},
|
watch: {
|
show(val) {
|
if (val) {
|
this.category = ''
|
this.name = ''
|
this.searchData = []
|
this.name1 = ''
|
this.name2 = ''
|
}
|
}
|
},
|
methods: {
|
aaa(index) {
|
this.fontColorIndex = index
|
},
|
bbb() {
|
this.fontColorIndex = ''
|
},
|
percentage(bgColor, alpha) {
|
const res = +(alpha * 2.55).toFixed(0)
|
return bgColor + res.toString(16)
|
},
|
resolveThemeConfig() {
|
const cfg = this.conMark
|
if (!cfg) {
|
return { bgType: 0, bgColor: DEFAULT_THEME_BG, colorType: 0, color: DEFAULT_THEME_COLOR }
|
}
|
if (cfg.theme) return cfg.theme
|
const t = cfg.table || {}
|
const h = cfg.header || {}
|
return {
|
bgType: Number(t.headerBgType) === 1 ? 1 : (Number(h.bgType) === 1 ? 1 : 0),
|
bgColor: t.headerBg || h.bgColor || DEFAULT_THEME_BG,
|
colorType: Number(t.headerColorType) === 1 ? 1 : (Number(h.colorType) === 1 ? 1 : 0),
|
color: t.headerColor || h.color || DEFAULT_THEME_COLOR
|
}
|
},
|
confirm() {
|
if (this.type === 2) {
|
this.name = this.searchData[this.index].name
|
this.$emit('result', this.searchData[this.index])
|
this.show = false
|
this.index = 0
|
return
|
}
|
if (this.categoryName) {
|
this.name = this.searchData[this.index].name
|
this.$emit('result', this.searchData[this.index])
|
this.show = false
|
this.index = 0
|
return
|
}
|
this.focus = false
|
this.name1 = this.searchData[this.index].name
|
this.category = ''
|
this.categoryId = this.searchData[this.index].id
|
this.searchData = []
|
this.$nextTick(() => {
|
setTimeout(() => {
|
this.focus = true
|
}, 500)
|
})
|
this.index = 0
|
},
|
changeTop() {
|
if (this.index === 0) return
|
this.index -= 1
|
},
|
changeBottom() {
|
if (this.searchData.length - 1 === this.index) return
|
this.index += 1
|
},
|
getShop(keyword) {
|
const categoryId = this.categoryid || this.categoryId
|
let list = []
|
if (this.allGoods && this.allGoods.length) {
|
list = filterGoods(this.allGoods, { categoryId, keyword })
|
} else {
|
listForH5({ categoryId, keyword }).then(res => {
|
this.searchData = this.filterExcludedGoods(res.data || [])
|
})
|
return
|
}
|
this.searchData = this.filterExcludedGoods(list)
|
},
|
filterExcludedGoods(list) {
|
const arr = Array.isArray(list) ? list : []
|
if (this.excludeGoodsId == null || this.excludeGoodsId === '') return arr
|
return arr.filter(item => String(item.id) !== String(this.excludeGoodsId))
|
},
|
inputName() {
|
if (this.status === 1 || this.status === 2) {
|
this.category = this.categoryName
|
}
|
if (!this.category && this.name) {
|
this.type = 1
|
this.searchData = this.shopList.filter(item => matchKeyword(item, this.name))
|
return this.searchData
|
}
|
if (this.category && this.name) {
|
this.type = 2
|
const arr = this.shopList.filter(item => item.categoryName == this.category)
|
this.searchData = arr.filter(item => matchKeyword(item, this.name))
|
} else {
|
this.searchData = []
|
}
|
},
|
inputCategory(type) {
|
if (this.status === 0) {
|
this.type = type
|
if (type === 1) {
|
if (!this.category) {
|
this.searchData = []
|
return
|
}
|
this.searchData = this.categoryList.filter(item => matchKeyword(item, this.category))
|
} else if (type === 2) {
|
if (!this.category) {
|
this.searchData = []
|
return
|
}
|
this.getShop(this.category)
|
} else {
|
this.searchData = []
|
}
|
} else {
|
this.getShop(this.category || '')
|
}
|
},
|
clickItem(item, index) {
|
if (this.type === 2) {
|
this.name = item.name
|
this.$emit('result', item)
|
this.show = false
|
this.index = 0
|
return
|
}
|
if (this.categoryName || this.status !== 0) {
|
this.name = item.name
|
this.$emit('result', item)
|
this.show = false
|
this.index = 0
|
return
|
}
|
this.focus = false
|
this.name1 = item.name
|
this.category = ''
|
this.categoryId = item.id
|
this.searchData = []
|
this.$nextTick(() => {
|
setTimeout(() => {
|
this.focus = true
|
}, 800)
|
})
|
this.index = 0
|
},
|
open(type) {
|
this.typeName = type
|
this.category = ''
|
this.name = ''
|
this.searchData = []
|
this.name1 = ''
|
this.name2 = ''
|
this.index = 0
|
this.show = true
|
this.focus = false
|
this.$nextTick(() => {
|
this.focus = true
|
if (this.status !== 0) {
|
this.loadCategoryGoods('')
|
}
|
})
|
},
|
loadCategoryGoods(keyword) {
|
const categoryId = this.categoryid || this.categoryId
|
if (!categoryId) {
|
this.searchData = []
|
return
|
}
|
this.getShop(keyword || '')
|
},
|
close() {
|
this.show = false
|
},
|
test() {
|
return false
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
$brown: #4A3728;
|
$brown-dark: #3D2E22;
|
$cream: #E8DCC8;
|
$panel-bg: #F7F0E6;
|
$orange: #FF8C42;
|
$gold: #FFD88A;
|
$search-icon-filter: brightness(0) saturate(100%) invert(23%) sepia(14%) saturate(1067%) hue-rotate(349deg) brightness(95%) contrast(91%);
|
|
/* ===== 根容器 ===== */
|
.search_root {
|
display: contents;
|
}
|
|
/* ===== PK 选择商品弹框 ===== */
|
.pk_search {
|
position: fixed;
|
z-index: 1000;
|
inset: 0;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
padding: 24px 16px;
|
box-sizing: border-box;
|
background: rgba(61, 46, 34, 0.48);
|
backdrop-filter: blur(4px);
|
}
|
|
.pk_search_panel {
|
width: 100%;
|
max-width: 640px;
|
max-height: min(78vh, 680px);
|
display: flex;
|
flex-direction: column;
|
border-radius: 18px;
|
overflow: hidden;
|
box-shadow: 0 20px 48px rgba(61, 46, 34, 0.28);
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
}
|
|
.pk_search_head {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 16px 18px;
|
flex-shrink: 0;
|
}
|
|
.pk_search_head_left {
|
display: flex;
|
align-items: center;
|
gap: 10px;
|
min-width: 0;
|
}
|
|
.pk_search_title {
|
font-size: 17px;
|
font-weight: 600;
|
line-height: 1.2;
|
}
|
|
.pk_search_badge {
|
padding: 3px 10px;
|
border-radius: 999px;
|
font-size: 11px;
|
font-weight: 600;
|
color: $brown;
|
background: $gold;
|
line-height: 1.3;
|
flex-shrink: 0;
|
}
|
|
.pk_search_close {
|
width: 32px;
|
height: 32px;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
border-radius: 50%;
|
background: rgba(255, 255, 255, 0.12);
|
cursor: pointer;
|
flex-shrink: 0;
|
transition: background 0.15s;
|
|
&:hover {
|
background: rgba(255, 255, 255, 0.22);
|
}
|
|
image {
|
width: 18px;
|
height: 18px;
|
opacity: 0.92;
|
}
|
}
|
|
.pk_search_body {
|
flex: 1;
|
min-height: 0;
|
display: flex;
|
flex-direction: column;
|
padding: 16px 16px 14px;
|
background: linear-gradient(180deg, #FFF9EC 0%, $panel-bg 100%);
|
}
|
|
.pk_search_cat {
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
margin-bottom: 12px;
|
padding: 8px 12px;
|
border-radius: 10px;
|
background: rgba(255, 255, 255, 0.72);
|
border: 1px solid rgba(74, 55, 40, 0.08);
|
}
|
|
.pk_search_cat_label {
|
font-size: 12px;
|
color: rgba(74, 55, 40, 0.55);
|
flex-shrink: 0;
|
}
|
|
.pk_search_cat_name {
|
font-size: 14px;
|
font-weight: 600;
|
color: $brown;
|
line-height: 1.3;
|
}
|
|
.pk_search_bar {
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
padding: 10px 14px;
|
margin-bottom: 12px;
|
border-radius: 24px;
|
box-shadow: 0 2px 10px rgba(74, 55, 40, 0.08);
|
border: 1px solid rgba(74, 55, 40, 0.08);
|
flex-shrink: 0;
|
}
|
|
.pk_search_bar_icon {
|
width: 15px;
|
height: 15px;
|
flex-shrink: 0;
|
filter: $search-icon-filter;
|
}
|
|
.pk_search_bar_divider {
|
width: 1px;
|
height: 16px;
|
background: rgba(74, 55, 40, 0.15);
|
flex-shrink: 0;
|
}
|
|
.pk_search_bar_input {
|
flex: 1;
|
min-width: 0;
|
height: 24px;
|
font-size: 14px;
|
color: $brown;
|
background: transparent;
|
border: none;
|
outline: none;
|
}
|
|
.pk_search_placeholder {
|
color: rgba(74, 55, 40, 0.38);
|
font-size: 14px;
|
}
|
|
.pk_search_table_head {
|
display: grid;
|
grid-template-columns: 1fr auto;
|
gap: 12px;
|
padding: 8px 14px;
|
margin-bottom: 6px;
|
border-radius: 10px;
|
background: rgba(74, 55, 40, 0.08);
|
flex-shrink: 0;
|
|
.col {
|
font-size: 12px;
|
font-weight: 600;
|
color: $brown;
|
opacity: 0.85;
|
}
|
|
.col_price {
|
text-align: right;
|
min-width: 72px;
|
}
|
}
|
|
.pk_search_list {
|
flex: 1;
|
min-height: 0;
|
max-height: 320px;
|
overflow-y: auto;
|
border-radius: 12px;
|
background: #fff;
|
border: 1px solid rgba(74, 55, 40, 0.08);
|
box-shadow: 0 6px 18px rgba(74, 55, 40, 0.08);
|
|
&::-webkit-scrollbar {
|
width: 5px;
|
}
|
|
&::-webkit-scrollbar-thumb {
|
background: rgba(74, 55, 40, 0.28);
|
border-radius: 999px;
|
}
|
}
|
|
.pk_search_item {
|
display: grid;
|
grid-template-columns: 1fr auto;
|
gap: 12px;
|
align-items: center;
|
padding: 12px 14px;
|
cursor: pointer;
|
border-bottom: 1px solid rgba(74, 55, 40, 0.06);
|
transition: background 0.12s;
|
|
&:last-child {
|
border-bottom: none;
|
}
|
|
&:hover,
|
&--active {
|
background: rgba(255, 216, 138, 0.22);
|
}
|
}
|
|
.pk_search_item_name {
|
font-size: 14px;
|
color: $brown;
|
line-height: 1.35;
|
word-break: break-all;
|
}
|
|
.pk_search_item_price {
|
font-size: 13px;
|
font-weight: 600;
|
color: $orange;
|
min-width: 72px;
|
text-align: right;
|
flex-shrink: 0;
|
}
|
|
.pk_search_empty {
|
flex: 1;
|
min-height: 180px;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
border-radius: 12px;
|
background: rgba(255, 255, 255, 0.72);
|
border: 1px dashed rgba(74, 55, 40, 0.14);
|
|
text {
|
font-size: 14px;
|
color: rgba(74, 55, 40, 0.45);
|
}
|
}
|
|
.pk_search_footer {
|
margin-top: 10px;
|
text-align: center;
|
flex-shrink: 0;
|
|
text {
|
font-size: 12px;
|
color: rgba(74, 55, 40, 0.5);
|
}
|
}
|
|
/* ===== 首页 legacy 搜索 ===== */
|
.search--legacy {
|
position: fixed;
|
z-index: 1000;
|
top: 0;
|
left: 0;
|
width: 100vw;
|
height: 100vh;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
background: rgba(61, 46, 34, 0.48);
|
backdrop-filter: blur(4px);
|
padding: 24px 16px;
|
box-sizing: border-box;
|
|
.search_box {
|
width: 100%;
|
max-width: 660px;
|
height: auto;
|
display: flex;
|
flex-direction: column;
|
border-radius: 18px;
|
overflow: hidden;
|
box-shadow: 0 20px 48px rgba(61, 46, 34, 0.28);
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
.search_box_item_xl::-webkit-scrollbar {
|
width: 5px;
|
}
|
|
.search_box_item_xl::-webkit-scrollbar-thumb {
|
background: rgba(74, 55, 40, 0.28);
|
border-radius: 999px;
|
}
|
|
.search_box_item_xl {
|
width: 100%;
|
max-height: min(52vh, 360px);
|
display: flex;
|
flex-direction: column;
|
background: linear-gradient(180deg, #FFFBF5 0%, $panel-bg 100%);
|
border-radius: 0 0 18px 18px;
|
overflow: hidden;
|
}
|
|
.search_box_item_xl_head {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 10px 18px;
|
background: $brown;
|
color: #fff;
|
flex-shrink: 0;
|
}
|
|
.search_box_item_xl_head_label {
|
font-size: 12px;
|
font-weight: 600;
|
letter-spacing: 0.5px;
|
}
|
|
.search_box_item_xl_head_count {
|
font-size: 11px;
|
padding: 2px 8px;
|
border-radius: 999px;
|
background: rgba(255, 216, 138, 0.22);
|
color: $gold;
|
font-weight: 600;
|
}
|
|
.search_box_item_xl_body {
|
flex: 1;
|
min-height: 0;
|
overflow-y: auto;
|
}
|
|
.search_box_item_xl_item {
|
width: 100%;
|
min-height: 44px;
|
padding: 0 18px;
|
cursor: pointer;
|
box-sizing: border-box;
|
display: flex;
|
align-items: center;
|
gap: 12px;
|
border-bottom: 1px solid rgba(74, 55, 40, 0.06);
|
transition: background 0.12s;
|
|
&:last-child {
|
border-bottom: none;
|
}
|
|
&:hover {
|
background: rgba(255, 216, 138, 0.22);
|
}
|
|
.active {
|
color: $orange !important;
|
font-weight: 600;
|
}
|
|
.search_box_item_xl_item_name {
|
flex: 1;
|
min-width: 0;
|
height: 100%;
|
display: flex;
|
align-items: center;
|
overflow: hidden;
|
white-space: nowrap;
|
text-overflow: ellipsis;
|
font-size: 14px;
|
color: $brown;
|
}
|
|
.search_box_item_xl_price {
|
flex-shrink: 0;
|
font-size: 13px;
|
font-weight: 600;
|
color: $orange;
|
}
|
}
|
|
.search_box_item {
|
width: 100%;
|
height: 72px;
|
background: $brown;
|
border-radius: 0;
|
display: flex;
|
align-items: center;
|
padding: 0 24px;
|
box-sizing: border-box;
|
margin-bottom: 0;
|
flex-shrink: 0;
|
|
.search_box_item_right {
|
display: flex;
|
align-items: center;
|
flex: 1;
|
min-width: 0;
|
|
text {
|
flex-shrink: 0;
|
font-size: 15px;
|
color: $gold;
|
margin-right: 10px;
|
font-weight: 500;
|
}
|
|
input,
|
.search_box_item_right_ipt {
|
flex: 1;
|
min-width: 0;
|
height: 100%;
|
font-size: 15px;
|
color: #FFFFFF;
|
background: transparent;
|
border: none;
|
outline: none;
|
}
|
}
|
|
.icon {
|
width: 20px;
|
height: 20px;
|
flex-shrink: 0;
|
margin-right: 14px;
|
filter: brightness(0) invert(1);
|
opacity: 0.9;
|
|
image {
|
width: 100%;
|
height: 100%;
|
}
|
}
|
|
.placeholder {
|
color: rgba(255, 255, 255, 0.45);
|
font-size: 15px;
|
}
|
}
|
}
|
}
|
</style>
|