imeik-bizui 2.6.2 → 2.6.4

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.
@@ -2,18 +2,18 @@
2
2
  通用「底价明细」弹窗(纯展示,无接口依赖)
3
3
  - 顶部汇总:由 Dashboard 传入概览产品行
4
4
  - 下方三区(销售订单 / 非销出库 / 销售费用)等分三列并排
5
- - 分区表格按当前页行数自适应高度,不设固定 height(避免表内纵向滚动裁切)
6
- - 分区数据前端分页(pageSize)
5
+ - 三列明细等高:固定表格高度 + 预留分页条高度
6
+ - 分区数据前端分页(pageSize);无底部关闭按钮,右上角关闭即可
7
7
  -->
8
8
  <template>
9
9
  <el-dialog
10
10
  :visible.sync="dialogVisible"
11
11
  :title="title"
12
- :width="width"
13
- :top="top"
12
+ :width="resolvedWidth"
13
+ :top="resolvedTop"
14
14
  :append-to-body="appendToBody"
15
15
  :destroy-on-close="destroyOnClose"
16
- custom-class="floor-price-detail-dialog"
16
+ :custom-class="dialogCustomClass"
17
17
  @close="onClose"
18
18
  >
19
19
  <div v-loading="loading" class="fpd-body">
@@ -21,6 +21,7 @@
21
21
 
22
22
  <template v-else>
23
23
  <div v-if="summaryColumns.length" class="fpd-summary">
24
+ <div v-if="isNarrow" class="fpd-summary__hint">汇总表可左右滑动</div>
24
25
  <el-table
25
26
  :data="summaryRows"
26
27
  border
@@ -37,7 +38,7 @@
37
38
  :min-width="col.minWidth || col.width || 100"
38
39
  :width="col.fixedWidth"
39
40
  :align="col.align || 'left'"
40
- :fixed="col.fixed"
41
+ :fixed="isNarrow ? false : col.fixed"
41
42
  show-overflow-tooltip
42
43
  >
43
44
  <template slot-scope="{ row }">
@@ -67,6 +68,7 @@
67
68
  <div class="fpd-section__head">
68
69
  <span class="fpd-section__title">{{ section.title }}</span>
69
70
  <span v-if="section.subtitle" class="fpd-section__subtitle">{{ section.subtitle }}</span>
71
+ <span v-if="isNarrow" class="fpd-section__hint">左右滑动查看完整信息</span>
70
72
  </div>
71
73
 
72
74
  <div class="fpd-section__table-wrap">
@@ -75,6 +77,7 @@
75
77
  border
76
78
  size="small"
77
79
  class="fpd-table"
80
+ :height="resolvedTableHeight"
78
81
  :header-cell-style="headerCellStyle"
79
82
  >
80
83
  <el-table-column
@@ -100,7 +103,8 @@
100
103
  :total-count="sectionRowCount(section)"
101
104
  :page="sectionPage(section)"
102
105
  :page-size="pageSize"
103
- :reserve-space="anySectionNeedsPager"
106
+ :reserve-space="showPagerReserve"
107
+ :compact="isNarrow"
104
108
  @update:page="(p) => setSectionPage(section, p)"
105
109
  />
106
110
 
@@ -132,10 +136,6 @@
132
136
  </div>
133
137
  </template>
134
138
  </div>
135
-
136
- <span slot="footer" class="fpd-dialog-footer">
137
- <button type="button" class="fpd-dialog-close-btn" @click="onClose">关闭</button>
138
- </span>
139
139
  </el-dialog>
140
140
  </template>
141
141
 
@@ -203,12 +203,10 @@ export default {
203
203
  type: Array,
204
204
  default: null
205
205
  },
206
- /**
207
- * @deprecated 三区表格已改为按内容撑开,不再使用固定高度(保留 prop 以免业务侧报错)
208
- */
206
+ /** 三列表格统一高度,保证等高 */
209
207
  tableHeight: {
210
208
  type: [Number, String],
211
- default: null
209
+ default: 260
212
210
  },
213
211
  /** 分区前端分页大小 */
