From e12f95510502a4fe7014f2bfc0dfa44ba68f38b0 Mon Sep 17 00:00:00 2001 From: zhangkai <17600160566@163.com> Date: Mon, 12 Aug 2024 11:27:32 +0800 Subject: [PATCH] 1 --- .DS_Store | Bin 10244 -> 10244 bytes build/assets/icon1-22423762.png | Bin 4481 -> 0 bytes build/assets/icon1-active-e898a63f.png | Bin 10710 -> 0 bytes build/assets/icon2-0a5dbb41.png | Bin 10482 -> 0 bytes build/assets/icon2-active-eae32509.png | Bin 19215 -> 0 bytes build/assets/icon3-active-56cabe9a.png | Bin 12328 -> 0 bytes build/assets/icon4-active-78d00c9a.png | Bin 8589 -> 0 bytes build/assets/icon5-187cba94.png | Bin 4256 -> 0 bytes build/assets/icon5-active-52a6d7fe.png | Bin 10443 -> 0 bytes build/index.html | 26 +- build/locales/en/bs.json | 122 +++- build/locales/zh/bs.json | 129 ++++- package-lock.json | 520 +++++++++++++++++- package.json | 3 + public/locales/en/bs.json | 122 +++- public/locales/zh/bs.json | 129 ++++- src/.DS_Store | Bin 10244 -> 10244 bytes .../components/parameterComponent/index.tsx | 130 +++-- src/assets/.DS_Store | Bin 10244 -> 10244 bytes src/assets/Login/.DS_Store | Bin 6148 -> 6148 bytes src/assets/Login/reset.png | Bin 0 -> 59994 bytes src/assets/nav/.DS_Store | Bin 6148 -> 8196 bytes src/assets/nav/admin.png | Bin 0 -> 2472 bytes src/assets/nav/admin1.png | Bin 0 -> 536 bytes src/assets/nav/icon1-active.png | Bin 10710 -> 8713 bytes src/assets/nav/icon1.png | Bin 4481 -> 3841 bytes src/assets/nav/icon2-active.png | Bin 19215 -> 14335 bytes src/assets/nav/icon2.png | Bin 10482 -> 7499 bytes src/assets/nav/icon3-active.png | Bin 12328 -> 10099 bytes src/assets/nav/icon3.png | Bin 3923 -> 3291 bytes src/assets/nav/icon4-active.png | Bin 8589 -> 7445 bytes src/assets/nav/icon4.png | Bin 2815 -> 2559 bytes src/assets/nav/icon5-active.png | Bin 10443 -> 11075 bytes src/assets/nav/icon5.png | Bin 4256 -> 4198 bytes src/assets/nav/icon6-active.png | Bin 0 -> 8044 bytes src/assets/nav/icon6.png | Bin 0 -> 3305 bytes src/assets/nav/icon7-active.png | Bin 0 -> 10172 bytes src/assets/nav/icon7.png | Bin 0 -> 3060 bytes src/assets/nav/mima.png | Bin 0 -> 783 bytes src/assets/nav/tuichu.png | Bin 0 -> 664 bytes src/components/.DS_Store | Bin 10244 -> 10244 bytes src/components/VariablesComponent/index.tsx | 11 +- src/components/bs-comp/.DS_Store | Bin 0 -> 6148 bytes .../bs-comp/chatComponent/ChatInput.tsx | 136 +++-- .../bs-comp/chatComponent/FileBs.tsx | 4 +- .../bs-comp/chatComponent/MessageBs.tsx | 3 +- .../bs-comp/chatComponent/MessagePanne.tsx | 3 +- .../bs-comp/chatComponent/index.tsx | 17 +- .../bs-comp/chatComponent/messageStore.ts | 61 +- src/components/bs-comp/loadMore/index.tsx | 24 + .../bs-comp/selectComponent/Users.tsx | 48 ++ .../bs-comp/selectComponent/knowledge.tsx | 51 ++ .../bs-comp/sheets/SkillChatSheet.tsx | 87 ++- src/components/bs-icons/.DS_Store | Bin 0 -> 8196 bytes src/components/bs-icons/del/Del.svg | 6 +- src/components/bs-icons/del/index.tsx | 2 +- src/components/bs-icons/down/DropDown.svg | 7 + src/components/bs-icons/down/index.tsx | 9 + src/components/bs-icons/en/En.svg | 2 +- src/components/bs-icons/filter/Filter.svg | 6 + src/components/bs-icons/filter/index.tsx | 9 + src/components/bs-icons/index.ts | 40 ++ .../{ => menu}/application/Application.svg | 0 .../bs-icons/{ => menu}/application/index.tsx | 0 .../bs-icons/menu/evaluation/Evaluation.svg | 6 + .../bs-icons/menu/evaluation/index.tsx | 9 + src/components/bs-icons/menu/log/Log.svg | 6 + src/components/bs-icons/menu/log/index.tsx | 9 + .../bs-icons/{ => menu}/model/Model.svg | 0 .../bs-icons/{ => menu}/model/index.tsx | 0 .../bs-icons/{ => menu}/system/System.svg | 0 .../bs-icons/{ => menu}/system/index.tsx | 0 .../{ => menu}/technology/Technology.svg | 0 .../bs-icons/{ => menu}/technology/index.tsx | 0 src/components/bs-icons/office/index.tsx | 2 +- src/components/bs-icons/plusBox/PlusBox.svg | 21 +- .../bs-icons/questionMark/index.tsx | 2 +- src/components/bs-icons/quit/Quit-dark.svg | 8 - src/components/bs-icons/quit/Quit.svg | 17 +- src/components/bs-icons/quit/index.tsx | 12 +- src/components/bs-icons/search/Search.svg | 4 +- src/components/bs-icons/thumbs/copy.svg | 6 +- src/components/bs-icons/thumbs/copyDark.svg | 6 - src/components/bs-icons/thumbs/index.tsx | 10 +- src/components/bs-icons/thumbs/like.svg | 8 +- src/components/bs-icons/thumbs/likeDark.svg | 12 - src/components/bs-icons/thumbs/unLike.svg | 6 +- src/components/bs-icons/thumbs/unLikeDark.svg | 14 - src/components/bs-icons/upload/index.tsx | 2 +- src/components/bs-ui/.DS_Store | Bin 8196 -> 8196 bytes src/components/bs-ui/calendar/datePicker.tsx | 58 ++ src/components/bs-ui/calendar/index.tsx | 72 +++ src/components/bs-ui/dialog/index.tsx | 2 +- src/components/bs-ui/input/avator.tsx | 46 ++ src/components/bs-ui/input/index.tsx | 30 +- src/components/bs-ui/popover/index.tsx | 2 +- src/components/bs-ui/select/filter.tsx | 57 ++ src/components/bs-ui/select/hover.tsx | 23 + src/components/bs-ui/select/index.tsx | 6 +- src/components/bs-ui/select/multi.tsx | 204 +++++-- src/components/bs-ui/select/select.tsx | 44 ++ src/components/bs-ui/table/index.tsx | 6 +- src/components/bs-ui/utils.tsx | 48 +- src/components/ui/dialog.tsx | 2 +- src/components/ui/table.tsx | 2 +- src/controllers/.DS_Store | Bin 6148 -> 6148 bytes src/controllers/API/.DS_Store | Bin 0 -> 6148 bytes src/controllers/API/assistant.ts | 20 +- src/controllers/API/evaluate.ts | 67 +++ src/controllers/API/flow.ts | 4 +- src/controllers/API/index.ts | 16 +- src/controllers/API/log.ts | 56 ++ src/controllers/API/pro.ts | 93 ++++ src/controllers/API/user.ts | 140 ++++- src/controllers/request.ts | 15 + src/layout/MainLayout.tsx | 165 +++++- src/pages/.DS_Store | Bin 8196 -> 8196 bytes src/pages/ChatAppPage/chatAssitantShare.tsx | 21 + src/pages/ChatAppPage/chatShare.tsx | 168 +----- .../ChatAppPage/components/ChatPanne.tsx | 56 +- src/pages/ChatAppPage/index.tsx | 74 ++- src/pages/ChatAppPage/mobile/ChatPanneM.tsx | 68 ++- .../ChatAppPage/mobile/chatAssitantShare.tsx | 25 + src/pages/ChatAppPage/mobile/chatShareM.tsx | 15 +- src/pages/EvaluationPage/EvaluationCreate.tsx | 376 +++++++++++++ src/pages/EvaluationPage/PromptCom.tsx | 91 +++ src/pages/EvaluationPage/defaultPrompt.js | 67 +++ src/pages/EvaluationPage/index.tsx | 223 ++++++++ src/pages/EvaluationPage/types.ts | 51 ++ src/pages/LogPage/index.tsx | 226 ++++++++ src/pages/LogPage/utils/index.ts | 48 ++ src/pages/LoginPage/UserPwdModal.tsx | 90 +++ src/pages/LoginPage/icons/wxpro.svg | 18 + src/pages/LoginPage/login.tsx | 223 ++++++++ src/pages/LoginPage/loginBridge.tsx | 35 ++ src/pages/LoginPage/resetPwd.tsx | 131 +++++ src/pages/LoginPage/utils.ts | 20 + src/pages/Page403.tsx | 24 + .../components/editAssistant/Setting.tsx | 26 +- .../components/editAssistant/TestChat.tsx | 2 +- src/pages/SkillPage/editAssistant.tsx | 2 +- src/pages/SkillPage/tabAssistant.tsx | 4 + src/pages/SystemPage/.DS_Store | Bin 0 -> 6148 bytes src/pages/SystemPage/components/.DS_Store | Bin 0 -> 6148 bytes .../SystemPage/components/CreateUser.tsx | 102 ++++ src/pages/SystemPage/components/EditRole.tsx | 183 ++++-- .../SystemPage/components/EditUserGroup.tsx | 266 +++++++++ src/pages/SystemPage/components/Roles.tsx | 291 +++++++--- src/pages/SystemPage/components/UserGroup.tsx | 160 ++++++ .../SystemPage/components/UserRoleItem.tsx | 89 +++ .../SystemPage/components/UserRoleModal.tsx | 146 +++-- .../SystemPage/components/Users copy.tsx | 129 +++++ src/pages/SystemPage/components/Users.tsx | 284 +++++++--- src/pages/SystemPage/index.tsx | 34 +- src/pages/SystemPage/theme/Example.tsx | 185 +++++++ src/pages/SystemPage/theme/HSLitem.tsx | 25 + src/pages/SystemPage/theme/index.tsx | 109 ++++ src/routes.tsx | 14 +- src/routesM.tsx | 2 + src/store/assistantStore.tsx | 6 +- src/style/zk.scss | 55 +- src/types/api/user.ts | 10 + src/types/assistant/index.tsx | 2 + src/util/hook.ts | 6 +- src/util/utils.ts | 33 +- vite.config.ts | 19 +- 166 files changed, 6288 insertions(+), 991 deletions(-) delete mode 100644 build/assets/icon1-22423762.png delete mode 100644 build/assets/icon1-active-e898a63f.png delete mode 100644 build/assets/icon2-0a5dbb41.png delete mode 100644 build/assets/icon2-active-eae32509.png delete mode 100644 build/assets/icon3-active-56cabe9a.png delete mode 100644 build/assets/icon4-active-78d00c9a.png delete mode 100644 build/assets/icon5-187cba94.png delete mode 100644 build/assets/icon5-active-52a6d7fe.png create mode 100644 src/assets/Login/reset.png create mode 100644 src/assets/nav/admin.png create mode 100644 src/assets/nav/admin1.png create mode 100644 src/assets/nav/icon6-active.png create mode 100644 src/assets/nav/icon6.png create mode 100644 src/assets/nav/icon7-active.png create mode 100644 src/assets/nav/icon7.png create mode 100644 src/assets/nav/mima.png create mode 100644 src/assets/nav/tuichu.png create mode 100644 src/components/bs-comp/.DS_Store create mode 100644 src/components/bs-comp/loadMore/index.tsx create mode 100644 src/components/bs-comp/selectComponent/Users.tsx create mode 100644 src/components/bs-comp/selectComponent/knowledge.tsx create mode 100644 src/components/bs-icons/.DS_Store create mode 100644 src/components/bs-icons/down/DropDown.svg create mode 100644 src/components/bs-icons/down/index.tsx create mode 100644 src/components/bs-icons/filter/Filter.svg create mode 100644 src/components/bs-icons/filter/index.tsx create mode 100644 src/components/bs-icons/index.ts rename src/components/bs-icons/{ => menu}/application/Application.svg (100%) rename src/components/bs-icons/{ => menu}/application/index.tsx (100%) create mode 100644 src/components/bs-icons/menu/evaluation/Evaluation.svg create mode 100644 src/components/bs-icons/menu/evaluation/index.tsx create mode 100644 src/components/bs-icons/menu/log/Log.svg create mode 100644 src/components/bs-icons/menu/log/index.tsx rename src/components/bs-icons/{ => menu}/model/Model.svg (100%) rename src/components/bs-icons/{ => menu}/model/index.tsx (100%) rename src/components/bs-icons/{ => menu}/system/System.svg (100%) rename src/components/bs-icons/{ => menu}/system/index.tsx (100%) rename src/components/bs-icons/{ => menu}/technology/Technology.svg (100%) rename src/components/bs-icons/{ => menu}/technology/index.tsx (100%) delete mode 100644 src/components/bs-icons/quit/Quit-dark.svg delete mode 100644 src/components/bs-icons/thumbs/copyDark.svg delete mode 100644 src/components/bs-icons/thumbs/likeDark.svg delete mode 100644 src/components/bs-icons/thumbs/unLikeDark.svg create mode 100644 src/components/bs-ui/calendar/datePicker.tsx create mode 100644 src/components/bs-ui/calendar/index.tsx create mode 100644 src/components/bs-ui/input/avator.tsx create mode 100644 src/components/bs-ui/select/filter.tsx create mode 100644 src/components/bs-ui/select/hover.tsx create mode 100644 src/components/bs-ui/select/select.tsx create mode 100644 src/controllers/API/.DS_Store create mode 100644 src/controllers/API/evaluate.ts create mode 100644 src/controllers/API/log.ts create mode 100644 src/controllers/API/pro.ts create mode 100644 src/pages/ChatAppPage/chatAssitantShare.tsx create mode 100644 src/pages/ChatAppPage/mobile/chatAssitantShare.tsx create mode 100644 src/pages/EvaluationPage/EvaluationCreate.tsx create mode 100644 src/pages/EvaluationPage/PromptCom.tsx create mode 100644 src/pages/EvaluationPage/defaultPrompt.js create mode 100755 src/pages/EvaluationPage/index.tsx create mode 100644 src/pages/EvaluationPage/types.ts create mode 100644 src/pages/LogPage/index.tsx create mode 100644 src/pages/LogPage/utils/index.ts create mode 100644 src/pages/LoginPage/UserPwdModal.tsx create mode 100644 src/pages/LoginPage/icons/wxpro.svg create mode 100644 src/pages/LoginPage/login.tsx create mode 100644 src/pages/LoginPage/loginBridge.tsx create mode 100644 src/pages/LoginPage/resetPwd.tsx create mode 100644 src/pages/LoginPage/utils.ts create mode 100644 src/pages/Page403.tsx create mode 100644 src/pages/SystemPage/.DS_Store create mode 100644 src/pages/SystemPage/components/.DS_Store create mode 100644 src/pages/SystemPage/components/CreateUser.tsx create mode 100644 src/pages/SystemPage/components/EditUserGroup.tsx create mode 100644 src/pages/SystemPage/components/UserGroup.tsx create mode 100644 src/pages/SystemPage/components/UserRoleItem.tsx create mode 100644 src/pages/SystemPage/components/Users copy.tsx create mode 100644 src/pages/SystemPage/theme/Example.tsx create mode 100644 src/pages/SystemPage/theme/HSLitem.tsx create mode 100644 src/pages/SystemPage/theme/index.tsx diff --git a/.DS_Store b/.DS_Store index b9ff8c584e955d803a0398abb09cf0903b415db9..f166eaf1c756b88474336f7165e3700501fc3320 100644 GIT binary patch delta 82 zcmZn(XbIThFTl8Ka)3Y~k5qNFsiA?6g07*l(d5$tGK@Ww3nb(jdpC0ko@bjJBUZ{` kX<($IU}S0rlAZijOl9+Ai9+_x>Px# delta 71 zcmZn(XbIThFEBY;sFdBzQb)ni*kbZo0h!64g;X~43Z7xZDltu>kbN_Y!atVHETUJL HfJ$@$Ko}Pj diff --git a/build/assets/icon1-22423762.png b/build/assets/icon1-22423762.png deleted file mode 100644 index a1d3787829c4d68114b8bdc6ab9bd1c4f3b12e7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4481 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 diff --git a/build/assets/icon1-active-e898a63f.png b/build/assets/icon1-active-e898a63f.png deleted file mode 100644 index f519402a96756dd1388ad9d672ba48f4d96926a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10710 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 o$mkQcIaSB$bTMj0i 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 diff --git a/build/assets/icon2-active-eae32509.png b/build/assets/icon2-active-eae32509.png deleted file mode 100644 index fa7f990c30a7851a3c35ad33daa22dd674df01d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19215 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 Js!}uy{U1Lj#3TR! diff --git a/build/assets/icon5-187cba94.png b/build/assets/icon5-187cba94.png deleted file mode 100644 index f9f1e921314a3facd06c66539b51c09aac130cc4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4256 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 - - - - - - - - - NPCs - - - - - - - - - - -
- - - - \ No newline at end of file +NPCs
\ No newline at end of file diff --git a/build/locales/en/bs.json b/build/locales/en/bs.json index 125bf29..56ad2eb 100644 --- a/build/locales/en/bs.json +++ b/build/locales/en/bs.json @@ -21,25 +21,34 @@ "pleaseEnterCaptcha": "Please enter captcha" }, "menu": { - "app": "App", - "skills": "Skills", + "app": "Chat", + "user": "User", + "github": "GitHub", + "bookopen": "Document", + "skills": "Build", "knowledge": "Knowledge", + "evaluation": "Evaluation", "models": "Models", "system": "System", + "log": "Logs", "themeSwitch": "Theme Switch", "document": "Documentation", "logout": "Logout", "logoutDescription": "Log out", + "logoutContent": "Are you sure to log out", "forBestExperience": "For the best experience, please access this website on a PC", - "onlineDocumentation": "Online Documentation" + "onlineDocumentation": "Online Documentation", + "changePwd": "Password" }, "system": { "userManagement": "User Management", "roleManagement": "Role Management", + "userGroupsM": "UserGroup Management", "systemConfiguration": "System Configuration", "username": "Username", "confirmDisable": "Confirm disabling this user?", - "roleSelect": "Select Role", + "roleSelect": "Select Roles", + "userGroupsSel": "Select UserGroups", "roleList": "Role List", "confirmText": "Are you sure you want to delete", "roleName": "Role Name", @@ -52,8 +61,41 @@ "roleNamePrompt": "Role name cannot exceed 50 characters", "roleNameRequired": "Role name is required", "roleNameExists": "Role name already exists", + "groupNameExists": "UserGroup name already exists", + "groupNamePrompt": "UserGroup name cannot exceed 30 characters", + "groupNameRequired": "UserGroup name is required", "parameterConfig": "Parameter Configuration", - "language": "Language" + "language": "Language", + "assistantAuthorization": "Assistant Authorization", + "assistantName": "Assistant Name", + "userList": "User List", + "userGroupList": "UserGroup List", + "userGroup": "userGroup", + "role": "Role", + "searchUserGroups": "Search user groups", + "searchRoles": "Search roles", + "reset": "Reset", + "confirm": "Confirm", + "userGroupName": "Enter UserGroup Name", + "groupName": "UserGroup Name", + "admins": "Admin", + "flowControl": "Overall UserGroup Flow Control", + "AssistantFlowCtrl": "Assistant Flow Control", + "SkillFlowCtrl": "Skill Flow Control", + "createdBy": "CreatedBy", + "flowCtrlStrategy": "Flow control strategy", + "limit": "Limit", + "unlimited": "Unlimited", + "iconHover": "Simultaneously constrained by the overall traffic control strategy of the user group", + "maximum": "Up to", + "perMinute": "simultaneous online sessions", + "changeTime": "Modification Time", + "deleteGroup": "After deletion 【{{name}}】 will no longer exist, Do you want to delete it?", + "currentGroup": "Current UserGroup", + "defaultGroup": "DefaultGroup", + "resetPwd": "ResetPassword", + "selectGroup": "Please select a user group", + "selectRole": "Please select a role" }, "skills": { "manageTemplate": "Manage Skill Templates", @@ -303,7 +345,40 @@ "knowledgeImg": "Knowledge Base Avatar", "indexModel": "Index model", "dataUp": "Single data upper limit", - "introduce": "Introduce" + "introduce": "Introduce", + "fileUploadResult": "Out of the {{total}} files uploaded, {{failed}} failed to upload.", + "modalTitle": "File Duplicate Prompt", + "modalMessage": "The following files already exist in the knowledge base. Continuing the upload will overwrite the original files and processing strategy. Do you want to proceed with overwrite?", + "keepOriginal": "Keep Original Files", + "override": "Override", + "toolName": "ToolName" + }, + "evaluation": { + "id": "任务ID", + "filename": "测试文件名称", + "skillAssistant": "技能助手", + "status": "状态", + "score": "评测分数", + "createDate": "创建日期", + "download": "下载", + "confirmDeleteEvaluation": "确认删除该评测任务?", + "createTitle": "新建任务", + "selectLabel": "选择要评测的技能或者助手:", + "selectPlaceholder": "请选择", + "dataLabel": "测试集数据:", + "fileExpandName": "支持扩展名:", + "downloadTemplate": "下载模板文件", + "promptLabel": "评测指令文本:", + "enterExecType": "请选择要评测的技能或助手", + "enterUniqueId": "请选择技能或助手ID", + "enterVersion": "请选择技能的版本", + "enterFile": "请选择测试集数据", + "enterPrompt": "评测指令不能为空", + "fileSizeLimit": "文件大小限制在10M以内", + "evaluationCollection": "评测集合", + "tooltip": "该指令文本用于指导大模型对 ground truth 和 answer 提取要点,如无特别需求请勿修改", + "create": "创建", + "cancel": "取消" }, "code": { "editPythonCodeDescription": "Edit your Python code here. This code snippet accepts module imports and a function definition. Make sure your function returns a string.", @@ -576,6 +651,41 @@ "result": "Test Result", "outResultPlaceholder": "Click the button to output the result" }, + "resetPassword": { + "slogen": "Securely Reset Your Password", + "currentPassword": "Current Password", + "newPassword": "New Password", + "confirmNewPassword": "Confirm New Password", + "pleaseEnterCurrentPassword": "Please enter your current password.", + "pleaseEnterNewPassword": "Please enter your new password.", + "pleaseEnterConfirmPassword": "Please confirm your new password.", + "newPasswordTooShort": "New password must be at least 8 characters.", + "passwordMismatch": "The new passwords do not match.", + "resetButton": "Change Password", + "passwordResetSuccess": "Your password has been successfully reset.", + "adminResetSuccess": "Password has been successfully reset", + "resetFailed": "Pwd Reset Failed", + "notEmpty": "The new password cannot be empty" + }, + "log": { + "auditManagement": "Audit Management", + "searchButton": "Search", + "resetButton": "Reset", + "auditId": "Audit ID", + "username": "Username", + "operationTime": "Operation Time", + "systemModule": "System Module", + "operationAction": "Operation Action", + "objectType": "Operation Object Type", + "operationObject": "Operation Object", + "ipAddress": "IP Address", + "remark": "Remark", + "selectUser": "Select User", + "selectUserGroup": "Select User Group", + "startDate": "Start Date", + "endDate": "End Date", + "actionBehavior": "Action Behavior" + }, "agents": { "AgentInitializer":{ "display_name": "AgentInitializer", diff --git a/build/locales/zh/bs.json b/build/locales/zh/bs.json index b2ff614..00a08d8 100644 --- a/build/locales/zh/bs.json +++ b/build/locales/zh/bs.json @@ -14,32 +14,42 @@ "pleaseEnterAccount": "请填写账号", "pleaseEnterPassword": "请填写密码", "accountTooShort": "账号过短", - "passwordTooShort": "请填写密码,至少6位", + "passwordTooShort": "请填写密码,至少7位", "passwordError": "密码必须包含字母、数字!", "passwordMismatch": "两次密码不一致", "registrationSuccess": "注册成功,请输入密码进行登录" }, "menu": { - "app": "聊天", + "user": "用户", + "bookopen": "帮助文档", + "github": "GitHub", + "app": "会 话", "skills": "NPC", "knowledge": "知识库", - "models": "模型", - "system": "账号", + "evaluation": "评 测", + "models": "模 型", + "system": "账 号", + "log": "审 计", "themeSwitch": "主题切换", "document": "文档", "logout": "退出", "logoutDescription": "退出登录", + "logoutContent": "确认退出登录吗", "forBestExperience": "为了您的良好体验,请在 PC 端访问该网站", - "onlineDocumentation": "在线文档" + "onlineDocumentation": "在线文档", + "changePwd": "修改密码" }, "system": { - "userManagement": "用户管理", + "userManagement": "用户管理", + "userGroupsM": "用户组管理", "roleManagement": "角色管理", "systemConfiguration": "系统配置", "username": "用户名", "confirmDisable": "确认禁用该用户?", "roleSelect": "角色选择", + "userGroupsSel": "用户组选择", "roleList": "角色列表", + "userGroupList": "用户组列表", "confirmText": "是否删除", "roleName": "角色名称", "skillAuthorization": "能力授权", @@ -49,10 +59,42 @@ "usePermission": "使用权限", "managePermission": "管理权限", "roleNamePrompt": "角色名称不能超过50字符", - "roleNameRequired": "角色名称不能为空", + "roleNameRequired": "角色名称不可为空", + "groupNameExists": "用户组名称不可重复", + "groupNamePrompt": "用户组名称不能超过30字符", + "groupNameRequired": "用户组名称不可为空", "roleNameExists": "角色名称已存在", "parameterConfig": "参数配置", - "language": "语言" + "language": "语言", + "assistantAuthorization": "NPC授权", + "assistantName": "NPC名称", + "userList": "用户列表", + "userGroup": "用户组", + "role": "角色", + "searchUserGroups": "搜索用户组", + "searchRoles": "搜索角色", + "reset": "重置", + "confirm": "确认", + "userGroupName": "输入用户组名称", + "groupName": "用户组名称", + "admins": "管理员", + "flowControl": "用户组整体流量控制", + "AssistantFlowCtrl": "NPC流量控制", + "SkillFlowCtrl": "能力流量控制", + "createdBy": "创建人", + "flowCtrlStrategy": "流量控制策略", + "limit": "有限制", + "unlimited": "无限制", + "iconHover": "同时受用户组整体流量控制策略约束", + "maximum": "最多", + "perMinute": "个同时在线会话", + "changeTime": "修改时间", + "deleteGroup": "删除后 【{{name}}】 将不再存在,是否删除?", + "currentGroup": "当前用户组", + "defaultGroup": "默认用户组", + "resetPwd": "重置密码", + "selectGroup": "请选择用户组", + "selectRole": "请选择角色" }, "skills": { "manageTemplate": "管理能力模板", @@ -295,7 +337,41 @@ "knowledgeImg": "知识库头像", "indexModel": "索引模型", "dataUp": "单条数据上限", - "introduce": "介绍" + "introduce": "介绍", + "fileUploadResult": "共上传 {{total}} 份文件,有 {{failed}} 份文件上传失败", + "modalTitle": "文件重复提示", + "modalMessage": "以下文件在知识库中已存在,继续上传将会覆盖原有文件以及处理策略,是否覆盖?", + "keepOriginal": "不覆盖,保留原文件", + "override": "覆盖", + "toolName": "工具名称" + }, + "evaluation": { + "id": "任务ID", + "filename": "测试文件名称", + "skillAssistant": "能力NPC", + "status": "状态", + "score": "评测分数", + "createDate": "创建日期", + "download": "下载", + "confirmDeleteEvaluation": "确认删除该评测任务?", + "createTitle": "新建任务", + "selectLabel": "选择要评测的能力或者NPC:", + "selectPlaceholder": "请选择", + "selectInputPlaceholder": "请根据名称进行搜索", + "dataLabel": "测试集数据:", + "fileExpandName": "支持扩展名:", + "downloadTemplate": "下载模板文件", + "promptLabel": "评测指令文本:", + "enterExecType": "请选择要评测的能力或NPC", + "enterUniqueId": "请选择能力或NPCID", + "enterVersion": "请选择能力的版本", + "enterFile": "请选择测试集数据", + "enterPrompt": "评测指令不能为空", + "fileSizeLimit": "文件大小限制在10M以内", + "evaluationCollection": "评测集合", + "tooltip": "该指令文本用于指导大模型对 ground truth 和 answer 提取要点,如无特别需求请勿修改", + "create": "创建", + "cancel": "取消" }, "code": { "editPythonCodeDescription": "编辑你的 Python 代码此代码片段接受模块导入和一个函数定义。确保您的函数返回一个字符串。", @@ -568,6 +644,41 @@ "result": "测试结果", "outResultPlaceholder": "点击按钮,输出结果" }, + "resetPassword": { + "slogen": "安全地重置您的密码", + "currentPassword": "当前密码", + "newPassword": "新密码", + "confirmNewPassword": "确认新密码", + "pleaseEnterCurrentPassword": "请输入当前密码。", + "pleaseEnterNewPassword": "请输入新密码。", + "pleaseEnterConfirmPassword": "请确认新密码。", + "newPasswordTooShort": "新密码必须至少 7 个字符。", + "passwordMismatch": "新密码不匹配。", + "resetButton": "修改密码", + "passwordResetSuccess": "您的密码已成功修改", + "adminResetSuccess": "密码已重置", + "resetFailed": "密码重置失败", + "notEmpty": "新密码不能为空" + }, + "log": { + "auditManagement": "审计管理", + "searchButton": "查询", + "resetButton": "重置", + "auditId": "审计ID", + "username": "用户名", + "operationTime": "操作时间", + "systemModule": "系统模块", + "operationAction": "操作行为", + "objectType": "操作对象类型", + "operationObject": "操作对象", + "ipAddress": "IP地址", + "remark": "备注", + "selectUser": "选择用户", + "selectUserGroup": "选择用户组", + "startDate": "开始日期", + "endDate": "结束日期", + "actionBehavior": "操作行为" + }, "agents": { "AgentInitializer": { "display_name": "AgentInitializer", diff --git a/package-lock.json b/package-lock.json index edfd2da..1e836b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,7 +61,9 @@ "react": "^18.2.0", "react-ace": "^10.1.0", "react-beautiful-dnd": "^13.1.1", + "react-color": "^2.19.3", "react-cookie": "^4.1.1", + "react-day-picker": "^8.10.1", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", "react-error-boundary": "^4.0.11", @@ -115,6 +117,7 @@ "tailwindcss": "^3.3.3", "typescript": "^5.2.2", "vite": "^4.5.2", + "vite-plugin-html": "^3.2.2", "vite-plugin-static-copy": "^0.17.0" }, "engines": { @@ -1283,6 +1286,14 @@ "react": ">= 16" } }, + "node_modules/@icons/material": { + "version": "0.2.4", + "resolved": "https://registry.npmmirror.com/@icons/material/-/material-0.2.4.tgz", + "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1401,6 +1412,16 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "devOptional": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", @@ -4950,6 +4971,12 @@ "node": ">=8" } }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmmirror.com/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true + }, "node_modules/async-validator": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", @@ -5284,6 +5311,12 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -5432,6 +5465,16 @@ "node": ">=6" } }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -5615,6 +5658,27 @@ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmmirror.com/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -5975,6 +6039,12 @@ "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -6014,7 +6084,22 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "optional": true + "devOptional": true + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmmirror.com/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", + "dev": true }, "node_modules/console-control-strings": { "version": "1.1.0", @@ -6115,6 +6200,22 @@ "tiny-invariant": "^1.0.6" } }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/css-selector-tokenizer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz", @@ -6124,6 +6225,18 @@ "fastparse": "^1.1.2" } }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", @@ -6401,6 +6514,16 @@ "node": ">=12" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", @@ -6702,6 +6825,32 @@ "csstype": "^3.0.2" } }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, "node_modules/domexception": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", @@ -6714,11 +6863,40 @@ "node": ">=12" } }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmmirror.com/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, "node_modules/dompurify": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.1.tgz", "integrity": "sha512-tVP8C/GJwnABOn/7cx/ymx/hXpmBfWIPihC1aOEvS8GbMqy3pgeYtJk1HXN3CO7tu+8bpY18f6isjR5Cymj0TQ==" }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmmirror.com/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", @@ -6728,6 +6906,27 @@ "tslib": "^2.0.3" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "8.0.3", + "resolved": "https://registry.npmmirror.com/dotenv-expand/-/dotenv-expand-8.0.3.tgz", + "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -6778,6 +6977,21 @@ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmmirror.com/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.750", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz", @@ -7177,6 +7391,27 @@ "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/filename-reserved-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", @@ -8168,6 +8403,15 @@ "node": ">=0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -8200,6 +8444,36 @@ "node": ">=12" } }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/html-parse-stringify": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", @@ -8909,6 +9183,46 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmmirror.com/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jake/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/jest-diff": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", @@ -9432,6 +9746,11 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/material-colors": { + "version": "1.2.6", + "resolved": "https://registry.npmmirror.com/material-colors/-/material-colors-1.2.6.tgz", + "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==" + }, "node_modules/mathjax-full": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz", @@ -11789,6 +12108,16 @@ } } }, + "node_modules/node-html-parser": { + "version": "5.4.2", + "resolved": "https://registry.npmmirror.com/node-html-parser/-/node-html-parser-5.4.2.tgz", + "integrity": "sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==", + "dev": true, + "dependencies": { + "css-select": "^4.2.1", + "he": "1.2.0" + } + }, "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", @@ -11862,6 +12191,18 @@ "set-blocking": "^2.0.0" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/nwsapi": { "version": "2.2.9", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", @@ -12080,6 +12421,16 @@ "node": ">=4" } }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -12147,6 +12498,16 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -12215,6 +12576,12 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/pathe/-/pathe-0.2.0.tgz", + "integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==", + "dev": true + }, "node_modules/pdfjs-dist": { "version": "3.10.111", "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.10.111.tgz", @@ -13432,6 +13799,23 @@ "react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-color": { + "version": "2.19.3", + "resolved": "https://registry.npmmirror.com/react-color/-/react-color-2.19.3.tgz", + "integrity": "sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==", + "dependencies": { + "@icons/material": "^0.2.4", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15", + "material-colors": "^1.2.1", + "prop-types": "^15.5.10", + "reactcss": "^1.2.0", + "tinycolor2": "^1.4.1" + }, + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-colorful": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", @@ -13454,6 +13838,19 @@ "react": ">= 16.3.0" } }, + "node_modules/react-day-picker": { + "version": "8.10.1", + "resolved": "https://registry.npmmirror.com/react-day-picker/-/react-day-picker-8.10.1.tgz", + "integrity": "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/gpbl" + }, + "peerDependencies": { + "date-fns": "^2.28.0 || ^3.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -13859,6 +14256,14 @@ "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/reactcss": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/reactcss/-/reactcss-1.2.3.tgz", + "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==", + "dependencies": { + "lodash": "^4.0.1" + } + }, "node_modules/reactflow": { "version": "11.11.2", "resolved": "https://registry.npmjs.org/reactflow/-/reactflow-11.11.2.tgz", @@ -14149,6 +14554,15 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmmirror.com/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/remark-breaks": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-breaks/-/remark-breaks-4.0.0.tgz", @@ -15308,6 +15722,31 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "devOptional": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "devOptional": true + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", @@ -15791,6 +16230,30 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "optional": true }, + "node_modules/terser": { + "version": "5.31.3", + "resolved": "https://registry.npmmirror.com/terser/-/terser-5.31.3.tgz", + "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", + "devOptional": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "devOptional": true + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -15845,6 +16308,11 @@ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -16487,6 +16955,56 @@ } } }, + "node_modules/vite-plugin-html": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/vite-plugin-html/-/vite-plugin-html-3.2.2.tgz", + "integrity": "sha512-vb9C9kcdzcIo/Oc3CLZVS03dL5pDlOFuhGlZYDCJ840BhWl/0nGeZWf3Qy7NlOayscY4Cm/QRgULCQkEZige5Q==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^4.2.0", + "colorette": "^2.0.16", + "connect-history-api-fallback": "^1.6.0", + "consola": "^2.15.3", + "dotenv": "^16.0.0", + "dotenv-expand": "^8.0.2", + "ejs": "^3.1.6", + "fast-glob": "^3.2.11", + "fs-extra": "^10.0.1", + "html-minifier-terser": "^6.1.0", + "node-html-parser": "^5.3.3", + "pathe": "^0.2.0" + }, + "peerDependencies": { + "vite": ">=2.0.0" + } + }, + "node_modules/vite-plugin-html/node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/vite-plugin-html/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/vite-plugin-static-copy": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-0.17.1.tgz", diff --git a/package.json b/package.json index c3aa430..511c5fe 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,9 @@ "react": "^18.2.0", "react-ace": "^10.1.0", "react-beautiful-dnd": "^13.1.1", + "react-color": "^2.19.3", "react-cookie": "^4.1.1", + "react-day-picker": "^8.10.1", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", "react-error-boundary": "^4.0.11", @@ -136,6 +138,7 @@ "tailwindcss": "^3.3.3", "typescript": "^5.2.2", "vite": "^4.5.2", + "vite-plugin-html": "^3.2.2", "vite-plugin-static-copy": "^0.17.0" }, "engines": { diff --git a/public/locales/en/bs.json b/public/locales/en/bs.json index 125bf29..56ad2eb 100644 --- a/public/locales/en/bs.json +++ b/public/locales/en/bs.json @@ -21,25 +21,34 @@ "pleaseEnterCaptcha": "Please enter captcha" }, "menu": { - "app": "App", - "skills": "Skills", + "app": "Chat", + "user": "User", + "github": "GitHub", + "bookopen": "Document", + "skills": "Build", "knowledge": "Knowledge", + "evaluation": "Evaluation", "models": "Models", "system": "System", + "log": "Logs", "themeSwitch": "Theme Switch", "document": "Documentation", "logout": "Logout", "logoutDescription": "Log out", + "logoutContent": "Are you sure to log out", "forBestExperience": "For the best experience, please access this website on a PC", - "onlineDocumentation": "Online Documentation" + "onlineDocumentation": "Online Documentation", + "changePwd": "Password" }, "system": { "userManagement": "User Management", "roleManagement": "Role Management", + "userGroupsM": "UserGroup Management", "systemConfiguration": "System Configuration", "username": "Username", "confirmDisable": "Confirm disabling this user?", - "roleSelect": "Select Role", + "roleSelect": "Select Roles", + "userGroupsSel": "Select UserGroups", "roleList": "Role List", "confirmText": "Are you sure you want to delete", "roleName": "Role Name", @@ -52,8 +61,41 @@ "roleNamePrompt": "Role name cannot exceed 50 characters", "roleNameRequired": "Role name is required", "roleNameExists": "Role name already exists", + "groupNameExists": "UserGroup name already exists", + "groupNamePrompt": "UserGroup name cannot exceed 30 characters", + "groupNameRequired": "UserGroup name is required", "parameterConfig": "Parameter Configuration", - "language": "Language" + "language": "Language", + "assistantAuthorization": "Assistant Authorization", + "assistantName": "Assistant Name", + "userList": "User List", + "userGroupList": "UserGroup List", + "userGroup": "userGroup", + "role": "Role", + "searchUserGroups": "Search user groups", + "searchRoles": "Search roles", + "reset": "Reset", + "confirm": "Confirm", + "userGroupName": "Enter UserGroup Name", + "groupName": "UserGroup Name", + "admins": "Admin", + "flowControl": "Overall UserGroup Flow Control", + "AssistantFlowCtrl": "Assistant Flow Control", + "SkillFlowCtrl": "Skill Flow Control", + "createdBy": "CreatedBy", + "flowCtrlStrategy": "Flow control strategy", + "limit": "Limit", + "unlimited": "Unlimited", + "iconHover": "Simultaneously constrained by the overall traffic control strategy of the user group", + "maximum": "Up to", + "perMinute": "simultaneous online sessions", + "changeTime": "Modification Time", + "deleteGroup": "After deletion 【{{name}}】 will no longer exist, Do you want to delete it?", + "currentGroup": "Current UserGroup", + "defaultGroup": "DefaultGroup", + "resetPwd": "ResetPassword", + "selectGroup": "Please select a user group", + "selectRole": "Please select a role" }, "skills": { "manageTemplate": "Manage Skill Templates", @@ -303,7 +345,40 @@ "knowledgeImg": "Knowledge Base Avatar", "indexModel": "Index model", "dataUp": "Single data upper limit", - "introduce": "Introduce" + "introduce": "Introduce", + "fileUploadResult": "Out of the {{total}} files uploaded, {{failed}} failed to upload.", + "modalTitle": "File Duplicate Prompt", + "modalMessage": "The following files already exist in the knowledge base. Continuing the upload will overwrite the original files and processing strategy. Do you want to proceed with overwrite?", + "keepOriginal": "Keep Original Files", + "override": "Override", + "toolName": "ToolName" + }, + "evaluation": { + "id": "任务ID", + "filename": "测试文件名称", + "skillAssistant": "技能助手", + "status": "状态", + "score": "评测分数", + "createDate": "创建日期", + "download": "下载", + "confirmDeleteEvaluation": "确认删除该评测任务?", + "createTitle": "新建任务", + "selectLabel": "选择要评测的技能或者助手:", + "selectPlaceholder": "请选择", + "dataLabel": "测试集数据:", + "fileExpandName": "支持扩展名:", + "downloadTemplate": "下载模板文件", + "promptLabel": "评测指令文本:", + "enterExecType": "请选择要评测的技能或助手", + "enterUniqueId": "请选择技能或助手ID", + "enterVersion": "请选择技能的版本", + "enterFile": "请选择测试集数据", + "enterPrompt": "评测指令不能为空", + "fileSizeLimit": "文件大小限制在10M以内", + "evaluationCollection": "评测集合", + "tooltip": "该指令文本用于指导大模型对 ground truth 和 answer 提取要点,如无特别需求请勿修改", + "create": "创建", + "cancel": "取消" }, "code": { "editPythonCodeDescription": "Edit your Python code here. This code snippet accepts module imports and a function definition. Make sure your function returns a string.", @@ -576,6 +651,41 @@ "result": "Test Result", "outResultPlaceholder": "Click the button to output the result" }, + "resetPassword": { + "slogen": "Securely Reset Your Password", + "currentPassword": "Current Password", + "newPassword": "New Password", + "confirmNewPassword": "Confirm New Password", + "pleaseEnterCurrentPassword": "Please enter your current password.", + "pleaseEnterNewPassword": "Please enter your new password.", + "pleaseEnterConfirmPassword": "Please confirm your new password.", + "newPasswordTooShort": "New password must be at least 8 characters.", + "passwordMismatch": "The new passwords do not match.", + "resetButton": "Change Password", + "passwordResetSuccess": "Your password has been successfully reset.", + "adminResetSuccess": "Password has been successfully reset", + "resetFailed": "Pwd Reset Failed", + "notEmpty": "The new password cannot be empty" + }, + "log": { + "auditManagement": "Audit Management", + "searchButton": "Search", + "resetButton": "Reset", + "auditId": "Audit ID", + "username": "Username", + "operationTime": "Operation Time", + "systemModule": "System Module", + "operationAction": "Operation Action", + "objectType": "Operation Object Type", + "operationObject": "Operation Object", + "ipAddress": "IP Address", + "remark": "Remark", + "selectUser": "Select User", + "selectUserGroup": "Select User Group", + "startDate": "Start Date", + "endDate": "End Date", + "actionBehavior": "Action Behavior" + }, "agents": { "AgentInitializer":{ "display_name": "AgentInitializer", diff --git a/public/locales/zh/bs.json b/public/locales/zh/bs.json index b2ff614..00a08d8 100644 --- a/public/locales/zh/bs.json +++ b/public/locales/zh/bs.json @@ -14,32 +14,42 @@ "pleaseEnterAccount": "请填写账号", "pleaseEnterPassword": "请填写密码", "accountTooShort": "账号过短", - "passwordTooShort": "请填写密码,至少6位", + "passwordTooShort": "请填写密码,至少7位", "passwordError": "密码必须包含字母、数字!", "passwordMismatch": "两次密码不一致", "registrationSuccess": "注册成功,请输入密码进行登录" }, "menu": { - "app": "聊天", + "user": "用户", + "bookopen": "帮助文档", + "github": "GitHub", + "app": "会 话", "skills": "NPC", "knowledge": "知识库", - "models": "模型", - "system": "账号", + "evaluation": "评 测", + "models": "模 型", + "system": "账 号", + "log": "审 计", "themeSwitch": "主题切换", "document": "文档", "logout": "退出", "logoutDescription": "退出登录", + "logoutContent": "确认退出登录吗", "forBestExperience": "为了您的良好体验,请在 PC 端访问该网站", - "onlineDocumentation": "在线文档" + "onlineDocumentation": "在线文档", + "changePwd": "修改密码" }, "system": { - "userManagement": "用户管理", + "userManagement": "用户管理", + "userGroupsM": "用户组管理", "roleManagement": "角色管理", "systemConfiguration": "系统配置", "username": "用户名", "confirmDisable": "确认禁用该用户?", "roleSelect": "角色选择", + "userGroupsSel": "用户组选择", "roleList": "角色列表", + "userGroupList": "用户组列表", "confirmText": "是否删除", "roleName": "角色名称", "skillAuthorization": "能力授权", @@ -49,10 +59,42 @@ "usePermission": "使用权限", "managePermission": "管理权限", "roleNamePrompt": "角色名称不能超过50字符", - "roleNameRequired": "角色名称不能为空", + "roleNameRequired": "角色名称不可为空", + "groupNameExists": "用户组名称不可重复", + "groupNamePrompt": "用户组名称不能超过30字符", + "groupNameRequired": "用户组名称不可为空", "roleNameExists": "角色名称已存在", "parameterConfig": "参数配置", - "language": "语言" + "language": "语言", + "assistantAuthorization": "NPC授权", + "assistantName": "NPC名称", + "userList": "用户列表", + "userGroup": "用户组", + "role": "角色", + "searchUserGroups": "搜索用户组", + "searchRoles": "搜索角色", + "reset": "重置", + "confirm": "确认", + "userGroupName": "输入用户组名称", + "groupName": "用户组名称", + "admins": "管理员", + "flowControl": "用户组整体流量控制", + "AssistantFlowCtrl": "NPC流量控制", + "SkillFlowCtrl": "能力流量控制", + "createdBy": "创建人", + "flowCtrlStrategy": "流量控制策略", + "limit": "有限制", + "unlimited": "无限制", + "iconHover": "同时受用户组整体流量控制策略约束", + "maximum": "最多", + "perMinute": "个同时在线会话", + "changeTime": "修改时间", + "deleteGroup": "删除后 【{{name}}】 将不再存在,是否删除?", + "currentGroup": "当前用户组", + "defaultGroup": "默认用户组", + "resetPwd": "重置密码", + "selectGroup": "请选择用户组", + "selectRole": "请选择角色" }, "skills": { "manageTemplate": "管理能力模板", @@ -295,7 +337,41 @@ "knowledgeImg": "知识库头像", "indexModel": "索引模型", "dataUp": "单条数据上限", - "introduce": "介绍" + "introduce": "介绍", + "fileUploadResult": "共上传 {{total}} 份文件,有 {{failed}} 份文件上传失败", + "modalTitle": "文件重复提示", + "modalMessage": "以下文件在知识库中已存在,继续上传将会覆盖原有文件以及处理策略,是否覆盖?", + "keepOriginal": "不覆盖,保留原文件", + "override": "覆盖", + "toolName": "工具名称" + }, + "evaluation": { + "id": "任务ID", + "filename": "测试文件名称", + "skillAssistant": "能力NPC", + "status": "状态", + "score": "评测分数", + "createDate": "创建日期", + "download": "下载", + "confirmDeleteEvaluation": "确认删除该评测任务?", + "createTitle": "新建任务", + "selectLabel": "选择要评测的能力或者NPC:", + "selectPlaceholder": "请选择", + "selectInputPlaceholder": "请根据名称进行搜索", + "dataLabel": "测试集数据:", + "fileExpandName": "支持扩展名:", + "downloadTemplate": "下载模板文件", + "promptLabel": "评测指令文本:", + "enterExecType": "请选择要评测的能力或NPC", + "enterUniqueId": "请选择能力或NPCID", + "enterVersion": "请选择能力的版本", + "enterFile": "请选择测试集数据", + "enterPrompt": "评测指令不能为空", + "fileSizeLimit": "文件大小限制在10M以内", + "evaluationCollection": "评测集合", + "tooltip": "该指令文本用于指导大模型对 ground truth 和 answer 提取要点,如无特别需求请勿修改", + "create": "创建", + "cancel": "取消" }, "code": { "editPythonCodeDescription": "编辑你的 Python 代码此代码片段接受模块导入和一个函数定义。确保您的函数返回一个字符串。", @@ -568,6 +644,41 @@ "result": "测试结果", "outResultPlaceholder": "点击按钮,输出结果" }, + "resetPassword": { + "slogen": "安全地重置您的密码", + "currentPassword": "当前密码", + "newPassword": "新密码", + "confirmNewPassword": "确认新密码", + "pleaseEnterCurrentPassword": "请输入当前密码。", + "pleaseEnterNewPassword": "请输入新密码。", + "pleaseEnterConfirmPassword": "请确认新密码。", + "newPasswordTooShort": "新密码必须至少 7 个字符。", + "passwordMismatch": "新密码不匹配。", + "resetButton": "修改密码", + "passwordResetSuccess": "您的密码已成功修改", + "adminResetSuccess": "密码已重置", + "resetFailed": "密码重置失败", + "notEmpty": "新密码不能为空" + }, + "log": { + "auditManagement": "审计管理", + "searchButton": "查询", + "resetButton": "重置", + "auditId": "审计ID", + "username": "用户名", + "operationTime": "操作时间", + "systemModule": "系统模块", + "operationAction": "操作行为", + "objectType": "操作对象类型", + "operationObject": "操作对象", + "ipAddress": "IP地址", + "remark": "备注", + "selectUser": "选择用户", + "selectUserGroup": "选择用户组", + "startDate": "开始日期", + "endDate": "结束日期", + "actionBehavior": "操作行为" + }, "agents": { "AgentInitializer": { "display_name": "AgentInitializer", diff --git a/src/.DS_Store b/src/.DS_Store index 907cc45d9945c4bc51707de01f31047e7e495c29..c128842d0e92bd754ecf8fdd5a56a5afe4b03252 100644 GIT binary patch delta 316 zcmZn(XbG6$&uF+YU^hRb;btCz1B{d7MM~K%4UBXYj7%ph%F0fDBcL(4M<{3Va+y*# zLjwaH1(V4arDP`C$*N3VA|$%`l<+CW$v=cjIgAWVfqD#0!Ln}zR3;aRif>L6Tf~SW zvsp*tCFA6mlDw1O3N@g}04-7z&t=GGNMT51$YCfh3ogpb$L)SC}k*N$YjWwd{D4~%>?K`Lo=|a-b$&6!X;5`S}5DOm|cN& PGKXjnri}=1&1D1t)4N`n delta 213 zcmZn(XbG6$dGU^hRb?q(i=1B{G2CdZ2ua!FKIn_2287#dql7L<^g>?*G^xl^cM za-2vhhp~Z~j)JkFB~Zd)^A_RzjFW!~m9iNd0tL;$iYExGOfD1^-<&SCh!L)Ov!Dbk q(`0sO2b>mcW|5hO)vRzir^$`-Z5tczGA?FUV4ch++Kb!Dd5i$AKs|8) diff --git a/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 03d4bee..90b67bd 100644 --- a/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -34,7 +34,7 @@ import { nodeIconsLucide, nodeIMgsLucide } from "../../../../utils"; -import { undoRedoContext } from "../../../../contexts/undoRedoContext"; +import KnowledgeSelect from "@/components/bs-comp/selectComponent/knowledge"; export default function ParameterComponent({ left, @@ -61,7 +61,7 @@ export default function ParameterComponent({ const updateNodeInternals = useUpdateNodeInternals(); const [position, setPosition] = useState(0); const { closePopUp } = useContext(PopUpContext); - const { setTabsState, flow, setFlow } = useContext(TabsContext); + const { setTabsState, flow, version } = useContext(TabsContext); const groupedEdge = useRef(null); // 用yu过滤菜单的数据 @@ -91,7 +91,7 @@ export default function ParameterComponent({ }, [id, data, reactFlowInstance]) // milvus 组件,知识库不为空是 embbeding取消必填限制 useEffect(() => { - const {embedding, index_name, collection_name, connection_args} = data.node.template + const { embedding, index_name, collection_name, connection_args } = data.node.template if ((index_name || collection_name) && embedding) { const hidden = disabled ? false : !!(collection_name || index_name).value data.node.template.embedding.required = !hidden @@ -101,7 +101,7 @@ export default function ParameterComponent({ } }, [data, disabled]) const handleRemoveMilvusEmbeddingEdge = (nodeId) => { - const edges = reactFlowInstance.getEdges().filter(edge => edge.targetHandle.indexOf('Embeddings|embedding|'+nodeId) === -1) + const edges = reactFlowInstance.getEdges().filter(edge => edge.targetHandle.indexOf('Embeddings|embedding|' + nodeId) === -1) reactFlowInstance.setEdges(edges) } const [myData, setMyData] = useState(useContext(typesContext).data); @@ -219,7 +219,6 @@ export default function ParameterComponent({ }} /> */} - {getNodeNames()[item.family] ?? "Other"}{" "} @@ -268,34 +267,6 @@ export default function ParameterComponent({ } }, [tooltipTitle]); - - // 记录快照 - const {takeSnapshot} = useContext(undoRedoContext); - const { types, deleteNode } = useContext(typesContext); -// const onNodeDragStart: NodeDragHandler = useCallback(() => { -// // 👇 make dragging a node undoable -// takeSnapshot(); -// // 👉 you can place your event handlers here -// }, [takeSnapshot]); - const onMouseDownColor = useCallback(() => { - // console.log(nodeColorsP) - // console.log(data,color,nodeColorsP,nodeColorsP[types[data.type]]); - // const type = types[data.type]; - // Object.keys(nodeColors).forEach(element => { - // if(element != type){ - // nodeColorsP[element] = "#000000" - // } - // }); - // console.log(nodeColors); - // takeSnapshot(); - - // data.node.display_name = "1"; - // console.log(flow) - },[takeSnapshot]); - // useEffect(() => { - // takeSnapshot(); - // }, [nodeColors, nodeColorsP]); - return (
- ) : ( - - - isValidConnection(connection, reactFlowInstance) - } - onConnect={(params) => console.log('handle onConnect', params)} - className={classNames( - left ? "-ml-0.5 " : "-mr-0.5 ", - "h-3 w-3 rounded-full border-2 bg-background" - )} - onMouseDown={onMouseDownColor} - style={{ - borderColor: color, - top: position, - }} - > - - )} + !optionalHandle ? (<>) + : ( + + + isValidConnection(connection, reactFlowInstance) + } + className={classNames( + left ? "-ml-0.5 " : "-mr-0.5 ", + "h-3 w-3 rounded-full border-2 bg-background" + )} + style={{ + borderColor: color, + top: position, + }} + > + + )} {/* 左侧input输入项 */} {!data.node.template[name] ? null : left === true && @@ -390,10 +360,6 @@ export default function ParameterComponent({ ) : ['index_name', 'collection_name'].includes(name) ? ( // 知识库选择 { - data.node = nodeClass; - }} - nodeClass={data.node} disabled={disabled} id={data.node.template[name].collection_id ?? ""} value={data.node.template[name].value ?? ""} @@ -410,6 +376,35 @@ export default function ParameterComponent({ /> )}
+ ) : left === true && type === "knowledge_one" ? ( + // 单选知识库 +
+ { handleOnNewLibValue(val, id); val && handleRemoveMilvusEmbeddingEdge(data.id) }} + onChange={() => { }} + /> +
+ ) : left === true && type === "knowledge_list" ? ( + // 多选知识库 +
+ ({ + label: item.value, + value: item.key, + })) || []} + onChange={(vals) => { + handleOnNewValue(vals.map(v => ({ + key: v.value, + value: v.label + }))) + }} + /> +
) : left === true && type === "bool" ? (
{/* switch */} @@ -480,7 +475,6 @@ export default function ParameterComponent({ { - console.log(nodeClass) if (reactFlowInstance) { reactFlowInstance.setNodes((nds) => nds.map((nd) => { @@ -548,7 +542,7 @@ export default function ParameterComponent({
) : left === true && type === "variable" ? (
- { + { data.node!.template[name].value = newValue; handleOnNewValue(newValue); }} /> diff --git a/src/assets/.DS_Store b/src/assets/.DS_Store index 687a95a60669610df326de4b069f2df41559ff02..7ae5f5a99271940713c5b554315b46c118a789a6 100644 GIT binary patch delta 117 zcmZn(XbIThEin1IU@3>Cfsu}ak*V3_i*gQ|*#*C_au^w!0!0i>!6MG$evFedMN8QX s4GeS?On_oClf+ae`%3zOb)%>ams-!dnO)%*%O=s^j3~xTb{0PX08d9GLI3~& delta 153 zcmZn(XbIThEx@>AvX4L^mqc~7nWc_`p|QneUP&3ouE~lb@{HY^Sp~nda+sMI=qMPO zn1N(AD~J~{BJ`M=n(8Q6f@NTOCVNQ+A{1aVG*oI6>t;5E-z=M%M1L`&7(ZD-{3!rt Cw<#0= diff --git a/src/assets/Login/.DS_Store b/src/assets/Login/.DS_Store index 1d11d77b4a24a36c7b06c28fcc9d8eef02cf006f..7aff727ae091c95c34696e5adb44fba857d8cccb 100644 GIT binary patch delta 52 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 z%0D95^**3Ks4zJspp=s~NU< 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 literal 0 HcmV?d00001 diff --git a/src/assets/nav/.DS_Store b/src/assets/nav/.DS_Store index 35e60900f009d93401d4dbf39d1f59264bad4308..4170852b4fdd7abd324c4cbe5330ae52b629f708 100644 GIT binary patch delta 515 zcmZoMXmOBWU|?W$DortDU;r^WfEYvza8E20o2aKKDh!eb@);QN81xtlfMmL7&SpUl zF_z5=9KFno**Q2SHn8x6lyNd7GNdr%GGsF3P5!_tF1raRcIiJD09gzSTnKpv!^s<1 z#rT+~(e<5q YGQWuDWPctG4q$A8VwqucJkK0v0J__h3jhEB delta 277 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 aMd20aXr>|j!nCmf0000 literal 0 HcmV?d00001 diff --git a/src/assets/nav/icon1-active.png b/src/assets/nav/icon1-active.png index f519402a96756dd1388ad9d672ba48f4d96926a8..549789db53ae0e19f0e4b6af00ae93362cd71529 100644 GIT binary patch literal 8713 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 literal 10710 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 o$mkQcIaSB$bHOttN5F&e}v1Av6s42=aJYp16 z6onWj%Edz+11yuBjkTzUX5lgwd+pII2Rh{#dJJ2?%1u$j@CIW2~9Gw z0gGT!ATaHK2}^wy zs-SeI`!Y!$l>A>cpu6#7#!-#(wlGfjt>R5h#8?q|O^LcdH$HhbaM(_5=N<3Z-rk#}19wCvkEvL~pahlXfG-qXY54_#pZ zo-mikk;^=us>s2E6*jn<*x}V2yE ztn-tfTe|323K^T;OCllBC3qZ{;_Hu&HG}#4k=mnv&3!1+aBX33;DYl(kl_<=rl+T0 z!|rshqJKSt)bE<&xUF9uNeMVyxgzx`o!x*PFPUf-mBKC&)r-~_78b@_abgW;yQJN3 z7R#zk8j#viB3%=Q=WeUZ1DP{fd&ubckF|rhgJ)5r*Dcf^yfj`KuWJ!B?-{9h=h; zkmMM5!wNDU_j%F$jbN#6sFB}D%>|af;b*tfbEso|4F%fH_q>HaS=R0)P}o~pBJ~)G za^;#I*WNjF>^D-3jTpMw%(f@Na(v{W3VuIpIg+~Yp)oaPrsmf9wk4N!@5T)e7XLnC z=&fzpRWfIz_wC!a{su@*p)6F6xcNoA8ZGO(=f`(*)p}X>veMFVns*pl3kK0YCd(H- zJuOvr!yp<|#bH7XE{(IEK8NDK26s#jAxGACHkpQ>zdWGGo+|2(NKH-ku=*b4*0$N6 zcmU%$qVOe%w#w*MOgjLFfUOem&TB3m(8 zF2@lzGRy80Sz4~7@7~n?+`4t2CxyFCGOIrrOq&@J-JD<|z{ir?j}06@emo(U?BO|M zi?hq3epfHOV8#pQC4aRmfV6qTj>JFbqsbu`e9iGpsK&!N$=A(D)tt@PfVZ{eGtnT9-QKmQY)(ZQ8`sk9=x!}eCuL-M!cLy6)VDGBRZgc~ zjOZ+B`xOr`6{;&^ffIXUTFaf2%V9gi`LO7swu+7_x{>O@fw}_i^TQp5-6w24BaWm| zdqtd1Tpc*hro?zir0Ob0&t42J~c=DxJ` zHU!XKNQubo)lFuSRjoQzp$M5rbnHz+WV~?7Uq*=PiXm4v(SC7DQ0kUolF1?1ZHm1} z*Wc}0&)&XdIN^83q3!B_|H+PJ1S)gN3myvqaDcTYxW%;S79E5>CY@R;L-Uz!4!Rjl zQ=%S=>{;U|r!xn$14JRHe@9}X26mlXCoT|qx!Az(>G}P2o(+RbI}v8jZJOCd(eDK^ zBl7+atwQoNVLig~;%p(lQWwYo-4ff`Ja+8x6KmJS=J0R$riP2IYS0u6Zti}p5;~k9 zZoc09?M8~E8A=Vt+ul`U##v0U!YT=rp}}EdWkD<0-EBfmYrs^s;eHP*?R#?+`;m^m zIz=aNIP+V7(VkCAIVVI02^l7${I&QssTHhIV&ZAxu$lF2Z>}e)G33u`BYPeyqvBuU zNC0u9`2H4G%cd$LkuJ{jjs9DrkYQ>c9Wmd%ccEgKI64!hXk-~TWBhEUAA2WmRd6f(n8vVCAM z@=8B=vUYv*QWI%Fy4HPu!fsMd2yWHst#hfS?R_4_7@2xmY1&Sasc`AVCVzg#Nm-mZ z+4w@Ym2NP2C;oQ6OxlzO+{$#9-Y`-UDSjsIt{F}}i`whvR~B#%E`18k>#6&DH^V+%aS^+SV2pWD<_%Hds3PzPoil1(0zt zn_YhnUZ#MaQKHHqk7@B8FH2yv9{7^;m`|Ke4rFn@WQG<$m@G|5y+>&f?)q~q+BR?B zhcFGOg3r&4_p^@xTfm-cV!a5W*|WZ58!rK*viYy<;kla_TA>`K;%Mrl%|&tIe!vLq z4{)^&3QaG6HqB?%Mex(d)StCQDg3;?rl6u+$^5?k6&;R7#3zxnq~HHIKw4AkJK3v{ z*-bqN==%sssxhWKn)&99$t;CI52ebIs@^)EEF6s~*EPpQA#>dgSreW(rkFx#t!=*S zX&*!@sjon#NZqxiZrR<*LKOS0pUpw8gq0?8e-VOf2_ zY~V{8xi~Fj`Ns)DwUN-&p`I`uJ-q;=)1$~7z?TRVk2Kz0zCW+c9{^BI7z(sesQlbI za)}pDvIs4GG%(k7MzyeS+04xBUNCdwx+tFpyfR{C!nRoN?OgV_p;c%wNuGzV3>U@7 zR>(aWyZp@>5!1_mb-H|>=FuAdZCoV5D=!aV@sLZ?4?s}$Tl6D4cJRUR|FAn$E15?) z&mB#7a>z`(ze&1Bs(sNdU_iZVo$(FWln&SuY&^M5F+mPmMRpZfykArWvni-(eGX}AZ?c4Ul(M;` zDbg{T>~KwM@L#Y%&UklgToE>mUPY)b)6&uT$4RL3&7FO~se~RD;VaE%^{}O#Bf4?x z4T4uf7{E+U$tb8D5`mEj;9gW4CEk?@7u7`qzXRk~`Q~j13cenETSVScgUL zN3;O+9XjrIR0Rk!n{Y4ZkvSMnHs63Q8v*ehNjb9&V4;k^5##YdeEYO%>i;(I{}6!< Z*(T0N-zi^NS>R6#vNpHF)th>y{0Evk<$VAE literal 4481 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 diff --git a/src/assets/nav/icon2-active.png b/src/assets/nav/icon2-active.png index fa7f990c30a7851a3c35ad33daa22dd674df01d8..d4e974bbe61911f34e4e943ffa3af1a6268d7b55 100644 GIT binary patch literal 14335 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 literal 10482 zcmeHtTMj0i zFkik4X+5}$3j?kuAwxiHxU2<9tjA8mc%j6>R}iWxiC78f^!)I3?co`Q%S=%7#yj7b zwp5XK$6}p6`(kqp+dN{Xi0nS-X-db-|2}O(d4QM8W{5vHVy1xkeDA+N$mcc46tdL; zgh66t)@hq7`M<9e(H7gR7Z6=QzWsys@dtT)^1vp`>~XuKa&#Qn|HYr(cO(1#9Tzm2 zZg$=A&&kOt@9F8G^lo3d*Z8jNprWko|FrNf%ZT{-^MHGN=82gYLEr{CtkYsJ+To=0 z>9J8cU5M~>N<~~=T|M4Q6dE2Cl_37Gr$R(Znj~s7nNQVuy&icj9{W~Dd=c2hr+oA| zX%}qrySo(ce7rq~JL$Nq5ai@ks;R9dfsG`x@1Qb@A^x4(O&3jEK0e$D-h>RfJy_tv z9$}>Ke`R;aw0azs_%IXcH#)Z8hv2_yy259inu!qrZZg6GE)N&zF7{_i#T*vvJ{dGR z8mX4+*OzRKCMRcS)5>5HF^Y?u)YQ~4zI^#ooRiaG;ZJwSj!wBg|K5DHh4{~Jg4_q5 z%nLIyyui(uFmW!f_6y4KlN4Q^H9UdNTEG#UD7ZeouWn^SLs99TYf9HMo5n7}xS(o_F8#&_+&ss9 z`t7+&L-Fhx@9BEvfqP7Jg`1VMbSSkLLKBZhm=WA;^*mYJ{%JT`o0eQOwOZD9<&5~T zF%EfU<+uh1r-abZjT(m~kMO86#;wsXxR+NGl13t%7Ne->TO=eTCVqacdMa}A7s-Yn ziZzP}D)QANC3{$ghljb9GK4QE2+tm4jK^oj$pi04)}FuqU?~m$S5~`7)x`_kCi>o< z9?R7ZzZ$B_V|fne*|It*RKpWH{L|Vn#yci5lOqd3Ro}d?dCM&Q3H=w+7(AoQRNS` z%bD2N6r!JtbFnC=U!QdaA-ig5XzXwsw+Zd&bmW#gfe}s8`<#sI$`rh>=h2@(e~yTb zP6FdyZN>Mmk`*`K`(H3N&7y2_kE`R~wx7b*)M`f(u~~UW+Se~4)XP z0WkVi=O(osD++S0EG=Jj2Wl3ZbawE)S2f|$1H+Sj)$b|;VSRUb6rKfFP{8{6#`*em zjpe&aR>!GMTVbgaKfv01dbK;T@kzT}e;gAZzY~cyi1T!S%4z6(mVXKPRm~`u)bF@* zgGRPtLL#EvF7*n-*TduE{W=AjO!ioh8Q+piHOnCnccU@lzT8v-jtN6UFHi{xl`E03 zSOjoj665QSqg;1i`Rr!jLU!|F-t<%@iySve>DRr_0fy_t!^2IEmz!Oeb7dk|IC~FT zZb^}2U8x_7HNJC|X_d~J{tGyadhUNMLCR%Vbogb-snaOPwD;4O_*iGj60K6Utx`k*UtN%zfG3snlYl3K`f)3Nf5>{GFB7ZK`QM8N z@A%}M#DoM*c@=S1r8Gl2FmDqamO7HYPzkdBS`K)6z)C4Hr@p&7F@chiy)$Rq;n_x` zEjTQjpPv`jF?8u4DJm-3UPeOhyjt-&zyJG_9nldpVlGB zv`HxIt#4u(S(F(SOicsp-Y*!Q|2^OA#TVCPWk*KGOJJ{PLTZ%`;$>pmDi!m&T;_LL zX**H8*{|pr1M-P`#m#y`1^De|?{#!_b;+Y*aKTjM9$~L+%f;DfaX(-~rcNxB{PcH|9W(P8S>(YeCN^4Xbkg9vI9ifxaoZ~~94Yz$jbYjNs`94U zZaALliLL*j^_B=ZwiYL#)BmAm*<;C}GPjW6S4eS|_cq1N&w$6glvv>TtvHvVwRgZ1 zjEPP3z1E1w&@=J=`B{jRE3JHj5}onzXg~aCY+Rn~$gzja?00jf07;<`H`5O&H=`AVqKk^yn-+tSfZ1HkkMI%Az0B6LX@#CrV80EJ>wN% z6NhHHKrva_sMW)0une2v^E=Vo-8`b_&$$!Xb+pF@aBypTyQs-m$L>dt|2RR}dER^H zeZVe=vpIU!7>+r>lNwJKWZ5#%caVQ*b?9WoD@+ z&+b|pZ07N7LoVNCW7O(=Q)mV{Ai7c!8X7vk)*B}N4yNu4HspjZ3L0UzCbM7J65q@i z$s-bC^=hq$x5vNDc=~8k18dr-(rRjPwn;i{u`HcDhTkjah@@McDS+v!gu1VdxA6CDh0$FJWccX>f*fn!lnY*&A1u<%s|?W2{7ptH3(>1(*Ba|_N~?5>u&!*c z8dLbA-&UdyTg+@6LnmBQld1pTh@F-x`}`-ydpn z*&xowRQ{1EW>AoCDxwGF4M^PYsr`iioGakrz$B4#rpippa6s;)z0t{CbQq0M2E<$I zy|~rY)fzq*`xmDJO5Zl)6}jTh>F6R-;pBa_p_{+<32hjDx43I`p3GNE1=;jRkh}_b z^kt7$8w-MUyV!~I!Jz)vW?Rhu4;OPPt*cxPhpR^pw4ApW2P|OQNv`a;RgkYEGxm}o z<Cmxc8w|^mSg?LAyG<$CZqHG)P8BL?;OG#+B7CaQhWf&v zk-#3od}Ny`szd)rOH$FY&z36cT~i|tAl2Dxs(F`kwkjdRh23_uS5At*XR60LcLfF& z>FYSnS9M#WlDT!n(F$-GR+)Cs5fTzAS&yaAZ47=%4hh2>k-`_tC&v@%jd)Egv+Gs@ zUutmJIv?du9zSVkF=%kq+E2{fQ|#TOqZZQ3!aBMqprSIUD2r_2gt)YV%i?E(~hQoGy-Us09*8%fhYElADSMnjcmdcx_d)ET2y;Tfj z+pr*R0D|Urt$^?IZNw)jKG$3%*%(p0?05D1eDkY{xle(|(PI6OqVw!Zt1~wbk+gJ+ z=gDJNN*FY4sa6iZz@yBdQF(!+=*8l1EMCHsU$9>sX3g>p1-3IKSQsY$Hw8$z0bxN- zO>1ZnH?KBRZBeBxzsuCOX?*g{24})+Hb|j?@ptbBM{es6(Tef(V4| zX3JPhd=^uOaEx?~_>N=N-o)-ni|m)71M>EL0dq#c#wx`G})wp-f3O z<(X53nYHz0OyoDlrN$FgYN@iIhB!Q8ldg*v#D(pJK{A(7LIyG{mVEYnk=_TrFl-pY z#`{J+LbR%J1)=zo2M;A>)&G4sGAEqDh!gb|z=ic<2J%f_5~+tyd%c&TCzSKvD@e8k z(Nmrdh{^7HEFUJ@6AvI@b-6E>kdROce-6S(RZ>obY@te4MGAp@&MRjzXu)KcVcAX7 zamztMNhn_zY;GSbzEJjp^89y4yMjA?@D~)iHxL+ztqO6>)#ZI5l1tL-FDLmmklPBC zzA1p)HvJcZ4@g|}8q>irr;xeYw4^6q1LX~o*A=+lnK8t@76r*Du3~HyM<68Eawg7Z z{*lUyPG#d{Z*TuFSv~pDJFyfp2~K{IVR$sRVz0IPgfWsXj{O=z)J0G)unZly7MLS} zr+DjC%TWiNc!)i>wnQ`T@J%fI)?0 zHZDs?FEaS~=Fa{r*zX-Xc@~}yowjTP$5LKyOr)gj4&#gRNGfN({c5A~_G<(Q+sIHH z!_3=KrjT|j2o@VYubaJn*{eD;V?Tgk`X!Ey=BuvY-vEX$q^BK(hLyLt--5GOf>E)F zEvE1$Av0m_+wkmopr@ASpIWn!q@>py0ge2=KFy^48M_w*gl2<3s#OMy`#8*jaM+K+(TM1hlp}>3oF2kOAO5vH zkrmalVD+?(&4-}lYpbK6g$)B}`*ky(+Zk>a*0z$V}_VYZb z2x<(^74MyJE~6G{la#}N%f=6!Fk#PQ!|(5YW{R6R@zlmcB3H)C_Nay%X0586hZT4y zfQecWV8R2dBx3f?Oq2Wzg#pz9dFLX0jtC_XfX?RTZ9Bh*_0)mq{r+m8TH?B0DDW5B zN$@m;=beZzav1qOSk*Kpk?+EnUj=_gc{^8Wvby<^%-FdgZA<^ZJSt|v=hb*?B-i!*kKSs%4xn0*kdfXh1TJS4Jdc zYhB^Lz$C;sx3E}BxBEucb5VghbiOr;&t=@!#0;gu!!a~$Qs&|sR-<~%FEl-6So38XYDVhwJR`}jYcu54Vx=P@ zgS?PW$&>vu0%Br^X%LA_aiJ87Cwn?G!4Ox+Mx8Q|q^;r7c|N>8d3Mh}GTX%HE&nLG z)bc~f(6)3K^&`=uKwM^sreOSZJfHXTT$_EFKGV?lsbU;MkbI02#ZCu><3N&x9q~=D zQ&~2eBc2w8D$W$1FbR)c*JjCGHw&1qFfxGpIwzDA1#jj$b=>Zk&Wka>&PHclXUYp>y2GWbA!a`Wfim!iekx6J6JzwTx#v( zKjp0j^l?cXN=OHGv%z2l)Zp-}DxT92VwIIY)VS)OcSvcCFbSlU0IX~v>ePRcVnF~^ zWVWL)=y@3Q;^(ig}Bc@%pLPugnbXUn|n zr-8FXT9liAAM_Y;j*W0Uf}`PtfMm@YSW>6S7rwYHw}C8Hhd#5xB;+%IO?XernKt^F zP{wh^m48wZ2_usO7R(6Y2}F^f%aIBr0dx4+k88}G&hS7XkVCiXPx(x#jwkIFwL3;^ zwj(&UstY(hsuV-k*(CsK8%D3XQ>+QDeas3IoFiTc3O-4kGb6=7%cW&v-w;#3gu=l# zXYudS$`1YF=wG;1aY^%Z;6NGiT-a?$>wi~P`|jsTz4Kbn=!=oAD8m8;Eea8js1G?c zf`bc5qe=PZHdLXe)I=fDQXd+J{!YgIi)S3FgkaDPqEUz;>LMm~-8>lcjKxhT3xPiO zgW0&376T>OtT+1eyuf`BIuyRt>gluvq8gI&Q#Pf%og4lNWH>kx_SnsoxZD3of89-9 zk{<;IfTGnh5u>Q@^-e9?VgxqvV!LijAqgH(;~4IhN1DMJZ;TPE$6MfwL6kofxjkx8 z^roX(w@+WYvqm3}TKGjO1;vPRwU#Q!+o>xf0edGZceYpblKsKjZTB@GFq2Utt>ZWE zbIv`-wH{BazZ2cLaiw2%2f`yG?c&qZ?=L`pv3!!tlpe{F5hdPSvRGN5?DbR*B>0O& zCUI>eH>~NoEORWp&j>j`A4ZqjWN!jnx0Ej>uipvxFsQfXWRQziRUctfq|82MaEaH& zV42I=&+&-MQ8cq(S@68b@t>n+6Mt-srP;gHEMkEo&D(_Cc6^~SSwS4mS67@{HsjF- zJl(A>1>Ej^clxR}T88^qb!xxxn`6R4?M@Na$LTK4J(yL{0u{e)zO}xnW>Xj#It@J_ zL0QzM*yJ~SH<`&*<6UjxMu{mQyF69|FY>?ag+>OM$s^NUDV&fX8KonhB#-AxNVDKU zNS+Sic83r=t?lBd^P3%$qG>YRSOZ5JZg4`}|Bq62-{C{e+97MjqXh}Y!*;XYPh_j! zJ2b__M)L7rLHwtr-lx*f;QX4^UQENRe2=SyZVf0&RVD=sH+-ssWPA0gn8 z4hE3gRL3@jP*lTtK81fq7Rq=X#S%plQgWJpRE3P9N`KP=(yg;;UGqf|O{Ea_EW!YkN3j)Vho$azeA zz>K~_sV~*#?KTcd7&hBui;Pp%h={bdbB`>1TuHU*oLt%1x#mlRS#>vXeD4g4P zfaJRA1re@sxM*=><3=J#QQ5KS{?&wNjzN)I)$|d8b>YGQMj$HKJ&**D6#vuX%wnB; zaD8siNPb|Pops<>kf4o?jt^xF50_^vj_26<_m3}8;6FM>t@jh|-JLfV@sDudIml*3 z>v39x-CRXD59_h!bmBKB$M2$g`4PlAF%hXGva;po{WN2D{bVKzl07f`uMe3&GMW`y zY0m;vS~z|hqwY7*_WD|DFZCroEqJb}i`zWItuMM}(PwG^Lfdl0mX1qVbdw=|mG(wM6&JY%RyxGZ8 z39fcSeo==_R!R{5KZT4Vj8*~C!W~M#G}AptMyky#u;i)xWy6%!sF?B znGVEdN4RBQL|^;;ZlL_!LQ}5a{mX-r&jC(8d7JYW3{2I@5y6$7(1~IVxx^xQO_Ngd ze{&$GC29uZ8kNi)(E#O5Fu%T=u({A6In_q)`?f1o< z(CYRwC06Sqn`eLQER1|Q-eZf%gixZ(xNw;qd2c)bC7C<`d@!1Z1ssch0GsKw9+^hV zbv9G24Nj|%5yqOKp2ap(cGCubnju2{G?!S+9mAo*lrhKnQaLTOaqlA+ggH123*zl6 ziEzr8kYUB@1vTaasMw?mmYSiWkMkQP0J00FKqrJY5b1Q6vg`g+!~o{dYcogX6->-Q zr%U8tfMljgdPaZ!vLckC&i|V3uAXe>Vti)yObI&VP*)Aq#jc%bOTb}nIbify=zAD9!;K1E>!6y^2sLU zg%DNrlk2e`Kh$}>9F;3>@3)4yKkWW8BMAZd){5L-E=<7f=A6zp1FLfnqfub!#%K?^&cLA^5IbQk}z!RJbu)nrBg(ZKYtXi8ezeo3gz z9E6dLZC|)@?ylGx5!l1=Q^0z7nDzV2NWrc|z3q(FjN9d}u8@zRf!+XqEhm(vK}qDp zW>Jd?`Zmu#B)I+ZIJK}QJKMBaHHaoByZ6NK8-&PLrym#*_-$$&-tLOZK>I(ObL3aq}LeJ}<0`GL1T1*BhAY zEvP&KD-31m>DgX<`n0#ex!)D^z?OH> z6%;a(Vf)UyVv5koNJNL%-DS-FY5dCb&S~-Vs@~NX*Y>W{PfS~%Ns^L|U+Cz_=Fj`8 zs`&U}33L_^KvA$Q)iR}X*%6bF%)EK|(#67t{6MmKz#TCANLWmv23Fn4@^_fnZ=VFnhg5fR71J5BfjiO8`hj| zxJcR_zwSTYqd#j-m-A5`dKTa3u~#Ob4Y-b`)AFy7-5xmFv1dShy8q6~>Zn~crIYVu zO(F2#-qc-fY;3Ic!BewwG$;h=i@z-GQN4`M^|0o~0}zpr@v07pm|y1#R|{N$*kMQZ zvLZU}eQ??D4}Y;sTQ|ndDavRte7_szf26@^k&b&<%=L(LC5TKz!SLO`f@v|ze3UVH ze0=<_U8bvc)X9z=DImp)8)9C54CleClh zO>G?G_a5@=*tD&DRizrU+nV<=h)#c07YueRpuvXJ`|XYKdsj`VQZ6V`k!CPRbiQY@6|)t1V}KxqOVtGyRk zJ!oJEP|4~(xag2sLqW^(WzgQqQLb*~VBNjP z3ZiqlQy<_1l?~`w6?dI@e3#1khYx)lCpt|^b%-Rt4OOdYJK3E~--}i`i0m3ntXIAC zx^af<=d3!4bL@xUpb8BmHwA1hsC+^n)0n^{ag2q5z@scj5y**qieAoJI3;BK{?RD{ zwoOnpzET2n{YP%Wam*4c9ROft|K|nx-CEkOn9vNtv2XW~8;t&-_i&5F7%1r!EWeLd zTjrPL*2-9I?J4GD(13uFwNt4T=tp= zl{HW~wm0^O0B;n6j25N%_N^}wkgW{CO6n&B!>4l)z!GTV~Y zYgUuNE{#A6`e>`uox&61({>Y|tg_9)O7n=iPe6Odt{}t_OAHJmk=klQ%mF!xe8S-n z12O`-7{}^w&<@8)YSJa2dFjBgrqx@!rCqRNT-G()a3^vlN9yo@#=0${@ZcqRT)k zUrXQ+Lorx4u!`Cusm033Nh@bZ#7(au{6!iB(rg)s93Gz0e-~T(F?16ak!@`rR((r| z8SL^uOBeSRe`_=jg#*XZ`0Z{$N5Ne3#caYxce#As_4YTXBxa?wqCmR0 z1&TpEuzXVjvLJ8O=EJ*h?3ikQ=xVxxf2hos*9Vw+C^sm;InGSS(Vtjj_tvTmyB8(0 z#~pmAfI$VDYUKd&fV01iU23~b?6C@#t+6g+?p{0pC=oa=j7&kW2M(lAVozAl`mxoj zB&m*CMuE~d0Rv{0Okbmgg`@k{DR;p8W-IyW0+b`4NQS$QmB~vHihRMLV^uANFUIgJ z)@C5&Jjsdr%KZ}TRLKkJCml;ty=^&WX4+;gJzG`w;iQGivspz#k)2uQjz<^kUl%eO z;&f*lob+sYsWX7ocuBl@`FeKJ&Me_Xy5{EDH%HX|{`vI=24cuqaiW;GxEk`G=b`Yo zD^e_MNCNE{{N8%P^(bWAm}y1&p!z29d+~RrNhjLQ^KZ!+=5r8BuqHmQ1pN}I1FxfE zuq2S^@thg9=~&S3Q5vwbMIw(9lhvtNLd=wCVV48U0VhK(tCPgJU=*oU<`^xe=bcv!@o(vzE81?C`znOeD?EI?cfyAS}Jhi zMgueUTKhOI;&Ip%RKiHjxR+y`gV%kJXtkVGalYMVH_+Ipidwc%mu^LtgKZb9-b;SFE6hL z(B3crIzRYzE&COu8L=0dK|6v55u`X=*u7Bd3U}{JGb1V{CQHy|y>G2^Z&awvWe$?> zb9H=y__te)@2vXxNy+gLz4nDIk&k6|K%R9MZIKE*tgf!E7ZVdxL|t9Ip+-SaOw4Zy z1nhXi_J##uAA9^l$=||9OPehZgTY33cX#dba&!05(b45-S>w0@`xJJ>vtc1eTdfTr zufD^ej;o+xK5bHC89u!2zG(VXxktfk{nq|JPAS(_BOoa?VS$K&G!dIhlFS{hr1U!j z^%61~Z8Qy~RLV2ZMb?LzXZqgR9u%#G vJl^A&Depp%30R_nbGrZk$^PGdX4m4z7N!fpaqO@sdjBO~c+ diff --git a/src/assets/nav/icon3-active.png b/src/assets/nav/icon3-active.png index d8a44e03c2daed731c1c4bc65d37410e152ce065..30c2ea6aa863f15da6fdf3548e49b0fa9ba6bd7e 100644 GIT binary patch literal 10099 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 B+6Djs literal 3923 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 Js!}uy{U1Lj#3TR! diff --git a/src/assets/nav/icon4.png b/src/assets/nav/icon4.png index 4932ca5e4482c83775ea596f576ba4bc450c25be..fd899f20665572d63558d1cc6665677ecd5065d3 100644 GIT binary patch literal 2559 zcmeH}`%@B#7RS+x8&M>rDftS>_VzY)Gtp2%6tz)Tle~s$KB6^EQB*=r3^7shl~$|Q z$5y@~veri`pl02a)}&Q8Sznm>K-5G{Li53T=l&CS?%X+Z&S%a~=R4n-bLM3H=s|#h z4Zr{Z0OIO`_ui&xJ4-;{ZC4w@Bx4&IRBr+fP%Ac)0{}Z)T=7_+8v&n7N$gO<{uH&1 z_@Pg!4?FQ4=HLM5ne(k|)M}OXZ{SQbY|zB>OVxKz|6=Ma zWJT<5t1-`T)9tOvc!IKH`_?tL{PLuKYQUmCb_iqH|A9gCR4YsGr+xmWwo$7jXFf=% zB@_pM=2M_i1Ojj?UK8|cHsz%i5Xzd;&;SNO91ytxTNjfv55dS3MA{F<7GFS!|J_#b zQ*3pAOKez}9An-o%M|H2O=`mEJa)u9>MX=>$S4tqw==}8ice0!t*&Z<>Ky+z%WoS% zt6)8LXjwqtoHDt#sKCE}+p1y8=XgPRj(Kt{ct!z6`rD-mD}26BL7Z@~Efsfgxyeu8 zt^4ykE>ry4$JD(I%LTsa0A>SaMapo)+gU9yzQ<2W;S)z-^ky!1Whi(!35lqoLE}10Ks3 zh?eykf|?FkQ$F5)ovy8>8Bh!Jbg&osBcJ1=vdr6pX2zp#L#6iwhxZuU#I9XF)qL&4SO1-wG^0%~uFuq~`ut?DL)>PF zY~+}86=u9dVBfh4PjiBwu`f)LPVXot9Z`(6Gt`zjM(E|JG<2rxEkwQkBv>}0a;|Dc zvnY+z+%M8<+Q&ZIXi`@gjIQTd-}#7xu+%ekm$kN&@Bvn5<2Xxc?)@9rgkKwTze;KN ziv0#l&)NPg#01Pa4-N8`DA(fihaEw_97)^P-ndJQKhdg|2QcjuW@dp6ZEainPtk6o zR0I`Taa})J+$xmJZQ?`5=?VcVCibu-wY$69GcYia@#8_p5i~T^gV`{T8ndS_PtN&X zxX`!jbH*OoNO~|wvPXdsez3Lk1{M_{t_#@g4I=(~z0fblye{p#_hYtP@qJg3s#1E- zm&U5FNE61}!hN?8RNaaz`bAUV`E=;4pGWggRHVpAYjDJ=FK{Wt?m;=F_of|dv12Fo zX9yt=y{nGT=Qq^VEyuxHt_3{dak=MmOfbc5kKdW&0NCl{qJfoC4_O?MSb4y!QUXyI zy>c6+h%doIk{+`;$vs<^NLJX!sR;0ucUFg(^Dr!VFkW%v-zdpE;!Z5YX-j`^3pc||HjLn|Dxv-}I{ zqw0spSEJwSV4Wr)2Vb;fC$~!-VIl{|Szo z_GUTIue&jOEG$0nIQgD_{?t%ianBwLJFD(2QOxxTTCuTdR?(DGXv+&8xjvPX+monf zA3K&QT7tg1J8^X=5hhJ+yH?lzV)5jKU56)_XK~4Pu2D@|*deVoE}ORplSBZGpB8Mq zuCGp~D-^oDq$V zOv!r8GfAQfbw*e__sm)*J?;Iv!}1w+fi%glidz8HLHraqFaDsPySv4LMM=5{DI!bx zwa;S2H^W17##qq4r+cl%jsWZnKfP_4#qbHpBgbHluh|fBCu!0p&_`GmR=kp9yo1SU z|4yi)Wr(iGGK3y@9G`O)6l8E;zF!?mK#4~ltGrNm;&+&#)U;^pg$99TaD1LIJkF-H znn+aI!s!0pzuR}h)gMdN*MC>?`u6>C0Ge+crPE5yia(7S?X|k(IX92)gsaf9vOAGK zA4I*6cuToPr>_M^ra#970terG8%~nRws&j%<_RXj0%SoBndNV#P)}mY?XAf(!t^o25Mgatv65ac zLiOY#ibmaPCd`$V@2;*=pL+%&M^{K})Vlex_A8s>mKBA) zm0D4jot-UM-`vtBN23O&9iZXHl_o?@(8J7v&;byF-I(K@dsGAH^~TjA90>i_MZ#mk zT>!J@lWEauO;GUDM}ItW17Llk@4Pe60RB4QHS2XK1;Mp;C1(Se|Cl?htl8@TC6<`h zI|H!1xWWXVoe1_(k2`(`QxF3-ZWt~Qir@G5w>;SY$NqPld`qpt!FCCTM_ LCl7or?lSW)g!h-Y literal 2815 zcmeHJ`!^E~8+Vx+qb8TUql{K5!Xk+@V=nu;wZ0{5w6ZAoYf}@`LZi|0&1Jb2l8BKc zV-#|oWz8kGc~{x=)ufaW@!k7<-+$pf=l$XR;dwsK=RD^*pYuHDe9n2&j(fVOsX$cZ zH02Je@RWjmrdBxOROYn(91|4&9|*T!m{SWvg9E(n0Ip?9{noHZ;ay4L2)5 zrj654Qbj1>T9OVPKL~cc8vtW{P*gN^pC;gc-(~J+HxX0LVwJyX%Nj_`vyloGZKb1) zl`K{t*a|Fny$GQCE=dmfeUBW{+}8e_mI4^SR|G(TA~|3W@SM_}D95|o6u>C-gFEFk zIlzCNCR4LuM{ZMz2N&I_vka7_C+f{^L+%E;yhBIbu8%{8mh8gjB>ess=%4Cl-vEu$ zD-NTrsH%rC@2j3ZA~t2-*N?>*$~RD8=xBM1(?1{2v!};`8xk@8zXperlq)o0=qw3m zEnmL=K=Aq&@nns`_gkhZfRifz)$Dxg*#j4z3u^tiO|~Nw!1q-K_dV$_H20hczjR$% zcTHb;S8?&|_RBH(G2wCgzX-VyFkQ24Q%BC$S7%nw8~*e~g2=l|`b&&hjZ@(WZ6_Y0 zMQV6V5U=mVOX)dNaZ@f5U-cOqj)1 z6#enz$6cMBop|c(T^lb5fx`&8x8A}f=ykn=_9Q7O4-{X}x|&S2n%UT7x4C^rTv4Gx z;0y=dJ9}_eKJ?j=fvXb5-OI}b1OlDc8arW*oX;$|6dV-vX-vz#sJqmNv{&5^6G>eu zHR%`lzS6NexgA`lfOObi<;$}XvdP%0VOCo@gCA;zpJ#8_0Y2Tf0z7u5|KZDHHN~v< zj{V9GO^82~KQJX&E!KSY%~3pw8yWpM>*PpJ2PjWNGVV)m8{}h$;M8_X8Zq;uG74$ zepEGNM~21YLgK)f(TEc?_~@e`NFp{(f(AfcUsFC-xh@mgbMfi~&VgIEZZY*gsumU$ zOb&1kSAXu%i6Pu8kKZ&Vbq>{~oHTK5P5;g+wO+eAD0NDip77FkAJHhZRh_>m`p}h! z*v2b#b92KZt}QQg=tlYH9ts2=1R%ei`uK{QL3^{Wimn*Ex4=XpK^LII^iNt?V2jog+$;YY;_Op zq^Nq)7bGNW48o>!x|RJt46c0`YQtau5NI@WNCH&Q+^XRSRFP~E%DjX3Ir4^J|ekWh4I8)z)Z`o6tSU<8!`55-)Y@ek^^Sg|L<{1iYxAuY7LPv;Qc;&`)nNB8-d#81ba8%Y%x!0RwbaDQ7J; zTVlRgWYQn*8?map?`$d5EKsy?Wg~myYc;O1$i~8={@EQBpCzBIde-KN?>o~LR8rHj z!wy3-_+pW0-njXVP2(d^`q~2?c~1#H63FwoKkE3wW@{NjR1klxXaIMy&<%oPPCwM( zbr1-Ii7h*iE`P~ljUONI2|28RSzfr}{p#hg-M78wgD)t_aWMr!w3Q&<=R;kSMdhF7 ztcEzILA4{}#p*n6i70QS0h^Q3RyBT7W!wJHYBi?A7ADGcJUrME5>cF=zuKHSR!iPk zPa`(}3N!rkN6pf2f|od#kzgfsR@rFp&*;MS3$!K*qiv=jz9sWD?n~a2hI|@)yLrqq z_k$99oPQ;{mE%wiUD^M1yx%hSA5$HiICY*KMsvra05NpQa-E#{o=v_>UGL=x**hD? zXmAO4uKchI<~wZ$nKG(tzNj52a7LLO>T21uM$SUsjMLO^ea^D#-4Y3{R8sbhpUQ7= z7Ht@mR5*)cg$eq?9lN~ngq_B5aonbb*OlWQZ0O2w(RtLR%0i{rY2?>Oq=^!DsOvFB znVnw11D#isfh!h^u{i;!DJgIJTi7aX5!0=H7)?JXl>9E{e~NcunhpTEYknOatRi^F9WU-r?;p`AQY JH4f(}e*sx~2d@AC diff --git a/src/assets/nav/icon5-active.png b/src/assets/nav/icon5-active.png index d17573097141ac684e623197e4d8dd8c84c9c299..a72d2c8c6e6fc931b59074f924890381a4113bb6 100644 GIT binary patch literal 11075 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 XNNvKZJZ|N^Di-iWSzD<_!7A*3Fy@5Y literal 10443 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 V-Zm5t1AZKU9L`|Tjn@8G{s$v&tsMXW literal 4256 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 iF*yA9{-2bOGv@cPnG*um(GsrDq6&91 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 literal 0 HcmV?d00001 diff --git a/src/assets/nav/icon6.png b/src/assets/nav/icon6.png new file mode 100644 index 0000000000000000000000000000000000000000..c344f1a0658af33a7a642000a5f1e607590d9d8d GIT binary patch literal 3305 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 V@k~2-0{C|Uow0PlF|n6!{0oUU-&+6x literal 0 HcmV?d00001 diff --git a/src/assets/nav/icon7-active.png b/src/assets/nav/icon7-active.png new file mode 100644 index 0000000000000000000000000000000000000000..40dada3e66c6daa2c81336345ec629235ceba3dd GIT binary patch literal 10172 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 BfKUJc literal 0 HcmV?d00001 diff --git a/src/assets/nav/mima.png b/src/assets/nav/mima.png new file mode 100644 index 0000000000000000000000000000000000000000..0d138498df379ad896d42f14225f23b7a0ec57b2 GIT binary patch literal 783 zcmV+q1MvKbP)Px%$w@>(R7gv;mQQFCQ4q$z*{rmsts1<@iuIzP;KhS@ka{T|y;entNZFlj0_i~z zMKNG4dhlW)$-Zr+f`Zz!f(K9HK}5leXsag`R1kxIT5R0SlMUJM8aCaeP2OqQ`R4oW zyf<%HLJP}v-4jyEaR5i6{$ZJ^^gBSiE>N&G6MJY(DTW7TYC zW@fljsoVpwBYaOpCoRjmA9>!*zQl2yyF_$KG09n$btOtKgt!RcY8aDJKD2H7Si8Wd zL^Q0J9JFowWt7S6?Cfse_unhA1!itMifXv&8M?0fOiFoJsqlbhS+Apjj^pehqD3Y4 zk(qbJRw#rR0>D9|5YeEN@~D#ZfQS-NCQ?ctz;PwED5ZQuL?3+Lzm-m>7wR7#J_sRh z065#`6=+E=r7YOCovClB5aKj|*eTJHdvnnQGf!8~PzdoHz@ZHq#-+bw=6xYhs%j!i z0SGSkx>u!AAtJh?82HSrM*=lX+isfXw{_D1K*8L-cTl! z`P2+pEEf0cy53`&=Bs9!LZOgMBoaTA_!2V@v<-9|Cr?D_no*IN!{=4(jsSDHoMsqC zaOdhPnN0SKj*gZaEA0qS2(bykD)W_+4C9|_?s?u|CX@No6<}0_ zx~^{?8yi!*vC8hqmd?-5CrYJK(9!DZXXfRuR9Krz1pvVhRj|6-r2(PVspCY{*W24$ zOr=swQFk$JOM_O|!bDBecABR7c_Wi%ZfPx%Qb|NXR7gv;mOW?`K^TVLcTw>NK^xm32mu=rY^)5%ze0Q_Y;jG=nHzC%QwYJgrDlGlteXEi(zS)^66qMRHO2 z6TpfHlRRgPxmu)3?Wnj909PDYTe<`nIUo>w87yN!K3i$VwM_@3)eC)#)nPH2$~NmUWu_ zBzKaWHpV>c)x75btjb=Tx7J=RvQV^4Tr|G`EYE;5*4pb@xJWJvzW^A>;2CS}P?17f zCjLZCkvx$DrUAUx77&q_3nzhwiNZ}JXEotPG9%X7N17V*-8_VF9KdZ2&?_S%lg_!* y8oqOUc<+Y+R7q|Duto!CnNK2e&^f0%QT_m?@C)lp?ih0b0000SP{)QfYREB!*%JU4~?ae1=?xf~4}|f~1`MBnAeC?UO$V z6mp7JR~s4_=qQ*>&J&bj?3~;!C@raB5h0%(|nEQS&kL)HoGfGgjeCz!#;$TazpKnq+9WP~6SLn%WhvbN2a W#nV|gvn%{!ncOHQzu83i2@?QO+CTvS delta 67 zcmV-J0KET%P=rvBPXQmXP`eKSACn9ab(3@vFq54UwFomXHY^}BF*%b@8bGs}6DS6= ZqZ(udv4G72vj-sh1hefH)dG{F8ZPNc7X| void @@ -27,11 +28,12 @@ export default function VariablesComponent({ nodeId, flowId, onChange }: { useEffect(() => { // api nodeId -> items - flowId && getVariablesApi({ + flowId && vid && getVariablesApi({ + version_id: vid, flow_id: flowId, node_id: nodeId }).then(arr => setItems(arr)) - }, [flowId]) + }, [flowId, vid]) const { openPopUp, closePopUp } = useContext(PopUpContext); const { setErrorData } = useContext(alertContext); @@ -60,6 +62,7 @@ export default function VariablesComponent({ nodeId, flowId, onChange }: { const param: any = { "flow_id": flowId, "node_id": nodeId, + version_id: vid, "variable_name": _item.name, "value_type": Number(_item.type === VariableType.Select) + 1, "value": _item.type === VariableType.Text ? _item.maxLength : _item.options.map(el => el.value).join(',') @@ -68,7 +71,7 @@ export default function VariablesComponent({ nodeId, flowId, onChange }: { param.id = _item.id } captureAndAlertRequestErrorHoc(saveVariableApi(param).then(res => { - const _items = items.map(item => item.id === _item.id ? { ..._item, id: res.id } : item) + const _items = items.map(item => item.id === _item.id ? { ..._item, id: res.id, update: true } : item) // const hasValue = _items.find(item => item.name) // 保存时 id传出去保存,用来校验必填项 onChange(_items.map(el => el.name)) diff --git a/src/components/bs-comp/.DS_Store b/src/components/bs-comp/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..158edbb1b59a1d19fa6462621cadb7d89d9e4728 GIT binary patch literal 6148 zcmeHK%Z}496uq7)L&|7G7a-UmMPgf^0W{Kx1))7Z7PfcMuGoL0kL-vXhJ^a6jFWvM%csUql8a_ga?QcN5lj8 z&7abcQ_Ly2Wh?XJ2GgPhr-Y9&9|LoW)<=+p)AQliUz=4}wl1X9PKmjlFPfLp~JG#Po-0 z?Vm|+rW2!pQDB=C5a)vp7wBrN6w0FmiF^V8JE)e1y!fLaIJQPtW2F!+Fs7(LMP>Sl z!4w_!wvKZ(RtgoJn0|aPJu=fT6edSU|F#S#<|;I)QNSp$uE4G;_Qd`F@Xzo6b&@F= z1&jh)r2y-UywMO-(syfPa^kMF;jiJsL|mm%QjqBDSZ2gkd=)MYZMMh&U5%AO)WFOi N0V#t?i~|2ufnQIe`z` { if (!chatId) return + continueRef.current = false setInputLock({ locked: false, reason: '' }) // console.log('message chatid', messages, form, chatId); setShowWhenLocked(false) @@ -85,13 +92,14 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on const event = new Event('input', { bubbles: true, cancelable: true }); inputRef.current.value = '' inputRef.current.dispatchEvent(event); // 触发调节input高度 - const [wsMsg, inputKey] = onBeforSend('', value) + const contunue = continueRef.current ? 'continue' : '' + continueRef.current = false + const [wsMsg, inputKey] = onBeforSend(contunue, value) // msg to store createSendMsg(wsMsg.inputs, inputKey) // 锁定 input setInputLock({ locked: true, reason: '' }) await createWebSocket(chatId) - // console.log(wsMsg,inputKey); sendWsMsg(wsMsg) // 滚动聊天到底 @@ -100,15 +108,13 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on messageDom.scrollTop = messageDom.scrollHeight; } } - const stop = async () => { - const [wsMsg] = onBeforSend('', '') - wsMsg.action = "stop" - sendWsMsg(wsMsg) - // console.log(wsMsg); - // sendWsMsg(wsMsg) - } + + const diffRef = useRef(0) const sendWsMsg = async (msg) => { try { + diffRef.current = Date.now() + // console.log('WebSocket send: ' + diffRef.current + ' 毫秒'); + wsRef.current.send(JSON.stringify(msg)) } catch (error) { toast({ @@ -128,14 +134,23 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on return new Promise((res, rej) => { try { + let startTime = Date.now(); const ws = new WebSocket(`${webSocketProtocol}://${wsUrl}&chat_id=${chatId}`) wsRef.current = ws // websocket linsen ws.onopen = () => { + // 记录连接成功的时间 + let endTime = Date.now(); + + // 计算连接建立所需的时间 + let connectionTime = endTime - startTime; + + // console.log('WebSocket 连接建立时间: ' + connectionTime + ' 毫秒'); console.log("WebSocket connection established!"); res('ok') }; ws.onmessage = (event) => { + // console.log(`WebSocket get: ${Date.now()} 毫秒;与send差值${Date.now() - diffRef.current}毫秒`); const data = JSON.parse(event.data); const errorMsg = data.category === 'error' ? data.intermediate_steps : '' // 异常类型处理,提示 @@ -145,13 +160,17 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on handleWsMessage(data) // 群聊@自己时,开启input if (['end', 'end_cover'].includes(data.type) && data.receiver?.is_self) { - setInputLock({ locked: true, reason: '' }) + setInputLock({ locked: false, reason: '' }) + setStop({ show: false, disable: false }) + continueRef.current = true } } ws.onclose = (event) => { wsRef.current = null console.error('链接手动断开 event :>> ', event); - if ([1005, 1008].includes(event.code)) { + setStop({ show: false, disable: false }) + + if ([1005, 1008, 1009].includes(event.code)) { console.warn('即将废弃 :>> '); setInputLock({ locked: true, reason: event.reason }) } else { @@ -167,8 +186,8 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on }; ws.onerror = (ev) => { wsRef.current = null + setStop({ show: false, disable: false }) console.error('链接异常error', ev); - setIsStop(true) toast({ title: `${t('chat.networkError')}:`, variant: 'error', @@ -189,15 +208,14 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on // 接受 ws 消息 const handleWsMessage = (data) => { - // console.log(data) if (Array.isArray(data) && data.length) return - if (data.type === "begin") { - setIsStop(false) - }else if (data.type === 'start') { + if (data.type === 'start') { + // 非continue时,展示stop按钮 + !continueRef.current && setStop({ show: true, disable: false }) createWsMsg(data) } else if (data.type === 'stream') { + //@ts-ignore updateCurrentMessage({ - flow_id: data.flow_id, chat_id: data.chat_id, message: data.message, thought: data.intermediate_steps @@ -209,16 +227,16 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on thought: data.intermediate_steps || '', messageId: data.message_id, noAccess: false, - liked: 0 + liked: 0, + update_time: formatDate(new Date(), 'yyyy-MM-ddTHH:mm:ss') }, data.type === 'end_cover') } else if (data.type === "close") { - setIsStop(true) + setStop({ show: false, disable: false }) setInputLock({ locked: false, reason: '' }) } - } - // 监听重发消息事件 + // 触发发送消息事件(重试、表单) useEffect(() => { const handleCustomEvent = (e) => { if (!showWhenLocked && inputLock.locked) return console.error('弹窗已锁定,消息无法发送') @@ -247,12 +265,12 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on // setInputEmpty(textarea.value.trim() === '') } - return

-
+ return
+
{/* form */} { formShow &&
-
+
{inputForm}
@@ -265,34 +283,51 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on onClick={handleClickGuideWord} /> {/* clear */} - {/*
+
{ clear &&
{ !inputLock.locked && destory() }} - >
+ >
} -
*/} - {/* form */} +
+ {/* form switch */}
{ form &&
(showWhenLocked || !inputLock.locked) && setFormShow(!formShow)} - >
+ >
}
{/* send */}
-
{ !inputLock.locked && handleSendClick() }} - style={{borderRadius:"20px"}} - > - {/* */} - -
+ {stop.show ? +
{ + if (stop.disable) return + setStop({ show: true, disable: true }); + sendWsMsg({ "action": "stop" }); + }}> + {/* */} + {/* { + if (stop.disable) return + setStop({ show: true, disable: true }); + sendWsMsg({ "action": "stop" }); + }} /> */} +
+
+ :
{ !inputLock.locked && handleSendClick() }} style={{borderRadius:"20px"}}> + {/* */} + +
+ }
{/* question */} - {!isStop &&
- -
} - - {/*

内容由AI生成,仅供参考

*/}

{appConfig.dialogTips}

-}; +}; \ No newline at end of file diff --git a/src/components/bs-comp/chatComponent/FileBs.tsx b/src/components/bs-comp/chatComponent/FileBs.tsx index faa0e80..7c8717b 100644 --- a/src/components/bs-comp/chatComponent/FileBs.tsx +++ b/src/components/bs-comp/chatComponent/FileBs.tsx @@ -36,7 +36,9 @@ export default function FileBs({ data,flow_type }) {
{data.sender &&

{data.sender}

}
- {data.flow_id && } + {/* {data.flow_id && } */} + {flow_type.id && } + {/*
*/}
{ }, flow_type, onSou const handleCopyMessage = () => { copyText(messageRef.current) } - // console.log(data) const chatId = useMessageStore(state => state.chatId) return
@@ -94,7 +93,7 @@ export default function MessageBs({ data, onUnlike = () => { }, flow_type, onSou {/* {(data.flow_id == "06b1d374-ba97-46e6-8782-c56dec8dcc17" || data.flow_id == "ed8e21f6-9757-43d0-b076-8c6e81bb0580") && } {data.flow_id == "ca214b41-2b73-4585-b172-bf1e546cf6ec" && } {(data.flow_id != "06b1d374-ba97-46e6-8782-c56dec8dcc17" && data.flow_id != "ed8e21f6-9757-43d0-b076-8c6e81bb0580" && data.flow_id != "ca214b41-2b73-4585-b172-bf1e546cf6ec") && } */} - {data.flow_id && } + {flow_type && flow_type.id && }
{/*
diff --git a/src/components/bs-comp/chatComponent/MessagePanne.tsx b/src/components/bs-comp/chatComponent/MessagePanne.tsx index 0797967..1416b98 100644 --- a/src/components/bs-comp/chatComponent/MessagePanne.tsx +++ b/src/components/bs-comp/chatComponent/MessagePanne.tsx @@ -10,7 +10,7 @@ import RunLog from "./RunLog"; import Separator from "./Separator"; import { useMessageStore } from "./messageStore"; -export default function MessagePanne({ useName, guideWord, loadMore, flow_type }) { +export default function MessagePanne({logo, useName, guideWord, loadMore, flow_type }) { const { t } = useTranslation() const { chatId, messages } = useMessageStore() @@ -75,7 +75,6 @@ export default function MessagePanne({ useName, guideWord, loadMore, flow_type } } else if (msg.thought) { type = 'system' } - // console.log(type) switch (type) { case 'user': return ; diff --git a/src/components/bs-comp/chatComponent/index.tsx b/src/components/bs-comp/chatComponent/index.tsx index 92b024b..40b0c9d 100644 --- a/src/components/bs-comp/chatComponent/index.tsx +++ b/src/components/bs-comp/chatComponent/index.tsx @@ -1,9 +1,22 @@ import ChatInput from "./ChatInput"; import MessagePanne from "./MessagePanne"; -export default function ChatComponent({ clear = false, questions = [], form = false, useName, inputForm = null, guideWord, wsUrl, onBeforSend, type, loadMore = () => { } }) { +export default function ChatComponent({ + stop = false, + logo = '', + clear = false, + questions = [], + form = false, + useName, + inputForm = null, + guideWord, + wsUrl, + onBeforSend, + type, + loadMore = () => { } +}) { return
- +
}; diff --git a/src/components/bs-comp/chatComponent/messageStore.ts b/src/components/bs-comp/chatComponent/messageStore.ts index 2b13410..28ee300 100644 --- a/src/components/bs-comp/chatComponent/messageStore.ts +++ b/src/components/bs-comp/chatComponent/messageStore.ts @@ -4,6 +4,7 @@ import { MessageDB, getChatHistory } from '@/controllers/API' import { ChatMessageType } from '@/types/chat' import { cloneDeep } from 'lodash' import { create } from 'zustand' +import { formatDate } from '@/util/utils'; /** * 会话消息管理 @@ -19,6 +20,8 @@ type State = { /** 没有更多历史纪录 */ historyEnd: boolean, messages: ChatMessageType[] + /** 历史回话独立存储 */ + hisMessages: ChatMessageType[] /** * 控制引导问题的显示状态 */ @@ -26,8 +29,8 @@ type State = { } type Actions = { - loadHistoryMsg: (flowid: string, chatId: string, flow_type: string) => Promise; - loadMoreHistoryMsg: (flowid: string, flow_type: string) => Promise; + loadHistoryMsg: (flowid: string, chatId: string, data: { appendHistory: boolean, lastMsg: string }, flow_type: string) => Promise; + loadMoreHistoryMsg: (flowid: string, appendHistory: boolean, flow_type: string) => Promise; destory: () => void; createSendMsg: (inputs: any, inputKey?: string) => void; createWsMsg: (data: any) => void; @@ -38,6 +41,7 @@ type Actions = { insetSystemMsg: (text: string) => void; insetBsMsg: (text: string) => void; setShowGuideQuestion: (text: boolean) => void; + clearMsgs: () => void; } @@ -76,18 +80,32 @@ export const useMessageStore = create((set, get) => ({ running: false, chatId: '', messages: [], + hisMessages: [], historyEnd: false, showGuideQuestion: false, setShowGuideQuestion(bln: boolean) { set({ showGuideQuestion: bln }) }, - async loadHistoryMsg(flowid, chatId, flow_type) { + async loadHistoryMsg(flowid, chatId, { appendHistory, lastMsg }, flow_type) { const res = await getChatHistory(flowid, chatId, 30, 0, flow_type) const msgs = handleHistoryMsg(res) currentChatId = chatId - set({ historyEnd: false, messages: msgs.reverse() }) + const hisMessages = appendHistory ? [] : msgs.reverse() + if (hisMessages.length) { + hisMessages.push({ + ...bsMsgItem, + id: Math.random() * 1000000, + category: 'divider', + message: lastMsg, + }) + } + set({ + historyEnd: false, + messages: appendHistory ? msgs.reverse() : [], + hisMessages + }) }, - async loadMoreHistoryMsg(flowid, flow_type) { + async loadMoreHistoryMsg(flowid, appendHistory, flow_type) { if (get().running) return // 会话进行中禁止加载more历史 if (get().historyEnd) return // 没有更多历史纪录 const chatId = get().chatId @@ -101,11 +119,16 @@ export const useMessageStore = create((set, get) => ({ } const msgs = handleHistoryMsg(res) if (msgs.length) { - set({ messages: [...msgs.reverse(), ...prevMsgs] }) + set({ [appendHistory ? 'messages' : 'hisMessages']: [...msgs.reverse(), ...prevMsgs] }) } else { set({ historyEnd: true }) } }, + clearMsgs() { + setTimeout(() => { + set({ hisMessages: [], messages: [], historyEnd: true }) + }, 0); + }, destory() { set({ chatId: '', messages: [] }) }, @@ -122,7 +145,8 @@ export const useMessageStore = create((set, get) => ({ category: '', files: [], end: false, - user_name: "" + user_name: "", + update_time: formatDate(new Date(), 'yyyy-MM-ddTHH:mm:ss') }] })) }, @@ -151,13 +175,20 @@ export const useMessageStore = create((set, get) => ({ // if (wsdata.end) { // debugger // } - console.log('change updateCurrentMessage'); + // console.log('change updateCurrentMessage'); const messages = get().messages const isRunLog = runLogsTypes.includes(wsdata.category); // run log类型存在嵌套情况,使用 extra 匹配 currentMessage; 否则取最近 - const currentMessageIndex = isRunLog ? - messages.findLastIndex((msg) => msg.extra === wsdata.extra) - : messages.findLastIndex((msg) => !runLogsTypes.includes(msg.category)) + let currentMessageIndex = 0 + for (let i = messages.length - 1; i >= 0; i--) { + if (isRunLog && messages[i].extra === wsdata.extra) { + currentMessageIndex = i; + break; + } else if (!isRunLog && !runLogsTypes.includes(messages[i].category)) { + currentMessageIndex = i; + break; + } + } const currentMessage = messages[currentMessageIndex] const newCurrentMessage = { @@ -166,13 +197,17 @@ export const useMessageStore = create((set, get) => ({ id: isRunLog ? wsdata.extra : wsdata.messageId, // 每条消息必唯一 message: isRunLog ? JSON.parse(wsdata.message) : currentMessage.message + wsdata.message, thought: currentMessage.thought + (wsdata.thought ? `${wsdata.thought}\n` : ''), - files: wsdata.files || null, + files: wsdata.files || [], category: wsdata.category || '', source: wsdata.source } + // 无id补上(如文件解析完成消息,后端无返回messageid) + if (!newCurrentMessage.id) { + newCurrentMessage.id = Math.random() * 1000000 + // console.log('msg:', newCurrentMessage); + } messages[currentMessageIndex] = newCurrentMessage - // console.log(messages,currentMessageIndex,newCurrentMessage) // 会话特殊处理,兼容后端的缺陷 if (!isRunLog) { // start - end 之间没有内容删除load diff --git a/src/components/bs-comp/loadMore/index.tsx b/src/components/bs-comp/loadMore/index.tsx new file mode 100644 index 0000000..35e866a --- /dev/null +++ b/src/components/bs-comp/loadMore/index.tsx @@ -0,0 +1,24 @@ +import { useEffect, useRef } from "react"; + +export default function LoadMore({ onScrollLoad }) { + // scroll load + const footerRef = useRef(null) + useEffect(function () { + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + onScrollLoad() + } + }); + }, { + // root: null, // 视口 + rootMargin: '0px', // 视口的边距 + threshold: 0.1 // 目标元素超过视口的10%即触发回调 + }); + + observer.observe(footerRef.current); + return () => footerRef.current && observer.unobserve(footerRef.current); + }, []) + + return
+}; diff --git a/src/components/bs-comp/selectComponent/Users.tsx b/src/components/bs-comp/selectComponent/Users.tsx new file mode 100644 index 0000000..655e77c --- /dev/null +++ b/src/components/bs-comp/selectComponent/Users.tsx @@ -0,0 +1,48 @@ +import MultiSelect from "@/components/bs-ui/select/multi"; +import { getUsersApi } from "@/controllers/API/user"; +import { useEffect, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; + +export default function UsersSelect({ multiple = false, lockedValues = [], value, disabled = false, onChange, children }: + { multiple?: boolean, lockedValues?: any[], value: any, disabled?: boolean, onChange: (a: any) => any, children?: (fun: any) => React.ReactNode }) { + + const { t } = useTranslation() + const [options, setOptions] = useState([]); + const originOptionsRef = useRef([]) + + const pageRef = useRef(1) + const reload = (page, name) => { + getUsersApi({ page, pageSize: 40, name }).then(res => { + pageRef.current = page + originOptionsRef.current = res.data + const opts = res.data.map(el => ({ label: el.user_name, value: el.user_id })) + setOptions(_ops => page > 1 ? [..._ops, ...opts] : opts) + }) + } + + useEffect(() => { + reload(1, '') + }, []) + + // 加载更多 + const loadMore = (name) => { + reload(pageRef.current + 1, name) + } + + return reload(1, '')} + onSearch={(val) => reload(1, val)} + onScrollLoad={(val) => loadMore(val)} + > + {children?.(reload)} + +}; diff --git a/src/components/bs-comp/selectComponent/knowledge.tsx b/src/components/bs-comp/selectComponent/knowledge.tsx new file mode 100644 index 0000000..5b22111 --- /dev/null +++ b/src/components/bs-comp/selectComponent/knowledge.tsx @@ -0,0 +1,51 @@ +import MultiSelect from "@/components/bs-ui/select/multi"; +import { readFileLibDatabase } from "@/controllers/API"; +import { useEffect, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; + +export default function KnowledgeSelect({ multiple = false, value, disabled = false, onChange, children }: + { multiple?: boolean, value: any, disabled?: boolean, onChange: (a: any) => any, children?: (fun: any) => React.ReactNode }) { + + const { t } = useTranslation() + const [options, setOptions] = useState([]); + const originOptionsRef = useRef([]) + + const pageRef = useRef(1) + const reload = (page, name) => { + readFileLibDatabase(page, 60, name).then(res => { + pageRef.current = page + originOptionsRef.current = res.data + const opts = res.data.map(el => ({ label: el.name, value: el.id })) + setOptions(_ops => page > 1 ? [..._ops, ...opts] : opts) + }) + } + + useEffect(() => { + reload(1, '') + }, []) + + // const handleChange = (res) => { + // // id => obj + // onChange(res.map(el => originOptionsRef.current.find(el2 => el2.id === el))) + // } + + // 加载更多 + const loadMore = (name) => { + reload(pageRef.current + 1, name) + } + + return reload(1, '')} + onSearch={(val) => reload(1, val)} + onScrollLoad={(val) => loadMore(val)} + > + {children?.(reload)} + +}; diff --git a/src/components/bs-comp/sheets/SkillChatSheet.tsx b/src/components/bs-comp/sheets/SkillChatSheet.tsx index 8af1ac7..cf14c32 100644 --- a/src/components/bs-comp/sheets/SkillChatSheet.tsx +++ b/src/components/bs-comp/sheets/SkillChatSheet.tsx @@ -19,6 +19,8 @@ import zidingyi1 from "../../../assets/npc/zidingyi1.png"; import zidingyi2 from "../../../assets/npc/zidingyi2.png"; import npcIcon from "../../../assets/npc/npcIcon.png"; import nengliIcon from "../../../assets/npc/nengliIcon.png"; +import { useDebounce } from "@/util/hook"; +import LoadMore from "../loadMore"; export default function SkillChatSheet({ children, onSelect }) { const [open, setOpen] = useState(false) @@ -30,34 +32,45 @@ export default function SkillChatSheet({ children, onSelect }) { const [keyword, setKeyword] = useState(' ') const allDataRef = useRef([]) - useEffect(() => { - open && getChatOnlineApi().then(res => { - allDataRef.current = res - setKeyword('') + const pageRef = useRef(1) + const searchRef = useRef('') + const [options, setOptions] = useState([]) + + const loadData = (more = false) => { + open && getChatOnlineApi(pageRef.current, searchRef.current).then(res => { + setOptions(opts => more ? [...opts, ...res] : res) }) + } + const debounceLoad = useDebounce(loadData, 600, false) + + useEffect(() => { + // open && getChatOnlineApi().then(res => { + // allDataRef.current = res + // setKeyword('') + // }) // setKeyword(' ') + pageRef.current = 1 + searchRef.current = '' + loadData() }, [open]) - const options = useMemo(() => { - return allDataRef.current.filter(el => el.name.toLowerCase().includes(keyword.toLowerCase())) - }, [keyword]) + // const options = useMemo(() => { + // return allDataRef.current.filter(el => el.name.toLowerCase().includes(keyword.toLowerCase())) + // }, [keyword]) + + const handleSearch = (e) => { + pageRef.current = 1 + searchRef.current = e.target.value + debounceLoad() + } + + const handleLoadMore = () => { + pageRef.current++ + loadData(true) + } const render = (item: any) => ( { onSelect(item); setOpen(false) }}> - {/* */} - {/* -
{item.name}
-
{item.name}
-
*/} - {/* onSelect(item)}> - - -
- {item.name} -
- {item.description} -
-
*/}
@@ -68,16 +81,11 @@ export default function SkillChatSheet({ children, onSelect }) {
- {/* {(item.id == "06b1d374-ba97-46e6-8782-c56dec8dcc17" || item.id == "ed8e21f6-9757-43d0-b076-8c6e81bb0580") && } - {item.id == "ca214b41-2b73-4585-b172-bf1e546cf6ec" && } - {(item.id != "06b1d374-ba97-46e6-8782-c56dec8dcc17" && item.id != "ed8e21f6-9757-43d0-b076-8c6e81bb0580" && item.id != "ca214b41-2b73-4585-b172-bf1e546cf6ec") && } */} - {/* */}

{item.name}

- {/*
绘画类
-
绘画类
*/} +
@@ -100,31 +108,12 @@ export default function SkillChatSheet({ children, onSelect }) {
选择对话 选择一个您想使用的上线NPC或能力 - setKeyword(e.target.value)} /> + {/* setKeyword(e.target.value)} /> */} +
- {/* { - options.length ? options.map((flow, i) => ( - - {flow.flow_type === 'flow' ? '技能' : 'NPC'} - - } - onClick={() => { onSelect(flow); setOpen(false) }} - /> - )) :
-

{t('build.empty')}

- -
- } */} +
diff --git a/src/components/bs-icons/.DS_Store b/src/components/bs-icons/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..cdbb4d8071c03c2d22a0d5c9498becaaa29d6ca9 GIT binary patch literal 8196 zcmeHMO>fgc5S>kCnD01_Y}S>nQ>f|{zO6_+%H0|$ge5F7xNqzSE6#~bp|AXP=V z1Al?PfH=bcfd9e?-i%$eyJk^S_PP#GCMIs8(*)A?%IHB=* z?sKhF9JvOo;7_FQrFy56>dqY2AMgx#20R0v0ndPE;O}4nb2hi|lzBft>qpOkXW+kN zfa^nq&bCq5S#G6tV2~vMY=Fbku#a_s_(X+m6n2(daYf90^`Ht@RV*=7?vC>j!(khR zo#i%nCzZRCDz2=G6^fFp!!HszsYY)7=o#<~%rn4i_X@SCi|vuMe&-iy6aD%RY2sQ3 za)d2GA7ekGv9aQ3kB^Q=6{rJrMh|VQy5e9%>X62^PY-B7J<1&XTL)jE9ZG?lkNn+1 zmhp5wO6_>1-IGzB>1a@V!}!t}q{(Q!y!=g-%0Z=C3&U_BeBRpA)7H2>o{XC9;Zy$g zNb9t7yx;CTPI}Yr#q(P_8@H3JHx!4Y+XLj;lO*fvX;V+K?nr!F`H8SzuWv72K0J)$ zTkA_v9IqTLMThat)#asVZT;raQ9ZnH^~UXo+xuxh)9-NaXsRfObT z!z|SqKP{sJaG`1HvRnF!b7rnf^BE{_IhZQFgced{x94WJ{K>%vz-k&&-_C+)?1Q1P zD(xcXnD%Hw9S6(mGO;CK&2LUnps32kgou_&{$JB|#2wi&6|2g`*P*{m7-DU8afP1a z!Rj(SYG6P^gxHNhPq<^x1^5+u?y(dQTg$#0^p43Mk@g@a2{ zGJhqOqdI5FQA4;a^Bwm(T8ZBAH_7Wxdm!mH4ek}G#i z_qpWJzT*d3T7H4};Z?G6EJz18LOgKk;E)>&SH&Gju>})*HkR{aVFSV9wR3PN3Kp&= zxUu9SBj?qTT)Z)IQ2}}%nMmDIE}1ZqWkhVd<%3IuGEr5axXko1@tjZ=EG$P%Xkb5& zV$RKo6`;5jV0yHX!n%nJ1gYI8;WBJRtm6Jyvr=H}n8Lap6WT+LoQam-2P-DO%xLA@ zTwH*?d;0hP9OXyPfM?*JWIzRXT6dawwBtV}-KXTWc7*-{og3q3xfK@-vK)t% - - + + + fill="#666" /> \ No newline at end of file diff --git a/src/components/bs-icons/del/index.tsx b/src/components/bs-icons/del/index.tsx index 9311cb6..d5ba290 100644 --- a/src/components/bs-icons/del/index.tsx +++ b/src/components/bs-icons/del/index.tsx @@ -5,5 +5,5 @@ export const DelIcon = forwardRef< SVGSVGElement & { className: any }, React.PropsWithChildren<{ className?: string }> >((props, ref) => { - return ; + return ; }); diff --git a/src/components/bs-icons/down/DropDown.svg b/src/components/bs-icons/down/DropDown.svg new file mode 100644 index 0000000..520177b --- /dev/null +++ b/src/components/bs-icons/down/DropDown.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/components/bs-icons/down/index.tsx b/src/components/bs-icons/down/index.tsx new file mode 100644 index 0000000..432f3fe --- /dev/null +++ b/src/components/bs-icons/down/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import { ReactComponent as DropDown } from "./DropDown.svg"; + +export const DropDownIcon = forwardRef< + SVGSVGElement & { className: any }, + React.PropsWithChildren<{ className?: string }> +>((props, ref) => { + return ; +}); \ No newline at end of file diff --git a/src/components/bs-icons/en/En.svg b/src/components/bs-icons/en/En.svg index e7d4ea3..f0cad0e 100644 --- a/src/components/bs-icons/en/En.svg +++ b/src/components/bs-icons/en/En.svg @@ -1,3 +1,3 @@ - + diff --git a/src/components/bs-icons/filter/Filter.svg b/src/components/bs-icons/filter/Filter.svg new file mode 100644 index 0000000..d4e2e2f --- /dev/null +++ b/src/components/bs-icons/filter/Filter.svg @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/src/components/bs-icons/filter/index.tsx b/src/components/bs-icons/filter/index.tsx new file mode 100644 index 0000000..de5c392 --- /dev/null +++ b/src/components/bs-icons/filter/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import { ReactComponent as Filter } from "./Filter.svg"; + +export const FilterIcon = forwardRef< + SVGSVGElement & { className: any }, + React.PropsWithChildren<{ className?: string }> +>((props, ref) => { + return ; +}); \ No newline at end of file diff --git a/src/components/bs-icons/index.ts b/src/components/bs-icons/index.ts new file mode 100644 index 0000000..8fcf52f --- /dev/null +++ b/src/components/bs-icons/index.ts @@ -0,0 +1,40 @@ +export { AddToIcon } from './addTo'; +export { ApplicationIcon } from './menu/application'; +export { AssistantIcon } from './assistant'; +export { AvatarIcon } from './avatar'; +export { BookOpenIcon } from './bookOpen'; +export { ClearIcon } from './clear'; +export { DelIcon } from './del'; +export { EnIcon } from './en'; +export { FilterIcon } from './filter'; +export { FormIcon } from './form'; +export { GithubIcon } from './github'; +export { GoIcon } from './go'; +export { KnowledgeIcon } from './knowledge'; +export { LoadIcon } from './loading'; +export { ModelIcon } from './menu/model'; +export { MoonIcon } from './moon'; +export { MoveOneIcon } from './moveOne'; +export { NewApplicationIcon } from './newApplication'; +export { WordIcon } from './office'; +export { PlusIcon } from './plus'; +export { PlusBoxIcon } from './plusBox'; +export { QuestionMarkIcon } from './questionMark'; +export { QuitIcon } from './quit'; +export { SaveIcon } from './save'; +export { SearchIcon } from './search'; +export { SendIcon } from './send'; +export { SettingIcon } from './setting'; +export { SkillIcon } from './skill'; +export { SystemIcon } from './menu/system'; +export { TabIcon } from './tab'; +export { TechnologyIcon } from './menu/technology'; +export { ThunmbIcon } from './thumbs'; +export { TipIcon } from './tip'; +export { ToastIcon } from './toast'; +export { ToolIcon } from './tool'; +export { UploadIcon } from './upload'; +export { UserIcon } from './user'; +export { LogIcon } from './menu/log'; +export { EvaluatingIcon } from './menu/evaluation'; +export { DropDownIcon } from './down' diff --git a/src/components/bs-icons/application/Application.svg b/src/components/bs-icons/menu/application/Application.svg similarity index 100% rename from src/components/bs-icons/application/Application.svg rename to src/components/bs-icons/menu/application/Application.svg diff --git a/src/components/bs-icons/application/index.tsx b/src/components/bs-icons/menu/application/index.tsx similarity index 100% rename from src/components/bs-icons/application/index.tsx rename to src/components/bs-icons/menu/application/index.tsx diff --git a/src/components/bs-icons/menu/evaluation/Evaluation.svg b/src/components/bs-icons/menu/evaluation/Evaluation.svg new file mode 100644 index 0000000..5775358 --- /dev/null +++ b/src/components/bs-icons/menu/evaluation/Evaluation.svg @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/src/components/bs-icons/menu/evaluation/index.tsx b/src/components/bs-icons/menu/evaluation/index.tsx new file mode 100644 index 0000000..c84605f --- /dev/null +++ b/src/components/bs-icons/menu/evaluation/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import { ReactComponent as Icon } from "./Evaluation.svg"; + +export const EvaluatingIcon = forwardRef< + SVGSVGElement & { className: any }, + React.PropsWithChildren<{ className?: string }> +>(({ className, ...props }, ref) => { + return ; +}); \ No newline at end of file diff --git a/src/components/bs-icons/menu/log/Log.svg b/src/components/bs-icons/menu/log/Log.svg new file mode 100644 index 0000000..ac0bcf3 --- /dev/null +++ b/src/components/bs-icons/menu/log/Log.svg @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/src/components/bs-icons/menu/log/index.tsx b/src/components/bs-icons/menu/log/index.tsx new file mode 100644 index 0000000..3fa9b18 --- /dev/null +++ b/src/components/bs-icons/menu/log/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import { ReactComponent as Log } from "./Log.svg"; + +export const LogIcon = forwardRef< + SVGSVGElement & { className: any }, + React.PropsWithChildren<{ className?: string }> +>(({ className, ...props }, ref) => { + return ; +}); \ No newline at end of file diff --git a/src/components/bs-icons/model/Model.svg b/src/components/bs-icons/menu/model/Model.svg similarity index 100% rename from src/components/bs-icons/model/Model.svg rename to src/components/bs-icons/menu/model/Model.svg diff --git a/src/components/bs-icons/model/index.tsx b/src/components/bs-icons/menu/model/index.tsx similarity index 100% rename from src/components/bs-icons/model/index.tsx rename to src/components/bs-icons/menu/model/index.tsx diff --git a/src/components/bs-icons/system/System.svg b/src/components/bs-icons/menu/system/System.svg similarity index 100% rename from src/components/bs-icons/system/System.svg rename to src/components/bs-icons/menu/system/System.svg diff --git a/src/components/bs-icons/system/index.tsx b/src/components/bs-icons/menu/system/index.tsx similarity index 100% rename from src/components/bs-icons/system/index.tsx rename to src/components/bs-icons/menu/system/index.tsx diff --git a/src/components/bs-icons/technology/Technology.svg b/src/components/bs-icons/menu/technology/Technology.svg similarity index 100% rename from src/components/bs-icons/technology/Technology.svg rename to src/components/bs-icons/menu/technology/Technology.svg diff --git a/src/components/bs-icons/technology/index.tsx b/src/components/bs-icons/menu/technology/index.tsx similarity index 100% rename from src/components/bs-icons/technology/index.tsx rename to src/components/bs-icons/menu/technology/index.tsx diff --git a/src/components/bs-icons/office/index.tsx b/src/components/bs-icons/office/index.tsx index 60a88a8..10e6163 100644 --- a/src/components/bs-icons/office/index.tsx +++ b/src/components/bs-icons/office/index.tsx @@ -5,6 +5,6 @@ export const WordIcon = forwardRef< SVGSVGElement & { className: any }, React.PropsWithChildren<{ className?: string }> >(({ className, ...props }, ref) => { - const _className = 'transition text-[#43AFD2] ' + (className || '') + const _className = 'transition text-gray-950 ' + (className || '') return ; }); diff --git a/src/components/bs-icons/plusBox/PlusBox.svg b/src/components/bs-icons/plusBox/PlusBox.svg index bbf3b3e..117bfcc 100644 --- a/src/components/bs-icons/plusBox/PlusBox.svg +++ b/src/components/bs-icons/plusBox/PlusBox.svg @@ -1,10 +1,13 @@ - - - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/src/components/bs-icons/questionMark/index.tsx b/src/components/bs-icons/questionMark/index.tsx index da07354..afed6f1 100644 --- a/src/components/bs-icons/questionMark/index.tsx +++ b/src/components/bs-icons/questionMark/index.tsx @@ -5,6 +5,6 @@ export const QuestionMarkIcon = forwardRef< SVGSVGElement & { className: any }, React.PropsWithChildren<{ className?: string }> >(({ className, ...props }, ref) => { - const _className = 'transition text-gray-950 ' + (className || '') + const _className = 'transition text-[#999] ' + (className || '') return ; }); diff --git a/src/components/bs-icons/quit/Quit-dark.svg b/src/components/bs-icons/quit/Quit-dark.svg deleted file mode 100644 index 37c3cc3..0000000 --- a/src/components/bs-icons/quit/Quit-dark.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/components/bs-icons/quit/Quit.svg b/src/components/bs-icons/quit/Quit.svg index 260f02a..6313b64 100644 --- a/src/components/bs-icons/quit/Quit.svg +++ b/src/components/bs-icons/quit/Quit.svg @@ -1,8 +1,11 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/src/components/bs-icons/quit/index.tsx b/src/components/bs-icons/quit/index.tsx index da09bec..bd198cd 100644 --- a/src/components/bs-icons/quit/index.tsx +++ b/src/components/bs-icons/quit/index.tsx @@ -1,17 +1,9 @@ import React, { forwardRef } from "react"; import { ReactComponent as Quit } from "./Quit.svg"; -import { ReactComponent as QuitDark } from "./Quit-dark.svg"; export const QuitIcon = forwardRef< SVGSVGElement & { className: any }, React.PropsWithChildren<{ className?: string }> ->(({className,...props}, ref) => { - return ; -}); - -export const QuitIconDark = forwardRef< - SVGSVGElement & { className: any }, - React.PropsWithChildren<{ className?: string }> ->(({className,...props}, ref) => { - return ; +>(({ className, ...props }, ref) => { + return ; }); \ No newline at end of file diff --git a/src/components/bs-icons/search/Search.svg b/src/components/bs-icons/search/Search.svg index 8929c0f..469d30f 100644 --- a/src/components/bs-icons/search/Search.svg +++ b/src/components/bs-icons/search/Search.svg @@ -1,8 +1,8 @@ - - + + \ No newline at end of file diff --git a/src/components/bs-icons/thumbs/copy.svg b/src/components/bs-icons/thumbs/copy.svg index a00df83..dd48ab2 100644 --- a/src/components/bs-icons/thumbs/copy.svg +++ b/src/components/bs-icons/thumbs/copy.svg @@ -1,8 +1,8 @@ - + - \ No newline at end of file diff --git a/src/components/bs-icons/thumbs/copyDark.svg b/src/components/bs-icons/thumbs/copyDark.svg deleted file mode 100644 index a917cc5..0000000 --- a/src/components/bs-icons/thumbs/copyDark.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/components/bs-icons/thumbs/index.tsx b/src/components/bs-icons/thumbs/index.tsx index eaa613d..fcfc2fe 100644 --- a/src/components/bs-icons/thumbs/index.tsx +++ b/src/components/bs-icons/thumbs/index.tsx @@ -1,11 +1,8 @@ import React, { forwardRef } from "react"; import { ReactComponent as copy } from "./copy.svg"; -import { ReactComponent as copyDark } from "./copyDark.svg"; import { ReactComponent as like } from "./like.svg"; -import { ReactComponent as likeDark } from "./likeDark.svg"; import { ReactComponent as unLike } from "./unLike.svg"; -import { ReactComponent as unLikeDark } from "./unLikeDark.svg"; - +import { cname } from "@/components/bs-ui/utils"; type ThunmbIconType = 'copy' | 'like' | 'unLike' | 'copyDark' | 'likeDark' | 'unLikeDark'; @@ -15,13 +12,10 @@ export const ThunmbIcon = forwardRef< >((props, ref) => { const comps = { 'copy': copy, - 'copyDark': copyDark, 'like': like, - 'likeDark': likeDark, 'unLike': unLike, - 'unLikeDark': unLikeDark, } const Comp = comps[props.type]; - const _className = 'transition text-gray-400 ' + (props.className || '') + const _className = cname('transition text-gray-400 hover:text-gray-500', props.className) return ; }); diff --git a/src/components/bs-icons/thumbs/like.svg b/src/components/bs-icons/thumbs/like.svg index 948999c..01c4599 100644 --- a/src/components/bs-icons/thumbs/like.svg +++ b/src/components/bs-icons/thumbs/like.svg @@ -1,15 +1,15 @@ - + - + + fill="transparent" /> diff --git a/src/components/bs-icons/thumbs/likeDark.svg b/src/components/bs-icons/thumbs/likeDark.svg deleted file mode 100644 index 67a6053..0000000 --- a/src/components/bs-icons/thumbs/likeDark.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/src/components/bs-icons/thumbs/unLike.svg b/src/components/bs-icons/thumbs/unLike.svg index e61a684..09e5c71 100644 --- a/src/components/bs-icons/thumbs/unLike.svg +++ b/src/components/bs-icons/thumbs/unLike.svg @@ -2,15 +2,15 @@ + transform="rotate(-180 19.25 14.25)" fill="transparent" stroke="currentColor" stroke-width="1.5" /> - + + fill="transparent" /> diff --git a/src/components/bs-icons/thumbs/unLikeDark.svg b/src/components/bs-icons/thumbs/unLikeDark.svg deleted file mode 100644 index 9224027..0000000 --- a/src/components/bs-icons/thumbs/unLikeDark.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/components/bs-icons/upload/index.tsx b/src/components/bs-icons/upload/index.tsx index eb5df7c..81dcbef 100644 --- a/src/components/bs-icons/upload/index.tsx +++ b/src/components/bs-icons/upload/index.tsx @@ -5,6 +5,6 @@ export const UploadIcon = forwardRef< SVGSVGElement & { className: any }, React.PropsWithChildren<{ className?: string }> >(({ className, ...props }, ref) => { - const _className = 'transition text-gray-950 ' + (className || '') + const _className = 'transition text-[#ffd025] ' + (className || '') return ; }); diff --git a/src/components/bs-ui/.DS_Store b/src/components/bs-ui/.DS_Store index 46b1205f7e4e2c35c95b3602e5293bd3da39f927..2f620eece3313873dc5d56de5b7e63f5bf63222e 100644 GIT binary patch delta 174 zcmZp1XmOa}&nUMsU^hRb++-esgQ^@1$qb1MISi=`c?>B)R*`2;esWSyei8!%g8%~q zOD~X~H~EmjTlP$#iUNkx$;X6S7)>X8i@1wIMHouTf{XHU^7GPxY8fZ55`4(value) + + const dateStr = useMemo(() => { + return date ? formatDate(date, 'yyyy-MM-dd') : '' + }, [date]) + + React.useEffect(() => { + setDate(value) + },[value]) + + return ( + + + {placeholder}} + + + + { + setDate(d) + onChange?.(d) + }} + initialFocus + /> + + + ) +} diff --git a/src/components/bs-ui/calendar/index.tsx b/src/components/bs-ui/calendar/index.tsx new file mode 100644 index 0000000..6727c2b --- /dev/null +++ b/src/components/bs-ui/calendar/index.tsx @@ -0,0 +1,72 @@ +"use client" + +import * as React from "react" +import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons" +import { DayPicker } from "react-day-picker" + +import { buttonVariants } from "@/components/bs-ui/button" +import { cname } from "../utils" + +export type CalendarProps = React.ComponentProps + +function Calendar({ + className, + classNames, + showOutsideDays = true, + ...props +}: CalendarProps) { + return ( + .day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" + : "[&:has([aria-selected])]:rounded-md" + ), + day: cname( + buttonVariants({ variant: "ghost" }), + "h-8 w-8 p-0 font-normal aria-selected:opacity-100" + ), + day_range_start: "day-range-start", + day_range_end: "day-range-end", + day_selected: + "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground", + day_today: "bg-accent text-accent-foreground", + day_outside: + "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30", + day_disabled: "text-muted-foreground opacity-50", + day_range_middle: + "aria-selected:bg-accent aria-selected:text-accent-foreground", + day_hidden: "invisible", + ...classNames, + }} + components={{ + IconLeft: ({ ...props }) => , + IconRight: ({ ...props }) => , + }} + {...props} + /> + ) +} +Calendar.displayName = "Calendar" + +export { Calendar } diff --git a/src/components/bs-ui/dialog/index.tsx b/src/components/bs-ui/dialog/index.tsx index fd87d5a..5b1bfa0 100644 --- a/src/components/bs-ui/dialog/index.tsx +++ b/src/components/bs-ui/dialog/index.tsx @@ -42,7 +42,7 @@ const DialogContent = React.forwardRef< {...props} > {children} - + Close diff --git a/src/components/bs-ui/input/avator.tsx b/src/components/bs-ui/input/avator.tsx new file mode 100644 index 0000000..960a1ae --- /dev/null +++ b/src/components/bs-ui/input/avator.tsx @@ -0,0 +1,46 @@ +import { Button } from "../button"; +import { useToast } from "../toast/use-toast"; +import { cname } from "../utils"; + +// 头像 +export default function Avator({ + size = 5 * 1024 * 1024, + accept = "image/jpeg,image/png", + value, + className, + buttonName = '上传头像', + onChange, + children +}) { + const { message } = useToast(); + + const handleFileChange = (event) => { + const file = event.target.files[0]; + if (file) { + const isValidSize = file.size <= size; + const isValidType = accept.split(',').some(type => file.type === type); + + const errormgs = [] + if (!isValidSize) errormgs.push(`文件大小不能超过 ${size / 1024 / 1024}MB`) + if (!isValidType) errormgs.push(`文件类型不符合要求:${accept}`) + + errormgs.length ? message({ + variant: 'error', + description: errormgs + }) : onChange(file) + } + }; + + return
+ {value ? : children} + +
+}; diff --git a/src/components/bs-ui/input/index.tsx b/src/components/bs-ui/input/index.tsx index 1bc4b29..e5b8e43 100644 --- a/src/components/bs-ui/input/index.tsx +++ b/src/components/bs-ui/input/index.tsx @@ -3,6 +3,9 @@ import { cname } from "../utils" import { SearchIcon } from "../../bs-icons/search" import { generateUUID } from "../utils" import { MinusCircledIcon } from "@radix-ui/react-icons" +import { EyeOpenIcon, EyeNoneIcon } from "@radix-ui/react-icons" +import { useState } from "react" + import sousuo from "../../../assets/npc/sousuo1.png" export interface InputProps extends React.InputHTMLAttributes { } @@ -13,7 +16,7 @@ const Input = React.forwardRef( { return
{/* */} - - +
+ +
+
} ) SearchInput.displayName = "SearchInput" +const PasswordInput = React.forwardRef( + ({ className, inputClassName, iconClassName, ...props }, ref) => { + const [type, setType] = useState('password') + const handleShowPwd = () => { + type === 'password' ? setType('text') : setType('password') + } + return
+ + { + type === 'password' + ? + : + } +
+ } +) +PasswordInput.displayName = 'PasswordInput' /** * 多行文本 @@ -146,4 +168,4 @@ const InputList = React.forwardRef void; + search: (event: React.ChangeEvent) => void; + onClearChecked: () => void; + onOk: () => void; +} + +const FilterUserGroup: React.FC = ({ + value = [], + options, + nameKey = 'name', + placeholder, + onChecked, + search, + onClearChecked, + onOk +}) => { + const { t } = useTranslation(); + + return ( +
+
+ +
+
+ {options.map((i) => ( +
+ onChecked(i.id)} /> + +
+ ))} + {options.length === 0 && ( +
+ +
+ )} +
+
+ + +
+
+ ); +} + +export default React.memo(FilterUserGroup); \ No newline at end of file diff --git a/src/components/bs-ui/select/hover.tsx b/src/components/bs-ui/select/hover.tsx new file mode 100644 index 0000000..b562965 --- /dev/null +++ b/src/components/bs-ui/select/hover.tsx @@ -0,0 +1,23 @@ +import { Button } from "../button"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../tooltip"; + +export function SelectHoverItem({ children, ...props }) { + + return
+ {children} +
+} + +export function SelectHover({ triagger, children }) { + + return + + + {triagger} + + + {children} + + + +}; diff --git a/src/components/bs-ui/select/index.tsx b/src/components/bs-ui/select/index.tsx index 8a266c5..d32d022 100644 --- a/src/components/bs-ui/select/index.tsx +++ b/src/components/bs-ui/select/index.tsx @@ -23,7 +23,7 @@ const SelectTrigger = React.forwardRef< span]:line-clamp-1 data-[placeholder]:text-gray-400", + "group flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border-input bg-[#1a1a1a] px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 data-[placeholder]:text-gray-400 border-[#666] text-[#999]", className )} {...props} @@ -79,7 +79,7 @@ const SelectContent = React.forwardRef< { +const MultiItem: React.FC< + { active: boolean; children: React.ReactNode; value: string; onClick: (value: string, label: string) => void } +> = ({ active, children, value, onClick }) => { - return
{ onClick(value) }} + return
{ onClick(value, children as string) }} > {active && } @@ -17,21 +21,45 @@ const MultiItem = ({ active, children, value, onClick }) => { {children}
} - - -interface IProps { - className?: string, - options: { label: string, value: string }[], - value?: string[], - defaultValue?: string[], - children?: React.ReactNode, - placeholder?: string, - searchPlaceholder?: string, - lockedValues?: string[], - onChange?: (value: string[]) => void +interface Option { + label: string; + value: string; } + +interface BaseProps { + /** 多选 */ + multiple?: boolean; + disabled?: boolean; + className?: string; + options: Option[]; + children?: React.ReactNode; + placeholder?: string; + searchPlaceholder?: string; + /** 锁定不可修改的值 */ + lockedValues?: string[]; + onLoad?: () => void; + onSearch?: (name: string) => void; + onChange?: (value: T) => void; +} + +// onScrollLoad有值表示开启分页、异步检索 +interface ScrollLoadProps extends BaseProps { + onScrollLoad: (name: string) => void; + value?: Option[]; + defaultValue?: Option[]; +} + +interface NonScrollLoadProps extends BaseProps { + onScrollLoad?: undefined; + value?: string[]; + defaultValue?: string[]; +} + +type IProps = ScrollLoadProps | NonScrollLoadProps; + // 临时用 andt 设计方案封装组件 const MultiSelect = ({ + multiple = false, className, value = [], defaultValue = [], @@ -40,13 +68,15 @@ const MultiSelect = ({ placeholder = '', searchPlaceholder = '', lockedValues = [], + onSearch, + onLoad, + onScrollLoad, onChange, ...props }: IProps) => { const [values, setValues] = React.useState(defaultValue) const [optionFilter, setOptionFilter] = React.useState(options) - - + const [created, creatInput] = useState(false) const inputRef = useRef(null) useEffect(() => { @@ -54,75 +84,145 @@ const MultiSelect = ({ }, [value]) useEffect(() => { - setOptionFilter(options) - if (inputRef.current) { - inputRef.current.value = '' - } - }, [options]) - // delete + // if (onScrollLoad) { + setOptionFilter(options); + // } + }, [options]); + + // delete const handleDelete = (value: string) => { - const newValues = values.filter((item) => { - return item !== value + const newValues = (values as any[]).filter((item) => { + const _value = onScrollLoad ? (item as Option).value : item; + return _value !== value }) setValues(newValues) onChange?.(newValues) } // add - const handleSwitch = (value: string) => { + const handleSwitch = (value: string, label: string) => { if (lockedValues.includes(value)) { return } - if (values.includes(value)) { - const newValues = values.filter((item) => { - return item !== value - }) - setValues(newValues) - onChange?.(newValues) + + const updateValues = (newValues: any) => { + setValues(newValues); + onChange?.(newValues); + }; + + // 单选 + if (!multiple) { + const newValues = onScrollLoad ? [{ label, value }] : [value] + updateValues(newValues); + return + } + + if (onScrollLoad) { + const newValues = (values as Option[]).some(item => item.value === value) + ? (values as Option[]).filter(item => item.value !== value) + : [...(values as Option[]), { label, value }]; + updateValues(newValues); } else { - const _newValues = [...values, value] - setValues(_newValues) - onChange?.(_newValues) + const newValues = (values as string[]).includes(value) + ? (values as string[]).filter(item => item !== value) + : [...(values as string[]), value]; + updateValues(newValues); } } // search - const handleSearch = (e) => { + const handleSearch = useDebounce((e) => { const newValues = options.filter((item) => { return item.label.toLowerCase().indexOf(e.target.value.toLowerCase()) !== -1 }) setOptionFilter(newValues) - } - return { + creatInput(e); + if (!e) { + onLoad?.(); + setOptionFilter(options); + } + }} + > + { - values.length - ?
+ !multiple && (values.length ? {onScrollLoad ? (values[0] as Option).label : options.find(op => op.value === values[0])?.label} : placeholder) + } + { + multiple && (values.length ? ( + onScrollLoad ?
{ - options.filter(option => values.includes(option.value)).map(option => - e.stopPropagation()} key={option.value} className="flex whitespace-normal items-center gap-1 select-none bg-primary/20 text-primary hover:bg-primary/15 m-[2px]"> + values.map(item => + e.stopPropagation()} key={item.value} className="flex whitespace-normal items-center gap-1 select-none bg-[#261F08] text-[#CCA831] hover:bg-[#261F08] m-[2px]"> + {item.label} + {lockedValues.includes(item.value) || handleDelete(item.value)}>} + + ) + } +
:
+ { + options.filter(option => (values as string[]).includes(option.value)).map(option => + e.stopPropagation()} key={option.value} className="flex whitespace-normal items-center gap-1 select-none bg-[#261F08] text-[#CCA831] hover:bg-[#261F08] m-[2px] break-all"> {option.label} {lockedValues.includes(option.value) || handleDelete(option.value)}>} ) } -
- : placeholder +
) + : placeholder) }
- - +
} footerNode={children} >
{ - optionFilter.map((item, index) => ( - {item.label} + optionFilter.map((item) => ( + val === item.value || val.value === item.value)} + value={item.value} + onClick={handleSwitch} + >{item.label} )) } +
diff --git a/src/components/bs-ui/select/select.tsx b/src/components/bs-ui/select/select.tsx new file mode 100644 index 0000000..0d8f2b8 --- /dev/null +++ b/src/components/bs-ui/select/select.tsx @@ -0,0 +1,44 @@ +import React, { ChangeEvent } from "react" +import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/bs-ui/select"; +import { SearchInput } from "../input"; + +interface SelectSearchProps { + value: string, + options: {label: string, value: string}[], + selectPlaceholder?:string, + inputPlaceholder?:string, + onOpenChange?: (open:boolean) => void, + onValueChange: (value: string) => void, + onChange: (e:ChangeEvent) => void, + selectClass?: string, + contentClass?: string +} + +const SelectSearch: React.FC = ({ + value, + options, + selectPlaceholder = '', + inputPlaceholder = '', + onOpenChange, + onValueChange, + onChange, + selectClass = '', + contentClass = '' +}) => { + return +} + +export default React.memo(SelectSearch) \ No newline at end of file diff --git a/src/components/bs-ui/table/index.tsx b/src/components/bs-ui/table/index.tsx index 643279f..fc5b186 100644 --- a/src/components/bs-ui/table/index.tsx +++ b/src/components/bs-ui/table/index.tsx @@ -57,7 +57,7 @@ const TableRow = React.forwardRef< [role=checkbox]]:translate-y-[2px] bg-[#2B2B2B] first:rounded-l-md last:rounded-r-md group-odd:bg-[#1a1a1a]", + "p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] first:rounded-l-md last:rounded-r-md ", // group-hover:bg-[#1a1a1a] className )} @@ -102,7 +102,7 @@ const TableCaption = React.forwardRef< >(({ className, ...props }, ref) => ( )) diff --git a/src/components/bs-ui/utils.tsx b/src/components/bs-ui/utils.tsx index 6b22f63..674c729 100644 --- a/src/components/bs-ui/utils.tsx +++ b/src/components/bs-ui/utils.tsx @@ -1,20 +1,50 @@ import clsx, { ClassValue } from "clsx"; +import { useCallback, useEffect, useRef } from "react"; import { twMerge } from "tailwind-merge"; /** * 样式合并 */ export function cname(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); + return twMerge(clsx(inputs)); } export const generateUUID = (length: number) => { - let d = new Date().getTime() - const uuid = ''.padStart(length, 'x').replace(/[xy]/g, (c) => { - const r = (d + Math.random() * 16) % 16 | 0 - d = Math.floor(d / 16) - return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16) - }) - return uuid - } \ No newline at end of file + let d = new Date().getTime() + const uuid = ''.padStart(length, 'x').replace(/[xy]/g, (c) => { + const r = (d + Math.random() * 16) % 16 | 0 + d = Math.floor(d / 16) + return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16) + }) + return uuid +} + + +// 防抖 +export function useDebounce(func: any, wait: number, immediate: boolean, callback?: any,): (any?: any) => any { + let timer = useRef(); + const fnRef = useRef(func); + useEffect(() => { fnRef.current = func; }, [func]); + const timerCancel = function () { if (timer.current) clearTimeout(timer.current); }; + + function debounced(...args: any[]) { + const runFunction = () => { + return callback + ? callback(fnRef.current.apply(fnRef.current, args)) + : fnRef.current.apply(fnRef.current, args); + }; + timerCancel(); + if (immediate) { + let runNow = !timer.current; + timer.current = setTimeout(() => { timer.current = null; }, wait); + if (runNow) { + runFunction(); + } + } else { + timer.current = setTimeout(() => { runFunction(); }, wait); + } + } + debounced.cancel = function () { timerCancel(); timer.current = null; }; + return useCallback(debounced, [wait, immediate, timerCancel, func]); +} diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 24470f8..7f4cd6d 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -51,7 +51,7 @@ const DialogContent = React.forwardRef< {...props} > {children} - + Close diff --git a/src/components/ui/table.tsx b/src/components/ui/table.tsx index 4560fdd..6a2025c 100644 --- a/src/components/ui/table.tsx +++ b/src/components/ui/table.tsx @@ -95,7 +95,7 @@ const TableCaption = React.forwardRef< >(({ className, ...props }, ref) => ( )); diff --git a/src/controllers/.DS_Store b/src/controllers/.DS_Store index 30ee57512d995d241bf70a5dbb4b4ddc60c6eceb..e288fdbf9162f531acac1d980bf8987d9a2c1eb1 100644 GIT binary patch delta 70 zcmZoMXffE}&cwKLvIkS4hGccMk)f%M0+6WHQK&XFvozFEurxNTt>xqpRo1r-iqFo; Y&CBnee4k04v1jvtCN|d1>>Pjj0mz9I(f|Me delta 68 zcmZoMXffE}&cwKVvIkS4ns{}!v7wHFv01H-LbaipC6H}tY*<^%$sww&Zygk$os*lF W-#PgqlRRVBW=3W<*3GOO|M>x)uM=tj diff --git a/src/controllers/API/.DS_Store b/src/controllers/API/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8dc1586a16df597861df290a2690c0c849d18c6e GIT binary patch literal 6148 zcmeHKu};G<5WNc(2`WQJ7NmSZr2avu%D~JIKq(-ks6kCD7_;*+?ED#1cz0(N)d?%A zs=Mg??8`elevaaph$joirm7znRlNX5UXUwz(W#+EG^QuytmqM0Tg3vkIO{XYN|9AjO>cNd zdThRo*qM&7#2D{`{Evu#O0Tp=?*n}&U*Jyd`MVDF4CB|hD$IL;&)-qsDQ4N=N!CN` zE;T!0 => { - return await axios.get(`/api/v1/assistant/info/${id}`) +export const getAssistantDetailApi = async (id, version): Promise => { + return await axios.get(`/api/${version}/assistant/info/${id}`) }; // 获取助手系统模型 @@ -55,10 +55,18 @@ export const deleteAssistantApi = async (id) => { // 获取会话选择列表 -export const getChatOnlineApi = async () => { - return await axios.get(`/api/v1/chat/online`) -}; - +// export const getChatOnlineApi = async () => { +// return await axios.get(`/api/v1/chat/online`) +// }; +export const getChatOnlineApi = async (page, keyword, tag_id) => { + return await axios.get(`/api/v1/chat/online`, { + params: { + page, keyword, + limit: 40, + tag_id: tag_id === -1 ? null : tag_id + } + }) +} // 获取工具集合 export const getAssistantToolsApi = async (type: 'all' | 'default' | 'custom'): Promise => { diff --git a/src/controllers/API/evaluate.ts b/src/controllers/API/evaluate.ts new file mode 100644 index 0000000..fca9101 --- /dev/null +++ b/src/controllers/API/evaluate.ts @@ -0,0 +1,67 @@ +import { ReactFlowJsonObject } from "reactflow"; +import { FlowStyleType, FlowType, FlowVersionItem } from "../../types/flow"; +import axios from "../request"; + + +export type Evaluation = { + file_path: string, + file_name: string, + unique_id: string, + prompt: string, + result_score: { + answer_f1: string, + answer_precision: string, + answer_recall: string, + }, + create_time: string, + id: number, + user_id: number, + exec_type: string, + version: number, + status: number, + progress?: string, + result_file_path: string, + is_delete: number, + update_time: string, + unique_name: string, + version_name: string, + user_name: string, +} + +/** + * 获取评测列表 + * @param data + * @returns + */ +export const getEvaluationApi = async (page, limit): Promise => { + return await axios.get(`/api/v1/evaluation`, { + params: { + page, limit + } + }); +}; + +/** + * 创建测评任务 + */ +export const createEvaluationApi = async (data): Promise => { + return await axios.post(`/api/v1/evaluation`, data,{ + headers: { + 'Content-Type':'multipart/form-data' + } + }); +}; + +/** + * 删除测评任务 + */ +export const deleteEvaluationApi = async (id): Promise => { + return await axios.delete(`/api/v1/evaluation/${id}`); +}; + +/** + * 获取下载链接 + */ +export const getEvaluationUrlApi = async (id): Promise<{ url: string }> => { + return await axios.get(`/api/v1/evaluation/result/file/download?file_url=${id}`); +}; diff --git a/src/controllers/API/flow.ts b/src/controllers/API/flow.ts index e052ed4..9514143 100644 --- a/src/controllers/API/flow.ts +++ b/src/controllers/API/flow.ts @@ -114,8 +114,8 @@ export function getReportFormApi(flow_id): Promise { * @returns {Promise} The flow data. * @throws Will throw an error if fetching fails. */ -export async function getFlowApi(flowId: string): Promise { - return axios.get(`/api/v1/flows/${flowId}`) +export async function getFlowApi(flowId: string, version: string = 'v1'): Promise { + return await axios.get(`/api/${version}/flows/${flowId}`) } /** diff --git a/src/controllers/API/index.ts b/src/controllers/API/index.ts index e33f2d0..4bae8b2 100644 --- a/src/controllers/API/index.ts +++ b/src/controllers/API/index.ts @@ -62,7 +62,12 @@ export async function delComponentApi(name): Promise { export async function getAppConfig(): Promise { return await axios.get(`/api/v1/env`); } - +/** + * 获取平台配置 + */ +export async function saveThemeApi(data: string): Promise { + return await axios.post(`/api/v1/web/config`, { value: data }); +} /** * Reads all templates from the database. * @@ -280,9 +285,12 @@ export async function postValidatePrompt( /** * 获取会话列表 */ -export const getChatsApi = () => { - return (axios.get(`/api/v1/chat/list`) as Promise).then(res => - res?.filter(el => el.chat_id) || [] +export const getChatsApi = (page) => { + // return (axios.get(`/api/v1/chat/list`) as Promise).then(res => + // res?.filter(el => el.chat_id) || [] + // ) + return (axios.get(`/api/v1/chat/list?page=${page}&limit=40`) as Promise).then(res => + res?.filter((el, i) => el.chat_id) || [] ) }; diff --git a/src/controllers/API/log.ts b/src/controllers/API/log.ts new file mode 100644 index 0000000..8faf0a1 --- /dev/null +++ b/src/controllers/API/log.ts @@ -0,0 +1,56 @@ +import axios from "../request"; + +// 获取操作过组下资源的所有用户 +export async function getOperatorsApi():Promise<[]> { + return await axios.get('/api/v1/audit/operators') +} + +// 分页获取审计列表 +export async function getLogsApi({page, pageSize, userIds, groupId = '', start, end, moduleId = '', action = ''}:{ + page:number, + pageSize:number, + userIds?:number[], + groupId?:string, + start?:string, + end?:string, + moduleId?:string, + action?:string +}):Promise<{data:any[], total:number}> { + const uids = userIds?.reduce((pre,val) => `${pre}&operator_ids=${val}`, '') || '' + const startStr = start ? `&start_time=${start}` : '' + const endStr = end ? `&end_time=${end}` : '' + return await axios.get( + `/api/v1/audit?page=${page}&limit=${pageSize}&group_ids=${groupId}${uids}` + + `&system_id=${moduleId}&event_type=${action}` + startStr + endStr + ) +} + +// 系统模块 +export async function getModulesApi():Promise<{data:any[]}> { + return { + data: [{name:'会话', value:'chat'},{name:'构建', value:'build'},{name:'知识库', value:'knowledge'},{name:'系统', value:'system'}] + } +} + +const actions = [ + {name:'新建会话',value:'create_chat'},{name:'删除会话',value:'delete_chat'},{name:'新建应用',value:'create_build'},{name:'编辑应用',value:'update_build'}, + {name:'删除应用',value:'delete_build'},{name:'新建知识库',value:'create_knowledge'},{name:'删除知识库',value:'delete_knowledge'},{name:'知识库上传文件',value:'upload_file'}, + {name:'知识库删除文件',value:'delete_file'},{name:'用户编辑',value:'update_user'},{name:'停用用户',value:'forbid_user'},{name:'启用用户',value:'recover_user'}, + {name:'新建用户组',value:'create_user_group'},{name:'删除用户组',value:'delete_user_group'},{name:'编辑用户组',value:'update_user_group'},{name:'新建角色',value:'create_role'}, + {name:'删除角色',value:'delete_role'},{name:'编辑角色',value:'update_role'},{name:'用户登录',value:'user_login'} +] + +// 全部操作行为 +export async function getActionsApi() { + return actions +} + +// 系统模块下操作行为 +export async function getActionsByModuleApi(moduleId) { + switch(moduleId) { + case 'chat': return actions.filter(a => a.value.includes('chat')) + case 'build': return actions.filter(a => a.value.includes('build')) + case 'knowledge': return actions.filter(a => a.value.includes('knowledge') || a.value.includes('file')) + case 'system': return actions.filter(a => a.value.includes('user') || a.value.includes('role')) + } +} \ No newline at end of file diff --git a/src/controllers/API/pro.ts b/src/controllers/API/pro.ts new file mode 100644 index 0000000..3d196f5 --- /dev/null +++ b/src/controllers/API/pro.ts @@ -0,0 +1,93 @@ +import axios from "../request"; + +/** + * 保存敏感词 + */ +export const sensitiveSaveApi = async (data: any): Promise => { + const { id, type, isCheck, words, wordsType, autoReply } = data + + return await axios.post(`/api/sensitive/saveWords`, { + resource_id: id, + resource_type: type, + is_check: isCheck, + words, + words_type: wordsType, + auto_reply: autoReply + }); +}; + +/** + * 获取敏感词配置 + */ +export const getSensitiveApi = async (resourceId, resourceType): Promise => { + + return await axios.get(`/api/sensitive/wordsDetail`, { + params: { + resourceId, + resourceType + } + }); +}; + +/** + * 获取资源组流量 + */ +export const getGroupFlowsApi = async (page: number, pageSize: number, resourceType: string, groupId: number, name: string): Promise => { + if (!groupId) return Promise.resolve([{ data: [], total: 0 }]); + return await axios.get(`/api/resource/groupFlows`, { + params: { + name, + page, + pageSize, + resourceType, + groupId + } + }); +}; + + +/** + * 保存组信息 + */ +export const saveGroupApi = async (data: any): Promise => { + const { id, + groupLimit: group_limit, + adminUser: admin_user, + adminUserId: admin_user_id, + groupName: group_name, + assistant, + skill } = data; + // const {resourceId, groupId, resourceLimit} = assistant + + return await axios.post(`/api/group/save`, { + id, + group_limit, + admin_user, + admin_user_id, + group_name, + assistant, + skill + }); +}; + +// 用户组列表 +export function getUserGroupsProApi() { + return axios.get(`/api/group/list`); +} + +// GET sso URL +export function getSSOurlApi() { + // return Promise.resolve(url) + return axios.get(`/api/oauth2/list`) +} + +export async function getKeyApi() { + return await axios.get('/api/getkey') +} + +export async function ldapLoginApi(username:string, password:string) { + return await axios.post('/api/oauth2/ldap', { + username, + password + }) +} \ No newline at end of file diff --git a/src/controllers/API/user.ts b/src/controllers/API/user.ts index 1a57bf1..b1743ed 100644 --- a/src/controllers/API/user.ts +++ b/src/controllers/API/user.ts @@ -27,16 +27,40 @@ export async function registerApi(name, pwd, captcha_key?, captcha?) { return await axios.post(`/api/v1/user/regist`, { user_name: name, password: pwd, captcha_key, captcha }); } // 用户列表 -export async function getUsersApi(name: string, page: number, pageSize: number): Promise<{ data: User[], total: number }> { - return await axios.get(`/api/v1/user/list?page_num=${page}&page_size=${pageSize}&name=${name || ''}`) -} +// export async function getUsersApi(name: string, page: number, pageSize: number): Promise<{ data: User[], total: number }> { +// return await axios.get(`/api/v1/user/list?page_num=${page}&page_size=${pageSize}&name=${name || ''}`) +// } +export async function getUsersApi({ name = '', page, pageSize, groupId, roleId }: { + name: string, + page: number, + pageSize: number, + groupId?: number[], + roleId?: number[] + }): Promise<{ data: User[]; total: number }> { + const groupStr = groupId?.reduce((res, id) => `${res}&group_id=${id}`, '') || '' + const roleStr = roleId?.reduce((res, id) => `${res}&role_id=${id}`, '') || '' + + return await axios.get( + `/api/v1/user/list?page_num=${page}&page_size=${pageSize}&name=${name}${groupStr}${roleStr}` + ); + } // 修改用户状态(启\禁用) export async function disableUserApi(userid, status) { return await axios.post(`/api/v1/user/update`, { user_id: userid, delete: status }); } // 角色列表 -export async function getRolesApi(searchkey = ''): Promise<{ data: ROLE[] }> { +// export async function getRolesApi(searchkey = ''): Promise<{ data: ROLE[] }> { +// return await axios.get(`/api/v1/role/list?role_name=${searchkey}`) +// } +export async function getRolesApi(searchkey = ""): Promise<{ data: ROLE[] }> { return await axios.get(`/api/v1/role/list?role_name=${searchkey}`) + .then(res => res.data); + } +// 用户组下角色列表 +export async function getRolesByGroupApi(searchkey = "", groupIds:any[]): Promise<{ data: ROLE[] }> { + const groupStr = groupIds?.reduce((pre, id) => `${pre}&group_id=${id}`, '') || '' + return await axios.get(`/api/v1/group/roles?keyword=${searchkey}${groupStr}`) + .then(res => res.data); } /** * 获取配置 @@ -68,6 +92,20 @@ export async function getRoleAssistApi(params): Promise<{ data: any[], total: nu export async function getRoleLibsApi(params): Promise<{ data: any[], total: number }> { return await axios.get(`/api/v1/role_access/knowledge`, { params }); } +/** + * 根据用户组获取资源列表 + */ +export async function getGroupResourcesApi( + params: { + group_id: string, + resource_type: number, + name: string, + page_size: number, + page_num: number + } +): Promise<{ data: any[]; total: number }> { + return await axios.get(`/api/v1/group/get_group_resources`, { params }); +} /** * 新增角色 */ @@ -119,6 +157,43 @@ export async function delRoleApi(roleId) { return axios.delete(`/api/v1/role/${roleId}`) } +// 用户组列表 +export function getUserGroupsApi() { + return axios.get(`/api/v1/group/list`); + } + + + // 删除用户组post + export function delUserGroupApi(group_id) { + return axios.delete(`/api/v1/group/create`, { params: { group_id } }); + // return axios.post(`/api/v1/group/del/${userGroupId}`); + } + + // 保存用户组 +export function saveUserGroup(form, selected) { + console.log('form :>> ', form); + const { groupName: group_name } = form + return axios.post(`/api/v1/group/create`, { + group_name, + group_admins: selected.map(item => item.value), + }); + } + + // 修改用户组 + export function updateUserGroup(id, form, selected) { + const { groupName: group_name } = form + const a = axios.put(`/api/v1/group/create`, { + id, + group_name + }); + const b = axios.post(`/api/v1/group/set_group_admin`, { + group_id: id, + user_ids: selected.map(item => item.value) + }) + return Promise.all([a, b]) + } + + /** * 获取用户的角色信息 */ @@ -134,4 +209,59 @@ export async function updateUserRoles(userId, roles) { user_id: userId, role_id: roles }); -} \ No newline at end of file +} + +// 更新用户组 +export async function updateUserGroups(userId, groupIds) { + return await axios.post(`/api/v1/group/set_user_group`, { + user_id: userId, + group_id: groupIds, + is_group_admin: false + }); +} + +// 超管创建用户组 +export async function createUserApi(user_name:string, password:string, group_roles:any[]) { + return await axios.post('/api/v1/user/create', { + user_name, + password, + group_roles + }) + } + + /** + * 获取所有管理员 + */ + export async function getAdminsApi(): Promise { + return axios.get(`/api/v1/user/admin`); + } + + + /** + * 重置密码(管理员专用) + */ + export async function resetPasswordApi(userId, password): Promise { + return axios.post(`/api/v1/user/reset_password`, { + user_id: userId, + password + }); + } + + /** + * 密码过期重置个人密码 + */ + export async function changePasswordApi(userName, password, new_password): Promise { + return axios.post(`/api/v1/user/change_password_public`, { + username: userName, + password, + new_password + }); + } + + // 已登录状态重置个人密码 + export async function loggedChangePasswordApi(password, new_password): Promise { + return axios.post(`/api/v1/user/change_password`, { + password, + new_password + }) + } \ No newline at end of file diff --git a/src/controllers/request.ts b/src/controllers/request.ts index 4cf45c9..a1d9ffc 100644 --- a/src/controllers/request.ts +++ b/src/controllers/request.ts @@ -3,13 +3,28 @@ import axios from "axios"; import i18next from "i18next"; axios.defaults.withCredentials = true; const customAxios = axios.create({ + baseURL: import.meta.env.BASE_URL // 配置 }); +export const requestInterceptor = { + remoteLoginFuc(msg) { } +}; + customAxios.interceptors.response.use(function (response) { if (response.data.status_code === 200) { return response.data.data; } + // 无权访问 + if (response.data.status_code === 403) { + // location.href = __APP_ENV__.BASE_URL + '/403' + // return Promise.reject(response.data.status_message); + } + // 异地登录 + if (response.data.status_code === 10604) { + requestInterceptor.remoteLoginFuc(response.data.status_message) + return Promise.reject(response.data.status_message); + } return Promise.reject(response.data.status_message); }, function (error) { console.error('application error :>> ', error); diff --git a/src/layout/MainLayout.tsx b/src/layout/MainLayout.tsx index a4f7e4b..0ce29fc 100755 --- a/src/layout/MainLayout.tsx +++ b/src/layout/MainLayout.tsx @@ -1,9 +1,22 @@ +import { + ApplicationIcon, + BookOpenIcon, + EnIcon, + EvaluatingIcon, + GithubIcon, + KnowledgeIcon, + LogIcon, + ModelIcon, + QuitIcon, + SystemIcon, + TechnologyIcon +} from "@/components/bs-icons"; import i18next from "i18next"; -import { AppWindow, BookOpen, Github, Globe, HardDrive, Languages, LayoutDashboard, LogOut, MoonIcon, Puzzle, Settings, SunIcon } from "lucide-react"; -import { useContext, useEffect, useState } from "react"; +// import { AppWindow, BookOpen, Github, Globe, HardDrive, Languages, LayoutDashboard, LogOut, MoonIcon, Puzzle, Settings, SunIcon } from "lucide-react"; +import { useContext, useEffect, useMemo, useRef, useState } from "react"; import { ErrorBoundary } from "react-error-boundary"; import { useTranslation } from "react-i18next"; -import { Link, NavLink, Outlet } from "react-router-dom"; +import { Link, NavLink, Outlet, useNavigate } from "react-router-dom"; import CrashErrorComponent from "../components/CrashErrorComponent"; import { Separator } from "../components/ui/separator"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../components/ui/tooltip"; @@ -14,19 +27,59 @@ import { captureAndAlertRequestErrorHoc } from "../controllers/request"; import { User } from "../types/api/user"; import login from "../assets/login.jpg" import shuoming from "../assets/nav/shuoming.png" +import adminImg from "../assets/nav/admin.png" +import adminImg1 from "../assets/nav/admin1.png" +import mima from "../assets/nav/mima.png" +import tuichu from "../assets/nav/tuichu.png" +import { locationContext } from "@/contexts/locationContext"; +import { bsConfirm } from "@/components/bs-ui/alertDialog/useConfirm"; +import { SelectHover, SelectHoverItem } from "@/components/bs-ui/select/hover"; +import { CaretDownIcon, LockClosedIcon, MoonIcon, SunIcon } from "@radix-ui/react-icons"; +import { Button } from "@/components/ui/button"; export default function MainLayout() { const { dark, setDark } = useContext(darkContext); + const { appConfig } = useContext(locationContext) // 角色 const { user, setUser } = useContext(userContext); const { language, options, changLanguage, t } = useLanguage(user) + const { delShow, idRef, close, delConfirm } = useDelete(); + const handleLogout = () => { captureAndAlertRequestErrorHoc(logoutApi()).then(_ => { setUser(null) localStorage.removeItem('isLogin') }) + // bsConfirm({ + // title: `${t('prompt')}!`, + // desc: `${t('menu.logoutContent')}?`, + // okTxt: t('system.confirm'), + // onOk(next) { + // captureAndAlertRequestErrorHoc(logoutApi()).then(_ => { + // setUser(null) + // localStorage.removeItem('isLogin') + // }) + // next() + // } + // }) + } + + // 重置密码 + const navigator = useNavigate() + const JumpResetPage = () => { + localStorage.setItem('account', user.user_name) + navigator('/reset') + } + + // 系统管理员(超管、组超管) + const isAdmin = useMemo(() => { + return ['admin', 'group_admin'].includes(user.role) + }, [user]) + + const isMenu = (menu) => { + return user.web_menu.includes(menu) || user.role === 'admin' } return
@@ -37,30 +90,58 @@ export default function MainLayout() { {/* */} {t('menu.app')} - - {/* */} - {t('menu.skills')} - - - {/* */} - {t('menu.knowledge')} - - - {/* */} - {t('menu.models')} - { - user.role === 'admin' && <> - + isMenu('build') && + + {/* */} + {t('menu.skills')} + + } + + { + isMenu('filelib') && + + {/* */} + {t('menu.knowledge')} + + } + + { + isMenu('model') && + + {/* */} + {t('menu.models')} + + } + { + isMenu('evaluation') && + + {/* */} + {t('menu.evaluation')} + + } + + { + isAdmin && <> + {/* */} {t('menu.system')} } + + { + isAdmin && <> + + {/* */} + {t('menu.log')} + + + }
-
+
说明
@@ -119,8 +200,8 @@ export default function MainLayout() { */} {/*
*/} -
- +
+ {/*
@@ -130,7 +211,18 @@ export default function MainLayout() {

{t('menu.logoutDescription')}

- + */} + + + {user.user_name} + +
+ }> + {t('menu.changePwd')} + {t('menu.logout')} +
@@ -143,7 +235,7 @@ export default function MainLayout() {
{/* // mobile */} -
+ {/*

{t('menu.forBestExperience')}

@@ -155,7 +247,17 @@ export default function MainLayout() {
-
+
*/} + +
+

{t('prompt')}

+

确认退出登录吗?

+
+ + +
+
+
}; @@ -183,3 +285,20 @@ const useLanguage = (user: User) => { t } } + +const useDelete = () => { + const [delShow, setDelShow] = useState(false) + const idRef = useRef(null) + + return { + delShow, + idRef, + close: () => { + setDelShow(false) + }, + delConfirm: (id) => { + // idRef.current = id + setDelShow(true) + } + } +} \ No newline at end of file diff --git a/src/pages/.DS_Store b/src/pages/.DS_Store index b0e260b1851b8b5419f80bac87675235e9bb6888..3f6373229c778ea4d3b4afb51f3a171831600aff 100644 GIT binary patch delta 371 zcmZp1XmOa}&nU4mU^hRb#AF@;%gOu#;yg*^#RW+@`AG~63_BGWf;3BTM5cD_5d|VO)eAUpIj>-xj9Ziol%sJ!IhzmA(0`6p%h4#Fk~|1GvrN{ z6OiVd_a6)x7$!Ffp6B!dil+l*L2_aSEWd#^>A@5L*_;e;1q=Z|gVGsNk=(QkS{wna|;~>Lqp?Q9ffK`BU1w%1v3ky+FDKyQDuGWp!n>Z+`RlAkX!kCQB9qkCn(O& z4zUH~1SZzZ%??6LOq2OU#3oM@Xb>?mu+&j7wlD#iY-t2E*u>0avX-FnWPTA*ke4Tx TsBUJL_|CF9Ug$9+3A&U3$?9a_ delta 62 zcmV-E0Kxx+K!iY$PXQ0HP`eKS50fDg8k46I6O%a*43mNp8IuhY4zqC)83B{V63nyk U6!8JGLJY+Nvj-UW1hIJr18Q#+aR2}S diff --git a/src/pages/ChatAppPage/chatAssitantShare.tsx b/src/pages/ChatAppPage/chatAssitantShare.tsx new file mode 100644 index 0000000..792c4bf --- /dev/null +++ b/src/pages/ChatAppPage/chatAssitantShare.tsx @@ -0,0 +1,21 @@ +// 支持嵌iframe、适配移动端 +import { useMemo, useState } from "react"; +import { useLocation, useParams } from "react-router-dom"; +import { generateUUID } from "../../utils"; +import ChatPanne from "./components/ChatPanne"; + +export default function chatAssitantShare() { + const { id: assitId } = useParams() + + const wsUrl = `/api/v2/assistant/chat/${assitId}` + + const [data] = useState({ id: assitId, chatId: generateUUID(32), type: 'assistant' }) + + if (!assitId) return
请选择会话
+ + return
+
+ +
+
+}; diff --git a/src/pages/ChatAppPage/chatShare.tsx b/src/pages/ChatAppPage/chatShare.tsx index cb6a27c..c64b4f5 100644 --- a/src/pages/ChatAppPage/chatShare.tsx +++ b/src/pages/ChatAppPage/chatShare.tsx @@ -1,21 +1,8 @@ // 嵌iframe、适配移动端 -import { useEffect, useMemo, useState, useRef, useContext } from "react"; +import { useMemo, useState } from "react"; import { useLocation, useParams } from "react-router-dom"; -import { getFlowApi, readOnlineFlows } from "../../controllers/API/flow"; -import { FlowType } from "../../types/flow"; import { generateUUID } from "../../utils"; import ChatPanne from "./components/ChatPanne"; -import { useTranslation } from "react-i18next"; -import { deleteChatApi, getChatsApi } from "../../controllers/API"; -import { captureAndAlertRequestErrorHoc } from "../../controllers/request"; -import { useDebounce, useTable } from "../../util/hook"; -import { TabsContext } from "../../contexts/tabsContext"; -import SkillTemps from "../SkillPage/components/SkillTemps"; -import duihuaDel from "../../assets/chat/duihua-del.png"; -import robot from "../../assets/robot.png"; -import duihuaItemTop from "../../assets/chat/duihua-item-top.png"; -import duihuaItemJia from "../../assets/chat/duihua-item-+.png"; -import duihuaItemGuan from "../../assets/chat/duihua-item-x.png"; export default function chatShare() { @@ -24,81 +11,13 @@ export default function chatShare() { const searchParams = new URLSearchParams(location.search); const libId = searchParams.get('lib') const tweak = searchParams.get('tweak') - const { t } = useTranslation(); - const [open, setOpen] = useState(false) - // 对话列表 - const { chatList, chatsRef, addChat, deleteChat } = useChatList() - const queryString = useMemo(() => { - const params = []; - - if (libId) params.push(`knowledge_id=${libId}`); - if (tweak) params.push(`tweak=${tweak}`); - - return params.length > 0 ? `&${params.join('&')}` : ''; - }, [libId, tweak]) - const chatIdRef = useRef('') - const handlerSelectFlow = async (node: FlowType) => { - // 会话ID - chatIdRef.current = generateUUID(32) - setOpen(false) - // add list - addChat({ - "flow_name": node.name, - "flow_description": node.description, - "flow_id": node.id, - "chat_id": chatIdRef.current, - "create_time": "-", - "update_time": "-" - }) - - const flow = await getFlowApi(node.id) - setFlow(flow) - setChatId(chatIdRef.current) - // setFace(false) - } - // - const { flow: initFlow } = useContext(TabsContext); - const [flow, setFlow] = useState(null) - const { - data: onlineFlows, - loading, - search, - } = useTable({}, (param) => - readOnlineFlows(param.page, param.keyword).then((res) => { - return res; - }) - ); - const [chatId, setChatId] = useState('') - console.log(flowId,libId,tweak) - useEffect(() => { - flowId && getFlowApi(flowId).then(node => { - // 会话ID - setFlow(node) - setChatId(generateUUID(32)) - }) - }, [flowId]) - // select chat - const handleSelectChat = useDebounce(async (chat) => { - if (chat.chat_id === chatId) return - - const flow = initFlow?.id === chat.flow_id ? initFlow : await getFlowApi(chat.flow_id) - - // if (!flow) { - // setInputState({ lock: true, errorCode: '1004' }) - // clearHistory() - // return setFace(false) - // } - - setFlow(flow) - setChatId(chat.chat_id) - }, 100, false) const wsUrl = useMemo(() => { const params = []; if (libId) params.push(`knowledge_id=${libId}`); - if (tweak) params.push(`tweak=${tweak}`); - + if (tweak) params.push(`tweak=${encodeURIComponent(tweak)}`); + const paramStr = params.length > 0 ? `${params.join('&')}` : ''; return `/api/v2/chat/ws/${flowId}?type=L1&${paramStr}` @@ -110,84 +29,7 @@ export default function chatShare() { return
- {/*
-
-
setOpen(true)}>{t('chat.newChat')}
-
- -
-
-
- { - chatList.map((chat, i) => ( -
handleSelectChat(chat)}> -
- -
-

{chat.flow_name}

-
离线
-
-
-
- - -
- -
- )) - } -
-
*/} - {/* chat */} - {/* {flow - ?
- {flow && } -
- :
-

{t('chat.selectChat')}

-
} */} - +
- {/* {flow ? : null} */} - {/* 选择对话技能 */} -
- // flow ? : null -}; -/** - * 本地对话列表 - */ -const useChatList = () => { - const [chatList, setChatList] = useState([]) - const chatsRef = useRef(null) - - useEffect(() => { - getChatsApi().then(setChatList) - }, []) - - return { - chatList, - chatsRef, - addChat: (chat) => { - const newList = [chat, ...chatList] - // localStorage.setItem(ITEM_KEY, JSON.stringify(newList)) - setChatList(newList) - setTimeout(() => { - chatsRef.current.scrollTop = 1 - }, 0); - }, - deleteChat: (id: string) => { - // api - captureAndAlertRequestErrorHoc(deleteChatApi(id).then(res => { - setChatList(oldList => oldList.filter(item => item.chat_id !== id)) - })) - } - } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/pages/ChatAppPage/components/ChatPanne.tsx b/src/pages/ChatAppPage/components/ChatPanne.tsx index 7bbd7dd..d2e5423 100644 --- a/src/pages/ChatAppPage/components/ChatPanne.tsx +++ b/src/pages/ChatAppPage/components/ChatPanne.tsx @@ -38,7 +38,7 @@ import { NewApplicationIcon } from "@/components/bs-icons/newApplication"; import { useToast } from "@/components/bs-ui/toast/use-toast"; import { useAssistantStore } from "@/store/assistantStore"; -export default function ChatPanne({ customWsHost = '', data }) { +export default function ChatPanne({ customWsHost = '', appendHistory = false, data, version = 'v1' }) { const { id, chatId, type } = data const { t } = useTranslation() @@ -54,24 +54,33 @@ export default function ChatPanne({ customWsHost = '', data }) { const build = useBuild() // 消息列表 // const { messages, messagesRef, loadHistory, setChatHistory, initGuide, changeHistoryByScroll } = useMessages(chatId, flow) - const { messages, loadHistoryMsg, loadMoreHistoryMsg, changeChatId } = useMessageStore() + // const { messages, loadHistoryMsg, loadMoreHistoryMsg, changeChatId } = useMessageStore() + const { messages, loadHistoryMsg, loadMoreHistoryMsg, changeChatId, clearMsgs} = useMessageStore() useEffect(() => { return destroy }, []) const init = async () => { if (type === 'flow') { setAssistant(null) - const _flow = await getFlowApi(id) + const _flow = await getFlowApi(id, version) await build(_flow, chatId) - loadHistoryMsg(_flow.id, chatId, type) + // loadHistoryMsg(_flow.id, chatId, type) + version === 'v1' ? loadHistoryMsg(_flow.id, chatId, { + appendHistory, + lastMsg: t('chat.historicalMessages') + }, type) : clearMsgs() flowRef.current = _flow setFlow(_flow) changeChatId(chatId) // ws } else { flowRef.current = null setFlow(null) - const _assistant = await loadAssistantState(id) - loadHistoryMsg(_assistant.id, chatId, type) + const _assistant = await loadAssistantState(id, version) + // loadHistoryMsg(_assistant.id, chatId, type) + version === 'v1' ? loadHistoryMsg(_assistant.id, chatId, { + appendHistory, + lastMsg: t('chat.historicalMessages') + }, type) : clearMsgs() setAssistant(_assistant) changeChatId(chatId) // ws } @@ -92,7 +101,7 @@ export default function ChatPanne({ customWsHost = '', data }) { const getWsParamData = (action, msg) => { if (type === 'flow') { const _flow = flowRef.current - console.log(_flow) + // console.log(_flow) let inputs = tabsState[_flow.id].formKeysData.input_keys; const input = inputs.find((el: any) => !el.type) const inputKey = input ? Object.keys(input)[0] : ''; @@ -115,7 +124,7 @@ export default function ChatPanne({ customWsHost = '', data }) { const inputKey = 'input'; const msgData = { chatHistory: messages, - flow_id: '', + flow_id: data?.id || '', chat_id: chatId, name: assistant.name, description: assistant.desc, @@ -382,33 +391,16 @@ export default function ChatPanne({ customWsHost = '', data }) {
*/} loadMoreHistoryMsg(flow.id,"flow")} - type={{"avatar_img":flow.avatar_img,"avatar_color":flow.avatar_color,"type":type}} + loadMore={() => loadMoreHistoryMsg(flow.id, appendHistory, "flow")} + type={{"avatar_img":flow.avatar_img,"avatar_color":flow.avatar_color,"type":type,"id":flow.id}} inputForm={flowSate.isForm ? : null} /> - {/*
- { - messages.map((c, i) => setSouce(c)} - onDislike={(chatId) => { thumbRef.current?.openModal(chatId) }} - onReSend={(msg) => { - inputRef.current.value = msg - handleSend() - }} - onEdit={(msg) => { inputRef.current.value = msg; setInputEmpty(!msg) }} - onSearch={(msg) => window.open(appConfig.dialogQuickSearch + encodeURIComponent(msg))} - >) - } -
*/}
} {/* 助手会话 */} @@ -420,13 +412,15 @@ export default function ChatPanne({ customWsHost = '', data }) { {assistant.name}
*/} item)} guideWord={assistantState.guide_word} wsUrl={wsUrl} onBeforSend={getWsParamData} - loadMore={() => loadMoreHistoryMsg(assistant.id,"assistant")} - type={{"avatar_img":assistant.avatar_img,"avatar_color":assistant.avatar_color,"type":type}} + loadMore={() => loadMoreHistoryMsg(assistant.id, appendHistory, "assistant")} + type={{"avatar_img":assistant.avatar_img,"avatar_color":assistant.avatar_color,"type":type,"id":assistant.id}} inputForm={null} />
diff --git a/src/pages/ChatAppPage/index.tsx b/src/pages/ChatAppPage/index.tsx index 8830844..c1f3618 100755 --- a/src/pages/ChatAppPage/index.tsx +++ b/src/pages/ChatAppPage/index.tsx @@ -22,6 +22,8 @@ import SkillChatSheet from "@/components/bs-comp/sheets/SkillChatSheet"; import { TitleIconBg } from "@/components/bs-comp/cardComponent"; import npcIcon from "../../assets/npc/npcIcon.png"; import nengliIcon from "../../assets/npc/nengliIcon.png"; +import { useMessageStore } from "@/components/bs-comp/chatComponent/messageStore"; +import { formatDate } from "@/util/utils"; export default function SkillChatPage() { @@ -44,8 +46,29 @@ export default function SkillChatPage() { return res; }) ); + + // scroll load + const footerRef = useRef(null) + useEffect(function () { + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + onScrollLoad() + } + }); + }, { + // root: null, // 视口 + rootMargin: '0px', // 视口的边距 + threshold: 0.1 // 目标元素超过视口的10%即触发回调 + }); + + observer.observe(footerRef.current); + return () => footerRef.current && observer.unobserve(footerRef.current); + }, []) + // 对话列表 - const { chatList, chatId, chatsRef, setChatId, addChat, deleteChat } = useChatList() + // const { chatList, chatId, chatsRef, setChatId, addChat, deleteChat } = useChatList() + const { chatList, chatId, chatsRef, setChatId, addChat, deleteChat, onScrollLoad } = useChatList() // select flow const handlerSelectFlow = async (card) => { @@ -71,7 +94,7 @@ export default function SkillChatPage() { // select chat const handleSelectChat = useDebounce(async (chat) => { - console.log('chat.id :>> ', chat); + // console.log('chat.id :>> ', chat); if (chat.chat_id === chatId) return setSelelctChat({ id: chat.flow_id, chatId: chat.chat_id, type: chat.flow_type }) setChatId(chat.chat_id) @@ -113,15 +136,16 @@ export default function SkillChatPage() {
handleSelectChat(chat)}> -
+
{/* {(chat.flow_id == "06b1d374-ba97-46e6-8782-c56dec8dcc17" || chat.flow_id == "ed8e21f6-9757-43d0-b076-8c6e81bb0580") && } {chat.flow_id == "ca214b41-2b73-4585-b172-bf1e546cf6ec" && } {(chat.flow_id != "06b1d374-ba97-46e6-8782-c56dec8dcc17" && chat.flow_id != "ed8e21f6-9757-43d0-b076-8c6e81bb0580" && chat.flow_id != "ca214b41-2b73-4585-b172-bf1e546cf6ec") && } */} {/* */} -
-

{chat.flow_name}

+
+

{chat.flow_name}

{/*
离线
*/} +

{chat.latest_message?.message || ''}

@@ -134,10 +158,17 @@ export default function SkillChatPage() {
)) } +
{/* chat */} - + {/* */} + + {/* { + location + ? + : + } */} {/* 选择对话技能 */} { const [id, setId] = useState('') const [chatList, setChatList] = useState([]) const chatsRef = useRef(null) + const { chatId, messages } = useMessageStore() useEffect(() => { - getChatsApi().then(setChatList) - }, []) + // getChatsApi().then(setChatList) + if (messages.length > 0) { + let latest: any = messages[messages.length - 1] + // 有分割线取上一条 + if (latest.category === 'divider') latest = messages[messages.length - 2] || {} + setChatList(chats => chats.map(chat => (chat.chat_id === chatId) + ? { + ...chat, + update_time: latest.update_time || formatDate(new Date(), 'yyyy-MM-ddTHH:mm:ss'), + latest_message: { + ...chat.latest_message, + message: (latest.thought || latest.message[latest.chatKey] || latest.message).substring(0, 40) + } + } + : chat) + ) + } + }, [messages, chatId]) + const pageRef = useRef(0) + const onScrollLoad = async () => { + pageRef.current++ + const res = await getChatsApi(pageRef.current) + setChatList((chats => [...chats, ...res])) + } + return { chatList, chatId: id, @@ -178,6 +233,7 @@ const useChatList = () => { captureAndAlertRequestErrorHoc(deleteChatApi(id).then(res => { setChatList(oldList => oldList.filter(item => item.chat_id !== id)) })) - } + }, + onScrollLoad } } \ No newline at end of file diff --git a/src/pages/ChatAppPage/mobile/ChatPanneM.tsx b/src/pages/ChatAppPage/mobile/ChatPanneM.tsx index 59b02e3..0deaa92 100644 --- a/src/pages/ChatAppPage/mobile/ChatPanneM.tsx +++ b/src/pages/ChatAppPage/mobile/ChatPanneM.tsx @@ -36,7 +36,7 @@ interface Iprops { version?: string } -export default function ChatPanne({ customWsHost = '', data }) { +export default function ChatPanne({ customWsHost = '', appendHistory = false, data, version = 'v1' }) { const { id, chatId, type } = data const { t } = useTranslation() @@ -47,7 +47,8 @@ export default function ChatPanne({ customWsHost = '', data }) { // build // const build = useBuild(flow, chatId) const build = useBuild() - const { messages, loadHistoryMsg, loadMoreHistoryMsg, changeChatId } = useMessageStore() + // const { messages, loadHistoryMsg, loadMoreHistoryMsg, changeChatId } = useMessageStore() + const { messages, loadHistoryMsg, loadMoreHistoryMsg, changeChatId, clearMsgs} = useMessageStore() useEffect(() => { return destroy }, []) @@ -55,17 +56,25 @@ export default function ChatPanne({ customWsHost = '', data }) { const init = async () => { if (type === 'flow') { setAssistant(null) - const _flow = await getFlowApi(id) + const _flow = await getFlowApi(id, version) await build(_flow, chatId) - loadHistoryMsg(_flow.id, chatId, type) + // loadHistoryMsg(_flow.id, chatId, type) + version === 'v1' ? loadHistoryMsg(_flow.id, chatId, { + appendHistory, + lastMsg: t('chat.historicalMessages') + }, type) : clearMsgs() flowRef.current = _flow setFlow(_flow) changeChatId(chatId) // ws } else { flowRef.current = null setFlow(null) - const _assistant = await loadAssistantState(id) - loadHistoryMsg(_assistant.id, chatId, type) + const _assistant = await loadAssistantState(id, version) + // loadHistoryMsg(_assistant.id, chatId, type) + version === 'v1' ? loadHistoryMsg(_assistant.id, chatId, { + appendHistory, + lastMsg: t('chat.historicalMessages') + }, type) : clearMsgs() setAssistant(_assistant) changeChatId(chatId) // ws } @@ -350,13 +359,13 @@ export default function ChatPanne({ customWsHost = '', data }) { {/*
setIsDuiHua(!isDuiHua)}>
*/} -

