feat: add plugins local cache and remote file MD5 validation (#2211)

* 修改openai的嵌入模型默认维度为1024

* 为插件市场添加本地缓存
- 优先使用api获取,获取失败时则使用本地缓存
- 每次获取后会更新本地缓存
- 如果获取结果为空,判定为获取失败,使用本地缓存
- 前端页面添加刷新按钮,用于手动刷新本地缓存

* feat: 增强插件市场缓存机制,支持MD5校验以确保数据有效性

---------

Co-authored-by: Soulter <905617992@qq.com>
This commit is contained in:
Misaka Mikoto
2025-08-02 14:03:53 +08:00
committed by GitHub
parent 23129a9ba2
commit 7a8d65d37d
5 changed files with 177 additions and 10 deletions
@@ -32,7 +32,8 @@
"cancel": "Cancel",
"actions": "Actions",
"back": "Back",
"selectFile": "Select File"
"selectFile": "Select File",
"refresh": "Refresh"
},
"status": {
"enabled": "Enabled",
@@ -32,7 +32,8 @@
"cancel": "取消",
"actions": "操作",
"back": "返回",
"selectFile": "选择文件"
"selectFile": "选择文件",
"refresh": "刷新"
},
"status": {
"enabled": "启用",
+5 -1
View File
@@ -159,7 +159,11 @@ export const useCommonStore = defineStore({
if (!force && this.pluginMarketData.length > 0) {
return Promise.resolve(this.pluginMarketData);
}
return axios.get('/api/plugin/market_list')
// 如果是强制刷新,添加 force_refresh 参数
const url = force ? '/api/plugin/market_list?force_refresh=true' : '/api/plugin/market_list';
return axios.get(url)
.then((res) => {
let data = []
for (let key in res.data.data) {
+34 -2
View File
@@ -71,6 +71,7 @@ const uploadTab = ref('file');
const showPluginFullName = ref(false);
const marketSearch = ref("");
const filterKeys = ['name', 'desc', 'author'];
const refreshingMarket = ref(false);
const plugin_handler_info_headers = computed(() => [
{ title: tm('table.headers.eventType'), key: 'event_type_h' },
@@ -560,6 +561,25 @@ const newExtension = async () => {
}
};
// 刷新插件市场数据
const refreshPluginMarket = async () => {
refreshingMarket.value = true;
try {
// 强制刷新插件市场数据
const data = await commonStore.getPluginCollections(true);
pluginMarketData.value = data;
trimExtensionName();
checkAlreadyInstalled();
checkUpdate();
toast(tm('messages.refreshSuccess'), "success");
} catch (err) {
toast(tm('messages.refreshFailed') + " " + err, "error");
} finally {
refreshingMarket.value = false;
}
};
// 生命周期
onMounted(async () => {
await getExtensions();
@@ -851,8 +871,20 @@ onMounted(async () => {
<div class="mt-4">
<div class="d-flex align-center mb-2" style="justify-content: space-between;">
<h2>{{ tm('market.allPlugins') }}</h2>
<v-switch v-model="showPluginFullName" :label="tm('market.showFullName')" hide-details density="compact"
style="margin-left: 12px" />
<div class="d-flex align-center">
<v-btn
variant="tonal"
size="small"
@click="refreshPluginMarket"
:loading="refreshingMarket"
class="mr-2"
>
<v-icon>mdi-refresh</v-icon>
{{ tm('buttons.refresh') }}
</v-btn>
<v-switch v-model="showPluginFullName" :label="tm('market.showFullName')" hide-details density="compact"
style="margin-left: 12px" />
</div>
</div>
<v-col cols="12" md="12" style="padding: 0px;">