init
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
<!--收寄地址-->
|
||||
<template>
|
||||
<view class="boxBg">
|
||||
<view class="addressCon">
|
||||
<view class="item" @click="handleDate(1)">
|
||||
<view class="sendIcon">寄</view>
|
||||
<view class="address">
|
||||
<view :class="mailCity.province ? 'active' : ''">
|
||||
<view v-if="!mailCity.province">请选择寄件城市</view>
|
||||
<view v-else>
|
||||
<text>{{ mailCity.province }}</text>
|
||||
<text>{{ mailCity.city }}</text>
|
||||
<text>{{ mailCity.area }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<icon class="nextIcon"></icon>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
</view>
|
||||
<view class="item" @click="handleDate(2)">
|
||||
<view class="receiveIcon">收</view>
|
||||
<view class="address">
|
||||
<view :class="consigneeCity.province ? 'active' : ''">
|
||||
<view v-if="!consigneeCity.province">请选择收件城市</view>
|
||||
<view v-else>
|
||||
<text>{{ consigneeCity.province }}</text>
|
||||
<text>{{ consigneeCity.city }}</text>
|
||||
<text>{{ consigneeCity.area }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<icon class="nextIcon"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<CityPopup ref="city" :type="type" @getCity="getCity"></CityPopup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
// 接口pai
|
||||
// 导入组件
|
||||
// 城市弹层
|
||||
import CityPopup from "@/components/uni-address/index.vue";
|
||||
// ------定义变量------
|
||||
const city = ref(); //定义子组件ref,获取子组件方法
|
||||
const emit = defineEmits();
|
||||
let type = ref(null); //触发的寄件还是收件:type=1 寄件;type=2 收件
|
||||
let mailCity = ref({}); //寄件数据
|
||||
let consigneeCity = ref({}); //收件数据
|
||||
// ------定义方法------
|
||||
// 地址弹层弹层
|
||||
const handleDate = (val) => {
|
||||
// type代表触发的寄件还是收件:type=1 寄件;type=2 收件
|
||||
type.value = val;
|
||||
city.value.handleOpen();
|
||||
};
|
||||
// 获取区县
|
||||
const getCity = (obj) => {
|
||||
if (type.value === 1) {
|
||||
mailCity.value = obj;
|
||||
} else {
|
||||
consigneeCity.value = obj;
|
||||
}
|
||||
if (mailCity.value.areaId && consigneeCity.value.areaId) {
|
||||
emit("handleCity", true);
|
||||
}
|
||||
};
|
||||
//把数据、方法暴漏给父组件
|
||||
defineExpose({
|
||||
mailCity,
|
||||
consigneeCity,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style></style>
|
@@ -0,0 +1,290 @@
|
||||
<!--重量体积计算-->
|
||||
<template>
|
||||
<view class="boxBg">
|
||||
<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>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, nextTick } from "vue";
|
||||
// ------定义变量------
|
||||
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³
|
||||
|
||||
// 暴漏给父组件
|
||||
defineExpose({
|
||||
weight,
|
||||
volume,
|
||||
measureLong,
|
||||
measureWidth,
|
||||
measureHigh,
|
||||
});
|
||||
// ------生命周期------
|
||||
// 监听重量数值,小数点后保留一位
|
||||
watch(weight, (newValue, oldValue) => {
|
||||
const val = Number(newValue);
|
||||
nextTick(() => {
|
||||
// 数值小于0.1并且大于0 数值默认为1
|
||||
if (val < 0.1 && val > 0) {
|
||||
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;
|
||||
}
|
||||
});
|
||||
});
|
||||
// ------定义方法------
|
||||
//触发重量输入如果输入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; //左侧减号去除置灰
|
||||
}
|
||||
if (value >= 9999) {
|
||||
isExceed.value = true; //右侧加号置灰
|
||||
weight.value = 9999;
|
||||
} else {
|
||||
isExceed.value = false; //右侧加号去除置灰
|
||||
}
|
||||
}
|
||||
};
|
||||
// 减重量
|
||||
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; //左侧减号置灰
|
||||
}
|
||||
};
|
||||
// 加重量
|
||||
const handleAdd = () => {
|
||||
// 重量加1
|
||||
if (weight.value < 9999) {
|
||||
++weight.value;
|
||||
isLessThan.value = false; //左侧减号去除置灰
|
||||
}
|
||||
if (weight.value === 9999) {
|
||||
isExceed.value = true; //右侧加号置灰
|
||||
}
|
||||
};
|
||||
|
||||
// 体积
|
||||
const handleVolume = (e) => {
|
||||
const value = Number(e.detail.value);
|
||||
if (value < 0.0001) {
|
||||
volume.value = 0;
|
||||
} else {
|
||||
if (value > 99) {
|
||||
volume.value = 99;
|
||||
return uni.showToast({
|
||||
title: "体积最大可不能超过99m³",
|
||||
duration: 1000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
// 减体积
|
||||
const handleVolumeMinus = () => {
|
||||
// 体积减去1
|
||||
if (volume.value > 1) {
|
||||
volume.value--;
|
||||
volume.value = parseInt(volume.value * 10000) / 10000;
|
||||
}
|
||||
// 体积
|
||||
if (volume.value <= 0 || volume.value === 1) {
|
||||
volume.value = 0;
|
||||
}
|
||||
};
|
||||
// 加体积
|
||||
const handleVolumeAdd = () => {
|
||||
// 体积加1
|
||||
if (volume.value < 99) {
|
||||
++volume.value;
|
||||
isLessThanVolume.value = false; //左侧减号去除置灰
|
||||
}
|
||||
if (volume.value === 99) {
|
||||
isExceedVolume.value = true; //右侧加号置灰
|
||||
}
|
||||
};
|
||||
// 计算立方米
|
||||
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; //右侧加号去除置灰
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
@@ -0,0 +1,23 @@
|
||||
<!--重量体积查询结果-->
|
||||
<template>
|
||||
<view class="boxBg result">
|
||||
<view>计费重量:{{ baseData.weight }} kg</view>
|
||||
<view>计费体积:{{ baseData.volumeValue }} m³</view>
|
||||
<view
|
||||
>首重(1.0kg){{ baseData.firstWeight }}元,续重{{
|
||||
baseData.continuousWeight
|
||||
}}元/kg</view
|
||||
>
|
||||
<view class="price"><text>¥</text>{{ baseData.freight }}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 获取父组件数据
|
||||
const props = defineProps({
|
||||
baseData: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
</script>
|
88
project-wl-kuaidiyuan-uniapp-vue3/pages/freight/index.scss
Normal file
88
project-wl-kuaidiyuan-uniapp-vue3/pages/freight/index.scss
Normal file
@@ -0,0 +1,88 @@
|
||||
body,
|
||||
uni-page-body {
|
||||
background: var(--neutral-color-background) !important;
|
||||
}
|
||||
.freightBox {
|
||||
.boxBg {
|
||||
box-shadow: none;
|
||||
margin-top: 36rpx;
|
||||
padding: 0 32rpx;
|
||||
}
|
||||
.btnBox{
|
||||
.btn-default{
|
||||
width: 400rpx;
|
||||
}
|
||||
}
|
||||
::v-deep .result{
|
||||
padding: 36rpx 26rpx 16rpx;
|
||||
line-height: 42rpx;
|
||||
margin-top: 0;
|
||||
position: relative;
|
||||
view{
|
||||
padding-bottom: 14rpx;
|
||||
&:nth-child(3){
|
||||
color: var(--neutral-color-font);
|
||||
font-weight: normal;
|
||||
font-size: var(--font-size-12);
|
||||
}
|
||||
}
|
||||
.price{
|
||||
position: absolute;
|
||||
right: 40rpx;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
font-size: 40rpx;
|
||||
color: var(--essential-color-red) !important;
|
||||
line-height: 42rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text{
|
||||
font-size: var(--font-size-12);
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep .addressCon {
|
||||
.item {
|
||||
height: 138rpx;
|
||||
line-height: 138rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:first-child {
|
||||
.address {
|
||||
border-bottom: 1px solid var(--neutral-color-background);
|
||||
}
|
||||
}
|
||||
.address {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&>view {
|
||||
flex: 1;
|
||||
color: var(--neutral-color-font);
|
||||
&.active {
|
||||
color: var(--neutral-color-main);
|
||||
font-weight: 600;
|
||||
font-size: var(--font-size-16);
|
||||
text{
|
||||
padding-right: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep .goodsCon {
|
||||
padding: 8rpx 0 32rpx;
|
||||
font-size: var(--font-size-13);
|
||||
font-weight: 600;
|
||||
.item{
|
||||
& > text {
|
||||
width: 104rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
114
project-wl-kuaidiyuan-uniapp-vue3/pages/freight/index.vue
Normal file
114
project-wl-kuaidiyuan-uniapp-vue3/pages/freight/index.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<!-- 运费查询页 -->
|
||||
<template>
|
||||
<!-- 自定义头部 -->
|
||||
<view class="navHead"><UniNav :title="title" @goBack="goBack"></UniNav></view>
|
||||
<!-- end -->
|
||||
<!-- 列表 -->
|
||||
<view class="pageBox freightBox">
|
||||
<!-- 地址 -->
|
||||
<UniAddress ref="address" @handleCity="handleCity"></UniAddress>
|
||||
<!-- end -->
|
||||
<!-- 重量、体积计算 -->
|
||||
<view class="boxBg">
|
||||
<GoodsInfo ref="goods"></GoodsInfo>
|
||||
</view>
|
||||
|
||||
<!-- end -->
|
||||
<!-- 查询按钮 -->
|
||||
<view class="btnBox"
|
||||
><button
|
||||
class="btn-default"
|
||||
:class="isCityId ? '' : 'btn-forbid'"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
立即查询
|
||||
</button></view
|
||||
>
|
||||
<!-- end -->
|
||||
<!-- 查询结果 -->
|
||||
<Result :baseData="baseData.value" v-if="isShow"></Result>
|
||||
<!-- end -->
|
||||
</view>
|
||||
<!-- end -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
// 接口 api
|
||||
import { calculateFreight } from "@/pages/api/freight.js";
|
||||
// 导入组件
|
||||
// 导航组件
|
||||
import UniNav from "@/components/uni-nav/index.vue";
|
||||
// 地址选择组件
|
||||
import UniAddress from "./components/address.vue";
|
||||
// 物品信息组件
|
||||
import GoodsInfo from "@/components/uni-goods/index.vue";
|
||||
// 查询结果
|
||||
import Result from "./components/result.vue";
|
||||
// ------定义变量------
|
||||
const title = ref("运费查询");
|
||||
const isShow = ref(false);//是否显示查询结果
|
||||
let baseData = reactive({});//储存数据
|
||||
const goods = ref(); //定义子组件的ref,可以调取子组件的值
|
||||
const address = ref(); //定义子组件的ref,可以调取子组件的值
|
||||
const isCityId = ref(false);
|
||||
// ------定义方法------
|
||||
// 立即查询
|
||||
const handleSubmit = async () => {
|
||||
// 显示查询结果
|
||||
const senderCountyId = address.value.mailCity.areaId; // 寄件id
|
||||
const receiverCountyId = address.value.consigneeCity.areaId; // 收件id
|
||||
const goodData = goods.value;
|
||||
|
||||
if (!senderCountyId) {
|
||||
return uni.showToast({
|
||||
title: "请选择寄件城市",
|
||||
duration: 1000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
if (!receiverCountyId) {
|
||||
return uni.showToast({
|
||||
title: "请选择收件城市",
|
||||
duration: 1000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
isShow.value = true;
|
||||
let data = {
|
||||
senderCountyId: senderCountyId,
|
||||
receiverCountyId: receiverCountyId,
|
||||
volume: goodData.volume === 0 ? 1 : goodData.volume * 1000000,
|
||||
weight: goodData.weight,
|
||||
measureLong: goodData.measureLong,
|
||||
measureWidth: goodData.measureWidth,
|
||||
measureHigh: goodData.measureHigh,
|
||||
};
|
||||
const res = await calculateFreight(data);
|
||||
if (res.code === 200) {
|
||||
baseData.value = {
|
||||
volumeValue: goodData.volume,
|
||||
...res.data,
|
||||
};
|
||||
} else {
|
||||
return uni.showToast({
|
||||
title: res.msg,
|
||||
duration: 1000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
};
|
||||
// 是否选择了寄件地址和收件地址
|
||||
const handleCity = (val) => {
|
||||
isCityId.value = val;
|
||||
};
|
||||
|
||||
// 返回上一页
|
||||
const goBack = () => {
|
||||
uni.redirectTo({
|
||||
url: "/pages/index/index",
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style src="./index.scss" lang="scss" scoped></style>
|
Reference in New Issue
Block a user