Commit 2b1e4e52 by Liu

feat: 用户分析传参

parent 3895ddce
......@@ -90,6 +90,78 @@ export const TacticsChat: React.FC = () => {
}, [])
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 date = new Date()
const pad = (value: number) => value.toString().padStart(2, '0')
......@@ -241,7 +313,7 @@ export const TacticsChat: React.FC = () => {
question: string | undefined,
productCode?: string,
toolId?: string,
extra?: { busiType?: string, recordType?: string, includeQuestion?: boolean, includeTacticsMeta?: boolean },
extra?: { busiType?: string, recordType?: string, numberType?: string, includeQuestion?: boolean, includeTacticsMeta?: boolean, includeUserMeta?: boolean },
) => {
// 优先读取缓存中的 toolId,再回退到传参
const sessionToolId = sessionStorage.getItem('currentToolId') ?? undefined
......@@ -293,6 +365,7 @@ export const TacticsChat: React.FC = () => {
const shouldSendQuestion = extra?.includeQuestion !== false
const shouldIncludeTacticsMeta = extra?.includeTacticsMeta !== false
const shouldIncludeUserMeta = extra?.includeUserMeta !== false
// 去除缓存中可能存在的 from 字段,避免作为参数传递
const { from: _omitFrom, ...safeTacticsMeta } = tacticsMeta || {}
......@@ -304,8 +377,16 @@ export const TacticsChat: React.FC = () => {
toolId: resolvedToolId,
...(extra?.busiType ? { busiType: extra.busiType } : {}),
...(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)
}
if (shouldSendQuestion) {
......@@ -431,14 +512,34 @@ export const TacticsChat: React.FC = () => {
}, [dispatch])
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())
if (currentIdRef.current) {
navigate(`/tactics/chat/${currentIdRef.current}`)
}
}, [dispatch, navigate, handleSubmitQuestion])
}, [dispatch, navigate, handleSubmitQuestion, userMeta, getNumberTypeWithUserMeta])
const handleCancelClear = useCallback(() => {
setShowClearConfirm(false)
......@@ -485,14 +586,40 @@ export const TacticsChat: React.FC = () => {
useEffect(() => {
if (currentIdRef.current && !isLoading && !hasAutoSubmittedRef.current) {
hasAutoSubmittedRef.current = true
handleSubmitQuestion(
'策略分析',
undefined,
undefined,
{ busiType: '02', recordType: 'A02', includeQuestion: true, includeTacticsMeta: 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(
'策略分析',
undefined,
undefined,
{
busiType: '02',
recordType: 'A02',
includeQuestion: true,
includeTacticsMeta: true,
},
)
}
}
}, [isLoading, handleSubmitQuestion, id])
}, [isLoading, handleSubmitQuestion, id, userMeta, getNumberTypeWithUserMeta])
// 创建新会话成功后跳转到新会话页面
useEffect(() => {
......@@ -501,12 +628,13 @@ export const TacticsChat: React.FC = () => {
state: {
shouldSendQuestion: shouldSendQuestionFromState,
tacticsMeta,
userMeta,
},
replace: true,
})
dispatch(clearTacticsNavigationFlag())
}
}, [shouldNavigateToNewConversation, currentConversationId, navigate, dispatch, shouldSendQuestionFromState, tacticsMeta])
}, [shouldNavigateToNewConversation, currentConversationId, navigate, dispatch, shouldSendQuestionFromState, tacticsMeta, userMeta])
// 处理shouldSendQuestion的变化 - 自动发送问题
useEffect(() => {
......@@ -525,11 +653,29 @@ export const TacticsChat: React.FC = () => {
) {
lastSentQuestionRef.current = shouldSendQuestion
dispatch(clearTacticsShouldSendQuestion())
const hasUserMeta = !!userMeta
setTimeout(() => {
handleSubmitQuestion(shouldSendQuestion)
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)
}
}, 100)
}
}, [shouldSendQuestion, isLoading, dispatch])
}, [shouldSendQuestion, isLoading, dispatch, userMeta, handleSubmitQuestion, getNumberTypeWithUserMeta])
return (
<div
......@@ -666,11 +812,35 @@ export const TacticsChat: React.FC = () => {
currentId: currentIdRef.current,
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(
question,
undefined,
undefined,
{
busiType: '02',
numberType: mappedNumberType,
includeQuestion: true,
includeTacticsMeta: false,
includeUserMeta: true,
},
)
}
return handleSubmitQuestion(
question,
undefined,
undefined,
{ busiType: '02', recordType: 'A01', includeQuestion: true, includeTacticsMeta: false },
{
busiType: '02',
recordType: 'A01',
includeQuestion: true,
includeTacticsMeta: false,
},
)
}}
placeholders={['']}
......
......@@ -60,6 +60,37 @@ export const TacticsHome: React.FC = () => {
}, [])
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 时写入,避免覆盖重定向缓存
useEffect(() => {
if (tacticsMeta) {
......@@ -67,6 +98,13 @@ export const TacticsHome: React.FC = () => {
}
}, [tacticsMeta])
// 同步 userMeta 到 sessionStorage
useEffect(() => {
if (userMeta) {
sessionStorage.setItem('userMeta', JSON.stringify(userMeta))
}
}, [userMeta])
const initTacticsConversation = () => {
const fromCollect = location.state?.fromCollect
// 只有在访问问答首页时才创建新对话
......@@ -93,6 +131,7 @@ export const TacticsHome: React.FC = () => {
state: {
shouldSendQuestion: question,
tacticsMeta,
userMeta,
},
})
return
......@@ -105,7 +144,7 @@ export const TacticsHome: React.FC = () => {
shouldSendQuestion: question,
}),
)
}, [dispatch, currentConversationId, navigate, tacticsMeta])
}, [dispatch, currentConversationId, navigate, tacticsMeta, userMeta])
// 监听导航到新对话
useEffect(() => {
......@@ -115,12 +154,13 @@ export const TacticsHome: React.FC = () => {
state: {
shouldSendQuestion,
tacticsMeta,
userMeta,
},
replace: true,
})
dispatch(clearTacticsNavigationFlag())
}
}, [shouldNavigateToNewConversation, currentConversationId, shouldSendQuestion, navigate, dispatch, tacticsMeta])
}, [shouldNavigateToNewConversation, currentConversationId, shouldSendQuestion, navigate, dispatch, tacticsMeta, userMeta])
const login = useCallback(async () => {
if (hasFetched.current) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment