Commit 54f173388c23554790a6d3dcccca3b3b2d8eb1fe
1 parent
35752d89
合并应付应收
Showing
59 changed files
with
4659 additions
and
297 deletions
src/api/project/global.ts
src/api/project/invoice.ts
... | ... | @@ -16,6 +16,7 @@ enum Api { |
16 | 16 | REUPLOADBGURL = '/order/erp/invoice_bill/reUploadBgUrl', //更新报关单 |
17 | 17 | INVOICEEXPORTRECEIPT = '/order/erp/invoice_bill/exportReceipt', //收款单导出 |
18 | 18 | SETBACKREFUNDDATE = '/order/erp/invoice_bill/setBackRefundDate', //必须回款日期 |
19 | + NOTE = '/order/erp/invoice_bill/notes', //备注 | |
19 | 20 | |
20 | 21 | PRODUCT_CREATE = '/order/erp/check_bill/create', //创建生产科应付单据 |
21 | 22 | PAYED_DATE = '/order/erp/check_bill/get_payed_date', //获取生产科应回款日期 |
... | ... | @@ -32,6 +33,7 @@ enum Api { |
32 | 33 | GETINVOICEURL_BY_ID = '/order/erp/check_bill/getInvoiceUrl_by_id', //获取扣款信息 |
33 | 34 | EXPORTRECEIPT = '/order/erp/check_bill/exportReceipt', //付款单导出 |
34 | 35 | SETPADYEDDATE = '/order/erp/check_bill/setPayedDate', //修改应付款日期 |
36 | + CHECKNOTE = '/order/erp/check_bill/notes', //备注 | |
35 | 37 | } |
36 | 38 | |
37 | 39 | export const getRefundDate = async (params: any, data?: any) => { |
... | ... | @@ -266,3 +268,17 @@ export const getSetPayedDate = async (params: any) => { |
266 | 268 | params, |
267 | 269 | }); |
268 | 270 | }; |
271 | + | |
272 | +export const getInvoiceNote = async (params: any) => { | |
273 | + return await defHttp.post<any>({ | |
274 | + url: Api.NOTE, | |
275 | + params, | |
276 | + }); | |
277 | +}; | |
278 | + | |
279 | +export const getCheckNote = async (params: any) => { | |
280 | + return await defHttp.post<any>({ | |
281 | + url: Api.CHECKNOTE, | |
282 | + params, | |
283 | + }); | |
284 | +}; | ... | ... |
src/router/routes/modules/project/finance.ts
... | ... | @@ -8,8 +8,9 @@ const finance: AppRouteModule = { |
8 | 8 | path: '/finance', |
9 | 9 | name: 'Finance', |
10 | 10 | component: LAYOUT, |
11 | - redirect: '/finance/receive', | |
11 | + redirect: '/finance', | |
12 | 12 | meta: { |
13 | + hideChildrenInMenu: true, | |
13 | 14 | orderNo: 3, |
14 | 15 | icon: 'ant-design:pay-circle-outlined', |
15 | 16 | title: '财务管理', |
... | ... | @@ -23,32 +24,42 @@ const finance: AppRouteModule = { |
23 | 24 | }, |
24 | 25 | children: [ |
25 | 26 | { |
26 | - path: 'receive', | |
27 | + path: '', | |
27 | 28 | name: 'Receive', |
28 | 29 | meta: { |
29 | - title: '应收款', | |
30 | + title: '财务管理', | |
30 | 31 | roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], |
31 | 32 | ignoreKeepAlive: false, |
32 | 33 | }, |
33 | - component: () => import('/@/views/project/finance/receive/index.vue'), | |
34 | - }, | |
35 | - { | |
36 | - path: 'pay', | |
37 | - name: 'Pay', | |
38 | - meta: { | |
39 | - title: '应付款', | |
40 | - ignoreKeepAlive: true, | |
41 | - roles: [ | |
42 | - RoleEnum.ADMIN, | |
43 | - RoleEnum.FINANCE, | |
44 | - RoleEnum.TRACKER, | |
45 | - RoleEnum.BUSINESS, | |
46 | - RoleEnum.PRODUCE, | |
47 | - RoleEnum.DATA_REPORT_USER, | |
48 | - ], | |
49 | - }, | |
50 | - component: () => import('/@/views/project/finance/pay/index.vue'), | |
34 | + component: () => import('/@/views/project/finance/index.vue'), | |
51 | 35 | }, |
36 | + // { | |
37 | + // path: 'receive', | |
38 | + // name: 'Receive', | |
39 | + // meta: { | |
40 | + // title: '应收款', | |
41 | + // roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
42 | + // ignoreKeepAlive: false, | |
43 | + // }, | |
44 | + // component: () => import('/@/views/project/finance/receive/index.vue'), | |
45 | + // }, | |
46 | + // { | |
47 | + // path: 'pay', | |
48 | + // name: 'Pay', | |
49 | + // meta: { | |
50 | + // title: '应付款', | |
51 | + // ignoreKeepAlive: true, | |
52 | + // roles: [ | |
53 | + // RoleEnum.ADMIN, | |
54 | + // RoleEnum.FINANCE, | |
55 | + // RoleEnum.TRACKER, | |
56 | + // RoleEnum.BUSINESS, | |
57 | + // RoleEnum.PRODUCE, | |
58 | + // RoleEnum.DATA_REPORT_USER, | |
59 | + // ], | |
60 | + // }, | |
61 | + // component: () => import('/@/views/project/finance/pay/index.vue'), | |
62 | + // }, | |
52 | 63 | ], |
53 | 64 | }; |
54 | 65 | ... | ... |
src/store/modules/data.ts
... | ... | @@ -50,7 +50,6 @@ export const useDataStore = defineStore({ |
50 | 50 | async getFetchChartData(): Promise<any> { |
51 | 51 | try { |
52 | 52 | const data = await getChartData(); |
53 | - console.log(data, '5656chartData'); | |
54 | 53 | const x = [], |
55 | 54 | y = []; |
56 | 55 | data.forEach((value) => { |
... | ... | @@ -58,7 +57,6 @@ export const useDataStore = defineStore({ |
58 | 57 | y.push(value.orderCount); |
59 | 58 | }); |
60 | 59 | this.chartData = { x, y }; |
61 | - console.log(this.getChartData, '5656 this.chartData'); | |
62 | 60 | } catch (error) { |
63 | 61 | return Promise.reject(error); |
64 | 62 | } | ... | ... |
src/utils/pdfShow.ts
... | ... | @@ -27,7 +27,7 @@ export async function downloadAndPreviewPDF(url) { |
27 | 27 | export const view = (url) => { |
28 | 28 | const { VITE_ALIYUN_OSS_DOMAIN } = getAppEnvConfig(); |
29 | 29 | if (url) { |
30 | - url = url.replace('https://test-alterego.oss-cn-qingdao.aliyuncs.com', '/aliyun-oss-pdf'); | |
30 | + url = url.replace('https://alterego.oss-cn-qingdao.aliyuncs.com', '/aliyun-oss-pdf'); | |
31 | 31 | } |
32 | 32 | downloadAndPreviewPDF(url); |
33 | 33 | }; | ... | ... |
src/views/project/approve/FieldPanel.vue
src/views/project/approve/PayPanel.vue
... | ... | @@ -6,8 +6,8 @@ |
6 | 6 | <img |
7 | 7 | :width="50" |
8 | 8 | :height="50" |
9 | - :src="record?.orderBaseInfo?.smallPicUrl" | |
10 | - @click="handlePreview(record?.orderBaseInfo?.picUrl)" | |
9 | + :src="record?.producePaymentCheckBillFieldVO?.smallPicUrl" | |
10 | + @click="handlePreview(record?.producePaymentCheckBillFieldVO?.picUrl)" | |
11 | 11 | /> |
12 | 12 | </template> |
13 | 13 | <template v-if="column.key === 'action'"> |
... | ... | @@ -229,9 +229,9 @@ |
229 | 229 | customRender: (column) => { |
230 | 230 | const { record } = column || {}; |
231 | 231 | if (record?.type === 40) { |
232 | - return record?.fieldInfos?.checkBillOrderDO?.financePerson; | |
232 | + return record?.fieldInfos?.producePaymentCheckBillFieldVO?.financePerson; | |
233 | 233 | } else if (record?.type == 50) { |
234 | - return record?.fieldInfos?.checkBillOrderDO?.productionName; | |
234 | + return record?.fieldInfos?.producePaymentCheckBillFieldVO?.productionName; | |
235 | 235 | } |
236 | 236 | }, |
237 | 237 | }, |
... | ... | @@ -241,7 +241,13 @@ |
241 | 241 | width: 150, |
242 | 242 | customRender: (column) => { |
243 | 243 | const { record } = column || {}; |
244 | - return record?.orderBaseInfo?.innerNo; | |
244 | + console.log(record, '565656565'); | |
245 | + const extractedValues = ref<string[]>( | |
246 | + record?.fieldInfos?.producePaymentCheckBillFieldVO?.innerNo.map((item) => item), | |
247 | + ); | |
248 | + // projectNo.value = extractedValues.value.join(','); | |
249 | + // return record?.fieldInfos?.producePaymentCheckBillFieldVO?.innerNo[0]; | |
250 | + return extractedValues.value.join(','); | |
245 | 251 | }, |
246 | 252 | }, |
247 | 253 | { |
... | ... | @@ -263,7 +269,7 @@ |
263 | 269 | width: 150, |
264 | 270 | customRender: (column) => { |
265 | 271 | const { record } = column || {}; |
266 | - return record?.fieldInfos?.checkBillOrderDO?.productionName; | |
272 | + return record?.fieldInfos?.producePaymentCheckBillFieldVO?.productionName; | |
267 | 273 | }, |
268 | 274 | }, |
269 | 275 | ]; |
... | ... | @@ -292,7 +298,7 @@ |
292 | 298 | // }, |
293 | 299 | columns, |
294 | 300 | useSearchForm: true, |
295 | - formConfig: getFormConfig(), | |
301 | + formConfig: getFormConfig('checkNo'), | |
296 | 302 | rowKey: 'id', |
297 | 303 | actionColumn: { |
298 | 304 | width: 160, |
... | ... | @@ -334,7 +340,7 @@ |
334 | 340 | openModal(true, { data }); |
335 | 341 | id.value = data.id; |
336 | 342 | itemArray.value = []; |
337 | - mockData.value = data.fieldInfos.checkBillOrderDO; | |
343 | + mockData.value = data.fieldInfos.producePaymentCheckBillFieldVO; | |
338 | 344 | actualPayCalculate.value = mockData.value.actualPayCalculate?.toFixed(2); // 实际付款金额计算 |
339 | 345 | checkNo.value = mockData.value.checkNo; // 对账单号 |
340 | 346 | actualPayedAmount.value = mockData.value.actualPayedAmount?.toFixed(2); // 实际应付金额 | ... | ... |
src/views/project/approve/ReceivePanel.vue
... | ... | @@ -6,8 +6,8 @@ |
6 | 6 | <img |
7 | 7 | :width="50" |
8 | 8 | :height="50" |
9 | - :src="record?.orderBaseInfo?.smallPicUrl" | |
10 | - @click="handlePreview(record?.orderBaseInfo?.picUrl)" | |
9 | + :src="record?.invoiceFieldVo?.smallPicUrl" | |
10 | + @click="handlePreview(record?.invoiceFieldVo?.picUrl)" | |
11 | 11 | /> |
12 | 12 | </template> |
13 | 13 | <template v-if="column.key === 'action'"> |
... | ... | @@ -209,7 +209,7 @@ |
209 | 209 | width: 150, |
210 | 210 | customRender: (column) => { |
211 | 211 | const { record } = column || {}; |
212 | - return record?.fieldInfos?.invoiceBillOrderDO?.invoiceNo; | |
212 | + return record?.fieldInfos?.invoiceFieldVO?.invoiceNo; | |
213 | 213 | }, |
214 | 214 | }, |
215 | 215 | { |
... | ... | @@ -218,18 +218,13 @@ |
218 | 218 | width: 150, |
219 | 219 | customRender: (column) => { |
220 | 220 | const { record } = column || {}; |
221 | - return record?.orderBaseInfo?.innerNo; | |
221 | + const extractedValues = ref<string[]>( | |
222 | + record?.fieldInfos?.invoiceFieldVO?.innerNo?.map((item) => item), | |
223 | + ); | |
224 | + // return record?.invoiceFieldVo?.innerNo; | |
225 | + return extractedValues?.value?.join(','); | |
222 | 226 | }, |
223 | 227 | }, |
224 | - // { | |
225 | - // title: '内部编号', | |
226 | - // dataIndex: 'innerNo', | |
227 | - // width: 150, | |
228 | - // customRender: (column) => { | |
229 | - // const { record } = column || {}; | |
230 | - // return record?.fieldInfos?.invoiceBillOrderDO?.innerNo; | |
231 | - // }, | |
232 | - // }, | |
233 | 228 | ]; |
234 | 229 | |
235 | 230 | if (props.isApproved) { |
... | ... | @@ -256,7 +251,7 @@ |
256 | 251 | // }, |
257 | 252 | columns, |
258 | 253 | useSearchForm: true, |
259 | - formConfig: getFormConfig(), | |
254 | + formConfig: getFormConfig('invoiceNo'), | |
260 | 255 | rowKey: 'id', |
261 | 256 | actionColumn: { |
262 | 257 | width: 160, |
... | ... | @@ -274,7 +269,7 @@ |
274 | 269 | } |
275 | 270 | } |
276 | 271 | function onSelectAll(selected, selectedRows, changeRows) { |
277 | - const changeIds = changeRows.map((item) => item.id); | |
272 | + const changeIds = changeRows?.map((item) => item.id); | |
278 | 273 | if (selected) { |
279 | 274 | checkedKeys.value = [...checkedKeys.value, ...changeIds]; |
280 | 275 | } else { |
... | ... | @@ -292,7 +287,7 @@ |
292 | 287 | |
293 | 288 | async function handleDetail(data) { |
294 | 289 | openModal(true, { data }); |
295 | - mockData.value = data.fieldInfos.invoiceBillOrderDO; | |
290 | + mockData.value = data.fieldInfos.invoiceFieldVO; | |
296 | 291 | id.value = data.id; |
297 | 292 | totalPayAmount.value = mockData.value.totalPayAmount?.toFixed(2); |
298 | 293 | totalCustomerAmount.value = mockData.value.totalCustomerAmount?.toFixed(2); | ... | ... |
src/views/project/approve/data.ts
1 | 1 | import { ref } from 'vue'; |
2 | 2 | import { queryNoOptions } from '../../../api/project/order'; |
3 | 3 | |
4 | -export function getFormConfig(showFieldConfig: boolean) { | |
4 | +export function getFormConfig(showFieldConfig: string) { | |
5 | 5 | const innerNoOptions = ref([]); |
6 | 6 | return { |
7 | 7 | labelWidth: 100, |
... | ... | @@ -9,21 +9,21 @@ export function getFormConfig(showFieldConfig: boolean) { |
9 | 9 | { |
10 | 10 | field: `innerNo`, |
11 | 11 | label: `内部编号`, |
12 | - component: 'Select', | |
12 | + component: 'Input', | |
13 | 13 | colProps: { |
14 | 14 | span: 6, |
15 | 15 | }, |
16 | 16 | labelWidth: 70, |
17 | - componentProps: { | |
18 | - options: innerNoOptions, | |
19 | - showSearch: true, | |
20 | - mode: 'multiple', | |
21 | - onSearch: async (value: any) => { | |
22 | - innerNoOptions.value = await queryNoOptions('innerNo', value); | |
23 | - }, | |
24 | - }, | |
17 | + // componentProps: { | |
18 | + // options: innerNoOptions, | |
19 | + // showSearch: true, | |
20 | + // mode: 'multiple', | |
21 | + // onSearch: async (value: any) => { | |
22 | + // innerNoOptions.value = await queryNoOptions('innerNo', value); | |
23 | + // }, | |
24 | + // }, | |
25 | 25 | }, |
26 | - ...(showFieldConfig | |
26 | + ...(showFieldConfig == 'true' | |
27 | 27 | ? [ |
28 | 28 | { |
29 | 29 | field: `auditType`, |
... | ... | @@ -42,6 +42,32 @@ export function getFormConfig(showFieldConfig: boolean) { |
42 | 42 | }, |
43 | 43 | ] |
44 | 44 | : []), |
45 | + ...(showFieldConfig == 'invoiceNo' | |
46 | + ? [ | |
47 | + { | |
48 | + field: `invoiceNo`, | |
49 | + label: `invoice编号`, | |
50 | + component: 'Input', | |
51 | + colProps: { | |
52 | + span: 6, | |
53 | + }, | |
54 | + labelWidth: 140, | |
55 | + }, | |
56 | + ] | |
57 | + : []), | |
58 | + ...(showFieldConfig == 'checkNo' | |
59 | + ? [ | |
60 | + { | |
61 | + field: `checkNo`, | |
62 | + label: `checkNo编号`, | |
63 | + component: 'Input', | |
64 | + colProps: { | |
65 | + span: 6, | |
66 | + }, | |
67 | + labelWidth: 140, | |
68 | + }, | |
69 | + ] | |
70 | + : []), | |
45 | 71 | ], |
46 | 72 | }; |
47 | 73 | } | ... | ... |
src/views/project/finance/CheckDetailCheck.vue
0 → 100644
1 | +<template> | |
2 | + <template> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + title="订单信息" | |
7 | + width="60%" | |
8 | + :isDetail="true" | |
9 | + :showDetailBack="false" | |
10 | + :destroyOnClose="true" | |
11 | + > | |
12 | + <div class="p-4"> | |
13 | + <BasicTable @register="registerTable"> | |
14 | + <template #bodyCell="{ column, record }"> | |
15 | + <template v-if="column.key === 'action'"> </template> | |
16 | + <template v-if="column.key === 'picUrl'"> | |
17 | + <img :z-index="100000" :width="50" :height="50" :src="record?.smallPicUrl" /> | |
18 | + </template> | |
19 | + </template> | |
20 | + </BasicTable> | |
21 | + </div> | |
22 | + </BasicDrawer> | |
23 | + </template> | |
24 | +</template> | |
25 | +<script lang="ts" setup> | |
26 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | |
27 | + import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue'; | |
28 | + import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table'; | |
29 | + import { checkDetail } from '/@/api/project/invoice'; | |
30 | + import { useDesign } from '@/hooks/web/useDesign'; | |
31 | + | |
32 | + // const handlePreview = (url) => { | |
33 | + // createImgPreview({ imageList: [url], defaultWidth: 500 }); | |
34 | + // return false; | |
35 | + // }; | |
36 | + const columns: BasicColumn[] = [ | |
37 | + { | |
38 | + title: '客户编码', | |
39 | + dataIndex: 'customerCode', | |
40 | + width: 100, | |
41 | + }, | |
42 | + { | |
43 | + title: '项目号', | |
44 | + dataIndex: 'projectNo', | |
45 | + width: 100, | |
46 | + }, | |
47 | + { | |
48 | + title: '内部编码', | |
49 | + dataIndex: 'innerNo', | |
50 | + width: 100, | |
51 | + }, | |
52 | + { | |
53 | + title: '客户po号', | |
54 | + dataIndex: 'customerPo', | |
55 | + width: 100, | |
56 | + }, | |
57 | + { | |
58 | + title: '客户STYLE', | |
59 | + width: 150, | |
60 | + dataIndex: 'customerStyle', | |
61 | + }, | |
62 | + { | |
63 | + title: 'Model(REFERENCE)', | |
64 | + width: 150, | |
65 | + dataIndex: 'modeleLo', | |
66 | + }, | |
67 | + { | |
68 | + title: '订单图片', | |
69 | + width: 150, | |
70 | + dataIndex: 'picUrl', | |
71 | + }, | |
72 | + { | |
73 | + title: '数量', | |
74 | + width: 150, | |
75 | + dataIndex: 'orderCount', | |
76 | + }, | |
77 | + { | |
78 | + title: '生产科单价¥', | |
79 | + width: 150, | |
80 | + dataIndex: 'productionDepartmentPrice', | |
81 | + customRender: (column) => { | |
82 | + const { record } = column || {}; | |
83 | + return record?.profitAnalysisInfo?.productionDepartmentPrice?.toFixed(2); | |
84 | + // ? `¥ ${record?.profitAnalysisInfo?.productionDepartmentPrice}` | |
85 | + // : ''; | |
86 | + }, | |
87 | + }, | |
88 | + { | |
89 | + title: '生产科总价¥', | |
90 | + width: 150, | |
91 | + dataIndex: 'productionDepartmentTotalPrice', | |
92 | + customRender: (column) => { | |
93 | + const { record } = column || {}; | |
94 | + return record?.profitAnalysisInfo?.productionDepartmentTotalPrice?.toFixed(2); | |
95 | + // ? `¥ ${record?.profitAnalysisInfo?.productionDepartmentTotalPrice}` | |
96 | + // : ''; | |
97 | + }, | |
98 | + }, | |
99 | + ]; | |
100 | + const checkNo = ref(); | |
101 | + | |
102 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
103 | + // 方式1 | |
104 | + checkNo.value = data.data.checkNo; | |
105 | + // checkDetail({ checkNo: checkNo.value }); | |
106 | + }); | |
107 | + const params = ref({ | |
108 | + checkNo: checkNo.value, | |
109 | + }); | |
110 | + const [registerTable] = useTable({ | |
111 | + api: () => { | |
112 | + const res = checkDetail({ checkNo: checkNo.value }); | |
113 | + return res; | |
114 | + }, | |
115 | + columns: columns, | |
116 | + bordered: true, | |
117 | + }); | |
118 | +</script> | ... | ... |
src/views/project/finance/CheckSumCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="应付款汇总" | |
6 | + width="60%" | |
7 | + okText="导出" | |
8 | + :isDetail="true" | |
9 | + :showDetailBack="false" | |
10 | + @ok="handleOk" | |
11 | + @visible-change="handleShow" | |
12 | + > | |
13 | + <div class="p-4"> | |
14 | + <BasicTable @register="registerTable"> | |
15 | + <template #bodyCell="{ column, record }"> | |
16 | + <template v-if="column.key === 'action'"> </template> | |
17 | + </template> | |
18 | + </BasicTable> | |
19 | + </div> | |
20 | + </BasicModal> | |
21 | +</template> | |
22 | +<script lang="ts" setup> | |
23 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
24 | + import { computed, ref } from 'vue'; | |
25 | + import { checkAnalysis, exportCheckAnalysis } from '@/api/project/invoice'; | |
26 | + import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table'; | |
27 | + // 处理弹窗的确定按钮点击事件 | |
28 | + import axios from 'axios'; | |
29 | + | |
30 | + const columnsAnalysis: BasicColumn[] = [ | |
31 | + { | |
32 | + title: '生产科名称', | |
33 | + dataIndex: 'productionDepartment', | |
34 | + width: 150, | |
35 | + customRender: (res) => { | |
36 | + return res.record.exportVOS[0].productionDepartment; | |
37 | + }, | |
38 | + }, | |
39 | + { | |
40 | + title: '生产科总价汇总¥', | |
41 | + dataIndex: 'checkProductionDepartmentTotalPrice', | |
42 | + width: 150, | |
43 | + customRender: (res) => { | |
44 | + return res.record.productionDepartmentTotalPrice.toFixed(2); | |
45 | + }, | |
46 | + }, | |
47 | + { | |
48 | + title: '生产科扣款金额汇总¥', | |
49 | + dataIndex: 'deductAmount', | |
50 | + width: 160, | |
51 | + customRender: (res) => { | |
52 | + return res.record.deductAmount.toFixed(2); | |
53 | + }, | |
54 | + }, | |
55 | + { | |
56 | + title: '生产科实际应付金额¥', | |
57 | + dataIndex: 'calculateActualPayedAmount', | |
58 | + width: 160, | |
59 | + customRender: (res) => { | |
60 | + return res.record.calculateActualPayedAmount.toFixed(2); | |
61 | + }, | |
62 | + }, | |
63 | + { | |
64 | + title: '实际付款金额汇总¥', | |
65 | + dataIndex: 'actualPayedAmount', | |
66 | + width: 160, | |
67 | + customRender: (res) => { | |
68 | + return res.record.actualPayedAmount.toFixed(2); | |
69 | + }, | |
70 | + }, | |
71 | + { | |
72 | + title: '未付金额¥', | |
73 | + dataIndex: 'unPayedAmount', | |
74 | + width: 150, | |
75 | + customRender: (res) => { | |
76 | + return res.record.unPayedAmount.toFixed(2); | |
77 | + }, | |
78 | + }, | |
79 | + ]; | |
80 | + // const ids = ref<number[]>([]); | |
81 | + const ids = ref(); | |
82 | + // const res = ref(); | |
83 | + | |
84 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
85 | + // ids.value = data.data; | |
86 | + ids.value = data.data; | |
87 | + setTimeout(() => { | |
88 | + reload(); | |
89 | + }, 50); | |
90 | + }); | |
91 | + const [registerTable, { reload }] = useTable({ | |
92 | + // api: () => invoiceAnalysis({ ids: ids.value }), | |
93 | + api: async () => { | |
94 | + const res = await checkAnalysis({ ids: ids.value }); | |
95 | + // 计算合计行 | |
96 | + const sum = { | |
97 | + productionDepartmentTotalPrice: 0, | |
98 | + deductAmount: 0, | |
99 | + calculateActualPayedAmount: 0, | |
100 | + actualPayedAmount: 0, | |
101 | + unPayedAmount: 0, | |
102 | + exportVOS: res[0].exportVOS ? JSON.parse(JSON.stringify(res[0].exportVOS)) : [], | |
103 | + }; | |
104 | + | |
105 | + res.forEach((item: any) => { | |
106 | + sum.productionDepartmentTotalPrice += item.productionDepartmentTotalPrice || 0; | |
107 | + sum.deductAmount += item.deductAmount || 0; | |
108 | + sum.calculateActualPayedAmount += item.calculateActualPayedAmount || 0; | |
109 | + sum.actualPayedAmount += item.actualPayedAmount || 0; | |
110 | + sum.unPayedAmount += item.unPayedAmount || 0; | |
111 | + }); | |
112 | + if (sum.exportVOS && sum.exportVOS[0]) { | |
113 | + sum.exportVOS[0].productionDepartment = '合计'; | |
114 | + } | |
115 | + res.push(sum); | |
116 | + return res; | |
117 | + }, | |
118 | + columns: columnsAnalysis, | |
119 | + bordered: true, | |
120 | + }); | |
121 | + function handleShow(visible: boolean) { | |
122 | + reload(); | |
123 | + } | |
124 | + const searchData = ref({}); | |
125 | + async function handleOk() { | |
126 | + // 构造符合 API 要求的参数 | |
127 | + // const ids = [23]; | |
128 | + // const requestData = { | |
129 | + // ids: ids.value, | |
130 | + // }; | |
131 | + const idss = ids.value; | |
132 | + // await exportCheckAnalysis({ ids: ids }); | |
133 | + axios | |
134 | + .post( | |
135 | + '/basic-api/order/erp/check_bill/export', | |
136 | + { ids: idss }, | |
137 | + { | |
138 | + responseType: 'blob', // 设置响应类型为 'blob' | |
139 | + }, | |
140 | + ) | |
141 | + .then((response) => { | |
142 | + // 创建一个 Blob 对象来保存二进制数据 | |
143 | + const blob = new Blob([response.data], { type: 'application/zip' }); | |
144 | + const getFormattedDate = (): string => { | |
145 | + const date = new Date(); | |
146 | + | |
147 | + const year = date.getFullYear(); | |
148 | + const month = String(date.getMonth() + 1).padStart(2, '0'); | |
149 | + const day = String(date.getDate()).padStart(2, '0'); | |
150 | + | |
151 | + const hours = String(date.getHours()).padStart(2, '0'); | |
152 | + const minutes = String(date.getMinutes()).padStart(2, '0'); | |
153 | + const seconds = String(date.getSeconds()).padStart(2, '0'); | |
154 | + | |
155 | + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | |
156 | + }; | |
157 | + const date = getFormattedDate(); | |
158 | + // 创建一个链接元素用于下载 | |
159 | + const link = document.createElement('a'); | |
160 | + link.href = window.URL.createObjectURL(blob); | |
161 | + link.download = `应付款分析${date}.xlsx`; // 你可以为文件命名 | |
162 | + document.body.appendChild(link); | |
163 | + link.click(); // 自动点击链接,触发下载 | |
164 | + document.body.removeChild(link); // 下载完成后移除链接 | |
165 | + }) | |
166 | + .catch((error) => { | |
167 | + console.error(error); | |
168 | + }); | |
169 | + reload(); | |
170 | + closeModal(); | |
171 | + } | |
172 | +</script> | |
173 | +<style scoped> | |
174 | + .divAll { | |
175 | + display: flex; | |
176 | + justify-content: center; | |
177 | + align-items: center; | |
178 | + } | |
179 | +</style> | ... | ... |
src/views/project/finance/Commit.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="提交审核" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + @visible-change="handleShow" | |
10 | + > | |
11 | + 请选择日期: | |
12 | + <a-date-picker v-model:value="date" /> | |
13 | + <div style="height: 10px"></div> | |
14 | + 请选择收款单位: | |
15 | + <a-select v-model:value="payee" style="width: 100%; padding: 5px; border-radius: 4px"> | |
16 | + <option value="翱特建行城阳支行-美元(5107)">翱特建行城阳支行-美元(5107)</option> | |
17 | + <option value="吉庆建行城阳支行-美元(4820)">吉庆建行城阳支行-美元(4820)</option> | |
18 | + </a-select> | |
19 | + </BasicModal> | |
20 | +</template> | |
21 | +<script lang="ts" setup> | |
22 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
23 | + import { ref } from 'vue'; | |
24 | + import { commit } from '@/api/project/invoice'; | |
25 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
26 | + | |
27 | + const id = ref(); | |
28 | + const payee = ref(); | |
29 | + const date = ref(); | |
30 | + const emit = defineEmits(['success']); | |
31 | + const { createMessage } = useMessage(); | |
32 | + const { error } = createMessage; | |
33 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
34 | + // id.value = data.checkedKeys; | |
35 | + id.value = data.data; | |
36 | + }); | |
37 | + function handleShow(visible: boolean) { | |
38 | + if (!visible) { | |
39 | + date.value = null; | |
40 | + payee.value = null; | |
41 | + } | |
42 | + } | |
43 | + function formatDate(input: string): string { | |
44 | + // 创建一个 Date 对象 | |
45 | + const date = new Date(input); | |
46 | + | |
47 | + // 获取年月日 | |
48 | + const year = date.getFullYear(); | |
49 | + const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始,所以要加 1 | |
50 | + const day = String(date.getDate()).padStart(2, '0'); | |
51 | + | |
52 | + // 返回格式化后的日期字符串 | |
53 | + return `${year}-${month}-${day}`; | |
54 | + } | |
55 | + const isDisabled = ref(false); | |
56 | + async function handleOk() { | |
57 | + if (isDisabled.value) { | |
58 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
59 | + return; | |
60 | + } | |
61 | + const formattedDate = formatDate(date.value); | |
62 | + isDisabled.value = true; | |
63 | + setTimeout(() => { | |
64 | + isDisabled.value = false; | |
65 | + }, 3000); | |
66 | + commit({ id: id.value, actualRefundDate: formattedDate, payee: payee.value }); | |
67 | + emit('success'); | |
68 | + closeModal(); | |
69 | + } | |
70 | +</script> | ... | ... |
src/views/project/finance/CommitCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="提交审核" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + @visible-change="handleShow" | |
10 | + > | |
11 | + 请选择日期: | |
12 | + <a-date-picker v-model:value="date" /> | |
13 | + </BasicModal> | |
14 | +</template> | |
15 | +<script lang="ts" setup> | |
16 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
17 | + import { ref } from 'vue'; | |
18 | + import { checkCommit } from '@/api/project/invoice'; | |
19 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
20 | + | |
21 | + const id = ref(); | |
22 | + const date = ref(); | |
23 | + const emit = defineEmits(['success']); | |
24 | + const { createMessage } = useMessage(); | |
25 | + const { error } = createMessage; | |
26 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
27 | + id.value = data.data; | |
28 | + }); | |
29 | + function handleShow(visible: boolean) { | |
30 | + if (!visible) { | |
31 | + date.value = null; | |
32 | + } | |
33 | + } | |
34 | + function formatDate(input: string): string { | |
35 | + // 创建一个 Date 对象 | |
36 | + const date = new Date(input); | |
37 | + | |
38 | + // 获取年月日 | |
39 | + const year = date.getFullYear(); | |
40 | + const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始,所以要加 1 | |
41 | + const day = String(date.getDate()).padStart(2, '0'); | |
42 | + | |
43 | + // 返回格式化后的日期字符串 | |
44 | + return `${year}-${month}-${day}`; | |
45 | + } | |
46 | + const isDisabled = ref(false); | |
47 | + async function handleOk() { | |
48 | + if (isDisabled.value) { | |
49 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
50 | + return; | |
51 | + } | |
52 | + const formattedDate = formatDate(date.value); | |
53 | + isDisabled.value = true; | |
54 | + setTimeout(() => { | |
55 | + isDisabled.value = false; | |
56 | + }, 3000); | |
57 | + checkCommit({ id: id.value, actualPayedDate: formattedDate }); | |
58 | + emit('success'); | |
59 | + closeModal(); | |
60 | + } | |
61 | +</script> | ... | ... |
src/views/project/finance/DeductShow.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="扣款单" | |
6 | + width="700px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + > | |
10 | + <a-list item-layout="horizontal" :data-source="itemArray"> | |
11 | + <template #renderItem="{ item }"> | |
12 | + <a-list-item> | |
13 | + <a-list-item-meta> | |
14 | + <template #title> | |
15 | + <!-- <a :href="item.url" target="_blank" rel="noopener noreferrer">{{ item.name }}</a> --> | |
16 | + <!-- <a @click="openPic(item.url)">{{ item.name }}</a> --> | |
17 | + <a | |
18 | + v-if="isImageUrl(item.url)" | |
19 | + @click="openPic(item.url)" | |
20 | + style="display: flex; align-items: center" | |
21 | + > | |
22 | + <img | |
23 | + :src="item.url" | |
24 | + alt="Image" | |
25 | + style="max-width: 150px; max-height: 150px; margin-right: 10px" | |
26 | + /> | |
27 | + {{ item.name }} | |
28 | + </a> | |
29 | + <a v-else @click="openPic(item.url)">{{ item.name }}</a> | |
30 | + </template> | |
31 | + </a-list-item-meta> | |
32 | + </a-list-item> | |
33 | + </template> | |
34 | + </a-list> | |
35 | + </BasicModal> | |
36 | +</template> | |
37 | +<script lang="ts" setup> | |
38 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
39 | + import { computed, ref } from 'vue'; | |
40 | + import type { UploadProps, UploadChangeParam } from 'ant-design-vue'; | |
41 | + import { InboxOutlined } from '@ant-design/icons-vue'; | |
42 | + import { message } from 'ant-design-vue'; | |
43 | + import { getInvoiceDeductUrlById } from '@/api/project/invoice'; | |
44 | + import { view } from '@/utils/pdfShow'; | |
45 | + | |
46 | + interface Item { | |
47 | + name: string; | |
48 | + url: string; | |
49 | + } | |
50 | + | |
51 | + const list = ref(); | |
52 | + const id = ref(); | |
53 | + const itemArray = ref<Item[]>([]); | |
54 | + | |
55 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
56 | + itemArray.value = []; | |
57 | + const res = await getInvoiceDeductUrlById({ id: data.data.invoiceId }); | |
58 | + for (let item in res) { | |
59 | + const url = res[item]; | |
60 | + const name = item; | |
61 | + // 将 name 和 url 放入对象并添加到数组中 | |
62 | + itemArray.value.push({ name, url }); | |
63 | + } | |
64 | + }); | |
65 | + | |
66 | + async function handleOk() { | |
67 | + itemArray.value = []; | |
68 | + closeModal(); | |
69 | + } | |
70 | + // function openPic(url) { | |
71 | + // window.open('', '', '').document.write(`<!DOCTYPE html> | |
72 | + // <html> | |
73 | + // <body | |
74 | + // style="display: flex; | |
75 | + // justify-content: center; | |
76 | + // align-items: center;"> | |
77 | + // <img src='${url}' width="500px" height="500px"/> | |
78 | + // </body> | |
79 | + // </html>`); | |
80 | + // } | |
81 | + // 新增的函数:判断 URL 是否为图片格式 | |
82 | + function isImageUrl(url: string): boolean { | |
83 | + const imageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg']; | |
84 | + const baseUrl = url.split('?')[0]; | |
85 | + return imageExtensions.some((ext) => baseUrl.toLowerCase().endsWith(ext)); | |
86 | + } | |
87 | + // 检查 URL 是否为 PDF 格式 | |
88 | + function isPdfUrl(url: string): boolean { | |
89 | + return url.toLowerCase().endsWith('.pdf'); | |
90 | + } | |
91 | + // 打开图片或 PDF | |
92 | + function openPic(url: string) { | |
93 | + const baseUrl = url.split('?')[0]; // 获取问号前的部分 | |
94 | + if (isImageUrl(baseUrl)) { | |
95 | + window.open('', '', '').document.write(`<!DOCTYPE html> | |
96 | + <html> | |
97 | + <body style="display: flex; justify-content: center; align-items: center;"> | |
98 | + <img src='${url}' width="300px" height="auto"/> | |
99 | + </body> | |
100 | + </html>`); | |
101 | + } else if (isPdfUrl(baseUrl)) { | |
102 | + view(url); // 新标签页打开 PDF | |
103 | + } else { | |
104 | + console.log('不支持的文件类型'); | |
105 | + } | |
106 | + } | |
107 | +</script> | ... | ... |
src/views/project/finance/DeductShowCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="扣款单" | |
6 | + width="700px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + > | |
10 | + <a-list item-layout="horizontal" :data-source="itemArray"> | |
11 | + <template #renderItem="{ item }"> | |
12 | + <a-list-item> | |
13 | + <a-list-item-meta> | |
14 | + <template #title> | |
15 | + <!-- <a :href="item.url" target="_blank" rel="noopener noreferrer">{{ item.name }}</a> --> | |
16 | + <a | |
17 | + v-if="isImageUrl(item.url)" | |
18 | + @click="openPic(item.url)" | |
19 | + style="display: flex; align-items: center" | |
20 | + > | |
21 | + <img | |
22 | + :src="item.url" | |
23 | + alt="Image" | |
24 | + style="max-width: 150px; max-height: 150px; margin-right: 10px" | |
25 | + /> | |
26 | + {{ item.name }} | |
27 | + </a> | |
28 | + <a v-else @click="openPic(item.url)">{{ item.name }}</a> | |
29 | + <!-- <a @click="openPic(item.url)">{{ item.name }}</a> --> | |
30 | + </template> | |
31 | + </a-list-item-meta> | |
32 | + </a-list-item> | |
33 | + </template> | |
34 | + </a-list> | |
35 | + </BasicModal> | |
36 | +</template> | |
37 | +<script lang="ts" setup> | |
38 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
39 | + import { computed, ref } from 'vue'; | |
40 | + import type { UploadProps, UploadChangeParam } from 'ant-design-vue'; | |
41 | + import { InboxOutlined } from '@ant-design/icons-vue'; | |
42 | + import { message } from 'ant-design-vue'; | |
43 | + import { getDeductUrlById } from '@/api/project/invoice'; | |
44 | + import { view } from '@/utils/pdfShow'; | |
45 | + | |
46 | + interface Item { | |
47 | + name: string; | |
48 | + url: string; | |
49 | + } | |
50 | + | |
51 | + const list = ref(); | |
52 | + const id = ref(); | |
53 | + const itemArray = ref<Item[]>([]); | |
54 | + | |
55 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
56 | + itemArray.value = []; | |
57 | + const res = await getDeductUrlById({ id: data.data.checkId }); | |
58 | + for (let item in res) { | |
59 | + const url = res[item]; | |
60 | + const name = item; | |
61 | + // 将 name 和 url 放入对象并添加到数组中 | |
62 | + itemArray.value.push({ name, url }); | |
63 | + } | |
64 | + }); | |
65 | + | |
66 | + async function handleOk() { | |
67 | + itemArray.value = []; | |
68 | + closeModal(); | |
69 | + } | |
70 | + | |
71 | + // 新增的函数:判断 URL 是否为图片格式 | |
72 | + function isImageUrl(url: string): boolean { | |
73 | + const imageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg']; | |
74 | + const baseUrl = url.split('?')[0]; | |
75 | + return imageExtensions.some((ext) => baseUrl.toLowerCase().endsWith(ext)); | |
76 | + } | |
77 | + // 检查 URL 是否为 PDF 格式 | |
78 | + function isPdfUrl(url: string): boolean { | |
79 | + return url.toLowerCase().endsWith('.pdf'); | |
80 | + } | |
81 | + // 打开图片或 PDF | |
82 | + function openPic(url: string) { | |
83 | + const baseUrl = url.split('?')[0]; // 获取问号前的部分 | |
84 | + if (isImageUrl(baseUrl)) { | |
85 | + window.open('', '', '').document.write(`<!DOCTYPE html> | |
86 | + <html> | |
87 | + <body style="display: flex; justify-content: center; align-items: center;"> | |
88 | + <img src='${url}' width="300px" height="auto"/> | |
89 | + </body> | |
90 | + </html>`); | |
91 | + } else if (isPdfUrl(baseUrl)) { | |
92 | + view(url); // 新标签页打开 PDF | |
93 | + } else { | |
94 | + console.log('不支持的文件类型'); | |
95 | + } | |
96 | + } | |
97 | +</script> | ... | ... |
src/views/project/finance/EditRefundTime.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="修改必须回款日期" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + @visible-change="handleShow" | |
10 | + > | |
11 | + 请选择日期: | |
12 | + <a-date-picker v-model:value="date" /> | |
13 | + <div style="height: 10px"></div> | |
14 | + </BasicModal> | |
15 | +</template> | |
16 | +<script lang="ts" setup> | |
17 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
18 | + import { ref } from 'vue'; | |
19 | + import { getSetBackRefundDate } from '@/api/project/invoice'; | |
20 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
21 | + | |
22 | + const id = ref(); | |
23 | + const date = ref(); | |
24 | + const emit = defineEmits(['success']); | |
25 | + const { createMessage } = useMessage(); | |
26 | + const { error } = createMessage; | |
27 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
28 | + id.value = data.data.invoiceId; | |
29 | + }); | |
30 | + function formatDate(input: string): string { | |
31 | + // 创建一个 Date 对象 | |
32 | + const date = new Date(input); | |
33 | + | |
34 | + // 获取年月日 | |
35 | + const year = date.getFullYear(); | |
36 | + const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始,所以要加 1 | |
37 | + const day = String(date.getDate()).padStart(2, '0'); | |
38 | + | |
39 | + // 返回格式化后的日期字符串 | |
40 | + return `${year}-${month}-${day}`; | |
41 | + } | |
42 | + const isDisabled = ref(false); | |
43 | + async function handleOk() { | |
44 | + if (isDisabled.value) { | |
45 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
46 | + return; | |
47 | + } | |
48 | + const formattedDate = formatDate(date.value); | |
49 | + isDisabled.value = true; | |
50 | + setTimeout(() => { | |
51 | + isDisabled.value = false; | |
52 | + }, 3000); | |
53 | + getSetBackRefundDate({ id: id.value, backRefundDate: formattedDate }); | |
54 | + emit('success'); | |
55 | + closeModal(); | |
56 | + } | |
57 | + function handleShow(visible: boolean) { | |
58 | + if (!visible) { | |
59 | + date.value = null; | |
60 | + } | |
61 | + } | |
62 | +</script> | ... | ... |
src/views/project/finance/EditRefundTimeCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="修改应付款日期" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @visible-change="handleShow" | |
9 | + @ok="handleOk" | |
10 | + > | |
11 | + 请选择日期: | |
12 | + <a-date-picker v-model:value="date" /> | |
13 | + <div style="height: 10px"></div> | |
14 | + </BasicModal> | |
15 | +</template> | |
16 | +<script lang="ts" setup> | |
17 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
18 | + import { ref } from 'vue'; | |
19 | + import { getSetPayedDate } from '@/api/project/invoice'; | |
20 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
21 | + | |
22 | + const id = ref(); | |
23 | + const date = ref(); | |
24 | + const emit = defineEmits(['success']); | |
25 | + const { createMessage } = useMessage(); | |
26 | + const { error } = createMessage; | |
27 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
28 | + id.value = data.data.checkId; | |
29 | + }); | |
30 | + function formatDate(input: string): string { | |
31 | + // 创建一个 Date 对象 | |
32 | + const date = new Date(input); | |
33 | + | |
34 | + // 获取年月日 | |
35 | + const year = date.getFullYear(); | |
36 | + const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始,所以要加 1 | |
37 | + const day = String(date.getDate()).padStart(2, '0'); | |
38 | + | |
39 | + // 返回格式化后的日期字符串 | |
40 | + return `${year}-${month}-${day}`; | |
41 | + } | |
42 | + const isDisabled = ref(false); | |
43 | + async function handleOk() { | |
44 | + if (isDisabled.value) { | |
45 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
46 | + return; | |
47 | + } | |
48 | + const formattedDate = formatDate(date.value); | |
49 | + isDisabled.value = true; | |
50 | + setTimeout(() => { | |
51 | + isDisabled.value = false; | |
52 | + }, 3000); | |
53 | + getSetPayedDate({ id: id.value, payedDate: formattedDate }); | |
54 | + emit('success'); | |
55 | + closeModal(); | |
56 | + } | |
57 | + function handleShow(visible: boolean) { | |
58 | + if (!visible) { | |
59 | + date.value = null; | |
60 | + } | |
61 | + } | |
62 | +</script> | ... | ... |
src/views/project/finance/FinanceEdit.vue
0 → 100644
1 | +<template> | |
2 | + <template> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + title="收入款单" | |
7 | + width="30%" | |
8 | + :isDetail="true" | |
9 | + @ok="handleSubmit" | |
10 | + :showDetailBack="false" | |
11 | + okText="保存" | |
12 | + showFooter | |
13 | + :destroyOnClose="true" | |
14 | + > | |
15 | + <!-- <div> | |
16 | + <BasicForm @register="registerForm" /> | |
17 | + </div> --> | |
18 | + <div style="font-size: 15px">实际收款金额1$</div> | |
19 | + <a-input v-model:value="input1" placeholder="请输入" :disabled="status === 10" auto-size /> | |
20 | + <div style="margin: 16px 0"></div> | |
21 | + <div style="font-size: 15px">实际收款金额2$</div> | |
22 | + <a-input v-model:value="input2" placeholder="请输入" :disabled="status === 10" auto-size /> | |
23 | + <div style="margin: 16px 0"></div> | |
24 | + <div style="font-size: 15px">实际收款金额3$</div> | |
25 | + <a-input v-model:value="input3" placeholder="请输入" :disabled="status === 10" auto-size /> | |
26 | + <div style="margin: 16px 0"></div> | |
27 | + <div style="font-size: 15px">其他费用金额$</div> | |
28 | + <a-input v-model:value="input4" placeholder="请输入" :disabled="status === 10" auto-size /> | |
29 | + <div style="margin: 16px 0"></div> | |
30 | + | |
31 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | |
32 | + <template #appendFooter> | |
33 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | |
34 | + </template> | |
35 | + </BasicDrawer> | |
36 | + </template> | |
37 | +</template> | |
38 | +<script lang="ts" setup> | |
39 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | |
40 | + import { BasicForm, FormSchema, useForm } from '@/components/Form'; | |
41 | + import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue'; | |
42 | + import { getEmailList } from '/@/api/sys/config'; | |
43 | + import { updateAmount } from '@/api/project/invoice'; | |
44 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
45 | + import { ROLE } from './type.d'; | |
46 | + | |
47 | + const emit = defineEmits(['success']); | |
48 | + const role = computed(() => { | |
49 | + return user?.roleSmallVO?.code; | |
50 | + }); | |
51 | + const schemas: FormSchema[] = [ | |
52 | + // { | |
53 | + // field: 'totalPayAmount', | |
54 | + // component: 'InputNumber', | |
55 | + // labelWidth: 250, | |
56 | + // colProps: { | |
57 | + // span: 23, | |
58 | + // }, | |
59 | + // label: '实际应收金额', | |
60 | + // }, | |
61 | + { | |
62 | + field: 'actualPayedAmount1', | |
63 | + component: 'InputNumber', | |
64 | + labelWidth: 250, | |
65 | + colProps: { | |
66 | + span: 23, | |
67 | + }, | |
68 | + componentProps: () => ({ | |
69 | + disabled: status.value === 10, | |
70 | + }), | |
71 | + label: '实际应收金额1$', | |
72 | + }, | |
73 | + { | |
74 | + field: 'actualPayedAmount2', | |
75 | + component: 'InputNumber', | |
76 | + labelWidth: 250, | |
77 | + colProps: { | |
78 | + span: 23, | |
79 | + }, | |
80 | + componentProps: () => ({ | |
81 | + disabled: status.value === 10, | |
82 | + }), | |
83 | + label: '实际应收金额2$', | |
84 | + }, | |
85 | + { | |
86 | + field: 'actualPayedAmount3', | |
87 | + component: 'InputNumber', | |
88 | + labelWidth: 250, | |
89 | + colProps: { | |
90 | + span: 23, | |
91 | + }, | |
92 | + componentProps: () => ({ | |
93 | + disabled: status.value === 10, | |
94 | + }), | |
95 | + label: '实际应收金额3$', | |
96 | + }, | |
97 | + { | |
98 | + field: 'otherAmount', | |
99 | + component: 'InputNumber', | |
100 | + labelWidth: 250, | |
101 | + colProps: { | |
102 | + span: 23, | |
103 | + }, | |
104 | + componentProps: () => ({ | |
105 | + disabled: status.value === 10, | |
106 | + }), | |
107 | + label: '其他费用金额$', | |
108 | + }, | |
109 | + ]; | |
110 | + const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ | |
111 | + labelWidth: 120, | |
112 | + schemas, | |
113 | + layout: 'vertical', | |
114 | + showActionButtonGroup: false, | |
115 | + actionColOptions: { | |
116 | + span: 24, | |
117 | + }, | |
118 | + }); | |
119 | + const { createMessage } = useMessage(); | |
120 | + const { error } = createMessage; | |
121 | + | |
122 | + const update = ref(); | |
123 | + const status = ref(); | |
124 | + | |
125 | + const input1 = ref(); | |
126 | + const input2 = ref(); | |
127 | + const input3 = ref(); | |
128 | + const input4 = ref(); | |
129 | + const id = ref(); | |
130 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
131 | + // 方式1 | |
132 | + status.value = data.data.invoiceStatus; | |
133 | + id.value = data.data.invoiceId; | |
134 | + input1.value = data.data.invoiceActualPayedAmount1; | |
135 | + input2.value = data.data.invoiceActualPayedAmount2; | |
136 | + input3.value = data.data.invoiceActualPayedAmount3; | |
137 | + input4.value = data.data.invoiceOtherAmount; | |
138 | + resetFields(); | |
139 | + setDrawerProps({ confirmLoading: false }); | |
140 | + setFieldsValue({ | |
141 | + ...toRaw(data.data), | |
142 | + }); | |
143 | + update.value = data; | |
144 | + }); | |
145 | + //完成编辑 | |
146 | + async function handleSubmit() { | |
147 | + // const values = await validate(); | |
148 | + // const updatedValues = { | |
149 | + // ...values, | |
150 | + // id: update.value.data.id, | |
151 | + // bgUrl: update.value.data.bgUrl, | |
152 | + // }; | |
153 | + if (!input1.value || !input2.value || !input3.value || !input4.value) { | |
154 | + error('选项不能为空'); | |
155 | + } else { | |
156 | + await updateAmount({ | |
157 | + id: id.value, | |
158 | + actualPayedAmount1: input1.value, | |
159 | + actualPayedAmount2: input2.value, | |
160 | + actualPayedAmount3: input3.value, | |
161 | + otherAmount: input4.value, | |
162 | + }); | |
163 | + emit('success'); | |
164 | + closeDrawer(); | |
165 | + } | |
166 | + } | |
167 | +</script> | ... | ... |
src/views/project/finance/FinanceEditCheck.vue
0 → 100644
1 | +<template> | |
2 | + <template> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + title="编辑" | |
7 | + width="30%" | |
8 | + :isDetail="true" | |
9 | + @ok="handleSubmit" | |
10 | + :showDetailBack="false" | |
11 | + okText="保存" | |
12 | + showFooter | |
13 | + :destroyOnClose="true" | |
14 | + > | |
15 | + <!-- <div> | |
16 | + <BasicForm @register="registerForm" /> | |
17 | + </div> --> | |
18 | + <div style="font-size: 15px">实际付款金额1¥</div> | |
19 | + <a-input v-model:value="input1" placeholder="请输入" :disabled="status === 10" auto-size /> | |
20 | + <div style="margin: 16px 0"></div> | |
21 | + <div style="font-size: 15px">实际付款金额2¥</div> | |
22 | + <a-input v-model:value="input2" placeholder="请输入" :disabled="status === 10" auto-size /> | |
23 | + <div style="margin: 16px 0"></div> | |
24 | + <div style="font-size: 15px">实际付款金额3¥</div> | |
25 | + <a-input v-model:value="input3" placeholder="请输入" :disabled="status === 10" auto-size /> | |
26 | + <div style="margin: 16px 0"></div> | |
27 | + | |
28 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | |
29 | + <template #appendFooter> | |
30 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | |
31 | + </template> | |
32 | + </BasicDrawer> | |
33 | + </template> | |
34 | +</template> | |
35 | +<script lang="ts" setup> | |
36 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | |
37 | + import { BasicForm, FormSchema, useForm } from '@/components/Form'; | |
38 | + import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue'; | |
39 | + import { getEmailList } from '/@/api/sys/config'; | |
40 | + import { updateAmountInfo } from '@/api/project/invoice'; | |
41 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
42 | + | |
43 | + const emit = defineEmits(['success']); | |
44 | + const schemas: FormSchema[] = [ | |
45 | + // { | |
46 | + // field: 'actualPayedAmount', | |
47 | + // component: 'InputNumber', | |
48 | + // labelWidth: 250, | |
49 | + // colProps: { | |
50 | + // span: 23, | |
51 | + // }, | |
52 | + // label: '生产科实际应付金额', | |
53 | + // }, | |
54 | + { | |
55 | + field: 'actualPayedAmount1', | |
56 | + component: 'InputNumber', | |
57 | + labelWidth: 250, | |
58 | + colProps: { | |
59 | + span: 23, | |
60 | + }, | |
61 | + label: '实际应付金额1¥', | |
62 | + componentProps: () => ({ | |
63 | + disabled: status.value === 10, | |
64 | + }), | |
65 | + }, | |
66 | + { | |
67 | + field: 'actualPayedAmount2', | |
68 | + component: 'InputNumber', | |
69 | + labelWidth: 250, | |
70 | + colProps: { | |
71 | + span: 23, | |
72 | + }, | |
73 | + label: '实际应付金额2¥', | |
74 | + componentProps: () => ({ | |
75 | + disabled: status.value === 10, | |
76 | + }), | |
77 | + }, | |
78 | + { | |
79 | + field: 'actualPayedAmount3', | |
80 | + component: 'InputNumber', | |
81 | + labelWidth: 250, | |
82 | + colProps: { | |
83 | + span: 23, | |
84 | + }, | |
85 | + label: '实际应付金额3¥', | |
86 | + componentProps: () => ({ | |
87 | + disabled: status.value === 10, | |
88 | + }), | |
89 | + }, | |
90 | + ]; | |
91 | + const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ | |
92 | + labelWidth: 120, | |
93 | + schemas, | |
94 | + layout: 'vertical', | |
95 | + showActionButtonGroup: false, | |
96 | + actionColOptions: { | |
97 | + span: 24, | |
98 | + }, | |
99 | + }); | |
100 | + const { createMessage } = useMessage(); | |
101 | + const { error } = createMessage; | |
102 | + const update = ref(); | |
103 | + const status = ref(); | |
104 | + const input1 = ref(); | |
105 | + const input2 = ref(); | |
106 | + const input3 = ref(); | |
107 | + const id = ref(); | |
108 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
109 | + // 方式1 | |
110 | + resetFields(); | |
111 | + status.value = data.data.checkStatus; | |
112 | + id.value = data.data.checkId; | |
113 | + input1.value = data.data.checkActualPayedAmount1; | |
114 | + input2.value = data.data.checkActualPayedAmount2; | |
115 | + input3.value = data.data.checkActualPayedAmount3; | |
116 | + setDrawerProps({ confirmLoading: false }); | |
117 | + // 将金额格式化为两位小数 | |
118 | + // setFieldsValue({ | |
119 | + // actualPayedAmount1: | |
120 | + // data.data.actualPayedAmount1 !== null ? data.data.actualPayedAmount1.toFixed(2) : undefined, | |
121 | + // actualPayedAmount2: | |
122 | + // data.data.actualPayedAmount2 !== null ? data.data.actualPayedAmount2.toFixed(2) : undefined, | |
123 | + // actualPayedAmount3: | |
124 | + // data.data.actualPayedAmount3 !== null ? data.data.actualPayedAmount3.toFixed(2) : undefined, | |
125 | + // ...toRaw(data.data), // 其他字段 | |
126 | + // }); | |
127 | + setFieldsValue({ | |
128 | + ...toRaw(data.data), | |
129 | + }); | |
130 | + update.value = data; | |
131 | + }); | |
132 | + //完成编辑 | |
133 | + async function handleSubmit() { | |
134 | + // const values = await validate(); | |
135 | + // const updatedValues = { | |
136 | + // ...values, | |
137 | + // id: update.value.data.id, | |
138 | + // }; | |
139 | + if (!input1.value || !input2.value || !input3.value) { | |
140 | + error('选项不能为空'); | |
141 | + } else { | |
142 | + await updateAmountInfo({ | |
143 | + id: id.value, | |
144 | + actualPayedAmount1: input1.value, | |
145 | + actualPayedAmount2: input2.value, | |
146 | + actualPayedAmount3: input3.value, | |
147 | + }); | |
148 | + emit('success'); | |
149 | + closeDrawer(); | |
150 | + } | |
151 | + } | |
152 | +</script> | ... | ... |
src/views/project/finance/InvoiceAnalysis.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="收款单分析" | |
6 | + width="60%" | |
7 | + okText="导出" | |
8 | + :isDetail="true" | |
9 | + :showDetailBack="false" | |
10 | + @ok="handleOk" | |
11 | + @visible-change="handleShow" | |
12 | + > | |
13 | + <div class="p-4"> | |
14 | + <BasicTable @register="registerTable"> | |
15 | + <template #bodyCell="{ column, record }"> | |
16 | + <template v-if="column.key === 'action'"> </template> | |
17 | + </template> | |
18 | + </BasicTable> | |
19 | + </div> | |
20 | + </BasicModal> | |
21 | +</template> | |
22 | +<script lang="ts" setup> | |
23 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
24 | + import { computed, ref } from 'vue'; | |
25 | + import { invoiceAnalysis, exportAnalysis } from '@/api/project/invoice'; | |
26 | + import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table'; | |
27 | + // 处理弹窗的确定按钮点击事件 | |
28 | + import axios from 'axios'; | |
29 | + | |
30 | + const columnsAnalysis: BasicColumn[] = [ | |
31 | + { | |
32 | + title: '客户编码', | |
33 | + dataIndex: 'actualPayedAmount', | |
34 | + width: 50, | |
35 | + customRender: (res) => { | |
36 | + return res?.record?.exportVOS[0]?.customerCode; | |
37 | + }, | |
38 | + }, | |
39 | + { | |
40 | + title: '客户总金额汇总$', | |
41 | + dataIndex: 'customerTotalPrice', | |
42 | + width: 50, | |
43 | + customRender: (res) => { | |
44 | + return res?.record?.customerTotalPrice.toFixed(2); | |
45 | + }, | |
46 | + }, | |
47 | + { | |
48 | + title: '客户扣款金额汇总$', | |
49 | + dataIndex: 'deductAmount', | |
50 | + width: 50, | |
51 | + customRender: (res) => { | |
52 | + return res?.record?.deductAmount.toFixed(2); | |
53 | + }, | |
54 | + }, | |
55 | + { | |
56 | + title: '实际应收款$', | |
57 | + dataIndex: 'otherAmount', | |
58 | + width: 50, | |
59 | + customRender: (res) => { | |
60 | + return res?.record?.otherAmount.toFixed(2); | |
61 | + }, | |
62 | + }, | |
63 | + { | |
64 | + title: '实际收款金额汇总$', | |
65 | + dataIndex: 'actualReceivableAmount', | |
66 | + width: 50, | |
67 | + customRender: (res) => { | |
68 | + return res?.record?.actualReceivableAmount.toFixed(2); | |
69 | + }, | |
70 | + }, | |
71 | + { | |
72 | + title: '其他费用金额汇总$', | |
73 | + dataIndex: 'otherTotalAmount', | |
74 | + width: 50, | |
75 | + customRender: (res) => { | |
76 | + return res?.record?.otherTotalAmount.toFixed(2); | |
77 | + }, | |
78 | + }, | |
79 | + { | |
80 | + title: '未收金额合计$', | |
81 | + dataIndex: 'actualPayedAmount', | |
82 | + width: 50, | |
83 | + customRender: (res) => { | |
84 | + return res?.record?.actualPayedAmount.toFixed(2); | |
85 | + }, | |
86 | + }, | |
87 | + ]; | |
88 | + // const ids = ref<number[]>([]); | |
89 | + const ids = ref(); | |
90 | + const tableData = ref([]); | |
91 | + // const res = ref(); | |
92 | + | |
93 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
94 | + ids.value = data.data; | |
95 | + setTimeout(() => { | |
96 | + reload(); | |
97 | + }, 50); | |
98 | + }); | |
99 | + const [registerTable, { reload }] = useTable({ | |
100 | + // api: () => invoiceAnalysis({ ids: ids.value }), | |
101 | + api: async () => { | |
102 | + const res = await invoiceAnalysis({ ids: ids.value }); | |
103 | + // 计算合计行 | |
104 | + const sum = { | |
105 | + customerTotalPrice: 0, | |
106 | + deductAmount: 0, | |
107 | + otherAmount: 0, | |
108 | + actualReceivableAmount: 0, | |
109 | + otherTotalAmount: 0, | |
110 | + actualPayedAmount: 0, | |
111 | + exportVOS: res[0].exportVOS ? JSON.parse(JSON.stringify(res[0].exportVOS)) : [], | |
112 | + }; | |
113 | + | |
114 | + res.forEach((item: any) => { | |
115 | + sum.customerTotalPrice += item.customerTotalPrice || 0; | |
116 | + sum.deductAmount += item.deductAmount || 0; | |
117 | + sum.otherAmount += item.otherAmount || 0; | |
118 | + sum.actualReceivableAmount += item.actualReceivableAmount || 0; | |
119 | + sum.otherTotalAmount += item.otherTotalAmount || 0; | |
120 | + sum.actualPayedAmount += item.actualPayedAmount || 0; | |
121 | + }); | |
122 | + if (sum.exportVOS && sum.exportVOS[0]) { | |
123 | + sum.exportVOS[0].customerCode = '合计'; | |
124 | + } | |
125 | + res.push(sum); | |
126 | + return res; | |
127 | + }, | |
128 | + columns: columnsAnalysis, | |
129 | + bordered: true, | |
130 | + }); | |
131 | + function handleShow(visible: boolean) { | |
132 | + reload(); | |
133 | + } | |
134 | + const searchData = ref({}); | |
135 | + async function handleOk() { | |
136 | + // 构造符合 API 要求的参数 | |
137 | + const idss = ids.value; | |
138 | + // await exportAnalysis({ ids: ids }); | |
139 | + axios | |
140 | + .post( | |
141 | + '/basic-api/order/erp/invoice_bill/export', | |
142 | + { ids: idss }, | |
143 | + { | |
144 | + responseType: 'blob', // 设置响应类型为 'blob' | |
145 | + }, | |
146 | + ) | |
147 | + .then((response) => { | |
148 | + // 创建一个 Blob 对象来保存二进制数据 | |
149 | + const blob = new Blob([response.data], { type: 'application/zip' }); | |
150 | + const getFormattedDate = (): string => { | |
151 | + const date = new Date(); | |
152 | + | |
153 | + const year = date.getFullYear(); | |
154 | + const month = String(date.getMonth() + 1).padStart(2, '0'); | |
155 | + const day = String(date.getDate()).padStart(2, '0'); | |
156 | + | |
157 | + const hours = String(date.getHours()).padStart(2, '0'); | |
158 | + const minutes = String(date.getMinutes()).padStart(2, '0'); | |
159 | + const seconds = String(date.getSeconds()).padStart(2, '0'); | |
160 | + | |
161 | + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | |
162 | + }; | |
163 | + const date = getFormattedDate(); | |
164 | + // 创建一个链接元素用于下载 | |
165 | + const link = document.createElement('a'); | |
166 | + link.href = window.URL.createObjectURL(blob); | |
167 | + link.download = `收款单分析${date}.xlsx`; // 你可以为文件命名 | |
168 | + document.body.appendChild(link); | |
169 | + link.click(); // 自动点击链接,触发下载 | |
170 | + document.body.removeChild(link); // 下载完成后移除链接 | |
171 | + }) | |
172 | + .catch((error) => { | |
173 | + console.error(error); | |
174 | + }); | |
175 | + closeModal(); | |
176 | + } | |
177 | +</script> | |
178 | +<style scoped> | |
179 | + .divAll { | |
180 | + display: flex; | |
181 | + justify-content: center; | |
182 | + align-items: center; | |
183 | + } | |
184 | +</style> | ... | ... |
src/views/project/finance/InvoiceDetail.vue
0 → 100644
1 | +<template> | |
2 | + <template> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + title="订单信息" | |
7 | + width="60%" | |
8 | + :isDetail="true" | |
9 | + :showDetailBack="false" | |
10 | + :destroyOnClose="true" | |
11 | + > | |
12 | + <div class="p-4"> | |
13 | + <BasicTable @register="registerTable"> | |
14 | + <template #bodyCell="{ column, record }"> | |
15 | + <template v-if="column.key === 'action'"> </template> | |
16 | + <template v-if="column.key === 'picUrl'"> | |
17 | + <img :z-index="100000" :width="50" :height="50" :src="record?.smallPicUrl" /> | |
18 | + </template> | |
19 | + </template> | |
20 | + </BasicTable> | |
21 | + </div> | |
22 | + </BasicDrawer> | |
23 | + </template> | |
24 | +</template> | |
25 | +<script lang="ts" setup> | |
26 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | |
27 | + import { BasicForm, FormSchema, useForm } from '@/components/Form'; | |
28 | + import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue'; | |
29 | + import { demoListApi } from '/@/api/demo/table'; | |
30 | + import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table'; | |
31 | + import { getBaseInvoice } from '/@/api/project/invoice'; | |
32 | + | |
33 | + const columns: BasicColumn[] = [ | |
34 | + { | |
35 | + title: '客户编码', | |
36 | + dataIndex: 'customerCode', | |
37 | + width: 100, | |
38 | + }, | |
39 | + { | |
40 | + title: '项目号', | |
41 | + dataIndex: 'projectNo', | |
42 | + width: 100, | |
43 | + }, | |
44 | + { | |
45 | + title: '内部编码', | |
46 | + dataIndex: 'innerNo', | |
47 | + width: 100, | |
48 | + }, | |
49 | + { | |
50 | + title: '客户po号', | |
51 | + dataIndex: 'customerPo', | |
52 | + width: 100, | |
53 | + }, | |
54 | + { | |
55 | + title: '客户STYLE', | |
56 | + width: 150, | |
57 | + dataIndex: 'customerStyle', | |
58 | + }, | |
59 | + { | |
60 | + title: 'Model(REFERENCE)', | |
61 | + width: 150, | |
62 | + dataIndex: 'modeleLo', | |
63 | + }, | |
64 | + { | |
65 | + title: '订单图片', | |
66 | + width: 150, | |
67 | + dataIndex: 'picUrl', | |
68 | + }, | |
69 | + { | |
70 | + title: '数量', | |
71 | + width: 150, | |
72 | + dataIndex: 'orderCount', | |
73 | + }, | |
74 | + { | |
75 | + title: '客户单价$', | |
76 | + width: 150, | |
77 | + dataIndex: 'customerPrice', | |
78 | + }, | |
79 | + { | |
80 | + title: '客户总价$', | |
81 | + width: 150, | |
82 | + dataIndex: 'customerTotalPrice', | |
83 | + }, | |
84 | + ]; | |
85 | + const invoiceNo = ref(); | |
86 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
87 | + // 方式1 | |
88 | + invoiceNo.value = data.data.invoiceNo; | |
89 | + // getBaseInvoice({ invoiceNo: invoiceNo.value }); | |
90 | + }); | |
91 | + const params = ref({ | |
92 | + invoiceNo: invoiceNo.value, | |
93 | + }); | |
94 | + const [registerTable] = useTable({ | |
95 | + api: () => { | |
96 | + const res = getBaseInvoice({ invoiceNo: invoiceNo.value }); | |
97 | + return res; | |
98 | + }, | |
99 | + columns: columns, | |
100 | + bordered: true, | |
101 | + }); | |
102 | +</script> | ... | ... |
src/views/project/finance/InvoiceShowCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="生产科发票" | |
6 | + width="700px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + > | |
10 | + <a-list item-layout="horizontal" :data-source="itemArray"> | |
11 | + <template #renderItem="{ item }"> | |
12 | + <a-list-item> | |
13 | + <a-list-item-meta> | |
14 | + <template #title> | |
15 | + <!-- <a :href="item.url" target="_blank" rel="noopener noreferrer">{{ item.name }}</a> --> | |
16 | + <a @click="view(item.url)">{{ item.name }}</a> | |
17 | + </template> | |
18 | + </a-list-item-meta> | |
19 | + </a-list-item> | |
20 | + </template> | |
21 | + </a-list> | |
22 | + </BasicModal> | |
23 | +</template> | |
24 | +<script lang="ts" setup> | |
25 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
26 | + import { computed, ref } from 'vue'; | |
27 | + import type { UploadProps, UploadChangeParam } from 'ant-design-vue'; | |
28 | + import { InboxOutlined } from '@ant-design/icons-vue'; | |
29 | + import { message } from 'ant-design-vue'; | |
30 | + import { getDeductUrlById, getInvoiceUrlById } from '@/api/project/invoice'; | |
31 | + import { view } from '@/utils/pdfShow'; | |
32 | + | |
33 | + interface Item { | |
34 | + name: string; | |
35 | + url: string; | |
36 | + } | |
37 | + | |
38 | + const list = ref(); | |
39 | + const id = ref(); | |
40 | + const itemArray = ref<Item[]>([]); | |
41 | + | |
42 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
43 | + itemArray.value = []; | |
44 | + const res = await getInvoiceUrlById({ id: data.data.checkId }); | |
45 | + for (let item in res) { | |
46 | + const url = res[item]; | |
47 | + const name = item; | |
48 | + // 将 name 和 url 放入对象并添加到数组中 | |
49 | + itemArray.value.push({ name, url }); | |
50 | + } | |
51 | + }); | |
52 | + | |
53 | + async function handleOk() { | |
54 | + itemArray.value = []; | |
55 | + closeModal(); | |
56 | + } | |
57 | +</script> | ... | ... |
src/views/project/finance/InvoiceUploadCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="发票上传" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + ><a-upload-dragger | |
10 | + v-model:fileList="fileList" | |
11 | + name="file" | |
12 | + :beforeUpload="beforeUpload" | |
13 | + :max-count="1" | |
14 | + :multiple="true" | |
15 | + :action="updateInvoiceUrl" | |
16 | + @change="handleChange" | |
17 | + @drop="handleDrop" | |
18 | + :disabled="status === 10" | |
19 | + > | |
20 | + <p class="ant-upload-drag-icon"> | |
21 | + <inbox-outlined></inbox-outlined> | |
22 | + </p> | |
23 | + <p class="ant-upload-text">点击或将文件拖拽到这里上传</p> | |
24 | + </a-upload-dragger> | |
25 | + </BasicModal> | |
26 | +</template> | |
27 | +<script lang="ts" setup> | |
28 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
29 | + import { computed, ref } from 'vue'; | |
30 | + import type { UploadProps, UploadChangeParam } from 'ant-design-vue'; | |
31 | + import { InboxOutlined } from '@ant-design/icons-vue'; | |
32 | + import { message } from 'ant-design-vue'; | |
33 | + import { updateInvoiceInfo } from '@/api/project/invoice'; | |
34 | + | |
35 | + const emit = defineEmits(['success']); | |
36 | + const uploadUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
37 | + const updateInvoiceUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
38 | + const invoiceUrl = ref(); | |
39 | + const id = ref(); | |
40 | + const status = ref(); | |
41 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
42 | + console.log(data); | |
43 | + status.value = data.data.checkStatus; | |
44 | + // fileList.value = []; | |
45 | + fileList.value = []; | |
46 | + invoiceUrl.value = data.data.invoiceUrl; | |
47 | + id.value = data.data.checkId; | |
48 | + }); | |
49 | + | |
50 | + const handleChange = (info) => { | |
51 | + if (info.file.status == 'done') { | |
52 | + updateInvoiceUrl.value = info.file.response.data.fileUrl; | |
53 | + invoiceUrl.value = updateInvoiceUrl.value; | |
54 | + } | |
55 | + }; | |
56 | + function beforeUpload(info) { | |
57 | + updateInvoiceUrl.value = uploadUrl.value + info.name; | |
58 | + } | |
59 | + function handleDrop(e: DragEvent) { | |
60 | + console.log(e); | |
61 | + } | |
62 | + const fileList = ref<UploadProps['fileList']>([]); | |
63 | + | |
64 | + async function handleOk() { | |
65 | + await updateInvoiceInfo({ | |
66 | + id: id.value, | |
67 | + invoiceUrl: invoiceUrl.value, | |
68 | + }); | |
69 | + fileList.value = []; | |
70 | + emit('success'); | |
71 | + closeModal(); | |
72 | + } | |
73 | +</script> | ... | ... |
src/views/project/finance/Note.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="添加备注" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + @visible-change="handleShow" | |
10 | + > | |
11 | + 备注: | |
12 | + <a-textarea v-model:value="notes" placeholder="请输入" :rows="6" /> | |
13 | + <div style="height: 10px"></div> | |
14 | + </BasicModal> | |
15 | +</template> | |
16 | +<script lang="ts" setup> | |
17 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
18 | + import { ref } from 'vue'; | |
19 | + import { getInvoiceNote } from '@/api/project/invoice'; | |
20 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
21 | + | |
22 | + const id = ref(); | |
23 | + const notes = ref(); | |
24 | + const emit = defineEmits(['success']); | |
25 | + const { createMessage } = useMessage(); | |
26 | + const { error } = createMessage; | |
27 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
28 | + id.value = data.data.invoiceId; | |
29 | + }); | |
30 | + const isDisabled = ref(false); | |
31 | + async function handleOk() { | |
32 | + if (isDisabled.value) { | |
33 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
34 | + return; | |
35 | + } | |
36 | + isDisabled.value = true; | |
37 | + setTimeout(() => { | |
38 | + isDisabled.value = false; | |
39 | + }, 3000); | |
40 | + getInvoiceNote({ id: id.value, notes: notes.value }); | |
41 | + emit('success'); | |
42 | + closeModal(); | |
43 | + } | |
44 | + function handleShow(visible: boolean) { | |
45 | + if (!visible) { | |
46 | + notes.value = null; | |
47 | + } | |
48 | + } | |
49 | +</script> | ... | ... |
src/views/project/finance/NoteCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="添加备注" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + @visible-change="handleShow" | |
10 | + > | |
11 | + 备注: | |
12 | + <a-textarea v-model:value="notes" placeholder="请输入" :rows="6" /> | |
13 | + <div style="height: 10px"></div> | |
14 | + </BasicModal> | |
15 | +</template> | |
16 | +<script lang="ts" setup> | |
17 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
18 | + import { ref } from 'vue'; | |
19 | + import { getCheckNote } from '@/api/project/invoice'; | |
20 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
21 | + | |
22 | + const id = ref(); | |
23 | + const notes = ref(); | |
24 | + const emit = defineEmits(['success']); | |
25 | + const { createMessage } = useMessage(); | |
26 | + const { error } = createMessage; | |
27 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
28 | + id.value = data.data.checkId; | |
29 | + }); | |
30 | + const isDisabled = ref(false); | |
31 | + async function handleOk() { | |
32 | + if (isDisabled.value) { | |
33 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
34 | + return; | |
35 | + } | |
36 | + isDisabled.value = true; | |
37 | + setTimeout(() => { | |
38 | + isDisabled.value = false; | |
39 | + }, 3000); | |
40 | + getCheckNote({ id: id.value, notes: notes.value }); | |
41 | + emit('success'); | |
42 | + closeModal(); | |
43 | + } | |
44 | + function handleShow(visible: boolean) { | |
45 | + if (!visible) { | |
46 | + notes.value = null; | |
47 | + } | |
48 | + } | |
49 | +</script> | ... | ... |
src/views/project/finance/ReUploadBgUrl.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="更新报关单" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + @visible-change="handleShow" | |
10 | + > | |
11 | + <div>报关单(请上传PDF格式)</div | |
12 | + ><a-space direction="vertical" style="width: 100%" size="large"> | |
13 | + <a-upload | |
14 | + v-model:file-list="fileList" | |
15 | + :beforeUpload="beforeUpload" | |
16 | + list-type="picture" | |
17 | + :max-count="1" | |
18 | + :action="updateUrl" | |
19 | + @change="handleChange" | |
20 | + > | |
21 | + <a-button> 上传报关单 </a-button> | |
22 | + </a-upload> | |
23 | + </a-space> | |
24 | + </BasicModal> | |
25 | +</template> | |
26 | +<script lang="ts" setup> | |
27 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
28 | + import { ref } from 'vue'; | |
29 | + import type { UploadProps } from 'ant-design-vue'; | |
30 | + import { reUploadBgUrl } from '@/api/project/invoice'; | |
31 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
32 | + | |
33 | + const fileList = ref<UploadProps['fileList']>([]); | |
34 | + const { createMessage } = useMessage(); | |
35 | + const { error } = createMessage; | |
36 | + const emit = defineEmits(['success']); | |
37 | + | |
38 | + const id = ref(); | |
39 | + const uploadUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
40 | + const updateUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
41 | + const bgUrl = ref(); | |
42 | + const urlOld = ref(); | |
43 | + | |
44 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
45 | + id.value = data.data.invoiceId; | |
46 | + }); | |
47 | + function handleChange(info) { | |
48 | + if (info.file.status == 'done') { | |
49 | + updateUrl.value = info.file.response.data.fileUrl; | |
50 | + bgUrl.value = updateUrl.value; | |
51 | + } | |
52 | + if (info.fileList.length == 0) { | |
53 | + info.file = null; | |
54 | + bgUrl.value = ''; | |
55 | + } | |
56 | + } | |
57 | + function beforeUpload(info) { | |
58 | + updateUrl.value += uploadUrl.value + info.name; | |
59 | + } | |
60 | + function handleShow(visible: boolean) { | |
61 | + if (!visible) { | |
62 | + updateUrl.value = ''; | |
63 | + fileList.value = null; | |
64 | + } | |
65 | + } | |
66 | + | |
67 | + async function handleOk() { | |
68 | + reUploadBgUrl({ id: id.value, bgUrl: bgUrl.value }); | |
69 | + emit('success'); | |
70 | + closeModal(); | |
71 | + } | |
72 | +</script> | ... | ... |
src/views/project/finance/TrackEdit.vue
0 → 100644
1 | +<template> | |
2 | + <template> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + title="收入款单" | |
7 | + width="30%" | |
8 | + :isDetail="true" | |
9 | + @ok="handleSubmit" | |
10 | + @visible-change="handleShow" | |
11 | + :showDetailBack="false" | |
12 | + okText="保存" | |
13 | + showFooter | |
14 | + :destroyOnClose="true" | |
15 | + > | |
16 | + <div> | |
17 | + <div style="font-size: 15px">客户扣款金额$</div> | |
18 | + <a-input v-model:value="input1" placeholder="请输入" :disabled="status === 10" auto-size /> | |
19 | + <div style="margin: 16px 0"></div> | |
20 | + <div>上传扣款单</div | |
21 | + ><a-space direction="vertical" style="width: 100%" size="large"> | |
22 | + <a-upload | |
23 | + v-model:file-list="fileList" | |
24 | + :beforeUpload="beforeUpload" | |
25 | + list-type="picture" | |
26 | + :max-count="1" | |
27 | + :action="updateDeductUrl" | |
28 | + @change="handleChange" | |
29 | + :disabled="status === 10" | |
30 | + > | |
31 | + <a-button> 上传扣款单 </a-button> | |
32 | + </a-upload> | |
33 | + </a-space> | |
34 | + </div> | |
35 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | |
36 | + <template #appendFooter> | |
37 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | |
38 | + </template> | |
39 | + </BasicDrawer> | |
40 | + </template> | |
41 | +</template> | |
42 | +<script lang="ts" setup> | |
43 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | |
44 | + import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue'; | |
45 | + import { getEmailList } from '/@/api/sys/config'; | |
46 | + import { UploadOutlined } from '@ant-design/icons-vue'; | |
47 | + import type { UploadProps } from 'ant-design-vue'; | |
48 | + import { updateDeduct } from '@/api/project/invoice'; | |
49 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
50 | + | |
51 | + const emit = defineEmits(['success']); | |
52 | + const fileList = ref<UploadProps['fileList']>([]); | |
53 | + | |
54 | + const input1 = ref(0); | |
55 | + const deductUrl = ref(); | |
56 | + const id = ref(); | |
57 | + const invoiceNo = ref(); | |
58 | + const uploadUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
59 | + // const uploadUrl = ref(''); | |
60 | + const updateDeductUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
61 | + // const updateDeductUrl = ref(''); | |
62 | + const deductUrlOld = ref(); | |
63 | + const { createMessage } = useMessage(); | |
64 | + const { error } = createMessage; | |
65 | + const status = ref(); | |
66 | + | |
67 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
68 | + status.value = data.data.invoiceStatus; | |
69 | + id.value = data.data.invoiceId; | |
70 | + invoiceNo.value = data.data.invoiceNo; | |
71 | + input1.value = data.data.invoiceDeductAmount; | |
72 | + deductUrl.value = data.data.invoiceDeductUrl; | |
73 | + deductUrlOld.value = data.data.invoiceDeductUrl; | |
74 | + }); | |
75 | + | |
76 | + function handleChange(info) { | |
77 | + if (info.file.status == 'done') { | |
78 | + updateDeductUrl.value = info.file.response.data.fileUrl; | |
79 | + deductUrl.value = updateDeductUrl.value; | |
80 | + } | |
81 | + if (info.fileList.length == 0) { | |
82 | + info.file = null; | |
83 | + deductUrl.value = ''; | |
84 | + } | |
85 | + } | |
86 | + function beforeUpload(info) { | |
87 | + updateDeductUrl.value = uploadUrl.value + info.name; | |
88 | + } | |
89 | + function handleShow() { | |
90 | + // if (!visible) { | |
91 | + // input1.value = 0; | |
92 | + // deductUrl.value = ''; | |
93 | + // updateDeductUrl.value = ''; | |
94 | + // fileList.value = []; | |
95 | + // } | |
96 | + // input1.value = ''; | |
97 | + // deductUrl.value = ''; | |
98 | + // updateDeductUrl.value = ''; | |
99 | + // fileList.value = []; | |
100 | + } | |
101 | + | |
102 | + //完成编辑 | |
103 | + async function handleSubmit() { | |
104 | + if (!input1.value) { | |
105 | + error('选项不能为空'); | |
106 | + } else { | |
107 | + await updateDeduct({ | |
108 | + id: id.value, | |
109 | + invoiceNo: invoiceNo.value, | |
110 | + deductAmount: input1.value, | |
111 | + deductUrl: deductUrl.value, | |
112 | + }); | |
113 | + fileList.value = []; | |
114 | + emit('success'); | |
115 | + closeDrawer(); | |
116 | + } | |
117 | + } | |
118 | +</script> | ... | ... |
src/views/project/finance/TrackEditCheck.vue
0 → 100644
1 | +<template> | |
2 | + <template> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + title="跟单编辑" | |
7 | + width="30%" | |
8 | + :isDetail="true" | |
9 | + @ok="handleSubmit" | |
10 | + :showDetailBack="false" | |
11 | + @visible-change="handleShow" | |
12 | + okText="保存" | |
13 | + showFooter | |
14 | + :destroyOnClose="true" | |
15 | + > | |
16 | + <div> | |
17 | + <div style="font-size: 15px">生产科扣款金额¥</div> | |
18 | + <a-input v-model:value="input1" placeholder="请输入" :disabled="status === 10" auto-size /> | |
19 | + <div style="margin: 16px 0"></div> | |
20 | + <div style="font-size: 15px">扣款责任部门</div> | |
21 | + <a-input | |
22 | + v-model:value="deductDept" | |
23 | + placeholder="请输入" | |
24 | + :disabled="status === 10" | |
25 | + auto-size | |
26 | + /> | |
27 | + <!-- <a-select | |
28 | + ref="select" | |
29 | + style="width: 60%" | |
30 | + v-model:value="selectedProductionDepartment" | |
31 | + :options="productionDepartmentOptions" | |
32 | + /> --> | |
33 | + <!-- <a-select | |
34 | + ref="select" | |
35 | + style="width: 100%" | |
36 | + v-model:value="productionDepartment" | |
37 | + :options="productDepartmentOptions" | |
38 | + /> --> | |
39 | + <div style="margin: 16px 0"></div> | |
40 | + <div>上传扣款单</div | |
41 | + ><a-space direction="vertical" style="width: 100%" size="large"> | |
42 | + <a-upload | |
43 | + v-model:file-list="fileList" | |
44 | + :beforeUpload="beforeUpload" | |
45 | + list-type="picture" | |
46 | + :max-count="1" | |
47 | + :disabled="status === 10" | |
48 | + :action="updateDeductUrl" | |
49 | + @change="handleChange" | |
50 | + > | |
51 | + <a-button> 上传扣款单 </a-button> | |
52 | + </a-upload> | |
53 | + </a-space> | |
54 | + </div> | |
55 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | |
56 | + <template #appendFooter> | |
57 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | |
58 | + </template> | |
59 | + </BasicDrawer> | |
60 | + </template> | |
61 | +</template> | |
62 | +<script lang="ts" setup> | |
63 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | |
64 | + import { defineComponent, ref, computed, unref, toRaw, reactive, onMounted } from 'vue'; | |
65 | + import { getEmailList } from '/@/api/sys/config'; | |
66 | + import { UploadOutlined } from '@ant-design/icons-vue'; | |
67 | + import type { UploadProps } from 'ant-design-vue'; | |
68 | + import { updateDeductInfo } from '@/api/project/invoice'; | |
69 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
70 | + import { useOrderInfo } from '/@/hooks/component/order'; | |
71 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
72 | + | |
73 | + const emit = defineEmits(['success']); | |
74 | + const fileList = ref<UploadProps['fileList']>([]); | |
75 | + // const orderStore = useOrderStoreWithOut(); | |
76 | + // const { productionDepartment: productionDepartmentOptions } = useOrderInfo(orderStore); | |
77 | + // console.log(productionDepartmentOptions.value, '565656565665orderStore'); | |
78 | + // onMounted(() => { | |
79 | + // const { productionDepartment } = useOrderInfo(orderStore); | |
80 | + // console.log(productionDepartment.value, '565656565665orderStore1'); | |
81 | + // }); | |
82 | + const orderStore = useOrderStoreWithOut(); | |
83 | + const { productionDepartment: productDepartmentOptions } = useOrderInfo(orderStore); | |
84 | + const productionDepartment = ref(); | |
85 | + const input1 = ref(0); | |
86 | + const deductUrl = ref(); | |
87 | + const id = ref(); | |
88 | + const checkNo = ref(); | |
89 | + const deductDept = ref(); | |
90 | + const uploadUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
91 | + const updateDeductUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
92 | + // const uploadUrl = ref(''); | |
93 | + // const updateDeductUrl = ref(''); | |
94 | + const deductUrlOld = ref(); | |
95 | + const selectedProductionDepartment = ref(); // 新增: 用于存储选中的生产科 | |
96 | + const { createMessage } = useMessage(); | |
97 | + const { error } = createMessage; | |
98 | + const status = ref(); | |
99 | + | |
100 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
101 | + status.value = data.data.checkStatus; | |
102 | + id.value = data.data.checkId; | |
103 | + checkNo.value = data.data.checkNo; | |
104 | + input1.value = data.data.checkDeductAmount; | |
105 | + deductDept.value = data.data.checkDeductDept; | |
106 | + deductUrl.value = data.data.checkDeductUrl; | |
107 | + deductUrlOld.value = data.data.checkDeductUrl; | |
108 | + }); | |
109 | + function handleChange(info) { | |
110 | + if (info.file.status == 'done') { | |
111 | + updateDeductUrl.value = info.file.response.data.fileUrl; | |
112 | + deductUrl.value = updateDeductUrl.value; | |
113 | + } | |
114 | + if (info.fileList.length == 0) { | |
115 | + info.file = null; | |
116 | + deductUrl.value = ''; | |
117 | + } | |
118 | + } | |
119 | + function beforeUpload(info) { | |
120 | + updateDeductUrl.value = uploadUrl.value + info.name; | |
121 | + } | |
122 | + function handleShow() { | |
123 | + // input1.value = ''; | |
124 | + // deductUrl.value = ''; | |
125 | + // deductDept.value = ''; | |
126 | + // updateDeductUrl.value = ''; | |
127 | + // fileList.value = []; | |
128 | + } | |
129 | + //完成编辑 | |
130 | + async function handleSubmit() { | |
131 | + if (!input1.value || !deductDept.value) { | |
132 | + error('选项不能为空'); | |
133 | + } else { | |
134 | + await updateDeductInfo({ | |
135 | + id: id.value, | |
136 | + checkNo: checkNo.value, | |
137 | + deductAmount: input1.value, | |
138 | + deductDept: deductDept.value, | |
139 | + deductUrl: deductUrl.value, | |
140 | + }); | |
141 | + // productionDepartment: selectedProductionDepartment.value, | |
142 | + fileList.value = []; | |
143 | + emit('success'); | |
144 | + closeDrawer(); | |
145 | + } | |
146 | + } | |
147 | +</script> | ... | ... |
src/views/project/finance/finance.data.tsx
0 → 100644
1 | +import { FormSchema } from '/@/components/Form'; | |
2 | +import { BasicColumn } from '/@/components/Table'; | |
3 | +import { icon } from 'ant-design-vue'; | |
4 | +import { FolderAddOutlined, FilePptOutlined } from '@ant-design/icons-vue'; | |
5 | +import { size } from 'lodash-es'; | |
6 | +import { view } from '@/utils/pdfShow'; | |
7 | + | |
8 | +export const searchFormSchema: FormSchema[] = [ | |
9 | + { | |
10 | + field: 'invoiceNo', | |
11 | + label: '发票单号', | |
12 | + component: 'Input', | |
13 | + colProps: { span: 8 }, | |
14 | + }, | |
15 | + { | |
16 | + field: 'checkNo', | |
17 | + label: '生产科对账单号', | |
18 | + component: 'Input', | |
19 | + colProps: { span: 8 }, | |
20 | + }, | |
21 | + { | |
22 | + field: 'invoiceStatus', | |
23 | + label: '发票状态', | |
24 | + component: 'Select', | |
25 | + colProps: { span: 8 }, | |
26 | + componentProps: { | |
27 | + options: [ | |
28 | + { label: '未创建', value: -1 }, | |
29 | + { label: '未收款', value: 0 }, | |
30 | + { label: '已收款', value: 10 }, | |
31 | + ], | |
32 | + }, | |
33 | + }, | |
34 | + { | |
35 | + field: 'checkNoStatus', | |
36 | + label: '对账单号状态', | |
37 | + component: 'Select', | |
38 | + colProps: { span: 8 }, | |
39 | + componentProps: { | |
40 | + options: [ | |
41 | + { label: '未创建', value: -1 }, | |
42 | + { label: '未收款', value: 0 }, | |
43 | + { label: '已收款', value: 10 }, | |
44 | + ], | |
45 | + }, | |
46 | + }, | |
47 | + { | |
48 | + field: 'customerCode', | |
49 | + label: '客户编码', | |
50 | + component: 'Input', | |
51 | + colProps: { span: 8 }, | |
52 | + }, | |
53 | + { | |
54 | + field: 'projectNo', | |
55 | + label: '项目号', | |
56 | + component: 'Input', | |
57 | + colProps: { span: 8 }, | |
58 | + }, | |
59 | + { | |
60 | + field: 'productionDepartment', | |
61 | + label: '生产科', | |
62 | + component: 'Input', | |
63 | + colProps: { span: 8 }, | |
64 | + }, | |
65 | + { | |
66 | + field: 'innerNo', | |
67 | + label: '内部编号', | |
68 | + component: 'Input', | |
69 | + colProps: { span: 8 }, | |
70 | + }, | |
71 | + { | |
72 | + field: 'customerPo', | |
73 | + label: '客户PO号', | |
74 | + component: 'Input', | |
75 | + colProps: { span: 8 }, | |
76 | + }, | |
77 | + { | |
78 | + field: 'invoiceStartTime', | |
79 | + label: '发票开始时间', | |
80 | + component: 'DatePicker', | |
81 | + colProps: { span: 8 }, | |
82 | + labelWidth: 150, | |
83 | + }, | |
84 | + { | |
85 | + field: 'invoiceEndTime', | |
86 | + label: '发票结束时间', | |
87 | + component: 'DatePicker', | |
88 | + colProps: { span: 8 }, | |
89 | + labelWidth: 150, | |
90 | + }, | |
91 | + { | |
92 | + field: 'checkStartTime', | |
93 | + label: '对账开始时间', | |
94 | + component: 'DatePicker', | |
95 | + colProps: { span: 8 }, | |
96 | + labelWidth: 150, | |
97 | + }, | |
98 | + { | |
99 | + field: 'checkEndTime', | |
100 | + label: '对账结束时间', | |
101 | + component: 'DatePicker', | |
102 | + colProps: { span: 8 }, | |
103 | + labelWidth: 150, | |
104 | + }, | |
105 | + { | |
106 | + field: 'createStartTime', | |
107 | + label: '订单开始时间', | |
108 | + component: 'DatePicker', | |
109 | + colProps: { span: 8 }, | |
110 | + labelWidth: 150, | |
111 | + }, | |
112 | + { | |
113 | + field: 'createEndTime', | |
114 | + label: '订单结束时间', | |
115 | + component: 'DatePicker', | |
116 | + colProps: { span: 8 }, | |
117 | + labelWidth: 150, | |
118 | + }, | |
119 | + { | |
120 | + field: 'productionDepartmentConsignStartTime', | |
121 | + label: '生产科拖货开始时间', | |
122 | + component: 'DatePicker', | |
123 | + colProps: { span: 8 }, | |
124 | + labelWidth: 150, | |
125 | + }, | |
126 | + { | |
127 | + field: 'productionDepartmentConsignEndTime', | |
128 | + label: '生产科拖货结束时间', | |
129 | + component: 'DatePicker', | |
130 | + colProps: { span: 8 }, | |
131 | + labelWidth: 150, | |
132 | + }, | |
133 | + { | |
134 | + field: 'orderHodStartTime', | |
135 | + label: 'HOD开始时间', | |
136 | + component: 'DatePicker', | |
137 | + colProps: { span: 8 }, | |
138 | + labelWidth: 150, | |
139 | + }, | |
140 | + { | |
141 | + field: 'orderHodEndTime', | |
142 | + label: 'HOD结束时间', | |
143 | + component: 'DatePicker', | |
144 | + colProps: { span: 8 }, | |
145 | + labelWidth: 150, | |
146 | + }, | |
147 | +]; | |
148 | + | |
149 | +export const columns: BasicColumn[] = [ | |
150 | + { | |
151 | + title: '客户编码', | |
152 | + dataIndex: 'customerCode', | |
153 | + width: 100, | |
154 | + }, | |
155 | + { | |
156 | + title: '项目号', | |
157 | + dataIndex: 'projectNo', | |
158 | + width: 100, | |
159 | + }, | |
160 | + { | |
161 | + title: '生产科', | |
162 | + dataIndex: 'productionDepartment', | |
163 | + width: 100, | |
164 | + }, | |
165 | + { | |
166 | + title: '内部编码', | |
167 | + dataIndex: 'innerNo', | |
168 | + width: 100, | |
169 | + }, | |
170 | + { | |
171 | + title: '订单图片', | |
172 | + width: 150, | |
173 | + dataIndex: 'picUrl', | |
174 | + }, | |
175 | + { | |
176 | + title: '数量', | |
177 | + width: 150, | |
178 | + dataIndex: 'orderCount', | |
179 | + }, | |
180 | + { | |
181 | + title: '生产科拖货时间', | |
182 | + width: 150, | |
183 | + dataIndex: 'productionDepartmentConsignTime', | |
184 | + customRender: (column) => { | |
185 | + return formatDate(column.record?.productionDepartmentConsignTime); | |
186 | + }, | |
187 | + }, | |
188 | + { | |
189 | + title: '订单上HOD时间', | |
190 | + width: 150, | |
191 | + dataIndex: 'orderHodTime', | |
192 | + customRender: (column) => { | |
193 | + return formatDate(column.record?.orderHodTime); | |
194 | + }, | |
195 | + }, | |
196 | + { | |
197 | + title: '客户单价$', | |
198 | + width: 150, | |
199 | + dataIndex: 'customerPrice', | |
200 | + customRender: (column) => { | |
201 | + return column.record.customerPrice?.toFixed(2); | |
202 | + }, | |
203 | + }, | |
204 | + { | |
205 | + title: '客户总价$', | |
206 | + width: 150, | |
207 | + dataIndex: 'customerTotalPrice', | |
208 | + customRender: (column) => { | |
209 | + return column.record.customerTotalPrice?.toFixed(2); | |
210 | + }, | |
211 | + }, | |
212 | + { | |
213 | + title: 'Invoice编号', | |
214 | + dataIndex: 'invoiceNo', | |
215 | + width: 180, | |
216 | + }, | |
217 | + { | |
218 | + title: '报关单', | |
219 | + dataIndex: 'invoiceBgUrl', | |
220 | + width: 80, | |
221 | + customRender: (column) => { | |
222 | + const bgUrl = column.record.invoiceBgUrl; | |
223 | + if (bgUrl == undefined) { | |
224 | + return; | |
225 | + } | |
226 | + return <FilePptOutlined style="font-size:25px" onClick={() => view(bgUrl)} />; | |
227 | + }, | |
228 | + }, | |
229 | + { | |
230 | + title: '必须回款日期', | |
231 | + dataIndex: 'invoiceBackRefundDate', | |
232 | + width: 120, | |
233 | + }, | |
234 | + { | |
235 | + title: '发生扣款金额$', | |
236 | + dataIndex: 'invoiceDeductAmount', | |
237 | + width: 120, | |
238 | + customRender: (column) => { | |
239 | + return column.record.invoiceDeductAmount?.toFixed(2); | |
240 | + }, | |
241 | + }, | |
242 | + { | |
243 | + title: '上传扣款单', | |
244 | + dataIndex: 'invoiceDeductUrl', | |
245 | + width: 80, | |
246 | + customRender: (column) => { | |
247 | + const deductUrl = column.record.invoiceDeductUrl; | |
248 | + if (deductUrl == undefined) { | |
249 | + return; | |
250 | + } | |
251 | + // return <FilePptOutlined style="font-size:25px" onClick={() => window.open(deductUrl[0])} />; | |
252 | + return <FilePptOutlined style="font-size:25px" />; | |
253 | + }, | |
254 | + }, | |
255 | + { | |
256 | + title: '实际应收金额$', | |
257 | + dataIndex: 'invoiceActualReceivableAmount', | |
258 | + width: 120, | |
259 | + customRender: (column) => { | |
260 | + return column.record.invoiceActualReceivableAmount?.toFixed(2); | |
261 | + }, | |
262 | + }, | |
263 | + { | |
264 | + title: '实际收款金额1$', | |
265 | + dataIndex: 'invoiceActualPayedAmount1', | |
266 | + width: 120, | |
267 | + customRender: (column) => { | |
268 | + return column.record.invoiceActualPayedAmount1?.toFixed(2); | |
269 | + }, | |
270 | + }, | |
271 | + { | |
272 | + title: '实际收款金额2$', | |
273 | + dataIndex: 'invoiceActualPayedAmount2', | |
274 | + width: 120, | |
275 | + customRender: (column) => { | |
276 | + return column.record.invoiceActualPayedAmount2?.toFixed(2); | |
277 | + }, | |
278 | + }, | |
279 | + { | |
280 | + title: '实际收款金额3$', | |
281 | + dataIndex: 'invoiceActualPayedAmount3', | |
282 | + width: 120, | |
283 | + customRender: (column) => { | |
284 | + return column.record.invoiceActualPayedAmount3?.toFixed(2); | |
285 | + }, | |
286 | + }, | |
287 | + { | |
288 | + title: '其他费用$', | |
289 | + dataIndex: 'invoiceOtherAmount', | |
290 | + width: 120, | |
291 | + customRender: (column) => { | |
292 | + return column.record.invoiceOtherAmount?.toFixed(2); | |
293 | + }, | |
294 | + }, | |
295 | + { | |
296 | + title: 'invoice备注', | |
297 | + dataIndex: 'invoiceNotes', | |
298 | + width: 200, | |
299 | + }, | |
300 | + { | |
301 | + title: 'INVOICE状态', | |
302 | + dataIndex: 'invoiceStatus', | |
303 | + width: 120, | |
304 | + customRender: (column) => { | |
305 | + if (column.record.invoiceStatus == null || column.record.invoiceStatus == undefined) { | |
306 | + return '未创建'; | |
307 | + } else if (column.record.invoiceStatus == 0) { | |
308 | + return '未收款'; | |
309 | + } else if (column.record.invoiceStatus == 10) { | |
310 | + return '已收款'; | |
311 | + } | |
312 | + }, | |
313 | + }, | |
314 | + { | |
315 | + title: 'Action', | |
316 | + key: 'action', // 对应 #bodyCell 中的 column.key | |
317 | + width: 280, | |
318 | + }, | |
319 | + { | |
320 | + title: '生产科单价¥', | |
321 | + dataIndex: 'productionDepartmentPrice', | |
322 | + width: 120, | |
323 | + customRender: (column) => { | |
324 | + return column.record.productionDepartmentPrice?.toFixed(2); | |
325 | + }, | |
326 | + }, | |
327 | + { | |
328 | + title: '生产科总价¥', | |
329 | + dataIndex: 'productionDepartmentTotalPrice', | |
330 | + width: 120, | |
331 | + customRender: (column) => { | |
332 | + return column.record.productionDepartmentTotalPrice?.toFixed(2); | |
333 | + }, | |
334 | + }, | |
335 | + { | |
336 | + title: 'CheckNo编号', | |
337 | + dataIndex: 'checkNo', | |
338 | + width: 120, | |
339 | + }, | |
340 | + { | |
341 | + title: '生产科应付款日期', | |
342 | + dataIndex: 'checkPayedDate', | |
343 | + width: 140, | |
344 | + }, | |
345 | + { | |
346 | + title: '生产科扣款金额¥', | |
347 | + dataIndex: 'checkDeductAmount', | |
348 | + width: 160, | |
349 | + customRender: (column) => { | |
350 | + return column.record.checkDeductAmount?.toFixed(2); | |
351 | + }, | |
352 | + }, | |
353 | + { | |
354 | + title: '扣款责任部门', | |
355 | + dataIndex: 'checkDeductDept', | |
356 | + width: 120, | |
357 | + }, | |
358 | + { | |
359 | + title: '上传扣款单', | |
360 | + dataIndex: 'checkDeductUrl', | |
361 | + width: 120, | |
362 | + customRender: (column) => { | |
363 | + const deductUrl = column.record.checkDeductUrl; | |
364 | + if (deductUrl == undefined) { | |
365 | + return; | |
366 | + } | |
367 | + return <FilePptOutlined style="font-size:25px" />; | |
368 | + }, | |
369 | + }, | |
370 | + { | |
371 | + title: '生产科实际应付金额¥', | |
372 | + dataIndex: 'checkActualPayedAmount', | |
373 | + width: 180, | |
374 | + customRender: (column) => { | |
375 | + return column.record.checkActualPayedAmount?.toFixed(2); | |
376 | + }, | |
377 | + }, | |
378 | + { | |
379 | + title: '生产科发票上传', | |
380 | + dataIndex: 'checkInvoiceUrl', | |
381 | + width: 80, | |
382 | + customRender: (column) => { | |
383 | + const deductUrl = column.record.checkInvoiceUrl; | |
384 | + if (deductUrl == undefined) { | |
385 | + return; | |
386 | + } | |
387 | + return <FilePptOutlined style="font-size:25px" />; | |
388 | + }, | |
389 | + }, | |
390 | + { | |
391 | + title: '实际付款金额1¥', | |
392 | + dataIndex: 'checkActualPayedAmount1', | |
393 | + width: 160, | |
394 | + customRender: (column) => { | |
395 | + return column.record.checkActualPayedAmount1?.toFixed(2); | |
396 | + }, | |
397 | + }, | |
398 | + { | |
399 | + title: '实际付款金额2¥', | |
400 | + dataIndex: 'checkActualPayedAmount2', | |
401 | + width: 160, | |
402 | + customRender: (column) => { | |
403 | + return column.record.checkActualPayedAmount2?.toFixed(2); | |
404 | + }, | |
405 | + }, | |
406 | + { | |
407 | + title: '实际付款金额3¥', | |
408 | + dataIndex: 'checkActualPayedAmount3', | |
409 | + width: 160, | |
410 | + customRender: (column) => { | |
411 | + return column.record.checkActualPayedAmount3?.toFixed(2); | |
412 | + }, | |
413 | + }, | |
414 | + { | |
415 | + title: '生产科发票审核', | |
416 | + dataIndex: 'checkDepartmentInvoiceStatus', | |
417 | + width: 120, | |
418 | + customRender: (column) => { | |
419 | + if (column.record.checkDepartmentInvoiceStatus == 0) { | |
420 | + return '待审核'; | |
421 | + } else if (column.record.checkDepartmentInvoiceStatus == 10) { | |
422 | + return '审核通过'; | |
423 | + } else if (column.record.checkDepartmentInvoiceStatus == 20) { | |
424 | + return '审核驳回'; | |
425 | + } | |
426 | + }, | |
427 | + }, | |
428 | + { | |
429 | + title: '生产科对账单号备注', | |
430 | + dataIndex: 'checkNotes', | |
431 | + width: 200, | |
432 | + }, | |
433 | + { | |
434 | + title: 'CHECKNO状态', | |
435 | + dataIndex: 'checkPayStatus', | |
436 | + width: 120, | |
437 | + customRender: (column) => { | |
438 | + if (column.record.checkPayStatus == null || column.record.checkPayStatus == undefined) { | |
439 | + return '未创建'; | |
440 | + } else if (column.record.checkPayStatus == 0) { | |
441 | + return '未收款'; | |
442 | + } else if (column.record.checkPayStatus == 10) { | |
443 | + return '已收款'; | |
444 | + } | |
445 | + }, | |
446 | + }, | |
447 | + { | |
448 | + title: 'Action', | |
449 | + key: 'action2', // 对应 #bodyCell 中的 column.key | |
450 | + width: 280, | |
451 | + }, | |
452 | +]; | |
453 | +function formatDate(input: string): string { | |
454 | + // 创建一个 Date 对象 | |
455 | + const date = new Date(input); | |
456 | + | |
457 | + // 获取年月日 | |
458 | + const year = date.getFullYear(); | |
459 | + const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始,所以要加 1 | |
460 | + const day = String(date.getDate()).padStart(2, '0'); | |
461 | + | |
462 | + // 返回格式化后的日期字符串 | |
463 | + return `${year}-${month}-${day}`; | |
464 | +} | |
0 | 465 | \ No newline at end of file | ... | ... |
src/views/project/finance/index.vue
0 → 100644
1 | +<template> | |
2 | + <div class="p-4"> | |
3 | + <BasicTable @register="registerTable"> | |
4 | + <template #toolbar> | |
5 | + <a-button | |
6 | + type="primary" | |
7 | + @click="handleCommit" | |
8 | + v-if="role == ROLE.ADMIN || role == ROLE.FINANCE" | |
9 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | |
10 | + >提交应收审核</a-button | |
11 | + > | |
12 | + <a-button | |
13 | + type="primary" | |
14 | + @click="handleCommitCheck" | |
15 | + v-if="role == ROLE.ADMIN || role == ROLE.FINANCE" | |
16 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | |
17 | + >提交应付审核</a-button | |
18 | + > | |
19 | + <a-button | |
20 | + type="primary" | |
21 | + @click="handleInvoiceAnalysis" | |
22 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | |
23 | + v-if="role == ROLE.ADMIN || role == ROLE.FINANCE" | |
24 | + >收款单分析</a-button | |
25 | + > | |
26 | + <a-button | |
27 | + type="primary" | |
28 | + @click="handleCheckSumCheck" | |
29 | + v-if="role == ROLE.ADMIN || role == ROLE.FINANCE" | |
30 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | |
31 | + >应付款汇总</a-button | |
32 | + > | |
33 | + <a-popconfirm | |
34 | + title="请确认是否删除?" | |
35 | + ok-text="是" | |
36 | + cancel-text="否" | |
37 | + @confirm="handleDeleteInvoiceIds" | |
38 | + > | |
39 | + <a-button type="primary" :style="{ borderRadius: '5px 5px 5px 5px' }" | |
40 | + >应付款删除</a-button | |
41 | + > | |
42 | + </a-popconfirm> | |
43 | + <a-popconfirm | |
44 | + title="请确认是否删除?" | |
45 | + ok-text="是" | |
46 | + cancel-text="否" | |
47 | + @confirm="handleDeleteCheckIds" | |
48 | + > | |
49 | + <a-button type="primary" :style="{ borderRadius: '5px 5px 5px 5px' }" | |
50 | + >应收款删除</a-button | |
51 | + > | |
52 | + </a-popconfirm> | |
53 | + <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | |
54 | + <InvoiceAnalysis @register="registerInvoiceAnalysis" /> | |
55 | + <TrackEdit @register="registerTrackEdit" @success="handleSuccess" /> | |
56 | + <InvoiceDetail @register="registerInvoiceDetail" /> | |
57 | + <DeductShow @register="registerDeductShow" /> | |
58 | + <Commit @register="registerCommit" @success="handleSuccess" /> | |
59 | + <EditRefundTime @register="registerEditRefundTime" @success="handleSuccess" /> | |
60 | + <ReUploadBgUrl @register="registerReUploadBgUrl" @success="handleSuccess" /> | |
61 | + <Note @register="registerNote" @success="handleSuccess" /> | |
62 | + <FinanceEditCheck @register="registerFinanceEditCheck" @success="handleSuccess" /> | |
63 | + <TrackEditCheck @register="registerTrackEditCheck" @success="handleSuccess" /> | |
64 | + <CheckSumCheck @register="registerCheckSumCheck" /> | |
65 | + <InvoiceUploadCheck @register="registerInvoiceUploadCheck" @success="handleSuccess" /> | |
66 | + <CheckDetailCheck @register="registerInvoiceDetailCheck" /> | |
67 | + <DeductShowCheck @register="registerDeductShowCheck" /> | |
68 | + <InvoiceShowCheck @register="registerInvoiceShowCheck" /> | |
69 | + <CommitCheck @register="registerCommitCheck" @success="handleSuccess" /> | |
70 | + <EditRefundTimeCheck @register="registerEditRefundTimeCheck" @success="handleSuccess" /> | |
71 | + <NoteCheck @register="registerNoteCheck" @success="handleSuccess" /> | |
72 | + </template> | |
73 | + <template #bodyCell="{ column, record }"> | |
74 | + <template v-if="column.key === 'picUrl'"> | |
75 | + <img :z-index="100000" :width="50" :height="50" :src="record?.smallPicUrl" /> | |
76 | + </template> | |
77 | + <template v-if="column.key === 'action'"> | |
78 | + <TableAction | |
79 | + :actions="[ | |
80 | + // { | |
81 | + // label: '财务编辑', | |
82 | + // onClick: handleFinanceEdit.bind(null, record), | |
83 | + // }, | |
84 | + ...(role == ROLE.ADMIN || role == ROLE.FINANCE | |
85 | + ? [ | |
86 | + { | |
87 | + label: '财务编辑', | |
88 | + onClick: handleFinanceEdit.bind(null, record), | |
89 | + }, | |
90 | + ] | |
91 | + : []), | |
92 | + { | |
93 | + label: '跟单编辑', | |
94 | + onClick: handleTrackEdit.bind(null, record), | |
95 | + }, | |
96 | + // ...(role == ROLE.ADMIN || role == ROLE.FINANCE | |
97 | + // ? [ | |
98 | + // { | |
99 | + // label: '提交审核', | |
100 | + // onClick: handleCommit.bind(null, record), | |
101 | + // }, | |
102 | + // ] | |
103 | + // : []), | |
104 | + ]" | |
105 | + :dropDownActions="[ | |
106 | + { | |
107 | + label: '订单信息', | |
108 | + onClick: handleInvoiceDetail.bind(null, record), | |
109 | + }, | |
110 | + { | |
111 | + label: '更新报关单', | |
112 | + onClick: handleReUploadBgUrl.bind(null, record), | |
113 | + }, | |
114 | + // { | |
115 | + // label: '删除', | |
116 | + // popConfirm: { | |
117 | + // title: '是否确认删除', | |
118 | + // placement: 'left', | |
119 | + // confirm: handleDelete.bind(null, record), | |
120 | + // }, | |
121 | + // // onClick: handleDelete.bind(null, record), | |
122 | + // }, | |
123 | + { | |
124 | + label: '扣款单', | |
125 | + onClick: handleDeductShow.bind(null, record), | |
126 | + }, | |
127 | + ...(role == ROLE.ADMIN | |
128 | + ? [ | |
129 | + { | |
130 | + label: '修改必须回款日期', | |
131 | + onClick: handleEditRefundTime.bind(null, record), | |
132 | + }, | |
133 | + ] | |
134 | + : []), | |
135 | + { | |
136 | + label: '添加备注', | |
137 | + onClick: handleNote.bind(null, record), | |
138 | + }, | |
139 | + ]" | |
140 | + /> | |
141 | + </template> | |
142 | + <template v-if="column.key === 'action2'"> | |
143 | + <TableAction | |
144 | + v-if=" | |
145 | + role == ROLE.ADMIN || | |
146 | + role == ROLE.FINANCE || | |
147 | + role == ROLE.TRACKER || | |
148 | + role == ROLE.BUSINESS | |
149 | + " | |
150 | + :actions="[ | |
151 | + ...(role == ROLE.ADMIN || role == ROLE.FINANCE | |
152 | + ? [ | |
153 | + { | |
154 | + label: '财务编辑', | |
155 | + onClick: handleFinanceEditCheck.bind(null, record), | |
156 | + }, | |
157 | + ] | |
158 | + : []), | |
159 | + { | |
160 | + label: '跟单编辑', | |
161 | + onClick: handleTrackEditCheck.bind(null, record), | |
162 | + }, | |
163 | + { | |
164 | + label: '发票上传', | |
165 | + onClick: handleInvoiceUploadCheck.bind(null, record), | |
166 | + }, | |
167 | + ]" | |
168 | + :dropDownActions="[ | |
169 | + // ...(role == ROLE.ADMIN || role == ROLE.FINANCE | |
170 | + // ? [ | |
171 | + // { | |
172 | + // label: '提交审核', | |
173 | + // onClick: handleCommitCheck.bind(null, record), | |
174 | + // }, | |
175 | + // ] | |
176 | + // : []), | |
177 | + { | |
178 | + label: '订单信息', | |
179 | + onClick: handleDetail.bind(null, record), | |
180 | + }, | |
181 | + // { | |
182 | + // label: '删除', | |
183 | + // popConfirm: { | |
184 | + // title: '是否确认删除', | |
185 | + // placement: 'left', | |
186 | + // confirm: handleDelete.bind(null, record), | |
187 | + // }, | |
188 | + // // onClick: handleDelete.bind(null, record), | |
189 | + // }, | |
190 | + { | |
191 | + label: '生产科发票', | |
192 | + onClick: handleInvoiceShowCheck.bind(null, record), | |
193 | + }, | |
194 | + { | |
195 | + label: '扣款单', | |
196 | + onClick: handleDeductShowCheck.bind(null, record), | |
197 | + }, | |
198 | + ...(role == ROLE.ADMIN | |
199 | + ? [ | |
200 | + { | |
201 | + label: '修改应付款日期', | |
202 | + onClick: handleEditRefundTimeCheck.bind(null, record), | |
203 | + }, | |
204 | + ] | |
205 | + : []), | |
206 | + { | |
207 | + label: '添加备注', | |
208 | + onClick: handleNoteCheck.bind(null, record), | |
209 | + }, | |
210 | + ]" | |
211 | + /> | |
212 | + <TableAction | |
213 | + v-if="role == ROLE.PRODUCE" | |
214 | + :actions="[ | |
215 | + { | |
216 | + label: '发票上传', | |
217 | + onClick: handleInvoiceUploadCheck.bind(null, record), | |
218 | + }, | |
219 | + { | |
220 | + label: '生产科发票', | |
221 | + onClick: handleInvoiceShowCheck.bind(null, record), | |
222 | + }, | |
223 | + ]" | |
224 | + /> | |
225 | + </template> | |
226 | + </template> | |
227 | + </BasicTable> | |
228 | + </div> | |
229 | +</template> | |
230 | +<script lang="ts" setup> | |
231 | + import { computed, defineComponent, ref } from 'vue'; | |
232 | + import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table'; | |
233 | + // import { searchFormSchema, columns } from './receive.data'; | |
234 | + import { searchFormSchema, columns } from './finance.data'; | |
235 | + import FinanceEdit from './FinanceEdit.vue'; | |
236 | + import TrackEdit from './TrackEdit.vue'; | |
237 | + import InvoiceAnalysis from './InvoiceAnalysis.vue'; | |
238 | + import InvoiceDetail from './InvoiceDetail.vue'; | |
239 | + import DeductShow from './DeductShow.vue'; | |
240 | + import Commit from './Commit.vue'; | |
241 | + import EditRefundTime from './EditRefundTime.vue'; | |
242 | + import ReUploadBgUrl from './ReUploadBgUrl.vue'; | |
243 | + import Note from './Note.vue'; | |
244 | + import TrackEditCheck from './TrackEditCheck.vue'; | |
245 | + import FinanceEditCheck from './FinanceEditCheck.vue'; | |
246 | + import InvoiceUploadCheck from './InvoiceUploadCheck.vue'; | |
247 | + import CheckDetailCheck from './CheckDetailCheck.vue'; | |
248 | + import CheckSumCheck from './CheckSumCheck.vue'; | |
249 | + import DeductShowCheck from './DeductShowCheck.vue'; | |
250 | + import InvoiceShowCheck from './InvoiceShowCheck.vue'; | |
251 | + import CommitCheck from './CommitCheck.vue'; | |
252 | + import EditRefundTimeCheck from './EditRefundTimeCheck.vue'; | |
253 | + import NoteCheck from './NoteCheck.vue'; | |
254 | + import { useDrawer } from '/@/components/Drawer'; | |
255 | + import { | |
256 | + getCheck, | |
257 | + checkDelete, | |
258 | + checkCommit, | |
259 | + checkDetail, | |
260 | + getInvoice, | |
261 | + deleteInvoice, | |
262 | + commit, | |
263 | + getBaseInvoice, | |
264 | + } from '@/api/project/invoice'; | |
265 | + import { useModal } from '/@/components/Modal'; | |
266 | + import { CheckOutlined, FilePptOutlined } from '@ant-design/icons-vue'; | |
267 | + import { icon } from 'ant-design-vue'; | |
268 | + import { ROLE } from './type.d'; | |
269 | + import { useUserStoreWithOut } from '/@/store/modules/user'; | |
270 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
271 | + | |
272 | + const [registerInvoiceAnalysis, { openModal: openInvoiceAnalysis }] = useModal(); | |
273 | + const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); | |
274 | + const [registerTrackEdit, { openDrawer: openTrackEdit }] = useDrawer(); | |
275 | + const [registerInvoiceDetail, { openDrawer: openInvoiceDetail }] = useDrawer(); | |
276 | + const [registerCommit, { openModal: openCommit }] = useModal(); | |
277 | + const [registerEditRefundTime, { openModal: openEditRefundTime }] = useModal(); | |
278 | + const [registerReUploadBgUrl, { openModal: openReUploadBgUrl }] = useModal(); | |
279 | + const [registerNote, { openModal: openNote }] = useModal(); | |
280 | + const [registerDeductShow, { openModal: openDeductShow }] = useModal(); | |
281 | + const [registerCheckSumCheck, { openModal: openCheckSumCheck }] = useModal(); | |
282 | + const [registerFinanceEditCheck, { openDrawer: openFinanceEditCheck }] = useDrawer(); | |
283 | + const [registerTrackEditCheck, { openDrawer: openTrackEditCheck }] = useDrawer(); | |
284 | + const [registerInvoiceUploadCheck, { openModal: openInvoiceUploadCheck }] = useModal(); | |
285 | + const [registerDeductShowCheck, { openModal: openDeductShowCheck }] = useModal(); | |
286 | + const [registerCommitCheck, { openModal: openCommitCheck }] = useModal(); | |
287 | + const [registerEditRefundTimeCheck, { openModal: openEditRefundTimeCheck }] = useModal(); | |
288 | + const [registerInvoiceShowCheck, { openModal: openInvoiceShowCheck }] = useModal(); | |
289 | + const [registerNoteCheck, { openModal: openNoteCheck }] = useModal(); | |
290 | + const [registerInvoiceDetailCheck, { openDrawer: openCheckDetailCheck }] = useDrawer(); | |
291 | + const checkedKeys = ref<Array<string | number>>([]); | |
292 | + const invoiceIdKeys = ref<Array<string | number>>([]); | |
293 | + const checkIdKeys = ref<Array<string | number>>([]); | |
294 | + const userStore = useUserStoreWithOut(); | |
295 | + const user = userStore.getUserInfo; | |
296 | + const role = computed(() => { | |
297 | + return user?.roleSmallVO?.code; | |
298 | + }); | |
299 | + const [registerTable, { reload: reloadTable }] = useTable({ | |
300 | + title: '', | |
301 | + api: getInvoice, | |
302 | + columns: columns, | |
303 | + bordered: true, | |
304 | + clickToRowSelect: false, | |
305 | + rowKey: 'id', | |
306 | + rowSelection: { | |
307 | + type: 'checkbox', | |
308 | + selectedRowKeys: checkedKeys, | |
309 | + onSelect, | |
310 | + onSelectAll, | |
311 | + }, | |
312 | + formConfig: { | |
313 | + labelWidth: 120, | |
314 | + schemas: searchFormSchema, | |
315 | + autoSubmitOnEnter: true, | |
316 | + }, | |
317 | + useSearchForm: true, | |
318 | + showTableSetting: true, | |
319 | + showIndexColumn: false, | |
320 | + tableSetting: { | |
321 | + setting: false, | |
322 | + }, | |
323 | + // actionColumn: { | |
324 | + // width: 330, | |
325 | + // title: 'Action', | |
326 | + // dataIndex: 'action', | |
327 | + // // slots: { customRender: 'action' }, | |
328 | + // }, | |
329 | + }); | |
330 | + | |
331 | + // 单选函数 | |
332 | + async function onSelect(record, selected: boolean) { | |
333 | + console.log(record, '5656565656record'); | |
334 | + | |
335 | + if (selected) { | |
336 | + checkedKeys.value = [...checkedKeys.value, record.id]; | |
337 | + | |
338 | + // 仅当 invoiceId 不为 undefined 时,才加入 | |
339 | + if (record.invoiceId !== undefined) { | |
340 | + invoiceIdKeys.value = [...invoiceIdKeys.value, record.invoiceId]; | |
341 | + } | |
342 | + | |
343 | + // 仅当 checkId 不为 undefined 时,才加入 | |
344 | + if (record.checkId !== undefined) { | |
345 | + checkIdKeys.value = [...checkIdKeys.value, record.checkId]; | |
346 | + } | |
347 | + } else { | |
348 | + checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); | |
349 | + | |
350 | + // 仅当 invoiceId 不为 undefined 时,才删除 | |
351 | + if (record.invoiceId !== undefined) { | |
352 | + invoiceIdKeys.value = invoiceIdKeys.value.filter( | |
353 | + (invoiceId) => invoiceId !== record.invoiceId, | |
354 | + ); | |
355 | + } | |
356 | + | |
357 | + // 仅当 checkId 不为 undefined 时,才删除 | |
358 | + if (record.checkId !== undefined) { | |
359 | + checkIdKeys.value = checkIdKeys.value.filter((checkId) => checkId !== record.checkId); | |
360 | + } | |
361 | + } | |
362 | + | |
363 | + console.log(checkedKeys.value, 565666666); // 输出当前的 checkedKeys 值 | |
364 | + console.log(invoiceIdKeys.value, 565666666); // 输出当前的 selectedCustomCodes 值 | |
365 | + console.log(checkIdKeys.value, 565666666); // 输出当前的 selectedProductionDepartment 值 | |
366 | + } | |
367 | + | |
368 | + // 全选函数 | |
369 | + async function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) { | |
370 | + const changeIds = changeRows.map((item) => item.id); | |
371 | + const invoiceIds = changeRows.map((item) => item.invoiceId); | |
372 | + const checkIds = changeRows.map((item) => item.checkId); | |
373 | + | |
374 | + if (selected) { | |
375 | + checkedKeys.value = [...checkedKeys.value, ...changeIds]; | |
376 | + | |
377 | + // 过滤掉 undefined 的 invoiceId 和 checkId | |
378 | + invoiceIdKeys.value = [ | |
379 | + ...invoiceIdKeys.value, | |
380 | + ...invoiceIds.filter((invoiceId) => invoiceId !== undefined), | |
381 | + ]; | |
382 | + checkIdKeys.value = [ | |
383 | + ...checkIdKeys.value, | |
384 | + ...checkIds.filter((checkId) => checkId !== undefined), | |
385 | + ]; | |
386 | + } else { | |
387 | + checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id)); | |
388 | + | |
389 | + // 仅当 invoiceId 不为 undefined 时,才删除 | |
390 | + invoiceIdKeys.value = invoiceIdKeys.value.filter( | |
391 | + (invoiceId) => invoiceIds.indexOf(invoiceId) === -1, | |
392 | + ); | |
393 | + | |
394 | + // 仅当 checkId 不为 undefined 时,才删除 | |
395 | + checkIdKeys.value = checkIdKeys.value.filter((checkId) => checkIds.indexOf(checkId) === -1); | |
396 | + } | |
397 | + | |
398 | + console.log(checkedKeys.value, 565666666); // 输出当前的 checkedKeys 值 | |
399 | + console.log(invoiceIdKeys.value, 565666666); // 输出当前的 selectedCustomCodes 值 | |
400 | + console.log(checkIdKeys.value, 565666666); // 输出当前的 selectedProductionDepartment 值 | |
401 | + } | |
402 | + | |
403 | + function handleFinanceEdit(record) { | |
404 | + openFinanceEdit(true, { | |
405 | + data: record, | |
406 | + }); | |
407 | + } | |
408 | + function handleTrackEdit(record) { | |
409 | + openTrackEdit(true, { | |
410 | + data: record, | |
411 | + }); | |
412 | + } | |
413 | + function handleDelete(record) { | |
414 | + const id: string[] = Array.isArray(record.id) ? record.id : [record.id]; | |
415 | + deleteInvoice({ ids: id }); | |
416 | + setTimeout(() => { | |
417 | + reloadTable(); | |
418 | + }, 50); | |
419 | + } | |
420 | + function handleDeleteInvoiceIds() { | |
421 | + // console.log(checkedKeys.value, '5656checkedKeys.value'); | |
422 | + deleteInvoice({ ids: invoiceIdKeys.value }); | |
423 | + setTimeout(() => { | |
424 | + reloadTable(); | |
425 | + }, 50); | |
426 | + } | |
427 | + function handleDeleteCheckIds() { | |
428 | + // console.log(checkedKeys.value, '5656checkedKeys.value'); | |
429 | + deleteInvoice({ ids: checkIdKeys.value }); | |
430 | + setTimeout(() => { | |
431 | + reloadTable(); | |
432 | + }, 50); | |
433 | + } | |
434 | + function handleDeductShow(record) { | |
435 | + openDeductShow(true, { | |
436 | + data: record, | |
437 | + }); | |
438 | + } | |
439 | + function handleCommit(record) { | |
440 | + openCommit(true, { | |
441 | + data: invoiceIdKeys.value, | |
442 | + }); | |
443 | + } | |
444 | + function handleEditRefundTime(record) { | |
445 | + openEditRefundTime(true, { | |
446 | + data: record, | |
447 | + }); | |
448 | + } | |
449 | + function handleInvoiceDetail(record) { | |
450 | + openInvoiceDetail(true, { | |
451 | + data: record, | |
452 | + }); | |
453 | + } | |
454 | + function handleReUploadBgUrl(record) { | |
455 | + openReUploadBgUrl(true, { | |
456 | + data: record, | |
457 | + }); | |
458 | + } | |
459 | + function handleNote(record) { | |
460 | + openNote(true, { | |
461 | + data: record, | |
462 | + }); | |
463 | + } | |
464 | + const { createMessage } = useMessage(); | |
465 | + const { error } = createMessage; | |
466 | + function handleInvoiceAnalysis(record) { | |
467 | + if (invoiceIdKeys.value.length == 0) { | |
468 | + error('请选择订单'); | |
469 | + return; | |
470 | + } | |
471 | + openInvoiceAnalysis(true, { | |
472 | + data: invoiceIdKeys.value, | |
473 | + }); | |
474 | + } | |
475 | + | |
476 | + function handleSuccess() { | |
477 | + setTimeout(() => { | |
478 | + reloadTable(); | |
479 | + }, 50); | |
480 | + } | |
481 | + | |
482 | + function handleFinanceEditCheck(record) { | |
483 | + openFinanceEditCheck(true, { | |
484 | + data: record, | |
485 | + }); | |
486 | + } | |
487 | + function handleTrackEditCheck(record) { | |
488 | + openTrackEditCheck(true, { | |
489 | + data: record, | |
490 | + }); | |
491 | + } | |
492 | + function handleInvoiceUploadCheck(record) { | |
493 | + openInvoiceUploadCheck(true, { | |
494 | + data: record, | |
495 | + }); | |
496 | + } | |
497 | + function handleInvoiceShowCheck(record) { | |
498 | + openInvoiceShowCheck(true, { | |
499 | + data: record, | |
500 | + }); | |
501 | + } | |
502 | + function handleNoteCheck(record) { | |
503 | + openNoteCheck(true, { | |
504 | + data: record, | |
505 | + }); | |
506 | + } | |
507 | + function handleDeductShowCheck(record) { | |
508 | + openDeductShowCheck(true, { | |
509 | + data: record, | |
510 | + }); | |
511 | + } | |
512 | + function handleDetail(record) { | |
513 | + openCheckDetailCheck(true, { | |
514 | + data: record, | |
515 | + }); | |
516 | + } | |
517 | + function handleCommitCheck(record) { | |
518 | + openCommitCheck(true, { | |
519 | + data: checkIdKeys.value, | |
520 | + }); | |
521 | + } | |
522 | + function handleEditRefundTimeCheck(record) { | |
523 | + openEditRefundTimeCheck(true, { | |
524 | + data: record, | |
525 | + }); | |
526 | + } | |
527 | + function handleCheckSumCheck(record) { | |
528 | + if (checkIdKeys.value.length == 0) { | |
529 | + error('请选择订单'); | |
530 | + return; | |
531 | + } | |
532 | + openCheckSumCheck(true, { | |
533 | + data: checkIdKeys.value, | |
534 | + }); | |
535 | + } | |
536 | +</script> | ... | ... |
src/views/project/finance/pay/CheckSum.vue
src/views/project/finance/pay/InvoiceUpload.vue
... | ... | @@ -33,8 +33,8 @@ |
33 | 33 | import { updateInvoiceInfo } from '@/api/project/invoice'; |
34 | 34 | |
35 | 35 | const emit = defineEmits(['success']); |
36 | - const uploadUrl = ref('http://47.104.8.35:8081/api/localStorage/upload_file_oss?name='); | |
37 | - const updateInvoiceUrl = ref('http://47.104.8.35:8081/api/localStorage/upload_file_oss?name='); | |
36 | + const uploadUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
37 | + const updateInvoiceUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
38 | 38 | const invoiceUrl = ref(); |
39 | 39 | const id = ref(); |
40 | 40 | const status = ref(); | ... | ... |
src/views/project/finance/pay/Note.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="添加备注" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + @visible-change="handleShow" | |
10 | + > | |
11 | + 备注: | |
12 | + <a-textarea v-model:value="notes" placeholder="请输入" :rows="6" /> | |
13 | + <div style="height: 10px"></div> | |
14 | + </BasicModal> | |
15 | +</template> | |
16 | +<script lang="ts" setup> | |
17 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
18 | + import { ref } from 'vue'; | |
19 | + import { getSetBackRefundDate } from '@/api/project/invoice'; | |
20 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
21 | + | |
22 | + const id = ref(); | |
23 | + const notes = ref(); | |
24 | + const checkedKeys = ref(); | |
25 | + const emit = defineEmits(['success']); | |
26 | + const { createMessage } = useMessage(); | |
27 | + const { error } = createMessage; | |
28 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
29 | + // id.value = data.data.id; | |
30 | + checkedKeys.value = data.checkedKeys; | |
31 | + }); | |
32 | + const isDisabled = ref(false); | |
33 | + async function handleOk() { | |
34 | + if (isDisabled.value) { | |
35 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
36 | + return; | |
37 | + } | |
38 | + isDisabled.value = true; | |
39 | + setTimeout(() => { | |
40 | + isDisabled.value = false; | |
41 | + }, 3000); | |
42 | + getSetBackRefundDate({ id: checkedKeys.value, notes: notes.value }); | |
43 | + emit('success'); | |
44 | + closeModal(); | |
45 | + } | |
46 | + function handleShow(visible: boolean) { | |
47 | + if (!visible) { | |
48 | + notes.value = null; | |
49 | + } | |
50 | + } | |
51 | +</script> | ... | ... |
src/views/project/finance/pay/TrackEdit.vue
... | ... | @@ -87,8 +87,10 @@ |
87 | 87 | const id = ref(); |
88 | 88 | const checkNo = ref(); |
89 | 89 | const deductDept = ref(); |
90 | - const uploadUrl = ref('http://47.104.8.35:8081/api/localStorage/upload_file_oss?name='); | |
91 | - const updateDeductUrl = ref('http://47.104.8.35:8081/api/localStorage/upload_file_oss?name='); | |
90 | + const uploadUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
91 | + const updateDeductUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
92 | + // const uploadUrl = ref(''); | |
93 | + // const updateDeductUrl = ref(''); | |
92 | 94 | const deductUrlOld = ref(); |
93 | 95 | const selectedProductionDepartment = ref(); // 新增: 用于存储选中的生产科 |
94 | 96 | const { createMessage } = useMessage(); | ... | ... |
src/views/project/finance/pay/index.vue
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 | <InvoiceShow @register="registerInvoiceShow" /> |
18 | 18 | <Commit @register="registerCommit" @success="handleSuccess" /> |
19 | 19 | <EditRefundTime @register="registerEditRefundTime" @success="handleSuccess" /> |
20 | + <Note @register="registerNote" @success="handleSuccess" /> | |
20 | 21 | </template> |
21 | 22 | <template #bodyCell="{ column, record }"> |
22 | 23 | <template v-if="column.key === 'action'"> |
... | ... | @@ -83,6 +84,10 @@ |
83 | 84 | }, |
84 | 85 | ] |
85 | 86 | : []), |
87 | + { | |
88 | + label: '添加备注', | |
89 | + onClick: handleNote.bind(null, record), | |
90 | + }, | |
86 | 91 | ]" |
87 | 92 | /> |
88 | 93 | <TableAction |
... | ... | @@ -116,6 +121,7 @@ |
116 | 121 | import InvoiceShow from './InvoiceShow.vue'; |
117 | 122 | import Commit from './Commit.vue'; |
118 | 123 | import EditRefundTime from './EditRefundTime.vue'; |
124 | + import Note from './Note.vue'; | |
119 | 125 | import { useDrawer } from '/@/components/Drawer'; |
120 | 126 | import { useModal } from '/@/components/Modal'; |
121 | 127 | import { getCheck, checkDelete, checkCommit, checkDetail } from '@/api/project/invoice'; |
... | ... | @@ -132,6 +138,7 @@ |
132 | 138 | const [registerCommit, { openModal: openCommit }] = useModal(); |
133 | 139 | const [registerEditRefundTime, { openModal: openEditRefundTime }] = useModal(); |
134 | 140 | const [registerInvoiceShow, { openModal: openInvoiceShow }] = useModal(); |
141 | + const [registerNote, { openModal: openNote }] = useModal(); | |
135 | 142 | const [registerInvoiceDetail, { openDrawer: openCheckDetail }] = useDrawer(); |
136 | 143 | const userStore = useUserStoreWithOut(); |
137 | 144 | const user = userStore.getUserInfo; |
... | ... | @@ -350,6 +357,11 @@ |
350 | 357 | data: record, |
351 | 358 | }); |
352 | 359 | } |
360 | + function handleNote(record) { | |
361 | + openNote(true, { | |
362 | + data: record, | |
363 | + }); | |
364 | + } | |
353 | 365 | function handleDeductShow(record) { |
354 | 366 | openDeductShow(true, { |
355 | 367 | data: record, | ... | ... |
src/views/project/finance/payBack/CheckDetailCheck.vue
0 → 100644
1 | +<template> | |
2 | + <template> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + title="订单信息" | |
7 | + width="60%" | |
8 | + :isDetail="true" | |
9 | + :showDetailBack="false" | |
10 | + :destroyOnClose="true" | |
11 | + > | |
12 | + <div class="p-4"> | |
13 | + <BasicTable @register="registerTable"> | |
14 | + <template #bodyCell="{ column, record }"> | |
15 | + <template v-if="column.key === 'action'"> </template> | |
16 | + <template v-if="column.key === 'picUrl'"> | |
17 | + <img :z-index="100000" :width="50" :height="50" :src="record?.smallPicUrl" /> | |
18 | + </template> | |
19 | + </template> | |
20 | + </BasicTable> | |
21 | + </div> | |
22 | + </BasicDrawer> | |
23 | + </template> | |
24 | +</template> | |
25 | +<script lang="ts" setup> | |
26 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | |
27 | + import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue'; | |
28 | + import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table'; | |
29 | + import { checkDetail } from '/@/api/project/invoice'; | |
30 | + import { useDesign } from '@/hooks/web/useDesign'; | |
31 | + | |
32 | + // const handlePreview = (url) => { | |
33 | + // createImgPreview({ imageList: [url], defaultWidth: 500 }); | |
34 | + // return false; | |
35 | + // }; | |
36 | + const columns: BasicColumn[] = [ | |
37 | + { | |
38 | + title: '客户编码', | |
39 | + dataIndex: 'customerCode', | |
40 | + width: 100, | |
41 | + }, | |
42 | + { | |
43 | + title: '项目号', | |
44 | + dataIndex: 'projectNo', | |
45 | + width: 100, | |
46 | + }, | |
47 | + { | |
48 | + title: '内部编码', | |
49 | + dataIndex: 'innerNo', | |
50 | + width: 100, | |
51 | + }, | |
52 | + { | |
53 | + title: '客户po号', | |
54 | + dataIndex: 'customerPo', | |
55 | + width: 100, | |
56 | + }, | |
57 | + { | |
58 | + title: '客户STYLE', | |
59 | + width: 150, | |
60 | + dataIndex: 'customerStyle', | |
61 | + }, | |
62 | + { | |
63 | + title: 'Model(REFERENCE)', | |
64 | + width: 150, | |
65 | + dataIndex: 'modeleLo', | |
66 | + }, | |
67 | + { | |
68 | + title: '订单图片', | |
69 | + width: 150, | |
70 | + dataIndex: 'picUrl', | |
71 | + }, | |
72 | + { | |
73 | + title: '数量', | |
74 | + width: 150, | |
75 | + dataIndex: 'orderCount', | |
76 | + }, | |
77 | + { | |
78 | + title: '生产科单价¥', | |
79 | + width: 150, | |
80 | + dataIndex: 'productionDepartmentPrice', | |
81 | + customRender: (column) => { | |
82 | + const { record } = column || {}; | |
83 | + return record?.profitAnalysisInfo?.productionDepartmentPrice?.toFixed(2); | |
84 | + // ? `¥ ${record?.profitAnalysisInfo?.productionDepartmentPrice}` | |
85 | + // : ''; | |
86 | + }, | |
87 | + }, | |
88 | + { | |
89 | + title: '生产科总价¥', | |
90 | + width: 150, | |
91 | + dataIndex: 'productionDepartmentTotalPrice', | |
92 | + customRender: (column) => { | |
93 | + const { record } = column || {}; | |
94 | + return record?.profitAnalysisInfo?.productionDepartmentTotalPrice?.toFixed(2); | |
95 | + // ? `¥ ${record?.profitAnalysisInfo?.productionDepartmentTotalPrice}` | |
96 | + // : ''; | |
97 | + }, | |
98 | + }, | |
99 | + ]; | |
100 | + const checkNo = ref(); | |
101 | + | |
102 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
103 | + // 方式1 | |
104 | + checkNo.value = data.data.checkNo; | |
105 | + // checkDetail({ checkNo: checkNo.value }); | |
106 | + }); | |
107 | + const params = ref({ | |
108 | + checkNo: checkNo.value, | |
109 | + }); | |
110 | + const [registerTable] = useTable({ | |
111 | + api: () => { | |
112 | + const res = checkDetail({ checkNo: checkNo.value }); | |
113 | + return res; | |
114 | + }, | |
115 | + columns: columns, | |
116 | + bordered: true, | |
117 | + }); | |
118 | +</script> | ... | ... |
src/views/project/finance/payBack/CheckSumCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="应收款汇总" | |
6 | + width="60%" | |
7 | + okText="导出" | |
8 | + :isDetail="true" | |
9 | + :showDetailBack="false" | |
10 | + @ok="handleOk" | |
11 | + @visible-change="handleShow" | |
12 | + > | |
13 | + <div class="p-4"> | |
14 | + <BasicTable @register="registerTable"> | |
15 | + <template #bodyCell="{ column, record }"> | |
16 | + <template v-if="column.key === 'action'"> </template> | |
17 | + </template> | |
18 | + </BasicTable> | |
19 | + </div> | |
20 | + </BasicModal> | |
21 | +</template> | |
22 | +<script lang="ts" setup> | |
23 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
24 | + import { computed, ref } from 'vue'; | |
25 | + import { checkAnalysis, exportCheckAnalysis } from '@/api/project/invoice'; | |
26 | + import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table'; | |
27 | + // 处理弹窗的确定按钮点击事件 | |
28 | + import axios from 'axios'; | |
29 | + | |
30 | + const columnsAnalysis: BasicColumn[] = [ | |
31 | + { | |
32 | + title: '生产科名称', | |
33 | + dataIndex: 'productionDepartment', | |
34 | + width: 150, | |
35 | + customRender: (res) => { | |
36 | + // console.log(res, 56562); | |
37 | + return res.record.exportVOS[0].productionDepartment; | |
38 | + }, | |
39 | + }, | |
40 | + { | |
41 | + title: '生产科总价汇总¥', | |
42 | + dataIndex: 'productionDepartmentTotalPrice', | |
43 | + width: 150, | |
44 | + customRender: (res) => { | |
45 | + // console.log(res, 56562); | |
46 | + return res.record.productionDepartmentTotalPrice.toFixed(2); | |
47 | + }, | |
48 | + }, | |
49 | + { | |
50 | + title: '生产科扣款金额汇总¥', | |
51 | + dataIndex: 'deductAmount', | |
52 | + width: 160, | |
53 | + customRender: (res) => { | |
54 | + // console.log(res, 56562); | |
55 | + return res.record.deductAmount.toFixed(2); | |
56 | + }, | |
57 | + }, | |
58 | + { | |
59 | + title: '生产科实际应付金额¥', | |
60 | + dataIndex: 'calculateActualPayedAmount', | |
61 | + width: 160, | |
62 | + customRender: (res) => { | |
63 | + return res.record.calculateActualPayedAmount.toFixed(2); | |
64 | + }, | |
65 | + }, | |
66 | + { | |
67 | + title: '实际付款金额汇总¥', | |
68 | + dataIndex: 'actualPayedAmount', | |
69 | + width: 160, | |
70 | + customRender: (res) => { | |
71 | + // console.log(res, 56562); | |
72 | + return res.record.actualPayedAmount.toFixed(2); | |
73 | + }, | |
74 | + }, | |
75 | + { | |
76 | + title: '未付金额¥', | |
77 | + dataIndex: 'unPayedAmount', | |
78 | + width: 150, | |
79 | + customRender: (res) => { | |
80 | + // console.log(res, 56562); | |
81 | + return res.record.unPayedAmount.toFixed(2); | |
82 | + }, | |
83 | + }, | |
84 | + ]; | |
85 | + // const ids = ref<number[]>([]); | |
86 | + const ids = ref(); | |
87 | + // const res = ref(); | |
88 | + | |
89 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
90 | + ids.value = data.data; | |
91 | + setTimeout(() => { | |
92 | + reload(); | |
93 | + }, 50); | |
94 | + }); | |
95 | + const [registerTable, { reload }] = useTable({ | |
96 | + // api: () => invoiceAnalysis({ ids: ids.value }), | |
97 | + api: async () => { | |
98 | + const res = await checkAnalysis({ ids: ids.value }); | |
99 | + const arrayRes = ref([]); | |
100 | + arrayRes.value.push(res); | |
101 | + console.log(res, '5656payana'); | |
102 | + return res; | |
103 | + }, | |
104 | + columns: columnsAnalysis, | |
105 | + bordered: true, | |
106 | + }); | |
107 | + function handleShow(visible: boolean) { | |
108 | + reload(); | |
109 | + } | |
110 | + const searchData = ref({}); | |
111 | + async function handleOk() { | |
112 | + // 构造符合 API 要求的参数 | |
113 | + // const ids = [23]; | |
114 | + // const requestData = { | |
115 | + // ids: ids.value, | |
116 | + // }; | |
117 | + const idss = ids.value; | |
118 | + // await exportCheckAnalysis({ ids: ids }); | |
119 | + axios | |
120 | + .post( | |
121 | + '/basic-api/order/erp/check_bill/export', | |
122 | + { ids: idss }, | |
123 | + { | |
124 | + responseType: 'blob', // 设置响应类型为 'blob' | |
125 | + }, | |
126 | + ) | |
127 | + .then((response) => { | |
128 | + // 创建一个 Blob 对象来保存二进制数据 | |
129 | + const blob = new Blob([response.data], { type: 'application/zip' }); | |
130 | + const getFormattedDate = (): string => { | |
131 | + const date = new Date(); | |
132 | + | |
133 | + const year = date.getFullYear(); | |
134 | + const month = String(date.getMonth() + 1).padStart(2, '0'); | |
135 | + const day = String(date.getDate()).padStart(2, '0'); | |
136 | + | |
137 | + const hours = String(date.getHours()).padStart(2, '0'); | |
138 | + const minutes = String(date.getMinutes()).padStart(2, '0'); | |
139 | + const seconds = String(date.getSeconds()).padStart(2, '0'); | |
140 | + | |
141 | + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | |
142 | + }; | |
143 | + const date = getFormattedDate(); | |
144 | + // 创建一个链接元素用于下载 | |
145 | + const link = document.createElement('a'); | |
146 | + link.href = window.URL.createObjectURL(blob); | |
147 | + link.download = `应付款分析${date}.xlsx`; // 你可以为文件命名 | |
148 | + document.body.appendChild(link); | |
149 | + link.click(); // 自动点击链接,触发下载 | |
150 | + document.body.removeChild(link); // 下载完成后移除链接 | |
151 | + }) | |
152 | + .catch((error) => { | |
153 | + console.error(error); | |
154 | + }); | |
155 | + reload(); | |
156 | + closeModal(); | |
157 | + } | |
158 | +</script> | |
159 | +<style scoped> | |
160 | + .divAll { | |
161 | + display: flex; | |
162 | + justify-content: center; | |
163 | + align-items: center; | |
164 | + } | |
165 | +</style> | ... | ... |
src/views/project/finance/payBack/CommitCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="提交审核" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + > | |
10 | + 请选择日期: | |
11 | + <a-date-picker v-model:value="date" /> | |
12 | + </BasicModal> | |
13 | +</template> | |
14 | +<script lang="ts" setup> | |
15 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
16 | + import { ref } from 'vue'; | |
17 | + import { checkCommit } from '@/api/project/invoice'; | |
18 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
19 | + | |
20 | + const id = ref(); | |
21 | + const date = ref(); | |
22 | + const emit = defineEmits(['success']); | |
23 | + const { createMessage } = useMessage(); | |
24 | + const { error } = createMessage; | |
25 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
26 | + id.value = data.data.id; | |
27 | + }); | |
28 | + function formatDate(input: string): string { | |
29 | + // 创建一个 Date 对象 | |
30 | + const date = new Date(input); | |
31 | + | |
32 | + // 获取年月日 | |
33 | + const year = date.getFullYear(); | |
34 | + const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始,所以要加 1 | |
35 | + const day = String(date.getDate()).padStart(2, '0'); | |
36 | + | |
37 | + // 返回格式化后的日期字符串 | |
38 | + return `${year}-${month}-${day}`; | |
39 | + } | |
40 | + const isDisabled = ref(false); | |
41 | + async function handleOk() { | |
42 | + if (isDisabled.value) { | |
43 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
44 | + return; | |
45 | + } | |
46 | + const formattedDate = formatDate(date.value); | |
47 | + isDisabled.value = true; | |
48 | + setTimeout(() => { | |
49 | + isDisabled.value = false; | |
50 | + }, 3000); | |
51 | + checkCommit({ id: id.value, actualPayedDate: formattedDate }); | |
52 | + emit('success'); | |
53 | + closeModal(); | |
54 | + } | |
55 | +</script> | ... | ... |
src/views/project/finance/payBack/DeductShowCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="扣款单" | |
6 | + width="700px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + > | |
10 | + <a-list item-layout="horizontal" :data-source="itemArray"> | |
11 | + <template #renderItem="{ item }"> | |
12 | + <a-list-item> | |
13 | + <a-list-item-meta> | |
14 | + <template #title> | |
15 | + <!-- <a :href="item.url" target="_blank" rel="noopener noreferrer">{{ item.name }}</a> --> | |
16 | + <a | |
17 | + v-if="isImageUrl(item.url)" | |
18 | + @click="openPic(item.url)" | |
19 | + style="display: flex; align-items: center" | |
20 | + > | |
21 | + <img | |
22 | + :src="item.url" | |
23 | + alt="Image" | |
24 | + style="max-width: 150px; max-height: 150px; margin-right: 10px" | |
25 | + /> | |
26 | + {{ item.name }} | |
27 | + </a> | |
28 | + <a v-else @click="openPic(item.url)">{{ item.name }}</a> | |
29 | + <!-- <a @click="openPic(item.url)">{{ item.name }}</a> --> | |
30 | + </template> | |
31 | + </a-list-item-meta> | |
32 | + </a-list-item> | |
33 | + </template> | |
34 | + </a-list> | |
35 | + </BasicModal> | |
36 | +</template> | |
37 | +<script lang="ts" setup> | |
38 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
39 | + import { computed, ref } from 'vue'; | |
40 | + import type { UploadProps, UploadChangeParam } from 'ant-design-vue'; | |
41 | + import { InboxOutlined } from '@ant-design/icons-vue'; | |
42 | + import { message } from 'ant-design-vue'; | |
43 | + import { getDeductUrlById } from '@/api/project/invoice'; | |
44 | + import { view } from '@/utils/pdfShow'; | |
45 | + | |
46 | + interface Item { | |
47 | + name: string; | |
48 | + url: string; | |
49 | + } | |
50 | + | |
51 | + const list = ref(); | |
52 | + const id = ref(); | |
53 | + const itemArray = ref<Item[]>([]); | |
54 | + | |
55 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
56 | + itemArray.value = []; | |
57 | + const res = await getDeductUrlById({ id: data.data.id }); | |
58 | + for (let item in res) { | |
59 | + const url = res[item]; | |
60 | + const name = item; | |
61 | + // 将 name 和 url 放入对象并添加到数组中 | |
62 | + itemArray.value.push({ name, url }); | |
63 | + } | |
64 | + }); | |
65 | + | |
66 | + async function handleOk() { | |
67 | + itemArray.value = []; | |
68 | + closeModal(); | |
69 | + } | |
70 | + | |
71 | + // 新增的函数:判断 URL 是否为图片格式 | |
72 | + function isImageUrl(url: string): boolean { | |
73 | + const imageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg']; | |
74 | + const baseUrl = url.split('?')[0]; | |
75 | + return imageExtensions.some((ext) => baseUrl.toLowerCase().endsWith(ext)); | |
76 | + } | |
77 | + // 检查 URL 是否为 PDF 格式 | |
78 | + function isPdfUrl(url: string): boolean { | |
79 | + return url.toLowerCase().endsWith('.pdf'); | |
80 | + } | |
81 | + // 打开图片或 PDF | |
82 | + function openPic(url: string) { | |
83 | + const baseUrl = url.split('?')[0]; // 获取问号前的部分 | |
84 | + if (isImageUrl(baseUrl)) { | |
85 | + window.open('', '', '').document.write(`<!DOCTYPE html> | |
86 | + <html> | |
87 | + <body style="display: flex; justify-content: center; align-items: center;"> | |
88 | + <img src='${url}' width="300px" height="auto"/> | |
89 | + </body> | |
90 | + </html>`); | |
91 | + } else if (isPdfUrl(baseUrl)) { | |
92 | + view(url); // 新标签页打开 PDF | |
93 | + } else { | |
94 | + console.log('不支持的文件类型'); | |
95 | + } | |
96 | + } | |
97 | +</script> | ... | ... |
src/views/project/finance/payBack/EditRefundTimeCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="修改应付款日期" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @visible-change="handleShow" | |
9 | + @ok="handleOk" | |
10 | + > | |
11 | + 请选择日期: | |
12 | + <a-date-picker v-model:value="date" /> | |
13 | + <div style="height: 10px"></div> | |
14 | + </BasicModal> | |
15 | +</template> | |
16 | +<script lang="ts" setup> | |
17 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
18 | + import { ref } from 'vue'; | |
19 | + import { getSetPayedDate } from '@/api/project/invoice'; | |
20 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
21 | + | |
22 | + const id = ref(); | |
23 | + const date = ref(); | |
24 | + const emit = defineEmits(['success']); | |
25 | + const { createMessage } = useMessage(); | |
26 | + const { error } = createMessage; | |
27 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
28 | + id.value = data.data.id; | |
29 | + }); | |
30 | + function formatDate(input: string): string { | |
31 | + // 创建一个 Date 对象 | |
32 | + const date = new Date(input); | |
33 | + | |
34 | + // 获取年月日 | |
35 | + const year = date.getFullYear(); | |
36 | + const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始,所以要加 1 | |
37 | + const day = String(date.getDate()).padStart(2, '0'); | |
38 | + | |
39 | + // 返回格式化后的日期字符串 | |
40 | + return `${year}-${month}-${day}`; | |
41 | + } | |
42 | + const isDisabled = ref(false); | |
43 | + async function handleOk() { | |
44 | + if (isDisabled.value) { | |
45 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
46 | + return; | |
47 | + } | |
48 | + const formattedDate = formatDate(date.value); | |
49 | + isDisabled.value = true; | |
50 | + setTimeout(() => { | |
51 | + isDisabled.value = false; | |
52 | + }, 3000); | |
53 | + getSetPayedDate({ id: id.value, payedDate: formattedDate }); | |
54 | + emit('success'); | |
55 | + closeModal(); | |
56 | + } | |
57 | + function handleShow(visible: boolean) { | |
58 | + if (!visible) { | |
59 | + date.value = null; | |
60 | + } | |
61 | + } | |
62 | +</script> | ... | ... |
src/views/project/finance/payBack/FinanceEditCheck.vue
0 → 100644
1 | +<template> | |
2 | + <template> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + title="编辑" | |
7 | + width="30%" | |
8 | + :isDetail="true" | |
9 | + @ok="handleSubmit" | |
10 | + :showDetailBack="false" | |
11 | + okText="保存" | |
12 | + showFooter | |
13 | + :destroyOnClose="true" | |
14 | + > | |
15 | + <!-- <div> | |
16 | + <BasicForm @register="registerForm" /> | |
17 | + </div> --> | |
18 | + <div style="font-size: 15px">实际付款金额1¥</div> | |
19 | + <a-input v-model:value="input1" placeholder="请输入" :disabled="status === 10" auto-size /> | |
20 | + <div style="margin: 16px 0"></div> | |
21 | + <div style="font-size: 15px">实际付款金额2¥</div> | |
22 | + <a-input v-model:value="input2" placeholder="请输入" :disabled="status === 10" auto-size /> | |
23 | + <div style="margin: 16px 0"></div> | |
24 | + <div style="font-size: 15px">实际付款金额3¥</div> | |
25 | + <a-input v-model:value="input3" placeholder="请输入" :disabled="status === 10" auto-size /> | |
26 | + <div style="margin: 16px 0"></div> | |
27 | + | |
28 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | |
29 | + <template #appendFooter> | |
30 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | |
31 | + </template> | |
32 | + </BasicDrawer> | |
33 | + </template> | |
34 | +</template> | |
35 | +<script lang="ts" setup> | |
36 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | |
37 | + import { BasicForm, FormSchema, useForm } from '@/components/Form'; | |
38 | + import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue'; | |
39 | + import { getEmailList } from '/@/api/sys/config'; | |
40 | + import { updateAmountInfo } from '@/api/project/invoice'; | |
41 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
42 | + | |
43 | + const emit = defineEmits(['success']); | |
44 | + const schemas: FormSchema[] = [ | |
45 | + // { | |
46 | + // field: 'actualPayedAmount', | |
47 | + // component: 'InputNumber', | |
48 | + // labelWidth: 250, | |
49 | + // colProps: { | |
50 | + // span: 23, | |
51 | + // }, | |
52 | + // label: '生产科实际应付金额', | |
53 | + // }, | |
54 | + { | |
55 | + field: 'actualPayedAmount1', | |
56 | + component: 'InputNumber', | |
57 | + labelWidth: 250, | |
58 | + colProps: { | |
59 | + span: 23, | |
60 | + }, | |
61 | + label: '实际应付金额1¥', | |
62 | + componentProps: () => ({ | |
63 | + disabled: status.value === 10, | |
64 | + }), | |
65 | + }, | |
66 | + { | |
67 | + field: 'actualPayedAmount2', | |
68 | + component: 'InputNumber', | |
69 | + labelWidth: 250, | |
70 | + colProps: { | |
71 | + span: 23, | |
72 | + }, | |
73 | + label: '实际应付金额2¥', | |
74 | + componentProps: () => ({ | |
75 | + disabled: status.value === 10, | |
76 | + }), | |
77 | + }, | |
78 | + { | |
79 | + field: 'actualPayedAmount3', | |
80 | + component: 'InputNumber', | |
81 | + labelWidth: 250, | |
82 | + colProps: { | |
83 | + span: 23, | |
84 | + }, | |
85 | + label: '实际应付金额3¥', | |
86 | + componentProps: () => ({ | |
87 | + disabled: status.value === 10, | |
88 | + }), | |
89 | + }, | |
90 | + ]; | |
91 | + const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ | |
92 | + labelWidth: 120, | |
93 | + schemas, | |
94 | + layout: 'vertical', | |
95 | + showActionButtonGroup: false, | |
96 | + actionColOptions: { | |
97 | + span: 24, | |
98 | + }, | |
99 | + }); | |
100 | + const { createMessage } = useMessage(); | |
101 | + const { error } = createMessage; | |
102 | + const update = ref(); | |
103 | + const status = ref(); | |
104 | + const input1 = ref(); | |
105 | + const input2 = ref(); | |
106 | + const input3 = ref(); | |
107 | + const id = ref(); | |
108 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
109 | + // 方式1 | |
110 | + resetFields(); | |
111 | + status.value = data.data.status; | |
112 | + id.value = data.data.id; | |
113 | + input1.value = data.data.actualPayedAmount1; | |
114 | + input2.value = data.data.actualPayedAmount2; | |
115 | + input3.value = data.data.actualPayedAmount3; | |
116 | + setDrawerProps({ confirmLoading: false }); | |
117 | + // 将金额格式化为两位小数 | |
118 | + // setFieldsValue({ | |
119 | + // actualPayedAmount1: | |
120 | + // data.data.actualPayedAmount1 !== null ? data.data.actualPayedAmount1.toFixed(2) : undefined, | |
121 | + // actualPayedAmount2: | |
122 | + // data.data.actualPayedAmount2 !== null ? data.data.actualPayedAmount2.toFixed(2) : undefined, | |
123 | + // actualPayedAmount3: | |
124 | + // data.data.actualPayedAmount3 !== null ? data.data.actualPayedAmount3.toFixed(2) : undefined, | |
125 | + // ...toRaw(data.data), // 其他字段 | |
126 | + // }); | |
127 | + setFieldsValue({ | |
128 | + ...toRaw(data.data), | |
129 | + }); | |
130 | + update.value = data; | |
131 | + }); | |
132 | + //完成编辑 | |
133 | + async function handleSubmit() { | |
134 | + // const values = await validate(); | |
135 | + // const updatedValues = { | |
136 | + // ...values, | |
137 | + // id: update.value.data.id, | |
138 | + // }; | |
139 | + if (!input1.value || !input2.value || !input3.value) { | |
140 | + error('选项不能为空'); | |
141 | + } else { | |
142 | + await updateAmountInfo({ | |
143 | + id: id.value, | |
144 | + actualPayedAmount1: input1.value, | |
145 | + actualPayedAmount2: input2.value, | |
146 | + actualPayedAmount3: input3.value, | |
147 | + }); | |
148 | + emit('success'); | |
149 | + closeDrawer(); | |
150 | + } | |
151 | + } | |
152 | +</script> | ... | ... |
src/views/project/finance/payBack/InvoiceShowCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="生产科发票" | |
6 | + width="700px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + > | |
10 | + <a-list item-layout="horizontal" :data-source="itemArray"> | |
11 | + <template #renderItem="{ item }"> | |
12 | + <a-list-item> | |
13 | + <a-list-item-meta> | |
14 | + <template #title> | |
15 | + <!-- <a :href="item.url" target="_blank" rel="noopener noreferrer">{{ item.name }}</a> --> | |
16 | + <a @click="view(item.url)">{{ item.name }}</a> | |
17 | + </template> | |
18 | + </a-list-item-meta> | |
19 | + </a-list-item> | |
20 | + </template> | |
21 | + </a-list> | |
22 | + </BasicModal> | |
23 | +</template> | |
24 | +<script lang="ts" setup> | |
25 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
26 | + import { computed, ref } from 'vue'; | |
27 | + import type { UploadProps, UploadChangeParam } from 'ant-design-vue'; | |
28 | + import { InboxOutlined } from '@ant-design/icons-vue'; | |
29 | + import { message } from 'ant-design-vue'; | |
30 | + import { getDeductUrlById, getInvoiceUrlById } from '@/api/project/invoice'; | |
31 | + import { view } from '@/utils/pdfShow'; | |
32 | + | |
33 | + interface Item { | |
34 | + name: string; | |
35 | + url: string; | |
36 | + } | |
37 | + | |
38 | + const list = ref(); | |
39 | + const id = ref(); | |
40 | + const itemArray = ref<Item[]>([]); | |
41 | + | |
42 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
43 | + itemArray.value = []; | |
44 | + const res = await getInvoiceUrlById({ id: data.data.id }); | |
45 | + for (let item in res) { | |
46 | + const url = res[item]; | |
47 | + const name = item; | |
48 | + // 将 name 和 url 放入对象并添加到数组中 | |
49 | + itemArray.value.push({ name, url }); | |
50 | + } | |
51 | + }); | |
52 | + | |
53 | + async function handleOk() { | |
54 | + itemArray.value = []; | |
55 | + closeModal(); | |
56 | + } | |
57 | +</script> | ... | ... |
src/views/project/finance/payBack/InvoiceUploadCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="发票上传" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + ><a-upload-dragger | |
10 | + v-model:fileList="fileList" | |
11 | + name="file" | |
12 | + :beforeUpload="beforeUpload" | |
13 | + :max-count="1" | |
14 | + :multiple="true" | |
15 | + :action="updateInvoiceUrl" | |
16 | + @change="handleChange" | |
17 | + @drop="handleDrop" | |
18 | + :disabled="status === 10" | |
19 | + > | |
20 | + <p class="ant-upload-drag-icon"> | |
21 | + <inbox-outlined></inbox-outlined> | |
22 | + </p> | |
23 | + <p class="ant-upload-text">点击或将文件拖拽到这里上传</p> | |
24 | + </a-upload-dragger> | |
25 | + </BasicModal> | |
26 | +</template> | |
27 | +<script lang="ts" setup> | |
28 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
29 | + import { computed, ref } from 'vue'; | |
30 | + import type { UploadProps, UploadChangeParam } from 'ant-design-vue'; | |
31 | + import { InboxOutlined } from '@ant-design/icons-vue'; | |
32 | + import { message } from 'ant-design-vue'; | |
33 | + import { updateInvoiceInfo } from '@/api/project/invoice'; | |
34 | + | |
35 | + const emit = defineEmits(['success']); | |
36 | + const uploadUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
37 | + const updateInvoiceUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
38 | + const invoiceUrl = ref(); | |
39 | + const id = ref(); | |
40 | + const status = ref(); | |
41 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
42 | + console.log(data); | |
43 | + status.value = data.data.status; | |
44 | + // fileList.value = []; | |
45 | + fileList.value = []; | |
46 | + invoiceUrl.value = data.data.invoiceUrl; | |
47 | + id.value = data.data.id; | |
48 | + }); | |
49 | + | |
50 | + const handleChange = (info) => { | |
51 | + if (info.file.status == 'done') { | |
52 | + updateInvoiceUrl.value = info.file.response.data.fileUrl; | |
53 | + invoiceUrl.value = updateInvoiceUrl.value; | |
54 | + } | |
55 | + }; | |
56 | + function beforeUpload(info) { | |
57 | + updateInvoiceUrl.value = uploadUrl.value + info.name; | |
58 | + } | |
59 | + function handleDrop(e: DragEvent) { | |
60 | + console.log(e); | |
61 | + } | |
62 | + const fileList = ref<UploadProps['fileList']>([]); | |
63 | + | |
64 | + async function handleOk() { | |
65 | + await updateInvoiceInfo({ | |
66 | + id: id.value, | |
67 | + invoiceUrl: invoiceUrl.value, | |
68 | + }); | |
69 | + fileList.value = []; | |
70 | + emit('success'); | |
71 | + closeModal(); | |
72 | + } | |
73 | +</script> | ... | ... |
src/views/project/finance/payBack/NoteCheck.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="添加备注" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + @visible-change="handleShow" | |
10 | + > | |
11 | + 备注: | |
12 | + <a-textarea v-model:value="notes" placeholder="请输入" :rows="6" /> | |
13 | + <div style="height: 10px"></div> | |
14 | + </BasicModal> | |
15 | +</template> | |
16 | +<script lang="ts" setup> | |
17 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
18 | + import { ref } from 'vue'; | |
19 | + import { getSetBackRefundDate } from '@/api/project/invoice'; | |
20 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
21 | + | |
22 | + const id = ref(); | |
23 | + const notes = ref(); | |
24 | + const checkedKeys = ref(); | |
25 | + const emit = defineEmits(['success']); | |
26 | + const { createMessage } = useMessage(); | |
27 | + const { error } = createMessage; | |
28 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
29 | + // id.value = data.data.id; | |
30 | + checkedKeys.value = data.checkedKeys; | |
31 | + }); | |
32 | + const isDisabled = ref(false); | |
33 | + async function handleOk() { | |
34 | + if (isDisabled.value) { | |
35 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
36 | + return; | |
37 | + } | |
38 | + isDisabled.value = true; | |
39 | + setTimeout(() => { | |
40 | + isDisabled.value = false; | |
41 | + }, 3000); | |
42 | + getSetBackRefundDate({ id: checkedKeys.value, notes: notes.value }); | |
43 | + emit('success'); | |
44 | + closeModal(); | |
45 | + } | |
46 | + function handleShow(visible: boolean) { | |
47 | + if (!visible) { | |
48 | + notes.value = null; | |
49 | + } | |
50 | + } | |
51 | +</script> | ... | ... |
src/views/project/finance/payBack/TrackEditCheck.vue
0 → 100644
1 | +<template> | |
2 | + <template> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + title="跟单编辑" | |
7 | + width="30%" | |
8 | + :isDetail="true" | |
9 | + @ok="handleSubmit" | |
10 | + :showDetailBack="false" | |
11 | + @visible-change="handleShow" | |
12 | + okText="保存" | |
13 | + showFooter | |
14 | + :destroyOnClose="true" | |
15 | + > | |
16 | + <div> | |
17 | + <div style="font-size: 15px">生产科扣款金额¥</div> | |
18 | + <a-input v-model:value="input1" placeholder="请输入" :disabled="status === 10" auto-size /> | |
19 | + <div style="margin: 16px 0"></div> | |
20 | + <div style="font-size: 15px">扣款责任部门</div> | |
21 | + <a-input | |
22 | + v-model:value="deductDept" | |
23 | + placeholder="请输入" | |
24 | + :disabled="status === 10" | |
25 | + auto-size | |
26 | + /> | |
27 | + <!-- <a-select | |
28 | + ref="select" | |
29 | + style="width: 60%" | |
30 | + v-model:value="selectedProductionDepartment" | |
31 | + :options="productionDepartmentOptions" | |
32 | + /> --> | |
33 | + <!-- <a-select | |
34 | + ref="select" | |
35 | + style="width: 100%" | |
36 | + v-model:value="productionDepartment" | |
37 | + :options="productDepartmentOptions" | |
38 | + /> --> | |
39 | + <div style="margin: 16px 0"></div> | |
40 | + <div>上传扣款单</div | |
41 | + ><a-space direction="vertical" style="width: 100%" size="large"> | |
42 | + <a-upload | |
43 | + v-model:file-list="fileList" | |
44 | + :beforeUpload="beforeUpload" | |
45 | + list-type="picture" | |
46 | + :max-count="1" | |
47 | + :disabled="status === 10" | |
48 | + :action="updateDeductUrl" | |
49 | + @change="handleChange" | |
50 | + > | |
51 | + <a-button> 上传扣款单 </a-button> | |
52 | + </a-upload> | |
53 | + </a-space> | |
54 | + </div> | |
55 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | |
56 | + <template #appendFooter> | |
57 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | |
58 | + </template> | |
59 | + </BasicDrawer> | |
60 | + </template> | |
61 | +</template> | |
62 | +<script lang="ts" setup> | |
63 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | |
64 | + import { defineComponent, ref, computed, unref, toRaw, reactive, onMounted } from 'vue'; | |
65 | + import { getEmailList } from '/@/api/sys/config'; | |
66 | + import { UploadOutlined } from '@ant-design/icons-vue'; | |
67 | + import type { UploadProps } from 'ant-design-vue'; | |
68 | + import { updateDeductInfo } from '@/api/project/invoice'; | |
69 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
70 | + import { useOrderInfo } from '/@/hooks/component/order'; | |
71 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
72 | + | |
73 | + const emit = defineEmits(['success']); | |
74 | + const fileList = ref<UploadProps['fileList']>([]); | |
75 | + // const orderStore = useOrderStoreWithOut(); | |
76 | + // const { productionDepartment: productionDepartmentOptions } = useOrderInfo(orderStore); | |
77 | + // console.log(productionDepartmentOptions.value, '565656565665orderStore'); | |
78 | + // onMounted(() => { | |
79 | + // const { productionDepartment } = useOrderInfo(orderStore); | |
80 | + // console.log(productionDepartment.value, '565656565665orderStore1'); | |
81 | + // }); | |
82 | + const orderStore = useOrderStoreWithOut(); | |
83 | + const { productionDepartment: productDepartmentOptions } = useOrderInfo(orderStore); | |
84 | + const productionDepartment = ref(); | |
85 | + const input1 = ref(0); | |
86 | + const deductUrl = ref(); | |
87 | + const id = ref(); | |
88 | + const checkNo = ref(); | |
89 | + const deductDept = ref(); | |
90 | + const uploadUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
91 | + const updateDeductUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
92 | + // const uploadUrl = ref(''); | |
93 | + // const updateDeductUrl = ref(''); | |
94 | + const deductUrlOld = ref(); | |
95 | + const selectedProductionDepartment = ref(); // 新增: 用于存储选中的生产科 | |
96 | + const { createMessage } = useMessage(); | |
97 | + const { error } = createMessage; | |
98 | + const status = ref(); | |
99 | + | |
100 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
101 | + status.value = data.data.status; | |
102 | + id.value = data.data.id; | |
103 | + checkNo.value = data.data.checkNo; | |
104 | + input1.value = data.data.deductAmount; | |
105 | + deductDept.value = data.data.deductDept; | |
106 | + deductUrl.value = data.data.deductUrl; | |
107 | + deductUrlOld.value = data.data.deductUrl; | |
108 | + }); | |
109 | + function handleChange(info) { | |
110 | + if (info.file.status == 'done') { | |
111 | + updateDeductUrl.value = info.file.response.data.fileUrl; | |
112 | + deductUrl.value = updateDeductUrl.value; | |
113 | + } | |
114 | + if (info.fileList.length == 0) { | |
115 | + info.file = null; | |
116 | + deductUrl.value = ''; | |
117 | + } | |
118 | + } | |
119 | + function beforeUpload(info) { | |
120 | + updateDeductUrl.value = uploadUrl.value + info.name; | |
121 | + } | |
122 | + function handleShow() { | |
123 | + // input1.value = ''; | |
124 | + // deductUrl.value = ''; | |
125 | + // deductDept.value = ''; | |
126 | + // updateDeductUrl.value = ''; | |
127 | + // fileList.value = []; | |
128 | + } | |
129 | + //完成编辑 | |
130 | + async function handleSubmit() { | |
131 | + if (!input1.value || !deductDept.value) { | |
132 | + error('选项不能为空'); | |
133 | + } else { | |
134 | + await updateDeductInfo({ | |
135 | + id: id.value, | |
136 | + checkNo: checkNo.value, | |
137 | + deductAmount: input1.value, | |
138 | + deductDept: deductDept.value, | |
139 | + deductUrl: deductUrl.value, | |
140 | + }); | |
141 | + // productionDepartment: selectedProductionDepartment.value, | |
142 | + fileList.value = []; | |
143 | + emit('success'); | |
144 | + closeDrawer(); | |
145 | + } | |
146 | + } | |
147 | +</script> | ... | ... |
src/views/project/finance/payBack/pay.data.tsx
0 → 100644
1 | +import { FormSchema } from '/@/components/Form'; | |
2 | +import { BasicColumn } from '/@/components/Table'; | |
3 | +import { icon } from 'ant-design-vue'; | |
4 | +import { FolderAddOutlined, FilePptOutlined } from '@ant-design/icons-vue'; | |
5 | +import { size } from 'lodash-es'; | |
6 | + | |
7 | +export const searchFormSchema: FormSchema[] = [ | |
8 | + { | |
9 | + field: 'checkNo', | |
10 | + label: '生产科对账单号', | |
11 | + component: 'Input', | |
12 | + colProps: { span: 8 }, | |
13 | + }, | |
14 | + { | |
15 | + field: 'productionDepartment', | |
16 | + label: '生产科', | |
17 | + component: 'Input', | |
18 | + colProps: { span: 8 }, | |
19 | + }, | |
20 | + { | |
21 | + field: 'status', | |
22 | + label: '总经理审核', | |
23 | + component: 'Select', | |
24 | + colProps: { span: 8 }, | |
25 | + componentProps: { | |
26 | + options: [ | |
27 | + { label: '未提交审核', value: -1 }, | |
28 | + { label: '待审核', value: 0 }, | |
29 | + { label: '审核通过', value: 10 }, | |
30 | + { label: '审核驳回', value: 20 }, | |
31 | + ], | |
32 | + }, | |
33 | + }, | |
34 | + { | |
35 | + field: 'customerCode', | |
36 | + label: '客户编码', | |
37 | + component: 'Input', | |
38 | + colProps: { | |
39 | + span: 8, | |
40 | + }, | |
41 | + }, | |
42 | +]; | |
43 | + | |
44 | +export const columns: BasicColumn[] = [ | |
45 | + { | |
46 | + title: '生产科对账单号', | |
47 | + dataIndex: 'checkNo', | |
48 | + width: 120, | |
49 | + }, | |
50 | + { | |
51 | + title: '生产科应付款日期', | |
52 | + dataIndex: 'payedDate', | |
53 | + width: 140, | |
54 | + }, | |
55 | + { | |
56 | + title: '生产科扣款金额¥', | |
57 | + dataIndex: 'deductAmount', | |
58 | + width: 160, | |
59 | + // customRender: (column) => { | |
60 | + // return column.record.deductAmount?.toFixed(2); | |
61 | + // }, | |
62 | + }, | |
63 | + { | |
64 | + title: '扣款责任部门', | |
65 | + dataIndex: 'deductDept', | |
66 | + width: 120, | |
67 | + }, | |
68 | + { | |
69 | + title: '上传扣款单', | |
70 | + dataIndex: 'deductUrl', | |
71 | + width: 120, | |
72 | + customRender: (column) => { | |
73 | + const deductUrl = column.record.deductUrl; | |
74 | + if (deductUrl == undefined) { | |
75 | + return; | |
76 | + } | |
77 | + return <FilePptOutlined style="font-size:25px" />; | |
78 | + }, | |
79 | + }, | |
80 | + { | |
81 | + title: '生产科实际应付金额¥', | |
82 | + dataIndex: 'actualPayedAmount', | |
83 | + width: 180, | |
84 | + // customRender: (column) => { | |
85 | + // return column.record.actualPayedAmount?.toFixed(2); | |
86 | + // }, | |
87 | + }, | |
88 | + { | |
89 | + title: '生产科发票上传', | |
90 | + dataIndex: 'invoiceUrl', | |
91 | + width: 80, | |
92 | + customRender: (column) => { | |
93 | + const deductUrl = column.record.invoiceUrl; | |
94 | + if (deductUrl == undefined) { | |
95 | + return; | |
96 | + } | |
97 | + return <FilePptOutlined style="font-size:25px" />; | |
98 | + }, | |
99 | + }, | |
100 | + { | |
101 | + title: '实际付款金额1¥', | |
102 | + dataIndex: 'actualPayedAmount1', | |
103 | + width: 160, | |
104 | + // customRender: (column) => { | |
105 | + // console.log(column, '5656ccc'); | |
106 | + // return column.record.actualPayedAmount1?.toFixed(2); | |
107 | + // }, | |
108 | + }, | |
109 | + { | |
110 | + title: '实际付款金额2¥', | |
111 | + dataIndex: 'actualPayedAmount2', | |
112 | + width: 160, | |
113 | + // customRender: (column) => { | |
114 | + // return column.record.actualPayedAmount2?.toFixed(2); | |
115 | + // }, | |
116 | + }, | |
117 | + { | |
118 | + title: '实际付款金额3¥', | |
119 | + dataIndex: 'actualPayedAmount3', | |
120 | + width: 160, | |
121 | + // customRender: (column) => { | |
122 | + // return column.record.actualPayedAmount3?.toFixed(2); | |
123 | + // }, | |
124 | + }, | |
125 | + { | |
126 | + title: '生产科发票审核', | |
127 | + dataIndex: 'departmentInvoiceStatus', | |
128 | + width: 120, | |
129 | + customRender: (column) => { | |
130 | + if (column.record.departmentInvoiceStatus == 0) { | |
131 | + return '待审核'; | |
132 | + } else if (column.record.departmentInvoiceStatus == 10) { | |
133 | + return '审核通过'; | |
134 | + } else if (column.record.departmentInvoiceStatus == 20) { | |
135 | + return '审核驳回'; | |
136 | + } | |
137 | + }, | |
138 | + }, | |
139 | + { | |
140 | + title: '总经理审核', | |
141 | + dataIndex: 'status', | |
142 | + width: 120, | |
143 | + customRender: (column) => { | |
144 | + if (column.record.status == -1) { | |
145 | + return '未提交审核'; | |
146 | + } else if (column.record.status == 0) { | |
147 | + return '待审核'; | |
148 | + } else if (column.record.status == 10) { | |
149 | + return '审核通过'; | |
150 | + } else if (column.record.status == 20) { | |
151 | + return '审核驳回'; | |
152 | + } | |
153 | + }, | |
154 | + }, | |
155 | +]; | ... | ... |
src/views/project/finance/payBack/type.d.ts
0 → 100644
1 | +export enum ROLE { | |
2 | + ADMIN = 'admin', // 超管 | |
3 | + CUSTOM_ADMIN = 'custom_admin', // 客户管理员 | |
4 | + DATA_REPORT_USER = 'data_report_user', //数据分析员 | |
5 | + BUSINESS = 'business_user', // 业务员 | |
6 | + TRACKER = 'tracker_user', // 跟单员 | |
7 | + INSPECT = 'inspect_user', // 质检员 | |
8 | + PRODUCE = 'produce_user', //生产科 | |
9 | + FINANCE = 'finance_user', //生产科 | |
10 | +} | ... | ... |
src/views/project/finance/receive.data.tsx
0 → 100644
1 | +import { FormSchema } from '/@/components/Form'; | |
2 | +import { BasicColumn } from '/@/components/Table'; | |
3 | +import { icon } from 'ant-design-vue'; | |
4 | +import { FilePptOutlined } from '@ant-design/icons-vue'; | |
5 | +import { size } from 'lodash-es'; | |
6 | +import { ref } from 'vue'; | |
7 | +import { view } from '@/utils/pdfShow'; | |
8 | + | |
9 | +export const searchFormSchema: FormSchema[] = [ | |
10 | + { | |
11 | + field: 'invoiceNo', | |
12 | + label: 'Invoice编号', | |
13 | + component: 'Input', | |
14 | + colProps: { span: 6 }, | |
15 | + }, | |
16 | + { | |
17 | + field: 'status', | |
18 | + label: '总经理审核', | |
19 | + component: 'Select', | |
20 | + colProps: { span: 6 }, | |
21 | + componentProps: { | |
22 | + options: [ | |
23 | + { label: '未提交审核', value: -1 }, | |
24 | + { label: '待审核', value: 0 }, | |
25 | + { label: '审核通过', value: 10 }, | |
26 | + { label: '审核驳回', value: 20 }, | |
27 | + ], | |
28 | + }, | |
29 | + }, | |
30 | + { | |
31 | + field: 'customerCode', | |
32 | + label: '客户编码', | |
33 | + component: 'Input', | |
34 | + colProps: { | |
35 | + span: 6, | |
36 | + }, | |
37 | + // labelWidth: 140, | |
38 | + }, | |
39 | +]; | |
40 | + | |
41 | +export const columns: BasicColumn[] = [ | |
42 | + { | |
43 | + title: 'Invoice编号', | |
44 | + dataIndex: 'invoiceNo', | |
45 | + width: 180, | |
46 | + }, | |
47 | + { | |
48 | + title: '报关单', | |
49 | + dataIndex: 'bgUrl', | |
50 | + width: 80, | |
51 | + customRender: (column) => { | |
52 | + const bgUrl = column.record.bgUrl; | |
53 | + if (bgUrl == undefined) { | |
54 | + return; | |
55 | + } | |
56 | + return <FilePptOutlined style="font-size:25px" onClick={() => view(bgUrl)} />; | |
57 | + }, | |
58 | + }, | |
59 | + { | |
60 | + title: '必须回款日期', | |
61 | + dataIndex: 'backRefundDate', | |
62 | + width: 120, | |
63 | + }, | |
64 | + { | |
65 | + title: '发生扣款金额$', | |
66 | + dataIndex: 'deductAmount', | |
67 | + width: 120, | |
68 | + // customRender: (column) => { | |
69 | + // return column.record.deductAmount?.toFixed(2); | |
70 | + // }, | |
71 | + }, | |
72 | + { | |
73 | + title: '上传扣款单', | |
74 | + dataIndex: 'deductUrl', | |
75 | + width: 80, | |
76 | + customRender: (column) => { | |
77 | + const deductUrl = column.record.deductUrl; | |
78 | + if (deductUrl == undefined) { | |
79 | + return; | |
80 | + } | |
81 | + // return <FilePptOutlined style="font-size:25px" onClick={() => window.open(deductUrl[0])} />; | |
82 | + return <FilePptOutlined style="font-size:25px" />; | |
83 | + }, | |
84 | + }, | |
85 | + { | |
86 | + title: '实际应收金额$', | |
87 | + dataIndex: 'actualReceivableAmount', | |
88 | + width: 120, | |
89 | + // customRender: (column) => { | |
90 | + // return column.record.actualReceivableAmount?.toFixed(2); | |
91 | + // }, | |
92 | + }, | |
93 | + { | |
94 | + title: '实际收款金额1$', | |
95 | + dataIndex: 'actualPayedAmount1', | |
96 | + width: 120, | |
97 | + // customRender: (column) => { | |
98 | + // return column.record.actualPayedAmount1?.toFixed(2); | |
99 | + // }, | |
100 | + }, | |
101 | + { | |
102 | + title: '实际收款金额2$', | |
103 | + dataIndex: 'actualPayedAmount2', | |
104 | + width: 120, | |
105 | + // customRender: (column) => { | |
106 | + // return column.record.actualPayedAmount2?.toFixed(2); | |
107 | + // }, | |
108 | + }, | |
109 | + { | |
110 | + title: '实际收款金额3$', | |
111 | + dataIndex: 'actualPayedAmount3', | |
112 | + width: 120, | |
113 | + // customRender: (column) => { | |
114 | + // return column.record.actualPayedAmount3?.toFixed(2); | |
115 | + // }, | |
116 | + }, | |
117 | + { | |
118 | + title: '其他费用$', | |
119 | + dataIndex: 'otherAmount', | |
120 | + width: 120, | |
121 | + customRender: (column) => { | |
122 | + return column.record.otherAmount?.toFixed(2); | |
123 | + }, | |
124 | + }, | |
125 | + { | |
126 | + title: '总经理审核', | |
127 | + dataIndex: 'status', | |
128 | + width: 120, | |
129 | + customRender: (column) => { | |
130 | + if (column.record.status == -1) { | |
131 | + return '未提交审核'; | |
132 | + } else if (column.record.status == 0) { | |
133 | + return '待审核'; | |
134 | + } else if (column.record.status == 10) { | |
135 | + return '审核通过'; | |
136 | + } else if (column.record.status == 20) { | |
137 | + return '审核驳回'; | |
138 | + } | |
139 | + }, | |
140 | + }, | |
141 | + { | |
142 | + title: '操作1', | |
143 | + key: 'action', // 对应 #bodyCell 中的 column.key | |
144 | + width: 280, | |
145 | + }, | |
146 | + { | |
147 | + title: '操作2', | |
148 | + key: 'action2', // 对应 #bodyCell 中的 column.key | |
149 | + width: 280, | |
150 | + }, | |
151 | +]; | |
152 | + | |
153 | +export const columnsAnalysis: BasicColumn[] = [ | |
154 | + { | |
155 | + title: '实际应付金额总计$', | |
156 | + dataIndex: 'actualPayedAmount', | |
157 | + width: 50, | |
158 | + customRender: (column) => { | |
159 | + return column.record.actualPayedAmount?.toFixed(2); | |
160 | + }, | |
161 | + }, | |
162 | + { | |
163 | + title: '实际应收金额总计$', | |
164 | + dataIndex: 'actualReceivableAmount', | |
165 | + width: 50, | |
166 | + customRender: (column) => { | |
167 | + return column.record.actualReceivableAmount?.toFixed(2); | |
168 | + }, | |
169 | + }, | |
170 | + { | |
171 | + title: '客户总价$', | |
172 | + dataIndex: 'customerTotalPrice', | |
173 | + width: 50, | |
174 | + customRender: (column) => { | |
175 | + return column.record.customerTotalPrice?.toFixed(2); | |
176 | + }, | |
177 | + }, | |
178 | + { | |
179 | + title: '发生扣款金额总计$', | |
180 | + dataIndex: 'deductAmount', | |
181 | + width: 50, | |
182 | + customRender: (column) => { | |
183 | + return column.record.deductAmount?.toFixed(2); | |
184 | + }, | |
185 | + }, | |
186 | + { | |
187 | + title: '实际应收金额总计$', | |
188 | + dataIndex: 'actualReceivableAmount', | |
189 | + width: 50, | |
190 | + customRender: (column) => { | |
191 | + return column.record.actualReceivableAmount?.toFixed(2); | |
192 | + }, | |
193 | + }, | |
194 | + { | |
195 | + title: '实际应收$', | |
196 | + dataIndex: 'otherAmount', | |
197 | + width: 50, | |
198 | + customRender: (column) => { | |
199 | + return column.record.otherAmount?.toFixed(2); | |
200 | + }, | |
201 | + }, | |
202 | + { | |
203 | + title: '其他费用金额汇总$', | |
204 | + dataIndex: 'otherTotalAmount', | |
205 | + width: 50, | |
206 | + customRender: (column) => { | |
207 | + return column.record.otherTotalAmount?.toFixed(2); | |
208 | + }, | |
209 | + }, | |
210 | +]; | ... | ... |
src/views/project/finance/receive/Commit.vue
... | ... | @@ -30,7 +30,7 @@ |
30 | 30 | const { createMessage } = useMessage(); |
31 | 31 | const { error } = createMessage; |
32 | 32 | const [register, { closeModal }] = useModalInner(async (data) => { |
33 | - id.value = data.data.id; | |
33 | + id.value = data.checkedKeys; | |
34 | 34 | }); |
35 | 35 | function formatDate(input: string): string { |
36 | 36 | // 创建一个 Date 对象 | ... | ... |
src/views/project/finance/receive/InvoiceAnalysis.vue
... | ... | @@ -33,7 +33,7 @@ |
33 | 33 | dataIndex: 'actualPayedAmount', |
34 | 34 | width: 50, |
35 | 35 | customRender: (res) => { |
36 | - return res.record.exportVOS[0].customerCode; | |
36 | + return res?.record?.exportVOS[0]?.customerCode; | |
37 | 37 | }, |
38 | 38 | }, |
39 | 39 | { |
... | ... | @@ -41,7 +41,7 @@ |
41 | 41 | dataIndex: 'customerTotalPrice', |
42 | 42 | width: 50, |
43 | 43 | customRender: (res) => { |
44 | - return res.record.customerTotalPrice.toFixed(2); | |
44 | + return res?.record?.customerTotalPrice.toFixed(2); | |
45 | 45 | }, |
46 | 46 | }, |
47 | 47 | { |
... | ... | @@ -49,7 +49,7 @@ |
49 | 49 | dataIndex: 'deductAmount', |
50 | 50 | width: 50, |
51 | 51 | customRender: (res) => { |
52 | - return res.record.deductAmount.toFixed(2); | |
52 | + return res?.record?.deductAmount.toFixed(2); | |
53 | 53 | }, |
54 | 54 | }, |
55 | 55 | { |
... | ... | @@ -57,7 +57,7 @@ |
57 | 57 | dataIndex: 'otherAmount', |
58 | 58 | width: 50, |
59 | 59 | customRender: (res) => { |
60 | - return res.record.otherAmount.toFixed(2); | |
60 | + return res?.record?.otherAmount.toFixed(2); | |
61 | 61 | }, |
62 | 62 | }, |
63 | 63 | { |
... | ... | @@ -65,7 +65,7 @@ |
65 | 65 | dataIndex: 'actualReceivableAmount', |
66 | 66 | width: 50, |
67 | 67 | customRender: (res) => { |
68 | - return res.record.actualReceivableAmount.toFixed(2); | |
68 | + return res?.record?.actualReceivableAmount.toFixed(2); | |
69 | 69 | }, |
70 | 70 | }, |
71 | 71 | { |
... | ... | @@ -73,7 +73,7 @@ |
73 | 73 | dataIndex: 'otherTotalAmount', |
74 | 74 | width: 50, |
75 | 75 | customRender: (res) => { |
76 | - return res.record.otherTotalAmount.toFixed(2); | |
76 | + return res?.record?.otherTotalAmount.toFixed(2); | |
77 | 77 | }, |
78 | 78 | }, |
79 | 79 | { |
... | ... | @@ -81,12 +81,13 @@ |
81 | 81 | dataIndex: 'actualPayedAmount', |
82 | 82 | width: 50, |
83 | 83 | customRender: (res) => { |
84 | - return res.record.actualPayedAmount.toFixed(2); | |
84 | + return res?.record?.actualPayedAmount.toFixed(2); | |
85 | 85 | }, |
86 | 86 | }, |
87 | 87 | ]; |
88 | 88 | // const ids = ref<number[]>([]); |
89 | 89 | const ids = ref(); |
90 | + const tableData = ref([]); | |
90 | 91 | // const res = ref(); |
91 | 92 | |
92 | 93 | const [register, { closeModal }] = useModalInner(async (data) => { |
... | ... | @@ -98,11 +99,38 @@ |
98 | 99 | const [registerTable, { reload }] = useTable({ |
99 | 100 | // api: () => invoiceAnalysis({ ids: ids.value }), |
100 | 101 | api: async () => { |
101 | - const res = await invoiceAnalysis({ ids: ids.value }); | |
102 | + // const res = await invoiceAnalysis({ ids: ids.value }); | |
102 | 103 | const arrayRes = ref([]); |
104 | + // return res; | |
105 | + const res = await invoiceAnalysis({ ids: ids.value }); | |
103 | 106 | arrayRes.value.push(res); |
107 | + | |
108 | + console.log(arrayRes.value, '5656resana'); | |
109 | + // // 计算合计行 | |
110 | + // const sum = { | |
111 | + // customerTotalPrice: 0, | |
112 | + // deductAmount: 0, | |
113 | + // otherAmount: 0, | |
114 | + // actualReceivableAmount: 0, | |
115 | + // otherTotalAmount: 0, | |
116 | + // actualPayedAmount: 0, | |
117 | + // exportVOS: res[0].exportVOS, | |
118 | + // }; | |
119 | + | |
120 | + // res.forEach((item: any) => { | |
121 | + // sum.customerTotalPrice += item.customerTotalPrice || 0; | |
122 | + // sum.deductAmount += item.deductAmount || 0; | |
123 | + // sum.otherAmount += item.otherAmount || 0; | |
124 | + // sum.actualReceivableAmount += item.actualReceivableAmount || 0; | |
125 | + // sum.otherTotalAmount += item.otherTotalAmount || 0; | |
126 | + // sum.actualPayedAmount += item.actualPayedAmount || 0; | |
127 | + // }); | |
128 | + | |
129 | + // // 在数据末尾添加合计行 | |
130 | + // tableData.value = [...res, { ...sum, actualPayedAmount: 123 }]; | |
131 | + // arrayRes.value.push(tableData.value); | |
132 | + console.log(arrayRes.value, '5656arrayRes.value'); | |
104 | 133 | return res; |
105 | - // return arrayRes.value; | |
106 | 134 | }, |
107 | 135 | columns: columnsAnalysis, |
108 | 136 | bordered: true, | ... | ... |
src/views/project/finance/receive/Note.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="register" | |
5 | + title="添加备注" | |
6 | + width="500px" | |
7 | + :bodyStyle="{ height: '240px' }" | |
8 | + @ok="handleOk" | |
9 | + @visible-change="handleShow" | |
10 | + > | |
11 | + 备注: | |
12 | + <a-textarea v-model:value="notes" placeholder="请输入" :rows="6" /> | |
13 | + <div style="height: 10px"></div> | |
14 | + </BasicModal> | |
15 | +</template> | |
16 | +<script lang="ts" setup> | |
17 | + import { BasicModal, useModalInner } from '@/components/Modal'; | |
18 | + import { ref } from 'vue'; | |
19 | + import { getSetBackRefundDate } from '@/api/project/invoice'; | |
20 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
21 | + | |
22 | + const id = ref(); | |
23 | + const notes = ref(); | |
24 | + const checkedKeys = ref(); | |
25 | + const emit = defineEmits(['success']); | |
26 | + const { createMessage } = useMessage(); | |
27 | + const { error } = createMessage; | |
28 | + const [register, { closeModal }] = useModalInner(async (data) => { | |
29 | + id.value = data.data.checkNo; | |
30 | + checkedKeys.value = data.checkedKeys; | |
31 | + }); | |
32 | + const isDisabled = ref(false); | |
33 | + async function handleOk() { | |
34 | + if (isDisabled.value) { | |
35 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
36 | + return; | |
37 | + } | |
38 | + isDisabled.value = true; | |
39 | + setTimeout(() => { | |
40 | + isDisabled.value = false; | |
41 | + }, 3000); | |
42 | + getSetBackRefundDate({ id: checkedKeys.value, notes: notes.value }); | |
43 | + emit('success'); | |
44 | + closeModal(); | |
45 | + } | |
46 | + function handleShow(visible: boolean) { | |
47 | + if (!visible) { | |
48 | + notes.value = null; | |
49 | + } | |
50 | + } | |
51 | +</script> | ... | ... |
src/views/project/finance/receive/ReUploadBgUrl.vue
... | ... | @@ -36,8 +36,8 @@ |
36 | 36 | const emit = defineEmits(['success']); |
37 | 37 | |
38 | 38 | const id = ref(); |
39 | - const uploadUrl = ref('http://47.104.8.35:8081/api/localStorage/upload_file_oss?name='); | |
40 | - const updateUrl = ref('http://47.104.8.35:8081/api/localStorage/upload_file_oss?name='); | |
39 | + const uploadUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
40 | + const updateUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
41 | 41 | const bgUrl = ref(); |
42 | 42 | const urlOld = ref(); |
43 | 43 | ... | ... |
src/views/project/finance/receive/TrackEdit.vue
... | ... | @@ -55,8 +55,10 @@ |
55 | 55 | const deductUrl = ref(); |
56 | 56 | const id = ref(); |
57 | 57 | const invoiceNo = ref(); |
58 | - const uploadUrl = ref('http://47.104.8.35:8081/api/localStorage/upload_file_oss?name='); | |
59 | - const updateDeductUrl = ref('http://47.104.8.35:8081/api/localStorage/upload_file_oss?name='); | |
58 | + const uploadUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
59 | + // const uploadUrl = ref(''); | |
60 | + const updateDeductUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
61 | + // const updateDeductUrl = ref(''); | |
60 | 62 | const deductUrlOld = ref(); |
61 | 63 | const { createMessage } = useMessage(); |
62 | 64 | const { error } = createMessage; | ... | ... |
src/views/project/finance/receive/index.vue
... | ... | @@ -2,6 +2,9 @@ |
2 | 2 | <div class="p-4"> |
3 | 3 | <BasicTable @register="registerTable"> |
4 | 4 | <template #toolbar> |
5 | + <a-button type="primary" @click="handleCommit" :style="{ borderRadius: '5px 5px 5px 5px' }" | |
6 | + >提交审核</a-button | |
7 | + > | |
5 | 8 | <a-button |
6 | 9 | type="primary" |
7 | 10 | @click="handleInvoiceAnalysis" |
... | ... | @@ -9,6 +12,14 @@ |
9 | 12 | v-if="role == ROLE.ADMIN || role == ROLE.FINANCE" |
10 | 13 | >收款单分析</a-button |
11 | 14 | > |
15 | + <a-popconfirm | |
16 | + title="请确认是否删除?" | |
17 | + ok-text="是" | |
18 | + cancel-text="否" | |
19 | + @confirm="handleDeleteIds" | |
20 | + > | |
21 | + <a-button type="primary" :style="{ borderRadius: '5px 5px 5px 5px' }">删除</a-button> | |
22 | + </a-popconfirm> | |
12 | 23 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> |
13 | 24 | <InvoiceAnalysis @register="registerInvoiceAnalysis" /> |
14 | 25 | <TrackEdit @register="registerTrackEdit" @success="handleSuccess" /> |
... | ... | @@ -17,6 +28,7 @@ |
17 | 28 | <Commit @register="registerCommit" @success="handleSuccess" /> |
18 | 29 | <EditRefundTime @register="registerEditRefundTime" @success="handleSuccess" /> |
19 | 30 | <ReUploadBgUrl @register="registerReUploadBgUrl" @success="handleSuccess" /> |
31 | + <Note @register="registerNote" @success="handleSuccess" /> | |
20 | 32 | </template> |
21 | 33 | <template #bodyCell="{ column, record }"> |
22 | 34 | <template v-if="column.key === 'action'"> |
... | ... | @@ -77,6 +89,10 @@ |
77 | 89 | }, |
78 | 90 | ] |
79 | 91 | : []), |
92 | + { | |
93 | + label: '添加备注', | |
94 | + onClick: handleNote.bind(null, record), | |
95 | + }, | |
80 | 96 | ]" |
81 | 97 | /> |
82 | 98 | </template> |
... | ... | @@ -96,10 +112,11 @@ |
96 | 112 | import Commit from './Commit.vue'; |
97 | 113 | import EditRefundTime from './EditRefundTime.vue'; |
98 | 114 | import ReUploadBgUrl from './ReUploadBgUrl.vue'; |
115 | + import Note from './Note.vue'; | |
99 | 116 | import { useDrawer } from '/@/components/Drawer'; |
100 | 117 | import { getInvoice, deleteInvoice, commit, getBaseInvoice } from '@/api/project/invoice'; |
101 | 118 | import { useModal } from '/@/components/Modal'; |
102 | - import { FilePptOutlined } from '@ant-design/icons-vue'; | |
119 | + import { CheckOutlined, FilePptOutlined } from '@ant-design/icons-vue'; | |
103 | 120 | import { icon } from 'ant-design-vue'; |
104 | 121 | import { ROLE } from './type.d'; |
105 | 122 | import { useUserStoreWithOut } from '/@/store/modules/user'; |
... | ... | @@ -112,6 +129,7 @@ |
112 | 129 | const [registerCommit, { openModal: openCommit }] = useModal(); |
113 | 130 | const [registerEditRefundTime, { openModal: openEditRefundTime }] = useModal(); |
114 | 131 | const [registerReUploadBgUrl, { openModal: openReUploadBgUrl }] = useModal(); |
132 | + const [registerNote, { openModal: openNote }] = useModal(); | |
115 | 133 | const [registerDeductShow, { openModal: openDeductShow }] = useModal(); |
116 | 134 | const checkedKeys = ref<Array<string | number>>([]); |
117 | 135 | const userStore = useUserStoreWithOut(); |
... | ... | @@ -257,6 +275,13 @@ |
257 | 275 | reload(); |
258 | 276 | }, 50); |
259 | 277 | } |
278 | + function handleDeleteIds() { | |
279 | + // console.log(checkedKeys.value, '5656checkedKeys.value'); | |
280 | + deleteInvoice({ ids: checkedKeys.value }); | |
281 | + setTimeout(() => { | |
282 | + reload(); | |
283 | + }, 50); | |
284 | + } | |
260 | 285 | function handleDeductShow(record) { |
261 | 286 | openDeductShow(true, { |
262 | 287 | data: record, |
... | ... | @@ -276,6 +301,7 @@ |
276 | 301 | // }, 50); |
277 | 302 | openCommit(true, { |
278 | 303 | data: record, |
304 | + checkedKeys: checkedKeys.value, | |
279 | 305 | }); |
280 | 306 | } |
281 | 307 | function handleEditRefundTime(record) { |
... | ... | @@ -293,6 +319,11 @@ |
293 | 319 | data: record, |
294 | 320 | }); |
295 | 321 | } |
322 | + function handleNote(record) { | |
323 | + openNote(true, { | |
324 | + data: record, | |
325 | + }); | |
326 | + } | |
296 | 327 | const { createMessage } = useMessage(); |
297 | 328 | const { error } = createMessage; |
298 | 329 | function handleInvoiceAnalysis(record) { | ... | ... |
src/views/project/finance/type.d.ts
0 → 100644
1 | +export enum ROLE { | |
2 | + ADMIN = 'admin', // 超管 | |
3 | + CUSTOM_ADMIN = 'custom_admin', // 客户管理员 | |
4 | + DATA_REPORT_USER = 'data_report_user', //数据分析员 | |
5 | + BUSINESS = 'business_user', // 业务员 | |
6 | + TRACKER = 'tracker_user', // 跟单员 | |
7 | + INSPECT = 'inspect_user', // 质检员 | |
8 | + PRODUCE = 'produce_user', //生产科 | |
9 | + FINANCE = 'finance_user', //生产科 | |
10 | +} | ... | ... |
src/views/project/order/CheckDetail.vue
... | ... | @@ -218,12 +218,13 @@ |
218 | 218 | ); |
219 | 219 | |
220 | 220 | if ( |
221 | - values.baseFields.projectNo == 'UN_LOCKED' || | |
222 | - values.baseFields.productionDepartment == 'UN_LOCKED' || | |
223 | - values.baseFields.innerNo == 'UN_LOCKED' || | |
224 | - values.baseFields.customerCode == 'UN_LOCKED' || | |
225 | - values.baseFields.customerPo == 'UN_LOCKED' || | |
226 | - values.baseFields.customerStyle == 'UN_LOCKED' | |
221 | + values.baseFields && | |
222 | + (values.baseFields.projectNo === 'UN_LOCKED' || | |
223 | + values.baseFields.productionDepartment === 'UN_LOCKED' || | |
224 | + values.baseFields.innerNo === 'UN_LOCKED' || | |
225 | + values.baseFields.customerCode === 'UN_LOCKED' || | |
226 | + values.baseFields.customerPo === 'UN_LOCKED' || | |
227 | + values.baseFields.customerStyle === 'UN_LOCKED') | |
227 | 228 | ) { |
228 | 229 | openReasonModal(true, { |
229 | 230 | data: values, | ... | ... |
src/views/project/order/index.vue
... | ... | @@ -387,202 +387,6 @@ |
387 | 387 | console.log(getForm().getFieldsValue()); |
388 | 388 | } |
389 | 389 | |
390 | - // type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] | |
391 | - // type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] | |
392 | - // type ProjectNoEntry = [string, number]; // 定义二维数组类型 [innerNo, count] | |
393 | - | |
394 | - // const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref | |
395 | - // const selectedProductionDepartment = ref<ProductionDepartmentEntry[]>([]); // 创建一个二维数组的 ref | |
396 | - // const selectedProjectNos = ref<ProjectNoEntry[]>([]); // 创建一个二维数组的 ref | |
397 | - | |
398 | - // // 单选处理函数 | |
399 | - // function onSelect( | |
400 | - // record: { | |
401 | - // customerCode: string; | |
402 | - // productionDepartment: string; | |
403 | - // projectNo: string; | |
404 | - // id: string; | |
405 | - // }, | |
406 | - // selected: boolean, | |
407 | - // ) { | |
408 | - // // 查找 customerCode 在 selectedCustomCodes 中的位置 | |
409 | - // const customerCodeIndex = selectedCustomCodes.value.findIndex( | |
410 | - // ([customerCode]) => customerCode === record.customerCode, | |
411 | - // ); | |
412 | - | |
413 | - // // 查找 productionDepartment 在 selectedProductionDepartment 中的位置 | |
414 | - // const productionDepartmentIndex = selectedProductionDepartment.value.findIndex( | |
415 | - // ([department]) => department === record.productionDepartment, | |
416 | - // ); | |
417 | - | |
418 | - // // 查找 projectNo 在 selectedProjectNos 中的位置 | |
419 | - // const projectNoIndex = selectedProjectNos.value.findIndex( | |
420 | - // ([projectNo]) => projectNo === record.projectNo, | |
421 | - // ); | |
422 | - | |
423 | - // if (selected) { | |
424 | - // // 添加到 checkedKeys | |
425 | - // checkedKeys.value = [...checkedKeys.value, record.id]; | |
426 | - | |
427 | - // // 更新 selectedCustomCodes | |
428 | - // if (customerCodeIndex !== -1) { | |
429 | - // // 如果已存在,增加计数 | |
430 | - // selectedCustomCodes.value[customerCodeIndex][1] += 1; | |
431 | - // } else { | |
432 | - // // 如果不存在,添加新项 [customerCode, 1] | |
433 | - // selectedCustomCodes.value.push([record.customerCode, 1]); | |
434 | - // } | |
435 | - | |
436 | - // // 更新 selectedProductionDepartment | |
437 | - // if (productionDepartmentIndex !== -1) { | |
438 | - // // 如果已存在,增加计数 | |
439 | - // selectedProductionDepartment.value[productionDepartmentIndex][1] += 1; | |
440 | - // } else { | |
441 | - // // 如果不存在,添加新项 [productionDepartment, 1] | |
442 | - // selectedProductionDepartment.value.push([record.productionDepartment, 1]); | |
443 | - // } | |
444 | - | |
445 | - // // 更新 selectedProjectNos | |
446 | - // if (projectNoIndex !== -1) { | |
447 | - // // 如果已存在,增加计数 | |
448 | - // selectedProjectNos.value[projectNoIndex][1] += 1; | |
449 | - // } else { | |
450 | - // // 如果不存在,添加新项 [projectNo, 1] | |
451 | - // selectedProjectNos.value.push([record.projectNo, 1]); | |
452 | - // } | |
453 | - // } else { | |
454 | - // // 从 checkedKeys 中移除 | |
455 | - // checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); | |
456 | - | |
457 | - // // 更新 selectedCustomCodes | |
458 | - // if (customerCodeIndex !== -1) { | |
459 | - // if (selectedCustomCodes.value[customerCodeIndex][1] > 1) { | |
460 | - // selectedCustomCodes.value[customerCodeIndex][1] -= 1; | |
461 | - // } else { | |
462 | - // selectedCustomCodes.value.splice(customerCodeIndex, 1); | |
463 | - // } | |
464 | - // } | |
465 | - | |
466 | - // // 更新 selectedProductionDepartment | |
467 | - // if (productionDepartmentIndex !== -1) { | |
468 | - // if (selectedProductionDepartment.value[productionDepartmentIndex][1] > 1) { | |
469 | - // selectedProductionDepartment.value[productionDepartmentIndex][1] -= 1; | |
470 | - // } else { | |
471 | - // selectedProductionDepartment.value.splice(productionDepartmentIndex, 1); | |
472 | - // } | |
473 | - // } | |
474 | - | |
475 | - // // 更新 selectedProjectNos | |
476 | - // if (projectNoIndex !== -1) { | |
477 | - // if (selectedProjectNos.value[projectNoIndex][1] > 1) { | |
478 | - // selectedProjectNos.value[projectNoIndex][1] -= 1; | |
479 | - // } else { | |
480 | - // selectedProjectNos.value.splice(projectNoIndex, 1); | |
481 | - // } | |
482 | - // } | |
483 | - // } | |
484 | - | |
485 | - // console.log('5656Checked Keys:', checkedKeys.value); | |
486 | - // console.log('5656Selected Customer Codes:', selectedCustomCodes.value); | |
487 | - // console.log('56565Selected Production Departments:', selectedProductionDepartment.value); | |
488 | - // console.log('5656Selected projectNo:', selectedProjectNos.value); | |
489 | - // } | |
490 | - | |
491 | - // // 全选处理函数 | |
492 | - // function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) { | |
493 | - // const changeIds = changeRows.map((item) => item.id); | |
494 | - // const changeCustomerCodes = changeRows.map((item) => item.customerCode); | |
495 | - // const changeProductionDepartments = changeRows.map((item) => item.productionDepartment); | |
496 | - // const changeProjectNos = changeRows.map((item) => item.projectNo); | |
497 | - | |
498 | - // if (selected) { | |
499 | - // // 添加到 checkedKeys | |
500 | - // checkedKeys.value = [...checkedKeys.value, ...changeIds]; | |
501 | - | |
502 | - // // 更新 selectedCustomCodes | |
503 | - // changeCustomerCodes.forEach((code) => { | |
504 | - // const index = selectedCustomCodes.value.findIndex( | |
505 | - // ([customerCode]) => customerCode === code, | |
506 | - // ); | |
507 | - // if (index !== -1) { | |
508 | - // selectedCustomCodes.value[index][1] += 1; | |
509 | - // } else { | |
510 | - // selectedCustomCodes.value.push([code, 1]); | |
511 | - // } | |
512 | - // }); | |
513 | - | |
514 | - // // 更新 selectedProductionDepartment | |
515 | - // changeProductionDepartments.forEach((department) => { | |
516 | - // const index = selectedProductionDepartment.value.findIndex( | |
517 | - // ([prodDepartment]) => prodDepartment === department, | |
518 | - // ); | |
519 | - // if (index !== -1) { | |
520 | - // selectedProductionDepartment.value[index][1] += 1; | |
521 | - // } else { | |
522 | - // selectedProductionDepartment.value.push([department, 1]); | |
523 | - // } | |
524 | - // }); | |
525 | - | |
526 | - // // 更新 selectedProjectNos | |
527 | - // changeProjectNos.forEach((projectNo) => { | |
528 | - // const index = selectedProjectNos.value.findIndex(([no]) => no === projectNo); | |
529 | - // if (index !== -1) { | |
530 | - // selectedProjectNos.value[index][1] += 1; | |
531 | - // } else { | |
532 | - // selectedProjectNos.value.push([projectNo, 1]); | |
533 | - // } | |
534 | - // }); | |
535 | - // } else { | |
536 | - // // 从 checkedKeys 中移除 | |
537 | - // checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id)); | |
538 | - | |
539 | - // // 更新 selectedCustomCodes | |
540 | - // changeCustomerCodes.forEach((code) => { | |
541 | - // const index = selectedCustomCodes.value.findIndex( | |
542 | - // ([customerCode]) => customerCode === code, | |
543 | - // ); | |
544 | - // if (index !== -1) { | |
545 | - // if (selectedCustomCodes.value[index][1] > 1) { | |
546 | - // selectedCustomCodes.value[index][1] -= 1; | |
547 | - // } else { | |
548 | - // selectedCustomCodes.value.splice(index, 1); | |
549 | - // } | |
550 | - // } | |
551 | - // }); | |
552 | - | |
553 | - // // 更新 selectedProductionDepartment | |
554 | - // changeProductionDepartments.forEach((department) => { | |
555 | - // const index = selectedProductionDepartment.value.findIndex( | |
556 | - // ([prodDepartment]) => prodDepartment === department, | |
557 | - // ); | |
558 | - // if (index !== -1) { | |
559 | - // if (selectedProductionDepartment.value[index][1] > 1) { | |
560 | - // selectedProductionDepartment.value[index][1] -= 1; | |
561 | - // } else { | |
562 | - // selectedProductionDepartment.value.splice(index, 1); | |
563 | - // } | |
564 | - // } | |
565 | - // }); | |
566 | - | |
567 | - // // 更新 selectedProjectNos | |
568 | - // changeProjectNos.forEach((projectNo) => { | |
569 | - // const index = selectedProjectNos.value.findIndex(([no]) => no === projectNo); | |
570 | - // if (index !== -1) { | |
571 | - // if (selectedProjectNos.value[index][1] > 1) { | |
572 | - // selectedProjectNos.value[index][1] -= 1; | |
573 | - // } else { | |
574 | - // selectedProjectNos.value.splice(index, 1); | |
575 | - // } | |
576 | - // } | |
577 | - // }); | |
578 | - // } | |
579 | - | |
580 | - // console.log('5656Checked Keys:', checkedKeys.value); | |
581 | - // console.log('5656Selected Customer Codes:', selectedCustomCodes.value); | |
582 | - // console.log('5656Selected Production Departments:', selectedProductionDepartment.value); | |
583 | - // console.log('5656Selected projectNos:', selectedProjectNos.value); | |
584 | - // } | |
585 | - | |
586 | 390 | type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] |
587 | 391 | type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] |
588 | 392 | type ProjectNoEntry = [string, number]; // 定义二维数组类型 [innerNo, count] |
... | ... | @@ -690,11 +494,11 @@ |
690 | 494 | } |
691 | 495 | } |
692 | 496 | |
693 | - console.log('Checked Keys:', checkedKeys.value); | |
694 | - console.log('Selected Customer Codes:', selectedCustomCodes.value); | |
695 | - console.log('Selected Production Departments:', selectedProductionDepartment.value); | |
696 | - console.log('Selected Project Nos:', selectedProjectNos.value); | |
697 | - console.log('Selected Business Persons:', selectedBusinessPersons.value); | |
497 | + // console.log('Checked Keys:', checkedKeys.value); | |
498 | + // console.log('Selected Customer Codes:', selectedCustomCodes.value); | |
499 | + // console.log('Selected Production Departments:', selectedProductionDepartment.value); | |
500 | + // console.log('Selected Project Nos:', selectedProjectNos.value); | |
501 | + // console.log('Selected Business Persons:', selectedBusinessPersons.value); | |
698 | 502 | } |
699 | 503 | |
700 | 504 | // 全选处理函数 |
... | ... | @@ -807,11 +611,11 @@ |
807 | 611 | }); |
808 | 612 | } |
809 | 613 | |
810 | - console.log('Checked Keys:', checkedKeys.value); | |
811 | - console.log('Selected Customer Codes:', selectedCustomCodes.value); | |
812 | - console.log('Selected Production Departments:', selectedProductionDepartment.value); | |
813 | - console.log('Selected Project Nos:', selectedProjectNos.value); | |
814 | - console.log('Selected Business Persons:', selectedBusinessPersons.value); | |
614 | + // console.log('Checked Keys:', checkedKeys.value); | |
615 | + // console.log('Selected Customer Codes:', selectedCustomCodes.value); | |
616 | + // console.log('Selected Production Departments:', selectedProductionDepartment.value); | |
617 | + // console.log('Selected Project Nos:', selectedProjectNos.value); | |
618 | + // console.log('Selected Business Persons:', selectedBusinessPersons.value); | |
815 | 619 | } |
816 | 620 | |
817 | 621 | function handleClearChoose() { | ... | ... |
src/views/project/order/tableData.tsx
... | ... | @@ -56,6 +56,11 @@ export const ORDER_LIST_BASE_FIELDS = [ |
56 | 56 | dataIndex: 'invoiceNo', |
57 | 57 | }, |
58 | 58 | { |
59 | + title: '生产科对账单号', | |
60 | + width: 150, | |
61 | + dataIndex: 'checkNo', | |
62 | + }, | |
63 | + { | |
59 | 64 | title: '生产科', |
60 | 65 | width: 150, |
61 | 66 | dataIndex: 'productionDepartment', |
... | ... | @@ -1857,6 +1862,41 @@ export function getFormConfig(businessUsers: any[]): Partial<FormProps> { |
1857 | 1862 | options: businessUsers, |
1858 | 1863 | }, |
1859 | 1864 | }, |
1865 | + { | |
1866 | + field: 'invoiceNo', | |
1867 | + label: '发票单号', | |
1868 | + component: 'Input', | |
1869 | + colProps: { span: 6 }, | |
1870 | + labelWidth: 150, | |
1871 | + }, | |
1872 | + { | |
1873 | + field: 'invoiceStatus', | |
1874 | + label: '发票状态', | |
1875 | + component: 'Select', | |
1876 | + colProps: { span: 6 }, | |
1877 | + labelWidth: 150, | |
1878 | + componentProps: { | |
1879 | + options: [ | |
1880 | + { label: '未创建', value: -1 }, | |
1881 | + { label: '未收款', value: 0 }, | |
1882 | + { label: '已收款', value: 10 }, | |
1883 | + ], | |
1884 | + }, | |
1885 | + }, | |
1886 | + { | |
1887 | + field: 'checkNoStatus', | |
1888 | + label: '对账单号状态', | |
1889 | + component: 'Select', | |
1890 | + colProps: { span: 6 }, | |
1891 | + labelWidth: 150, | |
1892 | + componentProps: { | |
1893 | + options: [ | |
1894 | + { label: '未创建', value: -1 }, | |
1895 | + { label: '未收款', value: 0 }, | |
1896 | + { label: '已收款', value: 10 }, | |
1897 | + ], | |
1898 | + }, | |
1899 | + }, | |
1860 | 1900 | ], |
1861 | 1901 | }; |
1862 | 1902 | } | ... | ... |
vite.config.ts
... | ... | @@ -22,7 +22,7 @@ export default defineApplicationConfig({ |
22 | 22 | server: { |
23 | 23 | proxy: { |
24 | 24 | '/aliyun-oss-pdf': { |
25 | - target: 'https://test-alterego.oss-cn-qingdao.aliyuncs.com', | |
25 | + target: 'https://alterego.oss-cn-qingdao.aliyuncs.com', | |
26 | 26 | changeOrigin: true, |
27 | 27 | secure: true, // 确保使用 HTTPS |
28 | 28 | rewrite(path) { |
... | ... | @@ -30,8 +30,8 @@ export default defineApplicationConfig({ |
30 | 30 | }, |
31 | 31 | }, |
32 | 32 | '/basic-api/order': { |
33 | - target: 'http://47.104.8.35:18001', | |
34 | - // target: 'http://localhost:8001', | |
33 | + target: 'http://47.104.8.35:18000', | |
34 | + // target: 'http://localhost:18001', | |
35 | 35 | // target: 'http://39.108.227.113:8000', |
36 | 36 | // target: 'http://localhost:8000', |
37 | 37 | // target: 'http://39.108.227.113:3000/mock/35', |
... | ... | @@ -41,8 +41,8 @@ export default defineApplicationConfig({ |
41 | 41 | rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), |
42 | 42 | }, |
43 | 43 | '/api/localStorage/upload': { |
44 | - target: 'http://47.104.8.35:18001', | |
45 | - // target: 'http://localhost:8001', | |
44 | + target: 'http://47.104.8.35:18000', | |
45 | + // target: 'http://localhost:18001', | |
46 | 46 | // target: 'http://39.108.227.113:8000', |
47 | 47 | // target: '192.168.31.250:18000', |
48 | 48 | // target: 'http://localhost:8000', | ... | ... |