Commit e66dda3eba798da304a57ad39e8d3df6d231b6a2

Authored by “wangming”
1 parent caa83ded

11

antis-ncc-admin/src/views/salaryCalculation/index.vue
1 <template> 1 <template>
2 <div class="salary-calculation-container"> 2 <div class="salary-calculation-container">
3 - <!-- 页面头部 -->  
4 - <div class="header-card">  
5 - <h1 class="title">工资计算与统计系统</h1>  
6 - <p class="subtitle">智能生成各类业绩统计数据,一键完成工资计算</p>  
7 - </div>  
8 -  
9 - <!-- 月份选择区域 -->  
10 - <el-card class="box-card month-selector-card">  
11 - <div slot="header" class="clearfix">  
12 - <span><i class="el-icon-date"></i> 选择统计月份</span>  
13 - <el-button style="float: right; padding: 3px 0" type="text" @click="resetMonth">重置</el-button>  
14 - </div>  
15 - <div class="month-picker-wrapper">  
16 - <el-date-picker  
17 - v-model="statisticsMonth"  
18 - type="month"  
19 - placeholder="选择月份"  
20 - format="yyyy年MM月"  
21 - value-format="yyyyMM"  
22 - :clearable="false"  
23 - class="month-picker"  
24 - >  
25 - </el-date-picker>  
26 - </div>  
27 - </el-card>  
28 -  
29 <!-- 主要内容区域 - 左右布局 --> 3 <!-- 主要内容区域 - 左右布局 -->
30 <div class="main-content"> 4 <div class="main-content">
31 <!-- 左侧:统计操作区域 --> 5 <!-- 左侧:统计操作区域 -->
32 <div class="left-panel"> 6 <div class="left-panel">
33 - <!-- 一键计算工资 -->  
34 - <el-card class="box-card calculate-card">  
35 - <div slot="header" class="clearfix">  
36 - <span><i class="el-icon-cpu"></i> 一键计算工资</span>  
37 - </div>  
38 - <div class="calculate-content">  
39 - <p class="calculate-desc">按顺序执行所有统计方法,生成完整的工资数据</p>  
40 - <el-button  
41 - type="primary"  
42 - size="large"  
43 - :loading="isCalculating"  
44 - @click="handleCalculateSalary"  
45 - class="calculate-button"  
46 - :disabled="!statisticsMonth"  
47 - >  
48 - <i class="el-icon-magic-stick"></i>  
49 - {{ isCalculating ? '计算中...' : '一键计算工资' }}  
50 - </el-button>  
51 - <div v-if="calculationProgress.length > 0" class="progress-info">  
52 - <div class="progress-title">计算进度:</div>  
53 - <div v-for="(step, index) in calculationProgress" :key="index" class="progress-step">  
54 - <i :class="getProgressIcon(step.status)" :style="{ color: getProgressColor(step.status) }"></i>  
55 - <span :class="{ 'completed': step.status === 'completed', 'failed': step.status === 'failed' }">  
56 - {{ step.name }}  
57 - </span>  
58 - </div> 7 + <!-- 顶部控制区域 - 同一行显示 -->
  8 + <div class="top-controls-row">
  9 + <!-- 月份选择区域 -->
  10 + <el-card class="box-card month-selector-card">
  11 + <div slot="header" class="clearfix">
  12 + <span><i class="el-icon-date"></i> 选择统计月份</span>
  13 + <el-button style="float: right; padding: 3px 0" type="text" @click="resetMonth">重置</el-button>
59 </div> 14 </div>
60 - </div>  
61 - </el-card> 15 + <div class="month-picker-wrapper">
  16 + <el-date-picker
  17 + v-model="statisticsMonth"
  18 + type="month"
  19 + placeholder="选择月份"
  20 + format="yyyy年MM月"
  21 + value-format="yyyyMM"
  22 + :clearable="false"
  23 + class="month-picker"
  24 + >
  25 + </el-date-picker>
  26 + </div>
  27 + </el-card>
  28 +
  29 + <!-- 一键计算工资 -->
  30 + <el-card class="box-card calculate-card">
  31 + <div slot="header" class="clearfix">
  32 + <span><i class="el-icon-cpu"></i> 一键计算工资</span>
  33 + </div>
  34 + <div class="calculate-content">
  35 + <p class="calculate-desc">按顺序执行所有统计方法,生成完整的工资数据</p>
  36 + <el-button
  37 + type="primary"
  38 + size="large"
  39 + :loading="isCalculating"
  40 + @click="handleCalculateSalary"
  41 + class="calculate-button"
  42 + :disabled="!statisticsMonth"
  43 + >
  44 + <i class="el-icon-magic-stick"></i>
  45 + {{ isCalculating ? '计算中...' : '一键计算工资' }}
  46 + </el-button>
  47 + </div>
  48 + </el-card>
  49 + </div>
62 50
63 <!-- 单独统计操作 --> 51 <!-- 单独统计操作 -->
64 <el-card class="box-card statistics-card"> 52 <el-card class="box-card statistics-card">
@@ -134,17 +122,27 @@ @@ -134,17 +122,27 @@
134 122
135 <!-- 右侧:结果显示区域 --> 123 <!-- 右侧:结果显示区域 -->
136 <div class="right-panel"> 124 <div class="right-panel">
  125 + <!-- 计算进度区域 -->
  126 + <el-card class="box-card progress-card" v-if="calculationProgress.length > 0">
  127 + <div slot="header" class="clearfix">
  128 + <span><i class="el-icon-time"></i> 计算进度</span>
  129 + </div>
  130 + <div class="progress-content">
  131 + <div v-for="(step, index) in calculationProgress" :key="index" class="progress-step">
  132 + <i :class="getProgressIcon(step.status)" :style="{ color: getProgressColor(step.status) }"></i>
  133 + <span :class="{ 'completed': step.status === 'completed', 'failed': step.status === 'failed' }">
  134 + {{ step.name }}
  135 + </span>
  136 + </div>
  137 + </div>
  138 + </el-card>
  139 +
137 <el-card class="box-card result-card"> 140 <el-card class="box-card result-card">
138 <div slot="header" class="clearfix"> 141 <div slot="header" class="clearfix">
139 <span><i class="el-icon-document"></i> 统计结果</span> 142 <span><i class="el-icon-document"></i> 统计结果</span>
140 - <div class="header-actions">  
141 - <el-button type="text" @click="exportResults" :disabled="results.length === 0">  
142 - <i class="el-icon-download"></i> 导出  
143 - </el-button>  
144 - <el-button type="text" @click="clearResults">  
145 - <i class="el-icon-delete"></i> 清空  
146 - </el-button>  
147 - </div> 143 + <el-button type="text" @click="clearResults">
  144 + <i class="el-icon-delete"></i> 清空
  145 + </el-button>
