瀏覽代碼

搜索接口部分

学习?学个屁 2 周之前
父節點
當前提交
7f61f30163
共有 41 個文件被更改,包括 1756 次插入1146 次删除
  1. 20 0
      src/components/zs-empty/index.vue
  2. 35 24
      src/components/zzx-cell/zzx-cell.vue
  3. 1 0
      src/components/zzx-navbar/zzx-navbar.vue
  4. 13 5
      src/manifest.json
  5. 42 2
      src/pages.json
  6. 116 12
      src/pages/index/index.vue
  7. 1 3
      src/pages/index/search/index.vue
  8. 92 98
      src/pages/index/searchPage/index.vue
  9. 115 2
      src/pages/index/submitOrder/index.vue
  10. 8 0
      src/pages/index/userList/index.vue
  11. 98 0
      src/pages/mine/accountSetting/index.vue
  12. 0 48
      src/pages/mine/charge.vue
  13. 151 0
      src/pages/mine/feedback/index.vue
  14. 131 0
      src/pages/mine/feedbackRecord/index.vue
  15. 234 4
      src/pages/mine/index.vue
  16. 148 0
      src/pages/mine/mineComments/index.vue
  17. 0 134
      src/pages/mine/music.vue
  18. 255 0
      src/pages/mine/orderInfo/index.vue
  19. 0 255
      src/pages/mine/particleEffects.vue
  20. 64 0
      src/pages/mine/reviseNickname/index.vue
  21. 0 138
      src/pages/mine/signPanel.vue
  22. 0 20
      src/pages/mine/switch.vue
  23. 0 46
      src/pages/mine/tabs.vue
  24. 0 7
      src/pages/mine/vrCheck.vue
  25. 0 30
      src/pages/mine/waterfall.vue
  26. 二進制
      src/static/account-setting.png
  27. 二進制
      src/static/default-header.png
  28. 二進制
      src/static/empty.png
  29. 0 0
      src/static/icons/m-after-sales.svg
  30. 1 0
      src/static/icons/m-allorder.svg
  31. 1 0
      src/static/icons/m-clear.svg
  32. 1 0
      src/static/icons/m-done.svg
  33. 1 0
      src/static/icons/m-pendPay.svg
  34. 0 0
      src/static/icons/m-pendUse.svg
  35. 二進制
      src/static/logo.png
  36. 二進制
      src/static/m-feedbackReocd.png
  37. 二進制
      src/static/mine_bg.png
  38. 二進制
      src/static/vr.jpg
  39. 10 1
      src/styles/variables.less
  40. 184 295
      src/utils/http/index.ts
  41. 34 22
      src/utils/util/index.ts

+ 20 - 0
src/components/zs-empty/index.vue

@@ -0,0 +1,20 @@
+<template>
+	<view class="zs-empty">
+		<image src="/src/static/empty.png" mode="widthFix"></image>
+		<view class="">暂无数据</view>
+	</view>
+</template>
+
+<script>
+</script>
+
+<style lang="less" scoped>
+	.zs-empty{
+		text-align: center;
+		font-size: 28rpx;
+		color: #222222;
+		&>image{
+			width: 320rpx;
+		}
+	}
+</style>

+ 35 - 24
src/components/zzx-cell/zzx-cell.vue

@@ -1,45 +1,53 @@
 <template>
-	<view class="zzx-cell-box" @click="gotoPage(url)">
+	<view class="zzx-cell-box" @click="handleClick">
+		<!-- 原有内容保持不变 -->
 		<view class="cell-left">
 			<view class="left-icon">
 				<image v-if="icon" :src="icon" :style="{
-				  width: iconSize,
-				  height: iconSize
-				}" class="empty-icon" mode="aspectFit" />
+          width: iconSize,
+          height: iconSize
+        }" class="empty-icon" mode="aspectFit" />
 			</view>
 			<view class="left-text">{{text}}</view>
 		</view>
 		<view class="cell-right">
 			<view class="right-text">{{instructionText}}</view>
-			<zzx-icon name="right"></zzx-icon>
+			<zzx-icon name="ashRight" size="10"></zzx-icon>
 		</view>
 	</view>
 </template>
 
 <script lang="ts" setup>
+	import {TipsUtils } from '@/utils/util';
 	interface Props {
-		icon ?: string         // 单元格图标
-		text ?: string         // 单元格名字
-		iconSize ?: string     // 图标尺寸(支持rpx/px)
-		instructionText ?: string    // 右侧说明文字
-		url ?: string  //跳转路径
+		icon ?: string;         // 单元格图标
+		text ?: string;         // 单元格名字
+		iconSize ?: string;     // 图标尺寸(支持rpx/px)
+		instructionText ?: string;    // 右侧说明文字
+		url ?: string;          // 跳转路径
+		customClick ?: Function; // 新增:自定义点击处理函数
 	}
-	// 默认props
+
 	const props = withDefaults(defineProps<Props>(), {
-		icon: '',  // 默认图标路径
+		icon: '',
 		text: '',
 		iconSize: '',
-		instructionText: '说明文字',
-		url: ''
-	})
+		instructionText: '',
+		url: '',
+		customClick: null
+	});
 
 	const emit = defineEmits(['click']);
 
-	const gotoPage = (path: string) => {
-		if (!path) return;
-		const hasHandlers = emit('click', path);
-		if (!hasHandlers) {
-			uni.navigateTo({ url: path });
+	const handleClick = () => {
+		if (typeof props.customClick === 'function') {
+			props.customClick(props.url);
+			return;
+		}
+		const hasHandlers = emit('click', props.url);
+		if (!hasHandlers && props.url) {
+			if(!uni.getStorageSync('TOKEN')) return TipsUtils.tips_alert('请先登录~',false)
+			uni.navigateTo({ url: props.url });
 		}
 	};
 </script>
@@ -50,7 +58,7 @@
 		align-items: center;
 		justify-content: space-between;
 		background-color: #fff;
-		height: 80rpx;
+		height: 70rpx;
 		padding: 10rpx;
 
 		.cell-left {
@@ -58,22 +66,25 @@
 			align-items: center;
 
 			.left-text {
-				margin-left: 10rpx;
-				font-size: 30rpx;
+				font-size: 28rpx;
+				color: #181818;
 			}
 		}
 
 		.cell-right {
 			display: flex;
+
 			.right-text {
 				color: @minitext-color;
-				margin-right: 10rpx;
 				font-size: 28rpx;
+				// margin-bottom: 30rpx;
 			}
 		}
 	}
 
 	.zzx-cell-box:active {
 		background-color: #ececec;
+		color: #676767;
+		border-radius: 20rpx;
 	}
 </style>

+ 1 - 0
src/components/zzx-navbar/zzx-navbar.vue

@@ -11,6 +11,7 @@
 			<slot></slot>
 		</view>
 	</view>
+	<!-- <view :style="{height:navBarHeight+'px'}"></view> -->
 </template>
 
 <script lang="ts" setup>

+ 13 - 5
src/manifest.json

@@ -52,14 +52,22 @@
 	"mp-weixin": {
 		"appid": "",
 		"setting": {
-			"urlCheck": false
+			"urlCheck": false,
+			"minified" : true
 		},
 		"requiredBackgroundModes": ["webgl"],
-		"permission": {
-			"scope.userFacing": {
-				"desc": "需要访问陀螺仪和屏幕旋转"
-			}
+		"permission" : {
+			"scope.userFuzzyLocation" : {
+			    "desc" : "提供周边线下服务商"
+			},
+		    "scope.userFacing" : {
+		        "desc" : "需要访问陀螺仪和屏幕旋转"
+		    },
+		    "scope.userLocation" : {
+		        "desc" : "获取您的位置,以便匹配合适距离场地"
+		    }
 		},
+		"requiredPrivateInfos": ["getLocation", "chooseLocation"],
 		"usingComponents": true
 	},
 	"mp-alipay": {

+ 42 - 2
src/pages.json

@@ -208,8 +208,48 @@
 		},{
 			"path": "pages/mine/index",
 			"style": {
-				"navigationBarBackgroundColor": "#54BCBD",
-				"navigationBarTitleText": "我的"
+				"navigationBarBackgroundColor": "#fff",
+				"navigationBarTitleText": "我的",
+				"navigationStyle": "custom"
+			}
+		},{
+			"path": "pages/mine/accountSetting/index",
+			"style": {
+				"navigationBarBackgroundColor": "#fff",
+				"navigationBarTitleText": "账户设置"
+			}
+		},{
+			"path": "pages/mine/reviseNickname/index",
+			"style": {
+				"navigationBarBackgroundColor": "#fff",
+				"navigationBarTitleText": "修改昵称"
+			}
+		},{
+			"path": "pages/mine/orderInfo/index",
+			"style": {
+				"navigationBarBackgroundColor": "#fff",
+				"navigationBarTitleText": "订单"
+			}
+		},{
+			"path": "pages/mine/feedback/index",
+			"style": {
+				"navigationBarBackgroundColor": "#fff",
+				"navigationBarTitleText": "意见反馈",
+				"navigationStyle": "custom"
+			}
+		},{
+			"path": "pages/mine/feedbackRecord/index",
+			"style": {
+				"navigationBarBackgroundColor": "#fff",
+				"navigationBarTitleText": "反馈记录",
+				"navigationStyle": "custom"
+			}
+		},{
+			"path": "pages/mine/mineComments/index",
+			"style": {
+				"navigationBarBackgroundColor": "#fff",
+				"navigationBarTitleText": "评价详情",
+				"navigationStyle": "custom"
 			}
 		}
 	],

+ 116 - 12
src/pages/index/index.vue

@@ -9,7 +9,8 @@
 	</view>
 	<view class="index-header">
 		<image class="header-bg" src="@/static/index_bg.png" mode="widthFix"></image>
-		<view class="back-icon" :style="{paddingTop:(statusBarHeight+10)+'px'}" v-if="navOpacity==0">
+		<view class="back-icon" :style="{paddingTop:(statusBarHeight+10)+'px'}" v-if="navOpacity==0"
+			@click="openSellocation">
 			<zzx-icon name="location" size="13"></zzx-icon>
 			<view class="location-text">富力中心A7</view>
 			<zzx-icon name="right" size="10"></zzx-icon>
@@ -24,8 +25,8 @@
 			</view>
 		</view>
 		<view class="header-banner">
-			<swiper class="header-swiper" :autoplay="true" :current="currentIndex" :circular="true" previous-margin="80rpx"
-				next-margin="80rpx" :interval="4000" :duration="500" @change="swierChange">
+			<swiper class="header-swiper" :autoplay="true" :current="currentIndex" :circular="true"
+				previous-margin="80rpx" next-margin="80rpx" :interval="4000" :duration="500" @change="swierChange">
 				<swiper-item v-for="(item,i) in bannerList" :key="i">
 					<image :src="item.img" class="slide-image" :class="currentIndex === i?'active':''"></image>
 				</swiper-item>
@@ -36,7 +37,8 @@
 		<view class="announcement" @click="gotoPage('/pages/index/messageNotice/index')">
 			<image src="/src/static/gg-icon.png" mode="heightFix"></image>
 			<view class="">
-				<swiper class="announcement-swiper" :vertical="true" :circular="true" :autoplay="true" :interval="3000" :duration="1000">
+				<swiper class="announcement-swiper" :vertical="true" :circular="true" :autoplay="true" :interval="3000"
+					:duration="1000">
 					<swiper-item v-for="item in 3">
 						<view class="swiper-item textHidden">学校为公益场地,请严格遵守相关规范!</view>
 					</swiper-item>
@@ -112,7 +114,9 @@
 				</view>
 			</view>
 			<view class="i-info-card">
-				<view class="i-card-list" :style="{background:index % 2=== 0?'linear-gradient(179deg, #FFD5FB 0%, #FFFFFF 40%)':'linear-gradient( 179deg, #F2FFBE 0%, #FFFFFF 40%)'}" v-for="(item,index) in 6">
+				<view class="i-card-list"
+					:style="{background:index % 2=== 0?'linear-gradient(179deg, #FFD5FB 0%, #FFFFFF 40%)':'linear-gradient( 179deg, #F2FFBE 0%, #FFFFFF 40%)'}"
+					v-for="(item,index) in 6">
 					<view class="i-info" @click="gotoPage('/pages/index/instructorDetail/index')">
 						<view class="header" :style="{background:index % 2=== 0?'#FFB8F9':'#C8FF0C'}">
 							<image class="head-img" src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg"
@@ -166,22 +170,32 @@
 				</view>
 			</view>
 		</view>
-				<view class="login-tips">
+		<view class="login-tips" v-if="!token">
 			<view class="">终于等到你!快去登录吧~</view>
-			<view class="">马上登录</view>
+			<view class="" @click="submitLogin">马上登录</view>
 		</view>
 	</view>
 </template>
 
 <script setup lang="ts">
 	import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
-	import { ref, onMounted } from 'vue'
-	import { onLoad, onPageScroll } from '@dcloudio/uni-app';
+	import { ref, onMounted, computed } from 'vue'
+	import { onShow, onPageScroll } from '@dcloudio/uni-app';
+	import { RouterUtils, TipsUtils } from '@/utils/util';
+	import { http } from '@/utils/http'
+	import { useCacheStore } from '@/stores/cache'
+	const cache = useCacheStore()
+	const token = computed(() => {
+		return cache.get('TOKEN')
+	})
 	const navBarHeight = ref(0);
 	const statusBarHeight = ref(0);
 	const titleBarHeight = ref(0);
 	const navOpacity = ref(0);
 	const backgroundColor = ref('#D2FD73');
+	onShow(() => {
+		get_location()
+	})
 	onMounted(() => {
 		get_navheight()
 	})
@@ -210,10 +224,94 @@
 	}
 
 	const gotoPage = (path : string) => {
+		if (!token.value) return TipsUtils.tips_alert('请先登录~', false)
 		uni.navigateTo({
 			url: path
 		})
 	}
