Blame view

src/views/project/order/ServiceProfit.vue 19.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- <template>
  <BasicModal
    v-bind="$attrs"
    @register="register"
    title="生产对账单"
    width="60%"
    :bodyStyle="{ height: '500px' }"
    @ok="handleOk"
  >
  </BasicModal>
</template> -->
<template>
  <BasicModal
    v-bind="$attrs"
    @register="register"
    title="净利润分析表"
    width="60%"
    :bodyStyle="{ height: '455px' }"
柏杨 authored
19
    @visible-change="handleShow"
20
21
22
23
    @ok="handleOk"
    okText="导出"
  >
    <template #appendFooter>
柏杨 authored
24
25
26
      <a-button style="background-color: #1890ff; color: white" @click="handleCalculate"
        >计算</a-button
      >
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    </template>
    <table
      style="
        width: 100%;
        border-collapse: collapse;
        text-align: center;
        border: 1px solid black;
        font-size: 16px;
      "
    >
      <thead>
        <!-- <tr>
          <th colspan="4" style="border: 1px solid black">净利润分析表</th>
        </tr> -->
      </thead>
      <tbody>
        <tr>
          <td style="border: 1px solid black; width: 25%">项目号</td>
柏杨 authored
45
          <td style="border: 1px solid black; width: 25%">{{ projectNo }}</td>
46
47
48
49
50
51
          <td style="border: 1px solid black; width: 25%">开始时间</td>
          <td style="border: 1px solid black; width: 25%">结束时间</td>
        </tr>
        <tr>
          <td style="border: 1px solid black"></td>
          <td style="border: 1px solid black">项目开始时间</td>
52
53
54
55
          <td style="border: 1px solid black">
            <input type="date" v-model="projectStartTime" style="width: 100%" />
          </td>
          <input type="date" v-model="projectEndTime" style="width: 100%" />
56
57
58
59
        </tr>
        <tr>
          <td style="border: 1px solid black"></td>
          <td style="border: 1px solid black">生产进行时间</td>
60
61
62
63
64
          <td style="border: 1px solid black">
            <input type="date" v-model="produceStartTime" style="width: 100%" />
          </td>
          <td style="border: 1px solid black">
            <input type="date" v-model="produceEndTime" style="width: 100%"
柏杨 authored
65
          /></td>
66
67
68
        </tr>
        <tr>
          <td style="border: 1px solid black">客户编码</td>
柏杨 authored
69
          <td style="border: 1px solid black">{{ customerCode }}</td>
70
71
72
73
74
          <td style="border: 1px solid black"></td>
          <td style="border: 1px solid black">备注</td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">客户总金额合计</td>
柏杨 authored
75
          <td style="border: 1px solid black">¥{{ customerTotalPrice }}</td>
柏杨 authored
76
          <td style="border: 1px solid black">${{ customerTotalPriceUsd }}</td>
77
78
79
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">生产科总价合计</td>
柏杨 authored
80
          <td style="border: 1px solid black">¥{{ productionDepartmentTotalPrice }}</td>
柏杨 authored
81
          <td style="border: 1px solid black">${{ productionDepartmentTotalPriceUsd }}</td>
82
83
84
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">包装费用合计</td>
柏杨 authored
85
          <td style="border: 1px solid black">¥{{ packetTotalPrice }}</td>
柏杨 authored
86
          <td style="border: 1px solid black">${{ packetTotalPriceUsd }}</td>
87
88
89
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">研发开发费合计</td>
柏杨 authored
90
          <td style="border: 1px solid black"
柏杨 authored
91
            ><a-input v-model:value="developTotalPrice" placeholder="请输入"
柏杨 authored
92
          /></td>
93
94
95
96
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">复制费用合计</td>
柏杨 authored
97
98
99
          <td style="border: 1px solid black"
            ><a-input v-model:value="copyTotalPrice" placeholder="请输入"
          /></td>
100
101
102
103
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">固定成本</td>
柏杨 authored
104
          <td style="border: 1px solid black">¥{{ fixCost }}</td>
105
106
107
108
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">西班牙提成</td>
柏杨 authored
109
          <td style="border: 1px solid black">¥{{ spainRatioProfitPrice }}</td>
110
111
112
113
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">中国团队提成</td>
柏杨 authored
114
          <td style="border: 1px solid black">¥{{ chinaRatioProfitPrice }}</td>
