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,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>

View File

@@ -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></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>

View File

@@ -0,0 +1,23 @@
<!--重量体积查询结果-->
<template>
<view class="boxBg result">
<view>计费重量{{ baseData.weight }} kg</view>
<view>计费体积{{ baseData.volumeValue }} </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>

View 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;
}
}
}

View 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>