Ver código fonte

添加用户协议

yangg 2 meses atrás
pai
commit
19a59b8221

+ 10 - 0
api/user.js

@@ -143,3 +143,13 @@ export const getApplicationDetail = (params) => {
 export const uploadPhoto = (params) => {
   return http.post('/api/upload/', params);
 };
+
+/* 用户协议 */
+export const getUserAgreement = () => {
+  return http.get('/api/public/agreements/terms_of_service/');
+};
+
+// 获取隐私政策
+/* export function getPrivacyPolicy() {
+  return http.get('/api/privacy-policy');
+} */

+ 1 - 1
common/config.js

@@ -1,7 +1,7 @@
 // API base URL configuration
 //线上 https://minlong.raycos.com.cn
 //测试 http://192.168.66.187:8083
-export const apiBaseUrl = 'https://minlong.raycos.com.cn';
+export const apiBaseUrl = 'http://192.168.66.187:8083';
 
 // You can add other global configuration settings here
 export const appVersion = '1.0.0';

+ 6 - 0
pages.json

@@ -87,6 +87,12 @@
 			{
 				"navigationBarTitleText" : ""
 			}
+		},
+		{
+			"path": "pages/agreement/agreement",
+			"style": {
+				"navigationBarTitleText": "用户协议"
+			}
 		}
 	],
 	

+ 177 - 0
pages/agreement/agreement.vue

@@ -0,0 +1,177 @@
+<template>
+  <view class="agreement-container">
+    <!-- <view class="agreement-header">
+      <view class="back-btn" @click="goBack">
+        <text class="iconfont icon-back">&#xe679;</text>
+      </view>
+      <view class="title">用户协议</view>
+      <view class="placeholder"></view>
+    </view> -->
+    
+    <scroll-view scroll-y class="agreement-content">
+     <!--  <view class="agreement-title">《用户协议》</view> -->
+      
+      <!-- 使用v-if控制加载状态 -->
+      <view v-if="loading" class="loading">
+        <text>加载中...</text>
+      </view>
+      
+      <!-- 使用v-else-if显示错误信息 -->
+      <view v-else-if="error" class="error">
+        <text>{{errorMsg}}</text>
+        <button class="retry-btn" @click="fetchAgreement">重新加载</button>
+      </view>
+      
+      <!-- 使用v-else和v-html动态渲染协议内容 -->
+      <rich-text v-else :nodes="agreementContent"></rich-text>
+    </scroll-view>
+  </view>
+</template>
+
+<script>
+import { getUserAgreement } from '@/api/user';
+export default {
+  data() {
+    return {
+      agreementContent: '',
+      loading: true,
+      error: false,
+      errorMsg: '加载失败,请重试'
+    }
+  },
+  onLoad() {
+    this.fetchAgreement();
+  },
+  methods: {
+    goBack() {
+      uni.navigateBack();
+    },
+    fetchAgreement() {
+      this.loading = true;
+      this.error = false;
+      
+      getUserAgreement()
+        .then(res => {
+          console.log(res);
+          this.loading = false;
+            // 假设API返回的数据中有content字段包含协议内容
+            this.agreementContent = res.content || '';
+            console.log(this.agreementContent);
+         
+        })
+        .catch(err => {
+          console.error('获取用户协议失败:', err);
+          this.error = true;
+          this.errorMsg = '网络异常,请稍后重试';
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    }
+  }
+}
+</script>
+
+<style>
+.agreement-container {
+  /* display: flex;
+  flex-direction: column; */
+  height: 100vh;
+  background-color: #fff;
+}
+
+.agreement-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 90rpx;
+  background-color: #fff;
+  padding: 0 30rpx;
+  position: relative;
+  border-bottom: 1rpx solid #eee;
+}
+
+.back-btn {
+  width: 60rpx;
+  height: 60rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.icon-back {
+  font-size: 40rpx;
+  color: #333;
+}
+
+.title {
+  font-size: 34rpx;
+  font-weight: 500;
+  color: #333;
+}
+
+.placeholder {
+  width: 60rpx;
+}
+
+.agreement-content {
+  width: 100%;
+  padding: 20rpx 30rpx;
+  box-sizing: border-box;
+  background-color: #fff;
+}
+
+.agreement-title {
+  font-size: 36rpx;
+  font-weight: bold;
+  text-align: center;
+  margin-bottom: 40rpx;
+  color: #333;
+}
+
+.section {
+  margin-bottom: 30rpx;
+}
+
+.section-title {
+  font-size: 32rpx;
+  font-weight: 500;
+  color: #333;
+  margin-bottom: 20rpx;
+}
+
+.section-content {
+  font-size: 28rpx;
+  color: #666;
+  line-height: 1.6;
+}
+
+.paragraph {
+  display: block;
+  margin-bottom: 20rpx;
+  text-align: justify;
+}
+
+.loading, .error {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 40rpx;
+  color: #666;
+  font-size: 28rpx;
+}
+
+.error {
+  color: #ff4d4f;
+}
+
+.retry-btn {
+  margin-top: 20rpx;
+  padding: 10rpx 30rpx;
+  background-color: #1890ff;
+  color: #fff;
+  border-radius: 8rpx;
+  font-size: 28rpx;
+}
+</style> 

+ 55 - 4
pages/index/index.vue

@@ -40,7 +40,6 @@
 					<text class="icon-error" v-else>✗</text>
 				</view>
 			</view>
-
 			<view class="form-item">
 				<input type="text" v-model="formData.idCard" placeholder="请输入身份证号" maxlength="18" @input="validateIdCard" />
 				<view class="validation-icon" v-if="formData.idCard">
@@ -48,6 +47,17 @@
 					<text class="icon-error" v-else>✗</text>
 				</view>
 			</view>
+			<!-- 添加性别选择 -->
+			<view class="form-item">
+				<picker @change="genderChange" :value="genderIndex" :range="genderOptions">
+					<view class="picker-input">
+						<input type="text" disabled placeholder="请选择性别" :value="formData.gender" />
+						<view class="dropdown-icon">▼</view>
+					</view>
+				</picker>
+			</view>
+
+			
 
 			<button class="verify-btn" :disabled="!canSubmitSimple" @click="submitForm">确认面试</button>
 
@@ -91,7 +101,9 @@ import { apiBaseUrl } from '@/common/config.js';
 				selectedJob: null,
 				isPhoneValid: false,
 				isNameValid: false,
-				isIdCardValid: false
+				isIdCardValid: false,
+				genderOptions: ['男', '女'],
+				genderIndex: 0
 			}
 		},
 		onLoad() {
@@ -319,6 +331,14 @@ import { apiBaseUrl } from '@/common/config.js';
 					return;
 				}
 
