lambo-design-bi 0.0.251 → 0.0.253

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.
@@ -1,46 +1,6 @@
1
1
  import biConfig from "../../config/config"
2
2
  import ajax from "@lambo-design/shared/utils/ajax"
3
3
 
4
- /**
5
- * 获取简报右侧摘要(data 阶段,单接口)
6
- * 后端:GET /bs/bulletin/data/summary,服务端读四个 *_api_id 分别取数并归一为 BulletinSummary
7
- * 前端直接使用返回结构,不再逐段请求。
8
- *
9
- * @param {*} bulletinWidgetId 简报控件 id
10
- * @param {*} params 页面级查询条件
11
- * @returns { code, data: { title, meta, conclusions[], metrics[], highlights[], risks[], advices[], warnings[] } }
12
- */
13
- export function getBulletinSummary(bulletinWidgetId, params) {
14
- return ajax.request({
15
- url: biConfig.dataServerContext + '/bs/bulletin/data/summary',
16
- method: 'get',
17
- params: {
18
- bulletinWidgetId: bulletinWidgetId,
19
- params: JSON.stringify(params || {})
20
- }
21
- })
22
- }
23
-
24
- /**
25
- * 查询简报已发布成品附件(data 阶段)
26
- * 后端:GET /bs/bulletin/data/publishedDocs,读 plat_bulletin_publish_doc 中 is_publish='1',
27
- * 按 bulletinWidgetId + params(期间按 period_type 落列 / 组织)过滤。
28
- *
29
- * @param {*} bulletinWidgetId 简报控件 id(= plat_bulletin.bulletin_id)
30
- * @param {*} params 页面级查询条件(如 period / orgCode)
31
- * @returns { code, data: [{ bulletinId, docId, docName, periodYear, comId, distCtId, publishTime, ... }] }
32
- */
33
- export function getPublishedBulletinDocs(bulletinWidgetId, params) {
34
- return ajax.request({
35
- url: biConfig.dataServerContext + '/bs/bulletin/data/publishedDocs',
36
- method: 'get',
37
- params: {
38
- bulletinWidgetId: bulletinWidgetId,
39
- params: JSON.stringify(params || {})
40
- }
41
- })
42
- }
43
-
44
4
  /**
45
5
  * 查询简报发布成品列表(data 阶段)
46
6
  * 后端:GET /bs/bulletin/doc/list,按 简报×期间×组织 查已发布成品
@@ -1,4 +1,3 @@
1
- <!-- eslint-disable -->
2
1
  <template>
3
2
  <div class="bulletin-widget">
4
3
  <div class="bulletin-header" v-if="hasTitle || previewUrl">
@@ -6,20 +5,13 @@
6
5
  <div class="bulletin-title">{{ cardTitle }}</div>
7
6
  <div class="bulletin-subtitle" v-if="subTitle">{{ subTitle }}</div>
8
7
  </div>
9
- <div
10
- v-if="previewUrl"
11
- class="bulletin-download-btn"
12
- title="下载简报"
13
- @click="doDownload">
8
+ <div v-if="previewUrl" class="bulletin-download-btn" title="下载简报" @click="doDownload">
14
9
  <Icon type="md-download" class="btn-icon" />
15
10
  <span class="btn-text">下载</span>
16
11
  </div>
17
12
  </div>
18
13
 
19
- <div
20
- class="bulletin-body"
21
- :class="{ 'is-empty': !previewUrl }"
22
- :style="containerStyle || {}">
14
+ <div class="bulletin-body" :class="{ 'is-empty': !previewUrl }" :style="containerStyle || {}">
23
15
  <div v-if="querying && !previewUrl" class="bulletin-placeholder">
24
16
  <p>加载简报中…</p>
25
17
  </div>
@@ -31,11 +23,7 @@
31
23
  <p>尚未发布简报</p>
32
24
  <p class="hint">该期间/组织暂无已发布的简报成品</p>
33
25
  </div>
34
- <lambo-doc-word
35
- v-else
36
- :url="previewUrl"
37
- :key="previewUrl"
38
- :report="summary"
26
+ <lambo-doc-word v-else :url="previewUrl" :key="previewUrl" :report="summary" :publisher="publisher"
39
27
  :publish-time="publishTime" />
40
28
  </div>
41
29
  </div>
@@ -52,7 +40,6 @@ const LOG = '[BiBulletin]'
52
40
  // 摘要空对象骨架,摘要内容未加载/缺省时兜底,避免 lambo-doc-word 内部空指针
53
41
  const EMPTY_SUMMARY = Object.freeze({
54
42
  title: '',
55
- meta: '',
56
43
  conclusions: [],
57
44
  metrics: [],
58
45
  highlights: [],
@@ -123,8 +110,10 @@ export default {
123
110
  previewUrl: '',
124
111
  lastDocId: '',
125
112
  lastFileName: '',
126
- // 简报生成时间(plat_bulletin_publish_doc.publish_time)
113
+ // 简报发布时间(plat_bulletin_publish_doc.publish_time),展示在左侧目录下方
127
114
  publishTime: '',
115
+ // 简报发布人(plat_bulletin_publish_doc.publish_user_name),展示在左侧目录下方
116
+ publisher: '',
128
117
  // 空态原因:'' 无 / 'invalid' 查询条件不足(校验未过)/ 'empty' 已查询但无成品
129
118
  emptyReason: '',
130
119
  // 摘要:取自已发布成品行的 sum_json(plat_bulletin_publish_doc.sum_json),缺省为 null
@@ -184,6 +173,7 @@ export default {
184
173
  this.lastFileName = ''
185
174
  this.previewUrl = ''
186
175
  this.publishTime = ''
176
+ this.publisher = ''
187
177
  this.emptyReason = reason || ''
188
178
  },
189
179
  loadDoc(params) {
@@ -249,8 +239,9 @@ export default {
249
239
  console.log(LOG, 'loadDoc 命中已发布成品,直接渲染', { docId: doc.docId, docName: doc.docName })
250
240
  this.lastDocId = doc.docId
251
241
  this.lastFileName = doc.docName || (this.cardTitle + '.docx')
252
- // 与右侧摘要 meta 保持统一格式(左侧语义为"简报发布时间":数据源 plat_bulletin_publish_doc.publish_time)
253
- this.publishTime = doc.publishTime ? `简报发布时间:${normalizePublishTime(doc.publishTime)}` : ''
242
+ // 发布人/发布时间统一展示在左侧目录下方(数据源 plat_bulletin_publish_doc)
243
+ this.publisher = doc.publishUserName ? `发布人:${String(doc.publishUserName).trim()}` : ''
244
+ this.publishTime = doc.publishTime ? `发布时间:${normalizePublishTime(doc.publishTime)}` : ''
254
245
  this.previewUrl = fileGetUrl + doc.docId
255
246
  this.emptyReason = ''
256
247
  this.$Message.success({ content: '查询到已发布的简报', duration: 1.8 })
@@ -305,9 +296,6 @@ export default {
305
296
  this.summaryData = null
306
297
  return
307
298
  }
308
- // 库内 meta 是生成时的"统计时间",发布后以发布人为准(发布时间已在左侧目录下方展示)
309
- const publisher = doc.publishUserName ? String(doc.publishUserName).trim() : ''
310
- parsed.meta = publisher ? ('发布人:' + publisher) : ''
311
299
  this.summaryData = parsed
312
300
  console.log(LOG, 'applySummaryFromDoc 摘要已加载', {
313
301
  docId: doc.docId,
@@ -353,15 +341,6 @@ export default {
353
341
  console.log(LOG, 'created config 阶段解析', { widget: this.widget, options: this.bulletinOptions })
354
342
  // config 阶段:由父页面完成配置装配,此处仅解析结构性配置
355
343
  this.initConfig()
356
- },
357
- mounted() {
358
- // params 已有值(父组件同步传入)→ 直接加载;否则等 watcher 触发
359
- // if (this.params && Object.keys(this.params).length > 0) {
360
- // console.log(LOG, 'mounted params 已就绪,直接加载', { params: this.params })
361
- // this.loadData(this.params)
362
- // } else {
363
- // console.log(LOG, 'mounted params 为空,等 watcher 触发')
364
- // }
365
344
  }
366
345
  }
367
346
  </script>
@@ -370,6 +349,7 @@ export default {
370
349
  .bulletin-widget {
371
350
  width: 100%;
372
351
  }
352
+
373
353
  /* 自绘标题栏:左标题右按钮,无边框,仅与下方内容留间距 */
