前言

本教程是基于 “apifm-wxapi” 模块,教你快速实现小程序开发,所以你可能需要先了解以下知识点:

《创建 HelloWorld 项目》
《使用 “apifm-wxapi” 快速开发小程序》
《免费注册开通后台,获得专属域名》

本案例中,部分功能,需要用户登录后才能操作,也就是说需要 token 授权,请先了解:

《微信小程序登录获取openid及三方token》

功能介绍

商城类小程序开发必备模块,可让用户填写并管理自己的多个收货地址,方便在下单的时候直接选择某个地址作为订单的配送地址

启用模块

登录 “第一步” 注册的后台,左侧菜单 —> 工厂设置 —> 模块管理

找到并启用下述模块:

收货地址管理

开后该模块后,你将可以在后台管理用户的收货地址:

快递/收货地址管理 - 图1

apifm-wxapi 方法说明

获取所有的收货地址

  1. WXAPI.queryAddress(token)

添加收货地址

  1. WXAPI.addAddress(Object object)

你也可以结合小程序自带的读取收货地址接口,实现快速添加收货地址功能

更新收货地址

  1. WXAPI.updateAddress(Object object)

获取默认的地址

  1. WXAPI.defaultAddress(token)

读取地址详细

  1. WXAPI.addressDetail(token, id)

删除收货地址

  1. WXAPI.deleteAddress(token, id)

小程序开发

效果截图

快递/收货地址管理 - 图2

快递/收货地址管理 - 图3

小程序代码

收货地址管理

  1. <view class="page">
  2. <view class="page__bd">
  3. <view wx:for="{{ addressList }}" wx:key="*this" class="weui-panel">
  4. <view class="weui-panel__hd"> {{ item.linkMan }} </view>
  5. <view class="weui-panel__bd">
  6. <view class="weui-media-box weui-media-box_text">
  7. <view class="weui-media-box__title weui-media-box__title_in-text">
  8. {{ item.mobile }}
  9. </view>
  10. <view class="weui-media-box__desc">
  11. {{ item.provinceStr }}{{ item.cityStr }}{{ item.areaStr }}{{ item.address }}
  12. </view>
  13. <view class="weui-media-box__info" style="margin-top: 0px;">
  14. <view class="button-sp-area">
  15. <button class="weui-btn mini-btn" type="default" size="mini" bindtap="addressDetail" data-id="{{ item.id }}">详情</button>
  16. <button class="weui-btn mini-btn marginL" type="primary" size="mini" bindtap="updateAddress" data-id="{{ item.id }}">编辑</button>
  17. <button class="weui-btn mini-btn marginL" type="warn" size="mini" bindtap="deleteAddress" data-id="{{ item.id }}">删除</button>
  18. </view>
  19. </view>
  20. </view>
  21. </view>
  22. </view>
  23. </view>
  24. </view>
  25. <button class="addAddress" type="default" bindtap="addAddress">添加新的收货地址</button>
  26. <button class="addAddress" type="primary" bindtap="defaultAddress">读取默认地址</button>
  1. const WXAPI = require('apifm-wxapi')
  2. Page({
  3. data: {
  4. addressList: undefined
  5. },
  6. onLoad: function (options) {
  7. },
  8. onShow: function () {
  9. const loginToken = wx.getStorageSync('loginToken')
  10. if (!loginToken) {
  11. wx.showToast({
  12. title: '请先登录',
  13. icon: 'none'
  14. })
  15. this.goRegist()
  16. return
  17. }
  18. WXAPI.queryAddress(loginToken.token).then(res => {
  19. console.log(res)
  20. if(res.code == 0){
  21. this.setData({
  22. addressList: res.data
  23. })
  24. }
  25. })
  26. },
  27. goRegist() {
  28. wx.navigateTo({
  29. url: '/pages/auth/index'
  30. })
  31. },
  32. addAddress() {
  33. wx.navigateTo({
  34. url: '/pages/shipping-address/add'
  35. })
  36. },
  37. addressDetail(e){
  38. const id = e.currentTarget.dataset.id
  39. const loginToken = wx.getStorageSync('loginToken')
  40. WXAPI.addressDetail(loginToken.token, id).then(res => {
  41. console.log(res)
  42. if (res.code == 0) {
  43. wx.showToast({
  44. title: '查看控制台',
  45. icon: 'success'
  46. })
  47. } else {
  48. wx.showToast({
  49. title: res.msg,
  50. icon: 'none'
  51. })
  52. }
  53. })
  54. },
  55. deleteAddress(e){
  56. const id = e.currentTarget.dataset.id
  57. const loginToken = wx.getStorageSync('loginToken')
  58. WXAPI.deleteAddress(loginToken.token, id).then(res => {
  59. if (res.code == 0) {
  60. wx.showToast({
  61. title: '删除成功',
  62. icon: 'success'
  63. })
  64. this.onShow()
  65. } else {
  66. wx.showToast({
  67. title: res.msg,
  68. icon: 'none'
  69. })
  70. }
  71. })
  72. },
  73. defaultAddress(){
  74. const loginToken = wx.getStorageSync('loginToken')
  75. WXAPI.defaultAddress(loginToken.token).then(res => {
  76. console.log(res)
  77. if (res.code == 0) {
  78. wx.showToast({
  79. title: '查看控制台',
  80. icon: 'success'
  81. })
  82. } else {
  83. wx.showToast({
  84. title: res.msg,
  85. icon: 'none'
  86. })
  87. }
  88. })
  89. },
  90. updateAddress(e){
  91. const id = e.currentTarget.dataset.id
  92. wx.showToast({
  93. title: '交给你啦~',
  94. icon: 'none'
  95. })
  96. },
  97. })