+				if (!this.formData.gender) {
+					uni.showToast({
+						title: '请选择性别',
+						icon: 'none'
+					});
+					return;
+				}
+
 				if (!this.formData.phone.trim()) {
 					uni.showToast({
 						title: '请输入手机号',
@@ -359,7 +379,7 @@ import { apiBaseUrl } from '@/common/config.js';
 					});
 					return;
 				}
-
+				
 				uni.showLoading({
 					title: '验证身份信息...'
 				});
@@ -420,7 +440,8 @@ import { apiBaseUrl } from '@/common/config.js';
 					emergency_phone: this.formData.emergencyPhone,
 					relation: this.formData.relation, */
 					age: '20',
-					job_id: this.selectedJobId
+					job_id: this.selectedJobId,
+					gender: this.formData.gender
 				};
 
 				fillUserInfo(submitData)
@@ -481,6 +502,10 @@ import { apiBaseUrl } from '@/common/config.js';
 			validateIdCard() {
 				const idCardReg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
 				this.isIdCardValid = idCardReg.test(this.formData.idCard);
+			},
+			genderChange(e) {
+				this.genderIndex = e.detail.value;
+				this.formData.gender = this.genderOptions[this.genderIndex];
 			}
 		}
 	}
@@ -752,4 +777,30 @@ import { apiBaseUrl } from '@/common/config.js';
 		color: #ff3b30;
 		font-weight: bold;
 	}