115
116
117
118
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">支出合计</td>
柏杨 authored
119
          <td style="border: 1px solid black">¥{{ outTotalPrice }}</td>
120
121
122
123
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">毛利润</td>
柏杨 authored
124
          <td style="border: 1px solid black">¥{{ grossProfit }}</td>
125
126
127
128
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">研发贸易净利润</td>
柏杨 authored
129
          <td style="border: 1px solid black">¥{{ developProfit }}</td>
130
131
132
133
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">包装费用合计金额</td>
柏杨 authored
134
          <td style="border: 1px solid black">¥{{ packetTotalPrice }}</td>
135
136
137
138
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">包装费用实际金额</td>
柏杨 authored
139
140
141
          <td style="border: 1px solid black"
            ><a-input v-model:value="packetActualTotalPrice" placeholder="请输入"
          /></td>
142
143
144
145
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">订单总数量</td>
146
          <td style="border: 1px solid black">{{ orderCount }}</td>
147
148
          <td style="border: 1px solid black"></td>
        </tr>
柏杨 authored
149
        <!-- <tr>
柏杨 authored
150
151
152
153
154
          <td style="border: 1px solid black" colspan="2">实际跟单费用</td>
          <td style="border: 1px solid black"
            ><a-input v-model:value="actualdocumentaryPrice" placeholder="请输入"
          /></td>
          <td style="border: 1px solid black"></td>
柏杨 authored
155
        </tr> -->
柏杨 authored
156
        <tr>
157
          <td style="border: 1px solid black" colspan="2">实际跟单单价=实际跟单费用/件数</td>
柏杨 authored
158
          <td style="border: 1px solid black">¥{{ actualRmbPrice }}</td>
159
160
161
162
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">实际跟单单价折算美金</td>
柏杨 authored
163
          <td style="border: 1px solid black">${{ actualPrice }}</td>
164
165
166
167
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">包装费用收益</td>
柏杨 authored
168
          <td style="border: 1px solid black">¥{{ packetProfitPrice }}</td>
169
170
171
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
柏杨 authored
172
173
174
175
176
177
178
          <td style="border: 1px solid black" colspan="2">实际汇率</td>
          <td style="border: 1px solid black"
            ><a-input v-model:value="actualRatio" placeholder="请输入"
          /></td>
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
179
          <td style="border: 1px solid black" colspan="2">汇率收益</td>
柏杨 authored
180
          <td style="border: 1px solid black">¥{{ actualRatioProfitPrice }}</td>
181
182
183
184
          <td style="border: 1px solid black"></td>
        </tr>
        <tr>
          <td style="border: 1px solid black" colspan="2">综合收益</td>
柏杨 authored
185
          <td style="border: 1px solid black">¥{{ totalProfitPrice }}</td>
186
187
188
189
190
191
192
193
          <td style="border: 1px solid black"></td>
        </tr>
      </tbody>
    </table>
  </BasicModal>
</template>
<script lang="ts" setup>
  import { BasicModal, useModalInner } from '@/components/Modal';
柏杨 authored
194
195
196
  import { computed, ref, toRaw } from 'vue';
  // import { payDate, checkCreate } from '@/api/project/invoice';
  import { calculateBusinessProfit, exportBusinessProfit } from '@/api/project/order';
197
  import { getList } from '/@/api/sys/config';
柏杨 authored
198
  import type { Dayjs } from 'dayjs';
199
  import axios from 'axios';
200
柏杨 authored
201
202
203
204
205
206
  const projectStartTime = ref();
  const projectEndTime = ref();
  const produceStartTime = ref();
  const produceEndTime = ref();

  const testinput = ref();
207
208
209
  const Input1 = ref('');
  const Input2 = ref();
  const res = ref();
柏杨 authored
210
211
212
  const orderList = ref();
  const customerCode = ref();
  const projectNo = ref();
柏杨 authored
213
214
215
  const developTotalPrice = ref();
  const copyTotalPrice = ref();
  const packetActualTotalPrice = ref();
216
217
  const spainRatio = ref(0);
  const chinaRatio = ref(0);
柏杨 authored
218
219
  const actualRmbPrice = ref(0); //实际跟单单价
  const actualPrice = ref(0); //实际跟单单价折算美金
柏杨 authored
220
  const actualRatio = ref(); //实际汇率