148 </div> 146 </div>
149 <div class="result-list" ref="resultList"> 147 <div class="result-list" ref="resultList">
150 <div v-if="results.length === 0" class="no-results"> 148 <div v-if="results.length === 0" class="no-results">
@@ -220,14 +218,6 @@ export default { @@ -220,14 +218,6 @@ export default {
220 } 218 }
221 return json 219 return json
222 }, 220 },
223 - exportResults() {  
224 - if (this.results.length === 0) {  
225 - this.$message.warning('没有可导出的结果')  
226 - return  
227 - }  
228 - // 这里可以实现导出功能  
229 - this.$message.success('导出功能开发中...')  
230 - },  
231 221
232 // 一键计算工资 222 // 一键计算工资
233 async handleCalculateSalary() { 223 async handleCalculateSalary() {
@@ -440,27 +430,6 @@ export default { @@ -440,27 +430,6 @@ export default {
440 min-height: calc(100vh - 50px); 430 min-height: calc(100vh - 50px);
441 font-family: 'Arial', sans-serif; 431 font-family: 'Arial', sans-serif;
442 432
443 - .header-card {  
444 - background: linear-gradient(135deg, #409EFF, #79BBFF);  
445 - color: #fff;  
446 - padding: 30px;  
447 - border-radius: 15px;  
448 - margin-bottom: 20px;  
449 - text-align: center;  
450 - box-shadow: 0 8px 20px rgba(0, 123, 255, 0.2);  
451 -  
452 - .title {  
453 - font-size: 2.5em;  
454 - margin-bottom: 10px;  
455 - font-weight: bold;  
456 - }  
457 -  
458 - .subtitle {  
459 - font-size: 1.1em;  
460 - opacity: 0.9;  
461 - }  
462 - }  
463 -  
464 .box-card { 433 .box-card {
465 border-radius: 10px; 434 border-radius: 10px;
466 margin-bottom: 20px; 435 margin-bottom: 20px;
@@ -480,115 +449,90 @@ export default { @@ -480,115 +449,90 @@ export default {
480 } 449 }
481 } 450 }
482 451
483 - .month-selector-card {  
484 - .month-picker-wrapper {  
485 - display: flex;  
486 - justify-content: center;  
487 - align-items: center;  
488 - }  
489 - .month-picker {  
490 - width: 100%;  
491 - max-width: 300px;  
492 - }  
493 - }  
494 -  
495 - // 主要内容区域 - 左右布局  
496 - .main-content { 452 + // 顶部控制区域 - 同一行显示两个卡片
  453 + .top-controls-row {
497 display: flex; 454 display: flex;
498 gap: 20px; 455 gap: 20px;
499 - min-height: 600px;  
500 -  
501 - .left-panel {  
502 - flex: 1;  
503 - min-width: 0; // 防止flex子项溢出  
504 - } 456 + margin-bottom: 20px;
505 457
506 - .right-panel { 458 + .month-selector-card, .calculate-card {
507 flex: 1; 459 flex: 1;
508 min-width: 0; 460 min-width: 0;
509 } 461 }
510 - }  
511 -  
512 - // 一键计算工资卡片  
513 - .calculate-card {  
514 - margin-bottom: 20px;  
515 - background: linear-gradient(135deg, #67C23A, #85CE61);  
516 - color: white;  
517 462
518 - ::v-deep .el-card__header {  
519 - background: rgba(255, 255, 255, 0.1);  
520 - color: white;  
521 - border-bottom: 1px solid rgba(255, 255, 255, 0.2);  
522 - }  
523 -  
524 - .calculate-content {  
525 - text-align: center;  
526 -  
527 - .calculate-desc {  
528 - color: rgba(255, 255, 255, 0.9);  
529 - margin-bottom: 20px;  
530 - font-size: 1.1em; 463 + .month-selector-card {
  464 + .month-picker-wrapper {
  465 + display: flex;
  466 + justify-content: flex-start;
  467 + align-items: center;
531 } 468 }
532 -  
533 - .calculate-button { 469 + .month-picker {
534 width: 100%; 470 width: 100%;
535 - height: 60px;  
536 - font-size: 1.3em;  
537 - font-weight: bold;  
538 - border-radius: 10px;  
539 - background: rgba(255, 255, 255, 0.2);  
540 - border: 2px solid rgba(255, 255, 255, 0.3);  
541 - color: white; 471 + max-width: 200px;
  472 + }
  473 + }
542 474
543 - &:hover:not(:disabled) {  
544 - background: rgba(255, 255, 255, 0.3);  
545 - border-color: rgba(255, 255, 255, 0.5);  
546 - } 475 + .calculate-card {
  476 + background: linear-gradient(135deg, #67C23A, #85CE61);
  477 + color: white;
547 478
548 - &:disabled {  
549 - opacity: 0.6;  
550 - } 479 + ::v-deep .el-card__header {
  480 + background: rgba(255, 255, 255, 0.1);
  481 + color: white;
  482 + border-bottom: 1px solid rgba(255, 255, 255, 0.2);
551 } 483 }
552 484
553 - .progress-info {  
554 - margin-top: 20px;  
555 - text-align: left; 485 + .calculate-content {
  486 + text-align: center;
556 487
557 - .progress-title {  
558 - font-weight: bold;  
559 - margin-bottom: 10px; 488 + .calculate-desc {
560 color: rgba(255, 255, 255, 0.9); 489 color: rgba(255, 255, 255, 0.9);
  490 + margin-bottom: 15px;
  491 + font-size: 0.95em;
  492 + line-height: 1.4;
561 } 493 }
562 494
563 - .progress-step {  
564 - display: flex;  
565 - align-items: center;  
566 - margin-bottom: 8px;  
567 - font-size: 0.95em; 495 + .calculate-button {
  496 + width: 100%;
  497 + height: 40px;
  498 + font-size: 1em;
  499 + font-weight: bold;
  500 + border-radius: 6px;
  501 + background: rgba(255, 255, 255, 0.2);
  502 + border: 2px solid rgba(255, 255, 255, 0.3);
  503 + color: white;
568 504
569 - i {  
570 - margin-right: 8px;  
571 - font-size: 1.1em; 505 + &:hover:not(:disabled) {
  506 + background: rgba(255, 255, 255, 0.3);
  507 + border-color: rgba(255, 255, 255, 0.5);
572 } 508 }
573 509
574 - span {  
575 - color: rgba(255, 255, 255, 0.9);  
576 -  
577 - &.completed {  
578 - color: #fff;  
579 - font-weight: bold;  
580 - }  
581 -  
582 - &.failed {  
583 - color: #ffeb3b;  
584 - font-weight: bold;  
585 - } 510 + &:disabled {
  511 + opacity: 0.6;
586 } 512 }
587 } 513 }
588 } 514 }
589 } 515 }
590 } 516 }
591 517
  518 + // 主要内容区域 - 左右布局
  519 + .main-content {
  520 + display: flex;
  521 + gap: 20px;
  522 + min-height: 600px;
  523 +
  524 + .left-panel {
  525 + flex: 1;
  526 + min-width: 0; // 防止flex子项溢出
  527 + }
  528 +
  529 + .right-panel {
  530 + flex: 1;
  531 + min-width: 0;
  532 + }
  533 + }
  534 +
  535 +
592 // 统计操作卡片 536 // 统计操作卡片
593 .statistics-card { 537 .statistics-card {
594 .statistics-grid { 538 .statistics-grid {
@@ -657,15 +601,53 @@ export default { @@ -657,15 +601,53 @@ export default {
657 } 601 }
658 } 602 }
659 603
  604 + // 进度卡片
  605 + .progress-card {
  606 + margin-bottom: 20px;
  607 + background: linear-gradient(135deg, #E6F7FF, #BAE7FF);
  608 + border: 1px solid #91D5FF;
  609 +
  610 + .progress-content {
  611 + .progress-step {
  612 + display: flex;
  613 + align-items: center;
  614 + margin-bottom: 12px;
  615 + padding: 8px 12px;
  616 + background: rgba(255, 255, 255, 0.7);
  617 + border-radius: 6px;
  618 + font-size: 0.95em;
  619 +
  620 + &:last-child {
  621 + margin-bottom: 0;
  622 + }
  623 +
  624 + i {
  625 + margin-right: 10px;
  626 + font-size: 1.1em;
  627 + }
  628 +
  629 + span {
  630 + color: #333;
  631 + font-weight: 500;
  632 +
  633 + &.completed {
  634 + color: #67C23A;
  635 + font-weight: bold;
  636 + }
  637 +
  638 + &.failed {
  639 + color: #F56C6C;
  640 + font-weight: bold;
  641 + }
  642 + }
  643 + }
  644 + }
  645 + }
  646 +
660 // 结果显示卡片 647 // 结果显示卡片
661 .result-card { 648 .result-card {
662 height: 100%; 649 height: 100%;
663 650
664 - .header-actions {  
665 - display: flex;  
666 - gap: 10px;  
667 - }  
668 -  
669 .result-list { 651 .result-list {
670 max-height: 500px; 652 max-height: 500px;
671 overflow-y: auto; 653 overflow-y: auto;
@@ -764,14 +746,13 @@ export default { @@ -764,14 +746,13 @@ export default {
764 padding: 10px; 746 padding: 10px;
765 } 747 }
766 748
767 - .header-card {  
768 - padding: 20px;  
769 - .title {  
770 - font-size: 1.8em;  
771 - }  
772 - .subtitle {  
773 - font-size: 0.9em;  
774 - } 749 + .top-controls-row {
  750 + flex-direction: column;
  751 + gap: 15px;
  752 + }
  753 +
  754 + .month-selector-card, .calculate-card {
  755 + width: 100%;
775 } 756 }
776 757
777 .statistics-grid { 758 .statistics-grid {