Browse Source

'修改页面样式'

master
Lj 3 weeks ago
parent
commit
1f7ace96f4
6 changed files with 446 additions and 144 deletions
  1. +317
    -24
      pages/component/home.vue
  2. +1
    -1
      pages/subcomponent/detail.vue
  3. +5
    -5
      pages/subcomponent/inspection-detail.vue
  4. +63
    -54
      pages/subcomponent/inspection-report.vue
  5. +41
    -41
      pages/subcomponent/order.vue
  6. +19
    -19
      pages/subcomponent/promo-qrcode.vue

+ 317
- 24
pages/component/home.vue View File

@ -5,32 +5,47 @@
<swiper :indicator-dots="false" :autoplay="true" :interval="3000" :duration="500" circular
style="width: 100%; height: 400rpx;">
<swiper-item v-for="(item, index) in bannerList" :key="item.id || index">
<view v-if="item.type == 1" class="video-container" @click="playVideo(item, index)">
<view v-if="item.type == 1" class="video-container">
<!-- 预览状态显示封面图 -->
<image
v-if="!videoPlayingStates[index]"
:src="item.image || ''"
mode="aspectFill"
style="width: 100%; height: 100%;"
class="video-poster"
@click="playVideoFullscreen(item, index)"
/>
<!-- 播放状态显示视频 -->
<video
v-else
:id="`video-${index}`"
:src="item.voUrl"
:autoplay="false"
:muted="true"
:autoplay="true"
:muted="false"
:loop="false"
:controls="true"
:show-play-btn="true"
:show-center-play-btn="true"
:show-center-play-btn="false"
:show-fullscreen-btn="true"
:show-progress="true"
:show-mute-btn="true"
:enable-progress-gesture="true"
:enable-play-gesture="true"
object-fit="cover"
:poster="item.image || ''"
style="width: 100%; height: 100%;"
@fullscreenchange="onFullscreenChange"
@play="onVideoPlay(index)"
@pause="onVideoPause(index)"
@ended="onVideoEnded(index)"
></video>
<view v-if="!videoPlayingStates[index]" class="video-overlay">
<view class="play-button">
<uni-icons type="play-filled" size="60" color="#fff"></uni-icons>
</view>
<!-- 播放按钮覆盖层 -->
<view v-if="!videoPlayingStates[index]" class="video-overlay" @click="playVideoFullscreen(item, index)">
<!-- <view class="play-button-large">
<uni-icons type="play-filled" size="50" color="#fff"></uni-icons>
</view> -->
</view>
</view>
<image v-else :src="item.image" mode="aspectFill" style="width: 100%; height: 100%;" />
<image v-else :src="item.image" mode="aspectFill" style="width: 100%; height: 100%;" @click="showServiceQrcode" />
</swiper-item>
</swiper>
</view>
@ -180,6 +195,37 @@
</template>
</uv-tabbar-item>
</uv-tabbar>
<!-- 客服二维码弹窗 -->
<view v-if="showQrcodeModal" class="qrcode-modal-mask" @click="closeQrcodeModal">
<view class="qrcode-modal-content" @click.stop>
<view class="qrcode-modal-header">
<text class="qrcode-modal-title">联系客服</text>
<view class="qrcode-modal-close" @click="closeQrcodeModal">
<uni-icons type="close" size="24" color="#999"></uni-icons>
</view>
</view>
<view class="qrcode-modal-body">
<image
v-if="serviceQrcodeUrl"
:src="serviceQrcodeUrl"
mode="aspectFit"
class="qrcode-modal-img"
:show-menu-by-longpress="true"
@longpress="onQrcodeLongPress"
></image>
<view v-else class="qrcode-placeholder">
<text>二维码加载中...</text>
</view>
<text class="qrcode-modal-tip">长按识别二维码添加客服微信</text>
<!-- <view class="qrcode-actions">
<button class="save-btn" @click="saveQrcodeToAlbum" v-if="serviceQrcodeUrl">
保存到相册
</button>
</view> -->
</view>
</view>
</view>
</view>
</template>
@ -194,6 +240,7 @@
priceList: [],
records: [],
videoPlayingStates: {}, //
showQrcodeModal: false, //
destinations: [
// {
// icon: '/static/home/.png',
@ -242,6 +289,10 @@
sbk_cion() {
const item = getApp().globalData.configData.find(i => i.keyName === 'sbk_cion')
return item ? item.keyContent : ''
},
serviceQrcodeUrl() {
const item = getApp().globalData.configData.find(i => i.keyName === 'kefu_code')
return item ? item.keyContent : ''
}
},
methods: {
@ -370,15 +421,120 @@
},
//
playVideo(item, index) {
const videoContext = uni.createVideoContext(`video-${index}`, this);
if (this.videoPlayingStates[index]) {
//
videoContext.pause();
} else {
//
videoContext.play();
playVideoFullscreen(item, index) {
if (!this.videoPlayingStates[index]) {
//
this.$set(this.videoPlayingStates, index, true);
//
this.$nextTick(() => {
setTimeout(() => {
const videoContext = uni.createVideoContext(`video-${index}`, this);
if (videoContext) {
//
videoContext.requestFullScreen({
direction: -1 //
});
}
}, 200);
});
}
},
//
showServiceQrcode() {
this.showQrcodeModal = true;
},
//
closeQrcodeModal() {
this.showQrcodeModal = false;
},
//
onQrcodeLongPress() {
console.log('长按二维码');
// show-menu-by-longpress="true"
//
uni.showToast({
title: '长按识别二维码',
icon: 'none',
duration: 1500
});
},
//
saveQrcodeToAlbum() {
if (!this.serviceQrcodeUrl) {
uni.showToast({
title: '二维码还未加载完成',
icon: 'none'
});
return;
}
//
uni.getSetting({
success: (res) => {
if (!res.authSetting['scope.writePhotosAlbum']) {
//
uni.authorize({
scope: 'scope.writePhotosAlbum',
success: () => {
this.doSaveQrcodeImage();
},
fail: () => {
//
uni.showModal({
title: '提示',
content: '需要您授权保存相册权限',
showCancel: false,
success: () => {
uni.openSetting();
}
});
}
});
} else {
//
this.doSaveQrcodeImage();
}
}
});
},
//
doSaveQrcodeImage() {
uni.downloadFile({
url: this.serviceQrcodeUrl,
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
});
},
fail: (err) => {
console.log('保存失败', err);
uni.showToast({
title: '保存失败',
icon: 'none'
});
}
});
}
},
fail: (err) => {
console.log('下载失败', err);
uni.showToast({
title: '下载失败',
icon: 'none'
});
}
});
},
onVideoPlay(index) {
@ -389,8 +545,23 @@
this.$set(this.videoPlayingStates, index, false);
},
onVideoEnded(index) {
//
this.$set(this.videoPlayingStates, index, false);
},
onFullscreenChange(e) {
console.log('全屏状态改变:', e.detail);
const videoIndex = e.target.id.replace('video-', '');
if (e.detail.fullScreen) {
//
console.log('进入全屏模式,方向:', e.detail.direction);
} else {
// 退
console.log('退出全屏模式,回到预览状态');
this.$set(this.videoPlayingStates, videoIndex, false);
}
},
//
initializePageData() {
@ -487,6 +658,15 @@
width: 100%;
height: 100%;
.video-poster {
cursor: pointer;
transition: transform 0.2s ease;
&:active {
transform: scale(0.98);
}
}
.video-overlay {
position: absolute;
top: 0;
@ -494,21 +674,28 @@
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.3);
z-index: 10;
cursor: pointer;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 10;
.play-button {
width: 120rpx;
height: 120rpx;
background: rgba(0, 0, 0, 0.6);
.play-button-large {
width: 100rpx;
height: 100rpx;
background: rgba(0, 0, 0, 0.7);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
backdrop-filter: blur(10rpx);
transition: all 0.3s ease;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.3);
&:active {
transform: scale(0.9);
background: rgba(0, 0, 0, 0.8);
}
}
}
}
@ -1031,4 +1218,110 @@
transform: scale(1);
}
}
//
.qrcode-modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
backdrop-filter: blur(5rpx);
}
.qrcode-modal-content {
background: #fff;
border-radius: 24rpx;
width: 600rpx;
max-width: 90vw;
animation: fadeInScale 0.3s ease;
overflow: hidden;
}
.qrcode-modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 40rpx 40rpx 20rpx 40rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.qrcode-modal-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.qrcode-modal-close {
padding: 10rpx;
margin: -10rpx;
}
.qrcode-modal-body {
padding: 40rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.qrcode-modal-img {
width: 400rpx;
height: 400rpx;
border-radius: 16rpx;
margin-bottom: 30rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
}
.qrcode-placeholder {
width: 400rpx;
height: 400rpx;
border-radius: 16rpx;
margin-bottom: 30rpx;
background: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
text {
color: #999;
font-size: 28rpx;
}
}
.qrcode-modal-tip {
font-size: 28rpx;
color: #666;
text-align: center;
line-height: 1.4;
margin-bottom: 20rpx;
}
.qrcode-actions {
display: flex;
justify-content: center;
margin-top: 20rpx;
}
.save-btn {
background: linear-gradient(90deg, #ff8917, #ffd01e);
color: #fff;
border: none;
border-radius: 25rpx;
padding: 16rpx 40rpx;
font-size: 28rpx;
font-weight: bold;
&::after {
border: none;
}
&:active {
opacity: 0.8;
}
}
</style>

+ 1
- 1
pages/subcomponent/detail.vue View File

@ -240,7 +240,7 @@ export default {
},
viewReport() {
// orderId
uni.navigateTo({
uni.navigateTo({
url: `/pages/subcomponent/inspection-report?orderId=${this.orderId}`
})
},


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

@ -183,12 +183,12 @@ export default {
}))
} else {
//
this.problemList = [
{
this.problemList = [
{
title: '质量问题',
images: this.testingImages
}
]
images: this.testingImages
}
]
}
} else if (this.status === 'qualified') {
this.qualifiedImages = this.testingImages


+ 63
- 54
pages/subcomponent/inspection-report.vue View File

@ -30,63 +30,69 @@
</view> -->
<!-- 主内容区卡片悬浮覆盖打钩区 -->
<view class="main-content">
<view v-if="showQualified && goodsList.length" class="inspection-card">
<view class="report-title">质检合格</view>
<view class="goods-list">
<view class="goods-item" v-for="(item, i) in goodsList" :key="i" @tap="goToInspectionDetail('qualified')">
<image class="goods-img" :src="item.img" mode="aspectFit" />
<view class="goods-info">
<view class="goods-row">
<view class="goods-name">{{item.name}}</view>
<view v-if="item.detail" class="detail-link">查看详情 <uni-icons type="right" size="16" color="#bbb" /></view>
</view>
<view class="goods-desc">{{item.desc}}</view>
<view class="goods-bottom-row">
<view class="goods-price-row">
<text class="goods-price">{{item.price}}</text>
<text class="goods-unit">/</text>
<text class="goods-count">x{{item.count}}</text>
<scroll-view
scroll-y
class="main-content"
enhanced
:show-scrollbar="false"
>
<view class="content-wrapper">
<view v-if="showQualified && goodsList.length" class="inspection-card">
<view class="report-title">质检合格</view>
<view class="goods-list">
<view class="goods-item" v-for="(item, i) in goodsList" :key="i" @tap="goToInspectionDetail('qualified')">
<image class="goods-img" :src="item.img" mode="aspectFit" />
<view class="goods-info">
<view class="goods-row">
<view class="goods-name">{{item.name}}</view>
<view v-if="item.detail" class="detail-link">查看详情 <uni-icons type="right" size="16" color="#bbb" /></view>
</view>
<view class="goods-desc">{{item.desc}}</view>
<view class="goods-bottom-row">
<view class="goods-price-row">
<text class="goods-price">{{item.price}}</text>
<text class="goods-unit">/</text>
<text class="goods-count">x{{item.count}}</text>
</view>
<view class="goods-total">{{item.total}}</view>
</view>
<view class="goods-total">{{item.total}}</view>
</view>
</view>
</view>
<view class="summary-row">
<text>件数<text class="highlight">{{totalCount}}</text> </text>
<text>结算金额<text class="highlight">{{totalAmount}}</text></text>
</view>
</view>
<view class="summary-row">
<text>件数<text class="highlight">{{totalCount}}</text> </text>
<text>结算金额<text class="highlight">{{totalAmount}}</text></text>
</view>
</view>
<view v-if="showProblem && problemList.length" class="inspection-card problem-card">
<view class="report-title">质量问题</view>
<view class="goods-list">
<view class="goods-item" v-for="(item, i) in problemList" :key="i" @tap="goToInspectionDetail('problem')">
<image class="goods-img" :src="item.img" mode="aspectFit" />
<view class="goods-info">
<view class="goods-row">
<view class="goods-name">{{item.name}}</view>
<view v-if="item.detail" class="detail-link">查看详情 <uni-icons type="right" size="16" color="#bbb" /></view>
</view>
<view class="goods-desc">{{item.desc}}</view>
<view class="goods-bottom-row">
<view class="goods-price-row problem-price-row">
<!-- <text class="goods-price">{{item.price}}</text>
<text class="goods-unit">/</text> -->
<text class="goods-count">x{{item.count}}</text>
<view v-if="showProblem && problemList.length" class="inspection-card problem-card">
<view class="report-title">质量问题</view>
<view class="goods-list">
<view class="goods-item" v-for="(item, i) in problemList" :key="i" @tap="goToInspectionDetail('problem')">
<image class="goods-img" :src="item.img" mode="aspectFit" />
<view class="goods-info">
<view class="goods-row">
<view class="goods-name">{{item.name}}</view>
<view v-if="item.detail" class="detail-link">查看详情 <uni-icons type="right" size="16" color="#bbb" /></view>
</view>
<view class="goods-desc">{{item.desc}}</view>
<view class="goods-bottom-row">
<view class="goods-price-row problem-price-row">
<!-- <text class="goods-price">{{item.price}}</text>
<text class="goods-unit">/</text> -->
<text class="goods-count">x{{item.count}}</text>
</view>
<!-- <view class="goods-total">{{item.total}}</view> -->
</view>
<!-- <view class="goods-total">{{item.total}}</view> -->
</view>
</view>
</view>
</view>
<view class="summary-row">
<text>件数<text class="highlight">{{problemCount}}</text> </text>
<text>结算金额<text class="highlight"> 0</text></text>
<view class="summary-row">
<text>件数<text class="highlight">{{problemCount}}</text> </text>
<text>结算金额<text class="highlight"> 0</text></text>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
@ -243,9 +249,7 @@ export default {
.inspection-page {
min-height: 100vh;
background: #422525;
height: 100vh;
overflow: hidden;
// padding-bottom: calc(env(safe-area-inset-bottom) + 120rpx);
position: relative;
}
.nav-bar {
@ -361,18 +365,21 @@ export default {
.main-content {
margin-top: 20rpx;
// padding-top: 88rpx;
background: linear-gradient(180deg, #fef7e6 0%, #fff 50%);
height: calc(100vh - 88rpx);
height: calc(100vh - 200rpx);
width: 100vw;
box-sizing: border-box;
position: relative;
z-index: 11;
border-radius: 40rpx 40rpx 0 0;
overflow: hidden;
}
.content-wrapper {
display: flex;
flex-direction: column;
align-items: center;
padding-bottom: calc(env(safe-area-inset-bottom) + 60rpx);
min-height: 100%;
}
.inspection-card {
@ -380,11 +387,12 @@ export default {
border-radius: 32rpx;
box-shadow: 0 8rpx 32rpx rgba(60, 167, 250, 0.08);
padding: 40rpx 32rpx 32rpx 32rpx;
margin: 24rpx auto 0 auto;
margin: 24rpx auto 0 auto;
width: calc(100vw - 64rpx);
max-width: 700rpx;
display: flex;
flex-direction: column;
flex-shrink: 0;
.report-title {
font-size: 32rpx;
font-weight: bold;
@ -500,7 +508,8 @@ export default {
}
.problem-card {
margin-top: 40rpx;
margin-top: 24rpx;
margin-bottom: 40rpx;
}
.problem-price-row {


+ 41
- 41
pages/subcomponent/order.vue View File

@ -126,57 +126,57 @@ export default {
async fetchOrderList(isLoadMore = false) {
this.loading = true
try {
let statusArr = []
if (this.currentTab === 1) statusArr = [0, 1, 2] //
else if (this.currentTab === 2) statusArr = [3] //
else statusArr = [] //
let allOrders = []
if (statusArr.length === 0) {
//
let statusArr = []
if (this.currentTab === 1) statusArr = [0, 1, 2] //
else if (this.currentTab === 2) statusArr = [3] //
else statusArr = [] //
let allOrders = []
if (statusArr.length === 0) {
//
await new Promise(resolve => {
this.$api('getOrderListPage', { pageSize: this.pageSize, current: this.page }, res => {
if (res && res.code === 200 && res.result && Array.isArray(res.result.records)) {
allOrders = res.result.records
if (isLoadMore) {
this.orderList = this.orderList.concat(allOrders)
} else {
this.orderList = allOrders
}
this.hasMore = allOrders.length === this.pageSize
}
resolve()
})
})
} else {
//
for (let status of statusArr) {
await new Promise(resolve => {
this.$api('getOrderListPage', { pageSize: this.pageSize, current: this.page }, res => {
this.$api('getOrderListPage', { status, pageSize: this.pageSize, current: this.page }, res => {
if (res && res.code === 200 && res.result && Array.isArray(res.result.records)) {
allOrders = res.result.records
if (isLoadMore) {
this.orderList = this.orderList.concat(allOrders)
} else {
this.orderList = allOrders
}
this.hasMore = allOrders.length === this.pageSize
allOrders = allOrders.concat(res.result.records)
}
resolve()
})
})
}
//
const map = {}
allOrders = allOrders.filter(item => {
if (map[item.id]) return false
map[item.id] = 1
return true
})
if (isLoadMore) {
this.orderList = this.orderList.concat(allOrders)
} else {
//
for (let status of statusArr) {
await new Promise(resolve => {
this.$api('getOrderListPage', { status, pageSize: this.pageSize, current: this.page }, res => {
if (res && res.code === 200 && res.result && Array.isArray(res.result.records)) {
allOrders = allOrders.concat(res.result.records)
}
resolve()
})
})
}
//
const map = {}
allOrders = allOrders.filter(item => {
if (map[item.id]) return false
map[item.id] = 1
return true
})
if (isLoadMore) {
this.orderList = this.orderList.concat(allOrders)
} else {
this.orderList = allOrders
}
this.hasMore = allOrders.length === this.pageSize
this.orderList = allOrders
}
this.hasMore = allOrders.length === this.pageSize
}
} catch (error) {
console.error('获取订单列表失败:', error)
} finally {
this.loading = false
this.loading = false
}
},
switchTab(index) {
@ -259,7 +259,7 @@ export default {
uni.stopPullDownRefresh()
}, 1000)
}
}
}
}
}
</script>


+ 19
- 19
pages/subcomponent/promo-qrcode.vue View File

@ -10,20 +10,20 @@
<!-- 页面内容 -->
<view class="content">
<!-- 用户信息 -->
<!-- 用户信息 -->
<view class="user-info-modal">
<view class="avatar-frame">
<view class="avatar-frame">
<image class="avatar-img" :src="userInfo.headImage || '/static/avatar.png'" mode="aspectFill" />
</view>
<view class="nickname">{{userInfo.nickName || '用户'}}</view>
</view>
<!-- 二维码区 -->
<view class="qrcode-modal-section">
<image class="qrcode-img" :src="qrcodeUrl" mode="widthFix" />
<!-- <view class="invite-code">邀请码{{inviteCode}}</view> -->
</view>
<!-- 底部按钮 -->
<view class="bottom-btns-modal">
<view class="nickname">{{userInfo.nickName || '用户'}}</view>
</view>
<!-- 二维码区 -->
<view class="qrcode-modal-section">
<image class="qrcode-img" :src="qrcodeUrl" mode="widthFix" />
<!-- <view class="invite-code">邀请码{{inviteCode}}</view> -->
</view>
<!-- 底部按钮 -->
<view class="bottom-btns-modal">
<button class="btn gray" open-type="share">分享给好友</button>
<button class="btn green" @tap="saveToAlbum">保存到本地</button>
</view>
@ -189,24 +189,24 @@
padding: 0 32rpx;
padding-top: var(--status-bar-height);
background: #fff;
position: fixed;
top: 0;
left: 0;
right: 0;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
box-sizing: border-box;
.back {
padding: 20rpx;
margin-left: -20rpx;
}
}
.title {
flex: 1;
text-align: center;
flex: 1;
text-align: center;
font-size: 34rpx;
font-weight: 500;
color: #222;
color: #222;
}
}


Loading…
Cancel
Save