{flow && flow.name}

+

{flow && flow.name}{assistant && assistant.name}

{/*
setIsNpcInfo(!isNpcInfo)}>
*/}
-
+
{ flow &&
{/* {flow && } */} @@ -366,33 +375,34 @@ export default function ChatPanne({ customWsHost = '', data }) {
*/} loadMoreHistoryMsg(flow.id, type)} - type={{"avatar_img":flow.avatar_img,"avatar_color":flow.avatar_color,"type":type}} + loadMore={() => loadMoreHistoryMsg(flow.id, appendHistory, "flow")} + type={{"avatar_img":flow.avatar_img,"avatar_color":flow.avatar_color,"type":type,"id":flow.id}} inputForm={flowSate.isForm ? : null} /> - {/*
- { - messages.map((c, i) => setSouce(c)} - onDislike={(chatId) => { thumbRef.current?.openModal(chatId) }} - onReSend={(msg) => { - inputRef.current.value = msg - handleSend() - }} - onEdit={(msg) => { inputRef.current.value = msg; setInputEmpty(!msg) }} - onSearch={(msg) => window.open(appConfig.dialogQuickSearch + encodeURIComponent(msg))} - >) - } -
*/} +
+ } + + {/* 助手会话 */} + { + assistant &&
+ item)} + guideWord={assistantState.guide_word} + wsUrl={wsUrl} + onBeforSend={getWsParamData} + loadMore={() => loadMoreHistoryMsg(assistant.id, appendHistory, "assistant")} + type={{"avatar_img":assistant.avatar_img,"avatar_color":assistant.avatar_color,"type":type,"id":assistant.id}} + inputForm={null} + />
}
diff --git a/src/pages/ChatAppPage/mobile/chatAssitantShare.tsx b/src/pages/ChatAppPage/mobile/chatAssitantShare.tsx new file mode 100644 index 0000000..c17e4c8 --- /dev/null +++ b/src/pages/ChatAppPage/mobile/chatAssitantShare.tsx @@ -0,0 +1,25 @@ +// 支持嵌iframe、适配移动端 +import { useMemo, useState } from "react"; +import { useLocation, useParams } from "react-router-dom"; +import { generateUUID } from "../../../utils"; +import ChatPanne from "./../components/ChatPanne"; +import ChatPanneM from "./ChatPanneM"; + +export default function chatAssitantShare() { + const { id: assitId } = useParams() + + const wsUrl = `/api/v2/assistant/chat/${assitId}` + + const [data] = useState({ id: assitId, chatId: generateUUID(32), type: 'assistant' }) + + if (!assitId) return
请选择会话
+ +// return
+//
+// +//
+//
+ return
+ +
+}; diff --git a/src/pages/ChatAppPage/mobile/chatShareM.tsx b/src/pages/ChatAppPage/mobile/chatShareM.tsx index d45c66f..9398fbd 100644 --- a/src/pages/ChatAppPage/mobile/chatShareM.tsx +++ b/src/pages/ChatAppPage/mobile/chatShareM.tsx @@ -105,21 +105,8 @@ export default function chatShare() { if (!flowId) return
请选择技能
return
- {/*
- -

对话名称

- -
*/} - {/* {flow - ?
- {flow && } -
- :
-

{t('chat.selectChat')}

-
} */} - +
- // flow ? : null }; /** * 本地对话列表 diff --git a/src/pages/EvaluationPage/EvaluationCreate.tsx b/src/pages/EvaluationPage/EvaluationCreate.tsx new file mode 100644 index 0000000..44cc63e --- /dev/null +++ b/src/pages/EvaluationPage/EvaluationCreate.tsx @@ -0,0 +1,376 @@ +import { QuestionMarkIcon } from "@/components/bs-icons/questionMark"; +import { UploadIcon } from "@/components/bs-icons/upload"; +import { Input } from "@/components/bs-ui/input"; +import { AssistantItemDB, getAssistantsApi } from "@/controllers/API/assistant"; +import { createEvaluationApi } from "@/controllers/API/evaluate"; +import { TypeModal } from "@/utils"; +import { SelectViewport } from "@radix-ui/react-select"; +import { debounce, find } from "lodash"; +import { ArrowLeft } from "lucide-react"; +import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react"; +import { useDropzone } from "react-dropzone"; +import { useTranslation } from "react-i18next"; +import { useNavigate, useParams } from "react-router-dom"; +import ShadTooltip from "@/components/ShadTooltipComponent"; +import { Button } from "@/components/bs-ui/button"; +import { Label } from "@/components/bs-ui/label"; +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/bs-ui/select"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/bs-ui/tooltip"; +import { alertContext } from "@/contexts/alertContext"; +import { TabsContext } from "@/contexts/tabsContext"; +import { readFlowsFromDatabase } from "@/controllers/API/flow"; +import PromptAreaComponent from "./PromptCom"; +import defaultPrompt from "./defaultPrompt"; +import { DownloadIcon, PlayIcon, QuestionMarkCircledIcon } from "@radix-ui/react-icons"; + +export default function EvaluatingCreate() { + const { t } = useTranslation(); + + const { id } = useParams(); + const { flow: nextFlow } = useContext(TabsContext); + const { setErrorData } = useContext(alertContext); + const flow = useMemo(() => { + return id ? nextFlow : null; + }, [nextFlow]); + const [selectedType, setSelectedType] = useState<"flow" | "assistant" | "">( + "" + ); + const [selectedKeyId, setSelectedKeyId] = useState(""); + const [selectedVersion, setSelectedVersion] = useState(""); + const [query, setQuery] = useState(""); + const [dataSource, setDataSource] = useState([]); + const [prompt, setPrompt] = useState(defaultPrompt); + const [fileName, setFileName] = useState(""); + + const [loading, setLoading] = useState(false); + const fileRef = useRef(null); + + const onDrop = (acceptedFiles) => { + fileRef.current = acceptedFiles[0]; + const size = fileRef.current.size + const errorlist = []; + + // 限制文件最大为 10M + if (size > 10 * 1024 * 1024) { + errorlist.push(t("evaluation.fileSizeLimit")); + fileRef.current = null + return handleError(errorlist); + } + + const names = acceptedFiles[0].name; + setFileName(names); + }; + + const { getRootProps, getInputProps } = useDropzone({ + accept: { + "application/*": [".csv"], + }, + useFsAccessApi: false, + onDrop, + maxFiles: 1, + }); + + const navigate = useNavigate(); + + const handleCreateEvaluation = async () => { + const errorlist = []; + if (!selectedType) errorlist.push(t("evaluation.enterExecType")); + if (!selectedKeyId) errorlist.push(t("evaluation.enterUniqueId")); + if (selectedType === "flow" && !selectedVersion) + errorlist.push(t("evaluation.enterVersion")); + if (!fileRef.current) errorlist.push(t("evaluation.enterFile")); + if (!prompt) errorlist.push(t("evaluation.enterPrompt")); + + if (errorlist.length) return handleError(errorlist); + setLoading(true); + try { + await createEvaluationApi({ + exec_type: selectedType, + unique_id: selectedKeyId, + version: selectedVersion, + prompt, + file: fileRef.current, + }); + navigate(-1); + } finally { + setLoading(false); + } + }; + + const handleError = (list) => { + setErrorData({ + title: t("prompt"), + list, + }); + }; + + // 助手技能发生变化 + const handleTypeChange = (type) => { + setQuery(""); + if (type === "flow") { + readFlowsFromDatabase(1, 100, "").then((_flow) => { + setDataSource(_flow.data); + }); + } else if (type === "assistant") { + getAssistantsApi(1, 100, "").then((data) => { + setDataSource((data as any).data as AssistantItemDB[]); + }); + } + }; + + const handleDownloadTemplate = () => { + const link = document.createElement("a"); + link.href = __APP_ENV__.BASE_URL + "/template.csv"; // 文件路径 + link.download = "template.csv"; // 下载时的文件名 + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }; + + const handleSearch = useCallback(debounce((value) => { + if (selectedType === "flow") { + readFlowsFromDatabase(1, 100, value).then((_flow) => { + setDataSource(_flow.data); + }); + } else if (selectedType === "assistant") { + getAssistantsApi(1, 100, value).then((data) => { + setDataSource((data as any).data as AssistantItemDB[]); + }); + } + }, 300), [selectedType]) + + const handleInputChange = (event) => { + setQuery(event.target.value); + handleSearch(event.target.value); + }; + + useEffect(() => { + return () => { + handleSearch.cancel(); + }; + }, [handleSearch]); + + return ( +
+
+
+ + + +
+ {/* form */} +
+

{t("evaluation.createTitle")}

+
+ {/* base form */} +
+
+ +
+ + + + {dataSource.map((item) => { + return ( + + {item.name} + + ); + })} + + + + + {selectedType === "flow" && ( + + )} +
+
+
+
+ +
+
+
+ +
+ + + {t("code.uploadFile")} + +
+ {fileName && ( +
{fileName}
+ )} + +
+ +
+
+
+
+ +
+
+ { + setPrompt(t); + }} + /> +
+
+ +
+
+
+ + +
+
+
+
+
+
+
+ ); +} diff --git a/src/pages/EvaluationPage/PromptCom.tsx b/src/pages/EvaluationPage/PromptCom.tsx new file mode 100644 index 0000000..060d34b --- /dev/null +++ b/src/pages/EvaluationPage/PromptCom.tsx @@ -0,0 +1,91 @@ +import { useContext, useEffect, useState } from "react"; +import { PopUpContext } from "@/contexts/popUpContext"; +import GenericModal from "@/modals/genericModal"; +import { TextAreaComponentType } from "@/types/components"; +import { TypeModal } from "@/utils"; + +import { ExternalLink } from "lucide-react"; + +export default function PromptAreaComponent({ + field_name, + setNodeClass, + nodeClass, + value, + onChange, + disabled, + editNode = false, + type = TypeModal.PROMPT, +}: TextAreaComponentType) { + const [myValue, setMyValue] = useState(value); + const { openPopUp } = useContext(PopUpContext); + useEffect(() => { + if (disabled) { + setMyValue(""); + onChange(""); + } + }, [disabled, onChange]); + + const handleSave = (t: string) => { + setMyValue(t); + onChange(t); + }; + + return ( +
+
+ { + openPopUp( + { + setMyValue(t); + onChange(t); + }} + nodeClass={nodeClass} + setNodeClass={setNodeClass} + /> + ); + }} + className={ + editNode + ? "input-edit-node input-dialog" + : (disabled ? " input-disable text-ring " : "") + + " whitespace-wrap input-primary text-[#fff]" + } + > + {myValue !== "" ? myValue : "enter your prompt"} + + +
+
+ ); +} diff --git a/src/pages/EvaluationPage/defaultPrompt.js b/src/pages/EvaluationPage/defaultPrompt.js new file mode 100644 index 0000000..09bddb5 --- /dev/null +++ b/src/pages/EvaluationPage/defaultPrompt.js @@ -0,0 +1,67 @@ +export default `Extract following from given question and ground truth + +Question:What powers the sun and what is its primary function? +Answer: The sun is powered by nuclear fission, similar to nuclear reactors on Earth, and its primary function is to provide light to the solar system. +Ground truth: The sun is actually powered by nuclear fusion, not fission. In its core, hydrogen atoms fuse to form helium, releasing a tremendous amount of energy. This energy is what lights up the sun and provides heat and light, essential for life on Earth. The sun's light also plays a critical role in Earth's climate system and helps to drive the weather and ocean currents. +Extracted statements: +[ +{{ + "statements that are present in both the answer and the ground truth": ["The sun's primary function is to provide light"], + "statements present in the answer but not found in the ground truth": ["The sun is powered by nuclear fission", "similar to nuclear reactors on Earth"], + "relevant statements found in the ground truth but omitted in the answer": ["The sun is powered by nuclear fusion, not fission", "In its core, hydrogen atoms fuse to form helium, releasing a tremendous amount of energy", "This energy provides heat and light, essential for life on Earth", "The sun's light plays a critical role in Earth's climate system", "The sun helps to drive the weather and ocean currents"] +}} +] + +Question: What is the boiling point of water? +Answer: The boiling point of water is 100 degrees Celsius at sea level. +Ground truth: The boiling point of water is 100 degrees Celsius (212 degrees Fahrenheit) at sea level, but it can change with altitude. +Extracted statements: +[ + {{ + "statements that are present in both the answer and the ground truth": ["The boiling point of water is 100 degrees Celsius at sea level"], + "statements present in the answer but not found in the ground truth": [], + "relevant statements found in the ground truth but omitted in the answer": ["The boiling point can change with altitude", "The boiling point of water is 212 degrees Fahrenheit at sea level"] + }} +] + +Question: 公司2021年的研发费用占营业收入的比例是多少? +Answer: 根据提供的信息,公司2021年的研发费用占营业收入的比例为15.86%。 +Ground truth: 根据公司招股书披露数据,公司2021年的研发费用占营业收入的比例为15.86%。 +Extracted statements: +[ + {{ + "statements that are present in both the answer and the ground truth": ["公司2021年的研发费用占营业收入的比例为15.86%"], + "statements present in the answer but not found in the ground truth": [], + "relevant statements found in the ground truth but omitted in the answer": [] + }} +] + +Question: 达梦2021年的息税折旧摊销前利润是多少? +Answer: 达梦2021年的息税折旧摊销前利润为49,189.87万元。 +Ground truth: 根据达梦数据库招股书披露数据,达梦2021年的息税折旧摊销前利润为49,189.85万元。 +Extracted statements: +[ + {{ + "statements that are present in both the answer and the ground truth": [], + "statements present in the answer but not found in the ground truth": ["达梦2021年的息税折旧摊销前利润为49,189.87万元"], + "relevant statements found in the ground truth but omitted in the answer": ["根据达梦数据库招股书披露数据,达梦2021年的息税折旧摊销前利润为49,189.85万元"] + }} +] + +Question: 达梦2022年的应收账款周转率是多少? +Answer: 根据提供的信息,无法得知达梦2022年的应收账款周转率。 +Ground truth: 很抱歉,达梦尚未披露2022年报数据。 +Extracted statements: +[ + {{ + "statements that are present in both the answer and the ground truth": ["无法得知达梦2022年的应收账款周转率"], + "statements present in the answer but not found in the ground truth": [], + "relevant statements found in the ground truth but omitted in the answer": [], + }} +] + + +Question:{question} +Answer: {answer} +Ground truth: {ground_truth} +Extracted statements:"""` \ No newline at end of file diff --git a/src/pages/EvaluationPage/index.tsx b/src/pages/EvaluationPage/index.tsx new file mode 100755 index 0000000..9cf829a --- /dev/null +++ b/src/pages/EvaluationPage/index.tsx @@ -0,0 +1,223 @@ +import { Button } from "@/components/bs-ui/button"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/bs-ui/table"; +import { Tabs, TabsContent } from "@/components/bs-ui/tabs"; +import { useNavigate } from "react-router-dom"; + +import { bsConfirm } from "@/components/bs-ui/alertDialog/useConfirm"; +import { Badge } from "@/components/bs-ui/badge"; +import AutoPagination from "@/components/bs-ui/pagination/autoPagination"; +import { + Evaluation, + deleteEvaluationApi, + getEvaluationApi, + getEvaluationUrlApi, +} from "@/controllers/API/evaluate"; +import { captureAndAlertRequestErrorHoc } from "@/controllers/request"; +import { useTable } from "@/util/hook"; +import { downloadFile } from "@/util/utils"; +import { map } from "lodash"; +import { useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { + EvaluationScore, + EvaluationScoreLabelMap, + EvaluationStatusEnum, + EvaluationStatusLabelMap, + EvaluationType, + EvaluationTypeLabelMap, +} from "./types"; +import { checkSassUrl } from "../ChatAppPage/components/FileView"; + +export default function EvaluationPage() { + const navigate = useNavigate(); + const { t } = useTranslation(); + + const { + page, + pageSize, + data: datalist, + total, + loading, + setPage, + search, + reload, + } = useTable({ cancelLoadingWhenReload: true }, (param) => + getEvaluationApi(param.page, param.pageSize) + ); + + useEffect(() => { + const intervalId = setInterval(() => { + reload(); + }, 6000); // 每 6 秒轮询一次 + + return () => clearInterval(intervalId); + }, [reload]); + + const handleDelete = (id) => { + bsConfirm({ + title: t("prompt"), + desc: t("evaluation.confirmDeleteEvaluation"), + onOk(next) { + captureAndAlertRequestErrorHoc( + deleteEvaluationApi(id).then((res) => { + reload(); + }) + ); + next(); + }, + }); + }; + + const handleDownload = async (el) => { + const { url } = await getEvaluationUrlApi(el.result_file_path); + await downloadFile(checkSassUrl(url), el.file_name); + }; + + return ( +
+ {loading && ( +
+ +
+ )} +
+

{t("evaluation.evaluationCollection")}

+ + +
+ +
+ + + + + {t("evaluation.id")} + + + {t("evaluation.filename")} + + {t("evaluation.skillAssistant")} + + {t("evaluation.status")} + + + {t("evaluation.score")} + + + {t("createTime")} + + + {t("operations")} + + + + + + {datalist.map((el: Evaluation) => ( + + {el.id} + {el.file_name || "--"} + +
+ + { + EvaluationTypeLabelMap[EvaluationType[el.exec_type]] + .label + } + +   + + {el.unique_name} + +   + + {el.version_name} + +
+
+ + {!!el.status && ( + + {EvaluationStatusLabelMap[el.status].label} + {el.status === EvaluationStatusEnum.running + ? ` ${el.progress}` + : null} + + )} + + +
+ {el.result_score + ? map(el.result_score, (value, key) => { + return ( + + { + EvaluationScoreLabelMap[ + EvaluationScore[key] + ].label + } + :{value}  + + ); + }) + : "-"} +
+
+ + {el.create_time.replace("T", " ") || "--"} + + +
+ + +
+
+
+ ))} +
+
+
+ +
+
+
+
+ setPage(newPage)} + /> +
+
+
+ ); +} diff --git a/src/pages/EvaluationPage/types.ts b/src/pages/EvaluationPage/types.ts new file mode 100644 index 0000000..b9e1d05 --- /dev/null +++ b/src/pages/EvaluationPage/types.ts @@ -0,0 +1,51 @@ +export enum EvaluationType { + flow = "flow", + assistant = "assistant", +} + +export const EvaluationTypeLabelMap = { + [EvaluationType.flow]: { + label: "能力", + }, + [EvaluationType.assistant]: { + label: "NPC", + }, +}; + +export enum EvaluationScore { + answer_f1 = "answer_f1", + answer_precision = "answer_precision", + answer_recall = "answer_recall", +} + +export const EvaluationScoreLabelMap = { + [EvaluationScore.answer_f1]: { + label: "F1", + }, + [EvaluationScore.answer_precision]: { + label: "准确率", + }, + [EvaluationScore.answer_recall]: { + label: "召回率", + }, +}; + +export enum EvaluationStatusEnum { + running = 1, + failed = 2, + success = 3, +} +export const EvaluationStatusLabelMap = { + [EvaluationStatusEnum.running]: { + label: "进行中", + variant: "secondary", + }, + [EvaluationStatusEnum.failed]: { + label: "失败", + variant: "destructive", + }, + [EvaluationStatusEnum.success]: { + label: "成功", + variant: "default", + }, +}; diff --git a/src/pages/LogPage/index.tsx b/src/pages/LogPage/index.tsx new file mode 100644 index 0000000..3d1ec6a --- /dev/null +++ b/src/pages/LogPage/index.tsx @@ -0,0 +1,226 @@ +import { Button } from "@/components/bs-ui/button"; +import { DatePicker } from "@/components/bs-ui/calendar/datePicker"; +import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/bs-ui/select"; +import MultiSelect from "@/components/bs-ui/select/multi"; +import { getActionsApi, getActionsByModuleApi, getLogsApi, getModulesApi, getOperatorsApi } from "@/controllers/API/log"; +import { getUserGroupsApi } from "@/controllers/API/user"; +import { useTable } from "@/util/hook"; +import { formatDate } from "@/util/utils"; +import { useEffect, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; +import AutoPagination from "../../components/bs-ui/pagination/autoPagination"; +import { + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow +} from "../../components/bs-ui/table"; +import { transformEvent, transformModule, transformObjectType } from "./utils"; + +const useGroups = () => { + const [groups, setGroups] = useState([]) + const loadData = () => { + getUserGroupsApi().then((res:any) => setGroups(res.records)) + } + return { groups, loadData } +} +const useModules = () => { + const [modules, setModules] = useState([]) + const loadModules = () => { + getModulesApi().then(res => setModules(res.data)) + } + return { modules, loadModules } +} + +export default function index() { + const { t } = useTranslation() + const { users, selectedRef, loadUsers, searchUser } = useUsers() + const { groups, loadData } = useGroups() + const { modules, loadModules } = useModules() + const { page, pageSize, data: logs, total, loading, setPage, filterData } = useTable({ pageSize: 20 }, (param) => + getLogsApi({...param}) + ) + const init = { + userIds: [], + groupId: '', + start: undefined, + end: undefined, + moduleId: '', + action: '' + } + + const [actions, setActions] = useState([]) + const [keys, setKeys] = useState({...init}) + + const handleActionOpen = async () => { + setActions((keys.moduleId ? await getActionsByModuleApi(keys.moduleId) : await getActionsApi())) + } + const handleSearch = () => { + const startTime = keys.start && formatDate(keys.start, 'yyyy-MM-dd HH:mm:ss') + const endTime = keys.end && formatDate(keys.end, 'yyyy-MM-dd HH:mm:ss').replace('00:00:00','23:59:59') + filterData({...keys, start:startTime, end:endTime}) + } + const handleReset = () => { + setKeys({...init}) + filterData(init) + } + useEffect(() => { + loadUsers() + },[]) + + return
+
+

