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,83 @@
<template>
<view class="commonUse">
<view class="hometit">常用功能</view>
<view class="commonList">
<view @click="handleChild">
<icon class="icon delivery"></icon>
<text>派件扫描</text>
</view>
<view @click="handleChild">
<icon class="icon sign"></icon>
<text>签收扫描</text>
</view>
<view>
<view @click="handleHistory">
<icon class="icon history"></icon>
<text>全部取派</text>
</view>
</view>
<view>
<view @click="handleNew">
<icon class="icon new"></icon>
<text>消息通知</text>
</view>
</view>
<view>
<navigator url="/pages/freight/index" open-type="redirect">
<icon class="icon freight"></icon>
<text>运费查询</text>
</navigator>
</view>
<view>
<view @click="handleTip">
<icon class="icon tip"></icon>
<text>签收提醒</text>
</view>
</view>
<view @click="handleChild">
<icon class="icon exclusive"></icon>
<text>专属取寄</text>
</view>
</view>
</view>
</template>
<script setup>
import { useStore } from "vuex";
// 获取父组件值、方法
const props = defineProps({});
const store = useStore(); //vuex获取储存数据
// 定义方法
const handleChild = () => {
uni.showToast({
title: "程序员哥哥正在实现中",
duration: 1000,
icon: "none",
});
};
// 历史派件
const handleHistory = () => {
store.commit("user/setTabIndex", 0);
store.commit("user/setNewType", null);
uni.navigateTo({
url: "/pages/history/index",
});
};
// 签收提醒
const handleTip = () => {
store.commit("user/setTaskStatus", -1);
uni.navigateTo({
url: "/pages/news/system?title=签收提醒&type=302",
});
};
// 消息通知
const handleNew = () => {
store.commit("user/setTabIndex", 1);
uni.navigateTo({
url: "/pages/news/index",
});
};
</script>
<style src="../index.scss" lang="scss"></style>

View File

@@ -0,0 +1,48 @@
<template>
<view class="commonData">
<view class="hometit">数据展示</view>
<view class="dataList">
<view class="todayGet" @click="handlTodayAcquired">
<view>今日已取</view>
<view class="num">{{ baseData.completePickUpNum }}</view>
<view class="rightIcon"></view>
</view>
<view class="todaySign" @click="handlTodaySign">
<view>今日已签</view>
<view class="num">{{ baseData.signedNum }}</view>
<view class="rightIcon"></view>
</view>
</view>
</view>
</template>
<script setup>
import { useStore } from "vuex";
const store = useStore(); //设置、获取数据
// 获取父组件值、方法
const props = defineProps({
baseData: {
type: Object,
default: () => ({}),
},
});
// ------定义方法------
// 进入 已取件列表页
const handlTodayAcquired = () => {
store.commit("user/setTabIndex", 1);
store.commit("setFootStatus", 1);
uni.redirectTo({
url: "/pages/pickup/index",
});
};
// 进入 已签收列表页
const handlTodaySign = () => {
store.commit("user/setTabIndex", 1);
store.commit("setFootStatus", 3);
uni.redirectTo({
url: "/pages/delivery/index",
});
};
</script>
<style src="../index.scss" lang="scss"></style>

View File

