consumer模块完成度95%,优化安卓端界面和小程序测试

This commit is contained in:
cyh666666
2026-03-11 17:17:32 +08:00
parent 5517c93666
commit 77f9968d18
622 changed files with 3100 additions and 1995 deletions

View File

@@ -48,13 +48,10 @@
</view>
</view>
<!-- 主内容区域 -->
<scroll-view
<!-- 主内容区域:改为普通 view由页面整体滚动 -->
<view
v-else
direction="vertical"
class="main-content"
:style="{ height: scrollHeight + 'px' }"
@scrolltolower="loadMore"
class="main-content"
>
<!-- 初始状态(无搜索词) -->
<view v-if="searchKeyword == '' && showResults == false">
@@ -233,12 +230,13 @@
<!-- 底部安全区域 -->
<view class="safe-area"></view>
</scroll-view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, reactive, onMounted, computed } from 'vue'
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
import { supabaseService } from '@/utils/supabaseService.uts'
import type { Product } from '@/utils/supabaseService.uts'
@@ -251,6 +249,7 @@ const loading = ref(false)
const hasMore = ref(true)
const isError = ref(false) // 错误状态控制
const autoFocus = ref(true)
const activeSort = ref('default') // 当前排序方式: default, sales, price
const priceSortAsc = ref(false) // 价格排序是否为升序
@@ -474,6 +473,8 @@ const performSearch = async (): Promise<void> => {
return
}
console.log('Search execution started for keyword:', keyword)
let sortBy = 'sales'
let ascending = false
if (activeSort.value === 'price') {
@@ -484,7 +485,9 @@ const performSearch = async (): Promise<void> => {
}
try {
console.log('Calling searchProducts with params:', keyword, currentPage.value, sortBy, ascending)
const prodResp = await supabaseService.searchProducts(keyword, currentPage.value, 20, sortBy, ascending)
console.log('searchProducts response received:', prodResp.data != null ? prodResp.data.length : 0, 'items')
let shopList: Array<ShopResultType> = []
if (currentPage.value === 1 && activeSort.value === 'default') {
@@ -539,7 +542,7 @@ const performSearch = async (): Promise<void> => {
hasMore.value = prodResp.hasmore
} catch(e) {
console.error('Search failed', e)
console.error('Search failed detailed error:', e)
} finally {
loading.value = false
}
@@ -691,19 +694,18 @@ const loadMore = async (): Promise<void> => {
} else if (activeSort.value === 'default') {
sortBy = 'default'
}
try {
const response = await supabaseService.searchProducts(keyword, currentPage.value, 20, sortBy, ascending)
const respData = response.data != null ? response.data : []
for (let i: number = 0; i < respData.length; i++) {
const p = respData[i] as UTSJSONObject
const p = respData[i] as Product
let tag = ''
const tagsRaw = p.get('tags')
const tagsRaw = p.tags
if (tagsRaw != null) {
try {
const tagsStr = p.getString('tags')
const tagsStr = p.tags
if (tagsStr != null) {
const tags = JSON.parse(tagsStr)
const tags = JSON.parse(tagsStr as string)
if (Array.isArray(tags) && tags.length > 0) {
const firstTag = tags[0]
tag = firstTag != null ? (firstTag as string) : ''
@@ -713,14 +715,14 @@ const loadMore = async (): Promise<void> => {
}
const searchItem: SearchResultType = {
id: p.getString('id') ?? '',
name: p.getString('name') ?? '',
image: p.getString('main_image_url') ?? '/static/default.jpg',
price: p.getNumber('base_price') ?? 0,
specification: p.getString('specification') ?? '标准规格',
id: p.id ?? '',
name: p.name ?? '',
image: p.main_image_url ?? '/static/default.jpg',
price: p.base_price ?? 0,
specification: p.specification ?? '标准规格',
tag: tag,
sales: p.getNumber('sale_count') ?? 0,
merchant_id: p.getString('merchant_id') ?? ''
sales: p.sale_count ?? 0,
merchant_id: p.merchant_id ?? ''
}
searchResults.value.push(searchItem)
}
@@ -733,6 +735,12 @@ const loadMore = async (): Promise<void> => {
}
}
onReachBottom(() => {
if (showResults.value) {
loadMore()
}
})
const refreshGuessList = () => {
uni.showLoading({ title: '刷新中' })
setTimeout(() => {
@@ -835,6 +843,7 @@ const goBack = () => {
background-color: #f5f5f5;
display: flex;
flex-direction: column;
min-height: 100vh; /* 确保背景色覆盖全屏 */
}
/* 店铺搜索结果 */
@@ -913,6 +922,7 @@ const goBack = () => {
/* #ifdef APP-PLUS */
padding-top: 0; /* 在App端由style动态控制 */
/* #endif */
flex-shrink: 0; /* 禁止头部被压缩 */
}
.search-bar-container {
@@ -920,7 +930,7 @@ const goBack = () => {
flex-direction: row; /* UVUE 必须显式设置 row */
align-items: center;
padding: 10px 16px;
width: 100%; /* 确保占满宽度 */
box-sizing: border-box;
}
.back-btn {
@@ -932,6 +942,7 @@ const goBack = () => {
width: 32px; /* 固定宽度防止压缩 */
height: 32px;
margin-right: 12px;
flex-shrink: 0;
}
.back-icon {
@@ -1194,16 +1205,30 @@ const goBack = () => {
background: #fff;
border-radius: 8px;
overflow: hidden;
width: 48%;
width: 48%; /* 手机端 2列 */
margin-bottom: 12px;
}
/* 猜测列表响应式,参照 index.uvue 的 hot-products */
@media screen and (min-width: 769px) {
.guess-item {
width: 32%; /* 平板 3列 */
}
}
@media screen and (min-width: 1025px) {
.guess-item {
width: 23%; /* 电脑 4列 */
}
}
.guess-img {
width: 100%;
height: 170px;
border-radius: 8px;
margin-bottom: 8px;
background: #f5f5f5;
object-fit: cover;
}
.guess-name {
@@ -1272,110 +1297,86 @@ const goBack = () => {
color: #333;
}
/* 搜索结果 */
.search-results {
padding-bottom: 20px;
}
.results-header {
display: flex;
flex-direction: row; /* UVUE 显式设置 row */
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
flex-wrap: wrap; /* 允许换行以适应小屏 */
padding: 10px 12px;
background-color: #fff;
margin-bottom: 2px;
}
.results-title {
font-size: 15px;
font-weight: bold;
color: #333;
margin-right: 8px;
}
.filter-tabs {
display: flex;
flex-direction: row; /* UVUE 显式设置 row */
flex: 1; /* 自适应填充剩余空间 */
justify-content: flex-end; /* 靠右对齐 */
flex-direction: row;
align-items: center;
flex-wrap: wrap;
justify-content: flex-start;
}
.filter-tab {
font-size: 13px;
color: #666;
padding: 4px 8px; /* 增加点击区域 */
margin-left: 16px;
padding: 8px 12px;
border-radius: 20px;
border: 1px solid #e0e0e0;
transition: all 0.2s ease;
white-space: nowrap;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
margin-left: 8px;
}
.filter-tab.active {
color: #4CAF50;
font-weight: bold; /* REPLACED 500 */
background: #ff5000;
color: white;
border-color: #ff5000;
}
.filter-tab:hover {
background: #f5f5f5;
}
/* 搜索结果列表 */
.search-results {
padding-bottom: 20px;
width: 100%;
display: flex;
flex-direction: column;
align-items: flex-start; /* 核心修复:确保内容不居中缩进 */
}
.results-header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 10px 12px;
background-color: #fff;
margin-bottom: 2px;
width: 100%; /* 核心修复:确保标题栏撑满宽度 */
box-sizing: border-box;
}
.results-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 4px;
}
/* 响应式布局 */
/* 平板设备 (768px以上) */
@media screen and (min-width: 768px) {
.results-list {
padding: 0 16px;
}
.result-item {
width: 32%;
}
.guess-item {
width: 24%;
}
}
/* 桌面设备 (1024px以上) */
@media screen and (min-width: 1024px) {
.results-list {
padding: 0 24px;
max-width: 1200px;
margin: 0 auto;
}
.result-item {
width: 19%;
}
.guess-item {
width: 16%;
}
.product-image {
height: 160px;
}
.guess-grid {
max-width: 1200px;
margin: 0 auto;
}
.main-content {
max-width: 1200px;
margin: 0 auto;
}
}
/* 大屏幕 (1440px以上) */
@media screen and (min-width: 1440px) {
.result-item {
width: 16%;
}
.guess-item {
width: 12%;
}
justify-content: flex-start;
padding: 10px;
width: 100%;
box-sizing: border-box;
margin-top: 5px;
background-color: #fff; /* 为列表添加背景色 */
}
.result-item {
@@ -1384,16 +1385,43 @@ const goBack = () => {
background: #fff;
border-radius: 8px;
overflow: hidden;
width: 48%;
/* width: calc(50% - 20px); 手机端一行2个 */
width: 48%;
margin-bottom: 12px;
margin-right: 2%;
border: 1px solid #f0f0f0; /* 添加微弱边框增加层次感 */
}
/* 电脑端响应式覆盖 - 强制拉伸宽度 */
@media screen and (min-width: 1025px) {
.main-content {
width: 1200px; /* 改为固定宽度或更大百分比 */
max-width: 95%;
margin: 0 auto;
padding: 20px 32px;
}
.result-item {
width: 23%; /* 4列布局 */
margin-right: 2%;
}
}
/* 大桌面端 (1400px以上) */
@media screen and (min-width: 1400px) {
.result-item {
width: 23%; /* 保持一行4个或者根据需要调整为 18% (一行5个) */
}
}
.product-image {
width: 100%;
height: 170px;
border-radius: 8px;
margin-bottom: 8px;
background: #f5f5f5;
height: 170px; /* 与主页一致 */
/* aspect-ratio: 1 / 1; */
object-fit: cover;
background-color: #f5f5f5;
border-radius: 8px;
margin-bottom: 8px;
}
.product-name {