Browse Source

'update:实现广场基本页面和模拟面试的逻辑'

abstract001 1 year ago
parent
commit
aa0e2bc7ab

+ 1 - 1
app-angular/package-lock.json

@@ -8679,7 +8679,7 @@
     },
     "node_modules/ng-zorro-antd": {
       "version": "16.2.2",
-      "resolved": "http://registry.npmmirror.com/ng-zorro-antd/-/ng-zorro-antd-16.2.2.tgz",
+      "resolved": "https://registry.npmjs.org/ng-zorro-antd/-/ng-zorro-antd-16.2.2.tgz",
       "integrity": "sha512-Y7ALO+iRjqBfVW9hqnlU4jJUovM5r6wNzXuwTxKIo/5c35/PJFwk++73iwhas6pCb3+kFucwL5XTUWUoLce3wQ==",
       "dependencies": {
         "@angular/cdk": "^16.0.0",

+ 0 - 1744
app-angular/src/assets/charts/data/role-graph.json

@@ -1,1744 +0,0 @@
-{
-    "nodes": [
-      {
-        "id": "0",
-        "name": "Myriel",
-        "symbolSize": 19.12381,
-        "x": -266.82776,
-        "y": 299.6904,
-        "value": 28.685715,
-        "category": 0
-      },
-      {
-        "id": "1",
-        "name": "Napoleon",
-        "symbolSize": 2.6666666666666665,
-        "x": -418.08344,
-        "y": 446.8853,
-        "value": 4,
-        "category": 0
-      },
-      {
-        "id": "2",
-        "name": "MlleBaptistine",
-        "symbolSize": 6.323809333333333,
-        "x": -212.76357,
-        "y": 245.29176,
-        "value": 9.485714,
-        "category": 1
-      },
-      {
-        "id": "3",
-        "name": "MmeMagloire",
-        "symbolSize": 6.323809333333333,
-        "x": -242.82404,
-        "y": 235.26283,
-        "value": 9.485714,
-        "category": 1
-      },
-      {
-        "id": "4",
-        "name": "CountessDeLo",
-        "symbolSize": 2.6666666666666665,
-        "x": -379.30386,
-        "y": 429.06424,
-        "value": 4,
-        "category": 0
-      },
-      {
-        "id": "5",
-        "name": "Geborand",
-        "symbolSize": 2.6666666666666665,
-        "x": -417.26337,
-        "y": 406.03506,
-        "value": 4,
-        "category": 0
-      },
-      {
-        "id": "6",
-        "name": "Champtercier",
-        "symbolSize": 2.6666666666666665,
-        "x": -332.6012,
-        "y": 485.16974,
-        "value": 4,
-        "category": 0
-      },
-      {
-        "id": "7",
-        "name": "Cravatte",
-        "symbolSize": 2.6666666666666665,
-        "x": -382.69568,
-        "y": 475.09113,
-        "value": 4,
-        "category": 0
-      },
-      {
-        "id": "8",
-        "name": "Count",
-        "symbolSize": 2.6666666666666665,
-        "x": -320.384,
-        "y": 387.17325,
-        "value": 4,
-        "category": 0
-      },
-      {
-        "id": "9",
-        "name": "OldMan",
-        "symbolSize": 2.6666666666666665,
-        "x": -344.39832,
-        "y": 451.16772,
-        "value": 4,
-        "category": 0
-      },
-      {
-        "id": "10",
-        "name": "Labarre",
-        "symbolSize": 2.6666666666666665,
-        "x": -89.34107,
-        "y": 234.56128,
-        "value": 4,
-        "category": 1
-      },
-      {
-        "id": "11",
-        "name": "Valjean",
-        "symbolSize": 66.66666666666667,
-        "x": -87.93029,
-        "y": -6.8120565,
-        "value": 100,
-        "category": 1
-      },
-      {
-        "id": "12",
-        "name": "Marguerite",
-        "symbolSize": 4.495239333333333,
-        "x": -339.77908,
-        "y": -184.69139,
-        "value": 6.742859,
-        "category": 1
-      },
-      {
-        "id": "13",
-        "name": "MmeDeR",
-        "symbolSize": 2.6666666666666665,
-        "x": -194.31313,
-        "y": 178.55301,
-        "value": 4,
-        "category": 1
-      },
-      {
-        "id": "14",
-        "name": "Isabeau",
-        "symbolSize": 2.6666666666666665,
-        "x": -158.05168,
-        "y": 201.99768,
-        "value": 4,
-        "category": 1
-      },
-      {
-        "id": "15",
-        "name": "Gervais",
-        "symbolSize": 2.6666666666666665,
-        "x": -127.701546,
-        "y": 242.55057,
-        "value": 4,
-        "category": 1
-      },
-      {
-        "id": "16",
-        "name": "Tholomyes",
-        "symbolSize": 17.295237333333333,
-        "x": -385.2226,
-        "y": -393.5572,
-        "value": 25.942856,
-        "category": 2
-      },
-      {
-        "id": "17",
-        "name": "Listolier",
-        "symbolSize": 13.638097333333334,
-        "x": -516.55884,
-        "y": -393.98975,
-        "value": 20.457146,
-        "category": 2
-      },
-      {
-        "id": "18",
-        "name": "Fameuil",
-        "symbolSize": 13.638097333333334,
-        "x": -464.79382,
-        "y": -493.57944,
-        "value": 20.457146,
-        "category": 2
-      },
-      {
-        "id": "19",
-        "name": "Blacheville",
-        "symbolSize": 13.638097333333334,
-        "x": -515.1624,
-        "y": -456.9891,
-        "value": 20.457146,
-        "category": 2
-      },
-      {
-        "id": "20",
-        "name": "Favourite",
-        "symbolSize": 13.638097333333334,
-        "x": -408.12122,
-        "y": -464.5048,
-        "value": 20.457146,
-        "category": 2
-      },
-      {
-        "id": "21",
-        "name": "Dahlia",
-        "symbolSize": 13.638097333333334,
-        "x": -456.44113,
-        "y": -425.13303,
-        "value": 20.457146,
-        "category": 2
-      },
-      {
-        "id": "22",
-        "name": "Zephine",
-        "symbolSize": 13.638097333333334,
-        "x": -459.1107,
-        "y": -362.5133,
-        "value": 20.457146,
-        "category": 2
-      },
-      {
-        "id": "23",
-        "name": "Fantine",
-        "symbolSize": 28.266666666666666,
-        "x": -313.42786,
-        "y": -289.44803,
-        "value": 42.4,
-        "category": 2
-      },
-      {
-        "id": "24",
-        "name": "MmeThenardier",
-        "symbolSize": 20.95238266666667,
-        "x": 4.6313396,
-        "y": -273.8517,
-        "value": 31.428574,
-        "category": 7
-      },
-      {
-        "id": "25",
-        "name": "Thenardier",
-        "symbolSize": 30.095235333333335,
-        "x": 82.80825,
-        "y": -203.1144,
-        "value": 45.142853,
-        "category": 7
-      },
-      {
-        "id": "26",
-        "name": "Cosette",
-        "symbolSize": 20.95238266666667,
-        "x": 78.64646,
-        "y": -31.512747,
-        "value": 31.428574,
-        "category": 6
-      },
-      {
-        "id": "27",
-        "name": "Javert",
-        "symbolSize": 31.923806666666668,
-        "x": -81.46074,
-        "y": -204.20204,
-        "value": 47.88571,
-        "category": 7
-      },
-      {
-        "id": "28",
-        "name": "Fauchelevent",
-        "symbolSize": 8.152382000000001,
-        "x": -225.73984,
-        "y": 82.41631,
-        "value": 12.228573,
-        "category": 4
-      },
-      {
-        "id": "29",
-        "name": "Bamatabois",
-        "symbolSize": 15.466666666666667,
-        "x": -385.6842,
-        "y": -20.206686,
-        "value": 23.2,
-        "category": 3
-      },
-      {
-        "id": "30",
-        "name": "Perpetue",
-        "symbolSize": 4.495239333333333,
-        "x": -403.92447,
-        "y": -197.69823,
-        "value": 6.742859,
-        "category": 2
-      },
-      {
-        "id": "31",
-        "name": "Simplice",
-        "symbolSize": 8.152382000000001,
-        "x": -281.4253,
-        "y": -158.45137,
-        "value": 12.228573,
-        "category": 2
-      },
-      {
-        "id": "32",
-        "name": "Scaufflaire",
-        "symbolSize": 2.6666666666666665,
-        "x": -122.41348,
-        "y": 210.37503,
-        "value": 4,
-        "category": 1
-      },
-      {
-        "id": "33",
-        "name": "Woman1",
-        "symbolSize": 4.495239333333333,
-        "x": -234.6001,
-        "y": -113.15067,
-        "value": 6.742859,
-        "category": 1
-      },
-      {
-        "id": "34",
-        "name": "Judge",
-        "symbolSize": 11.809524666666666,
-        "x": -387.84915,
-        "y": 58.7059,
-        "value": 17.714287,
-        "category": 3
-      },
-      {
-        "id": "35",
-        "name": "Champmathieu",
-        "symbolSize": 11.809524666666666,
-        "x": -338.2307,
-        "y": 87.48405,
-        "value": 17.714287,
-        "category": 3
-      },
-      {
-        "id": "36",
-        "name": "Brevet",
-        "symbolSize": 11.809524666666666,
-        "x": -453.26874,
-        "y": 58.94648,
-        "value": 17.714287,
-        "category": 3
-      },
-      {
-        "id": "37",
-        "name": "Chenildieu",
-        "symbolSize": 11.809524666666666,
-        "x": -386.44904,
-        "y": 140.05937,
-        "value": 17.714287,
-        "category": 3
-      },
-      {
-        "id": "38",
-        "name": "Cochepaille",
-        "symbolSize": 11.809524666666666,
-        "x": -446.7876,
-        "y": 123.38005,
-        "value": 17.714287,
-        "category": 3
-      },
-      {
-        "id": "39",
-        "name": "Pontmercy",
-        "symbolSize": 6.323809333333333,
-        "x": 336.49738,
-        "y": -269.55914,
-        "value": 9.485714,
-        "category": 6
-      },
-      {
-        "id": "40",
-        "name": "Boulatruelle",
-        "symbolSize": 2.6666666666666665,
-        "x": 29.187843,
-        "y": -460.13132,
-        "value": 4,
-        "category": 7
-      },
-      {
-        "id": "41",
-        "name": "Eponine",
-        "symbolSize": 20.95238266666667,
-        "x": 238.36697,
-        "y": -210.00926,
-        "value": 31.428574,
-        "category": 7
-      },
-      {
-        "id": "42",
-        "name": "Anzelma",
-        "symbolSize": 6.323809333333333,
-        "x": 189.69513,
-        "y": -346.50662,
-        "value": 9.485714,
-        "category": 7
-      },
-      {
-        "id": "43",
-        "name": "Woman2",
-        "symbolSize": 6.323809333333333,
-        "x": -187.00418,
-        "y": -145.02663,
-        "value": 9.485714,
-        "category": 6
-      },
-      {
-        "id": "44",
-        "name": "MotherInnocent",
-        "symbolSize": 4.495239333333333,
-        "x": -252.99521,
-        "y": 129.87549,
-        "value": 6.742859,
-        "category": 4
-      },
-      {
-        "id": "45",
-        "name": "Gribier",
-        "symbolSize": 2.6666666666666665,
-        "x": -296.07935,
-        "y": 163.11964,
-        "value": 4,
-        "category": 4
-      },
-      {
-        "id": "46",
-        "name": "Jondrette",
-        "symbolSize": 2.6666666666666665,
-        "x": 550.3201,
-        "y": 522.4031,
-        "value": 4,
-        "category": 5
-      },
-      {
-        "id": "47",
-        "name": "MmeBurgon",
-        "symbolSize": 4.495239333333333,
-        "x": 488.13535,
-        "y": 356.8573,
-        "value": 6.742859,
-        "category": 5
-      },
-      {
-        "id": "48",
-        "name": "Gavroche",
-        "symbolSize": 41.06667066666667,
-        "x": 387.89572,
-        "y": 110.462326,
-        "value": 61.600006,
-        "category": 8
-      },
-      {
-        "id": "49",
-        "name": "Gillenormand",
-        "symbolSize": 13.638097333333334,
-        "x": 126.4831,
-        "y": 68.10622,
-        "value": 20.457146,
-        "category": 6
-      },
-      {
-        "id": "50",
-        "name": "Magnon",
-        "symbolSize": 4.495239333333333,
-        "x": 127.07365,
-        "y": -113.05923,
-        "value": 6.742859,
-        "category": 6
-      },
-      {
-        "id": "51",
-        "name": "MlleGillenormand",
-        "symbolSize": 13.638097333333334,
-        "x": 162.63559,
-        "y": 117.6565,
-        "value": 20.457146,
-        "category": 6
-      },
-      {
-        "id": "52",
-        "name": "MmePontmercy",
-        "symbolSize": 4.495239333333333,
-        "x": 353.66415,
-        "y": -205.89165,
-        "value": 6.742859,
-        "category": 6
-      },
-      {
-        "id": "53",
-        "name": "MlleVaubois",
-        "symbolSize": 2.6666666666666665,
-        "x": 165.43939,
-        "y": 339.7736,
-        "value": 4,
-        "category": 6
-      },
-      {
-        "id": "54",
-        "name": "LtGillenormand",
-        "symbolSize": 8.152382000000001,
-        "x": 137.69348,
-        "y": 196.1069,
-        "value": 12.228573,
-        "category": 6
-      },
-      {
-        "id": "55",
-        "name": "Marius",
-        "symbolSize": 35.58095333333333,
-        "x": 206.44687,
-        "y": -13.805411,
-        "value": 53.37143,
-        "category": 6
-      },
-      {
-        "id": "56",
-        "name": "BaronessT",
-        "symbolSize": 4.495239333333333,
-        "x": 194.82993,
-        "y": 224.78036,
-        "value": 6.742859,
-        "category": 6
-      },
-      {
-        "id": "57",
-        "name": "Mabeuf",
-        "symbolSize": 20.95238266666667,
-        "x": 597.6618,
-        "y": 135.18481,
-        "value": 31.428574,
-        "category": 8
-      },
-      {
-        "id": "58",
-        "name": "Enjolras",
-        "symbolSize": 28.266666666666666,
-        "x": 355.78366,
-        "y": -74.882454,
-        "value": 42.4,
-        "category": 8
-      },
-      {
-        "id": "59",
-        "name": "Combeferre",
-        "symbolSize": 20.95238266666667,
-        "x": 515.2961,
-        "y": -46.167564,
-        "value": 31.428574,
-        "category": 8
-      },
-      {
-        "id": "60",
-        "name": "Prouvaire",
-        "symbolSize": 17.295237333333333,
-        "x": 614.29285,
-        "y": -69.3104,
-        "value": 25.942856,
-        "category": 8
-      },
-      {
-        "id": "61",
-        "name": "Feuilly",
-        "symbolSize": 20.95238266666667,
-        "x": 550.1917,
-        "y": -128.17537,
-        "value": 31.428574,
-        "category": 8
-      },
-      {
-        "id": "62",
-        "name": "Courfeyrac",
-        "symbolSize": 24.609526666666667,
-        "x": 436.17184,
-        "y": -12.7286825,
-        "value": 36.91429,
-        "category": 8
-      },
-      {
-        "id": "63",
-        "name": "Bahorel",
-        "symbolSize": 22.780953333333333,
-        "x": 602.55225,
-        "y": 16.421427,
-        "value": 34.17143,
-        "category": 8
-      },
-      {
-        "id": "64",
-        "name": "Bossuet",
-        "symbolSize": 24.609526666666667,
-        "x": 455.81955,
-        "y": -115.45826,
-        "value": 36.91429,
-        "category": 8
-      },
-      {
-        "id": "65",
-        "name": "Joly",
-        "symbolSize": 22.780953333333333,
-        "x": 516.40784,
-        "y": 47.242233,
-        "value": 34.17143,
-        "category": 8
-      },
-      {
-        "id": "66",
-        "name": "Grantaire",
-        "symbolSize": 19.12381,
-        "x": 646.4313,
-        "y": -151.06331,
-        "value": 28.685715,
-        "category": 8
-      },
-      {
-        "id": "67",
-        "name": "MotherPlutarch",
-        "symbolSize": 2.6666666666666665,
-        "x": 668.9568,
-        "y": 204.65488,
-        "value": 4,
-        "category": 8
-      },
-      {
-        "id": "68",
-        "name": "Gueulemer",
-        "symbolSize": 19.12381,
-        "x": 78.4799,
-        "y": -347.15146,
-        "value": 28.685715,
-        "category": 7
-      },
-      {
-        "id": "69",
-        "name": "Babet",
-        "symbolSize": 19.12381,
-        "x": 150.35959,
-        "y": -298.50797,
-        "value": 28.685715,
-        "category": 7
-      },
-      {
-        "id": "70",
-        "name": "Claquesous",
-        "symbolSize": 19.12381,
-        "x": 137.3717,
-        "y": -410.2809,
-        "value": 28.685715,
-        "category": 7
-      },
-      {
-        "id": "71",
-        "name": "Montparnasse",
-        "symbolSize": 17.295237333333333,
-        "x": 234.87747,
-        "y": -400.85983,
-        "value": 25.942856,
-        "category": 7
-      },
-      {
-        "id": "72",
-        "name": "Toussaint",
-        "symbolSize": 6.323809333333333,
-        "x": 40.942253,
-        "y": 113.78272,
-        "value": 9.485714,
-        "category": 1
-      },
-      {
-        "id": "73",
-        "name": "Child1",
-        "symbolSize": 4.495239333333333,
-        "x": 437.939,
-        "y": 291.58234,
-        "value": 6.742859,
-        "category": 8
-      },
-      {
-        "id": "74",
-        "name": "Child2",
-        "symbolSize": 4.495239333333333,
-        "x": 466.04922,
-        "y": 283.3606,
-        "value": 6.742859,
-        "category": 8
-      },
-      {
-        "id": "75",
-        "name": "Brujon",
-        "symbolSize": 13.638097333333334,
-        "x": 238.79364,
-        "y": -314.06345,
-        "value": 20.457146,
-        "category": 7
-      },
-      {
-        "id": "76",
-        "name": "MmeHucheloup",
-        "symbolSize": 13.638097333333334,
-        "x": 712.18353,
-        "y": 4.8131495,
-        "value": 20.457146,
-        "category": 8
-      }
-    ],
-    "links": [
-      {
-        "source": "1",
-        "target": "0"
-      },
-      {
-        "source": "2",
-        "target": "0"
-      },
-      {
-        "source": "3",
-        "target": "0"
-      },
-      {
-        "source": "3",
-        "target": "2"
-      },
-      {
-        "source": "4",
-        "target": "0"
-      },
-      {
-        "source": "5",
-        "target": "0"
-      },
-      {
-        "source": "6",
-        "target": "0"
-      },
-      {
-        "source": "7",
-        "target": "0"
-      },
-      {
-        "source": "8",
-        "target": "0"
-      },
-      {
-        "source": "9",
-        "target": "0"
-      },
-      {
-        "source": "11",
-        "target": "0"
-      },
-      {
-        "source": "11",
-        "target": "2"
-      },
-      {
-        "source": "11",
-        "target": "3"
-      },
-      {
-        "source": "11",
-        "target": "10"
-      },
-      {
-        "source": "12",
-        "target": "11"
-      },
-      {
-        "source": "13",
-        "target": "11"
-      },
-      {
-        "source": "14",
-        "target": "11"
-      },
-      {
-        "source": "15",
-        "target": "11"
-      },
-      {
-        "source": "17",
-        "target": "16"
-      },
-      {
-        "source": "18",
-        "target": "16"
-      },
-      {
-        "source": "18",
-        "target": "17"
-      },
-      {
-        "source": "19",
-        "target": "16"
-      },
-      {
-        "source": "19",
-        "target": "17"
-      },
-      {
-        "source": "19",
-        "target": "18"
-      },
-      {
-        "source": "20",
-        "target": "16"
-      },
-      {
-        "source": "20",
-        "target": "17"
-      },
-      {
-        "source": "20",
-        "target": "18"
-      },
-      {
-        "source": "20",
-        "target": "19"
-      },
-      {
-        "source": "21",
-        "target": "16"
-      },
-      {
-        "source": "21",
-        "target": "17"
-      },
-      {
-        "source": "21",
-        "target": "18"
-      },
-      {
-        "source": "21",
-        "target": "19"
-      },
-      {
-        "source": "21",
-        "target": "20"
-      },
-      {
-        "source": "22",
-        "target": "16"
-      },
-      {
-        "source": "22",
-        "target": "17"
-      },
-      {
-        "source": "22",
-        "target": "18"
-      },
-      {
-        "source": "22",
-        "target": "19"
-      },
-      {
-        "source": "22",
-        "target": "20"
-      },
-      {
-        "source": "22",
-        "target": "21"
-      },
-      {
-        "source": "23",
-        "target": "11"
-      },
-      {
-        "source": "23",
-        "target": "12"
-      },
-      {
-        "source": "23",
-        "target": "16"
-      },
-      {
-        "source": "23",
-        "target": "17"
-      },
-      {
-        "source": "23",
-        "target": "18"
-      },
-      {
-        "source": "23",
-        "target": "19"
-      },
-      {
-        "source": "23",
-        "target": "20"
-      },
-      {
-        "source": "23",
-        "target": "21"
-      },
-      {
-        "source": "23",
-        "target": "22"
-      },
-      {
-        "source": "24",
-        "target": "11"
-      },
-      {
-        "source": "24",
-        "target": "23"
-      },
-      {
-        "source": "25",
-        "target": "11"
-      },
-      {
-        "source": "25",
-        "target": "23"
-      },
-      {
-        "source": "25",
-        "target": "24"
-      },
-      {
-        "source": "26",
-        "target": "11"
-      },
-      {
-        "source": "26",
-        "target": "16"
-      },
-      {
-        "source": "26",
-        "target": "24"
-      },
-      {
-        "source": "26",
-        "target": "25"
-      },
-      {
-        "source": "27",
-        "target": "11"
-      },
-      {
-        "source": "27",
-        "target": "23"
-      },
-      {
-        "source": "27",
-        "target": "24"
-      },
-      {
-        "source": "27",
-        "target": "25"
-      },
-      {
-        "source": "27",
-        "target": "26"
-      },
-      {
-        "source": "28",
-        "target": "11"
-      },
-      {
-        "source": "28",
-        "target": "27"
-      },
-      {
-        "source": "29",
-        "target": "11"
-      },
-      {
-        "source": "29",
-        "target": "23"
-      },
-      {
-        "source": "29",
-        "target": "27"
-      },
-      {
-        "source": "30",
-        "target": "23"
-      },
-      {
-        "source": "31",
-        "target": "11"
-      },
-      {
-        "source": "31",
-        "target": "23"
-      },
-      {
-        "source": "31",
-        "target": "27"
-      },
-      {
-        "source": "31",
-        "target": "30"
-      },
-      {
-        "source": "32",
-        "target": "11"
-      },
-      {
-        "source": "33",
-        "target": "11"
-      },
-      {
-        "source": "33",
-        "target": "27"
-      },
-      {
-        "source": "34",
-        "target": "11"
-      },
-      {
-        "source": "34",
-        "target": "29"
-      },
-      {
-        "source": "35",
-        "target": "11"
-      },
-      {
-        "source": "35",
-        "target": "29"
-      },
-      {
-        "source": "35",
-        "target": "34"
-      },
-      {
-        "source": "36",
-        "target": "11"
-      },
-      {
-        "source": "36",
-        "target": "29"
-      },
-      {
-        "source": "36",
-        "target": "34"
-      },
-      {
-        "source": "36",
-        "target": "35"
-      },
-      {
-        "source": "37",
-        "target": "11"
-      },
-      {
-        "source": "37",
-        "target": "29"
-      },
-      {
-        "source": "37",
-        "target": "34"
-      },
-      {
-        "source": "37",
-        "target": "35"
-      },
-      {
-        "source": "37",
-        "target": "36"
-      },
-      {
-        "source": "38",
-        "target": "11"
-      },
-      {
-        "source": "38",
-        "target": "29"
-      },
-      {
-        "source": "38",
-        "target": "34"
-      },
-      {
-        "source": "38",
-        "target": "35"
-      },
-      {
-        "source": "38",
-        "target": "36"
-      },
-      {
-        "source": "38",
-        "target": "37"
-      },
-      {
-        "source": "39",
-        "target": "25"
-      },
-      {
-        "source": "40",
-        "target": "25"
-      },
-      {
-        "source": "41",
-        "target": "24"
-      },
-      {
-        "source": "41",
-        "target": "25"
-      },
-      {
-        "source": "42",
-        "target": "24"
-      },
-      {
-        "source": "42",
-        "target": "25"
-      },
-      {
-        "source": "42",
-        "target": "41"
-      },
-      {
-        "source": "43",
-        "target": "11"
-      },
-      {
-        "source": "43",
-        "target": "26"
-      },
-      {
-        "source": "43",
-        "target": "27"
-      },
-      {
-        "source": "44",
-        "target": "11"
-      },
-      {
-        "source": "44",
-        "target": "28"
-      },
-      {
-        "source": "45",
-        "target": "28"
-      },
-      {
-        "source": "47",
-        "target": "46"
-      },
-      {
-        "source": "48",
-        "target": "11"
-      },
-      {
-        "source": "48",
-        "target": "25"
-      },
-      {
-        "source": "48",
-        "target": "27"
-      },
-      {
-        "source": "48",
-        "target": "47"
-      },
-      {
-        "source": "49",
-        "target": "11"
-      },
-      {
-        "source": "49",
-        "target": "26"
-      },
-      {
-        "source": "50",
-        "target": "24"
-      },
-      {
-        "source": "50",
-        "target": "49"
-      },
-      {
-        "source": "51",
-        "target": "11"
-      },
-      {
-        "source": "51",
-        "target": "26"
-      },
-      {
-        "source": "51",
-        "target": "49"
-      },
-      {
-        "source": "52",
-        "target": "39"
-      },
-      {
-        "source": "52",
-        "target": "51"
-      },
-      {
-        "source": "53",
-        "target": "51"
-      },
-      {
-        "source": "54",
-        "target": "26"
-      },
-      {
-        "source": "54",
-        "target": "49"
-      },
-      {
-        "source": "54",
-        "target": "51"
-      },
-      {
-        "source": "55",
-        "target": "11"
-      },
-      {
-        "source": "55",
-        "target": "16"
-      },
-      {
-        "source": "55",
-        "target": "25"
-      },
-      {
-        "source": "55",
-        "target": "26"
-      },
-      {
-        "source": "55",
-        "target": "39"
-      },
-      {
-        "source": "55",
-        "target": "41"
-      },
-      {
-        "source": "55",
-        "target": "48"
-      },
-      {
-        "source": "55",
-        "target": "49"
-      },
-      {
-        "source": "55",
-        "target": "51"
-      },
-      {
-        "source": "55",
-        "target": "54"
-      },
-      {
-        "source": "56",
-        "target": "49"
-      },
-      {
-        "source": "56",
-        "target": "55"
-      },
-      {
-        "source": "57",
-        "target": "41"
-      },
-      {
-        "source": "57",
-        "target": "48"
-      },
-      {
-        "source": "57",
-        "target": "55"
-      },
-      {
-        "source": "58",
-        "target": "11"
-      },
-      {
-        "source": "58",
-        "target": "27"
-      },
-      {
-        "source": "58",
-        "target": "48"
-      },
-      {
-        "source": "58",
-        "target": "55"
-      },
-      {
-        "source": "58",
-        "target": "57"
-      },
-      {
-        "source": "59",
-        "target": "48"
-      },
-      {
-        "source": "59",
-        "target": "55"
-      },
-      {
-        "source": "59",
-        "target": "57"
-      },
-      {
-        "source": "59",
-        "target": "58"
-      },
-      {
-        "source": "60",
-        "target": "48"
-      },
-      {
-        "source": "60",
-        "target": "58"
-      },
-      {
-        "source": "60",
-        "target": "59"
-      },
-      {
-        "source": "61",
-        "target": "48"
-      },
-      {
-        "source": "61",
-        "target": "55"
-      },
-      {
-        "source": "61",
-        "target": "57"
-      },
-      {
-        "source": "61",
-        "target": "58"
-      },
-      {
-        "source": "61",
-        "target": "59"
-      },
-      {
-        "source": "61",
-        "target": "60"
-      },
-      {
-        "source": "62",
-        "target": "41"
-      },
-      {
-        "source": "62",
-        "target": "48"
-      },
-      {
-        "source": "62",
-        "target": "55"
-      },
-      {
-        "source": "62",
-        "target": "57"
-      },
-      {
-        "source": "62",
-        "target": "58"
-      },
-      {
-        "source": "62",
-        "target": "59"
-      },
-      {
-        "source": "62",
-        "target": "60"
-      },
-      {
-        "source": "62",
-        "target": "61"
-      },
-      {
-        "source": "63",
-        "target": "48"
-      },
-      {
-        "source": "63",
-        "target": "55"
-      },
-      {
-        "source": "63",
-        "target": "57"
-      },
-      {
-        "source": "63",
-        "target": "58"
-      },
-      {
-        "source": "63",
-        "target": "59"
-      },
-      {
-        "source": "63",
-        "target": "60"
-      },
-      {
-        "source": "63",
-        "target": "61"
-      },
-      {
-        "source": "63",
-        "target": "62"
-      },
-      {
-        "source": "64",
-        "target": "11"
-      },
-      {
-        "source": "64",
-        "target": "48"
-      },
-      {
-        "source": "64",
-        "target": "55"
-      },
-      {
-        "source": "64",
-        "target": "57"
-      },
-      {
-        "source": "64",
-        "target": "58"
-      },
-      {
-        "source": "64",
-        "target": "59"
-      },
-      {
-        "source": "64",
-        "target": "60"
-      },
-      {
-        "source": "64",
-        "target": "61"
-      },
-      {
-        "source": "64",
-        "target": "62"
-      },
-      {
-        "source": "64",
-        "target": "63"
-      },
-      {
-        "source": "65",
-        "target": "48"
-      },
-      {
-        "source": "65",
-        "target": "55"
-      },
-      {
-        "source": "65",
-        "target": "57"
-      },
-      {
-        "source": "65",
-        "target": "58"
-      },
-      {
-        "source": "65",
-        "target": "59"
-      },
-      {
-        "source": "65",
-        "target": "60"
-      },
-      {
-        "source": "65",
-        "target": "61"
-      },
-      {
-        "source": "65",
-        "target": "62"
-      },
-      {
-        "source": "65",
-        "target": "63"
-      },
-      {
-        "source": "65",
-        "target": "64"
-      },
-      {
-        "source": "66",
-        "target": "48"
-      },
-      {
-        "source": "66",
-        "target": "58"
-      },
-      {
-        "source": "66",
-        "target": "59"
-      },
-      {
-        "source": "66",
-        "target": "60"
-      },
-      {
-        "source": "66",
-        "target": "61"
-      },
-      {
-        "source": "66",
-        "target": "62"
-      },
-      {
-        "source": "66",
-        "target": "63"
-      },
-      {
-        "source": "66",
-        "target": "64"
-      },
-      {
-        "source": "66",
-        "target": "65"
-      },
-      {
-        "source": "67",
-        "target": "57"
-      },
-      {
-        "source": "68",
-        "target": "11"
-      },
-      {
-        "source": "68",
-        "target": "24"
-      },
-      {
-        "source": "68",
-        "target": "25"
-      },
-      {
-        "source": "68",
-        "target": "27"
-      },
-      {
-        "source": "68",
-        "target": "41"
-      },
-      {
-        "source": "68",
-        "target": "48"
-      },
-      {
-        "source": "69",
-        "target": "11"
-      },
-      {
-        "source": "69",
-        "target": "24"
-      },
-      {
-        "source": "69",
-        "target": "25"
-      },
-      {
-        "source": "69",
-        "target": "27"
-      },
-      {
-        "source": "69",
-        "target": "41"
-      },
-      {
-        "source": "69",
-        "target": "48"
-      },
-      {
-        "source": "69",
-        "target": "68"
-      },
-      {
-        "source": "70",
-        "target": "11"
-      },
-      {
-        "source": "70",
-        "target": "24"
-      },
-      {
-        "source": "70",
-        "target": "25"
-      },
-      {
-        "source": "70",
-        "target": "27"
-      },
-      {
-        "source": "70",
-        "target": "41"
-      },
-      {
-        "source": "70",
-        "target": "58"
-      },
-      {
-        "source": "70",
-        "target": "68"
-      },
-      {
-        "source": "70",
-        "target": "69"
-      },
-      {
-        "source": "71",
-        "target": "11"
-      },
-      {
-        "source": "71",
-        "target": "25"
-      },
-      {
-        "source": "71",
-        "target": "27"
-      },
-      {
-        "source": "71",
-        "target": "41"
-      },
-      {
-        "source": "71",
-        "target": "48"
-      },
-      {
-        "source": "71",
-        "target": "68"
-      },
-      {
-        "source": "71",
-        "target": "69"
-      },
-      {
-        "source": "71",
-        "target": "70"
-      },
-      {
-        "source": "72",
-        "target": "11"
-      },
-      {
-        "source": "72",
-        "target": "26"
-      },
-      {
-        "source": "72",
-        "target": "27"
-      },
-      {
-        "source": "73",
-        "target": "48"
-      },
-      {
-        "source": "74",
-        "target": "48"
-      },
-      {
-        "source": "74",
-        "target": "73"
-      },
-      {
-        "source": "75",
-        "target": "25"
-      },
-      {
-        "source": "75",
-        "target": "41"
-      },
-      {
-        "source": "75",
-        "target": "48"
-      },
-      {
-        "source": "75",
-        "target": "68"
-      },
-      {
-        "source": "75",
-        "target": "69"
-      },
-      {
-        "source": "75",
-        "target": "70"
-      },
-      {
-        "source": "75",
-        "target": "71"
-      },
-      {
-        "source": "76",
-        "target": "48"
-      },
-      {
-        "source": "76",
-        "target": "58"
-      },
-      {
-        "source": "76",
-        "target": "62"
-      },
-      {
-        "source": "76",
-        "target": "63"
-      },
-      {
-        "source": "76",
-        "target": "64"
-      },
-      {
-        "source": "76",
-        "target": "65"
-      },
-      {
-        "source": "76",
-        "target": "66"
-      }
-    ],
-    "categories": [
-      {
-        "name": "A"
-      },
-      {
-        "name": "B"
-      },
-      {
-        "name": "C"
-      },
-      {
-        "name": "D"
-      },
-      {
-        "name": "E"
-      },
-      {
-        "name": "F"
-      },
-      {
-        "name": "G"
-      },
-      {
-        "name": "H"
-      },
-      {
-        "name": "I"
-      }
-    ]
-  }

+ 99 - 0
app-angular/src/modules/home/class-chat-completion.ts

@@ -0,0 +1,99 @@
+export interface TestChatMessage{
+  role:string
+  content:string
+}
+export class TestChatCompletion{
+  messageList:Array<TestChatMessage>
+  constructor(messageList:Array<TestChatMessage>){
+    this.messageList = messageList
+  }
+  async createCompletionByStream() {
+
+    let token = localStorage.getItem("token");
+    let bodyJson = {
+      "token": `Bearer ${token}`,
+      "messages": this.messageList,
+      "model": "gpt-3.5-turbo",
+      "temperature": 0.5,
+      "presence_penalty": 0,
+      "frequency_penalty": 0,
+      "top_p": 1,
+      "stream":true
+    };
+
+    let response = await fetch("https://test.fmode.cn/api/apig/aigc/gpt/v1/chat/completions", {
+      "headers": {
+        "accept": "text/event-stream",
+        "sec-fetch-dest": "empty",
+        "sec-fetch-mode": "cors",
+        "sec-fetch-site": "same-site"
+      },
+      "referrer": "https://ai.fmode.cn/",
+      "referrerPolicy": "strict-origin-when-cross-origin",
+      "body": JSON.stringify(bodyJson),
+      "method": "POST",
+      "mode": "cors",
+      "credentials": "omit"
+    });
+
+    let messageAiReply = ""
+    let messageIndex = this.messageList.length
+    let reader = response.body?.getReader();
+    if (!reader) {
+      throw new Error("Failed to get the response reader.");
+    }
+
+    let decoder = new TextDecoder();
+    let buffer = "";
+
+    while (true) {
+      let { done, value } = await reader.read();
+      if (done) {
+        break;
+      }
+
+      buffer += decoder.decode(value);
+
+      // Split the buffer by newlines to get individual messages
+      let messages = buffer.split("\n");
+
+      // Process each message
+      for (let i = 0; i < messages.length - 1; i++) {
+        let message = messages[i];
+
+        // Process the message as needed
+        /**
+         * data: {"id":"chatcmpl-y2PLKqPDnwAFJIj2L5aqdH5TWK9Yv","object":"chat.completion.chunk","created":1696770162,"model":"gpt-3.5-turbo-0613","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
+         * data: {"id":"chatcmpl-y2PLKqPDnwAFJIj2L5aqdH5TWK9Yv","object":"chat.completion.chunk","created":1696770162,"model":"gpt-3.5-turbo-0613","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
+         * data: [DONE]
+         */
+        let dataText = message.replace("data:\ ","")
+        if(dataText.startsWith("{")){
+          try{
+            let dataJson = JSON.parse(dataText)
+            console.log(dataJson)
+            messageAiReply += dataJson?.choices?.[0]?.delta?.content || ""
+            this.messageList[messageIndex] = {
+              role:"assistant",
+              content:messageAiReply
+            }
+          }catch(err){}
+        }
+        if(dataText.startsWith("[")){
+          console.log(message)
+          console.log("完成")
+          this.messageList[messageIndex] = {
+            role:"assistant",
+            content:messageAiReply
+          }
+          messageAiReply = ""
+        }
+        // Parse the message as JSON
+        // let data = JSON.parse(message);
+
+        // Clear the processed message from the buffer
+        buffer = buffer.slice(message.length + 1);
+      }
+    }
+  }
+}

+ 137 - 3
app-angular/src/modules/home/experience-square-information/experience-square-information.component.html

@@ -1,7 +1,141 @@
+<div class="container">
+  <div class="breadcrumb-container">
+    <nz-breadcrumb>
+      <nz-breadcrumb-item>
+        <a [routerLink]="['../']">&lt;</a>
+      </nz-breadcrumb-item>
+      <nz-breadcrumb-item>
+        信息
+      </nz-breadcrumb-item>
+    </nz-breadcrumb>
+  </div>
+  <!-- 其他页面内容 -->
+</div>
+
 <nz-layout>
-  <nz-layout>
-    <nz-header>Header</nz-header>
-    <nz-content>Content</nz-content>
+  <nz-layout class="nz-content-container">
+    <nz-content>
+      <div class="card">
+        <div class="header">
+          <!-- 头像图片 -->
+          <nz-avatar
+            [nzSize]="ngSize ? ngSize : 'large'"
+            [nzSrc]="avatarSrc">
+          </nz-avatar>
+          <div class="share-button">
+            <button nz-button (click)="showModal()">
+              <span nz-icon nzType="share-alt" nzTheme="outline"></span>
+            </button>
+            <nz-modal [(nzVisible)]="isVisible" nzTitle="The first Modal" (nzOnCancel)="handleCancel()"
+                      (nzOnOk)="handleOk()">
+              <ng-container *nzModalContent>
+                <p>Content one</p>
+                <p>Content two</p>
+                <p>Content three</p>
+              </ng-container>
+            </nz-modal>
+          </div>
+        </div>
+        <hr class="divider"/>
+        <div class="content">
+          <!-- 文本和图片数据 -->
+          <h4>我今天找到了一个好工作</h4>
+          <p>Special beta pricing's almost over, don't miss out. Head to http://enva.t to check it out & sign up. Don’t
+            forget o subscribe.</p>
+          <img nz-image width="200px" src="assets/images/page-mine/myAvatar.png" alt=""/>
+        </div>
+        <hr class="divider"/>
+        <div class="actions">
+          <button class="icon-button" [ngClass]="{'active': likeActive}" (click)="toggleLike()">
+            <span nz-icon nzType="like" nzTheme="outline"></span>
+          </button>
+          <button class="icon-button" [ngClass]="{'active': dislikeActive}" (click)="toggleDislike()">
+            <span nz-icon nzType="dislike" nzTheme="outline"></span>
+          </button>
+          <button class="icon-button">
+            <span nz-icon nzType="comment" nzTheme="outline"></span>
+          </button>
+          <button class="icon-button">
+            <span nz-icon nzType="star" nzTheme="outline"></span>
+          </button>
+        </div>
+      </div>
+
+    </nz-content>
+    <nz-content>
+      <div class="message-box">
+        <div class="icons">
+          <button class="icon-button" (click)="uploadImage()">
+            <span class="icon">上传图片</span>
+          </button>
+          <button class="icon-button" (click)="sendEmoji()">
+            <span class="icon">发送表情</span>
+          </button>
+        </div>
+        <textarea class="message-input" [(ngModel)]="messageContent" (keydown)="handleKeyDown($event)"></textarea>
+        <button class="send-button" (click)="sendMessage()">发送</button>
+      </div>
+    </nz-content>
+    <nz-content>
+      <div class="comment-section">
+        <div class="comment-count">
+          <span class="count">{{ commentCount }}</span>
+        </div>
+        <hr class="divider">
+      </div>
+    </nz-content>
+    <nz-content>
+      <ng-template #commentTemplateRef let-comment="comment">
+        <nz-comment [nzAuthor]="comment.author">
+          <nz-avatar nz-comment-avatar nzIcon="user" [nzSrc]="comment.avatar"></nz-avatar>
+          <nz-comment-content>
+            <p>{{ comment.content }}</p>
+          </nz-comment-content>
+          <nz-comment-action>
+            <span
+              nz-tooltip
+              nzTitle="Like"
+              nz-icon
+              nzType="like"
+              [nzTheme]="likes > 0 ? 'twotone' : 'outline'"
+              (click)="like()"
+            ></span>
+            <span class="count like">{{ likes }}</span>
+          </nz-comment-action>
+          <nz-comment-action>
+            <span
+              nz-tooltip
+              nzTitle="Dislike"
+              nz-icon
+              nzType="dislike"
+              [nzTheme]="dislikes > 0 ? 'twotone' : 'outline'"
+              (click)="dislike()"
+            ></span>
+            <span class="count dislike">{{ dislikes }}</span>
+          </nz-comment-action>
+          <nz-comment-action>
+            <span *ngIf="comment.isParent"
+                  nz-tooltip
+                  nzTitle="Expand"
+                  nz-icon
+                  nzType="comment"
+                  nzTheme="outline"
+                  (click)="toggleExpand(comment)"></span>
+          </nz-comment-action>
+          <ng-container *ngIf="comment.children && comment.children.length && comment.children.expanded">
+            <ng-template ngFor let-child [ngForOf]="comment.children">
+              <ng-template
+                [ngTemplateOutlet]="commentTemplateRef"
+                [ngTemplateOutletContext]="{ comment: child }"
+              ></ng-template>
+            </ng-template>
+          </ng-container>
+        </nz-comment>
+      </ng-template>
+
+      <ng-template [ngTemplateOutlet]="commentTemplateRef"
+                   [ngTemplateOutletContext]="{ comment: data[0] }"></ng-template>
+    </nz-content>
     <nz-footer>Footer</nz-footer>
   </nz-layout>
   <nz-sider>Sider</nz-sider>

+ 210 - 11
app-angular/src/modules/home/experience-square-information/experience-square-information.component.scss

@@ -2,29 +2,21 @@
   text-align: center;
 }
 
-nz-header,
-nz-footer {
-  background: #7dbcea;
-  color: #fff;
-}
 
 nz-footer {
   line-height: 1.5;
 }
 
 nz-sider {
-  background: #3ba0e9;
-  color: #fff;
+  background-color: #EEF0F4FF;
   line-height: 120px;
 }
 
 nz-content {
-  background: rgba(16, 142, 233, 1);
-  color: #fff;
-  min-height: 120px;
-  line-height: 120px;
+  margin-top: 20px;
 }
 
+
 nz-layout {
   margin-bottom: 48px;
 }
@@ -34,3 +26,210 @@ nz-layout:last-child {
   margin: 0;
 }
 
+//面包屑
+.container {
+  display: flex;
+  align-items: center;
+  padding: 16px;
+  background-color: #eef0f4;
+}
+
+.breadcrumb-container {
+  margin-right: auto;
+}
+
+.breadcrumb-container nz-breadcrumb {
+  display: flex;
+  align-items: center;
+}
+
+.breadcrumb-container nz-breadcrumb-item {
+  margin-right: 8px;
+}
+
+.breadcrumb-container nz-breadcrumb-item:last-child {
+  margin-right: 0;
+}
+
+.breadcrumb-container nz-breadcrumb-item a {
+  color: #1890ff;
+}
+
+.breadcrumb-container nz-breadcrumb-item a:hover {
+  text-decoration: underline;
+}
+
+//信息展示页面
+.card {
+  border-radius: 8px;
+  background-color: #fff;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+  padding: 16px;
+}
+
+.header {
+  display: flex;
+  align-items: center;
+  height: 50px;
+}
+
+
+.share-button {
+  margin-left: auto;
+}
+
+.divider {
+  border: none;
+  border-top: 1px solid #eee;
+  margin: 16px 0;
+}
+
+.content p {
+  margin-top: 5px;
+  line-height: 15px;
+  /* 文本和图片样式 */
+}
+
+.actions {
+  display: flex;
+  justify-content: space-between;
+}
+
+//图标
+.icon-button {
+  background-color: transparent;
+  border: none;
+  outline: none;
+  cursor: pointer;
+  margin-right: 8px;
+}
+
+//图标更改颜色
+.icon-button {
+  background-color: #fff;
+  color: #000;
+  border: none;
+  padding: 0;
+  margin-right: 10px;
+  cursor: pointer;
+
+  &:hover {
+    background-color: #f2f2f2;
+  }
+
+  &.active {
+    background-color: red;
+    color: #fff;
+  }
+}
+
+.actions {
+  display: flex;
+  align-items: center;
+}
+
+
+//滚动条
+nz-content-container {
+  overflow: auto;
+}
+
+//留言框
+.message-box {
+  display: flex;
+  align-items: center;
+  background-color: #f2f2f2;
+  padding: 10px;
+}
+
+.icons {
+  display: flex;
+  margin-right: 10px;
+}
+
+.icon-button {
+  background-color: transparent;
+  border: none;
+  cursor: pointer;
+  margin-right: 10px;
+}
+
+.icon {
+  color: #000;
+}
+
+.message-input {
+  flex: 1;
+  height: 100px;
+  resize: vertical;
+  padding: 5px;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+}
+
+.send-button {
+  background-color: #007bff;
+  color: #fff;
+  border: none;
+  padding: 5px 10px;
+  border-radius: 5px;
+  cursor: pointer;
+}
+
+//评论条数
+.comment-section {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-start;
+}
+
+.comment-count {
+  font-size: 18px;
+  font-weight: bold;
+  margin-bottom: 10px;
+}
+
+.count {
+  background-color: #007bff;
+  color: #fff;
+  padding: 5px 10px;
+  border-radius: 50%;
+}
+
+.divider {
+  border: none;
+  border-top: 1px solid #ccc;
+  width: 100%;
+  margin: 10px 0;
+}
+
+//评论点赞
+.count {
+  padding-left: 8px;
+  cursor: auto;
+}
+
+.ant-comment-rtl .count {
+  padding-right: 8px;
+  padding-left: 0;
+}
+
+//评论子集查看
+.comment-section {
+  .nz-comment-action {
+    .anticon-comment {
+      cursor: pointer;
+    }
+
+    .expanded {
+      color: #1890ff;
+    }
+  }
+}
+
+
+
+
+
+
+

+ 112 - 1
app-angular/src/modules/home/experience-square-information/experience-square-information.component.ts

@@ -1,4 +1,5 @@
-import { Component } from '@angular/core';
+import {Component} from '@angular/core';
+import {formatDistance} from 'date-fns';
 
 @Component({
   selector: 'app-experience-square-information',
@@ -6,5 +7,115 @@ import { Component } from '@angular/core';
   styleUrls: ['./experience-square-information.component.scss']
 })
 export class ExperienceSquareInformationComponent {
+//  头像
+  avatarSrc: string | undefined = "assets/images/page-mine/myAvatar.png";
+  ngSize: number | null = null;
+  //分享框弹出
+  isVisible = false;
 
+  constructor() {
+  }
+
+  showModal(): void {
+    this.isVisible = true;
+  }
+
+  handleOk(): void {
+    console.log('Button ok clicked!');
+    this.isVisible = false;
+  }
+
+  handleCancel(): void {
+    console.log('Button cancel clicked!');
+    this.isVisible = false;
+  }
+
+  //点赞等逻辑
+  likeActive = false;
+  dislikeActive = false;
+
+  toggleLike() {
+    this.likeActive = !this.likeActive;
+    if (this.likeActive) {
+      this.dislikeActive = false;
+    }
+  }
+
+  toggleDislike() {
+    this.dislikeActive = !this.dislikeActive;
+    if (this.dislikeActive) {
+      this.likeActive = false;
+    }
+  }
+
+  //留言框
+  messageContent = '';
+
+  uploadImage() {
+    // 处理上传图片逻辑
+  }
+
+  sendEmoji() {
+    // 处理发送表情逻辑
+  }
+
+  handleKeyDown(event: KeyboardEvent) {
+    if (event.key === 'Enter' && !event.shiftKey) {
+      event.preventDefault();
+      // 处理发送逻辑
+    }
+  }
+
+  sendMessage() {
+    // 处理发送逻辑
+  }
+
+  //评论条数
+  commentCount: string = '345' + '条';
+  //评论列表数据
+  data = [
+    {
+      author: 'User1',
+      avatar: 'path/to/avatar1.jpg',
+      content: 'This is the first comment.',
+      likes: 10,
+      dislikes: 5,
+      isParent: true,
+      children: [
+        {
+          author: 'User2',
+          avatar: 'path/to/avatar2.jpg',
+          content: 'This is a nested comment.',
+          likes: 5,
+          dislikes: 2,
+          expanded: false,
+        }
+      ],
+      // 添加一个属性来记录子评论的显示状态,默认为false
+    }
+  ];
+  //评论点赞
+  likes = 0;
+  dislikes = 0;
+  time = formatDistance(new Date(), new Date());
+
+  like(): void {
+    this.likes = 1;
+    this.dislikes = 0;
+  }
+
+  dislike(): void {
+    this.likes = 0;
+    this.dislikes = 1;
+  }
+
+  //评论子集打开
+  toggleExpand(comment: any) {
+    console.log(comment)
+    if (comment.children.expanded) {
+      comment.children.expanded = !comment.children.expanded;
+    } else {
+      comment.children.expanded = !comment.children.expanded;
+    }
+  }
 }

+ 2 - 0
app-angular/src/modules/home/home.module.ts

@@ -44,6 +44,7 @@ import {
 } from './experience-square-information/experience-square-information.component';
 import {MapModule} from "../map/map.module";
 import {NzDrawerModule} from "ng-zorro-antd/drawer";
+import {NzBreadCrumbModule} from "ng-zorro-antd/breadcrumb";
 
 @NgModule({
   declarations: [
@@ -91,6 +92,7 @@ import {NzDrawerModule} from "ng-zorro-antd/drawer";
         NzToolTipModule,
         MapModule,
         NzDrawerModule,
+        NzBreadCrumbModule,
 
     ]
 })

+ 55 - 17
app-angular/src/modules/home/mock-interviews/mock-interviews.component.html

@@ -1,17 +1,55 @@
-<div class="container" *ngIf="!showContent">
-  <button class="btn-82" (click)="startAnimation()" [@fadeAnimation] *ngIf="!showProgress">
-    <span>Button</span>
-  </button>
-  <div class="progress-circle" *ngIf="showProgress">
-    <div class="progress-value">{{ progress }}%</div>
-  </div>
-</div>
-
-<div class="container" *ngIf="showContent">
-  <!-- 正式页面内容 -->
-  <nz-layout>
-    <nz-header>Header</nz-header>
-    <nz-content>Content</nz-content>
-    <nz-footer>Footer</nz-footer>
-  </nz-layout>
-</div>
+<!--<div class="chatlist col" *ngIf="false">-->
+
+<!--</div>-->
+
+<!--<div class="chatbox col">-->
+<!--  <div class="msglist">-->
+<!--    <ng-container *ngFor="let msg of messageList">-->
+<!--      <div class="msgbox">-->
+<!--        {{msg?.content}}-->
+<!--      </div>-->
+<!--    </ng-container>-->
+<!--  </div>-->
+<!--  &lt;!&ndash; 底部:用户输入 &ndash;&gt;-->
+<!--  <div class="footer">-->
+<!--    <ion-item>-->
+<!--      <ion-textarea [(ngModel)]="userInput"-->
+<!--                    labelPlacement="floating"-->
+<!--                    label="请输入" placeholder="提示词"></ion-textarea>-->
+<!--      <ion-button (click)="send()">发送</ion-button>-->
+<!--    </ion-item>-->
+<!--  </div>-->
+<!--</div>-->
+
+<nz-tabset [nzTabPosition]="'left'">
+  <nz-tab [nzTitle]="'选择页面'">
+    <!-- 选择页面的内容 -->
+  </nz-tab>
+  <nz-tab [nzTitle]="'面试环节'">
+    <div class="chat-container">
+      <div class="chat-window" #chatWindow>
+        <div class="chat-label">聊天记录</div>
+        <div class="chat-messages">
+          <div *ngFor="let message of messagesList" class="message"
+               [ngClass]="{'left': getReceived(message.role), 'right': getReceived(message.role)}">
+            <div class="avatar" [ngClass]="{'left': getReceived(message.role), 'right':getReceived(message.role)}">
+              <img [src]="getAvatar(message.role)" alt="Avatar"/>
+            </div>
+            <div class="content">{{ message.content }}</div>
+          </div>
+        </div>
+      </div>
+      <div class="input-container">
+        <textarea [nzSize]="'large'" nz-input [(ngModel)]="inputText" placeholder="请输入消息"
+                  (keydown)="handleKeyDown($event)"></textarea>
+        <button nz-button nzType="primary" (click)="send()">发送</button>
+      </div>
+    </div>
+  </nz-tab>
+</nz-tabset>
+
+
+
+
+
+

+ 79 - 183
app-angular/src/modules/home/mock-interviews/mock-interviews.component.scss

@@ -1,209 +1,105 @@
-//动画特效
-.container {
+.chat-container {
   display: flex;
   flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  height: 100vh;
-}
-
-.btn-82,
-.btn-82 *,
-.btn-82 :after,
-.btn-82 :before,
-.btn-82:after,
-.btn-82:before {
-  border: 0 solid;
-  box-sizing: border-box;
-}
-
-.btn-82 {
-  -webkit-tap-highlight-color: transparent;
-  -webkit-appearance: button;
-  background-color: darkgreen;
-  background-image: none;
-  color: pink;
-  cursor: pointer;
-  font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
-  Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif,
-  Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
-  font-size: 100%;
-  font-weight: 900;
-  line-height: 1.5;
-  margin: 0;
-  -webkit-mask-image: -webkit-radial-gradient(#000, #fff);
-  padding: 0;
-}
-
-.btn-82:disabled {
-  cursor: default;
-}
-
-.btn-82:-moz-focusring {
-  outline: auto;
-}
-
-.btn-82 svg {
-  display: block;
-  vertical-align: middle;
-}
-
-.btn-82 [hidden] {
-  display: none;
-}
+  height: calc(100vh - 120px); /* 使用Viewport单位,减去头部导航栏的高度 */
 
-.btn-82 {
-  background: none;
-  border-radius: 999px;
-  box-sizing: border-box;
-  display: block;
-  overflow: hidden;
-  padding: 1.2rem 3rem;
-  position: relative;
-  text-transform: uppercase;
-}
-
-.btn-82 span {
-  font-weight: 900;
-  mix-blend-mode: difference;
-  transition: opacity 0.2s;
-}
+  .chat-window {
+    flex-grow: 1;
+    overflow-y: auto;
+    border: 1px solid #ccc;
+    padding: 10px;
+  }
 
-.btn-82:hover span {
-  -webkit-animation: text-reset 0.2s 0.8s forwards;
-  animation: text-reset 0.2s 0.8s forwards;
-  opacity: 0;
-}
+  .chat-label {
+    font-weight: bold;
+    margin-bottom: 10px;
+  }
 
-.btn-82:after,
-.btn-82:before {
-  border: 4px solid #fff;
-  border-radius: 999px;
-  content: "";
-  height: 100%;
-  left: 0;
-  position: absolute;
-  top: 50%;
-  transform: translateY(-50%);
-  transition: height 0.2s;
-  width: 100%;
-}
+  .chat-messages {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+  }
 
-.btn-82:after {
-  background: darkgreen;
-  border: none;
-  height: 2rem;
-  width: 0;
-  z-index: -1;
-}
+  .message {
+    display: flex;
+    align-items: center;
+    margin-top: 10px;
 
-.btn-82:hover:before {
-  -webkit-animation: border-reset 0.2s linear 0.78s forwards;
-  animation: border-reset 0.2s linear 0.78s forwards;
-  height: 2rem;
-}
+    &.right {
+      flex-direction: row-reverse;
+      align-items: flex-end;
+    }
+  }
 
-.btn-82:hover:after {
-  -webkit-animation: progress-bar 1s;
-  animation: progress-bar 1s;
-}
+  .avatar {
+    width: 40px;
+    height: 40px;
+    margin-right: 10px;
 
-@-webkit-keyframes progress-bar {
-  0% {
-    opacity: 1;
-    width: 0;
+    img {
+      width: 100%;
+      height: 100%;
+      border-radius: 50%;
+    }
   }
-  10% {
-    opacity: 1;
-    width: 15%;
-  }
-  25% {
-    opacity: 1;
-    width: 25%;
-  }
-  40% {
-    opacity: 1;
-    width: 35%;
-  }
-  55% {
-    opacity: 1;
-    width: 75%;
-  }
-  60% {
-    opacity: 1;
-    width: 100%;
-  }
-  to {
-    opacity: 0;
-    width: 100%;
-  }
-}
 
-@keyframes progress-bar {
-  0% {
-    opacity: 1;
-    width: 0;
-  }
-  10% {
-    opacity: 1;
-    width: 15%;
-  }
-  25% {
-    opacity: 1;
-    width: 25%;
-  }
-  40% {
-    opacity: 1;
-    width: 35%;
-  }
-  55% {
-    opacity: 1;
-    width: 75%;
-  }
-  60% {
-    opacity: 1;
-    width: 100%;
-  }
-  to {
-    opacity: 0;
-    width: 100%;
+  .avatar.left {
+    align-self: flex-start;
   }
-}
 
-@-webkit-keyframes border-reset {
-  0% {
-    height: 2rem !important;
+  .avatar.right {
+    align-self: flex-end;
   }
-  to {
-    height: 100% !important;
+
+  .avatar img {
+    min-width: 40px;
+    max-height: 100%;
+    border-radius: 50%;
   }
-}
 
-@keyframes border-reset {
-  0% {
-    height: 2rem !important;
+  .content {
+    background-color: #f1f1f1;
+    padding: 10px;
+    border-radius: 5px;
   }
-  to {
-    height: 100% !important;
+
+  .left {
+    align-self: flex-start;
   }
-}
 
-@-webkit-keyframes text-reset {
-  0% {
-    opacity: 0;
+  .right {
+    align-self: flex-end;
   }
-  to {
-    opacity: 1;
+
+  .left .content {
+    background: cornflowerblue;
   }
-}
 
-@keyframes text-reset {
-  0% {
-    opacity: 0;
+  .right .content {
+    background: lightgray;
   }
-  to {
-    opacity: 1;
+
+  .segmented-container {
+    display: flex;
+    flex-direction: column;
   }
-}
 
+  .input-container {
+    display: flex;
+    align-items: center;
+    margin-top: auto; // 将输入框容器推到底部
 
+    textarea {
+      flex: 9; /* 输入框占据左边90% */
+      overflow-wrap: break-word; /* 当文字超过一行宽度时自动换行 */
+      white-space: normal; /* 允许文本换行 */
+    }
+
+    button {
+      flex: 1; /* 发送按钮占据右边10% */
+      margin-left: 10px; /* 添加一些间隔 */
+      justify-self: flex-end; /* 居右对齐 */
+    }
+  }
+}

+ 107 - 1
app-angular/src/modules/home/mock-interviews/mock-interviews.component.ts

@@ -1,5 +1,6 @@
-import {Component} from '@angular/core';
+import {Component, ElementRef, ViewChild} from '@angular/core';
 import {trigger, state, style, animate, transition} from '@angular/animations';
+import {TestChatCompletion, TestChatMessage} from '../class-chat-completion';
 
 @Component({
   selector: 'app-mock-interviews',
@@ -22,4 +23,109 @@ export class MockInterviewsComponent {
     this.showProgress = true;
     this.showContent = true;
   }
+
+  completion: TestChatCompletion
+  @ViewChild('chatWindow', {static: false}) chatWindow!: ElementRef;
+
+
+  constructor() {
+    this.completion = new TestChatCompletion(this.messagesList)
+
+  }
+
+  messagesList: Array<TestChatMessage> = [
+    {
+      role: "assistant",
+      content: "哈喽我的您的面试官,请点击发送,我们将准备开始面试"
+    },
+  ]
+
+  inputText = '';
+
+  getAvatar(role: string): string {
+    if (role === 'assistant') {
+      return 'assets/images/page-mine/myAvatar.png';
+    } else {
+      return 'assets/images/page-mine/myAvatar.png';
+    }
+  }
+
+  getReceived(role: string): boolean {
+    return role !== 'assistant';
+  }
+
+  handleShiftEnter() {
+    this.inputText += '?';
+  }
+
+  handleEnter() {
+    this.send()
+  }
+
+  handleKeyDown(event: KeyboardEvent) {
+    if (event.shiftKey && event.key === 'Enter') {
+      event.preventDefault()
+      this.handleShiftEnter();
+    } else if (event.key === 'Enter') {
+      event.preventDefault()
+      this.handleEnter();
+    }
+  }
+
+  isStart: number = 0
+
+
+  // 滚动到底部
+  scrollToBottom() {
+    const chatWindow = this.chatWindow.nativeElement;
+    chatWindow.scrollTop = chatWindow.scrollHeight;
+  }
+
+  // 在视图检查后滚动到底部
+  ngAfterViewChecked() {
+    this.scrollToBottom();
+  }
+
+  send() {
+    if (this.isStart == 0) {
+      this.getQuestion()
+      this.isStart += 1
+    }
+    if (this.isStart == 1) {
+      this.messagesList.push({
+        role: "user",
+        content: "开始面试",
+      });
+      this.inputText = "";
+      this.completion.createCompletionByStream();
+      this.isStart += 1
+      return;
+    }
+    if (this.inputText != '' && this.isStart > 1) {
+      console.log(this.inputText);
+      this.messagesList.push({
+        role: "user",
+        content: this.inputText += '回答完毕',
+      });
+      this.inputText = "";
+      this.completion.createCompletionByStream();
+      // 将滚动条滚动到底部
+      this.scrollToBottom();
+      return;
+    }
+  }
+
+  getQuestion() {
+    this.messagesList.push({
+      role: "user",
+      content: "您需要扮演一名公司的技术总监Jack,并主持一场,技术岗位招聘的第二轮技术面试。\n" +
+        "您任职于大米科技,一家互联网智能手机公司,主要产品是性价比高的手机系列。\n" +
+        "当前招聘前端开发工程师,需要熟悉HTML,JS,CSS基础,会Angular前端框架的优先,具有nodejs使用经验的优先。\n" +
+        "您是比较负责且严谨的面试官,提问内容偏难。\n" +
+        "接下来,请您根据面试岗位招聘要求,分别从技术能力、团队协作、职业规划等方面想出一个个面试问题。\n" +
+        "每次只问一个问题,当用户回答:回答完毕时进行下一个问题,当完成了所有的三个问题之后请生成一份关于我面试的报告,其中包括我的每一个回答的得分,和回答的不足之处,以及可以改进的地方.您准备好了之后请回答我说:如果您现在准备好了,请回答开始面试我将开始这一次的面试"
+    })
+    this.completion.createCompletionByStream();
+  }
+
 }

+ 4 - 2
app-angular/src/modules/home/nav-menu/nav-menu.component.html

@@ -16,7 +16,6 @@
       <input type="file" accept="image/*" style="display: none" (change)="onFileChange($event)" #fileInput>
     </div>
 
-
     <ul nz-menu nzTheme="dark" nzMode="inline" [nzInlineCollapsed]="isCollapsed">
       <li nz-submenu nzOpen nzTitle="招聘推荐" nzIcon="home">
         <ul>
@@ -44,7 +43,10 @@
       <li nz-submenu nzOpen nzTitle="实操测试" nzIcon="tag">
         <ul>
           <li nz-menu-item nzMatchRouter>
-            <a routerLink="/home/minterviews">模拟面试</a>
+            <a routerLink="/home/minterviews">模拟面试_文字</a>
+          </li>
+          <li nz-menu-item nzMatchRouter>
+            <a routerLink="/home/minterviews">模拟面试_语音</a>
           </li>
           <li nz-menu-item nzMatchRouter>
             <a>分析报告</a>

+ 1 - 0
app-angular/src/modules/home/nav-menu/nav-menu.component.scss

@@ -74,6 +74,7 @@ nz-header {
 
 nz-content {
   margin: 24px;
+  overflow: auto;
 }
 
 //头像

+ 2 - 1
app-angular/src/modules/home/nav-menu/nav-menu.component.ts

@@ -42,7 +42,8 @@ export class NavMenuComponent {
     let appId = "0210490" // 以自己学号作为应用目录
     let dateStr = `${new Date().getFullYear()}${new Date().getMonth() + 1}${new Date().getDate()}`
     let hourStr = `${new Date().getHours()}${new Date().getMinutes() + 1}${new Date().getSeconds()}`
-    let key = `storage/web-2023/${appId}/${dateStr}/${hourStr}-${filename}`
+    let key = `storage/web-2023/${appId}/${dateStr}/${hourStr}-${filename}`;
+
     this.hwobs.uploadFile(this.file, key)
 
   }

+ 0 - 1
app-angular/src/modules/home/suit-companies-comp/suit-companies-comp.component.ts

@@ -2,7 +2,6 @@ import {Component, HostListener} from '@angular/core';
 import {NzMessageService} from "ng-zorro-antd/message";
 
 
-
 @Component({
   selector: 'app-suit-companies-comp',
   templateUrl: './suit-companies-comp.component.html',