init
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<uni-load-more :status="status" :content-text="contentText" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
// ------定义变量------
|
||||
let status = ref('noMore'); //loading 的状态 more(加载前)/loading(加载中)/noMore(没有更多数据)
|
||||
const contentText = ref({ //加载状态说明
|
||||
contentdown: '上拉加载更多',
|
||||
contentrefresh: '加载中...',
|
||||
contentnomore: '- 没有更多了 -'
|
||||
});
|
||||
|
||||
//把数据、方法暴漏给父组件
|
||||
defineExpose({
|
||||
status,
|
||||
contentText
|
||||
});
|
||||
|
||||
</script>
|
@@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<view class="uniPopup">
|
||||
<uni-popup ref="popup" type="bottom" background-color="#fff">
|
||||
<view class="popup-content">
|
||||
<view class="tit">
|
||||
<view @click="handleCancel('bottom')">取消</view>
|
||||
<view>选择城市</view>
|
||||
<view @click="handleComplete">完成</view>
|
||||
</view>
|
||||
<view class="date-select address">
|
||||
<view>
|
||||
<picker-view class="picker-view" :value="defaultValue" :indicator-style="indicatorStyle" @change="getProvincesData">
|
||||
<!-- 省 -->
|
||||
<picker-view-column>
|
||||
<view class="item" v-for="(item, index) in provinceData.value" :key="index">
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
</picker-view-column>
|
||||
<!-- end -->
|
||||
<!-- 市 -->
|
||||
<picker-view-column>
|
||||
<view class="item" v-for="(item, index) in cityData.value" :key="index">
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
</picker-view-column>
|
||||
<!-- end -->
|
||||
<!-- 区 -->
|
||||
<picker-view-column>
|
||||
<view class="item" v-for="(item, index) in areaData.value" :key="index">
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
</picker-view-column>
|
||||
<!-- end -->
|
||||
</picker-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
// 接口pai
|
||||
// 公用接口
|
||||
import { getProvinces } from '@/pages/api/common.js';
|
||||
// 获取父组件数据
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: Number,
|
||||
default: null
|
||||
}
|
||||
});
|
||||
// ------定义变量------
|
||||
const emit = defineEmits('getCity'); //子组件向父组件事件传递
|
||||
const popup = ref()
|
||||
const indicatorStyle = ref(`height: 100rpx;`);
|
||||
let defaultValue = ref([0, 0, 0]); //省市区默认显示
|
||||
const provinceData = reactive([]); //省
|
||||
const cityData = reactive([]); //市
|
||||
const areaData = reactive([]); //区
|
||||
let cityBase = ref({})
|
||||
|
||||
// ------生命周期------
|
||||
onMounted(() => {
|
||||
getProvincesData();
|
||||
});
|
||||
// ------定义方法------
|
||||
// 获取省市区
|
||||
// 下拉选择省市区
|
||||
const getProvincesData = async e => {
|
||||
let res = await getProvinces();
|
||||
if (res.code === 200) {
|
||||
provinceData.value = res.data;
|
||||
let provincesId = null;
|
||||
if (!e) {
|
||||
provincesId = provinceData.value[0].id;
|
||||
} else {
|
||||
defaultValue.value = e.detail.value;
|
||||
provincesId = provinceData.value[e.detail.value[0]].id;
|
||||
}
|
||||
getCity(provincesId); //获取省
|
||||
} else {
|
||||
return uni.showToast({
|
||||
title: res.msg,
|
||||
duration: 1000,
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// // 获取市
|
||||
const getCity = async id => {
|
||||
let res = await getProvinces({ parentId: id });
|
||||
if (res.code === 200) {
|
||||
cityData.value = res.data;
|
||||
const cityId = cityData.value[defaultValue.value[1]].id;
|
||||
getArea(cityId);
|
||||
} else {
|
||||
return uni.showToast({
|
||||
title: res.msg,
|
||||
duration: 1000,
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
};
|
||||
// // 获取区
|
||||
const getArea = async id => {
|
||||
let res = await getProvinces({ parentId: id });
|
||||
if (res.code === 200) {
|
||||
areaData.value = res.data;
|
||||
cityBase.value={
|
||||
province:provinceData.value[defaultValue.value[0]].name,
|
||||
city:cityData.value[defaultValue.value[1]].name,
|
||||
area:areaData.value[defaultValue.value[2]].name,
|
||||
areaId:areaData.value[defaultValue.value[2]].id
|
||||
}
|
||||
} else {
|
||||
return uni.showToast({
|
||||
title: res.msg,
|
||||
duration: 1000,
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
};
|
||||
// 打开弹层
|
||||
const handleOpen = () => {
|
||||
popup.value.open('bottom');
|
||||
};
|
||||
// 关闭弹层
|
||||
const handleCancel = ()=>{
|
||||
popup.value.close('bottom');
|
||||
}
|
||||
// 完成
|
||||
const handleComplete = ()=>{
|
||||
handleCancel()
|
||||
emit('getCity',cityBase.value)
|
||||
}
|
||||
// 暴漏给父组件
|
||||
defineExpose({
|
||||
handleOpen
|
||||
});
|
||||
</script>
|
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<view class="emptyBox" v-if="emptyInfo!==''">{{emptyInfo}}</view>
|
||||
<view class="empty" v-else><view class="image" :class="emptyImage"></view>{{emptyData}}</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 获取父组件值、方法
|
||||
const props = defineProps({
|
||||
emptyInfo:{
|
||||
type:String,
|
||||
default: '',
|
||||
},
|
||||
emptyData:{
|
||||
type:String,
|
||||
default: '',
|
||||
},
|
||||
emptyImage:{
|
||||
type:String,
|
||||
default: '',
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style src="../../styles/common.scss" lang="scss" scoped></style>
|
@@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<view
|
||||
class="boxCon dataAdmin"
|
||||
v-if="store.state.user.deliveryData.length > 0"
|
||||
>
|
||||
<button class="uni-btn concelBtn" @click="handleAdmin" v-if="!isAdmin">
|
||||
管理
|
||||
</button>
|
||||
<view v-else class="adminInfo">
|
||||
<view class="selectInfo">
|
||||
<label class="checkRadio">
|
||||
<radio
|
||||
value="1"
|
||||
:checked="selected.size === store.state.user.deliveryData.length"
|
||||
:class="
|
||||
selected.size === store.state.user.deliveryData.length
|
||||
? 'active'
|
||||
: ''
|
||||
"
|
||||
@click="allSelect"
|
||||
/>
|
||||
全选
|
||||
</label>
|
||||
总计
|
||||
<text class="num">{{ selected.size }}</text>
|
||||
条
|
||||
</view>
|
||||
<view>
|
||||
<button
|
||||
class="uni-btn concelBtn"
|
||||
v-if="isAdmin"
|
||||
@click="handleAccomplish"
|
||||
>
|
||||
完成
|
||||
</button>
|
||||
<button
|
||||
class="uni-btn btn-default"
|
||||
v-if="tabIndex === 0 && !isDelivery"
|
||||
@click="handleOrder"
|
||||
>
|
||||
转单
|
||||
</button>
|
||||
<button
|
||||
class="uni-btn btn-default"
|
||||
v-else-if="tabIndex === 1 && !isDelivery"
|
||||
@click="handlePrint"
|
||||
>
|
||||
打印
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="uni-btn btn-default"
|
||||
v-if="!isDelivery && tabIndex === 2"
|
||||
@click="handleBatchDelete"
|
||||
>
|
||||
批量删除
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 提示窗示例 -->
|
||||
<UniPopup
|
||||
ref="popup"
|
||||
:tipInfo="tipInfo"
|
||||
@handleClick="handleClick"
|
||||
></UniPopup>
|
||||
<!-- end -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
// 弹层
|
||||
import UniPopup from "@/components/uni-popup/index.vue";
|
||||
// ------定义变量------
|
||||
// 获取父组件数据
|
||||
const props = defineProps({
|
||||
// 已选内容
|
||||
selected: {
|
||||
type: Map,
|
||||
default: () => [],
|
||||
},
|
||||
// 当前tab切换值,判断是已取件还是待取件
|
||||
tabIndex: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
// 是否触发管理按钮,此处是用来控制是否显示全选、条数、转单、打印、删除按钮
|
||||
isAdmin: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 区分取件派件
|
||||
isDelivery: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
const store = useStore();
|
||||
const users = store.state.user;
|
||||
const emit = defineEmits();
|
||||
let popup = ref();
|
||||
const tipInfo = ref("确定要批量删除吗?");
|
||||
let itemData = store.state.user.deliveryData;
|
||||
// ------定义方法------
|
||||
// 管理数据
|
||||
const handleAdmin = () => {
|
||||
emit("getAdmin", true);
|
||||
};
|
||||
// 全选
|
||||
const allSelect = () => {
|
||||
emit("allSelect");
|
||||
};
|
||||
// 转单
|
||||
const handleOrder = () => {
|
||||
if (props.selected.size > 0) {
|
||||
let ids = [];
|
||||
for (let [key, value] of props.selected) {
|
||||
ids.push(value);
|
||||
}
|
||||
if (props.isDelivery) {
|
||||
store.commit("user/setIsDelivery", true);
|
||||
} else {
|
||||
store.commit("user/setIsDelivery", false);
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: "/pages/turnorder/index",
|
||||
});
|
||||
} else {
|
||||
return uni.showToast({
|
||||
title: "请选择任务!",
|
||||
duration: 1000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
};
|
||||
// 批量删除
|
||||
const handleBatchDelete = () => {
|
||||
if (props.selected.size > 0) {
|
||||
popup.value.dialogOpen();
|
||||
} else {
|
||||
return uni.showToast({
|
||||
title: "请选择要删除的任务!",
|
||||
duration: 1000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
};
|
||||
// 打印
|
||||
const handlePrint = () => {
|
||||
uni.showToast({
|
||||
title: "程序员哥哥正在实现中",
|
||||
duration: 1000,
|
||||
icon: "none",
|
||||
});
|
||||
};
|
||||
// 完成
|
||||
const handleAccomplish = () => {
|
||||
let itemData = users.deliveryData;
|
||||
props.selected.clear(); // 全部清除
|
||||
itemData.forEach((element) => {
|
||||
element.selected = false; // 全部不选,就行了
|
||||
});
|
||||
store.commit("user/setDeliveryData", itemData);
|
||||
emit("getAdmin", false);
|
||||
};
|
||||
// 确认删除
|
||||
const handleClick = () => {
|
||||
emit("handleClick");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dataAdmin {
|
||||
padding: 24rpx 30rpx 24rpx 36rpx;
|
||||
position: fixed;
|
||||
bottom: 100rpx;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 0;
|
||||
.concelBtn,
|
||||
.btn-default {
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
width: 140rpx;
|
||||
border-radius: 30rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
.btn-default {
|
||||
margin-left: 20rpx !important;
|
||||
}
|
||||
.concelBtn {
|
||||
float: right;
|
||||
}
|
||||
.num {
|
||||
color: var(--essential-color-red);
|
||||
padding: 0 4rpx;
|
||||
}
|
||||
.adminInfo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
& > view {
|
||||
&.selectInfo {
|
||||
flex: 1;
|
||||
.checkRadio {
|
||||
padding-right: 24rpx;
|
||||
}
|
||||
}
|
||||
&:last-child {
|
||||
text-align: right;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<!-- 公用底部 -->
|
||||
<view class="footBox">
|
||||
<view class="uni-tabbar">
|
||||
<view class="tabbar-item" :class="currentPage === index ? 'active' : ''" v-for="(item, index) in tabbar" :key="index" @tap="changeTab(item, index)">
|
||||
<view v-if="true" class="uni-tabbar__bd">
|
||||
<view class="uni-tabbar__icon" v-if="item.pagePath !== ''">
|
||||
<img v-if="currentPage === index" class="item-img" :src="item.selectedIconPath" />
|
||||
<img v-else class="item-img" :src="item.iconPath" />
|
||||
</view>
|
||||
<view v-else class="qrCode"><img :src="item.iconPath" /></view>
|
||||
</view>
|
||||
<view class="uni-tabbar__label" v-if="item.text !== ''">{{ item.text }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- end -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
// 获取父组件值、方法
|
||||
const props = defineProps({
|
||||
pagePath: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
// ------定义变量------
|
||||
const store = useStore();//vuex获取储存数据
|
||||
const currentPage = ref(store.state.footStatus); //获取储存的当前tab状态
|
||||
let tabbar = ref([
|
||||
{
|
||||
pagePath: '/pages/index/index',
|
||||
iconPath: 'static/home.png',
|
||||
selectedIconPath: 'static/homeActive.png',
|
||||
text: '首页'
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/pickup/index',
|
||||
iconPath: 'static/collect.png',
|
||||
selectedIconPath: 'static/collectActive.png',
|
||||
text: '取件'
|
||||
},
|
||||
{
|
||||
pagePath: '',
|
||||
iconPath: 'static/qrcode.png',
|
||||
selectedIconPath: 'static/qrcode.png',
|
||||
text: ''
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/delivery/index',
|
||||
iconPath: 'static/delivery.png',
|
||||
selectedIconPath: 'static/deliveryActive.png',
|
||||
text: '派件'
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/my/index',
|
||||
iconPath: 'static/user.png',
|
||||
selectedIconPath: 'static/userActive.png',
|
||||
text: '我的'
|
||||
}
|
||||
]);
|
||||
// ------方法------
|
||||
// 触发tab事件
|
||||
const changeTab = (item, index) => {
|
||||
store.commit('user/setFilterOverTime',null);
|
||||
if (item.text !== '') {
|
||||
currentPage.value = index;
|
||||
store.commit('setFootStatus', index);
|
||||
// 因为取件、派件数据列表存在了vuex里面,切换tab时为了避免有沉余的数据,所以触发tab的时候先清空下数据
|
||||
store.commit('user/setDeliveryData', []);
|
||||
store.commit('user/setTabIndex', 0);
|
||||
store.commit('user/setTaskStatus', 0);
|
||||
store.commit('user/setDetailType', 0);
|
||||
|
||||
store.commit('user/setNewType',null)
|
||||
// 页面跳转
|
||||
uni.redirectTo({
|
||||
url: item.pagePath,
|
||||
success: e => {},
|
||||
fail: () => {}
|
||||
});
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '程序员哥哥正在实现中',
|
||||
duration: 1000,
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
292
project-wl-kuaidiyuan-uniapp-vue3/components/uni-goods/index.vue
Normal file
292
project-wl-kuaidiyuan-uniapp-vue3/components/uni-goods/index.vue
Normal file
@@ -0,0 +1,292 @@
|
||||
<template>
|
||||
<view class="goodsCon">
|
||||
<view class="item">
|
||||
<text>预估重量</text>
|
||||
<view class="bg goodInfo">
|
||||
<view class="symbol" :class="isLessThan ? 'active' : ''" @click="handleMinus">-</view>
|
||||
<view class="num">
|
||||
<input class="uni-input" type="number" maxlength="6" v-model="weight" @blur="handleSymbol" />
|
||||
<text>kg</text>
|
||||
</view>
|
||||
<view class="symbol" :class="isExceed ? 'active' : ''" @click="handleAdd">+</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<text>总体积</text>
|
||||
<view class="bg goodInfo">
|
||||
<!-- 暂时去除 :class="isLessThanVolume ? 'active' : ''" -->
|
||||
<view class="symbol" @click="handleVolumeMinus">-</view>
|
||||
<view class="num">
|
||||
<input class="uni-input" type="number" maxlength="6" v-model="volume" @blur="handleVolume" />
|
||||
<text>m³</text>
|
||||
</view>
|
||||
<!-- 暂时去除 :class="isExceedVolume ? 'active' : ''" -->
|
||||
<view class="symbol" @click="handleVolumeAdd">+</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item calculate">
|
||||
<view class="bg">
|
||||
<input class="uni-input" type="number" maxlength="3" v-model="measureLong" placeholder="长" @input="handleCalculate" />
|
||||
<text :class="measureLong ? 'active' : ''">cm</text>
|
||||
</view>
|
||||
<text>*</text>
|
||||
<view class="bg">
|
||||
<input class="uni-input" type="number" maxlength="3" v-model="measureWidth" placeholder="宽" @input="handleCalculate" />
|
||||
<text :class="measureWidth ? 'active' : ''">cm</text>
|
||||
</view>
|
||||
<text>*</text>
|
||||
<view class="bg">
|
||||
<input class="uni-input" type="number" maxlength="3" v-model="measureHigh" placeholder="高" @input="handleCalculate" />
|
||||
<text :class="measureHigh ? 'active' : ''">cm</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, nextTick } from 'vue';
|
||||
// 接口
|
||||
import { calculateFreight } from '@/pages/api/freight.js';
|
||||
// ------定义变量------
|
||||
const props = defineProps({
|
||||
detailsData:{
|
||||
type:Object,
|
||||
default:()=>({})
|
||||
}
|
||||
})
|
||||
let emit = defineEmits()
|
||||
let weight = ref(1); //重量
|
||||
let volume = ref(0); //体积
|
||||
let measureLong = ref(null); //长
|
||||
let measureWidth = ref(null); //宽
|
||||
let measureHigh = ref(null); //高
|
||||
let isLessThan = ref(true); //判断重量是否小于0.1
|
||||
let isExceed = ref(false); //判断重量是否大于9999
|
||||
let isLessThanVolume = ref(true); //判断体积是否小于0.0001m³
|
||||
let isExceedVolume = ref(false); //判断体积是否大于99m³
|
||||
let freightData = ref(null);
|
||||
// 暴漏给父组件
|
||||
defineExpose({
|
||||
weight,
|
||||
volume,
|
||||
measureLong,
|
||||
measureWidth,
|
||||
measureHigh,
|
||||
freightData
|
||||
});
|
||||
// ------生命周期------
|
||||
// 监听重量数值,小数点后保留一位
|
||||
watch(weight, (newValue, oldValue) => {
|
||||
const val = Number(newValue);
|
||||
nextTick(() => {
|
||||
// 数值小于0.1并且大于0 数值默认为1
|
||||
if (val < 0.1 &&( val > 0&&val < 1)) {
|
||||
weight.value = 1;
|
||||
}
|
||||
// 处理小数点,小数点保留1位
|
||||
if (val > 0.1) {
|
||||
weight.value = parseInt(val * 10) / 10;
|
||||
}
|
||||
// 数值小于等于1 左侧按钮置灰
|
||||
if (val <= 1) {
|
||||
isLessThan.value = true; //左侧减号置灰
|
||||
} else {
|
||||
isLessThan.value = false; //左侧减号去除置灰
|
||||
if (val >= 9999) {
|
||||
weight.value = 9999;
|
||||
isExceed.value = true; //右侧加号置灰
|
||||
} else {
|
||||
isExceed.value = false; //右侧加号去除置灰
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
// 监听长,取整
|
||||
watch(measureLong, (newValue, oldValue) => {
|
||||
const val = Number(newValue);
|
||||
nextTick(() => {
|
||||
measureLong.value = Math.floor(val);
|
||||
if (newValue <= 0) {
|
||||
measureLong.value = null;
|
||||
}
|
||||
});
|
||||
});
|
||||
// 监听宽,取整
|
||||
watch(measureWidth, (newValue, oldValue) => {
|
||||
const val = Number(newValue);
|
||||
nextTick(() => {
|
||||
measureWidth.value = Math.floor(val);
|
||||
if (newValue <= 0) {
|
||||
measureWidth.value = null;
|
||||
}
|
||||
});
|
||||
});
|
||||
// 监听高,取整
|
||||
watch(measureHigh, (newValue, oldValue) => {
|
||||
const val = Number(newValue);
|
||||
nextTick(() => {
|
||||
measureHigh.value = Math.floor(val);
|
||||
if (newValue <= 0) {
|
||||
measureHigh.value = null;
|
||||
}
|
||||
});
|
||||
});
|
||||
// ------定义方法------
|
||||
// 通过体积重量获取总额
|
||||
const getfreight = async () => {
|
||||
const details=props.detailsData
|
||||
let data = {
|
||||
senderCountyId: details.senderCountyId,
|
||||
receiverCountyId: details.receiverCountyId,
|
||||
volume:volume.value===0?1:volume.value*1000000,
|
||||
weight: weight.value
|
||||
};
|
||||
await calculateFreight(data).then(res => {
|
||||
emit('getFreight',res.data.freight)
|
||||
});
|
||||
};
|
||||
//触发重量输入如果输入0,自动判断为1kg,最小可输入值为0.1kg,最大值为9999kg
|
||||
const handleSymbol = e => {
|
||||
const value = e.detail.value;
|
||||
if (value < 0.1) {
|
||||
weight.value = 1;
|
||||
isLessThan.value = true; //左侧减号置灰
|
||||
} else {
|
||||
if (value > 0.1 && value <= 1) {
|
||||
isLessThan.value = true;
|
||||
} else {
|
||||
isLessThan.value = false; //左侧减号去除置灰
|
||||
}
|
||||
|
||||
isDetails()
|
||||
if (value >= 9999) {
|
||||
isExceed.value = true; //右侧加号置灰
|
||||
weight.value = 9999;
|
||||
} else {
|
||||
isExceed.value = false; //右侧加号去除置灰
|
||||
isDetails()
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
const isDetails=()=>{
|
||||
if(props.detailsData.id!==undefined){
|
||||
getfreight()
|
||||
}
|
||||
}
|
||||
// 减重量
|
||||
const handleMinus = () => {
|
||||
// 重量减去1
|
||||
if (weight.value > 1) {
|
||||
weight.value--;
|
||||
isExceed.value = false; //右侧加号去除置灰
|
||||
weight.value = weight.value.toFixed(1);
|
||||
}
|
||||
if (weight.value <= 0) {
|
||||
weight.value = 1;
|
||||
isLessThan.value = true; //左侧减号置灰
|
||||
}
|
||||
isDetails()
|
||||
};
|
||||
// 加重量
|
||||
const handleAdd = () => {
|
||||
// 重量加1
|
||||
if (weight.value < 9999) {
|
||||
++weight.value;
|
||||
isLessThan.value = false; //左侧减号去除置灰
|
||||
}
|
||||
if (weight.value === 9999) {
|
||||
isExceed.value = true; //右侧加号置灰
|
||||
}
|
||||
isDetails()
|
||||
};
|
||||
|
||||
// 体积
|
||||
const handleVolume = e => {
|
||||
const value = Number(e.detail.value);
|
||||
if (value < 0.0001) {
|
||||
// isLessThanVolume.value = true;
|
||||
volume.value = 0;
|
||||
} else {
|
||||
// isLessThanVolume.value = false;
|
||||
if (value > 99) {
|
||||
// isExceedVolume.value = true; //右侧加号置灰
|
||||
volume.value = 99;
|
||||
return uni.showToast({
|
||||
title: '体积最大可不能超过99m³',
|
||||
duration: 1000,
|
||||
icon: 'none'
|
||||
});
|
||||
} else {
|
||||
volume.value = Number(e.detail.value);
|
||||
// isExceedVolume.value = false; //右侧加号去除置灰
|
||||
}
|
||||
|
||||
}
|
||||
isDetails()
|
||||
};
|
||||
// 减体积
|
||||
const handleVolumeMinus = () => {
|
||||
// 体积减去1
|
||||
if (volume.value > 1) {
|
||||
volume.value--;
|
||||
// isExceedVolume.value = false; //右侧加号去除置灰
|
||||
volume.value = parseInt(volume.value * 10000) / 10000;
|
||||
}
|
||||
// 体积
|
||||
if (volume.value <= 0 || volume.value === 1) {
|
||||
volume.value = 0;
|
||||
// isLessThanVolume.value = true; //左侧减号置灰
|
||||
}
|
||||
isDetails()
|
||||
};
|
||||
// 加体积
|
||||
const handleVolumeAdd = () => {
|
||||
// 体积加1
|
||||
if (volume.value < 99) {
|
||||
++volume.value;
|
||||
isLessThanVolume.value = false; //左侧减号去除置灰
|
||||
}
|
||||
if (volume.value === 99) {
|
||||
isExceedVolume.value = true; //右侧加号置灰
|
||||
}
|
||||
isDetails()
|
||||
};
|
||||
// 计算立方米
|
||||
const handleCalculate = () => {
|
||||
const long = measureLong.value; //长
|
||||
const wide = measureWidth.value; //宽
|
||||
const height = measureHigh.value; //高
|
||||
// 长宽高都大于1才可以计算
|
||||
if (long >= 1 && wide >= 1 && height >= 1) {
|
||||
nextTick(() => {
|
||||
// 计算立方米:长/100*宽/100*高/100
|
||||
let val = (long / 100) * (wide / 100) * (height / 100);
|
||||
// 立方米必须大于0.0001
|
||||
if (val < 0.0001) {
|
||||
volume.value = 0;
|
||||
} else if (val > 99) {
|
||||
// 小数点后保留四位小数
|
||||
isExceedVolume.value = true; //右侧加号置灰
|
||||
volume.value = 99;
|
||||
return uni.showToast({
|
||||
title: '体积最大可不能超过99m³',
|
||||
duration: 1000,
|
||||
icon: 'none'
|
||||
});
|
||||
} else {
|
||||
volume.value = parseInt(val * 10000) / 10000;
|
||||
// 如果体积大于1左侧减号按钮去除置灰
|
||||
if (val > 1) {
|
||||
isLessThanVolume.value = false; //左侧减号去除置灰
|
||||
} else {
|
||||
isLessThanVolume.value = true; //左侧减号置灰
|
||||
}
|
||||
isExceedVolume.value = false; //右侧加号去除置灰
|
||||
}
|
||||
isDetails()
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<!-- 公用nav -->
|
||||
<view class="navBox">
|
||||
<view class="nav-bg">
|
||||
<!-- 头部自定义导航 -->
|
||||
<view class="headBg"></view>
|
||||
<uni-nav-bar>
|
||||
<view class="input-view">
|
||||
<uni-icons class="input-uni-icon" type="search" size="18" color="#999" />
|
||||
<input confirm-type="search" class="nav-bar-input" type="text" v-model="searchVal" placeholder="输入四位或完整运单号/手机号、姓名" @confirm="handleSearch" @tap="handleSearch"/>
|
||||
</view>
|
||||
<view slot="right">
|
||||
<view class="rightText">
|
||||
<view @click="handleNew">
|
||||
<uni-badge class="uni-badge-left-margin" :class="newVal > 9 ? 'big' : ''" :text="newVal" absolute="rightTop" size="small">
|
||||
<view class="box"><text class="box-text"></text></view>
|
||||
</uni-badge>
|
||||
<view class="newInfo">消息</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-nav-bar>
|
||||
<!-- end -->
|
||||
</view>
|
||||
</view>
|
||||
<!-- end -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
// 获取父组件值、方法
|
||||
const props = defineProps({
|
||||
newVal: {
|
||||
type: Number,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
// ------定义变量------
|
||||
const store = useStore(); //vuex获取、储存数据
|
||||
const users = store.state.user;
|
||||
const searchVal = ref('');
|
||||
// ------方法------
|
||||
const handleSearch = e => {
|
||||
// 跳转到搜索页面
|
||||
uni.redirectTo({
|
||||
url: '/pages/search/index'
|
||||
});
|
||||
};
|
||||
// 去消息页
|
||||
const handleNew = e => {
|
||||
store.commit('user/setTaskStatus',null)
|
||||
store.commit('user/setDetailType', 0);
|
||||
uni.redirectTo({
|
||||
url: '/pages/news/index'
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url(@/styles/theme.scss);
|
||||
// 导航
|
||||
.nav-bg {
|
||||
::v-deep .uni-navbar__header-btns-left,
|
||||
::v-deep .uni-navbar__header-btns-right {
|
||||
display: none !important;
|
||||
}
|
||||
// 重置首页搜索图标样式
|
||||
::v-deep .uni-icons {
|
||||
background: url(@/static/search.png) 50% 50% no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
// 重置首页搜索placeholder样式
|
||||
::v-deep .uni-input-placeholder {
|
||||
color: #f9c5c0;
|
||||
}
|
||||
// 重置首页搜索input样式
|
||||
::v-deep .uni-input-input {
|
||||
background: rgba(250, 250, 250, 0.24);
|
||||
color: #f9c5c0;
|
||||
}
|
||||
.uni-badge-absolute {
|
||||
margin-left: 40px;
|
||||
}
|
||||
.rightText {
|
||||
text-align: center;
|
||||
padding-left: 18rpx;
|
||||
}
|
||||
.box {
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
background: url(@/static/icon012.png) no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.box-text {
|
||||
text-align: center;
|
||||
color: var(--neutral-color-white);
|
||||
font-size: 12px;
|
||||
}
|
||||
::v-deep .uni-badge--error {
|
||||
background: var(--neutral-color-white);
|
||||
|
||||
font-size: 18rpx;
|
||||
color: #f25c4d;
|
||||
left: 18rpx !important;
|
||||
top: -3px !important;
|
||||
width: 26rpx !important;
|
||||
height: 26rpx;
|
||||
line-height: 26rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.big {
|
||||
::v-deep .uni-badge--error {
|
||||
width: 44rpx !important;
|
||||
border-radius: 11rpx;
|
||||
}
|
||||
}
|
||||
.newInfo {
|
||||
color: var(--neutral-color-white);
|
||||
font-size: 20rpx;
|
||||
line-height: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<view class="filtrateBox">
|
||||
<view class="item" @click="handleTab(index)" v-for="(item, index) in itemData" :key="index" :class="isActive === index||(item==='超时任务'&&users.filterOverTime) ? 'onHover' : ''">
|
||||
<text>{{ item }}</text>
|
||||
<icon class="up" :class="isActive === index && isSelect ? 'hover' : ''" v-if="index !== 2"></icon>
|
||||
<icon class="down" :class="isActive === index && !isSelect ? 'hover' : ''" v-if="index !== 2"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
// 获取父组件数据
|
||||
const props = defineProps({
|
||||
tabBars: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
});
|
||||
// ------定义变量------
|
||||
const store = useStore(); //设置、获取储存的数据
|
||||
const users = store.state.user;
|
||||
const emit = defineEmits()
|
||||
const itemData = ref(['距离', '时间', '超时任务']);
|
||||
let isActive = ref(-1); //当前触发tab样式
|
||||
let isSelect = ref(); //排序箭头的样式 true:升,false:降
|
||||
// ------定义方法------
|
||||
|
||||
// tab切换
|
||||
const handleTab = index => {
|
||||
isActive.value = index; //当前tab值
|
||||
isSelect.value = !isSelect.value; //当前tab 上下箭头选中样式
|
||||
store.commit('user/setIsFiltrate',true)
|
||||
store.commit('user/setIstabChange',true)
|
||||
store.commit('user/setFilterOverTime',false);
|
||||
// 距离排序,给后端传的距离排序值 1升序,2降序
|
||||
if (index === 0) {
|
||||
let val = null
|
||||
if (isSelect.value) {
|
||||
val = 1;
|
||||
} else {
|
||||
val = 2;
|
||||
}
|
||||
|
||||
store.commit('user/setOrderDistance',val) //储存,方便父组件使用
|
||||
store.commit('user/setFilterOverTime',null) //储存,清除时间排序值
|
||||
store.commit('user/setOrderTime',null) //储存,清除超时值
|
||||
} else if (index === 1){
|
||||
//时间排序,给后端传的时间排序值 1升序,2降序
|
||||
let val = null
|
||||
if (isSelect.value) {
|
||||
val = 1;
|
||||
} else {
|
||||
val = 2;
|
||||
}
|
||||
store.commit('user/setOrderTime',val) //储存,方便父组件使用
|
||||
store.commit('user/setOrderDistance',null) //储存,清除距离排序值
|
||||
store.commit('user/setFilterOverTime',null) //储存,清除超时值
|
||||
}else{
|
||||
store.commit('user/setFilterOverTime',true) //储存,方便父组件使用
|
||||
store.commit('user/setOrderTime',null) //储存,清除时间排序值
|
||||
store.commit('user/setOrderDistance',null) //储存,清除距离排序值
|
||||
}
|
||||
|
||||
emit('getList')
|
||||
};
|
||||
</script>
|
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<uni-nav-bar :title="title" statusBar="true" fixed="true" v-if="isLeftText"></uni-nav-bar>
|
||||
<uni-nav-bar v-else @clickLeft="goBack" left-icon="back" leftIcon="arrowleft" :title="title" statusBar="true" fixed="true" :right-text="rithtText" @clickRight="handleAll"></uni-nav-bar>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useStore } from "vuex";
|
||||
// 获取父组件数据
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
rithtText:{
|
||||
type:String,
|
||||
default:''
|
||||
},
|
||||
isLeftText:{
|
||||
type:Boolean
|
||||
}
|
||||
});
|
||||
// ------定义变量------
|
||||
const emit = defineEmits(); //子组件向父组件事件传递
|
||||
const store = useStore(); //vuex获取、储存数据
|
||||
const users = store.state.user; //vuex获取、储存数据
|
||||
const taskStatus = users.taskStatus;
|
||||
// ------定义方法------
|
||||
const goBack = () => {
|
||||
emit('goBack');
|
||||
};
|
||||
const handleAll = ()=>{
|
||||
emit('handleAll')
|
||||
}
|
||||
</script>
|
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<view class="container phoneCon">
|
||||
<uni-popup ref="popup" type="bottom" class="popupBox">
|
||||
<view class="popup-content">
|
||||
<view>{{ phoneData }}</view>
|
||||
<view @click="call">呼叫</view>
|
||||
</view>
|
||||
<view @click="closePopup" class="closePopup">取消</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { call } from "@/utils/index.js";
|
||||
|
||||
// 获取父组件数据
|
||||
const props = defineProps({
|
||||
// 是否触发管理按钮
|
||||
phoneData: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
const popup = ref();
|
||||
// //TODO 电话号码拨打
|
||||
// const call = () =>{
|
||||
// // 暂时关闭打电话
|
||||
// // call(this.phoneData)
|
||||
// }
|
||||
// // 打开弹层
|
||||
const dialogOpen = () => {
|
||||
popup.value.open();
|
||||
};
|
||||
// 关闭弹层
|
||||
const closePopup = () => {
|
||||
popup.value.close();
|
||||
};
|
||||
// //把数据、方法暴漏给父组件
|
||||
defineExpose({ dialogOpen });
|
||||
</script>
|
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<uni-popup ref="message" type="dialog" class="commDialog">
|
||||
<uni-popup-dialog :type="msgType" cancelText="取消" confirmText="确认" title=" " :content="tipInfo" @confirm="dialogConfirm" @close="dialogClose"></uni-popup-dialog>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
// 获取父组件数据
|
||||
const props = defineProps({
|
||||
tipInfo: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
// ------定义变量------
|
||||
const emit =defineEmits() //子组件向父组件事件传递
|
||||
const message =ref()
|
||||
// ------定义方法------
|
||||
// 确认清除弹层
|
||||
const dialogConfirm = () => {
|
||||
emit('handleClick',true)
|
||||
};
|
||||
// 打开弹层
|
||||
const dialogOpen = () => {
|
||||
message.value.open();
|
||||
};
|
||||
// 关闭弹层
|
||||
const dialogClose = () => {
|
||||
message.value.close();
|
||||
};
|
||||
// 向父组件暴露方法
|
||||
defineExpose({
|
||||
dialogOpen
|
||||
})
|
||||
</script>
|
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<!-- 公用nav -->
|
||||
<view class="navBox">
|
||||
<view class="search ">
|
||||
<!-- 头部自定义导航 -->
|
||||
<!-- <uni-nav-bar right-text="取消" @clickRight="handleCancel"> -->
|
||||
<view class="uni-navbar">
|
||||
<view class="input-view">
|
||||
<uni-icons class="input-uni-icon" type="search" size="18" color="#999" />
|
||||
<input
|
||||
confirm-type="search"
|
||||
class="nav-bar-input"
|
||||
type="text"
|
||||
v-model="searchVal"
|
||||
clearable
|
||||
placeholder="输入四位或完整运单号/手机号、姓名"
|
||||
@confirm="handleBlur"
|
||||
@input="handleSearch"
|
||||
/>
|
||||
<text v-if="searchVal" class="icon_close" @click="handleClear"></text>
|
||||
<!-- <view class="scanIcon" @click="handleQr"></view> -->
|
||||
</view>
|
||||
<view class="concelBox" @click="handleCancel" v-if="isShowCancel">取消</view>
|
||||
</view>
|
||||
<!-- </uni-nav-bar> -->
|
||||
<!-- end -->
|
||||
</view>
|
||||
</view>
|
||||
<!-- end -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
const store = useStore(); //vuex获取、储存数据
|
||||
const users = store.state.user;
|
||||
const props = defineProps({
|
||||
isShowCancel:{
|
||||
type:Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
// ------定义变量------
|
||||
const emit = defineEmits('handleSearch'); //子组件向父组件事件传递
|
||||
const searchVal = ref('');
|
||||
// -----方法------
|
||||
// 取消搜索
|
||||
const handleCancel = () => {
|
||||
searchVal.value = '';
|
||||
// 设置搜索的内容,从详情页返回搜索页的时候显示默认搜索的内容
|
||||
store.commit('user/setSearchText', '');
|
||||
if(users.taskStatus===-1){
|
||||
uni.redirectTo({
|
||||
url: '/pages/my/index'
|
||||
});
|
||||
}else{
|
||||
emit('goBack')
|
||||
}
|
||||
|
||||
};
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
emit('handleSearch', searchVal);
|
||||
};
|
||||
// 离开input框
|
||||
const handleBlur =()=>{
|
||||
emit('handleBlur')
|
||||
}
|
||||
// 清空
|
||||
const handleClear=()=>{
|
||||
searchVal.value = '';
|
||||
emit('clearSearchData')
|
||||
}
|
||||
// 扫二维码
|
||||
const handleQr = () => {};
|
||||
// 暴漏给父组件
|
||||
defineExpose({
|
||||
searchVal
|
||||
});
|
||||
</script>
|
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<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.label }}
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
// 获取父组件数据
|
||||
const props = defineProps({
|
||||
tabBars: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
// ------定义变量------
|
||||
const store = useStore();
|
||||
const users = store.state.user;
|
||||
const emit = defineEmits(""); //子组件向父组件事件传递
|
||||
const scrollinto = ref("tab0"); //tab切换
|
||||
let tabIndex = ref(users.tabIndex ? users.tabIndex : 0); //当前tab
|
||||
// ------定义方法------
|
||||
// tab选项卡切换轮播
|
||||
const changeTab = (index) => {
|
||||
// 点击的还是当前数据的时候直接return
|
||||
if (tabIndex.value == index) {
|
||||
return;
|
||||
}
|
||||
tabIndex.value = index;
|
||||
emit("getTabIndex", index);
|
||||
// 滑动
|
||||
scrollinto.value = "tab" + index;
|
||||
};
|
||||
//把数据、方法暴漏给父组件
|
||||
defineExpose({
|
||||
changeTab,
|
||||
});
|
||||
</script>
|
Reference in New Issue
Block a user