list.vue 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. <template>
  2. <view class="content" @click="hideOperate(currentAddressId)">
  3. <template v-if='addressList.length'>
  4. <view class="address_list">
  5. <view v-for="(item, index) in addressList" :key="index" @click="checkAddress(item)"
  6. :class="{'list':true,'b-b':index!=addressList.length-1}" @longpress="showOperate(item.addressId)">
  7. <view class="wrapper flex_row_start_center">
  8. <text v-if="sourceId==item.addressId" class="iconfont iconziyuan33"></text>
  9. <view class="flex_column_start_start">
  10. <view class="u-box flex_row_start_center">
  11. <text class="name">{{item.memberName}}</text>
  12. <text class="mobile">{{item.telMobile}}</text>
  13. <image v-if="item.isDefault" class="tag" :src="imgUrl+'default_address_tag.png'" />
  14. </view>
  15. <view class="address-box">
  16. <text class="address">{{item.addressAll}} {{item.detailAddress}}</text>
  17. </view>
  18. </view>
  19. </view>
  20. <view v-show="curOperateId==item.addressId" class="mask flex_row_center_center"
  21. @click="hideOperate(item.addressId)">
  22. <view class="edit flex_row_center_center" @click.stop="operateAddress('edit', item.addressId)">
  23. {{$L('编辑')}}</view>
  24. <view class="del flex_row_center_center" @click.stop="delAddress(item.addressId)">{{$L('删除')}}
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. <view class="add_btn_bottom">
  30. <button class="add_btn flex_row_center_center" @click="operateAddress('add')">+
  31. {{$L('新建收货地址')}}</button>
  32. </view>
  33. </template>
  34. <template v-if="!addressList.length&&loadingState != 'first_loading'">
  35. <view class="flex_column_start_center empty_part">
  36. <image class="img" :src="imgUrl+'empty_address.png'" />
  37. <text class="tip_con">{{$L('还没有收货地址哦')}}~</text>
  38. <view class="ope_btn flex_row_center_center" @click="operateAddress('add')">
  39. {{$L('新建地址')}}
  40. </view>
  41. </view>
  42. </template>
  43. <loadingState v-if="loadingState == 'first_loading'||addressList.length > 0" :state='loadingState' />
  44. <uni-popup ref="popup" type="dialog">
  45. <uni-popup-dialog type="input" :before-close="true" :title="$L('提示')" :content="popTip" :duration="2000" @close="cancelChange"
  46. @confirm="confirmChange"></uni-popup-dialog>
  47. </uni-popup>
  48. </view>
  49. </template>
  50. <script>
  51. import loadingState from "@/components/loading-state.vue";
  52. import uniPopup from '@/components/uni-popup/uni-popup.vue'
  53. import uniPopupDialog from '@/components/uni-popup/uni-popup-dialog.vue'
  54. import {
  55. mapState,
  56. mapMutations
  57. } from 'vuex';
  58. export default {
  59. components: {
  60. loadingState,
  61. uniPopup,
  62. uniPopupDialog
  63. },
  64. data() {
  65. return {
  66. imgUrl: getApp().globalData.imgUrl,
  67. source: 0,
  68. sourceId: '', //下单页面选中的地址addressId
  69. curOperateId: '',
  70. loadingState: 'first_loading',
  71. orderSn: '', //订单号
  72. currentAddressId: '', //记录当前长按点击的地址
  73. editing: false,
  74. addressId: 0,
  75. popTip: '',
  76. popType: ''
  77. }
  78. },
  79. onLoad(option) {
  80. this.orderSn = option.orderSn;
  81. this.source = option.source ? option.source :
  82. 0; // source :3 从订单详情页的修改地址进入的 2:从订单列表的修改地址进入 1:从确认下单页面的修改地址进入的
  83. this.sourceId = 15;
  84. this.getAddressList();
  85. },
  86. computed: {
  87. ...mapState(['userInfo', 'addressList'])
  88. },
  89. //滚动事件地址蒙层
  90. onPageScroll(e) {
  91. if (e.scrollTop > 0) {
  92. this.hideOperate(this.currentAddressId)
  93. }
  94. },
  95. methods: {
  96. ...mapMutations(['operateAddressData']),
  97. //获取地址列表
  98. getAddressList() {
  99. this.$request({
  100. url: 'v3/member/front/memberAddress/list',
  101. method: 'GET'
  102. }).then(res => {
  103. if (res.state == 200) {
  104. this.operateAddressData(res.data.list);
  105. } else {
  106. this.$api.msg(res.msg);
  107. }
  108. this.loadingState = 'complete';
  109. }).catch((e) => {
  110. //异常处理
  111. })
  112. },
  113. cancelChange() {
  114. this.editing = false
  115. this.$refs.popup.close()
  116. },
  117. confirmChange() {
  118. this.$refs.popup.close()
  119. if (this.popType == 'edit') {
  120. this.$request({
  121. url: 'v3/business/front/orderOperate/updateAddress',
  122. data: {
  123. orderSn: this.orderSn,
  124. addressId: this.addressId,
  125. },
  126. method: 'POST'
  127. }).then(res => {
  128. if (res.state == 200) {
  129. if (this.source == 3) { //从订单详情页的修改地址进入的
  130. this.$api.msg(res.msg);
  131. setTimeout(() => {
  132. this.$api.prePage().getOrderDetail();
  133. uni.navigateBack();
  134. this.editing = false
  135. }, 1500)
  136. } else if (this.source == 2) { //从订单列表的修改地址进入的
  137. this.$api.msg(res.msg);
  138. setTimeout(() => {
  139. uni.navigateBack({
  140. delta: 1
  141. })
  142. this.editing = false
  143. }, 1500)
  144. }
  145. } else {
  146. this.editing = false
  147. this.$api.msg(res.msg);
  148. }
  149. })
  150. } else if (this.popType == 'del') {
  151. this.operateAddressData(this.addressList);
  152. this.$request({
  153. url: 'v3/member/front/memberAddress/del',
  154. data: {
  155. addressIds: this.addressId,
  156. },
  157. method: 'POST'
  158. }).then(res => {
  159. this.$api.msg(res.msg);
  160. if (res.state == 200) {
  161. //更新数据
  162. let tmp_data = this.addressList.filter(item => item.addressId != this.addressId)
  163. this.operateAddressData(tmp_data);
  164. }
  165. }).catch((e) => {
  166. //异常处理
  167. })
  168. }
  169. },
  170. //选择地址
  171. checkAddress(item) {
  172. if (this.editing) {
  173. return
  174. }
  175. if (this.source == 1) {
  176. // this.$api.prePage().orderAddress=item
  177. this.$api.prePage().changeAddress(item);
  178. uni.navigateBack()
  179. } else if (this.source == 2 || this.source == 3) {
  180. this.editing = true
  181. //从订单详情或订单列表里面进入的地址列表
  182. this.addressId = item.addressId
  183. this.popTip = '确认修改地址?'
  184. this.popType = 'edit'
  185. this.$refs.popup.open()
  186. }
  187. },
  188. operateAddress(type, addressId) {
  189. this.curOperateId = '';
  190. let url = `/pages/address/operate?type=${type}`;
  191. if (type == 'edit') {
  192. url += `&addressId=${addressId}`;
  193. }
  194. uni.navigateTo({
  195. url: url
  196. })
  197. },
  198. //地址长按事件
  199. showOperate(addressId) {
  200. this.currentAddressId = addressId
  201. if (this.curOperateId == addressId) {
  202. this.curOperateId = '';
  203. } else {
  204. this.curOperateId = addressId;
  205. }
  206. //阻止浏览器默认行为
  207. document.oncontextmenu = function(e) {
  208. e.preventDefault()
  209. }
  210. },
  211. //点击蒙层隐藏
  212. hideOperate(addressId) {
  213. this.curOperateId = '';
  214. },
  215. //删除地址事件
  216. delAddress(addressId) {
  217. this.popTip = '确定删除地址?'
  218. this.popType = 'del'
  219. this.addressId = addressId
  220. this.$refs.popup.open()
  221. },
  222. }
  223. }
  224. </script>
  225. <style lang='scss'>
  226. page {
  227. width: 750rpx;
  228. margin: 0 auto;
  229. background: #FFFFFF;
  230. -webkit-touch-callout: none;
  231. /*系统默认菜单被禁用*/
  232. -webkit-user-select: none;
  233. /*webkit浏览器*/
  234. -khtml-user-select: none;
  235. /*早期浏览器*/
  236. -moz-user-select: none;
  237. /*火狐*/
  238. -ms-user-select: none;
  239. /*IE10*/
  240. user-select: none;
  241. -webkit-touch-callout: none;
  242. -moz-touch-callout: none;
  243. -ms-touch-callout: none;
  244. touch-callout: none;
  245. }
  246. uni-page-body {
  247. display: flex;
  248. height: 100%;
  249. }
  250. .content {
  251. position: relative;
  252. background: #fff;
  253. margin-top: 20rpx;
  254. width: 100%;
  255. padding-bottom: 128rpx;
  256. }
  257. .address_list {
  258. padding-bottom: 158rpx;
  259. }
  260. .list {
  261. display: flex;
  262. flex-direction: column;
  263. align-items: flex-start;
  264. justify-content: flex-start;
  265. padding: 30rpx 30rpx;
  266. background: #fff;
  267. position: relative;
  268. &.b-b {
  269. &:after {
  270. position: absolute;
  271. z-index: 3;
  272. left: 20rpx;
  273. right: 0;
  274. height: 0;
  275. content: '';
  276. -webkit-transform: scaleY(0.5);
  277. transform: scaleY(0.5);
  278. border-bottom: 1px solid rgba(0, 0, 0, .1);
  279. }
  280. }
  281. .mask {
  282. position: absolute;
  283. z-index: 4;
  284. left: 0;
  285. right: 0;
  286. top: 0;
  287. bottom: 0;
  288. background: rgba(0, 0, 0, .6);
  289. view {
  290. width: 166rpx;
  291. height: 90rpx;
  292. border-radius: 45rpx;
  293. color: #fff;
  294. font-size: 34rpx;
  295. &.edit {
  296. background: linear-gradient(-90deg, rgba(254, 152, 32, 1), rgba(255, 183, 43, 1));
  297. }
  298. &.del {
  299. background: linear-gradient(-90deg, rgba(252, 29, 28, 1), rgba(255, 122, 24, 1));
  300. margin-left: 80rpx;
  301. }
  302. }
  303. }
  304. }
  305. .wrapper {
  306. flex: 1;
  307. background: #fff;
  308. .iconfont {
  309. color: $main-color;
  310. font-size: 32rpx;
  311. margin-right: 30rpx;
  312. }
  313. }
  314. .address-box {
  315. display: flex;
  316. align-items: center;
  317. .address {
  318. font-size: 26rpx;
  319. color: main-font-color;
  320. line-height: 38rpx;
  321. margin-top: 5rpx;
  322. word-break: break-all;
  323. }
  324. }
  325. .u-box {
  326. font-size: 30rpx;
  327. color: $font-color-light;
  328. color: $main-font-color;
  329. font-weight: bold;
  330. .name {
  331. margin-right: 40rpx;
  332. overflow: hidden;
  333. text-overflow: ellipsis;
  334. white-space: nowrap;
  335. max-width: 240rpx;
  336. }
  337. .tag {
  338. width: 63rpx;
  339. height: 30rpx;
  340. margin-left: 20rpx;
  341. }
  342. }
  343. .icon-bianji {
  344. display: flex;
  345. align-items: center;
  346. height: 80rpx;
  347. font-size: 40rpx;
  348. color: $font-color-light;
  349. padding-left: 30rpx;
  350. }
  351. .add_btn_bottom {
  352. position: fixed;
  353. width: 750rpx;
  354. height: 168rpx;
  355. bottom: 0;
  356. padding: 40rpx 0;
  357. background: #FFFFFF;
  358. margin: 0 auto;
  359. z-index: 95;
  360. .add_btn {
  361. width: 664rpx;
  362. font-size: 34rpx;
  363. color: #fff;
  364. height: 88rpx;
  365. background: #F30300;
  366. border-radius: 44rpx;
  367. letter-spacing: 1rpx;
  368. }
  369. }
  370. .empty_part {
  371. display: flex;
  372. flex: 1;
  373. width: 100%;
  374. height: 100%;
  375. background: #fff;
  376. .img {
  377. width: 210rpx;
  378. height: 210rpx;
  379. margin-bottom: 37rpx;
  380. margin-top: 88rpx;
  381. }
  382. .tip_con {
  383. color: $main-third-color;
  384. font-size: 26rpx;
  385. }
  386. .ope_btn {
  387. color: $main-color;
  388. font-size: 28rpx;
  389. padding: 0 25rpx;
  390. height: 54rpx;
  391. background: rgba(252, 28, 28, .1);
  392. border-radius: 27rpx;
  393. margin-top: 20rpx;
  394. }
  395. }
  396. </style>