Commit 78ec6a79d3b243399fbea8840a157e6d3ae89798
1 parent
b1027295
完成第三版与第四版
Showing
33 changed files
with
1270 additions
and
235 deletions
src/api/project/global.ts
... | ... | @@ -3,6 +3,9 @@ import { defHttp } from '/@/utils/http/axios'; |
3 | 3 | enum Api { |
4 | 4 | DATA = '/order/erp/index/data', |
5 | 5 | CHART_DATA = '/order/erp/index/chartData', |
6 | + | |
7 | + SALES_DATA = '/order/erp/index/totalSalesStatistics', //销售额完成情况 | |
8 | + CUSTOMER_SALES = '/order/erp/index/salesStatusEveryCustomer', //每个客户销售额情况 | |
6 | 9 | } |
7 | 10 | |
8 | 11 | export const getApiData = async () => { |
... | ... | @@ -14,3 +17,13 @@ export const getChartData = async () => { |
14 | 17 | const res = await defHttp.get<any>({ url: Api.CHART_DATA }); |
15 | 18 | return res; |
16 | 19 | }; |
20 | + | |
21 | +export const getSalesData = async (params?) => { | |
22 | + const res = await defHttp.get<any>({ url: Api.SALES_DATA, params }); | |
23 | + return res; | |
24 | +}; | |
25 | + | |
26 | +export const getCustomerSalesData = async (params?) => { | |
27 | + const res = await defHttp.get<any>({ url: Api.CUSTOMER_SALES, params }); | |
28 | + return res; | |
29 | +}; | ... | ... |
src/api/project/order.ts
... | ... | @@ -34,6 +34,13 @@ enum Api { |
34 | 34 | |
35 | 35 | TRACK_HISTORY = '/order/erp/opinion/log/query_by_id', //跟单结果记录 |
36 | 36 | PASS_CALCULATE = '/order/erp/order/passRate', //一次性通过率 |
37 | + CREATE_PRODUCT_TEXT = '/order/erp/order/produceReport', //生成生产指标书 | |
38 | + EXPORT_PRODUCT_TEXT = '/order/erp/order/send', //导出生产指标书 | |
39 | + | |
40 | + BUSINESS_PROFIT_RATIO = '/order/erp/calculate_profit/business_profit_ratio', //业务/研发净利润分析 | |
41 | + BUSINESS_PROFIT_RATIO_EXPORT = '/order/erp/calculate_profit/business_profit_ratio_export', //业务/研发净利润分析_导出 | |
42 | + INNER_PROFIT_RATIO = '/order/erp/calculate_profit/inner_profit_ratio', //内部生产净利润分析表 | |
43 | + INNER_PROFIT_RATIO_EXPORT = '/order/erp/calculate_profit/inner_profit_ratio_export', //内部生产净利润分析表_导出 | |
37 | 44 | } |
38 | 45 | |
39 | 46 | export const formatSearchData = (params) => { |
... | ... | @@ -315,3 +322,51 @@ export const passCalculate = async (data: any) => { |
315 | 322 | }); |
316 | 323 | return res; |
317 | 324 | }; |
325 | + | |
326 | +export const createProductText = async (data: any) => { | |
327 | + const res = await defHttp.post<any>({ | |
328 | + url: Api.CREATE_PRODUCT_TEXT, | |
329 | + data: data, | |
330 | + }); | |
331 | + return res; | |
332 | +}; | |
333 | + | |
334 | +export const exportProductText = async (data: any) => { | |
335 | + const res = await defHttp.post<any>({ | |
336 | + url: Api.EXPORT_PRODUCT_TEXT, | |
337 | + data: data, | |
338 | + }); | |
339 | + return res; | |
340 | +}; | |
341 | + | |
342 | +export const calculateBusinessProfit = async (data: any) => { | |
343 | + const res = await defHttp.post<any>({ | |
344 | + url: Api.BUSINESS_PROFIT_RATIO, | |
345 | + data: data, | |
346 | + }); | |
347 | + return res; | |
348 | +}; | |
349 | + | |
350 | +export const exportBusinessProfit = async (data: any) => { | |
351 | + const res = await defHttp.post<any>({ | |
352 | + url: Api.BUSINESS_PROFIT_RATIO_EXPORT, | |
353 | + data: data, | |
354 | + }); | |
355 | + return res; | |
356 | +}; | |
357 | + | |
358 | +export const calculateInnerProfitRatio = async (data: any) => { | |
359 | + const res = await defHttp.post<any>({ | |
360 | + url: Api.INNER_PROFIT_RATIO, | |
361 | + data: data, | |
362 | + }); | |
363 | + return res; | |
364 | +}; | |
365 | + | |
366 | +export const exportInnerProfitRatio = async (data: any) => { | |
367 | + const res = await defHttp.post<any>({ | |
368 | + url: Api.INNER_PROFIT_RATIO_EXPORT, | |
369 | + data: data, | |
370 | + }); | |
371 | + return res; | |
372 | +}; | ... | ... |
src/enums/roleEnum.ts
... | ... | @@ -5,4 +5,9 @@ export enum RoleEnum { |
5 | 5 | // tester |
6 | 6 | TEST = 'test', |
7 | 7 | DATA_REPORT_USER = 'data_report_user', |
8 | + BUSINESS = 'business_user', // 业务员 | |
9 | + TRACKER = 'tracker_user', // 跟单员 | |
10 | + INSPECT = 'inspect_user', // 质检员 | |
11 | + PRODUCE = 'produce_user', //生产科 | |
12 | + FINANCE = 'finance_user', //财务 | |
8 | 13 | } | ... | ... |
src/router/routes/modules/project/approve.ts
... | ... | @@ -10,6 +10,13 @@ const order: AppRouteModule = { |
10 | 10 | redirect: '/approve', |
11 | 11 | meta: { |
12 | 12 | hideChildrenInMenu: true, |
13 | + roles: [ | |
14 | + RoleEnum.ADMIN, | |
15 | + RoleEnum.DATA_REPORT_USER, | |
16 | + RoleEnum.BUSINESS, | |
17 | + RoleEnum.TRACKER, | |
18 | + RoleEnum.INSPECT, | |
19 | + ], | |
13 | 20 | orderNo: 3, |
14 | 21 | icon: 'ion:grid-outline', |
15 | 22 | title: '审批管理', | ... | ... |
src/router/routes/modules/project/finance.ts
src/store/modules/data.ts
... | ... | @@ -3,9 +3,16 @@ import type { UserInfo } from '/#/store'; |
3 | 3 | import { defineStore } from 'pinia'; |
4 | 4 | import { store } from '/@/store'; |
5 | 5 | import { RoleEnum } from '/@/enums/roleEnum'; |
6 | +import { exchangeTab } from '@/store/modules/user'; | |
6 | 7 | |
7 | -import { getApiData, getChartData } from '/@/api/project/global'; | |
8 | +import { | |
9 | + getApiData, | |
10 | + getChartData, | |
11 | + getSalesData, | |
12 | + getCustomerSalesData, | |
13 | +} from '/@/api/project/global'; | |
8 | 14 | import { formatToDate } from '/@/utils/dateUtil'; |
15 | +import { watch } from 'vue'; | |
9 | 16 | |
10 | 17 | interface UserState { |
11 | 18 | userInfo: Nullable<UserInfo>; |
... | ... | @@ -22,6 +29,10 @@ export const useDataStore = defineStore({ |
22 | 29 | data: {}, |
23 | 30 | // token |
24 | 31 | chartData: {}, |
32 | + //销售额完成情况 | |
33 | + salesData: {}, | |
34 | + //每个客户销售额 | |
35 | + customerChartData1: {}, | |
25 | 36 | }), |
26 | 37 | getters: { |
27 | 38 | getData(state) { |
... | ... | @@ -30,6 +41,12 @@ export const useDataStore = defineStore({ |
30 | 41 | getChartData(state) { |
31 | 42 | return state.chartData; |
32 | 43 | }, |
44 | + getSalesData(state) { | |
45 | + return state.salesData; | |
46 | + }, | |
47 | + getCustomerChartData1(state) { | |
48 | + return state.customerChartData1; | |
49 | + }, | |
33 | 50 | }, |
34 | 51 | actions: { |
35 | 52 | setData(info) { |
... | ... | @@ -38,6 +55,12 @@ export const useDataStore = defineStore({ |
38 | 55 | setChartData(data) { |
39 | 56 | this.chartData = data; |
40 | 57 | }, |
58 | + setSalesData(info) { | |
59 | + this.salesData = info ? info : ''; | |
60 | + }, | |
61 | + setCustomerChartData1(data) { | |
62 | + this.customerChartData1 = data; | |
63 | + }, | |
41 | 64 | |
42 | 65 | async getFetchData(): Promise<any> { |
43 | 66 | try { |
... | ... | @@ -47,6 +70,14 @@ export const useDataStore = defineStore({ |
47 | 70 | return Promise.reject(error); |
48 | 71 | } |
49 | 72 | }, |
73 | + async getFetchData2(): Promise<any> { | |
74 | + try { | |
75 | + const data = await getSalesData(); | |
76 | + this.salesData = data; | |
77 | + } catch (error) { | |
78 | + return Promise.reject(error); | |
79 | + } | |
80 | + }, | |
50 | 81 | async getFetchChartData(): Promise<any> { |
51 | 82 | try { |
52 | 83 | const data = await getChartData(); |
... | ... | @@ -61,6 +92,23 @@ export const useDataStore = defineStore({ |
61 | 92 | return Promise.reject(error); |
62 | 93 | } |
63 | 94 | }, |
95 | + async getCustomerSalesData1(): Promise<any> { | |
96 | + try { | |
97 | + const data = await getCustomerSalesData(); | |
98 | + | |
99 | + const x = [], | |
100 | + y = [], | |
101 | + z = []; | |
102 | + for (const key in data) { | |
103 | + x.push(key); | |
104 | + y.push(data[key].salesAmount); | |
105 | + z.push(data[key].target); | |
106 | + } | |
107 | + this.customerChartData1 = { x, y, z }; | |
108 | + } catch (error) { | |
109 | + return Promise.reject(error); | |
110 | + } | |
111 | + }, | |
64 | 112 | }, |
65 | 113 | }); |
66 | 114 | ... | ... |
src/store/modules/user.ts
... | ... | @@ -191,3 +191,9 @@ export function useUserStoreWithOut() { |
191 | 191 | |
192 | 192 | //分析台切换页面变量 |
193 | 193 | export const exchangeTab = ref('tab1'); |
194 | +//分析台时期 | |
195 | +// export const period = ref(''); | |
196 | +//分析台业务员 | |
197 | +export const businessPersonIn = ref(); | |
198 | +//分析台客户编码 | |
199 | +export const customerCodeIn = ref(); | ... | ... |
src/utils/project.ts
... | ... | @@ -13,8 +13,15 @@ export const getProfitDisable = (field, code, id, value) => { |
13 | 13 | }; |
14 | 14 | |
15 | 15 | // 基本信息的权限校验 客户编码、项目号、生产科、内部编号、业务员 才需要审核 |
16 | -export const getBaseDisable = (field, code, id) => { | |
17 | - if ( | |
16 | +//业务员可更改的权限:订单基本信息:客户编码、项目号、内部编码 | |
17 | +//跟单员可更改的权限:订单基本信息:客户po号、客户style、Mode(REFERENCE)、COLLECTION(style desciption)、PO COLOR、订单图片、颜色中文、生产要求、订单成分、款式类型、生产科拖货时间、订单上HOD时间、出库类型、包装类型 | |
18 | + | |
19 | +export const getBaseDisable = (field, code, id, role) => { | |
20 | + if (['picUrl', 'productionComment'].includes(field) && role == 'business_user') { | |
21 | + return code === 'LOCKED' && !!id; | |
22 | + } else if (!['customerCode', 'projectNo', 'innerNo'].includes(field) && role == 'business_user') { | |
23 | + return code === 'LOCKED' && !!id; | |
24 | + } else if ( | |
18 | 25 | [ |
19 | 26 | 'customerCode', |
20 | 27 | 'projectNo', |
... | ... | @@ -22,12 +29,28 @@ export const getBaseDisable = (field, code, id) => { |
22 | 29 | 'innerNo', |
23 | 30 | 'orderCount', |
24 | 31 | 'businessPerson', |
25 | - ].includes(field) | |
32 | + ].includes(field) && | |
33 | + (role === 'admin' || role === 'tracker_user') | |
26 | 34 | ) { |
27 | 35 | return code === 'LOCKED' && !!id; |
28 | 36 | } |
29 | 37 | return false; |
30 | 38 | }; |
39 | +// export const getBaseDisable = (field, code, id) => { | |
40 | +// if ( | |
41 | +// [ | |
42 | +// 'customerCode', | |
43 | +// 'projectNo', | |
44 | +// 'productionDepartment', | |
45 | +// 'innerNo', | |
46 | +// 'orderCount', | |
47 | +// 'businessPerson', | |
48 | +// ].includes(field) | |
49 | +// ) { | |
50 | +// return code === 'LOCKED' && !!id; | |
51 | +// } | |
52 | +// return false; | |
53 | +// }; | |
31 | 54 | |
32 | 55 | // 质量检测的disable函数 |
33 | 56 | // 中期验货:只要是PASS, PASS 2ND, PASS 3RD, FAIL-RELEASE,就锁定。 | ... | ... |
src/views/dashboard/analysis/components/GrowCard.vue
1 | 1 | <template> |
2 | - <div class="md:flex"> | |
2 | + <div class="md:flex" v-if="exchangeTab === 'tab1'"> | |
3 | 3 | <template v-for="(item, index) in growCardList" :key="item.title"> |
4 | 4 | <Card |
5 | 5 | size="small" |
... | ... | @@ -24,6 +24,21 @@ |
24 | 24 | </Card> |
25 | 25 | </template> |
26 | 26 | </div> |
27 | + <div class="md:flex" v-if="exchangeTab === 'tab2'"> | |
28 | + <template v-for="(item, index) in growCardList2" :key="item.title"> | |
29 | + <Card | |
30 | + size="small" | |
31 | + :loading="loading" | |
32 | + :title="item.title" | |
33 | + class="md:w-1/4 w-full !md:mt-0" | |
34 | + :class="{ '!md:mr-4': index + 1 < 5, '!mt-4': index > 0 }" | |
35 | + > | |
36 | + <div class="py-4 px-4 flex justify-between items-center" style="font-size: 20px"> | |
37 | + {{ item.value }} | |
38 | + </div> | |
39 | + </Card> | |
40 | + </template> | |
41 | + </div> | |
27 | 42 | </template> |
28 | 43 | <script lang="ts" setup> |
29 | 44 | import { CountTo } from '/@/components/CountTo/index'; |
... | ... | @@ -31,12 +46,17 @@ |
31 | 46 | import { Tag, Card } from 'ant-design-vue'; |
32 | 47 | import { growCardList } from '../data'; |
33 | 48 | import { useDataStoreWithOut } from '/@/store/modules/data'; |
34 | - import { computed } from 'vue'; | |
49 | + import { computed, onMounted, ref, watch, watchEffect } from 'vue'; | |
50 | + import { exchangeTab, businessPersonIn, customerCodeIn } from '/@/store/modules/user'; | |
51 | + import { number } from 'vue-types'; | |
52 | + import { getSalesData, getCustomerSalesData } from '/@/api/project/global'; | |
53 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
35 | 54 | |
36 | 55 | const dataStore = useDataStoreWithOut(); |
37 | 56 | |
38 | 57 | const growCardList = computed(() => { |
39 | 58 | const data = dataStore.getData; |
59 | + | |
40 | 60 | return [ |
41 | 61 | { |
42 | 62 | title: '订单完成', |
... | ... | @@ -80,10 +100,83 @@ |
80 | 100 | }, |
81 | 101 | ]; |
82 | 102 | }); |
103 | + const data2 = ref(); | |
104 | + // watchEffect(async () => { | |
105 | + // data2.value = await getSalesData({ | |
106 | + // businessPersonIn: businessPersonIn, | |
107 | + // customerCodeIn: customerCodeIn, | |
108 | + // }); | |
109 | + // }); | |
110 | + onMounted(async () => { | |
111 | + data2.value = await getSalesData({ | |
112 | + businessPersonIn: businessPersonIn.value, | |
113 | + customerCodeIn: customerCodeIn.value, | |
114 | + }); | |
115 | + }); | |
116 | + watch( | |
117 | + [businessPersonIn, customerCodeIn], | |
118 | + async ([newBusinessPersonIn, newCustomerCodeIn], [oldBusinessPersonIn, oldCustomerCodeIn]) => { | |
119 | + console.log('businessPersonIn changed from', oldBusinessPersonIn, 'to', newBusinessPersonIn); | |
120 | + console.log('customerCodeIn changed from', oldCustomerCodeIn, 'to', newCustomerCodeIn); | |
121 | + | |
122 | + // 在这里添加你希望在这两个值改变时执行的逻辑 | |
123 | + data2.value = await getSalesData({ | |
124 | + businessPersonIn: newBusinessPersonIn, | |
125 | + customerCodeIn: newCustomerCodeIn, | |
126 | + }); | |
127 | + }, | |
128 | + ); | |
129 | + const growCardList2 = computed(() => { | |
130 | + return [ | |
131 | + { | |
132 | + title: '总销售额', | |
133 | + icon: 'visit-count|svg', | |
134 | + value: data2.value?.yearlySalesAmountTarget || 0, | |
135 | + total: 120000, | |
136 | + color: 'green', | |
137 | + action: '年', | |
138 | + }, | |
139 | + { | |
140 | + title: '总销售额完成率', | |
141 | + icon: 'visit-count|svg', | |
142 | + value: data2.value?.yearlySalesAmountCompletionRate || 0, | |
143 | + total: 120000, | |
144 | + color: 'green', | |
145 | + action: '年', | |
146 | + }, | |
147 | + { | |
148 | + title: '每月销售额目标', | |
149 | + icon: 'visit-count|svg', | |
150 | + value: data2.value?.monthlySalesAmountTarget || 0, | |
151 | + total: 120000, | |
152 | + color: 'green', | |
153 | + action: '月', | |
154 | + }, | |
155 | + { | |
156 | + title: '当月销售额完成率', | |
157 | + icon: 'visit-count|svg', | |
158 | + value: data2.value?.monthlySalesAmountCompletionRate || 0, | |
159 | + total: 120000, | |
160 | + color: 'green', | |
161 | + action: '月', | |
162 | + }, | |
163 | + { | |
164 | + title: '今日销售额', | |
165 | + icon: 'visit-count|svg', | |
166 | + value: data2.value?.daylySalesAmount || 0, | |
167 | + total: 120000, | |
168 | + color: 'green', | |
169 | + action: '日', | |
170 | + }, | |
171 | + ]; | |
172 | + }); | |
83 | 173 | |
84 | 174 | defineProps({ |
85 | 175 | loading: { |
86 | 176 | type: Boolean, |
87 | 177 | }, |
178 | + exchangeTab: { | |
179 | + type: String, | |
180 | + }, | |
88 | 181 | }); |
89 | 182 | </script> | ... | ... |
src/views/dashboard/analysis/components/SiteAnalysis.vue
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | <VisitAnalysis /> |
10 | 10 | </p> |
11 | 11 | <p v-if="activeKey === 'tab2'"> |
12 | - <VisitAnalysisBar /> | |
12 | + <VisitAnalysisBar style="margin-top: 100px" /> | |
13 | 13 | </p> |
14 | 14 | </Card> |
15 | 15 | </template> |
... | ... | @@ -19,6 +19,7 @@ |
19 | 19 | import VisitAnalysis from './VisitAnalysis.vue'; |
20 | 20 | import VisitAnalysisBar from './VisitAnalysisBar.vue'; |
21 | 21 | import { exchangeTab } from '@/store/modules/user'; |
22 | + import type { SelectProps } from 'ant-design-vue'; | |
22 | 23 | |
23 | 24 | const activeKey = ref('tab1'); |
24 | 25 | |
... | ... | @@ -38,3 +39,29 @@ |
38 | 39 | exchangeTab.value = key; |
39 | 40 | } |
40 | 41 | </script> |
42 | +<style scoped> | |
43 | + .custom-radio-group .ant-radio-button-wrapper { | |
44 | + background-color: white; /* 未选中按钮的背景颜色为白色 */ | |
45 | + color: #1684fc; /* 未选中按钮的文字颜色为 #1684fc */ | |
46 | + border-color: #1684fc; /* 未选中按钮的边框颜色 */ | |
47 | + } | |
48 | + | |
49 | + .custom-radio-group .ant-radio-button-wrapper-checked { | |
50 | + background-color: #1684fc; /* 选中按钮的背景颜色为 #1684fc */ | |
51 | + color: white; /* 选中按钮的文字颜色为白色 */ | |
52 | + border-color: #1684fc; /* 选中按钮的边框颜色 */ | |
53 | + } | |
54 | + | |
55 | + .custom-radio-group .ant-radio-button-wrapper-checked:hover { | |
56 | + background-color: #1684fc; /* 悬停在选中按钮时保持相同的背景颜色 */ | |
57 | + color: white; /* 悬停在选中按钮时保持文字为白色 */ | |
58 | + } | |
59 | + | |
60 | + .custom-radio-group .ant-radio-button-wrapper:hover { | |
61 | + border-color: #1684fc; /* 悬停在未选中按钮时的边框颜色 */ | |
62 | + } | |
63 | + | |
64 | + .custom-radio-group .ant-radio-button-wrapper:not(.ant-radio-button-wrapper-checked):hover { | |
65 | + color: #1684fc; /* 悬停在未选中按钮时文字颜色为 #1684fc */ | |
66 | + } | |
67 | +</style> | ... | ... |
src/views/dashboard/analysis/components/VisitAnalysisBar.vue
1 | 1 | <template> |
2 | + <div style="margin-bottom: 30px"> | |
3 | + <span v-if="role === ROLE.ADMIN"> | |
4 | + <span style="font-size: 18px; margin-right: 10px">业务员</span> | |
5 | + <a-select | |
6 | + v-model:value="value1" | |
7 | + show-search | |
8 | + placeholder="请选择" | |
9 | + style="width: 200px" | |
10 | + :options="customerCodeOptions" | |
11 | + :filter-option="filterOption" | |
12 | + @focus="handleFocus" | |
13 | + @blur="handleBlur" | |
14 | + @change="handleChangeBusiness" | |
15 | + /> | |
16 | + <span style="font-size: 18px; margin-left: 50px; margin-right: 10px">客户编码</span> | |
17 | + <a-select | |
18 | + v-model:value="value2" | |
19 | + show-search | |
20 | + placeholder="请选择" | |
21 | + style="width: 200px" | |
22 | + :options="businessPersonOptions" | |
23 | + :filter-option="filterOption" | |
24 | + @focus="handleFocus" | |
25 | + @blur="handleBlur" | |
26 | + @change="handleChangeCustomer" | |
27 | + /> | |
28 | + <span style="right: 10px" | |
29 | + ><a-button | |
30 | + type="default" | |
31 | + @click="clearData" | |
32 | + :style="{ marginLeft: '100px', borderRadius: '5px 5px 5px 5px' }" | |
33 | + > | |
34 | + 重置 | |
35 | + </a-button> | |
36 | + <a-button | |
37 | + :style="{ marginLeft: '20px', borderRadius: '5px 5px 5px 5px' }" | |
38 | + shape="default" | |
39 | + type="primary" | |
40 | + @click="updateData" | |
41 | + >查询</a-button | |
42 | + ></span | |
43 | + ></span | |
44 | + > | |
45 | + <div style="position: fixed; top: 80px; right: 70px"> | |
46 | + <a-radio-group | |
47 | + v-model:value="periodChange" | |
48 | + class="custom-radio-group" | |
49 | + :style="{ marginLeft: '100px' }" | |
50 | + > | |
51 | + <a-radio-button value="MONTH" @click="handlePeriodChange('MONTH')">月</a-radio-button> | |
52 | + <a-radio-button value="QUARTER" @click="handlePeriodChange('QUARTER')">季度</a-radio-button> | |
53 | + <a-radio-button value="YEAR" @click="handlePeriodChange('YEAR')">年</a-radio-button> | |
54 | + </a-radio-group> | |
55 | + </div></div | |
56 | + > | |
57 | + <div v-if="role !== ROLE.ADMIN" style="margin-bottom: 60px"></div> | |
2 | 58 | <div ref="chartRef" :style="{ height, width }"></div> |
3 | 59 | </template> |
4 | 60 | <script lang="ts"> |
5 | 61 | import { basicProps } from './props'; |
6 | 62 | </script> |
7 | 63 | <script lang="ts" setup> |
8 | - import { onMounted, ref, Ref } from 'vue'; | |
64 | + import { computed, onMounted, ref, Ref, watchEffect } from 'vue'; | |
9 | 65 | import { useECharts } from '/@/hooks/web/useECharts'; |
66 | + import { useDataStoreWithOut } from '/@/store/modules/data'; | |
67 | + import { businessPersonIn, customerCodeIn, useUserStoreWithOut } from '@/store/modules/user'; | |
68 | + | |
69 | + //biaoji | |
70 | + import type { SelectProps } from 'ant-design-vue'; | |
71 | + import { getCustomerSalesData } from '/@/api/project/global'; | |
72 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
73 | + import { useOrderInfo } from '/@/hooks/component/order'; | |
74 | + import { ROLE } from '/@/views/project/order/type.d'; | |
75 | + | |
76 | + const userStore = useUserStoreWithOut(); | |
77 | + const user = userStore.getUserInfo; | |
78 | + const role = computed(() => { | |
79 | + return user?.roleSmallVO?.code; | |
80 | + }); | |
81 | + const orderStore = useOrderStoreWithOut(); | |
82 | + console.log(orderStore, '5656order'); | |
83 | + onMounted(async () => { | |
84 | + await orderStore.getDict(); | |
85 | + }); | |
86 | + const { customerCode: customerCodeOptions, businessPerson: businessPersonOptions } = | |
87 | + useOrderInfo(orderStore); | |
88 | + | |
89 | + const periodChange = ref('MONTH'); | |
90 | + // const businessPersonInChange = ref(); | |
91 | + const businessPersonInChange: string[] = []; | |
92 | + const customerCodeInChange: string[] = []; | |
93 | + const handleChangeBusiness = (value: string) => { | |
94 | + if (businessPersonInChange.length === 0) { | |
95 | + // 如果数组为空,直接将 value 值放入数组 | |
96 | + businessPersonInChange.push(value); | |
97 | + } else { | |
98 | + // 如果数组不为空,清空数组再将 value 值放入数组 | |
99 | + businessPersonInChange.length = 0; // 也可以使用 array.splice(0, array.length); | |
100 | + businessPersonInChange.push(value); | |
101 | + } | |
102 | + console.log(`5656selected ${businessPersonInChange}`); | |
103 | + }; | |
104 | + const handleChangeCustomer = (value: string) => { | |
105 | + if (customerCodeInChange.length === 0) { | |
106 | + // 如果数组为空,直接将 value 值放入数组 | |
107 | + customerCodeInChange.push(value); | |
108 | + } else { | |
109 | + // 如果数组不为空,清空数组再将 value 值放入数组 | |
110 | + customerCodeInChange.length = 0; // 也可以使用 array.splice(0, array.length); | |
111 | + customerCodeInChange.push(value); | |
112 | + } | |
113 | + console.log(`5656selected ${customerCodeInChange}`); | |
114 | + }; | |
115 | + const handleBlur = () => { | |
116 | + console.log('5656blur'); | |
117 | + }; | |
118 | + const handleFocus = () => { | |
119 | + console.log('5656focus'); | |
120 | + }; | |
121 | + const filterOption = (input: string, option: any) => { | |
122 | + return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0; | |
123 | + }; | |
124 | + | |
125 | + const value1 = ref(); | |
126 | + const value2 = ref(); | |
127 | + | |
128 | + function handlePeriodChange(value) { | |
129 | + periodChange.value = value; | |
130 | + } | |
131 | + //biaoji | |
10 | 132 | |
11 | 133 | defineProps({ |
12 | 134 | ...basicProps, |
13 | 135 | }); |
136 | + const dataStore = useDataStoreWithOut(); | |
14 | 137 | |
15 | 138 | const chartRef = ref<HTMLDivElement | null>(null); |
16 | 139 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); |
17 | - onMounted(() => { | |
140 | + | |
141 | + function updateData() { | |
142 | + customerCodeIn.value = value1.value; | |
143 | + businessPersonIn.value = value2.value; | |
144 | + } | |
145 | + function clearData() { | |
146 | + customerCodeIn.value = null; | |
147 | + businessPersonIn.value = null; | |
148 | + value1.value = null; | |
149 | + value2.value = null; | |
150 | + } | |
151 | + | |
152 | + watchEffect(async () => { | |
153 | + // const data1 = dataStore?.getCustomerChartData1 || {}; | |
154 | + console.log(periodChange.value, '56565656periodChange'); | |
155 | + const data2 = await getCustomerSalesData({ | |
156 | + businessPersonIn: businessPersonIn.value, | |
157 | + customerCodeIn: customerCodeIn.value, | |
158 | + period: periodChange.value, | |
159 | + }); | |
160 | + console.log(data2, '5656data2'); | |
161 | + const x = [], | |
162 | + y = [], | |
163 | + z = []; | |
164 | + for (const key in data2) { | |
165 | + x.push(key); | |
166 | + y.push(data2[key].salesAmount); | |
167 | + z.push(data2[key].target); | |
168 | + } | |
169 | + const customerChartData1 = { x, y, z }; | |
18 | 170 | setOptions({ |
19 | 171 | tooltip: { |
20 | 172 | trigger: 'axis', |
... | ... | @@ -28,22 +180,22 @@ |
28 | 180 | grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, |
29 | 181 | xAxis: { |
30 | 182 | type: 'category', |
31 | - data: [...new Array(12)].map((_item, index) => `${index + 1}月`), | |
183 | + data: customerChartData1?.x, | |
32 | 184 | }, |
33 | 185 | yAxis: { |
34 | 186 | type: 'value', |
35 | - max: 8000, | |
187 | + // max: 8000, | |
36 | 188 | splitNumber: 4, |
37 | 189 | }, |
38 | 190 | series: [ |
39 | 191 | { |
40 | - data: [3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000, 3200, 4800], | |
192 | + data: customerChartData1?.y, | |
41 | 193 | type: 'bar', |
42 | 194 | barMaxWidth: 80, |
43 | 195 | }, |
44 | 196 | { |
45 | 197 | smooth: true, |
46 | - data: [111, 222, 4000, 1800, 3333, 555, 666, 333], | |
198 | + data: customerChartData1?.z, | |
47 | 199 | type: 'line', |
48 | 200 | areaStyle: { |
49 | 201 | color: 'rgba(255, 255, 255, 0)', |
... | ... | @@ -56,3 +208,29 @@ |
56 | 208 | }); |
57 | 209 | }); |
58 | 210 | </script> |
211 | +<style scoped> | |
212 | + .custom-radio-group .ant-radio-button-wrapper { | |
213 | + background-color: white; /* 未选中按钮的背景颜色为白色 */ | |
214 | + color: #1684fc; /* 未选中按钮的文字颜色为 #1684fc */ | |
215 | + border-color: #1684fc; /* 未选中按钮的边框颜色 */ | |
216 | + } | |
217 | + | |
218 | + .custom-radio-group .ant-radio-button-wrapper-checked { | |
219 | + background-color: #1684fc; /* 选中按钮的背景颜色为 #1684fc */ | |
220 | + color: white; /* 选中按钮的文字颜色为白色 */ | |
221 | + border-color: #1684fc; /* 选中按钮的边框颜色 */ | |
222 | + } | |
223 | + | |
224 | + .custom-radio-group .ant-radio-button-wrapper-checked:hover { | |
225 | + background-color: #1684fc; /* 悬停在选中按钮时保持相同的背景颜色 */ | |
226 | + color: white; /* 悬停在选中按钮时保持文字为白色 */ | |
227 | + } | |
228 | + | |
229 | + .custom-radio-group .ant-radio-button-wrapper:hover { | |
230 | + border-color: #1684fc; /* 悬停在未选中按钮时的边框颜色 */ | |
231 | + } | |
232 | + | |
233 | + .custom-radio-group .ant-radio-button-wrapper:not(.ant-radio-button-wrapper-checked):hover { | |
234 | + color: #1684fc; /* 悬停在未选中按钮时文字颜色为 #1684fc */ | |
235 | + } | |
236 | +</style> | ... | ... |
src/views/dashboard/analysis/data.ts
... | ... | @@ -49,3 +49,54 @@ export const growCardList: GrowCardItem[] = [ |
49 | 49 | action: '年', |
50 | 50 | }, |
51 | 51 | ]; |
52 | + | |
53 | +export const growCardList2: GrowCardItem[] = [ | |
54 | + { | |
55 | + title: '总销售额', | |
56 | + icon: 'visit-count|svg', | |
57 | + value: 2000, | |
58 | + total: 120000, | |
59 | + color: 'green', | |
60 | + action: '年', | |
61 | + }, | |
62 | + { | |
63 | + title: '总销售额完成率', | |
64 | + icon: 'visit-count|svg', | |
65 | + value: 2000, | |
66 | + total: 120000, | |
67 | + color: 'green', | |
68 | + action: '年', | |
69 | + }, | |
70 | + { | |
71 | + title: '每月销售额目标', | |
72 | + icon: 'visit-count|svg', | |
73 | + value: 2000, | |
74 | + total: 120000, | |
75 | + color: 'green', | |
76 | + action: '月', | |
77 | + }, | |
78 | + { | |
79 | + title: '当月销售额完成率', | |
80 | + icon: 'visit-count|svg', | |
81 | + value: 2000, | |
82 | + total: 120000, | |
83 | + color: 'green', | |
84 | + action: '月', | |
85 | + }, | |
86 | + { | |
87 | + title: '当月销售额完成率', | |
88 | + icon: 'visit-count|svg', | |
89 | + value: 2000, | |
90 | + total: 120000, | |
91 | + color: 'green', | |
92 | + action: '日', | |
93 | + }, | |
94 | + { | |
95 | + title: '今日销售额', | |
96 | + icon: 'visit-count|svg', | |
97 | + value: 2000, | |
98 | + total: 120000, | |
99 | + color: 'green', | |
100 | + action: '日', | |
101 | + }, | |
102 | +]; | ... | ... |
src/views/dashboard/analysis/index.vue
1 | 1 | <template> |
2 | 2 | <div class="p-4"> |
3 | - <GrowCard :loading="loading" class="enter-y" /> | |
3 | + <GrowCard :loading="loading" class="enter-y" :exchangeTab="exchangeTab" /> | |
4 | 4 | <SiteAnalysis class="!my-4 enter-y" :loading="loading" /> |
5 | 5 | <!-- <div class="md:flex enter-y"> |
6 | 6 | <VisitRadar class="md:w-1/3 w-full" :loading="loading" /> |
... | ... | @@ -20,13 +20,14 @@ |
20 | 20 | const dataStore = useDataStoreWithOut(); |
21 | 21 | watch( |
22 | 22 | () => exchangeTab.value, |
23 | - () => { | |
24 | - console.log(exchangeTab.value, 56562); | |
25 | - }, | |
23 | + () => {}, | |
26 | 24 | ); |
27 | 25 | onMounted(() => { |
28 | 26 | dataStore.getFetchData(); |
27 | + dataStore.getFetchData2(); | |
29 | 28 | dataStore.getFetchChartData(); |
29 | + dataStore.getCustomerSalesData1(); | |
30 | + exchangeTab.value; | |
30 | 31 | }); |
31 | 32 | |
32 | 33 | setTimeout(() => { | ... | ... |
src/views/project/approve/PayPanel.vue
... | ... | @@ -122,25 +122,22 @@ |
122 | 122 | dataIndex: 'createBy', |
123 | 123 | width: 150, |
124 | 124 | }, |
125 | - // { | |
126 | - // title: '内部编号', | |
127 | - // dataIndex: 'innerNo', | |
128 | - // width: 150, | |
129 | - // customRender: (column) => { | |
130 | - // const { record } = column || {}; | |
131 | - // return record?.fieldInfos?.invoiceBillOrderDO?.innerNo; | |
132 | - // }, | |
133 | - // }, | |
134 | 125 | { |
135 | - title: 'INVOICE编号', | |
136 | - dataIndex: 'invoiceNo', | |
126 | + title: '内部编号', | |
127 | + dataIndex: 'innerNo', | |
137 | 128 | width: 150, |
138 | 129 | customRender: (column) => { |
139 | 130 | const { record } = column || {}; |
140 | - return record?.fieldInfos?.invoiceBillOrderDO?.invoiceNo; | |
131 | + console.log(record, '56565repro'); | |
132 | + return record?.fieldInfos?.invoiceBillOrderDO?.innerNo; | |
141 | 133 | }, |
142 | 134 | }, |
143 | 135 | { |
136 | + title: '审核类型', | |
137 | + dataIndex: 'productionDepartment', | |
138 | + width: 150, | |
139 | + }, | |
140 | + { | |
144 | 141 | title: '生产科', |
145 | 142 | dataIndex: 'productionDepartment', |
146 | 143 | width: 150, | ... | ... |
src/views/project/approve/ReceivePanel.vue
... | ... | @@ -127,10 +127,20 @@ |
127 | 127 | dataIndex: 'invoiceNo', |
128 | 128 | width: 150, |
129 | 129 | customRender: (column) => { |
130 | + console.log(column, '5656coapprove'); | |
130 | 131 | const { record } = column || {}; |
131 | 132 | return record?.fieldInfos?.invoiceBillOrderDO?.invoiceNo; |
132 | 133 | }, |
133 | 134 | }, |
135 | + { | |
136 | + title: '内部编号', | |
137 | + dataIndex: 'innerNo', | |
138 | + width: 150, | |
139 | + customRender: (column) => { | |
140 | + const { record } = column || {}; | |
141 | + return record?.fieldInfos?.invoiceBillOrderDO?.innnerNo; | |
142 | + }, | |
143 | + }, | |
134 | 144 | // { |
135 | 145 | // title: '内部编号', |
136 | 146 | // dataIndex: 'innerNo', | ... | ... |
src/views/project/config/CreateModal.vue
src/views/project/config/DrawerCreate.vue
... | ... | @@ -66,24 +66,24 @@ |
66 | 66 | event: 'LATEST_DC_EVENT', |
67 | 67 | emails: [], |
68 | 68 | }, |
69 | - // { | |
70 | - // fieldName: '尾期验货日期', | |
71 | - // fieldValue: 'endCheckDate', | |
72 | - // event: 'END_CHECK_DATE_EVENT', | |
73 | - // emails: [], | |
74 | - // }, | |
75 | - // { | |
76 | - // fieldName: '中期验货报告', | |
77 | - // fieldValue: 'midCheckReport', | |
78 | - // event: 'MID_CHECK_REPORT_EVENT', | |
79 | - // emails: [], | |
80 | - // }, | |
81 | - // { | |
82 | - // fieldName: '尾期验货报告', | |
83 | - // fieldValue: 'endCheckReport', | |
84 | - // event: 'END_CHECK_REPORT_EVENT', | |
85 | - // emails: [], | |
86 | - // }, | |
69 | + { | |
70 | + fieldName: '尾期验货日期', | |
71 | + fieldValue: 'endCheckDate', | |
72 | + event: 'END_CHECK_DATE_EVENT', | |
73 | + emails: [], | |
74 | + }, | |
75 | + { | |
76 | + fieldName: '中期验货报告', | |
77 | + fieldValue: 'midCheckReport', | |
78 | + event: 'MID_CHECK_REPORT_EVENT', | |
79 | + emails: [], | |
80 | + }, | |
81 | + { | |
82 | + fieldName: '尾期验货报告', | |
83 | + fieldValue: 'endCheckReport', | |
84 | + event: 'END_CHECK_REPORT_EVENT', | |
85 | + emails: [], | |
86 | + }, | |
87 | 87 | ]; |
88 | 88 | const schemas: FormSchema[] = [ |
89 | 89 | { | ... | ... |
src/views/project/config/DrawerEdit.vue
... | ... | @@ -103,36 +103,36 @@ |
103 | 103 | label: '最晚订舱时间(填写邮箱)', |
104 | 104 | rules: [{ required: true }], |
105 | 105 | }, |
106 | - // { | |
107 | - // field: 'endCheckDate', | |
108 | - // component: 'InputTextArea', | |
109 | - // labelWidth: 250, | |
110 | - // colProps: { | |
111 | - // span: 23, | |
112 | - // }, | |
113 | - // label: '尾期验货日期(填写邮箱)', | |
114 | - // rules: [{ required: true }], | |
115 | - // }, | |
116 | - // { | |
117 | - // field: 'midCheckReport', | |
118 | - // component: 'InputTextArea', | |
119 | - // labelWidth: 250, | |
120 | - // colProps: { | |
121 | - // span: 23, | |
122 | - // }, | |
123 | - // label: '中期验货报告(填写邮箱)', | |
124 | - // rules: [{ required: true }], | |
125 | - // }, | |
126 | - // { | |
127 | - // field: 'endCheckReport', | |
128 | - // component: 'InputTextArea', | |
129 | - // labelWidth: 250, | |
130 | - // colProps: { | |
131 | - // span: 23, | |
132 | - // }, | |
133 | - // label: '尾期验货报告(填写邮箱)', | |
134 | - // rules: [{ required: true }], | |
135 | - // }, | |
106 | + { | |
107 | + field: 'endCheckDate', | |
108 | + component: 'InputTextArea', | |
109 | + labelWidth: 250, | |
110 | + colProps: { | |
111 | + span: 23, | |
112 | + }, | |
113 | + label: '尾期验货日期(填写邮箱)', | |
114 | + rules: [{ required: true }], | |
115 | + }, | |
116 | + { | |
117 | + field: 'midCheckReport', | |
118 | + component: 'InputTextArea', | |
119 | + labelWidth: 250, | |
120 | + colProps: { | |
121 | + span: 23, | |
122 | + }, | |
123 | + label: '中期验货报告(填写邮箱)', | |
124 | + rules: [{ required: true }], | |
125 | + }, | |
126 | + { | |
127 | + field: 'endCheckReport', | |
128 | + component: 'InputTextArea', | |
129 | + labelWidth: 250, | |
130 | + colProps: { | |
131 | + span: 23, | |
132 | + }, | |
133 | + label: '尾期验货报告(填写邮箱)', | |
134 | + rules: [{ required: true }], | |
135 | + }, | |
136 | 136 | { |
137 | 137 | field: 'id', |
138 | 138 | }, | ... | ... |
src/views/project/config/TablePanel.vue
... | ... | @@ -84,7 +84,6 @@ |
84 | 84 | } |
85 | 85 | |
86 | 86 | async function handleSave(record) { |
87 | - console.log(record, '5656s'); | |
88 | 87 | if (props.column === 3) { |
89 | 88 | await saveConfig({ id: record.id, settingValue: record.settingValue }); |
90 | 89 | } else { |
... | ... | @@ -95,7 +94,6 @@ |
95 | 94 | } |
96 | 95 | |
97 | 96 | function handleEdit(record: any) { |
98 | - console.log(record, '5656e'); | |
99 | 97 | record.onEdit?.(true); |
100 | 98 | } |
101 | 99 | |
... | ... | @@ -104,7 +102,6 @@ |
104 | 102 | } |
105 | 103 | |
106 | 104 | function handleModalSuccess() { |
107 | - console.log('5656ss'); | |
108 | 105 | reload(); |
109 | 106 | } |
110 | 107 | ... | ... |
src/views/project/config/data.tsx
... | ... | @@ -158,21 +158,21 @@ export const columns: BasicColumn[] = [ |
158 | 158 | dataIndex: 'latestDc', |
159 | 159 | width: 300, |
160 | 160 | }, |
161 | - // { | |
162 | - // title: '尾期验货日期', | |
163 | - // dataIndex: 'endCheckDate', | |
164 | - // width: 300, | |
165 | - // }, | |
166 | - // { | |
167 | - // title: '中期验货报告', | |
168 | - // dataIndex: 'midCheckReport', | |
169 | - // width: 300, | |
170 | - // }, | |
171 | - // { | |
172 | - // title: '尾期验货报告', | |
173 | - // dataIndex: 'endCheckReport', | |
174 | - // width: 300, | |
175 | - // }, | |
161 | + { | |
162 | + title: '尾期验货日期', | |
163 | + dataIndex: 'endCheckDate', | |
164 | + width: 300, | |
165 | + }, | |
166 | + { | |
167 | + title: '中期验货报告', | |
168 | + dataIndex: 'midCheckReport', | |
169 | + width: 300, | |
170 | + }, | |
171 | + { | |
172 | + title: '尾期验货报告', | |
173 | + dataIndex: 'endCheckReport', | |
174 | + width: 300, | |
175 | + }, | |
176 | 176 | ]; |
177 | 177 | |
178 | 178 | export const columnsProduct: BasicColumn[] = [ | ... | ... |
src/views/project/finance/pay/index.vue
... | ... | @@ -220,7 +220,7 @@ |
220 | 220 | // 单选函数 |
221 | 221 | async function onSelect(record, selected: boolean) { |
222 | 222 | const res = await checkDetail({ checkNo: record.checkNo }); |
223 | - | |
223 | + console.log(res, '5656respau'); | |
224 | 224 | const customerCode = res[0].customerCode; |
225 | 225 | const productionDepartment = res[0].productionDepartment; |
226 | 226 | ... | ... |
src/views/project/finance/receive/type.d.ts
src/views/project/order/ExportModal.vue
... | ... | @@ -125,6 +125,10 @@ |
125 | 125 | [item.dataIndex]: 'selected', |
126 | 126 | })); |
127 | 127 | fieldVO.baseFields = merge({}, ...fieldVO.baseFields); |
128 | + if (props.role === ROLE.PRODUCE) { | |
129 | + // 从 baseFields 中去除 orderHod | |
130 | + delete fieldVO.baseFields['orderHodTime']; | |
131 | + } | |
128 | 132 | } else if (item === 'reportFields') { |
129 | 133 | fieldVO.reportFields = ORDER_LIST_REPORT_FIELDS[0].children.map((item) => ({ |
130 | 134 | [item.dataIndex]: 'selected', | ... | ... |
src/views/project/order/FormDetail/BaseFormPanel.vue
... | ... | @@ -165,6 +165,12 @@ |
165 | 165 | }, |
166 | 166 | componentProps: { |
167 | 167 | imgUrl: picUrl.value, |
168 | + disabled: getBaseDisable( | |
169 | + item.field, | |
170 | + get(fields.value, `${item.field}`), | |
171 | + props.id, | |
172 | + role.value, | |
173 | + ), | |
168 | 174 | // disabled: getDisable(get(fields.value, 'picUrl'), props.id), |
169 | 175 | onChange: (res) => { |
170 | 176 | if (res.file?.response?.data) { |
... | ... | @@ -178,38 +184,89 @@ |
178 | 184 | }, |
179 | 185 | }; |
180 | 186 | } |
181 | - const businessNotDisabledFields = ['customerCode', 'projectNo', 'innerNo']; | |
182 | - const trackerNotDisabledFields = [ | |
183 | - 'customerPo', | |
184 | - 'customerStyle', | |
185 | - 'modeleLo', | |
186 | - 'collection', | |
187 | - 'poColor', | |
188 | - 'cnColor', | |
189 | - 'picUrl', | |
190 | - 'productStyle', | |
191 | - 'orderComposition', | |
192 | - 'productionDepartmentConsignTime', | |
193 | - 'orderHodTime', | |
194 | - 'outboundType', | |
195 | - 'packetType', | |
196 | - 'productionComment', | |
197 | - ]; | |
198 | - const isFieldNotDisabledForBusiness = businessNotDisabledFields.includes(item.field); | |
199 | - const isFieldNotDisabledForTracker = trackerNotDisabledFields.includes(item.field); | |
187 | + if (item.field === 'productionComment') { | |
188 | + return { | |
189 | + field: 'productionComment', | |
190 | + component: 'InputTextArea', | |
191 | + rules: [{ required: true }], | |
192 | + componentProps: { | |
193 | + rows: 10, | |
194 | + disabled: getBaseDisable( | |
195 | + item.field, | |
196 | + get(fields.value, `${item.field}`), | |
197 | + props.id, | |
198 | + role.value, | |
199 | + ), | |
200 | + }, | |
201 | + labelWidth: 600, | |
202 | + label: '产品意见', | |
203 | + }; | |
204 | + } | |
205 | + if (item.field === 'returnOrder') { | |
206 | + return { | |
207 | + field: 'returnOrder', | |
208 | + component: 'Select', | |
209 | + rules: [{ required: true }], | |
210 | + componentProps: { | |
211 | + options: [ | |
212 | + { | |
213 | + label: '是', | |
214 | + value: '1', | |
215 | + }, | |
216 | + { | |
217 | + label: '否', | |
218 | + value: '0', | |
219 | + }, | |
220 | + ], | |
221 | + disabled: getBaseDisable( | |
222 | + item.field, | |
223 | + get(fields.value, `${item.field}`), | |
224 | + props.id, | |
225 | + role.value, | |
226 | + ), | |
227 | + }, | |
228 | + labelWidth: 600, | |
229 | + // default: '请选择', | |
230 | + label: '是否返单 ', | |
231 | + }; | |
232 | + } | |
233 | + // const businessNotDisabledFields = ['customerCode', 'projectNo', 'innerNo']; | |
234 | + // const trackerNotDisabledFields = [ | |
235 | + // 'customerPo', | |
236 | + // 'customerStyle', | |
237 | + // 'modeleLo', | |
238 | + // 'collection', | |
239 | + // 'poColor', | |
240 | + // 'cnColor', | |
241 | + // 'picUrl', | |
242 | + // 'productStyle', | |
243 | + // 'orderComposition', | |
244 | + // 'productionDepartmentConsignTime', | |
245 | + // 'orderHodTime', | |
246 | + // 'outboundType', | |
247 | + // 'packetType', | |
248 | + // 'productionComment', | |
249 | + // ]; | |
250 | + // const isFieldNotDisabledForBusiness = businessNotDisabledFields.includes(item.field); | |
251 | + // const isFieldNotDisabledForTracker = trackerNotDisabledFields.includes(item.field); | |
200 | 252 | return { |
201 | 253 | ...item, |
202 | 254 | field: `${item.field}`, |
203 | 255 | componentProps: { |
204 | 256 | ...(item.component === 'Select' && { showSearch: true }), |
205 | 257 | ...(item.component === 'Select' && { options: options[item.field] }), |
206 | - disabled: | |
207 | - role.value === ROLE.BUSINESS | |
208 | - ? !isFieldNotDisabledForBusiness | |
209 | - : role.value === ROLE.TRACKER | |
210 | - ? !isFieldNotDisabledForTracker | |
211 | - : getBaseDisable(item.field, get(fields.value, `${item.field}`), props.id), | |
212 | - // disabled: getBaseDisable(item.field, get(fields.value, `${item.field}`), props.id), | |
258 | + // disabled: | |
259 | + // role.value === ROLE.BUSINESS | |
260 | + // ? !isFieldNotDisabledForBusiness | |
261 | + // : role.value === ROLE.TRACKER | |
262 | + // ? !isFieldNotDisabledForTracker | |
263 | + // : getBaseDisable(item.field, get(fields.value, `${item.field}`), props.id), | |
264 | + disabled: getBaseDisable( | |
265 | + item.field, | |
266 | + get(fields.value, `${item.field}`), | |
267 | + props.id, | |
268 | + role.value, | |
269 | + ), | |
213 | 270 | onChange: async (val) => { |
214 | 271 | if (item.field === 'customerCode' && !isCopy.value) { |
215 | 272 | if (!props.id) { | ... | ... |
src/views/project/order/PassCalculate.vue
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | v-bind="$attrs" |
4 | 4 | :title="title" |
5 | 5 | @register="register" |
6 | + @visible-change="handleShow" | |
6 | 7 | width="500px" |
7 | 8 | :bodyStyle="{ height: '100px' }" |
8 | 9 | @ok="handleOk" |
... | ... | @@ -17,7 +18,7 @@ |
17 | 18 | |
18 | 19 | const [register, { closeModal }] = useModalInner(async (data) => { |
19 | 20 | title.value = data.title; |
20 | - const id = data.check[0]; | |
21 | + const ids = data.check; | |
21 | 22 | const opinionType = ref(); |
22 | 23 | if (data.title == '确认意见') { |
23 | 24 | opinionType.value = 'pp样品确认意见'; |
... | ... | @@ -26,13 +27,18 @@ |
26 | 27 | } else if (data.title == '测试样品') { |
27 | 28 | opinionType.value = 'Altex测试结果'; |
28 | 29 | } |
29 | - num.value = await passCalculate({ orderId: id, opinionType: opinionType.value }); | |
30 | + num.value = await passCalculate({ ids: ids, opinionType: opinionType.value }); | |
30 | 31 | }); |
31 | 32 | const title = ref(''); |
32 | 33 | const num = ref(); |
33 | 34 | |
34 | 35 | async function handleOk() { |
35 | - closeModal(); | |
36 | 36 | num.value = ''; |
37 | + closeModal(); | |
38 | + } | |
39 | + function handleShow(visible: boolean) { | |
40 | + if (visible) { | |
41 | + num.value = ''; | |
42 | + } | |
37 | 43 | } |
38 | 44 | </script> | ... | ... |
src/views/project/order/ProductProfit.vue
... | ... | @@ -16,11 +16,14 @@ |
16 | 16 | title="内部生产净利润分析表" |
17 | 17 | width="60%" |
18 | 18 | :bodyStyle="{ height: '360px' }" |
19 | + @visible-change="handleShow" | |
19 | 20 | @ok="handleOk" |
20 | 21 | okText="导出" |
21 | 22 | > |
22 | 23 | <template #appendFooter> |
23 | - <a-button style="background-color: #1890ff; color: white">计算</a-button> | |
24 | + <a-button style="background-color: #1890ff; color: white" @click="handleCalculate" | |
25 | + >计算</a-button | |
26 | + > | |
24 | 27 | </template> |
25 | 28 | <table |
26 | 29 | style=" |
... | ... | @@ -39,7 +42,7 @@ |
39 | 42 | <tbody> |
40 | 43 | <tr> |
41 | 44 | <td style="border: 1px solid black; width: 20%">项目号</td> |
42 | - <td style="border: 1px solid black; width: 20%"></td> | |
45 | + <td style="border: 1px solid black; width: 20%">{{ projectNo }}</td> | |
43 | 46 | <td style="border: 1px solid black; width: 20%">开始时间</td> |
44 | 47 | <td style="border: 1px solid black; width: 20%">结束时间</td> |
45 | 48 | <td style="border: 1px solid black; width: 20%">生产持续时间</td> |
... | ... | @@ -47,56 +50,64 @@ |
47 | 50 | <tr> |
48 | 51 | <td style="border: 1px solid black; width: 20%"></td> |
49 | 52 | <td style="border: 1px solid black; width: 20%">项目开发时间</td> |
50 | - <td style="border: 1px solid black; width: 20%"></td> | |
51 | - <td style="border: 1px solid black; width: 20%"></td> | |
52 | - <td style="border: 1px solid black; width: 20%"></td> | |
53 | + <td style="border: 1px solid black; width: 20%"> | |
54 | + <input type="date" v-model="projectStartTime" style="width: 100%" /> | |
55 | + </td> | |
56 | + <td style="border: 1px solid black; width: 20%"> | |
57 | + <input type="date" v-model="projectEndTime" style="width: 100%" /> | |
58 | + </td> | |
59 | + <td style="border: 1px solid black; width: 20%">{{ projectDays }}</td> | |
53 | 60 | </tr> |
54 | 61 | <tr> |
55 | 62 | <td style="border: 1px solid black; width: 20%">客户编码</td> |
56 | - <td style="border: 1px solid black; width: 20%"></td> | |
63 | + <td style="border: 1px solid black; width: 20%">{{ customerCode }}</td> | |
57 | 64 | <td style="border: 1px solid black; width: 20%">明细</td> |
58 | 65 | <td style="border: 1px solid black; width: 20%">金额</td> |
59 | 66 | <td style="border: 1px solid black; width: 20%">订单数量</td> |
60 | 67 | </tr> |
61 | 68 | <tr> |
62 | 69 | <td style="border: 1px solid black; width: 40%" colspan="2">生产科总价合计</td> |
63 | - <td style="border: 1px solid black; width: 20%"></td> | |
64 | - <td style="border: 1px solid black; width: 20%"></td> | |
65 | - <td style="border: 1px solid black; width: 20%"></td> | |
70 | + <td style="border: 1px solid black; width: 20%">{{ productionDepartmentTotalPrice }}</td> | |
71 | + <td style="border: 1px solid black; width: 20%">{{ sumMoney }}</td> | |
72 | + <td style="border: 1px solid black; width: 20%">{{ sumCount }}</td> | |
66 | 73 | </tr> |
67 | 74 | <tr> |
68 | 75 | <td style="border: 1px solid black; width: 40%" colspan="2">生产科预算金额</td> |
69 | - <td style="border: 1px solid black; width: 20%"></td> | |
76 | + <td style="border: 1px solid black; width: 20%" | |
77 | + ><a-input v-model:value="productionDepartmentPredictPrice" placeholder="请输入" | |
78 | + /></td> | |
70 | 79 | <td style="border: 1px solid black; width: 20%">预算占比</td> |
71 | 80 | <td style="border: 1px solid black; width: 20%">预算占比与实际占比差</td> |
72 | 81 | </tr> |
73 | 82 | <tr> |
74 | 83 | <td style="border: 1px solid black; width: 40%" colspan="2">实际发生费用</td> |
75 | - <td style="border: 1px solid black; width: 20%"></td> | |
76 | - <td style="border: 1px solid black; width: 20%"></td> | |
77 | - <td style="border: 1px solid black; width: 20%"></td> | |
84 | + <td style="border: 1px solid black; width: 20%" | |
85 | + ><a-input v-model:value="productionActualPrice" placeholder="请输入" | |
86 | + /></td> | |
87 | + <td style="border: 1px solid black; width: 20%">{{ predictRatio }}</td> | |
88 | + <td style="border: 1px solid black; width: 20%">{{ predictRatioDeduct }}</td> | |
78 | 89 | </tr> |
79 | 90 | <tr> |
80 | 91 | <td style="border: 1px solid black; width: 40%" colspan="2">内部生产毛利润</td> |
81 | - <td style="border: 1px solid black; width: 20%"></td> | |
92 | + <td style="border: 1px solid black; width: 20%">{{ grossProfit }}</td> | |
82 | 93 | <td style="border: 1px solid black; width: 20%"></td> |
83 | 94 | <td style="border: 1px solid black; width: 20%"></td> |
84 | 95 | </tr> |
85 | 96 | <tr> |
86 | 97 | <td style="border: 1px solid black; width: 40%" colspan="2">内部生产固定成本</td> |
87 | - <td style="border: 1px solid black; width: 20%"></td> | |
98 | + <td style="border: 1px solid black; width: 20%">{{ innerProduceFixProfit }}</td> | |
88 | 99 | <td style="border: 1px solid black; width: 20%"></td> |
89 | 100 | <td style="border: 1px solid black; width: 20%"></td> |
90 | 101 | </tr> |
91 | 102 | <tr> |
92 | 103 | <td style="border: 1px solid black; width: 40%" colspan="2">内部生产提交</td> |
93 | - <td style="border: 1px solid black; width: 20%"></td> | |
104 | + <td style="border: 1px solid black; width: 20%">{{ innerProduceTotalPrice }}</td> | |
94 | 105 | <td style="border: 1px solid black; width: 20%"></td> |
95 | 106 | <td style="border: 1px solid black; width: 20%"></td> |
96 | 107 | </tr> |
97 | 108 | <tr> |
98 | 109 | <td style="border: 1px solid black; width: 40%" colspan="2">内部生产净利润</td> |
99 | - <td style="border: 1px solid black; width: 20%"></td> | |
110 | + <td style="border: 1px solid black; width: 20%">{{ innerProduceTotalProfit }}</td> | |
100 | 111 | <td style="border: 1px solid black; width: 20%"></td> |
101 | 112 | <td style="border: 1px solid black; width: 20%"></td> |
102 | 113 | </tr> |
... | ... | @@ -108,17 +119,83 @@ |
108 | 119 | import { BasicModal, useModalInner } from '@/components/Modal'; |
109 | 120 | import { computed, ref } from 'vue'; |
110 | 121 | import { payDate, checkCreate } from '@/api/project/invoice'; |
122 | + import type { Dayjs } from 'dayjs'; | |
123 | + import { calculateInnerProfitRatio, exportInnerProfitRatio } from '@/api/project/order'; | |
111 | 124 | |
112 | 125 | const Input1 = ref(''); |
113 | 126 | const Input2 = ref(); |
114 | 127 | const res = ref(); |
128 | + const customerCode = ref(); // 客户编码 | |
129 | + | |
130 | + const grossProfit = ref(); // 内部生产毛利润 | |
131 | + const innerProduceFixProfit = ref(); // 内部生产固定成本 | |
132 | + const innerProduceTotalPrice = ref(); // 内部生产提成 | |
133 | + const innerProduceTotalProfit = ref(); // 内部生产净利润 | |
134 | + const predictRatio = ref(); // 预算占比 | |
135 | + const predictRatioDeduct = ref(); // 预算占比差 | |
136 | + const productionActualPrice = ref(); // 实际发生费用 | |
137 | + const productionDepartmentPredictPrice = ref(); // 生产科预算金额 | |
138 | + const productionDepartmentTotalPrice = ref(); // 生产科总价合计 | |
139 | + const projectDays = ref(); // 生产持续时间 | |
140 | + const sumCount = ref(0); | |
141 | + const sumMoney = ref(0); | |
142 | + | |
143 | + const projectEndTime = ref(); // 项目开发结束时间 | |
144 | + const projectNo = ref(); // 项目号 | |
145 | + const projectStartTime = ref(); // 项目开发开始时间 | |
146 | + const filteredItems = ref(); | |
147 | + | |
115 | 148 | const [register, { closeModal }] = useModalInner(async (data) => { |
116 | 149 | res.value = data.data; |
150 | + customerCode.value = data.customerCode[0][0]; | |
151 | + projectNo.value = data.projectNo[0][0]; | |
117 | 152 | console.log(Input2.value, 565656); |
153 | + filteredItems.value = data.filteredItems; | |
118 | 154 | }); |
119 | 155 | async function handleOk() { |
120 | 156 | closeModal(); |
121 | 157 | } |
158 | + function handleShow(visible: boolean) { | |
159 | + if (visible) { | |
160 | + projectStartTime.value = null; | |
161 | + projectEndTime.value = null; | |
162 | + productionDepartmentPredictPrice.value = null; | |
163 | + productionActualPrice.value = null; | |
164 | + } | |
165 | + } | |
166 | + function formatDateTime(dateTime: string): string { | |
167 | + return dateTime.split('T')[0]; | |
168 | + } | |
169 | + | |
170 | + async function handleCalculate() { | |
171 | + projectStartTime.value = formatDateTime(projectStartTime.value); | |
172 | + projectEndTime.value = formatDateTime(projectEndTime.value); | |
173 | + const res = await calculateInnerProfitRatio({ | |
174 | + customerCode: customerCode.value, | |
175 | + projectNo: projectNo.value, | |
176 | + projectStartTime: projectStartTime.value, | |
177 | + projectEndTime: projectEndTime.value, | |
178 | + productionDepartmentPredictPrice: productionDepartmentPredictPrice.value, | |
179 | + productionActualPrice: productionActualPrice.value, | |
180 | + }); | |
181 | + console.log(res, '5656resproductprofit'); | |
182 | + grossProfit.value = res.grossProfit; | |
183 | + innerProduceFixProfit.value = res.innerProduceFixProfit; | |
184 | + innerProduceTotalPrice.value = res.innerProduceTotalPrice; | |
185 | + innerProduceTotalProfit.value = res.innerProduceTotalProfit; | |
186 | + predictRatio.value = res.predictRatio; | |
187 | + productionActualPrice.value = res.productionActualPrice; | |
188 | + productionDepartmentPredictPrice.value = res.productionDepartmentPredictPrice; | |
189 | + productionDepartmentTotalPrice.value = res.productionDepartmentTotalPrice; | |
190 | + projectDays.value = res.projectDays; | |
191 | + predictRatioDeduct.value = 1 - predictRatio.value; | |
192 | + console.log(filteredItems.value, '5656filteredItems'); | |
193 | + filteredItems.value.forEach((item) => { | |
194 | + sumMoney.value += item.profitAnalysisInfo.productionDepartmentTotalPrice; | |
195 | + sumCount.value += item.orderCount; | |
196 | + }); | |
197 | + console.log(sumMoney.value, '5656filteredItems', sumCount.value); | |
198 | + } | |
122 | 199 | </script> |
123 | 200 | <style scoped> |
124 | 201 | .divAll { | ... | ... |
src/views/project/order/ProductText.vue
... | ... | @@ -18,7 +18,7 @@ |
18 | 18 | width="500px" |
19 | 19 | @visible-change="handleShow" |
20 | 20 | :footer="null" |
21 | - :bodyStyle="{ height: '180px' }" | |
21 | + :bodyStyle="{ height: '210px' }" | |
22 | 22 | > |
23 | 23 | <div class="container"> |
24 | 24 | <div v-if="isShow1 == true" style="margin-top: 50px; text-align: center"> |
... | ... | @@ -55,6 +55,7 @@ |
55 | 55 | import { RadioGroup } from 'ant-design-vue'; |
56 | 56 | import { EyeOutlined, FilePptOutlined } from '@ant-design/icons-vue'; |
57 | 57 | import { useMessage } from '@/hooks/web/useMessage'; |
58 | + import { createProductText, exportProductText } from '@/api/project/order'; | |
58 | 59 | |
59 | 60 | export default defineComponent({ |
60 | 61 | props: { |
... | ... | @@ -70,16 +71,13 @@ |
70 | 71 | const loading = ref(true); |
71 | 72 | const exportLoading = ref(false); |
72 | 73 | const info = ref(); |
74 | + const checkedKeys = ref(); | |
73 | 75 | const choose = ref(); //选择公司 |
74 | 76 | const isShow1 = ref(true); //选择公司页面 |
75 | 77 | const isShow2 = ref(false); //生成PDF页面 |
76 | 78 | const pdf = ref(['/pdf.png']); |
77 | 79 | const [register, { setModalProps, closeModal }] = useModalInner(async (data) => { |
78 | - // if (data.customers.length == 0) { | |
79 | - // error('请选择订单'); | |
80 | - // closeModal(); | |
81 | - // } | |
82 | - console.log(data, '5656data'); | |
80 | + checkedKeys.value = data.checkedKeys; | |
83 | 81 | }); |
84 | 82 | const options = computed(() => { |
85 | 83 | // 运营总监-基本信息,跟单,质检 |
... | ... | @@ -89,7 +87,7 @@ |
89 | 87 | ]; |
90 | 88 | }); |
91 | 89 | const { createMessage } = useMessage(); |
92 | - const { error } = createMessage; | |
90 | + const { error, success } = createMessage; | |
93 | 91 | const customerCodeToCompanyMap: Record<string, string> = { |
94 | 92 | A01: '青岛翱特逸格饰品有限公司', |
95 | 93 | A04: '青岛吉庆天成饰品有限公司', |
... | ... | @@ -139,10 +137,21 @@ |
139 | 137 | return true; |
140 | 138 | } |
141 | 139 | //生成pdf |
140 | + const resText = ref(); | |
142 | 141 | // const customerCodeList: string[] = props.customerCodes; |
143 | - function handleProduct() { | |
142 | + let isDisabled = false; | |
143 | + async function handleProduct() { | |
144 | + if (isDisabled) { | |
145 | + error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | |
146 | + return; | |
147 | + } | |
144 | 148 | const customerCodeList = props.customerCodes; |
145 | 149 | const areValid = validateCompany(customerCodeList, choose.value); |
150 | + // // 设置禁用标志并在 3 秒后重置 | |
151 | + isDisabled = true; | |
152 | + setTimeout(() => { | |
153 | + isDisabled = false; | |
154 | + }, 3000); | |
146 | 155 | //如果选错了,弹出提示 |
147 | 156 | if (!areValid) { |
148 | 157 | error('勾选订单与选择的公司不匹配'); |
... | ... | @@ -151,6 +160,11 @@ |
151 | 160 | choose.value == '青岛翱特逸格饰品有限公司' || |
152 | 161 | choose.value == '青岛吉庆天成饰品有限公司' |
153 | 162 | ) { |
163 | + resText.value = await createProductText({ | |
164 | + ids: checkedKeys.value, | |
165 | + companyName: choose.value, | |
166 | + }); | |
167 | + console.log(resText.value, '5656restextF'); | |
154 | 168 | //此处设置接口,传递选择的公司值 |
155 | 169 | isShow1.value = false; |
156 | 170 | isShow2.value = true; |
... | ... | @@ -159,11 +173,17 @@ |
159 | 173 | } |
160 | 174 | //查看pdf |
161 | 175 | function handlePdf() { |
162 | - // const pdfUrl = './pdfs.pdf'; | |
163 | - // window.open(pdfUrl, '_blank'); | |
176 | + window.open(resText.value.produceFile); | |
164 | 177 | } |
165 | 178 | //发送按钮 |
166 | 179 | async function handleExport() { |
180 | + const res = await exportProductText({ | |
181 | + productionUrl: resText.value.productionUrl, | |
182 | + productionDepartment: resText.value.productionDepartment, | |
183 | + isSend: true, | |
184 | + }); | |
185 | + console.log(); | |
186 | + success('操作成功,' + res); | |
167 | 187 | closeModal(); |
168 | 188 | } |
169 | 189 | return { |
... | ... | @@ -198,23 +218,27 @@ |
198 | 218 | flex-direction: column; |
199 | 219 | min-height: 20vh; |
200 | 220 | } |
221 | + | |
201 | 222 | .bottom { |
202 | 223 | margin-top: auto; |
203 | - margin-left: auto; | |
204 | 224 | margin-right: 20px; |
225 | + margin-left: auto; | |
205 | 226 | } |
227 | + | |
206 | 228 | .showPdf { |
229 | + display: flex; | |
230 | + position: relative; | |
231 | + height: 30px; | |
207 | 232 | border: 2px solid; |
208 | - border-color: #d8d8d8; | |
209 | 233 | border-radius: 5px; |
210 | - height: 30px; | |
211 | - position: relative; | |
212 | - display: flex; | |
234 | + border-color: #d8d8d8; | |
213 | 235 | } |
236 | + | |
214 | 237 | .FilePptOutlined { |
215 | 238 | margin-top: 3px; |
216 | 239 | margin-left: 30px; |
217 | 240 | } |
241 | + | |
218 | 242 | .EyeOutlined { |
219 | 243 | margin-top: 3px; |
220 | 244 | margin-left: 290px; | ... | ... |
src/views/project/order/ServiceProfit.vue
... | ... | @@ -16,11 +16,14 @@ |
16 | 16 | title="净利润分析表" |
17 | 17 | width="60%" |
18 | 18 | :bodyStyle="{ height: '455px' }" |
19 | + @visible-change="handleShow" | |
19 | 20 | @ok="handleOk" |
20 | 21 | okText="导出" |
21 | 22 | > |
22 | 23 | <template #appendFooter> |
23 | - <a-button style="background-color: #1890ff; color: white">计算</a-button> | |
24 | + <a-button style="background-color: #1890ff; color: white" @click="handleCalculate" | |
25 | + >计算</a-button | |
26 | + > | |
24 | 27 | </template> |
25 | 28 | <table |
26 | 29 | style=" |
... | ... | @@ -39,25 +42,29 @@ |
39 | 42 | <tbody> |
40 | 43 | <tr> |
41 | 44 | <td style="border: 1px solid black; width: 25%">项目号</td> |
42 | - <td style="border: 1px solid black; width: 25%">M01-214425</td> | |
45 | + <td style="border: 1px solid black; width: 25%">{{ projectNo }}</td> | |
43 | 46 | <td style="border: 1px solid black; width: 25%">开始时间</td> |
44 | 47 | <td style="border: 1px solid black; width: 25%">结束时间</td> |
45 | 48 | </tr> |
46 | 49 | <tr> |
47 | 50 | <td style="border: 1px solid black"></td> |
48 | 51 | <td style="border: 1px solid black">项目开始时间</td> |
49 | - <td style="border: 1px solid black"></td> | |
50 | - <td style="border: 1px solid black"></td> | |
52 | + <td style="border: 1px solid black" | |
53 | + ><a-date-picker v-model:value="projectStartTime" | |
54 | + /></td> | |
55 | + <td style="border: 1px solid black"><a-date-picker v-model:value="projectEndTime" /></td> | |
51 | 56 | </tr> |
52 | 57 | <tr> |
53 | 58 | <td style="border: 1px solid black"></td> |
54 | 59 | <td style="border: 1px solid black">生产进行时间</td> |
55 | - <td style="border: 1px solid black"></td> | |
56 | - <td style="border: 1px solid black"></td> | |
60 | + <td style="border: 1px solid black" | |
61 | + ><a-date-picker v-model:value="produceStartTime" | |
62 | + /></td> | |
63 | + <td style="border: 1px solid black"><a-date-picker v-model:value="produceEndTime" /></td> | |
57 | 64 | </tr> |
58 | 65 | <tr> |
59 | 66 | <td style="border: 1px solid black">客户编码</td> |
60 | - <td style="border: 1px solid black">M01</td> | |
67 | + <td style="border: 1px solid black">{{ customerCode }}</td> | |
61 | 68 | <td style="border: 1px solid black"></td> |
62 | 69 | <td style="border: 1px solid black">备注</td> |
63 | 70 | </tr> |
... | ... | @@ -78,12 +85,16 @@ |
78 | 85 | </tr> |
79 | 86 | <tr> |
80 | 87 | <td style="border: 1px solid black" colspan="2">研发开发费合计</td> |
81 | - <td style="border: 1px solid black"></td> | |
88 | + <td style="border: 1px solid black" | |
89 | + ><a-input v-model:value="developTotalPrice" placeholder="请输入" | |
90 | + /></td> | |
82 | 91 | <td style="border: 1px solid black"></td> |
83 | 92 | </tr> |
84 | 93 | <tr> |
85 | 94 | <td style="border: 1px solid black" colspan="2">复制费用合计</td> |
86 | - <td style="border: 1px solid black"></td> | |
95 | + <td style="border: 1px solid black" | |
96 | + ><a-input v-model:value="copyTotalPrice" placeholder="请输入" | |
97 | + /></td> | |
87 | 98 | <td style="border: 1px solid black"></td> |
88 | 99 | </tr> |
89 | 100 | <tr> |
... | ... | @@ -123,7 +134,9 @@ |
123 | 134 | </tr> |
124 | 135 | <tr> |
125 | 136 | <td style="border: 1px solid black" colspan="2">包装费用实际金额</td> |
126 | - <td style="border: 1px solid black"></td> | |
137 | + <td style="border: 1px solid black" | |
138 | + ><a-input v-model:value="packetActualTotalPrice" placeholder="请输入" | |
139 | + /></td> | |
127 | 140 | <td style="border: 1px solid black"></td> |
128 | 141 | </tr> |
129 | 142 | <tr> |
... | ... | @@ -162,20 +175,116 @@ |
162 | 175 | </template> |
163 | 176 | <script lang="ts" setup> |
164 | 177 | import { BasicModal, useModalInner } from '@/components/Modal'; |
165 | - import { computed, ref } from 'vue'; | |
166 | - import { payDate, checkCreate } from '@/api/project/invoice'; | |
167 | - import { Description, DescItem, useDescription } from '@/components/Description'; | |
178 | + import { computed, ref, toRaw } from 'vue'; | |
179 | + // import { payDate, checkCreate } from '@/api/project/invoice'; | |
180 | + import { calculateBusinessProfit, exportBusinessProfit } from '@/api/project/order'; | |
181 | + import type { Dayjs } from 'dayjs'; | |
168 | 182 | |
183 | + const projectStartTime = ref(); | |
184 | + const projectEndTime = ref(); | |
185 | + const produceStartTime = ref(); | |
186 | + const produceEndTime = ref(); | |
187 | + | |
188 | + const testinput = ref(); | |
169 | 189 | const Input1 = ref(''); |
170 | 190 | const Input2 = ref(); |
171 | 191 | const res = ref(); |
192 | + const orderList = ref(); | |
193 | + const customerCode = ref(); | |
194 | + const projectNo = ref(); | |
195 | + const developTotalPrice = ref(); | |
196 | + const copyTotalPrice = ref(); | |
197 | + const packetActualTotalPrice = ref(); | |
198 | + const spainRatio = ref(); | |
199 | + const chinaRatio = ref(); | |
200 | + const actualRmbPrice = ref(0); //实际跟单单价 | |
201 | + const actualPrice = ref(0); //实际跟单单价折算美金 | |
202 | + const actualRatio = ref(6.2); //实际汇率 | |
203 | + const actualRatiactualRatioProfitPriceo = ref(); //汇率收益计算 | |
204 | + const chinaRatioProfitPrice = ref(); //中国团队提成比例 | |
205 | + const developProfit = ref(); //研发贸易利润 | |
206 | + const fixCost = ref(); // 固定成本 | |
207 | + const orderCount = ref(); //订单总数量 | |
208 | + const outTotalPrice = ref(); //支出合计计 | |
209 | + const packetProfitPrice = ref(); //包装费用收益计算 | |
210 | + const packetTotalPrice = ref(); //包装费用合计¥ | |
211 | + const productionDepartmentTotalPrice = ref(); //生成科总价¥ | |
212 | + const totalProfitPrice = ref(); //综合收益计算 | |
213 | + const spainRatioProfitPrice = ref(); //西班牙提成金额 | |
214 | + | |
215 | + // const orderRes = await getOrderList({}); | |
216 | + // console.log(orderRes, '5656orderRes'); | |
172 | 217 | const [register, { closeModal }] = useModalInner(async (data) => { |
173 | 218 | res.value = data.data; |
174 | - console.log(Input2.value, 565656); | |
219 | + orderList.value = data.res; | |
220 | + customerCode.value = data.customerCode[0][0]; | |
221 | + projectNo.value = data.projectNo[0][0]; | |
222 | + console.log(orderList.value, 565656); | |
175 | 223 | }); |
176 | 224 | async function handleOk() { |
177 | 225 | closeModal(); |
178 | 226 | } |
227 | + function handleShow(visible: boolean) { | |
228 | + if (visible) { | |
229 | + projectStartTime.value = null; | |
230 | + projectEndTime.value = null; | |
231 | + produceStartTime.value = null; | |
232 | + produceEndTime.value = null; | |
233 | + customerCode.value = null; | |
234 | + projectNo.value = null; | |
235 | + developTotalPrice.value = null; | |
236 | + copyTotalPrice.value = null; | |
237 | + packetActualTotalPrice.value = null; | |
238 | + } | |
239 | + } | |
240 | + async function handleCalculate() { | |
241 | + const packetCalculatePrice = ref(0); | |
242 | + const orderCalculateCount = ref(0); | |
243 | + const allList = toRaw(orderList.value); | |
244 | + console.log(allList, '5656allList'); | |
245 | + allList.forEach((item) => { | |
246 | + console.log(item, '5656orderList'); | |
247 | + console.log(item.profitAnalysisInfo.packetPrice, '5656orderList'); | |
248 | + packetCalculatePrice.value += item.profitAnalysisInfo.packetPrice; | |
249 | + orderCalculateCount.value += item.orderCount; | |
250 | + actualRmbPrice.value += packetCalculatePrice.value / orderCalculateCount.value; | |
251 | + }); | |
252 | + actualPrice.value = actualRmbPrice.value / actualRatio.value; | |
253 | + console.log(actualPrice.value, '5656actualPrice'); | |
254 | + | |
255 | + const res = await calculateBusinessProfit({ | |
256 | + customerCode: customerCode.value, | |
257 | + projectNo: projectNo.value, | |
258 | + projectStartTime: projectStartTime.value, | |
259 | + projectEndTime: projectEndTime.value, | |
260 | + produceStartTime: produceStartTime.value, | |
261 | + produceEndTime: produceEndTime.value, | |
262 | + developTotalPrice: developTotalPrice.value, | |
263 | + copyTotalPrice: copyTotalPrice.value, | |
264 | + spainRatio: spainRatio.value, | |
265 | + chinaRatio: chinaRatio.value, | |
266 | + packetActualTotalPrice: packetActualTotalPrice.value, | |
267 | + actualRmbPrice: actualRmbPrice.value, | |
268 | + actualPrice: actualPrice.value, | |
269 | + actualRatio: actualRatio.value, | |
270 | + }); | |
271 | + console.log(res, '5656resservice'); | |
272 | + | |
273 | + actualRmbPrice.value = res.data.actualRmbPrice; | |
274 | + actualPrice.value = res.data.actualPrice; | |
275 | + actualRatio.value = res.data.actualRatio; | |
276 | + actualRatiactualRatioProfitPriceo.value = res.data.actualRatioProfitPrice; //汇率收益计算 | |
277 | + chinaRatioProfitPrice.value = res.data.chinaRatioProfitPrice; //中国团队提成比例 | |
278 | + developProfit.value = res.data.developProfit; //研发贸易利润 | |
279 | + fixCost.value = res.data.fixCost; // 固定成本 | |
280 | + orderCount.value = res.data.orderCount; //订单总数量 | |
281 | + outTotalPrice.value = res.data.outTotalPrice; //支出合计 | |
282 | + packetProfitPrice.value = res.data.packetProfitPrice; //包装费用收益计算 | |
283 | + packetTotalPrice.value = res.data.packetTotalPrice; //包装费用合计 | |
284 | + productionDepartmentTotalPrice.value = res.data.productionDepartmentTotalPrice; //生成科总价 | |
285 | + totalProfitPrice.value = res.data.totalProfitPrice; //综合收益计算 | |
286 | + spainRatioProfitPrice.value = res.data.spainRatioProfitPrice; //西班牙提成金额 | |
287 | + } | |
179 | 288 | </script> |
180 | 289 | <style scoped> |
181 | 290 | .divAll { | ... | ... |
src/views/project/order/TrackHistory.vue
... | ... | @@ -91,16 +91,22 @@ |
91 | 91 | // 如果没有找到".",直接返回原始字符串 |
92 | 92 | return Result; |
93 | 93 | } |
94 | - const pagination1 = computed(() => { | |
95 | - return { | |
96 | - show: true, | |
97 | - pageSize: 20, | |
98 | - page: page1.value, | |
99 | - total: total1.value, | |
100 | - onChange(cur) { | |
101 | - console.log(cur); | |
102 | - getOrderOptLogFunc(orderId.value, 1, cur); | |
103 | - }, | |
104 | - }; | |
105 | - }); | |
94 | + // const pagination1 = computed(() => { | |
95 | + // return { | |
96 | + // show: true, | |
97 | + // pageSize: 20, | |
98 | + // page: page1.value, | |
99 | + // total: total1.value, | |
100 | + // onChange(cur) { | |
101 | + // console.log(cur); | |
102 | + // getOrderOptLogFunc(orderId.value, 1, cur); | |
103 | + // }, | |
104 | + // }; | |
105 | + // }); | |
106 | + const pagination1 = { | |
107 | + onChange: (page: number) => { | |
108 | + console.log(page); | |
109 | + }, | |
110 | + pageSize: 5, | |
111 | + }; | |
106 | 112 | </script> | ... | ... |
src/views/project/order/index.vue
... | ... | @@ -164,7 +164,7 @@ |
164 | 164 | :style="{ borderRadius: '5px 5px 5px 5px' }" |
165 | 165 | type="primary" |
166 | 166 | @click="handleProductModal" |
167 | - v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS || role === ROLE.TRACKER" | |
167 | + v-if="role === ROLE.ADMIN || role === ROLE.TRACKER" | |
168 | 168 | >生产指标书</a-button |
169 | 169 | > |
170 | 170 | <a-button |
... | ... | @@ -366,15 +366,91 @@ |
366 | 366 | console.log(getForm().getFieldsValue()); |
367 | 367 | } |
368 | 368 | |
369 | + // type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] | |
370 | + // type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] | |
371 | + | |
372 | + // const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref | |
373 | + // const selectedProductionDepartment = ref<ProductionDepartmentEntry[]>([]); // 创建一个二维数组的 ref | |
374 | + | |
375 | + // // 单选处理函数 | |
376 | + // function onSelect( | |
377 | + // record: { customerCode: string; productionDepartment: string; id: string }, | |
378 | + // selected: boolean, | |
379 | + // ) { | |
380 | + // // 查找 customerCode 在 selectedCustomCodes 中的位置 | |
381 | + // const customerCodeIndex = selectedCustomCodes.value.findIndex( | |
382 | + // ([customerCode]) => customerCode === record.customerCode, | |
383 | + // ); | |
384 | + | |
385 | + // // 查找 productionDepartment 在 selectedProductionDepartment 中的位置 | |
386 | + // const productionDepartmentIndex = selectedProductionDepartment.value.findIndex( | |
387 | + // ([department]) => department === record.productionDepartment, | |
388 | + // ); | |
389 | + | |
390 | + // if (selected) { | |
391 | + // // 添加到 checkedKeys | |
392 | + // checkedKeys.value = [...checkedKeys.value, record.id]; | |
393 | + | |
394 | + // // 更新 selectedCustomCodes | |
395 | + // if (customerCodeIndex !== -1) { | |
396 | + // // 如果已存在,增加计数 | |
397 | + // selectedCustomCodes.value[customerCodeIndex][1] += 1; | |
398 | + // } else { | |
399 | + // // 如果不存在,添加新项 [customerCode, 1] | |
400 | + // selectedCustomCodes.value.push([record.customerCode, 1]); | |
401 | + // } | |
402 | + | |
403 | + // // 更新 selectedProductionDepartment | |
404 | + // if (productionDepartmentIndex !== -1) { | |
405 | + // // 如果已存在,增加计数 | |
406 | + // selectedProductionDepartment.value[productionDepartmentIndex][1] += 1; | |
407 | + // } else { | |
408 | + // // 如果不存在,添加新项 [productionDepartment, 1] | |
409 | + // selectedProductionDepartment.value.push([record.productionDepartment, 1]); | |
410 | + // } | |
411 | + // } else { | |
412 | + // // 从 checkedKeys 中移除 | |
413 | + // checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); | |
414 | + | |
415 | + // // 更新 selectedCustomCodes | |
416 | + // if (customerCodeIndex !== -1) { | |
417 | + // if (selectedCustomCodes.value[customerCodeIndex][1] > 1) { | |
418 | + // selectedCustomCodes.value[customerCodeIndex][1] -= 1; | |
419 | + // } else { | |
420 | + // selectedCustomCodes.value.splice(customerCodeIndex, 1); | |
421 | + // } | |
422 | + // } | |
423 | + | |
424 | + // // 更新 selectedProductionDepartment | |
425 | + // if (productionDepartmentIndex !== -1) { | |
426 | + // if (selectedProductionDepartment.value[productionDepartmentIndex][1] > 1) { | |
427 | + // selectedProductionDepartment.value[productionDepartmentIndex][1] -= 1; | |
428 | + // } else { | |
429 | + // selectedProductionDepartment.value.splice(productionDepartmentIndex, 1); | |
430 | + // } | |
431 | + // } | |
432 | + // } | |
433 | + | |
434 | + // console.log('5656Checked Keys:', checkedKeys.value); | |
435 | + // console.log('5656Selected Customer Codes:', selectedCustomCodes.value); | |
436 | + // console.log('5656Selected Production Departments:', selectedProductionDepartment.value); | |
437 | + // } | |
369 | 438 | type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] |
370 | 439 | type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] |
440 | + type ProjectNoEntry = [string, number]; // 定义二维数组类型 [innerNo, count] | |
371 | 441 | |
372 | 442 | const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref |
373 | 443 | const selectedProductionDepartment = ref<ProductionDepartmentEntry[]>([]); // 创建一个二维数组的 ref |
444 | + const selectedProjectNos = ref<ProjectNoEntry[]>([]); // 创建一个二维数组的 ref | |
374 | 445 | |
375 | 446 | // 单选处理函数 |
376 | 447 | function onSelect( |
377 | - record: { customerCode: string; productionDepartment: string; id: string }, | |
448 | + record: { | |
449 | + customerCode: string; | |
450 | + productionDepartment: string; | |
451 | + projectNo: string; | |
452 | + id: string; | |
453 | + }, | |
378 | 454 | selected: boolean, |
379 | 455 | ) { |
380 | 456 | // 查找 customerCode 在 selectedCustomCodes 中的位置 |
... | ... | @@ -387,6 +463,11 @@ |
387 | 463 | ([department]) => department === record.productionDepartment, |
388 | 464 | ); |
389 | 465 | |
466 | + // 查找 projectNo 在 selectedProjectNos 中的位置 | |
467 | + const projectNoIndex = selectedProjectNos.value.findIndex( | |
468 | + ([projectNo]) => projectNo === record.projectNo, | |
469 | + ); | |
470 | + | |
390 | 471 | if (selected) { |
391 | 472 | // 添加到 checkedKeys |
392 | 473 | checkedKeys.value = [...checkedKeys.value, record.id]; |
... | ... | @@ -408,6 +489,15 @@ |
408 | 489 | // 如果不存在,添加新项 [productionDepartment, 1] |
409 | 490 | selectedProductionDepartment.value.push([record.productionDepartment, 1]); |
410 | 491 | } |
492 | + | |
493 | + // 更新 selectedProjectNos | |
494 | + if (projectNoIndex !== -1) { | |
495 | + // 如果已存在,增加计数 | |
496 | + selectedProjectNos.value[projectNoIndex][1] += 1; | |
497 | + } else { | |
498 | + // 如果不存在,添加新项 [projectNo, 1] | |
499 | + selectedProjectNos.value.push([record.projectNo, 1]); | |
500 | + } | |
411 | 501 | } else { |
412 | 502 | // 从 checkedKeys 中移除 |
413 | 503 | checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); |
... | ... | @@ -429,18 +519,100 @@ |
429 | 519 | selectedProductionDepartment.value.splice(productionDepartmentIndex, 1); |
430 | 520 | } |
431 | 521 | } |
522 | + | |
523 | + // 更新 selectedProjectNos | |
524 | + if (projectNoIndex !== -1) { | |
525 | + if (selectedProjectNos.value[projectNoIndex][1] > 1) { | |
526 | + selectedProjectNos.value[projectNoIndex][1] -= 1; | |
527 | + } else { | |
528 | + selectedProjectNos.value.splice(projectNoIndex, 1); | |
529 | + } | |
530 | + } | |
432 | 531 | } |
433 | 532 | |
434 | 533 | console.log('5656Checked Keys:', checkedKeys.value); |
435 | 534 | console.log('5656Selected Customer Codes:', selectedCustomCodes.value); |
436 | - console.log('5656Selected Production Departments:', selectedProductionDepartment.value); | |
535 | + console.log('56565Selected Production Departments:', selectedProductionDepartment.value); | |
536 | + console.log('5656Selected projectNo:', selectedProjectNos.value); | |
437 | 537 | } |
438 | 538 | |
539 | + // // 全选处理函数 | |
540 | + // function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) { | |
541 | + // const changeIds = changeRows.map((item) => item.id); | |
542 | + // const changeCustomerCodes = changeRows.map((item) => item.customerCode); | |
543 | + // const changeProductionDepartments = changeRows.map((item) => item.productionDepartment); | |
544 | + | |
545 | + // if (selected) { | |
546 | + // // 添加到 checkedKeys | |
547 | + // checkedKeys.value = [...checkedKeys.value, ...changeIds]; | |
548 | + | |
549 | + // // 更新 selectedCustomCodes | |
550 | + // changeCustomerCodes.forEach((code) => { | |
551 | + // const index = selectedCustomCodes.value.findIndex( | |
552 | + // ([customerCode]) => customerCode === code, | |
553 | + // ); | |
554 | + // if (index !== -1) { | |
555 | + // selectedCustomCodes.value[index][1] += 1; | |
556 | + // } else { | |
557 | + // selectedCustomCodes.value.push([code, 1]); | |
558 | + // } | |
559 | + // }); | |
560 | + | |
561 | + // // 更新 selectedProductionDepartment | |
562 | + // changeProductionDepartments.forEach((department) => { | |
563 | + // const index = selectedProductionDepartment.value.findIndex( | |
564 | + // ([prodDepartment]) => prodDepartment === department, | |
565 | + // ); | |
566 | + // if (index !== -1) { | |
567 | + // selectedProductionDepartment.value[index][1] += 1; | |
568 | + // } else { | |
569 | + // selectedProductionDepartment.value.push([department, 1]); | |
570 | + // } | |
571 | + // }); | |
572 | + // } else { | |
573 | + // // 从 checkedKeys 中移除 | |
574 | + // checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id)); | |
575 | + | |
576 | + // // 更新 selectedCustomCodes | |
577 | + // changeCustomerCodes.forEach((code) => { | |
578 | + // const index = selectedCustomCodes.value.findIndex( | |
579 | + // ([customerCode]) => customerCode === code, | |
580 | + // ); | |
581 | + // if (index !== -1) { | |
582 | + // if (selectedCustomCodes.value[index][1] > 1) { | |
583 | + // selectedCustomCodes.value[index][1] -= 1; | |
584 | + // } else { | |
585 | + // selectedCustomCodes.value.splice(index, 1); | |
586 | + // } | |
587 | + // } | |
588 | + // }); | |
589 | + | |
590 | + // // 更新 selectedProductionDepartment | |
591 | + // changeProductionDepartments.forEach((department) => { | |
592 | + // const index = selectedProductionDepartment.value.findIndex( | |
593 | + // ([prodDepartment]) => prodDepartment === department, | |
594 | + // ); | |
595 | + // if (index !== -1) { | |
596 | + // if (selectedProductionDepartment.value[index][1] > 1) { | |
597 | + // selectedProductionDepartment.value[index][1] -= 1; | |
598 | + // } else { | |
599 | + // selectedProductionDepartment.value.splice(index, 1); | |
600 | + // } | |
601 | + // } | |
602 | + // }); | |
603 | + // } | |
604 | + | |
605 | + // console.log('5656Checked Keys:', checkedKeys.value); | |
606 | + // console.log('5656Selected Customer Codes:', selectedCustomCodes.value); | |
607 | + // console.log('5656Selected Production Departments:', selectedProductionDepartment.value); | |
608 | + // } | |
609 | + | |
439 | 610 | // 全选处理函数 |
440 | 611 | function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) { |
441 | 612 | const changeIds = changeRows.map((item) => item.id); |
442 | 613 | const changeCustomerCodes = changeRows.map((item) => item.customerCode); |
443 | 614 | const changeProductionDepartments = changeRows.map((item) => item.productionDepartment); |
615 | + const changeProjectNos = changeRows.map((item) => item.projectNo); | |
444 | 616 | |
445 | 617 | if (selected) { |
446 | 618 | // 添加到 checkedKeys |
... | ... | @@ -469,6 +641,16 @@ |
469 | 641 | selectedProductionDepartment.value.push([department, 1]); |
470 | 642 | } |
471 | 643 | }); |
644 | + | |
645 | + // 更新 selectedProjectNos | |
646 | + changeProjectNos.forEach((projectNo) => { | |
647 | + const index = selectedProjectNos.value.findIndex(([no]) => no === projectNo); | |
648 | + if (index !== -1) { | |
649 | + selectedProjectNos.value[index][1] += 1; | |
650 | + } else { | |
651 | + selectedProjectNos.value.push([projectNo, 1]); | |
652 | + } | |
653 | + }); | |
472 | 654 | } else { |
473 | 655 | // 从 checkedKeys 中移除 |
474 | 656 | checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id)); |
... | ... | @@ -500,11 +682,24 @@ |
500 | 682 | } |
501 | 683 | } |
502 | 684 | }); |
685 | + | |
686 | + // 更新 selectedProjectNos | |
687 | + changeInnerNos.forEach((projectNo) => { | |
688 | + const index = selectedProjectNos.value.findIndex(([no]) => no === projectNo); | |
689 | + if (index !== -1) { | |
690 | + if (selectedProjectNos.value[index][1] > 1) { | |
691 | + selectedProjectNos.value[index][1] -= 1; | |
692 | + } else { | |
693 | + selectedProjectNos.value.splice(index, 1); | |
694 | + } | |
695 | + } | |
696 | + }); | |
503 | 697 | } |
504 | 698 | |
505 | 699 | console.log('5656Checked Keys:', checkedKeys.value); |
506 | 700 | console.log('5656Selected Customer Codes:', selectedCustomCodes.value); |
507 | 701 | console.log('5656Selected Production Departments:', selectedProductionDepartment.value); |
702 | + console.log('5656Selected projectNos:', selectedProjectNos.value); | |
508 | 703 | } |
509 | 704 | |
510 | 705 | function handleEdit(record, e) { |
... | ... | @@ -621,7 +816,7 @@ |
621 | 816 | // } |
622 | 817 | const { createMessage } = useMessage(); |
623 | 818 | const { error } = createMessage; |
624 | - function handleProductModal() { | |
819 | + function handleProductModal(record) { | |
625 | 820 | const form = getForm(); |
626 | 821 | const values = form.getFieldsValue(); |
627 | 822 | console.log(selectedCustomCodes.value, 5656); |
... | ... | @@ -674,21 +869,50 @@ |
674 | 869 | }); |
675 | 870 | } |
676 | 871 | |
677 | - function handleServiceProfitModal() { | |
872 | + async function handleServiceProfitModal() { | |
873 | + if (selectedCustomCodes.value.length > 1) { | |
874 | + error('勾选订单的客户编码需一致'); | |
875 | + return; | |
876 | + } | |
877 | + if (selectedProjectNos.value.length > 1) { | |
878 | + error('勾选订单的项目号需一致'); | |
879 | + return; | |
880 | + } | |
678 | 881 | const form = getForm(); |
679 | 882 | const values = form.getFieldsValue(); |
883 | + const resAll = await getOrderList({}); | |
884 | + console.log(resAll, '5656resall'); | |
885 | + const filteredItems = resAll.items.filter((item: { id: string }) => | |
886 | + checkedKeys.value.includes(item.id), | |
887 | + ); | |
888 | + console.log(filteredItems, '5656filteredItems'); | |
680 | 889 | openServiceProfitModal(true, { |
890 | + res: filteredItems, | |
681 | 891 | data: checkedKeys.value, |
892 | + orderList: resAll, | |
893 | + customerCode: selectedCustomCodes.value, | |
894 | + projectNo: selectedProjectNos.value, | |
682 | 895 | searchData: values, |
683 | 896 | }); |
684 | 897 | } |
685 | 898 | |
686 | - function handleProductProfitModal() { | |
899 | + async function handleProductProfitModal() { | |
900 | + if (selectedCustomCodes.value.length > 1) { | |
901 | + error('勾选订单的客户编码需一致'); | |
902 | + return; | |
903 | + } | |
687 | 904 | const form = getForm(); |
688 | 905 | const values = form.getFieldsValue(); |
906 | + const resAll = await getOrderList({}); | |
907 | + const filteredItems = resAll.items.filter((item: { id: string }) => | |
908 | + checkedKeys.value.includes(item.id), | |
909 | + ); | |
689 | 910 | openProductProfitModal(true, { |
911 | + filteredItems: filteredItems, | |
690 | 912 | data: checkedKeys.value, |
691 | 913 | searchData: values, |
914 | + customerCode: selectedCustomCodes.value, | |
915 | + projectNo: selectedProjectNos.value, | |
692 | 916 | }); |
693 | 917 | } |
694 | 918 | ... | ... |
src/views/project/order/tableData.tsx
... | ... | @@ -51,6 +51,11 @@ export const ORDER_LIST_BASE_FIELDS = [ |
51 | 51 | dataIndex: 'projectNo', |
52 | 52 | }, |
53 | 53 | { |
54 | + title: 'Invoice编号', | |
55 | + width: 150, | |
56 | + dataIndex: 'invoiceNo', | |
57 | + }, | |
58 | + { | |
54 | 59 | title: '生产科', |
55 | 60 | width: 150, |
56 | 61 | dataIndex: 'productionDepartment', |
... | ... | @@ -102,7 +107,7 @@ export const ORDER_LIST_BASE_FIELDS = [ |
102 | 107 | }, |
103 | 108 | { |
104 | 109 | title: '产品意见', |
105 | - width: 150, | |
110 | + width: 400, | |
106 | 111 | dataIndex: 'productionComment', |
107 | 112 | }, |
108 | 113 | { |
... | ... | @@ -153,6 +158,13 @@ export const ORDER_LIST_BASE_FIELDS = [ |
153 | 158 | width: 150, |
154 | 159 | dataIndex: 'businessPerson', |
155 | 160 | }, |
161 | + { | |
162 | + field: 'returnOrder', | |
163 | + component: 'Select', | |
164 | + default: '请选择', | |
165 | + label: '是否返单 ', | |
166 | + rules: [{ required: true }], | |
167 | + }, | |
156 | 168 | ]; |
157 | 169 | |
158 | 170 | export const ORDER_LIST_REPORT_FIELDS = [ |
... | ... | @@ -869,7 +881,7 @@ export const FIELDS_BASE_INFO = [ |
869 | 881 | }, |
870 | 882 | { |
871 | 883 | field: 'productionComment', |
872 | - component: 'Input', | |
884 | + component: 'InputTextArea', | |
873 | 885 | rules: [{ required: true }], |
874 | 886 | labelWidth: 150, |
875 | 887 | label: '产品意见', |
... | ... | @@ -1013,20 +1025,20 @@ export const FIELDS_TRACK_STAGE_INFO = [ |
1013 | 1025 | value: '1.1st Fail', |
1014 | 1026 | }, |
1015 | 1027 | { |
1016 | - label: '2.2st ok', | |
1017 | - value: '2.2st ok', | |
1028 | + label: '2.2nd ok', | |
1029 | + value: '2.2nd ok', | |
1018 | 1030 | }, |
1019 | 1031 | { |
1020 | - label: '2.2st Fail', | |
1021 | - value: '2.2st Fail', | |
1032 | + label: '2.2nd Fail', | |
1033 | + value: '2.2nd Fail', | |
1022 | 1034 | }, |
1023 | 1035 | { |
1024 | - label: '3.3st ok', | |
1025 | - value: '3.3st ok', | |
1036 | + label: '3.3rd ok', | |
1037 | + value: '3.3rd ok', | |
1026 | 1038 | }, |
1027 | 1039 | { |
1028 | - label: '3.3st Fail', | |
1029 | - value: '3.3st Fail', | |
1040 | + label: '3.3rd Fail', | |
1041 | + value: '3.3rd Fail', | |
1030 | 1042 | }, |
1031 | 1043 | ], |
1032 | 1044 | }, |
... | ... | @@ -1059,20 +1071,20 @@ export const FIELDS_TRACK_STAGE_INFO = [ |
1059 | 1071 | value: '1.1st Fail', |
1060 | 1072 | }, |
1061 | 1073 | { |
1062 | - label: '2.2st ok', | |
1063 | - value: '2.2st ok', | |
1074 | + label: '2.2nd ok', | |
1075 | + value: '2.2nd ok', | |
1064 | 1076 | }, |
1065 | 1077 | { |
1066 | - label: '2.2st Fail', | |
1067 | - value: '2.2st Fail', | |
1078 | + label: '2.2nd Fail', | |
1079 | + value: '2.2nd Fail', | |
1068 | 1080 | }, |
1069 | 1081 | { |
1070 | - label: '3.3st ok', | |
1071 | - value: '3.3st ok', | |
1082 | + label: '3.3rd ok', | |
1083 | + value: '3.3rd ok', | |
1072 | 1084 | }, |
1073 | 1085 | { |
1074 | - label: '3.3st Fail', | |
1075 | - value: '3.3st Fail', | |
1086 | + label: '3.3rd Fail', | |
1087 | + value: '3.3rd Fail', | |
1076 | 1088 | }, |
1077 | 1089 | ], |
1078 | 1090 | }, |
... | ... | @@ -1105,20 +1117,20 @@ export const FIELDS_TRACK_STAGE_INFO = [ |
1105 | 1117 | value: '1.1st Fail', |
1106 | 1118 | }, |
1107 | 1119 | { |
1108 | - label: '2.2st ok', | |
1109 | - value: '2.2st ok', | |
1120 | + label: '2.2nd ok', | |
1121 | + value: '2.2nd ok', | |
1110 | 1122 | }, |
1111 | 1123 | { |
1112 | - label: '2.2st Fail', | |
1113 | - value: '2.2st Fail', | |
1124 | + label: '2.2nd Fail', | |
1125 | + value: '2.2nd Fail', | |
1114 | 1126 | }, |
1115 | 1127 | { |
1116 | - label: '3.3st ok', | |
1117 | - value: '3.3st ok', | |
1128 | + label: '3.3rd ok', | |
1129 | + value: '3.3rd ok', | |
1118 | 1130 | }, |
1119 | 1131 | { |
1120 | - label: '3.3st Fail', | |
1121 | - value: '3.3st Fail', | |
1132 | + label: '3.3rd Fail', | |
1133 | + value: '3.3rd Fail', | |
1122 | 1134 | }, |
1123 | 1135 | ], |
1124 | 1136 | }, |
... | ... | @@ -1144,20 +1156,20 @@ export const FIELDS_TRACK_STAGE_INFO = [ |
1144 | 1156 | value: '1.1st Fail', |
1145 | 1157 | }, |
1146 | 1158 | { |
1147 | - label: '2.2st ok', | |
1148 | - value: '2.2st ok', | |
1159 | + label: '2.2nd ok', | |
1160 | + value: '2.2nd ok', | |
1149 | 1161 | }, |
1150 | 1162 | { |
1151 | - label: '2.2st Fail', | |
1152 | - value: '2.2st Fail', | |
1163 | + label: '2.2nd Fail', | |
1164 | + value: '2.2nd Fail', | |
1153 | 1165 | }, |
1154 | 1166 | { |
1155 | - label: '3.3st ok', | |
1156 | - value: '3.3st ok', | |
1167 | + label: '3.3rd ok', | |
1168 | + value: '3.3rd ok', | |
1157 | 1169 | }, |
1158 | 1170 | { |
1159 | - label: '3.3st Fail', | |
1160 | - value: '3.3st Fail', | |
1171 | + label: '3.3rd Fail', | |
1172 | + value: '3.3rd Fail', | |
1161 | 1173 | }, |
1162 | 1174 | ], |
1163 | 1175 | }, |
... | ... | @@ -1705,20 +1717,20 @@ export function getFormConfig(businessUsers: any[]): Partial<FormProps> { |
1705 | 1717 | value: '1.1st Fail', |
1706 | 1718 | }, |
1707 | 1719 | { |
1708 | - label: '2.2st ok', | |
1709 | - value: '2.2st ok', | |
1720 | + label: '2.2nd ok', | |
1721 | + value: '2.2nd ok', | |
1710 | 1722 | }, |
1711 | 1723 | { |
1712 | - label: '2.2st Fail', | |
1713 | - value: '2.2st Fail', | |
1724 | + label: '2.2nd Fail', | |
1725 | + value: '2.2nd Fail', | |
1714 | 1726 | }, |
1715 | 1727 | { |
1716 | - label: '3.3st ok', | |
1717 | - value: '3.3st ok', | |
1728 | + label: '3.3rd ok', | |
1729 | + value: '3.3rd ok', | |
1718 | 1730 | }, |
1719 | 1731 | { |
1720 | - label: '3.3st Fail', | |
1721 | - value: '3.3st Fail', | |
1732 | + label: '3.3rd Fail', | |
1733 | + value: '3.3rd Fail', | |
1722 | 1734 | }, |
1723 | 1735 | ], |
1724 | 1736 | }, | ... | ... |
src/views/project/order/type.d.ts
vite.config.ts
... | ... | @@ -20,8 +20,8 @@ export default defineApplicationConfig({ |
20 | 20 | server: { |
21 | 21 | proxy: { |
22 | 22 | '/basic-api/order': { |
23 | - // target: 'http://47.104.8.35:18000', | |
24 | - target: 'http://localhost:8000', | |
23 | + target: 'http://47.104.8.35:18000', | |
24 | + // target: 'http://localhost:8001', | |
25 | 25 | // target: 'http://39.108.227.113:8000', |
26 | 26 | // target: 'http://localhost:8000', |
27 | 27 | // target: 'http://39.108.227.113:3000/mock/35', |
... | ... | @@ -31,8 +31,8 @@ export default defineApplicationConfig({ |
31 | 31 | rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), |
32 | 32 | }, |
33 | 33 | '/api/localStorage/upload': { |
34 | - // target: 'http://47.104.8.35:18000', | |
35 | - target: 'http://localhost:8000', | |
34 | + target: 'http://47.104.8.35:18000', | |
35 | + // target: 'http://localhost:8001', | |
36 | 36 | // target: 'http://39.108.227.113:8000', |
37 | 37 | // target: '192.168.31.250:18000', |
38 | 38 | // target: 'http://localhost:8000', | ... | ... |