feat 合同中心
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { RouterLink } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { ElMessage, ElButton, ElRadioGroup, ElRadioButton, 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,6 +36,10 @@ 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()
|
||||
@@ -69,13 +73,8 @@ function onSendEmail(): void {
|
||||
ElMessage.success('发票已发送至绑定邮箱(演示)')
|
||||
}
|
||||
|
||||
function onToggleSelect(id: string): void {
|
||||
if (selectedIds.value.includes(id)) {
|
||||
selectedIds.value = selectedIds.value.filter((item) => item !== id)
|
||||
}
|
||||
else {
|
||||
selectedIds.value = [...selectedIds.value, id]
|
||||
}
|
||||
function onSelectionChange(rows: Invoice[]): void {
|
||||
selectedIds.value = rows.map((row) => row.id)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@@ -113,17 +112,19 @@ onMounted(() => {
|
||||
</RouterLink>
|
||||
</section>
|
||||
|
||||
<div class="invoices__tabs">
|
||||
<button
|
||||
<el-radio-group
|
||||
class="invoices__tabs"
|
||||
:model-value="invoiceQuery.status"
|
||||
@change="onTabChange"
|
||||
>
|
||||
<el-radio-button
|
||||
v-for="tab in STATUS_TABS"
|
||||
:key="tab.value"
|
||||
class="invoices__tab"
|
||||
:class="{ 'is-active': invoiceQuery.status === tab.value }"
|
||||
@click="onTab(tab.value)"
|
||||
:value="tab.value"
|
||||
>
|
||||
{{ tab.label }}
|
||||
</button>
|
||||
</div>
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
|
||||
<FilterPanel
|
||||
v-model:keyword="keyword"
|
||||
@@ -133,67 +134,121 @@ onMounted(() => {
|
||||
/>
|
||||
|
||||
<div class="invoices__table card">
|
||||
<table class="invoices__table-el">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="invoices__check">
|
||||
多选
|
||||
</th>
|
||||
<th>序号</th>
|
||||
<th>账单名称</th>
|
||||
<th>账单号</th>
|
||||
<th>交易流水号</th>
|
||||
<th>项目名称</th>
|
||||
<th>订单金额</th>
|
||||
<th>状态</th>
|
||||
<th>申请时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(invoice, index) in invoices" :key="invoice.id">
|
||||
<td class="invoices__check">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="selectedIds.includes(invoice.id)"
|
||||
@change="onToggleSelect(invoice.id)"
|
||||
>
|
||||
</td>
|
||||
<td>{{ index + 1 }}</td>
|
||||
<td>{{ invoice.planName }}</td>
|
||||
<td>{{ invoice.billNo }}</td>
|
||||
<td>{{ invoice.tradeNo ?? '—' }}</td>
|
||||
<td>{{ invoice.projectName }}</td>
|
||||
<td class="invoices__amount">¥{{ formatMoney(invoice.amount) }}</td>
|
||||
<td>
|
||||
<StatusTag :label="invoice.status" :variant="STATUS_VARIANTS[invoice.status]" />
|
||||
</td>
|
||||
<td>{{ invoice.applyTime }}</td>
|
||||
<td class="invoices__ops">
|
||||
<template v-if="invoice.status === '已开票'">
|
||||
<button class="invoices__link" @click="onPreview">
|
||||
<el-table
|
||||
class="invoices__table-el"
|
||||
:data="invoices"
|
||||
row-key="id"
|
||||
@selection-change="onSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
type="selection"
|
||||
width="48"
|
||||
/>
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="序号"
|
||||
width="60"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="planName"
|
||||
label="账单名称"
|
||||
min-width="180"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="billNo"
|
||||
label="账单号"
|
||||
width="150"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="tradeNo"
|
||||
label="交易流水号"
|
||||
min-width="180"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="projectName"
|
||||
label="项目名称"
|
||||
min-width="160"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
label="订单金额"
|
||||
width="110"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span class="invoices__amount">¥{{ formatMoney((row as Invoice).amount) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="状态"
|
||||
width="90"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<StatusTag
|
||||
:label="(row as Invoice).status"
|
||||
:variant="STATUS_VARIANTS[(row as Invoice).status]"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="applyTime"
|
||||
label="申请时间"
|
||||
width="140"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="180"
|
||||
fixed="right"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span class="invoices__ops">
|
||||
<template v-if="(row as Invoice).status === '已开票'">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
class="invoices__link"
|
||||
@click="onPreview"
|
||||
>
|
||||
预览
|
||||
</button>
|
||||
<button class="invoices__link" @click="onDownload">
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
class="invoices__link"
|
||||
@click="onDownload"
|
||||
>
|
||||
下载
|
||||
</button>
|
||||
<button class="invoices__link" @click="onSendEmail">
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
class="invoices__link"
|
||||
@click="onSendEmail"
|
||||
>
|
||||
发送邮箱
|
||||
</button>
|
||||
</el-button>
|
||||
</template>
|
||||
<span v-else-if="invoice.status === '开票中'" class="invoices__dash">—</span>
|
||||
<button v-else class="invoices__link" @click="onApply(invoice)">
|
||||
<span v-else-if="(row as Invoice).status === '开票中'" class="invoices__dash">—</span>
|
||||
<el-button
|
||||
v-else
|
||||
link
|
||||
type="primary"
|
||||
class="invoices__link"
|
||||
@click="onApply(row as Invoice)"
|
||||
>
|
||||
申请开票
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="invoices.length === 0">
|
||||
<td colspan="10" class="invoices__empty text-secondary">
|
||||
暂无发票记录
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<template #empty>
|
||||
<span class="invoices__empty text-secondary">暂无发票记录</span>
|
||||
</template>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<PaginationBar
|
||||
@@ -271,29 +326,26 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
&__tabs {
|
||||
.flex(row, flex-start);
|
||||
gap: @spacing-sm;
|
||||
}
|
||||
|
||||
&__tab {
|
||||
height: 34px;
|
||||
padding: 0 @spacing-base;
|
||||
border: 1px solid @border-color;
|
||||
border-radius: @radius-base;
|
||||
background: @white;
|
||||
color: @text-color;
|
||||
font-size: @font-size-base;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
border-color: @primary-color;
|
||||
color: @primary-color;
|
||||
:deep(.el-radio-button__inner) {
|
||||
height: 34px;
|
||||
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;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
:deep(.el-radio-button + .el-radio-button) {
|
||||
margin-left: @spacing-sm;
|
||||
}
|
||||
|
||||
:deep(.el-radio-button.is-active .el-radio-button__inner) {
|
||||
border-color: @primary-color;
|
||||
background: @primary-color;
|
||||
color: @white;
|
||||
box-shadow: -1px 0 0 0 @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,32 +359,35 @@ onMounted(() => {
|
||||
|
||||
&__table-el {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: @font-size-base;
|
||||
color: @text-color;
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: @spacing-sm;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
:deep(th.el-table__cell) {
|
||||
background: @bg-color-light;
|
||||
border-bottom: 1px solid @border-color;
|
||||
}
|
||||
|
||||
th {
|
||||
background: @bg-color-light;
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-base;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
tbody tr:hover {
|
||||
:deep(td.el-table__cell) {
|
||||
padding: @spacing-sm 0;
|
||||
border-bottom: 1px solid @border-color;
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
|
||||
:deep(.el-table__body tr:hover > td.el-table__cell) {
|
||||
background: @bg-color-light;
|
||||
}
|
||||
}
|
||||
|
||||
&__check {
|
||||
width: 48px;
|
||||
text-align: center;
|
||||
:deep(.el-table .cell) {
|
||||
padding-left: @spacing-sm;
|
||||
padding-right: @spacing-sm;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
&__amount {
|
||||
@@ -341,17 +396,23 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
&__ops {
|
||||
.flex(row, flex-start);
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: @spacing-sm;
|
||||
}
|
||||
|
||||
&__link {
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: @primary-color;
|
||||
font-size: @font-size-base;
|
||||
transition: color 0.2s;
|
||||
|
||||
&:hover {
|
||||
color: @primary-hover;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user