瀏覽代碼

feat: fix

Basil 2 年之前
父節點
當前提交
c021a0edbd

+ 30 - 30
components.d.ts

@@ -40,36 +40,36 @@ declare module '@vue/runtime-core' {
40 40
     FTabs: typeof import('./src/components/FTabs/FTabs.vue')['default']
41 41
     FTag: typeof import('./src/components/FTag/FTag.vue')['default']
42 42
     FTransition: typeof import('./src/components/FTransition/FTransition.vue')['default']
43
-    NutButton: typeof import('uniapp-nutui/components/button/button.vue')['default']
44
-    NutCalendar: typeof import('uniapp-nutui/components/calendar/calendar.vue')['default']
45
-    NutCascader: typeof import('uniapp-nutui/components/cascader/cascader.vue')['default']
46
-    NutCell: typeof import('uniapp-nutui/components/cell/cell.vue')['default']
47
-    NutCellGroup: typeof import('uniapp-nutui/components/cellgroup/cellgroup.vue')['default']
48
-    NutCheckbox: typeof import('uniapp-nutui/components/checkbox/checkbox.vue')['default']
49
-    NutDatePicker: typeof import('uniapp-nutui/components/datepicker/datepicker.vue')['default']
50
-    NutDialog: typeof import('uniapp-nutui/components/dialog/dialog.vue')['default']
51
-    NutForm: typeof import('uniapp-nutui/components/form/form.vue')['default']
52
-    NutFormItem: typeof import('uniapp-nutui/components/formitem/formitem.vue')['default']
53
-    NutIcon: typeof import('uniapp-nutui/components/icon/icon.vue')['default']
54
-    NutInput: typeof import('uniapp-nutui/components/input/input.vue')['default']
55
-    NutInputNumber: typeof import('uniapp-nutui/components/inputnumber/inputnumber.vue')['default']
56
-    NutMenu: typeof import('uniapp-nutui/components/menu/menu.vue')['default']
57
-    NutMenuItem: typeof import('uniapp-nutui/components/menuitem/menuitem.vue')['default']
58
-    NutNoticebar: typeof import('uniapp-nutui/components/noticebar/noticebar.vue')['default']
59
-    NutOverlay: typeof import('uniapp-nutui/components/overlay/overlay.vue')['default']
60
-    NutPicker: typeof import('uniapp-nutui/components/picker/picker.vue')['default']
61
-    NutPopup: typeof import('uniapp-nutui/components/popup/popup.vue')['default']
62
-    NutRadio: typeof import('uniapp-nutui/components/radio/radio.vue')['default']
63
-    NutRadioGroup: typeof import('uniapp-nutui/components/radiogroup/radiogroup.vue')['default']
64
-    NutRate: typeof import('uniapp-nutui/components/rate/rate.vue')['default']
65
-    NutSearchbar: typeof import('uniapp-nutui/components/searchbar/searchbar.vue')['default']
66
-    NutStep: typeof import('uniapp-nutui/components/step/step.vue')['default']
67
-    NutSteps: typeof import('uniapp-nutui/components/steps/steps.vue')['default']
68
-    NutSwitch: typeof import('uniapp-nutui/components/switch/switch.vue')['default']
69
-    NutTable: typeof import('uniapp-nutui/components/table/table.vue')['default']
70
-    NutTabPane: typeof import('uniapp-nutui/components/tabpane/tabpane.vue')['default']
71
-    NutTabs: typeof import('uniapp-nutui/components/tabs/tabs.vue')['default']
72
-    NutUploader: typeof import('uniapp-nutui/components/uploader/uploader.vue')['default']
43
+    NutButton: typeof import('nutui-uniapp/components/button/button.vue')['default']
44
+    NutCalendar: typeof import('nutui-uniapp/components/calendar/calendar.vue')['default']
45
+    NutCascader: typeof import('nutui-uniapp/components/cascader/cascader.vue')['default']
46
+    NutCell: typeof import('nutui-uniapp/components/cell/cell.vue')['default']
47
+    NutCellGroup: typeof import('nutui-uniapp/components/cellgroup/cellgroup.vue')['default']
48
+    NutCheckbox: typeof import('nutui-uniapp/components/checkbox/checkbox.vue')['default']
49
+    NutDatePicker: typeof import('nutui-uniapp/components/datepicker/datepicker.vue')['default']
50
+    NutDialog: typeof import('nutui-uniapp/components/dialog/dialog.vue')['default']
51
+    NutForm: typeof import('nutui-uniapp/components/form/form.vue')['default']
52
+    NutFormItem: typeof import('nutui-uniapp/components/formitem/formitem.vue')['default']
53
+    NutIcon: typeof import('nutui-uniapp/components/icon/icon.vue')['default']
54
+    NutInput: typeof import('nutui-uniapp/components/input/input.vue')['default']
55
+    NutInputNumber: typeof import('nutui-uniapp/components/inputnumber/inputnumber.vue')['default']
56
+    NutMenu: typeof import('nutui-uniapp/components/menu/menu.vue')['default']
57
+    NutMenuItem: typeof import('nutui-uniapp/components/menuitem/menuitem.vue')['default']
58
+    NutNoticebar: typeof import('nutui-uniapp/components/noticebar/noticebar.vue')['default']
59
+    NutOverlay: typeof import('nutui-uniapp/components/overlay/overlay.vue')['default']
60
+    NutPicker: typeof import('nutui-uniapp/components/picker/picker.vue')['default']
61
+    NutPopup: typeof import('nutui-uniapp/components/popup/popup.vue')['default']
62
+    NutRadio: typeof import('nutui-uniapp/components/radio/radio.vue')['default']
63
+    NutRadioGroup: typeof import('nutui-uniapp/components/radiogroup/radiogroup.vue')['default']
64
+    NutRate: typeof import('nutui-uniapp/components/rate/rate.vue')['default']
65
+    NutSearchbar: typeof import('nutui-uniapp/components/searchbar/searchbar.vue')['default']
66
+    NutStep: typeof import('nutui-uniapp/components/step/step.vue')['default']
67
+    NutSteps: typeof import('nutui-uniapp/components/steps/steps.vue')['default']
68
+    NutSwitch: typeof import('nutui-uniapp/components/switch/switch.vue')['default']
69
+    NutTable: typeof import('nutui-uniapp/components/table/table.vue')['default']
70
+    NutTabPane: typeof import('nutui-uniapp/components/tabpane/tabpane.vue')['default']
71
+    NutTabs: typeof import('nutui-uniapp/components/tabs/tabs.vue')['default']
72
+    NutUploader: typeof import('nutui-uniapp/components/uploader/uploader.vue')['default']
73 73
     ProductCard: typeof import('./src/components/ProductCard/ProductCard.vue')['default']
74 74
     ProductList: typeof import('./src/components/ProductList/ProductList.vue')['default']
75 75
     SignInGiftBag: typeof import('./src/components/CXBDialogSignIn/SignInGiftBag.vue')['default']

+ 1 - 1
package.json

@@ -59,9 +59,9 @@
59 59
     "less": "^4.2.0",
60 60
     "lodash-es": "^4.17.21",
61 61
     "mp-html": "^2.4.2",
62
+    "nutui-uniapp": "^1.1.8",
62 63
     "pinia": "^2.0.36",
63 64
     "sass": "^1.64.2",
64
-    "uniapp-nutui": "^0.2.5",
65 65
     "vue": "^3.3.4",
66 66
     "vue-i18n": "^9.2.2"
67 67
   },

+ 14 - 12
pnpm-lock.yaml

@@ -61,15 +61,15 @@ dependencies:
61 61
   mp-html:
62 62
     specifier: ^2.4.2
63 63
     version: 2.4.2
64
+  nutui-uniapp:
65
+    specifier: ^1.1.8
66
+    version: 1.1.8(@uni-helper/uni-app-types@0.5.8)(vue@3.3.4)
64 67
   pinia:
65 68
     specifier: ^2.0.36
66 69
     version: 2.0.36(typescript@5.1.6)(vue@3.3.4)
67 70
   sass:
68 71
     specifier: ^1.64.2
69 72
     version: 1.64.2
70
-  uniapp-nutui:
71
-    specifier: ^0.2.5
72
-    version: 0.2.5(vue@3.3.4)
73 73
   vue:
74 74
     specifier: ^3.3.4
75 75
     version: 3.3.4
@@ -3897,7 +3897,6 @@ packages:
3897 3897
       '@dcloudio/types': 3.3.3
3898 3898
       typescript: 5.1.6
3899 3899
       vue3: /vue@3.3.4
3900
-    dev: true
3901 3900
 
3902 3901
   /@uni-helper/uni-env@0.0.3:
3903 3902
     resolution: {integrity: sha512-K6MEnmN7Dg+NnEkfUUhjaKc/rPVY7tcGdsVUKOlC1/z2E6H6zjSSTdJg8z+sVJtZ03Ff1G/MHz2PYDyAS6gjQQ==}
@@ -7727,6 +7726,17 @@ packages:
7727 7726
       boolbase: 1.0.0
7728 7727
     dev: true
7729 7728
 
7729
+  /nutui-uniapp@1.1.8(@uni-helper/uni-app-types@0.5.8)(vue@3.3.4):
7730
+    resolution: {integrity: sha512-mJsPnj4TcJHWaZ22fDoLVv9iW0TcR1zZrI0cBVsDoWIWOGKaF4zY3QMeCB73Za8PZvaJCIsgvzqHch2yNkyb6g==}
7731
+    engines: {HBuilderX: ^3.6.17}
7732
+    peerDependencies:
7733
+      '@uni-helper/uni-app-types': ^0.5.10
7734
+      vue: ^3.2.0
7735
+    dependencies:
7736
+      '@uni-helper/uni-app-types': 0.5.8(typescript@5.1.6)
7737
+      vue: 3.3.4
7738
+    dev: false
7739
+
7730 7740
   /nwsapi@2.2.7:
7731 7741
     resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==}
7732 7742
     dev: true
@@ -9129,14 +9139,6 @@ packages:
9129 9139
       - '@swc/helpers'
9130 9140
     dev: true
9131 9141
 
9132
-  /uniapp-nutui@0.2.5(vue@3.3.4):
9133
-    resolution: {integrity: sha512-AiiFXuJlWyRecP4oDgscQFCv8PC/gEiDzUNFU7mxvPWke20cr+yq2kPN50e555mORd7bWxbzvAdodF7D5hV6sA==}
9134
-    peerDependencies:
9135
-      vue: ^3.2.0
9136
-    dependencies:
9137
-      vue: 3.3.4
9138
-    dev: false
9139
-
9140 9142
   /unicode-canonical-property-names-ecmascript@2.0.0:
9141 9143
     resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==}
9142 9144
     engines: {node: '>=4'}

+ 1 - 1
src/App.vue

@@ -15,5 +15,5 @@ onHide(() => {
15 15
 });
16 16
 </script>
17 17
 <style lang="scss">
18
-@import 'uniapp-nutui/styles/index';
18
+@import 'nutui-uniapp/styles/index';
19 19
 </style>

文件差異過大導致無法顯示
+ 1 - 1
src/pages.json


+ 1 - 1
src/pages/home/index.vue

@@ -162,7 +162,7 @@ page {
162 162
   background-color: #f8f8f8;
163 163
 }
164 164
 </style>
165
-<route lang="yaml" type="home">
165
+<route lang="yaml"  type="home">
166 166
 style:
167 167
   navigationStyle: custom
168 168
   navigationBarTitleText: 储蓄保

+ 4 - 0
src/pages/my-integral/user-invation.vue

@@ -87,9 +87,13 @@ function handleShowCode() {
87 87
 }
88 88
 
89 89
 function shareWeixin() {
90
+  uni.showLoading({
91
+    title: '数据加载中'
92
+  })
90 93
   wx.downloadFile({
91 94
     url: spreadData.value.wap_poster,
92 95
     success: (res) => {
96
+      uni.hideLoading()
93 97
       wx.showShareImageMenu({
94 98
         path: res.tempFilePath
95 99
       })

+ 11 - 4
src/pages/order-confirm/index.vue

@@ -32,7 +32,7 @@ const data = reactive({
32 32
   // 商品总价?
33 33
   // proPrice: ''
34 34
 })
35
-onLoad((options) => {
35
+onLoad(async (options) => {
36 36
 
37 37
   if (options && options.type) {
38 38
     data.type = options.type
@@ -55,9 +55,16 @@ onLoad((options) => {
55 55
   //     data.addressId = res.list.length > 0 ? res.list[0].address_id : '0'
56 56
   //   })
57 57
   // }
58
-  addressStore.getCurrentAddress()
59
-  data.addressInfo = addressStore.address
60
-  data.addressId = addressStore.address.address_id
58
+  const res = await getUserAddressList()
59
+  if (res.list && res.list.length > 0) {
60
+    data.addressInfo = res.list[0]
61
+    data.addressId = res.list[0].address_id
62
+  }
63
+  // await addressStore.getCurrentAddress()
64
+  // console.log(addressStore.address)
65
+  // data.addressInfo = addressStore.address
66
+  // data.addressId = addressStore.address.address_id
67
+  // console.log(  data.addressId )
61 68
 
62 69
   // console.log(addressStore.address)
63 70
   /// 查看用户VIP信息

+ 18 - 12
src/pages/order/components/OtherOrderItem.vue

@@ -4,6 +4,7 @@ import dayjs from "dayjs";
4 4
 import {getProductDetail} from "~/apis/product";
5 5
 import {handleProductItemClick} from "~/utils/product-page";
6 6
 import {encodeBase64} from "~/utils/http/helper";
7
+
7 8
 const props = defineProps({
8 9
   item: {
9 10
     type: Object,
@@ -32,12 +33,14 @@ const sourceType = computed(() => {
32 33
     }
33 34
   }
34 35
 })
36
+
35 37
 function navigateToDetail(params) {
36 38
   let otherDetailUrl = `/pages/store/product/other`
37 39
   return uni.navigateTo({
38 40
     url: `${otherDetailUrl}?params=${params}`
39 41
   })
40 42
 }
43
+
41 44
 function handleClick() {
42 45
   // uni.navigateTo({
43 46
   //   url: '/pages/'
@@ -50,15 +53,17 @@ function handleClick() {
50 53
   // })
51 54
   console.log(product)
52 55
   // if (product.source == '6') {
53
-    navigateToDetail(encodeBase64({
54
-      platform: product.source,
55
-      id: product.goods_id,
56
-      title: product.goods_name,
57
-      featured: [product.goods_img],
58
-      allowance: product.commission,
59
-      price: product.goods_price,
60
-      salePrice: product.pay_money,
61
-    }))
56
+  const productId = props.item.source == '1' ? product.goods_sign : product.goods_id
57
+  navigateToDetail(encodeBase64({
58
+    platform: product.source,
59
+    // id: product.goods_id,
60
+    id: productId,
61
+    title: product.goods_name,
62
+    featured: [product.goods_img],
63
+    allowance: product.commission,
64
+    price: product.goods_price,
65
+    salePrice: product.pay_money,
66
+  }))
62 67
   // }
63 68
 }
64 69
 
@@ -71,7 +76,7 @@ function handleClick() {
71 76
       <div class="text-primary">{{ item.other_status_desc }}</div>
72 77
     </div>
73 78
 
74
-    <div class="flex  gap-2"  @tap.stop="handleClick">
79
+    <div class="flex  gap-2" @tap.stop="handleClick">
75 80
       <div class="flex">
76 81
         <image :src="item.goods_img" mode="widthFix" class="w-16 h-16 rounded"></image>
77 82
 
@@ -90,11 +95,12 @@ function handleClick() {
90 95
     </div>
91 96
     <div class="flex justify-between text-[11px] items-center gap-2 f-hairline-bottom py-3">
92 97
       <div class="flex">
93
-        {{ dayjs(item.create_time).format('YYYY-MM-DD')}}
98
+        {{ dayjs(item.create_time).format('YYYY-MM-DD') }}
94 99
       </div>
95 100
       <div class="flex justify-center items-center gap-2">
96 101
         <div class="flex items-center">
97
-          预估养老金:<FPrice :price="item.yanlao"></FPrice>
102
+          预估养老金:
103
+          <FPrice :price="item.yanlao"></FPrice>
98 104
         </div>
99 105
         <div class="border border-solid border-1px border-gray-500 text-gray rounded px-1">{{ item.status_name }}</div>
100 106
       </div>

+ 16 - 17
src/pages/order/test.json

@@ -1,22 +1,21 @@
1 1
 {
2 2
   "status": 200,
3
-  "message": "success",
3
+  "message": "添加成功",
4 4
   "data": {
5
-    "wechat_user_id": "oGtg_6IyBcvYku_Q10x-N7__K2gQ",
6
-    "card_id": "",
7
-    "ali_user_id": "0",
8
-    "annuity_frozen": "0.00",
9
-    "annuity_num": "3",
10
-    "annuity": "0.07",
11
-    "create_time": "2023-08-30 11:27:09",
12
-    "birthday": "2023-09-21",
13
-    "birthday60": "未实名认证",
14
-    "card_number": null,
15
-    "annuity_yiqu": "0.00",
16
-    "pay_price": "14611.79",
17
-    "can_withdraw": 0,
18
-    "is_certification": 0,
19
-    "yinghang": "中信公证处消费养老金账户",
20
-    "add_up": 0
5
+    "address_id": "315",
6
+    "real_name": "TTT",
7
+    "phone": "13488689885",
8
+    "province": "重庆",
9
+    "city": "重庆郊县",
10
+    "city_id": "2",
11
+    "district": "奉节县",
12
+    "village": "",
13
+    "village_id": "",
14
+    "detail": "1111",
15
+    "post_code": "",
16
+    "is_default": "0",
17
+    "code_list": "2,69000,69124,71653",
18
+    "uid": "395",
19
+    "create_time": "2023-09-22 21:53:45"
21 20
   }
22 21
 }

+ 2 - 0
src/pages/store/product/other.vue

@@ -99,6 +99,8 @@ function loadProductDetail(product: Partial<IProductDetail>) {
99 99
         ...res
100 100
         // allowance:
101 101
       })
102
+
103
+      console.log(res)
102 104
       if (res.coupon_start_time > 0) {
103 105
         mergeProductDetail({
104 106
           coupon: {

+ 404 - 0
src/pages/user/address/create-4-level.vue

@@ -0,0 +1,404 @@
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
+
11
+    <nut-form-item label="手机号码" prop="phone" required :rules="[
12
+      { required: true, message: '请填写联系电话' },
13
+      { validator: asyncValidator, message: '电话格式不正确' }
14
+    ]">
15
+      <nut-input class="nut-input-text" v-model="formData.phone" placeholder="请填写手机号码" type="text" />
16
+    </nut-form-item>
17
+    <nut-form-item label="收货地址"
18
+                   required
19
+                   prop="address"
20
+                   :rules="[{ required: true, message: '请选择收货地址' }]"
21
+    >
22
+      <div class="nut-input-text"
23
+           @click="addressData.visible = true"
24
+      >
25
+        {{formData.address.toString() === '' ? '省市区县、省镇等' : formData.address.toString()}}
26
+      </div>
27
+
28
+
29
+      <nut-cascader
30
+          title="地址选择"
31
+          v-model:visible="addressData.visible"
32
+          v-model="formData.address"
33
+          @change="events.change"
34
+          @pathChange="events.pathChange"
35
+          valueKey="name"
36
+          text-key="name"
37
+          labelKey="name"
38
+          childrenKey="children"
39
+          :options="addressData.options"
40
+
41
+      ></nut-cascader>
42
+    </nut-form-item>
43
+    <nut-form-item label="详细地址" prop="detail" required :rules="[{ required: true, message: '请填写详细地址' }]">
44
+      <nut-input class="nut-input-text" v-model="formData.detail" placeholder="街道、楼牌号等" type="text" />
45
+    </nut-form-item>
46
+    <div class="p-4">
47
+      <div class="flex  items-center justify-between">
48
+        <div class="flex flex-col gap-2">
49
+          <div>设置为默认地址</div>
50
+          <div class="text-xs text-gray">提醒:下单会优先使用该地址</div>
51
+        </div>
52
+          <nut-switch v-model="formData.is_default"></nut-switch>
53
+
54
+      </div>
55
+    </div>
56
+
57
+    <div class="fixed bottom-0 p-safe w-full ">
58
+      <div class="px-3" v-if="state.isNew">
59
+        <nut-button block type="primary" @click="submit">保存</nut-button>
60
+      </div>
61
+
62
+      <div class="px-3 flex flex-col gap-3" v-else>
63
+        <nut-button block type="primary" @click="submit">保存</nut-button>
64
+        <nut-button block type="default" @click="handleDelete">删除</nut-button>
65
+      </div>
66
+    </div>
67
+  </nut-form>
68
+</template>
69
+<script lang="ts">
70
+import { ref,reactive } from 'vue';
71
+import type {FormItemRuleWithoutValidator} from "uniapp-nutui";
72
+import {addressNewCreate, deleteAddress, getCityList, getCityNewFiveList, getUserAddressDetail} from "~/apis/user";
73
+import FSwitch from "~/components/FSwitch/FSwitch.vue";
74
+export default {
75
+  components: {FSwitch},
76
+  setup(){
77
+    const userStore = useUserStore()
78
+
79
+    const formData = reactive({
80
+      uid: '',
81
+      address_id: '',
82
+      name: '',
83
+      detail: '',
84
+      phone: '',
85
+      address: [],
86
+      is_default: false,
87
+      code_list: ''
88
+    });
89
+    const state = reactive({
90
+      cartId: '', // 购物车 id
91
+      pinkId: 0, // 拼团 id
92
+      couponId: 0, // 优惠劵 id
93
+      addressId: 0, // 地址 id
94
+      userAddress: {
95
+        is_default: false
96
+      },
97
+      isNew: true,
98
+    })
99
+
100
+    // const state
101
+    const basicData = reactive({
102
+      addressObject: [],
103
+      isDefaultVal: true,
104
+      province: '',
105
+      provinceId: '',
106
+      city: '',
107
+      cityId: '',
108
+      country: '',
109
+      countryId: '',
110
+      // 街道
111
+      village: '',
112
+      villageId: ''
113
+    });
114
+
115
+    const addressData = reactive({
116
+      visible: false,
117
+      value: [],
118
+      options: [
119
+        // { value: '北京', text: '北京', id: 1, pid: null },
120
+      ],
121
+      // lazyLoad(node: any, resolve: (children: any) => void) {
122
+      //   // const {pid, id} = node
123
+      //   getCityNewFiveList(node.id).then(res => {
124
+      //     resolve(res)
125
+      //   })
126
+      // }
127
+    })
128
+
129
+    onLoad((options) => {
130
+
131
+      if (userStore.uid)  {
132
+        state.cartId = options.cartId || ''
133
+        state.pinkId = options.pinkId || 0
134
+        state.couponId = options.couponId || 0
135
+        state.addressId = options.id || 0
136
+        state.isNew = options.id && false
137
+
138
+
139
+        uni.setNavigationBarTitle({
140
+          title: options.id ? '修改地址' : '新增收货地址'
141
+        });
142
+
143
+        getUserAddress()
144
+        loadCityList()
145
+
146
+      } else {
147
+        // LOGIN
148
+        // userStore.logout()
149
+      }
150
+
151
+    })
152
+    const getUserAddress = () => {
153
+      if (!state.addressId) return false
154
+
155
+      getUserAddressDetail(state.addressId).then(res => {
156
+        console.log(res)
157
+        // let region = [res.province, res.city, res.district]
158
+        formData.address = [res.province, res.city, res.district]
159
+        // state.cityId = res.city_id
160
+        formData.address_id = res.address_id
161
+        formData.uid = res.uid
162
+        formData.name = res.real_name
163
+        formData.phone = res.phone
164
+        formData.detail = res.detail
165
+        // console.log(data.province)
166
+        // formData.address = [res.province, res.city, res.district, data.village]
167
+        // formData.address = [res.province, res.city, res.district, data.village]
168
+        // console.log(formData.address)
169
+        formData.is_default = res.is_default == '1'
170
+        formData.code_list = res.code_list
171
+        formData.village = res.village
172
+        formData.village_id = res.village_id
173
+      })
174
+    }
175
+    const loadCityList = () => {
176
+      uni.showLoading({
177
+        title: '加载中',
178
+        duration: 3000,
179
+        mask: true
180
+      })
181
+      getCityList().then(res => {
182
+        if (res) {
183
+            res.forEach((province) => {
184
+              addressData.options.push(province)
185
+            })
186
+        }
187
+        uni.hideLoading()
188
+      }).catch(error => {
189
+        uni.hideLoading()
190
+        console.error(error)
191
+      })
192
+    }
193
+    const validate = (item: any) => {
194
+      console.log(item);
195
+    };
196
+    const ruleForm = ref<any>(null);
197
+
198
+    const submit = () => {
199
+      ruleForm.value.validate().then(({ valid, errors }: any) => {
200
+        if (valid) {
201
+          console.log('success', formData);
202
+          const province = formData.address[0]
203
+          const city = formData.address[1]
204
+          const district = formData.address[2]
205
+          // const country = formData.address[3]
206
+          // const village = formData.address[3]
207
+          let provinceId = ''
208
+          let cityId = ''
209
+          let districtId = ''
210
+          let countryId = ''
211
+
212
+
213
+          // IDs
214
+          // const provinceId = basicData.addressObject[0].id
215
+          // const cityId = basicData.addressObject[1].id
216
+          // // const countryId = basicData.addressObject[2].id
217
+          // const districtId = basicData.addressObject[2].id
218
+          // const countryId = basicData.addressObject[3].id
219
+          // let villageId = ''
220
+          // let village = ''
221
+          // // const province =
222
+          // let code_list = ''
223
+          // if (formData.address[3]) {
224
+          //   // codeList = mProvinceId + "," + mCityId + "," + mCountyId + "," + mVillageId;
225
+          //   code_list = provinceId + ',' + cityId + ',' + districtId + ',' + countryId
226
+          // } else {
227
+          //   code_list = provinceId + ',' + cityId + ',' + districtId
228
+          // }
229
+          // if (formData.address[4]) {
230
+          //   villageId = basicData.addressObject[4].id
231
+          //   village = basicData.addressObject[4].value
232
+          // }
233
+
234
+          if (basicData.addressObject.length > 0) {
235
+            console.log(basicData.addressObject)
236
+            provinceId = basicData.addressObject[0].id
237
+            cityId = basicData.addressObject[1].id
238
+            districtId = basicData.addressObject[2].id
239
+            countryId = basicData.addressObject[3].id
240
+            if (formData.address[3]) {
241
+              // codeList = mProvinceId + "," + mCityId + "," + mCountyId + "," + mVillageId;
242
+              formData.code_list = provinceId + ',' + cityId + ',' + districtId + ',' + countryId
243
+            } else {
244
+              formData.code_list = provinceId + ',' + cityId + ',' + districtId
245
+            }
246
+            if (formData.address[4]) {
247
+              formData.viilage_id = basicData.addressObject[4].id
248
+              formData.village = basicData.addressObject[4].value
249
+            }
250
+          }
251
+          addressNewCreate({
252
+            province,
253
+            city,
254
+            district,
255
+            is_default: formData.is_default ? '1' : '0',
256
+            phone: formData.phone,
257
+            real_name: formData.name,
258
+            detail: formData.detail,
259
+            code_list: formData.code_list,
260
+            // city_id: '2',
261
+            city_id: cityId,
262
+            village_id: formData.villageId,
263
+            village: formData.village,
264
+            address_id: formData.address_id
265
+            // address_id
266
+          }).then(res => {
267
+            console.log(res)
268
+            if (res) {
269
+              uni.showToast({
270
+                title: '保存成功'
271
+              })
272
+              setTimeout(() => {
273
+                if (state.cartId) {
274
+                  let cartId = state.cartId
275
+                  let pinkId = state.pinkId
276
+                  let couponId = state.couponId
277
+                  state.cartId = ''
278
+                  state.pinkId = ''
279
+                  state.couponId = ''
280
+
281
+                  uni.redirectTo({
282
+                    url: '/pages/order-confirm/index?cartId=' +
283
+                        cartId +
284
+                        '&addressId=' +
285
+                        (state.addressId ? state.addressId : res.address_id) +
286
+                        '&pinkId=' +
287
+                        '&couponId=' +
288
+                        couponId
289
+                  })
290
+                } else {
291
+                  return uni.navigateBack({
292
+                    delta: 1
293
+                  })
294
+                }
295
+                // uni.redirectTo({
296
+                //   url: '/pages/user/address/index'
297
+                // })
298
+              }, 1000)
299
+            }
300
+          }).catch(message => {
301
+            console.log(message)
302
+            uni.hideLoading()
303
+
304
+            uni.showToast({
305
+              icon: "none",
306
+              title: message
307
+            })
308
+          })
309
+          // formData.address
310
+          console.log(formData.address.length)
311
+        } else {
312
+          console.log('error submit!!', errors);
313
+        }
314
+      });
315
+    };
316
+    const reset = () => {
317
+      ruleForm.value.reset();
318
+    };
319
+    // 失去焦点校验
320
+    const customBlurValidate = (prop: string) => {
321
+      ruleForm.value.validate(prop).then(({ valid, errors }: any) => {
322
+        if (valid) {
323
+          console.log('success', formData);
324
+
325
+        } else {
326
+          console.log('error submit!!', errors);
327
+        }
328
+      });
329
+    };
330
+    // 函数校验
331
+    const customValidator = (val: string) => /^\d+$/.test(val);
332
+    const customRulePropValidator = (val: string, rule: FormItemRuleWithoutValidator) => {
333
+      return (rule?.reg as RegExp).test(val);
334
+    };
335
+    const nameLengthValidator = (val: string) => val?.length >= 2;
336
+    // Promise 异步校验
337
+    const asyncValidator = (val: string) => {
338
+      return new Promise((resolve) => {
339
+        // console.log('模拟异步验证中...');
340
+        setTimeout(() => {
341
+          // console.log('验证完成');
342
+          resolve(/^400(-?)[0-9]{7}$|^1\d{10}$|^0[0-9]{2,3}-[0-9]{7,8}$/.test(val));
343
+        }, 1000);
344
+      });
345
+    };
346
+
347
+    const events = {
348
+      change(arg1, arg2) {
349
+        basicData.addressObject = arg2
350
+      },
351
+      pathChange(...args: any) {
352
+        console.log('pathChange', ...args);
353
+      },
354
+    };
355
+
356
+    function handleDelete() {
357
+      if (formData && formData.address_id) {
358
+        uni.showModal({
359
+          title: '温馨提示',
360
+          content: '是否删除该地址',
361
+          success: function (res) {
362
+            if (res.confirm) {
363
+              deleteAddress(formData.address_id).then(res => {
364
+                uni.showToast({
365
+                  title: '删除成功',
366
+                  icon: 'none'
367
+                })
368
+                setTimeout(() => {
369
+                  // uni.redirectTo({
370
+                  //   url: '/pages/user/address/index'
371
+                  // })
372
+                  uni.navigateBack()
373
+                }, 500)
374
+              }).catch(error => {
375
+                uni.showToast({
376
+                  title: error,
377
+                  icon: 'none'
378
+                })
379
+              })
380
+
381
+            }
382
+          }
383
+        })
384
+      }
385
+    }
386
+
387
+    return { ruleForm, formData,  basicData, addressData, events, validate, customValidator, customRulePropValidator, nameLengthValidator, asyncValidator, customBlurValidate, submit, reset, state, handleDelete };
388
+  }
389
+}
390
+</script>
391
+<style>
392
+.nut-input-text {
393
+  color: #000 !important;
394
+}
395
+
396
+.nut-cell-group__wrap {
397
+  background: none !important;
398
+  box-shadow: none !important;
399
+}
400
+</style>
401
+<route lang="yaml">
402
+style:
403
+  navigationBarTitleText: 收货地址
404
+</route>

+ 248 - 0
src/pages/user/address/create-five.vue

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

+ 465 - 79
src/pages/user/address/create.vue

@@ -1,31 +1,38 @@
1 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" />
2
+  <nut-form :model-value="state.userAddress" ref="ruleForm">
3
+    <nut-form-item label="联系人" prop="real_name"
4
+                   required>
5
+      <nut-input class="nut-input-text"
6
+                 v-model="state.userAddress.real_name"
7
+                 placeholder="请输入姓名" type="text"/>
9 8
     </nut-form-item>
10 9
 
11
-    <nut-form-item label="手机号码" prop="phone" required :rules="[
12
-      { required: true, message: '请填写联系电话' },
13
-      { validator: asyncValidator, message: '电话格式不正确' }
14
-    ]">
15
-      <nut-input class="nut-input-text" v-model="formData.phone" placeholder="请填写手机号码" type="text" />
10
+    <nut-form-item label="手机号码" prop="phone" required>
11
+      <nut-input class="nut-input-text" v-model="state.userAddress.phone" placeholder="请填写手机号码" type="text"/>
16 12
     </nut-form-item>
17 13
     <nut-form-item label="收货地址"
18 14
                    required
19 15
                    prop="address"
20
-                   :rules="[{ required: true, message: '请选择收货地址' }]"
21 16
     >
22
-      <div class="nut-input-text"
23
-           @click="addressData.visible = true"
24
-      >
25
-        {{formData.address.toString() === '' ? '省市区县、省镇等' : formData.address.toString()}}
26
-      </div>
17
+<!--      <div class="nut-input-text"-->
18
+<!--           @click="addressData.visible = true"-->
19
+<!--      >-->
20
+<!--      </div>-->
27 21
 
22
+      <picker mode="multiSelector" @change="bindRegionChange"
23
+              @columnchange="bindMultiPickerColumnChange" :value="state.valueRegion" :range="state.multiArray">
24
+        <view class=" flex ">
25
+          <view class="picker" v-if="state.region[3]">
26
+            {{ state.region[0] }},{{ state.region[1] }},{{ state.region[2] }},{{ state.region[3] }}
27
+          </view>
28
+          <view class="picker" v-else>
29
+            {{ state.region[0] }},{{ state.region[1] }},{{ state.region[2] }}
30
+          </view>
31
+          <view class="iconfont icon-dizhi font-color"></view>
32
+        </view>
33
+      </picker>
28 34
 
35
+      <!--
29 36
       <nut-cascader
30 37
           title="地址选择"
31 38
           v-model:visible="addressData.visible"
@@ -40,9 +47,10 @@
40 47
           lazy
41 48
           :lazyLoad="addressData.lazyLoad"
42 49
       ></nut-cascader>
50
+      -->
43 51
     </nut-form-item>
44 52
     <nut-form-item label="详细地址" prop="detail" required :rules="[{ required: true, message: '请填写详细地址' }]">
45
-      <nut-input class="nut-input-text" v-model="formData.detail" placeholder="街道、楼牌号等" type="text" />
53
+      <nut-input class="nut-input-text" v-model="state.userAddress.detail" placeholder="街道、楼牌号等" type="text"/>
46 54
     </nut-form-item>
47 55
     <div class="p-4">
48 56
       <div class="flex  items-center justify-between">
@@ -50,34 +58,74 @@
50 58
           <div>设置为默认地址</div>
51 59
           <div class="text-xs text-gray">提醒:下单会优先使用该地址</div>
52 60
         </div>
53
-          <nut-switch v-model="formData.is_default"></nut-switch>
61
+        <nut-switch v-model="state.userAddress.is_default"></nut-switch>
54 62
 
55 63
       </div>
56 64
     </div>
57 65
 
58 66
     <div class="fixed bottom-0 p-safe w-full ">
59
-      <div class="px-3">
67
+      <div class="px-3" v-if="state.addNew == 1">
68
+        <nut-button block type="primary" @click="submit">保存</nut-button>
69
+      </div>
70
+
71
+      <div class="px-3 flex flex-col gap-3" v-else>
60 72
         <nut-button block type="primary" @click="submit">保存</nut-button>
73
+        <nut-button block type="default" @click="handleDelete">删除</nut-button>
61 74
       </div>
62 75
     </div>
63 76
   </nut-form>
64 77
 </template>
65 78
 <script lang="ts">
66
-import { ref,reactive } from 'vue';
79
+import {ref, reactive} from 'vue';
67 80
 import type {FormItemRuleWithoutValidator} from "uniapp-nutui";
68
-import {addressNewCreate, getCityList, getCityNewFiveList} from "~/apis/user";
81
+import {addressNewCreate, deleteAddress, getCityList, getCityNewFiveList, getUserAddressDetail} from "~/apis/user";
69 82
 import FSwitch from "~/components/FSwitch/FSwitch.vue";
83
+
70 84
 export default {
71 85
   components: {FSwitch},
72
-  setup(){
86
+  setup() {
87
+    const userStore = useUserStore()
88
+
73 89
     const formData = reactive({
90
+      address_id: 0,
74 91
       name: '',
75 92
       detail: '',
76 93
       phone: '',
77 94
       address: [],
78 95
       is_default: false,
96
+
97
+      city_id: null,
98
+      code_list: '',
99
+      province: '',
100
+      city: '',
101
+      district: ''
79 102
     });
80 103
 
104
+    const state = reactive({
105
+      cartId: '', // 购物车 id
106
+      pinkId: 0, // 拼团 id
107
+      couponId: 0, // 优惠劵 id
108
+      addressId: 0, // 地址 id
109
+      userAddress: {
110
+        is_default: false
111
+      },
112
+      addNew: 0,
113
+      region: ['省', '市', '区', '县'],
114
+      valueRegion: [0, 0, 0, 0],
115
+      defaultRegion: ['广东省', '广州市', '番禺区'],
116
+      defaultRegionCode: '440113',
117
+      district: [],
118
+      multiArray: [],
119
+      multiIndex: [0, 0, 0, 0],
120
+      wikmn: [],
121
+      wikmns: ['', 439, ''],
122
+      // cityId: city
123
+      cityId: 0,
124
+
125
+      dxz: '',
126
+      dhy: '',
127
+      ljq: '',
128
+    })
81 129
     const basicData = reactive({
82 130
       addressObject: [],
83 131
       isDefaultVal: true,
@@ -106,68 +154,326 @@ export default {
106 154
       }
107 155
     })
108 156
 
109
-    onLoad(() => {
157
+    onLoad((options) => {
158
+     if (userStore.uid)  {
159
+       state.cartId = options.cartId || ''
160
+       state.pinkId = options.pinkId || 0
161
+       state.couponId = options.couponId || 0
162
+       state.addressId = options.id || 0
163
+       state.addNew = options.add || 1
110 164
 
111
-      getCityNewFiveList(0).then(res => {
112
-        // addressData.options.push()
113
-        // province.forEach()
114
-        res.forEach(province => {
115
-          addressData.options.push(province)
116
-        })
117
-      })
118
-      // getCityList().then(res => {
119
-      //   res.forEach((province) => {
165
+
166
+       uni.setNavigationBarTitle({
167
+         title: options.id ? '修改地址' : '新增收货地址'
168
+       });
169
+
170
+       getUserAddress()
171
+       loadCityList()
172
+
173
+     } else {
174
+       // LOGIN
175
+       // userStore.logout()
176
+     }
177
+      // getCityNewFiveList(0).then(res => {
178
+      //   // addressData.options.push()
179
+      //   // province.forEach()
180
+      //   res.forEach(province => {
120 181
       //     addressData.options.push(province)
121 182
       //   })
122 183
       // })
123 184
     })
185
+
186
+    const loadCityList = () => {
187
+      uni.showLoading({
188
+        title: '加载中',
189
+        duration: 3000,
190
+        mask: true
191
+      })
192
+      getCityList().then(res => {
193
+        if (res) {
194
+          state.district = res
195
+          // console.log(res)
196
+          // 初始化
197
+          initializePickerValue()
198
+        }
199
+        uni.hideLoading()
200
+      }).catch(error => {
201
+        uni.hideLoading()
202
+        console.error(error)
203
+      })
204
+    }
205
+
206
+    const getUserAddress = () => {
207
+      if (!state.addressId) return false
208
+
209
+      getUserAddressDetail(state.addressId).then(res => {
210
+        let region = [res.province, res.city, res.district]
211
+        state.userAddress = res
212
+        state.region = region
213
+        state.cityId = res.city_id
214
+      })
215
+    }
216
+    const initializePickerValue = () => {
217
+      let province = []
218
+      let city = []
219
+      let area = []
220
+      let xian = []
221
+      if (state.district.length) {
222
+        let cityChildren = state.district[0].children || []
223
+        let areaChildren = cityChildren.length ? cityChildren[0].children || [] : []
224
+        let xianChildren = areaChildren.length ? areaChildren[0].children || [] : []
225
+
226
+        state.district.forEach((item => {
227
+          province.push(item.name)
228
+        }))
229
+        cityChildren.forEach((item) => {
230
+          city.push(item.name)
231
+        })
232
+        areaChildren.forEach((item) => {
233
+          area.push(item.name)
234
+        })
235
+        if (xianChildren.length) {
236
+          xianChildren.forEach((item) => {
237
+            xian.push(item.name)
238
+          })
239
+        }
240
+
241
+        state.multiArray = [province, city, area, xian]
242
+      }
243
+    }
244
+
245
+    const bindRegionChange = (e) => {
246
+      console.log(e)
247
+      let multiIndex = state.multiIndex
248
+      let province = state.district[multiIndex[0]] || {children: []}
249
+      let city = province.children[multiIndex[1]] || {city_id: 0}
250
+      let multiArray = state.multiArray
251
+      let value = e.detail.value
252
+      let wikmnss = state.wikmn
253
+      console.log(multiArray)
254
+      console.log(multiArray[0][value[0]])
255
+      state.region = [multiArray[0][value[0]], multiArray[1][value[1]], multiArray[2][value[2]], multiArray[3]
256
+          [value[3]]
257
+      ]
258
+      state.wikmns = [wikmnss[3][value[3]], wikmnss[2][value[2]]]
259
+
260
+      // console.log(wikmnss)
261
+      // state.wikmns = [wikmnss[3][value[3]], wikmnss[2][value[2]]]
262
+      // console.log(province.children[multiArray[1]])
263
+      state.cityId = city.city_id
264
+      // 表示选择了 range 中的第几个(下标从 0 开始)
265
+      // state.valueRegion = [0, 0, 0, 0]
266
+      // state.valueRegion = [5, 0, 0, 0]
267
+
268
+      initializePickerValue()
269
+    }
270
+
271
+    /// 来自-原小程序代码转换
272
+    const bindMultiPickerColumnChange = (e) => {
273
+      let column = e.detail.column
274
+      let value = e.detail.value
275
+      let currentCity = state.district[value] || {children: []}
276
+      let multiArray = state.multiArray
277
+      let multiIndex = state.multiIndex
278
+      let wikmns = state.wikmn
279
+      multiIndex[column] = value
280
+
281
+      switch (column) {
282
+        case 0:
283
+          let areaList = currentCity.children[0] || {
284
+            children: []
285
+          };
286
+          console.log(currentCity.id, currentCity.name, '省')
287
+          state.cityId = currentCity.id
288
+          // console.log(areaList.id, areaList.name, '市')
289
+          state.dxz = areaList.id
290
+          let isareaList = areaList.children[0] || {
291
+            children: []
292
+          };
293
+
294
+          // console.log(isareaList.id, isareaList.name, '区')
295
+          state.dhy = isareaList.id
296
+          let isareaListssssss = areaList.children[0] || {
297
+            children: []
298
+          };
299
+          let xianshi = isareaListssssss.children[0] || {
300
+            children: []
301
+          };
302
+          // console.log(xianshi.id, xianshi.name, '县')
303
+          state.ljq = xianshi.id
304
+          multiArray[1] = currentCity.children.map(item => {
305
+            return item.name;
306
+          });
307
+
308
+          multiArray[2] = areaList.children.map(item => {
309
+            return item.name;
310
+          });
311
+          if (areaList.children) {
312
+            wikmns[2] = areaList.children.map(item => {
313
+              return item.id;
314
+            });
315
+
316
+          } else {
317
+            wikmns[2] = []
318
+          }
319
+
320
+          if (isareaList.children) {
321
+            multiArray[3] = isareaList.children.map(item => {
322
+              return item.name;
323
+            });
324
+          } else {
325
+            multiArray[3] = []
326
+          }
327
+          if (isareaListssssss.children) {
328
+            wikmns[3] = isareaListssssss.children.map(item => {
329
+              return item.id;
330
+            });
331
+          } else {
332
+            multiArray[3] = []
333
+          }
334
+          state.multiArray = multiArray
335
+          break;
336
+        case 1:
337
+          let cityList = state.district[multiIndex[0]].children[multiIndex[1]].children || [];
338
+          multiArray[2] = cityList.map(item => {
339
+            return item.name;
340
+          });
341
+
342
+          let cityListssaaa = state.district[multiIndex[0]].children[multiIndex[1]].children || [];
343
+          if (cityListssaaa) {
344
+            wikmns[2] = cityListssaaa.map(item => {
345
+              return item.id;
346
+            });
347
+          }
348
+          state.cityId = state.district[multiIndex[0]].id
349
+          state.dxz = state.district[multiIndex[0]].children[multiIndex[1]].id
350
+          state.dhy = state.district[multiIndex[0]].children[multiIndex[1]].children[multiIndex[2]].id
351
+          state.ljq = state.district[multiIndex[0]].children[multiIndex[1]].children[multiIndex[2]].children[multiIndex[3]].id
352
+
353
+
354
+          let cityListss = state.district[multiIndex[0]].children[multiIndex[1]].children[multiIndex[
355
+              2]] || [];
356
+          if (cityListss.children) {
357
+            multiArray[3] = cityListss.children.map(item => {
358
+              return item.name;
359
+            });
360
+          } else {
361
+            multiArray[3] = []
362
+          }
363
+          let cityListssssssssssss = state.district[multiIndex[0]].children[multiIndex[1]].children[
364
+              multiIndex[
365
+                  2]] || [];
366
+          if (cityListssssssssssss.children) {
367
+            wikmns[3] = cityListssssssssssss.children.map(item => {
368
+              return item.id;
369
+            });
370
+          } else {
371
+            wikmns[3] = []
372
+          }
373
+          break;
374
+        case 2:
375
+          let cityLists = state.district[multiIndex[0]].children[multiIndex[1]].children[multiIndex[2]]
376
+              .children || [];
377
+          multiArray[3] = cityLists.map(item => {
378
+            return item.name;
379
+          });
380
+          state.cityId = state.district[multiIndex[0]].id
381
+          state.dxz = state.district[multiIndex[0]].children[multiIndex[1]].id
382
+          state.dhy = state.district[multiIndex[0]].children[multiIndex[1]].children[multiIndex[2]].id
383
+          state.ljq = state.district[multiIndex[0]].children[multiIndex[1]].children[multiIndex[2]].children[multiIndex[3]].id
384
+          let cityListsss = state.district[multiIndex[0]].children[multiIndex[1]].children[multiIndex[2]]
385
+              .children || [];
386
+          wikmns[3] = cityListsss.map(item => {
387
+            return item.id;
388
+          });
389
+          break;
390
+        case 3:
391
+          let cityListsw = state.district[multiIndex[0]].children[multiIndex[1]].children[multiIndex[2]]
392
+              .children || [];
393
+          multiArray[3] = cityListsw.map(item => {
394
+            return item.name;
395
+          });
396
+          state.cityId = state.district[multiIndex[0]].id
397
+          state.dxz = state.district[multiIndex[0]].children[multiIndex[1]].id
398
+          state.dhy = state.district[multiIndex[0]].children[multiIndex[1]].children[multiIndex[2]].id
399
+          state.ljq = state.district[multiIndex[0]].children[multiIndex[1]].children[multiIndex[2]].children[multiIndex[3]].id
400
+
401
+          break;
402
+
403
+      }
404
+      // console.log(multiArray)
405
+      // state.multiArray = multiArray
406
+      state.multiArray[0] = multiArray[0]
407
+      state.multiArray[1] = multiArray[1]
408
+      state.multiArray[2] = multiArray[2]
409
+      state.multiIndex = multiIndex
410
+
411
+    }
124 412
     const validate = (item: any) => {
125 413
       console.log(item);
126 414
     };
127 415
     const ruleForm = ref<any>(null);
128 416
 
129 417
     const submit = () => {
130
-      ruleForm.value.validate().then(({ valid, errors }: any) => {
418
+      ruleForm.value.validate().then(({valid, errors}: any) => {
131 419
         if (valid) {
132
-          console.log('success', formData);
133
-          const province = formData.address[0]
134
-          const city = formData.address[1]
135
-          const district = formData.address[2]
136
-          // const village = formData.address[3]
137
-
138
-          // IDs
139
-          const provinceId = basicData.addressObject[0].id
140
-          const cityId = basicData.addressObject[1].id
141
-          // const countryId = basicData.addressObject[2].id
142
-          const districtId = basicData.addressObject[2].id
143
-          const countryId = basicData.addressObject[3].id
144
-          let villageId = ''
145
-          let village = ''
146
-          // const province =
147
-          let code_list = ''
148
-          if (formData.address[3]) {
149
-            // codeList = mProvinceId + "," + mCityId + "," + mCountyId + "," + mVillageId;
150
-            code_list = provinceId + ',' + cityId + ',' + districtId + ',' + countryId
151
-          } else {
152
-            code_list = provinceId + ',' + cityId + ',' + districtId
420
+          let formValue: any = {}
421
+
422
+          if (!state.userAddress.real_name) {
423
+            return uni.showToast({
424
+              title: '请输入收货人的姓名'
425
+            })
426
+          }
427
+          if (!state.userAddress.phone) {
428
+            return uni.showToast({
429
+              title: '请输入手机号'
430
+            })
431
+          }
432
+          if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(state.userAddress.phone)) {
433
+            return uni.showToast({
434
+              title: '请输入正确的手机号码',
435
+              icon: 'none'
436
+            })
437
+          }
438
+          // console.log(state.region.toString())
439
+          if (JSON.stringify(state.region) === JSON.stringify(['省', '市', '区', '县'])) {
440
+            return uni.showToast({
441
+              title: '请选择收货地址',
442
+              icon: "none"
443
+            })
153 444
           }
154
-          if (formData.address[4]) {
155
-            villageId = basicData.addressObject[4].id
156
-            village = basicData.addressObject[4].value
445
+
446
+          if (!state.userAddress.detail) {
447
+            return uni.showToast({
448
+              title: '请填写详细地址',
449
+              icon: 'none'
450
+            })
157 451
           }
452
+
453
+          formValue.real_name = state.userAddress.real_name
454
+          formValue.phone = state.userAddress.phone
455
+          formValue.detail = state.userAddress.detail
456
+
457
+          formValue.address_id = state.addressId
458
+          let regionArray = state.region
459
+          formValue.province = regionArray[0]
460
+          formValue.city = regionArray[1]
461
+          formValue.district = regionArray[2]
462
+
463
+          console.log(state.cityId)
464
+          if (state.cityId == undefined) {
465
+            // unPackageRegion.city_id = 1
466
+            formValue.city_id = 1
467
+            formValue.code_list = 1 + "," + 67449 + "," + 35 + "," + 493
468
+          } else {
469
+            formValue.city_id = state.cityId
470
+            formValue.code_list = state.cityId + ',' + state.dxz + ',' + state.dhy + ',' + state.ljq
471
+          }
472
+          formValue.is_default = state.userAddress.is_default ? 1 : 0
473
+
474
+
158 475
           addressNewCreate({
159
-            province,
160
-            city,
161
-            district,
162
-            is_default: formData.is_default ? '1' : '0',
163
-            phone: formData.phone,
164
-            real_name: formData.name,
165
-            detail: formData.detail,
166
-            code_list,
167
-            city_id: '2',
168
-            village_id: villageId,
169
-            village,
170
-            // address_id
476
+            ...formValue
171 477
           }).then(res => {
172 478
             console.log(res)
173 479
             if (res) {
@@ -175,20 +481,43 @@ export default {
175 481
                 title: '保存成功'
176 482
               })
177 483
               setTimeout(() => {
178
-                uni.redirectTo({
179
-                  url: '/pages/user/address/index'
180
-                })
181
-              }, 500)
484
+                if (state.cartId) {
485
+                  let cartId = state.cartId
486
+                  let pinkId = state.pinkId
487
+                  let couponId = state.couponId
488
+                  state.cartId = ''
489
+                  state.pinkId = ''
490
+                  state.couponId = ''
491
+
492
+                  uni.redirectTo({
493
+                    url: '/pages/order-confirm/index?cartId=' +
494
+                        cartId +
495
+                        '&addressId=' +
496
+                        (state.addressId ? state.addressId : res.address_id) +
497
+                        '&pinkId=' +
498
+                        '&couponId=' +
499
+                        couponId
500
+                  })
501
+                } else {
502
+                  return uni.navigateBack({
503
+                    delta: 1
504
+                  })
505
+                }
506
+                // uni.redirectTo({
507
+                //   url: '/pages/user/address/index'
508
+                // })
509
+              }, 1000)
182 510
             }
183 511
           }).catch(message => {
184 512
             console.log(message)
513
+            uni.hideLoading()
185 514
             uni.showToast({
186 515
               icon: "none",
187 516
               title: message
188 517
             })
189 518
           })
190 519
           // formData.address
191
-          console.log(formData.address.length)
520
+          // console.log(formData.address.length)
192 521
         } else {
193 522
           console.log('error submit!!', errors);
194 523
         }
@@ -199,7 +528,7 @@ export default {
199 528
     };
200 529
     // 失去焦点校验
201 530
     const customBlurValidate = (prop: string) => {
202
-      ruleForm.value.validate(prop).then(({ valid, errors }: any) => {
531
+      ruleForm.value.validate(prop).then(({valid, errors}: any) => {
203 532
         if (valid) {
204 533
           console.log('success', formData);
205 534
 
@@ -233,16 +562,73 @@ export default {
233 562
         console.log('pathChange', ...args);
234 563
       },
235 564
     };
236
-    return { ruleForm, formData,  basicData, addressData, events, validate, customValidator, customRulePropValidator, nameLengthValidator, asyncValidator, customBlurValidate, submit, reset };
565
+
566
+    function handleDelete() {
567
+      if (formData && formData.address_id) {
568
+        uni.showModal({
569
+          title: '温馨提示',
570
+          content: '是否删除该地址',
571
+          success: function (res) {
572
+            if (res.confirm) {
573
+              deleteAddress(formData.address_id).then(res => {
574
+                uni.showToast({
575
+                  title: '删除成功',
576
+                  icon: 'none'
577
+                })
578
+                setTimeout(() => {
579
+                  uni.redirectTo({
580
+                    url: '/pages/user/address/index'
581
+                  })
582
+                }, 500)
583
+              }).catch(error => {
584
+                uni.showToast({
585
+                  title: error,
586
+                  icon: 'none'
587
+                })
588
+              })
589
+
590
+            }
591
+          }
592
+        })
593
+      }
594
+    }
595
+
596
+    return {
597
+      ruleForm,
598
+      formData,
599
+      basicData,
600
+      addressData,
601
+      events,
602
+      validate,
603
+      customValidator,
604
+      customRulePropValidator,
605
+      nameLengthValidator,
606
+      asyncValidator,
607
+      customBlurValidate,
608
+      submit,
609
+      reset,
610
+      state,
611
+      bindRegionChange,
612
+      bindMultiPickerColumnChange,
613
+      handleDelete,
614
+    };
237 615
   }
238 616
 }
617
+
618
+function bindMultiPickerColumnChange() {
619
+}
239 620
 </script>
240 621
 <style>
241 622
 .nut-input-text {
242 623
   color: #000 !important;
243 624
 }
625
+
626
+.nut-cell-group__wrap {
627
+  background: none !important;
628
+  box-shadow: none !important;
629
+}
244 630
 </style>
245 631
 <route lang="yaml">
246 632
 style:
247
-  navigationBarTitleText: 收货地址
633
+navigationBarTitleText: 收货地址
248 634
 </route>

+ 6 - 1
src/pages/user/address/edit.vue

@@ -66,9 +66,12 @@
66 66
 <script setup lang="ts">
67 67
 import {reactive, ref} from "vue";
68 68
 import {decodeBase64} from "~/utils/http/helper";
69
-import {FormItemRuleWithoutValidator} from "uniapp-nutui";
69
+// import {FormItemRuleWithoutValidator} from "uniapp-nutui";
70 70
 import {addressNewCreate, deleteAddress, getCityNewFiveList} from "~/apis/user";
71 71
 import type {AddressModel} from "~/apis/model/address.model";
72
+import type {FormItemRuleWithoutValidator} from "nutui-uniapp";
73
+import {useAddressStore} from "~/stores/addressStore";
74
+const addressStore = useAddressStore()
72 75
 
73 76
 const formData = reactive({
74 77
   uid: '',
@@ -227,6 +230,8 @@ const submit = () => {
227 230
           uni.showToast({
228 231
             title: '保存成功'
229 232
           })
233
+
234
+          addressStore.setCurrentAddressId(res.address_id)
230 235
           setTimeout(() => {
231 236
           //   uni.redirectTo({
232 237
           //     url: '/pages/user/address/index'

+ 17 - 18
src/pages/user/address/index.vue

@@ -1,5 +1,4 @@
1 1
 <template>
2
-  <CXBBasePage>
3 2
     <div class="bg-white ">
4 3
       <div class="p-3 flex flex-col gap-3 pb-safe" v-if="data && data.length > 0">
5 4
         <div v-for="(item, index) in data" :key="index"
@@ -42,20 +41,6 @@
42 41
         </div>
43 42
       </div>
44 43
     </div>
45
-  </CXBBasePage>
46
-<!--  <nut-address-list
47
-      v-if="data && data.length > 0"
48
-      :data="data"
49
-      swipe-edition
50
-      show-bottom-button
51
-      @edit-icon="editClick"
52
-      @del-icon="delClick"
53
-      @click-item="clickItem"
54
-      @swipe-del="delClickSwipe"
55
-      @add="addAddress"
56
-      :options="dataOptions"
57
-  >
58
-  </nut-address-list>-->
59 44
 </template>
60 45
 <script lang="ts">
61 46
 import { ref, reactive } from 'vue';
@@ -77,13 +62,25 @@ export default {
77 62
         from.value = options.from
78 63
       }
79 64
       // from.value =
65
+      // getUserAddressList().then(res => {
66
+      //   if (res) {
67
+      //     // console.log(res)
68
+      //     data.value = res.list
69
+      //   }
70
+      // })
71
+    })
72
+
73
+   onShow(() => {
74
+     loadList()
75
+   })
76
+    function loadList() {
80 77
       getUserAddressList().then(res => {
81 78
         if (res) {
82 79
           // console.log(res)
83 80
           data.value = res.list
84 81
         }
85 82
       })
86
-    })
83
+    }
87 84
     const dataOptions = reactive({
88 85
       // id: 'testid',
89 86
       id: 'address_id',
@@ -94,7 +91,9 @@ export default {
94 91
     const handleEditItem = (item: AddressModel)=>{
95 92
 
96 93
       uni.navigateTo({
97
-        url: `/pages/user/address/edit?data=${encodeBase64(item)}`
94
+        // url: `/pages/user/address/edit?data=${encodeBase64(item)}`
95
+        // url: `/pages/user/address/edit?data=${encodeBase64(item)}`
96
+        url: `/pages/user/address/create-4-level?id=${item.address_id}`
98 97
       })
99 98
     }
100 99
 
@@ -126,7 +125,7 @@ export default {
126 125
 
127 126
     function handleCreateAddress() {
128 127
       uni.navigateTo({
129
-        url: '/pages/user/address/create'
128
+        url: '/pages/user/address/create-4-level'
130 129
       })
131 130
     }
132 131
 

+ 14 - 15
src/stores/addressStore.ts

@@ -16,24 +16,23 @@ export const useAddressStore = defineStore('addressStore', {
16 16
         setCurrentAddressId(addressId: string) {
17 17
             this.addressId = addressId
18 18
         },
19
-        getCurrentAddress(addressId?: string) {
19
+        async getCurrentAddress(addressId?: string) {
20
+            console.log('address...')
20 21
             if (addressId) {
21 22
                 // this.address = address
22
-                getUserAddressDetail(addressId).then(address => {
23
-                    // data.addressInfo = res
24
-                    // data.addressId = res.address_id || 0
25
-                    this.address = address
26
-                }).catch(error => {
27
-                    console.error(error + '->getUserAddressDetail')
28
-                })
23
+                this.address = await getUserAddressDetail(addressId)
29 24
             } else {
30
-                getUserAddressList().then(res => {
31
-                    this.address = res.list.length > 0 ? res.list[0] : {}
32
-                    // this.addressId = res.list.length > 0 ? res.list[0].address_id : '0'
33
-                }).catch(error => {
34
-                    console.error(error + '->getUserAddressList')
35
-
36
-                })
25
+                const res = await getUserAddressList()
26
+                if (res.list && res.list.length > 0) {
27
+                    this.address = res.list[0]
28
+                }
29
+                // this.address = await getUserAddressList().then(res => {
30
+                //     this.address = res.list.length > 0 ? res.list[0] : {}
31
+                //     // this.addressId = res.list.length > 0 ? res.list[0].address_id : '0'
32
+                // }).catch(error => {
33
+                //     console.error(error + '->getUserAddressList')
34
+                //
35
+                // })
37 36
             }
38 37
             // this.currentAddress = address
39 38
         },

+ 4 - 2
vite.config.ts

@@ -3,7 +3,9 @@ import uni from "@dcloudio/vite-plugin-uni";
3 3
 import AutoImport from 'unplugin-auto-import/vite'
4 4
 import UnoCSS from 'unocss/vite'
5 5
 import Components from '@uni-helper/vite-plugin-uni-components'
6
-import {NutResolver} from 'uniapp-nutui'
6
+// import {NutResolver} from 'uniapp-nutui'
7
+import { NutResolver } from 'nutui-uniapp'
8
+
7 9
 // import Components from 'unplugin-vue-components/vite'
8 10
 import UniPages from '@uni-helper/vite-plugin-uni-pages'
9 11
 import {resolve} from "node:path";
@@ -49,7 +51,7 @@ export default defineConfig({
49 51
     css: {
50 52
         preprocessorOptions: {
51 53
             scss: {
52
-                additionalData: '@import "uniapp-nutui/styles/variables.scss";',
54
+                additionalData: '@import "nutui-uniapp/styles/variables.scss";',
53 55
             },
54 56
         }
55 57
     }