爱简收旧衣按件回收前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1374 lines
40 KiB

<template>
<view class="inspect-container">
<!-- 顶部导航栏 -->
<view class="nav-bar">
<view class="back" @tap="goBack">
<uni-icons type="left" size="20" color="#222" />
</view>
<text class="nav-title">步骤一数量确认</text>
<view class="nav-icons">
<uni-icons type="scan" size="24" color="#222" />
</view>
</view>
<view class="main-content">
<!-- 左侧分类导航 -->
<view class="category-nav">
<view v-for="(cat, idx) in categories" :key="cat.title"
:class="['category-item', { active: idx === currentCategory }]" @tap="switchCategory(idx)">
<text>{{ cat.title }}</text>
<view v-if="cat.badge" class="category-badge">{{ cat.badge }}</view>
</view>
</view>
<!-- 右侧商品卡片区 -->
<scroll-view class="goods-list" scroll-y @scrolltolower="loadMoreGoods">
<view v-for="(item, idx) in currentGoods" :key="item.id" class="goods-card">
<view class="goods-header">
<image :src="item.image" class="goods-img" />
<view class="goods-info">
<view class="goods-title-row">
<text class="goods-name">{{ item.name }}</text>
<text class="goods-price">¥ {{ item.price }} <text class="goods-unit">/{{item.unit}}</text></text>
</view>
<text class="goods-desc">{{ item.desc }}</text>
</view>
</view>
<view class="goods-row">
<text class="row-label">合格数量</text>
<view class="num-ctrl">
<button class="num-btn" @tap="changeNum(item, 'qualified', -1)">-</button>
<text class="num">{{ item.qualified }}</text>
<button
class="num-btn"
@tap="changeNum(item, 'qualified', 1)"
>+</button>
</view>
</view>
<view class="goods-row">
<text class="row-label">总金额</text>
<input class="amount-input" :value="getInspectPrice(item)" @input="updateInspectPrice(item, $event)" placeholder="请输入金额" :disabled="!item.qualified || item.qualified === 0" />
</view>
</view>
<view v-if="loadingMore" class="loading-more">加载中...</view>
<view v-else-if="finished" class="loading-more">没有更多了</view>
</scroll-view>
</view>
<!-- 底部操作按钮 -->
<view class="footer-btns">
<button class="btn-outline" @tap="goBack">返回订单详情</button>
<button class="btn-main" @tap="goNext">下一步</button>
</view>
<!-- 品牌索引弹窗 -->
<view v-if="showBrandPopup" class="brand-popup-mask">
<view class="brand-popup">
<view class="brand-popup-header">
<text class="brand-popup-close" @click="closeBrandPopup">关闭</text>
<text class="brand-popup-title">可回收的品牌</text>
</view>
<view class="brand-popup-search">
<input class="brand-search-input" v-model="brandSearch" placeholder="请输入要查询的内容" @input="onBrandSearchInput" />
</view>
<scroll-view class="brand-popup-list" scroll-y>
<view v-for="letter in brandIndexList" :key="letter" :id="'brand-letter-' + letter">
<view class="brand-letter" :style="letter === '#' ? 'color:red' : ''">{{letter}}</view>
<view v-for="brand in brandList.filter(b => b.letter === letter)" :key="brand.name" class="brand-item" @click="openBrandConfirm(brand)">
<image :src="brand.logo" class="brand-logo" mode="aspectFit" />
<text class="brand-name">{{brand.name}}</text>
</view>
</view>
</scroll-view>
</view>
</view>
<!-- 品牌确认弹窗 -->
<view v-if="showBrandConfirm" class="brand-confirm-mask" @click.self="closeBrandConfirm">
<view class="brand-confirm-popup">
<view class="brand-confirm-title">品牌确认提示</view>
<view class="brand-confirm-logo-wrap">
<image :src="brandConfirmInfo.logo" class="brand-confirm-logo" mode="aspectFit" />
</view>
<view class="brand-confirm-name">{{ brandConfirmInfo.name }}</view>
<view class="brand-confirm-desc">请确认所选品牌是否与实物品牌信息一致,否则将无法进行回收。</view>
<view class="brand-confirm-btn-row">
<button class="brand-confirm-btn retry" @click="closeBrandConfirm">重新选择</button>
<button class="brand-confirm-btn confirm" @click="confirmBrand">确认一致</button>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
statusBarHeight: 0,
currentCategory: 0,
orderId: '',
order: null, // 订单数据
currentGoods: [], // 当前显示的商品列表
inspectResult: {}, // 质检结果对象,按照新的数据格式
allProducts: {}, // { [categoryId]: [商品数组] }
allProductsPage: {}, // { [categoryId]: 当前已加载页码 }
allProductsTotal: {}, // { [categoryId]: 总数 }
pageSize: 10,
loadingMore: false,
finished: false,
// 品牌选择相关
showBrandPopup: false,
brandList: [],
brandSearch: '',
currentProductId: null,
pendingBrandIndex: null,
brandConfirmInfo: {},
showBrandConfirm: false,
searchTimer: null,
// brandIndexList 改为 computed
}
},
computed: {
categories() {
const list = getApp().globalData.pricePreviewList || []
console.log('categories计算 - pricePreviewList:', list.length)
// 显示所有分类,不再根据订单数据筛选
const allCategories = list.filter(item => item.pid === '0').sort((a, b) => a.sort - b.sort)
console.log('categories计算 - allCategories:', allCategories.length)
// 为每个分类计算数量
const categoriesWithCount = allCategories.map(category => {
const count = this.getCategoryItemCountDirect(category.id)
return {
...category,
badge: count > 0 ? count : null
}
})
// 新增不可回收和质量问题分类
const extra = [
{ id: 'unrecyclable', title: '不可回收', badge: this.getUnrecyclableCount() },
{ id: 'quality_issue', title: '质量问题', badge: this.getQualityIssueCount() }
]
const result = [...categoriesWithCount, ...extra]
console.log('categories计算 - 最终结果:', result.map(c => ({ id: c.id, title: c.title, badge: c.badge })))
return result
},
// brandIndexList 改为 computed
brandIndexList() {
// 动态生成品牌索引,包含所有有品牌的首字母和 #
const letters = new Set()
let hasSharp = false
this.brandList.forEach(b => {
if (b.letter && /^[A-Z]$/.test(b.letter)) {
letters.add(b.letter)
} else {
letters.add('#')
hasSharp = true
}
})
const arr = Array.from(letters).filter(l => l !== '#').sort()
if (hasSharp) arr.push('#')
console.log('brandIndexList for render:', arr)
// 如果brandList里有letter为#的品牌但arr没有#,强制返回['#']
if (this.brandList.some(b => b.letter === '#') && !arr.includes('#')) return ['#']
return arr
},
},
methods: {
initInspectResult() {
// 只初始化空的list
this.inspectResult = {
id: this.order ? this.order.id : '',
list: []
}
},
// 获取分类商品数量(直接方法,避免递归)
getCategoryItemCountDirect(categoryId) {
if (categoryId === 'unrecyclable') {
return this.getUnrecyclableCount()
}
if (categoryId === 'quality_issue') {
return this.getQualityIssueCount()
}
let totalCount = 0
if (this.inspectResult.list && this.inspectResult.list.length > 0) {
this.inspectResult.list.forEach(inspectItem => {
if (inspectItem.categoryId === categoryId) {
totalCount += inspectItem.qualifiedNum || 0
}
})
}
return totalCount
},
// 获取当前分类ID(避免递归)
getCurrentCategoryId() {
const list = getApp().globalData.pricePreviewList || []
const allCategories = list.filter(item => item.pid === '0').sort((a, b) => a.sort - b.sort)
const extra = [
{ id: 'unrecyclable', title: '不可回收' },
{ id: 'quality_issue', title: '质量问题' }
]
const allCategoriesWithExtra = [...allCategories, ...extra]
return allCategoriesWithExtra[this.currentCategory]?.id
},
// 获取分类商品数量(保持原有方法名兼容性)
getCategoryItemCount(categoryId) {
return this.getCategoryItemCountDirect(categoryId)
},
// 获取不可回收数量
getUnrecyclableCount() {
// 从inspectResult中获取不可回收的数量
const unrecyclableItem = this.inspectResult.list?.find(item => item.id === 'unrecyclable')
return unrecyclableItem ? unrecyclableItem.unrecyclable : 0
},
// 获取质量问题数量
getQualityIssueCount() {
// 从inspectResult中获取质量问题的数量
const qualityIssueItem = this.inspectResult.list?.find(item => item.id === 'quality_issue')
return qualityIssueItem ? qualityIssueItem.noQualifiedNum : 0
},
fetchGoodsList(categoryId, page = 1, callback) {
this.$api('getClassGoodsList', {
classId: categoryId,
pageNo: page,
pageSize: this.pageSize
}, res => {
if (res.code === 200 && res.result && Array.isArray(res.result.records)) {
const oldList = this.allProducts[categoryId] || []
const newList = page === 1 ? res.result.records : oldList.concat(res.result.records)
this.$set(this.allProducts, categoryId, newList)
this.$set(this.allProductsPage, categoryId, page)
this.$set(this.allProductsTotal, categoryId, res.result.total)
this.updateCurrentGoods()
}
if (callback) callback()
})
},
updateCurrentGoods() {
const currentCategoryId = this.categories[this.currentCategory]?.id
// 不可回收分类内容
if (currentCategoryId === 'unrecyclable') {
// 从inspectResult中获取不可回收的数量
const unrecyclableItem = this.inspectResult.list?.find(item => item.id === 'unrecyclable')
const unrecyclableCount = unrecyclableItem ? unrecyclableItem.unrecyclable : 0
this.currentGoods = [{
id: 'unrecyclable-1',
image: '/static/回收/衣物.png',
name: '不可回收品类',
price: '—',
desc: '允许脏破烂,160码以上',
qualified: unrecyclableCount,
amount: '',
originalNum: 0 // 不设置最大数量限制
}]
return
}
// 质量问题分类内容
if (currentCategoryId === 'quality_issue') {
// 从inspectResult中获取质量问题的数量
const qualityIssueItem = this.inspectResult.list?.find(item => item.id === 'quality_issue')
const qualityIssueCount = qualityIssueItem ? qualityIssueItem.noQualifiedNum : 0
this.currentGoods = [{
id: 'quality-issue-1',
image: '/static/回收/衣物.png',
name: '质量问题品类',
price: '—',
desc: '存在质量问题,无法正常回收',
qualified: qualityIssueCount,
amount: '',
originalNum: 0 // 不设置最大数量限制
}]
return
}
// 从API获取的商品数据
const categoryGoods = this.allProducts[currentCategoryId] || []
// 将API商品数据转换为质检页面格式,并合并inspectResult.list中已选状态(shopId和id双向查找)
const goodsList = categoryGoods.map((item, index) => {
// 从订单数据中查找对应的商品
const orderItem = this.getOrderItemByProductId(item.id)
let itemId = item.id
if (orderItem && orderItem.id) {
itemId = orderItem.id
}
const inspectItem = this.inspectResult.list?.find(listItem =>
listItem.shopId == item.id || listItem.shopId == itemId || listItem.id == item.id || listItem.id == itemId
)
return {
id: item.id,
image: item.image || '/static/回收/衣物.png',
name: item.name,
price: item.price || 0,
desc: item.service || '允许脏破烂,160码以上',
qualified: inspectItem ? inspectItem.qualifiedNum : 0,
amount: inspectItem ? inspectItem.price : '', // 只用inspectResult里的金额
originalNum: 0,
estimatedPrice: orderItem ? orderItem.estimatedPrice : 0,
originalId: item.id,
isPin: item.isPin || 'N',
orderItem: orderItem
}
})
this.currentGoods = goodsList
},
// 根据商品ID从订单数据中查找对应商品
getOrderItemByProductId(productId) {
if (!this.order || !this.order.commonOrderList) {
return null
}
// 支持id和shopId双向查找
return this.order.commonOrderList.find(item => item.id == productId || item.shopId == productId)
},
goBack() {
uni.navigateBack()
},
goNext() {
// 检测是否所有商品都已完成质检和填写价格
const validationResult = this.validateInspectData()
if (!validationResult.isValid) {
uni.showToast({
title: validationResult.message,
icon: 'none',
duration: 2000
})
return
}
// 构造传递给步骤二的完整数据
const resultData = {
inspectResult: this.inspectResult,
order: this.order // 同时传递订单信息
}
console.log('resultDataStr:', resultData)
const resultDataStr = encodeURIComponent(JSON.stringify(resultData))
uni.navigateTo({
url: `/pages/manager/inspect-result?resultData=${resultDataStr}`
})
},
validateInspectData() {
if (!this.inspectResult.list || this.inspectResult.list.length === 0) {
return {
isValid: false,
message: '没有质检数据'
}
}
for (const item of this.inspectResult.list) {
// 不可回收和质量问题不需要校验金额
if (item.id === 'unrecyclable' || item.id === 'quality_issue') {
continue
}
// 只判断是否填写了commonOrderList(即有质检结果)
if (!item.commonOrderList || item.commonOrderList.length === 0) {
return {
isValid: false,
message: '有商品未完成质检选择'
}
}
// 检查是否有空的testingStatus
const hasEmptyStatus = item.commonOrderList.some(commonItem =>
commonItem.testingStatus === '' || commonItem.testingStatus === null || commonItem.testingStatus === undefined
)
if (hasEmptyStatus) {
return {
isValid: false,
message: '有商品未完成质检选择'
}
}
// 检查总金额(price)是否填写(不可回收和质量问题不校验)
if (!item.price || item.price === 0 || item.price === '') {
return {
isValid: false,
message: '有商品未填写总金额'
}
}
}
return {
isValid: true,
message: ''
}
},
switchCategory(idx) {
this.currentCategory = idx
this.loadingMore = false
this.finished = false
const categoryId = this.categories[idx]?.id
if (categoryId === 'unrecyclable' || categoryId === 'quality_issue') {
// 不可回收和质量问题分类直接更新商品列表
this.updateCurrentGoods()
return
}
// 如果该分类的商品还没有加载,调用API获取
if (!this.allProducts[categoryId]) {
this.fetchGoodsList(categoryId, 1)
} else {
// 已有数据,直接更新显示
this.updateCurrentGoods()
}
},
changeNum(item, key, delta) {
if (key === 'qualified') {
const currentCategoryId = this.categories[this.currentCategory]?.id
// 处理不可回收和质量问题
if (item.id === 'unrecyclable-1' || item.id === 'unrecyclable') {
const newQualified = Math.max(0, (item.qualified || 0) + delta)
this.$set(item, 'qualified', newQualified)
this.updateInspectResult(item, 'qualified', delta, currentCategoryId)
this.$forceUpdate()
return
}
// 处理普通商品
const newQualified = Math.max(0, (item.qualified || 0) + delta)
this.$set(item, 'qualified', newQualified)
this.updateInspectResult(item, 'qualified', delta, currentCategoryId)
// 新增:如果数量为0,移除该商品对象(包括不可回收和质量问题)
if (newQualified === 0) {
this.removeInspectItem(item)
}
this.$forceUpdate()
console.log('更新后的inspectResult:', JSON.stringify(this.inspectResult, null, 2))
}
},
// 修改:移除商品对象方法,支持不可回收和质量问题
removeInspectItem(item) {
// 判断不可回收和质量问题
if (item.id === 'unrecyclable-1' || item.id === 'unrecyclable') {
const idx = this.inspectResult.list.findIndex(listItem => listItem.id === 'unrecyclable')
if (idx !== -1) {
this.inspectResult.list.splice(idx, 1)
}
return
}
if (item.id === 'quality-issue-1' || item.id === 'quality_issue') {
const idx = this.inspectResult.list.findIndex(listItem => listItem.id === 'quality_issue')
if (idx !== -1) {
this.inspectResult.list.splice(idx, 1)
}
return
}
let itemId = item.originalId || item.id
const orderItem = this.getOrderItemByProductId(itemId)
if (orderItem && orderItem.id) {
itemId = orderItem.id
}
// shopId 匹配
const idx = this.inspectResult.list.findIndex(listItem => listItem.shopId == (orderItem ? (orderItem.shopId || orderItem.id) : itemId))
if (idx !== -1) {
this.inspectResult.list.splice(idx, 1)
}
},
updateInspectResult(item, type, delta, currentCategoryId) {
// 处理不可回收分类
if (item.id === 'unrecyclable-1') {
let inspectItem = this.inspectResult.list.find(listItem => listItem.id === 'unrecyclable')
if (!inspectItem && delta > 0) {
inspectItem = {
id: 'unrecyclable',
price: 0,
qualifiedNum: 0,
noQualifiedNum: 0,
unrecyclable: 0, // 初始值为0
shopId: '',
pinId: '',
categoryId: '',
commonOrderList: [] // 初始为空数组
}
this.inspectResult.list.push(inspectItem)
}
if (!inspectItem) return
if (type === 'qualified' && delta > 0) {
inspectItem.unrecyclable++
// 增加一个commonOrderList对象
inspectItem.commonOrderList.push({
testingInstructions: '',
testingImages: '',
testingStatus: 2
})
} else if (type === 'qualified' && delta < 0) {
inspectItem.unrecyclable = Math.max(0, inspectItem.unrecyclable - 1)
// 减少一个commonOrderList对象
if (inspectItem.commonOrderList.length > 0) {
inspectItem.commonOrderList.pop()
}
// 新增:如果减到0,移除该对象
if (inspectItem.unrecyclable === 0) {
const idx = this.inspectResult.list.findIndex(listItem => listItem === inspectItem)
if (idx !== -1) {
this.inspectResult.list.splice(idx, 1)
}
return
}
}
console.log('不可回收对象:', inspectItem)
return
}
if (item.id === 'quality-issue-1') {
let inspectItem = this.inspectResult.list.find(listItem => listItem.id === 'quality_issue')
if (!inspectItem && delta > 0) {
inspectItem = {
id: 'quality_issue',
price: 0,
qualifiedNum: 0,
noQualifiedNum: 0, // 初始值为0
unrecyclable: 0,
shopId: '',
pinId: '',
categoryId: '',
commonOrderList: [] // 初始为空数组
}
this.inspectResult.list.push(inspectItem)
}
if (!inspectItem) return
if (type === 'qualified' && delta > 0) {
inspectItem.noQualifiedNum++
// 增加一个commonOrderList对象
inspectItem.commonOrderList.push({
testingInstructions: '',
testingImages: '',
testingStatus: 1
})
} else if (type === 'qualified' && delta < 0) {
inspectItem.noQualifiedNum = Math.max(0, inspectItem.noQualifiedNum - 1)
// 减少一个commonOrderList对象
if (inspectItem.commonOrderList.length > 0) {
inspectItem.commonOrderList.pop()
}
// 新增:如果减到0,移除该对象
if (inspectItem.noQualifiedNum === 0) {
const idx = this.inspectResult.list.findIndex(listItem => listItem === inspectItem)
if (idx !== -1) {
this.inspectResult.list.splice(idx, 1)
}
return
}
}
console.log('质量问题对象:', inspectItem)
return
}
let itemId = item.originalId || item.id
const orderItem = this.getOrderItemByProductId(itemId)
if (orderItem && orderItem.id) {
itemId = orderItem.id
}
let inspectItem = this.inspectResult.list.find(listItem => listItem.shopId == (orderItem ? (orderItem.shopId || orderItem.id) : itemId))
if (!inspectItem && delta > 0) {
inspectItem = {
price: 0,
qualifiedNum: 0,
noQualifiedNum: 0,
unrecyclable: 0,
shopId: orderItem ? (orderItem.shopId || orderItem.id) : itemId,
pinId: '',
categoryId: currentCategoryId || '', // 直接用当前分类id
commonOrderList: [
{
testingInstructions: '',
testingImages: '',
testingStatus: 0
}
]
}
this.inspectResult.list.push(inspectItem)
}
if (!inspectItem) return
if (type === 'qualified' && delta > 0) {
inspectItem.qualifiedNum++
} else if (type === 'qualified' && delta < 0) {
inspectItem.qualifiedNum = Math.max(0, inspectItem.qualifiedNum - 1)
// 新增:如果减到0,移除该商品对象
if (inspectItem.qualifiedNum === 0) {
const idx = this.inspectResult.list.findIndex(listItem => listItem === inspectItem)
if (idx !== -1) {
this.inspectResult.list.splice(idx, 1)
}
return
}
}
console.log('更新后的inspectResult:', JSON.stringify(this.inspectResult, null, 2))
},
getInspectPrice(item) {
// 优化:不可回收和质量问题通过id匹配
if (item.id === 'unrecyclable-1' || item.id === 'unrecyclable') {
const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'unrecyclable')
return inspectItem ? inspectItem.price : ''
}
if (item.id === 'quality-issue-1' || item.id === 'quality_issue') {
const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'quality_issue')
return inspectItem ? inspectItem.price : ''
}
// 普通商品
const inspectItem = this.inspectResult.list?.find(listItem => listItem.shopId == item.id)
return inspectItem ? inspectItem.price : ''
},
updateInspectPrice(item, event) {
// 优化:不可回收和质量问题通过id匹配
if (item.id === 'unrecyclable-1' || item.id === 'unrecyclable') {
const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'unrecyclable')
if (!inspectItem) return
inspectItem.price = parseFloat(event.detail.value) || 0
return
}
if (item.id === 'quality-issue-1' || item.id === 'quality_issue') {
const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'quality_issue')
if (!inspectItem) return
inspectItem.price = parseFloat(event.detail.value) || 0
return
}
// 普通商品
let itemId = item.originalId || item.id
const orderItem = this.getOrderItemByProductId(itemId)
if (orderItem && orderItem.id) {
itemId = orderItem.id // 使用订单中的商品ID
}
// 只查找,不新建
let inspectItem = this.inspectResult.list?.find(listItem => listItem.shopId == (orderItem ? (orderItem.shopId || orderItem.id) : itemId))
if (!inspectItem) return // 没有就不处理
const newPrice = parseFloat(event.detail.value) || 0
inspectItem.price = newPrice
console.log('更新价格:', itemId, newPrice)
console.log('当前商品对象:', inspectItem)
},
loadMoreGoods() {
const categoryId = this.categories[this.currentCategory]?.id
// 不可回收和质量问题分类不支持加载更多
if (categoryId === 'unrecyclable' || categoryId === 'quality_issue') {
return
}
const page = (this.allProductsPage[categoryId] || 1) + 1
const total = this.allProductsTotal[categoryId] || 0
const loaded = (this.allProducts[categoryId] || []).length
if (this.loadingMore || this.finished) return
if (loaded < total) {
this.loadingMore = true
this.fetchGoodsList(categoryId, page, () => {
this.loadingMore = false
// 判断是否加载完
const newLoaded = (this.allProducts[categoryId] || []).length
this.finished = newLoaded >= (this.allProductsTotal[categoryId] || 0)
})
} else {
this.finished = true
}
},
// 获取品牌列表
getGoodsBrandList(productId, searchName = '') {
this.currentProductId = productId
const params = { productId }
if (searchName.trim()) {
params.name = searchName.trim()
}
this.$api('getGoodsBrandList', params, res => {
if (res && res.success && res.result && res.result.records) {
// 保证响应式
const newList = res.result.records.map(item => {
// 获取品牌名称的拼音首字母
const firstChar = this.getPinyinFirstLetter(item.name)
return {
id: item.id,
logo: item.image || '/static/brand/alexander.png',
name: item.name,
letter: firstChar
}
})
// 打印所有品牌的name和letter
newList.forEach(b => console.log('品牌:', b.name, 'letter:', b.letter))
this.brandList = [...newList]
// 打印brandList和brandIndexList
this.$nextTick(() => {
console.log('brandList:', this.brandList)
console.log('brandIndexList:', this.brandIndexList)
})
}
})
},
// 获取中文拼音首字母
getPinyinFirstLetter(str) {
if (!str) return '#'
const firstChar = str.charAt(0)
// 只认A-Z,否则归为#
if (/^[A-Za-z]$/.test(firstChar)) {
return firstChar.toUpperCase()
}
return '#'
},
// 品牌搜索输入事件处理
onBrandSearchInput(e) {
const searchValue = e.detail.value
// 清除之前的定时器
if (this.searchTimer) {
clearTimeout(this.searchTimer)
}
// 设置防抖,500ms后执行搜索
this.searchTimer = setTimeout(() => {
if (this.currentProductId) {
this.getGoodsBrandList(this.currentProductId, searchValue)
}
}, 500)
},
// 打开品牌确认弹窗
openBrandConfirm(brand) {
this.brandConfirmInfo = {
id: brand.id,
logo: brand.logo,
name: brand.name
}
this.showBrandConfirm = true
},
// 关闭品牌确认弹窗
closeBrandConfirm() {
this.showBrandConfirm = false
},
// 确认品牌选择
confirmBrand() {
this.showBrandConfirm = false
this.showBrandPopup = false
// 确认后增加商品数量
if (this.pendingBrandIndex !== null) {
const item = this.currentGoods[this.pendingBrandIndex]
if (item) {
const newQualified = Math.max(0, (item.qualified || 0) + 1)
this.$set(item, 'qualified', newQualified)
this.updateInspectResult(item, 'qualified', 1, this.categories[this.currentCategory]?.id)
// 强制更新categories计算属性,使左侧分类数字变化
this.$forceUpdate()
}
this.pendingBrandIndex = null
}
},
// 关闭品牌弹窗
closeBrandPopup() {
this.showBrandPopup = false
this.pendingBrandIndex = null
this.brandSearch = ''
this.currentProductId = null
},
},
created() {
this.currentCategory = 0
},
onLoad(options) {
// 接收订单数据
if (options && options.orderData) {
try {
this.order = JSON.parse(decodeURIComponent(options.orderData))
console.log('接收到的订单数据:', this.order)
// 订单数据加载完成后初始化质检结果
this.$nextTick(() => {
this.initInspectResult()
})
} catch (error) {
console.error('解析订单数据失败:', error)
}
}
if (options && options.orderId) {
this.orderId = options.orderId
}
// 初始化加载第一个分类的商品
this.$nextTick(() => {
// 确保categories已经计算完成
if (this.categories.length > 0) {
const firstCategoryId = this.categories[0]?.id
console.log('第一个分类ID:', firstCategoryId, '所有分类:', this.categories.map(c => c.id))
if (firstCategoryId && firstCategoryId !== 'unrecyclable' && firstCategoryId !== 'quality_issue') {
this.fetchGoodsList(firstCategoryId, 1)
} else if (firstCategoryId === 'unrecyclable' || firstCategoryId === 'quality_issue') {
this.updateCurrentGoods()
}
} else {
console.log('categories为空,等待数据加载')
// 如果categories为空,等待一下再尝试
setTimeout(() => {
if (this.categories.length > 0) {
const firstCategoryId = this.categories[0]?.id
if (firstCategoryId && firstCategoryId !== 'unrecyclable' && firstCategoryId !== 'quality_issue') {
this.fetchGoodsList(firstCategoryId, 1)
} else if (firstCategoryId === 'unrecyclable' || firstCategoryId === 'quality_issue') {
this.updateCurrentGoods()
}
}
}, 500)
}
})
console.log(this.orderId, 'orderId')
},
onShow() {
// 确保在页面显示时categories已经正确计算
console.log('onShow - categories:', this.categories.map(c => ({ id: c.id, title: c.title, badge: c.badge })))
// 强制更新视图,确保所有分类都显示
this.$nextTick(() => {
console.log('分类导航应该显示的分类数量:', this.categories.length)
this.categories.forEach((cat, index) => {
console.log(`分类 ${index}: ${cat.title} (${cat.id})`)
})
})
},
}
</script>
<style lang="scss" scoped>
.inspect-container {
min-height: 100vh;
background: #f8f8f8;
display: flex;
flex-direction: column;
}
.nav-bar {
display: flex;
align-items: center;
height: calc(150rpx + var(--status-bar-height));
padding: 0 32rpx;
padding-top: var(--status-bar-height);
background: #fff;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
box-sizing: border-box;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
.back {
padding: 20rpx;
margin-left: -20rpx;
}
.nav-title {
flex: 1;
text-align: center;
font-size: 32rpx;
font-weight: 500;
color: #222;
}
.nav-icons {
display: flex;
align-items: center;
gap: 12px;
}
}
.main-content {
margin-top: calc(200rpx + var(--status-bar-height));
display: flex;
background: none;
height: calc(100vh - 200rpx - var(--status-bar-height));
min-height: calc(100vh - 200rpx - var(--status-bar-height));
}
.category-nav {
width: 80px;
background: #fff;
border-radius: 24px 0 0 24px;
// padding: 24px 0;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
height: calc(100vh - 200rpx - var(--status-bar-height) - 80px);
max-height: calc(100vh - 200rpx - var(--status-bar-height) - 80px);
overflow-y: scroll;
overflow-x: hidden;
position: relative;
z-index: 2;
-webkit-overflow-scrolling: touch;
scrollbar-width: thin;
scrollbar-color: #ddd transparent;
&::-webkit-scrollbar {
width: 4px;
}
&::-webkit-scrollbar-track {
background: transparent;
}
&::-webkit-scrollbar-thumb {
background: #ddd;
border-radius: 2px;
}
&::-webkit-scrollbar-thumb:hover {
background: #ccc;
}
.category-item {
width: 64px;
height: 44px;
border-radius: 16px 0 0 16px;
display: flex;
align-items: center;
justify-content: flex-start;
font-size: 16px;
color: #222;
margin-bottom: 12px;
background: #fff;
position: relative;
transition: background 0.2s, color 0.2s, font-weight 0.2s;
padding-left: 12px;
&.active {
background: linear-gradient(90deg, #fff7e6 80%, #fff 100%);
color: #ffb400;
font-weight: bold;
&::before {
content: '';
position: absolute;
left: 0;
top: 30%;
height: 40%;
width: 2px;
border-radius: 4px;
background: #ffb400;
bottom: auto;
}
}
.category-badge {
position: absolute;
top: 6px;
right: 10px;
background: #ff4d4f;
color: #fff;
font-size: 12px;
border-radius: 50%;
width: 18px;
height: 18px;
display: flex;
align-items: center;
justify-content: center;
}
}
}
.goods-list {
flex: 1;
height: calc(100vh - 200rpx - var(--status-bar-height) - 80px);
padding: 0 0 0 16px;
overflow-y: auto;
background: none;
}
.goods-card {
background: #fff;
border-radius: 24px;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06);
margin-bottom: 18px;
padding: 18px 18px 9px 18px;
}
.goods-header {
display: flex;
align-items: center;
margin-bottom: 12px;
.goods-img {
width: 56px;
height: 56px;
border-radius: 16px;
margin-right: 12px;
background: #f8f8f8;
object-fit: contain;
}
.goods-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
min-width: 0;
.goods-title-row {
display: flex;
align-items: baseline;
.goods-name {
font-size: 16px;
font-weight: bold;
color: #222;
margin-right: 8px;
}
.goods-price {
font-size: 15px;
color: #ffb400;
font-weight: bold;
.goods-unit {
font-size: 13px;
color: #bbb;
}
}
}
.goods-desc {
font-size: 13px;
color: #999;
margin-top: 4px;
}
}
}
.goods-row {
display: flex;
align-items: center;
margin-bottom: 12px;
.row-label {
font-size: 14px;
color: #888;
width: 80px;
flex-shrink: 0;
}
.num-ctrl {
display: flex;
align-items: center;
.num-btn {
width: 60rpx;
height: 60rpx;
padding: 0;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #666;
background: #ffffff;
border: none;
border-radius: 50%;
&::after {
border: none;
}
&:active {
opacity: 0.8;
}
}
.num {
width: 80rpx;
text-align: center;
font-size: 32rpx;
color: #333;
}
}
.amount-input {
flex: 1;
height: 32px;
border-radius: 12px;
background: #f6f6f6;
border: none;
font-size: 15px;
color: #222;
padding-left: 10px;
margin-left: 8px;
}
}
.footer-btns {
position: fixed;
left: 0;
right: 0;
bottom: 0;
background: #fff;
display: flex;
gap: 16px;
padding: 12px 16px 24px 16px;
z-index: 101;
.btn-outline {
flex: 1;
height: 40px;
border-radius: 16px;
border: 1px solid #ffe09a;
color: #ffb400;
background: #fff0d2;
font-size: 15px;
font-weight: 500;
box-shadow: none;
padding: 0 18px;
}
.btn-main {
flex: 1;
height: 40px;
border-radius: 16px;
background: linear-gradient(90deg, #ffd01e 0%, #ffac04 100%);
color: #fff;
border: none;
font-size: 15px;
font-weight: 500;
box-shadow: none;
padding: 0 18px;
}
}
.loading-more {
text-align: center;
color: #999;
padding: 20rpx 0;
font-size: 26rpx;
}
// 品牌选择弹窗样式
.brand-popup-mask {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(0,0,0,0.35);
z-index: 3000;
display: flex;
align-items: flex-end;
justify-content: center;
}
.brand-popup {
position: relative;
width: 100%;
max-width: 750px;
background: #fff;
border-radius: 32rpx 32rpx 0 0;
box-shadow: 0 -4rpx 24rpx rgba(0,0,0,0.08);
padding-bottom: 40rpx;
max-height: 90vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
.brand-popup-header {
display: flex;
align-items: center;
justify-content: center;
padding: 32rpx 24rpx 0 24rpx;
font-size: 32rpx;
font-weight: bold;
position: relative;
}
.brand-popup-close {
position: absolute;
left: 24rpx;
font-size: 28rpx;
color: #888;
}
.brand-popup-title {
font-size: 32rpx;
color: #222;
font-weight: bold;
}
.brand-popup-search {
padding: 20rpx 24rpx 0 24rpx;
}
.brand-search-input {
width: 100%;
height: 60rpx;
border-radius: 30rpx;
background: #f5f5f5;
border: none;
padding-left: 40rpx;
font-size: 28rpx;
color: #888;
}
.brand-popup-list {
flex: 1;
overflow-y: auto;
max-height: 60vh;
padding: 0 24rpx;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE and Edge */
&::-webkit-scrollbar {
width: 0 !important;
display: none; /* Chrome, Safari, Opera */
}
}
.brand-letter {
font-size: 28rpx;
color: #888;
margin: 24rpx 0 8rpx 0;
font-weight: bold;
}
.brand-item {
display: flex;
align-items: center;
padding: 16rpx 0;
border-bottom: 1px solid #f0f0f0;
}
.brand-logo {
width: 60rpx;
height: 60rpx;
margin-right: 20rpx;
border-radius: 8rpx;
background: #f8f8f8;
}
.brand-name {
font-size: 28rpx;
color: #222;
}
// 品牌确认弹窗样式
.brand-confirm-mask {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(0,0,0,0.25);
z-index: 5001;
display: flex;
align-items: center;
justify-content: center;
}
.brand-confirm-popup {
width: 70vw;
max-width: 270px;
background: #fff;
border-radius: 32rpx;
box-shadow: 0 8rpx 32rpx rgba(0,0,0,0.12);
display: flex;
flex-direction: column;
align-items: center;
padding: 48rpx 20rpx 36rpx 20rpx;
position: relative;
}
.brand-confirm-title {
font-size: 36rpx;
color: #222;
font-weight: bold;
text-align: center;
margin-bottom: 24rpx;
}
.brand-confirm-logo-wrap {
width: 120rpx;
height: 120rpx;
background: #f8f8f8;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 18rpx;
}
.brand-confirm-logo {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
}
.brand-confirm-name {
font-size: 28rpx;
color: #222;
font-weight: bold;
text-align: center;
margin-bottom: 16rpx;
}
.brand-confirm-desc {
font-size: 24rpx;
color: #999;
text-align: center;
margin-bottom: 32rpx;
line-height: 1.6;
}
.brand-confirm-btn-row {
width: 100%;
display: flex;
justify-content: space-between;
gap: 24rpx;
}
.brand-confirm-btn {
flex: 1;
height: 72rpx;
border-radius: 36rpx;
font-size: 28rpx;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
border: none;
margin: 0 0;
}
.brand-confirm-btn.retry {
background: #fff;
color: #ff9c00;
border: 2rpx solid #ff9c00;
}
.brand-confirm-btn.confirm {
background: linear-gradient(to right, #ffd01e, #ff8917);
color: #fff;
border: none;
}
</style>