+
+	/* 修改性别选择样式,使其看起来像输入框 */
+	.picker-input {
+		position: relative;
+		width: 100%;
+	}
+
+	.picker-input input {
+		width: 100%;
+		height: 80rpx;
+		border: 1px solid #eee;
+		border-radius: 8rpx;
+		padding: 0 60rpx 0 20rpx;
+		font-size: 28rpx;
+		box-sizing: border-box;
+		background-color: #f9f9f9;
+	}
+
+	.picker-input .dropdown-icon {
+		position: absolute;
+		right: 20rpx;
+		top: 50%;
+		transform: translateY(-50%);
+		font-size: 24rpx;
+		color: #999;
+	}
 </style>

+ 15 - 3
pages/login/login.vue

@@ -7,9 +7,9 @@
       <checkbox :checked="isAgreed" @tap="toggleAgreement" color="#0039b3" />
       <text class="agreement-text">
         我已阅读并同意
-        <text class="agreement-link">《用户协议》</text>
-        和
-        <text class="agreement-link">《隐私政策》</text>
+        <text class="agreement-link" @tap="navigateToAgreement">《用户协议》</text>
+       <!-- 
+        <text class="agreement-link" @tap="navigateToPrivacy">《隐私政策》</text> -->
       </text>
     </view>
   </view>
@@ -257,6 +257,18 @@ export default {
         title: error.message || '登录失败',
         icon: 'none'
       });
+    },
+    
+    navigateToPrivacy() {
+      uni.navigateTo({
+        url: '/pages/privacy/privacy'
+      });
+    },
+    
+    navigateToAgreement() {
+      uni.navigateTo({
+        url: '/pages/agreement/agreement'
+      });
     }
   }
 }

+ 4 - 0
unpackage/dist/dev/mp-weixin/api/user.js

