diff --git a/apps/agent/src/page/WorkSpace/AI/components/MarkdownMessage/CustomImage/index.tsx b/apps/agent/src/page/WorkSpace/AI/components/MarkdownMessage/CustomImage/index.tsx
index 64444a63..d0ed3642 100644
--- a/apps/agent/src/page/WorkSpace/AI/components/MarkdownMessage/CustomImage/index.tsx
+++ b/apps/agent/src/page/WorkSpace/AI/components/MarkdownMessage/CustomImage/index.tsx
@@ -1,17 +1,16 @@
import Icon from "@ant-design/icons"
import { App, Button, Image, ImageProps, Tooltip } from "antd"
-import { FC } from "react"
+import { FC, useState } from "react"
import { DownloadIcon } from "@illa-public/icon"
+import imageLoadErrSrc from "@/assets/agent/imageLoadErr.svg"
import { handleDownloadFiles } from "@/utils/drive/download"
-import { MarkdownMessageProps } from "../interface"
-import { downloadIconStyle, imageContainerStyle } from "./style"
+import { downloadIconStyle, imageContainerStyle, imageStyle } from "./style"
-const CustomImage: FC<
- ImageProps & Pick
-> = ({ alt, src, isOwnMessage }) => {
+const CustomImage: FC = ({ alt, src }) => {
const { message } = App.useApp()
const URL = new URLSearchParams(src)
const fileName = URL.get("fileName")
+ const [isExpired, setIsExpired] = useState(false)
const handleDownload = () => {
if (!src) {
@@ -25,14 +24,34 @@ const CustomImage: FC<
name: fileName,
downloadURL: src,
}
- handleDownloadFiles([fileInfo])
+ handleDownloadFiles([fileInfo]).catch((e) => {
+ console.log("download", e)
+ })
}
const contentBody = (
-
+
+ }
+ onError={() => setIsExpired(true)}
+ />
)
- return isOwnMessage || !fileName ? (
+ return !fileName || isExpired ? (
contentBody
) : (
{
+ if (isExpired) {
+ return {
+ width: "120px",
+ height: "120px",
+ borderRadius: "8px",
+ }
+ } else {
+ return {
+ width: "100%",
+ minWidth: "120px",
+ minHeight: "120px",
+ borderRadius: "12px",
+ }
+ }
+}
diff --git a/apps/agent/src/page/WorkSpace/AI/components/MarkdownMessage/index.tsx b/apps/agent/src/page/WorkSpace/AI/components/MarkdownMessage/index.tsx
index d58cf4d9..e890dc9e 100644
--- a/apps/agent/src/page/WorkSpace/AI/components/MarkdownMessage/index.tsx
+++ b/apps/agent/src/page/WorkSpace/AI/components/MarkdownMessage/index.tsx
@@ -96,9 +96,7 @@ export const MarkdownMessage = memo((props: MarkdownMessageProps) => {
isReceiving={isReceiving}
/>
),
- img: ({ src, alt }) => (
-
- ),
+ img: ({ src, alt }) => ,
}}
>
{handleParseText(children ?? "", isOwnMessage)}
diff --git a/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/components/FileContent/index.tsx b/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/components/FileContent/index.tsx
new file mode 100644
index 00000000..fc6af266
--- /dev/null
+++ b/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/components/FileContent/index.tsx
@@ -0,0 +1,76 @@
+import Icon from "@ant-design/icons"
+import { Button, Tooltip } from "antd"
+import { FC, useState } from "react"
+import { useTranslation } from "react-i18next"
+import { DownloadIcon, getFileIconByContentType } from "@illa-public/icon"
+import { GCS_OBJECT_TYPE } from "@illa-public/public-types"
+import { handleDownloadFiles } from "@/utils/drive/download"
+import { IFileContentProps } from "./interface"
+import {
+ errorInfoStyle,
+ fileCardContainerStyle,
+ fileInfoStyle,
+ fileNameStyle,
+ fileTypeIconStyle,
+} from "./style"
+
+const FileContent: FC = ({
+ contentType,
+ fileName,
+ downloadURL,
+}) => {
+ const { t } = useTranslation()
+ const [isExpired, setIsExpired] = useState(false)
+ const handleDownload = (downloadURL: string, fileName: string) => {
+ if (!downloadURL || !fileName) {
+ return
+ }
+ const fileInfo = {
+ name: fileName,
+ downloadURL: downloadURL,
+ }
+ handleDownloadFiles([fileInfo]).catch((e) => {
+ console.log("download", e)
+ setIsExpired(true)
+ })
+ }
+ const contentBody = (
+
+ {getFileIconByContentType(
+ GCS_OBJECT_TYPE.FILE,
+ contentType,
+ fileTypeIconStyle,
+ )}
+
+ {fileName}
+ {isExpired && (
+ {t("The document has expired.")}
+ )}
+
+
+ )
+ return !downloadURL || !fileName || isExpired ? (
+ contentBody
+ ) : (
+ }
+ onClick={() => handleDownload(downloadURL, fileName)}
+ size="small"
+ />
+ }
+ >
+ {contentBody}
+
+ )
+}
+
+export default FileContent
diff --git a/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/components/FileContent/interface.ts b/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/components/FileContent/interface.ts
new file mode 100644
index 00000000..db4074f0
--- /dev/null
+++ b/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/components/FileContent/interface.ts
@@ -0,0 +1,5 @@
+export interface IFileContentProps {
+ contentType: string
+ fileName: string
+ downloadURL: string
+}
diff --git a/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/components/FileContent/style.ts b/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/components/FileContent/style.ts
new file mode 100644
index 00000000..7bc2ffa1
--- /dev/null
+++ b/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/components/FileContent/style.ts
@@ -0,0 +1,38 @@
+import { css } from "@emotion/react"
+import { getColor } from "@illa-public/color-scheme"
+
+export const fileCardContainerStyle = css`
+ display: flex;
+ padding: 8px 16px;
+ align-items: center;
+ gap: 4px;
+ border-radius: 16px;
+ border: 1px solid ${getColor("grayBlue", "08")};
+ background: #fafbfc;
+`
+
+export const fileTypeIconStyle = css`
+ width: 24px;
+ height: 30px;
+`
+
+export const fileNameStyle = css`
+ color: ${getColor("grayBlue", "02")};
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 22px;
+ flex: 1;
+`
+
+export const fileInfoStyle = css`
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+`
+
+export const errorInfoStyle = css`
+ color: ${getColor("red", "03")};
+ font-size: 12px;
+ font-weight: 400;
+ line-height: 18px;
+`
diff --git a/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/index.tsx b/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/index.tsx
index feef3235..49ea5bb1 100644
--- a/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/index.tsx
+++ b/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/index.tsx
@@ -1,15 +1,8 @@
import Icon from "@ant-design/icons"
-import { App, Button, Tooltip } from "antd"
+import { App, Tooltip } from "antd"
import { FC, useRef, useState } from "react"
import { useTranslation } from "react-i18next"
-import {
- CopyIcon,
- DownIcon,
- DownloadIcon,
- UpIcon,
- getFileIconByContentType,
-} from "@illa-public/icon"
-import { GCS_OBJECT_TYPE } from "@illa-public/public-types"
+import { CopyIcon, DownIcon, UpIcon } from "@illa-public/icon"
import { copyToClipboard } from "@illa-public/utils"
import LottieItem from "@/components/LottieItem"
import {
@@ -17,9 +10,9 @@ import {
MESSAGE_STATUS,
} from "@/components/PreviewChat/interface"
import tipiRunLoading from "@/config/lottieConfig/tipiRunLoading.json"
-import { handleDownloadFiles } from "@/utils/drive/download"
import MarkdownMessage from "../MarkdownMessage"
import { CODE_STATUS } from "../MarkdownMessage/interface"
+import FileContent from "./components/FileContent"
import { RUN_REQUEST_TYPE } from "./constants"
import {
IImageMessageProps,
@@ -30,9 +23,6 @@ import {
actionIconStyle,
containerStyle,
errorInfoLineStyle,
- fileCardContainerStyle,
- fileNameStyle,
- fileTypeIconStyle,
headerContainerStyle,
iconStyle,
infoContainerStyle,
@@ -208,33 +198,16 @@ export const FileMessageCard: FC = ({ message }) => {
fileInfo = JSON.parse(message)
} catch {}
- const handleDownload = (downloadURL: string, fileName: string) => {
- if (!downloadURL || !fileName) {
- return
- }
- const fileInfo = {
- name: fileName,
- downloadURL: downloadURL,
- }
- handleDownloadFiles([fileInfo])
- }
if (!message) return null
return (
{fileInfo.map(({ contentType, fileName, downloadURL }) => (
-
- {getFileIconByContentType(
- GCS_OBJECT_TYPE.FILE,
- contentType,
- fileTypeIconStyle,
- )}
- {fileName}
- }
- onClick={() => handleDownload(downloadURL, fileName)}
- size="small"
- />
-
+
))}
)
diff --git a/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/style.ts b/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/style.ts
index bdecf726..c7accd9e 100644
--- a/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/style.ts
+++ b/apps/agent/src/page/WorkSpace/AI/components/SyncMessageCard/style.ts
@@ -223,28 +223,5 @@ export const messageListContainerStyle = css`
display: flex;
flex-direction: column;
gap: 8px;
- width: 396px;
-`
-
-export const fileCardContainerStyle = css`
- display: flex;
- padding: 16px;
- align-items: center;
- gap: 4px;
- border-radius: 16px;
- border: 1px solid ${getColor("grayBlue", "08")};
- background: #fafbfc;
-`
-
-export const fileTypeIconStyle = css`
- width: 24px;
- height: 30px;
-`
-
-export const fileNameStyle = css`
- color: ${getColor("grayBlue", "02")};
- font-size: 14px;
- font-weight: 500;
- line-height: 22px;
- flex: 1;
+ width: 264px;
`
diff --git a/apps/agent/src/page/WorkSpace/AI/components/UserMessage/FileContent/index.tsx b/apps/agent/src/page/WorkSpace/AI/components/UserMessage/FileContent/index.tsx
new file mode 100644
index 00000000..1c5d36a2
--- /dev/null
+++ b/apps/agent/src/page/WorkSpace/AI/components/UserMessage/FileContent/index.tsx
@@ -0,0 +1,44 @@
+import { FC } from "react"
+import { useTranslation } from "react-i18next"
+import { getFileIconByContentType } from "@illa-public/icon"
+import { GCS_OBJECT_TYPE, IKnowledgeFile } from "@illa-public/public-types"
+import {
+ errorInfoStyle,
+ fileInfoStyle,
+ fileItemStyle,
+ fileNameStyle,
+ fileTypeIconStyle,
+ iconContainerStyle,
+} from "./style"
+
+interface IFileContentProps
+ extends Pick {
+ isExpired?: boolean
+}
+
+const FileContent: FC = ({
+ contentType,
+ fileName,
+ isExpired,
+}) => {
+ const { t } = useTranslation()
+ return (
+
+
+ {getFileIconByContentType(
+ GCS_OBJECT_TYPE.FILE,
+ contentType,
+ fileTypeIconStyle,
+ )}
+
+
+ {fileName}
+ {isExpired && (
+ {t("The document has expired.")}
+ )}
+
+
+ )
+}
+
+export default FileContent
diff --git a/apps/agent/src/page/WorkSpace/AI/components/UserMessage/FileContent/style.ts b/apps/agent/src/page/WorkSpace/AI/components/UserMessage/FileContent/style.ts
new file mode 100644
index 00000000..f63a130c
--- /dev/null
+++ b/apps/agent/src/page/WorkSpace/AI/components/UserMessage/FileContent/style.ts
@@ -0,0 +1,70 @@
+import { css } from "@emotion/react"
+import { getColor } from "@illa-public/color-scheme"
+import { applyMobileStyle } from "@illa-public/utils"
+
+export const containerStyle = css`
+ gap: 8px;
+ width: 100%;
+ display: flex;
+ justify-content: flex-end;
+ align-items: flex-start;
+ flex-wrap: wrap;
+ ${applyMobileStyle(css`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+ `)}
+`
+
+export const fileItemStyle = css`
+ display: flex;
+ width: 264px;
+ padding: 8px 16px;
+ align-items: center;
+ gap: 4px;
+ align-self: stretch;
+ border-radius: 16px;
+ background: ${getColor("grayBlue", "09")};
+ ${applyMobileStyle(css`
+ width: 100%;
+ `)}
+`
+
+export const iconContainerStyle = css`
+ display: flex;
+ width: 32px;
+ height: 32px;
+ padding: 1px 4px;
+ justify-content: center;
+ align-items: center;
+`
+
+export const fileTypeIconStyle = css`
+ width: 24px;
+ height: 30px;
+`
+
+export const fileNameStyle = css`
+ color: ${getColor("grayBlue", "02")};
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 22px;
+ display: inline-block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+`
+
+export const fileInfoStyle = css`
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+`
+
+export const errorInfoStyle = css`
+ color: ${getColor("red", "03")};
+ font-size: 12px;
+ font-weight: 400;
+ line-height: 18px;
+`
diff --git a/apps/agent/src/page/WorkSpace/AI/components/UserMessage/ShowFiles/index.tsx b/apps/agent/src/page/WorkSpace/AI/components/UserMessage/ShowFiles/index.tsx
index 05c35f59..e12f0eaf 100644
--- a/apps/agent/src/page/WorkSpace/AI/components/UserMessage/ShowFiles/index.tsx
+++ b/apps/agent/src/page/WorkSpace/AI/components/UserMessage/ShowFiles/index.tsx
@@ -1,21 +1,20 @@
import Icon from "@ant-design/icons"
-import { Button } from "antd"
-import { FC } from "react"
-import { DownloadIcon, getFileIconByContentType } from "@illa-public/icon"
-import { GCS_OBJECT_TYPE, IKnowledgeFile } from "@illa-public/public-types"
+import { Button, Tooltip } from "antd"
+import { FC, useState } from "react"
+import { DownloadIcon } from "@illa-public/icon"
+import { IKnowledgeFile } from "@illa-public/public-types"
import { handleDownloadFiles } from "@/utils/drive/download"
-import {
- containerStyle,
- fileItemStyle,
- fileNameStyle,
- fileTypeIconStyle,
- iconContainerStyle,
-} from "./style"
+import FileContent from "../FileContent"
+import { containerStyle } from "./style"
interface ShowFilesProps {
knowledgeFiles: IKnowledgeFile[]
}
-const ShowFiles: FC = ({ knowledgeFiles }) => {
+
+const SingleFile: FC<
+ Pick
+> = ({ downloadURL, fileName, contentType }) => {
+ const [isExpired, setIsExpired] = useState(false)
const handleDownload = (fileName: string, downloadURL: string) => {
if (!downloadURL || !fileName) {
return
@@ -24,27 +23,55 @@ const ShowFiles: FC = ({ knowledgeFiles }) => {
name: fileName,
downloadURL: downloadURL,
}
- handleDownloadFiles([fileInfo])
+ handleDownloadFiles([fileInfo]).catch((e) => {
+ console.log("download", e)
+ setIsExpired(true)
+ })
}
+
+ return isExpired ? (
+
+ ) : (
+ }
+ onClick={() => handleDownload(contentType, downloadURL!)}
+ size="small"
+ />
+ }
+ >
+
+
+ )
+}
+const ShowFiles: FC = ({ knowledgeFiles }) => {
return (
- {knowledgeFiles.map((item) => (
-
-
- {getFileIconByContentType(
- GCS_OBJECT_TYPE.FILE,
- item.contentType,
- fileTypeIconStyle,
- )}
-
- {item.fileName}
- }
- onClick={() => handleDownload(item.fileName, item.downloadURL!)}
- size="small"
+ {knowledgeFiles.map((item) =>
+ item.fileName && item.downloadURL ? (
+
+ ) : (
+
-
- ))}
+ ),
+ )}
)
}
diff --git a/apps/agent/src/page/WorkSpace/AI/components/UserMessage/ShowFiles/style.ts b/apps/agent/src/page/WorkSpace/AI/components/UserMessage/ShowFiles/style.ts
index a85b7b3b..320ea8cc 100644
--- a/apps/agent/src/page/WorkSpace/AI/components/UserMessage/ShowFiles/style.ts
+++ b/apps/agent/src/page/WorkSpace/AI/components/UserMessage/ShowFiles/style.ts
@@ -1,5 +1,4 @@
import { css } from "@emotion/react"
-import { getColor } from "@illa-public/color-scheme"
import { applyMobileStyle } from "@illa-public/utils"
export const containerStyle = css`
@@ -16,43 +15,3 @@ export const containerStyle = css`
align-items: flex-start;
`)}
`
-
-export const fileItemStyle = css`
- display: flex;
- width: 284px;
- padding: 8px;
- align-items: center;
- gap: 4px;
- align-self: stretch;
- border-radius: 16px;
- background: ${getColor("grayBlue", "09")};
- ${applyMobileStyle(css`
- width: 100%;
- `)}
-`
-
-export const iconContainerStyle = css`
- display: flex;
- width: 32px;
- height: 32px;
- padding: 1px 4px;
- justify-content: center;
- align-items: center;
-`
-
-export const fileTypeIconStyle = css`
- width: 24px;
- height: 30px;
-`
-
-export const fileNameStyle = css`
- color: ${getColor("grayBlue", "02")};
- font-size: 14px;
- font-weight: 500;
- line-height: 22px;
- flex: 1;
- display: inline-block;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-`
diff --git a/apps/agent/src/utils/drive/download.ts b/apps/agent/src/utils/drive/download.ts
index e7e3539a..b94f8a73 100644
--- a/apps/agent/src/utils/drive/download.ts
+++ b/apps/agent/src/utils/drive/download.ts
@@ -34,7 +34,13 @@ export const handleDownloadFiles = async (
const { name, downloadURL } = downloadInfo[i]
promise = promise.then(async () => {
try {
- const fileResponse = await fetch(downloadURL)
+ const fileResponse = await fetch(downloadURL, {
+ method: "GET",
+ headers: {
+ "Content-Type": "multipart/form-data",
+ "x-amz-acl": "public-read",
+ },
+ })
if (!asZip && window.WritableStream && fileResponse.body?.pipeTo) {
const fileStream = createWriteStream(name)