账单导出

This commit is contained in:
2026-10-30 10:51:09 +08:00
parent 42a3fa00d4
commit 7366d88baf
178 changed files with 1166 additions and 898 deletions
+47 -10
View File
@@ -24,7 +24,7 @@ import type {
import type { IBill, IBillDetail, IBillGoodsItem, IBillOrder } from '@/domain/iBill.ts';
import { BILL_STATUS_MAP } from '@/domain/iBill.ts';
import { STORE_ORDER_STATUS_MAP } from '@/domain/iStoreOrder.ts';
import { exportBill, getBillDetail, payBill } from '@/api/recon/bill.ts';
import { exportBill, exportBills, getBillDetail, payBill } from '@/api/recon/bill.ts';
import { getStoreOptions } from '@/api/customer/store.ts';
import type IStore from '@/domain/iStore.ts';
import AuthButton from '@/components/AuthButton';
@@ -56,6 +56,10 @@ const BillPage: React.FC = () => {
// 单独导出(每行一张账单,账单内明细按商品合并)
const [exportingId, setExportingId] = useState<number | null>(null);
// 批量导出(同一门店合并工作表,不同门店拆分工作表)
const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
const [batchExporting, setBatchExporting] = useState(false);
useEffect(() => {
getStoreOptions().then((res) => setStores(res.data.data ?? []));
}, []);
@@ -109,6 +113,20 @@ const BillPage: React.FC = () => {
}
};
/** 批量导出:下载失败时 downloadBlob 内部已提示 */
const handleBatchExport = async () => {
if (selectedRowKeys.length === 0) {
message.warning('请先勾选要导出的账单');
return;
}
setBatchExporting(true);
try {
await exportBills(selectedRowKeys);
} finally {
setBatchExporting(false);
}
};
/** 合并商品明细列:品名/包规/单位/单价(加权平均)/数量/重量/金额 */
const itemColumns: TableProps<IBillGoodsItem>['columns'] = [
{ title: '品名', dataIndex: 'product_name', width: 160, align: 'center' },
@@ -176,27 +194,27 @@ const BillPage: React.FC = () => {
);
return (
<Table.Summary.Row>
<Table.Summary.Cell index={0} colSpan={4} align="center">
<Table.Summary.Cell index={0} colSpan={5} align="center">
<Text strong>本页合计</Text>
</Table.Summary.Cell>
<Table.Summary.Cell index={4} align="center">
<Table.Summary.Cell index={5} align="center">
<Text strong>¥{sums.product_amount.toFixed(2)}</Text>
</Table.Summary.Cell>
<Table.Summary.Cell index={5} align="center">
<Table.Summary.Cell index={6} align="center">
<Text strong>¥{sums.delivery_fee.toFixed(2)}</Text>
</Table.Summary.Cell>
<Table.Summary.Cell index={6} align="center">
<Table.Summary.Cell index={7} align="center">
<Text strong>¥{sums.added_amount.toFixed(2)}</Text>
</Table.Summary.Cell>
<Table.Summary.Cell index={7} align="center">
<Table.Summary.Cell index={8} align="center">
<Text strong type={sums.after_sale < 0 ? 'success' : undefined}>
¥{sums.after_sale.toFixed(2)}
</Text>
</Table.Summary.Cell>
<Table.Summary.Cell index={8} align="center">
<Table.Summary.Cell index={9} align="center">
<Text strong type="danger">¥{sums.total_amount.toFixed(2)}</Text>
</Table.Summary.Cell>
<Table.Summary.Cell index={9} colSpan={4} />
<Table.Summary.Cell index={10} colSpan={4} />
</Table.Summary.Row>
);
};
@@ -383,7 +401,25 @@ const BillPage: React.FC = () => {
operateRender,
formProps: false,
summary: renderListSummary,
actionBarRender: (dom) => [dom.search, dom.keywordSearch],
actionBarRender: (dom) => [
dom.search,
<AuthButton key="batchExport" auth="recon.bill.export">
<Button
type="primary"
icon={<DownloadOutlined />}
disabled={selectedRowKeys.length === 0}
loading={batchExporting}
onClick={handleBatchExport}
>
批量导出{selectedRowKeys.length > 0 ? ` (${selectedRowKeys.length})` : ''}
</Button>
</AuthButton>,
dom.keywordSearch,
],
rowSelection: {
selectedRowKeys,
onChange: (keys) => setSelectedRowKeys(keys.map(Number)),
},
toolBarRender: (dom) => [
dom.columnSetting,
dom.hideBorder,
@@ -398,7 +434,8 @@ const BillPage: React.FC = () => {
<Title level={3}>门店账单</Title>
<Text type="secondary">
采购单完成后在「采购单」页生成,每个门店单独一张;账单总金额 = 商品金额 + 配送费 + 附加金额(周转筐/托盘)+ 售后金额(可正负);
每行可单独导出为一个 Excel(账单内明细按商品合并)。
每行可单独导出为一个 Excel(账单内明细按商品合并);也可勾选多张账单批量导出,
同一门店合并在一张工作表,不同门店自动拆分为多个工作表。
</Text>
</div>
<XinTable<IBill> {...tableProps} />