<template>
|
<view class="page">
|
<view class="page-header">
|
<view class="safe-space" :style="'height:' + navTop + 'px'"></view>
|
<view class="nav-row" :style="'height:' + navHeight + 'px;padding-right:' + navRight + 'px'">
|
<view class="back-button" hover-class="back-button-active" @tap="goBack"><image src="/static/news-assets/arrow-left.svg" mode="aspectFit"></image></view>
|
<text class="nav-title">解除绑定</text>
|
<view class="capsule-space" :style="'width:' + navWidth + 'px'"></view>
|
</view>
|
</view>
|
|
<scroll-view class="content" scroll-y="true" show-scrollbar="false">
|
<view class="content-inner">
|
<view v-if="listLoading" class="list-state"><view class="loading-spinner"></view><text>正在加载已绑定家属</text></view>
|
<view v-else-if="listError" class="list-state error-state"><text>家属列表加载失败</text><text class="retry-text" @tap="loadMembers">重新加载</text></view>
|
<view v-else-if="listLoaded && familyMembers.length == 0" class="list-state"><text>暂无可解绑家属</text></view>
|
<view class="member-card" v-for="member in familyMembers" :key="member.id" hover-class="member-card-active" @tap="toggleMember(member.id)">
|
<view class="member-copy"><text class="member-title">已绑定家属</text><view class="member-info"><text>{{member.name}}</text><text>{{member.mobile}}</text><text class="relation-mark">♡</text><text>{{member.relationship}}</text></view></view>
|
<view class="select-circle" :class="isSelected(member.id) ? 'selected' : ''"><text v-if="isSelected(member.id)">✓</text></view>
|
</view>
|
<view v-if="listLoaded && familyMembers.length > 0" class="unbind-button" hover-class="unbind-button-active" @tap="submitUnbind"><text>解除绑定</text></view>
|
<view class="safe-bottom"></view>
|
</view>
|
</scroll-view>
|
</view>
|
</template>
|
|
<script setup lang="uts">
|
import { apiEnvironment } from '../../config/api.uts'
|
import { getFamilyCards, unbindFamilyCards } from '../../services/portal.uts'
|
import { safeBack } from '../../utils/navigation.uts'
|
|
const navTop = ref(28)
|
const navHeight = ref(32)
|
const navWidth = ref(88)
|
const navRight = ref(10)
|
const selectedIds = ref<string[]>([])
|
const isSubmitting = ref(false)
|
const familyMembers = ref<any[]>([])
|
const listLoading = ref(true)
|
const listLoaded = ref(false)
|
const listError = ref(false)
|
const talentId = ref('')
|
|
onLoad((options: any) => {
|
// #ifdef MP-WEIXIN
|
const capsule = uni.getMenuButtonBoundingClientRect()
|
const systemInfo = uni.getSystemInfoSync()
|
navTop.value = capsule.top
|
navHeight.value = capsule.height
|
navWidth.value = capsule.width
|
navRight.value = systemInfo.windowWidth - capsule.right
|
// #endif
|
talentId.value = options != null && options['talentId'] != null ? options['talentId'] as string : (apiEnvironment == 'development' ? '2' : '')
|
loadMembers()
|
})
|
const loadMembers = () => {
|
listLoading.value = true
|
listLoaded.value = false
|
listError.value = false
|
if (talentId.value == '') { listLoading.value = false; listError.value = true; return }
|
getFamilyCards(talentId.value, (data: any) => {
|
familyMembers.value = (data as any[]).filter((item: any) => item.canUnbind === true).map((item: any) => { item.id = '' + item.id; return item })
|
selectedIds.value = selectedIds.value.filter((id: string) => familyMembers.value.some((item: any) => item.id == id))
|
listLoading.value = false
|
listLoaded.value = true
|
}, () => { listLoading.value = false; listError.value = true })
|
}
|
|
const goBack = () => safeBack('/pages/family-card/family-card')
|
const isSelected = (id: string) => selectedIds.value.indexOf(id) >= 0
|
const toggleMember = (id: string) => {
|
const next = selectedIds.value.slice()
|
const index = next.indexOf(id)
|
if (index >= 0) next.splice(index, 1)
|
else next.push(id)
|
selectedIds.value = next
|
}
|
const submitUnbind = () => {
|
if (isSubmitting.value) return
|
if (selectedIds.value.length == 0) {
|
uni.showToast({ title: '请选择需要解绑的家属', icon: 'none' })
|
return
|
}
|
uni.showModal({
|
title: '解除绑定',
|
content: '确认解除所选家属卡绑定吗?解除后相关权益将不可继续使用。',
|
confirmText: '解除绑定',
|
confirmColor: '#FF5935',
|
success: (result) => {
|
if (!result.confirm) return
|
if (isSubmitting.value) return
|
isSubmitting.value = true
|
unbindSelected(selectedIds.value.slice())
|
}
|
})
|
}
|
const unbindSelected = (ids: string[]) => {
|
unbindFamilyCards(ids, talentId.value, () => { isSubmitting.value = false; uni.showToast({ title: '已解除绑定', icon: 'success' }); setTimeout(() => safeBack('/pages/family-card/family-card'), 700) }, (error) => { isSubmitting.value = false; uni.showToast({ title: error.message, icon: 'none' }) })
|
}
|
</script>
|
|
<style>
|
.page { display: flex; width: 100%; height: 100vh; background-color: #FFFFFF; background-image: linear-gradient(180deg, #FFF0D7 0%, #FFF4E9 205rpx, #FFFFFF 420rpx); flex-direction: column; }
|
.page-header { position: relative; z-index: 10; flex-shrink: 0; }
|
.safe-space { height: 28px; }
|
.nav-row { display: flex; height: 32px; box-sizing: border-box; padding-left: 20rpx; padding-right: 10px; position: relative; flex-direction: row; align-items: center; justify-content: space-between; }
|
.back-button { display: flex; width: 70rpx; height: 64rpx; margin-left: -4rpx; justify-content: center; align-items: center; }
|
.back-button image { width: 36rpx; height: 36rpx; }
|
.back-button-active { opacity: .55; }
|
.nav-title { position: absolute; left: 50%; top: 50%; color: #171B22; font-family: sans-serif; font-size: 37rpx; line-height: 48rpx; font-weight: 700; transform: translate(-50%, -50%); white-space: nowrap; }
|
.capsule-space { width: 88px; height: 100%; flex-shrink: 0; }
|
.content { min-height: 0; flex: 1; }
|
.content-inner { padding: 91rpx 57rpx 0; }
|
.list-state { display:flex; height:420rpx; flex-direction:row; justify-content:center; align-items:center; color:#9199A5; font-size:25rpx; }
|
.error-state { flex-direction:column; }
|
.retry-text { margin-top:22rpx; color:#F26A38; }
|
.loading-spinner { width:28rpx; height:28rpx; margin-right:13rpx; box-sizing:border-box; border:3rpx solid #FFD6C4; border-top-color:#FF6C2B; border-radius:50%; animation:member-loading 720ms linear infinite; }
|
@keyframes member-loading { from { transform:rotate(0deg); } to { transform:rotate(360deg); } }
|
.member-card { display: flex; min-height: 157rpx; margin-bottom: 24rpx; box-sizing: border-box; padding: 27rpx 30rpx 27rpx 39rpx; border-radius: 22rpx; background-color: #FFFFFF; flex-direction: row; align-items: center; box-shadow: 0 9rpx 28rpx rgba(69,80,94,.055); }
|
.member-card-active { background-color: #FFF9F5; }
|
.member-copy { min-width: 0; flex: 1; }
|
.member-title { display: block; color: #26303A; font-size: 27rpx; line-height: 38rpx; font-weight: 700; }
|
.member-info { display: flex; margin-top: 16rpx; color: #788290; font-size: 23rpx; line-height: 32rpx; flex-direction: row; align-items: center; }
|
.member-info text + text { margin-left: 17rpx; }
|
.member-info .relation-mark { margin-left: 26rpx; color: #9BA5B1; font-size: 26rpx; }
|
.select-circle { display: flex; width: 40rpx; height: 40rpx; margin-left: 20rpx; flex-shrink: 0; box-sizing: border-box; border-width: 2rpx; border-style: solid; border-color: #D4DAE1; border-radius: 20rpx; justify-content: center; align-items: center; }
|
.select-circle.selected { border-color: #FF6330; background-color: #FF6330; }
|
.select-circle text { color: #FFFFFF; font-size: 25rpx; line-height: 28rpx; font-weight: 700; }
|
.unbind-button { display: flex; height: 84rpx; margin-top: 46rpx; border-radius: 44rpx; background-image: linear-gradient(90deg, #FF4E35 0%, #FF8318 100%); justify-content: center; align-items: center; }
|
.unbind-button text { color: #FFFFFF; font-size: 28rpx; line-height: 40rpx; font-weight: 700; }
|
.unbind-button-active { opacity: .8; transform: scale(.99); }
|
.safe-bottom { height: 40rpx; height: calc(40rpx + env(safe-area-inset-bottom)); }
|
</style>
|