Commit f267cff7999d05e481ae22a9c1aa3aa7641c38f6
1 parent
cbe36709
feat: 历史记录
Showing
17 changed files
with
1240 additions
and
55 deletions
src/api/project/approve.ts
@@ -21,12 +21,11 @@ export const approveAuditApi = async (params: any) => | @@ -21,12 +21,11 @@ export const approveAuditApi = async (params: any) => | ||
21 | { message: '操作成功' }, | 21 | { message: '操作成功' }, |
22 | ); | 22 | ); |
23 | 23 | ||
24 | -export const getWaitListApi = async (params: DemoParams) => { | 24 | +export const getWaitListApi = async (params: any) => { |
25 | const res = await defHttp.post({ | 25 | const res = await defHttp.post({ |
26 | url: Api.APPROVE, | 26 | url: Api.APPROVE, |
27 | params, | 27 | params, |
28 | }); | 28 | }); |
29 | - | ||
30 | res.records = res.records.map((item) => { | 29 | res.records = res.records.map((item) => { |
31 | return item; | 30 | return item; |
32 | }); | 31 | }); |
@@ -44,7 +43,7 @@ export const getApprovedListApi = async (params: any) => { | @@ -44,7 +43,7 @@ export const getApprovedListApi = async (params: any) => { | ||
44 | res.records = res.records.map((item) => { | 43 | res.records = res.records.map((item) => { |
45 | return item; | 44 | return item; |
46 | }); | 45 | }); |
47 | - | 46 | + console.log(res, '56567ressss'); |
48 | return new Promise((resolve) => { | 47 | return new Promise((resolve) => { |
49 | resolve({ items: res.records, total: res.total }); | 48 | resolve({ items: res.records, total: res.total }); |
50 | }); | 49 | }); |
src/api/project/invoice.ts
@@ -50,6 +50,12 @@ enum Api { | @@ -50,6 +50,12 @@ enum Api { | ||
50 | SERVICEAPPLYEDIT = '/project/applyEditFileds', //申请修改 | 50 | SERVICEAPPLYEDIT = '/project/applyEditFileds', //申请修改 |
51 | APPLYLIST = '/project/pageProjectLockFieldApply', //分页查询项目字段申请记录 | 51 | APPLYLIST = '/project/pageProjectLockFieldApply', //分页查询项目字段申请记录 |
52 | AUDITAPPLY = '/project/audit', //审核 | 52 | AUDITAPPLY = '/project/audit', //审核 |
53 | + ACTIONRECORD = '/projectOptLog/listByPage', //业务/内部研发净利润操作记录以及申请记录 | ||
54 | + ORDERCOSTDETAILEDOPTLOG = '/orderCostDetailedOptLog/listByPage', //包装费用明细/内部生产明细操作记录表 | ||
55 | + ORDERCOSTDETAILEDEXPORT = '/project/businessProfit/exportExcel', //业务研发净利润分析表导出 | ||
56 | + INNERPRODUCEPROFITEXPORT = '/project/innerProfitInfo/exportExcel', //内部生产净利润分析表导出 | ||
57 | + BUSINESSPROFITDETAIL = '/order/cost/businessProfitDetail/exportExcel', //包装费用明细导出 | ||
58 | + INNERPROFITDETAIL = '/order/cost/innerProfitDetail/exportExcel', //内部生产明细导出 | ||
53 | } | 59 | } |
54 | 60 | ||
55 | export const getRefundDate = async (params: any, data?: any) => { | 61 | export const getRefundDate = async (params: any, data?: any) => { |
@@ -427,18 +433,30 @@ export const getServiceApplyEdit = async (params: any) => { | @@ -427,18 +433,30 @@ export const getServiceApplyEdit = async (params: any) => { | ||
427 | }; | 433 | }; |
428 | 434 | ||
429 | export const getApplyList = async (params: any) => { | 435 | export const getApplyList = async (params: any) => { |
430 | - const res = ref(); | ||
431 | - res.value = await defHttp.post<any>({ | 436 | + // const res = ref(); |
437 | + // res.value = await defHttp.post<any>({ | ||
438 | + // url: Api.APPLYLIST, | ||
439 | + // params, | ||
440 | + // }); | ||
441 | + // res.value.data.records.forEach((record) => { | ||
442 | + // const jsonObj = JSON.parse(record?.fields); | ||
443 | + // if (jsonObj) { | ||
444 | + // record.fields = jsonObj; | ||
445 | + // } | ||
446 | + // }); | ||
447 | + // return res.value.data.records; | ||
448 | + const data = await defHttp.post({ | ||
432 | url: Api.APPLYLIST, | 449 | url: Api.APPLYLIST, |
433 | params, | 450 | params, |
434 | }); | 451 | }); |
435 | - res.value.data.records.forEach((record) => { | ||
436 | - const jsonObj = JSON.parse(record?.fields); | ||
437 | - if (jsonObj) { | ||
438 | - record.fields = jsonObj; | ||
439 | - } | 452 | + const res = data.data; |
453 | + res.records = res.records.map((item) => { | ||
454 | + return item; | ||
455 | + }); | ||
456 | + | ||
457 | + return new Promise((resolve) => { | ||
458 | + resolve({ items: res.records, total: res.total }); | ||
440 | }); | 459 | }); |
441 | - return res.value.data.records; | ||
442 | }; | 460 | }; |
443 | 461 | ||
444 | export const getAuditApply = async (params: any) => { | 462 | export const getAuditApply = async (params: any) => { |
@@ -461,3 +479,70 @@ export const checkDeleteDeduct = async (params: any) => { | @@ -461,3 +479,70 @@ export const checkDeleteDeduct = async (params: any) => { | ||
461 | params, | 479 | params, |
462 | }); | 480 | }); |
463 | }; | 481 | }; |
482 | + | ||
483 | +export const getProjectOptLog = async (params: any) => { | ||
484 | + const res = await defHttp.post<any>({ | ||
485 | + url: Api.ACTIONRECORD, | ||
486 | + params, | ||
487 | + }); | ||
488 | + const formattedRecords = res.records.map((record: any) => { | ||
489 | + return { | ||
490 | + ...record, | ||
491 | + }; | ||
492 | + }); | ||
493 | + const orderStore = useOrderStoreWithOut(); | ||
494 | + orderStore.setTotal(res.total); | ||
495 | + orderStore.setQueryVO(params); | ||
496 | + return new Promise((resolve) => { | ||
497 | + resolve({ | ||
498 | + items: formattedRecords, | ||
499 | + total: res.total, | ||
500 | + }); | ||
501 | + }); | ||
502 | +}; | ||
503 | + | ||
504 | +export const getOrderCostDetailedOptLog = async (params: any) => { | ||
505 | + const res = await defHttp.post<any>({ | ||
506 | + url: Api.ORDERCOSTDETAILEDOPTLOG, | ||
507 | + params, | ||
508 | + }); | ||
509 | + const formattedRecords = res.records.map((record: any) => { | ||
510 | + return { | ||
511 | + ...record, | ||
512 | + }; | ||
513 | + }); | ||
514 | + const orderStore = useOrderStoreWithOut(); | ||
515 | + orderStore.setTotal(res.total); | ||
516 | + orderStore.setQueryVO(params); | ||
517 | + return new Promise((resolve) => { | ||
518 | + resolve({ | ||
519 | + items: formattedRecords, | ||
520 | + total: res.total, | ||
521 | + }); | ||
522 | + }); | ||
523 | +}; | ||
524 | +export const getBusinessProfitExport = async (params: any) => { | ||
525 | + return await defHttp.post<any>({ | ||
526 | + url: Api.ORDERCOSTDETAILEDEXPORT, | ||
527 | + params, | ||
528 | + }); | ||
529 | +}; | ||
530 | + | ||
531 | +export const getInnerProfitInfoExport = async (params: any) => { | ||
532 | + return await defHttp.post<any>({ | ||
533 | + url: Api.INNERPRODUCEPROFITEXPORT, | ||
534 | + params, | ||
535 | + }); | ||
536 | +}; | ||
537 | +export const getBusinessProfitDetailExport = async (params: any) => { | ||
538 | + return await defHttp.post<any>({ | ||
539 | + url: Api.BUSINESSPROFITDETAIL, | ||
540 | + params, | ||
541 | + }); | ||
542 | +}; | ||
543 | +export const getInnerProfitDetail = async (params: any) => { | ||
544 | + return await defHttp.post<any>({ | ||
545 | + url: Api.INNERPROFITDETAIL, | ||
546 | + params, | ||
547 | + }); | ||
548 | +}; | ||
464 | \ No newline at end of file | 549 | \ No newline at end of file |
src/router/routes/modules/project/finance.ts
@@ -116,8 +116,8 @@ const finance: AppRouteModule = { | @@ -116,8 +116,8 @@ const finance: AppRouteModule = { | ||
116 | }, | 116 | }, |
117 | children: [ | 117 | children: [ |
118 | { | 118 | { |
119 | - path: 'InnerData', | ||
120 | - name: 'InnerData', | 119 | + path: 'InnerProduce', |
120 | + name: 'InnerProduce', | ||
121 | meta: { | 121 | meta: { |
122 | title: '内部生产净利润分析表', | 122 | title: '内部生产净利润分析表', |
123 | roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | 123 | roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], |
@@ -129,8 +129,8 @@ const finance: AppRouteModule = { | @@ -129,8 +129,8 @@ const finance: AppRouteModule = { | ||
129 | ), | 129 | ), |
130 | }, | 130 | }, |
131 | { | 131 | { |
132 | - path: 'InnerProduce', | ||
133 | - name: 'InnerProduce', | 132 | + path: 'InnerData', |
133 | + name: 'InnerData', | ||
134 | meta: { | 134 | meta: { |
135 | title: '内部生产明细表', | 135 | title: '内部生产明细表', |
136 | roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], | 136 | roles: [RoleEnum.ADMIN, RoleEnum.FINANCE, RoleEnum.TRACKER, RoleEnum.BUSINESS], |
src/views/project/finance/financeProfit/ProductProfit/InnerData/FinanceEdit.vue
@@ -32,6 +32,14 @@ | @@ -32,6 +32,14 @@ | ||
32 | auto-size | 32 | auto-size |
33 | /> | 33 | /> |
34 | <div style="margin: 16px 0"></div> | 34 | <div style="margin: 16px 0"></div> |
35 | + <div style="font-size: 15px">生产科预算单价</div> | ||
36 | + <a-input | ||
37 | + v-model:value="input3" | ||
38 | + placeholder="请输入" | ||
39 | + :disabled="status3 == 'LOCKED'" | ||
40 | + auto-size | ||
41 | + /> | ||
42 | + <div style="margin: 16px 0"></div> | ||
35 | 43 | ||
36 | <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | 44 | <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> |
37 | <template #appendFooter> | 45 | <template #appendFooter> |
@@ -126,20 +134,26 @@ | @@ -126,20 +134,26 @@ | ||
126 | const update = ref(); | 134 | const update = ref(); |
127 | const status1 = ref(); | 135 | const status1 = ref(); |
128 | const status2 = ref(); | 136 | const status2 = ref(); |
137 | + const status3 = ref(); | ||
129 | 138 | ||
130 | const input1 = ref(); | 139 | const input1 = ref(); |
131 | const input2 = ref(); | 140 | const input2 = ref(); |
141 | + const input3 = ref(); | ||
142 | + const orderCount = ref(); | ||
132 | const id = ref(); | 143 | const id = ref(); |
133 | const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | 144 | const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { |
134 | // 方式1 | 145 | // 方式1 |
135 | if (data.data?.lockFields) { | 146 | if (data.data?.lockFields) { |
136 | status1.value = data.data?.lockFields?.productionDepartmentPredictPrice; | 147 | status1.value = data.data?.lockFields?.productionDepartmentPredictPrice; |
137 | status2.value = data.data?.lockFields?.productionActualPrice; | 148 | status2.value = data.data?.lockFields?.productionActualPrice; |
149 | + status3.value = data.data?.lockFields?.productionDepartmentPredictUnitprice; | ||
138 | } | 150 | } |
139 | 151 | ||
140 | id.value = data.data.orderId; | 152 | id.value = data.data.orderId; |
141 | input1.value = data.data?.productionDepartmentPredictPrice.toFixed(2); | 153 | input1.value = data.data?.productionDepartmentPredictPrice.toFixed(2); |
142 | input2.value = data.data?.productionActualPrice.toFixed(2); | 154 | input2.value = data.data?.productionActualPrice.toFixed(2); |
155 | + orderCount.value = data.data?.orderCount; | ||
156 | + input3.value = data.data?.productionDepartmentPredictUnitprice.toFixed(2); | ||
143 | resetFields(); | 157 | resetFields(); |
144 | setDrawerProps({ confirmLoading: false }); | 158 | setDrawerProps({ confirmLoading: false }); |
145 | // setFieldsValue({ | 159 | // setFieldsValue({ |
@@ -155,13 +169,15 @@ | @@ -155,13 +169,15 @@ | ||
155 | // id: update.value.data.id, | 169 | // id: update.value.data.id, |
156 | // bgUrl: update.value.data.bgUrl, | 170 | // bgUrl: update.value.data.bgUrl, |
157 | // }; | 171 | // }; |
158 | - if (!input1.value || !input2.value) { | 172 | + if (!input1.value || !input2.value || !input3.value) { |
159 | error('选项不能为空'); | 173 | error('选项不能为空'); |
160 | } else { | 174 | } else { |
161 | await getPackageEdit({ | 175 | await getPackageEdit({ |
162 | orderId: id.value, | 176 | orderId: id.value, |
163 | productionDepartmentPredictPrice: input1.value, | 177 | productionDepartmentPredictPrice: input1.value, |
164 | productionActualPrice: input2.value, | 178 | productionActualPrice: input2.value, |
179 | + orderCount: orderCount.value, | ||
180 | + productionDepartmentPredictUnitprice: input3.value, | ||
165 | }); | 181 | }); |
166 | emit('success'); | 182 | emit('success'); |
167 | closeDrawer(); | 183 | closeDrawer(); |
@@ -171,6 +187,7 @@ | @@ -171,6 +187,7 @@ | ||
171 | if (!visible) { | 187 | if (!visible) { |
172 | input1.value = ''; | 188 | input1.value = ''; |
173 | input2.value = ''; | 189 | input2.value = ''; |
190 | + input3.value = ''; | ||
174 | } | 191 | } |
175 | } | 192 | } |
176 | </script> | 193 | </script> |
src/views/project/finance/financeProfit/ProductProfit/InnerData/HistoryDetail.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicDrawer | ||
3 | + @register="register" | ||
4 | + v-bind="$attrs" | ||
5 | + title="操作记录" | ||
6 | + width="60%" | ||
7 | + :isDetail="true" | ||
8 | + :showDetailBack="false" | ||
9 | + okText="保存" | ||
10 | + :destroyOnClose="true" | ||
11 | + > | ||
12 | + <Tabs v-model:activeKey="activeKey" className="my-0"> | ||
13 | + <TabPanel :key="1" tab="操作记录" className="w-full"> | ||
14 | + <a-list :pagination="pagination1" className="w-full"> | ||
15 | + <template v-for="item in list1" :key="item.id"> | ||
16 | + <a-list-item class="list"> | ||
17 | + <a-list-item-meta> | ||
18 | + <template #avatar> </template> | ||
19 | + <template #title> | ||
20 | + <span>{{ item.userName }}</span> | ||
21 | + </template> | ||
22 | + <template #description> | ||
23 | + <div class="description"> | ||
24 | + {{ item.optType }} | ||
25 | + </div> | ||
26 | + <div class="info"> | ||
27 | + <div><span>操作时间:</span>{{ formatToDateTime(item.createTime) }}</div> | ||
28 | + </div> | ||
29 | + </template> | ||
30 | + </a-list-item-meta> | ||
31 | + </a-list-item> | ||
32 | + </template> | ||
33 | + </a-list> | ||
34 | + </TabPanel> | ||
35 | + <TabPanel :key="2" tab="审批记录" className="w-full"> | ||
36 | + <a-list :pagination="pagination2" className="w-full"> | ||
37 | + <template v-for="item in list2" :key="item.id"> | ||
38 | + <a-list-item class="list"> | ||
39 | + <a-list-item-meta> | ||
40 | + <template #avatar> </template> | ||
41 | + <template #title> | ||
42 | + <span>{{ item.userName }}</span> | ||
43 | + </template> | ||
44 | + <template #description> | ||
45 | + <div class="description"> | ||
46 | + {{ item.optType }} | ||
47 | + </div> | ||
48 | + <div class="info"> | ||
49 | + <div><span>操作时间:</span>{{ formatToDateTime(item.createTime) }}</div> | ||
50 | + </div> | ||
51 | + </template> | ||
52 | + </a-list-item-meta> | ||
53 | + </a-list-item> | ||
54 | + </template> | ||
55 | + </a-list> | ||
56 | + </TabPanel> | ||
57 | + </Tabs> | ||
58 | + | ||
59 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | ||
60 | + <template #appendFooter> | ||
61 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | ||
62 | + </template> | ||
63 | + </BasicDrawer> | ||
64 | +</template> | ||
65 | +<script lang="ts"> | ||
66 | + import { defineComponent, ref, computed } from 'vue'; | ||
67 | + import { Tabs, List } from 'ant-design-vue'; | ||
68 | + import { FormSchema } from '/@/components/Form/index'; | ||
69 | + | ||
70 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
71 | + import { getOrderCostDetailedOptLog } from '/@/api/project/invoice'; | ||
72 | + import { formatToDateTime } from '/@/utils/dateUtil'; | ||
73 | + | ||
74 | + const TabPanel = Tabs.TabPane; | ||
75 | + | ||
76 | + const schemas: FormSchema[] = [ | ||
77 | + { | ||
78 | + field: '订单号', | ||
79 | + component: 'Input', | ||
80 | + label: '字段1', | ||
81 | + componentProps: { | ||
82 | + readonly: true, | ||
83 | + disabled: true, | ||
84 | + }, | ||
85 | + colProps: { | ||
86 | + span: 12, | ||
87 | + }, | ||
88 | + defaultValue: '111', | ||
89 | + }, | ||
90 | + { | ||
91 | + field: 'field2', | ||
92 | + component: 'Input', | ||
93 | + label: '字段2', | ||
94 | + colProps: { | ||
95 | + span: 12, | ||
96 | + }, | ||
97 | + }, | ||
98 | + ]; | ||
99 | + const achieveList = [ | ||
100 | + { | ||
101 | + key: '1', | ||
102 | + name: '操作记录', | ||
103 | + }, | ||
104 | + { | ||
105 | + key: '2', | ||
106 | + name: '审批记录', | ||
107 | + }, | ||
108 | + ]; | ||
109 | + export default defineComponent({ | ||
110 | + components: { | ||
111 | + BasicDrawer, | ||
112 | + Tabs, | ||
113 | + TabPanel, | ||
114 | + [List.name]: List, | ||
115 | + [List.Item.name]: List.Item, | ||
116 | + AListItemMeta: List.Item.Meta, | ||
117 | + }, | ||
118 | + props: { | ||
119 | + onGoCheckDetail: { | ||
120 | + type: Function, | ||
121 | + }, | ||
122 | + }, | ||
123 | + setup() { | ||
124 | + const list1 = ref([]); | ||
125 | + const total1 = ref(0); | ||
126 | + const page1 = ref(1); | ||
127 | + | ||
128 | + const list2 = ref([]); | ||
129 | + const total2 = ref(0); | ||
130 | + const page2 = ref(1); | ||
131 | + const orderId = ref(''); | ||
132 | + const activeKey = ref(1); | ||
133 | + | ||
134 | + const getOrderOptLogFunc = async (data, index, page) => { | ||
135 | + console.log('%c [ data ]-135', 'font-size:13px; background:pink; color:#bf2c9f;', data); | ||
136 | + if (index === 1) { | ||
137 | + const res = await getOrderCostDetailedOptLog({ | ||
138 | + orderId: data, | ||
139 | + type: 40, | ||
140 | + page: page, | ||
141 | + pageSize: 20, | ||
142 | + }); | ||
143 | + list1.value = res.items; | ||
144 | + total1.value = res.total; | ||
145 | + page1.value = page; | ||
146 | + } else { | ||
147 | + const res = await getOrderCostDetailedOptLog({ | ||
148 | + orderId: data, | ||
149 | + type: 70, | ||
150 | + page: page, | ||
151 | + pageSize: 20, | ||
152 | + }); | ||
153 | + list2.value = res.items; | ||
154 | + total2.value = res.total; | ||
155 | + page2.value = page; | ||
156 | + } | ||
157 | + }; | ||
158 | + const [register] = useDrawerInner((data) => { | ||
159 | + orderId.value = data.data.orderId; | ||
160 | + getOrderOptLogFunc(orderId.value, 1, 1); | ||
161 | + getOrderOptLogFunc(orderId.value, 2, 1); | ||
162 | + }); | ||
163 | + | ||
164 | + const pagination1 = computed(() => { | ||
165 | + return { | ||
166 | + show: true, | ||
167 | + pageSize: 20, | ||
168 | + page: page1.value, | ||
169 | + total: total1.value, | ||
170 | + onChange(cur) { | ||
171 | + getOrderOptLogFunc(orderId.value, 1, cur); | ||
172 | + }, | ||
173 | + }; | ||
174 | + }); | ||
175 | + | ||
176 | + const pagination2 = computed(() => { | ||
177 | + return { | ||
178 | + show: true, | ||
179 | + pageSize: 20, | ||
180 | + page: page1.value, | ||
181 | + total: total1.value, | ||
182 | + onChange(cur) { | ||
183 | + getOrderOptLogFunc(orderId.value, 2, cur); | ||
184 | + }, | ||
185 | + }; | ||
186 | + }); | ||
187 | + | ||
188 | + return { | ||
189 | + register, | ||
190 | + schemas, | ||
191 | + achieveList, | ||
192 | + list1, | ||
193 | + list2, | ||
194 | + prefixCls: 'account-center', | ||
195 | + pagination1, | ||
196 | + pagination2, | ||
197 | + activeKey, | ||
198 | + formatToDateTime, | ||
199 | + }; | ||
200 | + }, | ||
201 | + }); | ||
202 | +</script> |
src/views/project/finance/financeProfit/ProductProfit/InnerData/data.tsx
@@ -137,7 +137,15 @@ export const COLUMNS = [ | @@ -137,7 +137,15 @@ export const COLUMNS = [ | ||
137 | }, | 137 | }, |
138 | }, | 138 | }, |
139 | { | 139 | { |
140 | - title: '生产科预算金额¥', | 140 | + title: '生产科预算单价¥', |
141 | + width: 150, | ||
142 | + dataIndex: 'productionDepartmentPredictUnitprice', | ||
143 | + customRender: (column) => { | ||
144 | + return column.record?.productionDepartmentPredictUnitprice?.toFixed(2); | ||
145 | + }, | ||
146 | + }, | ||
147 | + { | ||
148 | + title: '生产科预算总金额¥', | ||
141 | width: 150, | 149 | width: 150, |
142 | dataIndex: 'productionDepartmentPredictPrice', | 150 | dataIndex: 'productionDepartmentPredictPrice', |
143 | customRender: (column) => { | 151 | customRender: (column) => { |
@@ -145,9 +153,9 @@ export const COLUMNS = [ | @@ -145,9 +153,9 @@ export const COLUMNS = [ | ||
145 | }, | 153 | }, |
146 | }, | 154 | }, |
147 | { | 155 | { |
148 | - title: '实际发生费用', | 156 | + title: '生产科实际花费总金额¥', |
149 | dataIndex: 'productionActualPrice', | 157 | dataIndex: 'productionActualPrice', |
150 | - width: 120, | 158 | + width: 180, |
151 | customRender: (column) => { | 159 | customRender: (column) => { |
152 | return column.record?.productionActualPrice?.toFixed(2); | 160 | return column.record?.productionActualPrice?.toFixed(2); |
153 | }, | 161 | }, |
@@ -212,6 +220,20 @@ export const COLUMNS = [ | @@ -212,6 +220,20 @@ export const COLUMNS = [ | ||
212 | return column.record?.grossProfitRate?.toFixed(2); | 220 | return column.record?.grossProfitRate?.toFixed(2); |
213 | }, | 221 | }, |
214 | }, | 222 | }, |
223 | + { | ||
224 | + title: '状态', | ||
225 | + dataIndex: 'status', | ||
226 | + width: 120, | ||
227 | + customRender: (column) => { | ||
228 | + if (column.record?.status === '-1') { | ||
229 | + return '未完成'; | ||
230 | + } else if (column.record?.status === '0') { | ||
231 | + return '待审核'; | ||
232 | + } else if (column.record?.status === '1') { | ||
233 | + return '已审核'; | ||
234 | + } | ||
235 | + }, | ||
236 | + }, | ||
215 | // { | 237 | // { |
216 | // title: '内部生产固定成本¥', | 238 | // title: '内部生产固定成本¥', |
217 | // dataIndex: 'innerProductionFixedCost', | 239 | // dataIndex: 'innerProductionFixedCost', |
src/views/project/finance/financeProfit/ProductProfit/InnerData/index.vue
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | <img :z-index="100000" :width="50" :height="50" :src="record?.picUrl" /> | 6 | <img :z-index="100000" :width="50" :height="50" :src="record?.picUrl" /> |
7 | </template> | 7 | </template> |
8 | <template v-if="column.key === 'action'"> | 8 | <template v-if="column.key === 'action'"> |
9 | - <TableAction :actions="createActions(record)" /> | 9 | + <TableAction :actions="createActions(record)" :dropDownActions="createDropActions(record)" /> |
10 | </template> | 10 | </template> |
11 | <!-- <template v-if="column.key === 'relationValue'"> | 11 | <!-- <template v-if="column.key === 'relationValue'"> |
12 | <a-input | 12 | <a-input |
@@ -32,8 +32,9 @@ | @@ -32,8 +32,9 @@ | ||
32 | <a-textarea :rows="6" placeholder="请输入拒绝原因" v-model:value="message" /> | 32 | <a-textarea :rows="6" placeholder="请输入拒绝原因" v-model:value="message" /> |
33 | </div> | 33 | </div> |
34 | </BasicModal> --> | 34 | </BasicModal> --> |
35 | - <CheckDetail @register="checkModalRegister" /> | 35 | + <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> |
36 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | 36 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> |
37 | + <HistoryDetail @register="registerHistoryDetail" /> | ||
37 | </div> | 38 | </div> |
38 | </template> | 39 | </template> |
39 | <script setup lang="ts"> | 40 | <script setup lang="ts"> |
@@ -42,11 +43,15 @@ | @@ -42,11 +43,15 @@ | ||
42 | import { searchFormSchema, COLUMNS } from './data'; | 43 | import { searchFormSchema, COLUMNS } from './data'; |
43 | import { BasicModal, useModal } from '/@/components/Modal'; | 44 | import { BasicModal, useModal } from '/@/components/Modal'; |
44 | import { useMessage } from '/@/hooks/web/useMessage'; | 45 | import { useMessage } from '/@/hooks/web/useMessage'; |
45 | - import { onMounted, ref } from 'vue'; | 46 | + import { onMounted, ref, computed } from 'vue'; |
46 | import { useDrawer } from '/@/components/Drawer'; | 47 | import { useDrawer } from '/@/components/Drawer'; |
47 | import FinanceEdit from './FinanceEdit.vue'; | 48 | import FinanceEdit from './FinanceEdit.vue'; |
48 | import CheckDetail from './CheckDetail.vue'; | 49 | import CheckDetail from './CheckDetail.vue'; |
50 | + import HistoryDetail from './HistoryDetail.vue'; | ||
49 | import { useOrderStoreWithOut } from '/@/store/modules/order'; | 51 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
52 | + import { useUserStoreWithOut } from '/@/store/modules/user'; | ||
53 | + import { RoleEnum } from '/@/enums/roleEnum'; | ||
54 | + import { ROLE } from '../../../type.d'; | ||
50 | 55 | ||
51 | const { createMessage } = useMessage(); | 56 | const { createMessage } = useMessage(); |
52 | const { error } = createMessage; | 57 | const { error } = createMessage; |
@@ -54,6 +59,12 @@ | @@ -54,6 +59,12 @@ | ||
54 | const orderStore = useOrderStoreWithOut(); | 59 | const orderStore = useOrderStoreWithOut(); |
55 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); | 60 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); |
56 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); | 61 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); |
62 | + const [registerHistoryDetail, { openDrawer: openHistoryDetail }] = useDrawer(); | ||
63 | + const userStore = useUserStoreWithOut(); | ||
64 | + const user = userStore.getUserInfo; | ||
65 | + const role = computed(() => { | ||
66 | + return user?.roleSmallVO?.code; | ||
67 | + }); | ||
57 | const handleOk = (record) => { | 68 | const handleOk = (record) => { |
58 | // 修改父组件的状态 | 69 | // 修改父组件的状态 |
59 | closeModal(); | 70 | closeModal(); |
@@ -80,7 +91,7 @@ | @@ -80,7 +91,7 @@ | ||
80 | setting: false, | 91 | setting: false, |
81 | }, | 92 | }, |
82 | actionColumn: { | 93 | actionColumn: { |
83 | - width: 240, | 94 | + width: 260, |
84 | title: 'Action', | 95 | title: 'Action', |
85 | dataIndex: 'action', | 96 | dataIndex: 'action', |
86 | }, | 97 | }, |
@@ -111,6 +122,18 @@ | @@ -111,6 +122,18 @@ | ||
111 | // }, | 122 | // }, |
112 | onClick: handleFalse.bind(null, record), | 123 | onClick: handleFalse.bind(null, record), |
113 | }, | 124 | }, |
125 | + { | ||
126 | + label: '审批通过', | ||
127 | + popConfirm: { | ||
128 | + title: '确认审批?', | ||
129 | + confirm: () => { | ||
130 | + if (record.status === 0 && role.value === ROLE.ADMIN) { | ||
131 | + handleStatus(record, true); | ||
132 | + } | ||
133 | + return; | ||
134 | + }, | ||
135 | + }, | ||
136 | + }, | ||
114 | ]; | 137 | ]; |
115 | } | 138 | } |
116 | return [ | 139 | return [ |
@@ -128,6 +151,18 @@ | @@ -128,6 +151,18 @@ | ||
128 | ]; | 151 | ]; |
129 | } | 152 | } |
130 | 153 | ||
154 | + function createDropActions(record: any) { | ||
155 | + if (!record.editable) { | ||
156 | + const actions = [ | ||
157 | + { | ||
158 | + label: '历史记录', | ||
159 | + onClick: handleHistoryDetail.bind(null, record), | ||
160 | + }, | ||
161 | + ]; | ||
162 | + return actions; | ||
163 | + } | ||
164 | + } | ||
165 | + | ||
131 | onMounted(async () => { | 166 | onMounted(async () => { |
132 | await orderStore.getDict(); | 167 | await orderStore.getDict(); |
133 | }); | 168 | }); |
@@ -175,5 +210,25 @@ | @@ -175,5 +210,25 @@ | ||
175 | reload(); | 210 | reload(); |
176 | }, 50); | 211 | }, 50); |
177 | } | 212 | } |
213 | + | ||
214 | + async function handleStatus(record, status) { | ||
215 | + try { | ||
216 | + // Add your API call here for updating status | ||
217 | + // Example: await updateStatus({ id: record.id, status: status ? 1 : 2 }); | ||
218 | + reload(); | ||
219 | + } catch (error) { | ||
220 | + console.error(error); | ||
221 | + } | ||
222 | + } | ||
223 | + | ||
224 | + function handleHistoryDetail(record) { | ||
225 | + openHistoryDetail(true, { | ||
226 | + data: record, | ||
227 | + }); | ||
228 | + } | ||
229 | + | ||
230 | + function handleGoFormDetail() { | ||
231 | + // Add your logic for form detail navigation | ||
232 | + } | ||
178 | </script> | 233 | </script> |
179 | <style></style> | 234 | <style></style> |
src/views/project/finance/financeProfit/ProductProfit/InnerProduce/HistoryDetail.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicDrawer | ||
3 | + @register="register" | ||
4 | + v-bind="$attrs" | ||
5 | + title="操作记录" | ||
6 | + width="60%" | ||
7 | + :isDetail="true" | ||
8 | + :showDetailBack="false" | ||
9 | + okText="保存" | ||
10 | + :destroyOnClose="true" | ||
11 | + > | ||
12 | + <Tabs v-model:activeKey="activeKey" className="my-0"> | ||
13 | + <TabPanel :key="1" tab="操作记录" className="w-full"> | ||
14 | + <a-list :pagination="pagination1" className="w-full"> | ||
15 | + <template v-for="item in list1" :key="item.id"> | ||
16 | + <a-list-item class="list"> | ||
17 | + <a-list-item-meta> | ||
18 | + <template #avatar> </template> | ||
19 | + <template #title> | ||
20 | + <span>{{ item.userName }}</span> | ||
21 | + </template> | ||
22 | + <template #description> | ||
23 | + <div class="description"> | ||
24 | + {{ item.optType }} | ||
25 | + </div> | ||
26 | + <div class="info"> | ||
27 | + <div><span>操作时间:</span>{{ formatToDateTime(item.createTime) }}</div> | ||
28 | + </div> | ||
29 | + </template> | ||
30 | + </a-list-item-meta> | ||
31 | + </a-list-item> | ||
32 | + </template> | ||
33 | + </a-list> | ||
34 | + </TabPanel> | ||
35 | + <TabPanel :key="2" tab="审批记录" className="w-full"> | ||
36 | + <a-list :pagination="pagination2" className="w-full"> | ||
37 | + <template v-for="item in list2" :key="item.id"> | ||
38 | + <a-list-item class="list"> | ||
39 | + <a-list-item-meta> | ||
40 | + <template #avatar> </template> | ||
41 | + <template #title> | ||
42 | + <span>{{ item.userName }}</span> | ||
43 | + </template> | ||
44 | + <template #description> | ||
45 | + <div class="description"> | ||
46 | + {{ item.optType }} | ||
47 | + </div> | ||
48 | + <div class="info"> | ||
49 | + <div><span>操作时间:</span>{{ formatToDateTime(item.createTime) }}</div> | ||
50 | + </div> | ||
51 | + </template> | ||
52 | + </a-list-item-meta> | ||
53 | + </a-list-item> | ||
54 | + </template> | ||
55 | + </a-list> | ||
56 | + </TabPanel> | ||
57 | + </Tabs> | ||
58 | + | ||
59 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | ||
60 | + <template #appendFooter> | ||
61 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | ||
62 | + </template> | ||
63 | + </BasicDrawer> | ||
64 | +</template> | ||
65 | +<script lang="ts"> | ||
66 | + import { defineComponent, ref, computed } from 'vue'; | ||
67 | + import { Tabs, List } from 'ant-design-vue'; | ||
68 | + import { FormSchema } from '/@/components/Form/index'; | ||
69 | + | ||
70 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
71 | + import { getProjectOptLog } from '/@/api/project/invoice'; | ||
72 | + import { formatToDateTime } from '/@/utils/dateUtil'; | ||
73 | + | ||
74 | + const TabPanel = Tabs.TabPane; | ||
75 | + | ||
76 | + const schemas: FormSchema[] = [ | ||
77 | + { | ||
78 | + field: '订单号', | ||
79 | + component: 'Input', | ||
80 | + label: '字段1', | ||
81 | + componentProps: { | ||
82 | + readonly: true, | ||
83 | + disabled: true, | ||
84 | + }, | ||
85 | + colProps: { | ||
86 | + span: 12, | ||
87 | + }, | ||
88 | + defaultValue: '111', | ||
89 | + }, | ||
90 | + { | ||
91 | + field: 'field2', | ||
92 | + component: 'Input', | ||
93 | + label: '字段2', | ||
94 | + colProps: { | ||
95 | + span: 12, | ||
96 | + }, | ||
97 | + }, | ||
98 | + ]; | ||
99 | + const achieveList = [ | ||
100 | + { | ||
101 | + key: '1', | ||
102 | + name: '操作记录', | ||
103 | + }, | ||
104 | + { | ||
105 | + key: '2', | ||
106 | + name: '审批记录', | ||
107 | + }, | ||
108 | + ]; | ||
109 | + export default defineComponent({ | ||
110 | + components: { | ||
111 | + BasicDrawer, | ||
112 | + Tabs, | ||
113 | + TabPanel, | ||
114 | + [List.name]: List, | ||
115 | + [List.Item.name]: List.Item, | ||
116 | + AListItemMeta: List.Item.Meta, | ||
117 | + }, | ||
118 | + props: { | ||
119 | + onGoCheckDetail: { | ||
120 | + type: Function, | ||
121 | + }, | ||
122 | + }, | ||
123 | + setup() { | ||
124 | + const list1 = ref([]); | ||
125 | + const total1 = ref(0); | ||
126 | + const page1 = ref(1); | ||
127 | + | ||
128 | + const list2 = ref([]); | ||
129 | + const total2 = ref(0); | ||
130 | + const page2 = ref(1); | ||
131 | + const orderId = ref(''); | ||
132 | + const activeKey = ref(1); | ||
133 | + | ||
134 | + const getOrderOptLogFunc = async (data, index, page) => { | ||
135 | + console.log('%c [ data ]-135', 'font-size:13px; background:pink; color:#bf2c9f;', data); | ||
136 | + if (index === 1) { | ||
137 | + const res = await getProjectOptLog({ orderId: data, type: 30, page: page, pageSize: 20 }); | ||
138 | + list1.value = res.items; | ||
139 | + total1.value = res.total; | ||
140 | + page1.value = page; | ||
141 | + } else { | ||
142 | + const res = await getProjectOptLog({ orderId: data, type: 1, page: page, pageSize: 20 }); | ||
143 | + list2.value = res.items; | ||
144 | + total2.value = res.total; | ||
145 | + page2.value = page; | ||
146 | + } | ||
147 | + }; | ||
148 | + const [register] = useDrawerInner((data) => { | ||
149 | + orderId.value = data.data.projectNoPrefix; | ||
150 | + getOrderOptLogFunc(orderId.value, 1, 1); | ||
151 | + getOrderOptLogFunc(orderId.value, 2, 1); | ||
152 | + }); | ||
153 | + | ||
154 | + const pagination1 = computed(() => { | ||
155 | + return { | ||
156 | + show: true, | ||
157 | + pageSize: 20, | ||
158 | + page: page1.value, | ||
159 | + total: total1.value, | ||
160 | + onChange(cur) { | ||
161 | + getOrderOptLogFunc(orderId.value, 1, cur); | ||
162 | + }, | ||
163 | + }; | ||
164 | + }); | ||
165 | + | ||
166 | + const pagination2 = computed(() => { | ||
167 | + return { | ||
168 | + show: true, | ||
169 | + pageSize: 20, | ||
170 | + page: page1.value, | ||
171 | + total: total1.value, | ||
172 | + onChange(cur) { | ||
173 | + getOrderOptLogFunc(orderId.value, 2, cur); | ||
174 | + }, | ||
175 | + }; | ||
176 | + }); | ||
177 | + | ||
178 | + return { | ||
179 | + register, | ||
180 | + schemas, | ||
181 | + achieveList, | ||
182 | + list1, | ||
183 | + list2, | ||
184 | + prefixCls: 'account-center', | ||
185 | + pagination1, | ||
186 | + pagination2, | ||
187 | + activeKey, | ||
188 | + formatToDateTime, | ||
189 | + }; | ||
190 | + }, | ||
191 | + }); | ||
192 | +</script> |
src/views/project/finance/financeProfit/ProductProfit/InnerProduce/data.tsx
@@ -241,6 +241,20 @@ export const COLUMNS = [ | @@ -241,6 +241,20 @@ export const COLUMNS = [ | ||
241 | }, | 241 | }, |
242 | }, | 242 | }, |
243 | { | 243 | { |
244 | + title: '状态', | ||
245 | + dataIndex: 'status', | ||
246 | + width: 120, | ||
247 | + customRender: (column) => { | ||
248 | + if (column.record?.status === '-1') { | ||
249 | + return '未完成'; | ||
250 | + } else if (column.record?.status === '0') { | ||
251 | + return '待审核'; | ||
252 | + } else if (column.record?.status === '1') { | ||
253 | + return '已审核'; | ||
254 | + } | ||
255 | + }, | ||
256 | + }, | ||
257 | + { | ||
244 | title: '文件', | 258 | title: '文件', |
245 | dataIndex: 'fileUrl', | 259 | dataIndex: 'fileUrl', |
246 | width: 120, | 260 | width: 120, |
src/views/project/finance/financeProfit/ProductProfit/InnerProduce/index.vue
@@ -6,7 +6,10 @@ | @@ -6,7 +6,10 @@ | ||
6 | <img :z-index="100000" :width="50" :height="50" :src="record?.picUrl" /> | 6 | <img :z-index="100000" :width="50" :height="50" :src="record?.picUrl" /> |
7 | </template> | 7 | </template> |
8 | <template v-if="column.key === 'action'"> | 8 | <template v-if="column.key === 'action'"> |
9 | - <TableAction :actions="createActions(record)" /> | 9 | + <TableAction |
10 | + :actions="createActions(record)" | ||
11 | + :dropDownActions="createDropActions(record)" | ||
12 | + /> | ||
10 | </template> | 13 | </template> |
11 | <!-- <template v-if="column.key === 'relationValue'"> | 14 | <!-- <template v-if="column.key === 'relationValue'"> |
12 | <a-input | 15 | <a-input |
@@ -32,8 +35,9 @@ | @@ -32,8 +35,9 @@ | ||
32 | <a-textarea :rows="6" placeholder="请输入拒绝原因" v-model:value="message" /> | 35 | <a-textarea :rows="6" placeholder="请输入拒绝原因" v-model:value="message" /> |
33 | </div> | 36 | </div> |
34 | </BasicModal> --> | 37 | </BasicModal> --> |
35 | - <CheckDetail @register="checkModalRegister" /> | 38 | + <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> |
36 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | 39 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> |
40 | + <HistoryDetail @register="registerHistoryDetail" /> | ||
37 | </div> | 41 | </div> |
38 | </template> | 42 | </template> |
39 | <script setup lang="ts"> | 43 | <script setup lang="ts"> |
@@ -42,11 +46,15 @@ | @@ -42,11 +46,15 @@ | ||
42 | import { searchFormSchema, COLUMNS } from './data'; | 46 | import { searchFormSchema, COLUMNS } from './data'; |
43 | import { BasicModal, useModal } from '/@/components/Modal'; | 47 | import { BasicModal, useModal } from '/@/components/Modal'; |
44 | import { useMessage } from '/@/hooks/web/useMessage'; | 48 | import { useMessage } from '/@/hooks/web/useMessage'; |
45 | - import { onMounted, ref } from 'vue'; | 49 | + import { onMounted, ref, computed } from 'vue'; |
46 | import { useDrawer } from '/@/components/Drawer'; | 50 | import { useDrawer } from '/@/components/Drawer'; |
47 | import FinanceEdit from './FinanceEdit.vue'; | 51 | import FinanceEdit from './FinanceEdit.vue'; |
48 | import CheckDetail from './CheckDetail.vue'; | 52 | import CheckDetail from './CheckDetail.vue'; |
53 | + import HistoryDetail from './HistoryDetail.vue'; | ||
49 | import { useOrderStoreWithOut } from '/@/store/modules/order'; | 54 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
55 | + import { useUserStoreWithOut } from '/@/store/modules/user'; | ||
56 | + import { RoleEnum } from '/@/enums/roleEnum'; | ||
57 | + import { ROLE } from '../../../type.d'; | ||
50 | 58 | ||
51 | const { createMessage } = useMessage(); | 59 | const { createMessage } = useMessage(); |
52 | const { error } = createMessage; | 60 | const { error } = createMessage; |
@@ -54,6 +62,12 @@ | @@ -54,6 +62,12 @@ | ||
54 | const orderStore = useOrderStoreWithOut(); | 62 | const orderStore = useOrderStoreWithOut(); |
55 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); | 63 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); |
56 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); | 64 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); |
65 | + const [registerHistoryDetail, { openDrawer: openHistoryDetail }] = useDrawer(); | ||
66 | + const userStore = useUserStoreWithOut(); | ||
67 | + const user = userStore.getUserInfo; | ||
68 | + const role = computed(() => { | ||
69 | + return user?.roleSmallVO?.code; | ||
70 | + }); | ||
57 | const handleOk = (record) => { | 71 | const handleOk = (record) => { |
58 | // 修改父组件的状态 | 72 | // 修改父组件的状态 |
59 | closeModal(); | 73 | closeModal(); |
@@ -81,7 +95,7 @@ | @@ -81,7 +95,7 @@ | ||
81 | setting: false, | 95 | setting: false, |
82 | }, | 96 | }, |
83 | actionColumn: { | 97 | actionColumn: { |
84 | - width: 240, | 98 | + width: 260, |
85 | title: 'Action', | 99 | title: 'Action', |
86 | dataIndex: 'action', | 100 | dataIndex: 'action', |
87 | }, | 101 | }, |
@@ -113,6 +127,18 @@ | @@ -113,6 +127,18 @@ | ||
113 | // }, | 127 | // }, |
114 | onClick: handleFalse.bind(null, record), | 128 | onClick: handleFalse.bind(null, record), |
115 | }, | 129 | }, |
130 | + { | ||
131 | + label: '审核通过', | ||
132 | + popConfirm: { | ||
133 | + title: '确认审核?', | ||
134 | + confirm: () => { | ||
135 | + if (record.status === 0 && role.value === ROLE.ADMIN) { | ||
136 | + handleStatus(record, true); | ||
137 | + } | ||
138 | + return; | ||
139 | + }, | ||
140 | + }, | ||
141 | + }, | ||
116 | ]; | 142 | ]; |
117 | } | 143 | } |
118 | return [ | 144 | return [ |
@@ -130,6 +156,18 @@ | @@ -130,6 +156,18 @@ | ||
130 | ]; | 156 | ]; |
131 | } | 157 | } |
132 | 158 | ||
159 | + function createDropActions(record: any) { | ||
160 | + if (!record.editable) { | ||
161 | + const actions = [ | ||
162 | + { | ||
163 | + label: '历史记录', | ||
164 | + onClick: handleHistoryDetail.bind(null, record), | ||
165 | + }, | ||
166 | + ]; | ||
167 | + return actions; | ||
168 | + } | ||
169 | + } | ||
170 | + | ||
133 | onMounted(async () => { | 171 | onMounted(async () => { |
134 | await orderStore.getDict(); | 172 | await orderStore.getDict(); |
135 | }); | 173 | }); |
@@ -173,5 +211,25 @@ | @@ -173,5 +211,25 @@ | ||
173 | reload(); | 211 | reload(); |
174 | }, 50); | 212 | }, 50); |
175 | } | 213 | } |
214 | + | ||
215 | + async function handleStatus(record, status) { | ||
216 | + try { | ||
217 | + // Add your API call here for updating status | ||
218 | + // Example: await updateStatus({ id: record.id, status: status ? 1 : 2 }); | ||
219 | + reload(); | ||
220 | + } catch (error) { | ||
221 | + console.error(error); | ||
222 | + } | ||
223 | + } | ||
224 | + | ||
225 | + function handleHistoryDetail(record) { | ||
226 | + openHistoryDetail(true, { | ||
227 | + data: record, | ||
228 | + }); | ||
229 | + } | ||
230 | + | ||
231 | + function handleGoFormDetail() { | ||
232 | + // Add your logic for form detail navigation | ||
233 | + } | ||
176 | </script> | 234 | </script> |
177 | <style></style> | 235 | <style></style> |
src/views/project/finance/financeProfit/ServiceProfit/PackageProfit/HistoryDetail.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicDrawer | ||
3 | + @register="register" | ||
4 | + v-bind="$attrs" | ||
5 | + title="操作记录" | ||
6 | + width="60%" | ||
7 | + :isDetail="true" | ||
8 | + :showDetailBack="false" | ||
9 | + okText="保存" | ||
10 | + :destroyOnClose="true" | ||
11 | + > | ||
12 | + <Tabs v-model:activeKey="activeKey" className="my-0"> | ||
13 | + <TabPanel :key="1" tab="操作记录" className="w-full"> | ||
14 | + <a-list :pagination="pagination1" className="w-full"> | ||
15 | + <template v-for="item in list1" :key="item.id"> | ||
16 | + <a-list-item class="list"> | ||
17 | + <a-list-item-meta> | ||
18 | + <template #avatar> </template> | ||
19 | + <template #title> | ||
20 | + <span>{{ item.userName }}</span> | ||
21 | + </template> | ||
22 | + <template #description> | ||
23 | + <div class="description"> | ||
24 | + {{ item.optType }} | ||
25 | + </div> | ||
26 | + <div class="info"> | ||
27 | + <div><span>操作时间:</span>{{ formatToDateTime(item.createTime) }}</div> | ||
28 | + </div> | ||
29 | + </template> | ||
30 | + </a-list-item-meta> | ||
31 | + </a-list-item> | ||
32 | + </template> | ||
33 | + </a-list> | ||
34 | + </TabPanel> | ||
35 | + <TabPanel :key="2" tab="审批记录" className="w-full"> | ||
36 | + <a-list :pagination="pagination2" className="w-full"> | ||
37 | + <template v-for="item in list2" :key="item.id"> | ||
38 | + <a-list-item class="list"> | ||
39 | + <a-list-item-meta> | ||
40 | + <template #avatar> </template> | ||
41 | + <template #title> | ||
42 | + <span>{{ item.userName }}</span> | ||
43 | + </template> | ||
44 | + <template #description> | ||
45 | + <div class="description"> | ||
46 | + {{ item.optType }} | ||
47 | + </div> | ||
48 | + <div class="info"> | ||
49 | + <div><span>操作时间:</span>{{ formatToDateTime(item.createTime) }}</div> | ||
50 | + </div> | ||
51 | + </template> | ||
52 | + </a-list-item-meta> | ||
53 | + </a-list-item> | ||
54 | + </template> | ||
55 | + </a-list> | ||
56 | + </TabPanel> | ||
57 | + </Tabs> | ||
58 | + | ||
59 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | ||
60 | + <template #appendFooter> | ||
61 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | ||
62 | + </template> | ||
63 | + </BasicDrawer> | ||
64 | +</template> | ||
65 | +<script lang="ts"> | ||
66 | + import { defineComponent, ref, computed } from 'vue'; | ||
67 | + import { Tabs, Progress, Row, Col, List } from 'ant-design-vue'; | ||
68 | + import { FormSchema, useForm } from '/@/components/Form/index'; | ||
69 | + | ||
70 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
71 | + import { getOrderCostDetailedOptLog } from '/@/api/project/invoice'; | ||
72 | + import { formatToDateTime } from '/@/utils/dateUtil'; | ||
73 | + | ||
74 | + const TabPanel = Tabs.TabPane; | ||
75 | + | ||
76 | + const schemas: FormSchema[] = [ | ||
77 | + { | ||
78 | + field: '订单号', | ||
79 | + component: 'Input', | ||
80 | + label: '字段1', | ||
81 | + componentProps: { | ||
82 | + readonly: true, | ||
83 | + disabled: true, | ||
84 | + }, | ||
85 | + colProps: { | ||
86 | + span: 12, | ||
87 | + }, | ||
88 | + defaultValue: '111', | ||
89 | + }, | ||
90 | + { | ||
91 | + field: 'field2', | ||
92 | + component: 'Input', | ||
93 | + label: '字段2', | ||
94 | + colProps: { | ||
95 | + span: 12, | ||
96 | + }, | ||
97 | + }, | ||
98 | + ]; | ||
99 | + const achieveList = [ | ||
100 | + { | ||
101 | + key: '1', | ||
102 | + name: '操作记录', | ||
103 | + }, | ||
104 | + { | ||
105 | + key: '2', | ||
106 | + name: '审批记录', | ||
107 | + }, | ||
108 | + ]; | ||
109 | + export default defineComponent({ | ||
110 | + components: { | ||
111 | + BasicDrawer, | ||
112 | + Tabs, | ||
113 | + TabPanel, | ||
114 | + [List.name]: List, | ||
115 | + [List.Item.name]: List.Item, | ||
116 | + AListItemMeta: List.Item.Meta, | ||
117 | + }, | ||
118 | + props: { | ||
119 | + onGoCheckDetail: { | ||
120 | + type: Function, | ||
121 | + }, | ||
122 | + }, | ||
123 | + setup() { | ||
124 | + const list1 = ref([]); | ||
125 | + const total1 = ref(0); | ||
126 | + const page1 = ref(1); | ||
127 | + | ||
128 | + const list2 = ref([]); | ||
129 | + const total2 = ref(0); | ||
130 | + const page2 = ref(1); | ||
131 | + const orderId = ref(''); | ||
132 | + const activeKey = ref(1); | ||
133 | + | ||
134 | + const getOrderOptLogFunc = async (data, index, page) => { | ||
135 | + console.log('%c [ data ]-135', 'font-size:13px; background:pink; color:#bf2c9f;', data); | ||
136 | + if (index === 1) { | ||
137 | + const res = await getOrderCostDetailedOptLog({ | ||
138 | + orderId: data, | ||
139 | + type: 20, | ||
140 | + page: page, | ||
141 | + pageSize: 20 | ||
142 | + }); | ||
143 | + list1.value = res.items; | ||
144 | + total1.value = res.total; | ||
145 | + page1.value = page; | ||
146 | + } else { | ||
147 | + const res = await getOrderCostDetailedOptLog({ | ||
148 | + orderId: data, | ||
149 | + type: 60, | ||
150 | + page: page, | ||
151 | + pageSize: 20 | ||
152 | + }); | ||
153 | + list2.value = res.items; | ||
154 | + total2.value = res.total; | ||
155 | + page2.value = page; | ||
156 | + } | ||
157 | + }; | ||
158 | + const [register] = useDrawerInner((data) => { | ||
159 | + orderId.value = data.data.orderId; | ||
160 | + getOrderOptLogFunc(orderId.value, 1, 1); | ||
161 | + getOrderOptLogFunc(orderId.value, 2, 1); | ||
162 | + }); | ||
163 | + | ||
164 | + const pagination1 = computed(() => { | ||
165 | + return { | ||
166 | + show: true, | ||
167 | + pageSize: 20, | ||
168 | + page: page1.value, | ||
169 | + total: total1.value, | ||
170 | + onChange(cur) { | ||
171 | + getOrderOptLogFunc(orderId.value, 1, cur); | ||
172 | + }, | ||
173 | + }; | ||
174 | + }); | ||
175 | + | ||
176 | + const pagination2 = computed(() => { | ||
177 | + return { | ||
178 | + show: true, | ||
179 | + pageSize: 20, | ||
180 | + page: page1.value, | ||
181 | + total: total1.value, | ||
182 | + onChange(cur) { | ||
183 | + getOrderOptLogFunc(orderId.value, 2, cur); | ||
184 | + }, | ||
185 | + }; | ||
186 | + }); | ||
187 | + | ||
188 | + return { | ||
189 | + register, | ||
190 | + schemas, | ||
191 | + achieveList, | ||
192 | + list1, | ||
193 | + list2, | ||
194 | + prefixCls: 'account-center', | ||
195 | + pagination1, | ||
196 | + pagination2, | ||
197 | + activeKey, | ||
198 | + formatToDateTime, | ||
199 | + }; | ||
200 | + }, | ||
201 | + }); | ||
202 | +</script> |
src/views/project/finance/financeProfit/ServiceProfit/PackageProfit/data.tsx
@@ -187,4 +187,18 @@ export const COLUMNS = [ | @@ -187,4 +187,18 @@ export const COLUMNS = [ | ||
187 | return column.record?.packetProfitRate?.toFixed(2); | 187 | return column.record?.packetProfitRate?.toFixed(2); |
188 | }, | 188 | }, |
189 | }, | 189 | }, |
190 | + { | ||
191 | + title: '状态', | ||
192 | + dataIndex: 'status', | ||
193 | + width: 120, | ||
194 | + customRender: (column) => { | ||
195 | + if (column.record?.status === '-1') { | ||
196 | + return '未完成'; | ||
197 | + } else if (column.record?.status === '0') { | ||
198 | + return '待审核'; | ||
199 | + } else if (column.record?.status === '1') { | ||
200 | + return '已审核'; | ||
201 | + } | ||
202 | + }, | ||
203 | + }, | ||
190 | ]; | 204 | ]; |
191 | \ No newline at end of file | 205 | \ No newline at end of file |
src/views/project/finance/financeProfit/ServiceProfit/PackageProfit/index.vue
@@ -6,7 +6,10 @@ | @@ -6,7 +6,10 @@ | ||
6 | <img :z-index="100000" :width="50" :height="50" :src="record?.picUrl" /> | 6 | <img :z-index="100000" :width="50" :height="50" :src="record?.picUrl" /> |
7 | </template> | 7 | </template> |
8 | <template v-if="column.key === 'action'"> | 8 | <template v-if="column.key === 'action'"> |
9 | - <TableAction :actions="createActions(record)" /> | 9 | + <TableAction |
10 | + :actions="createActions(record)" | ||
11 | + :dropDownActions="createDropActions(record)" | ||
12 | + /> | ||
10 | </template> | 13 | </template> |
11 | <!-- <template v-if="column.key === 'relationValue'"> | 14 | <!-- <template v-if="column.key === 'relationValue'"> |
12 | <a-input | 15 | <a-input |
@@ -34,6 +37,7 @@ | @@ -34,6 +37,7 @@ | ||
34 | </BasicModal> --> | 37 | </BasicModal> --> |
35 | <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> | 38 | <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> |
36 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | 39 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> |
40 | + <HistoryDetail @register="registerHistoryDetail" /> | ||
37 | </div> | 41 | </div> |
38 | </template> | 42 | </template> |
39 | <script setup lang="ts"> | 43 | <script setup lang="ts"> |
@@ -42,12 +46,16 @@ | @@ -42,12 +46,16 @@ | ||
42 | import { searchFormSchema, COLUMNS } from './data'; | 46 | import { searchFormSchema, COLUMNS } from './data'; |
43 | import { BasicModal, useModal } from '/@/components/Modal'; | 47 | import { BasicModal, useModal } from '/@/components/Modal'; |
44 | import { useMessage } from '/@/hooks/web/useMessage'; | 48 | import { useMessage } from '/@/hooks/web/useMessage'; |
45 | - import { onMounted, ref } from 'vue'; | 49 | + import { onMounted, ref, computed } from 'vue'; |
46 | import { useDrawer } from '/@/components/Drawer'; | 50 | import { useDrawer } from '/@/components/Drawer'; |
47 | import FinanceEdit from './FinanceEdit.vue'; | 51 | import FinanceEdit from './FinanceEdit.vue'; |
48 | import CheckDetail from './CheckDetail.vue'; | 52 | import CheckDetail from './CheckDetail.vue'; |
53 | + import HistoryDetail from './HistoryDetail.vue'; | ||
49 | import { FilePptOutlined } from '@ant-design/icons-vue'; | 54 | import { FilePptOutlined } from '@ant-design/icons-vue'; |
50 | import { useOrderStoreWithOut } from '/@/store/modules/order'; | 55 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
56 | + import { useUserStoreWithOut } from '/@/store/modules/user'; | ||
57 | + import { RoleEnum } from '/@/enums/roleEnum'; | ||
58 | + import { ROLE } from '../../../type.d'; | ||
51 | 59 | ||
52 | const { createMessage } = useMessage(); | 60 | const { createMessage } = useMessage(); |
53 | const { error } = createMessage; | 61 | const { error } = createMessage; |
@@ -55,6 +63,12 @@ | @@ -55,6 +63,12 @@ | ||
55 | const orderStore = useOrderStoreWithOut(); | 63 | const orderStore = useOrderStoreWithOut(); |
56 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); | 64 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); |
57 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); | 65 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); |
66 | + const [registerHistoryDetail, { openDrawer: openHistoryDetail }] = useDrawer(); | ||
67 | + const userStore = useUserStoreWithOut(); | ||
68 | + const user = userStore.getUserInfo; | ||
69 | + const role = computed(() => { | ||
70 | + return user?.roleSmallVO?.code; | ||
71 | + }); | ||
58 | const handleOk = (record) => { | 72 | const handleOk = (record) => { |
59 | // 修改父组件的状态 | 73 | // 修改父组件的状态 |
60 | closeModal(); | 74 | closeModal(); |
@@ -81,7 +95,7 @@ | @@ -81,7 +95,7 @@ | ||
81 | setting: false, | 95 | setting: false, |
82 | }, | 96 | }, |
83 | actionColumn: { | 97 | actionColumn: { |
84 | - width: 240, | 98 | + width: 260, |
85 | title: 'Action', | 99 | title: 'Action', |
86 | dataIndex: 'action', | 100 | dataIndex: 'action', |
87 | }, | 101 | }, |
@@ -113,6 +127,18 @@ | @@ -113,6 +127,18 @@ | ||
113 | // }, | 127 | // }, |
114 | onClick: handleFalse.bind(null, record), | 128 | onClick: handleFalse.bind(null, record), |
115 | }, | 129 | }, |
130 | + { | ||
131 | + label: '审核通过', | ||
132 | + popConfirm: { | ||
133 | + title: '确认审核?', | ||
134 | + confirm: () => { | ||
135 | + if (record.status === 0 && role.value === ROLE.ADMIN) { | ||
136 | + handleStatus(record, true); | ||
137 | + } | ||
138 | + return; | ||
139 | + }, | ||
140 | + }, | ||
141 | + }, | ||
116 | ]; | 142 | ]; |
117 | } | 143 | } |
118 | return [ | 144 | return [ |
@@ -130,9 +156,17 @@ | @@ -130,9 +156,17 @@ | ||
130 | ]; | 156 | ]; |
131 | } | 157 | } |
132 | 158 | ||
133 | - onMounted(async () => { | ||
134 | - await orderStore.getDict(); | ||
135 | - }); | 159 | + function createDropActions(record: any) { |
160 | + if (!record.editable) { | ||
161 | + const actions = [ | ||
162 | + { | ||
163 | + label: '历史记录', | ||
164 | + onClick: handleHistoryDetail.bind(null, record), | ||
165 | + }, | ||
166 | + ]; | ||
167 | + return actions; | ||
168 | + } | ||
169 | + } | ||
136 | 170 | ||
137 | function handleFinanceEdit(record) { | 171 | function handleFinanceEdit(record) { |
138 | openFinanceEdit(true, { | 172 | openFinanceEdit(true, { |
@@ -176,5 +210,29 @@ | @@ -176,5 +210,29 @@ | ||
176 | // await deleteConfig({ ids: [record.id] }); | 210 | // await deleteConfig({ ids: [record.id] }); |
177 | // reload(); | 211 | // reload(); |
178 | // } | 212 | // } |
213 | + | ||
214 | + async function handleStatus(record, status) { | ||
215 | + try { | ||
216 | + // Add your API call here for updating status | ||
217 | + // Example: await updateStatus({ id: record.id, status: status ? 1 : 2 }); | ||
218 | + reload(); | ||
219 | + } catch (error) { | ||
220 | + console.error(error); | ||
221 | + } | ||
222 | + } | ||
223 | + | ||
224 | + function handleHistoryDetail(record) { | ||
225 | + openHistoryDetail(true, { | ||
226 | + data: record, | ||
227 | + }); | ||
228 | + } | ||
229 | + | ||
230 | + function handleGoFormDetail() { | ||
231 | + // Add your logic for form detail navigation | ||
232 | + } | ||
233 | + | ||
234 | + onMounted(async () => { | ||
235 | + await orderStore.getDict(); | ||
236 | + }); | ||
179 | </script> | 237 | </script> |
180 | <style></style> | 238 | <style></style> |
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/HistoryDetail.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicDrawer | ||
3 | + @register="register" | ||
4 | + v-bind="$attrs" | ||
5 | + title="操作记录" | ||
6 | + width="60%" | ||
7 | + :isDetail="true" | ||
8 | + :showDetailBack="false" | ||
9 | + okText="保存" | ||
10 | + :destroyOnClose="true" | ||
11 | + > | ||
12 | + <Tabs v-model:activeKey="activeKey" className="my-0"> | ||
13 | + <TabPanel :key="1" tab="操作记录" className="w-full"> | ||
14 | + <a-list :pagination="pagination1" className="w-full"> | ||
15 | + <template v-for="item in list1" :key="item.id"> | ||
16 | + <a-list-item class="list"> | ||
17 | + <a-list-item-meta> | ||
18 | + <template #avatar> </template> | ||
19 | + <template #title> | ||
20 | + <span>{{ item.userName }}</span> | ||
21 | + </template> | ||
22 | + <template #description> | ||
23 | + <div class="description"> | ||
24 | + {{ item.optType }} | ||
25 | + </div> | ||
26 | + <div class="info"> | ||
27 | + <div><span>操作时间:</span>{{ formatToDateTime(item.createTime) }}</div> | ||
28 | + </div> | ||
29 | + </template> | ||
30 | + </a-list-item-meta> | ||
31 | + </a-list-item> | ||
32 | + </template> | ||
33 | + </a-list> | ||
34 | + </TabPanel> | ||
35 | + <TabPanel :key="2" tab="审批记录" className="w-full"> | ||
36 | + <a-list :pagination="pagination2" className="w-full"> | ||
37 | + <template v-for="item in list2" :key="item.id"> | ||
38 | + <a-list-item class="list"> | ||
39 | + <a-list-item-meta> | ||
40 | + <template #avatar> </template> | ||
41 | + <template #title> | ||
42 | + <span>{{ item.userName }}</span> | ||
43 | + </template> | ||
44 | + <template #description> | ||
45 | + <div class="description"> | ||
46 | + {{ item.optType }} | ||
47 | + </div> | ||
48 | + <div class="info"> | ||
49 | + <div><span>操作时间:</span>{{ formatToDateTime(item.createTime) }}</div> | ||
50 | + </div> | ||
51 | + </template> | ||
52 | + </a-list-item-meta> | ||
53 | + </a-list-item> | ||
54 | + </template> | ||
55 | + </a-list> | ||
56 | + </TabPanel> | ||
57 | + </Tabs> | ||
58 | + | ||
59 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | ||
60 | + <template #appendFooter> | ||
61 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | ||
62 | + </template> | ||
63 | + </BasicDrawer> | ||
64 | +</template> | ||
65 | +<script lang="ts"> | ||
66 | + import { defineComponent, ref, computed } from 'vue'; | ||
67 | + import { Tabs, Progress, Row, Col, List } from 'ant-design-vue'; | ||
68 | + import { FormSchema, useForm } from '/@/components/Form/index'; | ||
69 | + | ||
70 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
71 | + import { getProjectOptLog } from '/@/api/project/invoice'; | ||
72 | + import { formatToDateTime } from '/@/utils/dateUtil'; | ||
73 | + | ||
74 | + const TabPanel = Tabs.TabPane; | ||
75 | + | ||
76 | + const schemas: FormSchema[] = [ | ||
77 | + { | ||
78 | + field: '订单号', | ||
79 | + component: 'Input', | ||
80 | + label: '字段1', | ||
81 | + componentProps: { | ||
82 | + readonly: true, | ||
83 | + disabled: true, | ||
84 | + }, | ||
85 | + colProps: { | ||
86 | + span: 12, | ||
87 | + }, | ||
88 | + defaultValue: '111', | ||
89 | + }, | ||
90 | + { | ||
91 | + field: 'field2', | ||
92 | + component: 'Input', | ||
93 | + label: '字段2', | ||
94 | + colProps: { | ||
95 | + span: 12, | ||
96 | + }, | ||
97 | + }, | ||
98 | + ]; | ||
99 | + const achieveList = [ | ||
100 | + { | ||
101 | + key: '1', | ||
102 | + name: '操作记录', | ||
103 | + }, | ||
104 | + { | ||
105 | + key: '2', | ||
106 | + name: '审批记录', | ||
107 | + }, | ||
108 | + ]; | ||
109 | + export default defineComponent({ | ||
110 | + components: { | ||
111 | + BasicDrawer, | ||
112 | + Tabs, | ||
113 | + TabPanel, | ||
114 | + [List.name]: List, | ||
115 | + [List.Item.name]: List.Item, | ||
116 | + AListItemMeta: List.Item.Meta, | ||
117 | + }, | ||
118 | + props: { | ||
119 | + onGoCheckDetail: { | ||
120 | + type: Function, | ||
121 | + }, | ||
122 | + }, | ||
123 | + setup() { | ||
124 | + const list1 = ref([]); | ||
125 | + const total1 = ref(0); | ||
126 | + const page1 = ref(1); | ||
127 | + | ||
128 | + const list2 = ref([]); | ||
129 | + const total2 = ref(0); | ||
130 | + const page2 = ref(1); | ||
131 | + const orderId = ref(''); | ||
132 | + const activeKey = ref(1); | ||
133 | + | ||
134 | + const getOrderOptLogFunc = async (data, index, page) => { | ||
135 | + console.log('%c [ data ]-135', 'font-size:13px; background:pink; color:#bf2c9f;', data); | ||
136 | + if (index === 1) { | ||
137 | + const res = await getProjectOptLog({ | ||
138 | + projectNoPrefix: data, | ||
139 | + type: 10, | ||
140 | + page: page, | ||
141 | + pageSize: 20 | ||
142 | + }); | ||
143 | + console.log(res, '5656res'); | ||
144 | + list1.value = res.items; | ||
145 | + total1.value = res.total; | ||
146 | + page1.value = page; | ||
147 | + } else { | ||
148 | + const res = await getProjectOptLog({ | ||
149 | + projectNoPrefix: data, | ||
150 | + type: 0, | ||
151 | + page: page, | ||
152 | + pageSize: 20 | ||
153 | + }); | ||
154 | + list2.value = res.items; | ||
155 | + total2.value = res.total; | ||
156 | + page2.value = page; | ||
157 | + } | ||
158 | + }; | ||
159 | + const [register] = useDrawerInner((data) => { | ||
160 | + orderId.value = data.data.projectNoPrefix; | ||
161 | + getOrderOptLogFunc(orderId.value, 1, 1); | ||
162 | + getOrderOptLogFunc(orderId.value, 2, 1); | ||
163 | + }); | ||
164 | + | ||
165 | + const pagination1 = computed(() => { | ||
166 | + return { | ||
167 | + show: true, | ||
168 | + pageSize: 20, | ||
169 | + page: page1.value, | ||
170 | + total: total1.value, | ||
171 | + onChange(cur) { | ||
172 | + getOrderOptLogFunc(orderId.value, 1, cur); | ||
173 | + }, | ||
174 | + }; | ||
175 | + }); | ||
176 | + | ||
177 | + const pagination2 = computed(() => { | ||
178 | + return { | ||
179 | + show: true, | ||
180 | + pageSize: 20, | ||
181 | + page: page1.value, | ||
182 | + total: total1.value, | ||
183 | + onChange(cur) { | ||
184 | + getOrderOptLogFunc(orderId.value, 2, cur); | ||
185 | + }, | ||
186 | + }; | ||
187 | + }); | ||
188 | + | ||
189 | + return { | ||
190 | + register, | ||
191 | + schemas, | ||
192 | + achieveList, | ||
193 | + list1, | ||
194 | + list2, | ||
195 | + prefixCls: 'account-center', | ||
196 | + pagination1, | ||
197 | + pagination2, | ||
198 | + activeKey, | ||
199 | + formatToDateTime, | ||
200 | + }; | ||
201 | + }, | ||
202 | + }); | ||
203 | +</script> |
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/data.tsx
@@ -140,7 +140,6 @@ export const COLUMNS = [ | @@ -140,7 +140,6 @@ export const COLUMNS = [ | ||
140 | dataIndex: 'packetTotalPrice', | 140 | dataIndex: 'packetTotalPrice', |
141 | width: 150, | 141 | width: 150, |
142 | customRender: (column) => { | 142 | customRender: (column) => { |
143 | - console.log(column, '5656666666'); | ||
144 | return column.record?.packetRmbTotalPrice?.toFixed(2); | 143 | return column.record?.packetRmbTotalPrice?.toFixed(2); |
145 | }, | 144 | }, |
146 | }, | 145 | }, |
@@ -311,14 +310,6 @@ export const COLUMNS = [ | @@ -311,14 +310,6 @@ export const COLUMNS = [ | ||
311 | }, | 310 | }, |
312 | }, | 311 | }, |
313 | { | 312 | { |
314 | - title: '汇率收益¥', | ||
315 | - dataIndex: 'exchangeRateProfit', | ||
316 | - width: 120, | ||
317 | - customRender: (column) => { | ||
318 | - return column.record?.exchangeRateProfit?.toFixed(2); | ||
319 | - }, | ||
320 | - }, | ||
321 | - { | ||
322 | title: '综合收益¥', | 313 | title: '综合收益¥', |
323 | dataIndex: 'comprehensiveProfit', | 314 | dataIndex: 'comprehensiveProfit', |
324 | width: 120, | 315 | width: 120, |
@@ -381,4 +372,18 @@ export const COLUMNS = [ | @@ -381,4 +372,18 @@ export const COLUMNS = [ | ||
381 | return <FilePptOutlined style="font-size:25px" onClick={() => handleClick()} />; | 372 | return <FilePptOutlined style="font-size:25px" onClick={() => handleClick()} />; |
382 | }, | 373 | }, |
383 | }, | 374 | }, |
375 | + { | ||
376 | + title: '状态', | ||
377 | + dataIndex: 'status', | ||
378 | + width: 120, | ||
379 | + customRender: (column) => { | ||
380 | + if (column.record?.status === '-1') { | ||
381 | + return '未完成'; | ||
382 | + } else if (column.record?.status === '0') { | ||
383 | + return '待审核'; | ||
384 | + } else if (column.record?.status === '1') { | ||
385 | + return '已审核'; | ||
386 | + } | ||
387 | + }, | ||
388 | + }, | ||
384 | ]; | 389 | ]; |
385 | \ No newline at end of file | 390 | \ No newline at end of file |
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/index.vue
@@ -3,7 +3,10 @@ | @@ -3,7 +3,10 @@ | ||
3 | <BasicTable @register="registerTable" :bordered="true"> | 3 | <BasicTable @register="registerTable" :bordered="true"> |
4 | <template #bodyCell="{ column, record }"> | 4 | <template #bodyCell="{ column, record }"> |
5 | <template v-if="column.key === 'action'"> | 5 | <template v-if="column.key === 'action'"> |
6 | - <TableAction :actions="createActions(record)" /> | 6 | + <TableAction |
7 | + :actions="createActions(record)" | ||
8 | + :dropDownActions="createDropActions(record)" | ||
9 | + /> | ||
7 | </template> | 10 | </template> |
8 | <!-- <template v-if="column.key === 'relationValue'"> | 11 | <!-- <template v-if="column.key === 'relationValue'"> |
9 | <a-input | 12 | <a-input |
@@ -31,32 +34,39 @@ | @@ -31,32 +34,39 @@ | ||
31 | </BasicModal> --> | 34 | </BasicModal> --> |
32 | <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> | 35 | <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> |
33 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | 36 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> |
37 | + <HistoryDetail @register="registerHistoryDetail" /> | ||
34 | </div> | 38 | </div> |
35 | </template> | 39 | </template> |
36 | <script setup lang="ts"> | 40 | <script setup lang="ts"> |
37 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 41 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
38 | import { getServiceProfit } from '@/api/project/invoice'; | 42 | import { getServiceProfit } from '@/api/project/invoice'; |
39 | import { searchFormSchema, COLUMNS } from './data'; | 43 | import { searchFormSchema, COLUMNS } from './data'; |
40 | - import { BasicModal, useModal } from '/@/components/Modal'; | ||
41 | import { useMessage } from '/@/hooks/web/useMessage'; | 44 | import { useMessage } from '/@/hooks/web/useMessage'; |
42 | - import { onMounted, ref } from 'vue'; | 45 | + import { onMounted, ref, computed, unref } from 'vue'; |
43 | import { useDrawer } from '/@/components/Drawer'; | 46 | import { useDrawer } from '/@/components/Drawer'; |
44 | import FinanceEdit from './FinanceEdit.vue'; | 47 | import FinanceEdit from './FinanceEdit.vue'; |
48 | + import HistoryDetail from './HistoryDetail.vue'; | ||
45 | import CheckDetail from './CheckDetail.vue'; | 49 | import CheckDetail from './CheckDetail.vue'; |
50 | + import { useUserStoreWithOut } from '/@/store/modules/user'; | ||
51 | + import { ROLE } from '../../../type.d'; | ||
46 | import { useOrderStoreWithOut } from '/@/store/modules/order'; | 52 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
47 | 53 | ||
48 | const { createMessage } = useMessage(); | 54 | const { createMessage } = useMessage(); |
49 | - const { error } = createMessage; | ||
50 | const message = ref(); | 55 | const message = ref(); |
56 | + const checkedKeys = ref<string[]>([]); | ||
57 | + const invoiceIdKeys = ref<string[]>([]); | ||
58 | + const checkIdKeys = ref<string[]>([]); | ||
51 | const orderStore = useOrderStoreWithOut(); | 59 | const orderStore = useOrderStoreWithOut(); |
52 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); | 60 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); |
53 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); | 61 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); |
54 | - const handleClose = (visible: boolean) => { | ||
55 | - if (!visible) { | ||
56 | - message.value = ''; | ||
57 | - } | ||
58 | - }; | ||
59 | - const [registerTable, { reload }] = useTable({ | 62 | + const [registerHistoryDetail, { openDrawer: openHistoryDetail }] = useDrawer(); |
63 | + const userStore = useUserStoreWithOut(); | ||
64 | + const user = userStore.getUserInfo; | ||
65 | + const role = computed(() => { | ||
66 | + return user?.roleSmallVO?.code; | ||
67 | + }); | ||
68 | + const [registerTable, { reload, getSelectRowKeys, getDataSource, setSelectedRowKeys }] = useTable({ | ||
69 | + | ||
60 | api: getServiceProfit, | 70 | api: getServiceProfit, |
61 | bordered: true, | 71 | bordered: true, |
62 | columns: COLUMNS, | 72 | columns: COLUMNS, |
@@ -74,7 +84,7 @@ | @@ -74,7 +84,7 @@ | ||
74 | setting: false, | 84 | setting: false, |
75 | }, | 85 | }, |
76 | actionColumn: { | 86 | actionColumn: { |
77 | - width: 240, | 87 | + width: 260, |
78 | title: 'Action', | 88 | title: 'Action', |
79 | dataIndex: 'action', | 89 | dataIndex: 'action', |
80 | }, | 90 | }, |
@@ -82,7 +92,7 @@ | @@ -82,7 +92,7 @@ | ||
82 | 92 | ||
83 | function createActions(record: any): any[] { | 93 | function createActions(record: any): any[] { |
84 | if (!record.editable) { | 94 | if (!record.editable) { |
85 | - return [ | 95 | + const actions = [ |
86 | { | 96 | { |
87 | label: '财务编辑', | 97 | label: '财务编辑', |
88 | onClick: handleFinanceEdit.bind(null, record), | 98 | onClick: handleFinanceEdit.bind(null, record), |
@@ -106,7 +116,20 @@ | @@ -106,7 +116,20 @@ | ||
106 | // }, | 116 | // }, |
107 | onClick: handleFalse.bind(null, record), | 117 | onClick: handleFalse.bind(null, record), |
108 | }, | 118 | }, |
119 | + { | ||
120 | + label: '审核通过', | ||
121 | + popConfirm: { | ||
122 | + title: '确认审核?', | ||
123 | + confirm: () => { | ||
124 | + if (record.status === 0 && role.value === ROLE.ADMIN) { | ||
125 | + handleStatus(record, true); | ||
126 | + } | ||
127 | + return; | ||
128 | + }, | ||
129 | + }, | ||
130 | + }, | ||
109 | ]; | 131 | ]; |
132 | + return actions; | ||
110 | } | 133 | } |
111 | return [ | 134 | return [ |
112 | { | 135 | { |
@@ -122,6 +145,17 @@ | @@ -122,6 +145,17 @@ | ||
122 | }, | 145 | }, |
123 | ]; | 146 | ]; |
124 | } | 147 | } |
148 | + function createDropActions(record: any) { | ||
149 | + if (!record.editable) { | ||
150 | + const actions = [ | ||
151 | + { | ||
152 | + label: '历史记录', | ||
153 | + onClick: handleHistoryDetail.bind(null, record), | ||
154 | + }, | ||
155 | + ]; | ||
156 | + return actions; | ||
157 | + } | ||
158 | + } | ||
125 | 159 | ||
126 | onMounted(async () => { | 160 | onMounted(async () => { |
127 | await orderStore.getDict(); | 161 | await orderStore.getDict(); |
@@ -160,7 +194,6 @@ | @@ -160,7 +194,6 @@ | ||
160 | // error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | 194 | // error('请勿连续点击生成按钮,需要等待三秒再点击生成'); |
161 | // } else { | 195 | // } else { |
162 | record.onEdit?.(true); | 196 | record.onEdit?.(true); |
163 | - // } | ||
164 | } | 197 | } |
165 | 198 | ||
166 | function handleCancel(record) { | 199 | function handleCancel(record) { |
@@ -171,5 +204,21 @@ | @@ -171,5 +204,21 @@ | ||
171 | // await deleteConfig({ ids: [record.id] }); | 204 | // await deleteConfig({ ids: [record.id] }); |
172 | reload(); | 205 | reload(); |
173 | } | 206 | } |
207 | + | ||
208 | + async function handleStatus(record, status) { | ||
209 | + try { | ||
210 | + // You can implement the API call here | ||
211 | + // await someApiCall({ id: record.id, status }); | ||
212 | + reload(); | ||
213 | + } catch (error) { | ||
214 | + console.error('Error updating status:', error); | ||
215 | + } | ||
216 | + } | ||
217 | + | ||
218 | + async function handleHistoryDetail(record) { | ||
219 | + openHistoryDetail(true, { | ||
220 | + data: record, | ||
221 | + }); | ||
222 | + } | ||
174 | </script> | 223 | </script> |
175 | <style></style> | 224 | <style></style> |
src/views/project/finance/type.d.ts
0 → 100644
1 | +export enum ROLE { | ||
2 | + ADMIN = 'admin', // 超管 | ||
3 | + CUSTOM_ADMIN = 'custom_admin', // 客户管理员 | ||
4 | + DATA_REPORT_USER = 'data_report_user', //数据分析员 | ||
5 | + BUSINESS = 'business_user', // 业务员 | ||
6 | + TRACKER = 'tracker_user', // 跟单员 | ||
7 | + INSPECT = 'inspect_user', // 质检员 | ||
8 | + PRODUCE = 'produce_user', //生产科 | ||
9 | + FINANCE = 'finance_user', //财务 | ||
10 | +} |