imeik-bizui 2.8.3 → 2.8.5

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.
@@ -59,7 +59,7 @@ bizui: scene 选接口 → Dashboard 拉数 → Overview / Detail
59
59
  | 类型 | 内容 |
60
60
  | --- | --- |
61
61
  | Props | `scene`、`requestPayload`、`showDetailLink`、`narrowDetailMode`、`useMock`、`emptyText`、`debounceMs` |
62
- | Events | `submit-blocked`:`{ blocked, warn }`(禁止提交 / 预警) |
62
+ | Events | `submit-blocked`:`{ blocked, warn }`(禁止提交 / 预警);`board-visible`:`{ visible, status }`(`status=免于管控` 时 `visible=false`,宿主应隐藏含标题的整块) |
63
63
  | 明细形态 | 宽屏始终弹窗;窄屏(≤768px)由 `narrowDetailMode`:`inline`(默认)或 `dialog` |
64
64
  | 物资 · 查看 | `{ applyNumber }`(真实申请单号,不是 objectCode) |
65
65
  | 物资 · 实时 | `{ costBearEmployeeNo, costType, materialList[] }`;`materialList` **允许 `[]`**;可选 `budgetDate` |
@@ -5,7 +5,8 @@
5
5
  不负责:各业务域字段映射、拼请求体 —— 由业务系统组装后经 FieldPersonBudgetBoard 传入。
6
6
  -->
7
7
  <template>
8
- <div class="person-budget-dashboard">
8
+ <!-- 免于管控时不渲染看板 UI;组件保持挂载以便表单变化后重查 -->
9
+ <div v-if="!isExempt" class="person-budget-dashboard">
9
10
  <PersonBudgetOverview
10
11
  :overview="overview"
11
12
  :loading="loading"
