Browse Source

词云列表-部门-上传-图片-生成

master
談蓝色 10 months ago
parent
commit
81058b27ef
  1. 26
      frontend/src/App.jsx
  2. 3
      frontend/src/components/Modals/ManageWorkspace/Documents/Directory/index.jsx
  3. 63
      frontend/src/components/Modals/ManageWorkspace/Documents/UploadFile/index.jsx
  4. 3
      frontend/src/components/Modals/ManageWorkspace/Documents/WorkspaceDirectory/WorkspaceFileRow/index.jsx
  5. 5
      frontend/src/components/Modals/ManageWorkspace/Documents/WorkspaceDirectory/index.jsx
  6. 10
      frontend/src/components/Modals/ManageWorkspace/Documents/index.jsx
  7. 4
      frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx
  8. 3
      frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/PromptReply/index.jsx
  9. 2
      frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/index.jsx
  10. 29
      frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/SlashPresets/AddPresetModal.jsx
  11. 32
      frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/SlashPresets/EditPresetModal.jsx
  12. 45
      frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/index.jsx
  13. 34
      frontend/src/pages/Admin/Users/NewUserModal/index.jsx
  14. 18
      frontend/src/pages/Admin/Users/UserRow/EditUserModal/index.jsx
  15. 9
      frontend/src/pages/Admin/Users/UserRow/index.jsx
  16. 8
      frontend/src/pages/Admin/Users/index.jsx
  17. 2
      frontend/src/pages/Admin/Workspaces/WorkspaceRow/index.jsx
  18. 5
      frontend/src/pages/DataAnalysis/DataAnalysis.css
  19. BIN
      frontend/src/pages/DataAnalysis/img/1.png
  20. BIN
      frontend/src/pages/DataAnalysis/img/10.png
  21. BIN
      frontend/src/pages/DataAnalysis/img/11.png
  22. BIN
      frontend/src/pages/DataAnalysis/img/12.png
  23. BIN
      frontend/src/pages/DataAnalysis/img/13.png
  24. BIN
      frontend/src/pages/DataAnalysis/img/14.png
  25. BIN
      frontend/src/pages/DataAnalysis/img/2.png
  26. BIN
      frontend/src/pages/DataAnalysis/img/3.png
  27. BIN
      frontend/src/pages/DataAnalysis/img/4.png
  28. BIN
      frontend/src/pages/DataAnalysis/img/5.png
  29. BIN
      frontend/src/pages/DataAnalysis/img/6.png
  30. BIN
      frontend/src/pages/DataAnalysis/img/7.png
  31. BIN
      frontend/src/pages/DataAnalysis/img/8.png
  32. BIN
      frontend/src/pages/DataAnalysis/img/9.png
  33. 45
      frontend/src/pages/DataAnalysis/index.jsx
  34. 18
      frontend/src/pages/Home/index.jsx
  35. 5
      frontend/src/pages/ReportGeneration/ReportGeneration.css
  36. 44
      frontend/src/pages/ReportGeneration/index.jsx
  37. 5
      frontend/src/pages/Tendency/Tendency.css
  38. 33
      frontend/src/pages/Tendency/index.jsx
  39. 4
      frontend/src/utils/constants.js
  40. 15
      frontend/src/utils/paths.js
  41. 5
      server/models/slashCommandsPresets.js
  42. 2
      server/utils/chats/commands/reset.js

26
frontend/src/App.jsx

