order-stat.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <template>
  2. <ele-card>
  3. <div class="section-title">
  4. <span class="section-bar"></span>
  5. <span>回收数据</span>
  6. </div>
  7. <el-row :gutter="24">
  8. <el-col :span="12" :xs="24">
  9. <div
  10. v-for="(group, index) in leftGroups"
  11. :key="index"
  12. class="stat-panel"
  13. >
  14. <div
  15. v-for="item in group"
  16. :key="item.label"
  17. class="stat-cell"
  18. >
  19. <div class="stat-num">{{ item.value }}</div>
  20. <div class="stat-label">
  21. <i class="stat-dot" :class="item.dot"></i>
  22. <span>{{ item.label }}</span>
  23. </div>
  24. </div>
  25. </div>
  26. </el-col>
  27. <el-col :span="12" :xs="24">
  28. <div
  29. v-for="(group, index) in rightGroups"
  30. :key="index"
  31. class="stat-panel"
  32. >
  33. <div
  34. v-for="item in group"
  35. :key="item.label"
  36. class="stat-cell"
  37. >
  38. <div class="stat-num">{{ item.value }}</div>
  39. <div class="stat-label">
  40. <i class="stat-dot" :class="item.dot"></i>
  41. <span>{{ item.label }}</span>
  42. </div>
  43. </div>
  44. </div>
  45. </el-col>
  46. </el-row>
  47. </ele-card>
  48. </template>
  49. <script setup>
  50. import { computed } from 'vue';
  51. const props = defineProps({
  52. detail: {
  53. type: Object,
  54. default: () => ({})
  55. }
  56. });
  57. const num = (value) => {
  58. const count = Number(value);
  59. return Number.isFinite(count) ? count : 0;
  60. };
  61. const cell = (label, field, dot) => ({
  62. label,
  63. value: num(props.detail?.[field]),
  64. dot
  65. });
  66. const leftGroups = computed(() => [
  67. [
  68. cell('待初审订单', 'waitFirstCheckOrderNum', 'is-orange'),
  69. cell('待收货订单', 'waitReceiveOrderNum', 'is-green'),
  70. cell('待审核订单', 'waitCheckOrderNum', 'is-orange'),
  71. cell('待付款订单', 'waitPayOrderNum', 'is-orange')
  72. ],
  73. [
  74. cell('待退回订单', 'waitReturnOrderNum', 'is-orange'),
  75. cell('已到仓-收货超时', 'arriveReceiveTimeoutNum', 'is-green'),
  76. cell('已收货-审核超时', 'receiveCheckTimeoutNum', 'is-orange'),
  77. cell('回收催审核', 'recycleUrgeCheckNum', 'is-orange')
  78. ],
  79. [
  80. cell('待处理复审', 'waitRecheckNum', 'is-orange'),
  81. cell('待审核提醒', 'waitCheckRemindNum', 'is-green')
  82. ]
  83. ]);
  84. const rightGroups = computed(() => [
  85. [
  86. cell('库存预警', 'stockWarnNum', 'is-orange'),
  87. cell('库存已满', 'stockFullNum', 'is-green'),
  88. cell('24小时未初审', 'noFirstCheckNum', 'is-orange'),
  89. cell('回收价>出售价(中等)', 'recyclePriceAbnormalNum', 'is-orange')
  90. ],
  91. [
  92. cell('投诉管理', 'complaintsNum', 'is-orange'),
  93. cell('意见反馈', 'feedbackNum', 'is-green'),
  94. cell('上报', 'reportNum', 'is-orange'),
  95. cell('揽件超时', 'pickupTimeoutNum', 'is-orange')
  96. ],
  97. [
  98. cell('待入库不良单', 'waitBadStockNum', 'is-orange'),
  99. cell('待处理工单', 'waitHandleWorkOrderNum', 'is-green')
  100. ]
  101. ]);
  102. </script>
  103. <style lang="scss" scoped>
  104. .section-title {
  105. display: flex;
  106. align-items: center;
  107. margin-bottom: 16px;
  108. font-size: 16px;
  109. font-weight: 600;
  110. color: #303133;
  111. }
  112. .section-bar {
  113. width: 3px;
  114. height: 16px;
  115. margin-right: 8px;
  116. background: #67c23a;
  117. }
  118. .stat-panel {
  119. display: grid;
  120. grid-template-columns: 1fr 1fr;
  121. margin-bottom: 16px;
  122. border: 1px solid #ebeef5;
  123. border-radius: 4px;
  124. &:last-child {
  125. margin-bottom: 0;
  126. }
  127. }
  128. .stat-cell {
  129. padding: 22px 12px 18px;
  130. text-align: center;
  131. &:nth-child(2n) {
  132. border-left: 1px solid #ebeef5;
  133. }
  134. &:nth-child(n + 3) {
  135. border-top: 1px solid #ebeef5;
  136. }
  137. }
  138. .stat-num {
  139. font-size: 28px;
  140. line-height: 1.2;
  141. font-weight: 600;
  142. color: #303133;
  143. }
  144. .stat-label {
  145. display: flex;
  146. align-items: center;
  147. justify-content: center;
  148. margin-top: 8px;
  149. color: #606266;
  150. font-size: 14px;
  151. }
  152. .stat-dot {
  153. width: 8px;
  154. height: 8px;
  155. margin-right: 6px;
  156. border-radius: 50%;
  157. flex-shrink: 0;
  158. &.is-orange {
  159. background: #e6a23c;
  160. }
  161. &.is-green {
  162. background: #67c23a;
  163. }
  164. }
  165. </style>