214
212
  pageSize: {
@@ -218,7 +216,8 @@ export default {
218
216
  },
219
217
  data() {
220
218
  return {
221
- sectionPages: {}
219
+ sectionPages: {},
220
+ isNarrow: false
222
221
  }
223
222
  },
224
223
  computed: {
@@ -230,6 +229,22 @@ export default {
230
229
  this.$emit('update:visible', val)
231
230
  }
232
231
  },
232
+ dialogCustomClass() {
233
+ return this.isNarrow
234
+ ? 'floor-price-detail-dialog floor-price-detail-dialog--narrow'
235
+ : 'floor-price-detail-dialog'
236
+ },
237
+ resolvedWidth() {
238
+ return this.isNarrow ? 'calc(100% - 28px)' : this.width
239
+ },
240
+ resolvedTop() {
241
+ return this.isNarrow ? '5vh' : this.top
242
+ },
243
+ resolvedTableHeight() {
244
+ const base = Number(this.tableHeight)
245
+ const fallback = Number.isFinite(base) && base > 0 ? base : 260
246
+ return this.isNarrow ? Math.min(fallback, 200) : fallback
247
+ },
233
248
  formulaList() {
234
249
  if (Array.isArray(this.formulas)) return this.formulas
235
250
  return DEFAULT_DETAIL_FORMULAS
@@ -239,6 +254,10 @@ export default {
239
254
  const size = this.pageSize || 5
240
255
  return (this.sections || []).some((section) => this.sectionRowCount(section) > size)
241
256
  },
257
+ /** 窄屏三区已改为单列,无需为空分页占位 */
258
+ showPagerReserve() {
259
+ return this.anySectionNeedsPager && !this.isNarrow
260
+ },
242
261
  headerCellStyle() {
243
262
  return {
244
263
  background: '#fafbfc',
@@ -250,7 +269,10 @@ export default {
250
269
  },
251
270
  watch: {
252
271
  visible(val) {
253
- if (val) this.resetSectionPages()
272
+ if (val) {
273
+ this.updateNarrow()
274
+ this.resetSectionPages()
275
+ }
254
276
  },
255
277
  sections: {
256
278
  deep: true,
@@ -259,7 +281,22 @@ export default {
259
281
  }
260
282
  }
261
283
  },
284
+ mounted() {
285
+ this.updateNarrow()
286
+ if (typeof window !== 'undefined') {
287
+ window.addEventListener('resize', this.updateNarrow)
288
+ }
289
+ },
290
+ beforeDestroy() {
291
+ if (typeof window !== 'undefined') {
292
+ window.removeEventListener('resize', this.updateNarrow)
293
+ }
294
+ },
262
295
  methods: {
296
+ updateNarrow() {
297
+ if (typeof window === 'undefined') return
298
+ this.isNarrow = window.innerWidth <= 768
299
+ },
263
300
  onClose() {
264
301
  this.$emit('close')
265
302
  this.$emit('update:visible', false)
@@ -386,54 +423,57 @@ export default {
386
423
 
387
424
  .el-dialog__body {
388
425
  padding: 18px 20px 16px;
389
- max-height: calc(92vh - 120px);
426
+ max-height: calc(92vh - 64px);
390
427
  overflow: auto;
391
428
  background: #f7f8fa;
392
429
  }
393
430
 
394
431
  .el-dialog__footer {
395
- padding: 12px 20px;
396
- background: #fff;
397
- border-top: 1px solid #e5e7eb;
432
+ display: none;
433
+ padding: 0;
434
+ border: none;
398
435
  }
399
436
  }
400
- </style>
401
-
402
- <style lang="scss" scoped>
403
- .fpd-body {
404
- min-width: 0;
405
- }
406
437
 
407
- .fpd-dialog-footer {
408
- display: flex;
409
- justify-content: flex-end;
410
- }
438
+ @media (max-width: 768px) {
439
+ .floor-price-detail-dialog.floor-price-detail-dialog--narrow {
440
+ width: calc(100% - 28px) !important;
441
+ max-width: 560px;
442
+ margin-bottom: 5vh !important;
443
+ border-radius: 14px;
444
+ border: 1px solid #e4e7ec;
445
+ box-shadow: 0 18px 48px rgba(16, 24, 40, 0.2);
446
+
447
+ .el-dialog__header {
448
+ padding: 14px 16px 12px;
449
+ background: #fff;
450
+ }
411
451
 
412
- .fpd-dialog-close-btn {
413
- min-width: 80px;
414
- height: 34px;
415
- padding: 0 16px;
416
- color: #1f2329;
417
- background: #fff;
418
- border: 1px solid #d3d7de;
419
- border-radius: 6px;
420
- cursor: pointer;
421
- font-size: 14px;
422
- line-height: 1;
452
+ .el-dialog__title {
453
+ font-size: 16px;
454
+ line-height: 24px;
455
+ padding-right: 28px;
456
+ letter-spacing: 0.01em;
457
+ }
423
458
 
424
- &:hover {
425
- color: #3370ff;
426
- border-color: #8babff;
427
- }
459
+ .el-dialog__headerbtn {
460
+ top: 15px;
461
+ right: 14px;
462
+ }
428
463
 
429
- &:focus {
430
- outline: none;
464
+ .el-dialog__body {
465
+ padding: 12px 12px 16px;
466
+ max-height: calc(90vh - 64px);
467
+ background: linear-gradient(180deg, #f4f6f8 0%, #f7f8fa 40%, #f7f8fa 100%);
468
+ -webkit-overflow-scrolling: touch;
469
+ }
431
470
  }
471
+ }
472
+ </style>
432
473
 
433
- &:focus-visible {
434
- outline: 2px solid #3370ff;
435
- outline-offset: 2px;
436
- }
474
+ <style lang="scss" scoped>
475
+ .fpd-body {
476
+ min-width: 0;
437
477
  }
438
478
 
439
479
  .fpd-msg {
@@ -452,24 +492,29 @@ export default {
452
492
  .fpd-summary {
453
493
  margin-bottom: 12px;
454
494
  overflow-x: auto;
495
+ -webkit-overflow-scrolling: touch;
455
496
  background: #fff;
456
497
  border: 1px solid #e5e7eb;
457
498
  border-radius: 8px;
458
499
  }
459
500
 
501
+ .fpd-summary__hint {
502
+ display: none;
503
+ }
504
+
460
505
  .fpd-sections {
461
506
  display: grid;
462
507
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.05fr) minmax(0, 0.9fr);
463
508
  gap: 12px;
464
509
  margin-bottom: 12px;
465
- /* 按内容高度,不强制三列拉齐(数据少时不留大块空白) */
466
- align-items: start;
510
+ align-items: stretch;
467
511
  }
468
512
 
469
513
  .fpd-section {
470
514
  display: flex;
471
515
  flex-direction: column;
472
516
  min-width: 0;
517
+ min-height: 100%;
473
518
  border: 1px solid #e5e7eb;
474
519
  border-radius: 8px;
475
520
  overflow: hidden;
@@ -501,10 +546,15 @@ export default {
501
546
  color: #8f959e;
502
547
  }
503
548
 
549
+ .fpd-section__hint {
550
+ display: none;
551
+ }
552
+
504
553
  .fpd-section__table-wrap {
505
554
  flex: 0 0 auto;
506
555
  min-width: 0;
507
- overflow-x: hidden;
556
+ overflow-x: auto;
557
+ -webkit-overflow-scrolling: touch;
508
558
  }
509
559
 
510
560
  .fpd-section__footer {
@@ -688,4 +738,160 @@ export default {
688
738
  grid-template-columns: 1fr;
689
739
  }
690
740
  }
741
+
742
+ @media (max-width: 768px) {
743
+ .fpd-summary {
744
+ margin-bottom: 12px;
745
+ border-radius: 10px;
746
+ border-color: #e8ebf0;
747
+ box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
748
+ }
749
+
750
+ .fpd-summary__hint,
751
+ .fpd-section__hint {
752
+ display: block;
753
+ padding: 0;
754
+ font-size: 11px;
755
+ line-height: 16px;
756
+ color: #8f959e;
757
+ font-weight: 400;
758
+ }
759
+
760
+ .fpd-summary__hint {
761
+ padding: 8px 12px 0;
762
+ }
763
+
764
+ .fpd-sections {
765
+ gap: 12px;
766
+ margin-bottom: 12px;
767
+ align-items: start;
768
+ }
769
+
770
+ .fpd-section {
771
+ min-height: 0;
772
+ border-radius: 10px;
773
+ border-color: #e8ebf0;
774
+ box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
775
+ }
776
+
777
+ .fpd-section--purple {
778
+ border-color: #e4e0f5;
779
+
780
+ .fpd-section__head {
781
+ background: linear-gradient(90deg, #f6f4ff 0%, #fafbfc 48%);
782
+ border-bottom-color: #ece8f8;
783
+ }
784
+
785
+ .fpd-section__title::before {
786
+ background: #7b61ff;
787
+ }
788
+
789
+ .fpd-section__footer {
790
+ background: #f8f6ff;
791
+ border-top-color: #ece8f8;
792
+ }
793
+ }
794
+
795
+ .fpd-section--danger {
796
+ border-color: #f3d6d2;
797
+
798
+ .fpd-section__head {
799
+ background: linear-gradient(90deg, #fff6f5 0%, #fafbfc 48%);
800
+ border-bottom-color: #f3e0dd;
801
+ }
802
+
803
+ .fpd-section__title::before {
804
+ background: #e45b4c;
805
+ }
806
+
807
+ .fpd-section__footer {
808
+ background: #fff8f7;
809
+ border-top-color: #f3e0dd;
810
+ }
811
+ }
812
+
813
+ .fpd-section__head {
814
+ padding: 10px 12px 8px;
815
+ gap: 4px;
816
+ }
817
+
818
+ .fpd-section__title {
819
+ display: flex;
820
+ align-items: center;
821
+ gap: 8px;
822
+ font-size: 14px;
823
+ line-height: 20px;
824
+
825
+ &::before {
826
+ content: '';
827
+ flex: none;
828
+ width: 3px;
829
+ height: 14px;
830
+ border-radius: 2px;
831
+ background: #3370ff;
832
+ }
833
+ }
834
+
835
+ .fpd-section__footer {
836
+ padding: 9px 12px;
837
+ font-size: 12px;
838
+ }
839
+
840
+ .fpd-section__footer-values {
841
+ font-size: 13px;
842
+ justify-content: flex-end;
843
+ }
844
+
845
+ .fpd-formulas {
846
+ padding: 10px 12px;
847
+ border-radius: 10px;
848
+ border-color: #e8ebf0;
849
+ font-size: 11px;
850
+ line-height: 18px;
851
+ color: #6b7280;
852
+ box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
853
+ }
854
+
855
+ ::v-deep .fpd-table {
856
+ .cell {
857
+ padding: 9px 10px;
858
+ line-height: 20px;
859
+ }
860
+
861
+ .is-right .cell {
862
+ padding-left: 8px;
863
+ padding-right: 12px;
864
+ }
865
+
866
+ .is-center .cell {
867
+ padding-left: 8px;
868
+ padding-right: 8px;
869
+ }
870
+
871
+ th {
872
+ font-size: 12px;
873
+ }
874
+
875
+ td {
876
+ font-size: 12px;
877
+ }
878
+ }
879
+
880
+ ::v-deep .fpd-table--summary {
881
+ min-width: 960px;
882
+
883
+ th .cell,
884
+ td .cell {
885
+ padding-top: 9px;
886
+ padding-bottom: 9px;
887
+ }
888
+ }
889
+
890
+ .fpd-status {
891
+ min-height: 20px;
892
+ min-width: 40px;
893
+ padding: 0 6px;
894
+ font-size: 11px;
895
+ }
896
+ }
691
897
  </style>
@@ -3,13 +3,22 @@
3
3
  <div
4
4
  v-if="needPager || reserveSpace"
5
5
  class="fpd-pager"
6
- :class="{ 'fpd-pager--placeholder': !needPager }"
6
+ :class="{
7
+ 'fpd-pager--placeholder': !needPager,
8
+ 'fpd-pager--compact': compact
9
+ }"
7
10
  >
8
11
  <template v-if="needPager">
9
12
  <span class="fpd-pager__total">共 {{ totalCount }} 条</span>
10
- <button type="button" class="fpd-pager__btn" :disabled="page <= 1" @click="goPrev">&lt; 上一页</button>
11
- <span class="fpd-pager__page">第 {{ page }} / {{ totalPages }} 页</span>
12
- <button type="button" class="fpd-pager__btn" :disabled="page >= totalPages" @click="goNext">下一页 &gt;</button>
13
+ <button type="button" class="fpd-pager__btn" :disabled="page <= 1" @click="goPrev">
14
+ {{ compact ? '< 上页' : '< 上一页' }}
15
+ </button>
16
+ <span class="fpd-pager__page">
17
+ {{ compact ? `${page}/${totalPages}` : `第 ${page} / ${totalPages} 页` }}
18
+ </span>
19
+ <button type="button" class="fpd-pager__btn" :disabled="page >= totalPages" @click="goNext">
20
+ {{ compact ? '下页 >' : '下一页 >' }}
21
+ </button>
13
22
  </template>
14
23
  </div>
15
24
  </template>
@@ -35,6 +44,11 @@ export default {
35
44
  reserveSpace: {
36
45
  type: Boolean,
37
46
  default: false
47
+ },
48
+ /** 窄屏紧凑文案 */
49
+ compact: {
50
+ type: Boolean,
51
+ default: false
38
52
  }
39
53
  },
40
54
  computed: {
@@ -77,6 +91,17 @@ export default {
77
91
  border-top-color: transparent;
78
92
  }
79
93
 
94
+ .fpd-pager--compact {
95
+ gap: 4px 8px;
96
+ padding: 6px 10px;
97
+ min-height: 36px;
98
+
99
+ .fpd-pager__btn {
100
+ min-height: 28px;
101
+ padding: 0 4px;
102
+ }
103
+ }
104
+
80
105
  .fpd-pager__total {
81
106
  margin-right: auto;
82
107
  }
@@ -133,11 +133,11 @@ function buildSections(data = {}) {
133
133
  subtitle: '订单价 × 数量',
134
134
  theme: 'purple',
135
135
  columns: [
136
- { prop: 'orderNum', label: '订单号', minWidth: 120 },
137
- { prop: 'productName', label: '产品', minWidth: 80 },
136
+ { prop: 'orderNum', label: '订单号', minWidth: 140 },
137
+ { prop: 'productName', label: '产品', minWidth: 100 },
138
138
  { prop: 'saleTypeLabel', label: '类型', width: 64 },
139
139
  { prop: 'qty', label: '数量', align: 'right', width: 56 },
140
- { prop: 'amount', label: '金额', type: 'number', digits: 0, align: 'right', width: 88 }
140
+ { prop: 'amount', label: '金额', type: 'number', digits: 0, align: 'right', width: 96 }
141
141
  ],
142
142
  rows: saleRows,
143
143
  footer: {
@@ -154,10 +154,10 @@ function buildSections(data = {}) {
154
154
  subtitle: '折算非销售促进费',
155
155
  theme: 'danger',
156
156
  columns: [
157
- { prop: 'orderNum', label: '出库单号', minWidth: 120 },
158
- { prop: 'productName', label: '产品', minWidth: 80 },
157
+ { prop: 'orderNum', label: '出库单号', minWidth: 140 },
158
+ { prop: 'productName', label: '产品', minWidth: 100 },
159
159
  { prop: 'qty', label: '数量', align: 'right', width: 56 },
160
- { prop: 'amount', label: '折算费用', type: 'number', digits: 0, align: 'right', width: 88 }
160
+ { prop: 'amount', label: '折算费用', type: 'number', digits: 0, align: 'right', width: 96 }
161
161
  ],
162
162
  rows: nonSaleRows,
163
163
  footer: {
@@ -177,9 +177,9 @@ function buildSections(data = {}) {
177
177
  subtitle: '费用申请单口径',
178
178
  theme: 'danger',
179
179
  columns: [
180
- { prop: 'bizOrderCode', label: '单号', minWidth: 100 },
181
- { prop: 'costTypeName', label: '类型', minWidth: 80 },
182
- { prop: 'costAmount', label: '金额', type: 'number', digits: 0, align: 'right', width: 88 }
180
+ { prop: 'bizOrderCode', label: '单号', minWidth: 120 },
181
+ { prop: 'costTypeName', label: '类型', minWidth: 88 },
182
+ { prop: 'costAmount', label: '金额', type: 'number', digits: 0, align: 'right', width: 96 }
183
183
  ],
184
184
  rows: expenseRows,
185
185
  footer: {