You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
shop-pc/components/BsAddress.vue

510 lines
14 KiB

<template>
<div>
<div class="address flex flex-middle" v-if="!isOperation && !isAccount">
<article class="address__msg">
<div class="address__msg-line flex flex-middle">
<img src="@/assets/img/goods/point.png" alt="收货地址" />
<span class="address__msg-line--txt">默认地址</span>
<UiButton type="yellow_panel" @click="onEdit()"></UiButton>
</div>
<div class="address__msg-line flex flex-middle">
<span class="address__msg-line--type">收货地址:</span>
<span class="address__msg-line--txt">{{
curAddressListItem.province +
curAddressListItem.city +
curAddressListItem.area +
curAddressListItem.detailAddress
}}</span>
</div>
<div class="address__msg-line flex flex-middle">
<span class="address__msg-line--type"> :</span>
<span class="address__msg-line--txt">{{
curAddressListItem.name
}}</span>
</div>
<div class="address__msg-line flex flex-middle">
<span class="address__msg-line--type">手机号码:</span>
<span class="address__msg-line--txt">{{
curAddressListItem.phone
}}</span>
</div>
</article>
<div class="hr"></div>
<div class="address__operation flex flex-column flex-middle">
<UiButton type="grey" class="flex flex-middle" @click="onSwtich">
<img
class="icon"
src="@/assets/img/goods/switch.png"
alt="切换地址"
/>
切换地址
</UiButton>
<UiButton
type="grey"
@click="isOperation = true"
class="flex flex-middle"
>
<img class="icon" src="@/assets/img/goods/add.png" alt="新建地址" />
新建地址
</UiButton>
</div>
</div>
<div
class="address"
:class="isAccount ? 'account' : 'flex flex-middle'"
v-else
>
<article class="address__msg">
<div class="address__msg-line flex flex-middle">
<span class="address__msg-line--type">所在区域</span>
<no-ssr
><v-distpicker
:province="selectData.province.value"
:city="selectData.city.value"
:area="selectData.area.value"
@selected="onSelected"
></v-distpicker
></no-ssr>
</div>
<div class="address__msg-line flex flex-middle">
<span class="address__msg-line--type">详细地址</span>
<el-input
v-model="detailAddress"
type="textarea"
:rows="3"
class="max-ipt"
maxlength="60"
></el-input>
</div>
<div class="address__msg-line flex flex-middle">
<span class="address__msg-line--type">收货人</span>
<el-input v-model="addressUser" class="min-ipt"></el-input>
<span class="address__msg-line--type">手机号码</span>
<el-input
v-model="addressPhone"
oninput="value=value.replace(/[^\d]/g,'')"
class="min-ipt"
></el-input>
</div>
</article>
<div class="hr" v-if="!isAccount"></div>
<div
class="address__edit flex flex-middle"
:class="!isAccount ? 'flex-column' : ''"
>
<el-checkbox v-model="defaultAddress"></el-checkbox>
<div class="address__edit--btns flex flex-middle">
<UiButton
v-if="addressList && addressList.length && !isAccount"
type="grey"
@click="isOperation = false"
>取消</UiButton
>
<UiButton type="yellow_panel" @click="onAddAddress"
>{{ getEditState ? "保存" : "新增" }}地址</UiButton
>
</div>
</div>
</div>
<el-dialog
title="选择地址"
center
:visible.sync="dialogVisible"
width="380px"
>
<div class="address__list">
<section
@click="onAddressItem(item)"
class="address__list-item"
:class="
item.id == curAddressListItem.id ? 'address__list-active' : ''
"
v-for="item in addressList"
:key="item.id"
>
<div class="address__list-item--name">
<span class="address__list-item--label"> </span
>{{ item.name }}
</div>
<div class="address__list-item--phone">
<span class="address__list-item--label">手机号码</span
>{{ item.phone }}
</div>
<div class="address__list-item--detail">
<span class="address__list-item--label">收货地址</span>
{{ item.province + item.city + item.area + item.detailAddress }}
</div>
</section>
</div>
<span slot="footer" class="dialog-footer flex flex-between">
<UiButton type="grey" @click="onCancel"></UiButton>
<UiButton type="yellow_panel">确认</UiButton>
</span>
</el-dialog>
</div>
</template>
<script>
import UiButton from "@/components/UiButton.vue";
import { IsPhone } from "@/plugins/utils/index.js";
import {
ApiGetAddress,
ApiPostAddress,
ApiPutAddress,
} from "@/plugins/api/base";
export default {
components: { UiButton },
props: {
addressData: {
type: Object,
default: () => {},
},
isAccount: {
type: Boolean,
default: false,
},
isParentEdit: {
type: Boolean,
default: false,
},
},
model: {
prop: "addressData",
event: "emitAddress",
},
computed: {
getEditState() {
return this.isEdit || this.isParentEdit;
},
},
data() {
return {
isEdit: false,
isOperation: false,
dialogVisible: false,
detailAddress: "",
addressUser: "",
addressPhone: "",
defaultAddress: false,
selectData: {
area: {
value: "",
},
city: {
value: "",
},
province: {
value: "",
},
},
addressList: [{}],
curAddressListItem: 0,
editIndex: 0,
};
},
created() {
this.getAddressData();
},
methods: {
onEdit() {
let vm = this;
let curIndex = vm.addressList.findIndex(
(item) => item.id == vm.curAddressListItem.id
);
vm.isOperation = true;
vm.isEdit = true;
vm.setAddressData(curIndex);
},
async getAddressData() {
let vm = this;
let res = await ApiGetAddress();
if (res.result && res.result.length) {
vm.isOperation = false;
vm.addressList = res.result;
if (!vm.addressList.length) {
vm.defaultAddress = true;
}
let curIndex = vm.addressList.findIndex((item) => item.isDefault);
vm.curAddressListItem =
curIndex > -1 ? vm.addressList[curIndex] : vm.addressList[0];
vm.$emit("getList", vm.addressList);
vm.$emit("emitAddress", vm.curAddressListItem);
} else {
vm.isOperation = true;
}
console.log("获取收货地址", res);
},
setAddressData(i) {
let vm = this;
vm.editIndex = i;
let editItem = vm.addressList[i];
console.log(editItem);
vm.$set(vm.selectData.area, "value", editItem.area);
vm.$set(vm.selectData.city, "value", editItem.city);
vm.$set(vm.selectData.province, "value", editItem.province);
vm.$set(vm, "detailAddress", editItem.detailAddress);
vm.$set(vm, "defaultAddress", editItem.isDefault);
vm.$set(vm, "addressUser", editItem.name);
vm.$set(vm, "addressPhone", editItem.phone);
},
onSwtich() {
this.dialogVisible = true;
},
onCancel() {
this.dialogVisible = false;
},
onSelected(data) {
console.log(data);
this.selectData = data;
},
async onAddAddress() {
let vm = this;
if (!vm.selectData?.area?.code) {
vm.$message.error("请选择所在区域~");
return;
}
if (!vm.detailAddress) {
vm.$message.error("请输入详细地址~");
return;
}
if (!vm.addressUser) {
vm.$message.error("请输入收货人~");
return;
}
if (!IsPhone(vm.addressPhone)) {
vm.$message.error("请输入收货人手机号码~");
return;
}
let params = {
area: vm.selectData.area.value,
areaCode: vm.selectData.area.code,
city: vm.selectData.city.value,
cityCode: vm.selectData.city.code,
detailAddress: vm.detailAddress,
isDefault: vm.defaultAddress,
name: vm.addressUser,
phone: vm.addressPhone,
province: vm.selectData.province.value,
provinceCode: vm.selectData.province.code,
};
let res;
if (vm.getEditState) {
let editParams = Object.assign(vm.addressList[vm.editIndex], params);
res = await ApiPutAddress(editParams);
} else {
res = await ApiPostAddress(params);
}
if (!res.error) {
vm.$message.success("添加成功!");
vm.$set(vm.selectData.area, "value", "");
vm.$set(vm.selectData.city, "value", "");
vm.$set(vm.selectData.province, "value", "");
vm.$set(vm, "detailAddress", "");
vm.$set(vm, "defaultAddress", "");
vm.$set(vm, "addressUser", "");
vm.$set(vm, "addressPhone", "");
vm.$emit("onSaveSuccess");
vm.isEdit = false;
vm.getAddressData();
}
console.log(res);
},
onAddressItem(item) {
let vm = this;
vm.curAddressListItem = item;
vm.$emit("emitAddress", item);
vm.dialogVisible = false;
},
},
};
</script>
<style lang="scss" scoped>
.address {
@include layout-box;
min-height: 189px;
border: 1px solid #dddddd;
padding: 28px 34px 8px;
&__msg {
width: 776px;
&-line {
margin-bottom: 20px;
img {
width: 20px;
height: 24px;
margin-right: 14px;
}
&--type {
width: 70px;
font-size: 14px;
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
font-weight: 400;
color: #999999;
}
&--txt {
font-size: 14px;
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
font-weight: 400;
color: #333333;
}
/deep/.ui-button__yellow_panel {
width: 62px;
height: 30px;
color: #ff875b;
background: rgba(255, 135, 91, 0.1);
border-radius: 4px 4px 4px 4px;
margin-left: 54px;
}
.max-ipt {
width: 450px;
}
.min-ipt {
width: 164px;
margin-right: 50px;
/deep/.el-input__inner {
width: 164px;
height: 28px;
background: #ffffff;
border-radius: 2px;
border: 1px solid rgba(0, 0, 0, 0.15);
}
}
}
}
.hr {
width: 2px;
height: 107px;
background: #eeeeee;
}
&__operation {
flex: 1;
/deep/.ui-button__grey {
width: 114px;
font-size: 14px;
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
font-weight: 400;
color: #666666;
&:nth-child(1) {
margin-bottom: 30px;
}
}
.icon {
width: 18px;
height: 18px;
margin-right: 10px;
}
}
&__edit {
flex: 1;
&--btns {
margin-top: 30px;
/deep/.ui-button__grey {
width: 90px;
height: 30px;
font-size: 14px;
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
font-weight: 400;
color: #666666;
margin-right: 38px;
}
}
}
}
.address__list {
height: 265px;
overflow-y: auto;
//滚动条样式
overflow-y: auto;
scrollbar-width: none;
&::-webkit-scrollbar {
width: 4px;
}
/*定义滚动条轨道 内阴影+圆角*/
&::-webkit-scrollbar-track {
border-radius: 10px;
background-color: #fff;
}
/*定义滑块 内阴影+圆角*/
&::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: #eeeeee;
}
&-item {
width: 320px;
height: 120px;
border: 1px solid #dddddd;
margin-bottom: 24px;
cursor: pointer;
padding: 16px 20px;
> div {
margin-bottom: 10px;
}
&--detail {
@include ellipses(2);
}
&--label {
font-size: 14px;
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
font-weight: 400;
color: #999999;
}
}
&-active {
border: 1px solid #ff875b;
position: relative;
&::after {
content: "";
position: absolute;
right: 0;
bottom: 0;
width: 24px;
height: 24px;
background: url(@/assets/img/goods/active.png);
}
}
}
.dialog-footer {
/deep/.ui-button {
width: 150px;
height: 36px;
background: #ffffff;
border-radius: 2px 2px 2px 2px;
border: 1px solid #eeeeee;
font-size: 14px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400;
color: #000;
}
/deep/.ui-button__yellow_panel {
background: #ff875b;
color: #fff;
}
}
/deep/.distpicker-address-wrapper {
select {
width: 164px;
height: 28px;
background: #ffffff;
border-radius: 2px 2px 2px 2px;
border: 1px solid rgba(0, 0, 0, 0.15);
font-size: 14px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400;
color: #333333;
padding: 0;
}
}
.account {
width: 1000px;
}
</style>