- 统一设置系统:create_scheduler_service 读取 DB 设置覆盖默认值 - 修复 ProxyRepository.update_score 误删所有无效代理的 SQL - ValidationQueue:修复 Worker 计数漂移与启动恢复任务饿死 - SchedulerService:移除 drain() 阻塞,主循环可正常响应 stop - TaskService:在调度器周期内自动清理过期任务,防止内存泄漏 - lifespan/conftest:规范关闭顺序,消除 Event loop closed 警告 - Repository:异常日志增加 exc_info,今日新增按 created_at 统计 - ValidatorService:防止 HTTP session 重复关闭,移除 SOCKS 多余 close - 前端:补全 pluginsStore.isEmpty,ProxyList 最低分数上限改为 100 - 删除 config.py 中冗余的 cors_origins_list property
110 lines
2.5 KiB
JavaScript
110 lines
2.5 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { ref, computed } from 'vue'
|
|
import { pluginService } from '../services/pluginService'
|
|
|
|
/**
|
|
* Plugins Store
|
|
* 管理插件列表和状态
|
|
*/
|
|
export const usePluginsStore = defineStore('plugins', () => {
|
|
// ==================== State ====================
|
|
const plugins = ref([])
|
|
const loading = ref(false)
|
|
|
|
// ==================== Getters ====================
|
|
const enabledCount = computed(() => plugins.value.filter(p => p.enabled).length)
|
|
const totalCount = computed(() => plugins.value.length)
|
|
const isEmpty = computed(() => !loading.value && plugins.value.length === 0)
|
|
|
|
// ==================== Actions ====================
|
|
|
|
/**
|
|
* 获取插件列表
|
|
* @returns {Promise<boolean>}
|
|
*/
|
|
async function fetchPlugins() {
|
|
loading.value = true
|
|
try {
|
|
const response = await pluginService.getPlugins()
|
|
if (response.code === 200) {
|
|
plugins.value = response.data.plugins || []
|
|
return true
|
|
}
|
|
} catch (error) {
|
|
console.error('获取插件列表失败:', error)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* 切换插件启用状态
|
|
* @param {string|number} pluginId
|
|
* @param {boolean} enabled
|
|
* @returns {Promise<boolean>}
|
|
*/
|
|
async function togglePlugin(pluginId, enabled) {
|
|
try {
|
|
const response = await pluginService.togglePlugin(pluginId, enabled)
|
|
if (response.code === 200) {
|
|
const plugin = plugins.value.find(p => p.id === pluginId)
|
|
if (plugin) {
|
|
plugin.enabled = enabled
|
|
}
|
|
return true
|
|
}
|
|
} catch (error) {
|
|
console.error('切换插件状态失败:', error)
|
|
}
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* 触发插件爬取
|
|
* @param {string|number} pluginId
|
|
* @returns {Promise<boolean>}
|
|
*/
|
|
async function crawlPlugin(pluginId) {
|
|
try {
|
|
const response = await pluginService.crawlPlugin(pluginId)
|
|
return response.code === 200
|
|
} catch (error) {
|
|
console.error('触发插件爬取失败:', error)
|
|
return false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 根据 ID 获取插件
|
|
* @param {string|number} id
|
|
* @returns {object|undefined}
|
|
*/
|
|
function getPluginById(id) {
|
|
return plugins.value.find(p => p.id === id)
|
|
}
|
|
|
|
/**
|
|
* 重置状态
|
|
*/
|
|
function reset() {
|
|
plugins.value = []
|
|
}
|
|
|
|
return {
|
|
// State
|
|
plugins,
|
|
loading,
|
|
// Getters
|
|
enabledCount,
|
|
totalCount,
|
|
isEmpty,
|
|
// Actions
|
|
fetchPlugins,
|
|
togglePlugin,
|
|
crawlPlugin,
|
|
getPluginById,
|
|
reset
|
|
}
|
|
})
|