{t('log.auditManagement')}

+
+
+ { searchUser(key); selectedRef.current = keys.userIds}} + onChange={(values) => {setKeys({...keys,userIds:values}); console.log(values)}} + > +
+
+ +
+
+ setKeys({...keys,start:t})} /> +
+
+ setKeys({...keys,end:t})} /> +
+
+ +
+
+ +
+
+ + +
+
+ + + + {t('log.auditId')} + {t('log.username')} + {t('log.operationTime')} + {t('log.systemModule')} + {t('log.operationAction')} + {t('log.objectType')} + {t('log.operationObject')} + {t('log.ipAddress')} + {t('log.remark')} + + + { + loading + ?
+ +
+ : + {logs.map((log:any) => ( + + {log.id} +
{log.operator_name}
+ {log.create_time.replace('T', ' ')} + {transformModule(log.system_id)} + {transformEvent(log.event_type)} + {transformObjectType(log.object_type)} +
{log.object_name || '无'}
+ {log.ip_address} + +
{log.note?.replace('编辑后', `\n编辑后`) || '无'}
+
+
+ ))} +
+ } + + {!logs.length && + + {t('build.empty')} + + } +
+ {!logs.length &&
} +
+ {/* 分页 */} + {/* */} +
+ setPage(newPage)} + /> +
+
+}; + + +const useUsers = () => { + const [users, setUsers] = useState([]); + const userRef = useRef([]) + const selectedRef = useRef([]) + + const loadUsers = () => { + getOperatorsApi().then(res => { + const options = res.map((u:any) => ({label:u.user_name, value:u.user_id})) + userRef.current = options + setUsers(options) + }) + } + const search = (name) => { + const newUsers = userRef.current.filter(u => u.label.toLowerCase().includes(name.toLowerCase()) + || selectedRef.current.includes(u.value)) + setUsers(newUsers) + } + + return { + users, + selectedRef, + loadUsers, + searchUser(name) { + search(name) + } + } +} \ No newline at end of file diff --git a/src/pages/LogPage/utils/index.ts b/src/pages/LogPage/utils/index.ts new file mode 100644 index 0000000..32c511d --- /dev/null +++ b/src/pages/LogPage/utils/index.ts @@ -0,0 +1,48 @@ +export function transformModule(system: string): string { + switch(system) { + case 'chat': return '会话' + case 'build': return '构建' + case 'knowledge': return '知识库' + case 'system': return '系统' + default: return '转换失败' + } +} + +export function transformEvent(event: string): string { + switch(event) { + case 'create_chat': return '新建会话'; + case 'delete_chat': return '删除会话'; + case 'create_build': return '新建应用'; + case 'update_build': return '编辑应用'; + case 'delete_build': return '删除应用'; + case 'create_knowledge': return '新建知识库'; + case 'delete_knowledge': return '删除知识库'; + case 'upload_file': return '知识库上传文件'; + case 'delete_file': return '知识库删除文件'; + case 'update_user': return '用户编辑'; + case 'forbid_user': return '停用用户'; + case 'recover_user': return '启用用户'; + case 'create_user_group': return '新建用户组'; + case 'delete_user_group': return '删除用户组'; + case 'update_user_group': return '编辑用户组'; + case 'create_role': return '新建角色'; + case 'delete_role': return '删除角色'; + case 'update_role': return '编辑角色'; + case 'user_login': return '用户登录'; + default: return '转换失败' + } +} + +export function transformObjectType(object: string): string { + switch(object) { + case 'none': return '无' + case 'flow': return '技能' + case 'assistant': return '助手' + case 'knowledge': return '知识库' + case 'file': return '文件' + case 'user_conf': return '用户配置' + case 'user_group_conf': return '用户组配置' + case 'role_conf': return '角色配置' + default: return '转换失败' + } +} \ No newline at end of file diff --git a/src/pages/LoginPage/UserPwdModal.tsx b/src/pages/LoginPage/UserPwdModal.tsx new file mode 100644 index 0000000..e6e494e --- /dev/null +++ b/src/pages/LoginPage/UserPwdModal.tsx @@ -0,0 +1,90 @@ +import { Button } from "@/components/bs-ui/button"; +import { Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/bs-ui/dialog"; +import { PasswordInput } from "@/components/bs-ui/input"; +import { forwardRef, useImperativeHandle, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; +// import { resetUserPasswordApi } from "../controllers/API/user"; // 假设这是重置密码的API函数 +import { useToast } from "@/components/bs-ui/toast/use-toast"; +import { resetPasswordApi } from "@/controllers/API/user"; +import { captureAndAlertRequestErrorHoc } from "@/controllers/request"; +import { handleEncrypt, PWD_RULE } from "./utils"; + +interface UserPwdModalProps { + // onSuccess: () => void; +} + +interface UserPwdModalRef { + open: (userId: string) => void; +} + +const UserPwdModal = forwardRef((props, ref) => { + const { t } = useTranslation(); + const { message } = useToast(); + + const [editShow, setEditShow] = useState(false); + const [error, setError] = useState(''); + const passwordRef = useRef(null) + const userIdRef = useRef(null); + + useImperativeHandle(ref, () => ({ + open: (userId) => { + userIdRef.current = userId; + setEditShow(true); + } + })); + + const handleSubmit = async () => { + // if (!PWD_RULE.test(passwordRef.current.value)) { + // return setError(t('login.passwordError')) + // } + const errors:string[] = [] + if(!passwordRef.current.value) errors.push(t('resetPassword.notEmpty')) + if (!/.{6,}/.test(passwordRef.current.value)) errors.push(t('resetPassword.newPasswordTooShort')) + if (!PWD_RULE.test(passwordRef.current.value)) errors.push(t('login.passwordError')) + if(errors.length) return message({title: t('prompt'), variant: 'error', description: errors}) + + const cryptPwd = await handleEncrypt(passwordRef.current.value) + const res = await captureAndAlertRequestErrorHoc(resetPasswordApi(userIdRef.current, cryptPwd)) + if (res === null) { + message({ + title: `${t('prompt')}`, + variant: 'success', + description: [t('resetPassword.adminResetSuccess')] + }); + setEditShow(false); + // onSuccess(); + } + }; + + return ( + + + + {t('resetPassword.resetButton')} + +
+
+ + passwordRef.current.value = e.target.value} + /> + {error &&

{error}

} +
+
+ + + + + + +
+
+ ); +}); + +export default UserPwdModal; diff --git a/src/pages/LoginPage/icons/wxpro.svg b/src/pages/LoginPage/icons/wxpro.svg new file mode 100644 index 0000000..ed87cc0 --- /dev/null +++ b/src/pages/LoginPage/icons/wxpro.svg @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/src/pages/LoginPage/login.tsx b/src/pages/LoginPage/login.tsx new file mode 100644 index 0000000..df4dc7c --- /dev/null +++ b/src/pages/LoginPage/login.tsx @@ -0,0 +1,223 @@ +import { BookOpenIcon } from '@/components/bs-icons/bookOpen'; +import { GithubIcon } from '@/components/bs-icons/github'; +import { useContext, useEffect, useRef, useState } from "react"; +import { useTranslation } from 'react-i18next'; +import json from "../../../package.json"; +import { Button } from "../../components/bs-ui/button"; +import { Input } from "../../components/bs-ui/input"; +// import { alertContext } from "../contexts/alertContext"; +import { useToast } from "@/components/bs-ui/toast/use-toast"; +import { useNavigate } from 'react-router-dom'; +import { getCaptchaApi, loginApi, registerApi } from "../../controllers/API/user"; +import { captureAndAlertRequestErrorHoc } from "../../controllers/request"; +import LoginBridge from './loginBridge'; +import { PWD_RULE, handleEncrypt, handleLdapEncrypt } from './utils'; +import { locationContext } from '@/contexts/locationContext'; +import { ldapLoginApi } from '@/controllers/API/pro'; + +export const LoginPage = () => { + // const { setErrorData, setSuccessData } = useContext(alertContext); + const { t, i18n } = useTranslation(); + const { message, toast } = useToast() + const navigate = useNavigate() + const { appConfig } = useContext(locationContext) + + const isLoading = false + + const mailRef = useRef(null) + const pwdRef = useRef(null) + const agenPwdRef = useRef(null) + + // login or register + const [showLogin, setShowLogin] = useState(true) + + // captcha + const captchaRef = useRef(null) + const [captchaData, setCaptchaData] = useState({ captcha_key: '', user_capthca: false, captcha: '' }); + + useEffect(() => { + fetchCaptchaData(); + }, []); + + const fetchCaptchaData = () => { + getCaptchaApi().then(setCaptchaData) + }; + + const [isLDAP, setIsLDAP] = useState(false) + const handleLogin = async () => { + const error = [] + const [mail, pwd] = [mailRef.current.value, pwdRef.current.value] + if (!mail) error.push(t('login.pleaseEnterAccount')) + if (!pwd) error.push(t('login.pleaseEnterPassword')) + if (captchaData.user_capthca && !captchaRef.current.value) error.push(t('login.pleaseEnterCaptcha')) + if (error.length) return message({ + title: `${t('prompt')}`, + variant: 'warning', + description: error + }) + // if (error.length) return setErrorData({ + // title: `${t('prompt')}:`, + // list: error, + // }); + + const encryptPwd = isLDAP ? await handleLdapEncrypt(pwd) : await handleEncrypt(pwd) + captureAndAlertRequestErrorHoc( + (isLDAP + ? ldapLoginApi(mail, encryptPwd) + : loginApi(mail, encryptPwd, captchaData.captcha_key, captchaRef.current?.value) + ).then((res: any) => { + localStorage.setItem('ws_token', res.access_token) + localStorage.setItem('isLogin', '1') + location.href = __APP_ENV__.BASE_URL + '/' + }) + ), (error) => { + if (error.indexOf('过期') !== -1) { // 有时间改为 code 判断 + localStorage.setItem('account', mail) + navigate('/reset', { state: { noback: true } }) + } + } + + fetchCaptchaData() + } + + const handleRegister = async () => { + const error = [] + const [mail, pwd, apwd] = [mailRef.current.value, pwdRef.current.value, agenPwdRef.current.value] + if (!mail) { + error.push(t('login.pleaseEnterAccount')) + } + if (mail.length < 3) { + error.push(t('login.accountTooShort')) + } + if (!/.{7,}/.test(pwd)) { + error.push(t('login.passwordTooShort')) + } + if (!PWD_RULE.test(pwd)) { + error.push(t('login.passwordError')) + } + if (pwd !== apwd) { + error.push(t('login.passwordMismatch')) + } + if (captchaData.user_capthca && !captchaRef.current.value) { + error.push(t('login.pleaseEnterCaptcha')) + } + if (error.length) { + return message({ + title: `${t('prompt')}`, + variant: 'warning', + description: error + }) + } + const encryptPwd = await handleEncrypt(pwd) + captureAndAlertRequestErrorHoc(registerApi(mail, encryptPwd, captchaData.captcha_key, captchaRef.current?.value).then(res => { + // setSuccessData({ title: t('login.registrationSuccess') }) + message({ + title: `${t('prompt')}`, + variant: 'success', + description: [t('login.registrationSuccess')] + }) + pwdRef.current.value = '' + setShowLogin(true) + })) + + fetchCaptchaData() + } + + return
+}; \ No newline at end of file diff --git a/src/pages/LoginPage/loginBridge.tsx b/src/pages/LoginPage/loginBridge.tsx new file mode 100644 index 0000000..b284ff6 --- /dev/null +++ b/src/pages/LoginPage/loginBridge.tsx @@ -0,0 +1,35 @@ +import Separator from "@/components/bs-comp/chatComponent/Separator"; +import { Button } from "@/components/bs-ui/button"; +import { getSSOurlApi } from "@/controllers/API/pro"; +import { useEffect, useRef, useState } from "react"; +//@ts-ignore +import { ReactComponent as Wxpro } from "./icons/wxpro.svg"; +import { useTranslation } from "react-i18next"; + +export default function LoginBridge({ onHasLdap }) { + + const { t } = useTranslation() + + const urlRef = useRef('') + const [hasSSO, setHasSSO] = useState(false) + useEffect(() => { + getSSOurlApi().then((urls: any) => { + urlRef.current = urls.wx + setHasSSO(!!urls.sso) + urls.ldap && onHasLdap(true) + }) + }, []) + + const clickQwLogin = () => { + location.href = urlRef.current + } + + if (!hasSSO) return null + + return
+ +
+ +
+
+}; diff --git a/src/pages/LoginPage/resetPwd.tsx b/src/pages/LoginPage/resetPwd.tsx new file mode 100644 index 0000000..89c0771 --- /dev/null +++ b/src/pages/LoginPage/resetPwd.tsx @@ -0,0 +1,131 @@ +import { useToast } from "@/components/bs-ui/toast/use-toast"; +import { ArrowLeftIcon } from '@radix-ui/react-icons'; +import { useEffect, useRef } from "react"; +import { useTranslation } from 'react-i18next'; +import { useLocation, useNavigate } from 'react-router-dom'; +import { Button } from "../../components/bs-ui/button"; +import { PasswordInput } from "../../components/bs-ui/input"; +import { loggedChangePasswordApi, changePasswordApi } from "../../controllers/API/user"; +import { captureAndAlertRequestErrorHoc } from "../../controllers/request"; +import { PWD_RULE, handleEncrypt } from './utils'; +import reset from "../../assets/Login/reset.png"; +import loginIcon from "../../assets/Login/login-icon.png"; + +export const ResetPwdPage = () => { + const { t } = useTranslation(); + const { message } = useToast(); + const { state } = useLocation() + const navigate = useNavigate() + + useEffect(() => { + state?.noback && message({ + title: `${t('prompt')}`, + variant: 'warning', + description: '您的密码已过期,请及时修改' + }) + }, []) + + const currentPwdRef = useRef(null); + const newPwdRef = useRef(null); + const confirmPwdRef = useRef(null); + + const handleResetPassword = async () => { + const errors: string[] = []; + const [currentPwd, newPwd, confirmPwd] = [ + currentPwdRef.current?.value, + newPwdRef.current?.value, + confirmPwdRef.current?.value + ]; + + if (!currentPwd) errors.push(t('resetPassword.pleaseEnterCurrentPassword')); + if (!newPwd) errors.push(t('resetPassword.pleaseEnterNewPassword')); + if (!confirmPwd) errors.push(t('resetPassword.pleaseEnterConfirmPassword')); + if (!/.{7,}/.test(newPwd)) errors.push(t('resetPassword.newPasswordTooShort')); + if (!PWD_RULE.test(newPwd)) errors.push(t('login.passwordError')) + if (newPwd !== confirmPwd) errors.push(t('resetPassword.passwordMismatch')); + + if (errors.length) { + return message({ + title: `${t('prompt')}`, + variant: 'warning', + description: errors + }); + } + + const account = localStorage.getItem('account'); + const encryptCurrentPwd = await handleEncrypt(currentPwd); + const encryptNewPwd = await handleEncrypt(newPwd); + + console.log(state) + const res = await captureAndAlertRequestErrorHoc(state ? changePasswordApi(account, encryptCurrentPwd, encryptNewPwd) : loggedChangePasswordApi(encryptCurrentPwd, encryptNewPwd)) + if (res === null) { + message({ + title: `${t('prompt')}`, + variant: 'success', + description: [t('resetPassword.passwordResetSuccess')] + }); + // Clear input fields + if (currentPwdRef.current) currentPwdRef.current.value = ''; + if (newPwdRef.current) newPwdRef.current.value = ''; + if (confirmPwdRef.current) confirmPwdRef.current.value = ''; + // if (!state?.noback) { + navigate(-1); + // } + } + // })); + }; + + return ( +
+
+ {!state?.noback && } +
+
+ + {/* small_logo */} + {t('resetPassword.slogen')} +
+
+
+ +
+
+ +
+
+ +
+ +
+
+
+
+ ); +}; + +export default ResetPwdPage; diff --git a/src/pages/LoginPage/utils.ts b/src/pages/LoginPage/utils.ts new file mode 100644 index 0000000..6178ac1 --- /dev/null +++ b/src/pages/LoginPage/utils.ts @@ -0,0 +1,20 @@ +import { getPublicKeyApi } from "@/controllers/API/user"; +import { getKeyApi } from "@/controllers/API/pro"; +import { JSEncrypt } from 'jsencrypt'; + +export const handleEncrypt = async (pwd: string): Promise => { + const { public_key } = await getPublicKeyApi(); + const encrypt = new JSEncrypt(); + encrypt.setPublicKey(public_key); + return encrypt.encrypt(pwd) as string; +}; + +export const handleLdapEncrypt = async (pwd: string): Promise => { + const public_key:any = await getKeyApi(); + const encrypt = new JSEncrypt(); + encrypt.setPublicKey(public_key); + return encrypt.encrypt(pwd) as string; +}; + +// export const PWD_RULE = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}$/ +export const PWD_RULE = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d].{7,}$/ \ No newline at end of file diff --git a/src/pages/Page403.tsx b/src/pages/Page403.tsx new file mode 100644 index 0000000..79206f6 --- /dev/null +++ b/src/pages/Page403.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +export default function Page403() { + return ( +
+
+

+ 403 +

+

+ 您无权访问该页面 +

+
+ +
+
+
+ ); +}; diff --git a/src/pages/SkillPage/components/editAssistant/Setting.tsx b/src/pages/SkillPage/components/editAssistant/Setting.tsx index 72dae60..627a7c6 100644 --- a/src/pages/SkillPage/components/editAssistant/Setting.tsx +++ b/src/pages/SkillPage/components/editAssistant/Setting.tsx @@ -29,6 +29,7 @@ import { Link } from "react-router-dom"; import KnowledgeBaseMulti from "./KnowledgeBaseMulti"; import ModelSelect from "./ModelSelect"; import Temperature from "./Temperature"; +import KnowledgeSelect from "@/components/bs-comp/selectComponent/knowledge"; export default function Setting() { const { t } = useTranslation(); @@ -154,7 +155,7 @@ export default function Setting() {
- dispatchAssistant("setting", { knowledge_list: vals }) @@ -173,7 +174,28 @@ export default function Setting() {
)} - + */} + ({ label: el.name, value: el.id }))} + onChange={(vals) => + dispatchAssistant("setting", { knowledge_list: vals.map(el => ({ name: el.label, id: el.value })) }) + } + > + {(reload) => ( +
+ + + + +
+ )} +
diff --git a/src/pages/SkillPage/components/editAssistant/TestChat.tsx b/src/pages/SkillPage/components/editAssistant/TestChat.tsx index d5b2cb0..fdedb36 100644 --- a/src/pages/SkillPage/components/editAssistant/TestChat.tsx +++ b/src/pages/SkillPage/components/editAssistant/TestChat.tsx @@ -52,7 +52,7 @@ export default function TestChat({ assisId, guideQuestion }) { guideWord='' wsUrl={wsUrl} onBeforSend={getWsParamData} - type={{"avatar_img":assistantState.avatar_img,"avatar_color":assistantState.avatar_color,"type":"assistant"}} + type={{"avatar_img":assistantState.avatar_img,"avatar_color":assistantState.avatar_color,"type":"assistant","id":assistantState.id}} >
}; diff --git a/src/pages/SkillPage/editAssistant.tsx b/src/pages/SkillPage/editAssistant.tsx index 1f1d4ab..963bc32 100644 --- a/src/pages/SkillPage/editAssistant.tsx +++ b/src/pages/SkillPage/editAssistant.tsx @@ -21,7 +21,7 @@ export default function editAssistant() { const { startNewRound, insetSystemMsg, insetBsMsg, setShowGuideQuestion } = useMessageStore() useEffect(() => { - loadAssistantState(assisId).then((res) => { + loadAssistantState(assisId, 'v1').then((res) => { setShowGuideQuestion(true) setGuideQuestion(res.guide_question?.filter((item) => item) || []) res.guide_word && insetBsMsg(res.guide_word) diff --git a/src/pages/SkillPage/tabAssistant.tsx b/src/pages/SkillPage/tabAssistant.tsx index 54b072b..68a17e3 100644 --- a/src/pages/SkillPage/tabAssistant.tsx +++ b/src/pages/SkillPage/tabAssistant.tsx @@ -163,6 +163,10 @@ export default function Assistants() { 编辑
} + {openSwitch &&
{setIsShareLink(!isShareLink);setIsShareLinkData(location.origin + "/chat/assistant/" + item.id)}}> + +
} + {item.write &&
delConfirm(item)}>
} diff --git a/src/pages/SystemPage/.DS_Store b/src/pages/SystemPage/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c541456b90d381ccd015d0d0750c8f37a6fbfede GIT binary patch literal 6148 zcmeHK!D`z;5S>k&T1qJR&_FJQgqPpp!*Q&IKHaJ!!5>Z)eEIBq9gU-pv z^x7}!@3e1rHzkhkYaGH3%)HUgj8^+#XSGBmI-~eCQGTC9Xj}|z z&F^TCrA66l{Sh0RwXJ7$&+~S?)9_M_!?IV7icW9%ou9ral|{FHFZ!A$<8I@{2bGt- zG*5=QAdM5G{P>pUu^M;OD31$W8=8RU`+m2vH=VXyM@@P7u03nY>Cu~3Q?}o>XEWd1 zeRXjBx%)Hg=jvL2Jqh$HEzd39!VR3Id|ZXYJX84v;#})f3a(;wy9w>wwW$0ALNnTHy2V0@p~3fyK%oA`oFpfu>a0D~2%T7?(CLuvi&1KTv0-6SA90L!^z(3$QvNiw! literal 0 HcmV?d00001 diff --git a/src/pages/SystemPage/components/.DS_Store b/src/pages/SystemPage/components/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..92d05aaf47887c92f4e5838fa616e07a49019dae GIT binary patch literal 6148 zcmeHK%T59@6g@>2fJ$KJ#$>*L#6K7jVpzD*xK|z$lTnO7qPyAq3&tOC;rF@HbK5c& zW{@2*=H8?|eVu#TGif^oVA}KH5zqioVG=CYm=&1xOUhZvx9k#)^>K?aT9{#qr`%|5 zPz6+hzovlf-5O3X!98ve?B8B88T6A$pZ#(;95c1Ptg!^t$$7*G*WB$RTyn>cSoeE> znQLA+{w?4((Z!IlW;kcugv;WJ25Jun2c_@y2xWfC1yqNJRXFb83u?s!m zogQ9;xmU9}Pm39Lwc%X%Gj%q_5{*Nh8X0q;Q_re>wSF znTP47Z)8O4aQ4-JTc~YmOhy=uRkbZDU|g(3&M#!#vW6L?4cP)B|56{PYmPeY>)i7*kkI@(P8}K!}!R?zfg>gPXCb| z4ih`nToq6SmKE4>)rQ>v-SzMPWs=rZ0af5%DPYQ-i%y$M@^@=)adOv2Ojk@|GA?y! kDa`zJYzuM~A23;CUnB)$>@ju77MlJDSQ#`^1-7cdH;KHqMgRZ+ literal 0 HcmV?d00001 diff --git a/src/pages/SystemPage/components/CreateUser.tsx b/src/pages/SystemPage/components/CreateUser.tsx new file mode 100644 index 0000000..9e52eeb --- /dev/null +++ b/src/pages/SystemPage/components/CreateUser.tsx @@ -0,0 +1,102 @@ +import { Button } from "@/components/bs-ui/button" +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/bs-ui/dialog" +import { Input, PasswordInput } from "@/components/bs-ui/input" +import { Label } from "@/components/bs-ui/label" +import { useToast } from "@/components/bs-ui/toast/use-toast" +import { generateUUID } from "@/components/bs-ui/utils" +import { createUserApi } from "@/controllers/API/user" +import { captureAndAlertRequestErrorHoc } from "@/controllers/request" +import { handleEncrypt, PWD_RULE } from "@/pages/LoginPage/utils" +import { copyText } from "@/utils" +import { PlusIcon } from "@radix-ui/react-icons" +import { useState } from "react" +import { useTranslation } from "react-i18next" +import UserRoleItem from "./UserRoleItem" + +export default function CreateUser({open, onClose, onSave}) { + const { t } = useTranslation() + const { message } = useToast() + const initItems = { key:generateUUID(8), groupId:'', roles:[] } + const initUser = { + user_name:'', + password:'', + } + + const [items, setItems] = useState([initItems]) + const [form, setForm] = useState(initUser) + + const handleCancel = () => { + onClose(false) + setItems([initItems]) + setForm(initUser) + } + const errors = [] + const handleConfirm = async () => { + if(form.user_name === '') errors.push('用户名不可为空') + if(form.user_name.length > 30) errors.push('用户名最长 30 个字符') + if(!PWD_RULE.test(form.password)) errors.push('至少 7 个字符,需包含数字、字母') + if(items.every(item => item.roles.length === 0)) errors.push('至少选择一个角色') + if(errors.length > 0) return message({title:t('prompt'), description:errors, variant:'warning'}) + + const encryptPwd = await handleEncrypt(form.password) + const group_roles = items.map(item => ({ + group_id: Number(item.groupId), + role_ids: item.roles.map(r => Number(r)) + })) + captureAndAlertRequestErrorHoc(createUserApi(form.user_name, encryptPwd, group_roles).then(() => { + copyText(`用户名:${form.user_name},初始密码:${form.password}`).then(() => + message({title:t('prompt'), description:'创建用户成功!已复制用户名和初始密码到剪贴板', variant:'success'})) + onClose(false) + setItems([initItems]) + setForm(initUser) + onSave() + })) + } + + const handleChangeRoleItems = (index, groupId, roles) => { + setItems(items => items.map((item, i) => { + return i === index ? {...item, groupId:groupId[0], roles} : item + })) + } + + return onClose(b)}> + + + 创建用户 + +
+
+ + setForm({...form, user_name:e.target.value})} + placeholder="后续使用此用户名进行登录,用户名不可修改" className="h-[48px] npcInput mt-[10px]"/> +
+
+ + setForm({...form, password:e.target.value})} inputClassName="h-[48px] npcInput mt-[10px]"/> +
+
+ +
+ {items.map((item, index) => 1} + selectedRoles={[]} + onChange={(groupId, roles) => handleChangeRoleItems(index, groupId, roles)} + onDelete={() => setItems(items => items.filter((el, i) => i !== index))} + />)} +
+ +
+
+ + + + +
+
+} \ No newline at end of file diff --git a/src/pages/SystemPage/components/EditRole.tsx b/src/pages/SystemPage/components/EditRole.tsx index eb527e2..fdcc6c1 100644 --- a/src/pages/SystemPage/components/EditRole.tsx +++ b/src/pages/SystemPage/components/EditRole.tsx @@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next"; import { Button } from "../../../components/bs-ui/button"; import { Input, SearchInput } from "../../../components/bs-ui/input"; import AutoPagination from "../../../components/bs-ui/pagination/autoPagination"; +// import { Switch } from "../../../components/bs-ui/switch"; import { Switch } from "../../../components/ui/switch"; import { Table, @@ -13,27 +14,35 @@ import { TableRow } from "../../../components/bs-ui/table"; import { alertContext } from "../../../contexts/alertContext"; -import { createRole, getRoleAssistApi, getRoleLibsApi, getRolePermissionsApi, getRoleSkillsApi, updateRoleNameApi, updateRolePermissionsApi } from "../../../controllers/API/user"; +import { createRole, getGroupResourcesApi, getRolePermissionsApi, updateRoleNameApi, updateRolePermissionsApi } from "../../../controllers/API/user"; import { captureAndAlertRequestErrorHoc } from "../../../controllers/request"; import { useTable } from "../../../util/hook"; -const SearchPanne = ({ role_id, title, type, children }) => { +const SearchPanne = ({ groupId, title, type, children }) => { const { page, pageSize, data, total, loading, setPage, search } = useTable({ pageSize: 10 }, (params) => { const { page, pageSize, keyword } = params const param = { name: keyword, - role_id, + group_id: groupId, page_num: page, page_size: pageSize } - return type === 'skill' ? getRoleSkillsApi(param) - : (type === 'assistant' ? getRoleAssistApi({ ...param, type: 'assistant' }) - : getRoleLibsApi(param)) + + switch (type) { + case 'skill': + return getGroupResourcesApi({ ...param, resource_type: 2 }); + case 'tool': + return getGroupResourcesApi({ ...param, resource_type: 4 }); + case 'assistant': + return getGroupResourcesApi({ ...param, resource_type: 3 }); + default: + return getGroupResourcesApi({ ...param, resource_type: 1 }); + } }) return <>
-

