1191 行
31 KiB
Vue
1191 行
31 KiB
Vue
<template>
|
||
<view class="reports-page" :class="['theme-' + currentThemeKey]" :style="navStyle">
|
||
<!-- 顶部沉浸式自定义导航栏 -->
|
||
<view class="custom-nav-bar">
|
||
<view class="nav-content">
|
||
<view class="btn-nav-back btn-active" @click="handleBack">
|
||
<image class="nav-back-icon" :src="ICONS.chevronLeft" mode="aspectFit" />
|
||
</view>
|
||
<view class="nav-title-wrap">
|
||
<text class="nav-title">我的举报与维权反馈</text>
|
||
</view>
|
||
<!-- 胶囊右侧对称避让占位 -->
|
||
<view class="nav-capsule-placeholder"></view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 主滚动区域 -->
|
||
<scroll-view
|
||
scroll-y
|
||
class="reports-scroll-view"
|
||
refresher-enabled
|
||
:refresher-triggered="isRefreshing"
|
||
@refresherrefresh="onRefresh"
|
||
>
|
||
<view class="reports-content-body">
|
||
<!-- 1. 维权与举报工单总览卡片 -->
|
||
<view class="summary-stat-card">
|
||
<view class="card-bg-glow"></view>
|
||
<view class="summary-inner">
|
||
<view class="summary-title-row">
|
||
<view class="title-left">
|
||
<view class="shield-icon-box">
|
||
<image class="shield-icon-svg" :src="ICONS.alert" mode="aspectFit" />
|
||
</view>
|
||
<view class="title-text-wrap">
|
||
<text class="summary-card-title">安全风控与维权中心</text>
|
||
<text class="summary-card-sub">7x24h 专员核查 · 守护绿色纯净社区</text>
|
||
</view>
|
||
</view>
|
||
<view class="btn-contact-service btn-active" @click="handleContactService">
|
||
<image class="service-icon" :src="ICONS.headphones" mode="aspectFit" />
|
||
<text class="btn-txt">人工客服</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="summary-numbers-grid">
|
||
<view class="stat-col">
|
||
<text class="stat-num-val count">{{ allReports.length }} 单</text>
|
||
<text class="stat-num-label">累计提交工单</text>
|
||
</view>
|
||
<view class="col-divider"></view>
|
||
<view class="stat-col">
|
||
<text class="stat-num-val gold">{{ stats.pendingCount }} 单</text>
|
||
<text class="stat-num-label">专员核查中</text>
|
||
</view>
|
||
<view class="col-divider"></view>
|
||
<view class="stat-col">
|
||
<text class="stat-num-val green">{{ stats.resolvedCount }} 单</text>
|
||
<text class="stat-num-label">已办结反馈</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 2. 状态分类筛选选项卡 (Tabs) -->
|
||
<view class="filter-tabs-card">
|
||
<view class="filter-tabs-row">
|
||
<view
|
||
v-for="tab in tabList"
|
||
:key="tab.key"
|
||
class="tab-item btn-active"
|
||
:class="{ active: currentTab === tab.key }"
|
||
@click="selectTab(tab.key)"
|
||
>
|
||
<text class="tab-label">{{ tab.label }}</text>
|
||
<text class="tab-badge" v-if="tab.count > 0">{{ tab.count }}</text>
|
||
<view class="tab-indicator" v-if="currentTab === tab.key"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 3. 加载骨架屏 -->
|
||
<view class="skeleton-wrap" v-if="isLoading">
|
||
<view class="skeleton-card" v-for="n in 3" :key="n"></view>
|
||
</view>
|
||
|
||
<!-- 4. 举报与维权记录列表卡片 -->
|
||
<view class="records-list-wrap" v-else-if="filteredReports.length > 0">
|
||
<view
|
||
v-for="rpt in filteredReports"
|
||
:key="rpt.id"
|
||
class="report-card"
|
||
>
|
||
<!-- 卡片头部: 工单编号与处理状态胶囊 -->
|
||
<view class="card-head-row">
|
||
<view class="report-no-wrap" @click="handleCopyReportNo(rpt.id)">
|
||
<text class="report-no-badge">维权工单</text>
|
||
<text class="report-no-val">{{ formatReportNo(rpt.id) }}</text>
|
||
</view>
|
||
<view
|
||
class="status-pill"
|
||
:class="{
|
||
pending: !rpt.status || rpt.status === '待处理',
|
||
success: rpt.status === '已核实处罚' || rpt.status === '已处置',
|
||
rejected: rpt.status === '已驳回'
|
||
}"
|
||
>
|
||
<view class="status-dot"></view>
|
||
<text class="status-text">{{ rpt.status || '待处理' }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 卡片主体: 举报对象与违规类型 -->
|
||
<view class="card-main-box">
|
||
<view class="target-row">
|
||
<view class="target-info">
|
||
<text class="target-label">举报对象</text>
|
||
<text class="target-name">对象:{{ rpt.targetName || rpt.targetId || '违规内容' }}</text>
|
||
</view>
|
||
<view class="reason-tag">
|
||
<text class="reason-text">{{ rpt.reason || '违规举报' }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="desc-box" v-if="rpt.description">
|
||
<text class="desc-label">举报说明:</text>
|
||
<text class="desc-content">{{ rpt.description }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 卡片底部: 时间轴与官方风控反馈 -->
|
||
<view class="card-feedback-box">
|
||
<view class="feedback-row">
|
||
<text class="feedback-label">提交时间</text>
|
||
<text class="feedback-time">{{ formatReportTime(rpt.createdAt) }}</text>
|
||
</view>
|
||
<view class="feedback-divider"></view>
|
||
<view class="feedback-result-row">
|
||
<view class="result-badge-row">
|
||
<image class="result-icon" :src="ICONS.shield" mode="aspectFit" />
|
||
<text class="result-title">平台风控处置反馈</text>
|
||
</view>
|
||
<text
|
||
class="result-desc"
|
||
:class="{
|
||
highlight: rpt.handleNote || rpt.handleResult || rpt.status === '已核实处罚'
|
||
}"
|
||
>
|
||
{{ getFeedbackText(rpt) }}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 列表触底提示 -->
|
||
<view class="list-end-tip">
|
||
<text class="tip-line"></text>
|
||
<text class="tip-txt">已展示全部举报与维权记录</text>
|
||
<text class="tip-line"></text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 5. 暂无数据空状态 -->
|
||
<view class="empty-state-card" v-else>
|
||
<view class="empty-icon-wrap">
|
||
<image class="empty-icon-svg" :src="ICONS.shield" mode="aspectFit" />
|
||
</view>
|
||
<text class="empty-title">暂无举报与维权记录</text>
|
||
<text class="empty-sub">如在组局约玩或友圈互动中遇到违规行为,可在对应详情页发起举报,平台专员将第一时间核实处理</text>
|
||
<button class="btn-empty-back btn-active" @click="handleBack">返回个人中心</button>
|
||
</view>
|
||
|
||
<!-- 底部安全垫高 -->
|
||
<view class="bottom-spacer"></view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, onMounted } from 'vue';
|
||
import { onShow } from '@dcloudio/uni-app';
|
||
import { ICONS } from '@/common/icons.js';
|
||
import { getCurrentThemeKey, applyThemeToNativeUI } from '@/common/theme.js';
|
||
import { getNavBarInfo } from '@/common/nav.js';
|
||
import { getMyReports, getPlatformConfigs } from '@/common/api.js';
|
||
|
||
const currentThemeKey = ref(getCurrentThemeKey());
|
||
const navInfo = ref(getNavBarInfo());
|
||
const isLoading = ref(true);
|
||
const isRefreshing = ref(false);
|
||
const allReports = ref([]);
|
||
const currentTab = ref('ALL');
|
||
const serviceHotline = ref('400-888-6666');
|
||
const serviceWechat = ref('peiwan_vip_kefu');
|
||
|
||
const navStyle = computed(() => {
|
||
return {
|
||
'--safe-header-gap': `${navInfo.value.totalHeaderHeight}px`,
|
||
'--capsule-right-space': `${navInfo.value.capsuleRightSpace}px`,
|
||
'--capsule-height': `${navInfo.value.capsuleHeight}px`
|
||
};
|
||
});
|
||
|
||
const stats = computed(() => {
|
||
const list = allReports.value;
|
||
const pendingCount = list.filter(r => !r.status || r.status === '待处理').length;
|
||
const resolvedCount = list.length - pendingCount;
|
||
return {
|
||
pendingCount,
|
||
resolvedCount
|
||
};
|
||
});
|
||
|
||
const tabList = computed(() => {
|
||
const list = allReports.value;
|
||
const pendingCount = list.filter(r => !r.status || r.status === '待处理').length;
|
||
const punishedCount = list.filter(r => r.status === '已核实处罚' || r.status === '已处置').length;
|
||
const rejectedCount = list.filter(r => r.status === '已驳回').length;
|
||
|
||
return [
|
||
{ key: 'ALL', label: '全部', count: list.length },
|
||
{ key: 'PENDING', label: '待处理', count: pendingCount },
|
||
{ key: 'PUNISHED', label: '已核实处罚', count: punishedCount },
|
||
{ key: 'REJECTED', label: '已驳回', count: rejectedCount }
|
||
];
|
||
});
|
||
|
||
const filteredReports = computed(() => {
|
||
const tab = currentTab.value;
|
||
if (tab === 'PENDING') {
|
||
return allReports.value.filter(r => !r.status || r.status === '待处理');
|
||
}
|
||
if (tab === 'PUNISHED') {
|
||
return allReports.value.filter(r => r.status === '已核实处罚' || r.status === '已处置');
|
||
}
|
||
if (tab === 'REJECTED') {
|
||
return allReports.value.filter(r => r.status === '已驳回');
|
||
}
|
||
return allReports.value;
|
||
});
|
||
|
||
const selectTab = (key) => {
|
||
currentTab.value = key;
|
||
};
|
||
|
||
const formatReportNo = (id) => {
|
||
return `#RPT-${String(id || 100).padStart(4, '0')}`;
|
||
};
|
||
|
||
const formatReportTime = (rawTime) => {
|
||
if (!rawTime) return '刚刚提交';
|
||
const str = String(rawTime);
|
||
if (str.includes('T')) {
|
||
const d = new Date(str);
|
||
if (!isNaN(d.getTime())) {
|
||
const pad = (n) => String(n).padStart(2, '0');
|
||
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
||
}
|
||
return str.replace('T', ' ').replace(/\.\d+Z$/, '');
|
||
}
|
||
return str;
|
||
};
|
||
|
||
const getFeedbackText = (rpt) => {
|
||
if (rpt.handleNote || rpt.handleResult) {
|
||
return rpt.handleNote || rpt.handleResult;
|
||
}
|
||
if (rpt.status === '已核实处罚' || rpt.status === '已处置') {
|
||
return '平台已核实违规事实并对涉事账号或内容采取限制处罚措施,感谢您共同维护社区环境。';
|
||
}
|
||
if (rpt.status === '已驳回') {
|
||
return '经安全专员核查,暂未发现明显违规行为;若有补充凭证可随时联系官方在线客服申诉。';
|
||
}
|
||
return '平台安全专员正在核实处理中,预计 24 小时内同步处置结果。';
|
||
};
|
||
|
||
const handleCopyReportNo = (id) => {
|
||
const no = `RPT-${String(id || 100).padStart(4, '0')}`;
|
||
uni.setClipboardData({
|
||
data: no,
|
||
success: () => {
|
||
uni.showToast({ title: '工单号已复制', icon: 'none' });
|
||
}
|
||
});
|
||
};
|
||
|
||
const handleContactService = () => {
|
||
uni.showActionSheet({
|
||
itemList: [
|
||
`拨打维权专线 (${serviceHotline.value})`,
|
||
`复制客服微信 (${serviceWechat.value})`
|
||
],
|
||
success: (res) => {
|
||
if (res.tapIndex === 0) {
|
||
uni.makePhoneCall({
|
||
phoneNumber: serviceHotline.value,
|
||
fail: () => {
|
||
uni.setClipboardData({ data: serviceHotline.value });
|
||
}
|
||
});
|
||
} else if (res.tapIndex === 1) {
|
||
uni.setClipboardData({
|
||
data: serviceWechat.value,
|
||
success: () => {
|
||
uni.showToast({ title: '客服微信号已复制', icon: 'none' });
|
||
}
|
||
});
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
const handleBack = () => {
|
||
const pages = getCurrentPages();
|
||
if (pages && pages.length > 1) {
|
||
uni.navigateBack();
|
||
} else {
|
||
uni.switchTab({
|
||
url: '/pages/user/index'
|
||
});
|
||
}
|
||
};
|
||
|
||
const loadReportsData = async () => {
|
||
const uid = uni.getStorageSync('userId') || 1001;
|
||
try {
|
||
const list = await getMyReports(uid);
|
||
allReports.value = Array.isArray(list) ? list : [];
|
||
} catch (_) {
|
||
allReports.value = [];
|
||
} finally {
|
||
isLoading.value = false;
|
||
isRefreshing.value = false;
|
||
}
|
||
};
|
||
|
||
const loadConfig = async () => {
|
||
try {
|
||
const cfg = await getPlatformConfigs();
|
||
if (cfg && cfg.customer_service) {
|
||
if (cfg.customer_service.hotline) serviceHotline.value = cfg.customer_service.hotline;
|
||
if (cfg.customer_service.wechat) serviceWechat.value = cfg.customer_service.wechat;
|
||
}
|
||
} catch (_) {}
|
||
};
|
||
|
||
const onRefresh = async () => {
|
||
isRefreshing.value = true;
|
||
await loadReportsData();
|
||
};
|
||
|
||
onMounted(() => {
|
||
currentThemeKey.value = getCurrentThemeKey();
|
||
applyThemeToNativeUI();
|
||
navInfo.value = getNavBarInfo();
|
||
loadReportsData();
|
||
loadConfig();
|
||
});
|
||
|
||
onShow(() => {
|
||
currentThemeKey.value = getCurrentThemeKey();
|
||
applyThemeToNativeUI();
|
||
navInfo.value = getNavBarInfo();
|
||
loadReportsData();
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.reports-page {
|
||
min-height: 100vh;
|
||
background-color: #0A0F1D;
|
||
color: #F8FAFC;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
/* 顶部沉浸式自定义导航栏 */
|
||
.custom-nav-bar {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
z-index: 100;
|
||
height: var(--safe-header-gap);
|
||
background: rgba(10, 15, 29, 0.92);
|
||
backdrop-filter: blur(20px);
|
||
-webkit-backdrop-filter: blur(20px);
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||
|
||
.nav-content {
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
height: var(--capsule-height);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 0 24rpx;
|
||
|
||
.btn-nav-back {
|
||
width: 64rpx;
|
||
height: 64rpx;
|
||
border-radius: 32rpx;
|
||
background: rgba(255, 255, 255, 0.08);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.nav-back-icon {
|
||
width: 38rpx;
|
||
height: 38rpx;
|
||
}
|
||
}
|
||
|
||
.nav-title-wrap {
|
||
position: absolute;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
text-align: center;
|
||
|
||
.nav-title {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #F8FAFC;
|
||
letter-spacing: 0.5rpx;
|
||
}
|
||
}
|
||
|
||
.nav-capsule-placeholder {
|
||
width: var(--capsule-right-space);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 滚动主视图 */
|
||
.reports-scroll-view {
|
||
flex: 1;
|
||
margin-top: var(--safe-header-gap);
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.reports-content-body {
|
||
padding: 24rpx 28rpx 60rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* 1. 维权与举报工单总览卡片 */
|
||
.summary-stat-card {
|
||
position: relative;
|
||
border-radius: 28rpx;
|
||
padding: 30rpx 28rpx;
|
||
margin-bottom: 24rpx;
|
||
background: linear-gradient(135deg, #1E1B4B 0%, #0F172A 100%);
|
||
border: 1px solid rgba(244, 63, 94, 0.25);
|
||
box-shadow: 0 12rpx 36rpx rgba(15, 23, 42, 0.45);
|
||
overflow: hidden;
|
||
|
||
.card-bg-glow {
|
||
position: absolute;
|
||
top: -60rpx;
|
||
right: -60rpx;
|
||
width: 220rpx;
|
||
height: 220rpx;
|
||
border-radius: 50%;
|
||
background: radial-gradient(circle, rgba(244, 63, 94, 0.22) 0%, transparent 70%);
|
||
pointer-events: none;
|
||
}
|
||
|
||
.summary-inner {
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
|
||
.summary-title-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 28rpx;
|
||
|
||
.title-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
|
||
.shield-icon-box {
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
border-radius: 16rpx;
|
||
background: rgba(244, 63, 94, 0.15);
|
||
border: 1px solid rgba(244, 63, 94, 0.28);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.shield-icon-svg {
|
||
width: 34rpx;
|
||
height: 34rpx;
|
||
}
|
||
}
|
||
|
||
.title-text-wrap {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4rpx;
|
||
|
||
.summary-card-title {
|
||
font-size: 30rpx;
|
||
font-weight: 700;
|
||
color: #F8FAFC;
|
||
letter-spacing: 0.5rpx;
|
||
}
|
||
|
||
.summary-card-sub {
|
||
font-size: 20rpx;
|
||
color: #94A3B8;
|
||
}
|
||
}
|
||
}
|
||
|
||
.btn-contact-service {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
background: rgba(99, 102, 241, 0.2);
|
||
border: 1px solid rgba(99, 102, 241, 0.4);
|
||
padding: 10rpx 20rpx;
|
||
border-radius: 26rpx;
|
||
|
||
.service-icon {
|
||
width: 24rpx;
|
||
height: 24rpx;
|
||
}
|
||
|
||
.btn-txt {
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
color: #A5B4FC;
|
||
}
|
||
}
|
||
}
|
||
|
||
.summary-numbers-grid {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
background: rgba(15, 23, 42, 0.72);
|
||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||
border-radius: 20rpx;
|
||
padding: 24rpx 16rpx;
|
||
|
||
.stat-col {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
|
||
.stat-num-val {
|
||
font-size: 32rpx;
|
||
font-weight: 800;
|
||
color: #F8FAFC;
|
||
font-family: -apple-system, BlinkMacSystemFont, 'DIN Alternate', Roboto, sans-serif;
|
||
font-variant-numeric: tabular-nums;
|
||
|
||
&.green { color: #10B981; }
|
||
&.gold { color: #F59E0B; }
|
||
&.count { color: #818CF8; }
|
||
}
|
||
|
||
.stat-num-label {
|
||
font-size: 20rpx;
|
||
color: #94A3B8;
|
||
}
|
||
}
|
||
|
||
.col-divider {
|
||
width: 1px;
|
||
height: 44rpx;
|
||
background: rgba(255, 255, 255, 0.08);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 2. 状态分类筛选选项卡 */
|
||
.filter-tabs-card {
|
||
background: #0F172A;
|
||
border: 1px solid rgba(255, 255, 255, 0.07);
|
||
border-radius: 22rpx;
|
||
padding: 10rpx;
|
||
margin-bottom: 24rpx;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.2);
|
||
|
||
.filter-tabs-row {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.tab-item {
|
||
flex: 1;
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 6rpx;
|
||
height: 72rpx;
|
||
border-radius: 16rpx;
|
||
transition: all 0.2s ease;
|
||
|
||
.tab-label {
|
||
font-size: 24rpx;
|
||
font-weight: 500;
|
||
color: #94A3B8;
|
||
}
|
||
|
||
.tab-badge {
|
||
font-size: 18rpx;
|
||
color: #94A3B8;
|
||
background: rgba(255, 255, 255, 0.08);
|
||
padding: 2rpx 8rpx;
|
||
border-radius: 12rpx;
|
||
line-height: 1.2;
|
||
}
|
||
|
||
&.active {
|
||
background: rgba(99, 102, 241, 0.15);
|
||
|
||
.tab-label {
|
||
color: #818CF8;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.tab-badge {
|
||
background: #6366F1;
|
||
color: #FFFFFF;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.tab-indicator {
|
||
position: absolute;
|
||
bottom: 6rpx;
|
||
width: 32rpx;
|
||
height: 4rpx;
|
||
background: #818CF8;
|
||
border-radius: 2rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 3. 骨架屏 */
|
||
.skeleton-wrap {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 20rpx;
|
||
|
||
.skeleton-card {
|
||
height: 240rpx;
|
||
border-radius: 24rpx;
|
||
background: linear-gradient(90deg, #1E293B 25%, #334155 37%, #1E293B 63%);
|
||
background-size: 400% 100%;
|
||
animation: skeleton-loading 1.4s ease infinite;
|
||
}
|
||
}
|
||
|
||
@keyframes skeleton-loading {
|
||
0% { background-position: 100% 50%; }
|
||
100% { background-position: 0 50%; }
|
||
}
|
||
|
||
/* 4. 举报与维权记录列表 */
|
||
.records-list-wrap {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 22rpx;
|
||
|
||
.report-card {
|
||
background: #0F172A;
|
||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||
border-radius: 24rpx;
|
||
padding: 26rpx;
|
||
box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.25);
|
||
|
||
.card-head-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding-bottom: 20rpx;
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||
margin-bottom: 20rpx;
|
||
|
||
.report-no-wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10rpx;
|
||
|
||
.report-no-badge {
|
||
font-size: 20rpx;
|
||
font-weight: 600;
|
||
color: #F43F5E;
|
||
background: rgba(244, 63, 94, 0.14);
|
||
border: 1px solid rgba(244, 63, 94, 0.28);
|
||
padding: 2rpx 12rpx;
|
||
border-radius: 8rpx;
|
||
}
|
||
|
||
.report-no-val {
|
||
font-size: 24rpx;
|
||
font-weight: 600;
|
||
color: #CBD5E1;
|
||
font-family: monospace;
|
||
}
|
||
}
|
||
|
||
.status-pill {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
padding: 6rpx 18rpx;
|
||
border-radius: 20rpx;
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
|
||
.status-dot {
|
||
width: 10rpx;
|
||
height: 10rpx;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
&.pending {
|
||
background: rgba(245, 158, 11, 0.14);
|
||
color: #F59E0B;
|
||
border: 1px solid rgba(245, 158, 11, 0.32);
|
||
|
||
.status-dot {
|
||
background: #F59E0B;
|
||
box-shadow: 0 0 8rpx #F59E0B;
|
||
}
|
||
}
|
||
|
||
&.success {
|
||
background: rgba(16, 185, 129, 0.14);
|
||
color: #10B981;
|
||
border: 1px solid rgba(16, 185, 129, 0.32);
|
||
|
||
.status-dot {
|
||
background: #10B981;
|
||
box-shadow: 0 0 8rpx #10B981;
|
||
}
|
||
}
|
||
|
||
&.rejected {
|
||
background: rgba(239, 68, 68, 0.14);
|
||
color: #EF4444;
|
||
border: 1px solid rgba(239, 68, 68, 0.32);
|
||
|
||
.status-dot {
|
||
background: #EF4444;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.card-main-box {
|
||
margin-bottom: 20rpx;
|
||
|
||
.target-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-start;
|
||
gap: 16rpx;
|
||
margin-bottom: 16rpx;
|
||
|
||
.target-info {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 6rpx;
|
||
|
||
.target-label {
|
||
font-size: 20rpx;
|
||
color: #64748B;
|
||
}
|
||
|
||
.target-name {
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
color: #F8FAFC;
|
||
line-height: 1.35;
|
||
}
|
||
}
|
||
|
||
.reason-tag {
|
||
flex-shrink: 0;
|
||
background: rgba(99, 102, 241, 0.14);
|
||
border: 1px solid rgba(99, 102, 241, 0.3);
|
||
padding: 6rpx 16rpx;
|
||
border-radius: 12rpx;
|
||
|
||
.reason-text {
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
color: #818CF8;
|
||
}
|
||
}
|
||
}
|
||
|
||
.desc-box {
|
||
background: rgba(255, 255, 255, 0.03);
|
||
border-left: 4rpx solid #6366F1;
|
||
border-radius: 8rpx 14rpx 14rpx 8rpx;
|
||
padding: 14rpx 18rpx;
|
||
|
||
.desc-label {
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
color: #94A3B8;
|
||
}
|
||
|
||
.desc-content {
|
||
font-size: 24rpx;
|
||
color: #E2E8F0;
|
||
line-height: 1.5;
|
||
}
|
||
}
|
||
}
|
||
|
||
.card-feedback-box {
|
||
background: rgba(15, 23, 42, 0.8);
|
||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||
border-radius: 18rpx;
|
||
padding: 18rpx 20rpx;
|
||
|
||
.feedback-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
font-size: 22rpx;
|
||
|
||
.feedback-label {
|
||
color: #64748B;
|
||
}
|
||
|
||
.feedback-time {
|
||
color: #94A3B8;
|
||
font-family: -apple-system, BlinkMacSystemFont, 'DIN Alternate', monospace;
|
||
}
|
||
}
|
||
|
||
.feedback-divider {
|
||
height: 1px;
|
||
background: rgba(255, 255, 255, 0.05);
|
||
margin: 14rpx 0;
|
||
}
|
||
|
||
.feedback-result-row {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8rpx;
|
||
|
||
.result-badge-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
|
||
.result-icon {
|
||
width: 26rpx;
|
||
height: 26rpx;
|
||
}
|
||
|
||
.result-title {
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
color: #CBD5E1;
|
||
}
|
||
}
|
||
|
||
.result-desc {
|
||
font-size: 23rpx;
|
||
color: #94A3B8;
|
||
line-height: 1.5;
|
||
|
||
&.highlight {
|
||
color: #10B981;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.list-end-tip {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 16rpx;
|
||
padding: 30rpx 0 10rpx;
|
||
|
||
.tip-line {
|
||
width: 60rpx;
|
||
height: 1px;
|
||
background: rgba(255, 255, 255, 0.1);
|
||
}
|
||
|
||
.tip-txt {
|
||
font-size: 20rpx;
|
||
color: #475569;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 5. 空状态展示 */
|
||
.empty-state-card {
|
||
padding: 80rpx 40rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
text-align: center;
|
||
|
||
.empty-icon-wrap {
|
||
width: 140rpx;
|
||
height: 140rpx;
|
||
border-radius: 70rpx;
|
||
background: rgba(16, 185, 129, 0.1);
|
||
border: 1px solid rgba(16, 185, 129, 0.25);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 30rpx;
|
||
|
||
.empty-icon-svg {
|
||
width: 72rpx;
|
||
height: 72rpx;
|
||
}
|
||
}
|
||
|
||
.empty-title {
|
||
font-size: 30rpx;
|
||
font-weight: 700;
|
||
color: #F8FAFC;
|
||
margin-bottom: 14rpx;
|
||
}
|
||
|
||
.empty-sub {
|
||
font-size: 24rpx;
|
||
color: #64748B;
|
||
line-height: 1.6;
|
||
margin-bottom: 42rpx;
|
||
max-width: 540rpx;
|
||
}
|
||
|
||
.btn-empty-back {
|
||
height: 84rpx;
|
||
line-height: 84rpx;
|
||
padding: 0 60rpx;
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
color: #FFFFFF;
|
||
background: linear-gradient(135deg, #6366F1 0%, #4F46E5 100%);
|
||
border-radius: 42rpx;
|
||
box-shadow: 0 8rpx 28rpx rgba(99, 102, 241, 0.4);
|
||
margin: 0;
|
||
}
|
||
}
|
||
|
||
.bottom-spacer {
|
||
height: 40rpx;
|
||
}
|
||
|
||
/* 暖阳浅色模式适配 (theme-warm) */
|
||
&.theme-warm {
|
||
background-color: #FFFDF9;
|
||
color: #1C1917;
|
||
|
||
.custom-nav-bar {
|
||
background: rgba(255, 253, 249, 0.95);
|
||
border-bottom-color: rgba(234, 88, 12, 0.1);
|
||
|
||
.nav-content {
|
||
.btn-nav-back {
|
||
background: #FFF7ED;
|
||
border: 1px solid #FED7AA;
|
||
}
|
||
|
||
.nav-title-wrap .nav-title {
|
||
color: #1C1917;
|
||
}
|
||
}
|
||
}
|
||
|
||
.summary-stat-card {
|
||
background: linear-gradient(135deg, #FFF7ED 0%, #FFEDD5 100%);
|
||
border: 1px solid #FED7AA;
|
||
box-shadow: 0 8rpx 28rpx rgba(234, 88, 12, 0.08);
|
||
|
||
.summary-title-row {
|
||
.title-left {
|
||
.shield-icon-box {
|
||
background: #FFE4E6;
|
||
border-color: #FECDD3;
|
||
}
|
||
|
||
.title-text-wrap {
|
||
.summary-card-title {
|
||
color: #9A3412;
|
||
}
|
||
|
||
.summary-card-sub {
|
||
color: #C2410C;
|
||
}
|
||
}
|
||
}
|
||
|
||
.btn-contact-service {
|
||
background: #FFFFFF;
|
||
border-color: #FED7AA;
|
||
box-shadow: 0 2rpx 8rpx rgba(234, 88, 12, 0.08);
|
||
|
||
.btn-txt {
|
||
color: #EA580C;
|
||
}
|
||
}
|
||
}
|
||
|
||
.summary-numbers-grid {
|
||
background: #FFFFFF;
|
||
border-color: #FED7AA;
|
||
box-shadow: 0 2rpx 10rpx rgba(234, 88, 12, 0.04);
|
||
|
||
.stat-col {
|
||
.stat-num-val {
|
||
&.green { color: #059669; }
|
||
&.gold { color: #D97706; }
|
||
&.count { color: #EA580C; }
|
||
}
|
||
|
||
.stat-num-label {
|
||
color: #78716C;
|
||
}
|
||
}
|
||
|
||
.col-divider {
|
||
background: #F5EBE1;
|
||
}
|
||
}
|
||
}
|
||
|
||
.filter-tabs-card {
|
||
background: #FFFFFF;
|
||
border-color: #FED7AA;
|
||
box-shadow: 0 4rpx 16rpx rgba(234, 88, 12, 0.04);
|
||
|
||
.filter-tabs-row .tab-item {
|
||
.tab-label {
|
||
color: #78716C;
|
||
}
|
||
|
||
.tab-badge {
|
||
color: #78716C;
|
||
background: #F5F5F4;
|
||
}
|
||
|
||
&.active {
|
||
background: #FFF7ED;
|
||
|
||
.tab-label {
|
||
color: #EA580C;
|
||
}
|
||
|
||
.tab-badge {
|
||
background: #EA580C;
|
||
color: #FFFFFF;
|
||
}
|
||
|
||
.tab-indicator {
|
||
background: #EA580C;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.records-list-wrap {
|
||
.report-card {
|
||
background: #FFFFFF;
|
||
border-color: #FED7AA;
|
||
box-shadow: 0 4rpx 20rpx rgba(234, 88, 12, 0.05);
|
||
|
||
.card-head-row {
|
||
border-bottom-color: #F5F0E8;
|
||
|
||
.report-no-wrap {
|
||
.report-no-badge {
|
||
color: #E11D48;
|
||
background: #FFF1F2;
|
||
border-color: #FECDD3;
|
||
}
|
||
|
||
.report-no-val {
|
||
color: #44403C;
|
||
}
|
||
}
|
||
}
|
||
|
||
.card-main-box {
|
||
.target-row {
|
||
.target-info {
|
||
.target-label { color: #78716C; }
|
||
.target-name { color: #1C1917; }
|
||
}
|
||
|
||
.reason-tag {
|
||
background: #FFF7ED;
|
||
border-color: #FED7AA;
|
||
|
||
.reason-text {
|
||
color: #EA580C;
|
||
}
|
||
}
|
||
}
|
||
|
||
.desc-box {
|
||
background: #FFFBF5;
|
||
border-left-color: #F97316;
|
||
|
||
.desc-label { color: #78716C; }
|
||
.desc-content { color: #292524; }
|
||
}
|
||
}
|
||
|
||
.card-feedback-box {
|
||
background: #FAFAF9;
|
||
border-color: #F5F0E8;
|
||
|
||
.feedback-row {
|
||
.feedback-label { color: #78716C; }
|
||
.feedback-time { color: #57534E; }
|
||
}
|
||
|
||
.feedback-divider {
|
||
background: #EFECE6;
|
||
}
|
||
|
||
.feedback-result-row {
|
||
.result-badge-row .result-title {
|
||
color: #44403C;
|
||
}
|
||
|
||
.result-desc {
|
||
color: #57534E;
|
||
|
||
&.highlight {
|
||
color: #059669;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.list-end-tip {
|
||
.tip-line { background: #E7E2D8; }
|
||
.tip-txt { color: #A8A29E; }
|
||
}
|
||
}
|
||
|
||
.empty-state-card {
|
||
.empty-icon-wrap {
|
||
background: #FFF7ED;
|
||
border-color: #FED7AA;
|
||
}
|
||
|
||
.empty-title { color: #1C1917; }
|
||
.empty-sub { color: #78716C; }
|
||
|
||
.btn-empty-back {
|
||
background: linear-gradient(135deg, #F97316 0%, #EA580C 100%);
|
||
box-shadow: 0 8rpx 24rpx rgba(234, 88, 12, 0.3);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.btn-active {
|
||
transition: opacity 0.15s ease, transform 0.15s ease;
|
||
&:active {
|
||
opacity: 0.8;
|
||
transform: scale(0.98);
|
||
}
|
||
}
|
||
</style>
|