<template>
|
<div class="app-container">
|
<el-form :model="filters" :inline="true">
|
<el-form-item label="申请单号:">
|
<el-input v-model="filters.applyCode" placeholder="请输入申请单号" clearable style="width: 200px;" />
|
</el-form-item>
|
<el-form-item label="客户:">
|
<el-select v-model="filters.customerId" placeholder="请选择客户" clearable style="width: 200px;">
|
<el-option v-for="item in customerList" :key="item.id" :label="item.customerName" :value="item.id" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="审核状态:">
|
<el-select v-model="filters.status" placeholder="请选择审核状态" clearable style="width: 150px;">
|
<el-option label="待审核" :value="0" />
|
<el-option label="审核通过" :value="1" />
|
<el-option label="审核不通过" :value="2" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="申请日期:">
|
<el-date-picker
|
v-model="filters.dateRange"
|
type="daterange"
|
value-format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
range-separator="至"
|
start-placeholder="开始日期"
|
end-placeholder="结束日期"
|
clearable
|
style="width: 240px;"
|
/>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="onSearch">搜索</el-button>
|
<el-button @click="resetFilters">重置</el-button>
|
</el-form-item>
|
</el-form>
|
<div class="table_list">
|
<div class="actions">
|
<div></div>
|
<div>
|
<el-button type="primary" @click="add" icon="Plus">新增申请</el-button>
|
<el-button type="success" @click="handleExport" icon="Download">导出开票申请</el-button>
|
</div>
|
</div>
|
<PIMTable
|
rowKey="id"
|
isSelection
|
v-loading="tableLoading"
|
:column="columns"
|
:tableData="dataList"
|
:page="{
|
current: pagination.currentPage,
|
size: pagination.pageSize,
|
total: pagination.total,
|
}"
|
@selection-change="handleSelectionChange"
|
@pagination="changePage"
|
>
|
<template #amount="{ row }">
|
<span class="text-primary">¥{{ formatMoney(row.amount) }}</span>
|
</template>
|
<template #taxRate="{ row }">
|
<span>{{ row.taxRate }}%</span>
|
</template>
|
<template #status="{ row }">
|
<el-tag :type="getStatusType(row.status)" effect="light" round>
|
{{ getStatusLabel(row.status) }}
|
</el-tag>
|
</template>
|
<template #operation="{ row }">
|
<el-button type="primary" link @click="view(row)">查看</el-button>
|
<el-button type="primary" link @click="edit(row)" v-if="isPendingStatus(row.status)">编辑</el-button>
|
<el-button type="danger" link @click="handleDelete(row)" v-if="isPendingStatus(row.status)">删除</el-button>
|
<el-button type="success" link @click="handleAudit(row)" v-if="isPendingStatus(row.status)">审核</el-button>
|
<!-- <el-button type="warning" link @click="handleInvoice(row)" v-if="isApprovedStatus(row.status)">开票</el-button> -->
|
</template>
|
</PIMTable>
|
</div>
|
|
<FormDialog
|
:title="dialogTitle"
|
v-model="dialogVisible"
|
width="800px"
|
:operation-type="isView ? 'detail' : ''"
|
@confirm="submitForm"
|
@cancel="closeDialog"
|
>
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
|
<el-row v-if="isView" :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="审核状态">
|
<el-tag :type="getStatusType(form.status)" effect="light" round>
|
{{ getStatusLabel(form.status) }}
|
</el-tag>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="20">
|
<el-col :span="24">
|
<el-form-item label="申请单号" prop="applyCode">
|
<el-input v-model="form.applyCode" placeholder="系统自动生成" disabled />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="客户" prop="customerId">
|
<el-select
|
v-model="form.customerId"
|
placeholder="请选择客户"
|
style="width: 100%;"
|
:disabled="isEdit || isView"
|
filterable
|
@change="handleCustomerChange"
|
>
|
<el-option v-for="item in customerList" :key="item.id" :label="item.customerName" :value="item.id" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="出库单号" prop="outboundBatchNos">
|
<el-select
|
v-model="form.outboundBatchNos"
|
multiple
|
collapse-tags
|
collapse-tags-tooltip
|
filterable
|
placeholder="请先选择客户"
|
style="width: 100%;"
|
:disabled="!form.customerId || isView"
|
:loading="outboundBatchLoading"
|
@change="handleOutboundBatchChange"
|
>
|
<el-option
|
v-for="item in outboundBatchOptions"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="开票金额" prop="amount">
|
<el-input-number
|
v-model="form.amount"
|
:min="0"
|
:precision="2"
|
:disabled="isView"
|
style="width: 100%;"
|
placeholder="根据所选出库单自动汇总,可修改"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="税率" prop="taxRate">
|
<el-select v-model="form.taxRate" placeholder="请选择税率" style="width: 100%;" :disabled="isView">
|
<el-option
|
v-for="dict in tax_rate"
|
:key="dict.value"
|
:label="dict.label"
|
:value="Number(dict.value)"
|
/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="发票类型" prop="invoiceType">
|
<el-select v-model="form.invoiceType" placeholder="请选择发票类型" style="width: 100%;" :disabled="isView">
|
<el-option label="增值税专用发票" value="special" />
|
<el-option label="增值税普通发票" value="normal" />
|
<el-option label="电子发票" value="electronic" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="申请日期" prop="applyDate">
|
<el-date-picker
|
v-model="form.applyDate"
|
type="date"
|
placeholder="选择日期"
|
value-format="YYYY-MM-DD"
|
style="width: 100%;"
|
:disabled="isView"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-form-item label="发票内容" prop="content">
|
<el-input v-model="form.content" type="textarea" :rows="3" placeholder="请输入发票内容" :disabled="isView" />
|
</el-form-item>
|
<el-form-item label="备注" prop="remark">
|
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" :disabled="isView" />
|
</el-form-item>
|
</el-form>
|
<template v-if="!isView" #footer>
|
<el-button type="primary" :loading="submitLoading" @click="submitForm">确定</el-button>
|
<el-button @click="closeDialog">取消</el-button>
|
</template>
|
</FormDialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted, getCurrentInstance } from "vue";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
import FormDialog from "@/components/Dialog/FormDialog.vue";
|
import { listCustomer } from "@/api/basicData/customer.js";
|
import {
|
getOutboundBatchesByCustomer,
|
addAccountInvoiceApplication,
|
listPageAccountInvoiceApplication,
|
auditAccountInvoiceApplication,
|
updateAccountInvoiceApplication,
|
deleteAccountInvoiceApplication,
|
} from "@/api/financialManagement/invoiceApply.js";
|
|
defineOptions({
|
name: "开票申请",
|
});
|
|
const { proxy } = getCurrentInstance();
|
const { tax_rate } = proxy.useDict("tax_rate");
|
|
const filters = reactive({
|
applyCode: "",
|
customerId: "",
|
status: "",
|
dateRange: [],
|
});
|
|
const pagination = reactive({
|
currentPage: 1,
|
pageSize: 10,
|
total: 0,
|
});
|
|
const columns = [
|
{ label: "申请单号", prop: "applyCode", width: "150" },
|
{ label: "客户名称", prop: "customerName", width: "180" },
|
{ label: "开票金额", prop: "amount", dataType: "slot", slot: "amount" },
|
{ label: "税率", prop: "taxRate", dataType: "slot", slot: "taxRate" },
|
{ label: "发票类型", prop: "invoiceTypeLabel", width: "130" },
|
{ label: "申请日期", prop: "applyDate", width: "120" },
|
{ label: "审核状态", prop: "status", dataType: "slot", slot: "status", width: "110", align: "center" },
|
{ label: "操作", prop: "operation", dataType: "slot", slot: "operation", width: "260", fixed: "right" },
|
];
|
|
const dataList = ref([]);
|
const tableLoading = ref(false);
|
const selectedRows = ref([]);
|
const dialogVisible = ref(false);
|
const dialogTitle = ref("");
|
const formRef = ref(null);
|
const isEdit = ref(false);
|
const isView = ref(false);
|
const currentId = ref(null);
|
|
const closeDialog = () => {
|
dialogVisible.value = false;
|
isView.value = false;
|
isEdit.value = false;
|
};
|
|
const customerList = ref([]);
|
const outboundBatchOptions = ref([]);
|
const outboundBatchLoading = ref(false);
|
|
const getCustomerList = () => {
|
listCustomer({ current: -1, size: -1, type: 0 }).then((res) => {
|
if (res.code === 200) {
|
customerList.value = res.data?.records || [];
|
}
|
});
|
};
|
|
const normalizeOutboundBatchOptions = (data) => {
|
const list = Array.isArray(data) ? data : [];
|
return list.map((item, index) => {
|
if (typeof item === "string" || typeof item === "number") {
|
const text = String(item);
|
return { label: text, value: text, outboundAmount: 0 };
|
}
|
const label =
|
item.outboundBatches ??
|
item.batchNo ??
|
item.shippingNo ??
|
item.outboundNo ??
|
item.label ??
|
`出库单${index + 1}`;
|
const value = item.id ?? item.stockOutRecordId ?? item.stockOutRecordIds ?? label;
|
const outboundAmount = Number(item.outboundAmount) || 0;
|
const taxRate =
|
item.taxRate !== undefined && item.taxRate !== null && item.taxRate !== ""
|
? Number(item.taxRate)
|
: undefined;
|
return { label: String(label), value, outboundAmount, taxRate };
|
});
|
};
|
|
const getSelectedOutboundOptions = () => {
|
const selected = form.outboundBatchNos || [];
|
return outboundBatchOptions.value.filter((opt) => selected.includes(opt.value));
|
};
|
|
/** 校验所选出库单税率是否一致,一致则回填 form.taxRate */
|
const checkTaxRateConsistency = (showMessage = true) => {
|
const selected = getSelectedOutboundOptions();
|
if (selected.length === 0) return true;
|
|
const withTaxRate = selected.filter(
|
(opt) => opt.taxRate !== undefined && opt.taxRate !== null && !Number.isNaN(opt.taxRate)
|
);
|
if (withTaxRate.length === 0) return true;
|
|
const uniqueRates = [...new Set(withTaxRate.map((opt) => Number(opt.taxRate)))];
|
if (uniqueRates.length > 1) {
|
if (showMessage) {
|
const detail = withTaxRate.map((opt) => `${opt.label}(${opt.taxRate}%)`).join("、");
|
ElMessage.error(`所选出库单税率不一致,无法开票:${detail}`);
|
}
|
return false;
|
}
|
|
form.taxRate = uniqueRates[0];
|
return true;
|
};
|
|
/** 根据所选出库单汇总 outboundAmount 作为开票金额 */
|
const syncInvoiceAmount = () => {
|
const selected = form.outboundBatchNos || [];
|
const sum = outboundBatchOptions.value
|
.filter((opt) => selected.includes(opt.value))
|
.reduce((acc, opt) => acc + (Number(opt.outboundAmount) || 0), 0);
|
form.amount = sum > 0 ? Number(sum.toFixed(2)) : 0;
|
};
|
|
const handleOutboundBatchChange = () => {
|
syncInvoiceAmount();
|
checkTaxRateConsistency();
|
};
|
|
const loadOutboundBatches = (customerId, keepSelected = false) => {
|
if (!customerId) {
|
outboundBatchOptions.value = [];
|
if (!keepSelected) {
|
form.outboundBatchNos = [];
|
form.amount = 0;
|
}
|
return Promise.resolve();
|
}
|
outboundBatchLoading.value = true;
|
return getOutboundBatchesByCustomer({ customerId })
|
.then((res) => {
|
if (res.code === 200) {
|
const list = res.data?.records ?? res.data ?? [];
|
outboundBatchOptions.value = normalizeOutboundBatchOptions(list);
|
} else {
|
outboundBatchOptions.value = [];
|
}
|
})
|
.catch(() => {
|
outboundBatchOptions.value = [];
|
})
|
.finally(() => {
|
outboundBatchLoading.value = false;
|
if (keepSelected) {
|
syncInvoiceAmount();
|
checkTaxRateConsistency(false);
|
}
|
});
|
};
|
|
const handleCustomerChange = (customerId) => {
|
form.outboundBatchNos = [];
|
form.amount = 0;
|
loadOutboundBatches(customerId);
|
};
|
|
const form = reactive({
|
applyCode: "",
|
customerId: "",
|
outboundBatchNos: [],
|
amount: 0,
|
taxRate: 13,
|
invoiceType: "special",
|
applyDate: "",
|
content: "",
|
remark: "",
|
});
|
|
const rules = {
|
customerId: [{ required: true, message: "请选择客户", trigger: "change" }],
|
outboundBatchNos: [{ required: true, type: "array", min: 1, message: "请选择出库单号", trigger: "change" }],
|
amount: [{ required: true, message: "请输入开票金额", trigger: "blur" }],
|
taxRate: [{ required: true, message: "请选择税率", trigger: "change" }],
|
invoiceType: [{ required: true, message: "请选择发票类型", trigger: "change" }],
|
applyDate: [{ required: true, message: "请选择申请日期", trigger: "change" }],
|
};
|
|
const INVOICE_TYPE_LABEL_MAP = {
|
special: "增值税专用发票",
|
normal: "增值税普通发票",
|
electronic: "电子发票",
|
};
|
|
/** 审核状态:0待审核 1审核通过 2审核不通过 */
|
const STATUS_LABEL_MAP = {
|
0: "待审核",
|
1: "审核通过",
|
2: "审核不通过",
|
};
|
|
const STATUS_TYPE_MAP = {
|
0: "warning",
|
1: "success",
|
2: "danger",
|
};
|
|
const getInvoiceTypeLabel = (type) => INVOICE_TYPE_LABEL_MAP[type] || type || "";
|
|
const normalizeStatus = (status) => {
|
if (status === undefined || status === null || status === "") return status;
|
const num = Number(status);
|
return Number.isNaN(num) ? status : num;
|
};
|
|
const isPendingStatus = (status) => normalizeStatus(status) === 0;
|
const isApprovedStatus = (status) => normalizeStatus(status) === 1;
|
|
const normalizeTableRow = (row) => ({
|
...row,
|
applyCode: row.invoiceApplicationNo ?? row.applyCode,
|
amount: row.invoiceAmount ?? row.amount,
|
content: row.invoiceContent ?? row.content,
|
status: normalizeStatus(row.status ?? row.auditStatus),
|
invoiceTypeLabel: row.invoiceTypeLabel || getInvoiceTypeLabel(row.invoiceType),
|
});
|
|
const appendFilterParams = (params) => {
|
if (filters.applyCode) {
|
params.invoiceApplicationNo = filters.applyCode;
|
}
|
if (filters.customerId) {
|
params.customerId = filters.customerId;
|
}
|
if (filters.status !== "" && filters.status != null) {
|
params.status = filters.status;
|
}
|
if (filters.dateRange?.length === 2) {
|
params.startDate = filters.dateRange[0];
|
params.endDate = filters.dateRange[1];
|
}
|
return params;
|
};
|
|
const buildListParams = () => {
|
return appendFilterParams({
|
current: pagination.currentPage,
|
size: pagination.pageSize,
|
});
|
};
|
|
const buildExportParams = () => {
|
const params = appendFilterParams({});
|
if (selectedRows.value.length > 0) {
|
params.ids = selectedRows.value.map((row) => row.id).join(",");
|
}
|
return params;
|
};
|
|
const handleExport = () => {
|
const params = buildExportParams();
|
const filename =
|
selectedRows.value.length > 0
|
? `开票申请_已选${selectedRows.value.length}条_${Date.now()}.xlsx`
|
: `开票申请_${Date.now()}.xlsx`;
|
proxy.download("/accountInvoiceApplication/exportAccountInvoiceApplication", params, filename);
|
};
|
|
const formatMoney = (value) => {
|
if (value === undefined || value === null) return "0.00";
|
return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
};
|
|
const getStatusLabel = (status) => {
|
const num = normalizeStatus(status);
|
if (num === 0 || num === 1 || num === 2) {
|
return STATUS_LABEL_MAP[num];
|
}
|
return "-";
|
};
|
|
const getStatusType = (status) => {
|
const num = normalizeStatus(status);
|
if (num === 0 || num === 1 || num === 2) {
|
return STATUS_TYPE_MAP[num];
|
}
|
return "info";
|
};
|
|
const onSearch = () => {
|
pagination.currentPage = 1;
|
getTableData();
|
};
|
|
const getTableData = () => {
|
tableLoading.value = true;
|
listPageAccountInvoiceApplication(buildListParams())
|
.then((res) => {
|
const ok = res.code === 200 || res.code === 0;
|
if (ok && res.data) {
|
pagination.total = res.data.total ?? 0;
|
dataList.value = (res.data.records ?? []).map(normalizeTableRow);
|
} else {
|
ElMessage.error(res.msg || "查询失败");
|
dataList.value = [];
|
pagination.total = 0;
|
}
|
})
|
.catch(() => {
|
dataList.value = [];
|
pagination.total = 0;
|
})
|
.finally(() => {
|
tableLoading.value = false;
|
});
|
};
|
|
const resetFilters = () => {
|
filters.applyCode = "";
|
filters.customerId = "";
|
filters.status = "";
|
filters.dateRange = [];
|
pagination.currentPage = 1;
|
getTableData();
|
};
|
|
const changePage = ({ current, size }) => {
|
pagination.currentPage = current;
|
pagination.pageSize = size;
|
getTableData();
|
};
|
|
const handleSelectionChange = (selection) => {
|
selectedRows.value = selection;
|
};
|
|
const fillFormFromRow = (row) => {
|
const outboundBatchNos = Array.isArray(row.outboundBatchNos)
|
? row.outboundBatchNos
|
: parseStockOutRecordIds(row.stockOutRecordIds ?? row.outboundBatches);
|
Object.assign(form, {
|
...row,
|
applyCode: row.applyCode ?? row.invoiceApplicationNo ?? "",
|
amount: row.amount ?? row.invoiceAmount,
|
content: row.content ?? row.invoiceContent,
|
status: normalizeStatus(row.status ?? row.auditStatus),
|
outboundBatchNos,
|
});
|
};
|
|
const add = () => {
|
isEdit.value = false;
|
isView.value = false;
|
dialogTitle.value = "新增开票申请";
|
Object.assign(form, {
|
applyCode: "KP" + Date.now().toString().slice(-8),
|
customerId: "",
|
outboundBatchNos: [],
|
amount: 0,
|
taxRate: 13,
|
invoiceType: "special",
|
applyDate: new Date().toISOString().split('T')[0],
|
content: "",
|
remark: "",
|
});
|
outboundBatchOptions.value = [];
|
dialogVisible.value = true;
|
};
|
|
const parseStockOutRecordIds = (value) => {
|
if (!value) return [];
|
if (Array.isArray(value)) return value;
|
return String(value)
|
.split(/[,,]/)
|
.map((s) => s.trim())
|
.filter(Boolean)
|
.map((s) => (/^\d+$/.test(s) ? Number(s) : s));
|
};
|
|
const buildSubmitPayload = (forUpdate = false) => {
|
const payload = {
|
customerId: form.customerId,
|
stockOutRecordIds: (form.outboundBatchNos || []).join(","),
|
invoiceApplicationNo: form.applyCode || "",
|
invoiceType: form.invoiceType,
|
applyDate: form.applyDate,
|
invoiceContent: form.content,
|
remark: form.remark || "",
|
invoiceAmount: form.amount,
|
taxRate: form.taxRate,
|
status: 0,
|
};
|
if (forUpdate) {
|
payload.id = currentId.value;
|
}
|
return payload;
|
};
|
|
const edit = (row) => {
|
isEdit.value = true;
|
isView.value = false;
|
currentId.value = row.id;
|
dialogTitle.value = "编辑开票申请";
|
fillFormFromRow(row);
|
dialogVisible.value = true;
|
loadOutboundBatches(form.customerId, true);
|
};
|
|
const view = (row) => {
|
isView.value = true;
|
isEdit.value = false;
|
dialogTitle.value = "查看开票申请";
|
fillFormFromRow(row);
|
dialogVisible.value = true;
|
loadOutboundBatches(form.customerId, true);
|
};
|
|
const submitAudit = (row, status) => {
|
auditAccountInvoiceApplication({ id: row.id, status })
|
.then((res) => {
|
if (res.code === 200) {
|
ElMessage.success(status === 1 ? "审核通过" : "审核不通过");
|
getTableData();
|
} else {
|
ElMessage.error(res.msg || "审批失败");
|
}
|
})
|
.catch(() => {
|
ElMessage.error("审批失败");
|
});
|
};
|
|
const handleDelete = (row) => {
|
ElMessageBox.confirm(`确认删除申请单「${row.applyCode ?? row.invoiceApplicationNo}」吗?`, "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
}).then(() => {
|
deleteAccountInvoiceApplication([row.id])
|
.then((res) => {
|
if (res.code === 200) {
|
ElMessage.success("删除成功");
|
getTableData();
|
} else {
|
ElMessage.error(res.msg || "删除失败");
|
}
|
})
|
.catch(() => {
|
ElMessage.error("删除失败");
|
});
|
});
|
};
|
|
const handleAudit = (row) => {
|
ElMessageBox.confirm("请选择审批结果", "开票申请审核", {
|
confirmButtonText: "审核通过",
|
cancelButtonText: "审核不通过",
|
distinguishCancelAndClose: true,
|
type: "warning",
|
})
|
.then(() => {
|
submitAudit(row, 1);
|
})
|
.catch((action) => {
|
if (action === "cancel") {
|
submitAudit(row, 2);
|
}
|
});
|
};
|
|
const handleInvoice = (row) => {
|
ElMessageBox.confirm("确认已开具发票?", "提示", {
|
confirmButtonText: "确认",
|
cancelButtonText: "取消",
|
type: "info",
|
}).then(() => {
|
ElMessage.success("开票完成");
|
getTableData();
|
});
|
};
|
|
const handleBatchApply = () => {
|
ElMessage.success(`批量申请 ${selectedRows.value.length} 条记录`);
|
};
|
|
const submitLoading = ref(false);
|
|
const submitForm = () => {
|
formRef.value.validate((valid) => {
|
if (!valid) return;
|
if (!checkTaxRateConsistency()) return;
|
|
submitLoading.value = true;
|
const request = isEdit.value
|
? updateAccountInvoiceApplication(buildSubmitPayload(true))
|
: addAccountInvoiceApplication(buildSubmitPayload());
|
|
request
|
.then((res) => {
|
if (res.code === 200) {
|
ElMessage.success(isEdit.value ? "修改成功" : "新增成功");
|
closeDialog();
|
getTableData();
|
} else {
|
ElMessage.error(res.msg || (isEdit.value ? "修改失败" : "新增失败"));
|
}
|
})
|
.catch(() => {
|
ElMessage.error(isEdit.value ? "修改失败" : "新增失败");
|
})
|
.finally(() => {
|
submitLoading.value = false;
|
});
|
});
|
};
|
|
onMounted(() => {
|
getCustomerList();
|
getTableData();
|
});
|
</script>
|
|
<style lang="scss" scoped>
|
.actions {
|
display: flex;
|
justify-content: space-between;
|
margin-bottom: 15px;
|
}
|
|
.text-primary {
|
color: #409eff;
|
font-weight: bold;
|
}
|
</style>
|