edit.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <template>
  2. <nut-form :model-value="formData" ref="ruleForm">
  3. <nut-form-item label="联系人" prop="name"
  4. required
  5. :rules="[{ required: true, message: '请填写姓名' }]">
  6. <nut-input class="nut-input-text" @blur="customBlurValidate('name')"
  7. v-model="formData.name"
  8. placeholder="请输入姓名" type="text"/>
  9. </nut-form-item>
  10. <nut-form-item label="手机号码" prop="phone" required :rules="[
  11. { required: true, message: '请填写联系电话' },
  12. { validator: asyncValidator, message: '电话格式不正确' }
  13. ]">
  14. <nut-input class="nut-input-text" v-model="formData.phone" placeholder="请填写手机号码" type="text"/>
  15. </nut-form-item>
  16. <nut-form-item label="收货地址"
  17. required
  18. prop="address"
  19. :rules="[{ required: true, message: '请选择收货地址' }]"
  20. >
  21. <div class="nut-input-text"
  22. @click="addressData.visible = true"
  23. >
  24. {{ formData.address.toString() === '' ? '省市区县、省镇等' : formData.address.toString() }}
  25. </div>
  26. <nut-cascader
  27. title="地址选择"
  28. v-model:visible="addressData.visible"
  29. v-model="formData.address"
  30. @change="change"
  31. @pathChange="pathChange"
  32. valueKey="name"
  33. text-key="name"
  34. labelKey="id"
  35. childrenKey="children"
  36. :options="addressData.options"
  37. lazy
  38. :lazyLoad="addressData.lazyLoad"
  39. ></nut-cascader>
  40. </nut-form-item>
  41. <nut-form-item label="详细地址" prop="detail" required :rules="[{ required: true, message: '请填写详细地址' }]">
  42. <nut-input class="nut-input-text" v-model="formData.detail" placeholder="街道、楼牌号等" type="text"/>
  43. </nut-form-item>
  44. <div class="p-4">
  45. <div class="flex items-center justify-between">
  46. <div class="flex flex-col gap-2">
  47. <div>设置为默认地址</div>
  48. <div class="text-xs text-gray">提醒:下单会优先使用该地址</div>
  49. </div>
  50. <nut-switch v-model="formData.is_default"></nut-switch>
  51. </div>
  52. </div>
  53. <div class="fixed bottom-0 p-safe w-full ">
  54. <div class="px-3 flex flex-col gap-3">
  55. <nut-button block type="primary" @click="submit">保存</nut-button>
  56. <nut-button block type="default" @click="handleDelete">删除</nut-button>
  57. </div>
  58. </div>
  59. </nut-form>
  60. </template>
  61. <script setup lang="ts">
  62. import {reactive, ref} from "vue";
  63. import {decodeBase64} from "~/utils/http/helper";
  64. // import {FormItemRuleWithoutValidator} from "uniapp-nutui";
  65. import {addressNewCreate, deleteAddress, getCityNewFiveList} from "~/apis/user";
  66. import type {AddressModel} from "~/apis/model/address.model";
  67. import type {FormItemRuleWithoutValidator} from "nutui-uniapp";
  68. import {useAddressStore} from "~/stores/addressStore";
  69. const addressStore = useAddressStore()
  70. const formData = reactive({
  71. uid: '',
  72. address_id: '',
  73. name: '',
  74. detail: '',
  75. phone: '',
  76. address: [],
  77. is_default: false,
  78. // village: '',
  79. // village_id: '',
  80. code_list: ''
  81. });
  82. const basicData = reactive({
  83. addressObject: [],
  84. isDefaultVal: true,
  85. province: '',
  86. provinceId: '',
  87. city: '',
  88. cityId: '',
  89. country: '',
  90. countryId: '',
  91. // 街道
  92. // village: '',
  93. // villageId: '',
  94. // code_list: ''
  95. });
  96. onLoad((options) => {
  97. // console.log(options.data)
  98. // const base64Data = 'eyJhZGRyZXNzX2lkIjoiMjQzIiwidWlkIjoiOTkyOSIsInJlYWxfbmFtZSI6IkhFTExPIiwicGhvbmUiOiIxMzQ4ODY4OTg4NSIsInByb3ZpbmNlIjoi5YyX5LqsIiwiY2l0eSI6IuWMl+S6rOW4giIsImNpdHlfaWQiOiIyIiwiZGlzdHJpY3QiOiLpobrkuYnljLoiLCJ2aWxsYWdlIjoi5ruo5rKz5bCP5Yy656ys5LiA56S+5Yy65bGF5rCR5aeU5ZGY5LyaIiwidmlsbGFnZV9pZCI6Ijc2NjczIiwiZGV0YWlsIjoiMTExMSIsInBvc3RfY29kZSI6IjAiLCJsb25naXR1ZGUiOiIwIiwibGF0aXR1ZGUiOiIwIiwiaXNfZGVmYXVsdCI6IjEiLCJpc19kZWwiOiIwIiwiY3JlYXRlX3RpbWUiOiIyMDIzLTA5LTA0IDE4OjI3OjAzIiwiY29kZV9saXN0IjoiMSw2NzQ0OSwzNSw0OTMifQ'
  99. // if (options.data) {j
  100. const data: AddressModel = JSON.parse(decodeBase64(options.data))
  101. // const data: AddressModel = JSON.parse(decodeBase64(base64Data))
  102. if (data) {
  103. formData.address_id = data.address_id
  104. formData.uid = data.uid
  105. formData.name = data.real_name
  106. formData.phone = data.phone
  107. formData.detail = data.detail
  108. // console.log(data.province)
  109. formData.address = [data.province, data.city, data.district, data.village]
  110. // console.log(formData.address)
  111. formData.is_default = data.is_default === '1'
  112. formData.code_list = data.code_list
  113. formData.village = data.village
  114. formData.village_id = data.village_id
  115. }
  116. // }
  117. })
  118. const addressData = reactive({
  119. visible: false,
  120. // value: ['北京'],
  121. options: [
  122. // { value: '北京', text: '北京', id: 1, pid: null },
  123. ],
  124. lazyLoad(node: any, resolve: (children: any) => void) {
  125. // const {pid, id} = node
  126. getCityNewFiveList(node.id).then(res => {
  127. resolve(res)
  128. })
  129. }
  130. })
  131. const customBlurValidate = (prop: string) => {
  132. ruleForm.value.validate(prop).then(({valid, errors}: any) => {
  133. if (valid) {
  134. console.log('success', formData);
  135. } else {
  136. console.log('error submit!!', errors);
  137. }
  138. });
  139. };
  140. // 函数校验
  141. const customValidator = (val: string) => /^\d+$/.test(val);
  142. const customRulePropValidator = (val: string, rule: FormItemRuleWithoutValidator) => {
  143. return (rule?.reg as RegExp).test(val);
  144. };
  145. const nameLengthValidator = (val: string) => val?.length >= 2;
  146. // Promise 异步校验
  147. const asyncValidator = (val: string) => {
  148. return new Promise((resolve) => {
  149. // console.log('模拟异步验证中...');
  150. setTimeout(() => {
  151. // console.log('验证完成');
  152. resolve(/^400(-?)[0-9]{7}$|^1\d{10}$|^0[0-9]{2,3}-[0-9]{7,8}$/.test(val));
  153. }, 1000);
  154. });
  155. };
  156. const ruleForm = ref<any>(null);
  157. function change(...args: any) {
  158. basicData.addressObject = args[1]
  159. }
  160. function pathChange(...args: any) {
  161. console.log('pathChange', ...args);
  162. }
  163. const submit = () => {
  164. ruleForm.value.validate().then(({valid, errors}: any) => {
  165. if (valid) {
  166. console.log('success', formData);
  167. const province = formData.address[0]
  168. const city = formData.address[1]
  169. const district = formData.address[2]
  170. // const village = formData.address[3]
  171. let provinceId = ''
  172. let cityId = ''
  173. let districtId = ''
  174. let countryId = ''
  175. let villageId = ''
  176. let village = ''
  177. // const province =
  178. // let code_list = ''
  179. if (basicData.addressObject.length > 0) {
  180. console.log(basicData.addressObject)
  181. provinceId = basicData.addressObject[0].id
  182. cityId = basicData.addressObject[1].id
  183. districtId = basicData.addressObject[2].id
  184. countryId = basicData.addressObject[3].id
  185. if (formData.address[3]) {
  186. // codeList = mProvinceId + "," + mCityId + "," + mCountyId + "," + mVillageId;
  187. formData.code_list = provinceId + ',' + cityId + ',' + districtId + ',' + countryId
  188. } else {
  189. formData.code_list = provinceId + ',' + cityId + ',' + districtId
  190. }
  191. if (formData.address[4]) {
  192. formData.viilage_id = basicData.addressObject[4].id
  193. formData.village = basicData.addressObject[4].value
  194. }
  195. }
  196. addressNewCreate({
  197. province,
  198. city,
  199. district,
  200. is_default: formData.is_default ? '1' : '0',
  201. phone: formData.phone,
  202. real_name: formData.name,
  203. detail: formData.detail,
  204. code_list: formData.code_list,
  205. // city_id: '2',
  206. city_id: cityId,
  207. village_id: formData.village_id,
  208. village: formData.village,
  209. address_id: formData.address_id
  210. }).then(res => {
  211. // console.log(res)
  212. if (res) {
  213. uni.showToast({
  214. title: '保存成功'
  215. })
  216. addressStore.setCurrentAddressId(res.address_id)
  217. setTimeout(() => {
  218. // uni.redirectTo({
  219. // url: '/pages/user/address/index'
  220. // })
  221. uni.navigateBack()
  222. }, 500)
  223. }
  224. }).catch(message => {
  225. console.log(message)
  226. uni.showToast({
  227. icon: "none",
  228. title: message
  229. })
  230. })
  231. // formData.address
  232. console.log(formData.address.length)
  233. } else {
  234. console.log('error submit!!', errors);
  235. }
  236. });
  237. };
  238. function handleDelete() {
  239. if (formData && formData.address_id) {
  240. uni.showModal({
  241. title: '温馨提示',
  242. content: '是否删除该地址',
  243. success: function (res) {
  244. if (res.confirm) {
  245. deleteAddress(formData.address_id).then(res => {
  246. uni.showToast({
  247. title: '删除成功',
  248. icon: 'none'
  249. })
  250. setTimeout(() => {
  251. uni.redirectTo({
  252. url: '/pages/user/address/index'
  253. })
  254. }, 500)
  255. }).catch(error => {
  256. uni.showToast({
  257. title: error,
  258. icon: 'none'
  259. })
  260. })
  261. }
  262. }
  263. })
  264. }
  265. }
  266. </script>
  267. <route lang="yaml">
  268. style:
  269. navigationBarTitleText: 收货地址
  270. </route>