@@ -0,0 +1,198 @@
<template>
<view>
<scroll-view
scroll-x="true"
class="tabScroll"
:scroll-into-view="scrollinto"
:scroll-with-animation="true"
>
<view
v-for="(item, index) in tabBars"
:key="index"
:id="'tab' + index"
class="scroll-row-item"
@click="changeTab(index)"
>
<view :class="tabIndex == index ? 'scroll-row-item-act' : ''">
<text class="line"></text>
{{ item.name }}
<text class="num">{{ item.num }}</text>
</view>
</view>
</scroll-view>
<view class="homeSwiper">
<view v-if="tabIndex === 0 || tabIndex === 1">
<view v-if="itemData.length > 0">
<view
class="boxBg"
v-for="(item, index) in itemData.slice(0, 3)"
:key="index"
v-if="tabIndex === 0"
>
<view class="tabList">
<view class="item" @click.stop="handleDetail(item.id)">
<view class="titInfo">
{{ item.name }}
<text>{{ item.phone }}</text>
<icon
class="phone"
@click.stop="handlePhone($event, item.phone)"
></icon>
<icon class="note" @click.stop="handleNote"></icon>
</view>
<view class="address">{{ item.address }}</view>
<view class="distance">{{ item.distance }}公里</view>
<view class="time"
>预约取件时间{{
taskTimeFormat(item.estimatedStartTime)
}}
{{ overTimeFormat(item.estimatedEndTime) }}</view
>
</view>
</view>
</view>
<!-- 待派件 -->
<view
class="boxBg"
v-for="(item, index) in itemData.slice(0, 3)"
:key="index"
v-if="tabIndex === 1"
>
<view class="tabList">
<view class="item" @click.stop="handleDetail(item.id)">
<view class="titInfo">
{{ item.name }}
<text>{{ item.phone }}</text>
<icon
class="phone"
@click.stop="handlePhone($event, item.phone)"
></icon>
<icon class="note" @click.stop="handleNote"></icon>
</view>
<view class="address">{{ item.address }}</view>
<view class="address">{{ item.distance }}公里</view>
<view class="time">运单号{{ item.transportOrderId }}</view>
</view>
</view>
</view>
</view>
<view class="moreInfo" v-if="itemData.length > 3" @click="handleMore">
查看更多
<icon></icon>
</view>
</view>
<!-- 无数据显示 -->
<view v-if="itemData.length === 0"
><EmptyPage :emptyInfo="emptyInfo"></EmptyPage
></view>
<!-- end -->
</view>
<!-- 拨打手机弹层 -->
<Phone ref="phone" :phoneData="phoneData"></Phone>
<!-- end -->
</view>
</template>
<script setup>
import { ref } from "vue";
import { useStore } from "vuex";
// 处理事件封装的方法
import { taskTimeFormat, overTimeFormat } from "@/utils/index.js";
//组件
// 无数据
import EmptyPage from "@/components/uni-empty-page/index.vue";
import Phone from "@/components/uni-phone/index.vue";
// 获取父组件值、方法
const props = defineProps({
itemData: {
type: Array,
default: () => [],
},
tabBars: {
type: Array,
default: () => [],
},
});
// ------定义变量------
const store = useStore(); //设置、获取数据
let scrollinto = ref("tab0"); //tab切换
let tabIndex = ref(0); //当前tab
const phone = ref();
const emptyInfo = ref("- 空空如也,无运单记录 -");
const emit = defineEmits("getTabIndex");
const phoneData = ref("");
// ------定义方法------
// tab选项卡切换轮播
const changeTab = (index) => {
// 点击的还是当前数据的时候直接return
if (tabIndex.value == index) {
return;
}
tabIndex.value = index;
emit("getTabIndex", index);
// 滑动
scrollinto.value = "tab" + index;
};
// 触发选项卡事件
const onChangeSwiperTab = (e) => {
changeTab(e.detail.current);
};
// 进入详情
const handleDetail = (id) => {
// 把任务id用vuex的方法存储方便其他页面调用
store.commit("user/setTaskId", id);
store.commit("user/setNewType", null);
// 进入取件详情页
if (tabIndex.value === 0) {
// 由于取件详情地址和派件详情地址样式一致,所以用类型 1取件2派件区分开
store.commit("user/setTaskType", 1);
store.commit("user/setDetailType", 0);
store.commit("setFootStatus", 1); //修改底部tab当前标签
uni.redirectTo({
url: "/pages/details/index",
});
} else {
// 进入派件详情页
// 由于取件详情地址和派件详情地址样式一致,所以用类型 1取件2派件区分开
store.commit("user/setTaskType", 2);
store.commit("user/setDetailType", 0);
store.commit("setFootStatus", 3); //修改底部tab当前标签
uni.redirectTo({
url: "/pages/details/waybill",
});
}
};
// 进入待取件待派件页面
const handleMore = () => {
if (tabIndex.value === 0) {
uni.redirectTo({
url: "/pages/pickup/index",
});
} else {
uni.redirectTo({
url: "/pages/delivery/index",
});
}
};
// 拨打电话弹层
const handlePhone = (e, val) => {
// 阻止事件冒泡
e.stopPropagation();
phoneData.value = val;
phone.value.dialogOpen();
};
// 发短信
const handleNote = () => {
uni.showToast({
title: "程序员哥哥正在实现中",
duration: 1000,
icon: "none",
});
};
</script>
<style src="../index.scss" lang="scss"></style>