+
+	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)
+			TipsUtils.tips_toast('登录成功')
+		})
+	}
+
+	const get_location = () => {
+		uni.showLoading()
+		uni.authorize({
+			scope: 'scope.userLocation',
+			success() {
+				uni.getLocation({
+					type: 'wgs84',
+					success: function (res) {
+						uni.hideLoading()
+						cache.set('LON',res.longitude)
+						cache.set('LAT',res.latitude)
+						// console.log('当前位置的经度:' + res.longitude);
+						// console.log('当前位置的纬度:' + res.latitude);
+					},
+					fail: function (err) {
+						uni.hideLoading()
+						if (err.errMsg === 'getFuzzyLocation:fail system permission denied') {
+							TipsUtils.tips_alert('系统定位未开启,请开启定位以便提供更好服务', false)
+						} else if (err.errMsg === 'getFuzzyLocation:fail:ERROR_NOCELL&WIFI_LOCATIONSWITCHOFF' ||
+							err.errMsg === 'getFuzzyLocation:fail system permission denied' ||
+							err.errMsg === 'getFuzzyLocation:fail:system permission denied' || err.errMsg === 'getFuzzyLocation:fail auth deny'){
+								showAuthGuide()
+							}
+						console.log(err, '错误信息')
+					}
+				});
+			},
+			fail: (err) => {
+				uni.hideLoading()
+				showAuthGuide()
+			}
+		});
+	}
+
+	// 引导操作
+	const showAuthGuide = async() => {
+		let res:any = await TipsUtils.tips_alert('授权定位以提供更好服务',true)
+		if(res.confirm){
+			uni.openSetting()
+		}
+	}
+
+	// 手动选择
+	const openSellocation = () => {
+		uni.chooseLocation({
+			success: function (res) {
+				console.log('位置名称:' + res.name);
+				console.log('详细地址:' + res.address);
+				console.log('纬度:' + res.latitude);
+				console.log('经度:' + res.longitude);
+			},
+			fail(res) {
+				console.log(res);
+				// showAuthGuide()
+			}
+		});
+	}
+	
+	// 字典项查询
+	const get_dictItems=(code)=>{
+		http.get('/common/getDictItems',{data:{dictCode:code}}).then(res=>{
+			
+		})
+	}
+	
 </script>
 
 <style lang="less" scoped>
@@ -270,6 +368,7 @@
 			width: 685rpx;
 			padding: 8rpx;
 			border-radius: 40rpx;
+
 			&>input {
 				width: 670rpx;
 				font-weight: bold;
@@ -296,9 +395,11 @@
 			left: 0;
 			width: 100%;
 			height: 340rpx;
-			.header-swiper{
+
+			.header-swiper {
 				height: 340rpx;
 			}
+
 			.slide-image {
 				position: absolute;
 				height: 200rpx;
@@ -333,6 +434,7 @@
 		display: flex;
 		justify-content: space-around;
 		z-index: 9999;
+
 		&>image {
 			height: 32rpx;
 		}
@@ -341,7 +443,8 @@
 			font-size: 28rpx;
 			color: #222222;
 			width: 440rpx;
-			.announcement-swiper{
+
+			.announcement-swiper {
 				height: 40rpx;
 			}
 		}
@@ -551,7 +654,7 @@
 			position: absolute;
 
 			.i-card-list {
-				margin-bottom:24rpx;
+				margin-bottom: 24rpx;
 				border-radius: 32rpx;
 				padding: 20rpx;
 				width: 670rpx;
@@ -729,6 +832,7 @@
 		background: rgba(0, 0, 0, 0.6);
 		border-radius: 8rpx;
 		z-index: 9999;
+
 		&>view:first-child {
 			font-size: 28rpx;
 			color: #FFFFFF;

+ 1 - 3
src/pages/index/search/index.vue

@@ -47,10 +47,8 @@
 		}
 		//保存到缓存
 		cache.set('SEARCH_INFO', historyList.value);
+		RouterUtils.to_page(`/pages/index/searchPage/index?keyword=${keyword}`)
 		searchText.value = '';
-		// 这里添加实际搜索逻辑,例如跳转到搜索结果页
-		console.log('执行搜索:', keyword);
-		RouterUtils.to_page('/pages/index/searchPage/index')
 	};
 	const selectHistory = (keyword : string) => {
 		searchText.value = keyword;

+ 92 - 98
src/pages/index/searchPage/index.vue

@@ -8,8 +8,8 @@
 			</view>
 		</view>
 		<view class="venue-navbar">
-			<view class="navbar-list" v-for="(item,index) in navbarList" :key="index" @click="select_nav(index)">
-				<view class="list-text">{{item.text}}</view>
+			<view class="navbar-list" v-for="(item,index) in navbarList" :key="index" @click="select_nav(item)">
+				<view class="list-text">{{item.title}}</view>
 				<image :src="sel_index==index?'/static/notsel-icon.png':'/static/select-icon.png'" mode=""></image>
 			</view>
 		</view>
@@ -17,76 +17,71 @@
 	<view class="content">
 		<view class="select-btn">
 			<view :class="sel_btn===index?'distance':'score'" v-for="(item,index) in selectList" :key="index"
-				@click="select_btn(index)">{{item}}</view>
+				@click="select_btn(index)">{{item.text}}</view>
 		</view>
 		<view class="s-search-list">
 			<!-- 场地 -->
-			<view class="s-venue-card">
-				<view class="s-venue-info">
-					<view class="venue-img">
-						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
-					</view>
-					<view class="venue-info">
-						<view class="name">体育综合训练馆(观山湖店)</view>
-						<view class="appraise">
-							<zzx-icon name="star" size="12"></zzx-icon>
-							<view class="app-text"><text style="color: #FDD143	;">4.8</text> | 37条评论</view>
+			<view v-if="sel_index==0">
+				<view class="s-venue-card" v-for="(venue,index) in searchList" :key="venue.id">
+					<view class="s-venue-info">
+						<view class="venue-img">
+							<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
 						</view>
-						<view class="address">观山湖区万达广场 | 2.2km</view>
-						<view class="tags-box">
-							<view class="tags" v-for="item in 4">羽毛球</view>
+						<view class="venue-info">
+							<view class="name">{{venue.name}}</view>
+							<view class="appraise">
+								<zzx-icon name="star" size="12"></zzx-icon>
+								<view class="app-text"><text style="color: #FDD143	;">{{venue.goodRate}}</text> | 37条评论</view>
+							</view>
+							<view class="address">{{venue.address}} | {{venue.km}}km</view>
+							<view class="tags-box">
+								<view class="tags" v-for="(tags,index) in venue.category" :key="index">{{tags}}</view>
+							</view>
 						</view>
 					</view>
-				</view>
-				<view class="s-course-list" v-for="item in 2">
-					<view class="course-name">
-						<view class="price">¥25.6</view>
-						<view class="name">室内小班篮球培训课时</view>
+					<view class="s-course-list" v-for="item in 2">
+						<view class="course-name">
+							<view class="price">¥25.6</view>
+							<view class="name">室内小班篮球培训课时</view>
+						</view>
+						<view class="sales">年售1万+</view>
 					</view>
-					<view class="sales">年售1万+</view>
 				</view>
 			</view>
 			<!-- 培训 -->
-			<view class="s-training-card">
-				<view class="training-box">
-					<view class="training-img">
-						<image class="t-img" src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode="">
-						</image>
-						<image class="img-tags" src="@/static/search-icon2.png" mode="widthFix"></image>
-						<view class="tags-text">限时特惠</view>
-						<view class="s-downtime">
-							<view class="hours">{{hours}}</view>
-							<view class="unit">:</view>
-							<view class="hours">{{minutes}}</view>
-							<view class="unit">:</view>
-							<view class="hours">{{seconds}}</view>
-						</view>
-					</view>
-					<view class="training-info">
-						<view class="training-name">
-							<view class="t-tags">公益课</view>
-							<view class="t-name textHidden">1对1篮球30分钟室内30分钟室内</view>
+			<view v-if="sel_index==1">
+				<view class="s-training-card">
+					<view class="training-box">
+						<view class="training-img">
+							<image class="t-img" src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode="">
+							</image>
 						</view>
-						<view class="tips">促进青少年长高</view>
-						<view class="t-price">
-							<view class="price"><text class="mini-text">¥</text>25.9</view>
-							<view class="price-tips">不支持退款</view>
+						<view class="training-info">
+							<view class="training-name">
+								<view class="t-tags">公益课</view>
+								<view class="t-name textHidden">1对1篮球30分钟室内30分钟室内</view>
+							</view>
+							<view class="tips">促进青少年长高</view>
+							<view class="t-price">
+								<view class="price"><text class="mini-text">¥</text>25.9</view>
+								<view class="price-tips">不支持退款</view>
+							</view>
+							<view class="sales">已售37 98%好评</view>
+							<view class="address">观山湖区万达广场 | 2.2km</view>
 						</view>
-						<view class="sales">已售37 98%好评</view>
-						<view class="address">观山湖区万达广场 | 2.2km</view>
 					</view>
-				</view>
-				<view class="tags-img">
-					<image class="enroll-tags" src="@/static/search-icon1.png" mode="widthFix"></image>
+					<view class="tags-img">
+						<image class="enroll-tags" src="@/static/search-icon1.png" mode="widthFix"></image>
+					</view>
 				</view>
 			</view>
 			<!-- 赛事 -->
-			<view class="">
-				<events/>
+			<view v-if="sel_index==2">
+				<events />
 			</view>
 			<!-- 教练 -->
-			<view class="">
-				<instructor/>
+			<view v-if="sel_index==3">
+				<instructor />
 			</view>
 		</view>
 	</view>
@@ -94,61 +89,60 @@
 
 <script lang="ts" setup>
 	import { ref, onMounted } from 'vue';
+	import { onLoad } from '@dcloudio/uni-app';
+	import { http } from '@/utils/http'
+	import { useCacheStore } from '@/stores/cache'
 	import events from './components/events.vue'
 	import instructor from './components/instructor.vue'
+	const cache = useCacheStore()
 	const selectList = ref(['距离', '好评'])
 	const sel_index = ref(0);
 	const sel_btn = ref(0);
-	const hours = ref<string>('00');
-	const minutes = ref<string>('00');
-	const seconds = ref<string>('00');
-	// 设置结束时间 (格式:YYYY-MM-DD HH:mm:ss)
-	const endTime = ref<string>('2025-06-23 23:59:59');
-	const navbarList = ref([{
-		text: '场地'
-	}, {
-		text: '培训'
-	}, {
-		text: '赛事'
-	}, {
-		text: '教练'
-	}]);
+	const keyword = ref();
+	const searchList=ref();
+	const navbarList = ref([{title: '场地',value: 0,tagsVal:'0-1'},{title: '培训',value: 1,tagsVal:'1-1'},{title: '赛事',value: 2,tagsVal:'2-1'},{title: '教练',value: 3,tagsVal:'3-1'}]);
+	onLoad((options) => {
+		keyword.value = options.keyword
+		console.log(options);
+	})
 	onMounted(() => {
-		updateCountdown();
-		timer = setInterval(updateCountdown, 1000) as unknown as number;// 设置每秒更新
+		get_searchInfo('0-1')
+		// get_dictItems()
+		get_dictType(0)
 	})
 	const select_btn = (i) => {
 		sel_btn.value = i
 	}
-	const select_nav = (i) => {
-		sel_index.value = i
+	const select_nav = (e) => {
+		sel_index.value = e.value
+		get_dictType(e.value || 0)
+		get_searchInfo(e.tagsVal)
+	}
+
+	// 查询分类
+	const get_dictType = (type : number) => {
+		http.get('/common/getDictItems', { data: { dictCode: 'search_type' } }).then(res => {
+			let arr = []
+			res.result.forEach((item) => {
+				let value = parseInt(item.value.split('-')[0])
+				if (type == value){
+					return arr.push(item)
+				}
+			})
+			selectList.value=arr
+		})
+	}
+
+	const get_searchInfo = (tagsVal) => {
+		http.post('/home/search', { keyword: keyword.value, size: 10, current: 1, venueType:String(tagsVal), longitude: cache.get('LON'), latitude: cache.get('LAT') }, { loading: true }).then((res) => {
+			searchList.value=res.result.records
+			console.log(res);
+		})
+	}
+
+	const get_searchTab = () => {
+
 	}
-	// 倒计时
-	let timer : number | null = null;
-	const updateCountdown = () => {
-		const now = new Date().getTime();
-		const endDate = new Date(endTime.value).getTime();
-		const timeLeft = endDate - now;
-		if (timeLeft <= 0) {
-			hours.value = '00';
-			minutes.value = '00';
-			seconds.value = '00';
-			if (timer) {
-				clearInterval(timer);
-				timer = null;
-			}
-			return;
-		}
-		// 计算剩余时间
-		const d = Math.floor(timeLeft / (1000 * 60 * 60 * 24));
-		const h = Math.floor((timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
-		const m = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60));
-		const s = Math.floor((timeLeft % (1000 * 60)) / 1000);
-		// 格式化为两位数
-		hours.value = h.toString().padStart(2, '0');
-		minutes.value = m.toString().padStart(2, '0');
-		seconds.value = s.toString().padStart(2, '0');
-	};
 </script>
 
 <style lang="less" scoped>

+ 115 - 2
src/pages/index/submitOrder/index.vue

@@ -27,6 +27,28 @@
 				</scroll-view>
 			</view>
 		</view>
+		<view class="g-insurance-card">
+			<view class="g-insurance-info">
+				<view class="insurance-type">
+					<view class="type-name">
+						<view class="name">意外险</view>
+						<view class="tips">不支持退款</view>
+					</view>
+					<view class="insurance-more">
+						<text>查看详情</text>
+						<zzx-icon name="ashRight" size="12"></zzx-icon>
+					</view>
+				</view>
+				<view class="insurance-num" @click="select_insurance=!select_insurance">
+					<view class="">¥3/人×1份(意外事故10万,社保内医疗1万)</view>
+					<zzx-icon :name="select_insurance?'selected' : 'unchecked'" size="14"></zzx-icon>
+				</view>
+			</view>
+			<view class="insurance-total">
+				<view class="text">保险总价(共2件)</view>
+				<view class="price">¥6</view>
+			</view>
+		</view>
 		<view class="g-userinfo-card">
 			<view class="r-user">
 				<view class="user-title">用户信息</view>
@@ -44,11 +66,12 @@
 					<view class="id-num">身份证 51**************10</view>
 				</view>
 			</view>
-			<view class="g-adduser-btn">
+			<view class="g-adduser-btn" @click="toUserList">
 				<view class="add-icon">+</view>
 				<view class="add-text">添加用户</view>
 			</view>
 		</view>
+		<view class="submit-btn">免费 立即预约</view>
 	</view>
 	<uni-calendar ref="calendar" :insert="false" @confirm="confirm" />
 </template>
@@ -111,7 +134,7 @@
 					display: inline-block;
 					width: 104rpx;
 					height: 120rpx;
-					// background: #F6F6F6;
+					background: #F6F6F6;
 					border-radius: 16rpx;
 					font-size: 24rpx;
 					color: #222222;
@@ -179,6 +202,84 @@
 			}
 		}
 	}
+	.g-insurance-card {
+		background: #FFFFFF;
+		border-radius: 32rpx;
+		padding: 20rpx;
+		margin-top: 20rpx;
+	
+		.g-insurance-info {
+			.insurance-type {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+	
+				.type-name {
+					display: flex;
+					align-items: center;
+					gap: 10rpx;
+	
+					.name {
+						font-weight: bold;
+						font-size: 28rpx;
+						color: #222222;
+					}
+	
+					.tips {
+						width: 136rpx;
+						height: 36rpx;
+						background: #FDD143;
+						border-radius: 8rpx;
+						font-size: 22rpx;
+						color: #222222;
+						text-align: center;
+						line-height: 36rpx;
+					}
+				}
+	
+				.insurance-more {
+					display: flex;
+					align-items: center;
+					gap: 10rpx;
+	
+					&>text {
+						margin-bottom: 4rpx;
+						font-size: 24rpx;
+						color: #AAAAAA;
+					}
+				}
+			}
+	
+			.insurance-num {
+				margin-top: 16rpx;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				font-size: 24rpx;
+				color: #AAAAAA;
+			}
+		}
+	
+		.insurance-total {
+			margin-top: 20rpx;
+			border-top: 1rpx solid #F0F0F0;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			height: 88rpx;
+	
+			.text {
+				font-size: 28rpx;
+				color: #222222;
+			}
+	
+			.price {
+				font-weight: bold;
+				font-size: 28rpx;
+				color: #FB5B5B;
+			}
+		}
+	}
 
 	.g-userinfo-card {
 		margin-top: 20rpx;
@@ -281,4 +382,16 @@
 			}
 		}
 	}
+	.submit-btn{
+		margin-top: 20rpx;
+		width:100%;
+		height: 100rpx;
+		background: #C8FF0C;
+		border-radius: 60rpx;
+		font-weight: bold;
+		font-size: 32rpx;
+		color: #222222;
+		text-align: center;
+		line-height: 100rpx;
+	}
 </style>

+ 8 - 0
src/pages/index/userList/index.vue

@@ -22,7 +22,15 @@
 
 <script lang="ts" setup>
 	import { ref } from 'vue';
+	import { onLoad } from '@dcloudio/uni-app';
 	import { RouterUtils } from '@/utils/util';
+	onLoad((options) => {
+		if(options.name){
+			uni.setNavigationBarTitle({
+				title: options.name
+			});
+		}
+	})
 	const addUser = () => {
 		RouterUtils.to_page('/pages/index/attestation/index');
 	}

+ 98 - 0
src/pages/mine/accountSetting/index.vue

@@ -0,0 +1,98 @@
+<template>
+	<view class="content">
+		<view class="a-accountset-card">
+			<view class="a-header-cell">
+				<view class="a-header">头像</view>
+				<view class="a-set-deader" @click="selectUpType">
+					<view class="add" v-if="!tempFilePaths">+</view>
+					<view class="add-img-box" v-else>
+						<image class="add-img" :src="tempFilePaths" mode=""></image>
+					</view>
+					<zzx-icon name="ashRight" size="10"></zzx-icon>
+				</view>
+			</view>
+			<view class="a-nickname-cell">
+				<view class="a-nickname">昵称</view>
+				<view class="a-set-nickname" @click="RouterUtils.to_page('/pages/mine/reviseNickname/index')">
+					<view class="nickname">艾卡西亚大暴雨</view>
+					<zzx-icon name="ashRight" size="10"></zzx-icon>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script lang="ts" setup>
+	import { ref } from 'vue'
+	import { RouterUtils } from '@/utils/util';
+	const tempFilePaths=ref()
+	const selectUpType = () => {
+		uni.chooseImage({
+			count: 1,
+			sizeType: ['original', 'compressed'],
+			sourceType: ['album', 'camera'],
+			success: function (res) {
+				tempFilePaths.value = res.tempFilePaths
+			}
+		})
+	}
+</script>
+
+<style lang="less" scoped>
+	.a-accountset-card{
+		background: #FFFFFF;
+		border-radius: 32rpx;
+		padding: 20rpx;
+		margin-top: 20rpx;
+		.a-header-cell{
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			.a-header{
+				font-size: 28rpx;
+				color: #AAAAAA;
+			}
+			.a-set-deader{
+				display: flex;
+				align-items: center;
+				gap: 20rpx;
+				.add{
+					width: 70rpx;
+					height: 70rpx;
+					border-radius: 16rpx;
+					background: #F6F6F6;
+					text-align: center;
+					line-height: 70rpx;
+					color: #AAAAAA;
+				}
+				.add-img-box{
+					.add-img{
+						width: 70rpx;
+						height: 70rpx;
+						border-radius: 16rpx;
+					}
+				}
+			}
+		}
+		.a-nickname-cell{
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			margin-top: 30rpx;
+			.a-nickname{
+				font-size: 28rpx;
+				color: #AAAAAA;
+			}
+			.a-set-nickname{
+				display: flex;
+				align-items: center;
+				gap: 20rpx;
+				.nickname{
+					font-weight: bold;
+					font-size: 28rpx;
+					color: #222222;
+				}
+			}
+		}
+	}
+</style>

+ 0 - 48
src/pages/mine/charge.vue

@@ -1,48 +0,0 @@
-<template>
-	<view class="charge-loading-box">
-		<view class="charge-loading">
-			<view class="c-loading"></view>
-		</view>
-	</view>
-</template>
-
-<script>
-</script>
-
-<style lang="less" scoped>
-	.charge-loading-box {
-		margin-top: 50rpx;
-		margin-left: 100rpx;
-	}
-
-	.charge-loading {
-		width: 364rpx;
-		height: 36rpx;
-		background: #FFFFFF;
-		border-radius: 18rpx;
-		overflow: hidden;
-	}
-
-	.c-loading {
-		width: 100%;
-		height: 100%;
-		background: linear-gradient(66deg,
-				rgba(139, 243, 251, 0),
-				#60C8FE,
-				#53D4FF,
-				 rgba(139, 243, 251, 0.7),);
-		border-radius: 18rpx;
-		animation: loading 3s linear infinite;
-		background-size: 200% 100%;
-	}
-
-	@keyframes loading {
-		0% {
-			background-position: 100% 0;
-		}
-
-		100% {
-			background-position: -100% 0;
-		}
-	}
-</style>

+ 151 - 0
src/pages/mine/feedback/index.vue

@@ -0,0 +1,151 @@
+<template>
+	<zzx-navbar :scrollable="false" :back="true" bgColor="linear-gradient( 180deg, #E8FF9B 0%, #F6F6F6 100%)" title="意见反馈"></zzx-navbar>
+	<view style="height:170rpx;"></view>
+	<view class="f-checkout" @click="RouterUtils.to_page('/pages/mine/feedbackRecord/index')">
+		<image src="@/static/m-feedbackReocd.png" mode="widthFix"></image>
+	</view>
+	<view class="content">
+		<view class="f-issue-card">
+			<view class="f-title">(必填)请选择您在使用过程中遇到的问题</view>
+			<view class="item-issue-box">
+				<view :class="[selectType==index?'sel-item-issue':'item-issue']" v-for="(item,index) in 5"
+					@click="selectItem(index)">投诉吐槽</view>
+			</view>
+		</view>
+		<view class="f-issuedes-card">
+			<view class="f-title">(必填)问题描述</view>
+			<view class="item-issuedes-box">
+				<textarea name="" id="" maxlength="500" cols="30" rows="10"></textarea>
+			</view>
+		</view>
+		<view class="f-uploadimg">
+			<view class="f-title">上传图片(最多9张)</view>
+			<view class="">
+				<sunui-upimg :url="upPicUrl" ref="upload1" title="店铺logo" @upload="handleLoaded1"
+					@change="handleChange1" :number="3"></sunui-upimg>
+			</view>
+		</view>
+		<view class="f-tips">
+			咨询问题可联系<text style="color: #222222;">在线客服</text>
+		</view>
+		<view class="submit-btn">
+			提交
+		</view>
+	</view>
+</template>
+
+<script lang="ts" setup>
+	import { ref, onMounted } from 'vue'
+	import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
+	import { RouterUtils } from '@/utils/util';
+	const selectType = ref(0)
+	const selectItem = (i) => {
+		selectType.value = i
+		console.log(selectType.value);
+	}
+</script>
+
+<style lang="less" scoped>
+	.f-checkout {
+		position: relative;
+
+		&>image {
+			position: absolute;
+			right: 0;
+			top: -10rpx;
+			width: 194rpx;
+		}
+	}
+
+	.f-issue-card {
+		margin-top: 20rpx;
+
+		.f-title {
+			font-weight: bold;
+			font-size: 28rpx;
+			color: #222222;
+		}
+
+		.item-issue-box {
+			display: flex;
+			align-items: center;
+			flex-wrap: wrap;
+			gap: 20rpx;
+			background: #FFFFFF;
+			border-radius: 16rpx;
+			padding: 20rpx;
+			margin-top: 20rpx;
+
+			.sel-item-issue {
+				width: 200rpx;
+				height: 72rpx;
+				background: #C8FF0C;
+				border-radius: 16rpx;
+				font-size: 28rpx;
+				color: #222222;
+				text-align: center;
+				line-height: 72rpx;
+			}
+
+			.item-issue {
+				width: 200rpx;
+				height: 72rpx;
+				background: #F6F6F6;
+				border-radius: 16rpx;
+				font-size: 28rpx;
+				color: #AAAAAA;
+				text-align: center;
+				line-height: 72rpx;
+			}
+		}
+	}
+
+	.f-issuedes-card {
+		margin-top: 28rpx;
+
+		.f-title {
+			font-weight: bold;
+			font-size: 28rpx;
+			color: #222222;
+		}
+
+		.item-issuedes-box {
+			margin-top: 20rpx;
+			height: 290rpx;
+			padding: 20rpx;
+			background: #FFFFFF;
+			border-radius: 16rpx;
+		}
+	}
+
+	.f-uploadimg {
+		margin-top: 20rpx;
+
+		.f-title {
+			font-weight: bold;
+			font-size: 28rpx;
+			color: #222222;
+		}
+	}
+
+	.f-tips {
+		margin-top: 20rpx;
+		text-align: center;
+		font-weight: bold;
+		font-size: 24rpx;
+		color: #AAAAAA;
+	}
+
+	.submit-btn {
+		margin-top: 20rpx;
+		width: 100%;
+		height: 100rpx;
+		background: #C8FF0C;
+		border-radius: 60rpx;
+		font-weight: bold;
+		font-size: 32rpx;
+		color: #222222;
+		text-align: center;
+		line-height: 100rpx;
+	}
+</style>

+ 131 - 0
src/pages/mine/feedbackRecord/index.vue

