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

View File

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