mirror of
https://github.com/crmeb/CRMEB.git
synced 2026-10-28 13:31:04 +00:00
fix(首页图表): 订单统计按周期对齐 ECharts,并补商品支付排行
修正日环比零除口径,用户新增按日分组日期格式统一为 m-d。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
2444d60cc4
commit
b3f71d28e3
@ -388,27 +388,33 @@ class OrderCenterDao extends BaseDao
|
||||
|
||||
/**
|
||||
* 订单图表分组统计
|
||||
* 按周期对已支付订单进行分组,统计每天的订单量与销售额
|
||||
* @param int $startTime 开始时间戳
|
||||
* @param int $endTime 结束时间戳
|
||||
* @param string $cycle 统计周期:thirtyday=按天、month=按月、其余=按年
|
||||
* 按周期对已支付订单分组,统计订单量与销售额
|
||||
* @param string|int $dateBefore 开始日期(Y-m-d 或时间戳)
|
||||
* @param string|int $dateAfter 结束日期(Y-m-d 或时间戳)
|
||||
* @param string $timeType 分组粒度:30=月日、week=星期、month=日、year=月
|
||||
* @return array 返回分组统计列表(day/count/price)
|
||||
*/
|
||||
public function orderCharts(int $startTime, int $endTime, string $cycle = 'thirtyday'): array
|
||||
public function orderCharts($dateBefore, $dateAfter, string $timeType = '30'): array
|
||||
{
|
||||
// 根据统计周期决定分组粒度
|
||||
switch ($cycle) {
|
||||
case 'thirtyday':
|
||||
$format = '%Y-%m-%d';
|
||||
switch ($timeType) {
|
||||
case 'week':
|
||||
$format = '%w';
|
||||
break;
|
||||
case 'month':
|
||||
$format = '%Y-%m';
|
||||
$format = '%d';
|
||||
break;
|
||||
case 'year':
|
||||
$format = '%m';
|
||||
break;
|
||||
case '30':
|
||||
default:
|
||||
$format = '%Y';
|
||||
$format = '%m-%d';
|
||||
break;
|
||||
}
|
||||
|
||||
$startTime = is_numeric($dateBefore) ? (int)$dateBefore : strtotime((string)$dateBefore);
|
||||
$endTime = is_numeric($dateAfter) ? (int)$dateAfter : strtotime((string)$dateAfter);
|
||||
|
||||
return $this->getModel()
|
||||
->where('is_del', 0)
|
||||
->where('pay_status', 1)
|
||||
@ -420,6 +426,25 @@ class OrderCenterDao extends BaseDao
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计区间内已支付订单总量与销售额
|
||||
* @param string|int $dateBefore 开始日期
|
||||
* @param string|int $dateAfter 结束日期
|
||||
* @return array{count:int,price:float}
|
||||
*/
|
||||
public function preTotalFind($dateBefore, $dateAfter): array
|
||||
{
|
||||
$startTime = is_numeric($dateBefore) ? (int)$dateBefore : strtotime((string)$dateBefore);
|
||||
$endTime = is_numeric($dateAfter) ? (int)$dateAfter : strtotime((string)$dateAfter);
|
||||
$res = $this->getModel()
|
||||
->where('is_del', 0)
|
||||
->where('pay_status', 1)
|
||||
->whereBetween('pay_time', [$startTime, $endTime])
|
||||
->fieldRaw('COUNT(*) as count, COALESCE(SUM(pay_price), 0) as price')
|
||||
->find();
|
||||
return $res ? $res->toArray() : ['count' => 0, 'price' => 0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单列表(导出用)
|
||||
* 兼容旧 getOrderList 调用方,适配新订单中台字段:
|
||||
|
||||
@ -256,8 +256,8 @@ class UserDao extends BaseDao
|
||||
{
|
||||
return $this->getModel()
|
||||
->whereBetweenTime('add_time', $starday, $yesterday)
|
||||
->field("FROM_UNIXTIME(add_time,'%m-%e') as day,count(*) as count")
|
||||
->group("FROM_UNIXTIME(add_time, '%Y%m%e')")
|
||||
->field("FROM_UNIXTIME(add_time,'%m-%d') as day,count(*) as count")
|
||||
->group("FROM_UNIXTIME(add_time, '%Y-%m-%d')")
|
||||
->order('add_time asc')->select()->toArray();
|
||||
}
|
||||
|
||||
|
||||
@ -2374,16 +2374,16 @@ class OrderCenterServices extends BaseService implements OrderCenterSyncInterfac
|
||||
],
|
||||
];
|
||||
|
||||
// 计算日环比增长率
|
||||
// 计算日环比增长率(昨日为 0 时:今日有值记 100%,否则 0)
|
||||
foreach ($info as &$item) {
|
||||
$nowValue = $item['today'];
|
||||
$lastValue = $item['yesterday'];
|
||||
if ($lastValue == 0 && $nowValue == 0) {
|
||||
$nowValue = (float)$item['today'];
|
||||
$lastValue = (float)$item['yesterday'];
|
||||
if ($lastValue == 0.0 && $nowValue == 0.0) {
|
||||
$item['today_ratio'] = 0;
|
||||
} elseif ($lastValue == 0) {
|
||||
$item['today_ratio'] = round($nowValue, 2);
|
||||
} elseif ($nowValue == 0) {
|
||||
$item['today_ratio'] = -round($lastValue, 2);
|
||||
} elseif ($lastValue == 0.0) {
|
||||
$item['today_ratio'] = 100;
|
||||
} elseif ($nowValue == 0.0) {
|
||||
$item['today_ratio'] = -100;
|
||||
} else {
|
||||
$item['today_ratio'] = (float)bcmul(bcdiv((string)($nowValue - $lastValue), (string)$lastValue, 4), '100', 2);
|
||||
}
|
||||
@ -2396,38 +2396,227 @@ class OrderCenterServices extends BaseService implements OrderCenterSyncInterfac
|
||||
/**
|
||||
* 订单图表
|
||||
* 根据周期统计已支付订单的订单量与销售额,用于后台首页图表展示
|
||||
* @param string $cycle 统计周期:thirtyday=近30天、month=近12月、year=近1年
|
||||
* @return array 返回图表数据(legend/yAxis/xAxis/series)
|
||||
* @param string $cycle thirtyday=近30天;week/month/year=上期与本期对比
|
||||
* @return array 返回图表数据(legend/yAxis/xAxis/series 为 ECharts 结构)
|
||||
*/
|
||||
public function orderCharts(string $cycle): array
|
||||
{
|
||||
// 根据周期计算起始日期
|
||||
$starday = $cycle == 'thirtyday' ? date('Y-m-d', strtotime('-30 day')) : ($cycle == 'month' ? date('Y-m-d', strtotime('-12 month')) : date('Y-m-d', strtotime('-1 year')));
|
||||
$yesterday = date('Y-m-d', strtotime('+1 day'));
|
||||
$startTime = strtotime($starday);
|
||||
$endTime = strtotime($yesterday);
|
||||
|
||||
$orderList = $this->dao->orderCharts($startTime, $endTime, $cycle);
|
||||
|
||||
$chartdata = [];
|
||||
$data = [];
|
||||
$chartdata['legend'] = ['订单量', '销售额'];//分类
|
||||
$chartdata['yAxis']['maxnum'] = 0;//最大值数量
|
||||
$chartdata['xAxis'] = [$starday];//X轴值
|
||||
$chartdata['series'] = [0, 0];//分类1值
|
||||
if (!empty($orderList)) {
|
||||
foreach ($orderList as $v) {
|
||||
$data['day'][] = $v['day'];
|
||||
$data['count'][] = $v['count'];
|
||||
$data['price'][] = (float)$v['price'];
|
||||
if ($chartdata['yAxis']['maxnum'] < $v['count'])
|
||||
$chartdata['yAxis']['maxnum'] = $v['count'];
|
||||
}
|
||||
$chartdata['xAxis'] = $data['day'];//X轴值
|
||||
$chartdata['series'][0] = $data['count'];//分类1值
|
||||
$chartdata['series'][1] = $data['price'];//分类2值
|
||||
switch ($cycle) {
|
||||
case 'week':
|
||||
return $this->buildCompareOrderCharts(
|
||||
['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
|
||||
['上周金额', '本周金额', '上周订单数', '本周订单数'],
|
||||
date('Y-m-d', strtotime('-1 week Monday')),
|
||||
date('Y-m-d 23:59:59', strtotime('-1 week Sunday')),
|
||||
date('Y-m-d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600)),
|
||||
date('Y-m-d 23:59:59'),
|
||||
'week',
|
||||
static fn($k) => (string)(int)$k
|
||||
);
|
||||
case 'month':
|
||||
$days = [];
|
||||
for ($i = 1; $i <= 31; $i++) {
|
||||
$key = str_pad((string)$i, 2, '0', STR_PAD_LEFT);
|
||||
$days[$key] = (string)$i;
|
||||
}
|
||||
return $this->buildCompareOrderCharts(
|
||||
$days,
|
||||
['上月金额', '本月金额', '上月订单数', '本月订单数'],
|
||||
date('Y-m-01', strtotime('-1 month')),
|
||||
date('Y-m-d 23:59:59', strtotime(date('Y-m-01')) - 1),
|
||||
date('Y-m-01'),
|
||||
date('Y-m-d 23:59:59'),
|
||||
'month'
|
||||
);
|
||||
case 'year':
|
||||
return $this->buildCompareOrderCharts(
|
||||
[
|
||||
'01' => '一月', '02' => '二月', '03' => '三月', '04' => '四月',
|
||||
'05' => '五月', '06' => '六月', '07' => '七月', '08' => '八月',
|
||||
'09' => '九月', '10' => '十月', '11' => '十一月', '12' => '十二月',
|
||||
],
|
||||
['去年金额', '今年金额', '去年订单数', '今年订单数'],
|
||||
date('Y-01-01', strtotime('-1 year')),
|
||||
date('Y-12-31 23:59:59', strtotime('-1 year')),
|
||||
date('Y-01-01'),
|
||||
date('Y-12-31 23:59:59'),
|
||||
'year'
|
||||
);
|
||||
case 'thirtyday':
|
||||
default:
|
||||
return $this->buildThirtydayOrderCharts();
|
||||
}
|
||||
return $chartdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* 近 30 天订单金额/订单数图表(补齐缺失日期)
|
||||
*/
|
||||
protected function buildThirtydayOrderCharts(): array
|
||||
{
|
||||
$dateBefore = date('Y-m-d', strtotime('-29 day'));
|
||||
$dateAfter = date('Y-m-d 23:59:59');
|
||||
$preBefore = date('Y-m-d', strtotime('-59 day'));
|
||||
$preAfter = date('Y-m-d 23:59:59', strtotime('-30 day'));
|
||||
|
||||
$datalist = [];
|
||||
for ($i = -29; $i <= 0; $i++) {
|
||||
$label = date('m-d', strtotime($i . ' day'));
|
||||
$datalist[$label] = $label;
|
||||
}
|
||||
|
||||
$orderMap = [];
|
||||
foreach ($this->dao->orderCharts($dateBefore, $dateAfter, '30') as $row) {
|
||||
$orderMap[$row['day']] = $row;
|
||||
}
|
||||
|
||||
$counts = [];
|
||||
$prices = [];
|
||||
$xAxis = [];
|
||||
$maxNum = 0;
|
||||
$maxPrice = 0;
|
||||
foreach ($datalist as $day) {
|
||||
$count = (int)($orderMap[$day]['count'] ?? 0);
|
||||
$price = round((float)($orderMap[$day]['price'] ?? 0), 2);
|
||||
$xAxis[] = $day;
|
||||
$counts[] = $count;
|
||||
$prices[] = $price;
|
||||
$maxNum = max($maxNum, $count);
|
||||
$maxPrice = max($maxPrice, $price);
|
||||
}
|
||||
|
||||
$legend = ['订单金额', '订单数'];
|
||||
$chartdata = [
|
||||
'legend' => $legend,
|
||||
'xAxis' => $xAxis,
|
||||
'yAxis' => ['maxnum' => $maxNum, 'maxprice' => $maxPrice],
|
||||
'series' => [
|
||||
['name' => $legend[0], 'type' => 'bar', 'itemStyle' => $this->orderChartBarStyle('#69cdff', '#1495eb'), 'data' => $prices],
|
||||
['name' => $legend[1], 'type' => 'line', 'itemStyle' => $this->orderChartBarStyle('#6fdeab', '#2cc981'), 'data' => $counts, 'yAxisIndex' => 1],
|
||||
],
|
||||
];
|
||||
return array_merge($chartdata, $this->buildOrderCycleSummary($preBefore, $preAfter, $dateBefore, $dateAfter));
|
||||
}
|
||||
|
||||
/**
|
||||
* 周/月/年:上期 vs 本期对比图表
|
||||
* @param array $axisLabels 轴标签(索引或关联)
|
||||
* @param array $legend 图例四项
|
||||
* @param string $preBefore 上期开始
|
||||
* @param string $preAfter 上期结束
|
||||
* @param string $nowBefore 本期开始
|
||||
* @param string $nowAfter 本期结束
|
||||
* @param string $timeType DAO 分组类型
|
||||
* @param callable|null $keyNormalizer 将查询 day 规范为轴 key
|
||||
*/
|
||||
protected function buildCompareOrderCharts(
|
||||
array $axisLabels,
|
||||
array $legend,
|
||||
string $preBefore,
|
||||
string $preAfter,
|
||||
string $nowBefore,
|
||||
string $nowAfter,
|
||||
string $timeType,
|
||||
?callable $keyNormalizer = null
|
||||
): array {
|
||||
$preMap = [];
|
||||
foreach ($this->dao->orderCharts($preBefore, $preAfter, $timeType) as $row) {
|
||||
$key = $keyNormalizer ? $keyNormalizer($row['day']) : (string)$row['day'];
|
||||
$preMap[$key] = $row;
|
||||
}
|
||||
$nowMap = [];
|
||||
foreach ($this->dao->orderCharts($nowBefore, $nowAfter, $timeType) as $row) {
|
||||
$key = $keyNormalizer ? $keyNormalizer($row['day']) : (string)$row['day'];
|
||||
$nowMap[$key] = $row;
|
||||
}
|
||||
|
||||
$xAxis = [];
|
||||
$preCount = [];
|
||||
$prePrice = [];
|
||||
$nowCount = [];
|
||||
$nowPrice = [];
|
||||
$maxNum = 0;
|
||||
$maxPrice = 0;
|
||||
foreach ($axisLabels as $key => $label) {
|
||||
$axisKey = is_int($key) ? (string)$key : (string)$key;
|
||||
$labelText = is_array($label) ? ($label[0] ?? $axisKey) : (string)$label;
|
||||
$pc = (int)($preMap[$axisKey]['count'] ?? 0);
|
||||
$pp = round((float)($preMap[$axisKey]['price'] ?? 0), 2);
|
||||
$nc = (int)($nowMap[$axisKey]['count'] ?? 0);
|
||||
$np = round((float)($nowMap[$axisKey]['price'] ?? 0), 2);
|
||||
$xAxis[] = $labelText;
|
||||
$preCount[] = $pc;
|
||||
$prePrice[] = $pp;
|
||||
$nowCount[] = $nc;
|
||||
$nowPrice[] = $np;
|
||||
$maxNum = max($maxNum, $pc, $nc);
|
||||
$maxPrice = max($maxPrice, $pp, $np);
|
||||
}
|
||||
|
||||
$chartdata = [
|
||||
'legend' => $legend,
|
||||
'xAxis' => $xAxis,
|
||||
'yAxis' => ['maxnum' => $maxNum, 'maxprice' => $maxPrice],
|
||||
'series' => [
|
||||
['name' => $legend[0], 'type' => 'bar', 'itemStyle' => $this->orderChartBarStyle('#69cdff', '#1495eb'), 'data' => $prePrice],
|
||||
['name' => $legend[1], 'type' => 'bar', 'itemStyle' => $this->orderChartBarStyle('#6fdeab', '#2cc981'), 'data' => $nowPrice],
|
||||
['name' => $legend[2], 'type' => 'line', 'itemStyle' => $this->orderChartBarStyle('#69cdff', '#1495eb'), 'data' => $preCount, 'yAxisIndex' => 1],
|
||||
['name' => $legend[3], 'type' => 'line', 'itemStyle' => $this->orderChartBarStyle('#6fdeab', '#2cc981'), 'data' => $nowCount, 'yAxisIndex' => 1],
|
||||
],
|
||||
];
|
||||
return array_merge($chartdata, $this->buildOrderCycleSummary($preBefore, $preAfter, $nowBefore, $nowAfter));
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装上期/本期汇总(环比)
|
||||
*/
|
||||
protected function buildOrderCycleSummary(string $preBefore, string $preAfter, string $nowBefore, string $nowAfter): array
|
||||
{
|
||||
$preTotal = $this->dao->preTotalFind($preBefore, $preAfter);
|
||||
$total = $this->dao->preTotalFind($nowBefore, $nowAfter);
|
||||
$preCount = (int)($preTotal['count'] ?? 0);
|
||||
$prePrice = (float)($preTotal['price'] ?? 0);
|
||||
$nowCount = (int)($total['count'] ?? 0);
|
||||
$nowPrice = (float)($total['price'] ?? 0);
|
||||
$chaCount = $preCount - $nowCount;
|
||||
$chaPrice = round($prePrice, 2) - round($nowPrice, 2);
|
||||
$baseCount = $preCount == 0 ? 1 : $preCount;
|
||||
$basePrice = $prePrice == 0 ? 1 : $prePrice;
|
||||
return [
|
||||
'pre_cycle' => [
|
||||
'count' => ['data' => $preCount],
|
||||
'price' => ['data' => $prePrice],
|
||||
],
|
||||
'cycle' => [
|
||||
'count' => [
|
||||
'data' => $nowCount,
|
||||
'percent' => round((abs($chaCount) / $baseCount) * 100, 2),
|
||||
'is_plus' => $chaCount > 0 ? -1 : ($chaCount == 0 ? 0 : 1),
|
||||
],
|
||||
'price' => [
|
||||
'data' => $nowPrice,
|
||||
'percent' => round((abs($chaPrice) / $basePrice) * 100, 2),
|
||||
'is_plus' => $chaPrice > 0 ? -1 : ($chaPrice == 0 ? 0 : 1),
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* ECharts 柱/线渐变样式
|
||||
*/
|
||||
protected function orderChartBarStyle(string $startColor, string $endColor): array
|
||||
{
|
||||
return [
|
||||
'normal' => [
|
||||
'color' => [
|
||||
'x' => 0, 'y' => 0, 'x2' => 0, 'y2' => 1,
|
||||
'colorStops' => [
|
||||
['offset' => 0, 'color' => $startColor],
|
||||
['offset' => 1, 'color' => $endColor],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
></echarts-from>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xl="8" :lg="12" :md="24" :sm="24" :xs="24">
|
||||
<el-col :xl="8" :lg="12" :md="24" :sm="24" :xs="24" class="ivu-mb">
|
||||
<el-card :bordered="false" shadow="never" class="dashboard-console-visit">
|
||||
<div class="card-title">
|
||||
<el-avatar
|
||||
@ -31,6 +31,29 @@
|
||||
<echarts-from ref="visitChart" :infoList="infoList" :echartsTitle="circle"></echarts-from>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="24" class="ivu-mb">
|
||||
<el-card :bordered="false" shadow="never" class="dashboard-console-visit">
|
||||
<div class="card-title">
|
||||
<el-avatar
|
||||
icon="TrendCharts"
|
||||
style="color: var(--prev-color-primary); background-color: #e6f7ff"
|
||||
></el-avatar>
|
||||
<h4 class="ivu-pl-8">商品支付排行</h4>
|
||||
</div>
|
||||
<div class="trees-coadd">
|
||||
<div class="scollhide">
|
||||
<div v-if="lists.length" class="rank-list">
|
||||
<div v-for="(item, index) in lists" :key="item.product_id || index" class="rank-item">
|
||||
<span class="rank-index" :class="{ top: index < 3 }">{{ index + 1 }}</span>
|
||||
<span class="names" :title="item.store_name">{{ item.store_name }}</span>
|
||||
<span class="rank-val">¥{{ formatVal(item.val) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-empty v-else description="暂无排行数据" :image-size="64" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
@ -50,21 +73,21 @@ const line = 'line';
|
||||
const circle = 'circle';
|
||||
const infoList = ref({});
|
||||
const series = ref([]);
|
||||
const xData = ref([]);
|
||||
const y1Data = ref([]);
|
||||
const y2Data = ref([]);
|
||||
const lists = ref([]);
|
||||
const bing_data = ref([]);
|
||||
const bing_xdata = ref([]);
|
||||
|
||||
function formatVal(val) {
|
||||
const num = Number(val || 0);
|
||||
return Number.isFinite(num) ? num.toFixed(2) : '0.00';
|
||||
}
|
||||
|
||||
// 统计
|
||||
function getStatistics() {
|
||||
userApi()
|
||||
.then(async (res) => {
|
||||
infoList.value = res.data;
|
||||
infoList.value = res.data || {};
|
||||
series.value = [
|
||||
{
|
||||
data: res.data.series,
|
||||
data: infoList.value.series || [],
|
||||
name: '人数(人)',
|
||||
type: 'line',
|
||||
tooltip: true,
|
||||
@ -77,8 +100,6 @@ function getStatistics() {
|
||||
},
|
||||
},
|
||||
];
|
||||
bing_data.value = res.bing_data;
|
||||
bing_xdata.value = res.bing_xdata;
|
||||
})
|
||||
.catch((res) => {
|
||||
ElMessage.error(res.msg);
|
||||
@ -87,8 +108,7 @@ function getStatistics() {
|
||||
function getRank() {
|
||||
rankApi()
|
||||
.then(async (res) => {
|
||||
let data = res.data;
|
||||
lists.value = data.list;
|
||||
lists.value = res.data?.list || [];
|
||||
})
|
||||
.catch((res) => {
|
||||
ElMessage.error(res.msg);
|
||||
@ -120,21 +140,55 @@ onMounted(() => {
|
||||
height: 100%;
|
||||
.scollhide {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 320px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
.scollhide::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 4px;
|
||||
}
|
||||
.rank-list {
|
||||
padding: 8px 0 4px;
|
||||
}
|
||||
.rank-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 4px;
|
||||
border-bottom: 1px solid var(--prev-border-color-lighter, #f0f2f5);
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
.rank-index {
|
||||
flex: none;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin-right: 10px;
|
||||
border-radius: 50%;
|
||||
background: var(--prev-bg-color-page, #f5f7fa);
|
||||
color: var(--prev-color-text-secondary, #909399);
|
||||
font-size: 12px;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
&.top {
|
||||
background: var(--prev-color-primary);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.names {
|
||||
display: inline-block;
|
||||
text-overflow: ellipsis;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 84%;
|
||||
margin-bottom: -7px;
|
||||
color: var(--prev-color-text-regular);
|
||||
}
|
||||
.rank-val {
|
||||
flex: none;
|
||||
margin-left: 12px;
|
||||
color: var(--prev-color-text-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
.card-title {
|
||||
display: flex;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user