feat: 收货地址开发完成

This commit is contained in:
zc 2025-12-02 14:37:25 +08:00
parent 9dfa9fd1a2
commit ba07f22b6a
5 changed files with 93 additions and 199 deletions

View File

@ -43,7 +43,7 @@ export function receipt(orderId, data) {
return request.post(api.receipt, { orderId, ...data }) return request.post(api.receipt, { orderId, ...data })
} }
// 获取地理位置 // 获取买家地址
export const apiGetAddressList = (data) => { export const apiGetAddressList = (data) => {
return httpRequest.post( return httpRequest.post(
`${baseUrl}/buyer/address/list`, `${baseUrl}/buyer/address/list`,
@ -51,6 +51,14 @@ export const apiGetAddressList = (data) => {
); );
} }
// 新增或更新买家地址
export const apiInsertOrUpdateAddress = (data) => {
return httpRequest.post(
`${baseUrl}/buyer/address/insertOrUpdate`,
data
);
}
// 下单 // 下单
export const apiOrderAdd = (data) => { export const apiOrderAdd = (data) => {
return httpRequest.post( return httpRequest.post(

View File

@ -62,14 +62,15 @@
}, },
watch: { watch: {
// //
modelValue(val) { modelValue: { handler(val) {
// //
this.valueText = val.map(item => item.label).join('/') this.valueText = val.map(item => item.label).join('/')
this.setDefaultValue(val) this.setDefaultValue(val)
// u-form-item // u-form-item
// this.dispatch('u-form-item', 'on-form-change', val) // this.dispatch('u-form-item', 'on-form-change', val)
}, },
}, immediate: true
}},
created() { created() {
// () // ()
this.getTreeDataSync() this.getTreeDataSync()

View File

@ -5,11 +5,11 @@
<!-- 表单组件 --> <!-- 表单组件 -->
<view class="form-wrapper"> <view class="form-wrapper">
<u-form :model="form" ref="uForm" label-width="140rpx"> <u-form :model="form" ref="uForm" label-width="140rpx">
<u-form-item label="姓名" prop="name"> <u-form-item label="姓名" prop="buyerName">
<u-input v-model="form.name" placeholder="请输入收货人姓名" /> <u-input v-model="form.buyerName" placeholder="请输入收货人姓名" />
</u-form-item> </u-form-item>
<u-form-item label="电话" prop="phone"> <u-form-item label="电话" prop="buyerPhone">
<u-input v-model="form.phone" placeholder="请输入收货人手机号" /> <u-input v-model="form.buyerPhone" placeholder="请输入收货人手机号" />
</u-form-item> </u-form-item>
<u-form-item label="地区" prop="region"> <u-form-item label="地区" prop="region">
<select-region ref="sRegion" v-model="form.region" /> <select-region ref="sRegion" v-model="form.region" />
@ -34,27 +34,25 @@
<script> <script>
import SelectRegion from '@/components/select-region/select-region' import SelectRegion from '@/components/select-region/select-region'
import { isMobile } from '@/utils/verify' import { isMobile } from '@/utils/verify'
import * as AddressApi from '@/api/address' import * as OrderApi from '@/api/order'
// //
const rules = { const rules = {
name: [{ buyerName: [{
required: true, required: true,
message: '请输入姓名', message: '请输入姓名',
trigger: ['blur', 'change'] trigger: ['blur', 'change']
}], }],
phone: [{ buyerPhone: [{
required: true, required: true,
message: '请输入手机号', message: '请输入手机号',
trigger: ['blur', 'change'] trigger: ['blur', 'change']
}, { }, {
// //
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
// truefalse
return isMobile(value) return isMobile(value)
}, },
message: '手机号码不正确', message: '手机号码不正确',
// blurchange
trigger: ['blur'], trigger: ['blur'],
}], }],
region: [{ region: [{
@ -77,23 +75,16 @@
data() { data() {
return { return {
form: { form: {
content: '', buyerName: '',
name: '', buyerPhone: '',
phone: '',
region: [], region: [],
detail: '' detail: ''
}, },
rules, rules,
//
disabled: false disabled: false
} }
}, },
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {}, onLoad(options) {},
// onReadyonLoad // onReadyonLoad
onReady() { onReady() {
this.$refs.uForm.setRules(this.rules) this.$refs.uForm.setRules(this.rules)
@ -109,8 +100,8 @@
uni.chooseAddress({ uni.chooseAddress({
success(res) { success(res) {
const names = $refs.sRegion.getOptionItemByNames(res) const names = $refs.sRegion.getOptionItemByNames(res)
form.name = res.userName form.buyerName = res.userName
form.phone = res.telNumber form.buyerPhone = res.telNumber
form.detail = res.detailInfo form.detail = res.detailInfo
form.region = names.length > 0 ? names : [] form.region = names.length > 0 ? names : []
}, },
@ -124,33 +115,6 @@
}, },
// #endif // #endif
//
createFormData(detail) {
const { form } = this
form.name = detail.name
form.phone = detail.phone
form.detail = detail.detail
form.region = this.createRegion(detail)
},
// (select-region)
createRegion(detail) {
if (detail.province_id == 0 || detail.city_id == 0 || detail.region_id == 0) {
this.$toast('很抱歉,地区未能识别请手动选择', 2000)
return []
}
return [{
label: detail.region.province,
value: detail.province_id
}, {
label: detail.region.city,
value: detail.city_id
}, {
label: detail.region.region,
value: detail.region_id
}]
},
// //
handleSubmit() { handleSubmit() {
const app = this const app = this
@ -160,9 +124,13 @@
app.$refs.uForm.validate(valid => { app.$refs.uForm.validate(valid => {
if (valid) { if (valid) {
app.disabled = true app.disabled = true
AddressApi.add(app.form) const data = { ...app.form }
data.province = data.region[0].label
data.city = data.region[1].label
data.district = data.region[2].label
OrderApi.apiInsertOrUpdateAddress(data)
.then(result => { .then(result => {
app.$toast(result.message) app.$toast(result.msg)
uni.navigateBack() uni.navigateBack()
}) })
.finally(() => app.disabled = false) .finally(() => app.disabled = false)

View File

@ -3,8 +3,8 @@
<view class="addres-list"> <view class="addres-list">
<view class="address-item" v-for="(item, index) in list" :key="index"> <view class="address-item" v-for="(item, index) in list" :key="index">
<view class="contacts"> <view class="contacts">
<text class="name">{{ item.name }}</text> <text class="name">{{ item.buyerName }}</text>
<text class="phone">{{ item.phone }}</text> <text class="phone">{{ item.buyerPhone }}</text>
</view> </view>
<view class="address"> <view class="address">
<text class="region" v-for="(region, idx) in item.region" :key="idx">{{ region }}</text> <text class="region" v-for="(region, idx) in item.region" :key="idx">{{ region }}</text>
@ -14,18 +14,18 @@
<view class="item-option"> <view class="item-option">
<view class="_left"> <view class="_left">
<view class="item-radio"> <view class="item-radio">
<u-radio-group v-model="defaultId" @change="handleSetDefault(item.address_id)"> <u-radio-group v-model="defaultId" @change="handleSetDefault(item.id)">
<u-radio :name="item.address_id" :active-color="appTheme.mainBg">{{ item.address_id == defaultId ? '默认' : '选择' }}</u-radio> <u-radio :name="item.id" :active-color="appTheme.mainBg">默认</u-radio>
</u-radio-group> </u-radio-group>
</view> </view>
</view> </view>
<view class="_right"> <view class="_right">
<view class="events"> <view class="events">
<view class="event-item" @click="handleUpdate(item.address_id)"> <view class="event-item" @click="handleUpdate(item)">
<text class="iconfont icon-edit"></text> <text class="iconfont icon-edit"></text>
<text class="title">编辑</text> <text class="title">编辑</text>
</view> </view>
<view class="event-item" @click="handleRemove(item.address_id)"> <view class="event-item" @click="handleRemove(item.id)">
<text class="iconfont icon-delete"></text> <text class="iconfont icon-delete"></text>
<text class="title">删除</text> <text class="title">删除</text>
</view> </view>
@ -46,6 +46,7 @@
<script> <script>
import * as AddressApi from '@/api/address' import * as AddressApi from '@/api/address'
import * as OrderApi from '@/api/order'
import Empty from '@/components/empty' import Empty from '@/components/empty'
export default { export default {
@ -54,100 +55,52 @@
}, },
data() { data() {
return { return {
//
options: {}, options: {},
//
isLoading: true, isLoading: true,
//
list: [], list: [],
//
defaultId: null defaultId: null
} }
}, },
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) { onLoad(options) {
// //
this.options = options this.options = options
}, },
/**
* 生命周期函数--监听页面显示
*/
onShow() { onShow() {
//
this.getPageData() this.getPageData()
}, },
methods: { methods: {
//
getPageData() { getPageData() {
const app = this const app = this
app.isLoading = true app.isLoading = true
Promise.all([app.getDefaultId(), app.getAddressList()]) OrderApi.apiGetAddressList({}).then(res => {
.then(() => { const rows = res.data.rows.map(item => {
// return {
app.onReorder() ...item,
region: [item.province, item.city, item.district]
}
});
const defaultItemIndex = rows.findIndex(item => item.status === 'default');
if (defaultItemIndex !== -1) {
const [defaultItem] = rows.splice(defaultItemIndex, 1);
app.defaultId = defaultItem.id;
app.list = [defaultItem, ...rows];
} else {
app.list = rows;
}
}) })
.finally(() => app.isLoading = false) .finally(() => app.isLoading = false)
}, },
//
//
getAddressList() {
const app = this
return new Promise((resolve, reject) => {
AddressApi.list()
.then(result => {
app.list = result.data.list
resolve(result)
})
.catch(reject)
})
},
//
getDefaultId() {
return new Promise((resolve, reject) => {
const app = this
AddressApi.defaultId()
.then(result => {
app.defaultId = result.data.defaultId
resolve(result)
})
.catch(reject)
})
},
//
onReorder() {
const app = this
app.list.sort(item => {
return item.address_id == app.defaultId ? -1 : 1
})
},
/**
* 添加新地址
*/
handleCreate() { handleCreate() {
this.$navTo('pages/address/create') this.$navTo('pages/address/create')
}, },
//
/** handleUpdate(item) {
* 编辑地址 const data = encodeURIComponent(JSON.stringify(item))
* @param {int} addressId 收货地址ID this.$navTo('pages/address/update', { data })
*/
handleUpdate(addressId) {
this.$navTo('pages/address/update', { addressId })
}, },
//
/**
* 删除收货地址
* @param {int} addressId 收货地址ID
*/
handleRemove(addressId) { handleRemove(addressId) {
const app = this const app = this
uni.showModal({ uni.showModal({
@ -158,28 +111,19 @@
} }
}); });
}, },
//
/**
* 确认删除收货地址
* @param {int} addressId 收货地址ID
*/
onRemove(addressId) { onRemove(addressId) {
const app = this const app = this
AddressApi.remove(addressId) OrderApi.apiInsertOrUpdateAddress({ id: addressId, status: 'deleted' })
.then(result => { .then(result => {
app.getPageData() app.getPageData()
}) })
}, },
//
/**
* 设置为默认地址
* @param {Object} addressId
*/
handleSetDefault(addressId) { handleSetDefault(addressId) {
const app = this const app = this
AddressApi.setDefault(addressId) OrderApi.apiInsertOrUpdateAddress({ id: addressId, status: 'default' })
.then(result => { .then(() => {
// app.defaultId = addressId
app.options.from === 'checkout' && uni.navigateBack() app.options.from === 'checkout' && uni.navigateBack()
}) })
} }

View File

@ -5,11 +5,11 @@
<!-- 表单组件 --> <!-- 表单组件 -->
<view class="form-wrapper"> <view class="form-wrapper">
<u-form :model="form" ref="uForm" label-width="140rpx"> <u-form :model="form" ref="uForm" label-width="140rpx">
<u-form-item label="姓名" prop="name"> <u-form-item label="姓名" prop="buyerName">
<u-input v-model="form.name" placeholder="请输入收货人姓名" /> <u-input v-model="form.buyerName" placeholder="请输入收货人姓名" />
</u-form-item> </u-form-item>
<u-form-item label="电话" prop="phone"> <u-form-item label="电话" prop="buyerPhone">
<u-input v-model="form.phone" placeholder="请输入收货人手机号" /> <u-input v-model="form.buyerPhone" placeholder="请输入收货人手机号" />
</u-form-item> </u-form-item>
<u-form-item label="地区" prop="region"> <u-form-item label="地区" prop="region">
<select-region ref="sRegion" v-model="form.region" /> <select-region ref="sRegion" v-model="form.region" />
@ -35,15 +35,16 @@
import SelectRegion from '@/components/select-region/select-region' import SelectRegion from '@/components/select-region/select-region'
import { isMobile } from '@/utils/verify' import { isMobile } from '@/utils/verify'
import * as AddressApi from '@/api/address' import * as AddressApi from '@/api/address'
import * as OrderApi from '@/api/order'
// //
const rules = { const rules = {
name: [{ buyerName: [{
required: true, required: true,
message: '请输入姓名', message: '请输入姓名',
trigger: ['blur', 'change'] trigger: ['blur', 'change']
}], }],
phone: [{ buyerPhone: [{
required: true, required: true,
message: '请输入手机号', message: '请输入手机号',
trigger: ['blur', 'change'] trigger: ['blur', 'change']
@ -77,49 +78,25 @@
data() { data() {
return { return {
form: { form: {
content: '', buyerName: '',
name: '', buyerPhone: '',
phone: '',
region: [], region: [],
detail: '' detail: ''
}, },
rules, rules,
//
isLoading: true, isLoading: true,
// disabled: false
disabled: false,
// ID
addressId: null
} }
}, },
onLoad({ data }) {
/** data = JSON.parse(decodeURIComponent(data))
* 生命周期函数--监听页面加载 this.createFormData(data)
*/
onLoad({ addressId }) {
// ID
this.addressId = addressId
//
this.getDetail()
}, },
// onReadyonLoad
onReady() { onReady() {
this.$refs.uForm.setRules(this.rules) this.$refs.uForm.setRules(this.rules) // onReadyonLoad
}, },
methods: { methods: {
//
getDetail() {
const app = this
AddressApi.detail(app.addressId)
.then(result => {
const detail = result.data.detail
app.createFormData(detail)
})
},
// //
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
chooseAddress() { chooseAddress() {
@ -127,8 +104,8 @@
uni.chooseAddress({ uni.chooseAddress({
success(res) { success(res) {
const names = $refs.sRegion.getOptionItemByNames(res) const names = $refs.sRegion.getOptionItemByNames(res)
form.name = res.userName form.buyerName = res.userName
form.phone = res.telNumber form.buyerPhone = res.telNumber
form.detail = res.detailInfo form.detail = res.detailInfo
form.region = names.length > 0 ? names : [] form.region = names.length > 0 ? names : []
}, },
@ -139,34 +116,27 @@
}) })
}, },
// #endif // #endif
// //
createFormData(detail) { createFormData(detail) {
const { form } = this const { form } = this
form.name = detail.name form.buyerName = detail.buyerName
form.phone = detail.phone form.buyerPhone = detail.buyerPhone
form.detail = detail.detail form.detail = detail.detail
form.region = this.createRegion(detail) form.region = this.createRegion(detail)
}, },
// (select-region) // (select-region)
createRegion(detail) { createRegion(detail) {
if (detail.province_id == 0 || detail.city_id == 0 || detail.region_id == 0) {
this.$toast('很抱歉,地区未能识别请手动选择', 2000)
return []
}
return [{ return [{
label: detail.region.province, label: detail.province,
value: detail.province_id value: NaN
}, { }, {
label: detail.region.city, label: detail.city,
value: detail.city_id value: NaN
}, { }, {
label: detail.region.region, label: detail.district,
value: detail.region_id value: NaN
}] }]
}, },
// //
handleSubmit() { handleSubmit() {
const app = this const app = this
@ -176,16 +146,19 @@
app.$refs.uForm.validate(valid => { app.$refs.uForm.validate(valid => {
if (valid) { if (valid) {
app.disabled = true app.disabled = true
AddressApi.edit(app.addressId, app.form) const data = { ...app.form }
data.province = data.region[0].label
data.city = data.region[1].label
data.district = data.region[2].label
OrderApi.apiInsertOrUpdateAddress(data)
.then(result => { .then(result => {
app.$toast(result.message) app.$toast(result.msg)
uni.navigateBack() uni.navigateBack()
}) })
.finally(() => app.disabled = false) .finally(() => app.disabled = false)
} }
}) })
} }
} }
} }
</script> </script>