feat(index): add homepage with dashboard cards and knowledge graph support
- Add new Index view with dashboard layout and quick action cards - Create TopCardList component to display core data management options - Add GuideCard and VersionCard components for user guidance - Add QuickActions component for common operations - Create KnowledgeGraph and KnowledgeGraphCard components for knowledge base visualization - Add comprehensive SVG assets for index page (apps, arrows, management icons) - Add common API module for shared request utilities - Extend knowledgeBase API with knowledge graph endpoints (getKnowledgeGraph, getKnowledgeGraphEntityTypes) - Update i18n translations for English and Chinese with new index page strings - Update routing configuration to include new Index route - Update menu configuration to reflect new navigation structure - Update KnowledgeBase CreateModal and Private view components - Add TypeScript types for Index page components - Improve overall UI/UX with new dashboard-style homepage
1
web/src/api/common.ts
Normal file
@@ -0,0 +1 @@
|
||||
import { request } from "@/utils/request";
|
||||
@@ -285,3 +285,14 @@ export const getRetrievalModeType = async () => {
|
||||
const response = await request.get(`${apiPrefix}/chunks/retrieve_type`);
|
||||
return response as any;
|
||||
};
|
||||
|
||||
// 获取知识库图谱
|
||||
export const getKnowledgeGraph = async (kb_id: string) => {
|
||||
const response = await request.get(`${apiPrefix}/knowledges/${kb_id}/knowledge_graph`);
|
||||
return response;
|
||||
};
|
||||
// 获取知识库图谱实体类型
|
||||
export const getKnowledgeGraphEntityTypes = async (query: any) => {
|
||||
const response = await request.get(`${apiPrefix}/knowledges/knowledge_graph_entity_types`,query);
|
||||
return response ;
|
||||
};
|
||||
18
web/src/assets/images/index/apps.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 34</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-1056, -232)">
|
||||
<g id="核心数据" transform="translate(256, 216)">
|
||||
<g id="编组-19备份-3" transform="translate(648, 0)">
|
||||
<g id="编组-34" transform="translate(152, 16)">
|
||||
<rect id="矩形" fill="#9C6FFF" x="0" y="0" width="32" height="32" rx="8"></rect>
|
||||
<g id="icon-GIS_运行管理" transform="translate(7, 8)" fill="#FFFFFF" fill-rule="nonzero">
|
||||
<path d="M7.16762406,14.1962904 C6.34809084,14.1646209 5.54326395,13.9741465 4.80020028,13.636004 C3.71131238,13.1260904 3.00897969,12.3104053 2.71316514,11.2234143 L2.87831314,11.2234143 C3.04376149,11.2238267 3.19695148,11.1385171 3.28050226,10.9994401 C3.36405304,10.8603631 3.3653563,10.6885064 3.28392388,10.5482427 L2.07888794,8.54040242 C1.99542259,8.40040876 1.84176478,8.31425552 1.67554571,8.31425552 C1.50932664,8.31425552 1.35566883,8.40040876 1.27220348,8.54040242 L0.0617231013,10.5500101 C-0.0210158141,10.6903056 -0.0205423886,10.8629501 0.0629647773,11.0028132 C0.146471943,11.1426763 0.300303569,11.2284717 0.466426438,11.227833 L0.804889093,11.227833 C1.23681463,13.5308399 2.77123916,14.6911806 3.98534917,15.2567694 C4.98325891,15.7122175 6.06611522,15.9645167 7.16762406,15.998225 C7.68009348,15.9996891 8.09703053,15.596793 8.09953973,15.0976976 C8.100628,14.8580057 8.00249628,14.627997 7.82730865,14.4596427 C7.65206093,14.2900046 7.4147074,14.1952508 7.16762406,14.1962904 L7.16762406,14.1962904 Z M17.9430772,5.00547242 C17.8606071,4.86230637 17.7051137,4.77374302 17.5365591,4.77393451 L17.1980964,4.77393451 C16.7661709,2.47092761 15.230839,1.31058684 14.0176364,0.742346841 C13.0197435,0.28685171 11.9368771,0.0345501233 10.8353615,0.000895273713 C10.4982732,-0.0093928287 10.18217,0.159876081 10.0105024,0.442595865 C9.83883478,0.725315649 9.83883478,1.076638 10.0105024,1.35935779 C10.18217,1.64207757 10.4982732,1.81134648 10.8353615,1.80105838 C11.6548676,1.83493183 12.4595539,2.02529996 13.2036927,2.36134478 C14.2925806,2.87214217 14.9949133,3.68694353 15.2907278,4.77393451 L15.1255798,4.77393451 C14.9574006,4.77106293 14.8007624,4.85694697 14.7160555,4.99847492 C14.6313487,5.14000288 14.6318043,5.3150681 14.7172468,5.456176 L15.9213754,7.46401624 C16.0048407,7.60400991 16.1584985,7.69016315 16.3247176,7.69016315 C16.4909367,7.69016315 16.6445945,7.60400991 16.7280598,7.46401624 L17.9303735,5.4588272 C18.018434,5.32105318 18.023291,5.14771891 17.9430772,5.00547242 L17.9430772,5.00547242 Z M16.1563937,7.99424995 L10.1375658,7.99424995 C9.50717772,7.99229725 8.99410285,8.48763753 8.99060389,9.10157256 L8.99060389,14.8926716 C8.99410285,15.5066067 9.50717772,16.0019469 10.1375658,15.9999942 L16.1563937,15.9999942 C16.7867818,16.0019469 17.2998566,15.5066067 17.3033556,14.8926716 L17.3033556,9.10157256 C17.2998566,8.48763753 16.7867818,7.99229725 16.1563937,7.99424995 L16.1563937,7.99424995 Z M15.4431721,9.79530257 L15.4431721,14.1962904 L10.854417,14.1962904 L10.854417,9.79530257 L15.4431721,9.79530257 Z M9.00058536,1.10732836 C8.99708639,0.493393328 8.48401152,-0.0019469461 7.85362344,5.75355807e-06 L1.83207335,5.75355807e-06 C1.20203901,-0.00145886726 0.689517223,0.493739212 0.686018831,1.10732836 L0.686018831,6.89842744 C0.686499539,7.19390032 0.807543503,7.47707233 1.02249671,7.68558868 C1.23744991,7.89410503 1.5286856,8.0108668 1.83207335,8.01018014 L7.85090122,8.01018014 C8.15491658,8.01180822 8.44708623,7.89546249 8.66282574,7.68684408 C8.87856526,7.47822567 9.00010748,7.1945153 9.00058536,6.89842744 L9.00058536,1.10732836 Z M7.13677223,1.80105838 L7.13677223,6.20558116 L2.54983195,6.20558116 L2.54983195,1.80105838 L7.13677223,1.80105838 Z" id="形状"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
17
web/src/assets/images/index/arrow_down.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>箭头_向上</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-928, -367)" fill="#FF5D34" fill-rule="nonzero">
|
||||
<g id="核心数据" transform="translate(256, 216)">
|
||||
<g id="编组-19备份-3" transform="translate(648, 0)">
|
||||
<g id="标签1" transform="translate(16, 148)">
|
||||
<g id="箭头_向上" transform="translate(15, 10) scale(1, -1) translate(-15, -10)translate(8, 3)">
|
||||
<polygon id="路径" points="7.58333789 4.21666211 7.58333789 12.4416621 6.41666211 12.4416621 6.41666211 4.21666211 4.60833789 6.025 3.79166211 5.20832422 7 2 10.2083379 5.20832422 9.39166211 6.025"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
18
web/src/assets/images/index/arrow_down_d.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 30</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||
<g id="首页" transform="translate(-1006, -326)" stroke="#FF5D34" stroke-width="1.2">
|
||||
<g id="核心数据" transform="translate(256, 216)">
|
||||
<g id="编组-19备份-3" transform="translate(648, 0)">
|
||||
<g id="编组-30" transform="translate(108, 116) scale(1, -1) translate(-108, -116)translate(102, 110)">
|
||||
<g id="编组-31" transform="translate(2.5, 2.5)">
|
||||
<polyline id="路径" points="0 3 3.5 0 7 3"></polyline>
|
||||
<polyline id="路径备份" points="0 7 3.5 4 7 7"></polyline>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
16
web/src/assets/images/index/arrow_right.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 5</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-1229, -446)" stroke="#212332">
|
||||
<g id="编组-13" transform="translate(1120, 300)">
|
||||
<g id="编组-6" transform="translate(16, 138)">
|
||||
<g id="编组-5" transform="translate(93, 8)">
|
||||
<polyline id="路径" points="10 6 12 8 10 10"></polyline>
|
||||
<line x1="12" y1="8" x2="2" y2="8" id="路径-2"></line>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 820 B |
16
web/src/assets/images/index/arrow_right_blue.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 5</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-1226, -244)" stroke="#155EEF">
|
||||
<g id="新手指引" transform="translate(1120, 80)">
|
||||
<g id="编组-6" transform="translate(16, 156)">
|
||||
<g id="编组-5" transform="translate(90, 8)">
|
||||
<polyline id="路径" points="10 6 12 8 10 10"></polyline>
|
||||
<line x1="12" y1="8" x2="2" y2="8" id="路径-2"></line>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 822 B |
17
web/src/assets/images/index/arrow_up.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>箭头_向上</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-712, -367)" fill="#369F21" fill-rule="nonzero">
|
||||
<g id="核心数据" transform="translate(256, 216)">
|
||||
<g id="编组-19备份-2" transform="translate(432, 0)">
|
||||
<g id="标签1" transform="translate(16, 148)">
|
||||
<g id="箭头_向上" transform="translate(8, 3)">
|
||||
<polygon id="路径" points="7.58333789 4.21666211 7.58333789 12.4416621 6.41666211 12.4416621 6.41666211 4.21666211 4.60833789 6.025 3.79166211 5.20832422 7 2 10.2083379 5.20832422 9.39166211 6.025"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
18
web/src/assets/images/index/arrow_up_d.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 30</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||
<g id="首页" transform="translate(-488, -326)" stroke="#369F21" stroke-width="1.2">
|
||||
<g id="核心数据" transform="translate(256, 216)">
|
||||
<g id="编组-19备份" transform="translate(216, 0)">
|
||||
<g id="编组-30" transform="translate(16, 110)">
|
||||
<g id="编组-31" transform="translate(2.5, 2.5)">
|
||||
<polyline id="路径" points="0 3 3.5 0 7 3"></polyline>
|
||||
<polyline id="路径备份" points="0 7 3.5 4 7 7"></polyline>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1013 B |
22
web/src/assets/images/index/data_export.svg
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 23</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-1252, -664)">
|
||||
<g id="快捷操作" transform="translate(1120, 502)">
|
||||
<g id="编组-11" transform="translate(2, 38)">
|
||||
<g id="编组-23" transform="translate(130, 124)">
|
||||
<rect id="矩形" stroke="#DFE4ED" fill="#FFFFFF" x="0.5" y="0.5" width="39" height="39" rx="8"></rect>
|
||||
<g id="编组-12" transform="translate(11.5, 11)" stroke="#212332" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.7">
|
||||
<path d="M17,7.30064813 L17,14 C17,15.6568542 15.6568542,17 14,17 L3,17 C1.34314575,17 8.8817842e-16,15.6568542 8.8817842e-16,14 L-4.4408921e-16,5.42857143 C-4.4408921e-16,3.77171718 1.34314575,2.42857143 3,2.42857143 L12.7248521,2.42857143 L12.7248521,2.42857143" id="路径"></path>
|
||||
<polyline id="路径" points="10.9285714 0 13.3571429 2.42857143 10.9285714 4.85714286"></polyline>
|
||||
<line x1="4.86821714" y1="9.71428571" x2="4.86821714" y2="13.3571429" id="路径-13"></line>
|
||||
<line x1="12.1428571" y1="9.71428571" x2="12.1428571" y2="13.3571429" id="路径-13"></line>
|
||||
<line x1="8.51107429" y1="7.29747399" x2="8.51107429" y2="13.3689026" id="路径-13备份"></line>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
BIN
web/src/assets/images/index/guide_bg@2x.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
21
web/src/assets/images/index/help_center.svg
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 17</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-1252, -772)">
|
||||
<g id="快捷操作" transform="translate(1120, 502)">
|
||||
<g id="编组-11" transform="translate(2, 38)">
|
||||
<g id="编组-17" transform="translate(130, 232)">
|
||||
<rect id="矩形" stroke="#DFE4ED" fill="#FFFFFF" x="0.5" y="0.5" width="39" height="39" rx="8"></rect>
|
||||
<g id="使用帮助" transform="translate(8, 8)" stroke="#212332" stroke-width="1.7">
|
||||
<g id="编组-16" transform="translate(2.7, 1.2)">
|
||||
<rect id="矩形" x="0" y="3.20000312" width="18.6000182" height="16.2000158" rx="3.5"></rect>
|
||||
<path d="M6.43068654,1.74093758 L9.44000922,3.20000313 L9.44000922,3.20000313 L9.44000922,19.2000188 L4.24931901,16.6833205 C3.38736738,16.2654045 2.84000277,15.3917071 2.84000277,14.4337852 L2.84000277,3.99047285 C2.84000277,2.60976098 3.9592909,1.49047285 5.34000277,1.49047285 C5.71781927,1.49047285 6.09072193,1.57610626 6.43068654,1.74093758 Z" id="矩形" fill="#FFFFFF" stroke-linejoin="round"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
BIN
web/src/assets/images/index/index_bg@2x.png
Normal file
|
After Width: | Height: | Size: 359 KiB |
22
web/src/assets/images/index/log_mgt.svg
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 21</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-1352, -664)">
|
||||
<g id="快捷操作" transform="translate(1120, 502)">
|
||||
<g id="编组-11" transform="translate(2, 38)">
|
||||
<g id="编组-21" transform="translate(230, 124)">
|
||||
<rect id="矩形" stroke="#DFE4ED" fill="#FFFFFF" x="0.5" y="0.5" width="39" height="39" rx="8"></rect>
|
||||
<g id="编组-15" transform="translate(12, 11)" stroke="#212332" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.7">
|
||||
<path d="M6.98059242,17 L2,17 C0.8954305,17 -8.8817842e-16,16.1045695 -8.8817842e-16,15 L0,2 C0,0.8954305 0.8954305,2.22044605e-16 2,0 L14,0 C15.1045695,0 16,0.8954305 16,2 L16,6.06912749 L16,6.06912749" id="路径"></path>
|
||||
<line x1="3" y1="4.5" x2="12.8160264" y2="4.5" id="路径-17"></line>
|
||||
<line x1="3" y1="10.0001" x2="6.37326888" y2="10.0001" id="路径-18"></line>
|
||||
<circle id="椭圆形" cx="13" cy="13" r="4"></circle>
|
||||
<line x1="16" y1="16" x2="18" y2="18" id="路径-20"></line>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
30
web/src/assets/images/index/model_mgt.svg
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 25</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-1152, -556)">
|
||||
<g id="快捷操作" transform="translate(1120, 502)">
|
||||
<g id="编组-11" transform="translate(2, 38)">
|
||||
<g id="编组-25" transform="translate(30, 16)">
|
||||
<rect id="矩形" stroke="#DFE4ED" fill="#FFFFFF" x="0.5" y="0.5" width="39" height="39" rx="8"></rect>
|
||||
<g id="模型管理" transform="translate(9, 9)">
|
||||
<rect id="矩形" stroke="#212332" stroke-width="1.7" stroke-linejoin="round" x="2.2" y="7.7" width="12.1" height="12.1"></rect>
|
||||
<polygon id="矩形" stroke="#212332" stroke-width="1.7" stroke-linejoin="round" points="7.7 2.2 19.8 2.2 14.3 7.7 2.2 7.7"></polygon>
|
||||
<polygon id="矩形" stroke="#212332" stroke-width="1.7" stroke-linejoin="round" points="7.7 14.3 19.8 14.3 14.3 19.8 2.2 19.8"></polygon>
|
||||
<polygon id="矩形备份-9" stroke="#212332" stroke-width="1.7" stroke-linejoin="round" points="14.3 7.7 19.8 2.2 19.8 14.3 14.3 19.8"></polygon>
|
||||
<line x1="7.7" y1="2.2" x2="7.7" y2="14.3" id="路径-10" stroke="#212332" stroke-width="1.7"></line>
|
||||
<path d="M7.7,4.4 C8.91502645,4.4 9.9,3.41502645 9.9,2.2 C9.9,0.98497355 8.91502645,0 7.7,0 C6.48497355,0 5.5,0.98497355 5.5,2.2 C5.5,3.41502645 6.48497355,4.4 7.7,4.4 Z" id="椭圆形" fill="#212332"></path>
|
||||
<path d="M8.25899503,16.5 C9.47402148,16.5 10.458995,15.5150264 10.458995,14.3 C10.458995,13.0849736 9.47402148,12.1 8.25899503,12.1 C7.04396858,12.1 6.05899503,13.0849736 6.05899503,14.3 C6.05899503,15.5150264 7.04396858,16.5 8.25899503,16.5 Z" id="椭圆形" fill="#212332"></path>
|
||||
<path d="M2.2,9.9 C3.41502645,9.9 4.4,8.91502645 4.4,7.7 C4.4,6.48497355 3.41502645,5.5 2.2,5.5 C0.98497355,5.5 0,6.48497355 0,7.7 C0,8.91502645 0.98497355,9.9 2.2,9.9 Z" id="椭圆形备份-2" fill="#212332"></path>
|
||||
<path d="M2.2,22 C3.41502645,22 4.4,21.0150264 4.4,19.8 C4.4,18.5849736 3.41502645,17.6 2.2,17.6 C0.98497355,17.6 0,18.5849736 0,19.8 C0,21.0150264 0.98497355,22 2.2,22 Z" id="椭圆形备份-3" fill="#212332"></path>
|
||||
<path d="M19.8,4.4 C21.0150264,4.4 22,3.41502645 22,2.2 C22,0.98497355 21.0150264,0 19.8,0 C18.5849736,0 17.6,0.98497355 17.6,2.2 C17.6,3.41502645 18.5849736,4.4 19.8,4.4 Z" id="椭圆形" fill="#212332"></path>
|
||||
<path d="M19.8,16.5 C21.0150264,16.5 22,15.5150264 22,14.3 C22,13.0849736 21.0150264,12.1 19.8,12.1 C18.5849736,12.1 17.6,13.0849736 17.6,14.3 C17.6,15.5150264 18.5849736,16.5 19.8,16.5 Z" id="椭圆形" fill="#212332"></path>
|
||||
<path d="M14.3,9.9 C15.5150264,9.9 16.5,8.91502645 16.5,7.7 C16.5,6.48497355 15.5150264,5.5 14.3,5.5 C13.0849736,5.5 12.1,6.48497355 12.1,7.7 C12.1,8.91502645 13.0849736,9.9 14.3,9.9 Z" id="椭圆形备份-2" fill="#212332"></path>
|
||||
<path d="M14.3,22 C15.5150264,22 16.5,21.0150264 16.5,19.8 C16.5,18.5849736 15.5150264,17.6 14.3,17.6 C13.0849736,17.6 12.1,18.5849736 12.1,19.8 C12.1,21.0150264 13.0849736,22 14.3,22 Z" id="椭圆形备份-3" fill="#212332"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
19
web/src/assets/images/index/models.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 14</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-408, -232)">
|
||||
<g id="核心数据" transform="translate(256, 216)">
|
||||
<g id="编组-14" transform="translate(152, 16)">
|
||||
<rect id="矩形" fill="#155EEF" x="0" y="0" width="32" height="32" rx="8"></rect>
|
||||
<g id="模型管理" transform="translate(8, 7)" fill="#FFFFFF" fill-rule="nonzero">
|
||||
<polygon id="路径" points="7.4583178 17.9990012 0 13.715998 0 4.56667222 7.9512983 0 15.9025966 4.56567338 15.9025966 11.1380057 13.914772 11.1380057 13.914772 5.72631929 7.9512983 2.30131513 1.98782457 5.72731813 1.98782457 12.5573498 8.44427879 16.266023 7.4583178 18"></polygon>
|
||||
<polygon id="路径" points="14.6105106 3.99533877 15.6044229 5.72631929 8.37371102 9.921425 8.33594235 9.98634926 0.993912287 5.72631929 1.98782457 3.99533877 8.2991676 7.65606792"></polygon>
|
||||
<polygon id="路径" points="7.2555597 11.9860163 9.24338427 12.984851 9.24338427 8.98951224 7.2555597 8.98951224 7.2555597 11.9860163"></polygon>
|
||||
<polygon id="路径" points="14.5091316 12.4854337 16 15.0804062 14.5091316 17.6753787 11.5273947 17.6753787 10.0365263 15.0804062 11.5273947 12.4854337"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
21
web/src/assets/images/index/note_mgt.svg
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 20</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-1152, -772)">
|
||||
<g id="快捷操作" transform="translate(1120, 502)">
|
||||
<g id="编组-11" transform="translate(2, 38)">
|
||||
<g id="编组-20" transform="translate(30, 232)">
|
||||
<rect id="矩形" stroke="#DFE4ED" fill="#FFFFFF" x="0.5" y="0.5" width="39" height="39" rx="8"></rect>
|
||||
<g id="消息提醒" transform="translate(12, 11)" stroke="#212332" stroke-width="1.7">
|
||||
<path d="M2,14.0377426 L2,7.71071968 C2,4.39701118 4.6862915,1.71071968 8,1.71071968 C11.3137085,1.71071968 14,4.39701118 14,7.71071968 L14,14.0377426 L14,14.0377426" id="路径"></path>
|
||||
<line x1="1.08244944e-14" y1="14.5" x2="16" y2="14.5" id="路径-14" stroke-linecap="round" stroke-linejoin="round"></line>
|
||||
<line x1="8" y1="-5.46307465e-14" x2="8" y2="1.43460647" id="路径-15" stroke-linecap="round" stroke-linejoin="round"></line>
|
||||
<line x1="6.5" y1="17.5" x2="9.5" y2="17.5" id="路径-16" stroke-linecap="round" stroke-linejoin="round"></line>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
20
web/src/assets/images/index/space_mgt.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 26</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-1254, -556)">
|
||||
<g id="快捷操作" transform="translate(1120, 502)">
|
||||
<g id="编组-11" transform="translate(2, 38)">
|
||||
<g id="编组-26" transform="translate(132, 16)">
|
||||
<rect id="矩形" stroke="#DFE4ED" fill="#FFFFFF" x="0.5" y="0.5" width="39" height="39" rx="8"></rect>
|
||||
<g id="空间管理" transform="translate(11, 10)" stroke="#212332" stroke-linejoin="round" stroke-width="1.7">
|
||||
<polygon id="路径" points="0 5 9 0 18 5 18 15 9 20 0 15"></polygon>
|
||||
<polygon id="路径-8" points="9.00139153 1 1 15 17 15"></polygon>
|
||||
<polygon id="路径-8" transform="translate(9, 11) scale(1, -1) translate(-9, -11)" points="9.00065228 8 5.25 14 12.75 14"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
26
web/src/assets/images/index/spaces.svg
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 32</title>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="96.5083812%" id="linearGradient-1">
|
||||
<stop stop-color="#369F21" offset="0%"></stop>
|
||||
<stop stop-color="#369F21" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-624, -232)">
|
||||
<g id="核心数据" transform="translate(256, 216)">
|
||||
<g id="编组-19备份" transform="translate(216, 0)">
|
||||
<g id="编组-32" transform="translate(152, 16)">
|
||||
<rect id="矩形" fill="url(#linearGradient-1)" x="0" y="0" width="32" height="32" rx="8"></rect>
|
||||
<g id="空间-(1)" transform="translate(5, 7)" fill="#FFFFFF" fill-rule="nonzero">
|
||||
<path d="M21.8430883,4.38834951 C21.4863174,3.55339806 20.6408194,3.19174757 19.9932559,3.03640777 C19.3676851,2.88592233 18.5954962,2.83495146 17.6937946,2.8907767 C17.6131546,2.80582524 17.5325146,2.72087379 17.449431,2.63834951 C16.6185948,1.8131068 15.6484713,1.16262136 14.5683843,0.708737864 C13.4516427,0.240291262 12.2640357,0 11.0397741,0 C9.81795616,0 8.63034912,0.237864078 7.51116389,0.708737864 C6.43107684,1.16262136 5.46339703,1.81067961 4.6301172,2.63834951 C3.79683737,3.46601942 3.14438659,4.42718447 2.68742668,5.5 C2.21580496,6.6092233 1.973885,7.78883495 1.973885,9.00485437 C1.973885,9.1723301 1.97877228,9.33737864 1.98854682,9.50242718 C1.30188514,10.1237864 0.788721607,10.723301 0.456387128,11.288835 C0.121609013,11.8592233 -0.200950922,12.7135922 0.155819916,13.5485437 C0.519921661,14.4004854 1.39718694,14.7621359 2.06674317,14.9150485 C2.51637217,15.0169903 3.03686661,15.0679612 3.62333922,15.0679612 C3.84571008,15.0679612 4.07785549,15.0606796 4.31977544,15.0461165 C4.46150632,15.2014563 4.60812448,15.3519417 4.7596299,15.4975728 C5.02354257,15.7475728 5.3045607,15.9854369 5.59535337,16.2038835 C7.18371668,17.3786408 9.06531631,18 11.0446614,18 C12.2664793,18 13.4540863,17.7621359 14.5732716,17.2912621 C15.6533586,16.8373786 16.6210384,16.1893204 17.4543183,15.3616505 C18.2851545,14.5364078 18.9400489,13.5728155 19.3970088,12.5 C19.8686305,11.3907767 20.1105505,10.211165 20.1105505,8.99514563 C20.1105505,8.78398058 20.1032195,8.57038835 20.0885577,8.36165049 C20.7165721,7.78398058 21.1955248,7.22572816 21.5131974,6.69660194 C21.865081,6.11650485 22.2096337,5.24029126 21.8430883,4.38834951 Z M5.88125876,3.87135922 C7.2594694,2.50242718 9.09463994,1.74757282 11.0446614,1.74757282 C12.9946828,1.74757282 14.8298533,2.50242718 16.208064,3.87135922 C17.261271,4.91747573 17.9552636,6.23058252 18.2216199,7.65533981 C16.6503621,8.91504854 14.4437589,10.1747573 11.9683557,11.2208738 C9.51494531,12.2572816 7.09330216,12.9587379 5.09929529,13.2135922 C4.92824077,12.9781553 4.77429171,12.7305825 4.63256083,12.4781553 C4.56169539,12.3470874 4.49082995,12.2135922 4.42729542,12.0776699 C4.40285906,12.0242718 4.37597907,11.9684466 4.35154271,11.9150485 C3.94345552,10.9951456 3.7381901,10.0145631 3.7381901,9 C3.74307738,7.0631068 4.50304813,5.24271845 5.88125876,3.87135922 Z M1.78328141,12.8616505 C1.7417396,12.7645631 1.77350686,12.5291262 1.98610318,12.1650485 C2.08629225,11.9951456 2.21580496,11.8131068 2.37464129,11.6237864 C2.47727399,11.961165 2.60189942,12.2936893 2.74607394,12.618932 C2.77539757,12.6868932 2.80716484,12.7548544 2.8389321,12.8228155 C2.91468482,12.9830097 2.9953248,13.1432039 3.08085205,13.2985437 C2.17670678,13.2257282 1.83459776,12.9805825 1.78328141,12.8616505 L1.78328141,12.8616505 Z M16.208064,14.1286408 C14.8298533,15.5 12.9946828,16.2524272 11.0446614,16.2524272 C9.44896714,16.2524272 7.9339129,15.75 6.66322224,14.8009709 C6.63634225,14.7815534 6.60946225,14.7597087 6.58258226,14.7402913 C8.44952007,14.3762136 10.5510469,13.7160194 12.657461,12.8276699 C14.7858679,11.9296117 16.7383329,10.8713592 18.3047035,9.77669903 C18.1312054,11.4223301 17.4005583,12.9441748 16.208064,14.1286408 L16.208064,14.1286408 Z M19.6780269,6.25728155 C19.5949433,6 19.4996415,5.74757282 19.3945651,5.49757282 C19.2699397,5.2038835 19.1282088,4.91747573 18.9742598,4.63834951 C19.1990743,4.65776699 19.401896,4.68932039 19.5802815,4.73300971 C19.9932559,4.83252427 20.1838595,4.97330097 20.227845,5.07281553 C20.2742741,5.1868932 20.2180704,5.58737864 19.6780269,6.25728155 L19.6780269,6.25728155 Z" id="形状"></path>
|
||||
<path d="M6.83916403,8.87135922 C7.18127305,9.06796117 7.56981115,9.16504854 7.9681238,9.16504854 C8.28579646,9.16504854 8.61324367,9.10194175 8.9284727,8.97815534 C9.58092348,8.7184466 10.1502906,8.21601942 10.5290542,7.5631068 C10.9078178,6.91019417 11.0617668,6.16990291 10.9615777,5.47815534 C10.8516141,4.72087379 10.436196,4.08495146 9.82284343,3.73300971 C9.20949082,3.38106796 8.44707643,3.34223301 7.73109112,3.62621359 C7.07864034,3.88592233 6.50927318,4.38834951 6.13050962,5.04126214 C5.75174606,5.69417476 5.597797,6.43446602 5.69798607,7.12621359 C5.81039332,7.88349515 6.22581142,8.51941748 6.83916403,8.87135922 Z M7.65533841,5.91504854 C7.83616746,5.60436893 8.10252377,5.36165049 8.38598553,5.25 C8.51061096,5.20145631 8.74764364,5.13349515 8.94557815,5.24757282 C9.14106902,5.3592233 9.20460355,5.59708738 9.221709,5.73058252 C9.26569445,6.0315534 9.1874981,6.38106796 9.00666905,6.69174757 C8.82583999,7.00242718 8.55948368,7.24514563 8.27602192,7.35679612 C8.15139649,7.40533981 7.91436381,7.47330097 7.71642931,7.3592233 C7.39875664,7.17475728 7.2936803,6.53640777 7.65533841,5.91504854 Z" id="形状"></path>
|
||||
<path d="M14.3929157,5.78130192 C14.6699504,6.12865804 15.0730899,6.3338495 15.4504584,6.31957402 C15.8278269,6.30529853 16.1220856,6.07372518 16.2223777,5.71209515 C16.3226697,5.35046513 16.2137563,4.91372597 15.9366687,4.56641148 C15.659634,4.21905536 15.2564945,4.0138639 14.879126,4.02813938 C14.5017575,4.04241487 14.2074988,4.27398822 14.1072067,4.63561824 C14.0069147,4.99724827 14.1158281,5.43398743 14.3929157,5.78130192 L14.3929157,5.78130192 Z" id="路径"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.3 KiB |
22
web/src/assets/images/index/user_mgt.svg
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 24</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-1152, -664)">
|
||||
<g id="快捷操作" transform="translate(1120, 502)">
|
||||
<g id="编组-11" transform="translate(2, 38)">
|
||||
<g id="编组-24" transform="translate(30, 124)">
|
||||
<rect id="矩形" stroke="#DFE4ED" fill="#FFFFFF" x="0.5" y="0.5" width="39" height="39" rx="8"></rect>
|
||||
<g id="用户管理" transform="translate(9, 10)" stroke="#212332" stroke-width="1.7">
|
||||
<path d="M10.4752216,9.8347602 C12.0826337,9.8347602 13.5411901,10.4629457 14.5971671,11.4807313 C15.6415902,12.4873807 16.2916977,13.8763311 16.2916977,15.41013 L16.2916987,17.2469287 C16.292495,17.768016 16.0699552,18.2385306 15.715897,18.5800613 C15.3496472,18.9333521 14.8431448,19.15 14.2862956,19.15 L2.85772417,19.15 C2.30025073,19.15 1.79383233,18.9336648 1.42754075,18.5806207 C1.07279965,18.2387094 0.85,17.7674542 0.85,17.2456298 L0.85,15.41013 C0.85,13.8763309 1.50010692,12.4873802 2.54452956,11.4807307 C3.60050579,10.4629455 5.05906118,9.8347602 6.6664729,9.8347602 Z" id="路径" fill-rule="nonzero"></path>
|
||||
<path d="M8.51095419,0.85 C9.31202689,0.85 10.0374296,1.17449643 10.5625442,1.69913767 C11.0873448,2.22346508 11.4120985,2.94775006 11.4120985,3.74776253 C11.4120985,4.54882217 11.0868662,5.27413048 10.5618329,5.79931671 C10.0365783,6.32472447 9.31123944,6.65 8.51095419,6.65 C7.71104886,6.65 6.98645948,6.32499629 6.46178132,5.80015797 C5.93701763,5.27523409 5.61209853,4.5502916 5.61209853,3.75 C5.61209853,2.94883778 5.93633819,2.22374798 6.46093583,1.69899021 C6.98544108,1.17432485 7.71016945,0.85 8.51095419,0.85 Z" id="路径" fill-rule="nonzero"></path>
|
||||
<path d="M16.5,8 C17.8807119,8 19,6.88071187 19,5.5 C19,4.11928813 17.8807119,3 16.5,3" id="路径" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M18,11 C20.209139,11 22,12.790861 22,15 L22,16 C22,16.5522847 21.5522847,17 21,17 L20.4553443,17 L20.4553443,17" id="路径" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<line x1="8.57084884" y1="13.4113022" x2="8.57084884" y2="15.9113022" id="路径-21" stroke-linecap="round" stroke-linejoin="round"></line>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
18
web/src/assets/images/index/users.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 33</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-840, -232)">
|
||||
<g id="核心数据" transform="translate(256, 216)">
|
||||
<g id="编组-19备份-2" transform="translate(432, 0)">
|
||||
<g id="编组-33" transform="translate(152, 16)">
|
||||
<rect id="矩形" fill="#4DA8FF" x="0" y="0" width="32" height="32" rx="8"></rect>
|
||||
<g id="用户总数总计" transform="translate(6, 8)" fill="#FFFFFF" fill-rule="nonzero">
|
||||
<path d="M9.5,8.845 C10.9,7.95 11.9,6.45999999 11.9,4.77 C11.9,2.087 9.69999999,0 7,0 C4.30000001,0 2,2.087 2,4.77 C2,6.56 3,8.05 4.4,8.845 C1.8,9.839 0,12.224 0,15.105 C0,15.602 0.4,15.901 0.8,15.901 C1.2,15.901 1.6,15.503 1.6,15.106 C1.6,12.224 4,9.93799999 6.89999999,9.93799999 C9.79999998,9.93799999 12.2,12.224 12.2,15.106 C12.2,15.602 12.6,15.901 13,15.901 C13.4,15.901 13.8,15.503 13.8,15.106 C13.9,12.323 12,9.83899998 9.5,8.845 Z M6.89999999,7.95 C5.09999999,7.95 3.69999999,6.559 3.69999999,4.77 C3.69999999,2.98099999 5.19999999,1.59 6.89999999,1.59 C8.69999999,1.59 10.1,2.98100001 10.1,4.77 C10.1,6.559 8.69999999,7.95 6.89999999,7.95 Z M18.4,6.957 C18.4,4.77 16.6,2.98099999 14.4,2.98099999 C14,2.98099999 13.2,3.09957886 12.8,3.37899999 C12.5,3.57799999 12.3,3.87599999 12.3,4.17399999 C12.3,4.67099999 12.7,5.06799999 13.2,5.068 C13.4302275,5.068 13.6352352,4.87 14.2,4.87 C15.5,4.87 16.5,5.86300001 16.5,7.05599999 C16.5,8.34799999 15.5,9.34199999 14.3,9.34199999 C13.7,9.34199999 13.3,9.73899999 13.3,10.335 C13.3,10.832 13.8,11.329 14.3,11.329 L14.4,11.329 C16.5,11.329 18.2,13.019 18.2,15.106 C18.2,15.602 18.6,16 19.1,16 C19.6,16 20,15.602 20,15.106 C20,12.919 18.8,10.932 16.8,10.136 C17.8,9.34199999 18.4,8.14899999 18.4,6.957 Z" id="形状"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
21
web/src/assets/images/index/workflow_mgt.svg
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 29</title>
|
||||
<g id="V1.1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页" transform="translate(-1354, -556)">
|
||||
<g id="快捷操作" transform="translate(1120, 502)">
|
||||
<g id="编组-11" transform="translate(2, 38)">
|
||||
<g id="编组-29" transform="translate(232, 16)">
|
||||
<rect id="矩形" stroke="#DFE4ED" fill="#FFFFFF" x="0.5" y="0.5" width="39" height="39" rx="8"></rect>
|
||||
<g id="编组-9" transform="translate(11.5, 11.5)">
|
||||
<rect id="矩形" stroke="#212332" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" x="4.53333333" y="0" width="11.9" height="3.96666667" rx="0.4"></rect>
|
||||
<path d="M13.0448746,15.0166667 L16.6,15.0166667 C16.8209139,15.0166667 17,14.8375806 17,14.6166667 L17,8.9 C17,8.6790861 16.8209139,8.5 16.6,8.5 L0.4,8.5 C0.1790861,8.5 3.88578059e-16,8.3209139 3.88578059e-16,8.1 L0,2.38333333 C0,2.16241943 0.1790861,1.98333333 0.4,1.98333333 L4.55122349,1.98333333 L4.55122349,1.98333333" id="路径" stroke="#212332" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<rect id="矩形" stroke="#212332" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" x="1.13333333" y="13.0333333" width="11.9" height="3.96666667" rx="0.4"></rect>
|
||||
<path d="M8.78082738,6.23284271 L10.765142,8.21715729 C10.9213517,8.373367 10.9213517,8.626633 10.765142,8.78284271 L8.78082738,10.7671573 C8.62461766,10.923367 8.37135167,10.923367 8.21514196,10.7671573 L6.23082738,8.78284271 C6.07461766,8.626633 6.07461766,8.373367 6.23082738,8.21715729 L8.21514196,6.23284271 C8.37135167,6.076633 8.62461766,6.076633 8.78082738,6.23284271 Z" id="多边形" fill="#212332"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -3,6 +3,58 @@ export const en = {
|
||||
welcome: 'Welcome to React Font CLI',
|
||||
title: 'Memory Bear.AI ',
|
||||
memoryBear: 'Memory Bear.AI',
|
||||
index:{
|
||||
viewGuide: 'View Guide',
|
||||
watchVideo: 'Watch Video',
|
||||
viewDetails: 'View Details',
|
||||
changeLog: 'Change Log',
|
||||
latestUpdate: 'Latest Update',
|
||||
latestUpdateDesc: 'Version v0.2.0 release: Added visual workflow editor, model performance monitoring panel, and multi tenant permission management system.',
|
||||
getStarted: 'Getting Started',
|
||||
startedDesc: 'Understand the core functions of the platform and quickly get started through graphic guidance and video tutorials. Includes a full process demonstration from creating a space to publishing an application.',
|
||||
spaceTitle:'Memory Bear Intelligent Space Management Platform',
|
||||
spaceSubTitle: 'Making it easier to implement intelligent models - a one-stop platform for model management, knowledge building, workflow orchestration, and spatial operations',
|
||||
},
|
||||
quickActions:{
|
||||
title: 'Quick Actions',
|
||||
spaceManagement: 'Space Management',
|
||||
modelManagement: 'Model Management',
|
||||
workflowOrchestration: 'Workflow Orchestration',
|
||||
userManagement: 'User Management',
|
||||
dataExport: 'Data Export',
|
||||
logQuery:'Log Query',
|
||||
notificationReminder: 'Notification Reminder',
|
||||
helpCenter: 'Help Center',
|
||||
knowledgeBase: 'Knowledge Base',
|
||||
knowledgeBaseDesc: 'Manage and maintain your knowledge base data',
|
||||
modelManagementDesc: 'Configure and optimize AI model parameters',
|
||||
userManagementDesc: 'Manage system users and permission settings',
|
||||
systemSettings: 'System Settings',
|
||||
systemSettingsDesc: 'Configure global system parameters and options',
|
||||
memoryManagement: 'Memory Management',
|
||||
memoryManagementDesc: 'Manage user memories and conversation history',
|
||||
apiManagement: 'API Management',
|
||||
apiManagementDesc: 'Manage API keys and interface configurations',
|
||||
workflowEngine: 'Workflow Engine',
|
||||
workflowEngineDesc: 'Design and manage automated workflows',
|
||||
performanceMonitor: 'Performance Monitor',
|
||||
performanceMonitorDesc: 'Monitor system performance and operational status',
|
||||
},
|
||||
guide: {
|
||||
quickStart: 'Quick Start',
|
||||
createKnowledge: 'Create Knowledge Base',
|
||||
createKnowledgeDesc: 'Build your exclusive knowledge base to help AI better understand your business',
|
||||
manageModel: 'Manage Models',
|
||||
manageModelDesc: 'Configure and manage your AI models to optimize performance',
|
||||
createSpace: 'Create Space',
|
||||
createSpaceDesc: 'Create new workspaces to organize your projects and teams',
|
||||
systemConfig: 'System Configuration',
|
||||
systemConfigDesc: 'Configure system parameters to personalize your experience',
|
||||
startCreate: 'Start Creating',
|
||||
goManage: 'Go Manage',
|
||||
createNow: 'Create Now',
|
||||
goConfig: 'Go Configure',
|
||||
},
|
||||
menu: {
|
||||
home: 'Home',
|
||||
tenantManagement: 'Tenant Management',
|
||||
@@ -40,12 +92,22 @@ export const en = {
|
||||
selfReflectionEngine: 'Self Reflection Engine',
|
||||
},
|
||||
dashboard: {
|
||||
total_models: 'Total number of available models',
|
||||
total_spaces: 'Number of active spaces',
|
||||
total_users: 'Total number of users',
|
||||
total_apps_runs: 'Number of application runs',
|
||||
desc_models: 'Contains {{ account }} LLMs and {{ nums }} Embeddings',
|
||||
desc_spaces: 'more than yesterday',
|
||||
desc_users: 'New additions this week',
|
||||
desc_apps_runs: "Today's success rate",
|
||||
totalMemoryCapacity: 'Total Memory Capacity',
|
||||
userMemory: 'User Memory',
|
||||
knowledgeBaseCount: 'Knowledge Base Count',
|
||||
apiCallCount: 'API Call Count',
|
||||
comparedToYesterday: 'compared to yesterday',
|
||||
thisWeek: 'this week',
|
||||
thisDay: 'day on day',
|
||||
failureRate: 'Failure Rate',
|
||||
application: 'Application Count',
|
||||
total_num: 'Total Memory Capacity',
|
||||
|
||||
@@ -625,6 +687,37 @@ export const en = {
|
||||
fileDurationExceeds: 'File duration exceeds the limit',
|
||||
fileDurationLimitError: 'The duration of the media file exceeds the limit. The maximum supported duration is 150 seconds. Current duration',
|
||||
unableReadFile:'Unable to read the information of the media file. Please check the file format.',
|
||||
// Knowledge Graph related
|
||||
knowledgeGraph: 'Knowledge Graph',
|
||||
basicConfig: 'Basic Configuration',
|
||||
enableKnowledgeGraph: 'Enable Knowledge Graph',
|
||||
enableKnowledgeGraphTips: 'Once activated, it will automatically construct an entity relationship network.',
|
||||
graphConfig: 'Graph Configuration',
|
||||
sceneName: 'Scene Name',
|
||||
sceneNamePlaceholder: 'Please enter scene name',
|
||||
entityTypes: 'Entity Types',
|
||||
entityTypesPlaceholder: 'Please enter entity types, separate multiple types with line breaks',
|
||||
entityNormalization: 'Entity Normalization',
|
||||
entityNormalizationTips: 'Merge similar entities when enabled',
|
||||
entityMethod: 'Entity Method',
|
||||
entityMethodGeneral: 'General',
|
||||
entityMethodLight: 'Light',
|
||||
communityReportGeneration: 'Community Report Generation',
|
||||
communityReportGenerationTips: 'Generate community analysis reports when enabled',
|
||||
generateEntityTypes: 'Generate Entity Types',
|
||||
regenerateEntityTypes: 'Regenerate',
|
||||
generateEntityTypesSuccess: 'Entity types generated successfully',
|
||||
generateEntityTypesFailed: 'Failed to generate entity types',
|
||||
unknownError: 'Unknown error',
|
||||
pleaseSelectLLMModel: 'Please select a LLM model in basic configuration first',
|
||||
enterScenarioName: 'Please enter scenario name',
|
||||
entityDetails: 'Entity Details',
|
||||
entityDetailEmpty: 'Click on a node in the graph to view details',
|
||||
entityDetailEmptyDesc: 'Select an entity node to view its detailed information',
|
||||
entityDescription: 'Entity Description',
|
||||
graphTitle: 'Knowledge Graph: The Network of Entity, Relationship and Attribute Associations',
|
||||
graphTips: 'Explore the entity nodes in the knowledge base and their relationship networks',
|
||||
sourceDocuments: 'Source Documents',
|
||||
createForm:{
|
||||
name: 'Name',
|
||||
embedding_id: 'Embedding',
|
||||
|
||||
@@ -3,6 +3,58 @@ export const zh = {
|
||||
title: '记忆熊',
|
||||
memoryBear: '记忆熊',
|
||||
welcome: '欢迎使用 React Font CLI',
|
||||
index:{
|
||||
viewGuide: '查看引导',
|
||||
watchVideo: '观看视频',
|
||||
viewDetails: '查看详情',
|
||||
changeLog: '变更日志',
|
||||
getStarted:'快速开始',
|
||||
latestUpdate: '最新更新',
|
||||
latestUpdateDesc: '版本 v0.2.0 发布:新增了可视化工作流编辑器、模型性能监控面板以及多租户权限管理系统。',
|
||||
startedDesc: '了解该平台的核心功能,并通过图形指引和视频教程快速上手。包含从创建空间到发布应用程序的整个操作流程演示。',
|
||||
spaceTitle:'记忆熊智能空间管理平台',
|
||||
spaceSubTitle: '使智能模型的实施变得更加容易——一个集模型管理、知识构建、工作流程编排以及空间操作于一体的综合性平台',
|
||||
},
|
||||
quickActions:{
|
||||
title: '快速操作',
|
||||
spaceManagement: '空间管理',
|
||||
modelManagement: '模型管理',
|
||||
workflowOrchestration: '工作流编排',
|
||||
userManagement: '用户管理',
|
||||
dataExport: '数据导出',
|
||||
logQuery:'日志查询',
|
||||
notificationReminder: '通知提醒',
|
||||
helpCenter: '帮助中心',
|
||||
knowledgeBase: '知识库',
|
||||
knowledgeBaseDesc: '管理和维护您的知识库数据',
|
||||
modelManagementDesc: '配置和优化AI模型参数',
|
||||
userManagementDesc: '管理系统用户和权限设置',
|
||||
systemSettings: '系统设置',
|
||||
systemSettingsDesc: '配置系统全局参数和选项',
|
||||
memoryManagement: '记忆管理',
|
||||
memoryManagementDesc: '管理用户记忆和对话历史',
|
||||
apiManagement: 'API管理',
|
||||
apiManagementDesc: '管理API密钥和接口配置',
|
||||
workflowEngine: '工作流引擎',
|
||||
workflowEngineDesc: '设计和管理自动化工作流程',
|
||||
performanceMonitor: '性能监控',
|
||||
performanceMonitorDesc: '监控系统性能和运行状态',
|
||||
},
|
||||
guide: {
|
||||
quickStart: '快速开始',
|
||||
createKnowledge: '创建知识库',
|
||||
createKnowledgeDesc: '构建您的专属知识库,让AI更好地理解您的业务',
|
||||
manageModel: '管理模型',
|
||||
manageModelDesc: '配置和管理您的AI模型,优化性能表现',
|
||||
createSpace: '创建空间',
|
||||
createSpaceDesc: '创建新的工作空间,组织您的项目和团队',
|
||||
systemConfig: '系统配置',
|
||||
systemConfigDesc: '配置系统参数,个性化您的使用体验',
|
||||
startCreate: '开始创建',
|
||||
goManage: '去管理',
|
||||
createNow: '立即创建',
|
||||
goConfig: '去配置',
|
||||
},
|
||||
menu: {
|
||||
home: '首页',
|
||||
tenantManagement: '租户管理',
|
||||
@@ -247,6 +299,37 @@ export const zh = {
|
||||
fileDurationExceeds:'文件时长超过限制',
|
||||
fileDurationLimitError: '媒体文件时长超过限制,最大支持150秒,当前时长',
|
||||
unableReadFile:'无法读取媒体文件信息,请检查文件格式',
|
||||
// 知识图谱相关
|
||||
knowledgeGraph: '知识图谱',
|
||||
basicConfig: '基础配置',
|
||||
enableKnowledgeGraph: '启用知识图谱',
|
||||
enableKnowledgeGraphTips: '开启后将自动构建实体关系网络',
|
||||
graphConfig: '图谱配置',
|
||||
sceneName: '场景名称',
|
||||
sceneNamePlaceholder: '请输入场景名称',
|
||||
entityTypes: '实体类型',
|
||||
entityTypesPlaceholder: '请输入实体类型,多个类型用换行分隔',
|
||||
entityNormalization: '实体归一化',
|
||||
entityNormalizationTips: '开启后将对相似实体进行合并处理',
|
||||
entityMethod: '实体方法',
|
||||
entityMethodGeneral: '通用',
|
||||
entityMethodLight: '轻量',
|
||||
communityReportGeneration: '社区报告生成',
|
||||
communityReportGenerationTips: '开启后将生成社区分析报告',
|
||||
generateEntityTypes: '生成实体类型',
|
||||
regenerateEntityTypes: '重新生成',
|
||||
generateEntityTypesSuccess: '实体类型生成成功',
|
||||
generateEntityTypesFailed: '生成实体类型失败',
|
||||
unknownError: '未知错误',
|
||||
pleaseSelectLLMModel: '请先在基础配置中选择大语言模型',
|
||||
enterScenarioName: '请输入场景名称',
|
||||
entityDetails: '实体详情',
|
||||
entityDetailEmpty: '请点击图谱中的节点查看详情',
|
||||
entityDetailEmptyDesc: '选择一个实体节点来查看其详细信息',
|
||||
entityDescription: '实体描述',
|
||||
sourceDocuments: '来源文档',
|
||||
graphTitle: '知识图谱:实体、关系与属性的关联网络',
|
||||
graphTips: '探索知识库中的实体节点及其关系脉络',
|
||||
createForm: {
|
||||
name: '名称',
|
||||
embedding_id: '嵌入模型',
|
||||
@@ -581,12 +664,22 @@ export const zh = {
|
||||
totalRecords: '共 {{total}} 条记录'
|
||||
},
|
||||
dashboard: {
|
||||
total_models: '可用模型总数',
|
||||
total_spaces: '活跃空间数量',
|
||||
total_users: '用户总数',
|
||||
total_apps_runs: '应用运行次数',
|
||||
desc_models: '包含 {{ account }} 个大语言模型和 {{ nums }} 个嵌入模型',
|
||||
desc_spaces: '比昨天多',
|
||||
desc_users: '本周新增',
|
||||
desc_apps_runs: '今日成功率',
|
||||
totalMemoryCapacity: '总记忆容量',
|
||||
userMemory: '用户记忆',
|
||||
knowledgeBaseCount: '知识库数量',
|
||||
apiCallCount: 'API调用次数',
|
||||
comparedToYesterday: '与昨天相比',
|
||||
thisWeek: '本周',
|
||||
thisDay: '本日',
|
||||
failureRate: '故障率',
|
||||
application: '应用数量',
|
||||
total_num: '总记忆容量',
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ const componentMap: Record<string, LazyExoticComponent<ComponentType<object>>> =
|
||||
BasicLayout: lazy(() => import('@/components/Layout/BasicLayout')),
|
||||
LoginLayout: lazy(() => import('@/components/Layout/LoginLayout')),
|
||||
// 视图组件
|
||||
Index: lazy(() => import('@/views/Index')),
|
||||
Home: lazy(() => import('@/views/Home')),
|
||||
UserMemory: lazy(() => import('@/views/UserMemory')),
|
||||
UserMemoryDetail: lazy(() => import('@/views/UserMemoryDetail')),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
{
|
||||
"element": "AuthLayout",
|
||||
"children": [
|
||||
{ "path": "/index", "element": "Index" },
|
||||
{ "path": "/user-management", "element": "UserManagement" },
|
||||
{ "path": "/model", "element": "ModelManagement" },
|
||||
{ "path": "/space", "element": "SpaceManagement" },
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
{
|
||||
"manage": [
|
||||
{
|
||||
"id": 999,
|
||||
"parent": 0,
|
||||
"code": "dashboard",
|
||||
"label": "首页",
|
||||
"i18nKey": "menu.home",
|
||||
"path": "/index",
|
||||
"enable": true,
|
||||
"display": true,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"subs": []
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"parent": 0,
|
||||
|
||||
32
web/src/views/Index/components/GuideCard.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import guideBgImg from '@/assets/images/index/guide_bg@2x.png'
|
||||
import { Button } from 'antd';
|
||||
import { ArrowRightOutlined } from '@ant-design/icons'
|
||||
import arrowRight from '@/assets/images/index/arrow_right_blue.svg'
|
||||
const GuideCard: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className='rb:w-full rb:h-[204px] rb:p-4' style={{ backgroundImage: `url(${guideBgImg})`, backgroundSize: '100% 100%' }}>
|
||||
<div className='rb:flex rb:justify-start rb:text-white rb:text-base rb:font-semibold'>
|
||||
{ t('index.getStarted')}
|
||||
</div>
|
||||
<div className='rb:flex rb:text-xs rb:text-white rb:leading-[18px] rb:mt-3'>
|
||||
{ t('index.startedDesc')}
|
||||
</div>
|
||||
<div className='rb:flex rb:w-full rb:items-center rb:justify-between rb:gap-3 rb:mt-4'>
|
||||
<Button className='rb:gap-2 rb:flex rb:items-center rb:text-[#155EEF] '>
|
||||
<span className='rb:text-xs'>{ t('index.viewGuide')}</span>
|
||||
<img src={arrowRight} className='rb:size-4' />
|
||||
</Button>
|
||||
<Button className='rb:gap-2 rb:flex rb:items-center rb:text-[#155EEF]'>
|
||||
<span className='rb:text-xs'>{ t('index.watchVideo')}</span>
|
||||
<img src={arrowRight} className='rb:size-4' />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GuideCard;
|
||||
101
web/src/views/Index/components/QuickActions.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
import { type FC } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import modelIcon from '@/assets/images/index/model_mgt.svg'
|
||||
import spaceIcon from '@/assets/images/index/space_mgt.svg'
|
||||
import workflowIcon from '@/assets/images/index/workflow_mgt.svg'
|
||||
import userIcon from '@/assets/images/index/user_mgt.svg'
|
||||
import dataExportIcon from '@/assets/images/index/data_export.svg'
|
||||
import logIcon from '@/assets/images/index/log_mgt.svg'
|
||||
import noteIcon from '@/assets/images/index/note_mgt.svg'
|
||||
import helpCenterIcon from '@/assets/images/index/help_center.svg'
|
||||
interface QuickAction {
|
||||
key: string;
|
||||
icon: string;
|
||||
title: string;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
interface QuickActionsProps {
|
||||
className?: string;
|
||||
onNavigate?: (path: string) => void;
|
||||
}
|
||||
|
||||
const QuickActions: FC<QuickActionsProps> = ({ onNavigate }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const quickActions: QuickAction[] = [
|
||||
{
|
||||
key: 'model-management',
|
||||
icon: modelIcon,
|
||||
title: t('quickActions.modelManagement'),
|
||||
onClick: () => onNavigate?.('/model-management')
|
||||
},
|
||||
{
|
||||
key: 'space-management',
|
||||
icon: spaceIcon,
|
||||
title: t('quickActions.spaceManagement'),
|
||||
onClick: () => onNavigate?.('/spce')
|
||||
},
|
||||
{
|
||||
key: 'workflow-orchestration',
|
||||
icon: workflowIcon,
|
||||
title: t('quickActions.workflowOrchestration'),
|
||||
onClick: () => onNavigate?.('/workflow')
|
||||
},
|
||||
{
|
||||
key: 'user-management',
|
||||
icon: userIcon,
|
||||
title: t('quickActions.userManagement'),
|
||||
onClick: () => onNavigate?.('/user-management')
|
||||
},
|
||||
{
|
||||
key: 'data-export',
|
||||
icon: dataExportIcon,
|
||||
title: t('quickActions.dataExport'),
|
||||
onClick: () => onNavigate?.('/')
|
||||
},
|
||||
{
|
||||
key: 'log-query',
|
||||
icon: logIcon,
|
||||
title: t('quickActions.logQuery'),
|
||||
onClick: () => onNavigate?.('/log')
|
||||
},
|
||||
{
|
||||
key: 'notification-reminder',
|
||||
icon: noteIcon,
|
||||
title: t('quickActions.notificationReminder'),
|
||||
onClick: () => onNavigate?.('/notification-reminder')
|
||||
},
|
||||
|
||||
{
|
||||
key: 'help-center',
|
||||
icon: helpCenterIcon,
|
||||
title: t('quickActions.helpCenter'),
|
||||
onClick: () => onNavigate?.('/help-center')
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className='rb:w-full rb:p-4 rb:bg-[#FBFDFF] rb:border-1 rb:border-[#DFE4ED] rb:rounded-xl'>
|
||||
<div className='rb:flex rb:justify-start rb:text-base rb:font-medium rb:text-[#212332]'>
|
||||
{ t('quickActions.title') }
|
||||
</div>
|
||||
<div className="rb:grid rb:grid-cols-3 md:rb:grid-cols-4 rb:gap-4 rb:mt-4">
|
||||
|
||||
{quickActions.map((action) => (
|
||||
<div key={action.key}
|
||||
className="rb:flex rb:flex-col rb:items-center rb:text-center rb:cursor-pointer rb:group"
|
||||
onClick={action.onClick}
|
||||
>
|
||||
<img src={action.icon} className='rb:size-10 rb:mx-auto' />
|
||||
<div className="rb:mt-2 rb:text-xs rb:max-w-[74px] rb:text-[#5B6167] rb:text-center rb:leading-[14px]">
|
||||
{action.title}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>);
|
||||
};
|
||||
|
||||
export default QuickActions;
|
||||
99
web/src/views/Index/components/TopCardList/index.module.css
Normal file
@@ -0,0 +1,99 @@
|
||||
.card {
|
||||
border-radius: 12px;
|
||||
border: 1px solid #DFE4ED;
|
||||
padding: 16px;
|
||||
}
|
||||
.header {
|
||||
line-height: 16px;
|
||||
font-family: PingFangSC, PingFang SC;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #212332;
|
||||
font-style: normal;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.headerTitle {
|
||||
/* Add your header title styles here */
|
||||
}
|
||||
.avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 2px 6px 0px rgba(33, 35, 50, 0.1);
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
/* margin-right: 12px; */
|
||||
}
|
||||
.avatar img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
.content {
|
||||
padding: 24px 24px 8px 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-family: Gilroy, Gilroy;
|
||||
font-weight: 800;
|
||||
font-size: 28px;
|
||||
color: #212332;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
.content-right {
|
||||
text-align: right;
|
||||
font-family: PingFangSC, PingFang SC;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #5F6266;
|
||||
line-height: 16px;
|
||||
font-style: normal;
|
||||
row-gap: 4px;
|
||||
}
|
||||
.trend {
|
||||
font-family: PingFangSC, PingFang SC;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
font-style: normal;
|
||||
padding-left: 15px;
|
||||
position: relative;
|
||||
margin-bottom: 4px;
|
||||
display: inline-block;
|
||||
}
|
||||
.trend::before {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 1px;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
.trend.up {
|
||||
color: #369F21;
|
||||
}
|
||||
.trend.up::before {
|
||||
background-image: url('@/assets/images/home/arrow_up_success.svg');
|
||||
}
|
||||
.trend.down {
|
||||
color: #FF5D34;
|
||||
}
|
||||
.trend.down::before {
|
||||
background-image: url('@/assets/images/home/arrow_down.png');
|
||||
}
|
||||
|
||||
.trend-desc {
|
||||
font-family: PingFangSC, PingFang SC;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: #155EEF;
|
||||
line-height: 16px;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
110
web/src/views/Index/components/TopCardList/index.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import { type FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import totalModels from '@/assets/images/index/models.svg';
|
||||
import totalSpaces from '@/assets/images/index/spaces.svg';
|
||||
import totalUsers from '@/assets/images/index/users.svg';
|
||||
import totalApps from '@/assets/images/index/apps.svg';
|
||||
import arrowUpDb from '@/assets/images/index/arrow_up_d.svg'
|
||||
import arrowDownDb from '@/assets/images/index/arrow_down_d.svg'
|
||||
import arrowUp from '@/assets/images/index/arrow_up.svg'
|
||||
import arrowDown from '@/assets/images/index/arrow_down.svg'
|
||||
import styles from './index.module.css'
|
||||
import type { DashboardData } from '../../types'
|
||||
|
||||
const list = [
|
||||
{
|
||||
key: 'models',
|
||||
icon: totalModels,
|
||||
value: '24',
|
||||
// trendValue: '12.5%',
|
||||
trend: 'up',
|
||||
// trendDesc: 'comparedToYesterday',
|
||||
rate:"up",
|
||||
rateValue: '12%',
|
||||
background: 'linear-gradient( 136deg, rgba(21,94,239,0.06) 0%, rgba(251,253,255,0) 100%)'
|
||||
},
|
||||
{
|
||||
key: 'spaces',
|
||||
icon: totalSpaces,
|
||||
value: '156',
|
||||
trendValue: '+8',
|
||||
trend: 'down',
|
||||
rate:"up",
|
||||
rateValue: '5.4%',
|
||||
// trendDesc: 'comparedToYesterday',
|
||||
background: 'linear-gradient( 134deg, rgba(54,159,33,0.06) 0%, rgba(251,253,255,0) 100%)',
|
||||
},
|
||||
{
|
||||
key: 'users',
|
||||
icon: totalUsers,
|
||||
value: '1,248',
|
||||
trendValue: '+42',
|
||||
trend: 'up',
|
||||
rate:"up",
|
||||
rateValue: '12%',
|
||||
// trendDesc: 'thisWeek',
|
||||
background: 'linear-gradient( 136deg, rgba(77,168,255,0.06) 0%, rgba(251,253,255,0) 100%)',
|
||||
},
|
||||
{
|
||||
key: 'apps_runs',
|
||||
icon: totalApps,
|
||||
value: '12.8k',
|
||||
trendValue: '98.7%',
|
||||
trend: 'up',
|
||||
rate:"down",
|
||||
rateValue: '2.1%',
|
||||
// trendDesc: 'comparedToYesterday',
|
||||
background: 'linear-gradient( 136deg, rgba(156,111,255,0.06) 0%, rgba(251,253,255,0) 100%)',
|
||||
},
|
||||
]
|
||||
const TopCardList: FC<{data?: DashboardData}> = ({ data }) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className="rb:grid rb:grid-cols-4 rb:gap-[16px]">
|
||||
{list.map((item) => {
|
||||
return (
|
||||
<div
|
||||
key={item.key}
|
||||
className={styles.card}
|
||||
style={{
|
||||
background: item.background,
|
||||
}}
|
||||
>
|
||||
<div className={styles.header}>
|
||||
<div className="rb:text-xs rb:font-medium rb:text-[#212332] rb:w-[96px]">{t(`dashboard.${'total_' + item.key}`)}</div>
|
||||
<div className={styles.avatar}><img src={item.icon} /></div>
|
||||
</div>
|
||||
|
||||
<div className={styles.content}>
|
||||
{data?.[`total_${item.key}` as keyof DashboardData] || item.value || 0}
|
||||
</div>
|
||||
<div className='rb:flex rb:flex-col rb:items-start'>
|
||||
{item.key === 'models' ? (
|
||||
<div className='rb:text-xs rb:leading-4 rb:text-[#5F6266] rb:w-[130px]'>
|
||||
{t(`dashboard.${'desc_' + item.key}`, { account: 18, nums: 6 })}
|
||||
</div>
|
||||
) : (<>
|
||||
<div className='rb:flex rb:items-center rb:text-xs rb:leading-4 rb:gap-1'>
|
||||
<img src={item.trend === 'up' ? arrowUpDb : arrowDownDb} className='rb:size-3'/>
|
||||
<span className={item.trend === 'up' ? 'rb:text-[#369F21]' : 'rb:text-[#FF5D34]'}>{item.trendValue}</span>
|
||||
</div>
|
||||
<div className='rb:text-xs rb:leading-4 rb:text-[#5F6266]'>
|
||||
{t(`dashboard.${'desc_' + item.key}`)}
|
||||
</div>
|
||||
</>)}
|
||||
</div>
|
||||
<div className={`rb:flex rb:max-w-40 rb:text-xs rb:mt-2 rb:items-center rb:gap-1 rb:border-1 rb:rounded rb:px-2 rb:py-0.5 ${item.rate === 'up' ? 'rb:text-[#369F21] rb:border-[#369F21] rb:bg-[rgba(54, 159, 33, 0.25)]' : 'rb:text-[#FF5D34] rb:border-[#FF5D34] rb:bg-[rgba(255, 93, 52, 0.25)]'}`}>
|
||||
<img src={item.rate === 'up' ? arrowUp : arrowDown} className='rb:size-3'/>
|
||||
<span> {item.rateValue} </span>
|
||||
{(item.key === 'models' || item.key === 'users') && (<span>{t('dashboard.thisWeek')}</span>)}
|
||||
{item.key === 'apps_runs' && (<span>{t('dashboard.failureRate')}</span>)}
|
||||
{item.key === 'spaces' && (<span>{t('dashboard.thisDay')}</span>)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TopCardList
|
||||
30
web/src/views/Index/components/VersionCard.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from 'antd';
|
||||
import arrowRight from '@/assets/images/index/arrow_right.svg'
|
||||
const GuideCard: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className='rb:w-full rb:h-[186px] rb:p-4 rb:border-1 rb:border-[#DFE4ED] rb:bg-[#FBFDFF] rb:rounded-xl'>
|
||||
<div className='rb:flex rb:justify-start rb:text-[#5B6167] rb:text-base rb:font-semibold'>
|
||||
{ t('index.latestUpdate')}
|
||||
</div>
|
||||
<div className='rb:flex rb:text-xs rb:text-[#5B6167] rb:leading-[18px] rb:mt-3 rb:pl-2'>
|
||||
{ t('index.latestUpdateDesc')}
|
||||
</div>
|
||||
<div className='rb:flex rb:w-full rb:items-center rb:justify-between rb:gap-3 rb:mt-4'>
|
||||
<Button className='rb:gap-2 rb:flex rb:items-center rb:text-[#212332] '>
|
||||
<span className='rb:text-xs'>{ t('index.viewDetails')}</span>
|
||||
<img src={arrowRight} className='rb:size-4' />
|
||||
</Button>
|
||||
<Button className='rb:gap-2 rb:flex rb:items-center rb:text-[#212332]'>
|
||||
<span className='rb:text-xs'>{ t('index.changeLog')}</span>
|
||||
<img src={arrowRight} className='rb:size-4' />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GuideCard;
|
||||
121
web/src/views/Index/index.tsx
Normal file
@@ -0,0 +1,121 @@
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Row, Col, Space, Button } from 'antd';
|
||||
import TopCardList from './components/TopCardList';
|
||||
import GuideCard from './components/GuideCard';
|
||||
import VersionCard from './components/VersionCard';
|
||||
import QuickActions from './components/QuickActions';
|
||||
import bgImg from '@/assets/images/index/index_bg@2x.png'
|
||||
import type { DashboardData } from './types';
|
||||
import Table, { type TableRef } from '@/components/Table'
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { formatDateTime } from '@/utils/format';
|
||||
const Index = () => {
|
||||
const { t } = useTranslation();
|
||||
const [dashboardData, setDashboardData] = useState<DashboardData>({
|
||||
total_models: 24,
|
||||
total_spaces: 156,
|
||||
total_users: 1248,
|
||||
total_apps_runs: '12.8k',
|
||||
});
|
||||
const tableRef = useRef<TableRef>(null);
|
||||
const tableApi = '/workspaces';
|
||||
const [loading, setLoading] = useState({
|
||||
knowledgeTypeDistribution: true,
|
||||
});
|
||||
const [knowledgeTypeDistribution, setKnowledgeTypeDistribution] = useState<Array<{ name: string; value: number }>>([]);
|
||||
const [memoryIncrement, setMemoryIncrement] = useState<Array<{ updated_at: string; total_num: number; }>>([]);
|
||||
const [limit, setLimit] = useState(7);
|
||||
const columns: ColumnsType = [
|
||||
{
|
||||
title: t('space.spaceName'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
// {
|
||||
// title: t('space.associated') + ' ' + t('memorySummary.user'),
|
||||
// dataIndex: 'name',
|
||||
// key: 'name',
|
||||
// },
|
||||
{
|
||||
title: t('space.spaceIcon'),
|
||||
dataIndex: 'icon',
|
||||
key: 'icon',
|
||||
render:(value:string) => {
|
||||
return(
|
||||
<img src={value} alt="icon" className='rb:w-[24px] rb:h-[24px]' />
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: t('apiKey.createdAt'),
|
||||
dataIndex: 'created_at',
|
||||
key: 'created_at',
|
||||
render:(value:string) => {
|
||||
return(
|
||||
<span>{formatDateTime(Number(value) * 1000 ,'YYYY-MM-DD HH:mm:ss')}</span>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: t('common.operation'),
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
width: 100,
|
||||
render: (_, record) => (
|
||||
<Space size="middle">
|
||||
<Button color="primary" variant="text">{t('space.enterSpace')}</Button>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]
|
||||
// 模拟API获取数据
|
||||
useEffect(() => {
|
||||
tableRef.current?.loadData();
|
||||
}, [tableApi]);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="rb:pb-[24px]">
|
||||
<Row className="rb:mt-[16px]" gutter={16}>
|
||||
<Col span={19}>
|
||||
<div className='rb:flex-col rb:w-full rb:h-[120px] rb:mb-4 rb:p-6 rb:leading-[30px]' style={{backgroundImage: `url(${bgImg})`, backgroundSize: '100% 100%'}}>
|
||||
<div className='rb:flex rb:text-[22px] rb:text-[#0041C3] rb:font-semibold'>
|
||||
{ t('index.spaceTitle' )}
|
||||
</div>
|
||||
<div className='rb:flex rb:mt-2 rb:text-xs rb:leading-[18px] rb:text-[#5F6266] rb:max-w-[560px]'>
|
||||
{ t('index.spaceSubTitle' )}
|
||||
</div>
|
||||
</div>
|
||||
{/* 统计卡片 */}
|
||||
<TopCardList data={dashboardData} />
|
||||
<div className="rb:rounded rb:max-h-[calc(100%-100px)] rb:overflow-y-auto rb:mt-4">
|
||||
<Table
|
||||
ref={tableRef}
|
||||
apiUrl={tableApi}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
|
||||
/>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
{/* 引导 */}
|
||||
<GuideCard />
|
||||
<div className='rb:w-full rb:mt-4 '>
|
||||
<VersionCard />
|
||||
</div>
|
||||
{/* 快捷操作 */}
|
||||
<div className='rb:w-full rb:mt-4'>
|
||||
<QuickActions />
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Index
|
||||
13
web/src/views/Index/types.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export interface TopCardListProps {
|
||||
title:string;
|
||||
description:string;
|
||||
icon: Element;
|
||||
number: number;
|
||||
label: string;
|
||||
}
|
||||
export interface DashboardData {
|
||||
total_models:number;
|
||||
total_spaces:number;
|
||||
total_users:number;
|
||||
total_apps_runs: string;
|
||||
}
|
||||
@@ -2,18 +2,18 @@
|
||||
import { useEffect, useState, useRef, useCallback, type FC } from 'react';
|
||||
import { useNavigate, useParams, useLocation } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Switch, Button, Dropdown, Space, Modal, message } from 'antd';
|
||||
import { Switch, Button, Dropdown, Space, Modal, message, Radio } from 'antd';
|
||||
import type { MenuProps } from 'antd';
|
||||
import SearchInput from '@/components/SearchInput'
|
||||
import Table, { type TableRef } from '@/components/Table'
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import type { AnyObject } from 'antd/es/_util/type';
|
||||
import { MoreOutlined } from '@ant-design/icons';
|
||||
import { MoreOutlined, DeploymentUnitOutlined, BarsOutlined } from '@ant-design/icons';
|
||||
import folderIcon from '@/assets/images/knowledgeBase/folder.png';
|
||||
import textIcon from '@/assets/images/knowledgeBase/text.png';
|
||||
import editIcon from '@/assets/images/knowledgeBase/edit.png';
|
||||
import blankIcon from '@/assets/images/knowledgeBase/blankDocument.png';
|
||||
import imageIcon from '@/assets/images/knowledgeBase/image.png'
|
||||
// import blankIcon from '@/assets/images/knowledgeBase/blankDocument.png';
|
||||
// import imageIcon from '@/assets/images/knowledgeBase/image.png'
|
||||
import { getKnowledgeBaseDetail, deleteDocument, downloadFile, updateKnowledgeBase } from '@/api/knowledgeBase';
|
||||
import {
|
||||
type CreateModalRef,
|
||||
@@ -22,8 +22,10 @@ import {
|
||||
type CreateFolderModalRef,
|
||||
type CreateSetModalRef,
|
||||
type ShareModalRef,
|
||||
type CreateDatasetModalRef,type FolderFormData,
|
||||
type KnowledgeBaseDocumentData,
|
||||
type CreateDatasetModalRef,
|
||||
type FolderFormData,
|
||||
type KnowledgeBaseDocumentData,
|
||||
type KnowledgeBaseFormData,
|
||||
} from '@/views/KnowledgeBase/types';
|
||||
import RecallTestDrawer from '../components/RecallTestDrawer';
|
||||
import CreateFolderModal from '../components/CreateFolderModal';
|
||||
@@ -34,7 +36,7 @@ import CreateDatasetModal from '../components/CreateDatasetModal';
|
||||
import CreateImageDataset from '../components/CreateImageDataset';
|
||||
import FolderTree, { type TreeNodeData } from '../components/FolderTree';
|
||||
import { formatDateTime } from '@/utils/format';
|
||||
|
||||
import KnowledgeGraphCard from '../components/KnowledgeGraphCard';
|
||||
import { useBreadcrumbManager, type BreadcrumbItem } from '@/hooks/useBreadcrumbManager';
|
||||
import './Private.css'
|
||||
const { confirm } = Modal
|
||||
@@ -68,7 +70,7 @@ const Private: FC = () => {
|
||||
const datasetModalRef = useRef<CreateDatasetModalRef>(null);
|
||||
const [folderTreeRefreshKey, setFolderTreeRefreshKey] = useState(0);
|
||||
const [autoExpandPath, setAutoExpandPath] = useState<Array<{ id: string; name: string }>>([]);
|
||||
|
||||
const [isGraph, setIsGraph] = useState(false);
|
||||
const { updateBreadcrumbs } = useBreadcrumbManager({
|
||||
breadcrumbType: 'detail',
|
||||
// 不提供 onKnowledgeBaseMenuClick,让它使用默认的导航行为(返回列表页面)
|
||||
@@ -376,9 +378,37 @@ const Private: FC = () => {
|
||||
|
||||
// 处理开关
|
||||
const onChange = (checked: boolean) => {
|
||||
updateKnowledgeBase(knowledgeBaseId || '', {
|
||||
if (!knowledgeBase) return;
|
||||
|
||||
// 构造完整的更新数据,保留现有配置
|
||||
const updateData: KnowledgeBaseFormData = {
|
||||
name: knowledgeBase.name,
|
||||
description: knowledgeBase.description,
|
||||
embedding_id: knowledgeBase.embedding_id,
|
||||
llm_id: knowledgeBase.llm_id,
|
||||
image2text_id: knowledgeBase.image2text_id,
|
||||
reranker_id: knowledgeBase.reranker_id,
|
||||
permission_id: knowledgeBase.permission_id,
|
||||
type: knowledgeBase.type,
|
||||
status: checked ? 1 : 0,
|
||||
});
|
||||
parser_config: knowledgeBase.parser_config || {
|
||||
chunk_token_num: 512,
|
||||
delimiter: '\n',
|
||||
auto_keywords: 0,
|
||||
auto_questions: 0,
|
||||
html4excel: false,
|
||||
graphrag: {
|
||||
use_graphrag: false,
|
||||
scene_name: '',
|
||||
entity_types: '',
|
||||
method: '',
|
||||
resolution: false,
|
||||
community: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
updateKnowledgeBase(knowledgeBaseId || '', updateData);
|
||||
console.log(`switch to ${checked}`);
|
||||
};
|
||||
// 处理搜索
|
||||
@@ -626,17 +656,15 @@ const Private: FC = () => {
|
||||
}
|
||||
|
||||
const handleRefreshTable = () => {
|
||||
debugger
|
||||
// 刷新表格数据
|
||||
tableRef.current?.loadData();
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{contextHolder}
|
||||
<div className="rb:flex rb:h-full rb:gap-4">
|
||||
{folder && (
|
||||
<div className="rb:w-80 rb:flex-shrink-0 rb:h-[calc(100%+40px)] rb:mt-[-16px] rb:border-r rb:border-[#EAECEE] rb:p-4 rb:bg-transparent">
|
||||
<div className="rb:w-64 rb:flex-shrink-0 rb:h-[calc(100%+40px)] rb:mt-[-16px] rb:border-r rb:border-[#EAECEE] rb:p-4 rb:bg-transparent">
|
||||
<FolderTree
|
||||
multiple
|
||||
className="customTree"
|
||||
@@ -678,6 +706,14 @@ const Private: FC = () => {
|
||||
<div className='rb:flex rb:items-center rb:justify-between rb:mb-4'>
|
||||
<SearchInput placeholder={t('knowledgeBase.search')} onSearch={handleSearch} />
|
||||
<div className='rb:flex-1 rb:flex rb:items-center rb:justify-end rb:gap-2.5'>
|
||||
<Radio.Group value={isGraph} onChange={(e) => setIsGraph(e.target.value)}>
|
||||
<Radio.Button value={false} >
|
||||
<BarsOutlined />
|
||||
</Radio.Button>
|
||||
<Radio.Button value={true} >
|
||||
<DeploymentUnitOutlined />
|
||||
</Radio.Button>
|
||||
</Radio.Group>
|
||||
<Button onClick={handleShare}>{t('knowledgeBase.share')}</Button>
|
||||
<Button onClick={handleRecallTest}>{t('knowledgeBase.recallTest')}</Button>
|
||||
<Button onClick={handleSetting}>{t('knowledgeBase.knowledgeBase')} {t('knowledgeBase.setting')}</Button>
|
||||
@@ -688,14 +724,18 @@ const Private: FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="rb:rounded rb:max-h-[calc(100%-100px)] rb:overflow-y-auto">
|
||||
<Table
|
||||
ref={tableRef}
|
||||
apiUrl={tableApi}
|
||||
apiParams={query as Record<string, unknown>}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
scrollX={1500}
|
||||
/>
|
||||
{isGraph ? (
|
||||
<KnowledgeGraphCard knowledgeBaseId={knowledgeBase.id} />
|
||||
) : (
|
||||
<Table
|
||||
ref={tableRef}
|
||||
apiUrl={tableApi}
|
||||
apiParams={query as Record<string, unknown>}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
scrollX={1500}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<RecallTestDrawer
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';
|
||||
import { Form, Input, Select, Modal } from 'antd';
|
||||
import { Form, Input, Select, Modal, Tabs, Switch, Radio, Button,message } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import type { KnowledgeBaseListItem, KnowledgeBaseFormData, CreateModalRef, CreateModalRefProps } from '@/views/KnowledgeBase/types';
|
||||
import { getModelTypeList, getModelList, createKnowledgeBase, updateKnowledgeBase } from '@/api/knowledgeBase'
|
||||
import {
|
||||
getModelTypeList,
|
||||
getModelList,
|
||||
createKnowledgeBase,
|
||||
updateKnowledgeBase,
|
||||
getKnowledgeGraphEntityTypes
|
||||
} from '@/api/knowledgeBase'
|
||||
import RbModal from '@/components/RbModal'
|
||||
const { TextArea } = Input;
|
||||
const { confirm } = Modal
|
||||
@@ -14,22 +20,104 @@ const CreateModal = forwardRef<CreateModalRef, CreateModalRefProps>(({
|
||||
refreshTable
|
||||
}, ref) => {
|
||||
const { t } = useTranslation();
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [modelTypeList, setModelTypeList] = useState<string[]>([]);
|
||||
const [modelOptionsByType, setModelOptionsByType] = useState<Record<string, { label: string; value: string }[]>>({});
|
||||
const [datasets, setDatasets] = useState<KnowledgeBaseListItem | null>(null);
|
||||
const [currentType, setCurrentType] = useState<'General' | 'Web' | 'Third-party' | 'Folder'>('General');
|
||||
const [form] = Form.useForm<KnowledgeBaseFormData>();
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState('basic');
|
||||
const [generatingEntityTypes, setGeneratingEntityTypes] = useState(false);
|
||||
|
||||
// 监听 parser_config.graphrag 相关字段的变化
|
||||
const parserConfig = Form.useWatch('parser_config', form);
|
||||
const graphragConfig = parserConfig?.graphrag;
|
||||
const enableKnowledgeGraph = graphragConfig?.use_graphrag || false;
|
||||
const entityTypes = graphragConfig?.entity_types || '';
|
||||
const entityNormalization = graphragConfig?.resolution || false;
|
||||
const communityReportGeneration = graphragConfig?.community || false;
|
||||
|
||||
// 封装取消方法,添加关闭弹窗逻辑
|
||||
const handleClose = () => {
|
||||
setDatasets(null);
|
||||
form.resetFields();
|
||||
setLoading(false)
|
||||
setLoading(false);
|
||||
setActiveTab('basic');
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
// 生成实体类型的函数
|
||||
const generateEntityTypes = async () => {
|
||||
const sceneName = form.getFieldValue(['parser_config', 'graphrag', 'scene_name']);
|
||||
if (!sceneName) {
|
||||
// 可以添加提示用户输入场景名称
|
||||
messageApi.error(t('knowledgeBase.enterScenarioName'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否选择了 LLM 模型
|
||||
const llmId = form.getFieldValue('llm_id');
|
||||
if (!llmId) {
|
||||
// 跳转到基础配置页
|
||||
setActiveTab('basic');
|
||||
messageApi.error(t('knowledgeBase.pleaseSelectLLMModel'));
|
||||
return;
|
||||
}
|
||||
|
||||
setGeneratingEntityTypes(true);
|
||||
try {
|
||||
// 这里应该调用实际的API接口
|
||||
// const user = JSON.parse(localStorage.getItem('user') as any);
|
||||
//datasets?.id || datasets?.parent_id || user?.current_workspace_id,
|
||||
const params = {
|
||||
scenario: sceneName,
|
||||
llm_id: llmId
|
||||
};
|
||||
const response = await getKnowledgeGraphEntityTypes(params);
|
||||
// 模拟API调用
|
||||
// await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
// 处理API响应数据
|
||||
console.log('API Response:', response); // 调试日志
|
||||
|
||||
// 检查响应结构 - API直接返回字符串
|
||||
if (response && typeof response === 'string' && response.trim()) {
|
||||
// 将逗号分隔的字符串转换为换行分隔的格式以便在TextArea中显示
|
||||
const entityTypesString = response.replace(/,\s*/g, '\n');
|
||||
console.log('Converted entity types:', entityTypesString); // 调试日志
|
||||
|
||||
const currentGraphrag = form.getFieldValue(['parser_config', 'graphrag']) || {};
|
||||
const updatedGraphrag = {
|
||||
...currentGraphrag,
|
||||
entity_types: entityTypesString
|
||||
};
|
||||
|
||||
console.log('Updating form with:', updatedGraphrag); // 调试日志
|
||||
|
||||
// 使用更直接的方式更新表单字段
|
||||
form.setFieldValue(['parser_config', 'graphrag', 'entity_types'], entityTypesString);
|
||||
|
||||
// 强制触发表单重新渲染
|
||||
form.validateFields([['parser_config', 'graphrag', 'entity_types']]);
|
||||
|
||||
// 额外的强制更新机制
|
||||
setTimeout(() => {
|
||||
form.setFieldValue(['parser_config', 'graphrag', 'entity_types'], entityTypesString);
|
||||
}, 100);
|
||||
|
||||
messageApi.success(t('knowledgeBase.generateEntityTypesSuccess'));
|
||||
} else {
|
||||
messageApi.error(t('knowledgeBase.generateEntityTypesFailed') + ':' + t('knowledgeBase.unknownError'));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(t('knowledgeBase.generateEntityTypesFailed') + ':', error);
|
||||
} finally {
|
||||
setGeneratingEntityTypes(false);
|
||||
}
|
||||
};
|
||||
|
||||
const typeToFieldKey = (type: string): string => {
|
||||
switch ((type || '').toLowerCase()) {
|
||||
case 'embedding':
|
||||
@@ -89,6 +177,30 @@ const CreateModal = forwardRef<CreateModalRef, CreateModalRefProps>(({
|
||||
type: type || record.type || currentType,
|
||||
status: record.status,
|
||||
};
|
||||
|
||||
// 处理 parser_config 配置数据,如果没有则设置默认值
|
||||
baseValues.parser_config = record.parser_config || {
|
||||
graphrag: {
|
||||
use_graphrag: false,
|
||||
scene_name: '',
|
||||
entity_types: [] as any,
|
||||
method: 'general',
|
||||
resolution: false,
|
||||
community: false,
|
||||
}
|
||||
};
|
||||
|
||||
// 如果存在 entity_types,转换为换行分隔格式用于 TextArea 显示
|
||||
if (baseValues.parser_config.graphrag.entity_types) {
|
||||
if (Array.isArray(baseValues.parser_config.graphrag.entity_types)) {
|
||||
// 如果是数组格式,转换为换行分隔字符串
|
||||
(baseValues.parser_config.graphrag as any).entity_types = baseValues.parser_config.graphrag.entity_types.join('\n');
|
||||
} else if (typeof baseValues.parser_config.graphrag.entity_types === 'string') {
|
||||
// 如果是逗号分隔字符串格式,转换为换行分隔字符串(兼容旧数据)
|
||||
(baseValues.parser_config.graphrag as any).entity_types = (baseValues.parser_config.graphrag.entity_types as string).replace(/,\s*/g, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
form.setFieldsValue(baseValues);
|
||||
};
|
||||
|
||||
@@ -142,12 +254,26 @@ const CreateModal = forwardRef<CreateModalRef, CreateModalRefProps>(({
|
||||
.then(() => {
|
||||
setLoading(true)
|
||||
const formValues = form.getFieldsValue();
|
||||
|
||||
// 处理 entity_types 格式转换:从换行分隔字符串转换为字符串数组
|
||||
if (formValues.parser_config && formValues.parser_config.graphrag && formValues.parser_config.graphrag.entity_types) {
|
||||
const entityTypesString = formValues.parser_config.graphrag.entity_types as any as string;
|
||||
const entityTypesArray = entityTypesString
|
||||
.split('\n')
|
||||
.map((item: string) => item.trim())
|
||||
.filter((item: string) => item.length > 0);
|
||||
formValues.parser_config.graphrag.entity_types = entityTypesArray;
|
||||
}
|
||||
|
||||
const payload: KnowledgeBaseFormData = {
|
||||
...formValues,
|
||||
type: formValues.type || currentType,
|
||||
permission_id: formValues.permission_id || 'Private',
|
||||
parent_id: datasets?.parent_id || undefined,
|
||||
};
|
||||
|
||||
console.log('Saving payload:', payload); // 调试日志
|
||||
|
||||
const submit = datasets?.id
|
||||
? updateKnowledgeBase(datasets.id, payload)
|
||||
: createKnowledgeBase(payload);
|
||||
@@ -205,6 +331,192 @@ const CreateModal = forwardRef<CreateModalRef, CreateModalRefProps>(({
|
||||
|
||||
const dynamicTypeList = useMemo(() => modelTypeList.filter((tp) => (modelOptionsByType[tp] || []).length), [modelTypeList, modelOptionsByType]);
|
||||
|
||||
// 基础配置表单内容
|
||||
const renderBasicConfig = () => (
|
||||
<>
|
||||
{!datasets?.id && (
|
||||
<Form.Item
|
||||
name="name"
|
||||
label={t('knowledgeBase.createForm.name')}
|
||||
rules={[{ required: true, message: t('knowledgeBase.createForm.nameRequired') }]}
|
||||
>
|
||||
<Input placeholder={t('knowledgeBase.createForm.name')} />
|
||||
</Form.Item>
|
||||
)}
|
||||
<Form.Item name="description" label={t('knowledgeBase.createForm.description')}>
|
||||
<TextArea rows={2} placeholder={t('knowledgeBase.createForm.description')} />
|
||||
</Form.Item>
|
||||
|
||||
{currentType !== 'Folder' && dynamicTypeList.map((tp) => {
|
||||
const fieldKey = typeToFieldKey(tp);
|
||||
// 当 tp 为 'llm' 时,合并 llm 和 chat 的选项
|
||||
const options = tp.toLowerCase() === 'llm'
|
||||
? [...(modelOptionsByType['llm'] || []), ...(modelOptionsByType['chat'] || [])]
|
||||
: modelOptionsByType[tp] || [];
|
||||
return (
|
||||
<Form.Item
|
||||
key={tp}
|
||||
name={fieldKey as keyof KnowledgeBaseFormData}
|
||||
label={t(`knowledgeBase.createForm.${fieldKey}`) + ' ' + 'model'}
|
||||
rules={[{ required: true, message: t('knowledgeBase.createForm.modelRequired') }]}
|
||||
>
|
||||
<Select
|
||||
options={options}
|
||||
placeholder={t(`knowledgeBase.createForm.${fieldKey}`)}
|
||||
allowClear={false}
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
onChange={(value) => handleChange(value, tp)}
|
||||
/>
|
||||
</Form.Item>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
|
||||
// 知识图谱配置表单内容
|
||||
const renderKnowledgeGraphConfig = () => (
|
||||
<>
|
||||
<div className={`rb:flex rb:w-full rb:items-center rb:p-4 rb:border-1 rb:rounded-lg rb:mb-4 ${
|
||||
enableKnowledgeGraph
|
||||
? 'rb:border-[#155EEF] rb:bg-[rgba(21,94,239,0.06)]'
|
||||
: 'rb:border-[#EBEBEB]'
|
||||
}`}>
|
||||
<div className='rb:flex rb:flex-col rb:flex-1'>
|
||||
<div className='rb:text-[#212332] rb:text-base rb:font-medium'>
|
||||
{t('knowledgeBase.enableKnowledgeGraph')}
|
||||
</div>
|
||||
<div className='rb:text-xs rb:text-[#5B6167] rb:mt-2'>
|
||||
{t('knowledgeBase.enableKnowledgeGraphTips')}
|
||||
</div>
|
||||
</div>
|
||||
<Form.Item
|
||||
name={['parser_config', 'graphrag', 'use_graphrag']}
|
||||
label=''
|
||||
valuePropName="checked"
|
||||
className='rb:mb-0'
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
||||
{enableKnowledgeGraph && (
|
||||
<>
|
||||
<div className='rb:text-[#212332] rb:text-base rb:font-medium rb:mb-4'>
|
||||
{t('knowledgeBase.graphConfig')}
|
||||
</div>
|
||||
{/* 场景名称 */}
|
||||
<div className='rb:flex rb:items-center rb:gap-2'>
|
||||
<Form.Item
|
||||
name={['parser_config', 'graphrag', 'scene_name']}
|
||||
label={t('knowledgeBase.sceneName')}
|
||||
className='rb:w-full rb:min-w-[240px]'
|
||||
rules={[{ required: true, message: t('common.pleaseEnter') + t('knowledgeBase.sceneName') }]}
|
||||
>
|
||||
<Input placeholder={t('knowledgeBase.sceneNamePlaceholder')} />
|
||||
</Form.Item>
|
||||
<Button
|
||||
type="primary"
|
||||
loading={generatingEntityTypes}
|
||||
onClick={generateEntityTypes}
|
||||
className='rb:mt-1'
|
||||
>
|
||||
{!(entityTypes as any as string) || (entityTypes as any as string).trim() === ''
|
||||
? t('knowledgeBase.generateEntityTypes')
|
||||
: t('knowledgeBase.regenerateEntityTypes')
|
||||
}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
||||
{/* 实体类型 */}
|
||||
<Form.Item
|
||||
name={['parser_config', 'graphrag', 'entity_types']}
|
||||
label={t('knowledgeBase.entityTypes')}
|
||||
>
|
||||
<TextArea
|
||||
rows={4}
|
||||
placeholder={t('knowledgeBase.entityTypesPlaceholder')}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
{/* 实体归一化 */}
|
||||
<div className={`rb:flex rb:w-full rb:gap-2 rb:items-center rb:p-4 rb:border-1 rb:rounded-lg rb:mb-4 ${
|
||||
entityNormalization
|
||||
? 'rb:border-[#155EEF] rb:bg-[rgba(21,94,239,0.06)]'
|
||||
: 'rb:border-[#EBEBEB]'
|
||||
}`}>
|
||||
<div className='rb:flex rb:flex-col rb:flex-1'>
|
||||
<div className='rb:text-[#212332] rb:text-base rb:font-medium'>
|
||||
{t('knowledgeBase.entityNormalization')}
|
||||
</div>
|
||||
<div className='rb:text-xs rb:text-[#5B6167] rb:mt-2'>
|
||||
{t('knowledgeBase.entityNormalizationTips')}
|
||||
</div>
|
||||
</div>
|
||||
<Form.Item
|
||||
name={['parser_config', 'graphrag', 'resolution']}
|
||||
valuePropName="checked"
|
||||
className='rb:mb-0'
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
||||
|
||||
{/* 实体方法 */}
|
||||
<Form.Item
|
||||
name={['parser_config', 'graphrag', 'method']}
|
||||
label={t('knowledgeBase.entityMethod')}
|
||||
initialValue="general"
|
||||
>
|
||||
<Radio.Group>
|
||||
<Radio value="general">{t('knowledgeBase.entityMethodGeneral')}</Radio>
|
||||
<Radio value="light">{t('knowledgeBase.entityMethodLight')}</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
|
||||
{/* 社区报告生成 */}
|
||||
<div className={`rb:flex rb:w-full rb:gap-2 rb:items-center rb:p-4 rb:border-1 rb:rounded-lg rb:mb-4 ${
|
||||
communityReportGeneration
|
||||
? 'rb:border-[#155EEF] rb:bg-[rgba(21,94,239,0.06)]'
|
||||
: 'rb:border-[#EBEBEB]'
|
||||
}`}>
|
||||
<div className='rb:flex rb:flex-col rb:flex-1'>
|
||||
<div className='rb:text-[#212332] rb:text-base rb:font-medium'>
|
||||
{t('knowledgeBase.communityReportGeneration')}
|
||||
</div>
|
||||
<div className='rb:text-xs rb:text-[#5B6167] rb:mt-2'>
|
||||
{t('knowledgeBase.communityReportGenerationTips')}
|
||||
</div>
|
||||
</div>
|
||||
<Form.Item
|
||||
name={['parser_config', 'graphrag', 'community']}
|
||||
valuePropName="checked"
|
||||
className='rb:mb-0'
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
// Tabs 配置
|
||||
const tabItems = [
|
||||
{
|
||||
key: 'basic',
|
||||
label: t('knowledgeBase.basicConfig'),
|
||||
children: renderBasicConfig(),
|
||||
},
|
||||
{
|
||||
key: 'knowledgeGraph',
|
||||
label: t('knowledgeBase.knowledgeGraph'),
|
||||
children: renderKnowledgeGraphConfig(),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<RbModal
|
||||
title={getTitle()}
|
||||
@@ -220,48 +532,25 @@ const CreateModal = forwardRef<CreateModalRef, CreateModalRefProps>(({
|
||||
initialValues={{
|
||||
permission_id: 'Private', // 设置 permission_id 的默认值
|
||||
type: currentType,
|
||||
parser_config: {
|
||||
graphrag: {
|
||||
use_graphrag: false, // 默认不启用知识图谱
|
||||
scene_name: '', // 场景名称
|
||||
entity_types: '' as any, // 实体类型(界面上显示为字符串,保存时转为数组)
|
||||
method: 'general', // 默认使用通用方法
|
||||
resolution: false, // 默认不启用实体归一化
|
||||
community: false, // 默认不生成社区报告
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
{/* <div className="rb:text-[14px] rb:font-medium rb:text-[#5B6167] rb:mb-[16px]">{t('model.basicParameters')}</div> */}
|
||||
{!datasets?.id && (
|
||||
<Form.Item
|
||||
name="name"
|
||||
label={t('knowledgeBase.createForm.name')}
|
||||
rules={[{ required: true, message: t('knowledgeBase.createForm.nameRequired') }]}
|
||||
>
|
||||
<Input placeholder={t('knowledgeBase.createForm.name')} />
|
||||
</Form.Item>
|
||||
)}
|
||||
<Form.Item name="description" label={t('knowledgeBase.createForm.description')}>
|
||||
<TextArea rows={2} placeholder={t('knowledgeBase.createForm.description')} />
|
||||
</Form.Item>
|
||||
|
||||
{currentType !== 'Folder' && dynamicTypeList.map((tp) => {
|
||||
const fieldKey = typeToFieldKey(tp);
|
||||
// 当 tp 为 'llm' 时,合并 llm 和 chat 的选项
|
||||
const options = tp.toLowerCase() === 'llm'
|
||||
? [...(modelOptionsByType['llm'] || []), ...(modelOptionsByType['chat'] || [])]
|
||||
: modelOptionsByType[tp] || [];
|
||||
return (
|
||||
<Form.Item
|
||||
key={tp}
|
||||
name={fieldKey as keyof KnowledgeBaseFormData}
|
||||
label={t(`knowledgeBase.createForm.${fieldKey}`) + ' ' + 'model'}
|
||||
rules={[{ required: true, message: t('knowledgeBase.createForm.modelRequired') }]}
|
||||
>
|
||||
<Select
|
||||
options={options}
|
||||
placeholder={t(`knowledgeBase.createForm.${fieldKey}`)}
|
||||
allowClear={false}
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
onChange={(value) => handleChange(value, tp)}
|
||||
/>
|
||||
</Form.Item>
|
||||
);
|
||||
})}
|
||||
|
||||
<Tabs
|
||||
activeKey={activeTab}
|
||||
onChange={setActiveTab}
|
||||
items={tabItems}
|
||||
/>
|
||||
</Form>
|
||||
{contextHolder}
|
||||
</RbModal>
|
||||
);
|
||||
});
|
||||
|
||||
451
web/src/views/KnowledgeBase/components/KnowledgeGraph.tsx
Normal file
@@ -0,0 +1,451 @@
|
||||
import React, { type FC, useEffect, useState, useRef, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Col } from 'antd'
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import ReactEcharts from 'echarts-for-react'
|
||||
import zoom from '@/assets/images/userMemory/zoom.svg'
|
||||
import drag from '@/assets/images/userMemory/drag.svg'
|
||||
import pointer from '@/assets/images/userMemory/pointer.svg'
|
||||
import empty from '@/assets/images/userMemory/empty.svg'
|
||||
import Empty from '@/components/Empty'
|
||||
|
||||
// 知识图谱数据类型定义
|
||||
export interface KnowledgeNode {
|
||||
id: string
|
||||
entity_name: string
|
||||
entity_type: string
|
||||
description: string
|
||||
pagerank: number
|
||||
source_id: string[]
|
||||
// ECharts 需要的属性
|
||||
name: string
|
||||
category: number
|
||||
symbolSize: number
|
||||
itemStyle: {
|
||||
color: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface KnowledgeEdge {
|
||||
src_id: string
|
||||
tgt_id: string
|
||||
description: string
|
||||
keywords: string[]
|
||||
weight: number
|
||||
source_id: string[]
|
||||
source: string
|
||||
target: string
|
||||
// ECharts 需要的属性
|
||||
value: number
|
||||
}
|
||||
|
||||
export interface KnowledgeGraphData {
|
||||
directed: boolean
|
||||
multigraph: boolean
|
||||
graph: {
|
||||
source_id: string[]
|
||||
}
|
||||
nodes: KnowledgeNode[]
|
||||
edges: KnowledgeEdge[]
|
||||
}
|
||||
|
||||
export interface KnowledgeGraphResponse {
|
||||
graph: KnowledgeGraphData
|
||||
mind_map: Record<string, unknown>
|
||||
}
|
||||
|
||||
interface KnowledgeGraphProps {
|
||||
data?: KnowledgeGraphResponse
|
||||
loading?: boolean
|
||||
}
|
||||
|
||||
const operations = [
|
||||
{ name: 'click', icon: pointer },
|
||||
{ name: 'drag', icon: drag },
|
||||
{ name: 'zoom', icon: zoom },
|
||||
]
|
||||
|
||||
// 预定义的颜色调色板
|
||||
const colorPalette = [
|
||||
'#155EEF', '#4DA8FF', '#9C6FFF', '#8BAEF7', '#369F21',
|
||||
'#FF5D34', '#FF8A4C', '#FFB048', '#E74C3C', '#9B59B6',
|
||||
'#3498DB', '#1ABC9C', '#F39C12', '#D35400', '#C0392B',
|
||||
'#8E44AD', '#2980B9', '#16A085', '#F1C40F', '#E67E22'
|
||||
]
|
||||
|
||||
// 动态生成实体类型颜色映射
|
||||
const generateEntityTypeColors = (entityTypes: string[]): Record<string, string> => {
|
||||
const colorMap: Record<string, string> = {}
|
||||
entityTypes.forEach((type, index) => {
|
||||
colorMap[type] = colorPalette[index % colorPalette.length]
|
||||
})
|
||||
return colorMap
|
||||
}
|
||||
|
||||
const KnowledgeGraph: FC<KnowledgeGraphProps> = ({ data, loading = false }) => {
|
||||
const { t } = useTranslation()
|
||||
const chartRef = useRef<ReactEcharts>(null)
|
||||
const resizeScheduledRef = useRef(false)
|
||||
const modalRef = useRef<HTMLDivElement>(null)
|
||||
const [nodes, setNodes] = useState<KnowledgeNode[]>([])
|
||||
const [links, setLinks] = useState<KnowledgeEdge[]>([])
|
||||
const [categories, setCategories] = useState<{ name: string }[]>([])
|
||||
const [selectedNode, setSelectedNode] = useState<KnowledgeNode | null>(null)
|
||||
const [entityTypeColors, setEntityTypeColors] = useState<Record<string, string>>({})
|
||||
|
||||
// 弹框拖动相关状态
|
||||
const [modalPosition, setModalPosition] = useState({ x: 20, y: 20 })
|
||||
const [isDragging, setIsDragging] = useState(false)
|
||||
const [dragStart, setDragStart] = useState({ x: 0, y: 0 })
|
||||
|
||||
// 拖动处理函数
|
||||
const handleMouseDown = useCallback((e: React.MouseEvent) => {
|
||||
setIsDragging(true)
|
||||
setDragStart({
|
||||
x: e.clientX - modalPosition.x,
|
||||
y: e.clientY - modalPosition.y
|
||||
})
|
||||
}, [modalPosition])
|
||||
|
||||
const handleMouseMove = useCallback((e: MouseEvent) => {
|
||||
if (!isDragging) return
|
||||
|
||||
const newX = e.clientX - dragStart.x
|
||||
const newY = e.clientY - dragStart.y
|
||||
|
||||
// 限制拖动范围,确保弹框不会超出容器
|
||||
const container = chartRef.current?.getEchartsInstance().getDom().parentElement
|
||||
if (container && modalRef.current) {
|
||||
const containerRect = container.getBoundingClientRect()
|
||||
const modalRect = modalRef.current.getBoundingClientRect()
|
||||
|
||||
const maxX = containerRect.width - modalRect.width
|
||||
const maxY = containerRect.height - modalRect.height
|
||||
|
||||
setModalPosition({
|
||||
x: Math.max(0, Math.min(newX, maxX)),
|
||||
y: Math.max(0, Math.min(newY, maxY))
|
||||
})
|
||||
}
|
||||
}, [isDragging, dragStart])
|
||||
|
||||
const handleMouseUp = useCallback(() => {
|
||||
setIsDragging(false)
|
||||
}, [])
|
||||
|
||||
// 添加全局鼠标事件监听
|
||||
useEffect(() => {
|
||||
if (isDragging) {
|
||||
document.addEventListener('mousemove', handleMouseMove)
|
||||
document.addEventListener('mouseup', handleMouseUp)
|
||||
return () => {
|
||||
document.removeEventListener('mousemove', handleMouseMove)
|
||||
document.removeEventListener('mouseup', handleMouseUp)
|
||||
}
|
||||
}
|
||||
}, [isDragging, handleMouseMove, handleMouseUp])
|
||||
|
||||
// 关闭弹框
|
||||
const handleCloseModal = useCallback(() => {
|
||||
setSelectedNode(null)
|
||||
}, [])
|
||||
|
||||
// 处理知识图谱数据
|
||||
const processGraphData = useCallback(() => {
|
||||
if (!data?.graph) {
|
||||
setNodes([])
|
||||
setLinks([])
|
||||
setCategories([])
|
||||
setSelectedNode(null)
|
||||
return
|
||||
}
|
||||
|
||||
const { nodes: rawNodes, edges: rawEdges } = data.graph
|
||||
const processedNodes: KnowledgeNode[] = []
|
||||
const processedEdges: KnowledgeEdge[] = []
|
||||
|
||||
// 获取所有实体类型
|
||||
const entityTypes = [...new Set(rawNodes.map(node => node.entity_type))]
|
||||
const categoryMap = entityTypes.reduce((acc, type, index) => {
|
||||
acc[type] = index
|
||||
return acc
|
||||
}, {} as Record<string, number>)
|
||||
|
||||
// 动态生成实体类型颜色映射
|
||||
const dynamicEntityTypeColors = generateEntityTypeColors(entityTypes)
|
||||
setEntityTypeColors(dynamicEntityTypeColors)
|
||||
|
||||
// 计算每个节点的连接数
|
||||
const connectionCount: Record<string, number> = {}
|
||||
rawEdges.forEach(edge => {
|
||||
// 使用 src_id 和 tgt_id 计算连接数
|
||||
connectionCount[edge.src_id] = (connectionCount[edge.src_id] || 0) + 1
|
||||
connectionCount[edge.tgt_id] = (connectionCount[edge.tgt_id] || 0) + 1
|
||||
})
|
||||
|
||||
// 处理节点数据
|
||||
rawNodes.forEach(node => {
|
||||
const connections = connectionCount[node.id] || 0
|
||||
const categoryIndex = categoryMap[node.entity_type] || 0
|
||||
|
||||
// 根据 pagerank 和连接数计算节点大小
|
||||
let symbolSize = Math.max(10, Math.min(50, node.pagerank * 200 + connections * 2))
|
||||
|
||||
processedNodes.push({
|
||||
...node,
|
||||
name: node.entity_name,
|
||||
category: categoryIndex,
|
||||
symbolSize,
|
||||
itemStyle: {
|
||||
color: dynamicEntityTypeColors[node.entity_type] || colorPalette[0]
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// 处理边数据
|
||||
rawEdges.forEach(edge => {
|
||||
// 注意:根据数据结构,source 和 target 字段可能与 src_id 和 tgt_id 相反
|
||||
// 我们使用 src_id 和 tgt_id 作为正确的连接关系
|
||||
processedEdges.push({
|
||||
...edge, // 保留所有原始字段
|
||||
source: edge.src_id, // 使用 src_id 作为源节点
|
||||
target: edge.tgt_id, // 使用 tgt_id 作为目标节点
|
||||
value: edge.weight || 1
|
||||
})
|
||||
})
|
||||
|
||||
// 验证节点ID和边的连接
|
||||
const nodeIds = new Set(processedNodes.map(n => n.id))
|
||||
const validEdges = processedEdges.filter(edge => {
|
||||
const sourceExists = nodeIds.has(edge.source)
|
||||
const targetExists = nodeIds.has(edge.target)
|
||||
if (!sourceExists || !targetExists) {
|
||||
console.warn('Invalid edge:', edge, 'Source exists:', sourceExists, 'Target exists:', targetExists)
|
||||
}
|
||||
return sourceExists && targetExists
|
||||
})
|
||||
|
||||
// 调试信息
|
||||
console.log('Total nodes:', processedNodes.length)
|
||||
console.log('Total edges:', processedEdges.length)
|
||||
console.log('Valid edges:', validEdges.length)
|
||||
console.log('Node IDs:', Array.from(nodeIds).slice(0, 5))
|
||||
console.log('Edge sample:', validEdges.slice(0, 3))
|
||||
|
||||
// 设置分类
|
||||
const processedCategories = entityTypes.map(type => ({ name: type }))
|
||||
|
||||
setNodes(processedNodes)
|
||||
setLinks(validEdges) // 只使用有效的边
|
||||
setCategories(processedCategories)
|
||||
}, [data])
|
||||
|
||||
useEffect(() => {
|
||||
processGraphData()
|
||||
}, [processGraphData])
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
if (chartRef.current && !resizeScheduledRef.current) {
|
||||
resizeScheduledRef.current = true
|
||||
requestAnimationFrame(() => {
|
||||
chartRef.current?.getEchartsInstance().resize()
|
||||
resizeScheduledRef.current = false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver(handleResize)
|
||||
const chartElement = chartRef.current?.getEchartsInstance().getDom().parentElement
|
||||
if (chartElement) {
|
||||
resizeObserver.observe(chartElement)
|
||||
}
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect()
|
||||
}
|
||||
}, [nodes])
|
||||
|
||||
return (
|
||||
<Col span={24}>
|
||||
<RbCard
|
||||
title={t('knowledgeBase.knowledgeGraph')}
|
||||
headerType="borderless"
|
||||
headerClassName="rb:text-[18px]! rb:leading-[24px]"
|
||||
>
|
||||
<div className="rb:h-124 rb:relative">
|
||||
{loading ? (
|
||||
<div className="rb:h-full rb:flex rb:items-center rb:justify-center">
|
||||
<div className="rb:text-[#5B6167]">加载中...</div>
|
||||
</div>
|
||||
) : nodes.length === 0 ? (
|
||||
<Empty className="rb:h-full" />
|
||||
) : (
|
||||
<>
|
||||
<ReactEcharts
|
||||
ref={chartRef}
|
||||
option={{
|
||||
colors: Object.values(entityTypeColors),
|
||||
tooltip: {
|
||||
show: true,
|
||||
formatter: (params: any) => {
|
||||
if (params.dataType === 'node') {
|
||||
const node = params.data as KnowledgeNode
|
||||
return `
|
||||
<div>
|
||||
<div><strong>${node.entity_name}</strong></div>
|
||||
<div>类型: ${node.entity_type}</div>
|
||||
<div>重要度: ${(node.pagerank * 100).toFixed(2)}%</div>
|
||||
</div>
|
||||
`
|
||||
} else if (params.dataType === 'edge') {
|
||||
const edge = params.data as KnowledgeEdge
|
||||
return `
|
||||
<div>
|
||||
<div><strong>关系</strong></div>
|
||||
<div>权重: ${edge.weight}</div>
|
||||
<div>${edge.description}</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
return ''
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: categories.map(cat => cat.name),
|
||||
orient: 'vertical',
|
||||
left: 'right',
|
||||
top: 'center'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'graph',
|
||||
layout: 'force',
|
||||
data: nodes,
|
||||
links: links,
|
||||
categories: categories,
|
||||
roam: true,
|
||||
label: {
|
||||
show: true,
|
||||
position: 'right',
|
||||
formatter: '{b}',
|
||||
fontSize: 12
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#5B6167',
|
||||
curveness: 0.3,
|
||||
width: 2, // 固定线宽,避免函数问题
|
||||
opacity: 0.8
|
||||
},
|
||||
force: {
|
||||
repulsion: 300,
|
||||
edgeLength: 150,
|
||||
gravity: 0.1,
|
||||
layoutAnimation: true,
|
||||
preventOverlap: true
|
||||
},
|
||||
selectedMode: 'single',
|
||||
draggable: true,
|
||||
animationDurationUpdate: 0,
|
||||
select: {
|
||||
itemStyle: {
|
||||
borderWidth: 2,
|
||||
borderColor: '#ffffff',
|
||||
shadowBlur: 10,
|
||||
}
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'adjacency',
|
||||
lineStyle: {
|
||||
width: 3
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}}
|
||||
style={{ height: '496px', width: '100%' }}
|
||||
notMerge={false}
|
||||
lazyUpdate={true}
|
||||
onEvents={{
|
||||
click: (params: { dataType: string; data: KnowledgeNode }) => {
|
||||
if (params.dataType === 'node') {
|
||||
console.log('Knowledge node clicked:', params.data)
|
||||
setSelectedNode(params.data)
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 实体详情弹框 */}
|
||||
{selectedNode && (
|
||||
<div
|
||||
ref={modalRef}
|
||||
className="rb:absolute rb:bg-white rb:border rb:border-[#EBEBEB] rb:rounded-[12px] rb:shadow-lg rb:p-4 rb:w-80 rb:z-10"
|
||||
style={{
|
||||
left: modalPosition.x,
|
||||
top: modalPosition.y,
|
||||
cursor: isDragging ? 'grabbing' : 'grab'
|
||||
}}
|
||||
>
|
||||
{/* 弹框头部 - 可拖动区域 */}
|
||||
<div
|
||||
className="rb:flex rb:items-center rb:justify-between rb:mb-3 rb:pb-2 rb:border-b rb:border-[#EBEBEB] rb:cursor-grab"
|
||||
onMouseDown={handleMouseDown}
|
||||
style={{ cursor: isDragging ? 'grabbing' : 'grab' }}
|
||||
>
|
||||
<div className="rb:text-[16px] rb:font-medium rb:text-[#1A1A1A]">
|
||||
{t('knowledgeBase.entityDetails')}
|
||||
</div>
|
||||
<button
|
||||
onClick={handleCloseModal}
|
||||
className="rb:w-6 rb:h-6 rb:flex rb:items-center rb:justify-center rb:text-[#5B6167] hover:rb:text-[#1A1A1A] hover:rb:bg-[#F0F3F8] rb:rounded rb:transition-colors"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 弹框内容 */}
|
||||
<div>
|
||||
<div className="rb:font-medium rb:mb-4">
|
||||
<div className="rb:text-[16px] rb:mb-2">{selectedNode.entity_name}</div>
|
||||
<div className="rb:text-[12px] rb:text-[#5B6167] rb:mb-2">
|
||||
<span className="rb:inline-block rb:px-2 rb:py-1 rb:bg-[#F0F3F8] rb:rounded rb:mr-2">
|
||||
{selectedNode.entity_type}
|
||||
</span>
|
||||
<span>重要度: {(selectedNode.pagerank * 100).toFixed(2)}%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rb:font-medium rb:mb-4">
|
||||
{t('knowledgeBase.entityDescription')}
|
||||
<div className="rb:text-[12px] rb:text-[#5B6167] rb:mt-2 rb:leading-5">
|
||||
{selectedNode.description}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rb:font-medium rb:mb-2">
|
||||
{t('knowledgeBase.sourceDocuments')}
|
||||
<div className="rb:text-[12px] rb:text-[#5B6167] rb:mt-2">
|
||||
{selectedNode.source_id.length} 个文档
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="rb:bg-[#F0F3F8] rb:flex rb:items-center rb:gap-6 rb:rounded-[0px_0px_12px_12px] rb:p-[14px_40px] rb:m-[0_-20px_-16px_-16px]">
|
||||
{operations.map((item) => (
|
||||
<div key={item.name} className="rb:flex rb:items-center rb:text-[#5B6167] rb:leading-5">
|
||||
<img src={item.icon} className="rb:w-5 rb:h-5 rb:mr-1" />
|
||||
{t(`userMemory.${item.name}`)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</RbCard>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(KnowledgeGraph)
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* @Description:
|
||||
* @Version: 0.0.1
|
||||
* @Author: yujiangping
|
||||
* @Date: 2025-12-30 15:07:37
|
||||
* @LastEditors: yujiangping
|
||||
* @LastEditTime: 2026-01-04 20:15:12
|
||||
*/
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Row } from 'antd'
|
||||
import KnowledgeGraph, { type KnowledgeGraphResponse } from './KnowledgeGraph'
|
||||
import { getKnowledgeGraph } from '@/api/knowledgeBase';
|
||||
|
||||
interface KnowledgeGraphCardProps {
|
||||
knowledgeBaseId?: string;
|
||||
}
|
||||
|
||||
const KnowledgeGraphCard: React.FC<KnowledgeGraphCardProps> = ({ knowledgeBaseId }) => {
|
||||
const { t } = useTranslation();
|
||||
const [data, setData] = useState<KnowledgeGraphResponse | undefined>()
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
if (!knowledgeBaseId) {
|
||||
setLoading(false)
|
||||
return
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
try {
|
||||
const res = await getKnowledgeGraph(knowledgeBaseId)
|
||||
setData(res as KnowledgeGraphResponse)
|
||||
} catch (error) {
|
||||
console.error('获取知识图谱数据失败:', error)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
fetchData()
|
||||
}, [knowledgeBaseId])
|
||||
|
||||
return (
|
||||
<div className='rb:flex rb:flex-col'>
|
||||
<div className='rb:flex rb:flex-col rb:p-4'>
|
||||
<div className='rb:w-full rb:text-lg rb:font-medium rb:text-[#212332] rb:leading-6'>
|
||||
{t('knowledgeBase.graphTitle')}
|
||||
</div>
|
||||
<div className='rb:w-full rb:text-xs rb:text-[#5B6167] rb:leading-4 rb:mt-2'>
|
||||
{t('knowledgeBase.graphTips')}
|
||||
</div>
|
||||
<div className='rb:flex rb:items-center rb:justify-between'>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className='rb:p-4'>
|
||||
<KnowledgeGraph data={data} loading={loading} />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default KnowledgeGraphCard
|
||||
163
web/src/views/KnowledgeBase/components/README.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# KnowledgeGraph 组件
|
||||
|
||||
基于 ECharts 的知识图谱可视化组件,用于展示知识库中实体之间的关系网络。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- 🎯 **交互式图谱**: 支持节点点击、拖拽、缩放等交互操作
|
||||
- 🎨 **实体分类**: 根据实体类型自动分配颜色和图例
|
||||
- 📊 **智能布局**: 基于力导向算法的自动布局
|
||||
- 🔍 **详情展示**: 点击节点查看实体详细信息
|
||||
- 📱 **响应式设计**: 自适应容器大小变化
|
||||
- 🌐 **国际化支持**: 支持中英文切换
|
||||
|
||||
## 数据结构
|
||||
|
||||
### KnowledgeGraphResponse
|
||||
```typescript
|
||||
interface KnowledgeGraphResponse {
|
||||
code: number
|
||||
msg: string
|
||||
data: {
|
||||
graph: KnowledgeGraphData
|
||||
mind_map: Record<string, unknown>
|
||||
}
|
||||
error: string
|
||||
time: number
|
||||
}
|
||||
```
|
||||
|
||||
### KnowledgeNode
|
||||
```typescript
|
||||
interface KnowledgeNode {
|
||||
id: string // 节点唯一标识
|
||||
entity_name: string // 实体名称
|
||||
entity_type: string // 实体类型 (ORGANIZATION, PERSON, EVENT, CATEGORY, etc.)
|
||||
description: string // 实体描述
|
||||
pagerank: number // PageRank 重要度分数
|
||||
source_id: string[] // 来源文档ID列表
|
||||
}
|
||||
```
|
||||
|
||||
### KnowledgeEdge
|
||||
```typescript
|
||||
interface KnowledgeEdge {
|
||||
src_id: string // 源节点ID
|
||||
tgt_id: string // 目标节点ID
|
||||
description: string // 关系描述
|
||||
keywords: string[] // 关键词
|
||||
weight: number // 关系权重
|
||||
source_id: string[] // 来源文档ID列表
|
||||
source: string // 源节点名称
|
||||
target: string // 目标节点名称
|
||||
}
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 基础用法
|
||||
|
||||
```tsx
|
||||
import KnowledgeGraph from './components/KnowledgeGraph'
|
||||
|
||||
const MyComponent = () => {
|
||||
const [graphData, setGraphData] = useState<KnowledgeGraphResponse>()
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
return (
|
||||
<KnowledgeGraph
|
||||
data={graphData}
|
||||
loading={loading}
|
||||
/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### 完整示例
|
||||
|
||||
```tsx
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { Row } from 'antd'
|
||||
import KnowledgeGraph from './components/KnowledgeGraph'
|
||||
|
||||
const KnowledgeBasePage = () => {
|
||||
const [data, setData] = useState()
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
const fetchKnowledgeGraph = async () => {
|
||||
setLoading(true)
|
||||
try {
|
||||
const response = await api.getKnowledgeGraph(knowledgeBaseId)
|
||||
setData(response)
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch knowledge graph:', error)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
fetchKnowledgeGraph()
|
||||
}, [knowledgeBaseId])
|
||||
|
||||
return (
|
||||
<Row gutter={[16, 16]}>
|
||||
<KnowledgeGraph data={data} loading={loading} />
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## 组件属性
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| data | KnowledgeGraphResponse | undefined | 知识图谱数据 |
|
||||
| loading | boolean | false | 加载状态 |
|
||||
|
||||
## 实体类型颜色
|
||||
|
||||
组件内置了以下实体类型的颜色映射:
|
||||
|
||||
- `ORGANIZATION`: #155EEF (蓝色)
|
||||
- `PERSON`: #4DA8FF (浅蓝色)
|
||||
- `EVENT`: #9C6FFF (紫色)
|
||||
- `CATEGORY`: #8BAEF7 (淡蓝色)
|
||||
- `LOCATION`: #369F21 (绿色)
|
||||
- `TIME`: #FF5D34 (橙红色)
|
||||
- `CONCEPT`: #FF8A4C (橙色)
|
||||
- `OTHER`: #FFB048 (黄色)
|
||||
|
||||
## 交互功能
|
||||
|
||||
1. **节点点击**: 点击节点查看实体详细信息
|
||||
2. **拖拽**: 拖拽节点调整位置
|
||||
3. **缩放**: 鼠标滚轮缩放图谱
|
||||
4. **悬停**: 悬停显示节点和边的详细信息
|
||||
5. **高亮**: 点击节点高亮相邻节点和边
|
||||
|
||||
## 国际化
|
||||
|
||||
组件使用以下翻译键:
|
||||
|
||||
- `knowledgeBase.knowledgeGraph`: 知识图谱标题
|
||||
- `knowledgeBase.entityDetails`: 实体详情标题
|
||||
- `knowledgeBase.entityDetailEmpty`: 空状态提示
|
||||
- `knowledgeBase.entityDetailEmptyDesc`: 空状态描述
|
||||
- `knowledgeBase.entityDescription`: 实体描述标签
|
||||
- `knowledgeBase.sourceDocuments`: 来源文档标签
|
||||
- `userMemory.click/drag/zoom`: 操作说明
|
||||
|
||||
## 性能优化
|
||||
|
||||
- 使用 `React.memo` 避免不必要的重渲染
|
||||
- 使用 `ResizeObserver` 监听容器大小变化
|
||||
- 使用 `requestAnimationFrame` 优化图表重绘
|
||||
- 延迟更新和懒加载提升大数据集性能
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 确保传入的数据结构符合 `KnowledgeGraphResponse` 接口
|
||||
2. 节点的 `pagerank` 值用于计算节点大小,建议范围在 0-1 之间
|
||||
3. 边的 `weight` 值用于计算连线粗细,建议使用正数
|
||||
4. 大数据集可能影响渲染性能,建议进行数据分页或过滤
|
||||
@@ -14,6 +14,15 @@ export interface KnowledgeBaseFormData {
|
||||
parent_id?: string; // 父ID
|
||||
type?: string; // 知识库类型
|
||||
status?: number; // 状态
|
||||
parser_config: ParserConfig; // 解析器配置
|
||||
}
|
||||
export interface GraphragConfig{
|
||||
use_graphrag:boolean; // 是否启用图谱
|
||||
scene_name: string; // 场景名称
|
||||
entity_types: Array<string>; // 实体类型
|
||||
method: string; // 方法
|
||||
resolution: boolean; // 实体归一化
|
||||
community: boolean; /// 是否生成社区报告
|
||||
}
|
||||
export interface KnowledgeBase {
|
||||
id: string;
|
||||
@@ -86,6 +95,8 @@ export interface ParserConfig {
|
||||
auto_keywords?: number; // 自动关键词
|
||||
auto_questions?: number; // 自动问题
|
||||
html4excel?: boolean; // 是否为Excel文件
|
||||
graphrag:GraphragConfig; // 知识图谱生成
|
||||
|
||||
}
|
||||
// 文件数据
|
||||
export interface KnowledgeBaseDocumentData { // 知识库文档数据
|
||||
|
||||