| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641 |
- <template>
- <div class="app-delivery-module">
- <!-- 收花人 -->
- <div class="module-com">
- <tui-list-cell class="line-cell" :hover="false">
- <div class="tui-title">收花人姓名</div>
- <input v-model="form.receiveUserName" placeholder-class="phcolor" placeholder-style="color:#ccc" @blur="onInputBlur" class="tui-input" name="receiveUserName" placeholder="请填写姓名" />
- </tui-list-cell>
- <tui-list-cell class="line-cell" :hover="false">
- <div class="tui-title">收花人电话</div>
- <input v-model="form.receiveMobile" placeholder-class="phcolor" placeholder-style="color:#ccc" @blur="onInputBlur" class="tui-input" name="receiveMobile" placeholder="请填写电话" type="number" />
- </tui-list-cell>
- <tui-list-cell class="line-cell" :hover="false" :arrow="true" @click="openAddres">
- <div class="tui-title">所在城市</div>
- <div class="tui-input" v-if="form.province || form.city" >{{ form.province + '-' + form.city }}</div>
- <div class="tui-placeholder" v-else>请选择</div>
- </tui-list-cell>
- <tui-list-cell v-if="hasMap == 0" class="line-cell" :hover="false">
- <view class="tui-title">详细地址</view>
- <input v-model="form.address" placeholder-class="phcolor" class="tui-input" name="address" @input="modifyShow" placeholder="请填写地址" />
- </tui-list-cell>
- <tui-list-cell v-else class="line-cell" :hover="false" :arrow="true" @click="selRegionFn">
- <div class="tui-title">详细地址</div>
- <div class="tui-input" v-if="form.address">{{ form.address }}</div>
- <div class="tui-placeholder" v-else>请选择地址</div>
- </tui-list-cell>
- <tui-list-cell class="line-cell" :hover="false">
- <div class="tui-title">门牌号</div>
- <input v-model="form.floor" placeholder-class="phcolor" placeholder-style="color:#ccc" class="tui-input" name="floor" placeholder="楼号门牌号(选填)" @input="modifyShow" />
- </tui-list-cell>
- </div>
-
- <!-- 跑腿费 -->
- <div class="module-com" v-if="displaySendCost">
- <!-- 跑腿平台报价列表 -->
- <view v-if="deliveryQuotes.length > 0" class="delivery-quotes-container">
- <view class="delivery-quotes-grid">
- <view
- v-for="(item, index) in deliveryQuotes"
- :key="index"
- class="delivery-quote-item"
- :class="{
- 'active': selectedDeliveryIndex === index,
- 'disabled': !item.isAble,
- 'fixed-width': deliveryQuotes.length <= 2
- }"
- @click="selectDelivery(item, index)"
- >
- <view class="platform-name">{{ item.displayName || item.name }}</view>
- <view class="platform-price">{{ item.priceText }}元</view>
- <view v-if="item.type" class="platform-type">{{ item.type }}</view>
- </view>
- </view>
- </view>
- <view v-else-if="deliveryQuotesLoading" style="text-align: center; padding: 20upx 0; color: #999;">
- 正在获取报价...
- </view>
- <tui-list-cell class="line-cell" :hover="false" v-if="Number(showDistance)>0">
- <view class="tui-title">距离</view>
- <text v-if="showDistance > 100" style="color: #3385FF">{{ (showDistance/1000).toFixed(1) }}公里</text>
- <text v-else style="color: #3385FF">{{ showDistance }} 米</text>
- </tui-list-cell>
- <tui-list-cell class="line-cell" :hover="false">
- <view class="tui-title">跑腿费</view>
- <view>
- <text :class="isFreeDelivery ? 'delivery-price-free' : 'delivery-price-normal'">¥{{ isFreeDelivery ? 0 : (selectedDeliveryData ? selectedDeliveryData.priceNumber : 0) }}</text>
- <text v-if="isFreeDelivery" class="free-delivery-tag">¥0【免跑腿费】</text>
- </view>
- </tui-list-cell>
- </div>
- <!-- 订花人 -->
- <div class="module-com">
- <tui-list-cell class="line-cell" :hover="false" :arrow="true">
- <div class="tui-title">配送日期</div>
- <picker mode="date" :value="form.reachDate" @change="selTimeFn" class="tui-input">
- <div v-if="form.reachDate">{{ form.reachDate }}</div>
- <div v-else>今天</div>
- </picker>
- </tui-list-cell>
-
- <tui-list-cell class="line-cell" :hover="false" :arrow="false">
- <div class="tui-title">配送时间</div>
- <picker mode="multiSelector" :value="form.reachPeriod" :range="timeOptions" @change="bindTimeChange">
- <view class="uni-input" style="width:450upx;">{{form.reachPeriod}}<text style="margin-left:10upx;">前</text></view>
- </picker>
- </tui-list-cell>
- </div>
- <div class="module-com">
- <tui-list-cell class="line-cell" :hover="false">
- <div class="tui-title">贺卡内容</div>
- <textarea v-model="form.cardInfo" placeholder-class="phcolor" placeholder-style="color:#ccc" class="tui-input textarea-input" name="cardInfo" placeholder="请填写" :adjust-position="false" :cursor-spacing="0" :auto-height="false" :disable-default-padding="true" :show-confirm-bar="false" />
- </tui-list-cell>
- <tui-list-cell class="line-cell" :hover="false">
- <div class="tui-title">派送方式</div>
- <div class="delivery-mode-wrapper">
- <switch :checked="form.anonymity == 1" @change="anonymityChange" color="#ff6b35" />
- <span v-if="form.anonymity == 0" class="mode-text normal">不匿名</span>
- <span v-else class="mode-text anonymous">要匿名</span>
- </div>
- </tui-list-cell>
- <tui-list-cell class="line-cell" :hover="false">
- <div class="tui-title">备注内容</div>
- <textarea v-model="form.remark" placeholder-class="phcolor" placeholder-style="color:#ccc" class="tui-input textarea-input" name="remark" placeholder="选填,不要贺卡这里备注" :adjust-position="false" :cursor-spacing="0" :auto-height="false" :disable-default-padding="true" :show-confirm-bar="false" />
- </tui-list-cell>
- </div>
- <!-- 省市联动 -->
- <simple-address ref="simpleAddress" :region="orderShop.region" :pickerValueDefault="cityPickerValueDefault" @onConfirm="onCityConfirm" >
- </simple-address>
- <!-- 选择地区 -->
- <app-area-sel :isFocus="false" :show.sync="showRegion" :city="form.city" @change="changeAreaFn" />
- </div>
- </template>
- <script>
- import { mapGetters } from "vuex";
- import TuiListCell from "@/components/plugin/list-cell";
- import AppDatePicker from "@/components/app-date-picker";
- import SimpleAddress from "@/components/plugin/simple-address";
- import AppAreaSel from "@/components/app-area-sel";
- import { allDeliveryQuotes } from "@/api/express/delivery";
- export default {
- name: "app-delivery-module",
- components: {
- AppAreaSel,
- TuiListCell,
- AppDatePicker,
- SimpleAddress
- },
- props: {
- hasMap: {
- type: Number,
- default: 0
- },
- openIntraCity: {
- type: Number,
- default: 0
- },
- hcFreeKm: {
- type: Number,
- default: 0
- },
- hcMap: {
- type: Array,
- default: () => []
- },
- allPriceFun: {
- type: Number,
- default: 0
- },
- allCountFun: {
- type: Object,
- default: () => ({
- bigLength: 0,
- weight: 0
- })
- },
- },
- data() {
- return {
- region: [],
- showRegion: false,
- form: {
- receiveUserName: "", // 收花人姓名;到店自提的姓名
- receiveMobile: "", // 收花人手机;到店自提的电话;
- province: "", // 收花人省份
- city: "", // 收花人城市
- address: "", // 收花人城市
- floor: "", // 收花人门楼号和牌号
- showAddress: "", // 收花人完整地址,从腾讯地图接口获取
- reachDate: "", // 配送时间
- reachPeriod: "12:00", // 配送时段,0上午1下午2晚上
- cardInfo: "", // 贺卡信息
- remark: "", // 备注
- anonymity:0
- },
- region: {
- latitude: 0,
- longitude: 0
- },
- showDistance: 0,
- deliveryQuotes: [], // 跑腿平台报价列表
- selectedDeliveryIndex: -1, // 选中的报价索引
- deliveryQuotesLoading: false, // 报价加载状态
- selectedDeliveryData: null, // 选中的报价数据
- // 省市联动
- cityPickerValueDefault: [0, 0],
- timeOptions: [
- ['00', '01', '02','03','04','05','06','07','08','09','10','11','12','13', '14','15','16','17','18','19','20','21','22','23'],
- ['00', '05', '10','15','20','25','30','35','40','45','50','55']
- ]
- };
- },
- computed: {
- ...mapGetters({ orderShop: "getOrderShop" }),
- ...mapGetters({ shopUser: "getShopUser" }),
- displaySendCost() {
- if (this.openIntraCity == 1) {
- return true;
- }
- return false;
- },
- isFreeDelivery() {
- // 不显示跑腿费时,不需要判断
- if (this.displaySendCost == false) {
- return false;
- }
- // 条件1: 比较距离与免费公里数
- // showDistance单位是米,hcFreeKm单位是千米
- const distanceInMeters = Number(this.showDistance) || 0;
- const freeKmInMeters = (Number(this.hcFreeKm) || 0) * 1000;
- // 如果距离小于免费公里数,则免运费
- if (distanceInMeters < freeKmInMeters) {
- return true;
- }
- // 条件2: 如果距离大于免费公里数,判断hcMap
- if (distanceInMeters > freeKmInMeters) {
- // 判断hcMap是否为空
- if (this.hcMap && Array.isArray(this.hcMap) && this.hcMap.length > 0) {
- // 获取花材数量和总价
- const flowerCount = this.allCountFun.bigLength || 0;
- const flowerPrice = this.allPriceFun || 0;
- // 遍历hcMap,检查是否满足免运费条件
- for (const rule of this.hcMap) {
- const ruleNum = Number(rule.num) || 0;
- const rulePrice = Number(rule.price) || 0;
- const ruleDistance = (Number(rule.distance) || 0) * 1000; // 转换为米
- // 如果花材数量大于num,花材总价大于price,距离小于distance,则免运费
- if (flowerCount >= ruleNum && flowerPrice >= rulePrice && distanceInMeters <= ruleDistance) {
- return true;
- }
- }
- }
- }
- return false;
- }
- },
- watch: {
- orderShop(val) {
- console.log("val", val);
- this.form.province = val.shop.province ? val.shop.province : "";
- this.form.city = val.shop.city ? val.shop.city : "";
- }
- },
- mounted() {
- if (!this.$util.isEmpty(this.orderShop)) {
- this.form.province = this.orderShop.shop.province ? this.orderShop.shop.province : ""
- this.form.city = this.orderShop.shop.city ? this.orderShop.shop.city : ""
- }
- },
- methods: {
- bindTimeChange(event){
- let val = event.detail.value
- let before = Number(val[0])
- let after = Number(val[1])
- let timeOptions = this.timeOptions
- this.form.reachPeriod = timeOptions[0][before]+':'+timeOptions[1][after]
- },
- selTimeFn(e) {
- this.form.reachDate = e.detail.value;
- },
- // 选择地址
- selRegionFn() {
- if (!this.form.city) {
- this.$msg("请先选择地址!");
- return false;
- }
- this.showRegion = true;
- },
- changeAreaFn(e) {
- this.form.address = e.name;
- this.form.showAddress = e.address;
- let locationStr = e.location
- let fruits = locationStr.split(",").map(fruit => fruit.trim());
- this.region.latitude = fruits[1];
- this.region.longitude = fruits[0];
- this.triggerGetDeliveryQuotes();
- },
- onInputBlur(){
- this.triggerGetDeliveryQuotes();
- },
- triggerGetDeliveryQuotes() {
- if (this.form.receiveUserName && this.form.receiveMobile && this.form.address) {
- this.getDeliveryQuotes();
- }
- },
- getDeliveryQuotes() {
- this.deliveryQuotesLoading = true;
- this.deliveryQuotes = [];
- this.selectedDeliveryIndex = -1;
- this.selectedDeliveryData = null;
-
- allDeliveryQuotes({
- weight: this.allCountFun.weight,
- selectList: [], // 根据需要传递
- remark: this.form.remark,
- }).then(res => {
- this.deliveryQuotesLoading = false;
- if (res.code === 1 && res.data && res.data.deliveryList) {
- this.deliveryQuotes = res.data.deliveryList
- .filter(item => item.isAble !== false)
- .map(item => {
- const price = item.price ? (item.price / 100).toFixed(1) : '0.0';
- let displayName = item.name;
- if (displayName && displayName.includes('(')) {
- displayName = displayName.split('(')[0].trim();
- }
- return {
- ...item,
- displayName: displayName,
- priceText: price,
- priceNumber: parseFloat(price)
- };
- });
-
- const firstAvailableIndex = this.deliveryQuotes.findIndex(item => item.isAble);
- if (firstAvailableIndex !== -1) {
- this.selectDelivery(this.deliveryQuotes[firstAvailableIndex], firstAvailableIndex);
- }
- } else {
- uni.showToast({
- title: '暂无可用的配送平台',
- icon: 'none'
- });
- }
- }).catch(err => {
- this.deliveryQuotesLoading = false;
- console.error('获取跑腿报价失败:', err);
- uni.showToast({
- title: '获取报价失败',
- icon: 'none'
- });
- });
- },
- selectDelivery(item, index) {
- if (!item.isAble) return;
- this.selectedDeliveryIndex = index;
- this.selectedDeliveryData = item;
- this.showDistance = item.distance || 0;
- const freight = this.isFreeDelivery ? 0 : item.priceNumber;
- this.$emit("countFreight", {
- sendCost: freight,
- deliveryPlatform: item.en_name,
- deliveryPrice: item.priceNumber,
- deliveryDistance: item.distance || 0,
- });
- },
- anonymityChange(e) {
- this.form.anonymity = e.detail.value ? 1 : 0;
- },
- // 省市联动
- openAddres() {
- //城市暂时不可修改 shish 2020.5.11
- this.$refs.simpleAddress.open();
- },
- onCityConfirm(e) {
- this.form.address = e.label;
- this.form.province = e.provinceName;
- this.form.city = e.cityName;
- },
- modifyShow(){
- this.form.showAddress = this.form.province+this.form.city+this.form.address+this.form.floor
- },
- }
- };
- </script>
- <style lang="scss" scoped>
- .app-delivery-module {
- .module-com {
- margin-bottom: 20upx;
- background-color: #fff;
- .module-tit {
- padding: 20upx 18upx;
- font-size: 28upx;
- font-weight: 600;
- border-bottom: 1upx solid $borderColor;
- }
- .module-det {
- padding: 0 30upx;
- }
- }
- // 公共
- .line-cell {
- .tui-title {
- width: 210upx;
- color: $fontColor2;
- }
- .tui-input {
- width: calc(100% - 210upx);
- font-size: 28upx;
- }
- .tui-placeholder {
- color: #ccc;
- }
- .phcolor {
- color: green;
- }
- }
- // 今天时间选择
- .delivery-time {
- @include disFlex(center, center);
- .button-com {
- padding-top: 14upx;
- padding-bottom: 10upx;
- margin: 0 10upx;
- }
- }
- // 贺卡
- .gift-wrap {
- .gift-content {
- width: 100%;
- }
- .need-gift {
- margin-left: 14upx;
- color: $fontColor2;
- }
- .gitf-textarea {
- margin-top: 40upx;
- }
- }
- // 派送方式选择器样式
- .delivery-mode-wrapper {
- display: flex;
- align-items: center;
- justify-content: flex-end;
-
- .mode-text {
- font-size: 40upx;
- margin-left: 10upx;
- transition: color 0.3s ease;
- &.normal {
- // 不匿名 - 使用页面常规颜色
- color: #666666;
- }
-
- &.anonymous {
- // 匿名 - 使用显眼颜色
- color: #ff6b35;
- font-weight: bold;
- }
- }
-
- switch {
- transform: scale(0.8);
- }
- }
- // textarea样式 - 彻底解决input文字浮动问题
- .textarea-input {
- /* 重置textarea默认样式,使其表现像input */
- resize: none !important;
- overflow: hidden !important;
- border: none !important;
- outline: none !important;
- background: transparent !important;
- padding: 0 !important;
- margin: 0 !important;
-
- /* 固定高度和行高,防止浮动 */
- height: 44upx !important;
- max-height: 44upx !important;
- min-height: 44upx !important;
- line-height: 44upx !important;
-
- /* 字体样式保持一致 */
- font-size: 28upx !important;
- font-family: inherit !important;
- color: inherit !important;
-
- /* 文字单行显示,模拟input行为 */
- white-space: nowrap !important;
- text-overflow: ellipsis !important;
- word-wrap: normal !important;
- word-break: keep-all !important;
-
- /* 垂直对齐 */
- vertical-align: middle !important;
- text-align: left !important;
-
- /* 微信小程序特殊处理 */
- /* #ifdef MP-WEIXIN */
- /* 禁用textarea的多行特性 */
- overflow-y: hidden !important;
- scrollbar-width: none !important;
- /* 固定位置,防止键盘影响 */
- position: relative !important;
- z-index: 1 !important;
- /* 禁用文字大小自动调整 */
- -webkit-text-size-adjust: none !important;
- text-size-adjust: none !important;
- /* 强制使用系统字体 */
- font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, sans-serif !important;
- /* #endif */
-
- /* H5环境优化 */
- /* #ifdef H5 */
- box-sizing: border-box !important;
- -webkit-appearance: none !important;
- appearance: none !important;
- /* #endif */
-
- /* APP环境优化 */
- /* #ifdef APP-PLUS */
- box-sizing: border-box !important;
- /* #endif */
- }
- }
- /* 跑腿平台报价样式 */
- .delivery-quotes-container {
- width: 100%;
- margin-top: 20upx;
- padding: 0 20upx;
- }
- .delivery-quotes-grid {
- display: flex;
- flex-wrap: wrap;
- gap: 10upx;
- padding: 0;
- width: 100%;
- }
- .delivery-quote-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- flex: 0 0 calc(33% - 7upx);
- width: calc(33% - 7upx);
- min-height: 140upx;
- padding: 16upx 10upx;
- margin-bottom: 5upx;
- background: #FFFFFF;
- border: 2upx solid #DDDDDD;
- border-radius: 8upx;
- box-sizing: border-box;
- transition: all 0.3s;
-
- // 当只有1-2项时使用固定宽度
- &.fixed-width {
- flex: 0 0 220rpx;
- width: 220rpx;
- }
-
- .platform-name {
- font-size: 26upx;
- color: #333;
- font-weight: bold;
- margin-bottom: 8upx;
- text-align: center;
- line-height: 1.3;
- max-width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- line-clamp: 2;
- -webkit-box-orient: vertical;
- word-break: break-all;
- }
-
- .platform-price {
- font-size: 30upx;
- color: #333;
- font-weight: bold;
- margin-bottom: 4upx;
- }
-
- .platform-type {
- font-size: 20upx;
- color: #868686;
- margin-top: 4upx;
- text-align: center;
- line-height: 1.3;
- max-width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- line-clamp: 2;
- -webkit-box-orient: vertical;
- word-break: break-all;
- }
-
- // 选中状态
- &.active {
- background: #09C567;
- border-color: #09C567;
-
- .platform-name,
- .platform-price {
- color: #FFFFFF;
- }
-
- .platform-type {
- color: rgba(255, 255, 255, 0.85);
- }
- }
-
- // 不可用状态
- &.disabled {
- opacity: 0.5;
- background: #F5F5F5;
-
- .platform-name,
- .platform-price,
- .platform-type {
- color: #CCCCCC;
- }
- }
- }
- /* 跑腿费价格样式 */
- .delivery-price-normal {
- color: #3385FF;
- }
- .delivery-price-free {
- color: #999;
- text-decoration: line-through;
- }
- .free-delivery-tag {
- color: #3385FF;
- margin-left: 10upx;
- }
- </style>
|