mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-25 07:16:51 +00:00
fix:修复了日期选择的问题
This commit is contained in:
@@ -5,6 +5,7 @@ import { useChatStore } from '../stores/chatStore'
|
|||||||
import type { ChatSession, Message } from '../types/models'
|
import type { ChatSession, Message } from '../types/models'
|
||||||
import { getEmojiPath } from 'wechat-emojis'
|
import { getEmojiPath } from 'wechat-emojis'
|
||||||
import { ImagePreview } from '../components/ImagePreview'
|
import { ImagePreview } from '../components/ImagePreview'
|
||||||
|
import * as configService from '../services/config'
|
||||||
import './ChatPage.scss'
|
import './ChatPage.scss'
|
||||||
|
|
||||||
interface ChatPageProps {
|
interface ChatPageProps {
|
||||||
@@ -1317,6 +1318,16 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat }:
|
|||||||
const [voiceTranscriptError, setVoiceTranscriptError] = useState(false)
|
const [voiceTranscriptError, setVoiceTranscriptError] = useState(false)
|
||||||
const voiceTranscriptRequestedRef = useRef(false)
|
const voiceTranscriptRequestedRef = useRef(false)
|
||||||
const [showImagePreview, setShowImagePreview] = useState(false)
|
const [showImagePreview, setShowImagePreview] = useState(false)
|
||||||
|
const [autoTranscribeVoice, setAutoTranscribeVoice] = useState(true)
|
||||||
|
|
||||||
|
// 加载自动转文字配置
|
||||||
|
useEffect(() => {
|
||||||
|
const loadConfig = async () => {
|
||||||
|
const enabled = await configService.getAutoTranscribeVoice()
|
||||||
|
setAutoTranscribeVoice(enabled)
|
||||||
|
}
|
||||||
|
loadConfig()
|
||||||
|
}, [])
|
||||||
|
|
||||||
// 从缓存获取表情包 data URL
|
// 从缓存获取表情包 data URL
|
||||||
const cacheKey = message.emojiMd5 || message.emojiCdnUrl || ''
|
const cacheKey = message.emojiMd5 || message.emojiCdnUrl || ''
|
||||||
@@ -1638,10 +1649,11 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat }:
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isVoice) return
|
if (!isVoice) return
|
||||||
if (!voiceDataUrl) return
|
if (!voiceDataUrl) return
|
||||||
|
if (!autoTranscribeVoice) return // 如果自动转文字已关闭,不自动转文字
|
||||||
if (voiceTranscriptError) return
|
if (voiceTranscriptError) return
|
||||||
if (voiceTranscriptLoading || voiceTranscript !== undefined || voiceTranscriptRequestedRef.current) return
|
if (voiceTranscriptLoading || voiceTranscript !== undefined || voiceTranscriptRequestedRef.current) return
|
||||||
void requestVoiceTranscript()
|
void requestVoiceTranscript()
|
||||||
}, [isVoice, voiceDataUrl, voiceTranscript, voiceTranscriptError, voiceTranscriptLoading, requestVoiceTranscript])
|
}, [isVoice, voiceDataUrl, autoTranscribeVoice, voiceTranscript, voiceTranscriptError, voiceTranscriptLoading, requestVoiceTranscript])
|
||||||
|
|
||||||
if (isSystem) {
|
if (isSystem) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -215,18 +215,54 @@ function ExportPage() {
|
|||||||
const year = calendarDate.getFullYear()
|
const year = calendarDate.getFullYear()
|
||||||
const month = calendarDate.getMonth()
|
const month = calendarDate.getMonth()
|
||||||
const selectedDate = new Date(year, month, day)
|
const selectedDate = new Date(year, month, day)
|
||||||
|
// 设置时间为当天的开始或结束
|
||||||
|
selectedDate.setHours(selectingStart ? 0 : 23, selectingStart ? 0 : 59, selectingStart ? 0 : 59, selectingStart ? 0 : 999)
|
||||||
|
|
||||||
|
const now = new Date()
|
||||||
|
// 如果选择的日期晚于当前时间,限制为当前时间
|
||||||
|
if (selectedDate > now) {
|
||||||
|
selectedDate.setTime(now.getTime())
|
||||||
|
}
|
||||||
|
|
||||||
if (selectingStart) {
|
if (selectingStart) {
|
||||||
setOptions({
|
// 选择开始日期
|
||||||
...options,
|
const currentEnd = options.dateRange?.end || new Date()
|
||||||
dateRange: options.dateRange ? { ...options.dateRange, start: selectedDate } : { start: selectedDate, end: new Date() }
|
// 如果选择的开始日期晚于结束日期,则同时更新结束日期
|
||||||
})
|
if (selectedDate > currentEnd) {
|
||||||
|
const newEnd = new Date(selectedDate)
|
||||||
|
newEnd.setHours(23, 59, 59, 999)
|
||||||
|
// 确保结束日期也不晚于当前时间
|
||||||
|
if (newEnd > now) {
|
||||||
|
newEnd.setTime(now.getTime())
|
||||||
|
}
|
||||||
|
setOptions({
|
||||||
|
...options,
|
||||||
|
dateRange: { start: selectedDate, end: newEnd }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setOptions({
|
||||||
|
...options,
|
||||||
|
dateRange: options.dateRange ? { ...options.dateRange, start: selectedDate } : { start: selectedDate, end: new Date() }
|
||||||
|
})
|
||||||
|
}
|
||||||
setSelectingStart(false)
|
setSelectingStart(false)
|
||||||
} else {
|
} else {
|
||||||
setOptions({
|
// 选择结束日期
|
||||||
...options,
|
const currentStart = options.dateRange?.start || new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)
|
||||||
dateRange: options.dateRange ? { ...options.dateRange, end: selectedDate } : { start: new Date(), end: selectedDate }
|
// 如果选择的结束日期早于开始日期,则同时更新开始日期
|
||||||
})
|
if (selectedDate < currentStart) {
|
||||||
|
const newStart = new Date(selectedDate)
|
||||||
|
newStart.setHours(0, 0, 0, 0)
|
||||||
|
setOptions({
|
||||||
|
...options,
|
||||||
|
dateRange: { start: newStart, end: selectedDate }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setOptions({
|
||||||
|
...options,
|
||||||
|
dateRange: options.dateRange ? { ...options.dateRange, end: selectedDate } : { start: new Date(), end: selectedDate }
|
||||||
|
})
|
||||||
|
}
|
||||||
setSelectingStart(true)
|
setSelectingStart(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -547,6 +583,9 @@ function ExportPage() {
|
|||||||
<div className="export-overlay" onClick={() => setShowDatePicker(false)}>
|
<div className="export-overlay" onClick={() => setShowDatePicker(false)}>
|
||||||
<div className="date-picker-modal" onClick={e => e.stopPropagation()}>
|
<div className="date-picker-modal" onClick={e => e.stopPropagation()}>
|
||||||
<h3>选择时间范围</h3>
|
<h3>选择时间范围</h3>
|
||||||
|
<p style={{ fontSize: '13px', color: 'var(--text-secondary)', margin: '8px 0 16px 0' }}>
|
||||||
|
点击选择开始和结束日期,系统会自动调整确保时间顺序正确
|
||||||
|
</p>
|
||||||
<div className="quick-select">
|
<div className="quick-select">
|
||||||
<button
|
<button
|
||||||
className="quick-btn"
|
className="quick-btn"
|
||||||
@@ -641,12 +680,16 @@ function ExportPage() {
|
|||||||
const isStart = options.dateRange?.start.toDateString() === currentDate.toDateString()
|
const isStart = options.dateRange?.start.toDateString() === currentDate.toDateString()
|
||||||
const isEnd = options.dateRange?.end.toDateString() === currentDate.toDateString()
|
const isEnd = options.dateRange?.end.toDateString() === currentDate.toDateString()
|
||||||
const isInRange = options.dateRange && currentDate >= options.dateRange.start && currentDate <= options.dateRange.end
|
const isInRange = options.dateRange && currentDate >= options.dateRange.start && currentDate <= options.dateRange.end
|
||||||
|
const today = new Date()
|
||||||
|
today.setHours(0, 0, 0, 0)
|
||||||
|
const isFuture = currentDate > today
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={day}
|
key={day}
|
||||||
className={`calendar-day ${isStart ? 'start' : ''} ${isEnd ? 'end' : ''} ${isInRange ? 'in-range' : ''}`}
|
className={`calendar-day ${isStart ? 'start' : ''} ${isEnd ? 'end' : ''} ${isInRange ? 'in-range' : ''} ${isFuture ? 'disabled' : ''}`}
|
||||||
onClick={() => handleDateSelect(day)}
|
onClick={() => !isFuture && handleDateSelect(day)}
|
||||||
|
style={{ cursor: isFuture ? 'not-allowed' : 'pointer', opacity: isFuture ? 0.3 : 1 }}
|
||||||
>
|
>
|
||||||
{day}
|
{day}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ function SettingsPage() {
|
|||||||
const [whisperModelName, setWhisperModelName] = useState('base')
|
const [whisperModelName, setWhisperModelName] = useState('base')
|
||||||
const [whisperModelDir, setWhisperModelDir] = useState('')
|
const [whisperModelDir, setWhisperModelDir] = useState('')
|
||||||
const [whisperDownloadSource, setWhisperDownloadSource] = useState('tsinghua')
|
const [whisperDownloadSource, setWhisperDownloadSource] = useState('tsinghua')
|
||||||
|
const [autoTranscribeVoice, setAutoTranscribeVoice] = useState(true)
|
||||||
const [isWhisperDownloading, setIsWhisperDownloading] = useState(false)
|
const [isWhisperDownloading, setIsWhisperDownloading] = useState(false)
|
||||||
const [whisperDownloadProgress, setWhisperDownloadProgress] = useState(0)
|
const [whisperDownloadProgress, setWhisperDownloadProgress] = useState(0)
|
||||||
const [whisperModelStatus, setWhisperModelStatus] = useState<{ exists: boolean; path?: string } | null>(null)
|
const [whisperModelStatus, setWhisperModelStatus] = useState<{ exists: boolean; path?: string } | null>(null)
|
||||||
@@ -125,6 +126,7 @@ function SettingsPage() {
|
|||||||
const savedWhisperModelName = await configService.getWhisperModelName()
|
const savedWhisperModelName = await configService.getWhisperModelName()
|
||||||
const savedWhisperModelDir = await configService.getWhisperModelDir()
|
const savedWhisperModelDir = await configService.getWhisperModelDir()
|
||||||
const savedWhisperSource = await configService.getWhisperDownloadSource()
|
const savedWhisperSource = await configService.getWhisperDownloadSource()
|
||||||
|
const savedAutoTranscribeVoice = await configService.getAutoTranscribeVoice()
|
||||||
|
|
||||||
if (savedKey) setDecryptKey(savedKey)
|
if (savedKey) setDecryptKey(savedKey)
|
||||||
if (savedPath) setDbPath(savedPath)
|
if (savedPath) setDbPath(savedPath)
|
||||||
@@ -138,6 +140,7 @@ function SettingsPage() {
|
|||||||
if (savedWhisperModelName) setWhisperModelName(savedWhisperModelName)
|
if (savedWhisperModelName) setWhisperModelName(savedWhisperModelName)
|
||||||
if (savedWhisperModelDir) setWhisperModelDir(savedWhisperModelDir)
|
if (savedWhisperModelDir) setWhisperModelDir(savedWhisperModelDir)
|
||||||
if (savedWhisperSource) setWhisperDownloadSource(savedWhisperSource)
|
if (savedWhisperSource) setWhisperDownloadSource(savedWhisperSource)
|
||||||
|
setAutoTranscribeVoice(savedAutoTranscribeVoice)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('加载配置失败:', e)
|
console.error('加载配置失败:', e)
|
||||||
}
|
}
|
||||||
@@ -762,8 +765,25 @@ function SettingsPage() {
|
|||||||
<p className="section-desc">语音解密后自动转写为文字</p>
|
<p className="section-desc">语音解密后自动转写为文字</p>
|
||||||
<div className="form-group whisper-section">
|
<div className="form-group whisper-section">
|
||||||
<label>语音识别模型 (Whisper)</label>
|
<label>语音识别模型 (Whisper)</label>
|
||||||
<span className="form-hint">语音解密后自动转文字,模型越大越准确但下载更慢</span>
|
<span className="form-hint">点击语音解密后自动转文字,模型越大越准确但下载更慢</span>
|
||||||
<div className="whisper-grid">
|
|
||||||
|
<label style={{ marginTop: '12px', marginBottom: '8px', display: 'block' }}>自动转文字开关</label>
|
||||||
|
<label className="switch" htmlFor="auto-transcribe-toggle">
|
||||||
|
<input
|
||||||
|
id="auto-transcribe-toggle"
|
||||||
|
className="switch-input"
|
||||||
|
type="checkbox"
|
||||||
|
checked={autoTranscribeVoice}
|
||||||
|
onChange={(e) => {
|
||||||
|
const enabled = e.target.checked
|
||||||
|
setAutoTranscribeVoice(enabled)
|
||||||
|
configService.setAutoTranscribeVoice(enabled)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span className="switch-slider" />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div className="whisper-grid" style={{ marginTop: '16px' }}>
|
||||||
<div className="whisper-field">
|
<div className="whisper-field">
|
||||||
<span className="field-label">模型</span>
|
<span className="field-label">模型</span>
|
||||||
<select
|
<select
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ export const CONFIG_KEYS = {
|
|||||||
IMAGE_AES_KEY: 'imageAesKey',
|
IMAGE_AES_KEY: 'imageAesKey',
|
||||||
WHISPER_MODEL_NAME: 'whisperModelName',
|
WHISPER_MODEL_NAME: 'whisperModelName',
|
||||||
WHISPER_MODEL_DIR: 'whisperModelDir',
|
WHISPER_MODEL_DIR: 'whisperModelDir',
|
||||||
WHISPER_DOWNLOAD_SOURCE: 'whisperDownloadSource'
|
WHISPER_DOWNLOAD_SOURCE: 'whisperDownloadSource',
|
||||||
|
AUTO_TRANSCRIBE_VOICE: 'autoTranscribeVoice'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
// 获取解密密钥
|
// 获取解密密钥
|
||||||
@@ -218,3 +219,15 @@ export async function getOnboardingDone(): Promise<boolean> {
|
|||||||
export async function setOnboardingDone(done: boolean): Promise<void> {
|
export async function setOnboardingDone(done: boolean): Promise<void> {
|
||||||
await config.set(CONFIG_KEYS.ONBOARDING_DONE, done)
|
await config.set(CONFIG_KEYS.ONBOARDING_DONE, done)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取是否自动转文字
|
||||||
|
export async function getAutoTranscribeVoice(): Promise<boolean> {
|
||||||
|
const value = await config.get(CONFIG_KEYS.AUTO_TRANSCRIBE_VOICE)
|
||||||
|
// 默认为 true
|
||||||
|
return value !== false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置是否自动转文字
|
||||||
|
export async function setAutoTranscribeVoice(enabled: boolean): Promise<void> {
|
||||||
|
await config.set(CONFIG_KEYS.AUTO_TRANSCRIBE_VOICE, enabled)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user