ike-weblca-html 2.1.2 → 2.1.3

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,766 +1,1148 @@
1
- import { css, html, LitElement } from 'lit-element'
2
- import { property } from 'lodash-es'
3
- import cookies from 'js-cookie'
4
-
5
- /**
6
- * IkeWebHeader - Web LCA 网站头部组件
7
- *
8
- * 这是一个基于 LitElement 的 Web Components 组件,用于渲染网站的头部导航栏。
9
- * 支持多语言切换、动态菜单显示、响应式设计等功能。
10
- *
11
- * 主要功能:
12
- * - 多语言支持(简体中文、繁体中文、英文)
13
- * - 根据域名动态显示不同的菜单项
14
- * - 支持个性化配置(logo、机构名称等)
15
- * - 响应式导航菜单
16
- * - 平滑滚动到页面底部
17
- * - 登录状态检测和相应的URL跳转逻辑
18
- */
19
- export class IkeWebHeader extends LitElement {
20
- /**
21
- * 组件样式定义
22
- * 包含头部容器、菜单项、子菜单、悬停效果等样式
23
- */
24
- static styles = css`
25
- .ike-web-header {
26
- width: 100%;
27
- box-sizing: border-box;
28
- height: 72px;
29
- display: flex;
30
- padding: 0 72px;
31
- background: var(--ike-web-header-bg, #063223);
32
- align-items: center;
33
- justify-content: space-between;
34
- border-bottom: 1px solid rgba(211, 211, 211, 0.3);
35
- }
36
-
37
- .iwh-url {
38
- max-width: 220px;
39
- max-height: 40px;
40
- display: inline-block;
41
- }
42
-
43
- .header-list {
44
- color: #fff !important;
45
- height: 72px;
46
- }
47
-
48
- .menu-item:hover {
49
- background: rgba(0, 162, 44, 0.1);
50
- color: var(--ike-web-header-text-color, '#fff');
51
- }
52
-
53
- .el-menu-demo {
54
- display: flex;
55
- align-items: center;
56
- cursor: pointer;
57
- color: #fff;
58
- background: transparent;
59
- border: none;
60
- }
61
-
62
- .posi {
63
- position: absolute;
64
- top: 20%;
65
- left: 70%;
66
- }
67
-
68
- .box-a {
69
- display: inline-block;
70
- margin-left: 30px;
71
- }
72
-
73
- .box-a img {
74
- width: auto;
75
- height: 40px;
76
- }
77
-
78
- .left-menu-items {
79
- display: flex;
80
- align-items: center;
81
- margin-left: 20px;
82
- }
83
-
84
- .left-menu-item {
85
- padding: 0 15px;
86
- font-size: 14px;
87
- height: 72px;
88
- display: flex;
89
- align-items: center;
90
- cursor: pointer;
91
- border-radius: 4px;
92
- transition: background-color 0.3s ease;
93
- }
94
-
95
- .left-menu-item:hover {
96
- background: rgba(0, 162, 44, 0.1);
97
- }
98
-
99
- .menu-item {
100
- padding: 0 20px;
101
- font-size: 14px;
102
- height: 72px;
103
- text-align: center;
104
- box-sizing: border-box;
105
- display: flex;
106
- align-items: center;
107
- }
108
-
109
- .menu-item-database {
110
- position: relative;
111
- }
112
-
113
- .menu-sub-group {
114
- background: #e6f2e8;
115
- position: absolute;
116
- z-index: 999;
117
- width: 150%;
118
- //bottom: -72px;
119
- top: 100%;
120
- left: -50%;
121
- padding: 20px 20px 0 20px;
122
- //transform: translateX(50%);
123
- color: #06aa3e;
124
- box-shadow: 0px 0px 4px 0px rgba(6, 50, 35, 0.53);
125
- border-radius: 0px 0px 8px 8px;
126
- display: none;
127
- transition: opacity 0.3s ease;
128
- opacity: 0;
129
- }
130
- .menu-sub-group-1 {
131
- width: 280px;
132
- left: 50%;
133
- transform: translateX(-50%);
134
- }
135
- .menu-sub-item {
136
- padding-bottom: 20px;
137
- color: #373737;
138
- }
139
- .menu-sub-item:hover {
140
- color: #06aa3e;
141
- }
142
-
143
- .menu-item-database:hover .menu-sub-group {
144
- display: block;
145
- opacity: 1;
146
- }
147
-
148
- /* 消息图标样式 */
149
- .message-icon-container {
150
- position: relative;
151
- display: flex;
152
- align-items: center;
153
- margin: 0 15px;
154
- cursor: pointer;
155
- }
156
-
157
- .message-icon {
158
- width: 24px;
159
- height: 24px;
160
- }
161
-
162
- .message-badge {
163
- position: absolute;
164
- top: -8px;
165
- right: -8px;
166
- background: linear-gradient(90deg, #ffbb24 0%, #ff9900 100%);
167
- color: white;
168
- border-radius: 50%;
169
- width: 18px;
170
- height: 18px;
171
- display: flex;
172
- align-items: center;
173
- justify-content: center;
174
- font-size: 12px;
175
- font-weight: bold;
176
- }
177
-
178
- /* 登录按钮样式 */
179
- .login-button {
180
- padding: 8px 16px;
181
- border: 1px solid;
182
- border-radius: 4px;
183
- cursor: pointer;
184
- font-size: 14px;
185
- transition: all 0.3s ease;
186
- margin-left: 15px;
187
- }
188
-
189
- .login-button:hover {
190
- opacity: 0.8;
191
- }
192
- `
193
-
194
- // ==================== 环境和状态相关属性 ====================
195
-
196
- /** 当前网站状态,基于域名的第一部分 */
197
- status = window.location.hostname.split('.')[0]
198
-
199
- /** 当前页面完整URL */
200
- hostName = window.location.href
201
-
202
- /** 是否为平台版本(www、192、online环境) */
203
- isPlat =
204
- this.status === 'www' || this.status === '192' || this.status === 'online'
205
-
206
- /** 是否显示语言切换功能 */
207
- isShowLang =
208
- this.status === 'www' ||
209
- this.status === 'nanozeo' ||
210
- this.status === '192' ||
211
- this.status === 'online'
212
-
213
- // ==================== 数据相关属性 ====================
214
-
215
- /** 从API获取的数据 */
216
- data = []
217
-
218
- /** 个性化配置JSON数据 */
219
- personalizedConfigJson
220
-
221
- /** 机构logo URL */
222
- logo
223
-
224
- /** 机构联系方式 */
225
- orgContacts
226
-
227
- /** 机构名称 */
228
- name
229
-
230
- /** 机构邮箱 */
231
- email
232
-
233
- /** 机构电话 */
234
- phone
235
-
236
- /** 机构地址 */
237
- address
238
-
239
- /** 关注链接 */
240
- followUrl
241
-
242
- /** 已开通的服务列表 */
243
- alreadyServices
244
-
245
- // ==================== 多语言相关属性 ====================
246
-
247
- /** 当前语言 */
248
- currentLanguage = 'zh_CN'
249
-
250
- /** 简体中文语言包 */
251
- zhCN = {
252
- 首页: '首页',
253
- 数据库: '数据库',
254
- 资料库: '资料库',
255
- 皮革LCA数据库: '皮革LCA数据库',
256
- LCA大赛: 'LCA大赛',
257
- 专业培训: '专业培训',
258
- 联系我们: '联系我们',
259
- 标准库: '标准库',
260
- 核算模版: '核算模版',
261
- '2025全生命周期创新大赛': '2025全生命周期创新大赛',
262
-
263
- 化工专题比赛: '2025首届中国化工产品碳足迹数据库大赛',
264
- 登录: '登录',
265
- 个人中心: '个人中心',
266
- }
267
-
268
- /** 繁体中文语言包 */
269
- zhTW = {
270
- 首页: '首頁',
271
- 数据库: '數據庫',
272
- 资料库: '資料庫',
273
- 皮革LCA数据库: '皮革LCA數據庫',
274
- LCA大赛: 'LCA大賽',
275
- 专业培训: '專業培訓',
276
- 联系我们: '聯繫我們',
277
- 标准库: '標準庫',
278
- 核算模版: '核算模版',
279
- '2025全生命周期创新大赛': '2025全生命週期創新大賽',
280
- 化工专题比赛: '2025首届中國化工產品碳足迹資料庫大賽',
281
- 登录: '登录',
282
- 个人中心: '个人中心',
283
- }
284
-
285
- /** 英文语言包 */
286
- enUS = {
287
- 首页: 'Home',
288
- 数据库: 'Database',
289
- 资料库: 'Database',
290
- 皮革LCA数据库: 'Leather LCA Database',
291
- LCA大赛: 'LCA Competition',
292
- 专业培训: 'Professional Training',
293
- 联系我们: 'Contact Us',
294
- 标准库: 'Standard Library',
295
- 核算模版: 'Calculation Template',
296
- '2025全生命周期创新大赛': '2025 Life Cycle Innovation Competition',
297
- 化工专题比赛:
298
- '2025 First China Chemical Product Carbon Footprint Database Competition',
299
- 登录: 'Login',
300
- 个人中心: 'Personal Center',
301
- }
302
-
303
- /** 当前使用的国际化对象 */
304
- i18n = {}
305
-
306
- /** 浏览器默认语言 */
307
- createLang = navigator.language.replace('-', '_')
308
-
309
- /** 用户选择的语言(优先从localStorage获取,否则使用浏览器语言) */
310
- lang = window.localStorage.getItem('lang') || this.createLang
311
-
312
- /** 登录状态检测 - 检查cookie中是否存在token */
313
- isLoggedIn = !!cookies.get('token')
314
-
315
- /** 消息数量(当前写死为1) */
316
- messageCount = 1
317
-
318
- connectedCallback() {
319
- switch (this.lang) {
320
- case 'zh':
321
- this.currentLanguage = 'zh_CN'
322
- this.i18n = this.zhCN
323
- break
324
- case 'zh_CN':
325
- this.currentLanguage = 'zh_CN'
326
- this.i18n = this.zhCN
327
- break
328
- case 'zh_TW':
329
- this.currentLanguage = 'zh_TW'
330
- this.i18n = this.zhTW
331
- break
332
- case 'en_US':
333
- this.currentLanguage = 'en_US'
334
- this.i18n = this.enUS
335
- break
336
- default:
337
- this.currentLanguage = 'zh_CN'
338
- this.i18n = this.zhCN
339
- break
340
- }
341
-
342
- super.connectedCallback()
343
- this.fetchData()
344
- }
345
-
346
- // @ts-ignore
347
- async fetchData() {
348
- try {
349
- const response = await fetch(
350
- 'https://backsite.efootprint.net/Gpm/webLcaOrganization/GetOrganizationByDomain'
351
- ) // 替换为实际的 API 地址
352
- const jsonData = await response.json()
353
- let data = jsonData.data // 将获取到的数据保存到 data 属性中
354
- if (data && data.personalizedConfigJson) {
355
- this.personalizedConfigJson = JSON.parse(data.personalizedConfigJson)
356
- }
357
- // console.log('this.data.data.personalizedConfigJson', this.personalizedConfigJson)
358
- this.logo =
359
- this.personalizedConfigJson && this.personalizedConfigJson.logo
360
- this.orgContacts =
361
- this.personalizedConfigJson && this.personalizedConfigJson.orgContacts
362
- this.name =
363
- this.personalizedConfigJson &&
364
- this.personalizedConfigJson.institution &&
365
- this.personalizedConfigJson.institution.name
366
- this.email =
367
- this.personalizedConfigJson && this.personalizedConfigJson.orgEmail
368
- this.phone =
369
- this.personalizedConfigJson && this.personalizedConfigJson.orgPhone
370
- this.address =
371
- this.personalizedConfigJson && this.personalizedConfigJson.orgAddress
372
- this.followUrl =
373
- this.personalizedConfigJson && this.personalizedConfigJson.followUrl
374
- this.alreadyServices = data.alreadyServices
375
- setTimeout(() => this.requestUpdate())
376
- // this.requestUpdate(); // 更新组件以触发重新渲染
377
- } catch (error) {
378
- // console.error('Error fetching data:', error);
379
- }
380
- }
381
-
382
- render() {
383
- return html` <div
384
- class="ike-web-header"
385
- style="
386
- background: ${this.isPlat
387
- ? '#063223'
388
- : '#FFFFFF'}; color: ${this.isPlat ? '#fff' : '#063223'}"
389
- >
390
- <div style="display: flex;align-items: center">
391
- <img
392
- src="https://ike-web.oss-cn-hangzhou.aliyuncs.com/WebLCA_logo.png"
393
- class="iwh-url"
394
- alt=""
395
- />
396
- ${this.status !== 'www' && this.status !== '192'
397
- ? html` <div class="box-a" style="display: flex;align-items: center">
398
- <img src="${this.logo}" alt="" />
399
- <span
400
- style="margin-left: 12px;color: #373737;font-weight: 600;color: ${this
401
- .isPlat
402
- ? '#fff'
403
- : '#063223'}"
404
- >${this.name}</span
405
- >
406
- </div>`
407
- : ''}
408
-
409
- <!-- 左侧菜单项:eFootprint、CarbonZero、GPM -->
410
- ${this.isPlat
411
- ? html` <div class="left-menu-items">
412
- ${this.isPlat || this.alreadyServices.includes('eF')
413
- ? html` <div
414
- class="left-menu-item"
415
- style="color: ${this.hostName.includes(
416
- 'efootprint.net/login'
417
- )
418
- ? '#06AA3E'
419
- : this.isPlat
420
- ? '#fff'
421
- : '#373737'}"
422
- @click="${this._routerPush}"
423
- data-url="https://www.efootprint.net"
424
- data-login-url="https://www.efootprint.net/angular/weblca/ef/model/modelList"
425
- >
426
- eFootprint
427
- </div>`
428
- : ''}
429
- ${this.isPlat || this.alreadyServices.includes('scope')
430
- ? html` <div
431
- class="left-menu-item"
432
- style="color: ${this.hostName.includes('webcarbon.net')
433
- ? '#06AA3E'
434
- : this.isPlat
435
- ? '#fff'
436
- : '#373737'}"
437
- @click="${this._routerPush}"
438
- data-login-url="https://www.webcarbon.net/#/calculate/calculatCarbon"
439
- data-url="https://www.webcarbon.net"
440
- >
441
- CarbonZero
442
- </div>`
443
- : ''}
444
- ${this.isPlat || this.alreadyServices.includes('GPM')
445
- ? html` <div
446
- class="left-menu-item"
447
- style="color: ${this.hostName.includes('webgpm.net')
448
- ? '#06AA3E'
449
- : this.isPlat
450
- ? '#fff'
451
- : '#373737'}"
452
- @click="${this._routerPush}"
453
- data-login-url="https://www.webgpm.net/#/dashboard/targetCenter"
454
- data-url="https://www.webgpm.net"
455
- >
456
- GPM
457
- </div>`
458
- : ''}
459
- </div>`
460
- : ''}
461
- </div>
462
-
463
- <div class="iwh-right">
464
- <div class="header-list flex align-center">
465
- <div class="el-menu-demo">
466
- <div
467
- class="menu-item"
468
- style="color: ${this.hostName.includes('weblca.net/home')
469
- ? '#06AA3E'
470
- : this.isPlat
471
- ? '#fff'
472
- : '#373737'}"
473
- @click="${this._routerPush}"
474
- data-login-url="https://www.weblca.net/home"
475
- data-url="https://www.weblca.net/home"
476
- >
477
- ${this.i18n['首页']}
478
- </div>
479
-
480
- <!-- 平台专属菜单项:标准库和核算模版 -->
481
- ${this.isPlat
482
- ? html` <div
483
- class="menu-item"
484
- style="color: ${this.isPlat ? '#fff' : '#373737'}"
485
- @click="${this._routerPush}"
486
- data-login-url="https://www.weblca.net/standard"
487
- data-url="https://www.weblca.net/standard"
488
- >
489
- ${this.i18n['标准库']}
490
- </div>
491
- <div
492
- class="menu-item"
493
- style="color: ${this.isPlat ? '#fff' : '#373737'}"
494
- @click="${this._routerPush}"
495
- data-login-url="https://www.weblca.net/template"
496
- data-url="https://www.weblca.net/template"
497
- >
498
- ${this.i18n['核算模版']}
499
- </div>`
500
- : ''}
501
- ${this.isPlat || this.alreadyServices.includes('database')
502
- ? html` <div
503
- class="menu-item menu-item-database"
504
- style=" position: relative;color: ${this.hostName.includes(
505
- 'weblca.net/database'
506
- )
507
- ? '#06AA3E'
508
- : this.isPlat
509
- ? '#fff'
510
- : '#373737'}"
511
- @click="${this._routerPush}"
512
- data-login-urlurl="https://www.weblca.net/database"
513
- data-url="https://www.weblca.net/database"
514
- >
515
- ${this.isPlat
516
- ? html`<img
517
- class="posi"
518
- src="https://ike-web.oss-cn-hangzhou.aliyuncs.com/HOT.png"
519
- alt=""
520
- />`
521
- : ''}
522
- ${this.i18n['数据库']}
523
- <div class="menu-sub-group">
524
- <div
525
- @click="${this._routerPush}"
526
- data-login-url="https://www.weblca.net/database"
527
- data-url="https://www.weblca.net/database"
528
- class="menu-sub-item"
529
- >
530
- ${this.i18n['数据库']}
531
- </div>
532
- <div
533
- @click="${this._routerPush}"
534
- data-login-url="https://www.weblca.net/database/leather"
535
- data-url="https://www.weblca.net/database/leather"
536
- class="menu-sub-item"
537
- >
538
- ${this.i18n['皮革LCA数据库']}
539
- </div>
540
- </div>
541
- </div>`
542
- : ''}
543
- ${this.isPlat || this.alreadyServices.includes('databankpage')
544
- ? html` <div
545
- class="menu-item"
546
- style="color: ${this.hostName.includes('/databankpage')
547
- ? '#06AA3E'
548
- : this.isPlat
549
- ? '#fff'
550
- : '#373737'}"
551
- @click="${this._routerPush}"
552
- data-login-url="https://www.weblca.net/databankpage"
553
- data-url="https://www.weblca.net/databankpage"
554
- >
555
- ${this.i18n['资料库']}
556
- </div>`
557
- : ''}
558
- ${this.isPlat
559
- ? html` <div
560
- class="menu-item menu-item-database"
561
- style=" position: relative;color: ${this.hostName.includes(
562
- 'efootprint.net/contest'
563
- )
564
- ? '#06AA3E'
565
- : this.isPlat
566
- ? '#fff'
567
- : '#373737'}"
568
- >
569
- ${this.i18n['LCA大赛']}
570
- <div class="menu-sub-group menu-sub-group-1">
571
- <div
572
- @click="${this._routerPush}"
573
- data-login-url="https://www.weblca.net/contest"
574
- data-url="https://www.weblca.net/contest"
575
- class="menu-sub-item"
576
- >
577
- ${this.i18n['2025全生命周期创新大赛']}
578
- </div>
579
- <div
580
- @click="${this._routerPush}"
581
- data-login-url="https://www.weblca.net/contest/cccd"
582
- data-url="https://www.weblca.net/contest/cccd"
583
- class="menu-sub-item"
584
- >
585
- ${this.i18n['化工专题比赛']}
586
- </div>
587
- </div>
588
- </div>`
589
- : ''}
590
- ${this.isPlat
591
- ? html` <div
592
- class="menu-item"
593
- style="color: ${this.hostName.includes(
594
- 'efootprint.net/training'
595
- )
596
- ? '#06AA3E'
597
- : this.isPlat
598
- ? '#fff'
599
- : '#373737'}"
600
- @click="${this._routerPush}"
601
- data-login-url="https://www.weblca.net/training"
602
- data-url="https://www.weblca.net/training"
603
- >
604
- ${this.i18n['专业培训']}
605
- </div>`
606
- : ''}
607
- <div
608
- class="menu-item"
609
- style="color: ${this.isPlat ? '#fff' : '#373737'}"
610
- @click="${this._scroll}"
611
- data-login-url="#"
612
- data-url="#"
613
- >
614
- ${this.i18n['联系我们']}
615
- </div>
616
-
617
- ${this.isShowLang
618
- ? html` <div
619
- class="menu-item menu-item-database"
620
- style=" position: relative;
621
- text-align: center;
622
- display: flex;
623
- align-items: center;
624
- color: ${this.hostName.includes(
625
- 'weblca.net/database'
626
- )
627
- ? '#06AA3E'
628
- : this.isPlat
629
- ? '#fff'
630
- : '#373737'}"
631
- >
632
- ${this.isPlat
633
- ? html`<img
634
- src="http://ike-web.oss-cn-hangzhou.aliyuncs.com/language.png"
635
- alt=""
636
- />`
637
- : html`<img
638
- src="http://ike-web.oss-cn-hangzhou.aliyuncs.com/language_block.png"
639
- alt=""
640
- />`}
641
- <div class="menu-sub-group">
642
- <div
643
- @click="${this._clickLang}"
644
- data-lang="zh_CN"
645
- class="menu-sub-item"
646
- >
647
- 中文简体
648
- </div>
649
- <div
650
- @click="${this._clickLang}"
651
- data-lang="zh_TW"
652
- class="menu-sub-item"
653
- >
654
- 中文繁體
655
- </div>
656
- <div
657
- @click="${this._clickLang}"
658
- data-lang="en_US"
659
- class="menu-sub-item"
660
- >
661
- English
662
- </div>
663
- </div>
664
- </div>`
665
- : ''}
666
-
667
- <!-- 消息图标 - 仅在登录状态下显示 -->
668
- ${this.isLoggedIn
669
- ? html`
670
- <div
671
- @click="${this._routerPush}"
672
- data-login-url="https://www.weblca.net/notification"
673
- data-url="https://www.weblca.net/notification"
674
- class="message-icon-container"
675
- >
676
- <img
677
- src="https://ike-web.oss-cn-hangzhou.aliyuncs.com/message.png"
678
- alt="消息"
679
- class="message-icon"
680
- />
681
- <div class="message-badge">${this.messageCount}</div>
682
- </div>
683
- `
684
- : ''}
685
-
686
- <!-- 登录/首页按钮 -->
687
- ${this.isPlat
688
- ? html` <div
689
- class="login-button"
690
- style="border-color: ${this.isPlat
691
- ? '#fff'
692
- : '#373737'}; color: ${this.isPlat ? '#fff' : '#373737'}"
693
- @click="${this._handleLoginClick}"
694
- >
695
- ${this.isLoggedIn ? this.i18n['个人中心'] : this.i18n['登录']}
696
- </div>`
697
- : ''}
698
-
699
- <!-- <div class="menu-item">-->
700
- <!-- <el-icon style="cursor: pointer" size="28" color="#fff">-->
701
- <!-- <UserFilled/>-->
702
- <!-- </el-icon>-->
703
- <!-- </div>-->
704
- </div>
705
- </div>
706
- </div>
707
- </div>`
708
- }
709
-
710
- _routerPush(e) {
711
- e.stopPropagation()
712
- // @ts-ignore
713
- let to = e.currentTarget && e.currentTarget.getAttribute('data-url')
714
- let loginUrl =
715
- e.currentTarget && e.currentTarget.getAttribute('data-login-url')
716
-
717
- // 根据登录状态选择跳转URL
718
- if (loginUrl && this.isLoggedIn) {
719
- to = loginUrl
720
- }
721
- //192,www ,以及 to之中包含online的都不需要替换
722
- // @ts-ignore
723
- if (
724
- this.status !== '192' &&
725
- this.status !== 'www' &&
726
- this.status !== 'online' &&
727
- !to.includes('online')
728
- ) {
729
- to = to.replace('www', this.status)
730
- }
731
- window.location.href = to
732
- window.parent.postMessage({ type: 'navigate', url: to }, '*')
733
- }
734
-
735
- _clickLang(e) {
736
- e.stopPropagation()
737
- // @ts-ignore
738
- let lang = e.currentTarget && e.currentTarget.getAttribute('data-lang')
739
- //192,www ,以及 to之中包含online的都不需要替换
740
- // @ts-ignore
741
- localStorage.setItem('lang', lang)
742
- window.location.reload()
743
- // window.parent.postMessage({type: 'navigate', url: to}, '*');
744
- }
745
-
746
- _scroll() {
747
- let box = document.body
748
- // console.log(box.clientHeight)
749
- window.scrollTo({
750
- top: document.documentElement.scrollHeight,
751
- behavior: 'smooth',
752
- })
753
- }
754
-
755
- _handleLoginClick() {
756
- if (this.isLoggedIn) {
757
- // 如果已登录,跳转到首页
758
- window.location.href = 'https://www.weblca.net/selfCenter'
759
- } else {
760
- // 如果未登录,跳转到登录页面
761
- window.location.href = 'https://www.weblca.net/login'
762
- }
763
- }
764
- }
765
-
766
- customElements.define('ike-web-header', IkeWebHeader)
1
+ import { css, html, LitElement } from 'lit-element'
2
+ import { property } from 'lodash-es'
3
+ import cookies from 'js-cookie'
4
+
5
+ /**
6
+ * IkeWebHeader - Web LCA 网站头部组件
7
+ *
8
+ * 这是一个基于 LitElement 的 Web Components 组件,用于渲染网站的头部导航栏。
9
+ * 支持多语言切换、动态菜单显示、响应式设计等功能。
10
+ *
11
+ * 主要功能:
12
+ * - 多语言支持(简体中文、繁体中文、英文)
13
+ * - 根据域名动态显示不同的菜单项
14
+ * - 支持个性化配置(logo、机构名称等)
15
+ * - 响应式导航菜单
16
+ * - 平滑滚动到页面底部
17
+ * - 登录状态检测和相应的URL跳转逻辑
18
+ */
19
+ export class IkeWebHeader extends LitElement {
20
+ /**
21
+ * 组件样式定义
22
+ * 包含头部容器、菜单项、子菜单、悬停效果等样式
23
+ */
24
+ static styles = css`
25
+ .ike-web-header {
26
+ width: 100%;
27
+ box-sizing: border-box;
28
+ height: 72px;
29
+ display: flex;
30
+ padding: 0 72px;
31
+ background: var(--ike-web-header-bg, #063223);
32
+ align-items: center;
33
+ justify-content: space-between;
34
+ border-bottom: 1px solid rgba(211, 211, 211, 0.3);
35
+ }
36
+
37
+ .iwh-url {
38
+ max-width: 220px;
39
+ max-height: 40px;
40
+ display: inline-block;
41
+ }
42
+
43
+ .header-list {
44
+ color: #fff !important;
45
+ height: 72px;
46
+ }
47
+
48
+ .menu-item:hover {
49
+ background: rgba(0, 162, 44, 0.1);
50
+ color: var(--ike-web-header-text-color, '#fff');
51
+ }
52
+
53
+ .el-menu-demo {
54
+ display: flex;
55
+ align-items: center;
56
+ cursor: pointer;
57
+ color: #fff;
58
+ background: transparent;
59
+ border: none;
60
+ }
61
+
62
+ .posi {
63
+ position: absolute;
64
+ top: 20%;
65
+ left: 70%;
66
+ }
67
+
68
+ .box-a {
69
+ display: inline-block;
70
+ margin-left: 30px;
71
+ }
72
+
73
+ .box-a img {
74
+ width: auto;
75
+ height: 40px;
76
+ }
77
+
78
+ .left-menu-items {
79
+ display: flex;
80
+ align-items: center;
81
+ margin-left: 20px;
82
+ }
83
+
84
+ .left-menu-item {
85
+ padding: 0 15px;
86
+ font-size: 14px;
87
+ height: 72px;
88
+ display: flex;
89
+ align-items: center;
90
+ cursor: pointer;
91
+ border-radius: 4px;
92
+ transition: background-color 0.3s ease;
93
+ }
94
+
95
+ .left-menu-item:hover {
96
+ background: rgba(0, 162, 44, 0.1);
97
+ }
98
+
99
+ .menu-item {
100
+ padding: 0 20px;
101
+ font-size: 14px;
102
+ height: 72px;
103
+ text-align: center;
104
+ box-sizing: border-box;
105
+ display: flex;
106
+ align-items: center;
107
+ }
108
+
109
+ .menu-item-database {
110
+ position: relative;
111
+ }
112
+
113
+ .menu-sub-group {
114
+ background: #e6f2e8;
115
+ position: absolute;
116
+ z-index: 999;
117
+ width: 150%;
118
+ //bottom: -72px;
119
+ top: 100%;
120
+ left: -50%;
121
+ padding: 20px 20px 0 20px;
122
+ //transform: translateX(50%);
123
+ color: #06aa3e;
124
+ box-shadow: 0px 0px 4px 0px rgba(6, 50, 35, 0.53);
125
+ border-radius: 0px 0px 8px 8px;
126
+ display: none;
127
+ transition: opacity 0.3s ease;
128
+ opacity: 0;
129
+ }
130
+ .menu-sub-group-1 {
131
+ width: 280px;
132
+ left: 50%;
133
+ transform: translateX(-50%);
134
+ }
135
+ .menu-sub-item {
136
+ padding-bottom: 20px;
137
+ color: #373737;
138
+ }
139
+ .menu-sub-item:hover {
140
+ color: #06aa3e;
141
+ }
142
+
143
+ .menu-item-database:hover .menu-sub-group {
144
+ display: block;
145
+ opacity: 1;
146
+ }
147
+
148
+ /* 消息图标样式 */
149
+ .message-icon-container {
150
+ position: relative;
151
+ display: flex;
152
+ align-items: center;
153
+ margin: 0 15px;
154
+ cursor: pointer;
155
+ }
156
+
157
+ .message-icon {
158
+ width: 24px;
159
+ height: 24px;
160
+ }
161
+
162
+ .message-badge {
163
+ position: absolute;
164
+ top: -8px;
165
+ right: -8px;
166
+ background: linear-gradient(90deg, #ffbb24 0%, #ff9900 100%);
167
+ color: white;
168
+ border-radius: 50%;
169
+ width: 18px;
170
+ height: 18px;
171
+ display: flex;
172
+ align-items: center;
173
+ justify-content: center;
174
+ font-size: 12px;
175
+ font-weight: bold;
176
+ }
177
+
178
+ /* 登录按钮样式 */
179
+ .login-button {
180
+ padding: 8px 16px;
181
+ border: 1px solid;
182
+ border-radius: 4px;
183
+ cursor: pointer;
184
+ font-size: 14px;
185
+ transition: all 0.3s ease;
186
+ margin-left: 15px;
187
+ }
188
+
189
+ .login-button:hover {
190
+ opacity: 0.8;
191
+ }
192
+
193
+ .user-menu {
194
+ position: relative;
195
+ display: flex;
196
+ align-items: center;
197
+ margin-left: 12px;
198
+ cursor: pointer;
199
+ user-select: none;
200
+ }
201
+
202
+ .user-avatar {
203
+ width: 32px;
204
+ height: 32px;
205
+ border-radius: 50%;
206
+ object-fit: cover;
207
+ border: 1px solid rgba(255, 255, 255, 0.6);
208
+ background: #e9ecef;
209
+ }
210
+
211
+ .user-caret {
212
+ margin-left: 6px;
213
+ width: 0;
214
+ height: 0;
215
+ border-left: 4px solid transparent;
216
+ border-right: 4px solid transparent;
217
+ border-top: 6px solid #ffffff;
218
+ }
219
+
220
+ .user-dropdown {
221
+ position: absolute;
222
+ right: 0;
223
+ top: 48px;
224
+ min-width: 320px;
225
+ background: #ffffff;
226
+ color: #333333;
227
+ border-radius: 12px;
228
+ box-shadow: 0 12px 24px rgba(6, 50, 35, 0.18);
229
+ padding: 16px;
230
+ display: none;
231
+ opacity: 0;
232
+ transition: opacity 0.2s ease;
233
+ z-index: 1000;
234
+ }
235
+
236
+ .user-menu.open .user-dropdown {
237
+ display: block;
238
+ opacity: 1;
239
+ }
240
+
241
+ .user-summary {
242
+ display: flex;
243
+ align-items: center;
244
+ margin-bottom: 12px;
245
+ }
246
+
247
+ .user-avatar-large {
248
+ width: 48px;
249
+ height: 48px;
250
+ border-radius: 50%;
251
+ object-fit: cover;
252
+ margin-right: 12px;
253
+ background: #e9ecef;
254
+ }
255
+
256
+ .user-name {
257
+ font-size: 16px;
258
+ font-weight: 600;
259
+ margin-bottom: 4px;
260
+ }
261
+
262
+ .user-id {
263
+ font-size: 12px;
264
+ color: #666666;
265
+ }
266
+
267
+ .user-stats {
268
+ display: grid;
269
+ grid-template-columns: repeat(4, 1fr);
270
+ gap: 8px;
271
+ margin-bottom: 12px;
272
+ text-align: center;
273
+ }
274
+
275
+ .user-stat-value {
276
+ font-size: 16px;
277
+ font-weight: 600;
278
+ color: #063223;
279
+ }
280
+
281
+ .user-stat-label {
282
+ font-size: 12px;
283
+ color: #666666;
284
+ white-space: nowrap;
285
+ }
286
+
287
+ .user-actions {
288
+ display: flex;
289
+ align-items: center;
290
+ justify-content: space-between;
291
+ border-top: 1px solid #f0f0f0;
292
+ padding-top: 12px;
293
+ }
294
+
295
+ .user-action {
296
+ display: flex;
297
+ align-items: center;
298
+ justify-content: center;
299
+ flex: 1;
300
+ padding: 8px 0;
301
+ font-size: 14px;
302
+ color: #063223;
303
+ cursor: pointer;
304
+ border-radius: 6px;
305
+ transition: background-color 0.2s ease;
306
+ }
307
+
308
+ .user-action:hover {
309
+ background: rgba(6, 50, 35, 0.08);
310
+ }
311
+
312
+ .user-action + .user-action {
313
+ margin-left: 8px;
314
+ }
315
+ `
316
+
317
+ // ==================== 环境和状态相关属性 ====================
318
+
319
+ /** 当前网站状态,基于域名的第一部分 */
320
+ status = window.location.hostname.split('.')[0]
321
+
322
+ /** 当前页面完整URL */
323
+ hostName = window.location.href
324
+
325
+ /** 是否为平台版本(www、192、online环境) */
326
+ isPlat =
327
+ this.status === 'www' || this.status === '192' || this.status === 'online'
328
+
329
+ /** 是否显示语言切换功能 */
330
+ isShowLang =
331
+ this.status === 'www' ||
332
+ this.status === 'nanozeo' ||
333
+ this.status === '192' ||
334
+ this.status === 'online'
335
+
336
+ // ==================== 数据相关属性 ====================
337
+
338
+ /** 从API获取的数据 */
339
+ data = []
340
+
341
+ /** 个性化配置JSON数据 */
342
+ personalizedConfigJson
343
+
344
+ /** 机构logo URL */
345
+ logo
346
+
347
+ /** 机构联系方式 */
348
+ orgContacts
349
+
350
+ /** 机构名称 */
351
+ name
352
+
353
+ /** 机构邮箱 */
354
+ email
355
+
356
+ /** 机构电话 */
357
+ phone
358
+
359
+ /** 机构地址 */
360
+ address
361
+
362
+ /** 关注链接 */
363
+ followUrl
364
+
365
+ /** 已开通的服务列表 */
366
+ alreadyServices
367
+
368
+ // ==================== 多语言相关属性 ====================
369
+
370
+ /** 当前语言 */
371
+ currentLanguage = 'zh_CN'
372
+
373
+ /** 简体中文语言包 */
374
+ zhCN = {
375
+ 首页: '首页',
376
+ 数据库: '数据库',
377
+ 资料库: '资料库',
378
+ 皮革LCA数据库: '皮革LCA数据库',
379
+ LCA大赛: 'LCA大赛',
380
+ 专业培训: '专业培训',
381
+ 联系我们: '联系我们',
382
+ 标准库: '标准库',
383
+ 核算模版: '核算模版',
384
+ '2025全生命周期创新大赛': '2025全生命周期创新大赛',
385
+
386
+ 化工专题比赛: '2025首届中国化工产品碳足迹数据库大赛',
387
+ 登录: '登录',
388
+ 个人中心: '个人中心',
389
+ }
390
+
391
+ /** 繁体中文语言包 */
392
+ zhTW = {
393
+ 首页: '首頁',
394
+ 数据库: '數據庫',
395
+ 资料库: '資料庫',
396
+ 皮革LCA数据库: '皮革LCA數據庫',
397
+ LCA大赛: 'LCA大賽',
398
+ 专业培训: '專業培訓',
399
+ 联系我们: '聯繫我們',
400
+ 标准库: '標準庫',
401
+ 核算模版: '核算模版',
402
+ '2025全生命周期创新大赛': '2025全生命週期創新大賽',
403
+ 化工专题比赛: '2025首届中國化工產品碳足迹資料庫大賽',
404
+ 登录: '登录',
405
+ 个人中心: '个人中心',
406
+ }
407
+
408
+ /** 英文语言包 */
409
+ enUS = {
410
+ 首页: 'Home',
411
+ 数据库: 'Database',
412
+ 资料库: 'Database',
413
+ 皮革LCA数据库: 'Leather LCA Database',
414
+ LCA大赛: 'LCA Competition',
415
+ 专业培训: 'Professional Training',
416
+ 联系我们: 'Contact Us',
417
+ 标准库: 'Standard Library',
418
+ 核算模版: 'Calculation Template',
419
+ '2025全生命周期创新大赛': '2025 Life Cycle Innovation Competition',
420
+ 化工专题比赛:
421
+ '2025 First China Chemical Product Carbon Footprint Database Competition',
422
+ 登录: 'Login',
423
+ 个人中心: 'Personal Center',
424
+ }
425
+
426
+ /** 当前使用的国际化对象 */
427
+ i18n = {}
428
+
429
+ /** 浏览器默认语言 */
430
+ createLang = navigator.language.replace('-', '_')
431
+
432
+ /** 用户选择的语言(优先从localStorage获取,否则使用浏览器语言) */
433
+ lang = window.localStorage.getItem('lang') || this.createLang
434
+
435
+ /** 登录状态检测 - 检查cookie中是否存在token */
436
+ isLoggedIn = !!cookies.get('token')
437
+
438
+ /** logged in user summary */
439
+ userSummary = null
440
+
441
+ /** user avatar */
442
+ userAvatar = ''
443
+
444
+ /** user name */
445
+ userName = ''
446
+
447
+ /** user id */
448
+ userId = ''
449
+
450
+ /** user stats */
451
+ userStats = {
452
+ account: 0,
453
+ group: 0,
454
+ database: 0,
455
+ databank: 0,
456
+ }
457
+
458
+ /** user menu open state */
459
+ isUserMenuOpen = false
460
+
461
+ _documentClickHandler = null
462
+
463
+ /** 消息数量(当前写死为1) */
464
+ messageCount = 1
465
+
466
+ connectedCallback() {
467
+ switch (this.lang) {
468
+ case 'zh':
469
+ this.currentLanguage = 'zh_CN'
470
+ this.i18n = this.zhCN
471
+ break
472
+ case 'zh_CN':
473
+ this.currentLanguage = 'zh_CN'
474
+ this.i18n = this.zhCN
475
+ break
476
+ case 'zh_TW':
477
+ this.currentLanguage = 'zh_TW'
478
+ this.i18n = this.zhTW
479
+ break
480
+ case 'en_US':
481
+ this.currentLanguage = 'en_US'
482
+ this.i18n = this.enUS
483
+ break
484
+ default:
485
+ this.currentLanguage = 'zh_CN'
486
+ this.i18n = this.zhCN
487
+ break
488
+ }
489
+
490
+ super.connectedCallback()
491
+ this.fetchData()
492
+ if (this.isLoggedIn) {
493
+ this.fetchUserSummary()
494
+ }
495
+ this._documentClickHandler = this._handleDocumentClick.bind(this)
496
+ document.addEventListener('click', this._documentClickHandler)
497
+ }
498
+
499
+ disconnectedCallback() {
500
+ if (this._documentClickHandler) {
501
+ document.removeEventListener('click', this._documentClickHandler)
502
+ }
503
+ super.disconnectedCallback()
504
+ }
505
+
506
+ // @ts-ignore
507
+ async fetchData() {
508
+ try {
509
+ const response = await fetch(
510
+ 'https://backsite.efootprint.net/Gpm/webLcaOrganization/GetOrganizationByDomain'
511
+ ) // 替换为实际的 API 地址
512
+ const jsonData = await response.json()
513
+ let data = jsonData.data // 将获取到的数据保存到 data 属性中
514
+ if (data && data.personalizedConfigJson) {
515
+ this.personalizedConfigJson = JSON.parse(data.personalizedConfigJson)
516
+ }
517
+ // console.log('this.data.data.personalizedConfigJson', this.personalizedConfigJson)
518
+ this.logo =
519
+ this.personalizedConfigJson && this.personalizedConfigJson.logo
520
+ this.orgContacts =
521
+ this.personalizedConfigJson && this.personalizedConfigJson.orgContacts
522
+ this.name =
523
+ this.personalizedConfigJson &&
524
+ this.personalizedConfigJson.institution &&
525
+ this.personalizedConfigJson.institution.name
526
+ this.email =
527
+ this.personalizedConfigJson && this.personalizedConfigJson.orgEmail
528
+ this.phone =
529
+ this.personalizedConfigJson && this.personalizedConfigJson.orgPhone
530
+ this.address =
531
+ this.personalizedConfigJson && this.personalizedConfigJson.orgAddress
532
+ this.followUrl =
533
+ this.personalizedConfigJson && this.personalizedConfigJson.followUrl
534
+ this.alreadyServices = data.alreadyServices
535
+ setTimeout(() => this.requestUpdate())
536
+ // this.requestUpdate(); // 更新组件以触发重新渲染
537
+ } catch (error) {
538
+ // console.error('Error fetching data:', error);
539
+ }
540
+ }
541
+
542
+ _getUserSummaryUrl() {
543
+ const hostname = window.location.hostname
544
+ const isLocal =
545
+ hostname === '192.168.10.30' ||
546
+ hostname === 'localhost' ||
547
+ hostname.startsWith('192.168.10.')
548
+ return isLocal
549
+ ? 'http://192.168.10.175:41010/api/services/app/User/GetUserSummaryByHomePage'
550
+ : 'https://backsite.efootprint.net/ef_weblca/user/getUserSummaryByHomePage'
551
+ }
552
+
553
+ _getChangeSysUrl() {
554
+ const hostname = window.location.hostname
555
+ const isLocal =
556
+ hostname === '192.168.10.30' ||
557
+ hostname === 'localhost' ||
558
+ hostname.startsWith('192.168.10.')
559
+ return isLocal
560
+ ? 'http://192.168.10.175:41010/ids4/connect/changesys'
561
+ : 'https://backsite.efootprint.net/ids4/connect/changesys'
562
+ }
563
+
564
+ async _handleServiceClick(e) {
565
+ e.stopPropagation()
566
+ // @ts-ignore
567
+ const target = e.currentTarget
568
+ const loginUrl = target && target.getAttribute('data-login-url')
569
+ const url = target && target.getAttribute('data-url')
570
+
571
+ if (!this.isLoggedIn) {
572
+ // 未登录,直接跳转到 data-url
573
+ window.location.href = url
574
+ return
575
+ }
576
+
577
+ // 已登录,请求接口
578
+ const token = cookies.get('token')
579
+ if (!token) {
580
+ window.location.href = url
581
+ return
582
+ }
583
+
584
+ try {
585
+ const formData = new FormData()
586
+ formData.append('access_token', token)
587
+
588
+ const apiUrl = this._getChangeSysUrl()
589
+
590
+ const response = await fetch(apiUrl, {
591
+ method: 'POST',
592
+ headers: {
593
+ Authorization: token,
594
+ },
595
+ body: formData,
596
+ })
597
+
598
+ const res = await response.json()
599
+ if (res.success && res.data) {
600
+ const { sc, timestamp, sign } = res.data
601
+ // 拼接参数
602
+ const separator = loginUrl.includes('?') ? '&' : '?'
603
+ const finalUrl = `${loginUrl}${separator}sc=${sc}&timestamp=${timestamp}&sign=${sign}`
604
+
605
+ // 新标签页打开
606
+ window.open(finalUrl, '_blank')
607
+ } else {
608
+ // 接口调用失败,降级处理
609
+ window.open(loginUrl, '_blank')
610
+ }
611
+ } catch (err) {
612
+ console.error('Error during service jump:', err)
613
+ window.open(loginUrl, '_blank')
614
+ }
615
+ }
616
+
617
+ _getDefaultAvatar() {
618
+ return 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><circle cx="32" cy="32" r="32" fill="%23e9ecef"/><circle cx="32" cy="24" r="12" fill="%239aa1a9"/><path d="M10 58c4-12 16-18 22-18s18 6 22 18" fill="%239aa1a9"/></svg>'
619
+ }
620
+
621
+ async fetchUserSummary() {
622
+ const token = cookies.get('token')
623
+ if (!token) return
624
+ try {
625
+ const response = await fetch(this._getUserSummaryUrl(), {
626
+ method: 'GET',
627
+ headers: {
628
+ Authorization: token,
629
+ },
630
+ })
631
+ const jsonData = await response.json()
632
+ const data =
633
+ jsonData &&
634
+ (jsonData.data || jsonData.result || jsonData.user || jsonData)
635
+ this.userSummary = data || {}
636
+ this.userName =
637
+ data?.userName ||
638
+ data?.username ||
639
+ data?.realName ||
640
+ data?.name ||
641
+ data?.nickName ||
642
+ ''
643
+ this.userId = data?.userId || data?.id || data?.userCode || ''
644
+ this.userAvatar =
645
+ data?.avatar || data?.headImg || data?.headUrl || data?.photo || ''
646
+ this.userStats = {
647
+ account: data?.accountCount || 0,
648
+ group: data?.groupCount || 0,
649
+ database: data?.datasetCount || 0,
650
+ databank: data?.materialCount || 0,
651
+ }
652
+ setTimeout(() => this.requestUpdate())
653
+ } catch (error) {
654
+ // console.error('Error fetching user summary:', error)
655
+ }
656
+ }
657
+
658
+ _toggleUserMenu(e) {
659
+ e.stopPropagation()
660
+ this.isUserMenuOpen = !this.isUserMenuOpen
661
+ this.requestUpdate()
662
+ }
663
+
664
+ _stopPropagation(e) {
665
+ e.stopPropagation()
666
+ }
667
+
668
+ _handleDocumentClick(e) {
669
+ const path = e.composedPath ? e.composedPath() : []
670
+ if (path.includes(this)) return
671
+ if (this.isUserMenuOpen) {
672
+ this.isUserMenuOpen = false
673
+ this.requestUpdate()
674
+ }
675
+ }
676
+
677
+ _goPersonalCenter(e) {
678
+ if (e) e.stopPropagation()
679
+ window.location.href = 'https://www.weblca.net/selfCenter'
680
+ }
681
+
682
+ _logout(e) {
683
+ if (e) e.stopPropagation()
684
+ const allCookies = cookies.get() || {}
685
+ Object.keys(allCookies).forEach((key) => {
686
+ cookies.remove(key)
687
+ cookies.remove(key, { path: '/' })
688
+ })
689
+ window.location.reload()
690
+ }
691
+
692
+ render() {
693
+ return html` <div
694
+ class="ike-web-header"
695
+ style="
696
+ background: ${this.isPlat
697
+ ? '#063223'
698
+ : '#FFFFFF'}; color: ${this.isPlat ? '#fff' : '#063223'}"
699
+ >
700
+ <div style="display: flex;align-items: center">
701
+ <img
702
+ src="https://ike-web.oss-cn-hangzhou.aliyuncs.com/WebLCA_logo.png"
703
+ class="iwh-url"
704
+ alt=""
705
+ />
706
+ ${this.status !== 'www' && this.status !== '192'
707
+ ? html` <div class="box-a" style="display: flex;align-items: center">
708
+ <img src="${this.logo}" alt="" />
709
+ <span
710
+ style="margin-left: 12px;color: #373737;font-weight: 600;color: ${this
711
+ .isPlat
712
+ ? '#fff'
713
+ : '#063223'}"
714
+ >${this.name}</span
715
+ >
716
+ </div>`
717
+ : ''}
718
+
719
+ <!-- 左侧菜单项:eFootprint、CarbonZero、GPM -->
720
+ ${this.isPlat
721
+ ? html` <div class="left-menu-items">
722
+ ${this.isPlat || this.alreadyServices.includes('eF')
723
+ ? html` <div
724
+ class="left-menu-item"
725
+ style="color: ${this.hostName.includes(
726
+ 'efootprint.net/login'
727
+ )
728
+ ? '#06AA3E'
729
+ : this.isPlat
730
+ ? '#fff'
731
+ : '#373737'}"
732
+ @click="${this._handleServiceClick}"
733
+ data-url="https://www.weblca.net/content/login"
734
+ data-login-url="https://www.efootprint.net/jump"
735
+ >
736
+ eFootprint
737
+ </div>`
738
+ : ''}
739
+ ${this.isPlat || this.alreadyServices.includes('scope')
740
+ ? html` <div
741
+ class="left-menu-item"
742
+ style="color: ${this.hostName.includes('webcarbon.net')
743
+ ? '#06AA3E'
744
+ : this.isPlat
745
+ ? '#fff'
746
+ : '#373737'}"
747
+ @click="${this._handleServiceClick}"
748
+ data-login-url="https://www.webcarbon.net/#/converter"
749
+ data-url="https://www.weblca.net/content/login"
750
+ >
751
+ CarbonZero
752
+ </div>`
753
+ : ''}
754
+ ${this.isPlat || this.alreadyServices.includes('GPM')
755
+ ? html` <div
756
+ class="left-menu-item"
757
+ style="color: ${this.hostName.includes('webgpm.net')
758
+ ? '#06AA3E'
759
+ : this.isPlat
760
+ ? '#fff'
761
+ : '#373737'}"
762
+ @click="${this._handleServiceClick}"
763
+ data-login-url="https://www.webgpm.net/#/jump"
764
+ data-url="https://www.weblca.net/content/login"
765
+ >
766
+ GPM
767
+ </div>`
768
+ : ''}
769
+ </div>`
770
+ : ''}
771
+ </div>
772
+
773
+ <div class="iwh-right">
774
+ <div class="header-list flex align-center">
775
+ <div class="el-menu-demo">
776
+ <div
777
+ class="menu-item"
778
+ style="color: ${this.hostName.includes('weblca.net/home')
779
+ ? '#06AA3E'
780
+ : this.isPlat
781
+ ? '#fff'
782
+ : '#373737'}"
783
+ @click="${this._routerPush}"
784
+ data-login-url="https://www.weblca.net/home"
785
+ data-url="https://www.weblca.net/home"
786
+ >
787
+ ${this.i18n['首页']}
788
+ </div>
789
+
790
+ <!-- 平台专属菜单项:标准库和核算模板 -->
791
+ ${this.isPlat
792
+ ? html` <div
793
+ class="menu-item"
794
+ style="color: ${this.isPlat ? '#fff' : '#373737'}"
795
+ @click="${this._routerPush}"
796
+ data-login-url="https://www.weblca.net/standard"
797
+ data-url="https://www.weblca.net/standard"
798
+ >
799
+ ${this.i18n['标准库']}
800
+ </div>
801
+ <div
802
+ class="menu-item"
803
+ style="color: ${this.isPlat ? '#fff' : '#373737'}"
804
+ @click="${this._routerPush}"
805
+ data-login-url="https://www.weblca.net/template"
806
+ data-url="https://www.weblca.net/template"
807
+ >
808
+ ${this.i18n['核算模版']}
809
+ </div>`
810
+ : ''}
811
+ ${this.isPlat || this.alreadyServices.includes('database')
812
+ ? html` <div
813
+ class="menu-item menu-item-database"
814
+ style=" position: relative;color: ${this.hostName.includes(
815
+ 'weblca.net/database'
816
+ )
817
+ ? '#06AA3E'
818
+ : this.isPlat
819
+ ? '#fff'
820
+ : '#373737'}"
821
+ @click="${this._routerPush}"
822
+ data-login-urlurl="https://www.weblca.net/database"
823
+ data-url="https://www.weblca.net/database"
824
+ >
825
+ ${this.isPlat
826
+ ? html`<img
827
+ class="posi"
828
+ src="https://ike-web.oss-cn-hangzhou.aliyuncs.com/HOT.png"
829
+ alt=""
830
+ />`
831
+ : ''}
832
+ ${this.i18n['数据库']}
833
+ <div class="menu-sub-group">
834
+ <div
835
+ @click="${this._routerPush}"
836
+ data-login-url="https://www.weblca.net/database"
837
+ data-url="https://www.weblca.net/database"
838
+ class="menu-sub-item"
839
+ >
840
+ ${this.i18n['数据库']}
841
+ </div>
842
+ <div
843
+ @click="${this._routerPush}"
844
+ data-login-url="https://www.weblca.net/database/leather"
845
+ data-url="https://www.weblca.net/database/leather"
846
+ class="menu-sub-item"
847
+ >
848
+ ${this.i18n['皮革LCA数据库']}
849
+ </div>
850
+ </div>
851
+ </div>`
852
+ : ''}
853
+ ${this.isPlat || this.alreadyServices.includes('databankpage')
854
+ ? html` <div
855
+ class="menu-item"
856
+ style="color: ${this.hostName.includes('/databankpage')
857
+ ? '#06AA3E'
858
+ : this.isPlat
859
+ ? '#fff'
860
+ : '#373737'}"
861
+ @click="${this._routerPush}"
862
+ data-login-url="https://www.weblca.net/databankpage"
863
+ data-url="https://www.weblca.net/databankpage"
864
+ >
865
+ ${this.i18n['资料库']}
866
+ </div>`
867
+ : ''}
868
+ ${this.isPlat
869
+ ? html` <div
870
+ class="menu-item menu-item-database"
871
+ style=" position: relative;color: ${this.hostName.includes(
872
+ 'efootprint.net/contest'
873
+ )
874
+ ? '#06AA3E'
875
+ : this.isPlat
876
+ ? '#fff'
877
+ : '#373737'}"
878
+ >
879
+ ${this.i18n['LCA大赛']}
880
+ <div class="menu-sub-group menu-sub-group-1">
881
+ <div
882
+ @click="${this._routerPush}"
883
+ data-login-url="https://www.weblca.net/contest"
884
+ data-url="https://www.weblca.net/contest"
885
+ class="menu-sub-item"
886
+ >
887
+ ${this.i18n['2025全生命周期创新大赛']}
888
+ </div>
889
+ <div
890
+ @click="${this._routerPush}"
891
+ data-login-url="https://www.weblca.net/contest/cccd"
892
+ data-url="https://www.weblca.net/contest/cccd"
893
+ class="menu-sub-item"
894
+ >
895
+ ${this.i18n['化工专题比赛']}
896
+ </div>
897
+ </div>
898
+ </div>`
899
+ : ''}
900
+ ${this.isPlat
901
+ ? html` <div
902
+ class="menu-item"
903
+ style="color: ${this.hostName.includes(
904
+ 'efootprint.net/training'
905
+ )
906
+ ? '#06AA3E'
907
+ : this.isPlat
908
+ ? '#fff'
909
+ : '#373737'}"
910
+ @click="${this._routerPush}"
911
+ data-login-url="https://www.weblca.net/training"
912
+ data-url="https://www.weblca.net/training"
913
+ >
914
+ ${this.i18n['专业培训']}
915
+ </div>`
916
+ : ''}
917
+ <div
918
+ class="menu-item"
919
+ style="color: ${this.isPlat ? '#fff' : '#373737'}"
920
+ @click="${this._scroll}"
921
+ data-login-url="#"
922
+ data-url="#"
923
+ >
924
+ ${this.i18n['联系我们']}
925
+ </div>
926
+
927
+ ${this.isShowLang
928
+ ? html` <div
929
+ class="menu-item menu-item-database"
930
+ style=" position: relative;
931
+ text-align: center;
932
+ display: flex;
933
+ align-items: center;
934
+ color: ${this.hostName.includes(
935
+ 'weblca.net/database'
936
+ )
937
+ ? '#06AA3E'
938
+ : this.isPlat
939
+ ? '#fff'
940
+ : '#373737'}"
941
+ >
942
+ ${this.isPlat
943
+ ? html`<img
944
+ src="http://ike-web.oss-cn-hangzhou.aliyuncs.com/language.png"
945
+ alt=""
946
+ />`
947
+ : html`<img
948
+ src="http://ike-web.oss-cn-hangzhou.aliyuncs.com/language_block.png"
949
+ alt=""
950
+ />`}
951
+ <div class="menu-sub-group">
952
+ <div
953
+ @click="${this._clickLang}"
954
+ data-lang="zh_CN"
955
+ class="menu-sub-item"
956
+ >
957
+ 中文简体
958
+ </div>
959
+ <div
960
+ @click="${this._clickLang}"
961
+ data-lang="zh_TW"
962
+ class="menu-sub-item"
963
+ >
964
+ 中文繁体
965
+ </div>
966
+ <div
967
+ @click="${this._clickLang}"
968
+ data-lang="en_US"
969
+ class="menu-sub-item"
970
+ >
971
+ English
972
+ </div>
973
+ </div>
974
+ </div>`
975
+ : ''}
976
+
977
+ <!-- 消息图标 - 仅在登录状态下显示 -->
978
+ ${this.isLoggedIn
979
+ ? html`
980
+ <div
981
+ @click="${this._routerPush}"
982
+ data-login-url="https://www.weblca.net/notification"
983
+ data-url="https://www.weblca.net/notification"
984
+ class="message-icon-container"
985
+ >
986
+ <img
987
+ src="https://ike-web.oss-cn-hangzhou.aliyuncs.com/message.png"
988
+ alt="消息"
989
+ class="message-icon"
990
+ />
991
+ <div class="message-badge">${this.messageCount}</div>
992
+ </div>
993
+ `
994
+ : ''}
995
+
996
+ <!-- 登录/用户信息 -->
997
+ ${this.isPlat
998
+ ? this.isLoggedIn
999
+ ? html` <div
1000
+ class="user-menu ${this.isUserMenuOpen ? 'open' : ''}"
1001
+ @click="${this._toggleUserMenu}"
1002
+ >
1003
+ <img
1004
+ class="user-avatar"
1005
+ src="${this.userAvatar || this._getDefaultAvatar()}"
1006
+ alt="avatar"
1007
+ />
1008
+ <div
1009
+ class="user-caret"
1010
+ style="border-top-color: ${this.isPlat
1011
+ ? '#fff'
1012
+ : '#063223'}"
1013
+ ></div>
1014
+ <div
1015
+ class="user-dropdown"
1016
+ @click="${this._stopPropagation}"
1017
+ >
1018
+ <div class="user-summary">
1019
+ <img
1020
+ class="user-avatar-large"
1021
+ src="${this.userAvatar || this._getDefaultAvatar()}"
1022
+ alt="avatar"
1023
+ />
1024
+ <div>
1025
+ <div class="user-name">${this.userName || '-'}</div>
1026
+ <div class="user-id">
1027
+ 用户ID:${this.userId || '-'}
1028
+ </div>
1029
+ </div>
1030
+ </div>
1031
+ <div class="user-stats">
1032
+ <div>
1033
+ <div class="user-stat-value">
1034
+ ${this.userStats.account || 0}
1035
+ </div>
1036
+ <div class="user-stat-label">账号</div>
1037
+ </div>
1038
+ <div>
1039
+ <div class="user-stat-value">
1040
+ ${this.userStats.group || 0}
1041
+ </div>
1042
+ <div class="user-stat-label">工作组</div>
1043
+ </div>
1044
+ <div>
1045
+ <div class="user-stat-value">
1046
+ ${this.userStats.database || 0}
1047
+ </div>
1048
+ <div class="user-stat-label">我的数据库</div>
1049
+ </div>
1050
+ <div>
1051
+ <div class="user-stat-value">
1052
+ ${this.userStats.databank || 0}
1053
+ </div>
1054
+ <div class="user-stat-label">我的资料库</div>
1055
+ </div>
1056
+ </div>
1057
+ <div class="user-actions">
1058
+ <div
1059
+ class="user-action"
1060
+ @click="${this._goPersonalCenter}"
1061
+ >
1062
+ 个人中心
1063
+ </div>
1064
+ <div class="user-action" @click="${this._logout}">
1065
+ 退出登录
1066
+ </div>
1067
+ </div>
1068
+ </div>
1069
+ </div>`
1070
+ : html` <div
1071
+ class="login-button"
1072
+ style="border-color: ${this.isPlat
1073
+ ? '#fff'
1074
+ : '#373737'}; color: ${this.isPlat ? '#fff' : '#373737'}"
1075
+ @click="${this._handleLoginClick}"
1076
+ >
1077
+ ${this.i18n['登录']}
1078
+ </div>`
1079
+ : ''}
1080
+
1081
+ <!-- <div class="menu-item">-->
1082
+ <!-- <el-icon style="cursor: pointer" size="28" color="#fff">-->
1083
+ <!-- <UserFilled/>-->
1084
+ <!-- </el-icon>-->
1085
+ <!-- </div>-->
1086
+ </div>
1087
+ </div>
1088
+ </div>
1089
+ </div>`
1090
+ }
1091
+
1092
+ _routerPush(e) {
1093
+ e.stopPropagation()
1094
+ // @ts-ignore
1095
+ let to = e.currentTarget && e.currentTarget.getAttribute('data-url')
1096
+ let loginUrl =
1097
+ e.currentTarget && e.currentTarget.getAttribute('data-login-url')
1098
+
1099
+ // 根据登录状态选择跳转URL
1100
+ if (loginUrl && this.isLoggedIn) {
1101
+ to = loginUrl
1102
+ }
1103
+ //192,www ,以及 to之中包含online的都不需要替换
1104
+ // @ts-ignore
1105
+ if (
1106
+ this.status !== '192' &&
1107
+ this.status !== 'www' &&
1108
+ this.status !== 'online' &&
1109
+ !to.includes('online')
1110
+ ) {
1111
+ to = to.replace('www', this.status)
1112
+ }
1113
+ window.location.href = to
1114
+ window.parent.postMessage({ type: 'navigate', url: to }, '*')
1115
+ }
1116
+
1117
+ _clickLang(e) {
1118
+ e.stopPropagation()
1119
+ // @ts-ignore
1120
+ let lang = e.currentTarget && e.currentTarget.getAttribute('data-lang')
1121
+ //192,www ,以及 to之中包含online的都不需要替换
1122
+ // @ts-ignore
1123
+ localStorage.setItem('lang', lang)
1124
+ window.location.reload()
1125
+ // window.parent.postMessage({type: 'navigate', url: to}, '*');
1126
+ }
1127
+
1128
+ _scroll() {
1129
+ let box = document.body
1130
+ // console.log(box.clientHeight)
1131
+ window.scrollTo({
1132
+ top: document.documentElement.scrollHeight,
1133
+ behavior: 'smooth',
1134
+ })
1135
+ }
1136
+
1137
+ _handleLoginClick() {
1138
+ if (this.isLoggedIn) {
1139
+ // 如果已登录,跳转到首页
1140
+ window.location.href = 'https://www.weblca.net/selfCenter'
1141
+ } else {
1142
+ // 如果未登录,跳转到登录页面
1143
+ window.location.href = 'https://www.weblca.net/login'
1144
+ }
1145
+ }
1146
+ }
1147
+
1148
+ customElements.define('ike-web-header', IkeWebHeader)