3 Angajamente 0f3ec8b4f9 ... 46f14167c3

Autor SHA1 Permisiunea de a trimite mesaje. Dacă este dezactivată, utilizatorul nu va putea trimite nici un fel de mesaj Data
  Huanyi 46f14167c3 Merge branch 'dev/tys' of http://8.152.4.3:3000/yp_web/pet-system-merchant-app 3 zile în urmă
  Huanyi 8d2ab30512 代码格式化 3 zile în urmă
  沐梦. bc055aeb3b 隐藏部分协议内容 3 zile în urmă

+ 1 - 1
pages/index/index.vue

@@ -64,7 +64,7 @@
 				<image src="/static/images/index-hand.png" class="hand-img" mode="widthFix"></image>
 				<view class="hand-text-content">
 					<text class="hand-title">好萌友提醒您~</text>
-					<text class="hand-subtitle">功能优化中,敬请期待~</text>
+					<text class="hand-subtitle">懂你的爱,更懂你的小可爱~</text>
 				</view>
 			</view>
 		</view>

+ 12 - 9
pages/login/index.vue

@@ -58,7 +58,7 @@
 						<text class="agree-text">我已阅读并同意</text>
 						<text class="text-link" @click.stop="showAgreement(2)">《隐私政策》</text>
 						<text class="agree-text">和</text>
-						<text class="text-link" @click.stop="showAgreement(4)">《托运协议》</text>
+						<text class="text-link" @click.stop="showAgreement(1)">《用户服务协议》</text>
 					</label>
 				</checkbox-group>
 			</view>
@@ -78,7 +78,7 @@
 			<text>安全加密 · 保护您的账号信息</text>
 		</view>
 
-		<!-- 隐私政策/托运协议弹窗 -->
+		<!-- 隐私政策/用户服务协议弹窗 -->
 		<policy-dialog v-model:visible="dialogVisible" :title="dialogTitle" :content="dialogContent"></policy-dialog>
 	</view>
 </template>
@@ -139,18 +139,18 @@ const onSubmit = async () => {
 
 		if (res.access_token) {
 			uni.setStorageSync('token', res.access_token)
-			
+
 			// 获取用户信息并存储 tenantId
 			try {
 				const userRes = await getInfo()
 				if (userRes && userRes.user && userRes.user.tenantId) {
 					uni.setStorageSync('tenantId', userRes.user.tenantId)
 				}
-	} catch (e) {
-		console.error('获取用户信息失败', e)
-		uni.showToast({ title: typeof e === 'string' ? e : '请求失败', icon: 'none' })
-	}
-			
+			} catch (e) {
+				console.error('获取用户信息失败', e)
+				uni.showToast({ title: typeof e === 'string' ? e : '请求失败', icon: 'none' })
+			}
+
 			uni.showToast({ title: '登录成功', icon: 'success' })
 			setTimeout(() => {
 				uni.reLaunch({ url: '/pages/index/index' })
@@ -377,7 +377,10 @@ const showAgreement = async (agreementId) => {
 	border: none;
 	border-radius: 52rpx;
 	letter-spacing: 4rpx;
-	&::after { border: none; }
+
+	&::after {
+		border: none;
+	}
 }
 
 .footer-hint {

+ 12 - 11
pages/login/register.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="login-page">
 		<nav-bar title="注册" bgColor="transparent" color="#fff" :showBack="false"></nav-bar>
-		
+
 		<!-- 顶部渐变装饰区 -->
 		<view class="hero-bg">
 			<view class="deco-circle c1"></view>
@@ -54,8 +54,7 @@
 				<view class="input-icon-wrap">
 					<uni-icons type="staff" size="18" color="#ffc837"></uni-icons>
 				</view>
-				<input class="custom-input" v-model="name" placeholder="请输入姓名"
-					placeholder-class="input-placeholder" />
+				<input class="custom-input" v-model="name" placeholder="请输入姓名" placeholder-class="input-placeholder" />
 			</view>
 
 			<!-- 邮箱 -->
@@ -63,8 +62,7 @@
 				<view class="input-icon-wrap">
 					<uni-icons type="email" size="18" color="#ffc837"></uni-icons>
 				</view>
-				<input class="custom-input" v-model="email" placeholder="请输入邮箱"
-					placeholder-class="input-placeholder" />
+				<input class="custom-input" v-model="email" placeholder="请输入邮箱" placeholder-class="input-placeholder" />
 			</view>
 
 			<!-- 密码 -->
@@ -94,7 +92,7 @@
 						<text class="agree-text">我已阅读并同意</text>
 						<text class="text-link" @click.stop="showAgreement(2)">《隐私政策》</text>
 						<text class="agree-text">和</text>
-						<text class="text-link" @click.stop="showAgreement(4)">《托运协议》</text>
+						<text class="text-link" @click.stop="showAgreement(1)">《用户服务协议》</text>
 					</label>
 				</checkbox-group>
 			</view>
@@ -109,7 +107,7 @@
 			</view>
 		</view>
 
-		<!-- 隐私政策/托运协议弹窗 -->
+		<!-- 隐私政策/用户服务协议弹窗 -->
 		<policy-dialog v-model:visible="dialogVisible" :title="dialogTitle" :content="dialogContent"></policy-dialog>
 	</view>
 </template>
@@ -268,17 +266,17 @@ const onSubmit = async () => {
 			password: password.value,
 			confirmPassword: confirmPassword.value
 		})
-		
+
 		uni.hideLoading()
 		uni.showToast({
 			title: '提交成功',
 			icon: 'success'
 		})
-		
+
 		// 缓存商户名称和提交时间,供审核界面展示使用
 		uni.setStorageSync('registered_merchant', companyName.value)
 		uni.setStorageSync('registered_time', new Date().toLocaleString())
-		
+
 		setTimeout(() => {
 			uni.reLaunch({
 				url: '/pages/login/review'
@@ -441,7 +439,10 @@ const onSubmit = async () => {
 	border: none;
 	border-radius: 52rpx;
 	letter-spacing: 4rpx;
-	&::after { border: none; }
+
+	&::after {
+		border: none;
+	}
 }
 
 .register-redirect-row {

+ 64 - 4
pages/my/agreement/detail/index.vue

@@ -38,10 +38,70 @@ const fetchAgreement = async (id) => {
 			agreementData.value = res
 			// 解码 Base64 内容 (Admin端采用 btoa(unescape(encodeURIComponent(content))) 编码)
 			if (res.content) {
-				try {
-					contentHtml.value = decodeURIComponent(escape(atob(res.content)))
-				} catch (e) {
-					// 如果解码失败,回显原始内容
+				const cleanStr = String(res.content).trim().replace(/\s+/g, '')
+				// 检查是否是 base64 格式(仅包含 A-Z, a-z, 0-9, +, /, =)
+				const isBase64 = /^[A-Za-z0-9+/=]+$/.test(cleanStr)
+				
+				if (isBase64) {
+					try {
+						// 1. Base64 解码为二进制字符串
+						const atobPolyfill = (str) => {
+							if (typeof atob === 'function') return atob(str)
+							const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
+							let output = ''
+							const clean = str.replace(/=+$/, '')
+							for (let bc = 0, bs, buffer, idx = 0; idx < clean.length; ) {
+								const char = clean.charAt(idx++)
+								const buffer = chars.indexOf(char)
+								if (buffer === -1) throw new Error('Invalid base64 character')
+								bs = bc % 4 ? bs * 64 + buffer : buffer
+								if (bc++ % 4) {
+									output += String.fromCharCode(255 & bs >> (-2 * bc & 6))
+								}
+							}
+							return output
+						}
+						
+						const decodedBinary = atobPolyfill(cleanStr)
+						
+						// 2. 将二进制字符串解码为 UTF-8 字符串
+						const decodeUtf8 = (str) => {
+							let result = ''
+							let i = 0
+							while (i < str.length) {
+								const c1 = str.charCodeAt(i++)
+								if (c1 < 128) {
+									result += String.fromCharCode(c1)
+								} else if (c1 > 191 && c1 < 224) {
+									const c2 = str.charCodeAt(i++)
+									result += String.fromCharCode(((c1 & 31) << 6) | (c2 & 63))
+								} else if (c1 > 223 && c1 < 240) {
+									const c2 = str.charCodeAt(i++)
+									const c3 = str.charCodeAt(i++)
+									result += String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))
+								} else {
+									const c2 = str.charCodeAt(i++)
+									const c3 = str.charCodeAt(i++)
+									const c4 = str.charCodeAt(i++)
+									const codepoint = ((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)
+									if (codepoint > 0xffff) {
+										const offset = codepoint - 0x10000
+										result += String.fromCharCode((offset >> 10) + 0xd800, (offset & 0x3ff) + 0xdc00)
+									} else {
+										result += String.fromCharCode(codepoint)
+									}
+								}
+							}
+							return result
+						}
+						
+						contentHtml.value = decodeUtf8(decodedBinary)
+					} catch (e) {
+						// 解码失败,回显原始内容
+						contentHtml.value = res.content
+					}
+				} else {
+					// 非 base64 格式,直接回显原始 HTML 页面
 					contentHtml.value = res.content
 				}
 			} else {

+ 1 - 3
pages/my/agreement/list/index.vue

@@ -20,9 +20,7 @@ import navBar from '@/components/nav-bar/index.vue'
 // 协议列表,ID 参考 admin web 配置及后端 SysAgreementController
 const agreements = ref([
 	{ id: 2, title: '隐私政策' },
-	{ id: 1, title: '用户服务协议' },
-	{ id: 4, title: '商家托运协议' },
-	{ id: 5, title: '宠物洗护服务规范' } // 根据需求预留 ID:5
+	{ id: 1, title: '用户服务协议' }
 ])
 
 const goToDetail = (item) => {