1085 lines
26 KiB
Vue
1085 lines
26 KiB
Vue
<template>
|
||
<view class="content">
|
||
<uni-nav-bar color="#000000" backgroundColor="transparent" :fixed="true" :statusBar="true" :border="false"
|
||
@clickLeft="$c.back">
|
||
<view style="font-size: 34rpx; width: 100%; display: flex; justify-content: center; align-items: center;">
|
||
我的盒柜
|
||
</view>
|
||
</uni-nav-bar>
|
||
|
||
|
||
<!-- 顶部Tab -->
|
||
<view class="tab">
|
||
<view class="tab-item" v-for="(item, i) in tabList" :key="i"
|
||
:class="tabCur == i ? 'act' : ''" @click="tabChange(i)">
|
||
<text>{{ item.title }}</text>
|
||
<view v-if="tabCur == i" class="tab-line"></view>
|
||
</view>
|
||
</view>
|
||
|
||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getList" :down="downOption"
|
||
:up="upOption">
|
||
<template v-if="tabList[tabCur].id == 1">
|
||
<!-- 搜索框 -->
|
||
<view class="search-box">
|
||
<view class="search-input">
|
||
<uni-icons type="search" color="#999" size="18"></uni-icons>
|
||
<input v-model="keyword" placeholder="请输入关键字" placeholder-style="color:#999;" @confirm="tabChange(tabCur)" />
|
||
</view>
|
||
<view class="search-tip" @click="$refs.rulePop.getRule(10, '说明')">
|
||
<uni-icons type="info" color="#999" size="18"></uni-icons>
|
||
<text>说明</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 子Tab -->
|
||
<view class="sub-tab">
|
||
<view class="sub-tab-item" v-for="(item, i) in subTab" :key="i"
|
||
:class="subTabCur == i ? 'act' : ''" @click="subTabChange(i)">
|
||
{{ item.title }}
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 统计行 -->
|
||
<view class="stats-row">
|
||
<view class="stats-left">
|
||
<text>共<text class="num">{{ nowNum }}</text>个赏品</text>
|
||
<text class="ml20">已选<text class="num">{{ nowChooseNum }}</text>个</text>
|
||
</view>
|
||
<view class="stats-right">
|
||
<view class="stats-btn" @click="tabChange(tabCur)">刷新</view>
|
||
<view class="stats-btn" :class="{ act: isAll }" @click="chooseAll">全选</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 商品列表 - 两列 -->
|
||
<view class="goods-grid">
|
||
<view class="goods-item" v-for="(a, b) in GetOrderList" :key="a.prize_code">
|
||
<view class="goods-img">
|
||
<image :src="a.goodslist_imgurl" mode="aspectFill"></image>
|
||
<view class="goods-badge" v-if="subTab[subTabCur].id == 2">预售</view>
|
||
</view>
|
||
<view class="goods-title">{{ a.goodslist_title }}</view>
|
||
<view class="goods-qty">
|
||
<view class="qty-btn minus" @click="jian(a)">
|
||
<text>−</text>
|
||
</view>
|
||
<text class="qty-num">{{ a.chooseNum }}</text>
|
||
<view class="qty-btn plus" @click="jia(a)">
|
||
<text>+</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 申请提货/已发货/完成提货 -->
|
||
<view v-else class="order-list">
|
||
<view class="order-item" v-for="(item, i) in listData" :key="i" @click="toOrder(item)">
|
||
<view class="order-hd">
|
||
<text class="time">申请时间:{{ item.addtime }}</text>
|
||
<text class="status">{{ item.status_name }}</text>
|
||
</view>
|
||
<scroll-view class="order-bd" scroll-x>
|
||
<view class="order-goods" v-for="(a, b) in item.order_list" :key="b">
|
||
<view class="pic">
|
||
<image :src="a.goodslist_imgurl" mode="aspectFill"></image>
|
||
<view class="num">{{ a.prize_num }}</view>
|
||
<view class="shipped" v-if="a.fh_status == 1">已发货</view>
|
||
</view>
|
||
<view class="title">{{ a.goodslist_title }}</view>
|
||
</view>
|
||
</scroll-view>
|
||
<view class="order-btns" v-if="item.status == 2" @click.stop>
|
||
<view class="btn-outline" @click="toExpress(item)">查看物流</view>
|
||
<view class="btn-primary" @click="submitGet(item)">确认收货</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</mescroll-body>
|
||
|
||
<!-- 底部操作按钮 -->
|
||
<view v-if="tabList[tabCur].id == 1" class="bottom-action">
|
||
<view v-if="subTab[subTabCur].id == 4" class="action-btn" @click="open('model')">解锁</view>
|
||
<template v-else>
|
||
<view v-if="show_dadajuan && subTab[subTabCur].id != 2" class="action-btn secondary" @click="open('changePop')">
|
||
{{ $config.getAppSetting('currency2_name') }}
|
||
</view>
|
||
<view v-if="subTab[subTabCur].id != 2" class="action-btn" @click="open('sendPop')">发货</view>
|
||
<view v-if="subTab[subTabCur].id != 6" class="action-btn secondary" @click="open('model')">上锁</view>
|
||
</template>
|
||
</view>
|
||
|
||
<!-- 兑换弹窗 -->
|
||
<uni-popup ref="changePop" type="bottom">
|
||
<view class="popup-container">
|
||
<view class="popup-header">
|
||
<text class="popup-title">兑换确认</text>
|
||
<view class="popup-close" @click="close('changePop')">×</view>
|
||
</view>
|
||
<view class="popup-body">
|
||
<view class="selected-info">已选<text>{{ nowChooseNum }}</text>件赏品</view>
|
||
<scroll-view class="goods-scroll" scroll-x>
|
||
<view class="scroll-item" v-for="(item, i) in handelList" :key="i">
|
||
<view class="item-img">
|
||
<image :src="item.goodslist_imgurl" mode="aspectFill"></image>
|
||
<view class="item-num">{{ item.chooseNum }}</view>
|
||
</view>
|
||
<view class="item-title">{{ item.goodslist_title }}</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
<view class="popup-summary">
|
||
共<text>{{ nowChooseNum }}</text>件物品,合计兑换<text class="highlight">{{ totalChangeMoney }}</text>{{ $config.getAppSetting('currency2_name') }}
|
||
</view>
|
||
<view class="popup-btn" @click="$c.noDouble(submitChange)">确认兑换</view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
<!-- 发货弹窗 -->
|
||
<uni-popup ref="sendPop" type="bottom">
|
||
<view class="popup-container">
|
||
<view class="popup-header">
|
||
<text class="popup-title">发货确认单</text>
|
||
<view class="popup-close" @click="close('sendPop')">×</view>
|
||
</view>
|
||
<view class="popup-body">
|
||
<view class="selected-info">已选<text>{{ nowChooseNum }}</text>件赏品</view>
|
||
<scroll-view class="goods-scroll" scroll-x>
|
||
<view class="scroll-item" v-for="(item, i) in handelList" :key="i">
|
||
<view class="item-img">
|
||
<image :src="item.goodslist_imgurl" mode="aspectFill"></image>
|
||
<view class="item-num">{{ item.chooseNum }}</view>
|
||
</view>
|
||
<view class="item-title">{{ item.goodslist_title }}</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
<view class="address-card" @click="chooseAdd">
|
||
<view v-if="!addData" class="address-empty">请选择收货地址</view>
|
||
<view v-else class="address-info">
|
||
<view class="address-name">{{ addData.userName }} {{ addData.telNumber }}</view>
|
||
<view class="address-detail">{{ addData.detailed_address }}</view>
|
||
</view>
|
||
<text class="address-arrow">›</text>
|
||
</view>
|
||
<view class="freight-row">
|
||
<text>快递(满{{ freightData.free_post }}件包邮)</text>
|
||
<text>{{ nowChooseNum >= freightData.free_post ? '包邮' : `¥${freightData.post_money}` }}</text>
|
||
</view>
|
||
<view class="popup-btn" @click="$c.noDouble(submitSend)">确认发货</view>
|
||
<view class="agree-row" @click="isAgree = !isAgree">
|
||
<view class="check-icon" :class="{ active: isAgree }"></view>
|
||
<text>我已满18岁,阅读并同意《用户协议》《隐私政策》</text>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
<!-- 上锁/解锁弹窗 -->
|
||
<uni-popup ref="model" type="center">
|
||
<view class="confirm-modal">
|
||
<view class="modal-content">{{ lockMsg }}</view>
|
||
<view class="modal-btns">
|
||
<view class="modal-btn" @click="close('model')">取消</view>
|
||
<view class="modal-btn primary" @click="$c.noDouble(submitLock)">确定</view>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
<!-- 兑换成功弹窗 -->
|
||
<uni-popup ref="resPop" type="center" mask-background-color="rgba(0,0,0,0.8)">
|
||
<view class="result-modal">
|
||
<image class="result-icon" :src="$img1('shangdai/qianbao.png')"></image>
|
||
<view class="result-text">恭喜您成功兑换,获得{{ zhanshiMoney }} {{ $config.getAppSetting('currency2_name') }}</view>
|
||
<view class="result-btn" @click="$refs.resPop.close()">确定</view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
<rule-pop ref="rulePop"></rule-pop>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { getUserInfo } from '@/common/server/user.js';
|
||
import {
|
||
getWarehouseIndex,
|
||
confirmSend,
|
||
moveInSafe,
|
||
moveOutSafe,
|
||
recoveryPrizeWithType,
|
||
sendPrizeWithAddress,
|
||
getSendRecordWithStatus
|
||
} from '@/common/server/warehouse.js';
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
keyword: '',
|
||
remark: '',
|
||
downOption: { auto: false },
|
||
upOption: { auto: true, page: { size: 10 } },
|
||
tabList: [
|
||
{ id: 1, title: '全部' },
|
||
{ id: 2, status: 1, title: '申请提货' },
|
||
{ id: 3, status: 2, title: '已发货' },
|
||
{ id: 4, status: 3, title: '完成提货' }
|
||
],
|
||
tabCur: 0,
|
||
subTab: [
|
||
{ id: 1, title: '赏品' },
|
||
{ id: 4, title: '保险柜' },
|
||
{ id: 2, title: '预售' }
|
||
],
|
||
subTabCur: 0,
|
||
listData: [],
|
||
total: 0,
|
||
handelList: [],
|
||
addData: '',
|
||
lockMsg: '',
|
||
freightData: '',
|
||
canReload: false,
|
||
zhanshiMoney: 0,
|
||
isAgree: false,
|
||
is_exchange: '0',
|
||
show_dadajuan: true
|
||
}
|
||
},
|
||
onShow() {
|
||
if (uni.getStorageSync('token')) {
|
||
this.loadUserInfo()
|
||
}
|
||
this.canReload && this.tabChange(this.tabCur)
|
||
this.canReload = true
|
||
const curPages = getCurrentPages()[0];
|
||
if (typeof curPages.getTabBar === 'function' && curPages.getTabBar()) {
|
||
this.$mp.page.getTabBar().setData({ selected: 3 });
|
||
}
|
||
this.$platform.getOrderNo(this).then(order_num => {
|
||
if (order_num != null && order_num != "") {
|
||
this.$c.msg("支付成功~")
|
||
}
|
||
});
|
||
},
|
||
onLoad() {
|
||
this.$nextTick(() => {
|
||
this.$refs.mescrollRef.mescroll.optUp.empty.tip = '~ 快来抽赏吧 ~'
|
||
})
|
||
},
|
||
computed: {
|
||
totalChangeMoney() {
|
||
if (this.tabList[this.tabCur].id != 1) return
|
||
if (this.handelList.length <= 0) return 0
|
||
var total = this.handelList.reduce((pre, item) => pre + item.chooseNum * item.goodslist_money, 0)
|
||
return this.$c.removeTrailingZeros(total.toFixed(2));
|
||
},
|
||
isAll() {
|
||
if (this.tabList[this.tabCur].id != 1) return
|
||
if (this.listData.length <= 0) return false
|
||
return this.nowNum == this.nowChooseNum
|
||
},
|
||
nowChooseNum() {
|
||
if (this.tabList[this.tabCur].id != 1) return
|
||
const arr = this.getChooseGoods()
|
||
return arr.reduce((pre, item) => pre + Number(item.chooseNum), 0)
|
||
},
|
||
nowNum() {
|
||
if (this.tabList[this.tabCur].id != 1) return
|
||
const arr = []
|
||
if (this.listData != null && this.listData.length > 0) {
|
||
this.listData.forEach(item => {
|
||
if (item != null && item.orderlist != null && item.orderlist.length > 0) {
|
||
item.orderlist.forEach(a => arr.push(a))
|
||
}
|
||
})
|
||
}
|
||
return arr.filter(item => item.prize_num > 0).reduce((pre, item) => pre + Number(item.prize_num), 0)
|
||
},
|
||
GetOrderList() {
|
||
if (this.listData != null && this.listData.length > 0) {
|
||
let t = []
|
||
this.listData.forEach(it => {
|
||
if (it != null && it.orderlist != null && it.orderlist.length > 0) {
|
||
it.orderlist.forEach(a => t.push(a))
|
||
}
|
||
})
|
||
return t
|
||
}
|
||
return []
|
||
}
|
||
},
|
||
methods: {
|
||
async loadUserInfo() {
|
||
const res = await getUserInfo();
|
||
if (res && res.userinfo) {
|
||
uni.setStorageSync('userinfo', res.userinfo)
|
||
this.is_exchange = res.userinfo.is_exchange
|
||
}
|
||
},
|
||
async submitGet(item) {
|
||
const res = await confirmSend({ id: item.id });
|
||
if (res.status == 1) {
|
||
this.$c.toast({ title: res.msg, duration: 500, success: () => this.tabChange(this.tabCur) })
|
||
}
|
||
},
|
||
toExpress(item) {
|
||
this.$c.to({ url: '/pages/user/wuliu_detail', query: { id: item.id } })
|
||
},
|
||
toOrder(item) {
|
||
this.$c.to({ url: '/pages/user/order', query: { id: item.id } })
|
||
},
|
||
chooseAdd() {
|
||
this.canReload = false;
|
||
this.$platform.chooseAddress().then(res => {
|
||
this.addData = res
|
||
this.canReload = true;
|
||
});
|
||
},
|
||
async submitLock() {
|
||
let data = this.handelList.map(item => ({ prize_code: item.prize_code, number: item.chooseNum }))
|
||
let res;
|
||
if (this.subTab[this.subTabCur].id == 4) {
|
||
res = await moveOutSafe({ recovery_info: JSON.stringify(data) });
|
||
} else {
|
||
res = await moveInSafe({ recovery_info: JSON.stringify(data) });
|
||
}
|
||
if (res.status == 1) {
|
||
this.close('model')
|
||
this.$c.toast({ title: res.msg, duration: 500, success: () => this.tabChange(this.tabCur) })
|
||
}
|
||
},
|
||
async submitSend() {
|
||
if (!this.isAgree) {
|
||
this.$c.toast({ title: '请阅读并同意《用户协议》《隐私政策》' })
|
||
return
|
||
}
|
||
if (!this.addData) {
|
||
this.$c.toast({ title: '请选择地址' })
|
||
return
|
||
}
|
||
let data = this.handelList.map(item => ({ prize_code: item.prize_code, number: item.chooseNum }))
|
||
const res = await sendPrizeWithAddress({
|
||
recovery_info: JSON.stringify(data),
|
||
type: this.subTab[this.subTabCur].id,
|
||
name: this.addData.userName,
|
||
mobile: this.addData.telNumber,
|
||
address: this.addData.detailed_address,
|
||
message: this.remark
|
||
});
|
||
if (res.status == 1) {
|
||
this.close('sendPop')
|
||
this.remark = ''
|
||
if (res.data.status == 1) {
|
||
const status = await this.$platform.pay({ data: res.data.res }, this)
|
||
if (status == 'success') this.tabChange(this.tabCur)
|
||
} else {
|
||
this.$c.toast({ title: res.msg, duration: 500, success: () => this.tabChange(this.tabCur) })
|
||
}
|
||
}
|
||
},
|
||
async submitChange() {
|
||
let data = this.handelList.map(item => ({ prize_code: item.prize_code, number: item.chooseNum }))
|
||
const res = await recoveryPrizeWithType({ recovery_info: JSON.stringify(data), type: this.subTab[this.subTabCur].id });
|
||
if (res.status == 1) {
|
||
this.close('changePop')
|
||
this.zhanshiMoney = this.$c.removeTrailingZeros(this.totalChangeMoney);
|
||
setTimeout(() => {
|
||
this.$refs.resPop.open()
|
||
this.tabChange(this.tabCur)
|
||
}, 500)
|
||
} else {
|
||
this.$c.toast({ title: res.msg })
|
||
}
|
||
},
|
||
getChooseGoods() {
|
||
const arr = []
|
||
this.listData.forEach(item => {
|
||
item.orderlist.forEach(a => {
|
||
const child = a
|
||
if (a.order_list_ids) child.order_list_ids1 = a.order_list_ids.slice(0, a.chooseNum)
|
||
arr.push(child)
|
||
})
|
||
})
|
||
return arr.filter(item => item.chooseNum > 0)
|
||
},
|
||
chooseAll() {
|
||
if (this.isAll) {
|
||
this.listData.map(item => item.orderlist.map(a => a.chooseNum = 0))
|
||
} else {
|
||
this.listData.map(item => item.orderlist.map(a => a.chooseNum = a.prize_num))
|
||
}
|
||
},
|
||
verifyNum(item) {
|
||
if (item.chooseNum <= 0) { item.chooseNum = 0; return }
|
||
if (item.chooseNum >= item.prize_num) { item.chooseNum = item.prize_num; return }
|
||
},
|
||
jian(item) {
|
||
if (item.chooseNum <= 0) { item.chooseNum = 0; return }
|
||
item.chooseNum -= 1
|
||
},
|
||
jia(item) {
|
||
if (item.chooseNum >= item.prize_num) { item.chooseNum = item.prize_num; return }
|
||
item.chooseNum += 1
|
||
},
|
||
subTabChange(i) {
|
||
this.subTabCur = i
|
||
this.listData = []
|
||
this.mescroll.resetUpScroll()
|
||
this.mescroll.scrollTo(0, 0)
|
||
},
|
||
tabChange(i) {
|
||
this.tabCur = i
|
||
switch (i) {
|
||
case 0: this.subTabChange(this.subTabCur); break
|
||
default:
|
||
this.listData = []
|
||
this.mescroll.resetUpScroll()
|
||
this.mescroll.scrollTo(0, 0)
|
||
break
|
||
}
|
||
},
|
||
async getList({ num, size }) {
|
||
let data = { page: num }
|
||
try {
|
||
let res;
|
||
if (this.tabList[this.tabCur].id == 1) {
|
||
data.type = this.subTab[this.subTabCur].id
|
||
data.keyword = this.keyword
|
||
res = await getWarehouseIndex(data);
|
||
} else {
|
||
data.status = this.tabList[this.tabCur].status
|
||
res = await getSendRecordWithStatus(data);
|
||
}
|
||
if (res.status == 1) {
|
||
if (num == 1) this.listData = [];
|
||
if (this.tabList[this.tabCur].id == 1) {
|
||
res.data.data.map(item => item.orderlist.map(a => a.chooseNum = 0))
|
||
this.freightData = res.data.yufei
|
||
}
|
||
if (res.data.show_dadajuan != null) this.show_dadajuan = res.data.show_dadajuan
|
||
this.listData = this.listData.concat(res.data.data)
|
||
this.mescroll.endByPage(res.data.data.length, res.data.last_page)
|
||
} else {
|
||
this.listData = [];
|
||
this.mescroll.endByPage(0, 0)
|
||
}
|
||
} catch (error) {
|
||
this.listData = [];
|
||
this.mescroll.endByPage(0, 0)
|
||
}
|
||
},
|
||
close(e) { this.$refs[e].close() },
|
||
open(e) {
|
||
this.handelList = []
|
||
const choose = this.getChooseGoods()
|
||
if (choose.length <= 0) {
|
||
this.$c.toast({ title: '请选择赏品' })
|
||
return
|
||
}
|
||
this.handelList = choose
|
||
if (e == 'model') {
|
||
this.lockMsg = this.subTab[this.subTabCur].id != 4 ? '请问您是否要将所选择赏品放入保险柜?' : '请问您是否要将所选择赏品移出保险柜?'
|
||
}
|
||
this.$refs[e].open()
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.content {
|
||
min-height: 100vh;
|
||
padding-bottom: calc(var(--window-bottom) + 200rpx);
|
||
background: linear-gradient(180deg, #5FCDFF 0%, #F5F5F5 100%);
|
||
}
|
||
|
||
// 顶部Tab
|
||
.tab {
|
||
display: flex;
|
||
padding: 20rpx 30rpx;
|
||
|
||
.tab-item {
|
||
position: relative;
|
||
margin-right: 48rpx;
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
|
||
&.act {
|
||
color: #333;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.tab-line {
|
||
position: absolute;
|
||
bottom: -10rpx;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 40rpx;
|
||
height: 4rpx;
|
||
background: #333;
|
||
border-radius: 2rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 搜索框
|
||
.search-box {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0 30rpx;
|
||
margin-bottom: 20rpx;
|
||
|
||
.search-input {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
height: 72rpx;
|
||
padding: 0 24rpx;
|
||
background: #FFF;
|
||
border-radius: 36rpx;
|
||
|
||
input {
|
||
flex: 1;
|
||
margin-left: 16rpx;
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
|
||
.search-tip {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin-left: 20rpx;
|
||
|
||
text {
|
||
font-size: 20rpx;
|
||
color: #999;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 子Tab
|
||
.sub-tab {
|
||
display: flex;
|
||
padding: 0 30rpx 20rpx;
|
||
|
||
.sub-tab-item {
|
||
padding: 8rpx 20rpx;
|
||
margin-right: 16rpx;
|
||
font-family: PingFang SC, PingFang SC;
|
||
font-weight: 500;
|
||
font-size: 22rpx;
|
||
color: rgba(64,64,64,0.85);
|
||
background: #F3F3F3;
|
||
border-radius: 9rpx;
|
||
|
||
&.act {
|
||
color: #424242;
|
||
background: #03D8F4;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 统计行
|
||
.stats-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 0 30rpx 20rpx;
|
||
|
||
.stats-left {
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
|
||
.num { color: #333; font-weight: 500; }
|
||
.ml20 { margin-left: 20rpx; }
|
||
}
|
||
|
||
.stats-right {
|
||
display: flex;
|
||
|
||
.stats-btn {
|
||
padding: 8rpx 24rpx;
|
||
margin-left: 20rpx;
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
background: #FFF;
|
||
border-radius: 8rpx;
|
||
|
||
&.act {
|
||
color: #03D8F4;
|
||
background: rgba(3, 216, 244, 0.1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 商品网格 - 两列
|
||
.goods-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 20rpx;
|
||
padding: 0 30rpx;
|
||
|
||
.goods-item {
|
||
background: #FFF;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
|
||
.goods-img {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 330rpx;
|
||
|
||
image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.goods-badge {
|
||
position: absolute;
|
||
top: 16rpx;
|
||
left: 16rpx;
|
||
padding: 4rpx 16rpx;
|
||
font-size: 22rpx;
|
||
color: #FFF;
|
||
background: #FF6B6B;
|
||
border-radius: 4rpx;
|
||
}
|
||
}
|
||
|
||
.goods-title {
|
||
padding: 16rpx;
|
||
font-size: 26rpx;
|
||
color: #333;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.goods-qty {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 0 16rpx 20rpx;
|
||
|
||
.qty-btn {
|
||
width: 56rpx;
|
||
height: 56rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 50%;
|
||
font-size: 36rpx;
|
||
|
||
&.minus {
|
||
background: #03D8F4;
|
||
color: #FFF;
|
||
}
|
||
|
||
&.plus {
|
||
background: #03D8F4;
|
||
color: #FFF;
|
||
}
|
||
}
|
||
|
||
.qty-num {
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 订单列表
|
||
.order-list {
|
||
padding: 0 30rpx;
|
||
|
||
.order-item {
|
||
margin-bottom: 20rpx;
|
||
padding: 24rpx;
|
||
background: #FFF;
|
||
border-radius: 16rpx;
|
||
|
||
.order-hd {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 20rpx;
|
||
|
||
.time { font-size: 24rpx; color: #999; }
|
||
.status { font-size: 24rpx; color: #333; }
|
||
}
|
||
|
||
.order-bd {
|
||
white-space: nowrap;
|
||
|
||
.order-goods {
|
||
display: inline-block;
|
||
width: 160rpx;
|
||
margin-right: 16rpx;
|
||
|
||
.pic {
|
||
position: relative;
|
||
width: 160rpx;
|
||
height: 160rpx;
|
||
border-radius: 12rpx;
|
||
overflow: hidden;
|
||
|
||
image { width: 100%; height: 100%; }
|
||
|
||
.num {
|
||
position: absolute;
|
||
bottom: 8rpx;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
padding: 4rpx 16rpx;
|
||
font-size: 22rpx;
|
||
color: #FFF;
|
||
background: rgba(0,0,0,0.5);
|
||
border-radius: 20rpx;
|
||
}
|
||
|
||
.shipped {
|
||
position: absolute;
|
||
top: 8rpx;
|
||
right: 8rpx;
|
||
padding: 4rpx 12rpx;
|
||
font-size: 20rpx;
|
||
color: #03D8F4;
|
||
background: rgba(0,0,0,0.5);
|
||
border-radius: 4rpx;
|
||
}
|
||
}
|
||
|
||
.title {
|
||
margin-top: 12rpx;
|
||
font-size: 22rpx;
|
||
color: #333;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
}
|
||
}
|
||
|
||
.order-btns {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
margin-top: 20rpx;
|
||
|
||
.btn-outline {
|
||
padding: 12rpx 32rpx;
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
background: #F5F5F5;
|
||
border-radius: 8rpx;
|
||
}
|
||
|
||
.btn-primary {
|
||
margin-left: 20rpx;
|
||
padding: 12rpx 32rpx;
|
||
font-size: 24rpx;
|
||
color: #FFF;
|
||
background: #03D8F4;
|
||
border-radius: 8rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 底部操作按钮
|
||
.bottom-action {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: calc(var(--window-bottom) + 120rpx);
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 16rpx 30rpx;
|
||
|
||
.action-btn {
|
||
min-width: 140rpx;
|
||
height: 60rpx;
|
||
margin: 0 12rpx;
|
||
padding: 0 28rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 24rpx;
|
||
color: #404040;
|
||
background: #03D8F4;
|
||
border-radius: 30rpx;
|
||
|
||
&.secondary {
|
||
background: #FFF;
|
||
border: 2rpx solid #DDD;
|
||
color: #666;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 弹窗通用样式
|
||
.popup-container {
|
||
background: #FFF;
|
||
border-radius: 24rpx 24rpx 0 0;
|
||
padding: 0 30rpx 60rpx;
|
||
|
||
.popup-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 30rpx 0;
|
||
position: relative;
|
||
|
||
.popup-title {
|
||
font-size: 32rpx;
|
||
font-weight: 500;
|
||
color: #333;
|
||
}
|
||
|
||
.popup-close {
|
||
position: absolute;
|
||
right: 0;
|
||
font-size: 48rpx;
|
||
color: #999;
|
||
}
|
||
}
|
||
|
||
.popup-body {
|
||
background: #F7F7F7;
|
||
border-radius: 16rpx;
|
||
padding: 20rpx;
|
||
|
||
.selected-info {
|
||
text-align: center;
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
margin-bottom: 20rpx;
|
||
|
||
text { color: #333; font-weight: 500; }
|
||
}
|
||
|
||
.goods-scroll {
|
||
white-space: nowrap;
|
||
|
||
.scroll-item {
|
||
display: inline-block;
|
||
width: 160rpx;
|
||
margin-right: 16rpx;
|
||
|
||
.item-img {
|
||
position: relative;
|
||
width: 160rpx;
|
||
height: 160rpx;
|
||
border-radius: 12rpx;
|
||
overflow: hidden;
|
||
|
||
image { width: 100%; height: 100%; }
|
||
|
||
.item-num {
|
||
position: absolute;
|
||
bottom: 8rpx;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
padding: 4rpx 16rpx;
|
||
font-size: 22rpx;
|
||
color: #333;
|
||
background: rgba(255,255,255,0.8);
|
||
border-radius: 20rpx;
|
||
}
|
||
}
|
||
|
||
.item-title {
|
||
margin-top: 12rpx;
|
||
font-size: 22rpx;
|
||
color: #333;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.popup-summary {
|
||
margin: 20rpx 0;
|
||
padding: 20rpx;
|
||
background: #F7F7F7;
|
||
border-radius: 12rpx;
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
text-align: center;
|
||
|
||
text { color: #333; }
|
||
.highlight { color: #03D8F4; font-weight: 500; }
|
||
}
|
||
|
||
.address-card {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 24rpx;
|
||
margin-top: 20rpx;
|
||
background: #F7F7F7;
|
||
border-radius: 12rpx;
|
||
|
||
.address-empty {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
}
|
||
|
||
.address-info {
|
||
flex: 1;
|
||
|
||
.address-name {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.address-detail {
|
||
margin-top: 8rpx;
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
}
|
||
}
|
||
|
||
.address-arrow {
|
||
font-size: 32rpx;
|
||
color: #CCC;
|
||
}
|
||
}
|
||
|
||
.freight-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 20rpx 0;
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
border-top: 1rpx solid #EEE;
|
||
margin-top: 20rpx;
|
||
}
|
||
|
||
.popup-btn {
|
||
margin-top: 30rpx;
|
||
height: 88rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 30rpx;
|
||
color: #404040;
|
||
background: #03D8F4;
|
||
border-radius: 14rpx;
|
||
}
|
||
|
||
.agree-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-top: 20rpx;
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
|
||
.check-icon {
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
margin-right: 12rpx;
|
||
border: 2rpx solid #DDD;
|
||
border-radius: 50%;
|
||
|
||
&.active {
|
||
background: #03D8F4;
|
||
border-color: #03D8F4;
|
||
position: relative;
|
||
|
||
&::after {
|
||
content: '✓';
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
font-size: 20rpx;
|
||
color: #FFF;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 确认弹窗
|
||
.confirm-modal {
|
||
width: 600rpx;
|
||
background: #FFF;
|
||
border-radius: 24rpx;
|
||
overflow: hidden;
|
||
|
||
.modal-content {
|
||
text-align: center;
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
padding: 60rpx 40rpx 50rpx;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.modal-btns {
|
||
display: flex;
|
||
border-top: 1rpx solid #EEEEEE;
|
||
|
||
.modal-btn {
|
||
flex: 1;
|
||
height: 100rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 32rpx;
|
||
color: #666;
|
||
background: #FFF;
|
||
|
||
&:first-child {
|
||
border-right: 1rpx solid #EEEEEE;
|
||
}
|
||
|
||
&.primary {
|
||
color: #03D8F4;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 结果弹窗
|
||
.result-modal {
|
||
width: 480rpx;
|
||
background: #FFF;
|
||
border-radius: 24rpx;
|
||
padding: 40rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
|
||
.result-icon {
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
}
|
||
|
||
.result-text {
|
||
margin: 30rpx 0;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
text-align: center;
|
||
}
|
||
|
||
.result-btn {
|
||
width: 200rpx;
|
||
height: 72rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 28rpx;
|
||
color: #404040;
|
||
background: #03D8F4;
|
||
border-radius: 12rpx;
|
||
}
|
||
}
|
||
</style>
|