{title}

+

{title}

search(e.target.value)}>
@@ -48,32 +57,44 @@ const SearchPanne = ({ role_id, title, type, children }) => { } +const enum MenuType { + BUILD = 'build', + KNOWLEDGE = 'knowledge', + MODEL = 'model', + EVALUATION = 'evaluation' +} // -1 id表示新增 -export default function EditRole({ id, name, onChange, onBeforeChange }) { +export default function EditRole({ id, name, groupId, onChange, onBeforeChange }) { const { setErrorData, setSuccessData } = useContext(alertContext); const { t } = useTranslation() + // 使用的权限 const [form, setForm] = useState({ name, useSkills: [], useLibs: [], useAssistant: [], - manageLibs: [] + manageLibs: [], + useTools: [], + useMenu: [MenuType.BUILD, MenuType.KNOWLEDGE] }) useEffect(() => { if (id !== -1) { // 获取详情,初始化选中数据 getRolePermissionsApi(id).then(res => { - const useSkills = [], useLibs = [], manageLibs = [], useAssistant = [] + const useSkills = [], useLibs = [], manageLibs = [], useAssistant = [], useTools = [], + useMenu = [] res.data.forEach(item => { switch (item.type) { case 1: useLibs.push(Number(item.third_id)); break; case 2: useSkills.push(item.third_id); break; case 3: manageLibs.push(Number(item.third_id)); break; + case 7: useTools.push(Number(item.third_id)); break; case 5: useAssistant.push(item.third_id); break; + case 99: useMenu.push(item.third_id); break; } }) - setForm({ name, useSkills, useLibs, useAssistant, manageLibs }) + setForm({ name, useSkills, useLibs, useAssistant, manageLibs, useTools, useMenu }) }) } }, [id]) @@ -100,7 +121,7 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { * 1.验证重名 * 2.新增时先保存基本信息 创建 ID * 3.修改时先更新基本信息 - * 4.批量 保存各个种类权限信息(助手、技能、知识库等) + * 4.再批量 保存各个种类权限信息(助手、技能、知识库等) * @returns */ const handleSave = async () => { @@ -119,7 +140,7 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { // 没有id时需要走创建流程,否则修改 let roleId = id if (id === -1) { - const res = await captureAndAlertRequestErrorHoc(createRole(form.name)) + const res = await captureAndAlertRequestErrorHoc(createRole(groupId, form.name)) roleId = res.id } else { // 更新基本信息 @@ -130,7 +151,9 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { updateRolePermissionsApi({ role_id: roleId, access_id: form.useSkills, type: 2 }), updateRolePermissionsApi({ role_id: roleId, access_id: form.useLibs, type: 1 }), updateRolePermissionsApi({ role_id: roleId, access_id: form.manageLibs, type: 3 }), - updateRolePermissionsApi({ role_id: roleId, access_id: form.useAssistant, type: 5 }) + updateRolePermissionsApi({ role_id: roleId, access_id: form.useTools, type: 7 }), + updateRolePermissionsApi({ role_id: roleId, access_id: form.useAssistant, type: 5 }), + updateRolePermissionsApi({ role_id: roleId, access_id: form.useMenu, type: 99 }), ]) console.log('form :>> ', form, res); @@ -140,21 +163,66 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { const roleId = id === -1 ? 0 : id - return
+ return
-