添加收货地址

  1. <view class="page">
  2. <view class="page__bd">
  3. <form bindsubmit="bindSave" report-submit="true">
  4. <view class="weui-cells__title">选择</view>
  5. <view class="weui-cells weui-cells_after-title">
  6. <view class="weui-cell weui-cell_select">
  7. <view class="weui-cell__hd weui-cell__hd_in-select-after">
  8. <view class="weui-label">省份</view>
  9. </view>
  10. <view class="weui-cell__bd">
  11. <picker bindchange="provinceChange" value="{{pIndex}}" range="{{provinces}}" range-key="name">
  12. <view class="weui-select weui-select_in-select-after">{{provinces[pIndex].name}}</view>
  13. </picker>
  14. </view>
  15. </view>
  16. <view wx:if="{{cities}}" class="weui-cell weui-cell_select">
  17. <view class="weui-cell__hd weui-cell__hd_in-select-after">
  18. <view class="weui-label">城市</view>
  19. </view>
  20. <view class="weui-cell__bd">
  21. <picker bindchange="cityChange" value="{{cIndex}}" range="{{cities}}" range-key="name">
  22. <view class="weui-select weui-select_in-select-after">{{cities[cIndex].name}}</view>
  23. </picker>
  24. </view>
  25. </view>
  26. <view wx:if="{{areas}}" class="weui-cell weui-cell_select">
  27. <view class="weui-cell__hd weui-cell__hd_in-select-after">
  28. <view class="weui-label">区县</view>
  29. </view>
  30. <view class="weui-cell__bd">
  31. <picker bindchange="areaChange" value="{{aIndex}}" range="{{areas}}" range-key="name">
  32. <view class="weui-select weui-select_in-select-after">{{areas[aIndex].name}}</view>
  33. </picker>
  34. </view>
  35. </view>
  36. <view class="weui-cell ">
  37. <view class="weui-cell__hd">
  38. <view class="weui-label">联系人</view>
  39. </view>
  40. <view class="weui-cell__bd">
  41. <input name="linkMan" class="weui-input" placeholder="请输入真实姓名" />
  42. </view>
  43. </view>
  44. <view class="weui-cell ">
  45. <view class="weui-cell__hd">
  46. <view class="weui-label">详细地址</view>
  47. </view>
  48. <view class="weui-cell__bd">
  49. <input name="address" class="weui-input" placeholder="请输入真实姓名" />
  50. </view>
  51. </view>
  52. <view class="weui-cell ">
  53. <view class="weui-cell__hd">
  54. <view class="weui-label">手机号码</view>
  55. </view>
  56. <view class="weui-cell__bd">
  57. <input name="mobile" class="weui-input" placeholder="请输入真实姓名" />
  58. </view>
  59. </view>
  60. <view class="weui-cell ">
  61. <view class="weui-cell__hd">
  62. <view class="weui-label">邮编</view>
  63. </view>
  64. <view class="weui-cell__bd">
  65. <input name="code" class="weui-input" placeholder="请输入真实姓名" />
  66. </view>
  67. </view>
  68. </view>
  69. <view class="weui-btn-area">
  70. <button class="weui-btn" type="primary" formType="submit">{{ btnName }}</button>
  71. </view>
  72. </form>
  73. </view>
  74. </view>
  1. const WXAPI = require('apifm-wxapi')
  2. Page({
  3. data: {
  4. provinces: undefined,// 省份数据数组
  5. pIndex: 0,//选择的省下标
  6. cities: undefined,// 城市数据数组
  7. cIndex: 0,//选择的市下标
  8. areas: undefined,// 区县数数组
  9. aIndex: 0,//选择的区下标
  10. btnName: '添加收货地址',
  11. },
  12. onLoad: function (options) {
  13. WXAPI.province().then(res => {
  14. if (res.code == 0) {
  15. this.setData({
  16. provinces: res.data,
  17. })
  18. }
  19. })
  20. },
  21. provinceChange(e) {
  22. const index = e.detail.value
  23. this.setData({
  24. pIndex: index
  25. })
  26. const pid = this.data.provinces[index].id
  27. WXAPI.nextRegion(pid).then(res => {
  28. console.log(res)
  29. if (res.code == 0) {
  30. this.setData({
  31. cities: res.data
  32. })
  33. }
  34. })
  35. },
  36. cityChange(e) {
  37. const index = e.detail.value
  38. this.setData({
  39. cIndex: index
  40. })
  41. const pid = this.data.cities[index].id
  42. WXAPI.nextRegion(pid).then(res => {
  43. console.log(res)
  44. if (res.code == 0) {
  45. this.setData({
  46. areas: res.data
  47. })
  48. }
  49. })
  50. },
  51. areaChange(e) {
  52. const index = e.detail.value
  53. this.setData({
  54. aIndex: index
  55. })
  56. const pid = this.data.areas[index].id
  57. WXAPI.nextRegion(pid).then(res => {
  58. console.log(res)
  59. if (res.code == 0) {
  60. this.setData({
  61. streets: res.data
  62. })
  63. }
  64. })
  65. },
  66. goRegist() {
  67. wx.navigateTo({
  68. url: '/pages/auth/index'
  69. })
  70. },
  71. bindSave(e) {
  72. const loginToken = wx.getStorageSync('loginToken')
  73. if (!loginToken) {
  74. wx.showToast({
  75. title: '请先登录',
  76. icon: 'none'
  77. })
  78. this.goRegist()
  79. return
  80. }
  81. if (!this.data.cities) {
  82. wx.showToast({
  83. title: '请选择城市',
  84. icon: 'none'
  85. })
  86. return
  87. }
  88. WXAPI.addAddress({
  89. token: loginToken.token,
  90. provinceId: this.data.provinces[this.data.pIndex].id,
  91. cityId: this.data.cities[this.data.cIndex].id,
  92. districtId: this.data.areas ? this.data.areas[this.data.aIndex].id : '',
  93. linkMan: e.detail.value.linkMan,
  94. address: e.detail.value.address,
  95. mobile: e.detail.value.mobile,
  96. code: e.detail.value.code,
  97. }).then(res => {
  98. console.log(res)
  99. if (res.code == 0) {
  100. wx.showToast({
  101. title: '添加成功',
  102. icon: 'success'
  103. })
  104. wx.navigateBack()
  105. } else {
  106. wx.showToast({
  107. title: res.msg,
  108. icon: 'none'
  109. })
  110. }
  111. })
  112. },
  113. })

关于更加详细的参数使用,以及更加高级的进阶使用方法,可以参考api接口文档说明:

《api接口文档》

关于 apifm-wxapi 更多的使用方法:

《apifm-wxapi使用说明》

本案例Demo代码下载:

《apifm-wxapi使用Demo程序》

期待你的进步!
感谢!