zhentao 3 napja
szülő
commit
a774423876
26 módosított fájl, 1200 hozzáadás és 238 törlés
  1. 6 0
      pages.json
  2. 290 0
      pages/home/index.vue
  3. 1 3
      pages/index/index.vue
  4. 242 35
      pages/login/login.vue
  5. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/app.js.map
  6. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/common/assets.js.map
  7. 0 0
      unpackage/dist/dev/.sourcemap/mp-weixin/common/vendor.js.map
  8. 0 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/agreement/agreement.js.map
  9. 0 0
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/home/index.js.map
  10. 0 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/index.js.map
  11. 0 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/login/login.js.map
  12. 0 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/privacy/privacy.js.map
  13. 1 0
      unpackage/dist/dev/mp-weixin/app.js
  14. 2 1
      unpackage/dist/dev/mp-weixin/app.json
  15. 22 6
      unpackage/dist/dev/mp-weixin/common/assets.js
  16. 167 102
      unpackage/dist/dev/mp-weixin/common/vendor.js
  17. 23 0
      unpackage/dist/dev/mp-weixin/pages/home/index.js
  18. 4 0
      unpackage/dist/dev/mp-weixin/pages/home/index.json
  19. 0 0
      unpackage/dist/dev/mp-weixin/pages/home/index.wxml
  20. 174 0
      unpackage/dist/dev/mp-weixin/pages/home/index.wxss
  21. 1 3
      unpackage/dist/dev/mp-weixin/pages/index/index.js
  22. 190 50
      unpackage/dist/dev/mp-weixin/pages/login/login.js
  23. 0 0
      unpackage/dist/dev/mp-weixin/pages/login/login.wxml
  24. 43 0
      unpackage/dist/dev/mp-weixin/pages/login/login.wxss
  25. 26 26
      unpackage/dist/dev/mp-weixin/project.config.json
  26. 6 6
      unpackage/dist/dev/mp-weixin/project.private.config.json

+ 6 - 0
pages.json

@@ -26,6 +26,12 @@
 			{
 				"navigationBarTitleText" : ""
 			}
+		},
+		{
+			"path": "pages/home/index",
+			"style": {
+				"navigationBarTitleText": "首页"
+			}
 		}
 	],
 	"globalStyle": {

+ 290 - 0
pages/home/index.vue

@@ -0,0 +1,290 @@
+<template>
+  <view class="home-container">
+    <!-- 顶部搜索栏 -->
+    <view class="home-header">
+      <input class="search-input" placeholder="平江阳光国际大酒店(平江天岳汽..." />
+      <button class="search-btn">搜索</button>
+    </view>
+    <!-- 横幅广告 -->
+    <view class="banner">
+      <image class="banner-img" src="/static/banner.png" mode="widthFix"></image>
+    </view>
+    <!-- 分类宫格 -->
+    <view class="category-grid">
+      <view class="category-row">
+        <view class="category-item hotel">
+          <text class="cat-title">酒店</text>
+          <text class="cat-desc">特价酒店</text>
+        </view>
+        <view class="category-item hostel">
+          <text class="cat-title">民宿·客栈</text>
+        </view>
+        <view class="category-item overseas">
+          <text class="cat-title">海外酒店</text>
+        </view>
+        <view class="category-item special">
+          <text class="cat-title">特价酒店</text>
+        </view>
+      </view>
+      <view class="category-row">
+        <view class="category-item flight">
+          <text class="cat-title">机票</text>
+          <text class="cat-desc">低价机票</text>
+        </view>
+        <view class="category-item train">
+          <text class="cat-title">火车·高铁</text>
+          <view class="cat-badge">减1元</view>
+        </view>
+        <view class="category-item bus">
+          <text class="cat-title">汽车·船票</text>
+        </view>
+        <view class="category-item car">
+          <text class="cat-title">专车·租车</text>
+        </view>
+      </view>
+      <view class="category-row">
+        <view class="category-item travel">
+          <text class="cat-title">旅游</text>
+          <text class="cat-desc">出境/国内游</text>
+        </view>
+        <view class="category-item scenic">
+          <text class="cat-title">景点·门票</text>
+        </view>
+        <view class="category-item group">
+          <text class="cat-title">跟团游</text>
+        </view>
+        <view class="category-item loan">
+          <text class="cat-title">借钱/分期</text>
+        </view>
+      </view>
+    </view>
+    <!-- 横向活动栏 -->
+    <scroll-view class="activity-bar" scroll-x>
+      <view class="activity-item">天天神券<br/><text>签到领券</text></view>
+      <view class="activity-item">低价酒店<br/><text>岳阳7折</text></view>
+      <view class="activity-item">1折机票<br/><text>200元起</text></view>
+      <view class="activity-item">酒店囤货<br/><text>3折抄底</text></view>
+      <view class="activity-item">暑期出境<br/><text>可省1500</text></view>
+    </scroll-view>
+    <!-- 视频推荐和地图 -->
+    <view class="main-content">
+      <view class="video-section">
+        <image class="video-img" src="/static/video.png" mode="aspectFill"></image>
+        <view class="video-title">望仙谷</view>
+      </view>
+      <view class="map-section">
+        <image class="map-img" src="/static/map.png" mode="aspectFill"></image>
+        <view class="map-title">全国自驾地图</view>
+      </view>
+    </view>
+    <!-- 悬浮按钮 -->
+    <view class="float-btn">+</view>
+    <!-- 底部tabBar -->
+    <view class="tab-bar">
+      <view class="tab-item active">
+        <image class="tab-icon" src="/static/tab-home.png" />
+        <text>首页</text>
+      </view>
+      <view class="tab-item">
+        <image class="tab-icon" src="/static/tab-trip.png" />
+        <text>行程</text>
+      </view>
+      <view class="tab-item">
+        <image class="tab-icon" src="/static/tab-service.png" />
+        <text>客服</text>
+      </view>
+      <view class="tab-item">
+        <image class="tab-icon" src="/static/tab-world.png" />
+        <text>看世界</text>
+      </view>
+      <view class="tab-item">
+        <image class="tab-icon" src="/static/tab-mine.png" />
+        <text>我的</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  }
+}
+</script>
+
+<style scoped>
+.home-container {
+  background: #f7f8fa;
+  min-height: 100vh;
+  padding-bottom: 120rpx;
+}
+.home-header {
+  display: flex;
+  align-items: center;
+  padding: 32rpx 24rpx 0 24rpx;
+}
+.search-input {
+  flex: 1;
+  height: 64rpx;
+  border-radius: 32rpx;
+  border: none;
+  background: #fff;
+  padding: 0 24rpx;
+  font-size: 28rpx;
+  box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04);
+}
+.search-btn {
+  margin-left: 16rpx;
+  background: #7ac81e;
+  color: #fff;
+  border: none;
+  border-radius: 32rpx;
+  height: 64rpx;
+  padding: 0 32rpx;
+  font-size: 28rpx;
+}
+.banner {
+  margin: 24rpx 24rpx 0 24rpx;
+}
+.banner-img {
+  width: 100%;
+  border-radius: 16rpx;
+}
+.category-grid {
+  margin: 32rpx 24rpx 0 24rpx;
+}
+.category-row {
+  display: flex;
+  margin-bottom: 16rpx;
+}
+.category-item {
+  flex: 1;
+  background: #fff;
+  border-radius: 16rpx;
+  margin-right: 16rpx;
+  padding: 24rpx 0 16rpx 0;
+  text-align: center;
+  position: relative;
+  box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04);
+}
+.category-item:last-child {
+  margin-right: 0;
+}
+.cat-title {
+  font-size: 28rpx;
+  font-weight: bold;
+  color: #333;
+}
+.cat-desc {
+  display: block;
+  font-size: 20rpx;
+  color: #7ac81e;
+  margin-top: 8rpx;
+}
+.cat-badge {
+  position: absolute;
+  top: 8rpx;
+  right: 16rpx;
+  background: #ffe600;
+  color: #333;
+  font-size: 18rpx;
+  border-radius: 8rpx;
+  padding: 2rpx 8rpx;
+}
+.activity-bar {
+  display: flex;
+  flex-direction: row;
+  margin: 24rpx 0 0 0;
+  padding-left: 24rpx;
+  background: #fff;
+  height: 80rpx;
+  align-items: center;
+  overflow-x: scroll;
+}
+.activity-item {
+  min-width: 140rpx;
+  margin-right: 32rpx;
+  font-size: 24rpx;
+  color: #ff6600;
+  text-align: center;
+}
+.activity-item text {
+  color: #888;
+  font-size: 20rpx;
+}
+.main-content {
+  display: flex;
+  margin: 32rpx 24rpx 0 24rpx;
+}
+.video-section, .map-section {
+  flex: 1;
+  margin-right: 16rpx;
+  background: #fff;
+  border-radius: 16rpx;
+  overflow: hidden;
+  position: relative;
+  box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04);
+}
+.map-section {
+  margin-right: 0;
+}
+.video-img, .map-img {
+  width: 100%;
+  height: 160rpx;
+  object-fit: cover;
+}
+.video-title, .map-title {
+  position: absolute;
+  left: 16rpx;
+  bottom: 16rpx;
+  color: #fff;
+  font-size: 28rpx;
+  text-shadow: 0 2rpx 8rpx rgba(0,0,0,0.2);
+}
+.float-btn {
+  position: fixed;
+  right: 40rpx;
+  bottom: 180rpx;
+  width: 80rpx;
+  height: 80rpx;
+  background: #00e4ff;
+  color: #fff;
+  font-size: 60rpx;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  box-shadow: 0 4rpx 16rpx rgba(0,228,255,0.15);
+  z-index: 10;
+}
+.tab-bar {
+  position: fixed;
+  left: 0;
+  bottom: 0;
+  width: 100vw;
+  height: 100rpx;
+  background: #fff;
+  display: flex;
+  border-top: 1rpx solid #eee;
+  z-index: 20;
+}
+.tab-item {
+  flex: 1;
+  text-align: center;
+  color: #888;
+  font-size: 22rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+.tab-item.active {
+  color: #00c3ff;
+}
+.tab-icon {
+  width: 40rpx;
+  height: 40rpx;
+  margin-bottom: 4rpx;
+}
+</style> 

+ 1 - 3
pages/index/index.vue

@@ -26,9 +26,7 @@
 		},
 		methods: {
 			goLogin() {
-				uni.navigateTo({
-					url: '/pages/login/login'
-				});
+				uni.navigateTo({ url: '/pages/login/login' });
 			}
 		}
 	}

