Commit 0ace2d9a by Liu

feat:工单参数逻辑

parent 2514136e
......@@ -23,6 +23,7 @@ export const ChatAnswerOperate: React.FC<ChatAnswerOperateProps> = ({ answer })
// 读取路由参数 from
const from = searchParams.get('from')
const fromValues = searchParams.getAll('from')
// 兜底读取缓存的 tacticsMeta(会话从 tactics 打开的元信息)
const tacticsMetaFromStorage = useMemo(() => {
......@@ -50,8 +51,11 @@ export const ChatAnswerOperate: React.FC<ChatAnswerOperateProps> = ({ answer })
}
}, [])
// 规则:当 sessionStorage 中存在 userMeta 或 tacticsMeta 时,或路由参数 from=tactics 时,统一隐藏收藏按钮
const shouldHideCollect = !!userMetaFromStorage || !!tacticsMetaFromStorage || from === 'tactics'
// 检查路由参数中是否有 from=order
const hasOrderFromRoute = fromValues.includes('order')
// 规则:当 sessionStorage 中存在 userMeta 或 tacticsMeta 时,或路由参数 from=tactics 或 from=order 时,统一隐藏收藏按钮
const shouldHideCollect = !!userMetaFromStorage || !!tacticsMetaFromStorage || from === 'tactics' || hasOrderFromRoute
const [isCollect, setIsCollect] = useState(answer.collectionFlag)
const [isLike, setIsLike] = useState(answer.feedbackStatus === '01')
......
......@@ -23,13 +23,23 @@ export const ChatAnswerRecommend: React.FC<ChatAnswerRecommendProps> = ({ answer
// 仅在 from=tactics 场景下,按照要求补充 busiType / recordType 参数
const from = searchParams.get('from')
const place = searchParams.get('place')
const fromValues = searchParams.getAll('from')
const shouldAttachBusiParams = from === 'tactics'
const busiType = shouldAttachBusiParams ? '02' : undefined
let recordType: string | undefined
if (shouldAttachBusiParams) {
// from=tactics 且 from=order → recordType=A11
// from=tactics 且 place=user → recordType=A03
// from=tactics 且 place!=user/无 → recordType=A01
recordType = place === 'user' ? 'A03' : 'A01'
if (fromValues.includes('order')) {
recordType = 'A11'
}
else if (place === 'user') {
recordType = 'A03'
}
else {
recordType = 'A01'
}
}
try {
const res = await fetchQueryRecommendQuestion(
......
......@@ -107,23 +107,40 @@ export const TacticsChat: React.FC = () => {
}
}, [searchParams])
// 读取 from=order 时的 orderMeta 参数(直接从 query 读取,不再使用 sessionStorage)
const orderMeta = useMemo(() => {
const fromValues = searchParams.getAll('from')
if (!fromValues.includes('order')) {
return undefined
}
return {
workOrderIds: searchParams.get('workOrderIds') || undefined,
}
}, [searchParams])
// 仅用于创建会话的额外参数(create_conversation)
const getConversationExtra = useCallback(() => {
if (orderMeta) {
return {
busiType: '02',
// from=order 场景下,不传 busiId
} as Partial<any>
}
if (userMeta?.place === 'user') {
return {
busiType: '02',
// place=user 场景下,业务方要求 busiId 取 numberType
busiId: userMeta.numberType,
}
} as Partial<any>
}
if (tacticsMeta) {
return {
busiType: '02',
busiId: tacticsMeta.taskId,
}
} as Partial<any>
}
return {}
}, [tacticsMeta, userMeta])
return {} as Partial<any>
}, [orderMeta, tacticsMeta, userMeta])
// 根据 userMeta.numberType 与调用类型(自动/正常)计算请求参数用的 numberType(A03/A04...)
const getNumberTypeWithUserMeta = useCallback(
......@@ -290,7 +307,7 @@ export const TacticsChat: React.FC = () => {
question: string | undefined,
productCode?: string,
toolId?: string,
extra?: { busiType?: string, recordType?: string, numberType?: string, includeQuestion?: boolean, includeTacticsMeta?: boolean, includeUserMeta?: boolean, isReanalyze?: boolean },
extra?: { busiType?: string, recordType?: string, numberType?: string, includeQuestion?: boolean, includeTacticsMeta?: boolean, includeUserMeta?: boolean, includeOrderMeta?: boolean, isReanalyze?: boolean },
) => {
// 优先读取缓存中的 toolId,再回退到传参
const sessionToolId = sessionStorage.getItem('currentToolId') ?? undefined
......@@ -364,6 +381,7 @@ export const TacticsChat: React.FC = () => {
const shouldSendQuestion = extra?.includeQuestion !== false
const shouldIncludeTacticsMeta = extra?.includeTacticsMeta !== false
const shouldIncludeUserMeta = extra?.includeUserMeta !== false
const shouldIncludeOrderMeta = extra?.includeOrderMeta !== false
// 去除缓存中可能存在的 from 字段,避免作为参数传递
const { from: _omitFrom, ...safeTacticsMeta } = tacticsMeta || {}
......@@ -377,9 +395,14 @@ export const TacticsChat: React.FC = () => {
...(extra?.recordType ? { recordType: extra.recordType } : {}),
...(extra?.numberType ? { numberType: extra.numberType } : {}),
}
// 优先使用 userMeta,如果存在 userMeta 且需要包含,则传入 userMeta 的字段
// 注意:这里显式剔除 userMeta 自带的 numberType 和 place,避免覆盖映射后的 numberType,并按需去掉 place
if (userMeta && shouldIncludeUserMeta) {
// 优先级:orderMeta > userMeta > tacticsMeta
// 优先使用 orderMeta,如果存在 orderMeta 且需要包含,则传入 orderMeta 的字段
if (orderMeta && shouldIncludeOrderMeta) {
Object.assign(requestBody, orderMeta)
}
// 如果没有 orderMeta 或不需要包含 orderMeta,则使用 userMeta
else if (userMeta && shouldIncludeUserMeta) {
// 注意:这里显式剔除 userMeta 自带的 numberType 和 place,避免覆盖映射后的 numberType,并按需去掉 place
const { place: _omitPlace, ...safeUserMeta } = userMeta
Object.assign(requestBody, safeUserMeta)
}
......@@ -388,7 +411,11 @@ export const TacticsChat: React.FC = () => {
Object.assign(requestBody, safeTacticsMeta)
}
// from=tactics 场景下补充业务识别参数
if (userMeta?.place === 'user') {
if (orderMeta && shouldIncludeOrderMeta) {
requestBody.busiType ??= '02'
// from=order 场景下,不传 busiId
}
else if (userMeta?.place === 'user') {
requestBody.busiType ??= '02'
// place=user 场景下,业务方要求 busiId 取 numberType
requestBody.busiId ??= userMeta.numberType
......@@ -575,31 +602,44 @@ export const TacticsChat: React.FC = () => {
return
}
// 重新触发一次提问,与首次自动调用保持一致:
// - 无 userMeta:沿用原逻辑,传 recordType=A02,使用 tacticsMeta
// - 有 orderMeta:传 recordType=A11,使用 orderMeta
// - 有 userMeta:按 userMeta.numberType 映射 numberType(A03/A05/A07/A09),不传 recordType,仅传 userMeta
const hasUserMeta = !!userMeta
if (hasUserMeta) {
// place=user 场景下,重新分析也视为“自动调用”:
// - numberType 为 3/4/5/6:映射为 A03/A05/A07/A09
// - 其它值或不存在:recordType=A01
const mappedNumberType = getNumberTypeWithUserMeta('A01', true)
// - 无 userMeta:沿用原逻辑,传 recordType=A02,使用 tacticsMeta
if (orderMeta) {
await handleSubmitQuestion(undefined, undefined, undefined, {
busiType: '02',
recordType: mappedNumberType,
recordType: 'A11',
includeQuestion: false,
includeTacticsMeta: false,
includeUserMeta: true,
includeOrderMeta: true,
isReanalyze: true,
})
}
else {
await handleSubmitQuestion(undefined, undefined, undefined, {
busiType: '02',
recordType: 'A01',
includeQuestion: false,
includeTacticsMeta: true,
isReanalyze: true,
})
const hasUserMeta = !!userMeta
if (hasUserMeta) {
// place=user 场景下,重新分析也视为"自动调用":
// - numberType 为 3/4/5/6:映射为 A03/A05/A07/A09
// - 其它值或不存在:recordType=A01
const mappedNumberType = getNumberTypeWithUserMeta('A01', true)
await handleSubmitQuestion(undefined, undefined, undefined, {
busiType: '02',
recordType: mappedNumberType,
includeQuestion: false,
includeTacticsMeta: false,
includeUserMeta: true,
isReanalyze: true,
})
}
else {
await handleSubmitQuestion(undefined, undefined, undefined, {
busiType: '02',
recordType: 'A01',
includeQuestion: false,
includeTacticsMeta: true,
isReanalyze: true,
})
}
}
// 重新拉取会话列表,保持原有行为
await dispatch(fetchTacticsConversations())
......@@ -607,7 +647,7 @@ export const TacticsChat: React.FC = () => {
logFullUrl('before navigate reanalyze')
navigate(`/tactics/chat/${currentIdRef.current}${location.search}`)
}
}, [dispatch, navigate, handleSubmitQuestion, userMeta, getNumberTypeWithUserMeta, isLoading, isAsking, logFullUrl, location.search])
}, [dispatch, navigate, handleSubmitQuestion, orderMeta, userMeta, getNumberTypeWithUserMeta, isLoading, isAsking, logFullUrl, location.search])
const handleCancelClear = useCallback(() => {
setShowClearConfirm(false)
......@@ -680,42 +720,59 @@ export const TacticsChat: React.FC = () => {
}
hasAutoSubmittedRef.current = true
// 进入会话后自动触发一次提交:
// - 无 userMeta:沿用原逻辑,recordType=A02,携带 tacticsMeta
// - 有 orderMeta:传 recordType=A11,使用 orderMeta
// - 有 userMeta:按 userMeta.numberType 映射 numberType(A03/A05/A07/A09),不传 recordType,仅传 userMeta
const hasUserMeta = !!userMeta
if (hasUserMeta) {
// place=user 场景下,首次自动调用:
// - numberType 为 3/4/5/6:映射为 A03/A05/A07/A09
// - 其它值或不存在:recordType=A01
const mappedNumberType = getNumberTypeWithUserMeta('A01', true)
// - 无 userMeta:沿用原逻辑,recordType=A02,携带 tacticsMeta
if (orderMeta) {
handleSubmitQuestion(
undefined,
undefined,
undefined,
{
busiType: '02',
recordType: mappedNumberType,
recordType: 'A11',
includeQuestion: false,
includeTacticsMeta: false,
includeUserMeta: true,
includeOrderMeta: true,
},
)
}
else {
handleSubmitQuestion(
undefined,
undefined,
undefined,
{
busiType: '02',
recordType: 'A01',
includeQuestion: false,
includeTacticsMeta: true,
},
)
const hasUserMeta = !!userMeta
if (hasUserMeta) {
// place=user 场景下,首次自动调用:
// - numberType 为 3/4/5/6:映射为 A03/A05/A07/A09
// - 其它值或不存在:recordType=A01
const mappedNumberType = getNumberTypeWithUserMeta('A01', true)
handleSubmitQuestion(
undefined,
undefined,
undefined,
{
busiType: '02',
recordType: mappedNumberType,
includeQuestion: false,
includeTacticsMeta: false,
includeUserMeta: true,
},
)
}
else {
handleSubmitQuestion(
undefined,
undefined,
undefined,
{
busiType: '02',
recordType: 'A01',
includeQuestion: false,
includeTacticsMeta: true,
},
)
}
}
}
}, [isLoading, handleSubmitQuestion, id, userMeta, getNumberTypeWithUserMeta, hasHistory])
}, [isLoading, handleSubmitQuestion, id, orderMeta, userMeta, getNumberTypeWithUserMeta, hasHistory])
// 创建新会话成功后跳转到新会话页面
useEffect(() => {
......@@ -748,10 +805,8 @@ export const TacticsChat: React.FC = () => {
) {
lastSentQuestionRef.current = shouldSendQuestion
dispatch(clearTacticsShouldSendQuestion())
const hasUserMeta = !!userMeta
setTimeout(() => {
if (hasUserMeta) {
const mappedNumberType = getNumberTypeWithUserMeta('A01', false)
if (orderMeta) {
handleSubmitQuestion(
shouldSendQuestion,
undefined,
......@@ -759,22 +814,53 @@ export const TacticsChat: React.FC = () => {
{
includeQuestion: true,
includeTacticsMeta: false,
includeUserMeta: true,
recordType: mappedNumberType,
includeOrderMeta: true,
recordType: 'A12',
},
)
}
else {
// 无 userMeta:保持原有行为,不传任何 extra(不携带 numberType),由内部默认逻辑处理 tacticsMeta
handleSubmitQuestion(shouldSendQuestion)
const hasUserMeta = !!userMeta
if (hasUserMeta) {
const mappedNumberType = getNumberTypeWithUserMeta('A01', false)
handleSubmitQuestion(
shouldSendQuestion,
undefined,
undefined,
{
includeQuestion: true,
includeTacticsMeta: false,
includeUserMeta: true,
recordType: mappedNumberType,
},
)
}
else {
// 无 userMeta:保持原有行为,不传任何 extra(不携带 numberType),由内部默认逻辑处理 tacticsMeta
handleSubmitQuestion(shouldSendQuestion)
}
}
}, 100)
}
}, [shouldSendQuestion, isLoading, dispatch, userMeta, handleSubmitQuestion, getNumberTypeWithUserMeta])
}, [shouldSendQuestion, isLoading, dispatch, orderMeta, userMeta, handleSubmitQuestion, getNumberTypeWithUserMeta])
// 提供给 ChatAnswerBox/推荐问题的提交方法,保持与手动提问一致的 recordType 逻辑
const handleAnswerBoxSubmit = useCallback(
(question: string, productCode?: string) => {
if (orderMeta) {
return handleSubmitQuestion(
question,
productCode,
undefined,
{
busiType: '02',
recordType: 'A12',
includeQuestion: true,
includeTacticsMeta: false,
includeOrderMeta: true,
},
)
}
const hasUserMeta = !!userMeta
if (hasUserMeta) {
const mappedNumberType = getNumberTypeWithUserMeta('A02', false)
......@@ -803,7 +889,7 @@ export const TacticsChat: React.FC = () => {
},
)
},
[userMeta, getNumberTypeWithUserMeta, handleSubmitQuestion],
[orderMeta, userMeta, getNumberTypeWithUserMeta, handleSubmitQuestion],
)
return (
......@@ -955,8 +1041,23 @@ export const TacticsChat: React.FC = () => {
isLoading,
})
// 正常问答:
// - 无 userMeta:保持原有逻辑,recordType=A01、busiType=02、不带 numberType
// - 有 orderMeta:传 recordType=A12,使用 orderMeta
// - 有 userMeta:按 userMeta.numberType 映射 numberType(A04/A06/A08/A10),不传 recordType,仅传 userMeta
// - 无 userMeta:保持原有逻辑,recordType=A01、busiType=02、不带 numberType
if (orderMeta) {
return handleSubmitQuestion(
question,
undefined,
undefined,
{
busiType: '02',
recordType: 'A12',
includeQuestion: true,
includeTacticsMeta: false,
includeOrderMeta: true,
},
)
}
const hasUserMeta = !!userMeta
if (hasUserMeta) {
const mappedNumberType = getNumberTypeWithUserMeta('A02', false)
......
......@@ -59,23 +59,40 @@ export const TacticsHome: React.FC = () => {
}
}, [searchParams])
// 读取 from=order 时的 orderMeta 参数(直接从 query 读取,不再使用 sessionStorage)
const orderMeta = useMemo(() => {
const fromValues = searchParams.getAll('from')
if (!fromValues.includes('order')) {
return undefined
}
return {
workOrderIds: searchParams.get('workOrderIds') || undefined,
}
}, [searchParams])
// 仅用于创建会话的额外参数(对应 create_conversation)
const getConversationExtra = useCallback(() => {
if (orderMeta) {
return {
busiType: '02',
// from=order 场景下,不传 busiId
} as Partial<any>
}
if (userMeta?.place === 'user') {
return {
busiType: '02',
// place=user 场景下,业务方要求 busiId 取 numberType
busiId: userMeta.numberType,
}
} as Partial<any>
}
if (tacticsMeta) {
return {
busiType: '02',
busiId: tacticsMeta.taskId,
}
} as Partial<any>
}
return {}
}, [tacticsMeta, userMeta])
return {} as Partial<any>
}, [orderMeta, tacticsMeta, userMeta])
const initTacticsConversation = () => {
const fromCollect = location.state?.fromCollect
......@@ -94,7 +111,14 @@ export const TacticsHome: React.FC = () => {
const from = searchParams.get('from')
const place = searchParams.get('place')
if (conversationId && from === 'tactics') {
const storageKey = place === 'user' ? 'tactics_user_conversation_id' : 'tactics_conversation_id'
const fromValues = searchParams.getAll('from')
let storageKey = 'tactics_conversation_id'
if (fromValues.includes('order')) {
storageKey = 'tactics_order_conversation_id'
}
else if (place === 'user') {
storageKey = 'tactics_user_conversation_id'
}
window.localStorage.setItem(storageKey, conversationId)
}
// eslint-disable-next-line no-console
......
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