Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
sdream-ai-fe
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
侯明涛
sdream-ai-fe
Commits
1d4315f6
Commit
1d4315f6
authored
Oct 28, 2025
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 输入框样式&&点赞等功能
parent
210a7c92
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
71 additions
and
66 deletions
+71
-66
src/components/ChatEditor/index.tsx
+1
-1
src/pages/Chat/components/ChatItem/ChatAnswerOperate.tsx
+70
-65
No files found.
src/components/ChatEditor/index.tsx
View file @
1d4315f6
...
@@ -186,7 +186,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -186,7 +186,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
return
(
return
(
<
div
<
div
className=
"flex items-end w-full h-auto relative mx-auto rounded-[24px] overflow-hidden transition duration-200 py-[8px] pl-[12px] pr-[12px] sm:py-[12px] sm:pl-[32px] sm:pr-[20px]"
className=
"flex items-end w-full
max-w-[900px]
h-auto relative mx-auto rounded-[24px] overflow-hidden transition duration-200 py-[8px] pl-[12px] pr-[12px] sm:py-[12px] sm:pl-[32px] sm:pr-[20px]"
style=
{
{
style=
{
{
background
:
'#FFFFFF'
,
background
:
'#FFFFFF'
,
border
:
'1px solid #0a0a0a78'
,
border
:
'1px solid #0a0a0a78'
,
...
...
src/pages/Chat/components/ChatItem/ChatAnswerOperate.tsx
View file @
1d4315f6
...
@@ -4,8 +4,13 @@ import { useDebounceFn } from 'ahooks'
...
@@ -4,8 +4,13 @@ import { useDebounceFn } from 'ahooks'
import
type
{
Answer
}
from
'@/types/chat'
import
type
{
Answer
}
from
'@/types/chat'
import
CollectIcon
from
'@/assets/svg/shouc.svg?react'
import
CollectIcon
from
'@/assets/svg/shouc.svg?react'
import
CollectIconA
from
'@/assets/svg/shoucA.svg?react'
import
CollectIconA
from
'@/assets/svg/shoucA.svg?react'
import
LikeIcon
from
'@/assets/svg/zan.svg?react'
import
LikeIconA
from
'@/assets/svg/zanA.svg?react'
import
UnLikeIcon
from
'@/assets/svg/cai.svg?react'
import
UnLikeIconA
from
'@/assets/svg/caiA.svg?react'
import
CopyIcon
from
'@/assets/svg/copy.svg?react'
import
useToast
from
'@/hooks/useToast'
import
useToast
from
'@/hooks/useToast'
import
{
fetchCancelCollection
,
fetchSubmitCollection
}
from
'@/api/chat'
import
{
fetchCancelCollection
,
fetchSubmitCollection
,
fetchSubmitFeedback
}
from
'@/api/chat'
import
{
UnLikeModal
}
from
'@/components/UnLikeModal'
import
{
UnLikeModal
}
from
'@/components/UnLikeModal'
interface
ChatAnswerOperateProps
{
interface
ChatAnswerOperateProps
{
...
@@ -14,8 +19,8 @@ interface ChatAnswerOperateProps {
...
@@ -14,8 +19,8 @@ interface ChatAnswerOperateProps {
export
const
ChatAnswerOperate
:
React
.
FC
<
ChatAnswerOperateProps
>
=
({
answer
})
=>
{
export
const
ChatAnswerOperate
:
React
.
FC
<
ChatAnswerOperateProps
>
=
({
answer
})
=>
{
const
showToast
=
useToast
()
const
showToast
=
useToast
()
const
[
isCollect
,
setIsCollect
]
=
useState
(
answer
.
collectionFlag
)
const
[
isCollect
,
setIsCollect
]
=
useState
(
answer
.
collectionFlag
)
//
const [isLike, setIsLike] = useState(answer.feedbackStatus === '01')
const
[
isLike
,
setIsLike
]
=
useState
(
answer
.
feedbackStatus
===
'01'
)
//
const [isUnLike, setIsUnLike] = useState(answer.feedbackStatus === '02')
const
[
isUnLike
,
setIsUnLike
]
=
useState
(
answer
.
feedbackStatus
===
'02'
)
const
[
isOpenUnLikeModal
,
setIsOpenUnLikeOpen
]
=
useState
(
false
)
const
[
isOpenUnLikeModal
,
setIsOpenUnLikeOpen
]
=
useState
(
false
)
const
isProcessingRef
=
useRef
(
false
)
const
isProcessingRef
=
useRef
(
false
)
...
@@ -53,47 +58,47 @@ export const ChatAnswerOperate: React.FC<ChatAnswerOperateProps> = ({ answer })
...
@@ -53,47 +58,47 @@ export const ChatAnswerOperate: React.FC<ChatAnswerOperateProps> = ({ answer })
}
}
},
{
wait
:
200
})
},
{
wait
:
200
})
//
const handleLike = useDebounceFn(async () => {
const
handleLike
=
useDebounceFn
(
async
()
=>
{
//
if (!isLike) {
if
(
!
isLike
)
{
//
setIsLike(true)
setIsLike
(
true
)
//
setIsUnLike(false)
setIsUnLike
(
false
)
//
await fetchSubmitFeedback({
await
fetchSubmitFeedback
({
//
recordId: answer.recordId,
recordId
:
answer
.
recordId
,
//
feedbackStatus: '01',
feedbackStatus
:
'01'
,
//
content: '',
content
:
''
,
//
})
})
//
showToast('感谢您的反馈', 'success')
showToast
(
'感谢您的反馈'
,
'success'
)
//
}
}
//
else {
else
{
//
setIsLike(false)
setIsLike
(
false
)
//
await fetchSubmitFeedback({
await
fetchSubmitFeedback
({
//
recordId: answer.recordId,
recordId
:
answer
.
recordId
,
//
feedbackStatus: '00',
feedbackStatus
:
'00'
,
//
content: '',
content
:
''
,
//
})
})
//
}
}
//
})
})
//
const handleUnLike = async () => {
const
handleUnLike
=
async
()
=>
{
//
if (!isUnLike) {
if
(
!
isUnLike
)
{
//
setIsUnLike(true)
setIsUnLike
(
true
)
//
setIsLike(false)
setIsLike
(
false
)
//
await fetchSubmitFeedback({
await
fetchSubmitFeedback
({
//
recordId: answer.recordId,
recordId
:
answer
.
recordId
,
//
feedbackStatus: '02',
feedbackStatus
:
'02'
,
//
content: '',
content
:
''
,
//
})
})
//
showToast('感谢您的反馈', 'success')
showToast
(
'感谢您的反馈'
,
'success'
)
//
}
}
//
else {
else
{
//
setIsUnLike(false)
setIsUnLike
(
false
)
//
await fetchSubmitFeedback({
await
fetchSubmitFeedback
({
//
recordId: answer.recordId,
recordId
:
answer
.
recordId
,
//
feedbackStatus: '00',
feedbackStatus
:
'00'
,
//
content: '',
content
:
''
,
//
})
})
//
}
}
//
}
}
const
handleClose
=
(
isSubmit
?:
boolean
)
=>
{
const
handleClose
=
(
isSubmit
?:
boolean
)
=>
{
setIsOpenUnLikeOpen
(
false
)
setIsOpenUnLikeOpen
(
false
)
...
@@ -104,40 +109,40 @@ export const ChatAnswerOperate: React.FC<ChatAnswerOperateProps> = ({ answer })
...
@@ -104,40 +109,40 @@ export const ChatAnswerOperate: React.FC<ChatAnswerOperateProps> = ({ answer })
}
}
}
}
//
const handleCopy = async () => {
const
handleCopy
=
async
()
=>
{
//
try {
try
{
//
await navigator.clipboard.writeText(answer.answer)
await
navigator
.
clipboard
.
writeText
(
answer
.
answer
)
//
showToast('复制成功!', 'success')
showToast
(
'复制成功!'
,
'success'
)
//
}
}
//
catch {
catch
{
//
// 如果 clipboard API 不可用,使用传统方法
// 如果 clipboard API 不可用,使用传统方法
//
const textArea = document.createElement('textarea')
const
textArea
=
document
.
createElement
(
'textarea'
)
//
textArea.value = answer.answer
textArea
.
value
=
answer
.
answer
//
document.body.appendChild(textArea)
document
.
body
.
appendChild
(
textArea
)
//
textArea.select()
textArea
.
select
()
//
document.execCommand('copy')
document
.
execCommand
(
'copy'
)
//
document.body.removeChild(textArea)
document
.
body
.
removeChild
(
textArea
)
//
showToast('复制成功!', 'success')
showToast
(
'复制成功!'
,
'success'
)
//
}
}
//
}
}
return
(
return
(
<
div
className=
"sm:mt-[12px] flex gap-[4px] justify-end"
>
<
div
className=
"sm:mt-[12px] flex gap-[4px] justify-end"
>
{
/* 点赞 */
}
{
/* 点赞 */
}
{
/*
<Tooltip color="foreground" content={isLike ? '取消点赞' : '点赞'} className="capitalize">
<
Tooltip
color=
"foreground"
content=
{
isLike
?
'取消点赞'
:
'点赞'
}
className=
"capitalize"
>
<
Button
variant=
"light"
isIconOnly
aria
-
label=
"LikeIcon"
onPress=
{
handleLike
.
run
}
>
<
Button
variant=
"light"
isIconOnly
aria
-
label=
"LikeIcon"
onPress=
{
handleLike
.
run
}
>
{
isLike
?
<
LikeIconA
/>
:
<
LikeIcon
/>
}
{
isLike
?
<
LikeIconA
/>
:
<
LikeIcon
/>
}
</
Button
>
</
Button
>
</Tooltip>
*/
}
</
Tooltip
>
{
/* 点踩 */
}
{
/* 点踩 */
}
{
/*
<Tooltip color="foreground" content={isUnLike ? '取消点踩' : '点踩'} className="capitalize">
<
Tooltip
color=
"foreground"
content=
{
isUnLike
?
'取消点踩'
:
'点踩'
}
className=
"capitalize"
>
<
Button
variant=
"light"
isIconOnly
aria
-
label=
"UnLikeIcon"
onPress=
{
handleUnLike
}
>
<
Button
variant=
"light"
isIconOnly
aria
-
label=
"UnLikeIcon"
onPress=
{
handleUnLike
}
>
{
isUnLike
?
<
UnLikeIconA
/>
:
<
UnLikeIcon
/>
}
{
isUnLike
?
<
UnLikeIconA
/>
:
<
UnLikeIcon
/>
}
</
Button
>
</
Button
>
</Tooltip>
*/
}
</
Tooltip
>
{
/* 复制 */
}
{
/* 复制 */
}
{
/*
<Tooltip color="foreground" content="复制" className="capitalize">
<
Tooltip
color=
"foreground"
content=
"复制"
className=
"capitalize"
>
<
Button
variant=
"light"
isIconOnly
aria
-
label=
"CopyIcon"
onPress=
{
handleCopy
}
><
CopyIcon
/></
Button
>
<
Button
variant=
"light"
isIconOnly
aria
-
label=
"CopyIcon"
onPress=
{
handleCopy
}
><
CopyIcon
/></
Button
>
</Tooltip>
*/
}
</
Tooltip
>
{
/* 收藏 */
}
{
/* 收藏 */
}
<
Tooltip
color=
"foreground"
content=
{
isCollect
?
'取消收藏'
:
'收藏'
}
className=
"capitalize"
>
<
Tooltip
color=
"foreground"
content=
{
isCollect
?
'取消收藏'
:
'收藏'
}
className=
"capitalize"
>
<
Button
variant=
"light"
isIconOnly
aria
-
label=
"CollectIcon"
onPress=
{
handleCollect
.
run
}
>
<
Button
variant=
"light"
isIconOnly
aria
-
label=
"CollectIcon"
onPress=
{
handleCollect
.
run
}
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment