Browse Source

fix: 我的收藏、收货地址管理、订单支付页面样式调整

ext.zhangbin71 1 month ago
parent
commit
c50b4bf0c8

+ 74 - 49
components/addressWindow/index.vue

@@ -1,24 +1,32 @@
 <template>
 	<view>
 		<view class="address-window" :class="address.address == true ? 'on' : ''">
-			<view class='title'>选择地址<text class='iconfont icon-guanbi' @tap='close'></text></view>
+			<view class='title'>
+				<view class=""></view>
+				<view class="">选择地址</view>
+				<image @tap='close' src="/static/images/shop/close@2x.png" mode=""></image>
+			</view>
+			
 			<view class='list'>
-				<view class='item acea-row row-between-wrapper' :class='active == index ? "font-color" : ""'
+				<view class='item' :class='active == index ? "active" : ""'
 					v-for="(item, index) in addressList" @tap='tapAddress(index, item.id)' :key='index'>
-					<text class='iconfont icon-ditu' :class='active == index ? "font-color" : ""'></text>
 					<view class='address'>
-						<view class='name' :class='active == index ? "font-color" : ""'>{{ item.realName }}<text class='phone'>{{
+						<view class='address-t'>{{ item.province }}{{ item.city }}{{ item.district }}{{ item.detail }}</view>
+						<view class='name'>{{ item.realName }}<text class='phone'>{{
 							item.phone }}</text></view>
-						<view class='line1'>{{ item.province }}{{ item.city }}{{ item.district }}{{ item.detail }}</view>
+						
 					</view>
-					<text class='iconfont icon-complete' :class='active == index ? "font-color" : ""'></text>
+					<view v-if="active == index" class="default">默认</view>
 				</view>
 			</view>
 			<!-- 无地址 -->
 			<view class='pictrue' v-if="!is_loading && !addressList.length">
-				<image :src="HTTP_REQUEST_URL_IMG+'noAddress.png'"></image>
+				<image src='/static/images/noAddress.png'></image>
+			</view>
+			<view class="addressBnt-btn">
+				<view class='addressBnt' @tap='goAddressPages'>添加地址</view>
 			</view>
-			<view class='addressBnt bg-color' @tap='goAddressPages'>添加地址</view>
+			
 		</view>
 		<view class='mask' catchtouchmove="true" :hidden='address.address == false' @tap='close'></view>
 	</view>
@@ -27,7 +35,6 @@
 <script setup>
 import { ref } from 'vue';
 import { getAddressList } from '@/api/user.js';
-import { HTTP_REQUEST_URL_IMG } from "@/config/app";
 
 const props = defineProps({
   pagesUrl: {
@@ -116,7 +123,8 @@ function fetchAddressList() {
 
 <style scoped lang="scss">
 .address-window {
-	background-color: #fff;
+	background: #FFFFFF;
+	border-radius: 40rpx 40rpx 0 0;
 	position: fixed;
 	bottom: 0;
 	left: 0;
@@ -131,65 +139,82 @@ function fetchAddressList() {
 }
 
 .address-window .title {
-	font-size: 32rpx;
+	color: #333333;
+	font-size: 36rpx;
 	font-weight: bold;
-	text-align: center;
-	height: 123rpx;
-	line-height: 123rpx;
-	position: relative;
+	height: 100rpx;
+	padding: 0 20rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	image,view:first-child{
+		width: 32rpx;
+		height: 32rpx;
+	}
 }
 
-.address-window .title .iconfont {
-	position: absolute;
-	right: 30rpx;
-	color: #8a8a8a;
-	font-size: 35rpx;
+.address-window .list {
+	padding: 0 32rpx;
 }
-
 .address-window .list .item {
-	margin-left: 30rpx;
-	padding-right: 30rpx;
-	border-bottom: 1px solid #eee;
-	height: 129rpx;
-	font-size: 25rpx;
-	color: #333;
-}
-
-.address-window .list .item .iconfont {
-	font-size: 37rpx;
-	color: #2c2c2c;
-}
-
-.address-window .list .item .iconfont.icon-complete {
-	font-size: 30rpx;
-	color: #fff;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	background: #F9F7F0;
+	border-radius: 16rpx;
+	border-bottom: 2px solid transparent;
+	padding: 16rpx;
+	margin-bottom: 24rpx;
+	&:last-child {
+		margin-bottom: 0;
+	}
+}
+.address-window .list .active {
+	background: rgba(248,192,8,0.1);
+	border: 2rpx solid #F8C008;
 }
-
 .address-window .list .item .address {
-	width: 560rpx;
+	flex: 1;
+	margin-right: 16rpx;
+}
+.default {
+	width: 64rpx;
+	height: 40rpx;
+	color: #333333;
+	font-size: 24rpx;
+	background: #F8C008;
+	border-radius: 8rpx;
+	text-align: center;
+	line-height: 40rpx;
 }
 
 .address-window .list .item .address .name {
 	font-size: 28rpx;
-	font-weight: bold;
-	color: #282828;
-	margin-bottom: 4rpx;
+	
+	color: #666666;
+	margin-top: 16rpx;
 }
 
 .address-window .list .item .address .name .phone {
 	margin-left: 18rpx;
 }
+.address-t {
+	font-weight: bold;
+}
+.addressBnt-btn {
+	padding: 22rpx 32rpx;
+}
 
 .address-window .addressBnt {
-	font-size: 30rpx;
+	font-size: 32rpx;
 	font-weight: bold;
-	color: #fff;
-	width: 690rpx;
-	height: 86rpx;
-	border-radius: 43rpx;
+	color: #333333;
 	text-align: center;
-	line-height: 86rpx;
-	margin: 85rpx auto;
+	
+	line-height: 88rpx;
+	
+	background: #F8C008;
+	border-radius: 16rpx;
 }
 
 .address-window .pictrue {

+ 201 - 148
components/orderGoods/index.vue

@@ -1,163 +1,216 @@
 <template>
-  <view class="orderGoods borRadius14">
-<!--    <view class="total"-->
-<!--      >共{{ orderProNum ? orderProNum : totalNmu }}件商品</view-->
-<!--    >-->
-    <view class="total"
-    >
-      <view v-if="sbMerchant&&sbMerchant.merchantName" class="merchant-container" @click.stop="toMerchant(sbMerchant.id)">
-        <image v-if="sbMerchant.merchantLogo" class="merchant-logo" :src="sbMerchant.merchantLogo" mode=""></image>
-        <text class="merchant-name">{{sbMerchant.merchantName}}</text>
-        <uni-icons type="right" size="16" color="#333"></uni-icons>
-      </view>
-      <text>共{{ orderProNum ? orderProNum : totalNmu }}件商品</text>
-    </view>
-    <view class="goodWrapper pad30">
-      <view
-        class="item acea-row row-between-wrapper"
-        v-for="(item, index) in cartInfo"
-        :key="index"
-        @click="jumpCon(item.productId)"
+	<view class="orderGoods borRadius14">
+
+		<!-- <view class="total"
       >
-        <view class="pictrue">
-          <image :src="item.image"></image>
-        </view>
-        <view class="text">
-          <view class="acea-row row-between-wrapper">
-            <view class="name line1">
-              {{ item.productName ? item.productName : item.storeName }}
-            </view>
-            <view class="num">
-              x {{ item.payNum ? item.payNum : item.cartNum }}
-            </view>
-          </view>
-          <view class="attr line1" v-if="item.sku">属性: {{ item.sku }}</view>
-          <view v-if="mallType === 0" class="money font-color">
-            ¥{{ Number(item.storePrice).toFixed(2) }}
-          </view>
-          <view v-else class="money font-color">
-            贝币:{{ Number(item.storePrice).toFixed(2) }}
-          </view>
-        </view>
-      </view>
-    </view>
-  </view>
+		  <view v-if="sbMerchant&&sbMerchant.merchantName" class="merchant-container" @click.stop="toMerchant(sbMerchant.id)">
+			<image v-if="sbMerchant.merchantLogo" class="merchant-logo" :src="sbMerchant.merchantLogo" mode=""></image>
+			<text class="merchant-name">{{sbMerchant.merchantName}}</text>
+			<uni-icons type="right" size="16" color="#333"></uni-icons>
+		  </view>
+		  <text>共{{ orderProNum ? orderProNum : totalNmu }}件商品</text>
+	  </view
+    > -->
+		<view class="goodWrapper">
+			<view class="product-item" v-for="(item, index) in cartInfo" :key="index"
+				@click="jumpCon(item.productId)">
+				<view class="product-img">
+					<image class="img" :src="item.image"></image>
+				</view>
+				<view class="text">
+					<view class="acea-row no-wrap row-between-wrapper">
+						<view class="product-name">
+							{{ item.productName ? item.productName : item.storeName }}
+						</view>
+						<view v-if="mallType === 0" class="product-price">
+							¥{{ Number(item.storePrice).toFixed(2) }}
+						</view>
+						<view v-else class="product-price">
+							{{ Number(item.storePrice).toFixed(2) }}
+							<text class="sub">贝币</text>
+						</view>
+					</view>
+					<view class="acea-row row-between-wrapper">
+						<view class="t" v-if="item.sku">属性: {{ item.sku }}</view>
+						<view class="t">
+							x {{ item.payNum ? item.payNum : item.cartNum }}
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
 </template>
 
 <script setup>
-import { ref, watch } from "vue";
-import UniIcons from "../../uni_modules/uni-icons/components/uni-icons/uni-icons.vue";
+	import {
+		ref,
+		watch
+	} from "vue";
 
-const props = defineProps({
-  evaluate: {
-    type: Number,
-    default: 0,
-  },
-  mallType: {
-    type: Number,
-    default: 0, // 0: 水贝商城, 1: 贝币商城
-  },
-  cartInfo: {
-    type: Array,
-    default: () => [],
-  },
-  sbMerchant: {
-    type: Object,
-    default: () => {},
-  },
-  orderId: {
-    type: String,
-    default: "",
-  },
-  ids: {
-    type: Number,
-    default: 0,
-  },
-  jump: {
-    type: Boolean,
-    default: false,
-  },
-  orderProNum: {
-    type: Number,
-    default: 0,
-  },
-  productType: {
-    type: Number,
-    default: 0,
-  },
-});
+	const props = defineProps({
+		evaluate: {
+			type: Number,
+			default: 0,
+		},
+		mallType: {
+			type: Number,
+			default: 0, // 0: 水贝商城, 1: 贝币商城
+		},
+		cartInfo: {
+			type: Array,
+			default: () => [],
+		},
+		orderId: {
+			type: String,
+			default: "",
+		},
+		ids: {
+			type: Number,
+			default: 0,
+		},
+		jump: {
+			type: Boolean,
+			default: false,
+		},
+		orderProNum: {
+			type: Number,
+			default: 0,
+		},
+		productType: {
+			type: Number,
+			default: 0,
+		},
+		sbMerchant: {
+			type: Object,
+		}
+	});
 
-const totalNmu = ref("");
+	const totalNmu = ref("");
 
-watch(
-  () => props.cartInfo,
-  (nVal) => {
-    let num = 0;
-    nVal.forEach((item) => {
-      num += item.cartNum;
-    });
-    totalNmu.value = num;
-  },
-  { immediate: true }
-);
+	watch(
+		() => props.cartInfo,
+		(nVal) => {
+			let num = 0;
+			nVal.forEach((item) => {
+				num += item.cartNum;
+			});
+			totalNmu.value = num;
+		}, {
+			immediate: true
+		}
+	);
 
-function evaluateTap(item) {
-  uni.navigateTo({
-    url: `/pages/users/goods_comment_con/index?unique=${item.attrId}&orderId=${props.orderId}&id=${props.ids}`,
-  });
-}
+	function evaluateTap(item) {
+		uni.navigateTo({
+			url: `/pages/users/goods_comment_con/index?unique=${item.attrId}&orderId=${props.orderId}&id=${props.ids}`,
+		});
+	}
 
-function jumpCon(id) {
-  let type = props.productType == 0 ? "normal" : "video";
-  if (props.jump) {
-    uni.navigateTo({
-      url: `/pages/goods/goods_details/index?id=${id}&type=${type}`,
-    });
-  }
-}
-const toMerchant = (merchantId) => {
-  uni.navigateTo({ url:"/pages/merchantCenters/merchant?merchantId="+merchantId });
-}
+	function jumpCon(id) {
+		let type = props.productType == 0 ? "normal" : "video";
+		if (props.jump) {
+			uni.navigateTo({
+				url: `/pages/goods_details/index?id=${id}&type=${type}`,
+			});
+		}
+	}
+	// 前往商家详情页
+	const toMerchant = (merchantId) => {
+		uni.navigateTo({
+			url: "/pages/merchantCenters/merchant/merchant?merchantId=" + merchantId
+		});
+	}
 </script>
 
 <style scoped lang="scss">
-.orderGoods {
-  background-color: #fff;
-  margin-top: 15rpx;
-}
+	.orderGoods {
+		background-color: #fff;
+	}
+
+	.orderGoods .total {
+		width: 100%;
+		height: 86rpx;
+		padding: 0 24rpx;
+		border-bottom: 2rpx solid #f0f0f0;
+		font-size: 30rpx;
+		color: #282828;
+		line-height: 86rpx;
+		box-sizing: border-box;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+	}
+
+	.pictrue image {
+		background: #f4f4f4;
+	}
 
-.orderGoods .total {
-  width: 100%;
-  height: 86rpx;
-  padding: 0 24rpx;
-  border-bottom: 2rpx solid #f0f0f0;
-  font-size: 30rpx;
-  color: #282828;
-  line-height: 86rpx;
-  box-sizing: border-box;
-  display: flex;
-  align-items: center;
-}
+	.merchant-container {
+		display: flex;
+		justify-content: flex-start;
+		align-items: center;
+		color: #333;
 
-.pictrue image {
-  background: #f4f4f4;
-}
-.merchantImg{
-  width: 60rpx;
-  height: 60rpx;
-  border-radius: 50%;
-}
-.merchant-container{
-  display: flex;
-  justify-content: flex-start;
-  align-items: center;
-  color:#333;
-  .merchant-logo{
-    width: 40rpx;
-    height: 40rpx;
-    margin-right: 20rpx;
-    border-radius: 50%;
-    background-color: #000;
-  }
-}
-</style>
+		.merchant-logo {
+			width: 40rpx;
+			height: 40rpx;
+			margin-right: 20rpx;
+			border-radius: 50%;
+			background-color: #000;
+		}
+	}
+	
+	.text .no-wrap{
+		flex-wrap: nowrap;
+		
+		.product-name{
+			font-size: 28rpx;
+			color:#333;
+			line-height: 44rpx;
+			font-weight: bold;
+		}
+		.product-price{
+			font-size: 36rpx;
+			line-height: 44rpx;
+			flex-shrink: 0;
+			margin-left: 20rpx;
+			color: #333;
+			font-weight: bold;
+			
+			.sub{
+				font-size: 24rpx;
+			}
+		}
+	}
+	
+	.goodWrapper{
+		// padding: 16rpx;
+		.product-item{
+			display: flex;
+			width: 100%;
+			
+			.text{
+				flex: 1;
+				
+				.t{
+					font-size: 24rpx;
+					line-height: 40rpx;
+					margin-top: 12rpx;
+					color: #666;
+				}
+			}
+		}
+		.product-img{
+			width: 160rpx;
+			height: 160rpx;
+			margin-right: 16rpx;
+			.img{
+				width: 160rpx;
+				height: 160rpx;
+				border-radius: 16rpx;
+			}
+			
+		}
+	}
+</style>

+ 3 - 3
pages.json

@@ -164,7 +164,7 @@
           "path": "user_address_list/index",
           "style": {
             "navigationBarTitleText": "地址管理",
-            "navigationBarBackgroundColor": "#ffe079",
+            "navigationBarBackgroundColor": "#fff",
             "navigationBarTextStyle": "black",
             "app-plus": {
               // #ifdef APP-PLUS
@@ -178,8 +178,8 @@
         {
           "path": "user_address/index",
           "style": {
-            "navigationBarTitleText": "添加地址",
-            "navigationBarBackgroundColor": "#ffe079",
+            "navigationBarTitleText": "新增地址",
+            "navigationBarBackgroundColor": "#fff",
             "navigationBarTextStyle": "black",
             "app-plus": {
               // #ifdef APP-PLUS

File diff suppressed because it is too large
+ 1542 - 1422
pages/users/order_confirm/index.vue


File diff suppressed because it is too large
+ 1442 - 0
pages/users/order_confirm/index_bf.vue


+ 371 - 0
pages/users/personal_info/personal_info_bf.vue

@@ -0,0 +1,371 @@
+<template>
+  <view class="personal-info">
+    <!-- 上传 -->
+    <view class="upload-box">
+      <up-upload
+        @afterRead="
+          async (e) => {
+            await afterRead(e);
+            getImage();
+          }
+        "
+        name="1"
+        :maxCount="1"
+        :previewImage="false"
+        :deletable="false"
+        :multiple="false"
+      >
+        <!-- <template #default> -->
+        <view class="upload-block">
+          <up-avatar
+            size="160rpx"
+            shape="circle"
+            :src="userInfo.avatar"
+            mode="aspectFill"
+          ></up-avatar>
+        </view>
+        <!-- </template> -->
+      </up-upload>
+    </view>
+		<view class="flex-center-between personal-info-item">
+			<text class="label_width">昵称</text>
+			<up-input
+          class="title-input"
+          placeholder="请输入"
+          type="text"
+          confirmType="完成"
+          maxlength="50"
+          :adjustPosition="false"
+          border="none"
+          :showWordLimit="true"
+          v-model="userInfo.nickname"
+					inputAlign="right"
+          @blur="changeName"
+        ></up-input>
+		</view>
+		<view class="flex-center-between personal-info-item">
+			<text class="label_width">手机号</text>
+			<text class="gray">{{telEncrypt(userInfo.phone)}}</text>
+		</view>
+		<view class="flex-center-between personal-info-item" @click="pickerSexShow = true">
+			<text class="label_width">性别</text>
+			<view class="flex-center-between">
+				<text>{{sexText}}</text>
+				<uni-icons type="right" size="21"  color="#888"></uni-icons>
+			</view>
+		</view>
+		<view class="flex-center-between personal-info-item">
+			<text class="label_width">地址</text>
+      <picker mode="multiSelector" @change="bindRegionChange" @columnchange="bindMultiPickerColumnChange"
+        :value="valueRegion" :range="multiArray">
+        <view class='flex-center-between'>
+          <view class="picker line1">{{ region[0] }},{{ region[1] }},{{ region[2] }}</view>
+					<uni-icons type="right" size="21"  color="#888"></uni-icons>
+        </view>
+      </picker>
+      <!-- <up-input
+          class="title-input"
+          placeholder="请输入"
+          type="text"
+          confirmType="完成"
+          maxlength="50"
+          :adjustPosition="false"
+          border="none"
+          :showWordLimit="true"
+          v-model="userInfo.addres"
+					inputAlign="right"
+          @blur="change"
+        ></up-input> -->
+    </view>
+    <view class="flex-center-between personal-info-item">
+      <text class="label_width">年龄</text>
+      <up-input
+        class="title-input"
+        placeholder="请输入"
+        type="text"
+        confirmType="完成"
+        maxlength="50"
+        :adjustPosition="false"
+        border="none"
+        :showWordLimit="true"
+        v-model="userInfo.age"
+        inputAlign="right"
+      ></up-input>
+    </view>
+    <view class="flex-center-between personal-info-item">
+      <text class="label_width">个人简介</text>
+      <up-input
+        class="title-input"
+        placeholder="请输入"
+        type="text"
+        confirmType="完成"
+        maxlength="50"
+        :adjustPosition="false"
+        border="none"
+        :showWordLimit="true"
+        v-model="userInfo.mark"
+        inputAlign="right"
+      ></up-input>
+    </view>
+<!--    <view-->
+<!--      class="flex-center-between border-bottom personal-info-item"-->
+<!--      @tap.stop="setPayword"-->
+<!--    >-->
+<!--      <text class="label_width">支付密码</text>-->
+<!--      &lt;!&ndash; <up-input-->
+<!--        class="title-input"-->
+<!--        placeholder="请输入"-->
+<!--        type="text"-->
+<!--        confirmType="完成"-->
+<!--        maxlength="6"-->
+<!--        :adjustPosition="false"-->
+<!--        border="none"-->
+<!--        :showWordLimit="true"-->
+<!--        v-model="userInfo.payPassword"-->
+<!--        inputAlign="right"-->
+<!--        :password="true"-->
+<!--        :disabled="true"-->
+<!--        :passwordVisibilityToggle="false"-->
+<!--        disabledColor=""-->
+<!--      ></up-input> &ndash;&gt;-->
+<!--      <text>* * * * * *</text>-->
+<!--    </view>-->
+    <up-picker
+      @confirm="changeSex"
+      @cancel="pickerSexShow = false"
+      :show="pickerSexShow"
+      :columns="[
+        [
+          { label: '男', id: 1 },
+          { label: '女', id: 2 },
+          { label: '保密', id: 3 },
+        ],
+      ]"
+      keyName="label"
+      valueName="id"
+    ></up-picker>
+    <button
+      @click="submitFn"
+      class="submit-btn"
+    >提交</button>
+    <!-- 页面内 容结束 -->
+    <PayPop ref="paypopRef" :pwdlength="6" @pwd_e="handlerPwd"></PayPop>
+  </view>
+</template>
+
+<script setup>
+import { ref, computed, nextTick } from "vue";
+import PayPop from "../../../components/pay-pop/pay-pop.vue";
+import { useImageUpload } from "@/hooks/useImageUpload";
+import { useAppStore } from "@/stores/app";
+import { onLoad } from "@dcloudio/uni-app";
+import { useToast } from "@/hooks/useToast";
+import { getUserInfo, userEdit, registerpayPasswordAPI } from "@/api/user";
+import { getCity } from "@/api/api.js";
+import Cache from "@/utils/cache";
+import { telEncrypt } from "@/utils/util.js";
+const paypopRef = ref(null);
+const { Toast } = useToast();
+const { imageList, afterRead, deletePic, uploadLoading } = useImageUpload({
+  pid: 5,
+  model: "book",
+});
+const appStore = useAppStore();
+const userInfo = ref({
+  avatar: "",
+  nickname: "",
+  addres: "",
+  mark: "",
+  sex: "",
+  age: "",
+});
+const pickerSexShow = ref(false);
+const sexText = computed(() => {
+  return userInfo.value.sex == 1
+    ? "男"
+    : userInfo.value.sex == 2
+    ? "女"
+    : userInfo.value.sex == 3
+    ? "保密"
+    : "未知";
+});
+
+//省市区选择
+const district = ref([]);
+const multiArray = ref([[], [], []]);
+const multiIndex = ref([0, 0, 0]);
+const region = ref(["省", "市", "区"]);
+const valueRegion = ref([0, 0, 0]);
+
+onLoad(() => {
+  console.log("personal_info 页面 onLoad");
+  fetchUserInfo();
+  getCityList();
+});
+
+const changeSex = (e) => {
+  console.log("changeSex", e.value[0]);
+  userInfo.value.sex = e.value[0].id;
+  pickerSexShow.value = false;
+  // change();
+};
+// 设置支付密码
+const setPayword = () => {
+  console.log(111111);
+
+  console.log(paypopRef.value);
+  nextTick(() => {
+    paypopRef.value.Open();
+  });
+};
+const handlerPwd = async (e) => {
+  const res = await registerpayPasswordAPI({
+    account: appStore.userInfo.phone,
+    payPassword: e,
+  });
+  uni.showToast({
+    title: "修改成功",
+    duration: 2000,
+  });
+  change();
+};
+// 获取用户头像
+async function getImage() {
+  console.log("getImage", imageList.value[0]);
+  if (imageList.value.length > 0) {
+    if (imageList.value[0].status == "success") {
+      userInfo.value.avatar = imageList.value[0].info.url;
+      // change();
+    } else {
+      Toast({ title: "上传失败" });
+    }
+  }
+  imageList.value = [];
+}
+function submitFn() {
+  change();
+}
+function changeName(e) {
+  // console.log(e)
+  // console.log(userInfo.value)
+}
+const change = async () => {
+  await userEdit(userInfo.value);
+  Toast({ title: "修改成功", endtime: 1500 });
+  appStore.USERINFO();
+  setTimeout(() => {
+    uni.navigateBack();
+  }, 1600);
+  // const { data } = await getUserInfo(appStore.uid);
+  // appStore.UPDATE_userPanelInfo(data);
+};
+// 获取用户信息
+async function fetchUserInfo() {
+  try {
+    const { data } = await getUserInfo(appStore.uid);
+    userInfo.value = data;
+    userInfo.value.addres = userInfo.value.addres || "";
+    const list = userInfo.value.addres.split("-");
+    if (list.length > 0) {
+      region.value = [list[0], list[1], list[2]];
+    }
+  } catch (error) {
+    console.error("otherUserinfo", error);
+    Toast({ title: "获取用户信息失败" });
+  }
+}
+
+function bindRegionChange(e) {
+  const mi = multiIndex.value;
+  const province = district.value[mi[0]] || { child: [] };
+  const ma = multiArray.value;
+  const value = e.detail.value;
+  region.value = [ma[0][value[0]], ma[1][value[1]], ma[2][value[2]]];
+  userInfo.value.addres = region.value.join("-");
+  valueRegion.value = [0, 0, 0];
+  //   change();
+  initialize();
+}
+
+function getCityList() {
+  getCity().then((res) => {
+    district.value = res.data;
+    let oneDay = 24 * 3600 * 1000;
+    Cache.setItem({ name: "cityList", value: res.data, expires: oneDay * 7 }); //设置七天过期时间
+    initialize();
+  });
+}
+function initialize() {
+  if (district.value.length) {
+    let province = [],
+      city = [],
+      area = [];
+    let cityChildren = district.value[0].child || [];
+    let areaChildren = cityChildren.length ? cityChildren[0].child || [] : [];
+    district.value.forEach((item) => province.push(item.name));
+    cityChildren.forEach((item) => city.push(item.name));
+    areaChildren.forEach((item) => area.push(item.name));
+    multiArray.value = [province, city, area];
+  }
+}
+function bindMultiPickerColumnChange(e) {
+  const column = e.detail.column;
+  const value = e.detail.value;
+  const ma = multiArray.value;
+  const mi = multiIndex.value;
+  mi[column] = value;
+  switch (column) {
+    case 0:
+      const currentCity = district.value[value] || { child: [] };
+      const areaList = currentCity.child[0] || { child: [] };
+      ma[1] = currentCity.child.map((item) => item.name);
+      ma[2] = areaList.child.map((item) => item.name);
+      break;
+    case 1:
+      const cityList = district.value[mi[0]].child[mi[1]].child || [];
+      ma[2] = cityList.map((item) => item.name);
+      break;
+    case 2:
+      break;
+  }
+  multiArray.value = [...ma];
+  multiIndex.value = [...mi];
+}
+</script>
+
+<style lang="scss">
+.personal-info {
+  padding: 0 30rpx;
+
+  .upload-block {
+    display: flex;
+    justify-content: center;
+    width: 90vw;
+    box-sizing: border-box;
+    padding: 80rpx 0;
+  }
+  .personal-info-item {
+    height: 100rpx;
+    line-height: 100rpx;
+    padding: 0 30rpx;
+    box-sizing: border-box;
+    border-radius: 16rpx;
+    background-color: #FFF;
+    margin-bottom: 30rpx;
+    .label_width {
+      width: 200rpx;
+      display: inline-block;
+    }
+  }
+  .submit-btn {
+    font-size: 32rpx;
+    color: #333;
+    height: 88rpx;
+    line-height: 88rpx;
+    border-radius: 16rpx;
+    background-color: #F8C008;
+    border: none;
+    margin-top: 20px;
+  }
+}
+</style>

File diff suppressed because it is too large
+ 599 - 516
pages/users/user_address/index.vue


File diff suppressed because it is too large
+ 507 - 541
pages/users/user_address_list/index.vue


+ 547 - 0
pages/users/user_address_list/index_bf.vue

@@ -0,0 +1,547 @@
+<template>
+  <view>
+    <!-- #ifdef APP-->
+    <view class="status_1"></view>
+    <!-- #endif -->
+    <view class="line">
+      <image
+        src="../../../static/images/line.jpg"
+        v-if="addressList.length"
+      ></image>
+    </view>
+    <view
+      class="address-management"
+      :class="addressList.length < 1 && page > 1 ? 'fff' : ''"
+    >
+      <up-radio-group
+        class="radio-group"
+        @change="radioChange"
+        v-if="addressList.length"
+        activeColor="#F8C008"
+        v-model="currentCheckedValue"
+      >
+        <view
+          class="item borRadius14"
+          v-for="(item, index) in addressList"
+          :key="index"
+        >
+          <view class="address" @click="goOrder(item.id)">
+            <view class="consignee"
+              >收货人:{{ item.realName
+              }}<text class="phone">{{ item.phone }}</text></view
+            >
+            <view
+              >收货地址:{{ item.province }}{{ item.city }}{{ item.district
+              }}{{ item.detail }}</view
+            >
+          </view>
+          <view class="operation acea-row row-between-wrapper">
+            <!-- #ifndef MP -->
+            <up-radio
+              class="radio"
+              :value="index.toString()"
+              :name="item.id"
+              label="设为默认"
+            >
+            </up-radio>
+            <!-- #endif -->
+            <!-- #ifdef MP -->
+            <up-radio class="radio" :name="item.id" label="设为默认"></up-radio>
+            <!-- #endif -->
+            <view class="acea-row row-middle">
+              <view @click="editAddressFn(item.id)"
+                ><text class="iconfont icon-bianji"></text>编辑</view
+              >
+              <view @click="delAddressFn(index)"
+                ><text class="iconfont icon-shanchu"></text>删除</view
+              >
+            </view>
+          </view>
+        </view>
+      </up-radio-group>
+      <view
+        class="loadingicon acea-row row-center-wrapper"
+        v-if="addressList.length"
+      >
+        <text
+          class="loading iconfont icon-jiazai"
+          :hidden="loading == false"
+        ></text
+        >{{ loadTitle }}
+      </view>
+      <view class="noCommodity" v-if="addressList.length < 1 && page > 1">
+        <view class="pictrue">
+          <image :src="HTTP_REQUEST_URL_IMG+'noAddress.png'"></image>
+        </view>
+      </view>
+      <view style="height: 120rpx"></view>
+    </view>
+    <view class="footer acea-row row-between-wrapper">
+      <!-- #ifdef MP-->
+      <view class="addressBnt bg-color" @click="addAddress"
+        ><text class="iconfont icon-tianjiadizhi"></text>添加新地址</view
+      >
+      <view class="addressBnt wxbnt" @click="getWxAddress"
+        ><text class="iconfont icon-weixin2"></text>导入微信地址</view
+      >
+      <!-- #endif -->
+      <!-- #ifdef H5-->
+
+      <view
+        class="addressBnt bg-color"
+        :class="wechat.isWeixin() ? '' : 'on'"
+        @click="addAddress"
+        ><text class="iconfont icon-tianjiadizhi"></text>添加新地址</view
+      >
+      <view
+        v-if="wechat.isWeixin()"
+        class="addressBnt wxbnt"
+        @click="getAddress"
+        ><text class="iconfont icon-weixin2"></text>导入微信地址</view
+      >
+      <!-- #endif -->
+
+      <!-- #ifdef APP-->
+      <view class="addressBnt on bg-color" @click="addAddress"
+        ><text class="iconfont icon-tianjiadizhi"></text>添加新地址
+      </view>
+      <!-- #endif -->
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { ref, computed, watch } from "vue";
+import { useAppStore } from "@/stores/app.js";
+import { onLoad, onShow, onReachBottom } from "@dcloudio/uni-app";
+import {
+  getAddressList,
+  setAddressDefault,
+  delAddress,
+  editAddress,
+} from "@/api/user.js";
+import { toLogin } from "@/libs/login.js";
+import { useToast } from "@/hooks/useToast.js";
+import wechat from "@/libs/wechat.js";
+const { Toast } = useToast();
+const appStore = useAppStore();
+import { HTTP_REQUEST_URL_IMG } from "@/config/app";
+
+const addressList = ref([]);
+const cartId = ref("");
+const pinkId = ref(0);
+const couponId = ref(0);
+const loading = ref(false);
+const loadend = ref(false);
+const loadTitle = ref("加载更多");
+const page = ref(1);
+const limit = ref(20);
+const isAuto = ref(false);
+const isShowAuth = ref(false);
+const bargain = ref(false);
+const combination = ref(false);
+const secKill = ref(false);
+const preOrderNo = ref(0);
+const isFlashSale = ref(false); // 是否为秒杀订单
+const isGroupBuy = ref(false); // 是否为团购订单
+const currentCheckedValue = ref("");
+
+watch(
+  () => appStore.isLogin,
+  (newV) => {
+    if (newV) {
+      getUserAddress(true);
+    }
+  }
+);
+
+function getUserAddress(isPage) {
+  getAddressListFn(isPage);
+}
+
+onLoad((options) => {
+  if (appStore.isLogin) {
+    preOrderNo.value = options.preOrderNo || 0;
+    isFlashSale.value = options.isFlashSale === "1"; // 接收秒杀订单标识
+    isGroupBuy.value = options.isGroupBuy === "1"; // 接收团购订单标识
+    getAddressListFn(true);
+  } else {
+    // toLogin();
+  }
+});
+
+onShow(() => {
+  getAddressListFn(true);
+});
+
+function onLoadFun() {
+  getAddressListFn();
+}
+
+function authColse(e) {
+  isShowAuth.value = e;
+}
+
+// 导入微信地址(小程序)
+function getWxAddress() {
+  uni.authorize({
+    scope: "scope.address",
+    success: function () {
+      uni.chooseAddress({
+        success: function (res) {
+          let addressP = {
+            province: res.provinceName,
+            city: res.cityName,
+            district: res.countyName,
+            cityId: 0,
+          };
+          editAddress({
+            address: addressP,
+            isDefault: true,
+            realName: res.userName,
+            postCode: res.postalCode,
+            phone: res.telNumber,
+            detail: res.detailInfo,
+            id: 0,
+          })
+            .then(() => {
+              Toast(
+                {
+                  title: "添加成功",
+                  icon: "success",
+                },
+                () => {
+                  getAddressListFn(true);
+                }
+              );
+            })
+            .catch((err) => {
+              return Toast({
+                title: err,
+              });
+            });
+        },
+        fail: function (res) {
+          if (res.errMsg == "chooseAddress:cancel")
+            return Toast({
+              title: "取消选择",
+            });
+        },
+      });
+    },
+    fail: function () {
+      uni.showModal({
+        title: "您已拒绝导入微信地址权限",
+        content: "是否进入权限管理,调整授权?",
+        success(res) {
+          if (res.confirm) {
+            uni.openSetting({
+              success: function (res) {
+                console.log(res.authSetting);
+              },
+            });
+          } else if (res.cancel) {
+            return Toast({
+              title: "已取消!",
+            });
+          }
+        },
+      });
+    },
+  });
+}
+
+// 导入微信地址(公众号)
+function getAddress() {
+  wechat.openAddress().then((userInfo) => {
+    editAddress({
+      realName: userInfo.userName,
+      phone: userInfo.telNumber,
+      address: {
+        province: userInfo.provinceName,
+        city: userInfo.cityName,
+        district: userInfo.countryName,
+        cityId: 0,
+      },
+      detail: userInfo.detailInfo,
+      postCode: userInfo.postalCode,
+      isDefault: true,
+    })
+      .then(() => {
+        Toast(
+          {
+            title: "添加成功",
+            icon: "success",
+          },
+          () => {
+            getAddressListFn(true);
+          }
+        );
+      })
+      .catch((err) => {
+        Toast({
+          title: err || "添加失败",
+        });
+      });
+  });
+}
+
+function getAddressListFn(isPage) {
+  if (isPage) {
+    loadend.value = false;
+    page.value = 1;
+    addressList.value = [];
+  }
+  if (loading.value || loadend.value) return;
+  loading.value = true;
+  loadTitle.value = "";
+  getAddressList({
+    page: page.value,
+    limit: limit.value,
+  })
+    .then((res) => {
+      let list = res.data.list;
+      let isLoadend = list.length < limit.value;
+      addressList.value = [...addressList.value, ...list];
+
+      const defaultAddress = addressList.value.find(item => item.isDefault);
+      console.log(defaultAddress)
+      if (defaultAddress) {
+        currentCheckedValue.value = defaultAddress.id;
+      } else if (addressList.value.length > 0) {
+        // 如果没有默认地址,选择第一个
+        currentCheckedValue.value = newList[0].id;
+      }
+      console.log('currentCheckedValue.value',currentCheckedValue.value)
+
+      loadend.value = isLoadend;
+      loadTitle.value = isLoadend ? "我也是有底线的" : "加载更多";
+      page.value = page.value + 1;
+      loading.value = false;
+    })
+    .catch(() => {
+      loading.value = false;
+      loadTitle.value = "加载更多";
+    });
+}
+
+// 设置默认地址
+function radioChange(e) {
+  const addressId = e; // 现在是地址ID
+  const address = addressList.value.find(item => item.id === addressId);
+  if (!address) return Toast({ title: "您设置的默认地址不存在!" });
+
+  setAddressDefault(addressId)
+      .then(() => {
+        // 更新所有地址的isDefault状态
+        addressList.value.forEach(item => {
+          item.isDefault = item.id === addressId;
+        });
+
+        // 更新当前选中的值
+        currentCheckedValue.value = addressId;
+
+        Toast(
+            {
+              title: "设置成功",
+              icon: "success",
+            },
+            () => {
+              addressList.value = [...addressList.value];
+            }
+        );
+      })
+      .catch((err) => {
+        return Toast({
+          title: err,
+        });
+      });
+}
+
+// 编辑地址
+function editAddressFn(id) {
+  const cart = cartId.value;
+  const pink = pinkId.value;
+  const coupon = couponId.value;
+  cartId.value = "";
+  pinkId.value = "";
+  couponId.value = "";
+  const flashSaleParam = isFlashSale.value ? "&isFlashSale=1" : "";
+  uni.navigateTo({
+    url: `/pages/users/user_address/index?id=${id}&cartId=${cart}&pinkId=${pink}&couponId=${coupon}&secKill=${secKill.value}&combination=${combination.value}&bargain=${bargain.value}&preOrderNo=${preOrderNo.value}${flashSaleParam}`,
+  });
+}
+
+// 删除地址
+function delAddressFn(index) {
+  let address = addressList.value[index];
+  if (address == undefined) return Toast({ title: "您删除的地址不存在!" });
+  delAddress(address.id)
+    .then(() => {
+      Toast(
+        {
+          title: "删除成功",
+          icon: "success",
+        },
+        () => {
+          addressList.value.splice(index, 1);
+          addressList.value = [...addressList.value];
+        }
+      );
+    })
+    .catch((err) => {
+      return Toast({
+        title: err,
+      });
+    });
+}
+
+// 新增地址
+function addAddress() {
+  cartId.value = "";
+  pinkId.value = "";
+  couponId.value = "";
+  const flashSaleParam = isFlashSale.value ? "&isFlashSale=1" : "";
+  const groupBuyParam = isGroupBuy.value ? "&isGroupBuy=1" : "";
+  uni.navigateTo({
+    url: `/pages/users/user_address/index?preOrderNo=${preOrderNo.value}${flashSaleParam}${groupBuyParam}`,
+  });
+}
+
+function goOrder(id) {
+  if (preOrderNo.value) {
+    // 根据订单类型跳转到不同的确认页面
+    if (isFlashSale.value) {
+      // 秒杀订单跳转到秒杀确认页面
+      uni.redirectTo({
+        url: `/pages/users/utils/flashSale/confirmOrder?is_address=1&preOrderNo=${preOrderNo.value}&addressId=${id}`,
+      });
+    } else if (isGroupBuy.value) {
+      // 团购支付返回到支付详情页
+      uni.redirectTo({
+        url: `/pages/group_buying/paydetail?is_address=1&preOrderNo=${preOrderNo.value}&addressId=${id}`,
+      });
+    } else {
+      // 普通订单跳转到普通确认页面
+      uni.redirectTo({
+        url: `/pages/users/order_confirm/index?is_address=1&preOrderNo=${preOrderNo.value}&addressId=${id}`,
+      });
+    }
+  }
+}
+
+onReachBottom(() => {
+  getAddressListFn();
+});
+</script>
+
+<style lang="scss" scoped>
+.address-management {
+  padding: 20rpx 30rpx;
+}
+
+.address-management.fff {
+  background-color: #fff;
+  height: 1300rpx;
+}
+
+.line {
+  width: 100%;
+  height: 3rpx;
+
+  image {
+    width: 100%;
+    height: 100%;
+    display: block;
+  }
+}
+
+.address-management .item {
+  background-color: #fff;
+  padding: 0 20rpx;
+  margin-bottom: 20rpx;
+  width: 100%;
+}
+
+.address-management .item .address {
+  padding: 35rpx 0;
+  border-bottom: 1rpx solid #eee;
+  font-size: 28rpx;
+  color: #282828;
+}
+
+.address-management .item .address .consignee {
+  font-size: 28rpx;
+  font-weight: bold;
+  margin-bottom: 8rpx;
+}
+
+.address-management .item .address .consignee .phone {
+  margin-left: 25rpx;
+}
+
+.address-management .item .operation {
+  height: 83rpx;
+  font-size: 28rpx;
+  color: #282828;
+}
+
+.address-management .item .operation .radio text {
+  margin-left: 13rpx;
+}
+
+.address-management .item .operation .iconfont {
+  color: #2c2c2c;
+  font-size: 35rpx;
+  vertical-align: -2rpx;
+  margin-right: 10rpx;
+}
+
+.address-management .item .operation .iconfont.icon-shanchu {
+  margin-left: 35rpx;
+  font-size: 38rpx;
+}
+
+.footer {
+  position: fixed;
+  width: 100%;
+  background-color: #fff;
+  bottom: 0;
+  height: 106rpx;
+  padding: 0 30rpx;
+  box-sizing: border-box;
+}
+
+.footer .addressBnt {
+  width: 330rpx;
+  font-weight: bold;
+  height: 76rpx;
+  border-radius: 50rpx;
+  text-align: center;
+  line-height: 76rpx;
+  font-size: 30rpx;
+  color: #fff;
+}
+
+.footer .addressBnt.on {
+  width: 690rpx;
+  margin: 0 auto;
+}
+
+.footer .addressBnt .iconfont {
+  font-size: 35rpx;
+  margin-right: 8rpx;
+  vertical-align: -1rpx;
+}
+
+.footer .addressBnt.wxbnt {
+  background-color: #fe960f;
+}
+
+.status_1 {
+  display: flex;
+  width: 750rpx;
+  // background-color: #E93323;
+  height: var(--status-bar-height);
+}
+</style>

BIN
static/images/balance-icon.png


BIN
static/images/line.png