{t('system.roleName')}

+

{t('system.roleName')}

setForm({ ...form, name: e.target.value })} maxLength={60}>
+ {/* 菜单授权 */} +
+
+

菜单授权

+
+
+ + + + 一级菜单 + 查看权限 + + + + + NPC + + switchDataChange(MenuType.BUILD, 'useMenu', bln)} /> + + + + 知识库 + + switchDataChange(MenuType.KNOWLEDGE, 'useMenu', bln)} /> + + + + 模型 + + switchDataChange(MenuType.MODEL, 'useMenu', bln)} /> + + + + 评测 + + switchDataChange(MenuType.EVALUATION, 'useMenu', bln)} /> + + + +
+
+
{/* 助手 */}
- + {(data) => ( - NPC名称 - {t('system.creator')} - {t('system.usePermission')} + {t('system.assistantName')} + {t('system.creator')} + {t('system.usePermission')} @@ -162,7 +230,7 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { {el.name} {el.user_name} - + switchDataChange(el.id, 'useAssistant', bln)} /> @@ -174,14 +242,18 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { {/* 技能 */}
- + {(data) => (
- {t('system.skillName')} - {t('system.creator')} - {t('system.usePermission')} + {t('system.skillName')} + {t('system.creator')} + {t('system.usePermission')} @@ -189,7 +261,7 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { {el.name} {el.user_name} - + switchDataChange(el.id, 'useSkills', bln)} /> @@ -200,16 +272,19 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { {/* 知识库 */} -
- +
+ {(data) => (
- {t('lib.libraryName')} - {t('system.creator')} - {t('system.usePermission')} - {t('system.managePermission')} + {t('lib.libraryName')} + {t('system.creator')} + {t('system.usePermission')} + {t('system.managePermission')} @@ -217,10 +292,10 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { {el.name} {el.user_name} - + switchUseLib(el.id, bln)} /> - + switchLibManage(el.id, bln)} /> @@ -230,8 +305,44 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { )} -
- + {/* 工具 */} +
+ + {(data) => ( +
+ + + {t('lib.toolName')} + {t('system.creator')} + {t('system.usePermission')} + + + + {data.map((el) => ( + + {el.name} + {el.user_name} + + switchDataChange(el.id, 'useTools', bln)} + /> + + + ))} + +
+ )} +
+
+
+ {/* + */} +
diff --git a/src/pages/SystemPage/components/EditUserGroup.tsx b/src/pages/SystemPage/components/EditUserGroup.tsx new file mode 100644 index 0000000..b25e222 --- /dev/null +++ b/src/pages/SystemPage/components/EditUserGroup.tsx @@ -0,0 +1,266 @@ +import UsersSelect from "@/components/bs-comp/selectComponent/Users"; +import { Button } from "@/components/bs-ui/button"; +import { Label } from "@/components/bs-ui/label"; +import AutoPagination from "@/components/bs-ui/pagination/autoPagination"; +import { RadioGroup, RadioGroupItem } from "@/components/bs-ui/radio"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/bs-ui/table"; +import { useToast } from "@/components/bs-ui/toast/use-toast"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/bs-ui/tooltip"; +import { locationContext } from "@/contexts/locationContext"; +import { getGroupFlowsApi, saveGroupApi } from "@/controllers/API/pro"; +import { getAdminsApi, saveUserGroup, updateUserGroup } from "@/controllers/API/user"; +import { captureAndAlertRequestErrorHoc } from "@/controllers/request"; +import { useTable } from "@/util/hook"; +import { QuestionMarkCircledIcon } from "@radix-ui/react-icons"; +import { useContext, useEffect, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Input, SearchInput } from "../../../components/bs-ui/input"; + +/** + * + * 用户组编辑&创建接口逻辑 + * 创建 + * 1.用名字和管理员作为参数 调开源接口创建 + * 2.再调闭源接口设置 流控 + * 编辑 + * 1.用名字调开源接口修改 + * 2.用管理员s调开源接口修改 + * 3.再调闭源接口设置 流控 + * + * 资源流控控制,每次调接口只传变动的 limit + * limitState中转状态,limit只在初始化接收一次(不支持异步加载) + * @returns + */ +const enum LimitType { + LIMITED = 'limited', + UNLIMITED = 'unlimited' +} + +function FlowRadio({ limit, onChange }) { + const { t } = useTranslation() + const [status, setStatus] = useState(LimitType.UNLIMITED) + const [limitState, setLimitState] = useState(limit) + + const handleCommit = (type: LimitType, value: string = '0') => { + const valueNum = parseInt(value) + if (valueNum < 0 || valueNum > 9999) return + setStatus(type) + setLimitState(value) + onChange(Number(value)) + } + useEffect(() => { + setStatus(limit ? LimitType.LIMITED : LimitType.UNLIMITED) + setLimitState(limit) + }, [limit]) + + return
+ handleCommit(value, value === LimitType.LIMITED ? '10' : '0')}> +
+ +
+
+ +
+ {status === LimitType.LIMITED &&
+ + handleCommit(LimitType.LIMITED, e.target.value)} /> + +
} +
+
+} + +function FlowControl({ groupId, type, onChange }) { + const { t } = useTranslation() + const { name, label, placeholder } = type === 3 + ? { name: t('build.assistantName'), label: t('system.AssistantFlowCtrl'), placeholder: t('system.assistantName') } + : { name: t('skills.skillName'), label: t('system.SkillFlowCtrl'), placeholder: t('skills.skillName') } + const { page, pageSize, data, total, setPage, search, refreshData } = useTable({ pageSize: 10 }, (params) => + getGroupFlowsApi(params.page, params.pageSize, type, groupId, params.keyword) + ) + + const itemsRef = useRef([]) + const handleChange = (value, id) => { + // resourceId, groupId, resourceLimit + const item = itemsRef.current.find(item => item.resource_id === id) + if (item) { + item.resource_limit = value + } else { + itemsRef.current.push({ + resource_id: id, + group_id: groupId, + resource_limit: value + }) + } + refreshData((item) => item.id === id, { limit: value }) + onChange(itemsRef.current) + } + + const searchEndRef = useRef(false) + const handleSearch = (e) => { + searchEndRef.current = true + search(e.target.value) + } + + if (!searchEndRef.current && !data.length) return null + + return <> +
+
+

{label}

+ + + + + + +

{t('system.iconHover')}

+
+
+
+
+ +
+
+ + + + {name} + {t('system.createdBy')} + {t('system.flowCtrlStrategy')} + + + + {data.map((i: any) => ( + {i.name} + {i.user_name} + + handleChange(val, i.id)}> + + ))} + +
+ +
+ +} + +export default function EditUserGroup({ data, onBeforeChange, onChange }) { + const { t } = useTranslation() + const { toast } = useToast() // 类似于alert + const { appConfig } = useContext(locationContext) + + const [form, setForm] = useState({ + groupName: '', + adminUser: '', + groupLimit: 0, + assistant: [], + skill: [] + }) + /** + * 用户 + */ + const [selected, setSelected] = useState([]) + const [lockOptions, setLockOptions] = useState([]) + + const handleSave = async () => { + console.log('form', form); + + if (!form.groupName) { + setForm({ ...form, groupName: data.group_name || '' }) + return toast({ title: t('prompt'), description: t('system.groupNameRequired'), variant: 'error' }); + } + if (form.groupName.length > 30) { + setForm({ ...form, groupName: data.group_name || '' }) + return toast({ title: t('prompt'), description: t('system.groupNamePrompt'), variant: 'error' }); + } + const flag = onBeforeChange(form.groupName) + if (flag) { + setForm({ ...form, groupName: '' }) + return toast({ title: t('prompt'), description: t('system.groupNameExists'), variant: 'error' }); + } + + // 过滤系统管理员 + const users = selected.filter(item => !lockOptions.some(id => id === item.value)) + + const res: any = await (data.id ? updateUserGroup(data.id, form, users) : // 修改 + saveUserGroup(form, users)) // 保存 + + if (appConfig.isPro) { + await captureAndAlertRequestErrorHoc(saveGroupApi({ + ...form, + id: data.id || res.id, // 修改id:data.id, 创建id:res.id + adminUser: users.map(item => item.label).join(','), + adminUserId: users.map(item => item.value).join(',') + })) + } + + onChange(true) + } + + useEffect(() => { // 初始化数据 + setForm({ ...form, groupName: data.group_name, groupLimit: data.group_limit || 0 }) + async function init() { + const res = await getAdminsApi() + const users = data.group_admins?.map(d => ({ label: d.user_name, value: d.user_id })) || [] + const defaultUsers = res.map(d => ({ label: d.user_name, value: d.user_id })) + setLockOptions(defaultUsers.map(el => el.value)) + setSelected([...defaultUsers, ...users]) + } + init() + }, []) + + return
+
+

{t('system.groupName')}

+ setForm({ ...form, groupName: e.target.value })}> +
+
+

{t('system.admins')}

+
+ +
+
+ {appConfig.isPro && <> +
+

{t('system.flowControl')}

+ setForm({ ...form, groupLimit: f })}> +
+
+ setForm({ ...form, assistant: vals })} + > +
+
+ setForm({ ...form, skill: vals })} + > +
+ } +
+ + +
+
+} \ No newline at end of file diff --git a/src/pages/SystemPage/components/Roles.tsx b/src/pages/SystemPage/components/Roles.tsx index 42db983..354e1b4 100644 --- a/src/pages/SystemPage/components/Roles.tsx +++ b/src/pages/SystemPage/components/Roles.tsx @@ -1,101 +1,234 @@ -import { useEffect, useRef, useState } from "react"; +import { PlusIcon } from "@/components/bs-icons/plus"; +import { bsConfirm } from "@/components/bs-ui/alertDialog/useConfirm"; +import { Label } from "@/components/bs-ui/label"; +import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; -import { bsconfirm } from "../../../alerts/confirm"; -import { Button } from "../../../components/ui/button"; +import { Button } from "../../../components/bs-ui/button"; +import { SearchInput } from "../../../components/bs-ui/input"; import { Table, TableBody, - TableCaption, TableCell, + TableFooter, TableHead, TableHeader, TableRow -} from "../../../components/ui/table"; -import { delRoleApi, getRolesApi } from "../../../controllers/API/user"; +} from "../../../components/bs-ui/table"; +import { delRoleApi, getRolesByGroupApi, getUserGroupsApi } from "../../../controllers/API/user"; import { captureAndAlertRequestErrorHoc } from "../../../controllers/request"; import { ROLE } from "../../../types/api/user"; import EditRole from "./EditRole"; -import { Input } from "../../../components/ui/input"; -import { Search } from "lucide-react"; +import SelectSearch from "@/components/bs-ui/select/select" + +interface State { + roles: ROLE[]; + role: Partial | null; + searchWord: string; + group: string; + groups: { label: string; value: string }[]; +} + +const initialState: State = { + roles: [], + role: null, + searchWord: '', + group: '', + groups: [] +}; + +type Action = + | { type: 'SET_ROLES'; payload: ROLE[] } + | { type: 'SET_ROLE'; payload: Partial | null } + | { type: 'SET_SEARCH_WORD'; payload: string } + | { type: 'SET_GROUP'; payload: string } + | { type: 'SET_GROUPS'; payload: any }; + +function reducer(state: State, action: Action): State { + switch (action.type) { + case 'SET_ROLES': + return { ...state, roles: action.payload }; + case 'SET_ROLE': + return { ...state, role: action.payload }; + case 'SET_SEARCH_WORD': + return { ...state, searchWord: action.payload }; + case 'SET_GROUP': + return { ...state, group: action.payload }; + case 'SET_GROUPS': + return { ...state, groups: action.payload }; + default: + return state; + } +} export default function Roles() { - const { t } = useTranslation() + const { t } = useTranslation(); + const [state, dispatch] = useReducer(reducer, initialState); + const allRolesRef = useRef([]); + const { delShow, idRef, close, delConfirm } = useDelete(); - const [role, setRole] = useState | null>(null) - const [roles, setRoles] = useState([]) - const allRolesRef = useRef([]) + const loadData = useCallback(async () => { + const inputDom = document.getElementById('role-input') as HTMLInputElement; + if (inputDom) { + inputDom.value = ''; + } + try { + const data:any = await getRolesByGroupApi('', [state.group]); + dispatch({ type: 'SET_ROLES', payload: data }); + allRolesRef.current = data; + } catch (error) { + console.error(error); + } + }, [state.group]); - const handleChange = (change: boolean) => { - change && loadData() - setRole(null) - } - - const loadData = () => { - getRolesApi().then(data => { - setRoles(data) - allRolesRef.current = data + useEffect(() => { + getUserGroupsApi().then((res:any) => { + const groups = res.records.map(ug => ({ label: ug.group_name, value: ug.id })) + // 获取最近修改用户组 + dispatch({ type: 'SET_GROUP', payload: groups[0].value }); + dispatch({ type: 'SET_GROUPS', payload: groups }); }) - } + }, []); - useEffect(() => loadData(), []) - - // 删除 - const handleDelete = (item) => { - bsconfirm({ - desc: `${t('system.confirmText')} 【${item.role_name}】 ?`, - okTxt: t('delete'), - onOk(next) { - captureAndAlertRequestErrorHoc(delRoleApi(item.id).then(loadData)) - next() - } + const handleDelete = (user) => { + // const handleDelete = async (item: ROLE) => { + // bsConfirm({ + // desc: `${t('system.confirmText')} 【${item.role_name}】 ?`, + // okTxt: t('delete'), + // onOk: async (next) => { + // try { + // await captureAndAlertRequestErrorHoc(delRoleApi(item.id)); + // await loadData(); + // next(); + // } catch (error) { + // console.error(error); + // } + // } + // }); + captureAndAlertRequestErrorHoc(delRoleApi(idRef.current.id)).then(res => { + loadData() + close(); }) + }; + + const checkSameName = useCallback((name: string) => { + return state.roles.find(_role => _role.role_name === name && state.role?.id !== _role.id); + }, [state.roles, state.role]); + + const handleSearch = (e: React.ChangeEvent) => { + const word = e.target.value; + dispatch({ type: 'SET_SEARCH_WORD', payload: word }); + dispatch({ type: 'SET_ROLES', payload: allRolesRef.current.filter(item => item.role_name.toUpperCase().includes(word.toUpperCase())) }); + }; + useEffect(() => { + loadData() + }, [state.group]) + + const [keyWord, setKeyWord] = useState('') + const options = useMemo(() => { + if (!keyWord || !state.group) return state.groups + return state.groups.filter(group => group.label.toUpperCase().includes(keyWord.toUpperCase()) || group.value === state.group) + }, [keyWord, state.group]) + + if (state.role) { + return { + dispatch({ type: 'SET_ROLE', payload: null }) + loadData() + }} + />; } - // 验证重名 - const checkSameName = (name: string) => { - return (roles.find(_role => - _role.role_name === name && role.id !== _role.id)) - } - - // search - const [searchWord, setSearchWord] = useState('') - const handleSearch = (e) => { - const word = e.target.value - setSearchWord(word) - setRoles(allRolesRef.current.filter(item => item.role_name.toUpperCase().includes(word.toUpperCase()))) - } - - if (role) return - - return
-
-
- - + return ( +
+
+

{t('system.roleList')}.

+
+
+ + { + !open && setKeyWord('') + }} + onValueChange={(value) => { + dispatch({ type: 'SET_GROUP', payload: value}) + }} + onChange={e => setKeyWord(e.target.value)} + /> +
+
+
+ +
+ +
+
+ + + + {t('system.roleName')} + {t('createTime')} + {t('operations')} + + + + {state.roles.map(el => ( + + {el.role_name} + {el.create_time.replace('T', ' ')} + + + + + + ))} + + + {!state.roles.length && + {t('build.empty')} + } + +
- +
+
+ + + +
+

{t('prompt')}

+

确认删除该角色?

+
+ + +
+
+
- - {t('system.roleList')}. - - - {t('system.roleName')} - {t('createTime')} - {t('operations')} - - - - {roles.map((el) => ( - - {el.role_name} - {el.create_time.replace('T', ' ')} - - - - - - ))} - -
-
-}; + ); +} + +const useDelete = () => { + const [delShow, setDelShow] = useState(false) + const idRef = useRef(null) + + return { + delShow, + idRef, + close: () => { + setDelShow(false) + }, + delConfirm: (id) => { + idRef.current = id + setDelShow(true) + } + } +} \ No newline at end of file diff --git a/src/pages/SystemPage/components/UserGroup.tsx b/src/pages/SystemPage/components/UserGroup.tsx new file mode 100644 index 0000000..35a74ac --- /dev/null +++ b/src/pages/SystemPage/components/UserGroup.tsx @@ -0,0 +1,160 @@ +import { useTranslation } from "react-i18next" +import { Button } from "../../../components/bs-ui/button"; +import { SearchInput } from "../../../components/bs-ui/input"; +import { PlusIcon } from "@/components/bs-icons/plus"; +import { getUserGroupsApi, delUserGroupApi, getAdminsApi } from "@/controllers/API/user" +import { bsConfirm } from "@/components/bs-ui/alertDialog/useConfirm"; +import { captureAndAlertRequestErrorHoc } from "../../../controllers/request"; +import { useContext, useEffect, useRef, useState } from "react"; +import { + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow +} from "../../../components/bs-ui/table"; +import EditUserGroup from "./EditUserGroup"; +import { UserGroup } from "@/types/api/user"; +import { locationContext } from "@/contexts/locationContext"; +import { getUserGroupsProApi } from "@/controllers/API/pro"; + +export default function UserGroups() { + const { t } = useTranslation() + const [userGroups, setUserGroups] = useState([]) + const [userGroup, setUserGroup] = useState(null) + const tempRef = useRef([]) // 搜索功能的数据暂存 + const { appConfig } = useContext(locationContext) + const defaultAdminsRef = useRef([]) + const { delShow, idRef, close, delConfirm } = useDelete(); + + const loadData = async () => { + const res: any = await (appConfig.isPro ? getUserGroupsProApi : getUserGroupsApi)() + defaultAdminsRef.current = await getAdminsApi() + res.records.map(g => g.group_admins = [...defaultAdminsRef.current, ...g.group_admins]) + setUserGroups(res.records) + tempRef.current = res.records + } + + const handleSearch = (e) => { + const word = e.target.value + const newUgs = tempRef.current.filter(ug => ug.group_name.toUpperCase().includes(word.toUpperCase())) + setUserGroups(newUgs) + } + const handleDelete = (userGroup) => { + // bsConfirm({ + // desc: t('system.deleteGroup', { name: userGroup.group_name }), + // okTxt: t('delete'), + // onOk(next) { + // captureAndAlertRequestErrorHoc(delUserGroupApi(userGroup.id).then(res => { + // loadData() + // close(); + // })) + // next() + // } + // }) + captureAndAlertRequestErrorHoc(delUserGroupApi(idRef.current.id).then(res => { + loadData() + close(); + })) + } + + const checkSameName = (name: string) => { + return (userGroups.find(ug => + ug.group_name === name && ug.id !== userGroup.id)) + } + const handleChange = (flag: boolean) => { + flag && loadData() + setUserGroup(null) + } + + useEffect(() => { loadData() }, []) + + if (userGroup) return + + return
+
+

{t('system.userGroupList')}

+
+
+ +
+ +
+ + + + {t('system.groupName')} + {t('system.admins')} + {appConfig.isPro && {t('system.flowControl')}} + {t('system.changeTime')} + {t('operations')} + + + + {userGroups.map((ug: any) => ( + + {ug.group_name} + {(ug.admin_user || ug.group_admins).map(el => el.user_name).join(',')} + {appConfig.isPro && {ug.group_limit ? t('system.limit') : t('system.unlimited')}} + {ug.update_time.replace('T', ' ')} + + + + + + ))} + + + {!userGroups.length && + {t('build.empty')} + } + +
+
+
+ +
+ + +
+

{t('prompt')}

+

删除后数据无法恢复,请确认!

+
+ + +
+
+
+
+} + +const useDelete = () => { + const [delShow, setDelShow] = useState(false) + const idRef = useRef(null) + + return { + delShow, + idRef, + close: () => { + setDelShow(false) + }, + delConfirm: (id) => { + idRef.current = id + setDelShow(true) + } + } +} \ No newline at end of file diff --git a/src/pages/SystemPage/components/UserRoleItem.tsx b/src/pages/SystemPage/components/UserRoleItem.tsx new file mode 100644 index 0000000..67646eb --- /dev/null +++ b/src/pages/SystemPage/components/UserRoleItem.tsx @@ -0,0 +1,89 @@ +// import { DelIcon } from "@/components/bs-icons"; +import { Button } from "@/components/bs-ui/button"; +import MultiSelect from "@/components/bs-ui/select/multi"; +import { getRolesByGroupApi, getUserGroupsApi } from "@/controllers/API/user"; +import { useEffect, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; +import SelectSearch from "@/components/bs-ui/select/select" +import { DelIcon } from "@/components/bs-icons/del"; + +export default function UserRoleItem({ showDel, groupId, selectedRoles, onDelete, onChange }: + { showDel: boolean, groupId: null | string, selectedRoles: any[], onDelete: any, onChange: any }) { + const { t } = useTranslation() + + // 用户组 + const [groups, setGroups] = useState([]) + const groupsRef = useRef([]) + const [userGroupSelected, setUserGroupSelected] = useState(groupId ? [groupId] : []) + const loadGroups = () => { + getUserGroupsApi().then((res: any) => { + const groups = res.records.map((ug) => { + return { + label: ug.group_name, + value: ug.id.toString() + } + }) + setGroups(groups) + groupsRef.current = groups + }) + } + useEffect(() => { + // 用户组option列表 + loadGroups() + }, []) + + const handleSelectGroup = (value) => { //单选之后value要改成数组传出去 + onChange([value], []) + setUserGroupSelected([value]); + setSelected([]) + } + const handleSearch = (e) => { + const keyword = e.target.value + const newGroups = groupsRef.current.filter(g => g.label.toUpperCase().includes(keyword.toUpperCase()) + || g.value === userGroupSelected[0]) + setGroups(newGroups) + } + + // 角色 + const [roles, setRoles] = useState([]) + const [selected, setSelected] = useState(selectedRoles) + useEffect(() => { + // setSelected([]) + // 用户组option列表 + getRolesByGroupApi('', userGroupSelected).then((res: any) => { + const roleOptions = res.map(role => { + return { + label: role.role_name, + value: role.id.toString() + } + }) + setRoles(roleOptions); + }) + }, [userGroupSelected]) + + const handleSelectRole = (values) => { + onChange(userGroupSelected, values) + setSelected(values) + } + + return
+ setGroups(groupsRef.current)} + onValueChange={handleSelectGroup} + onChange={handleSearch} + /> + + + {showDel && } +
+}; diff --git a/src/pages/SystemPage/components/UserRoleModal.tsx b/src/pages/SystemPage/components/UserRoleModal.tsx index 74f6236..167e324 100644 --- a/src/pages/SystemPage/components/UserRoleModal.tsx +++ b/src/pages/SystemPage/components/UserRoleModal.tsx @@ -1,101 +1,79 @@ -import { Listbox } from "@headlessui/react" -import { CheckIcon, ChevronsUpDown } from "lucide-react" +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/bs-ui/dialog" +import { useToast } from "@/components/bs-ui/toast/use-toast" +import { PlusIcon } from "@radix-ui/react-icons" import { useEffect, useState } from "react" import { useTranslation } from "react-i18next" -import { Button } from "../../../components/ui/button" -import { getRolesApi, getUserRoles, updateUserRoles } from "../../../controllers/API/user" -import { ROLE } from "../../../types/api/user" -import { captureAndAlertRequestErrorHoc } from "../../../controllers/request" +import { Button } from "../../../components/bs-ui/button" +import UserRoleItem from "./UserRoleItem" +import { updateUserGroups, updateUserRoles } from "@/controllers/API/user" +import { captureAndAlertRequestErrorHoc } from "@/controllers/request" +import { generateUUID } from "@/components/bs-ui/utils" -export default function UserRoleModal({ id, onClose, onChange }) { +export default function UserRoleModal({ user, onClose, onChange }) { const { t } = useTranslation() - const [roles, setRoles] = useState([]) - const [selected, setSelected] = useState([]) - const [error, setError] = useState(false) - + // 初始化数据 + const [roleItems, setRoleItems] = useState([]) useEffect(() => { - if (!id) return - getRolesApi().then(data => { - const roleOptions = data.filter(role => role.id !== 1) - .map(role => ({ ...role, role_id: role.id })) - setRoles(roleOptions); + if (user) { + const { groups, roles } = user + const items = groups.map(item => { - getUserRoles(id).then(userRoles => { - // 默认设置 普通用户 - if (!userRoles.find(role => role.role_id === 2)) { - const roleByroles = roleOptions.find(role => role.role_id === 2) - userRoles.unshift({ ...roleByroles }) + return { + key: generateUUID(8), + groupId: item.id, + roles: roles.filter(role => role.group_id === item.id) + .map(el => el.id.toString()) } - setSelected(userRoles) }) - }) - setError(false) - }, [id]) + setRoleItems(items) + } + }, [user]) - function compareDepartments(a, b) { - return a.role_id === b.role_id + const handleChangeRoleItems = (index, groupId, roles) => { + setRoleItems(items => items.map((el, i) => { + return (index !== i) ? el : { groupId: groupId[0], roles } + })) } + const { message } = useToast() const handleSave = async () => { - if (!selected.length) return setError(true) - const res = await captureAndAlertRequestErrorHoc(updateUserRoles(id, selected.map(item => item.role_id))) - console.log('res :>> ', res); + const map = {} + const items = roleItems.filter(item => { + if (map[item.groupId] || !item.groupId) return false + map[item.groupId] = true + return true + }) + if (items.some(item => item.roles.length === 0)) return message({ title: t('prompt'), variant: 'warning', description: t('system.selectRole') }) + if (items.length === 0) return message({ title: t('prompt'), variant: 'warning', description: t('system.selectGroup') }) + captureAndAlertRequestErrorHoc(updateUserRoles(user.user_id, items.reduce((res, item) => [...res, ...item.roles], []))) + captureAndAlertRequestErrorHoc(updateUserGroups(user.user_id, items.map(item => item.groupId))) onChange() } - return -
-

{t('system.roleSelect')}

- -
- -
{selected.map(el => el.role_name).join(';')}
- - - -
- - - {roles.map((role, personIdx) => ( - - `relative select-none py-2 pl-10 pr-4 - ${active - ? 'bg-[#404040] text-[#fff]' - : 'text-[#fff] bg-[#333]'} - ${role.role_id === 2 - ? 'cursor-not-allowed text-gray-300' - : "cursor-default"}` - } - value={role} - disabled={role.role_id === 2} - > - {({ selected }) => ( - <> - - {role.role_name} - - {selected ? ( - - - ) : null} - - )} - - ))} - -
-
-
- - + return { !b && setRoleItems([]); onClose(b) }}> + + + {t('system.roleSelect')} + +
+ { + roleItems.map((item, i) => handleChangeRoleItems(i, g, r)} + showDel={roleItems.length > 1} + onDelete={() => setRoleItems(roleItems.filter((el, index) => index !== i))} + />) + }
-
-
-}; + + + + + + + +}; \ No newline at end of file diff --git a/src/pages/SystemPage/components/Users copy.tsx b/src/pages/SystemPage/components/Users copy.tsx new file mode 100644 index 0000000..8b6d6d9 --- /dev/null +++ b/src/pages/SystemPage/components/Users copy.tsx @@ -0,0 +1,129 @@ +import { useContext, useEffect, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Button } from "../../../components/ui/button"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow +} from "../../../components/ui/table"; +import { userContext } from "../../../contexts/userContext"; +import { disableUserApi, getUsersApi } from "../../../controllers/API/user"; +import UserRoleModal from "./UserRoleModal"; +import { captureAndAlertRequestErrorHoc } from "../../../controllers/request"; +import { useTable } from "../../../util/hook"; +import { Input } from "../../../components/ui/input"; +import PaginationComponent from "../../../components/PaginationComponent"; +import { Search } from "lucide-react"; + +export default function Users(params) { + const { user } = useContext(userContext); + const { t } = useTranslation() + + const { page, pageSize, data: users, total, loading, setPage, search, reload } = useTable({},(param) => + getUsersApi(param.keyword, param.page, param.pageSize) + ) + + // 禁用 + const { delShow, idRef, close, delConfim } = useDelete() + const handleDelete = () => { + captureAndAlertRequestErrorHoc(disableUserApi(idRef.current.user_id, 1).then(res => { + reload() + close() + })) + } + const handleEnableUser = (user) => { + captureAndAlertRequestErrorHoc(disableUserApi(user.user_id, 0).then(res => { + reload() + close() + })) + } + + // 编辑 + const [roleOpenId, setRoleOpenId] = useState(null) + const handleRoleChange = () => { + setRoleOpenId(null) + reload() + } + + return <> +
+
+ search(e.target.value)}> + +
+
+ + {/* 用户列表. */} + + + {t('system.username')} + {t('createTime')} + {t('operations')} + + + + {users.map((el) => ( + + {el.user_name} + {/* {el.role} */} + {el.update_time.replace('T', ' ')} + + {user.user_id === el.user_id ? {t('edit')} : + setRoleOpenId(el.user_id)} className="underline ml-4">{t('edit')}} + { + el.delete === 1 ? handleEnableUser(el)} className="underline ml-4">{t('enable')} : + user.user_id === el.user_id ? {t('disable')} : + delConfim(el)} className="underline ml-4 text-red-500">{t('disable')} + } + + + ))} + +
+ {/* 分页 */} + {/* */} +
+ setPage(newPage)} + /> +
+ + {/* 禁用确认 */} + +
+

