Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
sdream-ai-fe
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
侯明涛
sdream-ai-fe
Commits
bc0509b3
Commit
bc0509b3
authored
Jun 18, 2026
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:引入sdk方法
parent
6992b396
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
273 additions
and
4 deletions
+273
-4
rsbuild.config.ts
+14
-0
src/api/sdkChat.ts
+128
-0
src/config/env.ts
+12
-0
src/index.tsx
+51
-3
src/pages/Chat/Chat.tsx
+2
-1
src/utils/sdkLoader.ts
+66
-0
No files found.
rsbuild.config.ts
View file @
bc0509b3
...
...
@@ -8,6 +8,10 @@ import { envConf } from './src/config/env'
const
mode
=
process
.
env
.
MODE
as
EnvConfKey
||
'dev'
const
apiUrl
=
envConf
[
mode
].
apiUrl
||
''
const
proxyUrl
=
envConf
[
mode
].
proxyUrl
||
''
const
sdkCode
=
envConf
[
mode
].
sdkCode
||
''
const
sdkChannel
=
envConf
[
mode
].
sdkChannel
||
''
const
sdkMock
=
envConf
[
mode
].
sdkMock
||
false
const
sdkApiBaseUrl
=
envConf
[
mode
].
sdkApiBaseUrl
||
''
// 处理 VITE_ 前缀的环境变量
const
viteEnvVars
:
Record
<
string
,
string
>
=
{}
...
...
@@ -50,10 +54,20 @@ export default defineConfig({
font
:
'assets'
,
media
:
'assets'
,
},
copy
:
[
{
from
:
'./src/sdk/'
,
to
:
'./sdk/'
,
},
],
},
source
:
{
define
:
{
'import.meta.env.MODE'
:
JSON
.
stringify
(
mode
),
'import.meta.env.VITE_SDK_CODE'
:
JSON
.
stringify
(
sdkCode
),
'import.meta.env.VITE_SDK_CHANNEL'
:
JSON
.
stringify
(
sdkChannel
),
'import.meta.env.VITE_SDK_MOCK'
:
JSON
.
stringify
(
sdkMock
),
'import.meta.env.VITE_SDK_API_BASE_URL'
:
JSON
.
stringify
(
sdkApiBaseUrl
),
...
viteEnvVars
,
},
},
...
...
src/api/sdkChat.ts
0 → 100644
View file @
bc0509b3
export
function
fetchStreamResponse
(
url
:
string
,
body
:
Record
<
string
,
any
>
,
onMessage
:
(
msg
:
any
)
=>
void
,
signal
?:
AbortSignal
,
):
Promise
<
void
>
{
const
ChatSDK
=
(
window
as
any
).
ChatSDK
if
(
ChatSDK
&&
typeof
ChatSDK
.
fetchStreamResponse
===
'function'
)
{
return
ChatSDK
.
fetchStreamResponse
(
url
,
body
,
onMessage
,
signal
)
}
const
STREAM_TIMEOUT_MS
=
30
*
60
*
1000
body
.
stream
=
true
const
decoder
=
new
TextDecoder
(
'utf-8'
)
let
buffer
=
''
let
dataMsgBuffer
=
''
const
controller
=
new
AbortController
()
const
timeoutId
=
setTimeout
(()
=>
controller
.
abort
(),
STREAM_TIMEOUT_MS
)
if
(
signal
)
{
signal
.
addEventListener
(
'abort'
,
()
=>
controller
.
abort
())
}
const
effectiveSignal
=
controller
.
signal
const
cleanup
=
()
=>
clearTimeout
(
timeoutId
)
return
new
Promise
<
void
>
((
resolve
,
reject
)
=>
{
function
processMessage
(
reader
:
any
)
{
reader
.
read
().
then
((
content
:
any
)
=>
{
if
(
effectiveSignal
.
aborted
)
{
cleanup
()
resolve
()
return
}
buffer
+=
decoder
.
decode
(
content
.
value
,
{
stream
:
!
content
.
done
})
const
lines
=
buffer
.
split
(
'
\
n'
)
buffer
=
lines
.
pop
()
as
string
lines
.
forEach
((
line
)
=>
{
if
(
line
===
''
)
{
try
{
onMessage
({
type
:
'DATA'
,
content
:
JSON
.
parse
(
dataMsgBuffer
),
})
}
catch
{
}
dataMsgBuffer
=
''
return
}
const
[
type
]
=
line
.
split
(
':'
,
1
)
const
content
=
line
.
substring
(
type
.
length
+
1
)
if
(
type
===
'data'
)
{
dataMsgBuffer
+=
content
.
trim
()
}
else
if
(
type
===
''
&&
content
!==
''
)
{
onMessage
({
type
:
'COMMENT'
,
content
:
content
.
trim
(),
})
}
else
{
onMessage
({
type
,
content
:
content
.
trim
(),
})
}
})
if
(
!
content
.
done
)
{
processMessage
(
reader
)
}
else
{
cleanup
()
resolve
()
}
}).
catch
((
error
:
unknown
)
=>
{
if
(
error
instanceof
Error
&&
error
.
name
===
'AbortError'
)
{
cleanup
()
resolve
()
return
}
onMessage
({
type
:
'ERROR'
,
content
:
error
})
cleanup
()
reject
(
error
)
})
}
const
tokenStr
=
window
.
localStorage
.
getItem
(
'__TOKEN__'
)
||
'""'
let
token
=
''
try
{
token
=
JSON
.
parse
(
tokenStr
)
}
catch
{
token
=
''
}
fetch
(
url
,
{
headers
:
{
'accept'
:
'text/event-stream'
,
'Content-Type'
:
'application/json'
,
'X-Token'
:
token
,
},
method
:
'POST'
,
body
:
JSON
.
stringify
(
body
),
signal
:
effectiveSignal
,
})
.
then
((
response
)
=>
{
return
response
.
body
?.
getReader
()
})
.
then
((
reader
)
=>
{
if
(
!
reader
)
{
cleanup
()
reject
(
new
Error
(
'Failed to get reader from response'
))
return
}
return
processMessage
(
reader
)
})
.
catch
((
error
:
unknown
)
=>
{
if
(
error
instanceof
Error
&&
error
.
name
===
'AbortError'
)
{
cleanup
()
resolve
()
return
}
onMessage
({
type
:
'ERROR'
,
content
:
error
})
cleanup
()
reject
(
error
)
})
})
}
src/config/env.ts
View file @
bc0509b3
...
...
@@ -2,14 +2,26 @@ export const envConf = {
dev
:
{
apiUrl
:
'/api'
,
proxyUrl
:
'http://43.143.240.58:19002/dev-sdream-api'
,
sdkCode
:
'dev_code'
,
sdkChannel
:
'dev_channel'
,
sdkMock
:
true
,
sdkApiBaseUrl
:
'http://43.143.240.58:19002/dev-sdream-api'
,
},
sit
:
{
apiUrl
:
'/api'
,
proxyUrl
:
'http://43.143.240.58:19002/dev-sdream-api'
,
sdkCode
:
'sit_code'
,
sdkChannel
:
'sit_channel'
,
sdkMock
:
false
,
sdkApiBaseUrl
:
'http://43.143.240.58:19002/dev-sdream-api'
,
},
prod
:
{
apiUrl
:
'http://43.143.240.58:19002/dev-sdream-api'
,
proxyUrl
:
'http://43.143.240.58:19002/dev-sdream-api'
,
sdkCode
:
'prod_code'
,
sdkChannel
:
'prod_channel'
,
sdkMock
:
false
,
sdkApiBaseUrl
:
'http://43.143.240.58:19002/dev-sdream-api'
,
},
}
...
...
src/index.tsx
View file @
bc0509b3
...
...
@@ -10,7 +10,6 @@ const rootEl = document.getElementById('root')
document
.
documentElement
.
classList
.
add
(
'light'
)
// 添加 Object.hasOwn 的 polyfill
if
(
!
Object
.
hasOwn
)
{
Object
.
defineProperty
(
Object
,
'hasOwn'
,
{
value
(
object
:
any
,
property
:
PropertyKey
)
{
...
...
@@ -24,13 +23,62 @@ if (!Object.hasOwn) {
writable
:
true
,
})
}
// printText2Console()
if
(
rootEl
)
{
async
function
loadSDK
():
Promise
<
void
>
{
return
new
Promise
((
resolve
)
=>
{
const
checkAndInitSDK
=
()
=>
{
// const ChatSDK = (window as any).ChatSDK
// if (ChatSDK && ChatSDK.createChatSDK) {
// const toolId = typeof window !== 'undefined' ? sessionStorage.getItem('currentToolId') : null
// console.log('[SDK] toolId:', toolId)
// const config = {
// code: import.meta.env.VITE_SDK_CODE || 'default_code',
// channel: import.meta.env.VITE_SDK_CHANNEL || 'default_channel',
// toolId,
// mock: import.meta.env.VITE_SDK_MOCK === 'true',
// apiBaseUrl: import.meta.env.VITE_SDK_API_BASE_URL,
// }
// try {
// console.error('[SDK] 初始化')
// } catch (error) {
// console.error('[SDK] 初始化失败:', error)
// }
// resolve()
// return true
// }
return
false
}
if
(
checkAndInitSDK
())
{
return
}
const
script
=
document
.
createElement
(
'script'
)
script
.
src
=
'/sdream-ai/sdk/index.js'
script
.
type
=
'text/javascript'
script
.
onload
=
()
=>
{
checkAndInitSDK
()
}
script
.
onerror
=
(
event
)
=>
{
console
.
error
(
'[SDK] ChatSDK 脚本加载失败:'
,
event
)
console
.
warn
(
'[SDK] 将使用原生实现'
)
resolve
()
}
document
.
body
.
appendChild
(
script
)
})
}
async
function
initApp
()
{
await
loadSDK
()
if
(
rootEl
)
{
const
root
=
ReactDOM
.
createRoot
(
rootEl
)
root
.
render
(
<
HeroUIProvider
className=
"h-full"
>
<
App
/>
</
HeroUIProvider
>,
)
}
}
initApp
()
src/pages/Chat/Chat.tsx
View file @
bc0509b3
...
...
@@ -13,7 +13,8 @@ import { trimSpacesOnly } from './components/ChatItem/markdownFormatter'
import
{
ChatEditor
}
from
'@/components/ChatEditor'
import
type
{
Answer
,
ChatRecord
,
OriginalRecord
}
from
'@/types/chat'
import
{
fetchSessionConversationId
,
fetchUserQaRecordPage
}
from
'@/api/conversation'
import
{
fetchCheckTokenApi
,
fetchStreamResponse
}
from
'@/api/chat'
import
{
fetchCheckTokenApi
}
from
'@/api/chat'
import
{
fetchStreamResponse
}
from
'@/api/sdkChat'
import
{
clearCurrentToolId
,
clearShouldSendQuestion
,
exitBusinessInsightSubWorkflow
,
fetchConversations
,
setBusinessInsightMainWorkflow
,
setBusinessInsightPendingQuestion
,
setBusinessInsightSubWorkflow
,
setCurrentToolId
,
updateBusinessInsightParamMap
}
from
'@/store/conversationSlice'
import
{
getUserRolesForApi
,
safeSessionStorageGetItem
,
waitForToken
}
from
'@/lib/utils'
import
{
findToolRowBySessionToolId
,
getFirstToolListRow
,
readToolListFromSessionStorage
,
resolveSubmitQuestionToolPair
}
from
'@/lib/toolRoleRecordTypes'
...
...
src/utils/sdkLoader.ts
0 → 100644
View file @
bc0509b3
interface
ChatSDKConfig
{
code
:
string
channel
:
string
toolId
?:
string
apiBaseUrl
?:
string
mock
?:
boolean
isDesktop
?:
boolean
}
interface
ChatSDKInstance
{
speak
:
(
text
:
string
)
=>
void
stopSpeak
:
()
=>
void
destroy
:
()
=>
void
}
let
sdkInstance
:
ChatSDKInstance
|
null
=
null
let
sdkLoadingPromise
:
Promise
<
void
>
|
null
=
null
export
async
function
loadChatSDK
(
config
:
ChatSDKConfig
):
Promise
<
ChatSDKInstance
|
null
>
{
if
(
sdkInstance
)
{
return
sdkInstance
}
if
(
sdkLoadingPromise
)
{
await
sdkLoadingPromise
return
sdkInstance
}
sdkLoadingPromise
=
new
Promise
((
resolve
)
=>
{
const
script
=
document
.
createElement
(
'script'
)
script
.
src
=
'/sdream-ai/sdk/index.js'
script
.
onload
=
()
=>
{
try
{
const
ChatSDK
=
(
window
as
any
).
ChatSDK
if
(
ChatSDK
&&
ChatSDK
.
createChatSDK
)
{
sdkInstance
=
ChatSDK
.
createChatSDK
(
config
)
console
.
log
(
'[SDK] toolId:'
,
config
.
toolId
)
}
}
catch
(
error
)
{
console
.
error
(
'[SDK] 初始化失败:'
,
error
)
}
resolve
()
}
script
.
onerror
=
()
=>
{
console
.
error
(
'[SDK] ChatSDK 脚本加载失败'
)
resolve
()
}
document
.
body
.
appendChild
(
script
)
})
await
sdkLoadingPromise
return
sdkInstance
}
export
function
getSDKInstance
():
ChatSDKInstance
|
null
{
return
sdkInstance
}
export
function
destroySDK
():
void
{
if
(
sdkInstance
)
{
sdkInstance
.
destroy
()
sdkInstance
=
null
}
sdkLoadingPromise
=
null
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment