Browse Source

‘优化页面逻辑和样式’

master
Lj 4 weeks ago
parent
commit
06f0815f49
11 changed files with 1769 additions and 686 deletions
  1. +217
    -38
      App.vue
  2. +70
    -0
      README.md
  3. +39
    -10
      pages/component/home.vue
  4. +37
    -14
      pages/component/my.vue
  5. +58
    -25
      pages/component/recycle.vue
  6. +555
    -115
      pages/manager/inspect-result.vue
  7. +748
    -464
      pages/manager/inspect.vue
  8. +12
    -5
      pages/manager/order-detail.vue
  9. +27
    -12
      pages/manager/order.vue
  10. +5
    -3
      pages/subcomponent/detail.vue
  11. +1
    -0
      pages/subcomponent/promotion.vue

+ 217
- 38
App.vue View File

@ -1,7 +1,32 @@
<template>
<view v-if="!globalDataLoaded" class="global-loading">
<view class="loading-container">
<view class="loading-logo">
<image src="/static/回收/衣物.png" mode="aspectFit" class="logo-img" />
</view>
<view class="loading-spinner">
<view class="spinner"></view>
</view>
<text class="loading-text">正在加载...</text>
<view class="loading-progress">
<view class="progress-bar" :style="{width: loadingProgress + '%'}"></view>
</view>
</view>
</view>
</template>
<script>
import routerInterception from '@/utils/router-interception.js'
import config from '/config.js'
export default {
data() {
return {
globalDataLoaded: false,
loadingProgress: 0,
loadedCount: 0,
totalRequests: 4 //
}
},
globalData: {
flag: 1,
login_status: true,
@ -9,69 +34,150 @@
bannerList: [],
pricePreviewList: [],
configData: [],
qr_path: ''
qr_path: '',
isAppDataReady: false //
},
onLaunch: function() {
routerInterception()
this.getBannerList()
this.getPricePreviewList()
this.getConfigData()
this.getQrCode()
// console.log(this.$utils)
this.initializeAppData()
console.log('App Launch')
},
onLoad: function() {
this.getBannerList()
this.getQrCode();
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
},
methods: {
//
async initializeAppData() {
try {
//
this.loadingProgress = 0
this.loadedCount = 0
//
const promises = [
this.getBannerList(),
this.getPricePreviewList(),
this.getConfigData(),
this.getQrCode()
]
await Promise.all(promises)
// 100%
this.loadingProgress = 100
//
this.globalDataLoaded = true
getApp().globalData.isAppDataReady = true
//
setTimeout(() => {
uni.$emit('appDataReady')
}, 500)
} catch (error) {
console.error('App data loading failed:', error)
// 使
this.loadingProgress = 100
this.globalDataLoaded = true
getApp().globalData.isAppDataReady = true
setTimeout(() => {
uni.$emit('appDataReady')
}, 500)
}
},
//
updateProgress() {
this.loadedCount++
this.loadingProgress = Math.round((this.loadedCount / this.totalRequests) * 100)
},
getBannerList() {
// this.$api
this.$api && this.$api('getBanner', {}, res => {
if (res && res.code === 200 && Array.isArray(res.result)) {
getApp().globalData.bannerList = res.result
console.log(getApp().globalData.bannerList, 'bannerList')
uni.$emit('bannerListUpdated')
return new Promise((resolve) => {
if (!this.$api) {
this.updateProgress()
resolve()
return
}
this.$api('getBanner', {}, res => {
if (res && res.code === 200 && Array.isArray(res.result)) {
getApp().globalData.bannerList = res.result
console.log(getApp().globalData.bannerList, 'bannerList')
uni.$emit('bannerListUpdated')
}
this.updateProgress()
resolve()
})
})
},
getPricePreviewList() {
this.$api && this.$api('getPricePreviewClassList', {}, res => {
if (res && res.success && Array.isArray(res.result)) {
getApp().globalData.pricePreviewList = res.result
uni.$emit('pricePreviewListUpdated')
return new Promise((resolve) => {
if (!this.$api) {
this.updateProgress()
resolve()
return
}
this.$api('getPricePreviewClassList', {}, res => {
if (res && res.success && Array.isArray(res.result)) {
getApp().globalData.pricePreviewList = res.result
uni.$emit('pricePreviewListUpdated')
}
this.updateProgress()
resolve()
})
})
},
getConfigData() {
this.$api('getConfig', {}, res => {
console.log('Config data response:', JSON.parse(JSON.stringify(res)))
if (res && res.success && Array.isArray(res.result)) {
getApp().globalData.configData = res.result
// console.log('Config data set:', JSON.parse(JSON.stringify(this.configData)) )
return new Promise((resolve) => {
if (!this.$api) {
this.updateProgress()
resolve()
return
}
this.$api('getConfig', {}, res => {
console.log('Config data response:', JSON.parse(JSON.stringify(res)))
if (res && res.success && Array.isArray(res.result)) {
getApp().globalData.configData = res.result
uni.$emit('configDataUpdated')
}
this.updateProgress()
resolve()
})
})
},
getQrCode() {
// console.log(config.baseUrl,'config.baseUrl')
let that = this;
if (!uni.getStorageSync('token')) {
return
}
uni.getImageInfo({
src: `${config.baseUrl}/recycle-admin/applet/promotion/getInviteCode?token=${uni.getStorageSync('token')}`,
success: res => {
getApp().globalData.configData.qr_path = res.path
console.log(getApp().globalData.configData.qr_path,
'getApp().globalData.configData.qr_path')
},
fail: err => {
console.log(err)
return new Promise((resolve) => {
if (!uni.getStorageSync('token')) {
this.updateProgress()
resolve()
return
}
uni.getImageInfo({
src: `${config.baseUrl}/recycle-admin/applet/promotion/getInviteCode?token=${uni.getStorageSync('token')}`,
success: res => {
getApp().globalData.configData.qr_path = res.path
console.log(getApp().globalData.configData.qr_path, 'qr_path')
this.updateProgress()
resolve()
},
fail: err => {
console.log('QR code load failed:', err)
this.updateProgress()
resolve()
}
})
})
}
}
@ -79,8 +185,81 @@
</script>
<style>
/* // @import "./uni_modules/vk-uview-ui/index.scss"; */
/* 全局loading样式 */
.global-loading {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
z-index: 99999;
}
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.loading-logo {
margin-bottom: 60rpx;
}
.logo-img {
width: 160rpx;
height: 160rpx;
border-radius: 32rpx;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.2);
}
.loading-spinner {
margin-bottom: 40rpx;
}
.spinner {
width: 60rpx;
height: 60rpx;
border: 4rpx solid rgba(255, 255, 255, 0.3);
border-top-color: #fff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
.loading-text {
color: #fff;
font-size: 32rpx;
font-weight: 500;
margin-bottom: 40rpx;
opacity: 0.9;
}
.loading-progress {
width: 400rpx;
height: 6rpx;
background: rgba(255, 255, 255, 0.2);
border-radius: 3rpx;
overflow: hidden;
}
.progress-bar {
height: 100%;
background: linear-gradient(90deg, #fff 0%, #f0f8ff 100%);
border-radius: 3rpx;
transition: width 0.3s ease;
box-shadow: 0 0 10rpx rgba(255, 255, 255, 0.3);
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* 原有样式 */
/*每个页面公共css */
.uni-tabbar-bottom {
display: none;


+ 70
- 0
README.md View File

@ -409,3 +409,73 @@ export default {
- 确认网络请求是否正常
- 查看请求参数格式是否正确
## 全局加载机制
### 概述
为了确保应用启动时的数据完整性,项目实现了全局加载机制。在App.vue中的关键数据加载完成之前,会显示加载页面,防止用户在数据未准备好的情况下访问功能。
### 实现原理
#### 1. App.vue 全局数据加载
- **数据类型**: bannerList(轮播图)、pricePreviewList(价格预览)、configData(配置数据)、qr_path(二维码)
- **加载方式**: 并发加载所有数据,使用 Promise.all 确保全部完成
- **进度显示**: 实时更新加载进度条(0-100%)
- **状态标识**: globalData.isAppDataReady 标识数据是否准备完成
#### 2. 页面等待机制
主要页面(首页、回收页、我的页面)会检查App数据状态:
- 如果数据未准备好:显示uni.showLoading,监听'appDataReady'事件
- 如果数据已准备好:直接初始化页面数据
#### 3. 加载界面设计
- **背景**: 渐变色背景(紫色到蓝色)
- **元素**: Logo图片、旋转加载器、加载文字、进度条
- **动画**: 平滑的旋转动画和进度条过渡效果
### 使用方式
#### 在新页面中添加等待逻辑:
```javascript
onLoad(options) {
// 保存参数
this.loadOptions = options
// 检查App数据是否已经准备好
if (!getApp().globalData.isAppDataReady) {
// 显示加载状态
uni.showLoading({
title: '加载中...',
mask: true
})
// 监听App数据准备完成事件
uni.$on('appDataReady', () => {
uni.hideLoading()
this.initializePageData()
})
} else {
// App数据已经准备好,直接初始化页面数据
this.initializePageData()
}
},
// 初始化页面数据的方法
initializePageData() {
// 在这里放置原来在onLoad中的数据初始化逻辑
// ...
}
```
### 优势
1. **用户体验**: 避免页面显示不完整或错误数据
2. **数据一致性**: 确保全局数据在页面使用前已加载完成
3. **错误处理**: 即使加载失败也会继续运行,不会阻塞应用
4. **性能优化**: 并发加载提高加载效率
5. **视觉反馈**: 清晰的加载进度和状态提示
### 注意事项
- 管理页面等非核心页面可以不使用此机制
- 确保在页面卸载时移除事件监听器
- 加载失败时应有合理的降级处理

+ 39
- 10
pages/component/home.vue View File

@ -220,6 +220,7 @@ export default {
cityList: [],
addressCion: '',
sbkCion: '',
queryParams: {},
}
},
computed: {
@ -357,17 +358,22 @@ export default {
this.addressCion = address ? address.keyContent : '';
this.sbkCion = sbk ? sbk.keyContent : '';
},
},
onLoad(query) {
if (query.shareId) {
uni.setStorageSync('shareId', query.shareId)
};
this.getAreaList();
this.getPricePreview();
this.getRecentGoods();
//
initializePageData() {
const query = this.queryParams || {}
if (query.shareId) {
uni.setStorageSync('shareId', query.shareId)
}
this.getAreaList()
this.getPricePreview()
this.getRecentGoods()
this.pricePreviewList = getApp().globalData.pricePreviewList || []
this.bannerList = getApp().globalData.bannerList || []
this.getFreeCityList();
this.getFreeCityList()
//
uni.$on('pricePreviewListUpdated', () => {
this.pricePreviewList = getApp().globalData.pricePreviewList || []
this.getPricePreview()
@ -375,6 +381,29 @@ export default {
uni.$on('bannerListUpdated', () => {
this.bannerList = getApp().globalData.bannerList || []
})
},
},
onLoad(query) {
// query
this.queryParams = query
// App
if (!getApp().globalData.isAppDataReady) {
//
uni.showLoading({
title: '加载中...',
mask: true
})
// App
uni.$on('appDataReady', () => {
uni.hideLoading()
this.initializePageData()
})
} else {
// App
this.initializePageData()
}
},
onUnload() {
uni.$off('pricePreviewListUpdated')
@ -386,7 +415,7 @@ export default {
//
uni.$on('configDataUpdated', this.updateCionData);
this.getPricePreview();
}
},
}
</script>


+ 37
- 14
pages/component/my.vue View File

@ -30,7 +30,7 @@
<view class="user-card" v-if="login_status">
<view class="user-info">
<view class="avatar-badge-box">
<image class="avatar" :src="userInfo.headImage" mode="aspectFill"></image>
<image class="avatar" :src="userInfo.headImage" mode="aspectFill"></image>
<view class="avatar-badge">{{ userTypeText }}</view>
</view>
<view class="info">
@ -360,6 +360,26 @@ export default {
this.totalOrders = 0
}
})
},
//
initializePageData() {
//
// uni.startPullDownRefresh()
uni.$on('refreshUserInfo', () => {
this.fetchUserInfo()
})
this.fetchUserInfo()
this.fetchOrderList()
this.getCumulativeRecoveryCount()
uni.$on('bannerListUpdated', () => {
this.$forceUpdate && this.$forceUpdate()
})
if (getApp().globalData.bannerList && getApp().globalData.bannerList.length > 0) {
this.$forceUpdate && this.$forceUpdate()
}
},
goAbout(){
}
},
computed: {
@ -384,19 +404,22 @@ export default {
}
},
onLoad() {
//
// uni.startPullDownRefresh()
uni.$on('refreshUserInfo', () => {
this.fetchUserInfo()
})
this.fetchUserInfo()
this.fetchOrderList()
this.getCumulativeRecoveryCount()
uni.$on('bannerListUpdated', () => {
this.$forceUpdate && this.$forceUpdate()
})
if (getApp().globalData.bannerList && getApp().globalData.bannerList.length > 0) {
this.$forceUpdate && this.$forceUpdate()
// App
if (!getApp().globalData.isAppDataReady) {
//
uni.showLoading({
title: '加载中...',
mask: true
})
// App
uni.$on('appDataReady', () => {
uni.hideLoading()
this.initializePageData()
})
} else {
// App
this.initializePageData()
}
},
onShow() {


+ 58
- 25
pages/component/recycle.vue View File

@ -351,6 +351,7 @@ export default {
reduceItem: null, //
reduceBrandList: [], //
viewedRuleItems: new Set(), // ID
loadOptions: null, // options
}
},
computed: {
@ -891,6 +892,44 @@ export default {
return '#'
},
//
initializePageData() {
const options = this.loadOptions || {}
if (options && options.categoryId) {
const idx = this.categories.findIndex(c => c.id == options.categoryId)
if (idx !== -1) this.currentCategory = idx
}
if (this.categories.length > 0) {
this.fetchGoodsList(this.categories[this.currentCategory].id, 1)
}
uni.$on('bannerListUpdated', () => {
this.$forceUpdate && this.$forceUpdate()
})
if (getApp().globalData.bannerList && getApp().globalData.bannerList.length > 0) {
this.$forceUpdate && this.$forceUpdate()
}
// reLaunch
if (getApp().globalData.shouldClearRecycle) {
Object.values(this.allProducts).forEach(categoryItems => {
categoryItems.forEach(item => {
this.$set(item, 'quantity', 0)
if (item.brandQuantities) {
this.$set(item, 'brandQuantities', {})
}
})
})
//
this.viewedRuleItems.clear()
this.showDetailPanel = false
this.$forceUpdate()
getApp().globalData.shouldClearRecycle = false
}
},
},
created() {
this.currentCategory = 0
@ -917,34 +956,28 @@ export default {
})
},
onLoad(options) {
if (options && options.categoryId) {
const idx = this.categories.findIndex(c => c.id == options.categoryId)
if (idx !== -1) this.currentCategory = idx
}
this.fetchGoodsList(this.categories[this.currentCategory].id, 1)
uni.$on('bannerListUpdated', () => {
this.$forceUpdate && this.$forceUpdate()
})
if (getApp().globalData.bannerList && getApp().globalData.bannerList.length > 0) {
this.$forceUpdate && this.$forceUpdate()
}
// reLaunch
if (getApp().globalData.shouldClearRecycle) {
Object.values(this.allProducts).forEach(categoryItems => {
categoryItems.forEach(item => {
this.$set(item, 'quantity', 0)
if (item.brandQuantities) {
this.$set(item, 'brandQuantities', {})
}
})
// options
this.loadOptions = options
// App
if (!getApp().globalData.isAppDataReady) {
//
uni.showLoading({
title: '加载中...',
mask: true
})
//
this.viewedRuleItems.clear()
this.showDetailPanel = false
this.$forceUpdate()
getApp().globalData.shouldClearRecycle = false
// App
uni.$on('appDataReady', () => {
uni.hideLoading()
this.initializePageData()
})
} else {
// App
this.initializePageData()
}
},
onUnload() {
uni.$off('bannerListUpdated')
//


+ 555
- 115
pages/manager/inspect-result.vue View File

@ -1,5 +1,5 @@
<template>
<view class="inspect-result-container">
<view class="inspect-result-container" :class="{ 'popup-open': isPopupOpen }">
<!-- 顶部导航栏 -->
<view class="nav-bar">
<view class="back" @tap="goBack">
@ -12,52 +12,73 @@
</view>
<view class="main-content">
<!-- 合格产品卡片 -->
<view class="result-card">
<view v-if="hasQualifiedItems" class="result-card">
<view class="card-title">合格产品</view>
<view v-for="item in qualifiedList" :key="item.id" class="result-row">
<view class="row-main">
<text class="row-name">{{item.name}}</text>
<view class="goods-name-section">
<text class="goods-name">{{getItemName(item.id)}}</text>
<text class="goods-brand">{{getItemBrand(item.id)}}</text>
</view>
<text class="row-price">¥ {{item.price}} <text class="row-unit">/</text></text>
<text class="row-count">x{{item.count}}</text>
<text class="row-total">¥{{item.total}}</text>
</view>
<view class="row-reason">
<text class="reason-label">理由填写</text>
<input class="reason-input" v-model="item.reason" placeholder="请选择理由(选填)" />
<text class="reason-label">{{getItemName(item.id)}}</text>
<view class="reason-select" @tap="selectReasonForQualified(item)">
<text class="reason-placeholder" :class="{ 'selected': hasSelectedReason(item) }">
{{ hasSelectedReason(item) ? '已选择' : '请选择理由(选填)' }}
</text>
<uni-icons type="right" size="18" color="#bbb" />
</view>
</view>
</view>
</view>
<!-- 不合格产品卡片 -->
<view class="result-card">
<view v-if="hasUnqualifiedItems" class="result-card">
<view class="card-title">不合格产品</view>
<view v-for="group in unqualifiedGroups" :key="group.name" class="result-group">
<view class="row-main">
<text class="row-name">{{group.name}}</text>
<view class="goods-name-section">
<text class="goods-name">{{getItemName(group.id)}}</text>
<text class="goods-brand">{{getItemBrand(group.id)}}</text>
</view>
<text class="row-price">¥ {{group.price}} <text class="row-unit">/</text></text>
<text class="row-total">¥{{group.total}}</text>
</view>
<view v-for="item in group.items" :key="item.id" class="row-reason">
<text class="reason-label">{{item.name}}</text>
<view class="reason-select" @tap="selectReason(item)">
<text class="reason-placeholder">请选择理由</text>
<text class="reason-placeholder" :class="{ 'selected': hasSelectedReason(item) }">
{{ hasSelectedReason(item) ? '已选择' : '请选择理由' }}
</text>
<uni-icons type="right" size="18" color="#bbb" />
</view>
</view>
</view>
</view>
<!-- 不可回收产品卡片 -->
<view class="result-card">
<view v-if="hasUnrecyclableItems" class="result-card">
<view class="card-title">不可回收产品</view>
<view v-for="item in unrecyclableList" :key="item.id" class="result-row">
<view class="row-main">
<text class="row-name">{{item.name}}</text>
<view class="goods-name-section">
<text class="goods-name">{{getItemName(item.id)}}</text>
<text class="goods-brand">{{getItemBrand(item.id)}}</text>
</view>
<text class="row-price">¥ {{item.price || '—'}} <text class="row-unit">/</text></text>
<text class="row-count">x{{item.count}}</text>
<text class="row-total">¥{{item.total}}</text>
</view>
<view class="row-reason">
<text class="reason-label">理由填写</text>
<input class="reason-input" v-model="item.reason" placeholder="请选择理由(选填)" />
<text class="reason-label">{{getItemName(item.id)}}</text>
<view class="reason-select" @tap="selectReasonForUnrecyclable(item)">
<text class="reason-placeholder" :class="{ 'selected': hasSelectedReason(item) }">
{{ hasSelectedReason(item) ? '已选择' : '请选择理由(选填)' }}
</text>
<uni-icons type="right" size="18" color="#bbb" />
</view>
</view>
</view>
</view>
@ -69,11 +90,11 @@
</view>
<view class="info-row">
<text class="info-label">订单编号</text>
<text class="info-value copy-btn">RE82738127861525 复制</text>
<text class="info-value copy-btn">{{ order?.ordeNo || 'RE82738127861525' }} 复制</text>
</view>
<view class="info-row">
<text class="info-label">取件时间</text>
<text class="info-value">2025-03-20 11:00</text>
<text class="info-value">{{ order?.goTime || '2025-03-20 11:00' }}</text>
</view>
</view>
</view>
@ -83,31 +104,33 @@
<button class="btn-main" @tap="finishInspect">完成质检</button>
</view>
<!-- 理由弹窗 -->
<uni-popup ref="reasonPopup" type="bottom" :mask-click="false">
<uni-popup ref="reasonPopup" type="bottom" :mask-click="false" :safe-area="false" class="reason-popup-wrapper">
<view class="reason-popup">
<view class="popup-header">
<text class="popup-close" @tap="closeReasonPopup">关闭</text>
<text class="popup-title">{{ currentReasonTitle }}</text>
</view>
<view class="popup-section">
<text class="section-label">上传图片</text>
<view class="img-list">
<view v-for="(img, idx) in reasonImages" :key="idx" class="img-item">
<image :src="img" class="img" />
<view class="img-del" @tap="removeReasonImg(idx)">×</view>
</view>
<view class="img-item add" @tap="addReasonImg">
<uni-icons type="plusempty" size="40" color="#bbb" />
<scroll-view class="popup-content" scroll-y="true">
<view class="popup-section">
<text class="section-label">上传图片</text>
<view class="img-list">
<view class="img-item add" @tap="addReasonImg">
<uni-icons type="plusempty" size="32" color="#bbb" />
</view>
<view v-for="(img, idx) in reasonImages" :key="idx" class="img-item">
<image :src="img" class="img" />
<view class="img-del" @tap="removeReasonImg(idx)">×</view>
</view>
</view>
</view>
</view>
<view class="popup-section">
<text class="section-label">选择理由</text>
<view v-for="(item, idx) in reasonOptions" :key="item" class="reason-row" @tap="toggleReason(idx)">
<view :class="['checkbox', {checked: reasonChecked[idx]}]" />
<text class="reason-text">{{ item }}</text>
<view class="popup-section">
<text class="section-label">选择理由</text>
<view v-for="(item, idx) in reasonOptions" :key="item" class="reason-row" @tap="toggleReason(idx)">
<view :class="['checkbox', {checked: reasonChecked[idx]}]" />
<text class="reason-text">{{ item }}</text>
</view>
</view>
</view>
</scroll-view>
<button class="popup-save-btn" @tap="saveReason">保存</button>
</view>
</uni-popup>
@ -116,46 +139,186 @@
<script>
import pullRefreshMixin from '../mixins/pullRefreshMixin.js'
import OSS from '@/utils/oss-upload/oss/index.js'
export default {
mixins: [pullRefreshMixin],
data() {
return {
qualifiedList: [
{ id: 1, name: '羽绒服', price: 8, count: 8, total: 64, reason: '' }
],
unqualifiedGroups: [
{
name: '羽绒服', price: 8, total: 0,
items: [
{ id: 11, name: '羽绒服1', reason: '' },
{ id: 12, name: '羽绒服2', reason: '' },
{ id: 13, name: '羽绒服3', reason: '' },
{ id: 14, name: '羽绒服4', reason: '' },
{ id: 15, name: '羽绒服5', reason: '' },
{ id: 16, name: '羽绒服6', reason: '' },
{ id: 17, name: '羽绒服7', reason: '' },
{ id: 18, name: '羽绒服8', reason: '' }
]
},
{
name: '品牌服饰', price: 8, total: 0,
items: [
{ id: 21, name: '品牌服饰1', reason: '' }
]
}
],
unrecyclableList: [
{ id: 31, name: '毛衣', price: '', count: 8, total: 0, reason: '' }
],
inspectData: null, //
order: null, //
qualifiedList: [],
unqualifiedGroups: [],
unrecyclableList: [],
reasonPopupVisible: false,
currentReasonTitle: '',
reasonImages: [],
reasonOptions: ['大面积破损', '不可回收', '顽固污渍', '污渍无法清除', '异味严重', '带有危险物品'],
reasonChecked: [false, true, false, true, false, false],
currentReasonItem: null
currentReasonItem: null,
isPopupOpen: false //
}
},
computed: {
hasQualifiedItems() {
return this.qualifiedList && this.qualifiedList.length > 0
},
hasUnqualifiedItems() {
return this.unqualifiedGroups && this.unqualifiedGroups.length > 0
},
hasUnrecyclableItems() {
return this.unrecyclableList && this.unrecyclableList.length > 0
}
},
onLoad(options) {
//
if (options && options.resultData) {
try {
const resultData = JSON.parse(decodeURIComponent(options.resultData))
this.inspectData = resultData.inspectResult
this.order = resultData.order
console.log('接收到的质检数据:', this.inspectData)
console.log('接收到的订单数据:', this.order)
this.processInspectData()
} catch (error) {
console.error('解析数据失败:', error)
}
}
//
if (options && options.inspectData && !options.resultData) {
try {
this.inspectData = JSON.parse(decodeURIComponent(options.inspectData))
console.log('接收到的质检数据:', this.inspectData)
this.processInspectData()
} catch (error) {
console.error('解析质检数据失败:', error)
}
}
},
methods: {
processInspectData() {
if (!this.inspectData || !this.inspectData.list) return
this.qualifiedList = []
this.unqualifiedGroups = []
this.unrecyclableList = []
this.inspectData.list.forEach(item => {
//
if (item.id === 'unrecyclable') return
// order
const orderItem = this.order?.commonOrderList?.find(orderGoods => orderGoods.id == item.id)
if (!orderItem) return
const itemName = orderItem.title || '未知商品'
const itemBrand = orderItem.pinName || ''
const displayName = itemBrand ? `${itemName} ${itemBrand}` : itemName
const itemNames = itemBrand ? `${itemName}` : itemName
const itemPrice = orderItem.onePrice || 0
//
let qualifiedCount = 0
let unqualifiedCount = 0
let unrecyclableCount = 0
item.commonOrderList.forEach(commonItem => {
if (commonItem.testingStatus === 0) {
qualifiedCount++
} else if (commonItem.testingStatus === 1) {
unqualifiedCount++
} else if (commonItem.testingStatus === 2) {
unrecyclableCount++
}
})
//
if (qualifiedCount > 0) {
//
const qualifiedCommonItem = item.commonOrderList.find(commonItem => commonItem.testingStatus === 0)
const savedImages = qualifiedCommonItem?.testingImages ? qualifiedCommonItem.testingImages.split(',').filter(img => img) : []
const savedReasons = this.parseTestingInstructions(qualifiedCommonItem?.testingInstructions || '')
this.qualifiedList.push({
id: item.id,
name: displayName,
shopClass: item.shopClass,
shopId: item.shopId,
price: itemPrice,
count: qualifiedCount,
total: item.price || 0, // 使
reason: '',
images: savedImages,
reasons: savedReasons
})
}
//
if (unqualifiedCount > 0) {
const unqualifiedItems = []
let index = 1
item.commonOrderList.forEach(commonItem => {
if (commonItem.testingStatus === 1) {
const savedImages = commonItem.testingImages ? commonItem.testingImages.split(',').filter(img => img) : []
const savedReasons = this.parseTestingInstructions(commonItem.testingInstructions || '')
unqualifiedItems.push({
id: commonItem.id,
name: `${itemNames}${index}`,
shopClass: item.shopClass,
shopId: item.shopId,
reason: '',
images: savedImages,
reasons: savedReasons
})
index++
}
})
if (unqualifiedItems.length > 0) {
this.unqualifiedGroups.push({
id: item.id,
name: displayName,
shopClass: item.shopClass,
shopId: item.shopId,
price: itemPrice,
total: 0, // 0
items: unqualifiedItems
})
}
}
//
if (unrecyclableCount > 0) {
//
const unrecyclableCommonItem = item.commonOrderList.find(commonItem => commonItem.testingStatus === 2)
const savedImages = unrecyclableCommonItem?.testingImages ? unrecyclableCommonItem.testingImages.split(',').filter(img => img) : []
const savedReasons = this.parseTestingInstructions(unrecyclableCommonItem?.testingInstructions || '')
this.unrecyclableList.push({
id: item.id,
name: displayName,
shopClass: item.shopClass,
shopId: item.shopId,
price: '', //
count: unrecyclableCount,
total: 0,
reason: '',
images: savedImages,
reasons: savedReasons
})
}
})
console.log('处理后的数据:', {
qualifiedList: this.qualifiedList,
unqualifiedGroups: this.unqualifiedGroups,
unrecyclableList: this.unrecyclableList
})
},
goBack() {
uni.navigateBack()
},
@ -163,6 +326,17 @@ export default {
uni.navigateBack()
},
finishInspect() {
// inspectData
console.log('最终的质检数据:', JSON.stringify(this.inspectData, null, 2))
// API
// this.$api('submitInspectResult', { inspectData: this.inspectData }, res => {
// if (res && res.code === 200) {
// uni.showToast({ title: '', icon: 'success' })
// uni.navigateBack()
// }
// })
uni.showToast({ title: '完成质检', icon: 'success' })
},
selectReason(item) {
@ -170,19 +344,94 @@ export default {
this.currentReasonTitle = item.name
this.reasonImages = item.images || []
this.reasonChecked = item.reasons || Array(this.reasonOptions.length).fill(false)
this.lockScroll()
this.$refs.reasonPopup.open()
},
selectReasonForQualified(item) {
this.currentReasonItem = item
this.currentReasonTitle = this.getItemName(item.id)
this.reasonImages = item.images || []
this.reasonChecked = item.reasons || Array(this.reasonOptions.length).fill(false)
this.lockScroll()
this.$refs.reasonPopup.open()
},
selectReasonForUnrecyclable(item) {
this.currentReasonItem = item
this.currentReasonTitle = this.getItemName(item.id)
this.reasonImages = item.images || []
this.reasonChecked = item.reasons || Array(this.reasonOptions.length).fill(false)
this.lockScroll()
this.$refs.reasonPopup.open()
},
closeReasonPopup() {
this.unlockScroll()
this.$refs.reasonPopup.close()
},
addReasonImg() {
uni.chooseImage({
count: 3 - this.reasonImages.length,
success: res => {
this.reasonImages = this.reasonImages.concat(res.tempFilePaths)
//
if (this.reasonImages.length >= 3) {
uni.showToast({
title: '最多只能上传3张图片',
icon: 'none'
})
return
}
uni.chooseMedia({
count: 3 - this.reasonImages.length, //
mediaType: ['image'], //
sourceType: ['album', 'camera'], //
maxDuration: 30,
camera: 'back',
success: (res) => {
console.log('选择的图片:', res.tempFiles)
//
uni.showLoading({
title: '上传中...'
})
//
const uploadPromises = res.tempFiles.map(file => {
return this.uploadImageToOSS(file.tempFilePath)
})
//
Promise.all(uploadPromises).then(urls => {
this.reasonImages = this.reasonImages.concat(urls)
uni.hideLoading()
uni.showToast({
title: '上传成功',
icon: 'success'
})
}).catch(error => {
console.error('上传失败:', error)
uni.hideLoading()
uni.showToast({
title: '上传失败,请重试',
icon: 'none'
})
})
},
fail: (error) => {
console.error('选择图片失败:', error)
uni.showToast({
title: '选择图片失败',
icon: 'none'
})
}
})
},
async uploadImageToOSS(filePath) {
try {
// 使OSS
const url = await OSS.ossUpload(filePath)
return url
} catch (error) {
console.error('OSS上传失败:', error)
throw error
}
},
removeReasonImg(idx) {
this.reasonImages.splice(idx, 1)
},
@ -194,15 +443,140 @@ export default {
if (this.currentReasonItem) {
this.currentReasonItem.images = [...this.reasonImages]
this.currentReasonItem.reasons = [...this.reasonChecked]
// inspectData
this.updateInspectData()
}
this.closeReasonPopup()
},
updateInspectData() {
if (!this.inspectData || !this.currentReasonItem) return
// IDID
const selectedReasonIds = []
this.reasonChecked.forEach((checked, index) => {
if (checked) {
selectedReasonIds.push(index.toString())
}
})
// ID
const testingInstructions = selectedReasonIds.join(',')
// URL
const testingImages = this.reasonImages.join(',')
// inspectData
if (this.isQualifiedItem(this.currentReasonItem)) {
this.updateQualifiedItemInspectData(testingInstructions, testingImages)
} else if (this.isUnqualifiedItem(this.currentReasonItem)) {
this.updateUnqualifiedItemInspectData(testingInstructions, testingImages)
} else if (this.isUnrecyclableItem(this.currentReasonItem)) {
this.updateUnrecyclableItemInspectData(testingInstructions, testingImages)
}
console.log('更新后的inspectData:', JSON.stringify(this.inspectData, null, 2))
},
isQualifiedItem(item) {
return this.qualifiedList.some(qualified => qualified.id === item.id)
},
isUnqualifiedItem(item) {
return this.unqualifiedGroups.some(group =>
group.items.some(unqualified => unqualified.id === item.id)
)
},
isUnrecyclableItem(item) {
return this.unrecyclableList.some(unrecyclable => unrecyclable.id === item.id)
},
updateQualifiedItemInspectData(testingInstructions, testingImages) {
const inspectItem = this.inspectData.list.find(item => item.id == this.currentReasonItem.id)
if (inspectItem && inspectItem.commonOrderList) {
// 0
inspectItem.commonOrderList.forEach(commonItem => {
if (commonItem.testingStatus === 0) {
commonItem.testingInstructions = testingInstructions
commonItem.testingImages = testingImages
}
})
}
},
updateUnqualifiedItemInspectData(testingInstructions, testingImages) {
// commonOrderListID
this.unqualifiedGroups.forEach(group => {
const targetItem = group.items.find(item => item.id === this.currentReasonItem.id)
if (targetItem) {
// inspectData
const inspectItem = this.inspectData.list.find(item => item.id == group.id)
if (inspectItem && inspectItem.commonOrderList) {
// IDcommonOrderList
const commonItem = inspectItem.commonOrderList.find(common => common.id === targetItem.id)
if (commonItem) {
commonItem.testingInstructions = testingInstructions
commonItem.testingImages = testingImages
}
}
}
})
},
updateUnrecyclableItemInspectData(testingInstructions, testingImages) {
const inspectItem = this.inspectData.list.find(item => item.id == this.currentReasonItem.id)
if (inspectItem && inspectItem.commonOrderList) {
// 2
inspectItem.commonOrderList.forEach(commonItem => {
if (commonItem.testingStatus === 2) {
commonItem.testingInstructions = testingInstructions
commonItem.testingImages = testingImages
}
})
}
},
lockScroll() {
//
this.isPopupOpen = true
},
unlockScroll() {
//
this.isPopupOpen = false
},
async onRefresh() {
await this.refreshData && this.refreshData()
},
refreshData() {
//
//
},
getItemName(id) {
if (this.order && this.order.commonOrderList) {
const orderItem = this.order.commonOrderList.find(item => item.id == id)
return orderItem ? (orderItem.title || '未知商品') : '未知商品'
}
return '未知商品'
},
getItemBrand(id) {
if (this.order && this.order.commonOrderList) {
const orderItem = this.order.commonOrderList.find(item => item.id == id)
return orderItem ? (orderItem.pinName || '') : ''
}
return ''
},
parseTestingInstructions(instructions) {
// ID
const reasonArray = Array(this.reasonOptions.length).fill(false)
if (instructions) {
const selectedIds = instructions.split(',').map(id => id.trim()).filter(id => id)
selectedIds.forEach(id => {
const index = parseInt(id)
if (index >= 0 && index < reasonArray.length) {
reasonArray[index] = true
}
})
}
return reasonArray
},
hasSelectedReason(item) {
//
return (item.reasons && item.reasons.some(checked => checked)) ||
(item.images && item.images.length > 0)
}
}
}
@ -214,6 +588,12 @@ export default {
background: #f8f8f8;
display: flex;
flex-direction: column;
&.popup-open {
overflow: hidden;
position: fixed;
width: 100%;
height: 100vh;
}
}
.nav-bar {
display: flex;
@ -247,7 +627,7 @@ export default {
}
}
.main-content {
margin-top: calc(150rpx + var(--status-bar-height));
margin-top: calc(200rpx + var(--status-bar-height));
display: flex;
flex-direction: column;
background: none;
@ -261,7 +641,7 @@ export default {
padding: 24px 24px 0 24px;
}
.card-title {
font-size: 18px;
font-size: 16px;
font-weight: bold;
color: #222;
margin-bottom: 18px;
@ -275,7 +655,7 @@ export default {
.status-tag {
background: #fff7e6;
color: #ffb400;
font-size: 14px;
font-size: 12px;
border-radius: 12px;
padding: 2px 14px;
font-weight: 400;
@ -289,29 +669,47 @@ export default {
.row-main {
display: flex;
align-items: center;
.goods-name-section {
display: flex;
flex-direction: column;
margin-right: 8px;
.goods-name {
font-size: 14px;
font-weight: bold;
color: #222;
line-height: 1.2;
}
.goods-brand {
font-size: 11px;
color: #999;
font-weight: normal;
line-height: 1.2;
margin-top: 2px;
}
}
.row-name {
font-size: 16px;
font-size: 14px;
font-weight: bold;
color: #222;
margin-right: 8px;
}
.row-price {
font-size: 15px;
font-size: 13px;
color: #ffb400;
font-weight: bold;
margin-right: 8px;
.row-unit {
font-size: 13px;
font-size: 11px;
color: #bbb;
}
}
.row-count {
font-size: 15px;
font-size: 13px;
color: #888;
margin-right: 8px;
}
.row-total {
font-size: 16px;
font-size: 14px;
color: #222;
font-weight: bold;
margin-left: auto;
@ -322,17 +720,17 @@ export default {
align-items: center;
margin-top: 8px;
.reason-label {
font-size: 15px;
font-size: 13px;
color: #bbb;
min-width: 80px;
}
.reason-input {
flex: 1;
height: 40px;
height: 36px;
border-radius: 12px;
background: #f6f6f6;
border: none;
font-size: 16px;
font-size: 14px;
color: #222;
padding-left: 12px;
margin-left: 8px;
@ -341,18 +739,22 @@ export default {
flex: 1;
display: flex;
align-items: center;
height: 40px;
height: 36px;
border-radius: 12px;
background: #f6f6f6;
font-size: 16px;
font-size: 14px;
color: #bbb;
padding-left: 12px;
margin-left: 8px;
justify-content: space-between;
justify-content: flex-end;
}
.reason-placeholder {
color: #bbb;
font-size: 16px;
font-size: 14px;
&.selected {
color: #52c41a;
font-weight: 500;
}
}
}
.info-card {
@ -367,12 +769,12 @@ export default {
align-items: center;
margin-bottom: 16px;
.info-label {
font-size: 15px;
font-size: 13px;
color: #bbb;
min-width: 80px;
}
.info-value {
font-size: 15px;
font-size: 13px;
color: #222;
margin-left: 8px;
}
@ -416,70 +818,90 @@ export default {
padding: 0 18px;
}
}
.reason-popup-wrapper {
z-index: 10000 !important;
}
.reason-popup-wrapper .uni-popup__wrapper {
z-index: 10000 !important;
}
.reason-popup {
background: #fff;
border-radius: 32px 32px 0 0;
padding: 0 0 24px 0;
border-radius: 24px 24px 0 0;
padding: 0;
height: 75vh;
position: relative;
z-index: 9999;
.popup-header {
display: flex;
align-items: center;
justify-content: center;
height: 56px;
border-bottom: 1px solid #f5f5f5;
height: 60px;
border-bottom: 1px solid #f0f0f0;
position: relative;
.popup-close {
position: absolute;
left: 24px;
color: #888;
font-size: 18px;
left: 20px;
color: #666;
font-size: 16px;
}
.popup-title {
font-size: 20px;
font-weight: bold;
font-size: 18px;
font-weight: 600;
color: #222;
}
}
.popup-content {
height: calc(75vh - 60px - 82px);
overflow-y: auto;
}
.popup-section {
padding: 24px 24px 0 24px;
padding: 0 20px 24px 20px;
&:first-child {
padding-top: 24px;
}
.section-label {
font-size: 16px;
color: #888;
margin-bottom: 12px;
color: #222;
margin-bottom: 16px;
display: block;
font-weight: 500;
}
.img-list {
display: flex;
gap: 12px;
margin-bottom: 16px;
margin-bottom: 32px;
.img-item {
width: 80px;
height: 80px;
border-radius: 16px;
background: #f6f6f6;
border-radius: 12px;
background: #f8f8f8;
position: relative;
.img {
width: 100%;
height: 100%;
border-radius: 16px;
border-radius: 12px;
object-fit: cover;
}
.img-del {
position: absolute;
top: 4px;
right: 4px;
width: 20px;
height: 20px;
background: rgba(0,0,0,0.3);
top: -6px;
right: -6px;
width: 24px;
height: 24px;
background: rgba(0,0,0,0.6);
color: #fff;
border-radius: 50%;
text-align: center;
line-height: 20px;
line-height: 24px;
font-size: 16px;
font-weight: bold;
}
&.add {
display: flex;
align-items: center;
justify-content: center;
background: #f6f6f6;
background: #f8f8f8;
border: 2px dashed #ddd;
color: #bbb;
}
}
@ -487,39 +909,57 @@ export default {
.reason-row {
display: flex;
align-items: center;
padding: 18px 0;
border-bottom: 1px solid #f5f5f5;
padding: 16px 0;
border-bottom: 1px solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.checkbox {
width: 22px;
height: 22px;
border-radius: 6px;
width: 20px;
height: 20px;
border-radius: 4px;
border: 2px solid #ddd;
margin-right: 16px;
margin-right: 12px;
background: #fff;
position: relative;
&.checked {
border-color: #ffb400;
background: #ffb400;
&::after {
content: '✓';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
font-size: 12px;
font-weight: bold;
}
}
}
.reason-text {
font-size: 16px;
color: #222;
line-height: 1.4;
}
}
}
.popup-save-btn {
width: 90%;
margin: 32px auto 0 auto;
height: 52px;
border-radius: 26px;
position: fixed;
bottom: 34px;
left: 20px;
right: 20px;
height: 48px;
border-radius: 24px;
background: linear-gradient(90deg, #ffd01e 0%, #ffac04 100%);
color: #fff;
font-size: 20px;
font-weight: bold;
font-size: 18px;
font-weight: 600;
border: none;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(255, 172, 4, 0.3);
}
}
</style>

+ 748
- 464
pages/manager/inspect.vue
File diff suppressed because it is too large
View File


+ 12
- 5
pages/manager/order-detail.vue View File

@ -80,13 +80,14 @@
<image :src="item.image" class="custom-goods-img" />
<view class="custom-goods-info">
<text class="custom-goods-name">{{ item.title }}</text>
<text class="custom-goods-desc">{{ item.pinName }}</text>
<text class="custom-goods-desc">{{ item.details }}</text>
<view class="custom-goods-meta">
<text class="custom-goods-price">¥{{ item.onePrice }}<text class="custom-goods-unit"> /</text></text>
<text class="custom-goods-count">x{{ item.num }}</text>
</view>
</view>
<text class="custom-goods-total">¥{{ item.price }}</text>
<text class="custom-goods-total">¥{{ item.estimatedPrice }}</text>
</view>
</view>
</view>
@ -119,13 +120,14 @@
<image :src="item.image" class="custom-goods-img" />
<view class="custom-goods-info">
<text class="custom-goods-name">{{ item.title }}</text>
<text class="custom-goods-desc">{{ item.pinName }}</text>
<text class="custom-goods-desc">{{ item.details }}</text>
<view class="custom-goods-meta">
<text class="custom-goods-price">¥{{ item.onePrice }}<text class="custom-goods-unit"> /</text></text>
<text class="custom-goods-count">x{{ item.num }}</text>
</view>
</view>
<text class="custom-goods-total">¥{{ item.price }}</text>
<text class="custom-goods-total">¥{{ item.estimatedPrice }}</text>
</view>
</view>
</view>
@ -161,13 +163,14 @@
<image :src="item.image" class="custom-goods-img" />
<view class="custom-goods-info">
<text class="custom-goods-name">{{ item.title }}</text>
<text class="custom-goods-desc">{{ item.pinName }}</text>
<text class="custom-goods-desc">{{ item.details }}</text>
<view class="custom-goods-meta">
<text class="custom-goods-price">¥{{ item.onePrice }}<text class="custom-goods-unit"> /</text></text>
<text class="custom-goods-count">x{{ item.num }}</text>
</view>
</view>
<text class="custom-goods-total">¥{{ item.price }}</text>
<text class="custom-goods-total">¥{{ item.estimatedPrice }}</text>
</view>
</view>
</view>
@ -262,7 +265,10 @@ export default {
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
},
goToInspect() {
uni.navigateTo({ url: '/pages/manager/inspect' })
const orderData = encodeURIComponent(JSON.stringify(this.order))
uni.navigateTo({
url: `/pages/manager/inspect?orderData=${orderData}`
})
},
async onUserStatClick() {
if (!this.order || !this.order.userId) return;
@ -361,7 +367,7 @@ $order-card-padding: 40px 28px;
}
}
.main-content {
margin-top: calc(150rpx + var(--status-bar-height));
margin-top: calc(200rpx + var(--status-bar-height));
width: 100vw;
min-width: 0;
box-sizing: border-box;
@ -545,6 +551,7 @@ $order-card-padding: 40px 28px;
position: relative;
min-height: 36px;
justify-content: space-between;
align-items: center;
.base-label-wrap { min-width: 80px; text-align: left; color: #8b8b8b; font-size: 13px;}
.base-value-wrap { display: flex; align-items: center; flex: 1; justify-content: flex-end; }
.base-value { color: #222; font-size: 15px; font-weight: 600; word-break: break-all; text-align: right; }


+ 27
- 12
pages/manager/order.vue View File

@ -146,8 +146,8 @@ export default {
searchMode: false,
searchText: '',
historyOrderMode: false,
pageNum: 1,
pageSize: 10,
pageNo: 1,
pageSize: 3,
hasMore: true,
isLoading: false,
userId: ''
@ -207,9 +207,10 @@ export default {
},
onTabChange(idx) {
this.currentTab = idx
this.pageNum = 1
this.pageNo = 1
this.hasMore = true
this.orderList = []
this.isLoading = false
this.fetchOrderList()
},
onSearchIconClick() {
@ -236,18 +237,22 @@ export default {
async onRefresh() {
await this.refreshData && this.refreshData()
},
fetchOrderList(isLoadMore = false) {
if (this.isLoading || (!isLoadMore && !this.hasMore)) return
fetchOrderList(isLoadMore) {
if (this.isLoading) return
if (isLoadMore && !this.hasMore) return
console.log(isLoadMore,'isLoadMore')
this.isLoading = true
const params = {
pageNum: this.pageNum,
pageNo: isLoadMore ? this.pageNo + 1 : 1,
pageSize: this.pageSize
}
console.log(params,'params')
if (this.userId) {
params.userId = this.userId;
}
this.$api && this.$api('getOrderList', params, res => {
if (res && res.code === 200 && res.result && res.result.records) {
console.log(res.result,'res.result.records')
const newOrders = res.result.records.map(order => {
const statusInfo = this.getOrderStatusInfo(order.status, order.state)
return {
@ -265,13 +270,22 @@ export default {
status: this.getOrderStatus(order.status, order.state)
}
})
if (isLoadMore) {
this.orderList = [...this.orderList, ...newOrders]
//
const existingIds = new Set(this.orderList.map(order => order.id))
const uniqueNewOrders = newOrders.filter(order => !existingIds.has(order.id))
this.orderList = [...this.orderList, ...uniqueNewOrders]
this.pageNo = params.pageNo +1
} else {
this.orderList = newOrders
this.pageNo = 1
}
//
this.hasMore = newOrders.length === this.pageSize
this.pageNum = isLoadMore ? this.pageNum + 1 : 1
} else {
this.hasMore = false
}
this.isLoading = false
})
@ -280,13 +294,13 @@ export default {
// if (state === 3) {
// return { label: '', class: 'gray' }
// }
if (status === 1 ) {
if (status === 1 && state != 3) {
return { label: '已预约', class: 'green' }
} else if (state === 1) {
return { label: '待质检', class: 'orange' }
} else if (status === 3) {
return { label: '已结款', class: 'blue' }
} else if (status === 1 && state === 3) {
} else if (state ===4) {
return { label: '已驳回', class: 'red' }
}
return { label: '未知状态', class: 'gray' }
@ -305,7 +319,7 @@ export default {
if (status === 3 ) return 3
// -
if (status === 1 && state === 3) return 4
if (state ===4) return 4
return -1
},
@ -347,9 +361,10 @@ export default {
},
},
onPullDownRefresh() {
this.pageNum = 1;
this.pageNo = 1;
this.hasMore = true;
this.orderList = [];
this.isLoading = false;
this.fetchOrderList();
uni.stopPullDownRefresh();
},


+ 5
- 3
pages/subcomponent/detail.vue View File

@ -111,14 +111,15 @@
<view class="goods-item" v-for="(item, index) in clothesList" :key="index">
<image class="goods-img" :src="item.image" mode="aspectFit"></image>
<view class="goods-info">
<text class="goods-name">{{ item.name }}</text>
<text class="goods-name">{{ item.title }}</text>
<text class="desc">{{ item.pinName }}</text>
<text class="goods-desc">{{ item.details }}</text>
<view class="goods-meta">
<text class="goods-price">¥ {{ item.onePrice }}<text class="goods-unit"> /</text></text>
<text class="goods-count">x{{ item.num }}</text>
</view>
</view>
<text class="goods-total">¥{{ item.price }}</text>
<text class="goods-total">¥{{ item.estimatedPrice }}</text>
</view>
</view>
</view>
@ -359,7 +360,7 @@ export default {
//
this.address = res.result.address + (res.result.addressDetail || '')
this.appointmentTime = res.result.goTime || ''
this.estimatePrice = res.result.price || ''
this.estimatePrice = res.result.estimatedPrice || ''
this.finalPrice = res.result.price || ''
this.clothesList = res.result.commonOrderList || []
this.expressCompany = res.result.wliu || ''
@ -750,6 +751,7 @@ letter-spacing: 0%;
font-weight: bold;
margin-bottom: 6rpx;
}
.desc { font-size: 24rpx; color: #999; margin: 4rpx 0 8rpx 0; }
.goods-desc {
font-size: 24rpx;
color: #bcbcbc;


+ 1
- 0
pages/subcomponent/promotion.vue View File

@ -165,6 +165,7 @@ export default {
},
onShow(){
this.getMyPromotionInfo()
},
onPullDownRefresh() {
this.getUserInfoByToken()


Loading…
Cancel
Save