{t('prompt')}!

+

{t('system.confirmDisable')}

+
+ + +
+
+
+ + setRoleOpenId(null)} onChange={handleRoleChange}> + +}; + + +const useDelete = () => { + const [delShow, setDelShow] = useState(false) + const idRef = useRef(null) + + return { + delShow, + idRef, + close: () => { + setDelShow(false) + }, + delConfim: (id) => { + idRef.current = id + setDelShow(true) + } + } +} \ No newline at end of file diff --git a/src/pages/SystemPage/components/Users.tsx b/src/pages/SystemPage/components/Users.tsx index 8b6d6d9..6408a17 100644 --- a/src/pages/SystemPage/components/Users.tsx +++ b/src/pages/SystemPage/components/Users.tsx @@ -1,92 +1,250 @@ -import { useContext, useEffect, useRef, useState } from "react"; +import { FilterIcon } from "@/components/bs-icons/filter"; +import { bsConfirm } from "@/components/bs-ui/alertDialog/useConfirm"; +import { Button } from "@/components/bs-ui/button"; +import { Popover, PopoverContent, PopoverTrigger } from "@/components/bs-ui/popover"; +import FilterUserGroup from "@/components/bs-ui/select/filter"; +import { getRolesApi, getUserGroupsApi } from "@/controllers/API/user"; +import { useContext, useEffect, useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; -import { Button } from "../../../components/ui/button"; +import { SearchInput } from "../../../components/bs-ui/input"; +import AutoPagination from "../../../components/bs-ui/pagination/autoPagination"; import { Table, TableBody, TableCell, + TableFooter, TableHead, TableHeader, TableRow -} from "../../../components/ui/table"; +} from "../../../components/bs-ui/table"; import { userContext } from "../../../contexts/userContext"; import { disableUserApi, getUsersApi } from "../../../controllers/API/user"; -import UserRoleModal from "./UserRoleModal"; import { captureAndAlertRequestErrorHoc } from "../../../controllers/request"; import { useTable } from "../../../util/hook"; -import { Input } from "../../../components/ui/input"; -import PaginationComponent from "../../../components/PaginationComponent"; -import { Search } from "lucide-react"; +import UserRoleModal from "./UserRoleModal"; +import UserPwdModal from "@/pages/LoginPage/UserPwdModal"; +import { PlusIcon } from "@/components/bs-icons"; +import CreateUser from "./CreateUser"; + +function UsersFilter({ options, onChecked, nameKey, placeholder, onFilter }) { + const [open, setOpen] = useState(false) + const [_value, setValue] = useState([]) + const [searchKey, setSearchKey] = useState('') + // 点击 checkbox + const handlerChecked = (id) => { + setValue(val => { + const index = val.indexOf(id) + index === -1 ? val.push(id) : val.splice(index, 1) + return [...val] + }) + // 已选项上浮 + const checked = options.filter(o => _value.includes(o.id)) + const uncheck = options.filter(o => !_value.includes(o.id)) + onChecked([...checked, ...uncheck]) + } + + const filterData = () => { + onFilter(_value) + setOpen(false) + } + // 搜索 + const _options = useMemo(() => { + if (!searchKey) return options + return options.filter(a => a[nameKey].toUpperCase().includes(searchKey.toUpperCase())) + }, [searchKey, options]) + // 重置 + const reset = () => { + setValue([]) + setSearchKey('') + } + + return { setOpen(bln); setSearchKey('') }}> + + {/* @ts-ignore */} + setOpen(!open)} className={_value.length ? 'text-[#ffd025]' : 'text-[#999]'} /> + + + setSearchKey(e.target.value)} + onClearChecked={reset} + onOk={filterData} + /> + + + +} + export default function Users(params) { const { user } = useContext(userContext); const { t } = useTranslation() + const { delShow, idRef, close, delConfirm } = useDelete(); - const { page, pageSize, data: users, total, loading, setPage, search, reload } = useTable({},(param) => - getUsersApi(param.keyword, param.page, param.pageSize) + const { page, pageSize, data: users, total, setPage, search, reload, filterData } = useTable({ pageSize: 20 }, (param) => + getUsersApi({ + ...param, + name: param.keyword + }) ) - // 禁用 - const { delShow, idRef, close, delConfim } = useDelete() - const handleDelete = () => { + // 禁用确认 + const handleDelete = (user) => { + // bsConfirm({ + // title: `${t('prompt')}!`, + // desc: t('system.confirmDisable'), + // okTxt: t('disable'), + // onOk(next) { + // captureAndAlertRequestErrorHoc(disableUserApi(idRef.current.id, 1).then(res => { + // reload() + // })) + // next() + // } + // }) captureAndAlertRequestErrorHoc(disableUserApi(idRef.current.user_id, 1).then(res => { reload() - close() + close(); })) } const handleEnableUser = (user) => { captureAndAlertRequestErrorHoc(disableUserApi(user.user_id, 0).then(res => { reload() - close() })) } // 编辑 - const [roleOpenId, setRoleOpenId] = useState(null) + const [currentUser, setCurrentUser] = useState(null) + const userPwdModalRef = useRef(null) const handleRoleChange = () => { - setRoleOpenId(null) + setCurrentUser(null) reload() } - return <> -
-
- search(e.target.value)}> - -
+ // 获取用户组类型数据 + const [userGroups, setUserGroups] = useState([]) + const getUserGoups = async () => { + const res: any = await getUserGroupsApi() + setUserGroups(res.records) + } + // 获取角色类型数据 + const [roles, setRoles] = useState([]) + const getRoles = async () => { + const res: any = await getRolesApi() + setRoles(res) + } + // 已选项上浮 + const handleGroupChecked = (values) => { + setUserGroups(values) + } + const handleRoleChecked = (values) => { + setRoles(values) + } + + const [openCreate, setOpenCreate] = useState(false) + + useEffect(() => { + getUserGoups() + getRoles() + return () => { setUserGroups([]); setRoles([]) } + }, []) + + const operations = (el) => { + const isSuperAdmin = el.roles.some(role => role.id === 1) + // 禁止编辑admin用户 + if (isSuperAdmin) return
+ + {/* */} + +
- - {/* 用户列表. */} - - - {t('system.username')} - {t('createTime')} - {t('operations')} - - - - {users.map((el) => ( - - {el.user_name} - {/* {el.role} */} - {el.update_time.replace('T', ' ')} - - {user.user_id === el.user_id ? {t('edit')} : - setRoleOpenId(el.user_id)} className="underline ml-4">{t('edit')}} - { - el.delete === 1 ? handleEnableUser(el)} className="underline ml-4">{t('enable')} : - user.user_id === el.user_id ? {t('disable')} : - delConfim(el)} className="underline ml-4 text-red-500">{t('disable')} - } - + + return
+ {/* 编辑 */} + + {/* 重置密码 */} + {(user.role === 'admin' || user.role === 'group_admin') && + } + {/* 禁用 */} + { + el.delete === 1 ? : + + } +
+ } + + return
+
+