@@ -0,0 +1,131 @@
+<template>
+	<zzx-navbar :scrollable="false" :back="true" bgColor="linear-gradient( 180deg, #E8FF9B 0%, #F6F6F6 100%)"
+		title="意见反馈"></zzx-navbar>
+		<view style="height:170rpx;"></view>
+	<view class="content">
+		<view class="f-record-card" v-for="item in 6">
+			<view class="f-user-info">
+				<view class="user-info">
+					<view class="user-header">
+						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+					</view>
+					<view class="user-name">张三</view>
+				</view>
+				<view class="user-time">03-20</view>
+			</view>
+			<view class="user-tags">投诉吐槽</view>
+			<view class="user-des">
+				詹姆四对孩子很有耐心,也非常照顾小朋友的情绪,值得推荐!
+			</view>
+			<view class="user-picture">
+				<scroll-view class="scroll-view_H" scroll-x="true">
+					<view class="scroll-view-item_H" v-for="item in 9">
+						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+					</view>
+				</scroll-view>
+			</view>
+			<view class="f-merchants-reply">
+				<view class="merchants">商家回复</view>
+				<view class="reply">
+					<text :class="[switchOpen?'':'textHidden']">谢评价,我们会越来越好,谢谢您的评价,我,谢我,谢谢您的评价,我们会越来越好</text>
+					<text class="open-colse" @click="switchOpen=!switchOpen">{{switchOpen?'收起':'展开'}}</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script lang="ts" setup>
+	import { ref, onMounted } from 'vue'
+	import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
+	const switchOpen=ref(true)
+</script>
+
+<style lang="less">
+	.f-record-card{
+		background: #FFFFFF;
+		border-radius: 32rpx;
+		padding: 20rpx;
+		margin-top: 20rpx;
+		.f-user-info{
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			.user-info{
+				display: flex;
+				align-items: center;
+				gap: 16rpx;
+				.user-header{
+					&>image{
+						width: 60rpx;
+						height: 60rpx;
+						border-radius: 50%;
+					}
+				}
+				.user-name{
+					font-weight: bold;
+					font-size: 24rpx;
+					color: #222222;
+				}
+			}
+			.user-time{
+				font-size: 24rpx;
+				color: #AAAAAA;
+			}
+		}
+		.user-tags{
+			background: #F5F5F5;
+			border-radius: 8rpx;
+			width: 152rpx;
+			height: 48rpx;
+			font-size: 28rpx;
+			color: #AAAAAA;
+			text-align: center;
+			line-height: 48rpx;
+			margin-top: 20rpx;
+		}
+		.user-des{
+			margin-top: 16rpx;
+			font-size: 28rpx;
+			color: #222222;
+		}
+		.user-picture{
+			margin-top: 20rpx;
+			.scroll-view_H{
+				.scroll-view-item_H{
+					&>image{
+						width: 160rpx;
+						height: 160rpx;
+						border-radius: 8rpx;
+						margin-right: 20rpx;
+					}
+				}
+			}
+		}
+		.f-merchants-reply{
+			display: flex;
+			gap: 12rpx;
+			background: #F6F6F6;
+			border-radius: 16rpx;
+			padding: 20rpx;
+			margin-top: 20rpx;
+			transition: all .3s;
+			.merchants{
+				width: 100rpx;
+				height: 40rpx;
+				font-size: 24rpx;
+				color: #AAAAAA;
+			}
+			.reply{
+				width: 520rpx;
+				font-size: 24rpx;
+				color: #222222;
+				display: flex;
+				.open-colse{
+					color: #AAAAAA;
+					width:120rpx;
+				}
+			}
+		}
+	}
+</style>

+ 234 - 4
src/pages/mine/index.vue

@@ -1,15 +1,245 @@
 <template>
-	<view class="">
-		<zzx-cell text="标签栏" url='/pages/mine/tabs'></zzx-cell>
+	<zzx-navbar :scrollable="true" :back="false" title="我的"></zzx-navbar>
+	<view class="m-header">
+		<image class="header-bgImg" src="@/static/mine_bg.png" mode="widthFix"></image>
+	</view>
+	<view class="m-content-box">
+		<view class="m-content">
+			<view class="m-header-info">
+				<view class="user-info">
+					<image class="user-header" v-if="token&&userinfo.userAvatar!==null" :src="userinfo.userAvatar" mode=""></image>
+					<image class="user-header" v-else src="@/static/default-header.png" mode=""></image>
+					<view class="user-nickname">{{token?userinfo.userName:'暂未登录'}}</view>
+				</view>
+				<view class="user-setting" @click="RouterUtils.to_page('/pages/mine/accountSetting/index')">
+					<image src="@/static/account-setting.png" mode="widthFix"></image>
+				</view>
+			</view>
+		</view>
+	</view>
+	<view style="height: 100rpx;"></view>
+	<view class="content">
+		<view class="m-mineinfo-card">
+			<view class="item-info" v-for="(item,idnex) in cardList" :key="index"
+				@click="RouterUtils.to_page('/pages/mine/orderInfo/index')">
+				<zzx-icon :name="item.icon" size="30"></zzx-icon>
+				<view class="item-text">{{item.name}}</view>
+			</view>
+		</view>
+		<view class="m-function-list">
+			<view class="list-title">我的功能</view>
+			<view class="cell-list">
+				<view class="item-cell-contact">
+					<view class="">客服</view>
+					<zzx-icon name="ashRight" size="10"></zzx-icon>
+					<button class="contact-btn" open-type="contact"></button>
+				</view>
+				<zzx-cell text="发票" url=''></zzx-cell>
+				<zzx-cell text="意见反馈" url='/pages/mine/feedback/index'></zzx-cell>
+				<zzx-cell text="家庭成员" url="/pages/index/userList/index?name=家庭成员"></zzx-cell>
+				<zzx-cell text="评价" url='/pages/mine/mineComments/index'></zzx-cell>
+			</view>
+		</view>
+		<view class="login-tips" v-if="!token">
+			<view class="">终于等到你!快去登录吧~</view>
+			<view class="" @click="submitLogin">马上登录</view>
+		</view>
 	</view>
 </template>
 
 <script lang="ts" setup>
+	import { ref, onMounted,computed } from 'vue'
+	import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
 	import zzxCell from '@/components/zzx-cell/zzx-cell.vue';
+	import { RouterUtils,TipsUtils } from '@/utils/util';
+	import { http } from '@/utils/http'
+	import { useCacheStore } from '@/stores/cache'
+	import { onLoad, onPageScroll } from '@dcloudio/uni-app';
+	const cache = useCacheStore()
+	const token=computed(()=>{
+		return cache.get('TOKEN')
+	})
+	const userinfo=computed(()=>{
+		return cache.get('USER_INFO')
+	})
+	const userAvatar=ref('/src/static/default-header.png')
+	const cardList = ref([{
+		name: '全部订单',
+		icon: 'm-allorder'
+	}, {
+		name: '待付款',
+		icon: 'm-pendPay'
+	}, {
+		name: '待使用',
+		icon: 'm-pendUse'
+	}, {
+		name: '已完成',
+		icon: 'm-done'
+	}, {
+		name: '售后',
+		icon: 'm-after-sales'
+	},])
+	onPageScroll((e) => { })
+
+	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)
+			TipsUtils.tips_toast('登录成功')
+		})
+	}
 </script>
 
+<style>
+	page {
+		background: #fff;
+	}
+</style>
 <style lang="less" scoped>
-	.line{
-		border: 1rpx solid #f5f5f5;
+	.m-header {
+		.header-bgImg {
+			width: 100%;
+		}
+	}
+
+	.m-content-box {
+		position: relative;
+
+		.m-content {
+			position: absolute;
+			border-radius: 32rpx 32rpx 0 0;
+			background: #fff;
+			top: -60rpx;
+			width: 100%;
+			height: 160rpx;
+
+			.m-header-info {
+				.user-info {
+					text-align: center;
+					position: relative;
+
+					.user-header {
+						position: absolute;
+						left: 50%;
+						transform: translate(-50%, -50%);
+						width: 160rpx;
+						height: 160rpx;
+					}
+
+					.user-nickname {
+						position: absolute;
+						left: 50%;
+						transform: translate(-50%, -50%);
+						top: 130rpx;
+						font-weight: 800;
+						font-size: 36rpx;
+						color: #222222;
+					}
+				}
+
+				.user-setting {
+					position: absolute;
+					right: 0;
+					top: 24rpx;
+
+					&>image {
+						width: 170rpx;
+					}
+				}
+			}
+		}
+	}
+
+	.m-mineinfo-card {
+		background: #F6F6F6;
+		border-radius: 32rpx;
+		padding: 20rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-around;
+		margin-top: 20rpx;
+
+		.item-info {
+			text-align: center;
+
+			.item-text {
+				font-size: 24rpx;
+				color: #222222;
+			}
+		}
+	}
+
+	.m-function-list {
+		margin-top: 28rpx;
+
+		.list-title {
+			font-weight: 800;
+			font-size: 32rpx;
+			color: #222222;
+		}
+
+		.cell-list {
+			.item-cell-contact {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				font-size: 28rpx;
+				color: #181818;
+				height: 70rpx;
+				padding: 10rpx;
+				position: relative;
+
+				.contact-btn {
+					position: absolute;
+					width: 100%;
+					height: 70rpx;
+					opacity: 0;
+					// background-color: #C8FF0C;
+				}
+			}
+
+			.item-cell-contact:active {
+				background-color: #ececec;
+				border-radius: 20rpx;
+			}
+		}
+	}
+
+	.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;
+
+		&>view:first-child {
+			font-size: 28rpx;
+			color: #FFFFFF;
+		}
+
+		&>view:last-child {
+			width: 160rpx;
+			height: 60rpx;
+			background: #C8FF0C;
+			border-radius: 8rpx;
+			font-size: 28rpx;
+			color: #222222;
+			text-align: center;
+			line-height: 60rpx;
+		}
 	}
 </style>

+ 148 - 0
src/pages/mine/mineComments/index.vue

@@ -0,0 +1,148 @@
+<template>
+	<zzx-navbar :scrollable="false" :back="true" bgColor="linear-gradient( 180deg, #E8FF9B 0%, #F6F6F6 100%)"
+		title="评价详情"></zzx-navbar>
+	<view style="height:170rpx;"></view>
+	<view class="content">
+		<view class="m-comments-card" v-for="item in 5">
+			<view class="m-comments-name">
+				<zzx-icon name="venue-icon4" size="14"></zzx-icon>
+				<view class="name">林旦综合运动馆</view>
+				<zzx-icon name="ashRight" size="12"></zzx-icon>
+			</view>
+			<view class="line"></view>
+			<view class="m-user-info">
+				<view class="user-info">
+					<view class="user-header">
+						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+					</view>
+					<view class="user-name">张三</view>
+				</view>
+				<view class="user-time">03-20</view>
+			</view>
+			<view class="m-star">
+				<view class="star">4.0</view>
+				<uni-rate :readonly="true" size="16" :value="2" />
+			</view>
+			<view class="m-comments">
+				詹姆四对孩子很有耐心,也非常照顾小朋友的情绪,值得推荐!
+			</view>
+			<view class="user-picture">
+				<scroll-view class="scroll-view_H" scroll-x="true">
+					<view class="scroll-view-item_H" v-for="item in 9">
+						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+					</view>
+				</scroll-view>
+			</view>
+			<view class="f-merchants-reply">
+				<view class="merchants">商家回复</view>
+				<view class="reply">
+					<text :class="[switchOpen?'':'textHidden']">谢评价,我们会越来越好,谢谢您的评价,我,谢我,谢谢您的评价,我们会越来越好</text>
+					<text class="open-colse" @click="switchOpen=!switchOpen">{{switchOpen?'收起':'展开'}}</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script lang="ts" setup>
+	import { ref, onMounted } from 'vue'
+	import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
+	const switchOpen=ref(false)
+</script>
+
+<style lang="less" scoped>
+	.m-comments-card {
+		padding: 20rpx;
+		background: #FFFFFF;
+		border-radius: 32rpx;
+		margin-top: 20rpx;
+
+		.m-comments-name {
+			display: flex;
+			align-items: center;
+			gap: 16rpx;
+			margin-bottom: 20rpx;
+
+			.name {
+				font-size: 28rpx;
+				color: #222222;
+			}
+		}
+		.m-user-info{
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			.user-info{
+				display: flex;
+				align-items: center;
+				gap: 16rpx;
+				.user-header{
+					&>image{
+						width: 60rpx;
+						height: 60rpx;
+						border-radius: 50%;
+					}
+				}
+				.user-name{
+					font-weight: bold;
+					font-size: 24rpx;
+					color: #222222;
+				}
+			}
+			.user-time{
+				font-size: 24rpx;
+				color: #AAAAAA;
+			}
+		}
+		.m-star{
+			display: flex;
+			align-items: center;
+			gap: 20rpx;
+			font-size: 24rpx;
+			color: #AAAAAA;
+		}
+		.m-comments{
+			margin-top: 20rpx;
+			font-size: 28rpx;
+			color: #222222;
+		}
+		.user-picture{
+			margin-top: 20rpx;
+			.scroll-view_H{
+				.scroll-view-item_H{
+					&>image{
+						width: 160rpx;
+						height: 160rpx;
+						border-radius: 8rpx;
+						margin-right: 20rpx;
+					}
+				}
+			}
+		}
+		.f-merchants-reply{
+			display: flex;
+			gap: 12rpx;
+			background: #F6F6F6;
+			border-radius: 16rpx;
+			padding: 20rpx;
+			margin-top: 20rpx;
+			transition: all .3s;
+			.merchants{
+				width: 100rpx;
+				height: 40rpx;
+				font-size: 24rpx;
+				color: #AAAAAA;
+			}
+			.reply{
+				width: 520rpx;
+				font-size: 24rpx;
+				color: #222222;
+				display: flex;
+				.open-colse{
+					color: #AAAAAA;
+					width:120rpx;
+				}
+			}
+		}
+	}
+</style>

