Commit e66dda3eba798da304a57ad39e8d3df6d231b6a2
1 parent
caa83ded
11
Showing
1 changed file
with
168 additions
and
187 deletions
antis-ncc-admin/src/views/salaryCalculation/index.vue
| 1 | 1 | <template> |
| 2 | 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 | 4 | <div class="main-content"> |
| 31 | 5 | <!-- 左侧:统计操作区域 --> |
| 32 | 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 | 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 | 52 | <el-card class="box-card statistics-card"> |
| ... | ... | @@ -134,17 +122,27 @@ |
| 134 | 122 | |
| 135 | 123 | <!-- 右侧:结果显示区域 --> |
| 136 | 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 | 140 | <el-card class="box-card result-card"> |
| 138 | 141 | <div slot="header" class="clearfix"> |
| 139 | 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 | 146 | </div> |
| 149 | 147 | <div class="result-list" ref="resultList"> |
| 150 | 148 | <div v-if="results.length === 0" class="no-results"> |
| ... | ... | @@ -220,14 +218,6 @@ export default { |
| 220 | 218 | } |
| 221 | 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 | 223 | async handleCalculateSalary() { |
| ... | ... | @@ -440,27 +430,6 @@ export default { |
| 440 | 430 | min-height: calc(100vh - 50px); |
| 441 | 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 | 433 | .box-card { |
| 465 | 434 | border-radius: 10px; |
| 466 | 435 | margin-bottom: 20px; |
| ... | ... | @@ -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 | 454 | display: flex; |
| 498 | 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 | 459 | flex: 1; |
| 508 | 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 | 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 | 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 | 537 | .statistics-card { |
| 594 | 538 | .statistics-grid { |
| ... | ... | @@ -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 | 648 | .result-card { |
| 662 | 649 | height: 100%; |
| 663 | 650 | |
| 664 | - .header-actions { | |
| 665 | - display: flex; | |
| 666 | - gap: 10px; | |
| 667 | - } | |
| 668 | - | |
| 669 | 651 | .result-list { |
| 670 | 652 | max-height: 500px; |
| 671 | 653 | overflow-y: auto; |
| ... | ... | @@ -764,14 +746,13 @@ export default { |
| 764 | 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 | 758 | .statistics-grid { | ... | ... |