Browse Source

feat: knowledge page

Signed-off-by: carlos <568187512@qq.com>
carlos 3 months ago
parent
commit
66b38155f3
74 changed files with 1656 additions and 191 deletions
  1. 1 1
      src/app/nz.config.ts
  2. 27 0
      src/app/pages/manager/knowledge/bank/bank.component.html
  3. 0 0
      src/app/pages/manager/knowledge/bank/bank.component.less
  4. 23 0
      src/app/pages/manager/knowledge/bank/bank.component.spec.ts
  5. 34 0
      src/app/pages/manager/knowledge/bank/bank.component.ts
  6. 1 0
      src/app/pages/manager/knowledge/bank/enterprise-input/enterprise-input.component.html
  7. 0 0
      src/app/pages/manager/knowledge/bank/enterprise-input/enterprise-input.component.less
  8. 23 0
      src/app/pages/manager/knowledge/bank/enterprise-input/enterprise-input.component.spec.ts
  9. 10 0
      src/app/pages/manager/knowledge/bank/enterprise-input/enterprise-input.component.ts
  10. 84 0
      src/app/pages/manager/knowledge/bank/risk-item-form/risk-item-form.component.html
  11. 0 0
      src/app/pages/manager/knowledge/bank/risk-item-form/risk-item-form.component.less
  12. 23 0
      src/app/pages/manager/knowledge/bank/risk-item-form/risk-item-form.component.spec.ts
  13. 17 0
      src/app/pages/manager/knowledge/bank/risk-item-form/risk-item-form.component.ts
  14. 49 0
      src/app/pages/manager/knowledge/bank/risk-item-list/risk-item-list.component.html
  15. 47 0
      src/app/pages/manager/knowledge/bank/risk-item-list/risk-item-list.component.less
  16. 23 0
      src/app/pages/manager/knowledge/bank/risk-item-list/risk-item-list.component.spec.ts
  17. 67 0
      src/app/pages/manager/knowledge/bank/risk-item-list/risk-item-list.component.ts
  18. 90 0
      src/app/pages/manager/knowledge/bank/risk-item-table/risk-item-table.component.html
  19. 0 0
      src/app/pages/manager/knowledge/bank/risk-item-table/risk-item-table.component.less
  20. 23 0
      src/app/pages/manager/knowledge/bank/risk-item-table/risk-item-table.component.spec.ts
  21. 59 0
      src/app/pages/manager/knowledge/bank/risk-item-table/risk-item-table.component.ts
  22. 72 0
      src/app/pages/manager/knowledge/bank/update-record/detail/detail.component.html
  23. 19 0
      src/app/pages/manager/knowledge/bank/update-record/detail/detail.component.less
  24. 23 0
      src/app/pages/manager/knowledge/bank/update-record/detail/detail.component.spec.ts
  25. 86 0
      src/app/pages/manager/knowledge/bank/update-record/detail/detail.component.ts
  26. 40 0
      src/app/pages/manager/knowledge/bank/update-record/update-record.component.html
  27. 19 0
      src/app/pages/manager/knowledge/bank/update-record/update-record.component.less
  28. 23 0
      src/app/pages/manager/knowledge/bank/update-record/update-record.component.spec.ts
  29. 70 0
      src/app/pages/manager/knowledge/bank/update-record/update-record.component.ts
  30. 1 0
      src/app/pages/manager/knowledge/doc/doc.component.html
  31. 0 0
      src/app/pages/manager/knowledge/doc/doc.component.less
  32. 23 0
      src/app/pages/manager/knowledge/doc/doc.component.spec.ts
  33. 12 0
      src/app/pages/manager/knowledge/doc/doc.component.ts
  34. 1 0
      src/app/pages/manager/knowledge/knowledge.component.html
  35. 0 0
      src/app/pages/manager/knowledge/knowledge.component.less
  36. 23 0
      src/app/pages/manager/knowledge/knowledge.component.spec.ts
  37. 11 0
      src/app/pages/manager/knowledge/knowledge.component.ts
  38. 31 0
      src/app/pages/manager/knowledge/knowledge.route.ts
  39. 18 0
      src/app/pages/manager/knowledge/list/list.component.html
  40. 1 0
      src/app/pages/manager/knowledge/list/list.component.less
  41. 23 0
      src/app/pages/manager/knowledge/list/list.component.spec.ts
  42. 32 0
      src/app/pages/manager/knowledge/list/list.component.ts
  43. 28 0
      src/app/pages/manager/knowledge/list/risk-category/risk-category.component.html
  44. 45 0
      src/app/pages/manager/knowledge/list/risk-category/risk-category.component.less
  45. 23 0
      src/app/pages/manager/knowledge/list/risk-category/risk-category.component.spec.ts
  46. 54 0
      src/app/pages/manager/knowledge/list/risk-category/risk-category.component.ts
  47. 37 0
      src/app/pages/manager/knowledge/list/risk-level/risk-level.component.html
  48. 52 0
      src/app/pages/manager/knowledge/list/risk-level/risk-level.component.less
  49. 23 0
      src/app/pages/manager/knowledge/list/risk-level/risk-level.component.spec.ts
  50. 61 0
      src/app/pages/manager/knowledge/list/risk-level/risk-level.component.ts
  51. 2 2
      src/app/pages/manager/layout/header/header.component.ts
  52. 2 2
      src/app/pages/manager/layout/sidebar/navigation/navigation.component.less
  53. 11 1
      src/app/pages/manager/manager.routes.ts
  54. 27 25
      src/app/pages/manager/workbench/my/hazard-statistics/hazard-statistics.component.html
  55. 1 1
      src/app/shared/custom-drawer/custom-drawer.component.less
  56. 0 14
      src/app/shared/secondary-tabs/secondary-tabs.component.html
  57. 0 46
      src/app/shared/secondary-tabs/secondary-tabs.component.less
  58. 0 22
      src/app/shared/secondary-tabs/secondary-tabs.component.spec.ts
  59. 0 56
      src/app/shared/secondary-tabs/secondary-tabs.component.ts
  60. 1 0
      src/app/shared/star/star.icon.svg
  61. 13 0
      src/app/shared/star/star.icon.ts
  62. 3 3
      src/app/shared/workbench-tabs/workbench-tabs.component.less
  63. 11 0
      src/assets/icons/danger.svg
  64. 11 0
      src/assets/icons/knowledge-bank.svg
  65. 6 0
      src/assets/icons/knowledge-doc.svg
  66. 12 0
      src/assets/icons/knowledge-list.svg
  67. BIN
      src/assets/images/drawer-arrow.png
  68. 1 0
      src/styles.less
  69. 36 15
      src/styles/custom.less
  70. 63 0
      src/styles/knowledge.less
  71. 2 0
      src/styles/variables.less
  72. 1 1
      src/styles/workbench.less
  73. 0 1
      src/types/common.d.ts
  74. 1 1
      tailwind.config.js

+ 1 - 1
src/app/nz.config.ts

@@ -2,6 +2,6 @@ import { NzConfig } from 'ng-zorro-antd/core/config';
 
 export const ngZorroConfig: NzConfig = {
   theme: {
-    primaryColor: '#2953E8',
+    primaryColor: '#1E5EFF',
   },
 };

+ 27 - 0
src/app/pages/manager/knowledge/bank/bank.component.html

@@ -0,0 +1,27 @@
+<div class="knowledge-panel">
+  <div class="knowledge-header">
+    <div class="title">集团运营安全风险库</div>
+    <div>
+      <div class="header-button-group">
+        @for (tab of tabs; track tab.value) {
+          <div class="button-item" [class.active]="activeTab === tab.value" (click)="changeTab(tab.value)">
+            {{ tab.label }}
+          </div>
+        }
+      </div>
+    </div>
+  </div>
+  <div class="knowledge-content">
+    @switch (activeTab) {
+      @case ('risk-knowledge') {
+        <risk-item-list />
+      }
+      @case ('enterprise-input') {
+        <risk-enterprise-input />
+      }
+      @case ('update-record') {
+        <risk-update-record />
+      }
+    }
+  </div>
+</div>

+ 0 - 0
src/app/pages/manager/knowledge/bank/bank.component.less


