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 | 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 | 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 | 18 | return res; |
19 | 19 | }; |
20 | 20 | ... | ... |
src/api/project/order.ts
... | ... | @@ -34,8 +34,8 @@ enum Api { |
34 | 34 | |
35 | 35 | TRACK_HISTORY = '/order/erp/opinion/log/query_by_id', //跟单结果记录 |
36 | 36 | PASS_CALCULATE = '/order/erp/order/passRate', //一次性通过率 |
37 | - CREATE_PRODUCT_TEXT = '/order/erp/order/produceReport', //生成生产指标书 | |
38 | - EXPORT_PRODUCT_TEXT = '/order/erp/order/send', //导出生产指标书 | |
37 | + CREATE_PRODUCT_TEXT = '/order/erp/order/produceReport', //生成生产指示书 | |
38 | + EXPORT_PRODUCT_TEXT = '/order/erp/order/send', //导出生产指示书 | |
39 | 39 | |
40 | 40 | BUSINESS_PROFIT_RATIO = '/order/erp/calculate_profit/business_profit_ratio', //业务/研发净利润分析 |
41 | 41 | BUSINESS_PROFIT_RATIO_EXPORT = '/order/erp/calculate_profit/business_profit_ratio_export', //业务/研发净利润分析_导出 | ... | ... |
src/router/routes/modules/project/approve.ts
src/store/modules/user.ts
... | ... | @@ -189,10 +189,15 @@ export function useUserStoreWithOut() { |
189 | 189 | return useUserStore(store); |
190 | 190 | } |
191 | 191 | |
192 | +//分析台订单趋势 | |
193 | +export const dateTime = ref(); | |
194 | +//分析台时期 | |
195 | +export const period = ref(); | |
196 | + | |
192 | 197 | //分析台切换页面变量 |
193 | 198 | export const exchangeTab = ref('tab1'); |
194 | -//分析台时期 | |
195 | -// export const period = ref(''); | |
199 | + | |
200 | +//销售额完成率 | |
196 | 201 | //分析台业务员 |
197 | 202 | export const businessPersonIn = ref(); |
198 | 203 | //分析台客户编码 | ... | ... |
src/views/dashboard/analysis/components/GrowCard.vue
... | ... | @@ -47,21 +47,40 @@ |
47 | 47 | import { growCardList } from '../data'; |
48 | 48 | import { useDataStoreWithOut } from '/@/store/modules/data'; |
49 | 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 | 57 | import { number } from 'vue-types'; |
52 | - import { getSalesData, getCustomerSalesData } from '/@/api/project/global'; | |
58 | + import { getSalesData, getApiData } from '/@/api/project/global'; | |
53 | 59 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
54 | 60 | |
55 | 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 | 76 | const growCardList = computed(() => { |
58 | 77 | const data = dataStore.getData; |
59 | - | |
78 | + console.log(data1.value, '5656data1.value'); | |
60 | 79 | return [ |
61 | 80 | { |
62 | 81 | title: '订单完成', |
63 | 82 | icon: 'visit-count|svg', |
64 | - value: data?.orderFinishedCount || 0, | |
83 | + value: data1.value?.allCount || 0, | |
65 | 84 | total: 120000, |
66 | 85 | color: 'green', |
67 | 86 | action: '月', |
... | ... | @@ -69,7 +88,7 @@ |
69 | 88 | { |
70 | 89 | title: '跟单和质检中', |
71 | 90 | icon: 'total-sales|svg', |
72 | - value: data?.orderInspectingCount || 0, | |
91 | + value: data1.value?.trackingAndInspectingList || 0, | |
73 | 92 | total: 500000, |
74 | 93 | color: 'blue', |
75 | 94 | action: '月', |
... | ... | @@ -77,7 +96,7 @@ |
77 | 96 | { |
78 | 97 | title: '利润分析表待审核', |
79 | 98 | icon: 'download-count|svg', |
80 | - value: data?.orderProfitWaitAuditCount || 0, | |
99 | + value: data1.value?.profitList || 0, | |
81 | 100 | total: 120000, |
82 | 101 | color: 'orange', |
83 | 102 | action: '周', |
... | ... | @@ -85,7 +104,7 @@ |
85 | 104 | { |
86 | 105 | title: '项目报告书待审核', |
87 | 106 | icon: 'transaction|svg', |
88 | - value: data?.orderReportWaitAuditCount || 0, | |
107 | + value: data1.value?.reportList || 0, | |
89 | 108 | total: 50000, |
90 | 109 | color: 'purple', |
91 | 110 | action: '年', |
... | ... | @@ -93,7 +112,7 @@ |
93 | 112 | { |
94 | 113 | title: '订单初始化', |
95 | 114 | icon: 'transaction|svg', |
96 | - value: data?.orderCount || 0, | |
115 | + value: data1.value?.orderInitList || 0, | |
97 | 116 | total: 50000, |
98 | 117 | color: 'purple', |
99 | 118 | action: '年', |
... | ... | @@ -108,6 +127,11 @@ |
108 | 127 | // }); |
109 | 128 | // }); |
110 | 129 | onMounted(async () => { |
130 | + data1.value = await getApiData({ | |
131 | + dateTime: dateTime.value, | |
132 | + period: period.value, | |
133 | + }); | |
134 | + console.log(data1.value, '56565656'); | |
111 | 135 | data2.value = await getSalesData({ |
112 | 136 | businessPersonIn: businessPersonIn.value, |
113 | 137 | customerCodeIn: customerCodeIn.value, |
... | ... | @@ -115,14 +139,14 @@ |
115 | 139 | }); |
116 | 140 | watch( |
117 | 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 | 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 | 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 | 22 | <div ref="chartRef" :style="{ height: '500px', width }"></div> |
3 | 23 | </template> |
4 | 24 | |
... | ... | @@ -8,15 +28,71 @@ |
8 | 28 | import { basicProps } from './props'; |
9 | 29 | import { max } from 'lodash-es'; |
10 | 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 | 35 | defineProps({ |
13 | 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 | 56 | const chartRef = ref<HTMLDivElement | null>(null); |
16 | 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 | 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 | 96 | const maxY = data?.y ? max(data?.y) : 0; |
21 | 97 | setOptions({ |
22 | 98 | tooltip: { |
... | ... | @@ -30,7 +106,6 @@ |
30 | 106 | }, |
31 | 107 | xAxis: { |
32 | 108 | type: 'category', |
33 | - boundaryGap: false, | |
34 | 109 | data: data?.x, |
35 | 110 | splitLine: { |
36 | 111 | show: true, |
... | ... | @@ -87,3 +162,29 @@ |
87 | 162 | }); |
88 | 163 | }); |
89 | 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 | 55 | </div></div |
56 | 56 | > |
57 | 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 | 59 | </template> |
60 | 60 | <script lang="ts"> |
61 | 61 | import { basicProps } from './props'; |
... | ... | @@ -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 | 184 | xAxis: { |
182 | 185 | type: 'category', |
183 | 186 | data: customerChartData1?.x, |
184 | 187 | }, |
185 | 188 | yAxis: { |
186 | 189 | type: 'value', |
187 | - // max: 8000, | |
188 | - splitNumber: 4, | |
190 | + // // max: 8000, | |
191 | + // splitNumber: 4, | |
189 | 192 | }, |
190 | 193 | series: [ |
191 | 194 | { |
195 | + name: '销售额', | |
192 | 196 | data: customerChartData1?.y, |
193 | 197 | type: 'bar', |
194 | 198 | barMaxWidth: 80, |
195 | 199 | }, |
196 | 200 | { |
201 | + name: '销售目标', | |
197 | 202 | smooth: true, |
198 | 203 | data: customerChartData1?.z, |
199 | 204 | type: 'line', | ... | ... |
src/views/project/approve/FieldPanel.vue
src/views/project/approve/PayPanel.vue
... | ... | @@ -12,6 +12,7 @@ |
12 | 12 | </template> |
13 | 13 | <template v-if="column.key === 'action'"> |
14 | 14 | <TableAction |
15 | + v-if="!isApproved" | |
15 | 16 | :actions="[ |
16 | 17 | { |
17 | 18 | label: '编辑', |
... | ... | @@ -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 | 34 | </template> |
24 | 35 | </template> |
25 | 36 | </BasicTable> |
37 | + <!-- :showFooter="!isApproved && role === ROLE.ADMIN" --> | |
38 | + | |
26 | 39 | <BasicModal |
27 | - :showFooter="!isApproved && role === ROLE.ADMIN" | |
40 | + :formFooter="!isApproved && role === ROLE.ADMIN" | |
28 | 41 | @register="registerModal" |
29 | 42 | title="申请信息" |
30 | 43 | okText="通过" |
31 | 44 | @ok="handleTrue" |
45 | + :showCancelBtn="!isApproved && role === ROLE.ADMIN" | |
46 | + :showOkBtn="!isApproved && role === ROLE.ADMIN" | |
32 | 47 | > |
33 | 48 | <Description |
34 | 49 | class="mt-4" |
... | ... | @@ -39,7 +54,7 @@ |
39 | 54 | :schema="schema" |
40 | 55 | /> |
41 | 56 | <template #appendFooter> |
42 | - <a-button @click="handleFalse"> 不通过</a-button> | |
57 | + <a-button v-if="!isApproved && role === ROLE.ADMIN" @click="handleFalse"> 不通过</a-button> | |
43 | 58 | </template> |
44 | 59 | </BasicModal> |
45 | 60 | <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> |
... | ... | @@ -84,29 +99,30 @@ |
84 | 99 | const id = ref(''); |
85 | 100 | |
86 | 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 | 106 | label: '生产科实际应付金额汇总', |
91 | 107 | }, |
92 | 108 | { |
93 | - field: 'all', | |
109 | + field: 'payedDate', | |
94 | 110 | label: '生产科付款日期', |
95 | 111 | }, |
96 | 112 | { |
97 | - field: 'deductAmount', | |
113 | + field: 'actualPayedDate', | |
98 | 114 | label: '实际付款日期', |
99 | 115 | }, |
100 | 116 | { |
101 | - field: 'productionDepartmentTotalPrice', | |
117 | + field: 'totalProductionAmount', | |
102 | 118 | label: '生产科总金额汇总', |
103 | 119 | }, |
104 | 120 | { |
105 | - field: 'actualPayedAmount', | |
121 | + field: 'totalActualPayedAmount', | |
106 | 122 | label: '实际付款金额汇总', |
107 | 123 | }, |
108 | 124 | { |
109 | - field: 'actualReceivableAmount', | |
125 | + field: 'deductAmount', | |
110 | 126 | label: '生产科扣款金额汇总', |
111 | 127 | }, |
112 | 128 | ]; |
... | ... | @@ -128,19 +144,31 @@ |
128 | 144 | width: 150, |
129 | 145 | customRender: (column) => { |
130 | 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 | 151 | title: '审核类型', |
137 | 152 | dataIndex: 'productionDepartment', |
138 | 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 | 164 | title: '生产科', |
142 | 165 | dataIndex: 'productionDepartment', |
143 | 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 | 232 | |
205 | 233 | async function handleDetail(data) { |
206 | 234 | openModal(true, { data }); |
207 | - mockData.value = data.fieldInfos.invoiceBillOrderDO; | |
208 | - console.log(mockData.value, 5656); | |
235 | + mockData.value = data.fieldInfos.checkBillOrderDO; | |
209 | 236 | id.value = data.id; |
210 | 237 | } |
211 | 238 | ... | ... |
src/views/project/approve/ProfitPanel.vue
src/views/project/approve/ReceivePanel.vue
... | ... | @@ -12,6 +12,7 @@ |
12 | 12 | </template> |
13 | 13 | <template v-if="column.key === 'action'"> |
14 | 14 | <TableAction |
15 | + v-if="!isApproved" | |
15 | 16 | :actions="[ |
16 | 17 | { |
17 | 18 | label: '编辑', |
... | ... | @@ -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 | 34 | </template> |
24 | 35 | </template> |
25 | 36 | </BasicTable> |
26 | 37 | <BasicModal |
27 | - :showFooter="!isApproved && role === ROLE.ADMIN" | |
38 | + :formFooter="!isApproved && role === ROLE.ADMIN" | |
28 | 39 | @register="registerModal" |
29 | 40 | title="申请信息" |
30 | 41 | okText="通过" |
31 | 42 | @ok="handleTrue" |
43 | + :showCancelBtn="!isApproved && role === ROLE.ADMIN" | |
44 | + :showOkBtn="!isApproved && role === ROLE.ADMIN" | |
32 | 45 | > |
33 | 46 | <Description |
34 | 47 | class="mt-4" |
... | ... | @@ -39,7 +52,7 @@ |
39 | 52 | :schema="schema" |
40 | 53 | /> |
41 | 54 | <template #appendFooter> |
42 | - <a-button @click="handleFalse"> 不通过</a-button> | |
55 | + <a-button v-if="!isApproved && role === ROLE.ADMIN" @click="handleFalse"> 不通过</a-button> | |
43 | 56 | </template> |
44 | 57 | </BasicModal> |
45 | 58 | <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> |
... | ... | @@ -90,7 +103,7 @@ |
90 | 103 | label: '实际收款金额汇总', |
91 | 104 | }, |
92 | 105 | { |
93 | - field: 'all', | |
106 | + field: 'totalCustomerAmount', | |
94 | 107 | label: '客户总价金额汇总', |
95 | 108 | }, |
96 | 109 | { |
... | ... | @@ -102,7 +115,7 @@ |
102 | 115 | label: '必须回款日期', |
103 | 116 | }, |
104 | 117 | { |
105 | - field: 'addr', | |
118 | + field: 'actualRefundDate', | |
106 | 119 | label: '实际回款日期', |
107 | 120 | }, |
108 | 121 | { |
... | ... | @@ -138,7 +151,7 @@ |
138 | 151 | width: 150, |
139 | 152 | customRender: (column) => { |
140 | 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 | 226 | async function handleDetail(data) { |
214 | 227 | openModal(true, { data }); |
215 | 228 | mockData.value = data.fieldInfos.invoiceBillOrderDO; |
216 | - console.log(mockData.value, 5656); | |
229 | + console.log(data, 5656777); | |
217 | 230 | id.value = data.id; |
218 | 231 | } |
219 | 232 | ... | ... |
src/views/project/config/CreateModal.vue
... | ... | @@ -58,16 +58,7 @@ |
58 | 58 | { |
59 | 59 | field: 'relationValue', |
60 | 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 | 62 | rules: [{ required: true }], |
72 | 63 | colProps: { |
73 | 64 | span: 24, |
... | ... | @@ -105,16 +96,7 @@ |
105 | 96 | settingName: '客户编码', |
106 | 97 | settingValue: values.settingValue, |
107 | 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 | 100 | relationName: '包装费用', |
119 | 101 | relationValue: values.relationValue, |
120 | 102 | }; | ... | ... |
src/views/project/config/TablePanel.vue
1 | 1 | <template> |
2 | 2 | <BasicTable @register="registerTable" :bordered="true"> |
3 | 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 | 11 | </template> |
6 | 12 | <template #bodyCell="{ column, record }"> |
7 | 13 | <template v-if="column.key === 'action'"> |
... | ... | @@ -9,6 +15,8 @@ |
9 | 15 | </template> |
10 | 16 | </template> |
11 | 17 | </BasicTable> |
18 | + <CostEdit @register="registerEdit" @success="handleModalSuccess" /> | |
19 | + <CostCreate @register="registerCostCreate" @modal-success="handleModalSuccess" /> | |
12 | 20 | <CreateModal |
13 | 21 | @register="createModalRegister" |
14 | 22 | @modal-success="handleModalSuccess" |
... | ... | @@ -21,6 +29,9 @@ |
21 | 29 | import { deleteConfig, getList, saveConfig } from '/@/api/sys/config'; |
22 | 30 | import { COLUMNS } from './data'; |
23 | 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 | 36 | const props = defineProps({ |
26 | 37 | searchInfo: { |
... | ... | @@ -31,6 +42,8 @@ |
31 | 42 | }, |
32 | 43 | }); |
33 | 44 | const [createModalRegister, { openModal }] = useModal(); |
45 | + const [registerCostCreate, { openModal: openCostCreateModal }] = useModal(); | |
46 | + const [registerEdit, { openDrawer: openDrawerEdit }] = useDrawer(); | |
34 | 47 | |
35 | 48 | const [registerTable, { reload }] = useTable({ |
36 | 49 | api: getList, |
... | ... | @@ -52,10 +65,27 @@ |
52 | 65 | function createActions(record: any): any[] { |
53 | 66 | if (!record.editable) { |
54 | 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 | 90 | ...(props.column !== 3 && { |
61 | 91 | label: '删除', |
... | ... | @@ -92,7 +122,21 @@ |
92 | 122 | handleCancel(record); |
93 | 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 | 140 | function handleEdit(record: any) { |
97 | 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 | 70 | title: '固定成本', |
71 | 71 | dataIndex: 'relationValue', |
72 | 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 | 79 | title: '提成比例', |
78 | 80 | dataIndex: 'relationValue', |
79 | 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 | 89 | dataIndex: 'relationValue', |
86 | 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 | 106 | 7: [ | ... | ... |
src/views/project/config/index.vue
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <TablePanel :searchInfo="{ relationCode: 'orderHodTime' }" :column="5" /> |
21 | 21 | </Tabs.TabPane> |
22 | 22 | <Tabs.TabPane key="6" tab="提成成本配置"> |
23 | - <TablePanel :searchInfo="{ relationCode: 'orderHodTime' }" :column="6" /> | |
23 | + <TablePanel :searchInfo="{ relationCode: 'costSettingItem' }" :column="6" /> | |
24 | 24 | </Tabs.TabPane> |
25 | 25 | <Tabs.TabPane key="7" tab="销售额配置"> |
26 | 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 | 2 | <div class="p-4"> |
3 | 3 | <BasicTable @register="registerTable"> |
4 | 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 | 11 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> |
7 | 12 | <TrackEdit @register="registerTrackEdit" @success="handleSuccess" /> |
8 | 13 | <CheckSum @register="registerCheckSum" /> |
9 | 14 | <InvoiceUpload @register="registerInvoiceUpload" @success="handleSuccess" /> |
10 | 15 | <CheckDetail @register="registerInvoiceDetail" /> |
16 | + <DeductShow @register="registerDeductShow" /> | |
11 | 17 | </template> |
12 | 18 | <template #bodyCell="{ column, record }"> |
13 | 19 | <template v-if="column.key === 'action'"> |
... | ... | @@ -39,6 +45,14 @@ |
39 | 45 | label: '删除', |
40 | 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 | 58 | </template> |
... | ... | @@ -55,6 +69,7 @@ |
55 | 69 | import InvoiceUpload from './InvoiceUpload.vue'; |
56 | 70 | import CheckDetail from './CheckDetail.vue'; |
57 | 71 | import CheckSum from './CheckSum.vue'; |
72 | + import DeductShow from './DeductShow.vue'; | |
58 | 73 | import { useDrawer } from '/@/components/Drawer'; |
59 | 74 | import { useModal } from '/@/components/Modal'; |
60 | 75 | import { getCheck, checkDelete, checkCommit, checkDetail } from '@/api/project/invoice'; |
... | ... | @@ -64,6 +79,7 @@ |
64 | 79 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); |
65 | 80 | const [registerTrackEdit, { openDrawer: openTrackEdit }] = useDrawer(); |
66 | 81 | const [registerInvoiceUpload, { openModal: openInvoiceUpload }] = useModal(); |
82 | + const [registerDeductShow, { openModal: openDeductShow }] = useModal(); | |
67 | 83 | const [registerInvoiceDetail, { openDrawer: openCheckDetail }] = useDrawer(); |
68 | 84 | const checkedKeys = ref<Array<string | number>>([]); |
69 | 85 | |
... | ... | @@ -209,7 +225,7 @@ |
209 | 225 | // console.log(selectedCustomCodes.value, 56561); |
210 | 226 | // console.log(checkedKeys.value, 56562); |
211 | 227 | // } |
212 | - | |
228 | + //选择算法:创建二维数组,使客户编码和生产科相同 | |
213 | 229 | type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] |
214 | 230 | type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] |
215 | 231 | |
... | ... | @@ -376,6 +392,14 @@ |
376 | 392 | reload(); |
377 | 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 | 403 | function handleDetail(record) { |
380 | 404 | openCheckDetail(true, { |
381 | 405 | data: record, | ... | ... |
src/views/project/finance/receive/index.vue
... | ... | @@ -2,7 +2,12 @@ |
2 | 2 | <div class="p-4"> |
3 | 3 | <BasicTable @register="registerTable"> |
4 | 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 | 11 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> |
7 | 12 | <InvoiceAnalysis @register="registerInvoiceAnalysis" /> |
8 | 13 | <TrackEdit @register="registerTrackEdit" @success="handleSuccess" /> | ... | ... |
src/views/project/order/CheckDetail.vue
1 | 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 | 40 | <a-button type="primary" @click="onGoFormDetail"> 返回编辑</a-button> |
40 | 41 | </template> --> |
41 | - </BasicDrawer> | |
42 | + </BasicDrawer> | |
43 | + <ApproveReason @register="approveReasonModalRegister" @success="handleCloseModal" /> | |
44 | + </div> | |
42 | 45 | </template> |
43 | 46 | <script lang="ts"> |
44 | 47 | import { computed, defineComponent, reactive, ref } from 'vue'; |
45 | 48 | import { BasicForm, useForm } from '/@/components/Form/index'; |
46 | 49 | import { orderAuth } from '/@/api/project/order'; |
47 | 50 | import { ROLE } from './type.d'; |
51 | + import { useModal } from '/@/components/Modal'; | |
52 | + import ApproveReason from './FormDetail/ApproveReason.vue'; | |
48 | 53 | |
49 | 54 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; |
50 | 55 | import { |
... | ... | @@ -79,7 +84,7 @@ |
79 | 84 | ); |
80 | 85 | |
81 | 86 | export default defineComponent({ |
82 | - components: { BasicDrawer, BasicForm }, | |
87 | + components: { BasicDrawer, BasicForm, ApproveReason }, | |
83 | 88 | props: { |
84 | 89 | onGoFormDetail: { |
85 | 90 | type: Function, |
... | ... | @@ -92,6 +97,7 @@ |
92 | 97 | const reportSchemas = getSchema(FIELDS_REPORT_INFO); |
93 | 98 | const inspecSchemas = getSchema(FIELDS_INSPECTION_INFO); |
94 | 99 | const trackSchemas = getSchema(FIELDS_TRACK_STAGE_INFO); |
100 | + const [approveReasonModalRegister, { openModal: openReasonModal }] = useModal(); | |
95 | 101 | const [registerForm, { getFieldsValue }] = useForm({ |
96 | 102 | labelWidth: 120, |
97 | 103 | schemas, |
... | ... | @@ -137,6 +143,9 @@ |
137 | 143 | Object.assign(lockFields, data.lockFields); |
138 | 144 | id.value = data.id; |
139 | 145 | }); |
146 | + function handleCloseModal() { | |
147 | + closeDrawer(); | |
148 | + } | |
140 | 149 | |
141 | 150 | const role = computed(() => { |
142 | 151 | return userStore.getUserInfo?.roleSmallVO?.code; |
... | ... | @@ -148,7 +157,6 @@ |
148 | 157 | const reportFieldValues = getReportFieldsValue(); |
149 | 158 | const inspectFieldValues = getInspectFieldsValue(); |
150 | 159 | const trackFieldValues = getTrackFieldsValue(); |
151 | - | |
152 | 160 | if (baseFieldValues) { |
153 | 161 | FIELDS_BASE_INFO.map( |
154 | 162 | ({ field }) => |
... | ... | @@ -156,14 +164,12 @@ |
156 | 164 | baseFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), |
157 | 165 | ); |
158 | 166 | } |
159 | - | |
160 | 167 | if (reportFieldValues) |
161 | 168 | FIELDS_REPORT_INFO.map( |
162 | 169 | ({ field }) => |
163 | 170 | (reportFieldValues[field] = |
164 | 171 | reportFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), |
165 | 172 | ); |
166 | - | |
167 | 173 | if (profitFieldValues) |
168 | 174 | FIELDS_PROFIT_INFO.map( |
169 | 175 | ({ field }) => |
... | ... | @@ -176,21 +182,18 @@ |
176 | 182 | (trackFieldValues[field] = |
177 | 183 | trackFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), |
178 | 184 | ); |
179 | - | |
180 | 185 | if (inspectFieldValues) |
181 | 186 | FIELDS_INSPECTION_INFO.map( |
182 | 187 | ({ field }) => |
183 | 188 | (inspectFieldValues[field] = |
184 | 189 | inspectFieldValues[field] === 'UN_LOCKED' ? 'UN_LOCKED' : 'LOCKED'), |
185 | 190 | ); |
186 | - | |
187 | 191 | // !isEmpty(baseFieldValues) && |
188 | 192 | // Object.keys(baseFieldValues.baseFields)?.map((key) => { |
189 | 193 | // baseFieldValues.baseFields[key] = baseFieldValues.baseFields[key] |
190 | 194 | // ? 'UN_LOCKED' |
191 | 195 | // : 'LOCKED'; |
192 | 196 | // }); |
193 | - | |
194 | 197 | // !isEmpty(profitFieldValues) && |
195 | 198 | // Object.keys(profitFieldValues.profitAnalysisFields).map((key) => { |
196 | 199 | // profitFieldValues.profitAnalysisFields[key] = profitFieldValues.profitAnalysisFields[ |
... | ... | @@ -199,14 +202,12 @@ |
199 | 202 | // ? 'UN_LOCKED' |
200 | 203 | // : 'LOCKED'; |
201 | 204 | // }); |
202 | - | |
203 | 205 | // !isEmpty(reportFieldValues) && |
204 | 206 | // Object.keys(reportFieldValues.reportFields).map((key) => { |
205 | 207 | // reportFieldValues.reportFields[key] = reportFieldValues.reportFields[key] |
206 | 208 | // ? 'UN_LOCKED' |
207 | 209 | // : 'LOCKED'; |
208 | 210 | // }); |
209 | - | |
210 | 211 | const values = Object.assign( |
211 | 212 | { orderId: id.value }, |
212 | 213 | { baseFields: baseFieldValues }, |
... | ... | @@ -215,9 +216,25 @@ |
215 | 216 | { trackStageFields: trackFieldValues }, |
216 | 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 | 238 | return { |
222 | 239 | register, |
223 | 240 | schemas, |
... | ... | @@ -227,9 +244,17 @@ |
227 | 244 | registryInspectForm, |
228 | 245 | registerTrackForm, |
229 | 246 | handleSubmit, |
247 | + handleCloseModal, | |
248 | + approveReasonModalRegister, | |
230 | 249 | ROLE, |
231 | 250 | role, |
232 | 251 | }; |
233 | 252 | }, |
234 | 253 | }); |
235 | 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 | 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 | 96 | if (props.role === ROLE.TRACKER) { |
88 | 97 | return [ |
89 | 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 | 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 | 233 | // const businessNotDisabledFields = ['customerCode', 'projectNo', 'innerNo']; |
234 | 234 | // const trackerNotDisabledFields = [ |
235 | 235 | // 'customerPo', |
... | ... | @@ -254,7 +254,9 @@ |
254 | 254 | field: `${item.field}`, |
255 | 255 | componentProps: { |
256 | 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 | 260 | // disabled: |
259 | 261 | // role.value === ROLE.BUSINESS |
260 | 262 | // ? !isFieldNotDisabledForBusiness | ... | ... |
src/views/project/order/ProductProfit.vue
... | ... | @@ -121,6 +121,7 @@ |
121 | 121 | import { payDate, checkCreate } from '@/api/project/invoice'; |
122 | 122 | import type { Dayjs } from 'dayjs'; |
123 | 123 | import { calculateInnerProfitRatio, exportInnerProfitRatio } from '@/api/project/order'; |
124 | + import axios from 'axios'; | |
124 | 125 | |
125 | 126 | const Input1 = ref(''); |
126 | 127 | const Input2 = ref(); |
... | ... | @@ -153,6 +154,50 @@ |
153 | 154 | filteredItems.value = data.filteredItems; |
154 | 155 | }); |
155 | 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 | 201 | closeModal(); |
157 | 202 | } |
158 | 203 | function handleShow(visible: boolean) { | ... | ... |
src/views/project/order/ProductText.vue
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | v-bind="$attrs" |
4 | 4 | destroyOnClose |
5 | 5 | @register="register" |
6 | - title="生产指标书" | |
6 | + title="生产指示书" | |
7 | 7 | width="500px" |
8 | 8 | :height="80" |
9 | 9 | wrapClassName="h-[340px]" |
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | v-bind="$attrs" |
15 | 15 | destroyOnClose |
16 | 16 | @register="register" |
17 | - title="生产指标书" | |
17 | + title="生产指示书" | |
18 | 18 | width="500px" |
19 | 19 | @visible-change="handleShow" |
20 | 20 | :footer="null" |
... | ... | @@ -27,7 +27,7 @@ |
27 | 27 | <div class="showPdf" v-if="isShow2 == true" style="margin-top: 35px; text-align: center"> |
28 | 28 | <!-- <img src="/pdf.png" /> --> |
29 | 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 | 31 | <EyeOutlined :style="{ fontSize: '20px' }" class="EyeOutlined" @click="handlePdf" /> |
32 | 32 | </div> |
33 | 33 | <div class="bottom"> |
... | ... | @@ -83,7 +83,7 @@ |
83 | 83 | // 运营总监-基本信息,跟单,质检 |
84 | 84 | return [ |
85 | 85 | { label: '青岛翱特逸格饰品有限公司', value: '青岛翱特逸格饰品有限公司' }, |
86 | - { label: ' 青岛吉庆天成饰品有限公司', value: '青岛吉庆天成饰品有限公司' }, | |
86 | + { label: '青岛吉庆天成饰品有限公司', value: '青岛吉庆天成饰品有限公司' }, | |
87 | 87 | ]; |
88 | 88 | }); |
89 | 89 | const { createMessage } = useMessage(); |
... | ... | @@ -173,17 +173,18 @@ |
173 | 173 | } |
174 | 174 | //查看pdf |
175 | 175 | function handlePdf() { |
176 | - window.open(resText.value.produceFile); | |
176 | + window.open(resText.value.productionUrl); | |
177 | 177 | } |
178 | 178 | //发送按钮 |
179 | 179 | async function handleExport() { |
180 | 180 | const res = await exportProductText({ |
181 | 181 | productionUrl: resText.value.productionUrl, |
182 | 182 | productionDepartment: resText.value.productionDepartment, |
183 | + personList: resText.value.personList, | |
183 | 184 | isSend: true, |
184 | 185 | }); |
185 | 186 | console.log(); |
186 | - success('操作成功,' + res); | |
187 | + success('操作成功,已发送给生产科、业务员、跟单员'); | |
187 | 188 | closeModal(); |
188 | 189 | } |
189 | 190 | return { | ... | ... |
src/views/project/order/ServiceProfit.vue
... | ... | @@ -49,18 +49,20 @@ |
49 | 49 | <tr> |
50 | 50 | <td style="border: 1px solid black"></td> |
51 | 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 | 56 | </tr> |
57 | 57 | <tr> |
58 | 58 | <td style="border: 1px solid black"></td> |
59 | 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 | 65 | /></td> |
63 | - <td style="border: 1px solid black"><a-date-picker v-model:value="produceEndTime" /></td> | |
64 | 66 | </tr> |
65 | 67 | <tr> |
66 | 68 | <td style="border: 1px solid black">客户编码</td> |
... | ... | @@ -70,17 +72,17 @@ |
70 | 72 | </tr> |
71 | 73 | <tr> |
72 | 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 | 76 | <td style="border: 1px solid black"></td> |
75 | 77 | </tr> |
76 | 78 | <tr> |
77 | 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 | 81 | <td style="border: 1px solid black"></td> |
80 | 82 | </tr> |
81 | 83 | <tr> |
82 | 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 | 86 | <td style="border: 1px solid black"></td> |
85 | 87 | </tr> |
86 | 88 | <tr> |
... | ... | @@ -99,37 +101,37 @@ |
99 | 101 | </tr> |
100 | 102 | <tr> |
101 | 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 | 105 | <td style="border: 1px solid black"></td> |
104 | 106 | </tr> |
105 | 107 | <tr> |
106 | 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 | 110 | <td style="border: 1px solid black"></td> |
109 | 111 | </tr> |
110 | 112 | <tr> |
111 | 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 | 115 | <td style="border: 1px solid black"></td> |
114 | 116 | </tr> |
115 | 117 | <tr> |
116 | 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 | 120 | <td style="border: 1px solid black"></td> |
119 | 121 | </tr> |
120 | 122 | <tr> |
121 | 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 | 125 | <td style="border: 1px solid black"></td> |
124 | 126 | </tr> |
125 | 127 | <tr> |
126 | 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 | 130 | <td style="border: 1px solid black"></td> |
129 | 131 | </tr> |
130 | 132 | <tr> |
131 | 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 | 135 | <td style="border: 1px solid black"></td> |
134 | 136 | </tr> |
135 | 137 | <tr> |
... | ... | @@ -141,32 +143,32 @@ |
141 | 143 | </tr> |
142 | 144 | <tr> |
143 | 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 | 147 | <td style="border: 1px solid black"></td> |
146 | 148 | </tr> |
147 | 149 | <tr> |
148 | 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 | 152 | <td style="border: 1px solid black"></td> |
151 | 153 | </tr> |
152 | 154 | <tr> |
153 | 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 | 157 | <td style="border: 1px solid black"></td> |
156 | 158 | </tr> |
157 | 159 | <tr> |
158 | 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 | 162 | <td style="border: 1px solid black"></td> |
161 | 163 | </tr> |
162 | 164 | <tr> |
163 | 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 | 167 | <td style="border: 1px solid black"></td> |
166 | 168 | </tr> |
167 | 169 | <tr> |
168 | 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 | 172 | <td style="border: 1px solid black"></td> |
171 | 173 | </tr> |
172 | 174 | </tbody> |
... | ... | @@ -178,7 +180,9 @@ |
178 | 180 | import { computed, ref, toRaw } from 'vue'; |
179 | 181 | // import { payDate, checkCreate } from '@/api/project/invoice'; |
180 | 182 | import { calculateBusinessProfit, exportBusinessProfit } from '@/api/project/order'; |
183 | + import { getList } from '/@/api/sys/config'; | |
181 | 184 | import type { Dayjs } from 'dayjs'; |
185 | + import axios from 'axios'; | |
182 | 186 | |
183 | 187 | const projectStartTime = ref(); |
184 | 188 | const projectEndTime = ref(); |
... | ... | @@ -195,11 +199,14 @@ |
195 | 199 | const developTotalPrice = ref(); |
196 | 200 | const copyTotalPrice = ref(); |
197 | 201 | const packetActualTotalPrice = ref(); |
198 | - const spainRatio = ref(); | |
199 | - const chinaRatio = ref(); | |
202 | + const spainRatio = ref(0); | |
203 | + const chinaRatio = ref(0); | |
200 | 204 | const actualRmbPrice = ref(0); //实际跟单单价 |
201 | 205 | const actualPrice = ref(0); //实际跟单单价折算美金 |
202 | 206 | const actualRatio = ref(6.2); //实际汇率 |
207 | + const customerTotalPrice = ref(); //客户总价合计 | |
208 | + const actualRatioProfitPrice = ref(); //汇率收益 | |
209 | + const grossProfit = ref(); //毛利润合计 | |
203 | 210 | const actualRatiactualRatioProfitPriceo = ref(); //汇率收益计算 |
204 | 211 | const chinaRatioProfitPrice = ref(); //中国团队提成比例 |
205 | 212 | const developProfit = ref(); //研发贸易利润 |
... | ... | @@ -222,6 +229,58 @@ |
222 | 229 | console.log(orderList.value, 565656); |
223 | 230 | }); |
224 | 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 | 284 | closeModal(); |
226 | 285 | } |
227 | 286 | function handleShow(visible: boolean) { |
... | ... | @@ -237,6 +296,25 @@ |
237 | 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 | 318 | async function handleCalculate() { |
241 | 319 | const packetCalculatePrice = ref(0); |
242 | 320 | const orderCalculateCount = ref(0); |
... | ... | @@ -250,8 +328,32 @@ |
250 | 328 | actualRmbPrice.value += packetCalculatePrice.value / orderCalculateCount.value; |
251 | 329 | }); |
252 | 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 | 357 | const res = await calculateBusinessProfit({ |
256 | 358 | customerCode: customerCode.value, |
257 | 359 | projectNo: projectNo.value, |
... | ... | @@ -270,20 +372,23 @@ |
270 | 372 | }); |
271 | 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 | 393 | </script> |
289 | 394 | <style scoped> | ... | ... |
src/views/project/order/index.vue
... | ... | @@ -23,7 +23,7 @@ |
23 | 23 | <a-button |
24 | 24 | :style="{ borderRadius: '5px 5px 5px 5px' }" |
25 | 25 | type="link" |
26 | - @click="checkedKeys = []" | |
26 | + @click="handleClearChoose" | |
27 | 27 | size="small" |
28 | 28 | >清空</a-button |
29 | 29 | > |
... | ... | @@ -38,7 +38,7 @@ |
38 | 38 | <template v-if="column.key === 'action'"> |
39 | 39 | <TableAction |
40 | 40 | :actions=" |
41 | - role !== ROLE.PRODUCE | |
41 | + role !== ROLE.PRODUCE && role !== ROLE.FINANCE | |
42 | 42 | ? [ |
43 | 43 | { |
44 | 44 | // 数据分析没有编辑权限 |
... | ... | @@ -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 | 84 | label: '复制', |
83 | 85 | // icon: 'ic:outline-delete-outline', |
84 | 86 | onClick: handleCopy.bind(null, record), |
... | ... | @@ -111,93 +113,100 @@ |
111 | 113 | </template> |
112 | 114 | |
113 | 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 | 210 | </template> |
202 | 211 | </BasicTable> |
203 | 212 | <FormDetail |
... | ... | @@ -368,13 +377,20 @@ |
368 | 377 | |
369 | 378 | // type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] |
370 | 379 | // type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] |
380 | + // type ProjectNoEntry = [string, number]; // 定义二维数组类型 [innerNo, count] | |
371 | 381 | |
372 | 382 | // const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref |
373 | 383 | // const selectedProductionDepartment = ref<ProductionDepartmentEntry[]>([]); // 创建一个二维数组的 ref |
384 | + // const selectedProjectNos = ref<ProjectNoEntry[]>([]); // 创建一个二维数组的 ref | |
374 | 385 | |
375 | 386 | // // 单选处理函数 |
376 | 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 | 394 | // selected: boolean, |
379 | 395 | // ) { |
380 | 396 | // // 查找 customerCode 在 selectedCustomCodes 中的位置 |
... | ... | @@ -387,6 +403,11 @@ |
387 | 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 | 411 | // if (selected) { |
391 | 412 | // // 添加到 checkedKeys |
392 | 413 | // checkedKeys.value = [...checkedKeys.value, record.id]; |
... | ... | @@ -408,6 +429,15 @@ |
408 | 429 | // // 如果不存在,添加新项 [productionDepartment, 1] |
409 | 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 | 441 | // } else { |
412 | 442 | // // 从 checkedKeys 中移除 |
413 | 443 | // checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); |
... | ... | @@ -429,19 +459,127 @@ |
429 | 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 | 568 | // console.log('5656Checked Keys:', checkedKeys.value); |
435 | 569 | // console.log('5656Selected Customer Codes:', selectedCustomCodes.value); |
436 | 570 | // console.log('5656Selected Production Departments:', selectedProductionDepartment.value); |
571 | + // console.log('5656Selected projectNos:', selectedProjectNos.value); | |
437 | 572 | // } |
573 | + | |
438 | 574 | type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count] |
439 | 575 | type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count] |
440 | 576 | type ProjectNoEntry = [string, number]; // 定义二维数组类型 [innerNo, count] |
577 | + type BusinessPersonEntry = [string, number]; // 定义二维数组类型 [businessPerson, count] | |
441 | 578 | |
442 | 579 | const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref |
443 | 580 | const selectedProductionDepartment = ref<ProductionDepartmentEntry[]>([]); // 创建一个二维数组的 ref |
444 | 581 | const selectedProjectNos = ref<ProjectNoEntry[]>([]); // 创建一个二维数组的 ref |
582 | + const selectedBusinessPersons = ref<BusinessPersonEntry[]>([]); // 创建一个二维数组的 ref | |
445 | 583 | |
446 | 584 | // 单选处理函数 |
447 | 585 | function onSelect( |
... | ... | @@ -449,57 +587,58 @@ |
449 | 587 | customerCode: string; |
450 | 588 | productionDepartment: string; |
451 | 589 | projectNo: string; |
590 | + businessPerson: string; // 添加 businessPerson 属性 | |
452 | 591 | id: string; |
453 | 592 | }, |
454 | 593 | selected: boolean, |
455 | 594 | ) { |
456 | - // 查找 customerCode 在 selectedCustomCodes 中的位置 | |
457 | 595 | const customerCodeIndex = selectedCustomCodes.value.findIndex( |
458 | 596 | ([customerCode]) => customerCode === record.customerCode, |
459 | 597 | ); |
460 | 598 | |
461 | - // 查找 productionDepartment 在 selectedProductionDepartment 中的位置 | |
462 | 599 | const productionDepartmentIndex = selectedProductionDepartment.value.findIndex( |
463 | 600 | ([department]) => department === record.productionDepartment, |
464 | 601 | ); |
465 | 602 | |
466 | - // 查找 projectNo 在 selectedProjectNos 中的位置 | |
467 | 603 | const projectNoIndex = selectedProjectNos.value.findIndex( |
468 | 604 | ([projectNo]) => projectNo === record.projectNo, |
469 | 605 | ); |
470 | 606 | |
607 | + const businessPersonIndex = selectedBusinessPersons.value.findIndex( | |
608 | + ([businessPerson]) => businessPerson === record.businessPerson, | |
609 | + ); | |
610 | + | |
471 | 611 | if (selected) { |
472 | - // 添加到 checkedKeys | |
473 | 612 | checkedKeys.value = [...checkedKeys.value, record.id]; |
474 | 613 | |
475 | 614 | // 更新 selectedCustomCodes |
476 | 615 | if (customerCodeIndex !== -1) { |
477 | - // 如果已存在,增加计数 | |
478 | 616 | selectedCustomCodes.value[customerCodeIndex][1] += 1; |
479 | 617 | } else { |
480 | - // 如果不存在,添加新项 [customerCode, 1] | |
481 | 618 | selectedCustomCodes.value.push([record.customerCode, 1]); |
482 | 619 | } |
483 | 620 | |
484 | 621 | // 更新 selectedProductionDepartment |
485 | 622 | if (productionDepartmentIndex !== -1) { |
486 | - // 如果已存在,增加计数 | |
487 | 623 | selectedProductionDepartment.value[productionDepartmentIndex][1] += 1; |
488 | 624 | } else { |
489 | - // 如果不存在,添加新项 [productionDepartment, 1] | |
490 | 625 | selectedProductionDepartment.value.push([record.productionDepartment, 1]); |
491 | 626 | } |
492 | 627 | |
493 | 628 | // 更新 selectedProjectNos |
494 | 629 | if (projectNoIndex !== -1) { |
495 | - // 如果已存在,增加计数 | |
496 | 630 | selectedProjectNos.value[projectNoIndex][1] += 1; |
497 | 631 | } else { |
498 | - // 如果不存在,添加新项 [projectNo, 1] | |
499 | 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 | 641 | } else { |
502 | - // 从 checkedKeys 中移除 | |
503 | 642 | checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); |
504 | 643 | |
505 | 644 | // 更新 selectedCustomCodes |
... | ... | @@ -528,94 +667,33 @@ |
528 | 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 | 689 | function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) { |
612 | 690 | const changeIds = changeRows.map((item) => item.id); |
613 | 691 | const changeCustomerCodes = changeRows.map((item) => item.customerCode); |
614 | 692 | const changeProductionDepartments = changeRows.map((item) => item.productionDepartment); |
615 | 693 | const changeProjectNos = changeRows.map((item) => item.projectNo); |
694 | + const changeBusinessPersons = changeRows.map((item) => item.businessPerson); // 新增处理 businessPerson | |
616 | 695 | |
617 | 696 | if (selected) { |
618 | - // 添加到 checkedKeys | |
619 | 697 | checkedKeys.value = [...checkedKeys.value, ...changeIds]; |
620 | 698 | |
621 | 699 | // 更新 selectedCustomCodes |
... | ... | @@ -651,8 +729,17 @@ |
651 | 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 | 742 | } else { |
655 | - // 从 checkedKeys 中移除 | |
656 | 743 | checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id)); |
657 | 744 | |
658 | 745 | // 更新 selectedCustomCodes |
... | ... | @@ -684,7 +771,7 @@ |
684 | 771 | }); |
685 | 772 | |
686 | 773 | // 更新 selectedProjectNos |
687 | - changeInnerNos.forEach((projectNo) => { | |
774 | + changeProjectNos.forEach((projectNo) => { | |
688 | 775 | const index = selectedProjectNos.value.findIndex(([no]) => no === projectNo); |
689 | 776 | if (index !== -1) { |
690 | 777 | if (selectedProjectNos.value[index][1] > 1) { |
... | ... | @@ -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 | 813 | function handleEdit(record, e) { |
... | ... | @@ -820,10 +928,18 @@ |
820 | 928 | const form = getForm(); |
821 | 929 | const values = form.getFieldsValue(); |
822 | 930 | console.log(selectedCustomCodes.value, 5656); |
823 | - if (selectedCustomCodes.value.length == 0) { | |
931 | + if (checkedKeys.value.length == 0) { | |
824 | 932 | error('请选择订单'); |
825 | 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 | 943 | openProductModal(true, { |
828 | 944 | checkedKeys: checkedKeys.value, |
829 | 945 | customers: selectedCustomCodes.value, |
... | ... | @@ -980,6 +1096,7 @@ |
980 | 1096 | handleDelete, |
981 | 1097 | handleServiceProfitModal, |
982 | 1098 | handleProductProfitModal, |
1099 | + handleClearChoose, | |
983 | 1100 | selectedCustomCodes, |
984 | 1101 | role, |
985 | 1102 | ROLE, | ... | ... |
src/views/project/order/tableData.tsx
... | ... | @@ -161,9 +161,21 @@ export const ORDER_LIST_BASE_FIELDS = [ |
161 | 161 | { |
162 | 162 | field: 'returnOrder', |
163 | 163 | component: 'Select', |
164 | - default: '请选择', | |
165 | - label: '是否返单 ', | |
164 | + labelWidth: 150, | |
165 | + label: '是否返单', | |
166 | 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 | 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 | 719 | if (role === ROLE.BUSINESS) { |
697 | 720 | return [ | ... | ... |
vite.config.ts
... | ... | @@ -20,7 +20,7 @@ export default defineApplicationConfig({ |
20 | 20 | server: { |
21 | 21 | proxy: { |
22 | 22 | '/basic-api/order': { |
23 | - target: 'http://47.104.8.35:18000', | |
23 | + target: 'http://47.104.8.35:18001', | |
24 | 24 | // target: 'http://localhost:8001', |
25 | 25 | // target: 'http://39.108.227.113:8000', |
26 | 26 | // target: 'http://localhost:8000', |
... | ... | @@ -31,7 +31,7 @@ export default defineApplicationConfig({ |
31 | 31 | rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), |
32 | 32 | }, |
33 | 33 | '/api/localStorage/upload': { |
34 | - target: 'http://47.104.8.35:18000', | |
34 | + target: 'http://47.104.8.35:18001', | |
35 | 35 | // target: 'http://localhost:8001', |
36 | 36 | // target: 'http://39.108.227.113:8000', |
37 | 37 | // target: '192.168.31.250:18000', | ... | ... |