hookehuyr

feat(authCar): 添加支付协议勾选功能及弹窗

增加支付协议勾选组件和协议弹窗展示功能
修改认证按钮逻辑,需同意协议方可操作
添加用户协议状态检查及更新逻辑
...@@ -499,3 +499,85 @@ ...@@ -499,3 +499,85 @@
499 .popup-content::-webkit-scrollbar-thumb:hover { 499 .popup-content::-webkit-scrollbar-thumb:hover {
500 background: #a8a8a8; 500 background: #a8a8a8;
501 } 501 }
502 +
503 +/* 协议勾选区域样式 */
504 +.agreement-section {
505 + margin: 32rpx 0;
506 + padding: 0 32rpx;
507 + text-align: center;
508 +
509 + .agreement-checkbox {
510 + font-size: 28rpx;
511 +
512 + .checkbox-text {
513 + white-space: nowrap;
514 + display: inline-block;
515 + }
516 +
517 + .agreement-link {
518 + color: #ffa500;
519 + text-decoration: underline;
520 + cursor: pointer;
521 + }
522 + }
523 +}
524 +
525 +/* 支付协议弹框样式 */
526 +.protocol-container {
527 + width: 100%;
528 + height: 100vh;
529 + background: white;
530 + display: flex;
531 + flex-direction: column;
532 +}
533 +
534 +.protocol-header {
535 + display: flex;
536 + justify-content: space-between;
537 + align-items: center;
538 + padding: 32rpx 40rpx;
539 + border-bottom: 1rpx solid #eee;
540 + background: white;
541 + position: sticky;
542 + top: 0;
543 + z-index: 10;
544 +}
545 +
546 +.protocol-title {
547 + font-size: 36rpx;
548 + font-weight: bold;
549 + color: #333;
550 +}
551 +
552 +.close-btn {
553 + width: 60rpx;
554 + height: 60rpx;
555 + display: flex;
556 + align-items: center;
557 + justify-content: center;
558 + background: #f5f5f5;
559 + border-radius: 50%;
560 + cursor: pointer;
561 +}
562 +
563 +.close-text {
564 + font-size: 40rpx;
565 + color: #666;
566 + line-height: 1;
567 +}
568 +
569 +.protocol-scroll {
570 + flex: 1;
571 + padding: 0 40rpx;
572 +}
573 +
574 +.protocol-body {
575 + padding: 40rpx 0;
576 +}
577 +
578 +.protocol-text {
579 + font-size: 28rpx;
580 + line-height: 1.8;
581 + color: #333;
582 + white-space: pre-line;
583 +}
......
1 <!-- 1 <!--
2 * @Date: 2022-09-19 14:11:06 2 * @Date: 2022-09-19 14:11:06
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-08-04 13:29:45 4 + * @LastEditTime: 2025-08-05 20:33:55
5 * @FilePath: /jgdl/src/pages/authCar/index.vue 5 * @FilePath: /jgdl/src/pages/authCar/index.vue
6 * @Description: 认证车源 6 * @Description: 认证车源
7 --> 7 -->
...@@ -101,17 +101,63 @@ ...@@ -101,17 +101,63 @@
101 </view> 101 </view>
102 </scroll-view> 102 </scroll-view>
103 103
104 + <!-- 协议勾选区域 -->
105 + <div v-if="!hasAgreed" class="agreement-section">
106 + <nut-checkbox v-model="isChecked" class="agreement-checkbox">
107 + <view class="checkbox-text">
108 + <text>我已阅读并同意</text>
109 + <text class="agreement-link" @tap.stop="showProtocol">
110 + 《支付协议》
111 + </text>
112 + </view>
113 + </nut-checkbox>
114 + </div>
115 +
104 <!-- 底部按钮 --> 116 <!-- 底部按钮 -->
105 <view class="popup-footer"> 117 <view class="popup-footer">
106 <nut-button plain class="footer-btn cancel-btn" @click="showAuthInfoPopup = false"> 118 <nut-button plain class="footer-btn cancel-btn" @click="showAuthInfoPopup = false">
107 关闭 119 关闭
108 </nut-button> 120 </nut-button>
109 - <nut-button type="warning" class="footer-btn confirm-btn" color="#fb923c" @click="handleConfirmAuth"> 121 + <nut-button
122 + type="warning"
123 + class="footer-btn confirm-btn"
124 + color="#fb923c"
125 + :disabled="!hasAgreed && !isChecked"
126 + @click="handleConfirmAuth"
127 + >
110 知道了 128 知道了
111 </nut-button> 129 </nut-button>
112 </view> 130 </view>
113 </view> 131 </view>
114 </nut-popup> 132 </nut-popup>
133 +
134 + <!-- 支付协议弹框 -->
135 + <nut-popup
136 + v-model:visible="protocolVisible"
137 + position="right"
138 + :closeable="true"
139 + :close-on-click-overlay="true"
140 + :safe-area-inset-bottom="true"
141 + :style="{ width: '100%', height: '100%' }"
142 + @close="protocolVisible = false"
143 + >
144 + <view class="protocol-container">
145 + <!-- 标题栏 -->
146 + <view class="protocol-header">
147 + <text class="protocol-title">支付协议</text>
148 + <view class="close-btn" @click="protocolVisible = false">
149 + <text class="close-text">×</text>
150 + </view>
151 + </view>
152 +
153 + <!-- 内容区域 -->
154 + <scroll-view class="protocol-scroll" :scroll-y="true">
155 + <view class="protocol-body">
156 + <view class="protocol-text">{{ protocolContent }}</view>
157 + </view>
158 + </scroll-view>
159 + </view>
160 + </nut-popup>
115 </view> 161 </view>
116 </template> 162 </template>
117 163
...@@ -125,8 +171,13 @@ import './index.less' ...@@ -125,8 +171,13 @@ import './index.less'
125 // 接口导入 171 // 接口导入
126 import { getVehicleListAPI, getArticleListAPI } from '@/api/car'; 172 import { getVehicleListAPI, getArticleListAPI } from '@/api/car';
127 import { getVerificationPriceAPI } from '@/api/other'; 173 import { getVerificationPriceAPI } from '@/api/other';
174 +import { updateProfileAPI, getProfileAPI } from '@/api/index';
175 +import { useUserStore } from '@/stores/user';
128 176
129 import { DEFAULT_COVER_IMG } from '@/utils/config' 177 import { DEFAULT_COVER_IMG } from '@/utils/config'
178 +
179 +const userStore = useUserStore()
180 +
130 // Banner数据 181 // Banner数据
131 const bannerList = ref([]) 182 const bannerList = ref([])
132 183
...@@ -154,6 +205,20 @@ const toastType = ref('success') ...@@ -154,6 +205,20 @@ const toastType = ref('success')
154 // 认证费用说明弹窗 205 // 认证费用说明弹窗
155 const showAuthInfoPopup = ref(false) 206 const showAuthInfoPopup = ref(false)
156 207
208 +// 协议相关数据
209 +const isChecked = ref(false)
210 +const hasAgreed = ref(false)
211 +const protocolVisible = ref(false)
212 +
213 +// 支付协议内容
214 +const protocolContent = ref(`
215 +1. 用户在使用捡个电驴收款服务时,需遵守相关法律法规。
216 +2. 平台有权对异常交易进行风险控制。
217 +3. 用户应确保收款信息的真实性和准确性。
218 +4. 平台将按照约定收取相应的服务费用。
219 +5. 如有争议,双方应友好协商解决。
220 +`)
221 +
157 // 滚动样式 222 // 滚动样式
158 const scrollStyle = computed(() => { 223 const scrollStyle = computed(() => {
159 return { 224 return {
...@@ -172,7 +237,30 @@ const handleAuth = () => { ...@@ -172,7 +237,30 @@ const handleAuth = () => {
172 /** 237 /**
173 * 确认认证,跳转到认证页面 238 * 确认认证,跳转到认证页面
174 */ 239 */
175 -const handleConfirmAuth = () => { 240 +const handleConfirmAuth = async () => {
241 + // 如果未同意协议且未勾选,不允许操作
242 + if (!hasAgreed.value && !isChecked.value) {
243 + return
244 + }
245 +
246 + // 如果勾选了但还未同意,先更新协议状态
247 + if (!hasAgreed.value && isChecked.value) {
248 + try {
249 + const result = await updateProfileAPI({
250 + is_signed: true
251 + })
252 +
253 + if (result.code) {
254 + hasAgreed.value = true
255 + if (userStore.userInfo) {
256 + userStore.userInfo.is_signed = true
257 + }
258 + }
259 + } catch (error) {
260 + console.error('更新协议状态失败:', error)
261 + }
262 + }
263 +
176 // 关闭弹窗 264 // 关闭弹窗
177 showAuthInfoPopup.value = false 265 showAuthInfoPopup.value = false
178 // 跳转到认证页面 266 // 跳转到认证页面
...@@ -194,6 +282,34 @@ const onCarClick = (car) => { ...@@ -194,6 +282,34 @@ const onCarClick = (car) => {
194 const { toggleFavorite } = useFavorite() 282 const { toggleFavorite } = useFavorite()
195 283
196 /** 284 /**
285 + * 显示支付协议
286 + */
287 +const showProtocol = () => {
288 + protocolVisible.value = true
289 +}
290 +
291 +/**
292 + * 检查用户是否已同意过协议
293 + */
294 +const checkAgreementStatus = async () => {
295 + try {
296 + const result = await getProfileAPI()
297 +
298 + if (result.code && result.data) {
299 + hasAgreed.value = result.data.is_signed || false
300 + if (userStore.userInfo) {
301 + userStore.userInfo.is_signed = result.data.is_signed
302 + }
303 + } else {
304 + hasAgreed.value = userStore.userInfo?.is_signed || false
305 + }
306 + } catch (error) {
307 + console.error('获取用户协议状态失败:', error)
308 + hasAgreed.value = userStore.userInfo?.is_signed || false
309 + }
310 +}
311 +
312 +/**
197 * 加载认证车辆数据 313 * 加载认证车辆数据
198 * @param {boolean} isLoadMore - 是否为加载更多 314 * @param {boolean} isLoadMore - 是否为加载更多
199 */ 315 */
...@@ -288,6 +404,8 @@ const getVerificationPrice = async () => { ...@@ -288,6 +404,8 @@ const getVerificationPrice = async () => {
288 404
289 // 初始化 405 // 初始化
290 onMounted(async () => { 406 onMounted(async () => {
407 + // 检查协议状态
408 + await checkAgreementStatus()
291 // 加载初始认证车辆数据 409 // 加载初始认证车辆数据
292 await loadAuthCarData() 410 await loadAuthCarData()
293 // 获取认证费用 411 // 获取认证费用
......
1 <!-- 1 <!--
2 * @Date: 2022-09-19 14:11:06 2 * @Date: 2022-09-19 14:11:06
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-08-05 18:35:51 4 + * @LastEditTime: 2025-08-05 20:03:22
5 * @FilePath: /jgdl/src/pages/collectionSettings/index.vue 5 * @FilePath: /jgdl/src/pages/collectionSettings/index.vue
6 * @Description: 收款设置 6 * @Description: 收款设置
7 --> 7 -->
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
41 <nut-popup 41 <nut-popup
42 v-model:visible="showAccountModal" 42 v-model:visible="showAccountModal"
43 position="bottom" 43 position="bottom"
44 - :style="{ width: '100%', height: '80%' }" 44 + :style="{ width: '100%', height: '85%' }"
45 :catch-move="true" 45 :catch-move="true"
46 closeable 46 closeable
47 close-icon-position="top-right" 47 close-icon-position="top-right"
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
69 placeholder="请输入银行账号" 69 placeholder="请输入银行账号"
70 class="form-input" 70 class="form-input"
71 type="number" 71 type="number"
72 + :cursorSpacing="50"
72 /> 73 />
73 </view> 74 </view>
74 </view> 75 </view>
...@@ -98,7 +99,7 @@ ...@@ -98,7 +99,7 @@
98 <nut-popup 99 <nut-popup
99 v-model:visible="showIdentityModal" 100 v-model:visible="showIdentityModal"
100 position="bottom" 101 position="bottom"
101 - :style="{ width: '100%', height: '80%' }" 102 + :style="{ width: '100%', height: '85%' }"
102 :catch-move="true" 103 :catch-move="true"
103 closeable 104 closeable
104 close-icon-position="top-right" 105 close-icon-position="top-right"
...@@ -127,6 +128,7 @@ ...@@ -127,6 +128,7 @@
127 class="form-input" 128 class="form-input"
128 maxlength="18" 129 maxlength="18"
129 @blur="handleIdCardBlur" 130 @blur="handleIdCardBlur"
131 + :cursorSpacing="50"
130 /> 132 />
131 <text v-if="idCardError" class="error-text">{{ idCardError }}</text> 133 <text v-if="idCardError" class="error-text">{{ idCardError }}</text>
132 </view> 134 </view>
......