Browse Source

地址模块接口

template
liruiqiang 2 months ago
parent
commit
0474e99b7a
  1. 170
      src/pagesMember/address-form/address-form.vue
  2. 93
      src/pagesMember/address/address.vue
  3. 59
      src/services/address.ts
  4. 16
      src/stores/modules/address.ts
  5. 25
      src/types/address.d.ts

170
src/pagesMember/address-form/address-form.vue

@ -1,37 +1,76 @@
<template>
<view class="content">
<form>
<uni-forms :rules="rules" :model="form" ref="formRef">
<!-- 表单内容 -->
<view class="form-item">
<uni-forms-item name="receiver" class="form-item">
<text class="label">收货人</text>
<input class="input" placeholder="请填写收货人姓名" value="" />
</view>
<view class="form-item">
<input class="input" placeholder="请填写收货人姓名" v-model="form.receiver" />
</uni-forms-item>
<uni-forms-item name="contact" class="form-item">
<text class="label">手机号码</text>
<input class="input" placeholder="请填写收货人手机号码" value="" />
</view>
<view class="form-item">
<input
class="input"
placeholder="请填写收货人手机号码"
:maxlength="11"
v-model="form.contact"
/>
</uni-forms-item>
<uni-forms-item name="countyCode" class="form-item">
<text class="label">所在地区</text>
<picker class="picker" mode="region" value="">
<view v-if="false">广东省 广州市 天河区</view>
<!-- #ifdef MP-WEIXIN -->
<picker
@change="onRegionChange"
class="picker"
mode="region"
:value="form.fullLocation.split(' ')"
>
<view v-if="form.fullLocation">{{ form.fullLocation }}</view>
<view v-else class="placeholder">请选择省//()</view>
</picker>
</view>
<view class="form-item">
<!-- #endif -->
<!-- #ifdef H5 || APP-PLUS -->
<uni-data-picker
placeholder="请选择地址"
popup-title="请选择城市"
collection="opendb-city-china"
field="code as value, name as text"
orderby="value asc"
:step-searh="true"
self-field="code"
parent-field="parent_code"
@change="onCityChange"
:clear-icon="false"
v-model="form.countyCode"
/>
<!-- #endif -->
</uni-forms-item>
<uni-forms-item name="address" class="form-item">
<text class="label">详细地址</text>
<input class="input" placeholder="街道、楼牌号等信息" value="" />
</view>
<input class="input" placeholder="街道、楼牌号等信息" v-model="form.address" />
</uni-forms-item>
<view class="form-item">
<label class="label">设为默认地址</label>
<switch class="switch" color="#27ba9b" :checked="true" />
<switch
@change="onSwitchChange"
class="switch"
color="#27ba9b"
:checked="form.isDefault === 1"
/>
</view>
</form>
</uni-forms>
</view>
<!-- 提交按钮 -->
<button class="button">保存并使用</button>
<button @tap="onSubmit" class="button">保存并使用</button>
</template>
<script setup lang="ts">
import {
getMemberAddressByIdAPI,
postMemberAddressAPI,
putMemberAddressByIdAPI,
} from '@/services/address'
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'
//
@ -51,11 +90,106 @@ const query = defineProps<{
id?: string
}>()
//
const getMemberAddressByIdData = async () => {
if (query.id) {
//
const res = await getMemberAddressByIdAPI(query.id)
//
Object.assign(form.value, res.result)
}
}
//
onLoad(() => {
getMemberAddressByIdData()
})
//
uni.setNavigationBarTitle({ title: query.id ? '修改地址' : '新建地址' })
//
const onRegionChange: UniHelper.RegionPickerOnChange = (ev) => {
// ()
form.value.fullLocation = ev.detail.value.join(' ')
// ()
const [provinceCode, cityCode, countyCode] = ev.detail.code!
// form.value.provinceCode = provinceCode
Object.assign(form.value, { provinceCode, cityCode, countyCode })
}
//
const onSwitchChange: UniHelper.SwitchOnChange = (ev) => {
form.value.isDefault = ev.detail.value ? 1 : 0
}
//
const rules: UniHelper.UniFormsRules = {
receiver: {
rules: [{ required: true, errorMessage: '请输入收货人姓名' }],
},
contact: {
rules: [
{ required: true, errorMessage: '请输入联系方式' },
{ pattern: /^1[3-9]\d{9}$/, errorMessage: '手机号格式不正确' },
],
},
countyCode: {
rules: [{ required: true, errorMessage: '请选择所在地区' }],
},
address: {
rules: [{ required: true, errorMessage: '请选择详细地址' }],
},
}
//
const formRef = ref<UniHelper.UniFormsInstance>()
//
const onSubmit = async () => {
try {
//
await formRef.value?.validate?.()
//
if (query.id) {
//
await putMemberAddressByIdAPI(query.id, form.value)
} else {
//
await postMemberAddressAPI(form.value)
}
//
uni.showToast({ icon: 'success', title: query.id ? '修改成功' : '添加成功' })
//
setTimeout(() => {
uni.navigateBack()
}, 400)
} catch (error) {
uni.showToast({ icon: 'error', title: '请填写完整信息' })
}
}
// #ifdef H5 || APP-PLUS
const onCityChange: UniHelper.UniDataPickerOnChange = (ev) => {
//
const [province, city, county] = ev.detail.value
// code
Object.assign(form.value, {
provinceCode: province.value,
cityCode: city.value,
countyCode: county.value,
})
}
// #endif
</script>
<style lang="scss">
// uni-data-picker
:deep(.selected-area) {
flex: 0 1 auto;
height: auto;
}
page {
background-color: #f4f4f4;
}
@ -71,7 +205,7 @@ page {
display: flex;
align-items: center;
min-height: 96rpx;
padding: 25rpx 10rpx 40rpx;
padding: 25rpx 10rpx;
background-color: #fff;
font-size: 28rpx;
border-bottom: 1rpx solid #ddd;

93
src/pagesMember/address/address.vue

@ -1,46 +1,35 @@
<template>
<view class="viewport">
<!-- 地址列表 -->
<scroll-view class="scroll-view" scroll-y>
<view v-if="true" class="address">
<view class="address-list">
<scroll-view enable-back-to-top class="scroll-view" scroll-y>
<view v-if="addressList.length" class="address">
<uni-swipe-action class="address-list">
<!-- 收货地址项 -->
<view class="item">
<view class="item-content">
<uni-swipe-action-item class="item" v-for="item in addressList" :key="item.id">
<view class="item-content" @tap="onChangeAddress(item)">
<view class="user">
黑马小王子
<text class="contact">13111111111</text>
<text v-if="true" class="badge">默认</text>
{{ item.receiver }}
<text class="contact">{{ item.contact }}</text>
<text v-if="item.isDefault" class="badge">默认</text>
</view>
<view class="locate">广东省 广州市 天河区 黑马程序员</view>
<view class="locate">{{ item.fullLocation }} {{ item.address }}</view>
<!-- H5 端需添加 .prevent 阻止链接的默认行为 -->
<navigator
class="edit"
hover-class="none"
:url="`/pagesMember/address-form/address-form?id=1`"
:url="`/pagesMember/address-form/address-form?id=${item.id}`"
@tap.stop="() => {}"
@tap.prevent="() => {}"
>
修改
</navigator>
</view>
</view>
<!-- 收货地址项 -->
<view class="item">
<view class="item-content">
<view class="user">
黑马小公主
<text class="contact">13222222222</text>
<text v-if="false" class="badge">默认</text>
</view>
<view class="locate">北京市 北京市 顺义区 黑马程序员</view>
<navigator
class="edit"
hover-class="none"
:url="`/pagesMember/address-form/address-form?id=2`"
>
修改
</navigator>
</view>
</view>
</view>
<!-- 右侧插槽 -->
<template #right>
<button @tap="onDeleteAddress(item.id)" class="delete-button">删除</button>
</template>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
<view v-else class="blank">暂无收货地址</view>
</scroll-view>
@ -54,7 +43,49 @@
</template>
<script setup lang="ts">
//
import { deleteMemberAddressByIdAPI, getMemberAddressAPI } from '@/services/address'
import { useAddressStore } from '@/stores/modules/address'
import type { AddressItem } from '@/types/address'
import { onShow } from '@dcloudio/uni-app'
import { ref } from 'vue'
//
const addressList = ref<AddressItem[]>([])
const getMemberAddressData = async () => {
const res = await getMemberAddressAPI()
addressList.value = res.result
}
// ()
onShow(() => {
getMemberAddressData()
})
//
const onDeleteAddress = (id: string) => {
//
uni.showModal({
content: '删除地址?',
confirmColor: '#27BA9B',
success: async (res) => {
if (res.confirm) {
// id
await deleteMemberAddressByIdAPI(id)
//
getMemberAddressData()
}
},
})
}
//
const onChangeAddress = (item: AddressItem) => {
//
const addressStore = useAddressStore()
addressStore.changeSelectedAddress(item)
//
uni.navigateBack()
}
</script>
<style lang="scss">

59
src/services/address.ts

@ -0,0 +1,59 @@
import type { AddressItem, AddressParams } from '@/types/address'
import { http } from '@/utils/http'
/**
*
* @param data
*/
export const postMemberAddressAPI = (data: AddressParams) => {
return http({
method: 'POST',
url: '/member/address',
data,
})
}
/**
*
*/
export const getMemberAddressAPI = () => {
return http<AddressItem[]>({
method: 'GET',
url: '/member/address',
})
}
/**
*
* @param id id()
*/
export const getMemberAddressByIdAPI = (id: string) => {
return http<AddressItem>({
method: 'GET',
url: `/member/address/${id}`,
})
}
/**
*
* @param id id()
* @param data ()
*/
export const putMemberAddressByIdAPI = (id: string, data: AddressParams) => {
return http({
method: 'PUT',
url: `/member/address/${id}`,
data,
})
}
/**
*
* @param id id()
*/
export const deleteMemberAddressByIdAPI = (id: string) => {
return http({
method: 'DELETE',
url: `/member/address/${id}`,
})
}

16
src/stores/modules/address.ts

@ -0,0 +1,16 @@
import type { AddressItem } from '@/types/address'
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useAddressStore = defineStore('address', () => {
const selectedAddress = ref<AddressItem>()
const changeSelectedAddress = (val: AddressItem) => {
selectedAddress.value = val
}
return {
selectedAddress,
changeSelectedAddress,
}
})

25
src/types/address.d.ts

@ -0,0 +1,25 @@
/** 添加收货地址: 请求参数 */
export type AddressParams = {
/** 收货人姓名 */
receiver: string
/** 联系方式 */
contact: string
/** 省份编码 */
provinceCode: string
/** 城市编码 */
cityCode: string
/** 区/县编码 */
countyCode: string
/** 详细地址 */
address: string
/** 默认地址,1为是,0为否 */
isDefault: number
}
/** 收货地址项 */
export type AddressItem = AddressParams & {
/** 收货地址 id */
id: string
/** 省市区 */
fullLocation: string
}
Loading…
Cancel
Save