| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form" |
| | | style="margin-bottom: 20px;"> |
| | | <div> |
| | | <span class="search_title">回款台账</span> |
| | | <el-input |
| | | v-model="searchForm.searchText" |
| | | style="width: 240px" |
| | | placeholder="输入客户名称搜索" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> |
| | | <span class="search_title">客户名称:</span> |
| | | <el-input v-model="searchForm.searchText" |
| | | style="width: 240px" |
| | | placeholder="输入客户名称搜索" |
| | | @change="handleQuery" |
| | | clearable |
| | | prefix-icon="Search" /> |
| | | <el-button type="primary" |
| | | @click="handleQuery" |
| | | style="margin-left: 10px">搜索</el-button> |
| | | </div> |
| | | </div> |
| | | <div style="display: flex"> |
| | | <div class="table_list"> |
| | | <el-table :data="tableData" border v-loading="tableLoading" |
| | | :row-key="row => row.id" |
| | | show-summary |
| | | :summary-method="summarizeMainTable" |
| | | @row-click = "rowClickMethod" |
| | | height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" label="序号" type="index" width="60" /> |
| | | <el-table-column label="客户名称" prop="customerName" show-overflow-tooltip/> |
| | | <el-table-column label="开票金额" prop="invoiceTotal" show-overflow-tooltip :formatter="formattedNumber"/> |
| | | <el-table-column label="回款金额" prop="receiptPaymentAmount" show-overflow-tooltip :formatter="formattedNumber"/> |
| | | <el-table-column label="未回款金额" prop="unReceiptPaymentAmount" show-overflow-tooltip :formatter="formattedNumber"/> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" :page="page.current" |
| | | :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | <div class="table_list"> |
| | | <el-table :data="receiptRecord" border |
| | | :row-key="row => row.id" |
| | | show-summary |
| | | :summary-method="summarizeMainTable" |
| | | height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" label="序号" type="index" width="60" /> |
| | | <el-table-column label="发生日期" prop="receiptPaymentDate" show-overflow-tooltip/> |
| | | <el-table-column label="回款金额" prop="receiptPaymentAmount" show-overflow-tooltip :formatter="formattedNumber"/> |
| | | <el-table-column label="待收金额" prop="noReceiptAmount" show-overflow-tooltip :formatter="formattedNumber"/> |
| | | <el-table-column label="应收金额" prop="invoiceTotal" show-overflow-tooltip :formatter="formattedNumber"/> |
| | | </el-table> |
| | | <pagination v-show="recordTotal > 0" :total="recordTotal" layout="total, sizes, prev, pager, next, jumper" :page="recordPage.current" |
| | | :limit="recordPage.size" @pagination="recordPaginationChange" /> |
| | | </div> |
| | | </div> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <div class="table_list" |
| | | style="width: 100%"> |
| | | <el-table :data="tableData" |
| | | border |
| | | v-loading="tableLoading" |
| | | :row-key="(row) => row.customerId" |
| | | show-summary |
| | | :summary-method="summarizeMainTable" |
| | | @row-click="rowClickMethod" |
| | | highlight-current-row |
| | | height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" |
| | | label="序号" |
| | | type="index" |
| | | width="60" /> |
| | | <el-table-column label="客户名称" |
| | | prop="customerName" |
| | | show-overflow-tooltip |
| | | width="200" /> |
| | | <el-table-column label="合同金额(元)" |
| | | prop="contractAmounts" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" |
| | | width="200" /> |
| | | <el-table-column label="回款金额(元)" |
| | | prop="receiptPaymentAmount" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" |
| | | width="200" /> |
| | | <el-table-column label="应收金额(元)" |
| | | prop="receiptableAmount" |
| | | show-overflow-tooltip |
| | | width="200"> |
| | | <template #default="{ row, column }"> |
| | | <el-text type="danger"> |
| | | {{ formattedNumber(row, column, row.receiptableAmount) }} |
| | | </el-text> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" |
| | | :total="total" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | @pagination="paginationChange" /> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="table_list" |
| | | style="width: 100%"> |
| | | <el-table :data="receiptRecord" |
| | | border |
| | | :row-key="(row) => row.id" |
| | | show-summary |
| | | :summary-method="summarizeMainTable1" |
| | | height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" |
| | | label="序号" |
| | | type="index" |
| | | width="60" /> |
| | | <el-table-column label="合同签订日期" prop="executionDate" show-overflow-tooltip width="110" /> |
| | | <el-table-column label="销售合同号" prop="salesContractNo" show-overflow-tooltip width="200" /> |
| | | <el-table-column label="合同金额(元)" prop="contractAmount" show-overflow-tooltip :formatter="formattedNumber" width="200" /> |
| | | <el-table-column label="回款金额(元)" prop="receiptPaymentAmount" show-overflow-tooltip :formatter="formattedNumber" width="200" /> |
| | | <el-table-column label="应收金额(元)" prop="receiptableAmount" show-overflow-tooltip width="200"> |
| | | <template #default="{ row, column }"> |
| | | <el-text type="danger">{{ formattedNumber(row, column, row.receiptableAmount) }}</el-text> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" fixed="right" align="center" width="100"> |
| | | <template #default="{ row }"> |
| | | <el-button link type="primary" @click="openReceiptDialog(row)">新增回款</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="recordTotal > 0" |
| | | :total="recordTotal" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page="recordPage.current" |
| | | :limit="recordPage.size" |
| | | @pagination="recordPaginationChange" /> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-dialog v-model="receiptDialogVisible" title="新增回款" width="35%" @close="closeReceiptDialog"> |
| | | <el-form :model="receiptForm" label-width="100px" :rules="receiptRules" ref="receiptFormRef"> |
| | | <el-form-item label="销售合同号:">{{ currentRow.salesContractNo || '--' }}</el-form-item> |
| | | <el-form-item label="回款日期:" prop="paymentDate"> |
| | | <el-date-picker style="width:100%" v-model="receiptForm.paymentDate" value-format="YYYY-MM-DD" type="date" placeholder="请选择回款日期" clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="回款金额:" prop="paymentAmount"> |
| | | <el-input-number style="width:100%" v-model="receiptForm.paymentAmount" :min="0" :max="Math.max(0,(Number(currentRow.receiptableAmount)||0)-(Number(currentRow.receiptPaymentAmount)||0))" placeholder="请输入回款金额" controls-position="right" /> |
| | | <div style="color:#e6a23c;font-size:12px;margin-top:4px">当前可回款余额:{{ formattedNumber(null,null,Math.max(0,(Number(currentRow.receiptableAmount)||0)-(Number(currentRow.receiptPaymentAmount)||0))) }} 元</div> |
| | | </el-form-item> |
| | | <el-form-item label="回款方式:" prop="paymentMethod"> |
| | | <el-select v-model="receiptForm.paymentMethod" placeholder="请选择回款方式" style="width:100%" clearable> |
| | | <el-option label="银行转账" value="银行转账" /><el-option label="现金" value="现金" /><el-option label="支票" value="支票" /><el-option label="微信/支付宝" value="微信/支付宝" /><el-option label="其他" value="其他" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="备注:" prop="remark"> |
| | | <el-input v-model="receiptForm.remark" type="textarea" :rows="3" placeholder="请输入备注信息" clearable /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer><el-button type="primary" @click="submitReceiptForm">确认</el-button><el-button @click="closeReceiptDialog">取消</el-button></template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | import { |
| | | invoiceLedgerSalesAccount, |
| | | } from "../../../api/salesManagement/invoiceLedger.js"; |
| | | import { |
| | | receiptPaymentListPage |
| | | } from "../../../api/salesManagement/receiptPayment.js"; |
| | | import Pagination from "../../../components/PIMTable/Pagination.vue"; |
| | | import { onMounted, ref, reactive, toRefs, getCurrentInstance } from "vue"; |
| | | import { customewTransactions, customewTransactionsDetails, saveReceiptPayment } from "@/api/salesManagement/indicatorStats.js"; |
| | | import Pagination from "../../../components/PIMTable/Pagination.vue"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const tableData = ref([]); |
| | | const receiptRecord = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ current: 1, size: 100 }); |
| | | const recordPage = reactive({ current: 1, size: 100 }); |
| | | const total = ref(0); |
| | | const recordTotal = ref(0); |
| | | const data = reactive({ searchForm: { searchText: "", invoiceDate: "" } }); |
| | | const customerId = ref(""); |
| | | const { searchForm } = toRefs(data); |
| | | const originReceiptRecord = ref([]); |
| | | |
| | | const tableData = ref([]) |
| | | const receiptRecord = ref([]) |
| | | const tableLoading = ref(false) |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | }) |
| | | const recordPage = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | }) |
| | | const total = ref(0) |
| | | const recordTotal = ref(0) |
| | | const data = reactive({ |
| | | searchForm: { |
| | | searchText: '', |
| | | invoiceDate:'' |
| | | } |
| | | }) |
| | | const customerId = ref('') |
| | | const { searchForm } = toRefs(data) |
| | | // 查询列表 |
| | | /** 搜索按钮操作 */ |
| | | const handleQuery = () => { |
| | | page.current = 1 |
| | | getList() |
| | | } |
| | | const paginationChange = (obj) => { |
| | | console.log('paginationChange', current,limit) |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList() |
| | | } |
| | | const getList = () => { |
| | | tableLoading.value = true |
| | | invoiceLedgerSalesAccount({...searchForm.value, ...page}).then(res => { |
| | | tableLoading.value = false |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | if(tableData.value.length > 0) { |
| | | recordPage.current = 1 |
| | | customerId.value = tableData.value[0].id |
| | | receiptPaymentList(customerId.value); |
| | | } |
| | | }) |
| | | } |
| | | const formattedNumber = (row, column, cellValue) => { |
| | | return parseFloat(cellValue).toFixed(2); |
| | | }; |
| | | // 主表合计方法 |
| | | const summarizeMainTable = (param) => { |
| | | const { columns, data } = param; |
| | | const sums = []; |
| | | columns.forEach((column, index) => { |
| | | if (index === 0) { |
| | | sums[index] = '合计'; |
| | | return; |
| | | } |
| | | const prop = column.property; |
| | | if (['invoiceAmount','receiptPaymentAmount','unReceiptPaymentAmount'].includes(prop)) { |
| | | const values = data.map(item => Number(item[prop])); |
| | | if (!values.every(value => isNaN(value))) { |
| | | sums[index] = values.reduce((acc, val) => (!isNaN(val) ? acc + val : acc), 0); |
| | | } else { |
| | | sums[index] = ''; |
| | | const receiptDialogVisible = ref(false); |
| | | const currentRow = ref({}); |
| | | const receiptFormRef = ref(null); |
| | | const receiptForm = reactive({ paymentDate:"", paymentAmount:undefined, paymentMethod:"", remark:"" }); |
| | | const vPA = (_,v,cb) => { if(!v) return cb(new Error("请输入回款金额")); const m=Math.max(0,(Number(currentRow.value.receiptableAmount)||0)-(Number(currentRow.value.receiptPaymentAmount)||0)); if(v>m) return cb(new Error(`回款金额不能超过可回款余额 ${m.toFixed(2)} 元`)); cb(); }; |
| | | const receiptRules = { paymentDate:[{required:true,message:"请选择回款日期",trigger:"change"}], paymentAmount:[{required:true,validator:vPA,trigger:"blur"}], paymentMethod:[{required:true,message:"请选择回款方式",trigger:"change"}] }; |
| | | const openReceiptDialog = r => { currentRow.value=r; receiptForm.paymentDate=""; receiptForm.paymentAmount=undefined; receiptForm.paymentMethod=""; receiptForm.remark=""; receiptDialogVisible.value=true; }; |
| | | const closeReceiptDialog = () => { receiptFormRef.value?.resetFields(); receiptDialogVisible.value=false; }; |
| | | const submitReceiptForm = () => { receiptFormRef.value?.validate(v=>{ if(v){ saveReceiptPayment({ customerId:customerId.value, salesContractNo:currentRow.value.salesContractNo, paymentDate:receiptForm.paymentDate, paymentAmount:receiptForm.paymentAmount, paymentMethod:receiptForm.paymentMethod, remark:receiptForm.remark }).then(res=>{ proxy.$modal.msgSuccess("新增回款成功"); closeReceiptDialog(); receiptPaymentList(customerId.value); getList(); }); } }); }; |
| | | // 查询列表 |
| | | /** 搜索按钮操作 */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | const paginationChange = obj => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | customewTransactions({ ...searchForm.value, ...page }).then(res => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | if (tableData.value.length > 0) { |
| | | recordPage.current = 1; |
| | | customerId.value = tableData.value[0].customerId; |
| | | receiptPaymentList(customerId.value); |
| | | } |
| | | } else { |
| | | sums[index] = ''; |
| | | } |
| | | }) |
| | | return sums; |
| | | }; |
| | | }); |
| | | }; |
| | | const formattedNumber = (row, column, cellValue) => { |
| | | return cellValue ? parseFloat(cellValue).toFixed(2) : "0.00"; |
| | | }; |
| | | // 主表合计方法 |
| | | const summarizeMainTable = param => { |
| | | return proxy.summarizeTable( |
| | | param, |
| | | ["invoiceTotal", "receiptPaymentAmount", "unReceiptPaymentAmount"], |
| | | { |
| | | ticketsNum: { noDecimal: true }, // 不保留小数 |
| | | futureTickets: { noDecimal: true }, // 不保留小数 |
| | | } |
| | | ); |
| | | }; |
| | | // 子表合计方法 |
| | | const summarizeMainTable1 = param => { |
| | | var summarizeTable = proxy.summarizeTable( |
| | | param, |
| | | ["contractAmount", "receiptPaymentAmount", "receiptableAmount"], |
| | | { |
| | | ticketsNum: { noDecimal: true }, // 不保留小数 |
| | | futureTickets: { noDecimal: true }, // 不保留小数 |
| | | } |
| | | ); |
| | | return summarizeTable; |
| | | }; |
| | | |
| | | const receiptPaymentList = (id) => { |
| | | const param = { |
| | | customerId:id, |
| | | current: recordPage.current, |
| | | size: recordPage.size, |
| | | } |
| | | console.log('param', param) |
| | | receiptPaymentListPage(param).then(res => { |
| | | receiptRecord.value = res.data.records; |
| | | recordTotal.value = res.data.total; |
| | | const receiptPaymentList = id => { |
| | | const param = { |
| | | customerId: id, |
| | | current: recordPage.current, |
| | | size: recordPage.size, |
| | | }; |
| | | customewTransactionsDetails(param).then(res => { |
| | | if (Array.isArray(res.data)) { |
| | | originReceiptRecord.value = res.data; |
| | | recordTotal.value = res.data.length; |
| | | handlePagination({ page: 1, limit: recordPage.size }); |
| | | } else { |
| | | receiptRecord.value = res.data.records; |
| | | recordTotal.value = res.data.total; |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | }) |
| | | } |
| | | // 汇款记录列表分页 |
| | | const recordPaginationChange = pagination => { |
| | | recordPage.current = pagination.page; |
| | | recordPage.size = pagination.limit; |
| | | receiptPaymentList(customerId.value); |
| | | }; |
| | | |
| | | // 汇款记录列表分页 |
| | | const recordPaginationChange = (obj) => { |
| | | console.log('recordPaginationChange', obj ); |
| | | recordPage.current = obj.page; |
| | | recordPage.size = obj.limit; |
| | | console.log('recordPage',recordPage) |
| | | receiptPaymentList(customerId.value); |
| | | } |
| | | const rowClickMethod = row => { |
| | | customerId.value = row.customerId; |
| | | receiptPaymentList(customerId.value); |
| | | }; |
| | | |
| | | const rowClickMethod = (row) => { |
| | | customerId.value = row.id; |
| | | receiptPaymentList(customerId.value); |
| | | } |
| | | const handlePagination = ({ page, limit }) => { |
| | | recordPage.current = page; |
| | | recordPage.size = limit; |
| | | |
| | | const start = (page - 1) * limit; |
| | | const end = start + limit; |
| | | |
| | | getList() |
| | | receiptRecord.value = originReceiptRecord.value.slice(start, end); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | |
| | | .table_list { |
| | | width: 50%; |
| | | } |
| | | |
| | | .table_list { |
| | | width: 50%; |
| | | } |
| | | </style> |