fix(qa): bug fix
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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(/ /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
|
||||
|
||||
Reference in New Issue
Block a user