@ -24,7 +24,12 @@ const PolicyLibrary = lazy(() => import("@/pages/PolicyLibrary")); // 政策库
const DataAnalysis = lazy(() => import("@/pages/DataAnalysis")); // const DataAnalysis = lazy(() => import("@/pages/DataAnalysis")); //
const Tendency = lazy(() => import("@/pages/Tendency")); // const Tendency = lazy(() => import("@/pages/Tendency")); //
const Yuqingfenxi = lazy(() => import("@/pages/Yuqingfenxi")); // const Yuqingfenxi = lazy(() => import("@/pages/Yuqingfenxi")); //
const Economics = lazy(() => import("@/pages/Economics")); //
const Talents = lazy(() => import("@/pages/Talents")); //
const Industry = lazy(() => import("@/pages/Industry")); //
const TrendPrediction = lazy(() => import("@/pages/TrendPrediction")); //
const ReportGeneration = lazy(() => import("@/pages/ReportGeneration")); // const ReportGeneration = lazy(() => import("@/pages/ReportGeneration")); //
const Report = lazy(() => import("@/pages/Report")); // 1
const InvitePage = lazy(() => import("@/pages/Invite")); const InvitePage = lazy(() => import("@/pages/Invite"));
const WorkspaceChat = lazy(() => import("@/pages/WorkspaceChat")); const WorkspaceChat = lazy(() => import("@/pages/WorkspaceChat"));
@ -110,6 +115,22 @@ export default function App() {
path="/home/Yuqingfenxi" path="/home/Yuqingfenxi"
element={<ManagerRoute Component={Yuqingfenxi} />} element={<ManagerRoute Component={Yuqingfenxi} />}
/> />
<Route
path="/home/TrendPrediction"
element={<ManagerRoute Component={TrendPrediction} />}
/>
<Route
path="/home/Economics"
element={<ManagerRoute Component={Economics} />}
/>
<Route
path="/home/Talents"
element={<ManagerRoute Component={Talents} />}
/>
<Route
path="/home/Industry"
element={<ManagerRoute Component={Industry} />}
/>
<Route <Route
path="/home/DataAnalysis" path="/home/DataAnalysis"
element={<ManagerRoute Component={DataAnalysis} />} element={<ManagerRoute Component={DataAnalysis} />}
@ -118,7 +139,10 @@ export default function App() {
path="/home/ReportGeneration" path="/home/ReportGeneration"
element={<ManagerRoute Component={ReportGeneration} />} element={<ManagerRoute Component={ReportGeneration} />}
/> />
<Route
path="/home/Report"
element={<ManagerRoute Component={Report} />}
/>
<Route path="/login" element={<Login />} /> <Route path="/login" element={<Login />} />
<Route <Route
path="/sso/simple" path="/sso/simple"

3
frontend/src/components/Modals/ManageWorkspace/Documents/Directory/index.jsx

@ -178,8 +178,7 @@ function Directory({
setSearchTerm(searchValue); setSearchTerm(searchValue);
}, 500); }, 500);
const filteredFiles = filterFileSearchResults(files, searchTerm);
console.log(333,filteredFiles);
const filteredFiles = filterFileSearchResults(files, searchTerm)
const handleContextMenu = (event) => { const handleContextMenu = (event) => {
event.preventDefault(); event.preventDefault();

63
frontend/src/components/Modals/ManageWorkspace/Documents/UploadFile/index.jsx

@ -80,7 +80,7 @@ export default function UploadFile({
return ( return (
<div> <div>
<div <div
// 560px
// 560px
className={`w-[100%] border-dashed border-[1px] border-theme-modal-border light:border-[#686C6F] rounded-2xl bg-theme-bg-primary transition-colors duration-300 p-3 ${ready className={`w-[100%] border-dashed border-[1px] border-theme-modal-border light:border-[#686C6F] rounded-2xl bg-theme-bg-primary transition-colors duration-300 p-3 ${ready
? " light:bg-transparent cursor-pointer hover:bg-theme-bg-secondary light:hover:bg-[#E0F2FE]" ? " light:bg-transparent cursor-pointer hover:bg-theme-bg-secondary light:hover:bg-[#E0F2FE]"
: "cursor-not-allowed" : "cursor-not-allowed"
@ -92,42 +92,43 @@ export default function UploadFile({
<div className="flex flex-col items-center justify-center h-full"> <div className="flex flex-col items-center justify-center h-full">
<CloudArrowUp className="w-8 h-8 text-white/80 light:invert" /> <CloudArrowUp className="w-8 h-8 text-white/80 light:invert" />
<div className="text-white text-opacity-80 text-sm font-semibold py-1"> <div className="text-white text-opacity-80 text-sm font-semibold py-1">
Document Processor Unavailable
文档处理器不可用
</div> </div>
<div className="text-white text-opacity-60 text-xs font-medium py-1 px-20 text-center"> <div className="text-white text-opacity-60 text-xs font-medium py-1 px-20 text-center">
We can't upload your files right now because the document
processor is offline. Please try again later.
我们现在不能上传你的文件因为文件
处理器脱机请稍后再试
</div> </div>
</div> </div>
) : files.length === 0 ? (
<div className="flex flex-col items-center justify-center">
<CloudArrowUp className="w-8 h-8 text-white/80 light:invert" />
<div className="text-white text-opacity-80 text-sm font-semibold py-1">
单击上传或拖放
)
: files.length === 0 ? (
<div className="flex flex-col items-center justify-center">
<CloudArrowUp className="w-8 h-8 text-white/80 light:invert" />
<div className="text-white text-opacity-80 text-sm font-semibold py-1">
单击上传或拖放
</div>
<div className="text-white text-opacity-60 text-xs font-medium py-1">
支持文本文件csv电子表格音频文件和更多
</div>
</div> </div>
<div className="text-white text-opacity-60 text-xs font-medium py-1">
支持文本文件csv电子表格音频文件和更多
) : (
<div className="grid grid-cols-2 gap-2 overflow-auto max-h-[180px] p-1 overflow-y-scroll no-scroll">
{files.map((file) => (
<FileUploadProgress
key={file.uid}
file={file.file}
uuid={file.uid}
setFiles={setFiles}
slug={workspace.slug}
rejected={file?.rejected}
reason={file?.reason}
onUploadSuccess={handleUploadSuccess}
onUploadError={handleUploadError}
setLoading={setLoading}
setLoadingMessage={setLoadingMessage}
/>
))}
</div> </div>
</div>
) : (
<div className="grid grid-cols-2 gap-2 overflow-auto max-h-[180px] p-1 overflow-y-scroll no-scroll">
{files.map((file) => (
<FileUploadProgress
key={file.uid}
file={file.file}
uuid={file.uid}
setFiles={setFiles}
slug={workspace.slug}
rejected={file?.rejected}
reason={file?.reason}
onUploadSuccess={handleUploadSuccess}
onUploadError={handleUploadError}
setLoading={setLoading}
setLoadingMessage={setLoadingMessage}
/>
))}
</div>
)}
)}
</div> </div>
<div className="text-center text-white text-opacity-50 text-xs font-medium w-[560px] py-2"> <div className="text-center text-white text-opacity-50 text-xs font-medium w-[560px] py-2">
或者提交一个链接 或者提交一个链接

3
frontend/src/components/Modals/ManageWorkspace/Documents/WorkspaceDirectory/WorkspaceFileRow/index.jsx

@ -31,7 +31,8 @@ export default function WorkspaceFileRow({
setLoadingMessage(`从文件分析区中删除文件中`); setLoadingMessage(`从文件分析区中删除文件中`);
await Workspace.modifyEmbeddings(workspace.slug, { await Workspace.modifyEmbeddings(workspace.slug, {
adds: [], adds: [],
deletes: [`${folderName}/${item.name}`],
// deletes: [`${folderName}/${item.name}`],
deletes: [`${item.relativePath}`],
}); });
await fetchKeys(true); await fetchKeys(true);
} catch (error) { } catch (error) {

5
frontend/src/components/Modals/ManageWorkspace/Documents/WorkspaceDirectory/index.jsx

@ -26,7 +26,6 @@ function WorkspaceDirectory({
movedItems, movedItems,
}) { }) {
const [selectedItems, setSelectedItems] = useState({}); const [selectedItems, setSelectedItems] = useState({});
const toggleSelection = (item) => { const toggleSelection = (item) => {
setSelectedItems((prevSelectedItems) => { setSelectedItems((prevSelectedItems) => {
const newSelectedItems = { ...prevSelectedItems }; const newSelectedItems = { ...prevSelectedItems };
@ -41,6 +40,7 @@ function WorkspaceDirectory({
const toggleSelectAll = () => { const toggleSelectAll = () => {
const allItems = files.items.flatMap((folder) => folder.items); const allItems = files.items.flatMap((folder) => folder.items);
const allSelected = allItems.every((item) => selectedItems[item.id]); const allSelected = allItems.every((item) => selectedItems[item.id]);
if (allSelected) { if (allSelected) {
setSelectedItems({}); setSelectedItems({});
@ -53,6 +53,7 @@ function WorkspaceDirectory({
} }
}; };
const removeSelectedItems = async () => { const removeSelectedItems = async () => {
setLoading(true); setLoading(true);
setLoadingMessage("Removing selected files from workspace"); setLoadingMessage("Removing selected files from workspace");
@ -60,7 +61,9 @@ function WorkspaceDirectory({
const itemsToRemove = Object.keys(selectedItems).map((itemId) => { const itemsToRemove = Object.keys(selectedItems).map((itemId) => {
const folder = files.items.find((f) => const folder = files.items.find((f) =>
f.items.some((i) => i.id === itemId) f.items.some((i) => i.id === itemId)
); );
const item = folder.items.find((i) => i.id === itemId); const item = folder.items.find((i) => i.id === itemId);
return `${folder.name}/${item.name}`; return `${folder.name}/${item.name}`;
}); });

10
frontend/src/components/Modals/ManageWorkspace/Documents/index.jsx

@ -34,7 +34,7 @@ export default function DocumentSettings({ workspace, systemSettings }) {
: workspace; : workspace;
const documentsInWorkspace = const documentsInWorkspace =
currentWorkspace.documents.map((doc) => doc.docpath) || [];
currentWorkspace.documents.map((doc) => doc.filename) || [];
// Documents that are not in the workspace // Documents that are not in the workspace
const availableDocs = { const availableDocs = {
@ -46,7 +46,7 @@ export default function DocumentSettings({ workspace, systemSettings }) {
items: folder.items.filter( items: folder.items.filter(
(file) => (file) =>
file.type === "file" && file.type === "file" &&
!documentsInWorkspace.includes(`${folder.name}/${file.name}`)
!documentsInWorkspace.includes(`${file.name}`)
), ),
}; };
} else { } else {
@ -65,7 +65,7 @@ export default function DocumentSettings({ workspace, systemSettings }) {
items: folder.items.filter( items: folder.items.filter(
(file) => (file) =>
file.type === "file" && file.type === "file" &&
documentsInWorkspace.includes(`${folder.name}/${file.name}`)
documentsInWorkspace.includes(`${file.name}`)
), ),
}; };
} else { } else {
@ -90,9 +90,11 @@ export default function DocumentSettings({ workspace, systemSettings }) {
setLoadingMessage("对于大型文档,这可能需要一段时间"); setLoadingMessage("对于大型文档,这可能需要一段时间");
const changesToSend = { const changesToSend = {
adds: movedItems.map((item) => `${item.folderName}/${item.name}`),
// adds: movedItems.map((item) => `${item.folderName}/${item.name}`),
adds: movedItems.map((item) => `${item.relativePath}`),
}; };
setSelectedItems({}); setSelectedItems({});
setHasChanges(false); setHasChanges(false);
setHighlightWorkspace(false); setHighlightWorkspace(false);

4
frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx

@ -53,7 +53,7 @@ const HistoricalMessage = ({
return ( return (
<div <div
key={uuid} key={uuid}
className={`flex justify-center items-end w-full bg-theme-bg-chat`}
className={`flex justify-center items-end w-full`}
> >
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col"> <div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col">
<div className="flex gap-x-5"> <div className="flex gap-x-5">
@ -81,7 +81,7 @@ const HistoricalMessage = ({
onAnimationEnd={onEndAnimation} onAnimationEnd={onEndAnimation}
className={`${ className={`${
isDeleted ? "animate-remove" : "" isDeleted ? "animate-remove" : ""
} flex justify-center items-end w-full group `}
} flex justify-center items-end w-full group`}
> >
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col"> <div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col">
<div className="flex gap-x-5"> <div className="flex gap-x-5">

3
frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/PromptReply/index.jsx

@ -19,7 +19,8 @@ const PromptReply = ({
sources = [], sources = [],
closed = true, closed = true,
}) => { }) => {
const assistantBackgroundColor = "bg-theme-bg-chat";
// const assistantBackgroundColor = bg-theme-bg-chat
const assistantBackgroundColor = "bg-[#F9FBFD]";
if (!reply && sources.length === 0 && !pending && !error) return null; if (!reply && sources.length === 0 && !pending && !error) return null;

2
frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/index.jsx

@ -176,7 +176,7 @@ export default function ChatHistory({
if (history.length === 0 && !hasAttachments) { if (history.length === 0 && !hasAttachments) {
return ( return (
<div className="flex flex-col h-full md:mt-0 pb-44 md:pb-40 w-full justify-end items-center">
<div className="flex flex-col h-full md:mt-0 pb-44 md:pb-40 w-full justify-end items-center mb-[50px]">
<div className="flex flex-col items-center md:items-start md:max-w-[600px] w-full px-4"> <div className="flex flex-col items-center md:items-start md:max-w-[600px] w-full px-4">
<p className="text-white/60 text-lg font-base py-4"> <p className="text-white/60 text-lg font-base py-4">
欢迎来到你的新工作空间 欢迎来到你的新工作空间

29
frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/SlashPresets/AddPresetModal.jsx

@ -9,17 +9,22 @@ export default function AddPresetModal({ isOpen, onClose, onSave }) {
const handleSubmit = async (e) => { const handleSubmit = async (e) => {
e.preventDefault(); e.preventDefault();
const form = new FormData(e.target); const form = new FormData(e.target);
const sanitizedCommand = command.replace(CMD_REGEX, "");
//
// const sanitizedCommand = command.replace(CMD_REGEX, "");
const sanitizedCommand = command
const saved = await onSave({ const saved = await onSave({
command: `/${sanitizedCommand}`,
// command: `/${sanitizedCommand}`,
command:sanitizedCommand,
prompt: form.get("prompt"), prompt: form.get("prompt"),
description: form.get("description"), description: form.get("description"),
}); });
if (saved) setCommand(""); if (saved) setCommand("");
window.location.reload()
}; };
const handleCommandChange = (e) => { const handleCommandChange = (e) => {
const value = e.target.value.replace(CMD_REGEX, "");
// const value = e.target.value.replace(CMD_REGEX, "");
const value = e.target.value
setCommand(value); setCommand(value);
}; };
@ -29,7 +34,7 @@ export default function AddPresetModal({ isOpen, onClose, onSave }) {
<div className="relative p-6 border-b rounded-t border-theme-modal-border"> <div className="relative p-6 border-b rounded-t border-theme-modal-border">
<div className="w-full flex gap-x-2 items-center"> <div className="w-full flex gap-x-2 items-center">
<h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap"> <h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap">
Add New Preset
添加新的提示词
</h3> </h3>
</div> </div>
<button <button
@ -52,7 +57,7 @@ export default function AddPresetModal({ isOpen, onClose, onSave }) {
htmlFor="command" htmlFor="command"
className="block mb-2 text-sm font-medium text-white" className="block mb-2 text-sm font-medium text-white"
> >
Command
命令
</label> </label>
<div className="flex items-center"> <div className="flex items-center">
<span className="text-white text-sm mr-2 font-bold">/</span> <span className="text-white text-sm mr-2 font-bold">/</span>
@ -60,7 +65,7 @@ export default function AddPresetModal({ isOpen, onClose, onSave }) {
name="command" name="command"
type="text" type="text"
id="command" id="command"
placeholder="your-command"
placeholder="您的命令"
value={command} value={command}
onChange={handleCommandChange} onChange={handleCommandChange}
maxLength={25} maxLength={25}
@ -75,13 +80,13 @@ export default function AddPresetModal({ isOpen, onClose, onSave }) {
htmlFor="prompt" htmlFor="prompt"
className="block mb-2 text-sm font-medium text-white" className="block mb-2 text-sm font-medium text-white"
> >
Prompt
提示
</label> </label>
<textarea <textarea
name="prompt" name="prompt"
id="prompt" id="prompt"
autoComplete="off" autoComplete="off"
placeholder="This is the content that will be injected in front of your prompt."
placeholder="这是将被注入到提示符前面的内容."
required={true} required={true}
className="border-none bg-theme-settings-input-bg w-full text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" className="border-none bg-theme-settings-input-bg w-full text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
></textarea> ></textarea>
@ -91,13 +96,13 @@ export default function AddPresetModal({ isOpen, onClose, onSave }) {
htmlFor="description" htmlFor="description"
className="block mb-2 text-sm font-medium text-white" className="block mb-2 text-sm font-medium text-white"
> >
Description
描述
</label> </label>
<input <input
type="text" type="text"
name="description" name="description"
id="description" id="description"
placeholder="Responds with a poem about LLMs."
placeholder="描述提示次的内容."
maxLength={80} maxLength={80}
autoComplete="off" autoComplete="off"
required={true} required={true}
@ -112,13 +117,13 @@ export default function AddPresetModal({ isOpen, onClose, onSave }) {
type="button" type="button"
className="transition-all duration-300 bg-transparent text-white hover:opacity-60 px-4 py-2 rounded-lg text-sm" className="transition-all duration-300 bg-transparent text-white hover:opacity-60 px-4 py-2 rounded-lg text-sm"
> >
Cancel
取消
</button> </button>
<button <button
type="submit" type="submit"
className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm" className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm"
> >
Save
保存
</button> </button>
</div> </div>
</form> </form>

32
frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/SlashPresets/EditPresetModal.jsx

@ -22,27 +22,33 @@ export default function EditPresetModal({
const handleSubmit = (e) => { const handleSubmit = (e) => {
e.preventDefault(); e.preventDefault();
const form = new FormData(e.target); const form = new FormData(e.target);
const sanitizedCommand = command.replace(CMD_REGEX, "");
//
// const sanitizedCommand = command.replace(CMD_REGEX, "");
const sanitizedCommand = command
onSave({ onSave({
id: preset.id, id: preset.id,
command: `/${sanitizedCommand}`,
// command: `/${sanitizedCommand}`,
command: sanitizedCommand,
prompt: form.get("prompt"), prompt: form.get("prompt"),
description: form.get("description"), description: form.get("description"),
}); });
window.location.reload()
}; };
const handleCommandChange = (e) => { const handleCommandChange = (e) => {
const value = e.target.value.replace(CMD_REGEX, "");
// const value = e.target.value.replace(CMD_REGEX, "");
const value = e.target.value
setCommand(value); setCommand(value);
}; };
const handleDelete = async () => { const handleDelete = async () => {
if (!window.confirm("Are you sure you want to delete this preset?")) return;
if (!window.confirm("您确定要删除此预设吗?")) return;
setDeleting(true); setDeleting(true);
await onDelete(preset.id); await onDelete(preset.id);
setDeleting(false); setDeleting(false);
onClose(); onClose();
window.location.reload()
}; };
return ( return (
@ -51,7 +57,7 @@ export default function EditPresetModal({
<div className="relative p-6 border-b rounded-t border-theme-modal-border"> <div className="relative p-6 border-b rounded-t border-theme-modal-border">
<div className="w-full flex gap-x-2 items-center"> <div className="w-full flex gap-x-2 items-center">
<h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap"> <h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap">
Edit Preset
编辑预设
</h3> </h3>
</div> </div>
<button <button
@ -74,14 +80,14 @@ export default function EditPresetModal({
htmlFor="command" htmlFor="command"
className="block mb-2 text-sm font-medium text-white" className="block mb-2 text-sm font-medium text-white"
> >
Command
命令
</label> </label>
<div className="flex items-center"> <div className="flex items-center">
<span className="text-white text-sm mr-2 font-bold">/</span> <span className="text-white text-sm mr-2 font-bold">/</span>
<input <input
type="text" type="text"
name="command" name="command"
placeholder="your-command"
placeholder="您的命令"
value={command} value={command}
onChange={handleCommandChange} onChange={handleCommandChange}
required={true} required={true}
@ -94,11 +100,11 @@ export default function EditPresetModal({
htmlFor="prompt" htmlFor="prompt"
className="block mb-2 text-sm font-medium text-white" className="block mb-2 text-sm font-medium text-white"
> >
Prompt
提示
</label> </label>
<textarea <textarea
name="prompt" name="prompt"
placeholder="This is a test prompt. Please respond with a poem about LLMs."
placeholder="请输入提示内容."
defaultValue={preset.prompt} defaultValue={preset.prompt}
required={true} required={true}
className="border-none bg-theme-settings-input-bg w-full text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" className="border-none bg-theme-settings-input-bg w-full text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
@ -109,7 +115,7 @@ export default function EditPresetModal({
htmlFor="description" htmlFor="description"
className="block mb-2 text-sm font-medium text-white" className="block mb-2 text-sm font-medium text-white"
> >
Description
描述
</label> </label>
<input <input
type="text" type="text"
@ -129,7 +135,7 @@ export default function EditPresetModal({
type="button" type="button"
className="transition-all duration-300 bg-transparent text-red-500 hover:bg-red-500/25 px-4 py-2 rounded-lg text-sm disabled:opacity-50" className="transition-all duration-300 bg-transparent text-red-500 hover:bg-red-500/25 px-4 py-2 rounded-lg text-sm disabled:opacity-50"
> >
{deleting ? "Deleting..." : "Delete Preset"}
{deleting ? "Deleting..." : "删除"}
</button> </button>
<div className="flex space-x-2"> <div className="flex space-x-2">
<button <button
@ -137,13 +143,13 @@ export default function EditPresetModal({
type="button" type="button"
className="transition-all duration-300 bg-transparent text-white hover:opacity-60 px-4 py-2 rounded-lg text-sm" className="transition-all duration-300 bg-transparent text-white hover:opacity-60 px-4 py-2 rounded-lg text-sm"
> >
Cancel
取消
</button> </button>
<button <button
type="submit" type="submit"
className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm" className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm"
> >
Save
保存
</button> </button>
</div> </div>
</div> </div>

45
frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/index.jsx

@ -18,6 +18,7 @@ import AttachItem from "./AttachItem";
import { PASTE_ATTACHMENT_EVENT } from "../DnDWrapper"; import { PASTE_ATTACHMENT_EVENT } from "../DnDWrapper";
import useTextSize from "@/hooks/useTextSize"; import useTextSize from "@/hooks/useTextSize";
import "../../srk.css" import "../../srk.css"
import System from "@/models/system";
export const PROMPT_INPUT_EVENT = "set_prompt_input"; export const PROMPT_INPUT_EVENT = "set_prompt_input";
const MAX_EDIT_STACK_SIZE = 100; const MAX_EDIT_STACK_SIZE = 100;
@ -39,7 +40,7 @@ export default function PromptInput({
const undoStack = useRef([]); const undoStack = useRef([]);
const redoStack = useRef([]); const redoStack = useRef([]);
const { textSizeClass } = useTextSize(); const { textSizeClass } = useTextSize();
const [presets, setPresets] = useState([]);
/** /**
* To prevent too many re-renders we remotely listen for updates from the parent * To prevent too many re-renders we remotely listen for updates from the parent
* via an event cycle. Otherwise, using message as a prop leads to a re-render every * via an event cycle. Otherwise, using message as a prop leads to a re-render every
@ -235,6 +236,16 @@ export default function PromptInput({
setPromptInput(e.target.value); setPromptInput(e.target.value);
} }
useEffect(() => {
fetchPresets();
}, []);
//
const fetchPresets = async () => {
const presets = await System.getSlashCommandPresets();
setPresets(presets);
};
return ( return (
<div className="w-full fixed md:absolute bottom-0 left-0 z-10 md:z-0 flex justify-center items-center"> <div className="w-full fixed md:absolute bottom-0 left-0 z-10 md:z-0 flex justify-center items-center">
<SlashCommands <SlashCommands
@ -250,10 +261,34 @@ export default function PromptInput({
/> />
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="flex flex-col gap-y-1 rounded-t-lg md:w-3/4 w-full mx-auto max-w-xl items-center"
// className="flex flex-col gap-y-1 rounded-t-lg md:w-3/4 w-full mx-auto max-w-xl items-center"
> >
<div className="flex items-center rounded-lg md:mb-4 input_border">
<div className="w-[95vw] md:w-[800px] shadow-[0_0_11px_0px_#EBEDF6] bg-theme-bg-chat-input light:bg-white light:border-theme-chat-input-border rounded-2xl flex flex-col px-4 overflow-hidden">
<div style={{ display: 'flex', flexWrap:'wrap'}} className='w-[95vw] md:w-[800px]'>
<button
onClick={() => {
sendCommand("/reset", true);
}}
className="bg-[#F9FBFD] hover:bg-[#cacad1] border border-solid border-[#E5E7EB]"
style={{ textAlign: 'left', padding: '3px 15px', margin: '5px 0 5px 10px', display: 'flex', alignItems: 'center', borderRadius: '5px' }}
>
<div className="text-[14px]" >重置</div>
</button>
{presets.map((preset) => (
<button
key={preset.id}
onClick={() => {
sendCommand(`${preset.command}`, true);
}}
className="bg-[#F9FBFD] hover:bg-[#cacad1] border border-solid border-[#E5E7EB]"
style={{ textAlign: 'left', padding: '3px 15px', margin: '5px 0 5px 10px', display: 'flex', alignItems: 'center', borderRadius: '5px' }}
>
<div className="text-[14px]" >{preset.command}</div>
</button>
))}
</div>
<div className="flex items-center rounded-lg md:mb-4 input_border">
<div className="w-[95vw] md:w-[800px] shadow-[0_0_11px_0px_#EBEDF6] bg-theme-bg-chat-input light:bg-white light:border-theme-chat-input-border rounded-2xl flex flex-col px-4 overflow-hidden">
<AttachmentManager attachments={attachments} /> <AttachmentManager attachments={attachments} />
<div className="flex items-center w-full border-b border-gray-200"> <div className="flex items-center w-full border-b border-gray-200">
<textarea <textarea
@ -272,7 +307,7 @@ export default function PromptInput({
adjustTextArea(e); adjustTextArea(e);
}} }}
value={promptInput} value={promptInput}
className={`border-none cursor-text max-h-[50vh] md:max-h-[350px] md:min-h-[40px] mx-2 md:mx-0 pt-[12px] pb-[5px] w-full leading-5 md:text-md text-white bg-transparent resize-none active:outline-none focus:outline-none flex-grow ${textSizeClass}`}
className={`border-none cursor-text max-h-[50vh] md:max-h-[350px] md:min-h-[40px] mx-2 md:mx-0 pt-[10px] w-full leading-5 md:text-md text-white bg-transparent resize-none active:outline-none focus:outline-none flex-grow ${textSizeClass}`}
placeholder={"和deepSeek说几句话"} placeholder={"和deepSeek说几句话"}
/> />
{buttonDisabled ? ( {buttonDisabled ? (

34
frontend/src/pages/Admin/Users/NewUserModal/index.jsx

@ -3,7 +3,7 @@ import { X } from "@phosphor-icons/react";
import Admin from "@/models/admin"; import Admin from "@/models/admin";
import { userFromStorage } from "@/utils/request"; import { userFromStorage } from "@/utils/request";
import { MessageLimitInput, RoleHintDisplay } from ".."; import { MessageLimitInput, RoleHintDisplay } from "..";
import { Select } from "antd";
import { Select,message } from "antd";
export default function NewUserModal({ closeModal }) { export default function NewUserModal({ closeModal }) {
const [error, setError] = useState(null); const [error, setError] = useState(null);
@ -13,26 +13,30 @@ export default function NewUserModal({ closeModal }) {
limit: 10, limit: 10,
}); });
const [depId, setDepId] = useState([]); const [depId, setDepId] = useState([]);
const [flag, setFlag] = useState(null);
const handleCreate = async (e) => { const handleCreate = async (e) => {
setError(null);
e.preventDefault();
const data = {};
const form = new FormData(e.target);
for (var [key, value] of form.entries()) data[key] = value;
data.dailyMessageLimit = messageLimit.enabled ? messageLimit.limit : null;
console.log('用户', data);
const { user, error } = await Admin.newUserTo(data,depId);
// console.log('',user);
console.log('获取',depId);
// if (!!user) window.location.reload();
setError(error);
if(depId.length==0){
message.info(`部门不能为空`)
e.preventDefault();
setFlag('error')
}else{
setError(null);
e.preventDefault();
const data = {};
const form = new FormData(e.target);
for (var [key, value] of form.entries()) data[key] = value;
data.dailyMessageLimit = messageLimit.enabled ? messageLimit.limit : null;
const { user, error } = await Admin.newUserTo(data,depId);
if (!!user) window.location.reload();
setError(error);
}
}; };
const user = userFromStorage(); const user = userFromStorage();
const [departments, setDepartments] = useState([]); const [departments, setDepartments] = useState([]);
const [treeData, setTreeData] = useState([]); const [treeData, setTreeData] = useState([]);
useEffect(() => { useEffect(() => {
async function fetchDepartments() { async function fetchDepartments() {
@ -41,7 +45,6 @@ export default function NewUserModal({ closeModal }) {
value:item.deptId, value:item.deptId,
label:item.deptName label:item.deptName
})) }))
console.log(222222, list);
setDepartments(list); setDepartments(list);
} }
fetchDepartments(); fetchDepartments();
@ -129,6 +132,7 @@ export default function NewUserModal({ closeModal }) {
部门 部门
</label> </label>
<Select <Select
status={flag}
className="w-[100%] h-[42px]" className="w-[100%] h-[42px]"
showSearch showSearch
placeholder="请选择部门" placeholder="请选择部门"

18
frontend/src/pages/Admin/Users/UserRow/EditUserModal/index.jsx

@ -37,7 +37,7 @@ export default function EditUserModal({ currentUser, user, closeModal }) {
<div className="relative p-6 border-b rounded-t border-theme-modal-border"> <div className="relative p-6 border-b rounded-t border-theme-modal-border">
<div className="w-full flex gap-x-2 items-center"> <div className="w-full flex gap-x-2 items-center">
<h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap"> <h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap">
Edit {user.username}
编辑 {user.username}
</h3> </h3>
</div> </div>
<button <button
@ -56,7 +56,7 @@ export default function EditUserModal({ currentUser, user, closeModal }) {
htmlFor="username" htmlFor="username"
className="block mb-2 text-sm font-medium text-white" className="block mb-2 text-sm font-medium text-white"
> >
Username
用户名
</label> </label>
<input <input
name="username" name="username"
@ -69,8 +69,8 @@ export default function EditUserModal({ currentUser, user, closeModal }) {
autoComplete="off" autoComplete="off"
/> />
<p className="mt-2 text-xs text-white/60"> <p className="mt-2 text-xs text-white/60">
Username must only contain lowercase letters, numbers,
underscores, and hyphens with no spaces
用户名只能包含小写字母数字
下划线和连字符不带空格
</p> </p>
</div> </div>
<div> <div>
@ -78,7 +78,7 @@ export default function EditUserModal({ currentUser, user, closeModal }) {
htmlFor="password" htmlFor="password"
className="block mb-2 text-sm font-medium text-white" className="block mb-2 text-sm font-medium text-white"
> >
New Password
新密码
</label> </label>
<input <input
name="password" name="password"
@ -89,7 +89,7 @@ export default function EditUserModal({ currentUser, user, closeModal }) {
minLength={8} minLength={8}
/> />
<p className="mt-2 text-xs text-white/60"> <p className="mt-2 text-xs text-white/60">
Password must be at least 8 characters long
密码长度至少为8个字符
</p> </p>
</div> </div>
<div> <div>
@ -97,7 +97,7 @@ export default function EditUserModal({ currentUser, user, closeModal }) {
htmlFor="role" htmlFor="role"
className="block mb-2 text-sm font-medium text-white" className="block mb-2 text-sm font-medium text-white"
> >
Role
角色
</label> </label>
<select <select
name="role" name="role"
@ -128,13 +128,13 @@ export default function EditUserModal({ currentUser, user, closeModal }) {
type="button" type="button"
className="transition-all duration-300 text-white hover:bg-zinc-700 px-4 py-2 rounded-lg text-sm" className="transition-all duration-300 text-white hover:bg-zinc-700 px-4 py-2 rounded-lg text-sm"
> >
Cancel
取消
</button> </button>
<button <button
type="submit" type="submit"
className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm" className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm"
> >
Update user
更新用户
</button> </button>
</div> </div>
</form> </form>

9
frontend/src/pages/Admin/Users/UserRow/index.jsx

@ -5,6 +5,7 @@ import EditUserModal from "./EditUserModal";
import showToast from "@/utils/toast"; import showToast from "@/utils/toast";
import { useModal } from "@/hooks/useModal"; import { useModal } from "@/hooks/useModal";
import ModalWrapper from "@/components/ModalWrapper"; import ModalWrapper from "@/components/ModalWrapper";
import moment from 'moment';
const ModMap = { const ModMap = {
admin: ["admin", "manager", "default"], admin: ["admin", "manager", "default"],
@ -20,7 +21,7 @@ export default function UserRow({ currUser, user }) {
const handleSuspend = async () => { const handleSuspend = async () => {
if ( if (
!window.confirm( !window.confirm(
`Are you sure you want to suspend ${user.username}?\nAfter you do this they will be logged out and unable to log back into this instance of AnythingLLM until unsuspended by an admin.`
`您确定要删除吗 ${user.username}?\n在您这样做之后,它们将被注销,并且无法重新登录`
) )
) )
return false; return false;
@ -41,7 +42,7 @@ export default function UserRow({ currUser, user }) {
const handleDelete = async () => { const handleDelete = async () => {
if ( if (
!window.confirm( !window.confirm(
`Are you sure you want to delete ${user.username}?\nAfter you do this they will be logged out and unable to use this instance of AnythingLLM.\n\nThis action is irreversible.`
`您确定要删除吗 ${user.username}?\n在您这样做之后,它们将被注销,并且无法重新登录`
) )
) )
return false; return false;
@ -70,7 +71,7 @@ export default function UserRow({ currUser, user }) {
onClick={openModal} onClick={openModal}
className="text-sm font-medium text-white/80 light:text-black/80 rounded-lg hover:text-white hover:light:text-gray-500 px-2 py-1 hover:bg-white hover:bg-opacity-10" className="text-sm font-medium text-white/80 light:text-black/80 rounded-lg hover:text-white hover:light:text-gray-500 px-2 py-1 hover:bg-white hover:bg-opacity-10"
> >
Edit
编辑
</button> </button>
)} )}
{currUser?.id !== user.id && canModify && ( {currUser?.id !== user.id && canModify && (
@ -85,7 +86,7 @@ export default function UserRow({ currUser, user }) {
onClick={handleDelete} onClick={handleDelete}
className="text-sm font-medium text-white/80 light:text-black/80 hover:light:text-red-500 hover:text-red-300 rounded-lg px-2 py-1 hover:bg-white hover:light:bg-red-50 hover:bg-opacity-10" className="text-sm font-medium text-white/80 light:text-black/80 hover:light:text-red-500 hover:text-red-300 rounded-lg px-2 py-1 hover:bg-white hover:light:bg-red-50 hover:bg-opacity-10"
> >
Delete
删除
</button> </button>
</> </>
)} )}

8
frontend/src/pages/Admin/Users/index.jsx

@ -62,7 +62,6 @@ function UsersContainer() {
useEffect(() => { useEffect(() => {
async function fetchUsers() { async function fetchUsers() {
const _users = await Admin.users(); const _users = await Admin.users();
console.log(1111, _users);
setUsers(_users); setUsers(_users);
setLoading(false); setLoading(false);
} }
@ -96,6 +95,9 @@ function UsersContainer() {
<th scope="col" className="px-6 py-3"> <th scope="col" className="px-6 py-3">
添加日期 添加日期
</th> </th>
<th scope="col" className="px-6 py-3">
操作
</th>
<th scope="col" className="px-6 py-3 rounded-tr-lg"> <th scope="col" className="px-6 py-3 rounded-tr-lg">
{" "} {" "}
</th> </th>
@ -121,8 +123,8 @@ const ROLE_HINT = {
"Cannot modify LLM, vectorDB, embedding, or other connections.", "Cannot modify LLM, vectorDB, embedding, or other connections.",
], ],
admin: [ admin: [
"Highest user level privilege.",
"Can see and do everything across the system.",
"最高用户权限",
"可以看到并执行整个系统的所有操作。",
], ],
}; };

2
frontend/src/pages/Admin/Workspaces/WorkspaceRow/index.jsx

@ -8,7 +8,7 @@ export default function WorkspaceRow({ workspace, users }) {
const handleDelete = async () => { const handleDelete = async () => {
if ( if (
!window.confirm( !window.confirm(
`Are you sure you want to delete ${workspace.name}?\nAfter you do this it will be unavailable in this instance of AnythingLLM.\n\nThis action is irreversible.`
`您确定要删除吗 ${workspace.name}?\nAfter you do this it will be unavailable in this instance of AnythingLLM.\n\nThis action is irreversible.`
) )
) )
return false; return false;

5
frontend/src/pages/DataAnalysis/DataAnalysis.css

@ -97,7 +97,8 @@
} }
.nr1 img { .nr1 img {
width: 100%;
/* width: 100%; */
width: 70px;
} }
.nr2 { .nr2 {
@ -136,4 +137,4 @@
margin-right: 20px; margin-right: 20px;
border-radius: 5px; border-radius: 5px;
font-size: 14px; font-size: 14px;
}
}

BIN
frontend/src/pages/DataAnalysis/img/1.png

Before

Width: 61  |  Height: 62  |  Size: 4.5 KiB

After

Width: 1667  |  Height: 1667  |  Size: 24 KiB

BIN
frontend/src/pages/DataAnalysis/img/10.png

Before

Width: 61  |  Height: 62  |  Size: 3.2 KiB

After

Width: 1668  |  Height: 1667  |  Size: 33 KiB

BIN
frontend/src/pages/DataAnalysis/img/11.png

Before

Width: 62  |  Height: 60  |  Size: 4.2 KiB

After

Width: 1668  |  Height: 1667  |  Size: 15 KiB

BIN
frontend/src/pages/DataAnalysis/img/12.png

Before

Width: 64  |  Height: 62  |  Size: 5.1 KiB

After

Width: 1667  |  Height: 1667  |  Size: 35 KiB

BIN
frontend/src/pages/DataAnalysis/img/13.png

Before

Width: 64  |  Height: 64  |  Size: 4.9 KiB

After

Width: 1668  |  Height: 1667  |  Size: 26 KiB

BIN
frontend/src/pages/DataAnalysis/img/14.png

Before

Width: 62  |  Height: 62  |  Size: 3.9 KiB

After

Width: 1668  |  Height: 1667  |  Size: 39 KiB

BIN
frontend/src/pages/DataAnalysis/img/2.png

Before

Width: 62  |  Height: 64  |  Size: 3.6 KiB

After

Width: 1668  |  Height: 1667  |  Size: 28 KiB

BIN
frontend/src/pages/DataAnalysis/img/3.png

Before

Width: 62  |  Height: 61  |  Size: 4.5 KiB

After

Width: 1668  |  Height: 1667  |  Size: 27 KiB

BIN
frontend/src/pages/DataAnalysis/img/4.png

Before

Width: 63  |  Height: 64  |  Size: 4.4 KiB

After

Width: 1667  |  Height: 1667  |  Size: 30 KiB

BIN
frontend/src/pages/DataAnalysis/img/5.png

Before

Width: 64  |  Height: 63  |  Size: 5.0 KiB

After

Width: 1667  |  Height: 1667  |  Size: 39 KiB

BIN
frontend/src/pages/DataAnalysis/img/6.png

Before

Width: 62  |  Height: 63  |  Size: 4.1 KiB

After

Width: 1668  |  Height: 1667  |  Size: 28 KiB

BIN
frontend/src/pages/DataAnalysis/img/7.png

Before

Width: 63  |  Height: 62  |  Size: 3.9 KiB

After

Width: 1668  |  Height: 1667  |  Size: 39 KiB

BIN
frontend/src/pages/DataAnalysis/img/8.png

Before

Width: 64  |  Height: 62  |  Size: 2.9 KiB

After

Width: 1667  |  Height: 1667  |  Size: 37 KiB

BIN
frontend/src/pages/DataAnalysis/img/9.png

Before

Width: 63  |  Height: 61  |  Size: 3.5 KiB

After

Width: 1667  |  Height: 1667  |  Size: 30 KiB

45
frontend/src/pages/DataAnalysis/index.jsx

@ -3,16 +3,16 @@ import { useNavigate } from 'react-router-dom';
import './DataAnalysis.css' import './DataAnalysis.css'
import sou from './img/sou.png' import sou from './img/sou.png'
import home from './img/home.png' import home from './img/home.png'
import tu1 from './img/1.png'
import tu2 from './img/2.png'
import tu12 from './img/12.png'
import tu3 from './img/3.png' import tu3 from './img/3.png'
import tu4 from './img/4.png' import tu4 from './img/4.png'
import tu5 from './img/5.png' import tu5 from './img/5.png'
import tu6 from './img/6.png' import tu6 from './img/6.png'
import tu7 from './img/7.png' import tu7 from './img/7.png'
import tu8 from './img/8.png' import tu8 from './img/8.png'
import tu9 from './img/9.png'
import tu10 from './img/10.png'
import tu11 from './img/11.png' import tu11 from './img/11.png'
import tu14 from './img/14.png'
import { message } from "antd"; import { message } from "antd";
function DataAnalysis() { function DataAnalysis() {
@ -22,54 +22,58 @@ function DataAnalysis() {
{ {
name: '舆情分析', name: '舆情分析',
text: '收集群众反馈意见,对意见进行分类,并分析对应舆情状态', text: '收集群众反馈意见,对意见进行分类,并分析对应舆情状态',
img: tu1,
img: tu3,
url: '/home/Yuqingfenxi' url: '/home/Yuqingfenxi'
}, },
{ {
name: '经济发展分析', name: '经济发展分析',
text: '整合并分析经济数据,输出经济趋势分析报告,自动生成包含图表和文字解读的分析报告', text: '整合并分析经济数据,输出经济趋势分析报告,自动生成包含图表和文字解读的分析报告',
img: tu2
img: tu4,
url: '/home/Economics'
},
{
name: '人才分析',
text: '分析人才流动情况、就业情况、人才数量、性别占比、岗位数量、录用率等',
img: tu8,
url: '/home/Talents'
},
{
name: '产业分析',
text: '对新能源、盐碱化工等产业进行资源、市场、技术分析用户输入产业信息,系统自动进行分析并输出报告资源分析:评估产业所需的自然、人力资源市场分析:分析当前市场需求、竞争态势',
img: tu12,
url: '/home/Industry'
}, },
{ {
name: '沙漠化分析', name: '沙漠化分析',
text: '分析植被覆盖率和沙化面积', text: '分析植被覆盖率和沙化面积',
img: tu3
img: tu5
}, },
{ {
name: '工业污染分析', name: '工业污染分析',
text: '分析工业区域污染物排放情况', text: '分析工业区域污染物排放情况',
img: tu4
img: tu6
}, },
{ {
name: '生态修复分析', name: '生态修复分析',
text: '分析不同区域内环境治理前后生态指标', text: '分析不同区域内环境治理前后生态指标',
img: tu5
},
{
name: '人才分析',
text: '分析人才流动情况、就业情况、人才数量、性别占比、岗位数量、录用率等',
img: tu6
img: tu7
}, },
{ {
name: '教育资源分析', name: '教育资源分析',
text: '分析教育资源的分布情况,评估教育公平性', text: '分析教育资源的分布情况,评估教育公平性',
img: tu7
img: tu9
}, },
{ {
name: '医疗服务分析', name: '医疗服务分析',
text: '监测医疗服务数据,分析就诊率和疾病谱变化', text: '监测医疗服务数据,分析就诊率和疾病谱变化',
img: tu8
img: tu10
}, },
{ {
name: '项目进度跟踪', name: '项目进度跟踪',
text: '实时显示项目的进度状态,对比计划与实际进度', text: '实时显示项目的进度状态,对比计划与实际进度',
img: tu11 img: tu11
}, },
{
name: '产业分析',
text: '对新能源、盐碱化工等产业进行资源、市场、技术分析用户输入产业信息,系统自动进行分析并输出报告资源分析:评估产业所需的自然、人力资源市场分析:分析当前市场需求、竞争态势',
img: tu14
},
] ]
useEffect(() => { useEffect(() => {
@ -77,7 +81,6 @@ function DataAnalysis() {
}, []); }, []);
const bindUrl = (e) => { const bindUrl = (e) => {
console.log(1234, e);
if (e.url) { if (e.url) {
navigate(e.url) navigate(e.url)
} else { } else {

18
frontend/src/pages/Home/index.jsx

@ -13,20 +13,33 @@ import icon5 from "./img/5.png"
import icon6 from "./img/6.png" import icon6 from "./img/6.png"
import icon7 from "./img/7.png" import icon7 from "./img/7.png"
import icon8 from "./img/8.png" import icon8 from "./img/8.png"
import paths from "@/utils/paths";
import Workspace from "@/models/workspace";
export default function Home() { export default function Home() {
const [workspaces, setWorkspaces] = useState([]);
const WeekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; const WeekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const [currentTime, setCurrentTime] = useState(moment()); const [currentTime, setCurrentTime] = useState(moment());
const navigate = useNavigate(); const navigate = useNavigate();
useEffect(() => {
async function getWorkspaces() {
const workspaces = await Workspace.all();
const workSlug = workspaces[0].slug
setWorkspaces(workSlug);
}
getWorkspaces();
}, []);
// 1- 2- 3- 4- // 1- 2- 3- 4-
const list = [ const list = [
{ {
type: 1, type: 1,
url: '/Main',
url: paths.workspace.chat(workspaces),
name: 'AI问政', name: 'AI问政',
icon: icon3, icon: icon3,
// paths.workspace.chat(workspaces)
}, },
{ {
type: 1, type: 1,
@ -75,7 +88,6 @@ export default function Home() {
// //
const bindUrl = (e) => { const bindUrl = (e) => {
console.log(1234, e);
if (e.type == 1) { if (e.type == 1) {
// window.location = e.url // window.location = e.url
navigate(e.url) navigate(e.url)

5
frontend/src/pages/ReportGeneration/ReportGeneration.css

@ -97,7 +97,8 @@
} }
.nr1 img { .nr1 img {
width: 100%;
/* width: 100%; */
width: 70px;
} }
.nr2 { .nr2 {
@ -136,4 +137,4 @@
margin-right: 20px; margin-right: 20px;
border-radius: 5px; border-radius: 5px;
font-size: 14px; font-size: 14px;
}
}

44
frontend/src/pages/ReportGeneration/index.jsx

@ -1,37 +1,41 @@
// import React, { useEffect, useRef } from 'react';
import React, { useEffect, useState, useRef } from 'react'; import React, { useEffect, useState, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import { message } from "antd";
import './ReportGeneration.css' import './ReportGeneration.css'
import sou from '../DataAnalysis/img/sou.png' import sou from '../DataAnalysis/img/sou.png'
import home from '../DataAnalysis/img/home.png' import home from '../DataAnalysis/img/home.png'
import tu1 from '../DataAnalysis/img/8.png'
import tu17 from '../DataAnalysis/img/17.png'
import tu2 from '../DataAnalysis/img/2.png' import tu2 from '../DataAnalysis/img/2.png'
import tu3 from '../DataAnalysis/img/3.png'
import tu4 from '../DataAnalysis/img/14.png'
import tu4 from '../DataAnalysis/img/4.png'
import tu1 from '../DataAnalysis/img/1.png'
function IframeComponent() { function IframeComponent() {
const [renderKey, setRenderKey] = useState(); const [renderKey, setRenderKey] = useState();
const navigate = useNavigate();
const list = [ const list = [
{
name: '报告生成',
text: '根据分析结果和用户需求,自动生成各类报告,并支持多种输出格式。',
img: tu17,
url: '/home/Report'
},
{ {
name: '报告模板', name: '报告模板',
text: '根据需要选择合适的模板进行编辑和生成报告。', text: '根据需要选择合适的模板进行编辑和生成报告。',
img: tu1
img: tu2
}, },
{ {
name: '数据支撑', name: '数据支撑',
text: '可从文件库内选取指定参考文件', text: '可从文件库内选取指定参考文件',
img: tu2
},
{
name: '报告生成',
text: '根据分析结果和用户需求,自动生成各类报告,并支持多种输出格式。',
img: tu3
img: tu4
}, },
{ {
name: '智能推送', name: '智能推送',
text: '支持根据预设条件自动推送报告,确保相关人员及时获取报告信息', text: '支持根据预设条件自动推送报告,确保相关人员及时获取报告信息',
img: tu4
img: tu1
}, },
] ]
@ -39,7 +43,17 @@ function IframeComponent() {
}, []); }, []);
const bindUrl = () =>{
const bindUrl = (e) => {
if (e.url) {
navigate(e.url)
} else {
message.info({
content: e.name + '开发中...'
})
}
}
const bindUrl1 = () =>{
window.location = '/' window.location = '/'
} }
@ -47,7 +61,7 @@ function IframeComponent() {
<div className='box'> <div className='box'>
<div className='box1'> <div className='box1'>
<div className='head'> <div className='head'>
<div><img src={home} onClick={bindUrl} alt="" /></div>
<div><img src={home} onClick={bindUrl1} alt="" /></div>
<div className='search'> <div className='search'>
<div className='search1'> <div className='search1'>
<img src={sou} alt="" /> <img src={sou} alt="" />
@ -68,7 +82,7 @@ function IframeComponent() {
<div>{item.text}</div> <div>{item.text}</div>
</div> </div>
</div> </div>
<div className='content2_2'>
<div className='content2_2' onClick={() => bindUrl(item)}>
<button>立即使用</button> <button>立即使用</button>
</div> </div>
</div> </div>

5
frontend/src/pages/Tendency/Tendency.css

@ -96,7 +96,8 @@
} }
.nr1 img { .nr1 img {
width: 100%;
/* width: 100%; */
width: 70px;
} }
.nr2 { .nr2 {
@ -135,4 +136,4 @@
margin-right: 20px; margin-right: 20px;
border-radius: 5px; border-radius: 5px;
font-size: 14px; font-size: 14px;
}
}

33
frontend/src/pages/Tendency/index.jsx

@ -1,29 +1,32 @@
import React, { useEffect, useState, useRef } from 'react'; import React, { useEffect, useState, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import { message } from "antd";
import './Tendency.css' import './Tendency.css'
import sou from '../DataAnalysis/img/sou.png' import sou from '../DataAnalysis/img/sou.png'
import home from '../DataAnalysis/img/home.png' import home from '../DataAnalysis/img/home.png'
import tu1 from '../DataAnalysis/img/5.png'
import tu2 from '../DataAnalysis/img/8.png'
import tu3 from '../DataAnalysis/img/11.png'
import tu13 from '../DataAnalysis/img/13.png'
import tu14 from '../DataAnalysis/img/14.png'
import tu15 from '../DataAnalysis/img/15.png'
function Tendency() { function Tendency() {
const [renderKey, setRenderKey] = useState(); const [renderKey, setRenderKey] = useState();
const navigate = useNavigate();
const list = [ const list = [
{ {
name: '趋势预测', name: '趋势预测',
text: '利用机器学习算法对历史数据进行分析,预测未来一段时间内的数据变化趋势,如经济发展、人口流动、环境状况等。', text: '利用机器学习算法对历史数据进行分析,预测未来一段时间内的数据变化趋势,如经济发展、人口流动、环境状况等。',
img: tu1
img: tu13,
url: '/home/TrendPrediction'
}, },
{ {
name: '异常监测', name: '异常监测',
text: '自动检测数据中的异常值或突变点,提醒用户注意可能存在的问题或风险。', text: '自动检测数据中的异常值或突变点,提醒用户注意可能存在的问题或风险。',
img: tu2
img: tu14
}, },
{ {
name: '指标监测', name: '指标监测',
text: '对关键指标进行实时监控,当指标达到预设阈值时,自动触发警报,确保管理层能迅速响应。', text: '对关键指标进行实时监控,当指标达到预设阈值时,自动触发警报,确保管理层能迅速响应。',
img: tu3
img: tu15
}, },
] ]
@ -31,7 +34,17 @@ function Tendency() {
}, []); }, []);
const bindUrl = () => {
const bindUrl = (e) => {
if (e.url) {
navigate(e.url)
} else {
message.info({
content: e.name + '开发中...'
})
}
}
const bindUrl1 = () => {
window.location = '/' window.location = '/'
} }
@ -39,7 +52,7 @@ function Tendency() {
<div className='box'> <div className='box'>
<div className='box1'> <div className='box1'>
<div className='head'> <div className='head'>
<div><img src={home} onClick={bindUrl} alt="" /></div>
<div><img src={home} onClick={bindUrl1} alt="" /></div>
<div className='search'> <div className='search'>
<div className='search1'> <div className='search1'>
<img src={sou} alt="" /> <img src={sou} alt="" />
@ -60,7 +73,7 @@ function Tendency() {
<div>{item.text}</div> <div>{item.text}</div>
</div> </div>
</div> </div>
<div className='content2_2'>
<div className='content2_2' onClick={() => bindUrl(item)}>
<button>立即使用</button> <button>立即使用</button>
</div> </div>
</div> </div>

4
frontend/src/utils/constants.js

@ -1,5 +1,5 @@
export const API_BASE = import.meta.env.VITE_API_BASE || "/api";
// export const API_BASE = 'http://172.16.2.31:3001/api'
// export const API_BASE = import.meta.env.VITE_API_BASE || "/api";
export const API_BASE = 'http://172.16.2.9:3001/api'
export const ONBOARDING_SURVEY_URL = "https://onboarding.anythingllm.com"; export const ONBOARDING_SURVEY_URL = "https://onboarding.anythingllm.com";
export const AUTH_USER = "anythingllm_user"; export const AUTH_USER = "anythingllm_user";

15
frontend/src/utils/paths.js

@ -20,11 +20,26 @@ export default {
Yuqingfenxi: () => { Yuqingfenxi: () => {
return "/home/Yuqingfenxi"; return "/home/Yuqingfenxi";
}, },
Economics: () => {
return "/home/Economics";
},
TrendPrediction: () => {
return "/home/TrendPrediction";
},
Industry: () => {
return "/home/Industry";
},
Talents: () => {
return "/home/Talents";
},
DataAnalysis: () => { DataAnalysis: () => {
return "/home/DataAnalysis"; return "/home/DataAnalysis";
}, },
ReportGeneration:() =>{ ReportGeneration:() =>{
return "/home/ReportGeneration"; return "/home/ReportGeneration";
},
Report:() =>{
return "/home/Report";
} }
}, },
onboarding: { onboarding: {

5
server/models/slashCommandsPresets.js

@ -6,9 +6,10 @@ const SlashCommandPresets = {
formatCommand: function (command = "") { formatCommand: function (command = "") {
if (!command || command.length < 2) return `/${v4().split("-")[0]}`; if (!command || command.length < 2) return `/${v4().split("-")[0]}`;
let adjustedCmd = command.toLowerCase(); // force lowercase
let adjustedCmd = command.toLowerCase(); // force lowercase
if (!adjustedCmd.startsWith("/")) adjustedCmd = `/${adjustedCmd}`; // Fix if no preceding / is found. if (!adjustedCmd.startsWith("/")) adjustedCmd = `/${adjustedCmd}`; // Fix if no preceding / is found.
return `/${adjustedCmd.slice(1).toLowerCase().replace(CMD_REGEX, "-")}`; // replace any invalid chars with '-'
return `${adjustedCmd.slice(1).toLowerCase()}`; // replace any invalid chars with '-'
// return `/${adjustedCmd.slice(1).toLowerCase().replace(CMD_REGEX, "-")}`
}, },
get: async function (clause = {}) { get: async function (clause = {}) {

2
server/utils/chats/commands/reset.js

@ -19,7 +19,7 @@ async function resetMemory(
return { return {
uuid: msgUUID, uuid: msgUUID,
type: "textResponse", type: "textResponse",
textResponse: "Workspace chat memory was reset!",
textResponse: "清空聊天记录!",
sources: [], sources: [],
close: true, close: true,
error: false, error: false,

Loading…
Cancel
Save