| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <el-form :inline="true" :model="searchForm" style="width: 100%"> |
| | | <el-row justify="space-between"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="客æ·åç§°"> |
| | | <el-input |
| | | v-model="searchForm.customerName" |
| | | placeholder="请è¾å
¥" |
| | | @change="handleQuery" |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="客æ·ååå·"> |
| | | <el-input |
| | | v-model="searchForm.customerContractNo" |
| | | placeholder="请è¾å
¥" |
| | | @change="handleQuery" |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="项ç®åç§°"> |
| | | <el-input |
| | | v-model="searchForm.projectName" |
| | | placeholder="请è¾å
¥" |
| | | @change="handleQuery" |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-checkbox |
| | | v-model="searchForm.status" |
| | | label="䏿¾ç¤ºå¾
忬¾ä¸º0" |
| | | @change="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <br/> |
| | | <el-form-item label="å¼ç¥¨æ¥æ"> |
| | | <el-date-picker style="width: 240px" v-model="searchForm.commonDate" value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" type="daterange" start-placeholder="å¼å§æ¶é´" end-placeholder="ç»ææ¶é´" clearable |
| | | @change="changeDateRange" @clear="clearRange" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery"> æç´¢ </el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </div> |
| | | <div class="table_list"> |
| | | <div class="actions"> |
| | | <div></div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')"> |
| | | æ°å¢å款 |
| | | </el-button> |
| | | <el-button icon="Download" @click="handleOut"> å¯¼åº </el-button> |
| | | </div> |
| | | </div> |
| | | <el-table |
| | | :data="tableData" |
| | | border |
| | | v-loading="tableLoading" |
| | | @selection-change="handleSelectionChange" |
| | | :row-key="(row) => row.id" |
| | | show-summary |
| | | :summary-method="summarizeMainTable" |
| | | :expand-row-keys="expandedRowKeys" |
| | | @expand-change="expandChange" |
| | | stripe |
| | | height="calc(100vh - 21.5em)" |
| | | > |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column type="expand"> |
| | | <template #default="props"> |
| | | <el-table |
| | | :data="props.row.children" |
| | | border |
| | | show-summary |
| | | :summary-method="summarizeChildrenTable" |
| | | stripe |
| | | > |
| | | <el-table-column |
| | | align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" |
| | | /> |
| | | <el-table-column label="忬¾æ¥æ" prop="receiptPaymentDate" width="130"/> |
| | | <el-table-column label="忬¾éé¢" prop="receiptPaymentAmount"> |
| | | <template #default="scope"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" |
| | | v-model="scope.row.receiptPaymentAmount" |
| | | :disabled="!scope.row.editType" |
| | | :precision="2" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="忬¾æ¹å¼" prop="receiptPaymentType"> |
| | | <template #default="scope"> |
| | | <el-input |
| | | v-model="scope.row.receiptPaymentType" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | :disabled="!scope.row.editType" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç»è®°äºº" prop="registrant" width="90"/> |
| | | <el-table-column label="ç»è®°æ¥æ" prop="createTime" width="130"/> |
| | | <el-table-column label="æä½" width="150" align="center"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="changeEditType(scope.row)" |
| | | v-if="!scope.row.editType" |
| | | :disabled="scope.row.registrant !== userStore.nickName" |
| | | >ç¼è¾</el-button |
| | | > |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="saveReceiptPayment(scope.row)" |
| | | v-if="scope.row.editType" |
| | | :disabled="scope.row.registrant !== userStore.nickName" |
| | | >ä¿å</el-button |
| | | > |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="delReceiptRecord(scope.row)" |
| | | :disabled="scope.row.registrant !== userStore.nickName" |
| | | >å é¤</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column |
| | | label="å¼ç¥¨æ¥æ" |
| | | prop="invoiceDate" |
| | | show-overflow-tooltip |
| | | width="240" |
| | | /> |
| | | <el-table-column |
| | | label="éå®ååå·" |
| | | prop="salesContractNo" |
| | | show-overflow-tooltip |
| | | width="240" |
| | | /> |
| | | <el-table-column |
| | | label="客æ·ååå·" |
| | | prop="customerContractNo" |
| | | show-overflow-tooltip |
| | | width="240" |
| | | |
| | | /> |
| | | <el-table-column |
| | | label="客æ·åç§°" |
| | | prop="customerName" |
| | | show-overflow-tooltip |
| | | width="240" |
| | | /> |
| | | <el-table-column |
| | | label="项ç®åç§°" |
| | | prop="projectName" |
| | | show-overflow-tooltip |
| | | width="340" |
| | | /> |
| | | <el-table-column |
| | | label="产å大类" |
| | | prop="productCategory" |
| | | show-overflow-tooltip |
| | | width="100" |
| | | /> |
| | | <el-table-column |
| | | label="å票å·" |
| | | prop="invoiceNo" |
| | | show-overflow-tooltip |
| | | width="200" |
| | | /> |
| | | <el-table-column |
| | | label="å票éé¢(å
)" |
| | | prop="invoiceTotal" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" |
| | | width="200" |
| | | /> |
| | | <el-table-column label="ç¨ç(%)" prop="taxRate" show-overflow-tooltip /> |
| | | <el-table-column |
| | | label="忬¾éé¢(å
)" |
| | | prop="receiptPaymentAmountTotal" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" |
| | | width="200" |
| | | /> |
| | | <el-table-column |
| | | label="å¾
忬¾éé¢(å
)" |
| | | prop="noReceiptAmount" |
| | | show-overflow-tooltip |
| | | width="200" |
| | | > |
| | | <template #default="{ row, column }"> |
| | | <el-text type="danger"> |
| | | {{ formattedNumber(row, column, row.noReceiptAmount) }} |
| | | </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-dialog |
| | | v-model="dialogFormVisible" |
| | | title="æ°å¢å票å·é¡µé¢" |
| | | width="70%" |
| | | @close="closeDia" |
| | | > |
| | | <el-form |
| | | :model="form" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef" |
| | | > |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éå®ååå·ï¼" prop="salesContractNo"> |
| | | <el-input |
| | | v-model="form.salesContractNo" |
| | | placeholder="èªå¨å¡«å
" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客æ·åç§°ï¼" prop="customerName"> |
| | | <el-input |
| | | v-model="form.customerName" |
| | | placeholder="èªå¨å¡«å
" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å票å·ï¼" prop="invoiceNo"> |
| | | <el-input |
| | | v-model="form.invoiceNo" |
| | | placeholder="èªå¨å¡«å
" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å票éé¢(å
)ï¼" prop="invoiceTotal"> |
| | | <el-input |
| | | type="number" |
| | | v-model="form.invoiceTotal" |
| | | placeholder="èªå¨å¡«å
" |
| | | :step="0.01" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¨çï¼" prop="taxRate"> |
| | | <el-input |
| | | type="number" |
| | | v-model="form.taxRate" |
| | | placeholder="èªå¨å¡«å
" |
| | | :step="0.01" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¬æ¬¡å款éé¢ï¼" prop="receiptPaymentAmount"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" |
| | | :precision="2" |
| | | v-model="form.receiptPaymentAmount" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="忬¾å½¢å¼ï¼" prop="receiptPaymentType"> |
| | | <el-input |
| | | v-model="form.receiptPaymentType" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»è®°äººï¼" prop="registrant"> |
| | | <el-input |
| | | v-model="form.registrant" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥æ¬¾æ¥æï¼" prop="receiptPaymentDate"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.receiptPaymentDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import pagination from "@/components/PIMTable/Pagination.vue"; |
| | | import { onMounted, ref } from "vue"; |
| | | import { |
| | | receiptPaymentSaveOrUpdate, |
| | | bindInvoiceNoRegPage, |
| | | invoiceInfo, |
| | | receiptPaymentHistoryListNoPage, |
| | | receiptPaymentDel, |
| | | } from "../../../api/salesManagement/receiptPayment.js"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | |
| | | const userStore = useUserStore(); |
| | | const { proxy } = getCurrentInstance(); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | }); |
| | | const total = ref(0); |
| | | const expandedRowKeys = ref([]); |
| | | |
| | | // ç¨æ·ä¿¡æ¯è¡¨åå¼¹æ¡æ°æ® |
| | | const dialogFormVisible = ref(false); |
| | | const data = reactive({ |
| | | searchForm: { |
| | | searchText: "", |
| | | status: true, |
| | | customerName: "", |
| | | customerContractNo: "", |
| | | projectName: "", |
| | | }, |
| | | form: { |
| | | salesContractNo: "", |
| | | customerName: "", |
| | | invoiceNo: "", |
| | | invoiceTotal: "", |
| | | taxRate: "", |
| | | receiptPaymentAmount: "", |
| | | receiptPaymentType: "", |
| | | registrant: "", |
| | | receiptPaymentDate: "", |
| | | }, |
| | | rules: { |
| | | salesContractNo: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | customerName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | invoiceNo: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | invoiceTotal: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | taxRate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | receiptPaymentAmount: [ |
| | | { required: true, message: "è¯·éæ©", trigger: "change" }, |
| | | ], |
| | | receiptPaymentType: [ |
| | | { required: true, message: "è¯·éæ©", trigger: "change" }, |
| | | ], |
| | | registrant: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | receiptPaymentDate: [ |
| | | { required: true, message: "è¯·éæ©", trigger: "change" }, |
| | | ], |
| | | }, |
| | | }); |
| | | const { form, rules } = toRefs(data); |
| | | const { form: searchForm, resetForm } = useFormData(data.searchForm); |
| | | |
| | | const formattedNumber = (row, column, cellValue) => { |
| | | return parseFloat(cellValue).toFixed(2); |
| | | }; |
| | | |
| | | const changeDateRange = (date) => { |
| | | if (date) { |
| | | searchForm.invoiceDateStart = date[0]; |
| | | searchForm.invoiceDateEnd = date[1]; |
| | | getList(); |
| | | } |
| | | }; |
| | | |
| | | const clearRange = () => { |
| | | searchForm.commonDate = []; |
| | | searchForm.invoiceDateStart = undefined; |
| | | searchForm.invoiceDateEnd = undefined; |
| | | getList(); |
| | | }; |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | const paginationChange = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | bindInvoiceNoRegPage({ ...searchForm, ...page }) |
| | | .then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | if (expandedRowKeys.value.length > 0) { |
| | | const arr = [] |
| | | const index = tableData.value.findIndex(item => item.id === expandedRowKeys.value[0]); |
| | | if (index > -1) { |
| | | arr.push(tableData.value[index]); |
| | | expandChange(tableData.value[index], arr) |
| | | } |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | // å±å¼è¡ |
| | | const expandChange = (row, expandedRows) => { |
| | | if (expandedRows.length > 0) { |
| | | expandedRowKeys.value = []; |
| | | try { |
| | | receiptPaymentHistoryListNoPage({ |
| | | invoiceLedgerId: row.id, |
| | | type: 1, |
| | | }).then((res) => { |
| | | const index = tableData.value.findIndex((item) => item.id === row.id); |
| | | if (index > -1) { |
| | | if (res?.length > 0) { |
| | | res.forEach((item) => { |
| | | item.editType = false; |
| | | }); |
| | | } |
| | | tableData.value[index].children = res; |
| | | } |
| | | expandedRowKeys.value.push(row.id); |
| | | }); |
| | | } catch (error) { |
| | | console.log(error); |
| | | } |
| | | } else { |
| | | expandedRowKeys.value = []; |
| | | } |
| | | }; |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | console.log("selection", selection); |
| | | selectedRows.value = selection.filter( |
| | | (item) => item.customerContractNo !== null |
| | | ); |
| | | }; |
| | | // 主表åè®¡æ¹æ³ |
| | | const summarizeMainTable = (param) => { |
| | | return proxy.summarizeTable( |
| | | param, |
| | | ["invoiceTotal", "receiptPaymentAmountTotal", "noReceiptAmount"], |
| | | { |
| | | ticketsNum: { noDecimal: true }, // ä¸ä¿çå°æ° |
| | | futureTickets: { noDecimal: true }, // ä¸ä¿çå°æ° |
| | | } |
| | | ); |
| | | }; |
| | | // å表åè®¡æ¹æ³ |
| | | const summarizeChildrenTable = (param) => { |
| | | return proxy.summarizeTable(param, ["receiptPaymentAmount"]); |
| | | }; |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = () => { |
| | | form.value = {}; |
| | | if (selectedRows.value.length !== 1) { |
| | | proxy.$modal.msgError("è¯·éæ©ä¸æ¡æ°æ®"); |
| | | return; |
| | | } |
| | | if (selectedRows.value[0].noReceiptAmount == 0) { |
| | | proxy.$modal.msgWarning("æ éå忬¾"); |
| | | return; |
| | | } |
| | | invoiceInfo({ id: selectedRows.value[0].id }).then((res) => { |
| | | form.value = { ...res.data }; |
| | | form.value.invoiceLedgerId = form.value.id; |
| | | form.value.id = ""; |
| | | form.value.registrant = userStore.nickName; |
| | | }); |
| | | dialogFormVisible.value = true; |
| | | }; |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate((valid) => { |
| | | if (valid) { |
| | | receiptPaymentSaveOrUpdate(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | }; |
| | | |
| | | // å é¤åæ¬¾è®°å½ |
| | | const delReceiptRecord = (row) => { |
| | | console.log("row", row); |
| | | ElMessageBox.confirm("确认å é¤è¯¥è®°å½åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(async () => { |
| | | try { |
| | | let ids = []; |
| | | ids.push(row.id); |
| | | await receiptPaymentDel(ids); |
| | | ElMessage.success("å 餿å"); |
| | | getList(); |
| | | } catch (error) { |
| | | console.error("å é¤å¤±è´¥:", error); |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.info("已忶å é¤"); |
| | | }); |
| | | }; |
| | | |
| | | // ç¼è¾ä¿®æ¹ç¶æ |
| | | const changeEditType = (row) => { |
| | | row.editType = !row.editType; |
| | | }; |
| | | |
| | | // ä¿å忬¾è®°å½ |
| | | const saveReceiptPayment = (row) => { |
| | | let updateData = { |
| | | id: row.id, |
| | | receiptPaymentType: row.receiptPaymentType, |
| | | receiptPaymentAmount: row.receiptPaymentAmount, |
| | | }; |
| | | receiptPaymentSaveOrUpdate(updateData).then((res) => { |
| | | row.editType = !row.editType; |
| | | getList(); |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | const ids = selectedRows.value.map((item) => item.id); |
| | | proxy.download( |
| | | `/receiptPayment/export`, |
| | | { ids: `${ids}` }, |
| | | "忬¾ç»è®°æ¡£æ¡.xlsx" |
| | | ); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .table_list { |
| | | margin-top: unset; |
| | | } |
| | | ::v-deep(.el-checkbox__label) { |
| | | font-weight: bold; |
| | | } |
| | | .actions { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 10px; |
| | | } |
| | | </style> |