address-list.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <template>
  2. <view class="address-list">
  3. <tui-skeleton v-if="isRequest" :loadingType="3" :isLoading="true"></tui-skeleton>
  4. <!-- 收货地址为空 -->
  5. <template v-if="list.length === 0">
  6. <tui-no-data :imgUrl="staticUrl + 'icon-empty-address.png'" :imgHeight="230" :imgWidth="290">
  7. <view class="empty-tip">您还没有收货地址</view>
  8. <view class="empty-tip">点击底部按钮添加收货地址吧~~</view>
  9. </tui-no-data>
  10. </template>
  11. <!-- 收货地址列表 -->
  12. <template v-else>
  13. <view class="address" v-for="item in list" :key="item.addressId" @click="chooseAddress(item)">
  14. <text v-if="item.defaultFlag == 1" class="default-tag">默认</text>
  15. <view class="contact">
  16. <text class="name" v-text="item.shouHuoRen"></text>
  17. <text class="mobile" v-text="item.mobile"></text>
  18. </view>
  19. <view class="detail">
  20. <text class="opacity">收货地址:</text>
  21. {{ item.provinceName }}{{ item.cityName }}{{ item.townName }}{{ item.address }}
  22. </view>
  23. <view class="control">
  24. <view class="default">
  25. <view class="iconfont icon-xuanze icon" v-if="item.defaultFlag == 1">
  26. <text class="opacity">已设为默认地址</text>
  27. </view>
  28. <view class="iconfont icon-weixuanze" v-else @click.stop="setDefalut(item)">
  29. <text class="opacity">设为默认地址</text>
  30. </view>
  31. </view>
  32. <view class="update">
  33. <text
  34. class="iconfont icon-shanchu"
  35. @click.stop="handleRemoveAddress(item)"
  36. v-if="type !== 'choose'"
  37. >
  38. 删除
  39. </text>
  40. <text class="iconfont icon-bianji" @click.stop="editAddress(item)">编辑</text>
  41. </view>
  42. </view>
  43. </view>
  44. <cm-loadmore :hasMore="hasNextPage" :isLoading="isLoading" :visiable="visiable"></cm-loadmore>
  45. </template>
  46. <tui-button
  47. class="create"
  48. type="base"
  49. :size="28"
  50. width="650rpx"
  51. height="88rpx"
  52. shape="circle"
  53. @click="createAddress"
  54. >
  55. 添加新地址
  56. </tui-button>
  57. <!-- 确认弹框 -->
  58. <tui-modal :show="removeModal" content="确认删除该地址吗?" @click="modalClick"></tui-modal>
  59. </view>
  60. </template>
  61. <script>
  62. import { fetchAddressList, removeAddress, setDefaultAddress } from '@/services/api/user.js'
  63. import { debounce } from '@/common/utils.js'
  64. import { mapGetters } from 'vuex'
  65. export default {
  66. data() {
  67. return {
  68. type: 'list',
  69. isRequest: true,
  70. isLoading: false,
  71. listQuery: {
  72. userId: 0,
  73. pageNum: 1,
  74. pageSize: 10
  75. },
  76. list: [],
  77. total: 0,
  78. hasNextPage: true,
  79. removeModal: false,
  80. currentRemove: null // 当前选中需要被删除的地址
  81. }
  82. },
  83. computed: {
  84. ...mapGetters(['userId']),
  85. visiable() {
  86. return this.list.length > this.listQuery.pageSize
  87. }
  88. },
  89. onLoad(options) {
  90. this.type = options.type
  91. this.initAddressList()
  92. },
  93. onShow() {
  94. if (this.$router.checkRefreshType('createAddressBack')) {
  95. this.initAddressList()
  96. }
  97. },
  98. onReachBottom() {
  99. this.fetchAddressList()
  100. },
  101. methods: {
  102. // 选择收货地址
  103. chooseAddress(item) {
  104. if (this.type !== 'choose') {
  105. return
  106. }
  107. this.$router.addRefreshType('chooseAddress')
  108. uni.setStorageSync('CHOOSE_ADDRESS', item)
  109. this.$router.navigateBack()
  110. },
  111. // 新增收货地址
  112. createAddress() {
  113. this.$router.navigateTo('address/address-create?type=add')
  114. },
  115. // 编辑收货地址
  116. editAddress(item) {
  117. uni.setStorageSync('eidtAddress', item)
  118. this.$router.navigateTo('address/address-create?type=edit')
  119. },
  120. // 删除收货地址事件
  121. handleRemoveAddress(item) {
  122. this.currentRemove = item
  123. this.removeModal = true
  124. },
  125. // 删除收货地址
  126. async removeAddress() {
  127. try {
  128. const { addressId } = this.currentRemove
  129. await removeAddress({ userId: this.listQuery.userId, addressId })
  130. this.$toast.success('删除地址成功')
  131. const index = this.list.findIndex(item => item.addressId === addressId)
  132. this.list.splice(index, 1)
  133. } catch (e) {
  134. console.log(e)
  135. } finally {
  136. this.removeModal = false
  137. }
  138. },
  139. // 删除确认框事件
  140. modalClick({ index }) {
  141. if (!index) return (this.removeModal = false)
  142. this.removeAddress()
  143. },
  144. // 设为默认地址
  145. async setDefalut(item) {
  146. try {
  147. const userId = this.listQuery.userId
  148. const addressId = item.addressId
  149. await setDefaultAddress({ userId, addressId })
  150. this.$toast.success('默认地址修改成功')
  151. // 更新列表信息
  152. const find = this.list.find(item => item.defaultFlag === '1')
  153. if (find) {
  154. find.defaultFlag = '0'
  155. }
  156. item.defaultFlag = '1'
  157. } catch (e) {
  158. //TODO handle the exception
  159. }
  160. },
  161. // 初始化地址列表
  162. initAddressList() {
  163. this.listQuery.userId = this.userId
  164. this.listQuery.pageNum = 1
  165. this.list = []
  166. this.hasNextPage = true
  167. this.fetchAddressList()
  168. },
  169. // 获取地址列表
  170. fetchAddressList: debounce(async function() {
  171. if (!this.hasNextPage) return
  172. this.isLoading = true
  173. try {
  174. const res = await fetchAddressList(this.listQuery)
  175. this.list = [...this.list, ...res.data.list]
  176. this.total = res.data.total
  177. this.hasNextPage = res.data.hasNextPage
  178. this.listQuery.pageNum++
  179. } catch (e) {
  180. console.log(e)
  181. } finally {
  182. this.isRequest = false
  183. this.isLoading = false
  184. uni.stopPullDownRefresh()
  185. }
  186. }, 500)
  187. }
  188. }
  189. </script>
  190. <style lang="scss" scoped>
  191. .address-list {
  192. color: #333;
  193. padding-bottom: 138rpx;
  194. overflow: hidden;
  195. .create {
  196. position: fixed;
  197. left: 50rpx;
  198. bottom: 50rpx;
  199. z-index: 9;
  200. }
  201. .address {
  202. position: relative;
  203. padding: 24rpx;
  204. margin: 24rpx 0;
  205. background-color: #fff;
  206. .default-tag {
  207. position: absolute;
  208. right: 24rpx;
  209. top: 24rpx;
  210. font-size: 22rpx;
  211. padding: 0 24rpx;
  212. line-height: 40rpx;
  213. background: #f83c6c;
  214. color: #fff;
  215. border-radius: 20rpx;
  216. }
  217. .contact {
  218. @include ellipsis(1);
  219. font-size: 30rpx;
  220. font-weight: bold;
  221. .name {
  222. margin-right: 24rpx;
  223. }
  224. }
  225. .detail {
  226. // @include ellipsis(1);
  227. margin: 8rpx 0;
  228. max-width: 650rpx;
  229. font-size: 28rpx;
  230. color: #333;
  231. }
  232. }
  233. .control {
  234. @extend .cm-flex-between;
  235. .iconfont {
  236. font-size: 24rpx;
  237. }
  238. .default {
  239. .opacity {
  240. margin-left: 8rpx;
  241. }
  242. }
  243. .update {
  244. .icon-shanchu {
  245. margin-right: 40rpx;
  246. }
  247. }
  248. }
  249. .opacity {
  250. opacity: 0.8;
  251. color: #333;
  252. }
  253. }
  254. </style>