+ 242 - 35
pages/login/login.vue

@@ -62,6 +62,30 @@
 			</view>
 		</view>
 	</view>
+
+	<!-- 忘记密码弹窗 -->
+	<view v-if="showForgotPopup" class="popup-overlay">
+		<view class="forgot-popup-content">
+			<view class="popup-title">找回密码</view>
+			<view class="forgot-form">
+				<input class="login-input" type="text" placeholder="请输入手机号" v-model="forgotPhone" />
+				<view class="code-row">
+					<input class="login-input code-input" type="text" placeholder="请输入验证码" v-model="forgotCode" />
+					<button class="code-btn" @click="sendForgotCode" :disabled="forgotCodeTimer > 0 || isSendingForgotCode">
+						{{ forgotCodeTimer > 0 ? forgotCodeTimer + 's' : '获取验证码' }}
+					</button>
+				</view>
+				<input class="login-input" type="password" password placeholder="请输入新密码" v-model="newPassword" />
+				<input class="login-input" type="password" password placeholder="请确认新密码" v-model="confirmPassword" />
+			</view>
+
+			<button class="login-btn" @click="doResetPassword">确认修改</button>
+
+			<view class="close-btn" @click="showForgotPopup = false">
+				<image src="/static/cw.png" class="icon"></image>
+			</view>
+		</view>
+	</view>
 </template>
 
 <script>
@@ -84,6 +108,13 @@
 				isSendingRegCode: false, // Flag to prevent multiple requests
 				loginCodeTimer: 0, // Countdown timer for login code
 				isSendingLoginCode: false, // Flag to prevent multiple requests
+				showForgotPopup: false,
+				forgotPhone: '',
+				forgotCode: '',
+				newPassword: '',
+				confirmPassword: '',
+				forgotCodeTimer: 0,
+				isSendingForgotCode: false,
 			}
 		},
 		methods: {
@@ -201,48 +232,74 @@
 					uni.showToast({ title: '请先同意协议', icon: 'none' });
 					return;
 				}
-				if (!this.phone || !this.code) {
-					uni.showToast({ title: '请填写手机号和验证码', icon: 'none' });
-					return;
-				}
-
-				uni.showLoading({ title: '登录中...', mask: true });
-
-				try {
-					const res = await uni.request({
-						url: 'http://localhost:3333/user/login',
-						method: 'POST',
-						data: {
-							phone: this.phone,
-							code: this.code
-						},
-						header: { 'content-type': 'application/json' }
-					});
 
-					uni.hideLoading();
-
-					if (res.statusCode === 200 && res.data) {
-						console.log('Login success:', res.data);
-						uni.showToast({ title: '登录成功', icon: 'success' });
-						// Navigate to home page on success
-						setTimeout(() => {
-							uni.switchTab({ url: '/pages/home/index' });
-						}, 1500); // Delay slightly to show toast
-					} else {
-						console.error('Login failed:', res.data);
-						uni.showToast({ title: res.data?.message || '登录失败', icon: 'error' });
+				if (this.loginType === 'phone') {
+					// 手机号+验证码登录
+					if (!this.phone || !this.code) {
+						uni.showToast({ title: '请填写手机号和验证码', icon: 'none' });
+						return;
+					}
+					uni.showLoading({ title: '登录中...', mask: true });
+					try {
+						const res = await uni.request({
+							url: 'http://localhost:3333/user/login',
+							method: 'POST',
+							data: {
+								phone: this.phone,
+								code: this.code
+							},
+							header: { 'content-type': 'application/json' }
+						});
+						uni.hideLoading();
+						if (res.statusCode === 200 && res.data) {
+							uni.showToast({ title: '登录成功', icon: 'success' });
+							setTimeout(() => {
+								uni.switchTab({ url: '/pages/home/index' });
+							}, 1500);
+						} else {
+							uni.showToast({ title: res.data?.message || '登录失败', icon: 'error' });
+						}
+					} catch (err) {
+						uni.hideLoading();
+						uni.showToast({ title: '登录失败', icon: 'none' });
+					}
+				} else if (this.loginType === 'account') {
+					// 账号+密码登录
+					if (!this.username || !this.password) {
+						uni.showToast({ title: '请填写账号和密码', icon: 'none' });
+						return;
+					}
+					uni.showLoading({ title: '登录中...', mask: true });
+					try {
+						const res = await uni.request({
+							url: 'http://localhost:3333/user/UserPassLogin',
+							method: 'POST',
+							data: {
+								username: this.username,
+								password: this.password
+							},
+							header: { 'content-type': 'application/json' }
+						});
+						uni.hideLoading();
+						if (res.statusCode === 200 && res.data && res.data.code === 200) {
+							uni.showToast({ title: '登录成功', icon: 'success' });
+							setTimeout(() => {
+								uni.switchTab({ url: '/pages/home/index' });
+							}, 1500);
+						} else {
+							uni.showToast({ title: res.data?.msg || '登录失败', icon: 'error' });
+						}
+					} catch (err) {
+						uni.hideLoading();
+						uni.showToast({ title: '登录失败', icon: 'none' });
 					}
-				} catch (err) {
-					uni.hideLoading();
-					console.error('Login request failed:', err);
-					uni.showToast({ title: '登录失败', icon: 'none' });
 				}
 			},
 			toRegister() {
 				this.showRegisterPopup = true;
 			},
 			toForgot() {
-				uni.showToast({ title: '跳转找回密码', icon: 'none' });
+				this.showForgotPopup = true;
 			},
 			openAgreement() {
 				uni.navigateTo({ url: '/pages/agreement/agreement' });
@@ -354,7 +411,108 @@
 					console.error('Registration request failed:', err);
 					uni.showToast({ title: '注册失败', icon: 'none' });
 				}
-			}
+			},
+			async sendForgotCode() {
+				if (this.isSendingForgotCode || this.forgotCodeTimer > 0) {
+					return;
+				}
+				if (!this.forgotPhone) {
+					uni.showToast({ title: '请输入手机号', icon: 'none' });
+					return;
+				}
+
+				this.isSendingForgotCode = true;
+				uni.showLoading({ title: '发送中...', mask: true });
+
+				try {
+					const res = await uni.request({
+						url: 'http://localhost:3333/user/code',
+						method: 'POST',
+						data: {
+							phone: this.forgotPhone
+						},
+						header: { 'content-type': 'application/json' }
+					});
+
+					uni.hideLoading();
+					this.isSendingForgotCode = false;
+
+					if (res.statusCode === 200 && res.data) {
+						console.log('Send forgot code success:', res.data);
+						uni.showToast({ title: '验证码已发送', icon: 'success' });
+
+						this.forgotCodeTimer = 60;
+						const timerInterval = setInterval(() => {
+							this.forgotCodeTimer--;
+							if (this.forgotCodeTimer <= 0) {
+								clearInterval(timerInterval);
+								this.forgotCodeTimer = 0;
+							}
+						}, 1000);
+					} else {
+						console.error('Send forgot code failed:', res);
+						uni.showToast({ title: res.data?.message || '发送失败', icon: 'none' });
+					}
+				} catch (err) {
+					uni.hideLoading();
+					this.isSendingForgotCode = false;
+					console.error('Send forgot code request failed:', err);
+					uni.showToast({ title: '发送失败', icon: 'none' });
+				}
+			},
+			async doResetPassword() {
+				if (!this.forgotPhone || !this.forgotCode || !this.newPassword || !this.confirmPassword) {
+					uni.showToast({ title: '请填写所有信息', icon: 'none' });
+					return;
+				}
+
+				if (this.newPassword !== this.confirmPassword) {
+					uni.showToast({ title: '两次密码输入不一致', icon: 'none' });
+					return;
+				}
+
+				uni.showLoading({ title: '修改中...', mask: true });
+
+				try {
+					const res = await uni.request({
+						url: 'http://localhost:3333/user/ForgetPass',
+						method: 'POST',
+						data: {
+							phone: this.forgotPhone,
+							code: this.forgotCode,
+							newPassword: this.newPassword
+						},
+						header: { 'content-type': 'application/json' }
+					});
+
+					uni.hideLoading();
+
+					if (res.statusCode === 200 && res.data) {
+						console.log('Reset password success:', res.data);
+						uni.showToast({ title: '密码修改成功', icon: 'success' });
+						
+						// 清空表单
+						this.forgotPhone = '';
+						this.forgotCode = '';
+						this.newPassword = '';
+						this.confirmPassword = '';
+						
+						// 关闭弹窗并返回登录界面
+						setTimeout(() => {
+							this.showForgotPopup = false;
+							// 切换到账号密码登录
+							this.loginType = 'account';
+						}, 1500);
+					} else {
+						console.error('Reset password failed:', res);
+						uni.showToast({ title: res.data?.message || '修改失败', icon: 'none' });
+					}
+				} catch (err) {
+					uni.hideLoading();
+					console.error('Reset password request failed:', err);
+					uni.showToast({ title: '修改失败', icon: 'none' });
+				}
+			},
 		}
 	}
 </script>
@@ -605,4 +763,53 @@
 		color: #7ac81e;
 		font-size: 26rpx;
 	}
+
+	.forgot-popup-content {
+		background-color: #fff;
+		border-radius: 24rpx;
+		width: 85vw;
+		max-width: 600rpx;
+		padding: 60rpx 40rpx;
+		position: relative;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+	}
+
+	.forgot-form {
+		width: 100%;
+		margin-bottom: 30rpx;
+	}
+
+	.forgot-form .login-input {
+		width: 90%;
+		height: 80rpx;
+		border: 1rpx solid #eee;
+		border-radius: 12rpx;
+		margin-bottom: 20rpx;
+		padding: 0 24rpx;
+		font-size: 28rpx;
+		background: #f7f8fa;
+	}
+
+	.forgot-form .code-row {
+		display: flex;
+		align-items: center;
+		margin-bottom: 20rpx;
+	}
+
+	.forgot-form .code-input {
+		flex: 1;
+		margin-right: 16rpx;
+		width: auto;
+	}
+
+	.forgot-form .code-btn {
+		height: 80rpx;
+		background: #7ac81e;
+		color: #fff;
+		border-radius: 12rpx;
+		padding: 0 24rpx;
+		font-size: 28rpx;
+	}
 </style>

+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/app.js.map

@@ -1 +1 @@
-{"version":3,"file":"app.js","sources":["App.vue"],"sourcesContent":["<script>\r\n\texport default {\r\n\t\tonLaunch: function() {\r\n\t\t\tconsole.log('App Launch')\r\n\t\t},\r\n\t\tonShow: function() {\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function() {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t/*每个页面公共css */\r\n</style>\n"],"names":["uni"],"mappings":";;;;;;;;;AACC,MAAK,YAAU;AAAA,EACd,UAAU,WAAW;AACpBA,kBAAAA,MAAA,MAAA,OAAA,gBAAY,YAAY;AAAA,EACxB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,gBAAA,UAAU;AAAA,EACtB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACvB;AACD;;;;;;;;;"}
+{"version":3,"file":"app.js","sources":["App.vue","main.js"],"sourcesContent":["<script>\r\n\texport default {\r\n\t\tonLaunch: function() {\r\n\t\t\tconsole.log('App Launch')\r\n\t\t},\r\n\t\tonShow: function() {\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function() {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t/*每个页面公共css */\r\n</style>\r\n","import App from './App'\r\n\r\n// #ifndef VUE3\r\nimport Vue from 'vue'\r\nimport './uni.promisify.adaptor'\r\nVue.config.productionTip = false\r\nApp.mpType = 'app'\r\nconst app = new Vue({\r\n  ...App\r\n})\r\napp.$mount()\r\n// #endif\r\n\r\n// #ifdef VUE3\r\nimport { createSSRApp } from 'vue'\r\nexport function createApp() {\r\n  const app = createSSRApp(App)\r\n  return {\r\n    app\r\n  }\r\n}\r\n// #endif"],"names":["uni","createSSRApp","App"],"mappings":";;;;;;;;;;AACC,MAAK,YAAU;AAAA,EACd,UAAU,WAAW;AACpBA,kBAAAA,MAAA,MAAA,OAAA,gBAAY,YAAY;AAAA,EACxB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,gBAAA,UAAU;AAAA,EACtB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACvB;AACD;ACIM,SAAS,YAAY;AAC1B,QAAM,MAAMC,cAAY,aAACC,SAAG;AAC5B,SAAO;AAAA,IACL;AAAA,EACD;AACH;;;"}

+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/common/assets.js.map

@@ -1 +1 @@
-{"version":3,"file":"assets.js","sources":["static/bg.png","static/wechat.png","static/cw.png"],"sourcesContent":["export default \"__VITE_ASSET__8a6e5bcd__\"","export default \"__VITE_ASSET__48cf9c4d__\"","export default \"__VITE_ASSET__123e9b1a__\""],"names":[],"mappings":";AAAA,MAAe,eAAA;ACAf,MAAe,aAAA;ACAf,MAAe,aAAA;;;;"}
+{"version":3,"file":"assets.js","sources":["static/bg.png","static/wechat.png","static/cw.png","D:/static/banner.png","D:/static/video.png","D:/static/map.png","D:/static/tab-home.png","D:/static/tab-trip.png","D:/static/tab-service.png","D:/static/tab-world.png","D:/static/tab-mine.png"],"sourcesContent":["export default \"__VITE_ASSET__8a6e5bcd__\"","export default \"__VITE_ASSET__48cf9c4d__\"","export default \"__VITE_ASSET__123e9b1a__\"","export default \"/static/banner.png\"","export default \"/static/video.png\"","export default \"/static/map.png\"","export default \"/static/tab-home.png\"","export default \"/static/tab-trip.png\"","export default \"/static/tab-service.png\"","export default \"/static/tab-world.png\"","export default \"/static/tab-mine.png\""],"names":[],"mappings":";AAAA,MAAe,eAAA;ACAf,MAAe,eAAA;ACAf,MAAe,eAAA;ACAf,MAAe,aAAA;ACAf,MAAe,aAAA;ACAf,MAAe,aAAA;ACAf,MAAe,aAAA;ACAf,MAAe,aAAA;ACAf,MAAe,aAAA;ACAf,MAAe,aAAA;ACAf,MAAe,aAAA;;;;;;;;;;;;"}

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
unpackage/dist/dev/.sourcemap/mp-weixin/common/vendor.js.map


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/agreement/agreement.js.map


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
unpackage/dist/dev/.sourcemap/mp-weixin/pages/home/index.js.map


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/index.js.map


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/login/login.js.map


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/privacy/privacy.js.map


+ 1 - 0
unpackage/dist/dev/mp-weixin/app.js