柏杨 authored
221
222
223
224
  const customerTotalPrice = ref(0); //客户总价合计
  const actualdocumentaryPrice = ref(0); //实际跟单费用
  const actualRatioProfitPrice = ref(0); //汇率收益
  const grossProfit = ref(0); //毛利润合计
柏杨 authored
225
226
  const customerTotalPriceUsd = ref(0); //客户总价$
  const productionDepartmentTotalPriceUsd = ref(0); //生产科总价$
柏杨 authored
227
  const actualRatiactualRatioProfitPriceo = ref(0); //汇率收益计算
柏杨 authored
228
  const packetTotalPriceUsd = ref(0); //汇率收益计算
柏杨 authored
229
230
231
  const chinaRatioProfitPrice = ref(0); //中国团队提成比例
  const developProfit = ref(0); //研发贸易利润
  const fixCost = ref(0); // 固定成本
柏杨 authored
232
  const orderCount = ref(0); //订单总数量
柏杨 authored
233
234
235
236
237
238
  const outTotalPrice = ref(0); //支出合计计
  const packetProfitPrice = ref(0); //包装费用收益计算
  const packetTotalPrice = ref(0); //包装费用合计¥
  const productionDepartmentTotalPrice = ref(0); //生成科总价¥
  const totalProfitPrice = ref(0); //综合收益计算
  const spainRatioProfitPrice = ref(0); //西班牙提成金额
柏杨 authored
239
  const ids = ref();
柏杨 authored
240
241

  // const orderRes = await getOrderList({});
242
243
  const [register, { closeModal }] = useModalInner(async (data) => {
    res.value = data.data;
柏杨 authored
244
    orderList.value = data.res;
柏杨 authored
245
246
247
    orderList.value.forEach((item) => {
      orderCount.value += item.orderCount;
    });
柏杨 authored
248
    customerCode.value = data.customerCode[0][0];
柏杨 authored
249
250
    ids.value = data.data;
    const extractedValues = ref<string[]>(data.projectNo.map((item) => item[0]));
柏杨 authored
251
    projectNo.value = extractedValues.value.join(',');
252
253
  });
  async function handleOk() {
254
255
256
257
258
259
    axios
      .post(
        '/basic-api/order/erp/calculate_profit/business_profit_ratio_export',
        {
          customerCode: customerCode.value,
          projectNo: projectNo.value,
柏杨 authored
260
          ids: ids.value,
261
262
263
264
265
          projectStartTime: projectStartTime.value,
          projectEndTime: projectEndTime.value,
          produceStartTime: produceStartTime.value,
          produceEndTime: produceEndTime.value,
          developTotalPrice: developTotalPrice.value,
柏杨 authored
266
          // actualdocumentaryPrice: actualdocumentaryPrice.value,
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
          copyTotalPrice: copyTotalPrice.value,
          spainRatio: spainRatio.value,
          chinaRatio: chinaRatio.value,
          packetActualTotalPrice: packetActualTotalPrice.value,
          actualRmbPrice: actualRmbPrice.value,
          actualPrice: actualPrice.value,
          actualRatio: actualRatio.value,
        },
        {
          responseType: 'blob', // 设置响应类型为 'blob'
        },
      )
      .then((response) => {
        // 创建一个 Blob 对象来保存二进制数据
        const blob = new Blob([response.data], { type: 'application/octet-stream' });
        const getFormattedDate = (): string => {
          const date = new Date();

          const year = date.getFullYear();
          const month = String(date.getMonth() + 1).padStart(2, '0');
          const day = String(date.getDate()).padStart(2, '0');

          const hours = String(date.getHours()).padStart(2, '0');
          const minutes = String(date.getMinutes()).padStart(2, '0');
          const seconds = String(date.getSeconds()).padStart(2, '0');

          return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
        };
        const date = getFormattedDate();
        // 创建一个链接元素用于下载
        const link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
柏杨 authored
299
        link.download = `业务/研发净利润分析${date}.xlsx`; // 你可以为文件命名
300
301
302
303
304
305
306
        document.body.appendChild(link);
        link.click(); // 自动点击链接,触发下载
        document.body.removeChild(link); // 下载完成后移除链接
      })
      .catch((error) => {
        console.error(error);
      });
307
308
    closeModal();
  }
