imeik-bizui 2.7.7 → 2.7.9
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.
- package/dist/bizui/src/FieldFloorPriceBoard/README.md +4 -1
- package/dist/bizui/src/FieldFloorPriceBoard/core/FloorPriceBoard.vue +98 -8
- package/dist/bizui/src/FieldFloorPriceBoard/core/FloorPriceDashboard.vue +114 -12
- package/dist/bizui/src/FieldFloorPriceBoard/core/FloorPriceDetailDialog.vue +26 -93
- package/dist/bizui/src/FieldFloorPriceBoard/core/FloorPriceDetailInline.vue +739 -0
- package/dist/bizui/src/FieldFloorPriceBoard/core/detailFormat.js +111 -0
- package/dist/bizui/src/FieldFloorPriceBoard/core/normalize.js +11 -10
- package/dist/bizui/src/FieldFloorPriceBoard/core/utils.js +3 -0
- package/dist/bizui/src/FieldFloorPriceBoard/index.vue +14 -0
- package/dist/imeik-bizui.common.js +1036 -442
- package/dist/imeik-bizui.common.js.gz +0 -0
- package/dist/imeik-bizui.css +2 -2
- package/dist/imeik-bizui.css.gz +0 -0
- package/dist/imeik-bizui.umd.js +1036 -442
- package/dist/imeik-bizui.umd.js.gz +0 -0
- package/dist/imeik-bizui.umd.min.js +5 -5
- package/dist/imeik-bizui.umd.min.js.gz +0 -0
- package/package.json +1 -1
|
@@ -30,6 +30,8 @@ imeik-bizui/src/bizui/
|
|
|
30
30
|
/>
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
移动端想保留弹窗:加 `narrow-detail-mode="dialog"`(默认 `inline`,在看板下方展开)。
|
|
34
|
+
|
|
33
35
|
`scene`:`supplies` | `meeting` | `apply` / `applyCenter`。
|
|
34
36
|
|
|
35
37
|
请求体组装在业务系统(如会议 `buildFloorPricePayload.js`)。
|
|
@@ -55,7 +57,8 @@ bizui: scene 选接口 → Dashboard 拉数 → Board / Detail
|
|
|
55
57
|
|
|
56
58
|
| 类型 | 内容 |
|
|
57
59
|
| --- | --- |
|
|
58
|
-
| Props | `scene`、`requestPayload`、`customerName`、`showDetailLink`、`useMock`、`emptyText` |
|
|
60
|
+
| Props | `scene`、`requestPayload`、`customerName`、`showDetailLink`、`narrowDetailMode`、`useMock`、`emptyText` |
|
|
61
|
+
| 明细形态 | 宽屏始终弹窗;窄屏 / 移动端(≤768px)由 `narrowDetailMode` 决定:`inline`(默认,看板下方展开)或 `dialog`(弹窗) |
|
|
59
62
|
| 物资入参 | `customUniqueCode`、`businessLineNumber`、`isGroupCustomer`、`applyDeptCode`、`costBearDeptCode`、`costType`、`materialList[]`(允许 `[]`) |
|
|
60
63
|
| 会议入参 | `meetTypeCode`、`meetFormJson`、`customUniqueCode`、`forceRefresh`;`meetCode` 有值才传 |
|
|
61
64
|
| 申请中心入参 | 见丽臻底价接口文档 |
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
<div v-if="error" class="fpb-msg fpb-msg--error">{{ error }}</div>
|
|
20
20
|
|
|
21
21
|
<div v-else-if="hasContent" :class="['fpb-panel', panelThemeClass]" role="status">
|
|
22
|
-
<div class="fpb-result">
|
|
22
|
+
<div :class="['fpb-result', { 'fpb-result--with-link': showDetailLink }]">
|
|
23
23
|
<div class="fpb-result__main">
|
|
24
24
|
<div class="fpb-result__heading">
|
|
25
25
|
<img
|
|
@@ -1083,35 +1083,125 @@ export default {
|
|
|
1083
1083
|
|
|
1084
1084
|
@media (max-width: 640px) {
|
|
1085
1085
|
.fpb-panel {
|
|
1086
|
-
padding:
|
|
1086
|
+
padding: 12px;
|
|
1087
1087
|
}
|
|
1088
1088
|
|
|
1089
|
+
/* 链接钉在标题行右侧,说明文字可占满整行 */
|
|
1089
1090
|
.fpb-result {
|
|
1090
|
-
|
|
1091
|
-
|
|
1091
|
+
position: relative;
|
|
1092
|
+
display: block;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
.fpb-result__heading {
|
|
1096
|
+
gap: 6px 8px;
|
|
1097
|
+
margin-bottom: 4px;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
.fpb-result--with-link .fpb-result__heading {
|
|
1101
|
+
padding-right: 104px;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
.fpb-mark {
|
|
1105
|
+
width: 22px;
|
|
1106
|
+
height: 22px;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
.fpb-result__title {
|
|
1110
|
+
font-size: 15px;
|
|
1111
|
+
line-height: 22px;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
.fpb-badge {
|
|
1115
|
+
min-height: 22px;
|
|
1116
|
+
padding: 0 8px;
|
|
1117
|
+
border-radius: 4px;
|
|
1118
|
+
font-size: 12px;
|
|
1119
|
+
line-height: 18px;
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
.fpb-result__desc {
|
|
1123
|
+
font-size: 12px;
|
|
1124
|
+
line-height: 18px;
|
|
1092
1125
|
}
|
|
1093
1126
|
|
|
1094
1127
|
.fpb-link {
|
|
1095
|
-
|
|
1128
|
+
position: absolute;
|
|
1129
|
+
top: 0;
|
|
1130
|
+
right: 0;
|
|
1131
|
+
min-height: 22px;
|
|
1132
|
+
font-size: 13px;
|
|
1133
|
+
line-height: 22px;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
.fpb-list {
|
|
1137
|
+
gap: 8px;
|
|
1138
|
+
margin-top: 10px;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
.fpb-card {
|
|
1142
|
+
padding: 10px 12px;
|
|
1143
|
+
border-radius: 6px;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
.fpb-card__topline {
|
|
1147
|
+
gap: 6px 8px;
|
|
1148
|
+
margin-bottom: 8px;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
.fpb-card-title {
|
|
1152
|
+
font-size: 14px;
|
|
1153
|
+
line-height: 20px;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
.fpb-card__tag {
|
|
1157
|
+
min-height: 20px;
|
|
1158
|
+
padding: 0 6px;
|
|
1159
|
+
font-size: 11px;
|
|
1096
1160
|
}
|
|
1097
1161
|
|
|
1162
|
+
/* 与下方「申请前 / 申请后」重复,窄屏省掉这一行 */
|
|
1098
1163
|
.fpb-card__shift {
|
|
1099
|
-
|
|
1100
|
-
width: 100%;
|
|
1164
|
+
display: none;
|
|
1101
1165
|
}
|
|
1102
1166
|
|
|
1103
1167
|
.fpb-price-grid {
|
|
1104
1168
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1169
|
+
gap: 6px 12px;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
.fpb-price-item {
|
|
1173
|
+
dt {
|
|
1174
|
+
margin-bottom: 1px;
|
|
1175
|
+
font-size: 11px;
|
|
1176
|
+
line-height: 16px;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
dd {
|
|
1180
|
+
font-size: 14px;
|
|
1181
|
+
line-height: 20px;
|
|
1182
|
+
|
|
1183
|
+
&.is-strong {
|
|
1184
|
+
font-size: 15px;
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1105
1187
|
}
|
|
1106
1188
|
|
|
1107
1189
|
.fpb-footer {
|
|
1108
1190
|
flex-direction: column;
|
|
1109
|
-
gap:
|
|
1191
|
+
gap: 4px;
|
|
1192
|
+
margin-top: 10px;
|
|
1193
|
+
padding-top: 8px;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
.fpb-footer__note {
|
|
1197
|
+
font-size: 11px;
|
|
1198
|
+
line-height: 16px;
|
|
1110
1199
|
}
|
|
1111
1200
|
|
|
1112
1201
|
.fpb-footer__meta {
|
|
1113
1202
|
justify-content: flex-start;
|
|
1114
1203
|
flex-wrap: wrap;
|
|
1204
|
+
line-height: 18px;
|
|
1115
1205
|
}
|
|
1116
1206
|
}
|
|
1117
1207
|
</style>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
通用底价看板(展示 + 拉数编排)
|
|
3
3
|
|
|
4
|
-
职责:防抖请求、normalize、看板/明细 UI
|
|
4
|
+
职责:防抖请求、normalize、看板/明细 UI(宽屏弹窗;≤ NARROW_BREAKPOINT 按 narrowDetailMode 就地展开或弹窗)。
|
|
5
5
|
不负责:各业务域字段映射、拼请求体 —— 由业务系统组装后经 FieldFloorPriceBoard 传入。
|
|
6
6
|
|
|
7
7
|
推荐:业务侧挂 <FieldFloorPriceBoard scene="..." :request-payload="..." />
|
|
@@ -24,11 +24,23 @@
|
|
|
24
24
|
:year="board.year"
|
|
25
25
|
:footer-text="board.footerText"
|
|
26
26
|
:show-detail-link="showDetailLink"
|
|
27
|
+
:detail-link-text="detailLinkText"
|
|
27
28
|
:use-demo="useDemo"
|
|
28
29
|
:empty-text="emptyText"
|
|
29
30
|
@view-detail="onViewDetail"
|
|
30
31
|
@toggle-demo="onToggleDemo"
|
|
31
32
|
/>
|
|
33
|
+
<FloorPriceDetailInline
|
|
34
|
+
v-if="useInlineDetail && inlineOpen"
|
|
35
|
+
:loading="detailLoading"
|
|
36
|
+
:error="detailError"
|
|
37
|
+
:title="detailView.title"
|
|
38
|
+
:summary-columns="detailView.summaryColumns"
|
|
39
|
+
:summary-rows="detailView.summaryRows"
|
|
40
|
+
:sections="detailView.sections"
|
|
41
|
+
:formulas="detailView.formulas"
|
|
42
|
+
@collapse="collapseInline"
|
|
43
|
+
/>
|
|
32
44
|
<FloorPriceDetailDialog
|
|
33
45
|
:visible.sync="detailVisible"
|
|
34
46
|
:loading="detailLoading"
|
|
@@ -45,9 +57,10 @@
|
|
|
45
57
|
<script>
|
|
46
58
|
import FloorPriceBoard from './FloorPriceBoard.vue'
|
|
47
59
|
import FloorPriceDetailDialog from './FloorPriceDetailDialog.vue'
|
|
60
|
+
import FloorPriceDetailInline from './FloorPriceDetailInline.vue'
|
|
48
61
|
import { createDemoDetail, createDemoOverview, nextDemoState } from './mock'
|
|
49
62
|
import { normalizeDetail, normalizeOverview } from './normalize'
|
|
50
|
-
import { PANEL_STATE } from './utils'
|
|
63
|
+
import { NARROW_BREAKPOINT, PANEL_STATE } from './utils'
|
|
51
64
|
|
|
52
65
|
const EMPTY_DETAIL = {
|
|
53
66
|
title: '底价明细',
|
|
@@ -79,7 +92,8 @@ export default {
|
|
|
79
92
|
name: 'FloorPriceDashboard',
|
|
80
93
|
components: {
|
|
81
94
|
FloorPriceBoard,
|
|
82
|
-
FloorPriceDetailDialog
|
|
95
|
+
FloorPriceDetailDialog,
|
|
96
|
+
FloorPriceDetailInline
|
|
83
97
|
},
|
|
84
98
|
props: {
|
|
85
99
|
// ——— 受控:外部已拉好数 ———
|
|
@@ -109,6 +123,14 @@ export default {
|
|
|
109
123
|
title: { type: String, default: '底价信息' },
|
|
110
124
|
showTitle: { type: Boolean, default: false },
|
|
111
125
|
showDetailLink: { type: Boolean, default: true },
|
|
126
|
+
/** 窄屏(≤ NARROW_BREAKPOINT)明细形态:inline 看板下方展开 | dialog 弹窗;宽屏恒为弹窗 */
|
|
127
|
+
narrowDetailMode: {
|
|
128
|
+
type: String,
|
|
129
|
+
default: 'inline',
|
|
130
|
+
validator(v) {
|
|
131
|
+
return ['inline', 'dialog'].includes(v)
|
|
132
|
+
}
|
|
133
|
+
},
|
|
112
134
|
useDemo: { type: Boolean, default: false },
|
|
113
135
|
customerName: { type: String, default: '' },
|
|
114
136
|
/** 无概览数据时的空态文案 */
|
|
@@ -123,6 +145,10 @@ export default {
|
|
|
123
145
|
detailLoading: false,
|
|
124
146
|
detailError: '',
|
|
125
147
|
innerDetail: null,
|
|
148
|
+
/** 已加载明细对应的概览入参签名;与当前不一致时视为过期 */
|
|
149
|
+
detailLoadedSig: null,
|
|
150
|
+
isNarrow: false,
|
|
151
|
+
inlineOpen: false,
|
|
126
152
|
debouncedFetch: null,
|
|
127
153
|
/** demo 三态:blocked → pass → exempt → … */
|
|
128
154
|
demoState: PANEL_STATE.BLOCKED
|
|
@@ -175,6 +201,13 @@ export default {
|
|
|
175
201
|
},
|
|
176
202
|
overviewSignature() {
|
|
177
203
|
return JSON.stringify(this.overviewPayload || null)
|
|
204
|
+
},
|
|
205
|
+
useInlineDetail() {
|
|
206
|
+
return this.isNarrow && this.narrowDetailMode === 'inline'
|
|
207
|
+
},
|
|
208
|
+
detailLinkText() {
|
|
209
|
+
if (!this.useInlineDetail) return '查看底价明细 →'
|
|
210
|
+
return this.inlineOpen ? '收起底价明细 ↑' : '查看底价明细 ↓'
|
|
178
211
|
}
|
|
179
212
|
},
|
|
180
213
|
watch: {
|
|
@@ -192,24 +225,47 @@ export default {
|
|
|
192
225
|
} else if (this.selfFetch) {
|
|
193
226
|
this.scheduleFetch()
|
|
194
227
|
}
|
|
228
|
+
},
|
|
229
|
+
/** 跨断点或切换配置时两种形态互换:已开弹窗 → 就地展开;离开内联不自动弹窗 */
|
|
230
|
+
useInlineDetail(inline) {
|
|
231
|
+
if (inline && this.detailVisible) {
|
|
232
|
+
this.detailVisible = false
|
|
233
|
+
this.inlineOpen = true
|
|
234
|
+
} else if (!inline) {
|
|
235
|
+
this.inlineOpen = false
|
|
236
|
+
}
|
|
195
237
|
}
|
|
196
238
|
},
|
|
197
239
|
created() {
|
|
240
|
+
this._detailReqSeq = 0
|
|
198
241
|
this.debouncedFetch = debounce(this.runFetch, this.debounceMs)
|
|
199
242
|
if (this.selfFetch) this.debouncedFetch()
|
|
200
243
|
},
|
|
244
|
+
mounted() {
|
|
245
|
+
this.updateNarrow()
|
|
246
|
+
if (typeof window !== 'undefined') {
|
|
247
|
+
window.addEventListener('resize', this.updateNarrow)
|
|
248
|
+
}
|
|
249
|
+
},
|
|
201
250
|
beforeDestroy() {
|
|
202
251
|
if (this.debouncedFetch && this.debouncedFetch.cancel) {
|
|
203
252
|
this.debouncedFetch.cancel()
|
|
204
253
|
}
|
|
254
|
+
if (typeof window !== 'undefined') {
|
|
255
|
+
window.removeEventListener('resize', this.updateNarrow)
|
|
256
|
+
}
|
|
205
257
|
},
|
|
206
258
|
methods: {
|
|
259
|
+
updateNarrow() {
|
|
260
|
+
if (typeof window === 'undefined') return
|
|
261
|
+
this.isNarrow = window.innerWidth <= NARROW_BREAKPOINT
|
|
262
|
+
},
|
|
207
263
|
/** Mock 按钮:循环切换 禁止 → 通过 → 免于监控 */
|
|
208
264
|
onToggleDemo() {
|
|
209
265
|
if (!this.useDemo) return
|
|
210
266
|
this.demoState = nextDemoState(this.demoState)
|
|
211
267
|
// 明细若已打开,随概览产品行一起刷新汇总
|
|
212
|
-
if (this.detailVisible) {
|
|
268
|
+
if (this.detailVisible || this.inlineOpen) {
|
|
213
269
|
this.innerDetail = createDemoDetail({
|
|
214
270
|
...this.board,
|
|
215
271
|
customerName: this.board.customerName || this.customerName
|
|
@@ -246,16 +302,54 @@ export default {
|
|
|
246
302
|
} finally {
|
|
247
303
|
this.innerLoading = false
|
|
248
304
|
}
|
|
305
|
+
this.syncInlineAfterOverview()
|
|
249
306
|
},
|
|
250
|
-
|
|
307
|
+
/** 内联已展开时:概览没了就收起,入参变了就重拉明细 */
|
|
308
|
+
syncInlineAfterOverview() {
|
|
309
|
+
if (!this.useInlineDetail || !this.inlineOpen) return
|
|
310
|
+
if (!this.innerOverview) {
|
|
311
|
+
this.inlineOpen = false
|
|
312
|
+
return
|
|
313
|
+
}
|
|
314
|
+
if (this.detailLoadedSig !== this.overviewSignature) this.loadDetailData()
|
|
315
|
+
},
|
|
316
|
+
onViewDetail() {
|
|
317
|
+
if (this.useInlineDetail) {
|
|
318
|
+
this.toggleInline()
|
|
319
|
+
return
|
|
320
|
+
}
|
|
321
|
+
this.detailVisible = true
|
|
322
|
+
this.loadDetailData()
|
|
323
|
+
},
|
|
324
|
+
toggleInline() {
|
|
325
|
+
if (this.inlineOpen) {
|
|
326
|
+
this.inlineOpen = false
|
|
327
|
+
return
|
|
328
|
+
}
|
|
329
|
+
this.inlineOpen = true
|
|
330
|
+
const hasDetail = !!(this.innerDetail || this.detail)
|
|
331
|
+
const stale = this.detailLoadedSig !== this.overviewSignature
|
|
332
|
+
if (this.useDemo || this.detailError || !hasDetail || stale) this.loadDetailData()
|
|
333
|
+
},
|
|
334
|
+
collapseInline() {
|
|
335
|
+
this.inlineOpen = false
|
|
336
|
+
this.$nextTick(() => {
|
|
337
|
+
const el = this.$el
|
|
338
|
+
if (!el || typeof el.getBoundingClientRect !== 'function') return
|
|
339
|
+
if (el.getBoundingClientRect().top < 0) el.scrollIntoView({ block: 'start' })
|
|
340
|
+
})
|
|
341
|
+
},
|
|
342
|
+
async loadDetailData() {
|
|
343
|
+
const reqId = ++this._detailReqSeq
|
|
344
|
+
const isLatest = () => reqId === this._detailReqSeq
|
|
345
|
+
const sig = this.overviewSignature
|
|
251
346
|
this.detailError = ''
|
|
252
|
-
// 先进入 loading
|
|
347
|
+
// 先进入 loading 再展示,避免首帧只有公式行的窄框
|
|
253
348
|
const willFetch =
|
|
254
349
|
this.useDemo ||
|
|
255
350
|
typeof this.fetchDetail === 'function' ||
|
|
256
351
|
typeof this.loadDetail === 'function'
|
|
257
352
|
if (willFetch) this.detailLoading = true
|
|
258
|
-
this.detailVisible = true
|
|
259
353
|
|
|
260
354
|
if (this.useDemo) {
|
|
261
355
|
try {
|
|
@@ -263,6 +357,7 @@ export default {
|
|
|
263
357
|
...this.board,
|
|
264
358
|
customerName: this.board.customerName || this.customerName
|
|
265
359
|
})
|
|
360
|
+
this.detailLoadedSig = sig
|
|
266
361
|
} finally {
|
|
267
362
|
this.detailLoading = false
|
|
268
363
|
}
|
|
@@ -280,24 +375,26 @@ export default {
|
|
|
280
375
|
const detailPayload = this.detailPayload
|
|
281
376
|
if (!detailPayload) {
|
|
282
377
|
this.innerDetail = base
|
|
283
|
-
this.
|
|
378
|
+
this.detailLoadedSig = sig
|
|
284
379
|
return
|
|
285
380
|
}
|
|
286
381
|
const res = await this.fetchDetail(detailPayload)
|
|
382
|
+
if (!isLatest()) return
|
|
287
383
|
if (res && res.code === 200) {
|
|
288
384
|
// 保留接口 customName,勿用空 prop 覆盖
|
|
289
385
|
this.innerDetail = {
|
|
290
386
|
...base,
|
|
291
387
|
...(res.data || {})
|
|
292
388
|
}
|
|
389
|
+
this.detailLoadedSig = sig
|
|
293
390
|
} else {
|
|
294
391
|
this.innerDetail = null
|
|
295
392
|
throw new Error((res && res.message) || '底价明细获取失败')
|
|
296
393
|
}
|
|
297
394
|
} catch (e) {
|
|
298
|
-
this.detailError = (e && e.message) || '底价明细获取失败'
|
|
395
|
+
if (isLatest()) this.detailError = (e && e.message) || '底价明细获取失败'
|
|
299
396
|
} finally {
|
|
300
|
-
this.detailLoading = false
|
|
397
|
+
if (isLatest()) this.detailLoading = false
|
|
301
398
|
}
|
|
302
399
|
return
|
|
303
400
|
}
|
|
@@ -305,13 +402,16 @@ export default {
|
|
|
305
402
|
if (typeof this.loadDetail === 'function') {
|
|
306
403
|
try {
|
|
307
404
|
const data = await this.loadDetail({ overview: this.board, raw: this.rawOverview })
|
|
405
|
+
if (!isLatest()) return
|
|
308
406
|
this.innerDetail = data || null
|
|
309
|
-
if (
|
|
407
|
+
if (data) this.detailLoadedSig = sig
|
|
408
|
+
else this.detailError = '暂无底价明细'
|
|
310
409
|
} catch (e) {
|
|
410
|
+
if (!isLatest()) return
|
|
311
411
|
this.innerDetail = null
|
|
312
412
|
this.detailError = (e && e.message) || '底价明细获取失败'
|
|
313
413
|
} finally {
|
|
314
|
-
this.detailLoading = false
|
|
414
|
+
if (isLatest()) this.detailLoading = false
|
|
315
415
|
}
|
|
316
416
|
return
|
|
317
417
|
}
|
|
@@ -331,5 +431,7 @@ export default {
|
|
|
331
431
|
padding: 0;
|
|
332
432
|
box-sizing: border-box;
|
|
333
433
|
min-width: 0;
|
|
434
|
+
/* 收起明细回滚时给宿主固定顶栏留位 */
|
|
435
|
+
scroll-margin-top: 80px;
|
|
334
436
|
}
|
|
335
437
|
</style>
|
|
@@ -172,8 +172,8 @@
|
|
|
172
172
|
</template>
|
|
173
173
|
|
|
174
174
|
<script>
|
|
175
|
-
import {
|
|
176
|
-
import
|
|
175
|
+
import { NARROW_BREAKPOINT } from './utils'
|
|
176
|
+
import detailFormat from './detailFormat'
|
|
177
177
|
import FloorPriceSectionPager from './FloorPriceSectionPager.vue'
|
|
178
178
|
|
|
179
179
|
export default {
|
|
@@ -181,6 +181,7 @@ export default {
|
|
|
181
181
|
components: {
|
|
182
182
|
FloorPriceSectionPager
|
|
183
183
|
},
|
|
184
|
+
mixins: [detailFormat],
|
|
184
185
|
props: {
|
|
185
186
|
visible: {
|
|
186
187
|
type: Boolean,
|
|
@@ -253,8 +254,7 @@ export default {
|
|
|
253
254
|
data() {
|
|
254
255
|
return {
|
|
255
256
|
sectionPages: {},
|
|
256
|
-
isNarrow: false
|
|
257
|
-
displayMode: getDisplayMode()
|
|
257
|
+
isNarrow: false
|
|
258
258
|
}
|
|
259
259
|
},
|
|
260
260
|
computed: {
|
|
@@ -288,22 +288,6 @@ export default {
|
|
|
288
288
|
const headH = this.isNarrow ? 36 : 38
|
|
289
289
|
return headH + size * rowH
|
|
290
290
|
},
|
|
291
|
-
formulaList() {
|
|
292
|
-
if (Array.isArray(this.formulas)) return this.formulas
|
|
293
|
-
return DEFAULT_DETAIL_FORMULAS
|
|
294
|
-
},
|
|
295
|
-
/** 拆成「指标名 = 表达式」,便于加粗高亮 */
|
|
296
|
-
formulaItems() {
|
|
297
|
-
return (this.formulaList || []).map((line) => {
|
|
298
|
-
const text = String(line || '').trim()
|
|
299
|
-
const idx = text.indexOf('=')
|
|
300
|
-
if (idx < 0) return { key: text, expr: '' }
|
|
301
|
-
return {
|
|
302
|
-
key: text.slice(0, idx).trim(),
|
|
303
|
-
expr: text.slice(idx + 1).trim()
|
|
304
|
-
}
|
|
305
|
-
}).filter((item) => item.key)
|
|
306
|
-
},
|
|
307
291
|
/** 有汇总或分区时视为已有明细内容(可在旧数据上盖 loading) */
|
|
308
292
|
hasDetailContent() {
|
|
309
293
|
return (this.summaryColumns && this.summaryColumns.length > 0) ||
|
|
@@ -350,20 +334,16 @@ export default {
|
|
|
350
334
|
if (typeof window !== 'undefined') {
|
|
351
335
|
window.addEventListener('resize', this.updateNarrow)
|
|
352
336
|
}
|
|
353
|
-
this._unsubDisplayMode = subscribeDisplayMode((mode) => {
|
|
354
|
-
this.displayMode = mode
|
|
355
|
-
})
|
|
356
337
|
},
|
|
357
338
|
beforeDestroy() {
|
|
358
339
|
if (typeof window !== 'undefined') {
|
|
359
340
|
window.removeEventListener('resize', this.updateNarrow)
|
|
360
341
|
}
|
|
361
|
-
if (this._unsubDisplayMode) this._unsubDisplayMode()
|
|
362
342
|
},
|
|
363
343
|
methods: {
|
|
364
344
|
updateNarrow() {
|
|
365
345
|
if (typeof window === 'undefined') return
|
|
366
|
-
this.isNarrow = window.innerWidth <=
|
|
346
|
+
this.isNarrow = window.innerWidth <= NARROW_BREAKPOINT
|
|
367
347
|
},
|
|
368
348
|
onClose() {
|
|
369
349
|
this.$emit('close')
|
|
@@ -401,74 +381,6 @@ export default {
|
|
|
401
381
|
const start = (page - 1) * size
|
|
402
382
|
return rows.slice(start, start + size)
|
|
403
383
|
},
|
|
404
|
-
formatCell(value, col = {}) {
|
|
405
|
-
if (col.type === 'number' || col.type === 'highlight' || col.digits != null) {
|
|
406
|
-
return formatNumber(value, {
|
|
407
|
-
digits: col.digits != null ? col.digits : null,
|
|
408
|
-
mode: this.displayMode,
|
|
409
|
-
fallback: '-'
|
|
410
|
-
})
|
|
411
|
-
}
|
|
412
|
-
if (value === undefined || value === null || value === '') return '-'
|
|
413
|
-
return String(value)
|
|
414
|
-
},
|
|
415
|
-
formatGapCell(value, col = {}) {
|
|
416
|
-
return formatSignedNumber(value, {
|
|
417
|
-
digits: col.digits != null ? col.digits : null,
|
|
418
|
-
mode: this.displayMode,
|
|
419
|
-
fallback: '-'
|
|
420
|
-
})
|
|
421
|
-
},
|
|
422
|
-
formatFooterValue(v) {
|
|
423
|
-
if (v == null) return ''
|
|
424
|
-
if (typeof v !== 'object') return String(v)
|
|
425
|
-
if (v.kind === 'qty') {
|
|
426
|
-
const n = v.value == null ? '-' : String(v.value)
|
|
427
|
-
return v.label ? `${v.label} ${n}` : n
|
|
428
|
-
}
|
|
429
|
-
const body = formatNumber(v.value, { mode: this.displayMode, fallback: '-' })
|
|
430
|
-
return v.label ? `${v.label} ${body}` : body
|
|
431
|
-
},
|
|
432
|
-
gapClass(value, row) {
|
|
433
|
-
const n = Number(value != null ? value : row && row.gap)
|
|
434
|
-
if (Number.isNaN(n) || n >= 0) return ''
|
|
435
|
-
return 'fpd-td--danger'
|
|
436
|
-
},
|
|
437
|
-
statusText(row, col) {
|
|
438
|
-
if (col.statusMap && row[col.prop] != null && col.statusMap[row[col.prop]]) {
|
|
439
|
-
return col.statusMap[row[col.prop]]
|
|
440
|
-
}
|
|
441
|
-
if (row.statusLabel) return row.statusLabel
|
|
442
|
-
return row.hit ? '禁止' : '通过'
|
|
443
|
-
},
|
|
444
|
-
statusClass(row) {
|
|
445
|
-
if (row.statusTone === 'danger' || row.statusTone === 'ok') {
|
|
446
|
-
return row.statusTone === 'danger' ? 'fpd-status--danger' : 'fpd-status--ok'
|
|
447
|
-
}
|
|
448
|
-
return row.hit ? 'fpd-status--danger' : 'fpd-status--ok'
|
|
449
|
-
},
|
|
450
|
-
highlightClass(row, col) {
|
|
451
|
-
const tone = col.highlightTone || row[col.toneField] || 'current'
|
|
452
|
-
if (tone === 'danger') return 'fpd-td--danger fpd-td--bold'
|
|
453
|
-
if (tone === 'ok') return 'fpd-td--ok fpd-td--bold'
|
|
454
|
-
return 'fpd-td--current fpd-td--bold'
|
|
455
|
-
},
|
|
456
|
-
/** 申请后底价:低于标准时标红 */
|
|
457
|
-
summaryCellClass(row, col) {
|
|
458
|
-
const classes = []
|
|
459
|
-
if (col.bold) classes.push('fpd-td--bold')
|
|
460
|
-
if (col.prop === 'afterPrice' && row && row.hit) {
|
|
461
|
-
classes.push('fpd-td--danger')
|
|
462
|
-
}
|
|
463
|
-
return classes
|
|
464
|
-
},
|
|
465
|
-
cellToneClass(row, col) {
|
|
466
|
-
if (row.current || row.isCurrent || (col.currentField && row[col.currentField])) {
|
|
467
|
-
return 'fpd-td--current'
|
|
468
|
-
}
|
|
469
|
-
if (col.tone === 'danger') return 'fpd-td--danger'
|
|
470
|
-
return ''
|
|
471
|
-
},
|
|
472
384
|
sectionThemeClass(section) {
|
|
473
385
|
const t = section.theme || 'default'
|
|
474
386
|
return `fpd-section--${t}`
|
|
@@ -808,6 +720,14 @@ export default {
|
|
|
808
720
|
background-color: transparent !important;
|
|
809
721
|
}
|
|
810
722
|
|
|
723
|
+
/*
|
|
724
|
+
* 右固定列的左分割线原本是前一列的 border-right,属于主表;
|
|
725
|
+
* 列宽有小数时会被固定层盖住,故由固定列自绘左线
|
|
726
|
+
*/
|
|
727
|
+
.el-table__fixed-right .el-table__cell:not(.is-hidden):not(.gutter) {
|
|
728
|
+
box-shadow: inset 1px 0 0 #eef0f3;
|
|
729
|
+
}
|
|
730
|
+
|
|
811
731
|
.el-table__header-wrapper,
|
|
812
732
|
.el-table__body-wrapper {
|
|
813
733
|
width: 100% !important;
|
|
@@ -1004,6 +924,19 @@ export default {
|
|
|
1004
924
|
color: #4e5969;
|
|
1005
925
|
}
|
|
1006
926
|
|
|
927
|
+
/* 三栏并排放不下各表最小列宽:首区独占一行,其余两区并排 */
|
|
928
|
+
@media (min-width: 1101px) and (max-width: 1360px) {
|
|
929
|
+
.fpd-sections,
|
|
930
|
+
.fpd-skeleton__sections {
|
|
931
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
.fpd-section:first-child:nth-last-child(3),
|
|
935
|
+
.fpd-skeleton__section:first-child {
|
|
936
|
+
grid-column: 1 / -1;
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
1007
940
|
@media (max-width: 1100px) {
|
|
1008
941
|
.fpd-sections,
|
|
1009
942
|
.fpd-skeleton__sections {
|