@@ -6,6 +6,7 @@ if (!Math) {
   "./pages/login/login.js";
   "./pages/agreement/agreement.js";
   "./pages/privacy/privacy.js";
+  "./pages/home/index.js";
 }
 const _sfc_main = {
   onLaunch: function() {

+ 2 - 1
unpackage/dist/dev/mp-weixin/app.json

@@ -3,7 +3,8 @@
     "pages/index/index",
     "pages/login/login",
     "pages/agreement/agreement",
-    "pages/privacy/privacy"
+    "pages/privacy/privacy",
+    "pages/home/index"
   ],
   "window": {
     "navigationBarTextStyle": "black",

+ 22 - 6
unpackage/dist/dev/mp-weixin/common/assets.js

@@ -1,8 +1,24 @@
 "use strict";
-const _imports_0$1 = "/static/bg.png";
-const _imports_0 = "/static/wechat.png";
-const _imports_1 = "/static/cw.png";
-exports._imports_0 = _imports_0$1;
-exports._imports_0$1 = _imports_0;
-exports._imports_1 = _imports_1;
+const _imports_0$2 = "/static/bg.png";
+const _imports_0$1 = "/static/wechat.png";
+const _imports_1$1 = "/static/cw.png";
+const _imports_0 = "/static/banner.png";
+const _imports_1 = "/static/video.png";
+const _imports_2 = "/static/map.png";
+const _imports_3 = "/static/tab-home.png";
+const _imports_4 = "/static/tab-trip.png";
+const _imports_5 = "/static/tab-service.png";
+const _imports_6 = "/static/tab-world.png";
+const _imports_7 = "/static/tab-mine.png";
+exports._imports_0 = _imports_0$2;
+exports._imports_0$1 = _imports_0$1;
+exports._imports_0$2 = _imports_0;
+exports._imports_1 = _imports_1$1;
+exports._imports_1$1 = _imports_1;
+exports._imports_2 = _imports_2;
+exports._imports_3 = _imports_3;
+exports._imports_4 = _imports_4;
+exports._imports_5 = _imports_5;
+exports._imports_6 = _imports_6;
+exports._imports_7 = _imports_7;
 //# sourceMappingURL=../../.sourcemap/mp-weixin/common/assets.js.map

+ 167 - 102
unpackage/dist/dev/mp-weixin/common/vendor.js

@@ -5086,9 +5086,10 @@ function createApp$1(rootComponent, rootProps = null) {
 }
 const createSSRApp = createApp$1;
 function getLocaleLanguage$1() {
+  var _a;
   let localeLanguage = "";
   {
-    const appBaseInfo = wx.getAppBaseInfo();
+    const appBaseInfo = ((_a = wx.getAppBaseInfo) === null || _a === void 0 ? void 0 : _a.call(wx)) || wx.getSystemInfoSync();
     const language = appBaseInfo && appBaseInfo.language ? appBaseInfo.language : LOCALE_EN;
     localeLanguage = normalizeLocale(language) || LOCALE_EN;
   }
@@ -5499,9 +5500,15 @@ let isIOS = false;
 let deviceWidth = 0;
 let deviceDPR = 0;
 function checkDeviceWidth() {
-  const { windowWidth, pixelRatio, platform } = Object.assign({}, wx.getWindowInfo(), {
-    platform: wx.getDeviceInfo().platform
-  });
+  var _a, _b;
+  let windowWidth, pixelRatio, platform;
+  {
+    const windowInfo = ((_a = wx.getWindowInfo) === null || _a === void 0 ? void 0 : _a.call(wx)) || wx.getSystemInfoSync();
+    const deviceInfo = ((_b = wx.getDeviceInfo) === null || _b === void 0 ? void 0 : _b.call(wx)) || wx.getSystemInfoSync();
+    windowWidth = windowInfo.windowWidth;
+    pixelRatio = windowInfo.pixelRatio;
+    platform = deviceInfo.platform;
+  }
   deviceWidth = windowWidth;
   deviceDPR = pixelRatio;
   isIOS = platform === "ios";
@@ -5956,11 +5963,29 @@ function getOSInfo(system, platform) {
     osName = platform;
     osVersion = system;
   } else {
-    osName = system.split(" ")[0] || "";
+    osName = system.split(" ")[0] || platform;
     osVersion = system.split(" ")[1] || "";
   }
+  osName = osName.toLocaleLowerCase();
+  switch (osName) {
+    case "harmony":
+    case "ohos":
+    case "openharmony":
+      osName = "harmonyos";
+      break;
+    case "iphone os":
+      osName = "ios";
+      break;
+    case "mac":
+    case "darwin":
+      osName = "macos";
+      break;
+    case "windows_nt":
+      osName = "windows";
+      break;
+  }
   return {
-    osName: osName.toLocaleLowerCase(),
+    osName,
     osVersion
   };
 }
@@ -5981,9 +6006,9 @@ function populateParameters(fromRes, toRes) {
     appVersion: "1.0.0",
     appVersionCode: "100",
     appLanguage: getAppLanguage(hostLanguage),
-    uniCompileVersion: "4.57",
-    uniCompilerVersion: "4.57",
-    uniRuntimeVersion: "4.57",
+    uniCompileVersion: "4.64",
+    uniCompilerVersion: "4.64",
+    uniRuntimeVersion: "4.64",
     uniPlatform: "mp-weixin",
     deviceBrand,
     deviceModel: model,
@@ -6132,9 +6157,9 @@ const getAppBaseInfo = {
       appLanguage: getAppLanguage(hostLanguage),
       isUniAppX: false,
       uniPlatform: "mp-weixin",
-      uniCompileVersion: "4.57",
-      uniCompilerVersion: "4.57",
-      uniRuntimeVersion: "4.57"
+      uniCompileVersion: "4.64",
+      uniCompilerVersion: "4.64",
+      uniRuntimeVersion: "4.64"
     };
     extend(toRes, parameters);
   }
@@ -6415,6 +6440,91 @@ function tryConnectSocket(host2, port, id) {
     });
   });
 }
+const CONSOLE_TYPES = ["log", "warn", "error", "info", "debug"];
+const originalConsole = /* @__PURE__ */ CONSOLE_TYPES.reduce((methods, type) => {
+  methods[type] = console[type].bind(console);
+  return methods;
+}, {});
+let sendError = null;
+const errorQueue = /* @__PURE__ */ new Set();
+const errorExtra = {};
+function sendErrorMessages(errors) {
+  if (sendError == null) {
+    errors.forEach((error) => {
+      errorQueue.add(error);
+    });
+    return;
+  }
+  const data = errors.map((err) => {
+    if (typeof err === "string") {
+      return err;
+    }
+    const isPromiseRejection = err && "promise" in err && "reason" in err;
+    const prefix = isPromiseRejection ? "UnhandledPromiseRejection: " : "";
+    if (isPromiseRejection) {
+      err = err.reason;
+    }
+    if (err instanceof Error && err.stack) {
+      if (err.message && !err.stack.includes(err.message)) {
+        return `${prefix}${err.message}
+${err.stack}`;
+      }
+      return `${prefix}${err.stack}`;
+    }
+    if (typeof err === "object" && err !== null) {
+      try {
+        return prefix + JSON.stringify(err);
+      } catch (err2) {
+        return prefix + String(err2);
+      }
+    }
+    return prefix + String(err);
+  }).filter(Boolean);
+  if (data.length > 0) {
+    sendError(JSON.stringify(Object.assign({
+      type: "error",
+      data
+    }, errorExtra)));
+  }
+}
+function setSendError(value, extra = {}) {
+  sendError = value;
+  Object.assign(errorExtra, extra);
+  if (value != null && errorQueue.size > 0) {
+    const errors = Array.from(errorQueue);
+    errorQueue.clear();
+    sendErrorMessages(errors);
+  }
+}
+function initOnError() {
+  function onError2(error) {
+    try {
+      if (typeof PromiseRejectionEvent !== "undefined" && error instanceof PromiseRejectionEvent && error.reason instanceof Error && error.reason.message && error.reason.message.includes(`Cannot create property 'errMsg' on string 'taskId`)) {
+        return;
+      }
+      if (true) {
+        originalConsole.error(error);
+      }
+      sendErrorMessages([error]);
+    } catch (err) {
+      originalConsole.error(err);
+    }
+  }
+  if (typeof index.onError === "function") {
+    index.onError(onError2);
+  }
+  if (typeof index.onUnhandledRejection === "function") {
+    index.onUnhandledRejection(onError2);
+  }
+  return function offError2() {
+    if (typeof index.offError === "function") {
+      index.offError(onError2);
+    }
+    if (typeof index.offUnhandledRejection === "function") {
+      index.offUnhandledRejection(onError2);
+    }
+  };
+}
 function formatMessage(type, args) {
   try {
     return {
@@ -6447,7 +6557,16 @@ function formatArg(arg, depth = 0) {
     case "boolean":
       return formatBoolean(arg);
     case "object":
-      return formatObject(arg, depth);
+      try {
+        return formatObject(arg, depth);
+      } catch (e2) {
+        return {
+          type: "object",
+          value: {
+            properties: []
+          }
+        };
+      }
     case "undefined":
       return formatUndefined();
     case "function":
@@ -6593,14 +6712,21 @@ function formatObject(value, depth) {
       }
     }
   }
+  let entries = Object.entries(value);
+  if (isHarmonyBuilderParams(value)) {
+    entries = entries.filter(([key]) => key !== "modifier" && key !== "nodeContent");
+  }
   return {
     type: "object",
     className,
     value: {
-      properties: Object.entries(value).map((entry) => formatObjectProperty(entry[0], entry[1], depth + 1))
+      properties: entries.map((entry) => formatObjectProperty(entry[0], entry[1], depth + 1))
     }
   };
 }
+function isHarmonyBuilderParams(value) {
+  return value.modifier && value.modifier._attribute && value.nodeContent;
+}
 function isComponentPublicInstance(value) {
   return value.$ && isComponentInternalInstance(value.$);
 }
@@ -6678,10 +6804,11 @@ function formatMapEntry(value, depth) {
     value: formatArg(value[1], depth)
   };
 }
-const CONSOLE_TYPES = ["log", "warn", "error", "info", "debug"];
 let sendConsole = null;
 const messageQueue = [];
 const messageExtra = {};
+const EXCEPTION_BEGIN_MARK = "---BEGIN:EXCEPTION---";
+const EXCEPTION_END_MARK = "---END:EXCEPTION---";
 function sendConsoleMessages(messages) {
   if (sendConsole == null) {
     messageQueue.push(...messages);
@@ -6701,10 +6828,6 @@ function setSendConsole(value, extra = {}) {
     sendConsoleMessages(messages);
   }
 }
-const originalConsole = /* @__PURE__ */ CONSOLE_TYPES.reduce((methods, type) => {
-  methods[type] = console[type].bind(console);
-  return methods;
-}, {});
 const atFileRegex = /^\s*at\s+[\w/./-]+:\d+$/;
 function rewriteConsole() {
   function wrapConsole(type) {
@@ -6719,6 +6842,18 @@ function rewriteConsole() {
       {
         originalConsole[type](...originalArgs);
       }
+      if (type === "error" && args.length === 1) {
+        const arg = args[0];
+        if (typeof arg === "string" && arg.startsWith(EXCEPTION_BEGIN_MARK)) {
+          const startIndex = EXCEPTION_BEGIN_MARK.length;
+          const endIndex = arg.length - EXCEPTION_END_MARK.length;
+          sendErrorMessages([arg.slice(startIndex, endIndex)]);
+          return;
+        } else if (arg instanceof Error) {
+          sendErrorMessages([arg]);
+          return;
+        }
+      }
       sendConsoleMessages([formatMessage(type, args)]);
     };
   }
@@ -6763,87 +6898,10 @@ function isConsoleWritable() {
   console.log = value;
   return isWritable;
 }
-let sendError = null;
-const errorQueue = /* @__PURE__ */ new Set();
-const errorExtra = {};
-function sendErrorMessages(errors) {
-  if (sendError == null) {
-    errors.forEach((error) => {
-      errorQueue.add(error);
-    });
-    return;
-  }
-  const data = errors.map((err) => {
-    const isPromiseRejection = err && "promise" in err && "reason" in err;
-    const prefix = isPromiseRejection ? "UnhandledPromiseRejection: " : "";
-    if (isPromiseRejection) {
-      err = err.reason;
-    }
-    if (err instanceof Error && err.stack) {
-      if (err.message && !err.stack.includes(err.message)) {
-        return `${prefix}${err.message}
-${err.stack}`;
-      }
-      return `${prefix}${err.stack}`;
-    }
-    if (typeof err === "object" && err !== null) {
-      try {
-        return prefix + JSON.stringify(err);
-      } catch (err2) {
-        return prefix + String(err2);
-      }
-    }
-    return prefix + String(err);
-  }).filter(Boolean);
-  if (data.length > 0) {
-    sendError(JSON.stringify(Object.assign({
-      type: "error",
-      data
-    }, errorExtra)));
-  }
-}
-function setSendError(value, extra = {}) {
-  sendError = value;
-  Object.assign(errorExtra, extra);
-  if (value != null && errorQueue.size > 0) {
-    const errors = Array.from(errorQueue);
-    errorQueue.clear();
-    sendErrorMessages(errors);
-  }
-}
-function initOnError() {
-  function onError2(error) {
-    try {
-      if (typeof PromiseRejectionEvent !== "undefined" && error instanceof PromiseRejectionEvent && error.reason instanceof Error && error.reason.message && error.reason.message.includes(`Cannot create property 'errMsg' on string 'taskId`)) {
-        return;
-      }
-      if (true) {
-        originalConsole.error(error);
-      }
-      sendErrorMessages([error]);
-    } catch (err) {
-      originalConsole.error(err);
-    }
-  }
-  if (typeof index.onError === "function") {
-    index.onError(onError2);
-  }
-  if (typeof index.onUnhandledRejection === "function") {
-    index.onUnhandledRejection(onError2);
-  }
-  return function offError2() {
-    if (typeof index.offError === "function") {
-      index.offError(onError2);
-    }
-    if (typeof index.offUnhandledRejection === "function") {
-      index.offUnhandledRejection(onError2);
-    }
-  };
-}
 function initRuntimeSocketService() {
-  const hosts = "192.168.190.1,192.168.192.1,127.0.0.1";
+  const hosts = "192.168.137.1,192.168.254.1,192.168.108.1,192.168.157.240,127.0.0.1";
   const port = "8090";
-  const id = "mp-weixin__TVxDl";
+  const id = "mp-weixin_ZyPX_N";
   const lazy = typeof swan !== "undefined";
   let restoreError = lazy ? () => {
   } : initOnError();
@@ -6859,13 +6917,19 @@ function initRuntimeSocketService() {
         restoreError();
         restoreConsole();
         originalConsole.error(wrapError("开发模式下日志通道建立 socket 连接失败。"));
-        originalConsole.error(wrapError("如果是小程序平台,请勾选不校验合法域名配置。"));
+        {
+          originalConsole.error(wrapError("小程序平台,请勾选不校验合法域名配置。"));
+        }
         originalConsole.error(wrapError("如果是运行到真机,请确认手机与电脑处于同一网络。"));
         return false;
       }
-      initMiniProgramGlobalFlag();
+      {
+        initMiniProgramGlobalFlag();
+      }
       socket.onClose(() => {
-        originalConsole.error(wrapError("开发模式下日志通道 socket 连接关闭,请在 HBuilderX 中重新运行。"));
+        {
+          originalConsole.error(wrapError("开发模式下日志通道 socket 连接关闭,请在 HBuilderX 中重新运行。"));
+        }
         restoreError();
         restoreConsole();
       });
@@ -7006,9 +7070,10 @@ function findVmByVueId(instance, vuePid) {
   }
 }
 function getLocaleLanguage() {
+  var _a;
   let localeLanguage = "";
   {
-    const appBaseInfo = wx.getAppBaseInfo();
+    const appBaseInfo = ((_a = wx.getAppBaseInfo) === null || _a === void 0 ? void 0 : _a.call(wx)) || wx.getSystemInfoSync();
     const language = appBaseInfo && appBaseInfo.language ? appBaseInfo.language : LOCALE_EN;
     localeLanguage = normalizeLocale(language) || LOCALE_EN;
   }

+ 23 - 0
unpackage/dist/dev/mp-weixin/pages/home/index.js

@@ -0,0 +1,23 @@
+"use strict";
+const common_assets = require("../../common/assets.js");
+const common_vendor = require("../../common/vendor.js");
+const _sfc_main = {
+  data() {
+    return {};
+  }
+};
+function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
+  return {
+    a: common_assets._imports_0$2,
+    b: common_assets._imports_1$1,
+    c: common_assets._imports_2,
+    d: common_assets._imports_3,
+    e: common_assets._imports_4,
+    f: common_assets._imports_5,
+    g: common_assets._imports_6,
+    h: common_assets._imports_7
+  };
+}
+const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-4978fed5"]]);
+wx.createPage(MiniProgramPage);
+//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/home/index.js.map

+ 4 - 0
unpackage/dist/dev/mp-weixin/pages/home/index.json

@@ -0,0 +1,4 @@
+{
+  "navigationBarTitleText": "首页",
+  "usingComponents": {}
+}

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
unpackage/dist/dev/mp-weixin/pages/home/index.wxml


+ 174 - 0
unpackage/dist/dev/mp-weixin/pages/home/index.wxss

@@ -0,0 +1,174 @@
+
+.home-container.data-v-4978fed5 {
+  background: #f7f8fa;
+  min-height: 100vh;
+  padding-bottom: 120rpx;
+}
+.home-header.data-v-4978fed5 {
+  display: flex;
+  align-items: center;
+  padding: 32rpx 24rpx 0 24rpx;
+}
+.search-input.data-v-4978fed5 {
+  flex: 1;
+  height: 64rpx;
+  border-radius: 32rpx;
+  border: none;
+  background: #fff;
+  padding: 0 24rpx;
+  font-size: 28rpx;
+  box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04);
+}
+.search-btn.data-v-4978fed5 {
+  margin-left: 16rpx;
+  background: #7ac81e;
+  color: #fff;
+  border: none;
+  border-radius: 32rpx;
+  height: 64rpx;
+  padding: 0 32rpx;
+  font-size: 28rpx;
+}
+.banner.data-v-4978fed5 {
+  margin: 24rpx 24rpx 0 24rpx;
+}
+.banner-img.data-v-4978fed5 {
+  width: 100%;
+  border-radius: 16rpx;
+}
+.category-grid.data-v-4978fed5 {
+  margin: 32rpx 24rpx 0 24rpx;
+}
+.category-row.data-v-4978fed5 {
+  display: flex;
+  margin-bottom: 16rpx;
+}
+.category-item.data-v-4978fed5 {
+  flex: 1;
+  background: #fff;
+  border-radius: 16rpx;
+  margin-right: 16rpx;
+  padding: 24rpx 0 16rpx 0;
+  text-align: center;
+  position: relative;
+  box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04);
+}
+.category-item.data-v-4978fed5:last-child {
+  margin-right: 0;
+}
+.cat-title.data-v-4978fed5 {
+  font-size: 28rpx;
+  font-weight: bold;
+  color: #333;
+}
+.cat-desc.data-v-4978fed5 {
+  display: block;
+  font-size: 20rpx;
+  color: #7ac81e;
+  margin-top: 8rpx;
+}
+.cat-badge.data-v-4978fed5 {
+  position: absolute;
+  top: 8rpx;
+  right: 16rpx;
+  background: #ffe600;
+  color: #333;
+  font-size: 18rpx;
+  border-radius: 8rpx;
+  padding: 2rpx 8rpx;
+}
+.activity-bar.data-v-4978fed5 {
+  display: flex;
+  flex-direction: row;
+  margin: 24rpx 0 0 0;
+  padding-left: 24rpx;
+  background: #fff;
+  height: 80rpx;
+  align-items: center;
+  overflow-x: scroll;
+}
+.activity-item.data-v-4978fed5 {
+  min-width: 140rpx;
+  margin-right: 32rpx;
+  font-size: 24rpx;
+  color: #ff6600;
+  text-align: center;
+}
+.activity-item text.data-v-4978fed5 {
+  color: #888;
+  font-size: 20rpx;
+}
+.main-content.data-v-4978fed5 {
+  display: flex;
+  margin: 32rpx 24rpx 0 24rpx;
+}
+.video-section.data-v-4978fed5, .map-section.data-v-4978fed5 {
+  flex: 1;
+  margin-right: 16rpx;
+  background: #fff;
+  border-radius: 16rpx;
+  overflow: hidden;
+  position: relative;
+  box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04);
+}
+.map-section.data-v-4978fed5 {
+  margin-right: 0;
+}
+.video-img.data-v-4978fed5, .map-img.data-v-4978fed5 {
+  width: 100%;
+  height: 160rpx;
+  object-fit: cover;
+}
+.video-title.data-v-4978fed5, .map-title.data-v-4978fed5 {
+  position: absolute;
+  left: 16rpx;
+  bottom: 16rpx;
+  color: #fff;
+  font-size: 28rpx;
+  text-shadow: 0 2rpx 8rpx rgba(0,0,0,0.2);
+}
+.float-btn.data-v-4978fed5 {
+  position: fixed;
+  right: 40rpx;
+  bottom: 180rpx;
+  width: 80rpx;
+  height: 80rpx;
+  background: #00e4ff;
+  color: #fff;
+  font-size: 60rpx;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  box-shadow: 0 4rpx 16rpx rgba(0,228,255,0.15);
+  z-index: 10;
+}
+.tab-bar.data-v-4978fed5 {
+  position: fixed;
+  left: 0;
+  bottom: 0;
+  width: 100vw;
+  height: 100rpx;
+  background: #fff;
+  display: flex;
+  border-top: 1rpx solid #eee;
+  z-index: 20;
+}
+.tab-item.data-v-4978fed5 {
+  flex: 1;
+  text-align: center;
+  color: #888;
+  font-size: 22rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+.tab-item.active.data-v-4978fed5 {
+  color: #00c3ff;
+}
+.tab-icon.data-v-4978fed5 {
+  width: 40rpx;
+  height: 40rpx;
+  margin-bottom: 4rpx;
+}

+ 1 - 3
unpackage/dist/dev/mp-weixin/pages/index/index.js

@@ -11,9 +11,7 @@ const _sfc_main = {
   },
   methods: {
     goLogin() {
-      common_vendor.index.navigateTo({
-        url: "/pages/login/login"
-      });
+      common_vendor.index.navigateTo({ url: "/pages/login/login" });
     }
   }
 };

+ 190 - 50
unpackage/dist/dev/mp-weixin/pages/login/login.js

@@ -22,25 +22,32 @@ const _sfc_main = {
       // Flag to prevent multiple requests
       loginCodeTimer: 0,
       // Countdown timer for login code
-      isSendingLoginCode: false
+      isSendingLoginCode: false,
       // Flag to prevent multiple requests
+      showForgotPopup: false,
+      forgotPhone: "",
+      forgotCode: "",
+      newPassword: "",
+      confirmPassword: "",
+      forgotCodeTimer: 0,
+      isSendingForgotCode: false
     };
   },
   methods: {
     // 处理微信登录
     async oneClickLogin() {
-      common_vendor.index.__f__("log", "at pages/login/login.vue:92", "WeChat login button clicked");
+      common_vendor.index.__f__("log", "at pages/login/login.vue:123", "WeChat login button clicked");
       common_vendor.index.getUserProfile({
         desc: "用于完善用户资料",
         lang: "zh_CN",
         success: (userRes) => {
-          common_vendor.index.__f__("log", "at pages/login/login.vue:98", userRes);
+          common_vendor.index.__f__("log", "at pages/login/login.vue:129", userRes);
           common_vendor.index.showLoading({ title: "登录中...", mask: true });
           common_vendor.index.login({
             provider: "weixin",
             success: (wx_res) => {
-              common_vendor.index.__f__("log", "at pages/login/login.vue:105", "uni.getUserProfile success:", userRes);
-              common_vendor.index.__f__("log", "at pages/login/login.vue:106", "uni.login success, got code:", wx_res.code);
+              common_vendor.index.__f__("log", "at pages/login/login.vue:136", "uni.getUserProfile success:", userRes);
+              common_vendor.index.__f__("log", "at pages/login/login.vue:137", "uni.login success, got code:", wx_res.code);
               common_vendor.index.request({
                 url: "http://localhost:3333/WeChart/login",
                 method: "POST",
@@ -53,32 +60,32 @@ const _sfc_main = {
                   var _a;
                   common_vendor.index.hideLoading();
                   if (res.statusCode === 200 && res.data) {
-                    common_vendor.index.__f__("log", "at pages/login/login.vue:119", "Backend login success:", res.data);
+                    common_vendor.index.__f__("log", "at pages/login/login.vue:150", "Backend login success:", res.data);
                     common_vendor.index.showToast({ title: "登录成功", icon: "success" });
                     setTimeout(() => {
                       common_vendor.index.switchTab({ url: "/pages/home/index" });
                     }, 1500);
                   } else {
-                    common_vendor.index.__f__("error", "at pages/login/login.vue:125", "Backend login failed:", res);
+                    common_vendor.index.__f__("error", "at pages/login/login.vue:156", "Backend login failed:", res);
                     common_vendor.index.showToast({ title: ((_a = res.data) == null ? void 0 : _a.message) || "登录失败", icon: "none" });
                   }
                 },
                 fail: (err) => {
                   common_vendor.index.hideLoading();
-                  common_vendor.index.__f__("error", "at pages/login/login.vue:131", "Backend request failed:", err);
+                  common_vendor.index.__f__("error", "at pages/login/login.vue:162", "Backend request failed:", err);
                   common_vendor.index.showToast({ title: "微信登录失败", icon: "none" });
                 }
               });
             },
             fail: (err) => {
               common_vendor.index.hideLoading();
-              common_vendor.index.__f__("error", "at pages/login/login.vue:138", "uni.login failed:", err);
+              common_vendor.index.__f__("error", "at pages/login/login.vue:169", "uni.login failed:", err);
               common_vendor.index.showToast({ title: "微信登录失败", icon: "none" });
             }
           });
         },
         fail: (err) => {
-          common_vendor.index.__f__("error", "at pages/login/login.vue:144", "uni.getUserProfile failed:", err);
+          common_vendor.index.__f__("error", "at pages/login/login.vue:175", "uni.getUserProfile failed:", err);
           common_vendor.index.showToast({ title: "获取用户信息失败", icon: "none" });
         }
       });
@@ -106,7 +113,7 @@ const _sfc_main = {
         common_vendor.index.hideLoading();
         this.isSendingLoginCode = false;
         if (res.statusCode === 200 && res.data) {
-          common_vendor.index.__f__("log", "at pages/login/login.vue:175", "Send login code success:", res.data);
+          common_vendor.index.__f__("log", "at pages/login/login.vue:206", "Send login code success:", res.data);
           common_vendor.index.showToast({ title: "验证码已发送", icon: "success" });
           this.loginCodeTimer = 60;
           const timerInterval = setInterval(() => {
@@ -117,59 +124,87 @@ const _sfc_main = {
             }
           }, 1e3);
         } else {
-          common_vendor.index.__f__("error", "at pages/login/login.vue:189", "Send login code failed:", res);
+          common_vendor.index.__f__("error", "at pages/login/login.vue:220", "Send login code failed:", res);
           common_vendor.index.showToast({ title: ((_a = res.data) == null ? void 0 : _a.message) || "发送失败", icon: "none" });
         }
       } catch (err) {
         common_vendor.index.hideLoading();
         this.isSendingLoginCode = false;
-        common_vendor.index.__f__("error", "at pages/login/login.vue:195", "Send login code request failed:", err);
+        common_vendor.index.__f__("error", "at pages/login/login.vue:226", "Send login code request failed:", err);
         common_vendor.index.showToast({ title: "发送失败", icon: "none" });
       }
     },
     async doLogin() {
-      var _a;
+      var _a, _b;
       if (!this.agreed) {
         common_vendor.index.showToast({ title: "请先同意协议", icon: "none" });
         return;
       }
-      if (!this.phone || !this.code) {
-        common_vendor.index.showToast({ title: "请填写手机号和验证码", icon: "none" });
-        return;
-      }
-      common_vendor.index.showLoading({ title: "登录中...", mask: true });
-      try {
-        const res = await common_vendor.index.request({
-          url: "http://localhost:3333/user/login",
-          method: "POST",
-          data: {
-            phone: this.phone,
-            code: this.code
-          },
-          header: { "content-type": "application/json" }
-        });
-        common_vendor.index.hideLoading();
-        if (res.statusCode === 200 && res.data) {
-          common_vendor.index.__f__("log", "at pages/login/login.vue:225", "Login success:", res.data);
-          common_vendor.index.showToast({ title: "登录成功", icon: "success" });
-          setTimeout(() => {
-            common_vendor.index.switchTab({ url: "/pages/home/index" });
-          }, 1500);
-        } else {
-          common_vendor.index.__f__("error", "at pages/login/login.vue:232", "Login failed:", res.data);
-          common_vendor.index.showToast({ title: ((_a = res.data) == null ? void 0 : _a.message) || "登录失败", icon: "error" });
+      if (this.loginType === "phone") {
+        if (!this.phone || !this.code) {
+          common_vendor.index.showToast({ title: "请填写手机号和验证码", icon: "none" });
+          return;
+        }
+        common_vendor.index.showLoading({ title: "登录中...", mask: true });
+        try {
+          const res = await common_vendor.index.request({
+            url: "http://localhost:3333/user/login",
+            method: "POST",
+            data: {
+              phone: this.phone,
+              code: this.code
+            },
+            header: { "content-type": "application/json" }
+          });
+          common_vendor.index.hideLoading();
+          if (res.statusCode === 200 && res.data) {
+            common_vendor.index.showToast({ title: "登录成功", icon: "success" });
+            setTimeout(() => {
+              common_vendor.index.switchTab({ url: "/pages/home/index" });
+            }, 1500);
+          } else {
+            common_vendor.index.showToast({ title: ((_a = res.data) == null ? void 0 : _a.message) || "登录失败", icon: "error" });
+          }
+        } catch (err) {
+          common_vendor.index.hideLoading();
+          common_vendor.index.showToast({ title: "登录失败", icon: "none" });
+        }
+      } else if (this.loginType === "account") {
+        if (!this.username || !this.password) {
+          common_vendor.index.showToast({ title: "请填写账号和密码", icon: "none" });
+          return;
+        }
+        common_vendor.index.showLoading({ title: "登录中...", mask: true });
+        try {
+          const res = await common_vendor.index.request({
+            url: "http://localhost:3333/user/UserPassLogin",
+            method: "POST",
+            data: {
+              username: this.username,
+              password: this.password
+            },
+            header: { "content-type": "application/json" }
+          });
+          common_vendor.index.hideLoading();
+          if (res.statusCode === 200 && res.data && res.data.code === 200) {
+            common_vendor.index.showToast({ title: "登录成功", icon: "success" });
+            setTimeout(() => {
+              common_vendor.index.switchTab({ url: "/pages/home/index" });
+            }, 1500);
+          } else {
+            common_vendor.index.showToast({ title: ((_b = res.data) == null ? void 0 : _b.msg) || "登录失败", icon: "error" });
+          }
+        } catch (err) {
+          common_vendor.index.hideLoading();
+          common_vendor.index.showToast({ title: "登录失败", icon: "none" });
         }
-      } catch (err) {
-        common_vendor.index.hideLoading();
-        common_vendor.index.__f__("error", "at pages/login/login.vue:237", "Login request failed:", err);
-        common_vendor.index.showToast({ title: "登录失败", icon: "none" });
       }
     },
     toRegister() {
       this.showRegisterPopup = true;
     },
     toForgot() {
-      common_vendor.index.showToast({ title: "跳转找回密码", icon: "none" });
+      this.showForgotPopup = true;
     },
     openAgreement() {
       common_vendor.index.navigateTo({ url: "/pages/agreement/agreement" });
@@ -204,7 +239,7 @@ const _sfc_main = {
         common_vendor.index.hideLoading();
         this.isSendingRegCode = false;
         if (res.statusCode === 200 && res.data) {
-          common_vendor.index.__f__("log", "at pages/login/login.vue:288", "Send registration code success:", res.data);
+          common_vendor.index.__f__("log", "at pages/login/login.vue:345", "Send registration code success:", res.data);
           common_vendor.index.showToast({ title: "验证码已发送", icon: "success" });
           this.regCodeTimer = 60;
           const timerInterval = setInterval(() => {
@@ -215,13 +250,13 @@ const _sfc_main = {
             }
           }, 1e3);
         } else {
-          common_vendor.index.__f__("error", "at pages/login/login.vue:302", "Send registration code failed:", res);
+          common_vendor.index.__f__("error", "at pages/login/login.vue:359", "Send registration code failed:", res);
           common_vendor.index.showToast({ title: ((_a = res.data) == null ? void 0 : _a.message) || "发送失败", icon: "none" });
         }
       } catch (err) {
         common_vendor.index.hideLoading();
         this.isSendingRegCode = false;
-        common_vendor.index.__f__("error", "at pages/login/login.vue:309", "Send registration code request failed:", err);
+        common_vendor.index.__f__("error", "at pages/login/login.vue:366", "Send registration code request failed:", err);
         common_vendor.index.showToast({ title: "发送失败", icon: "none" });
       }
     },
@@ -246,7 +281,7 @@ const _sfc_main = {
         });
         common_vendor.index.hideLoading();
         if (res.statusCode === 200 && res.data) {
-          common_vendor.index.__f__("log", "at pages/login/login.vue:337", "Registration success:", res.data);
+          common_vendor.index.__f__("log", "at pages/login/login.vue:394", "Registration success:", res.data);
           common_vendor.index.showToast({ title: "注册成功", icon: "success" });
           this.regPhone = "";
           this.regCode = "";
@@ -256,14 +291,102 @@ const _sfc_main = {
             this.showRegisterPopup = false;
           }, 1500);
         } else {
-          common_vendor.index.__f__("error", "at pages/login/login.vue:349", "Registration failed:", res);
+          common_vendor.index.__f__("error", "at pages/login/login.vue:406", "Registration failed:", res);
           common_vendor.index.showToast({ title: ((_a = res.data) == null ? void 0 : _a.message) || "注册失败", icon: "none" });
         }
       } catch (err) {
         common_vendor.index.hideLoading();
-        common_vendor.index.__f__("error", "at pages/login/login.vue:354", "Registration request failed:", err);
+        common_vendor.index.__f__("error", "at pages/login/login.vue:411", "Registration request failed:", err);
         common_vendor.index.showToast({ title: "注册失败", icon: "none" });
       }
+    },
+    async sendForgotCode() {
+      var _a;
+      if (this.isSendingForgotCode || this.forgotCodeTimer > 0) {
+        return;
+      }
+      if (!this.forgotPhone) {
+        common_vendor.index.showToast({ title: "请输入手机号", icon: "none" });
+        return;
+      }
+      this.isSendingForgotCode = true;
+      common_vendor.index.showLoading({ title: "发送中...", mask: true });
+      try {
+        const res = await common_vendor.index.request({
+          url: "http://localhost:3333/user/code",
+          method: "POST",
+          data: {
+            phone: this.forgotPhone
+          },
+          header: { "content-type": "application/json" }
+        });
+        common_vendor.index.hideLoading();
+        this.isSendingForgotCode = false;
+        if (res.statusCode === 200 && res.data) {
+          common_vendor.index.__f__("log", "at pages/login/login.vue:441", "Send forgot code success:", res.data);
+          common_vendor.index.showToast({ title: "验证码已发送", icon: "success" });
+          this.forgotCodeTimer = 60;
+          const timerInterval = setInterval(() => {
+            this.forgotCodeTimer--;
+            if (this.forgotCodeTimer <= 0) {
+              clearInterval(timerInterval);
+              this.forgotCodeTimer = 0;
+            }
+          }, 1e3);
+        } else {
+          common_vendor.index.__f__("error", "at pages/login/login.vue:453", "Send forgot code failed:", res);
+          common_vendor.index.showToast({ title: ((_a = res.data) == null ? void 0 : _a.message) || "发送失败", icon: "none" });
+        }
+      } catch (err) {
+        common_vendor.index.hideLoading();
+        this.isSendingForgotCode = false;
+        common_vendor.index.__f__("error", "at pages/login/login.vue:459", "Send forgot code request failed:", err);
+        common_vendor.index.showToast({ title: "发送失败", icon: "none" });
+      }
+    },
+    async doResetPassword() {
+      var _a;
+      if (!this.forgotPhone || !this.forgotCode || !this.newPassword || !this.confirmPassword) {
+        common_vendor.index.showToast({ title: "请填写所有信息", icon: "none" });
+        return;
+      }
+      if (this.newPassword !== this.confirmPassword) {
+        common_vendor.index.showToast({ title: "两次密码输入不一致", icon: "none" });
+        return;
+      }
+      common_vendor.index.showLoading({ title: "修改中...", mask: true });
+      try {
+        const res = await common_vendor.index.request({
+          url: "http://localhost:3333/user/ForgetPass",
+          method: "POST",
+          data: {
+            phone: this.forgotPhone,
+            code: this.forgotCode,
+            newPassword: this.newPassword
+          },
+          header: { "content-type": "application/json" }
+        });
+        common_vendor.index.hideLoading();
+        if (res.statusCode === 200 && res.data) {
+          common_vendor.index.__f__("log", "at pages/login/login.vue:491", "Reset password success:", res.data);
+          common_vendor.index.showToast({ title: "密码修改成功", icon: "success" });
+          this.forgotPhone = "";
+          this.forgotCode = "";
+          this.newPassword = "";
+          this.confirmPassword = "";
+          setTimeout(() => {
+            this.showForgotPopup = false;
+            this.loginType = "account";
+          }, 1500);
+        } else {
+          common_vendor.index.__f__("error", "at pages/login/login.vue:507", "Reset password failed:", res);
+          common_vendor.index.showToast({ title: ((_a = res.data) == null ? void 0 : _a.message) || "修改失败", icon: "none" });
+        }
+      } catch (err) {
+        common_vendor.index.hideLoading();
+        common_vendor.index.__f__("error", "at pages/login/login.vue:512", "Reset password request failed:", err);
+        common_vendor.index.showToast({ title: "修改失败", icon: "none" });
+      }
     }
   }
 };
@@ -314,6 +437,23 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
     N: common_vendor.o((...args) => $options.doRegister && $options.doRegister(...args)),
     O: common_assets._imports_1,
     P: common_vendor.o(($event) => $data.showRegisterPopup = false)
+  } : {}, {
+    Q: $data.showForgotPopup
+  }, $data.showForgotPopup ? {
+    R: $data.forgotPhone,
+    S: common_vendor.o(($event) => $data.forgotPhone = $event.detail.value),
+    T: $data.forgotCode,
+    U: common_vendor.o(($event) => $data.forgotCode = $event.detail.value),
+    V: common_vendor.t($data.forgotCodeTimer > 0 ? $data.forgotCodeTimer + "s" : "获取验证码"),
+    W: common_vendor.o((...args) => $options.sendForgotCode && $options.sendForgotCode(...args)),
+    X: $data.forgotCodeTimer > 0 || $data.isSendingForgotCode,
+    Y: $data.newPassword,
+    Z: common_vendor.o(($event) => $data.newPassword = $event.detail.value),
+    aa: $data.confirmPassword,
+    ab: common_vendor.o(($event) => $data.confirmPassword = $event.detail.value),
+    ac: common_vendor.o((...args) => $options.doResetPassword && $options.doResetPassword(...args)),
+    ad: common_assets._imports_1,
+    ae: common_vendor.o(($event) => $data.showForgotPopup = false)
   } : {});
 }
 const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
unpackage/dist/dev/mp-weixin/pages/login/login.wxml


+ 43 - 0
unpackage/dist/dev/mp-weixin/pages/login/login.wxss

@@ -236,3 +236,46 @@
 		color: #7ac81e;
 		font-size: 26rpx;
 }
+.forgot-popup-content {
+		background-color: #fff;
+		border-radius: 24rpx;
+		width: 85vw;
+		max-width: 600rpx;
+		padding: 60rpx 40rpx;
+		position: relative;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+}
+.forgot-form {
+		width: 100%;
+		margin-bottom: 30rpx;
+}
+.forgot-form .login-input {
+		width: 90%;
+		height: 80rpx;
+		border: 1rpx solid #eee;
+		border-radius: 12rpx;
+		margin-bottom: 20rpx;
+		padding: 0 24rpx;
+		font-size: 28rpx;
+		background: #f7f8fa;
+}
+.forgot-form .code-row {
+		display: flex;
+		align-items: center;
+		margin-bottom: 20rpx;
+}
+.forgot-form .code-input {
+		flex: 1;
+		margin-right: 16rpx;
+		width: auto;
+}
+.forgot-form .code-btn {
+		height: 80rpx;
+		background: #7ac81e;
+		color: #fff;
+		border-radius: 12rpx;
+		padding: 0 24rpx;
+		font-size: 28rpx;
+}

+ 26 - 26
unpackage/dist/dev/mp-weixin/project.config.json

@@ -1,29 +1,29 @@
 {
-    "description": "项目配置文件。",
-    "packOptions": {
-        "ignore": [],
-        "include": []
-    },
-    "setting": {
-        "urlCheck": false,
-        "es6": true,
-        "postcss": false,
-        "minified": false,
-        "newFeature": true,
-        "bigPackageSizeSupport": true,
-        "babelSetting": {
-            "ignore": [],
-            "disablePlugins": [],
-            "outputPath": ""
-        }
-    },
-    "compileType": "miniprogram",
-    "libVersion": "",
-    "appid": "wx97b71d70f5b2d51f",
-    "projectname": "TourismApp",
-    "condition": {},
-    "editorSetting": {
-        "tabIndent": "insertSpaces",
-        "tabSize": 4
+  "description": "项目配置文件。",
+  "packOptions": {
+    "ignore": [],
+    "include": []
+  },
+  "setting": {
+    "urlCheck": false,
+    "es6": true,
+    "postcss": false,
+    "minified": false,
+    "newFeature": true,
+    "bigPackageSizeSupport": true,
+    "babelSetting": {
+      "ignore": [],
+      "disablePlugins": [],
+      "outputPath": ""
     }
+  },
+  "compileType": "miniprogram",
+  "libVersion": "",
+  "appid": "wx97b71d70f5b2d51f",
+  "projectname": "TourismApp",
+  "condition": {},
+  "editorSetting": {
+    "tabIndent": "insertSpaces",
+    "tabSize": 2
+  }
 }

+ 6 - 6
unpackage/dist/dev/mp-weixin/project.private.config.json

@@ -1,8 +1,8 @@
 {
-    "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
-    "projectname": "TourismApp",
-    "setting": {
-        "compileHotReLoad": true
-    },
-    "libVersion": "2.25.4"
+  "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+  "projectname": "TourismApp",
+  "setting": {
+    "compileHotReLoad": true
+  },
+  "libVersion": "2.25.4"
 }

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott