Commit 327b80fac800d683c2293565f56792542d0c9b17
1 parent
78ec6a79
业务利润分析完成,应付/应收审核完成
Showing
30 changed files
with
1262 additions
and
394 deletions
src/api/project/global.ts
@@ -8,13 +8,13 @@ enum Api { | @@ -8,13 +8,13 @@ enum Api { | ||
8 | CUSTOMER_SALES = '/order/erp/index/salesStatusEveryCustomer', //每个客户销售额情况 | 8 | CUSTOMER_SALES = '/order/erp/index/salesStatusEveryCustomer', //每个客户销售额情况 |
9 | } | 9 | } |
10 | 10 | ||
11 | -export const getApiData = async () => { | ||
12 | - const res = await defHttp.get<any>({ url: Api.DATA }); | 11 | +export const getApiData = async (params?) => { |
12 | + const res = await defHttp.get<any>({ url: Api.DATA, params }); | ||
13 | return res; | 13 | return res; |
14 | }; | 14 | }; |
15 | 15 | ||
16 | -export const getChartData = async () => { | ||
17 | - const res = await defHttp.get<any>({ url: Api.CHART_DATA }); | 16 | +export const getChartData = async (params?) => { |
17 | + const res = await defHttp.get<any>({ url: Api.CHART_DATA, params }); | ||
18 | return res; | 18 | return res; |
19 | }; | 19 | }; |
20 | 20 |
src/api/project/order.ts
@@ -34,8 +34,8 @@ enum Api { | @@ -34,8 +34,8 @@ enum Api { | ||
34 | 34 | ||
35 | TRACK_HISTORY = '/order/erp/opinion/log/query_by_id', //跟单结果记录 | 35 | TRACK_HISTORY = '/order/erp/opinion/log/query_by_id', //跟单结果记录 |
36 | PASS_CALCULATE = '/order/erp/order/passRate', //一次性通过率 | 36 | PASS_CALCULATE = '/order/erp/order/passRate', //一次性通过率 |
37 | - CREATE_PRODUCT_TEXT = '/order/erp/order/produceReport', //生成生产指标书 | ||
38 | - EXPORT_PRODUCT_TEXT = '/order/erp/order/send', //导出生产指标书 | 37 | + CREATE_PRODUCT_TEXT = '/order/erp/order/produceReport', //生成生产指示书 |
38 | + EXPORT_PRODUCT_TEXT = '/order/erp/order/send', //导出生产指示书 | ||
39 | 39 | ||
40 | BUSINESS_PROFIT_RATIO = '/order/erp/calculate_profit/business_profit_ratio', //业务/研发净利润分析 | 40 | BUSINESS_PROFIT_RATIO = '/order/erp/calculate_profit/business_profit_ratio', //业务/研发净利润分析 |
41 | BUSINESS_PROFIT_RATIO_EXPORT = '/order/erp/calculate_profit/business_profit_ratio_export', //业务/研发净利润分析_导出 | 41 | BUSINESS_PROFIT_RATIO_EXPORT = '/order/erp/calculate_profit/business_profit_ratio_export', //业务/研发净利润分析_导出 |
src/router/routes/modules/project/approve.ts
@@ -16,6 +16,7 @@ const order: AppRouteModule = { | @@ -16,6 +16,7 @@ const order: AppRouteModule = { | ||
16 | RoleEnum.BUSINESS, | 16 | RoleEnum.BUSINESS, |
17 | RoleEnum.TRACKER, | 17 | RoleEnum.TRACKER, |
18 | RoleEnum.INSPECT, | 18 | RoleEnum.INSPECT, |
19 | + RoleEnum.FINANCE, | ||
19 | ], | 20 | ], |
20 | orderNo: 3, | 21 | orderNo: 3, |
21 | icon: 'ion:grid-outline', | 22 | icon: 'ion:grid-outline', |
src/store/modules/user.ts
@@ -189,10 +189,15 @@ export function useUserStoreWithOut() { | @@ -189,10 +189,15 @@ export function useUserStoreWithOut() { | ||
189 | return useUserStore(store); | 189 | return useUserStore(store); |
190 | } | 190 | } |
191 | 191 | ||
192 | +//分析台订单趋势 | ||
193 | +export const dateTime = ref(); | ||
194 | +//分析台时期 | ||
195 | +export const period = ref(); | ||
196 | + | ||
192 | //分析台切换页面变量 | 197 | //分析台切换页面变量 |
193 | export const exchangeTab = ref('tab1'); | 198 | export const exchangeTab = ref('tab1'); |
194 | -//分析台时期 | ||
195 | -// export const period = ref(''); | 199 | + |
200 | +//销售额完成率 | ||
196 | //分析台业务员 | 201 | //分析台业务员 |
197 | export const businessPersonIn = ref(); | 202 | export const businessPersonIn = ref(); |
198 | //分析台客户编码 | 203 | //分析台客户编码 |
src/views/dashboard/analysis/components/GrowCard.vue
@@ -47,21 +47,40 @@ | @@ -47,21 +47,40 @@ | ||
47 | import { growCardList } from '../data'; | 47 | import { growCardList } from '../data'; |
48 | import { useDataStoreWithOut } from '/@/store/modules/data'; | 48 | import { useDataStoreWithOut } from '/@/store/modules/data'; |
49 | import { computed, onMounted, ref, watch, watchEffect } from 'vue'; | 49 | import { computed, onMounted, ref, watch, watchEffect } from 'vue'; |
50 | - import { exchangeTab, businessPersonIn, customerCodeIn } from '/@/store/modules/user'; | 50 | + import { |
51 | + exchangeTab, | ||
52 | + businessPersonIn, | ||
53 | + customerCodeIn, | ||
54 | + dateTime, | ||
55 | + period, | ||
56 | + } from '/@/store/modules/user'; | ||
51 | import { number } from 'vue-types'; | 57 | import { number } from 'vue-types'; |
52 | - import { getSalesData, getCustomerSalesData } from '/@/api/project/global'; | 58 | + import { getSalesData, getApiData } from '/@/api/project/global'; |
53 | import { useOrderStoreWithOut } from '/@/store/modules/order'; | 59 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
54 | 60 | ||
55 | const dataStore = useDataStoreWithOut(); | 61 | const dataStore = useDataStoreWithOut(); |
62 | + const data1 = ref(); | ||
63 | + watch( | ||
64 | + [dateTime, period], | ||
65 | + async ([newDateTime, newPeriod], [oldBusinessPersonIn, oldCustomerCodeIn]) => { | ||
66 | + console.log('businessPersonIn changed from', oldBusinessPersonIn, 'to', newDateTime); | ||
67 | + console.log('customerCodeIn changed from', oldCustomerCodeIn, 'to', newPeriod); | ||
56 | 68 | ||
69 | + // 在这里添加你希望在这两个值改变时执行的逻辑 | ||
70 | + data1.value = await getApiData({ | ||
71 | + dateTime: newDateTime, | ||
72 | + period: newPeriod, | ||
73 | + }); | ||
74 | + }, | ||
75 | + ); | ||
57 | const growCardList = computed(() => { | 76 | const growCardList = computed(() => { |
58 | const data = dataStore.getData; | 77 | const data = dataStore.getData; |
59 | - | 78 | + console.log(data1.value, '5656data1.value'); |
60 | return [ | 79 | return [ |
61 | { | 80 | { |
62 | title: '订单完成', | 81 | title: '订单完成', |
63 | icon: 'visit-count|svg', | 82 | icon: 'visit-count|svg', |
64 | - value: data?.orderFinishedCount || 0, | 83 | + value: data1.value?.allCount || 0, |
65 | total: 120000, | 84 | total: 120000, |
66 | color: 'green', | 85 | color: 'green', |
67 | action: '月', | 86 | action: '月', |
@@ -69,7 +88,7 @@ | @@ -69,7 +88,7 @@ | ||
69 | { | 88 | { |
70 | title: '跟单和质检中', | 89 | title: '跟单和质检中', |
71 | icon: 'total-sales|svg', | 90 | icon: 'total-sales|svg', |
72 | - value: data?.orderInspectingCount || 0, | 91 | + value: data1.value?.trackingAndInspectingList || 0, |
73 | total: 500000, | 92 | total: 500000, |
74 | color: 'blue', | 93 | color: 'blue', |
75 | action: '月', | 94 | action: '月', |
@@ -77,7 +96,7 @@ | @@ -77,7 +96,7 @@ | ||
77 | { | 96 | { |
78 | title: '利润分析表待审核', | 97 | title: '利润分析表待审核', |
79 | icon: 'download-count|svg', | 98 | icon: 'download-count|svg', |
80 | - value: data?.orderProfitWaitAuditCount || 0, | 99 | + value: data1.value?.profitList || 0, |
81 | total: 120000, | 100 | total: 120000, |
82 | color: 'orange', | 101 | color: 'orange', |
83 | action: '周', | 102 | action: '周', |
@@ -85,7 +104,7 @@ | @@ -85,7 +104,7 @@ | ||
85 | { | 104 | { |
86 | title: '项目报告书待审核', | 105 | title: '项目报告书待审核', |
87 | icon: 'transaction|svg', | 106 | icon: 'transaction|svg', |
88 | - value: data?.orderReportWaitAuditCount || 0, | 107 | + value: data1.value?.reportList || 0, |
89 | total: 50000, | 108 | total: 50000, |
90 | color: 'purple', | 109 | color: 'purple', |
91 | action: '年', | 110 | action: '年', |
@@ -93,7 +112,7 @@ | @@ -93,7 +112,7 @@ | ||
93 | { | 112 | { |
94 | title: '订单初始化', | 113 | title: '订单初始化', |
95 | icon: 'transaction|svg', | 114 | icon: 'transaction|svg', |
96 | - value: data?.orderCount || 0, | 115 | + value: data1.value?.orderInitList || 0, |
97 | total: 50000, | 116 | total: 50000, |
98 | color: 'purple', | 117 | color: 'purple', |
99 | action: '年', | 118 | action: '年', |
@@ -108,6 +127,11 @@ | @@ -108,6 +127,11 @@ | ||
108 | // }); | 127 | // }); |
109 | // }); | 128 | // }); |
110 | onMounted(async () => { | 129 | onMounted(async () => { |
130 | + data1.value = await getApiData({ | ||
131 | + dateTime: dateTime.value, | ||
132 | + period: period.value, | ||
133 | + }); | ||
134 | + console.log(data1.value, '56565656'); | ||
111 | data2.value = await getSalesData({ | 135 | data2.value = await getSalesData({ |
112 | businessPersonIn: businessPersonIn.value, | 136 | businessPersonIn: businessPersonIn.value, |
113 | customerCodeIn: customerCodeIn.value, | 137 | customerCodeIn: customerCodeIn.value, |
@@ -115,14 +139,14 @@ | @@ -115,14 +139,14 @@ | ||
115 | }); | 139 | }); |
116 | watch( | 140 | watch( |
117 | [businessPersonIn, customerCodeIn], | 141 | [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); | 142 | + async ([newDateTime, newPeriod], [oldBusinessPersonIn, oldCustomerCodeIn]) => { |
143 | + console.log('businessPersonIn changed from', oldBusinessPersonIn, 'to', newDateTime); | ||
144 | + console.log('customerCodeIn changed from', oldCustomerCodeIn, 'to', newPeriod); | ||
121 | 145 | ||
122 | // 在这里添加你希望在这两个值改变时执行的逻辑 | 146 | // 在这里添加你希望在这两个值改变时执行的逻辑 |
123 | data2.value = await getSalesData({ | 147 | data2.value = await getSalesData({ |
124 | - businessPersonIn: newBusinessPersonIn, | ||
125 | - customerCodeIn: newCustomerCodeIn, | 148 | + businessPersonIn: newDateTime, |
149 | + customerCodeIn: newPeriod, | ||
126 | }); | 150 | }); |
127 | }, | 151 | }, |
128 | ); | 152 | ); |
src/views/dashboard/analysis/components/VisitAnalysis.vue
1 | <template> | 1 | <template> |
2 | + <span style="margin-left: 50px; font-size: 18px">选择年份:</span> | ||
3 | + <a-select | ||
4 | + v-model:value="yearValue" | ||
5 | + show-search | ||
6 | + placeholder="请选择" | ||
7 | + style="width: 200px" | ||
8 | + :options="yearOptions" | ||
9 | + :filter-option="filterOption" | ||
10 | + @change="handleChangeYear" | ||
11 | + /> | ||
12 | + <div style="position: fixed; top: 80px; right: 70px"> | ||
13 | + <a-radio-group | ||
14 | + v-model:value="periodCopy" | ||
15 | + class="custom-radio-group" | ||
16 | + :style="{ marginLeft: '100px' }" | ||
17 | + > | ||
18 | + <a-radio-button value="月" @click="handlePeriodChange('月')">月</a-radio-button> | ||
19 | + <a-radio-button value="年" @click="handlePeriodChange('年')">年</a-radio-button> | ||
20 | + </a-radio-group> | ||
21 | + </div> | ||
2 | <div ref="chartRef" :style="{ height: '500px', width }"></div> | 22 | <div ref="chartRef" :style="{ height: '500px', width }"></div> |
3 | </template> | 23 | </template> |
4 | 24 | ||
@@ -8,15 +28,71 @@ | @@ -8,15 +28,71 @@ | ||
8 | import { basicProps } from './props'; | 28 | import { basicProps } from './props'; |
9 | import { max } from 'lodash-es'; | 29 | import { max } from 'lodash-es'; |
10 | import { useDataStoreWithOut } from '/@/store/modules/data'; | 30 | import { useDataStoreWithOut } from '/@/store/modules/data'; |
31 | + import { getChartData } from '/@/api/project/global'; | ||
32 | + import { dateTime, period } from '/@/store/modules/user'; | ||
33 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
11 | 34 | ||
12 | defineProps({ | 35 | defineProps({ |
13 | ...basicProps, | 36 | ...basicProps, |
14 | }); | 37 | }); |
38 | + const yearValue = ref(); | ||
39 | + const yearOptions = [ | ||
40 | + // { | ||
41 | + // label: '2025', | ||
42 | + // value: 2025, | ||
43 | + // }, | ||
44 | + { | ||
45 | + label: '2024', | ||
46 | + value: 2024, | ||
47 | + }, | ||
48 | + { | ||
49 | + label: '2023', | ||
50 | + value: 2023, | ||
51 | + }, | ||
52 | + ]; | ||
53 | + const periodCopy = ref(); | ||
54 | + const { createMessage } = useMessage(); //错误提示组件 | ||
55 | + const { error } = createMessage; | ||
15 | const chartRef = ref<HTMLDivElement | null>(null); | 56 | const chartRef = ref<HTMLDivElement | null>(null); |
16 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); | 57 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); |
58 | + const filterOption = (input: string, option: any) => { | ||
59 | + return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0; | ||
60 | + }; | ||
61 | + function handlePeriodChange(value) { | ||
62 | + //没选年份报错 | ||
63 | + if (value == '月') { | ||
64 | + if (dateTime.value == undefined) { | ||
65 | + error('请选择年份'); | ||
66 | + return; | ||
67 | + } | ||
68 | + } else if (value == '年') { | ||
69 | + yearValue.value = null; | ||
70 | + } | ||
71 | + period.value = value; | ||
72 | + } | ||
73 | + function handleChangeYear(value) { | ||
74 | + if (period.value == null) { | ||
75 | + period.value = '月'; | ||
76 | + periodCopy.value = '月'; | ||
77 | + } | ||
78 | + yearValue.value = value; | ||
79 | + dateTime.value = yearValue.value; | ||
80 | + } | ||
17 | const dataStore = useDataStoreWithOut(); | 81 | const dataStore = useDataStoreWithOut(); |
18 | - watchEffect(() => { | ||
19 | - const data = dataStore?.getChartData || {}; | 82 | + //监控选择器变化 |
83 | + watchEffect(async () => { | ||
84 | + // const data = dataStore?.getChartData || {}; | ||
85 | + const chartData = await getChartData({ | ||
86 | + dateTime: dateTime.value, | ||
87 | + period: period.value, | ||
88 | + }); | ||
89 | + const x = [], | ||
90 | + y = []; | ||
91 | + for (const key in chartData) { | ||
92 | + x.push(chartData[key].date); | ||
93 | + y.push(chartData[key].count); | ||
94 | + } | ||
95 | + const data = { x, y }; | ||
20 | const maxY = data?.y ? max(data?.y) : 0; | 96 | const maxY = data?.y ? max(data?.y) : 0; |
21 | setOptions({ | 97 | setOptions({ |
22 | tooltip: { | 98 | tooltip: { |
@@ -30,7 +106,6 @@ | @@ -30,7 +106,6 @@ | ||
30 | }, | 106 | }, |
31 | xAxis: { | 107 | xAxis: { |
32 | type: 'category', | 108 | type: 'category', |
33 | - boundaryGap: false, | ||
34 | data: data?.x, | 109 | data: data?.x, |
35 | splitLine: { | 110 | splitLine: { |
36 | show: true, | 111 | show: true, |
@@ -87,3 +162,29 @@ | @@ -87,3 +162,29 @@ | ||
87 | }); | 162 | }); |
88 | }); | 163 | }); |
89 | </script> | 164 | </script> |
165 | +<style scoped> | ||
166 | + .custom-radio-group .ant-radio-button-wrapper { | ||
167 | + border-color: #1684fc; /* 未选中按钮的边框颜色 */ | ||
168 | + background-color: white; /* 未选中按钮的背景颜色为白色 */ | ||
169 | + color: #1684fc; /* 未选中按钮的文字颜色为 #1684fc */ | ||
170 | + } | ||
171 | + | ||
172 | + .custom-radio-group .ant-radio-button-wrapper-checked { | ||
173 | + border-color: #1684fc; /* 选中按钮的边框颜色 */ | ||
174 | + background-color: #1684fc; /* 选中按钮的背景颜色为 #1684fc */ | ||
175 | + color: white; /* 选中按钮的文字颜色为白色 */ | ||
176 | + } | ||
177 | + | ||
178 | + .custom-radio-group .ant-radio-button-wrapper-checked:hover { | ||
179 | + background-color: #1684fc; /* 悬停在选中按钮时保持相同的背景颜色 */ | ||
180 | + color: white; /* 悬停在选中按钮时保持文字为白色 */ | ||
181 | + } | ||
182 | + | ||
183 | + .custom-radio-group .ant-radio-button-wrapper:hover { | ||
184 | + border-color: #1684fc; /* 悬停在未选中按钮时的边框颜色 */ | ||
185 | + } | ||
186 | + | ||
187 | + .custom-radio-group .ant-radio-button-wrapper:not(.ant-radio-button-wrapper-checked):hover { | ||
188 | + color: #1684fc; /* 悬停在未选中按钮时文字颜色为 #1684fc */ | ||
189 | + } | ||
190 | +</style> |
src/views/dashboard/analysis/components/VisitAnalysisBar.vue
@@ -55,7 +55,7 @@ | @@ -55,7 +55,7 @@ | ||
55 | </div></div | 55 | </div></div |
56 | > | 56 | > |
57 | <div v-if="role !== ROLE.ADMIN" style="margin-bottom: 60px"></div> | 57 | <div v-if="role !== ROLE.ADMIN" style="margin-bottom: 60px"></div> |
58 | - <div ref="chartRef" :style="{ height, width }"></div> | 58 | + <div ref="chartRef" :style="{ height: '400px', width }"></div> |
59 | </template> | 59 | </template> |
60 | <script lang="ts"> | 60 | <script lang="ts"> |
61 | import { basicProps } from './props'; | 61 | import { basicProps } from './props'; |
@@ -177,23 +177,28 @@ | @@ -177,23 +177,28 @@ | ||
177 | }, | 177 | }, |
178 | }, | 178 | }, |
179 | }, | 179 | }, |
180 | - grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, | 180 | + legend: { |
181 | + data: ['销售额', '销售目标'], | ||
182 | + }, | ||
183 | + grid: { left: '1%', right: '1%', top: '10 %', bottom: 0, containLabel: true }, | ||
181 | xAxis: { | 184 | xAxis: { |
182 | type: 'category', | 185 | type: 'category', |
183 | data: customerChartData1?.x, | 186 | data: customerChartData1?.x, |
184 | }, | 187 | }, |
185 | yAxis: { | 188 | yAxis: { |
186 | type: 'value', | 189 | type: 'value', |
187 | - // max: 8000, | ||
188 | - splitNumber: 4, | 190 | + // // max: 8000, |
191 | + // splitNumber: 4, | ||
189 | }, | 192 | }, |
190 | series: [ | 193 | series: [ |
191 | { | 194 | { |
195 | + name: '销售额', | ||
192 | data: customerChartData1?.y, | 196 | data: customerChartData1?.y, |
193 | type: 'bar', | 197 | type: 'bar', |
194 | barMaxWidth: 80, | 198 | barMaxWidth: 80, |
195 | }, | 199 | }, |
196 | { | 200 | { |
201 | + name: '销售目标', | ||
197 | smooth: true, | 202 | smooth: true, |
198 | data: customerChartData1?.z, | 203 | data: customerChartData1?.z, |
199 | type: 'line', | 204 | type: 'line', |
src/views/project/approve/FieldPanel.vue
@@ -143,6 +143,11 @@ | @@ -143,6 +143,11 @@ | ||
143 | dataIndex: 'picUrl', | 143 | dataIndex: 'picUrl', |
144 | width: 150, | 144 | width: 150, |
145 | }, | 145 | }, |
146 | + { | ||
147 | + title: '申请原因', | ||
148 | + dataIndex: 'applyRemark', | ||
149 | + width: 150, | ||
150 | + }, | ||
146 | ]; | 151 | ]; |
147 | 152 | ||
148 | if (props.isApproved) { | 153 | if (props.isApproved) { |
src/views/project/approve/PayPanel.vue
@@ -12,6 +12,7 @@ | @@ -12,6 +12,7 @@ | ||
12 | </template> | 12 | </template> |
13 | <template v-if="column.key === 'action'"> | 13 | <template v-if="column.key === 'action'"> |
14 | <TableAction | 14 | <TableAction |
15 | + v-if="!isApproved" | ||
15 | :actions="[ | 16 | :actions="[ |
16 | { | 17 | { |
17 | label: '编辑', | 18 | label: '编辑', |
@@ -20,15 +21,29 @@ | @@ -20,15 +21,29 @@ | ||
20 | }, | 21 | }, |
21 | ]" | 22 | ]" |
22 | /> | 23 | /> |
24 | + <TableAction | ||
25 | + v-if="isApproved" | ||
26 | + :actions="[ | ||
27 | + { | ||
28 | + label: '详情', | ||
29 | + // icon: 'ic:outline-delete-outline', | ||
30 | + onClick: handleDetail.bind(null, record), | ||
31 | + }, | ||
32 | + ]" | ||
33 | + /> | ||
23 | </template> | 34 | </template> |
24 | </template> | 35 | </template> |
25 | </BasicTable> | 36 | </BasicTable> |
37 | + <!-- :showFooter="!isApproved && role === ROLE.ADMIN" --> | ||
38 | + | ||
26 | <BasicModal | 39 | <BasicModal |
27 | - :showFooter="!isApproved && role === ROLE.ADMIN" | 40 | + :formFooter="!isApproved && role === ROLE.ADMIN" |
28 | @register="registerModal" | 41 | @register="registerModal" |
29 | title="申请信息" | 42 | title="申请信息" |
30 | okText="通过" | 43 | okText="通过" |
31 | @ok="handleTrue" | 44 | @ok="handleTrue" |
45 | + :showCancelBtn="!isApproved && role === ROLE.ADMIN" | ||
46 | + :showOkBtn="!isApproved && role === ROLE.ADMIN" | ||
32 | > | 47 | > |
33 | <Description | 48 | <Description |
34 | class="mt-4" | 49 | class="mt-4" |
@@ -39,7 +54,7 @@ | @@ -39,7 +54,7 @@ | ||
39 | :schema="schema" | 54 | :schema="schema" |
40 | /> | 55 | /> |
41 | <template #appendFooter> | 56 | <template #appendFooter> |
42 | - <a-button @click="handleFalse"> 不通过</a-button> | 57 | + <a-button v-if="!isApproved && role === ROLE.ADMIN" @click="handleFalse"> 不通过</a-button> |
43 | </template> | 58 | </template> |
44 | </BasicModal> | 59 | </BasicModal> |
45 | <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> | 60 | <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> |
@@ -84,29 +99,30 @@ | @@ -84,29 +99,30 @@ | ||
84 | const id = ref(''); | 99 | const id = ref(''); |
85 | 100 | ||
86 | const mockData = ref(); | 101 | const mockData = ref(); |
87 | - const schema: DescItem[] = [ | 102 | + const actualPayCalculate = ref(0); |
103 | + const schema = [ | ||
88 | { | 104 | { |
89 | - field: 'actualReceivableAmount', | 105 | + field: 'actualPayedAmount', |
90 | label: '生产科实际应付金额汇总', | 106 | label: '生产科实际应付金额汇总', |
91 | }, | 107 | }, |
92 | { | 108 | { |
93 | - field: 'all', | 109 | + field: 'payedDate', |
94 | label: '生产科付款日期', | 110 | label: '生产科付款日期', |
95 | }, | 111 | }, |
96 | { | 112 | { |
97 | - field: 'deductAmount', | 113 | + field: 'actualPayedDate', |
98 | label: '实际付款日期', | 114 | label: '实际付款日期', |
99 | }, | 115 | }, |
100 | { | 116 | { |
101 | - field: 'productionDepartmentTotalPrice', | 117 | + field: 'totalProductionAmount', |
102 | label: '生产科总金额汇总', | 118 | label: '生产科总金额汇总', |
103 | }, | 119 | }, |
104 | { | 120 | { |
105 | - field: 'actualPayedAmount', | 121 | + field: 'totalActualPayedAmount', |
106 | label: '实际付款金额汇总', | 122 | label: '实际付款金额汇总', |
107 | }, | 123 | }, |
108 | { | 124 | { |
109 | - field: 'actualReceivableAmount', | 125 | + field: 'deductAmount', |
110 | label: '生产科扣款金额汇总', | 126 | label: '生产科扣款金额汇总', |
111 | }, | 127 | }, |
112 | ]; | 128 | ]; |
@@ -128,19 +144,31 @@ | @@ -128,19 +144,31 @@ | ||
128 | width: 150, | 144 | width: 150, |
129 | customRender: (column) => { | 145 | customRender: (column) => { |
130 | const { record } = column || {}; | 146 | const { record } = column || {}; |
131 | - console.log(record, '56565repro'); | ||
132 | - return record?.fieldInfos?.invoiceBillOrderDO?.innerNo; | 147 | + return record?.orderBaseInfo?.innerNo; |
133 | }, | 148 | }, |
134 | }, | 149 | }, |
135 | { | 150 | { |
136 | title: '审核类型', | 151 | title: '审核类型', |
137 | dataIndex: 'productionDepartment', | 152 | dataIndex: 'productionDepartment', |
138 | width: 150, | 153 | width: 150, |
154 | + customRender: (column) => { | ||
155 | + const { record } = column || {}; | ||
156 | + if (record?.type === 40) { | ||
157 | + return '生产科应付款'; | ||
158 | + } else if (record?.type == 50) { | ||
159 | + return '生产科发票'; | ||
160 | + } | ||
161 | + }, | ||
139 | }, | 162 | }, |
140 | { | 163 | { |
141 | title: '生产科', | 164 | title: '生产科', |
142 | dataIndex: 'productionDepartment', | 165 | dataIndex: 'productionDepartment', |
143 | width: 150, | 166 | width: 150, |
167 | + customRender: (column) => { | ||
168 | + const { record } = column || {}; | ||
169 | + console.log(record, '56565repro'); | ||
170 | + return record?.fieldInfos?.checkBillOrderDO?.deductDept; | ||
171 | + }, | ||
144 | }, | 172 | }, |
145 | ]; | 173 | ]; |
146 | 174 | ||
@@ -204,8 +232,7 @@ | @@ -204,8 +232,7 @@ | ||
204 | 232 | ||
205 | async function handleDetail(data) { | 233 | async function handleDetail(data) { |
206 | openModal(true, { data }); | 234 | openModal(true, { data }); |
207 | - mockData.value = data.fieldInfos.invoiceBillOrderDO; | ||
208 | - console.log(mockData.value, 5656); | 235 | + mockData.value = data.fieldInfos.checkBillOrderDO; |
209 | id.value = data.id; | 236 | id.value = data.id; |
210 | } | 237 | } |
211 | 238 |
src/views/project/approve/ProfitPanel.vue
@@ -93,7 +93,7 @@ | @@ -93,7 +93,7 @@ | ||
93 | const { record } = column || {}; | 93 | const { record } = column || {}; |
94 | return record?.orderBaseInfo?.innerNo; | 94 | return record?.orderBaseInfo?.innerNo; |
95 | }, | 95 | }, |
96 | - }, | 96 | + }, |
97 | { | 97 | { |
98 | title: '图片', | 98 | title: '图片', |
99 | dataIndex: 'picUrl', | 99 | dataIndex: 'picUrl', |
src/views/project/approve/ReceivePanel.vue
@@ -12,6 +12,7 @@ | @@ -12,6 +12,7 @@ | ||
12 | </template> | 12 | </template> |
13 | <template v-if="column.key === 'action'"> | 13 | <template v-if="column.key === 'action'"> |
14 | <TableAction | 14 | <TableAction |
15 | + v-if="!isApproved" | ||
15 | :actions="[ | 16 | :actions="[ |
16 | { | 17 | { |
17 | label: '编辑', | 18 | label: '编辑', |
@@ -20,15 +21,27 @@ | @@ -20,15 +21,27 @@ | ||
20 | }, | 21 | }, |
21 | ]" | 22 | ]" |
22 | /> | 23 | /> |
24 | + <TableAction | ||
25 | + v-if="isApproved" | ||
26 | + :actions="[ | ||
27 | + { | ||
28 | + label: '详情', | ||
29 | + // icon: 'ic:outline-delete-outline', | ||
30 | + onClick: handleDetail.bind(null, record), | ||
31 | + }, | ||
32 | + ]" | ||
33 | + /> | ||
23 | </template> | 34 | </template> |
24 | </template> | 35 | </template> |
25 | </BasicTable> | 36 | </BasicTable> |
26 | <BasicModal | 37 | <BasicModal |
27 | - :showFooter="!isApproved && role === ROLE.ADMIN" | 38 | + :formFooter="!isApproved && role === ROLE.ADMIN" |
28 | @register="registerModal" | 39 | @register="registerModal" |
29 | title="申请信息" | 40 | title="申请信息" |
30 | okText="通过" | 41 | okText="通过" |
31 | @ok="handleTrue" | 42 | @ok="handleTrue" |
43 | + :showCancelBtn="!isApproved && role === ROLE.ADMIN" | ||
44 | + :showOkBtn="!isApproved && role === ROLE.ADMIN" | ||
32 | > | 45 | > |
33 | <Description | 46 | <Description |
34 | class="mt-4" | 47 | class="mt-4" |
@@ -39,7 +52,7 @@ | @@ -39,7 +52,7 @@ | ||
39 | :schema="schema" | 52 | :schema="schema" |
40 | /> | 53 | /> |
41 | <template #appendFooter> | 54 | <template #appendFooter> |
42 | - <a-button @click="handleFalse"> 不通过</a-button> | 55 | + <a-button v-if="!isApproved && role === ROLE.ADMIN" @click="handleFalse"> 不通过</a-button> |
43 | </template> | 56 | </template> |
44 | </BasicModal> | 57 | </BasicModal> |
45 | <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> | 58 | <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> |
@@ -90,7 +103,7 @@ | @@ -90,7 +103,7 @@ | ||
90 | label: '实际收款金额汇总', | 103 | label: '实际收款金额汇总', |
91 | }, | 104 | }, |
92 | { | 105 | { |
93 | - field: 'all', | 106 | + field: 'totalCustomerAmount', |
94 | label: '客户总价金额汇总', | 107 | label: '客户总价金额汇总', |
95 | }, | 108 | }, |
96 | { | 109 | { |
@@ -102,7 +115,7 @@ | @@ -102,7 +115,7 @@ | ||
102 | label: '必须回款日期', | 115 | label: '必须回款日期', |
103 | }, | 116 | }, |
104 | { | 117 | { |
105 | - field: 'addr', | 118 | + field: 'actualRefundDate', |
106 | label: '实际回款日期', | 119 | label: '实际回款日期', |
107 | }, | 120 | }, |
108 | { | 121 | { |
@@ -138,7 +151,7 @@ | @@ -138,7 +151,7 @@ | ||
138 | width: 150, | 151 | width: 150, |
139 | customRender: (column) => { | 152 | customRender: (column) => { |
140 | const { record } = column || {}; | 153 | const { record } = column || {}; |
141 | - return record?.fieldInfos?.invoiceBillOrderDO?.innnerNo; | 154 | + return record?.orderBaseInfo?.innerNo; |
142 | }, | 155 | }, |
143 | }, | 156 | }, |
144 | // { | 157 | // { |
@@ -213,7 +226,7 @@ | @@ -213,7 +226,7 @@ | ||
213 | async function handleDetail(data) { | 226 | async function handleDetail(data) { |
214 | openModal(true, { data }); | 227 | openModal(true, { data }); |
215 | mockData.value = data.fieldInfos.invoiceBillOrderDO; | 228 | mockData.value = data.fieldInfos.invoiceBillOrderDO; |
216 | - console.log(mockData.value, 5656); | 229 | + console.log(data, 5656777); |
217 | id.value = data.id; | 230 | id.value = data.id; |
218 | } | 231 | } |
219 | 232 |
src/views/project/config/CreateModal.vue
@@ -58,16 +58,7 @@ | @@ -58,16 +58,7 @@ | ||
58 | { | 58 | { |
59 | field: 'relationValue', | 59 | field: 'relationValue', |
60 | component: 'InputNumber', | 60 | component: 'InputNumber', |
61 | - label: | ||
62 | - props.column === 1 | ||
63 | - ? '利润率' | ||
64 | - : props.column === 5 | ||
65 | - ? '回款时间' | ||
66 | - : props.column === 6 | ||
67 | - ? '固定成本' | ||
68 | - : props.column === 7 | ||
69 | - ? '销售额' | ||
70 | - : '包装费用', | 61 | + label: props.column === 1 ? '利润率' : '包装费用', |
71 | rules: [{ required: true }], | 62 | rules: [{ required: true }], |
72 | colProps: { | 63 | colProps: { |
73 | span: 24, | 64 | span: 24, |
@@ -105,16 +96,7 @@ | @@ -105,16 +96,7 @@ | ||
105 | settingName: '客户编码', | 96 | settingName: '客户编码', |
106 | settingValue: values.settingValue, | 97 | settingValue: values.settingValue, |
107 | settingType: 1, | 98 | settingType: 1, |
108 | - // relationCode: props.column === 1 ? 'profitRate' : 'packetPrice', | ||
109 | - relationCode: | ||
110 | - props.column === 1 | ||
111 | - ? 'profitRate' | ||
112 | - : props.column === 5 | ||
113 | - ? 'orderHodTime' | ||
114 | - : props.column === 7 | ||
115 | - ? 'salesAmount' | ||
116 | - : 'packetPrice', | ||
117 | - | 99 | + relationCode: props.column === 1 ? 'profitRate' : 'packetPrice', |
118 | relationName: '包装费用', | 100 | relationName: '包装费用', |
119 | relationValue: values.relationValue, | 101 | relationValue: values.relationValue, |
120 | }; | 102 | }; |
src/views/project/config/TablePanel.vue
1 | <template> | 1 | <template> |
2 | <BasicTable @register="registerTable" :bordered="true"> | 2 | <BasicTable @register="registerTable" :bordered="true"> |
3 | <template #toolbar> | 3 | <template #toolbar> |
4 | - <a-button v-if="props.column !== 3" type="primary" @click="handleCreateModal">新建</a-button> | 4 | + <a-button |
5 | + v-if="props.column !== 3 && props.column !== 6" | ||
6 | + type="primary" | ||
7 | + @click="handleCreateModal" | ||
8 | + >新建</a-button | ||
9 | + > | ||
10 | + <a-button v-if="props.column == 6" type="primary" @click="handleCostCreate">新建</a-button> | ||
5 | </template> | 11 | </template> |
6 | <template #bodyCell="{ column, record }"> | 12 | <template #bodyCell="{ column, record }"> |
7 | <template v-if="column.key === 'action'"> | 13 | <template v-if="column.key === 'action'"> |
@@ -9,6 +15,8 @@ | @@ -9,6 +15,8 @@ | ||
9 | </template> | 15 | </template> |
10 | </template> | 16 | </template> |
11 | </BasicTable> | 17 | </BasicTable> |
18 | + <CostEdit @register="registerEdit" @success="handleModalSuccess" /> | ||
19 | + <CostCreate @register="registerCostCreate" @modal-success="handleModalSuccess" /> | ||
12 | <CreateModal | 20 | <CreateModal |
13 | @register="createModalRegister" | 21 | @register="createModalRegister" |
14 | @modal-success="handleModalSuccess" | 22 | @modal-success="handleModalSuccess" |
@@ -21,6 +29,9 @@ | @@ -21,6 +29,9 @@ | ||
21 | import { deleteConfig, getList, saveConfig } from '/@/api/sys/config'; | 29 | import { deleteConfig, getList, saveConfig } from '/@/api/sys/config'; |
22 | import { COLUMNS } from './data'; | 30 | import { COLUMNS } from './data'; |
23 | import { useModal } from '/@/components/Modal'; | 31 | import { useModal } from '/@/components/Modal'; |
32 | + import { useDrawer } from '/@/components/Drawer'; | ||
33 | + import CostEdit from './costEdit.vue'; | ||
34 | + import CostCreate from './costCreate.vue'; | ||
24 | 35 | ||
25 | const props = defineProps({ | 36 | const props = defineProps({ |
26 | searchInfo: { | 37 | searchInfo: { |
@@ -31,6 +42,8 @@ | @@ -31,6 +42,8 @@ | ||
31 | }, | 42 | }, |
32 | }); | 43 | }); |
33 | const [createModalRegister, { openModal }] = useModal(); | 44 | const [createModalRegister, { openModal }] = useModal(); |
45 | + const [registerCostCreate, { openModal: openCostCreateModal }] = useModal(); | ||
46 | + const [registerEdit, { openDrawer: openDrawerEdit }] = useDrawer(); | ||
34 | 47 | ||
35 | const [registerTable, { reload }] = useTable({ | 48 | const [registerTable, { reload }] = useTable({ |
36 | api: getList, | 49 | api: getList, |
@@ -52,10 +65,27 @@ | @@ -52,10 +65,27 @@ | ||
52 | function createActions(record: any): any[] { | 65 | function createActions(record: any): any[] { |
53 | if (!record.editable) { | 66 | if (!record.editable) { |
54 | return [ | 67 | return [ |
55 | - { | ||
56 | - label: '编辑', | ||
57 | - onClick: handleEdit.bind(null, record), | ||
58 | - }, | 68 | + // { |
69 | + // ...(props.column !== 6 && { | ||
70 | + // label: '编辑', | ||
71 | + // onClick: handleEdit.bind(null, record), | ||
72 | + // }), | ||
73 | + // }, | ||
74 | + ...(props.column === 6 | ||
75 | + ? [ | ||
76 | + { | ||
77 | + label: '编辑', | ||
78 | + onClick: handleCostEdit.bind(null, record), | ||
79 | + }, | ||
80 | + ] | ||
81 | + : props.column !== 6 | ||
82 | + ? [ | ||
83 | + { | ||
84 | + label: '编辑', | ||
85 | + onClick: handleEdit.bind(null, record), | ||
86 | + }, | ||
87 | + ] | ||
88 | + : []), | ||
59 | { | 89 | { |
60 | ...(props.column !== 3 && { | 90 | ...(props.column !== 3 && { |
61 | label: '删除', | 91 | label: '删除', |
@@ -92,7 +122,21 @@ | @@ -92,7 +122,21 @@ | ||
92 | handleCancel(record); | 122 | handleCancel(record); |
93 | reload(); | 123 | reload(); |
94 | } | 124 | } |
95 | - | 125 | + function handleCostEdit(record: any) { |
126 | + console.log('5656hasedit'); | ||
127 | + openDrawerEdit(true, { | ||
128 | + data: record, | ||
129 | + isUpdate: true, | ||
130 | + }); | ||
131 | + } | ||
132 | + function handleCostCreate(record: any) { | ||
133 | + console.log(56561); | ||
134 | + openCostCreateModal(true, { | ||
135 | + data: record, | ||
136 | + isUpdate: true, | ||
137 | + }); | ||
138 | + console.log(56562); | ||
139 | + } | ||
96 | function handleEdit(record: any) { | 140 | function handleEdit(record: any) { |
97 | record.onEdit?.(true); | 141 | record.onEdit?.(true); |
98 | } | 142 | } |
src/views/project/config/costCreate.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicModal | ||
3 | + v-bind="$attrs" | ||
4 | + destroyOnClose | ||
5 | + @register="register" | ||
6 | + title="创建配置" | ||
7 | + width="600px" | ||
8 | + @visible-change="handleShow" | ||
9 | + @ok="handleOk" | ||
10 | + > | ||
11 | + <a-space direction="vertical" style="width: 100%"> | ||
12 | + <div | ||
13 | + ><span style="margin-right: 8px">客户编码:</span> | ||
14 | + <a-select | ||
15 | + ref="select" | ||
16 | + style="width: 100%" | ||
17 | + v-model:value="customerCode" | ||
18 | + :options="customerCodeOptions" | ||
19 | + /></div> | ||
20 | + <div | ||
21 | + ><span style="margin-right: 8px; width: 80%">固定成本:</span> | ||
22 | + <a-input v-model:value="fixCost" | ||
23 | + /></div> | ||
24 | + <div | ||
25 | + ><span style="margin-right: 8px; width: 80%">提成比例:</span> | ||
26 | + <a-input v-model:value="ratio" /> | ||
27 | + </div> | ||
28 | + <div | ||
29 | + ><span style="margin-right: 8px; width: 80%">西班牙提成比例:</span> | ||
30 | + <a-input v-model:value="spainRatio" /> | ||
31 | + </div> | ||
32 | + <div | ||
33 | + ><span style="margin-right: 8px; width: 80%">生产提成单价:</span> | ||
34 | + <a-input v-model:value="price" /> | ||
35 | + </div> | ||
36 | + </a-space> | ||
37 | + </BasicModal> | ||
38 | +</template> | ||
39 | +<script lang="ts"> | ||
40 | + import { defineComponent, ref, defineEmits } from 'vue'; | ||
41 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | ||
42 | + import { orderGravity } from '/@/api/project/order'; | ||
43 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | ||
44 | + import { useOrderInfo } from '/@/hooks/component/order'; | ||
45 | + import { BasicForm, useForm } from '/@/components/Form/index'; | ||
46 | + import { addConfig } from '/@/api/sys/config'; | ||
47 | + | ||
48 | + export default defineComponent({ | ||
49 | + components: { BasicModal, BasicForm }, | ||
50 | + props: { | ||
51 | + column: { type: Number }, | ||
52 | + }, | ||
53 | + emits: ['modal-success'], | ||
54 | + setup(props, { emit }) { | ||
55 | + const orderStore = useOrderStoreWithOut(); | ||
56 | + const loading = ref(true); | ||
57 | + const activeUser = ref(); | ||
58 | + const info = ref(); | ||
59 | + const [register, { setModalProps, closeModal }] = useModalInner(async (data) => { | ||
60 | + listAll.value = data; | ||
61 | + console.log(listAll.value, '5656modaldata.value'); | ||
62 | + }); | ||
63 | + //获取现有的列表 | ||
64 | + const listAll = ref(); | ||
65 | + const fixCost = ref(); | ||
66 | + const ratio = ref(); | ||
67 | + const spainRatio = ref(); | ||
68 | + const price = ref(); | ||
69 | + // const relationValue = ref(); | ||
70 | + const customerCode = ref(); | ||
71 | + const relationValue = ref([ | ||
72 | + { | ||
73 | + relationCode: 'fixCost', | ||
74 | + relationName: '固定成本', | ||
75 | + relationValue: '', | ||
76 | + }, | ||
77 | + { | ||
78 | + relationCode: 'ratio', | ||
79 | + relationName: '提成比例', | ||
80 | + relationValue: '', | ||
81 | + }, | ||
82 | + { | ||
83 | + relationCode: 'spainRatio', | ||
84 | + relationName: '西班牙提成比例', | ||
85 | + relationValue: '', | ||
86 | + }, | ||
87 | + { | ||
88 | + relationCode: 'price', | ||
89 | + relationName: '生产提成单价', | ||
90 | + relationValue: '', | ||
91 | + }, | ||
92 | + ]); | ||
93 | + // const loading = ref(true); | ||
94 | + | ||
95 | + const { customerCode: customerCodeOptions } = useOrderInfo(orderStore); | ||
96 | + | ||
97 | + function handleShow(visible: boolean) { | ||
98 | + if (visible) { | ||
99 | + loading.value = true; | ||
100 | + // setModalProps({ loading: true, confirmLoading: true }); | ||
101 | + setModalProps({ loading: false, confirmLoading: false }); | ||
102 | + } | ||
103 | + } | ||
104 | + | ||
105 | + async function handleOk() { | ||
106 | + try { | ||
107 | + relationValue.value[0].relationValue = fixCost.value; | ||
108 | + relationValue.value[1].relationValue = ratio.value; | ||
109 | + relationValue.value[2].relationValue = spainRatio.value; | ||
110 | + relationValue.value[3].relationValue = price.value; | ||
111 | + await addConfig({ | ||
112 | + settingCode: 'customerCode', | ||
113 | + settingName: '客户提成成本配置', | ||
114 | + settingValue: customerCode.value, | ||
115 | + settingType: 3, | ||
116 | + relationCode: 'costSettingItem', | ||
117 | + relationName: '成本配置项集合', | ||
118 | + costSettingItemVOS: relationValue.value, | ||
119 | + }); | ||
120 | + emit('modal-success'); | ||
121 | + closeModal(); | ||
122 | + } catch (error) { | ||
123 | + console.log('%c [ error ]-108', 'font-size:13px; background:pink; color:#bf2c9f;', error); | ||
124 | + } | ||
125 | + } | ||
126 | + return { | ||
127 | + register, | ||
128 | + loading, | ||
129 | + handleShow, | ||
130 | + info, | ||
131 | + activeUser, | ||
132 | + fixCost, | ||
133 | + ratio, | ||
134 | + spainRatio, | ||
135 | + price, | ||
136 | + customerCode, | ||
137 | + customerCodeOptions, | ||
138 | + handleOk, | ||
139 | + }; | ||
140 | + }, | ||
141 | + }); | ||
142 | +</script> | ||
143 | +<style scoped> | ||
144 | + .empty-tips { | ||
145 | + height: 100px; | ||
146 | + line-height: 100px; | ||
147 | + text-align: center; | ||
148 | + } | ||
149 | +</style> |
src/views/project/config/costEdit.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicDrawer | ||
3 | + v-cloakv-bind="$attrs" | ||
4 | + @register="register" | ||
5 | + title="编辑" | ||
6 | + width="35%" | ||
7 | + showFooter | ||
8 | + @ok="handleSubmit" | ||
9 | + ref="formRef" | ||
10 | + okText="保存" | ||
11 | + :destroyOnClose="true" | ||
12 | + :isDetail="true" | ||
13 | + :showDetailBack="false" | ||
14 | + :mask="false" | ||
15 | + class="z-20" | ||
16 | + > | ||
17 | + <a-space direction="vertical" style="width: 100%"> | ||
18 | + <a-input v-model:value="fixCost" addonBefore="固定成本 " /> | ||
19 | + <a-input v-model:value="ratio" addonBefore="提成比例 " /> | ||
20 | + <a-input v-model:value="spainRatio" addonBefore="西班牙提成比例 " /> | ||
21 | + <a-input v-model:value="price" addonBefore="生产提成单价" /> | ||
22 | + </a-space> | ||
23 | + </BasicDrawer> | ||
24 | +</template> | ||
25 | +<script lang="ts" setup> | ||
26 | + import { BasicDrawer, useDrawerInner } from '@/components/Drawer'; | ||
27 | + import { BasicForm, FormSchema, useForm } from '@/components/Form'; | ||
28 | + import { defineComponent, ref, computed, unref, toRaw, reactive, onMounted } from 'vue'; | ||
29 | + import { saveConfig } from '/@/api/sys/config'; | ||
30 | + | ||
31 | + // const emit = defineEmits(['success']); | ||
32 | + // const isUpdate = ref(true); | ||
33 | + const emit = defineEmits(['success']); | ||
34 | + | ||
35 | + const [register, { closeDrawer }] = useDrawerInner((data) => { | ||
36 | + listAll.value = data.data; | ||
37 | + console.log(listAll.value, '5656listAll.value'); | ||
38 | + relationValue.value = JSON.parse(listAll.value.relationValue); | ||
39 | + fixCost.value = relationValue.value[0].relationValue; | ||
40 | + ratio.value = relationValue.value[1].relationValue; | ||
41 | + spainRatio.value = relationValue.value[2].relationValue; | ||
42 | + price.value = relationValue.value[3].relationValue; | ||
43 | + }); | ||
44 | + //获取现有的列表 | ||
45 | + const listAll = ref(); | ||
46 | + const fixCost = ref(); | ||
47 | + const ratio = ref(); | ||
48 | + const spainRatio = ref(); | ||
49 | + const price = ref(); | ||
50 | + const relationValue = ref(); | ||
51 | + | ||
52 | + //完成编辑 | ||
53 | + async function handleSubmit() { | ||
54 | + relationValue.value[0].relationValue = fixCost.value; | ||
55 | + relationValue.value[1].relationValue = ratio.value; | ||
56 | + relationValue.value[2].relationValue = spainRatio.value; | ||
57 | + relationValue.value[3].relationValue = price.value; | ||
58 | + console.log(relationValue.value, '5656relationValue.value'); | ||
59 | + await saveConfig({ | ||
60 | + id: listAll.value.id, | ||
61 | + settingCode: 'customerCode', | ||
62 | + settingName: '客户提成成本配置', | ||
63 | + settingValue: listAll.value.settingValue, | ||
64 | + settingType: 3, | ||
65 | + relationCode: 'costSettingItem', | ||
66 | + relationName: '成本配置项集合', | ||
67 | + costSettingItemVOS: relationValue.value, | ||
68 | + }); | ||
69 | + emit('success'); | ||
70 | + closeDrawer(); | ||
71 | + } | ||
72 | +</script> |
src/views/project/config/data.tsx
@@ -70,22 +70,37 @@ export const COLUMNS = { | @@ -70,22 +70,37 @@ export const COLUMNS = { | ||
70 | title: '固定成本', | 70 | title: '固定成本', |
71 | dataIndex: 'relationValue', | 71 | dataIndex: 'relationValue', |
72 | width: 150, | 72 | width: 150, |
73 | - editComponent: 'InputNumber', | ||
74 | - editRow: true, | 73 | + customRender: (column) => { |
74 | + const value = JSON.parse(column.record.relationValue); | ||
75 | + return value[0].relationValue; | ||
76 | + }, | ||
75 | }, | 77 | }, |
76 | { | 78 | { |
77 | title: '提成比例', | 79 | title: '提成比例', |
78 | dataIndex: 'relationValue', | 80 | dataIndex: 'relationValue', |
79 | width: 150, | 81 | width: 150, |
80 | - editComponent: 'InputNumber', | ||
81 | - editRow: true, | 82 | + customRender: (column) => { |
83 | + const value = JSON.parse(column.record.relationValue); | ||
84 | + return value[1].relationValue; | ||
85 | + }, | ||
82 | }, | 86 | }, |
83 | { | 87 | { |
84 | - title: '生产科提成单价', | 88 | + title: '西班牙提成比例', |
85 | dataIndex: 'relationValue', | 89 | dataIndex: 'relationValue', |
86 | width: 150, | 90 | width: 150, |
87 | - editComponent: 'InputNumber', | ||
88 | - editRow: true, | 91 | + customRender: (column) => { |
92 | + const value = JSON.parse(column.record.relationValue); | ||
93 | + return value[2].relationValue; | ||
94 | + }, | ||
95 | + }, | ||
96 | + { | ||
97 | + title: '生产提成单价', | ||
98 | + dataIndex: 'relationValue', | ||
99 | + width: 150, | ||
100 | + customRender: (column) => { | ||
101 | + const value = JSON.parse(column.record.relationValue); | ||
102 | + return value[3].relationValue; | ||
103 | + }, | ||
89 | }, | 104 | }, |
90 | ], | 105 | ], |
91 | 7: [ | 106 | 7: [ |
src/views/project/config/index.vue
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <TablePanel :searchInfo="{ relationCode: 'orderHodTime' }" :column="5" /> | 20 | <TablePanel :searchInfo="{ relationCode: 'orderHodTime' }" :column="5" /> |
21 | </Tabs.TabPane> | 21 | </Tabs.TabPane> |
22 | <Tabs.TabPane key="6" tab="提成成本配置"> | 22 | <Tabs.TabPane key="6" tab="提成成本配置"> |
23 | - <TablePanel :searchInfo="{ relationCode: 'orderHodTime' }" :column="6" /> | 23 | + <TablePanel :searchInfo="{ relationCode: 'costSettingItem' }" :column="6" /> |
24 | </Tabs.TabPane> | 24 | </Tabs.TabPane> |
25 | <Tabs.TabPane key="7" tab="销售额配置"> | 25 | <Tabs.TabPane key="7" tab="销售额配置"> |
26 | <TablePanel :searchInfo="{ relationCode: 'salesAmount' }" :column="7" /> | 26 | <TablePanel :searchInfo="{ relationCode: 'salesAmount' }" :column="7" /> |
src/views/project/finance/pay/DeductShow.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicModal | ||
3 | + v-bind="$attrs" | ||
4 | + @register="register" | ||
5 | + title="扣款单" | ||
6 | + width="500px" | ||
7 | + :bodyStyle="{ height: '240px' }" | ||
8 | + @ok="handleOk" | ||
9 | + > | ||
10 | + </BasicModal> | ||
11 | +</template> | ||
12 | +<script lang="ts" setup> | ||
13 | + import { BasicModal, useModalInner } from '@/components/Modal'; | ||
14 | + import { computed, ref } from 'vue'; | ||
15 | + import type { UploadProps, UploadChangeParam } from 'ant-design-vue'; | ||
16 | + import { InboxOutlined } from '@ant-design/icons-vue'; | ||
17 | + import { message } from 'ant-design-vue'; | ||
18 | + import { updateInvoiceInfo } from '@/api/project/invoice'; | ||
19 | + | ||
20 | + const deductUrl = ref(); | ||
21 | + const id = ref(); | ||
22 | + | ||
23 | + const [register, { closeModal }] = useModalInner(async (data) => { | ||
24 | + deductUrl.value = data; | ||
25 | + }); | ||
26 | + | ||
27 | + async function handleOk() { | ||
28 | + closeModal(); | ||
29 | + } | ||
30 | +</script> |
src/views/project/finance/pay/index.vue
@@ -2,12 +2,18 @@ | @@ -2,12 +2,18 @@ | ||
2 | <div class="p-4"> | 2 | <div class="p-4"> |
3 | <BasicTable @register="registerTable"> | 3 | <BasicTable @register="registerTable"> |
4 | <template #toolbar> | 4 | <template #toolbar> |
5 | - <a-button type="primary" @click="handleCheckSum">应付款汇总</a-button> | 5 | + <a-button |
6 | + type="primary" | ||
7 | + @click="handleCheckSum" | ||
8 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
9 | + >应付款汇总</a-button | ||
10 | + > | ||
6 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | 11 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> |
7 | <TrackEdit @register="registerTrackEdit" @success="handleSuccess" /> | 12 | <TrackEdit @register="registerTrackEdit" @success="handleSuccess" /> |
8 | <CheckSum @register="registerCheckSum" /> | 13 | <CheckSum @register="registerCheckSum" /> |
9 | <InvoiceUpload @register="registerInvoiceUpload" @success="handleSuccess" /> | 14 | <InvoiceUpload @register="registerInvoiceUpload" @success="handleSuccess" /> |
10 | <CheckDetail @register="registerInvoiceDetail" /> | 15 | <CheckDetail @register="registerInvoiceDetail" /> |
16 | + <DeductShow @register="registerDeductShow" /> | ||
11 | </template> | 17 | </template> |
12 | <template #bodyCell="{ column, record }"> | 18 | <template #bodyCell="{ column, record }"> |
13 | <template v-if="column.key === 'action'"> | 19 | <template v-if="column.key === 'action'"> |
@@ -39,6 +45,14 @@ | @@ -39,6 +45,14 @@ | ||
39 | label: '删除', | 45 | label: '删除', |
40 | onClick: handleDelete.bind(null, record), | 46 | onClick: handleDelete.bind(null, record), |
41 | }, | 47 | }, |
48 | + { | ||
49 | + label: '生产科发票', | ||
50 | + onClick: handleInvoiceShow.bind(null, record), | ||
51 | + }, | ||
52 | + { | ||
53 | + label: '扣款单', | ||
54 | + onClick: handleDeductShow.bind(null, record), | ||
55 | + }, | ||
42 | ]" | 56 | ]" |
43 | /> | 57 | /> |
44 | </template> | 58 | </template> |
@@ -55,6 +69,7 @@ | @@ -55,6 +69,7 @@ | ||
55 | import InvoiceUpload from './InvoiceUpload.vue'; | 69 | import InvoiceUpload from './InvoiceUpload.vue'; |
56 | import CheckDetail from './CheckDetail.vue'; | 70 | import CheckDetail from './CheckDetail.vue'; |
57 | import CheckSum from './CheckSum.vue'; | 71 | import CheckSum from './CheckSum.vue'; |
72 | + import DeductShow from './DeductShow.vue'; | ||
58 | import { useDrawer } from '/@/components/Drawer'; | 73 | import { useDrawer } from '/@/components/Drawer'; |
59 | import { useModal } from '/@/components/Modal'; | 74 | import { useModal } from '/@/components/Modal'; |
60 | import { getCheck, checkDelete, checkCommit, checkDetail } from '@/api/project/invoice'; | 75 | import { getCheck, checkDelete, checkCommit, checkDetail } from '@/api/project/invoice'; |
@@ -64,6 +79,7 @@ | @@ -64,6 +79,7 @@ | ||
64 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); | 79 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); |
65 | const [registerTrackEdit, { openDrawer: openTrackEdit }] = useDrawer(); | 80 | const [registerTrackEdit, { openDrawer: openTrackEdit }] = useDrawer(); |
66 | const [registerInvoiceUpload, { openModal: openInvoiceUpload }] = useModal(); | 81 | const [registerInvoiceUpload, { openModal: openInvoiceUpload }] = useModal(); |
82 | + const [registerDeductShow, { openModal: openDeductShow }] = useModal(); | ||
67 | const [registerInvoiceDetail, { openDrawer: openCheckDetail }] = useDrawer(); | 83 | const [registerInvoiceDetail, { openDrawer: openCheckDetail }] = useDrawer(); |
68 | const checkedKeys = ref<Array<string | number>>([]); | 84 | const checkedKeys = ref<Array<string | number>>([]); |
69 | 85 | ||
@@ -209,7 +225,7 @@ | @@ -209,7 +225,7 @@ | ||
209 | // console.log(selectedCustomCodes.value, 56561); | 225 | // console.log(selectedCustomCodes.value, 56561); |
210 | // console.log(checkedKeys.value, 56562); | 226 | // console.log(checkedKeys.value, 56562); |
211 | // } | 227 | // } |
212 | - | 228 | + //选择算法:创建二维数组,使客户编码和生产科相同 |
213 | type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] | 229 | type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] |
214 | type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] | 230 | type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] |
215 | 231 | ||
@@ -376,6 +392,14 @@ | @@ -376,6 +392,14 @@ | ||
376 | reload(); | 392 | reload(); |
377 | }, 50); | 393 | }, 50); |
378 | } | 394 | } |
395 | + function handleInvoiceShow(record) { | ||
396 | + window.open(record.invoiceUrl); | ||
397 | + } | ||
398 | + function handleDeductShow(record) { | ||
399 | + openDeductShow(true, { | ||
400 | + data: record.deductUrl, | ||
401 | + }); | ||
402 | + } | ||
379 | function handleDetail(record) { | 403 | function handleDetail(record) { |
380 | openCheckDetail(true, { | 404 | openCheckDetail(true, { |
381 | data: record, | 405 | data: record, |
src/views/project/finance/receive/index.vue
@@ -2,7 +2,12 @@ | @@ -2,7 +2,12 @@ | ||
2 | <div class="p-4"> | 2 | <div class="p-4"> |
3 | <BasicTable @register="registerTable"> | 3 | <BasicTable @register="registerTable"> |
4 | <template #toolbar> | 4 | <template #toolbar> |
5 | - <a-button type="primary" @click="handleInvoiceAnalysis">收款单分析</a-button> | 5 | + <a-button |
6 | + type="primary" | ||
7 | + @click="handleInvoiceAnalysis" | ||
8 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
9 | + >收款单分析</a-button | ||
10 | + > | ||
6 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | 11 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> |
7 | <InvoiceAnalysis @register="registerInvoiceAnalysis" /> | 12 | <InvoiceAnalysis @register="registerInvoiceAnalysis" /> |
8 | <TrackEdit @register="registerTrackEdit" @success="handleSuccess" /> | 13 | <TrackEdit @register="registerTrackEdit" @success="handleSuccess" /> |
src/views/project/order/CheckDetail.vue
1 | <template> | 1 | <template> |
2 | - <BasicDrawer | ||
3 | - @register="register" | ||
4 | - v-bind="$attrs" | ||
5 | - showFooter | ||
6 | - title="字段编辑权限申请" | ||
7 | - width="60%" | ||
8 | - :destroyOnClose="true" | ||
9 | - :isDetail="true" | ||
10 | - @ok="handleSubmit" | ||
11 | - :showDetailBack="false" | ||
12 | - okText="申请" | ||
13 | - ><input /> | ||
14 | - <div> | ||
15 | - <template v-if="role === ROLE.ADMIN || role === ROLE.TRACKER"> | ||
16 | - <h3>基本信息</h3> | ||
17 | - <BasicForm @register="registerForm" /> | ||
18 | - </template> | ||
19 | - <template v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS"> | ||
20 | - <h3>利润分析</h3> | ||
21 | - <BasicForm @register="registerProfitForm" /> | ||
22 | - </template> | ||
23 | - <template v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS"> | ||
24 | - <h3>项目报告书</h3> | ||
25 | - <BasicForm @register="registerReportForm" /> | ||
26 | - </template> | ||
27 | - <template v-if="role === ROLE.ADMIN || role === ROLE.TRACKER"> | ||
28 | - <h3>跟单信息</h3> | ||
29 | - <BasicForm @register="registerTrackForm" /> | ||
30 | - </template> | ||
31 | - <template v-if="role === ROLE.ADMIN || role === ROLE.INSPECT"> | ||
32 | - <h3>质量信息</h3> | ||
33 | - <BasicForm @register="registryInspectForm" /> | ||
34 | - </template> | ||
35 | - </div> | ||
36 | - <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | 2 | + <div class="container"> |
3 | + <BasicDrawer | ||
4 | + @register="register" | ||
5 | + v-bind="$attrs" | ||
6 | + showFooter | ||
7 | + title="字段编辑权限申请" | ||
8 | + width="60%" | ||
9 | + :destroyOnClose="true" | ||
10 | + :isDetail="true" | ||
11 | + @ok="handleSubmit" | ||
12 | + :showDetailBack="false" | ||
13 | + okText="申请" | ||
14 | + ><input /> | ||
15 | + <div> | ||
16 | + <template v-if="role === ROLE.ADMIN || role === ROLE.TRACKER"> | ||
17 | + <h3>基本信息</h3> | ||
18 | + <BasicForm @register="registerForm" /> | ||
19 | + </template> | ||
20 | + <template v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS"> | ||
21 | + <h3>利润分析</h3> | ||
22 | + <BasicForm @register="registerProfitForm" /> | ||
23 | + </template> | ||
24 | + <template v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS"> | ||
25 | + <h3>项目报告书</h3> | ||
26 | + <BasicForm @register="registerReportForm" /> | ||
27 | + </template> | ||
28 | + <template v-if="role === ROLE.ADMIN || role === ROLE.TRACKER"> | ||
29 | + <h3>跟单信息</h3> | ||
30 | + <BasicForm @register="registerTrackForm" /> | ||
31 | + </template> | ||
32 | + <template v-if="role === ROLE.ADMIN || role === ROLE.INSPECT"> | ||
33 | + <h3>质量信息</h3> | ||
34 | + <BasicForm @register="registryInspectForm" /> | ||
35 | + </template> | ||
36 | + </div> | ||
37 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | ||
37 | 38 | ||
38 | - <!-- <template #appendFooter> | 39 | + <!-- <template #appendFooter> |
39 | <a-button type="primary" @click="onGoFormDetail"> 返回编辑</a-button> | 40 | <a-button type="primary" @click="onGoFormDetail"> 返回编辑</a-button> |
40 | </template> --> | 41 | </template> --> |
41 | - </BasicDrawer> | 42 | + </BasicDrawer> |
43 | + <ApproveReason @register="approveReasonModalRegister" @success="handleCloseModal" /> | ||
44 | + </div> | ||
42 | </template> | 45 | </template> |
43 | <script lang="ts"> | 46 | <script lang="ts"> |
44 | import { computed, defineComponent, reactive, ref } from 'vue'; | 47 | import { computed, defineComponent, reactive, ref } from 'vue'; |
45 | import { BasicForm, useForm } from '/@/components/Form/index'; | 48 | import { BasicForm, useForm } from '/@/components/Form/index'; |
46 | import { orderAuth } from '/@/api/project/order'; | 49 | import { orderAuth } from '/@/api/project/order'; |
47 | import { ROLE } from './type.d'; | 50 | import { ROLE } from './type.d'; |
51 | + import { useModal } from '/@/components/Modal'; | ||
52 | + import ApproveReason from './FormDetail/ApproveReason.vue'; | ||
48 | 53 | ||
49 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | 54 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; |
50 | import { | 55 | import { |
@@ -79,7 +84,7 @@ | @@ -79,7 +84,7 @@ | ||
79 | ); | 84 | ); |
80 | 85 | ||
81 | export default defineComponent({ | 86 | export default defineComponent({ |
82 | - components: { BasicDrawer, BasicForm }, | 87 | + components: { BasicDrawer, BasicForm, ApproveReason }, |
83 | props: { | 88 | props: { |
84 | onGoFormDetail: { | 89 | onGoFormDetail: { |
85 | type: Function, | 90 | type: Function, |
@@ -92,6 +97,7 @@ | @@ -92,6 +97,7 @@ | ||
92 | const reportSchemas = getSchema(FIELDS_REPORT_INFO); | 97 | const reportSchemas = getSchema(FIELDS_REPORT_INFO); |
93 | const inspecSchemas = getSchema(FIELDS_INSPECTION_INFO); | 98 | const inspecSchemas = getSchema(FIELDS_INSPECTION_INFO); |
94 | const trackSchemas = getSchema(FIELDS_TRACK_STAGE_INFO); | 99 | const trackSchemas = getSchema(FIELDS_TRACK_STAGE_INFO); |
100 | + const [approveReasonModalRegister, { openModal: openReasonModal }] = useModal(); | ||
95 | const [registerForm, { getFieldsValue }] = useForm({ | 101 | const [registerForm, { getFieldsValue }] = useForm({ |
96 | labelWidth: 120, | 102 | labelWidth: 120, |
97 | schemas, | 103 | schemas, |
@@ -137,6 +143,9 @@ | @@ -137,6 +143,9 @@ | ||
137 | Object.assign(lockFields, data.lockFields); | 143 | Object.assign(lockFields, data.lockFields); |
138 | id.value = data.id; | 144 | id.value = data.id; |
139 | }); | 145 | }); |
146 | + function handleCloseModal() { | ||
147 | + closeDrawer(); | ||
148 | + } | ||
140 | 149 | ||
141 | const role = computed(() => { | 150 | const role = computed(() => { |
142 | return userStore.getUserInfo?.roleSmallVO?.code; | 151 | return userStore.getUserInfo?.roleSmallVO?.code; |
@@ -148,7 +157,6 @@ | @@ -148,7 +157,6 @@ | ||
148 | const reportFieldValues = getReportFieldsValue(); | 157 | const reportFieldValues = getReportFieldsValue(); |
149 | const inspectFieldValues = getInspectFieldsValue(); | 158 | const inspectFieldValues = getInspectFieldsValue(); |
150 | const trackFieldValues = getTrackFieldsValue(); | 159 | const trackFieldValues = getTrackFieldsValue(); |
151 | - | ||
152 | if (baseFieldValues) { | 160 | if (baseFieldValues) { |
153 | FIELDS_BASE_INFO.map( | 161 | FIELDS_BASE_INFO.map( |
154 | ({ field }) => | 162 | ({ field }) => |
@@ -156,14 +164,12 @@ | @@ -156,14 +164,12 @@ | ||
156 | baseFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), | 164 | baseFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), |
157 | ); | 165 | ); |
158 | } | 166 | } |
159 | - | ||
160 | if (reportFieldValues) | 167 | if (reportFieldValues) |
161 | FIELDS_REPORT_INFO.map( | 168 | FIELDS_REPORT_INFO.map( |
162 | ({ field }) => | 169 | ({ field }) => |
163 | (reportFieldValues[field] = | 170 | (reportFieldValues[field] = |
164 | reportFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), | 171 | reportFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), |
165 | ); | 172 | ); |
166 | - | ||
167 | if (profitFieldValues) | 173 | if (profitFieldValues) |
168 | FIELDS_PROFIT_INFO.map( | 174 | FIELDS_PROFIT_INFO.map( |
169 | ({ field }) => | 175 | ({ field }) => |
@@ -176,21 +182,18 @@ | @@ -176,21 +182,18 @@ | ||
176 | (trackFieldValues[field] = | 182 | (trackFieldValues[field] = |
177 | trackFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), | 183 | trackFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), |
178 | ); | 184 | ); |
179 | - | ||
180 | if (inspectFieldValues) | 185 | if (inspectFieldValues) |
181 | FIELDS_INSPECTION_INFO.map( | 186 | FIELDS_INSPECTION_INFO.map( |
182 | ({ field }) => | 187 | ({ field }) => |
183 | (inspectFieldValues[field] = | 188 | (inspectFieldValues[field] = |
184 | inspectFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), | 189 | inspectFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), |
185 | ); | 190 | ); |
186 | - | ||
187 | // !isEmpty(baseFieldValues) && | 191 | // !isEmpty(baseFieldValues) && |
188 | // Object.keys(baseFieldValues.baseFields)?.map((key) => { | 192 | // Object.keys(baseFieldValues.baseFields)?.map((key) => { |
189 | // baseFieldValues.baseFields[key] = baseFieldValues.baseFields[key] | 193 | // baseFieldValues.baseFields[key] = baseFieldValues.baseFields[key] |
190 | // ? 'UN_LOCKED' | 194 | // ? 'UN_LOCKED' |
191 | // : 'LOCKED'; | 195 | // : 'LOCKED'; |
192 | // }); | 196 | // }); |
193 | - | ||
194 | // !isEmpty(profitFieldValues) && | 197 | // !isEmpty(profitFieldValues) && |
195 | // Object.keys(profitFieldValues.profitAnalysisFields).map((key) => { | 198 | // Object.keys(profitFieldValues.profitAnalysisFields).map((key) => { |
196 | // profitFieldValues.profitAnalysisFields[key] = profitFieldValues.profitAnalysisFields[ | 199 | // profitFieldValues.profitAnalysisFields[key] = profitFieldValues.profitAnalysisFields[ |
@@ -199,14 +202,12 @@ | @@ -199,14 +202,12 @@ | ||
199 | // ? 'UN_LOCKED' | 202 | // ? 'UN_LOCKED' |
200 | // : 'LOCKED'; | 203 | // : 'LOCKED'; |
201 | // }); | 204 | // }); |
202 | - | ||
203 | // !isEmpty(reportFieldValues) && | 205 | // !isEmpty(reportFieldValues) && |
204 | // Object.keys(reportFieldValues.reportFields).map((key) => { | 206 | // Object.keys(reportFieldValues.reportFields).map((key) => { |
205 | // reportFieldValues.reportFields[key] = reportFieldValues.reportFields[key] | 207 | // reportFieldValues.reportFields[key] = reportFieldValues.reportFields[key] |
206 | // ? 'UN_LOCKED' | 208 | // ? 'UN_LOCKED' |
207 | // : 'LOCKED'; | 209 | // : 'LOCKED'; |
208 | // }); | 210 | // }); |
209 | - | ||
210 | const values = Object.assign( | 211 | const values = Object.assign( |
211 | { orderId: id.value }, | 212 | { orderId: id.value }, |
212 | { baseFields: baseFieldValues }, | 213 | { baseFields: baseFieldValues }, |
@@ -215,9 +216,25 @@ | @@ -215,9 +216,25 @@ | ||
215 | { trackStageFields: trackFieldValues }, | 216 | { trackStageFields: trackFieldValues }, |
216 | { inspectionStageFields: inspectFieldValues }, | 217 | { inspectionStageFields: inspectFieldValues }, |
217 | ); | 218 | ); |
218 | - await orderAuth(values); | ||
219 | - closeDrawer(); | 219 | + |
220 | + if ( | ||
221 | + values.baseFields.projectNo == 'UN_LOCKED' || | ||
222 | + values.baseFields.productionDepartment == 'UN_LOCKED' || | ||
223 | + values.baseFields.innerNo == 'UN_LOCKED' || | ||
224 | + values.baseFields.customerCode == 'UN_LOCKED' || | ||
225 | + values.baseFields.customerPo == 'UN_LOCKED' || | ||
226 | + values.baseFields.customerStyle == 'UN_LOCKED' | ||
227 | + ) { | ||
228 | + openReasonModal(true, { | ||
229 | + data: values, | ||
230 | + }); | ||
231 | + } else { | ||
232 | + values.applyRemark = ''; | ||
233 | + await orderAuth(values); | ||
234 | + closeDrawer(); | ||
235 | + } | ||
220 | }; | 236 | }; |
237 | + | ||
221 | return { | 238 | return { |
222 | register, | 239 | register, |
223 | schemas, | 240 | schemas, |
@@ -227,9 +244,17 @@ | @@ -227,9 +244,17 @@ | ||
227 | registryInspectForm, | 244 | registryInspectForm, |
228 | registerTrackForm, | 245 | registerTrackForm, |
229 | handleSubmit, | 246 | handleSubmit, |
247 | + handleCloseModal, | ||
248 | + approveReasonModalRegister, | ||
230 | ROLE, | 249 | ROLE, |
231 | role, | 250 | role, |
232 | }; | 251 | }; |
233 | }, | 252 | }, |
234 | }); | 253 | }); |
235 | </script> | 254 | </script> |
255 | +<style> | ||
256 | + .container { | ||
257 | + position: fixed; /* 或 absolute, fixed */ | ||
258 | + z-index: 10; | ||
259 | + } | ||
260 | +</style> |
src/views/project/order/ExportModal.vue
@@ -84,6 +84,15 @@ | @@ -84,6 +84,15 @@ | ||
84 | { label: '质检信息', value: 'inspectionStageFields' }, | 84 | { label: '质检信息', value: 'inspectionStageFields' }, |
85 | ]; | 85 | ]; |
86 | } | 86 | } |
87 | + if (props.role === ROLE.FINANCE) { | ||
88 | + return [ | ||
89 | + { label: '基本信息', value: 'baseFields' }, | ||
90 | + { label: '项目报告', value: 'reportFields' }, | ||
91 | + { label: '利润分析', value: 'profitAnalysisFields' }, | ||
92 | + { label: '跟单信息', value: 'trackStageFields' }, | ||
93 | + { label: '质检信息', value: 'inspectionStageFields' }, | ||
94 | + ]; | ||
95 | + } | ||
87 | if (props.role === ROLE.TRACKER) { | 96 | if (props.role === ROLE.TRACKER) { |
88 | return [ | 97 | return [ |
89 | { label: '基本信息', value: 'baseFields' }, | 98 | { label: '基本信息', value: 'baseFields' }, |
src/views/project/order/FormDetail/ApproveReason.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicModal | ||
3 | + v-bind="$attrs" | ||
4 | + destroyOnClose | ||
5 | + @register="register" | ||
6 | + title="申请原因" | ||
7 | + :helpMessage="['提示1', '提示2']" | ||
8 | + @open-change="handleShow" | ||
9 | + :bodyStyle="{ height: '200px' }" | ||
10 | + @ok="handleOk" | ||
11 | + z-index="9999" | ||
12 | + > | ||
13 | + <a-textarea v-model:value="input" :rows="7" /> | ||
14 | + </BasicModal> | ||
15 | +</template> | ||
16 | +<script lang="ts" setup> | ||
17 | + import { ref, watch } from 'vue'; | ||
18 | + import { BasicModal, useModalInner } from '@/components/Modal'; | ||
19 | + import { orderAuth } from '/@/api/project/order'; | ||
20 | + | ||
21 | + const emit = defineEmits(['success']); | ||
22 | + const input = ref(''); | ||
23 | + const res = ref(); | ||
24 | + const [register, { setModalProps, redoModalHeight, closeModal }] = useModalInner(async (data) => { | ||
25 | + console.log(data, '5656approvedata'); | ||
26 | + res.value = data; | ||
27 | + }); | ||
28 | + async function handleOk() { | ||
29 | + res.value.data.applyRemark = input.value; | ||
30 | + await orderAuth(res.value.data); | ||
31 | + emit('success'); | ||
32 | + setTimeout(() => { | ||
33 | + closeModal(); | ||
34 | + }, 50); | ||
35 | + } | ||
36 | + function handleShow() { | ||
37 | + closeModal(); | ||
38 | + } | ||
39 | +</script> |
src/views/project/order/FormDetail/BaseFormPanel.vue
@@ -202,34 +202,34 @@ | @@ -202,34 +202,34 @@ | ||
202 | label: '产品意见', | 202 | label: '产品意见', |
203 | }; | 203 | }; |
204 | } | 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 | - } | 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']; | 233 | // const businessNotDisabledFields = ['customerCode', 'projectNo', 'innerNo']; |
234 | // const trackerNotDisabledFields = [ | 234 | // const trackerNotDisabledFields = [ |
235 | // 'customerPo', | 235 | // 'customerPo', |
@@ -254,7 +254,9 @@ | @@ -254,7 +254,9 @@ | ||
254 | field: `${item.field}`, | 254 | field: `${item.field}`, |
255 | componentProps: { | 255 | componentProps: { |
256 | ...(item.component === 'Select' && { showSearch: true }), | 256 | ...(item.component === 'Select' && { showSearch: true }), |
257 | - ...(item.component === 'Select' && { options: options[item.field] }), | 257 | + ...(item.component === 'Select' && { |
258 | + options: options[item.field] || item?.componentProps?.options, | ||
259 | + }), | ||
258 | // disabled: | 260 | // disabled: |
259 | // role.value === ROLE.BUSINESS | 261 | // role.value === ROLE.BUSINESS |
260 | // ? !isFieldNotDisabledForBusiness | 262 | // ? !isFieldNotDisabledForBusiness |
src/views/project/order/ProductProfit.vue
@@ -121,6 +121,7 @@ | @@ -121,6 +121,7 @@ | ||
121 | import { payDate, checkCreate } from '@/api/project/invoice'; | 121 | import { payDate, checkCreate } from '@/api/project/invoice'; |
122 | import type { Dayjs } from 'dayjs'; | 122 | import type { Dayjs } from 'dayjs'; |
123 | import { calculateInnerProfitRatio, exportInnerProfitRatio } from '@/api/project/order'; | 123 | import { calculateInnerProfitRatio, exportInnerProfitRatio } from '@/api/project/order'; |
124 | + import axios from 'axios'; | ||
124 | 125 | ||
125 | const Input1 = ref(''); | 126 | const Input1 = ref(''); |
126 | const Input2 = ref(); | 127 | const Input2 = ref(); |
@@ -153,6 +154,50 @@ | @@ -153,6 +154,50 @@ | ||
153 | filteredItems.value = data.filteredItems; | 154 | filteredItems.value = data.filteredItems; |
154 | }); | 155 | }); |
155 | async function handleOk() { | 156 | async function handleOk() { |
157 | + axios | ||
158 | + .post( | ||
159 | + '/basic-api/order/erp/calculate_profit/inner_profit_ratio_export', | ||
160 | + { | ||
161 | + customerCode: customerCode.value, | ||
162 | + projectNo: projectNo.value, | ||
163 | + projectStartTime: projectStartTime.value, | ||
164 | + projectEndTime: projectEndTime.value, | ||
165 | + productionDepartmentPredictPrice: productionDepartmentPredictPrice.value, | ||
166 | + productionActualPrice: productionActualPrice.value, | ||
167 | + }, | ||
168 | + { | ||
169 | + responseType: 'blob', // 设置响应类型为 'blob' | ||
170 | + }, | ||
171 | + ) | ||
172 | + .then((response) => { | ||
173 | + // 创建一个 Blob 对象来保存二进制数据 | ||
174 | + const blob = new Blob([response.data], { type: 'application/octet-stream' }); | ||
175 | + const getFormattedDate = (): string => { | ||
176 | + const date = new Date(); | ||
177 | + | ||
178 | + const year = date.getFullYear(); | ||
179 | + const month = String(date.getMonth() + 1).padStart(2, '0'); | ||
180 | + const day = String(date.getDate()).padStart(2, '0'); | ||
181 | + | ||
182 | + const hours = String(date.getHours()).padStart(2, '0'); | ||
183 | + const minutes = String(date.getMinutes()).padStart(2, '0'); | ||
184 | + const seconds = String(date.getSeconds()).padStart(2, '0'); | ||
185 | + | ||
186 | + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | ||
187 | + }; | ||
188 | + const date = getFormattedDate(); | ||
189 | + // 创建一个链接元素用于下载 | ||
190 | + const link = document.createElement('a'); | ||
191 | + link.href = window.URL.createObjectURL(blob); | ||
192 | + link.download = `内部生产净利润分析${date}.pdf`; // 你可以为文件命名 | ||
193 | + document.body.appendChild(link); | ||
194 | + link.click(); // 自动点击链接,触发下载 | ||
195 | + console.log(link, 5656); | ||
196 | + document.body.removeChild(link); // 下载完成后移除链接 | ||
197 | + }) | ||
198 | + .catch((error) => { | ||
199 | + console.error(error); | ||
200 | + }); | ||
156 | closeModal(); | 201 | closeModal(); |
157 | } | 202 | } |
158 | function handleShow(visible: boolean) { | 203 | function handleShow(visible: boolean) { |
src/views/project/order/ProductText.vue
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | v-bind="$attrs" | 3 | v-bind="$attrs" |
4 | destroyOnClose | 4 | destroyOnClose |
5 | @register="register" | 5 | @register="register" |
6 | - title="生产指标书" | 6 | + title="生产指示书" |
7 | width="500px" | 7 | width="500px" |
8 | :height="80" | 8 | :height="80" |
9 | wrapClassName="h-[340px]" | 9 | wrapClassName="h-[340px]" |
@@ -14,7 +14,7 @@ | @@ -14,7 +14,7 @@ | ||
14 | v-bind="$attrs" | 14 | v-bind="$attrs" |
15 | destroyOnClose | 15 | destroyOnClose |
16 | @register="register" | 16 | @register="register" |
17 | - title="生产指标书" | 17 | + title="生产指示书" |
18 | width="500px" | 18 | width="500px" |
19 | @visible-change="handleShow" | 19 | @visible-change="handleShow" |
20 | :footer="null" | 20 | :footer="null" |
@@ -27,7 +27,7 @@ | @@ -27,7 +27,7 @@ | ||
27 | <div class="showPdf" v-if="isShow2 == true" style="margin-top: 35px; text-align: center"> | 27 | <div class="showPdf" v-if="isShow2 == true" style="margin-top: 35px; text-align: center"> |
28 | <!-- <img src="/pdf.png" /> --> | 28 | <!-- <img src="/pdf.png" /> --> |
29 | <FilePptOutlined :style="{ fontSize: '20px' }" class="FilePptOutlined" /> | 29 | <FilePptOutlined :style="{ fontSize: '20px' }" class="FilePptOutlined" /> |
30 | - <div style="margin-top: 1px; margin-left: 10px">生产指标书</div> | 30 | + <div style="margin-top: 1px; margin-left: 10px">生产指示书</div> |
31 | <EyeOutlined :style="{ fontSize: '20px' }" class="EyeOutlined" @click="handlePdf" /> | 31 | <EyeOutlined :style="{ fontSize: '20px' }" class="EyeOutlined" @click="handlePdf" /> |
32 | </div> | 32 | </div> |
33 | <div class="bottom"> | 33 | <div class="bottom"> |
@@ -83,7 +83,7 @@ | @@ -83,7 +83,7 @@ | ||
83 | // 运营总监-基本信息,跟单,质检 | 83 | // 运营总监-基本信息,跟单,质检 |
84 | return [ | 84 | return [ |
85 | { label: '青岛翱特逸格饰品有限公司', value: '青岛翱特逸格饰品有限公司' }, | 85 | { label: '青岛翱特逸格饰品有限公司', value: '青岛翱特逸格饰品有限公司' }, |
86 | - { label: ' 青岛吉庆天成饰品有限公司', value: '青岛吉庆天成饰品有限公司' }, | 86 | + { label: '青岛吉庆天成饰品有限公司', value: '青岛吉庆天成饰品有限公司' }, |
87 | ]; | 87 | ]; |
88 | }); | 88 | }); |
89 | const { createMessage } = useMessage(); | 89 | const { createMessage } = useMessage(); |
@@ -173,17 +173,18 @@ | @@ -173,17 +173,18 @@ | ||
173 | } | 173 | } |
174 | //查看pdf | 174 | //查看pdf |
175 | function handlePdf() { | 175 | function handlePdf() { |
176 | - window.open(resText.value.produceFile); | 176 | + window.open(resText.value.productionUrl); |
177 | } | 177 | } |
178 | //发送按钮 | 178 | //发送按钮 |
179 | async function handleExport() { | 179 | async function handleExport() { |
180 | const res = await exportProductText({ | 180 | const res = await exportProductText({ |
181 | productionUrl: resText.value.productionUrl, | 181 | productionUrl: resText.value.productionUrl, |
182 | productionDepartment: resText.value.productionDepartment, | 182 | productionDepartment: resText.value.productionDepartment, |
183 | + personList: resText.value.personList, | ||
183 | isSend: true, | 184 | isSend: true, |
184 | }); | 185 | }); |
185 | console.log(); | 186 | console.log(); |
186 | - success('操作成功,' + res); | 187 | + success('操作成功,已发送给生产科、业务员、跟单员'); |
187 | closeModal(); | 188 | closeModal(); |
188 | } | 189 | } |
189 | return { | 190 | return { |
src/views/project/order/ServiceProfit.vue
@@ -49,18 +49,20 @@ | @@ -49,18 +49,20 @@ | ||
49 | <tr> | 49 | <tr> |
50 | <td style="border: 1px solid black"></td> | 50 | <td style="border: 1px solid black"></td> |
51 | <td style="border: 1px solid black">项目开始时间</td> | 51 | <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> | 52 | + <td style="border: 1px solid black"> |
53 | + <input type="date" v-model="projectStartTime" style="width: 100%" /> | ||
54 | + </td> | ||
55 | + <input type="date" v-model="projectEndTime" style="width: 100%" /> | ||
56 | </tr> | 56 | </tr> |
57 | <tr> | 57 | <tr> |
58 | <td style="border: 1px solid black"></td> | 58 | <td style="border: 1px solid black"></td> |
59 | <td style="border: 1px solid black">生产进行时间</td> | 59 | <td style="border: 1px solid black">生产进行时间</td> |
60 | - <td style="border: 1px solid black" | ||
61 | - ><a-date-picker v-model:value="produceStartTime" | 60 | + <td style="border: 1px solid black"> |
61 | + <input type="date" v-model="produceStartTime" style="width: 100%" /> | ||
62 | + </td> | ||
63 | + <td style="border: 1px solid black"> | ||
64 | + <input type="date" v-model="produceEndTime" style="width: 100%" | ||
62 | /></td> | 65 | /></td> |
63 | - <td style="border: 1px solid black"><a-date-picker v-model:value="produceEndTime" /></td> | ||
64 | </tr> | 66 | </tr> |
65 | <tr> | 67 | <tr> |
66 | <td style="border: 1px solid black">客户编码</td> | 68 | <td style="border: 1px solid black">客户编码</td> |
@@ -70,17 +72,17 @@ | @@ -70,17 +72,17 @@ | ||
70 | </tr> | 72 | </tr> |
71 | <tr> | 73 | <tr> |
72 | <td style="border: 1px solid black" colspan="2">客户总金额合计</td> | 74 | <td style="border: 1px solid black" colspan="2">客户总金额合计</td> |
73 | - <td style="border: 1px solid black"></td> | 75 | + <td style="border: 1px solid black">{{ customerTotalPrice }}</td> |
74 | <td style="border: 1px solid black"></td> | 76 | <td style="border: 1px solid black"></td> |
75 | </tr> | 77 | </tr> |
76 | <tr> | 78 | <tr> |
77 | <td style="border: 1px solid black" colspan="2">生产科总价合计</td> | 79 | <td style="border: 1px solid black" colspan="2">生产科总价合计</td> |
78 | - <td style="border: 1px solid black"></td> | 80 | + <td style="border: 1px solid black">{{ productionDepartmentTotalPrice }}</td> |
79 | <td style="border: 1px solid black"></td> | 81 | <td style="border: 1px solid black"></td> |
80 | </tr> | 82 | </tr> |
81 | <tr> | 83 | <tr> |
82 | <td style="border: 1px solid black" colspan="2">包装费用合计</td> | 84 | <td style="border: 1px solid black" colspan="2">包装费用合计</td> |
83 | - <td style="border: 1px solid black"></td> | 85 | + <td style="border: 1px solid black">{{ packetTotalPrice }}</td> |
84 | <td style="border: 1px solid black"></td> | 86 | <td style="border: 1px solid black"></td> |
85 | </tr> | 87 | </tr> |
86 | <tr> | 88 | <tr> |
@@ -99,37 +101,37 @@ | @@ -99,37 +101,37 @@ | ||
99 | </tr> | 101 | </tr> |
100 | <tr> | 102 | <tr> |
101 | <td style="border: 1px solid black" colspan="2">固定成本</td> | 103 | <td style="border: 1px solid black" colspan="2">固定成本</td> |
102 | - <td style="border: 1px solid black"></td> | 104 | + <td style="border: 1px solid black">{{ fixCost }}</td> |
103 | <td style="border: 1px solid black"></td> | 105 | <td style="border: 1px solid black"></td> |
104 | </tr> | 106 | </tr> |
105 | <tr> | 107 | <tr> |
106 | <td style="border: 1px solid black" colspan="2">西班牙提成</td> | 108 | <td style="border: 1px solid black" colspan="2">西班牙提成</td> |
107 | - <td style="border: 1px solid black"></td> | 109 | + <td style="border: 1px solid black">{{ spainRatioProfitPrice }}</td> |
108 | <td style="border: 1px solid black"></td> | 110 | <td style="border: 1px solid black"></td> |
109 | </tr> | 111 | </tr> |
110 | <tr> | 112 | <tr> |
111 | <td style="border: 1px solid black" colspan="2">中国团队提成</td> | 113 | <td style="border: 1px solid black" colspan="2">中国团队提成</td> |
112 | - <td style="border: 1px solid black"></td> | 114 | + <td style="border: 1px solid black">{{ chinaRatioProfitPrice }}</td> |
113 | <td style="border: 1px solid black"></td> | 115 | <td style="border: 1px solid black"></td> |
114 | </tr> | 116 | </tr> |
115 | <tr> | 117 | <tr> |
116 | <td style="border: 1px solid black" colspan="2">支出合计</td> | 118 | <td style="border: 1px solid black" colspan="2">支出合计</td> |
117 | - <td style="border: 1px solid black"></td> | 119 | + <td style="border: 1px solid black">{{ outTotalPrice }}</td> |
118 | <td style="border: 1px solid black"></td> | 120 | <td style="border: 1px solid black"></td> |
119 | </tr> | 121 | </tr> |
120 | <tr> | 122 | <tr> |
121 | <td style="border: 1px solid black" colspan="2">毛利润</td> | 123 | <td style="border: 1px solid black" colspan="2">毛利润</td> |
122 | - <td style="border: 1px solid black"></td> | 124 | + <td style="border: 1px solid black">{{ grossProfit }}</td> |
123 | <td style="border: 1px solid black"></td> | 125 | <td style="border: 1px solid black"></td> |
124 | </tr> | 126 | </tr> |
125 | <tr> | 127 | <tr> |
126 | <td style="border: 1px solid black" colspan="2">研发贸易净利润</td> | 128 | <td style="border: 1px solid black" colspan="2">研发贸易净利润</td> |
127 | - <td style="border: 1px solid black"></td> | 129 | + <td style="border: 1px solid black">{{ developProfit }}</td> |
128 | <td style="border: 1px solid black"></td> | 130 | <td style="border: 1px solid black"></td> |
129 | </tr> | 131 | </tr> |
130 | <tr> | 132 | <tr> |
131 | <td style="border: 1px solid black" colspan="2">包装费用合计金额</td> | 133 | <td style="border: 1px solid black" colspan="2">包装费用合计金额</td> |
132 | - <td style="border: 1px solid black"></td> | 134 | + <td style="border: 1px solid black">{{ packetTotalPrice }}</td> |
133 | <td style="border: 1px solid black"></td> | 135 | <td style="border: 1px solid black"></td> |
134 | </tr> | 136 | </tr> |
135 | <tr> | 137 | <tr> |
@@ -141,32 +143,32 @@ | @@ -141,32 +143,32 @@ | ||
141 | </tr> | 143 | </tr> |
142 | <tr> | 144 | <tr> |
143 | <td style="border: 1px solid black" colspan="2">订单总数量</td> | 145 | <td style="border: 1px solid black" colspan="2">订单总数量</td> |
144 | - <td style="border: 1px solid black"></td> | 146 | + <td style="border: 1px solid black">{{ orderCount }}</td> |
145 | <td style="border: 1px solid black"></td> | 147 | <td style="border: 1px solid black"></td> |
146 | </tr> | 148 | </tr> |
147 | <tr> | 149 | <tr> |
148 | <td style="border: 1px solid black" colspan="2">实际跟单单价=实际跟单费用/件数</td> | 150 | <td style="border: 1px solid black" colspan="2">实际跟单单价=实际跟单费用/件数</td> |
149 | - <td style="border: 1px solid black"></td> | 151 | + <td style="border: 1px solid black">{{ actualRmbPrice }}</td> |
150 | <td style="border: 1px solid black"></td> | 152 | <td style="border: 1px solid black"></td> |
151 | </tr> | 153 | </tr> |
152 | <tr> | 154 | <tr> |
153 | <td style="border: 1px solid black" colspan="2">实际跟单单价折算美金</td> | 155 | <td style="border: 1px solid black" colspan="2">实际跟单单价折算美金</td> |
154 | - <td style="border: 1px solid black"></td> | 156 | + <td style="border: 1px solid black">{{ actualPrice }}</td> |
155 | <td style="border: 1px solid black"></td> | 157 | <td style="border: 1px solid black"></td> |
156 | </tr> | 158 | </tr> |
157 | <tr> | 159 | <tr> |
158 | <td style="border: 1px solid black" colspan="2">包装费用收益</td> | 160 | <td style="border: 1px solid black" colspan="2">包装费用收益</td> |
159 | - <td style="border: 1px solid black"></td> | 161 | + <td style="border: 1px solid black">{{ packetProfitPrice }}</td> |
160 | <td style="border: 1px solid black"></td> | 162 | <td style="border: 1px solid black"></td> |
161 | </tr> | 163 | </tr> |
162 | <tr> | 164 | <tr> |
163 | <td style="border: 1px solid black" colspan="2">汇率收益</td> | 165 | <td style="border: 1px solid black" colspan="2">汇率收益</td> |
164 | - <td style="border: 1px solid black"></td> | 166 | + <td style="border: 1px solid black">{{ actualRatioProfitPrice }}</td> |
165 | <td style="border: 1px solid black"></td> | 167 | <td style="border: 1px solid black"></td> |
166 | </tr> | 168 | </tr> |
167 | <tr> | 169 | <tr> |
168 | <td style="border: 1px solid black" colspan="2">综合收益</td> | 170 | <td style="border: 1px solid black" colspan="2">综合收益</td> |
169 | - <td style="border: 1px solid black"></td> | 171 | + <td style="border: 1px solid black">{{ totalProfitPrice }}</td> |
170 | <td style="border: 1px solid black"></td> | 172 | <td style="border: 1px solid black"></td> |
171 | </tr> | 173 | </tr> |
172 | </tbody> | 174 | </tbody> |
@@ -178,7 +180,9 @@ | @@ -178,7 +180,9 @@ | ||
178 | import { computed, ref, toRaw } from 'vue'; | 180 | import { computed, ref, toRaw } from 'vue'; |
179 | // import { payDate, checkCreate } from '@/api/project/invoice'; | 181 | // import { payDate, checkCreate } from '@/api/project/invoice'; |
180 | import { calculateBusinessProfit, exportBusinessProfit } from '@/api/project/order'; | 182 | import { calculateBusinessProfit, exportBusinessProfit } from '@/api/project/order'; |
183 | + import { getList } from '/@/api/sys/config'; | ||
181 | import type { Dayjs } from 'dayjs'; | 184 | import type { Dayjs } from 'dayjs'; |
185 | + import axios from 'axios'; | ||
182 | 186 | ||
183 | const projectStartTime = ref(); | 187 | const projectStartTime = ref(); |
184 | const projectEndTime = ref(); | 188 | const projectEndTime = ref(); |
@@ -195,11 +199,14 @@ | @@ -195,11 +199,14 @@ | ||
195 | const developTotalPrice = ref(); | 199 | const developTotalPrice = ref(); |
196 | const copyTotalPrice = ref(); | 200 | const copyTotalPrice = ref(); |
197 | const packetActualTotalPrice = ref(); | 201 | const packetActualTotalPrice = ref(); |
198 | - const spainRatio = ref(); | ||
199 | - const chinaRatio = ref(); | 202 | + const spainRatio = ref(0); |
203 | + const chinaRatio = ref(0); | ||
200 | const actualRmbPrice = ref(0); //实际跟单单价 | 204 | const actualRmbPrice = ref(0); //实际跟单单价 |
201 | const actualPrice = ref(0); //实际跟单单价折算美金 | 205 | const actualPrice = ref(0); //实际跟单单价折算美金 |
202 | const actualRatio = ref(6.2); //实际汇率 | 206 | const actualRatio = ref(6.2); //实际汇率 |
207 | + const customerTotalPrice = ref(); //客户总价合计 | ||
208 | + const actualRatioProfitPrice = ref(); //汇率收益 | ||
209 | + const grossProfit = ref(); //毛利润合计 | ||
203 | const actualRatiactualRatioProfitPriceo = ref(); //汇率收益计算 | 210 | const actualRatiactualRatioProfitPriceo = ref(); //汇率收益计算 |
204 | const chinaRatioProfitPrice = ref(); //中国团队提成比例 | 211 | const chinaRatioProfitPrice = ref(); //中国团队提成比例 |
205 | const developProfit = ref(); //研发贸易利润 | 212 | const developProfit = ref(); //研发贸易利润 |
@@ -222,6 +229,58 @@ | @@ -222,6 +229,58 @@ | ||
222 | console.log(orderList.value, 565656); | 229 | console.log(orderList.value, 565656); |
223 | }); | 230 | }); |
224 | async function handleOk() { | 231 | async function handleOk() { |
232 | + axios | ||
233 | + .post( | ||
234 | + '/basic-api/order/erp/calculate_profit/business_profit_ratio_export', | ||
235 | + { | ||
236 | + customerCode: customerCode.value, | ||
237 | + projectNo: projectNo.value, | ||
238 | + projectStartTime: projectStartTime.value, | ||
239 | + projectEndTime: projectEndTime.value, | ||
240 | + produceStartTime: produceStartTime.value, | ||
241 | + produceEndTime: produceEndTime.value, | ||
242 | + developTotalPrice: developTotalPrice.value, | ||
243 | + copyTotalPrice: copyTotalPrice.value, | ||
244 | + spainRatio: spainRatio.value, | ||
245 | + chinaRatio: chinaRatio.value, | ||
246 | + packetActualTotalPrice: packetActualTotalPrice.value, | ||
247 | + actualRmbPrice: actualRmbPrice.value, | ||
248 | + actualPrice: actualPrice.value, | ||
249 | + actualRatio: actualRatio.value, | ||
250 | + }, | ||
251 | + { | ||
252 | + responseType: 'blob', // 设置响应类型为 'blob' | ||
253 | + }, | ||
254 | + ) | ||
255 | + .then((response) => { | ||
256 | + // 创建一个 Blob 对象来保存二进制数据 | ||
257 | + const blob = new Blob([response.data], { type: 'application/octet-stream' }); | ||
258 | + const getFormattedDate = (): string => { | ||
259 | + const date = new Date(); | ||
260 | + | ||
261 | + const year = date.getFullYear(); | ||
262 | + const month = String(date.getMonth() + 1).padStart(2, '0'); | ||
263 | + const day = String(date.getDate()).padStart(2, '0'); | ||
264 | + | ||
265 | + const hours = String(date.getHours()).padStart(2, '0'); | ||
266 | + const minutes = String(date.getMinutes()).padStart(2, '0'); | ||
267 | + const seconds = String(date.getSeconds()).padStart(2, '0'); | ||
268 | + | ||
269 | + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | ||
270 | + }; | ||
271 | + const date = getFormattedDate(); | ||
272 | + // 创建一个链接元素用于下载 | ||
273 | + const link = document.createElement('a'); | ||
274 | + link.href = window.URL.createObjectURL(blob); | ||
275 | + link.download = `业务/研发净利润分析${date}.pdf`; // 你可以为文件命名 | ||
276 | + document.body.appendChild(link); | ||
277 | + link.click(); // 自动点击链接,触发下载 | ||
278 | + console.log(link, 5656); | ||
279 | + document.body.removeChild(link); // 下载完成后移除链接 | ||
280 | + }) | ||
281 | + .catch((error) => { | ||
282 | + console.error(error); | ||
283 | + }); | ||
225 | closeModal(); | 284 | closeModal(); |
226 | } | 285 | } |
227 | function handleShow(visible: boolean) { | 286 | function handleShow(visible: boolean) { |
@@ -237,6 +296,25 @@ | @@ -237,6 +296,25 @@ | ||
237 | packetActualTotalPrice.value = null; | 296 | packetActualTotalPrice.value = null; |
238 | } | 297 | } |
239 | } | 298 | } |
299 | + //提成接口 | ||
300 | + interface RatioListItem { | ||
301 | + createBy: string; | ||
302 | + createTime: string; | ||
303 | + enableFlag: number; | ||
304 | + id: number; | ||
305 | + modifyBy: string; | ||
306 | + modifyTime: string; | ||
307 | + relationCode: string; | ||
308 | + relationName: string; | ||
309 | + relationValue: string; // 这里 relationValue 是一个字符串,但内部是一个 JSON 数组,需要进一步解析 | ||
310 | + settingCode: string; | ||
311 | + settingName: string; | ||
312 | + settingType: number; | ||
313 | + settingValue: string; | ||
314 | + } | ||
315 | + interface RatioList { | ||
316 | + items: RatioListItem[]; | ||
317 | + } | ||
240 | async function handleCalculate() { | 318 | async function handleCalculate() { |
241 | const packetCalculatePrice = ref(0); | 319 | const packetCalculatePrice = ref(0); |
242 | const orderCalculateCount = ref(0); | 320 | const orderCalculateCount = ref(0); |
@@ -250,8 +328,32 @@ | @@ -250,8 +328,32 @@ | ||
250 | actualRmbPrice.value += packetCalculatePrice.value / orderCalculateCount.value; | 328 | actualRmbPrice.value += packetCalculatePrice.value / orderCalculateCount.value; |
251 | }); | 329 | }); |
252 | actualPrice.value = actualRmbPrice.value / actualRatio.value; | 330 | actualPrice.value = actualRmbPrice.value / actualRatio.value; |
253 | - console.log(actualPrice.value, '5656actualPrice'); | ||
254 | - | 331 | + // const ratioList = (await getList({ settingType: 3 })) as Array<RatioListItem>; |
332 | + const ratioList = (await getList({ settingType: 3 })) as RatioList; | ||
333 | + const ratios = ratioList.items.filter((item) => item.settingValue === customerCode.value); | ||
334 | + console.log(ratios, '5656ratios'); | ||
335 | + const ratioAll = JSON.parse(ratios[0].relationValue); | ||
336 | + console.log(ratioAll, '5656ratios', ratioAll[1].relationValue, ratioAll[2].relationValue); | ||
337 | + chinaRatio.value = ratioAll[1].relationValue; | ||
338 | + spainRatio.value = ratioAll[2].relationValue; | ||
339 | + //提成比例为0,提成设为0 | ||
340 | + const params = { | ||
341 | + customerCode: customerCode.value, | ||
342 | + projectNo: projectNo.value, | ||
343 | + projectStartTime: projectStartTime.value, | ||
344 | + projectEndTime: projectEndTime.value, | ||
345 | + produceStartTime: produceStartTime.value, | ||
346 | + produceEndTime: produceEndTime.value, | ||
347 | + developTotalPrice: developTotalPrice.value, | ||
348 | + copyTotalPrice: copyTotalPrice.value, | ||
349 | + spainRatio: spainRatio.value, | ||
350 | + chinaRatio: chinaRatio.value, | ||
351 | + packetActualTotalPrice: packetActualTotalPrice.value, | ||
352 | + actualRmbPrice: actualRmbPrice.value, | ||
353 | + actualPrice: actualPrice.value, | ||
354 | + actualRatio: actualRatio.value, | ||
355 | + }; | ||
356 | + console.log(params, '5656params'); | ||
255 | const res = await calculateBusinessProfit({ | 357 | const res = await calculateBusinessProfit({ |
256 | customerCode: customerCode.value, | 358 | customerCode: customerCode.value, |
257 | projectNo: projectNo.value, | 359 | projectNo: projectNo.value, |
@@ -270,20 +372,23 @@ | @@ -270,20 +372,23 @@ | ||
270 | }); | 372 | }); |
271 | console.log(res, '5656resservice'); | 373 | console.log(res, '5656resservice'); |
272 | 374 | ||
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; //西班牙提成金额 | 375 | + customerTotalPrice.value = res.customerTotalPrice; |
376 | + grossProfit.value = res.grossProfit; | ||
377 | + actualRatioProfitPrice.value = res.actualRatioProfitPrice; | ||
378 | + actualRmbPrice.value = res.actualRmbPrice; | ||
379 | + actualPrice.value = res.actualPrice; | ||
380 | + actualRatio.value = res.actualRatio; | ||
381 | + actualRatiactualRatioProfitPriceo.value = res.actualRatioProfitPrice; //汇率收益计算 | ||
382 | + chinaRatioProfitPrice.value = res.chinaRatioProfitPrice; //中国团队提成比例 | ||
383 | + developProfit.value = res.developProfit; //研发贸易利润 | ||
384 | + fixCost.value = res.fixCost; // 固定成本 | ||
385 | + orderCount.value = res.orderCount; //订单总数量 | ||
386 | + outTotalPrice.value = res.outTotalPrice; //支出合计 | ||
387 | + packetProfitPrice.value = res.packetProfitPrice; //包装费用收益计算 | ||
388 | + packetTotalPrice.value = res.packetTotalPrice; //包装费用合计 | ||
389 | + productionDepartmentTotalPrice.value = res.productionDepartmentTotalPrice; //生成科总价 | ||
390 | + totalProfitPrice.value = res.totalProfitPrice; //综合收益计算 | ||
391 | + spainRatioProfitPrice.value = res.spainRatioProfitPrice; //西班牙提成金额 | ||
287 | } | 392 | } |
288 | </script> | 393 | </script> |
289 | <style scoped> | 394 | <style scoped> |
src/views/project/order/index.vue
@@ -23,7 +23,7 @@ | @@ -23,7 +23,7 @@ | ||
23 | <a-button | 23 | <a-button |
24 | :style="{ borderRadius: '5px 5px 5px 5px' }" | 24 | :style="{ borderRadius: '5px 5px 5px 5px' }" |
25 | type="link" | 25 | type="link" |
26 | - @click="checkedKeys = []" | 26 | + @click="handleClearChoose" |
27 | size="small" | 27 | size="small" |
28 | >清空</a-button | 28 | >清空</a-button |
29 | > | 29 | > |
@@ -38,7 +38,7 @@ | @@ -38,7 +38,7 @@ | ||
38 | <template v-if="column.key === 'action'"> | 38 | <template v-if="column.key === 'action'"> |
39 | <TableAction | 39 | <TableAction |
40 | :actions=" | 40 | :actions=" |
41 | - role !== ROLE.PRODUCE | 41 | + role !== ROLE.PRODUCE && role !== ROLE.FINANCE |
42 | ? [ | 42 | ? [ |
43 | { | 43 | { |
44 | // 数据分析没有编辑权限 | 44 | // 数据分析没有编辑权限 |
@@ -78,7 +78,9 @@ | @@ -78,7 +78,9 @@ | ||
78 | }, | 78 | }, |
79 | { | 79 | { |
80 | // 数据分析没有编辑权限 | 80 | // 数据分析没有编辑权限 |
81 | - ...((role === ROLE.ADMIN || role === ROLE.TRACKER) && { | 81 | + ...((role === ROLE.ADMIN || |
82 | + role === ROLE.TRACKER || | ||
83 | + role === ROLE.FINANCE) && { | ||
82 | label: '复制', | 84 | label: '复制', |
83 | // icon: 'ic:outline-delete-outline', | 85 | // icon: 'ic:outline-delete-outline', |
84 | onClick: handleCopy.bind(null, record), | 86 | onClick: handleCopy.bind(null, record), |
@@ -111,93 +113,100 @@ | @@ -111,93 +113,100 @@ | ||
111 | </template> | 113 | </template> |
112 | 114 | ||
113 | <template #toolbar> | 115 | <template #toolbar> |
114 | - <div style="width: 1050px; padding-left: 50px"> | ||
115 | - <!-- <a-space wrap :size="[8, 16]" :style="{ marginBottom: '2px', marginLeft: '10px' }"> --> | ||
116 | - <a-space wrap :style="{ marginBottom: '2px', marginTop: '2px' }"> | ||
117 | - <a-button | ||
118 | - :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
119 | - type="primary" | ||
120 | - @click="handleProductInvoiceModal" | ||
121 | - v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS || role === ROLE.TRACKER" | ||
122 | - >生产对账单创建</a-button | ||
123 | - > | ||
124 | - <a-button | ||
125 | - :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
126 | - shape="default" | ||
127 | - type="primary" | ||
128 | - @click="handleInvoiceCreateModal" | ||
129 | - v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS || role === ROLE.TRACKER" | ||
130 | - >Invoice创建</a-button | ||
131 | - > | ||
132 | - <a-select | ||
133 | - ref="select" | ||
134 | - v-model:value="value1" | ||
135 | - @change="handleChange" | ||
136 | - class="passCalculate" | ||
137 | - dropdown-class-name="dropdown-class" | ||
138 | - v-if="role === ROLE.ADMIN || role === ROLE.TRACKER || role === ROLE.BUSINESS" | ||
139 | - > | ||
140 | - <a-select-option value1="一次通过率">一次通过率</a-select-option> | ||
141 | - <a-select-option value="确认样品" @click="handlePassModal('确认意见')" | ||
142 | - >确认样品</a-select-option | 116 | + <div style="position: relative"> |
117 | + <div style="padding-left: 50px; right: 123px"> | ||
118 | + <!-- <a-space wrap :size="[8, 16]" :style="{ marginBottom: '2px', marginLeft: '10px' }"> --> | ||
119 | + <a-space wrap :style="{ marginBottom: '2px', marginTop: '2px' }"> | ||
120 | + <a-button | ||
121 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
122 | + type="primary" | ||
123 | + @click="handleProductInvoiceModal" | ||
124 | + v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS || role === ROLE.TRACKER" | ||
125 | + >生产对账单创建</a-button | ||
143 | > | 126 | > |
144 | - <a-select-option value="生产样品" @click="handlePassModal('生产样品')" | ||
145 | - >生产样品</a-select-option | 127 | + <a-button |
128 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
129 | + shape="default" | ||
130 | + type="primary" | ||
131 | + @click="handleInvoiceCreateModal" | ||
132 | + v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS || role === ROLE.TRACKER" | ||
133 | + >Invoice创建</a-button | ||
146 | > | 134 | > |
147 | - <a-select-option value="测试样品" @click="handlePassModal('测试样品')" | ||
148 | - >测试样品</a-select-option | 135 | + <a-select |
136 | + ref="select" | ||
137 | + v-model:value="value1" | ||
138 | + @change="handleChange" | ||
139 | + class="passCalculate" | ||
140 | + dropdown-class-name="dropdown-class" | ||
141 | + v-if="role === ROLE.ADMIN || role === ROLE.TRACKER || role === ROLE.BUSINESS" | ||
149 | > | 142 | > |
150 | - </a-select> | ||
151 | - <a-button | ||
152 | - :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
153 | - type="primary" | ||
154 | - @click="handleProductProfitModal" | ||
155 | - >内部生产净利润分析</a-button | ||
156 | - > | ||
157 | - <a-button | ||
158 | - :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
159 | - type="primary" | ||
160 | - @click="handleServiceProfitModal" | ||
161 | - >业务/研发净利润分析</a-button | ||
162 | - > | ||
163 | - <a-button | ||
164 | - :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
165 | - type="primary" | ||
166 | - @click="handleProductModal" | ||
167 | - v-if="role === ROLE.ADMIN || role === ROLE.TRACKER" | ||
168 | - >生产指标书</a-button | ||
169 | - > | ||
170 | - <a-button | ||
171 | - :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
172 | - type="primary" | ||
173 | - @click="handleRateModal" | ||
174 | - v-if="role === ROLE.ADMIN" | ||
175 | - >比重计算</a-button | ||
176 | - > | ||
177 | - <!-- 质检角色不能导出任何信息 --> | ||
178 | - <a-button | ||
179 | - :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
180 | - type="primary" | ||
181 | - @click="handleExportModal" | ||
182 | - v-if="role === ROLE.ADMIN || role === ROLE.TRACKER || role === ROLE.BUSINESS" | ||
183 | - >导出</a-button | ||
184 | - > | ||
185 | - <a-button | ||
186 | - :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
187 | - type="primary" | ||
188 | - @click="handleProfitModal" | ||
189 | - v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS" | ||
190 | - >分析利润</a-button | 143 | + <a-select-option value1="一次通过率">一次通过率</a-select-option> |
144 | + <a-select-option value="确认样品" @click="handlePassModal('确认意见')" | ||
145 | + >确认样品</a-select-option | ||
146 | + > | ||
147 | + <a-select-option value="生产样品" @click="handlePassModal('生产样品')" | ||
148 | + >生产样品</a-select-option | ||
149 | + > | ||
150 | + <a-select-option value="测试样品" @click="handlePassModal('测试样品')" | ||
151 | + >测试样品</a-select-option | ||
152 | + > | ||
153 | + </a-select> | ||
154 | + <a-button | ||
155 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
156 | + type="primary" | ||
157 | + @click="handleProductProfitModal" | ||
158 | + >内部生产净利润分析</a-button | ||
159 | + > | ||
160 | + <a-button | ||
161 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
162 | + type="primary" | ||
163 | + @click="handleServiceProfitModal" | ||
164 | + >业务/研发净利润分析</a-button | ||
165 | + > | ||
166 | + <a-button | ||
167 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
168 | + type="primary" | ||
169 | + @click="handleProductModal" | ||
170 | + v-if="role === ROLE.ADMIN || role === ROLE.TRACKER" | ||
171 | + >生产指示书</a-button | ||
172 | + > | ||
173 | + <a-button | ||
174 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
175 | + type="primary" | ||
176 | + @click="handleRateModal" | ||
177 | + v-if="role === ROLE.ADMIN" | ||
178 | + >比重计算</a-button | ||
179 | + > | ||
180 | + <!-- 质检角色不能导出任何信息 --> | ||
181 | + <a-button | ||
182 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
183 | + type="primary" | ||
184 | + @click="handleExportModal" | ||
185 | + v-if=" | ||
186 | + role === ROLE.ADMIN || | ||
187 | + role === ROLE.TRACKER || | ||
188 | + role === ROLE.BUSINESS || | ||
189 | + role === ROLE.FINANCE | ||
190 | + " | ||
191 | + >导出</a-button | ||
192 | + > | ||
193 | + <a-button | ||
194 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
195 | + type="primary" | ||
196 | + @click="handleProfitModal" | ||
197 | + v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS" | ||
198 | + >分析利润</a-button | ||
199 | + > | ||
200 | + <a-button | ||
201 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
202 | + type="primary" | ||
203 | + @click="handleAdd" | ||
204 | + v-if="role === ROLE.ADMIN || role === ROLE.TRACKER" | ||
205 | + >创建订单</a-button | ||
206 | + ></a-space | ||
191 | > | 207 | > |
192 | - <a-button | ||
193 | - :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
194 | - type="primary" | ||
195 | - @click="handleAdd" | ||
196 | - v-if="role === ROLE.ADMIN || role === ROLE.TRACKER" | ||
197 | - >创建订单</a-button | ||
198 | - ></a-space | ||
199 | - > | ||
200 | - </div> | 208 | + </div></div |
209 | + > | ||
201 | </template> | 210 | </template> |
202 | </BasicTable> | 211 | </BasicTable> |
203 | <FormDetail | 212 | <FormDetail |
@@ -368,13 +377,20 @@ | @@ -368,13 +377,20 @@ | ||
368 | 377 | ||
369 | // type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] | 378 | // type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] |
370 | // type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] | 379 | // type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] |
380 | + // type ProjectNoEntry = [string, number]; // 定义二维数组类型 [innerNo, count] | ||
371 | 381 | ||
372 | // const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref | 382 | // const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref |
373 | // const selectedProductionDepartment = ref<ProductionDepartmentEntry[]>([]); // 创建一个二维数组的 ref | 383 | // const selectedProductionDepartment = ref<ProductionDepartmentEntry[]>([]); // 创建一个二维数组的 ref |
384 | + // const selectedProjectNos = ref<ProjectNoEntry[]>([]); // 创建一个二维数组的 ref | ||
374 | 385 | ||
375 | // // 单选处理函数 | 386 | // // 单选处理函数 |
376 | // function onSelect( | 387 | // function onSelect( |
377 | - // record: { customerCode: string; productionDepartment: string; id: string }, | 388 | + // record: { |
389 | + // customerCode: string; | ||
390 | + // productionDepartment: string; | ||
391 | + // projectNo: string; | ||
392 | + // id: string; | ||
393 | + // }, | ||
378 | // selected: boolean, | 394 | // selected: boolean, |
379 | // ) { | 395 | // ) { |
380 | // // 查找 customerCode 在 selectedCustomCodes 中的位置 | 396 | // // 查找 customerCode 在 selectedCustomCodes 中的位置 |
@@ -387,6 +403,11 @@ | @@ -387,6 +403,11 @@ | ||
387 | // ([department]) => department === record.productionDepartment, | 403 | // ([department]) => department === record.productionDepartment, |
388 | // ); | 404 | // ); |
389 | 405 | ||
406 | + // // 查找 projectNo 在 selectedProjectNos 中的位置 | ||
407 | + // const projectNoIndex = selectedProjectNos.value.findIndex( | ||
408 | + // ([projectNo]) => projectNo === record.projectNo, | ||
409 | + // ); | ||
410 | + | ||
390 | // if (selected) { | 411 | // if (selected) { |
391 | // // 添加到 checkedKeys | 412 | // // 添加到 checkedKeys |
392 | // checkedKeys.value = [...checkedKeys.value, record.id]; | 413 | // checkedKeys.value = [...checkedKeys.value, record.id]; |
@@ -408,6 +429,15 @@ | @@ -408,6 +429,15 @@ | ||
408 | // // 如果不存在,添加新项 [productionDepartment, 1] | 429 | // // 如果不存在,添加新项 [productionDepartment, 1] |
409 | // selectedProductionDepartment.value.push([record.productionDepartment, 1]); | 430 | // selectedProductionDepartment.value.push([record.productionDepartment, 1]); |
410 | // } | 431 | // } |
432 | + | ||
433 | + // // 更新 selectedProjectNos | ||
434 | + // if (projectNoIndex !== -1) { | ||
435 | + // // 如果已存在,增加计数 | ||
436 | + // selectedProjectNos.value[projectNoIndex][1] += 1; | ||
437 | + // } else { | ||
438 | + // // 如果不存在,添加新项 [projectNo, 1] | ||
439 | + // selectedProjectNos.value.push([record.projectNo, 1]); | ||
440 | + // } | ||
411 | // } else { | 441 | // } else { |
412 | // // 从 checkedKeys 中移除 | 442 | // // 从 checkedKeys 中移除 |
413 | // checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); | 443 | // checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); |
@@ -429,19 +459,127 @@ | @@ -429,19 +459,127 @@ | ||
429 | // selectedProductionDepartment.value.splice(productionDepartmentIndex, 1); | 459 | // selectedProductionDepartment.value.splice(productionDepartmentIndex, 1); |
430 | // } | 460 | // } |
431 | // } | 461 | // } |
462 | + | ||
463 | + // // 更新 selectedProjectNos | ||
464 | + // if (projectNoIndex !== -1) { | ||
465 | + // if (selectedProjectNos.value[projectNoIndex][1] > 1) { | ||
466 | + // selectedProjectNos.value[projectNoIndex][1] -= 1; | ||
467 | + // } else { | ||
468 | + // selectedProjectNos.value.splice(projectNoIndex, 1); | ||
469 | + // } | ||
470 | + // } | ||
471 | + // } | ||
472 | + | ||
473 | + // console.log('5656Checked Keys:', checkedKeys.value); | ||
474 | + // console.log('5656Selected Customer Codes:', selectedCustomCodes.value); | ||
475 | + // console.log('56565Selected Production Departments:', selectedProductionDepartment.value); | ||
476 | + // console.log('5656Selected projectNo:', selectedProjectNos.value); | ||
477 | + // } | ||
478 | + | ||
479 | + // // 全选处理函数 | ||
480 | + // function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) { | ||
481 | + // const changeIds = changeRows.map((item) => item.id); | ||
482 | + // const changeCustomerCodes = changeRows.map((item) => item.customerCode); | ||
483 | + // const changeProductionDepartments = changeRows.map((item) => item.productionDepartment); | ||
484 | + // const changeProjectNos = changeRows.map((item) => item.projectNo); | ||
485 | + | ||
486 | + // if (selected) { | ||
487 | + // // 添加到 checkedKeys | ||
488 | + // checkedKeys.value = [...checkedKeys.value, ...changeIds]; | ||
489 | + | ||
490 | + // // 更新 selectedCustomCodes | ||
491 | + // changeCustomerCodes.forEach((code) => { | ||
492 | + // const index = selectedCustomCodes.value.findIndex( | ||
493 | + // ([customerCode]) => customerCode === code, | ||
494 | + // ); | ||
495 | + // if (index !== -1) { | ||
496 | + // selectedCustomCodes.value[index][1] += 1; | ||
497 | + // } else { | ||
498 | + // selectedCustomCodes.value.push([code, 1]); | ||
499 | + // } | ||
500 | + // }); | ||
501 | + | ||
502 | + // // 更新 selectedProductionDepartment | ||
503 | + // changeProductionDepartments.forEach((department) => { | ||
504 | + // const index = selectedProductionDepartment.value.findIndex( | ||
505 | + // ([prodDepartment]) => prodDepartment === department, | ||
506 | + // ); | ||
507 | + // if (index !== -1) { | ||
508 | + // selectedProductionDepartment.value[index][1] += 1; | ||
509 | + // } else { | ||
510 | + // selectedProductionDepartment.value.push([department, 1]); | ||
511 | + // } | ||
512 | + // }); | ||
513 | + | ||
514 | + // // 更新 selectedProjectNos | ||
515 | + // changeProjectNos.forEach((projectNo) => { | ||
516 | + // const index = selectedProjectNos.value.findIndex(([no]) => no === projectNo); | ||
517 | + // if (index !== -1) { | ||
518 | + // selectedProjectNos.value[index][1] += 1; | ||
519 | + // } else { | ||
520 | + // selectedProjectNos.value.push([projectNo, 1]); | ||
521 | + // } | ||
522 | + // }); | ||
523 | + // } else { | ||
524 | + // // 从 checkedKeys 中移除 | ||
525 | + // checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id)); | ||
526 | + | ||
527 | + // // 更新 selectedCustomCodes | ||
528 | + // changeCustomerCodes.forEach((code) => { | ||
529 | + // const index = selectedCustomCodes.value.findIndex( | ||
530 | + // ([customerCode]) => customerCode === code, | ||
531 | + // ); | ||
532 | + // if (index !== -1) { | ||
533 | + // if (selectedCustomCodes.value[index][1] > 1) { | ||
534 | + // selectedCustomCodes.value[index][1] -= 1; | ||
535 | + // } else { | ||
536 | + // selectedCustomCodes.value.splice(index, 1); | ||
537 | + // } | ||
538 | + // } | ||
539 | + // }); | ||
540 | + | ||
541 | + // // 更新 selectedProductionDepartment | ||
542 | + // changeProductionDepartments.forEach((department) => { | ||
543 | + // const index = selectedProductionDepartment.value.findIndex( | ||
544 | + // ([prodDepartment]) => prodDepartment === department, | ||
545 | + // ); | ||
546 | + // if (index !== -1) { | ||
547 | + // if (selectedProductionDepartment.value[index][1] > 1) { | ||
548 | + // selectedProductionDepartment.value[index][1] -= 1; | ||
549 | + // } else { | ||
550 | + // selectedProductionDepartment.value.splice(index, 1); | ||
551 | + // } | ||
552 | + // } | ||
553 | + // }); | ||
554 | + | ||
555 | + // // 更新 selectedProjectNos | ||
556 | + // changeProjectNos.forEach((projectNo) => { | ||
557 | + // const index = selectedProjectNos.value.findIndex(([no]) => no === projectNo); | ||
558 | + // if (index !== -1) { | ||
559 | + // if (selectedProjectNos.value[index][1] > 1) { | ||
560 | + // selectedProjectNos.value[index][1] -= 1; | ||
561 | + // } else { | ||
562 | + // selectedProjectNos.value.splice(index, 1); | ||
563 | + // } | ||
564 | + // } | ||
565 | + // }); | ||
432 | // } | 566 | // } |
433 | 567 | ||
434 | // console.log('5656Checked Keys:', checkedKeys.value); | 568 | // console.log('5656Checked Keys:', checkedKeys.value); |
435 | // console.log('5656Selected Customer Codes:', selectedCustomCodes.value); | 569 | // console.log('5656Selected Customer Codes:', selectedCustomCodes.value); |
436 | // console.log('5656Selected Production Departments:', selectedProductionDepartment.value); | 570 | // console.log('5656Selected Production Departments:', selectedProductionDepartment.value); |
571 | + // console.log('5656Selected projectNos:', selectedProjectNos.value); | ||
437 | // } | 572 | // } |
573 | + | ||
438 | type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] | 574 | type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] |
439 | type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] | 575 | type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] |
440 | type ProjectNoEntry = [string, number]; // 定义二维数组类型 [innerNo, count] | 576 | type ProjectNoEntry = [string, number]; // 定义二维数组类型 [innerNo, count] |
577 | + type BusinessPersonEntry = [string, number]; // 定义二维数组类型 [businessPerson, count] | ||
441 | 578 | ||
442 | const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref | 579 | const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref |
443 | const selectedProductionDepartment = ref<ProductionDepartmentEntry[]>([]); // 创建一个二维数组的 ref | 580 | const selectedProductionDepartment = ref<ProductionDepartmentEntry[]>([]); // 创建一个二维数组的 ref |
444 | const selectedProjectNos = ref<ProjectNoEntry[]>([]); // 创建一个二维数组的 ref | 581 | const selectedProjectNos = ref<ProjectNoEntry[]>([]); // 创建一个二维数组的 ref |
582 | + const selectedBusinessPersons = ref<BusinessPersonEntry[]>([]); // 创建一个二维数组的 ref | ||
445 | 583 | ||
446 | // 单选处理函数 | 584 | // 单选处理函数 |
447 | function onSelect( | 585 | function onSelect( |
@@ -449,57 +587,58 @@ | @@ -449,57 +587,58 @@ | ||
449 | customerCode: string; | 587 | customerCode: string; |
450 | productionDepartment: string; | 588 | productionDepartment: string; |
451 | projectNo: string; | 589 | projectNo: string; |
590 | + businessPerson: string; // 添加 businessPerson 属性 | ||
452 | id: string; | 591 | id: string; |
453 | }, | 592 | }, |
454 | selected: boolean, | 593 | selected: boolean, |
455 | ) { | 594 | ) { |
456 | - // 查找 customerCode 在 selectedCustomCodes 中的位置 | ||
457 | const customerCodeIndex = selectedCustomCodes.value.findIndex( | 595 | const customerCodeIndex = selectedCustomCodes.value.findIndex( |
458 | ([customerCode]) => customerCode === record.customerCode, | 596 | ([customerCode]) => customerCode === record.customerCode, |
459 | ); | 597 | ); |
460 | 598 | ||
461 | - // 查找 productionDepartment 在 selectedProductionDepartment 中的位置 | ||
462 | const productionDepartmentIndex = selectedProductionDepartment.value.findIndex( | 599 | const productionDepartmentIndex = selectedProductionDepartment.value.findIndex( |
463 | ([department]) => department === record.productionDepartment, | 600 | ([department]) => department === record.productionDepartment, |
464 | ); | 601 | ); |
465 | 602 | ||
466 | - // 查找 projectNo 在 selectedProjectNos 中的位置 | ||
467 | const projectNoIndex = selectedProjectNos.value.findIndex( | 603 | const projectNoIndex = selectedProjectNos.value.findIndex( |
468 | ([projectNo]) => projectNo === record.projectNo, | 604 | ([projectNo]) => projectNo === record.projectNo, |
469 | ); | 605 | ); |
470 | 606 | ||
607 | + const businessPersonIndex = selectedBusinessPersons.value.findIndex( | ||
608 | + ([businessPerson]) => businessPerson === record.businessPerson, | ||
609 | + ); | ||
610 | + | ||
471 | if (selected) { | 611 | if (selected) { |
472 | - // 添加到 checkedKeys | ||
473 | checkedKeys.value = [...checkedKeys.value, record.id]; | 612 | checkedKeys.value = [...checkedKeys.value, record.id]; |
474 | 613 | ||
475 | // 更新 selectedCustomCodes | 614 | // 更新 selectedCustomCodes |
476 | if (customerCodeIndex !== -1) { | 615 | if (customerCodeIndex !== -1) { |
477 | - // 如果已存在,增加计数 | ||
478 | selectedCustomCodes.value[customerCodeIndex][1] += 1; | 616 | selectedCustomCodes.value[customerCodeIndex][1] += 1; |
479 | } else { | 617 | } else { |
480 | - // 如果不存在,添加新项 [customerCode, 1] | ||
481 | selectedCustomCodes.value.push([record.customerCode, 1]); | 618 | selectedCustomCodes.value.push([record.customerCode, 1]); |
482 | } | 619 | } |
483 | 620 | ||
484 | // 更新 selectedProductionDepartment | 621 | // 更新 selectedProductionDepartment |
485 | if (productionDepartmentIndex !== -1) { | 622 | if (productionDepartmentIndex !== -1) { |
486 | - // 如果已存在,增加计数 | ||
487 | selectedProductionDepartment.value[productionDepartmentIndex][1] += 1; | 623 | selectedProductionDepartment.value[productionDepartmentIndex][1] += 1; |
488 | } else { | 624 | } else { |
489 | - // 如果不存在,添加新项 [productionDepartment, 1] | ||
490 | selectedProductionDepartment.value.push([record.productionDepartment, 1]); | 625 | selectedProductionDepartment.value.push([record.productionDepartment, 1]); |
491 | } | 626 | } |
492 | 627 | ||
493 | // 更新 selectedProjectNos | 628 | // 更新 selectedProjectNos |
494 | if (projectNoIndex !== -1) { | 629 | if (projectNoIndex !== -1) { |
495 | - // 如果已存在,增加计数 | ||
496 | selectedProjectNos.value[projectNoIndex][1] += 1; | 630 | selectedProjectNos.value[projectNoIndex][1] += 1; |
497 | } else { | 631 | } else { |
498 | - // 如果不存在,添加新项 [projectNo, 1] | ||
499 | selectedProjectNos.value.push([record.projectNo, 1]); | 632 | selectedProjectNos.value.push([record.projectNo, 1]); |
500 | } | 633 | } |
634 | + | ||
635 | + // 更新 selectedBusinessPersons | ||
636 | + if (businessPersonIndex !== -1) { | ||
637 | + selectedBusinessPersons.value[businessPersonIndex][1] += 1; | ||
638 | + } else { | ||
639 | + selectedBusinessPersons.value.push([record.businessPerson, 1]); | ||
640 | + } | ||
501 | } else { | 641 | } else { |
502 | - // 从 checkedKeys 中移除 | ||
503 | checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); | 642 | checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); |
504 | 643 | ||
505 | // 更新 selectedCustomCodes | 644 | // 更新 selectedCustomCodes |
@@ -528,94 +667,33 @@ | @@ -528,94 +667,33 @@ | ||
528 | selectedProjectNos.value.splice(projectNoIndex, 1); | 667 | selectedProjectNos.value.splice(projectNoIndex, 1); |
529 | } | 668 | } |
530 | } | 669 | } |
670 | + | ||
671 | + // 更新 selectedBusinessPersons | ||
672 | + if (businessPersonIndex !== -1) { | ||
673 | + if (selectedBusinessPersons.value[businessPersonIndex][1] > 1) { | ||
674 | + selectedBusinessPersons.value[businessPersonIndex][1] -= 1; | ||
675 | + } else { | ||
676 | + selectedBusinessPersons.value.splice(businessPersonIndex, 1); | ||
677 | + } | ||
678 | + } | ||
531 | } | 679 | } |
532 | 680 | ||
533 | - console.log('5656Checked Keys:', checkedKeys.value); | ||
534 | - console.log('5656Selected Customer Codes:', selectedCustomCodes.value); | ||
535 | - console.log('56565Selected Production Departments:', selectedProductionDepartment.value); | ||
536 | - console.log('5656Selected projectNo:', selectedProjectNos.value); | 681 | + console.log('Checked Keys:', checkedKeys.value); |
682 | + console.log('Selected Customer Codes:', selectedCustomCodes.value); | ||
683 | + console.log('Selected Production Departments:', selectedProductionDepartment.value); | ||
684 | + console.log('Selected Project Nos:', selectedProjectNos.value); | ||
685 | + console.log('Selected Business Persons:', selectedBusinessPersons.value); | ||
537 | } | 686 | } |
538 | 687 | ||
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 | - | ||
610 | // 全选处理函数 | 688 | // 全选处理函数 |
611 | function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) { | 689 | function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) { |
612 | const changeIds = changeRows.map((item) => item.id); | 690 | const changeIds = changeRows.map((item) => item.id); |
613 | const changeCustomerCodes = changeRows.map((item) => item.customerCode); | 691 | const changeCustomerCodes = changeRows.map((item) => item.customerCode); |
614 | const changeProductionDepartments = changeRows.map((item) => item.productionDepartment); | 692 | const changeProductionDepartments = changeRows.map((item) => item.productionDepartment); |
615 | const changeProjectNos = changeRows.map((item) => item.projectNo); | 693 | const changeProjectNos = changeRows.map((item) => item.projectNo); |
694 | + const changeBusinessPersons = changeRows.map((item) => item.businessPerson); // 新增处理 businessPerson | ||
616 | 695 | ||
617 | if (selected) { | 696 | if (selected) { |
618 | - // 添加到 checkedKeys | ||
619 | checkedKeys.value = [...checkedKeys.value, ...changeIds]; | 697 | checkedKeys.value = [...checkedKeys.value, ...changeIds]; |
620 | 698 | ||
621 | // 更新 selectedCustomCodes | 699 | // 更新 selectedCustomCodes |
@@ -651,8 +729,17 @@ | @@ -651,8 +729,17 @@ | ||
651 | selectedProjectNos.value.push([projectNo, 1]); | 729 | selectedProjectNos.value.push([projectNo, 1]); |
652 | } | 730 | } |
653 | }); | 731 | }); |
732 | + | ||
733 | + // 更新 selectedBusinessPersons | ||
734 | + changeBusinessPersons.forEach((businessPerson) => { | ||
735 | + const index = selectedBusinessPersons.value.findIndex(([bp]) => bp === businessPerson); | ||
736 | + if (index !== -1) { | ||
737 | + selectedBusinessPersons.value[index][1] += 1; | ||
738 | + } else { | ||
739 | + selectedBusinessPersons.value.push([businessPerson, 1]); | ||
740 | + } | ||
741 | + }); | ||
654 | } else { | 742 | } else { |
655 | - // 从 checkedKeys 中移除 | ||
656 | checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id)); | 743 | checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id)); |
657 | 744 | ||
658 | // 更新 selectedCustomCodes | 745 | // 更新 selectedCustomCodes |
@@ -684,7 +771,7 @@ | @@ -684,7 +771,7 @@ | ||
684 | }); | 771 | }); |
685 | 772 | ||
686 | // 更新 selectedProjectNos | 773 | // 更新 selectedProjectNos |
687 | - changeInnerNos.forEach((projectNo) => { | 774 | + changeProjectNos.forEach((projectNo) => { |
688 | const index = selectedProjectNos.value.findIndex(([no]) => no === projectNo); | 775 | const index = selectedProjectNos.value.findIndex(([no]) => no === projectNo); |
689 | if (index !== -1) { | 776 | if (index !== -1) { |
690 | if (selectedProjectNos.value[index][1] > 1) { | 777 | if (selectedProjectNos.value[index][1] > 1) { |
@@ -694,12 +781,33 @@ | @@ -694,12 +781,33 @@ | ||
694 | } | 781 | } |
695 | } | 782 | } |
696 | }); | 783 | }); |
784 | + | ||
785 | + // 更新 selectedBusinessPersons | ||
786 | + changeBusinessPersons.forEach((businessPerson) => { | ||
787 | + const index = selectedBusinessPersons.value.findIndex(([bp]) => bp === businessPerson); | ||
788 | + if (index !== -1) { | ||
789 | + if (selectedBusinessPersons.value[index][1] > 1) { | ||
790 | + selectedBusinessPersons.value[index][1] -= 1; | ||
791 | + } else { | ||
792 | + selectedBusinessPersons.value.splice(index, 1); | ||
793 | + } | ||
794 | + } | ||
795 | + }); | ||
697 | } | 796 | } |
698 | 797 | ||
699 | - console.log('5656Checked Keys:', checkedKeys.value); | ||
700 | - console.log('5656Selected Customer Codes:', selectedCustomCodes.value); | ||
701 | - console.log('5656Selected Production Departments:', selectedProductionDepartment.value); | ||
702 | - console.log('5656Selected projectNos:', selectedProjectNos.value); | 798 | + console.log('Checked Keys:', checkedKeys.value); |
799 | + console.log('Selected Customer Codes:', selectedCustomCodes.value); | ||
800 | + console.log('Selected Production Departments:', selectedProductionDepartment.value); | ||
801 | + console.log('Selected Project Nos:', selectedProjectNos.value); | ||
802 | + console.log('Selected Business Persons:', selectedBusinessPersons.value); | ||
803 | + } | ||
804 | + | ||
805 | + function handleClearChoose() { | ||
806 | + checkedKeys.value = []; | ||
807 | + selectedCustomCodes.value = []; | ||
808 | + selectedProductionDepartment.value = []; | ||
809 | + selectedProjectNos.value = []; | ||
810 | + selectedBusinessPersons.value = []; | ||
703 | } | 811 | } |
704 | 812 | ||
705 | function handleEdit(record, e) { | 813 | function handleEdit(record, e) { |
@@ -820,10 +928,18 @@ | @@ -820,10 +928,18 @@ | ||
820 | const form = getForm(); | 928 | const form = getForm(); |
821 | const values = form.getFieldsValue(); | 929 | const values = form.getFieldsValue(); |
822 | console.log(selectedCustomCodes.value, 5656); | 930 | console.log(selectedCustomCodes.value, 5656); |
823 | - if (selectedCustomCodes.value.length == 0) { | 931 | + if (checkedKeys.value.length == 0) { |
824 | error('请选择订单'); | 932 | error('请选择订单'); |
825 | return; | 933 | return; |
826 | } | 934 | } |
935 | + if (selectedCustomCodes.value.length > 1) { | ||
936 | + error('客户编码需一致'); | ||
937 | + return; | ||
938 | + } | ||
939 | + if (selectedBusinessPersons.value.length > 1) { | ||
940 | + error('业务员需一致'); | ||
941 | + return; | ||
942 | + } | ||
827 | openProductModal(true, { | 943 | openProductModal(true, { |
828 | checkedKeys: checkedKeys.value, | 944 | checkedKeys: checkedKeys.value, |
829 | customers: selectedCustomCodes.value, | 945 | customers: selectedCustomCodes.value, |
@@ -980,6 +1096,7 @@ | @@ -980,6 +1096,7 @@ | ||
980 | handleDelete, | 1096 | handleDelete, |
981 | handleServiceProfitModal, | 1097 | handleServiceProfitModal, |
982 | handleProductProfitModal, | 1098 | handleProductProfitModal, |
1099 | + handleClearChoose, | ||
983 | selectedCustomCodes, | 1100 | selectedCustomCodes, |
984 | role, | 1101 | role, |
985 | ROLE, | 1102 | ROLE, |
src/views/project/order/tableData.tsx
@@ -161,9 +161,21 @@ export const ORDER_LIST_BASE_FIELDS = [ | @@ -161,9 +161,21 @@ export const ORDER_LIST_BASE_FIELDS = [ | ||
161 | { | 161 | { |
162 | field: 'returnOrder', | 162 | field: 'returnOrder', |
163 | component: 'Select', | 163 | component: 'Select', |
164 | - default: '请选择', | ||
165 | - label: '是否返单 ', | 164 | + labelWidth: 150, |
165 | + label: '是否返单', | ||
166 | rules: [{ required: true }], | 166 | rules: [{ required: true }], |
167 | + componentProps: { | ||
168 | + options: [ | ||
169 | + { | ||
170 | + label: '是', | ||
171 | + value: '1', | ||
172 | + }, | ||
173 | + { | ||
174 | + label: '否', | ||
175 | + value: '0', | ||
176 | + }, | ||
177 | + ], | ||
178 | + }, | ||
167 | }, | 179 | }, |
168 | ]; | 180 | ]; |
169 | 181 | ||
@@ -692,6 +704,17 @@ export function getOrderColumns(role: ROLE) { | @@ -692,6 +704,17 @@ export function getOrderColumns(role: ROLE) { | ||
692 | ...ORDER_LIST_SCHEDULE, | 704 | ...ORDER_LIST_SCHEDULE, |
693 | ]; | 705 | ]; |
694 | } | 706 | } |
707 | + //财务看到所有列 | ||
708 | + if (role === ROLE.FINANCE) { | ||
709 | + return [ | ||
710 | + ...ORDER_LIST_BASE_FIELDS, | ||
711 | + ...ORDER_LIST_PROFIT_FIELDS, | ||
712 | + ...ORDER_LIST_REPORT_FIELDS, | ||
713 | + ...ORDER_LIST_TRACK_FIELDS, | ||
714 | + ...ORDER_LIST_INSPECT_FIELDS, | ||
715 | + ...ORDER_LIST_SCHEDULE, | ||
716 | + ]; | ||
717 | + } | ||
695 | //业务员看到-基本,项目报告书,利润分析,跟单信息,质检 | 718 | //业务员看到-基本,项目报告书,利润分析,跟单信息,质检 |
696 | if (role === ROLE.BUSINESS) { | 719 | if (role === ROLE.BUSINESS) { |
697 | return [ | 720 | return [ |
vite.config.ts
@@ -20,7 +20,7 @@ export default defineApplicationConfig({ | @@ -20,7 +20,7 @@ export default defineApplicationConfig({ | ||
20 | server: { | 20 | server: { |
21 | proxy: { | 21 | proxy: { |
22 | '/basic-api/order': { | 22 | '/basic-api/order': { |
23 | - target: 'http://47.104.8.35:18000', | 23 | + target: 'http://47.104.8.35:18001', |
24 | // target: 'http://localhost:8001', | 24 | // target: 'http://localhost:8001', |
25 | // target: 'http://39.108.227.113:8000', | 25 | // target: 'http://39.108.227.113:8000', |
26 | // target: 'http://localhost:8000', | 26 | // target: 'http://localhost:8000', |
@@ -31,7 +31,7 @@ export default defineApplicationConfig({ | @@ -31,7 +31,7 @@ export default defineApplicationConfig({ | ||
31 | rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), | 31 | rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), |
32 | }, | 32 | }, |
33 | '/api/localStorage/upload': { | 33 | '/api/localStorage/upload': { |
34 | - target: 'http://47.104.8.35:18000', | 34 | + target: 'http://47.104.8.35:18001', |
35 | // target: 'http://localhost:8001', | 35 | // target: 'http://localhost:8001', |
36 | // target: 'http://39.108.227.113:8000', | 36 | // target: 'http://39.108.227.113:8000', |
37 | // target: '192.168.31.250:18000', | 37 | // target: '192.168.31.250:18000', |