You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

477 lines
11 KiB

8 months ago
8 months ago
8 months ago
  1. <template>
  2. <view class="address">
  3. <mNavbar title="地址管理" :leftClick="leftClick"></mNavbar>
  4. <view v-if="addressList.length > 0" class="address-list">
  5. <van-radio-group v-model="selectAddress">
  6. <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
  7. <view v-for="item in addressList" :key="item.id" class="address-item">
  8. <view class="address-item-top">
  9. <view class="img-box">
  10. <image src="@/static/address/address-icon.png" mode="aspectFill"></image>
  11. </view>
  12. <view class="address-info">
  13. <view class="user-info">
  14. <text class="user-name">{{ item.name }}</text>
  15. <text class="user-phone">{{ item.phone }}</text>
  16. <text v-if="item.defaultId == '1'" class="is-default">默认</text>
  17. </view>
  18. <view class="address-detail">
  19. {{ item.address + " " + item.addressDetail }}
  20. </view>
  21. </view>
  22. </view>
  23. <view class="controls">
  24. <view class="default-checkbox">
  25. <van-radio @click="addDefault(item)" :name="item.id" label-disabled icon-size="30rpx">
  26. 默认地址
  27. </van-radio>
  28. </view>
  29. <view class="edit-btn">
  30. <image src="@/static/address/edit-icon.png" mode="aspectFill"></image>
  31. <text @click="getAddressDetail(item.id)" class="control-title">编辑</text>
  32. </view>
  33. <view class="del-btn">
  34. <image src="@/static/address/delete-icon.png" mode="aspectFill"></image>
  35. <text class="control-title" @click="deleteAddress(item.id)">删除</text>
  36. </view>
  37. </view>
  38. </view>
  39. </van-list>
  40. </van-radio-group>
  41. </view>
  42. <van-empty v-else image="/static/empty/address.png" image-size="400rpx" description="暂无服务地址请添加" />
  43. <van-popup v-model:show="showOverlay" position="bottom" round closeable close-icon="close" :z-index="100"
  44. :style="{ height: 'auto' , width : '100%' , padding : '20rpx'}">
  45. <redactAddress :addressDetail="addressDetail" @saveOrUpdate="saveOrUpdate" :title="title"
  46. @clickAddressIcon="selectAddr"></redactAddress>
  47. </van-popup>
  48. <view class="add-btn">
  49. <view @click="addBtn" class="btn">
  50. 新增地址
  51. </view>
  52. </view>
  53. </view>
  54. </template>
  55. <script>
  56. import mNavbar from '@/components/base/m-navbar.vue'
  57. import redactAddress from '@/components/address/redactAddress.vue'
  58. import {
  59. showNotify
  60. } from 'vant'
  61. import {
  62. showConfirmDialog
  63. } from 'vant';
  64. import Position from '@/utils/position.js'
  65. export default {
  66. components: {
  67. mNavbar,
  68. redactAddress
  69. },
  70. data() {
  71. return {
  72. selectAddress: 0, //单选框选中的地址
  73. showOverlay: false,
  74. queryParams: {
  75. pageNo: 1,
  76. pageSize: 10
  77. },
  78. addressList: [],
  79. addressDetail: {},
  80. loading: false,
  81. finished: false,
  82. title: '新增地址'
  83. }
  84. },
  85. onShow() {
  86. if (this.$route.query.current == 'payOrder') {
  87. this.showOverlay = true;
  88. }
  89. this.getAddressList()
  90. },
  91. methods: {
  92. //list列表滑动到底部自动新增数据列表
  93. onLoad() {
  94. this.queryParams.pageSize += 10
  95. this.getAddressList()
  96. },
  97. //获取地址列表
  98. getAddressList() {
  99. this.$api('getAddressList', this.queryParams, res => {
  100. if (res.code == 200) {
  101. this.addressList = res.result.records || [];
  102. this.addressList.forEach(n => { //筛选默认地址
  103. if (n.defaultId == '1') {
  104. this.selectAddress = n.id
  105. }
  106. })
  107. if (this.queryParams.pageSize > res.result.total) {
  108. this.finished = true
  109. }
  110. }
  111. this.loading = false
  112. })
  113. },
  114. //获取地址详情
  115. getAddressDetail(id) {
  116. this.title = '修改地址'
  117. this.$api('getAddressDetail', {
  118. id
  119. }, res => {
  120. if (res.code == 200) {
  121. this.addressDetail = res.result;
  122. this.showOverlay = true
  123. }
  124. })
  125. },
  126. //返回个人中心
  127. leftClick() {
  128. if (this.$route.query.current == 'payOrder') { //如果是从订单支付过来添加地址的就再调回去
  129. return uni.navigateTo({
  130. url: `/pages/order/payOrder?orderId=${this.$route.query.orderId}`
  131. })
  132. }
  133. uni.switchTab({
  134. url: '/pages/index/center'
  135. })
  136. },
  137. //添加和修改地址
  138. saveOrUpdate() {
  139. let isOk = this.parameterVerification()
  140. if (isOk && !isOk.auth) {
  141. return showNotify({
  142. type: 'warning',
  143. message: isOk.title,
  144. 'z-index': 10000
  145. });
  146. }
  147. let data = {
  148. name: this.addressDetail.name,
  149. phone: this.addressDetail.phone,
  150. address: this.addressDetail.address,
  151. addressDetail: this.addressDetail.addressDetail,
  152. defaultId: this.addressDetail.defaultId || '0',
  153. latitude: this.addressDetail.latitude,
  154. longitude: this.addressDetail.longitude
  155. }
  156. if (this.addressDetail.id) {
  157. data.id = this.addressDetail.id
  158. }
  159. this.$api('addOrUpdateAddress', data, res => {
  160. if (res.code == 200) {
  161. this.showOverlay = false
  162. this.getAddressList()
  163. uni.showToast({
  164. title: '操作成功',
  165. icon: 'none'
  166. })
  167. if (this.$route.query.current == 'payOrder') { //如果是从订单支付过来添加地址的就再调回去
  168. uni.navigateTo({
  169. url: `/pages/order/payOrder?orderId=${this.$route.query.orderId}`
  170. })
  171. }
  172. }
  173. })
  174. },
  175. //新增默认地址
  176. addDefault(item) {
  177. this.selectAddress = item.id
  178. this.$api('addOrUpdateAddress', {
  179. id: item.id,
  180. defaultId: '1',
  181. }, res => {
  182. if (res.code == 200) {
  183. this.showOverlay = false
  184. uni.showToast({
  185. title: '操作成功',
  186. icon: 'none'
  187. })
  188. this.getAddressList()
  189. }
  190. })
  191. },
  192. //删除地址
  193. deleteAddress(id) {
  194. showConfirmDialog({
  195. title: '删除地址',
  196. message: '确认删除此地址?删除后数据不可恢复',
  197. }).then(() => {
  198. this.$api('deleteAddress', {
  199. id
  200. }, res => {
  201. if (res.code == 200) {
  202. uni.showToast({
  203. title: '删除成功',
  204. icon: 'none'
  205. })
  206. this.getAddressList()
  207. }
  208. })
  209. }).catch(() => {});
  210. },
  211. //点击新增按钮
  212. addBtn() {
  213. this.title = '新增地址'
  214. this.addressDetail = { //初始化数据
  215. name: '',
  216. phone: '',
  217. address: '',
  218. addressDetail: '',
  219. defaultId: '',
  220. latitude: '',
  221. longitude: ''
  222. }
  223. this.showOverlay = true
  224. },
  225. //验证用户参数合法性
  226. parameterVerification() {
  227. let {
  228. name,
  229. phone,
  230. address,
  231. addressDetail
  232. } = this.addressDetail
  233. if (name.trim() == '') {
  234. return {
  235. title: '请填写联系人',
  236. auth: false
  237. }
  238. } else if (phone.trim() == '') {
  239. return {
  240. title: '请填写手机号',
  241. auth: false
  242. }
  243. } else if (address.trim() == '') {
  244. return {
  245. title: '请填写所在地区',
  246. auth: false
  247. }
  248. } else if (addressDetail.trim() == '') {
  249. return {
  250. title: '请填写详细地址',
  251. auth: false
  252. }
  253. } else if (phone.trim() != '') {
  254. if (!this.$utils.verificationPhone(phone)) {
  255. return {
  256. title: '手机号格式不合法',
  257. auth: false
  258. }
  259. }
  260. }
  261. return {
  262. title: '验证通过',
  263. auth: true
  264. }
  265. },
  266. //地图上选择地址
  267. selectAddr() {
  268. // Position.getLocation(res => {
  269. Position.selectAddress(success => {
  270. this.setAddress(success)
  271. // })
  272. })
  273. },
  274. //提取用户选择的地址信息复制给表单数据
  275. setAddress(res) {
  276. //经纬度信息
  277. this.addressDetail.latitude = res.latitude
  278. this.addressDetail.longitude = res.longitude
  279. if (!res.address && res.name) { //用户直接选择城市的逻辑
  280. return this.addressDetail.address = res.name
  281. }
  282. if (res.address || res.name) {
  283. return this.addressDetail.address = res.address + res.name
  284. }
  285. this.addressDetail.address = '' //用户啥都没选就点击勾选
  286. }
  287. }
  288. }
  289. </script>
  290. <style lang="scss" scoped>
  291. .address {
  292. width: 750rpx;
  293. margin: 0rpx auto;
  294. background: #F5F5F5;
  295. box-sizing: border-box;
  296. min-height: 100vh;
  297. .address-list {
  298. padding: 40rpx 20rpx 120rpx 20rpx;
  299. .address-item {
  300. background: white;
  301. border-radius: 20rpx;
  302. overflow: hidden;
  303. margin-bottom: 20rpx;
  304. padding: 15rpx 15rpx 0rpx 15rpx;
  305. .address-item-top {
  306. border-bottom: 1px dashed #D3D1D1;
  307. display: flex;
  308. align-items: center;
  309. padding: 0rpx 0rpx 15rpx 0rpx;
  310. .img-box {
  311. width: 120rpx;
  312. height: 120rpx;
  313. image {
  314. width: 75%;
  315. height: 75%;
  316. display: block;
  317. margin: 12.5% auto;
  318. }
  319. }
  320. .address-info {
  321. width: calc(100% - 120rpx);
  322. height: 100%;
  323. display: flex;
  324. flex-direction: column;
  325. justify-content: space-between;
  326. .user-info {
  327. display: flex;
  328. align-items: center;
  329. text {
  330. display: block;
  331. line-height: 40rpx;
  332. margin-right: 20rpx;
  333. }
  334. .user-name,
  335. .user-phone {
  336. font-size: 30rpx;
  337. }
  338. .is-default {
  339. display: flex;
  340. align-items: center;
  341. justify-content: center;
  342. background: #FEB773;
  343. color: white;
  344. width: 80rpx;
  345. height: 35rpx;
  346. border-radius: 20rpx;
  347. font-size: 22rpx;
  348. }
  349. }
  350. .address-detail {
  351. color: #4a4a4a;
  352. font-size: 26rpx;
  353. overflow: hidden;
  354. display: -webkit-box;
  355. -webkit-box-orient: vertical;
  356. -webkit-line-clamp: 2;
  357. text-overflow: ellipsis;
  358. }
  359. }
  360. }
  361. .controls {
  362. display: flex;
  363. align-items: center;
  364. justify-content: space-between;
  365. align-items: center;
  366. font-size: 26rpx;
  367. padding: 15rpx 15rpx 25rpx 15rpx;
  368. .default-checkbox {
  369. display: flex;
  370. text {
  371. margin-left: 8rpx;
  372. }
  373. }
  374. .control-title {
  375. height: 30rpx;
  376. line-height: 30rpx;
  377. color: #666666;
  378. }
  379. view {
  380. display: flex;
  381. align-items: center;
  382. }
  383. image {
  384. width: 23rpx;
  385. height: 23rpx;
  386. vertical-align: middle;
  387. margin-right: 8rpx;
  388. }
  389. }
  390. }
  391. }
  392. .add-btn {
  393. position: fixed;
  394. display: flex;
  395. justify-content: center;
  396. align-items: center;
  397. left: 0;
  398. bottom: 0;
  399. width: 750rpx;
  400. height: 100rpx;
  401. background: white;
  402. .btn {
  403. display: flex;
  404. align-items: center;
  405. justify-content: center;
  406. width: 85%;
  407. height: 80rpx;
  408. border-radius: 40rpx;
  409. color: white;
  410. text-align: center;
  411. font-size: 28rpx;
  412. background: linear-gradient(180deg, #6FDFBE, #5AC796);
  413. }
  414. }
  415. }
  416. @media all and (min-width: 961px) {
  417. .add-btn {
  418. left: 50% !important;
  419. transform: translateX(-50%);
  420. }
  421. }
  422. //选择位置地图样式
  423. :deep(.uni-system-choose-location) {
  424. z-index: 99999 !important;
  425. }
  426. </style>