374
354
  .bulletin-header {
375
355
  display: flex;
@@ -378,27 +358,32 @@ export default {
378
358
  gap: 12px;
379
359
  padding: 0 0 3px;
380
360
  }
361
+
381
362
  .bulletin-title-wrap {
382
363
  min-width: 0;
383
364
  }
365
+
384
366
  .bulletin-title {
385
367
  font-size: 16px;
386
368
  font-weight: 600;
387
369
  color: #17233d;
388
370
  line-height: 1.4;
389
371
  }
372
+
390
373
  .bulletin-subtitle {
391
374
  margin-top: 2px;
392
375
  color: #999;
393
376
  font-size: 12px;
394
377
  line-height: 1.4;
395
378
  }
379
+
396
380
  .bulletin-body {
397
381
  width: 100%;
398
382
  /* 视口自适应高度:吃满屏幕剩余空间,大屏不留白;减去的值覆盖页头/查询栏/简报标题栏/边距 */
399
383
  height: calc(100vh - 210px);
400
384
  min-height: 480px;
401
385
  }
386
+
402
387
  /* 下载按钮:标题栏右侧,文字链接式,主题蓝可点,hover 加深 */
403
388
  .bulletin-download-btn {
404
389
  flex-shrink: 0;
@@ -411,20 +396,25 @@ export default {
411
396
  cursor: pointer;
412
397
  transition: color 0.18s ease;
413
398
  }
399
+
414
400
  .bulletin-download-btn .btn-icon {
415
401
  font-size: 16px;
416
402
  }
403
+
417
404
  .bulletin-download-btn:hover {
418
405
  color: #57a3f3;
419
406
  }
407
+
420
408
  .bulletin-download-btn:active {
421
409
  color: #2372c8;
422
410
  }
411
+
423
412
  /* 空态/加载态:无文档时高度自适应内容,避免撑出大片空白 */
424
413
  .bulletin-body.is-empty {
425
414
  height: auto;
426
415
  min-height: 0;
427
416
  }
417
+
428
418
  .bulletin-placeholder {
429
419
  width: 100%;
430
420
  height: 100%;
@@ -439,14 +429,17 @@ export default {
439
429
  border: 1px dashed #e2e8f0;
440
430
  border-radius: 6px;
441
431
  }
432
+
442
433
  /* 空态容器高度自适应时,用内边距撑出紧凑高度而非塌陷 */
443
434
  .bulletin-body.is-empty .bulletin-placeholder {
444
435
  height: auto;
445
436
  padding: 48px 16px;
446
437
  }
438
+
447
439
  .bulletin-placeholder p {
448
440
  margin: 0;
449
441
  }
442
+
450
443
  .bulletin-placeholder .hint {
451
444
  font-size: 12px;
452
445
  color: #cbd5e1;
@@ -108,14 +108,15 @@ export default {
108
108
  this.subTitle = row['sub_title']
109
109
  this.num = row['num']
110
110
  this.subNum1 = row['sub_num1']
111
- this.trend1 = row['trend1']
111
+ // 过滤掉前端缺省值'-'的情况,组件传值有要求
112
+ this.trend1 = row['trend1']==='-'?null:row['trend1']
112
113
  this.subNum2 = row['sub_num2']
113
- this.trend2 = row['trend2']
114
+ this.trend2 = row['trend2']==='-'?null:row['trend2']
114
115
  if (Object.prototype.hasOwnProperty.call(row, 'polar1')) {
115
- this.polar1 = row['polar1']
116
+ this.polar1 = row['polar1']==='-'?null:row['polar1']
116
117
  }
117
118
  if (Object.prototype.hasOwnProperty.call(row, 'polar2')) {
118
- this.polar2 = row['polar2']
119
+ this.polar2 = row['polar2']==='-'?null:row['polar2']
119
120
  }
120
121
  if (Object.prototype.hasOwnProperty.call(row, 'drill_k1') && Object.prototype.hasOwnProperty.call(row, 'drill_v1')) {
121
122
  this.drillK1 = row['drill_k1'] || ''
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambo-design-bi",
3
- "version": "0.0.251",
3
+ "version": "0.0.253",
4
4
  "description": "Vue2 BI 数据可视化组件库",
5
5
  "main": "index.js",
6
6
  "author": "finch",
@@ -1159,9 +1159,12 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
1159
1159
  let datas = [];
1160
1160
  let colorList = [];
1161
1161
 
1162
+ let sortedIndices = []
1162
1163
  // 将 dataY 转换为带索引的排序数组
1163
- let sortedIndices = dataY[0].map((_, index) => index)
1164
- .sort((a, b) => dataY[0][b] - dataY[0][a]); // 根据 dataX 的值降序排列
1164
+ if (dataY && dataY[0]) {
1165
+ sortedIndices = dataY[0].map((_, index) => index)
1166
+ .sort((a, b) => dataY[0][b] - dataY[0][a]); // 根据 dataX 的值降序排列
1167
+ }
1165
1168
 
1166
1169
  for (let i = 0; i < sortedIndices.length; i++) {
1167
1170
  const index = sortedIndices[i];
@@ -1243,8 +1246,12 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
1243
1246
  let colorList = [];
1244
1247
  let radius = ['40%', '60%']; // 控制饼块粗细的半径范围
1245
1248
  let prevAngle = 0; // 初始角度
1246
- let sortedIndices = dataY[0].map((_, index) => index)
1247
- .sort((a, b) => dataY[0][b] - dataY[0][a]); // 根据dataY的值进行降序排序并获取索引
1249
+ let sortedIndices = []
1250
+ // 将 dataY 转换为带索引的排序数组
1251
+ if (dataY && dataY[0]) {
1252
+ sortedIndices = dataY[0].map((_, index) => index)
1253
+ .sort((a, b) => dataY[0][b] - dataY[0][a]); // 根据dataY的值进行降序排序并获取索引
1254
+ }
1248
1255
 
1249
1256
  for (let i = 0; i < sortedIndices.length; i++) {
1250
1257
  const index = sortedIndices[i];
@@ -1459,7 +1466,7 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
1459
1466
  itemStyle: {
1460
1467
  normal: {
1461
1468
  color: function (params) {
1462
- return lightColors[params.dataIndex]
1469
+ return lightColors[params.dataIndex]
1463
1470
  }
1464
1471
  }
1465
1472
  },
@@ -2097,7 +2104,7 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
2097
2104
  fontSize: 20
2098
2105
  }
2099
2106
  },
2100
- data: dataY[0].map((value, index) => {
2107
+ data: dataY[0] ? dataY[0].map((value, index) => {
2101
2108
  const rank = sortedDataX.indexOf(value) + 1;
2102
2109
  let p;
2103
2110
  if (dataY[0].reduce((a, b) => a + b) === 0) {
@@ -2117,7 +2124,7 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
2117
2124
  showname: dataX[index],
2118
2125
  reaVal: d + '%'
2119
2126
  }
2120
- })
2127
+ }) : []
2121
2128
  },
2122
2129
  ]
2123
2130
  };
@@ -2334,7 +2341,11 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
2334
2341
  });
2335
2342
  }
