fix(qa): bug fix

This commit is contained in:
zhangheng
2026-03-28 15:23:08 +08:00
parent c892ec4fe6
commit 28660de4ed
3 changed files with 77 additions and 33 deletions

View File

@@ -6,9 +6,9 @@ NEXT_PUBLIC_ENV=development
# redis # redis
# NEXT_PUBLIC_REDIS_URL="172.16.115.128" # NEXT_PUBLIC_REDIS_URL="172.16.115.128"
NEXT_PUBLIC_REDIS_URL="localhost" NEXT_PUBLIC_REDIS_URL="172.30.21.213"
NEXT_PUBLIC_REDIS_PORT=9765 NEXT_PUBLIC_REDIS_PORT=9765
NEXT_PUBLIC_REDIS_PASSWORD=password NEXT_PUBLIC_REDIS_PASSWORD=password
NEXT_PUBLIC_REDIS_USERNAME=default NEXT_PUBLIC_REDIS_USERNAME=default
NEXT_PUBLIC_REDIS_DB=0 NEXT_PUBLIC_REDIS_DB=1

View File

@@ -9,7 +9,7 @@ import Placeholder from "@tiptap/extension-placeholder"
import { RichTextEditor } from "@mantine/tiptap" import { RichTextEditor } from "@mantine/tiptap"
import { useTopToolsStore } from "../useTopToolsStore" import { useTopToolsStore } from "../useTopToolsStore"
import { useKeyEventStore } from "../store" import { useKeyEventStore } from "../store"
import { useEffect, useRef } from "react" import { useEffect, useRef, type ChangeEvent } from "react"
import { Box } from "@mantine/core" import { Box } from "@mantine/core"
import { IconPhoto } from "@tabler/icons-react" import { IconPhoto } from "@tabler/icons-react"
import "@mantine/tiptap/styles.css" import "@mantine/tiptap/styles.css"
@@ -33,6 +33,7 @@ const EditorContainer = ({
const fileInputRef = useRef<HTMLInputElement>(null) const fileInputRef = useRef<HTMLInputElement>(null)
const editor = useEditor({ const editor = useEditor({
immediatelyRender: false,
extensions: [ extensions: [
StarterKit, StarterKit,
Underline, Underline,
@@ -72,7 +73,7 @@ const EditorContainer = ({
} }
}, [value, editor]) }, [value, editor])
const handleImageUpload = (e: React.ChangeEvent<HTMLInputElement>) => { const handleImageUpload = (e: ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0] const file = e.target.files?.[0]
if (file && editor) { if (file && editor) {
const reader = new FileReader() const reader = new FileReader()

View File

@@ -19,6 +19,7 @@ import { IconEdit } from "@tabler/icons-react"
import dayjs from "dayjs" import dayjs from "dayjs"
import parse from "html-react-parser" import parse from "html-react-parser"
import { ArrowUpIcon, ArrowUpToLineIcon } from "lucide-react" import { ArrowUpIcon, ArrowUpToLineIcon } from "lucide-react"
import dynamic from "next/dynamic"
import { import {
forwardRef, forwardRef,
useCallback, useCallback,
@@ -36,7 +37,11 @@ import { useDescToolsStore } from "../useDescToolsStore"
import { useTopToolsStore } from "../useTopToolsStore" import { useTopToolsStore } from "../useTopToolsStore"
import { safeClone } from "../utils/clone" import { safeClone } from "../utils/clone"
import CustomModal from "./CustomModal" import CustomModal from "./CustomModal"
import EditorContainer, { splitWord } from "./EditorContainer" import { splitWord } from "./EditorContainer"
const EditorContainer = dynamic(() => import("./EditorContainer"), {
ssr: false,
})
interface ComponentProps { interface ComponentProps {
taskDetail?: Task.DataProps taskDetail?: Task.DataProps
@@ -54,6 +59,25 @@ const escapeRegExp = (str: string) => {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
} }
const getHtmlFromStoredValue = (value?: string) => {
if (!value) return ""
const [html] = value.split(splitWord)
return html ?? value
}
const getTextFromHtml = (html: string) => {
return html
.replace(/<[^>]+>/g, "")
.replace(/&nbsp;/g, " ")
.trim()
}
const ensureStoredValue = (value?: string) => {
if (!value) return ""
if (value.includes(splitWord)) return value
return `${value}${splitWord}${getTextFromHtml(value)}`
}
const RightQAContent = forwardRef( const RightQAContent = forwardRef(
({ taskDetail }: ComponentProps, ref: React.Ref<unknown>) => { ({ taskDetail }: ComponentProps, ref: React.Ref<unknown>) => {
const { isView } = useTopToolsStore() const { isView } = useTopToolsStore()
@@ -114,11 +138,21 @@ const RightQAContent = forwardRef(
type QaObj = Record<string, any> type QaObj = Record<string, any>
const handleFormUpdate = (changeValues: any) => { const handleFormUpdate = (
changeValues: Record<string, any>,
rawEditorValue?: string
) => {
if (!selectedQuestion) return if (!selectedQuestion) return
const keys = Object.keys(changeValues) const keys = Object.keys(changeValues)
const hasTagChange = keys.includes("tag") const hasTagChange = keys.includes("tag")
const formData = form.values const formData = {
...form.values,
...changeValues,
}
const nextStoredValue =
typeof rawEditorValue === "string"
? ensureStoredValue(rawEditorValue)
: ensureStoredValue(formData.value)
const { label, type, category } = selectedQuestion const { label, type, category } = selectedQuestion
const currentQaDataArr = currentQaData[category] ?? [] const currentQaDataArr = currentQaData[category] ?? []
let newArr: { [x: string]: any }[] = [] let newArr: { [x: string]: any }[] = []
@@ -127,7 +161,7 @@ const RightQAContent = forwardRef(
if (question_name === label) { if (question_name === label) {
newArr.push({ newArr.push({
[question_name]: { [question_name]: {
value: type === "value" ? formData.value : detail.value, value: type === "value" ? nextStoredValue : detail.value,
id: formData.round, id: formData.round,
is_pre: detail.is_pre, is_pre: detail.is_pre,
tag: formData.tag, tag: formData.tag,
@@ -139,7 +173,7 @@ const RightQAContent = forwardRef(
: dayjs().unix(), : dayjs().unix(),
modify_uid: usePermissionStore.getState().user_id, modify_uid: usePermissionStore.getState().user_id,
modify_timestamp: dayjs().unix(), modify_timestamp: dayjs().unix(),
comment: type === "comment" ? formData.value : detail.comment, comment: type === "comment" ? nextStoredValue : detail.comment,
flag: hasTagChange ? 0 : detail.tag === 2 ? 1 : 0, flag: hasTagChange ? 0 : detail.tag === 2 ? 1 : 0,
}, },
}) })
@@ -158,9 +192,13 @@ const RightQAContent = forwardRef(
} }
} }
const onFieldChange = (field: string, value: any) => { const onFieldChange = (
field: string,
value: any,
rawEditorValue?: string
) => {
form.setFieldValue(field, value) form.setFieldValue(field, value)
handleFormUpdate({ [field]: value }) handleFormUpdate({ [field]: value }, rawEditorValue)
} }
useEffect(() => { useEffect(() => {
@@ -170,12 +208,10 @@ const RightQAContent = forwardRef(
selectedQuestion.type === "comment" selectedQuestion.type === "comment"
) { ) {
const { value: v } = selectedQuestion const { value: v } = selectedQuestion
let htmlText = "" const htmlText =
if (selectedQuestion.type === "value") { selectedQuestion.type === "value"
htmlText = v.value ? v.value.split(splitWord)[0] : "" ? getHtmlFromStoredValue(v.value)
} else { : getHtmlFromStoredValue(v.comment)
htmlText = v.comment ? v.comment.split(splitWord)[0] : ""
}
const obj = { const obj = {
value: htmlText, value: htmlText,
round: v.id, round: v.id,
@@ -183,7 +219,8 @@ const RightQAContent = forwardRef(
} }
form.setValues(obj) form.setValues(obj)
} }
}, [selectedQuestion, form]) // eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedQuestion])
useEffect(() => { useEffect(() => {
if (updateDescDataFlag) { if (updateDescDataFlag) {
@@ -230,9 +267,10 @@ const RightQAContent = forwardRef(
const newQaData = safeClone(currentQaData) const newQaData = safeClone(currentQaData)
const handleText = (v: string) => { const handleText = (v: string) => {
// 提取文本内容 // 优先使用存储中的纯文本部分;若历史数据不规范则兜底从 HTML 中提取
const text = v.split(splitWord)[1] const text =
let textContent = text.replace(/<[^>]+>/g, "") v.split(splitWord)[1] ?? getTextFromHtml(getHtmlFromStoredValue(v))
let textContent = text
// 替换错词 // 替换错词
for (let i = 0; i < wrongWords.length; i++) { for (let i = 0; i < wrongWords.length; i++) {
const wrong = escapeRegExp(wrongWords[i]) const wrong = escapeRegExp(wrongWords[i])
@@ -256,17 +294,20 @@ const RightQAContent = forwardRef(
const { value, comment } = questionData const { value, comment } = questionData
const update = (v: string, key: "value" | "comment") => { const update = (v: string, key: "value" | "comment") => {
const checkValue = v.split(splitWord)[1] const checkValue =
v.split(splitWord)[1] ??
getTextFromHtml(getHtmlFromStoredValue(v))
const updatedValue = handleText(v) const updatedValue = handleText(v)
if (checkValue !== updatedValue) { if (checkValue !== updatedValue) {
let newValue = `<p>${updatedValue}</p>${splitWord}${updatedValue}` const htmlValue = `<p>${updatedValue}</p>`
let newValue = `${htmlValue}${splitWord}${updatedValue}`
questionData[key] = newValue questionData[key] = newValue
if ( if (
selectedQuestion?.label === name && selectedQuestion?.label === name &&
selectedQuestion?.type === key selectedQuestion?.type === key
) )
form.setFieldValue("value", `<p>${updatedValue}</p>`) form.setFieldValue("value", htmlValue)
} }
} }
@@ -312,12 +353,10 @@ const RightQAContent = forwardRef(
<Stack gap="xs"> <Stack gap="xs">
{qaDataArr.map((qaObj, index) => { {qaDataArr.map((qaObj, index) => {
const [question_name, detail] = Object.entries(qaObj)[0] const [question_name, detail] = Object.entries(qaObj)[0]
const htmlText = detail.value const htmlText = getHtmlFromStoredValue(detail.value)
? detail.value.split(splitWord)[0] const commentHtmlText = getHtmlFromStoredValue(
: "" detail.comment
const commentHtmlText = detail.comment )
? detail.comment.split(splitWord)[0]
: ""
return ( return (
<Box <Box
@@ -561,7 +600,9 @@ const RightQAContent = forwardRef(
</Flex> </Flex>
<EditorContainer <EditorContainer
value={form.values.value} value={form.values.value}
onChange={(val: any) => onFieldChange("value", val)} onChange={(val: string) =>
onFieldChange("value", getHtmlFromStoredValue(val), val)
}
disabled={!selectedQuestion} disabled={!selectedQuestion}
/> />
</Stack> </Stack>
@@ -601,7 +642,7 @@ const RightQAContent = forwardRef(
const finalData = safeClone(currentQaData) const finalData = safeClone(currentQaData)
const updateData = safeClone(currentOperation) const updateData = safeClone(currentOperation)
let obj = { let obj = {
value: formData.value ?? "<p></p>", value: ensureStoredValue(formData.value ?? "<p></p>"),
id: formData.round_id, id: formData.round_id,
is_pre: false, is_pre: false,
tag: 0, tag: 0,
@@ -657,7 +698,9 @@ const RightQAContent = forwardRef(
</Text> </Text>
<EditorContainer <EditorContainer
value={textForm.values.value} value={textForm.values.value}
onChange={(val: any) => textForm.setFieldValue("value", val)} onChange={(val: string) =>
textForm.setFieldValue("value", getHtmlFromStoredValue(val))
}
/> />
</Box> </Box>
<NumberInput <NumberInput