+ 0 - 134
src/pages/mine/music.vue

@@ -1,134 +0,0 @@
-<template>
-	<!-- :style="{backgroundImage:`url(${musicList.listImg})`}" -->
-	<view class="hot-music">
-		<image :src="musicList.listImg" mode="widthFix"></image>
-		<view class="hot-music-left">
-			<view class="">{{musicList.listDesc}}</view>
-		</view>
-	</view>
-	<view class="content">
-		<view class="music-list-box">
-			<view class="music-list" v-for="item in musicList.songs" :key="item.id" @click="playMusic(item)">
-				<view class="list-left">
-					<view class="music-id text-ellipsis">{{item.id}}</view>
-					<view class="music-info">
-						<view class="music-name">{{item.name}}</view>
-						<view class="singer-name">{{item.artistsname}}</view>
-					</view>
-				</view>
-				<view class="music-more">...</view>
-			</view>
-		</view>
-		<view class="music-play-card" v-if="isplay">
-			<audio style="width: 100%;" :src="playMusicInfo.url" :poster="playMusicInfo.picurl"
-				:name="playMusicInfo.name" :author="playMusicInfo.artistsname" :action="audioAction" controls></audio>
-			<!-- 			<view class="music-card-info">
-				<image src="../../static/logo.png" mode=""></image>
-				<view class="">
-					<view class="">歌曲名</view>
-					<view class="">歌手名</view>
-					</view>
-					<view class="">></view>
-				</view> -->
-		</view>
-	</view>
-</template>
-
-<script lang="ts" setup>
-	import { ref, onMounted } from 'vue'
-	import { http } from '@/utils/http'
-	const musicList = ref();
-	const playMusicInfo = ref();
-	const isplay = ref(false)
-	onMounted(() => {
-		get_musiclsit()
-	})
-	const get_musiclsit = () => {
-		http.get('/api/wangyi/musicChart', { loading: true })
-			.then(res => {
-				musicList.value = res
-			})
-	}
-	const playMusic = (e) => {
-		const innerAudioContext = uni.createInnerAudioContext();
-		if (e.url === null) {
-			uni.showToast({
-				title: '暂无音源',
-				icon: 'none'
-			})
-			return
-		}
-		console.log(innerAudioContext);
-		playMusicInfo.value = e
-		isplay.value = true
-		innerAudioContext.autoplay = true;
-		innerAudioContext.onError((err) => {
-			console.error('音频错误:', err);
-		});
-	}
-</script>
-
-<style lang="less" scoped>
-	.hot-music {
-		position: relative;
-
-		&>image {
-			width: 100%;
-		}
-
-		.hot-music-left {
-			position: absolute;
-			top: 20rpx;
-			font-size: @main-fontsize;
-			color: @white-bg;
-		}
-	}
-
-	.music-list-box {
-		margin-top: 20rpx;
-		background-color: @white-bg;
-		border-radius: 10rpx;
-		padding: 10rpx;
-
-		.music-list {
-			height: 100rpx;
-			display: flex;
-			align-items: center;
-			justify-content: space-between;
-			border-bottom: 1rpx solid #f5f5f5;
-
-			.list-left {
-				display: flex;
-				align-items: center;
-
-				.music-id {
-					width: 80rpx;
-				}
-
-				.music-info {
-					margin-left: 20rpx;
-
-					.music-name {
-						font-size: @main-fontsize;
-					}
-
-					.singer-name {
-						font-size: 26rpx;
-						color: #8f8f94;
-					}
-				}
-			}
-		}
-	}
-
-	.music-play-card {
-		position: fixed;
-		text-align: center;
-		bottom: 0;
-		left: 0;
-		border-radius: 20rpx;
-		background-color: rgb(252, 252, 252);
-		width: 100%;
-		height: 300rpx;
-	}
-</style>

+ 255 - 0
src/pages/mine/orderInfo/index.vue

@@ -0,0 +1,255 @@
+<template>
+	<view class="o-header-list">
+		<view :class="[selected==index?'sel-item-list':'item-list']" v-for="(item,index) in orderTypeList" :key="index"
+			@click="selectedItem(index)">{{item}}</view>
+	</view>
+	<view style="height: 80rpx;"></view>
+	<view class="content">
+		<view class="o-orderlist-card" v-for="item in 2">
+			<view class="o-order-name">
+				<view class="order-name">场地:林旦综合运动馆</view>
+				<!-- 待付款 -->
+				<view class="order-status" v-if="selected==1">待支付(剩余14:23)</view>
+				<view class="item-order-status" v-if="selected==2">待使用</view>
+				<view class="item-order-status" v-if="selected==3">已使用</view>
+			</view>
+			<view class="line"></view>
+			<view class="o-order-info">
+				<view class="item-info">
+					<!-- 多个商品 -->
+					<!-- 					<scroll-view class="scroll-view_H scroll-order" scroll-x="true">
+						<view class="scroll-view-item_H scroll-order-item" v-for="item in 5">
+							<view class="item-order">
+								<view class="order-img">
+									<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+								</view>
+								<view class="order-name textHidden">参赛意外险参赛意外险</view>
+							</view>
+						</view>
+					</scroll-view> -->
+					<!-- 单个商品 -->
+					<view class="item-order-single">
+						<view class="single-img">
+							<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+						</view>
+						<view class="single-name">
+							<view class="item-single-name textHidden" v-for="item in 3">不限场地·指定时段·免费不限场地·指定时段·免费...
+							</view>
+						</view>
+					</view>
+				</view>
+				<view class="order-data">
+					<view class="order-price"><text class="mini-text">¥</text>25.9</view>
+					<view class="order-num">共2件</view>
+				</view>
+			</view>
+			<view class="line"></view>
+			<!-- 待付款 -->
+			<view class="o-order-btn">
+				<view class="cancel-btn" v-if="selected==1">取消订单</view>
+				<view class="pay-btn" v-if="selected==1">付款</view>
+				<!-- 售后/退款 -->
+				<view class="pay-btn" v-if="selected==3">评价</view>
+				<!-- 已使用 -->
+				<view class="cancel-btn" v-if="selected==4">申请退款</view>
+				<view class="pay-btn" v-if="selected==4">凭证</view>
+			</view>
+			<!-- 待使用 -->
+			<view class="o-order-tips">
+				限04.23 06:00-08:00使用,过期作废
+			</view>
+		</view>
+		<zs-empty></zs-empty>
+	</view>
+</template>
+
+<script lang="ts" setup>
+	import { ref, onMounted } from 'vue'
+	import zsEmpty from '@/components/zs-empty/index.vue'
+	const selected = ref(0)
+	const orderTypeList = ref(['全部', '待付款', '待使用', '已使用', '退款/售后'])
+
+	const selectedItem = (i) => {
+		selected.value = i
+	}
+</script>
+
+<style lang="less" scoped>
+	.o-header-list {
+		position: fixed;
+		top: 0;
+		width: 100%;
+		display: flex;
+		align-items: center;
+		justify-content: space-around;
+		height: 80rpx;
+		background: #fff;
+		z-index: 1000;
+
+		.sel-item-list {
+			font-weight: bold;
+			font-size: 28rpx;
+			color: #222222;
+			transition: all .3s;
+		}
+
+		.item-list {
+			font-size: 28rpx;
+			color: #AAAAAA;
+			transition: all .3s;
+		}
+	}
+
+	.o-orderlist-card {
+		background: #FFFFFF;
+		border-radius: 32rpx;
+		padding: 20rpx;
+		margin-top: 20rpx;
+
+		.o-order-name {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			margin-bottom: 26rpx;
+
+			.order-name {
+				font-size: 24rpx;
+				color: #222222;
+			}
+
+			.order-status {
+				font-weight: bold;
+				font-size: 28rpx;
+				color: #FB5B5B;
+			}
+
+			.item-order-status {
+				font-weight: bold;
+				font-size: 28rpx;
+				color: #AAAAAA;
+			}
+		}
+
+		.o-order-info {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			margin-top: 24rpx;
+			margin-bottom: 24rpx;
+
+			.item-info {
+
+				// 多个商品
+				.scroll-order {
+					width: 560rpx;
+
+					.scroll-order-item {
+						margin-right: 20rpx;
+
+						.item-order {
+							.order-img {
+								&>image {
+									width: 160rpx;
+									height: 160rpx;
+									border-radius: 16rpx;
+								}
+							}
+
+							.order-name {
+								width: 160rpx;
+								font-size: 28rpx;
+								color: #222222;
+							}
+						}
+					}
+				}
+
+				// 单个商品
+				.item-order-single {
+					display: flex;
+					align-items: center;
+					gap: 20rpx;
+
+					.single-img {
+						&>image {
+							width: 160rpx;
+							height: 160rpx;
+							border-radius: 16rpx;
+						}
+					}
+
+					.single-name {
+						width: 360rpx;
+						font-size: 28rpx;
+						color: #222222;
+
+						.item-single-name {
+							width: 360rpx;
+							margin-bottom: 10rpx;
+						}
+					}
+				}
+			}
+
+			.order-data {
+				width: 100rpx;
+				border-left: 1rpx solid #efefef;
+				text-align: center;
+
+				.order-price {
+					font-weight: 800;
+					font-size: 36rpx;
+					color: #FB5B5B;
+				}
+
+				.order-num {
+					margin-top: 10rpx;
+					font-size: 24rpx;
+					color: #AAAAAA;
+				}
+			}
+		}
+
+		.o-order-btn {
+			display: flex;
+			align-items: center;
+			justify-content: flex-end;
+			gap: 20rpx;
+			margin-top: 24rpx;
+
+			.cancel-btn {
+				width: 200rpx;
+				height: 68rpx;
+				background: #FFFFFF;
+				border-radius: 60rpx;
+				border: 2rpx solid #AAAAAA;
+				font-weight: bold;
+				font-size: 28rpx;
+				color: #AAAAAA;
+				line-height: 68rpx;
+				text-align: center;
+			}
+
+			.pay-btn {
+				width: 200rpx;
+				height: 68rpx;
+				background: #C8FF0C;
+				border-radius: 60rpx;
+				font-weight: bold;
+				font-size: 28rpx;
+				color: #222222;
+				text-align: center;
+				line-height: 68rpx;
+			}
+		}
+
+		.o-order-tips {
+			margin-top: 24rpx;
+			background: #F6F6F6;
+			border-radius: 16rpx;
+			padding: 20rpx;
+			font-size: 28rpx;
+			color: #222222;
+		}
+	}
+</style>

+ 0 - 255
src/pages/mine/particleEffects.vue

