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
0db97af0
Commit
0db97af0
authored
Nov 30, 2025
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 路由拼接参数控制权限&&推荐问样式图标
parent
2d419f61
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
58 additions
and
17 deletions
+58
-17
src/api/home.ts
+6
-3
src/assets/smart-ice.png
+0
-0
src/components/ChatEditor/index.tsx
+28
-8
src/layouts/HistoryBar/components/HistoryBarList/index.tsx
+9
-1
src/pages/Chat/components/ChatItem/ChatAnswerRecommend.tsx
+12
-2
src/pages/Home/HomeNew.tsx
+2
-2
src/pages/Home/components/QuestionList/QuestionList.tsx
+1
-1
No files found.
src/api/home.ts
View file @
0db97af0
...
@@ -10,10 +10,13 @@ export function fetchQuestionList(data: any) {
...
@@ -10,10 +10,13 @@ export function fetchQuestionList(data: any) {
/**
/**
* 查询工具列表
* 查询工具列表
* @params params.userRoles: 角色,用于按角色返回工具
* @params params.userRoles: 角色
数组
,用于按角色返回工具
*/
*/
export
function
fetchToolList
(
params
?:
{
userRoles
?:
string
})
{
export
function
fetchToolList
(
params
?:
{
userRoles
?:
string
[]
})
{
const
requestBody
:
Record
<
string
,
string
>
=
{
toolType
:
'03'
}
const
requestBody
:
Record
<
string
,
string
|
string
[]
>
=
{
toolType
:
'03'
,
userRoles
:
[],
}
if
(
params
?.
userRoles
)
if
(
params
?.
userRoles
)
requestBody
.
userRoles
=
params
.
userRoles
requestBody
.
userRoles
=
params
.
userRoles
return
http
.
post
(
'/config-center/api/tool/mobile/v1/get_tool_list'
,
requestBody
)
return
http
.
post
(
'/config-center/api/tool/mobile/v1/get_tool_list'
,
requestBody
)
...
...
src/assets/smart-ice.png
View file @
0db97af0
This diff was suppressed by a .gitattributes entry.
src/components/ChatEditor/index.tsx
View file @
0db97af0
...
@@ -10,13 +10,27 @@ import { useAppDispatch, useAppSelector } from '@/store/hook'
...
@@ -10,13 +10,27 @@ import { useAppDispatch, useAppSelector } from '@/store/hook'
import
{
fetchToolList
}
from
'@/api/home'
import
{
fetchToolList
}
from
'@/api/home'
import
{
clearCurrentToolId
,
createConversation
,
setCurrentToolId
}
from
'@/store/conversationSlice'
import
{
clearCurrentToolId
,
createConversation
,
setCurrentToolId
}
from
'@/store/conversationSlice'
function
getUserRole
FromRoute
()
{
function
getUserRole
sFromRoute
():
string
[]
{
try
{
try
{
const
searchParams
=
new
URLSearchParams
(
window
.
location
.
search
)
const
searchParams
=
new
URLSearchParams
(
window
.
location
.
search
)
return
searchParams
.
get
(
'userRoles'
)
||
undefined
const
rolesFromRepeatedKeys
=
searchParams
.
getAll
(
'userRoles'
).
filter
(
Boolean
)
if
(
rolesFromRepeatedKeys
.
length
)
return
Array
.
from
(
new
Set
(
rolesFromRepeatedKeys
))
const
commaSeparated
=
searchParams
.
get
(
'userRoles'
)
if
(
commaSeparated
)
{
const
roles
=
commaSeparated
.
split
(
','
)
.
map
(
role
=>
role
.
trim
())
.
filter
(
Boolean
)
if
(
roles
.
length
)
return
Array
.
from
(
new
Set
(
roles
))
}
return
[]
}
}
catch
{
catch
{
return
undefined
return
[]
}
}
}
}
...
@@ -24,7 +38,7 @@ interface ChatEditorProps {
...
@@ -24,7 +38,7 @@ interface ChatEditorProps {
onChange
?:
(
value
:
string
)
=>
void
onChange
?:
(
value
:
string
)
=>
void
onFocus
?:
()
=>
void
onFocus
?:
()
=>
void
onSubmit
?:
(
value
:
string
,
toolId
?:
string
)
=>
void
onSubmit
?:
(
value
:
string
,
toolId
?:
string
)
=>
void
onToolClick
?:
(
isToolBtn
:
boolean
,
toolId
?:
string
,
shouldChangeStyle
?:
boolean
)
=>
void
onToolClick
?:
(
isToolBtn
:
boolean
,
toolId
?:
string
,
toolName
?:
string
,
shouldChangeStyle
?:
boolean
)
=>
void
placeholders
:
string
[]
placeholders
:
string
[]
showContentTips
?:
boolean
showContentTips
?:
boolean
initialValue
?:
string
initialValue
?:
string
...
@@ -47,8 +61,8 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -47,8 +61,8 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 获取工具列表
// 获取工具列表
const
getToolList
=
async
()
=>
{
const
getToolList
=
async
()
=>
{
try
{
try
{
const
userRoles
=
getUserRoleFromRoute
()
const
userRoles
=
getUserRole
s
FromRoute
()
const
res
=
await
fetchToolList
(
userRoles
?
{
userRoles
}
:
undefined
)
const
res
=
await
fetchToolList
(
{
userRoles
}
)
if
(
res
?.
data
)
{
if
(
res
?.
data
)
{
// 根据 toolId 去重,防止重复渲染
// 根据 toolId 去重,防止重复渲染
const
uniqueList
=
res
.
data
.
filter
((
tool
:
any
,
index
:
number
,
self
:
any
[])
=>
const
uniqueList
=
res
.
data
.
filter
((
tool
:
any
,
index
:
number
,
self
:
any
[])
=>
...
@@ -155,7 +169,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -155,7 +169,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
shouldNavigate
:
true
,
shouldNavigate
:
true
,
shouldSendQuestion
:
''
,
shouldSendQuestion
:
''
,
})).
unwrap
()
})).
unwrap
()
onToolClick
?.(
true
,
undefined
,
false
)
onToolClick
?.(
true
,
undefined
,
'通用模式'
,
false
)
}
}
catch
(
error
)
{
catch
(
error
)
{
console
.
error
(
'创建会话失败:'
,
error
)
console
.
error
(
'创建会话失败:'
,
error
)
...
@@ -166,6 +180,12 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -166,6 +180,12 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const
handleToolClick
=
async
(
tool
:
any
)
=>
{
const
handleToolClick
=
async
(
tool
:
any
)
=>
{
if
(
!
checkAuth
())
if
(
!
checkAuth
())
return
return
if
(
tool
.
toolName
===
'数据助手'
)
{
sessionStorage
.
setItem
(
'showToolQuestion'
,
'true'
)
}
else
{
sessionStorage
.
removeItem
(
'showToolQuestion'
)
}
dispatch
(
setCurrentToolId
(
tool
.
toolId
))
dispatch
(
setCurrentToolId
(
tool
.
toolId
))
setSelectedToolId
(
tool
.
toolId
)
setSelectedToolId
(
tool
.
toolId
)
setIsToolBtnActive
(
false
)
setIsToolBtnActive
(
false
)
...
@@ -175,7 +195,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -175,7 +195,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
shouldNavigate
:
true
,
shouldNavigate
:
true
,
shouldSendQuestion
:
''
,
shouldSendQuestion
:
''
,
})).
unwrap
()
})).
unwrap
()
onToolClick
?.(
false
,
tool
.
toolId
,
true
)
onToolClick
?.(
false
,
tool
.
toolId
,
t
ool
.
toolName
,
t
rue
)
}
}
catch
(
error
)
{
catch
(
error
)
{
console
.
error
(
'创建会话失败:'
,
error
)
console
.
error
(
'创建会话失败:'
,
error
)
...
...
src/layouts/HistoryBar/components/HistoryBarList/index.tsx
View file @
0db97af0
...
@@ -5,9 +5,10 @@ import { useEffect, useState } from 'react'
...
@@ -5,9 +5,10 @@ import { useEffect, useState } from 'react'
import
{
useDebounceFn
}
from
'ahooks'
import
{
useDebounceFn
}
from
'ahooks'
import
{
containerVariants
,
itemVariants
}
from
'../../motionAnimate'
import
{
containerVariants
,
itemVariants
}
from
'../../motionAnimate'
import
EmptyIcon
from
'@/assets/svg/empty.svg?react'
import
EmptyIcon
from
'@/assets/svg/empty.svg?react'
import
{
useAppSelector
}
from
'@/store/hook'
import
{
useApp
Dispatch
,
useApp
Selector
}
from
'@/store/hook'
import
type
{
Conversation
}
from
'@/types/conversation'
import
type
{
Conversation
}
from
'@/types/conversation'
import
{
processConversationData
}
from
'@/store/conversationSlice.helper'
import
{
processConversationData
}
from
'@/store/conversationSlice.helper'
import
{
clearCurrentToolId
,
setCurrentToolId
}
from
'@/store/conversationSlice'
import
{
isMobile
}
from
'@/utils'
import
{
isMobile
}
from
'@/utils'
interface
HistoryBarListProps
{
interface
HistoryBarListProps
{
...
@@ -19,11 +20,18 @@ export const HistoryBarList: React.FC<HistoryBarListProps> = ({ searchValue, onS
...
@@ -19,11 +20,18 @@ export const HistoryBarList: React.FC<HistoryBarListProps> = ({ searchValue, onS
const
navigate
=
useNavigate
()
const
navigate
=
useNavigate
()
const
{
currentConversationId
,
conversations
}
=
useAppSelector
(
state
=>
state
.
conversation
)
const
{
currentConversationId
,
conversations
}
=
useAppSelector
(
state
=>
state
.
conversation
)
const
[
allItems
,
setAllItems
]
=
useState
<
Conversation
[]
>
([])
const
[
allItems
,
setAllItems
]
=
useState
<
Conversation
[]
>
([])
const
dispatch
=
useAppDispatch
()
const
handleClick
=
(
conversation
:
Conversation
)
=>
{
const
handleClick
=
(
conversation
:
Conversation
)
=>
{
if
(
isMobile
())
{
if
(
isMobile
())
{
onSetHistoryVisible
(
false
)
onSetHistoryVisible
(
false
)
}
}
if
(
conversation
.
toolId
)
{
dispatch
(
setCurrentToolId
(
conversation
.
toolId
))
}
else
{
dispatch
(
clearCurrentToolId
())
}
// 直接导航到历史记录,不设置shouldSendQuestion
// 直接导航到历史记录,不设置shouldSendQuestion
navigate
(
`/chat/
${
conversation
.
conversationId
}
`
)
navigate
(
`/chat/
${
conversation
.
conversationId
}
`
)
}
}
...
...
src/pages/Chat/components/ChatItem/ChatAnswerRecommend.tsx
View file @
0db97af0
...
@@ -24,6 +24,16 @@ export const ChatAnswerRecommend: React.FC<ChatAnswerRecommendProps> = ({ answer
...
@@ -24,6 +24,16 @@ export const ChatAnswerRecommend: React.FC<ChatAnswerRecommendProps> = ({ answer
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
!
isGet
)
{
if
(
!
isGet
)
{
isGet
=
true
isGet
=
true
if
(
typeof
window
===
'undefined'
)
{
return
}
const
shouldSkipFetch
=
sessionStorage
.
getItem
(
'showToolQuestion'
)
===
'true'
if
(
shouldSkipFetch
)
{
return
// skip calling recommend API when tool question mode is enabled
}
getAnswerRecommend
()
getAnswerRecommend
()
}
}
},
[])
},
[])
...
@@ -32,8 +42,8 @@ export const ChatAnswerRecommend: React.FC<ChatAnswerRecommendProps> = ({ answer
...
@@ -32,8 +42,8 @@ export const ChatAnswerRecommend: React.FC<ChatAnswerRecommendProps> = ({ answer
{
!
loading
&&
questionList
.
length
!==
0
&&
questionList
.
length
>
0
&&
(
{
!
loading
&&
questionList
.
length
!==
0
&&
questionList
.
length
>
0
&&
(
<
div
className=
"flex flex-col gap-[8px]"
>
<
div
className=
"flex flex-col gap-[8px]"
>
{
{
questionList
.
map
(
(
item
,
index
)
=>
(
questionList
.
map
(
item
=>
(
<
Button
onPress=
{
()
=>
onSubmitQuestion
(
item
)
}
key=
{
i
ndex
}
color=
"primary"
variant=
"light"
className=
"text-left bg-[#fff] w-fit max-w-full text-[#333] rounded-[8px] data-[hover=true]:bg-[#F6F6F8] data-[hover=true]:text-[#333]"
>
<
Button
onPress=
{
()
=>
onSubmitQuestion
(
item
)
}
key=
{
i
tem
}
color=
"primary"
variant=
"light"
className=
"text-left bg-[#fff] w-fit max-w-full text-[#333] rounded-[8px] data-[hover=true]:bg-[#F6F6F8] data-[hover=true]:text-[#333]"
>
<
div
className=
"w-full sm:w-full text-nowrap text-ellipsis overflow-hidden"
>
<
div
className=
"w-full sm:w-full text-nowrap text-ellipsis overflow-hidden"
>
{
item
}
{
item
}
</
div
>
</
div
>
...
...
src/pages/Home/HomeNew.tsx
View file @
0db97af0
...
@@ -210,7 +210,7 @@ export const Home: React.FC = () => {
...
@@ -210,7 +210,7 @@ export const Home: React.FC = () => {
{
/* 左侧区域 - 产品问答和您可以试着问我 */
}
{
/* 左侧区域 - 产品问答和您可以试着问我 */
}
<
div
<
div
className=
"flex flex-col gap-[20px] items-center overflow-y-auto scrollbar-hide"
className=
"flex flex-col gap-[20px] items-center overflow-y-auto scrollbar-hide"
style=
{
{
height
:
shouldChangeStyle
?
'calc(-64px + 100vh)'
:
'500px'
,
background
:
shouldChangeStyle
?
'linear-gradient(180deg, #
F0F8
FF 0%, #FFFFFF 50%, #FFFFFF 100%)'
:
''
,
borderRadius
:
'24px'
}
}
style=
{
{
height
:
shouldChangeStyle
?
'calc(-64px + 100vh)'
:
'500px'
,
background
:
shouldChangeStyle
?
'linear-gradient(180deg, #
DEF6
FF 0%, #FFFFFF 50%, #FFFFFF 100%)'
:
''
,
borderRadius
:
'24px'
}
}
>
>
{
/* {!shouldChangeStyle && (
{
/* {!shouldChangeStyle && (
<motion.div className="w-full sm:w-auto" {...getAnimationProps(2)}>
<motion.div className="w-full sm:w-auto" {...getAnimationProps(2)}>
...
@@ -229,7 +229,7 @@ export const Home: React.FC = () => {
...
@@ -229,7 +229,7 @@ export const Home: React.FC = () => {
<
QuestionList
<
QuestionList
questions=
{
otherQuestions
.
content
}
questions=
{
otherQuestions
.
content
}
dotColor=
"#CBECFF"
dotColor=
"#CBECFF"
background=
"linear-gradient(180deg, #
F0F8
FF 0%, #FFFFFF 50%, #FFFFFF 100%)"
background=
"linear-gradient(180deg, #
DEF6
FF 0%, #FFFFFF 50%, #FFFFFF 100%)"
height=
{
shouldChangeStyle
?
'288px'
:
'auto'
}
height=
{
shouldChangeStyle
?
'288px'
:
'auto'
}
title=
{
otherQuestions
.
configName
}
title=
{
otherQuestions
.
configName
}
iconImg=
{
HomeIcon2
}
iconImg=
{
HomeIcon2
}
...
...
src/pages/Home/components/QuestionList/QuestionList.tsx
View file @
0db97af0
...
@@ -124,7 +124,7 @@ const QuestionListBase: React.FC<QuestionListProps & WithAuthProps> = ({
...
@@ -124,7 +124,7 @@ const QuestionListBase: React.FC<QuestionListProps & WithAuthProps> = ({
},
[
updateDisplayedItems
])
},
[
updateDisplayedItems
])
return
(
return
(
<
div
<
div
className=
"bg-white box-border px-[20px] py-[12px]
rounded-[24px]
w-full sm:w-[300px] md:w-[300px]"
className=
"bg-white box-border px-[20px] py-[12px] w-full sm:w-[300px] md:w-[300px]"
style=
{
{
background
,
height
}
}
style=
{
{
background
,
height
}
}
>
>
<
h3
className=
"flex items-center justify-between whitespace-nowrap"
>
<
h3
className=
"flex items-center justify-between whitespace-nowrap"
>
...
...
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