From 2c8a663d12ef967a6378d9f38a4224d14201f9d9 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期四, 28 五月 2026 21:53:18 +0800
Subject: [PATCH] chore: 使用 dev_NEW_pro 覆盖当前分支代码
---
src/views/financialManagement/receivable/reconciliation.vue | 738 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 738 insertions(+), 0 deletions(-)
diff --git a/src/views/financialManagement/receivable/reconciliation.vue b/src/views/financialManagement/receivable/reconciliation.vue
new file mode 100644
index 0000000..b1bff0e
--- /dev/null
+++ b/src/views/financialManagement/receivable/reconciliation.vue
@@ -0,0 +1,738 @@
+<template>
+ <div class="app-container">
+ <el-form :model="filters" :inline="true">
+ <el-form-item label="瀹㈡埛:">
+ <el-select v-model="filters.customerId" placeholder="璇烽�夋嫨瀹㈡埛" clearable filterable 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-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-form-item>
+ </el-form>
+ <div class="table_list">
+ <div class="actions">
+ <div>
+ <el-button type="primary" @click="generateStatement" icon="Document">鐢熸垚瀵硅处鍗�</el-button>
+ </div>
+ <div>
+ <el-button @click="handleOut" icon="Download">瀵煎嚭瀵硅处鍗�</el-button>
+ </div>
+ </div>
+ <PIMTable
+ rowKey="id"
+ :column="columns"
+ :tableData="dataList"
+ :tableLoading="tableLoading"
+ :page="{
+ current: pagination.currentPage,
+ size: pagination.pageSize,
+ total: pagination.total,
+ }"
+ @pagination="changePage"
+ >
+ <template #openingBalance="{ row }">
+ <span :class="row.openingBalance >= 0 ? 'text-success' : 'text-danger'">楼{{ formatMoney(row.openingBalance) }}</span>
+ </template>
+ <template #currentPlan="{ row }">
+ <span class="text-primary">楼{{ formatMoney(row.currentPlan) }}</span>
+ </template>
+ <template #currentActually="{ row }">
+ <span class="text-success">楼{{ formatMoney(row.currentActually) }}</span>
+ </template>
+ <template #closingBalance="{ row }">
+ <span :class="row.closingBalance >= 0 ? 'text-success' : 'text-danger'">楼{{ formatMoney(row.closingBalance) }}</span>
+ </template>
+ <template #operation="{ row }">
+ <el-button type="primary" link @click="viewDetail(row)">鏌ョ湅鏄庣粏</el-button>
+ <!-- <el-button type="primary" link @click="printStatement(row)">鎵撳嵃</el-button> -->
+ <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
+ </template>
+ </PIMTable>
+ </div>
+
+ <FormDialog title="瀵硅处鏄庣粏" v-model="detailDialogVisible" width="900px" @confirm="printDetail" @cancel="detailDialogVisible = false" operationType="detail">
+ <div class="statement-header">
+ <h3>{{ currentCustomer }} 搴旀敹瀵硅处鍗�</h3>
+ <p>瀵硅处鏈熼棿: {{ currentPeriod }}</p>
+ </div>
+ <el-table :data="detailData" border style="width: 100%" v-loading="detailLoading">
+ <el-table-column prop="date" label="鏃ユ湡" width="120" />
+ <el-table-column prop="type" label="绫诲瀷" width="100">
+ <template #default="{ row }">
+ <el-tag :type="row.type === '鍑哄簱' ? 'success' : row.type === '閫�璐�' ? 'danger' : 'primary'">{{ row.type }}</el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="code" label="鍗曟嵁缂栧彿" width="150" />
+ <el-table-column prop="debit" label="鍊熸柟(搴旀敹)" width="120">
+ <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 prop="credit" label="璐锋柟(鏀舵)" width="120">
+ <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 prop="balance" label="浣欓" width="120">
+ <template #default="{ row }">
+ <span :class="row.balance >= 0 ? 'text-success' : 'text-danger'">楼{{ formatMoney(row.balance) }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="remark" label="澶囨敞" show-overflow-tooltip />
+ </el-table>
+ <template #footer>
+ <el-button type="primary" @click="printDetail">鎵撳嵃</el-button>
+ <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
+ </template>
+ </FormDialog>
+
+ <FormDialog title="鐢熸垚瀵硅处鍗�" v-model="generateDialogVisible" width="1000px" @confirm="confirmGenerate" @cancel="generateDialogVisible = false">
+ <el-form :model="generateForm" label-width="100px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="閫夋嫨瀹㈡埛" prop="customerId">
+ <el-select
+ v-model="generateForm.customerId"
+ placeholder="璇烽�夋嫨瀹㈡埛"
+ style="width: 100%;"
+ filterable
+ @change="onCustomerChange"
+ >
+ <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="statementMonth">
+ <el-date-picker v-model="generateForm.statementMonth" type="month" placeholder="閫夋嫨鏈堜唤" value-format="YYYY-MM" style="width: 100%;" @change="onStatementMonthChange" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+
+ <div v-if="statementDetailLoaded" class="sales-section">
+ <div v-if="salesData.length > 0" class="section-title">鏈湀閿�鍞暟鎹�</div>
+ <el-table
+ v-if="salesData.length > 0"
+ ref="salesTableRef"
+ :data="salesData"
+ border
+ row-key="id"
+ style="width: 100%; margin-bottom: 15px;"
+ v-loading="salesLoading"
+ @selection-change="handleSalesSelectionChange"
+ >
+ <el-table-column type="selection" width="55" align="center" />
+ <el-table-column prop="occurrenceDate" label="鏃ユ湡" width="120" />
+ <el-table-column prop="receiptNumber" label="鍗曟嵁缂栧彿" width="150" />
+ <el-table-column prop="type" label="绫诲瀷" width="100">
+ <template #default="{ row }">
+ <el-tag :type="getDetailTypeTagType(row.type)">{{ row.typeLabel }}</el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="amount" label="閲戦" width="120">
+ <template #default="{ row }">
+ <span :class="getDetailAmountClass(row.type)">楼{{ formatMoney(row.amount) }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="remark" label="澶囨敞" />
+ </el-table>
+ <el-empty v-else description="璇ュ鎴锋湰鏈堟殏鏃犳槑缁嗘暟鎹�" :image-size="80" />
+
+ <div class="summary-row">
+ <span>鏈熷垵浣欓: <strong class="text-primary">楼{{ formatMoney(generateForm.openingBalance) }}</strong></span>
+ <span>鏈湡搴旀敹: <strong class="text-primary">楼{{ formatMoney(generateForm.currentPlan) }}</strong></span>
+ <span>鏈湡鏀舵: <strong class="text-success">楼{{ formatMoney(generateForm.currentActually) }}</strong></span>
+ <span>鏈熸湯浣欓: <strong :class="displayClosingBalance >= 0 ? 'text-success' : 'text-danger'">楼{{ formatMoney(displayClosingBalance) }}</strong></span>
+ </div>
+ </div>
+
+ <div v-else-if="generateForm.customerId && generateForm.statementMonth && !salesLoading" class="empty-tip">
+ <el-empty description="璇ュ鎴锋湰鏈堟殏鏃犻攢鍞暟鎹�" />
+ </div>
+
+ <template #footer>
+ <el-button type="primary" @click="confirmGenerate" :disabled="!canGenerate" :loading="submitLoading">纭鐢熸垚</el-button>
+ <el-button @click="generateDialogVisible = false">鍙栨秷</el-button>
+ </template>
+ </FormDialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, computed, nextTick, getCurrentInstance } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { listCustomer } from "@/api/basicData/customer.js";
+import {
+ getAccountStatementDetailsByMonth,
+ addAccountStatement,
+ listPageAccountStatement,
+ deleteAccountStatement,
+} from "@/api/financialManagement/accountStatement.js";
+
+const ACCOUNT_TYPE_RECEIVABLE = 1;
+
+const { proxy } = getCurrentInstance();
+
+defineOptions({
+ name: "搴旀敹瀵硅处",
+});
+
+const filters = reactive({
+ customerId: "",
+ startMonth: "",
+ endMonth: "",
+});
+
+const pagination = reactive({
+ currentPage: 1,
+ pageSize: 10,
+ total: 0,
+});
+
+const columns = [
+ { label: "瀵硅处鍗曞彿", prop: "statementNumber", width: "150" },
+ { label: "瀹㈡埛鍚嶇О", prop: "customerName", width: "180" },
+ { label: "瀵硅处鏈熼棿", prop: "statementMonth", width: "150" },
+ { label: "鏈熷垵浣欓", prop: "openingBalance", dataType: "slot", slot: "openingBalance" },
+ { label: "鏈湡搴旀敹", prop: "currentPlan", dataType: "slot", slot: "currentPlan" },
+ { label: "鏈湡鏀舵", prop: "currentActually", dataType: "slot", slot: "currentActually" },
+ { label: "鏈熸湯浣欓", prop: "closingBalance", dataType: "slot", slot: "closingBalance" },
+ { label: "鎿嶄綔", prop: "operation", dataType: "slot", slot: "operation", width: "200", fixed: "right" },
+];
+
+const dataList = ref([]);
+const tableLoading = ref(false);
+const submitLoading = ref(false);
+const detailDialogVisible = ref(false);
+const currentCustomer = ref("");
+const currentPeriod = ref("");
+const detailData = ref([]);
+const detailLoading = ref(false);
+
+const generateDialogVisible = ref(false);
+const salesLoading = ref(false);
+const statementDetailLoaded = ref(false);
+const salesData = ref([]);
+const selectedSales = ref([]);
+const salesTableRef = ref(null);
+const customerList = ref([]);
+
+/** 鏄庣粏 type锛�1鍑哄簱 2鍏ュ簱 3鏀舵 4浠樻 5閫�璐� */
+const STATEMENT_DETAIL_TYPE_MAP = {
+ 1: "鍑哄簱",
+ 2: "鍏ュ簱",
+ 3: "鏀舵",
+ 4: "浠樻",
+ 5: "閫�璐�",
+};
+
+const calculateEndBalance = (openingBalance, currentPlan, currentActually) => {
+ return openingBalance + currentPlan - currentActually;
+};
+
+const getDetailTypeLabel = (type) => STATEMENT_DETAIL_TYPE_MAP[Number(type)] ?? "";
+
+const getDetailTypeTagType = (type) => {
+ const t = Number(type);
+ if (t === 1) return "success";
+ if (t === 3) return "primary";
+ if (t === 5) return "danger";
+ return "info";
+};
+
+const getDetailAmountClass = (type) => {
+ const t = Number(type);
+ if (t === 1) return "text-primary";
+ if (t === 3) return "text-success";
+ return "text-danger";
+};
+
+const generateForm = reactive({
+ customerId: "",
+ customerName: "",
+ statementMonth: "",
+ openingBalance: 0,
+ currentPlan: 0,
+ currentActually: 0,
+ closingBalance: 0,
+});
+
+const displayClosingBalance = computed(() => {
+ return calculateEndBalance(
+ generateForm.openingBalance,
+ generateForm.currentPlan,
+ generateForm.currentActually
+ );
+});
+
+const canGenerate = computed(() => {
+ return generateForm.customerId && generateForm.statementMonth && selectedSales.value.length > 0;
+});
+
+const applyStatementSummary = (data) => {
+ generateForm.openingBalance = Number(data.openingBalance ?? 0);
+ generateForm.currentPlan = Number(data.currentPlan ?? 0);
+ generateForm.currentActually = Number(data.currentActually ?? 0);
+ generateForm.closingBalance = Number(
+ data.closingBalance ??
+ calculateEndBalance(
+ generateForm.openingBalance,
+ generateForm.currentPlan,
+ generateForm.currentActually
+ )
+ );
+};
+
+const getCustomerList = () => {
+ listCustomer({ current: -1, size: -1, type: 0 }).then((res) => {
+ if (res.code === 200) {
+ customerList.value = res.data?.records || [];
+ }
+ });
+};
+
+const normalizeSalesRows = (list) => {
+ const rows = Array.isArray(list) ? list : [];
+ return rows.map((item, index) => {
+ const type = Number(item.type);
+ return {
+ id: item.id ?? `detail-${index}`,
+ accountStatementId: item.accountStatementId,
+ occurrenceDate: item.occurrenceDate ?? "",
+ receiptNumber: item.receiptNumber ?? "",
+ type,
+ typeLabel: getDetailTypeLabel(type),
+ amount: Math.abs(Number(item.amount ?? 0)),
+ remark: item.remark ?? "",
+ };
+ });
+};
+
+const selectAllSalesRows = (keepApiSummary = false) => {
+ nextTick(() => {
+ const table = salesTableRef.value;
+ if (!table) return;
+ table.clearSelection();
+ salesData.value.forEach((row) => table.toggleRowSelection(row, true));
+ selectedSales.value = [...salesData.value];
+ if (!keepApiSummary) {
+ calculateSummary();
+ }
+ });
+};
+
+const isNumericId = (id) => id !== undefined && id !== null && id !== "" && /^\d+$/.test(String(id));
+
+const buildFilterParams = (params = {}) => {
+ const result = { ...params, accountType: ACCOUNT_TYPE_RECEIVABLE };
+ if (filters.customerId) {
+ result.customerId = filters.customerId;
+ }
+ if (filters.startMonth && filters.endMonth && filters.startMonth === filters.endMonth) {
+ result.statementMonth = filters.startMonth;
+ } else if (filters.startMonth) {
+ result.startMonth = filters.startMonth;
+ }
+ if (filters.endMonth && filters.startMonth !== filters.endMonth) {
+ result.endMonth = filters.endMonth;
+ }
+ return result;
+};
+
+const buildListParams = () =>
+ buildFilterParams({
+ current: pagination.currentPage,
+ size: pagination.pageSize,
+ });
+
+const buildExportParams = () => buildFilterParams({});
+
+const buildDetailSubmitItem = (row) => {
+ const item = {
+ occurrenceDate: row.occurrenceDate,
+ receiptNumber: row.receiptNumber,
+ type: row.type,
+ amount: row.amount,
+ remark: row.remark ?? "",
+ };
+ if (isNumericId(row.id)) {
+ item.id = Number(row.id);
+ }
+ if (row.accountStatementId) {
+ item.accountStatementId = row.accountStatementId;
+ }
+ return item;
+};
+
+const buildAddPayload = () => ({
+ customerId: generateForm.customerId,
+ customerName: generateForm.customerName,
+ statementMonth: generateForm.statementMonth,
+ accountType: ACCOUNT_TYPE_RECEIVABLE,
+ statementNumber: "",
+ openingBalance: generateForm.openingBalance,
+ currentPlan: generateForm.currentPlan,
+ currentActually: generateForm.currentActually,
+ closingBalance: generateForm.closingBalance,
+ accountStatementDetails: selectedSales.value.map(buildDetailSubmitItem),
+});
+
+const formatMoney = (value) => {
+ if (value === undefined || value === null) return "0.00";
+ return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const getTableData = () => {
+ tableLoading.value = true;
+ listPageAccountStatement(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 ?? [];
+ } else {
+ ElMessage.error(res.msg || "鏌ヨ澶辫触");
+ dataList.value = [];
+ pagination.total = 0;
+ }
+ })
+ .catch(() => {
+ dataList.value = [];
+ pagination.total = 0;
+ ElMessage.error("鏌ヨ澶辫触");
+ })
+ .finally(() => {
+ tableLoading.value = false;
+ });
+};
+
+const resetFilters = () => {
+ filters.customerId = "";
+ filters.startMonth = "";
+ filters.endMonth = "";
+ pagination.currentPage = 1;
+ getTableData();
+};
+
+const changePage = ({ current, size }) => {
+ pagination.currentPage = current;
+ pagination.pageSize = size;
+ getTableData();
+};
+
+const generateStatement = () => {
+ generateForm.customerId = "";
+ generateForm.customerName = "";
+ generateForm.statementMonth = "";
+ generateForm.openingBalance = 0;
+ generateForm.currentPlan = 0;
+ generateForm.currentActually = 0;
+ generateForm.closingBalance = 0;
+ statementDetailLoaded.value = false;
+ salesData.value = [];
+ selectedSales.value = [];
+ generateDialogVisible.value = true;
+};
+
+const onCustomerChange = (customerId) => {
+ const customer = customerList.value.find((item) => item.id === customerId);
+ generateForm.customerName = customer?.customerName ?? "";
+ loadSalesData();
+};
+
+const onStatementMonthChange = () => {
+ loadSalesData();
+};
+
+const loadSalesData = () => {
+ if (!generateForm.customerId || !generateForm.statementMonth) {
+ salesData.value = [];
+ selectedSales.value = [];
+ statementDetailLoaded.value = false;
+ generateForm.openingBalance = 0;
+ generateForm.currentPlan = 0;
+ generateForm.currentActually = 0;
+ generateForm.closingBalance = 0;
+ return;
+ }
+
+ salesLoading.value = true;
+ selectedSales.value = [];
+ statementDetailLoaded.value = false;
+
+ getAccountStatementDetailsByMonth({
+ accountType: ACCOUNT_TYPE_RECEIVABLE,
+ customerId: generateForm.customerId,
+ statementMonth: generateForm.statementMonth,
+ })
+ .then((res) => {
+ if (res.code === 200) {
+ const data = res.data ?? {};
+ const details = data.accountStatementDetails;
+ const list = Array.isArray(details) ? details : [];
+ salesData.value = normalizeSalesRows(list);
+ applyStatementSummary(data);
+ statementDetailLoaded.value = true;
+
+ if (salesData.value.length > 0) {
+ selectAllSalesRows(true);
+ }
+ } else {
+ salesData.value = [];
+ statementDetailLoaded.value = false;
+ ElMessage.error(res.msg || "鏌ヨ瀵硅处鏄庣粏澶辫触");
+ }
+ })
+ .catch(() => {
+ salesData.value = [];
+ statementDetailLoaded.value = false;
+ ElMessage.error("鏌ヨ瀵硅处鏄庣粏澶辫触");
+ })
+ .finally(() => {
+ salesLoading.value = false;
+ });
+};
+
+const calculateSummary = () => {
+ let receivable = 0;
+ let receipt = 0;
+
+ selectedSales.value.forEach((item) => {
+ if (item.type === 1) {
+ receivable += item.amount;
+ } else if (item.type === 5) {
+ receivable -= item.amount;
+ } else if (item.type === 3) {
+ receipt += item.amount;
+ }
+ });
+
+ generateForm.currentPlan = receivable;
+ generateForm.currentActually = receipt;
+ generateForm.closingBalance = calculateEndBalance(
+ generateForm.openingBalance,
+ generateForm.currentPlan,
+ generateForm.currentActually
+ );
+};
+
+const handleSalesSelectionChange = (selection) => {
+ selectedSales.value = selection;
+ calculateSummary();
+};
+
+const confirmGenerate = () => {
+ if (!canGenerate.value) return;
+ submitLoading.value = true;
+ addAccountStatement(buildAddPayload())
+ .then((res) => {
+ if (res.code === 200) {
+ generateDialogVisible.value = false;
+ ElMessage.success("瀵硅处鍗曠敓鎴愭垚鍔�");
+ pagination.currentPage = 1;
+ getTableData();
+ } else {
+ ElMessage.error(res.msg || "鐢熸垚澶辫触");
+ }
+ })
+ .catch(() => {
+ ElMessage.error("鐢熸垚澶辫触");
+ })
+ .finally(() => {
+ submitLoading.value = false;
+ });
+};
+
+const handleDelete = (row) => {
+ ElMessageBox.confirm(`纭鍒犻櫎瀵硅处鍗曘��${row.statementNumber || row.id}銆嶅悧锛焋, "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ }).then(() => {
+ deleteAccountStatement([row.id])
+ .then((res) => {
+ if (res.code === 200) {
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ getTableData();
+ } else {
+ ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+ }
+ })
+ .catch(() => {
+ ElMessage.error("鍒犻櫎澶辫触");
+ });
+ });
+};
+
+const buildDetailTableFromApi = (data, statementMonth) => {
+ const details = Array.isArray(data.accountStatementDetails) ? data.accountStatementDetails : [];
+ let runningBalance = Number(data.openingBalance ?? 0);
+ const rows = [
+ {
+ date: statementMonth ?? "",
+ type: "鏈熷垵",
+ code: "-",
+ debit: 0,
+ credit: 0,
+ balance: runningBalance,
+ remark: "鏈熷垵浣欓",
+ },
+ ];
+
+ details.forEach((item) => {
+ const amount = Math.abs(Number(item.amount ?? 0));
+ const type = Number(item.type);
+ let debit = 0;
+ let credit = 0;
+
+ if (type === 1) {
+ debit = amount;
+ runningBalance += amount;
+ } else if (type === 3 || type === 5) {
+ credit = amount;
+ runningBalance -= amount;
+ }
+
+ rows.push({
+ date: item.occurrenceDate ?? "",
+ type: getDetailTypeLabel(type),
+ code: item.receiptNumber ?? "",
+ debit,
+ credit,
+ balance: runningBalance,
+ remark: item.remark ?? "",
+ });
+ });
+
+ return rows;
+};
+
+const viewDetail = (row) => {
+ if (!row.customerId || !row.statementMonth) {
+ ElMessage.warning("缂哄皯瀹㈡埛鎴栧璐︽湀浠斤紝鏃犳硶鏌ヨ鏄庣粏");
+ return;
+ }
+
+ currentCustomer.value = row.customerName ?? "";
+ currentPeriod.value = row.statementMonth ?? "";
+ detailData.value = [];
+ detailDialogVisible.value = true;
+ detailLoading.value = true;
+
+ getAccountStatementDetailsByMonth({
+ accountType: ACCOUNT_TYPE_RECEIVABLE,
+ customerId: row.customerId,
+ statementMonth: row.statementMonth,
+ })
+ .then((res) => {
+ if (res.code === 200) {
+ detailData.value = buildDetailTableFromApi(res.data ?? {}, row.statementMonth);
+ } else {
+ ElMessage.error(res.msg || "鏌ヨ鏄庣粏澶辫触");
+ detailDialogVisible.value = false;
+ }
+ })
+ .catch(() => {
+ ElMessage.error("鏌ヨ鏄庣粏澶辫触");
+ detailDialogVisible.value = false;
+ })
+ .finally(() => {
+ detailLoading.value = false;
+ });
+};
+
+const printStatement = (row) => {
+ ElMessage.info(`鎵撳嵃瀵硅处鍗�: ${row.statementNumber}`);
+};
+
+const printDetail = () => {
+ ElMessage.info("鎵撳嵃鏄庣粏");
+};
+
+const handleOut = () => {
+ const params = buildExportParams();
+ proxy.download("/accountStatement/exportAccountStatement", params, `搴旀敹瀵硅处鍗昣${Date.now()}.xlsx`);
+};
+
+onMounted(() => {
+ getCustomerList();
+ getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 15px;
+}
+
+.text-success {
+ color: #67c23a;
+}
+
+.text-danger {
+ color: #f56c6c;
+}
+
+.text-primary {
+ color: #409eff;
+}
+
+.statement-header {
+ text-align: center;
+ margin-bottom: 20px;
+ h3 {
+ margin: 0 0 10px 0;
+ }
+ p {
+ color: #909399;
+ margin: 0;
+ }
+}
+
+.sales-section {
+ margin-top: 20px;
+
+ .section-title {
+ font-size: 16px;
+ font-weight: bold;
+ margin-bottom: 15px;
+ padding-left: 10px;
+ border-left: 4px solid #409eff;
+ }
+}
+
+.summary-row {
+ display: flex;
+ justify-content: space-around;
+ padding: 15px;
+ background-color: #f5f7fa;
+ border-radius: 4px;
+ margin-top: 15px;
+
+ span {
+ font-size: 14px;
+
+ strong {
+ font-size: 16px;
+ margin-left: 5px;
+ }
+ }
+}
+
+.empty-tip {
+ margin-top: 30px;
+}
+</style>
--
Gitblit v1.9.3