@@ -1,255 +0,0 @@
-<template>
-	<view class="container">
-	  <view class="charge-container">
-	    <!-- 水波动画层 -->
-	    <view class="wave-wrap">
-	      <view class="wave wave-1"></view>
-	      <view class="wave wave-2"></view>
-	    </view>
-	    
-	    <!-- 粒子容器 -->
-	    <view class="particles-box">
-	      <view 
-	        v-for="(item,index) in 15" 
-	        :key="index" 
-	        class="particle"
-	        :style="`--delay:${index*0.2}s; --x:${Math.random()}; --y:${Math.random()}`"
-	      ></view>
-	    </view>
-	    
-	    <!-- 中央内容 -->
-	    <view class="core">
-	      <text class="value">正在充电</text>
-	    </view>
-	  </view>
-	</view>
-	
-	<view class="containers">
-	    <view class="header"></view>
-	    <view class="battery">
-	    </view>
-	    <view class="battery-copy">
-	        <view class="g-wave"></view>
-	        <view class="g-wave"></view>
-	        <view class="g-wave"></view>
-	    </view>
-	</view>
-</template>
-
-<script>
-</script>
-
-<style lang="less" scoped>
-	/* 容器样式 */
-	.container {
-	  display: flex;
-	  justify-content: center;
-	  align-items: center;
-	  min-height: 100vh;
-	  background: #0a1a30;
-	}
-	
-	.charge-container {
-	  position: relative;
-	  width: 320rpx;
-	  height: 320rpx;
-	}
-	
-	/* 水波动画 */
-	.wave-wrap {
-	  position: absolute;
-	  width: 100%;
-	  height: 100%;
-	  border-radius: 50%;
-	  overflow: hidden;
-	}
-	
-	.wave {
-	  position: absolute;
-	  width: 100%;
-	  height: 100%;
-	  border-radius: 50%;
-	  border: 4rpx solid #7ad4ff;
-	}
-	
-	.wave-1 {
-	  animation: wave-drift 10s infinite linear;
-	}
-	
-	.wave-2 {
-	  animation: wave-drift 6s infinite linear reverse;
-	}
-	
-	@keyframes wave-drift {
-	  0% {
-	    transform: scale(0.9);
-	    opacity: 0.6;
-	  }
-	  50% {
-	    transform: scale(1.1);
-	    opacity: 0.3;
-	  }
-	  100% {
-	    transform: scale(0.9);
-	    opacity: 0.6;
-	  }
-	}
-	
-	/* 粒子系统 */
-	.particles-box {
-	  position: absolute;
-	  width:100%;
-	  height:100%;
-	  overflow: hidden;
-	}
-	
-	.particle {
-	  position: absolute;
-	  width: 6rpx;
-	  height: 6rpx;
-	  background: #5ec3ff;
-	  border-radius: 50%;
-	  filter: blur(2rpx);
-	  animation: float 10s infinite ease-in-out;
-	  animation-delay: var(--delay);
-	}
-	
-	/* 随机漂浮动画 */
-	@keyframes float {
-	  0%, 100% {
-	    transform: 
-	      translate(calc(-50% + var(--x)*200rpx), 
-	                calc(-50% + var(--y)*400rpx));
-	    opacity:1;
-	  }
-	  50% {
-	    transform: 
-	      translate(calc(-50% + var(--x)*500rpx), 
-	                calc(-50% + var(--y)*400rpx));
-	    opacity:0.8;
-	  }
-	}
-	
-	/* 核心显示 */
-	.core {
-	  position: absolute;
-	  width: 200rpx;
-	  height: 200rpx;
-	  background: rgba(32, 85, 255, 0.1);
-	  border-radius: 50%;
-	  display: flex;
-	  justify-content: center;
-	  align-items: center;
-	  left: 50%;
-	  top: 50%;
-	  transform: translate(-50%, -50%);
-	  box-shadow: inset 0 0 40rpx #7ad4ff;
-	}
-	
-	.value {
-	  color: #7ad4ff;
-	  font-size: 28rpx;
-	  font-weight: bold;
-	  text-shadow: 0 0 20rpx rgba(122, 212, 255, 0.8);
-	}
-	
-	.containers {
-	    position: relative;
-	    width: 140px;
-	    margin: auto;
-		margin-top: 50rpx;
-	}
-	
-	.header {
-	    position: absolute;
-	    width: 26px;
-	    height: 10px;
-	    left: 50%;
-	    top: 0;
-	    transform: translate(-50%, -10px);
-	    border-radius: 5px 5px 0 0;
-	    background: rgba(255, 255, 255, .88);
-	}
-	
-	.battery-copy {
-	    position: absolute;
-	    top: 0;
-	    left: 0;
-	    height: 220px;
-	    width: 140px;
-	    border-radius: 15px 15px 5px 5px;
-	    overflow: hidden;
-	}
-	
-	.battery {
-	    position: relative;
-	    height: 220px;
-	    box-sizing: border-box;
-	    border-radius: 15px 15px 5px 5px;
-	    box-shadow: 0 0 5px 2px rgba(255, 255, 255, 0.22);
-	    background: #fff;
-	    z-index: 1;
-	    
-	    &::after {
-	        content: "";
-	        position: absolute;
-	        left: 0;
-	        right: 0;
-	        bottom: 0;
-	        top: 80%;
-	        background: linear-gradient(to bottom, #7abcff 0%, #00BCD4 44%, #2196F3 100%);
-	        border-radius: 0px 0px 5px 5px;
-	        box-shadow: 0 14px 28px rgba(33, 150, 243, 0), 0 10px 10px rgba(9, 188, 215, 0.08);
-	        animation: charging 10s linear infinite;
-	        filter: hue-rotate(90deg);
-	    }
-	}
-	
-	.g-wave {
-	    position: absolute;
-	    width: 300px;
-	    height: 300px;
-	    background: rgba(255, 255, 255, .8);
-	    border-radius: 45% 47% 44% 42%;
-	    bottom: 25px;
-	    left: 50%;
-	    transform: translate(-50%, 0);
-	    z-index: 1;
-	    animation: move 10s linear infinite;
-	}
-	
-	.g-wave:nth-child(2) {
-	    border-radius: 38% 46% 43% 47%;
-	    transform: translate(-50%, 0) rotate(-135deg);
-	}
-	
-	.g-wave:nth-child(3) {
-	    border-radius: 42% 46% 37% 40%;
-	    transform: translate(-50%, 0) rotate(135deg);
-	}
-	
-	@keyframes charging {
-		50% {
-	        box-shadow: 0 14px 28px rgba(0, 150, 136, 0.83), 0px 4px 10px rgba(9, 188, 215, 0.4);
-	    }
-	    
-	    95% {
-	        top: 5%;
-	        filter: hue-rotate(0deg);
-	        border-radius: 0 0 5px 5px;
-	        box-shadow: 0 14px 28px rgba(4, 188, 213, .2), 0 10px 10px rgba(9, 188, 215, 0.08);
-	    }
-	    100% {
-	        top: 0%;
-	        filter: hue-rotate(0deg);
-	        border-radius: 15px 15px 5px 5px;
-	        box-shadow: 0 14px 28px rgba(4, 188, 213, 0), 0 10px 10px rgba(9, 188, 215, 0.4);
-	    }
-	}
-	
-	@keyframes move {
-	    100% {
-	        transform: translate(-50%, -160px) rotate(720deg);
-	    }
-	}
-</style>

+ 64 - 0
src/pages/mine/reviseNickname/index.vue

@@ -0,0 +1,64 @@
+<template>
+	<view class="content">
+		<view class="r-nickname-card">
+			<view class="r-nickinput">
+				<input type="text" maxlength="10" placeholder="11111" />
+			</view>
+			<view class="r-clear-icon">
+				<zzx-icon name="m-clear" size="16"></zzx-icon> 
+			</view>
+		</view>
+		<view class="r-tips">限2-10个汉字</view>
+	</view>
+	<view class="r-bottom-btn">
+		<view class="submit-btn">确定</view>
+	</view>
+</template>
+
+<script>
+</script>
+
+<style lang="less" scoped>
+	.r-nickname-card{
+		background: #FFFFFF;
+		border-radius: 32rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding: 20rpx;
+		margin-top: 20rpx;
+		.r-nickinput{
+			font-weight: bold;
+			font-size: 28rpx;
+			color: #222222;
+		}
+	}
+	.r-tips{
+		margin-top: 14rpx;
+		font-size: 24rpx;
+		color: #AAAAAA;
+	}
+	.r-bottom-btn{
+		position: fixed;
+		bottom: 0;
+		width: 750rpx;
+		height: 166rpx;
+		background: #FFFFFF;
+		box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0,0,0,0.09);
+		border-radius: 32rpx 32rpx 0rpx 0rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		.submit-btn{
+			width: 686rpx;
+			height: 100rpx;
+			background: #C8FF0C;
+			border-radius: 60rpx;
+			font-weight: bold;
+			font-size: 32rpx;
+			color: #222222;
+			text-align: center;
+			line-height: 100rpx;
+		}
+	}
+</style>

+ 0 - 138
src/pages/mine/signPanel.vue

@@ -1,138 +0,0 @@
-<template>
-	<view class="canvas-box">
-		<!-- @touchstart:触摸开始,@touchmove:触摸移动,@touchend:触摸结束 -->
-		<canvas @touchstart="handleTouch" @touchmove="handleMove" @touchend="handleEnd" class="my-canvas" type="2d"
-			canvas-id="myCanvas" id="myCanvas"></canvas>
-		<view class="sign-btn-box">
-			<view @click="clearSign">清空</view>
-			<view @click="confirmSign">确定</view>
-		</view>
-	</view>
-</template>
-
-<script lang="ts" setup>
-	import { ref, reactive } from 'vue';
-	import { onReady } from '@dcloudio/uni-app';
-	const isDrawing = ref(false);
-	const ctx = ref(null);
-
-	const position = reactive({
-		x: 0,
-		y: 0
-	})
-	onReady(() => {
-		const query = uni.createSelectorQuery()
-		console.log(query);
-		query.select('#myCanvas').fields({ node: true, size: true }, null).exec((res) => {
-			const canvas = res[0].node;
-			console.log(canvas, '----canvas对象');
-			ctx.value = canvas.getContext('2d');   //渲染上下文
-			const dpr = uni.getSystemInfoSync().pixelRatio  //获取设备像素进行画布初始化
-			canvas.width = res[0].width * dpr
-			canvas.height = res[0].height * dpr
-			ctx.value.scale(dpr, dpr)
-			// 设置绘制属性
-			ctx.value.strokeStyle = '#000'; // 黑色线条
-			ctx.value.lineWidth =4; // 线条宽度
-			draw_signBg()
-		})
-	})
-
-	const draw_signBg = () => {
-		// 创建白色矩形背景板
-		ctx.value.fillStyle = "#fff"
-		ctx.value.fillRect(0, 0, ctx.value.canvas.width, ctx.value.canvas.height)
-	}
-	// 开始绘制
-	const handleTouch = (e) => {
-		isDrawing.value = true
-		// 获取当前点的坐标
-		const x = e.touches[0].x;
-		const y = e.touches[0].y;
-		position.x = x;
-		position.y = y;
-	}
-
-	// 进行绘制
-	const handleMove = (e) => {
-		if (!isDrawing.value) return;
-		const x = e.touches[0].x;
-		const y = e.touches[0].y;
-		// beginPath() 新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
-		ctx.value.beginPath();
-		// moveTo(x,y) 将笔触移动到指定的坐标 x 以及 y 上。
-		ctx.value.moveTo(position.x, position.y);
-		// lineTo(x, y) 绘制一条从当前位置到指定 x 以及 y 位置的直线。
-		ctx.value.lineTo(x, y);
-		// stroke() 使用描边通过线条来绘制当前路径,不需要填充闭合路径
-		ctx.value.stroke();
-		position.x = x;
-		position.y = y;
-	}
-
-	// 结束绘制
-	const handleEnd = (e) => {
-		isDrawing.value = false
-	}
-
-	const clearSign = () => {
-		ctx.value.clearRect(0, 0, ctx.value.canvas.width, ctx.value.canvas.height)
-		draw_signBg() // 设置成白色背景
-	}
-
-	const confirmSign = () => {
-		// 获取 canvas 对象
-		uni.createSelectorQuery()
-			.select('#myCanvas')
-			.node()
-			.exec((res) => {
-				// 获取 Canvas 对象
-				const canvas = res[0].node;
-				// 生成图片
-				uni.canvasToTempFilePath({canvas,success: function (res) {
-						// 在H5平台下,tempFilePath 为 base64
-						console.log(res.tempFilePath)
-						// 预览图片
-						uni.previewImage({
-							urls: [res.tempFilePath]
-						})
-					},
-					fail: (res) => {
-						console.log(res)
-					}
-				})
-			})
-	}
-</script>
-
-<style lang="less" scoped>
-	.my-canvas {
-		width: 100%;
-		height: 1200rpx;
-	}
-	.sign-btn-box{
-		margin-top: 20rpx;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		gap: 50rpx;
-		&>view:first-child{
-			width: 150rpx;
-			height: 80rpx;
-			border: 2rpx solid #00aaff;
-			border-radius: 20rpx;
-			text-align: center;
-			line-height: 80rpx;
-		}
-		&>view:last-child{
-			width: 150rpx;
-			height: 80rpx;
-			border: 2rpx solid #00aaff;
-			background: #00aaff;
-			border-radius: 20rpx;
-			text-align: center;
-			line-height: 80rpx;
-			color: white;
-		}
-	}
-</style>

+ 0 - 20
src/pages/mine/switch.vue

@@ -1,20 +0,0 @@
-<template>
-	<view class="content" style="margin-top: 30rpx;">
-		<zzx-switch v-model="switchState" active-color="#6cb3f0" inactive-color="#909399"
-			@change="handleSwitchChange" />
-	</view>
-</template>
-
-<script setup lang="ts">
-	import { ref } from 'vue'
-	import zzxSwitch from '@/components/zzx-switch/zzx-switch.vue'
-
-	const switchState = ref(false)
-
-	const handleSwitchChange = (value : boolean) => {
-		console.log('状态:', value)
-	}
-</script>
-<style scoped>
-
-</style>

+ 0 - 46
src/pages/mine/tabs.vue

@@ -1,46 +0,0 @@
-<template>
-	<view class="content">
-		<view class="">菜单栏样式1:type值为slider时</view>
-		<view style="height: 20rpx;"></view>
-		<zzx-tabs :menus="['菜单1', '菜单2', '菜单3']" type="slider"
-			@change="handleTabChange">
-		</zzx-tabs>
-		<view style="height: 40rpx;"></view>
-		<view class="">菜单栏样式2:type值为underline时;使用activeColor可定义选中的字体颜色</view>
-		<view style="height: 20rpx;"></view>
-		<zzx-tabs :menus="['菜单1', '菜单2', '菜单3']" type="underline" activeColor="#6cb3f0"
-			:disabled="[false, false, false]" @change="handleTabChange">
-		</zzx-tabs>
-			<view class="toggle-window" style="background-color:#00557f;" v-if="toggle===0">
-				1111111111
-			</view>
-			<view class="toggle-window" style="background-color: #aaaa00;" v-else-if="toggle===1">
-				2222222222
-			</view>
-			<view class="toggle-window" style="background-color: #55557f;" v-else>
-				3333333333
-			</view>
-	</view>
-</template>
-
-<script lang="ts" setup>
-	import { ref } from 'vue';
-	import zzxTabs from '@/components/zzx-tabs/zzx-tabs.vue';
-	const toggle = ref(0);
-	const handleTabChange = (index : any) => {
-		toggle.value = index
-		console.log('当前选中:', index);
-	};
-</script>
-
-<style lang="less" scoped>
-	.toggle-window {
-		margin-top: 20rpx;
-		border-radius: 10rpx;
-		height: 500rpx;
-		width: 100%;
-		text-align: center;
-		line-height: 500rpx;
-		transition: all 1s ease;
-	}
-</style>

+ 0 - 7
src/pages/mine/vrCheck.vue

@@ -1,7 +0,0 @@
-<template>
-	<!-- <zzx-vr></zzx-vr> -->
-</template>
-<script lang="ts" setup>
-// import zzxVr from '../../uni_modules/HOLES-VR/components/HOLES-VR/HOLES-VR.vue'
-</script>
-<style></style>

+ 0 - 30
src/pages/mine/waterfall.vue

@@ -1,30 +0,0 @@
-<template>
-	<view style="height: 20rpx;"></view>
-	<zzx-waterfall :list="goodsList" nameKey="name" imageKey="picurl" textKey="artistsname" gap="10"
-		@item-click="handleItemClick">
-	</zzx-waterfall>
-</template>
-
-<script lang="ts" setup>
-	import zzxWaterfall from '@/components/zzx-waterfall/zzx-waterfall.vue';
-	import { ref, onMounted } from 'vue';
-	import { http } from '@/utils/http';
-	const goodsList = ref([])
-	onMounted(() => {
-		get_lsit()
-	})
-	const get_lsit = () => {
-		http.get('/api/wangyi/musicChart', { loading: true })
-			.then(res => {
-				goodsList.value = res.songs
-			})
-	}
-
-	const handleItemClick = (e : any) => {
-		console.log(e);
-	}
-</script>
-
-<style lang="less" scoped>
-
-</style>

二進制
src/static/account-setting.png


二進制
src/static/default-header.png


二進制
src/static/empty.png


文件差異過大導致無法顯示
+ 0 - 0
src/static/icons/m-after-sales.svg


+ 1 - 0
src/static/icons/m-allorder.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28" height="28" viewBox="0 0 28 28"><defs><style>.a{fill:url(#a);}.b{fill:#222;stroke:#222;}.c{fill:url(#b);}.d{fill:none;}</style><linearGradient id="a" x1="0.89" y1="0.07" x2="0.13" y2="0.9" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#c8ff0c"/><stop offset="1" stop-color="#c8ff0c" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="0.935" y1="0.5" x2="0" y2="0.5" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#222"/><stop offset="1" stop-color="#6b6b6b" stop-opacity="0"/></linearGradient></defs><g transform="translate(-20 -267)"><rect class="a" width="19" height="14" rx="2" transform="translate(26.432 268)"/><g transform="translate(23.001 267.809)"><path class="b" d="M142.438,217.556H129.884A1.885,1.885,0,0,1,128,215.671V196.445a1.885,1.885,0,0,1,1.885-1.885h16.61a1.885,1.885,0,0,1,1.885,1.885v15.17a.354.354,0,0,1-.113.264l-5.564,5.557a.325.325,0,0,1-.264.121Zm-12.553-22.242a1.129,1.129,0,0,0-1.131,1.131v19.226a1.129,1.129,0,0,0,1.131,1.131h12.4l5.338-5.338V196.445a1.129,1.129,0,0,0-1.131-1.131h-16.61Z" transform="translate(-128 -191.369)"/><path class="b" d="M244.979,381.764a.373.373,0,0,1-.377-.377V377.33a1.885,1.885,0,0,1,1.885-1.885h4.056a.377.377,0,1,1,0,.754h-4.056a1.129,1.129,0,0,0-1.131,1.131v4.056A.373.373,0,0,1,244.979,381.764Zm2.383-17h-9.477a.377.377,0,1,1,0-.754h9.47a.377.377,0,0,1,.008.754Zm-12.116,0H234.19a.377.377,0,0,1,0-.754h1.056a.373.373,0,0,1,.377.377A.378.378,0,0,1,235.246,364.762Z" transform="translate(-230.541 -355.577)"/><rect class="c" width="13" height="2" rx="1" transform="translate(3.431 14.191)"/></g><g transform="translate(20.258 267.258)"><rect class="d" width="28" height="28" transform="translate(-0.258 -0.258)"/></g></g></svg>

+ 1 - 0
src/static/icons/m-clear.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15"><defs><style>.a{fill:#f6f6f6;}.b{fill:#aaa;}</style></defs><g transform="translate(-332.001 -115)"><path class="a" d="M71.5,64A7.5,7.5,0,1,0,79,71.5,7.509,7.509,0,0,0,71.5,64Zm3.059,9.81a.536.536,0,1,1-.759.756l-2.3-2.311-2.311,2.286a.536.536,0,1,1-.753-.762L70.741,71.5l-2.3-2.307a.536.536,0,0,1,.759-.756l2.3,2.31,2.311-2.286a.536.536,0,1,1,.753.762L72.259,71.5Z" transform="translate(268.001 51)"/><path class="b" d="M259.807,274.5l2.336-2.336a.471.471,0,0,0-.666-.666l-2.336,2.336-2.336-2.336a.471.471,0,0,0-.666.666l2.336,2.336-2.336,2.336a.471.471,0,1,0,.666.666l2.336-2.336,2.336,2.336a.471.471,0,1,0,.666-.666Z" transform="translate(80.359 -151.998)"/></g></svg>

+ 1 - 0
src/static/icons/m-done.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28" height="28" viewBox="0 0 28 28"><defs><style>.a{fill:none;}.b{fill:url(#a);}.c{fill:#222;stroke:#222;stroke-width:0.7px;}.d{fill:url(#b);}</style><linearGradient id="a" x1="0.89" y1="0.07" x2="0.13" y2="0.9" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#c8ff0c"/><stop offset="1" stop-color="#c8ff0c" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="0.935" y1="0.5" x2="0" y2="0.5" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#222"/><stop offset="1" stop-color="#6b6b6b" stop-opacity="0"/></linearGradient></defs><g transform="translate(-255 -267)"><rect class="a" width="28" height="28" transform="translate(255 267)"/><g transform="translate(-1)"><g transform="translate(81.58)"><rect class="b" width="19" height="14" transform="translate(182.5 268)"/></g><g transform="translate(258 271.92)"><g transform="translate(0 -0.416)"><path class="c" d="M53.214,373.682h-19.7A1.552,1.552,0,0,1,32,372.044v-13.1a.5.5,0,0,1,.505-.546H54.224a.5.5,0,0,1,.505.546v13.1a1.585,1.585,0,0,1-1.515,1.637Zm-20.2-14.191v12.553a.5.5,0,0,0,.505.546h19.7a.5.5,0,0,0,.505-.546V359.491H33.01Z" transform="translate(-32 -351.408)"/><path class="c" d="M55.854,76.249a.529.529,0,0,1-.455-.256l-3.233-6.4a.529.529,0,0,0-.455-.256H38.275a.529.529,0,0,0-.455.256l-3.233,6.345a.463.463,0,0,1-.657.2c-.2-.154-.354-.461-.2-.665l3.233-6.4a1.475,1.475,0,0,1,1.364-.819H51.762a1.589,1.589,0,0,1,1.364.819l3.233,6.4a.454.454,0,0,1-.2.665c-.152.051-.2.1-.3.1Z" transform="translate(-33.624 -68.267)"/><path class="c" d="M324.786,89.6h1.092v7.083h-1.092Z" transform="translate(-313.962 -88.674)"/></g></g><rect class="d" width="14" height="2" rx="1" transform="translate(262 285)"/></g></g></svg>

+ 1 - 0
src/static/icons/m-pendPay.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28" height="28" viewBox="0 0 28 28"><defs><style>.a{fill:none;}.b{fill:url(#a);}.c{fill:#222;stroke:#222;}.d{fill:url(#b);}</style><linearGradient id="a" x1="0.89" y1="0.07" x2="0.13" y2="0.9" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#c8ff0c"/><stop offset="1" stop-color="#c8ff0c" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="0.935" y1="0.5" x2="0" y2="0.5" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#222"/><stop offset="1" stop-color="#6b6b6b" stop-opacity="0"/></linearGradient></defs><g transform="translate(-94 -267)"><rect class="a" width="28" height="28" transform="translate(94 267)"/><g transform="translate(-0.6)"><rect class="b" width="19" height="14" rx="2" transform="translate(102 268)"/><g transform="translate(0 1)"><g transform="translate(-34.651 44.58)"><g transform="translate(131.252 225.458)"><path class="c" d="M.408,58.79A.423.423,0,0,1,0,58.354V53.847a1.519,1.519,0,0,1,1.481-1.552H19.043a1.519,1.519,0,0,1,1.481,1.552v2.092a.409.409,0,1,1-.816,0V53.847a.716.716,0,0,0-.2-.488.626.626,0,0,0-.465-.192H1.481a.626.626,0,0,0-.465.192.716.716,0,0,0-.2.488v4.508a.423.423,0,0,1-.408.436Z" transform="translate(0 -52.295)"/><path class="c" d="M21.509,207.346H1.491A1.536,1.536,0,0,1,0,205.77V189.185a1.536,1.536,0,0,1,1.491-1.575H21.509A1.536,1.536,0,0,1,23,189.185v1.522a.412.412,0,1,1-.821,0v-1.522a.73.73,0,0,0-.2-.5.628.628,0,0,0-.468-.2H1.491a.628.628,0,0,0-.468.2.73.73,0,0,0-.2.5V205.77a.681.681,0,0,0,.669.69H21.509a.681.681,0,0,0,.669-.69v-2.58a.412.412,0,1,1,.821,0v2.58a1.536,1.536,0,0,1-1.491,1.575Z" transform="translate(0 -184.384)"/></g></g><rect class="d" width="19" height="2" rx="1" transform="translate(100.432 281)"/></g></g></g></svg>

文件差異過大導致無法顯示
+ 0 - 0
src/static/icons/m-pendUse.svg


二進制
src/static/logo.png


二進制
src/static/m-feedbackReocd.png


二進制
src/static/mine_bg.png


二進制
src/static/vr.jpg


+ 10 - 1
src/styles/variables.less

@@ -20,4 +20,13 @@
 	 background-repeat: no-repeat;
 	 background-size: cover;
 	 background-position: center;
- }
+ }
+ .line {
+ 	border: 1rpx solid #f5f5f5;
+ }
+ 	.scroll-view_H {
+ 		white-space: nowrap;
+ 	}
+	.scroll-view-item_H {
+			display: inline-block;
+		}

+ 184 - 295
src/utils/http/index.ts