2336
2343
  }
2337
- const dynamicColors = dataDim.map((_, index) => colors[index % colors.length]);
2344
+
2345
+ let dynamicColors = []
2346
+ if (dataDim) {
2347
+ dynamicColors = dataDim.map((_, index) => colors[index % colors.length])
2348
+ }
2338
2349
  opt = {
2339
2350
  tooltip: {
2340
2351
  trigger: 'axis',
@@ -2446,7 +2457,10 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
2446
2457
 
2447
2458
  }
2448
2459
  }
2449
- const dynamicColors = dataDim.map((_, index) => colors[index % colors.length]);
2460
+ let dynamicColors = []
2461
+ if (dataDim) {
2462
+ dynamicColors = dataDim.map((_, index) => colors[index % colors.length])
2463
+ }
2450
2464
 
2451
2465
  opt = {
2452
2466
  tooltip: {
@@ -2524,20 +2538,25 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
2524
2538
  series: series
2525
2539
  };
2526
2540
  } else if (type === '44') {
2527
- const transData = transpose(dataY);
2528
- const indicators = dataX.map((name, index) => {
2529
- let maxValue = 0;
2530
- for (let i = 0; i < dataY[index].length; i++) {
2531
- if (dataY[index] && dataY[index][i] > maxValue) {
2532
- maxValue = dataY[index][i];
2541
+ const transData = transpose(dataY)
2542
+
2543
+ let indicators = []
2544
+ if (dataX) {
2545
+ indicators = dataX.map((name, index) => {
2546
+ let maxValue = 0
2547
+ for (let i = 0; i < dataY[index].length; i++) {
2548
+ if (dataY[index] && dataY[index][i] > maxValue) {
2549
+ maxValue = dataY[index][i];
2550
+ }
2533
2551
  }
2534
- }
2535
- return {
2536
- name: name,
2537
- max: Math.ceil(maxValue)
2538
- };
2539
- });
2540
- const seriesData = [];
2552
+ return {
2553
+ name: name,
2554
+ max: Math.ceil(maxValue)
2555
+ }
2556
+ })
2557
+ }
2558
+
2559
+ const seriesData = []
2541
2560
  transData.forEach((data, index) => {
2542
2561
  seriesData.push({
2543
2562
  name: dataDim[index],
@@ -2552,7 +2571,7 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
2552
2571
  areaStyle: {
2553
2572
  color: areaColors[index % areaColors.length]
2554
2573
  }
2555
- });
2574
+ })
2556
2575
  });
