<template>
|
<view class="order-page">
|
<view class="order-page__nav" :style="{ paddingTop: statusBarHeight + 'px' }">
|
<view class="order-page__nav-inner">
|
<text class="order-page__nav-title">我的订单</text>
|
</view>
|
</view>
|
|
<view class="order-page__search" :style="{ top: navHeight + 'px' }">
|
<view class="order-page__search-box">
|
<u-icon name="search" color="#999999" size="28"></u-icon>
|
<input class="order-page__search-input" v-model="searchKeyword" placeholder="输入姓名、电话、订单编号搜索" placeholder-class="order-page__search-placeholder" @confirm="searchOrder" />
|
</view>
|
</view>
|
|
<view class="order-page__tabs" :style="{ top: (navHeight + 44) + 'px' }">
|
<view v-for="tab in displayTabs" :key="tab.value" class="order-page__tab" :class="{ 'order-page__tab--active': activeTab === tab.value }" @click="activeTab = tab.value">
|
<text class="order-page__tab-text">{{ tab.label }}</text>
|
<view v-if="activeTab === tab.value" class="order-page__tab-line"></view>
|
</view>
|
</view>
|
|
<scroll-view class="order-page__body" scroll-y :style="bodyStyle" @scrolltolower="handleScrollToLower">
|
<view class="order-page__list">
|
<view v-for="(item, index) in orders" :key="item.id" class="order-card" @click="goToOrderDetail(item, index)">
|
<view class="order-card__head">
|
<view class="order-card__head-left">
|
<image class="order-card__badge-icon" :src="getBadgeIcon(item)" mode="widthFix"></image>
|
<text class="order-card__time-text">下单时间:{{ item.createTime }}</text>
|
</view>
|
<text class="order-card__status" :class="{ 'order-card__status--highlight': item.status === 3 || item.status === 4 }">{{ getStatusText(item.status) }}</text>
|
</view>
|
|
<view class="order-card__route-item">
|
<view class="order-card__point order-card__point--pickup">取</view>
|
<view class="order-card__route-texts">
|
<text class="order-card__route-title">{{ item.depositShopName }}</text>
|
<text class="order-card__route-desc">{{ item.depositShopAddress }}</text>
|
</view>
|
</view>
|
|
<view class="order-card__route-item order-card__route-item--delivery">
|
<view class="order-card__point order-card__point--delivery">送</view>
|
<view class="order-card__route-texts">
|
<text class="order-card__route-title">{{ item.takeName }}</text>
|
<text class="order-card__route-desc">{{ item.takeAddress }}</text>
|
</view>
|
</view>
|
|
<view class="order-card__footer">
|
<view class="order-card__arrival">
|
<image class="order-card__clock" src="/static/image/ic_clock@2x.png" mode="aspectFit"></image>
|
<text class="order-card__arrival-text">剩余{{ item.remainMinutes }}分钟</text>
|
</view>
|
<view class="order-card__price-wrap">
|
<text class="order-card__price">¥{{ (item.driverFee / 100).toFixed(2) }}</text>
|
</view>
|
</view>
|
|
<view v-if="getActions(item).length" class="order-card__actions">
|
<view></view>
|
<view style="display: flex;flex-wrap: wrap;gap: 20rpx;">
|
<button
|
v-for="action in getActions(item)"
|
:key="action.text"
|
class="order-card__action-btn"
|
:class="['order-card__action-btn--' + action.type, { 'order-card__action-btn--primary-fill': action.fill }]"
|
hover-class="order-card__action-btn--hover"
|
@click.stop="handleAction(item, action)"
|
>
|
{{ action.text }}
|
</button>
|
</view>
|
|
</view>
|
</view>
|
|
<view v-if="orders.length === 0 && !loading" class="order-page__empty">
|
<image class="order-page__empty-icon" src="/static/image/default_nodata@2x.png" mode="aspectFit"></image>
|
</view>
|
|
<view v-if="loading" class="order-page__loading">
|
<text>加载中...</text>
|
</view>
|
</view>
|
</scroll-view>
|
|
<u-modal
|
:show="showCancelModal"
|
showCancelButton
|
@cancel="showCancelModal = false"
|
cancelColor="#666666"
|
confirmColor="#0055FF"
|
title="取消订单确认"
|
@confirm="confirmCancelOrder">
|
<view style="text-align: center;color: #333333;font-size: 28rpx;font-weight: 400;">
|
您今日还可取消 {{ cancelRemain }} 次订单,次数用尽后今日将无法接单,是否确认取消?
|
</view>
|
</u-modal>
|
|
<u-popup :show="showQRPopup" round="20" mode="bottom">
|
<view class="qrcode">
|
<view class="qrcode-title">
|
<image src="/static/image/ic_close@2x.png" mode="widthFix" style="opacity: 0;"></image>
|
<text>{{ selectedOrder && selectedOrder.status === 4 ? '存件码' : '取货码' }}</text>
|
<image src="/static/image/ic_close@2x.png" mode="widthFix" @click="showQRPopup = false"></image>
|
</view>
|
<view class="qrcode-image">
|
<image v-if="selectedOrder && selectedOrder.driverVerifyCode" :src="'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=' + selectedOrder.driverVerifyCode" mode="widthFix"></image>
|
</view>
|
<view class="qrcode-btn" hover-class="qrcode-btn--hover" @click="showQRPopup = false">关闭</view>
|
</view>
|
</u-popup>
|
|
<u-popup :show="showPhotoPopup" round="20" mode="bottom">
|
<view class="photo-popup">
|
<view class="photo-popup__header">
|
<view class="photo-popup__placeholder"></view>
|
<text class="photo-popup__title">{{ photoPopupTitle }}</text>
|
<image class="photo-popup__close" src="/static/image/ic_close2@2x.png" mode="aspectFit" @click="closePhotoPopup"></image>
|
</view>
|
|
<view class="photo-popup__section">
|
<view class="photo-popup__label-row">
|
<text class="photo-popup__label">{{ photoPopupLabel }}</text>
|
<text class="photo-popup__required">*</text>
|
<text class="photo-popup__hint">最多3张照片</text>
|
</view>
|
|
<view class="photo-popup__photos">
|
<view v-for="(photo, index) in uploadedPhotos" :key="index" class="photo-popup__preview-card">
|
<image class="photo-popup__preview-image" :src="photo" mode="aspectFill"></image>
|
<view class="photo-popup__preview-mask" @click="deletePhoto(index)">
|
<text class="photo-popup__preview-delete">删除</text>
|
</view>
|
</view>
|
<view v-if="uploadedPhotos.length < 3" class="photo-popup__upload-btn" @click="choosePhoto">
|
<image src="/static/image/btn_upload2@2x.png" mode="aspectFit"></image>
|
</view>
|
</view>
|
</view>
|
|
<view class="photo-popup__section photo-popup__section--remark">
|
<text class="photo-popup__remark-title">备注信息</text>
|
<textarea v-model="photoRemark" class="photo-popup__textarea" maxlength="200" placeholder="请输入" placeholder-style="color: #c7cbd3;" />
|
</view>
|
|
<button class="photo-popup__submit" hover-class="photo-popup__submit--hover" @click="submitPhotoPopup">{{ photoPopupSubmitText }}</button>
|
</view>
|
</u-popup>
|
</view>
|
</template>
|
|
<script>
|
export default {
|
data() {
|
return {
|
statusBarHeight: 0,
|
navHeight: 0,
|
activeTab: null,
|
searchKeyword: '',
|
tabs: [
|
{ label: '全部', value: null },
|
{ label: '待取货', value: 3 },
|
{ label: '配送中', value: 4 },
|
{ label: '已完成', value: 7 }
|
],
|
orders: [],
|
page: 1,
|
hasMore: true,
|
loading: false,
|
showCancelModal: false,
|
showQRPopup: false,
|
showPhotoPopup: false,
|
selectedOrder: null,
|
cancelRemain: 0,
|
photoPopupMode: '',
|
photoRemark: '',
|
uploadedPhotos: [],
|
activeOrderCount: null
|
}
|
},
|
computed: {
|
displayTabs() {
|
return this.tabs.map((tab) => {
|
let count = null
|
if (tab.value === 3) {
|
count = this.activeOrderCount?.grabbedCount
|
} else if (tab.value === 4) {
|
count = this.activeOrderCount?.deliveringCount
|
}
|
if (count) {
|
return {
|
...tab,
|
label: `${tab.label} ${count}`
|
}
|
}
|
return tab
|
})
|
},
|
|
bodyStyle() {
|
return {
|
marginTop: this.navHeight + uni.upx2px(88) + uni.upx2px(88) + 'px',
|
height: `calc(100vh - ${this.navHeight + uni.upx2px(88) + uni.upx2px(72)}px)`
|
}
|
},
|
photoPopupTitle() {
|
return this.photoPopupMode === 'deliver' ? '拍照送达' : '拍照取货'
|
},
|
photoPopupLabel() {
|
return this.photoPopupMode === 'deliver' ? '拍摄送达照片' : '拍摄取货照片'
|
},
|
photoPopupSubmitText() {
|
return this.photoPopupMode === 'deliver' ? '确认送达' : '确认取货'
|
}
|
},
|
onLoad() {
|
const systemInfo = uni.getSystemInfoSync()
|
this.statusBarHeight = systemInfo.statusBarHeight || 0
|
this.navHeight = this.statusBarHeight + uni.upx2px(88)
|
this.getOrderList()
|
},
|
onShow() {
|
this.getActiveOrderCount()
|
},
|
watch: {
|
activeTab() {
|
this.page = 1
|
this.hasMore = true
|
this.orders = []
|
this.getOrderList()
|
}
|
},
|
methods: {
|
handleScrollToLower() {
|
if (!this.hasMore || this.loading) return
|
this.page++
|
this.getOrderList()
|
},
|
searchOrder() {
|
this.page = 1
|
this.hasMore = true
|
this.orders = []
|
this.getOrderList()
|
},
|
getActiveOrderCount() {
|
this.$u.api.activeOrderCount().then(res => {
|
if (res.code === 200) {
|
this.activeOrderCount = res.data
|
} else {
|
this.activeOrderCount = null
|
}
|
}).catch(() => {
|
this.activeOrderCount = null
|
})
|
},
|
getBadgeIcon(item) {
|
return item.isUrgent ? '/static/image/ic_jisuda@2x.png' : '/static/image/ic_biaosuda@2x.png'
|
},
|
getStatusText(status) {
|
const map = {
|
2: '待接单',
|
3: '待取货',
|
4: '配送中',
|
5: '已送达',
|
7: '已完成',
|
99: '已取消'
|
}
|
return map[status] || ''
|
},
|
getActions(item) {
|
if (item.status === 3) {
|
return [
|
{ text: '取消订单', type: 'light', fill: false },
|
{ text: '取货码', type: 'primary', fill: false },
|
{ text: '拍照取货', type: 'primary', fill: true }
|
]
|
}
|
if (item.status === 4 && item.takeShopId) {
|
return [
|
{ text: '存件码', type: 'primary', fill: false }
|
]
|
}
|
if (item.status === 4 && !item.takeShopId) {
|
return [
|
{ text: '拍照送达', type: 'primary', fill: true }
|
]
|
}
|
return []
|
},
|
getOrderList() {
|
if (this.loading) return
|
console.log({
|
status: this.activeTab,
|
keyword: this.searchKeyword
|
})
|
this.loading = true
|
this.$u.api.orderPage({
|
capacity: 10,
|
page: this.page,
|
model: {
|
status: this.activeTab,
|
keyword: this.searchKeyword
|
}
|
}).then(res => {
|
if (res.code === 200) {
|
const list = res.data.records || []
|
console.log(list)
|
if (this.page === 1) {
|
this.orders = list
|
} else {
|
this.orders = [...this.orders, ...list]
|
}
|
this.hasMore = list.length >= 10
|
}
|
}).finally(() => {
|
this.loading = false
|
})
|
},
|
goToOrderDetail(item, index) {
|
uni.navigateTo({
|
url: `/pages/order-detail/order-detail?id=${item.id}`
|
})
|
},
|
handleAction(item, action) {
|
const text = action.text
|
if (text === '取消订单') {
|
this.handleCancelOrder(item)
|
} else if (text === '取货码' || text === '存件码') {
|
this.handleShowQRCode(item)
|
} else if (text === '拍照取货') {
|
this.handlePhotoPickup(item)
|
} else if (text === '拍照送达') {
|
this.handlePhotoDeliver(item)
|
}
|
},
|
handleCancelOrder(item) {
|
this.selectedOrder = item
|
this.$u.api.cancelLimit().then(res => {
|
if (res.code === 200) {
|
this.cancelRemain = res.data.remain
|
}
|
}).finally(() => {
|
this.showCancelModal = true
|
})
|
},
|
confirmCancelOrder() {
|
if (!this.selectedOrder) return
|
this.$u.api.cancelOrder({ orderId: this.selectedOrder.id }).then(res => {
|
this.showCancelModal = false
|
if (res.code === 200) {
|
uni.showToast({ title: '取消成功', icon: 'success' })
|
this.getOrderList()
|
this.getActiveOrderCount()
|
} else {
|
uni.showToast({ title: res.message || '取消失败', icon: 'none' })
|
}
|
}).catch(() => {
|
this.showCancelModal = false
|
})
|
},
|
handleShowQRCode(item) {
|
this.selectedOrder = item
|
this.showQRPopup = true
|
},
|
handlePhotoPickup(item) {
|
this.checkOperationRadius(item.id, 'pickup')
|
},
|
handlePhotoDeliver(item) {
|
this.checkOperationRadius(item.id, 'deliver')
|
},
|
checkOperationRadius(orderId, mode) {
|
uni.getLocation({
|
type: 'gcj02',
|
success: (res) => {
|
this.$u.api.checkDriverOperationRadius({
|
lat: res.latitude,
|
lng: res.longitude,
|
orderId: orderId
|
}).then(apiRes => {
|
if (apiRes.code === 200) {
|
console.log(apiRes.data)
|
if (apiRes.data === true) {
|
this.selectedOrder = { id: orderId }
|
this.photoPopupMode = mode
|
this.uploadedPhotos = []
|
this.photoRemark = ''
|
this.showPhotoPopup = true
|
} else {
|
uni.showToast({
|
title: '您当前位置与收货地址距离超出范围,请在地址附近重新拍照',
|
icon: 'none'
|
})
|
}
|
}
|
})
|
},
|
fail: () => {
|
uni.showToast({
|
title: '无法获取您的位置信息',
|
icon: 'none'
|
})
|
}
|
})
|
},
|
closePhotoPopup() {
|
this.showPhotoPopup = false
|
},
|
choosePhoto() {
|
if (this.uploadedPhotos.length >= 3) {
|
uni.showToast({ title: '最多上传3张照片', icon: 'none' })
|
return
|
}
|
uni.chooseImage({
|
count: 3 - this.uploadedPhotos.length,
|
sourceType: ['camera', 'album'],
|
success: (res) => {
|
this.uploadedPhotos = [...this.uploadedPhotos, ...res.tempFilePaths]
|
}
|
})
|
},
|
deletePhoto(index) {
|
this.uploadedPhotos.splice(index, 1)
|
},
|
submitPhotoPopup() {
|
if (this.uploadedPhotos.length === 0) {
|
uni.showToast({ title: '请上传照片', icon: 'none' })
|
return
|
}
|
uni.showLoading({ title: '上传中...' })
|
uni.getLocation({
|
type: 'gcj02',
|
success: (locationRes) => {
|
this.doUploadPhotos(locationRes.latitude, locationRes.longitude)
|
},
|
fail: () => {
|
this.doUploadPhotos(null, null)
|
}
|
})
|
},
|
|
doUploadPhotos(latitude, longitude) {
|
const uploadTasks = this.uploadedPhotos.map(path => {
|
return new Promise((resolve, reject) => {
|
const formData = { folder: 'orders' }
|
if (latitude && longitude) {
|
formData.latitude = latitude
|
formData.longitude = longitude
|
}
|
console.log('formData:', formData)
|
uni.uploadFile({
|
url: this.$baseUrl + 'web/public/upload',
|
filePath: path,
|
name: 'file',
|
formData: formData,
|
success: (uploadRes) => {
|
const data = JSON.parse(uploadRes.data)
|
if (data.code === 200) {
|
resolve(data.data)
|
} else {
|
reject(new Error(data.msg))
|
}
|
},
|
fail: (err) => {
|
reject(err)
|
}
|
})
|
})
|
})
|
|
Promise.all(uploadTasks).then(images => {
|
const api = this.photoPopupMode === 'deliver' ? 'confirmDeliver' : 'confirmPickup'
|
const params = {
|
images: images.map(img => img.imgaddr),
|
orderId: this.selectedOrder.id,
|
remark: this.photoRemark
|
}
|
if (latitude && longitude) {
|
params.latitude = latitude
|
params.longitude = longitude
|
}
|
return this.$u.api[api](params)
|
}).then(res => {
|
uni.hideLoading()
|
if (res.code === 200) {
|
uni.showToast({ title: '提交成功', icon: 'success' })
|
this.showPhotoPopup = false
|
this.getOrderList()
|
this.getActiveOrderCount()
|
} else {
|
uni.showToast({ title: res.msg || '提交失败', icon: 'none' })
|
}
|
}).catch(err => {
|
uni.hideLoading()
|
uni.showToast({ title: err.message || '上传失败', icon: 'none' })
|
})
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.order-page {
|
height: 100vh;
|
background: #f5f7fb;
|
overflow: hidden;
|
|
&__nav {
|
position: fixed;
|
left: 0;
|
top: 0;
|
right: 0;
|
z-index: 10;
|
background: linear-gradient(180deg, #1f73f6 0%, #1b6cf2 100%);
|
}
|
|
&__nav-inner {
|
height: 88rpx;
|
display: flex;
|
align-items: center;
|
padding: 0 28rpx;
|
}
|
|
&__nav-title {
|
font-size: 38rpx;
|
font-weight: 700;
|
color: #ffffff;
|
}
|
|
&__search {
|
position: fixed;
|
left: 0;
|
right: 0;
|
z-index: 10;
|
height: 88rpx;
|
padding: 8rpx 30rpx;
|
box-sizing: border-box;
|
display: flex;
|
align-items: center;
|
background: #ffffff;
|
}
|
|
&__search-box {
|
width: 100%;
|
height: 72rpx;
|
display: flex;
|
align-items: center;
|
padding: 0 24rpx;
|
background: #EEEEEE;
|
border-radius: 16rpx;
|
}
|
|
&__search-input {
|
flex: 1;
|
height: 72rpx;
|
margin-left: 12rpx;
|
color: #333333;
|
font-weight: 400;
|
font-size: 26rpx;
|
}
|
|
&__search-placeholder {
|
font-size: 28rpx;
|
color: #999999;
|
}
|
|
&__tabs {
|
position: fixed;
|
left: 0;
|
right: 0;
|
z-index: 9;
|
height: 88rpx;
|
display: flex;
|
align-items: center;
|
background: #ffffff;
|
box-shadow: 0 10rpx 20rpx rgba(40, 72, 128, 0.04);
|
}
|
|
&__tab {
|
position: relative;
|
flex: 1;
|
height: 100%;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
|
&--active {
|
.order-page__tab-text {
|
color: #272b33;
|
font-weight: 700;
|
}
|
}
|
}
|
|
&__tab-text {
|
font-size: 30rpx;
|
color: #8f96a3;
|
}
|
|
&__tab-line {
|
position: absolute;
|
left: 26rpx;
|
right: 26rpx;
|
bottom: 0;
|
height: 4rpx;
|
border-radius: 999rpx;
|
background: #1a73f8;
|
}
|
|
&__body {
|
box-sizing: border-box;
|
}
|
|
&__list {
|
padding: 18rpx 22rpx calc(env(safe-area-inset-bottom) + 26rpx);
|
}
|
|
&__empty {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
padding-top: 200rpx;
|
}
|
|
&__empty-icon {
|
width: 320rpx;
|
height: 320rpx;
|
}
|
|
&__loading {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
padding: 30rpx 0;
|
color: #8f96a3;
|
font-size: 26rpx;
|
}
|
}
|
|
.order-card {
|
margin-bottom: 18rpx;
|
padding: 20rpx 18rpx 18rpx;
|
border-radius: 20rpx;
|
background: #ffffff;
|
box-shadow: 0 8rpx 20rpx rgba(43, 65, 106, 0.05);
|
|
&__head {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
&__head-left {
|
display: flex;
|
align-items: center;
|
gap: 12rpx;
|
min-width: 0;
|
}
|
|
&__badge {
|
padding: 4rpx 10rpx;
|
border-radius: 10rpx;
|
font-size: 22rpx;
|
line-height: 1.2;
|
font-weight: 600;
|
|
&--blue {
|
border: 1rpx solid #75cfff;
|
color: #27a8f8;
|
background: #eefaff;
|
}
|
|
&--red {
|
border: 1rpx solid #ff8f8f;
|
color: #ff5d5d;
|
background: #fff1f1;
|
}
|
}
|
|
&__badge-icon {
|
width: 108rpx;
|
height: 40rpx;
|
flex-shrink: 0;
|
}
|
|
&__time-text,
|
&__status,
|
&__route-desc,
|
&__arrival-text {
|
font-size: 24rpx;
|
color: #a1a7b2;
|
}
|
|
&__status {
|
flex-shrink: 0;
|
|
&--highlight {
|
color: #ff4a3d;
|
font-weight: 700;
|
}
|
}
|
|
&__route-item {
|
display: flex;
|
align-items: flex-start;
|
margin-top: 22rpx;
|
|
&--delivery {
|
margin-top: 20rpx;
|
}
|
}
|
|
&__point {
|
width: 34rpx;
|
height: 34rpx;
|
line-height: 34rpx;
|
text-align: center;
|
border-radius: 50%;
|
font-size: 22rpx;
|
font-weight: 700;
|
color: #ffffff;
|
flex-shrink: 0;
|
margin-right: 16rpx;
|
|
&--pickup {
|
background: #2ab8ff;
|
}
|
|
&--delivery {
|
background: #ff9d2e;
|
}
|
}
|
|
&__route-texts {
|
flex: 1;
|
min-width: 0;
|
}
|
|
&__route-title {
|
display: block;
|
font-size: 34rpx;
|
font-weight: 700;
|
color: #2d3139;
|
line-height: 1.3;
|
}
|
|
&__route-desc {
|
display: block;
|
margin-top: 8rpx;
|
line-height: 1.4;
|
}
|
|
&__footer {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-top: 22rpx;
|
padding-top: 16rpx;
|
border-top: 1rpx solid #f0f2f6;
|
}
|
|
&__arrival {
|
display: flex;
|
align-items: center;
|
gap: 10rpx;
|
}
|
|
&__clock {
|
width: 24rpx;
|
height: 24rpx;
|
flex-shrink: 0;
|
}
|
|
&__price-wrap {
|
display: flex;
|
align-items: center;
|
gap: 10rpx;
|
}
|
|
&__price-tag {
|
padding: 3rpx 8rpx;
|
border-radius: 8rpx;
|
border: 1rpx solid #ff8f8f;
|
font-size: 22rpx;
|
font-weight: 600;
|
color: #ff6a6a;
|
background: #fff4f4;
|
}
|
|
&__price {
|
font-size: 40rpx;
|
font-weight: 700;
|
color: #ff4030;
|
}
|
|
&__actions {
|
display: flex;
|
justify-content: space-between;
|
margin-top: 18rpx;
|
padding-top: 18rpx;
|
border-top: 1rpx solid #f0f2f6;
|
}
|
|
&__action-btn {
|
width: 160rpx;
|
height: 64rpx;
|
line-height: 64rpx;
|
padding: 0;
|
border-radius: 34rpx;
|
font-size: 28rpx;
|
font-weight: 500;
|
border: 1rpx solid transparent;
|
background: #ffffff;
|
box-sizing: border-box;
|
|
&::after {
|
border: 0;
|
}
|
|
&--light {
|
border-color: #d7dbe3;
|
color: #8f96a3;
|
}
|
|
&--primary {
|
border-color: #2c7cff;
|
color: #2c7cff;
|
}
|
|
&--primary-fill {
|
background: #2c7cff;
|
color: #ffffff;
|
}
|
|
&--hover {
|
opacity: 0.92;
|
}
|
}
|
}
|
|
.qrcode {
|
padding: 30rpx 40rpx 50rpx;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
|
&-title {
|
width: 100%;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 40rpx;
|
|
image {
|
width: 40rpx;
|
height: 40rpx;
|
}
|
|
text {
|
font-size: 34rpx;
|
font-weight: 700;
|
color: #2d3139;
|
}
|
}
|
|
&-image {
|
width: 400rpx;
|
height: 400rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
border-radius: 16rpx;
|
|
image {
|
width: 360rpx;
|
height: 360rpx;
|
}
|
}
|
|
&-btn {
|
width: 100%;
|
height: 88rpx;
|
line-height: 88rpx;
|
text-align: center;
|
background: #106EFA;
|
border-radius: 44rpx;
|
font-size: 32rpx;
|
font-weight: 600;
|
color: #ffffff;
|
margin-top: 40rpx;
|
|
&--hover {
|
background: #0d5fc7;
|
}
|
}
|
}
|
|
.photo-popup {
|
padding: 30rpx 30rpx calc(env(safe-area-inset-bottom) + 30rpx);
|
|
&__header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 40rpx;
|
}
|
|
&__placeholder {
|
width: 40rpx;
|
height: 40rpx;
|
}
|
|
&__title {
|
font-size: 34rpx;
|
font-weight: 700;
|
color: #2d3139;
|
}
|
|
&__close {
|
width: 40rpx;
|
height: 40rpx;
|
}
|
|
&__section {
|
margin-bottom: 30rpx;
|
|
&--remark {
|
margin-top: 30rpx;
|
}
|
}
|
|
&__label-row {
|
display: flex;
|
align-items: center;
|
margin-bottom: 20rpx;
|
}
|
|
&__label {
|
font-size: 30rpx;
|
font-weight: 600;
|
color: #2d3139;
|
}
|
|
&__required {
|
color: #ff4030;
|
margin-left: 8rpx;
|
}
|
|
&__hint {
|
font-size: 24rpx;
|
color: #8f96a3;
|
margin-left: auto;
|
}
|
|
&__photos {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 20rpx;
|
}
|
|
&__preview-card {
|
position: relative;
|
width: 144rpx;
|
height: 144rpx;
|
border-radius: 12rpx;
|
overflow: hidden;
|
}
|
|
&__preview-image {
|
width: 100%;
|
height: 100%;
|
}
|
|
&__preview-mask {
|
position: absolute;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
height: 56rpx;
|
background: rgba(0, 0, 0, 0.5);
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
&__preview-delete {
|
font-size: 26rpx;
|
color: #ffffff;
|
}
|
|
&__upload-btn {
|
width: 144rpx;
|
height: 144rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
|
image {
|
width: 100%;
|
height: 100%;
|
}
|
}
|
|
&__remark-title {
|
font-size: 30rpx;
|
font-weight: 600;
|
color: #2d3139;
|
margin-bottom: 20rpx;
|
display: block;
|
}
|
|
&__textarea {
|
width: 100%;
|
height: 160rpx;
|
padding: 20rpx;
|
background: #f5f7fb;
|
border-radius: 12rpx;
|
font-size: 28rpx;
|
color: #2d3139;
|
box-sizing: border-box;
|
}
|
|
&__submit {
|
width: 100%;
|
height: 88rpx;
|
line-height: 88rpx;
|
background: #2c7cff;
|
border-radius: 44rpx;
|
font-size: 32rpx;
|
font-weight: 600;
|
color: #ffffff;
|
margin-top: 40rpx;
|
|
&--hover {
|
background: #2678e8;
|
}
|
}
|
}
|
</style>
|