imeik-bizui 2.6.4 → 2.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,12 @@
10
10
  <span class="fpb-title__text">{{ title }}</span>
11
11
  </div>
12
12
 
13
- <div v-loading="loading" class="fpb-body">
13
+ <div
14
+ v-loading="loading"
15
+ class="fpb-body"
16
+ :class="{ 'fpb-body--loading': loading }"
17
+ element-loading-text="加载中..."
18
+ >
14
19
  <div v-if="error" class="fpb-msg fpb-msg--error">{{ error }}</div>
15
20
 
16
21
  <div v-else-if="hasContent" :class="['fpb-panel', panelThemeClass]" role="status">
@@ -406,10 +411,21 @@ export default {
406
411
  }
407
412
 
408
413
  .fpb-body {
414
+ position: relative;
409
415
  min-width: 0;
410
416
  max-width: 100%;
411
417
  }
412
418
 
419
+ /* loading 时内容为空会高度塌陷,spinner 会溢出到下方区块;对齐费率看板预留占位 */
420
+ .fpb-body--loading {
421
+ min-height: 80px;
422
+
423
+ /* Element 默认 loading 文案 margin 过小,和转圈贴在一起 */
424
+ ::v-deep .el-loading-spinner .el-loading-text {
425
+ margin-top: 12px;
426
+ }
427
+ }
428
+
413
429
  .fpb-msg {
414
430
  padding: 12px 16px;
415
431
  font-size: 13px;
@@ -167,6 +167,7 @@ export default {
167
167
  const raw = this.innerDetail || this.detail
168
168
  if (!raw) return EMPTY_DETAIL
169
169
  return normalizeDetail(raw, {
170
+ // 优先接口 customName(在 normalizeDetail 内读取);prop / 概览作兜底
170
171
  customerName: this.customerName || this.board.customerName,
171
172
  // 顶部汇总取概览产品行(与看板同源),明细接口只负责三区列表
172
173
  overviewProducts: this.board.products
@@ -247,12 +248,16 @@ export default {
247
248
  }
248
249
  },
249
250
  async onViewDetail() {
250
- this.detailVisible = true
251
251
  this.detailError = ''
252
- this.innerDetail = null
252
+ // 先进入 loading,再打开弹窗,避免首帧只有公式行的窄框
253
+ const willFetch =
254
+ this.useDemo ||
255
+ typeof this.fetchDetail === 'function' ||
256
+ typeof this.loadDetail === 'function'
257
+ if (willFetch) this.detailLoading = true
258
+ this.detailVisible = true
253
259
 
254
260
  if (this.useDemo) {
255
- this.detailLoading = true
256
261
  try {
257
262
  this.innerDetail = createDemoDetail({
258
263
  ...this.board,
@@ -265,7 +270,6 @@ export default {
265
270
  }
266
271
 
267
272
  if (typeof this.fetchDetail === 'function') {
268
- this.detailLoading = true
269
273
  try {
270
274
  const base = {
271
275
  customerName: this.customerName,
@@ -276,16 +280,18 @@ export default {
276
280
  const detailPayload = this.detailPayload
277
281
  if (!detailPayload) {
278
282
  this.innerDetail = base
283
+ this.detailLoading = false
279
284
  return
280
285
  }
281
286
  const res = await this.fetchDetail(detailPayload)
282
287
  if (res && res.code === 200) {
288
+ // 保留接口 customName,勿用空 prop 覆盖
283
289
  this.innerDetail = {
284
290
  ...base,
285
- ...(res.data || {}),
286
- customerName: this.customerName
291
+ ...(res.data || {})
287
292
  }
288
293
  } else {
294
+ this.innerDetail = null
289
295
  throw new Error((res && res.message) || '底价明细获取失败')
290
296
  }
291
297
  } catch (e) {
@@ -297,12 +303,12 @@ export default {
297
303
  }
298
304
 
299
305
  if (typeof this.loadDetail === 'function') {
300
- this.detailLoading = true
301
306
  try {
302
307
  const data = await this.loadDetail({ overview: this.board, raw: this.rawOverview })
303
308
  this.innerDetail = data || null
304
309
  if (!data) this.detailError = '暂无底价明细'
305
310
  } catch (e) {
311
+ this.innerDetail = null
306
312
  this.detailError = (e && e.message) || '底价明细获取失败'
307
313
  } finally {
308
314
  this.detailLoading = false
@@ -2,7 +2,7 @@
2
2
  通用「底价明细」弹窗(纯展示,无接口依赖)
3
3
  - 顶部汇总:由 Dashboard 传入概览产品行
4
4
  - 下方三区(销售订单 / 非销出库 / 销售费用)等分三列并排
5
- - 三列明细等高:固定表格高度 + 预留分页条高度
5
+ - 三列卡片按内容收高(不强制等高撑白),表格按当前页行数自适应、无内部滚动条
6
6
  - 分区数据前端分页(pageSize);无底部关闭按钮,右上角关闭即可
7
7
  -->
8
8
  <template>
@@ -16,10 +16,49 @@
16
16
  :custom-class="dialogCustomClass"
17
17
  @close="onClose"
18
18
  >
19
- <div v-loading="loading" class="fpd-body">
19
+ <div
20
+ v-loading="loading && !showLoadingShell"
21
+ :class="['fpd-body', { 'fpd-body--loading': showLoadingShell }]"
22
+ >
20
23
  <div v-if="error" class="fpd-msg fpd-msg--error">{{ error }}</div>
21
24
 
25
+ <!-- 首次加载无内容时用骨架撑住高度,避免先闪出一条窄框 -->
26
+ <div v-else-if="showLoadingShell" class="fpd-skeleton" aria-hidden="true">
27
+ <div class="fpd-skeleton__formulas">
28
+ <div class="fpd-skeleton__bar fpd-skeleton__bar--label" />
29
+ <div class="fpd-skeleton__bar fpd-skeleton__bar--md" />
30
+ <div class="fpd-skeleton__bar fpd-skeleton__bar--sm" />
31
+ </div>
32
+ <div class="fpd-skeleton__summary">
33
+ <div class="fpd-skeleton__bar fpd-skeleton__bar--lg" />
34
+ <div class="fpd-skeleton__bar" />
35
+ <div class="fpd-skeleton__bar fpd-skeleton__bar--sm" />
36
+ </div>
37
+ <div class="fpd-skeleton__sections">
38
+ <div v-for="n in 3" :key="n" class="fpd-skeleton__section">
39
+ <div class="fpd-skeleton__bar fpd-skeleton__bar--title" />
40
+ <div class="fpd-skeleton__block" :style="{ height: resolvedTableHeight + 'px' }" />
41
+ <div class="fpd-skeleton__bar fpd-skeleton__bar--footer" />
42
+ </div>
43
+ </div>
44
+ </div>
45
+
22
46
  <template v-else>
47
+ <div v-if="formulaItems.length" class="fpd-formulas" role="note">
48
+ <span class="fpd-formulas__label">计算说明</span>
49
+ <div class="fpd-formulas__list">
50
+ <span
51
+ v-for="(item, idx) in formulaItems"
52
+ :key="idx"
53
+ class="fpd-formulas__item"
54
+ >
55
+ <em class="fpd-formulas__key">{{ item.key }}</em>
56
+ <span class="fpd-formulas__eq">=</span>
57
+ <span class="fpd-formulas__expr">{{ item.expr }}</span>
58
+ </span>
59
+ </div>
60
+ </div>
61
+
23
62
  <div v-if="summaryColumns.length" class="fpd-summary">
24
63
  <div v-if="isNarrow" class="fpd-summary__hint">汇总表可左右滑动</div>
25
64
  <el-table
@@ -76,8 +115,7 @@
76
115
  :data="pagedRows(section)"
77
116
  border
78
117
  size="small"
79
- class="fpd-table"
80
- :height="resolvedTableHeight"
118
+ class="fpd-table fpd-table--section"
81
119
  :header-cell-style="headerCellStyle"
82
120
  >
83
121
  <el-table-column
@@ -128,12 +166,6 @@
128
166
  </div>
129
167
  </div>
130
168
  </div>
131
-
132
- <div v-if="formulaList.length" class="fpd-formulas">
133
- <div v-for="(line, idx) in formulaList" :key="idx" class="fpd-formulas__line">
134
- {{ line }}
135
- </div>
136
- </div>
137
169
  </template>
138
170
  </div>
139
171
  </el-dialog>
@@ -203,15 +235,17 @@ export default {
203
235
  type: Array,
204
236
  default: null
205
237
  },
206
- /** 三列表格统一高度,保证等高 */
238
+ /**
239
+ * 骨架屏占位高度(表格本身按当前页行数自适应,不再用固定 height,避免内部滚动条)
240
+ */
207
241
  tableHeight: {
208
242
  type: [Number, String],
209
- default: 260
243
+ default: 180
210
244
  },
211
- /** 分区前端分页大小 */
245
+ /** 分区前端分页大小(略少以控制弹窗总高) */
212
246
  pageSize: {
213
247
  type: Number,
214
- default: 5
248
+ default: 4
215
249
  }
216
250
  },
217
251
  data() {
@@ -240,18 +274,40 @@ export default {
240
274
  resolvedTop() {
241
275
  return this.isNarrow ? '5vh' : this.top
242
276
  },
277
+ /** 仅骨架屏使用;真实表格按页内行数撑开,不设固定 height */
243
278
  resolvedTableHeight() {
244
279
  const base = Number(this.tableHeight)
245
- const fallback = Number.isFinite(base) && base > 0 ? base : 260
246
- return this.isNarrow ? Math.min(fallback, 200) : fallback
280
+ const fallback = Number.isFinite(base) && base > 0 ? base : 220
281
+ return this.isNarrow ? Math.min(fallback, 180) : fallback
247
282
  },
248
283
  formulaList() {
249
284
  if (Array.isArray(this.formulas)) return this.formulas
250
285
  return DEFAULT_DETAIL_FORMULAS
251
286
  },
287
+ /** 拆成「指标名 = 表达式」,便于加粗高亮 */
288
+ formulaItems() {
289
+ return (this.formulaList || []).map((line) => {
290
+ const text = String(line || '').trim()
291
+ const idx = text.indexOf('=')
292
+ if (idx < 0) return { key: text, expr: '' }
293
+ return {
294
+ key: text.slice(0, idx).trim(),
295
+ expr: text.slice(idx + 1).trim()
296
+ }
297
+ }).filter((item) => item.key)
298
+ },
299
+ /** 有汇总或分区时视为已有明细内容(可在旧数据上盖 loading) */
300
+ hasDetailContent() {
301
+ return (this.summaryColumns && this.summaryColumns.length > 0) ||
302
+ (this.sections && this.sections.length > 0)
303
+ },
304
+ /** 首次打开尚无数据:用骨架撑高,避免窄框闪一下 */
305
+ showLoadingShell() {
306
+ return this.loading && !this.error && !this.hasDetailContent
307
+ },
252
308
  /** 任一分区需要分页时,其余无分页列才占位对齐;全都没有则不占空白 */
253
309
  anySectionNeedsPager() {
254
- const size = this.pageSize || 5
310
+ const size = this.pageSize || 4
255
311
  return (this.sections || []).some((section) => this.sectionRowCount(section) > size)
256
312
  },
257
313
  /** 窄屏三区已改为单列,无需为空分页占位 */
@@ -329,7 +385,7 @@ export default {
329
385
  pagedRows(section) {
330
386
  const rows = section.rows || []
331
387
  const page = this.sectionPage(section)
332
- const size = this.pageSize || 5
388
+ const size = this.pageSize || 4
333
389
  const start = (page - 1) * size
334
390
  return rows.slice(start, start + size)
335
391
  },
@@ -405,25 +461,25 @@ export default {
405
461
  box-shadow: 0 24px 64px rgba(16, 24, 40, 0.24);
406
462
 
407
463
  .el-dialog__header {
408
- padding: 14px 22px;
464
+ padding: 12px 20px;
409
465
  border-bottom: 1px solid #e5e7eb;
410
466
  }
411
467
 
412
468
  .el-dialog__title {
413
- font-size: 18px;
469
+ font-size: 17px;
414
470
  font-weight: 600;
415
471
  color: #1f2329;
416
- line-height: 26px;
472
+ line-height: 24px;
417
473
  }
418
474
 
419
475
  .el-dialog__headerbtn {
420
- top: 18px;
476
+ top: 16px;
421
477
  right: 18px;
422
478
  }
423
479
 
424
480
  .el-dialog__body {
425
- padding: 18px 20px 16px;
426
- max-height: calc(92vh - 64px);
481
+ padding: 12px 16px 12px;
482
+ max-height: calc(92vh - 56px);
427
483
  overflow: auto;
428
484
  background: #f7f8fa;
429
485
  }
@@ -476,6 +532,110 @@ export default {
476
532
  min-width: 0;
477
533
  }
478
534
 
535
+ .fpd-body--loading {
536
+ min-height: 400px;
537
+ }
538
+
539
+ .fpd-skeleton {
540
+ display: flex;
541
+ flex-direction: column;
542
+ gap: 12px;
543
+ pointer-events: none;
544
+ }
545
+
546
+ .fpd-skeleton__summary {
547
+ padding: 14px 16px;
548
+ background: #fff;
549
+ border: 1px solid #e5e7eb;
550
+ border-radius: 8px;
551
+ display: flex;
552
+ flex-direction: column;
553
+ gap: 10px;
554
+ }
555
+
556
+ .fpd-skeleton__sections {
557
+ display: grid;
558
+ grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.05fr) minmax(0, 0.9fr);
559
+ gap: 12px;
560
+ }
561
+
562
+ .fpd-skeleton__section {
563
+ display: flex;
564
+ flex-direction: column;
565
+ gap: 10px;
566
+ padding: 12px 14px 14px;
567
+ background: #fff;
568
+ border: 1px solid #e5e7eb;
569
+ border-radius: 8px;
570
+ min-width: 0;
571
+ }
572
+
573
+ .fpd-skeleton__block {
574
+ width: 100%;
575
+ border-radius: 6px;
576
+ background: linear-gradient(90deg, #eef0f3 0%, #f6f7f9 50%, #eef0f3 100%);
577
+ background-size: 200% 100%;
578
+ animation: fpd-skeleton-shine 1.2s ease-in-out infinite;
579
+ }
580
+
581
+ .fpd-skeleton__formulas {
582
+ padding: 8px 12px;
583
+ background: #eef3ff;
584
+ border: 1px solid #d6e0f5;
585
+ border-radius: 8px;
586
+ display: flex;
587
+ align-items: center;
588
+ gap: 10px;
589
+ flex-wrap: wrap;
590
+ }
591
+
592
+ .fpd-skeleton__bar--label {
593
+ width: 56px;
594
+ height: 18px;
595
+ flex: none;
596
+ }
597
+
598
+ .fpd-skeleton__bar {
599
+ height: 12px;
600
+ border-radius: 4px;
601
+ background: linear-gradient(90deg, #eef0f3 0%, #f6f7f9 50%, #eef0f3 100%);
602
+ background-size: 200% 100%;
603
+ animation: fpd-skeleton-shine 1.2s ease-in-out infinite;
604
+ width: 72%;
605
+ }
606
+
607
+ .fpd-skeleton__bar--lg {
608
+ width: 88%;
609
+ height: 14px;
610
+ }
611
+
612
+ .fpd-skeleton__bar--md {
613
+ width: 64%;
614
+ }
615
+
616
+ .fpd-skeleton__bar--sm {
617
+ width: 48%;
618
+ }
619
+
620
+ .fpd-skeleton__bar--title {
621
+ width: 42%;
622
+ height: 14px;
623
+ }
624
+
625
+ .fpd-skeleton__bar--footer {
626
+ width: 56%;
627
+ margin-top: 2px;
628
+ }
629
+
630
+ @keyframes fpd-skeleton-shine {
631
+ 0% {
632
+ background-position: 100% 0;
633
+ }
634
+ 100% {
635
+ background-position: -100% 0;
636
+ }
637
+ }
638
+
479
639
  .fpd-msg {
480
640
  padding: 12px 16px;
481
641
  font-size: 13px;
@@ -490,7 +650,7 @@ export default {
490
650
  }
491
651
 
492
652
  .fpd-summary {
493
- margin-bottom: 12px;
653
+ margin-bottom: 10px;
494
654
  overflow-x: auto;
495
655
  -webkit-overflow-scrolling: touch;
496
656
  background: #fff;
@@ -505,16 +665,16 @@ export default {
505
665
  .fpd-sections {
506
666
  display: grid;
507
667
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.05fr) minmax(0, 0.9fr);
508
- gap: 12px;
509
- margin-bottom: 12px;
510
- align-items: stretch;
668
+ gap: 10px;
669
+ margin-bottom: 0;
670
+ align-items: start;
511
671
  }
512
672
 
513
673
  .fpd-section {
514
674
  display: flex;
515
675
  flex-direction: column;
516
676
  min-width: 0;
517
- min-height: 100%;
677
+ min-height: 0;
518
678
  border: 1px solid #e5e7eb;
519
679
  border-radius: 8px;
520
680
  overflow: hidden;
@@ -524,10 +684,10 @@ export default {
524
684
 
525
685
  .fpd-section__head {
526
686
  flex-shrink: 0;
527
- padding: 10px 14px;
687
+ padding: 8px 12px;
528
688
  display: flex;
529
689
  flex-direction: column;
530
- gap: 2px;
690
+ gap: 1px;
531
691
  box-sizing: border-box;
532
692
  background: #fafbfc;
533
693
  border-bottom: 1px solid #eef0f3;
@@ -535,14 +695,14 @@ export default {
535
695
  }
536
696
 
537
697
  .fpd-section__title {
538
- font-size: 15px;
698
+ font-size: 14px;
539
699
  font-weight: 600;
540
- line-height: 22px;
700
+ line-height: 20px;
541
701
  }
542
702
 
543
703
  .fpd-section__subtitle {
544
704
  font-size: 12px;
545
- line-height: 18px;
705
+ line-height: 16px;
546
706
  color: #8f959e;
547
707
  }
548
708
 
@@ -554,6 +714,7 @@ export default {
554
714
  flex: 0 0 auto;
555
715
  min-width: 0;
556
716
  overflow-x: auto;
717
+ overflow-y: hidden;
557
718
  -webkit-overflow-scrolling: touch;
558
719
  }
559
720
 
@@ -563,8 +724,8 @@ export default {
563
724
  justify-content: space-between;
564
725
  align-items: center;
565
726
  gap: 8px;
566
- padding: 10px 14px;
567
- font-size: 13px;
727
+ padding: 7px 12px;
728
+ font-size: 12px;
568
729
  font-weight: 600;
569
730
  flex-wrap: wrap;
570
731
  color: #646a73;
@@ -673,6 +834,25 @@ export default {
673
834
  }
674
835
  }
675
836
 
837
+ /* 分区表略收紧行高,一页内更紧凑且无内部滚动 */
838
+ ::v-deep .fpd-table--section {
839
+ .cell {
840
+ padding-top: 6px;
841
+ padding-bottom: 6px;
842
+ line-height: 18px;
843
+ }
844
+
845
+ th .cell {
846
+ padding-top: 6px;
847
+ padding-bottom: 6px;
848
+ }
849
+
850
+ /* 无固定 height 时仍兜底隐藏纵向滚动条 */
851
+ .el-table__body-wrapper {
852
+ overflow-y: hidden !important;
853
+ }
854
+ }
855
+
676
856
  .fpd-td--bold {
677
857
  font-weight: 700;
678
858
  color: #1f2329;
@@ -720,26 +900,95 @@ export default {
720
900
  }
721
901
 
722
902
  .fpd-formulas {
723
- padding: 12px 14px;
724
- border-radius: 8px;
725
- background: #fff;
726
- border: 1px solid #e5e7eb;
727
- font-size: 12px;
903
+ display: flex;
904
+ align-items: center;
905
+ gap: 8px 10px;
906
+ margin-bottom: 10px;
907
+ padding: 6px 10px;
908
+ border-radius: 6px;
909
+ background: linear-gradient(90deg, #eef4ff 0%, #f5f8ff 100%);
910
+ border: 1px solid #c9daf8;
911
+ box-shadow: inset 3px 0 0 #3370ff;
912
+ }
913
+
914
+ .fpd-formulas__label {
915
+ flex: none;
916
+ display: inline-flex;
917
+ align-items: center;
918
+ height: 20px;
919
+ padding: 0 7px;
920
+ border-radius: 3px;
921
+ background: #3370ff;
922
+ color: #fff;
923
+ font-size: 11px;
924
+ font-weight: 600;
728
925
  line-height: 20px;
729
- color: #646a73;
926
+ letter-spacing: 0.02em;
730
927
  }
731
928
 
732
- .fpd-formulas__line + .fpd-formulas__line {
733
- margin-top: 4px;
929
+ .fpd-formulas__list {
930
+ flex: 1;
931
+ min-width: 0;
932
+ display: flex;
933
+ flex-wrap: wrap;
934
+ align-items: center;
935
+ gap: 2px 0;
936
+ }
937
+
938
+ .fpd-formulas__item {
939
+ display: inline-flex;
940
+ align-items: baseline;
941
+ flex-wrap: wrap;
942
+ max-width: 100%;
943
+ font-size: 12px;
944
+ line-height: 18px;
945
+ color: #4e5969;
946
+
947
+ &:not(:last-child)::after {
948
+ content: '';
949
+ display: inline-block;
950
+ width: 1px;
951
+ height: 11px;
952
+ margin: 0 10px;
953
+ background: #b7c9ef;
954
+ vertical-align: middle;
955
+ position: relative;
956
+ top: 1px;
957
+ }
958
+ }
959
+
960
+ .fpd-formulas__key {
961
+ font-style: normal;
962
+ font-weight: 700;
963
+ color: #1f2329;
964
+ }
965
+
966
+ .fpd-formulas__eq {
967
+ margin: 0 4px;
968
+ color: #86909c;
969
+ font-weight: 500;
970
+ }
971
+
972
+ .fpd-formulas__expr {
973
+ color: #4e5969;
734
974
  }
735
975
 
736
976
  @media (max-width: 1100px) {
737
- .fpd-sections {
977
+ .fpd-sections,
978
+ .fpd-skeleton__sections {
738
979
  grid-template-columns: 1fr;
739
980
  }
740
981
  }
741
982
 
742
983
  @media (max-width: 768px) {
984
+ .fpd-body--loading {
985
+ min-height: 380px;
986
+ }
987
+
988
+ .fpd-skeleton__sections {
989
+ grid-template-columns: 1fr;
990
+ }
991
+
743
992
  .fpd-summary {
744
993
  margin-bottom: 12px;
745
994
  border-radius: 10px;
@@ -763,7 +1012,7 @@ export default {
763
1012
 
764
1013
  .fpd-sections {
765
1014
  gap: 12px;
766
- margin-bottom: 12px;
1015
+ margin-bottom: 0;
767
1016
  align-items: start;
768
1017
  }
769
1018
 
@@ -842,14 +1091,36 @@ export default {
842
1091
  justify-content: flex-end;
843
1092
  }
844
1093
 
1094
+ .fpd-skeleton__formulas {
1095
+ flex-direction: column;
1096
+ align-items: stretch;
1097
+ gap: 6px;
1098
+ }
1099
+
845
1100
  .fpd-formulas {
846
- padding: 10px 12px;
847
- border-radius: 10px;
848
- border-color: #e8ebf0;
1101
+ flex-direction: column;
1102
+ gap: 6px;
1103
+ padding: 8px 10px 8px 12px;
1104
+ margin-bottom: 12px;
1105
+ }
1106
+
1107
+ .fpd-formulas__label {
1108
+ align-self: flex-start;
1109
+ }
1110
+
1111
+ .fpd-formulas__list {
1112
+ display: grid;
1113
+ grid-template-columns: 1fr;
1114
+ gap: 4px;
1115
+ }
1116
+
1117
+ .fpd-formulas__item {
849
1118
  font-size: 11px;
850
- line-height: 18px;
851
- color: #6b7280;
852
- box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
1119
+ line-height: 17px;
1120
+
1121
+ &:not(:last-child)::after {
1122
+ display: none;
1123
+ }
853
1124
  }
854
1125
 
855
1126
  ::v-deep .fpd-table {
@@ -77,9 +77,9 @@ export default {
77
77
  display: flex;
78
78
  flex-wrap: wrap;
79
79
  align-items: center;
80
- gap: 6px 10px;
81
- min-height: 32px;
82
- padding: 4px 12px;
80
+ gap: 4px 8px;
81
+ min-height: 28px;
82
+ padding: 2px 12px;
83
83
  box-sizing: border-box;
84
84
  font-size: 12px;
85
85
  color: rgba(0, 0, 0, 0.65);
@@ -172,8 +172,10 @@ function buildExpenseRows() {
172
172
 
173
173
  /** 模拟 getProductPriceDetail data */
174
174
  export function createDemoDetail(overview = {}) {
175
+ const name = overview.customerName || overview.customName || DEMO_CUSTOMER
175
176
  return {
176
- customerName: overview.customerName || DEMO_CUSTOMER,
177
+ customName: name,
178
+ customerName: name,
177
179
  saleOrderList: buildSalesOrderRows(),
178
180
  noSaleOrderList: buildNonSalesRows(),
179
181
  costList: buildExpenseRows()
@@ -83,7 +83,7 @@ export function normalizeOverview(data = {}, options = {}) {
83
83
  applyTotalFee: data.applyTotalFee,
84
84
  year: data.year,
85
85
  footerText: DEFAULT_FOOTER_TEXT,
86
- customerName: options.customerName || data.customerName || '',
86
+ customerName: options.customerName || data.customName || data.customerName || '',
87
87
  controlMethod: data.controlMethod
88
88
  }
89
89
  }
@@ -196,7 +196,9 @@ function buildSections(data = {}) {
196
196
  * getProductPriceDetail data → DetailDialog
197
197
  */
198
198
  export function normalizeDetail(data = {}, options = {}) {
199
- const customerName = options.customerName || data.customerName || ''
199
+ // 详情标题优先接口 customName,其次外部传入 / customerName 兼容字段
200
+ const customerName =
201
+ data.customName || options.customerName || data.customerName || ''
200
202
  const overviewProducts = options.overviewProducts
201
203
  const summaryRows =
202
204
  Array.isArray(overviewProducts) && overviewProducts.length