View File

@@ -0,0 +1,59 @@
<template>
<view class="infoBox">
<view class="boxBg">
<view @click="handlePicup">
<view class="num">{{ baseData.newPickUpNum }}</view>
<view>取件任务</view>
</view>
<view @click="handleDelivery">
<view class="num">{{ baseData.newDispatchNum }}</view>
<view>派件任务</view>
</view>
<view @click="handleOvertime">
<view class="num">{{ baseData.overTimeNum }}</view>
<view>超时任务</view>
</view>
</view>
</view>
</template>
<script setup>
import { useStore } from "vuex";
const store = useStore(); //设置、获取数据
// 获取父组件值、方法
const props = defineProps({
baseData: {
type: Object,
default: () => ({}),
},
});
// ------定义方法------
// 进入 待取件列表页
const handlePicup = () => {
store.commit("user/setTabIndex", 0);
store.commit("setFootStatus", 1);
uni.redirectTo({
url: "/pages/pickup/index",
});
};
// 进入 待派件列表页
const handleDelivery = () => {
store.commit("user/setTabIndex", 0);
store.commit("setFootStatus", 3);
store.commit("user/setDetailType", 0);
uni.redirectTo({
url: "/pages/delivery/index",
});
};
// 进入 选中超时任务
const handleOvertime = () => {
store.commit("user/setTabIndex", 0);
store.commit("setFootStatus", 1);
store.commit("user/setFilterOverTime", true);
uni.redirectTo({
url: "/pages/pickup/index",
});
};
</script>
<style src="../index.scss" lang="scss"></style>

View File

@@ -0,0 +1,48 @@
<template>
<view class="orderTip" v-if="orderData" @click="handleLink">
<view class="btn">消息通知</view>
<view>{{ orderData.recentMsg }}</view>
<view>
{{ orderData.minutes === 0 ? 1 : orderData.minutes }}分钟前
<icon class="iconNext"></icon>
</view>
</view>
</template>
<script setup>
import { useStore } from "vuex";
const store = useStore(); //vuex获取、储存数据
// 获取父组件值、方法
const props = defineProps({
orderData: Object,
default: () => ({}),
});
// ------定义方法------
const handleLink = () => {
const type = props.orderData.contentType;
store.commit("user/setTaskStatus", -1);
if (type === 300) {
uni.redirectTo({
url: "/pages/news/index",
});
} else if (type === 301) {
uni.redirectTo({
url: "/pages/news/system?title=取件相关&type=301",
});
} else if (type === 302) {
uni.redirectTo({
url: "/pages/news/system?title=签收提醒&type=302",
});
} else if (type === 303) {
uni.redirectTo({
url: "/pages/news/system?title=快件取消&type=303",
});
} else {
uni.redirectTo({
url: "/pages/news/system?title=派件相关&type=304",
});
}
};
</script>
<style src="../index.scss" lang="scss"></style>

View File

