Commit 735854dffdf6cd1afa05918b7882d93dfdb7585b
1 parent
3fcc4455
chore: 为发票和银行流水页面添加导出按钮
在发票和银行流水页面添加了导出按钮,该按钮允许用户选择所需的数据并将其导出为Excel文件。使用了messageApi来显示导出过程的加载状态。 增加了optionRender属性来在搜索配置中添加导出按钮,并确保按钮位于搜索区域的右侧。 服务端点和文件: - 在`index.tsx`文件的Invoice页面中添加了导出功能。 - 在`index.tsx`文件的InvoiceVerification页面中添加了导出功能。 - 更新了`definition.ts`文件,对现有的类型定义没有做出修改,保持了一致性。与订单状态和流水号相关的配置。权限管理与页面加载优化 - 更新了发票和银行流水页面的权限控制逻辑,现在基于用户权限动态渲染操作按钮。 - 重构了分页设置,采用了更灵活的分页选项配置。 -优化了核销逻辑的判断条件,提高了代码的可读性。- 在发票和银行流水页面的组件中应用了新的权限检查机制。 - 调整了数据请求逻辑,以更好地处理分页和权限数据。 另外,调整了路由配置,扩展了相关页面的访问权限,以适应更多用户角色。 BREAKING CHANGE: 动态权限控制逻辑的更新可能会影响依赖于之前静态按钮配置的代码。请检查相关组件以确保兼容性。
Showing
7 changed files
with
109 additions
and
31 deletions
.umirc.ts
@@ -75,14 +75,14 @@ export default defineConfig({ | @@ -75,14 +75,14 @@ export default defineConfig({ | ||
75 | name: '发票核销', | 75 | name: '发票核销', |
76 | path: 'invoice', | 76 | path: 'invoice', |
77 | icon: 'BookOutlined', | 77 | icon: 'BookOutlined', |
78 | - access: 'canReadAdminAndFinance', | 78 | + access: 'canReadAdminAndFinanceAndSales', |
79 | component: './Invoice/Invoice', | 79 | component: './Invoice/Invoice', |
80 | }, | 80 | }, |
81 | { | 81 | { |
82 | name: '银行流水', | 82 | name: '银行流水', |
83 | path: 'invoiceVerification', | 83 | path: 'invoiceVerification', |
84 | icon: 'BookOutlined', | 84 | icon: 'BookOutlined', |
85 | - access: 'canReadAdminAndFinance', | 85 | + access: 'canReadAdminAndFinanceAndSales', |
86 | component: './Invoice/InvoiceVerification', | 86 | component: './Invoice/InvoiceVerification', |
87 | }, | 87 | }, |
88 | { | 88 | { |
src/pages/Invoice/Invoice/components/AddBankStatementModal.tsx
@@ -24,6 +24,11 @@ export default ({ getRows, onFinish }) => { | @@ -24,6 +24,11 @@ export default ({ getRows, onFinish }) => { | ||
24 | dataIndex: 'serialNumber', | 24 | dataIndex: 'serialNumber', |
25 | }, | 25 | }, |
26 | { | 26 | { |
27 | + title: '流水号', | ||
28 | + hideInTable: true, | ||
29 | + dataIndex: 'serialNumber', | ||
30 | + }, | ||
31 | + { | ||
27 | title: '收款时间', | 32 | title: '收款时间', |
28 | dataIndex: 'collectionDatetime', | 33 | dataIndex: 'collectionDatetime', |
29 | hideInSearch: true, | 34 | hideInSearch: true, |
src/pages/Invoice/Invoice/components/InvoiceVerificationModal.tsx
@@ -20,7 +20,6 @@ export default ({ invoiceId, setVisible, onClose }) => { | @@ -20,7 +20,6 @@ export default ({ invoiceId, setVisible, onClose }) => { | ||
20 | const [bankChooseModalVisible, setBankChooseModalVisible] = useState(false); | 20 | const [bankChooseModalVisible, setBankChooseModalVisible] = useState(false); |
21 | const [invoiceInfo, setInvoiceInfo] = useState({}); | 21 | const [invoiceInfo, setInvoiceInfo] = useState({}); |
22 | const [relationOrderIds, setRelationOrderIds] = useState([]); | 22 | const [relationOrderIds, setRelationOrderIds] = useState([]); |
23 | - const [setRelationBankStatements] = useState([]); | ||
24 | const actionRef = useRef<ActionType>(); | 23 | const actionRef = useRef<ActionType>(); |
25 | 24 | ||
26 | const loadInvoiceData = async () => { | 25 | const loadInvoiceData = async () => { |
@@ -31,7 +30,6 @@ export default ({ invoiceId, setVisible, onClose }) => { | @@ -31,7 +30,6 @@ export default ({ invoiceId, setVisible, onClose }) => { | ||
31 | setInvoiceInfo(res.data); | 30 | setInvoiceInfo(res.data); |
32 | setRelationOrderIds(res.data.mainOrderIds); | 31 | setRelationOrderIds(res.data.mainOrderIds); |
33 | console.log('bs:' + res.data.bankStatementDtos); | 32 | console.log('bs:' + res.data.bankStatementDtos); |
34 | - setRelationBankStatements(res.data.bankStatementDtos); | ||
35 | } | 33 | } |
36 | }; | 34 | }; |
37 | 35 | ||
@@ -117,6 +115,18 @@ export default ({ invoiceId, setVisible, onClose }) => { | @@ -117,6 +115,18 @@ export default ({ invoiceId, setVisible, onClose }) => { | ||
117 | }, | 115 | }, |
118 | { | 116 | { |
119 | key: '11', | 117 | key: '11', |
118 | + label: '订单类型', | ||
119 | + children: invoiceInfo?.orderTypeText, | ||
120 | + span: 12, | ||
121 | + }, | ||
122 | + { | ||
123 | + key: '12', | ||
124 | + label: '绑定流水号', | ||
125 | + children: invoiceInfo?.serialNumbersTextByOrder, | ||
126 | + span: 12, | ||
127 | + }, | ||
128 | + { | ||
129 | + key: '13', | ||
120 | label: '备注', | 130 | label: '备注', |
121 | children: invoiceInfo?.notes, | 131 | children: invoiceInfo?.notes, |
122 | span: 24, | 132 | span: 24, |
src/pages/Invoice/Invoice/components/invoiceWriteOffModal.tsx
@@ -30,24 +30,29 @@ export default ({ getData, triggerButton, readOnly }) => { | @@ -30,24 +30,29 @@ export default ({ getData, triggerButton, readOnly }) => { | ||
30 | { | 30 | { |
31 | title: '发票号码', | 31 | title: '发票号码', |
32 | dataIndex: 'invoiceNumber', | 32 | dataIndex: 'invoiceNumber', |
33 | + ellipsis: true, | ||
33 | }, | 34 | }, |
34 | { | 35 | { |
35 | title: '收款方', | 36 | title: '收款方', |
36 | dataIndex: 'payeeText', | 37 | dataIndex: 'payeeText', |
38 | + ellipsis: true, | ||
37 | }, | 39 | }, |
38 | { | 40 | { |
39 | title: '付款方', | 41 | title: '付款方', |
40 | dataIndex: 'purchaser', | 42 | dataIndex: 'purchaser', |
43 | + ellipsis: true, | ||
41 | }, | 44 | }, |
42 | { | 45 | { |
43 | title: '金额', | 46 | title: '金额', |
44 | dataIndex: 'money', | 47 | dataIndex: 'money', |
45 | valueType: 'money', | 48 | valueType: 'money', |
49 | + ellipsis: true, | ||
46 | }, | 50 | }, |
47 | { | 51 | { |
48 | title: '日期', | 52 | title: '日期', |
49 | dataIndex: 'invoicingTime', | 53 | dataIndex: 'invoicingTime', |
50 | valueType: 'date', | 54 | valueType: 'date', |
55 | + ellipsis: true, | ||
51 | }, | 56 | }, |
52 | ]; | 57 | ]; |
53 | if (!readOnly) { | 58 | if (!readOnly) { |
@@ -84,24 +89,29 @@ export default ({ getData, triggerButton, readOnly }) => { | @@ -84,24 +89,29 @@ export default ({ getData, triggerButton, readOnly }) => { | ||
84 | { | 89 | { |
85 | title: '流水号', | 90 | title: '流水号', |
86 | dataIndex: 'serialNumber', | 91 | dataIndex: 'serialNumber', |
92 | + ellipsis: true, | ||
87 | }, | 93 | }, |
88 | { | 94 | { |
89 | title: '收款方', | 95 | title: '收款方', |
90 | dataIndex: 'payeeText', | 96 | dataIndex: 'payeeText', |
97 | + ellipsis: true, | ||
91 | }, | 98 | }, |
92 | { | 99 | { |
93 | title: '付款方', | 100 | title: '付款方', |
94 | dataIndex: 'payer', | 101 | dataIndex: 'payer', |
102 | + ellipsis: true, | ||
95 | }, | 103 | }, |
96 | { | 104 | { |
97 | title: '金额', | 105 | title: '金额', |
98 | dataIndex: 'amount', | 106 | dataIndex: 'amount', |
99 | valueType: 'money', | 107 | valueType: 'money', |
108 | + ellipsis: true, | ||
100 | }, | 109 | }, |
101 | { | 110 | { |
102 | title: '日期', | 111 | title: '日期', |
103 | dataIndex: 'collectionDatetime', | 112 | dataIndex: 'collectionDatetime', |
104 | valueType: 'date', | 113 | valueType: 'date', |
114 | + ellipsis: true, | ||
105 | }, | 115 | }, |
106 | ]; | 116 | ]; |
107 | columns.push({ | 117 | columns.push({ |
src/pages/Invoice/Invoice/index.tsx
@@ -24,6 +24,7 @@ const InvoiceRecord = () => { | @@ -24,6 +24,7 @@ const InvoiceRecord = () => { | ||
24 | const [invoiceVerificationVisible, setInvoiceVerificationVisible] = | 24 | const [invoiceVerificationVisible, setInvoiceVerificationVisible] = |
25 | useState(false); | 25 | useState(false); |
26 | const [invoiceId, setInvoiceId] = useState(undefined); | 26 | const [invoiceId, setInvoiceId] = useState(undefined); |
27 | + const [perms, setPerms] = useState([]); | ||
27 | const [messageApi, contextHolder] = message.useMessage(); | 28 | const [messageApi, contextHolder] = message.useMessage(); |
28 | const reloadInvoiceTable = () => { | 29 | const reloadInvoiceTable = () => { |
29 | invoiceActionRef.current?.reload(); | 30 | invoiceActionRef.current?.reload(); |
@@ -101,7 +102,7 @@ const InvoiceRecord = () => { | @@ -101,7 +102,7 @@ const InvoiceRecord = () => { | ||
101 | width: 160, | 102 | width: 160, |
102 | render: (text, record) => { | 103 | render: (text, record) => { |
103 | let btns = []; | 104 | let btns = []; |
104 | - if (!record.writeOffId) { | 105 | + if (record.paths?.includes('writeOff') && !record.writeOffId) { |
105 | btns.push( | 106 | btns.push( |
106 | <InvoiceWriteOffModal | 107 | <InvoiceWriteOffModal |
107 | getData={() => { | 108 | getData={() => { |
@@ -120,7 +121,7 @@ const InvoiceRecord = () => { | @@ -120,7 +121,7 @@ const InvoiceRecord = () => { | ||
120 | ); | 121 | ); |
121 | } | 122 | } |
122 | 123 | ||
123 | - if (record.writeOffId) { | 124 | + if (record.paths?.includes('writeOff') && record.writeOffId) { |
124 | btns.push( | 125 | btns.push( |
125 | <InvoiceWriteOffModal | 126 | <InvoiceWriteOffModal |
126 | getData={async () => { | 127 | getData={async () => { |
@@ -192,13 +193,14 @@ const InvoiceRecord = () => { | @@ -192,13 +193,14 @@ const InvoiceRecord = () => { | ||
192 | actionRef={invoiceActionRef} | 193 | actionRef={invoiceActionRef} |
193 | cardBordered | 194 | cardBordered |
194 | pagination={{ | 195 | pagination={{ |
195 | - pageSize: 10, | 196 | + pageSizeOptions: ['10', '20', '50', '100'], |
196 | }} | 197 | }} |
197 | request={async (params) => { | 198 | request={async (params) => { |
198 | const res = await postServiceInvoiceQueryInvoice({ | 199 | const res = await postServiceInvoiceQueryInvoice({ |
199 | data: { ...params }, | 200 | data: { ...params }, |
200 | }); | 201 | }); |
201 | if (res) { | 202 | if (res) { |
203 | + setPerms(res?.data?.specialPath); | ||
202 | return { | 204 | return { |
203 | data: res?.data?.data || [], | 205 | data: res?.data?.data || [], |
204 | total: res?.data?.total || 0, | 206 | total: res?.data?.total || 0, |
@@ -254,18 +256,26 @@ const InvoiceRecord = () => { | @@ -254,18 +256,26 @@ const InvoiceRecord = () => { | ||
254 | headerTitle="发票列表" | 256 | headerTitle="发票列表" |
255 | scroll={{ x: 1400, y: 360 }} | 257 | scroll={{ x: 1400, y: 360 }} |
256 | toolBarRender={() => [ | 258 | toolBarRender={() => [ |
257 | - <AddInvoiceDrawerForm | ||
258 | - onClose={() => { | ||
259 | - invoiceActionRef.current?.reload(); | ||
260 | - }} | ||
261 | - key="add" | ||
262 | - ></AddInvoiceDrawerForm>, | ||
263 | - <InvoiceWriteOffModal | ||
264 | - readOnly={false} | ||
265 | - getData={() => ({})} | ||
266 | - key="writeOff" | ||
267 | - triggerButton={<Button type="primary">核销</Button>} | ||
268 | - />, | 259 | + <> |
260 | + {perms.includes('add') && ( | ||
261 | + <AddInvoiceDrawerForm | ||
262 | + onClose={() => { | ||
263 | + invoiceActionRef.current?.reload(); | ||
264 | + }} | ||
265 | + key="add" | ||
266 | + ></AddInvoiceDrawerForm> | ||
267 | + )} | ||
268 | + </>, | ||
269 | + <> | ||
270 | + {perms.includes('writeOff') && ( | ||
271 | + <InvoiceWriteOffModal | ||
272 | + readOnly={false} | ||
273 | + getData={() => ({})} | ||
274 | + key="writeOff" | ||
275 | + triggerButton={<Button type="primary">核销</Button>} | ||
276 | + /> | ||
277 | + )} | ||
278 | + </>, | ||
269 | ]} | 279 | ]} |
270 | /> | 280 | /> |
271 | 281 |
src/pages/Invoice/InvoiceVerification/index.tsx
@@ -30,6 +30,7 @@ const InvoiceRecord = () => { | @@ -30,6 +30,7 @@ const InvoiceRecord = () => { | ||
30 | const [bankImportModalVisible, setBankImportModalVisible] = useState(false); | 30 | const [bankImportModalVisible, setBankImportModalVisible] = useState(false); |
31 | const [invoiceVerificationVisible, setInvoiceVerificationVisible] = | 31 | const [invoiceVerificationVisible, setInvoiceVerificationVisible] = |
32 | useState(false); | 32 | useState(false); |
33 | + const [perms, setPerms] = useState([]); | ||
33 | const [messageApi, contextHolder] = message.useMessage(); | 34 | const [messageApi, contextHolder] = message.useMessage(); |
34 | const [invoiceId] = useState(undefined); | 35 | const [invoiceId] = useState(undefined); |
35 | const [invoiceRecordDetailVisible, setInvoiceRecordDetailVisible] = | 36 | const [invoiceRecordDetailVisible, setInvoiceRecordDetailVisible] = |
@@ -137,7 +138,7 @@ const InvoiceRecord = () => { | @@ -137,7 +138,7 @@ const InvoiceRecord = () => { | ||
137 | ); | 138 | ); |
138 | } | 139 | } |
139 | 140 | ||
140 | - if (record.writeOffId !== null) { | 141 | + if (record.paths?.includes('writeOff') && record.writeOffId !== null) { |
141 | btns.push( | 142 | btns.push( |
142 | <InvoiceWriteOffModal | 143 | <InvoiceWriteOffModal |
143 | getData={async () => { | 144 | getData={async () => { |
@@ -192,7 +193,7 @@ const InvoiceRecord = () => { | @@ -192,7 +193,7 @@ const InvoiceRecord = () => { | ||
192 | actionRef={bankActionRef} | 193 | actionRef={bankActionRef} |
193 | cardBordered | 194 | cardBordered |
194 | pagination={{ | 195 | pagination={{ |
195 | - pageSize: 10, | 196 | + pageSizeOptions: ['10', '20', '50', '100'], |
196 | }} | 197 | }} |
197 | editable={{ | 198 | editable={{ |
198 | type: 'multiple', | 199 | type: 'multiple', |
@@ -209,6 +210,7 @@ const InvoiceRecord = () => { | @@ -209,6 +210,7 @@ const InvoiceRecord = () => { | ||
209 | data: { ...params }, | 210 | data: { ...params }, |
210 | }); | 211 | }); |
211 | if (res) { | 212 | if (res) { |
213 | + setPerms(res?.data?.specialPath); | ||
212 | return { | 214 | return { |
213 | data: res?.data?.data || [], | 215 | data: res?.data?.data || [], |
214 | total: res?.data?.total || 0, | 216 | total: res?.data?.total || 0, |
@@ -264,16 +266,20 @@ const InvoiceRecord = () => { | @@ -264,16 +266,20 @@ const InvoiceRecord = () => { | ||
264 | headerTitle="银行流水列表" | 266 | headerTitle="银行流水列表" |
265 | scroll={{ x: 1400, y: 360 }} | 267 | scroll={{ x: 1400, y: 360 }} |
266 | toolBarRender={() => [ | 268 | toolBarRender={() => [ |
267 | - <Button | ||
268 | - key="button" | ||
269 | - icon={<PlusOutlined />} | ||
270 | - onClick={() => { | ||
271 | - setBankImportModalVisible(true); | ||
272 | - }} | ||
273 | - type="primary" | ||
274 | - > | ||
275 | - 导入 | ||
276 | - </Button>, | 269 | + <> |
270 | + {perms.includes('writeOff') && ( | ||
271 | + <Button | ||
272 | + key="button" | ||
273 | + icon={<PlusOutlined />} | ||
274 | + onClick={() => { | ||
275 | + setBankImportModalVisible(true); | ||
276 | + }} | ||
277 | + type="primary" | ||
278 | + > | ||
279 | + 导入 | ||
280 | + </Button> | ||
281 | + )} | ||
282 | + </>, | ||
277 | ]} | 283 | ]} |
278 | /> | 284 | /> |
279 | 285 |
src/pages/Invoice/constant.tsx
@@ -78,6 +78,43 @@ export const INVOICE_COLUMNS = [ | @@ -78,6 +78,43 @@ export const INVOICE_COLUMNS = [ | ||
78 | hideInTable: true, | 78 | hideInTable: true, |
79 | }, | 79 | }, |
80 | { | 80 | { |
81 | + title: '订单状态', | ||
82 | + dataIndex: 'orderTypeText', | ||
83 | + valueType: 'text', | ||
84 | + width: 180, | ||
85 | + }, | ||
86 | + { | ||
87 | + title: '绑定流水号', | ||
88 | + dataIndex: 'serialNumbersTextByOrder', | ||
89 | + hideInSearch: true, | ||
90 | + valueType: 'text', | ||
91 | + width: 180, | ||
92 | + }, | ||
93 | + { | ||
94 | + title: '是否预付款', | ||
95 | + dataIndex: 'orderIsPrePay', | ||
96 | + valueType: 'select', | ||
97 | + valueEnum: { | ||
98 | + true: { | ||
99 | + text: '是', | ||
100 | + status: true, | ||
101 | + }, | ||
102 | + false: { | ||
103 | + text: '否', | ||
104 | + status: false, | ||
105 | + }, | ||
106 | + }, | ||
107 | + hideInTable: true, | ||
108 | + width: 180, | ||
109 | + }, | ||
110 | + { | ||
111 | + title: '绑定流水号', | ||
112 | + dataIndex: 'serialNumberLike', | ||
113 | + hideInTable: true, | ||
114 | + valueType: 'text', | ||
115 | + width: 180, | ||
116 | + }, | ||
117 | + { | ||
81 | title: '购买方', | 118 | title: '购买方', |
82 | dataIndex: 'purchaser', | 119 | dataIndex: 'purchaser', |
83 | valueType: 'text', | 120 | valueType: 'text', |