3069 lines
74 KiB
Vue
3069 lines
74 KiB
Vue
<template>
|
||
<view :class="'province-theme-' + currentProvinceCode">
|
||
<!-- 加载骨架屏 -->
|
||
<view class="loading-skeleton" v-if="isLoading">
|
||
<view class="skeleton-header"></view>
|
||
<view class="skeleton-cards">
|
||
<view class="skeleton-card" v-for="i in 3" :key="i"></view>
|
||
</view>
|
||
<view class="skeleton-list">
|
||
<view class="skeleton-item" v-for="i in 5" :key="i"></view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="page-body" v-if="showPage">
|
||
<AnhHead :today="today" :headMsg="headMsg" :lastDay="lastDay" :groupType="theRequest && theRequest.GroupType"
|
||
:provinceCode="theRequest && theRequest.ProvinceCode" @bindDateChange="bindDateChange" :isup="isup"
|
||
:nowDay="nowDay" :selectDate="theRequest && theRequest.time" @toggle="toggleCard" :currentMoney="currentMoney">
|
||
</AnhHead>
|
||
<!--营收占比的上面组件 -->
|
||
<view class="main-content">
|
||
<!--安徽省 昨日营收占比 -->
|
||
<view v-if="theRequest && theRequest.GroupType != 1010">
|
||
<view class="section-header">
|
||
<view class="section-title">
|
||
<view class="section-icon">
|
||
<text class="icon-emoji">📊</text>
|
||
</view>
|
||
<text class="section-text">营收占比</text>
|
||
</view>
|
||
|
||
</view>
|
||
<view class="analysis-container">
|
||
|
||
<view class="modern-tabs">
|
||
<view class="tab-item" @click="selectTab('nowTab', 1)" v-if="theRequest.ProvinceCode == 340000"
|
||
:class="{ 'active': nowTab == 1 }">
|
||
<view class="tab-icon">🏢</view>
|
||
<view class="tab-label">经营模式</view>
|
||
</view>
|
||
<view class="tab-item" @click="selectTab('nowTab', 2)" :class="{ 'active': nowTab == 2 }">
|
||
<view class="tab-icon">🏪</view>
|
||
<view class="tab-label">经营业态</view>
|
||
</view>
|
||
<view class="tab-item" @click="selectTab('nowTab', 3)"
|
||
v-if="areaProgress.length && areaProgress.length > 1" :class="{ 'active': nowTab == 3 }">
|
||
<view class="tab-icon">🗺</view>
|
||
<view class="tab-label">区域营收</view>
|
||
</view>
|
||
<view class="tab-item" @click="selectTab('nowTab', 4)"
|
||
v-if="theRequest.ProvinceCode == 340000 && theRequest.GroupType == 1000"
|
||
:class="{ 'active': nowTab == 4 }">
|
||
<view class="tab-icon">🚗</view>
|
||
<view class="tab-label">车流分析</view>
|
||
</view>
|
||
</view>
|
||
<view class="content-wrapper">
|
||
<view class="chart-section" v-show="nowTab == 1"
|
||
v-if="modelProgress.length > 0 && theRequest.ProvinceCode == 340000">
|
||
<view class="chart-container">
|
||
<canvas canvas-id="modelCont" id="modelCont" class="modern-chart"
|
||
@touchstart="touchPie($event, 'modelCont')"></canvas>
|
||
</view>
|
||
<view class="data-cards">
|
||
<view class="data-card" v-for="(item, o) in modelProgress" :key="o">
|
||
<view class="card-header">
|
||
<view class="category-name">{{ item.name }}</view>
|
||
<view class="percentage">{{ item.bili }}%</view>
|
||
</view>
|
||
<view class="amount">¥{{ item.data }}</view>
|
||
<view class="progress-bar">
|
||
<view class="progress-fill" :style="{ 'width': item.bili + '%' }"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="chart-section" v-show="nowTab == 2" v-if="regionProgress.length > 0">
|
||
<view class="chart-container">
|
||
<canvas canvas-id="businessCont" id="businessCont" class="modern-chart"
|
||
@touchstart="touchPie($event, 'businessCont')"></canvas>
|
||
</view>
|
||
<view class="data-cards">
|
||
<view class="data-card" v-for="(item, o) in regionProgress" :key="o">
|
||
<view class="card-header">
|
||
<view class="category-name">{{ item.name }}</view>
|
||
<view class="percentage">{{ item.bili }}%</view>
|
||
</view>
|
||
<view class="amount">¥{{ item.data }}</view>
|
||
<view class="progress-bar">
|
||
<view class="progress-fill" :style="{ 'width': item.bili + '%' }"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="chart-section" v-show="nowTab == 3" v-if="areaProgress.length > 0">
|
||
<view class="chart-container">
|
||
<canvas canvas-id="areaCont" id="areaCont" class="modern-chart"
|
||
@touchstart="touchPie($event, 'areaCont')"></canvas>
|
||
</view>
|
||
<view class="data-cards">
|
||
<view class="data-card" v-for="(item, o) in areaProgress" :key="o">
|
||
<view class="card-header">
|
||
<view class="category-name">{{ item.name }}</view>
|
||
<view class="percentage">{{ item.bili }}%</view>
|
||
</view>
|
||
<view class="amount">¥{{ item.data }}</view>
|
||
<view class="progress-bar">
|
||
<view class="progress-fill" :style="{ 'width': item.bili + '%' }"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="traffic-analysis" v-show="nowTab == 4" v-if="bayonetProgress && bayonetProgress.length > 0">
|
||
<view class="traffic-header">
|
||
<view class="traffic-title">
|
||
<view class="traffic-icon">🚗</view>
|
||
<text>车流分析概览</text>
|
||
</view>
|
||
<view class="traffic-summary">
|
||
{{ bayonetProgress.length }}个区域
|
||
</view>
|
||
</view>
|
||
|
||
<scroll-view class="traffic-scroll-container" scroll-y="true">
|
||
<view class="traffic-regions">
|
||
<view class="region-card" v-for="(item, o) in bayonetProgress" :key="o">
|
||
<!-- 区域标题 -->
|
||
<view class="region-header" @click="toggleRegionCollapse(item)">
|
||
<view class="region-badge">
|
||
<view class="region-icon">🗺️</view>
|
||
<view class="region-title">{{ item.name }}</view>
|
||
</view>
|
||
<view class="region-actions">
|
||
<view class="region-count">{{ item.list.length }}个服务区</view>
|
||
<view class="region-arrow" :class="{ 'collapsed': item.collapsed }">▼</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 服务区列表 -->
|
||
<view class="service-areas" v-if="!item.collapsed">
|
||
<view class="service-area-item" v-for="(child, idx) in item.list" :key="idx">
|
||
<view class="service-header" @click="toggleServiceArea(item, idx)">
|
||
<view class="service-info">
|
||
<view class="service-name">{{ child.name }}</view>
|
||
<view class="service-ratio">占比 {{ child.bili }}%</view>
|
||
</view>
|
||
<view class="service-actions">
|
||
<view class="flow-stats">
|
||
<view class="flow-item">
|
||
<text class="flow-label">入区</text>
|
||
<text class="flow-value">{{ child.data }}</text>
|
||
</view>
|
||
<view class="flow-divider">|</view>
|
||
<view class="flow-item">
|
||
<text class="flow-label">断面</text>
|
||
<text class="flow-value">{{ child.flow }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="expand-arrow" :class="{ 'expanded': child.expanded }">▼</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 方向车流数据 -->
|
||
<view class="direction-list" v-if="child.expanded && child.list && child.list.length > 0">
|
||
<view class="direction-item" v-for="(direction, didx) in child.list" :key="didx">
|
||
<view class="direction-header">
|
||
<view class="direction-info">
|
||
<text class="direction-name">{{ direction.name }}区</text>
|
||
<text class="direction-percent">{{ direction.bili }}%</text>
|
||
</view>
|
||
<view class="vehicle-stats">
|
||
<view class="vehicle-type-group">
|
||
<view class="vehicle-type-item">
|
||
<text class="vehicle-type-label">大型车</text>
|
||
<text class="vehicle-count-value">{{ direction.LargeVehicle_Count }}</text>
|
||
</view>
|
||
<view class="vehicle-type-item">
|
||
<text class="vehicle-type-label">中型车</text>
|
||
<text class="vehicle-count-value">{{ direction.MediumVehicle_Count }}</text>
|
||
</view>
|
||
<view class="vehicle-type-item">
|
||
<text class="vehicle-type-label">小型车</text>
|
||
<text class="vehicle-count-value">{{ direction.MinVehicle_Count }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 日结上传区域 -->
|
||
<view class="upload-section" v-if="regionList.length > 0">
|
||
<view class="upload-header">
|
||
<view class="upload-title">
|
||
<view class="upload-icon">📊</view>
|
||
<view class="upload-text">日结上传状态</view>
|
||
</view>
|
||
<view class="upload-summary">
|
||
<view class="summary-label">上传情况</view>
|
||
<view class="summary-value">{{ headMsg.uploadState }}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<template v-if="theRequest && theRequest.GroupType == 1020 && regionList.length">
|
||
<view class="service-list">
|
||
<view v-for="(item, i) in regionList[0].child" :key="i" class="service-card" @click="toDetail(item)">
|
||
<view class="service-header">
|
||
<view class="service-info">
|
||
<view class="service-name">🏢 {{ item.serverpart_Name }}</view>
|
||
<view class="service-revenue">¥{{ $util.fmoney(item.cashpay, 2) }}</view>
|
||
</view>
|
||
<view class="service-status">
|
||
<view class="upload-rate" :class="{ 'warning': item.uploadcount != item.totalcount }">
|
||
{{ item.totalcount > item.uploadcount ?
|
||
$util.fmoney((item.uploadcount / item.totalcount) * 100, 2) : 100 }}%
|
||
</view>
|
||
<view class="upload-fraction" :class="{ 'incomplete': item.uploadcount != item.totalcount }">
|
||
{{ item.uploadcount }}/{{ item.totalcount }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="service-indicator">
|
||
<view class="status-dot"
|
||
:class="{ 'complete': item.uploadcount == item.totalcount, 'incomplete': item.uploadcount != item.totalcount }">
|
||
</view>
|
||
<view class="arrow-icon">›</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
<template v-else-if="theRequest && theRequest.GroupType == 1000">
|
||
<view class="region-list" v-show="regionShow1">
|
||
<block v-for="(item, i) in regionList" :key="i">
|
||
<view class="region-card" @click="toggleRegion(item)">
|
||
<view class="region-main">
|
||
<view class="region-info">
|
||
<view class="region-name">{{ item.name }}</view>
|
||
<view class="region-revenue">¥{{ $util.fmoney(item.cashpay, 2) }}</view>
|
||
</view>
|
||
<view class="region-metrics">
|
||
<view class="metric-item">
|
||
<view class="metric-label">上传率</view>
|
||
<view class="metric-value rate" :class="{ 'incomplete': item.uploadcount != item.totalcount }">
|
||
{{ (item.totalcount > item.uploadcount) ?
|
||
$util.fmoney((item.uploadcount / item.totalcount) * 100, 2) : '100.00'
|
||
}}%
|
||
</view>
|
||
</view>
|
||
<view class="metric-item">
|
||
<view class="metric-label">状态</view>
|
||
<view class="metric-value fraction"
|
||
:class="{ 'incomplete': item.uploadcount != item.totalcount }">
|
||
{{ item.uploadcount }}/{{ item.totalcount }}
|
||
</view>
|
||
</view>
|
||
<view class="expand-indicator" :class="{ 'expanded': item.show }">
|
||
<view class="expand-icon">▼</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="service-sublist" v-show="item.show">
|
||
<view class="subservice-card" v-for="(child, index) in item.child"
|
||
:class="{ 'visited': child.visited }" :key="index" @click.stop="toDetail(child)">
|
||
<view class="subservice-info">
|
||
<view class="subservice-name">{{ child.serverpart_Name }}</view>
|
||
<view class="subservice-revenue">¥{{ $util.fmoney(child.cashpay, 2) }}
|
||
</view>
|
||
</view>
|
||
<view class="subservice-status" :class="{ 'incomplete': child.uploadcount != child.totalcount }">
|
||
{{ child.uploadcount }}/{{ child.totalcount }}
|
||
</view>
|
||
<view class="subservice-arrow">›</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
</view>
|
||
</template>
|
||
<template v-else>
|
||
<shopCell v-for="(item, i) in regionList" :key="i" :item='item' @toggleShow="toggleShow" :i='i' />
|
||
</template>
|
||
</view>
|
||
<template v-if="theRequest && theRequest.ProvinceCode == '620000' || theRequest.ProvinceCode == '530000'">
|
||
<view class="uni-inline-item modle-title">
|
||
<image src="/static/images/revenue/product-ranking.png" mode="aspectFit"></image>
|
||
<text class="strong-text">商品销售排行</text>
|
||
</view>
|
||
<RankContent :wechatPushSalesList="wechatPushSalesList" v-if="!isLoading"></RankContent>
|
||
</template>
|
||
</view>
|
||
<view v-if="!showPage && !isLoading">
|
||
<noFound :nodata="!showPage && !isLoading" :text="'您暂无' + lastDay + '营收数据'" />
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
mapState
|
||
} from 'vuex';
|
||
import uCharts from '@/components/u-charts.js';
|
||
import shopCell from './components/listUnit.vue'
|
||
import AnhHead from './components/anhHead.vue'
|
||
import RankContent from './components/RankContent.vue'
|
||
import anhuiYestodayRevenueData from './components/anhuiYestodayRevenueData.js'
|
||
var rincanvas = {};
|
||
import request from '@/util/index.js'
|
||
export default {
|
||
data() {
|
||
const lastDay = this.$util.cutDate(new Date(), 'YYYY-MM-DD', -1)
|
||
|
||
const nowDay = this.$util.cutDate(new Date(), 'MM月DD日')
|
||
|
||
return {
|
||
showPage: false,
|
||
opacity: 0, // 背景颜色透明度
|
||
customBarH: this.CustomBar,
|
||
statusBarH: this.StatusBar,
|
||
isLoading: true,
|
||
theRequest: null,
|
||
sevenDate: null,
|
||
lastDay: lastDay, // 该页面的最近有效日期
|
||
nowDay: nowDay,
|
||
headMsg: null,
|
||
today: null, // 今日数据
|
||
regionList: null,
|
||
nowTab: 1,
|
||
regionShow1: true,
|
||
regionProgress: null,
|
||
tradeType: null,
|
||
areaProgress: null,
|
||
bayonetProgress: null,
|
||
modelProgress: null,
|
||
isup: true,
|
||
wechatPushSalesList: null, // 甘肃单品排行数据
|
||
currentMoney: '',
|
||
currentProvinceCode: '' // 当前省份代码
|
||
}
|
||
},
|
||
computed: {
|
||
...mapState({
|
||
'PushAuthority': (state) => state.userData.PushAuthority,
|
||
'ProvinceCode': (state) => state.userData.ProvinceCode,
|
||
}),
|
||
hasSeverpartIndexAuthority() {
|
||
let theRequest = this.theRequest
|
||
if (this.theRequest && theRequest.ProvinceCode && this.PushAuthority) {
|
||
return this.PushAuthority.some(n =>
|
||
n.ProvinceCode == theRequest.ProvinceCode && n.ShopAnalysisType == 1
|
||
)
|
||
}
|
||
return false
|
||
},
|
||
// 省份主题配色
|
||
provinceTheme() {
|
||
const themes = {
|
||
'330200': { // 宁波
|
||
primary: '#1890FF',
|
||
secondary: '#69C0FF',
|
||
background: '#E6F7FF',
|
||
accent: '#40A9FF'
|
||
},
|
||
'340000': { // 安徽
|
||
primary: '#748ED6',
|
||
secondary: '#91A7E3',
|
||
background: '#F0F4FF',
|
||
accent: '#A3B8E8'
|
||
},
|
||
'500000': { // 重庆
|
||
primary: '#FA541C',
|
||
secondary: '#FF7A45',
|
||
background: '#FFF2E8',
|
||
accent: '#FF8C73'
|
||
},
|
||
'510000': { // 四川
|
||
primary: '#FA8C16',
|
||
secondary: '#FFA940',
|
||
background: '#FFF7E6',
|
||
accent: '#FFAB65'
|
||
},
|
||
'520000': { // 贵州
|
||
primary: '#52C41A',
|
||
secondary: '#73D13D',
|
||
background: '#F6FFED',
|
||
accent: '#7CB342'
|
||
},
|
||
'530000': { // 云南(保持原色)
|
||
primary: '#27B25F',
|
||
secondary: '#4CCC7F',
|
||
background: '#F6FFED',
|
||
accent: '#5CDB87'
|
||
},
|
||
'630000': { // 青海
|
||
primary: '#13C2C2',
|
||
secondary: '#36CFC9',
|
||
background: '#E6FFFB',
|
||
accent: '#5CDBD3'
|
||
},
|
||
'734100': { // 海南
|
||
primary: '#E91E63',
|
||
secondary: '#F06292',
|
||
background: '#FCE4EC',
|
||
accent: '#F48FB1'
|
||
}
|
||
}
|
||
return themes[this.currentProvinceCode] || themes['530000'] // 如果找不到对应省份,使用云南配色
|
||
}
|
||
},
|
||
components: {
|
||
shopCell,
|
||
AnhHead,
|
||
RankContent
|
||
},
|
||
methods: {
|
||
// 解析二维码参数 - uniapp兼容版本
|
||
parseQRCodeParams: function (qParam) {
|
||
try {
|
||
// 解码URL
|
||
var decodedUrl = decodeURIComponent(qParam)
|
||
console.log('解码后的URL:', decodedUrl)
|
||
|
||
// 提取查询参数部分
|
||
var urlParts = decodedUrl.split('?')
|
||
if (urlParts.length < 2) {
|
||
console.log('二维码URL没有参数,使用默认值')
|
||
return this.getDefaultParams()
|
||
}
|
||
|
||
var queryString = urlParts[1]
|
||
var params = {}
|
||
|
||
// 解析查询参数
|
||
var pairs = queryString.split('&')
|
||
for (var i = 0; i < pairs.length; i++) {
|
||
var pair = pairs[i]
|
||
var equalIndex = pair.indexOf('=')
|
||
if (equalIndex > -1) {
|
||
var key = pair.substring(0, equalIndex)
|
||
var value = pair.substring(equalIndex + 1)
|
||
if (key && value !== '') {
|
||
try {
|
||
params[decodeURIComponent(key)] = decodeURIComponent(value)
|
||
} catch (e) {
|
||
// 解码失败时使用原值
|
||
params[key] = value
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
console.log('解析的参数对象:', params)
|
||
|
||
// 确保必需参数存在
|
||
var finalParams = {
|
||
ProvinceCode: params.ProvinceCode || '530000', // 默认云南
|
||
GroupType: params.GroupType || '1000',
|
||
time: params.time || this.lastDay,
|
||
ServerpartIds: params.ServerpartIds || ''
|
||
}
|
||
|
||
// 处理时间格式
|
||
if (finalParams.time) {
|
||
var timeStr = finalParams.time
|
||
console.log('原始时间字符串:', timeStr)
|
||
|
||
// 处理URL编码的+号(空格被编码为+)
|
||
timeStr = timeStr.replace(/\+/g, ' ')
|
||
console.log('处理+号后:', timeStr)
|
||
|
||
// 分离日期和时间部分
|
||
var datePart = ''
|
||
var timePart = ''
|
||
|
||
if (timeStr.indexOf(' ') > -1) {
|
||
var parts = timeStr.split(' ')
|
||
datePart = parts[0]
|
||
timePart = parts[1] || ''
|
||
} else {
|
||
datePart = timeStr
|
||
}
|
||
|
||
// 处理日期部分:2025/9/1 -> 2025/09/01
|
||
if (datePart.indexOf('/') > -1) {
|
||
var dateSegments = datePart.split('/')
|
||
if (dateSegments.length === 3) {
|
||
var year = dateSegments[0]
|
||
var month = dateSegments[1].length === 1 ? '0' + dateSegments[1] : dateSegments[1]
|
||
var day = dateSegments[2].length === 1 ? '0' + dateSegments[2] : dateSegments[2]
|
||
datePart = year + '/' + month + '/' + day
|
||
}
|
||
}
|
||
|
||
// 处理时间部分:确保格式正确
|
||
if (timePart && timePart.indexOf(':') > -1) {
|
||
var timeSegments = timePart.split(':')
|
||
if (timeSegments.length >= 2) {
|
||
var hour = timeSegments[0].length === 1 ? '0' + timeSegments[0] : timeSegments[0]
|
||
var minute = timeSegments[1].length === 1 ? '0' + timeSegments[1] : timeSegments[1]
|
||
var second = '00'
|
||
if (timeSegments[2]) {
|
||
second = timeSegments[2].length === 1 ? '0' + timeSegments[2] : timeSegments[2]
|
||
}
|
||
timePart = hour + ':' + minute + ':' + second
|
||
}
|
||
}
|
||
|
||
// 组合最终时间字符串
|
||
if (timePart) {
|
||
finalParams.time = datePart + ' ' + timePart
|
||
} else {
|
||
finalParams.time = datePart
|
||
}
|
||
|
||
console.log('最终时间格式:', finalParams.time)
|
||
|
||
// 验证时间格式
|
||
if (finalParams.time.length < 8) {
|
||
console.log('时间格式不正确,使用默认时间')
|
||
finalParams.time = this.lastDay
|
||
}
|
||
}
|
||
|
||
console.log('最终参数:', finalParams)
|
||
return finalParams
|
||
|
||
} catch (error) {
|
||
console.log('解析二维码参数失败:', error)
|
||
return this.getDefaultParams()
|
||
}
|
||
},
|
||
|
||
// 获取默认参数 - uniapp兼容版本
|
||
getDefaultParams: function () {
|
||
return {
|
||
ProvinceCode: '530000', // 默认云南
|
||
GroupType: '1000',
|
||
time: this.lastDay,
|
||
ServerpartIds: ''
|
||
}
|
||
},
|
||
|
||
// 初始化省份代码
|
||
initProvinceCode() {
|
||
let provinceCode = ''
|
||
|
||
// 优先使用theRequest中的省份代码
|
||
if (this.theRequest && this.theRequest.ProvinceCode) {
|
||
provinceCode = this.theRequest.ProvinceCode
|
||
} else if (this.ProvinceCode) {
|
||
// 备用方案使用store中的省份代码
|
||
provinceCode = this.ProvinceCode
|
||
}
|
||
|
||
// 只有在确实找到省份代码时才设置和更新
|
||
if (provinceCode) {
|
||
this.currentProvinceCode = provinceCode
|
||
console.log('设置省份主题:', provinceCode)
|
||
// 强制更新以应用新主题
|
||
this.$forceUpdate()
|
||
}
|
||
},
|
||
// 获取主题颜色(小程序兼容版本)
|
||
getThemeColors() {
|
||
return this.provinceTheme
|
||
},
|
||
toggleCard(isup) {
|
||
this.isup = !isup
|
||
// 移除不必要的$forceUpdate,由Vue自动检测变化
|
||
},
|
||
bindDateChange(e) { // 切换日期 加载选中日期的营收数据
|
||
// let nowDate = this.theRequest.time
|
||
let selectT = new Date(e.detail.value)
|
||
if (selectT <= new Date(this.lastDay)) {
|
||
this.theRequest.time = e.detail.value
|
||
this.theRequest.month = this.$util.cutDate(e.detail.value, 'YYYYMM')
|
||
this.sevenDate = [this.$util.cutDate(selectT, 'MM.DD', -13),
|
||
this.$util.cutDate(selectT, 'MM.DD', -7)]
|
||
uni.showLoading({
|
||
title: '正在加载...',
|
||
mask: false // 减少遮罩,提升用户体验
|
||
})
|
||
// 异步并行加载数据
|
||
Promise.all([
|
||
this.initData(),
|
||
this.todayAmount()
|
||
]).catch(err => {
|
||
console.error('数据刷新失败:', err)
|
||
uni.hideLoading()
|
||
})
|
||
// 移除不必要的$forceUpdate
|
||
}
|
||
|
||
},
|
||
toDetail(item, provinceId) { // 如果当前页面至存在一个初始化的省份编码 则不需要传入参数provinceId
|
||
let date = this.theRequest.time
|
||
let pcode = provinceId || this.theRequest.ProvinceCode
|
||
|
||
let severpartIndexPath = '/pages/everdayRenven/AnhuiServerpart?ServerpartIds=' + item.serverpart_Id +
|
||
'&time=' + date + '&ProvinceCode=' + pcode
|
||
let serverpartUploadPath = '/pages/everdayRenven/detail?id=' + item.serverpart_Id + '&time=' + date +
|
||
'&provinceId=' + pcode
|
||
|
||
// 是否有权限进入服务区营收分析页面
|
||
let canToSeverpartIndex = !provinceId ? this.hasSeverpartIndexAuthority : this.PushAuthority.some(n => {
|
||
return n.ProvinceCode == provinceId && n.ShopAnalysisType == 1
|
||
})
|
||
this.$util.toNextRoute('navigateTo', severpartIndexPath)
|
||
|
||
// 使用Vue.set确保响应式更新
|
||
this.$set(item, 'visited', true)
|
||
},
|
||
selectTab(name, index) {
|
||
this[name] = index
|
||
},
|
||
toggleRegion(item) {
|
||
// 使用Vue.set确保响应式更新
|
||
this.$set(item, 'show', !item.show)
|
||
},
|
||
// 切换区域展开/收起状态
|
||
toggleRegionCollapse(item) {
|
||
this.$set(item, 'collapsed', !item.collapsed)
|
||
},
|
||
// 切换服务区展开/收起状态
|
||
toggleServiceArea(region, serviceIndex) {
|
||
const service = region.list[serviceIndex]
|
||
this.$set(service, 'expanded', !service.expanded)
|
||
},
|
||
touchPie(e, id) {
|
||
rincanvas[id].showToolTip(e, {
|
||
format: function (item) {
|
||
return item.name + ':' + item.data
|
||
}
|
||
});
|
||
},
|
||
todayAmount() {
|
||
let _this = this
|
||
let theRequest = this.theRequest
|
||
this.$request.$get('getCurRevenue', {
|
||
pushProvinceCode: theRequest.ProvinceCode,
|
||
serverPartId: theRequest.GroupType == 1000 ? '' : theRequest.ServerpartIds
|
||
}).then(res => {
|
||
if (res.ResultCode != 100) return
|
||
|
||
let avrticket = (res.Data.TOTALTICKET != 0 && res.Data.TOTALPRICE != 0) ? res.Data.TOTALPRICE /
|
||
res.Data
|
||
.TOTALTICKET : 0
|
||
_this.today = {
|
||
timeMoney: this.$util.fmoney(res.Data.TOTALPRICE, 2),
|
||
totalTicketCount: res.Data.TOTALTICKET,
|
||
avrticketCount: this.$util.fmoney(avrticket, 2),
|
||
}
|
||
// 移除不必要的$forceUpdate
|
||
})
|
||
|
||
},
|
||
|
||
showPie(obj) {
|
||
let data = {
|
||
series: []
|
||
}
|
||
const ctx = uni.createCanvasContext(obj.id, this);
|
||
data.series = data.series.concat(obj.data)
|
||
rincanvas[obj.id] = new uCharts({
|
||
// 小程序图表工具
|
||
// $this: this,
|
||
// canvasId: obj.id,
|
||
context: ctx,
|
||
color: obj.colors,
|
||
type: 'ring',
|
||
fontSize: 12,
|
||
padding: [15, 15, 25, 15],
|
||
legend: {
|
||
show: false,
|
||
padding: 5,
|
||
lineHeight: 11,
|
||
margin: 0,
|
||
},
|
||
background: '#FFFFFF',
|
||
pixelRatio: 1,
|
||
series: data.series,
|
||
animation: false,
|
||
width: uni.upx2px(686),
|
||
height: uni.upx2px(510),
|
||
dataLabel: true,
|
||
extra: {
|
||
ring: {
|
||
ringWidth: 40,
|
||
labelWidth: 16,
|
||
border: true,
|
||
borderWidth: 1,
|
||
|
||
borderColor: '#fff'
|
||
}
|
||
},
|
||
});
|
||
},
|
||
getDetail(obj) {
|
||
console.log('obj', obj)
|
||
let _this = this
|
||
this.$request.$webGet('CommercialApi/Revenue/GetServerpartEndAccountList', {
|
||
Serverpart_ID: obj.ServerpartIds,
|
||
pushProvinceCode: obj.ProvinceCode,
|
||
Statistics_Date: obj.time,
|
||
|
||
}).then(res => {
|
||
if (res.Result_Code != 100) return
|
||
res.Result_Data.ShopEndaccountList.map(n => {
|
||
n.show = false
|
||
n.detail = this.getListDetail(n)
|
||
})
|
||
|
||
_this.regionList = res.Result_Data.ShopEndaccountList
|
||
console.log('_this.regionList', _this.regionList)
|
||
})
|
||
},
|
||
getListDetail(data) {
|
||
let arr = []
|
||
let keyJson = {
|
||
SHOWMORE_SIGN: {
|
||
1: '【长款】',
|
||
2: '【异常长款】'
|
||
}, // 长款
|
||
SHOWLESS_SIGN: {
|
||
1: '【短款】',
|
||
2: '【异常短款】'
|
||
}, // 短款
|
||
SHOWABNORMAL_SIGN: {
|
||
1: '【异常校验】'
|
||
}, // 异常日结
|
||
SHOWSCAN_SIGN: {
|
||
1: '【扫】'
|
||
}, // 扫码上传
|
||
SHOWSSUPPLY_SIGN: {
|
||
1: '【补】'
|
||
}, // 账期补录
|
||
SHOWCHECK_SIGN: {
|
||
1: '【稽核检查】'
|
||
}, // 稽核检查
|
||
INTERFACE_SIGN: {
|
||
1: '【接口传输】'
|
||
}, // 接口传输
|
||
}
|
||
var keyCode = ['SHOWABNORMAL_SIGN', 'SHOWCHECK_SIGN', 'SHOWMORE_SIGN', 'SHOWLESS_SIGN', 'SHOWSCAN_SIGN',
|
||
'SHOWSSUPPLY_SIGN', 'INTERFACE_SIGN'
|
||
]
|
||
keyCode.map(n => {
|
||
if (keyJson[n][data[n]]) arr.push(keyJson[n][data[n]])
|
||
})
|
||
return arr
|
||
},
|
||
toggleShow(i) {
|
||
let item = this.regionList[i]
|
||
// 使用Vue.set确保响应式更新
|
||
this.$set(item, 'show', !item.show)
|
||
},
|
||
defaultMsg() {
|
||
let option = null
|
||
let _this = this
|
||
if (this.PushAuthority && this.PushAuthority.length > 1) {
|
||
option = this.PushAuthority.find(n => n.ProvinceCode === _this.ProvinceCode)
|
||
} else {
|
||
option = this.PushAuthority[0]
|
||
}
|
||
return {
|
||
...option
|
||
}
|
||
},
|
||
async initData() { // 初始化营收数据
|
||
let _this = this
|
||
console.log('this.theRequest1', this.theRequest)
|
||
|
||
// 检查theRequest是否存在,如果不存在则使用默认值
|
||
if (!this.theRequest) {
|
||
console.error('theRequest未初始化')
|
||
this.isLoading = false
|
||
this.showPage = false
|
||
uni.hideLoading()
|
||
return
|
||
}
|
||
|
||
this.theRequest.GroupType = 1000
|
||
this.theRequest.ServerpartIds = ''
|
||
|
||
try {
|
||
// 异步加载数据,添加错误处理
|
||
const result = await anhuiYestodayRevenueData.getData(this.theRequest)
|
||
|
||
if (!result) {
|
||
console.error('数据获取失败')
|
||
this.isLoading = false
|
||
this.showPage = false
|
||
uni.hideLoading()
|
||
return
|
||
}
|
||
|
||
const [reginList, totalData, busniessTypePie, busniessTradePie, busniessAreaPie, bayonetPie] = result
|
||
|
||
if (this.theRequest.GroupType !== 1010) {
|
||
console.log('reginList', reginList)
|
||
this.regionList = reginList // 营收上传列表 reginListModel[]
|
||
}
|
||
// 组合及格式化 头部卡片总营收数据。
|
||
totalData.tickave = totalData.ticketCount > 0 ? this.$util.fmoney(
|
||
totalData.cashPay / totalData.ticketCount, 2) : 0
|
||
totalData.countave = totalData.totalCount > 0 ? this.$util.fmoney(
|
||
totalData.cashPay / totalData.totalCount, 2) : 0
|
||
|
||
totalData.totalMoneyShow = this.$util.fmoney(totalData.cashPay) // 营收总数据格式化
|
||
totalData.dayOfShow = this.$util.cutDate(this.theRequest.time, 'MM月DD日') // 当前日期
|
||
totalData.budgetamoutShow = totalData.budgetAmount ?
|
||
_this.$util.fmoney(totalData.budgetAmount) : 0.00 // 预算总营收
|
||
|
||
busniessTypePie.forEach((n, i) => {
|
||
if (n.name === '自营') {
|
||
// 预算和实际差额
|
||
totalData.diffBudgetTotal = Math.abs(totalData.budgetAmount - n.data)
|
||
// 预算和实际增长额比例
|
||
totalData.diffBili = totalData.budgetAmount > 0 ?
|
||
this.$util.fmoney((totalData.diffBudgetTotal /
|
||
totalData.budgetAmount) * 100, 2) : '100'
|
||
}
|
||
});
|
||
this.headMsg = totalData
|
||
// 饼图分析及数据条形分析
|
||
const [progressList, pieList] = this.getProgressData(busniessTypePie, totalData.cashPay)
|
||
this.modelProgress = progressList
|
||
// 延迟渲染图表,优化首屏加载
|
||
this.$nextTick(() => {
|
||
setTimeout(() => {
|
||
// 经营类型分析
|
||
var colors1 = ['#FFAC37', '#6B75B8'];
|
||
if (pieList.length > 0) {
|
||
this.showPie({
|
||
id: 'modelCont',
|
||
data: pieList,
|
||
colors: colors1,
|
||
});
|
||
}
|
||
|
||
// 饼图分析及数据条形分析
|
||
const [tprogressList, tpieList] = this.getProgressData(busniessTradePie, totalData.cashPay)
|
||
this.regionProgress = tprogressList
|
||
|
||
// 经营类型分析
|
||
var colors2 = ['#5E67B4', '#4E5699', '#75B7AD', '#AFB7E6'];
|
||
if (tpieList.length > 0) {
|
||
this.showPie({
|
||
id: 'businessCont',
|
||
data: tpieList,
|
||
colors: colors2,
|
||
});
|
||
}
|
||
|
||
// 饼图分析及数据条形分析
|
||
const [aprogressList, apieList] = this.getProgressData(busniessAreaPie, totalData.cashPay)
|
||
this.areaProgress = aprogressList
|
||
|
||
// 区域营收分析
|
||
var colors3 = ['#FFAC37', '#d8ece9', '#f7f5f6', '#b2b7e3', '#F4B27A', '#F3B1C9', '#e0e3f7', '#FFE886', '#f7f5f6'];
|
||
if (apieList.length > 0) {
|
||
this.showPie({
|
||
id: 'areaCont',
|
||
data: apieList,
|
||
colors: colors3,
|
||
});
|
||
}
|
||
}, 100);
|
||
});
|
||
|
||
// 安徽省本级显示的内容
|
||
if (this.theRequest.GroupType == 1000 && this.theRequest.ProvinceCode == 340000) {
|
||
// 显示片区车流量数据分析
|
||
const [bayonetList] = this.getBayonetData(bayonetPie)
|
||
this.bayonetProgress = bayonetList
|
||
}
|
||
|
||
// 数据加载完成后显示页面并隐藏loading
|
||
// 即使没有数据也要显示页面,避免白屏
|
||
this.showPage = true
|
||
this.isLoading = false
|
||
uni.hideLoading()
|
||
} catch (error) {
|
||
console.error('initData执行错误:', error)
|
||
this.isLoading = false
|
||
this.showPage = false
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '数据加载失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
},
|
||
getProgressData(data, total) {
|
||
var _data1 = [];
|
||
var _data2 = [];
|
||
let _this = this
|
||
data.forEach((n, i) => {
|
||
|
||
_data1.push({
|
||
...n,
|
||
textColor: '#999',
|
||
formatter: function (arg) {
|
||
|
||
if (typeof arg === 'number') {
|
||
return [n.name, (arg * 100).toFixed(2) + '%']
|
||
} else {
|
||
return [arg.name, (arg._proportion_ * 100).toFixed(2) + '%']
|
||
}
|
||
|
||
}
|
||
});
|
||
|
||
_data2.push({
|
||
name: n.name,
|
||
num: n.data,
|
||
data: _this.$util.fmoney(n.data, 2), //+Number(data2[n[0]])
|
||
bili: _this.$util.fmoney((n.data / total) * 100, 2)
|
||
});
|
||
|
||
});
|
||
_data1.sort(function (a, b) {
|
||
return b.data - a.data
|
||
})
|
||
_data2.sort(function (a, b) {
|
||
return b.num - a.num
|
||
})
|
||
return [_data2, _data1];
|
||
},
|
||
getBayonetData(data) {
|
||
var _data1 = [];
|
||
let _this = this
|
||
|
||
data.forEach((n, i) => {
|
||
var childData = [];
|
||
n.spList.forEach((m, i) => {
|
||
// 获取服务区各个方位的入区信息
|
||
var _list = [];
|
||
m.regionList.forEach((o, i) => {
|
||
_list.push({
|
||
name: o.name,
|
||
data: o.Vehicle_Count,
|
||
flow: o.SectionFlow_Count,
|
||
bili: o.SectionFlow_Count == 0 ? 100 : _this.$util.fmoney(
|
||
(o.Vehicle_Count / o.SectionFlow_Count) * 100, 2),
|
||
MinVehicle_Count: o.MinVehicle_Count,
|
||
MediumVehicle_Count: o.MediumVehicle_Count,
|
||
LargeVehicle_Count: o.LargeVehicle_Count
|
||
});
|
||
});
|
||
_list.sort(function (a, b) {
|
||
return b.bili - a.bili
|
||
})
|
||
|
||
childData.push({
|
||
name: m.name,
|
||
data: m.Vehicle_Count, //+Number(data2[n[0]])
|
||
flow: m.SectionFlow_Count,
|
||
bili: m.SectionFlow_Count == 0 ? 0 : _this.$util.fmoney(
|
||
(m.Vehicle_Count / m.SectionFlow_Count) * 100, 2),
|
||
list: _list
|
||
});
|
||
});
|
||
childData.sort(function (a, b) {
|
||
return b.bili - a.bili
|
||
})
|
||
|
||
_data1.push({
|
||
name: n.name,
|
||
index: n.index,
|
||
list: childData
|
||
});
|
||
});
|
||
_data1.sort(function (a, b) {
|
||
return a.index - b.index
|
||
})
|
||
|
||
return [_data1];
|
||
},
|
||
async getRankContent() { // 甘肃需要单品排行显示
|
||
const {
|
||
ProvinceCode,
|
||
time
|
||
} = this.theRequest
|
||
|
||
const data = await this.$request.$webGet('CommercialApi/Revenue/GetWechatPushSalesList', {
|
||
pushProvinceCode: ProvinceCode,
|
||
Statistics_Date: time
|
||
})
|
||
|
||
if (data.Result_Code === 100 && data.Result_Data.TotalCount > 0) {
|
||
this.wechatPushSalesList = {}
|
||
data.Result_Data.List.forEach(n => {
|
||
this.wechatPushSalesList[n.Data_Type] = n.GoodsList
|
||
})
|
||
|
||
} else {
|
||
this.wechatPushSalesList = {}
|
||
}
|
||
// 移除不必要的$forceUpdate
|
||
},
|
||
// 实时营收
|
||
handleRealRevenue() {
|
||
const {
|
||
ProvinceCode,
|
||
} = this.theRequest
|
||
const date = new Date()
|
||
let y = date.getFullYear()
|
||
let m = date.getMonth() + 1
|
||
let d = date.getDate()
|
||
if (m < 10) {
|
||
m = '0' + m
|
||
}
|
||
if (d < 10) {
|
||
d = '0' + d
|
||
}
|
||
let req = {
|
||
pushProvinceCode: ProvinceCode,
|
||
StatisticsDate: `${y}-${m}-${d}`
|
||
}
|
||
request.$webGet('CommercialApi/Revenue/GetCurRevenue', req).then(res => {
|
||
console.log('res222222', res)
|
||
this.currentMoney = this.$util.fmoney(res.Result_Data.CurRevenueAmount, 2)
|
||
})
|
||
},
|
||
},
|
||
|
||
onUnload() {
|
||
this.$util.addUserBehavior()
|
||
},
|
||
onPageScroll(options) {
|
||
this.opacity = (options.scrollTop - 30) / 68
|
||
},
|
||
onLoad(option) {
|
||
console.log('AnhuiIndex onLoad 接收参数:', option)
|
||
|
||
// 处理扫码进入的情况
|
||
if (option.q) {
|
||
console.log('扫码进入,解析二维码参数')
|
||
option = this.parseQRCodeParams(option.q)
|
||
console.log('解析后的参数:', option)
|
||
}
|
||
|
||
// 显示更友好的加载提示
|
||
uni.showLoading({
|
||
title: '正在加载...',
|
||
mask: false // 允许用户操作,避免阻塞感
|
||
})
|
||
if (option.ProvinceCode) { // 从推送进入或扫码进入
|
||
console.log('进入页面,参数:', JSON.stringify(option))
|
||
this.theRequest = option
|
||
|
||
// 确保时间格式正确
|
||
if (option.time) {
|
||
console.log('处理前的时间:', option.time)
|
||
// 如果是完整的日期时间格式,提取日期部分用于API调用
|
||
var dateForApi = option.time
|
||
if (option.time.indexOf(' ') > -1) {
|
||
dateForApi = option.time.split(' ')[0]
|
||
}
|
||
// 转换为API需要的格式 YYYY-MM-DD
|
||
option.time = this.$util.cutDate(dateForApi, 'YYYY-MM-DD')
|
||
option.month = this.$util.cutDate(option.time, 'YYYYMM')
|
||
console.log('API用时间格式:', option.time, '月份:', option.month)
|
||
} else {
|
||
option.time = this.lastDay
|
||
option.month = this.$util.cutDate(this.lastDay, 'YYYYMM')
|
||
}
|
||
|
||
console.log('处理后的theRequest:', JSON.stringify(this.theRequest))
|
||
|
||
// 初始化省份主题
|
||
this.initProvinceCode()
|
||
// 优化加载顺序:先显示基础界面,再异步加载数据
|
||
Promise.all([
|
||
this.initData(),
|
||
this.handleRealRevenue()
|
||
]).catch(err => {
|
||
console.error('数据加载失败:', err)
|
||
this.isLoading = false
|
||
this.showPage = false
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '加载失败,请重试',
|
||
icon: 'none'
|
||
})
|
||
})
|
||
} else { // 默认
|
||
|
||
if (this.PushAuthority.length > 0) {
|
||
console.log('11111')
|
||
this.theRequest = this.defaultMsg() || {}
|
||
let storeTime = uni.getStorageSync('lastDay')
|
||
if (storeTime) {
|
||
this.theRequest.time = storeTime
|
||
this.theRequest.month = this.$util.cutDate(storeTime, 'YYYYMM')
|
||
} else {
|
||
this.theRequest.time = this.lastDay
|
||
this.theRequest.month = this.$util.cutDate(this.lastDay, 'YYYYMM')
|
||
}
|
||
|
||
// 初始化省份主题
|
||
this.initProvinceCode()
|
||
// 优化加载顺序:先显示基础界面,再异步加载数据
|
||
Promise.all([
|
||
this.initData(),
|
||
this.handleRealRevenue()
|
||
]).catch(err => {
|
||
console.error('数据加载失败:', err)
|
||
this.isLoading = false
|
||
this.showPage = false
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '加载失败,请重试',
|
||
icon: 'none'
|
||
})
|
||
})
|
||
} else {
|
||
uni.hideLoading()
|
||
this.theRequest = null
|
||
this.isLoading = false
|
||
this.showPage = false
|
||
this.opacity = 1
|
||
// 即使没有权限,也设置一个默认省份以避免样式异常
|
||
this.currentProvinceCode = '530000'
|
||
}
|
||
}
|
||
this.nowTab = this.theRequest && this.theRequest.ProvinceCode == 340000 ? 1 : 2
|
||
this.todayAmount()
|
||
if (this.theRequest && this.theRequest.GroupType == 1010) {
|
||
this.getDetail(this.theRequest)
|
||
}
|
||
// 若省份为甘肃,则加载甘肃单品排行
|
||
if (this.theRequest && (this.theRequest.ProvinceCode == "620000" || this.theRequest.ProvinceCode == "530000")) {
|
||
this.getRankContent()
|
||
}
|
||
},
|
||
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
// 省份主题定义 - 创建mixin以便复用
|
||
@mixin theme-colors($primary, $secondary) {
|
||
|
||
// 主要操作按钮和强调元素 - 使用主题色
|
||
.section-badge {
|
||
background: $primary;
|
||
}
|
||
|
||
.tab-item.active {
|
||
background: $primary;
|
||
}
|
||
|
||
.operation-tab-box .operation-tab-unit.active {
|
||
background: linear-gradient(135deg, $primary, $secondary);
|
||
}
|
||
|
||
// 装饰性元素 - 使用主题色
|
||
.data-card::before {
|
||
background: $primary;
|
||
}
|
||
|
||
.service-card::before {
|
||
background: $primary;
|
||
}
|
||
|
||
.region-main::before {
|
||
background: $primary;
|
||
}
|
||
|
||
.progress-fill {
|
||
background: $primary;
|
||
}
|
||
|
||
.operation-c-list .progress .bgO {
|
||
background: linear-gradient(90deg, $primary, $secondary);
|
||
}
|
||
|
||
.region-cell-area li:nth-child(2n+1):before {
|
||
background: linear-gradient(135deg, $primary, $secondary);
|
||
}
|
||
|
||
.status-dot.complete {
|
||
background: $primary;
|
||
}
|
||
|
||
// 关键数据和金额 - 使用主题色突出显示
|
||
.amount {
|
||
color: $primary;
|
||
}
|
||
|
||
.service-revenue {
|
||
color: $primary;
|
||
}
|
||
|
||
.region-revenue {
|
||
color: $primary;
|
||
}
|
||
|
||
.subservice-revenue {
|
||
color: $primary;
|
||
}
|
||
|
||
.flow-value {
|
||
color: $primary;
|
||
}
|
||
|
||
// 百分比和比率 - 使用主题色
|
||
.percentage {
|
||
color: $primary;
|
||
}
|
||
|
||
.service-ratio {
|
||
color: $primary;
|
||
}
|
||
|
||
.direction-percent {
|
||
color: $primary;
|
||
}
|
||
|
||
.metric-value.rate {
|
||
color: $primary;
|
||
}
|
||
|
||
// 状态和上传相关 - 使用主题色
|
||
.upload-count {
|
||
color: $primary;
|
||
}
|
||
|
||
.upload-rate {
|
||
color: $primary;
|
||
}
|
||
|
||
.summary-value {
|
||
color: $primary;
|
||
}
|
||
|
||
// 特殊状态 - 使用主题色
|
||
.subservice-card.visited .subservice-name {
|
||
color: $primary;
|
||
}
|
||
|
||
.uni-icon-arrowright.active {
|
||
color: $primary;
|
||
}
|
||
|
||
// 注释掉的部分,改用默认灰色/黑色,不跟随主题变化
|
||
// .flow-ratio { color: $primary; }
|
||
// .stat-value { color: $primary; }
|
||
// .direction-ratio { color: $primary; }
|
||
}
|
||
|
||
// 宁波 330200
|
||
.province-theme-330200 {
|
||
@include theme-colors(#1890FF, #69C0FF);
|
||
}
|
||
|
||
// 安徽 340000
|
||
.province-theme-340000 {
|
||
@include theme-colors(#748ED6, #91A7E3);
|
||
}
|
||
|
||
// 重庆 500000
|
||
.province-theme-500000 {
|
||
@include theme-colors(#FA541C, #FF7A45);
|
||
}
|
||
|
||
// 四川 510000
|
||
.province-theme-510000 {
|
||
@include theme-colors(#FA8C16, #FFA940);
|
||
}
|
||
|
||
// 贵州 520000
|
||
.province-theme-520000 {
|
||
@include theme-colors(#52C41A, #73D13D);
|
||
}
|
||
|
||
// 云南 530000
|
||
.province-theme-530000 {
|
||
@include theme-colors(#27B25F, #4CCC7F);
|
||
}
|
||
|
||
// 青海 630000
|
||
.province-theme-630000 {
|
||
@include theme-colors(#13C2C2, #36CFC9);
|
||
}
|
||
|
||
// 海南 734100
|
||
.province-theme-734100 {
|
||
@include theme-colors(#E91E63, #F06292);
|
||
}
|
||
|
||
.page-body {
|
||
background-color: #f8f9fa;
|
||
position: relative;
|
||
box-sizing: border-box;
|
||
min-height: 100vh;
|
||
padding-bottom: env(safe-area-inset-bottom);
|
||
}
|
||
|
||
.uni-flex-column {
|
||
flex-direction: column;
|
||
}
|
||
|
||
.justify-between {
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.justify-around {
|
||
justify-content: space-around;
|
||
}
|
||
|
||
.uni-icon-arrowright {
|
||
font-size: 32rpx;
|
||
color: #5A5A5A;
|
||
}
|
||
|
||
.uni-icon-arrowright.active {
|
||
transform: rotate(90deg);
|
||
}
|
||
|
||
.ct01 {
|
||
color: #383838;
|
||
}
|
||
|
||
.strong-text {
|
||
font-weight: 700;
|
||
}
|
||
|
||
.ct-red {
|
||
color: #ff4757 !important;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.new-content {
|
||
background: url('https://eshangtech.com/ShopICO/ahyd-BID/revenue/banner.png') no-repeat bottom left;
|
||
height: 383rpx;
|
||
background-size: 100%;
|
||
color: #fff;
|
||
box-sizing: border-box;
|
||
padding-top: 20rpx;
|
||
}
|
||
|
||
.new-content .text-title {
|
||
flex: 1;
|
||
text-align: center;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.uni-icon-arrowleft {
|
||
font-size: 38rpx;
|
||
padding: 8rpx 16rpx;
|
||
}
|
||
|
||
.page-title {
|
||
display: flex;
|
||
align-items: center;
|
||
padding-right: 70rpx;
|
||
width: 100%;
|
||
|
||
color: #fff;
|
||
background-color: #3b64a3;
|
||
}
|
||
|
||
.page-title .uni-icon-arrowleft,
|
||
.page-title .uni-icon-arrowleft:before {
|
||
color: #fff;
|
||
}
|
||
|
||
.new-content .header-card {
|
||
background-size: contain;
|
||
background-repeat: no-repeat;
|
||
background-position: center right;
|
||
padding: 0 30rpx;
|
||
color: #BED4F4;
|
||
padding-top: 8rpx;
|
||
position: relative;
|
||
}
|
||
|
||
.head-log {
|
||
position: absolute;
|
||
right: 12rpx;
|
||
top: 0rpx;
|
||
width: 376rpx;
|
||
height: 198rpx;
|
||
}
|
||
|
||
.new-content .top-number {
|
||
padding-top: 28rpx;
|
||
font-size: 76rpx;
|
||
padding-bottom: 16rpx;
|
||
color: #fff;
|
||
padding-left: 4rpx;
|
||
font-family: 'Bahnschrift Regular';
|
||
letter-spacing: 2rpx;
|
||
line-height: 1.1;
|
||
transition: all 1s;
|
||
}
|
||
|
||
.new-content .header-today-info {
|
||
align-items: baseline;
|
||
}
|
||
|
||
.new-content .header-today-info text {
|
||
font-family: 'Bahnschrift Regular';
|
||
font-size: 30rpx;
|
||
}
|
||
|
||
.ml10 {
|
||
margin-left: 20rpx;
|
||
}
|
||
|
||
.new-content .header-today-info text.fs12,
|
||
text.fs12 {
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.ml-135 {
|
||
margin-left: 135rpx;
|
||
}
|
||
|
||
.top-number view {
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.heade-text {
|
||
text-align: right;
|
||
line-height: 1;
|
||
letter-spacing: 0;
|
||
color: #BED4F4;
|
||
font-family: 'Bahnschrift Regular';
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
/* 营收汇总 数据概览卡片 */
|
||
.revenue-card-cont {
|
||
padding: 6rpx 0 32rpx 0;
|
||
border-radius: 12rpx;
|
||
margin: 0 32rpx;
|
||
box-shadow: 0rpx 0rpx 6rpx 0px rgba(224, 224, 224, 0.54);
|
||
}
|
||
|
||
.head-cost-text {
|
||
color: #BED4F4;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.top-revenue-card {
|
||
padding: 16rpx 30rpx 6rpx 30rpx;
|
||
font-family: 'Bahnschrift Regular';
|
||
color: #D7B89A;
|
||
align-items: flex-end;
|
||
|
||
}
|
||
|
||
.top-revenue-card .top-number {
|
||
font-size: 56rpx;
|
||
color: #D0AC8B;
|
||
line-height: 1;
|
||
}
|
||
|
||
.top-revenue-card .upLoad-text {
|
||
font-size: 32rpx;
|
||
}
|
||
|
||
.check-unit {
|
||
font-size: 24rpx;
|
||
margin-top: 16rpx;
|
||
flex: 1;
|
||
text-align: center;
|
||
}
|
||
|
||
.check-price-color {
|
||
font-size: 32rpx;
|
||
color: #868686;
|
||
line-height: 1.2;
|
||
font-family: 'Bahnschrift Regular';
|
||
}
|
||
|
||
.check-price-color text {
|
||
font-size: 22rpx;
|
||
}
|
||
|
||
/* end */
|
||
|
||
.modle-title {
|
||
padding: 0 32rpx 24rpx 32rpx;
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
display: flex;
|
||
align-items: center;
|
||
margin: 32rpx 20rpx 0 20rpx;
|
||
box-sizing: border-box;
|
||
|
||
image {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
margin-right: 12rpx;
|
||
}
|
||
}
|
||
|
||
.modle-title .uni-icon-arrowdown {
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.modle-title picker {
|
||
color: #000000;
|
||
padding-right: 24rpx;
|
||
position: relative;
|
||
width: 164rpx;
|
||
}
|
||
|
||
.modle-title picker .revenue-date:before {
|
||
content: '';
|
||
position: absolute;
|
||
width: 0rpx;
|
||
height: 0rpx;
|
||
border: 0rpx;
|
||
border-left: 12rpx solid transparent;
|
||
border-right: 12rpx solid transparent;
|
||
border-top: 12rpx solid #000;
|
||
right: 22rpx;
|
||
top: 22rpx;
|
||
|
||
display: block;
|
||
border-radius: 6rpx;
|
||
}
|
||
|
||
.upload-count {
|
||
font-family: 'DIN Alternate', 'Bahnschrift', sans-serif;
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #27B25F;
|
||
margin-left: 16rpx;
|
||
margin-right: 36rpx;
|
||
}
|
||
|
||
.region-title {
|
||
padding: 20rpx 60rpx 20rpx 80rpx;
|
||
position: relative;
|
||
font-size: 30rpx;
|
||
font-weight: bolder;
|
||
|
||
}
|
||
|
||
.region-title:before {
|
||
content: '';
|
||
position: absolute;
|
||
width: 20rpx;
|
||
height: 20rpx;
|
||
background: url(/static/images/revenue/select.png) no-repeat center;
|
||
background-size: contain;
|
||
left: 40rpx;
|
||
top: 36rpx;
|
||
|
||
}
|
||
|
||
.active.region-title:before {
|
||
background: url(/static/images/revenue/select_active.png) no-repeat center;
|
||
background-size: contain;
|
||
|
||
}
|
||
|
||
/*日结上传*/
|
||
.region-cell {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 32rpx 24rpx;
|
||
background-color: #fff;
|
||
margin-bottom: 12rpx;
|
||
border-radius: 12rpx;
|
||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||
border: 1rpx solid #f5f5f5;
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(0.98);
|
||
box-shadow: 0 4rpx 20rpx rgba(39, 178, 95, 0.15);
|
||
}
|
||
}
|
||
|
||
.region-cell .region-cell-unit {
|
||
flex: 2;
|
||
display: flex;
|
||
flex-direction: column;
|
||
color: #666;
|
||
font-size: 28rpx;
|
||
line-height: 1.4;
|
||
text-align: right;
|
||
|
||
.strong-text {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', sans-serif;
|
||
}
|
||
}
|
||
|
||
.region-cell .region-cell-unit:nth-child(1) {
|
||
flex: 3;
|
||
text-align: left;
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
|
||
.region-cell .region-cell-unit:nth-child(3) {
|
||
line-height: 1.2;
|
||
font-size: 26rpx;
|
||
font-weight: 500;
|
||
padding: 8rpx 12rpx;
|
||
background-color: #f8f9fa;
|
||
border-radius: 8rpx;
|
||
min-width: 80rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
.region-cell-image {
|
||
width: 48rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 48rpx;
|
||
|
||
.uni-icon-arrowright {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
transition: all 0.3s ease;
|
||
|
||
&.active {
|
||
transform: rotate(90deg);
|
||
color: #27B25F;
|
||
}
|
||
}
|
||
}
|
||
|
||
.region-cell image {
|
||
width: 14rpx;
|
||
height: 23rpx;
|
||
}
|
||
|
||
/*日结上传服务区*/
|
||
.region-cell-area {
|
||
max-height: 600rpx;
|
||
overflow: auto;
|
||
-webkit-overflow-scrolling: touch;
|
||
background-color: #f8f9fa;
|
||
border-radius: 12rpx;
|
||
margin: 12rpx 0 0 0;
|
||
padding: 16rpx 0;
|
||
}
|
||
|
||
.region-cell-area li.visited view:first-child {
|
||
color: #007AFF;
|
||
|
||
}
|
||
|
||
.region-cell-area li:after {
|
||
content: '›';
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
display: block;
|
||
position: absolute;
|
||
right: 16rpx;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
.region-cell-area li:nth-child(2n+1) {
|
||
background-color: #fff;
|
||
}
|
||
|
||
.region-cell-area li:nth-child(2n+1):before {
|
||
content: '';
|
||
background: linear-gradient(135deg, #27B25F, #4CCC7F);
|
||
width: 8rpx;
|
||
height: 8rpx;
|
||
border-radius: 50%;
|
||
display: block;
|
||
position: absolute;
|
||
left: 20rpx;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
.region-cell-area li:nth-child(2n):before {
|
||
content: '';
|
||
background: linear-gradient(135deg, #ff9f43, #ff6b6b);
|
||
width: 8rpx;
|
||
height: 8rpx;
|
||
border-radius: 50%;
|
||
display: block;
|
||
position: absolute;
|
||
left: 20rpx;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
.region-cell-area li {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 20rpx 24rpx 20rpx 48rpx;
|
||
position: relative;
|
||
text-align: right;
|
||
color: #333;
|
||
background-color: #fff;
|
||
margin: 8rpx 12rpx;
|
||
border-radius: 8rpx;
|
||
border: 1rpx solid #f0f0f0;
|
||
transition: all 0.2s ease;
|
||
|
||
&:active {
|
||
background-color: #f8f9fa;
|
||
transform: scale(0.99);
|
||
}
|
||
}
|
||
|
||
.region-cell-area li>div {
|
||
flex: 2;
|
||
font-size: 22rpx;
|
||
|
||
}
|
||
|
||
.region-cell-area li>div:nth-child(1) {
|
||
flex: 3;
|
||
text-align: left;
|
||
}
|
||
|
||
/*车流量分析*/
|
||
.bayonet-cell-area {
|
||
/* display: none; */
|
||
max-height: 460rpx;
|
||
overflow: auto;
|
||
-webkit-overflow-scrolling: touch;
|
||
}
|
||
|
||
.bayonet-cell-area li {
|
||
width: 100%;
|
||
}
|
||
|
||
.bayonet-cell-area li .server {
|
||
width: 30%;
|
||
display: inline-block;
|
||
text-align: left;
|
||
padding-left: 15rpx;
|
||
}
|
||
|
||
.bayonet-cell-area li .type {
|
||
width: 35%;
|
||
display: inline-block;
|
||
text-align: center;
|
||
}
|
||
|
||
.bayonet-cell-area li .carType {
|
||
width: 30%;
|
||
display: inline-block;
|
||
text-align: right;
|
||
}
|
||
|
||
.bayonet-cell-area li:nth-child(2n+1):before {
|
||
content: '';
|
||
background-color: #5596F9;
|
||
width: 8rpx;
|
||
height: 8rpx;
|
||
border-radius: 8rpx;
|
||
display: block;
|
||
position: absolute;
|
||
left: 0;
|
||
top: 40%;
|
||
}
|
||
|
||
.bayonet-cell-area li:nth-child(2n):before {
|
||
content: '';
|
||
background-color: #FE6D67;
|
||
width: 8rpx;
|
||
height: 8rpx;
|
||
border-radius: 8rpx;
|
||
display: block;
|
||
position: absolute;
|
||
left: 0;
|
||
top: 40%;
|
||
}
|
||
|
||
.bayonet-cell-area li {
|
||
width: 100%;
|
||
/*display: flex;*/
|
||
/*align-items: center;*/
|
||
/*justify-content: space-around;*/
|
||
position: relative;
|
||
}
|
||
|
||
.bayonet-cell-area li>div {
|
||
flex: 2;
|
||
}
|
||
|
||
.bayonet-cell-area li>div:nth-child(1) {
|
||
flex: 3;
|
||
text-align: left;
|
||
}
|
||
|
||
.bayonet-c-list {
|
||
padding: 16rpx 32rpx;
|
||
width: 100%;
|
||
position: relative;
|
||
}
|
||
|
||
.bayonet-c-list div:before {
|
||
content: '';
|
||
background: url(/static/images/authority/fwq.png) no-repeat center;
|
||
width: 35rpx;
|
||
height: 35rpx;
|
||
display: inline-block;
|
||
position: absolute;
|
||
left: 0;
|
||
top: 7px;
|
||
}
|
||
|
||
.modle-title image {
|
||
max-width: 36rpx;
|
||
max-height: 36rpx;
|
||
}
|
||
|
||
.line-tab-unit {
|
||
margin-top: 20rpx;
|
||
/* width: 60rpx; */
|
||
height: 44rpx;
|
||
font-size: 28rpx;
|
||
color: #A9A9A9;
|
||
background: #ececec;
|
||
border-radius: 8rpx;
|
||
text-align: center;
|
||
line-height: 44rpx;
|
||
margin-right: 32rpx;
|
||
padding: 0 10rpx;
|
||
font-size: 22rpx;
|
||
}
|
||
|
||
.line-tab-unit.active {
|
||
background-color: #667ED5;
|
||
color: #fff;
|
||
}
|
||
|
||
.revenue-line-box {
|
||
background-color: #fff;
|
||
margin: 0 16rpx;
|
||
border-radius: 20rpx;
|
||
padding: 34rpx 16rpx 34rpx 16rpx;
|
||
box-shadow: 1rpx 0rpx 6rpx 0px rgba(224, 224, 224, 0.54);
|
||
}
|
||
|
||
.revenue-line-box+.revenue-line-box {
|
||
margin-top: 38rpx;
|
||
}
|
||
|
||
.revenue-line-data {
|
||
width: 216rpx;
|
||
height: 144rpx;
|
||
background-color: #F8F8F8;
|
||
border-radius: 12rpx;
|
||
color: #A5A5A5;
|
||
font-size: 24rpx;
|
||
text-align: center;
|
||
padding-top: 20rpx;
|
||
border: 2rpx solid #F8F8F8;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.revenue-line-data+.revenue-line-data {
|
||
margin-left: 24rpx;
|
||
}
|
||
|
||
.revenue-line-data p:last-child {
|
||
font-size: 40rpx;
|
||
font-family: 'Bahnschrift Regular';
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.revenue-line-data.active {
|
||
border: 2rpx solid #889DED;
|
||
background-color: #f1f3fb;
|
||
color: #667ED5;
|
||
}
|
||
|
||
.revenue-line-box .text-title {
|
||
color: #9498A4;
|
||
font-size: 24rpx;
|
||
margin-top: 38rpx;
|
||
}
|
||
|
||
.revenue-line-box .up-text-title {
|
||
color: #6eb92b;
|
||
font-family: 'Bahnschrift Regular';
|
||
font-size: 36rpx;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.up-text-title:after {
|
||
content: "";
|
||
margin-left: 12rpx;
|
||
width: 20rpx;
|
||
height: 22rpx;
|
||
display: inline-block;
|
||
background: url('/static/images/revenue/up-arrow.png') no-repeat center;
|
||
background-size: contain;
|
||
|
||
}
|
||
|
||
.text-week {
|
||
color: #C2C2C2;
|
||
margin-left: 32rpx;
|
||
}
|
||
|
||
.down-text-title:after {
|
||
content: "";
|
||
margin-left: 12rpx;
|
||
width: 20rpx;
|
||
height: 22rpx;
|
||
display: inline-block;
|
||
background: url('/static/images/revenue/down-arrow.png') no-repeat center;
|
||
background-size: contain;
|
||
|
||
}
|
||
|
||
.revenue-line-box .down-text-title {
|
||
color: #F07878;
|
||
font-family: 'Bahnschrift Regular';
|
||
font-size: 36rpx;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.revenue-line-box .title {
|
||
color: #000;
|
||
font-size: 28rpx;
|
||
font-weight: bolder;
|
||
}
|
||
|
||
.revenue-line-box canvas.operation-content {
|
||
height: 350rpx;
|
||
width: 686rpx;
|
||
margin: 0 auto 0 auto;
|
||
background-color: #fff;
|
||
}
|
||
|
||
/*区域营收占比*/
|
||
/* //.operation-bgfc {
|
||
// background-color: #FCFCFC;
|
||
// padding-bottom: 32rpx;
|
||
//} */
|
||
|
||
.box-operation {
|
||
background-color: #fff;
|
||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||
margin: 0 0 24rpx 0;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
border: 1rpx solid #f0f0f0;
|
||
}
|
||
|
||
.operation-tab-box {
|
||
background: #f8f9fa;
|
||
border-radius: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
text-align: center;
|
||
overflow: hidden;
|
||
margin: 0;
|
||
}
|
||
|
||
.operation-tab-box .operation-tab-unit {
|
||
color: #666;
|
||
flex: 1;
|
||
height: 88rpx;
|
||
line-height: 88rpx;
|
||
position: relative;
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
transition: all 0.3s ease;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.operation-tab-box .operation-tab-unit.active {
|
||
background: linear-gradient(135deg, #27B25F, #4CCC7F);
|
||
color: #fff;
|
||
font-weight: 600;
|
||
position: relative;
|
||
z-index: 2;
|
||
box-shadow: 0 4rpx 12rpx rgba(39, 178, 95, 0.3);
|
||
border-radius: 8rpx;
|
||
margin: 4rpx;
|
||
height: 80rpx;
|
||
line-height: 80rpx;
|
||
}
|
||
|
||
.operation-tab-box .operation-tab-unit.active:after {
|
||
content: none;
|
||
}
|
||
|
||
.operation-tab-box .operation-tab-unit:after {
|
||
content: none;
|
||
}
|
||
|
||
.operation-content-box {
|
||
width: 100%;
|
||
overflow: hidden;
|
||
padding: 24rpx;
|
||
background-color: #fff;
|
||
}
|
||
|
||
canvas.operation-content {
|
||
height: 400rpx;
|
||
width: 100%;
|
||
max-width: 600rpx;
|
||
margin: 0 auto;
|
||
background-color: #fff;
|
||
border-radius: 8rpx;
|
||
}
|
||
|
||
.operation-c-list {
|
||
padding: 20rpx 0;
|
||
border-bottom: 1rpx solid #f5f5f5;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
}
|
||
|
||
.operation-cl-unit {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
margin-bottom: 8rpx;
|
||
|
||
text:first-child {
|
||
font-weight: 600;
|
||
color: #27B25F;
|
||
}
|
||
|
||
text:last-child {
|
||
font-weight: 600;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', sans-serif;
|
||
}
|
||
}
|
||
|
||
.operation-cl-unit1 {
|
||
width: 100%;
|
||
font-size: 26rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.operation-cl-unit1 .server {
|
||
width: 30%;
|
||
display: inline-block;
|
||
text-align: left;
|
||
padding-left: 30rpx;
|
||
}
|
||
|
||
.operation-cl-unit1 .type {
|
||
width: 40%;
|
||
display: inline-block;
|
||
text-align: left;
|
||
}
|
||
|
||
.operation-cl-unit1 .carType {
|
||
width: 30%;
|
||
display: inline-block;
|
||
text-align: center;
|
||
}
|
||
|
||
.operation-c-list .progress {
|
||
width: 100%;
|
||
height: 8rpx;
|
||
background-color: #f0f0f0;
|
||
border-radius: 4rpx;
|
||
margin-top: 12rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.operation-c-list .progress .bgO {
|
||
height: 100%;
|
||
border-radius: 4rpx;
|
||
background: linear-gradient(90deg, #27B25F, #4CCC7F);
|
||
transition: width 0.6s ease;
|
||
}
|
||
|
||
/*排行*/
|
||
.ranking-tab-box {
|
||
margin: 20rpx 20rpx;
|
||
border: 2rpx solid #565656;
|
||
border-radius: 8rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
text-align: center;
|
||
|
||
}
|
||
|
||
.ranking-tab-box .ranking-tab-unit {
|
||
color: #565656;
|
||
flex: 1;
|
||
height: 64rpx;
|
||
line-height: 60rpx;
|
||
}
|
||
|
||
.ranking-tab-box .ranking-tab-unit.active {
|
||
background-color: #565656;
|
||
color: #fff
|
||
}
|
||
|
||
.ranking-tab-box .ranking-tab-unit+.ranking-tab-unit {
|
||
border-left: 2rpx solid #565656;
|
||
}
|
||
|
||
.ranking-content {
|
||
/* display: none; */
|
||
min-height: 160rpx;
|
||
}
|
||
|
||
.ranking-content {
|
||
margin: 0 20rpx;
|
||
}
|
||
|
||
.ranking-content .ranking-list {
|
||
display: flex;
|
||
align-items: center;
|
||
color: #000;
|
||
padding: 24rpx 32rpx;
|
||
}
|
||
|
||
.ranking-content .rank-index {
|
||
width: 72rpx;
|
||
height: 72rpx;
|
||
text-align: center;
|
||
line-height: 72rpx;
|
||
font-size: 30rpx;
|
||
font-weight: bolder;
|
||
margin-right: 32rpx;
|
||
}
|
||
|
||
.ranking-content .ranking-list:nth-child(1) .rank-index {
|
||
background: url('https://eshangtech.com/ShopICO/ahyd-BID/revenue/top1.png') no-repeat center;
|
||
background-size: contain;
|
||
font-size: 0;
|
||
}
|
||
|
||
.ranking-content .ranking-list:nth-child(2) .rank-index {
|
||
background: url('https://eshangtech.com/ShopICO/ahyd-BID/revenue/top1.png') no-repeat center;
|
||
background-size: contain;
|
||
font-size: 0;
|
||
}
|
||
|
||
.ranking-content .ranking-list:nth-child(3) .rank-index {
|
||
background: url('https://eshangtech.com/ShopICO/ahyd-BID/revenue/top3.png') no-repeat center;
|
||
background-size: contain;
|
||
font-size: 0;
|
||
}
|
||
|
||
.ranking-content .ranking-list-unit {
|
||
font-size: 28rpx;
|
||
flex: 1;
|
||
}
|
||
|
||
.ranking-content .ranking-unit-info {
|
||
/* margin-top: 16rpx; */
|
||
display: flex;
|
||
align-items: center;
|
||
/* font-size: .13rem; */
|
||
}
|
||
|
||
.ranking-content .ranking-unit-info text {
|
||
flex: 2;
|
||
color: #929292;
|
||
}
|
||
|
||
.ranking-content .ranking-unit-info text:nth-child(2) {
|
||
flex: 3;
|
||
}
|
||
|
||
.ranking-content .ranking-unit-info text:nth-child(2n) {
|
||
color: #000
|
||
}
|
||
|
||
.ranking-ico {
|
||
width: 72rpx;
|
||
height: 72rpx;
|
||
}
|
||
|
||
// 新增主内容区域样式
|
||
.main-content {
|
||
background-color: #fff;
|
||
margin: 0 20rpx 24rpx 20rpx;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||
border: 1rpx solid #f0f0f0;
|
||
}
|
||
|
||
/* 现代化页面重设计样式 */
|
||
.section-header {
|
||
padding: 24rpx;
|
||
border-bottom: 2rpx solid #f1f3f4;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
background: #f8f9fa;
|
||
}
|
||
|
||
.section-title {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.section-icon {
|
||
margin-right: 12rpx;
|
||
}
|
||
|
||
.icon-emoji {
|
||
font-size: 32rpx;
|
||
}
|
||
|
||
.section-text {
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
color: #2c3e50;
|
||
}
|
||
|
||
.section-badge {
|
||
background: #27B25F;
|
||
color: white;
|
||
font-size: 22rpx;
|
||
padding: 8rpx 16rpx;
|
||
border-radius: 20rpx;
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* 分析容器 */
|
||
.analysis-container {
|
||
background: #fff;
|
||
margin-top: 16rpx;
|
||
}
|
||
|
||
/* 现代化标签页 */
|
||
.modern-tabs {
|
||
display: flex;
|
||
background: #f8f9fa;
|
||
padding: 8rpx;
|
||
margin: 0 24rpx 24rpx;
|
||
border-radius: 16rpx;
|
||
}
|
||
|
||
.tab-item {
|
||
flex: 1;
|
||
padding: 24rpx 16rpx;
|
||
text-align: center;
|
||
border-radius: 12rpx;
|
||
transition: all 0.3s ease;
|
||
cursor: pointer;
|
||
border: none;
|
||
background: transparent;
|
||
color: #666;
|
||
margin: 0 8rpx;
|
||
}
|
||
|
||
.tab-item.active {
|
||
background: #27B25F;
|
||
color: white;
|
||
box-shadow: 0 4rpx 16rpx rgba(39, 178, 95, 0.2);
|
||
}
|
||
|
||
.tab-icon {
|
||
font-size: 32rpx;
|
||
margin-bottom: 8rpx;
|
||
line-height: 1;
|
||
}
|
||
|
||
.tab-label {
|
||
font-size: 26rpx;
|
||
font-weight: 500;
|
||
line-height: 1.2;
|
||
}
|
||
|
||
/* 内容包装器 */
|
||
.content-wrapper {
|
||
padding: 0 24rpx 32rpx;
|
||
}
|
||
|
||
/* 图表区域 */
|
||
.chart-section {
|
||
// margin-bottom: 32rpx;
|
||
}
|
||
|
||
.chart-container {
|
||
background: #f8f9fa;
|
||
border-radius: 16rpx;
|
||
// padding: 24rpx;
|
||
margin-bottom: 24rpx;
|
||
// box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.04);
|
||
// border: 1rpx solid rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
.modern-chart {
|
||
width: 100%;
|
||
height: 500rpx;
|
||
border-radius: 8rpx;
|
||
background: white;
|
||
}
|
||
|
||
/* 数据卡片布局 - 使用flex替代grid */
|
||
.data-cards {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
margin: -8rpx;
|
||
}
|
||
|
||
.data-card {
|
||
background: white;
|
||
border-radius: 12rpx;
|
||
padding: 24rpx 20rpx;
|
||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||
border: 1rpx solid rgba(0, 0, 0, 0.04);
|
||
position: relative;
|
||
overflow: hidden;
|
||
width: calc(50% - 16rpx);
|
||
margin: 8rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.data-card::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
height: 4rpx;
|
||
background: #27B25F;
|
||
}
|
||
|
||
.card-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.category-name {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #2c3e50;
|
||
}
|
||
|
||
.percentage {
|
||
font-size: 24rpx;
|
||
font-weight: 600;
|
||
color: #27B25F;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
}
|
||
|
||
.amount {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #27B25F;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
margin-bottom: 12rpx;
|
||
line-height: 1.1;
|
||
}
|
||
|
||
.progress-bar {
|
||
width: 100%;
|
||
height: 8rpx;
|
||
background-color: #f0f0f0;
|
||
border-radius: 4rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.progress-fill {
|
||
height: 100%;
|
||
border-radius: 4rpx;
|
||
background: #27B25F;
|
||
transition: width 0.6s ease;
|
||
}
|
||
|
||
/* 车流分析区域 - 重构版本 */
|
||
.traffic-analysis {
|
||
// margin: 0 20rpx 32rpx 20rpx;
|
||
background: #fff;
|
||
border-radius: 12rpx;
|
||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||
border: 1rpx solid #f0f0f0;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.traffic-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 20rpx 24rpx;
|
||
background: linear-gradient(135deg, #f8f9fa, #e9ecef);
|
||
border-bottom: 2rpx solid #f1f3f4;
|
||
}
|
||
|
||
.traffic-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.traffic-icon {
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.traffic-title text {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #2c3e50;
|
||
}
|
||
|
||
.traffic-summary {
|
||
font-size: 24rpx;
|
||
color: #6c757d;
|
||
background: #fff;
|
||
padding: 6rpx 12rpx;
|
||
border-radius: 16rpx;
|
||
border: 1rpx solid #e9ecef;
|
||
}
|
||
|
||
.traffic-scroll-container {
|
||
height: 700rpx;
|
||
background: #fff;
|
||
}
|
||
|
||
.traffic-regions {
|
||
padding: 20rpx;
|
||
}
|
||
|
||
.region-card {
|
||
background: #f8f9fa;
|
||
border-radius: 12rpx;
|
||
margin-bottom: 20rpx;
|
||
border: 1rpx solid rgba(0, 0, 0, 0.04);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.region-card:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.region-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 16rpx 20rpx;
|
||
background: linear-gradient(135deg, #fff, #f8f9fa);
|
||
border-bottom: 1rpx solid #e9ecef;
|
||
}
|
||
|
||
.region-badge {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10rpx;
|
||
}
|
||
|
||
.region-icon {
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.region-title {
|
||
font-size: 26rpx;
|
||
font-weight: 600;
|
||
color: #2c3e50;
|
||
}
|
||
|
||
.region-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.region-count {
|
||
font-size: 22rpx;
|
||
color: #6c757d;
|
||
background: rgba(108, 117, 125, 0.1);
|
||
padding: 4rpx 12rpx;
|
||
border-radius: 12rpx;
|
||
}
|
||
|
||
.region-arrow {
|
||
font-size: 20rpx;
|
||
color: #999;
|
||
transition: transform 0.3s ease;
|
||
}
|
||
|
||
.region-arrow.collapsed {
|
||
transform: rotate(-90deg);
|
||
}
|
||
|
||
.service-areas {
|
||
padding: 12rpx;
|
||
}
|
||
|
||
.service-area-item {
|
||
background: #fff;
|
||
border-radius: 8rpx;
|
||
margin-bottom: 12rpx;
|
||
border: 1rpx solid rgba(0, 0, 0, 0.04);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.service-area-item:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.service-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 16rpx 16rpx 12rpx;
|
||
border-bottom: 1rpx solid #f1f3f4;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.service-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.service-info {
|
||
flex: 1;
|
||
}
|
||
|
||
.service-name {
|
||
font-size: 26rpx;
|
||
font-weight: 600;
|
||
color: #2c3e50;
|
||
margin-bottom: 4rpx;
|
||
}
|
||
|
||
.service-ratio {
|
||
font-size: 22rpx;
|
||
color: #27B25F;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.flow-stats {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.flow-item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 2rpx;
|
||
}
|
||
|
||
.flow-label {
|
||
font-size: 20rpx;
|
||
color: #6c757d;
|
||
}
|
||
|
||
.flow-value {
|
||
font-size: 24rpx;
|
||
font-weight: 600;
|
||
color: #27B25F;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
}
|
||
|
||
// 一些保持灰色的数据文字
|
||
.stat-value {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #495057;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
}
|
||
|
||
.direction-ratio {
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
color: #6c757d;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
}
|
||
|
||
.flow-divider {
|
||
color: #e9ecef;
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.expand-arrow {
|
||
font-size: 18rpx;
|
||
color: #999;
|
||
transition: transform 0.3s ease;
|
||
margin-left: 12rpx;
|
||
}
|
||
|
||
.expand-arrow.expanded {
|
||
transform: rotate(180deg);
|
||
}
|
||
|
||
.direction-list {
|
||
padding: 12rpx 16rpx 16rpx;
|
||
}
|
||
|
||
.direction-item {
|
||
background: #f8f9fa;
|
||
border-radius: 6rpx;
|
||
padding: 12rpx;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.direction-item:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.direction-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.direction-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4rpx;
|
||
}
|
||
|
||
.direction-name {
|
||
font-size: 24rpx;
|
||
font-weight: 600;
|
||
color: #2c3e50;
|
||
}
|
||
|
||
.direction-percent {
|
||
font-size: 20rpx;
|
||
color: #27B25F;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.vehicle-stats {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
}
|
||
|
||
.vehicle-type-group {
|
||
display: flex;
|
||
gap: 16rpx;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.vehicle-type-item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
background: #f8f9fa;
|
||
padding: 8rpx 12rpx;
|
||
border-radius: 8rpx;
|
||
border: 1rpx solid #e9ecef;
|
||
min-width: 60rpx;
|
||
}
|
||
|
||
.vehicle-type-label {
|
||
font-size: 20rpx;
|
||
color: #6c757d;
|
||
margin-bottom: 4rpx;
|
||
}
|
||
|
||
.vehicle-count-value {
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
color: #2c3e50;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
}
|
||
|
||
/* 上传数据区域 */
|
||
.upload-section {
|
||
background: white;
|
||
border-radius: 16rpx;
|
||
padding: 24rpx;
|
||
margin: 0 20rpx 24rpx 20rpx;
|
||
box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.06);
|
||
border: 1rpx solid rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
.upload-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
// margin-bottom: 24rpx;
|
||
// padding-bottom: 16rpx;
|
||
// border-bottom: 2rpx solid #f1f3f4;
|
||
}
|
||
|
||
.upload-title {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.upload-icon {
|
||
font-size: 28rpx;
|
||
margin-right: 12rpx;
|
||
}
|
||
|
||
.upload-text {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #2c3e50;
|
||
}
|
||
|
||
.upload-summary {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.summary-label {
|
||
font-size: 24rpx;
|
||
color: #6c757d;
|
||
}
|
||
|
||
.summary-value {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #27B25F;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
}
|
||
|
||
/* 服务列表 */
|
||
.service-list {
|
||
background: white;
|
||
border-radius: 16rpx;
|
||
padding: 24rpx;
|
||
margin: 0 20rpx 32rpx 20rpx;
|
||
box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.06);
|
||
border: 1rpx solid rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
.service-card {
|
||
background: #f8f9fa;
|
||
border-radius: 12rpx;
|
||
padding: 24rpx 20rpx;
|
||
margin-bottom: 16rpx;
|
||
border: 1rpx solid rgba(0, 0, 0, 0.04);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.service-card:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.service-card::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
height: 4rpx;
|
||
background: #27B25F;
|
||
}
|
||
|
||
.service-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.service-info {
|
||
flex: 1;
|
||
}
|
||
|
||
.service-name {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
color: #2c3e50;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.service-revenue {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #27B25F;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
}
|
||
|
||
.service-status {
|
||
text-align: right;
|
||
}
|
||
|
||
.upload-rate {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #27B25F;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
margin-bottom: 4rpx;
|
||
}
|
||
|
||
.upload-rate.warning {
|
||
color: #ff9f43;
|
||
}
|
||
|
||
.upload-fraction {
|
||
font-size: 22rpx;
|
||
color: #6c757d;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
}
|
||
|
||
.upload-fraction.incomplete {
|
||
color: #ff4757;
|
||
}
|
||
|
||
.service-indicator {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
margin-top: 16rpx;
|
||
}
|
||
|
||
.status-dot {
|
||
width: 8rpx;
|
||
height: 8rpx;
|
||
border-radius: 50%;
|
||
background: #ff4757;
|
||
}
|
||
|
||
.status-dot.complete {
|
||
background: #27B25F;
|
||
}
|
||
|
||
.arrow-icon {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
font-weight: 600;
|
||
}
|
||
|
||
/* 区域列表 */
|
||
.region-list {
|
||
background: white;
|
||
border-radius: 16rpx;
|
||
padding: 0 0 24rpx;
|
||
margin: 0 20rpx;
|
||
// box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.06);
|
||
// border: 1rpx solid rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
.region-card {
|
||
background: #f8f9fa;
|
||
border-radius: 12rpx;
|
||
margin-bottom: 16rpx;
|
||
border: 1rpx solid rgba(0, 0, 0, 0.04);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.region-card:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.region-main {
|
||
padding: 24rpx 20rpx;
|
||
position: relative;
|
||
}
|
||
|
||
.region-main::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
height: 4rpx;
|
||
background: #27B25F;
|
||
}
|
||
|
||
.region-info {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.region-name {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
color: #2c3e50;
|
||
}
|
||
|
||
.region-revenue {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #27B25F;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
}
|
||
|
||
.region-metrics {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 24rpx;
|
||
}
|
||
|
||
.metric-item {
|
||
text-align: center;
|
||
}
|
||
|
||
.metric-label {
|
||
font-size: 22rpx;
|
||
color: #6c757d;
|
||
margin-bottom: 4rpx;
|
||
}
|
||
|
||
.metric-value {
|
||
font-size: 26rpx;
|
||
font-weight: 600;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
}
|
||
|
||
.metric-value.rate {
|
||
color: #27B25F;
|
||
}
|
||
|
||
.metric-value.rate.incomplete {
|
||
color: #ff9f43;
|
||
}
|
||
|
||
.metric-value.fraction {
|
||
color: #6c757d;
|
||
}
|
||
|
||
.metric-value.fraction.incomplete {
|
||
color: #ff4757;
|
||
}
|
||
|
||
.expand-indicator {
|
||
margin-left: auto;
|
||
}
|
||
|
||
.expand-icon {
|
||
font-size: 20rpx;
|
||
color: #999;
|
||
}
|
||
|
||
.service-sublist {
|
||
background: white;
|
||
border-top: 1rpx solid #e9ecef;
|
||
padding: 16rpx 0 0;
|
||
}
|
||
|
||
.subservice-card {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 16rpx 20rpx;
|
||
margin: 8rpx 16rpx;
|
||
background: #f8f9fa;
|
||
border-radius: 8rpx;
|
||
border: 1rpx solid rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
.subservice-card.visited .subservice-name {
|
||
color: #27B25F;
|
||
}
|
||
|
||
.subservice-info {
|
||
flex: 1;
|
||
}
|
||
|
||
.subservice-name {
|
||
font-size: 26rpx;
|
||
font-weight: 600;
|
||
color: #2c3e50;
|
||
margin-bottom: 4rpx;
|
||
}
|
||
|
||
.subservice-revenue {
|
||
font-size: 24rpx;
|
||
font-weight: 600;
|
||
color: #27B25F;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
}
|
||
|
||
.subservice-status {
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
color: #6c757d;
|
||
font-family: 'DIN Alternate', 'Bahnschrift', monospace;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.subservice-status.incomplete {
|
||
color: #ff4757;
|
||
}
|
||
|
||
.subservice-arrow {
|
||
font-size: 20rpx;
|
||
color: #999;
|
||
font-weight: 600;
|
||
}
|
||
|
||
/* 微信小程序兼容性修正 - 移除不支持的特性 */
|
||
/* 移除 @media 查询,改用 flex 替代 grid */
|
||
|
||
/* 加载骨架屏样式 */
|
||
.loading-skeleton {
|
||
padding: 20rpx;
|
||
background-color: #f8f9fa;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.skeleton-header {
|
||
height: 300rpx;
|
||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||
background-size: 200% 100%;
|
||
animation: loading 1.5s infinite;
|
||
border-radius: 16rpx;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.skeleton-cards {
|
||
display: flex;
|
||
gap: 16rpx;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.skeleton-card {
|
||
flex: 1;
|
||
height: 120rpx;
|
||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||
background-size: 200% 100%;
|
||
animation: loading 1.5s infinite;
|
||
border-radius: 12rpx;
|
||
}
|
||
|
||
.skeleton-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.skeleton-item {
|
||
height: 100rpx;
|
||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||
background-size: 200% 100%;
|
||
animation: loading 1.5s infinite;
|
||
border-radius: 12rpx;
|
||
}
|
||
|
||
@keyframes loading {
|
||
0% {
|
||
background-position: 200% 0;
|
||
}
|
||
|
||
100% {
|
||
background-position: -200% 0;
|
||
}
|
||
}
|
||
</style>
|