Commit cfeaf8a04714a1fc5d8d07db2a3034e71e3b5b0d
1 parent
7a8f528e
审核调试
Showing
32 changed files
with
3284 additions
and
138 deletions
src/api/project/invoice.ts
... | ... | @@ -34,6 +34,19 @@ enum Api { |
34 | 34 | EXPORTRECEIPT = '/order/erp/check_bill/exportReceipt', //付款单导出 |
35 | 35 | SETPADYEDDATE = '/order/erp/check_bill/setPayedDate', //修改应付款日期 |
36 | 36 | CHECKNOTE = '/order/erp/check_bill/notes', //备注 |
37 | + | |
38 | + PACKAGEPROFIT = '/order/cost/BusinessProfitDetail/listByPage', //包装费用明细表 | |
39 | + INNERPROFIT = '/order/cost/InnerProfitDetail/listByPage', //内部生产费用明细表 | |
40 | + PACKAGEEDIT = '/order/cost/edit', //编辑 | |
41 | + PACKAGEAPPLYEDIT = '/order/cost/applyEditFileds', //申请编辑字段 | |
42 | + SERVICEPROFIT = '/project/BusinessProfitInfo/listByPage', //业务研发净利润分析表 | |
43 | + INNERPRODUCEPROFIT = '/project/InnerProfitInfo/listByPage', //内部生产利润分析表 | |
44 | + SERVICEPROFITEXPORT = '/project/businessProfit/export', //业务研发净利润分析表导出 | |
45 | + INNERPROFITEXPORT = '/project/innerProfit/export', //内部研发净利润分析表导出 | |
46 | + SERVICEEDIT = '/project/edit', //编辑 | |
47 | + SERVICEAPPLYEDIT = '/project/applyEditFileds', //申请修改 | |
48 | + APPLYLIST = '/project/pageProjectLockFieldApply', //分页查询项目字段申请记录 | |
49 | + AUDITAPPLY = '/project/audit', //审核 | |
37 | 50 | } |
38 | 51 | |
39 | 52 | export const getRefundDate = async (params: any, data?: any) => { |
... | ... | @@ -71,6 +84,7 @@ export const getInvoice = async (params: any) => { |
71 | 84 | }); |
72 | 85 | const orderStore = useOrderStoreWithOut(); |
73 | 86 | orderStore.setTotal(res.total); |
87 | + orderStore.setQueryVO(params); | |
74 | 88 | return new Promise((resolve) => { |
75 | 89 | resolve({ |
76 | 90 | items: formattedRecords, |
... | ... | @@ -282,3 +296,143 @@ export const getCheckNote = async (params: any) => { |
282 | 296 | params, |
283 | 297 | }); |
284 | 298 | }; |
299 | + | |
300 | +export const getPackageProfit = async (params: any) => { | |
301 | + const res = await defHttp.post<any>({ | |
302 | + url: Api.PACKAGEPROFIT, | |
303 | + params, | |
304 | + }); | |
305 | + const formattedRecords = res.records.map((record: any) => { | |
306 | + return { | |
307 | + ...record, | |
308 | + }; | |
309 | + }); | |
310 | + const orderStore = useOrderStoreWithOut(); | |
311 | + orderStore.setTotal(res.total); | |
312 | + orderStore.setQueryVO(params); | |
313 | + return new Promise((resolve) => { | |
314 | + resolve({ | |
315 | + items: formattedRecords, | |
316 | + total: res.total, | |
317 | + }); | |
318 | + }); | |
319 | +}; | |
320 | + | |
321 | +export const getInnerProfit = async (params: any) => { | |
322 | + const res = await defHttp.post<any>({ | |
323 | + url: Api.INNERPROFIT, | |
324 | + params, | |
325 | + }); | |
326 | + const formattedRecords = res.records.map((record: any) => { | |
327 | + return { | |
328 | + ...record, | |
329 | + }; | |
330 | + }); | |
331 | + const orderStore = useOrderStoreWithOut(); | |
332 | + orderStore.setTotal(res.total); | |
333 | + orderStore.setQueryVO(params); | |
334 | + return new Promise((resolve) => { | |
335 | + resolve({ | |
336 | + items: formattedRecords, | |
337 | + total: res.total, | |
338 | + }); | |
339 | + }); | |
340 | +}; | |
341 | + | |
342 | +export const getPackageEdit = async (params: any) => { | |
343 | + return await defHttp.post<any>({ | |
344 | + url: Api.PACKAGEEDIT, | |
345 | + params, | |
346 | + }); | |
347 | +}; | |
348 | + | |
349 | +export const getPackageApplyEdit = async (params: any) => { | |
350 | + return await defHttp.post<any>({ | |
351 | + url: Api.PACKAGEAPPLYEDIT, | |
352 | + params, | |
353 | + }); | |
354 | +}; | |
355 | + | |
356 | +export const getServiceProfit = async (params: any) => { | |
357 | + const res = await defHttp.post<any>({ | |
358 | + url: Api.SERVICEPROFIT, | |
359 | + params, | |
360 | + }); | |
361 | + const formattedRecords = res.records.map((record: any) => { | |
362 | + return { | |
363 | + ...record, | |
364 | + }; | |
365 | + }); | |
366 | + const orderStore = useOrderStoreWithOut(); | |
367 | + orderStore.setTotal(res.total); | |
368 | + orderStore.setQueryVO(params); | |
369 | + return new Promise((resolve) => { | |
370 | + resolve({ | |
371 | + items: formattedRecords, | |
372 | + total: res.total, | |
373 | + }); | |
374 | + }); | |
375 | +}; | |
376 | + | |
377 | +export const getInnerProduceProfit = async (params: any) => { | |
378 | + const res = await defHttp.post<any>({ | |
379 | + url: Api.INNERPRODUCEPROFIT, | |
380 | + params, | |
381 | + }); | |
382 | + const formattedRecords = res.records.map((record: any) => { | |
383 | + return { | |
384 | + ...record, | |
385 | + }; | |
386 | + }); | |
387 | + const orderStore = useOrderStoreWithOut(); | |
388 | + orderStore.setTotal(res.total); | |
389 | + orderStore.setQueryVO(params); | |
390 | + return new Promise((resolve) => { | |
391 | + resolve({ | |
392 | + items: formattedRecords, | |
393 | + total: res.total, | |
394 | + }); | |
395 | + }); | |
396 | +}; | |
397 | + | |
398 | +export const getServiceProfitExport = async (params: any) => { | |
399 | + return await defHttp.post<any>({ | |
400 | + url: Api.SERVICEPROFITEXPORT, | |
401 | + params, | |
402 | + }); | |
403 | +}; | |
404 | + | |
405 | +export const getInnerProfitExport = async (params: any) => { | |
406 | + return await defHttp.post<any>({ | |
407 | + url: Api.INNERPROFITEXPORT, | |
408 | + params, | |
409 | + }); | |
410 | +}; | |
411 | + | |
412 | +export const getServiceEdit = async (params: any) => { | |
413 | + return await defHttp.post<any>({ | |
414 | + url: Api.SERVICEEDIT, | |
415 | + params, | |
416 | + }); | |
417 | +}; | |
418 | + | |
419 | +export const getServiceApplyEdit = async (params: any) => { | |
420 | + return await defHttp.post<any>({ | |
421 | + url: Api.SERVICEAPPLYEDIT, | |
422 | + params, | |
423 | + }); | |
424 | +}; | |
425 | + | |
426 | +export const getApplyList = async (params: any) => { | |
427 | + return await defHttp.post<any>({ | |
428 | + url: Api.APPLYLIST, | |
429 | + params, | |
430 | + }); | |
431 | +}; | |
432 | + | |
433 | +export const getAuditApply = async (params: any) => { | |
434 | + return await defHttp.post<any>({ | |
435 | + url: Api.AUDITAPPLY, | |
436 | + params, | |
437 | + }); | |
438 | +}; | ... | ... |
src/router/routes/modules/project/finance.ts
... | ... | @@ -43,96 +43,106 @@ const finance: AppRouteModule = { |
43 | 43 | }, |
44 | 44 | component: () => import('/@/views/project/finance/financeList/index.vue'), |
45 | 45 | }, |
46 | - // { | |
47 | - // path: 'financeProfit', | |
48 | - // name: 'FinanceProfit', | |
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 | - // children: [ | |
62 | - // // { | |
63 | - // // path: '', | |
64 | - // // name: 'Receive', | |
65 | - // // meta: { | |
66 | - // // title: '财务管理', | |
67 | - // // roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
68 | - // // ignoreKeepAlive: false, | |
69 | - // // }, | |
70 | - // // // component: () => import('/@/views/project/finance/index.vue'), | |
71 | - // // }, | |
72 | - // { | |
73 | - // path: 'serviceProfit', | |
74 | - // name: 'ServiceProfit', | |
75 | - // meta: { | |
76 | - // title: '业务研发净利润分析', | |
77 | - // roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
78 | - // ignoreKeepAlive: false, | |
79 | - // }, | |
80 | - // children: [ | |
81 | - // { | |
82 | - // path: 'serviceProfit', | |
83 | - // name: 'ServiceProfit', | |
84 | - // meta: { | |
85 | - // title: '业务研发净利润分析', | |
86 | - // roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
87 | - // ignoreKeepAlive: false, | |
88 | - // }, | |
89 | - // component: () => import('/@/views/project/finance/financeProfit/index.vue'), | |
90 | - // }, | |
91 | - // { | |
92 | - // path: 'serviceProfit', | |
93 | - // name: 'ServiceProfit', | |
94 | - // meta: { | |
95 | - // title: '业务研发净利润分析', | |
96 | - // roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
97 | - // ignoreKeepAlive: false, | |
98 | - // }, | |
99 | - // component: () => import('/@/views/project/finance/financeProfit/index.vue'), | |
100 | - // }, | |
101 | - // ], | |
102 | - // }, | |
103 | - // { | |
104 | - // path: 'productProfit', | |
105 | - // name: 'ProductProfit', | |
106 | - // meta: { | |
107 | - // title: '内部生产净利润分析', | |
108 | - // roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
109 | - // ignoreKeepAlive: false, | |
110 | - // }, | |
111 | - // children: [ | |
112 | - // { | |
113 | - // path: 'serviceProfit', | |
114 | - // name: 'ServiceProfit', | |
115 | - // meta: { | |
116 | - // title: '业务研发净利润分析', | |
117 | - // roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
118 | - // ignoreKeepAlive: false, | |
119 | - // }, | |
120 | - // component: () => import('/@/views/project/finance/index.vue'), | |
121 | - // }, | |
122 | - // { | |
123 | - // path: 'serviceProfit', | |
124 | - // name: 'ServiceProfit', | |
125 | - // meta: { | |
126 | - // title: '业务研发净利润分析', | |
127 | - // roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
128 | - // ignoreKeepAlive: false, | |
129 | - // }, | |
130 | - // component: () => import('/@/views/project/finance/index.vue'), | |
131 | - // }, | |
132 | - // ], | |
133 | - // }, | |
134 | - // ], | |
135 | - // }, | |
46 | + { | |
47 | + path: 'financeProfit', | |
48 | + name: 'FinanceProfit', | |
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 | + children: [ | |
62 | + // { | |
63 | + // path: '', | |
64 | + // name: 'Receive', | |
65 | + // meta: { | |
66 | + // title: '财务管理', | |
67 | + // roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
68 | + // ignoreKeepAlive: false, | |
69 | + // }, | |
70 | + // // component: () => import('/@/views/project/finance/index.vue'), | |
71 | + // }, | |
72 | + { | |
73 | + path: 'serviceProfit', | |
74 | + name: 'ServiceProfit', | |
75 | + meta: { | |
76 | + title: '业务研发净利润分析', | |
77 | + roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
78 | + ignoreKeepAlive: false, | |
79 | + }, | |
80 | + children: [ | |
81 | + { | |
82 | + path: 'ServiceProfit', | |
83 | + name: 'ServiceProfit', | |
84 | + meta: { | |
85 | + title: '业务研发净利润分析表', | |
86 | + roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
87 | + ignoreKeepAlive: false, | |
88 | + }, | |
89 | + component: () => | |
90 | + import( | |
91 | + '/@/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/index.vue' | |
92 | + ), | |
93 | + }, | |
94 | + { | |
95 | + path: 'PackageProfit', | |
96 | + name: 'PackageProfit', | |
97 | + meta: { | |
98 | + title: '包装费用明细表', | |
99 | + roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
100 | + ignoreKeepAlive: false, | |
101 | + }, | |
102 | + component: () => | |
103 | + import( | |
104 | + '/@/views/project/finance/financeProfit/ServiceProfit/PackageProfit/index.vue' | |
105 | + ), | |
106 | + }, | |
107 | + ], | |
108 | + }, | |
109 | + { | |
110 | + path: 'ProductProfit', | |
111 | + name: 'ProductProfit', | |
112 | + meta: { | |
113 | + title: '内部生产净利润分析', | |
114 | + roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
115 | + ignoreKeepAlive: false, | |
116 | + }, | |
117 | + children: [ | |
118 | + { | |
119 | + path: 'InnerData', | |
120 | + name: 'InnerData', | |
121 | + meta: { | |
122 | + title: '内部生产净利润分析表', | |
123 | + roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
124 | + ignoreKeepAlive: false, | |
125 | + }, | |
126 | + component: () => | |
127 | + import( | |
128 | + '/@/views/project/finance/financeProfit/ProductProfit/InnerProduce/index.vue' | |
129 | + ), | |
130 | + }, | |
131 | + { | |
132 | + path: 'InnerProduce', | |
133 | + name: 'InnerProduce', | |
134 | + meta: { | |
135 | + title: '内部生产明细表', | |
136 | + roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | |
137 | + ignoreKeepAlive: false, | |
138 | + }, | |
139 | + component: () => | |
140 | + import('/@/views/project/finance/financeProfit/ProductProfit/InnerData/index.vue'), | |
141 | + }, | |
142 | + ], | |
143 | + }, | |
144 | + ], | |
145 | + }, | |
136 | 146 | ], |
137 | 147 | }; |
138 | 148 | ... | ... |
src/settings/componentSetting.ts
... | ... | @@ -18,7 +18,7 @@ export default { |
18 | 18 | totalField: 'total', |
19 | 19 | }, |
20 | 20 | // Number of pages that can be selected |
21 | - pageSizeOptions: ['10', '50', '80', '100'], | |
21 | + pageSizeOptions: ['10', '50', '80', '100', '1000'], | |
22 | 22 | // Default display quantity on one page |
23 | 23 | defaultPageSize: 10, |
24 | 24 | // Default Size | ... | ... |
src/store/modules/order.ts
... | ... | @@ -18,12 +18,36 @@ import { h } from 'vue'; |
18 | 18 | import { getInitDictData } from '/@/api/project/order'; |
19 | 19 | import { groupBy } from 'lodash-es'; |
20 | 20 | |
21 | +interface QueryVO { | |
22 | + checkEndTime?: string; | |
23 | + checkNo?: string; | |
24 | + checkNoStatus?: number; | |
25 | + checkStartTime?: string; | |
26 | + createEndTime?: string; | |
27 | + createStartTime?: string; | |
28 | + customerCode?: string[]; | |
29 | + innerNo?: string[]; | |
30 | + invoiceEndTime?: string; | |
31 | + invoiceNo?: string; | |
32 | + invoiceStartTime?: string; | |
33 | + invoiceStatus?: number; | |
34 | + orderHodEndTime?: string; | |
35 | + orderHodStartTime?: string; | |
36 | + page: number; | |
37 | + pageSize: number; | |
38 | + productionDepartment?: string[]; | |
39 | + productionDepartmentConsignEndTime?: string; | |
40 | + productionDepartmentConsignStartTime?: string; | |
41 | + projectNo?: string[]; | |
42 | +} | |
43 | + | |
21 | 44 | interface UserState { |
22 | 45 | userInfo: Nullable<UserInfo>; |
23 | 46 | token?: string; |
24 | 47 | roleList: RoleEnum[]; |
25 | 48 | sessionTimeout?: boolean; |
26 | 49 | lastUpdateTime: number; |
50 | + queryVO: QueryVO[]; | |
27 | 51 | } |
28 | 52 | |
29 | 53 | export const useOrderStore = defineStore({ |
... | ... | @@ -39,6 +63,7 @@ export const useOrderStore = defineStore({ |
39 | 63 | sessionTimeout: false, |
40 | 64 | // Last fetch time |
41 | 65 | lastUpdateTime: 0, |
66 | + queryVO: [], | |
42 | 67 | }), |
43 | 68 | getters: { |
44 | 69 | getDictInfo(state): UserInfo { |
... | ... | @@ -59,6 +84,9 @@ export const useOrderStore = defineStore({ |
59 | 84 | getLastUpdateTime(state): number { |
60 | 85 | return state.lastUpdateTime; |
61 | 86 | }, |
87 | + getQueryVO(state) { | |
88 | + return state.queryVO; // 新增 getter 返回 queryVO | |
89 | + }, | |
62 | 90 | }, |
63 | 91 | actions: { |
64 | 92 | setToken(info: string | undefined) { |
... | ... | @@ -80,6 +108,11 @@ export const useOrderStore = defineStore({ |
80 | 108 | setSessionTimeout(flag: boolean) { |
81 | 109 | this.sessionTimeout = flag; |
82 | 110 | }, |
111 | + setQueryVO(params: QueryVO[]) { | |
112 | + params.page = undefined; | |
113 | + params.pageSize = undefined; | |
114 | + this.queryVO = params; | |
115 | + }, | |
83 | 116 | resetState() { |
84 | 117 | this.userInfo = null; |
85 | 118 | this.token = ''; | ... | ... |
src/views/project/approve/PayPanel.vue
... | ... | @@ -114,15 +114,18 @@ |
114 | 114 | <template #appendFooter> |
115 | 115 | <a-button |
116 | 116 | v-if=" |
117 | - ((!isApproved && role === ROLE.ADMIN) || (!isApproved && showInvoice)) && | |
118 | - (role !== ROLE.BUSINESS || role !== ROLE.TRACKER) | |
117 | + (!isApproved && role === ROLE.ADMIN) || | |
118 | + (!isApproved && showInvoice && role === ROLE.FINANCE) | |
119 | 119 | " |
120 | 120 | @click="handleFalse" |
121 | 121 | > |
122 | 122 | 不通过</a-button |
123 | 123 | > |
124 | 124 | <a-button |
125 | - v-if="(isApproved && role === ROLE.ADMIN) || (isApproved && showInvoice)" | |
125 | + v-if=" | |
126 | + (isApproved && role === ROLE.ADMIN) || | |
127 | + (isApproved && showInvoice && role === ROLE.FINANCE) | |
128 | + " | |
126 | 129 | @click="handleFalse" |
127 | 130 | > |
128 | 131 | 驳回重填</a-button |
... | ... | @@ -232,7 +235,7 @@ |
232 | 235 | if (record?.type === 40) { |
233 | 236 | data.value = record?.fieldInfos?.producePaymentCheckBillFieldVO; |
234 | 237 | } else if (record?.type == 50) { |
235 | - data.value = record?.fieldInfos?.checkBillOrderDO; | |
238 | + data.value = record?.fieldInfos?.checkBillVO; | |
236 | 239 | } |
237 | 240 | if (record?.type === 40) { |
238 | 241 | return data.value?.financePerson; |
... | ... | @@ -253,9 +256,7 @@ |
253 | 256 | const extractedValues = ref<string[]>(data.value?.innerNo.map((item) => item)); |
254 | 257 | return extractedValues.value.join(','); |
255 | 258 | } else if (record?.type == 50) { |
256 | - if (record?.orderBaseInfo) { | |
257 | - return record?.orderBaseInfo?.innerNo; | |
258 | - } | |
259 | + return record?.fieldInfos?.checkBillVO?.innerNo; | |
259 | 260 | } |
260 | 261 | }, |
261 | 262 | }, |
... | ... | @@ -282,7 +283,7 @@ |
282 | 283 | if (record?.type === 40) { |
283 | 284 | data.value = record?.fieldInfos?.producePaymentCheckBillFieldVO; |
284 | 285 | } else if (record?.type == 50) { |
285 | - data.value = record?.fieldInfos?.checkBillOrderDO; | |
286 | + data.value = record?.fieldInfos?.checkBillVO; | |
286 | 287 | } |
287 | 288 | return data.value?.productionName; |
288 | 289 | }, |
... | ... | @@ -349,7 +350,7 @@ |
349 | 350 | async function handleDetail(data) { |
350 | 351 | if (data.type == 50) { |
351 | 352 | showInvoice.value = true; |
352 | - mockData.value = data.fieldInfos.checkBillOrderDO; | |
353 | + mockData.value = data.fieldInfos.checkBillVO; | |
353 | 354 | } else if (data.type == 40) { |
354 | 355 | showInvoice.value = false; |
355 | 356 | mockData.value = data.fieldInfos.producePaymentCheckBillFieldVO; | ... | ... |
src/views/project/config/data.tsx
... | ... | @@ -17,15 +17,6 @@ export const COLUMNS = { |
17 | 17 | width: 150, |
18 | 18 | editComponent: 'InputNumber', |
19 | 19 | editRow: true, |
20 | - // Function to determine if the row is editable based on the value of 'relationValue' | |
21 | - // editRow: (text) => { | |
22 | - // console.log(text, '56565665editrecord'); // Log the text value for debugging | |
23 | - // return false; // Only make the row editable if the value is 0.34 | |
24 | - // }, | |
25 | - // onEditRow: (text, record) => { | |
26 | - // console.log(text, '56565665editrecord', record); // Log the text value for debugging | |
27 | - // return false; // Only make the row editable if the value is 0.34 | |
28 | - // }, | |
29 | 20 | }, |
30 | 21 | ], |
31 | 22 | 2: [ |
... | ... | @@ -253,8 +244,3 @@ export const columnsProduct: BasicColumn[] = [ |
253 | 244 | editRow: true, |
254 | 245 | }, |
255 | 246 | ]; |
256 | -const handleEdit = (key, value) => { | |
257 | - // Logic to update the data based on key and value | |
258 | - // You can update the state or call your API depending on how your data is structured | |
259 | - console.log(`Editing row ${key}, new value: ${value}`); | |
260 | -}; | ... | ... |
src/views/project/finance/financeList/CheckSumCheck.vue
... | ... | @@ -21,11 +21,13 @@ |
21 | 21 | </template> |
22 | 22 | <script lang="ts" setup> |
23 | 23 | import { BasicModal, useModalInner } from '@/components/Modal'; |
24 | - import { computed, ref } from 'vue'; | |
24 | + import { computed, ref, watch } from 'vue'; | |
25 | 25 | import { checkAnalysis, exportCheckAnalysis } from '@/api/project/invoice'; |
26 | 26 | import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table'; |
27 | 27 | // 处理弹窗的确定按钮点击事件 |
28 | 28 | import axios from 'axios'; |
29 | + import { store } from '/@/store'; | |
30 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
29 | 31 | |
30 | 32 | const columnsAnalysis: BasicColumn[] = [ |
31 | 33 | { |
... | ... | @@ -81,6 +83,16 @@ |
81 | 83 | const ids = ref(); |
82 | 84 | const orderIds = ref(); |
83 | 85 | // const res = ref(); |
86 | + const dataStore = useOrderStoreWithOut(); // 获取 store 实例 | |
87 | + const queryVO = ref(); | |
88 | + watch( | |
89 | + () => store.state, // 监控 queryVO | |
90 | + (newQueryVO, oldQueryVO) => { | |
91 | + queryVO.value = dataStore.getQueryVO; | |
92 | + // 在这里可以根据 queryVO 的变化进行其他操作,比如重新请求数据等 | |
93 | + }, | |
94 | + { deep: true }, // 深度监控 queryVO 数组或对象的变化 | |
95 | + ); | |
84 | 96 | |
85 | 97 | const [register, { closeModal }] = useModalInner(async (data) => { |
86 | 98 | // ids.value = data.data; |
... | ... | @@ -93,7 +105,11 @@ |
93 | 105 | const [registerTable, { reload }] = useTable({ |
94 | 106 | // api: () => invoiceAnalysis({ ids: ids.value }), |
95 | 107 | api: async () => { |
96 | - const res = await checkAnalysis({ ids: ids.value, orderIds: orderIds.value }); | |
108 | + const res = await checkAnalysis({ | |
109 | + ids: ids.value, | |
110 | + orderIds: orderIds.value, | |
111 | + queryVO: queryVO.value, | |
112 | + }); | |
97 | 113 | // 计算合计行 |
98 | 114 | const sum = { |
99 | 115 | productionDepartmentTotalPrice: 0, |
... | ... | @@ -135,7 +151,7 @@ |
135 | 151 | axios |
136 | 152 | .post( |
137 | 153 | '/basic-api/order/erp/check_bill/export', |
138 | - { ids: idss, orderIds: orderIds.value }, | |
154 | + { ids: idss, orderIds: orderIds.value, queryVO: queryVO.value }, | |
139 | 155 | { |
140 | 156 | responseType: 'blob', // 设置响应类型为 'blob' |
141 | 157 | }, | ... | ... |
src/views/project/finance/financeList/FinanceEdit.vue
... | ... | @@ -131,6 +131,7 @@ |
131 | 131 | // 方式1 |
132 | 132 | status.value = data.data.invoiceStatus; |
133 | 133 | id.value = data.data.invoiceId; |
134 | + console.log(data, '5656afds'); | |
134 | 135 | input1.value = data.data.invoiceActualPayedAmount1; |
135 | 136 | input2.value = data.data.invoiceActualPayedAmount2; |
136 | 137 | input3.value = data.data.invoiceActualPayedAmount3; | ... | ... |
src/views/project/finance/financeList/InvoiceAnalysis.vue
... | ... | @@ -21,11 +21,14 @@ |
21 | 21 | </template> |
22 | 22 | <script lang="ts" setup> |
23 | 23 | import { BasicModal, useModalInner } from '@/components/Modal'; |
24 | - import { computed, ref } from 'vue'; | |
24 | + import { computed, ref, watch } from 'vue'; | |
25 | 25 | import { invoiceAnalysis, exportAnalysis } from '@/api/project/invoice'; |
26 | 26 | import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table'; |
27 | 27 | // 处理弹窗的确定按钮点击事件 |
28 | 28 | import axios from 'axios'; |
29 | + import { useDataStoreWithOut } from '/@/store/modules/data'; | |
30 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
31 | + import { store } from '/@/store'; | |
29 | 32 | |
30 | 33 | const columnsAnalysis: BasicColumn[] = [ |
31 | 34 | { |
... | ... | @@ -89,6 +92,16 @@ |
89 | 92 | const ids = ref(); |
90 | 93 | const orderIds = ref(); |
91 | 94 | const tableData = ref([]); |
95 | + const dataStore = useOrderStoreWithOut(); // 获取 store 实例 | |
96 | + const queryVO = ref(); | |
97 | + watch( | |
98 | + () => store.state, // 监控 queryVO | |
99 | + (newQueryVO, oldQueryVO) => { | |
100 | + queryVO.value = dataStore.getQueryVO; | |
101 | + // 在这里可以根据 queryVO 的变化进行其他操作,比如重新请求数据等 | |
102 | + }, | |
103 | + { deep: true }, // 深度监控 queryVO 数组或对象的变化 | |
104 | + ); | |
92 | 105 | // const res = ref(); |
93 | 106 | |
94 | 107 | const [register, { closeModal }] = useModalInner(async (data) => { |
... | ... | @@ -101,7 +114,11 @@ |
101 | 114 | const [registerTable, { reload }] = useTable({ |
102 | 115 | // api: () => invoiceAnalysis({ ids: ids.value }), |
103 | 116 | api: async () => { |
104 | - const res = await invoiceAnalysis({ ids: ids.value, orderId: orderIds.value }); | |
117 | + const res = await invoiceAnalysis({ | |
118 | + ids: ids.value, | |
119 | + orderIds: orderIds.value, | |
120 | + queryVO: queryVO.value, | |
121 | + }); | |
105 | 122 | // 计算合计行 |
106 | 123 | const sum = { |
107 | 124 | customerTotalPrice: 0, |
... | ... | @@ -141,7 +158,11 @@ |
141 | 158 | axios |
142 | 159 | .post( |
143 | 160 | '/basic-api/order/erp/invoice_bill/export', |
144 | - { ids: idss, orderId: orderIds.value }, | |
161 | + { | |
162 | + ids: idss, | |
163 | + orderIds: orderIds.value, | |
164 | + queryVO: queryVO.value, | |
165 | + }, | |
145 | 166 | { |
146 | 167 | responseType: 'blob', // 设置响应类型为 'blob' |
147 | 168 | }, | ... | ... |
src/views/project/finance/financeList/finance.data.tsx
... | ... | @@ -51,8 +51,8 @@ export const searchFormSchema: FormSchema[] = [ |
51 | 51 | componentProps: { |
52 | 52 | options: [ |
53 | 53 | { label: '未创建', value: -1 }, |
54 | - { label: '未收款', value: 0 }, | |
55 | - { label: '已收款', value: 10 }, | |
54 | + { label: '未付款', value: 0 }, | |
55 | + { label: '已付款', value: 10 }, | |
56 | 56 | ], |
57 | 57 | }, |
58 | 58 | }, |
... | ... | @@ -484,9 +484,9 @@ export const columns: BasicColumn[] = [ |
484 | 484 | if (column.record.checkPayStatus == null || column.record.checkPayStatus == undefined) { |
485 | 485 | return '未创建'; |
486 | 486 | } else if (column.record.checkPayStatus == 0) { |
487 | - return '未收款'; | |
487 | + return '未付款'; | |
488 | 488 | } else if (column.record.checkPayStatus == 10) { |
489 | - return '已收款'; | |
489 | + return '已付款'; | |
490 | 490 | } |
491 | 491 | }, |
492 | 492 | }, | ... | ... |
src/views/project/finance/financeList/index.vue
... | ... | @@ -167,10 +167,13 @@ |
167 | 167 | role == ROLE.BUSINESS |
168 | 168 | " |
169 | 169 | :actions="[ |
170 | - ...(role == ROLE.ADMIN || role == ROLE.FINANCE | |
170 | + ...(role == ROLE.ADMIN || | |
171 | + role == ROLE.FINANCE || | |
172 | + role == ROLE.TRACKER || | |
173 | + role == ROLE.BUSINESS | |
171 | 174 | ? [ |
172 | 175 | { |
173 | - label: '财务编辑', | |
176 | + label: '付款编辑', | |
174 | 177 | onClick: handleFinanceEditCheck.bind(null, record), |
175 | 178 | }, |
176 | 179 | ] |
... | ... | @@ -247,7 +250,7 @@ |
247 | 250 | </div> |
248 | 251 | </template> |
249 | 252 | <script lang="ts" setup> |
250 | - import { computed, defineComponent, onMounted, ref } from 'vue'; | |
253 | + import { computed, defineComponent, onMounted, ref, watchEffect } from 'vue'; | |
251 | 254 | import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table'; |
252 | 255 | // import { searchFormSchema, columns } from './receive.data'; |
253 | 256 | import { searchFormSchema, columns } from './finance.data'; |
... | ... | @@ -483,10 +486,6 @@ |
483 | 486 | const { createMessage } = useMessage(); |
484 | 487 | const { error } = createMessage; |
485 | 488 | function handleInvoiceAnalysis(record) { |
486 | - if (invoiceIdKeys.value.length == 0) { | |
487 | - error('请选择订单'); | |
488 | - return; | |
489 | - } | |
490 | 489 | openInvoiceAnalysis(true, { |
491 | 490 | data: invoiceIdKeys.value, |
492 | 491 | id: checkedKeys.value, |
... | ... | @@ -545,10 +544,6 @@ |
545 | 544 | }); |
546 | 545 | } |
547 | 546 | function handleCheckSumCheck(record) { |
548 | - if (checkIdKeys.value.length == 0) { | |
549 | - error('请选择订单'); | |
550 | - return; | |
551 | - } | |
552 | 547 | openCheckSumCheck(true, { |
553 | 548 | data: checkIdKeys.value, |
554 | 549 | id: checkedKeys.value, | ... | ... |
src/views/project/finance/financeProfit/ProductProfit/InnerData/CheckDetail.vue
0 → 100644
1 | +<template> | |
2 | + <div class="container"> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + showFooter | |
7 | + title="字段编辑权限申请" | |
8 | + width="60%" | |
9 | + :destroyOnClose="true" | |
10 | + :isDetail="true" | |
11 | + @ok="handleSubmit" | |
12 | + :showDetailBack="false" | |
13 | + okText="申请" | |
14 | + ><input /> | |
15 | + <div> | |
16 | + <template v-if="role === ROLE.ADMIN || role === ROLE.TRACKER"> | |
17 | + <h3>基本信息</h3> | |
18 | + <BasicForm @register="registerForm" /> | |
19 | + </template> | |
20 | + </div> | |
21 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | |
22 | + | |
23 | + <!-- <template #appendFooter> | |
24 | + <a-button type="primary" @click="onGoFormDetail"> 返回编辑</a-button> | |
25 | + </template> --> | |
26 | + </BasicDrawer> | |
27 | + </div> | |
28 | +</template> | |
29 | +<script lang="ts"> | |
30 | + import { computed, defineComponent, reactive, ref } from 'vue'; | |
31 | + import { BasicForm, useForm } from '/@/components/Form/index'; | |
32 | + import { orderAuth } from '/@/api/project/order'; | |
33 | + import { ROLE } from '../../../financeList/type.d'; | |
34 | + import { useModal } from '/@/components/Modal'; | |
35 | + | |
36 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | |
37 | + import { FIELDS_BASE_INFO } from './tableData'; | |
38 | + import { useUserStoreWithOut } from '/@/store/modules/user'; | |
39 | + | |
40 | + const userStore = useUserStoreWithOut(); | |
41 | + const getSchema = (fields) => | |
42 | + fields | |
43 | + .map((item) => ({ | |
44 | + field: `${item.field}`, | |
45 | + dataIndex: `${item.field}`, | |
46 | + label: item.label, | |
47 | + component: 'Switch', | |
48 | + componentProps: { | |
49 | + checkedValue: 'UN_LOCKED', | |
50 | + unCheckedValue: 'LOCKED', | |
51 | + }, | |
52 | + colProps: { | |
53 | + span: 6, | |
54 | + }, | |
55 | + })) | |
56 | + .filter( | |
57 | + (item) => | |
58 | + // item.field !== 'packetPrice' && | |
59 | + item.field !== 'exchangeRate' && item.field !== 'profitRate', | |
60 | + ); | |
61 | + | |
62 | + export default defineComponent({ | |
63 | + components: { BasicDrawer, BasicForm }, | |
64 | + props: { | |
65 | + onGoFormDetail: { | |
66 | + type: Function, | |
67 | + }, | |
68 | + }, | |
69 | + setup() { | |
70 | + const id = ref(''); | |
71 | + const schemas = getSchema(FIELDS_BASE_INFO); | |
72 | + const [registerForm, { getFieldsValue }] = useForm({ | |
73 | + labelWidth: 120, | |
74 | + schemas, | |
75 | + showActionButtonGroup: false, | |
76 | + actionColOptions: { | |
77 | + span: 24, | |
78 | + }, | |
79 | + }); | |
80 | + const lockFields = reactive({}); | |
81 | + const [register, { closeDrawer }] = useDrawerInner((data) => { | |
82 | + Object.assign(lockFields, data.lockFields); | |
83 | + id.value = data.id; | |
84 | + }); | |
85 | + function handleCloseModal() { | |
86 | + closeDrawer(); | |
87 | + } | |
88 | + | |
89 | + const role = computed(() => { | |
90 | + return userStore.getUserInfo?.roleSmallVO?.code; | |
91 | + }); | |
92 | + | |
93 | + const handleSubmit = async () => { | |
94 | + const baseFieldValues = getFieldsValue(); | |
95 | + | |
96 | + if (baseFieldValues) { | |
97 | + FIELDS_BASE_INFO.map( | |
98 | + ({ field }) => | |
99 | + (baseFieldValues[field] = | |
100 | + baseFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), | |
101 | + ); | |
102 | + } | |
103 | + const values = Object.assign({ orderId: id.value }, { baseFields: baseFieldValues }); | |
104 | + | |
105 | + if ( | |
106 | + values.baseFields && | |
107 | + (values.baseFields.projectNo === 'UN_LOCKED' || | |
108 | + values.baseFields.productionDepartment === 'UN_LOCKED' || | |
109 | + values.baseFields.innerNo === 'UN_LOCKED' || | |
110 | + values.baseFields.customerCode === 'UN_LOCKED' || | |
111 | + values.baseFields.customerPo === 'UN_LOCKED' || | |
112 | + values.baseFields.customerStyle === 'UN_LOCKED') | |
113 | + ) { | |
114 | + openReasonModal(true, { | |
115 | + data: values, | |
116 | + }); | |
117 | + } else { | |
118 | + await orderAuth(values); | |
119 | + closeDrawer(); | |
120 | + } | |
121 | + }; | |
122 | + | |
123 | + return { | |
124 | + register, | |
125 | + schemas, | |
126 | + registerForm, | |
127 | + handleSubmit, | |
128 | + handleCloseModal, | |
129 | + ROLE, | |
130 | + role, | |
131 | + }; | |
132 | + }, | |
133 | + }); | |
134 | +</script> | |
135 | +<style> | |
136 | + .container { | |
137 | + position: fixed; /* 或 absolute, fixed */ | |
138 | + z-index: 10; | |
139 | + } | |
140 | +</style> | ... | ... |
src/views/project/finance/financeProfit/ProductProfit/InnerData/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">生产科预算金额</div> | |
19 | + <a-input | |
20 | + v-model:value="input1" | |
21 | + placeholder="请输入" | |
22 | + :disabled="status1 === 'LOCKED'" | |
23 | + auto-size | |
24 | + /> | |
25 | + <div style="margin: 16px 0"></div> | |
26 | + <div style="font-size: 15px">实际发生费用</div> | |
27 | + <a-input | |
28 | + v-model:value="input2" | |
29 | + placeholder="请输入" | |
30 | + :disabled="status2 === 'LOCKED'" | |
31 | + auto-size | |
32 | + /> | |
33 | + <div style="margin: 16px 0"></div> | |
34 | + | |
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 { BasicForm, FormSchema, useForm } from '@/components/Form'; | |
45 | + import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue'; | |
46 | + import { getPackageEdit } from '@/api/project/invoice'; | |
47 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
48 | + import { ROLE } from './type.d'; | |
49 | + | |
50 | + const emit = defineEmits(['success']); | |
51 | + const role = computed(() => { | |
52 | + return user?.roleSmallVO?.code; | |
53 | + }); | |
54 | + const schemas: FormSchema[] = [ | |
55 | + // { | |
56 | + // field: 'totalPayAmount', | |
57 | + // component: 'InputNumber', | |
58 | + // labelWidth: 250, | |
59 | + // colProps: { | |
60 | + // span: 23, | |
61 | + // }, | |
62 | + // label: '实际应收金额', | |
63 | + // }, | |
64 | + { | |
65 | + field: 'actualPayedAmount1', | |
66 | + component: 'InputNumber', | |
67 | + labelWidth: 250, | |
68 | + colProps: { | |
69 | + span: 23, | |
70 | + }, | |
71 | + componentProps: () => ({ | |
72 | + disabled: status.value === 10, | |
73 | + }), | |
74 | + label: '实际应收金额1$', | |
75 | + }, | |
76 | + { | |
77 | + field: 'actualPayedAmount2', | |
78 | + component: 'InputNumber', | |
79 | + labelWidth: 250, | |
80 | + colProps: { | |
81 | + span: 23, | |
82 | + }, | |
83 | + componentProps: () => ({ | |
84 | + disabled: status.value === 10, | |
85 | + }), | |
86 | + label: '实际应收金额2$', | |
87 | + }, | |
88 | + { | |
89 | + field: 'actualPayedAmount3', | |
90 | + component: 'InputNumber', | |
91 | + labelWidth: 250, | |
92 | + colProps: { | |
93 | + span: 23, | |
94 | + }, | |
95 | + componentProps: () => ({ | |
96 | + disabled: status.value === 10, | |
97 | + }), | |
98 | + label: '实际应收金额3$', | |
99 | + }, | |
100 | + { | |
101 | + field: 'otherAmount', | |
102 | + component: 'InputNumber', | |
103 | + labelWidth: 250, | |
104 | + colProps: { | |
105 | + span: 23, | |
106 | + }, | |
107 | + componentProps: () => ({ | |
108 | + disabled: status.value === 10, | |
109 | + }), | |
110 | + label: '其他费用金额$', | |
111 | + }, | |
112 | + ]; | |
113 | + const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ | |
114 | + labelWidth: 120, | |
115 | + schemas, | |
116 | + layout: 'vertical', | |
117 | + showActionButtonGroup: false, | |
118 | + actionColOptions: { | |
119 | + span: 24, | |
120 | + }, | |
121 | + }); | |
122 | + const { createMessage } = useMessage(); | |
123 | + const { error } = createMessage; | |
124 | + | |
125 | + const update = ref(); | |
126 | + const status1 = ref(); | |
127 | + const status2 = ref(); | |
128 | + | |
129 | + const input1 = ref(); | |
130 | + const input2 = ref(); | |
131 | + const id = ref(); | |
132 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
133 | + // 方式1 | |
134 | + if (data.data.lockFields) { | |
135 | + status1.value = data.data?.productionDepartmentPredictPrice; | |
136 | + status2.value = data.data?.productionActualPrice; | |
137 | + } | |
138 | + | |
139 | + id.value = data.data.orderId; | |
140 | + input1.value = data.data?.productionDepartmentPredictPrice.toFixed(2); | |
141 | + input2.value = data.data?.productionActualPrice.toFixed(2); | |
142 | + resetFields(); | |
143 | + setDrawerProps({ confirmLoading: false }); | |
144 | + setFieldsValue({ | |
145 | + ...toRaw(data.data), | |
146 | + }); | |
147 | + update.value = data; | |
148 | + }); | |
149 | + //完成编辑 | |
150 | + async function handleSubmit() { | |
151 | + // const values = await validate(); | |
152 | + // const updatedValues = { | |
153 | + // ...values, | |
154 | + // id: update.value.data.id, | |
155 | + // bgUrl: update.value.data.bgUrl, | |
156 | + // }; | |
157 | + if (!input1.value || !input2.value) { | |
158 | + error('选项不能为空'); | |
159 | + } else { | |
160 | + await getPackageEdit({ | |
161 | + orderId: id.value, | |
162 | + productionDepartmentPredictPrice: input1.value, | |
163 | + productionActualPrice: input2.value, | |
164 | + }); | |
165 | + emit('success'); | |
166 | + closeDrawer(); | |
167 | + } | |
168 | + } | |
169 | +</script> | ... | ... |
src/views/project/finance/financeProfit/ProductProfit/InnerData/data.tsx
0 → 100644
1 | +import { InputNumber, Tag } from 'ant-design-vue'; | |
2 | +import { BasicColumn } from '@/components/Table'; | |
3 | +import { func } from 'vue-types'; | |
4 | +import { h, ref } from 'vue'; | |
5 | +import { FilePptOutlined } from '@ant-design/icons-vue'; | |
6 | + | |
7 | +// export const COLUMNS = [ | |
8 | +// { | |
9 | +// title: '客户编码', | |
10 | +// dataIndex: 'settingValue', | |
11 | +// width: 150, | |
12 | +// }, | |
13 | +// { | |
14 | +// title: '利润率', | |
15 | +// dataIndex: 'relationValue', | |
16 | +// width: 150, | |
17 | +// editComponent: 'InputNumber', | |
18 | +// editRow: true, | |
19 | +// scopedSlots: { customRender: 'name' } | |
20 | +// }, | |
21 | +// ]; | |
22 | +export const COLUMNS = [ | |
23 | + { | |
24 | + title: '客户编码', | |
25 | + dataIndex: 'customerCode', | |
26 | + width: 150, | |
27 | + }, | |
28 | + { | |
29 | + title: '项目号', | |
30 | + dataIndex: 'projectNo', | |
31 | + width: 100, | |
32 | + }, | |
33 | + { | |
34 | + title: '生产科', | |
35 | + dataIndex: 'productionDepartment', | |
36 | + width: 100, | |
37 | + }, | |
38 | + { | |
39 | + title: '内部编号', | |
40 | + dataIndex: 'innerNo', | |
41 | + width: 100, | |
42 | + }, | |
43 | + { | |
44 | + title: '订单图片', | |
45 | + dataIndex: 'picUrl', | |
46 | + width: 100, | |
47 | + }, | |
48 | + { | |
49 | + title: '数量', | |
50 | + dataIndex: 'orderCount', | |
51 | + width: 100, | |
52 | + }, | |
53 | + { | |
54 | + title: '生产科总价¥', | |
55 | + width: 150, | |
56 | + dataIndex: 'productionDepartmentTotalPrice', | |
57 | + customRender: (column) => { | |
58 | + console.log(column, '5656csd'); | |
59 | + return column.record?.productionDepartmentTotalPrice?.toFixed(2); | |
60 | + }, | |
61 | + }, | |
62 | + { | |
63 | + title: '生产科预算金额¥', | |
64 | + width: 150, | |
65 | + dataIndex: 'productionDepartmentPredictPrice', | |
66 | + customRender: (column) => { | |
67 | + return column.record?.productionDepartmentPredictPrice?.toFixed(2); | |
68 | + }, | |
69 | + }, | |
70 | + { | |
71 | + title: '实际发生费用¥', | |
72 | + dataIndex: 'productionActualPrice', | |
73 | + width: 120, | |
74 | + customRender: (column) => { | |
75 | + return column.record?.productionActualPrice?.toFixed(2); | |
76 | + }, | |
77 | + }, | |
78 | + { | |
79 | + title: '预算占比', | |
80 | + dataIndex: 'predictRatio', | |
81 | + width: 120, | |
82 | + customRender: (column) => { | |
83 | + return column.record?.predictRatio?.toFixed(2); | |
84 | + }, | |
85 | + }, | |
86 | + { | |
87 | + title: '预算占比差', | |
88 | + dataIndex: 'predictAndActualRatio', | |
89 | + width: 120, | |
90 | + customRender: (column) => { | |
91 | + return column.record?.predictAndActualRatio?.toFixed(2); | |
92 | + }, | |
93 | + }, | |
94 | + { | |
95 | + title: '事前毛利润', | |
96 | + dataIndex: 'beforeGrossProfit', | |
97 | + width: 120, | |
98 | + customRender: (column) => { | |
99 | + return column.record?.beforeGrossProfit?.toFixed(2); | |
100 | + }, | |
101 | + }, | |
102 | + { | |
103 | + title: '事前毛利率', | |
104 | + dataIndex: 'beforeGrossProfitRate', | |
105 | + width: 120, | |
106 | + customRender: (column) => { | |
107 | + return column.record?.beforeGrossProfitRate?.toFixed(2); | |
108 | + }, | |
109 | + }, | |
110 | + { | |
111 | + title: '事后毛利润', | |
112 | + dataIndex: 'grossProfit', | |
113 | + width: 120, | |
114 | + customRender: (column) => { | |
115 | + return column.record?.grossProfit?.toFixed(2); | |
116 | + }, | |
117 | + }, | |
118 | + { | |
119 | + title: '事后毛利率', | |
120 | + dataIndex: 'grossProfitRate', | |
121 | + width: 120, | |
122 | + customRender: (column) => { | |
123 | + return column.record?.grossProfitRate?.toFixed(2); | |
124 | + }, | |
125 | + }, | |
126 | + { | |
127 | + title: '内部生产固定成本¥', | |
128 | + dataIndex: 'innerProductionFixedCost', | |
129 | + width: 120, | |
130 | + customRender: (column) => { | |
131 | + return column.record?.innerProductionFixedCost?.toFixed(2); | |
132 | + }, | |
133 | + }, | |
134 | + { | |
135 | + title: '内部生产提成¥', | |
136 | + dataIndex: 'innerProductionCommission', | |
137 | + width: 120, | |
138 | + customRender: (column) => { | |
139 | + return column.record?.innerProductionCommission?.toFixed(2); | |
140 | + }, | |
141 | + }, | |
142 | + { | |
143 | + title: '内部生产净利润¥', | |
144 | + dataIndex: 'innerProductionProfit', | |
145 | + width: 120, | |
146 | + customRender: (column) => { | |
147 | + return column.record?.innerProductionProfit?.toFixed(2); | |
148 | + }, | |
149 | + }, | |
150 | + { | |
151 | + title: '内部生产净利润率', | |
152 | + dataIndex: 'innerProductionProfitRate', | |
153 | + width: 120, | |
154 | + customRender: (column) => { | |
155 | + return column.record?.innerProductionProfitRate?.toFixed(2); | |
156 | + }, | |
157 | + }, | |
158 | +]; | |
0 | 159 | \ No newline at end of file | ... | ... |
src/views/project/finance/financeProfit/ProductProfit/InnerData/index.vue
0 → 100644
1 | +<template> | |
2 | + <div> | |
3 | + <BasicTable @register="registerTable" :bordered="true"> | |
4 | + <template #bodyCell="{ column, record }"> | |
5 | + <template v-if="column.key === 'picUrl'"> | |
6 | + <img :z-index="100000" :width="50" :height="50" :src="record?.picUrl" /> | |
7 | + </template> | |
8 | + <template v-if="column.key === 'action'"> | |
9 | + <TableAction :actions="createActions(record)" /> | |
10 | + </template> | |
11 | + <!-- <template v-if="column.key === 'relationValue'"> | |
12 | + <a-input | |
13 | + v-if="record.settingValue === 'A01'" | |
14 | + v-model:value="record.settingValue" | |
15 | + :max-length="50" | |
16 | + /> | |
17 | + <span v-else style="color: red"> | |
18 | + {{ record.settingValue }} | |
19 | + </span> | |
20 | + </template> --> | |
21 | + </template> | |
22 | + </BasicTable> | |
23 | + <!-- <BasicModal | |
24 | + title="拒绝原因" | |
25 | + width="30%" | |
26 | + @register="registerModal" | |
27 | + @visible-change="handleClose" | |
28 | + @ok="handleOk" | |
29 | + wrapClassName="approve-modal" | |
30 | + > | |
31 | + <div className="pa-8"> | |
32 | + <a-textarea :rows="6" placeholder="请输入拒绝原因" v-model:value="message" /> | |
33 | + </div> | |
34 | + </BasicModal> --> | |
35 | + <CheckDetail @register="checkModalRegister" /> | |
36 | + <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | |
37 | + </div> | |
38 | +</template> | |
39 | +<script setup lang="ts"> | |
40 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | |
41 | + import { getInnerProfit } from '@/api/project/invoice'; | |
42 | + import { COLUMNS } from './data'; | |
43 | + import { BasicModal, useModal } from '/@/components/Modal'; | |
44 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
45 | + import { ref } from 'vue'; | |
46 | + import { useDrawer } from '/@/components/Drawer'; | |
47 | + import FinanceEdit from './FinanceEdit.vue'; | |
48 | + import CheckDetail from './CheckDetail.vue'; | |
49 | + | |
50 | + const { createMessage } = useMessage(); | |
51 | + const { error } = createMessage; | |
52 | + const message = ref(); | |
53 | + const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); | |
54 | + const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); | |
55 | + const handleOk = (record) => { | |
56 | + // 修改父组件的状态 | |
57 | + console.log(message.value, '5656messsage', record); | |
58 | + closeModal(); | |
59 | + }; | |
60 | + const handleClose = (visible: boolean) => { | |
61 | + if (!visible) { | |
62 | + message.value = ''; | |
63 | + } | |
64 | + }; | |
65 | + const [registerTable, { reload }] = useTable({ | |
66 | + api: getInnerProfit, | |
67 | + bordered: true, | |
68 | + columns: COLUMNS, | |
69 | + rowKey: 'id', | |
70 | + useSearchForm: true, | |
71 | + actionColumn: { | |
72 | + width: 240, | |
73 | + title: 'Action', | |
74 | + dataIndex: 'action', | |
75 | + }, | |
76 | + }); | |
77 | + function createActions(record: any): any[] { | |
78 | + if (!record.editable) { | |
79 | + return [ | |
80 | + { | |
81 | + label: '财务编辑', | |
82 | + onClick: handleFinanceEdit.bind(null, record), | |
83 | + }, | |
84 | + // { | |
85 | + // label: '编辑', | |
86 | + // onClick: handleEdit.bind(null, record), | |
87 | + // }, | |
88 | + // { | |
89 | + // label: '删除', | |
90 | + // popConfirm: { | |
91 | + // title: '确认删除?', | |
92 | + // confirm: handleDelete.bind(null, record), | |
93 | + // }, | |
94 | + // }, | |
95 | + { | |
96 | + label: '申请权限', | |
97 | + // popConfirm: { | |
98 | + // title: '确认申请?', | |
99 | + // confirm: handleFalse.bind(null, record), | |
100 | + // }, | |
101 | + onClick: handleFalse.bind(null, record), | |
102 | + }, | |
103 | + ]; | |
104 | + } | |
105 | + return [ | |
106 | + { | |
107 | + label: '保存', | |
108 | + onClick: handleSave.bind(null, record), | |
109 | + }, | |
110 | + { | |
111 | + label: '取消', | |
112 | + popConfirm: { | |
113 | + title: '是否取消编辑', | |
114 | + confirm: handleCancel.bind(null, record), | |
115 | + }, | |
116 | + }, | |
117 | + ]; | |
118 | + } | |
119 | + | |
120 | + function handleFinanceEdit(record) { | |
121 | + openFinanceEdit(true, { | |
122 | + data: record, | |
123 | + }); | |
124 | + } | |
125 | + | |
126 | + function handleFalse(record, e) { | |
127 | + openCheckDetailDrawer(true, record); | |
128 | + e?.stopPropagation(); | |
129 | + return false; | |
130 | + } | |
131 | + | |
132 | + // async function handleFalse(record: any) { | |
133 | + // console.log(record); | |
134 | + // // openModal(true, { record }); | |
135 | + // } | |
136 | + | |
137 | + async function handleSave(record) { | |
138 | + await saveConfig({ id: record.id, relationValue: record.relationValue }); | |
139 | + handleCancel(record); | |
140 | + reload(); | |
141 | + } | |
142 | + function handleEdit(record: any) { | |
143 | + console.log(record, '5656edit'); | |
144 | + // if (record.settingValue == 'A01') { | |
145 | + // error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
146 | + // } else { | |
147 | + record.onEdit?.(true); | |
148 | + // } | |
149 | + } | |
150 | + | |
151 | + function handleCancel(record) { | |
152 | + record.onEdit?.(false, false); | |
153 | + } | |
154 | + | |
155 | + async function handleDelete(record) { | |
156 | + await deleteConfig({ ids: [record.id] }); | |
157 | + reload(); | |
158 | + } | |
159 | + function handleSuccess() { | |
160 | + setTimeout(() => { | |
161 | + reload(); | |
162 | + }, 50); | |
163 | + } | |
164 | +</script> | |
165 | +<style></style> | ... | ... |
src/views/project/finance/financeProfit/ProductProfit/InnerData/tableData.tsx
0 → 100644
1 | +import { ref } from 'vue'; | |
2 | +import { ROLE } from '../../../financeList/type.d'; | |
3 | +import { queryNoOptions } from '/@/api/project/order'; | |
4 | +import { useOrderInfo } from '/@/hooks/component/order'; | |
5 | +import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
6 | +import { formatToDate } from '/@/utils/dateUtil'; | |
7 | + | |
8 | +// 角色 | |
9 | +// 业务员- 查看all,编辑-利润分析,报告书 | |
10 | +// 跟单员- 查看利润分析(单价和总金额),跟单,质检,编辑 | |
11 | +// 质检员- 查看跟单,质检,编辑质检 | |
12 | + | |
13 | +const innerNoOptions = ref([]); | |
14 | +const projectNoOptions = ref([]); | |
15 | +const orderStore = useOrderStoreWithOut(); | |
16 | +// const { productionDepartment: productionDepartmentOptions } = useOrderInfo(orderStore); | |
17 | + | |
18 | +/** | |
19 | + * drawer面板的字段 | |
20 | + */ | |
21 | +// 基本信息 | |
22 | +export const FIELDS_BASE_INFO = [ | |
23 | + { | |
24 | + field: 'customerCode', | |
25 | + component: 'Select', | |
26 | + labelWidth: 150, | |
27 | + label: '客户编码', | |
28 | + rules: [{ required: true }], | |
29 | + }, | |
30 | + { | |
31 | + field: 'projectNo', | |
32 | + component: 'Input', | |
33 | + labelWidth: 150, | |
34 | + label: '项目号', | |
35 | + rules: [{ required: true }], | |
36 | + }, | |
37 | + { | |
38 | + field: 'productionDepartment', | |
39 | + component: 'Select', | |
40 | + // componentProps: { | |
41 | + // options: productionDepartmentOptions, | |
42 | + // }, | |
43 | + labelWidth: 150, | |
44 | + label: '生产科', | |
45 | + rules: [{ required: true }], | |
46 | + }, | |
47 | + | |
48 | + { | |
49 | + field: 'innerNo', | |
50 | + component: 'Input', | |
51 | + labelWidth: 150, | |
52 | + label: '内部编号', | |
53 | + rules: [ | |
54 | + { required: true }, | |
55 | + { | |
56 | + validator: async (rule, value) => { | |
57 | + if (value.includes(' ')) { | |
58 | + return Promise.reject(); | |
59 | + } | |
60 | + return Promise.resolve(); | |
61 | + }, | |
62 | + message: '内容存在空格,请检查', | |
63 | + trigger: ['change', 'blur'], | |
64 | + }, | |
65 | + ], | |
66 | + }, | |
67 | + { | |
68 | + field: 'customerPo', | |
69 | + component: 'Input', | |
70 | + labelWidth: 150, | |
71 | + label: '客户po号', | |
72 | + rules: [{ required: true }], | |
73 | + }, | |
74 | + { | |
75 | + field: 'customerStyle', | |
76 | + component: 'Input', | |
77 | + labelWidth: 150, | |
78 | + label: '客户STYLE', | |
79 | + rules: [ | |
80 | + { required: true }, | |
81 | + { | |
82 | + validator: async (rule, value) => { | |
83 | + if (value.includes(' ')) { | |
84 | + return Promise.reject(); | |
85 | + } | |
86 | + return Promise.resolve(); | |
87 | + }, | |
88 | + message: '内容存在空格,请检查', | |
89 | + trigger: ['change', 'blur'], | |
90 | + }, | |
91 | + ], | |
92 | + }, | |
93 | +]; | |
94 | + | ... | ... |
src/views/project/finance/financeProfit/ProductProfit/InnerProduce/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">项目开始时间</div> | |
25 | + <a-date-picker v-model:value="input3" :disabled="status === 10" auto-size /> | |
26 | + <div style="margin: 16px 0"></div> | |
27 | + <div style="font-size: 15px">项目结束时间</div> | |
28 | + <a-date-picker v-model:value="input4" :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/financeProfit/ProductProfit/InnerProduce/data.tsx
0 → 100644
1 | +import { InputNumber, Tag } from 'ant-design-vue'; | |
2 | +import { BasicColumn } from '@/components/Table'; | |
3 | +import { func } from 'vue-types'; | |
4 | +import { h, ref } from 'vue'; | |
5 | +import { FilePptOutlined } from '@ant-design/icons-vue'; | |
6 | +import axios from 'axios'; | |
7 | + | |
8 | +// export const COLUMNS = [ | |
9 | +// { | |
10 | +// title: '客户编码', | |
11 | +// dataIndex: 'settingValue', | |
12 | +// width: 150, | |
13 | +// }, | |
14 | +// { | |
15 | +// title: '利润率', | |
16 | +// dataIndex: 'relationValue', | |
17 | +// width: 150, | |
18 | +// editComponent: 'InputNumber', | |
19 | +// editRow: true, | |
20 | +// scopedSlots: { customRender: 'name' } | |
21 | +// }, | |
22 | +// ]; | |
23 | +export const COLUMNS = [ | |
24 | + { | |
25 | + title: '客户编码', | |
26 | + dataIndex: 'customerCode', | |
27 | + width: 150, | |
28 | + }, | |
29 | + { | |
30 | + title: '项目号', | |
31 | + dataIndex: 'projectNoPrefix', | |
32 | + width: 100, | |
33 | + }, | |
34 | + { | |
35 | + title: '生产科', | |
36 | + dataIndex: 'productionDepartment', | |
37 | + width: 100, | |
38 | + }, | |
39 | + { | |
40 | + title: '数量', | |
41 | + dataIndex: 'orderCount', | |
42 | + width: 100, | |
43 | + }, | |
44 | + { | |
45 | + title: '生产科单价¥', | |
46 | + dataIndex: 'productionDepartmentPrice', | |
47 | + width: 120, | |
48 | + customRender: (column) => { | |
49 | + console.log(column, '5656column'); | |
50 | + return column.record?.productionDepartmentPrice?.toFixed(2); | |
51 | + }, | |
52 | + }, | |
53 | + { | |
54 | + title: '生产科总价¥', | |
55 | + dataIndex: 'productionDepartmentTotalPrice', | |
56 | + width: 120, | |
57 | + customRender: (column) => { | |
58 | + console.log(column, '5656column'); | |
59 | + return column.record?.productionDepartmentTotalPrice?.toFixed(2); | |
60 | + }, | |
61 | + }, | |
62 | + { | |
63 | + title: '生产科预算金额', | |
64 | + dataIndex: 'productionDepartmentPredictPrice', | |
65 | + width: 120, | |
66 | + customRender: (column) => { | |
67 | + return column.record?.productionDepartmentPredictPrice?.toFixed(2); | |
68 | + }, | |
69 | + }, | |
70 | + { | |
71 | + title: '实际发生费用', | |
72 | + dataIndex: 'productionActualPrice', | |
73 | + width: 120, | |
74 | + customRender: (column) => { | |
75 | + return column.record?.productionActualPrice?.toFixed(2); | |
76 | + }, | |
77 | + }, | |
78 | + { | |
79 | + title: '预算占比', | |
80 | + dataIndex: 'predictRatio', | |
81 | + width: 120, | |
82 | + customRender: (column) => { | |
83 | + return column.record?.predictRatio?.toFixed(2); | |
84 | + }, | |
85 | + }, | |
86 | + { | |
87 | + title: '预算占比与实际占比差', | |
88 | + dataIndex: 'predictAndActualRatio', | |
89 | + width: 150, | |
90 | + customRender: (column) => { | |
91 | + return column.record?.predictAndActualRatio?.toFixed(2); | |
92 | + }, | |
93 | + }, | |
94 | + { | |
95 | + title: '事前毛利润', | |
96 | + dataIndex: 'beforeGrossProfit', | |
97 | + width: 120, | |
98 | + customRender: (column) => { | |
99 | + return column.record?.beforeGrossProfit?.toFixed(2); | |
100 | + }, | |
101 | + }, | |
102 | + { | |
103 | + title: '事前毛利率', | |
104 | + dataIndex: 'beforeGrossProfitRate', | |
105 | + width: 120, | |
106 | + customRender: (column) => { | |
107 | + return column.record?.beforeGrossProfitRate?.toFixed(2); | |
108 | + }, | |
109 | + }, | |
110 | + { | |
111 | + title: '事后毛利润', | |
112 | + dataIndex: 'grossProfit', | |
113 | + width: 120, | |
114 | + customRender: (column) => { | |
115 | + return column.record?.grossProfit?.toFixed(2); | |
116 | + }, | |
117 | + }, | |
118 | + { | |
119 | + title: '事后毛利率', | |
120 | + dataIndex: 'grossProfitRate', | |
121 | + width: 120, | |
122 | + customRender: (column) => { | |
123 | + return column.record?.grossProfitRate?.toFixed(2); | |
124 | + }, | |
125 | + }, | |
126 | + { | |
127 | + title: '文件', | |
128 | + dataIndex: 'fileUrl', | |
129 | + width: 120, | |
130 | + customRender: (column) => { | |
131 | + // 构造符合 API 要求的参数 | |
132 | + // await exportAnalysis({ ids: ids }); | |
133 | + const handleClick = () => { | |
134 | + axios | |
135 | + .post( | |
136 | + '/basic-api/project/innerProfit/export', | |
137 | + { | |
138 | + projectNoPrefix: column.record.projectNoPrefix, | |
139 | + }, | |
140 | + { | |
141 | + responseType: 'blob', // 设置响应类型为 'blob' | |
142 | + }, | |
143 | + ) | |
144 | + .then((response) => { | |
145 | + // 创建一个 Blob 对象来保存二进制数据 | |
146 | + const blob = new Blob([response.data], { type: 'application/zip' }); | |
147 | + const getFormattedDate = (): string => { | |
148 | + const date = new Date(); | |
149 | + | |
150 | + const year = date.getFullYear(); | |
151 | + const month = String(date.getMonth() + 1).padStart(2, '0'); | |
152 | + const day = String(date.getDate()).padStart(2, '0'); | |
153 | + | |
154 | + const hours = String(date.getHours()).padStart(2, '0'); | |
155 | + const minutes = String(date.getMinutes()).padStart(2, '0'); | |
156 | + const seconds = String(date.getSeconds()).padStart(2, '0'); | |
157 | + | |
158 | + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | |
159 | + }; | |
160 | + const date = getFormattedDate(); | |
161 | + // 创建一个链接元素用于下载 | |
162 | + const link = document.createElement('a'); | |
163 | + link.href = window.URL.createObjectURL(blob); | |
164 | + link.download = `${date}.xlsx`; // 你可以为文件命名 | |
165 | + document.body.appendChild(link); | |
166 | + link.click(); // 自动点击链接,触发下载 | |
167 | + document.body.removeChild(link); // 下载完成后移除链接 | |
168 | + }) | |
169 | + .catch((error) => { | |
170 | + console.error(error); | |
171 | + }); | |
172 | + }; | |
173 | + return <FilePptOutlined style="font-size:25px" onClick={() => handleClick()} />; | |
174 | + }, | |
175 | + }, | |
176 | +]; | |
0 | 177 | \ No newline at end of file | ... | ... |
src/views/project/finance/financeProfit/ProductProfit/InnerProduce/index.vue
0 → 100644
1 | +<template> | |
2 | + <div> | |
3 | + <BasicTable @register="registerTable" :bordered="true"> | |
4 | + <template #bodyCell="{ column, record }"> | |
5 | + <template v-if="column.key === 'picUrl'"> | |
6 | + <img :z-index="100000" :width="50" :height="50" :src="record?.picUrl" /> | |
7 | + </template> | |
8 | + <!-- <template v-if="column.key === 'action'"> | |
9 | + <TableAction :actions="createActions(record)" /> | |
10 | + </template> --> | |
11 | + <!-- <template v-if="column.key === 'relationValue'"> | |
12 | + <a-input | |
13 | + v-if="record.settingValue === 'A01'" | |
14 | + v-model:value="record.settingValue" | |
15 | + :max-length="50" | |
16 | + /> | |
17 | + <span v-else style="color: red"> | |
18 | + {{ record.settingValue }} | |
19 | + </span> | |
20 | + </template> --> | |
21 | + </template> | |
22 | + </BasicTable> | |
23 | + <!-- <BasicModal | |
24 | + title="拒绝原因" | |
25 | + width="30%" | |
26 | + @register="registerModal" | |
27 | + @visible-change="handleClose" | |
28 | + @ok="handleOk" | |
29 | + wrapClassName="approve-modal" | |
30 | + > | |
31 | + <div className="pa-8"> | |
32 | + <a-textarea :rows="6" placeholder="请输入拒绝原因" v-model:value="message" /> | |
33 | + </div> | |
34 | + </BasicModal> --> | |
35 | + <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | |
36 | + </div> | |
37 | +</template> | |
38 | +<script setup lang="ts"> | |
39 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | |
40 | + import { getInnerProduceProfit } from '@/api/project/invoice'; | |
41 | + import { COLUMNS } from './data'; | |
42 | + import { BasicModal, useModal } from '/@/components/Modal'; | |
43 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
44 | + import { ref } from 'vue'; | |
45 | + import { useDrawer } from '/@/components/Drawer'; | |
46 | + import FinanceEdit from './FinanceEdit.vue'; | |
47 | + | |
48 | + const { createMessage } = useMessage(); | |
49 | + const { error } = createMessage; | |
50 | + const message = ref(); | |
51 | + const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); | |
52 | + const handleOk = (record) => { | |
53 | + // 修改父组件的状态 | |
54 | + console.log(message.value, '5656messsage', record); | |
55 | + closeModal(); | |
56 | + }; | |
57 | + const handleClose = (visible: boolean) => { | |
58 | + if (!visible) { | |
59 | + message.value = ''; | |
60 | + } | |
61 | + }; | |
62 | + const [registerTable, { reload }] = useTable({ | |
63 | + api: getInnerProduceProfit, | |
64 | + bordered: true, | |
65 | + columns: COLUMNS, | |
66 | + rowKey: 'id', | |
67 | + useSearchForm: true, | |
68 | + // actionColumn: { | |
69 | + // width: 240, | |
70 | + // title: 'Action', | |
71 | + // dataIndex: 'action', | |
72 | + // }, | |
73 | + }); | |
74 | + | |
75 | + // function createActions(record: any): any[] { | |
76 | + // if (!record.editable) { | |
77 | + // return [ | |
78 | + // // { | |
79 | + // // label: '财务编辑', | |
80 | + // // onClick: handleFinanceEdit.bind(null, record), | |
81 | + // // }, | |
82 | + // // { | |
83 | + // // label: '编辑', | |
84 | + // // onClick: handleEdit.bind(null, record), | |
85 | + // // }, | |
86 | + // // { | |
87 | + // // label: '删除', | |
88 | + // // popConfirm: { | |
89 | + // // title: '确认删除?', | |
90 | + // // confirm: handleDelete.bind(null, record), | |
91 | + // // }, | |
92 | + // // }, | |
93 | + // // { | |
94 | + // // label: '申请权限', | |
95 | + // // // popConfirm: { | |
96 | + // // // title: '确认申请?', | |
97 | + // // // confirm: handleFalse.bind(null, record), | |
98 | + // // // }, | |
99 | + // // onClick: handleFalse.bind(null, record), | |
100 | + // // }, | |
101 | + // ]; | |
102 | + // } | |
103 | + // return [ | |
104 | + // { | |
105 | + // label: '保存', | |
106 | + // onClick: handleSave.bind(null, record), | |
107 | + // }, | |
108 | + // { | |
109 | + // label: '取消', | |
110 | + // popConfirm: { | |
111 | + // title: '是否取消编辑', | |
112 | + // confirm: handleCancel.bind(null, record), | |
113 | + // }, | |
114 | + // }, | |
115 | + // ]; | |
116 | + // } | |
117 | + | |
118 | + function handleFinanceEdit(record) { | |
119 | + openFinanceEdit(true, { | |
120 | + data: record, | |
121 | + }); | |
122 | + } | |
123 | + | |
124 | + // async function handleFalse(record: any) { | |
125 | + // console.log(record); | |
126 | + // // openModal(true, { record }); | |
127 | + // } | |
128 | + | |
129 | + async function handleSave(record) { | |
130 | + await saveConfig({ id: record.id, relationValue: record.relationValue }); | |
131 | + handleCancel(record); | |
132 | + reload(); | |
133 | + } | |
134 | + function handleEdit(record: any) { | |
135 | + console.log(record, '5656edit'); | |
136 | + // if (record.settingValue == 'A01') { | |
137 | + // error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
138 | + // } else { | |
139 | + record.onEdit?.(true); | |
140 | + // } | |
141 | + } | |
142 | + | |
143 | + function handleCancel(record) { | |
144 | + record.onEdit?.(false, false); | |
145 | + } | |
146 | + | |
147 | + async function handleDelete(record) { | |
148 | + await deleteConfig({ ids: [record.id] }); | |
149 | + reload(); | |
150 | + } | |
151 | +</script> | |
152 | +<style></style> | ... | ... |
src/views/project/finance/financeProfit/ProductProfit/InnerProduce/tableData.tsx
0 → 100644
1 | +import { ref } from 'vue'; | |
2 | +import { ROLE } from '../../../financeList/type.d'; | |
3 | +import { queryNoOptions } from '/@/api/project/order'; | |
4 | +import { useOrderInfo } from '/@/hooks/component/order'; | |
5 | +import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
6 | +import { formatToDate } from '/@/utils/dateUtil'; | |
7 | + | |
8 | +// 角色 | |
9 | +// 业务员- 查看all,编辑-利润分析,报告书 | |
10 | +// 跟单员- 查看利润分析(单价和总金额),跟单,质检,编辑 | |
11 | +// 质检员- 查看跟单,质检,编辑质检 | |
12 | + | |
13 | +const innerNoOptions = ref([]); | |
14 | +const projectNoOptions = ref([]); | |
15 | +const orderStore = useOrderStoreWithOut(); | |
16 | +// const { productionDepartment: productionDepartmentOptions } = useOrderInfo(orderStore); | |
17 | + | |
18 | +/** | |
19 | + * drawer面板的字段 | |
20 | + */ | |
21 | +// 基本信息 | |
22 | +export const FIELDS_BASE_INFO = [ | |
23 | + { | |
24 | + field: 'customerCode', | |
25 | + component: 'Select', | |
26 | + labelWidth: 150, | |
27 | + label: '客户编码', | |
28 | + rules: [{ required: true }], | |
29 | + }, | |
30 | + { | |
31 | + field: 'projectNo', | |
32 | + component: 'Input', | |
33 | + labelWidth: 150, | |
34 | + label: '项目号', | |
35 | + rules: [{ required: true }], | |
36 | + }, | |
37 | + { | |
38 | + field: 'productionDepartment', | |
39 | + component: 'Select', | |
40 | + // componentProps: { | |
41 | + // options: productionDepartmentOptions, | |
42 | + // }, | |
43 | + labelWidth: 150, | |
44 | + label: '生产科', | |
45 | + rules: [{ required: true }], | |
46 | + }, | |
47 | + | |
48 | + { | |
49 | + field: 'innerNo', | |
50 | + component: 'Input', | |
51 | + labelWidth: 150, | |
52 | + label: '内部编号', | |
53 | + rules: [ | |
54 | + { required: true }, | |
55 | + { | |
56 | + validator: async (rule, value) => { | |
57 | + if (value.includes(' ')) { | |
58 | + return Promise.reject(); | |
59 | + } | |
60 | + return Promise.resolve(); | |
61 | + }, | |
62 | + message: '内容存在空格,请检查', | |
63 | + trigger: ['change', 'blur'], | |
64 | + }, | |
65 | + ], | |
66 | + }, | |
67 | + { | |
68 | + field: 'customerPo', | |
69 | + component: 'Input', | |
70 | + labelWidth: 150, | |
71 | + label: '客户po号', | |
72 | + rules: [{ required: true }], | |
73 | + }, | |
74 | + { | |
75 | + field: 'customerStyle', | |
76 | + component: 'Input', | |
77 | + labelWidth: 150, | |
78 | + label: '客户STYLE', | |
79 | + rules: [ | |
80 | + { required: true }, | |
81 | + { | |
82 | + validator: async (rule, value) => { | |
83 | + if (value.includes(' ')) { | |
84 | + return Promise.reject(); | |
85 | + } | |
86 | + return Promise.resolve(); | |
87 | + }, | |
88 | + message: '内容存在空格,请检查', | |
89 | + trigger: ['change', 'blur'], | |
90 | + }, | |
91 | + ], | |
92 | + }, | |
93 | +]; | |
94 | + | ... | ... |
src/views/project/finance/financeProfit/ServiceProfit/PackageProfit/CheckDetail.vue
0 → 100644
1 | +<template> | |
2 | + <div class="container"> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + showFooter | |
7 | + title="字段编辑权限申请" | |
8 | + width="60%" | |
9 | + :destroyOnClose="true" | |
10 | + :isDetail="true" | |
11 | + @ok="handleSubmit" | |
12 | + :showDetailBack="false" | |
13 | + okText="申请" | |
14 | + ><input /> | |
15 | + <div> | |
16 | + <template v-if="role === ROLE.ADMIN || role === ROLE.TRACKER"> | |
17 | + <h3>基本信息</h3> | |
18 | + <BasicForm @register="registerForm" /> | |
19 | + </template> | |
20 | + </div> | |
21 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | |
22 | + | |
23 | + <!-- <template #appendFooter> | |
24 | + <a-button type="primary" @click="onGoFormDetail"> 返回编辑</a-button> | |
25 | + </template> --> | |
26 | + </BasicDrawer> | |
27 | + </div> | |
28 | +</template> | |
29 | +<script lang="ts"> | |
30 | + import { computed, defineComponent, reactive, ref } from 'vue'; | |
31 | + import { BasicForm, useForm } from '/@/components/Form/index'; | |
32 | + import { orderAuth } from '/@/api/project/order'; | |
33 | + import { ROLE } from '../../../financeList/type.d'; | |
34 | + import { useModal } from '/@/components/Modal'; | |
35 | + | |
36 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | |
37 | + import { FIELDS_BASE_INFO } from './tableData'; | |
38 | + import { useUserStoreWithOut } from '/@/store/modules/user'; | |
39 | + | |
40 | + const userStore = useUserStoreWithOut(); | |
41 | + const getSchema = (fields) => | |
42 | + fields | |
43 | + .map((item) => ({ | |
44 | + field: `${item.field}`, | |
45 | + dataIndex: `${item.field}`, | |
46 | + label: item.label, | |
47 | + component: 'Switch', | |
48 | + componentProps: { | |
49 | + checkedValue: 'UN_LOCKED', | |
50 | + unCheckedValue: 'LOCKED', | |
51 | + }, | |
52 | + colProps: { | |
53 | + span: 6, | |
54 | + }, | |
55 | + })) | |
56 | + .filter( | |
57 | + (item) => | |
58 | + // item.field !== 'packetPrice' && | |
59 | + item.field !== 'exchangeRate' && item.field !== 'profitRate', | |
60 | + ); | |
61 | + | |
62 | + export default defineComponent({ | |
63 | + components: { BasicDrawer, BasicForm }, | |
64 | + props: { | |
65 | + onGoFormDetail: { | |
66 | + type: Function, | |
67 | + }, | |
68 | + }, | |
69 | + setup() { | |
70 | + const id = ref(''); | |
71 | + const schemas = getSchema(FIELDS_BASE_INFO); | |
72 | + const [registerForm, { getFieldsValue }] = useForm({ | |
73 | + labelWidth: 120, | |
74 | + schemas, | |
75 | + showActionButtonGroup: false, | |
76 | + actionColOptions: { | |
77 | + span: 24, | |
78 | + }, | |
79 | + }); | |
80 | + const lockFields = reactive({}); | |
81 | + const [register, { closeDrawer }] = useDrawerInner((data) => { | |
82 | + Object.assign(lockFields, data.lockFields); | |
83 | + id.value = data.id; | |
84 | + }); | |
85 | + function handleCloseModal() { | |
86 | + closeDrawer(); | |
87 | + } | |
88 | + | |
89 | + const role = computed(() => { | |
90 | + return userStore.getUserInfo?.roleSmallVO?.code; | |
91 | + }); | |
92 | + | |
93 | + const handleSubmit = async () => { | |
94 | + const baseFieldValues = getFieldsValue(); | |
95 | + | |
96 | + if (baseFieldValues) { | |
97 | + FIELDS_BASE_INFO.map( | |
98 | + ({ field }) => | |
99 | + (baseFieldValues[field] = | |
100 | + baseFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), | |
101 | + ); | |
102 | + } | |
103 | + const values = Object.assign({ orderId: id.value }, { baseFields: baseFieldValues }); | |
104 | + | |
105 | + if ( | |
106 | + values.baseFields && | |
107 | + (values.baseFields.projectNo === 'UN_LOCKED' || | |
108 | + values.baseFields.productionDepartment === 'UN_LOCKED' || | |
109 | + values.baseFields.innerNo === 'UN_LOCKED' || | |
110 | + values.baseFields.customerCode === 'UN_LOCKED' || | |
111 | + values.baseFields.customerPo === 'UN_LOCKED' || | |
112 | + values.baseFields.customerStyle === 'UN_LOCKED') | |
113 | + ) { | |
114 | + openReasonModal(true, { | |
115 | + data: values, | |
116 | + }); | |
117 | + } else { | |
118 | + await orderAuth(values); | |
119 | + closeDrawer(); | |
120 | + } | |
121 | + }; | |
122 | + | |
123 | + return { | |
124 | + register, | |
125 | + schemas, | |
126 | + registerForm, | |
127 | + handleSubmit, | |
128 | + handleCloseModal, | |
129 | + ROLE, | |
130 | + role, | |
131 | + }; | |
132 | + }, | |
133 | + }); | |
134 | +</script> | |
135 | +<style> | |
136 | + .container { | |
137 | + position: fixed; /* 或 absolute, fixed */ | |
138 | + z-index: 10; | |
139 | + } | |
140 | +</style> | ... | ... |
src/views/project/finance/financeProfit/ServiceProfit/PackageProfit/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">包装费用实际金额¥</div> | |
19 | + <a-input | |
20 | + v-model:value="input1" | |
21 | + placeholder="请输入" | |
22 | + :disabled="status === 'LOCKED'" | |
23 | + auto-size | |
24 | + /> | |
25 | + <div style="margin: 16px 0"></div> | |
26 | + | |
27 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | |
28 | + <template #appendFooter> | |
29 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | |
30 | + </template> | |
31 | + </BasicDrawer> | |
32 | + </template> | |
33 | +</template> | |
34 | +<script lang="ts" setup> | |
35 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | |
36 | + import { BasicForm, FormSchema, useForm } from '@/components/Form'; | |
37 | + import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue'; | |
38 | + import { getPackageEdit } from '@/api/project/invoice'; | |
39 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
40 | + import { ROLE } from './type.d'; | |
41 | + | |
42 | + const emit = defineEmits(['success']); | |
43 | + const role = computed(() => { | |
44 | + return user?.roleSmallVO?.code; | |
45 | + }); | |
46 | + const schemas: FormSchema[] = [ | |
47 | + // { | |
48 | + // field: 'totalPayAmount', | |
49 | + // component: 'InputNumber', | |
50 | + // labelWidth: 250, | |
51 | + // colProps: { | |
52 | + // span: 23, | |
53 | + // }, | |
54 | + // label: '实际应收金额', | |
55 | + // }, | |
56 | + { | |
57 | + field: 'actualPayedAmount1', | |
58 | + component: 'InputNumber', | |
59 | + labelWidth: 250, | |
60 | + colProps: { | |
61 | + span: 23, | |
62 | + }, | |
63 | + componentProps: () => ({ | |
64 | + disabled: status.value === 10, | |
65 | + }), | |
66 | + label: '实际应收金额1$', | |
67 | + }, | |
68 | + { | |
69 | + field: 'actualPayedAmount2', | |
70 | + component: 'InputNumber', | |
71 | + labelWidth: 250, | |
72 | + colProps: { | |
73 | + span: 23, | |
74 | + }, | |
75 | + componentProps: () => ({ | |
76 | + disabled: status.value === 10, | |
77 | + }), | |
78 | + label: '实际应收金额2$', | |
79 | + }, | |
80 | + { | |
81 | + field: 'actualPayedAmount3', | |
82 | + component: 'InputNumber', | |
83 | + labelWidth: 250, | |
84 | + colProps: { | |
85 | + span: 23, | |
86 | + }, | |
87 | + componentProps: () => ({ | |
88 | + disabled: status.value === 10, | |
89 | + }), | |
90 | + label: '实际应收金额3$', | |
91 | + }, | |
92 | + { | |
93 | + field: 'otherAmount', | |
94 | + component: 'InputNumber', | |
95 | + labelWidth: 250, | |
96 | + colProps: { | |
97 | + span: 23, | |
98 | + }, | |
99 | + componentProps: () => ({ | |
100 | + disabled: status.value === 10, | |
101 | + }), | |
102 | + label: '其他费用金额$', | |
103 | + }, | |
104 | + ]; | |
105 | + const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ | |
106 | + labelWidth: 120, | |
107 | + schemas, | |
108 | + layout: 'vertical', | |
109 | + showActionButtonGroup: false, | |
110 | + actionColOptions: { | |
111 | + span: 24, | |
112 | + }, | |
113 | + }); | |
114 | + const { createMessage } = useMessage(); | |
115 | + const { error } = createMessage; | |
116 | + | |
117 | + const update = ref(); | |
118 | + const status = ref(); | |
119 | + | |
120 | + const input1 = ref(); | |
121 | + const id = ref(); | |
122 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
123 | + // 方式1 | |
124 | + if (data.data.lockFields) { | |
125 | + status.value = data.data.lockFields?.packetActualRmbPrice; | |
126 | + } | |
127 | + id.value = data.data.orderId; | |
128 | + input1.value = data.data?.packetActualRmbTotalPrice; | |
129 | + resetFields(); | |
130 | + setDrawerProps({ confirmLoading: false }); | |
131 | + setFieldsValue({ | |
132 | + ...toRaw(data.data), | |
133 | + }); | |
134 | + update.value = data; | |
135 | + }); | |
136 | + //完成编辑 | |
137 | + async function handleSubmit() { | |
138 | + // const values = await validate(); | |
139 | + // const updatedValues = { | |
140 | + // ...values, | |
141 | + // id: update.value.data.id, | |
142 | + // bgUrl: update.value.data.bgUrl, | |
143 | + // }; | |
144 | + if (!input1.value) { | |
145 | + error('选项不能为空'); | |
146 | + } else { | |
147 | + await getPackageEdit({ | |
148 | + orderId: id.value, | |
149 | + packetActualRmbTotalPrice: input1.value, | |
150 | + }); | |
151 | + emit('success'); | |
152 | + closeDrawer(); | |
153 | + } | |
154 | + } | |
155 | +</script> | ... | ... |
src/views/project/finance/financeProfit/ServiceProfit/PackageProfit/data.tsx
0 → 100644
1 | +import { InputNumber, Tag } from 'ant-design-vue'; | |
2 | +import { BasicColumn } from '@/components/Table'; | |
3 | +import { func } from 'vue-types'; | |
4 | +import { h, ref } from 'vue'; | |
5 | +import { FilePptOutlined } from '@ant-design/icons-vue'; | |
6 | + | |
7 | +// export const COLUMNS = [ | |
8 | +// { | |
9 | +// title: '客户编码', | |
10 | +// dataIndex: 'settingValue', | |
11 | +// width: 150, | |
12 | +// }, | |
13 | +// { | |
14 | +// title: '利润率', | |
15 | +// dataIndex: 'relationValue', | |
16 | +// width: 150, | |
17 | +// editComponent: 'InputNumber', | |
18 | +// editRow: true, | |
19 | +// scopedSlots: { customRender: 'name' } | |
20 | +// }, | |
21 | +// ]; | |
22 | +export const COLUMNS = [ | |
23 | + { | |
24 | + title: '客户编码', | |
25 | + dataIndex: 'customerCode', | |
26 | + width: 150, | |
27 | + }, | |
28 | + { | |
29 | + title: '项目号', | |
30 | + dataIndex: 'projectNo', | |
31 | + width: 100, | |
32 | + }, | |
33 | + { | |
34 | + title: '生产科', | |
35 | + dataIndex: 'productionDepartment', | |
36 | + width: 100, | |
37 | + }, | |
38 | + { | |
39 | + title: '内部编号', | |
40 | + dataIndex: 'innerNo', | |
41 | + width: 100, | |
42 | + }, | |
43 | + { | |
44 | + title: '订单图片', | |
45 | + dataIndex: 'picUrl', | |
46 | + width: 100, | |
47 | + }, | |
48 | + { | |
49 | + title: '数量', | |
50 | + dataIndex: 'orderCount', | |
51 | + width: 100, | |
52 | + }, | |
53 | + { | |
54 | + title: '包装费用$', | |
55 | + dataIndex: 'packetPrice', | |
56 | + width: 120, | |
57 | + customRender: (column) => { | |
58 | + console.log(column, '565665pa'); | |
59 | + return column.record?.packetPrice?.toFixed(2); | |
60 | + }, | |
61 | + }, | |
62 | + { | |
63 | + title: '包装费用合计¥', | |
64 | + dataIndex: 'packetRmbTotalPrice', | |
65 | + width: 120, | |
66 | + customRender: (column) => { | |
67 | + console.log(column, '565665pa'); | |
68 | + return column.record?.packetRmbTotalPrice?.toFixed(2); | |
69 | + }, | |
70 | + }, | |
71 | + { | |
72 | + title: '包装费用合计$', | |
73 | + dataIndex: 'packetTotalPrice', | |
74 | + width: 120, | |
75 | + customRender: (column) => { | |
76 | + console.log(column, '5656column'); | |
77 | + | |
78 | + return column.record?.packetTotalPrice?.toFixed(2); | |
79 | + }, | |
80 | + }, | |
81 | + { | |
82 | + title: '包装费用实际金额¥', | |
83 | + dataIndex: 'packetActualRmbTotalPrice', | |
84 | + width: 150, | |
85 | + customRender: (column) => { | |
86 | + return column.record?.packetActualRmbTotalPrice?.toFixed(2); | |
87 | + }, | |
88 | + }, | |
89 | + { | |
90 | + title: '实际跟单单价¥', | |
91 | + dataIndex: 'packetActualRmbPrice', | |
92 | + width: 120, | |
93 | + customRender: (column) => { | |
94 | + return column.record?.packetActualRmbPrice?.toFixed(2); | |
95 | + }, | |
96 | + }, | |
97 | + { | |
98 | + title: '实际跟单单价折算美金$', | |
99 | + dataIndex: 'packetActualPrice', | |
100 | + width: 170, | |
101 | + customRender: (column) => { | |
102 | + return column.record?.packetActualPrice?.toFixed(2); | |
103 | + }, | |
104 | + }, | |
105 | + { | |
106 | + title: '包装费用收益¥', | |
107 | + dataIndex: 'packetProfitRmbPrice', | |
108 | + width: 120, | |
109 | + customRender: (column) => { | |
110 | + return column.record?.packetProfitRmbPrice?.toFixed(2); | |
111 | + }, | |
112 | + }, | |
113 | + { | |
114 | + title: '包装费用净利润率', | |
115 | + dataIndex: 'packetProfitRate', | |
116 | + width: 140, | |
117 | + customRender: (column) => { | |
118 | + return column.record?.packetProfitRate?.toFixed(2); | |
119 | + }, | |
120 | + }, | |
121 | +]; | |
0 | 122 | \ No newline at end of file | ... | ... |
src/views/project/finance/financeProfit/ServiceProfit/PackageProfit/index.vue
0 → 100644
1 | +<template> | |
2 | + <div> | |
3 | + <BasicTable @register="registerTable" :bordered="true"> | |
4 | + <template #bodyCell="{ column, record }"> | |
5 | + <template v-if="column.key === 'picUrl'"> | |
6 | + <img :z-index="100000" :width="50" :height="50" :src="record?.picUrl" /> | |
7 | + </template> | |
8 | + <template v-if="column.key === 'action'"> | |
9 | + <TableAction :actions="createActions(record)" /> | |
10 | + </template> | |
11 | + <!-- <template v-if="column.key === 'relationValue'"> | |
12 | + <a-input | |
13 | + v-if="record.settingValue === 'A01'" | |
14 | + v-model:value="record.settingValue" | |
15 | + :max-length="50" | |
16 | + /> | |
17 | + <span v-else style="color: red"> | |
18 | + {{ record.settingValue }} | |
19 | + </span> | |
20 | + </template> --> | |
21 | + </template> | |
22 | + </BasicTable> | |
23 | + <!-- <BasicModal | |
24 | + title="拒绝原因" | |
25 | + width="30%" | |
26 | + @register="registerModal" | |
27 | + @visible-change="handleClose" | |
28 | + @ok="handleOk" | |
29 | + wrapClassName="approve-modal" | |
30 | + > | |
31 | + <div className="pa-8"> | |
32 | + <a-textarea :rows="6" placeholder="请输入拒绝原因" v-model:value="message" /> | |
33 | + </div> | |
34 | + </BasicModal> --> | |
35 | + <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> | |
36 | + <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | |
37 | + </div> | |
38 | +</template> | |
39 | +<script setup lang="ts"> | |
40 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | |
41 | + import { getPackageProfit } from '@/api/project/invoice'; | |
42 | + import { COLUMNS } from './data'; | |
43 | + import { BasicModal, useModal } from '/@/components/Modal'; | |
44 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
45 | + import { ref } from 'vue'; | |
46 | + import { useDrawer } from '/@/components/Drawer'; | |
47 | + import FinanceEdit from './FinanceEdit.vue'; | |
48 | + import CheckDetail from './CheckDetail.vue'; | |
49 | + | |
50 | + const { createMessage } = useMessage(); | |
51 | + const { error } = createMessage; | |
52 | + const message = ref(); | |
53 | + const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); | |
54 | + const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); | |
55 | + const handleOk = (record) => { | |
56 | + // 修改父组件的状态 | |
57 | + console.log(message.value, '5656messsage', record); | |
58 | + closeModal(); | |
59 | + }; | |
60 | + const handleClose = (visible: boolean) => { | |
61 | + if (!visible) { | |
62 | + message.value = ''; | |
63 | + } | |
64 | + }; | |
65 | + const [registerTable, { reload }] = useTable({ | |
66 | + api: getPackageProfit, | |
67 | + bordered: true, | |
68 | + columns: COLUMNS, | |
69 | + rowKey: 'id', | |
70 | + useSearchForm: true, | |
71 | + actionColumn: { | |
72 | + width: 240, | |
73 | + title: 'Action', | |
74 | + dataIndex: 'action', | |
75 | + }, | |
76 | + }); | |
77 | + | |
78 | + function createActions(record: any): any[] { | |
79 | + if (!record.editable) { | |
80 | + return [ | |
81 | + { | |
82 | + label: '财务编辑', | |
83 | + onClick: handleFinanceEdit.bind(null, record), | |
84 | + }, | |
85 | + // { | |
86 | + // label: '编辑', | |
87 | + // onClick: handleEdit.bind(null, record), | |
88 | + // }, | |
89 | + // { | |
90 | + // label: '删除', | |
91 | + // popConfirm: { | |
92 | + // title: '确认删除?', | |
93 | + // confirm: handleDelete.bind(null, record), | |
94 | + // }, | |
95 | + // }, | |
96 | + { | |
97 | + label: '申请权限', | |
98 | + // popConfirm: { | |
99 | + // title: '确认申请?', | |
100 | + // confirm: handleFalse.bind(null, record), | |
101 | + // }, | |
102 | + onClick: handleFalse.bind(null, record), | |
103 | + }, | |
104 | + ]; | |
105 | + } | |
106 | + return [ | |
107 | + { | |
108 | + label: '保存', | |
109 | + onClick: handleSave.bind(null, record), | |
110 | + }, | |
111 | + { | |
112 | + label: '取消', | |
113 | + popConfirm: { | |
114 | + title: '是否取消编辑', | |
115 | + confirm: handleCancel.bind(null, record), | |
116 | + }, | |
117 | + }, | |
118 | + ]; | |
119 | + } | |
120 | + | |
121 | + function handleFinanceEdit(record) { | |
122 | + openFinanceEdit(true, { | |
123 | + data: record, | |
124 | + }); | |
125 | + } | |
126 | + | |
127 | + function handleFalse(record, e) { | |
128 | + openCheckDetailDrawer(true, record); | |
129 | + e?.stopPropagation(); | |
130 | + return false; | |
131 | + } | |
132 | + function handleSuccess() { | |
133 | + setTimeout(() => { | |
134 | + reload(); | |
135 | + }, 50); | |
136 | + } | |
137 | + // async function handleFalse(record: any) { | |
138 | + // console.log(record); | |
139 | + // // openModal(true, { record }); | |
140 | + // } | |
141 | + | |
142 | + async function handleSave(record) { | |
143 | + await saveConfig({ id: record.id, relationValue: record.relationValue }); | |
144 | + handleCancel(record); | |
145 | + reload(); | |
146 | + } | |
147 | + function handleEdit(record: any) { | |
148 | + console.log(record, '5656edit'); | |
149 | + // if (record.settingValue == 'A01') { | |
150 | + // error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
151 | + // } else { | |
152 | + record.onEdit?.(true); | |
153 | + // } | |
154 | + } | |
155 | + | |
156 | + function handleCancel(record) { | |
157 | + record.onEdit?.(false, false); | |
158 | + } | |
159 | + | |
160 | + // async function handleDelete(record) { | |
161 | + // await deleteConfig({ ids: [record.id] }); | |
162 | + // reload(); | |
163 | + // } | |
164 | +</script> | |
165 | +<style></style> | ... | ... |
src/views/project/finance/financeProfit/ServiceProfit/PackageProfit/tableData.tsx
0 → 100644
1 | +import { ref } from 'vue'; | |
2 | +import { ROLE } from '../../../financeList/type.d'; | |
3 | +import { queryNoOptions } from '/@/api/project/order'; | |
4 | +import { useOrderInfo } from '/@/hooks/component/order'; | |
5 | +import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
6 | +import { formatToDate } from '/@/utils/dateUtil'; | |
7 | + | |
8 | +// 角色 | |
9 | +// 业务员- 查看all,编辑-利润分析,报告书 | |
10 | +// 跟单员- 查看利润分析(单价和总金额),跟单,质检,编辑 | |
11 | +// 质检员- 查看跟单,质检,编辑质检 | |
12 | + | |
13 | +const innerNoOptions = ref([]); | |
14 | +const projectNoOptions = ref([]); | |
15 | +const orderStore = useOrderStoreWithOut(); | |
16 | +// const { productionDepartment: productionDepartmentOptions } = useOrderInfo(orderStore); | |
17 | + | |
18 | +/** | |
19 | + * drawer面板的字段 | |
20 | + */ | |
21 | +// 基本信息 | |
22 | +export const FIELDS_BASE_INFO = [ | |
23 | + { | |
24 | + field: 'customerCode', | |
25 | + component: 'Select', | |
26 | + labelWidth: 150, | |
27 | + label: '客户编码', | |
28 | + rules: [{ required: true }], | |
29 | + }, | |
30 | + { | |
31 | + field: 'projectNo', | |
32 | + component: 'Input', | |
33 | + labelWidth: 150, | |
34 | + label: '项目号', | |
35 | + rules: [{ required: true }], | |
36 | + }, | |
37 | + { | |
38 | + field: 'productionDepartment', | |
39 | + component: 'Select', | |
40 | + // componentProps: { | |
41 | + // options: productionDepartmentOptions, | |
42 | + // }, | |
43 | + labelWidth: 150, | |
44 | + label: '生产科', | |
45 | + rules: [{ required: true }], | |
46 | + }, | |
47 | + | |
48 | + { | |
49 | + field: 'innerNo', | |
50 | + component: 'Input', | |
51 | + labelWidth: 150, | |
52 | + label: '内部编号', | |
53 | + rules: [ | |
54 | + { required: true }, | |
55 | + { | |
56 | + validator: async (rule, value) => { | |
57 | + if (value.includes(' ')) { | |
58 | + return Promise.reject(); | |
59 | + } | |
60 | + return Promise.resolve(); | |
61 | + }, | |
62 | + message: '内容存在空格,请检查', | |
63 | + trigger: ['change', 'blur'], | |
64 | + }, | |
65 | + ], | |
66 | + }, | |
67 | + { | |
68 | + field: 'customerPo', | |
69 | + component: 'Input', | |
70 | + labelWidth: 150, | |
71 | + label: '客户po号', | |
72 | + rules: [{ required: true }], | |
73 | + }, | |
74 | + { | |
75 | + field: 'customerStyle', | |
76 | + component: 'Input', | |
77 | + labelWidth: 150, | |
78 | + label: '客户STYLE', | |
79 | + rules: [ | |
80 | + { required: true }, | |
81 | + { | |
82 | + validator: async (rule, value) => { | |
83 | + if (value.includes(' ')) { | |
84 | + return Promise.reject(); | |
85 | + } | |
86 | + return Promise.resolve(); | |
87 | + }, | |
88 | + message: '内容存在空格,请检查', | |
89 | + trigger: ['change', 'blur'], | |
90 | + }, | |
91 | + ], | |
92 | + }, | |
93 | +]; | |
94 | + | ... | ... |
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/CheckDetail.vue
0 → 100644
1 | +<template> | |
2 | + <div class="container"> | |
3 | + <BasicDrawer | |
4 | + @register="register" | |
5 | + v-bind="$attrs" | |
6 | + showFooter | |
7 | + title="字段编辑权限申请" | |
8 | + width="60%" | |
9 | + :destroyOnClose="true" | |
10 | + :isDetail="true" | |
11 | + @ok="handleSubmit" | |
12 | + :showDetailBack="false" | |
13 | + okText="申请" | |
14 | + ><input /> | |
15 | + <div> | |
16 | + <template v-if="role === ROLE.ADMIN || role === ROLE.TRACKER"> | |
17 | + <h3>基本信息</h3> | |
18 | + <BasicForm @register="registerForm" /> | |
19 | + </template> | |
20 | + </div> | |
21 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | |
22 | + | |
23 | + <!-- <template #appendFooter> | |
24 | + <a-button type="primary" @click="onGoFormDetail"> 返回编辑</a-button> | |
25 | + </template> --> | |
26 | + </BasicDrawer> | |
27 | + </div> | |
28 | +</template> | |
29 | +<script lang="ts"> | |
30 | + import { computed, defineComponent, reactive, ref } from 'vue'; | |
31 | + import { BasicForm, useForm } from '/@/components/Form/index'; | |
32 | + import { orderAuth } from '/@/api/project/order'; | |
33 | + import { ROLE } from '../../../financeList/type.d'; | |
34 | + import { useModal } from '/@/components/Modal'; | |
35 | + | |
36 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | |
37 | + import { FIELDS_BASE_INFO } from './tableData'; | |
38 | + import { useUserStoreWithOut } from '/@/store/modules/user'; | |
39 | + | |
40 | + const userStore = useUserStoreWithOut(); | |
41 | + const getSchema = (fields) => | |
42 | + fields | |
43 | + .map((item) => ({ | |
44 | + field: `${item.field}`, | |
45 | + dataIndex: `${item.field}`, | |
46 | + label: item.label, | |
47 | + component: 'Switch', | |
48 | + componentProps: { | |
49 | + checkedValue: 'UN_LOCKED', | |
50 | + unCheckedValue: 'LOCKED', | |
51 | + }, | |
52 | + colProps: { | |
53 | + span: 6, | |
54 | + }, | |
55 | + })) | |
56 | + .filter( | |
57 | + (item) => | |
58 | + // item.field !== 'packetPrice' && | |
59 | + item.field !== 'exchangeRate' && item.field !== 'profitRate', | |
60 | + ); | |
61 | + | |
62 | + export default defineComponent({ | |
63 | + components: { BasicDrawer, BasicForm }, | |
64 | + props: { | |
65 | + onGoFormDetail: { | |
66 | + type: Function, | |
67 | + }, | |
68 | + }, | |
69 | + setup() { | |
70 | + const id = ref(''); | |
71 | + const schemas = getSchema(FIELDS_BASE_INFO); | |
72 | + const [registerForm, { getFieldsValue }] = useForm({ | |
73 | + labelWidth: 120, | |
74 | + schemas, | |
75 | + showActionButtonGroup: false, | |
76 | + actionColOptions: { | |
77 | + span: 24, | |
78 | + }, | |
79 | + }); | |
80 | + const lockFields = reactive({}); | |
81 | + const [register, { closeDrawer }] = useDrawerInner((data) => { | |
82 | + Object.assign(lockFields, data.lockFields); | |
83 | + id.value = data.id; | |
84 | + }); | |
85 | + function handleCloseModal() { | |
86 | + closeDrawer(); | |
87 | + } | |
88 | + | |
89 | + const role = computed(() => { | |
90 | + return userStore.getUserInfo?.roleSmallVO?.code; | |
91 | + }); | |
92 | + | |
93 | + const handleSubmit = async () => { | |
94 | + const baseFieldValues = getFieldsValue(); | |
95 | + | |
96 | + if (baseFieldValues) { | |
97 | + FIELDS_BASE_INFO.map( | |
98 | + ({ field }) => | |
99 | + (baseFieldValues[field] = | |
100 | + baseFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), | |
101 | + ); | |
102 | + } | |
103 | + const values = Object.assign({ orderId: id.value }, { baseFields: baseFieldValues }); | |
104 | + | |
105 | + if ( | |
106 | + values.baseFields && | |
107 | + (values.baseFields.projectNo === 'UN_LOCKED' || | |
108 | + values.baseFields.productionDepartment === 'UN_LOCKED' || | |
109 | + values.baseFields.innerNo === 'UN_LOCKED' || | |
110 | + values.baseFields.customerCode === 'UN_LOCKED' || | |
111 | + values.baseFields.customerPo === 'UN_LOCKED' || | |
112 | + values.baseFields.customerStyle === 'UN_LOCKED') | |
113 | + ) { | |
114 | + openReasonModal(true, { | |
115 | + data: values, | |
116 | + }); | |
117 | + } else { | |
118 | + await orderAuth(values); | |
119 | + closeDrawer(); | |
120 | + } | |
121 | + }; | |
122 | + | |
123 | + return { | |
124 | + register, | |
125 | + schemas, | |
126 | + registerForm, | |
127 | + handleSubmit, | |
128 | + handleCloseModal, | |
129 | + ROLE, | |
130 | + role, | |
131 | + }; | |
132 | + }, | |
133 | + }); | |
134 | +</script> | |
135 | +<style> | |
136 | + .container { | |
137 | + position: fixed; /* 或 absolute, fixed */ | |
138 | + z-index: 10; | |
139 | + } | |
140 | +</style> | ... | ... |
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/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">研发复制费合计¥</div> | |
19 | + <a-input | |
20 | + v-model:value="input1" | |
21 | + placeholder="请输入" | |
22 | + :disabled="status1 === 'LOCKED'" | |
23 | + auto-size | |
24 | + /> | |
25 | + <div style="margin: 16px 0"></div> | |
26 | + <div style="font-size: 15px">项目开始时间</div> | |
27 | + <a-date-picker v-model:value="input3" :disabled="status3 === 'LOCKED'" auto-size /> | |
28 | + <div style="margin: 16px 0"></div> | |
29 | + <div style="font-size: 15px">项目结束时间</div> | |
30 | + <a-date-picker v-model:value="input4" :disabled="status4 === 'LOCKED'" auto-size /> | |
31 | + <div style="margin: 16px 0"></div> | |
32 | + <div style="font-size: 15px">西班牙已发提成¥</div> | |
33 | + <a-input | |
34 | + v-model:value="input2" | |
35 | + placeholder="请输入" | |
36 | + :disabled="status2 === 'LOCKED'" | |
37 | + auto-size | |
38 | + /> | |
39 | + <div style="margin: 16px 0"></div> | |
40 | + <div style="font-size: 15px">中国团队已发提成¥</div> | |
41 | + <a-input | |
42 | + v-model:value="input5" | |
43 | + placeholder="请输入" | |
44 | + :disabled="status5 === 'LOCKED'" | |
45 | + auto-size | |
46 | + /> | |
47 | + <div style="margin: 16px 0"></div> | |
48 | + <div style="font-size: 15px">实际汇率¥</div> | |
49 | + <a-input | |
50 | + v-model:value="input6" | |
51 | + placeholder="请输入" | |
52 | + :disabled="status6 === 'LOCKED'" | |
53 | + auto-size | |
54 | + /> | |
55 | + <div style="margin: 16px 0"></div> | |
56 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | |
57 | + <template #appendFooter> | |
58 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | |
59 | + </template> | |
60 | + </BasicDrawer> | |
61 | + </template> | |
62 | +</template> | |
63 | +<script lang="ts" setup> | |
64 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | |
65 | + import { BasicForm, FormSchema, useForm } from '@/components/Form'; | |
66 | + import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue'; | |
67 | + import { getServiceEdit } from '@/api/project/invoice'; | |
68 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
69 | + import { ROLE } from './type.d'; | |
70 | + import type { Dayjs } from 'dayjs'; | |
71 | + import dayjs from 'dayjs'; | |
72 | + | |
73 | + const emit = defineEmits(['success']); | |
74 | + const role = computed(() => { | |
75 | + return user?.roleSmallVO?.code; | |
76 | + }); | |
77 | + const schemas: FormSchema[] = [ | |
78 | + // { | |
79 | + // field: 'totalPayAmount', | |
80 | + // component: 'InputNumber', | |
81 | + // labelWidth: 250, | |
82 | + // colProps: { | |
83 | + // span: 23, | |
84 | + // }, | |
85 | + // label: '实际应收金额', | |
86 | + // }, | |
87 | + { | |
88 | + field: 'developmentCopyRmbTotalPrice', | |
89 | + component: 'InputNumber', | |
90 | + labelWidth: 250, | |
91 | + colProps: { | |
92 | + span: 23, | |
93 | + }, | |
94 | + // componentProps: () => ({ | |
95 | + // disabled: status.value === 10, | |
96 | + // }), | |
97 | + label: '研发复制费合计¥', | |
98 | + }, | |
99 | + { | |
100 | + field: 'actualPayedAmount2', | |
101 | + component: 'InputNumber', | |
102 | + labelWidth: 250, | |
103 | + colProps: { | |
104 | + span: 23, | |
105 | + }, | |
106 | + | |
107 | + label: '实际应收金额2$', | |
108 | + }, | |
109 | + { | |
110 | + field: 'actualPayedAmount3', | |
111 | + component: 'InputNumber', | |
112 | + labelWidth: 250, | |
113 | + colProps: { | |
114 | + span: 23, | |
115 | + }, | |
116 | + | |
117 | + label: '实际应收金额3$', | |
118 | + }, | |
119 | + { | |
120 | + field: 'otherAmount', | |
121 | + component: 'InputNumber', | |
122 | + labelWidth: 250, | |
123 | + colProps: { | |
124 | + span: 23, | |
125 | + }, | |
126 | + | |
127 | + label: '其他费用金额$', | |
128 | + }, | |
129 | + ]; | |
130 | + const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ | |
131 | + labelWidth: 120, | |
132 | + schemas, | |
133 | + layout: 'vertical', | |
134 | + showActionButtonGroup: false, | |
135 | + actionColOptions: { | |
136 | + span: 24, | |
137 | + }, | |
138 | + }); | |
139 | + const { createMessage } = useMessage(); | |
140 | + const { error } = createMessage; | |
141 | + | |
142 | + const update = ref(); | |
143 | + const status1 = ref(); | |
144 | + const status2 = ref(); | |
145 | + const status3 = ref(); | |
146 | + const status4 = ref(); | |
147 | + const status5 = ref(); | |
148 | + const status6 = ref(); | |
149 | + | |
150 | + const input1 = ref(); | |
151 | + const input2 = ref(); | |
152 | + const input3 = ref(); | |
153 | + // const input4 = ref(); | |
154 | + const input4 = ref(dayjs('2013-12-01')); | |
155 | + | |
156 | + const input5 = ref(); | |
157 | + const input6 = ref(); | |
158 | + const id = ref(); | |
159 | + // function formatDate(dateStr: string): string { | |
160 | + // const date = new Date(dateStr); | |
161 | + // const year = date.getFullYear(); | |
162 | + // const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,+1 | |
163 | + // const day = String(date.getDate()).padStart(2, '0'); | |
164 | + // const hours = String(date.getHours()).padStart(2, '0'); | |
165 | + // const minutes = String(date.getMinutes()).padStart(2, '0'); | |
166 | + // const seconds = String(date.getSeconds()).padStart(2, '0'); | |
167 | + | |
168 | + // // 返回格式化后的字符串:'YYYY-MM-DD HH:mm:ss' | |
169 | + // return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | |
170 | + // } | |
171 | + function formatDateToDateOnly(dateStr: string): string { | |
172 | + const date = new Date(dateStr); | |
173 | + const year = date.getFullYear(); | |
174 | + const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,+1 | |
175 | + const day = String(date.getDate()).padStart(2, '0'); | |
176 | + | |
177 | + // 返回格式化后的日期字符串:'YYYY-MM-DD' | |
178 | + return `${year}-${month}-${day}`; | |
179 | + } | |
180 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | |
181 | + // 方式1 | |
182 | + if (data.data.lockFields) { | |
183 | + status1.value = data?.data?.lockFields?.developmentCopyRmbTotalPrice; | |
184 | + status2.value = data?.data?.lockFields?.spainPaidRmbCommission; | |
185 | + status3.value = data?.data?.lockFields?.projectStartTime; | |
186 | + status4.value = data?.data?.lockFields?.projectEndTime; | |
187 | + status5.value = data?.data?.lockFields?.paidRmbCommission; | |
188 | + status6.value = data?.data?.lockFields?.actualExchangeRate; | |
189 | + } | |
190 | + id.value = data?.data?.projectNoPrefix; | |
191 | + input1.value = data?.data?.developmentCopyRmbTotalPrice.toFixed(2); | |
192 | + input2.value = data?.data?.spainPaidRmbCommission.toFixed(2); | |
193 | + input3.value = dayjs(formatDateToDateOnly(data?.data?.projectStartTime)); | |
194 | + input4.value = dayjs(formatDateToDateOnly(data?.data?.projectEndTime)); | |
195 | + input5.value = data?.data?.paidRmbCommission.toFixed(2); | |
196 | + input6.value = data?.data?.actualExchangeRate.toFixed(2); | |
197 | + // console.log(input3.value, '5656gbg', input4.value); | |
198 | + resetFields(); | |
199 | + setDrawerProps({ confirmLoading: false }); | |
200 | + setFieldsValue({ | |
201 | + ...toRaw(data.data), | |
202 | + }); | |
203 | + update.value = data; | |
204 | + }); | |
205 | + //完成编辑 | |
206 | + async function handleSubmit() { | |
207 | + // const values = await validate(); | |
208 | + // const updatedValues = { | |
209 | + // ...values, | |
210 | + // id: update.value.data.id, | |
211 | + // bgUrl: update.value.data.bgUrl, | |
212 | + // }; | |
213 | + if (!input1.value || !input2.value || !input3.value || !input4.value) { | |
214 | + error('选项不能为空'); | |
215 | + } else { | |
216 | + await getServiceEdit({ | |
217 | + projectNoPrefix: id.value, | |
218 | + developmentCopyRmbTotalPrice: input1.value, | |
219 | + spainPaidRmbCommission: input2.value, | |
220 | + projectStartTime: input3.value, | |
221 | + projectEndTime: input4.value, | |
222 | + paidRmbCommission: input5.value, | |
223 | + actualExchangeRate: input6.value, | |
224 | + }); | |
225 | + emit('success'); | |
226 | + closeDrawer(); | |
227 | + } | |
228 | + } | |
229 | +</script> | ... | ... |
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/data.tsx
0 → 100644
1 | +import { InputNumber, Tag } from 'ant-design-vue'; | |
2 | +import { BasicColumn } from '@/components/Table'; | |
3 | +import { func } from 'vue-types'; | |
4 | +import { h, ref } from 'vue'; | |
5 | +import { FilePptOutlined } from '@ant-design/icons-vue'; | |
6 | +import axios from 'axios'; | |
7 | + | |
8 | +// export const COLUMNS = [ | |
9 | +// { | |
10 | +// title: '客户编码', | |
11 | +// dataIndex: 'settingValue', | |
12 | +// width: 150, | |
13 | +// }, | |
14 | +// { | |
15 | +// title: '利润率', | |
16 | +// dataIndex: 'relationValue', | |
17 | +// width: 150, | |
18 | +// editComponent: 'InputNumber', | |
19 | +// editRow: true, | |
20 | +// scopedSlots: { customRender: 'name' } | |
21 | +// }, | |
22 | +// ]; | |
23 | +export const COLUMNS = [ | |
24 | + { | |
25 | + title: '客户编码', | |
26 | + dataIndex: 'customerCode', | |
27 | + width: 150, | |
28 | + }, | |
29 | + { | |
30 | + title: '项目号', | |
31 | + dataIndex: 'projectNoPrefix', | |
32 | + width: 100, | |
33 | + }, | |
34 | + { | |
35 | + title: '客户总价¥', | |
36 | + width: 150, | |
37 | + dataIndex: 'customerTotalPrice', | |
38 | + customRender: (column) => { | |
39 | + return column.record?.customerRmbTotalPrice?.toFixed(2); | |
40 | + }, | |
41 | + }, | |
42 | + { | |
43 | + title: '客户总价$', | |
44 | + width: 150, | |
45 | + dataIndex: 'customerTotalPrice', | |
46 | + customRender: (column) => { | |
47 | + return column.record?.customerTotalPrice?.toFixed(2); | |
48 | + }, | |
49 | + }, | |
50 | + { | |
51 | + title: '生产科总价¥', | |
52 | + dataIndex: 'productionDepartmentTotalPrice', | |
53 | + width: 120, | |
54 | + customRender: (column) => { | |
55 | + return column.record?.productionDepartmentTotalPrice?.toFixed(2); | |
56 | + }, | |
57 | + }, | |
58 | + { | |
59 | + title: '包装费用合计¥', | |
60 | + dataIndex: 'packetTotalPrice', | |
61 | + width: 120, | |
62 | + customRender: (column) => { | |
63 | + return column.record?.packetTotalPrice?.toFixed(2); | |
64 | + }, | |
65 | + }, | |
66 | + { | |
67 | + title: '包装费用合计$', | |
68 | + dataIndex: 'packetTotalPrice', | |
69 | + width: 120, | |
70 | + customRender: (column) => { | |
71 | + return column.record?.packetTotalPrice?.toFixed(2); | |
72 | + }, | |
73 | + }, | |
74 | + { | |
75 | + title: '研发复制费合计¥', | |
76 | + dataIndex: 'developmentCopyRmbTotalPrice', | |
77 | + width: 120, | |
78 | + customRender: (column) => { | |
79 | + return column.record?.developmentCopyRmbTotalPrice?.toFixed(2); | |
80 | + }, | |
81 | + }, | |
82 | + { | |
83 | + title: '固定成本¥', | |
84 | + dataIndex: 'fixedCost', | |
85 | + width: 120, | |
86 | + customRender: (column) => { | |
87 | + return column.record?.fixedCost?.toFixed(2); | |
88 | + }, | |
89 | + }, | |
90 | + { | |
91 | + title: '西班牙提成¥', | |
92 | + dataIndex: 'spainRmbCommission', | |
93 | + width: 120, | |
94 | + customRender: (column) => { | |
95 | + return column.record?.spainRmbCommission?.toFixed(2); | |
96 | + }, | |
97 | + }, | |
98 | + { | |
99 | + title: '已发提成¥', | |
100 | + dataIndex: 'spainPaidRmbCommission', | |
101 | + width: 120, | |
102 | + customRender: (column) => { | |
103 | + return column.record?.spainPaidRmbCommission?.toFixed(2); | |
104 | + }, | |
105 | + }, | |
106 | + { | |
107 | + title: '未发提成¥', | |
108 | + dataIndex: 'spainUnpaidRmbCommission', | |
109 | + width: 120, | |
110 | + customRender: (column) => { | |
111 | + return column.record?.spainUnpaidRmbCommission?.toFixed(2); | |
112 | + }, | |
113 | + }, | |
114 | + { | |
115 | + title: '中国团队提成¥', | |
116 | + dataIndex: 'rmbCommission', | |
117 | + width: 120, | |
118 | + customRender: (column) => { | |
119 | + return column.record?.rmbCommission?.toFixed(2); | |
120 | + }, | |
121 | + }, | |
122 | + { | |
123 | + title: '已发提成¥', | |
124 | + dataIndex: 'paidRmbCommission', | |
125 | + width: 120, | |
126 | + customRender: (column) => { | |
127 | + return column.record?.paidRmbCommission?.toFixed(2); | |
128 | + }, | |
129 | + }, | |
130 | + { | |
131 | + title: '未发提成¥', | |
132 | + dataIndex: 'unpaidRmbCommission', | |
133 | + width: 120, | |
134 | + customRender: (column) => { | |
135 | + return column.record?.unpaidRmbCommission?.toFixed(2); | |
136 | + }, | |
137 | + }, | |
138 | + { | |
139 | + title: '支出合计¥', | |
140 | + dataIndex: 'rmbTotalExpense', | |
141 | + width: 120, | |
142 | + customRender: (column) => { | |
143 | + return column.record?.rmbTotalExpense?.toFixed(2); | |
144 | + }, | |
145 | + }, | |
146 | + { | |
147 | + title: '毛利润¥', | |
148 | + dataIndex: 'profit', | |
149 | + width: 120, | |
150 | + customRender: (column) => { | |
151 | + return column.record?.profit?.toFixed(2); | |
152 | + }, | |
153 | + }, | |
154 | + { | |
155 | + title: '毛利率', | |
156 | + dataIndex: 'profitRate', | |
157 | + width: 120, | |
158 | + customRender: (column) => { | |
159 | + return column.record?.profitRate?.toFixed(2); | |
160 | + }, | |
161 | + }, | |
162 | + { | |
163 | + title: '研发贸易净利润¥', | |
164 | + dataIndex: 'developmentProfit', | |
165 | + width: 120, | |
166 | + customRender: (column) => { | |
167 | + return column.record?.developmentProfit?.toFixed(2); | |
168 | + }, | |
169 | + }, | |
170 | + { | |
171 | + title: '净利润率', | |
172 | + dataIndex: 'developmentProfitRate', | |
173 | + width: 120, | |
174 | + customRender: (column) => { | |
175 | + return column.record?.developmentProfitRate?.toFixed(2); | |
176 | + }, | |
177 | + }, | |
178 | + { | |
179 | + title: '包装费用合计¥', | |
180 | + dataIndex: 'packetRmbTotalPrice', | |
181 | + width: 120, | |
182 | + customRender: (column) => { | |
183 | + return column.record?.packetRmbTotalPrice?.toFixed(2); | |
184 | + }, | |
185 | + }, | |
186 | + { | |
187 | + title: '包装费用实际金额¥', | |
188 | + dataIndex: 'packetActualRmbTotalPrice', | |
189 | + width: 120, | |
190 | + customRender: (column) => { | |
191 | + return column.record?.packetActualRmbTotalPrice?.toFixed(2); | |
192 | + }, | |
193 | + }, | |
194 | + { | |
195 | + title: '订单总数量', | |
196 | + dataIndex: 'orderCount', | |
197 | + width: 120, | |
198 | + customRender: (column) => { | |
199 | + return column.record?.orderCount; | |
200 | + }, | |
201 | + }, | |
202 | + { | |
203 | + title: '实际跟单单价¥', | |
204 | + dataIndex: 'actualOrderRmbPrice', | |
205 | + width: 120, | |
206 | + customRender: (column) => { | |
207 | + return column.record?.actualOrderRmbPrice?.toFixed(2); | |
208 | + }, | |
209 | + }, | |
210 | + { | |
211 | + title: '实际跟单单价折算美金¥', | |
212 | + dataIndex: 'actualOrderPrice', | |
213 | + width: 120, | |
214 | + customRender: (column) => { | |
215 | + return column.record?.actualOrderPrice?.toFixed(2); | |
216 | + }, | |
217 | + }, | |
218 | + { | |
219 | + title: '包装费用收益¥', | |
220 | + dataIndex: 'packetProfitRmbPrice', | |
221 | + width: 120, | |
222 | + customRender: (column) => { | |
223 | + return column.record?.packetProfitRmbPrice?.toFixed(2); | |
224 | + }, | |
225 | + }, | |
226 | + { | |
227 | + title: '实际汇率¥', | |
228 | + dataIndex: 'actualExchangeRate', | |
229 | + width: 120, | |
230 | + customRender: (column) => { | |
231 | + return column.record?.actualExchangeRate?.toFixed(2); | |
232 | + }, | |
233 | + }, | |
234 | + { | |
235 | + title: '汇率收益¥', | |
236 | + dataIndex: 'exchangeRateProfit', | |
237 | + width: 120, | |
238 | + customRender: (column) => { | |
239 | + return column.record?.exchangeRateProfit?.toFixed(2); | |
240 | + }, | |
241 | + }, | |
242 | + { | |
243 | + title: '综合收益¥', | |
244 | + dataIndex: 'comprehensiveProfit', | |
245 | + width: 120, | |
246 | + customRender: (column) => { | |
247 | + return column.record?.comprehensiveProfit?.toFixed(2); | |
248 | + }, | |
249 | + }, | |
250 | + { | |
251 | + title: '文件', | |
252 | + dataIndex: 'fileUrl', | |
253 | + width: 120, | |
254 | + customRender: (column) => { | |
255 | + // 构造符合 API 要求的参数 | |
256 | + // await exportAnalysis({ ids: ids }); | |
257 | + const handleClick = () => { | |
258 | + axios | |
259 | + .post( | |
260 | + '/basic-api/project/businessProfit/export', | |
261 | + { | |
262 | + projectNoPrefix: column.record.projectNoPrefix, | |
263 | + }, | |
264 | + { | |
265 | + responseType: 'blob', // 设置响应类型为 'blob' | |
266 | + }, | |
267 | + ) | |
268 | + .then((response) => { | |
269 | + // 创建一个 Blob 对象来保存二进制数据 | |
270 | + const blob = new Blob([response.data], { type: 'application/zip' }); | |
271 | + const getFormattedDate = (): string => { | |
272 | + const date = new Date(); | |
273 | + | |
274 | + const year = date.getFullYear(); | |
275 | + const month = String(date.getMonth() + 1).padStart(2, '0'); | |
276 | + const day = String(date.getDate()).padStart(2, '0'); | |
277 | + | |
278 | + const hours = String(date.getHours()).padStart(2, '0'); | |
279 | + const minutes = String(date.getMinutes()).padStart(2, '0'); | |
280 | + const seconds = String(date.getSeconds()).padStart(2, '0'); | |
281 | + | |
282 | + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | |
283 | + }; | |
284 | + const date = getFormattedDate(); | |
285 | + // 创建一个链接元素用于下载 | |
286 | + const link = document.createElement('a'); | |
287 | + link.href = window.URL.createObjectURL(blob); | |
288 | + link.download = `${date}.xlsx`; // 你可以为文件命名 | |
289 | + document.body.appendChild(link); | |
290 | + link.click(); // 自动点击链接,触发下载 | |
291 | + document.body.removeChild(link); // 下载完成后移除链接 | |
292 | + }) | |
293 | + .catch((error) => { | |
294 | + console.error(error); | |
295 | + }); | |
296 | + }; | |
297 | + return <FilePptOutlined style="font-size:25px" onClick={() => handleClick()} />; | |
298 | + }, | |
299 | + }, | |
300 | +]; | |
0 | 301 | \ No newline at end of file | ... | ... |
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/index.vue
0 → 100644
1 | +<template> | |
2 | + <div> | |
3 | + <BasicTable @register="registerTable" :bordered="true"> | |
4 | + <template #bodyCell="{ column, record }"> | |
5 | + <template v-if="column.key === 'action'"> | |
6 | + <TableAction :actions="createActions(record)" /> | |
7 | + </template> | |
8 | + <!-- <template v-if="column.key === 'relationValue'"> | |
9 | + <a-input | |
10 | + v-if="record.settingValue === 'A01'" | |
11 | + v-model:value="record.settingValue" | |
12 | + :max-length="50" | |
13 | + /> | |
14 | + <span v-else style="color: red"> | |
15 | + {{ record.settingValue }} | |
16 | + </span> | |
17 | + </template> --> | |
18 | + </template> | |
19 | + </BasicTable> | |
20 | + <!-- <BasicModal | |
21 | + title="拒绝原因" | |
22 | + width="30%" | |
23 | + @register="registerModal" | |
24 | + @visible-change="handleClose" | |
25 | + @ok="handleOk" | |
26 | + wrapClassName="approve-modal" | |
27 | + > | |
28 | + <div className="pa-8"> | |
29 | + <a-textarea :rows="6" placeholder="请输入拒绝原因" v-model:value="message" /> | |
30 | + </div> | |
31 | + </BasicModal> --> | |
32 | + <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> | |
33 | + <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | |
34 | + </div> | |
35 | +</template> | |
36 | +<script setup lang="ts"> | |
37 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | |
38 | + import { getServiceProfit } from '@/api/project/invoice'; | |
39 | + import { COLUMNS } from './data'; | |
40 | + import { BasicModal, useModal } from '/@/components/Modal'; | |
41 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
42 | + import { ref } from 'vue'; | |
43 | + import { useDrawer } from '/@/components/Drawer'; | |
44 | + import FinanceEdit from './FinanceEdit.vue'; | |
45 | + import CheckDetail from './CheckDetail.vue'; | |
46 | + | |
47 | + const { createMessage } = useMessage(); | |
48 | + const { error } = createMessage; | |
49 | + const message = ref(); | |
50 | + const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); | |
51 | + const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); | |
52 | + // const handleOk = (record) => { | |
53 | + // // 修改父组件的状态 | |
54 | + // console.log(message.value, '5656messsage', record); | |
55 | + // closeModal(); | |
56 | + // }; | |
57 | + const handleClose = (visible: boolean) => { | |
58 | + if (!visible) { | |
59 | + message.value = ''; | |
60 | + } | |
61 | + }; | |
62 | + const [registerTable, { reload }] = useTable({ | |
63 | + api: getServiceProfit, | |
64 | + bordered: true, | |
65 | + columns: COLUMNS, | |
66 | + rowKey: 'id', | |
67 | + useSearchForm: true, | |
68 | + actionColumn: { | |
69 | + width: 240, | |
70 | + title: 'Action', | |
71 | + dataIndex: 'action', | |
72 | + }, | |
73 | + }); | |
74 | + | |
75 | + function createActions(record: any): any[] { | |
76 | + if (!record.editable) { | |
77 | + return [ | |
78 | + { | |
79 | + label: '财务编辑', | |
80 | + onClick: handleFinanceEdit.bind(null, record), | |
81 | + }, | |
82 | + // { | |
83 | + // label: '编辑', | |
84 | + // onClick: handleEdit.bind(null, record), | |
85 | + // }, | |
86 | + // { | |
87 | + // label: '删除', | |
88 | + // popConfirm: { | |
89 | + // title: '确认删除?', | |
90 | + // confirm: handleDelete.bind(null, record), | |
91 | + // }, | |
92 | + // }, | |
93 | + { | |
94 | + label: '申请权限', | |
95 | + // popConfirm: { | |
96 | + // title: '确认申请?', | |
97 | + // confirm: handleFalse.bind(null, record), | |
98 | + // }, | |
99 | + onClick: handleFalse.bind(null, record), | |
100 | + }, | |
101 | + ]; | |
102 | + } | |
103 | + return [ | |
104 | + { | |
105 | + label: '保存', | |
106 | + onClick: handleSave.bind(null, record), | |
107 | + }, | |
108 | + { | |
109 | + label: '取消', | |
110 | + popConfirm: { | |
111 | + title: '是否取消编辑', | |
112 | + confirm: handleCancel.bind(null, record), | |
113 | + }, | |
114 | + }, | |
115 | + ]; | |
116 | + } | |
117 | + | |
118 | + function handleFinanceEdit(record) { | |
119 | + console.log(record, '5656reer'); | |
120 | + openFinanceEdit(true, { | |
121 | + data: record, | |
122 | + }); | |
123 | + } | |
124 | + | |
125 | + function handleFalse(record, e) { | |
126 | + openCheckDetailDrawer(true, record); | |
127 | + e?.stopPropagation(); | |
128 | + return false; | |
129 | + } | |
130 | + | |
131 | + // async function handleFalse(record: any) { | |
132 | + // console.log(record); | |
133 | + // // openModal(true, { record }); | |
134 | + // } | |
135 | + | |
136 | + function handleSuccess() { | |
137 | + setTimeout(() => { | |
138 | + reload(); | |
139 | + }, 50); | |
140 | + } | |
141 | + | |
142 | + async function handleSave(record) { | |
143 | + await saveConfig({ id: record.id, relationValue: record.relationValue }); | |
144 | + handleCancel(record); | |
145 | + reload(); | |
146 | + } | |
147 | + function handleEdit(record: any) { | |
148 | + console.log(record, '5656edit'); | |
149 | + // if (record.settingValue == 'A01') { | |
150 | + // error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
151 | + // } else { | |
152 | + record.onEdit?.(true); | |
153 | + // } | |
154 | + } | |
155 | + | |
156 | + function handleCancel(record) { | |
157 | + record.onEdit?.(false, false); | |
158 | + } | |
159 | + | |
160 | + async function handleDelete(record) { | |
161 | + // await deleteConfig({ ids: [record.id] }); | |
162 | + reload(); | |
163 | + } | |
164 | +</script> | |
165 | +<style></style> | ... | ... |
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/tableData.tsx
0 → 100644
1 | +import { ref } from 'vue'; | |
2 | +import { ROLE } from '../../../financeList/type.d'; | |
3 | +import { queryNoOptions } from '/@/api/project/order'; | |
4 | +import { useOrderInfo } from '/@/hooks/component/order'; | |
5 | +import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
6 | +import { formatToDate } from '/@/utils/dateUtil'; | |
7 | + | |
8 | +// 角色 | |
9 | +// 业务员- 查看all,编辑-利润分析,报告书 | |
10 | +// 跟单员- 查看利润分析(单价和总金额),跟单,质检,编辑 | |
11 | +// 质检员- 查看跟单,质检,编辑质检 | |
12 | + | |
13 | +const innerNoOptions = ref([]); | |
14 | +const projectNoOptions = ref([]); | |
15 | +const orderStore = useOrderStoreWithOut(); | |
16 | +// const { productionDepartment: productionDepartmentOptions } = useOrderInfo(orderStore); | |
17 | + | |
18 | +/** | |
19 | + * drawer面板的字段 | |
20 | + */ | |
21 | +// 基本信息 | |
22 | +export const FIELDS_BASE_INFO = [ | |
23 | + { | |
24 | + field: 'customerCode', | |
25 | + component: 'Select', | |
26 | + labelWidth: 150, | |
27 | + label: '客户编码', | |
28 | + rules: [{ required: true }], | |
29 | + }, | |
30 | + { | |
31 | + field: 'projectNo', | |
32 | + component: 'Input', | |
33 | + labelWidth: 150, | |
34 | + label: '项目号', | |
35 | + rules: [{ required: true }], | |
36 | + }, | |
37 | + { | |
38 | + field: 'productionDepartment', | |
39 | + component: 'Select', | |
40 | + // componentProps: { | |
41 | + // options: productionDepartmentOptions, | |
42 | + // }, | |
43 | + labelWidth: 150, | |
44 | + label: '生产科', | |
45 | + rules: [{ required: true }], | |
46 | + }, | |
47 | + | |
48 | + { | |
49 | + field: 'innerNo', | |
50 | + component: 'Input', | |
51 | + labelWidth: 150, | |
52 | + label: '内部编号', | |
53 | + rules: [ | |
54 | + { required: true }, | |
55 | + { | |
56 | + validator: async (rule, value) => { | |
57 | + if (value.includes(' ')) { | |
58 | + return Promise.reject(); | |
59 | + } | |
60 | + return Promise.resolve(); | |
61 | + }, | |
62 | + message: '内容存在空格,请检查', | |
63 | + trigger: ['change', 'blur'], | |
64 | + }, | |
65 | + ], | |
66 | + }, | |
67 | + { | |
68 | + field: 'customerPo', | |
69 | + component: 'Input', | |
70 | + labelWidth: 150, | |
71 | + label: '客户po号', | |
72 | + rules: [{ required: true }], | |
73 | + }, | |
74 | + { | |
75 | + field: 'customerStyle', | |
76 | + component: 'Input', | |
77 | + labelWidth: 150, | |
78 | + label: '客户STYLE', | |
79 | + rules: [ | |
80 | + { required: true }, | |
81 | + { | |
82 | + validator: async (rule, value) => { | |
83 | + if (value.includes(' ')) { | |
84 | + return Promise.reject(); | |
85 | + } | |
86 | + return Promise.resolve(); | |
87 | + }, | |
88 | + message: '内容存在空格,请检查', | |
89 | + trigger: ['change', 'blur'], | |
90 | + }, | |
91 | + ], | |
92 | + }, | |
93 | +]; | |
94 | + | ... | ... |
src/views/project/order/InvoiceCreate.vue
... | ... | @@ -41,7 +41,7 @@ |
41 | 41 | const { error } = createMessage; |
42 | 42 | const Input1 = ref(''); |
43 | 43 | const Input2 = ref(); |
44 | - const uploadUrl = ref('http://47.104.8.35:8081/api/localStorage/upload_file_oss?name='); | |
44 | + const uploadUrl = ref('http://47.104.8.35:80/api/localStorage/upload_file_oss?name='); | |
45 | 45 | const bgUrl = ref(); |
46 | 46 | const orderIds = ref(); |
47 | 47 | ... | ... |
vite.config.ts
... | ... | @@ -30,7 +30,18 @@ export default defineApplicationConfig({ |
30 | 30 | }, |
31 | 31 | }, |
32 | 32 | '/basic-api/order': { |
33 | - target: 'http://47.104.8.35:8000', | |
33 | + target: 'http://47.104.8.35:18000', | |
34 | + // target: 'http://localhost:18000', | |
35 | + // target: 'http://39.108.227.113:8000', | |
36 | + // target: 'http://localhost:8000', | |
37 | + // target: 'http://39.108.227.113:3000/mock/35', | |
38 | + // http://39.108.227.113:8000/order/erp/captcha/get_img_captcha_code | |
39 | + changeOrigin: true, | |
40 | + ws: true, | |
41 | + rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), | |
42 | + }, | |
43 | + '/basic-api/project': { | |
44 | + target: 'http://47.104.8.35:18000', | |
34 | 45 | // target: 'http://localhost:18000', |
35 | 46 | // target: 'http://39.108.227.113:8000', |
36 | 47 | // target: 'http://localhost:8000', |
... | ... | @@ -41,7 +52,7 @@ export default defineApplicationConfig({ |
41 | 52 | rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), |
42 | 53 | }, |
43 | 54 | '/api/localStorage/upload': { |
44 | - target: 'http://47.104.8.35:8000', | |
55 | + target: 'http://47.104.8.35:18000', | |
45 | 56 | // target: 'http://localhost:18000', |
46 | 57 | // target: 'http://39.108.227.113:8000', |
47 | 58 | // target: '192.168.31.250:18000', | ... | ... |