1079 行
27 KiB
Vue
1079 行
27 KiB
Vue
<template>
|
||
<view class="workspace-container">
|
||
<!-- 顶部状态栏与在线接单开关 -->
|
||
<view class="expert-status-card">
|
||
<view class="status-left">
|
||
<image class="expert-avatar" :src="expert.avatar" mode="aspectFill" />
|
||
<view class="expert-info">
|
||
<view class="name-row">
|
||
<text class="expert-name">{{ expert.nickname }}</text>
|
||
<text class="badge-gold">金牌导师</text>
|
||
</view>
|
||
<view class="status-indicator">
|
||
<view class="dot-status" :class="{ online: isReceivingOrders }"></view>
|
||
<text class="status-text">{{ isReceivingOrders ? '接单中 (派单池活跃)' : '已打烊休息' }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="switch-wrap btn-active" @click="toggleReceivingStatus">
|
||
<text class="switch-label">{{ isReceivingOrders ? '停止接单' : '开启接单' }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 今日经营看板 -->
|
||
<view class="stats-board">
|
||
<view class="stat-col">
|
||
<text class="stat-label">今日预计收益 (元)</text>
|
||
<text class="stat-val green-val">¥{{ todayIncome }}</text>
|
||
</view>
|
||
<view class="stat-divider"></view>
|
||
<view class="stat-col">
|
||
<text class="stat-label">今日履约单数</text>
|
||
<text class="stat-val">3 单</text>
|
||
</view>
|
||
<view class="stat-divider"></view>
|
||
<view class="stat-col">
|
||
<text class="stat-label">待签到核销</text>
|
||
<text class="stat-val gold-val">1 人</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 核心亮点功能:4 位数字门票现场核销中心 (严格依 UIUX 规范 4.2 落地) -->
|
||
<view class="verify-section-card">
|
||
<view class="sec-head">
|
||
<view class="title-wrap">
|
||
<image class="sec-svg" :src="ICONS.ticket" mode="aspectFit" />
|
||
<text class="sec-title">4位活动门票现场核销工具</text>
|
||
</view>
|
||
<text class="sec-sub">车队房主专属</text>
|
||
</view>
|
||
|
||
<view class="verify-box">
|
||
<text class="input-tips">输入参与人出示的 4 位门票码完成入队签到:</text>
|
||
|
||
<!-- 4位独立方块卡槽 PIN Code -->
|
||
<view class="pin-slots-wrap" :class="{ shake: isCodeError }">
|
||
<view
|
||
v-for="i in 4"
|
||
:key="i"
|
||
class="pin-slot"
|
||
:class="{
|
||
filled: inputDigits.length >= i,
|
||
active: inputDigits.length === i - 1,
|
||
error: isCodeError
|
||
}"
|
||
>
|
||
<text class="pin-char">{{ inputDigits[i - 1] || '' }}</text>
|
||
<view class="cursor-line" v-if="inputDigits.length === i - 1"></view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 自定义九宫格大按键数字键盘 (触控热区 >= 88rpx,无原生键盘遮挡) -->
|
||
<view class="keypad-grid">
|
||
<view v-for="num in [1, 2, 3, 4, 5, 6, 7, 8, 9]" :key="num" class="key-btn btn-active" @click="pressKey(num)">
|
||
<text class="key-num">{{ num }}</text>
|
||
</view>
|
||
<view class="key-btn action-key btn-active" @click="clearCode">
|
||
<image class="key-svg" :src="ICONS.clearKey" mode="aspectFit" />
|
||
<text class="action-text">清空</text>
|
||
</view>
|
||
<view class="key-btn btn-active" @click="pressKey(0)">
|
||
<text class="key-num">0</text>
|
||
</view>
|
||
<view class="key-btn action-key btn-active" @click="backspace">
|
||
<image class="key-svg" :src="ICONS.deleteKey" mode="aspectFit" />
|
||
<text class="action-text">删除</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="quick-demo" @click="fillDemoCode">
|
||
<text>点击自动填入演示码 [8392] 并触发核销</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 参与人身份核验确认卡弹窗 (Modal) -->
|
||
<view class="verify-modal-mask" v-if="showConfirmModal" @click.self="showConfirmModal = false">
|
||
<view class="verify-modal-content">
|
||
<view class="modal-header">
|
||
<text class="modal-title">参与人身份核验确认</text>
|
||
<view class="badge-ready">门票有效</view>
|
||
</view>
|
||
|
||
<view class="participant-card">
|
||
<image class="part-avatar" :src="verifiedParticipant.avatar" mode="aspectFill" />
|
||
<view class="part-info">
|
||
<view class="part-name-row">
|
||
<text class="part-name">{{ verifiedParticipant.nickname }}</text>
|
||
<text class="part-tag">VIP 黄金玩家</text>
|
||
</view>
|
||
<text class="part-activity">活动:{{ verifiedParticipant.activityTitle }}</text>
|
||
<view class="part-code-row">
|
||
<text class="label">核销码:</text>
|
||
<text class="code-val highlight">{{ verifiedParticipant.code }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="verify-fee-box">
|
||
<text class="fee-k">已付 AA 分摊款:</text>
|
||
<text class="fee-v">¥{{ verifiedParticipant.fee }}</text>
|
||
</view>
|
||
|
||
<view class="modal-actions">
|
||
<button class="btn-cancel btn-active" @click="showConfirmModal = false">取消</button>
|
||
<button class="btn-confirm-checkin btn-active" @click="confirmCheckin">确认核销签到</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 待抢订单池 (即时匹配派单) -->
|
||
<view class="section-card">
|
||
<view class="sec-head">
|
||
<view class="title-wrap">
|
||
<image class="sec-svg" :src="ICONS.bolt" mode="aspectFit" />
|
||
<text class="sec-title">即时抢单派单池 ({{ poolOrders.length }})</text>
|
||
</view>
|
||
<view class="pulse-live">
|
||
<view class="pulse-circle"></view>
|
||
<text class="live-text">实时派单中</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="pool-list" v-if="poolOrders.length > 0">
|
||
<view v-for="order in poolOrders" :key="order.id" class="pool-card">
|
||
<view class="pool-top">
|
||
<text class="game-tag">{{ order.game }}</text>
|
||
<text class="pool-price">¥{{ order.price }}</text>
|
||
</view>
|
||
<text class="pool-desc">{{ order.desc }}</text>
|
||
<view class="pool-foot">
|
||
<text class="pool-time">倒计时: {{ order.countdown }}s</text>
|
||
<button class="btn-grab btn-active" @click="grabOrder(order)">立即抢单</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-else class="empty-pool">
|
||
<text>暂无待抢订单,保持在线有更高派单权重</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 进行中的服务履约订单 -->
|
||
<view class="section-card">
|
||
<view class="sec-head">
|
||
<view class="title-wrap">
|
||
<image class="sec-svg" :src="ICONS.orderList" mode="aspectFit" />
|
||
<text class="sec-title">进行中履约服务 ({{ activeOrders.length }})</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="active-list">
|
||
<view v-for="order in activeOrders" :key="order.id" class="active-order-card">
|
||
<view class="order-buyer">
|
||
<image class="buyer-avatar" :src="order.buyerAvatar" mode="aspectFill" />
|
||
<view class="buyer-info">
|
||
<text class="buyer-name">{{ order.buyerName }}</text>
|
||
<text class="service-tag">{{ order.serviceTitle }} · {{ order.hours }}小时</text>
|
||
</view>
|
||
<text class="order-amount">¥{{ order.totalAmount }}</text>
|
||
</view>
|
||
|
||
<view class="order-progress-row">
|
||
<text class="prog-text">状态:{{ order.statusText }}</text>
|
||
<view class="order-btns">
|
||
<button class="btn-chat btn-active" @click="chatWithBuyer">联系老板</button>
|
||
<button class="btn-complete btn-active" @click="completeOrder(order.id)">
|
||
申请验收结算
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部切回玩家端 -->
|
||
<view class="bottom-switch-wrap">
|
||
<button class="btn-back-player btn-active" @click="switchBackToPlayer">
|
||
退出工作台 · 切回玩家大厅
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref } from 'vue';
|
||
import { ICONS } from '@/common/icons.js';
|
||
import { EXPERTS_LIST } from '@/common/mock.js';
|
||
|
||
const expert = ref(EXPERTS_LIST[0]);
|
||
const isReceivingOrders = ref(true);
|
||
const todayIncome = ref(175);
|
||
const inputDigits = ref([]);
|
||
const isCodeError = ref(false);
|
||
const showConfirmModal = ref(false);
|
||
|
||
const verifiedParticipant = ref({
|
||
nickname: '电竞萌新小可爱',
|
||
avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=150&h=150&fit=crop',
|
||
activityTitle: 'AA制五排王者百星车队',
|
||
code: '8392',
|
||
fee: '25.00'
|
||
});
|
||
|
||
const poolOrders = ref([
|
||
{
|
||
id: 'pool_101',
|
||
game: '王者荣耀',
|
||
price: 35,
|
||
desc: 'QQ区/星耀1晋级赛冲王者/需连麦/射手或辅助',
|
||
countdown: 48
|
||
},
|
||
{
|
||
id: 'pool_102',
|
||
game: '和平精英',
|
||
price: 45,
|
||
desc: '微信区/四排海岛/刚枪上分/kd保4以上',
|
||
countdown: 32
|
||
},
|
||
{
|
||
id: 'pool_103',
|
||
game: '美食陪吃',
|
||
price: 68,
|
||
desc: '朝阳大悦城海底捞/周末饭搭子/消费现场AA/需守时礼貌',
|
||
countdown: 56
|
||
}
|
||
]);
|
||
|
||
const activeOrders = ref([
|
||
{
|
||
id: 'ord_active_1',
|
||
buyerName: '超能电竞玩家',
|
||
buyerAvatar: 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=150&h=150&fit=crop',
|
||
serviceTitle: '排位包胜率',
|
||
hours: 2,
|
||
totalAmount: 70,
|
||
statusText: '正在开黑连麦对局中'
|
||
},
|
||
{
|
||
id: 'ord_active_2',
|
||
buyerName: '北京吃货小张',
|
||
buyerAvatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=150&h=150&fit=crop',
|
||
serviceTitle: '火锅探店饭搭子',
|
||
hours: 2,
|
||
totalAmount: 136,
|
||
statusText: '已核销4位码入座,服务中'
|
||
}
|
||
]);
|
||
|
||
const toggleReceivingStatus = () => {
|
||
isReceivingOrders.value = !isReceivingOrders.value;
|
||
uni.showToast({
|
||
title: isReceivingOrders.value ? '已开启在线接单通道!' : '已打烊停止接单',
|
||
icon: 'none'
|
||
});
|
||
};
|
||
|
||
const pressKey = (num) => {
|
||
if (inputDigits.value.length >= 4) return;
|
||
inputDigits.value.push(num);
|
||
if (inputDigits.value.length === 4) {
|
||
verifyInputCode();
|
||
}
|
||
};
|
||
|
||
const backspace = () => {
|
||
if (inputDigits.value.length > 0) {
|
||
inputDigits.value.pop();
|
||
isCodeError.value = false;
|
||
}
|
||
};
|
||
|
||
const clearCode = () => {
|
||
inputDigits.value = [];
|
||
isCodeError.value = false;
|
||
};
|
||
|
||
const fillDemoCode = () => {
|
||
inputDigits.value = [8, 3, 9, 2];
|
||
verifyInputCode();
|
||
};
|
||
|
||
const verifyInputCode = () => {
|
||
const codeStr = inputDigits.value.join('');
|
||
if (codeStr === '8392') {
|
||
isCodeError.value = false;
|
||
showConfirmModal.value = true;
|
||
} else {
|
||
isCodeError.value = true;
|
||
uni.showToast({
|
||
title: `核销码 [${codeStr}] 无效或已被核销`,
|
||
icon: 'none'
|
||
});
|
||
setTimeout(() => {
|
||
isCodeError.value = false;
|
||
}, 800);
|
||
}
|
||
};
|
||
|
||
const confirmCheckin = () => {
|
||
showConfirmModal.value = false;
|
||
todayIncome.value += 25;
|
||
inputDigits.value = [];
|
||
uni.showToast({
|
||
title: '核销成功!¥25已释放到账',
|
||
icon: 'success'
|
||
});
|
||
};
|
||
|
||
const grabOrder = (order) => {
|
||
uni.showToast({
|
||
title: `抢单成功!已接单 ¥${order.price}`,
|
||
icon: 'success'
|
||
});
|
||
poolOrders.value = poolOrders.value.filter(o => o.id !== order.id);
|
||
activeOrders.value.push({
|
||
id: `ord_grabbed_${Date.now()}`,
|
||
buyerName: '特惠预约老板',
|
||
buyerAvatar: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=150&h=150&fit=crop',
|
||
serviceTitle: order.game,
|
||
hours: 1,
|
||
totalAmount: order.price,
|
||
statusText: '待双方进房连麦'
|
||
});
|
||
};
|
||
|
||
const chatWithBuyer = () => {
|
||
uni.showToast({ title: '已连接买家专属密聊通道', icon: 'none' });
|
||
};
|
||
|
||
const completeOrder = (id) => {
|
||
uni.showModal({
|
||
title: '确认提交服务验收',
|
||
content: '服务已完成?提交后买家确认无误或 24 小时内未异议将自动解冻订单资金打入钱包。',
|
||
confirmColor: '#10B981',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
activeOrders.value = activeOrders.value.filter(o => o.id !== id);
|
||
uni.showToast({ title: '已申请验收结算!', icon: 'success' });
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
const switchBackToPlayer = () => {
|
||
uni.switchTab({
|
||
url: '/pages/user/index'
|
||
});
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.workspace-container {
|
||
min-height: 100vh;
|
||
background-color: #0A0F1D;
|
||
padding: 24rpx 32rpx calc(60rpx + env(safe-area-inset-bottom));
|
||
}
|
||
|
||
.expert-status-card {
|
||
background: linear-gradient(135deg, #1E1B4B 0%, #151D30 100%);
|
||
border: 1px solid rgba(99, 102, 241, 0.3);
|
||
border-radius: 28rpx;
|
||
padding: 28rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 24rpx;
|
||
box-shadow: 0 8rpx 28rpx rgba(99, 102, 241, 0.25);
|
||
|
||
.status-left {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.expert-avatar {
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
border-radius: 50rpx;
|
||
border: 4rpx solid #6366F1;
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
.expert-info {
|
||
.name-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
margin-bottom: 8rpx;
|
||
|
||
.expert-name {
|
||
font-size: 30rpx;
|
||
font-weight: 700;
|
||
color: #FFF;
|
||
}
|
||
|
||
.badge-gold {
|
||
font-size: 18rpx;
|
||
background: linear-gradient(135deg, #F59E0B, #D97706);
|
||
color: #FFF;
|
||
padding: 2rpx 10rpx;
|
||
border-radius: 6rpx;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.status-indicator {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
|
||
.dot-status {
|
||
width: 12rpx;
|
||
height: 12rpx;
|
||
border-radius: 50%;
|
||
background: #64748B;
|
||
|
||
&.online {
|
||
background: #10B981;
|
||
box-shadow: 0 0 10rpx #10B981;
|
||
}
|
||
}
|
||
|
||
.status-text {
|
||
font-size: 22rpx;
|
||
color: #94A3B8;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.switch-wrap {
|
||
background: rgba(255, 255, 255, 0.08);
|
||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||
border-radius: 32rpx;
|
||
padding: 10rpx 24rpx;
|
||
|
||
.switch-label {
|
||
font-size: 22rpx;
|
||
color: #E2E8F0;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
}
|
||
|
||
.stats-board {
|
||
background-color: #151D30;
|
||
border-radius: 24rpx;
|
||
padding: 24rpx;
|
||
margin-bottom: 24rpx;
|
||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-around;
|
||
|
||
.stat-col {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
|
||
.stat-label {
|
||
font-size: 20rpx;
|
||
color: #94A3B8;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.stat-val {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #F8FAFC;
|
||
font-variant-numeric: tabular-nums;
|
||
|
||
&.green-val {
|
||
color: #10B981;
|
||
}
|
||
&.gold-val {
|
||
color: #F59E0B;
|
||
}
|
||
}
|
||
}
|
||
|
||
.stat-divider {
|
||
width: 1px;
|
||
height: 60rpx;
|
||
background: rgba(255, 255, 255, 0.08);
|
||
}
|
||
}
|
||
|
||
.verify-section-card {
|
||
background: linear-gradient(135deg, rgba(16, 185, 129, 0.12) 0%, rgba(21, 29, 48, 1) 100%);
|
||
border: 1px solid rgba(16, 185, 129, 0.35);
|
||
border-radius: 24rpx;
|
||
padding: 28rpx;
|
||
margin-bottom: 24rpx;
|
||
box-shadow: 0 8rpx 24rpx rgba(16, 185, 129, 0.2);
|
||
|
||
.sec-head {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20rpx;
|
||
|
||
.title-wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
|
||
.sec-svg {
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
}
|
||
|
||
.sec-title {
|
||
font-size: 26rpx;
|
||
font-weight: 700;
|
||
color: #10B981;
|
||
}
|
||
}
|
||
|
||
.sec-sub {
|
||
font-size: 20rpx;
|
||
color: #64748B;
|
||
}
|
||
}
|
||
|
||
.verify-box {
|
||
.input-tips {
|
||
font-size: 22rpx;
|
||
color: #94A3B8;
|
||
display: block;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.pin-slots-wrap {
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: 20rpx;
|
||
margin: 20rpx 0 28rpx;
|
||
|
||
&.shake {
|
||
animation: errorShake 0.4s ease-in-out;
|
||
}
|
||
|
||
.pin-slot {
|
||
width: 104rpx;
|
||
height: 116rpx;
|
||
background: #0A0F1D;
|
||
border: 2rpx solid rgba(255, 255, 255, 0.12);
|
||
border-radius: 18rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
position: relative;
|
||
transition: all 0.2s ease;
|
||
|
||
&.filled {
|
||
border-color: rgba(16, 185, 129, 0.6);
|
||
background: rgba(16, 185, 129, 0.08);
|
||
}
|
||
|
||
&.active {
|
||
border-color: #10B981;
|
||
box-shadow: 0 0 16rpx rgba(16, 185, 129, 0.4);
|
||
}
|
||
|
||
&.error {
|
||
border-color: #EF4444;
|
||
background: rgba(239, 68, 68, 0.1);
|
||
color: #EF4444;
|
||
}
|
||
|
||
.pin-char {
|
||
font-size: 46rpx;
|
||
font-weight: 800;
|
||
color: #10B981;
|
||
font-family: 'Courier New', Courier, monospace;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
.cursor-line {
|
||
width: 4rpx;
|
||
height: 48rpx;
|
||
background: #10B981;
|
||
border-radius: 2rpx;
|
||
animation: cursorBlink 1s infinite;
|
||
}
|
||
}
|
||
}
|
||
|
||
.keypad-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 16rpx;
|
||
|
||
.key-btn {
|
||
height: 96rpx;
|
||
background: rgba(255, 255, 255, 0.04);
|
||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||
border-radius: 16rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.key-num {
|
||
font-size: 38rpx;
|
||
font-weight: 700;
|
||
color: #F8FAFC;
|
||
font-family: 'Courier New', Courier, monospace;
|
||
}
|
||
|
||
&.action-key {
|
||
background: rgba(255, 255, 255, 0.02);
|
||
|
||
.key-svg {
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
}
|
||
|
||
.action-text {
|
||
font-size: 18rpx;
|
||
color: #94A3B8;
|
||
margin-top: 4rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.quick-demo {
|
||
margin-top: 20rpx;
|
||
text-align: center;
|
||
font-size: 22rpx;
|
||
color: #818CF8;
|
||
padding: 10rpx;
|
||
background: rgba(99, 102, 241, 0.1);
|
||
border: 1px dashed rgba(99, 102, 241, 0.3);
|
||
border-radius: 12rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 参与人身份核验确认卡弹窗样式 */
|
||
.verify-modal-mask {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.75);
|
||
backdrop-filter: blur(8px);
|
||
display: flex;
|
||
align-items: flex-end;
|
||
z-index: 999;
|
||
animation: fadeIn 0.2s ease-out;
|
||
|
||
.verify-modal-content {
|
||
width: 100%;
|
||
background: #151D30;
|
||
border-top: 2rpx solid rgba(16, 185, 129, 0.45);
|
||
border-radius: 36rpx 36rpx 0 0;
|
||
padding: 36rpx 32rpx calc(40rpx + env(safe-area-inset-bottom));
|
||
box-shadow: 0 -12rpx 40rpx rgba(0, 0, 0, 0.6);
|
||
animation: slideUp 0.25s cubic-bezier(0.16, 1, 0.3, 1);
|
||
|
||
.modal-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 28rpx;
|
||
|
||
.modal-title {
|
||
font-size: 30rpx;
|
||
font-weight: 700;
|
||
color: #F8FAFC;
|
||
}
|
||
|
||
.badge-ready {
|
||
font-size: 20rpx;
|
||
background: rgba(16, 185, 129, 0.15);
|
||
border: 1px solid rgba(16, 185, 129, 0.35);
|
||
color: #10B981;
|
||
padding: 4rpx 14rpx;
|
||
border-radius: 8rpx;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.participant-card {
|
||
background: rgba(255, 255, 255, 0.03);
|
||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||
border-radius: 20rpx;
|
||
padding: 24rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 20rpx;
|
||
|
||
.part-avatar {
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
border-radius: 50rpx;
|
||
border: 2rpx solid #10B981;
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
.part-info {
|
||
flex: 1;
|
||
|
||
.part-name-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
margin-bottom: 8rpx;
|
||
|
||
.part-name {
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
color: #FFF;
|
||
}
|
||
|
||
.part-tag {
|
||
font-size: 18rpx;
|
||
background: linear-gradient(135deg, #F59E0B, #D97706);
|
||
color: #FFF;
|
||
padding: 2rpx 10rpx;
|
||
border-radius: 6rpx;
|
||
}
|
||
}
|
||
|
||
.part-activity {
|
||
font-size: 22rpx;
|
||
color: #94A3B8;
|
||
display: block;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.part-code-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
|
||
.label {
|
||
font-size: 20rpx;
|
||
color: #64748B;
|
||
}
|
||
|
||
.code-val {
|
||
font-size: 28rpx;
|
||
font-weight: 800;
|
||
color: #10B981;
|
||
letter-spacing: 2rpx;
|
||
font-family: 'Courier New', Courier, monospace;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.verify-fee-box {
|
||
background: rgba(16, 185, 129, 0.08);
|
||
border: 1px solid rgba(16, 185, 129, 0.2);
|
||
border-radius: 16rpx;
|
||
padding: 20rpx 24rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 32rpx;
|
||
|
||
.fee-k {
|
||
font-size: 24rpx;
|
||
color: #94A3B8;
|
||
}
|
||
|
||
.fee-v {
|
||
font-size: 34rpx;
|
||
font-weight: 800;
|
||
color: #10B981;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
}
|
||
|
||
.modal-actions {
|
||
display: flex;
|
||
gap: 20rpx;
|
||
|
||
.btn-cancel {
|
||
flex: 1;
|
||
background: rgba(255, 255, 255, 0.08);
|
||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||
color: #94A3B8;
|
||
font-size: 26rpx;
|
||
height: 84rpx;
|
||
line-height: 84rpx;
|
||
border-radius: 20rpx;
|
||
}
|
||
|
||
.btn-confirm-checkin {
|
||
flex: 2;
|
||
background: linear-gradient(135deg, #10B981 0%, #059669 100%);
|
||
color: #FFF;
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
height: 84rpx;
|
||
line-height: 84rpx;
|
||
border-radius: 20rpx;
|
||
box-shadow: 0 4rpx 20rpx rgba(16, 185, 129, 0.4);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
@keyframes cursorBlink {
|
||
0%, 100% { opacity: 1; }
|
||
50% { opacity: 0; }
|
||
}
|
||
|
||
@keyframes errorShake {
|
||
0%, 100% { transform: translateX(0); }
|
||
20%, 60% { transform: translateX(-10rpx); }
|
||
40%, 80% { transform: translateX(10rpx); }
|
||
}
|
||
|
||
@keyframes fadeIn {
|
||
from { opacity: 0; }
|
||
to { opacity: 1; }
|
||
}
|
||
|
||
@keyframes slideUp {
|
||
from { transform: translateY(100%); }
|
||
to { transform: translateY(0); }
|
||
}
|
||
|
||
.section-card {
|
||
background-color: #151D30;
|
||
border-radius: 24rpx;
|
||
padding: 28rpx;
|
||
margin-bottom: 24rpx;
|
||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||
|
||
.sec-head {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20rpx;
|
||
|
||
.title-wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
|
||
.sec-svg {
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
}
|
||
|
||
.sec-title {
|
||
font-size: 26rpx;
|
||
font-weight: 700;
|
||
color: #F8FAFC;
|
||
}
|
||
}
|
||
|
||
.pulse-live {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
|
||
.pulse-circle {
|
||
width: 10rpx;
|
||
height: 10rpx;
|
||
border-radius: 50%;
|
||
background-color: #10B981;
|
||
box-shadow: 0 0 8rpx #10B981;
|
||
}
|
||
.live-text {
|
||
font-size: 20rpx;
|
||
color: #10B981;
|
||
}
|
||
}
|
||
}
|
||
|
||
.pool-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 18rpx;
|
||
|
||
.pool-card {
|
||
background: rgba(255, 255, 255, 0.03);
|
||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||
border-radius: 18rpx;
|
||
padding: 20rpx;
|
||
|
||
.pool-top {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 10rpx;
|
||
|
||
.game-tag {
|
||
font-size: 20rpx;
|
||
background: rgba(99, 102, 241, 0.2);
|
||
color: #818CF8;
|
||
padding: 2rpx 10rpx;
|
||
border-radius: 6rpx;
|
||
}
|
||
|
||
.pool-price {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #10B981;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
}
|
||
|
||
.pool-desc {
|
||
font-size: 22rpx;
|
||
color: #CBD5E1;
|
||
line-height: 1.4;
|
||
margin-bottom: 14rpx;
|
||
display: block;
|
||
}
|
||
|
||
.pool-foot {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
.pool-time {
|
||
font-size: 20rpx;
|
||
color: #EF4444;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
.btn-grab {
|
||
background: linear-gradient(135deg, #6366F1 0%, #8B5CF6 100%);
|
||
color: #FFF;
|
||
font-size: 22rpx;
|
||
font-weight: 700;
|
||
border-radius: 28rpx;
|
||
height: 56rpx;
|
||
line-height: 56rpx;
|
||
padding: 0 28rpx;
|
||
margin: 0;
|
||
box-shadow: 0 4rpx 16rpx rgba(99, 102, 241, 0.4);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.empty-pool {
|
||
text-align: center;
|
||
color: #64748B;
|
||
font-size: 22rpx;
|
||
padding: 24rpx 0;
|
||
}
|
||
|
||
.active-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 18rpx;
|
||
|
||
.active-order-card {
|
||
background: rgba(255, 255, 255, 0.03);
|
||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||
border-radius: 18rpx;
|
||
padding: 20rpx;
|
||
|
||
.order-buyer {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 16rpx;
|
||
|
||
.buyer-avatar {
|
||
width: 72rpx;
|
||
height: 72rpx;
|
||
border-radius: 36rpx;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.buyer-info {
|
||
flex: 1;
|
||
|
||
.buyer-name {
|
||
font-size: 24rpx;
|
||
font-weight: 700;
|
||
color: #F8FAFC;
|
||
display: block;
|
||
}
|
||
|
||
.service-tag {
|
||
font-size: 20rpx;
|
||
color: #94A3B8;
|
||
}
|
||
}
|
||
|
||
.order-amount {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #10B981;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
}
|
||
|
||
.order-progress-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
||
padding-top: 14rpx;
|
||
|
||
.prog-text {
|
||
font-size: 22rpx;
|
||
color: #64748B;
|
||
}
|
||
|
||
.order-btns {
|
||
display: flex;
|
||
gap: 12rpx;
|
||
|
||
.btn-chat {
|
||
background: rgba(99, 102, 241, 0.15);
|
||
color: #818CF8;
|
||
border: 1px solid rgba(99, 102, 241, 0.3);
|
||
font-size: 20rpx;
|
||
height: 52rpx;
|
||
line-height: 50rpx;
|
||
padding: 0 20rpx;
|
||
border-radius: 26rpx;
|
||
margin: 0;
|
||
}
|
||
|
||
.btn-complete {
|
||
background: linear-gradient(135deg, #10B981 0%, #059669 100%);
|
||
color: #FFF;
|
||
font-size: 20rpx;
|
||
font-weight: 600;
|
||
height: 52rpx;
|
||
line-height: 52rpx;
|
||
padding: 0 22rpx;
|
||
border-radius: 26rpx;
|
||
margin: 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.bottom-switch-wrap {
|
||
margin-top: 40rpx;
|
||
|
||
.btn-back-player {
|
||
background: #151D30;
|
||
color: #94A3B8;
|
||
font-size: 26rpx;
|
||
height: 84rpx;
|
||
line-height: 84rpx;
|
||
border-radius: 42rpx;
|
||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||
}
|
||
}
|
||
</style>
|