{t('system.userList')}

+
+
+ search(e.target.value)}> +
+ {user.role === 'admin' && } +
+
+ {/* 用户列表. */} + + + {t('system.username')} + +
+ {t('system.userGroup')} + filterData({ groupId: ids })} + > +
+
+ +
+ {t('system.role')} + filterData({ roleId: ids })} + > +
+
+ {t('system.changeTime')} + {t('operations')}
- ))} - -
+ + + {users.map((el: any) => ( + + {el.user_name} + {/* {el.role} */} + {(el.groups || []).map(el => el.name).join(',')} + {(el.roles || []).map(el => el.name).join(',')} + {el.update_time.replace('T', ' ')} + {operations(el)} + + ))} + + + {!users.length && + {t('build.empty')} + } + + +
{/* 分页 */} {/* */} -
- +
- {/* 禁用确认 */} + { setOpenCreate(bool); reload() }} onSave={reload} /> + setCurrentUser(null)} onChange={handleRoleChange}> + + -
-

{t('prompt')}!

-

{t('system.confirmDisable')}

-
- - + +

{t('prompt')}

+

确认禁用该用户?

+
+ +
- - setRoleOpenId(null)} onChange={handleRoleChange}> - +
}; - const useDelete = () => { const [delShow, setDelShow] = useState(false) const idRef = useRef(null) @@ -121,7 +279,7 @@ const useDelete = () => { close: () => { setDelShow(false) }, - delConfim: (id) => { + delConfirm: (id) => { idRef.current = id setDelShow(true) } diff --git a/src/pages/SystemPage/index.tsx b/src/pages/SystemPage/index.tsx index 065fe58..1968358 100644 --- a/src/pages/SystemPage/index.tsx +++ b/src/pages/SystemPage/index.tsx @@ -1,4 +1,6 @@ - +import { userContext } from "@/contexts/userContext"; +import { useContext } from "react"; +import { useTranslation } from "react-i18next"; import { Tabs, TabsContent, @@ -7,16 +9,18 @@ import { } from "../../components/ui/tabs"; import Roles from "./components/Roles"; import Config from "./components/Config"; +import Theme from "./theme"; +import UserGroups from "./components/UserGroup"; import Users from "./components/Users"; -import { useTranslation } from "react-i18next"; export default function FileLibPage() { - + const { user } = useContext(userContext); + const { t } = useTranslation() return
- + {/* {t('system.userManagement')} {t('system.roleManagement')} {t('system.systemConfiguration')} @@ -29,7 +33,29 @@ export default function FileLibPage() { + */} + + {t('system.userManagement')} + {user.role === 'admin' && {t('system.userGroupsM')}} + {t('system.roleManagement')} + {user.role === 'admin' && {t('system.systemConfiguration')}} + {/* {user.role === 'admin' && 主题配色} */} + + + + + + + + + + + + + {/* + + */}
}; diff --git a/src/pages/SystemPage/theme/Example.tsx b/src/pages/SystemPage/theme/Example.tsx new file mode 100644 index 0000000..5631683 --- /dev/null +++ b/src/pages/SystemPage/theme/Example.tsx @@ -0,0 +1,185 @@ +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/bs-ui/accordion"; +import { Badge } from "@/components/bs-ui/badge"; +import { Button } from "@/components/bs-ui/button"; +import { Calendar } from "@/components/bs-ui/calendar"; +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/bs-ui/card"; +import { Checkbox } from "@/components/bs-ui/checkBox"; +import { SearchInput, Textarea } from "@/components/bs-ui/input"; +import { Label } from "@/components/bs-ui/label"; +import AutoPagination from "@/components/bs-ui/pagination/autoPagination"; +import { RadioGroup, RadioGroupItem } from "@/components/bs-ui/radio"; +import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/bs-ui/select"; +import { Slider } from "@/components/bs-ui/slider"; +import { Switch } from "@/components/bs-ui/switch"; +import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "@/components/bs-ui/table"; + +const invoices = [ + { + invoice: "INV001", + paymentStatus: "Paid", + totalAmount: "$250.00", + paymentMethod: "Credit Card", + }, + { + invoice: "INV002", + paymentStatus: "Pending", + totalAmount: "$150.00", + paymentMethod: "PayPal", + }, + { + invoice: "INV003", + paymentStatus: "Unpaid", + totalAmount: "$350.00", + paymentMethod: "Bank Transfer", + }, +] + +export default function Example(params) { + + return
+ +
+ + + + + + +
+ +
+ Badge + Badge + Badge + Badge +
+ +
+ +

+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + +
+ + +
+
+ + +
+
+
+ +
+ + A list of your recent invoices. + + + Invoice + Status + Method + Amount + + + + {invoices.map((invoice) => ( + + {invoice.invoice} + {invoice.paymentStatus} + {invoice.paymentMethod} + {invoice.totalAmount} + + ))} + + + + Total + $2,500.00 + + +
+ +
+ +
+ +
+ +
+ + + Create project + Deploy your new project in one-click. + + + 内容 + + + + + + +
+ +
+ + + Is it accessible? + + Yes. It adheres to the WAI-ARIA design pattern. + + + + Is it styled? + + Yes. It comes with default styles that matches the other + components' aesthetic. + + + + Is it animated? + + Yes. It's animated by default, but you can disable it if you prefer. + + + +
+
+}; diff --git a/src/pages/SystemPage/theme/HSLitem.tsx b/src/pages/SystemPage/theme/HSLitem.tsx new file mode 100644 index 0000000..4bce802 --- /dev/null +++ b/src/pages/SystemPage/theme/HSLitem.tsx @@ -0,0 +1,25 @@ +import { Button } from "@/components/bs-ui/button"; +import { Label } from "@/components/bs-ui/label"; +import { useState } from "react"; +import { SketchPicker } from 'react-color'; + +export default function HSLitem({ label, name, value, onChange }) { + const [show, setShow] = useState(false) + + return
+ +
+ + {show &&
+
setShow(false)}>
+ { onChange(name, e.hsl), setShow(false) }} + /> +
} +
+
+}; diff --git a/src/pages/SystemPage/theme/index.tsx b/src/pages/SystemPage/theme/index.tsx new file mode 100644 index 0000000..0a43b67 --- /dev/null +++ b/src/pages/SystemPage/theme/index.tsx @@ -0,0 +1,109 @@ +import { useState } from "react"; +import HSLitem from "./HSLitem"; +import Example from "./Example"; +import { Button } from "@/components/bs-ui/button"; +import { LoadIcon } from "@/components/bs-icons"; +import { ReloadIcon } from "@radix-ui/react-icons"; +import { saveThemeApi } from "@/controllers/API"; + +const defaultTheme = { + '--background': { h: 0, s: 0, l: 1 }, + '--foreground': { h: 222.2, s: 0.474, l: 0.112 }, + '--muted': { h: 210, s: 0.4, l: 0.98 }, + '--muted-foreground': { h: 215.4, s: 0.163, l: 0.469 }, + '--popover': { h: 0, s: 0, l: 1 }, + '--popover-foreground': { h: 222.2, s: 0.474, l: 0.112 }, + '--card': { h: 0, s: 0, l: 1 }, + '--card-foreground': { h: 222.2, s: 0.474, l: 0.112 }, + '--border': { h: 214.3, s: 0.218, l: 0.914 }, + '--input': { h: 223, s: 0.48, l: 0.44 }, + '--primary': { h: 220, s: 0.98, l: 0.45 }, + '--primary-foreground': { h: 210, s: 0.4, l: 0.98 }, + '--secondary': { h: 210, s: 0.4, l: 0.961 }, + '--secondary-foreground': { h: 222.2, s: 0.474, l: 0.112 }, + '--accent': { h: 210, s: 0.3, l: 0.961 }, + '--accent-foreground': { h: 222.2, s: 0.474, l: 0.112 }, + '--destructive': { h: 0, s: 1, l: 0.5 }, + '--destructive-foreground': { h: 210, s: 0.4, l: 0.98 }, + '--black-button': { h: 0, s: 0, l: 0.07 }, +}; + +const themeKeys = { + "--primary": "主题色", + "--primary-foreground": "主题前景色", + "--background": "背景色", + "--foreground": "前景色", + "--muted": "柔和背景色", + "--muted-foreground": "柔和前景色", + "--card": "卡片背景色", + "--card-foreground": "卡片前景色", + "--popover": "弹出框背景色", + "--popover-foreground": "弹出框前景色", + "--border": "边框色", + "--input": "输入框边框色", + "--secondary": "次要按钮背景色", + "--secondary-foreground": "次要按钮前景色", + "--accent": "强调色", + "--accent-foreground": "强调前景色", + "--destructive": "警告按钮背景色", + "--destructive-foreground": "警告按钮前景色", + "--ring": "聚焦边框色", + "--radius": "圆角半径", + "--warning": "警告色", + "--warning-foreground": "警告前景色", + '--black-button': '黑按钮', +}; + +export default function Theme() { + const [theme, setTheme] = useState(Object.keys(window.ThemeStyle.comp).length ? window.ThemeStyle.comp : { ...defaultTheme }); + + const applyTheme = (theme) => { + Object.keys(theme).forEach(key => { + document.documentElement.style.setProperty(key, handleHSLtoStr(theme[key])); + }); + setTheme(theme); + window.ThemeStyle = { comp: theme } + saveThemeApi(JSON.stringify({ comp: theme })) + }; + + // hsl -> '220 98% 95%' + const handleHSLtoStr = (hsl) => { + return `${hsl.h} ${hsl.s * 100}% ${hsl.l * 100}%` + } + + const handleHSLChange = (name, hsl) => { + const newTheme = { + ...theme, + [name]: hsl, + }; + setTheme(newTheme); + document.documentElement.style.setProperty(name, handleHSLtoStr(hsl)); + // save + window.ThemeStyle = { comp: newTheme } + saveThemeApi(JSON.stringify({ comp: newTheme })) + }; + + + return
+
+

+ 颜色配置 + +

+
+ { + Object.keys(theme).map(key => { + return + }) + } +
+
+
+

组件预览

+
+ {/* 组件列表 */} + +
+
+
+}; diff --git a/src/routes.tsx b/src/routes.tsx index 41844c8..6c6732b 100755 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -5,11 +5,15 @@ import FileLibPage from "./pages/FileLibPage"; import FilesPage from "./pages/FileLibPage/files"; // import FilesPage from "./pages/Knowledge/knowledge"; import FlowPage from "./pages/FlowPage"; +import LogPage from "./pages/LogPage"; +import { ResetPwdPage } from "./pages/LoginPage/resetPwd"; import ModelPage from "./pages/ModelPage"; import Doc from "./pages/ModelPage/doc"; +import Page403 from "./pages/Page403"; import Report from "./pages/Report"; import SkillChatPage from "./pages/ChatAppPage"; import ChatShare from "./pages/ChatAppPage/chatShare"; +import ChatAssitantShare from "./pages/ChatAppPage/chatAssitantShare"; import SkillAssisPage from "./pages/SkillPage/tabAssistant"; import EditAssistantPage from "./pages/SkillPage/editAssistant"; import SkillsPage from "./pages/SkillPage/tabSkills"; @@ -23,6 +27,8 @@ import Templates from "./pages/SkillPage/temps"; import DiffFlowPage from "./pages/DiffFlowPage"; import { ErrorBoundary } from "react-error-boundary"; import CrashErrorComponent from "./components/CrashErrorComponent"; +import EvaluatingPage from "./pages/EvaluationPage"; +import EvaluatingCreate from "./pages/EvaluationPage/EvaluationCreate"; // react 与 react router dom版本不匹配 // const FileLibPage = lazy(() => import(/* webpackChunkName: "FileLibPage" */ "./pages/FileLibPage")); @@ -68,13 +74,16 @@ const router = createBrowserRouter([ { path: "build/temps", element: }, { path: "model", element: }, { path: "sys", element: }, + { path: "log", element: }, + { path: "evaluation", element: }, + { path: "evaluation/create", element: }, ], }, { path: "model/doc", element: }, { path: "/flow/:id/", children: [ - { path: "", element: } + { path: "", element: } ] }, { @@ -86,9 +95,12 @@ const router = createBrowserRouter([ // 独立会话页 { path: "/chat", element: }, { path: "/chat/:id/", element: }, + { path: "/chat/assistant/:id/", element: }, { path: "/report/:id/", element: }, { path: "/diff/:id/:vid/:cid", element: }, + { path: "/reset", element: }, // { path: "/test", element: }, + { path: "/403", element: }, { path: "*", element: } ]); diff --git a/src/routesM.tsx b/src/routesM.tsx index 7e09070..9ded233 100755 --- a/src/routesM.tsx +++ b/src/routesM.tsx @@ -8,6 +8,7 @@ import Doc from "./pages/ModelPage/doc"; import Report from "./pages/Report"; import SkillChatPage from "./pages/ChatAppPage"; import ChatShare from "./pages/ChatAppPage/mobile/chatShareM"; +import ChatAssitantShare from "./pages/ChatAppPage/mobile/chatAssitantShare"; import SkillPage from "./pages/SkillPage"; import L2Edit from "./pages/SkillPage/l2Edit"; import SystemPage from "./pages/SystemPage"; @@ -44,6 +45,7 @@ const router = createBrowserRouter([ // 独立会话页 { path: "/chat", element: }, { path: "/chat/:id/", element: }, + { path: "/chat/assistant/:id/", element: }, { path: "/report/:id/", element: }, // { path: "/test", element: }, { path: "*", element: } diff --git a/src/store/assistantStore.tsx b/src/store/assistantStore.tsx index 802ba30..dc4ddd0 100644 --- a/src/store/assistantStore.tsx +++ b/src/store/assistantStore.tsx @@ -13,7 +13,7 @@ type State = { type Actions = { dispatchAssistant: (action: Action, assistantState: Partial) => void, - loadAssistantState: (id: string) => Promise + loadAssistantState: (id: string, version: string) => Promise saveAfter: () => void destroy: () => void } @@ -58,8 +58,8 @@ export const useAssistantStore = create((set) => ({ assistantState: { ...assistantTemp }, dispatchAssistant: (action: Action, data: Partial) => set((state) => assistantReducer(state, action, data)), // 加载助手状态 - loadAssistantState: (id) => { - return getAssistantDetailApi(id).then(data => { + loadAssistantState: (id, version) => { + return getAssistantDetailApi(id, version).then(data => { set({ assistantState: { ...data, diff --git a/src/style/zk.scss b/src/style/zk.scss index 2ba65db..5661490 100644 --- a/src/style/zk.scss +++ b/src/style/zk.scss @@ -1,17 +1,17 @@ -.nav-link1,.nav-link2,.nav-link3,.nav-link4,.nav-link5 { +.nav-link1,.nav-link2,.nav-link3,.nav-link4,.nav-link5,.nav-link6,.nav-link7 { background-image: none; text-decoration: none; color: white; display: flex; justify-content: center; align-items: flex-end; - margin-bottom: 40px; + margin-bottom: 20px; & span { font-weight: 400; font-size: 12px; color: #666666; - margin-bottom: -3px; + // margin-bottom: -3px; } } .nav-link1 { @@ -79,6 +79,32 @@ color: #FFCF33; } } + .nav-link6 { + background-image: url('../assets/nav/icon6.png'); + background-size: 100%; + background-repeat: no-repeat; + } + .nav-link6.active { + background-image: url('../assets/nav/icon6-active.png'); + background-size: 100%; + background-repeat: no-repeat; + & span { + color: #FFCF33; + } + } + .nav-link7 { + background-image: url('../assets/nav/icon7.png'); + background-size: 100%; + background-repeat: no-repeat; + } + .nav-link7.active { + background-image: url('../assets/nav/icon7-active.png'); + background-size: 100%; + background-repeat: no-repeat; + & span { + color: #FFCF33; + } + } .xinDuiHua-box{ background-image: url('../assets/chat/duihua-bg.png'); background-size: 30px 100%; @@ -132,7 +158,7 @@ background-color: rgba(255, 225, 128, 0.1); >div:nth-of-type(1){ >div{ - >p{ + >p:nth-of-type(1){ color: #E5BB2E!important; } } @@ -2481,6 +2507,9 @@ .border-radius-7{ border-radius: 7px; } + .border-radius-35{ + border-radius: 35px!important; + } .skillSettings{ width: 542px; margin: 0 auto; @@ -3026,7 +3055,7 @@ } } */ .zhanghaoTab{ - width: 203px; + width: 300px; height: 27px; background: #333333!important; border-radius: 7px; @@ -3402,7 +3431,7 @@ } } .selectNpcFlexbox{ - height: 127px; + min-height: 127px; padding-bottom: 14px; display: block; /* padding: 14px; */ @@ -3806,6 +3835,17 @@ height: 20px!important; background: #4D4D4D!important; } + .xiala .data-\[state\=checked\]\:bg-primary[data-state=checked]{ + width: 15px!important; + height: 15px!important; + background: #ffd025!important; + } + .xiala button{ + width: 15px!important; + height: 15px!important; + border: 1px solid #ffd025!important; + } + .build-tab{ display: flex; @@ -4214,4 +4254,7 @@ } } } + } + .bg-reset{ + box-shadow: 0px 3px 14px 0px rgba(255,255,255,0.2)!important; } \ No newline at end of file diff --git a/src/types/api/user.ts b/src/types/api/user.ts index a448550..7992eb9 100644 --- a/src/types/api/user.ts +++ b/src/types/api/user.ts @@ -19,3 +19,13 @@ export type ROLE = { role_name: string update_time: string } + +export type UserGroup = { + id: number + group_name: string + adminUser: string + group_admins: any[] + createTime: string + updateTime: string + groupLimit?: number +} \ No newline at end of file diff --git a/src/types/assistant/index.tsx b/src/types/assistant/index.tsx index 64f3cae..d8e614b 100644 --- a/src/types/assistant/index.tsx +++ b/src/types/assistant/index.tsx @@ -27,6 +27,8 @@ export interface AssistantDetail { create_time: string; /** 更新时间 */ update_time: string; + /** 内容安全审查对象 */ + // content_security: object; /** 助手的工具ID列表, 空列表则清空绑定的工具,为None则不更新 */ tool_list?: AssistantTool[]; /** 助手的技能ID列表,为None则不更新 */ diff --git a/src/util/hook.ts b/src/util/hook.ts index d7ca84c..7d13f96 100644 --- a/src/util/hook.ts +++ b/src/util/hook.ts @@ -57,7 +57,7 @@ export function useCopyText() { // 表格通用逻辑(分页展示、表格数据、关键词检索) export function useTable(param, apiFun) { - + const cancelLoadingWhenReload = param.cancelLoadingWhenReload || false; const [page, setPage] = useState({ page: 1, pageSize: param.pageSize || 20, @@ -71,7 +71,7 @@ export function useTable(param, apiFun) { const requestIdRef = useRef(0); // 控制请求响应顺序 const loadData = () => { - // setLoading(true); + !cancelLoadingWhenReload && setLoading(true); const requestId = ++requestIdRef.current apiFun({ ...page, ...paramRef.current }).then(res => { if (requestId !== requestIdRef.current) return @@ -79,7 +79,7 @@ export function useTable(param, apiFun) { // res.data.unshift({type:0}) setData(res.data); setTotal(res.total); - // setLoading(false); + setLoading(false); }).catch(() => { // setLoading(false); }) diff --git a/src/util/utils.ts b/src/util/utils.ts index 0a417d5..3be2240 100644 --- a/src/util/utils.ts +++ b/src/util/utils.ts @@ -77,6 +77,37 @@ export function formatMilliseconds(ms: number, format: string): string { return formattedString; } +// Date转换为目标格式 +export function formatDate(date: Date, format: string): string { + const addZero = (num) => num < 10 ? `0${num}` : `${num}` + const replacements = { + 'yyyy': date.getFullYear(), + 'MM': addZero(date.getMonth() + 1), + 'dd': addZero(date.getDate()), + 'HH': addZero(date.getHours()), + 'mm': addZero(date.getMinutes()), + 'ss': addZero(date.getSeconds()) + } + return format.replace(/yyyy|MM|dd|HH|mm|ss/g, (match) => replacements[match]) +} + +// param time: yyyy-mm-ddTxxxx +export function formatStrTime(time: string, notSameDayFormat: string): string { + if (!time) return '' + const date1 = new Date(time) + const date2 = new Date() + return date1.getFullYear() === date2.getFullYear() && + date1.getMonth() === date2.getMonth() && + date1.getDate() === date2.getDate() ? formatDate(date1, 'HH:mm') : formatDate(date1, notSameDayFormat) + // const newTime = time.substring(0, time.indexOf('T')).split('-') + // const arrayTime = newTime.map(t => Number(t)) + // const [year, month, day] = [date.getFullYear(), date.getMonth() + 1, date.getDay()] + // if(year === arrayTime[0] && month === arrayTime[1] && day === arrayTime[2]) { + // return time.substring(time.indexOf('T') + 1, time.length - 3) + // } + // return `${newTime[1]}月${newTime[2]}日` +} + export function toTitleCase(str: string | undefined): string { if (!str) return ""; let result = str @@ -113,4 +144,4 @@ export function getFieldTitle( : template[templateField].name ? toTitleCase(template[templateField].name!) : toTitleCase(templateField); -} +} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index 3ae5fe7..d5e3b19 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,14 +1,15 @@ import react from "@vitejs/plugin-react-swc"; import { visualizer } from "rollup-plugin-visualizer"; import { defineConfig } from "vite"; +import { createHtmlPlugin } from 'vite-plugin-html'; import { viteStaticCopy } from 'vite-plugin-static-copy'; import svgr from "vite-plugin-svgr"; const apiRoutes = ["^/api/", "/health"]; import path from "path"; // Use environment variable to determine the target. // const target = process.env.VITE_PROXY_TARGET || "http://localhost:7860"; - const target = process.env.VITE_PROXY_TARGET || "http://npcall.ai:3003"; -// const target = process.env.VITE_PROXY_TARGET || "http://172.30.40.241:7866"; +// const target = process.env.VITE_PROXY_TARGET || "http://npcall.ai:3101"; + const target = process.env.VITE_PROXY_TARGET || "http://dev.npcall.ai:3201"; const proxyTargets = apiRoutes.reduce((proxyObj, route) => { proxyObj[route] = { @@ -27,8 +28,11 @@ const proxyTargets = apiRoutes.reduce((proxyObj, route) => { return proxyObj; }, {}); +const app_env = { BASE_URL: '' } + export default defineConfig(() => { return { + base: app_env.BASE_URL || '/', build: { outDir: "build", rollupOptions: { @@ -50,6 +54,14 @@ export default defineConfig(() => { plugins: [ react(), svgr(), + createHtmlPlugin({ + minify: true, + inject: { + data: { + aceScriptSrc: ``, + }, + }, + }), viteStaticCopy({ targets: [ { @@ -73,6 +85,9 @@ export default defineConfig(() => { // open: true, // }) ], + define: { + __APP_ENV__: JSON.stringify(app_env) + }, server: { host: '0.0.0.0', port: 3001,