2557
2576
  opt = {
2558
2577
  legend: {
@@ -3690,7 +3709,7 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
3690
3709
  fontFamily: 'Microsoft YaHei',
3691
3710
  color: '#999',
3692
3711
  fontSize: 10,
3693
- formatter: function(value) {
3712
+ formatter: function (value) {
3694
3713
  return Math.round(value)
3695
3714
  }
3696
3715
  }
@@ -4059,7 +4078,7 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
4059
4078
  show: true,
4060
4079
  position: 'top',
4061
4080
  distance: 5,
4062
- formatter: function(params) {
4081
+ formatter: function (params) {
4063
4082
  return params.value
4064
4083
  },
4065
4084
  fontSize: 11,
@@ -4085,7 +4104,7 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
4085
4104
  label: {
4086
4105
  show: true,
4087
4106
  position: 'right',
4088
- formatter: function() {
4107
+ formatter: function () {
4089
4108
  return sortedValues[i] + ' ' + badge
4090
4109
  },
4091
4110
  fontSize: 11,
@@ -4111,7 +4130,7 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
4111
4130
  },
4112
4131
  tooltip: {
4113
4132
  trigger: 'item',
4114
- formatter: function(params) {
4133
+ formatter: function (params) {
4115
4134
  if (!params) return ''
4116
4135
  let idx = params.dataIndex
4117
4136
  let name = params.name
@@ -4150,7 +4169,7 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
4150
4169
  fontFamily: 'Microsoft YaHei',
4151
4170
  color: '#666',
4152
4171
  fontSize: 12,
4153
- formatter: function(value) {
4172
+ formatter: function (value) {
4154
4173
  return value === selfLabel ? '{highlight|' + value + '}' : value
4155
4174
  },
4156
4175
  rich: {
@@ -4162,7 +4181,6 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
4162
4181
  }
4163
4182
  },
4164
4183
  series: [
4165
- // 我公司高亮背景
4166
4184
  ...(selfIndex >= 0 ? [{
4167
4185
  name: '高亮背景',
4168
4186
  type: 'bar',
@@ -4215,7 +4233,7 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
4215
4233
  label: {
4216
4234
  show: true,
4217
4235
  position: 'end',
4218
- formatter: function() {
4236
+ formatter: function () {
4219
4237
  // 第一名始终在最上面一行 (i=0), 排序方向已保证
4220
4238
  return (i === 0 ? '🥇 ' : '') + sortedValues[i]
4221
4239
  },
@@ -8,7 +8,6 @@
8
8
  <Icon type="ios-arrow-back" />
9
9
  </span>
10
10
  </div>
11
- <div class="word-nav-publish" v-if="publishTime">{{ publishTime }}</div>
12
11
  <div v-if="!ready" class="word-nav-empty">解析中…</div>
13
12
  <div v-else-if="!toc.length" class="word-nav-empty">未识别到章节目录</div>
14
13
  <a
@@ -18,6 +17,10 @@
18
17
  :class="['level-' + item.level, { active: activeId === item.id }]"
19
18
  @click="scrollTo(item)"
20
19
  >{{ item.text }}</a>
20
+ <div class="word-nav-publish" v-if="publisher || publishTime">
21
+ <div v-if="publisher" class="meta-line">{{ publisher }}</div>
22
+ <div v-if="publishTime" class="meta-line">{{ publishTime }}</div>
23
+ </div>
21
24
  </aside>
22
25
  <!-- 左侧折叠窄条 -->
23
26
  <div class="word-rail word-rail-left" v-else title="展开目录" @click="toggleNav">
@@ -46,7 +49,6 @@
46
49
  <Icon type="ios-arrow-forward" />
47
50
  </span>
48
51
  <div class="paper-title" v-if="internalReport.title">{{ internalReport.title }}</div>
49
- <div class="paper-meta" v-if="internalReport.meta">{{ internalReport.meta }}</div>
50
52
 
51
53
  <!-- 1. 核心结论(数据为空时整段隐藏,含标题) -->
52
54
  <div class="summary-section" v-if="internalReport.conclusions && internalReport.conclusions.length">
@@ -121,47 +123,18 @@ export default {
121
123
  type: Object,
122
124
  default: null
123
125
  },
124
- // 简报生成时间(plat_bulletin_publish_doc.publish_time),展示在目录下方
126
+ // 简报发布人(plat_bulletin_publish_doc.publish_user_name),展示在目录下方
127
+ publisher: {
128
+ type: String,
129
+ default: ""
130
+ },
131
+ // 简报发布时间(plat_bulletin_publish_doc.publish_time),展示在目录下方
125
132
  publishTime: {
126
133
  type: String,
127
134
  default: ""
128
135
  }
129
136
  },
130
137
  data() {
131
- // 内置模拟摘要 —— 作为未传 report 时的 fallback,同时保留原 demo 页面观感
132
- const defaultReport = {
133
- title: "文档摘要",
134
- meta: "2025年全省系统卷烟物流费用及对标指标情况通报",
135
- conclusions: [
136
- "2025年全省物流费用全面攀升,总量增幅28.72%",
137
- "单箱费用增幅67.34%",
138
- "人工成本占比近七成是主因",
139
- "各单位间差距悬殊"
140
- ],
141
- metrics: [
142
- { name: "物流总费用", value: "2279.53万元", change: "+28.72%", trend: "up-bad" },
143
- { name: "单箱物流费用", value: "10912.47元/箱", change: "+67.34%", trend: "up-bad" },
144
- { name: "人工费用占比", value: "69.53%", change: "+3.42个百分点", trend: "up-bad" },
145
- { name: "物流费用率", value: "27.11%", change: "+4.88个百分点", trend: "up-bad" },
146
- { name: "单箱可控费用", value: "1579.56元/箱", change: "-43.69%", trend: "down-good" }
147
- ],
148
- highlights: [
149
- "扣除人工折旧后单箱可控费用同比下降43.69%",
150
- "10家单位实现下降,精细化管理初显成效",
151
- "咸阳市公司物流总费用降幅33.66%,全省最大"
152
- ],
153
- risks: [
154
- "配送费用激增67.13%,占物流总费用六成",
155
- "单箱配送费用增幅70.99%,成本管控压力大",
156
- "各单位指标差异悬殊,单箱费用最高与最低相差2.6倍",
157
- "对标短板明显"
158
- ],
159
- advices: [
160
- "重点管控配送环节成本,优化送货线路与车辆调度",
161
- "推广咸阳市降本经验,组织落后单位专项对标改进",
162
- "关注人工成本刚性增长趋势,探索外包与自动化替代方案"
163
- ]
164
- };
165
138
  return {
166
139
  ready: false,
167
140
  toc: [],
@@ -172,8 +145,7 @@ export default {
172
145
  docRoot: null,
173
146
  scrollEl: null,
174
147
  // 右侧摘要(优先使用外部 report prop,缺失时回退到内置模拟数据)
175
- internalReport: this.report || defaultReport,
176
- defaultReport: defaultReport,
148
+ internalReport: this.report,
177
149
  // 折叠状态(从 localStorage 恢复,容错降级为默认展开)
178
150
  navCollapsed: this.readCollapsed(NAV_COLLAPSE_KEY),
179
151
  asideCollapsed: this.readCollapsed(ASIDE_COLLAPSE_KEY)
@@ -181,7 +153,7 @@ export default {
181
153
  },
182
154
  watch: {
183
155
  report(v) {
184
- this.internalReport = v || this.defaultReport;
156
+ this.internalReport = v
185
157
  },
186
158
  url: {
187
159
  immediate: true,
@@ -595,13 +567,18 @@ export default {
595
567
  color: #1e40af;
596
568
  font-weight: 700;
597
569
  }
598
- /* 文档目录标题下方:简报发布时间,与右侧 .paper-meta 同一套样式 */
570
+ /* 文档目录底部:简报发布人 / 发布时间 */
599
571
  .word-nav-publish {
600
- margin: 4px 0 6px;
572
+ margin-top: 10px;
573
+ padding-top: 8px;
574
+ border-top: 1px solid #eef1f5;
601
575
  font-size: 11px;
602
576
  color: #64748b;
603
577
  line-height: 1.6;
604
578
  }
579
+ .word-nav-publish .meta-line {
580
+ margin: 0;
581
+ }
605
582
 
606
583
  /* 中间 Word 预览 */
607
584
  .word-doc {
@@ -648,11 +625,6 @@ export default {
648
625
  /* 给右上角悬浮收起按钮让位 */
649
626
  padding-right: 26px;
650
627
  }
651
- .paper-meta {
652
- font-size: 11px;
653
- color: #64748b;
654
- margin-bottom: 6px;
655
- }
656
628
  /* 摘要分区 */
657
629
  .summary-section {
658
630
  margin-bottom: 18px;
@@ -29,7 +29,7 @@
29
29
  <span class="ivu-number-info-total">
30
30
  <slot name="num">{{ num }}</slot>
31
31
  </span>
32
- <span class="ivu-number-info-subTotal" v-if="subNum1 || subNum2">
32
+ <span class="ivu-number-info-subTotal">
33
33
  <slot name="subNum">
34
34
  <template v-if="subNum1">
35
35
  <template v-if="trend1">