Browse Source

fix(activity): 修复活动服务商身份判定与角色申请体验

- profile.vue checkVendorStatus 改用 isApprovedActivityProvider,
  兼容 vendor 入驻与服务角色申请两条链路(修用户12「我的团队」仍报未申请)
- service-role-apply.vue:
  * 已通过角色置灰锁定不可重复勾选,提交前过滤
  * 身份证从历史申请记录预填,不要求重传
  * goToCenter 活动服务商跳活动管理页,其余跳供应商中心
  * handleAddRole 保留 applyRecord 用于标记已通过角色
Xiaogang Liao 4 days ago
parent
commit
889d6f699d

+ 4 - 2
cfc-frontend/pages/profile-main/profile.vue

@@ -314,6 +314,7 @@ import {
   vendorStatus
 } from '../../utils/api.js'
 import { BrandColors } from '../../utils/brand-colors.js'
+import { isApprovedActivityProvider } from '../../utils/activity-role.js'
 import fontScaleMixin from '@/mixins/font-scale.js'
 
 export default {
@@ -421,11 +422,12 @@ export default {
     }
   },
   methods: {
-    // 服务商身份:vendorStatus 返回 approved 即为已通过审核的服务商
+    // 服务商身份:兼容两条申请/审核链路(vendor 入驻 / 服务角色申请)
+    // 用 isApprovedActivityProvider 统一判定,避免只认 vendorStatus 漏掉服务角色申请链路
     checkVendorStatus() {
       var self = this
       vendorStatus().then(function(res) {
-        self.isVendor = !!(res && res.data && res.data.vendorStatus === 'approved')
+        self.isVendor = isApprovedActivityProvider((res && res.data) || {})
       }).catch(function() {
         self.isVendor = false
       })

+ 64 - 8
cfc-frontend/pages/profile/service-role-apply.vue

@@ -55,12 +55,13 @@
               <view
                 v-if="!role.placeholder"
                 class="role-card"
-                :class="{ selected: selectedRoles.indexOf(role.key) > -1 }"
+                :class="{ selected: selectedRoles.indexOf(role.key) > -1, approved: isApprovedRole(role.key) }"
                 @click="toggleRole(role.key)"
               >
                 <text class="role-icon">{{ role.icon }}</text>
                 <text class="role-name">{{ role.name }}</text>
-                <view v-if="selectedRoles.indexOf(role.key) > -1" class="check-mark">✓</view>
+                <view v-if="isApprovedRole(role.key)" class="approved-badge">已通过</view>
+                <view v-else-if="selectedRoles.indexOf(role.key) > -1" class="check-mark">✓</view>
               </view>
             </view>
           </view>
@@ -190,6 +191,14 @@ export default {
     hasApprovedRole() {
       return this.applyRecord && this.applyRecord.status === 1
     },
+    // 已通过审核的角色集合(key 数组)——这些角色已开通,不可重复勾选
+    approvedRoles() {
+      if (!this.applyRecord || this.applyRecord.status !== 1 || !this.applyRecord.roles) return []
+      try {
+        const roles = JSON.parse(this.applyRecord.roles)
+        return Array.isArray(roles) ? roles : []
+      } catch (e) { return [] }
+    },
     approvedRoleLabel() {
       if (!this.applyRecord || !this.applyRecord.roles) return ''
       try {
@@ -232,6 +241,8 @@ export default {
         const res = await getMyServiceRoleApply()
         if (res.code === 200 && res.data) {
           this.applyRecord = res.data
+          // 身份证预填:原申请记录里已上传的身份证不再要求重传
+          this.prefillIdCard(this.applyRecord)
           const status = res.data.status
           if (status === 0) {
             // 审核中,展示进度
@@ -248,7 +259,26 @@ export default {
         // 无申请记录,显示表单
       }
     },
+    // 从历史申请记录回填身份证号码与正反面图片(已上传过则不再要求重传)
+    prefillIdCard(record) {
+      if (!record) return
+      if (record.idCard) this.form.idCard = record.idCard
+      if (record.idCardImages) {
+        try {
+          const imgs = JSON.parse(record.idCardImages)
+          if (Array.isArray(imgs) && imgs.length) {
+            if (imgs[0]) this.form.idCardFront = imgs[0]
+            if (imgs[1]) this.form.idCardBack = imgs[1]
+          }
+        } catch (e) {}
+      }
+    },
     toggleRole(key) {
+      // 已通过审核的角色不可重复申请(不可勾选)
+      if (this.approvedRoles.indexOf(key) > -1) {
+        uni.showToast({ title: '该角色已开通,无需重复申请', icon: 'none' })
+        return
+      }
       const idx = this.selectedRoles.indexOf(key)
       if (idx > -1) {
         this.selectedRoles.splice(idx, 1)
@@ -256,6 +286,9 @@ export default {
         this.selectedRoles.push(key)
       }
     },
+    isApprovedRole(key) {
+      return this.approvedRoles.indexOf(key) > -1
+    },
     chooseIdCardImage(side) {
       pickImage({
         count: 1,
@@ -328,8 +361,10 @@ export default {
       this.addressText = e.fullName || ''
     },
     async handleSubmit() {
-      if (this.selectedRoles.length === 0) {
-        uni.showToast({ title: '请至少选择一个角色', icon: 'none' })
+      // 提交前过滤已通过角色(防御:仅提交新增角色,不重复申请已开通角色)
+      const newRoles = (this.selectedRoles || []).filter(r => this.approvedRoles.indexOf(r) === -1)
+      if (newRoles.length === 0) {
+        uni.showToast({ title: '请至少选择一个新增角色', icon: 'none' })
         return
       }
       if (!this.form.idCardFront || !this.form.idCardBack) {
@@ -345,7 +380,7 @@ export default {
       uni.showLoading({ title: '提交中...' })
       try {
         const res = await submitServiceRoleApply({
-          roles: this.selectedRoles,
+          roles: newRoles,
           idCard: this.form.idCard,
           idCardImages: [this.form.idCardFront, this.form.idCardBack],
           certificateImages: this.form.certificateImages,
@@ -388,11 +423,15 @@ export default {
       }
     },
     goToCenter() {
-      uni.redirectTo({ url: '/pages/vendor/center' })
+      // 活动服务商 → 活动管理页(管理 Tab 由权限控制);其余角色 → 供应商中心
+      if (this.approvedRoles.indexOf('activity_provider') > -1) {
+        uni.redirectTo({ url: '/pages/activity/index' })
+      } else {
+        uni.redirectTo({ url: '/pages/vendor/center' })
+      }
     },
     handleAddRole() {
-      // 清空申请状态,展示表单,提示可多选
-      this.applyRecord = null
+      // 保留 applyRecord(用于标记已通过角色),仅切到表单视图;身份证沿用历史预填不重传
       this.showStatusView = false
       this.selectedRoles = []
       uni.showToast({ title: '可多选新增角色', icon: 'none', duration: 2000 })
@@ -590,6 +629,23 @@ export default {
   background: $uni-primary-pale;
   border-color: $brand-primary;
 }
+/* 已通过角色:置灰锁定,显示"已通过"徽标,不可勾选 */
+.role-card.approved {
+  background: #f0f7f0;
+  border-color: #7cc576;
+  opacity: 0.85;
+}
+.approved-badge {
+  position: absolute;
+  top: 8rpx;
+  right: 12rpx;
+  color: #4a9b4a;
+  font-size: 20rpx;
+  font-weight: bold;
+  background: rgba(124, 197, 118, 0.18);
+  border-radius: 8rpx;
+  padding: 4rpx 10rpx;
+}
 .role-icon {
   font-size: 44rpx;
   margin-bottom: 10rpx;