@@ -0,0 +1,237 @@
body,
uni-page-body,
uni-page-head,
.uni-page-head {
background-color: var(--neutral-color-white) !important;
}
.homePageBox{
// height: calc(100vh);
position: relative;
padding-top: 430rpx;
overflow: hidden;
.boxBg {
box-shadow: 0 0 22rpx 22rpx rgba(162, 162, 162, 0.06);}
}
.noOrder{
padding-top: 460rpx;
}
.infoBox {
margin-top: 216rpx;
position: relative;
z-index: 9;
// position: fixed;
// z-index: 10;
// left: 0;
// right: 0;
.boxBg {
padding: 38rpx 0;
// height: 200rpx;
display: flex;
box-shadow: 0 0 22rpx 22rpx rgba(162, 162, 162, 0.06);
& > view {
flex: 1;
text-align: center;
border-left: 1px solid var(--neutral-color-background);
font-size: var(--font-size-14);
line-height: 40rpx;
color: var(--neutral-color-font);
&:first-child {
border: 0 none;
}
.num {
font-weight: 600;
font-size: 64rpx;
line-height: 80rpx;
color: var(--neutral-color-main);
padding-bottom: 6rpx;
}
& > view {
padding-bottom: 10rpx;
}
}
}
}
.orderTip {
height: 68rpx;
line-height: 68rpx;
background: #fff1f0;
border-radius: 20rpx;
margin-top: 40rpx;
margin-bottom: 30rpx;
padding: 0 22rpx 0 14rpx;
display: flex;
font-size: 20rpx;
color: var(--essential-color-red);
align-items: center;
& > view {
&:nth-child(2) {
flex: 1;
}
&:nth-child(3) {
display: flex;
align-items: center;
}
}
.btn {
display: inline-block;
width: 106rpx;
// height: 36rpx;
line-height: 34rpx;
// padding: 0 0 0 10rpx;
background: url(@/static/new.png) no-repeat;
background-size: contain;
color: var(--neutral-color-white);
font-size: 20rpx;
margin-right: 12rpx;
text-emphasis: none;
text-align: center;
}
}
// 常用功能
.hometit {
line-height: 46rpx;
font-weight: 600;
font-family: PingFangSC-Medium;
font-size: 32rpx;
color: var(--neutral-color-main);
letter-spacing: 0.36rpx;
}
.commonList {
display: flex;
flex-flow: row wrap;
align-content: flex-start;
& > view {
box-sizing: border-box;
flex: 0 0 25%;
font-size: var(--font-size-12);
color: var(--neutral-color-font);
letter-spacing: 0.28px;
line-height: 34rpx;
padding: 30rpx 0;
text-align: center;
text {
display: block;
}
icon {
width: 48rpx;
height: 48rpx;
margin-bottom: 16rpx;
&.delivery {
background: url(@/static/icon03.png);
background-size: contain;
}
&.sign {
background: url(@/static/icon04.png);
background-size: contain;
}
&.history {
background: url(@/static/icon05.png);
background-size: contain;
}
&.new {
background: url(@/static/icon06.png);
background-size: contain;
}
&.freight {
background: url(@/static/icon07.png);
background-size: contain;
}
&.tip {
background: url(@/static/icon08.png);
background-size: contain;
}
&.exclusive {
background: url(@/static/icon09.png);
background-size: contain;
}
}
}
}
.commonData {
padding-top: 18rpx;
.dataList {
display: flex;
margin-left: -20rpx;
padding: 32rpx 0 6rpx;
& > view {
height: 112rpx;
border-radius: 16rpx;
padding: 34rpx 24rpx;
line-height: 34rpx;
flex: 1;
margin-left: 20rpx;
position: relative;
font-size: var(--font-size-12);
}
.rightIcon {
position: absolute;
right: 18rpx;
bottom: 6rpx;
}
}
.todayGet {
background-image: linear-gradient(178deg, #ffebeb 4%, #fbf3f3 100%);
color: #ce6864;
.rightIcon {
background: url(@/static/fetch.png) no-repeat;
background-size: contain;
width: 136rpx;
height: 146rpx;
}
}
.todaySign {
background-image: linear-gradient(178deg, #ffe9dd 5%, #faf3ee 100%);
color: #c97f59;
.rightIcon {
background: url(@/static/sign.png) no-repeat;
background-size: contain;
width: 162rpx;
height: 148rpx;
}
}
.rigIcon {
position: absolute;
right: 20rpx;
}
.num {
line-height: 60rpx;
font-size: 44rpx;
color: #c24340;
letter-spacing: 0.5px;
font-weight: 600;
padding-top: 10rpx;
}
}
// 首页查看更多
.moreInfo {
font-size: var(--font-size-12);
padding: 62rpx 0 80rpx;
text-align: center;
line-height: 34rpx;
icon {
background: url(@/static/icon16.png) no-repeat;
background-size: contain;
width: 16rpx;
height: 22rpx;
margin-left: 6rpx;
flex: 1;
vertical-align: middle;
margin-top: -4rpx;
}
}
.homeSwiper{
padding-bottom: 136rpx;
::v-deep .uni-swiper-wrapper{
overflow: unset !important;
position: static !important;
// width: auto !important;
height:auto !important;
uni-swiper-item{
overflow: unset !important;
}
}
}

View File

@@ -0,0 +1,147 @@
<!-- 首页 -->
<template>
<view class="navFrame">
<!-- nav -->
<UniNav :newVal="newVal" @goBack="goBack"></UniNav>
<!-- 订单信息 -->
<OrderInfo :baseData="baseData"></OrderInfo>
<!-- end -->
</view>
<!-- end -->
<view class="homePageBox" :class="!orderData.value ? 'noOrder' : ''">
<view class="boxPad">
<!-- 订单提示 -->
<OrderTip :orderData="orderData.value"></OrderTip>
<!-- end -->
<!-- 常用功能 -->
<CommonUse></CommonUse>
<!-- end -->
<!-- 数据展示 -->
<DataPresentation :baseData="baseData"></DataPresentation>
<!-- end -->
</view>
<!-- 取件状态列表 -->
<ExpressageInfo :itemData="itemData.value" :tabBars="tabBars" @getTabIndex="getTabIndex"></ExpressageInfo>
<!-- end -->
</view>
<!-- footer -->
<UniFooter :pagePath="'pages/index/index'"></UniFooter>
<!-- end -->
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { useStore } from 'vuex';
import { getTimeDate, positionsUploadInit } from '@/utils/index.js';
// 静态数据
import { tabBars } from '@/utils/commonData.js'
// 导入接口
import { getHomeInfo, getHomeData, getDeliveryList} from '@/pages/api/index.js';
// 导入组件
// 导航
import UniNav from '@/components/uni-home-nav/index.vue';
// 底部导航
import UniFooter from '@/components/uni-footer/index.vue';
// 订单信息
import OrderInfo from './components/orderInfo.vue';
// 订单消息提示
import OrderTip from './components/orderTip.vue';
// 常用功能
import CommonUse from './components/commonUse.vue';
// 数据展示
import DataPresentation from './components/dataPresent.vue';
// 取件信息
import ExpressageInfo from './components/expressageInfo.vue';
// ------定义变量------
const store = useStore(); //vuex获取储存数据
const users = store.state.user;
const newVal = ref(Number(null)); //消息
const orderData = reactive({}); //首页相关默认信息
const itemData = reactive([]);
const noPickupTaskList = reactive([]); //取件列表数据
const noDispatchTaskList = reactive([]); //派件列表数据
const locationData = ref({});
let baseData = ref({});
let page = reactive({
latitude: users.loacation.latitude !== undefined ? users.loacation.latitude : 40.062595,
longitude: users.loacation.longitude !== undefined ? users.loacation.longitude : 116.372809,
page: 1,
pageSize: 10,
dateTime: getTimeDate(new Date()).veryDayDate,
taskStatus: 1
});
// ------生命周期------
onMounted(() => {
// 上报位置 进入首页立即上报
positionsUploadInit()
init();
});
// ------定义方法------
// 获取初始值
const init = () => {
getNewData();
getHomeBase();
getList();
};
// 获取相关消息
const getNewData = async () => {
await getHomeInfo().then(res => {
if (res.code === 200) {
orderData.value = res.data;
newVal.value = res.data.newsNum;
}
});
};
// 获取相关任务、取件、派件、今日已取、已签
const getList = async () => {
await getDeliveryList(page).then(res => {
if (res.code === 200) {
if (res.data) {
itemData.value = res.data.items;
}
}
});
};
// 获取相关任务、取件、派件、今日已取、已签
const getHomeBase = async () => {
const locition = {
longitude: 116.344015,
latitude: 40.060607
};
await getHomeData(locition).then(res => {
if (res.code === 200) {
baseData.value = res.data;
}
});
};
// 列表tab当前切换的index
const getTabIndex = val => {
itemData.value = [];
if (val === 0) {
page.taskStatus = 1;
} else {
page.taskStatus = 4;
}
getList();
};
// 获取当前位置
const getLocation = () => {
uni.getLocation({
type: 'gcj02',
success: res => {}
});
};
// 返回上一页
const goBack = () => {
uni.redirectTo({
url: '/pages/index/index'
});
};
</script>
<style src="./index.scss" lang="scss" scoped></style>
<style lang="scss">
body {
background: #fff;
}
</style>