@@ -28,314 +28,203 @@ import type { UniRequestConfig, UniResponse } from '@dcloudio/uni-app'
 
 // 定义基础响应类型
 export interface HttpResponse<T = any> {
-	code : number
-	message : string
-	data : T
-	[key : string] : any
+  code: number
+  message: string
+  data: T
+  [key: string]: any
 }
 
 // 请求配置类型
 export interface RequestConfig extends UniRequestConfig {
-	baseURL ?: string
-	retry ?: number // 重试次数
-	retryDelay ?: number // 重试延迟时间(ms)
-	loading ?: boolean // 是否显示加载状态
-	headers ?: Record<string, string>
-	timeout ?: number
-	skipAuth ?: boolean // 是否跳过认证检查
-}
-
-// 定义 Token 类型
-export interface TokenData {
-	value : string
-	expire : number
-}
-
-// 拦截器类型
-interface Interceptor<V> {
-	fulfilled : (value : V) => V | Promise<V>
-	rejected ?: (error : any) => any
+  baseURL?: string
+  retry?: number // 重试次数
+  retryDelay?: number // 重试延迟时间(ms)
+  loading?: boolean // 是否显示加载状态
+  headers?: Record<string, string>
+  timeout?: number
+  skipAuth?: boolean // 是否跳过认证检查
 }
 
 export class HttpClient {
-	private defaults : RequestConfig
-	private interceptors : {
-		request : Interceptor<RequestConfig>[]
-		response : Interceptor<UniResponse<HttpResponse>>[]
-	}
-	private pendingRequests : Map<string, RequestTask>
-
-	// 新增刷新相关属性
-	private isRefreshing = false
-	private refreshSubscribers : ((token : string) => void)[] = []
-
-	constructor(config : RequestConfig = {}) {
-		this.defaults = {
-			baseURL: '',
-			timeout: 10000,
-			retry: 0,
-			retryDelay: 1000,
-			loading: false,
-			...config
-		}
-
-		this.interceptors = {
-			request: [],
-			response: []
-		}
-		this.pendingRequests = new Map()
-	}
-
-	//token检查方法
-	static checkTokenValidity(token : any) : string | null {
-		let tokenValue : string | null = null
-		let tokenExpire : number | null = null
-		try {
-			if (token) {
-				// 处理字符串类型的token(可能是JSON或原始字符串)
-				if (typeof token === 'string') {
-					try {
-						// 尝试解析为JSON对象
-						const parsed = JSON.parse(token)
-						if (parsed && typeof parsed.value === 'string') {
-							tokenValue = parsed.value
-							tokenExpire = parsed.expire
-						} else {
-							// 不是有效JSON对象,当作原始token字符串
-							tokenValue = token
-						}
-					} catch (e) {
-						// JSON解析失败,当作原始token字符串
-						tokenValue = token
-					}
-				}
-				else if (typeof token === 'object' && token.value) {
-					tokenValue = token.value
-					tokenExpire = token.expire
-				}
-				if (tokenValue) {
-					const now = Date.now() + 10000 // 10秒缓冲
-					// 如果有过期时间则检查,否则认为有效
-					if (tokenExpire) {
-						return tokenExpire > now ? tokenValue : null
-					}
-					return tokenValue
-				}
-			}
-		} catch (e) {
-			console.error('Token 有效性检查失败:', e)
-		}
-		return null
-	}
-
-	private createRequestKey(config : RequestConfig) : string {
-		return `${config.method}-${config.url}-${JSON.stringify(config.data)}`
-	}
-
-	// token刷新
-	private async refreshToken() : Promise<void> {
-		try {
-			const refreshToken = uni.getStorageSync('refreshToken');
-			const tokenValue = HttpClient.checkTokenValidity(refreshToken);
-
-			const response = await this.request<{
-				accessToken : string;
-				refreshToken : string;
-			}>({
-				url: `/member/auth/refresh-token?refreshToken=${tokenValue}`,
-				method: 'POST',
-				data: '',
-				skipAuth: true
-			});
-
-			uni.setStorageSync('token', response.accessToken);
-			uni.setStorageSync('refreshToken', response.refreshToken);
-
-			this.refreshSubscribers.forEach(callback => callback(response.accessToken));
-			this.refreshSubscribers = [];
-		} catch (error) {
-			console.error('刷新Token失败:', error);
-			uni.removeStorageSync('token');
-			uni.removeStorageSync('refreshToken');
-			uni.reLaunch({ url: '/pages/login/selectLogin' });
-			throw error;
-		} finally {
-			this.isRefreshing = false;
-		}
-	}
-
-	// 核心方法增加无感刷新逻辑
-	async request<T = any>(config : RequestConfig) : Promise<T> {
-		let mergedConfig : RequestConfig = { ...this.defaults, ...config }
-		// 执行请求拦截器
-		for (const interceptor of this.interceptors.request) {
-			try {
-				mergedConfig = await interceptor.fulfilled(mergedConfig)
-			} catch (error) {
-				interceptor.rejected?.(error)
-				throw error
-			}
-		}
-		const requestKey = this.createRequestKey(mergedConfig)
-		// 取消重复请求
-		if (this.pendingRequests.has(requestKey)) {
-			this.pendingRequests.get(requestKey)?.abort()
-		}
-
-		return new Promise((resolve, reject) => {
-			const sendRequest = async (retryCount = 0) => {
-				if (mergedConfig.loading) {
-					uni.showLoading({ title: '加载中...', mask: true })
-				}
-
-				try {
-					const task = uni.request({
-						...mergedConfig,
-						url: mergedConfig.baseURL + mergedConfig.url,
-						success: async (response) => {
-							const res = response.data as HttpResponse;
-							if (res.code === 401 && !mergedConfig.skipAuth) {
-								const retryOriginalRequest = new Promise<T>((resolve) => {
-									this.refreshSubscribers.push((newToken) => {
-										// 使用新Token重试请求
-										const retryConfig = {
-											...mergedConfig,
-											header: {
-												...mergedConfig.header,
-												Authorization: `Bearer ${newToken}`
-											}
-										}
-										this.request(retryConfig).then(resolve)
-									})
-								})
-								if (!this.isRefreshing) {
-									this.isRefreshing = true
-									this.refreshToken().catch((error) => {
-										this.refreshSubscribers = []
-										reject(error)
-									})
-								}
-								return resolve(await retryOriginalRequest)
-							}
-							// 执行响应拦截器
-							let processedResponse = response
-							for (const interceptor of this.interceptors.response) {
-								try {
-									processedResponse = await interceptor.fulfilled(processedResponse)
-								} catch (error) {
-									interceptor.rejected?.(error)
-									reject(error)
-									return
-								}
-							}
-
-							const resData = processedResponse.data as HttpResponse<T>
-							if (resData.code === 0) {
-								resolve(resData.data)
-							} else {
-								uni.showToast({
-									title: resData.msg || '请求失败',
-									icon: 'none'
-								})
-								reject(resData)
-							}
-						},
-						fail: async (error) => {
-							// 重试逻辑
-							if (retryCount < mergedConfig.retry!) {
-								setTimeout(() => {
-									sendRequest(retryCount + 1)
-								}, mergedConfig.retryDelay)
-							} else {
-								reject(error)
-							}
-						},
-						complete: () => {
-							this.pendingRequests.delete(requestKey)
-							if (mergedConfig.loading) {
-								uni.hideLoading()
-							}
-						}
-					}) as RequestTask
-
-					this.pendingRequests.set(requestKey, task)
-				} catch (error) {
-					reject(error)
-				}
-			}
-			sendRequest()
-		})
-	}
-
-	// 添加请求拦截器
-	useRequestInterceptor(interceptor : Interceptor<RequestConfig>) {
-		this.interceptors.request.push(interceptor)
-	}
-
-	// 添加响应拦截器
-	useResponseInterceptor(interceptor : Interceptor<UniResponse<HttpResponse>>) {
-		this.interceptors.response.push(interceptor)
-	}
-
-	// 快捷方法
-	get<T = any>(url : string, config ?: RequestConfig) {
-		return this.request<T>({ ...config, url, method: 'GET' })
-	}
-
-	post<T = any>(url : string, data ?: any, config ?: RequestConfig) {
-		return this.request<T>({ ...config, url, data, method: 'POST' })
-	}
-
-	delete<T = any>(url : string, data ?: any, config ?: RequestConfig) {
-		return this.request<T>({ ...config, url, data, method: 'DELETE' })
-	}
-
-	put<T = any>(url : string, data ?: any, config ?: RequestConfig) {
-		return this.request<T>({ ...config, url, data, method: 'PUT' })
-	}
+  private defaults: RequestConfig
+  private pendingRequests: Map<string, RequestTask>
+
+  constructor(config: RequestConfig = {}) {
+    this.defaults = {
+      baseURL: '',
+      timeout: 10000,
+      retry: 0,
+      retryDelay: 1000,
+      loading: false,
+      ...config
+    }
+
+    this.pendingRequests = new Map()
+  }
+
+  // token检查方法
+  static checkTokenValidity(token: any): string | null {
+    let tokenValue: string | null = null
+    try {
+      if (token) {
+        if (typeof token === 'string') {
+          try {
+            const parsed = JSON.parse(token)
+            if (parsed && typeof parsed.value === 'string') {
+              tokenValue = parsed.value
+            } else {
+              tokenValue = token
+            }
+          } catch (e) {
+            tokenValue = token
+          }
+        }
+        else if (typeof token === 'object' && token.value) {
+          tokenValue = token.value
+        }
+      }
+    } catch (e) {
+      console.error('Token 有效性检查失败:', e)
+    }
+    return tokenValue
+  }
+
+  private createRequestKey(config: RequestConfig): string {
+    return `${config.method}-${config.url}-${JSON.stringify(config.data)}`
+  }
+
+  async request<T = any>(config: RequestConfig): Promise<T> {
+    let mergedConfig: RequestConfig = { ...this.defaults, ...config }
+    const requestKey = this.createRequestKey(mergedConfig)
+    
+    // 取消重复请求
+    if (this.pendingRequests.has(requestKey)) {
+      this.pendingRequests.get(requestKey)?.abort()
+    }
+
+    return new Promise((resolve, reject) => {
+      const sendRequest = (retryCount = 0) => {
+        if (mergedConfig.loading) {
+          uni.showLoading({ title: '加载中...', mask: true })
+        }
+
+        try {
+          const task = uni.request({
+            ...mergedConfig,
+            url: mergedConfig.baseURL + mergedConfig.url,
+            success: (response) => {
+              const res = response.data as HttpResponse
+              if (res.code === 200) {
+                resolve(res as T)
+              } else {
+                uni.showToast({
+                  title: res.message || '请求失败',
+                  icon: 'none'
+                })
+                reject(res)
+              }
+            },
+            fail: (error) => {
+              // 重试逻辑
+              if (retryCount < mergedConfig.retry!) {
+                setTimeout(() => {
+                  sendRequest(retryCount + 1)
+                }, mergedConfig.retryDelay)
+              } else {
+                uni.showToast({
+                  title: '网络错误,请重试',
+                  icon: 'none'
+                })
+                reject(error)
+              }
+            },
+            complete: () => {
+              this.pendingRequests.delete(requestKey)
+              if (mergedConfig.loading) {
+                uni.hideLoading()
+              }
+            }
+          }) as RequestTask
+
+          this.pendingRequests.set(requestKey, task)
+        } catch (error) {
+          reject(error)
+        }
+      }
+      sendRequest()
+    })
+  }
+
+  // 快捷方法
+  get<T = any>(url: string, config?: RequestConfig) {
+    return this.request<T>({ ...config, url, method: 'GET' })
+  }
+
+  post<T = any>(url: string, data?: any, config?: RequestConfig) {
+    return this.request<T>({ ...config, url, data, method: 'POST' })
+  }
+
+  delete<T = any>(url: string, data?: any, config?: RequestConfig) {
+    return this.request<T>({ ...config, url, data, method: 'DELETE' })
+  }
+
+  put<T = any>(url: string, data?: any, config?: RequestConfig) {
+    return this.request<T>({ ...config, url, data, method: 'PUT' })
+  }
 }
 
 // 创建实例
 export const http = new HttpClient({
-	baseURL: 'http://qhmall.natapp1.cc/app-api',
-	headers: {
-		'Content-Type': 'application/json'
-	}
+  baseURL: 'http://192.168.1.34:8080/jeecg-boot/app',
+  headers: {
+    'Content-Type': 'application/json'
+  }
 })
 
-// 添加请求拦截器 - 处理鉴权
-http.useRequestInterceptor({
-	fulfilled: (config) => {
-		// 跳过不需要认证的请求
-		if (config.skipAuth) return config
-		const tokenStorage = uni.getStorageSync('token')
-		// 检查 token 有效性并提取值
-		const tokenValue = HttpClient.checkTokenValidity(tokenStorage)
-		if (tokenValue) {
-			config.header = config.header || {}
-			config.header.Authorization = `Bearer ${tokenValue}`
-		} else {
-			console.log('[请求拦截器] 无有效Token')
-		}
-		return config
-	}
+// 使用UniApp原生请求拦截器
+uni.addInterceptor('request', {
+  invoke(args: UniApp.RequestOptions) {
+    // 跳过不需要认证的请求
+    if (args.skipAuth) return
+    const tokenStorage = uni.getStorageSync('TOKEN')
+    const tokenValue = HttpClient.checkTokenValidity(tokenStorage)
+    
+    if (tokenValue) {
+      args.header = args.header || {}
+      args.header['x-access-token'] = tokenValue
+    } else {
+      console.log('[请求拦截器] 无有效Token')
+    }
+  },
+  fail(err) {
+    console.error('请求拦截器失败:', err)
+  }
 })
 
-// 添加响应拦截器 - 错误处理
-http.useResponseInterceptor({
-	fulfilled: (response) => {
-		const resData = response.data as HttpResponse;
-		if (resData.code !== 0) {
-			return Promise.reject(response)
-		}
-		return response
-	},
-	rejected: (error) => {
-		console.log(error.data, 'err');
-		uni.showToast({
-			title: error.data.msg || '请求失败',
-			icon: 'none'
-		})
-		return Promise.reject(error)
-	}
+// 使用UniApp原生响应拦截器
+uni.addInterceptor('request', {
+  success: (res) => {
+    const data = res.data as HttpResponse
+    if (data.code !== 200) {
+      uni.showToast({
+        title: data.message || '请求失败',
+        icon: 'none'
+      })
+      // 返回自定义错误对象,触发fail回调
+      return {
+        ...res,
+        errMsg: `业务错误: ${data.message}`,
+        data: null
+      }
+    }
+    return res
+  },
+  fail: (err) => {
+    console.error('响应拦截器捕获错误:', err)
+    uni.showToast({
+      title: '网络错误,请重试',
+      icon: 'none'
+    })
+    return err
+  }
 })

+ 34 - 22
src/utils/util/index.ts

@@ -1,3 +1,14 @@
+import { http } from '@/utils/http'
+
+/**
+ * 数据字典请求
+ * 
+ */
+export const getDict =(type : string) => {
+	http.get('/common/getDictItems',{data:{dictCode:type}}).then(res=>{
+	})
+}
+
 /**
  * 提示工具类
 */
@@ -18,14 +29,14 @@ export class TipsUtils {
 	 * @param text - 提示内容
 	 * @param showCancel - 是否显示取消按钮
 	 */
-	static tips_alert(text : string,showCancel:boolean) {
-		return new Promise((resolve,reject)=>{
+	static tips_alert(text : string, showCancel : boolean) {
+		return new Promise((resolve, reject) => {
 			uni.showModal({
 				title: '提示',
 				content: text,
 				showCancel: showCancel,
 				confirmText: '确定',
-				confirmColor:'#9BB051',
+				confirmColor: '#9BB051',
 				success(res) {
 					resolve(res)
 				},
@@ -72,25 +83,26 @@ export class ValidateUtils {
 /**
  * 路由工具类
  */
- export class RouterUtils {
-	 /**
-	 * 返回上一页
-	 */
-	 static back() {
-		 uni.navigateBack();
-	 }
-	 
-	 /**
-	 * 跳转到指定页面
-	 * @param path - 页面路径
-	 */
-	 static to_page(path:string){
-		 uni.navigateTo({
-		 	url:path
-		 })
-	 }
- }
- 
+export class RouterUtils {
+	/**
+	* 返回上一页
+	*/
+	static back() {
+		uni.navigateBack();
+	}
+
+	/**
+	* 跳转到指定页面
+	* @param path - 页面路径
+	*/
+	static to_page(path : string) {
+		if (!uni.getStorageSync('TOKEN')) return TipsUtils.tips_alert('请先登录~', false)
+		uni.navigateTo({
+			url: path
+		})
+	}
+}
+
 /**
  * 日期时间格式化工具
  * @param date - 日期对象或时间戳

部分文件因文件數量過多而無法顯示