feat: 支持配置每次拉取消息数

This commit is contained in:
digua authored and digua committed 2026-04-26 23:38:29 +08:00
1 parent 352a071a21
commit c97e2e7098
13 files changed
+92 -22

No files matched your search

+8 -1
View File
@@ -30,6 +30,7 @@ export interface DataSource {
baseUrl: string
token: string
intervalMinutes: number
pullLimit: number
enabled: boolean
createdAt: number
sessions: ImportSession[]
@@ -62,6 +63,9 @@ export function loadDataSources(): DataSource[] {
return []
}
for (const ds of parsed) {
if (!ds.pullLimit) ds.pullLimit = 1000
}
return parsed
}
} catch (err) {
@@ -101,6 +105,7 @@ export function addDataSource(partial: {
baseUrl: string
token: string
intervalMinutes: number
pullLimit?: number
}): DataSource {
const sources = loadDataSources()
const ds: DataSource = {
@@ -109,6 +114,7 @@ export function addDataSource(partial: {
baseUrl: normalizeBaseUrl(partial.baseUrl),
token: partial.token,
intervalMinutes: partial.intervalMinutes,
pullLimit: partial.pullLimit || 1000,
enabled: true,
createdAt: Math.floor(Date.now() / 1000),
sessions: [],
@@ -120,7 +126,7 @@ export function addDataSource(partial: {
export function updateDataSource(
id: string,
updates: Partial<Pick<DataSource, 'name' | 'baseUrl' | 'token' | 'intervalMinutes' | 'enabled'>>
updates: Partial<Pick<DataSource, 'name' | 'baseUrl' | 'token' | 'intervalMinutes' | 'pullLimit' | 'enabled'>>
): DataSource | null {
const sources = loadDataSources()
const idx = sources.findIndex((s) => s.id === id)
@@ -130,6 +136,7 @@ export function updateDataSource(
if (updates.baseUrl !== undefined) ds.baseUrl = normalizeBaseUrl(updates.baseUrl)
if (updates.token !== undefined) ds.token = updates.token
if (updates.intervalMinutes !== undefined) ds.intervalMinutes = updates.intervalMinutes
if (updates.pullLimit !== undefined) ds.pullLimit = updates.pullLimit
if (updates.enabled !== undefined) ds.enabled = updates.enabled
saveDataSources(sources)
return ds
+1 -2
View File
@@ -233,7 +233,6 @@ async function importTempFile(baseUrl: string, sess: ImportSession, tempFile: st
// ==================== Core pull loop (per ImportSession) ====================
const MAX_PAGES_PER_PULL = 50
const DEFAULT_PULL_LIMIT = 1000
const PULL_OVERLAP_SECONDS = 60
interface PullSessionResult {
@@ -264,7 +263,7 @@ async function executePullSession(sourceId: string, ds: DataSource, sess: Import
since,
offset,
end,
limit: DEFAULT_PULL_LIMIT,
limit: ds.pullLimit,
})
try {
+5 -2
View File
@@ -59,7 +59,10 @@ export function registerApiHandlers(_ctx: IpcContext): void {
ipcMain.handle(
'api:addDataSource',
(_event, partial: { name?: string; baseUrl: string; token: string; intervalMinutes: number }) => {
(
_event,
partial: { name?: string; baseUrl: string; token: string; intervalMinutes: number; pullLimit?: number }
) => {
const ds = addDataSource(partial)
return ds
}
@@ -70,7 +73,7 @@ export function registerApiHandlers(_ctx: IpcContext): void {
(
_event,
id: string,
updates: Partial<Pick<DataSource, 'name' | 'baseUrl' | 'token' | 'intervalMinutes' | 'enabled'>>
updates: Partial<Pick<DataSource, 'name' | 'baseUrl' | 'token' | 'intervalMinutes' | 'pullLimit' | 'enabled'>>
) => {
const ds = updateDataSource(id, updates)
if (ds) {
+3 -1
View File
@@ -35,6 +35,7 @@ export interface DataSource {
baseUrl: string
token: string
intervalMinutes: number
pullLimit: number
enabled: boolean
createdAt: number
sessions: ImportSession[]
@@ -100,13 +101,14 @@ export const apiServerApi = {
baseUrl: string
token: string
intervalMinutes: number
pullLimit?: number
}): Promise<DataSource> => {
return ipcRenderer.invoke('api:addDataSource', partial)
},
updateDataSource: (
id: string,
updates: Partial<Pick<DataSource, 'name' | 'baseUrl' | 'token' | 'intervalMinutes' | 'enabled'>>
updates: Partial<Pick<DataSource, 'name' | 'baseUrl' | 'token' | 'intervalMinutes' | 'pullLimit' | 'enabled'>>
): Promise<DataSource | null> => {
return ipcRenderer.invoke('api:updateDataSource', id, updates)
},
+3 -1
View File
@@ -1019,6 +1019,7 @@ interface DataSource {
baseUrl: string
token: string
intervalMinutes: number
pullLimit: number
enabled: boolean
createdAt: number
sessions: ImportSession[]
@@ -1057,10 +1058,11 @@ interface ApiServerApi {
baseUrl: string
token: string
intervalMinutes: number
pullLimit?: number
}) => Promise<DataSource>
updateDataSource: (
id: string,
updates: Partial<Pick<DataSource, 'name' | 'baseUrl' | 'token' | 'intervalMinutes' | 'enabled'>>
updates: Partial<Pick<DataSource, 'name' | 'baseUrl' | 'token' | 'intervalMinutes' | 'pullLimit' | 'enabled'>>
) => Promise<DataSource | null>
deleteDataSource: (id: string) => Promise<boolean>
addImportSessions: (
@@ -26,6 +26,7 @@ const formData = ref({
baseUrl: '',
token: '',
intervalMinutes: 60,
pullLimit: 1000,
})
const remoteSessions = ref<RemoteSession[]>([])
@@ -53,9 +54,10 @@ watch(
baseUrl: props.manageSource.baseUrl,
token: props.manageSource.token,
intervalMinutes: props.manageSource.intervalMinutes,
pullLimit: props.manageSource.pullLimit,
}
} else {
formData.value = { name: '', baseUrl: '', token: '', intervalMinutes: 60 }
formData.value = { name: '', baseUrl: '', token: '', intervalMinutes: 60, pullLimit: 1000 }
}
remoteSessions.value = []
selectedSessionIds.value = new Set()
@@ -205,6 +207,7 @@ async function handleSubmit() {
baseUrl: formData.value.baseUrl,
token: formData.value.token,
intervalMinutes: formData.value.intervalMinutes,
pullLimit: formData.value.pullLimit || undefined,
})
if (ds && selectedSessionIds.value.size > 0) {
const sessions = remoteSessions.value
@@ -273,11 +276,26 @@ function formatMessageCount(count?: number): string {
/>
</div>
<div>
<label class="mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300">
{{ t('settings.api.dataSources.form.interval') }}
</label>
<UInput v-model.number="formData.intervalMinutes" type="number" :min="1" class="w-full" />
<div class="grid grid-cols-2 gap-3">
<div>
<label class="mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300">
{{ t('settings.api.dataSources.form.interval') }}
</label>
<UInput v-model.number="formData.intervalMinutes" type="number" :min="1" class="w-full" />
</div>
<div>
<label class="mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300">
{{ t('settings.api.dataSources.form.pullLimit') }}
</label>
<UInput
v-model.number="formData.pullLimit"
type="number"
:min="100"
:max="10000"
class="w-full"
:placeholder="t('settings.api.dataSources.form.pullLimitPlaceholder')"
/>
</div>
</div>
<div class="flex items-center gap-2">
@@ -10,7 +10,7 @@ const props = defineProps<{
const emit = defineEmits<{
'update:open': [value: boolean]
saved: [updates: { name: string; baseUrl: string; token: string; intervalMinutes: number }]
saved: [updates: { name: string; baseUrl: string; token: string; intervalMinutes: number; pullLimit: number }]
}>()
const { t } = useI18n()
@@ -20,6 +20,7 @@ const form = ref({
baseUrl: '',
token: '',
intervalMinutes: 60,
pullLimit: 1000,
})
watch(
@@ -31,6 +32,7 @@ watch(
baseUrl: props.dataSource.baseUrl,
token: props.dataSource.token,
intervalMinutes: props.dataSource.intervalMinutes,
pullLimit: props.dataSource.pullLimit,
}
}
}
@@ -42,6 +44,7 @@ function save() {
baseUrl: form.value.baseUrl,
token: form.value.token,
intervalMinutes: form.value.intervalMinutes,
pullLimit: form.value.pullLimit,
})
emit('update:open', false)
}
@@ -85,11 +88,26 @@ function save() {
/>
</div>
<div>
<label class="mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300">
{{ t('settings.api.dataSources.form.interval') }}
</label>
<UInput v-model.number="form.intervalMinutes" type="number" :min="1" class="w-full" />
<div class="grid grid-cols-2 gap-3">
<div>
<label class="mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300">
{{ t('settings.api.dataSources.form.interval') }}
</label>
<UInput v-model.number="form.intervalMinutes" type="number" :min="1" class="w-full" />
</div>
<div>
<label class="mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300">
{{ t('settings.api.dataSources.form.pullLimit') }}
</label>
<UInput
v-model.number="form.pullLimit"
type="number"
:min="100"
:max="10000"
class="w-full"
:placeholder="t('settings.api.dataSources.form.pullLimitPlaceholder')"
/>
</div>
</div>
<div class="flex justify-end gap-2 pt-2">
@@ -128,7 +128,13 @@ function openEditSource(ds: DataSource) {
showEditModal.value = true
}
async function handleEditSaved(updates: { name: string; baseUrl: string; token: string; intervalMinutes: number }) {
async function handleEditSaved(updates: {
name: string
baseUrl: string
token: string
intervalMinutes: number
pullLimit: number
}) {
if (!editingDataSource.value) return
await store.updateDataSource(editingDataSource.value.id, updates)
}
+2
View File
@@ -498,6 +498,8 @@
"token": "Access Token (optional)",
"tokenPlaceholder": "Bearer Token for the remote API",
"interval": "Pull Interval (minutes)",
"pullLimit": "Messages per Pull",
"pullLimitPlaceholder": "Default 1000",
"targetSession": "Target Session ID (optional)",
"targetSessionPlaceholder": "Leave empty to create new session each time",
"add": "Add"
+2
View File
@@ -497,6 +497,8 @@
"token": "アクセストークン(任意)",
"tokenPlaceholder": "リモート API の Bearer Token",
"interval": "取得間隔(分)",
"pullLimit": "1回の取得メッセージ数",
"pullLimitPlaceholder": "デフォルト 1000",
"targetSession": "ターゲットセッション ID(任意)",
"targetSessionPlaceholder": "空欄の場合、毎回新規セッションを作成",
"add": "追加"
+2
View File
@@ -498,6 +498,8 @@
"token": "访问令牌(可选)",
"tokenPlaceholder": "远程 API 的 Bearer Token",
"interval": "拉取间隔(分钟)",
"pullLimit": "每次拉取消息数",
"pullLimitPlaceholder": "默认 1000",
"targetSession": "目标会话 ID(可选)",
"targetSessionPlaceholder": "留空则每次新建会话",
"add": "添加"
+2
View File
@@ -497,6 +497,8 @@
"token": "存取權杖(可選)",
"tokenPlaceholder": "遠端 API 的 Bearer Token",
"interval": "拉取間隔(分鐘)",
"pullLimit": "每次拉取訊息數",
"pullLimitPlaceholder": "預設 1000",
"targetSession": "目標會話 ID(可選)",
"targetSessionPlaceholder": "留空則每次新建會話",
"add": "新增"
+9 -2
View File
@@ -36,6 +36,7 @@ export interface DataSource {
baseUrl: string
token: string
intervalMinutes: number
pullLimit: number
enabled: boolean
createdAt: number
sessions: ImportSession[]
@@ -153,7 +154,13 @@ export const useApiServerStore = defineStore('apiServer', () => {
}
}
async function addDataSource(partial: { name?: string; baseUrl: string; token: string; intervalMinutes: number }) {
async function addDataSource(partial: {
name?: string
baseUrl: string
token: string
intervalMinutes: number
pullLimit?: number
}) {
try {
const ds = await window.apiServerApi.addDataSource(partial)
dataSources.value.push(ds)
@@ -166,7 +173,7 @@ export const useApiServerStore = defineStore('apiServer', () => {
async function updateDataSource(
id: string,
updates: Partial<Pick<DataSource, 'name' | 'baseUrl' | 'token' | 'intervalMinutes' | 'enabled'>>
updates: Partial<Pick<DataSource, 'name' | 'baseUrl' | 'token' | 'intervalMinutes' | 'pullLimit' | 'enabled'>>
) {
try {
const ds = await window.apiServerApi.updateDataSource(id, updates)