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
2b1e4e52
Commit
2b1e4e52
authored
Dec 16, 2025
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 用户分析传参
parent
3895ddce
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
222 additions
and
12 deletions
+222
-12
src/pages/ChatTactics/TacticsChat.tsx
+180
-10
src/pages/ChatTactics/TacticsHome.tsx
+42
-2
No files found.
src/pages/ChatTactics/TacticsChat.tsx
View file @
2b1e4e52
...
@@ -90,6 +90,78 @@ export const TacticsChat: React.FC = () => {
...
@@ -90,6 +90,78 @@ export const TacticsChat: React.FC = () => {
},
[])
},
[])
const
tacticsMeta
=
useMemo
(()
=>
tacticsMetaFromState
||
tacticsMetaFromQuery
||
tacticsMetaFromStorage
,
[
tacticsMetaFromState
,
tacticsMetaFromQuery
,
tacticsMetaFromStorage
])
const
tacticsMeta
=
useMemo
(()
=>
tacticsMetaFromState
||
tacticsMetaFromQuery
||
tacticsMetaFromStorage
,
[
tacticsMetaFromState
,
tacticsMetaFromQuery
,
tacticsMetaFromStorage
])
// 读取 place=user 时的 userMeta 参数
const
userMetaFromState
=
(
location
.
state
as
{
userMeta
?:
any
}
|
null
)?.
userMeta
const
userMetaFromQuery
=
useMemo
(()
=>
{
const
place
=
searchParams
.
get
(
'place'
)
if
(
place
!==
'user'
)
{
return
undefined
}
return
{
place
,
cstId
:
searchParams
.
get
(
'cstId'
)
||
undefined
,
userId
:
searchParams
.
get
(
'userId'
)
||
undefined
,
numberType
:
searchParams
.
get
(
'numberType'
)
||
undefined
,
}
},
[
searchParams
])
const
userMetaFromStorage
=
useMemo
(()
=>
{
const
raw
=
sessionStorage
.
getItem
(
'userMeta'
)
if
(
!
raw
)
{
return
undefined
}
try
{
const
parsed
=
JSON
.
parse
(
raw
)
if
(
parsed
?.
place
===
'user'
)
{
return
parsed
}
}
catch
{
// ignore
}
return
undefined
},
[])
const
userMeta
=
useMemo
(()
=>
userMetaFromState
||
userMetaFromQuery
||
userMetaFromStorage
,
[
userMetaFromState
,
userMetaFromQuery
,
userMetaFromStorage
])
// 根据 userMeta.numberType 与调用类型(自动/正常)计算请求参数用的 numberType(A03/A04...)
const
getNumberTypeWithUserMeta
=
useCallback
(
(
defaultNumberType
:
string
,
isAuto
:
boolean
):
string
=>
{
const
numberType
=
userMeta
?.
numberType
if
(
!
numberType
)
return
defaultNumberType
// numberType 仅在 3~6 时生效,其它保持默认
if
(
isAuto
)
{
// 自动调用
switch
(
numberType
)
{
case
'3'
:
return
'A03'
case
'4'
:
return
'A05'
case
'5'
:
return
'A07'
case
'6'
:
return
'A09'
default
:
return
defaultNumberType
}
}
// 正常问答
switch
(
numberType
)
{
case
'3'
:
return
'A04'
case
'4'
:
return
'A06'
case
'5'
:
return
'A08'
case
'6'
:
return
'A10'
default
:
return
defaultNumberType
}
},
[
userMeta
],
)
const
formatCurrentTime
=
()
=>
{
const
formatCurrentTime
=
()
=>
{
const
date
=
new
Date
()
const
date
=
new
Date
()
const
pad
=
(
value
:
number
)
=>
value
.
toString
().
padStart
(
2
,
'0'
)
const
pad
=
(
value
:
number
)
=>
value
.
toString
().
padStart
(
2
,
'0'
)
...
@@ -241,7 +313,7 @@ export const TacticsChat: React.FC = () => {
...
@@ -241,7 +313,7 @@ export const TacticsChat: React.FC = () => {
question
:
string
|
undefined
,
question
:
string
|
undefined
,
productCode
?:
string
,
productCode
?:
string
,
toolId
?:
string
,
toolId
?:
string
,
extra
?:
{
busiType
?:
string
,
recordType
?:
string
,
includeQuestion
?:
boolean
,
includeTactics
Meta
?:
boolean
},
extra
?:
{
busiType
?:
string
,
recordType
?:
string
,
numberType
?:
string
,
includeQuestion
?:
boolean
,
includeTacticsMeta
?:
boolean
,
includeUser
Meta
?:
boolean
},
)
=>
{
)
=>
{
// 优先读取缓存中的 toolId,再回退到传参
// 优先读取缓存中的 toolId,再回退到传参
const
sessionToolId
=
sessionStorage
.
getItem
(
'currentToolId'
)
??
undefined
const
sessionToolId
=
sessionStorage
.
getItem
(
'currentToolId'
)
??
undefined
...
@@ -293,6 +365,7 @@ export const TacticsChat: React.FC = () => {
...
@@ -293,6 +365,7 @@ export const TacticsChat: React.FC = () => {
const
shouldSendQuestion
=
extra
?.
includeQuestion
!==
false
const
shouldSendQuestion
=
extra
?.
includeQuestion
!==
false
const
shouldIncludeTacticsMeta
=
extra
?.
includeTacticsMeta
!==
false
const
shouldIncludeTacticsMeta
=
extra
?.
includeTacticsMeta
!==
false
const
shouldIncludeUserMeta
=
extra
?.
includeUserMeta
!==
false
// 去除缓存中可能存在的 from 字段,避免作为参数传递
// 去除缓存中可能存在的 from 字段,避免作为参数传递
const
{
from
:
_omitFrom
,
...
safeTacticsMeta
}
=
tacticsMeta
||
{}
const
{
from
:
_omitFrom
,
...
safeTacticsMeta
}
=
tacticsMeta
||
{}
...
@@ -304,8 +377,16 @@ export const TacticsChat: React.FC = () => {
...
@@ -304,8 +377,16 @@ export const TacticsChat: React.FC = () => {
toolId
:
resolvedToolId
,
toolId
:
resolvedToolId
,
...(
extra
?.
busiType
?
{
busiType
:
extra
.
busiType
}
:
{}),
...(
extra
?.
busiType
?
{
busiType
:
extra
.
busiType
}
:
{}),
...(
extra
?.
recordType
?
{
recordType
:
extra
.
recordType
}
:
{}),
...(
extra
?.
recordType
?
{
recordType
:
extra
.
recordType
}
:
{}),
...(
extra
?.
numberType
?
{
numberType
:
extra
.
numberType
}
:
{}),
}
// 优先使用 userMeta,如果存在 userMeta 且需要包含,则传入 userMeta 的字段
// 注意:这里显式剔除 userMeta 自带的 numberType 和 place,避免覆盖映射后的 numberType,并按需去掉 place
if
(
userMeta
&&
shouldIncludeUserMeta
)
{
const
{
numberType
:
_rawNumberType
,
place
:
_omitPlace
,
...
safeUserMeta
}
=
userMeta
Object
.
assign
(
requestBody
,
safeUserMeta
)
}
}
if
(
shouldIncludeTacticsMeta
)
{
// 如果没有 userMeta 或不需要包含 userMeta,则使用 tacticsMeta
else
if
(
tacticsMeta
&&
shouldIncludeTacticsMeta
)
{
Object
.
assign
(
requestBody
,
safeTacticsMeta
)
Object
.
assign
(
requestBody
,
safeTacticsMeta
)
}
}
if
(
shouldSendQuestion
)
{
if
(
shouldSendQuestion
)
{
...
@@ -431,14 +512,34 @@ export const TacticsChat: React.FC = () => {
...
@@ -431,14 +512,34 @@ export const TacticsChat: React.FC = () => {
},
[
dispatch
])
},
[
dispatch
])
const
handleReanalyze
=
useCallback
(
async
()
=>
{
const
handleReanalyze
=
useCallback
(
async
()
=>
{
// 重新触发一次提问,与首次自动调用保持一致:busiType 01 / recordType A02
// 重新触发一次提问,与首次自动调用保持一致:
await
handleSubmitQuestion
(
undefined
,
undefined
,
undefined
,
{
busiType
:
'02'
,
recordType
:
'A02'
,
includeQuestion
:
false
})
// - 无 userMeta:沿用原逻辑,传 recordType=A02,使用 tacticsMeta
// - 有 userMeta:按 userMeta.numberType 映射 numberType(A03/A05/A07/A09),不传 recordType,仅传 userMeta
const
hasUserMeta
=
!!
userMeta
if
(
hasUserMeta
)
{
const
mappedNumberType
=
getNumberTypeWithUserMeta
(
'A02'
,
true
)
await
handleSubmitQuestion
(
undefined
,
undefined
,
undefined
,
{
busiType
:
'02'
,
numberType
:
mappedNumberType
,
includeQuestion
:
false
,
includeTacticsMeta
:
false
,
includeUserMeta
:
true
,
})
}
else
{
await
handleSubmitQuestion
(
undefined
,
undefined
,
undefined
,
{
busiType
:
'02'
,
recordType
:
'A02'
,
includeQuestion
:
false
,
includeTacticsMeta
:
true
,
})
}
// 重新拉取会话列表,保持原有行为
// 重新拉取会话列表,保持原有行为
await
dispatch
(
fetchTacticsConversations
())
await
dispatch
(
fetchTacticsConversations
())
if
(
currentIdRef
.
current
)
{
if
(
currentIdRef
.
current
)
{
navigate
(
`/tactics/chat/
${
currentIdRef
.
current
}
`
)
navigate
(
`/tactics/chat/
${
currentIdRef
.
current
}
`
)
}
}
},
[
dispatch
,
navigate
,
handleSubmitQuestion
])
},
[
dispatch
,
navigate
,
handleSubmitQuestion
,
userMeta
,
getNumberTypeWithUserMeta
])
const
handleCancelClear
=
useCallback
(()
=>
{
const
handleCancelClear
=
useCallback
(()
=>
{
setShowClearConfirm
(
false
)
setShowClearConfirm
(
false
)
...
@@ -485,14 +586,40 @@ export const TacticsChat: React.FC = () => {
...
@@ -485,14 +586,40 @@ export const TacticsChat: React.FC = () => {
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
currentIdRef
.
current
&&
!
isLoading
&&
!
hasAutoSubmittedRef
.
current
)
{
if
(
currentIdRef
.
current
&&
!
isLoading
&&
!
hasAutoSubmittedRef
.
current
)
{
hasAutoSubmittedRef
.
current
=
true
hasAutoSubmittedRef
.
current
=
true
// 进入会话后自动触发一次提交:
// - 无 userMeta:沿用原逻辑,recordType=A02,携带 tacticsMeta
// - 有 userMeta:按 userMeta.numberType 映射 numberType(A03/A05/A07/A09),不传 recordType,仅传 userMeta
const
hasUserMeta
=
!!
userMeta
if
(
hasUserMeta
)
{
const
mappedNumberType
=
getNumberTypeWithUserMeta
(
'A02'
,
true
)
handleSubmitQuestion
(
'策略分析'
,
undefined
,
undefined
,
{
busiType
:
'02'
,
numberType
:
mappedNumberType
,
includeQuestion
:
true
,
includeTacticsMeta
:
false
,
includeUserMeta
:
true
,
},
)
}
else
{
handleSubmitQuestion
(
handleSubmitQuestion
(
'策略分析'
,
'策略分析'
,
undefined
,
undefined
,
undefined
,
undefined
,
{
busiType
:
'02'
,
recordType
:
'A02'
,
includeQuestion
:
true
,
includeTacticsMeta
:
true
},
{
busiType
:
'02'
,
recordType
:
'A02'
,
includeQuestion
:
true
,
includeTacticsMeta
:
true
,
},
)
)
}
}
},
[
isLoading
,
handleSubmitQuestion
,
id
])
}
},
[
isLoading
,
handleSubmitQuestion
,
id
,
userMeta
,
getNumberTypeWithUserMeta
])
// 创建新会话成功后跳转到新会话页面
// 创建新会话成功后跳转到新会话页面
useEffect
(()
=>
{
useEffect
(()
=>
{
...
@@ -501,12 +628,13 @@ export const TacticsChat: React.FC = () => {
...
@@ -501,12 +628,13 @@ export const TacticsChat: React.FC = () => {
state
:
{
state
:
{
shouldSendQuestion
:
shouldSendQuestionFromState
,
shouldSendQuestion
:
shouldSendQuestionFromState
,
tacticsMeta
,
tacticsMeta
,
userMeta
,
},
},
replace
:
true
,
replace
:
true
,
})
})
dispatch
(
clearTacticsNavigationFlag
())
dispatch
(
clearTacticsNavigationFlag
())
}
}
},
[
shouldNavigateToNewConversation
,
currentConversationId
,
navigate
,
dispatch
,
shouldSendQuestionFromState
,
tacticsMeta
])
},
[
shouldNavigateToNewConversation
,
currentConversationId
,
navigate
,
dispatch
,
shouldSendQuestionFromState
,
tacticsMeta
,
userMeta
])
// 处理shouldSendQuestion的变化 - 自动发送问题
// 处理shouldSendQuestion的变化 - 自动发送问题
useEffect
(()
=>
{
useEffect
(()
=>
{
...
@@ -525,11 +653,29 @@ export const TacticsChat: React.FC = () => {
...
@@ -525,11 +653,29 @@ export const TacticsChat: React.FC = () => {
)
{
)
{
lastSentQuestionRef
.
current
=
shouldSendQuestion
lastSentQuestionRef
.
current
=
shouldSendQuestion
dispatch
(
clearTacticsShouldSendQuestion
())
dispatch
(
clearTacticsShouldSendQuestion
())
const
hasUserMeta
=
!!
userMeta
setTimeout
(()
=>
{
setTimeout
(()
=>
{
if
(
hasUserMeta
)
{
const
mappedNumberType
=
getNumberTypeWithUserMeta
(
'A01'
,
false
)
handleSubmitQuestion
(
shouldSendQuestion
,
undefined
,
undefined
,
{
includeQuestion
:
true
,
includeTacticsMeta
:
false
,
includeUserMeta
:
true
,
numberType
:
mappedNumberType
,
},
)
}
else
{
// 无 userMeta:保持原有行为,不传任何 extra(不携带 numberType),由内部默认逻辑处理 tacticsMeta
handleSubmitQuestion
(
shouldSendQuestion
)
handleSubmitQuestion
(
shouldSendQuestion
)
}
},
100
)
},
100
)
}
}
},
[
shouldSendQuestion
,
isLoading
,
dispatch
])
},
[
shouldSendQuestion
,
isLoading
,
dispatch
,
userMeta
,
handleSubmitQuestion
,
getNumberTypeWithUserMeta
])
return
(
return
(
<
div
<
div
...
@@ -666,11 +812,35 @@ export const TacticsChat: React.FC = () => {
...
@@ -666,11 +812,35 @@ export const TacticsChat: React.FC = () => {
currentId
:
currentIdRef
.
current
,
currentId
:
currentIdRef
.
current
,
isLoading
,
isLoading
,
})
})
// 正常问答:
// - 无 userMeta:保持原有逻辑,recordType=A01、busiType=02、不带 numberType
// - 有 userMeta:按 userMeta.numberType 映射 numberType(A04/A06/A08/A10),不传 recordType,仅传 userMeta
const
hasUserMeta
=
!!
userMeta
if
(
hasUserMeta
)
{
const
mappedNumberType
=
getNumberTypeWithUserMeta
(
'A01'
,
false
)
return
handleSubmitQuestion
(
return
handleSubmitQuestion
(
question
,
question
,
undefined
,
undefined
,
undefined
,
undefined
,
{
busiType
:
'02'
,
recordType
:
'A01'
,
includeQuestion
:
true
,
includeTacticsMeta
:
false
},
{
busiType
:
'02'
,
numberType
:
mappedNumberType
,
includeQuestion
:
true
,
includeTacticsMeta
:
false
,
includeUserMeta
:
true
,
},
)
}
return
handleSubmitQuestion
(
question
,
undefined
,
undefined
,
{
busiType
:
'02'
,
recordType
:
'A01'
,
includeQuestion
:
true
,
includeTacticsMeta
:
false
,
},
)
)
}
}
}
}
placeholders=
{
[
''
]
}
placeholders=
{
[
''
]
}
...
...
src/pages/ChatTactics/TacticsHome.tsx
View file @
2b1e4e52
...
@@ -60,6 +60,37 @@ export const TacticsHome: React.FC = () => {
...
@@ -60,6 +60,37 @@ export const TacticsHome: React.FC = () => {
},
[])
},
[])
const
tacticsMeta
=
useMemo
(()
=>
tacticsMetaFromSearch
||
tacticsMetaFromStorage
,
[
tacticsMetaFromSearch
,
tacticsMetaFromStorage
])
const
tacticsMeta
=
useMemo
(()
=>
tacticsMetaFromSearch
||
tacticsMetaFromStorage
,
[
tacticsMetaFromSearch
,
tacticsMetaFromStorage
])
// 读取 place=user 时的 userMeta 参数
const
userMetaFromSearch
=
useMemo
(()
=>
{
const
place
=
searchParams
.
get
(
'place'
)
if
(
place
!==
'user'
)
{
return
undefined
}
return
{
place
,
cstId
:
searchParams
.
get
(
'cstId'
)
||
undefined
,
userId
:
searchParams
.
get
(
'userId'
)
||
undefined
,
numberType
:
searchParams
.
get
(
'numberType'
)
||
undefined
,
}
},
[
searchParams
])
const
userMetaFromStorage
=
useMemo
(()
=>
{
const
raw
=
sessionStorage
.
getItem
(
'userMeta'
)
if
(
!
raw
)
{
return
undefined
}
try
{
const
parsed
=
JSON
.
parse
(
raw
)
if
(
parsed
?.
place
===
'user'
)
{
return
parsed
}
}
catch
{
// ignore
}
return
undefined
},
[])
const
userMeta
=
useMemo
(()
=>
userMetaFromSearch
||
userMetaFromStorage
,
[
userMetaFromSearch
,
userMetaFromStorage
])
// 同步到 sessionStorage,便于跳转后读取;仅在有 meta 时写入,避免覆盖重定向缓存
// 同步到 sessionStorage,便于跳转后读取;仅在有 meta 时写入,避免覆盖重定向缓存
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
tacticsMeta
)
{
if
(
tacticsMeta
)
{
...
@@ -67,6 +98,13 @@ export const TacticsHome: React.FC = () => {
...
@@ -67,6 +98,13 @@ export const TacticsHome: React.FC = () => {
}
}
},
[
tacticsMeta
])
},
[
tacticsMeta
])
// 同步 userMeta 到 sessionStorage
useEffect
(()
=>
{
if
(
userMeta
)
{
sessionStorage
.
setItem
(
'userMeta'
,
JSON
.
stringify
(
userMeta
))
}
},
[
userMeta
])
const
initTacticsConversation
=
()
=>
{
const
initTacticsConversation
=
()
=>
{
const
fromCollect
=
location
.
state
?.
fromCollect
const
fromCollect
=
location
.
state
?.
fromCollect
// 只有在访问问答首页时才创建新对话
// 只有在访问问答首页时才创建新对话
...
@@ -93,6 +131,7 @@ export const TacticsHome: React.FC = () => {
...
@@ -93,6 +131,7 @@ export const TacticsHome: React.FC = () => {
state
:
{
state
:
{
shouldSendQuestion
:
question
,
shouldSendQuestion
:
question
,
tacticsMeta
,
tacticsMeta
,
userMeta
,
},
},
})
})
return
return
...
@@ -105,7 +144,7 @@ export const TacticsHome: React.FC = () => {
...
@@ -105,7 +144,7 @@ export const TacticsHome: React.FC = () => {
shouldSendQuestion
:
question
,
shouldSendQuestion
:
question
,
}),
}),
)
)
},
[
dispatch
,
currentConversationId
,
navigate
,
tacticsMeta
])
},
[
dispatch
,
currentConversationId
,
navigate
,
tacticsMeta
,
userMeta
])
// 监听导航到新对话
// 监听导航到新对话
useEffect
(()
=>
{
useEffect
(()
=>
{
...
@@ -115,12 +154,13 @@ export const TacticsHome: React.FC = () => {
...
@@ -115,12 +154,13 @@ export const TacticsHome: React.FC = () => {
state
:
{
state
:
{
shouldSendQuestion
,
shouldSendQuestion
,
tacticsMeta
,
tacticsMeta
,
userMeta
,
},
},
replace
:
true
,
replace
:
true
,
})
})
dispatch
(
clearTacticsNavigationFlag
())
dispatch
(
clearTacticsNavigationFlag
())
}
}
},
[
shouldNavigateToNewConversation
,
currentConversationId
,
shouldSendQuestion
,
navigate
,
dispatch
,
tacticsMeta
])
},
[
shouldNavigateToNewConversation
,
currentConversationId
,
shouldSendQuestion
,
navigate
,
dispatch
,
tacticsMeta
,
userMeta
])
const
login
=
useCallback
(
async
()
=>
{
const
login
=
useCallback
(
async
()
=>
{
if
(
hasFetched
.
current
)
{
if
(
hasFetched
.
current
)
{
...
...
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