✨ feat: 财务单据完善
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
},
|
||||
methods: {
|
||||
getFinancialAccounts() {
|
||||
console.log(this.financialAccounts, 'financialAccounts');
|
||||
this.options = this.financialAccounts.map(item => ({
|
||||
label: item.accountName,
|
||||
value: item.accountId
|
||||
|
||||
@@ -13,7 +13,8 @@ const mutations = {
|
||||
const actions = {
|
||||
getFinancialAccounts({ commit }) {
|
||||
listAccount({ pageSize: 1000 }).then(response => {
|
||||
commit('SET_FINANCIAL_ACCOUNTS', response.rows);
|
||||
console.log(response.data, 'finance.response.rows');
|
||||
commit('SET_FINANCIAL_ACCOUNTS', response.data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div class="finance-voucher-component">
|
||||
<div
|
||||
v-for="(voucher, index) in voucherData"
|
||||
:key="index"
|
||||
class="voucher-item"
|
||||
>
|
||||
<!-- 主单据信息行 -->
|
||||
<div class="voucher-header">
|
||||
<div class="header-cell">
|
||||
<el-checkbox v-model="voucher.checked"></el-checkbox>
|
||||
</div>
|
||||
<div class="header-cell">日期: {{ formatDate(voucher.docDate) }}</div>
|
||||
<div class="header-cell">单据编号: {{ voucher.docNo }}</div>
|
||||
<div class="header-cell">单据类型: {{ voucher.docType }}</div>
|
||||
<div class="header-cell operation-group">
|
||||
<el-button type="text" size="mini" @click.stop="handleView(voucher)">查看</el-button>
|
||||
<el-button type="text" size="mini" @click.stop="handleDelete(voucher)">删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 凭证明细表格 -->
|
||||
<el-table :data="voucher.detailList || []" border style="width: 100%;">
|
||||
<el-table-column label="摘要" prop="voucherNo" />
|
||||
<el-table-column label="科目" prop="accountId" />
|
||||
<el-table-column label="借方金额" prop="debitAmount" align="right" />
|
||||
<el-table-column label="贷方金额" prop="creditAmount" align="right" />
|
||||
</el-table>
|
||||
|
||||
<!-- 总计行 -->
|
||||
<div class="total-row">
|
||||
<div class="total-cell" :colspan="3">总计</div>
|
||||
<div class="total-cell" align="right">{{ calculateTotal(voucher.detailList, 'debitAmount') }}</div>
|
||||
<div class="total-cell" align="right">{{ calculateTotal(voucher.detailList, 'creditAmount') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "FinanceVoucherComponent",
|
||||
props: {
|
||||
voucherData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 用于存储选中状态,若父组件需控制,可改为 prop 或 sync 修饰符
|
||||
internalVoucherData: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
voucherData: {
|
||||
handler(val) {
|
||||
this.internalVoucherData = val.map((v) => ({
|
||||
...v,
|
||||
checked: false,
|
||||
}));
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleView(voucher) {
|
||||
this.$emit("view-voucher", voucher);
|
||||
},
|
||||
handleDelete(voucher) {
|
||||
this.$emit("delete-voucher", voucher);
|
||||
},
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr) return "";
|
||||
return new Date(dateStr).toLocaleDateString();
|
||||
},
|
||||
calculateTotal(detailList, field) {
|
||||
if (!detailList || detailList.length === 0) return "0.00";
|
||||
return detailList.reduce(
|
||||
(sum, item) => sum + parseFloat(item[field] || 0),
|
||||
0
|
||||
).toFixed(2);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.finance-voucher-component {
|
||||
padding: 16px;
|
||||
}
|
||||
.voucher-item {
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.voucher-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f5f5f5;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
.header-cell {
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.operation-group {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
.total-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f0f9ff;
|
||||
padding: 8px 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.total-cell {
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
@@ -13,6 +13,11 @@
|
||||
<el-form-item label="关联订单" prop="relatedOrderId">
|
||||
<el-input v-model="form.relatedOrderId" placeholder="请输入关联订单" />
|
||||
</el-form-item>
|
||||
<el-form-item label="单据类型" prop="docType">
|
||||
<el-select v-model="form.docType" placeholder="请选择单据类型">
|
||||
<el-option v-for="item in dict.type.finance_voucher_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
@@ -94,18 +99,20 @@
|
||||
<script>
|
||||
import AmountSelect from '@/components/KLPService/AmountSelect/index.vue';
|
||||
import { addFinancialDocumentWithDetail, updateFinancialDocument } from "@/api/finance/financialDocument";
|
||||
import { updateJournalEntry } from "@/api/finance/jouneryEntry";
|
||||
import { updateJournalEntry, addJournalEntry } from "@/api/finance/jouneryEntry";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AmountSelect
|
||||
},
|
||||
dicts: ['finance_voucher_type'],
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
docNo: undefined,
|
||||
docDate: undefined,
|
||||
relatedOrderId: undefined
|
||||
relatedOrderId: undefined,
|
||||
docType: undefined
|
||||
},
|
||||
tableData: [{
|
||||
voucherNo: '',
|
||||
@@ -167,24 +174,26 @@ export default {
|
||||
initData: {
|
||||
handler(newVal) {
|
||||
console.log(newVal, 'watchData');
|
||||
if (newVal) {
|
||||
if (newVal.detailList) {
|
||||
this.tableData = newVal.detailList;
|
||||
} else {
|
||||
this.tableData = [{
|
||||
voucherNo: '',
|
||||
accountId: undefined,
|
||||
debitAmount: 0,
|
||||
creditAmount: 0,
|
||||
remark: '',
|
||||
voucherNo: ''
|
||||
}]
|
||||
}
|
||||
if (newVal && newVal.detailList) {
|
||||
this.tableData = newVal.detailList;
|
||||
this.form.docNo = newVal.docNo;
|
||||
this.form.docDate = newVal.docDate;
|
||||
this.form.relatedOrderId = newVal.relatedOrderId;
|
||||
this.form.docType = newVal.docType;
|
||||
this.isCreate = false;
|
||||
} else {
|
||||
this.form.docNo = undefined;
|
||||
this.form.docDate = undefined;
|
||||
this.form.relatedOrderId = undefined;
|
||||
this.form.docType = undefined;
|
||||
this.tableData = [{
|
||||
voucherNo: '',
|
||||
accountId: undefined,
|
||||
debitAmount: 0,
|
||||
creditAmount: 0,
|
||||
remark: '',
|
||||
voucherNo: ''
|
||||
}]
|
||||
this.isCreate = true;
|
||||
}
|
||||
},
|
||||
@@ -312,6 +321,38 @@ export default {
|
||||
},
|
||||
|
||||
handleCreate() {
|
||||
if (!this.validateTableData()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 6. 提交数据
|
||||
addFinancialDocumentWithDetail({
|
||||
docNo: form.docNo,
|
||||
docDate: form.docDate,
|
||||
// 保持变量名一致
|
||||
relatedOrderId: form.relatedOrderId,
|
||||
amount: this.debitAmount,
|
||||
details: validData.map((row, idx) => ({
|
||||
// voucherNo: row.voucherNo,
|
||||
voucherNo: row.voucherNo,
|
||||
// 保持变量名一致
|
||||
accountId: row.accountId,
|
||||
debitAmount: row.debitAmount,
|
||||
creditAmount: row.creditAmount,
|
||||
remark: row.remark,
|
||||
lineNo: idx + 1,
|
||||
entryDate: form.docDate
|
||||
}))
|
||||
}).then(response => {
|
||||
this.$message.success('凭证创建成功');
|
||||
this.$emit('success');
|
||||
}).catch(error => {
|
||||
this.$message.error('凭证创建失败:' + (error.message || '未知错误'));
|
||||
this.$emit('error', error);
|
||||
});
|
||||
},
|
||||
|
||||
validateTableData() {
|
||||
// 收集所有错误信息
|
||||
const errors = [];
|
||||
const { form, tableData } = this;
|
||||
@@ -321,6 +362,7 @@ export default {
|
||||
if (!form.docDate) errors.push('单据日期必填');
|
||||
// 注意:原模板中是relatedOrderId,保持变量名一致
|
||||
if (!form.relatedOrderId) errors.push('关联订单必填');
|
||||
if (!form.docType) errors.push('单据类型必填');
|
||||
|
||||
// 2. 过滤有效行并检查基本存在性
|
||||
const validData = tableData.filter(row => this.isRowNotEmpty(row));
|
||||
@@ -365,47 +407,37 @@ export default {
|
||||
message: errors.map(error => `<p>${error}</p>`).join(''),
|
||||
type: 'error'
|
||||
})
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 6. 提交数据
|
||||
addFinancialDocumentWithDetail({
|
||||
docNo: form.docNo,
|
||||
docDate: form.docDate,
|
||||
// 保持变量名一致
|
||||
relatedOrderId: form.relatedOrderId,
|
||||
amount: this.debitAmount,
|
||||
details: validData.map((row, idx) => ({
|
||||
// voucherNo: row.voucherNo,
|
||||
voucherNo: row.voucherNo,
|
||||
// 保持变量名一致
|
||||
accountId: row.accountId,
|
||||
debitAmount: row.debitAmount,
|
||||
creditAmount: row.creditAmount,
|
||||
remark: row.remark,
|
||||
lineNo: idx + 1,
|
||||
entryDate: form.docDate
|
||||
}))
|
||||
}).then(response => {
|
||||
this.$message.success('凭证创建成功');
|
||||
this.$emit('success');
|
||||
}).catch(error => {
|
||||
this.$message.error('凭证创建失败:' + (error.message || '未知错误'));
|
||||
this.$emit('error', error);
|
||||
});
|
||||
return true;
|
||||
},
|
||||
|
||||
handleEdit(index) {
|
||||
// 找到对应的列变更
|
||||
const row = this.tableData[index];
|
||||
updateJournalEntry(row).then(response => {
|
||||
this.$message.success('明细变更成功');
|
||||
}).catch(error => {
|
||||
this.$message.error('明细变更失败:' + (error.message || '未知错误'));
|
||||
});
|
||||
if (row.entryId) {
|
||||
updateJournalEntry(row).then(response => {
|
||||
this.$message.success('明细变更成功');
|
||||
}).catch(error => {
|
||||
this.$message.error('明细变更失败:' + (error.message || '未知错误'));
|
||||
});
|
||||
} else {
|
||||
addJournalEntry({
|
||||
...row,
|
||||
documentId: this.initData.documentId,
|
||||
}).then(response => {
|
||||
this.$message.success('明细变更成功');
|
||||
}).catch(error => {
|
||||
this.$message.error('明细变更失败:' + (error.message || '未知错误'));
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
handleChange() {
|
||||
if (!this.validateTableData()) {
|
||||
return;
|
||||
}
|
||||
updateFinancialDocument({
|
||||
documentId: this.initData.documentId,
|
||||
docNo: this.form.docNo,
|
||||
|
||||
@@ -73,37 +73,11 @@
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="financialDocumentList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="单据ID" align="center" prop="documentId" v-if="true"/>
|
||||
<el-table-column label="单据编号" align="center" prop="docNo" />
|
||||
<el-table-column label="单据类型" align="center" prop="docType" />
|
||||
<el-table-column label="单据日期" align="center" prop="docDate" width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.docDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单据金额" align="center" prop="amount" />
|
||||
<el-table-column label="关联订单ID" align="center" prop="relatedOrderId" />
|
||||
<el-table-column label="单据状态" align="center" prop="status" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<FinanceVoucherTable
|
||||
:voucher-data="financialDocumentList"
|
||||
@view-voucher="handleUpdate"
|
||||
@delete-voucher="handleDelete"
|
||||
/>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
@@ -123,11 +97,13 @@
|
||||
<script>
|
||||
import { listFinancialDocumentWithDetail, getFinancialDocument, delFinancialDocument, addFinancialDocument, updateFinancialDocument } from "@/api/finance/financialDocument";
|
||||
import CreateDocument from "./components/Voucher.vue";
|
||||
import FinanceVoucherTable from "./components/FinanceVoucherTable.vue"; // 引入定制表格
|
||||
|
||||
export default {
|
||||
name: "FinancialDocument",
|
||||
components: {
|
||||
CreateDocument
|
||||
CreateDocument,
|
||||
FinanceVoucherTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -227,6 +203,8 @@ export default {
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.currentRow = {}
|
||||
// this.isCreate = true;
|
||||
this.title = "添加财务单据";
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div style="position: relative; padding-top: 60px;">
|
||||
<div style="position: relative;">
|
||||
<div style="position: absolute; top: 10px; left: 10px;">
|
||||
<!-- 策略切换单选框 -->
|
||||
<el-radio-group
|
||||
v-model="currentStrategy"
|
||||
size="small"
|
||||
size="mini"
|
||||
>
|
||||
<el-radio label="stockIo">盘点单</el-radio>
|
||||
<el-radio label="order">订单</el-radio>
|
||||
@@ -16,6 +16,7 @@
|
||||
v-model="currentId"
|
||||
:placeholder="`请选择${strategyLabels[currentStrategy]}`"
|
||||
style="width: 200px;"
|
||||
size="mini"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in currentList"
|
||||
@@ -26,7 +27,6 @@
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="print-container" v-loading="loading">
|
||||
<BarCode :barcodes="drawerBarcodeData" />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user