```json
{
"summary": "将步骤条改为竖排布局,从上到下展示4个步骤。每个步骤卡片左侧带步骤指示器和连接线,右侧为卡片内容,形成清晰的时间线风格。保持橘红主色/蓝绿辅色配色体系,uni-app Vue2 + SCSS 结构,适配微信小程序。",
"widget": {
"type": "full-html",
"html": "<template>\n <view class=\"deposit-setting\">\n <!-- ===== 顶部导航 ===== -->\n <view class=\"nav-bar\">\n <view class=\"nav-back\" @click=\"onBack\">\n <image src=\"/static/icons/chevron-left.svg\" mode=\"aspectFit\" class=\"nav-icon\"></image>\n </view>\n <text class=\"nav-title\">押金设置</text>\n <view class=\"nav-placeholder\"></view>\n </view>\n\n <scroll-view class=\"main-scroll\" scroll-y>\n <!-- ===== 竖排步骤条容器 ===== -->\n <view class=\"steps-vertical\">\n <!-- ====== 步骤1: 选择设备 ====== -->\n <view class=\"step-wrapper\" :class=\"{ locked: stepLocked[0], active: currentStep === 0 }\">\n <!-- 左侧时间线 -->\n <view class=\"timeline-col\">\n <view class=\"timeline-dot\" :class=\"getDotClass(0)\">\n <image v-if=\"isCompleted(0)\" src=\"/static/icons/circle-check.svg\" mode=\"aspectFit\" class=\"dot-check\"></image>\n <text v-else class=\"dot-num\">1</text>\n </view>\n <view class=\"timeline-line\" :class=\"getTimelineLineClass(0)\"></view>\n </view>\n <!-- 右侧内容卡片 -->\n <view class=\"step-content\">\n <view class=\"card\" @click=\"currentStep = 0\">\n <view class=\"card-header\">\n <image src=\"/static/icons/mobile-screen-button.svg\" mode=\"aspectFit\" class=\"card-icon\"></image>\n <text class=\"card-title\">步骤1: 选择设备</text>\n <view class=\"step-badge\" :class=\"getBadgeClass(0)\">\n <text class=\"badge-text\">{{ getBadgeText(0) }}</text>\n </view>\n </view>\n <view class=\"divider\"></view>\n <view class=\"card-body\">\n <!-- 输入 + 按钮 -->\n <view class=\"input-row\">\n <view class=\"input-wrapper\">\n <input\n class=\"custom-input\"\n v-model=\"deviceNumber\"\n placeholder=\"请输入设备号\"\n placeholder-class=\"input-placeholder\"\n :disabled=\"stepLocked[0]\"\n />\n </view>\n <view class=\"btn-group\">\n <view class=\"btn btn-scan\" @click.stop=\"scanDevice\" :class=\"{ disabled: stepLocked[0] }\">\n <image src=\"/static/icons/qrcode.svg\" mode=\"aspectFit\" class=\"btn-icon\"></image>\n <text>扫码</text>\n </view>\n <view class=\"btn btn-query\" @click.stop=\"queryDevice\" :class=\"{ disabled: stepLocked[0] }\">\n <image src=\"/static/icons/magnifying-glass.svg\" mode=\"aspectFit\" class=\"btn-icon\"></image>\n <text>查询</text>\n </view>\n </view>\n </view>\n\n <!-- 设备信息 -->\n <view class=\"device-info-panel\" v-if=\"deviceInfo\">\n <view class=\"panel-header\">\n <image src=\"/static/icons/circle-info.svg\" mode=\"aspectFit\" class=\"info-icon\"></image>\n <text class=\"panel-title\">设备信息</text>\n </view>\n <view class=\"info-row\">\n <text class=\"info-label\">终端号码</text>\n <text class=\"info-value\">{{ deviceInfo.terminalNumber }}</text>\n </view>\n <view class=\"info-row\">\n <text class=\"info-label\">终端平台</text>\n <view class=\"info-tag\">\n <text class=\"tag-text\">{{ deviceInfo.platform }}</text>\n </view>\n </view>\n <view class=\"info-row last\">\n <text class=\"info-label\">设备名称</text>\n <text class=\"info-value\">{{ deviceInfo.name }}</text>\n </view>\n </view>\n\n <!-- 空提示 -->\n <view class=\"empty-hint\" v-if=\"!deviceInfo && deviceNumber\">\n <image src=\"/static/icons/circle-exclamation.svg\" mode=\"aspectFit\" class=\"empty-icon\"></image>\n <text class=\"empty-text\">未查询到设备信息,请检查设备号</text>\n </view>\n </view>\n <view class=\"divider\"></view>\n <view class=\"card-footer\">\n <view class=\"btn-next\" @click.stop=\"goNext(0)\" :class=\"{ disabled: !canStep1Proceed }\">\n <text>下一步</text>\n <image src=\"/static/icons/chevron-right.svg\" mode=\"aspectFit\" class=\"next-icon\"></image>\n </view>\n </view>\n </view>\n </view>\n </view>\n\n <!-- ====== 步骤2: 押金模式 ====== -->\n <view class=\"step-wrapper\" :class=\"{ locked: stepLocked[1], active: currentStep === 1 }\">\n <!-- 左侧时间线 -->\n <view class=\"timeline-col\">\n <view class=\"timeline-dot\" :class=\"getDotClass(1)\">\n <image v-if=\"isCompleted(1)\" src=\"/static/icons/circle-check.svg\" mode=\"aspectFit\" class=\"dot-check\"></image>\n <text v-else class=\"dot-num\">2</text>\n </view>\n <view class=\"timeline-line\" :class=\"getTimelineLineClass(1)\"></view>\n </view>\n <!-- 右侧内容卡片 -->\n <view class=\"step-content\">\n <view class=\"card\" @click=\"currentStep = 1\">\n <view class=\"card-header\">\n <image src=\"/static/icons/coins.svg\" mode=\"aspectFit\" class=\"card-icon\"></image>\n <text class=\"card-title\">步骤2: 押金模式选择</text>\n <view class=\"step-badge\" :class=\"getBadgeClass(1)\">\n <text class=\"badge-text\">{{ getBadgeText(1) }}</text>\n </view>\n </view>\n <view class=\"divider\"></view>\n <view class=\"card-body\">\n <view class=\"picker-wrapper\">\n <text class=\"field-label\">押金模式</text>\n <picker\n mode=\"selector\"\n :range=\"depositModes\"\n :value=\"depositModeIndex\"\n @change=\"onDepositModeChange\"\n :disabled=\"stepLocked[1]\"\n >\n <view class=\"picker-trigger\" :class=\"{ 'has-value': depositModeIndex >= 0, disabled: stepLocked[1] }\">\n <text v-if=\"depositModeIndex >= 0\" class=\"picker-text\">{{ depositModes[depositModeIndex] }}</text>\n <text v-else class=\"picker-placeholder\">请选择押金模式</text>\n <image src=\"/static/icons/chevron-down.svg\" mode=\"aspectFit\" class=\"picker-arrow\"></image>\n </view>\n </picker>\n </view>\n\n <!-- 模式说明 -->\n <view class=\"mode-detail\" v-if=\"depositModeIndex >= 0\">\n <view class=\"mode-detail-header\">\n <image src=\"/static/icons/circle-info.svg\" mode=\"aspectFit\" class=\"detail-icon\"></image>\n <text class=\"detail-title\">模式说明</text>\n </view>\n <text class=\"detail-desc\">{{ depositModeDesc[depositModeIndex] }}</text>\n <view class=\"detail-amount\">\n <text class=\"amount-label\">押金金额</text>\n <text class=\"amount-value\">{{ depositModeAmount[depositModeIndex] }}</text>\n </view>\n </view>\n </view>\n <view class=\"divider\"></view>\n <view class=\"card-footer\">\n <view class=\"footer-btns\">\n <view class=\"btn-prev\" @click.stop=\"goPrev\">\n <image src=\"/static/icons/chevron-left.svg\" mode=\"aspectFit\" class=\"prev-icon\"></image>\n <text>上一步</text>\n </view>\n <view class=\"btn-next\" @click.stop=\"goNext(1)\" :class=\"{ disabled: !canStep2Proceed }\">\n <text>下一步</text>\n <image src=\"/static/icons/chevron-right.svg\" mode=\"aspectFit\" class=\"next-icon\"></image>\n </view>\n </view>\n </view>\n </view>\n </view>\n </view>\n\n <!-- ====== 步骤3: 核对确认 ====== -->\n <view class=\"step-wrapper\" :class=\"{ locked: stepLocked[2], active: currentStep === 2 }\">\n <!-- 左侧时间线 -->\n <view class=\"timeline-col\">\n <view class=\"timeline-dot\" :class=\"getDotClass(2)\">\n <image v-if=\"isCompleted(2)\" src=\"/static/icons/circle-check.svg\" mode=\"aspectFit\" class=\"dot-check\"></image>\n <text v-else class=\"dot-num\">3</text>\n </view>\n <view class=\"timeline-line\" :class=\"getTimelineLineClass(2)\"></view>\n </view>\n <!-- 右侧内容卡片 -->\n <view class=\"step-content\">\n <view class=\"card\" @click=\"currentStep = 2\">\n <view class=\"card-header\">\n <image src=\"/static/icons/clipboard-list.svg\" mode=\"aspectFit\" class=\"card-icon\"></image>\n <text class=\"card-title\">步骤3: 核对确认</text>\n <view class=\"step-badge\" :class=\"getBadgeClass(2)\">\n <text class=\"badge-text\">{{ getBadgeText(2) }}</text>\n </view>\n </view>\n <view class=\"divider\"></view>\n <view class=\"card-body\">\n <view class=\"confirm-section\">\n <view class=\"confirm-item\">\n <view class=\"confirm-label-row\">\n <image src=\"/static/icons/mobile-screen-button.svg\" mode=\"aspectFit\" class=\"confirm-item-icon\"></image>\n <text class=\"confirm-label\">设备号</text>\n </view>\n <view class=\"confirm-value-box\">\n <text class=\"confirm-value\">{{ deviceNumber || '未输入' }}</text>\n </view>\n </view>\n <view class=\"confirm-divider\"></view>\n <view class=\"confirm-item\">\n <view class=\"confirm-label-row\">\n <image src=\"/static/icons/coins.svg\" mode=\"aspectFit\" class=\"confirm-item-icon\"></image>\n <text class=\"confirm-label\">押金模式</text>\n </view>\n <view class=\"confirm-value-box\">\n <text class=\"confirm-value\" v-if=\"depositModeIndex >= 0\">{{ depositModes[depositModeIndex] }}</text>\n <text class=\"confirm-value muted\" v-else>未选择</text>\n </view>\n </view>\n <view class=\"confirm-divider\"></view>\n <view class=\"confirm-item\" v-if=\"depositModeIndex >= 0\">\n <view class=\"confirm-label-row\">\n <image src=\"/static/icons/sack-dollar.svg\" mode=\"aspectFit\" class=\"confirm-item-icon\"></image>\n <text class=\"confirm-label\">押金金额</text>\n </view>\n <view class=\"confirm-value-box\">\n <text class=\"confirm-value amount\">{{ depositModeAmount[depositModeIndex] }}</text>\n </view>\n </view>\n </view>\n <view class=\"confirm-notice\">\n <image src=\"/static/icons/triangle-exclamation.svg\" mode=\"aspectFit\" class=\"notice-icon\"></image>\n <text class=\"notice-text\">请仔细核对以上信息,确认无误后提交</text>\n </view>\n </view>\n <view class=\"divider\"></view>\n <view class=\"card-footer\">\n <view class=\"footer-btns\">\n <view class=\"btn-prev\" @click.stop=\"goPrev\">\n <image src=\"/static/icons/chevron-left.svg\" mode=\"aspectFit\" class=\"prev-icon\"></image>\n <text>上一步</text>\n </view>\n <view class=\"btn-submit\" @click.stop=\"submitConfirm\">\n <image src=\"/static/icons/check.svg\" mode=\"aspectFit\" class=\"submit-icon\"></image>\n <text>确认提交</text>\n </view>\n </view>\n </view>\n </view>\n </view>\n </view>\n\n <!-- ====== 步骤4: 订单支付码 ====== -->\n <view class=\"step-wrapper\" :class=\"{ locked: stepLocked[3], active: currentStep === 3, last: true }\">\n <!-- 左侧时间线(无底部连线) -->\n <view class=\"timeline-col\">\n <view class=\"timeline-dot\" :class=\"getDotClass(3)\">\n <image v-if=\"isCompleted(3)\" src=\"/static/icons/circle-check.svg\" mode=\"aspectFit\" class=\"dot-check\"></image>\n <text v-else class=\"dot-num\">4</text>\n </view>\n <!-- 最后一步不显示连线 -->\n </view>\n <!-- 右侧内容卡片 -->\n <view class=\"step-content\">\n <view class=\"card\" @click=\"currentStep = 3\">\n <view class=\"card-header\">\n <image src=\"/static/icons/qrcode.svg\" mode=\"aspectFit\" class=\"card-icon\"></image>\n <text class=\"card-title\">步骤4: 订单支付码</text>\n <view class=\"step-badge\" :class=\"getBadgeClass(3)\">\n <text class=\"badge-text\">{{ getBadgeText(3) }}</text>\n </view>\n </view>\n <view class=\"divider\"></view>\n <view class=\"card-body\">\n <view class=\"success-banner\">\n <image src=\"/static/icons/circle-check.svg\" mode=\"aspectFit\" class=\"success-icon\"></image>\n <text class=\"success-text\">押金设置提交成功!</text>\n </view>\n <view class=\"order-info\">\n <view class=\"order-row\">\n <text class=\"order-label\">订单编号</text>\n <text class=\"order-value\">{{ orderCode }}</text>\n </view>\n <view class=\"order-row\">\n <text class=\"order-label\">设备编号</text>\n <text class=\"order-value\">{{ deviceNumber }}</text>\n </view>\n <view class=\"order-row\">\n <text class=\"order-label\">押金模式</text>\n <text class=\"order-value\" v-if=\"depositModeIndex >= 0\">{{ depositModes[depositModeIndex] }}</text>\n </view>\n <view class=\"order-row highlight\">\n <text class=\"order-label\">应付金额</text>\n <text class=\"order-value amt\">{{ depositModeIndex >= 0 ? depositModeAmount[depositModeIndex] : '' }}</text>\n </view>\n </view>\n <view class=\"qr-section\">\n <text class=\"qr-hint\">请使用微信/支付宝扫码支付</text>\n <view class=\"qr-box\">\n <image src=\"/static/icons/qrcode.svg\" mode=\"aspectFit\" class=\"qr-placeholder\"></image>\n <view class=\"qr-overlay\">\n <image src=\"/static/icons/check.svg\" mode=\"aspectFit\" class=\"qr-check\"></image>\n </view>\n </view>\n <text class=\"qr-expire\">支付码有效期:30分钟</text>\n </view>\n </view>\n <view class=\"divider\"></view>\n <view class=\"card-footer\">\n <view class=\"footer-btns\">\n <view class=\"btn-reset\" @click.stop=\"resetAll\">\n <image src=\"/static/icons/arrow-rotate-left.svg\" mode=\"aspectFit\" class=\"reset-icon\"></image>\n <text>重新设置</text>\n </view>\n <view class=\"btn-done\" @click.stop=\"onDone\">\n <text>完成</text>\n <image src=\"/static/icons/check.svg\" mode=\"aspectFit\" class=\"done-icon\"></image>\n </view>\n </view>\n </view>\n </view>\n </view>\n </view>\n </view>\n\n <!-- 底部留白 -->\n <view class=\"bottom-spacer\"></view>\n </scroll-view>\n </view>\n</template>\n\n<script>\nexport default {\n name: 'DepositSetting',\n data() {\n return {\n currentStep: 0,\n steps: ['选择设备', '押金模式', '核对确认', '支付码'],\n stepLocked: [false, false, false, false],\n deviceNumber: '',\n deviceInfo: null,\n depositModeIndex: -1,\n depositModes: [\n '固定押金 - 标准版',\n '按天计费 - 灵活版',\n '信用免押 - 优质版',\n '阶梯押金 - 阶梯版'\n ],\n depositModeDesc: [\n '一次性收取固定押金,退租时全额返还(无损坏情况下)。适合短期租赁场景,简单透明。',\n '按实际使用天数计算押金,每日收取少量押金费用,使用更灵活。适合长期租赁场景。',\n '基于信用评估结果,优质信用用户可免交押金。需要授权信用查询,审核通过后生效。',\n '根据设备价值和租赁周期,押金金额分阶梯递增。设备价值越高、周期越长,押金相应增加。'\n ],\n depositModeAmount: [\n '¥ 500.00',\n '¥ 10.00/天',\n '¥ 0.00(免押金)',\n '¥ 300.00 ~ ¥ 1,000.00'\n ],\n orderCode: '',\n submitted: false\n }\n },\n computed: {\n canStep1Proceed() {\n return !!this.deviceInfo\n },\n canStep2Proceed() {\n return this.depositModeIndex >= 0\n }\n },\n methods: {\n /* ---- 步骤状态 ---- */\n isCompleted(i) {\n return this.stepLocked[i]\n },\n getDotClass(i) {\n if (this.isCompleted(i)) return 'dot-completed'\n if (i === this.currentStep) return 'dot-active'\n return 'dot-pending'\n },\n getTimelineLineClass(i) {\n if (i >= 3) return ''\n if (this.isCompleted(i)) return 'line-completed'\n return 'line-pending'\n },\n getBadgeClass(i) {\n if (this.isCompleted(i)) return 'badge-completed'\n if (i === this.currentStep) return 'badge-active'\n return 'badge-pending'\n },\n getBadgeText(i) {\n if (this.isCompleted(i)) return '已完成'\n if (i === this.currentStep) return '进行中'\n return '待处理'\n },\n\n /* ---- 步骤1: 扫码 ---- */\n scanDevice() {\n if (this.stepLocked[0]) return\n uni.showToast({ title: '正在打开扫码...', icon: 'none', duration: 1500 })\n setTimeout(() => {\n this.deviceNumber = 'SN' + Math.random().toString(36).substr(2, 8).toUpperCase()\n this.queryDevice()\n }, 800)\n },\n\n /* ---- 步骤1: 查询设备 ---- */\n queryDevice() {\n if (!this.deviceNumber.trim()) {\n uni.showToast({ title: '请输入设备号', icon: 'none' })\n return\n }\n if (this.stepLocked[0]) return\n uni.showLoading({ title: '查询中...' })\n setTimeout(() => {\n uni.hideLoading()\n this.deviceInfo = {\n terminalNumber: this.deviceNumber,\n platform: 'Android 12 · 鸿蒙系统',\n name: '智能共享终端 - ' + this.deviceNumber.slice(-4)\n }\n uni.showToast({ title: '查询成功', icon: 'success' })\n }, 1000)\n },\n\n /* ---- 下一步 ---- */\n goNext(stepIdx) {\n if (stepIdx === 0 && !this.canStep1Proceed) {\n uni.showToast({ title: '请先查询设备信息', icon: 'none' })\n return\n }\n if (stepIdx === 1 && !this.canStep2Proceed) {\n uni.showToast({ title: '请选择押金模式', icon: 'none' })\n return\n }\n this.stepLocked[stepIdx] = true\n this.currentStep = stepIdx + 1\n },\n\n /* ---- 上一步 ---- */\n goPrev() {\n if (this.currentStep > 0) {\n this.stepLocked[this.currentStep] = false\n this.currentStep--\n if (this.currentStep === 1) {\n this.stepLocked[1] = false\n }\n if (this.currentStep === 0) {\n this.stepLocked[0] = false\n this.stepLocked[1] = false\n }\n }\n },\n\n /* ---- 步骤2: 押金模式选择 ---- */\n onDepositModeChange(e) {\n this.depositModeIndex = e.detail.value\n },\n\n /* ---- 步骤3: 提交确认 ---- */\n submitConfirm() {\n uni.showLoading({ title: '提交中...' })\n setTimeout(() => {\n uni.hideLoading()\n this.orderCode = 'DEP' + Date.now().toString().slice(-10)\n this.submitted = true\n this.stepLocked[2] = true\n this.currentStep = 3\n this.stepLocked[3] = false\n uni.showToast({ title: '提交成功', icon: 'success' })\n }, 1500)\n },\n\n /* ---- 重置 ---- */\n resetAll() {\n uni.showModal({\n title: '提示',\n content: '确定要重新设置押金吗?',\n success: (res) => {\n if (res.confirm) {\n this.currentStep = 0\n this.stepLocked = [false, false, false, false]\n this.deviceNumber = ''\n this.deviceInfo = null\n this.depositModeIndex = -1\n this.orderCode = ''\n this.submitted = false\n }\n }\n })\n },\n\n /* ---- 返回 ---- */\n onBack() {\n if (this.currentStep > 0) {\n uni.showModal({\n title: '提示',\n content: '当前设置尚未完成,确定要返回吗?',\n success: (res) => {\n if (res.confirm) uni.navigateBack()\n }\n })\n } else {\n uni.navigateBack()\n }\n },\n\n /* ---- 完成 ---- */\n onDone() {\n uni.showToast({ title: '设置完成', icon: 'success' })\n setTimeout(() => uni.navigateBack(), 1500)\n }\n }\n}\n</script>\n\n<style lang=\"scss\">\n// ====== 变量 ======\n$color-primary: #FF5A1F;\n$color-primary-dark: #E04A0E;\n$color-orange: #FF8C42;\n$color-orange-light: #FFB088;\n$color-blue: #2E7DF6;\n$color-blue-light: #6EA8FE;\n$color-blue-dark: #1A5CC7;\n$color-green: #10B981;\n$color-green-light: #34D399;\n$color-green-dark: #059669;\n$color-bg: #F5F6FA;\n$color-card: #FFFFFF;\n$color-text: #1A1A2E;\n$color-text-secondary: #6B7280;\n$color-text-muted: #9CA3AF;\n$color-border: #E5E5E5;\n$radius-sm: 8rpx;\n$radius-md: 16rpx;\n$radius-lg: 24rpx;\n$radius-full: 50%;\n$shadow-sm: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);\n$shadow-md: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);\n$shadow-glow-orange: 0 0 20rpx rgba(255, 90, 31, 0.35);\n$shadow-glow-green: 0 0 20rpx rgba(16, 185, 129, 0.35);\n\n// ====== 页面 ======\n.deposit-setting {\n display: flex;\n flex-direction: column;\n height: 100vh;\n background: $color-bg;\n position: relative;\n\n // 导航栏\n .nav-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20rpx 30rpx;\n background: linear-gradient(135deg, $color-primary 0%, $color-orange 100%);\n position: relative;\n z-index: 10;\n box-shadow: 0 4rpx 20rpx rgba(255, 90, 31, 0.3);\n\n &::after {\n content: '';\n position: absolute;\n bottom: -20rpx;\n left: 0;\n right: 0;\n height: 40rpx;\n background: linear-gradient(to bottom, rgba(255, 90, 31, 0.15), transparent);\n pointer-events: none;\n }\n\n .nav-back {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 60rpx;\n height: 60rpx;\n border-radius: $radius-full;\n background: rgba(255, 255, 255, 0.2);\n transition: all 0.3s ease;\n\n &:active {\n background: rgba(255, 255, 255, 0.35);\n transform: scale(0.92);\n }\n\n .nav-icon {\n width: 32rpx;\n height: 32rpx;\n }\n }\n\n .nav-title {\n font-size: 34rpx;\n font-weight: 700;\n color: #FFFFFF;\n letter-spacing: 2rpx;\n text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15);\n }\n\n .nav-placeholder {\n width: 60rpx;\n }\n }\n\n // 主滚动区域\n .main-scroll {\n flex: 1;\n padding: 30rpx 24rpx;\n -webkit-overflow-scrolling: touch;\n }\n\n // ====== 竖排步骤容器 ======\n .steps-vertical {\n display: flex;\n flex-direction: column;\n gap: 0;\n }\n\n // ====== 每一步包装 ======\n .step-wrapper {\n display: flex;\n flex-direction: row;\n align-items: stretch;\n margin-bottom: 0;\n position: relative;\n\n &.last .timeline-line {\n display: none;\n }\n }\n\n // ====== 左侧时间线列 ======\n .timeline-col {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 72rpx;\n flex-shrink: 0;\n padding: 36rpx 0;\n position: relative;\n z-index: 2;\n\n .timeline-dot {\n width: 56rpx;\n height: 56rpx;\n border-radius: $radius-full;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);\n position: relative;\n z-index: 2;\n\n .dot-num {\n font-size: 24rpx;\n font-weight: 700;\n color: #FFFFFF;\n }\n\n .dot-check {\n width: 30rpx;\n height: 30rpx;\n }\n\n // 已完成\n &.dot-completed {\n background: linear-gradient(135deg, $color-green 0%, $color-green-light 100%);\n box-shadow: 0 0 0 4rpx rgba(16, 185, 129, 0.2), $shadow-glow-green;\n transform: scale(1);\n }\n\n // 当前激活\n &.dot-active {\n background: linear-gradient(135deg, $color-primary 0%, $color-orange 100%);\n box-shadow: 0 0 0 4rpx rgba(255, 90, 31, 0.2), $shadow-glow-orange;\n transform: scale(1.08);\n animation: pulse-dot 2s ease-in-out infinite;\n\n @keyframes pulse-dot {\n 0%, 100% { box-shadow: 0 0 0 4rpx rgba(255, 90, 31, 0.2), $shadow-glow-orange; }\n 50% { box-shadow: 0 0 0 8rpx rgba(255, 90, 31, 0.12), 0 0 28rpx rgba(255, 90, 31, 0.5); }\n }\n }\n\n // 待处理\n &.dot-pending {\n background: linear-gradient(135deg, #D1D5DB 0%, #E5E7EB 100%);\n box-shadow: none;\n }\n }\n\n // 纵向连接线\n .timeline-line {\n width: 4rpx;\n flex: 1;\n margin: 4rpx 0;\n min-height: 20rpx;\n transition: all 0.5s ease;\n\n &.line-completed {\n background: linear-gradient(180deg, $color-green 0%, $color-green-light 100%);\n }\n\n &.line-pending {\n background: linear-gradient(180deg, #D1D5DB 0%, #E5E7EB 100%);\n }\n }\n }\n\n // ====== 右侧内容区 ======\n .step-content {\n flex: 1;\n padding-left: 16rpx;\n padding-bottom: 28rpx;\n }\n\n // ====== 卡片 ======\n .card {\n background: $color-card;\n border-radius: $radius-lg;\n box-shadow: $shadow-md;\n overflow: hidden;\n transition: all 0.3s ease;\n animation: fade-slide-up 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both;\n border: 2rpx solid transparent;\n\n // 当前步骤高亮边框\n .step-wrapper.active & {\n border-color: rgba(255, 90, 31, 0.25);\n box-shadow: 0 4rpx 24rpx rgba(255, 90, 31, 0.1), $shadow-md;\n }\n\n @keyframes fade-slide-up {\n from {\n opacity: 0;\n transform: translateY(30rpx);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .card-header {\n display: flex;\n align-items: center;\n padding: 28rpx 28rpx 0;\n\n .card-icon {\n width: 38rpx;\n height: 38rpx;\n margin-right: 14rpx;\n flex-shrink: 0;\n }\n\n .card-title {\n font-size: 28rpx;\n font-weight: 700;\n color: $color-text;\n letter-spacing: 1rpx;\n flex: 1;\n }\n\n // 步骤徽标\n .step-badge {\n padding: 6rpx 16rpx;\n border-radius: 20rpx;\n font-size: 20rpx;\n font-weight: 600;\n margin-left: 12rpx;\n flex-shrink: 0;\n\n &.badge-completed {\n background: rgba(16, 185, 129, 0.12);\n color: $color-green-dark;\n }\n\n &.badge-active {\n background: rgba(255, 90, 31, 0.12);\n color: $color-primary;\n }\n\n &.badge-pending {\n background: #F3F4F6;\n color: $color-text-muted;\n }\n\n .badge-text {\n font-size: 20rpx;\n font-weight: 600;\n }\n }\n }\n\n .divider {\n height: 1rpx;\n background: $color-border;\n margin: 20rpx 28rpx;\n }\n\n .card-body {\n padding: 0 28rpx 10rpx;\n }\n\n .card-footer {\n padding: 16rpx 28rpx 24rpx;\n }\n }\n\n // ====== 步骤1: 输入行 ======\n .input-row {\n display: flex;\n flex-direction: column;\n gap: 18rpx;\n\n .input-wrapper {\n width: 100%;\n\n .custom-input {\n width: 100%;\n height: 84rpx;\n background: #F8F9FB;\n border: 2rpx solid $color-border;\n border-radius: $radius-md;\n padding: 0 28rpx;\n font-size: 26rpx;\n color: $color-text;\n transition: all 0.3s ease;\n box-sizing: border-box;\n\n &:focus {\n border-color: $color-primary;\n box-shadow: 0 0 0 4rpx rgba(255, 90, 31, 0.12);\n background: #FFFFFF;\n }\n }\n\n .input-placeholder {\n color: $color-text-muted;\n font-size: 26rpx;\n }\n }\n\n .btn-group {\n display: flex;\n gap: 16rpx;\n\n .btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10rpx;\n height: 76rpx;\n border-radius: $radius-md;\n font-size: 26rpx;\n font-weight: 600;\n transition: all 0.25s ease;\n\n &:active {\n transform: scale(0.96);\n }\n\n &.disabled {\n opacity: 0.5;\n pointer-events: none;\n }\n\n .btn-icon {\n width: 34rpx;\n height: 34rpx;\n }\n\n &.btn-scan {\n background: $color-card;\n border: 2rpx solid $color-primary;\n color: $color-primary;\n\n &:active {\n background: rgba(255, 90, 31, 0.06);\n }\n }\n\n &.btn-query {\n background: linear-gradient(135deg, $color-blue 0%, $color-blue-light 100%);\n border: none;\n color: #FFFFFF;\n box-shadow: 0 4rpx 12rpx rgba(46, 125, 246, 0.3);\n\n &:active {\n box-shadow: 0 2rpx 6rpx rgba(46, 125, 246, 0.2);\n }\n }\n }\n }\n }\n\n // ====== 设备信息面板 ======\n .device-info-panel {\n margin-top: 24rpx;\n background: linear-gradient(135deg, #F0F9FF 0%, #EFF6FF 100%);\n border: 1rpx solid rgba(46, 125, 246, 0.2);\n border-radius: $radius-md;\n padding: 22rpx;\n animation: fade-slide-up 0.4s ease both;\n\n .panel-header {\n display: flex;\n align-items: center;\n margin-bottom: 18rpx;\n\n .info-icon {\n width: 30rpx;\n height: 30rpx;\n margin-right: 10rpx;\n }\n\n .panel-title {\n font-size: 24rpx;\n font-weight: 600;\n color: $color-blue-dark;\n }\n }\n\n .info-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12rpx 0;\n border-bottom: 1rpx solid rgba(46, 125, 246, 0.08);\n\n &.last {\n border-bottom: none;\n }\n\n .info-label {\n font-size: 24rpx;\n color: $color-text-secondary;\n }\n\n .info-value {\n font-size: 24rpx;\n font-weight: 600;\n color: $color-text;\n }\n\n .info-tag {\n display: flex;\n align-items: center;\n background: linear-gradient(135deg, $color-green 0%, $color-green-light 100%);\n padding: 4rpx 16rpx;\n border-radius: 20rpx;\n\n .tag-text {\n font-size: 20rpx;\n color: #FFFFFF;\n font-weight: 600;\n }\n }\n }\n }\n\n // ====== 空提示 ======\n .empty-hint {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10rpx;\n margin-top: 24rpx;\n padding: 24rpx 0;\n\n .empty-icon {\n width: 34rpx;\n height: 34rpx;\n }\n\n .empty-text {\n font-size: 24rpx;\n color: #F59E0B;\n }\n }\n\n // ====== 步骤2: 下拉 ======\n .picker-wrapper {\n .field-label {\n display: block;\n font-size: 26rpx;\n font-weight: 600;\n color: $color-text;\n margin-bottom: 14rpx;\n }\n\n .picker-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 84rpx;\n background: #F8F9FB;\n border: 2rpx solid $color-border;\n border-radius: $radius-md;\n padding: 0 28rpx;\n transition: all 0.3s ease;\n box-sizing: border-box;\n\n &:active {\n border-color: $color-primary;\n background: #FFFFFF;\n }\n\n &.has-value {\n border-color: $color-primary;\n background: #FFFFFF;\n }\n\n &.disabled {\n opacity: 0.6;\n pointer-events: none;\n }\n\n .picker-text {\n font-size: 26rpx;\n color: $color-text;\n font-weight: 500;\n }\n\n .picker-placeholder {\n font-size: 26rpx;\n color: $color-text-muted;\n }\n\n .picker-arrow {\n width: 30rpx;\n height: 30rpx;\n transition: transform 0.3s ease;\n }\n }\n }\n\n // ====== 押金模式说明 ======\n .mode-detail {\n margin-top: 24rpx;\n background: linear-gradient(135deg, #FFF7ED 0%, #FFFBEB 100%);\n border: 1rpx solid rgba(255, 90, 31, 0.15);\n border-radius: $radius-md;\n padding: 22rpx;\n animation: fade-slide-up 0.35s ease both;\n\n .mode-detail-header {\n display: flex;\n align-items: center;\n margin-bottom: 14rpx;\n\n .detail-icon {\n width: 28rpx;\n height: 28rpx;\n margin-right: 10rpx;\n }\n\n .detail-title {\n font-size: 24rpx;\n font-weight: 600;\n color: $color-primary-dark;\n }\n }\n\n .detail-desc {\n font-size: 22rpx;\n color: $color-text-secondary;\n line-height: 1.6;\n margin-bottom: 14rpx;\n }\n\n .detail-amount {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14rpx 18rpx;\n background: rgba(255, 255, 255, 0.7);\n border-radius: $radius-sm;\n\n .amount-label {\n font-size: 24rpx;\n color: $color-text-secondary;\n }\n\n .amount-value {\n font-size: 30rpx;\n font-weight: 700;\n color: $color-primary;\n }\n }\n }\n\n // ====== 步骤3: 核对 ======\n .confirm-section {\n background: linear-gradient(135deg, #FAFAFA 0%, #F8F9FB 100%);\n border-radius: $radius-md;\n padding: 22rpx;\n\n .confirm-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16rpx 0;\n\n .confirm-label-row {\n display: flex;\n align-items: center;\n gap: 10rpx;\n\n .confirm-item-icon {\n width: 30rpx;\n height: 30rpx;\n }\n\n .confirm-label {\n font-size: 24rpx;\n color: $color-text-secondary;\n font-weight: 500;\n }\n }\n\n .confirm-value-box {\n .confirm-value {\n font-size: 26rpx;\n font-weight: 600;\n color: $color-text;\n\n &.muted {\n color: $color-text-muted;\n font-weight: 400;\n }\n\n &.amount {\n color: $color-primary;\n font-size: 30rpx;\n }\n }\n }\n }\n\n .confirm-divider {\n height: 1rpx;\n background: $color-border;\n margin: 0 0 0 40rpx;\n }\n }\n\n .confirm-notice {\n display: flex;\n align-items: center;\n gap: 10rpx;\n margin-top: 20rpx;\n padding: 18rpx 22rpx;\n background: linear-gradient(135deg, #FEF3C7 0%, #FDE68A 100%);\n border-radius: $radius-sm;\n border-left: 6rpx solid #F59E0B;\n\n .notice-icon {\n width: 30rpx;\n height: 30rpx;\n flex-shrink: 0;\n }\n\n .notice-text {\n font-size: 22rpx;\n color: #92400E;\n line-height: 1.5;\n }\n }\n\n // ====== 步骤4: 成功 & 支付码 ======\n .success-banner {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 14rpx;\n padding: 24rpx 0 8rpx;\n animation: fade-slide-up 0.5s ease both;\n\n .success-icon {\n width: 44rpx;\n height: 44rpx;\n }\n\n .success-text {\n font-size: 30rpx;\n font-weight: 700;\n color: $color-green-dark;\n }\n }\n\n .order-info {\n margin-top: 22rpx;\n background: linear-gradient(135deg, #F0FFF4 0%, #ECFDF5 100%);\n border: 1rpx solid rgba(16, 185, 129, 0.2);\n border-radius: $radius-md;\n padding: 22rpx;\n\n .order-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14rpx 0;\n border-bottom: 1rpx solid rgba(16, 185, 129, 0.1);\n\n &:last-child {\n border-bottom: none;\n }\n\n &.highlight {\n background: rgba(16, 185, 129, 0.08);\n margin: 6rpx -10rpx 0;\n padding: 14rpx 10rpx;\n border-radius: $radius-sm;\n border-bottom: none;\n\n .order-value.amt {\n font-size: 34rpx;\n font-weight: 800;\n color: $color-primary;\n }\n }\n\n .order-label {\n font-size: 24rpx;\n color: $color-text-secondary;\n }\n\n .order-value {\n font-size: 24rpx;\n font-weight: 600;\n color: $color-text;\n\n &.amt {\n font-size: 32rpx;\n font-weight: 700;\n color: $color-primary;\n }\n }\n }\n }\n\n .qr-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-top: 28rpx;\n padding-bottom: 10rpx;\n\n .qr-hint {\n font-size: 24rpx;\n color: $color-text-secondary;\n margin-bottom: 20rpx;\n }\n\n .qr-box {\n position: relative;\n width: 300rpx;\n height: 300rpx;\n background: #FFFFFF;\n border: 4rpx solid $color-border;\n border-radius: $radius-md;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 22rpx;\n box-shadow: $shadow-md;\n\n .qr-placeholder {\n width: 100%;\n height: 100%;\n }\n\n .qr-overlay {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 66rpx;\n height: 66rpx;\n background: $color-primary;\n border-radius: $radius-sm;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 4rpx 12rpx rgba(255, 90, 31, 0.4);\n\n .qr-check {\n width: 36rpx;\n height: 36rpx;\n }\n }\n }\n\n .qr-expire {\n font-size: 20rpx;\n color: $color-text-muted;\n margin-top: 18rpx;\n }\n }\n\n // ====== 底部按钮组 ======\n .footer-btns {\n display: flex;\n gap: 16rpx;\n\n .btn-prev,\n .btn-next,\n .btn-submit,\n .btn-reset,\n .btn-done {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10rpx;\n height: 82rpx;\n border-radius: $radius-md;\n font-size: 28rpx;\n font-weight: 600;\n transition: all 0.25s ease;\n\n &:active {\n transform: scale(0.96);\n }\n\n &.disabled {\n opacity: 0.4;\n pointer-events: none;\n }\n\n .prev-icon,\n .next-icon,\n .submit-icon,\n .reset-icon,\n .done-icon {\n width: 30rpx;\n height: 30rpx;\n }\n }\n\n .btn-next,\n .btn-done {\n flex: 1;\n background: linear-gradient(135deg, $color-primary 0%, $color-orange 100%);\n color: #FFFFFF;\n box-shadow: 0 4rpx 16rpx rgba(255, 90, 31, 0.35);\n\n &:active {\n box-shadow: 0 2rpx 8rpx rgba(255, 90, 31, 0.2);\n }\n\n &.disabled {\n background: linear-gradient(135deg, #D1D5DB 0%, #E5E7EB 100%);\n box-shadow: none;\n }\n }\n\n .btn-prev {\n background: $color-card;\n border: 2rpx solid $color-border;\n color: $color-text-secondary;\n padding: 0 24rpx;\n\n &:active {\n background: #F8F9FB;\n border-color: #D1D5DB;\n }\n }\n\n .btn-submit {\n flex: 1;\n background: linear-gradient(135deg, $color-green 0%, $color-green-light 100%);\n color: #FFFFFF;\n box-shadow: 0 4rpx 16rpx rgba(16, 185, 129, 0.35);\n font-size: 30rpx;\n\n &:active {\n box-shadow: 0 2rpx 8rpx rgba(16, 185, 129, 0.2);\n }\n }\n\n .btn-reset {\n background: $color-card;\n border: 2rpx solid $color-border;\n color: $color-text-secondary;\n padding: 0 24rpx;\n\n &:active {\n background: #F8F9FB;\n border-color: #D1D5DB;\n }\n }\n }\n\n // ====== 独立下一步按钮 ======\n .btn-next {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10rpx;\n width: 100%;\n height: 82rpx;\n background: linear-gradient(135deg, $color-primary 0%, $color-orange 100%);\n color: #FFFFFF;\n border-radius: $radius-md;\n font-size: 28rpx;\n font-weight: 600;\n transition: all 0.25s ease;\n box-shadow: 0 4rpx 16rpx rgba(255, 90, 31, 0.35);\n\n &:active {\n transform: scale(0.97);\n box-shadow: 0 2rpx 8rpx rgba(255, 90, 31, 0.2);\n }\n\n &.disabled {\n background: linear-gradient(135deg, #D1D5DB 0%, #E5E7EB 100%);\n box-shadow: none;\n\n &:active {\n transform: none;\n }\n }\n\n .next-icon {\n width: 30rpx;\n height: 30rpx;\n }\n }\n\n // ====== 底部留白 ======\n .bottom-spacer {\n height: 40rpx;\n }\n}\n</style>"
},
"next": [
"添加数据校验动画",
"接入真实扫码API",
"增加语音播报反馈",
"添加步骤编辑功能",
"接入支付网关二维码"
],
"breakpoint": "xs"
}
```
推理
用户希望步骤条从横排改为竖排布局,从上到下展示。这是一个移动端页面,我需要调整步骤条的结构,让它变成纵向排列,同时保持卡片布局和原有功能不变。
需要修改的地方:
1. `steps-bar` 改为纵向 flex 布局
2. 步骤指示器、连接线都改为纵向
3. 整体样式调整
我来重新设计这个竖排步骤条布局。
需要修改的地方:
1. `steps-bar` 改为纵向 flex 布局
2. 步骤指示器、连接线都改为纵向
3. 整体样式调整
我来重新设计这个竖排步骤条布局。
角色
assistant
content
total_tokens
30346
summary
将步骤条改为竖排布局,从上到下展示4个步骤。每个步骤卡片左侧带步骤指示器和连接线,右侧为卡片内容,形成清晰的时间线风格。保持橘红主色/蓝绿辅色配色体系,uni-app Vue2 + SCSS 结构,适配微信小程序。
uiParsing
关闭