柏杨 authored
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  // function handleShow(visible: boolean) {
  //   if (visible) {
  //     projectStartTime.value = null;
  //     projectEndTime.value = null;
  //     produceStartTime.value = null;
  //     produceEndTime.value = null;
  //     customerCode.value = null;
  //     projectNo.value = null;
  //     ids.value = null;
  //     developTotalPrice.value = null;
  //     actualdocumentaryPrice.value = null;
  //     copyTotalPrice.value = null;
  //     packetActualTotalPrice.value = null;
  //     orderCount.value = 0;
  //   }
  // }
柏杨 authored
325
  function handleShow(visible: boolean) {
柏杨 authored
326
    if (!visible) {
柏杨 authored
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
      projectStartTime.value = null; // 项目开发开始时间
      projectEndTime.value = null; // 项目开发结束时间
      produceStartTime.value = null; // 生产开始时间
      produceEndTime.value = null; // 生产结束时间
      customerCode.value = null; // 客户编码
      projectNo.value = null; // 项目号
      ids.value = null; // 假设存在的 ID 列表
      developTotalPrice.value = null; // 开发总价格
      actualdocumentaryPrice.value = null; // 实际跟单费用
      copyTotalPrice.value = null; // 复制总价格
      packetActualTotalPrice.value = null; // 包装实际总价格
      orderCount.value = 0; // 订单总数量

      // 新增的数据 - 修改的位置
      testinput.value = null; // 新增输入框
      Input1.value = ''; // 输入框 1
      Input2.value = null; // 输入框 2
      res.value = null; // 结果
      orderList.value = null; // 订单列表
      spainRatio.value = 0; // 西班牙比例
      chinaRatio.value = 0; // 中国比例
      actualRmbPrice.value = 0; // 实际跟单单价
      actualPrice.value = 0; // 实际跟单单价折算美金
柏杨 authored
350
351
352
353
354
355
356
357
358
359
360
361
362
      actualRatio.value = 0; // 实际汇率
      customerTotalPrice.value = 0; // 客户总价合计
      actualRatioProfitPrice.value = 0; // 汇率收益
      grossProfit.value = 0; // 毛利润合计
      chinaRatioProfitPrice.value = 0; // 中国团队提成比例
      developProfit.value = 0; // 研发贸易利润
      fixCost.value = 0; // 固定成本
      outTotalPrice.value = 0; // 支出合计
      packetProfitPrice.value = 0; // 包装费用收益计算
      packetTotalPrice.value = 0; // 包装费用合计
      productionDepartmentTotalPrice.value = 0; // 生成科总价
      totalProfitPrice.value = 0; // 综合收益计算
      spainRatioProfitPrice.value = 0; // 西班牙提成金额
柏杨 authored
363
364
365
      customerTotalPriceUsd.value = 0;
      productionDepartmentTotalPriceUsd.value = 0;
      packetTotalPriceUsd.value = 0;
柏杨 authored
366
367
    }
  }
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
  //提成接口
  interface RatioListItem {
    createBy: string;
    createTime: string;
    enableFlag: number;
    id: number;
    modifyBy: string;
    modifyTime: string;
    relationCode: string;
    relationName: string;
    relationValue: string; // 这里 relationValue 是一个字符串,但内部是一个 JSON 数组,需要进一步解析
    settingCode: string;
    settingName: string;
    settingType: number;
    settingValue: string;
  }
  interface RatioList {
    items: RatioListItem[];
  }