+ 23 - 0
src/app/pages/manager/knowledge/bank/bank.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { BankComponent } from './bank.component';
+
+describe('BankComponent', () => {
+  let component: BankComponent;
+  let fixture: ComponentFixture<BankComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [BankComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(BankComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 34 - 0
src/app/pages/manager/knowledge/bank/bank.component.ts

@@ -0,0 +1,34 @@
+import { Component } from '@angular/core';
+import { CommonNzModule } from '../../../../common.nz.module';
+import { EnterpriseInputComponent } from './enterprise-input/enterprise-input.component';
+import { RiskItemListComponent } from './risk-item-list/risk-item-list.component';
+import { UpdateRecordComponent } from './update-record/update-record.component';
+
+@Component({
+  selector: 'knowledge-bank',
+  standalone: true,
+  imports: [CommonNzModule, RiskItemListComponent, UpdateRecordComponent, EnterpriseInputComponent],
+  templateUrl: './bank.component.html',
+  styleUrl: './bank.component.less',
+})
+export class BankComponent {
+  tabs = [
+    {
+      label: '风险知识',
+      value: 'risk-knowledge',
+    },
+    {
+      label: '企业录入情况',
+      value: 'enterprise-input',
+    },
+    {
+      label: '更新纪录',
+      value: 'update-record',
+    },
+  ];
+  activeTab = this.tabs[2].value;
+
+  changeTab(tab: string) {
+    this.activeTab = tab;
+  }
+}

+ 1 - 0
src/app/pages/manager/knowledge/bank/enterprise-input/enterprise-input.component.html

@@ -0,0 +1 @@
+<p>enterprise-input works!</p>

+ 0 - 0
src/app/pages/manager/knowledge/bank/enterprise-input/enterprise-input.component.less


+ 23 - 0
src/app/pages/manager/knowledge/bank/enterprise-input/enterprise-input.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EnterpriseInputComponent } from './enterprise-input.component';
+
+describe('EnterpriseInputComponent', () => {
+  let component: EnterpriseInputComponent;
+  let fixture: ComponentFixture<EnterpriseInputComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [EnterpriseInputComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(EnterpriseInputComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 10 - 0
src/app/pages/manager/knowledge/bank/enterprise-input/enterprise-input.component.ts

@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'risk-enterprise-input',
+  standalone: true,
+  imports: [],
+  templateUrl: './enterprise-input.component.html',
+  styleUrl: './enterprise-input.component.less',
+})
+export class EnterpriseInputComponent {}

+ 84 - 0
src/app/pages/manager/knowledge/bank/risk-item-form/risk-item-form.component.html

@@ -0,0 +1,84 @@
+<form
+  class="w-full"
+  nz-form
+  nzNoColon
+  nzLayout="horizontal"
+  nzLabelAlign="right"
+  nzLabelWrap="false"
+  [formGroup]="validateForm"
+>
+  <div nz-row>
+    <div nz-col nzSpan="10">
+      <nz-form-item>
+        <nz-form-label nzSpan="8">风险项名称:</nz-form-label>
+        <nz-form-control nzSpan="16" nzErrorTip="请输入 2 - 18 字符风险项名称">
+          <input class="precaution-input" nz-input placeholder="请输入风险项名称:" formControlName="title" />
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+
+    <div nz-col nzSpan="14">
+      <nz-form-item>
+        <nz-form-label nzSpan="10">可能导致的后果:</nz-form-label>
+        <nz-form-control nzSpan="14" nzErrorTip="请输入 2 - 18 字符">
+          <input class="precaution-input" nz-input placeholder="请输入" formControlName="title" />
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+  <div nz-row>
+    <div nz-col nzSpan="10">
+      <nz-form-item>
+        <nz-form-label nzSpan="8">风险等级:</nz-form-label>
+        <nz-form-control nzSpan="16" nzErrorTip="请输入 2 - 18 字符风险项名称">
+          <input class="precaution-input" nz-input placeholder="请输入风险项名称:" formControlName="title" />
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+
+    <div nz-col nzSpan="14">
+      <nz-form-item>
+        <nz-form-label nzSpan="10">涉及场所/设备:</nz-form-label>
+        <nz-form-control nzSpan="7" nzErrorTip="请输入 2 - 18 字符">
+          <input class="precaution-input" nz-input placeholder="请输入" formControlName="title" />
+        </nz-form-control>
+        <nz-form-control nzSpan="7" nzErrorTip="请输入 2 - 18 字符">
+          <input class="precaution-input" nz-input placeholder="请输入" formControlName="title" />
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+  <div nz-row>
+    <div nz-col nzSpan="8">
+      <nz-form-item>
+        <nz-form-label nzSpan="10">责任岗位:</nz-form-label>
+        <nz-form-control nzSpan="14" nzErrorTip="请输入 2 - 18 字符">
+          <input class="precaution-input" nz-input placeholder="请输入" formControlName="title" />
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col nzSpan="8">
+      <nz-form-item>
+        <nz-form-label nzSpan="10">责任人:</nz-form-label>
+        <nz-form-control nzSpan="14" nzErrorTip="请输入 2 - 18 字符">
+          <input class="precaution-input" nz-input placeholder="请输入" formControlName="title" />
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col nzSpan="8">
+      <nz-form-item>
+        <nz-form-label nzSpan="10">具体单位:</nz-form-label>
+        <nz-form-control nzSpan="14" nzErrorTip="请输入 2 - 18 字符">
+          <input class="precaution-input" nz-input placeholder="请输入" formControlName="title" />
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+  <nz-form-item>
+    <nz-form-label style="width: 100px">风险描述:</nz-form-label>
+    <nz-form-control nzSpan="21" nzErrorTip="请输入 2 - 18 字符">
+      <textarea nz-input rows="3" class="precaution-input" placeholder="请输入" formControlName="title"></textarea>
+    </nz-form-control>
+  </nz-form-item>
+  <div class="px-2 font-bold text-sm pb-4">请输入判定风险等级的主要事项或近期事故关联:</div>
+</form>

+ 0 - 0
src/app/pages/manager/knowledge/bank/risk-item-form/risk-item-form.component.less


+ 23 - 0
src/app/pages/manager/knowledge/bank/risk-item-form/risk-item-form.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RiskItemFormComponent } from './risk-item-form.component';
+
+describe('RiskItemFormComponent', () => {
+  let component: RiskItemFormComponent;
+  let fixture: ComponentFixture<RiskItemFormComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [RiskItemFormComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(RiskItemFormComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 17 - 0
src/app/pages/manager/knowledge/bank/risk-item-form/risk-item-form.component.ts

@@ -0,0 +1,17 @@
+import { Component } from '@angular/core';
+import { NonNullableFormBuilder, Validators } from '@angular/forms';
+import { CommonNzModule } from '../../../../../common.nz.module';
+
+@Component({
+  selector: 'risk-item-form',
+  standalone: true,
+  imports: [CommonNzModule],
+  templateUrl: './risk-item-form.component.html',
+  styleUrl: './risk-item-form.component.less',
+})
+export class RiskItemFormComponent {
+  constructor(private fb: NonNullableFormBuilder) {}
+  validateForm = this.fb.group({
+    title: [null, [Validators.required, Validators.minLength(2), Validators.maxLength(18)]],
+  });
+}

+ 49 - 0
src/app/pages/manager/knowledge/bank/risk-item-list/risk-item-list.component.html

@@ -0,0 +1,49 @@
+<div class="risk-item-list">
+  <div class="risk-item-header">
+    <div class="title">XXXXX公司风险项列表</div>
+    <div>
+      <button nz-button nzType="primary" class="precaution-secondary" style="border-radius: 12px">创建风险项</button>
+      <button
+        nz-button
+        nzType="primary"
+        class="precaution-secondary ml-4"
+        style="border-radius: 12px"
+        (click)="createRiskItem()"
+      >
+        创建风险条目
+      </button>
+    </div>
+  </div>
+  <div class="risk-item-filter">
+    <div class="filter-item">
+      <label class="label">风险类别: </label>
+      <div class="flex-1">
+        @for (category of categories; track category.value) {
+          <div
+            class="button-item"
+            [class.active]="activeCategory === category.value"
+            (click)="changeCategory(category.value)"
+          >
+            {{ category.label }}
+          </div>
+        }
+      </div>
+    </div>
+
+    <div class="filter-item">
+      <label class="label">风险等级: </label>
+      <div class="flex-1">
+        @for (level of levels; track level.value) {
+          <div class="button-item" [class.active]="activeLevel === level.value" (click)="changeLevel(level.value)">
+            {{ level.label }}
+          </div>
+        }
+      </div>
+    </div>
+  </div>
+  <app-risk-item-table></app-risk-item-table>
+</div>
+
+<custom-drawer [width]="738" [title]="drawerConfig.title" [visible]="drawerConfig.visible" (onClose)="closeDrawer()">
+  <risk-item-form></risk-item-form>
+</custom-drawer>

+ 47 - 0
src/app/pages/manager/knowledge/bank/risk-item-list/risk-item-list.component.less

@@ -0,0 +1,47 @@
+.risk-item-list {
+  .title {
+    font-size: 20px;
+    color: #333333;
+    line-height: 28px;
+  }
+  .risk-item-header {
+    display: flex;
+    justify-content: space-between;
+    padding-bottom: 16px;
+  }
+}
+
+.risk-item-filter {
+  .filter-item {
+    display: flex;
+    gap: 10px;
+    align-items: flex-start;
+    justify-content: flex-start;
+    margin-bottom: 16px;
+  }
+  .label {
+    line-height: 32px;
+  }
+  .button-item {
+    display: inline-block;
+    border-radius: 10px;
+    padding: 0 18px;
+    height: 32px;
+    line-height: 32px;
+    color: rgba(102, 102, 102, 0.667);
+    margin-right: 8px;
+    cursor: pointer;
+    transition: all 0.3s;
+    &:hover {
+      background-color: var(--ant-primary-1);
+    }
+
+    &:last-child {
+      margin-right: 0;
+    }
+    &.active {
+      background-color: var(--deep-blue);
+      color: #ffffff;
+    }
+  }
+}

+ 23 - 0
src/app/pages/manager/knowledge/bank/risk-item-list/risk-item-list.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RiskItemListComponent } from './risk-item-list.component';
+
+describe('RiskItemListComponent', () => {
+  let component: RiskItemListComponent;
+  let fixture: ComponentFixture<RiskItemListComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [RiskItemListComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(RiskItemListComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 67 - 0
src/app/pages/manager/knowledge/bank/risk-item-list/risk-item-list.component.ts

@@ -0,0 +1,67 @@
+import { Component } from '@angular/core';
+import { CommonNzModule } from '../../../../../common.nz.module';
+import { CustomDrawerComponent } from '../../../../../shared/custom-drawer/custom-drawer.component';
+import { RiskItemFormComponent } from '../risk-item-form/risk-item-form.component';
+import { RiskItemTableComponent } from '../risk-item-table/risk-item-table.component';
+
+const categories = [
+  '客运组织',
+  '行车组织',
+  '检修施工',
+  '车辆运维',
+  '通号运维',
+  '公务运维',
+  '供电运维',
+  '物资后勤',
+  '机电运维',
+  '八防措施',
+  '保护区',
+  '恶劣气象',
+  '消防',
+  '综治',
+];
+
+const levels = ['R1', 'R2', 'R2*', 'R3', 'R4'];
+
+@Component({
+  selector: 'risk-item-list',
+  standalone: true,
+  imports: [CommonNzModule, RiskItemTableComponent, CustomDrawerComponent, RiskItemFormComponent],
+  templateUrl: './risk-item-list.component.html',
+  styleUrl: './risk-item-list.component.less',
+})
+export class RiskItemListComponent {
+  drawerConfig = {
+    title: '创建风险条目',
+    visible: false,
+  };
+
+  categories: Option<string>[] = categories.map(item => ({
+    label: item,
+    value: item,
+  }));
+
+  levels: Option<string>[] = levels.map(item => ({
+    label: item,
+    value: item,
+  }));
+
+  activeCategory: string | null = '客运组织';
+  activeLevel: string | null = 'R1';
+
+  changeCategory(value: string) {
+    this.activeCategory = value;
+  }
+
+  changeLevel(value: string) {
+    this.activeLevel = value;
+  }
+
+  createRiskItem() {
+    this.drawerConfig.visible = true;
+  }
+
+  closeDrawer() {
+    this.drawerConfig.visible = false;
+  }
+}

+ 90 - 0
src/app/pages/manager/knowledge/bank/risk-item-table/risk-item-table.component.html

@@ -0,0 +1,90 @@
+<nz-table
+  class="precaution-table"
+  #table
+  [nzData]="list"
+  nzShowPagination
+  nzPaginationType="small"
+  [nzFrontPagination]="false"
+  [nzTotal]="pageConfig.total"
+  [nzPageIndex]="pageConfig.page + 1"
+  (nzPageIndexChange)="onCurrentPageChange($event - 1)"
+>
+  <thead>
+    <tr>
+      <th>序号</th>
+      <th>风险项</th>
+      <th nzWidth="200px">风险描述</th>
+      <th>导致后果</th>
+      <th>风险等级</th>
+      <th>涉及场所/作业/设备</th>
+      <th>责任岗位</th>
+      <th [nzRight]="'0px'">操作</th>
+    </tr>
+  </thead>
+  <tbody>
+    @for (data of table.data; track $index) {
+      <tr>
+        <td>{{ data.id }}</td>
+        <td>
+          @for (title of data.titles; track title) {
+            <div class="title-item font-medium">{{ title }}</div>
+          }
+        </td>
+        <td>
+          <span
+            class="line-clamp-1"
+            nz-tooltip
+            nzTooltipColor="var(--manager-gray)"
+            nzTooltipOverlayClassName="customTooltip"
+            [nzTooltipTitle]="data.description"
+          >
+            {{ data.description }}
+          </span>
+        </td>
+        <td>
+          @for (consequence of data.consequences; track consequence) {
+            <div class="consequence-item">{{ consequence }}</div>
+          }
+        </td>
+        <td>
+          {{ data.level }}
+        </td>
+        <td>
+          @for (related of data.related; track related) {
+            <div class="related-item">{{ related }}</div>
+          }
+        </td>
+        <td>
+          @for (job of data.job; track job) {
+            <div class="job-item">{{ job }}</div>
+          }
+        </td>
+
+        <td [nzRight]="'0px'">
+          <button class="precaution-secondary px-2" nz-button nzSize="small" nzType="primary" (click)="onEdit(data)">
+            编辑
+          </button>
+          <button
+            class="precaution-secondary px-2 ml-4"
+            nz-button
+            nzSize="small"
+            nzType="primary"
+            nzDanger
+            (click)="onRemove(data)"
+          >
+            删除
+          </button>
+          <button
+            class="precaution-button px-2 ml-4"
+            nz-button
+            nzSize="small"
+            nzType="primary"
+            (click)="onUpdate(data)"
+          >
+            更新记录
+          </button>
+        </td>
+      </tr>
+    }
+  </tbody>
+</nz-table>

+ 0 - 0
src/app/pages/manager/knowledge/bank/risk-item-table/risk-item-table.component.less


+ 23 - 0
src/app/pages/manager/knowledge/bank/risk-item-table/risk-item-table.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RiskItemTableComponent } from './risk-item-table.component';
+
+describe('RiskItemTableComponent', () => {
+  let component: RiskItemTableComponent;
+  let fixture: ComponentFixture<RiskItemTableComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [RiskItemTableComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(RiskItemTableComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 59 - 0
src/app/pages/manager/knowledge/bank/risk-item-table/risk-item-table.component.ts

@@ -0,0 +1,59 @@
+import { Component } from '@angular/core';
+import { CommonNzModule } from '../../../../../common.nz.module';
+
+interface RiskItem {
+  // 序号
+  id: number;
+  // 风险项
+  titles: string[];
+  // 风险描述
+  description: string;
+  // 导致后果
+  consequences: string[];
+  // 风险等级
+  level: string;
+  // 涉及场所/作业/设备
+  related: string[];
+  // 责任岗位
+  job: string[];
+}
+
+const getMockItem = (id: number): RiskItem => ({
+  id,
+  titles: ['车站环境', '客运组织'],
+  description: `风险描述描述文本描述文本描述文本描述文本描述文本描述文本${id}`,
+  consequences: ['行车事故', '人身伤亡'],
+  level: `R3-一般风险`,
+  related: ['5号线- XX站点', '中心- XX作业', '站点/中心- XX设备'],
+  job: ['车站值班员', '车站值班站长', '车站站长'],
+});
+
+@Component({
+  selector: 'app-risk-item-table',
+  standalone: true,
+  imports: [CommonNzModule],
+  templateUrl: './risk-item-table.component.html',
+  styleUrl: './risk-item-table.component.less',
+})
+export class RiskItemTableComponent {
+  pageConfig: IPageConfig = {
+    page: 0,
+    total: 0,
+    size: 10,
+  };
+  onCurrentPageChange(page: number) {
+    this.pageConfig.page = page;
+  }
+
+  list: RiskItem[] = Array.from({ length: 10 }, (_, index) => getMockItem(index + 1));
+
+  onRemove(data: RiskItem) {
+    console.log(data);
+  }
+  onUpdate(data: RiskItem) {
+    console.log(data);
+  }
+  onEdit(data: RiskItem) {
+    console.log(data);
+  }
+}

+ 72 - 0
src/app/pages/manager/knowledge/bank/update-record/detail/detail.component.html

@@ -0,0 +1,72 @@
+<div class="px-6 overflow-y-auto custom-scroll-bar" style="max-height: calc(100vh - 200px)">
+  <table class="update-record-detail-table">
+    <!-- <thead>
+      <tr>
+      </tr>
+    </thead> -->
+    <tbody>
+      @for (item of tableData; track item.name) {
+        <tr>
+          <td style="width: 200px">
+            <span
+              class="line-clamp-1"
+              nz-tooltip
+              nzTooltipColor="var(--manager-gray)"
+              nzTooltipOverlayClassName="customTooltip"
+              [nzTooltipTitle]="item.description"
+            >
+              {{ item.description }}
+            </span>
+          </td>
+          <td>
+            @for (title of item.titles; track $index) {
+              <div class="title-item font-medium">{{ $index + 1 }}. {{ title }}</div>
+            }
+          </td>
+          <td>
+            @if (item.level === 'R1') {
+              <span nz-icon nzType="icons:danger"></span>
+            }
+            <span class="mx-[5px]">{{ item.level }}</span>
+            <span
+              class="inline-block px-2 py-[2px] text-white rounded-lg text-xs"
+              [ngStyle]="{ background: getLevelColor(item.level) }"
+              >{{ getLevelText(item.level) }}</span
+            >
+          </td>
+          <td>{{ item.spot }}</td>
+          <td>{{ item.work }}</td>
+          <td>{{ item.equipment }}</td>
+          <td>
+            @for (job of item.jobs; track $index) {
+              <div class="job-item">{{ $index + 1 }}. {{ job }}</div>
+            }
+          </td>
+          <td>
+            @for (reason of item.reasons; track $index) {
+              <div class="reason-item">{{ $index + 1 }}. {{ reason }}</div>
+            }
+          </td>
+          <td>
+            <div>
+              <span>集团级:</span>
+              {{ item.groupLevel }}
+            </div>
+            <div>
+              <span>公司级:</span>
+              {{ item.enterpriseLevel }}
+            </div>
+          </td>
+          <td>
+            <span>班组级:</span>
+            <span>
+              {{ item.groupLevel }}
+            </span>
+          </td>
+          <td>{{ item.empty }}</td>
+          <td>{{ item.enterprise }}</td>
+        </tr>
+      }
+    </tbody>
+  </table>
+</div>

+ 19 - 0
src/app/pages/manager/knowledge/bank/update-record/detail/detail.component.less

@@ -0,0 +1,19 @@
+.update-record-detail-table {
+  width: 100%;
+  tbody {
+    tr {
+      border-bottom: 1px solid rgba(151, 151, 151, 0.27);
+      td {
+        padding-left: 12px;
+        padding-right: 12px;
+        color: rgba(22, 23, 54, 0.8);
+        font-size: 14px;
+        line-height: 19px;
+        min-height: 46px;
+        padding-right: 32px;
+        padding-top: 32px;
+        padding-bottom: 32px;
+      }
+    }
+  }
+}

+ 23 - 0
src/app/pages/manager/knowledge/bank/update-record/detail/detail.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DetailComponent } from './detail.component';
+
+describe('DetailComponent', () => {
+  let component: DetailComponent;
+  let fixture: ComponentFixture<DetailComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [DetailComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(DetailComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 86 - 0
src/app/pages/manager/knowledge/bank/update-record/detail/detail.component.ts

@@ -0,0 +1,86 @@
+import { Component } from '@angular/core';
+import { CommonNzModule } from '../../../../../../common.nz.module';
+
+interface RowData {
+  name: string;
+  description: string;
+  titles: string[];
+  level: string;
+  spot: string;
+  work: string;
+  equipment: string;
+  jobs: string[];
+  reasons: string[];
+  groupLevel: string;
+  ltdLevel: string;
+  enterpriseLevel: string;
+  empty: string;
+  enterprise: string;
+}
+
+const levelMap: Record<string, { color: string; text: string }> = {
+  R1: {
+    color: '#FE0707',
+    text: '重大风险',
+  },
+  R2: {
+    color: '#FF914D',
+    text: '较大风险',
+  },
+  'R2*': {
+    color: '#FF914D',
+    text: '较大风险',
+  },
+  R3: {
+    color: '#FFD666',
+    text: '一般风险',
+  },
+  R4: {
+    color: '#0177FB',
+    text: '低风险',
+  },
+};
+
+const getRandomLevel = () => {
+  return Object.keys(levelMap)[Math.floor(Math.random() * Object.keys(levelMap).length)];
+};
+
+const getRowData = (): RowData => ({
+  name: '',
+  description: `车站轨行区封闭设施不完备
+或施工人员在轨行区施工、
+行走、坐卧等可能导致列车
+撞击伤亡或中断行车`,
+  titles: ['行车事故', '人身伤亡'],
+  level: getRandomLevel(),
+  spot: '上课官站',
+  work: 'XX作业',
+  equipment: '轨道设备',
+  jobs: ['施工人员', '轨道车司机'],
+  reasons: ['车站设施设备因素', '乘客自身原因'],
+  groupLevel: 'Ⅱ',
+  ltdLevel: 'Ⅱ',
+  enterpriseLevel: 'Ⅱ',
+  empty: '无',
+  enterprise: '加共开单位',
+});
+
+@Component({
+  selector: 'update-record-detail',
+  standalone: true,
+  imports: [CommonNzModule],
+  templateUrl: './detail.component.html',
+  styleUrl: './detail.component.less',
+})
+export class DetailComponent {
+  tableData: RowData[] = Array.from({ length: 10 }).map(() => getRowData());
+  levelMap = levelMap;
+
+  getLevelText(level: string) {
+    return this.levelMap[level]?.text;
+  }
+
+  getLevelColor(level: string) {
+    return this.levelMap[level]?.color;
+  }
+}

+ 40 - 0
src/app/pages/manager/knowledge/bank/update-record/update-record.component.html

@@ -0,0 +1,40 @@
+<nz-table
+  class="precaution-table"
+  #table
+  [nzData]="list"
+  nzShowPagination
+  nzPaginationType="small"
+  [nzFrontPagination]="false"
+  [nzTotal]="pageConfig.total"
+  [nzPageIndex]="pageConfig.page + 1"
+  (nzPageIndexChange)="onCurrentPageChange($event - 1)"
+>
+  <thead>
+    <tr>
+      <th>企业名称</th>
+      <th>更新风险类别</th>
+      <th>更新原因</th>
+      <th>查看变更内容</th>
+      <th>上传人</th>
+      <th>更新日期</th>
+    </tr>
+  </thead>
+  <tbody>
+    @for (data of table.data; track $index) {
+      <tr>
+        <td>{{ data.enterpriseName }}</td>
+        <td>{{ data.updateRiskCategory }}</td>
+        <td>{{ data.updateReason }}</td>
+        <td>
+          <button nz-button nzType="link" (click)="showDetail(data)">查看详情</button>
+        </td>
+        <td>{{ data.uploader }}</td>
+        <td>{{ data.updateDate }}</td>
+      </tr>
+    }
+  </tbody>
+</nz-table>
+
+<ng-template #detailTpl let-params>
+  <update-record-detail></update-record-detail>
+</ng-template>

+ 19 - 0
src/app/pages/manager/knowledge/bank/update-record/update-record.component.less

@@ -0,0 +1,19 @@
+.noop-modal {
+  ::ng-deep &.ant-modal {
+    padding-bottom: 0;
+    .ant-modal-body {
+      padding: 0;
+    }
+    .ant-modal-content {
+      border-radius: 19px;
+    }
+    &.ant-modal .ant-modal-close {
+      // color: var(--ant-primary-color);
+      // top: 8px;
+      // right: 8px;
+      &:hover {
+        color: var(--ant-primary-color);
+      }
+    }
+  }
+}

+ 23 - 0
src/app/pages/manager/knowledge/bank/update-record/update-record.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { UpdateRecordComponent } from './update-record.component';
+
+describe('UpdateRecordComponent', () => {
+  let component: UpdateRecordComponent;
+  let fixture: ComponentFixture<UpdateRecordComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [UpdateRecordComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(UpdateRecordComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 70 - 0
src/app/pages/manager/knowledge/bank/update-record/update-record.component.ts

@@ -0,0 +1,70 @@
+import { Component, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core';
+import { NzModalService } from 'ng-zorro-antd/modal';
+import { CommonNzModule } from '../../../../../common.nz.module';
+import { DetailComponent } from './detail/detail.component';
+
+interface RecordItem {
+  // 序号
+  id: number;
+  // 企业名称
+  enterpriseName: string;
+  // 更新风险类别
+  updateRiskCategory: string;
+  // 更新原因
+  updateReason: string;
+  // 上传人
+  uploader: string;
+  // 更新日期
+  updateDate: string;
+}
+
+const getMockItem = (id: number): RecordItem => ({
+  id,
+  enterpriseName: `企业名称${id}`,
+  updateRiskCategory: `XXXXX风险项`,
+  updateReason: `XXXXX更新原因`,
+  uploader: `阿松大`,
+  updateDate: `2024/01/01 12:00`,
+});
+
+@Component({
+  selector: 'risk-update-record',
+  standalone: true,
+  imports: [CommonNzModule, DetailComponent],
+  templateUrl: './update-record.component.html',
+  styleUrl: './update-record.component.less',
+})
+export class UpdateRecordComponent {
+  @ViewChild('detailTpl') detailTpl!: TemplateRef<void>;
+  pageConfig: IPageConfig = {
+    page: 0,
+    total: 0,
+    size: 10,
+  };
+  constructor(
+    private viewContainerRef: ViewContainerRef,
+    private modal: NzModalService
+  ) {}
+  onCurrentPageChange(page: number) {
+    this.pageConfig.page = page;
+  }
+
+  list: RecordItem[] = Array.from({ length: 10 }, (_, index) => getMockItem(index + 1));
+
+  showDetail(data: RecordItem) {
+    console.log(data);
+    this.modal.create<TemplateRef<void>, {}>({
+      nzContent: this.detailTpl,
+      nzViewContainerRef: this.viewContainerRef,
+      nzClassName: 'noop-modal',
+      nzClosable: true,
+      // nzCloseIcon: this.closeIcon,
+      nzData: {
+        id: null,
+        data,
+      },
+      nzWidth: 'calc(100vw - 344px)',
+      nzFooter: null,
+    });
+  }
+}

+ 1 - 0
src/app/pages/manager/knowledge/doc/doc.component.html

@@ -0,0 +1 @@
+<p>doc works!</p>

+ 0 - 0
src/app/pages/manager/knowledge/doc/doc.component.less


+ 23 - 0
src/app/pages/manager/knowledge/doc/doc.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DocComponent } from './doc.component';
+
+describe('DocComponent', () => {
+  let component: DocComponent;
+  let fixture: ComponentFixture<DocComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [DocComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(DocComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 12 - 0
src/app/pages/manager/knowledge/doc/doc.component.ts

@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-doc',
+  standalone: true,
+  imports: [],
+  templateUrl: './doc.component.html',
+  styleUrl: './doc.component.less'
+})
+export class DocComponent {
+
+}

+ 1 - 0
src/app/pages/manager/knowledge/knowledge.component.html

@@ -0,0 +1 @@
+<router-outlet></router-outlet>

+ 0 - 0
src/app/pages/manager/knowledge/knowledge.component.less


+ 23 - 0
src/app/pages/manager/knowledge/knowledge.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { KnowledgeComponent } from './knowledge.component';
+
+describe('KnowledgeComponent', () => {
+  let component: KnowledgeComponent;
+  let fixture: ComponentFixture<KnowledgeComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [KnowledgeComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(KnowledgeComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 11 - 0
src/app/pages/manager/knowledge/knowledge.component.ts

@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+import { RouterOutlet } from '@angular/router';
+
+@Component({
+  selector: 'app-knowledge',
+  standalone: true,
+  imports: [RouterOutlet],
+  templateUrl: './knowledge.component.html',
+  styleUrl: './knowledge.component.less',
+})
+export class KnowledgeComponent {}

+ 31 - 0
src/app/pages/manager/knowledge/knowledge.route.ts

@@ -0,0 +1,31 @@
+import { Routes } from '@angular/router';
+
+export const knowledgeRoutes: Routes = [
+  {
+    path: 'list',
+    loadComponent: () => import('./list/list.component').then(m => m.ListComponent),
+    data: {
+      title: '风险知识',
+      icon: 'icons:knowledge-list',
+      weight: 1,
+    },
+  },
+  {
+    path: 'bank',
+    loadComponent: () => import('./bank/bank.component').then(m => m.BankComponent),
+    data: {
+      title: '风险库',
+      icon: 'icons:knowledge-bank',
+      weight: 2,
+    },
+  },
+  {
+    path: 'document',
+    loadComponent: () => import('./doc/doc.component').then(m => m.DocComponent),
+    data: {
+      title: '风险文档',
+      icon: 'icons:knowledge-doc',
+      weight: 3,
+    },
+  },
+];

+ 18 - 0
src/app/pages/manager/knowledge/list/list.component.html

@@ -0,0 +1,18 @@
+<div class="knowledge-panel">
+  <div class="knowledge-header">
+    <div class="title">集团运营安全风险库</div>
+    <div>
+      <div class="header-button-group">
+        @for (tab of tabs; track tab.value) {
+          <div class="button-item" [class.active]="activeTab === tab.value" (click)="changeTab(tab.value)">
+            {{ tab.label }}
+          </div>
+        }
+      </div>
+    </div>
+  </div>
+  <div class="knowledge-content">
+    <knowledge-risk-level />
+    <knowledge-risk-category />
+  </div>
+</div>

+ 1 - 0
src/app/pages/manager/knowledge/list/list.component.less

@@ -0,0 +1 @@
+

+ 23 - 0
src/app/pages/manager/knowledge/list/list.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ListComponent } from './list.component';
+
+describe('ListComponent', () => {
+  let component: ListComponent;
+  let fixture: ComponentFixture<ListComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ListComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(ListComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 32 - 0
src/app/pages/manager/knowledge/list/list.component.ts

@@ -0,0 +1,32 @@
+import { Component } from '@angular/core';
+import { RiskCategoryComponent } from './risk-category/risk-category.component';
+import { RiskLevelComponent } from './risk-level/risk-level.component';
+
+@Component({
+  selector: 'knowledge-list',
+  standalone: true,
+  imports: [RiskLevelComponent, RiskCategoryComponent],
+  templateUrl: './list.component.html',
+  styleUrl: './list.component.less',
+})
+export class ListComponent {
+  tabs = [
+    {
+      label: '风险知识',
+      value: 'risk-knowledge',
+    },
+    {
+      label: '企业录入情况',
+      value: 'enterprise-input',
+    },
+    {
+      label: '更新纪录',
+      value: 'update-record',
+    },
+  ];
+  activeTab = this.tabs[0].value;
+
+  changeTab(tab: string) {
+    this.activeTab = tab;
+  }
+}

+ 28 - 0
src/app/pages/manager/knowledge/list/risk-category/risk-category.component.html

@@ -0,0 +1,28 @@
+<div class="flex justify-between py-4">
+  <div>
+    <span class="title-text">风险项分类</span>
+    <span class="update-time">(更新日期:2024/9/9)</span>
+  </div>
+  <div>
+    <!-- <button nz-button nzType="primary" class="precaution-secondary" style="border-radius: 12px">风险知识更新</button> -->
+  </div>
+</div>
+<div>
+  <table class="category-table">
+    <thead>
+      <tr>
+        <th style="min-width: 200px">风险类别</th>
+        <th>风险项</th>
+      </tr>
+    </thead>
+    <tbody>
+      @for (item of tableData; track item.category) {
+        <tr>
+          <td class="text-sm">{{ item.category }}</td>
+          <td>{{ item.detail }}</td>
+        </tr>
+      }
+    </tbody>
+  </table>
+</div>
+<div class="gap-line"></div>

+ 45 - 0
src/app/pages/manager/knowledge/list/risk-category/risk-category.component.less

@@ -0,0 +1,45 @@
+.title-text {
+  font-weight: 500;
+  font-size: 20px;
+  color: #333333;
+  line-height: 28px;
+  text-shadow: 0px 0px 8px rgba(223, 223, 223, 0.5);
+}
+
+.update-time {
+  .title-text();
+  color: #666666bb;
+}
+.category-table {
+  width: 100%;
+  thead {
+    border-radius: 10px;
+    tr {
+      background-color: rgba(165, 180, 203, 0.1);
+      th {
+        text-align: left;
+        font-weight: 500;
+        font-size: 16px;
+        color: #7d8da6;
+        line-height: 64px;
+        padding-left: 18px;
+        padding-right: 18px;
+      }
+    }
+  }
+  tbody {
+    tr {
+      td {
+        padding-left: 18px;
+        padding-right: 18px;
+        color: rgba(22, 23, 54, 0.8);
+        font-size: 16px;
+        line-height: 19px;
+        min-height: 46px;
+        padding-right: 32px;
+        padding-top: 16px;
+        padding-bottom: 16px;
+      }
+    }
+  }
+}

+ 23 - 0
src/app/pages/manager/knowledge/list/risk-category/risk-category.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RiskCategoryComponent } from './risk-category.component';
+
+describe('RiskCategoryComponent', () => {
+  let component: RiskCategoryComponent;
+  let fixture: ComponentFixture<RiskCategoryComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [RiskCategoryComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(RiskCategoryComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 54 - 0
src/app/pages/manager/knowledge/list/risk-category/risk-category.component.ts

@@ -0,0 +1,54 @@
+import { Component } from '@angular/core';
+
+interface TableRowData {
+  category: string;
+  detail: string;
+}
+
+@Component({
+  selector: 'knowledge-risk-category',
+  standalone: true,
+  imports: [],
+  templateUrl: './risk-category.component.html',
+  styleUrl: './risk-category.component.less',
+})
+export class RiskCategoryComponent {
+  tableData: TableRowData[] = [
+    {
+      category: '客运组织1',
+      detail: '1.客流疏导、2.车站环境、3.乘客行为',
+    },
+    {
+      category: '行车组织2',
+      detail: '1.调度指挥、2.正常行车作业、3.非正常行车作业、4.车场调车作业、5.应急行车处置',
+    },
+    {
+      category: '施工检修3',
+      detail: '1.轨行区施工、2.车场施工、3.车站施工、4.工程车开行',
+    },
+    {
+      category: '车辆运维4 ',
+      detail:
+        '1.车钩/车体/转向架/胶轮、2.受电弓/集电靴/接地靴、3.车门、4.牵引/制动/控制、5.蓄电池/辅助电源、6.空调/广播/视频/照明等、7.特种设备、8.DCC管理、9.工程车辆',
+    },
+    {
+      category: '通号运维5',
+      detail:
+        '1.列车自动防护系统、2.列车自动运行系统、3.列车自动监控系统、4.联锁设备、5.传输网络系统、6.无线通信/专用电话设备、7.转辙设备、8.轨道占用检查设备、9.电源设备',
+    },
+    {
+      category: '工务运维6',
+      detail: '1.桥梁、2.隧道、3.轨道、4.车站主体结构、5.工程车辆',
+    },
+    {
+      category: '供电运维7',
+      detail:
+        ' 1.中高压设备、2.牵引直流设备、3.低压配电设备、4.电力监控系统、5.直流/应急电源设备、6.电缆、7.杂散电流防护、8.柔性/刚性接触网、9.接触轨/供电轨',
+    },
+    {
+      category: '物资后勤8',
+      detail:
+        '1.易燃品/危废品仓库、2.道口及场内交通、3.特种设备、4.膳食、5.储运 、6.膳食、7.公共环境及卫生、8.房屋及其附属设施',
+    },
+  ];
+}

+ 37 - 0
src/app/pages/manager/knowledge/list/risk-level/risk-level.component.html

@@ -0,0 +1,37 @@
+<div class="flex justify-between pb-4">
+  <div>
+    <span class="title-text">风险等级</span>
+    <span class="update-time">(更新日期:2024/9/9)</span>
+  </div>
+  <div>
+    <button nz-button nzType="primary" class="precaution-secondary" style="border-radius: 12px">风险知识更新</button>
+  </div>
+</div>
+<div>
+  <table class="level-table">
+    <thead>
+      <tr>
+        <th style="width: 200px">风险名称</th>
+        <th style="width: 110px">风险色</th>
+        <th>管控责任</th>
+        <th>定级标准</th>
+      </tr>
+    </thead>
+    <tbody>
+      @for (item of tableData; track item.name) {
+        <tr>
+          <td class="text-sm">{{ item.name }}</td>
+          <td>
+            <span>
+              <star-icon class="align-top" [color]="colorMap[item.color]"></star-icon>
+              <span class="ml-1">{{ item.color }}</span>
+            </span>
+          </td>
+          <td style="padding-right: 6%">{{ item.responsibility }}</td>
+          <td style="padding-right: 6%">{{ item.standard }}</td>
+        </tr>
+      }
+    </tbody>
+  </table>
+</div>
+<div class="gap-line"></div>

+ 52 - 0
src/app/pages/manager/knowledge/list/risk-level/risk-level.component.less

@@ -0,0 +1,52 @@
+.title-text {
+  font-weight: 500;
+  font-size: 20px;
+  color: #333333;
+  line-height: 28px;
+  text-shadow: 0px 0px 8px rgba(223, 223, 223, 0.5);
+}
+
+.update-time {
+  .title-text();
+  color: #666666bb;
+}
+
+.level-table {
+  width: 100%;
+  thead {
+    border-radius: 10px;
+    tr {
+      background-color: rgba(165, 180, 203, 0.1);
+      th {
+        text-align: left;
+        font-weight: 500;
+        font-size: 16px;
+        color: #7d8da6;
+        line-height: 64px;
+        padding-left: 18px;
+        padding-right: 18px;
+      }
+    }
+  }
+  tbody {
+    tr {
+      td {
+        padding-left: 18px;
+        padding-right: 18px;
+        color: rgba(22, 23, 54, 0.8);
+        font-size: 16px;
+        line-height: 19px;
+        min-height: 46px;
+        padding-right: 32px;
+        padding-top: 16px;
+        padding-bottom: 16px;
+      }
+    }
+  }
+}
+
+.gap-line {
+  box-shadow: 0px 0px 8px 0px rgba(223, 223, 223, 0.5);
+  border-bottom: 2px solid rgba(151, 151, 151, 0.44);
+  opacity: 0.44;
+}

+ 23 - 0
src/app/pages/manager/knowledge/list/risk-level/risk-level.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RiskLevelComponent } from './risk-level.component';
+
+describe('RiskLevelComponent', () => {
+  let component: RiskLevelComponent;
+  let fixture: ComponentFixture<RiskLevelComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [RiskLevelComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(RiskLevelComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 61 - 0
src/app/pages/manager/knowledge/list/risk-level/risk-level.component.ts

@@ -0,0 +1,61 @@
+import { Component } from '@angular/core';
+import { CommonNzModule } from '../../../../../common.nz.module';
+import { StarIconComponent } from '../../../../../shared/star/star.icon';
+
+interface TableRowData {
+  name: string;
+  color: string;
+  responsibility: string;
+  standard: string;
+}
+
+const colorMap: Record<string, string> = {
+  '红色': '#FF0000',
+  '橙色': '#EB5D00',
+  '黄色': '#FBE800',
+  '蓝色': '#4677F2',
+};
+
+@Component({
+  selector: 'knowledge-risk-level',
+  standalone: true,
+  imports: [CommonNzModule, StarIconComponent],
+  templateUrl: './risk-level.component.html',
+  styleUrl: './risk-level.component.less',
+})
+export class RiskLevelComponent {
+  colorMap = colorMap;
+
+  tableData: TableRowData[] = [
+    {
+      name: '重大风险:R1',
+      color: '红色',
+      responsibility: '由集团级、公司级、部门/中心级、班组(车站)级4个层级按各自职责要求,落实具体管控措施',
+      standard: '频繁的出现严重后果事件或发现存在隐患或有明显不满足的趋势,可定为红色风险条目',
+    },
+    {
+      name: '较大风险:R2',
+      color: '橙色',
+      responsibility: '由公司级、部门/中心级、班组(车站)级3个层级按各自职责要求,落实具体管控措施',
+      standard: '偶而的出现严重后果事件或发现存在隐患或有明显不满足的趋势,可定为橙色风险条目',
+    },
+    {
+      name: '特殊较大风险:R2*',
+      color: '橙色',
+      responsibility: '由公司级、部门/中心级、班组(车站)级3个层级按各自职责要求,落实具体管控措施',
+      standard: '偶而的出现严重后果事件或发现存在隐患或有明显不满足的趋势,可定为橙色风险条目',
+    },
+    {
+      name: '一般风险:R3',
+      color: '黄色',
+      responsibility: '由部门/中心级、班组(车站)级2个层级按各自职责要求,落实具体管控措施',
+      standard: '极少的出现严重后果事件或发现存在隐患或有明显不满足的趋势,可定为黄色风险条目',
+    },
+    {
+      name: '低风险:R4',
+      color: '蓝色',
+      responsibility: '由班组(车站)级直接负责落实具体管控措施',
+      standard: '基本没出现严重后果事件或发现存在隐患或有明显不满足的趋势,可定为蓝色风险条目',
+    },
+  ];
+}

+ 2 - 2
src/app/pages/manager/layout/header/header.component.ts

@@ -26,7 +26,7 @@ export class HeaderComponent {
       icon: 'assets/images/nav/dashboard.png',
     },
     {
-      path: '/manager/workbench',
+      path: '/manager/workbench/my',
       label: '我的工作台',
       icon: 'assets/images/nav/workbench.png',
     },
@@ -41,7 +41,7 @@ export class HeaderComponent {
       icon: 'assets/images/nav/control.png',
     },
     {
-      path: '/manager/knowledge',
+      path: '/manager/risk-knowledge/list',
       label: '风险知识管理',
       icon: 'assets/images/nav/knowledge.png',
     },

+ 2 - 2
src/app/pages/manager/layout/sidebar/navigation/navigation.component.less

@@ -34,12 +34,12 @@ nav {
     }
     &.active {
       &:before {
-        background-color: var(--ant-primary-color);
+        background-color: var(--deep-blue);
       }
     }
     &.active,
     &:hover {
-      color: var(--ant-primary-color);
+      color: var(--deep-blue);
     }
   }
 }

+ 11 - 1
src/app/pages/manager/manager.routes.ts

@@ -1,4 +1,5 @@
 import { Routes } from '@angular/router';
+import { knowledgeRoutes } from './knowledge/knowledge.route';
 import { workbenchRoutes } from './workbench/workbench.route';
 
 export const managerRoutes: Routes = [
@@ -12,6 +13,15 @@ export const managerRoutes: Routes = [
       weight: 0,
     },
   },
-
+  {
+    path: 'risk-knowledge',
+    loadComponent: () => import('./knowledge/knowledge.component').then(m => m.KnowledgeComponent),
+    children: knowledgeRoutes,
+    data: {
+      title: '风险知识管理',
+      icon: 'user',
+      weight: 0,
+    },
+  },
   { path: '', pathMatch: 'full', redirectTo: 'workbench' },
 ];

+ 27 - 25
src/app/pages/manager/workbench/my/hazard-statistics/hazard-statistics.component.html

@@ -2,32 +2,34 @@
   <div class="workbench-panel-header">
     <div class="text-lg font-bold leading-[52px] pl-2">隐患统计</div>
   </div>
-  <div class="flex justify-between relative" style="height: 208px">
-    <div #chart class="w-1/2"></div>
-    <div #chart2 class="w-1/2"></div>
-    <div class="absolute top-[18px] text-sm" style="left: calc(0% + 106px)">
-      <span>近30天新增</span>
-      <span class="font-bold mx-1">1</span>
-      <span>起</span>
+  <div class="pt-2">
+    <div class="flex justify-between relative" style="height: 238px">
+      <div #chart class="w-1/2"></div>
+      <div #chart2 class="w-1/2"></div>
+      <div class="absolute top-[21px] text-sm" style="left: calc(0% + 106px)">
+        <span>近30天新增</span>
+        <span class="font-bold mx-1">1</span>
+        <span>起</span>
+      </div>
+      <div class="absolute top-[21px] text-sm" style="left: calc(50% + 106px)">
+        <span>近30天新增</span>
+        <span class="font-bold mx-1">4</span>
+        <span>起</span>
+      </div>
     </div>
-    <div class="absolute top-[18px] text-sm" style="left: calc(50% + 106px)">
-      <span>近30天新增</span>
-      <span class="font-bold mx-1">4</span>
-      <span>起</span>
-    </div>
-  </div>
-  <div class="flex justify-between relative" style="height: 208px">
-    <div #chart3 class="w-1/2"></div>
-    <div #chart4 class="w-1/2"></div>
-    <div class="absolute top-[18px] text-sm" style="left: calc(0% + 106px)">
-      <span>近30天新增</span>
-      <span class="font-bold mx-1">2</span>
-      <span>起</span>
-    </div>
-    <div class="absolute top-[18px] text-sm" style="left: calc(50% + 106px)">
-      <span>近30天新增</span>
-      <span class="font-bold mx-1">3</span>
-      <span>起</span>
+    <div class="flex justify-between relative" style="height: 238px">
+      <div #chart3 class="w-1/2"></div>
+      <div #chart4 class="w-1/2"></div>
+      <div class="absolute top-[21px] text-sm" style="left: calc(0% + 106px)">
+        <span>近30天新增</span>
+        <span class="font-bold mx-1">2</span>
+        <span>起</span>
+      </div>
+      <div class="absolute top-[21px] text-sm" style="left: calc(50% + 106px)">
+        <span>近30天新增</span>
+        <span class="font-bold mx-1">3</span>
+        <span>起</span>
+      </div>
     </div>
   </div>
 </div>

+ 1 - 1
src/app/shared/custom-drawer/custom-drawer.component.less

@@ -37,7 +37,7 @@
       transform: translateY(-50%);
       width: 16px;
       height: 16px;
-      background-image: url('/assets/images/task/arrow.png');
+      background-image: url('/assets/images/drawer-arrow.png');
       background-size: cover;
       background-repeat: no-repeat;
       z-index: 999;

+ 0 - 14
src/app/shared/secondary-tabs/secondary-tabs.component.html

@@ -1,14 +0,0 @@
-<nav>
-  <div class="secondary-tabs">
-    @for (item of paths; track $index) {
-      <a class="secondary-tab-item" [routerLink]="item.path" routerLinkActive="active">
-        <span class="ml-2 inline-block" [style.minWidth]="item.minWith ? item.minWith + 'px' : 'auto'">
-          {{ item.label }}
-        </span>
-      </a>
-    }
-  </div>
-</nav>
-<div class="relative" [@routeAnimations]="getRouteAnimationData()">
-  <router-outlet></router-outlet>
-</div>

+ 0 - 46
src/app/shared/secondary-tabs/secondary-tabs.component.less

@@ -1,46 +0,0 @@
-:host {
-  display: block;
-  min-height: calc(100vh - var(--header-height) - 48px);
-  background: #ffffff;
-  box-shadow: 0px 1px 4px 0px rgba(21, 34, 50, 0.08);
-  border-radius: 4px;
-  overflow: hidden;
-}
-
-.secondary-tabs {
-  display: flex;
-  height: 72px;
-  padding: 0 32px;
-  border-bottom: 1px solid rgba(151, 151, 151, 0.32);
-
-  .secondary-tab-item {
-    display: flex;
-    align-items: center;
-    height: 100%;
-    padding-left: 12px;
-    padding-right: 16px;
-    color: var(--manager-gray);
-    font-size: 14px;
-    cursor: pointer;
-    transition: all 0.2s;
-    span {
-      display: inline-flex;
-      align-items: center;
-      justify-content: center;
-      height: 100%;
-      border-bottom: 2px solid transparent;
-    }
-    &:active {
-      opacity: 0.8;
-    }
-    &.active {
-      span {
-        border-bottom-color: var(--ant-primary-color);
-      }
-      color: var(--ant-primary-color);
-    }
-    &:hover {
-      color: var(--ant-primary-color);
-    }
-  }
-}

+ 0 - 22
src/app/shared/secondary-tabs/secondary-tabs.component.spec.ts

@@ -1,22 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { SecondaryTabsComponent } from './secondary-tabs.component';
-
-describe('SecondaryTabsComponent', () => {
-  let component: SecondaryTabsComponent;
-  let fixture: ComponentFixture<SecondaryTabsComponent>;
-
-  beforeEach(async () => {
-    await TestBed.configureTestingModule({
-      imports: [SecondaryTabsComponent],
-    }).compileComponents();
-
-    fixture = TestBed.createComponent(SecondaryTabsComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

+ 0 - 56
src/app/shared/secondary-tabs/secondary-tabs.component.ts

@@ -1,56 +0,0 @@
-import { Component, Input } from '@angular/core';
-import { ActivatedRoute, ChildrenOutletContexts, NavigationStart, Router, RouterModule } from '@angular/router';
-import { slideInAnimation } from '../../animations';
-import { CommonNzModule } from '../../common.nz.module';
-import { IPath } from '../../pages/manager/auth/routes/route.service';
-
-interface IPathEnhance extends IPath {
-  label: string;
-  path: string;
-  minWith?: number;
-}
-
-@Component({
-  selector: 'secondary-tabs',
-  standalone: true,
-  imports: [RouterModule, CommonNzModule],
-  templateUrl: './secondary-tabs.component.html',
-  styleUrl: './secondary-tabs.component.less',
-  animations: [slideInAnimation],
-})
-export class SecondaryTabsComponent {
-  @Input() paths: IPathEnhance[] = [];
-  @Input() parentMatchString: string = '';
-  constructor(
-    private router: Router,
-    private readonly route: ActivatedRoute,
-    private contexts: ChildrenOutletContexts
-  ) {
-    this.router.events.subscribe(event => {
-      if (event instanceof NavigationStart) {
-        if (event.url === this.parentMatchString) {
-          this.resetActiveTab();
-        }
-      }
-    });
-  }
-  getRouteAnimationData() {
-    return this.contexts.getContext('primary')?.route?.snapshot?.data?.['animation'];
-  }
-  ngOnInit() {
-    if (this.isNoTargetPage()) {
-      this.resetActiveTab();
-    }
-  }
-  isNoTargetPage() {
-    return this.router.url === this.parentMatchString;
-  }
-  resetActiveTab() {
-    if (this.paths[0]) {
-      this.navigateTo(this.paths[0]);
-    }
-  }
-  navigateTo(path: IPath) {
-    this.router.navigate([path.path], { relativeTo: this.route });
-  }
-}

+ 1 - 0
src/app/shared/star/star.icon.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 12 12" [style.color]="color" [style.width]="size" [style.height]="size"><g fill="none"><path d="M5.283 1.546a.8.8 0 0 1 1.435 0L7.83 3.798l2.486.361a.8.8 0 0 1 .443 1.365L8.96 7.277l.425 2.476a.8.8 0 0 1-1.16.844L6 9.427l-2.224 1.17a.8.8 0 0 1-1.16-.844l.424-2.476l-1.799-1.753a.8.8 0 0 1 .444-1.365l2.486-.36l1.111-2.253z" fill="currentColor"></path></g></svg>

+ 13 - 0
src/app/shared/star/star.icon.ts

@@ -0,0 +1,13 @@
+import { Component, CUSTOM_ELEMENTS_SCHEMA, Input } from '@angular/core';
+
+@Component({
+  selector: 'star-icon',
+  standalone: true,
+  imports: [],
+  templateUrl: './star.icon.svg',
+  schemas: [CUSTOM_ELEMENTS_SCHEMA],
+})
+export class StarIconComponent {
+  @Input() color = '#333333';
+  @Input() size = 17;
+}

+ 3 - 3
src/app/shared/workbench-tabs/workbench-tabs.component.less

@@ -15,7 +15,7 @@
     bottom: 0;
     height: 4px;
     border-radius: 2px;
-    background: var(--ant-primary-color);
+    background: var(--deep-blue);
     width: var(--active-width);
     transition:
       left 0.2s ease-in-out,
@@ -31,10 +31,10 @@
   color: #72767c;
   transition: color 0.2s ease-in-out;
   &:hover {
-    color: var(--ant-primary-color);
+    color: var(--deep-blue);
   }
   &.active {
     font-weight: 500;
-    color: var(--ant-primary-color);
+    color: var(--deep-blue);
   }
 }

+ 11 - 0
src/assets/icons/danger.svg

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="21px" height="19px" viewBox="0 0 21 19" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组 26</title>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="风险知识-更新记录-查看详情" transform="translate(-523.000000, -501.000000)" fill="#FE0707" fill-rule="nonzero">
+            <g id="编组" transform="translate(523.000000, 501.000000)">
+                <path d="M20.5703385,15.7865342 L12.3313048,1.32597951 C11.3235549,-0.44199317 9.67659784,-0.44199317 8.66911222,1.32597951 L0.430037799,15.7865342 C-0.577447827,17.5563198 0.246782827,19 2.26035146,19 L18.7399436,19 C20.7535935,19 21.5769704,17.5562168 20.5703385,15.7865342 Z M9.36855061,5.42901434 C9.66462478,5.10461889 10.0410344,4.94239027 10.5000967,4.94239027 C10.959403,4.94239027 11.335467,5.10290906 11.6318461,5.42252519 C11.926294,5.74286235 12.0734672,6.14347949 12.0734672,6.62522125 C12.0734672,7.03970251 11.4588566,10.0875406 11.2538509,12.3048505 L9.77348006,12.3048505 C9.59368081,10.08752 8.92678721,7.03970251 8.92678721,6.62522125 C8.92682786,6.15079266 9.07424495,5.75182355 9.36855061,5.42901434 Z M11.6111117,15.9723504 C11.2996901,16.2797093 10.9291146,16.4328737 10.5001983,16.4328737 C10.0713837,16.4328737 9.7007066,16.2797093 9.38934593,15.9723504 C9.07883903,15.6657125 8.9245105,15.2942862 8.9245105,14.8580715 C8.9245105,14.4241228 9.07883903,14.0486794 9.38934593,13.7340074 C9.7007066,13.4192324 10.0713837,13.2618449 10.5001983,13.2618449 C10.9291146,13.2618449 11.2996901,13.4192324 11.6111117,13.7340074 C11.9214153,14.0486794 12.0761098,14.4241228 12.0761098,14.8580715 C12.0761098,15.2942862 11.9214153,15.6657125 11.6111117,15.9723504 Z" id="形状"></path>
+            </g>
+        </g>
+    </g>
+</svg>

+ 11 - 0
src/assets/icons/knowledge-bank.svg

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="23px" height="26px" viewBox="0 0 23 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title></title>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="风险知识-首页" transform="translate(-72.000000, -211.000000)" fill="currentColor" fill-rule="nonzero">
+            <g id="编组" transform="translate(72.000000, 211.000000)">
+                <path d="M0.0103297847,8.99936059 C0.0103297847,7.2707242 0.0318352128,5.54046923 0.000404202527,3.81992571 C-0.0128299071,3.06728908 0.298171668,2.66912002 1.04259033,2.49107695 C4.39082006,1.67693453 7.7291242,0.840132082 11.0806624,0.0373196755 C11.404791,-0.0236290515 11.7389809,-0.00977397284 12.056678,0.0777840105 C15.2824922,0.8471459 18.5061008,1.6299959 21.7275036,2.42633401 C22.8540572,2.70149149 22.9963239,2.88762743 22.9963239,4.03034025 C22.9963239,7.13800118 23.0045952,10.2440435 22.9963239,13.3517045 C22.9863983,16.8267816 21.5753113,19.6285321 18.8325421,21.8411219 C16.7845637,23.4823554 14.6770317,25.0232372 12.1608966,25.8956483 C11.73971,26.0347839 11.2834862,26.0347839 10.8622996,25.8956483 C7.50532186,24.6267191 4.53163438,22.5463349 2.21877182,19.8486581 C0.781216668,18.2009504 0.119511189,16.1842079 0.0351437402,14.0347424 C-0.0326810714,12.359519 0.0219096306,10.6778212 0.0219096306,8.99936059 L0.0103297847,8.99936059 Z M11.5339307,3.86362719 L11.3469989,3.82801858 C9.73574606,6.70422351 8.1162219,9.57233557 6.5397086,12.4614891 C6.07155197,13.3177144 6.5397086,13.9926595 7.55211798,14.0153196 C8.37097851,14.0331239 9.18983904,14.0153196 10.0086996,14.0153196 L11.5339307,14.0153196 L11.5339307,20.3746944 C13.2212797,17.6004596 14.7779418,14.8148948 16.3312954,12.0244743 C16.9930009,10.8315857 16.579435,10.1647334 15.1832364,10.1598777 L11.5438563,10.1598777 L11.5339307,3.86362719 Z" id="形状"></path>
+            </g>
+        </g>
+    </g>
+</svg>

File diff suppressed because it is too large
+ 6 - 0
src/assets/icons/knowledge-doc.svg


+ 12 - 0
src/assets/icons/knowledge-list.svg

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="28px" height="26px" viewBox="0 0 28 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title></title>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="风险知识-首页" transform="translate(-70.000000, -163.000000)" fill="currentColor" fill-rule="nonzero">
+            <g id="编组" transform="translate(70.000000, 163.000000)">
+                <path d="M22.629625,13.097043 L15.76065,16.4160628 C15.3683856,16.6048358 14.9370551,16.7027324 14.5,16.7021852 C14.0624946,16.7026806 13.6307128,16.6047923 13.237925,16.4160628 L6.36989998,13.0975082 C5.73909999,12.792311 5,13.2421978 5,13.9321482 L5,21.812843 C5,24.1255494 9.25314999,26 14.5,26 C19.74685,26 24,24.1255494 24,21.812843 L24,13.931683 C24,13.2421978 23.2609,12.792311 22.629625,13.097043 L22.629625,13.097043 Z" id="路径"></path>
+                <path d="M27.4780232,6.58402493 L14.4142116,0.0971537476 C14.153066,-0.0323845825 13.846934,-0.0323845825 13.5857884,0.0971537476 L0.521976775,6.58402493 C-0.173992258,6.92980295 -0.173992258,7.9285079 0.521976775,8.27381482 L1.33355063,8.6770655 L1.33355063,14.5246713 C1.33355063,14.9149327 1.64787069,15.2313022 2.03560414,15.2313022 C2.42333758,15.2313022 2.73765764,14.9149327 2.73765764,14.5246713 L2.73765764,9.37427459 L13.5857884,14.760686 C13.846934,14.8902243 14.153066,14.8902243 14.4142116,14.760686 L27.4780232,8.27381482 C28.1739923,7.92850787 28.1739923,6.92980295 27.4780232,6.58402493 Z M2.03607218,16.6445638 C1.64833874,16.6445638 1.33401867,16.9609333 1.33401867,17.3511947 L1.33401867,18.2933692 C1.33401867,18.6836306 1.64833874,19 2.03607218,19 C2.42380563,19 2.73812569,18.6836306 2.73812569,18.2933692 L2.73812569,17.3511947 C2.73812569,17.1637845 2.66415955,16.9840502 2.53249898,16.8515312 C2.4008384,16.7190122 2.22226835,16.6445638 2.03607218,16.6445638 L2.03607218,16.6445638 Z" id="形状"></path>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
src/assets/images/drawer-arrow.png


+ 1 - 0
src/styles.less

@@ -6,6 +6,7 @@
 @import './styles/variables.less';
 @import './styles/custom.less';
 @import './styles/workbench.less';
+@import './styles/knowledge.less';
 
 @layer components {
   .flex-center {

+ 36 - 15
src/styles/custom.less

@@ -119,11 +119,15 @@ textarea {
   --ant-primary-color: #d9e4ff;
   --ant-primary-color-hover: #b2caff;
   --ant-primary-color-active: #839dfd;
+  --ant-error-color: #ffd9d9;
+  &.ant-btn-dangerous {
+    color: #ff0000;
+  }
   &:hover,
   &:active {
-    color: #2953e8;
+    color: #1e5eff;
   }
-  color: #2953e8 !important;
+  color: #1e5eff;
 }
 
 .precaution-green {
@@ -147,26 +151,43 @@ textarea {
 }
 
 .precaution-table {
+  border-radius: 10px;
   .ant-table-title {
     padding: 0;
   }
   thead {
-    th {
-      padding: 8px 14px;
-      color: #5a607f;
-      font-weight: 500;
-      border-bottom: 2px solid #d7dbec;
+    border-radius: 10px;
+    overflow: hidden;
+    > tr {
+      border-radius: 10px;
+      overflow: hidden;
+
+      > th {
+        padding: 18px 18px;
+        color: #7d8da6;
+        font-weight: 500;
+        border-bottom: 1px solid transparent;
+        font-size: 16px;
+        background-color: rgba(165, 180, 203, 0.1);
+        &::before {
+          display: none;
+        }
+        &:last-child {
+          border-top-right-radius: 10px !important;
+        }
+        &:first-child {
+          border-top-left-radius: 10px !important;
+        }
+      }
     }
   }
   tbody {
-    td {
-      color: #131523;
-    }
-  }
-  tr {
-    td {
-      border-bottom: 1px solid #d7dbec;
-      padding: 14px;
+    tr {
+      td {
+        color: rgba(22, 23, 54, 0.8);
+        border-bottom: 1px solid rgba(151, 151, 151, 0.3);
+        padding: 16px;
+      }
     }
   }
   nz-pagination {

+ 63 - 0
src/styles/knowledge.less

@@ -0,0 +1,63 @@
+.knowledge-panel {
+  box-shadow:
+    0px 0px 8px 0px rgba(223, 223, 223, 0.5),
+    0px 3px 4px 0px rgba(0, 0, 0, 0.04);
+  border-radius: 20px;
+  .knowledge-header {
+    height: 97px;
+    box-shadow:
+      0px 0px 8px 0px rgba(223, 223, 223, 0.5),
+      0px 12px 23px 0px rgba(62, 73, 84, 0.04);
+    border-radius: 20px 20px 0px 0px;
+    padding-left: 32px;
+    padding-right: 16px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .title {
+      font-size: 20px;
+      font-weight: 500;
+      line-height: 97px;
+      text-shadow: 0px 0px 8px rgba(223, 223, 223, 0.5);
+    }
+
+    .header-button-group {
+      display: flex;
+      align-items: center;
+      padding: 8px 10px;
+      background-color: rgba(225, 225, 225, 0.57);
+      border-radius: 49px;
+    }
+    .button-item {
+      display: inline-block;
+      min-width: 164px;
+      text-align: center;
+      height: 47px;
+      background: transparent;
+      border-radius: 45px;
+      line-height: 46px;
+      color: #656565;
+      margin-right: 8px;
+      padding: 0 16px;
+      cursor: pointer;
+      transition: all 0.3s;
+      font-size: 18px;
+      font-weight: 600;
+      &:hover {
+        background-color: white;
+      }
+
+      &:last-child {
+        margin-right: 0;
+      }
+      &.active {
+        background-color: #fff;
+        color: var(--deep-blue);
+      }
+    }
+  }
+  .knowledge-content {
+    padding: 24px;
+  }
+}

+ 2 - 0
src/styles/variables.less

@@ -1,4 +1,6 @@
 :root {
   --manager-gray: #5a607f;
   --ant-primary-1: #ecf2ff !important;
+
+  --deep-blue: #2953e8;
 }

+ 1 - 1
src/styles/workbench.less

@@ -35,7 +35,7 @@
         margin-right: 0;
       }
       &.active {
-        background-color: var(--ant-primary-color);
+        background-color: var(--deep-blue);
         color: #ffffff;
       }
     }

+ 0 - 1
src/types/common.d.ts

@@ -25,5 +25,4 @@ interface IPageConfig {
   total: number;
   size: number;
   page: number;
-  current?: number;
 }

+ 1 - 1
tailwind.config.js

@@ -7,7 +7,7 @@ module.exports = {
   theme: {
     extend: {
       colors: {
-        primary: "#2953E8",
+        primary: "#1E5EFF",
       },
     },
   },

Some files were not shown because too many files changed in this diff