2970 lines
83 KiB
Vue
2970 lines
83 KiB
Vue
<template>
|
||
<view class="statistics-container">
|
||
<view class="top—1"></view>
|
||
<!-- 顶部导航栏 -->
|
||
<view class="nav-bar">
|
||
<uni-icons class="back-icon" @click="goBack" size="24" type="left" color="#fff"></uni-icons>
|
||
<view class="title-tabs">
|
||
<text :class="['tab-item', activeTab === 'order' ? 'active' : '']" @click="switchTab('order')">
|
||
业务渠道统计
|
||
</text>
|
||
<text :class="['tab-item', activeTab === 'category' ? 'active' : '']" @click="switchTab('category')">
|
||
业绩统计
|
||
</text>
|
||
<text :class="['tab-item', activeTab === '' ? 'active' : '']" @click="switchTab('')">
|
||
财务统计
|
||
</text>
|
||
</view>
|
||
<view class="filter-btn" ></view>
|
||
</view>
|
||
|
||
<!-- 工单统计 -->
|
||
<view v-if="activeTab === 'order'">
|
||
|
||
<view class="dil" >
|
||
<!-- 四个选项 -->
|
||
<!-- #ifdef APP-PLUS || H5 -->
|
||
<view class="tab-choose-class">
|
||
<view class="tab-content" @click="tabChoose(item, index)"
|
||
v-for='(item, index) in ["当日", "当月","当年", "全部", "自定义"]' :key='index'>
|
||
<!-- tab 名称信息 -->
|
||
<view class='tab-name-class'
|
||
:style='{ color: index + 1 == tabValue ? "#101A3E" : "#8D90A6", fontWeight: index + 1 == tabValue ? "bold" : "normal" }'>
|
||
{{ item }}
|
||
<view class="icon-tab" v-if='index == 4'>
|
||
<image src="@/static/icons/homeOrderCard/xialajiantou.svg" mode="scaleToFill"></image>
|
||
</view>
|
||
</view>
|
||
<!-- 名称下 icon -->
|
||
<view class="tab-icon"
|
||
:style='{ background: index + 1 == tabValue ? "linear-gradient( 180deg, #054DF3 0%, #55A3FF 100%)" : "" }'>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="example-body" v-show="tabValue==5" style="margin-bottom: 16rpx;">
|
||
<uni-datetime-picker v-model="range" type="daterange" @maskClick="maskClick" />
|
||
</view>
|
||
<view class="four-box-header">
|
||
<view class="blue-line"></view>
|
||
<text class="four-box-header-title">业务</text>
|
||
</view>
|
||
<!-- <view class="tab-choose-class tab-choose-multi tab-choose-equal">
|
||
<view class="tab-content" @click="channelTabChoose(item, index)"
|
||
v-for='(item, index) in ["泸渝高速", "泸贵高速","交警二大队", "泸州人才保险", "泸州中华保险","泸州中华保险","泸州平安保险","蓝安修理厂","其他修理场","其他修理场"]' :key='index'>
|
||
<view class='tab-name-class'
|
||
:style='{ color: index + 1 == channelTabValue ? "#101A3E" : "#8D90A6", fontWeight: index + 1 == channelTabValue ? "bold" : "normal" }'>
|
||
{{ item }}
|
||
</view>
|
||
</view>
|
||
</view> -->
|
||
<!-- 快捷统计卡 -->
|
||
<view class="four-box">
|
||
<view class="boxf" @click="goToOrder('null')">
|
||
<view class="zi1">
|
||
<image class="zi1-icon" src="@/static/icons/homeOrderCard/receivedOrder_new.png" mode="aspectFit" />
|
||
<text>已接单</text>
|
||
</view>
|
||
<view class="zi2" style="margin-top: 10rpx;">{{countNum.yjdNum ? countNum.yjdNum : '0'}}</view>
|
||
</view>
|
||
<view class="boxf" @click="goToOrder(1)">
|
||
<view class="zi1">
|
||
<image class="zi1-icon" src="@/static/icons/homeOrderCard/jyz_new.png" mode="aspectFit" />
|
||
<text>救援中</text>
|
||
</view>
|
||
<view class="zi2" style="margin-top: 10rpx;">{{countNum.jyzNum ? countNum.jyzNum : '0'}}</view>
|
||
</view>
|
||
<view class="boxf" @click="goToOrder(5)">
|
||
<view class="zi1">
|
||
<image class="zi1-icon" src="@/static/icons/homeOrderCard/ywc_new.png" mode="aspectFit" />
|
||
<text>已完成</text>
|
||
</view>
|
||
<view class="zi2" style="margin-top: 10rpx;">{{countNum.ywcNum ? countNum.ywcNum : '0'}}</view>
|
||
</view>
|
||
</view>
|
||
<!-- 金额/待取车卡 -->
|
||
<view class="two-box-container">
|
||
<view class="two-box">
|
||
<view class="boxf2" style="background: linear-gradient(135deg, #E0F0FF 40%, #BBD9FF 100%);">
|
||
<view style="display: flex; justify-content: space-between; align-items: center;">
|
||
<view class="zi1_1">
|
||
<image class="zi1_1-icon" src="@/static/icons/homeOrderCard/ysk_solid.png" mode="aspectFit" />
|
||
<text style="color: #3d6ba0; font-weight: bold; font-size: 30rpx;">应收款</text>
|
||
</view>
|
||
<uni-icons class="eye-icon" type="eye" />
|
||
</view>
|
||
<view class="zi2_2" style="margin-top: 10rpx;">{{ countNum.yingskNum ? countNum.yingskNum : '0' }}</view>
|
||
</view>
|
||
<view class="boxf2" style="background: linear-gradient(135deg, #FFF7E0 40%, #FFE7B8 100%);" @click="goToOrder(3)">
|
||
<view style="display: flex; justify-content: space-between; align-items: center;">
|
||
<view class="zi1_1">
|
||
<image class="zi1_1-icon" src="@/static/icons/homeOrderCard/qucar.png" mode="aspectFit" />
|
||
<text style="color: #a97747; font-size: 30rpx; font-weight: bold;">待取车</text>
|
||
</view>
|
||
<uni-icons class="eye-icon" type="eye" />
|
||
</view>
|
||
<view class="zi2_2" style="margin-top: 10rpx;">{{ countNum.dqcNum ? countNum.dqcNum : '0' }}</view>
|
||
</view>
|
||
</view>
|
||
<view class="two-box">
|
||
<view class="boxf2" style="background: linear-gradient(135deg, #E6F8ED 40%, #C8F0D8 100%);">
|
||
<view style="display: flex; justify-content: space-between; align-items: center;">
|
||
<view class="zi1_1">
|
||
<image class="zi1_1-icon" src="@/static/icons/homeOrderCard/yisk_solid.png" mode="aspectFit" />
|
||
<text style="color: #169948; font-size: 30rpx; font-weight: bold;">已收款</text>
|
||
</view>
|
||
<uni-icons class="eye-icon" type="eye" />
|
||
</view>
|
||
<view class="zi2_2" style="margin-top: 10rpx;">{{ countNum.yiskNum ? countNum.yiskNum : '0' }}</view>
|
||
</view>
|
||
<view class="boxf2" style="background: linear-gradient(135deg, #F0E9FF 40%, #D9CEFF 100%);">
|
||
<view style="display: flex; justify-content: space-between; align-items: center;">
|
||
<view class="zi1_1">
|
||
<image class="zi1_1-icon" src="@/static/icons/homeOrderCard/dsk_solid.png" mode="aspectFit" />
|
||
<text style="color: #6657da; font-weight: bold; font-size: 30rpx;">待收款</text>
|
||
</view>
|
||
<uni-icons class="eye-icon" type="eye" />
|
||
</view>
|
||
<view class="zi2_2" style="margin-top: 10rpx;">{{ countNum.dskNum ? countNum.dskNum : '0' }}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- #endif -->
|
||
|
||
|
||
|
||
<!-- ===== 业务渠道统计 标题栏 ===== -->
|
||
<view class="bc-header">
|
||
<view class="blue-line"></view>
|
||
<text class="section-title">业务渠道统计</text>
|
||
|
||
<!-- 右侧时间 Tab -->
|
||
<!-- <view class="time-tabs">
|
||
<text class="time-item active">本日</text>
|
||
<text class="time-item">本月</text>
|
||
<text class="time-item">本年</text>
|
||
<text class="time-item">全部</text>
|
||
<text class="time-item">自定义</text>
|
||
</view> -->
|
||
<!-- 右侧时间 Tab ✅ 改成循环 -->
|
||
<view class="time-tabs">
|
||
<text
|
||
v-for="(t,i) in ['本日','本月','本年','全部','自定义']"
|
||
:key="i"
|
||
:class="['time-item', cTab===i ? 'active' : '']"
|
||
@click.stop="switchCTab(i)"
|
||
>
|
||
{{ t }}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
<!-- 仅当点了「自定义」才出现 -->
|
||
<uni-datetime-picker
|
||
class="full-width-picker"
|
||
v-if="cTab===4"
|
||
v-model="customRange"
|
||
type="daterange"
|
||
rangeSeparator="至"
|
||
@change="onCustomRangeChange"
|
||
/>
|
||
|
||
|
||
<view v-for="stat in channelStats" :key="stat.channel" class="channel-card" @click="goSource(stat)">
|
||
<view class="c-header">
|
||
<text class="c-name">{{ stat.channel }}</text>
|
||
<view class="pk-btn" @click="toChannelPk(stat.channelId)">PK 去对比</view>
|
||
</view>
|
||
<view class="c-row four">
|
||
<view class="c-cell"><text class="c-num">{{ stat.yjdNum }}</text><text class="c-lab">已接单</text></view>
|
||
<view class="c-cell"><text class="c-num">{{ stat.jyzNum }}</text><text class="c-lab">救援中</text></view>
|
||
<view class="c-cell"><text class="c-num">{{ stat.ywcNum }}</text><text class="c-lab">已完成</text></view>
|
||
<view class="c-cell wait-car"><text class="c-num">{{ stat.dqcNum }}</text><text class="c-lab">待取车</text></view>
|
||
</view>
|
||
<view class="c-row three">
|
||
<view class="c-cell"><text class="c-num">{{ stat.receivable }}</text><text class="c-lab">应收款</text></view>
|
||
<view class="c-cell"><text class="c-num">{{ stat.receivedMoney }}</text><text class="c-lab">已收款</text></view>
|
||
<view class="c-cell"><text class="c-num">{{ stat.dskNum }}</text><text class="c-lab">待收款</text></view>
|
||
</view>
|
||
</view>
|
||
|
||
|
||
<!-- ===== 渠道卡 1:泸渝高速 ===== -->
|
||
<view class="channel-card">
|
||
<view class="c-header">
|
||
<text class="c-name">泸渝高速</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view>
|
||
|
||
<!-- 第一行 4 格 -->
|
||
<view class="c-row four">
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">已接单</text>
|
||
</view>
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">救援中</text>
|
||
</view>
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">已完成</text>
|
||
</view>
|
||
<!-- 待取车:浅灰描边 + 倾斜数字示例 -->
|
||
<view class="c-cell wait-car">
|
||
<text class="c-num">0</text><text class="c-lab">待取车</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 第二行 3 格 -->
|
||
<view class="c-row three">
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">应收款</text>
|
||
</view>
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">已收款</text>
|
||
</view>
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">待收款</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- ===== 渠道卡 1:泸渝高速 ===== -->
|
||
<view class="channel-card">
|
||
<view class="c-header">
|
||
<text class="c-name">泸渝高速</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view>
|
||
|
||
<!-- 第一行 4 格 -->
|
||
<view class="c-row four">
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">已接单</text>
|
||
</view>
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">救援中</text>
|
||
</view>
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">已完成</text>
|
||
</view>
|
||
<!-- 待取车:浅灰描边 + 倾斜数字示例 -->
|
||
<view class="c-cell wait-car">
|
||
<text class="c-num">0</text><text class="c-lab">待取车</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 第二行 3 格 -->
|
||
<view class="c-row three">
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">应收款</text>
|
||
</view>
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">已收款</text>
|
||
</view>
|
||
<view class="c-cell">
|
||
<text class="c-num">0</text><text class="c-lab">待收款</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
|
||
<!-- ===== 再复制一份改名即可:泸贵高速 / 交警二大队 … ===== -->
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<!-- ===== 业务管理统计 标题栏 ===== -->
|
||
<view class="bm-header">
|
||
<view class="blue-line"></view>
|
||
<text class="section-title">业务管理统计</text>
|
||
|
||
<!-- <view class="time-tabs">
|
||
<text class="time-item active">本日</text>
|
||
<text class="time-item">本月</text>
|
||
<text class="time-item">本年</text>
|
||
<text class="time-item">全部</text>
|
||
<text class="time-item">自定义</text>
|
||
</view> -->
|
||
<!-- 放在业务管理统计标题栏右侧 -->
|
||
<view class="time-tabs">
|
||
<text v-for="(t,i) in ['本日','本月','本年','全部','自定义']"
|
||
:key="i"
|
||
:class="['time-item', bmTimeTab===i ? 'active' : '']"
|
||
@click.stop="changeBmTime(i)">
|
||
{{ t }}
|
||
</text>
|
||
</view>
|
||
<!-- 新:外面套一层 -->
|
||
<view class="bm-picker" v-if="bmTimeTab===4">
|
||
<uni-datetime-picker class="full-width-picker" v-model="bmRange"
|
||
type="daterange"
|
||
@change="changeBmTime(4,true)" />
|
||
</view>
|
||
</view>
|
||
|
||
|
||
<!-- ===== 业务管理统计标题栏保持不变 ===== -->
|
||
|
||
<!-- ===== 业务管理卡:统一 v-for 渲染 ===== -->
|
||
<view v-for="cat in bmCategories" :key="cat" class="manage-card">
|
||
<view class="m-header">
|
||
<text class="m-title">{{ bmTitleMap[cat] || cat }}</text>
|
||
<view class="pk-btn" @click="toPk(cat)">PK 去对比</view>
|
||
</view>
|
||
|
||
<view class="m-grid">
|
||
<view class="m-item" v-for="item in bmStats[cat]" :key="item.name">
|
||
<text class="m-key">{{ item.name }}</text>
|
||
<text class="m-val">{{ item.count }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
|
||
|
||
|
||
|
||
<!-- ===== 统计卡 1:救援类型统计 ===== -->
|
||
<!-- <view class="manage-card">
|
||
<view class="m-header">
|
||
<text class="m-title">救援类型统计</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view> -->
|
||
|
||
<!-- 数据区域:任意偶数个条目均可,自动两列排版 -->
|
||
<!-- <view class="m-grid">
|
||
<view class="m-item">
|
||
<text class="m-key">道路救援</text>
|
||
<text class="m-val">46</text>
|
||
</view>
|
||
<view class="m-item">
|
||
<text class="m-key">事故救援</text>
|
||
<text class="m-val">29</text>
|
||
</view>
|
||
</view>
|
||
</view> -->
|
||
|
||
<!-- ===== 统计卡 2:故障地点统计(示例 4 项) ===== -->
|
||
<!-- <view class="manage-card">
|
||
<view class="m-header">
|
||
<text class="m-title">故障地点统计</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view>
|
||
|
||
<view class="m-grid">
|
||
<view class="m-item"><text class="m-key">新旧转换区</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">莱芜区</text><text class="m-val">29</text></view>
|
||
<view class="m-item"><text class="m-key">历城区</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">章丘区</text><text class="m-val">29</text></view>
|
||
</view>
|
||
</view> -->
|
||
|
||
<!-- 车辆类型统计 -->
|
||
<!-- <view class="manage-card">
|
||
<view class="m-header">
|
||
<text class="m-title">车辆类型统计</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view>
|
||
<view class="m-grid">
|
||
<view class="m-item"><text class="m-key">小型车</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">中型车</text><text class="m-val">29</text></view>
|
||
<view class="m-item"><text class="m-key">大型车</text><text class="m-val">46</text></view>
|
||
</view>
|
||
</view> -->
|
||
|
||
<!-- 车辆品牌统计 -->
|
||
<!-- <view class="manage-card">
|
||
<view class="m-header">
|
||
<text class="m-title">车辆品牌统计</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view>
|
||
<view class="m-grid">
|
||
<view class="m-item"><text class="m-key">奔驰</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">沃尔玛</text><text class="m-val">29</text></view>
|
||
<view class="m-item"><text class="m-key">大众</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">宝马</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">五菱宏光</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">小米汽车</text><text class="m-val">29</text></view>
|
||
<view class="m-item"><text class="m-key">凯迪拉克</text><text class="m-val">46</text></view>
|
||
</view>
|
||
</view> -->
|
||
|
||
<!-- 下车地统计 -->
|
||
<!-- <view class="manage-card">
|
||
<view class="m-header">
|
||
<text class="m-title">下车地统计</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view>
|
||
<view class="m-grid">
|
||
<view class="m-item"><text class="m-key">新旧转换区</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">莱芜区</text><text class="m-val">29</text></view>
|
||
<view class="m-item"><text class="m-key">历城区</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">章丘区</text><text class="m-val">29</text></view>
|
||
</view>
|
||
</view> -->
|
||
|
||
<!-- 移交易由统计 -->
|
||
<!-- <view class="manage-card">
|
||
<view class="m-header">
|
||
<text class="m-title">移交易由统计</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view>
|
||
<view class="m-grid">
|
||
<view class="m-item"><text class="m-key">请假</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">技术问题</text><text class="m-val">29</text></view>
|
||
</view>
|
||
</view> -->
|
||
|
||
<!-- 是否新能源统计 -->
|
||
<!-- <view class="manage-card">
|
||
<view class="m-header">
|
||
<text class="m-title">是否新能源统计</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view>
|
||
<view class="m-grid">
|
||
<view class="m-item"><text class="m-key">新能源统计</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">非新能源统计</text><text class="m-val">29</text></view>
|
||
</view>
|
||
</view> -->
|
||
|
||
<!-- 救援需求统计 -->
|
||
<!-- <view class="manage-card">
|
||
<view class="m-header">
|
||
<text class="m-title">救援需求统计</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view>
|
||
<view class="m-grid">
|
||
<view class="m-item"><text class="m-key">轮胎问题</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">汽车故障</text><text class="m-val">29</text></view>
|
||
</view>
|
||
</view> -->
|
||
|
||
<!-- 收费类型统计 -->
|
||
<!-- <view class="manage-card">
|
||
<view class="m-header">
|
||
<text class="m-title">收费类型统计</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view>
|
||
<view class="m-grid">
|
||
<view class="m-item"><text class="m-key">线上支付</text><text class="m-val">46</text></view>
|
||
<view class="m-item"><text class="m-key">线下支付</text><text class="m-val">29</text></view>
|
||
</view>
|
||
</view> -->
|
||
<!-- 是否扣车统计 -->
|
||
<!-- <view class="manage-card">
|
||
<view class="m-header">
|
||
<text class="m-title">是否扣车统计</text>
|
||
<view class="pk-btn">PK 去对比</view>
|
||
</view>
|
||
<view class="m-grid">
|
||
<view class="m-item">
|
||
<text class="m-key">待取车数量</text>
|
||
<text class="m-val">46</text>
|
||
</view>
|
||
<view class="m-item">
|
||
<text class="m-key">车辆信息</text>
|
||
<text class="m-val">29</text>
|
||
</view>
|
||
</view>
|
||
</view> -->
|
||
|
||
|
||
|
||
|
||
|
||
<!-- =========== 财务统计 BEGIN =========== -->
|
||
<!-- ========= 财务统计 ========= -->
|
||
<view class="sec-bar">
|
||
<view class="blue-line"></view>
|
||
<text class="sec-title">财务统计</text>
|
||
|
||
<!-- 时间切换 -->
|
||
<view class="time-tabs">
|
||
<text v-for="t in ['本日','本月','本年','全部','自定义']"
|
||
:key="t"
|
||
:class="['t-item', t==='本日' ? 'active' : '']">
|
||
{{ t }}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="list-wrap">
|
||
|
||
<!-- ===== 应收款统计 ===== -->
|
||
<view class="uni-card">
|
||
<view class="card-hd">
|
||
<text class="card-title">应收款统计</text>
|
||
<button class="pk-btn">PK 去对比</button>
|
||
</view>
|
||
|
||
<view class="row-g">
|
||
<view class="row"><text class="lbl">金额</text><text class="val">1414.70</text><text class="lbl">数量</text><text class="val">208</text></view>
|
||
<view class="row"><text class="lbl">相对应的渠道</text><text class="val">489</text><text class="lbl">来源</text><text class="val">512</text></view>
|
||
<view class="row"><text class="lbl">救援类型</text><text class="val">216</text><text class="lbl">故障地点</text><text class="val">390</text></view>
|
||
<view class="row"><text class="lbl">车辆品牌</text><text class="val">968</text><text class="lbl">车辆类型</text><text class="val">776</text></view>
|
||
<view class="row"><text class="lbl">是否新能源</text><text class="val">994</text><text class="lbl">救援需求</text><text class="val">468</text></view>
|
||
<view class="row"><text class="lbl">收费类型</text><text class="val">965</text><text class="lbl">待取车数量</text><text class="val">684</text></view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- ===== 已收款统计 ===== -->
|
||
<view class="uni-card">
|
||
<view class="card-hd">
|
||
<text class="card-title">已收款统计</text>
|
||
<button class="pk-btn">PK 去对比</button>
|
||
</view>
|
||
|
||
<view class="row-g">
|
||
<view class="row"><text class="lbl">金额</text><text class="val">6629.45</text><text class="lbl">数量</text><text class="val">646</text></view>
|
||
<view class="row"><text class="lbl">相对应的渠道</text><text class="val">466</text><text class="lbl">来源</text><text class="val">271</text></view>
|
||
<view class="row"><text class="lbl">救援类型</text><text class="val">268</text><text class="lbl">故障地点</text><text class="val">573</text></view>
|
||
<view class="row"><text class="lbl">车辆品牌</text><text class="val">828</text><text class="lbl">车辆类型</text><text class="val">242</text></view>
|
||
<view class="row"><text class="lbl">是否新能源</text><text class="val">240</text><text class="lbl">救援需求</text><text class="val">432</text></view>
|
||
<view class="row"><text class="lbl">收费类型</text><text class="val">752</text><text class="lbl">待取车数量</text><text class="val">627</text></view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- ===== 待收款统计 ===== -->
|
||
<view class="uni-card">
|
||
<view class="card-hd">
|
||
<text class="card-title">待收款统计</text>
|
||
<button class="pk-btn">PK 去对比</button>
|
||
</view>
|
||
|
||
<view class="row-g">
|
||
<view class="row"><text class="lbl">金额</text><text class="val">7774.92</text><text class="lbl">数量</text><text class="val">504</text></view>
|
||
<view class="row"><text class="lbl">相对应的渠道</text><text class="val">240</text><text class="lbl">来源</text><text class="val">365</text></view>
|
||
<view class="row"><text class="lbl">救援类型</text><text class="val">608</text><text class="lbl">故障地点</text><text class="val">936</text></view>
|
||
<view class="row"><text class="lbl">车辆品牌</text><text class="val">347</text><text class="lbl">车辆类型</text><text class="val">841</text></view>
|
||
<view class="row"><text class="lbl">是否新能源</text><text class="val">765</text><text class="lbl">救援需求</text><text class="val">219</text></view>
|
||
<view class="row"><text class="lbl">收费类型</text><text class="val">630</text><text class="lbl">待取车数量</text><text class="val">637</text></view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
|
||
<!-- =========== 财务统计 END =========== -->
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<view class="four-box-header_2">
|
||
<view class="four-box-header">
|
||
<view class="blue-line"></view>
|
||
<text class="four-box-header-title">救援列表</text>
|
||
</view>
|
||
</view>
|
||
<view class="tap-box">
|
||
<view class="ques" v-if="loading && orderList.length == 0">
|
||
<view class="loading-container">
|
||
<view class="loading-spinner"></view>
|
||
<text class="loading-text">加载中,请稍候...</text>
|
||
</view>
|
||
</view>
|
||
<view class="ques" v-else-if="!loading && orderList.length == 0">
|
||
<image src="../../static/quesheng.png" mode="aspectFit"></image>
|
||
</view>
|
||
<!-- <view style="display: flex;flex-direction: column;row-gap: 10px;" v-else>
|
||
<order-card-new :status="1" @revokeOk="revokeOrderHandle"
|
||
@refresh="getlist" v-for="(item, index) in orderList" :key="index" :orderData="item"
|
||
:activeTab="activeTab" @update:activeTab="activeTab = $event"></order-card-new>
|
||
</view> -->
|
||
</view>
|
||
</view>
|
||
|
||
|
||
<view class="stat-cards-container">
|
||
<view class="stat-cards">
|
||
<view class="stat-card">
|
||
<text class="stat-num">{{ countNum.yjdNum }}</text>
|
||
<text class="stat-label">已接单</text>
|
||
</view>
|
||
<view class="stat-card">
|
||
<text class="stat-num">{{ countNum.jyzNum }}</text>
|
||
<text class="stat-label">救援中</text>
|
||
</view>
|
||
<view class="stat-card">
|
||
<text class="stat-num">{{ countNum.ywcNum }}</text>
|
||
<text class="stat-label">已完成</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 展开后的额外统计块 -->
|
||
<view class="expanded-cards">
|
||
<view class="stat-cards" style="margin-bottom: 20rpx;">
|
||
<view class="stat-card">
|
||
<text class="stat-num">{{ countNum.yingskNum }}</text>
|
||
<text class="stat-label">应收款(元)</text>
|
||
</view>
|
||
<view class="stat-card">
|
||
<text class="stat-num">{{ countNum.yiskNum }}</text>
|
||
<text class="stat-label">已收款(元)</text>
|
||
</view>
|
||
</view>
|
||
<view class="stat-cards">
|
||
<view class="stat-card">
|
||
<text class="stat-num">{{ countNum.dskNum }}</text>
|
||
<text class="stat-label">待收款(元)</text>
|
||
</view>
|
||
<view class="stat-card">
|
||
<text class="stat-num">{{ countNum.dqcNum }}</text>
|
||
<text class="stat-label">待取车</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 搜索和时间筛选区域 -->
|
||
<view class="search-filter-area">
|
||
<!-- 全部、筛选选项卡 -->
|
||
<view class="tab-choose-class">
|
||
<view class="tab-content" @click="tabChoose(item, index)" v-for='(item, index) in tabTwoList'
|
||
:key='index'>
|
||
<view class='tab-name-class' :style='{ color: index + 1 == tabValue ? "#101A3E" : "#8D90A6" }'>
|
||
{{ item }}
|
||
<view class="icon-tab" v-if='index >= 1'>
|
||
<image src="@/static/icons/homeOrderCard/xialajiantou.svg" mode="scaleToFill"></image>
|
||
</view>
|
||
</view>
|
||
<view class="tab-icon"
|
||
:style='{ background: index + 1 == tabValue ? "linear-gradient( 180deg, #054DF3 0%, #55A3FF 100%)" : "" }'>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 筛选弹窗 -->
|
||
<u-popup :show="isShowPop" ref="popup" round="55" @close="closePop" @open="openPop">
|
||
<view class="popup-content" :style="{'height':windowsHeight + 'px'}">
|
||
<view class="popup-header">
|
||
<text>选择筛选项</text>
|
||
<view style="display: flex;justify-content: space-between" @click="clearSelection">
|
||
<u-icon name="close-circle" size="18" color="#327DFB"></u-icon>
|
||
<text style="color:#327DFB;">清除筛选项</text>
|
||
</view>
|
||
</view>
|
||
|
||
<scroll-view scroll-y="true" class="scroll_view_style" style="height: 80%">
|
||
<view class="popup-body">
|
||
<view style="">
|
||
<view class="filter-section" style="padding: 0 10rpx;">
|
||
<text>时间范围</text>
|
||
<view style="margin-top: 10rpx">
|
||
<uni-datetime-picker v-model="queryParams.rangeTime" type="daterange"
|
||
rangeSeparator="至" />
|
||
</view>
|
||
</view>
|
||
<!-- 其余筛选项省略, 保持原有逻辑 -->
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<view class="popup-footer">
|
||
<u-button @click="closePop" style="background: #F7F8FC;color: black">取消</u-button>
|
||
<u-button @click="submitPop">确定</u-button>
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
</view>
|
||
|
||
<!-- 订单列表 -->
|
||
<view class="dil">
|
||
<!-- 初始加载状态 -->
|
||
<view class="ques" v-if="initialLoading">
|
||
<view class="loading-container">
|
||
<view class="loading-spinner"></view>
|
||
<text class="loading-text">加载中,请稍候...</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 无数据状态 -->
|
||
<view class="ques" v-else-if="!initialLoading && orderList.length == 0">
|
||
<image src="@/static/quesheng.png" mode=""></image>
|
||
</view>
|
||
|
||
<view v-else>
|
||
<order-card-vue @refresh="getlist" :status="gindex" v-for="(item,index) in orderList" :key="index"
|
||
:orderData="item" :brandList="brandList" :staffList="staffList"
|
||
:activeTab="activeInfoTab"></order-card-vue>
|
||
|
||
<!-- 底部加载更多状态 -->
|
||
<view v-if="loadingMore" class="loading-more">
|
||
<view class="loading-spinner mini"></view>
|
||
<text>正在加载更多...</text>
|
||
</view>
|
||
|
||
<view v-if="!hasMore" class="no-more-data">
|
||
<text>没有更多数据了</text>
|
||
</view>
|
||
</view>
|
||
<view style="width: 100%; height: 60px;"></view>
|
||
</view>
|
||
</view>
|
||
|
||
|
||
<!-- 分类统计 -->
|
||
<view v-else>
|
||
<view class="sub-tabs">
|
||
<text v-for="(tab, index) in filteredSubTabs" :key="index"
|
||
:class="['sub-tab-item', activeSubTab === tab.value ? 'active' : '']"
|
||
@click="switchSubTab(tab.value)">
|
||
{{ tab.label }}
|
||
</text>
|
||
</view>
|
||
|
||
<!-- 列表部分 -->
|
||
<category-list :type="activeSubTab" :list="currentList" />
|
||
</view>
|
||
<!-- 各种 picker 组件 -->
|
||
<lzc-picker ref="lzcPickerRescueStatus" :pickerList="jyStatusOptions" pickerTittle="选择救援状态"
|
||
@change="onPickerConfirm('rescueStatus', $event)" />
|
||
<lzc-picker ref="lzcPickerChannel" :pickerList="channelOptions" pickerTittle="选择渠道"
|
||
@change="onPickerConfirm('channel', $event)" />
|
||
<lzc-picker ref="lzcPickerSource" :pickerList="sourceOptions" pickerTittle="选择来源"
|
||
@change="onPickerConfirm('source', $event)" />
|
||
<lzc-picker ref="lzcPickerDispatcher" :pickerList="dispatcherOptions" pickerTittle="选择调度"
|
||
@change="onPickerConfirm('secondDispatchId', $event)" />
|
||
<lzc-picker ref="lzcPickerRescueType" :pickerList="jyTypeOptions" pickerTittle="选择救援类型"
|
||
@change="onPickerConfirm('rescueType', $event)" />
|
||
<lzc-picker ref="lzcPickerFaultType" :pickerList="faultTypeOptions" pickerTittle="选择故障类型"
|
||
@change="onPickerConfirm('faultType', $event)" />
|
||
<lzc-picker ref="lzcPickerPhenomenon" :pickerList="phenomenonOptions" pickerTittle="选择故障现象"
|
||
@change="onPickerConfirm('phenomenon', $event)" />
|
||
<lzc-picker ref="lzcPickerRescueDriver" :pickerList="rescueDriverOptions" pickerTittle="选择救援司机"
|
||
@change="onPickerConfirm('rescueDriver', $event)" />
|
||
<lzc-picker ref="lzcPickerRescueCar" :pickerList="rescueCarOptions" pickerTittle="选择救援车牌号"
|
||
@change="onPickerConfirm('rescueCar', $event)" />
|
||
</view>
|
||
|
||
</template>
|
||
|
||
<!-- 省略 script 与 style 块,其内容保持用户提供版本 -->
|
||
|
||
<script>
|
||
// import OrderCardVue from '../../components/orderCard/StatisticsInfoOrderCard.vue';
|
||
import OrderCardNew from '@/components/orderCard/OrderCardNew.vue'
|
||
import request from '../../utils/request';
|
||
import CategoryList from '../../components/categoryList/CategoryList.vue';
|
||
import lzcPicker from '@/components/lzc-picker/lzc-picker.vue';
|
||
import BusinessPanel from '@/components/BusinessPanel.vue'
|
||
import {
|
||
hasRole,
|
||
hasRoleNew
|
||
} from "@/utils/auth";
|
||
|
||
export default {
|
||
name: "StatisticsInfo",
|
||
data() {
|
||
return {
|
||
customRange: [], // ← 加这一行,保证是响应式数组
|
||
// ↓ 渠道 Tab 当前索引
|
||
channelTabIdx: 0,
|
||
|
||
// ↓ 你已有 — 改默认值为空数组,供模板 v-for
|
||
channelOptions: [],
|
||
// 时间 Tab(0~4 对应 本日、本月…)
|
||
cTab: 0,
|
||
timeTypeMap: ['day', 'month', 'year', 'all', 'more'],
|
||
/* ↓↓↓ 新增 ↓↓↓ */
|
||
// bmCatKeys: [
|
||
// 'rescueType', // 救援类型统计
|
||
// 'faultDistrict', // 故障地点统计
|
||
// 'carBrand', // 车辆品牌统计
|
||
// 'carType', // 车辆类型统计
|
||
// 'downDestination', // 下车地统计
|
||
// 'transferReason', // 移交易由统计
|
||
// 'newEnergy', // 是否新能源统计
|
||
// 'rescueNeeds', // 救援需求统计
|
||
// 'feeType', // 收费类型统计
|
||
// 'kouChe' // 是否扣车统计
|
||
// ],
|
||
bmTimeTab: 0, // 0 本日 1 本月 2 本年 3 全部 4 自定义
|
||
bmRange: [], // 自定义时间
|
||
bmStats: {}, // 后端返回的整个 data
|
||
bmTitleMap:{ // key ➜ 卡片标题
|
||
rescueType:'救援类型统计',
|
||
faultDistrict:'故障地点统计',
|
||
carBrand:'车辆品牌统计',
|
||
carType:'车辆类型统计',
|
||
downDestination:'下车地统计',
|
||
transferReason:'移交易由统计',
|
||
newEnergy:'是否新能源统计',
|
||
rescueNeeds:'救援需求统计',
|
||
feeType:'收费类型统计',
|
||
kouChe:'是否扣车统计'
|
||
},
|
||
|
||
|
||
|
||
financeTimeTab:0, // 0~4 对应 本日…自定义
|
||
financeData:{
|
||
/* 应收款 y 前缀 */
|
||
yAmount:0,yQty:0,yChannel:0,ySource:0,
|
||
yRescueType:0,yFault:0,yBrand:0,yCarType:0,
|
||
yNewEnergy:0,yNeed:0,yFeeType:0,yDqc:0,
|
||
/* 已收款 r 前缀 */
|
||
rAmount:0,rQty:0,rChannel:0,rSource:0,
|
||
rRescueType:0,rFault:0,rBrand:0,rCarType:0,
|
||
rNewEnergy:0,rNeed:0,rFeeType:0,rDqc:0,
|
||
},
|
||
|
||
cTab: 0, // 0:本日 1:本月 ...
|
||
channelStats: [], // 渠道统计列表
|
||
|
||
activeTab: "order", // 默认进入工单统计
|
||
activeSubTab: "driver", // 默认进入救援司机
|
||
|
||
// 工单统计相关数据
|
||
tabValue: 1,
|
||
channelTabValue: 1,
|
||
timeType: "all",
|
||
range: [],
|
||
startTimeStr: null,
|
||
endTimeStr: null,
|
||
searchText: '',
|
||
searchKeyword: null,
|
||
gindex: 1,
|
||
brandList: [],
|
||
staffList: [],
|
||
orderList: [],
|
||
total: 0,
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
totalPages: 0,
|
||
activeInfoTab: 4, // 信息选项卡
|
||
initialLoading: true,
|
||
loadingMore: false,
|
||
hasMore: true,
|
||
scrollTop: 0,
|
||
totalNum: null,
|
||
|
||
// 筛选相关数据
|
||
isShowPop: false,
|
||
windowsHeight: 700,
|
||
tabTwoList: ["全部", "筛选"],
|
||
queryParams: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
timeType: null,
|
||
rescueStatus: null,
|
||
rescueType: null,
|
||
licenseNum: null,
|
||
rangeTime: [],
|
||
startTimeStr: null,
|
||
endTimeStr: null,
|
||
|
||
connectionName: null,
|
||
connectionPhone: null,
|
||
rescuePosition: null,
|
||
secondDispatchId: null,
|
||
driverId: null,
|
||
rescueDriver: null,
|
||
rescueCar: null,
|
||
driverCarNum: null,
|
||
faultType: null,
|
||
phenomenon: null,
|
||
channel: null,
|
||
channelId: null,
|
||
source: null
|
||
},
|
||
rescueStatusList: [{
|
||
text: "已接单",
|
||
value: "1"
|
||
},
|
||
{
|
||
text: "救援中",
|
||
value: "2"
|
||
},
|
||
{
|
||
text: "已完成",
|
||
value: "3"
|
||
}
|
||
],
|
||
sortList: [{
|
||
text: "正序",
|
||
value: "asc"
|
||
},
|
||
{
|
||
text: "倒序",
|
||
value: "desc"
|
||
}
|
||
],
|
||
|
||
// 分类统计相关数据
|
||
subTabs: [{
|
||
label: "救援司机",
|
||
value: "driver"
|
||
},
|
||
{
|
||
label: "救援车辆",
|
||
value: "vehicle"
|
||
},
|
||
{
|
||
label: "调度",
|
||
value: "dispatch"
|
||
},
|
||
],
|
||
driverList: [],
|
||
vehicleList: [],
|
||
dispatchList: [],
|
||
orderStats: {
|
||
received: 235,
|
||
rescuing: 152,
|
||
completed: 39,
|
||
},
|
||
// 调度人员信息
|
||
dispatcherColumns: [],
|
||
userinfo: {},
|
||
jyStatusOptions: [],
|
||
jyTypeOptions: [],
|
||
faultTypeOptions: [],
|
||
phenomenonOptions: [],
|
||
currentPickerType: '', // 当前选择器类型
|
||
dispatcherOptions: [], // 调度选项
|
||
rescueDriverOptions: [],
|
||
rescueCarOptions: [],
|
||
channelOptions: [],
|
||
sourceOptions: [],
|
||
|
||
countNum: {
|
||
jyzNum: 0,
|
||
dzfNum: 0,
|
||
dqcNum: 0,
|
||
ywcNum: 0,
|
||
zwxNum: 0,
|
||
yjdNum: 0,
|
||
yingskNum: 0,
|
||
yiskNum: 0,
|
||
dskNum: 0,
|
||
},
|
||
};
|
||
},
|
||
components: {
|
||
// OrderCardVue,
|
||
OrderCardNew,
|
||
CategoryList,
|
||
lzcPicker,
|
||
BusinessPanel
|
||
},
|
||
onLoad(option) {
|
||
this.gindex = option.id || 1
|
||
this.getOptions()
|
||
this.getlist()
|
||
this.getBrandList()
|
||
this.getStaffList()
|
||
uni.getSystemInfo({
|
||
success: function(res) {
|
||
this.windowsHeight = res.windowHeight - 100;
|
||
console.log('屏幕高度:', res.windowHeight);
|
||
}
|
||
});
|
||
|
||
this.fetchBmStats();
|
||
// 只需一次,后面所有刷新都在 fetchChannelStats 内部做
|
||
this.loadChannelOptions();
|
||
},
|
||
created() {
|
||
// this.fetchChannelStats('day');
|
||
},
|
||
onReachBottom() {
|
||
console.log('触底加载');
|
||
if (this.pageNum >= this.totalPages) {
|
||
this.hasMore = false;
|
||
} else if (!this.loadingMore) {
|
||
this.loadingMore = true;
|
||
this.pageNum++;
|
||
this.getlist();
|
||
}
|
||
},
|
||
onPageScroll(e) {
|
||
this.scrollTop = e.scrollTop;
|
||
},
|
||
watch: {
|
||
range(newval) {
|
||
if (newval && newval.length === 2) {
|
||
this.startTimeStr = newval[0];
|
||
this.endTimeStr = newval[1];
|
||
this.pageNum = 1;
|
||
this.orderList = [];
|
||
this.hasMore = true;
|
||
this.initialLoading = true;
|
||
this.getlist();
|
||
}
|
||
},
|
||
'queryParams.rangeTime': {
|
||
handler(newval) {
|
||
if (newval && newval.length === 2) {
|
||
this.queryParams.startTimeStr = newval[0];
|
||
this.queryParams.endTimeStr = newval[1];
|
||
this.queryParams.timeType = 'more';
|
||
} else {
|
||
this.queryParams.startTimeStr = null;
|
||
this.queryParams.endTimeStr = null;
|
||
}
|
||
},
|
||
deep: true
|
||
}
|
||
},
|
||
computed: {
|
||
/* 过滤掉 null 或空数组的分类,只渲染有数据的 */
|
||
bmCategories(){
|
||
// return Object.keys(this.bmStats)
|
||
// .filter(k=>Array.isArray(this.bmStats[k]) && this.bmStats[k].length);
|
||
|
||
if (!this.bmStats || typeof this.bmStats !== 'object') {
|
||
return [];
|
||
}
|
||
|
||
return Object.keys(this.bmStats).filter(k => {
|
||
const value = this.bmStats[k];
|
||
return Array.isArray(value) && value.length > 0;
|
||
});
|
||
},
|
||
|
||
currentList() {
|
||
switch (this.activeSubTab) {
|
||
case "driver":
|
||
return this.driverList;
|
||
case "vehicle":
|
||
return this.vehicleList;
|
||
case "dispatch":
|
||
return this.dispatchList;
|
||
default:
|
||
return [];
|
||
}
|
||
},
|
||
filteredSubTabs() {
|
||
const tabs = [{
|
||
label: "救援司机",
|
||
value: "driver"
|
||
},
|
||
{
|
||
label: "救援车辆",
|
||
value: "vehicle"
|
||
}
|
||
];
|
||
|
||
if (this.hasRole('ddzx')) {
|
||
tabs.push({
|
||
label: "调度",
|
||
value: "dispatch"
|
||
});
|
||
}
|
||
|
||
return tabs;
|
||
},
|
||
},
|
||
methods: {
|
||
/* 进入来源页 */
|
||
async goSource(stat){
|
||
const map = ['day','month','year','all','more']
|
||
const dateType = map[this.cTab]
|
||
|
||
// 共用的查询串
|
||
const baseQuery = [
|
||
`channelId=${stat.channelId}`,
|
||
`channel=${encodeURIComponent(stat.channel)}`,
|
||
`dateType=${dateType}`
|
||
].join('&')
|
||
|
||
try{
|
||
const { data:list=[] } = await request({
|
||
url:`/rescue-channel-source/sources/${stat.channelId}`,
|
||
method:'get'
|
||
})
|
||
|
||
// 没有来源 ⇒ 直接查订单
|
||
if(!list.length){
|
||
uni.navigateTo({
|
||
url:`/pages/rescue/businessManageOrder?${baseQuery}&sourceName=`
|
||
})
|
||
}else{
|
||
// 有来源 ⇒ 去来源页
|
||
uni.navigateTo({
|
||
url:`/pages/rescue/businessManageSource?${baseQuery}`
|
||
})
|
||
}
|
||
}catch(e){
|
||
uni.showToast({ title:'获取来源失败', icon:'none' })
|
||
}
|
||
},
|
||
|
||
switchCTab(i){ // 顶部时间 Tab 点击
|
||
this.cTab = i;
|
||
// this.fetchChannelStats();
|
||
if(i!==4) this.fetchChannelStats()
|
||
},
|
||
/* 选完日期再打接口 */
|
||
onCustomRangeChange(val){
|
||
// val 形如 ['2024-01-01','2024-01-31']
|
||
if(Array.isArray(val) && val.length===2){
|
||
this.customRange = val
|
||
this.fetchChannelStats()
|
||
}
|
||
},
|
||
|
||
// ③ 真正调用 /app/rescueInfo/getRescueStatistics
|
||
async fetchChannelStats(){
|
||
const timeType = ['day','month','year','all','more'][this.cTab]
|
||
|
||
/* ---- 参数拼装 ---- */
|
||
const baseParams = { timeType }
|
||
if(timeType==='more'){
|
||
if(!this.customRange.length){
|
||
return uni.showToast({title:'请选择时间区间',icon:'none'})
|
||
}
|
||
baseParams.startTimeStr = this.customRange[0] + ' 00:00:01'
|
||
baseParams.endTimeStr = this.customRange[1] + ' 23:59:59'
|
||
}
|
||
|
||
/* ---- 并发请求各渠道 ---- */
|
||
const list = this.channelOptions.filter(c=>c.id!=='all')
|
||
const tasks = list.map(c=>{
|
||
return request({
|
||
url:'/app/rescueInfo/getRescueStatistics',
|
||
params:{ ...baseParams, channel:c.nickname }
|
||
}).then(r=>({
|
||
channel : c.nickname,
|
||
channelId : c.id,
|
||
yjdNum : r.data.yjdNum,
|
||
jyzNum : r.data.jyzNum,
|
||
ywcNum : r.data.ywcNum,
|
||
dqcNum : r.data.dqcNum,
|
||
receivable : (r.data.yingskNum/100).toFixed(1),
|
||
receivedMoney : (r.data.yiskNum/100).toFixed(1),
|
||
dskNum : (r.data.dskNum/100).toFixed(1),
|
||
}))
|
||
})
|
||
this.channelStats = await Promise.all(tasks)
|
||
|
||
// const timeType = this.timeTypeMap[this.cTab]
|
||
// // 过滤掉“全部”那条,只查真正的渠道
|
||
// const list = this.channelOptions.filter(c => c.id !== 'all')
|
||
// console.log('list',list)
|
||
// // 并发请求每个渠道的数据
|
||
// const tasks = list.map(c =>
|
||
// request({
|
||
// url : '/app/rescueInfo/getRescueStatistics',
|
||
// params: { timeType, channel: c.nickname }
|
||
// }).then(r => ({
|
||
// channel : c.nickname, // 前端取中文名
|
||
// channelId : c.id,
|
||
// yjdNum : r.data.yjdNum,
|
||
// jyzNum : r.data.jyzNum,
|
||
// ywcNum : r.data.ywcNum,
|
||
// dqcNum : r.data.dqcNum,
|
||
// receivable : (r.data.yingskNum / 100).toFixed(1),
|
||
// receivedMoney : (r.data.yiskNum / 100).toFixed(1),
|
||
// dskNum : (r.data.dskNum / 100).toFixed(1)
|
||
// }))
|
||
// )
|
||
|
||
// this.channelStats = await Promise.all(tasks)
|
||
/* 接口字段 → 页面字段 */
|
||
// this.channelStats = [{
|
||
// channel: chn.nickname,
|
||
// channelId: chn.id,
|
||
// // 已接单、救援中…接口字段一一对应
|
||
// yjdNum: data.yjdNum,
|
||
// jyzNum: data.jyzNum,
|
||
// ywcNum: data.ywcNum,
|
||
// dqcNum: data.dqcNum,
|
||
// receivable: (data.yingskNum/100).toFixed(1),
|
||
// receivedMoney: (data.yiskNum/100).toFixed(1),
|
||
// dskNum: (data.dskNum/100).toFixed(1)
|
||
// }];
|
||
},
|
||
|
||
|
||
|
||
|
||
changeBmTime(i,rangePicked=false){
|
||
this.bmTimeTab=i;
|
||
/* 自定义必须选完区间再请接口 */
|
||
if(i===4 && !rangePicked) return;
|
||
const map=['day','month','year','all','more'];
|
||
const params={timeType:map[i]};
|
||
if(i===4){params.startTime=this.bmRange[0];params.endTime=this.bmRange[1];}
|
||
this.fetchBmStats(params);
|
||
},
|
||
|
||
/* 真正请求接口 */
|
||
fetchBmStats(params={timeType:'day'}){
|
||
request({
|
||
url:'/rescueBusiness/statistics/overview',
|
||
method:'get',
|
||
params
|
||
}).then(res=>{
|
||
const raw = res.data || {};
|
||
const filled = {};
|
||
|
||
/* 给 10 个分类都补一份数据,没数据就放一条 count=0 */
|
||
this.bmCatKeys.forEach(k=>{
|
||
if(Array.isArray(raw[k]) && raw[k].length){
|
||
filled[k] = raw[k];
|
||
}else{
|
||
filled[k] = [{ name:'—', count:0 }]; // 占位
|
||
}
|
||
});
|
||
|
||
this.bmStats = filled;
|
||
});
|
||
},
|
||
|
||
|
||
|
||
|
||
|
||
// PK 跳转
|
||
toChannelPk(channelId) {
|
||
uni.navigateTo({
|
||
url: `/pages/rescue/channelPk?channelId=${channelId}`
|
||
});
|
||
},
|
||
|
||
|
||
|
||
hasRole,
|
||
hasRoleNew,
|
||
switchTab(tab) {
|
||
this.activeTab = tab;
|
||
if (tab == 'category') {
|
||
this.switchSubTab('driver')
|
||
}
|
||
},
|
||
switchSubTab(tab) {
|
||
this.activeSubTab = tab;
|
||
let data = {}
|
||
if (tab == 'driver') {
|
||
data.queryType = 'driver'
|
||
this.getStatisticsList(data)
|
||
} else if (tab == 'vehicle') {
|
||
data.queryType = 'car'
|
||
this.getStatisticsList(data)
|
||
} else if (tab == 'dispatch') {
|
||
data.queryType = 'dispatch'
|
||
this.getStatisticsList(data)
|
||
}
|
||
console.log('切换到tab:', tab);
|
||
},
|
||
switchInfoTab(index) {
|
||
this.activeInfoTab = index;
|
||
console.log('切换到信息选项卡:', index);
|
||
},
|
||
toggleExpand() {
|
||
this.isExpanded = !this.isExpanded;
|
||
},
|
||
goBack() {
|
||
uni.navigateBack();
|
||
},
|
||
Fourhammers() {
|
||
request({
|
||
url: '/app/rescueInfo/getRescueStatistics',
|
||
method: 'get',
|
||
params: {
|
||
timeType: this.timeType,
|
||
startTimeStr: this.startTimeStr,
|
||
endTimeStr: this.endTimeStr,
|
||
}
|
||
}).then((res) => {
|
||
console.log('四个', res);
|
||
this.countNum.dqcNum = res.data.dqcNum
|
||
this.countNum.dzfNum = res.data.dzfNum
|
||
this.countNum.jyzNum = res.data.jyzNum
|
||
this.countNum.ywcNum = res.data.ywcNum
|
||
this.countNum.yjdNum = res.data.yjdNum
|
||
this.countNum.yingskNum = res.data.yingskNum ? res.data.yingskNum / 100 : 0
|
||
this.countNum.yiskNum = res.data.yiskNum ? res.data.yiskNum / 100 : 0
|
||
this.countNum.dskNum = res.data.dskNum ? res.data.dskNum / 100 : 0
|
||
})
|
||
},
|
||
getRescueList(item){
|
||
return new Promise((resolve, reject) => {
|
||
this.loading = true;
|
||
let data = {
|
||
rescueStatus: 1,
|
||
pageSize: this.pageSize,
|
||
pageNum: this.pageNum,
|
||
channel: item
|
||
}
|
||
request({
|
||
url: '/app/rescueInfo/getRescueList',
|
||
method: 'get',
|
||
params: data
|
||
}).then((res) => {
|
||
console.log('首页', res);
|
||
if (res.code == 200) {
|
||
if (this.pageNum != 1) {
|
||
this.orderList = this.orderList.concat(res.rows)
|
||
} else {
|
||
this.orderList = res.rows
|
||
}
|
||
let total = res.total
|
||
this.totalPages = Math.ceil(total / this.pageSize);
|
||
}
|
||
resolve(); // 请求完成
|
||
}).catch(error => {
|
||
console.error('获取列表失败', error);
|
||
reject(error);
|
||
}).finally(() => {
|
||
this.loading = false;
|
||
})
|
||
});
|
||
},
|
||
|
||
showPicker(type) {
|
||
this.currentPickerType = type;
|
||
|
||
// 根据类型选择对应的选择器引用
|
||
let pickerRef = '';
|
||
|
||
switch (type) {
|
||
case 'channel':
|
||
pickerRef = 'lzcPickerChannel';
|
||
break;
|
||
case 'source':
|
||
pickerRef = 'lzcPickerSource';
|
||
break;
|
||
case 'rescueStatus':
|
||
pickerRef = 'lzcPickerRescueStatus';
|
||
break;
|
||
case 'secondDispatchId':
|
||
pickerRef = 'lzcPickerDispatcher';
|
||
break;
|
||
case 'rescueType':
|
||
pickerRef = 'lzcPickerRescueType';
|
||
break;
|
||
case 'faultType':
|
||
pickerRef = 'lzcPickerFaultType';
|
||
break;
|
||
case 'phenomenon':
|
||
pickerRef = 'lzcPickerPhenomenon';
|
||
break;
|
||
case 'rescueCar':
|
||
pickerRef = 'lzcPickerRescueCar';
|
||
break;
|
||
case 'rescueDriver':
|
||
pickerRef = 'lzcPickerRescueDriver';
|
||
break;
|
||
default:
|
||
console.error('未知的选择器类型:', type);
|
||
return;
|
||
}
|
||
|
||
// 确保选择器引用存在
|
||
if (!this.$refs[pickerRef]) {
|
||
console.error(`选择器引用 ${pickerRef} 未找到`);
|
||
return;
|
||
}
|
||
|
||
// 如果选项为空,先加载数据
|
||
this.loadPickerOptions(type).then(() => {
|
||
this.$refs[pickerRef].handleShow();
|
||
}).catch(error => {
|
||
console.error('加载选项失败:', error);
|
||
});
|
||
},
|
||
|
||
|
||
async loadPickerOptions(type) {
|
||
switch (type) {
|
||
case 'channel':
|
||
if (this.channelOptions.length === 0) {
|
||
await this.loadChannelOptions();
|
||
}
|
||
break;
|
||
case 'source':
|
||
if (this.sourceOptions.length === 0) {
|
||
await this.loadSourceOptions();
|
||
}
|
||
break;
|
||
case 'rescueStatus':
|
||
if (this.jyStatusOptions.length === 0) {
|
||
await this.loadjyStatusOptions();
|
||
}
|
||
break;
|
||
case 'secondDispatchId':
|
||
if (this.dispatcherOptions.length === 0) {
|
||
await this.loadDispatcherOptions();
|
||
}
|
||
break;
|
||
case 'rescueType':
|
||
if (this.jyTypeOptions.length === 0) {
|
||
await this.loadjyTypeOptions();
|
||
}
|
||
break;
|
||
case 'faultType':
|
||
if (this.faultTypeOptions.length === 0) {
|
||
await this.loadFaultTypeOptions();
|
||
}
|
||
break;
|
||
case 'phenomenon':
|
||
if (this.phenomenonOptions.length === 0) {
|
||
await this.loadPhenomenonOptions();
|
||
}
|
||
break;
|
||
case 'rescueDriver':
|
||
if (this.rescueDriverOptions.length === 0) {
|
||
await this.loadRescueDriverOptions();
|
||
}
|
||
break;
|
||
case 'rescueCar':
|
||
if (this.rescueCarOptions.length === 0) {
|
||
await this.loadRescueCarOptions();
|
||
}
|
||
break;
|
||
}
|
||
},
|
||
|
||
// 选择器确认回调
|
||
onPickerConfirm(field, selectedItem) {
|
||
if (selectedItem && selectedItem.value) {
|
||
if (field == 'rescueDriver') {
|
||
this.queryParams.driverId = selectedItem.id
|
||
} else if (field == 'rescueCar') {
|
||
this.queryParams.driverCarNum = selectedItem.value
|
||
}else if(field == 'channel') {
|
||
this.queryParams.channelId = selectedItem.id
|
||
}
|
||
// 根据字段名设置对应的值
|
||
this.queryParams[field] = selectedItem.value;
|
||
|
||
// 强制更新视图
|
||
this.$forceUpdate();
|
||
console.log(`选择了 ${field}:`, selectedItem);
|
||
}
|
||
},
|
||
|
||
|
||
// 获取选中项的显示文本
|
||
getSelectedLabel(type, value) {
|
||
let options = [];
|
||
switch (type) {
|
||
case 'channel':
|
||
options = this.channelOptions;
|
||
break;
|
||
case 'source':
|
||
options = this.sourceOptions;
|
||
break;
|
||
case 'rescueStatus':
|
||
options = this.jyStatusOptions;
|
||
break;
|
||
case 'secondDispatchId':
|
||
options = this.dispatcherOptions;
|
||
break;
|
||
case 'rescueType':
|
||
options = this.jyTypeOptions;
|
||
break;
|
||
case 'faultType':
|
||
options = this.faultTypeOptions;
|
||
break;
|
||
case 'phenomenon':
|
||
options = this.phenomenonOptions;
|
||
break;
|
||
case 'rescueDriver':
|
||
options = this.rescueDriverOptions;
|
||
break;
|
||
case 'rescueCar':
|
||
options = this.rescueCarOptions;
|
||
break;
|
||
default:
|
||
options = [];
|
||
}
|
||
|
||
const selected = options.find(item => item.value === value);
|
||
return selected ? selected.nickname : '请选择';
|
||
},
|
||
openFilter() {
|
||
uni.showToast({
|
||
title: "筛选功能待实现",
|
||
icon: "none",
|
||
});
|
||
},
|
||
|
||
// 选项卡选择
|
||
tabChoose(item, index) {
|
||
this.tabValue = index + 1
|
||
if (1 == this.tabValue) {
|
||
this.timeType = "day"
|
||
} else if (2 == this.tabValue) {
|
||
this.timeType = "month"
|
||
} else if (3 == this.tabValue) {
|
||
this.timeType = "year"
|
||
}else if (4 == this.tabValue) {
|
||
this.timeType = "all"
|
||
}else if (5 == this.tabValue) {
|
||
this.timeType = "more"
|
||
this.range = []
|
||
}
|
||
if (5 == this.tabValue) {
|
||
if (this.range.length > 0) {
|
||
this.startTimeStr = this.range[0]
|
||
this.endTimeStr = this.range[1]
|
||
this.Fourhammers()
|
||
}
|
||
} else {
|
||
this.Fourhammers()
|
||
}
|
||
// this.tabValue = index + 1;
|
||
// if (1 == this.tabValue) {
|
||
// // 全部 - 清除筛选条件
|
||
// this.clearSelection();
|
||
// this.refreshList();
|
||
// } else if (2 == this.tabValue) {
|
||
// // 筛选 - 打开弹窗
|
||
// this.isShowPop = true;
|
||
// }
|
||
},
|
||
|
||
|
||
maskClick(e) {
|
||
console.log('maskClick事件:', e);
|
||
},
|
||
|
||
// 处理搜索
|
||
handleSearch() {
|
||
this.searchKeyword = this.searchText.trim();
|
||
this.pageNum = 1;
|
||
this.orderList = [];
|
||
this.getlist();
|
||
},
|
||
|
||
getBrandList() {
|
||
let data = {
|
||
pageSize: 1000,
|
||
pageNum: 1,
|
||
}
|
||
request({
|
||
url: '/base/carBrand/page',
|
||
method: 'get',
|
||
params: data
|
||
}).then((res) => {
|
||
console.log('list', res);
|
||
if (res.code == 200) {
|
||
this.brandList = res.data.records
|
||
}
|
||
})
|
||
},
|
||
|
||
getStaffList() {
|
||
let data = {
|
||
pageSize: 1000,
|
||
pageNum: 1,
|
||
}
|
||
request({
|
||
url: '/company/staff/list',
|
||
method: 'get',
|
||
params: data
|
||
}).then((res) => {
|
||
console.log('list', res);
|
||
if (res.code == 200) {
|
||
this.staffList = res.data
|
||
}
|
||
})
|
||
},
|
||
|
||
getlist() {
|
||
console.log('queryParams', this.queryParams)
|
||
request({
|
||
url: '/app/rescueInfo/getRescueStatisticsInfoList',
|
||
method: 'get',
|
||
params: this.queryParams
|
||
}).then((res) => {
|
||
console.log('list', res);
|
||
if (res.code == 200) {
|
||
this.getCountNum()
|
||
if (this.pageNum != 1) {
|
||
const currentScrollTop = this.scrollTop;
|
||
this.orderList = this.orderList.concat(res.rows)
|
||
this.$nextTick(() => {
|
||
uni.pageScrollTo({
|
||
scrollTop: currentScrollTop,
|
||
duration: 0
|
||
});
|
||
});
|
||
} else {
|
||
this.orderList = res.rows
|
||
}
|
||
this.totalNum = res.total
|
||
let total = res.total
|
||
this.totalPages = Math.ceil(total / this.pageSize);
|
||
this.hasMore = this.pageNum < this.totalPages;
|
||
}
|
||
}).catch((error) => {
|
||
console.error('获取数据失败', error);
|
||
uni.showToast({
|
||
title: '数据加载失败',
|
||
icon: 'none'
|
||
});
|
||
}).finally(() => {
|
||
this.initialLoading = false;
|
||
this.loadingMore = false;
|
||
});
|
||
},
|
||
|
||
// 刷新列表
|
||
refreshList() {
|
||
this.pageNum = 1;
|
||
this.orderList = [];
|
||
this.hasMore = true;
|
||
this.initialLoading = true;
|
||
this.getlist();
|
||
},
|
||
|
||
// 关闭弹窗
|
||
closePop() {
|
||
this.isShowPop = false;
|
||
document.body.style.overflow = ''
|
||
uni.pageScrollTo({
|
||
scrollTop: 0,
|
||
duration: 0
|
||
});
|
||
},
|
||
|
||
// 提交筛选
|
||
submitPop() {
|
||
this.refreshList();
|
||
this.isShowPop = false;
|
||
document.body.style.overflow = '';
|
||
// 对于uni-app,可能需要使用uni API
|
||
uni.pageScrollTo({
|
||
scrollTop: 0,
|
||
duration: 0
|
||
});
|
||
},
|
||
|
||
// 打开弹窗
|
||
openPop() {
|
||
this.isShowPop = true;
|
||
document.body.style.overflow = 'hidden'
|
||
},
|
||
|
||
// 清除筛选条件
|
||
clearSelection() {
|
||
this.queryParams = {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
timeType: null,
|
||
rescueStatus: null,
|
||
rescueType: null,
|
||
licenseNum: null,
|
||
rangeTime: [],
|
||
startTimeStr: null,
|
||
endTimeStr: null,
|
||
|
||
connectionName: null,
|
||
connectionPhone: null,
|
||
rescuePosition: null,
|
||
secondDispatchId: null,
|
||
rescueCar: null,
|
||
rescueDriver: null,
|
||
driverId: null,
|
||
driverCarNum: null,
|
||
faultType: null,
|
||
phenomenon: null,
|
||
channel: null,
|
||
source: null
|
||
};
|
||
this.searchText = '';
|
||
this.searchKeyword = null;
|
||
this.$forceUpdate();
|
||
},
|
||
|
||
getStatisticsList(data) {
|
||
let url = '';
|
||
if (this.hasRole('ddzx')) {
|
||
url = '/app/rescueInfo/statisticsAll';
|
||
} else if (this.hasRole('second_dispatcher')) {
|
||
url = '/app/rescueInfo/statisticsAllSecond';
|
||
} else {
|
||
this.driverList = [];
|
||
this.vehicleList = [];
|
||
return;
|
||
}
|
||
request({
|
||
url: url,
|
||
method: 'get',
|
||
params: data
|
||
}).then((res) => {
|
||
console.log('list', res);
|
||
if (res.code == 200) {
|
||
const processedData = res.data.map(item => {
|
||
if (item.money !== undefined && item.money !== null) {
|
||
return {
|
||
...item,
|
||
money: Math.trunc(item.money / 100),
|
||
mileage: Math.trunc(item.mileage)
|
||
};
|
||
}
|
||
return item;
|
||
});
|
||
switch (data.queryType) {
|
||
case 'driver':
|
||
this.driverList = processedData;
|
||
break;
|
||
case 'car':
|
||
this.vehicleList = processedData;
|
||
break;
|
||
case 'dispatch':
|
||
this.dispatchList = processedData;
|
||
break;
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 获取所有渠道信息
|
||
// async loadChannelOptions () {
|
||
// const { data } = await request({ url:'/rescue-channel-source/channelList' })
|
||
// this.channelOptions = [
|
||
// { id:'all', nickname:'全部' },
|
||
// ...data.map(v => ({ id:v.id, nickname:v.name }))
|
||
// ]
|
||
|
||
// /* ① 默认高亮第一项 */
|
||
// this.channelTabIdx = 0
|
||
|
||
// /* ② 直接取一次统计,否则初次进入页面看不到数据 */
|
||
// this.fetchChannelStats()
|
||
// },
|
||
|
||
async loadChannelOptions() {
|
||
return new Promise((resolve, reject) => {
|
||
request({
|
||
url: '/rescue-channel-source/channelList',
|
||
method: 'get',
|
||
}).then((res) => {
|
||
this.channelOptions = res.data.map(item => ({
|
||
nickname: item.name, // 显示文本
|
||
value: item.name, // 实际值
|
||
id: item.id, // ID
|
||
label: item.name // 保留原字段
|
||
}));
|
||
resolve();
|
||
}).catch(reject);
|
||
});
|
||
},
|
||
// 获取所有来源信息
|
||
async loadSourceOptions() {
|
||
return new Promise((resolve, reject) => {
|
||
request({
|
||
url: '/rescue-channel-source/sourceList',
|
||
method: 'get',
|
||
}).then((res) => {
|
||
this.sourceOptions = res.data.map(item => ({
|
||
nickname: item.name, // 显示文本
|
||
value: item.name, // 实际值
|
||
id: item.id, // ID
|
||
label: item.name // 保留原字段
|
||
}));
|
||
resolve();
|
||
}).catch(reject);
|
||
});
|
||
},
|
||
|
||
// 获取调度人员信息
|
||
loadDispatcherOptions() {
|
||
return new Promise((resolve, reject) => {
|
||
this.dispatcherColumns = [];
|
||
const tenantId = this.userinfo.tenantId + '';
|
||
|
||
const request1 = request({
|
||
url: `/company/staff/staffListByRoleCode?tenantId=${tenantId}&code=second_dispatcher`,
|
||
method: 'get',
|
||
});
|
||
|
||
const request2 = request({
|
||
url: `/company/staff/staffListByRoleCode?tenantId=${tenantId}&code=ddzx`,
|
||
method: 'get',
|
||
});
|
||
|
||
Promise.all([request1, request2])
|
||
.then(([res1, res2]) => {
|
||
const combinedData = [...(res1.data || []), ...(res2.data || [])];
|
||
const uniqueMap = new Map();
|
||
combinedData.forEach(item => {
|
||
if (item && item.id) {
|
||
uniqueMap.set(item.id, item);
|
||
}
|
||
});
|
||
const uniqueData = Array.from(uniqueMap.values());
|
||
this.dispatcherColumns.push(uniqueData);
|
||
this.dispatcherOptions = this.dispatcherColumns[0].map(item => ({
|
||
nickname: item.name || item.nickname,
|
||
value: item.id,
|
||
id: item.id,
|
||
name: item.id // 存储实际值
|
||
}));
|
||
console.log('this.dispatcherColumns', this.dispatcherColumns)
|
||
console.log('this.dispatcherOptions', this.dispatcherOptions)
|
||
resolve(uniqueData);
|
||
})
|
||
.catch(error => {
|
||
console.error('获取调度人员数据失败:', error);
|
||
reject(error);
|
||
});
|
||
});
|
||
},
|
||
// 获取救援状态 字典
|
||
async loadjyStatusOptions() {
|
||
return new Promise((resolve, reject) => {
|
||
request({
|
||
url: '/rescue/dict/data/type/jy_status',
|
||
method: 'get',
|
||
}).then((res) => {
|
||
this.jyStatusOptions = res.data.map(item => ({
|
||
nickname: item.label,
|
||
value: item.value,
|
||
id: item.id,
|
||
name: item.value // 存储实际值
|
||
}));
|
||
resolve();
|
||
}).catch(reject);
|
||
});
|
||
},
|
||
|
||
// 获取救援类型 字典
|
||
async loadjyTypeOptions() {
|
||
return new Promise((resolve, reject) => {
|
||
request({
|
||
url: '/rescue/dict/data/type/dljy_type',
|
||
method: 'get',
|
||
}).then((res) => {
|
||
this.jyTypeOptions = res.data.map(item => ({
|
||
nickname: item.label, // 显示文本
|
||
value: item.value, // 实际值
|
||
id: item.id, // ID
|
||
label: item.label // 保留原字段
|
||
}));
|
||
resolve();
|
||
}).catch(reject);
|
||
});
|
||
},
|
||
|
||
// 加载故障类型选项
|
||
async loadFaultTypeOptions() {
|
||
return new Promise((resolve, reject) => {
|
||
request({
|
||
url: '/rescue-type-phenomenon/typeList',
|
||
method: 'get',
|
||
}).then((res) => {
|
||
this.faultTypeOptions = res.data.map(item => ({
|
||
nickname: item.name, // 显示文本
|
||
value: item.name, // 实际值
|
||
id: item.id, // ID
|
||
label: item.name // 保留原字段
|
||
}));
|
||
resolve();
|
||
}).catch(reject);
|
||
});
|
||
},
|
||
|
||
// 加载故障现象选项方法
|
||
async loadPhenomenonOptions() {
|
||
return new Promise((resolve, reject) => {
|
||
request({
|
||
url: '/rescue-type-phenomenon/listPhenomenonByPid',
|
||
method: 'get',
|
||
}).then((res) => {
|
||
this.phenomenonOptions = res.data.map(item => ({
|
||
nickname: item.name, // 显示文本
|
||
value: item.name, // 实际值
|
||
id: item.id, // ID
|
||
label: item.name // 保留原字段
|
||
}));
|
||
resolve();
|
||
}).catch(reject);
|
||
});
|
||
},
|
||
|
||
// 加载司机选项方法
|
||
async loadRescueDriverOptions() {
|
||
return new Promise((resolve, reject) => {
|
||
let url = '';
|
||
|
||
if (this.hasRole('ddzx')) {
|
||
url = '/system/DriverInfo/listDriverInfo';
|
||
} else if (this.hasRole('second_dispatcher')) {
|
||
url = '/system/DriverInfo/listDriverInfoSecond';
|
||
} else {
|
||
this.rescueDriverOptions = [];
|
||
resolve();
|
||
return;
|
||
}
|
||
|
||
request({
|
||
url: url,
|
||
method: 'get',
|
||
}).then((res) => {
|
||
this.rescueDriverOptions = res.data.map(item => ({
|
||
nickname: item.nickName,
|
||
value: item.userId,
|
||
id: item.id,
|
||
label: item.nickName
|
||
}));
|
||
resolve();
|
||
}).catch(reject);
|
||
});
|
||
},
|
||
|
||
// 加载救援车辆选项方法
|
||
async loadRescueCarOptions() {
|
||
return new Promise((resolve, reject) => {
|
||
let url = '';
|
||
|
||
if (this.hasRole('ddzx')) {
|
||
url = '/system/DriverInfo/listCarInfo';
|
||
} else if (this.hasRole('second_dispatcher')) {
|
||
url = '/system/DriverInfo/listCarInfoSecond';
|
||
} else {
|
||
this.rescueCarOptions = [];
|
||
resolve();
|
||
return;
|
||
}
|
||
request({
|
||
url: url,
|
||
method: 'get',
|
||
}).then((res) => {
|
||
this.rescueCarOptions = res.data.map(item => ({
|
||
nickname: item.rescueCarNum, // 显示文本
|
||
value: item.rescueCarNum,
|
||
id: item.id,
|
||
label: item.rescueCarNum
|
||
}));
|
||
resolve();
|
||
}).catch(reject);
|
||
});
|
||
},
|
||
|
||
async getOptions() {
|
||
this.userinfo = uni.getStorageSync('userInfo')
|
||
// await this.getDispatcher()
|
||
await this.loadDispatcherOptions() // 新增
|
||
await this.loadjyStatusOptions()
|
||
await this.loadjyTypeOptions()
|
||
await this.loadFaultTypeOptions()
|
||
await this.loadPhenomenonOptions()
|
||
await this.loadRescueDriverOptions()
|
||
await this.loadRescueCarOptions()
|
||
await this.loadChannelOptions()
|
||
},
|
||
|
||
getCountNum() {
|
||
request({
|
||
url: '/app/rescueInfo/getRescueStatisticsInfoNum',
|
||
method: 'get',
|
||
params: this.queryParams
|
||
}).then((res) => {
|
||
console.log('四个', res);
|
||
this.countNum.dqcNum = res.data.dqcNum
|
||
this.countNum.dzfNum = res.data.dzfNum
|
||
this.countNum.jyzNum = res.data.jyzNum
|
||
this.countNum.ywcNum = res.data.ywcNum
|
||
this.countNum.yjdNum = res.data.yjdNum
|
||
this.countNum.zwxNum = res.data.zwxNum
|
||
this.countNum.yingskNum = res.data.yingskNum ? res.data.yingskNum / 100 : 0
|
||
this.countNum.yiskNum = res.data.yiskNum ? res.data.yiskNum / 100 : 0
|
||
this.countNum.dskNum = res.data.dskNum ? res.data.dskNum / 100 : 0
|
||
})
|
||
},
|
||
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/* ========== 财务统计 (最终) ========== */
|
||
|
||
/* 标题条:与上面所有二级标题保持一致 */
|
||
.sec-bar{
|
||
display:flex;align-items:center;
|
||
margin:16rpx 0 6rpx; /* 与上一块距离缩窄 */
|
||
line-height:1;
|
||
.blue-line{width:8rpx;height:32rpx;border-radius:4rpx;background:#054df3;margin-right:16rpx;}
|
||
.sec-title{font-size:30rpx;font-weight:bold;color:#101A3E;margin-right:20rpx;}
|
||
}
|
||
|
||
/* 时间切换(本日/本月…)保持一行、间隔统一 */
|
||
.time-tabs{
|
||
display:flex;column-gap:28rpx;align-items:center;font-size:26rpx;color:#8d90a6;
|
||
.t-item{position:relative;}
|
||
.t-item.active{font-weight:bold;color:#101A3E;}
|
||
.t-item.active::after{
|
||
content:'';position:absolute;left:50%;bottom:-12rpx;transform:translateX(-50%);
|
||
width:22rpx;height:6rpx;border-radius:3rpx;background:linear-gradient(180deg,#054df3 0%,#55a3ff 100%);
|
||
}
|
||
}
|
||
|
||
/* 卡片外观:保持同一浅蓝渐变,卡片间距16rpx */
|
||
.uni-card{
|
||
background:linear-gradient(180deg,rgba(166,188,255,.24) 0%,#ffffff 100%);
|
||
border-radius:16rpx;
|
||
padding:26rpx 24rpx;
|
||
margin-bottom:16rpx;
|
||
}
|
||
|
||
/* 头部:标题在左,PK按钮贴最右 */
|
||
.card-hd{
|
||
display:flex;align-items:center;
|
||
.card-title{font-size:30rpx;font-weight:bold;color:#101A3E;margin-right:auto;}
|
||
.pk-btn{
|
||
margin-left:auto; /* ← 让按钮永远贴右 */
|
||
padding:10rpx 38rpx;
|
||
font-size:24rpx;
|
||
color:#327DFB;
|
||
background:#fff;
|
||
border:2rpx solid #327DFB;
|
||
border-radius:34rpx;
|
||
line-height:1;
|
||
}
|
||
}
|
||
|
||
/* 数据行:与「是否扣车统计」间距一致,整体再左移一些 */
|
||
.row-g{display:flex;flex-direction:column;row-gap:12rpx;}
|
||
|
||
.row{
|
||
display:grid;
|
||
grid-template-columns:max-content 96rpx max-content 96rpx; /* 标签-数值 | 标签-数值 */
|
||
column-gap:16rpx; /* 间隔统一 */
|
||
font-size:26rpx;color:#666;
|
||
.lbl{white-space:nowrap;}
|
||
.val{font-weight:bold;color:#32373d;}
|
||
}
|
||
|
||
/* ------- 财务统计 · 间距微调 ------- */
|
||
|
||
/* 整体行距:比原来略大,看起来更舒展 */
|
||
.row-g{
|
||
display:flex;
|
||
flex-direction:column;
|
||
row-gap:20rpx; /* 原来 12rpx ➜ 20rpx */
|
||
}
|
||
|
||
/* 单行:两列组之间的左右留白做大,和“待取车数量 / 车辆信息”那行保持一致 */
|
||
.row{
|
||
display:grid;
|
||
/* 标签 值 标签 值 */
|
||
grid-template-columns:max-content 120rpx max-content 120rpx;
|
||
column-gap:40rpx; /* 横向间距;原来 16rpx ➜ 40rpx */
|
||
font-size:26rpx;color:#666;
|
||
|
||
.lbl{white-space:nowrap;}
|
||
.val{font-weight:bold;color:#32373d;}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/* ========== 业务管理统计样式 开始 ========= */
|
||
/* ========== 业务管理统计标题 · 最终微调 ========== */
|
||
.bm-header{
|
||
/* ——① 去掉背景、圆角、阴影 —— */
|
||
background:transparent; /* 删掉原来那条 linear-gradient */
|
||
border-radius:0;
|
||
box-shadow:none;
|
||
padding:0 0 10rpx 0; /* 保留一点下内边距即可 */
|
||
margin:32rpx 0 16rpx; /* 与上下模块留距离 */
|
||
display:flex;align-items:center;flex-wrap:wrap;
|
||
}
|
||
|
||
.bm-header .blue-line{ /* 竖线保持不变,可略缩左右空隙 */
|
||
margin-right:12rpx;
|
||
}
|
||
|
||
.bm-header .section-title{
|
||
font-size:30rpx;font-weight:bold;color:#101A3E;
|
||
margin-right:20rpx; /* 这里把多余的 margin-left 删除 */
|
||
}
|
||
|
||
/* ③ 自定义日期选择器与标题栏之间留距离 */
|
||
.bm-header + uni-datetime-picker{
|
||
margin-top:16rpx; /* 上下间隔 */
|
||
}
|
||
/* 业务管理统计 – 时间 Tab 选中态 */
|
||
.bm-header .time-item{
|
||
position:relative;
|
||
font-size:26rpx;
|
||
color:#8D90A6;
|
||
}
|
||
.bm-header .time-item.active{
|
||
font-weight:600;
|
||
color:#101A3E;
|
||
}
|
||
|
||
.bm-header{
|
||
padding:0 20rpx 10rpx;
|
||
display:flex;align-items:center;
|
||
|
||
.time-tabs{ // ← 新增 / 保留,里头只留这一句
|
||
margin-left:40rpx; // 想再右一点就调大,左一点就调小
|
||
}
|
||
}
|
||
.bm-picker{ // ← 刚刚包的那层
|
||
margin-top:16rpx;
|
||
}
|
||
.time-item.active::after{
|
||
width:220rpx; // ← 想宽就调大
|
||
}
|
||
|
||
/* 日期选择器外层容器(example-body 已存在)*/
|
||
.example-body{
|
||
display:flex; /* 让里面元素可用 flex:1 撑满 */
|
||
padding:0 20rpx; /* 如果想去掉左右留白可设为 0 */
|
||
}
|
||
|
||
/* 让 picker 占满整行 */
|
||
.full-width-picker{
|
||
flex:1; /* 关键:横向拉伸 */
|
||
width:100%;
|
||
}
|
||
|
||
/* 深度选择——把内部输入框也拉满(HBuilderX ≤3.8 需 ::v-deep) */
|
||
.full-width-picker::v-deep .uni-date__content,
|
||
.full-width-picker::v-deep .uni-date__input{
|
||
width:100% !important;
|
||
}
|
||
|
||
|
||
|
||
|
||
/* ========== 业务管理统计卡 ========= */
|
||
.manage-card{
|
||
margin-bottom:10rpx;
|
||
padding:24rpx;
|
||
border-radius:12rpx;
|
||
background:linear-gradient(180deg,#e4ecff 0%,#ffffff 100%);
|
||
box-shadow:0 4rpx 12rpx rgba(0,0,0,.06);
|
||
}
|
||
|
||
/* 头部:标题 + PK */
|
||
.m-header{display:flex;justify-content:space-between;align-items:center;}
|
||
.m-title{font-size:28rpx;font-weight:600;}
|
||
|
||
/* PK 按钮沿用之前的 pk-btn 样式,无需重复 */
|
||
|
||
/* 数据区:自动两列网格,条目多少都可 */
|
||
/* 统计卡内部表格 - 调整对齐 */
|
||
/* ===== 故障地点统计 – 列表排版优化 ===== */
|
||
|
||
/* ① 把 flex ➜ grid,一行 2 项 */
|
||
.m-grid{
|
||
display:grid;
|
||
grid-template-columns:repeat(2,1fr); /* 两列等宽 */
|
||
column-gap:20rpx; /* 左右留白 */
|
||
row-gap:12rpx; /* 行距 */
|
||
padding:18rpx 0;
|
||
}
|
||
|
||
/* ② 每项左右各占一边 */
|
||
.m-item{
|
||
display:flex;
|
||
justify-content:space-between; /* 关键:数字贴右 */
|
||
align-items:center;
|
||
}
|
||
|
||
/* ③ 左侧地点名 */
|
||
.m-key{
|
||
flex:1; /* 自动占剩余 */
|
||
font-size:26rpx;
|
||
color:#646b79;
|
||
overflow:hidden; /* 超长省略 */
|
||
text-overflow:ellipsis;
|
||
white-space:nowrap;
|
||
}
|
||
|
||
/* ④ 右侧数量 */
|
||
.m-val{
|
||
flex:none;
|
||
font-size:32rpx;
|
||
font-weight:600;
|
||
color:#101A3E;
|
||
margin-left:12rpx; /* 与文字拉开一点 */
|
||
}
|
||
|
||
/* ========== 业务管理统计样式 结束 ========= */
|
||
|
||
|
||
/* ========== 业务渠道统计样式 开始 ========== */
|
||
/* -------- 业务渠道统计标题 -------- */
|
||
.bc-header{
|
||
display:flex;align-items:center;justify-content:space-between;
|
||
margin:32rpx 0 16rpx 0;
|
||
|
||
.blue-line{width:8rpx;height:32rpx;border-radius:4rpx;background:#054df3;}
|
||
.section-title{font-size:30rpx;font-weight:600;margin-left:20rpx;white-space:nowrap;}
|
||
|
||
.time-tabs{margin-left:auto;display:flex;align-items:center;}
|
||
.time-item{font-size:26rpx;color:#666;margin-left:28rpx;position:relative;}
|
||
.time-item.active{color:#101a3e;font-weight:600;}
|
||
.time-item.active::after{
|
||
content:'';position:absolute;left:50%;bottom:-14rpx;transform:translateX(-50%);
|
||
border-left:10rpx solid transparent;border-right:10rpx solid transparent;border-top:10rpx solid #054df3;
|
||
}
|
||
}
|
||
/* 底部小箭头 */
|
||
.time-item.active::after{
|
||
content:"";
|
||
position:absolute;left:50%;transform:translateX(-50%);
|
||
bottom:-14rpx;width:0;height:0;
|
||
border-left:10rpx solid transparent;
|
||
border-right:10rpx solid transparent;
|
||
border-top:10rpx solid #054df3;
|
||
}
|
||
/* ========== 渠道卡(加深渐变) ========== */
|
||
.channel-card{
|
||
margin-bottom:24rpx;padding:24rpx;border-radius:12rpx;
|
||
/* 深一点的浅蓝到白渐变 */
|
||
background:linear-gradient(180deg,#d9e6ff 0%,#ffffff 100%);
|
||
box-shadow:0 4rpx 12rpx rgba(0,0,0,.06);
|
||
}
|
||
/* 待取车无描边 */
|
||
.wait-car{border:none;padding:0;} /* 如果之前还保留,可留着覆盖 */
|
||
|
||
/* 顶部:渠道名 + PK */
|
||
.c-header{display:flex;justify-content:space-between;align-items:center;}
|
||
.c-name{font-size:28rpx;font-weight:600;}
|
||
.pk-btn{
|
||
font-size:22rpx;color:#327dfb;border:1rpx solid #327dfb;
|
||
border-radius:20rpx;padding:4rpx 20rpx;
|
||
}
|
||
|
||
/* 行容器:四格或三格 */
|
||
.c-row{display:grid;column-gap:0;row-gap:24rpx;margin-top:24rpx;}
|
||
.c-row.four{grid-template-columns:repeat(4,1fr);} /* 第一行 4 列 */
|
||
.c-row.three{grid-template-columns:repeat(3,1fr);} /* 第二行 3 列 */
|
||
|
||
.c-cell{text-align:center;}
|
||
.c-num{font-size:30rpx;font-weight:600;color:#101a3e;}
|
||
.c-lab{display:block;margin-top:6rpx;font-size:22rpx;color:#666;}
|
||
/* ========== 业务渠道统计样式 结束 ========== */
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
.dil {
|
||
// background-color: #F7F8FC;
|
||
background-color: #f3f5fc;
|
||
box-sizing: border-box;
|
||
padding: 0 30rpx;
|
||
}
|
||
.four-box-header {
|
||
display: flex;
|
||
justify-content: start;
|
||
align-items: center;
|
||
padding: 20rpx 0 10rpx 0;
|
||
}
|
||
.blue-line {
|
||
width: 8rpx;
|
||
height: 32rpx;
|
||
background: #054DF3;
|
||
border-radius: 4rpx;
|
||
margin-right: 20rpx;
|
||
}
|
||
.four-box-header-title {
|
||
font-weight: bold;
|
||
}
|
||
.tab-choose-class {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 4rpx 20rpx 16rpx 20rpx;
|
||
border-top: 1rpx solid #F5F5F5;
|
||
|
||
.tab-content {
|
||
font-size: 28rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
|
||
.tab-name-class {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.icon-tab {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
|
||
image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.tab-icon {
|
||
width: 66rpx;
|
||
height: 8rpx;
|
||
margin-top: 8rpx;
|
||
}
|
||
}
|
||
.four-box {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr 1fr;
|
||
gap: 24rpx;
|
||
// margin-top: 15px;
|
||
width: 100%;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
.boxf {
|
||
height: 130rpx;
|
||
overflow: hidden;
|
||
box-sizing: border-box;
|
||
border-radius: 6px;
|
||
padding: 12px;
|
||
// background-image: url('~@/static/images/homeOrderCard/dzf.png');
|
||
// background: rgba(218, 218, 218, 0.2);
|
||
background-color: #fdfeff;
|
||
background-size: cover;
|
||
background-position: center;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
// 边框
|
||
border: 1px solid #badeff;
|
||
// 阴影
|
||
box-shadow: inset 0 2px 8px rgba(186, 222, 255, 0.3);
|
||
}
|
||
.zi1 {
|
||
font-size: 24rpx;
|
||
color: #333;
|
||
display: flex;
|
||
align-items: center;
|
||
column-gap: 10rpx;
|
||
|
||
.zi1-icon {
|
||
width: 38rpx;
|
||
height: 38rpx;
|
||
}
|
||
}
|
||
.zi2 {
|
||
width: 100%;
|
||
font-size: 40rpx;
|
||
font-weight: bold;
|
||
color: #000;
|
||
}
|
||
.two-box-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 20rpx;
|
||
width: 100%;
|
||
}
|
||
.two-box {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 18rpx;
|
||
width: 100%;
|
||
}
|
||
.boxf2 {
|
||
height: 120rpx;
|
||
overflow: hidden;
|
||
box-sizing: border-box;
|
||
border-radius: 6px;
|
||
padding: 2px 12px 2px 12px;
|
||
background: rgba(218, 218, 218, 0.2);
|
||
background-size: cover;
|
||
background-position: center;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
}
|
||
.zi1_1 {
|
||
font-size: 24rpx;
|
||
color: #333;
|
||
display: flex;
|
||
align-items: center;
|
||
column-gap: 10rpx;
|
||
|
||
.zi1_1-icon {
|
||
width: 38rpx;
|
||
height: 38rpx;
|
||
}
|
||
}
|
||
.zi2_2 {
|
||
width: 100%;
|
||
font-size: 30rpx;
|
||
font-weight: bold;
|
||
color: #000;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/* 三列自动换行专用 */
|
||
.tab-choose-multi {
|
||
display: flex;
|
||
flex-wrap: wrap; // 允许换行
|
||
}
|
||
/* 每个选项占 1/3 宽度 */
|
||
.tab-choose-multi .tab-content {
|
||
flex: 0 0 33.333%;
|
||
box-sizing: border-box;
|
||
text-align: center;
|
||
margin-bottom: 12rpx; // 行间距,可按需调整
|
||
}
|
||
/* 三列对齐 + 文字居中专用 */
|
||
.tab-choose-equal {
|
||
/* 用网格替代 flex,列宽完全一致 */
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr); // 3 列等宽
|
||
row-gap: 5rpx; // 行间距,可按需调整
|
||
column-gap: 0; // 列间距,如需分隔可自行设置
|
||
}
|
||
/* 每个格子内部再居中一下文字 */
|
||
.tab-choose-equal .tab-content {
|
||
display: flex; // 保留原来的竖直布局
|
||
flex-direction: column;
|
||
align-items: center; // 水平居中
|
||
justify-content: center; // 垂直居中(可选)
|
||
text-align: center;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/* 原有样式保持不变,只添加弹窗相关样式 */
|
||
.popup-content {
|
||
padding: 20rpx 20rpx 20rpx 20rpx;
|
||
overflow-y: scroll;
|
||
background: white;
|
||
border-radius: 20rpx;
|
||
}
|
||
|
||
.popup-header {
|
||
font-size: 32rpx;
|
||
color: #101A3E;
|
||
margin-bottom: 40rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.popup-body {
|
||
font-size: 28rpx;
|
||
color: #101A3E;
|
||
}
|
||
|
||
.filter-section {
|
||
margin-top: 30rpx;
|
||
}
|
||
|
||
.filter-section text {
|
||
display: block;
|
||
margin-bottom: 10rpx;
|
||
}
|
||
|
||
.options {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
}
|
||
|
||
.popup-footer {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-top: 60rpx;
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.popup-footer button {
|
||
padding: 10rpx 20rpx;
|
||
margin: 0 10rpx;
|
||
border-radius: 5px;
|
||
background-color: #327DFB;
|
||
color: #fff;
|
||
border: none;
|
||
}
|
||
|
||
/* 搜索和时间筛选区域 */
|
||
/* .search-filter-area {
|
||
width: 100%;
|
||
background: #fff;
|
||
margin: 0 20rpx;
|
||
border-radius: 16rpx;
|
||
padding: 6rpx 0 10rpx 0;
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
} */
|
||
|
||
.tab-icon {
|
||
width: 66rpx;
|
||
height: 8rpx;
|
||
margin-top: 8rpx;
|
||
}
|
||
|
||
.statistics-container {
|
||
background: #f6f8fc;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.top—1 {
|
||
width: 100%;
|
||
height: 100rpx;
|
||
background: #3a8dff;
|
||
}
|
||
|
||
/* 顶部导航 */
|
||
.nav-bar {
|
||
position:relative; // 关键①:让子元素能绝对定位
|
||
display: flex;
|
||
align-items: center;
|
||
background: linear-gradient(180deg, #3a8dff, #579dff);
|
||
color: #fff;
|
||
padding: 10px 16px;
|
||
height: 100rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
/* ① 给箭头固定宽度 */
|
||
.nav-bar uni-icons {
|
||
flex:0 0 60rpx; // 60rpx 左右自己调,够摆下箭头就行
|
||
}
|
||
/* 左侧返回箭头占 60rpx */
|
||
.back-icon { width:60rpx; flex-shrink:0; }
|
||
|
||
.title-tabs {
|
||
position:absolute; /* 关键 */
|
||
left:50%;
|
||
top:0;
|
||
transform:translateX(-50%); /* 真正水平居中 */
|
||
height:100%;
|
||
display:flex;
|
||
align-items:center;
|
||
}
|
||
|
||
.tab-item {
|
||
padding:0 24rpx;
|
||
font-size:15px;
|
||
line-height:100rpx;
|
||
white-space:nowrap; /* 不允许自动换行 */
|
||
flex:none; /* 别再撑满父元素 */
|
||
}
|
||
|
||
.tab-item.active {
|
||
font-weight: bold;
|
||
border-bottom: 3px solid #fff;
|
||
opacity: 1;
|
||
}
|
||
|
||
.filter-btn {
|
||
width:60rpx; flex-shrink:0;
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* 统计卡片 */
|
||
/* .stat-cards {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
margin: 14rpx 0;
|
||
} */
|
||
|
||
.stat-card {
|
||
background: #fff;
|
||
border-radius: 12rpx;
|
||
padding: 4rpx;
|
||
flex: 1;
|
||
margin: 0 16rpx;
|
||
text-align: center;
|
||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.stat-num {
|
||
font-size: 20px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.stat-label {
|
||
display: block;
|
||
margin-top: 6px;
|
||
color: #666;
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* 搜索和时间筛选区域 */
|
||
.search-filter-area {
|
||
background: #fff;
|
||
margin: 0 20rpx;
|
||
border-radius: 16rpx;
|
||
/* padding: 6rpx 0 10rpx 0; */
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
}
|
||
|
||
.top-icon {
|
||
box-sizing: border-box;
|
||
width: 100%;
|
||
padding: 5px 0;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.h-text {
|
||
width: 124rpx;
|
||
height: 56rpx;
|
||
background: rgba(255, 255, 255, 0.2);
|
||
border-radius: 28rpx;
|
||
font-size: 28rpx;
|
||
color: #FFFFFF;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: #327DFB;
|
||
}
|
||
|
||
.s-input {
|
||
width: 78%;
|
||
height: 56rpx;
|
||
background: #f5f5f5;
|
||
border-radius: 50px;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0px 10px;
|
||
|
||
input {
|
||
margin-left: 5px;
|
||
flex: 1;
|
||
width: 0;
|
||
font-size: 14px;
|
||
color: #999999;
|
||
}
|
||
}
|
||
|
||
/* 时间筛选选项卡样式 */
|
||
.tab-choose-class {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 20rpx 0 16rpx 0;
|
||
background-color: #fff;
|
||
/* border-bottom: 1rpx solid #F5F5F5; */
|
||
width: 100%;
|
||
/* 新增:让容器占满宽度 */
|
||
}
|
||
|
||
.tab-content {
|
||
font-size: 28rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
flex: 1;
|
||
text-align: center;
|
||
}
|
||
|
||
.tab-name-class {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.icon-tab {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
}
|
||
|
||
.icon-tab image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.example-body {
|
||
display:flex;
|
||
background-color: #fff;
|
||
padding: 0 20rpx;
|
||
}
|
||
|
||
/* 信息选项卡样式 */
|
||
.four-box-header_2 {
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 20rpx 0;
|
||
}
|
||
|
||
.four-box-header_2_right {
|
||
width: 60%;
|
||
display: flex;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
}
|
||
|
||
.four-box-header_2_right .tab-item {
|
||
font-size: 28rpx;
|
||
font-weight: normal;
|
||
color: #a1a6aa;
|
||
position: relative;
|
||
padding: 0rpx 20rpx;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.four-box-header_2_right .tab-item.active {
|
||
font-weight: bold;
|
||
color: #000000;
|
||
}
|
||
|
||
.four-box-header_2_right .tab-item.active::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: -10rpx;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 33.33%;
|
||
height: 6rpx;
|
||
background: linear-gradient(90deg, #054DF3 0%, #55A3FF 100%);
|
||
border-radius: 3rpx 3rpx 0 0;
|
||
}
|
||
|
||
/* 订单列表区域 */
|
||
.dil {
|
||
background-color: #F7F8FC;
|
||
box-sizing: border-box;
|
||
padding: 8px 12px 15px 12px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
row-gap: 10px;
|
||
}
|
||
|
||
.loading-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
z-index: 9999;
|
||
}
|
||
|
||
.loading-spinner {
|
||
position: relative;
|
||
width: 60px;
|
||
height: 60px;
|
||
border: 4px solid #f3f3f3;
|
||
border-top: 4px solid #327DFB;
|
||
border-radius: 50%;
|
||
animation: spin 1s linear infinite;
|
||
margin-bottom: 15px;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.loading-text {
|
||
font-size: 16px;
|
||
color: #666;
|
||
}
|
||
|
||
@keyframes spin {
|
||
0% {
|
||
transform: rotate(0deg);
|
||
}
|
||
|
||
100% {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
.ques {
|
||
margin: 0px auto;
|
||
margin-top: 40px;
|
||
width: 80%;
|
||
}
|
||
|
||
.ques image {
|
||
width: 100%;
|
||
}
|
||
|
||
.loading-more {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
padding: 20rpx;
|
||
color: #999;
|
||
font-size: 26rpx;
|
||
}
|
||
|
||
.loading-more .mini {
|
||
width: 30px;
|
||
height: 30px;
|
||
border-width: 2px;
|
||
margin-right: 10rpx;
|
||
}
|
||
|
||
.no-more-data {
|
||
text-align: center;
|
||
padding: 20rpx;
|
||
color: #999;
|
||
font-size: 26rpx;
|
||
}
|
||
|
||
/* 分类统计样式 */
|
||
.sub-tabs {
|
||
display: flex;
|
||
background: #fff;
|
||
padding: 10px 0;
|
||
justify-content: space-around;
|
||
border-bottom: 1px solid #eee;
|
||
}
|
||
|
||
.sub-tab-item {
|
||
font-size: 15px;
|
||
color: #666;
|
||
padding: 4px 10px;
|
||
}
|
||
|
||
.sub-tab-item.active {
|
||
font-weight: bold;
|
||
color: #3a8dff;
|
||
border-bottom: 2px solid #3a8dff;
|
||
}
|
||
|
||
.list-container {
|
||
margin: 10px;
|
||
}
|
||
|
||
.table-header,
|
||
.table-row {
|
||
display: flex;
|
||
align-items: center;
|
||
background: #fff;
|
||
border-radius: 8px;
|
||
padding: 10px;
|
||
margin-bottom: 6px;
|
||
}
|
||
|
||
.table-header {
|
||
font-weight: bold;
|
||
background: #f0f3f8;
|
||
}
|
||
|
||
.col-rank {
|
||
width: 40px;
|
||
text-align: center;
|
||
}
|
||
|
||
.col-driver {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.avatar {
|
||
width: 28px;
|
||
height: 28px;
|
||
border-radius: 50%;
|
||
margin-right: 6px;
|
||
}
|
||
|
||
.col-num,
|
||
.col-distance,
|
||
.col-money {
|
||
width: 80px;
|
||
text-align: center;
|
||
}
|
||
|
||
.scroll_view_style {
|
||
flex: 1;
|
||
}
|
||
|
||
/* 新增选择字段样式 */
|
||
.select-field {
|
||
width: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 20rpx;
|
||
background: #fff;
|
||
border-radius: 8rpx;
|
||
border: 1rpx solid #e9ecef;
|
||
min-height: 80rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.select-text {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
flex: 1;
|
||
}
|
||
|
||
.select-field:active {
|
||
background: #e9ecef;
|
||
}
|
||
|
||
.stat-cards-container {
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
margin: 14rpx 0;
|
||
}
|
||
|
||
.stat-cards {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
flex: 1;
|
||
}
|
||
|
||
.expand-btn {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 60rpx;
|
||
height: 80rpx;
|
||
margin-right: 20rpx;
|
||
background: #fff;
|
||
border-radius: 12rpx;
|
||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.expand-text {
|
||
font-size: 20rpx;
|
||
color: #327DFB;
|
||
margin-top: 4rpx;
|
||
}
|
||
|
||
.expanded-cards {
|
||
margin-top: 10rpx;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
</style> |