@@ -54,10 +54,14 @@ const getInterviewList = (params) => {
 const applyJob = (params) => {
   return utils_request.http.post("/api/job/apply", params);
 };
+const getUserAgreement = () => {
+  return utils_request.http.get("/api/public/agreements/terms_of_service/");
+};
 exports.applyJob = applyJob;
 exports.fillUserInfo = fillUserInfo;
 exports.getInterviewList = getInterviewList;
 exports.getJobList = getJobList;
+exports.getUserAgreement = getUserAgreement;
 exports.getUserInfo = getUserInfo;
 exports.logout = logout;
 exports.wxLogin = wxLogin;

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

@@ -16,6 +16,7 @@ if (!Math) {
   "./pages/interview-question/interview-question.js";
   "./pages/preview/preview.js";
   "./pages/interview_success/interview_success.js";
+  "./pages/agreement/agreement.js";
 }
 const _sfc_main = {
   onLaunch: function() {

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

@@ -12,7 +12,8 @@
     "pages/ResumeEvaluation/ResumeEvaluation",
     "pages/interview-question/interview-question",
     "pages/preview/preview",
-    "pages/interview_success/interview_success"
+    "pages/interview_success/interview_success",
+    "pages/agreement/agreement"
   ],
   "window": {
     "navigationBarTextStyle": "black",

+ 1 - 1
unpackage/dist/dev/mp-weixin/common/config.js

@@ -1,3 +1,3 @@
 "use strict";
-const apiBaseUrl = "https://minlong.raycos.com.cn";
+const apiBaseUrl = "http://192.168.66.187:8083";
 exports.apiBaseUrl = apiBaseUrl;

+ 51 - 0
unpackage/dist/dev/mp-weixin/pages/agreement/agreement.js

@@ -0,0 +1,51 @@
+"use strict";
+const common_vendor = require("../../common/vendor.js");
+const api_user = require("../../api/user.js");
+const _sfc_main = {
+  data() {
+    return {
+      agreementContent: "",
+      loading: true,
+      error: false,
+      errorMsg: "加载失败,请重试"
+    };
+  },
+  onLoad() {
+    this.fetchAgreement();
+  },
+  methods: {
+    goBack() {
+      common_vendor.index.navigateBack();
+    },
+    fetchAgreement() {
+      this.loading = true;
+      this.error = false;
+      api_user.getUserAgreement().then((res) => {
+        console.log(res);
+        this.loading = false;
+        this.agreementContent = res.content || "";
+        console.log(this.agreementContent);
+      }).catch((err) => {
+        console.error("获取用户协议失败:", err);
+        this.error = true;
+        this.errorMsg = "网络异常,请稍后重试";
+      }).finally(() => {
+        this.loading = false;
+      });
+    }
+  }
+};
+function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
+  return common_vendor.e({
+    a: $data.loading
+  }, $data.loading ? {} : $data.error ? {
+    c: common_vendor.t($data.errorMsg),
+    d: common_vendor.o((...args) => $options.fetchAgreement && $options.fetchAgreement(...args))
+  } : {
+    e: $data.agreementContent
+  }, {
+    b: $data.error
+  });
+}
+const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
+wx.createPage(MiniProgramPage);

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

@@ -0,0 +1,4 @@
+{
+  "navigationBarTitleText": "用户协议",
+  "usingComponents": {}
+}

+ 1 - 0
unpackage/dist/dev/mp-weixin/pages/agreement/agreement.wxml

@@ -0,0 +1 @@
+<view class="agreement-container"><scroll-view scroll-y class="agreement-content"><view wx:if="{{a}}" class="loading"><text>加载中...</text></view><view wx:elif="{{b}}" class="error"><text>{{c}}</text><button class="retry-btn" bindtap="{{d}}">重新加载</button></view><rich-text wx:else nodes="{{e}}"></rich-text></scroll-view></view>

+ 88 - 0
unpackage/dist/dev/mp-weixin/pages/agreement/agreement.wxss

@@ -0,0 +1,88 @@
+
+.agreement-container {
+  /* display: flex;
+  flex-direction: column; */
+  height: 100vh;
+  background-color: #fff;
+}
+.agreement-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 90rpx;
+  background-color: #fff;
+  padding: 0 30rpx;
+  position: relative;
+  border-bottom: 1rpx solid #eee;
+}
+.back-btn {
+  width: 60rpx;
+  height: 60rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.icon-back {
+  font-size: 40rpx;
+  color: #333;
+}
+.title {
+  font-size: 34rpx;
+  font-weight: 500;
+  color: #333;
+}
+.placeholder {
+  width: 60rpx;
+}
+.agreement-content {
+  width: 100%;
+  padding: 20rpx 30rpx;
+  box-sizing: border-box;
+  background-color: #fff;
+}
+.agreement-title {
+  font-size: 36rpx;
+  font-weight: bold;
+  text-align: center;
+  margin-bottom: 40rpx;
+  color: #333;
+}
+.section {
+  margin-bottom: 30rpx;
+}
+.section-title {
+  font-size: 32rpx;
+  font-weight: 500;
+  color: #333;
+  margin-bottom: 20rpx;
+}
+.section-content {
+  font-size: 28rpx;
+  color: #666;
+  line-height: 1.6;
+}
+.paragraph {
+  display: block;
+  margin-bottom: 20rpx;
+  text-align: justify;
+}
+.loading, .error {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 40rpx;
+  color: #666;
+  font-size: 28rpx;
+}
+.error {
+  color: #ff4d4f;
+}
+.retry-btn {
+  margin-top: 20rpx;
+  padding: 10rpx 30rpx;
+  background-color: #1890ff;
+  color: #fff;
+  border-radius: 8rpx;
+  font-size: 28rpx;
+}

+ 24 - 6
unpackage/dist/dev/mp-weixin/pages/index/index.js

@@ -24,7 +24,9 @@ const _sfc_main = {
       selectedJob: null,
       isPhoneValid: false,
       isNameValid: false,
-      isIdCardValid: false
+      isIdCardValid: false,
+      genderOptions: ["男", "女"],
+      genderIndex: 0
     };
   },
   onLoad() {
@@ -215,6 +217,13 @@ const _sfc_main = {
         });
         return;
       }
