address_edit.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. <template>
  2. <div class="box">
  3. <div class="null-page" v-show="yes"></div>
  4. <el-card class="box-card">
  5. <div slot="header" class="clearfix">
  6. <span>编辑收货地址</span>
  7. </div>
  8. <div v-loading="loading" class="ns-member-address-list">
  9. <el-form :model="formData" :rules="rules" ref="ruleForm" label-width="80px">
  10. <el-form-item label="姓名" prop="name">
  11. <el-input v-model="formData.name" placeholder="收货人姓名" class="ns-len-input"></el-input>
  12. </el-form-item>
  13. <el-form-item label="手机" prop="mobile">
  14. <el-input v-model="formData.mobile" autocomplete="off" placeholder="收货人手机号" class="ns-len-input"></el-input>
  15. </el-form-item>
  16. <el-form-item label="电话">
  17. <el-input v-model.trim="formData.telephone" autocomplete="off" placeholder="收货人固定电话(选填)"
  18. class="ns-len-input"></el-input>
  19. </el-form-item>
  20. <el-form-item label="地址" prop="full_address">
  21. <el-select :value="formData.province_id" placeholder="请选择省" @change="changeProvice">
  22. <el-option v-for="option in province" :key="option.id" :label="option.name" :value="option.id">
  23. {{ option.name }}</el-option>
  24. </el-select>
  25. <el-select :value="formData.city_id" placeholder="请选择市" @change="changeCity">
  26. <el-option v-for="option in city" :key="option.id" :label="option.name" :value="option.id">
  27. {{ option.name }}</el-option>
  28. </el-select>
  29. <el-select :value="formData.district_id" placeholder="请选择区/县"
  30. @change="changeDistrict">
  31. <el-option v-for="option in district" :key="option.id" :label="option.name" :value="option.id">
  32. {{ option.name }}</el-option>
  33. </el-select>
  34. </el-form-item>
  35. <el-form-item label="详细地址" prop="address">
  36. <el-input v-model.trim="formData.address" autocomplete="off" placeholder="定位到小区、街道、写字楼"
  37. class="ns-len-input"></el-input>
  38. </el-form-item>
  39. <el-form-item label="是否默认">
  40. <el-radio-group v-model="formData.is_default">
  41. <el-radio :label="1">是</el-radio>
  42. <el-radio :label="0">否</el-radio>
  43. </el-radio-group>
  44. </el-form-item>
  45. <el-form-item>
  46. <el-button type="primary" size="medium" @click="saveAddress('ruleForm')">保存</el-button>
  47. </el-form-item>
  48. </el-form>
  49. </div>
  50. </el-card>
  51. </div>
  52. </template>
  53. <script>
  54. import {
  55. addressInfo,
  56. saveAddress
  57. } from "@/api/member/member"
  58. import {
  59. getArea
  60. } from "@/api/address"
  61. export default {
  62. name: "address_edit",
  63. layout: "member",
  64. components: {},
  65. data() {
  66. let self = this
  67. var isMobile = (rule, value, callback) => {
  68. if (!value) {
  69. return callback(new Error("手机号不能为空"))
  70. } else {
  71. if (/^\d{11}$/.test(value)) {
  72. callback()
  73. } else {
  74. callback(new Error("请输入正确的手机号"))
  75. }
  76. }
  77. }
  78. var fullAddress = (rule, value, callback) => {
  79. if (self.formData.province_id) {
  80. if (self.formData.city_id) {
  81. if (self.district.length > 0) {
  82. if (self.formData.district_id) {
  83. return callback()
  84. } else {
  85. return callback(new Error("请选择区/县"))
  86. }
  87. } else {
  88. return callback()
  89. }
  90. } else {
  91. return callback(new Error("请选择市"))
  92. }
  93. } else {
  94. return callback(new Error("请选择省"))
  95. }
  96. }
  97. return {
  98. formData: {
  99. id: 0,
  100. name: "",
  101. mobile: "",
  102. telephone: "",
  103. province_id: "",
  104. city_id: "",
  105. district_id: "",
  106. community_id: "",
  107. address: "",
  108. full_address: "",
  109. latitude: 0,
  110. longitude: 0,
  111. is_default: 1
  112. },
  113. addressValue: "",
  114. flag: false, //防重复标识
  115. defaultRegions: [],
  116. rules: {
  117. name: [{
  118. required: true,
  119. message: "请输入收货人姓名",
  120. trigger: "blur"
  121. }],
  122. mobile: [{
  123. required: true,
  124. validator: isMobile,
  125. trigger: "blur"
  126. }],
  127. address: [{
  128. required: true,
  129. message: "请输入详细地址",
  130. trigger: "blur"
  131. }],
  132. full_address: [{
  133. required: true,
  134. validator: fullAddress,
  135. trigger: "blur"
  136. }]
  137. },
  138. province: [],
  139. city: [],
  140. district: [],
  141. pickerValueArray: [],
  142. multiIndex: [0, 0, 0],
  143. isInitMultiArray: false,
  144. // 是否加载完默认地区
  145. isLoadDefaultAreas: false,
  146. loading: true,
  147. yes: true
  148. }
  149. },
  150. created() {
  151. this.formData.id = this.$route.query.id
  152. this.getAddressDetail()
  153. this.getDefaultAreas(0, {
  154. level: 0
  155. })
  156. },
  157. mounted() {
  158. let self = this;
  159. setTimeout(function() {
  160. self.yes = false
  161. }, 300)
  162. },
  163. watch: {
  164. defaultRegions: {
  165. handler(arr, oldArr = []) {
  166. // 避免传的是字面量的时候重复触发
  167. if (arr.length !== 3 || arr.join("") === oldArr.join("")) return
  168. this.handleDefaultRegions()
  169. },
  170. immediate: true
  171. }
  172. },
  173. computed: {
  174. pickedArr() {
  175. // 进行初始化
  176. if (this.isInitMultiArray) {
  177. return [this.pickerValueArray[0], this.pickerValueArray[1], this.pickerValueArray[2]]
  178. }
  179. return [this.pickerValueArray[0], this.city, this.district]
  180. }
  181. },
  182. methods: {
  183. /**
  184. * 改变省
  185. */
  186. changeProvice(id) {
  187. this.formData.province_id = id;
  188. this.getAreas(id, data => (this.city = data))
  189. let obj = {}
  190. obj = this.province.find(item => {
  191. //这里的province就是上面遍历的数据源
  192. return item.id === id //筛选出匹配数据
  193. })
  194. this.formData.city_id = ""
  195. this.formData.district_id = ""
  196. this.formData.full_address = obj.name // 设置选中的地址
  197. },
  198. /**
  199. * 改变市
  200. */
  201. changeCity(id) {
  202. this.formData.city_id = id;
  203. this.getAreas(id, data => (this.district = data))
  204. let obj = {}
  205. obj = this.city.find(item => {
  206. //这里的province就是上面遍历的数据源
  207. return item.id === id //筛选出匹配数据
  208. })
  209. this.formData.district_id = ""
  210. this.formData.full_address = this.formData.full_address + "-" + obj.name
  211. },
  212. /**
  213. * 改变区
  214. */
  215. changeDistrict(id) {
  216. this.formData.district_id = id;
  217. let obj = {}
  218. obj = this.district.find(item => {
  219. //这里的province就是上面遍历的数据源
  220. return item.id === id //筛选出匹配数据
  221. })
  222. this.formData.full_address = this.formData.full_address + "-" + obj.name
  223. },
  224. /**
  225. * 获取地址信息
  226. */
  227. getAddressDetail() {
  228. addressInfo({
  229. id: this.formData.id
  230. })
  231. .then(res => {
  232. let data = res.data
  233. if (data != null) {
  234. this.formData.name = data.name
  235. this.formData.mobile = data.mobile
  236. this.formData.telephone = data.telephone
  237. this.formData.address = data.address
  238. this.formData.full_address = data.full_address
  239. this.formData.latitude = data.latitude
  240. this.formData.longitude = data.longitude
  241. this.formData.is_default = data.is_default
  242. this.formData.province_id = data.province_id
  243. this.formData.city_id = data.city_id
  244. this.formData.district_id = data.district_id
  245. this.defaultRegions = [data.province_id, data.city_id, data.district_id]
  246. }
  247. })
  248. .catch(err => {})
  249. },
  250. // 异步获取地区
  251. getAreas(pid, callback) {
  252. getArea({
  253. pid: pid
  254. })
  255. .then(res => {
  256. if (res.code == 0) {
  257. var data = []
  258. res.data.forEach((item, index) => {
  259. data.push(item)
  260. })
  261. if (callback) callback(data)
  262. }
  263. })
  264. .catch(err => {})
  265. },
  266. /**
  267. * 获取省市区列表
  268. */
  269. getDefaultAreas(pid, obj) {
  270. getArea({
  271. pid: pid
  272. })
  273. .then(res => {
  274. if (res.code == 0) {
  275. var data = []
  276. var selected = undefined
  277. res.data.forEach((item, index) => {
  278. if (obj != undefined) {
  279. if (obj.level == 0 && obj.province_id != undefined) {
  280. selected = obj.province_id
  281. } else if (obj.level == 1 && obj.city_id != undefined) {
  282. selected = obj.city_id
  283. } else if (obj.level == 2 && obj.district_id != undefined) {
  284. selected = obj.district_id
  285. }
  286. }
  287. if (selected == undefined && index == 0) {
  288. selected = item.id
  289. }
  290. data.push(item)
  291. })
  292. this.pickerValueArray[obj.level] = data
  293. if (obj.level + 1 < 3) {
  294. obj.level++
  295. this.getDefaultAreas(selected, obj)
  296. } else {
  297. this.isInitMultiArray = true
  298. this.isLoadDefaultAreas = true
  299. }
  300. this.province = this.pickerValueArray[0]
  301. }
  302. setTimeout(() => {
  303. this.loading = false
  304. }, 500)
  305. })
  306. .catch(err => {
  307. this.loading = false
  308. })
  309. },
  310. /**
  311. * 渲染默认值
  312. */
  313. handleDefaultRegions() {
  314. var time = setInterval(() => {
  315. if (!this.isLoadDefaultAreas) return
  316. this.isInitMultiArray = false
  317. for (let i = 0; i < this.defaultRegions.length; i++) {
  318. for (let j = 0; j < this.pickerValueArray[i].length; j++) {
  319. this.province = this.pickerValueArray[0]
  320. // 匹配省
  321. if (this.defaultRegions[i] == this.pickerValueArray[i][j].id) {
  322. // 设置选中省
  323. this.$set(this.multiIndex, i, j)
  324. // 查询市
  325. this.getAreas(this.pickerValueArray[i][j].id, data => {
  326. this.city = data
  327. for (let k = 0; k < this.city.length; k++) {
  328. if (this.defaultRegions[1] == this.city[k].id) {
  329. // 设置选中市
  330. this.$set(this.multiIndex, 1, k)
  331. // 查询区县
  332. this.getAreas(this.city[k].id, data => {
  333. this.district = data
  334. // 设置选中区县
  335. for (let u = 0; u < this.district.length; u++) {
  336. if (this.defaultRegions[2] == this.district[u].id) {
  337. this.$set(this.multiIndex, 2, u)
  338. this.handleValueChange({
  339. detail: {
  340. value: [j, k, u]
  341. }
  342. })
  343. break
  344. }
  345. }
  346. })
  347. break
  348. }
  349. }
  350. })
  351. }
  352. }
  353. }
  354. if (this.isLoadDefaultAreas) clearInterval(time)
  355. }, 100)
  356. },
  357. handleValueChange(e) {
  358. // 结构赋值
  359. let [index0, index1, index2] = e.detail.value
  360. let [arr0, arr1, arr2] = this.pickedArr
  361. let address = [arr0[index0], arr1[index1], arr2[index2]]
  362. this.formData.full_address = ""
  363. for (let i = 0; i < address.length; i++) {
  364. if (this.formData.full_address) {
  365. this.formData.full_address = this.formData.full_address + "-" + address[i].name
  366. } else {
  367. this.formData.full_address = this.formData.full_address + address[i].name
  368. }
  369. }
  370. },
  371. /**
  372. * 保存地址
  373. */
  374. saveAddress(formName) {
  375. this.$refs[formName].validate(valid => {
  376. if (valid) {
  377. var data = {
  378. name: this.formData.name,
  379. mobile: this.formData.mobile,
  380. telephone: this.formData.telephone,
  381. province_id: this.formData.province_id,
  382. city_id: this.formData.city_id,
  383. district_id: this.formData.district_id,
  384. community_id: "",
  385. address: this.formData.address,
  386. full_address: this.formData.full_address,
  387. latitude: this.formData.latitude,
  388. longitude: this.formData.longitude,
  389. is_default: this.formData.is_default
  390. }
  391. data.url = "add"
  392. if (this.formData.id) {
  393. data.url = "edit"
  394. data.id = this.formData.id
  395. }
  396. if (this.flag) return
  397. this.flag = true
  398. saveAddress(data)
  399. .then(res => {
  400. if (res.code == 0) {
  401. this.$router.push({
  402. path: "/member/delivery_address"
  403. })
  404. } else {
  405. this.flag = false
  406. this.$message({
  407. message: res.message,
  408. type: "warning"
  409. })
  410. }
  411. })
  412. .catch(err => {
  413. this.flag = false
  414. this.$message.error(err.message)
  415. })
  416. } else {
  417. return false
  418. }
  419. })
  420. }
  421. }
  422. }
  423. </script>
  424. <style lang="scss" scoped>
  425. .box {
  426. width: 100%;
  427. position: relative;
  428. }
  429. .null-page {
  430. width: 100%;
  431. height: 730px;
  432. background-color: #FFFFFF;
  433. position: absolute;
  434. top: 0;
  435. left: 0;
  436. z-index: 9;
  437. }
  438. .el-card.is-always-shadow,
  439. .el-card.is-hover-shadow:focus,
  440. .el-card.is-hover-shadow:hover {
  441. box-shadow: unset;
  442. }
  443. .el-card {
  444. border: 0;
  445. }
  446. .ns-len-input {
  447. width: 350px;
  448. }
  449. .el-select {
  450. margin-right: 10px;
  451. }
  452. </style>