index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. <template>
  2. <view>
  3. <view class="to_bottom" v-if="!addrList.length"> -----还没有地址啦-----</view>
  4. <view class="addr_list">
  5. <view class="addr_item" v-for="(item, index) in addrList" :key="index">
  6. <view class="contact_user">
  7. <text class="contact_name">{{ item.contact_name }}</text>
  8. <text class="contact_phone">{{ item.contact_phone }}</text>
  9. <text class="contact_shop">{{ item.contact_shop }}</text>
  10. </view>
  11. <view class="contact_addr"> {{ item.contact_province }} {{ item.contact_city }} {{ item.contact_area }} {{ item.contact_addr }} </view>
  12. <view class="contact_handler">
  13. <view class="radio_label" @click="setDefault(index)">
  14. <image class="radio_icon" :src="item.is_default ? '../../static/icon/radioed.png' : '../../static/icon/radio.png'"></image>
  15. <text :class="item.is_default ? 'radioed_text' : ''">{{ item.is_default ? "已默认" : "设为默认" }}</text>
  16. </view>
  17. <view class="addr_right_btn" @click="removeAddr(index)"> 删除 </view>
  18. <view class="addr_right_btn" @click="openForm(item)"> 编辑 </view>
  19. </view>
  20. </view>
  21. </view>
  22. <view class="create_box">
  23. <button class="create_addr" @click="openForm()">新建收货地址</button>
  24. </view>
  25. <view class="to_bottom" v-if="isLast"> -----到底啦-----</view>
  26. <uni-popup ref="addrForm" type="bottom" class="popup" background-color="#FFFFFF" @change="popupChange">
  27. <view class="contact_addr_form">
  28. <!-- 地区代表表单 -->
  29. <form class="info_form">
  30. <view class="form_group">
  31. <view class="group_title">收货人:</view>
  32. <view class="group_box">
  33. <input type="text" class="form_ctrl" placeholder="请输入收件人" maxlength="20" required="" v-model="addrRequest.contact_name" />
  34. </view>
  35. </view>
  36. <view class="form_group">
  37. <view class="group_title">手机号:</view>
  38. <view class="group_box">
  39. <input type="text" class="form_ctrl" placeholder="请输入手机号" maxlength="11" required="" v-model="addrRequest.contact_phone" />
  40. </view>
  41. </view>
  42. <view class="form_group">
  43. <view class="group_title">店铺名称:</view>
  44. <view class="group_box">
  45. <input type="text" class="form_ctrl" placeholder="请输入店铺名称" maxlength="20" required="" v-model="addrRequest.contact_shop" />
  46. </view>
  47. </view>
  48. <view class="form_group">
  49. <view class="group_title">所在地区:</view>
  50. <view class="group_box">
  51. <picker mode="multiSelector" class="form_ctrl" :range="cityArray" @columnchange="cityChange" @change="cityFinish">
  52. <view class="area_text">
  53. <text v-if="addrRequest.contact_province">{{ addrRequest.contact_province }}</text>
  54. <text v-if="addrRequest.contact_city">/{{ addrRequest.contact_city }}</text>
  55. <text v-if="addrRequest.contact_area">/{{ addrRequest.contact_area }}</text>
  56. </view>
  57. </picker>
  58. </view>
  59. </view>
  60. <view class="form_group">
  61. <view class="group_title">详细地址:</view>
  62. <view class="group_box">
  63. <input type="text" class="form_ctrl" placeholder="请输入详细地址:街道/小区/门牌号" maxlength="64" required="" v-model="addrRequest.contact_addr" />
  64. </view>
  65. </view>
  66. <view class="form_group">
  67. <view class="group_title">设为默认</view>
  68. <view class="group_box">
  69. <switch color="#E03519" style="transform: scale(0.6); float: right" @change="defaultSwitch" :checked="addrRequest.is_default ? true : false" />
  70. </view>
  71. </view>
  72. <button class="submit_btn" @click="saveAddr">保存地址</button>
  73. </form>
  74. </view>
  75. </uni-popup>
  76. </view>
  77. </template>
  78. <script>
  79. import { getProvinces, getMyCity, getAreas } from "../../utils/city";
  80. export default {
  81. data() {
  82. return {
  83. // 产品列表
  84. addrList: [],
  85. // 请求参数
  86. requestParam: {
  87. page: 1,
  88. status: 0,
  89. },
  90. // 保存地址
  91. addrRequest: {
  92. id: 0,
  93. contact_name: "",
  94. contact_phone: "",
  95. contact_province: "",
  96. contact_city: "",
  97. contact_area: "",
  98. contact_addr: "",
  99. contact_shop: "",
  100. is_default: 0,
  101. },
  102. // 是否最后一页
  103. isLast: false,
  104. // 是否请求中
  105. isReqing: false,
  106. // 所在地区
  107. cityArray: [[], [], []],
  108. cityValue: [0, 0, 0],
  109. // 自动弹出
  110. autoShowForm: false,
  111. // 异步通知
  112. AddrEmit: false,
  113. };
  114. },
  115. onLoad(param) {
  116. this.AddrEmit = param.notify == "addr" ? true : false;
  117. this.autoShowForm = param.type == "create" ? true : false;
  118. // 获取列表
  119. this.getList();
  120. },
  121. onReady() {
  122. if (this.autoShowForm) {
  123. var that = this;
  124. // 500毫秒后自动弹出
  125. setTimeout(function () {
  126. that.openForm();
  127. }, 500);
  128. }
  129. },
  130. onShow() {
  131. // 替换对应的数据
  132. this.cityArray.splice(0, 1, getProvinces());
  133. this.cityArray.splice(1, 1, getMyCity(this.cityValue[0]));
  134. this.cityArray.splice(2, 1, getAreas(this.cityValue[0], this.cityValue[1]));
  135. // 默认地址
  136. this.addrRequest.contact_province = this.cityArray[0][this.cityValue[0]];
  137. this.addrRequest.contact_city = this.cityArray[1][this.cityValue[1]];
  138. this.addrRequest.contact_area = this.cityArray[2][this.cityValue[2]];
  139. },
  140. methods: {
  141. // 获取列表
  142. getList() {
  143. // 登录提示
  144. if (!this.$checkAccess.alterLogin()) return;
  145. // 判断数据
  146. this.$http.request("api/custom_addr/get_list").then((callback) => {
  147. // 获取成功
  148. if (callback.code == "success") {
  149. this.addrList = callback.data;
  150. // 通知地址变更
  151. if (this.AddrEmit) uni.$emit("addr_list_change", { list: this.addrList });
  152. }
  153. });
  154. },
  155. // 打开弹窗
  156. openForm(item) {
  157. if (!item) {
  158. this.addrRequest.id = 0;
  159. this.addrRequest.contact_name = "";
  160. this.addrRequest.contact_phone = "";
  161. this.addrRequest.contact_shop = "";
  162. this.addrRequest.contact_addr = "";
  163. this.addrRequest.is_default = 0;
  164. } else {
  165. this.addrRequest = item;
  166. }
  167. // 显示下单弹出层
  168. this.$refs.addrForm.open("bottom");
  169. },
  170. // 默认开关
  171. defaultSwitch(e) {
  172. this.addrRequest.is_default = e.detail.value ? 1 : 0;
  173. },
  174. // 弹出层
  175. popupChange(e) {
  176. // 禁止滚动穿透
  177. this.show = e.show;
  178. },
  179. // 城市修改
  180. cityChange(e) {
  181. // 替换三个选项
  182. this.cityValue.splice(e.detail.column, 1, e.detail.value);
  183. // 下一级设置为0
  184. if (e.detail.column == 0) {
  185. this.cityValue.splice(1, 1, 0);
  186. this.cityValue.splice(2, 1, 0);
  187. }
  188. if (e.detail.column == 1) {
  189. this.cityValue.splice(2, 1, 0);
  190. }
  191. // 替换对应的数据
  192. this.cityArray.splice(0, 1, getProvinces());
  193. this.cityArray.splice(1, 1, getMyCity(this.cityValue[0]));
  194. this.cityArray.splice(2, 1, getAreas(this.cityValue[0], this.cityValue[1]));
  195. },
  196. // 城市选择
  197. cityFinish(e) {
  198. this.addrRequest.contact_province = this.cityArray[0][this.cityValue[0]];
  199. this.addrRequest.contact_city = this.cityArray[1][this.cityValue[1]];
  200. this.addrRequest.contact_area = this.cityArray[2][this.cityValue[2]];
  201. },
  202. // 城市选中
  203. cityFinish(e) {
  204. this.addrRequest.contact_province = this.cityArray[0][this.cityValue[0]];
  205. this.addrRequest.contact_city = this.cityArray[1][this.cityValue[1]];
  206. this.addrRequest.contact_area = this.cityArray[2][this.cityValue[2]];
  207. },
  208. // 保存地址
  209. saveAddr() {
  210. // 判断姓名
  211. if (!this.addrRequest.contact_name) {
  212. uni.showToast({ icon: "none", title: "请填写收件人" });
  213. return;
  214. }
  215. if (this.addrRequest.contact_name.length < 2) {
  216. uni.showToast({ icon: "none", title: "请填写收件人完整姓名" });
  217. return;
  218. }
  219. if (!this.addrRequest.contact_shop) {
  220. uni.showToast({ icon: "none", title: "请填写店铺名称" });
  221. return;
  222. }
  223. if (!this.addrRequest.contact_phone) {
  224. uni.showToast({ icon: "none", title: "请填写收件人手机号" });
  225. return;
  226. }
  227. if (!this.addrRequest.contact_addr) {
  228. uni.showToast({ icon: "none", title: "请填写联系地址" });
  229. return;
  230. }
  231. if (this.addrRequest.contact_addr.length < 3) {
  232. uni.showToast({ icon: "none", title: "请填写可用联系地址" });
  233. return;
  234. }
  235. // 请求状态
  236. uni.showLoading({ mask: true });
  237. // 请求路径
  238. var url = this.addrRequest.id ? "api/custom_addr/edit" : "api/custom_addr/add";
  239. // 授权成功以后,调用绑定
  240. this.$http.request(url, this.addrRequest, "post").then((re) => {
  241. // 关闭
  242. uni.hideLoading();
  243. // 成功的话
  244. if (re.code != "success") {
  245. // 跳转
  246. uni.showToast({ title: re.msg, icon: "none" });
  247. return;
  248. }
  249. // 地址变动
  250. this.getList();
  251. // 显示下单弹出层
  252. this.$refs.addrForm.close();
  253. });
  254. },
  255. // 删除地址
  256. removeAddr(index) {
  257. // 授权成功以后,调用绑定
  258. this.$http.request("api/custom_addr/del", { id: this.addrList[index].id }, "post").then((re) => {
  259. // 关闭
  260. uni.hideLoading();
  261. // 成功的话
  262. if (re.code != "success") {
  263. // 跳转
  264. uni.showToast({ title: re.msg, icon: "none" });
  265. return;
  266. }
  267. // 成功删除该项
  268. this.addrList.splice(index, 1);
  269. // 通知地址变更
  270. if (this.AddrEmit) uni.$emit("addr_list_change", { list: this.addrList });
  271. });
  272. },
  273. // 设置默认
  274. setDefault(index) {
  275. // 如果已经是默认状态
  276. if (this.addrList[index].is_default) return;
  277. // 授权成功以后,调用绑定
  278. this.$http.request("api/custom_addr/set_default", { id: this.addrList[index].id }, "post").then((re) => {
  279. // 关闭
  280. uni.hideLoading();
  281. // 成功的话
  282. if (re.code != "success") {
  283. // 跳转
  284. uni.showToast({ title: re.msg, icon: "none" });
  285. return;
  286. }
  287. // 更新其他的默认项
  288. for (let i in this.addrList) {
  289. this.addrList[i].is_default = 0;
  290. }
  291. // 成功修改值
  292. this.addrList[index].is_default = 1;
  293. // 通知地址变更
  294. if (this.AddrEmit) uni.$emit("addr_list_change", { list: this.addrList });
  295. });
  296. },
  297. },
  298. };
  299. </script>
  300. <style lang="less">
  301. .addr_list {
  302. width: 730rpx;
  303. display: block;
  304. overflow: hidden;
  305. margin: 0rpx auto;
  306. .addr_item {
  307. display: block;
  308. font-size: 24rpx;
  309. overflow: hidden;
  310. line-height: 40rpx;
  311. padding: 15rpx 10rpx;
  312. border-radius: 15rpx;
  313. padding-bottom: 0rpx;
  314. margin-bottom: 10rpx;
  315. background-color: #ffffff;
  316. .contact_user {
  317. display: block;
  318. font-size: 24rpx;
  319. line-height: 50rpx;
  320. .contact_name {
  321. font-size: 26rpx;
  322. font-weight: bold;
  323. margin-right: 16rpx;
  324. }
  325. .contact_shop {
  326. float: right;
  327. }
  328. }
  329. .contact_addr {
  330. display: block;
  331. font-size: 24rpx;
  332. line-height: 30rpx;
  333. padding: 10rpx 5rpx;
  334. border-bottom: 2rpx solid #dddddd;
  335. }
  336. .contact_handler {
  337. height: 60rpx;
  338. display: block;
  339. line-height: 60rpx;
  340. font-size: 20rpx;
  341. .radio_label {
  342. float: left;
  343. height: 60rpx;
  344. line-height: 60rpx;
  345. .radio_icon {
  346. width: 40rpx;
  347. height: 40rpx;
  348. vertical-align: middle;
  349. }
  350. .radioed_text {
  351. color: #e03519;
  352. }
  353. }
  354. .addr_right_btn {
  355. float: right;
  356. height: 40rpx;
  357. display: block;
  358. line-height: 40rpx;
  359. padding: 10rpx 35rpx;
  360. }
  361. }
  362. }
  363. }
  364. .create_box {
  365. left: 0rpx;
  366. width: 750rpx;
  367. height: 140rpx;
  368. display: block;
  369. position: fixed;
  370. bottom: var(--window-bottom);
  371. .create_addr {
  372. width: 700rpx;
  373. height: 80rpx;
  374. display: block;
  375. color: #ffffff;
  376. font-size: 30rpx;
  377. overflow: hidden;
  378. line-height: 80rpx;
  379. padding: 0rpx 0rpx;
  380. text-align: center;
  381. margin: 0rpx auto;
  382. margin-top: 20rpx;
  383. border-radius: 40rpx;
  384. background-color: #e03519;
  385. }
  386. }
  387. .popup {
  388. .info_form {
  389. display: block;
  390. overflow: hidden;
  391. padding: 20rpx 0rpx;
  392. padding-top: 80rpx;
  393. background: #ffffff;
  394. .form_group {
  395. display: block;
  396. overflow: hidden;
  397. line-height: 60rpx;
  398. padding: 20rpx 35rpx;
  399. .group_title {
  400. float: left;
  401. width: 160rpx;
  402. display: block;
  403. overflow: hidden;
  404. font-size: 30rpx;
  405. margin-right: 20rpx;
  406. }
  407. .group_box {
  408. float: left;
  409. width: 480rpx;
  410. display: block;
  411. .form_ctrl {
  412. height: 56rpx;
  413. font-size: 28rpx;
  414. padding: 0rpx 20rpx;
  415. line-height: 56rpx;
  416. border: 2rpx solid #dddddd;
  417. }
  418. .area_text {
  419. width: 446rpx;
  420. font-size: 20rpx;
  421. overflow: hidden;
  422. white-space: nowrap;
  423. text-overflow: ellipsis;
  424. }
  425. .group_image {
  426. width: 200rpx;
  427. height: 200rpx;
  428. }
  429. .choose_image {
  430. display: block;
  431. width: 200rpx;
  432. height: 200rpx;
  433. font-size: 38rpx;
  434. text-align: center;
  435. line-height: 200rpx;
  436. border: 2rpx solid #dddddd;
  437. }
  438. }
  439. }
  440. .submit_btn {
  441. width: 700rpx;
  442. height: 80rpx;
  443. display: block;
  444. color: #ffffff;
  445. font-size: 30rpx;
  446. overflow: hidden;
  447. line-height: 80rpx;
  448. padding: 0rpx 0rpx;
  449. text-align: center;
  450. margin: 20rpx auto;
  451. margin-top: 40rpx;
  452. border-radius: 40rpx;
  453. background-color: #e03519;
  454. }
  455. }
  456. }
  457. </style>