前端-胡立永 3 months ago
parent
commit
bd78bf59bb
8 changed files with 691 additions and 182 deletions
  1. +79
    -2
      pages/manager/inspect-result.vue
  2. +45
    -5
      pages/manager/inspect.vue
  3. +5
    -0
      pages/manager/order.vue
  4. +30
    -6
      pages/subcomponent/detail.vue
  5. +348
    -109
      pages/subcomponent/inspection-detail.vue
  6. +2
    -4
      pages/subcomponent/inspection-report.vue
  7. +3
    -1
      pages/subcomponent/order.vue
  8. +179
    -55
      pages/wxUserInfo.vue

+ 79
- 2
pages/manager/inspect-result.vue View File

@ -26,6 +26,7 @@
<text class="price-label">总金额</text> <text class="price-label">总金额</text>
<input class="price-input" v-model="item.total" type="digit" placeholder="请输入金额" /> <input class="price-input" v-model="item.total" type="digit" placeholder="请输入金额" />
</view> </view>
<!-- 选择理由模块 --> <!-- 选择理由模块 -->
<view v-if="item.items && item.items.length > 0"> <view v-if="item.items && item.items.length > 0">
<view v-for="(commonItem, itemIndex) in item.items" :key="commonItem.id || itemIndex" class="row-reason"> <view v-for="(commonItem, itemIndex) in item.items" :key="commonItem.id || itemIndex" class="row-reason">
@ -147,6 +148,16 @@
<text class="section-label">自定义理由</text> <text class="section-label">自定义理由</text>
<textarea class="custom-reason-input" v-model="customReason" placeholder="请输入自定义理由..." maxlength="200" /> <textarea class="custom-reason-input" v-model="customReason" placeholder="请输入自定义理由..." maxlength="200" />
</view> </view>
<view class="popup-section">
<text class="section-label">质检级别</text>
<view class="level-options">
<view v-for="level in ['S', 'A', 'B', 'C']" :key="level"
:class="['level-option', { 'selected': currentQualityLevel === level }]"
@tap="selectQualityLevel(level)">
<text class="level-text">{{ level }}</text>
</view>
</view>
</view>
<view class="popup-section"> <view class="popup-section">
<text class="section-label">选择理由</text> <text class="section-label">选择理由</text>
<view v-for="(item, index) in reasonOptions" :key="item.id" class="reason-row" @tap="toggleReason(index)"> <view v-for="(item, index) in reasonOptions" :key="item.id" class="reason-row" @tap="toggleReason(index)">
@ -182,6 +193,7 @@ export default {
reasonChecked: [], reasonChecked: [],
customReason: '', // customReason: '', //
currentReasonItem: null, currentReasonItem: null,
currentQualityLevel: '', //
isPopupOpen: false, // isPopupOpen: false, //
scrollTop: 0 // scrollTop: 0 //
} }
@ -251,6 +263,7 @@ export default {
pinId: item.pinId || '', pinId: item.pinId || '',
styleId: item.styleId || '', styleId: item.styleId || '',
uniqueKey: uniqueKey, uniqueKey: uniqueKey,
qualityLevel: item.qualityLevel || '', //
originalItem: item, // originalItem: item, //
items: item.commonOrderList ? [...item.commonOrderList] : [{ items: item.commonOrderList ? [...item.commonOrderList] : [{
testingInstructions: '', testingInstructions: '',
@ -409,6 +422,8 @@ export default {
} else { } else {
this.reasonImages = [] this.reasonImages = []
} }
//
this.currentQualityLevel = popupItem.qualityLevel || ''
// reasonChecked // reasonChecked
this.selectReasonForUnqualified(popupItem, type) this.selectReasonForUnqualified(popupItem, type)
this.lockScroll() this.lockScroll()
@ -423,6 +438,8 @@ export default {
} else { } else {
this.reasonImages = [] this.reasonImages = []
} }
//
this.currentQualityLevel = commonItem.qualityLevel || ''
// 使categoryId // 使categoryId
this.selectReasonForUnqualified(commonItem, 0, parentItem.classId) this.selectReasonForUnqualified(commonItem, 0, parentItem.classId)
this.lockScroll() this.lockScroll()
@ -588,6 +605,7 @@ export default {
// //
this.currentReasonItem.testingInstructions = allReasons.join(',') this.currentReasonItem.testingInstructions = allReasons.join(',')
this.currentReasonItem.testingImages = this.reasonImages.join(',') this.currentReasonItem.testingImages = this.reasonImages.join(',')
this.currentReasonItem.qualityLevel = this.currentQualityLevel
} }
this.closeReasonPopup() this.closeReasonPopup()
}, },
@ -669,6 +687,11 @@ export default {
} }
}, },
selectQualityLevel(level) {
//
this.currentQualityLevel = level
},
syncPriceToInspectData() { syncPriceToInspectData() {
// - // -
this.qualifiedList.forEach(qualifiedItem => { this.qualifiedList.forEach(qualifiedItem => {
@ -687,6 +710,9 @@ export default {
if (inspectItem) { if (inspectItem) {
inspectItem.price = parseFloat(qualifiedItem.total) || 0 inspectItem.price = parseFloat(qualifiedItem.total) || 0
// - items
const itemWithLevel = qualifiedItem.items && qualifiedItem.items.find(item => item.qualityLevel)
inspectItem.qualityLevel = itemWithLevel ? itemWithLevel.qualityLevel : (qualifiedItem.qualityLevel || '')
// //
if (qualifiedItem.items && qualifiedItem.items.length > 0) { if (qualifiedItem.items && qualifiedItem.items.length > 0) {
inspectItem.commonOrderList = qualifiedItem.items inspectItem.commonOrderList = qualifiedItem.items
@ -694,19 +720,33 @@ export default {
} }
}) })
//
//
this.unqualifiedGroups.forEach(group => { this.unqualifiedGroups.forEach(group => {
const inspectItem = this.inspectData.list.find(item => item.id === 'quality_issue') const inspectItem = this.inspectData.list.find(item => item.id === 'quality_issue')
if (inspectItem) { if (inspectItem) {
inspectItem.price = parseFloat(group.total) || 0 inspectItem.price = parseFloat(group.total) || 0
//
if (inspectItem.commonOrderList && inspectItem.commonOrderList.length > 0) {
const itemWithLevel = inspectItem.commonOrderList.find(item => item.qualityLevel)
if (itemWithLevel) {
inspectItem.qualityLevel = itemWithLevel.qualityLevel
}
}
} }
}) })
//
//
this.unrecyclableList.forEach(unrecyclableItem => { this.unrecyclableList.forEach(unrecyclableItem => {
const inspectItem = this.inspectData.list.find(item => item.id === 'unrecyclable') const inspectItem = this.inspectData.list.find(item => item.id === 'unrecyclable')
if (inspectItem) { if (inspectItem) {
inspectItem.price = parseFloat(unrecyclableItem.total) || 0 inspectItem.price = parseFloat(unrecyclableItem.total) || 0
//
if (inspectItem.commonOrderList && inspectItem.commonOrderList.length > 0) {
const itemWithLevel = inspectItem.commonOrderList.find(item => item.qualityLevel)
if (itemWithLevel) {
inspectItem.qualityLevel = itemWithLevel.qualityLevel
}
}
} }
}) })
} }
@ -882,6 +922,8 @@ export default {
} }
} }
.row-reason { .row-reason {
display: flex; display: flex;
align-items: center; align-items: center;
@ -1057,6 +1099,41 @@ export default {
font-weight: 500; font-weight: 500;
} }
.level-options {
display: flex;
gap: 12px;
margin-bottom: 16px;
.level-option {
width: 40px;
height: 40px;
border-radius: 8px;
border: 2px solid #ddd;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
cursor: pointer;
transition: all 0.2s;
&.selected {
border-color: #ffb400;
background: #ffb400;
.level-text {
color: #fff;
font-weight: bold;
}
}
.level-text {
font-size: 16px;
color: #666;
font-weight: 500;
}
}
}
.custom-reason-input { .custom-reason-input {
width: 100%; width: 100%;
min-height: 80px; min-height: 80px;


+ 45
- 5
pages/manager/inspect.vue View File

@ -23,7 +23,11 @@
<scroll-view class="goods-list" scroll-y @scrolltolower="loadMoreGoods"> <scroll-view class="goods-list" scroll-y @scrolltolower="loadMoreGoods">
<view v-for="(item, idx) in currentGoods" :key="item.id" class="goods-card"> <view v-for="(item, idx) in currentGoods" :key="item.id" class="goods-card">
<view class="goods-header"> <view class="goods-header">
<image :src="item.image" class="goods-img" />
<view class="goods-img-container">
<image :src="item.image" class="goods-img" />
<!-- 品牌标签 -->
<view class="brand-tag" v-if="item.isPin === 'Y'">品牌</view>
</view>
<view class="goods-info"> <view class="goods-info">
<view class="goods-title-row"> <view class="goods-title-row">
<text class="goods-name">{{ item.name }}</text> <text class="goods-name">{{ item.name }}</text>
@ -573,13 +577,30 @@ export default {
} }
} }
//
if (item.isPin === 'Y' && delta > 0) {
// 0
if (item.isPin === 'Y' && (this.getItemTotalQuantity(item) === 0) && delta > 0) {
this.pendingBrandIndex = index this.pendingBrandIndex = index
this.$refs.brandSelector.open(item.id) this.$refs.brandSelector.open(item.id)
return return
} }
//
if (item.isPin === 'Y' && this.getItemTotalQuantity(item) > 0 && delta > 0) {
//
if (item.brandStyleQuantities && Object.keys(item.brandStyleQuantities).length === 1) {
const uniqueKey = Object.keys(item.brandStyleQuantities)[0]
const currentQty = item.brandStyleQuantities[uniqueKey] || 0
this.$set(item.brandStyleQuantities, uniqueKey, currentQty + delta)
this.updateInspectResultFromBrandStyle(item)
return
} else {
//
this.pendingBrandIndex = index
this.$refs.brandSelector.open(item.id)
return
}
}
// //
if (item.isPin !== 'Y') { if (item.isPin !== 'Y') {
let newQuantity = (item.quantity || 0) + delta let newQuantity = (item.quantity || 0) + delta
@ -1258,15 +1279,34 @@ export default {
align-items: center; align-items: center;
margin-bottom: 24rpx; margin-bottom: 24rpx;
.goods-img {
.goods-img-container {
position: relative;
width: 112rpx; width: 112rpx;
height: 112rpx; height: 112rpx;
border-radius: 32rpx;
margin-right: 24rpx; margin-right: 24rpx;
flex-shrink: 0;
}
.goods-img {
width: 100%;
height: 100%;
border-radius: 32rpx;
background: #f8f8f8; background: #f8f8f8;
object-fit: contain; object-fit: contain;
} }
.brand-tag {
position: absolute;
top: 0rpx;
left: 0rpx;
background: rgba(0, 0, 0, 0.8);
color: #fff;
font-size: 20rpx;
padding: 4rpx 8rpx;
border-radius: 8rpx;
z-index: 2;
}
.goods-info { .goods-info {
flex: 1; flex: 1;
display: flex; display: flex;


+ 5
- 0
pages/manager/order.vue View File

@ -366,6 +366,11 @@
label: '已驳回', label: '已驳回',
class: 'red' class: 'red'
} }
} else if (state === 5) {
return {
label: '已退款',
class: 'gray'
}
} else if (state === 3) { } else if (state === 3) {
return { return {
label: '已取消', label: '已取消',


+ 30
- 6
pages/subcomponent/detail.vue View File

@ -135,11 +135,10 @@
<!-- 质检结果卡片仅结款状态显示 --> <!-- 质检结果卡片仅结款状态显示 -->
<view class="order-detail-card" v-if="status === 3"> <view class="order-detail-card" v-if="status === 3">
<text class="order-title">质检结果</text> <text class="order-title">质检结果</text>
<view class="order-row"><text class="order-label">质检数量</text><text class="order-value">9 </text></view>
<view class="order-row"><text class="order-label">质检合格</text><text class="order-value">7 </text></view>
<view class="order-row"><text class="order-label">质量问题</text><text class="order-value">2 </text></view>
<view class="order-row"><text class="order-label">不可回收</text><text class="order-value">0 </text></view>
<view class="order-row"><text class="order-label">订单重量</text><text class="order-value">2.85 kg</text></view>
<view class="order-row"><text class="order-label">质检数量</text><text class="order-value">{{ totalInspectCount }} </text></view>
<view class="order-row"><text class="order-label">质检合格</text><text class="order-value">{{ orderDetail.qualifiedNum || 0 }} </text></view>
<view class="order-row"><text class="order-label">质量问题</text><text class="order-value">{{ orderDetail.noQualifiedNum || 0 }} </text></view>
<view class="order-row"><text class="order-label">不可回收</text><text class="order-value">{{ orderDetail.unrecyclable || 0 }} </text></view>
<view class="order-divider"></view> <view class="order-divider"></view>
<view class="report-btn" @tap="viewReport">点此查看质检报告详情</view> <view class="report-btn" @tap="viewReport">点此查看质检报告详情</view>
</view> </view>
@ -225,6 +224,11 @@ export default {
}, },
showEstimate() { showEstimate() {
return this.status < 2 return this.status < 2
},
totalInspectCount() {
//
if (!this.orderDetail) return 0
return (this.orderDetail.qualifiedNum || 0) + (this.orderDetail.noQualifiedNum || 0) + (this.orderDetail.unrecyclable || 0)
} }
}, },
methods: { methods: {
@ -425,7 +429,7 @@ export default {
}, },
setOrderStatus(status, state, data) { setOrderStatus(status, state, data) {
// 0:线 1: 2: 3: // 0:线 1: 2: 3:
// state:0 1 2 3
// state:0 1 2 3 4 5退
if (state == 3) { if (state == 3) {
this.currentStep = 0 this.currentStep = 0
this.currentStatus = { this.currentStatus = {
@ -436,6 +440,26 @@ export default {
this.showEditButton = false this.showEditButton = false
return return
} }
if (state == 4) {
this.currentStep = 0
this.currentStatus = {
text: '已驳回',
time: '',
icon: '/static/【待取件】快递员正在赶来.png'
}
this.showEditButton = false
return
}
if (state == 5) {
this.currentStep = 0
this.currentStatus = {
text: '已退款',
time: '',
icon: '/static/【待取件】快递员正在赶来.png'
}
this.showEditButton = false
return
}
if (status == 0) { if (status == 0) {
this.currentStep = 1 this.currentStep = 1
this.currentStatus = { this.currentStatus = {


+ 348
- 109
pages/subcomponent/inspection-detail.vue View File

@ -11,105 +11,162 @@
<uni-icons type="camera" size="22" color="#222" style="margin-left: 12rpx;" /> <uni-icons type="camera" size="22" color="#222" style="margin-left: 12rpx;" />
</view> </view>
</view> </view>
<view class="main-content safe-area-inset-bottom" :style="{ marginTop: navBarTotalHeight + 'px' }">
<view v-if="(status === 'problem' || status === 'unrecyclable') && item" class="card card-problem">
<view class="card-header">
<view class="dot dot-orange"></view>
<text class="card-title card-title-orange">质检有问题不可回收</text>
</view>
<view class="card-desc card-desc-orange">
感谢您参与旧衣回收活动支持环保事业\n我们已收到您的旧衣并完成质检经平台专业质检员严格查验发现商品存在质量问题
<scroll-view scroll-y class="main-content safe-area-inset-bottom" :style="{ marginTop: navBarTotalHeight + 'px' }">
<!-- 质检合格列表 -->
<view v-if="qualifiedList.length > 0" class="section">
<view class="section-title">
<view class="dot dot-green"></view>
<text class="title-text">质检合格</text>
</view> </view>
<view class="timeline">
<view class="timeline-item">
<view class="timeline-dot"></view>
<view class="timeline-content">
<view class="timeline-title-row">
<text class="timeline-title">质检说明</text>
<text class="timeline-time">{{ item.testingTime }}</text>
</view>
<view v-for="(desc, idx) in problemDescArr.length ? problemDescArr : [item.problemDesc]" :key="idx"
class="problem-block">
<view class="problem-index">{{ (idx + 1).toString().padStart(2, '0') }} /
{{ problemDescArr.length.toString().padStart(2, '0') }}</view>
<view class="problem-title">{{ desc || '质量问题' }}</view>
<view class="problem-divider"></view>
<view class="problem-label">质量问题实拍</view>
<view class="problem-images">
<view v-for="(img, i) in imagesArr" :key="i" class="img-lock-wrap"
@tap="isSelf && previewImage(img, i)">
<image :src="img" class="problem-img" mode="aspectFill" />
<view v-if="!isSelf" class="img-lock-mask">
<image src="/static/lock.png" class="lock-icon" />
<view class="lock-tip">为保护用户隐私衣物照片仅本人可见您无权限查看</view>
</view>
</view>
<view v-for="(item, index) in qualifiedList" :key="'qualified-' + index" class="card card-qualified">
<view v-if="item.qualityLevel" class="quality-level-badge">{{ item.qualityLevel }}</view>
<view class="card-header">
<view class="goods-info">
<image :src="item.img" class="goods-img" mode="aspectFit" />
<view class="goods-detail">
<text class="goods-name">{{ item.name }}</text>
<text class="goods-desc">{{ item.desc }}</text>
<text v-if="item.styleName" class="goods-style">款式{{ item.styleName }}</text>
<view class="goods-price-row">
<text class="goods-price" v-if="item.price">{{ (item.price / item.count).toFixed(2) }}/</text>
<text class="goods-count">x{{ item.count }}</text>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view class="timeline-item">
<view class="timeline-dot gray"></view>
<view class="timeline-content">
<view class="timeline-title-row">
<text class="timeline-title">开始查验质检</text>
<text class="timeline-time">{{ item.testingTime }}</text>
</view>
<view class="timeline-desc">
感谢您参与旧衣回收活动支持环保事业\n我们已收到您的旧衣正在进行逐件查验
<view class="timeline">
<view class="timeline-item">
<view class="timeline-dot"></view>
<view class="timeline-content">
<view class="timeline-title-row">
<text class="timeline-title">质检说明</text>
<text class="timeline-time">{{ item.testingTime }}</text>
</view>
<view class="problem-block">
<view class="problem-title">质检图片</view>
<view class="problem-divider"></view>
<view class="problem-images" v-if="item.imagesArr && item.imagesArr.length > 0">
<view v-for="(img, i) in item.imagesArr" :key="i" class="img-lock-wrap"
@tap="isSelf && previewImage(img, i)">
<image :src="img" class="problem-img" mode="aspectFill" />
<view v-if="!isSelf" class="img-lock-mask">
<image src="/static/lock.png" class="lock-icon" />
<view class="lock-tip">为保护用户隐私衣物照片仅本人可见您无权限查看</view>
</view>
</view>
</view>
<view v-else class="no-images">暂无质检图片</view>
</view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view v-else-if="status === 'qualified' && item" class="card card-qualified">
<view class="card-header">
<view class="dot dot-green"></view>
<text class="card-title card-title-green">质检合格</text>
</view>
<view class="card-desc card-desc-green">
感谢您参与旧衣回收活动支持环保事业\n经平台专业质检员严格查验商品合格
<!-- 不可回收列表 -->
<view v-if="unrecyclableList.length > 0" class="section">
<view class="section-title">
<view class="dot dot-orange"></view>
<text class="title-text">不可回收</text>
</view> </view>
<view class="timeline">
<view class="timeline-item">
<view class="timeline-dot"></view>
<view class="timeline-content">
<view class="timeline-title-row">
<text class="timeline-title">质检说明</text>
<text class="timeline-time">{{ item.testingTime }}</text>
<view v-for="(item, index) in unrecyclableList" :key="'unrecyclable-' + index" class="card card-problem">
<view v-if="item.qualityLevel" class="quality-level-badge">{{ item.qualityLevel }}</view>
<view class="card-header">
<view class="goods-info">
<image :src="item.img || bkhs_image" class="goods-img" mode="aspectFit" />
<view class="goods-detail">
<text class="goods-name">{{ item.name }}</text>
<text class="goods-desc">{{ item.desc }}</text>
<text v-if="item.styleName" class="goods-style">款式{{ item.styleName }}</text>
<view class="goods-price-row">
<text class="goods-price" v-if="item.price">{{ (item.price / item.count).toFixed(2) }}/</text>
<text class="goods-count">x{{ item.count }}</text>
</view>
</view> </view>
<view class="problem-block">
<view class="problem-index">01 / {{ imagesArr.length.toString().padStart(2, '0') }}</view>
<view class="problem-title">质检图片</view>
<view class="problem-divider"></view>
<view class="problem-images">
<view v-for="(img, i) in imagesArr" :key="i" class="img-lock-wrap"
@tap="isSelf && previewImage(img, i)">
<image :src="img" class="problem-img" mode="aspectFill" />
<view v-if="!isSelf" class="img-lock-mask">
<image src="/static/lock.png" class="lock-icon" />
<view class="lock-tip">为保护用户隐私衣物照片仅本人可见您无权限查看</view>
</view>
</view>
<view class="timeline">
<view class="timeline-item">
<view class="timeline-dot"></view>
<view class="timeline-content">
<view class="timeline-title-row">
<text class="timeline-title">质检说明</text>
<text class="timeline-time">{{ item.testingTime }}</text>
</view>
<view class="problem-block">
<view class="problem-title">{{ item.problemDesc || '不可回收' }}</view>
<view class="problem-divider"></view>
<view class="problem-label">质检实拍</view>
<view class="problem-images" v-if="item.imagesArr && item.imagesArr.length > 0">
<view v-for="(img, i) in item.imagesArr" :key="i" class="img-lock-wrap"
@tap="isSelf && previewImage(img, i)">
<image :src="img" class="problem-img" mode="aspectFill" />
<view v-if="!isSelf" class="img-lock-mask">
<image src="/static/lock.png" class="lock-icon" />
<view class="lock-tip">为保护用户隐私衣物照片仅本人可见您无权限查看</view>
</view>
</view> </view>
</view> </view>
<view v-else class="no-images">暂无质检图片</view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view class="timeline-item">
<view class="timeline-dot gray"></view>
<view class="timeline-content">
<view class="timeline-title-row">
<text class="timeline-title">开始查验质检</text>
<text class="timeline-time">{{ item.testingTime }}</text>
</view>
</view>
<!-- 质量问题列表 -->
<view v-if="problemList.length > 0" class="section">
<view class="section-title">
<view class="dot dot-orange"></view>
<text class="title-text">质量问题</text>
</view>
<view v-for="(item, index) in problemList" :key="'problem-' + index" class="card card-problem">
<view v-if="item.qualityLevel" class="quality-level-badge">{{ item.qualityLevel }}</view>
<view class="card-header">
<view class="goods-info">
<image :src="item.img || zlwt_image" class="goods-img" mode="aspectFit" />
<view class="goods-detail">
<text class="goods-name">{{ item.name }}</text>
<text class="goods-desc">{{ item.desc }}</text>
<text v-if="item.styleName" class="goods-style">款式{{ item.styleName }}</text>
<view class="goods-price-row">
<text class="goods-price" v-if="item.price">{{ (item.price / item.count).toFixed(2) }}/</text>
<text class="goods-count">x{{ item.count }}</text>
</view>
</view> </view>
<view class="timeline-desc">
感谢您参与旧衣回收活动支持环保事业\n我们已收到您的旧衣正在进行逐件查验
</view>
</view>
<view class="timeline">
<view class="timeline-item">
<view class="timeline-dot"></view>
<view class="timeline-content">
<view class="timeline-title-row">
<text class="timeline-title">质检说明</text>
<text class="timeline-time">{{ item.testingTime }}</text>
</view>
<view class="problem-block">
<view class="problem-title">{{ item.problemDesc || '质量问题' }}</view>
<view class="problem-divider"></view>
<view class="problem-label">质量问题实拍</view>
<view class="problem-images" v-if="item.imagesArr && item.imagesArr.length > 0">
<view v-for="(img, i) in item.imagesArr" :key="i" class="img-lock-wrap"
@tap="isSelf && previewImage(img, i)">
<image :src="img" class="problem-img" mode="aspectFill" />
<view v-if="!isSelf" class="img-lock-mask">
<image src="/static/lock.png" class="lock-icon" />
<view class="lock-tip">为保护用户隐私衣物照片仅本人可见您无权限查看</view>
</view>
</view>
</view>
<view v-else class="no-images">暂无质检图片</view>
</view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view>
</scroll-view>
</view> </view>
</template> </template>
@ -117,58 +174,143 @@
export default { export default {
data() { data() {
return { return {
status: 'problem', // 'problem' or 'qualified' or 'unrecyclable'
statusBarHeight: 0, statusBarHeight: 0,
navBarHeight: 44, navBarHeight: 44,
navBarTotalHeight: 44, navBarTotalHeight: 44,
item: null,
problemDescArr: [],
imagesArr: [],
orderId: '',
qualifiedList: [],
problemList: [],
unrecyclableList: [],
isSelf: true, isSelf: true,
} }
}, },
computed: {
bkhs_image() {//
const item = getApp().globalData.configData.find(i => i.keyName === 'bkhs_image')
return item ? item.keyContent : ''
},
zlwt_image() {//
const item = getApp().globalData.configData.find(i => i.keyName === 'zlwt_image')
return item ? item.keyContent : ''
},
},
onLoad(options) { onLoad(options) {
// //
const sysInfo = uni.getSystemInfoSync() const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight this.statusBarHeight = sysInfo.statusBarHeight
this.navBarHeight = 44 this.navBarHeight = 44
this.navBarTotalHeight = this.statusBarHeight + this.navBarHeight this.navBarTotalHeight = this.statusBarHeight + this.navBarHeight
if (options && options.status) {
this.status = options.status
// ID
if (options && options.orderId) {
this.orderId = options.orderId
this.fetchOrderDetail()
} }
if (options.data) {
this.item = JSON.parse(decodeURIComponent(options.data))
// id
const myUserId = uni.getStorageSync('userInfo')?.id
const orderUserId = this.item.userId
this.isSelf = myUserId && orderUserId && String(myUserId) === String(orderUserId)
if (options.isSelf) {
console.log(options.isSelf, 'options.isSelf管理员')
this.isSelf = true
}
//
if (this.item.testingImages) {
console.log(this.item.testingImages, 'this.item.testingImages')
this.imagesArr = String(this.item.testingImages).split(',').filter(i => i)
} else {
this.imagesArr = []
}
//
if (this.item.problemDesc) {
this.problemDescArr = String(this.item.problemDesc).split(',').filter(i => i)
} else {
this.problemDescArr = []
}
//
if (options.isSelf) {
this.isSelf = true
} }
}, },
methods: { methods: {
async fetchOrderDetail() {
this.$api && this.$api('getOrderDetail', {
orderId: this.orderId
}, res => {
if (res && res.code === 200 && res.result) {
this.parseOrderData(res.result)
}
})
},
parseOrderData(orderData) {
this.qualifiedList = []
this.problemList = []
this.unrecyclableList = []
if (orderData.orderCheckList && orderData.orderCheckList.length > 0) {
orderData.orderCheckList.forEach(item => {
//
if (Number(item.qualifiedNum) > 0) {
const imagesArr = item.commonOrderList && item.commonOrderList[0] && item.commonOrderList[0].testingImages
? item.commonOrderList[0].testingImages.split(',').filter(img => img.trim() !== '')
: []
this.qualifiedList.push({
img: item.image || '/static/default-goods.png',
name: item.title || '未知品类',
desc: item.pinName ? `${item.pinName}` : '',
styleName: item.styleName || '',
price: item.price || 0,
count: item.qualifiedNum,
qualityLevel: item.qualityLevel || '',
testingTime: item.commonOrderList && item.commonOrderList[0] && item.commonOrderList[0].testingTime || '',
imagesArr: imagesArr
})
}
//
if (Array.isArray(item.commonOrderList)) {
item.commonOrderList.forEach(sub => {
const imagesArr = sub.testingImages ? sub.testingImages.split(',').filter(img => img.trim() !== '') : []
//
if (sub.testingStatus == 1) {
this.problemList.push({
img: item.image,
name: item.title || '未知品类',
desc: item.pinName ? `${item.pinName}` : '',
styleName: item.styleName || '',
price: (item.price || 0) / (item.noQualifiedNum || 1),
count: sub.num || 1,
qualityLevel: sub.qualityLevel || '',
testingTime: sub.testingTime || '',
problemDesc: sub.testingInstructions || '',
imagesArr: imagesArr
})
}
//
if (sub.testingStatus == 2) {
this.unrecyclableList.push({
img: item.image,
name: item.title || '未知品类',
desc: item.pinName ? `${item.pinName}` : '',
styleName: item.styleName || '',
price: (item.price || 0) / (item.unrecyclable || 1),
count: sub.num || 1,
qualityLevel: sub.qualityLevel || '',
testingTime: sub.testingTime || '',
problemDesc: sub.testingInstructions || '',
imagesArr: imagesArr
})
}
})
}
})
}
},
navigateBack() { navigateBack() {
uni.navigateBack() uni.navigateBack()
}, },
previewImage(img, i) { previewImage(img, i) {
//
let allImages = []
this.qualifiedList.forEach(item => {
if (item.imagesArr) allImages = allImages.concat(item.imagesArr)
})
this.problemList.forEach(item => {
if (item.imagesArr) allImages = allImages.concat(item.imagesArr)
})
this.unrecyclableList.forEach(item => {
if (item.imagesArr) allImages = allImages.concat(item.imagesArr)
})
uni.previewImage({ uni.previewImage({
current: img, current: img,
urls: this.imagesArr
urls: allImages.length > 0 ? allImages : [img]
}) })
} }
} }
@ -221,15 +363,94 @@ export default {
} }
.main-content { .main-content {
padding: 32rpx 0 0 0;
padding: 32rpx 24rpx 0 24rpx;
width: 100%; width: 100%;
max-width: 750rpx; max-width: 750rpx;
margin: 0 auto; margin: 0 auto;
box-sizing: border-box; box-sizing: border-box;
height: calc(100vh - var(--nav-bar-height));
}
.section {
margin-bottom: 40rpx;
}
.section-title {
display: flex; display: flex;
flex-direction: column;
align-items: center; align-items: center;
overflow: hidden;
margin-bottom: 24rpx;
padding: 0 16rpx;
}
.title-text {
font-size: 32rpx;
font-weight: bold;
color: #222;
}
.goods-info {
display: flex;
align-items: center;
margin-bottom: 16rpx;
}
.goods-img {
width: 80rpx;
height: 80rpx;
border-radius: 16rpx;
margin-right: 20rpx;
background: #f5f5f5;
}
.goods-detail {
flex: 1;
display: flex;
flex-direction: column;
}
.goods-name {
font-size: 28rpx;
font-weight: bold;
color: #222;
margin-bottom: 4rpx;
}
.goods-desc {
font-size: 24rpx;
color: #999;
margin-bottom: 4rpx;
}
.goods-style {
font-size: 24rpx;
color: #666;
margin-bottom: 4rpx;
}
.goods-price-row {
display: flex;
align-items: baseline;
justify-content: space-between;
}
.goods-price {
font-size: 24rpx;
color: #ff6600;
font-weight: bold;
}
.goods-count {
font-size: 24rpx;
color: #666;
}
.no-images {
color: #999;
font-size: 24rpx;
text-align: center;
padding: 20rpx;
background: #f8f8f8;
border-radius: 12rpx;
} }
.safe-area-inset-bottom { .safe-area-inset-bottom {
@ -244,11 +465,29 @@ export default {
box-shadow: 0 4rpx 24rpx rgba(60, 167, 250, 0.08); box-shadow: 0 4rpx 24rpx rgba(60, 167, 250, 0.08);
background: #fff; background: #fff;
max-width: 700rpx; max-width: 700rpx;
width: 100%;
width: calc(100% - 30rpx);
box-sizing: border-box; box-sizing: border-box;
position: relative; position: relative;
} }
.quality-level-badge {
position: absolute;
top: 16rpx;
right: 16rpx;
width: 48rpx;
height: 48rpx;
border-radius: 50%;
background: #ffb400;
color: #fff;
font-size: 24rpx;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
box-shadow: 0 2rpx 8rpx rgba(255, 180, 0, 0.3);
}
.card-problem { .card-problem {
background: linear-gradient(180deg, #fff7e6 0%, #fff 40%); background: linear-gradient(180deg, #fff7e6 0%, #fff 40%);
} }


+ 2
- 4
pages/subcomponent/inspection-report.vue View File

@ -311,10 +311,8 @@ export default {
uni.navigateBack() uni.navigateBack()
}, },
goToInspectionDetail(status, item) { goToInspectionDetail(status, item) {
if (!item) return;
const userId = this.reportData && this.reportData.userId;
const data = { ...item, userId };
let url = `/pages/subcomponent/inspection-detail?status=${status}&data=${encodeURIComponent(JSON.stringify(data))}`
if (!this.orderId) return;
let url = `/pages/subcomponent/inspection-detail?orderId=${this.orderId}`
if (this.isSelf) { if (this.isSelf) {
console.log(this.isSelf, 'this.isSelf'); console.log(this.isSelf, 'this.isSelf');


+ 3
- 1
pages/subcomponent/order.vue View File

@ -191,6 +191,8 @@ export default {
getOrderStatusText(order) { getOrderStatusText(order) {
const { status, state } = order const { status, state } = order
if (state == 3) return '已取消' if (state == 3) return '已取消'
if (state == 4) return '已驳回'
if (state == 5) return '已退款'
if (status == 0) return '【在线预约】' if (status == 0) return '【在线预约】'
if (status == 1 && state == 0) return '【待取件】快递员正在赶来' if (status == 1 && state == 0) return '【待取件】快递员正在赶来'
if (status == 1 && state == 1) return '【已取件】快递员正在送至质检' if (status == 1 && state == 1) return '【已取件】快递员正在送至质检'
@ -524,4 +526,4 @@ export default {
color: #bbb; color: #bbb;
font-size: 24rpx; font-size: 24rpx;
} }
</style>
</style>

+ 179
- 55
pages/wxUserInfo.vue View File

@ -1,36 +1,37 @@
<template> <template>
<view class="login"> <view class="login">
<image :src='logoImage' mode="" class="img"></image>
<view class="title">
{{logoName}}
</view>
<view class="title">
申请获取你的头像昵称
<view class="header">
<image :src='logoImage' mode="aspectFit" class="logo-img"></image>
<view class="app-title">
{{logoName}}
</view>
<view class="subtitle">
申请获取你的头像昵称
</view>
</view> </view>
<button class="chooseAvatar" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<view class="line">
<view class="">
头像
<view class="form-container">
<button class="avatar-section" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<view class="avatar-label">头像</view>
<view class="avatar-container">
<image :src="userInfo.avatarUrl" v-if="userInfo.avatarUrl" class="avatar-img" mode="aspectFill"></image>
<view v-else class="avatar-placeholder">
<image src="/static/暂未登录 请先登录.png" class="placeholder-img" mode="aspectFit"></image>
<text class="placeholder-text">点击选择头像</text>
</view>
</view> </view>
<view class="">
<image :src="userInfo.avatarUrl" v-if="userInfo.avatarUrl" style="width: 60rpx;height: 60rpx;"
mode=""></image>
<image src="/static/暂未登录 请先登录.png" v-else style="width: 50rpx;height: 50rpx;" mode=""></image>
</button>
<view class="nickname-section">
<view class="nickname-label">昵称</view>
<view class="nickname-input-container">
<input type="nickname" placeholder="请输入昵称" class="nickname-input" id="nickName"
v-model="userInfo.nickName" />
</view> </view>
</view> </view>
</button>
<view class="line">
<view class="">
昵称
</view>
<view class="">
<input type="nickname" placeholder="请输入昵称" style="text-align: right;" id="nickName"
v-model="userInfo.nickName" />
</view>
</view> </view>
<view class="btn" @click="submit">
<view class="submit-btn" @click="submit">
确认 确认
</view> </view>
</view> </view>
@ -108,50 +109,173 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.img{
width: 20%;
height: 15%;
margin-top: 10%;
}
.login { .login {
min-height: 100vh;
background: linear-gradient(180deg, #fff7e6 0%, #fff 40%);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center;
align-items: center; align-items: center;
height: 80vh;
padding: 0 48rpx;
box-sizing: border-box;
}
.header {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 120rpx;
margin-bottom: 80rpx;
.title {
line-height: 45rpx;
font-weight: 900;
.logo-img {
width: 160rpx;
height: 160rpx;
border-radius: 32rpx;
margin-bottom: 32rpx;
box-shadow: 0 8rpx 24rpx rgba(255, 156, 0, 0.15);
} }
.line {
.app-title {
font-size: 48rpx;
font-weight: bold;
color: #222;
margin-bottom: 16rpx;
}
.subtitle {
font-size: 28rpx;
color: #666;
line-height: 1.4;
}
}
.form-container {
width: 100%;
max-width: 600rpx;
margin-bottom: 80rpx;
}
.avatar-section {
width: 100%;
background: #fff;
border-radius: 24rpx;
padding: 48rpx 36rpx;
margin-bottom: 32rpx;
border: none;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
display: flex;
flex-direction: column;
align-items: center;
gap: 32rpx;
&::after {
border: none;
}
.avatar-label {
font-size: 32rpx;
font-weight: 500;
color: #333;
}
.avatar-container {
position: relative;
width: 200rpx;
height: 200rpx;
}
.avatar-img {
width: 100%;
height: 100%;
border-radius: 50%;
border: 4rpx solid #fff;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
}
.avatar-placeholder {
width: 100%;
height: 100%;
border-radius: 50%;
border: 4rpx dashed #ddd;
display: flex; display: flex;
justify-content: space-between;
flex-direction: column;
align-items: center; align-items: center;
width: 80%;
border-bottom: 1px solid #00000023;
padding: 30rpx 0;
margin: 0 auto;
justify-content: center;
background: #f8f8f8;
gap: 16rpx;
.placeholder-img {
width: 80rpx;
height: 80rpx;
opacity: 0.6;
}
.placeholder-text {
font-size: 24rpx;
color: #999;
}
}
}
.nickname-section {
background: #fff;
border-radius: 24rpx;
padding: 48rpx 36rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
.nickname-label {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 32rpx;
text-align: center;
}
.nickname-input-container {
position: relative;
} }
.chooseAvatar {
.nickname-input {
width: 100%; width: 100%;
padding: 0;
margin: 0;
margin-top: 10vh;
border: none;
height: 88rpx;
background: #f8f8f8;
border-radius: 16rpx;
padding: 0 24rpx;
font-size: 32rpx;
color: #333;
border: 2rpx solid transparent;
box-sizing: border-box;
transition: all 0.3s;
&:focus {
border-color: #ffb400;
background: #fff;
outline: none;
}
&::placeholder {
color: #bbb;
font-size: 28rpx;
}
} }
}
.btn {
// background: $uni-linear-gradient-btn-color;
background: red;
color: #fff;
width: 80%;
padding: 20rpx 0;
text-align: center;
border-radius: 15rpx;
margin-top: 10vh;
.submit-btn {
width: 100%;
max-width: 600rpx;
height: 96rpx;
background: linear-gradient(90deg, #ffd01e 0%, #ff8917 100%);
color: #fff;
font-size: 36rpx;
font-weight: bold;
text-align: center;
line-height: 96rpx;
border-radius: 48rpx;
box-shadow: 0 8rpx 24rpx rgba(255, 156, 0, 0.3);
transition: all 0.3s;
&:active {
transform: translateY(2rpx);
box-shadow: 0 4rpx 12rpx rgba(255, 156, 0, 0.3);
} }
} }
</style> </style>

Loading…
Cancel
Save