hookehuyr

feat(收款设置): 新增收款设置页面及相关功能

添加收款设置页面,包括银行账号和身份信息设置功能
扩展权限检查功能,支持返回未通过校验的字段信息
更新用户个人中心,添加收款设置入口
...@@ -44,6 +44,7 @@ declare module 'vue' { ...@@ -44,6 +44,7 @@ declare module 'vue' {
44 Picker: typeof import('./src/components/time-picker-data/picker.vue')['default'] 44 Picker: typeof import('./src/components/time-picker-data/picker.vue')['default']
45 PosterBuilder: typeof import('./src/components/PosterBuilder/index.vue')['default'] 45 PosterBuilder: typeof import('./src/components/PosterBuilder/index.vue')['default']
46 PrivacyAgreementModal: typeof import('./src/components/PrivacyAgreementModal.vue')['default'] 46 PrivacyAgreementModal: typeof import('./src/components/PrivacyAgreementModal.vue')['default']
47 + QrcodePay: typeof import('./src/components/qrcodePay.vue')['default']
47 RouterLink: typeof import('vue-router')['RouterLink'] 48 RouterLink: typeof import('vue-router')['RouterLink']
48 RouterView: typeof import('vue-router')['RouterView'] 49 RouterView: typeof import('vue-router')['RouterView']
49 SearchPopup: typeof import('./src/components/SearchPopup.vue')['default'] 50 SearchPopup: typeof import('./src/components/SearchPopup.vue')['default']
......
1 /* 1 /*
2 * @Date: 2025-06-28 10:33:00 2 * @Date: 2025-06-28 10:33:00
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-15 15:42:47 4 + * @LastEditTime: 2025-08-05 15:12:01
5 * @FilePath: /jgdl/src/app.config.js 5 * @FilePath: /jgdl/src/app.config.js
6 * @Description: 配置文件 6 * @Description: 配置文件
7 */ 7 */
...@@ -29,6 +29,7 @@ export default { ...@@ -29,6 +29,7 @@ export default {
29 'pages/helpCenter/index', 29 'pages/helpCenter/index',
30 'pages/search/index', 30 'pages/search/index',
31 'pages/recommendCarList/index', 31 'pages/recommendCarList/index',
32 + 'pages/collectionSettings/index',
32 ], 33 ],
33 subpackages: [ // 配置在tabBar中的页面不能分包写到subpackages中去 34 subpackages: [ // 配置在tabBar中的页面不能分包写到subpackages中去
34 { 35 {
......
1 +/*
2 + * @Date: 2025-08-05 15:10:51
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-08-05 15:12:21
5 + * @FilePath: /jgdl/src/pages/collectionSettings/index.config.js
6 + * @Description: 收款设置
7 + */
8 +export default {
9 + navigationBarTitleText: '收款设置',
10 + usingComponents: {
11 + },
12 +}
1 +.collection-settings {
2 + min-height: 100vh;
3 + background-color: #f5f5f5;
4 + padding: 0;
5 +
6 + .page-title {
7 + background-color: #fff;
8 + padding: 32rpx;
9 + font-size: 36rpx;
10 + font-weight: 600;
11 + color: #333;
12 + text-align: center;
13 + border-bottom: 1rpx solid #eee;
14 + }
15 +
16 + .settings-list {
17 + margin-top: 24rpx;
18 + background-color: #fff;
19 + // border-radius: 16rpx;
20 + // margin: 24rpx 32rpx;
21 + overflow: hidden;
22 +
23 + .setting-item {
24 + display: flex;
25 + align-items: center;
26 + justify-content: space-between;
27 + padding: 32rpx 24rpx;
28 + border-bottom: 1rpx solid #f0f0f0;
29 + transition: background-color 0.2s;
30 +
31 + &:last-child {
32 + border-bottom: none;
33 + }
34 +
35 + &:active {
36 + background-color: #f8f8f8;
37 + }
38 +
39 + .setting-left {
40 + .setting-label {
41 + font-size: 32rpx;
42 + color: #333;
43 + // font-weight: 500;
44 + }
45 + }
46 +
47 + .setting-right {
48 + display: flex;
49 + align-items: center;
50 + gap: 16rpx;
51 +
52 + .setting-status {
53 + font-size: 28rpx;
54 + color: #999;
55 +
56 + &.status-set {
57 + color: #52c41a;
58 + }
59 + }
60 +
61 + .arrow {
62 + font-size: 24rpx;
63 + color: #ccc;
64 + }
65 + }
66 + }
67 + }
68 +
69 + // 弹窗样式
70 + .modal-content {
71 + height: 100%;
72 + display: flex;
73 + flex-direction: column;
74 + background-color: #fff;
75 +
76 + .modal-header {
77 + padding: 32rpx;
78 + border-bottom: 1rpx solid #eee;
79 + background-color: #fff;
80 + position: sticky;
81 + top: 0;
82 + z-index: 10;
83 +
84 + .modal-title {
85 + font-size: 36rpx;
86 + font-weight: 600;
87 + color: #333;
88 + text-align: center;
89 + }
90 + }
91 +
92 + .form-content {
93 + flex: 1;
94 + padding: 32rpx;
95 + overflow-y: auto;
96 +
97 + .form-item {
98 + margin-bottom: 48rpx;
99 +
100 + .form-label {
101 + display: block;
102 + font-size: 28rpx;
103 + color: #333;
104 + margin-bottom: 16rpx;
105 + font-weight: 500;
106 + }
107 +
108 + .form-input {
109 + width: 100%;
110 + padding: 24rpx 0;
111 + font-size: 32rpx;
112 + border: none;
113 + // border-bottom: 2rpx solid #eee;
114 + background: transparent;
115 + transition: border-color 0.3s;
116 +
117 + &:focus {
118 + border-bottom-color: #1890ff;
119 + }
120 + }
121 +
122 + .error-text {
123 + display: block;
124 + font-size: 24rpx;
125 + color: #ff4d4f;
126 + margin-top: 8rpx;
127 + }
128 + }
129 + }
130 +
131 + .modal-footer {
132 + padding: 32rpx;
133 + border-top: 1rpx solid #eee;
134 + background-color: #fff;
135 + display: flex;
136 + gap: 24rpx;
137 +
138 + .footer-btn {
139 + flex: 1;
140 + height: 88rpx;
141 + font-size: 32rpx;
142 + border-radius: 44rpx;
143 + }
144 +
145 + .footer-btn-cancel {
146 + // background-color: #f5f5f5;
147 + color: #666;
148 + // border: 1rpx solid #d9d9d9;
149 + }
150 +
151 + .footer-btn-save {
152 + background-color: #ffa500;
153 + color: #fff;
154 + border: 1rpx solid #ffa500;
155 + }
156 + }
157 + }
158 +}
159 +
160 +// NutUI 组件样式覆盖
161 +:deep(.nut-popup) {
162 + .nut-icon {
163 + font-size: 32rpx;
164 + color: #666;
165 + }
166 +}
167 +
168 +:deep(.nut-input) {
169 + .nut-input-value {
170 + font-size: 32rpx;
171 + color: #333;
172 + }
173 +
174 + .nut-input-placeholder {
175 + color: #ccc;
176 + }
177 +}
178 +
179 +:deep(.nut-button) {
180 + &.nut-button--disabled {
181 + background-color: #f5f5f5 !important;
182 + color: #ccc !important;
183 + border-color: #f5f5f5 !important;
184 + }
185 +}
1 +<!--
2 + * @Date: 2022-09-19 14:11:06
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-08-05 15:29:14
5 + * @FilePath: /jgdl/src/pages/collectionSettings/index.vue
6 + * @Description: 收款设置
7 +-->
8 +<template>
9 + <view class="collection-settings">
10 +
11 + <!-- 设置列表 -->
12 + <view class="settings-list">
13 + <!-- 收款账号 -->
14 + <view class="setting-item" @click="openAccountModal">
15 + <view class="setting-left">
16 + <text class="setting-label">收款账号</text>
17 + </view>
18 + <view class="setting-right">
19 + <text class="setting-status" :class="{ 'status-set': accountInfo.bankName }">
20 + {{ accountInfo.bankName ? '已设置' : '未设置' }}
21 + </text>
22 + <text class="arrow">></text>
23 + </view>
24 + </view>
25 +
26 + <!-- 身份信息 -->
27 + <view class="setting-item" @click="openIdentityModal">
28 + <view class="setting-left">
29 + <text class="setting-label">身份信息</text>
30 + </view>
31 + <view class="setting-right">
32 + <text class="setting-status" :class="{ 'status-set': identityInfo.userName }">
33 + {{ identityInfo.userName ? '已设置' : '未设置' }}
34 + </text>
35 + <text class="arrow">></text>
36 + </view>
37 + </view>
38 + </view>
39 +
40 + <!-- 收款账号弹窗 -->
41 + <nut-popup
42 + v-model:visible="showAccountModal"
43 + position="bottom"
44 + :style="{ width: '100%', height: '80%' }"
45 + closeable
46 + close-icon-position="top-right"
47 + @close="closeAccountModal"
48 + >
49 + <view class="modal-content">
50 + <view class="modal-header">
51 + <text class="modal-title">收款账号设置</text>
52 + </view>
53 +
54 + <view class="form-content">
55 + <view class="form-item">
56 + <text class="form-label">银行名称</text>
57 + <nut-input
58 + v-model="tempAccountInfo.bankName"
59 + placeholder="请输入银行名称"
60 + class="form-input"
61 + />
62 + </view>
63 +
64 + <view class="form-item">
65 + <text class="form-label">银行账号</text>
66 + <nut-input
67 + v-model="tempAccountInfo.bankAccount"
68 + placeholder="请输入银行账号"
69 + class="form-input"
70 + type="number"
71 + />
72 + </view>
73 + </view>
74 +
75 + <view class="modal-footer">
76 + <nut-button
77 + type="default"
78 + @click="closeAccountModal"
79 + class="footer-btn footer-btn-cancel"
80 + >
81 + 关闭
82 + </nut-button>
83 + <nut-button
84 + type="primary"
85 + @click="saveAccountInfo"
86 + color="#ffa500"
87 + :disabled="!tempAccountInfo.bankName || !tempAccountInfo.bankAccount"
88 + class="footer-btn footer-btn-save"
89 + >
90 + 保存
91 + </nut-button>
92 + </view>
93 + </view>
94 + </nut-popup>
95 +
96 + <!-- 身份信息弹窗 -->
97 + <nut-popup
98 + v-model:visible="showIdentityModal"
99 + position="bottom"
100 + :style="{ width: '100%', height: '80%' }"
101 + closeable
102 + close-icon-position="top-right"
103 + @close="closeIdentityModal"
104 + >
105 + <view class="modal-content">
106 + <view class="modal-header">
107 + <text class="modal-title">身份信息设置</text>
108 + </view>
109 +
110 + <view class="form-content">
111 + <view class="form-item">
112 + <text class="form-label">用户名称</text>
113 + <nut-input
114 + v-model="tempIdentityInfo.userName"
115 + placeholder="请输入真实姓名"
116 + class="form-input"
117 + />
118 + </view>
119 +
120 + <view class="form-item">
121 + <text class="form-label">身份证号码</text>
122 + <nut-input
123 + v-model="tempIdentityInfo.idCard"
124 + placeholder="请输入身份证号码"
125 + class="form-input"
126 + maxlength="18"
127 + @blur="handleIdCardBlur"
128 + />
129 + <text v-if="idCardError" class="error-text">{{ idCardError }}</text>
130 + </view>
131 + </view>
132 +
133 + <view class="modal-footer">
134 + <nut-button
135 + type="default"
136 + @click="closeIdentityModal"
137 + class="footer-btn footer-btn-cancel"
138 + >
139 + 关闭
140 + </nut-button>
141 + <nut-button
142 + type="primary"
143 + @click="saveIdentityInfo"
144 + color="#ffa500"
145 + :disabled="!tempIdentityInfo.userName || !tempIdentityInfo.idCard || !!idCardError"
146 + class="footer-btn footer-btn-save"
147 + >
148 + 保存
149 + </nut-button>
150 + </view>
151 + </view>
152 + </nut-popup>
153 + </view>
154 +</template>
155 +
156 +<script setup>
157 +import { ref } from "vue";
158 +import Taro from "@tarojs/taro";
159 +import "./index.less";
160 +
161 +/**
162 + * 收款账号信息
163 + */
164 +const accountInfo = ref({
165 + bankName: '',
166 + bankAccount: ''
167 +});
168 +
169 +/**
170 + * 身份信息
171 + */
172 +const identityInfo = ref({
173 + userName: '',
174 + idCard: ''
175 +});
176 +
177 +/**
178 + * 临时收款账号信息(用于弹窗编辑)
179 + */
180 +const tempAccountInfo = ref({
181 + bankName: '',
182 + bankAccount: ''
183 +});
184 +
185 +/**
186 + * 临时身份信息(用于弹窗编辑)
187 + */
188 +const tempIdentityInfo = ref({
189 + userName: '',
190 + idCard: ''
191 +});
192 +
193 +/**
194 + * 弹窗显示状态
195 + */
196 +const showAccountModal = ref(false);
197 +const showIdentityModal = ref(false);
198 +
199 +/**
200 + * 身份证号码错误信息
201 + */
202 +const idCardError = ref('');
203 +
204 +/**
205 + * 身份证号码校验
206 + * @param {string} idCard - 身份证号码
207 + * @returns {boolean} - 是否有效
208 + */
209 +const validateIdCard = (idCard) => {
210 + if (!idCard) {
211 + return { valid: false, error: '请输入身份证号码' };
212 + }
213 +
214 + // 身份证号码正则表达式
215 + const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
216 +
217 + if (!idCardRegex.test(idCard)) {
218 + return { valid: false, error: '身份证号码格式不正确' };
219 + }
220 +
221 + // 校验码验证
222 + const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
223 + const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
224 +
225 + let sum = 0;
226 + for (let i = 0; i < 17; i++) {
227 + sum += parseInt(idCard[i]) * weights[i];
228 + }
229 +
230 + const checkCode = checkCodes[sum % 11];
231 + const lastChar = idCard[17].toUpperCase();
232 +
233 + if (checkCode !== lastChar) {
234 + return { valid: false, error: '身份证号码校验失败' };
235 + }
236 +
237 + return { valid: true, error: '' };
238 +};
239 +
240 +/**
241 + * 处理身份证号码失焦事件
242 + */
243 +const handleIdCardBlur = () => {
244 + const idCard = tempIdentityInfo.value.idCard;
245 + if (idCard) {
246 + const result = validateIdCard(idCard);
247 + idCardError.value = result.error;
248 + } else {
249 + idCardError.value = '';
250 + }
251 +};
252 +
253 +/**
254 + * 打开收款账号弹窗
255 + */
256 +const openAccountModal = () => {
257 + tempAccountInfo.value = { ...accountInfo.value };
258 + showAccountModal.value = true;
259 +};
260 +
261 +/**
262 + * 关闭收款账号弹窗
263 + */
264 +const closeAccountModal = () => {
265 + showAccountModal.value = false;
266 + tempAccountInfo.value = { bankName: '', bankAccount: '' };
267 +};
268 +
269 +/**
270 + * 保存收款账号信息
271 + */
272 +const saveAccountInfo = () => {
273 + if (!tempAccountInfo.value.bankName || !tempAccountInfo.value.bankAccount) {
274 + Taro.showToast({
275 + title: '请填写完整信息',
276 + icon: 'none'
277 + });
278 + return;
279 + }
280 +
281 + accountInfo.value = { ...tempAccountInfo.value };
282 + closeAccountModal();
283 +
284 + Taro.showToast({
285 + title: '保存成功',
286 + icon: 'success'
287 + });
288 +};
289 +
290 +/**
291 + * 打开身份信息弹窗
292 + */
293 +const openIdentityModal = () => {
294 + tempIdentityInfo.value = { ...identityInfo.value };
295 + idCardError.value = '';
296 + showIdentityModal.value = true;
297 +};
298 +
299 +/**
300 + * 关闭身份信息弹窗
301 + */
302 +const closeIdentityModal = () => {
303 + showIdentityModal.value = false;
304 + tempIdentityInfo.value = { userName: '', idCard: '' };
305 + idCardError.value = '';
306 +};
307 +
308 +/**
309 + * 保存身份信息
310 + */
311 +const saveIdentityInfo = () => {
312 + if (!tempIdentityInfo.value.userName || !tempIdentityInfo.value.idCard) {
313 + Taro.showToast({
314 + title: '请填写完整信息',
315 + icon: 'none'
316 + });
317 + return;
318 + }
319 +
320 + const validation = validateIdCard(tempIdentityInfo.value.idCard);
321 + if (!validation.valid) {
322 + Taro.showToast({
323 + title: validation.error,
324 + icon: 'none'
325 + });
326 + return;
327 + }
328 +
329 + identityInfo.value = { ...tempIdentityInfo.value };
330 + closeIdentityModal();
331 +
332 + Taro.showToast({
333 + title: '保存成功',
334 + icon: 'success'
335 + });
336 +};
337 +</script>
338 +
339 +<script>
340 +export default {
341 + name: "collectionSettings",
342 +};
343 +</script>
...@@ -357,13 +357,15 @@ const copyWechat = () => { ...@@ -357,13 +357,15 @@ const copyWechat = () => {
357 */ 357 */
358 const conversation_id = ref('') 358 const conversation_id = ref('')
359 const handleContactSeller = async () => { 359 const handleContactSeller = async () => {
360 - const hasPermission = await checkPermission(PERMISSION_TYPES.CONTACT_SELLER, { 360 + const permissionResult = await checkPermission(PERMISSION_TYPES.CONTACT_SELLER, {
361 showToast: false, 361 showToast: false,
362 autoRedirect: false 362 autoRedirect: false
363 }) 363 })
364 364
365 // 如果没有权限,显示确认弹窗 365 // 如果没有权限,显示确认弹窗
366 - if (!hasPermission) { 366 + if (!permissionResult.hasPermission) {
367 + // 可以通过 permissionResult.missingFields 获取未通过校验的字段
368 + // 可以通过 permissionResult.validFields 获取已通过校验的字段
367 Taro.showModal({ 369 Taro.showModal({
368 title: '提示', 370 title: '提示',
369 content: '联系卖家需要先完善个人信息', 371 content: '联系卖家需要先完善个人信息',
...@@ -441,13 +443,13 @@ const sendMessageToSeller = async () => { ...@@ -441,13 +443,13 @@ const sendMessageToSeller = async () => {
441 * 购买商品 443 * 购买商品
442 */ 444 */
443 const handlePurchase = async () => { 445 const handlePurchase = async () => {
444 - const hasPermission = await checkPermission(PERMISSION_TYPES.BUY_CAR, { 446 + const permissionResult = await checkPermission(PERMISSION_TYPES.BUY_CAR, {
445 showToast: false, 447 showToast: false,
446 autoRedirect: false 448 autoRedirect: false
447 }) 449 })
448 450
449 // 如果没有权限,显示确认弹窗 451 // 如果没有权限,显示确认弹窗
450 - if (!hasPermission) { 452 + if (!permissionResult.hasPermission) {
451 Taro.showModal({ 453 Taro.showModal({
452 title: '提示', 454 title: '提示',
453 content: '购买车辆需要先完善个人信息', 455 content: '购买车辆需要先完善个人信息',
......
...@@ -58,6 +58,12 @@ ...@@ -58,6 +58,12 @@
58 <Right size="18" color="#9ca3af" /> 58 <Right size="18" color="#9ca3af" />
59 </view> 59 </view>
60 60
61 + <view class="menu-item" @click="onCollectionSettings">
62 + <Scan size="20" color="#6b7280" />
63 + <text class="menu-text">收款设置</text>
64 + <Right size="18" color="#9ca3af" />
65 + </view>
66 +
61 <view class="menu-item" @click="onFeedback"> 67 <view class="menu-item" @click="onFeedback">
62 <Message size="20" color="#6b7280" /> 68 <Message size="20" color="#6b7280" />
63 <text class="menu-text">意见反馈</text> 69 <text class="menu-text">意见反馈</text>
...@@ -74,10 +80,10 @@ ...@@ -74,10 +80,10 @@
74 80
75 <!-- 自定义TabBar --> 81 <!-- 自定义TabBar -->
76 <TabBar /> 82 <TabBar />
77 - 83 +
78 <!-- 隐私政策同意弹框 --> 84 <!-- 隐私政策同意弹框 -->
79 - <PrivacyAgreementModal 85 + <PrivacyAgreementModal
80 - v-model:visible="showPrivacyModal" 86 + v-model:visible="showPrivacyModal"
81 @confirm="onPrivacyConfirm" 87 @confirm="onPrivacyConfirm"
82 @cancel="onPrivacyCancel" 88 @cancel="onPrivacyCancel"
83 /> 89 />
...@@ -86,7 +92,7 @@ ...@@ -86,7 +92,7 @@
86 92
87 <script setup> 93 <script setup>
88 import { computed, ref } from 'vue' 94 import { computed, ref } from 'vue'
89 -import { Heart, Clock, Notice, Cart, Message, Tips, Right, StarN } from '@nutui/icons-vue-taro' 95 +import { Heart, Clock, Notice, Cart, Message, Tips, Right, StarN, Scan } from '@nutui/icons-vue-taro'
90 import Taro, { useDidShow } from '@tarojs/taro' 96 import Taro, { useDidShow } from '@tarojs/taro'
91 import TabBar from '@/components/TabBar.vue' 97 import TabBar from '@/components/TabBar.vue'
92 import PrivacyAgreementModal from '@/components/PrivacyAgreementModal.vue' 98 import PrivacyAgreementModal from '@/components/PrivacyAgreementModal.vue'
...@@ -114,7 +120,7 @@ useDidShow(async () => { ...@@ -114,7 +120,7 @@ useDidShow(async () => {
114 const onEditProfile = async () => { 120 const onEditProfile = async () => {
115 // 检查用户是否已完善资料 121 // 检查用户是否已完善资料
116 const hasCompleteProfile = userStore.hasCompleteProfile 122 const hasCompleteProfile = userStore.hasCompleteProfile
117 - 123 +
118 if (hasCompleteProfile) { 124 if (hasCompleteProfile) {
119 // 已完善资料,直接进入编辑页面 125 // 已完善资料,直接进入编辑页面
120 Taro.navigateTo({ 126 Taro.navigateTo({
...@@ -207,6 +213,15 @@ const onFeedback = () => { ...@@ -207,6 +213,15 @@ const onFeedback = () => {
207 } 213 }
208 214
209 /** 215 /**
216 + * 收款设置
217 + */
218 +const onCollectionSettings = () => {
219 + Taro.navigateTo({
220 + url: '/pages/collectionSettings/index'
221 + })
222 +}
223 +
224 +/**
210 * 我的认证车 225 * 我的认证车
211 */ 226 */
212 const onMyAuthCar = () => { 227 const onMyAuthCar = () => {
......
...@@ -1130,24 +1130,33 @@ const loadBrandsModels = async () => { ...@@ -1130,24 +1130,33 @@ const loadBrandsModels = async () => {
1130 // 页面加载时执行 1130 // 页面加载时执行
1131 onMounted(async () => { 1131 onMounted(async () => {
1132 // 检查卖车权限 1132 // 检查卖车权限
1133 - const hasPermission = await checkPermission(PERMISSION_TYPES.SELL_CAR, { 1133 + const permissionResult = await checkPermission(PERMISSION_TYPES.SELL_CAR, {
1134 showToast: false, 1134 showToast: false,
1135 autoRedirect: false 1135 autoRedirect: false
1136 }) 1136 })
1137 1137
1138 // 如果没有权限,显示确认弹窗 1138 // 如果没有权限,显示确认弹窗
1139 - if (!hasPermission) { 1139 + if (!permissionResult.hasPermission) {
1140 + // 可以通过 permissionResult.missingFields 获取未通过校验的字段
1141 + // 可以通过 permissionResult.validFields 获取已通过校验的字段
1140 Taro.showModal({ 1142 Taro.showModal({
1141 - title: '提示', 1143 + title: '温馨提示',
1142 - content: '发布车源需要先完善个人信息', 1144 + content: `您还未填写${permissionResult.missingFields.includes('phone') ? '个人资料' : '收款信息'},展示无法发布`,
1143 - cancelText: '关闭', 1145 + cancelText: '稍后设置',
1144 - confirmText: '前往完善', 1146 + confirmText: '立即设置',
1145 success: (res) => { 1147 success: (res) => {
1146 if (res.confirm) { 1148 if (res.confirm) {
1147 - // 用户点击前往完善,跳转到注册页面 1149 + if (permissionResult.missingFields.includes('phone')) {
1148 - Taro.navigateTo({ 1150 + // 用户信息未填写
1149 - url: '/pages/register/index' 1151 + Taro.navigateTo({
1150 - }) 1152 + url: '/pages/register/index'
1153 + })
1154 + } else if (permissionResult.missingFields.includes('paymentInfo')) {
1155 + // 收款信息未填写
1156 + Taro.navigateTo({
1157 + url: '/pages/collectionSettings/index'
1158 + })
1159 + }
1151 } else { 1160 } else {
1152 // 用户点击关闭,返回上一页 1161 // 用户点击关闭,返回上一页
1153 // Taro.navigateBack() 1162 // Taro.navigateBack()
......
...@@ -76,10 +76,25 @@ const PERMISSION_CONFIG = { ...@@ -76,10 +76,25 @@ const PERMISSION_CONFIG = {
76 * @returns {boolean} 是否满足要求 76 * @returns {boolean} 是否满足要求
77 */ 77 */
78 function checkUserFields(userInfo, checkFields) { 78 function checkUserFields(userInfo, checkFields) {
79 - return checkFields.every(field => { 79 + const result = {
80 + isValid: true,
81 + missingFields: [],
82 + validFields: []
83 + }
84 +
85 + checkFields.forEach(field => {
80 const value = userInfo[field] 86 const value = userInfo[field]
81 - return value && value.toString().trim() !== '' 87 + const isFieldValid = value && value.toString().trim() !== ''
88 +
89 + if (isFieldValid) {
90 + result.validFields.push(field)
91 + } else {
92 + result.missingFields.push(field)
93 + result.isValid = false
94 + }
82 }) 95 })
96 +
97 + return result
83 } 98 }
84 99
85 /** 100 /**
...@@ -93,7 +108,11 @@ function checkUserFields(userInfo, checkFields) { ...@@ -93,7 +108,11 @@ function checkUserFields(userInfo, checkFields) {
93 * @param {Function} options.onFail - 验证失败回调 108 * @param {Function} options.onFail - 验证失败回调
94 * @param {boolean} options.showToast - 是否显示提示(默认true) 109 * @param {boolean} options.showToast - 是否显示提示(默认true)
95 * @param {boolean} options.autoRedirect - 是否自动跳转(默认true) 110 * @param {boolean} options.autoRedirect - 是否自动跳转(默认true)
96 - * @returns {Promise<boolean>} 是否通过权限验证 111 + * @returns {Promise<Object>} 权限检查结果
112 + * @returns {boolean} returns.hasPermission - 是否通过权限验证
113 + * @returns {Array} returns.validFields - 已通过校验的字段
114 + * @returns {Array} returns.missingFields - 未通过校验的字段
115 + * @returns {string} [returns.error] - 错误信息(如果有)
97 */ 116 */
98 export async function checkPermission(permissionType, options = {}) { 117 export async function checkPermission(permissionType, options = {}) {
99 const userStore = useUserStore() 118 const userStore = useUserStore()
...@@ -119,12 +138,16 @@ export async function checkPermission(permissionType, options = {}) { ...@@ -119,12 +138,16 @@ export async function checkPermission(permissionType, options = {}) {
119 } 138 }
120 139
121 // 检查用户字段 140 // 检查用户字段
122 - const hasPermission = checkUserFields(userStore.userInfo, finalConfig.checkFields) 141 + const fieldCheckResult = checkUserFields(userStore.userInfo, finalConfig.checkFields)
123 142
124 - if (hasPermission) { 143 + if (fieldCheckResult.isValid) {
125 // 权限验证成功 144 // 权限验证成功
126 - finalConfig.onSuccess && finalConfig.onSuccess() 145 + finalConfig.onSuccess && finalConfig.onSuccess(fieldCheckResult)
127 - return true 146 + return {
147 + hasPermission: true,
148 + validFields: fieldCheckResult.validFields,
149 + missingFields: []
150 + }
128 } else { 151 } else {
129 // 权限验证失败 152 // 权限验证失败
130 if (finalConfig.showToast) { 153 if (finalConfig.showToast) {
...@@ -148,13 +171,22 @@ export async function checkPermission(permissionType, options = {}) { ...@@ -148,13 +171,22 @@ export async function checkPermission(permissionType, options = {}) {
148 }) 171 })
149 } 172 }
150 173
151 - finalConfig.onFail && finalConfig.onFail() 174 + finalConfig.onFail && finalConfig.onFail(fieldCheckResult)
152 - return false 175 + return {
176 + hasPermission: false,
177 + validFields: fieldCheckResult.validFields,
178 + missingFields: fieldCheckResult.missingFields
179 + }
153 } 180 }
154 } catch (error) { 181 } catch (error) {
155 console.error('权限检查失败:', error) 182 console.error('权限检查失败:', error)
156 - finalConfig.onFail && finalConfig.onFail(error) 183 + finalConfig.onFail && finalConfig.onFail({ error, missingFields: finalConfig.checkFields, validFields: [] })
157 - return false 184 + return {
185 + hasPermission: false,
186 + validFields: [],
187 + missingFields: finalConfig.checkFields,
188 + error: error.message
189 + }
158 } 190 }
159 } 191 }
160 192
......