Selaa lähdekoodia

```
feat(upimg): 添加图片上传组件的选择图片方法

- 新增selectImage方法用于选择图片
- 修改图片预览时的路径访问方式

fix(attestation): 完善认证页面的上传功能和编辑逻辑

- 添加上传遮罩层阻止重复点击
- 实现上传提示弹窗和倒计时功能
- 修复编辑模式下的表单数据回显问题
- 添加图片处理失败时的错误提示

refactor(index): 优化首页的登录流程和数据加载

- 将登录方式改为微信手机号授权
- 替换onLoad为onShow钩子确保页面显示时执行
- 移除废弃的轮播图组件和相关代码
- 优化CSS样式实现文本溢出省略

fix(allInstructor): 修复教练列表页面的数据请求

- 移除重复的生命周期函数导入
- 修正教练列表查询接口调用

chore(vue-global-types): 更新Vue全局类型定义文件

- 调整全局变量声明结构
- 修正组件类型定义中的泛型参数默认值
- 更新props类型推导逻辑
- 移除未使用的类型定义

refactor(writeComments): 优化评论页面的图片上传配置

- 移除硬编码的上传URL配置
- 修正匿名评价图标状态判断逻辑

fix(feedback): 修复反馈页面的图片上传功能

- 移除硬编码的上传URL配置
- 修正图片数组连接逻辑

refactor(mine): 优化个人中心页面的登录功能

- 统一登录流程为手机号授权方式
- 添加登录相关的UI组件和样式

refactor(orderInfo): 优化订单详情页面的登录功能

- 添加登录组件到订单列表底部
- 实现完整的手机号授权登录流程
- 修正条件渲染中的空格问题

style(toBeUsed): 调整待使用页面的布局细节

- 修正条件判断中的空格格式
- 更新联系方式显示逻辑

refactor(useNotice): 简化使用须知页面的依赖引入

- 移除未使用的Vue API导入

fix(http): 修正HTTP客户端的基础URL配置

- 注释掉测试环境的baseURL配置
- 确保使用正确的API基础地址
```

zouzexu 1 päivä sitten
vanhempi
commit
9c3e432b86

+ 5 - 10
node_modules/.vue-global-types/vue_3.5_0.d.ts

@@ -1,9 +1,9 @@
 // @ts-nocheck
 export {};
+declare global {
+	var __VLS_PROPS_FALLBACK: Record<string, unknown>;
 
-; declare global {
 	const __VLS_directiveBindingRestFields: { instance: null, oldValue: null, modifiers: any, dir: any };
-	const __VLS_unref: typeof import('vue').unref;
 	const __VLS_placeholder: any;
 	const __VLS_intrinsics: import('vue/jsx-runtime').JSX.IntrinsicElements;
 
@@ -13,7 +13,7 @@ export {};
 	type __VLS_IsAny<T> = 0 extends 1 & T ? true : false;
 	type __VLS_PickNotAny<A, B> = __VLS_IsAny<A> extends true ? B : A;
 	type __VLS_SpreadMerge<A, B> = Omit<A, keyof B> & B;
-	type __VLS_WithComponent<N0 extends string, LocalComponents, Self, N1 extends string, N2 extends string, N3 extends string> =
+	type __VLS_WithComponent<N0 extends string, LocalComponents, Self, N1 extends string, N2 extends string = N1, N3 extends string = N1> =
 		N1 extends keyof LocalComponents ? { [K in N0]: LocalComponents[N1] } :
 		N2 extends keyof LocalComponents ? { [K in N0]: LocalComponents[N2] } :
 		N3 extends keyof LocalComponents ? { [K in N0]: LocalComponents[N3] } :
@@ -35,7 +35,7 @@ export {};
 			attrs?: any;
 			slots?: T extends { $slots: infer Slots } ? Slots : Record<string, any>;
 			emit?: T extends { $emit: infer Emit } ? Emit : {};
-			props?: (T extends { $props: infer Props } ? Props : {}) & Record<string, unknown>;
+			props?: typeof props;
 			expose?: (exposed: T) => void;
 		};
 	};
@@ -95,12 +95,7 @@ export {};
 	type __VLS_ResolveDirectives<T> = {
 		[K in keyof T & string as `v${Capitalize<K>}`]: T[K];
 	};
-	type __VLS_PrettifyGlobal<T> = { [K in keyof T as K]: T[K]; } & {};
-	type __VLS_WithDefaultsGlobal<P, D> = {
-		[K in keyof P as K extends keyof D ? K : never]-?: P[K];
-	} & {
-		[K in keyof P as K extends keyof D ? never : K]: P[K];
-	};
+	type __VLS_PrettifyGlobal<T> = (T extends any ? { [K in keyof T]: T[K]; } : { [K in keyof T as K]: T[K]; }) & {};
 	type __VLS_UseTemplateRef<T> = Readonly<import('vue').ShallowRef<T | null>>;
 	type __VLS_ProxyRefs<T> = import('vue').ShallowUnwrapRef<T>;
 

+ 7 - 2
src/components/sunui-upimg/sunui-upimg.vue

@@ -6,7 +6,8 @@
 					:class="[item.upload_percent < 100 ? 'sunui-uploader-file-status' : '']"
 					@click="previewImage(index)">
 					<!-- step1.这里修改服务器返回字段 !!! -->