+      if (!this.formData.gender) {
+        common_vendor.index.showToast({
+          title: "请选择性别",
+          icon: "none"
+        });
+        return;
+      }
       if (!this.formData.phone.trim()) {
         common_vendor.index.showToast({
           title: "请输入手机号",
@@ -308,7 +317,8 @@ const _sfc_main = {
         emergency_phone: this.formData.emergencyPhone,
         relation: this.formData.relation, */
         age: "20",
-        job_id: this.selectedJobId
+        job_id: this.selectedJobId,
+        gender: this.formData.gender
       };
       api_user.fillUserInfo(submitData).then((res) => {
         common_vendor.index.hideLoading();
@@ -359,6 +369,10 @@ const _sfc_main = {
     validateIdCard() {
       const idCardReg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
       this.isIdCardValid = idCardReg.test(this.formData.idCard);
+    },
+    genderChange(e) {
+      this.genderIndex = e.detail.value;
+      this.formData.gender = this.genderOptions[this.genderIndex];
     }
   }
 };
@@ -399,10 +413,14 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
   }, $data.formData.idCard ? common_vendor.e({
     q: $data.isIdCardValid
   }, $data.isIdCardValid ? {} : {}) : {}, {
-    r: !$options.canSubmitSimple,
-    s: common_vendor.o((...args) => $options.submitForm && $options.submitForm(...args)),
-    t: $data.isAgreed,
-    v: common_vendor.o((...args) => $options.toggleAgreement && $options.toggleAgreement(...args))
+    r: $data.formData.gender,
+    s: common_vendor.o((...args) => $options.genderChange && $options.genderChange(...args)),
+    t: $data.genderIndex,
+    v: $data.genderOptions,
+    w: !$options.canSubmitSimple,
+    x: common_vendor.o((...args) => $options.submitForm && $options.submitForm(...args)),
+    y: $data.isAgreed,
+    z: common_vendor.o((...args) => $options.toggleAgreement && $options.toggleAgreement(...args))
   }) : {});
 }
 const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/dev/mp-weixin/pages/index/index.wxml


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

@@ -231,3 +231,27 @@ input {
 		color: #ff3b30;
 		font-weight: bold;
 }
+
+	/* 修改性别选择样式,使其看起来像输入框 */
+.picker-input {
+		position: relative;
+		width: 100%;
+}
+.picker-input input {
+		width: 100%;
+		height: 80rpx;
+		border: 1px solid #eee;
+		border-radius: 8rpx;
+		padding: 0 60rpx 0 20rpx;
+		font-size: 28rpx;
+		box-sizing: border-box;
+		background-color: #f9f9f9;
+}
+.picker-input .dropdown-icon {
+		position: absolute;
+		right: 20rpx;
+		top: 50%;
+		transform: translateY(-50%);
+		font-size: 24rpx;
+		color: #999;
+}

+ 12 - 1
unpackage/dist/dev/mp-weixin/pages/login/login.js

@@ -188,6 +188,16 @@ const _sfc_main = {
         title: error.message || "登录失败",
         icon: "none"
       });
+    },
+    navigateToPrivacy() {
+      common_vendor.index.navigateTo({
+        url: "/pages/privacy/privacy"
+      });
+    },
+    navigateToAgreement() {
+      common_vendor.index.navigateTo({
+        url: "/pages/agreement/agreement"
+      });
     }
   }
 };
@@ -196,7 +206,8 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
     a: common_assets._imports_0,
     b: common_vendor.o((...args) => $options.handleLogin && $options.handleLogin(...args)),
     c: $data.isAgreed,
-    d: common_vendor.o((...args) => $options.toggleAgreement && $options.toggleAgreement(...args))
+    d: common_vendor.o((...args) => $options.toggleAgreement && $options.toggleAgreement(...args)),
+    e: common_vendor.o((...args) => $options.navigateToAgreement && $options.navigateToAgreement(...args))
   };
 }
 const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);

+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/login/login.wxml

@@ -1 +1 @@
-<view class="login-container"><image class="login-image" src="{{a}}" mode="aspectFit"></image><view class="login-title">登录奇才,开始面试</view><button class="login-btn" bindtap="{{b}}">身份验证并登录</button><view class="agreement"><checkbox checked="{{c}}" bindtap="{{d}}" color="#0039b3"/><text class="agreement-text"> 我已阅读并同意 <text class="agreement-link">《用户协议》</text> 和 <text class="agreement-link">《隐私政策》</text></text></view></view>
+<view class="login-container"><image class="login-image" src="{{a}}" mode="aspectFit"></image><view class="login-title">登录奇才,开始面试</view><button class="login-btn" bindtap="{{b}}">身份验证并登录</button><view class="agreement"><checkbox checked="{{c}}" bindtap="{{d}}" color="#0039b3"/><text class="agreement-text"> 我已阅读并同意 <text class="agreement-link" bindtap="{{e}}">《用户协议》</text></text></view></view>