@@ -128,6 +129,8 @@ export default {
128
129
  loading: false,
129
130
  error: '',
130
131
  overview: null,
132
+ /** 接口判定免于管控后隐藏看板;配置态 mock 不走此逻辑 */
133
+ isExempt: false,
131
134
  detailVisible: false,
132
135
  inlineOpen: false,
133
136
  isNarrow: false,
@@ -158,7 +161,9 @@ export default {
158
161
  this.overview = createDemoOverview()
159
162
  this.error = ''
160
163
  this.loading = false
164
+ this.isExempt = false
161
165
  this.emitSubmitBlocked(false, false)
166
+ this.emitBoardVisible(true, '')
162
167
  return
163
168
  }
164
169
  if (this.debouncedFetch) this.debouncedFetch()
@@ -205,19 +210,27 @@ export default {
205
210
  emitSubmitBlocked(blocked, warn) {
206
211
  this.$emit('submit-blocked', { blocked: !!blocked, warn: !!warn })
207
212
  },
213
+ /** 通知宿主是否展示整块(含标题);免于管控时 visible=false */
214
+ emitBoardVisible(visible, status) {
215
+ this.$emit('board-visible', { visible: !!visible, status: status || '' })
216
+ },
208
217
  clearBoard() {
209
218
  this.overview = null
210
219
  this.error = ''
211
220
  this.loading = false
212
221
  this.inlineOpen = false
222
+ this.isExempt = false
213
223
  this.emitSubmitBlocked(false, false)
224
+ this.emitBoardVisible(true, '')
214
225
  },
215
226
  async fetchOverviewNow() {
216
227
  if (this.useDemo) {
217
228
  this.overview = createDemoOverview()
218
229
  this.error = ''
219
230
  this.loading = false
231
+ this.isExempt = false
220
232
  this.emitSubmitBlocked(false, false)
233
+ this.emitBoardVisible(true, '')
221
234
  return
222
235
  }
223
236
 
@@ -232,6 +245,9 @@ export default {
232
245
 
233
246
  this.loading = true
234
247
  this.error = ''
248
+ // 请求中保持可见,避免宿主拆掉组件导致无法重查
249
+ this.isExempt = false
250
+ this.emitBoardVisible(true, '')
235
251
  try {
236
252
  const res = await this.fetchOverview(payload)
237
253
  if (seq !== this.reqSeq || sig !== payloadSignature(this.requestPayload)) return
@@ -239,21 +255,40 @@ export default {
239
255
  if (!res || res.code !== 200) {
240
256
  this.overview = null
241
257
  this.error = (res && res.message) || '个人预算概述获取失败'
258
+ this.isExempt = false
259
+ this.emitSubmitBlocked(false, false)
260
+ this.emitBoardVisible(true, '')
261
+ return
262
+ }
263
+
264
+ const data = res.data || null
265
+ const status = normalizeBudgetStatus(data && data.status)
266
+
267
+ if (status === BUDGET_STATUS.EXEMPT) {
268
+ this.overview = null
269
+ this.error = ''
270
+ this.inlineOpen = false
271
+ this.detailVisible = false
272
+ this.isExempt = true
242
273
  this.emitSubmitBlocked(false, false)
274
+ this.emitBoardVisible(false, status)
243
275
  return
244
276
  }
245
277
 
246
- this.overview = res.data || null
247
- const status = normalizeBudgetStatus(this.overview && this.overview.status)
278
+ this.overview = data
279
+ this.isExempt = false
248
280
  this.emitSubmitBlocked(
249
281
  status === BUDGET_STATUS.FORBID,
250
282
  status === BUDGET_STATUS.WARN
251
283
  )
284
+ this.emitBoardVisible(true, status)
252
285
  } catch (e) {
253
286
  if (seq !== this.reqSeq) return
254
287
  this.overview = null
255
288
  this.error = (e && e.message) || '个人预算概述获取失败'
289
+ this.isExempt = false
256
290
  this.emitSubmitBlocked(false, false)
291
+ this.emitBoardVisible(true, '')
257
292
  } finally {
258
293
  if (seq === this.reqSeq) this.loading = false
259
294
  }
@@ -141,13 +141,16 @@ export default {
141
141
  budgetNum() {
142
142
  return parseAmount(this.overview && this.overview.budgetAmount)
143
143
  },
144
+ /** 有有效总预算才算占比;否则不展示假的 100% 剩余 */
145
+ hasBudgetRatio() {
146
+ return Number.isFinite(this.usedNum) && Number.isFinite(this.budgetNum) && this.budgetNum > 0
147
+ },
144
148
  usagePercent() {
145
- const used = this.usedNum
146
- const budget = this.budgetNum
147
- if (!Number.isFinite(used) || !Number.isFinite(budget) || budget <= 0) return 0
148
- return (used / budget) * 100
149
+ if (!this.hasBudgetRatio) return NaN
150
+ return (this.usedNum / this.budgetNum) * 100
149
151
  },
150
152
  fillWidth() {
153
+ if (!this.hasBudgetRatio) return '0'
151
154
  return Math.min(Math.max(this.usagePercent, 0), 100).toFixed(2)
152
155
  },
153
156
  warnAmount() {
@@ -171,6 +174,7 @@ export default {
171
174
  return 'is-mid'
172
175
  },
173
176
  barLabel() {
177
+ if (!this.hasBudgetRatio) return '剩余 —'
174
178
  const remain = 100 - this.usagePercent
175
179
  if (remain < 0) return `已超 ${formatPercent(this.usagePercent - 100)}`
176
180
  return `剩余 ${formatPercent(remain)}`
@@ -3,15 +3,18 @@
3
3
  export const BUDGET_STATUS = {
4
4
  PASS: '通过',
5
5
  WARN: '预警',
6
- FORBID: '禁止'
6
+ FORBID: '禁止',
7
+ /** 免于管控:业务宿主应隐藏整块个人预算模块 */
8
+ EXEMPT: '免于管控'
7
9
  }
8
10
 
9
- /** 接口 status → 通过/预警/禁止;「警告」兼容为预警 */
11
+ /** 接口 status → 通过/预警/禁止/免于管控;「警告」兼容为预警 */
10
12
  export function normalizeBudgetStatus(status) {
11
13
  const s = String(status || '').trim()
12
14
  if (s === BUDGET_STATUS.FORBID || s === '禁止提交') return BUDGET_STATUS.FORBID
13
15
  if (s === BUDGET_STATUS.WARN || s === '警告') return BUDGET_STATUS.WARN
14
16
  if (s === BUDGET_STATUS.PASS || s === '正常') return BUDGET_STATUS.PASS
17
+ if (s === BUDGET_STATUS.EXEMPT || /免于/.test(s)) return BUDGET_STATUS.EXEMPT
15
18
  return s || ''
16
19
  }
17
20
 
@@ -25,6 +25,7 @@
25
25
  :fetch-performance-page="useMock ? null : sceneApi.fetchPerformancePage"
26
26
  :use-demo="useMock"
27
27
  @submit-blocked="$emit('submit-blocked', $event)"
28
+ @board-visible="$emit('board-visible', $event)"
28
29
  />
29
30
  </template>
30
31