Files
jurong_circle_front_app/pages/my/shippingAddress.vue
Sun_sun 091b655a0f 2025-10-20
收货地址完成
2025-10-20 10:33:19 +08:00

405 lines
9.7 KiB
Vue

<template>
<view class="shipping-container">
<u-navbar id="uNavbarId" back-text="收货地址" :back-text-style="navBarTitle"
:background="{background: 'transparent' }" :border-bottom="false" back-icon-color="#000" title-color="#000">
<template v-slot:right>
<view class="right-menu">
<view @click="handleManage">
{{isManage?'取消':'管理'}}
</view>
<view v-if="isManage" class="u-m-l-10 del-text" @click="showDelModel">
删除
</view>
<view class="u-m-l-10 add-text" @click="handleAdd">
新增地址
</view>
</view>
</template>
</u-navbar>
<scroll-view scroll-y="true" :style="'height:'+scrollHeight+'px'">
<view class="data-list">
<view class="data-item" v-for="item in dataList" @click="handleClick(item)">
<view class="item-text">
<view class="address u-m-b-18">
{{item.province_name + " " + item.city_name + " " + item.district_name}}
</view>
<view class="specific-address u-m-b-18">
{{item.detailed_address}}
</view>
<view class="info">
<div class="u-m-r-20">{{item.receiver_name}}</div>
<div class="u-m-r-20">{{item.receiver_phone}}</div>
<span v-if="item.is_default" class="u-m-r-10">默认</span>
<span class="u-m-r-10">{{item.label}}</span>
</view>
</view>
<view class="item-icon">
<image v-if="!isManage" @click="handleEdit(item)" style="width: 100%;height: 100%;"
src="/static/icon/Edit.png" mode="">
</image>
<template v-else>
<image v-if="!isIncludeId(item.id)" style="width: 100%;height: 100%;"
src="/static/icon/chose.png" mode=""></image>
<image v-else style="width: 100%;height: 100%;" src="/static/icon/chose-active.png" mode="">
</image>
</template>
</view>
</view>
</view>
</scroll-view>
<!-- 新增/修改 -->
<u-popup v-model="showForm" mode="bottom" length="60%" class="form-popup" @close="form={label:0}">
<view class="form">
<view class="form-item u-m-b-30">
<view class="item-title">
<image class="must-icon" src="/static/my/must.png" mode=""></image>
<u-input v-model="form.regionLabel" type="select" placeholder="请选择省市区" @click="openProvince" />
</view>
</view>
<view class="form-item">
<view class="item-title">
<image class="must-icon" src="/static/my/must.png" mode=""></image>详细地址与门牌号
</view>
<view class="item-value">
<u-input v-model="form.detailed_address" maxlength="30" placeholder="请输入详细地址与门牌号" type="text" />
</view>
</view>
<view class="form-item">
<view class="item-title">
<image class="must-icon" src="/static/my/must.png" mode=""></image>收货人名字
</view>
<view class="item-value">
<u-input v-model="form.recipient_name" maxlength="10" placeholder="请输入收货人名字" type="text" />
</view>
</view>
<view class="form-item">
<view class="item-title">
<image class="must-icon" src="/static/my/must.png" mode=""></image>手机号
</view>
<view class="item-value">
<u-input v-model="form.phone" maxlength="11" type="number" placeholder="请输入收货人手机号" />
</view>
</view>
<view class="form-item">
<view class="item-title">
标签
</view>
<view class="item-tag u-m-t-10">
<span :class="{active:form.label==0}" @click="handleChangeTag(0)"></span>
<span :class="{active:form.label==1}" @click="handleChangeTag(1)">公司</span>
<span :class="{active:form.label==2}" @click="handleChangeTag(2)">学校</span>
</view>
</view>
<view class="form-item">
<view class="item-title">
<span class="u-m-r-10">是否设置为默认地址</span><u-checkbox v-model="form.is_default"
:disabled="false"></u-checkbox>
</view>
</view>
</view>
<u-button class="submit" hover-class="none" @click="handleSubmit">确定</u-button>
</u-popup>
<!-- 省市区 -->
<u-select v-model="showRegitionPicker" :list="regionOptions" mode="mutil-column-auto" label-name="label"
value-name="code" child-name="children" @confirm="handleRegion"></u-select>
<!-- 确认是否删除 -->
<u-modal v-model="showDel" content="是否删除选中的地址" :show-cancel-button="true" @confirm="handleDel"></u-modal>
<!-- 提示 -->
<u-toast ref="msgRef" />
</view>
</template>
<script setup>
import {
computed,
getCurrentInstance,
onMounted,
ref
} from 'vue'
import {
addressAPI
} from '../../api/address'
import {
commonAPI
} from '../../api/common'
const navBarTitle = {
fontWeight: '510',
fontStyle: 'Medium',
fontSize: '40rpx',
lineHeight: '52px'
}
const msgRef = ref()
const isManage = ref(false)
const showDel = ref(false)
const showForm = ref(false)
const showRegitionPicker = ref(false)
const form = ref({
label: 0
})
const handleAdd = () => {
showForm.value = true
}
const handleEdit = (item) => {
let data = {
id: item.id,
regionLabel: item.province_name + '/' + item.district_name + '/' + item.city_name,
province_code: item.province,
city_code: item.city,
district_code: item.district,
detailed_address: item.detailed_address,
recipient_name: item.receiver_name,
phone: item.receiver_phone,
is_default: item.is_default
}
if (item.label == '家') {
data.label = 0
}
if (item.label == '公司') {
data.label = 1
}
if (item.label == '学校') {
data.label = 2
}
form.value = data
showForm.value = true
}
const handleManage = () => {
if (isManage.value) {
ids.value = []
}
isManage.value = !isManage.value
}
const showDelModel = () => {
showDel.value = true
}
const handleDel = async () => {
// TODO 删除
for (var i = 0; i < ids.value.length; i++) {
await addressAPI.delAddress(ids.value[i])
}
msgRef.value.show({
title: '删除成功',
type: 'success'
})
isManage.value = false
ids.value = []
loadData()
}
// 打开省市区选择
const openProvince = () => {
showRegitionPicker.value = true
}
// 选择省市区
const handleRegion = (e) => {
form.value.regionLabel = e[0].label + "/" + e[1].label + "/" + e[2].label
form.value.province_code = e[0].value
form.value.city_code = e[1].value
form.value.district_code = e[2].value
}
const handleChangeTag = (val) => {
form.value.label = val
}
// 确认提交
const handleSubmit = () => {
if (form.value.id != null) {
addressAPI.editAddress(form.value).then(res => {
if (res.success) {
msgRef.value.show({
title: '修改成功',
type: 'success'
})
showForm.value = false
loadData()
}
})
} else {
addressAPI.addAddress(form.value).then(res => {
if (res.success) {
msgRef.value.show({
title: '添加成功',
type: 'success'
})
showForm.value = false
loadData()
}
})
}
}
const scrollHeight = ref(0)
const instance = getCurrentInstance();
const loadHeight = () => {
uni.getSystemInfo({
success(res) {
let screenHeight = res.screenHeight
uni.createSelectorQuery().in(instance.proxy).select("#uNavbarId").boundingClientRect((
data) => {
scrollHeight.value = screenHeight - data.height
}).exec()
}
})
}
const dataList = ref([])
const regionOptions = ref([])
const loadData = () => {
addressAPI.getList().then((res) => {
dataList.value = res.data
})
commonAPI.getRegion().then(res => {
regionOptions.value = res.data
})
}
const ids = ref([])
const handleClick = (item) => {
if (isManage.value) { // 开始管理
ids.value.push(item.id)
}
}
const isIncludeId = (id) => {
return ids.value.includes(id);
}
onMounted(() => {
loadHeight()
loadData()
})
</script>
<style scoped lang="scss">
.shipping-container {
width: 100%;
height: 100vh;
background: #E5ECFD;
.right-menu {
display: flex;
margin-right: 24rpx;
font-family: Work Sans;
font-weight: 500;
font-style: Medium;
font-size: 32rpx;
leading-trim: NONE;
line-height: 100%;
letter-spacing: -2%;
.del-text {
color: red;
}
.add-text {
color: #305DEF;
}
}
.data-list {
.data-item {
width: 100%;
display: flex;
justify-content: space-between;
padding: 28rpx 22rpx;
background: #F5F8FF;
margin-bottom: 4rpx;
align-items: center;
.item-text {
font-weight: 400;
line-height: 100%;
.address {
font-size: 20rpx;
color: #7B7E8F;
}
.specific-address {
font-size: 26rpx;
}
.info {
font-size: 24rpx;
display: flex;
align-items: center;
span {
padding: 2rpx 8rpx;
font-size: 16rpx;
background: #DADDEA;
color: #305DEF;
border-radius: 2rpx;
}
}
}
.item-icon {
width: 40rpx;
height: 40rpx;
}
}
}
.form-popup {
.form {
padding: 30rpx 28rpx;
.form-item {
margin-bottom: 20rpx;
line-height: 100%;
.item-title {
display: flex;
align-items: center;
font-weight: 400;
font-size: 24rpx;
.must-icon {
width: 24rpx;
height: 24rpx;
}
}
.item-value {}
.item-tag {
font-weight: 400;
font-size: 26rpx;
line-height: 100%;
letter-spacing: -2%;
span {
padding: 0 20rpx;
background: #D9D9D9;
border-radius: 12rpx;
margin-left: 16rpx;
}
.active {
background: #BFCEFF;
color: #305DEF;
}
}
}
}
.submit {
position: absolute;
bottom: 10rpx;
width: 248rpx;
left: 0;
right: 0;
text-align: center;
background: #7B99FF;
border: none;
border-radius: 24rpx;
color: #fff;
}
}
}
</style>