+ 51 - 0
unpackage/dist/dev/mp-weixin/pages/privacy/privacy.js

@@ -0,0 +1,51 @@
+"use strict";
+const common_vendor = require("../../common/vendor.js");
+const api_user = require("../../api/user.js");
+const _sfc_main = {
+  data() {
+    return {
+      agreementContent: "",
+      loading: true,
+      error: false,
+      errorMsg: "加载失败,请重试"
+    };
+  },
+  onLoad() {
+    this.fetchAgreement();
+  },
+  methods: {
+    goBack() {
+      common_vendor.index.navigateBack();
+    },
+    fetchAgreement() {
+      this.loading = true;
+      this.error = false;
+      api_user.getUserAgreement().then((res) => {
+        console.log(res);
+        this.loading = false;
+        this.agreementContent = res.content || "";
+        console.log(this.agreementContent);
+      }).catch((err) => {
+        console.error("获取用户协议失败:", err);
+        this.error = true;
+        this.errorMsg = "网络异常,请稍后重试";
+      }).finally(() => {
+        this.loading = false;
+      });
+    }
+  }
+};
+function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
+  return common_vendor.e({
+    a: $data.loading
+  }, $data.loading ? {} : $data.error ? {
+    c: common_vendor.t($data.errorMsg),
+    d: common_vendor.o((...args) => $options.fetchAgreement && $options.fetchAgreement(...args))
+  } : {
+    e: $data.agreementContent
+  }, {
+    b: $data.error
+  });
+}
+const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
+wx.createPage(MiniProgramPage);

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

@@ -0,0 +1,4 @@
+{
+  "navigationBarTitleText": "隐私政策",
+  "usingComponents": {}
+}

+ 1 - 0
unpackage/dist/dev/mp-weixin/pages/privacy/privacy.wxml

@@ -0,0 +1 @@
+<view class="agreement-container"><scroll-view scroll-y class="agreement-content"><view wx:if="{{a}}" class="loading"><text>加载中...</text></view><view wx:elif="{{b}}" class="error"><text>{{c}}</text><button class="retry-btn" bindtap="{{d}}">重新加载</button></view><rich-text wx:else nodes="{{e}}"></rich-text></scroll-view></view>

+ 88 - 0
unpackage/dist/dev/mp-weixin/pages/privacy/privacy.wxss

@@ -0,0 +1,88 @@
+
+.agreement-container {
+  /* display: flex;
+  flex-direction: column; */
+  height: 100vh;
+  background-color: #fff;
+}
+.agreement-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 90rpx;
+  background-color: #fff;
+  padding: 0 30rpx;
+  position: relative;
+  border-bottom: 1rpx solid #eee;
+}
+.back-btn {
+  width: 60rpx;
+  height: 60rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.icon-back {
+  font-size: 40rpx;
+  color: #333;
+}
+.title {
+  font-size: 34rpx;
+  font-weight: 500;
+  color: #333;
+}
+.placeholder {
+  width: 60rpx;
+}
+.agreement-content {
+  width: 100%;
+  padding: 20rpx 30rpx;
+  box-sizing: border-box;
+  background-color: #fff;
+}
+.agreement-title {
+  font-size: 36rpx;
+  font-weight: bold;
+  text-align: center;
+  margin-bottom: 40rpx;
+  color: #333;
+}
+.section {
+  margin-bottom: 30rpx;
+}
+.section-title {
+  font-size: 32rpx;
+  font-weight: 500;
+  color: #333;
+  margin-bottom: 20rpx;
+}
+.section-content {
+  font-size: 28rpx;
+  color: #666;
+  line-height: 1.6;
+}
+.paragraph {
+  display: block;
+  margin-bottom: 20rpx;
+  text-align: justify;
+}
+.loading, .error {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 40rpx;
+  color: #666;
+  font-size: 28rpx;
+}
+.error {
+  color: #ff4d4f;
+}
+.retry-btn {
+  margin-top: 20rpx;
+  padding: 10rpx 30rpx;
+  background-color: #1890ff;
+  color: #fff;
+  border-radius: 8rpx;
+  font-size: 28rpx;
+}

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff