This commit is contained in:
shuhongfan
2023-09-04 16:40:17 +08:00
commit cf5ac25c14
8267 changed files with 1305066 additions and 0 deletions

View File

@@ -0,0 +1,247 @@
.address{
background-color:#F3F5F9 ;
height: 100vh;
}
.seachBox{
display: flex;
align-items: center;
background-color: white;
::v-deep .uni-searchbar{
padding-left: 40rpx;
padding-right: 40rpx;
.uni-searchbar__box{
border-radius: 34rpx!important;
justify-content: flex-start;
}
}
uni-search-bar{
flex: auto;
}
.search-icon{
width: 40rpx;
height: 40rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url(data:image/png;base64,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);
}
.search-btn{
font-weight: bold;
font-size: 28rpx;
}
}
.list-container{
padding: 0 18rpx;
.checkbox{
margin-right: 50rpx;
}
.address-list.isChecked{
display: flex;
align-items: center;
background-color:#F3F5F9 ;
padding: 36rpx 0;
padding-bottom: 0;
padding-top: 0;
}
.address-item.isChecked{
border-radius: 20rpx;
padding: 36rpx 30rpx 0rpx;
background: #FFFFFF;
.address-item-footer{
margin-bottom: 36rpx;
}
}
.address-list{
margin-top: 20rpx;
background: #FFFFFF;
border-radius: 20rpx;
padding: 36rpx 30rpx 0rpx;
padding-bottom: 30rpx;
.address-item{
flex: auto;
}
.address-name,.address-phone{
display: inline-block;
}
.address-name{
font-size: 30rpx;
font-weight: bold;
margin-right: 12rpx;
}
.address-phone,.address-address{
color: #888;
font-size: 26rpx;
}
.address-address{
margin-top: 10rpx;
}
.line{
margin-top: 20rpx;
height: 2rpx;
background-color:#F4F4F4 ;
width: 100%;
}
.address-item-footer{
display: flex;
justify-content: space-between;
margin-top: 20rpx;
.save-address{
display: flex;
align-items: center;
.label{
font-size: 26rpx;
color: #888;
}
.active,.checkbox{
width: 40rpx;
height: 40rpx;
background-repeat: no-repeat;
background-size: contain;
margin-right: 10rpx;
}
.checkbox{
background-image: url('../../static/checkbox.png');
}
.active{
background-image: url('../../static/checkboxActive.png');
}
}
.right-box{
display: flex;
}
.edit-btn,.delete-btn{
display: flex;
align-items: center;
icon{
background: url(../../static/btn-bianji.png) no-repeat;
background-size: contain;
width: 40rpx;
height: 40rpx;
margin-right: 6rpx;
}
text{
font-size: 26rpx;
color: #888;
}
}
.delete-btn{
margin-left: 20rpx;
icon{
background: url(../../static/btn-shanchu.png) no-repeat;
background-size: contain;
width: 30rpx;
height: 30rpx;
}
}
.right-box.active{
.edit-btn,.delete-btn{
text{
color: #DADADA;
}
}
.edit-btn{
icon{
width: 40rpx;
height: 40rpx;
background: url(../../static/btn-bianji-gray.png) no-repeat;
background-size: contain;
}
}
.delete-btn{
icon{
width: 30rpx;
height: 30rpx;
background: url(../../static/btn-shanchu-gray.png) no-repeat;
background-size: contain;
}
}
}
}
.address-item-footer.active{
justify-content: flex-end;
}
}
.address-footer{
height:160rpx ;
width: 100%;
position: fixed;
left: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: #FFFFFF;
.manage-btn{
width: 250rpx;
height: 88rpx;
border: 2rpx solid #979797;
border-radius: 44rpx;
color:#0F0F0F ;
text-align: center;
line-height: 88rpx;
}
.addAddress-btn{
width: 400rpx;
height: 88rpx;
background-color:#CCCCCC ;
border-radius: 44rpx;
color:#FFFFFF ;
text-align: center;
line-height: 88rpx;
margin-left: 26rpx;
}
.addAddress-btn.active{
background-color:#E84134 ;
}
}
.all-select{
display: flex;
width: 100%;
position: fixed;
align-items: center;
left: 0;
bottom:160rpx ;
height: 84rpx;
background-color: #FFFFFF;
border-bottom: 1px solid #F4F4F4;
font-size: 24rpx;
.checkbox{
margin-right: 0rpx;
margin-left:28rpx ;
}
}
}
.empty-box{
margin-top: 300rpx;
image{
width: 400rpx;
height: 240rpx;
display: block;
margin: 0 auto;
}
view{
font-size: 28rpx;
color:#818181 ;
margin-top: 40rpx;
text-align: center;
}
}
.address-popup{
::v-deep .uni-button-color{
color: #E84134;
}
::v-deep .uni-dialog-title{
display: none;
}
}

View File

@@ -0,0 +1,363 @@
<template>
<nav-bar title="地址簿" :handleToLink="handleToLink"></nav-bar>
<view class="address" v-if="netStatus">
<view class="seachBox">
<uni-search-bar cancelButton="none" placeholder="请输入姓名/手机号" v-model="searchValue" @input="input"
@cancel="cancel" @clear="clear">
<template v-slot:searchIcon>
<view class="search-icon"></view>
</template>
</uni-search-bar>
</view>
<view class="list-container">
<scroll-view v-if="list.data.length > 0" scroll-y :style="scrollHeight" lower-threshold="30"
@scrolltolower="LoadMoreCustomers">
<!-- 列表内容 -->
<view v-for="(item, index) in list.data" @click.stop.prevent="
isManage ? checkbox(index, item) : handleToAddressInfo(item.id)
" :key="index" class="address-list" :class="isManage ? 'isChecked' : ''">
<view class="checkbox" v-if="isManage">
<view class="checkRadio">
<radio style="transform: scale(0.77)" color="#F23C24" :value="String(index)"
:checked="item.selected" />
</view>
</view>
<view class="address-item" :class="isManage ? 'isChecked' : ''">
<view class="address-name">{{ item.name }}</view>
<view class="address-phone">{{ item.phoneNumber }}</view>
<view class="address-address">
{{
item.province
? item.province.name +
item.city.name +
item.county.name +
item.address
: ''
}}
</view>
<view class="line"></view>
<view class="address-item-footer" :class="type === 'get' ? 'active' : ''">
<view class="save-address" v-if="type !== 'get'" @click.stop="
handleSaveToDefaultAddress(item.id, item.isDefault)
">
<view class="checkbox" :class="{ active: Boolean(item.isDefault) }"></view>
<view class="label">默认寄件地址</view>
</view>
<view class="right-box" :class="!isManage ? '' : 'active'">
<view class="edit-btn" @click.stop="handleEditAddress(item)">
<icon></icon>
<text>编辑</text>
</view>
<view class="delete-btn" @click.stop="handledDelete(item.id)">
<icon></icon>
<text>删除</text>
</view>
</view>
</view>
</view>
</view>
<!-- 加载底部 -->
<uni-load-more :status="status" />
</scroll-view>
<!-- 空页面 -->
<view v-else class="empty-box">
<image src="../../static/address-empty.png"></image>
<view>{{ searchValue ? '没有搜索到相关条件的地址' : '暂无数据' }}</view>
</view>
<!-- 全选操作栏 -->
<view class="all-select" v-if="isManage">
<view class="checkbox" @click="selectAll">
<view class="checkRadio">
<radio style="transform: scale(0.77)" :checked="isAllSelect" color="#F23C24" />
</view>
</view>
<view>全选</view>
</view>
<!-- 底部操作栏 -->
<view class="address-footer">
<view class="manage-btn" v-if="list.data.length > 0" @click="handleEdit">{{ isManage ? '完成' : '管理' }}
</view>
<view class="addAddress-btn" :class="
(isManage && deleteIds.data.length) || !isManage ? 'active' : ''
" @click="handleDeleteOrAdd">{{ isManage ? '删除' : '新增地址' }}</view>
</view>
</view>
</view>
<!-- 断网显示的页面 -->
<net-fail v-else :handleToRefresh="handleToRefresh"></net-fail>
<!-- 删除确认对话框 -->
<uni-popup ref="popup" type="dialog" class="address-popup">
<uni-popup-dialog mode="base" :content="isManage ? '确定是否删除所选地址?' : '确定是否删除此条地址?'" :animation="false"
:before-close="true" @close="close" @confirm="confirm">
</uni-popup-dialog>
</uni-popup>
</template>
<script setup>
import {
ref,
reactive,
onMounted,
} from 'vue'
import {
onLoad,
onPullDownRefresh
} from '@dcloudio/uni-app'
import {
getAddressList,
deleteAddress,
editAddress
} from '@/pages/api/address.js'
let scrollHeight = ref('')
let searchValue = ref('')
let popup = ref(null)
let isAllSelect = ref(false)
let isManage = ref(false)
let deleteIds = reactive({
data: [] //删除的地址id集合
})
let list = reactive({
data: [] //列表数据
})
let pageInfo = reactive({
page: 1,
pageSize: 10
})
let status = ref('more') //加载状态
let type = ref('')
let isFromAddress = ref('')
let netStatus = ref(true)
// 监听页面加载执行
onLoad((options) => {
type.value = options.type
isFromAddress.value = options.isFromAddress
uni.getSystemInfo({
success: (res) => {
scrollHeight.value = 'height:' + (res.screenHeight - 190) + 'px'
}
})
})
onMounted(() => {
getList()
})
// 监听下拉刷新
onPullDownRefresh(() => {
pageInfo.page = 1
getList()
})
// 断网刷新
const handleToRefresh = () => {
pageInfo.page = 1
getList()
}
const input = (e) => {
searchValue.value = e
pageInfo.page = 1
getList()
}
const clear = () => {
}
//设置是否为默认寄件地址
const handleSaveToDefaultAddress = (id, isDefault) => {
if (isManage.value) {
return
}
// 修改默认地址
editAddress({
id,
isDefault: isDefault === 1 ? 0 : 1
}).then((res) => {
pageInfo.page = 1
getList()
if (res.code === 200) {
uni.showToast({
title: '修改成功',
icon: 'none',
duration: 1000,
type: 'success'
})
} else {
uni.showToast({
title: '修改成功',
icon: 'none',
duration: 1000, //提示的延迟时间单位毫秒默认1500
type: 'error'
})
}
}).catch(() => {
uni.showToast({
title: '网络异常',
duration: 2000,
icon: 'none'
})
})
}
//返回上一级防止是最后一级报错
const handleToLink = () => {
if (type.value !== 'address') {
uni.navigateBack()
} else {
uni.switchTab({
url: '/pages/my/index'
})
}
}
//跳转回寄件收件选择地址
const handleToAddressInfo = (id) => {
if (type.value === 'address') {
return
} else if (type.value === 'get') {
if (uni.getStorageSync('sendId') === id) return uni.showToast({
title: '寄件地址和收件地址不能选择同一个',
icon: 'none',
duration: 1000
})
} else {
if (uni.getStorageSync('getId') === id) return uni.showToast({
title: '寄件地址和收件地址不能选择同一个',
icon: 'none',
duration: 1000
})
}
// 关闭当前页面,跳转回寄件收件选择地址
uni.redirectTo({
url: '/pages/express-delivery/index?type=' + type.value + '&editOrAdd=edit&id=' + id +
'&isFromAddress=true'
})
}
//批量删除或者新增地址
const handleDeleteOrAdd = () => {
if (isManage.value) {
if (deleteIds.data.length) popup.value.open()
} else {
uni.redirectTo({
url: '/subPages/address-info/index?isFromAddress=' + isFromAddress.value +
'&editOrAdd=add&type=' + type.value
})
}
}
//编辑地址
const handleEditAddress = (item) => {
if (isManage.value) {
return
}
uni.redirectTo({
url: '/subPages/address-info/index?id=' + item.id + '&isFromAddress=' + isFromAddress.value +
'&editOrAdd=edit' +
'&type=' + type.value + '&isDefault=' + item.isDefault
})
}
//获取列表数据
const getList = (flag) => {
status.value = 'loading'
getAddressList({
page: pageInfo.page,
pageSize: pageInfo.pageSize,
keyword: searchValue.value
}).then((res) => {
let arr = res.data.items ? res.data.items : []
status.value = arr.length < 10 ? 'no-more' : 'more'
//用于区分是一次进页面记载数据还是后续上拉加载
if (flag === 'topPull') {
list.data = list.data.concat(arr)
} else {
list.data = arr
}
// 与搜索框等内容关联全选矿和具体选中状态如果list.data中所有的selected都为true即全选全选文字前的radio框高亮
if (list.data.every((item) => item.selected)) {
isAllSelect.value = true
} else {
isAllSelect.value = false
}
uni.stopPullDownRefresh()
netStatus.value = true
console.log(456)
}).catch((err) => {
uni.showToast({
title: '网络异常',
duration: 2000,
icon: 'none'
})
netStatus.value = false
console.log(123)
})
}
//上拉加载
const LoadMoreCustomers = () => {
pageInfo.page = pageInfo.page + 1
if (status.value === 'no-more') {
return
}
getList('topPull')
}
//管理地址簿
const handleEdit = () => {
isManage.value = !isManage.value
}
//删除
const handledDelete = (id) => {
if (isManage.value) {
return
}
popup.value.open()
deleteIds.data.push(id)
}
//关闭删除确认提示框
const close = () => {
popup.value.close()
deleteIds.data = []
}
//确认删除
const confirm = () => {
popup.value.close()
deleteAddress(deleteIds.data).then((res) => {
pageInfo.page = 1
pageInfo.pageSize = 10
getList()
uni.showToast({
title: '删除成功',
icon: 'success',
duration: 1000
})
isManage.value = false
}).catch(() => {
uni.showToast({
title: '网络异常',
duration: 2000,
icon: 'none'
})
})
}
//选中,与取消选中(和全选联动)
const checkbox = (index, item) => {
list.data[index].selected = !list.data[index].selected
// 如果list.data中所有的selected都为true即全选全选前的radio框高亮
if (list.data.every((item) => item.selected)) {
isAllSelect.value = true
} else {
isAllSelect.value = false
}
deleteIds.data = list.data.filter(item => item.selected).map(item => item.id)
}
//全选或者全不选
const selectAll = () => {
isAllSelect.value = !isAllSelect.value
list.data = list.data.map((item) => {
return Object.assign({}, item, {
selected: isAllSelect.value
})
})
deleteIds.data = list.data.filter(item => item.selected).map(item => item.id)
}
</script>
<style src="./index.scss" lang="scss" scoped></style>

View File

@@ -0,0 +1,50 @@
import {
request
} from "../../utils/request.js"
//地址簿列表
export const getAddressList = (params) =>
request({
url: `/address/page`,
method: 'get',
params
})
//查询地址详情
export const getAddressInfoDetail = (params) =>
request({
url: `/address/detail/` + params,
method: 'get',
params
})
//新建地址簿
export const addAddress = (params) =>
request({
url: `/address`,
method: 'post',
params
})
//修改地址簿
export const editAddress = (params) =>
request({
url: `/address`,
method: 'put',
params
})
//删除地址簿
export const deleteAddress = (params) =>
request({
url: `/address`,
method: 'delete',
params
})
//查询用户默认寄件地址
export const defaultAddress = (params) =>
request({
url: `/address/defaultAddress`,
method: 'post',
params
})

View File

@@ -0,0 +1,11 @@
import {
request
} from "../../utils/request.js"
// 获取省市区
export const getProvinces = (params) =>
request({
url: '/areas/children',
method: 'get',
params
})

View File

@@ -0,0 +1,11 @@
import {
request
} from "../../utils/request.js"
// 计算运费
export const calculateFreight = (params) =>
request({
url: '/tasks/calculate',
method: 'post',
params
})