柏杨 authored
387
388
389
390
391
  async function handleCalculate() {
    const packetCalculatePrice = ref(0);
    const orderCalculateCount = ref(0);
    const allList = toRaw(orderList.value);
    allList.forEach((item) => {
柏杨 authored
392
      packetCalculatePrice.value += item?.profitAnalysisInfo?.packetPrice;
柏杨 authored
393
394
395
396
      orderCalculateCount.value += item.orderCount;
      actualRmbPrice.value += packetCalculatePrice.value / orderCalculateCount.value;
    });
    actualPrice.value = actualRmbPrice.value / actualRatio.value;
397
398
399
400
401
402
403
404
405
406
    // const ratioList = (await getList({ settingType: 3 })) as Array<RatioListItem>;
    const ratioList = (await getList({ settingType: 3 })) as RatioList;
    const ratios = ratioList.items.filter((item) => item.settingValue === customerCode.value);
    const ratioAll = JSON.parse(ratios[0].relationValue);
    chinaRatio.value = ratioAll[1].relationValue;
    spainRatio.value = ratioAll[2].relationValue;
    //提成比例为0,提成设为0
    const params = {
      customerCode: customerCode.value,
      projectNo: projectNo.value,
柏杨 authored
407
      ids: ids.value,
408
409
410
411
412
      projectStartTime: projectStartTime.value,
      projectEndTime: projectEndTime.value,
      produceStartTime: produceStartTime.value,
      produceEndTime: produceEndTime.value,
      developTotalPrice: developTotalPrice.value,
柏杨 authored
413
      // actualdocumentaryPrice: actualdocumentaryPrice.value,
414
415
416
417
418
419
420
421
      copyTotalPrice: copyTotalPrice.value,
      spainRatio: spainRatio.value,
      chinaRatio: chinaRatio.value,
      packetActualTotalPrice: packetActualTotalPrice.value,
      actualRmbPrice: actualRmbPrice.value,
      actualPrice: actualPrice.value,
      actualRatio: actualRatio.value,
    };
柏杨 authored
422
423
424
    const res = await calculateBusinessProfit({
      customerCode: customerCode.value,
      projectNo: projectNo.value,
柏杨 authored
425
      ids: ids.value,
柏杨 authored
426
427
428
429
430
      projectStartTime: projectStartTime.value,
      projectEndTime: projectEndTime.value,
      produceStartTime: produceStartTime.value,
      produceEndTime: produceEndTime.value,
      developTotalPrice: developTotalPrice.value,
柏杨 authored
431
      // actualdocumentaryPrice: actualdocumentaryPrice.value,
柏杨 authored
432
433
434
435
436
437
438
439
      copyTotalPrice: copyTotalPrice.value,
      spainRatio: spainRatio.value,
      chinaRatio: chinaRatio.value,
      packetActualTotalPrice: packetActualTotalPrice.value,
      actualRmbPrice: actualRmbPrice.value,
      actualPrice: actualPrice.value,
      actualRatio: actualRatio.value,
    });
柏杨 authored
440
441
442
443
444
    customerTotalPrice.value = res.customerTotalPrice.toFixed(2);
    grossProfit.value = res.grossProfit.toFixed(2);
    actualRatioProfitPrice.value = res.actualRatioProfitPrice.toFixed(2);
    actualRmbPrice.value = res.actualRmbPrice.toFixed(2);
    actualPrice.value = res.actualPrice.toFixed(2);
445
    actualRatio.value = res.actualRatio;
柏杨 authored
446
447
448
449
450
451
452
453
    actualRatiactualRatioProfitPriceo.value = res.actualRatioProfitPrice.toFixed(2); //汇率收益计算
    chinaRatioProfitPrice.value = res.chinaRatioProfitPrice.toFixed(2); //中国团队提成比例
    developProfit.value = res.developProfit.toFixed(2); //研发贸易利润
    developTotalPrice.value = res.developTotalPrice.toFixed(2);
    copyTotalPrice.value = res.copyTotalPrice.toFixed(2);
    packetActualTotalPrice.value = res.packetActualTotalPrice.toFixed(2);
    actualRatio.value = res.actualRatio.toFixed(2);
    fixCost.value = res.fixCost.toFixed(2); // 固定成本
454
    orderCount.value = res.orderCount; //订单总数量
柏杨 authored
455
456
457
458
459
460
    outTotalPrice.value = res.outTotalPrice.toFixed(2); //支出合计
    packetProfitPrice.value = res.packetProfitPrice.toFixed(2); //包装费用收益计算
    packetTotalPrice.value = res.packetTotalPrice.toFixed(2); //包装费用合计
    productionDepartmentTotalPrice.value = res.productionDepartmentTotalPrice.toFixed(2); //生成科总价
    totalProfitPrice.value = res.totalProfitPrice.toFixed(2); //综合收益计算
    spainRatioProfitPrice.value = res.spainRatioProfitPrice.toFixed(2); //西班牙提成金额
柏杨 authored
461
462
463
    customerTotalPriceUsd.value = res.customerTotalPriceUsd.toFixed(2);
    productionDepartmentTotalPriceUsd.value = res.productionDepartmentTotalPriceUsd.toFixed(2);
    packetTotalPriceUsd.value = res.packetTotalPriceUsd.toFixed(2);
柏杨 authored
464
  }
465
466
467
468
469
470
471
472
</script>
<style scoped>
  .divAll {
    display: flex;
    justify-content: center;
    align-items: center;
  }
</style>