diff --git a/app/schedule/syncGitAgents.js b/app/schedule/syncGitAgents.js index 1527900..2e068d8 100644 --- a/app/schedule/syncGitAgents.js +++ b/app/schedule/syncGitAgents.js @@ -1,12 +1,9 @@ -module.exports = (app) => { - const autoSyncInterval = app.config.agentMarket?.autoSyncInterval; - +module.exports = () => { return { schedule: { - interval: autoSyncInterval || '1h', + cron: '0 0 * * * *', // 每小时整点执行 type: 'worker', // 仅由单个 worker 执行,避免多 worker 并发冲突 immediate: false, // 应用启动后等待到达周期再执行 - disable: !autoSyncInterval || autoSyncInterval === '0', }, // 定时轮询同步所有已配置 GitLab 仓库的 Agent 插件 async task(ctx) { diff --git a/app/service/skills.js b/app/service/skills.js index a791670..8e1c253 100644 --- a/app/service/skills.js +++ b/app/service/skills.js @@ -221,9 +221,19 @@ class SkillsService extends Service { await SkillsItem.increment('downloads', { by: 1, where: { slug: value, is_delete: 0 }, - // Do not bump updated_at — downloads must not reorder "recent" sort. + // 不触发 updated_at 变更,下载量增加不应影响最近更新时间与排序 silent: true, + attributes: { + updated_at: this.app.Sequelize.col('updated_at'), + }, }); + if (this.skillCache) { + const target = + this.skillCache.bySlug?.[value] || this.skillCache.byInstallKey?.[value]; + if (target) { + target.downloads = (target.downloads || 0) + 1; + } + } } catch (error) { this.ctx.logger.warn( `[skills] increment downloads failed for ${value}: ${error.message}` diff --git a/app/web/pages/agents/detail/AgentDetailContent.tsx b/app/web/pages/agents/detail/AgentDetailContent.tsx index ae1d490..1237204 100644 --- a/app/web/pages/agents/detail/AgentDetailContent.tsx +++ b/app/web/pages/agents/detail/AgentDetailContent.tsx @@ -572,7 +572,7 @@ const AgentDetailContent: React.FC = ({ name, history }
最近刷新时间 - + @@ -581,7 +581,7 @@ const AgentDetailContent: React.FC = ({ name, history }
最近同步代码时间 - + diff --git a/app/web/pages/skills/detail/SkillDetailContent.tsx b/app/web/pages/skills/detail/SkillDetailContent.tsx index ad78eda..eb74233 100644 --- a/app/web/pages/skills/detail/SkillDetailContent.tsx +++ b/app/web/pages/skills/detail/SkillDetailContent.tsx @@ -129,6 +129,11 @@ const SkillDetailContent: React.FC = ({ } }; + // 点击下载仅递增下载量,不更新最近更新时间 + const handleDownload = () => { + setDetail((prev) => (prev ? { ...prev, downloads: (prev.downloads || 0) + 1 } : prev)); + }; + useEffect(() => { setUiSelectedFilePath(''); setSelectedFilePath(''); @@ -312,6 +317,7 @@ const SkillDetailContent: React.FC = ({ agentTerminalCommand={agentTerminalCommand} manualDownloadUrl={manualDownloadUrl} contributor={detail?.contributor || ''} + onDownload={handleDownload} /> ) : null}
diff --git a/app/web/pages/skills/detail/components/SkillInstallPanel.tsx b/app/web/pages/skills/detail/components/SkillInstallPanel.tsx index 3c39fc6..c30d9be 100644 --- a/app/web/pages/skills/detail/components/SkillInstallPanel.tsx +++ b/app/web/pages/skills/detail/components/SkillInstallPanel.tsx @@ -38,6 +38,7 @@ interface SkillInstallPanelProps { agentTerminalCommand: string; manualDownloadUrl: string; contributor?: string; + onDownload?: () => void; } const renderTerminalCommand = (command: string, copyMessage: string) => ( @@ -77,6 +78,7 @@ export const SkillInstallPanel: React.FC = ({ agentTerminalCommand, manualDownloadUrl, contributor = '', + onDownload, }) => (