View File

@@ -0,0 +1,18 @@
import {
request
} from "../../utils/request.js"
// 手机号登录
export const login = (params) =>
request({
url: `/user/login`,
method: 'post',
params
})
// 刷新token
export const resetToken = (params) =>
request({
url: `/user/refresh`,
method: 'post',
params
})

View File

@@ -0,0 +1,24 @@
import {
request
} from "../../utils/request.js"
// 获取用户信息
export const getUserInfo = (params) =>
request({
url: `/user/profile`,
method: 'get',
params
})
// 获取用户实名认证
export const getRealNameStatusApi = (params) =>
request({
url: `/user/realNameVerify`,
method: 'post',
params
})
//修改用户信息
export const updateUserInfo = (params) =>
request({
url: `/user/profile`,
method: 'put',
params
})

View File

@@ -0,0 +1,88 @@
import {
request
} from "../../utils/request.js"
// 省市区三级联动
export const getArea = (params) =>
request({
url: `/areas/children`,
method: 'get',
params
})
//获取常用货物列表
export const usualGoodsList = (params) =>
request({
url: `/order-manager/cargo/hot`,
method: 'get',
params
})
//获取货物列表
export const goodsList = (params) =>
request({
url: `/order-manager/cargo/last`,
method: 'get',
params
})
//下单
export const doOrder = (params) =>
request({
url: `/order-manager/order`,
method: 'post',
params
})
//获取订单详情
export const getOrderDetail = (params) =>
request({
url: `/order-manager/order/` + params,
method: 'get',
})
//获取订单列表
export const getOrderList = (params) =>
request({
url: `/order-manager/order/page`,
method: 'post',
params
})
//获取预估总价
export const getEstimatePrice = (params) =>
request({
url: `/order-manager/order/totalPrice`,
method: 'post',
params
})
//取消订单
export const cancelOrder = (params) =>
request({
url: `/order-manager/order/cancel/` + params,
method: 'put',
params
})
//支付订单
export const payOrder = (params) =>
request({
url: `/order-manager/order/pay`,
method: 'put',
params
})
//删除订单
export const deleteOrder = (params) =>
request({
url: `/order-manager/order/del/` + params,
method: 'put',
params
})
//获取查快递的寄件和收件的数量
export const getGoodsNum = (params) =>
request({
url: `/order-manager/order/count`,
method: 'get',
})
//获取订单轨迹
export const getOrderLine = (params) =>
request({
url: `/order-manager/order/track/` + params,
method: 'get',
})

View File

@@ -0,0 +1,32 @@
import {
request
} from "../../utils/request.js"
// 手机号登录
export const phoneLogins = (params) =>
request({
url: `/logins/phone`,
method: 'post',
params
})
// 账号登录
export const userLogins = (params) =>
request({
url: `/login/account`,
method: 'post',
params
})
// 发送短信验证码
export const getsmsCode = (params) =>
request({
url: `/verifyCodes/smsCode`,
method: 'post',
params
})
// 获取用户信息
export const getUserInfo = (params) =>
request({
url: `/users/get`,
method: 'get',
params
})

View File

@@ -0,0 +1,77 @@
.getTimePicker {
::v-deep .uni-popup__wrapper {
height: 680rpx;
background-color: white !important;
border-radius: 24rpx 24rpx 0 0;
}
.header {
display: flex;
height: 56rpx;
padding: 30rpx 38rpx;
align-items: center;
justify-content: space-between;
border-radius: 24rpx 24rpx 0 0;
.header-title {
font-size: 32rpx;
color: #151515;
font-weight: bold;
}
.close {
width: 24rpx;
height: 24rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../../static/icon21.png');
}
}
.time-select{
display: flex;
.select-day{
width: 296rpx;
height: 500rpx;
background: #F6F6F6;
.select-day-item{
height: 108rpx;
line-height: 108rpx;
text-align: center;
font-size: 28rpx;
}
.select-day-item.active{
background: #fff;
color:#E84134 ;
}
}
.select-time{
.time-item{
font-size: 28rpx;
display: flex;
padding-left: 80rpx;
margin-bottom: 46rpx;
.time-value{
padding-right: 126rpx;
}
.time-select{
width: 40rpx;
height: 40rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../../static/gouxuan.png');
}
}
.time-item.active{
color:#E84134 ;
}
::v-deep scroll-view{
height:500rpx ;
}
//隐藏滚动条
::v-deep ::-webkit-scrollbar {
display: none;
}
}
}
}

View File

@@ -0,0 +1,103 @@
<!-- 期待上门时间弹窗 -->
<template>
<view class="getTimePicker">
<uni-popup ref="popup" type="bottom" :safe-area="false">
<view class="header">
<view class="header-title">期望上门时间</view>
<view class="close" @click="handleCancel"></view>
</view>
<!-- 时间选择区域 -->
<view class="time-select">
<view class="select-day">
<view :class="selectedDay === index ?'active':''" class="select-day-item"
@click="handleSelectDay(index,item)" v-for="(item,index) in selectDay" :key='index'>
{{item}}
</view>
</view>
<view class="select-time">
<scroll-view scroll-y :scroll-top="scrollTop" @scroll="scroll">
<view :class="selectedTime === item.value ?'active':''" class="time-item"
v-for="(item,index) in (selectedDay===0?todayList.todos:dateList)" :key="index"
@click='handleSelectTime(item.value,item.label)'>
<view class="time-value">{{item.label}}</view>
<view class="time-select" v-if='selectedTime === item.value'></view>
</view>
</scroll-view>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import {
ref,
reactive,
onMounted,
} from 'vue';
const emits = defineEmits(["@getTime"]);
const popup = ref()
let scrollTop = ref(0) //顶部位置
let selectedDay = ref(0)
let selectedDayLabel = ref('今天')
let selectedTime = ref(0)
let selectedTimeLabel = ref()
const selectDay = reactive(['今天', '明天', '后天'])
let todayList = reactive({
todos: [{
label: '一小时内',
value: 1
}]
})
onMounted(() => {
todayList.todos = [...todayList.todos.concat(
dateList.filter(item => item.value > new Date().getHours())
)]
})
const dateList = reactive(
// 弹窗中的时间列表
Array.from({
length: 11
}, (v, k) => ({
label: `${k + 9}:00-${k + 10}:00`,
value: k + 9
}))
)
const scroll = (e) => {
scrollTop.value = e.detail.scrollTop
}
//选择具体时间段
const handleSelectTime = (index, item) => {
selectedTime.value = index
selectedTimeLabel.value = item
popup.value.close('bottom');
emits('getTime', {
selectedDay: selectedDay.value,
selectedDayLabel: selectedDayLabel.value,
selectedTime: selectedTime.value,
selectedTimeLabel: selectedTimeLabel.value
})
}
//选择哪天
const handleSelectDay = (index, item) => {
selectedDay.value = index
scrollTop.value = 0
selectedTime.value = 0
selectedDayLabel.value = item
}
// 打开弹层
const handleOpen = () => {
popup.value.open('bottom');
};
// 关闭弹层
const handleCancel = () => {
popup.value.close('bottom');
}
// 暴漏给父组件
defineExpose({
handleOpen
});
</script>
<style lang="scss" scoped src='./getTimePicker.scss'></style>

View File

@@ -0,0 +1,80 @@
.payType{
::v-deep .uni-popup__wrapper {
height:480rpx;
background-color: white !important;
border-radius: 24rpx 24rpx 0 0;
padding: 29rpx 38rpx 43rpx;
}
.headers {
display: flex;
height: 56rpx;
align-items: center;
justify-content: space-between;
border-radius: 24rpx 24rpx 0 0;
.header-title {
font-size: 32rpx;
color: #151515;
font-weight: bold;
}
.close {
width: 40rpx;
height: 40rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../../static/guanbi.png');
}
}
.contents{
margin-top: 64rpx;
.content-item{
display: flex;
align-items: center;
justify-content: space-between;
.left-content{
.title{
font-size: 28rpx;
color: #151515;
margin-bottom: 20rpx;
}
.subTitle{
font-size: 24rpx;
color: #888888;
}
}
.right-content{
.active,.checkbox{
width: 50rpx;
height: 50rpx;
background-repeat: no-repeat;
background-size: contain;
}
.checkbox{
background-image: url('../../../static/checkbox.png');
}
.active{
background-image: url('../../../static/checkboxActive.png');
}
}
}
.content-item:last-child{
margin-top: 60rpx;
}
}
.footers{
.btn{
width: 404rpx;
height: 88rpx;
background-color: #E84134;
border-radius: 44rpx;
text-align: center;
line-height: 88rpx;
color: white;
margin: 0 auto;
margin-top: 43rpx;
}
}
}

View File

@@ -0,0 +1,70 @@
<!-- 付款方式弹窗 -->
<template>
<view class="payType">
<uni-popup ref="popup" type="bottom" :safe-area="false">
<view class="headers">
<view class="header-title">付款方式</view>
<view class="close" @click="handleCancel"></view>
</view>
<view class="contents">
<view class="content-item" v-for="(item,index) in list" :key="index" @click="handleChangePayType(item)">
<view class="left-content">
<view class="title">{{item.title}}</view>
<view class="subTitle">{{item.subTitle}}</view>
</view>
<view class="right-content">
<view class="checkbox" :class="{active:item.value===payType}"></view>
</view>
</view>
</view>
<view class="footers" @click="handleCancel">
<view class="btn">确定</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import {
ref,
reactive,
} from 'vue';
const emits = defineEmits(["@getPayType"]);
const popup = ref()
const payType = ref(1)
const list = reactive([
{
title:'寄付',
subTitle:'快递员取件时,寄方可在线支付、扫快递员收款码进行支付',
value:1
},
{
title:'到付',
subTitle:'快递签收后,收方可通过扫快递员收款码进行支付',
value:2
}
])
//选择付款方式
const handleChangePayType =(item)=>{
payType.value = item.value
}
// 打开弹层
const handleOpen = () => {
popup.value.open('bottom');
};
// 关闭弹层
const handleCancel = () => {
popup.value.close('bottom');
emits('getPayType',payType.value)
}
// 暴漏给父组件
defineExpose({
handleOpen
});
</script>
<style lang="scss" src='./payType.scss' scoped></style>

View File

@@ -0,0 +1,351 @@
.express-delivery{
background-color: #F3F5F9 !important;
padding: 20rpx;
height: 80vh;
.address-box{
background: #FFFFFF;
border-radius: 20rpx;
display: flex;
padding: 42rpx 28rpx;
padding-bottom: 0rpx;
.left{
margin-right: 20rpx;
.send,.get{
width: 40rpx;
height: 40prx;
border-radius: 50%;
text-align: center;
line-height: 40rpx;
font-size: 24rpx;
}
.send{
background: #000000;
color: white;
}
.get{
background: #E63E32;
color: white;
}
.line{
width: 2rpx;
height: 120rpx;
border-left: 2rpx dashed #D5D1D1;
margin-left: 18rpx;
}
.active{
height: 153rpx;
}
}
.right{
width: 100%;
position: relative;
.send-people,.get-people{
display: flex;
align-items: center;
justify-content: space-between;
.send-title{
max-width: 490rpx;
height: 100%;
}
.send-sub-title{
color: #151515;
font-size: 32rpx;
margin-bottom: 6rpx;
font-weight: bold;
text{
color: #888888;
font-size: 24rpx;
}
}
.send-desc{
color: #888888;
font-size: 24rpx;
}
.address-enter{
font-weight: bold;
border-left: 2rpx solid #F4F4F4;
padding-left: 28rpx;
font-size: 24rpx;
}
}
.get-people{
margin-bottom: 40rpx;
}
.send-people{
margin-bottom: 40rpx;
}
.line{
width: 100%;
height: 2rpx;
background-color: #F4F4F4;
margin-bottom: 40rpx;
}
}
}
.send-form{
height: 400rpx;
width: 100%;
border-radius: 20rpx;
margin-top: 40rpx;
.tab-box{
display: flex;
position: relative;
background-color: white;
border-radius: 0 20rpx 0 0;
.tab-item{
flex: 1;
text-align: center;
height: 76rpx;
line-height: 76rpx;
font-size: 30rpx;
background-color:#E3E7ED ;
border-radius:0 20rpx 0 20rpx ;
position: relative;
}
.tab-item.active{
font-weight: bold;
height: 96rpx;
line-height: 96rpx;
background-color:white ;
border-radius:20rpx 20rpx 0 0rpx ;
position: relative;
bottom: 20rpx;
}
.isNotActive.tab-item:first-child{
border-radius:20rpx 0rpx 20rpx 0rpx ;
}
}
.tab-box.active{
border-radius: 20rpx 0 0 0;
}
.form-box{
background-color: #FFFFFF;
position: relative;
bottom: 20rpx;
padding: 0 36rpx 0 28rpx;
border-radius: 0 0 20rpx 20rpx;
.form-getTime,.goods-info,.pay-type{
display: flex;
align-items: center;
justify-content: space-between;
height: 96rpx;
border-bottom: 2rpx solid #F4F4F4;
.left{
display: flex;
align-items: center;
.label{
font-size: 26rpx;
color:#151515 ;
font-weight: bold;
}
.required{
margin-left: 12rpx;
width: 62rpx;
height: 30rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../static/required.png');
}
}
.right{
display: flex;
align-items: center;
.nextIcon{
margin-left: 18rpx;
}
.value{
color: #888888;
font-size: 26rpx;
}
.value.active{
color: #151515;
font-weight: bold;
}
}
}
.pay-type{
border-bottom: none;
}
}
}
.footer{
height:172rpx ;
background-color: white;
display: flex;
justify-content: space-between;
position: fixed;
width: 100%;
bottom: 0;
left: 0;
padding-top: 22rpx;
.right{
.btn{
width: 268rpx;
height: 88rpx;
background-color: #CCCCCC;
border-radius: 44rpx;
text-align: center;
line-height: 88rpx;
color: white;
margin-right: 29rpx;
}
.btn.active{
background-color:#E84134 ;
}
}
.left{
margin-left: 29rpx;
.left-top{
font-size:26rpx ;
color:#323232 ;
display: flex;
.all-account{
border-right: 2rpx solid #F4F4F4;
display: flex;
padding-right: 10rpx;
margin-right: 10rpx;
.price{
color: #E73F33;
}
}
.price-detail{
display: flex;
align-items: center;
.arrow{
width: 0;
height: 0;
border: 10rpx solid transparent;
border-top-color: black;
margin-left: 10rpx;
margin-top: 8rpx;
}
}
}
.left-bottom{
display: flex;
align-items: center;
margin-top: 22rpx;
.active,.checkbox{
width: 32rpx;
height: 32rpx;
background-repeat: no-repeat;
background-size: contain;
margin-right: 10rpx;
}
.checkbox{
background-image: url('../../static/checkbox.png');
}
.active{
background-image: url('../../static/checkboxActive.png');
}
.content{
color: #696969;
font-size: 20rpx;
}
}
}
}
.footer.active{
z-index: 9999;
}
.priceDetail{
::v-deep .uni-popup__wrapper {
height:640rpx;
background-color: white !important;
border-radius: 24rpx 24rpx 0 0;
padding: 29rpx 38rpx 150rpx;
}
.header {
display: flex;
height: 56rpx;
// padding: 30rpx 38rpx;
align-items: center;
justify-content: space-between;
border-radius: 24rpx 24rpx 0 0;
.header-title {
font-size: 32rpx;
color: #151515;
font-weight: bold;
}
.close {
width: 40rpx;
height: 40rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../static/guanbi.png');
}
}
.title{
margin-top: 40rpx;
font-size: 26rpx;
color: #151515;
display: flex;
.title-red{
color: #E84134;
}
}
.base-price{
margin-top: 36rpx;
font-size: 26rpx;
color: #151515;
font-weight: bold;
display: flex;
align-items: center;
justify-content: space-between;
}
.price-rule{
font-size: 24rpx;
color: #888888;
margin-top: 20rpx;
}
.billing-weight{
display: flex;
align-items: center;
justify-content: space-between;
height: 80rpx;
background-color:#F5F5F5 ;
border-radius: 4rpx;
padding: 10rpx 27rpx;
margin-top: 22rpx;
.left{
font-size: 24prx;
color: #888888;
}
.right{
font-size: 26rpx;
}
}
.line{
margin-top: 20rpx;
width: 100%;
height: 2rpx;
background-color: #F4F4F4;
}
.add-service,.setTimeout-send{
display: flex;
align-items: center;
justify-content: space-between;
}
.add-service{
font-size: 26rpx;
font-weight: bold;
margin-top: 22rpx;
margin-bottom: 22rpx;
}
.setTimeout-send{
font-size: 26rpx;
.left{
color: #888888;
}
.right{
font-weight: bold;
}
}
}
}

View File

@@ -0,0 +1,578 @@
<template>
<!-- 头部导航栏 -->
<nav-bar title='寄快递' :handleToLink="handleToLink"></nav-bar>
<view class="express-delivery" v-if="netStatus">
<!-- 寄件人收件人信息填写地址簿 -->
<view class="address-box">
<view class="left">
<view class="send"></view>
<view class="line" :class="{active:twoLine>=2}"></view>
<view class="get"></view>
</view>
<view class="right">
<view class="send-people">
<view class="send-title" @click="toSendAddressInfo">
<view class="send-sub-title">
{{senderInfo.name?senderInfo.name:'寄件人信息'}}
<text
v-if="senderInfo.phone">{{senderInfo.phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2")}}</text>
</view>
<view class="send-desc">
{{senderInfo.address?senderInfo.areaLabel+senderInfo.address:'去填写'}}
</view>
</view>
<view class="address-enter" @click="handleToAddress('send')">地址簿</view>
</view>
<view class="line"></view>
<view class="get-people">
<view class="send-title" @click="toGetAddressInfo">
<view class="send-sub-title">
{{geterInfo.name?geterInfo.name:'收件人信息'}}
<text
v-if="geterInfo.phone">{{geterInfo.phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2")}}</text>
</view>
<view class="send-desc">
{{geterInfo.address?geterInfo.areaLabel+geterInfo.address:'去填写'}}
</view>
</view>
<view class="address-enter" @click="handleToAddress('get')">地址簿</view>
</view>
</view>
</view>
<!-- 寄件其他信息填写 -->
<view class="send-form">
<view class="tab-box" :class="activeIndex===1?'active':''">
<view class="tab-item" :class="activeIndex===index?'active':'isNotActive'"
v-for='(item,index) in tabList' @click="changeTab(index)" :key='index'>
{{item}}
</view>
</view>
<view class="form-box">
<view class="toDoor" v-if='activeIndex === 0'>
<!-- 期望上门时间 -->
<view class="form-getTime" @click='handleGetTime'>
<view class="left">
<view class="label">期望上门时间</view>
<view class="required"></view>
</view>
<view class="right">
<view class="value" :class="toDoorTimeLabel?'active':''">
{{toDoorTimeLabel?toDoorTimeLabel:'请选择'}}
</view>
<icon class="nextIcon"></icon>
</view>
</view>
<!-- 物品信息 -->
<view class="goods-info" @click='handleToGoodsInfo'>
<view class="left">
<view class="label">物品信息</view>
<view class="required"></view>
</view>
<view class="right">
<view class="value" :class="goods.goodsName?'active':''">
{{goods.goodsName?(goods.goodsName + ', '+ (goods.weight+'公斤') + (goods.volume?', '+(dealWithVolume(goods.volume/1000000)+'m³'):'')):'请选择'}}
</view>
<icon class="nextIcon"></icon>
</view>
</view>
<!-- 付款方式 -->
<view class="pay-type" @click='handleToPayType'>
<view class="left">
<view class="label">付款方式</view>
</view>
<view class="right">
<view class="value" :class="payMethod?'active':''">
{{payMethod ===1?'寄付':payMethod ===2?'到付':'请选择'}}
</view>
<icon class="nextIcon"></icon>
</view>
</view>
</view>
<!-- 网点自寄 -->
<view class="branch-send" v-else>
网点自寄
</view>
</view>
</view>
<!-- 期待上门时间弹窗 -->
<GetTimePicker ref='timePicker' @getTime="getTime"></GetTimePicker>
<!-- 付款方式弹窗 -->
<PayTypeDialog ref='payType' @getPayType="getPayType"></PayTypeDialog>
<!-- 底部 -->
<view class="footer" :class="{active:isSeachPriceDetail}">
<view class="left">
<view class="left-top" @click="searchPriceDetail">
<view class="all-account">
预估总价
<view class="price">{{feightPrice.expense}}</view>
</view>
<view class="price-detail">
明细
<view class="arrow"></view>
</view>
</view>
<view class="left-bottom">
<view class="active"></view>
<view class="content">阅读并同意电子运单契约条款</view>
</view>
</view>
<view class="right">
<view class="btn" :class="isCanSubmit?'active':''" @click="order">下单</view>
</view>
</view>
<!-- 运费明细弹窗 -->
<uni-popup ref="priceDetail" type="bottom" class="priceDetail">
<view class="header">
<view class="header-title">运费预估</view>
<view class="close" @click="handleCancel"></view>
</view>
<view class="title">
实际费用请以快递员揽收为准
<view class="title-red" @click="openAccountRulesDialog">了解计费规则</view>
</view>
<view class="base-price">
<view class="left">基础运费</view>
<view class="right">{{feightPrice.expense}}</view>
</view>
<view class="price-rule">首重1.0kg{{feightPrice.firstWeight}}续重{{feightPrice.continuousWeight}}/kg</view>
<view class="billing-weight">
<view class="left">计费重量</view>
<view class="right">含包装{{feightPrice.weight}}kg</view>
</view>
<view class="line"></view>
<view class="add-service">
<view class="left">增值服务</view>
<view class="right">¥0</view>
</view>
<view class="setTimeout-send">
<view class="left">礼物定时派送</view>
<view class="right">¥0</view>
</view>
</uni-popup>
</view>
<!-- 断网显示的页面 -->
<net-fail v-else :handleToRefresh="handleToRefresh"></net-fail>
</template>
<script setup>
import {
ref,
reactive,
onMounted,
computed,
nextTick
} from 'vue';
import {
onLoad,
} from '@dcloudio/uni-app';
import {
getAddressInfoDetail,
defaultAddress
} from '@/pages/api/address.js'
import {
doOrder,
getEstimatePrice
} from '@/pages/api/order.js'
import GetTimePicker from './components/getTimePicker.vue';
import PayTypeDialog from './components/payType.vue';
import {
handleSecondQi,
} from '@/utils/index.js'
import {
useStore
} from 'vuex';
const twoLine = ref()
const store = useStore(); //vuex获取、储存数据
const users = store.state.user
const isCanSubmit = computed(() => {
return (geterInfo.name && senderInfo.name && goods.goodsName && payMethod.value && toDoorTimeLabel.value)
})
const timePicker = ref() //期望上门时间组件的引用
const payType = ref() //付款方式弹窗组件的引用
const priceDetail = ref()//运费弹窗明细组件的引用
const isSeachPriceDetail = ref(false)
const toDoorTime = ref('') //预计上门时间
const toDoorTimeLabel = ref('今天 一小时内')
const payMethod = ref(1) //付款方式
const type = ref('') //判断是从寄件地址返回的还是收件地址
const feightPrice = reactive({
expense: '', //运费
weight: '', //计算重量
firstWeight: '', //首重价格
continuousWeight: '' //续重价格
})
const isFromGoods = ref(false)
const stopClick = ref(false)
const goods = reactive({
weight: 1,
volume: 1,
goodsName: '',
goodsType: ''
})
const sendAddress = ref('')
const senderInfo = reactive({
name: '',
phone: '',
address: '',
areaLabel: '',
}) //寄件人信息
const geterInfo = reactive({
name: '',
phone: '',
address: '',
areaLabel: '',
}) //收件人信息
let netStatus = ref(true)
//tab常量
const tabList = reactive(['上门取件',
'网点自寄'
])
//当前
let activeIndex = ref(0)
//打开计费规则弹窗
const openAccountRulesDialog = () => {
uni.navigateTo({
url: '/subPages/account-rules/index'
});
}
onMounted(() => {
feightPrice.expense = users.expense
feightPrice.weight = users.computeWeight
feightPrice.firstWeight = users.firstWeight
feightPrice.continuousWeight = users.continuousWeight
})
onLoad((options) => {
console.log(options,'options')
if (options.type === 'send') {
sendAddress.value = options.id
uni.setStorageSync('sendId', options.id)
} else if (options.type === 'get') {
uni.setStorageSync('getId', options.id)
}
//用于解决点击地址薄选择了非默认地址回来之后被默认地址覆盖的问题
if(!options.id){
getDefaultAddress()
}
//用于解决页面跳转回来数据缺失问题
if (uni.getStorageSync('sendId')) {
searchAddressDetail(uni.getStorageSync('sendId'), 'send')
}
if (uni.getStorageSync('getId')) {
searchAddressDetail(uni.getStorageSync('getId'), 'get')
}
type.value = options.type
goods.volume = users.volume
goods.weight = users.weight
goods.goodsName = users.goodsInfo.name
goods.goodsType = users.goodsInfo.goodsType ? users.goodsInfo.goodsType.id : ''
toDoorTimeLabel.value = users.toDoorTimeLabel || '今天 一小时内'
toDoorTime.value = users.toDoorTime
payMethod.value = users.payMethod
isFromGoods.value = options.isFromGoods
//必须寄件收件人地址和物品信息都选择了才能计算运费
//这里不能将逻辑提前,应该置于赋值后面
if (uni.getStorageSync('getId') && (uni.getStorageSync('sendId') || sendAddress.value) && users.goodsInfo
.name) {
console.log(666)
calcFreight()
}
})
const handleToRefresh = ()=>{
uni.redirectTo({
url:'/pages/express-delivery/index'
})
}
//处理体积如果是超过小数点后四位则保留四位小数,其他情况直接展示
const dealWithVolume = (value) => {
let dot = String(value).indexOf(".");
if (dot != -1) {
let dotCnt = String(value).substring(dot + 1, value.length);
if (dotCnt.length > 4) {
value = value.toFixed(4);
return value
} else {
return value
}
} else {
return value
}
}
const getDefaultAddress = () => {
if (!type.value && !isFromGoods.value) {
defaultAddress().then((res) => {
if (res.data) {
sendAddress.value = res.data.id
senderInfo.name = res.data.name
senderInfo.phone = res.data.phoneNumber
senderInfo.address = res.data.address
senderInfo.areaLabel = res.data.province.name + ' ' + res.data.city.name + ' ' + res.data
.county.name
uni.setStorageSync('sendId', res.data.id)
netStatus.value = true
nextTick(()=>{
//用来获取详细地址有几行,从而适配寄和收之间竖线的高度
uni.createSelectorQuery().select('.send-desc').boundingClientRect(res => {
let height = res.height;
let line = height / 15
twoLine.value = line
}).exec();
})
}
}).catch((err) => {
uni.showToast({
title: '网络异常',
duration: 2000,
icon: 'none'
});
netStatus.value = false
})
}
}
//查询地址簿详情,并赋值
const searchAddressDetail = (id, type) => {
getAddressInfoDetail(id).then((res) => {
const {
name,
phoneNumber,
address,
city,
county,
province,
} = res.data
if (type === 'send') {
senderInfo.name = name
senderInfo.phone = phoneNumber
senderInfo.address = address
senderInfo.areaLabel = province.name + ' ' + city.name + ' ' + county.name
} else {
geterInfo.name = name
geterInfo.phone = phoneNumber
geterInfo.address = address
geterInfo.areaLabel = province.name + ' ' + city.name + ' ' + county.name
}
nextTick(()=>{
//用来获取详细地址有几行,从而适配寄和收之间竖线的高度
uni.createSelectorQuery().select('.send-desc').boundingClientRect(res => {
let height = res.height;
let line = height / 15
twoLine.value = line
}).exec();
})
})
}
// 切换tab
const changeTab = (index) => {
if (index === 1) {
return handleSecondQi()
}
activeIndex.value = index
}
//打开选择期望上门时间弹窗
const handleGetTime = () => {
timePicker.value.handleOpen()
}
//打开付款方式弹窗
const handleToPayType = () => {
payType.value.handleOpen()
}
const clearCurrentPageData = () => {
store.commit('user/setGoodsInfo', {})
store.commit('user/setVolume', '')
store.commit('user/setExpense', 0)
store.commit('user/setComputeWeight', 0)
store.commit('user/setFirstWeight', 0)
store.commit('user/setContinuousWeight', 0)
store.commit('user/setToDoorTimeLabel', '')
store.commit('user/setToDoorTime', String(new Date().getFullYear()) + '-' + String(new Date().getMonth() + 1) +
'-' +
new Date().getDate() + ' ' + String(new Date().getHours() + 1) + ':' + String(Number(new Date()
.getMinutes()) < 10 ? '0' + Number(new Date().getMinutes()) : Number(new Date()
.getMinutes())) + ':00')
store.commit('user/setWeight', 1)
store.commit('user/setPayMethod', 1)
}
const handleToLink = () => {
clearCurrentPageData()
uni.removeStorageSync('getId');
uni.removeStorageSync('sendId');
uni.switchTab({
url: '/pages/index/index'
});
}
//跳转到物品信息页面
const handleToGoodsInfo = () => {
uni.navigateTo({
url: '/pages/goodsInfo/index'
});
}
//跳转地址簿
const handleToAddress = (type) => {
uni.navigateTo({
url: '/pages/address/index?type=' + type + '&isFromAddress=false'
});
}
//查看运费明细
const searchPriceDetail = () => {
priceDetail.value.open('bottom')
isSeachPriceDetail.value = true
}
//关闭运费明细弹窗
const handleCancel = () => {
priceDetail.value.close()
isSeachPriceDetail.value = false
}
//重置期望上门时间为最新时间
const resetPickUpTime = ()=>{
if(toDoorTimeLabel.value === '今天 一小时内'){
store.commit('user/setToDoorTime', toDoorTime.value)
}
}
//下单
const order = () => {
if (!isCanSubmit.value) {
return
}
if (stopClick.value) {
return
}
stopClick.value = true
console.log(goods,'下单')
doOrder({
goodNum: 1,
goodsName: goods.goodsName,
goodsType: goods.goodsType,
payMethod: payMethod.value,
pickUpTime:toDoorTimeLabel.value==='今天 一小时内'?String(new Date().getFullYear()) + '-' + String(new Date().getMonth() + 1) + '-' +
new Date().getDate() + ' ' + String(new Date().getHours() + 1) + ':' + String(Number(new Date()
.getMinutes()) < 10 ? '0' + Number(new Date().getMinutes()) : Number(new Date()
.getMinutes())) + ':00': users.toDoorTime,
totalVolume: goods.volume ,
totalWeight: goods.weight,
receiptAddress: uni.getStorageSync('getId'),
sendAddress: sendAddress.value || uni.getStorageSync('sendId'),
pickupType: 0 //0上门取件1网点自寄
}).then((res) => {
console.log(res,'resss')
if (res.code !== 200) {
uni.showToast({
title: res.data.msg,
icon: 'none',
duration: 1000
})
} else {
uni.redirectTo({
url: '/subPages/order-success/index?orderId=' + res.data.id
});
uni.removeStorageSync('getId');
uni.removeStorageSync('sendId');
clearCurrentPageData()
}
stopClick.value = false
}).catch((err)=>{
stopClick.value = false
console.log(err,'err')
})
}
//跳转到寄件人地址信息填写页面
const toSendAddressInfo = () => {
if (sendAddress.value || uni.getStorageSync('sendId')) {
uni.navigateTo({
url: '/subPages/address-info/index?type=send&editOrAdd=edit' + '&id=' +
uni.getStorageSync(
'sendId')
});
} else {
uni.navigateTo({
url: '/subPages/address-info/index?type=send&editOrAdd=add'
});
}
}
//跳转到收件人地址信息填写页面
const toGetAddressInfo = () => {
if (uni.getStorageSync('getId')) {
uni.navigateTo({
url: '/subPages/address-info/index?type=get&editOrAdd=edit' + '&id=' + uni.getStorageSync(
'getId')
});
} else {
uni.navigateTo({
url: '/subPages/address-info/index?type=get&editOrAdd=add'
});
}
}
//获取期望上门时间数据
const getTime = (value) => {
toDoorTimeLabel.value = value.selectedDayLabel + ' ' + value.selectedTimeLabel
toDoorTime.value = String(new Date().getFullYear()) + '-' + String(new Date().getMonth() + 1) + '-' + (
new Date().getDate() + value.selectedDay + ' ' + String((value.selectedTime === 1 ? new Date()
.getHours() + 1 : value.selectedTime) + ':00:00'))
store.commit('user/setToDoorTimeLabel', toDoorTimeLabel.value)
store.commit('user/setToDoorTime', toDoorTime.value)
}
//获取付款方式数据
const getPayType = (value) => {
payMethod.value = value
store.commit('user/setPayMethod', value)
}
//计算运费
const calcFreight = () => {
console.log(goods,'计算运费')
getEstimatePrice({
goodNum: 1,
goodsName: goods.goodsName,
goodsType: goods.goodsType,
payMethod: payMethod.value,
pickUpTime: toDoorTime.value,
totalVolume: goods.volume ,
totalWeight: goods.weight,
receiptAddress: uni.getStorageSync('getId'),
sendAddress: uni.getStorageSync('sendId'),
pickupType: 0 //0上门取件1网点自寄
}).then((res) => {
if (res.code == 200) {
store.commit('user/setExpense', res.data.expense)
store.commit('user/setComputeWeight', res.data.computeWeight)
store.commit('user/setFirstWeight', res.data.firstWeight)
store.commit('user/setContinuousWeight', res.data.continuousWeight)
feightPrice.expense = res.data.expense
feightPrice.weight = res.data.computeWeight
feightPrice.firstWeight = res.data.firstWeight
feightPrice.continuousWeight = res.data.continuousWeight
} else {
uni.showToast({
title: res.msg,
duration: 1000,
icon: 'none'
});
}
})
}
</script>
<style src='./components/getTimePicker.scss' lang="scss"></style>
<style src='./components/payType.scss' lang="scss"></style>
<style src="./index.scss" lang="scss"></style>

View File

@@ -0,0 +1,179 @@
.goodsSearch{
background-color: white;
padding: 38rpx 40rpx 0rpx 40rpx;
.searchBox-title{
display: flex;
justify-content: space-between;
align-items: center;
.title{
font-size: 32rpx;
color: #0F0F0F;
font-weight: bold;
.label{
display: inline-block;
width: 62rpx;
height: 30rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../../static/required.png');
margin-left: 10rpx;
}
}
.stopSend{
font-size: 24rpx;
color: #888888;
display: flex;
align-items: center;
.gantanhao{
display: inline-block;
width: 40rpx;
height: 40rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../../static/gantanhao.png');
}
}
}
.selected-goods{
padding-top: 32rpx;
overflow: hidden;
.goods{
position: relative;
margin-bottom: 46rpx;
border: 2rpx solid #E63E32;
border-radius: 32rpx;
font-size: 24rpx;
color:#E63E32 ;
text-align: center;
line-height: 34rpx;
padding:15rpx 22rpx 15rpx 18rpx ;
height: 34rpx;
display: inline-block;
image{
position: absolute;
right: 0rpx;
width: 40rpx;
height: 40rpx;
bottom: 10rpx;
top: -20rpx;
}
}
}
.seachBox{
display: flex;
align-items: center;
::v-deep .uni-searchbar{
padding-left: 0rpx!important;
.uni-searchbar__box{
border-radius: 34rpx!important;
justify-content: flex-start;
}
}
uni-search-bar{
flex: auto;
}
.search-icon{
width: 40rpx;
height: 40rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../../static/search.png');
}
.search-btn{
font-weight: bold;
font-size: 28rpx;
}
}
.recent-send,.recent-send-goods,.hot-send-goods{
padding: 20rpx 40rpx 0rpx 0rpx;
.recent-send-title{
font-size: 26rpx;
color: #0F0F0F;
}
.recent-send-list{
display: flex;
flex-wrap: wrap;
padding-bottom: 44rpx;
.recent-send-item{
margin-right: 20rpx;
margin-top: 35rpx;
font-size: 24rpx;
color: #0F0F0F;
padding:15rpx 22rpx 15rpx 18rpx ;
height: 34rpx;
background: #F4F4F4;
border-radius: 32rpx;
text-align: center;
line-height: 34rpx;
}
}
}
.recent-send-goods{
.title{
font-size: 32rpx;
color: #0F0F0F;
font-weight: bold;
}
}
.hot-send-goods{
font-size: 28rpx;
padding-top: 0rpx;
.title{
font-size: 28rpx;
color: #0F0F0F;
font-weight: bold;
}
}
.search-list{
.seatch-list-item{
display: flex;
justify-content: space-between;
align-items: center;
height: 102rpx;
border-bottom: 2rpx solid #F4F4F4;
.label{
font-size: 28rpx;
color: #151515;
}
.classify{
font-size: 28rpx;
color: #888888;
}
}
}
::v-deep .uni-popup{
.uni-popup__wrapper{
background-color:white!important;
padding:36rpx 33rpx 43rpx 33rpx ;
border-radius: 24rpx 24rpx 0 0;
}
.title{
font-size: 30rpx;
color: #151515;
text-align: center;
margin-bottom: 34rpx;
font-weight: bold;
}
.content{
font-size: 28rpx;
color: #151515;
line-height: 40prx;
margin-top: 28rpx;
}
.btn{
width: 404rpx;
height: 88rpx;
background-color: #E84134;
border-radius: 44rpx;
text-align: center;
line-height: 88rpx;
color: white;
margin: 0 auto;
margin-top: 42rpx;
}
}
}

View File

@@ -0,0 +1,270 @@
<!-- 物品类型弹窗页面 -->
<template>
<view class="goodsSearch">
<!-- 头部 -->
<view class="searchBox-title">
<view class="title">
物品名称
<view class="label"></view>
</view>
<view class="stopSend" @click="openForbidGoodsDialog">
禁寄物品
<view class="gantanhao"></view>
</view>
</view>
<!-- 搜索框 -->
<view class="seachBox" v-if="!isSelectedGoods">
<uni-search-bar :cancelButton='isFocus && searchValue?"none":"auto"' :focus="isFocus" placeholder="请输入搜索内容"
v-model="searchValue" @blur="blur" @focus="focus" @input="input" @cancel="cancel" @clear="clear">
<template v-slot:searchIcon>
<view class="search-icon"></view>
</template>
</uni-search-bar>
<view class="search-btn" @click="userDefined" v-if="searchValue && isFocus">确定</view>
</view>
<!-- 最近寄件 -->
<view class="recent-send-goods" v-if='!isSelectedGoods && recentSendList.data.length && !isInput'>
<view class="title">最近寄件</view>
<view class="recent-send-list">
<view class="recent-send-item" v-for="(item,index) in recentSendList.data" :key='index'
@click="handleClick(item)">
{{item.name}}{{item.goodsType?'('+item.goodsType.name+')':''}}
</view>
</view>
</view>
<!-- 选择的物品 -->
<view class="selected-goods" v-if="isSelectedGoods">
<view class="goods" @click.prevent="handleSelectedGoods">
<image src='../../../static/shanchu-after.png' @click.stop="handleCancelGood"></image>
{{goods.info.name}}{{goods.info.goodsType?'('+goods.info.goodsType.name+')':""}}
</view>
</view>
<!-- 热门寄件 -->
<view class="hot-send-goods" v-if='!isSelectedGoods && !isInput && isFocus'>
<view class="title">热门寄件</view>
<view class="recent-send-list">
<view class="recent-send-item" v-for="(item,index) in hotSendList.data" :key='index'
@click="handleClick(item)">
{{item.name}}{{item.goodsType?'('+item.goodsType.name+')':''}}
</view>
</view>
</view>
<!-- 模糊查询出的列表 -->
<view class="search-list" v-if="isInput">
<view class="seatch-list-item" @click="handleClick(item)" v-for="(item,index) in dimSearchList.data"
:key="index">
<view class="label">{{item.name}}</view>
<view class="classify">{{item.name}}{{item.goodsType?'('+item.goodsType.name+')':''}}</view>
</view>
</view>
<!-- 禁寄物品弹窗 -->
<uni-popup ref="popup" type="bottom" :safe-area="false">
<view class="title">禁止寄递物品目录</view>
<view class="content">
1.枪支(含仿制品主要零部件)弹药
</view>
<view class="content">
2管制器具如匕首三棱刮刀带有自锁装置的弹簧刀(跳刀)催泪器等
</view>
<view class="content">
3.爆炸物品如炸药雷管导火索烟花鞭炮摔炮拉炮砸炮等
</view>
<view class="content">
4.压缩和液化气体及其容器如氢气甲烷乙烷乙炔打火机氯气压缩氧气氮气等
</view>
<view class="content">
5.易燃液体如汽油柴油煤油桐油丙酮乙醚油漆生漆酒精松香油等
</view>
<view class="content">
6.易燃固体自燃物质遇水易燃物质如红磷硫磺固体酒精火柴活性炭等
</view>
<view class="content">
7.氧化剂和过氧化物如高锰酸盐高氯酸盐氧化氢双氧水等
</view>
<view class="content">
8.毒性物质如砷砒霜汞化物铊化物氰化物硒粉苯酚剧毒农药等
</view>
<view class="content">
9.生化制品传染性感染性物质如病菌炭疽寄生虫排泄物医疗废弃物尸骨动物器官等
</view>
<view class="content">
10.放射性物质如铀钚等
</view>
<view class="btn" @click="closeForbidGoodsDialog">知道了</view>
</uni-popup>
</view>
</template>
<script setup>
import {
ref,
reactive,
onMounted,
} from 'vue';
import {
usualGoodsList,
goodsList
} from '@/pages/api/order.js'
import {
useStore
} from 'vuex';
const store = useStore(); //vuex获取、储存数据
const users = store.state.user
const emits = defineEmits(["@getGoodsInfo"]);
const props = defineProps({
isShowOther: {
type: Function,
required: true
},
})
const goods = reactive({
info: {}
})
const isSelectedGoods = ref(false) //是否选择了物品
const popup = ref()
const searchValue = ref('')
const isFocus = ref(false) //是否搜索框为聚焦状态
const isInput = ref(false) //是否搜索框为输入状态
const isUpload = ref(true) //是否输入框加载完毕
//模糊查询出的列表数据
const dimSearchList = reactive({
data: []
})
//热门寄件物品
const hotSendList = reactive({
data: []
})
const recentSendList = reactive({
data: [],
})
onMounted(() => {
getData()
})
const getData = () => {
usualGoodsList({
name: ''
}).then((res) => {
if (res.data) {
hotSendList.data = res.data.slice(0, 6)
}
}).catch((err) => {
uni.showToast({
title: '网络异常',
duration: 2000,
icon: 'none'
});
})
isSelectedGoods.value = users.goodsInfo.name
if (isSelectedGoods.value) goods.info = users.goodsInfo
goodsList().then((res) => {
if (res.data) {
recentSendList.data = res.data.slice(0, 5)
}
}).catch((err) => {
uni.showToast({
title: '网络异常',
duration: 2000,
icon: 'none'
});
})
}
const handleSelectedGoods = () => {
searchValue.value = goods.info.name
isFocus.value = true
isInput.value = true
isSelectedGoods.value = false
dimSearch(searchValue.value)
props.isShowOther(true, 'always')
}
//模糊查询列表数据
const dimSearch = (key) => {
if (!isUpload.value) return
isUpload.value = false
usualGoodsList({
name: key
}).then((res) => {
dimSearchList.data = res.data
isUpload.value = true
})
}
const input = (e) => {
isFocus.value = e ? true : false
isInput.value = Boolean(e)
if (!isUpload.value) return
searchValue.value = e
dimSearch(e)
props.isShowOther(e ? true : false)
}
const cancel = () => {
isInput.value = false
props.isShowOther(false)
}
const clear = () => {
props.isShowOther(true)
}
const blur = () => {
console.log('blur')
}
const focus = () => {
isFocus.value = true
props.isShowOther(true)
}
//用户自定义的物品
const userDefined = () => {
goods.info = {
name: searchValue.value
}
isSelectedGoods.value = Boolean(searchValue.value)
props.isShowOther(false)
emits('getGoodsInfo', {
name: searchValue.value
})
isFocus.value = false
}
//取消物品选择
const handleCancelGood = () => {
goods.info = {}
store.commit('user/setGoodsInfo', {})
emits('getGoodsInfo', {})
isSelectedGoods.value = false
searchValue.value = ''
isFocus.value = false
isInput.value = false
}
//点击标签物品
const handleClick = (item) => {
searchValue.value = item.value
isFocus.value = true
goods.info = item
isSelectedGoods.value = true
isInput.value = false
props.isShowOther(false)
emits('getGoodsInfo', item)
}
//打开禁寄物品弹窗
const openForbidGoodsDialog = () => {
popup.value.open('bottom');
}
//关闭禁寄物品弹窗
const closeForbidGoodsDialog = () => {
popup.value.close();
}
</script>
<style lang="scss" scoped src='./goodsSearch.scss'></style>

View File

@@ -0,0 +1,109 @@
.weightAndVolume{
background-color: white;
margin-top: 20rpx;
padding:56rpx 40rpx ;
position: relative;
z-index: 1;
margin-bottom: 200rpx;
.volume-box{
margin-top: 50rpx;
.isVolumeInfo{
display: flex;
align-items: center;
justify-content: space-between;
.isVolumeInfo-title{
font-size: 24rpx;
color: #888888;
margin-right: 18rpx;
}
::v-deep .uni-switch-input::before{
background-color: #CCCCCC;
width: 120rpx;
}
::v-deep .uni-switch-input.uni-switch-input-checked:after{
transform: translateX(60rpx);
}
::v-deep .uni-switch-input{
width: 120rpx;
}
switch{
position: relative;
left: 20rpx;
}
}
}
.weight-box,.volume-box,.isVolumeInfo-title-box{
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
.unit{
position: absolute;
right: 126rpx;
top:16rpx ;
}
.weight-box-title,.volume-box-title{
font-weight: bold;
font-size: 32rpx;
color: #0F0F0F;
}
.uni-numbox{
height: 76rpx;
.uni-numbox__value{
height: 76rpx!important;
margin: 0;
background-color: #F9F9F9!important;
width: 220rpx;
}
.uni-numbox__plus,.uni-numbox__minus{
width: 76rpx;
border-radius: 0rpx 36rpx 36rpx 0;
background-color: #ECECEC!important;
.uni-numbox--text{
span{
font-weight: bold;
}
}
}
.uni-numbox__minus{
border-radius: 36rpx 0rpx 0rpx 36rpx;
}
}
}
.isVolumeInfo-title-box{
justify-content: flex-end;
margin-top: 10rpx;
.unit{
}
}
.long-width-height{
display: flex;
align-items: center;
margin-top: 16rpx;
.cheng{
margin: 0 12rpx;
height: 19rpx;
line-height: 30rpx;
}
.long,.width,.height{
::v-deep .uni-input-wrapper,.uni-input{
background-color: #F4F4F4;
border-radius: 36rpx;
width: 198rpx;
height: 74rpx;
text-align: center;
}
}
}
.accounting-rules{
font-size: 24rpx;
color: #888888;
margin-top: 40rpx;
.red{
color: #E84134;
font-size: 24rpx;
text-decoration: underline;
}
}
}

View File

@@ -0,0 +1,244 @@
<!-- 重量和体积 -->
<template>
<view class="weightAndVolume">
<!-- 重量 -->
<view class="weight-box">
<view class="weight-box-title">预估重量</view>
<!-- <uni-number-box max="9999" min="1" :value="weight" @change="changeWeight" /> -->
<view class="number-box">
<view class="minus-btn" :class="isLessThan ? 'active' : ''" @click="handleMinus">-</view>
<input class="uni-input" type="digit" maxlength="4" v-model="weight" @blur="handleWeigthBlur"/>
<view class="add-btn" :class="isExceed ? 'active' : ''" @click="handleAdd">+</view>
</view>
<view class="unit">kg</view>
</view>
<!-- 体积 -->
<view class="volume-box">
<view class="volume-box-title">总体积</view>
<view class="isVolumeInfo">
<view class="isVolumeInfo-title">补充体积预估费用更准确</view>
<switch color="#1DC779" style="transform:scale(0.7)" @change="switchChange" :checked="isVolumeInfo" />
</view>
</view>
<!-- 体积输入框 -->
<view class="isVolumeInfo-title-box" v-if='isVolumeInfo'>
<uni-number-box />
<view class="number-box">
<view class="minus-btn" :class="isLessThanVolume ? 'active' : ''" @click="handleVolumeMinus">-</view>
<input class="uni-input" type="digit" maxlength="6" v-model="volume" @blur="handleVolume" />
<view class="add-btn" :class="isExceedVolume ? 'active' : ''" @click="handleVolumeAdd">+</view>
</view>
<view class="unit"></view>
</view>
<!-- 长宽高输入框 -->
<view class="long-width-height" v-if="isVolumeInfo">
<view class="long">
<input class="uni-input" type="digit" :value="long" maxlength="3" placeholder="长 cm"
@input="longFun" />
</view>
<view class="cheng">*</view>
<view class="width">
<input class="uni-input" type="digit" :value="width" maxlength="3" placeholder="宽 cm"
@input="widthFun" />
</view>
<view class="cheng">*</view>
<view class="height">
<input class="uni-input" type="digit" :value="height" maxlength="3" placeholder="高 cm"
@input="heightFun" />
</view>
</view>
<view class="accounting-rules">
实际质量与体积以收派员确定为准物品在包装后重量可能会增加重量体积大时会体积重量收费
<text class="red" @click="openAccountRulesDialog">了解计费规则</text>
</view>
</view>
</template>
<script setup>
import {
ref,
onMounted,
} from 'vue';
import {
useStore
} from 'vuex';
const emits = defineEmits(["@getWeight", '@getVolume']);
let isLessThan = ref(true); //判断重量是否小于0.1
let isExceed = ref(false); //判断重量是否大于9999
let isLessThanVolume = ref(true); //判断体积是否小于0.0001m³
let isExceedVolume = ref(false); //判断体积是否大于99m³
const weight = ref(1) //重量
const volume = ref(0) //体积
const long = ref() //长
const width = ref() //宽
const height = ref() //高
const isVolumeInfo = ref(false)
const store = useStore(); //vuex获取、储存数据
const users = store.state.user
onMounted(() => {
weight.value = users.weight
width.value = users.width
height.value = users.height
long.value = users.long
volume.value = users.volume ? (Number(users.volume) / 1000000) : 0
isVolumeInfo.value = users.width && users.long && users.height
})
// 减重量
const handleMinus = () => {
// 重量减去1
if (weight.value > 1) {
weight.value--;
isExceed.value = false; //右侧加号去除置灰
weight.value = weight.value.toFixed(1);
}
if (weight.value <= 1) {
isLessThan.value = true; //左侧减号置灰
if (weight.value <= 0.1) {
weight.value = 0.1
}
}
emits('getWeight', weight.value)
};
// 加重量
const handleAdd = () => {
// 重量加1
if (weight.value < 9999) {
++weight.value;
isLessThan.value = false; //左侧减号去除置灰
}
if (weight.value === 9999) {
isExceed.value = true; //右侧加号置灰
}
if (weight.value <= 1) {
// weight.value = 1;
isLessThan.value = true; //左侧减号置灰
}
emits('getWeight', weight.value)
};
//触发重量输入如果输入0自动判断为1kg,最小可输入值为0.1kg,最大值为9999kg
const handleWeigthBlur = e => {
let value = e.detail.value;
if (value < 0.1) {
value = 1;
isLessThan.value = true; //左侧减号置灰
} else {
if (value >= 0.1 && value <= 1) {
isLessThan.value = true;
} else {
isLessThan.value = false; //左侧减号去除置灰
}
if (value >= 9999) {
isExceed.value = true; //右侧加号置灰
value = 9999;
uni.showToast({
title: '重量最大可不能超过9999kg',
duration: 1000,
icon: 'none'
});
} else {
isExceed.value = false; //右侧加号去除置灰
}
}
weight.value = value
emits('getWeight', weight.value)
};
// 体积
const handleVolume = e => {
let value = Number(e.detail.value);
if (value < 0.0001) {
isLessThanVolume.value = true;
value = 0;
} else {
isLessThanVolume.value = false;
if (value >= 999) {
isExceedVolume.value = true; //右侧加号置灰
value = 999;
uni.showToast({
title: '体积最大可不能超过999m³',
duration: 1000,
icon: 'none'
});
} else {
value = Number(e.detail.value);
isExceedVolume.value = false; //右侧加号去除置灰
}
}
volume.value = value
emits('getVolume', (volume.value) * 1000000, long.value, width.value, height.value)
};
// 减体积
const handleVolumeMinus = () => {
// 体积减去1
if (volume.value > 1) {
volume.value--;
isExceedVolume.value = false; //右侧加号去除置灰
volume.value = volume.value.toFixed(1);
}
// 体积
if (volume.value <= 1) {
isLessThanVolume.value = true; //左侧减号置灰
if (weight.value <= 0.0001) {
weight.value = 0.0001
}
}
emits('getVolume', (volume.value) * 1000000, long.value, width.value, height.value)
};
// 加体积
const handleVolumeAdd = () => {
// 体积加1
if (volume.value < 999) {
++volume.value;
isLessThanVolume.value = false; //左侧减号去除置灰
}
if (volume.value === 999) {
isExceedVolume.value = true; //右侧加号置灰
}
emits('getVolume', (volume.value) * 1000000, long.value, width.value, height.value)
};
//是否显示具体体积
const switchChange = (e) => {
isVolumeInfo.value = e.detail.value
}
//修改长度
const longFun = (e) => {
long.value = e.detail.value
let valueFun = (Number(long.value) * Number(width.value) * Number(height.value)) / 1000000
volume.value = valueFun < 0.0001 ? 0.0001 : valueFun
emits('getVolume', ((volume.value) * 1000000), e.detail.value, width.value, height.value)
}
//修改宽度
const widthFun = (e) => {
width.value = e.detail.value
let valueFun = (Number(long.value) * Number(width.value) * Number(height.value)) / 1000000
volume.value = valueFun < 0.0001 ? 0.0001 : valueFun
emits('getVolume', (volume.value) * 1000000, long.value, e.detail.value, height.value)
}
//修改高度
const heightFun = (e) => {
height.value = e.detail.value
let valueFun = (Number(long.value) * Number(width.value) * Number(height.value)) / 1000000
volume.value = valueFun < 0.0001 ? 0.0001 : valueFun
emits('getVolume', (volume.value) * 1000000, long.value, width.value, e.detail.value)
}
//打开计费规则弹窗
const openAccountRulesDialog = () => {
uni.navigateTo({
url: '/subPages/account-rules/index'
});
}
</script>
<style src="./weightAndVolume.scss" lang="scss" scoped></style>

View File

@@ -0,0 +1,37 @@
.goodsInfo-box{
height: 100vh;
background-color:#F3F5F9
}
.goods-info{
background-color:#F3F5F9;
overflow: scroll;
.footer{
height: 164rpx;
width: 100%;
background-color: white;
position: fixed;
bottom: 0;
left: 0;
z-index: 9;
.btn{
width: 404rpx;
height: 88rpx;
background-color: #CCCCCC;
border-radius: 44rpx;
text-align: center;
line-height: 88rpx;
color: white;
margin: 0 auto;
margin-top: 17rpx;
}
.btn.active{
background-color:#E84134
}
}
}
.isAll{
background-color: white;
height: 100vh;
}

View File

@@ -0,0 +1,87 @@
<template>
<view class="goodsInfo-box">
<!-- 头部导航栏 -->
<nav-bar title='物品信息'></nav-bar>
<view class="goods-info" :class="{isAll:isShow}">
<!-- 物品名称搜索组件 -->
<GoodsSeach :isShowOther="isShowOther" @getGoodsInfo="getGoodsInfo"></GoodsSeach>
<!-- 预估重量 -->
<WeightAndVolume v-if="!isShow" @getWeight="getWeight" @getVolume="getVolume"></WeightAndVolume>
<!-- 底部 -->
<view class="footer" v-if="!isShow">
<view class="btn" :class="isActive?'active':''" @click="confirm">确定</view>
</view>
</view>
</view>
</template>
<script setup>
import {
ref,
reactive,
onMounted,
computed
} from 'vue';
import {
useStore
} from 'vuex';
import GoodsSeach from './components/goodsSearch.vue'
import WeightAndVolume from './components/weightAndVolume.vue'
const weight = ref(1)
const volume = ref('')
const goods = reactive({
info: {}
})
const store = useStore(); //vuex获取、储存数据
const users = store.state.user
const isShow = ref(false)
let isAlways = ref()
onMounted(() => {
goods.info = users.goodsInfo
})
const isActive = computed(() => {
return Boolean(users.goodsInfo.name)
})
const isShowOther = (flag, type) => {
if (type === 'always') {
isAlways.value = true
}
isShow.value = type === 'always' ? true : flag
}
//子组件传出来填写的重量的值
const getWeight = (value, ) => {
weight.value = value
store.commit('user/setWeight', value)
}
//子组件传出来填写的体积的值
const getVolume = (value, long, width, height) => {
volume.value = value
store.commit('user/setLong', long)
store.commit('user/setWidth', width)
store.commit('user/setHeight', height)
store.commit('user/setVolume', value)
}
//子组件传出来填写的物品的值
const getGoodsInfo = (value) => {
goods.info = value
store.commit('user/setGoodsInfo', value)
}
const confirm = () => {
if (!goods.info.name) {
return uni.showToast({
title: '请选择物品',
duration: 1000,
icon: 'none'
})
}
uni.redirectTo({
url: '/pages/express-delivery/index?isFromGoods=true'
});
}
</script>
<style src="./components/weightAndVolume.scss" lang="scss"></style>
<style lang="scss" src='./components/goodsSearch.scss'></style>
<style lang="scss" src='./index.scss'></style>

View File

@@ -0,0 +1,196 @@
.maxHeight{
height: 1170rpx;
}
.orderList{
margin: 40rpx 30rpx 0;
position: relative;
bottom: 49rpx;
::v-deep .scrollView{
padding-bottom: 40rpx;
}
//隐藏滚动条
::v-deep ::-webkit-scrollbar {
display: none;
}
.title{
font-size: 30rpx;
color:#333334 ;
font-weight: bold;
margin-bottom: 10rpx;
}
.see-more{
font-size: 24rpx;
text-align: center;
margin-top: 22rpx;
display: flex;
align-items: center;
justify-content: center;
.arrow{
margin-left: 10rpx;
margin-top: 4rpx;
width: 12rpx;
height: 18rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../../static/icon15.png');
}
}
.empty-data{
.empty-data-image{
width: 400rpx;
height: 240rpx;
text-align: center;
margin: 0 auto;
display: block;
}
.tips{
color: #818181;
font-size: 28rpx;
text-align: center;
margin-top: 40rpx;
margin-left: 25rpx;
}
}
.notLogin{
margin-top: 150rpx;
.toLogin-btn{
width: 240rpx;
height: 88rpx;
background: #E63E32;
border-radius: 44rpx;
color: white;
font-size: 30rpx;
margin: 0 auto;
text-align: center;
line-height: 88rpx;
}
.tips{
color:#6C6C6C ;
font-size: 24rpx;
text-align: center;
margin-top: 30rpx;
}
}
.order-item{
position: relative;
background: #FFFFFF;
border-radius: 24rpx;
padding:28rpx 32rpx 20rpx;
margin-top: 20rpx;
.orderNumber{
font-size: 20rpx;
color: #878787;
display: flex;
align-items: center;
.copy{
width: 40rpx;
height: 40rpx;
margin-left: 10rpx;
}
}
.area-to-area{
display: flex;
align-items: center;
justify-content: space-between;
margin-top:40rpx ;
margin-left: 42rpx;
margin-right: 42rpx;
margin-bottom: 20rpx;
.sendBox,.getBox{
text-align: center;
.sendArea,.getArea{
font-size: 30rpx;
font-weight: bold;
}
.sendName,.getName{
font-size: 24rpx;
color: #878787;
}
}
.order-status{
.status{
font-size: 24rpx;
color: #878787;
padding-left: 20rpx;
}
.arrow{
width: 160rpx;
height: 20rpx;
background-repeat: no-repeat;
background-size: contain;
}
.green-arrow{
background-image: url(data:image/png;base64,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);
}
.red-arrow{
background-image: url(data:image/png;base64,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);
}
.gray-arrow{
background-image: url('data:image/png;base64,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');
}
}
}
.order-detail{
margin-top: 12rpx;
overflow: hidden;
border-bottom: 2rpx solid #F4F4F4;
padding-bottom: 26rpx;
.detail-item{
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
font-size: 24rpx;
margin-top: 12rpx;
uni-text,text{
color: #878787;
display: inline-block;
}
}
}
.btn-box{
.btn{
width: 144rpx;
height: 56rpx;
background: #FFFFFF;
border: 2rpx solid #DDDDDD;
border-radius: 28rpx;
text-align: center;
line-height: 56rpx;
font-size: 24rpx;
color:#303030 ;
}
.wait-pay{
margin-top: 29rpx;
display: flex;
align-items: center;
justify-content: space-between;
.price{
font-size: 26rpx;
font-weight: bold;
uni-text,text{
color: #E84134;
}
}
}
.btn-list{
display: flex;
justify-content: flex-end;
margin-top: 19rpx;
.btn{
margin-left: 20rpx;
}
}
}
.paymentStatus{
position: absolute;
right: 29rpx;
top: 27rpx;
image{
width: 76rpx;
height: 30rpx;
}
}
}
}

View File

@@ -0,0 +1,281 @@
<template>
<view class="orderList">
<view v-if="!isLogin" class="notLogin">
<view class="toLogin-btn" @click="toLogin">登录/注册</view>
<view class="tips">登录后可查看快递信息</view>
</view>
<view v-else-if="!allOrderList.data.length && isLogin" class="empty-data">
<image src="../../../static/emptyData.png" class="empty-data-image"></image>
<view class="tips">没有运单~</view>
</view>
<view v-else>
<view class="title">运单信息</view>
<view class="order-item" v-for="(item,index) in allOrderList.data" :key="index"
@click='handleToOrderInfo(event,item.id,item.transportOrderId)'>
<view class="orderNumber">
{{[23000,22000,230011].includes(item.status)?'订':'运'}}单号{{[23000,22000,230011].includes(item.status)?item.id:item.transportOrderId}}
<image src="../../../static/pickUp-copy.png" class="copy"
@click.stop="handleCopy([23000,22000,230011].includes(item.status)?item.id:item.transportOrderId)">
</image>
</view>
<view class="area-to-area">
<view class="sendBox">
<view class="sendArea">{{item.senderCity.name}}</view>
<view class="sendName">{{item.senderName}}</view>
</view>
<view class="order-status">
<view class="status">
{{showOrderStatus(item.status)}}
</view>
<view class="arrow" :class="
[[21000,23000,23001,23005,23008].includes(item.status)?'green-arrow':'',
[23009,23010].includes(item.status)?'red-arrow':'',
[230011,22000].includes(item.status)?'gray-arrow':'']
"></view>
</view>
<view class="getBox">
<view class="getArea">{{item.receiverCity.name}}</view>
<view class="getName">{{item.receiverName}}</view>
</view>
</view>
<view class="order-detail">
<!-- 已取件运输信息 -->
<view v-if="item.status ===23001 && item.transportOrderPointVOS" class="detail-item">
<text>已取件</text>
{{ item.transportOrderPointVOS.length>0?item.transportOrderPointVOS[item.transportOrderPointVOS.length-1].info:''}}
</view>
<!-- 运输中信息 -->
<view v-if="[23005,23008].includes(item.status) && item.transportOrderPointVOS" class="detail-item">
<text>运送中</text>{{ item.transportOrderPointVOS.length>0?item.transportOrderPointVOS[item.transportOrderPointVOS.length-1].info:''}}
</view>
<!-- 已签收 -->
<view v-if="item.status ===23009 && item.transportOrderPointVOS" class="detail-item">
<text>已签收</text>{{ item.transportOrderPointVOS.length>0?item.transportOrderPointVOS[item.transportOrderPointVOS.length-1].info:''}}
</view>
<!-- 已拒收 -->
<view v-if="item.status ===23010 && item.transportOrderPointVOS" class="detail-item">
<text>已拒收</text>{{ item.transportOrderPointVOS.length>0?item.transportOrderPointVOS[item.transportOrderPointVOS.length-1].info:''}}
</view>
<!-- 预计上门时间 -->
<view v-if="item.status ===23000 " class="detail-item">
<text>预计上门时间</text>{{item.estimatedStartTime}}
</view>
<!-- 取消时间 -->
<view v-if="item.status ===230011 " class="detail-item"><text>取消时间</text>{{item.updated}}</view>
<!-- 预计送达时间 -->
<view v-if="[23001,23005,23008,23010].includes(item.status) " class="detail-item">
<text>预计送达时间</text>{{item.estimatedArrivalTime}}
</view>
<!-- 已关闭时间 -->
<view v-if="item.status ===22000 " class="detail-item"><text>关闭时间</text>{{item.updated}}</view>
<!-- 签收时间 -->
<view v-if="item.status ===23009 " class="detail-item"><text>签收时间</text>{{item.updated}}</view>
</view>
<!-- 功能按钮区域 -->
<view class="btn-box">
<view class="btn-list" @click.stop="handleSecondQi">
<view class="btn" v-if="[23000,23001,23005,23008,23010].includes(item.status)">分享</view>
<view class="btn" v-if='item.status===23000' @click.stop="handleOrderCancel(item.id)">取消寄件
</view>
<view class="btn" v-if="[22000,230011,23009].includes(item.status)"
@click.stop="handleOrderDelete(item.id)">删除</view>
</view>
</view>
<view class="paymentStatus"
v-if="item.paymentStatus && [23001,23005,23008,23009,23010].includes(item.status)">
<image :src="item.paymentStatus===1?'../../../static/daizhifu.png':'../../../static/yizhifu.png'">
</image>
</view>
</view>
<view class="see-more" @click="handleSeeMore">
查看更多
<view class="arrow"></view>
</view>
</view>
<!-- 删除确认对话框 -->
<uni-popup ref="popup" type="dialog" class='address-popup'>
<uni-popup-dialog mode="base" :content="'确定是否删除此条订单?'" :animation='false' :before-close="true"
@close="close" @confirm="confirm">
</uni-popup-dialog>
</uni-popup>
</view>
</template>
<script setup>
import {
ref,
reactive,
onMounted,
} from 'vue';
import {
getOrderList,
deleteOrder
} from '@/pages/api/order.js'
import {
onShow,
} from '@dcloudio/uni-app';
import {
handleSecondQi
} from '@/utils/index.js'
import {
useStore
} from 'vuex';
const store = useStore(); //vuex获取、储存数据
const emits = defineEmits(["@stopRefresh"]);
let pageInfo = reactive({
page: 1,
pageSize: 10
})
let status = ref('more') //加载状态
let scrollTop = ref(0) //顶部位置
let allOrderList = reactive({
data: []
})
let orderId = ref()
let isLogin = ref('')
let popup = ref(null)
//关闭删除确认提示框
const close = () => {
popup.value.close()
orderId.value = ''
}
onShow((options) => {
isLogin.value = uni.getStorageSync('token')
console.log(!isLogin, (!allOrderList.data.length && isLogin.value), '6666')
})
onMounted(() => {
getOrderListFunc()
})
//复制
const handleCopy = (value) => {
uni.setClipboardData({
data: value,
showToast: false,
success: () => {
uni.hideToast(); // 隐藏弹出提示
uni.hideKeyboard(); // 隐藏软键盘
uni.showToast({
title: '复制成功',
icon: 'success',
duration: 1000
})
}
});
}
//确认删除订单
const confirm = () => {
popup.value.close()
deleteOrder(orderId.value).then((res) => {
pageInfo.page = 1
pageInfo.pageSize = 10
getOrderListFunc()
uni.showToast({
title: '删除成功',
icon: 'success',
duration: 1000
})
}).catch((err) => {
uni.showToast({
title: '网络异常',
duration: 2000,
icon: 'none'
});
})
}
//删除订单
const handleOrderDelete = (id) => {
orderId.value = id
popup.value.open()
}
//跳转到取消订单页面
const handleOrderCancel = (id) => {
uni.navigateTo({
url: '/subPages/order-cancel/index?orderId=' + id
})
}
const toLogin = () => {
uni.navigateTo({
url: '/pages/login/index'
})
}
const getOrderListFunc = (flag) => {
status.value = 'loading'
getOrderList({
page: pageInfo.page,
pageSize: pageInfo.pageSize,
}).then((res) => {
console.log(res, 'getOrderListFunc')
if (res.data) {
allOrderList.data = res.data.items ? res.data.items.slice(0, 3) : []
}
})
}
//查看更多
const handleSeeMore = () => {
uni.switchTab({
url: '/pages/pickup/index'
})
}
//根据状态去显示对应的运单状态文案
const showOrderStatus = (status) => {
switch (status) {
case 21000:
return '待支付';
case 23000:
return '待取件';
case 230011:
return '已取消';
case 23001:
return '已取件';
case 23005:
return '运送中';
case 22000:
return '已关闭';
case 23008:
return '派送中';
case 23009:
return '已签收';
case 23010:
return '已拒收';
}
}
//跳转到订单详情页面
const handleToOrderInfo = (event, id, transportOrderId) => {
uni.navigateTo({
url: '/subPages/order-info/index?orderId=' + id + '&transportOrderId=' + transportOrderId
});
store.commit('user/setIsToOrderInfo', true)
}
//下拉加载更多
const LoadMoreCustomers = () => {
if (status.value === 'no-more') {
return
}
pageInfo.page = pageInfo.page + 1
getOrderListFunc('topPull')
}
//
const indexGetOrderListFunc = () => {
pageInfo.page = 1
getOrderListFunc()
}
// 暴漏给父组件
defineExpose({
indexGetOrderListFunc,
LoadMoreCustomers
});
</script>
<style src="./orderList.scss" lang="scss" scoped></style>

View File

@@ -0,0 +1,68 @@
@import url('@/styles/theme.scss');
.scrollView{
background-color: #F3F5F9 !important;
height: 100vh;
}
.homePage{
background-color: #F3F5F9 !important;
position: relative;
// padding-bottom: 30rpx;
min-height: 100vh;
image{
width: 100%;
height: 400rpx;
}
.feature-top{
height: 80rpx;
margin: 0 28rpx;
background: #FFFFFF;
border-radius: 24rpx;
display: flex;
padding: 48rpx;
align-items: center;
justify-content: space-between;
position: relative;
bottom: 48rpx;
.feature-top-line{
position: absolute;
left: 50%;
height: 114rpx;
background-color:#F4F4F4 ;
width: 2rpx;
}
}
.jikuaidi,.saomaji,.piliangji,.saomaji{
display: flex;
image{
width: 80rpx;
height: 80rpx;
margin-right: 15rpx;
}
.des-title{
font-size: 30rpx;
font-weight: bold;
color: #151515;
}
.des-dec{
font-size: 22rpx;
color: #878787;
}
}
.feature-bottom{
display: flex;
padding: 20rpx 32rpx;
align-items: center;
justify-content: space-between;
position: relative;
bottom: 49rpx;
.piliangji,.saomaji{
height:128rpx ;
width: 334rpx;
background: #FFFFFF;
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
}

View File

@@ -0,0 +1,91 @@
<!-- 首页 -->
<template>
<view class="homePage">
<!-- banner图 -->
<image src='../../static/tupian-banner.png' />
<!-- 功能列表 -->
<!-- 寄快递和扫码寄 -->
<view class="feature-top">
<view class="jikuaidi" @click="toExpressDelivery">
<image src='../../static/fe-jikuaidi.png' />
<view class="des">
<view class="des-title">寄快递</view>
<view class="des-dec">1小时上门取件</view>
</view>
</view>
<view class="feature-top-line"></view>
<view class="saomaji" @click="handleSecondQi">
<image src='../../static/fe-saomaji.png' />
<view class="des">
<view class="des-title">扫码寄</view>
<view class="des-dec">扫二维码下单</view>
</view>
</view>
</view>
<!-- 批量寄和礼物寄 -->
<view class="feature-bottom">
<view class="piliangji" @click="handleSecondQi">
<image src='../../static/fe-piliangji.png' />
<view class="des">
<view class="des-title">批量寄</view>
<view class="des-dec">便捷寄多个快递</view>
</view>
</view>
<view class="saomaji" @click="handleSecondQi">
<image src='../../static/fe-liwuji.png' />
<view class="des">
<view class="des-title">礼物寄</view>
<view class="des-dec">保留神秘寄</view>
</view>
</view>
</view>
<!-- 运单列表 -->
<OrderList ref='orderListRef' @stopRefresh="stopRefreshFunc"></OrderList>
</view>
</template>
<script setup>
import {
ref
} from 'vue';
import {
onShow,
onPullDownRefresh,
} from '@dcloudio/uni-app';
import {
handleSecondQi
} from '@/utils/index.js'
//运单列表
import OrderList from './components/orderList';
import {
useStore
} from 'vuex';
const store = useStore(); //vuex获取、储存数据
const users = store.state.user
let orderListRef = ref()
// ------定义变量------
onShow(() => {
// if (users.isToOrderInfo) {
// store.commit('user/setIsToOrderInfo', false)
// } else {
// orderListRef.value && orderListRef.value.indexGetOrderListFunc()
// }
orderListRef.value && orderListRef.value.indexGetOrderListFunc()
})
// ------生命周期------
onPullDownRefresh(() => {
orderListRef.value.indexGetOrderListFunc()
});
//
const stopRefreshFunc = () => {
uni.stopPullDownRefresh();
}
//跳转到寄快递页面
const toExpressDelivery = () => {
uni.navigateTo({
url: uni.getStorageSync('token') ? '/pages/express-delivery/index' : '/pages/login/index'
});
}
</script>
<style src="./index.scss" lang="scss" scoped></style>

View File

@@ -0,0 +1,84 @@
.loginBox {
background-color: white;
height: 100vh;
::v-deep .uni-popup__wrapper {
height:500rpx;
background-color: white !important;
border-radius: 24rpx 24rpx 0 0;
padding: 65rpx 39rpx 180rpx;
}
.logo-box{
text-align: center;
margin-top: 204rpx;
image{
width: 166rpx;
height: 174rpx;
}
.title{
font-size: 32rpx;
color:#20232A ;
font-weight: bold;
}
}
.open-dialog{
height: 88rpx;
background: #E63E32;
border-radius: 44rpx;
color: white;
text-align: center;
line-height: 88rpx;
margin: 228rpx 46rpx 0;
}
uni-popup{
.header{
display: flex;
align-items: center;
justify-content: flex-end;
border-radius: 24rpx 24rpx 0 0;
image{
height: 35rpx;
width:35rpx ;
}
.title{
font-weight: bold;
font-size: 30rpx;
margin: 0 auto;
}
}
.content{
font-size: 28rpx;
margin-top: 35rpx;
.tips{
margin-top: 50rpx;
}
text{
font-weight: bold;
}
}
.footer{
display: flex;
margin-top: 90rpx;
.btn{
width: 276rpx;
height: 88rpx;
line-height: 88rpx;
border: 2rpx solid #E84134;
border-radius: 44rpx;
font-size: 30rpx;
}
.cancel-btn{
background: #FFFFFF;
color: #E84134;
}
.agree-btn{
background: #E84134;
color: white;
}
}
}
}

View File

@@ -0,0 +1,106 @@
<!-- 手机短信登录页 -->
<template>
<view class="loginBox">
<!-- 头部导航栏 -->
<NavBar title='登录'></NavBar>
<view class="logo-box">
<image src='../../static/userLogo.png'></image>
</view>
<view class="open-dialog" @click="handleOpen">微信登录</view>
<!-- 服务条款及隐私政策弹窗 -->
<uni-popup ref="popup" type="bottom" :safe-area="false">
<view class="header">
<view class="title">服务条款及隐私政策</view>
<image src='../../static/guanbi.png' @click="handleClose"></image>
</view>
<view class="content">
<view>
在您注册成为神领快递会员的过程中您需要通过点击同意的形式在线签署<text>神领快递服务条款</text><text>神领快递隐私政策</text>请您务必仔细阅读充分理解条款内容后再点击同意尤其是以粗体并下划线标识的条款因为这些条款可能会明确您应履行的义务或对您的权利有所限制
</view>
<view class="tips">
请您注意如果您不同意上述服务条款隐私政策或其中任何约定请您停止注册
</view>
</view>
<view class="footer">
<button class="cancel-btn btn" @click="handleClose">不同意</button>
<button class="agree-btn btn" open-type="getPhoneNumber"
@getphonenumber="decryptPhoneNumber">同意</button>
</view>
</uni-popup>
</view>
</template>
<script setup>
import {
ref,
} from 'vue';
// 接口
import {
login
} from '../api/login.js';
import NavBar from '@/components/Navbar/index.vue'
import {
useStore
} from 'vuex';
// ------定义变量-----
const popup = ref();
const store = useStore(); //vuex获取、储存数据
const handleOpen = () => {
popup.value.open()
}
// 跳转到首页
const decryptPhoneNumber = (e) => {
handleClose()
console.log('fff')
wx.login({
success(res) {
//允许授权
if (e.detail.errMsg === 'getPhoneNumber:ok' && e.target.errMsg === 'getPhoneNumber:ok') {
if (!store.state.user.isLoginSuccess) return uni.showToast({
title: '请勿重复登录',
duration: 2000,
icon: 'none'
});
store.commit('user/setIsLoginSuccess', false)
login({
code: res.code,
phoneCode: e.detail.code
}).then((res) => {
console.log(res,'----------------')
//将token存到缓存中后续在统一请求头上加上token短令牌
uni.setStorageSync('token', res.data.accessToken);
//长令牌
uni.setStorageSync('refreshToken', res.data.refreshToken);
//登录成功后跳转到首页
uni.switchTab({
url: '/pages/index/index'
});
store.commit('user/setIsLoginSuccess', true)
}).catch((err) => {
console.log(err,'==================')
uni.showToast({
title: '网络异常',
duration: 2000,
icon: 'none'
});
store.commit('user/setIsLoginSuccess', true)
})
} else {
console.log(err,'++++++++++++')
uni.redirectTo({
url: '/pages/login/index'
});
}
},
})
}
const handleClose = () => {
popup.value.close()
}
</script>
<style src="./index.scss" lang="scss" scoped></style>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,198 @@
<!-- 我的页面 -->
<template>
<view class="my">
<!-- banner图 -->
<view class="banner">
<!-- 头像用户名 -->
<view class="headBox" @click="toLogin">
<image :src="avatarUrl" />
<view class="userName">{{nickName}}</view>
</view>
</view>
<!-- 地址簿实名认证专属快递员 -->
<view class="list-top">
<view class="list-item" @click="handleToAddress">
<view class="left">
<image class="icon" src='../../static/my-address.png' />
<view class="label">地址簿</view>
</view>
<image class="arrow" src='../../static/icon15.png' />
</view>
<view class="list-item" @click="handleTorealName">
<view class="left">
<image class="icon" src='../../static/my-name.png' />
<view class="label">实名认证</view>
</view>
<image class="arrow" src='../../static/icon15.png' />
</view>
<view class="list-item" @click="handleSecondQi">
<view class="left">
<image class="icon" src='../../static/my-send.png' />
<view class="label">专属快递员</view>
</view>
<image class="arrow" src='../../static/icon15.png' />
</view>
</view>
<view class="list-bottom" v-if="token">
<picker mode="selector" @change="changeSex" :value="sex" :range="sexList">
<view class="list-item sex">
<view class="label">性别</view>
<view class="item-value">{{sex?'男':'女'}}</view>
<image class="arrow" src='../../static/icon15.png' />
</view>
</picker>
<view class="line"></view>
<picker mode="date" :value="birthday" :start="startDate" :end="endDate" @change="getDateChange">
<view class="list-item">
<view class="label">生日</view>
<view class="item-value">{{birthday}}</view>
<image class="arrow" src='../../static/icon15.png' />
</view>
</picker>
</view>
<view class="logout" @click="handleLogout" v-if="token">退出登录</view>
</view>
<!-- end -->
</template>
<script setup>
import {
ref,
reactive,
} from 'vue';
import {
getUserInfo,
updateUserInfo
} from '@/pages/api/my.js';
import {
onShow,
} from '@dcloudio/uni-app';
import {
handleSecondQi
} from '@/utils/index.js'
const token = ref()
const sexList = reactive(['女', '男'])
let nickName = ref('')
let avatarUrl = ref('')
let startDate = ref()
let endDate = ref()
let idCard = ref('')
let name = ref('')
let sex = ref(1)
let birthday = ref('1995-09-01')
const isRealNameAuth = ref(false)
onShow(() => {
startDate.value = getDate('start')
endDate.value = getDate('end')
nickName.value = uni.getStorageSync('nickName') || '神领用户'
avatarUrl.value = uni.getStorageSync('avatarUrl') || '../../static/defaultHeadImg.png'
token.value = uni.getStorageSync('token')
baseUserInfo()
})
//退出登录
const handleLogout = () => {
uni.removeStorageSync('token');
uni.removeStorageSync('nickName');
uni.removeStorageSync('avatarUrl');
uni.switchTab({
url: '/pages/index/index'
});
}
const baseUserInfo = () => {
getUserInfo().then((res) => {
if (res) {
isRealNameAuth.value = Boolean(res.data.idCardNoVerify)
idCard.value = res.data.idCardNo || ''
name.value = res.data.name
sex.value = res.data.sex
birthday.value = res.data.birthday
nickName.value = res.data.phone
uni.setStorageSync('nickName', res.data.phone);
}
})
}
const getDate = (type) => {
const date = new Date()
let year = date.getFullYear()
let month = date.getMonth() + 1
let day = date.getDate()
if (type === "start") {
year = year - 60
} else {
year = year + 2
}
month = month > 9 ? month : "0" + month
day = day > 9 ? day : '0' + day
return `${year}-${month}-${day}`
}
const toLogin = () => {
if (uni.getStorageSync('token')) {
getUserInfoFunc()
} else {
uni.navigateTo({
url: '/pages/login/index'
});
}
}
//跳转到地址簿
const handleToAddress = () => {
uni.navigateTo({
url: uni.getStorageSync('token') ? '/pages/address/index?type=address&isFromAddress=true' :
'/pages/login/index'
});
}
//跳转到实名认证页面
const handleTorealName = () => {
if (!uni.getStorageSync('token')) {
return uni.navigateTo({
url: '/pages/login/index'
});
}
if (isRealNameAuth.value) {
uni.navigateTo({
url: '/subPages/authentication-success/index?name=' + name.value + '&idCard=' + idCard.value
});
} else {
uni.navigateTo({
url: '/subPages/realName-authentication/index'
});
}
}
const getDateChange = (e) => {
updateUserInfo({
birthday: e.detail.value
}).then((res) => {
baseUserInfo()
}).catch((err) => {
uni.showToast({
title: '网络异常',
duration: 2000,
icon: 'none'
});
})
}
const changeSex = (e) => {
updateUserInfo({
sex: Number(e.detail.value)
}).then((res) => {
baseUserInfo()
}).catch((err) => {
uni.showToast({
title: '网络异常',
duration: 2000,
icon: 'none'
});
})
}
</script>
<style src="./index.scss" lang="scss" scoped></style>

View File

@@ -0,0 +1,138 @@
<template>
<!-- 待取件 -->
<DealParcel ref="dealparcel" :tabIndex="tabIndex" :isAdmin="isAdmin" @checkbox="checkbox" @getSelected="getSelected"></DealParcel>
<!-- end -->
<!-- 已取件 -->
<AlreadyParcel ref="already" :tabIndex="tabIndex" :isAdmin="isAdmin" @checkbox="checkbox"></AlreadyParcel>
<!-- end -->
<!-- 已取件 -->
<CancelParcel :tabIndex="tabIndex" ref="cancel" :isAdmin="isAdmin" @checkbox="checkbox" @handleOpen="handleOpen"></CancelParcel>
<!-- end -->
<!-- 提示窗 -->
<UniPopup ref="popup" :tipInfo="tipInfo" @handleClick="handleClick"></UniPopup>
<!-- end -->
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { useStore } from 'vuex';
//接口
import { taskDelete } from '@/pages/api/index.js';
// 导入组件
// 待取件
import DealParcel from './components/dealParcel.vue';
// 已取件
import AlreadyParcel from './components/alreadyParcel.vue';
// 已取件
import CancelParcel from './components/cancelParcel.vue';
// 弹层
import UniPopup from '@/components/uni-popup/index.vue';
// 获取父组件数据
const props = defineProps({
// tab切换数据
tabBars: {
type: Object,
default: () => ({})
},
tabIndex: {
type: Number,
default: 0
},
// 当前高度
scrollH: {
type: String,
default: ''
},
// 是否触发管理按钮
isAdmin: {
type: Boolean,
default: false
},
// 获取当前筛选的距离升序还是降序
orderDistance: {
type: Number,
default: 0
},
// 获取当前筛选的时间升序还是降序
orderTime: {
type: Number,
default: 0
},
// 获取当前筛选超时
filterOverTime: {
type: Number,
default: 0
}
});
// ------定义变量------
const emit = defineEmits(''); //子组件向父组件事件传递
const store = useStore(); //设置、获取储存的数据
const users = store.state.user;
let popup = ref();
let dealparcel = ref();
let already = ref();
let cancel = ref();
const tipInfo = ref('确定要删除吗?');
let taskId = ref('');
let scrollH = ref(0); //滚动高度
// ------生命周期------
onMounted(() => {
// 获取屏幕信息
uni.getSystemInfo({
success: res => {
scrollH.value = res.windowHeight;
}
});
});
// ------定义方法------
// 获取已经选的任务
const getSelected = array => {
emit('getSelected', array);
};
// 获取待取件列表方法
const dealPList = () => {
dealparcel.value.getList();
};
// 获取已取件列表方法
const alreadList = () => {
already.value.getList();
};
// 获取取消件列表方法
const cancelList = () => {
cancel.value.getList();
};
// 确认删除
const handleClick = async () => {
await taskDelete(taskId.value)
.then(res => {
if (res.code === 200) {
dealparcel.value.getList();
return uni.showToast({
title: '删除成功!',
duration: 1000,
icon: 'none'
});
}
})
.catch(err => {});
};
// 选项框点击事件,参数是数据的下标
const checkbox = index => {
emit('checkbox', index);
};
// 删除弹层id
const handleOpen = id => {
popup.value.dialogOpen();
taskId.value = id;
};
//把数据、方法暴漏给父组件
defineExpose({
dealPList,
alreadList,
cancelList
});
</script>
<style></style>

View File

@@ -0,0 +1,200 @@
.maxHeight{
height: 1170rpx;
}
.orderList{
margin: 40rpx 28rpx 0;
position: relative;
margin-top: 0rpx;
::v-deep .scrollView {
height:1300rpx ;
}
//隐藏滚动条
::v-deep ::-webkit-scrollbar {
display: none;
}
.title{
font-size: 30rpx;
color:#333334 ;
font-weight: bold;
margin-bottom: 10rpx;
}
.see-more{
font-size: 24rpx;
text-align: center;
margin-top: 22rpx;
display: flex;
align-items: center;
justify-content: center;
.arrow{
margin-left: 10rpx;
margin-top: 4rpx;
width: 12rpx;
height: 18rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../../static/icon15.png');
}
}
.empty-data{
height:1200rpx ;
overflow: hidden;
image{
width: 400rpx;
height: 240rpx;
text-align: center;
margin: 0 auto;
display: block;
margin-top: 27vh;
}
.tips{
color: #818181;
font-size: 28rpx;
text-align: center;
margin-top: 40rpx;
margin-left: 25rpx;
}
}
.notLogin{
position: relative;
top: 36vh;
.toLogin-btn{
width: 240rpx;
height: 88rpx;
background: #E63E32;
border-radius: 44rpx;
color: white;
font-size: 30rpx;
margin: 0 auto;
text-align: center;
line-height: 88rpx;
}
.tips{
color:#6C6C6C ;
font-size: 24rpx;
text-align: center;
margin-top: 30rpx;
}
}
.order-item{
position: relative;
background: #FFFFFF;
border-radius: 24rpx;
padding:28rpx 32rpx 20rpx;
margin-top: 20rpx;
.orderNumber{
font-size: 20rpx;
color: #878787;
display: flex;
align-items: center;
.copy{
width: 40rpx;
height: 40rpx;
margin-left: 10rpx;
}
}
.area-to-area{
display: flex;
align-items: center;
justify-content: space-between;
margin-top:40rpx ;
margin-left: 42rpx;
margin-right: 42rpx;
margin-bottom: 20rpx;
.sendBox,.getBox{
text-align: center;
.sendArea,.getArea{
font-size: 30rpx;
font-weight: bold;
}
.sendName,.getName{
font-size: 24rpx;
color: #878787;
}
}
.order-status{
.status{
font-size: 24rpx;
color: #878787;
padding-left: 20rpx;
}
.arrow{
width: 160rpx;
height: 20rpx;
background-repeat: no-repeat;
background-size: contain;
}
.green-arrow{
background-image: url(data:image/png;base64,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);
}
.red-arrow{
background-image: url(data:image/png;base64,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);
}
.gray-arrow{
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKYAAAAaCAYAAAA9gCd5AAAAAXNSR0IArs4c6QAABbVJREFUeF7tmk1oXFUUx//nvjeZ1EVFuxErIiIuREFciAgig2A3TaatWrXtTD+giCsXrgQhMwvdKe5URJI23bSRSvqhC9F2I+LGlYgLBatNM0mar8l8vDfvvXvkvnk3TpJJ5s17AyaZdyEQmHvPved/f3PuPecOIWmJAjEUYGaamJgQR48e9WKY2TCUemkssdVfCigolcdExIVCQRQKBdkrBRIwe6Vkn9m5dOmSoaLkhS++eUga7uP5M8M/KFAVpL2QIgGzFyr2mQ0dHc+du7yPPDEBICMMHDlx8tDXNwo3zEwh48aVJAEzroJ9Nl6DNzp6/QED3iRYPhtIUCFBb+ROZa/3As4EzD4DK467+vgeH598DA5PMPA0ABUdRfC3JITx6olTQ9/rvlHnS8CMqlyfjdOgnT9/7Um43iTAjwZQmoEUKvFRgN5lQw6fPHnkpzhwJmD2GWBR3NVH84XRK88x+CIzPwxAlYeMdfZ8OEnQbUjK5s4M/xIVzv8NTF1qaHUsaka33lav7OhSSJTN3A1jlK43izcNlcxcGLv6kpTeRQD7NoFSu+wDS4S/DRgHjp0e+j0KnF2BGQCgwnUvSgKqtrBqJ7Dd1Xq0EoEd35a2UwQwEoIO3a9YLGJ9HU7ZKhaLkdYUYuod0OVFUShk3PGxyWGWPA5gbwco18AJot/IRDaXy/7RbZ0ztOitxdQdoGiyxJgK6Jrk+dErObD8HMAeAPoeGcZ6M3ICvyLlvZzLvTLdTeQMBWbLUZmq17yPiPkJAA1V9A+zwjV91AgJVGtOSkKmdPRlCRcsG+odIaxNIgKz5OnpmQHHsUyQAEt2mKXTjR3TEJibWxB35xbTpM4D5RgTSXBDShm7JhfWn23Vj8EgNgB6AcBgl1BqV5R2JkA/mx6yx85mZ8JGzo4QtN7frJr3KTO/FXGRq7pbdQeOE/9plUBYWJjHUnkJ6v8oTQiB5eUKStOzkLJnL2pRlrJdx+jrVjSBgySJiH4UA8bQ8eMHF8NEzo6TMbMgIlmtOB8S8F5QIlCL7Ti2ndKW5aBhezourrcR+u6qouXC4oIPpiHUibGmhbLjQ7m0gqk7Jf/WrN7TotjZrkT1aF0q84601y3z+5GTQN+xOXg4nz9Q7RQ5t5yQmQ0i8qya946U8pM4kVJtuWW5aNjxT0YF1NLSIubn5xVMkfRXNsrLK5iamlEJU2Q7kSbvz0HN8hKJqzDSb3aCc9Nd1VDW626ePf4yqFmpSBTcwrpQl+BHSXWER+RodTIfqHIZc3OzkWFq2qjgjoJSqlDZhS9J1zgKOABSJOirP/8afh0oYmRkZE11RhtvuyXMbBKRa1Xdg8y4zGBd3e96CxWIjUYTyrhNAVWtVDA7Owt1N4/SmlCu+FBKmUTKKBrGHONn9oIwtv+Re89mMhm33bG+ATQdKZ0aP+9I9xqA+4LaVbeR0j9lHUeiXlMJfKi2GW3+9c+yLMyUSvCkuqNufQtpMxtFjJTRvgGh3O3bTupYN0H0Wf509u2OYOpEp1HlZ1y4V8F4MCjndB0pleSuJ1GvOqrqHeu4VEDZtoVSqQTXdTtB2Xa3SRAqK1VM3S4lkXJ7fB/8BJqIP86dPvyuWlLr7zlXgdNQ1mq8n6T7LQNPAai2eQ8N5ZaULGrVBqnEImRTIX5jZwI816NSaVrYDVtl4H6yskXbYEdF11qlLm5PTdPq8R1iXdxcT1JDCrmBXXbTm6gK9+/nzxz6oC2Y2igz77Us3D/owQJFSHSahthqWOmqJwYHwpCp6lGmtB1HWm1KE1yplNPl8nI6jQHYHbyX0rY9j21hif+i/D3ArVtTe0xPpMxUiptvA1s3VxC5FcuqlGu2aZqRToxOc/T75+5Ams2GTYZJ5mv5oX9an6gTwfudjm3q/2ZZeQLsNt2w3bqs9b8ISwDcrTu9w/1KwNzhG7hbl5+AuVt3dof79S+Hyb052GDwIQAAAABJRU5ErkJggg==');
}
}
}
.order-detail{
margin-top: 12rpx;
overflow: hidden;
border-bottom: 2rpx solid #F4F4F4;
padding-bottom: 26rpx;
.detail-item{
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
font-size: 24rpx;
margin-top: 12rpx;
uni-text,text{
color: #878787;
display: inline-block;
}
}
}
.btn-box{
.btn{
width: 144rpx;
height: 56rpx;
background: #FFFFFF;
border: 2rpx solid #DDDDDD;
border-radius: 28rpx;
text-align: center;
line-height: 56rpx;
font-size: 24rpx;
color:#303030 ;
}
.wait-pay{
margin-top: 29rpx;
display: flex;
align-items: center;
justify-content: space-between;
.price{
font-size: 26rpx;
font-weight: bold;
uni-text,text{
color: #E84134;
}
}
}
.btn-list{
display: flex;
justify-content: flex-end;
margin-top: 19rpx;
.btn{
margin-left: 20rpx;
}
}
}
.paymentStatus{
position: absolute;
right: 29rpx;
top: 27rpx;
image{
width: 76rpx;
height: 30rpx;
}
}
}
}

View File

@@ -0,0 +1,299 @@
<template>
<view class="orderList" :style="{'paddingTop':capsuleBottom +'px'}">
<view v-if="!isLogin" class="notLogin">
<view class="toLogin-btn" @click="toLogin">登录/注册</view>
<view class="tips">登录后可查看快递信息</view>
</view>
<view v-else>
<view v-if="!allOrderList.data.length && isLogin" class="empty-data">
<image src="../../../static/emptyData.png"></image>
<view class="tips">{{serchValue?'没有搜索到相关条件的运单':'暂无数据'}}</view>
</view>
<scroll-view v-else class="scrollView" scroll-y lower-threshold="30" @scrolltolower="LoadMoreCustomers">
<view class="order-item" v-for="(item,index) in allOrderList.data" :key="index"
@click='handleToOrderInfo(event,item.id,item.transportOrderId)'>
<view class="orderNumber">
{{[23000,22000,230011].includes(item.status)?'订':'运'}}单号{{[23000,22000,230011].includes(item.status)?item.id:item.transportOrderId}}
<image src="../../../static/pickUp-copy.png" class="copy"
@click.stop="handleCopy([23000,22000,230011].includes(item.status)?item.id:item.transportOrderId)">
</image>
</view>
<view class="area-to-area">
<view class="sendBox">
<view class="sendArea">{{item.senderCity.name}}</view>
<view class="sendName">{{item.senderName}}</view>
</view>
<view class="order-status">
<view class="status">
{{showOrderStatus(item.status)}}
</view>
<view class="arrow" :class="
[[21000,23000,23001,23005,23008].includes(item.status)?'green-arrow':'',
[23009,23010].includes(item.status)?'red-arrow':'',
[230011,22000].includes(item.status)?'gray-arrow':'']
"></view>
</view>
<view class="getBox">
<view class="getArea">{{item.receiverCity.name}}</view>
<view class="getName">{{item.receiverName}}</view>
</view>
</view>
<view class="order-detail">
<!-- 已取件运输信息 -->
<view v-if="item.status ===23001 && item.transportOrderPointVOS" class="detail-item">
<text>已取件</text>{{ item.transportOrderPointVOS.length>0?item.transportOrderPointVOS[item.transportOrderPointVOS.length-1].info:''}}
</view>
<!-- 运输中信息 -->
<view v-if="[23005,23008].includes(item.status) && item.transportOrderPointVOS"
class="detail-item">
<text>运送中</text>{{item.transportOrderPointVOS.length>0?item.transportOrderPointVOS[item.transportOrderPointVOS.length-1].info:''}}
</view>
<!-- 已签收 -->
<view v-if="item.status ===23009 && item.transportOrderPointVOS" class="detail-item">
<text>已签收</text>{{item.transportOrderPointVOS.length>0?item.transportOrderPointVOS[item.transportOrderPointVOS.length-1].info:''}}
</view>
<!-- 已拒收 -->
<view v-if="item.status ===23010 && item.transportOrderPointVOS" class="detail-item">
<text>已拒收</text>{{item.transportOrderPointVOS.length>0?item.transportOrderPointVOS[item.transportOrderPointVOS.length-1].info:''}}
</view>
<!-- 预计上门时间 -->
<view v-if="item.status ===23000 " class="detail-item">
<text>预计上门时间</text>{{item.estimatedStartTime}}
</view>
<!-- 取消时间 -->
<view v-if="item.status ===230011 " class="detail-item"><text>取消时间</text>{{item.updated}}
</view>
<!-- 预计送达时间 -->
<view v-if="[23001,23005,23008,23010].includes(item.status) " class="detail-item">
<text>预计送达时间</text>{{item.estimatedArrivalTime}}
</view>
<!-- 已关闭时间 -->
<view v-if="item.status ===22000 " class="detail-item"><text>关闭时间</text>{{item.updated}}</view>
<!-- 签收时间 -->
<view v-if="item.status ===23009 " class="detail-item"><text>签收时间</text>{{item.updated}}</view>
</view>
<!-- 功能按钮区域 -->
<view class="btn-box">
<view class="btn-list" @click.stop="handleSecondQi">
<view class="btn" v-if="[23000,23001,23005,23008,23010].includes(item.status)">分享</view>
<view class="btn" v-if='item.status===23000' @click.stop="handleOrderCancel(item.id)">取消寄件
</view>
<view class="btn" v-if="[22000,230011,23009].includes(item.status)"
@click.stop="handleOrderDelete(item.id)">删除</view>
</view>
</view>
<view class="paymentStatus"
v-if="item.paymentStatus && [23001,23005,23008,23009,23010].includes(item.status)">
<image
:src="item.paymentStatus===1?'../../../static/daizhifu.png':'../../../static/yizhifu.png'">
</image>
</view>
</view>
<!-- 加载底部 -->
<uni-load-more :status="status" v-if="!isShowMore && isLogin && allOrderList.data.length" />
</scroll-view>
</view>
<!-- 删除确认对话框 -->
<uni-popup ref="popup" type="dialog" class='address-popup'>
<uni-popup-dialog mode="base" :content="'确定是否删除此条订单?'" :animation='false' :before-close="true"
@close="close" @confirm="confirm">
</uni-popup-dialog>
</uni-popup>
</view>
</template>
<script setup>
import {
ref,
reactive,
onMounted,
} from 'vue';
import {
getOrderList,
deleteOrder
} from '@/pages/api/order.js'
import {
onLoad,
onShow,
} from '@dcloudio/uni-app';
import {
handleSecondQi
} from '@/utils/index.js'
import {
useStore
} from 'vuex';
// 获取父组件数据
const props = defineProps({
serchValue: {
type: String
}
})
const store = useStore(); //vuex获取、储存数据
const users = store.state.user
const emits = defineEmits(["@stopRefresh"]);
let pageInfo = reactive({
page: 1,
pageSize: 10,
mailType: 1
})
let status = ref('more') //加载状态
let isShowMore = ref(false) //是否显示更多
let allOrderList = reactive({
data: []
})
let orderId = ref()
let isLogin = ref('')
let popup = ref(null)
//胶囊底部距离头部的距离
let capsuleBottom = ref()
// let height = ref('570rpx')
//关闭删除确认提示框
const close = () => {
popup.value.close()
orderId.value = ''
}
onLoad(() => {
uni.getSystemInfo({
success: (res) => {
capsuleBottom.value = uni.getMenuButtonBoundingClientRect().bottom + 52
}
})
})
onShow(() => {
isLogin.value = uni.getStorageSync('token')
allOrderList.data = users.indexList
})
onMounted(() => {
getOrderListFunc()
})
//复制
const handleCopy = (value) => {
uni.setClipboardData({
data: value,
showToast: false,
success: () => {
uni.hideToast(); // 隐藏弹出提示
uni.hideKeyboard(); // 隐藏软键盘
uni.showToast({
title: '复制成功',
icon: 'success',
duration: 1000
})
}
});
}
//确认删除订单
const confirm = () => {
popup.value.close()
deleteOrder(orderId.value).then((res) => {
pageInfo.page = 1
pageInfo.pageSize = 10
getOrderListFunc()
uni.showToast({
title: '删除成功',
icon: 'success',
duration: 1000
})
}).catch((err) => {
uni.showToast({
title: '网络异常',
duration: 2000,
icon: 'none'
});
})
}
//删除订单
const handleOrderDelete = (id) => {
orderId.value = id
popup.value.open()
}
//跳转到取消订单页面
const handleOrderCancel = (id) => {
uni.navigateTo({
url: '/subPages/order-cancel/index?orderId=' + id
})
}
const toLogin = () => {
uni.navigateTo({
url: '/pages/login/index'
})
}
const getOrderListFunc = (flag) => {
status.value = 'loading'
getOrderList(pageInfo).then((res) => {
console.log(res, '接受到了resovle')
if (res.data) {
console.log(res.data.items && res.data.items.length, 'res.data.items && res.data.items.length')
status.value = (res.data.items && res.data.items.length) < 10 ? 'no-more' : 'more'
if (flag === 'topPull') {
allOrderList.data = allOrderList.data.concat(res.data.items ? res.data.items : [])
} else {
allOrderList.data = res.data.items ? res.data.items : []
}
}
store.commit('user/setIndexList', allOrderList.data)
emits('stopRefresh')
})
}
//根据状态去显示对应的运单状态文案
const showOrderStatus = (status) => {
switch (status) {
case 21000:
return '待支付';
case 23000:
return '待取件';
case 230011:
return '已取消';
case 23001:
return '已取件';
case 23005:
return '运送中';
case 22000:
return '已关闭';
case 23008:
return '派送中';
case 23009:
return '已签收';
case 23010:
return '已拒收';
}
}
//跳转到订单详情页面
const handleToOrderInfo = (event, id, transportOrderId) => {
uni.navigateTo({
url: '/subPages/order-info/index?orderId=' + id + '&transportOrderId=' + transportOrderId
});
store.commit('user/setIsToOrderInfo', true)
}
//下拉加载更多
const LoadMoreCustomers = () => {
if (status.value === 'no-more') {
return
}
pageInfo.page = pageInfo.page + 1
getOrderListFunc('topPull')
}
//
const indexGetOrderListFunc = (params) => {
pageInfo.page = 1
pageInfo = Object.assign({}, pageInfo, params)
getOrderListFunc()
}
// 暴漏给父组件
defineExpose({
indexGetOrderListFunc,
LoadMoreCustomers
});
</script>
<style src="./orderList.scss" lang="scss" scoped></style>

View File

@@ -0,0 +1,18 @@
.tabScroll {
.scroll-row-item {
margin-right: 80rpx;
}
}
.boxTop{
position: fixed;
top: 0;
width: 100%;
z-index: 2;
box-shadow: 0 4rpx 12rpx 0 rgba(0,0,0,0.03);
}
.pickup{
min-height: 100vh!important;
background-color: #F3F5F9;
}

View File

@@ -0,0 +1,108 @@
<!-- 取件页面 -->
<template>
<view class="pickup">
<!-- 搜索nav -->
<SearchPage @handleSearch="handleSearch"></SearchPage>
<!-- end -->
<view class="boxTop" :style="{'paddingTop':capsuleBottom +'px'}">
<!-- tab切换 -->
<UniTab :tabBars="tabBars" ref="tab" @getTabIndex="getTabIndex" :staticNum="staticNum.data"></UniTab>
</view>
<!-- 运单列表 -->
<OrderList ref='orderListRef' :serchValue="serchValue" @stopRefresh="stopRefreshFunc"></OrderList>
</view>
<!-- end -->
</template>
<script setup>
import {
ref,
reactive,
} from 'vue';
import {
onLoad,
onShow
} from '@dcloudio/uni-app';
// 基本数据
import {
DeliveryData
} from '@/utils/commonData.js';
import {
getGoodsNum
} from '@/pages/api/order.js'
// 导入组件
// 搜索组件
import SearchPage from '@/components/uni-search/index.vue';
// tab切换
import UniTab from '@/components/uni-tab/index.vue';
//运单列表
import OrderList from './components/orderList';
// 筛选
const emit = defineEmits(''); //子组件向父组件事件传递
const tab = ref();
const tabBars = DeliveryData;
let tabIndex = ref(0); //当前tab
let staticNum = reactive({
data: [0, 0]
})
// 存储已选内容, 因为这个列表是增删很频繁的所以选用map而不是数组key对应的是数据的下标。至于value存放什么完全由自己定
let selected = reactive(new Map());
let orderListRef = ref() //列表组件引用
//设备栏高度
let deviceNavHeight = ref()
//胶囊顶部距离头部的距离
let capsuleTop = ref()
//胶囊底部距离头部的距离
let capsuleBottom = ref()
//导航栏高度
let all = ref()
//胶囊高度
let capsuleHeight = ref()
let serchValue = ref()//头部搜索栏的关键字
// ------生命周期------
onShow(() => {
getStaticNum()
orderListRef.value && getTabIndex(tabIndex.value)
});
onLoad(() => {
uni.getSystemInfo({
success: (res) => {
deviceNavHeight.value = res.statusBarHeight
capsuleTop.value = uni.getMenuButtonBoundingClientRect().top
capsuleBottom.value = uni.getMenuButtonBoundingClientRect().bottom
all.value = (capsuleTop.value + capsuleBottom.value - deviceNavHeight.value) + 'px'
capsuleHeight.value = uni.getMenuButtonBoundingClientRect().height
}
})
})
// ------定义方法------
// 搜索
const handleSearch = (index) => {
serchValue.value = index.value
orderListRef.value.indexGetOrderListFunc({
keyword: index.value
}) //触发子组件获取列表数据的方法
};
// 获取寄件和收件的数量
const getStaticNum = () => {
getGoodsNum().then((res) => {
if(res.code === 200){
staticNum.data = [res.data['1'],res.data['2']]
}
})
}
// 获取tab切换当前的index
const getTabIndex = index => {
tabIndex.value = index
orderListRef.value.indexGetOrderListFunc({
mailType: index + 1,
}) //触发子组件获取列表数据的方法
};
</script>
<style src="../../styles/expressage.scss" lang="scss" scoped></style>
<style src="./index.scss" lang="scss" scoped></style>