回筐导出
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
import { downloadBlob } from '@/api/common/download.ts';
|
||||
|
||||
/**
|
||||
* 汇总导出回筐记录:行=日期(同日记录合并),列=门店,
|
||||
* 单元格为抵扣(附加)金额,含行合计/列合计,当天门店无记录填 0
|
||||
*
|
||||
* @param storeIds 门店ID列表,空数组=全部门店
|
||||
*/
|
||||
export async function exportContainerReturns(startDate: string, endDate: string, storeIds: number[]) {
|
||||
return downloadBlob(
|
||||
'/recon/container-return/export',
|
||||
{
|
||||
start_date: startDate,
|
||||
end_date: endDate,
|
||||
...(storeIds.length > 0 ? { store_ids: storeIds.join(',') } : {}),
|
||||
},
|
||||
'回筐记录.xlsx'
|
||||
);
|
||||
}
|
||||
@@ -1,12 +1,23 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Typography } from 'antd';
|
||||
import { Button, DatePicker, Form, Modal, Select, Typography } from 'antd';
|
||||
import { DownloadOutlined } from '@ant-design/icons';
|
||||
import dayjs from 'dayjs';
|
||||
import XinTable from '@/components/XinTable';
|
||||
import type { XinTableColumn, XinTableProps } from '@/components/XinTable/typings.ts';
|
||||
import type IContainerReturn from '@/domain/iContainerReturn.ts';
|
||||
import { getStoreOptions } from '@/api/customer/store.ts';
|
||||
import { exportContainerReturns } from '@/api/recon/containerReturn.ts';
|
||||
import type IStore from '@/domain/iStore.ts';
|
||||
import AuthButton from '@/components/AuthButton';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
/** 汇总导出表单值 */
|
||||
interface ExportFormValues {
|
||||
date_range: [dayjs.Dayjs, dayjs.Dayjs];
|
||||
store_ids?: number[];
|
||||
}
|
||||
|
||||
/** 有符号数量展示:正数=压筐(橙色 +N),负数=回筐(绿色 N),0 置灰 */
|
||||
const SignedNum: React.FC<{ value?: number }> = ({ value }) => {
|
||||
@@ -39,10 +50,31 @@ const SignedAmount: React.FC<{ value?: string }> = ({ value }) => {
|
||||
const ContainerReturnPage: React.FC = () => {
|
||||
const [stores, setStores] = useState<IStore[]>([]);
|
||||
|
||||
// 汇总导出(日期区间 + 门店:行=日期,列=门店,单元格为抵扣/附加金额)
|
||||
const [exportOpen, setExportOpen] = useState(false);
|
||||
const [exporting, setExporting] = useState(false);
|
||||
const [exportForm] = Form.useForm<ExportFormValues>();
|
||||
|
||||
useEffect(() => {
|
||||
getStoreOptions().then((res) => setStores(res.data.data ?? []));
|
||||
}, []);
|
||||
|
||||
/** 提交汇总导出:下载失败时 downloadBlob 内部已提示 */
|
||||
const handleExport = async (values: ExportFormValues) => {
|
||||
const [start, end] = values.date_range;
|
||||
setExporting(true);
|
||||
try {
|
||||
await exportContainerReturns(
|
||||
start.format('YYYY-MM-DD'),
|
||||
end.format('YYYY-MM-DD'),
|
||||
values.store_ids ?? []
|
||||
);
|
||||
setExportOpen(false);
|
||||
} finally {
|
||||
setExporting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const columns: XinTableColumn<IContainerReturn>[] = [
|
||||
{
|
||||
title: '门店',
|
||||
@@ -143,6 +175,17 @@ const ContainerReturnPage: React.FC = () => {
|
||||
editShow: false,
|
||||
deleteShow: false,
|
||||
formProps: false,
|
||||
toolBarRender: (dom) => [
|
||||
<AuthButton key="export" auth="recon.containerReturn.export">
|
||||
<Button icon={<DownloadOutlined />} onClick={() => setExportOpen(true)}>
|
||||
导出
|
||||
</Button>
|
||||
</AuthButton>,
|
||||
dom.columnSetting,
|
||||
dom.hideBorder,
|
||||
dom.reload,
|
||||
dom.columnHeight,
|
||||
],
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -150,10 +193,55 @@ const ContainerReturnPage: React.FC = () => {
|
||||
<div className="mb-5">
|
||||
<Title level={3}>回筐记录</Title>
|
||||
<Text type="secondary">
|
||||
周转筐/托盘跟账单走:生成账单时按填写数量自动写入;正数=压筐(附加金额),负数=回筐(抵扣金额),数量为 0 不生成记录。
|
||||
周转筐/托盘跟账单走:生成账单时按填写数量自动写入;正数=压筐(附加金额),负数=回筐(抵扣金额),数量为 0 不生成记录;
|
||||
可按日期区间与门店汇总导出(行=日期,列=门店,含行列合计)。
|
||||
</Text>
|
||||
</div>
|
||||
<XinTable<IContainerReturn> {...tableProps} />
|
||||
|
||||
{/* 汇总导出:日期区间 + 门店,同日记录合并,无记录填 0 */}
|
||||
<Modal
|
||||
title="导出回筐记录"
|
||||
open={exportOpen}
|
||||
onCancel={() => setExportOpen(false)}
|
||||
onOk={() => exportForm.submit()}
|
||||
confirmLoading={exporting}
|
||||
okText="导出"
|
||||
destroyOnHidden
|
||||
>
|
||||
<div className="py-2 text-gray-500">
|
||||
按日期区间与门店导出抵扣(附加)金额汇总表:行=日期(同日记录合并),列=门店,
|
||||
当天门店无记录填 0,含行合计与列合计。门店不选默认导出全部门店。
|
||||
</div>
|
||||
<Form
|
||||
form={exportForm}
|
||||
layout="vertical"
|
||||
onFinish={handleExport}
|
||||
initialValues={{
|
||||
date_range: [dayjs().startOf('month'), dayjs()],
|
||||
store_ids: [],
|
||||
}}
|
||||
>
|
||||
<Form.Item
|
||||
label="日期区间"
|
||||
name="date_range"
|
||||
rules={[{ required: true, message: '请选择日期区间' }]}
|
||||
>
|
||||
<RangePicker className="w-full" allowClear={false} />
|
||||
</Form.Item>
|
||||
<Form.Item label="门店" name="store_ids">
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
maxTagCount="responsive"
|
||||
placeholder="全部门店"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
options={stores.map((s) => ({ label: s.name, value: s.id }))}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user