-					<image class="sunui-uploader-img" lazy-load :style="upload_img_wh" :src="item.path" mode="aspectFill" />
+					<image class="sunui-uploader-img" lazy-load :style="upload_img_wh" :src="item.path"
+						mode="aspectFill" />
 					<view class="sunui-img-removeicon right" @click.stop="removeImage(index)" v-show="upimg_move">×
 					</view>
 					<view class="sunui-loader-filecontent" v-if="item.upload_percent < 100">{{ item.upload_percent }}%
@@ -37,6 +38,7 @@ export default {
 		url: {
 			type: String,
 			default: 'https://api.qlapp.cn/jeecgboot/sys/common/upload'
+			// default: 'http://192.168.0.11:8080/jeecg-boot/sys/common/upload'
 		},
 		// 上传样式宽高
 		upload_img_wh: {
@@ -132,6 +134,9 @@ export default {
 					uni.hideLoading();
 				});
 		},
+		selectImage() {
+			this.chooseImage();
+		},
 		chooseImage() {
 			let _self = this;
 			uni.chooseImage({
@@ -219,7 +224,7 @@ const upload = function (options) {
 			try {
 				//Tip : 切记->主要修改这里图片的返回值为真实返回路径!!! 详情见示例
 				data = JSON.parse(res.data).message;
-				console.log('上传成功1', data);
+				console.log('上传结果', data);
 			} catch (e) {
 				throw (e, data);
 			}

+ 44 - 43
src/pages/index/allInstructor/index.vue

@@ -3,60 +3,61 @@
 		<view class="a-instructor-card" v-for="item in instructorList" :key="item.id" @click="to_instructor(item)">
 			<image class="instructor-img" :src="item.avatar" mode=""></image>
 			<view class="a-instructor-name">
-				<view class="name">{{item.realname}}</view>
-				<view class="type">{{item.trainingProgramsName}}</view>
+				<view class="name">{{ item.realname }}</view>
+				<view class="type">{{ item.trainingProgramsName }}</view>
 			</view>
 		</view>
 	</view>
 </template>
 
 <script lang="ts" setup>
-	import { ref, onMounted, computed } from 'vue'
-	import { onLoad, onReachBottom } from '@dcloudio/uni-app'
-	import { http } from '@/utils/http'
-	import zsEmpty from '@/components/zs-empty/index.vue'
-	onMounted(()=>{
-		get_findCoachList()
+import { ref, onMounted } from 'vue'
+import { http } from '@/utils/http'
+onMounted(() => {
+	get_findCoachList()
+})
+const to_instructor = (e) => {
+	uni.navigateTo({
+		url: `/pages/index/instructorDetail/index?id=${e.id}`
 	})
-	const to_instructor=(e)=>{
-		uni.navigateTo({
-			url:`/pages/index/instructorDetail/index?id=${e.id}`
-		})
-	}
-	
-	const instructorList=ref()
-	const get_findCoachList=()=>{
-		http.get('/coachC/findCoachList',{loading:true}).then((res)=>{
-			instructorList.value=res.result
-		})
-	}
+}
+
+const instructorList = ref()
+const get_findCoachList = () => {
+	http.get('/coachC/findCoachList', { loading: true }).then((res) => {
+		instructorList.value = res.result
+	})
+}
 </script>
 
 <style lang="less" scoped>
-	.a-instructor-card{
-		display: flex;
-		align-items: center;
-		gap: 20rpx;
-		background: #FFFFFF;
-		border-radius: 32rpx;
-		padding: 20rpx;
-		margin-top: 20rpx;
-		.instructor-img{
-			width: 120rpx;
-			height: 120rpx;
-			border-radius: 50%;
+.a-instructor-card {
+	display: flex;
+	align-items: center;
+	gap: 20rpx;
+	background: #FFFFFF;
+	border-radius: 32rpx;
+	padding: 20rpx;
+	margin-top: 20rpx;
+
+	.instructor-img {
+		width: 120rpx;
+		height: 120rpx;
+		border-radius: 50%;
+	}
+
+	.a-instructor-name {
+		.name {
+			font-weight: bold;
+			font-size: 32rpx;
+			color: #222222;
 		}
-		.a-instructor-name{
-			.name{
-				font-weight: bold;
-				font-size: 32rpx;
-				color: #222222;
-			}
-			.type{
-				margin-top: 20rpx;
-				font-size: 28rpx;
-				color: #AAAAAA;
-			}
+
+		.type {
+			margin-top: 20rpx;
+			font-size: 28rpx;
+			color: #AAAAAA;
 		}
 	}
+}
 </style>

+ 89 - 4
src/pages/index/attestation/index.vue

@@ -40,7 +40,11 @@
 				<view class="">近期照片</view>
 				<sunui-upimg :header="{ 'x-access-token': cache.get('TOKEN') }" ref="upload1" title="店铺logo"
 					@change="handleChange" :upload_count="1" :previewImageUrl="formData.realNameImg"
-					@remove="removeImages"></sunui-upimg>
+					@remove="removeImages" :style="{ pointerEvents: showOverlay ? 'none' : 'auto' }">
+				</sunui-upimg>
+				<!-- 提示框拦截点击事件 -->
+				<view v-if="!formData.realNameImg" class="upload-overlay" @click="handleUploadClick">
+				</view>
 			</view>
 			<view class="form-tips-upload">请上传近期高清、无遮挡照片</view>
 		</view>
@@ -49,6 +53,12 @@
 			<button hover-class="hover-btn" v-else @click="submit">下一步</button>
 		</view>
 	</view>
+	<uni-popup ref="tipsPopup" type="center" :is-mask-click="false" width="700rpx" :height="'auto'">
+		<view class="tipsPopup-content">
+			<image class="tipsPopup-img" :src="tipsImgUrl" mode="widthFix" />
+			<view class="tipsPopup-text">我知道了({{ countdown }}s)</view>
+		</view>
+	</uni-popup>
 </template>
 
 <script setup>
@@ -71,20 +81,56 @@ const formData = ref({
 	userId: cache.get('SHARER_ID') || null,
 })
 
+
 const frontImg = ref('')
 const flipSideImg = ref('')
 const isEdit = ref(false)
+const newFormData = ref({
+	identityCard: null,
+	phone: null,
+})
 onLoad((option) => {
 	if (option.edit) {
 		formData.value = JSON.parse(option.userData)
+		newFormData.value.identityCard = formData.value.identityCard;
+		newFormData.value.phone = formData.value.phone;
 		formData.value.identityCard = idCardHide(formData.value.identityCard);
 		formData.value.phone = phoneHide(formData.value.phone);
+
 		isEdit.value = option.edit
-		console.log(option, '编辑');
+		showOverlay.value = false;
+		hasShownTip.value = true;
+		console.log(newFormData.value, '编辑');
 	}
 })
+
+const showOverlay = ref(true);
+const tipsPopup = ref(null);
+const upload1 = ref(null);
+const tipsImgUrl = 'https://national-motion.oss-cn-beijing.aliyuncs.com/opt/upFiles/EMoDXGUrpuCtb560b5ae5cc44a9f4412b567e79ac045_1764126985962.jpg';
+const countdown = ref(3);
+const hasShownTip = ref(false);
+// 添加 handleUploadClick 方法
+const handleUploadClick = () => {
+	tipsPopup.value.open();
+	countdown.value = 3;
+	const countdownInterval = setInterval(() => {
+		countdown.value--;
+		if (countdown.value <= 0) {
+			clearInterval(countdownInterval);
+		}
+	}, 1000);
+	setTimeout(() => {
+		tipsPopup.value.close();
+		showOverlay.value = false;
+		hasShownTip.value = true;
+		upload1.value.selectImage();
+	}, 3000);
+};
 // 压缩图片处理
 const handleChange = async (e) => {
+	// tipsPopup.value.open();
+	// return
 	try {
 		const imageUrl = e.join(','); // 获取网络图片URL
 		const downloadRes = await uni.downloadFile({ url: imageUrl });
@@ -111,6 +157,7 @@ const handleChange = async (e) => {
 		});
 	} catch (error) {
 		console.error('图片处理失败:', error);
+		TipsUtils.tips_toast('图片处理失败,请重新上传:', error.errMsg);
 		formData.value.realNameImg = imageUrl;
 		console.log('上传图片返回的地址:', formData.value.realNameImg);
 	}
@@ -131,7 +178,7 @@ const checkImageSizeBeforeSubmit = async () => {
 			throw new Error('图片下载失败');
 		}
 		const fileInfo = await uni.getFileInfo({ filePath: downloadRes.tempFilePath });
-		console.log(fileInfo,'图片信息');
+		console.log(fileInfo, '图片信息');
 		// 如果图片小于60KB (60 * 1024 字节),提示重新上传
 		if (fileInfo.size < 60 * 1024) {
 			TipsUtils.tips_toast('图片大小不能小于60KB,请重新上传');
@@ -147,7 +194,12 @@ const checkImageSizeBeforeSubmit = async () => {
 
 const editSubmit = () => {
 	if (!formData.value.realNameImg) return TipsUtils.tips_toast('请上传近期高清、无遮挡照片');
-	http.post('/my/familyMembers/editFamilyMembers', { ...formData.value }, { loading: true }).then((res) => {
+	const from = {
+		...formData.value,
+		identityCard: isEdit.value ? newFormData.value.identityCard : formData.value.identityCard,
+		phone: isEdit.value ? newFormData.value.phone : formData.value.phone,
+	}
+	http.post('/my/familyMembers/editFamilyMembers', { ...from }, { loading: true }).then((res) => {
 		TipsUtils.tips_toast(res.message)
 		setTimeout(() => {
 			uni.navigateBack()
@@ -299,6 +351,14 @@ const getFaceRecognition = () => {
 			font-weight: bold;
 			font-size: 28rpx;
 			color: #222222;
+			position: relative;
+
+			.upload-overlay {
+				position: absolute;
+				left: 200rpx;
+				width: 100rpx;
+				height: 100rpx;
+			}
 		}
 
 		.form-tips {
@@ -342,4 +402,29 @@ const getFaceRecognition = () => {
 		}
 	}
 }
+
+.tipsPopup-content {
+	// background: #fff;
+	padding: 40rpx;
+	border-radius: 20rpx;
+	position: relative;
+
+	.tipsPopup-img {
+		width: 600rpx;
+		border-radius: 16rpx 16rpx 0 0;
+	}
+
+	.tipsPopup-text {
+		position: absolute;
+		background: #fff;
+		width: 600rpx;
+		bottom: -10rpx;
+		height: 80rpx;
+		text-align: center;
+		font-size: 26rpx;
+		color: #30f000;
+		line-height: 80rpx;
+		border-radius: 0 0 16rpx 16rpx;
+	}
+}
 </style>

+ 61 - 29
src/pages/index/index.vue

@@ -36,8 +36,6 @@
 			</view>
 			<view style="height: 34rpx;"></view>
 			<liu-slide-img :list="bannerList" :type="2" :interval="3000" :indicator-show="false"></liu-slide-img>
-			<!-- <zs-banner type="2" radius="30rpx" previousMargin="40rpx" nextMargin="40rpx" spacing="20rpx"
-				:isIndicator="false" :autoplay="true" :bannerList="bannerList" height="300rpx"></zs-banner> -->
 		</view>
 	</view>
 	<view class="content">
@@ -186,17 +184,18 @@
 			<!-- </view> -->
 		</view>
 		<view class="login-tips" v-if="!token">
-			<view class="">终于等到你!快去登录吧~</view>
-			<view class="" @click="submitLogin">马上登录</view>
+			<view class="login-text">终于等到你!快去登录吧~</view>
+			<view class="login-btn" @click="submitLogin">马上登录</view>
+			<button type="default" open-type="getPhoneNumber" @getphonenumber="decryptPhoneNumber"
+				class="getPhoneNumber-btn"></button>
 		</view>
 	</view>
 </template>
 
 <script setup lang="ts">
 import zsLoading from '@/components/zzx-loading/zzx-loading.vue';
-import zsBanner from '@/components/zs-banner/index.vue';
 import { ref, onMounted, computed } from 'vue'
-import { onLoad, onPageScroll, onPullDownRefresh, onShareAppMessage } from '@dcloudio/uni-app';
+import { onShow, onPageScroll, onPullDownRefresh, onShareAppMessage } from '@dcloudio/uni-app';
 import zsEmpty from '@/components/zs-empty/index.vue'
 import { TipsUtils, RouterUtils } from '@/utils/util';
 import { http } from '@/utils/http'
@@ -213,7 +212,7 @@ const instructorList = ref();
 const indexLoading = ref(true);
 const hotInstructorImg1 = ref('https://national-motion.oss-cn-beijing.aliyuncs.com/opt/upFiles/dxVfKxD7aH2397154f377d68fb59a71226c9c2f078a9_1758071827887.png')
 const hotInstructorImg2 = ref('https://national-motion.oss-cn-beijing.aliyuncs.com/opt/upFiles/uv0VmclIvXiJc1081e0e33e281a8a436d24ec9ca87c3_1758071769194.png')
-onLoad(() => {
+onShow(() => {
 	get_location()
 })
 onShareAppMessage(() => {
@@ -246,11 +245,7 @@ const get_navheight = () => {
 	navBarHeight.value = statusBarHeight.value + titleBarHeight.value;
 }
 
-const currentIndex = ref(0);
 const bannerList = ref([])
-const swierChange = (e) => {
-	currentIndex.value = e.detail.current
-}
 
 const gotoPage = (path: string) => {
 	// if (!token.value) return TipsUtils.tips_alert('请先登录~', false)
@@ -259,23 +254,49 @@ const gotoPage = (path: string) => {
 	})
 }
 
-const submitLogin = () => {
-	uni.login({
-		provider: 'weixin',
-		success: (res) => {
-			get_logininfo(res.code)
-		}
-	})
+// 手机号授权登录
+const phoneCode = ref('')
+const decryptPhoneNumber = (e: any) => {
+	phoneCode.value = e.detail.code
+	if (e.detail.code) {
+		uni.login({
+			provider: 'weixin',
+			success: (res) => {
+				get_logininfo(res.code)
+			}
+		})
+	}
 }
+// 微信code登录
+// const submitLogin = () => {
+// 	uni.login({
+// 		provider: 'weixin',
+// 		success: (res) => {
+// 			get_logininfo(res.code)
+// 		}
+// 	})
+// }
 
 const get_logininfo = (item: string) => {
 	http.get('/user/loginByCode', { data: { code: item }, loading: true }).then(res => {
 		cache.set('TOKEN', res.result.token)
 		cache.set('USER_INFO', res.result)
+		getMobilePhone(phoneCode.value)
+	})
+}
+
+const getMobilePhone = (code: string) => {
+	http.get('/user//getMobilePhone', { data: { code: code }, loading: true }).then(res => {
 		get_indexInfo()
 		get_message()
 		get_searchList()
 		get_userinfo()
+	})
+}
+
+const get_userinfo = () => {
+	http.get('/user/getUserInfo', { loading: true }).then(res => {
+		cache.set('USER_INFO', res.result)
 		TipsUtils.tips_toast('登录成功')
 		if (cache.get('SHARER_ID') && token.value) {
 			gotoPage('/pages/index/userList/index')
@@ -304,12 +325,6 @@ const get_logininfo = (item: string) => {
 	})
 }
 
-const get_userinfo = () => {
-	http.get('/user/getUserInfo', { loading: true }).then(res => {
-		cache.set('USER_INFO', res.result)
-	})
-}
-
 const get_location = () => {
 	uni.authorize({
 		scope: 'scope.userLocation',
@@ -330,7 +345,7 @@ const get_location = () => {
 					uni.hideLoading()
 					cache.set('LON', res.longitude)
 					cache.set('LAT', res.latitude)
-					getAddressInfo()
+					// getAddressInfo()
 				},
 				fail: function (err) {
 					if (err.errMsg === 'getFuzzyLocation:fail system permission denied') {
@@ -350,7 +365,7 @@ const get_location = () => {
 	});
 }
 
-// 经纬度逆解析获取当前位置信息
+// 经纬度逆解析获取当前位置信息-----已弃用
 const getAddressInfo = () => {
 	const qqmapsdk = new QQMapWX({ key: 'IPQBZ-NTL35-DCDI7-IU6JL-LUMO2-5XB3W' });
 	qqmapsdk.reverseGeocoder({
@@ -378,7 +393,7 @@ const showAuthGuide = async () => {
 }
 
 // 手动选择
-const addressName = ref('选择定位')
+const addressName = ref('全龄动能')
 const openSellocation = () => {
 	uni.chooseLocation({
 		success: function (res) {
@@ -934,6 +949,15 @@ const searchInfoBtn = () => {
 			margin-top: 20rpx;
 			font-size: 24rpx;
 			color: #AAAAAA;
+			display: -webkit-box;
+			-webkit-line-clamp: 2;
+			-webkit-box-orient: vertical;
+			overflow: hidden;
+			text-overflow: ellipsis;
+			white-space: normal;
+			word-wrap: break-word;
+			word-break: break-all;
+
 		}
 
 		.i-course {
@@ -1002,12 +1026,12 @@ const searchInfoBtn = () => {
 	border-radius: 8rpx;
 	z-index: 9999;
 
-	&>view:first-child {
+	.login-text {
 		font-size: 28rpx;
 		color: #FFFFFF;
 	}
 
-	&>view:last-child {
+	.login-btn {
 		width: 160rpx;
 		height: 60rpx;
 		background: #C8FF0C;
@@ -1017,5 +1041,13 @@ const searchInfoBtn = () => {
 		text-align: center;
 		line-height: 60rpx;
 	}
+
+	.getPhoneNumber-btn {
+		position: absolute;
+		right: 10rpx;
+		width: 160rpx;
+		height: 60rpx;
+		opacity: 0;
+	}
 }
 </style>

+ 8 - 7
src/pages/index/toBeUsed/index.vue

@@ -160,14 +160,14 @@
 				<view style="display: flex;align-items: center;justify-content: space-between;">
 					<view class="order-num" @click="selectOrderInfo(item, index)">
 						<text v-if="item.type != 6">{{ item.ticketNo }}&nbsp;&nbsp; {{ item.userName }}
-							{{item.classGroupingName }} {{ item.coachName }}</text>
-							<text v-if="!item.classGroupingName&& item.type ==5">暂未分班</text>
+							{{ item.classGroupingName }} {{ item.coachName }}</text>
+						<text v-if="!item.classGroupingName && item.type == 5">暂未分班</text>
 						<zzx-icon v-if="item.type != 6" name="ashRight" size="12"></zzx-icon>
 						<!-- <text v-if="item.type != 6 && orderPageInfo?.orderType == 1">{{ item.expireTime }}到期</text> -->
 					</view>
 					<!-- &&item.type != 5 -->
 					<view class="application-btn" @click="openRefund(item)"
-						v-if="(item.type == 1 || item.type == 2||item.type == 5) && (item.orderStatus == 1 && orderDetailInfo?.refundType != 2)">
+						v-if="(item.type == 1 || item.type == 2 || item.type == 5) && (item.orderStatus == 1 && orderDetailInfo?.refundType != 2)">
 						申请退款</view>
 				</view>
 			</view>
@@ -267,7 +267,7 @@
 			</view>
 			<view class="info-list">
 				<view class="item-left">手机号码</view>
-				<view class="item-right">{{ orderDetailInfo?.phoneNumber || orderDetailInfo?.phone }}</view>
+				<view class="item-right">{{ orderDetailInfo?.phoneNumber || '--' }}</view>
 			</view>
 			<view class="info-list">
 				<view class="item-left">订单编号</view>
@@ -508,7 +508,7 @@ const refundFromData = ref({
 	orderCode: '',
 	orderProInfoIds: '',
 	reason: '',
-	type:1
+	type: 1
 })
 const refund_btn = async () => {
 	if (refundFromData.value.reason == '') {
@@ -601,7 +601,7 @@ const open_map = () => {
 
 // 拨打电话
 const open_phone = () => {
-	if(!orderDetailInfo.value.phone) return TipsUtils.tips_toast('暂无联系电话')
+	if (!orderDetailInfo.value.phone) return TipsUtils.tips_toast('暂无联系电话')
 	uni.makePhoneCall({
 		phoneNumber: orderDetailInfo.value.phone
 	});
@@ -1101,6 +1101,7 @@ const getSignUrl = (signFlowId: string) => {
 			align-items: center;
 			gap: 8rpx;
 			width: 280rpx;
+
 			&>text {
 				margin-bottom: 10rpx;
 			}
@@ -1457,7 +1458,7 @@ const getSignUrl = (signFlowId: string) => {
 
 				.sign-names-container {
 					display: flex;
-					flex-wrap: wrap; 
+					flex-wrap: wrap;
 					flex: 1;
 					gap: 20rpx;
 				}

+ 14 - 14
src/pages/index/useNotice/index.vue

@@ -9,27 +9,27 @@
 </template>
 
 <script setup>
-import { ref, onMounted, computed } from 'vue';
+import { ref } from 'vue';
 import { onLoad } from '@dcloudio/uni-app';
-import { http } from '@/utils/http'
 
 const notice = ref('')
 onLoad((options) => {
-    notice.value = options.reminder || ''
+	notice.value = options.reminder || ''
 })
 </script>
 
 <style lang="less" scoped>
-	.u-tips-card{
-		margin-top: 20rpx;
-		padding: 20rpx;
-		background: #FFFFFF;
-		border-radius: 32rpx;
-		.item-tips{
-			font-weight: bold;
-			font-size: 28rpx;
-			color: #222222;
-			margin-bottom: 20rpx;
-		}
+.u-tips-card {
+	margin-top: 20rpx;
+	padding: 20rpx;
+	background: #FFFFFF;
+	border-radius: 32rpx;
+
+	.item-tips {
+		font-weight: bold;
+		font-size: 28rpx;
+		color: #222222;
+		margin-bottom: 20rpx;
 	}
+}
 </style>

+ 6 - 7
src/pages/index/writeComments/index.vue

@@ -11,13 +11,13 @@
 		<view class="w-content-card">
 			<textarea v-model="formData.evaluateContent" id="" cols="30" rows="10" maxlength="150"></textarea>
 			<view class="">
-				<sunui-upimg :url="upPicUrl" :header="{ 'x-access-token': cache.get('TOKEN') }" ref="upload1" title="店铺logo" @upload="handleLoaded1"
-					@change="handleChange" :number="9"></sunui-upimg>
+				<sunui-upimg :header="{ 'x-access-token': cache.get('TOKEN') }" ref="upload1" title="店铺logo"
+					@upload="handleLoaded1" @change="handleChange" :number="9"></sunui-upimg>
 			</view>
 		</view>
 		<view class="w-anonymity">
 			<view class="select-anonymity" @click="formData.isAnonymous = formData.isAnonymous === 1 ? 0 : 1">
-				<zzx-icon :name="formData.isAnonymous==0 ? 'selected' : 'unchecked'" size="14"></zzx-icon>
+				<zzx-icon :name="formData.isAnonymous == 0 ? 'selected' : 'unchecked'" size="14"></zzx-icon>
 				<view class="">匿名评价</view>
 			</view>
 			<view class="anonymity-tips">
@@ -35,13 +35,12 @@ import { TipsUtils } from '@/utils/util';
 import { http } from '@/utils/http';
 import { useCacheStore } from '@/stores/cache';
 const cache = useCacheStore()
-const upPicUrl = ref('http://192.168.0.11:8080/jeecg-boot/sys/common/upload')
-const siteName= ref('')
+const siteName = ref('')
 onLoad((options) => {
 	console.log(options);
 	formData.value.siteId = options.siteId
 	formData.value.orderId = options.orderId
-	siteName.value=options.siteName
+	siteName.value = options.siteName
 })
 const formData = ref({
 	score: 0,
@@ -56,7 +55,7 @@ const onRateChange = (e) => {
 }
 
 const handleChange = (e) => {
-	formData.value.images= e.join(',');
+	formData.value.images = e.join(',');
 }
 const publish = () => {
 	http.post('/my/evaluate/submitFeedback', formData.value, { loading: true }).then((res) => {

+ 7 - 6
src/pages/mine/feedback/index.vue

@@ -9,8 +9,9 @@
 		<view class="f-issue-card">
 			<view class="f-title">(必填)请选择您在使用过程中遇到的问题</view>
 			<view class="item-issue-box">
-				<view :class="[selectType == item.value ? 'sel-item-issue' : 'item-issue']" v-for="(item, index) in issueType"
-					:key="item.value" @click="selectItem(item)">{{ item.text }}</view>
+				<view :class="[selectType == item.value ? 'sel-item-issue' : 'item-issue']"
+					v-for="(item, index) in issueType" :key="item.value" @click="selectItem(item)">{{ item.text }}
+				</view>
 			</view>
 		</view>
 		<view class="f-issuedes-card">
@@ -23,8 +24,8 @@
 		<view class="f-uploadimg">
 			<view class="f-title">上传图片(最多9张)</view>
 			<view class="">
-				<sunui-upimg :url="upPicUrl" :header="{ 'x-access-token': cache.get('TOKEN') }" ref="upload1"
-					title="店铺logo" @upload="handleLoaded1" @change="handleChange" :number="9"></sunui-upimg>
+				<sunui-upimg :header="{ 'x-access-token': cache.get('TOKEN') }" ref="upload1" title="店铺logo"
+					@upload="handleLoaded1" @change="handleChange" :number="9"></sunui-upimg>
 			</view>
 		</view>
 		<view class="f-tips">
@@ -44,7 +45,7 @@ import { useCacheStore } from '@/stores/cache'
 import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
 import { RouterUtils, TipsUtils } from '@/utils/util';
 const cache = useCacheStore()
-const upPicUrl = ref('http://192.168.0.11:8080/jeecg-boot/sys/common/upload')
+// const upPicUrl = ref('http://192.168.0.11:8080/jeecg-boot/sys/common/upload')
 const selectType = ref(0);
 const issueType = ref()
 const userinfo = computed(() => {
@@ -65,7 +66,7 @@ const selectItem = (e) => {
 	formData.value.feedbackType = e.value
 }
 const handleChange = (e) => {
-	formData.value.feedbackImg= e.join(',');
+	formData.value.feedbackImg = e.join(',');
 }
 // 查询分类
 const get_dictType = () => {

+ 42 - 22
src/pages/mine/index.vue

@@ -21,8 +21,7 @@
 	<view style="height: 100rpx;"></view>
 	<view class="content">
 		<view class="m-mineinfo-card">
-			<view class="item-info" v-for="(item, index) in cardList" :key="index"
-				@click="checkoutOrder(index)">
+			<view class="item-info" v-for="(item, index) in cardList" :key="index" @click="checkoutOrder(index)">
 				<zzx-icon :name="item.icon" size="30"></zzx-icon>
 				<view class="item-text">{{ item.name }}</view>
 			</view>
@@ -42,8 +41,10 @@
 			</view>
 		</view>
 		<view class="login-tips" v-if="!token">
-			<view class="">终于等到你!快去登录吧~</view>
-			<view class="" @click="submitLogin">马上登录</view>
+			<view class="login-text">终于等到你!快去登录吧~</view>
+			<view class="login-btn" @click="submitLogin">马上登录</view>
+			<button type="default" open-type="getPhoneNumber" @getphonenumber="decryptPhoneNumber"
+				class="getPhoneNumber-btn"></button>
 		</view>
 	</view>
 </template>
@@ -84,27 +85,29 @@ onMounted(() => {
 })
 onPageScroll((e) => { })
 
-const submitLogin = () => {
-	uni.login({
-		provider: 'weixin',
-		success: (res) => {
-			get_logininfo(res.code)
-		}
-	})
-}
-
-// RouterUtils.to_page(`/pages/mine/orderInfo/index?selIndex=${index}`)
-const checkoutOrder=(index:number)=>{
-	cache.set('ORDER_SEL_INDEX',index)
-	uni.switchTab({
-		url:`/pages/mine/orderInfo/index`
-	})
+// 手机号授权登录strart
+const phoneCode = ref('')
+const decryptPhoneNumber = (e: any) => {
+	phoneCode.value = e.detail.code
+	if (e.detail.code) {
+		uni.login({
+			provider: 'weixin',
+			success: (res) => {
+				get_logininfo(res.code)
+			}
+		})
+	}
 }
-
 const get_logininfo = (item: string) => {
 	http.get('/user/loginByCode', { data: { code: item }, loading: true }).then(res => {
 		cache.set('TOKEN', res.result.token)
 		cache.set('USER_INFO', res.result)
+		getMobilePhone(phoneCode.value)
+	})
+}
+
+const getMobilePhone = (code: string) => {
+	http.get('/user//getMobilePhone', { data: { code: code }, loading: true }).then(res => {
 		get_userinfo()
 		TipsUtils.tips_toast('登录成功')
 	})
@@ -115,6 +118,15 @@ const get_userinfo = () => {
 		cache.set('USER_INFO', res.result)
 	})
 }
+// 手机号授权登录end
+
+// RouterUtils.to_page(`/pages/mine/orderInfo/index?selIndex=${index}`)
+const checkoutOrder = (index: number) => {
+	cache.set('ORDER_SEL_INDEX', index)
+	uni.switchTab({
+		url: `/pages/mine/orderInfo/index`
+	})
+}
 </script>
 
 <style>
@@ -246,12 +258,12 @@ page {
 	border-radius: 8rpx;
 	z-index: 9999;
 
-	&>view:first-child {
+	.login-text {
 		font-size: 28rpx;
 		color: #FFFFFF;
 	}
 
-	&>view:last-child {
+	.login-btn {
 		width: 160rpx;
 		height: 60rpx;
 		background: #C8FF0C;
@@ -261,5 +273,13 @@ page {
 		text-align: center;
 		line-height: 60rpx;
 	}
+
+	.getPhoneNumber-btn {
+		position: absolute;
+		right: 10rpx;
+		width: 160rpx;
+		height: 60rpx;
+		opacity: 0;
+	}
 }
 </style>

+ 89 - 7
src/pages/mine/orderInfo/index.vue

@@ -81,7 +81,9 @@
 					@click.stop="RouterUtils.to_page(`/pages/index/writeComments/index?siteId=${item.addressSiteId}&orderId=${item.orderId}&siteName=${item.orderProInfoList[0].address}`)">
 					评价</view>
 				<!-- 已使用 -->
-				<view class="cancel-btn" v-if="selected == 4&&(item.orderProInfoList[0].type==1||item.orderProInfoList[0].type==2)&&(item.orderStatus==1)">申请退款</view>
+				<view class="cancel-btn"
+					v-if="selected == 4 && (item.orderProInfoList[0].type == 1 || item.orderProInfoList[0].type == 2) && (item.orderStatus == 1)">
+					申请退款</view>
 				<!-- <view class="pay-btn" v-if="selected == 4">凭证</view> -->
 			</view>
 			<!-- 待使用 -->
@@ -94,17 +96,24 @@
 			</view>
 		</view>
 		<zs-empty v-if="orderList.length == 0"></zs-empty>
+		<view class="login-tips" v-if="!token">
+			<view class="login-text">终于等到你!快去登录吧~</view>
+			<view class="login-btn" @click="submitLogin">马上登录</view>
+			<button type="default" open-type="getPhoneNumber" @getphonenumber="decryptPhoneNumber"
+				class="getPhoneNumber-btn"></button>
+		</view>
 	</view>
 </template>
 
 <script lang="ts" setup>
-import { ref, onMounted, onUnmounted } from 'vue'
+import { ref, onMounted, computed, onUnmounted } from 'vue'
 import { http } from '@/utils/http'
 import { onLoad, onReachBottom, onShow } from '@dcloudio/uni-app';
 import zsEmpty from '@/components/zs-empty/index.vue';
 import { RouterUtils, TipsUtils } from '@/utils/util';
 import { useCacheStore } from '@/stores/cache'
 const cache = useCacheStore()
+const token = computed(() => cache.token)
 const selected = ref(0)
 const orderTypeList = ref(['全部', '待付款', '待使用', '已使用', '退款/售后'])
 onLoad((option) => {
@@ -112,7 +121,7 @@ onLoad((option) => {
 })
 onShow(() => {
 	// selected.value = cache.get('ORDER_SEL_INDEX') || 0
-	const statusMap:any = {
+	const statusMap: any = {
 		0: { orderStatus: null, orAfterSale: 0 },
 		1: { orderStatus: 0, orAfterSale: 0 },
 		2: { orderStatus: 1, orAfterSale: 0 },
@@ -121,7 +130,7 @@ onShow(() => {
 	}
 
 	const selectedIndex = cache.get('ORDER_SEL_INDEX')
-	selected.value = selectedIndex||0
+	selected.value = selectedIndex || 0
 
 	if (statusMap[selectedIndex]) {
 		Object.assign(orderFormData.value, statusMap[selectedIndex])
@@ -160,6 +169,42 @@ const selectedItem = (i) => {
 	getOrderList()
 }
 
+
+// 手机号授权登录strart
+const phoneCode = ref('')
+const decryptPhoneNumber = (e: any) => {
+	phoneCode.value = e.detail.code
+	if (e.detail.code) {
+		uni.login({
+			provider: 'weixin',
+			success: (res) => {
+				get_logininfo(res.code)
+			}
+		})
+	}
+}
+const get_logininfo = (item: string) => {
+	http.get('/user/loginByCode', { data: { code: item }, loading: true }).then(res => {
+		cache.set('TOKEN', res.result.token)
+		cache.set('USER_INFO', res.result)
+		getMobilePhone(phoneCode.value)
+	})
+}
+
+const getMobilePhone = (code: string) => {
+	http.get('/user//getMobilePhone', { data: { code: code }, loading: true }).then(res => {
+		get_userinfo()
+	})
+}
+
+const get_userinfo = () => {
+	http.get('/user/getUserInfo', { loading: true }).then(res => {
+		cache.set('USER_INFO', res.result)
+		TipsUtils.tips_toast('登录成功')
+	})
+}
+// 手机号授权登录end
+
 // 提交支付start
 const orderCode = ref()
 const orderId = ref()
@@ -271,9 +316,9 @@ const startCountdown = (item) => {
 				item.downTime = "00:00";
 				if (callCount < 3) {
 					callCount++;
-					setTimeout(()=>{
-					getOrderList();
-					},500)
+					setTimeout(() => {
+						getOrderList();
+					}, 500)
 				}
 				return;
 			}
@@ -488,4 +533,41 @@ onUnmounted(() => {
 		color: #222222;
 	}
 }
+
+.login-tips {
+	position: fixed;
+	bottom: 22rpx;
+	width: 686rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 10rpx;
+	background: rgba(0, 0, 0, 0.6);
+	border-radius: 8rpx;
+	z-index: 9999;
+
+	.login-text {
+		font-size: 28rpx;
+		color: #FFFFFF;
+	}
+
+	.login-btn {
+		width: 160rpx;
+		height: 60rpx;
+		background: #C8FF0C;
+		border-radius: 8rpx;
+		font-size: 28rpx;
+		color: #222222;
+		text-align: center;
+		line-height: 60rpx;
+	}
+
+	.getPhoneNumber-btn {
+		position: absolute;
+		right: 10rpx;
+		width: 160rpx;
+		height: 60rpx;
+		opacity: 0;
+	}
+}
 </style>

+ 2 - 2
src/utils/http/index.ts

@@ -179,9 +179,9 @@ export class HttpClient {
 
 // 创建实例
 export const http = new HttpClient({
-  // baseURL: 'http://192.168.0.217:8080/jeecg-boot/app',
+  baseURL: 'http://192.168.0.217:8080/jeecg-boot/app',
   // baseURL: 'http://192.168.1.166:8080/jeecg-boot/app',
-  baseURL: 'http://192.168.0.11:8080/jeecg-boot/app',
+  // baseURL: 'http://192.168.0.11:8080/jeecg-boot/app',
   // baseURL: 'https://api.qlapp.cn/jeecgboot/app', //生产
   headers: {
     'Content-Type': 'application/json'