feat 财务中心
This commit is contained in:
@@ -284,3 +284,5 @@
|
||||
@finance-entry-export-bg: #e6f6ec;
|
||||
@finance-entry-badge-bg: #f53f3f;
|
||||
@finance-chart-switch-active: #024fff;
|
||||
@finance-switch-active-bg: #e8f0ff;
|
||||
@finance-switch-idle-bg: #f2f4f7;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { ElRadioGroup, ElRadioButton } from 'element-plus'
|
||||
import { ElButton } from 'element-plus'
|
||||
|
||||
interface DistributionItem {
|
||||
name: string
|
||||
@@ -31,9 +31,23 @@ const AXIS = [250, 200, 150, 100, 50]
|
||||
const AXIS_MAX = AXIS[0]
|
||||
const MONTHS = ['1月', '2月', '3月', '4月', '5月']
|
||||
|
||||
interface PeriodOption {
|
||||
label: string
|
||||
value: 'month' | 'half'
|
||||
}
|
||||
|
||||
// 设计稿 #20 右上角切换:月度账单(激活)/ 上半
|
||||
const PERIODS: PeriodOption[] = [
|
||||
{ label: '月度账单', value: 'month' },
|
||||
{ label: '上半', value: 'half' },
|
||||
]
|
||||
|
||||
const period = ref<'month' | 'half'>('month')
|
||||
|
||||
function onPeriodChange(value: 'month' | 'half'): void {
|
||||
period.value = value
|
||||
}
|
||||
|
||||
// 柱高按 Y 轴量程绝对值换算(设计稿 #20:Y 轴 250 为满量程),非占比
|
||||
function heightPercentOf(value: number): number {
|
||||
if (value <= 0) return 0
|
||||
@@ -47,14 +61,17 @@ function heightPercentOf(value: number): number {
|
||||
业务类型分布
|
||||
</h3>
|
||||
|
||||
<el-radio-group v-model="period" class="finance-chart__switch">
|
||||
<el-radio-button value="month">
|
||||
月度账单
|
||||
</el-radio-button>
|
||||
<el-radio-button value="half">
|
||||
上半
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="finance-chart__switch">
|
||||
<el-button
|
||||
v-for="item in PERIODS"
|
||||
:key="item.value"
|
||||
class="finance-chart__switch-btn"
|
||||
:class="{ 'is-active': period === item.value }"
|
||||
@click="onPeriodChange(item.value)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div class="finance-chart__body">
|
||||
<ul class="finance-chart__axis" aria-hidden="true">
|
||||
@@ -136,30 +153,38 @@ function heightPercentOf(value: number): number {
|
||||
}
|
||||
|
||||
&__switch {
|
||||
.flex(row, flex-end, center);
|
||||
gap: 8px;
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
right: 23px;
|
||||
|
||||
:deep(.el-radio-button__inner) {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
line-height: 15px;
|
||||
color: @finance-muted-text;
|
||||
transition: color 0.2s;
|
||||
:deep(.el-button + .el-button) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-radio-button.is-active .el-radio-button__inner) {
|
||||
background: transparent;
|
||||
&__switch-btn {
|
||||
height: 24px;
|
||||
margin-left: 0;
|
||||
padding: 0 12px;
|
||||
border: none;
|
||||
border-radius: @radius-round;
|
||||
background: @finance-switch-idle-bg;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
color: @finance-muted-text;
|
||||
transition: color 0.2s, background 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: @finance-switch-idle-bg;
|
||||
color: @finance-chart-switch-active;
|
||||
}
|
||||
|
||||
:deep(.el-radio-button + .el-radio-button) {
|
||||
margin-left: 14px;
|
||||
&.is-active {
|
||||
background: @finance-switch-active-bg;
|
||||
color: @finance-chart-switch-active;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { RouterLink } from 'vue-router'
|
||||
import { ElMessage, ElButton, ElRadioGroup, ElRadioButton, ElTable, ElTableColumn } from 'element-plus'
|
||||
import { ElMessage, ElButton, ElTable, ElTableColumn } from 'element-plus'
|
||||
import { FilterPanel, PaginationBar, StatusTag } from '@/components'
|
||||
import { useFinanceStore } from '@/stores/modules/finance'
|
||||
import type { Invoice, InvoiceStatus } from '@/types/business/finance'
|
||||
@@ -36,10 +36,6 @@ function onTab(value: InvoiceStatus | 'all'): void {
|
||||
void financeStore.searchInvoices()
|
||||
}
|
||||
|
||||
function onTabChange(val: string | number | boolean | undefined): void {
|
||||
onTab(val as InvoiceStatus | 'all')
|
||||
}
|
||||
|
||||
function onSearch(): void {
|
||||
financeStore.setInvoiceQuery({ ...invoiceQuery.value, keyword: keyword.value })
|
||||
void financeStore.searchInvoices()
|
||||
@@ -112,19 +108,17 @@ onMounted(() => {
|
||||
</RouterLink>
|
||||
</section>
|
||||
|
||||
<el-radio-group
|
||||
class="invoices__tabs"
|
||||
:model-value="invoiceQuery.status"
|
||||
@change="onTabChange"
|
||||
>
|
||||
<el-radio-button
|
||||
<div class="invoices__tabs">
|
||||
<el-button
|
||||
v-for="tab in STATUS_TABS"
|
||||
:key="tab.value"
|
||||
:value="tab.value"
|
||||
class="invoices__tab"
|
||||
:class="{ 'is-active': invoiceQuery.status === tab.value }"
|
||||
@click="onTab(tab.value)"
|
||||
>
|
||||
{{ tab.label }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<FilterPanel
|
||||
v-model:keyword="keyword"
|
||||
@@ -326,26 +320,40 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
&__tabs {
|
||||
:deep(.el-radio-button__inner) {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
gap: @spacing-sm;
|
||||
}
|
||||
|
||||
&__tab {
|
||||
height: 34px;
|
||||
margin: 0;
|
||||
padding: 0 @spacing-base;
|
||||
border: 1px solid @border-color;
|
||||
border-radius: @radius-base;
|
||||
background: @white;
|
||||
color: @text-color;
|
||||
font-size: @font-size-base;
|
||||
box-shadow: none;
|
||||
font-weight: 400;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
border-color: @primary-color;
|
||||
background: @white;
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
:deep(.el-radio-button + .el-radio-button) {
|
||||
margin-left: @spacing-sm;
|
||||
}
|
||||
|
||||
:deep(.el-radio-button.is-active .el-radio-button__inner) {
|
||||
&.is-active {
|
||||
border-color: @primary-color;
|
||||
background: @primary-color;
|
||||
color: @white;
|
||||
box-shadow: -1px 0 0 0 @primary-color;
|
||||
|
||||
&:hover {
|
||||
border-color: @primary-color;
|
||||
background: @primary-color;
|
||||
color: @white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user