<template>
|
<div class="app-container">
|
<el-form :model="filters" :inline="true">
|
<el-form-item label="会计科目:">
|
<el-cascader v-model="filters.subject" :options="subjectOptions" :props="{ label: 'name', value: 'code' }" placeholder="请选择会计科目" clearable style="width: 250px;" filterable />
|
</el-form-item>
|
<el-form-item label="辅助核算:">
|
<el-select v-model="filters.auxiliary" placeholder="请选择辅助核算" clearable style="width: 180px;">
|
<el-option label="客户" value="customer" />
|
<el-option label="供应商" value="supplier" />
|
<el-option label="部门" value="department" />
|
<el-option label="员工" value="employee" />
|
<el-option label="项目" value="project" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="核算对象:">
|
<el-select v-model="filters.auxiliaryItem" placeholder="请选择核算对象" clearable style="width: 200px;" :disabled="!filters.auxiliary">
|
<el-option v-for="item in auxiliaryItems" :key="item.value" :label="item.label" :value="item.value" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="期间:">
|
<el-date-picker v-model="filters.startMonth" type="month" placeholder="开始月份" value-format="YYYY-MM" style="width: 140px;" />
|
<span style="margin: 0 10px;">至</span>
|
<el-date-picker v-model="filters.endMonth" type="month" placeholder="结束月份" value-format="YYYY-MM" style="width: 140px;" />
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="getTableData">查询</el-button>
|
<el-button @click="resetFilters">重置</el-button>
|
<el-button @click="handlePrint" icon="Printer">打印</el-button>
|
<el-button @click="handleOut" icon="Download">导出</el-button>
|
</el-form-item>
|
</el-form>
|
|
<div class="ledger-header" v-if="currentSubject">
|
<h2>科目明细账</h2>
|
<p>科目: {{ currentSubject.code }} {{ currentSubject.name }}</p>
|
<p v-if="filters.auxiliary && filters.auxiliaryItem">辅助核算: {{ getAuxiliaryLabel() }}</p>
|
<p>期间: {{ filters.startMonth }} 至 {{ filters.endMonth }}</p>
|
</div>
|
|
<div class="table_list">
|
<el-table :data="dataList" border style="width: 100%" show-summary :summary-method="getSummaries">
|
<el-table-column prop="date" label="日期" width="120" />
|
<el-table-column prop="voucherNo" label="凭证字号" width="120" />
|
<el-table-column prop="summary" label="摘要" min-width="200" show-overflow-tooltip />
|
<el-table-column label="借方" width="150">
|
<template #default="{ row }">
|
<span v-if="row.debit > 0" class="text-danger">¥{{ formatMoney(row.debit) }}</span>
|
<span v-else>-</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="贷方" width="150">
|
<template #default="{ row }">
|
<span v-if="row.credit > 0" class="text-success">¥{{ formatMoney(row.credit) }}</span>
|
<span v-else>-</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="方向" width="80">
|
<template #default="{ row }">
|
<el-tag :type="row.direction === '借' ? 'success' : 'danger'" size="small">{{ row.direction }}</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="余额" width="150">
|
<template #default="{ row }">
|
<span :class="row.balance >= 0 ? 'text-primary' : 'text-warning'">¥{{ formatMoney(Math.abs(row.balance)) }}</span>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
|
<el-empty v-if="!currentSubject" description="请选择会计科目查询" style="margin-top: 50px;" />
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted, computed, watch } from "vue";
|
import { ElMessage } from "element-plus";
|
|
defineOptions({
|
name: "科目明细账",
|
});
|
|
const filters = reactive({
|
subject: [],
|
auxiliary: "",
|
auxiliaryItem: "",
|
startMonth: "2024-01",
|
endMonth: "2024-03",
|
});
|
|
const dataList = ref([]);
|
|
const subjectOptions = [
|
{
|
code: "1122",
|
name: "应收账款",
|
children: [
|
{ code: "112201", name: "北京科技有限公司" },
|
{ code: "112202", name: "上海贸易公司" },
|
{ code: "112203", name: "广州实业有限公司" },
|
],
|
},
|
{
|
code: "2202",
|
name: "应付账款",
|
children: [
|
{ code: "220201", name: "北京原材料供应商" },
|
{ code: "220202", name: "上海电子元器件公司" },
|
{ code: "220203", name: "广州包装材料厂" },
|
],
|
},
|
{
|
code: "6602",
|
name: "管理费用",
|
children: [
|
{ code: "660201", name: "办公费" },
|
{ code: "660202", name: "差旅费" },
|
{ code: "660203", name: "业务招待费" },
|
],
|
},
|
];
|
|
const auxiliaryItems = computed(() => {
|
const map = {
|
customer: [
|
{ value: "1", label: "北京科技有限公司" },
|
{ value: "2", label: "上海贸易公司" },
|
{ value: "3", label: "广州实业有限公司" },
|
],
|
supplier: [
|
{ value: "1", label: "北京原材料供应商" },
|
{ value: "2", label: "上海电子元器件公司" },
|
{ value: "3", label: "广州包装材料厂" },
|
],
|
department: [
|
{ value: "1", label: "财务部" },
|
{ value: "2", label: "销售部" },
|
{ value: "3", label: "采购部" },
|
],
|
employee: [
|
{ value: "1", label: "张三" },
|
{ value: "2", label: "李四" },
|
{ value: "3", label: "王五" },
|
],
|
project: [
|
{ value: "1", label: "项目A" },
|
{ value: "2", label: "项目B" },
|
{ value: "3", label: "项目C" },
|
],
|
};
|
return map[filters.auxiliary] || [];
|
});
|
|
watch(() => filters.auxiliary, () => {
|
filters.auxiliaryItem = "";
|
});
|
|
const currentSubject = computed(() => {
|
if (!filters.subject || filters.subject.length === 0) return null;
|
const code = filters.subject[filters.subject.length - 1];
|
return findSubject(subjectOptions, code);
|
});
|
|
const findSubject = (options, code) => {
|
for (const item of options) {
|
if (item.code === code) return item;
|
if (item.children && item.children.length > 0) {
|
const found = findSubject(item.children, code);
|
if (found) return found;
|
}
|
}
|
return null;
|
};
|
|
const getAuxiliaryLabel = () => {
|
const item = auxiliaryItems.value.find(i => i.value === filters.auxiliaryItem);
|
return item ? item.label : "";
|
};
|
|
const formatMoney = (value) => {
|
if (value === undefined || value === null) return "0.00";
|
return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
};
|
|
const mockData = [
|
{ date: "2024-01-01", voucherNo: "-", summary: "期初余额", debit: 0, credit: 0, direction: "借", balance: 10000 },
|
{ date: "2024-01-05", voucherNo: "记-0001", summary: "销售出库", debit: 5000, credit: 0, direction: "借", balance: 15000 },
|
{ date: "2024-01-10", voucherNo: "记-0002", summary: "收到货款", debit: 0, credit: 3000, direction: "借", balance: 12000 },
|
{ date: "2024-01-15", voucherNo: "记-0003", summary: "销售出库", debit: 8000, credit: 0, direction: "借", balance: 20000 },
|
{ date: "2024-01-20", voucherNo: "记-0004", summary: "销售退货", debit: 0, credit: 2000, direction: "借", balance: 18000 },
|
{ date: "2024-01-25", voucherNo: "记-0005", summary: "收到货款", debit: 0, credit: 5000, direction: "借", balance: 13000 },
|
{ date: "2024-01-31", voucherNo: "-", summary: "本月合计", debit: 13000, credit: 10000, direction: "借", balance: 13000 },
|
{ date: "2024-02-01", voucherNo: "-", summary: "期初余额", debit: 0, credit: 0, direction: "借", balance: 13000 },
|
{ date: "2024-02-10", voucherNo: "记-0006", summary: "销售出库", debit: 6000, credit: 0, direction: "借", balance: 19000 },
|
{ date: "2024-02-15", voucherNo: "记-0007", summary: "收到货款", debit: 0, credit: 4000, direction: "借", balance: 15000 },
|
{ date: "2024-02-28", voucherNo: "-", summary: "本月合计", debit: 6000, credit: 4000, direction: "借", balance: 15000 },
|
{ date: "2024-03-01", voucherNo: "-", summary: "期初余额", debit: 0, credit: 0, direction: "借", balance: 15000 },
|
{ date: "2024-03-05", voucherNo: "记-0008", summary: "销售出库", debit: 7000, credit: 0, direction: "借", balance: 22000 },
|
{ date: "2024-03-10", voucherNo: "记-0009", summary: "收到货款", debit: 0, credit: 6000, direction: "借", balance: 16000 },
|
{ date: "2024-03-31", voucherNo: "-", summary: "本月合计", debit: 7000, credit: 6000, direction: "借", balance: 16000 },
|
{ date: "2024-03-31", voucherNo: "-", summary: "本年累计", debit: 26000, credit: 20000, direction: "借", balance: 16000 },
|
];
|
|
const getTableData = () => {
|
if (!currentSubject.value) {
|
dataList.value = [];
|
return;
|
}
|
dataList.value = [...mockData];
|
};
|
|
const resetFilters = () => {
|
filters.subject = [];
|
filters.auxiliary = "";
|
filters.auxiliaryItem = "";
|
filters.startMonth = "2024-01";
|
filters.endMonth = "2024-03";
|
dataList.value = [];
|
};
|
|
const getSummaries = (param) => {
|
const { columns, data } = param;
|
const sums = [];
|
columns.forEach((column, index) => {
|
if (index === 0) {
|
sums[index] = "合计";
|
return;
|
}
|
if (column.property === "debit") {
|
const values = data.map(item => Number(item.debit));
|
const sum = values.reduce((prev, curr) => prev + curr, 0);
|
sums[index] = "¥" + formatMoney(sum);
|
} else if (column.property === "credit") {
|
const values = data.map(item => Number(item.credit));
|
const sum = values.reduce((prev, curr) => prev + curr, 0);
|
sums[index] = "¥" + formatMoney(sum);
|
} else {
|
sums[index] = "";
|
}
|
});
|
return sums;
|
};
|
|
const handlePrint = () => {
|
ElMessage.info("打印功能");
|
};
|
|
const handleOut = () => {
|
ElMessage.success("导出成功");
|
};
|
|
onMounted(() => {
|
// 默认不加载数据,需要选择科目
|
});
|
</script>
|
|
<style lang="scss" scoped>
|
.ledger-header {
|
text-align: center;
|
margin-bottom: 20px;
|
h2 {
|
margin: 0 0 10px 0;
|
}
|
p {
|
color: #606266;
|
margin: 5px 0;
|
}
|
}
|
|
.text-primary {
|
color: #409eff;
|
font-weight: bold;
|
}
|
|
.text-success {
|
color: #67c23a;
|
font-weight: bold;
|
}
|
|
.text-danger {
|
color: #f56c6c;
|
font-weight: bold;
|
}
|
|
.text-warning {
|
color: #e6a23c;
|
font-weight: bold;
|
}
|
</style>
|