完善家长留言录音与会话展示
This commit is contained in:
@@ -85,8 +85,8 @@ const DEFAULT_RECORD_PROFILE: RecordProfile = {
|
|||||||
const COMPAT_RECORD_PROFILE: RecordProfile = {
|
const COMPAT_RECORD_PROFILE: RecordProfile = {
|
||||||
format: 'aac',
|
format: 'aac',
|
||||||
mimeType: 'audio/aac',
|
mimeType: 'audio/aac',
|
||||||
sampleRate: 16000,
|
sampleRate: 44100,
|
||||||
encodeBitRate: 64000,
|
encodeBitRate: 192000,
|
||||||
}
|
}
|
||||||
|
|
||||||
const FALLBACK_RUNTIME_INFO: VoiceRuntimeInfo = {
|
const FALLBACK_RUNTIME_INFO: VoiceRuntimeInfo = {
|
||||||
@@ -105,6 +105,11 @@ const FALLBACK_RUNTIME_INFO: VoiceRuntimeInfo = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const CHAT_BOTTOM_ANCHOR_ID = 'chat-bottom'
|
const CHAT_BOTTOM_ANCHOR_ID = 'chat-bottom'
|
||||||
|
const RECORD_LONG_PRESS_DELAY_MS = 350
|
||||||
|
|
||||||
|
type LoadChatOptions = {
|
||||||
|
showLoading?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
function compareVersion(left: string, right: string): number {
|
function compareVersion(left: string, right: string): number {
|
||||||
const leftParts = left.split('.').map((item) => Number(item) || 0)
|
const leftParts = left.split('.').map((item) => Number(item) || 0)
|
||||||
@@ -162,7 +167,7 @@ function readVoiceRuntimeInfo(): VoiceRuntimeInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getPreferredRecordProfile(runtime: VoiceRuntimeInfo): RecordProfile {
|
function getPreferredRecordProfile(runtime: VoiceRuntimeInfo): RecordProfile {
|
||||||
if (runtime.isHarmony || !runtime.supportsMp3Record) return COMPAT_RECORD_PROFILE
|
if (runtime.isIOS || runtime.isHarmony || !runtime.supportsMp3Record) return COMPAT_RECORD_PROFILE
|
||||||
return DEFAULT_RECORD_PROFILE
|
return DEFAULT_RECORD_PROFILE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,13 +235,21 @@ export default function ChatDetail() {
|
|||||||
const audioContextRef = useRef<Taro.InnerAudioContext | null>(null)
|
const audioContextRef = useRef<Taro.InnerAudioContext | null>(null)
|
||||||
const recorderManagerRef = useRef<Taro.RecorderManager | null>(null)
|
const recorderManagerRef = useRef<Taro.RecorderManager | null>(null)
|
||||||
const activeConversationIdRef = useRef(initialConversationId)
|
const activeConversationIdRef = useRef(initialConversationId)
|
||||||
const latestLoadChatDataRef = useRef<(conversationId: number) => Promise<void>>(async () => {})
|
const latestLoadChatDataRef = useRef<(conversationId: number, options?: LoadChatOptions) => Promise<void>>(
|
||||||
|
async () => {}
|
||||||
|
)
|
||||||
const recordingChildIdRef = useRef<number | null>(null)
|
const recordingChildIdRef = useRef<number | null>(null)
|
||||||
const recordProfileRef = useRef<RecordProfile>(DEFAULT_RECORD_PROFILE)
|
const recordProfileRef = useRef<RecordProfile>(DEFAULT_RECORD_PROFILE)
|
||||||
const runtimeInfoRef = useRef<VoiceRuntimeInfo>(FALLBACK_RUNTIME_INFO)
|
const runtimeInfoRef = useRef<VoiceRuntimeInfo>(FALLBACK_RUNTIME_INFO)
|
||||||
const recordStartedAtRef = useRef<number>(0)
|
const recordStartedAtRef = useRef<number>(0)
|
||||||
const playingMessageIdRef = useRef<number | null>(null)
|
const playingMessageIdRef = useRef<number | null>(null)
|
||||||
const scrollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
const scrollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||||
|
const recordStartTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||||
|
const hasLoadedChatRef = useRef(false)
|
||||||
|
const skipNextAutoLoadRef = useRef(false)
|
||||||
|
const recordPressedRef = useRef(false)
|
||||||
|
const recordStartPendingRef = useRef(false)
|
||||||
|
const recordingActiveRef = useRef(false)
|
||||||
|
|
||||||
const scrollToBottom = () => {
|
const scrollToBottom = () => {
|
||||||
if (scrollTimerRef.current) {
|
if (scrollTimerRef.current) {
|
||||||
@@ -311,6 +324,10 @@ export default function ChatDetail() {
|
|||||||
clearTimeout(scrollTimerRef.current)
|
clearTimeout(scrollTimerRef.current)
|
||||||
scrollTimerRef.current = null
|
scrollTimerRef.current = null
|
||||||
}
|
}
|
||||||
|
if (recordStartTimerRef.current) {
|
||||||
|
clearTimeout(recordStartTimerRef.current)
|
||||||
|
recordStartTimerRef.current = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
@@ -323,11 +340,18 @@ export default function ChatDetail() {
|
|||||||
}, [playingMessageId])
|
}, [playingMessageId])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (skipNextAutoLoadRef.current) {
|
||||||
|
skipNextAutoLoadRef.current = false
|
||||||
|
return
|
||||||
|
}
|
||||||
void loadChatData(activeConversationId)
|
void loadChatData(activeConversationId)
|
||||||
}, [activeConversationId, conversationSource, conversationPeerKind])
|
}, [activeConversationId, conversationSource, conversationPeerKind])
|
||||||
|
|
||||||
const loadChatData = async (conversationId: number) => {
|
const loadChatData = async (conversationId: number, options: LoadChatOptions = {}) => {
|
||||||
setLoading(true)
|
const shouldShowLoading = options.showLoading ?? !hasLoadedChatRef.current
|
||||||
|
if (shouldShowLoading) {
|
||||||
|
setLoading(true)
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const char = await getCharacter({
|
const char = await getCharacter({
|
||||||
conversationId,
|
conversationId,
|
||||||
@@ -352,6 +376,7 @@ export default function ChatDetail() {
|
|||||||
if (msgs.length > 0) {
|
if (msgs.length > 0) {
|
||||||
scrollToBottom()
|
scrollToBottom()
|
||||||
}
|
}
|
||||||
|
hasLoadedChatRef.current = true
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('[chat-detail] load failed:', error)
|
console.error('[chat-detail] load failed:', error)
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
@@ -375,6 +400,8 @@ export default function ChatDetail() {
|
|||||||
recorderManagerRef.current = recorderManager
|
recorderManagerRef.current = recorderManager
|
||||||
|
|
||||||
recorderManager.onStart(() => {
|
recorderManager.onStart(() => {
|
||||||
|
recordingActiveRef.current = true
|
||||||
|
recordStartPendingRef.current = false
|
||||||
console.info('[record] started', {
|
console.info('[record] started', {
|
||||||
profile: recordProfileRef.current,
|
profile: recordProfileRef.current,
|
||||||
runtime: runtimeInfoRef.current,
|
runtime: runtimeInfoRef.current,
|
||||||
@@ -384,6 +411,8 @@ export default function ChatDetail() {
|
|||||||
recorderManager.onError((error) => {
|
recorderManager.onError((error) => {
|
||||||
recordingChildIdRef.current = null
|
recordingChildIdRef.current = null
|
||||||
recordStartedAtRef.current = 0
|
recordStartedAtRef.current = 0
|
||||||
|
recordStartPendingRef.current = false
|
||||||
|
recordingActiveRef.current = false
|
||||||
setRecording(false)
|
setRecording(false)
|
||||||
setRecordHint('长按开始留言')
|
setRecordHint('长按开始留言')
|
||||||
console.error('[record] error', {
|
console.error('[record] error', {
|
||||||
@@ -400,6 +429,8 @@ export default function ChatDetail() {
|
|||||||
const fallbackDurationMs = startedAt > 0 ? Date.now() - startedAt : 0
|
const fallbackDurationMs = startedAt > 0 ? Date.now() - startedAt : 0
|
||||||
recordingChildIdRef.current = null
|
recordingChildIdRef.current = null
|
||||||
recordStartedAtRef.current = 0
|
recordStartedAtRef.current = 0
|
||||||
|
recordStartPendingRef.current = false
|
||||||
|
recordingActiveRef.current = false
|
||||||
setRecording(false)
|
setRecording(false)
|
||||||
setRecordHint('长按开始留言')
|
setRecordHint('长按开始留言')
|
||||||
|
|
||||||
@@ -447,9 +478,11 @@ export default function ChatDetail() {
|
|||||||
messageId: response.message?.id,
|
messageId: response.message?.id,
|
||||||
})
|
})
|
||||||
if (response.conversation_id && response.conversation_id !== activeConversationIdRef.current) {
|
if (response.conversation_id && response.conversation_id !== activeConversationIdRef.current) {
|
||||||
|
skipNextAutoLoadRef.current = true
|
||||||
setActiveConversationId(response.conversation_id)
|
setActiveConversationId(response.conversation_id)
|
||||||
|
await latestLoadChatDataRef.current(response.conversation_id, { showLoading: false })
|
||||||
} else {
|
} else {
|
||||||
await latestLoadChatDataRef.current(activeConversationIdRef.current)
|
await latestLoadChatDataRef.current(activeConversationIdRef.current, { showLoading: false })
|
||||||
}
|
}
|
||||||
Taro.showToast({ title: '留言已发送', icon: 'success' })
|
Taro.showToast({ title: '留言已发送', icon: 'success' })
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -502,8 +535,15 @@ export default function ChatDetail() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRecordStart = async () => {
|
const resetRecordStartTimer = () => {
|
||||||
if (sending || recording) return
|
if (recordStartTimerRef.current) {
|
||||||
|
clearTimeout(recordStartTimerRef.current)
|
||||||
|
recordStartTimerRef.current = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const startRecording = async () => {
|
||||||
|
if (sending || recordingActiveRef.current || recordStartPendingRef.current) return
|
||||||
if (!character.canSend || !character.childId) {
|
if (!character.canSend || !character.childId) {
|
||||||
Taro.showToast({ title: '当前会话不支持发送', icon: 'none' })
|
Taro.showToast({ title: '当前会话不支持发送', icon: 'none' })
|
||||||
return
|
return
|
||||||
@@ -515,8 +555,17 @@ export default function ChatDetail() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recordStartPendingRef.current = true
|
||||||
const hasPermission = await ensureRecordPermission()
|
const hasPermission = await ensureRecordPermission()
|
||||||
if (!hasPermission) return
|
if (!recordPressedRef.current) {
|
||||||
|
recordStartPendingRef.current = false
|
||||||
|
console.info('[record] start skipped: touch already ended')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!hasPermission) {
|
||||||
|
recordStartPendingRef.current = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const runtime = readVoiceRuntimeInfo()
|
const runtime = readVoiceRuntimeInfo()
|
||||||
const profile = getPreferredRecordProfile(runtime)
|
const profile = getPreferredRecordProfile(runtime)
|
||||||
@@ -524,6 +573,7 @@ export default function ChatDetail() {
|
|||||||
recordProfileRef.current = profile
|
recordProfileRef.current = profile
|
||||||
recordingChildIdRef.current = character.childId
|
recordingChildIdRef.current = character.childId
|
||||||
recordStartedAtRef.current = Date.now()
|
recordStartedAtRef.current = Date.now()
|
||||||
|
recordingActiveRef.current = true
|
||||||
setRecording(true)
|
setRecording(true)
|
||||||
setRecordHint('松开发送留言')
|
setRecordHint('松开发送留言')
|
||||||
console.info('[record] start request', {
|
console.info('[record] start request', {
|
||||||
@@ -542,6 +592,8 @@ export default function ChatDetail() {
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
recordingChildIdRef.current = null
|
recordingChildIdRef.current = null
|
||||||
recordStartedAtRef.current = 0
|
recordStartedAtRef.current = 0
|
||||||
|
recordStartPendingRef.current = false
|
||||||
|
recordingActiveRef.current = false
|
||||||
setRecording(false)
|
setRecording(false)
|
||||||
setRecordHint('长按开始留言')
|
setRecordHint('长按开始留言')
|
||||||
console.error('[record] start failed:', {
|
console.error('[record] start failed:', {
|
||||||
@@ -556,11 +608,49 @@ export default function ChatDetail() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleRecordTouchStart = () => {
|
||||||
|
if (sending || recordingActiveRef.current || recordStartPendingRef.current) return
|
||||||
|
recordPressedRef.current = true
|
||||||
|
resetRecordStartTimer()
|
||||||
|
setRecordHint('继续按住开始录音')
|
||||||
|
console.info('[record] touch start', {
|
||||||
|
delayMs: RECORD_LONG_PRESS_DELAY_MS,
|
||||||
|
runtime: runtimeInfoRef.current,
|
||||||
|
})
|
||||||
|
recordStartTimerRef.current = setTimeout(() => {
|
||||||
|
recordStartTimerRef.current = null
|
||||||
|
if (!recordPressedRef.current) return
|
||||||
|
console.info('[record] long press threshold reached')
|
||||||
|
void startRecording()
|
||||||
|
}, RECORD_LONG_PRESS_DELAY_MS)
|
||||||
|
}
|
||||||
|
|
||||||
const handleRecordStop = () => {
|
const handleRecordStop = () => {
|
||||||
if (!recording) return
|
recordPressedRef.current = false
|
||||||
|
resetRecordStartTimer()
|
||||||
|
console.info('[record] touch end', {
|
||||||
|
active: recordingActiveRef.current,
|
||||||
|
pending: recordStartPendingRef.current,
|
||||||
|
elapsedMs: recordStartedAtRef.current > 0 ? Date.now() - recordStartedAtRef.current : 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (recordStartPendingRef.current && !recordingActiveRef.current) {
|
||||||
|
setRecordHint('长按开始留言')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!recordingActiveRef.current) {
|
||||||
|
setRecordHint('长按开始留言')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
recordingActiveRef.current = false
|
||||||
const recorderManager = recorderManagerRef.current
|
const recorderManager = recorderManagerRef.current
|
||||||
if (!recorderManager) {
|
if (!recorderManager) {
|
||||||
console.warn('[record] stop skipped: recorder unavailable')
|
console.warn('[record] stop skipped: recorder unavailable')
|
||||||
|
recordingChildIdRef.current = null
|
||||||
|
recordStartedAtRef.current = 0
|
||||||
|
setRecording(false)
|
||||||
|
setRecordHint('长按开始留言')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,7 +658,21 @@ export default function ChatDetail() {
|
|||||||
console.info('[record] stop request', {
|
console.info('[record] stop request', {
|
||||||
elapsedMs: recordStartedAtRef.current > 0 ? Date.now() - recordStartedAtRef.current : 0,
|
elapsedMs: recordStartedAtRef.current > 0 ? Date.now() - recordStartedAtRef.current : 0,
|
||||||
})
|
})
|
||||||
recorderManager.stop()
|
try {
|
||||||
|
recorderManager.stop()
|
||||||
|
} catch (error) {
|
||||||
|
recordingChildIdRef.current = null
|
||||||
|
recordStartedAtRef.current = 0
|
||||||
|
recordStartPendingRef.current = false
|
||||||
|
setRecording(false)
|
||||||
|
setRecordHint('长按开始留言')
|
||||||
|
console.error('[record] stop failed', {
|
||||||
|
error,
|
||||||
|
profile: recordProfileRef.current,
|
||||||
|
runtime: runtimeInfoRef.current,
|
||||||
|
})
|
||||||
|
Taro.showToast({ title: '录音停止失败,请重试', icon: 'none' })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePlayAudio = (message: ChatMessage) => {
|
const handlePlayAudio = (message: ChatMessage) => {
|
||||||
@@ -706,7 +810,7 @@ export default function ChatDetail() {
|
|||||||
</View>
|
</View>
|
||||||
<View
|
<View
|
||||||
className={`composer-record ${recording ? 'recording' : ''} ${sending ? 'disabled' : ''}`}
|
className={`composer-record ${recording ? 'recording' : ''} ${sending ? 'disabled' : ''}`}
|
||||||
onLongPress={handleRecordStart}
|
onTouchStart={handleRecordTouchStart}
|
||||||
onTouchEnd={handleRecordStop}
|
onTouchEnd={handleRecordStop}
|
||||||
onTouchCancel={handleRecordStop}
|
onTouchCancel={handleRecordStop}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -296,6 +296,17 @@ function getPeerDisplayName(peerKind: PeerKind, peerId?: string, peerName?: stri
|
|||||||
return getParticipantDisplayName(peerKind, peerId, peerName)
|
return getParticipantDisplayName(peerKind, peerId, peerName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getParentConversationName(parentUserId: number | null, peerId: string, peerName: string | null | undefined, context: BindingContext): string {
|
||||||
|
if (parentUserId && parentUserId === context.currentUserId) return '家长沟通'
|
||||||
|
|
||||||
|
const displayName = getParticipantDisplayName('parent', peerId, peerName)
|
||||||
|
return `${displayName}的留言记录`
|
||||||
|
}
|
||||||
|
|
||||||
|
function canSendParentConversation(parentUserId: number | null, context: BindingContext): boolean {
|
||||||
|
return Boolean(parentUserId && parentUserId === context.currentUserId)
|
||||||
|
}
|
||||||
|
|
||||||
function getConversationRank(conversation: ChatConversation): number {
|
function getConversationRank(conversation: ChatConversation): number {
|
||||||
if (isParentChildConversation(conversation.conversationTypeName)) return 0
|
if (isParentChildConversation(conversation.conversationTypeName)) return 0
|
||||||
return 1
|
return 1
|
||||||
@@ -371,27 +382,34 @@ function toImConversation(item: ChildConversationItem, context: BindingContext):
|
|||||||
const isParentConversation = isParentChildConversation(item.conversation_type_name)
|
const isParentConversation = isParentChildConversation(item.conversation_type_name)
|
||||||
const peerKind: PeerKind = item.peer_type === 'parent' ? 'parent' : 'child'
|
const peerKind: PeerKind = item.peer_type === 'parent' ? 'parent' : 'child'
|
||||||
const meta = PEER_META[peerKind]
|
const meta = PEER_META[peerKind]
|
||||||
|
const parentUserId = isParentConversation ? parseNumericId(item.peer_id) : null
|
||||||
|
const canSend = isParentConversation ? canSendParentConversation(parentUserId, context) : false
|
||||||
|
const parentConversationName = getParentConversationName(parentUserId, item.peer_id, item.peer_name, context)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: item.conversation_id,
|
id: item.conversation_id,
|
||||||
key: `im-${item.conversation_id}`,
|
key: `im-${item.conversation_id}`,
|
||||||
source: 'im',
|
source: 'im',
|
||||||
peerKind,
|
peerKind,
|
||||||
name: isParentConversation ? '家长沟通' : getPeerDisplayName(peerKind, item.peer_id, item.peer_name),
|
name: isParentConversation ? parentConversationName : getPeerDisplayName(peerKind, item.peer_id, item.peer_name),
|
||||||
avatar: meta.icon,
|
avatar: meta.icon,
|
||||||
typeLabel: isParentConversation ? '家长沟通' : meta.label,
|
typeLabel: isParentConversation ? (canSend ? '家长沟通' : '留言记录') : meta.label,
|
||||||
description: isParentConversation ? '家长通过微信小程序和孩子直接沟通' : meta.description,
|
description: isParentConversation
|
||||||
lastMessage: item.last_message_preview || (isParentConversation ? '还没有消息,点进去发送第一条' : '暂无消息'),
|
? canSend
|
||||||
|
? '家长通过微信小程序和孩子直接沟通'
|
||||||
|
: '其他家长和孩子的留言记录'
|
||||||
|
: meta.description,
|
||||||
|
lastMessage: item.last_message_preview || (isParentConversation ? (canSend ? '还没有消息,点进去发送第一条' : '暂无留言记录') : '暂无消息'),
|
||||||
time: formatListTime(item.last_message_at),
|
time: formatListTime(item.last_message_at),
|
||||||
sortAt: item.last_message_at || '',
|
sortAt: item.last_message_at || '',
|
||||||
conversationTypeName: item.conversation_type_name,
|
conversationTypeName: item.conversation_type_name,
|
||||||
peerId: item.peer_id,
|
peerId: item.peer_id,
|
||||||
childId: context.childId,
|
childId: context.childId,
|
||||||
childName: context.childName,
|
childName: context.childName,
|
||||||
parentUserId: isParentConversation ? parseNumericId(item.peer_id) : null,
|
parentUserId,
|
||||||
deviceId: context.deviceId,
|
deviceId: context.deviceId,
|
||||||
channelLabel: isParentConversation ? '微信小程序' : '设备端',
|
channelLabel: isParentConversation ? '微信小程序' : '设备端',
|
||||||
canSend: isParentConversation,
|
canSend,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,6 +614,7 @@ export async function getCharacter(options: {
|
|||||||
channelLabel,
|
channelLabel,
|
||||||
canSend = false,
|
canSend = false,
|
||||||
} = options
|
} = options
|
||||||
|
const context = await getBindingContext()
|
||||||
|
|
||||||
if (source === 'ai') {
|
if (source === 'ai') {
|
||||||
const meta = getAiMeta(roleKey)
|
const meta = getAiMeta(roleKey)
|
||||||
@@ -618,10 +637,14 @@ export async function getCharacter(options: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isParentChildConversation(conversationTypeName)) {
|
if (isParentChildConversation(conversationTypeName)) {
|
||||||
|
const normalizedParentUserId = parentUserId || parseNumericId(peerId)
|
||||||
|
const canSendParentMessage = Boolean(canSend && normalizedParentUserId === context.currentUserId)
|
||||||
|
const normalizedName = name || getParentConversationName(normalizedParentUserId, peerId || '', null, context)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: conversationId,
|
id: conversationId,
|
||||||
name: '家长沟通',
|
name: normalizedName,
|
||||||
description: '微信小程序 <-> 儿童设备',
|
description: canSendParentMessage ? '微信小程序 <-> 儿童设备' : '其他家长和孩子的留言记录',
|
||||||
icon: PEER_META.parent.icon,
|
icon: PEER_META.parent.icon,
|
||||||
peerKind: 'parent',
|
peerKind: 'parent',
|
||||||
source,
|
source,
|
||||||
@@ -629,10 +652,10 @@ export async function getCharacter(options: {
|
|||||||
childId,
|
childId,
|
||||||
childName,
|
childName,
|
||||||
peerId,
|
peerId,
|
||||||
parentUserId: parentUserId || parseNumericId(peerId),
|
parentUserId: normalizedParentUserId,
|
||||||
deviceId,
|
deviceId,
|
||||||
channelLabel: channelLabel || '微信小程序',
|
channelLabel: channelLabel || '微信小程序',
|
||||||
canSend: canSend || true,
|
canSend: canSendParentMessage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user