Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d87d586c0a | |||
| 410789311a |
@@ -43,6 +43,7 @@ class SessionManagementRoute(Route):
|
||||
"/session/group/create": ("POST", self.create_group),
|
||||
"/session/group/update": ("POST", self.update_group),
|
||||
"/session/group/delete": ("POST", self.delete_group),
|
||||
"/session/group/update-config": ("POST", self.update_group_config),
|
||||
}
|
||||
self.conv_mgr = core_lifecycle.conversation_manager
|
||||
self.core_lifecycle = core_lifecycle
|
||||
@@ -145,9 +146,20 @@ class SessionManagementRoute(Route):
|
||||
page=page, page_size=page_size, search=search
|
||||
)
|
||||
|
||||
# 构建规则列表
|
||||
# 收集属于有配置分组的 UMO,避免重复显示
|
||||
grouped_umos = set()
|
||||
groups = self._get_groups()
|
||||
for group_data in groups.values():
|
||||
if group_data.get("config"):
|
||||
grouped_umos.update(group_data.get("umos", []))
|
||||
|
||||
# 构建规则列表(排除已被分组管理的 UMO)
|
||||
rules_list = []
|
||||
filtered_count = 0
|
||||
for umo, rules in umo_rules.items():
|
||||
if umo in grouped_umos:
|
||||
filtered_count += 1
|
||||
continue
|
||||
rule_info = {
|
||||
"umo": umo,
|
||||
"rules": rules,
|
||||
@@ -159,6 +171,7 @@ class SessionManagementRoute(Route):
|
||||
rule_info["message_type"] = parts[1]
|
||||
rule_info["session_id"] = parts[2]
|
||||
rules_list.append(rule_info)
|
||||
total -= filtered_count
|
||||
|
||||
# 获取可用的 providers 和 personas
|
||||
provider_manager = self.core_lifecycle.provider_manager
|
||||
@@ -240,6 +253,7 @@ class SessionManagementRoute(Route):
|
||||
"available_plugins": available_plugins,
|
||||
"available_kbs": available_kbs,
|
||||
"available_rule_keys": AVAILABLE_SESSION_RULE_KEYS,
|
||||
"group_rules": self._get_group_rules(),
|
||||
}
|
||||
)
|
||||
.__dict__
|
||||
@@ -793,6 +807,51 @@ class SessionManagementRoute(Route):
|
||||
"""保存分组"""
|
||||
sp.put("session_groups", groups)
|
||||
|
||||
def _get_group_rules(self) -> list:
|
||||
"""获取有配置的分组列表,用于在规则列表中显示"""
|
||||
groups = self._get_groups()
|
||||
group_rules = []
|
||||
for group_id, group_data in groups.items():
|
||||
config = group_data.get("config", {})
|
||||
if config: # 只返回有配置的分组
|
||||
group_rules.append(
|
||||
{
|
||||
"group_id": group_id,
|
||||
"name": group_data.get("name", ""),
|
||||
"umo_count": len(group_data.get("umos", [])),
|
||||
"config": config,
|
||||
}
|
||||
)
|
||||
return group_rules
|
||||
|
||||
async def _sync_group_config_to_umos(
|
||||
self, config: dict, umos: list[str]
|
||||
) -> tuple[int, list[str]]:
|
||||
"""将分组配置同步到指定的 UMO 列表
|
||||
|
||||
Returns:
|
||||
(success_count, failed_umos)
|
||||
"""
|
||||
success_count = 0
|
||||
failed_umos = []
|
||||
for umo in umos:
|
||||
try:
|
||||
for rule_key, rule_value in config.items():
|
||||
if rule_key not in AVAILABLE_SESSION_RULE_KEYS:
|
||||
continue
|
||||
if rule_value is None:
|
||||
continue
|
||||
if rule_key == "session_plugin_config":
|
||||
# session_plugin_config 需要包裹 umo key
|
||||
await sp.session_put(umo, rule_key, {umo: rule_value})
|
||||
else:
|
||||
await sp.session_put(umo, rule_key, rule_value)
|
||||
success_count += 1
|
||||
except Exception as e:
|
||||
logger.error(f"同步配置到 {umo} 失败: {e!s}")
|
||||
failed_umos.append(umo)
|
||||
return success_count, failed_umos
|
||||
|
||||
async def list_groups(self):
|
||||
"""获取所有分组列表"""
|
||||
try:
|
||||
@@ -806,6 +865,7 @@ class SessionManagementRoute(Route):
|
||||
"name": group_data.get("name", ""),
|
||||
"umos": group_data.get("umos", []),
|
||||
"umo_count": len(group_data.get("umos", [])),
|
||||
"config": group_data.get("config", {}),
|
||||
}
|
||||
)
|
||||
return Response().ok({"groups": groups_list}).__dict__
|
||||
@@ -875,6 +935,7 @@ class SessionManagementRoute(Route):
|
||||
return Response().error(f"分组 '{group_id}' 不存在").__dict__
|
||||
|
||||
group = groups[group_id]
|
||||
old_umos = set(group.get("umos", []))
|
||||
|
||||
# 更新名称
|
||||
if name is not None:
|
||||
@@ -883,6 +944,7 @@ class SessionManagementRoute(Route):
|
||||
# 直接设置 umos 列表
|
||||
if umos is not None:
|
||||
group["umos"] = umos
|
||||
new_umos = set(umos)
|
||||
else:
|
||||
# 增量更新
|
||||
current_umos = set(group.get("umos", []))
|
||||
@@ -891,9 +953,21 @@ class SessionManagementRoute(Route):
|
||||
if remove_umos:
|
||||
current_umos.difference_update(remove_umos)
|
||||
group["umos"] = list(current_umos)
|
||||
new_umos = current_umos
|
||||
|
||||
self._save_groups(groups)
|
||||
|
||||
# 自动同步分组配置给新加入的成员
|
||||
group_config = group.get("config", {})
|
||||
newly_added = new_umos - old_umos
|
||||
if group_config and newly_added:
|
||||
sync_count, _ = await self._sync_group_config_to_umos(
|
||||
group_config, list(newly_added)
|
||||
)
|
||||
logger.info(
|
||||
f"自动同步分组 '{group['name']}' 配置到 {sync_count} 个新成员"
|
||||
)
|
||||
|
||||
return (
|
||||
Response()
|
||||
.ok(
|
||||
@@ -936,3 +1010,81 @@ class SessionManagementRoute(Route):
|
||||
except Exception as e:
|
||||
logger.error(f"删除分组失败: {e!s}")
|
||||
return Response().error(f"删除分组失败: {e!s}").__dict__
|
||||
|
||||
async def update_group_config(self):
|
||||
"""更新分组的配置,并同步到所有成员 UMO
|
||||
|
||||
请求体:
|
||||
{
|
||||
"group_id": "分组ID",
|
||||
"config": {
|
||||
"session_service_config": {...},
|
||||
"session_plugin_config": {...},
|
||||
"kb_config": {...},
|
||||
"provider_perf_chat_completion": ...,
|
||||
"provider_perf_speech_to_text": ...,
|
||||
"provider_perf_text_to_speech": ...
|
||||
}
|
||||
}
|
||||
"""
|
||||
try:
|
||||
data = await request.get_json()
|
||||
group_id = data.get("group_id")
|
||||
config = data.get("config", {})
|
||||
|
||||
if not group_id:
|
||||
return Response().error("缺少必要参数: group_id").__dict__
|
||||
|
||||
groups = self._get_groups()
|
||||
|
||||
if group_id not in groups:
|
||||
return Response().error(f"分组 '{group_id}' 不存在").__dict__
|
||||
|
||||
group = groups[group_id]
|
||||
|
||||
# 保存配置到分组
|
||||
group["config"] = config
|
||||
self._save_groups(groups)
|
||||
|
||||
# 同步到所有成员 UMO
|
||||
umos = group.get("umos", [])
|
||||
|
||||
if not config:
|
||||
# 空配置 → 清除成员上的所有分组下发规则
|
||||
success_count = 0
|
||||
failed_umos = []
|
||||
for umo in umos:
|
||||
try:
|
||||
for rule_key in AVAILABLE_SESSION_RULE_KEYS:
|
||||
try:
|
||||
await sp.session_remove(umo, rule_key)
|
||||
except Exception:
|
||||
pass
|
||||
success_count += 1
|
||||
except Exception as e:
|
||||
logger.error(f"清除 {umo} 规则失败: {e!s}")
|
||||
failed_umos.append(umo)
|
||||
else:
|
||||
success_count, failed_umos = await self._sync_group_config_to_umos(
|
||||
config, umos
|
||||
)
|
||||
|
||||
msg = f"分组 '{group['name']}' 配置已保存并同步到 {success_count}/{len(umos)} 个会话"
|
||||
if failed_umos:
|
||||
msg += f",{len(failed_umos)} 个失败"
|
||||
|
||||
return (
|
||||
Response()
|
||||
.ok(
|
||||
{
|
||||
"message": msg,
|
||||
"success_count": success_count,
|
||||
"failed_count": len(failed_umos),
|
||||
"failed_umos": failed_umos,
|
||||
}
|
||||
)
|
||||
.__dict__
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"更新分组配置失败: {e!s}")
|
||||
return Response().error(f"更新分组配置失败: {e!s}").__dict__
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div class="session-management-page">
|
||||
<v-container fluid class="pa-0">
|
||||
<v-card flat>
|
||||
@@ -35,7 +35,16 @@
|
||||
<!-- UMO 信息 -->
|
||||
<template v-slot:item.umo_info="{ item }">
|
||||
<div>
|
||||
<div class="d-flex align-center">
|
||||
<div class="d-flex align-center" v-if="item.isGroup">
|
||||
<v-chip size="x-small" color="deep-purple" variant="flat" class="mr-2">
|
||||
分组
|
||||
</v-chip>
|
||||
<span class="font-weight-medium">{{ item.groupName }}</span>
|
||||
<v-chip size="x-small" variant="outlined" class="ml-2">
|
||||
{{ item.umo_count }} 个会话
|
||||
</v-chip>
|
||||
</div>
|
||||
<div class="d-flex align-center" v-else>
|
||||
<v-chip size="x-small" :color="getPlatformColor(item.platform)" class="mr-2">
|
||||
{{ item.platform || 'unknown' }}
|
||||
</v-chip>
|
||||
@@ -282,14 +291,24 @@
|
||||
{{ tm('addRule.description') }}
|
||||
</v-alert>
|
||||
|
||||
<v-autocomplete v-model="selectedNewUmo" :items="availableUmos" :loading="loadingUmos"
|
||||
<v-radio-group v-model="addRuleTargetType" inline hide-details class="mb-4">
|
||||
<v-radio label="单个会话" value="session"></v-radio>
|
||||
<v-radio label="分组" value="group" :disabled="groups.length === 0"></v-radio>
|
||||
</v-radio-group>
|
||||
|
||||
<v-autocomplete v-if="addRuleTargetType === 'session'" v-model="selectedNewUmo" :items="availableUmos" :loading="loadingUmos"
|
||||
:label="tm('addRule.selectUmo')" variant="outlined" clearable :no-data-text="tm('addRule.noUmos')" />
|
||||
|
||||
<v-select v-if="addRuleTargetType === 'group'" v-model="selectedGroup" :items="groupSelectOptions"
|
||||
item-title="label" item-value="value" return-object
|
||||
label="选择分组" variant="outlined" clearable
|
||||
:no-data-text="'暂无分组,请先创建分组'" />
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions class="px-4 pb-4">
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn variant="text" @click="addRuleDialog = false">{{ tm('buttons.cancel') }}</v-btn>
|
||||
<v-btn color="primary" variant="tonal" @click="createNewRule" :disabled="!selectedNewUmo">
|
||||
<v-btn color="primary" variant="tonal" @click="createNewRule" :disabled="addRuleTargetType === 'session' ? !selectedNewUmo : !selectedGroup">
|
||||
{{ tm('buttons.next') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
@@ -334,12 +353,7 @@
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<div class="d-flex justify-end mt-4">
|
||||
<v-btn color="primary" variant="tonal" size="small" @click="saveServiceConfig" :loading="saving"
|
||||
prepend-icon="mdi-content-save">
|
||||
{{ tm('buttons.save') }}
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Provider Config Section -->
|
||||
<div class="d-flex align-center mb-4 mt-4">
|
||||
@@ -364,12 +378,7 @@
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<div class="d-flex justify-end mt-4">
|
||||
<v-btn color="primary" variant="tonal" size="small" @click="saveProviderConfig" :loading="saving"
|
||||
prepend-icon="mdi-content-save">
|
||||
{{ tm('buttons.save') }}
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Persona Config Section -->
|
||||
<div class="d-flex align-center mb-4 mt-4">
|
||||
@@ -389,12 +398,7 @@
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<div class="d-flex justify-end mt-4">
|
||||
<v-btn color="primary" variant="tonal" size="small" @click="saveServiceConfig" :loading="saving"
|
||||
prepend-icon="mdi-content-save">
|
||||
{{ tm('buttons.save') }}
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Plugin Config Section -->
|
||||
<div class="d-flex align-center mb-4 mt-4">
|
||||
@@ -414,12 +418,7 @@
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<div class="d-flex justify-end mt-4">
|
||||
<v-btn color="primary" variant="tonal" size="small" @click="savePluginConfig" :loading="saving"
|
||||
prepend-icon="mdi-content-save">
|
||||
{{ tm('buttons.save') }}
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- KB Config Section -->
|
||||
<div class="d-flex align-center mb-4 mt-4">
|
||||
@@ -442,14 +441,17 @@
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<div class="d-flex justify-end mt-4">
|
||||
<v-btn color="primary" variant="tonal" size="small" @click="saveKbConfig" :loading="saving"
|
||||
prepend-icon="mdi-content-save">
|
||||
{{ tm('buttons.save') }}
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions class="px-6 pb-4">
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn variant="text" @click="closeRuleEditor">{{ tm('buttons.cancel') }}</v-btn>
|
||||
<v-btn color="primary" variant="tonal" @click="saveAllConfigs" :loading="saving"
|
||||
prepend-icon="mdi-content-save">
|
||||
{{ tm('buttons.save') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
@@ -567,6 +569,8 @@ export default {
|
||||
addRuleDialog: false,
|
||||
availableUmos: [],
|
||||
selectedNewUmo: null,
|
||||
addRuleTargetType: 'session',
|
||||
selectedGroup: null,
|
||||
|
||||
// 规则编辑
|
||||
ruleDialog: false,
|
||||
@@ -729,6 +733,13 @@ export default {
|
||||
return options
|
||||
},
|
||||
|
||||
groupSelectOptions() {
|
||||
return this.groups.map(g => ({
|
||||
label: `${g.name} (${g.umo_count} 个会话)`,
|
||||
value: g,
|
||||
}))
|
||||
},
|
||||
|
||||
groupOptions() {
|
||||
return this.groups.map(g => ({
|
||||
label: `${g.name} (${g.umo_count} 个会话)`,
|
||||
@@ -811,7 +822,7 @@ export default {
|
||||
})
|
||||
if (response.data.status === 'ok') {
|
||||
const data = response.data.data
|
||||
this.rulesList = data.rules
|
||||
this.rulesList = data.rules || []
|
||||
this.totalItems = data.total
|
||||
this.availablePersonas = data.available_personas
|
||||
this.availableChatProviders = data.available_chat_providers
|
||||
@@ -819,6 +830,20 @@ export default {
|
||||
this.availableTtsProviders = data.available_tts_providers
|
||||
this.availablePlugins = data.available_plugins || []
|
||||
this.availableKbs = data.available_kbs || []
|
||||
|
||||
// 合并分组规则到列表中
|
||||
const groupRules = data.group_rules || []
|
||||
for (const gr of groupRules) {
|
||||
this.rulesList.unshift({
|
||||
umo: `[\u5206\u7ec4] ${gr.name}`,
|
||||
isGroup: true,
|
||||
groupId: gr.group_id,
|
||||
groupName: gr.name,
|
||||
umo_count: gr.umo_count,
|
||||
rules: gr.config || {},
|
||||
})
|
||||
}
|
||||
this.totalItems += groupRules.length
|
||||
} else {
|
||||
this.showError(response.data.message || this.tm('messages.loadError'))
|
||||
}
|
||||
@@ -872,10 +897,89 @@ export default {
|
||||
async openAddRuleDialog() {
|
||||
this.addRuleDialog = true
|
||||
this.selectedNewUmo = null
|
||||
this.addRuleTargetType = 'session'
|
||||
this.selectedGroup = null
|
||||
await this.loadUmos()
|
||||
},
|
||||
|
||||
async saveAllConfigs() {
|
||||
if (!this.selectedUmo) return
|
||||
|
||||
// 分组模式:调用分组配置 API
|
||||
if (this.selectedUmo.isGroup) {
|
||||
this.saving = true
|
||||
try {
|
||||
const config = {
|
||||
session_service_config: { ...this.serviceConfig },
|
||||
provider_perf_chat_completion: this.providerConfig.chat_completion || null,
|
||||
provider_perf_speech_to_text: this.providerConfig.speech_to_text || null,
|
||||
provider_perf_text_to_speech: this.providerConfig.text_to_speech || null,
|
||||
session_plugin_config: { ...this.pluginConfig },
|
||||
kb_config: { ...this.kbConfig },
|
||||
}
|
||||
// 清理空值
|
||||
if (!config.session_service_config.custom_name) delete config.session_service_config.custom_name
|
||||
if (config.session_service_config.persona_id === null) delete config.session_service_config.persona_id
|
||||
|
||||
const response = await axios.post('/api/session/group/update-config', {
|
||||
group_id: this.selectedUmo.groupId,
|
||||
config: config
|
||||
})
|
||||
if (response.data.status === 'ok') {
|
||||
this.showSuccess(response.data.data?.message || '分组配置已保存并同步')
|
||||
await this.loadData()
|
||||
} else {
|
||||
this.showError(response.data.message || this.tm('messages.saveError'))
|
||||
}
|
||||
} catch (error) {
|
||||
this.showError(error.response?.data?.message || this.tm('messages.saveError'))
|
||||
} finally {
|
||||
this.saving = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 单个会话模式
|
||||
this.saving = true
|
||||
this._batchSaving = true
|
||||
try {
|
||||
await this.saveServiceConfig()
|
||||
await this.saveProviderConfig()
|
||||
await this.savePluginConfig()
|
||||
await this.saveKbConfig()
|
||||
this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
} catch (error) {
|
||||
this.showError(error.response?.data?.message || this.tm('messages.saveError'))
|
||||
} finally {
|
||||
this._batchSaving = false
|
||||
this.saving = false
|
||||
}
|
||||
},
|
||||
|
||||
createNewRule() {
|
||||
if (this.addRuleTargetType === 'group') {
|
||||
// 分组模式
|
||||
if (!this.selectedGroup) return
|
||||
const group = this.selectedGroup.value || this.selectedGroup
|
||||
if (!group.umos || group.umos.length === 0) {
|
||||
this.showError('该分组没有成员会话')
|
||||
return
|
||||
}
|
||||
// 创建一个特殊的规则项,标记为分组
|
||||
const newItem = {
|
||||
umo: `[分组] ${group.name}`,
|
||||
isGroup: true,
|
||||
groupId: group.id,
|
||||
groupName: group.name,
|
||||
groupUmos: group.umos,
|
||||
rules: {},
|
||||
}
|
||||
this.addRuleDialog = false
|
||||
this.openRuleEditor(newItem)
|
||||
return
|
||||
}
|
||||
|
||||
// 单个会话模式(原逻辑)
|
||||
if (!this.selectedNewUmo) return
|
||||
|
||||
// 创建一个新的规则项并打开编辑器
|
||||
@@ -943,13 +1047,37 @@ export default {
|
||||
async saveServiceConfig() {
|
||||
if (!this.selectedUmo) return
|
||||
|
||||
this.saving = true
|
||||
if (!this._batchSaving) this.saving = true
|
||||
try {
|
||||
const config = { ...this.serviceConfig }
|
||||
// 清理空值
|
||||
if (!config.custom_name) delete config.custom_name
|
||||
if (config.persona_id === null) delete config.persona_id
|
||||
|
||||
// 分组模式:批量下发给所有成员
|
||||
if (this.selectedUmo.isGroup) {
|
||||
const umos = this.selectedUmo.groupUmos
|
||||
let successCount = 0
|
||||
for (const umo of umos) {
|
||||
try {
|
||||
await axios.post('/api/session/update-rule', {
|
||||
umo: umo,
|
||||
rule_key: 'session_service_config',
|
||||
rule_value: config
|
||||
})
|
||||
successCount++
|
||||
} catch (e) {
|
||||
console.error(`更新 ${umo} 失败:`, e)
|
||||
}
|
||||
}
|
||||
if (!this._batchSaving) {
|
||||
this.showSuccess(`已更新 ${successCount}/${umos.length} 个会话的服务配置`)
|
||||
await this.loadData()
|
||||
this.saving = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const response = await axios.post('/api/session/update-rule', {
|
||||
umo: this.selectedUmo.umo,
|
||||
rule_key: 'session_service_config',
|
||||
@@ -957,7 +1085,7 @@ export default {
|
||||
})
|
||||
|
||||
if (response.data.status === 'ok') {
|
||||
this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
if (!this._batchSaving) this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
this.editingRules.session_service_config = config
|
||||
|
||||
// 更新或添加到列表
|
||||
@@ -980,17 +1108,45 @@ export default {
|
||||
} catch (error) {
|
||||
this.showError(error.response?.data?.message || this.tm('messages.saveError'))
|
||||
}
|
||||
this.saving = false
|
||||
if (!this._batchSaving) this.saving = false
|
||||
},
|
||||
|
||||
async saveProviderConfig() {
|
||||
if (!this.selectedUmo) return
|
||||
|
||||
this.saving = true
|
||||
if (!this._batchSaving) this.saving = true
|
||||
try {
|
||||
const providerTypes = ['chat_completion', 'speech_to_text', 'text_to_speech']
|
||||
|
||||
// 分组模式:批量下发给所有成员
|
||||
if (this.selectedUmo.isGroup) {
|
||||
const umos = this.selectedUmo.groupUmos
|
||||
let successCount = 0
|
||||
for (const umo of umos) {
|
||||
try {
|
||||
const tasks = []
|
||||
for (const type of providerTypes) {
|
||||
const value = this.providerConfig[type]
|
||||
if (value) {
|
||||
tasks.push(axios.post('/api/session/update-rule', { umo, rule_key: `provider_perf_${type}`, rule_value: value }))
|
||||
}
|
||||
}
|
||||
if (tasks.length > 0) await Promise.all(tasks)
|
||||
successCount++
|
||||
} catch (e) {
|
||||
console.error(`更新 ${umo} Provider 失败:`, e)
|
||||
}
|
||||
}
|
||||
if (!this._batchSaving) {
|
||||
this.showSuccess(`已更新 ${successCount}/${umos.length} 个会话的 Provider 配置`)
|
||||
await this.loadData()
|
||||
this.saving = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const updateTasks = []
|
||||
const deleteTasks = []
|
||||
const providerTypes = ['chat_completion', 'speech_to_text', 'text_to_speech']
|
||||
|
||||
for (const type of providerTypes) {
|
||||
const value = this.providerConfig[type]
|
||||
@@ -1017,7 +1173,7 @@ export default {
|
||||
const allTasks = [...updateTasks, ...deleteTasks]
|
||||
if (allTasks.length > 0) {
|
||||
await Promise.all(allTasks)
|
||||
this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
if (!this._batchSaving) this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
|
||||
// 更新或添加到列表
|
||||
let item = this.rulesList.find(u => u.umo === this.selectedUmo.umo)
|
||||
@@ -1042,24 +1198,48 @@ export default {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.showSuccess(this.tm('messages.noChanges'))
|
||||
if (!this._batchSaving) this.showSuccess(this.tm('messages.noChanges'))
|
||||
}
|
||||
} catch (error) {
|
||||
this.showError(error.response?.data?.message || this.tm('messages.saveError'))
|
||||
}
|
||||
this.saving = false
|
||||
if (!this._batchSaving) this.saving = false
|
||||
},
|
||||
|
||||
async savePluginConfig() {
|
||||
if (!this.selectedUmo) return
|
||||
|
||||
this.saving = true
|
||||
if (!this._batchSaving) this.saving = true
|
||||
try {
|
||||
const config = {
|
||||
enabled_plugins: this.pluginConfig.enabled_plugins,
|
||||
disabled_plugins: this.pluginConfig.disabled_plugins,
|
||||
}
|
||||
|
||||
// 分组模式:批量下发给所有成员
|
||||
if (this.selectedUmo.isGroup) {
|
||||
const umos = this.selectedUmo.groupUmos
|
||||
let successCount = 0
|
||||
for (const umo of umos) {
|
||||
try {
|
||||
if (config.enabled_plugins.length === 0 && config.disabled_plugins.length === 0) {
|
||||
await axios.post('/api/session/delete-rule', { umo, rule_key: 'session_plugin_config' })
|
||||
} else {
|
||||
await axios.post('/api/session/update-rule', { umo, rule_key: 'session_plugin_config', rule_value: config })
|
||||
}
|
||||
successCount++
|
||||
} catch (e) {
|
||||
console.error(`更新 ${umo} 插件配置失败:`, e)
|
||||
}
|
||||
}
|
||||
if (!this._batchSaving) {
|
||||
this.showSuccess(`已更新 ${successCount}/${umos.length} 个会话的插件配置`)
|
||||
await this.loadData()
|
||||
this.saving = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 如果两个列表都为空,删除配置
|
||||
if (config.enabled_plugins.length === 0 && config.disabled_plugins.length === 0) {
|
||||
if (this.editingRules.session_plugin_config) {
|
||||
@@ -1071,7 +1251,7 @@ export default {
|
||||
let item = this.rulesList.find(u => u.umo === this.selectedUmo.umo)
|
||||
if (item) delete item.rules.session_plugin_config
|
||||
}
|
||||
this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
if (!this._batchSaving) this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
} else {
|
||||
const response = await axios.post('/api/session/update-rule', {
|
||||
umo: this.selectedUmo.umo,
|
||||
@@ -1080,7 +1260,7 @@ export default {
|
||||
})
|
||||
|
||||
if (response.data.status === 'ok') {
|
||||
this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
if (!this._batchSaving) this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
this.editingRules.session_plugin_config = config
|
||||
|
||||
let item = this.rulesList.find(u => u.umo === this.selectedUmo.umo)
|
||||
@@ -1102,13 +1282,13 @@ export default {
|
||||
} catch (error) {
|
||||
this.showError(error.response?.data?.message || this.tm('messages.saveError'))
|
||||
}
|
||||
this.saving = false
|
||||
if (!this._batchSaving) this.saving = false
|
||||
},
|
||||
|
||||
async saveKbConfig() {
|
||||
if (!this.selectedUmo) return
|
||||
|
||||
this.saving = true
|
||||
if (!this._batchSaving) this.saving = true
|
||||
try {
|
||||
const config = {
|
||||
kb_ids: this.kbConfig.kb_ids,
|
||||
@@ -1116,6 +1296,30 @@ export default {
|
||||
enable_rerank: this.kbConfig.enable_rerank,
|
||||
}
|
||||
|
||||
// 分组模式:批量下发给所有成员
|
||||
if (this.selectedUmo.isGroup) {
|
||||
const umos = this.selectedUmo.groupUmos
|
||||
let successCount = 0
|
||||
for (const umo of umos) {
|
||||
try {
|
||||
if (config.kb_ids.length === 0) {
|
||||
await axios.post('/api/session/delete-rule', { umo, rule_key: 'kb_config' })
|
||||
} else {
|
||||
await axios.post('/api/session/update-rule', { umo, rule_key: 'kb_config', rule_value: config })
|
||||
}
|
||||
successCount++
|
||||
} catch (e) {
|
||||
console.error(`更新 ${umo} 知识库配置失败:`, e)
|
||||
}
|
||||
}
|
||||
if (!this._batchSaving) {
|
||||
this.showSuccess(`已更新 ${successCount}/${umos.length} 个会话的知识库配置`)
|
||||
await this.loadData()
|
||||
this.saving = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 如果 kb_ids 为空,删除配置
|
||||
if (config.kb_ids.length === 0) {
|
||||
if (this.editingRules.kb_config) {
|
||||
@@ -1127,7 +1331,7 @@ export default {
|
||||
let item = this.rulesList.find(u => u.umo === this.selectedUmo.umo)
|
||||
if (item) delete item.rules.kb_config
|
||||
}
|
||||
this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
if (!this._batchSaving) this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
} else {
|
||||
const response = await axios.post('/api/session/update-rule', {
|
||||
umo: this.selectedUmo.umo,
|
||||
@@ -1136,7 +1340,7 @@ export default {
|
||||
})
|
||||
|
||||
if (response.data.status === 'ok') {
|
||||
this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
if (!this._batchSaving) this.showSuccess(this.tm('messages.saveSuccess'))
|
||||
this.editingRules.kb_config = config
|
||||
|
||||
let item = this.rulesList.find(u => u.umo === this.selectedUmo.umo)
|
||||
@@ -1158,7 +1362,7 @@ export default {
|
||||
} catch (error) {
|
||||
this.showError(error.response?.data?.message || this.tm('messages.saveError'))
|
||||
}
|
||||
this.saving = false
|
||||
if (!this._batchSaving) this.saving = false
|
||||
},
|
||||
|
||||
confirmDeleteRules(item) {
|
||||
@@ -1171,6 +1375,24 @@ export default {
|
||||
|
||||
this.deleting = true
|
||||
try {
|
||||
// 分组规则:清空分组配置
|
||||
if (this.deleteTarget.isGroup) {
|
||||
const response = await axios.post('/api/session/group/update-config', {
|
||||
group_id: this.deleteTarget.groupId,
|
||||
config: {}
|
||||
})
|
||||
if (response.data.status === 'ok') {
|
||||
this.showSuccess('分组配置已清除')
|
||||
this.deleteDialog = false
|
||||
this.deleteTarget = null
|
||||
await this.loadData()
|
||||
} else {
|
||||
this.showError(response.data.message || this.tm('messages.deleteError'))
|
||||
}
|
||||
this.deleting = false
|
||||
return
|
||||
}
|
||||
|
||||
const response = await axios.post('/api/session/delete-rule', {
|
||||
umo: this.deleteTarget.umo
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user