添加会话模型和API Key配置功能
- 在模型模块中新增会话开关状态字段,支持会话模型的管理。 - 更新模型选择器,增加系统模型的API Key配置弹窗,提升用户体验。 - 优化错误处理逻辑,确保接口错误由全局拦截器处理,减少冗余提示。 - 更新相关样式以增强界面可读性和美观性。
This commit is contained in:
@@ -138,7 +138,7 @@ const openDialog = async (row?: DialogFormData) => {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取账号详情失败:', error);
|
||||
ElMessage.error('获取账号详情失败');
|
||||
// 错误已由全局拦截器处理
|
||||
} finally {
|
||||
state.loading = false;
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ const loadDatasets = async () => {
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('加载数据集列表失败');
|
||||
// 错误已由全局拦截器处理
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -790,10 +790,11 @@ const buildTreeNodes = (tree: ExecutionTreeItem[]): TreeNode[] =>
|
||||
const getList = async () => {
|
||||
treeLoading.value = true;
|
||||
try {
|
||||
const res = await getExecutionList({ errorMode: 'page' });
|
||||
const res = await getExecutionList();
|
||||
imgAddressPrefix.value = res.data?.imgAddressPrefix || '';
|
||||
treeNodes.value = buildTreeNodes(res.data?.tree || []);
|
||||
} catch {
|
||||
// 错误已由全局拦截器处理
|
||||
treeNodes.value = [];
|
||||
imgAddressPrefix.value = '';
|
||||
} finally {
|
||||
@@ -802,9 +803,10 @@ const getList = async () => {
|
||||
};
|
||||
const getNodeLibrary = async () => {
|
||||
try {
|
||||
const res = await getNodeLibraryList({ errorMode: 'page' });
|
||||
const res = await getNodeLibraryList();
|
||||
nodeLibraryGroups.value = res.data?.groups || [];
|
||||
} catch {
|
||||
// 错误已由全局拦截器处理
|
||||
nodeLibraryGroups.value = [];
|
||||
}
|
||||
};
|
||||
@@ -812,7 +814,7 @@ const getNodeLibrary = async () => {
|
||||
const fetchWorkflowList = async () => {
|
||||
workflowListLoading.value = true;
|
||||
try {
|
||||
const res = await getWorkflowList({ errorMode: 'page' });
|
||||
const res = await getWorkflowList();
|
||||
|
||||
// 分别处理用户工作流和模板工作流
|
||||
const userWorkflows = res.data?.listFlowUserRes?.list || [];
|
||||
@@ -833,6 +835,7 @@ const fetchWorkflowList = async () => {
|
||||
const templateEnd = templateStart + templateWorkflowPagination.pageSize;
|
||||
templateWorkflowList.value = templateWorkflows.slice(templateStart, templateEnd);
|
||||
} catch {
|
||||
// 错误已由全局拦截器处理
|
||||
userWorkflowList.value = [];
|
||||
templateWorkflowList.value = [];
|
||||
userWorkflowPagination.total = 0;
|
||||
@@ -892,7 +895,7 @@ const handleRemoveModel = () => {
|
||||
const useWorkflow = async (workflow: WorkflowItem) => {
|
||||
try {
|
||||
// 调用详情接口获取最新的工作流数据
|
||||
const res = await getWorkflowDetail(workflow.id, { errorMode: 'page' });
|
||||
const res = await getWorkflowDetail(workflow.id);
|
||||
if (res.data) {
|
||||
// 切换到创作模式
|
||||
isCreationMode.value = true;
|
||||
@@ -946,7 +949,7 @@ const useWorkflow = async (workflow: WorkflowItem) => {
|
||||
const editWorkflow = async (workflow: WorkflowItem) => {
|
||||
try {
|
||||
// 调用详情接口获取最新的工作流数据
|
||||
const res = await getWorkflowDetail(workflow.id, { errorMode: 'page' });
|
||||
const res = await getWorkflowDetail(workflow.id);
|
||||
if (res.data?.flowContent) {
|
||||
// 切换回画布编辑模式
|
||||
isCreationMode.value = false;
|
||||
@@ -994,7 +997,7 @@ const deleteWorkflowAction = async (workflow: WorkflowItem) => {
|
||||
type: 'warning',
|
||||
});
|
||||
|
||||
await deleteWorkflow(workflow.id, { errorMode: 'page' });
|
||||
await deleteWorkflow(workflow.id);
|
||||
ElMessage.success('工作流删除成功');
|
||||
|
||||
// 如果删除的是当前正在编辑的工作流,清空编辑状态
|
||||
@@ -1038,15 +1041,10 @@ const sendMessage = async () => {
|
||||
const fileUrls: string[] = [];
|
||||
if (selectedFiles.value.length > 0) {
|
||||
for (const file of selectedFiles.value) {
|
||||
try {
|
||||
const uploadRes = await uploadFile(file, { errorMode: 'page' });
|
||||
// 拼接完整的文件地址
|
||||
const fullUrl = uploadRes.data.fileAddressPrefix ? `${uploadRes.data.fileAddressPrefix}${uploadRes.data.fileURL}` : uploadRes.data.fileURL;
|
||||
fileUrls.push(fullUrl);
|
||||
} catch (error) {
|
||||
ElMessage.error(`文件 ${file.name} 上传失败`);
|
||||
throw error;
|
||||
}
|
||||
const uploadRes = await uploadFile(file);
|
||||
// 拼接完整的文件地址
|
||||
const fullUrl = uploadRes.data.fileAddressPrefix ? `${uploadRes.data.fileAddressPrefix}${uploadRes.data.fileURL}` : uploadRes.data.fileURL;
|
||||
fileUrls.push(fullUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1109,7 +1107,7 @@ const sendMessage = async () => {
|
||||
};
|
||||
|
||||
// 5. 调用执行接口(不再使用 FormData,直接传 JSON)
|
||||
await executeFlow(params, { errorMode: 'page' });
|
||||
await executeFlow(params);
|
||||
|
||||
ElMessage.success('创作完成!');
|
||||
|
||||
@@ -1117,8 +1115,8 @@ const sendMessage = async () => {
|
||||
userInput.value = '';
|
||||
selectedFiles.value = [];
|
||||
selectedCreationSkill.value = null;
|
||||
} catch (error) {
|
||||
ElMessage.error('创作失败,请重试');
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
} finally {
|
||||
isCreating.value = false;
|
||||
}
|
||||
@@ -1149,7 +1147,7 @@ const downloadNode = async (d: TreeNode) => {
|
||||
if (!d.fileUrl) return ElMessage.warning('当前节点没有可下载地址');
|
||||
try {
|
||||
// 下载失败时希望展示更贴近页面语义的提示,因此改为 page 模式。
|
||||
const r = await downloadToFile({ fileURL: d.fileUrl }, { errorMode: 'page' });
|
||||
const r = await downloadToFile({ fileURL: d.fileUrl });
|
||||
const blob = r instanceof Blob ? r : r?.data;
|
||||
if (!(blob instanceof Blob)) throw new Error('invalid blob');
|
||||
const name = decodeURIComponent(d.fileUrl.split('/').pop() || `${d.label}.${d.nodeType === 'html' ? 'html' : 'png'}`);
|
||||
@@ -1163,7 +1161,7 @@ const downloadNode = async (d: TreeNode) => {
|
||||
URL.revokeObjectURL(u);
|
||||
ElMessage.success('下载成功');
|
||||
} catch {
|
||||
// 下载接口使用 errorMode: 'page',后端错误会自动显示
|
||||
// 下载失败由 request 全局提示后端 message
|
||||
}
|
||||
};
|
||||
const syncDsl = () => {
|
||||
@@ -1847,26 +1845,20 @@ const confirmSaveWorkflow = async () => {
|
||||
// 判断是新建还是更新
|
||||
if (currentEditingWorkflowId.value) {
|
||||
// 更新现有工作流
|
||||
await updateWorkflow(
|
||||
{
|
||||
id: currentEditingWorkflowId.value,
|
||||
flowName: saveForm.flowName,
|
||||
description: saveForm.description,
|
||||
flowContent: workflowDsl.value,
|
||||
},
|
||||
{ errorMode: 'page' }
|
||||
);
|
||||
await updateWorkflow({
|
||||
id: currentEditingWorkflowId.value,
|
||||
flowName: saveForm.flowName,
|
||||
description: saveForm.description,
|
||||
flowContent: workflowDsl.value,
|
||||
});
|
||||
ElMessage.success('工作流更新成功');
|
||||
} else {
|
||||
// 创建新工作流
|
||||
await saveWorkflow(
|
||||
{
|
||||
flowName: saveForm.flowName,
|
||||
description: saveForm.description,
|
||||
flowContent: workflowDsl.value,
|
||||
},
|
||||
{ errorMode: 'page' }
|
||||
);
|
||||
await saveWorkflow({
|
||||
flowName: saveForm.flowName,
|
||||
description: saveForm.description,
|
||||
flowContent: workflowDsl.value,
|
||||
});
|
||||
ElMessage.success('工作流保存成功');
|
||||
}
|
||||
saveDialogVisible.value = false;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div class="system-edit-module-container">
|
||||
<el-dialog :title="state.dialog.title" v-model="state.dialog.isShowDialog" width="900px">
|
||||
<el-form
|
||||
@@ -19,12 +19,7 @@
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="模型类型" prop="modelsType">
|
||||
<el-select v-model="state.ruleForm.modelsType" placeholder="请选择模型类型" clearable style="width: 100%">
|
||||
<el-option
|
||||
v-for="t in modelTypeOptions"
|
||||
:key="String(t.id)"
|
||||
:label="t.label"
|
||||
:value="typeOptionValue(t.id)"
|
||||
></el-option>
|
||||
<el-option v-for="t in modelTypeOptions" :key="String(t.id)" :label="t.label" :value="typeOptionValue(t.id)"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -53,13 +48,7 @@
|
||||
</el-col>
|
||||
<el-col v-if="state.ruleForm.isPrivate === 1" :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="API 密钥" prop="apiKey">
|
||||
<el-input
|
||||
v-model="state.ruleForm.apiKey"
|
||||
type="password"
|
||||
show-password
|
||||
placeholder="请输入 API 密钥字符串"
|
||||
clearable
|
||||
></el-input>
|
||||
<el-input v-model="state.ruleForm.apiKey" type="password" show-password placeholder="请输入 API 密钥字符串" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
@@ -139,29 +128,21 @@
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="自动清理间隔(秒)" prop="autoCleanSeconds">
|
||||
<el-input-number v-model="state.ruleForm.autoCleanSeconds" :min="0" :max="86400" style="width: 100%"></el-input-number>
|
||||
<el-input-number v-model="state.ruleForm.autoCleanSeconds" :min="0" :max="86400" style="width: 100%"> </el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="请求映射" prop="requestMappingJson">
|
||||
<el-input
|
||||
v-model="state.ruleForm.requestMappingJson"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder='JSON 对象,例如 {}'
|
||||
clearable
|
||||
></el-input>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="请求映射" prop="requestMapping">
|
||||
<el-button @click="showRequestMappingDialog = true" style="width: 100%">
|
||||
配置请求映射 ({{ state.requestMappingFields.length }})
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="响应映射" prop="responseMappingJson">
|
||||
<el-input
|
||||
v-model="state.ruleForm.responseMappingJson"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder='JSON 对象,例如 {}'
|
||||
clearable
|
||||
></el-input>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="响应映射" prop="responseMapping">
|
||||
<el-button @click="showResponseMappingDialog = true" style="width: 100%">
|
||||
配置响应映射 ({{ state.responseMappingFields.length }})
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -170,13 +151,7 @@
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="onSubmit"
|
||||
size="default"
|
||||
:loading="state.dialog.loading"
|
||||
:disabled="state.dialog.detailLoading"
|
||||
>
|
||||
<el-button type="primary" @click="onSubmit" size="default" :loading="state.dialog.loading" :disabled="state.dialog.detailLoading">
|
||||
{{ state.dialog.submitTxt }}
|
||||
</el-button>
|
||||
</span>
|
||||
@@ -219,6 +194,51 @@
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 请求映射配置弹窗 -->
|
||||
<el-dialog v-model="showRequestMappingDialog" title="配置请求映射" width="600px" :close-on-click-modal="false">
|
||||
<div class="mapping-config-container">
|
||||
<div v-for="(field, index) in state.requestMappingFields" :key="index" class="mapping-field-item">
|
||||
<el-input v-model="field.key" placeholder="请输入字段名 (Key)" style="width: 40%" clearable></el-input>
|
||||
<span class="separator">=</span>
|
||||
<el-input v-model="field.value" placeholder="请输入字段值 (Value)" style="width: 40%" clearable></el-input>
|
||||
<el-button type="danger" link @click="removeRequestMappingField(index)">删除</el-button>
|
||||
</div>
|
||||
<el-button type="primary" link @click="addRequestMappingField" style="margin-top: 10px">+ 添加字段</el-button>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showRequestMappingDialog = false" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="confirmRequestMappingFields" size="default">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 响应映射配置弹窗 -->
|
||||
<el-dialog v-model="showResponseMappingDialog" title="配置响应映射" width="700px" :close-on-click-modal="false">
|
||||
<div class="mapping-config-container">
|
||||
<div v-for="(field, index) in state.responseMappingFields" :key="index" class="mapping-field-item">
|
||||
<el-input v-model="field.key" placeholder="请输入字段名 (Key)" style="width: 30%" clearable></el-input>
|
||||
<span class="separator">=</span>
|
||||
<el-input v-model="field.value" placeholder="请输入字段值 (Value)" style="width: 30%" clearable></el-input>
|
||||
<el-button
|
||||
:type="field.isMainBody ? 'success' : 'primary'"
|
||||
:plain="!field.isMainBody"
|
||||
@click="setMainBody(index)"
|
||||
size="small"
|
||||
>
|
||||
{{ field.isMainBody ? '✓ 返回主体' : '设置返回主体' }}
|
||||
</el-button>
|
||||
<el-button type="danger" link @click="removeResponseMappingField(index)">删除</el-button>
|
||||
</div>
|
||||
<el-button type="primary" link @click="addResponseMappingField" style="margin-top: 10px">+ 添加字段</el-button>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showResponseMappingDialog = false" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="confirmResponseMappingFields" size="default">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -227,12 +247,7 @@ import { reactive, ref, computed } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import { ArrowUp, ArrowDown } from '@element-plus/icons-vue';
|
||||
import {
|
||||
addModelModule,
|
||||
updateModelModule,
|
||||
getModelModuleDetail,
|
||||
type ModelFormEntry,
|
||||
} from '/@/api/digitalHuman/modelConfig/modelModule/index';
|
||||
import { addModelModule, updateModelModule, getModelModuleDetail, type ModelFormEntry } from '/@/api/digitalHuman/modelConfig/modelModule/index';
|
||||
|
||||
export type ModelTypeOption = { id: number | string; label: string };
|
||||
|
||||
@@ -254,6 +269,8 @@ const editModuleFormRef = ref();
|
||||
const emit = defineEmits(['refresh']);
|
||||
const showHeaderDialog = ref(false);
|
||||
const showFormDialog = ref(false);
|
||||
const showRequestMappingDialog = ref(false);
|
||||
const showResponseMappingDialog = ref(false);
|
||||
const state = reactive({
|
||||
ruleForm: {
|
||||
id: '',
|
||||
@@ -274,8 +291,6 @@ const state = reactive({
|
||||
retryQueueMaxSeconds: 60,
|
||||
autoCleanSeconds: 300,
|
||||
remark: '',
|
||||
requestMappingJson: '{}',
|
||||
responseMappingJson: '{}',
|
||||
},
|
||||
rules: {
|
||||
modelName: [{ required: true, message: '请输入模型名称', trigger: 'blur' }],
|
||||
@@ -293,48 +308,6 @@ const state = reactive({
|
||||
],
|
||||
baseUrl: [{ required: true, message: '请输入模型服务地址', trigger: 'blur' }],
|
||||
httpMethod: [{ required: true, message: '请选择请求方式', trigger: 'change' }],
|
||||
requestMappingJson: [
|
||||
{
|
||||
validator: (_rule: unknown, value: string, callback: (e?: Error) => void) => {
|
||||
if (!value || !String(value).trim()) {
|
||||
callback(new Error('请输入请求映射 JSON'));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const o = JSON.parse(value);
|
||||
if (o === null || typeof o !== 'object' || Array.isArray(o)) {
|
||||
callback(new Error('请求映射须为 JSON 对象'));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
} catch {
|
||||
callback(new Error('请求映射 JSON 格式无效'));
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
responseMappingJson: [
|
||||
{
|
||||
validator: (_rule: unknown, value: string, callback: (e?: Error) => void) => {
|
||||
if (!value || !String(value).trim()) {
|
||||
callback(new Error('请输入响应映射 JSON'));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const o = JSON.parse(value);
|
||||
if (o === null || typeof o !== 'object' || Array.isArray(o)) {
|
||||
callback(new Error('响应映射须为 JSON 对象'));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
} catch {
|
||||
callback(new Error('响应映射 JSON 格式无效'));
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
maxConcurrency: [{ required: true, message: '请输入最大并发数', trigger: 'blur' }],
|
||||
queueLimit: [{ required: true, message: '请输入排队队列上限', trigger: 'blur' }],
|
||||
timeoutSeconds: [{ required: true, message: '请输入请求超时时间', trigger: 'blur' }],
|
||||
@@ -351,8 +324,22 @@ const state = reactive({
|
||||
showAdvanced: false,
|
||||
headers: [] as Array<{ key: string; value: string }>,
|
||||
formFields: [] as Array<{ key: string; value: string }>,
|
||||
requestMappingFields: [] as Array<{ key: string; value: string }>,
|
||||
responseMappingFields: [] as Array<{ key: string; value: string; isMainBody?: boolean }>,
|
||||
mainBodyIndex: -1, // 记录哪一行被设置为返回主体
|
||||
});
|
||||
|
||||
// 将数组转换为对象
|
||||
const fieldsToObject = (fields: Array<{ key: string; value: string }>) => {
|
||||
const obj: Record<string, string> = {};
|
||||
fields.forEach((f) => {
|
||||
if (f.key && f.key.trim()) {
|
||||
obj[f.key.trim()] = f.value || '';
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
};
|
||||
|
||||
const parseHeaders = (headMsg: string) => parseKeyValueString(headMsg);
|
||||
// 解析 form:支持数组 [{ key, value }] 或历史对象 { k: { value } }
|
||||
const parseFormFields = (form: unknown) => {
|
||||
@@ -368,15 +355,25 @@ const parseFormFields = (form: unknown) => {
|
||||
if (typeof form === 'object') {
|
||||
const fields: Array<{ key: string; value: string }> = [];
|
||||
Object.keys(form as Record<string, unknown>).forEach((key) => {
|
||||
const v = (form as Record<string, { value?: string }>)[key];
|
||||
if (v && typeof v === 'object' && v.value !== undefined) {
|
||||
fields.push({ key, value: String(v.value) });
|
||||
}
|
||||
const v = (form as Record<string, unknown>)[key];
|
||||
const value = String(v || '');
|
||||
fields.push({ key, value });
|
||||
});
|
||||
return fields;
|
||||
}
|
||||
return [];
|
||||
};
|
||||
// 解析 requestMapping 对象为数组
|
||||
const parseRequestMappingFields = (mapping: unknown) => {
|
||||
if (!mapping || typeof mapping !== 'object' || Array.isArray(mapping)) return [];
|
||||
return Object.entries(mapping).map(([key, value]) => ({ key, value: String(value) }));
|
||||
};
|
||||
|
||||
// 解析 responseMapping 对象为数组
|
||||
const parseResponseMappingFields = (mapping: unknown) => {
|
||||
if (!mapping || typeof mapping !== 'object' || Array.isArray(mapping)) return [];
|
||||
return Object.entries(mapping).map(([key, value]) => ({ key, value: String(value) }));
|
||||
};
|
||||
|
||||
const buildFormArray = (): ModelFormEntry[] => {
|
||||
return state.formFields
|
||||
@@ -454,9 +451,48 @@ const removeFormField = (index: number) => {
|
||||
const confirmFormFields = () => {
|
||||
showFormDialog.value = false;
|
||||
};
|
||||
// 请求映射字段操作
|
||||
const addRequestMappingField = () => {
|
||||
state.requestMappingFields.push({ key: '', value: '' });
|
||||
};
|
||||
|
||||
const removeRequestMappingField = (index: number) => {
|
||||
state.requestMappingFields.splice(index, 1);
|
||||
};
|
||||
|
||||
const confirmRequestMappingFields = () => {
|
||||
showRequestMappingDialog.value = false;
|
||||
};
|
||||
|
||||
// 响应映射字段操作
|
||||
const addResponseMappingField = () => {
|
||||
state.responseMappingFields.push({ key: '', value: '', isMainBody: false });
|
||||
};
|
||||
|
||||
const removeResponseMappingField = (index: number) => {
|
||||
state.responseMappingFields.splice(index, 1);
|
||||
};
|
||||
|
||||
// 设置返回主体(单选)
|
||||
const setMainBody = (index: number) => {
|
||||
// 清除所有字段的返回主体标记
|
||||
state.responseMappingFields.forEach((field, i) => {
|
||||
field.isMainBody = i === index;
|
||||
});
|
||||
state.mainBodyIndex = index;
|
||||
};
|
||||
|
||||
const confirmResponseMappingFields = () => {
|
||||
showResponseMappingDialog.value = false;
|
||||
};
|
||||
|
||||
const ensureKeyValueRows = (rows: Array<{ key: string; value: string }>) => (rows.length ? rows : [{ key: '', value: '' }]);
|
||||
|
||||
const ensureResponseMappingRows = (rows: Array<{ key: string; value: string; isMainBody?: boolean }>) => {
|
||||
if (!rows.length) return [{ key: '', value: '', isMainBody: false }];
|
||||
return rows.map(row => ({ ...row, isMainBody: row.isMainBody || false }));
|
||||
};
|
||||
|
||||
/** 从 getModel 返回的 data 中取出单条模型对象 */
|
||||
const unwrapModelDetailPayload = (data: unknown): Record<string, unknown> | null => {
|
||||
if (data == null) return null;
|
||||
@@ -487,10 +523,7 @@ const fillFormFromDetailRow = (row: Record<string, unknown>) => {
|
||||
state.ruleForm = {
|
||||
id: row.id as string,
|
||||
modelName: String(row.modelName ?? ''),
|
||||
modelsType:
|
||||
row.modelsType !== undefined && row.modelsType !== null
|
||||
? typeOptionValue(row.modelsType as number | string)
|
||||
: null,
|
||||
modelsType: row.modelsType !== undefined && row.modelsType !== null ? typeOptionValue(row.modelsType as number | string) : null,
|
||||
baseUrl: String(row.baseUrl ?? ''),
|
||||
httpMethod: String(row.httpMethod || 'POST'),
|
||||
headMsg: String(row.headMsg || ''),
|
||||
@@ -506,21 +539,25 @@ const fillFormFromDetailRow = (row: Record<string, unknown>) => {
|
||||
retryQueueMaxSeconds: Number(row.retryQueueMaxSeconds ?? 60),
|
||||
autoCleanSeconds: Number(row.autoCleanSeconds ?? 300),
|
||||
remark: String(row.remark || ''),
|
||||
requestMappingJson: JSON.stringify(
|
||||
row.requestMapping && typeof row.requestMapping === 'object' ? row.requestMapping : {},
|
||||
null,
|
||||
2
|
||||
),
|
||||
responseMappingJson: JSON.stringify(
|
||||
row.responseMapping && typeof row.responseMapping === 'object' ? row.responseMapping : {},
|
||||
null,
|
||||
2
|
||||
),
|
||||
};
|
||||
state.headers = ensureKeyValueRows(parseHeaders(String(row.headMsg || '')));
|
||||
state.formFields = ensureKeyValueRows(parseFormFields(row.form));
|
||||
// 解析请求映射和响应映射
|
||||
state.requestMappingFields = ensureKeyValueRows(parseRequestMappingFields(row.requestMapping));
|
||||
state.responseMappingFields = ensureResponseMappingRows(parseResponseMappingFields(row.responseMapping));
|
||||
|
||||
// 根据 responseBody 字段设置返回主体标记 (responseBody 是对象 {key: value})
|
||||
if (row.responseBody && typeof row.responseBody === 'object') {
|
||||
const responseBodyKey = Object.keys(row.responseBody)[0];
|
||||
if (responseBodyKey) {
|
||||
const mainBodyIndex = state.responseMappingFields.findIndex(f => f.key === responseBodyKey);
|
||||
if (mainBodyIndex !== -1) {
|
||||
state.responseMappingFields[mainBodyIndex].isMainBody = true;
|
||||
state.mainBodyIndex = mainBodyIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 打开弹窗(编辑时会请求 /model/getModel 详情)
|
||||
const openDialog = async (type: string, row?: Record<string, unknown>) => {
|
||||
state.dialog.type = type;
|
||||
@@ -553,7 +590,7 @@ const openDialog = async (type: string, row?: Record<string, unknown>) => {
|
||||
}
|
||||
fillFormFromDetailRow(detail as Record<string, unknown>);
|
||||
} catch {
|
||||
ElMessage.error('获取模型详情失败');
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
state.dialog.isShowDialog = false;
|
||||
} finally {
|
||||
state.dialog.detailLoading = false;
|
||||
@@ -578,11 +615,11 @@ const openDialog = async (type: string, row?: Record<string, unknown>) => {
|
||||
retryQueueMaxSeconds: 60,
|
||||
autoCleanSeconds: 300,
|
||||
remark: '',
|
||||
requestMappingJson: '{}',
|
||||
responseMappingJson: '{}',
|
||||
};
|
||||
state.headers = [{ key: '', value: '' }];
|
||||
state.formFields = [{ key: '', value: '' }];
|
||||
state.requestMappingFields = [{ key: '', value: '' }];
|
||||
state.responseMappingFields = [{ key: '', value: '', isMainBody: false }];
|
||||
state.dialog.title = '新增模型配置';
|
||||
state.dialog.submitTxt = '新 增';
|
||||
}
|
||||
@@ -608,8 +645,11 @@ const onSubmit = () => {
|
||||
state.dialog.loading = true;
|
||||
try {
|
||||
state.ruleForm.headMsg = stringifyHeaders();
|
||||
const requestMapping = parseJsonObjectField(state.ruleForm.requestMappingJson, {});
|
||||
const responseMapping = parseJsonObjectField(state.ruleForm.responseMappingJson, {});
|
||||
const requestMapping = fieldsToObject(state.requestMappingFields);
|
||||
const responseMapping = fieldsToObject(state.responseMappingFields);
|
||||
// 获取被设置为返回主体的字段 {key: value}
|
||||
const responseBodyField = state.responseMappingFields.find(f => f.isMainBody);
|
||||
const responseBody = responseBodyField ? { [responseBodyField.key.trim()]: responseBodyField.value } : {};
|
||||
const submitData = {
|
||||
modelName: state.ruleForm.modelName,
|
||||
modelsType: state.ruleForm.modelsType as number | string,
|
||||
@@ -620,9 +660,10 @@ const onSubmit = () => {
|
||||
enabled: state.ruleForm.enabled,
|
||||
isChatModel: state.ruleForm.isChatModel,
|
||||
apiKey: state.ruleForm.isPrivate === 1 ? String(state.ruleForm.apiKey ?? '').trim() : '',
|
||||
form: buildFormArray(),
|
||||
form: fieldsToObject(state.formFields),
|
||||
requestMapping,
|
||||
responseMapping,
|
||||
responseBody,
|
||||
maxConcurrency: state.ruleForm.maxConcurrency,
|
||||
queueLimit: state.ruleForm.queueLimit,
|
||||
timeoutSeconds: state.ruleForm.timeoutSeconds,
|
||||
@@ -642,8 +683,8 @@ const onSubmit = () => {
|
||||
}
|
||||
closeDialog();
|
||||
emit('refresh');
|
||||
} catch (error) {
|
||||
ElMessage.error('保存失败');
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
} finally {
|
||||
state.dialog.loading = false;
|
||||
}
|
||||
@@ -657,6 +698,19 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mapping-config-container {
|
||||
.mapping-field-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.separator {
|
||||
font-weight: bold;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
}
|
||||
.form-config-container {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
@@ -689,3 +743,50 @@ defineExpose({
|
||||
color: #606266;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,25 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="httpMethod" label="请求方式" width="100"></el-table-column>
|
||||
<el-table-column label="会话模型" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="Number(row.isChatModel) === 1 ? 'success' : 'info'" size="small">
|
||||
{{ Number(row.isChatModel) === 1 ? '是' : '否' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="会话开关" width="110" align="center">
|
||||
<template #default="{ row }">
|
||||
<template v-if="Number(row.isChatModel) === 1">
|
||||
<el-switch
|
||||
size="small"
|
||||
:model-value="chatSessionSwitchOn(row)"
|
||||
:before-change="() => onChatSessionSwitchRequest(row)"
|
||||
/>
|
||||
</template>
|
||||
<span v-else class="text-muted">—</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="enabled" label="状态" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.enabled === 1 ? 'success' : 'danger'">{{ scope.row.enabled === 1 ? '启用' : '禁用' }}</el-tag>
|
||||
@@ -94,6 +113,16 @@ const state = reactive({
|
||||
},
|
||||
});
|
||||
|
||||
/** 列表行与会话开关接口约定字段 chatSessionEnabled(0/1);接口未就绪前占位 */
|
||||
const chatSessionSwitchOn = (row: { chatSessionEnabled?: number }) => Number(row.chatSessionEnabled) === 1;
|
||||
|
||||
const onChatSessionSwitchRequest = (_row: { id?: number | string }) => {
|
||||
return new Promise<boolean>((resolve) => {
|
||||
ElMessage.info('会话开关接口接入后即可生效');
|
||||
resolve(false);
|
||||
});
|
||||
};
|
||||
|
||||
const resolveModelTypeLabel = (modelsType: number | string | undefined | null) => {
|
||||
if (modelsType === undefined || modelsType === null || modelsType === '') {
|
||||
return '—';
|
||||
@@ -108,8 +137,8 @@ const loadModelTypes = async () => {
|
||||
if (res.code === 0) {
|
||||
state.modelTypes = normalizeModelTypeOptions(res);
|
||||
}
|
||||
} catch (e) {
|
||||
ElMessage.error('获取模型类型失败:');
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
}
|
||||
};
|
||||
|
||||
@@ -122,8 +151,8 @@ const getTableData = async () => {
|
||||
state.tableData.data = res.data.list || [];
|
||||
state.tableData.total = res.data.total || 0;
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('获取模型列表失败');
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
} finally {
|
||||
state.tableData.loading = false;
|
||||
}
|
||||
@@ -151,8 +180,8 @@ const onRowDel = (row: any) => {
|
||||
await deleteModelModule(row.id);
|
||||
ElMessage.success('删除成功');
|
||||
getTableData();
|
||||
} catch (error) {
|
||||
ElMessage.error('删除失败');
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
@@ -178,6 +207,10 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.text-muted {
|
||||
color: var(--el-text-color-placeholder);
|
||||
}
|
||||
|
||||
.system-user-container {
|
||||
:deep(.el-card__body) {
|
||||
display: flex;
|
||||
|
||||
@@ -162,7 +162,7 @@ const handleFileChange: UploadProps['onChange'] = async (uploadFile) => {
|
||||
}
|
||||
try {
|
||||
ElMessage.info('正在上传文件到 OSS...');
|
||||
const uploadRes = await uploadFileToOss(uploadFile.raw, { errorMode: 'page' });
|
||||
const uploadRes = await uploadFileToOss(uploadFile.raw);
|
||||
formData.fileName = uploadRes.data.fileName;
|
||||
formData.fileUrl = uploadRes.data.fileURL;
|
||||
fileList.value = [uploadFile];
|
||||
@@ -180,7 +180,7 @@ const fetchSkillList = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = { pageNum: pagination.pageNum, pageSize: pagination.pageSize, keyword: searchParams.keyword || undefined };
|
||||
const res = await getUserSkillList(params, { errorMode: 'page' });
|
||||
const res = await getUserSkillList(params);
|
||||
skillList.value = res.data?.list || [];
|
||||
pagination.total = res.data?.total || 0;
|
||||
} catch (error) {
|
||||
@@ -222,21 +222,18 @@ const handleSubmit = async () => {
|
||||
}
|
||||
submitting.value = true;
|
||||
try {
|
||||
await createUserSkill(
|
||||
{
|
||||
name: formData.name,
|
||||
description: formData.description,
|
||||
category: formData.category,
|
||||
fileName: formData.fileName,
|
||||
fileUrl: formData.fileUrl,
|
||||
},
|
||||
{ errorMode: 'page' }
|
||||
);
|
||||
await createUserSkill({
|
||||
name: formData.name,
|
||||
description: formData.description,
|
||||
category: formData.category,
|
||||
fileName: formData.fileName,
|
||||
fileUrl: formData.fileUrl,
|
||||
});
|
||||
ElMessage.success('创建成功');
|
||||
dialogVisible.value = false;
|
||||
fetchSkillList();
|
||||
} catch (error) {
|
||||
// 错误已由 errorMode: 'page' 处理
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
@@ -251,12 +248,12 @@ const handleCommand = async (command: string, skill: SkillItem) => {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
await deleteUserSkill(skill.id, { errorMode: 'page' });
|
||||
await deleteUserSkill(skill.id);
|
||||
ElMessage.success('删除成功');
|
||||
fetchSkillList();
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
// 错误已由 errorMode: 'page' 处理
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,7 +558,7 @@ const getknowledgeList = async () => {
|
||||
});
|
||||
knowledgeList.value = response.data.list || [];
|
||||
} catch (_error) {
|
||||
ElMessage.error('获取知识库列表失败');
|
||||
// 错误已由全局拦截器处理
|
||||
} finally {
|
||||
knowledgeLoading.value = false;
|
||||
}
|
||||
@@ -648,7 +648,7 @@ const onSaveknowledge = async () => {
|
||||
showknowledgeDialog.value = false;
|
||||
getknowledgeList();
|
||||
} catch (_error) {
|
||||
ElMessage.error('保存失败,请重试');
|
||||
// 错误已由全局拦截器处理
|
||||
} finally {
|
||||
knowledgeSaving.value = false;
|
||||
}
|
||||
@@ -673,7 +673,7 @@ const getFileList = async () => {
|
||||
statusEnabled: item.status === 1,
|
||||
}));
|
||||
} catch (_error) {
|
||||
ElMessage.error('获取文件列表失败');
|
||||
// 错误已由全局拦截器处理
|
||||
} finally {
|
||||
fileLoading.value = false;
|
||||
}
|
||||
@@ -745,7 +745,7 @@ const onConfirmUpload = async () => {
|
||||
showUploadDialog.value = false;
|
||||
getFileList();
|
||||
} catch (_error) {
|
||||
ElMessage.error('创建文档失败,请重试');
|
||||
// 错误已由全局拦截器处理
|
||||
} finally {
|
||||
uploading.value = false;
|
||||
}
|
||||
@@ -764,7 +764,7 @@ const onFileStatusChange = async (row: any) => {
|
||||
} catch (error) {
|
||||
// 失败时恢复原状态
|
||||
row.statusEnabled = !row.statusEnabled;
|
||||
ElMessage.error('状态更新失败');
|
||||
// 错误已由全局拦截器处理
|
||||
}
|
||||
};
|
||||
|
||||
@@ -779,7 +779,7 @@ const onGenerateVector = async (row: any) => {
|
||||
getFileList();
|
||||
}, 1000);
|
||||
} catch (error) {
|
||||
ElMessage.error('生成向量失败');
|
||||
// 错误已由全局拦截器处理
|
||||
}
|
||||
};
|
||||
|
||||
@@ -791,7 +791,7 @@ const onViewDocumentDetail = async (row: any) => {
|
||||
currentDocument.value = response.data;
|
||||
showDocumentDetailDialog.value = true;
|
||||
} catch (error) {
|
||||
ElMessage.error('获取文件详情失败');
|
||||
// 错误已由全局拦截器处理
|
||||
}
|
||||
};
|
||||
|
||||
@@ -917,7 +917,7 @@ const onEditModelConfig = async (row: any) => {
|
||||
// 打开弹窗
|
||||
showCreateModelDialog.value = true;
|
||||
} catch (error) {
|
||||
ElMessage.error('获取模型配置详情失败');
|
||||
// 错误已由全局拦截器处理
|
||||
}
|
||||
};
|
||||
|
||||
@@ -928,7 +928,7 @@ const getModelEnums = async () => {
|
||||
const response = await getAllModelEnums();
|
||||
modelEnums.value = response.data?.options || [];
|
||||
} catch (error) {
|
||||
ElMessage.error('获取模型类型枚举失败');
|
||||
// 错误已由全局拦截器处理
|
||||
modelEnums.value = [];
|
||||
} finally {
|
||||
modelEnumsLoading.value = false;
|
||||
@@ -975,7 +975,7 @@ const getModelFormFields = async () => {
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
ElMessage.error('获取模型表单字段失败');
|
||||
// 错误已由全局拦截器处理
|
||||
modelFormFields.value = [];
|
||||
} finally {
|
||||
modelFormLoading.value = false;
|
||||
@@ -1016,7 +1016,7 @@ const onSaveModelConfig = async () => {
|
||||
showCreateModelDialog.value = false;
|
||||
getModelConfigList();
|
||||
} catch (error) {
|
||||
ElMessage.error(isEditMode.value ? '更新模型配置失败' : '创建模型配置失败');
|
||||
// 错误已由全局拦截器处理
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1040,7 +1040,7 @@ const getModelConfigList = async () => {
|
||||
});
|
||||
modelConfigList.value = response.data?.list || [];
|
||||
} catch (error) {
|
||||
ElMessage.error('获取模型配置列表失败');
|
||||
// 错误已由全局拦截器处理
|
||||
modelConfigList.value = [];
|
||||
} finally {
|
||||
modelConfigLoading.value = false;
|
||||
@@ -1128,7 +1128,7 @@ const getTaskList = async () => {
|
||||
const response = await listTasks();
|
||||
taskList.value = response.data?.list || [];
|
||||
} catch (error) {
|
||||
ElMessage.error('获取任务列表失败');
|
||||
// 错误已由全局拦截器处理
|
||||
taskList.value = [];
|
||||
} finally {
|
||||
taskListLoading.value = false;
|
||||
@@ -1149,7 +1149,7 @@ const onReexecuteTask = async (task: any) => {
|
||||
// 重新获取任务列表
|
||||
await getTaskList();
|
||||
} catch (error) {
|
||||
ElMessage.error('重新执行任务失败,请重试');
|
||||
// 错误已由全局拦截器处理
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
@@ -114,7 +114,7 @@ const openDialog = async (row?: DialogFormData) => {
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('获取主播详情失败');
|
||||
// 错误已由全局拦截器处理
|
||||
} finally {
|
||||
state.loading = false;
|
||||
}
|
||||
@@ -160,7 +160,7 @@ const onSubmit = async () => {
|
||||
closeDialog();
|
||||
emit('refresh');
|
||||
} catch (error) {
|
||||
ElMessage.error('操作失败');
|
||||
// 错误已由全局拦截器处理
|
||||
} finally {
|
||||
state.loading = false;
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ const getList = async () => {
|
||||
tableData.total = res.data.total || 0;
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('获取主播列表失败');
|
||||
// 错误已由全局拦截器处理
|
||||
} finally {
|
||||
tableData.loading = false;
|
||||
}
|
||||
@@ -192,7 +192,7 @@ const handleDelete = async (row: TableDataItem) => {
|
||||
getList();
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('删除失败');
|
||||
// 错误已由全局拦截器处理
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -101,14 +101,13 @@ const openDialog = async (row?: { id?: string }) => {
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
// 详情加载失败时由当前弹窗给出更易懂的业务提示。
|
||||
const res = await getLiveAccountDetail({ id: String(row.id) }, { errorMode: 'page' });
|
||||
const res = await getLiveAccountDetail({ id: String(row.id) });
|
||||
if (res?.data) {
|
||||
fillForm(res.data);
|
||||
}
|
||||
dialogVisible.value = true;
|
||||
} catch (error) {
|
||||
ElMessage.error('获取直播账号详情失败');
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
@@ -130,19 +129,18 @@ const handleSubmit = async () => {
|
||||
remark: formData.remark,
|
||||
};
|
||||
|
||||
// 提交失败提示交给当前弹窗自己处理,避免和 request.ts 的统一报错重复。
|
||||
if (isEdit.value) {
|
||||
await updateLiveAccount(payload, { errorMode: 'page' });
|
||||
await updateLiveAccount(payload);
|
||||
ElMessage.success('修改成功');
|
||||
} else {
|
||||
await createLiveAccount(payload, { errorMode: 'page' });
|
||||
await createLiveAccount(payload);
|
||||
ElMessage.success('新增成功');
|
||||
}
|
||||
|
||||
dialogVisible.value = false;
|
||||
emit('refresh');
|
||||
} catch (error) {
|
||||
ElMessage.error(isEdit.value ? '修改失败' : '新增失败');
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
@@ -131,17 +131,13 @@ const tableData = reactive({
|
||||
const getList = async () => {
|
||||
try {
|
||||
tableData.loading = true;
|
||||
// 列表失败文案由当前页面决定,避免和全局请求报错同时出现。
|
||||
const res = await getLiveAccountList(
|
||||
{
|
||||
...tableData.param,
|
||||
platform: searchForm.platform || undefined,
|
||||
accountName: searchForm.accountName || undefined,
|
||||
accountId: searchForm.accountId || undefined,
|
||||
status: searchForm.status,
|
||||
},
|
||||
{ errorMode: 'page' }
|
||||
);
|
||||
const res = await getLiveAccountList({
|
||||
...tableData.param,
|
||||
platform: searchForm.platform || undefined,
|
||||
accountName: searchForm.accountName || undefined,
|
||||
accountId: searchForm.accountId || undefined,
|
||||
status: searchForm.status,
|
||||
});
|
||||
if (res && res.data) {
|
||||
tableData.data = (res.data.list || []).map((item: any) => ({
|
||||
...item,
|
||||
@@ -149,8 +145,8 @@ const getList = async () => {
|
||||
}));
|
||||
tableData.total = res.data.total || 0;
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('获取直播账号列表失败');
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
} finally {
|
||||
tableData.loading = false;
|
||||
}
|
||||
@@ -195,12 +191,12 @@ const handleDelete = async (row: LiveAccountItem) => {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
await deleteLiveAccount({ id: row.id }, { errorMode: 'page' });
|
||||
await deleteLiveAccount({ id: row.id });
|
||||
ElMessage.success('删除成功');
|
||||
getList();
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('删除失败');
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -153,8 +153,7 @@ const openDialog = async (row?: { id?: string }) => {
|
||||
await loadOptions();
|
||||
|
||||
if (row?.id) {
|
||||
// 详情请求失败时,这个弹窗希望给出更明确的页面语义提示。
|
||||
const res = await getScheduleDetail({ id: String(row.id) }, { errorMode: 'page' });
|
||||
const res = await getScheduleDetail({ id: String(row.id) });
|
||||
const detail = res?.data;
|
||||
if (detail) {
|
||||
formData.id = String(detail.id);
|
||||
@@ -170,8 +169,8 @@ const openDialog = async (row?: { id?: string }) => {
|
||||
}
|
||||
|
||||
dialogVisible.value = true;
|
||||
} catch (error) {
|
||||
ElMessage.error(isEdit.value ? '获取排班详情失败' : '加载排班基础数据失败');
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message;表单校验错误由表单项展示
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
@@ -196,19 +195,18 @@ const handleSubmit = async () => {
|
||||
remark: formData.remark,
|
||||
};
|
||||
|
||||
// 提交失败文案由弹窗自己控制,避免接口层和弹窗层重复报错。
|
||||
if (isEdit.value) {
|
||||
await updateSchedule(payload, { errorMode: 'page' });
|
||||
await updateSchedule(payload);
|
||||
ElMessage.success('修改排班成功');
|
||||
} else {
|
||||
await createSchedule(payload, { errorMode: 'page' });
|
||||
await createSchedule(payload);
|
||||
ElMessage.success('新增排班成功');
|
||||
}
|
||||
|
||||
dialogVisible.value = false;
|
||||
emit('refresh');
|
||||
} catch (error) {
|
||||
ElMessage.error(isEdit.value ? '修改排班失败' : '新增排班失败');
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
@@ -144,16 +144,12 @@ const getStatusTagType = (status: number): 'success' | 'info' | 'warning' => {
|
||||
const getList = async () => {
|
||||
try {
|
||||
tableData.loading = true;
|
||||
// 列表失败文案由当前页面决定,避免和 request.ts 的全局错误提示重复。
|
||||
const res = await getScheduleList(
|
||||
{
|
||||
...tableData.param,
|
||||
anchorName: searchForm.anchorName || undefined,
|
||||
accountName: searchForm.accountName || undefined,
|
||||
status: searchForm.status,
|
||||
} as any,
|
||||
{ errorMode: 'page' }
|
||||
);
|
||||
const res = await getScheduleList({
|
||||
...tableData.param,
|
||||
anchorName: searchForm.anchorName || undefined,
|
||||
accountName: searchForm.accountName || undefined,
|
||||
status: searchForm.status,
|
||||
} as any);
|
||||
const scheduleData = res?.data;
|
||||
if (scheduleData) {
|
||||
tableData.data = (scheduleData.list || []).map((item: any) => ({
|
||||
@@ -166,8 +162,8 @@ const getList = async () => {
|
||||
}));
|
||||
tableData.total = scheduleData.total || 0;
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('获取排班列表失败');
|
||||
} catch {
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
} finally {
|
||||
tableData.loading = false;
|
||||
}
|
||||
@@ -211,12 +207,12 @@ const handleDelete = async (row: ScheduleItem) => {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
await deleteSchedule({ id: row.id }, { errorMode: 'page' });
|
||||
await deleteSchedule({ id: row.id });
|
||||
ElMessage.success('删除成功');
|
||||
getList();
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('删除失败');
|
||||
// 接口错误由 request 全局提示后端 message
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user