feat: ai
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
|
||||
import { DICT_TYPE, getDictOptions } from '#/utils';
|
||||
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
/** 列表的搜索表单 */
|
||||
export function useGridFormSchema(): VbenFormSchema[] {
|
||||
@@ -30,8 +30,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
|
||||
label: '创建时间',
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
placeholder: ['开始时间', '结束时间'],
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
...getRangePickerDefaultProps(),
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -28,14 +28,14 @@ const basicInfoRef = ref<InstanceType<typeof BasicInfo>>();
|
||||
const workflowDesignRef = ref<InstanceType<typeof WorkflowDesign>>();
|
||||
|
||||
/** 步骤校验函数 */
|
||||
const validateBasic = async () => {
|
||||
async function validateBasic() {
|
||||
await basicInfoRef.value?.validate();
|
||||
};
|
||||
}
|
||||
|
||||
/** 工作流设计校验 */
|
||||
const validateWorkflow = async () => {
|
||||
async function validateWorkflow() {
|
||||
await workflowDesignRef.value?.validate();
|
||||
};
|
||||
}
|
||||
|
||||
const currentStep = ref(-1); // 步骤控制。-1 用于,一开始全部不展示等当前页面数据初始化完成
|
||||
|
||||
@@ -60,7 +60,8 @@ provide('workflowData', workflowData);
|
||||
|
||||
/** 初始化数据 */
|
||||
const actionType = route.params.type as string;
|
||||
const initData = async () => {
|
||||
|
||||
async function initData() {
|
||||
if (actionType === 'update') {
|
||||
const workflowId = route.params.id as string;
|
||||
formData.value = await getWorkflow(workflowId);
|
||||
@@ -79,10 +80,10 @@ const initData = async () => {
|
||||
|
||||
// 设置当前步骤
|
||||
currentStep.value = 0;
|
||||
};
|
||||
}
|
||||
|
||||
/** 校验所有步骤数据是否完整 */
|
||||
const validateAllSteps = async () => {
|
||||
async function validateAllSteps() {
|
||||
// 基本信息校验
|
||||
try {
|
||||
await validateBasic();
|
||||
@@ -99,10 +100,10 @@ const validateAllSteps = async () => {
|
||||
throw new Error('请完善工作流信息');
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
/** 保存操作 */
|
||||
const handleSave = async () => {
|
||||
async function handleSave() {
|
||||
try {
|
||||
// 保存前校验所有步骤的数据
|
||||
await validateAllSteps();
|
||||
@@ -124,10 +125,10 @@ const handleSave = async () => {
|
||||
console.error('保存失败:', error);
|
||||
message.warning(error.message || '请完善所有步骤的必填信息');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 发布操作 */
|
||||
const handleDeploy = async () => {
|
||||
async function handleDeploy() {
|
||||
try {
|
||||
// 修改场景下直接发布,新增场景下需要先确认
|
||||
if (!formData.value.id) {
|
||||
@@ -158,10 +159,10 @@ const handleDeploy = async () => {
|
||||
console.error('发布失败:', error);
|
||||
message.warning(error.message || '发布失败');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 步骤切换处理 */
|
||||
const handleStepClick = async (index: number) => {
|
||||
async function handleStepClick(index: number) {
|
||||
try {
|
||||
if (index !== 0) {
|
||||
await validateBasic();
|
||||
@@ -176,17 +177,17 @@ const handleStepClick = async (index: number) => {
|
||||
console.error('步骤切换失败:', error);
|
||||
message.warning('请先完善当前步骤必填信息');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const tabs = useTabs();
|
||||
|
||||
/** 返回列表页 */
|
||||
const handleBack = () => {
|
||||
function handleBack() {
|
||||
// 关闭当前页签
|
||||
tabs.closeCurrentTab();
|
||||
// 跳转到列表页,使用路径, 目前后端的路由 name: 'name'+ menuId
|
||||
router.push({ path: '/ai/workflow' });
|
||||
};
|
||||
}
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(async () => {
|
||||
|
||||
@@ -18,9 +18,9 @@ const rules: Record<string, Rule[]> = {
|
||||
};
|
||||
|
||||
/** 表单校验 */
|
||||
const validate = async () => {
|
||||
async function validate() {
|
||||
await formRef.value?.validate();
|
||||
};
|
||||
}
|
||||
|
||||
defineExpose({ validate });
|
||||
</script>
|
||||
|
||||
@@ -4,11 +4,12 @@ import type { Ref } from 'vue';
|
||||
import { inject, ref } from 'vue';
|
||||
|
||||
import { useVbenDrawer } from '@vben/common-ui';
|
||||
import { isNumber } from '@vben/utils';
|
||||
|
||||
import { Button, Input, Select } from 'ant-design-vue';
|
||||
|
||||
import { testWorkflow } from '#/api/ai/workflow';
|
||||
import Tinyflow from '#/components/tinyflow/tinyflow.vue';
|
||||
import { Tinyflow } from '#/components/tinyflow';
|
||||
|
||||
defineProps<{
|
||||
provider: any;
|
||||
@@ -28,26 +29,26 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
||||
modal: false,
|
||||
});
|
||||
/** 展示工作流测试抽屉 */
|
||||
const testWorkflowModel = () => {
|
||||
function testWorkflowModel() {
|
||||
drawerApi.open();
|
||||
const startNode = getStartNode();
|
||||
|
||||
// 获取参数定义
|
||||
const parameters = startNode.data?.parameters || [];
|
||||
const paramDefinitions = {};
|
||||
const paramDefinitions: Record<string, any> = {};
|
||||
|
||||
// 加入参数选项方便用户添加非必须参数
|
||||
parameters.forEach((param) => {
|
||||
parameters.forEach((param: any) => {
|
||||
paramDefinitions[param.name] = param;
|
||||
});
|
||||
|
||||
function mergeIfRequiredButNotSet(target) {
|
||||
function mergeIfRequiredButNotSet(target: any) {
|
||||
const needPushList = [];
|
||||
for (const key in paramDefinitions) {
|
||||
const param = paramDefinitions[key];
|
||||
|
||||
if (param.required) {
|
||||
const item = target.find((item) => item.key === key);
|
||||
const item = target.find((item: any) => item.key === key);
|
||||
|
||||
if (!item) {
|
||||
needPushList.push({
|
||||
@@ -63,10 +64,10 @@ const testWorkflowModel = () => {
|
||||
mergeIfRequiredButNotSet(params4Test.value);
|
||||
|
||||
paramsOfStartNode.value = paramDefinitions;
|
||||
};
|
||||
}
|
||||
|
||||
/** 运行流程 */
|
||||
const goRun = async () => {
|
||||
async function goRun() {
|
||||
try {
|
||||
const val = tinyflowRef.value.getData();
|
||||
loading.value = true;
|
||||
@@ -77,13 +78,13 @@ const goRun = async () => {
|
||||
|
||||
// 获取参数定义
|
||||
const parameters = startNode.data?.parameters || [];
|
||||
const paramDefinitions = {};
|
||||
parameters.forEach((param) => {
|
||||
const paramDefinitions: Record<string, any> = {};
|
||||
parameters.forEach((param: any) => {
|
||||
paramDefinitions[param.name] = param.dataType;
|
||||
});
|
||||
|
||||
// 参数类型转换
|
||||
const convertedParams = {};
|
||||
const convertedParams: Record<string, any> = {};
|
||||
for (const { key, value } of params4Test.value) {
|
||||
const paramKey = key.trim();
|
||||
if (!paramKey) continue;
|
||||
@@ -95,8 +96,8 @@ const goRun = async () => {
|
||||
|
||||
try {
|
||||
convertedParams[paramKey] = convertParamValue(value, dataType);
|
||||
} catch (error_) {
|
||||
throw new Error(`参数 ${paramKey} 转换失败: ${error_.message}`);
|
||||
} catch (error: any) {
|
||||
throw new Error(`参数 ${paramKey} 转换失败: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,42 +108,42 @@ const goRun = async () => {
|
||||
|
||||
const response = await testWorkflow(data);
|
||||
testResult.value = response;
|
||||
} catch (error_) {
|
||||
} catch (error: any) {
|
||||
error.value =
|
||||
error_.response?.data?.message || '运行失败,请检查参数和网络连接';
|
||||
error.response?.data?.message || '运行失败,请检查参数和网络连接';
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 获取开始节点 */
|
||||
const getStartNode = () => {
|
||||
function getStartNode() {
|
||||
const val = tinyflowRef.value.getData();
|
||||
const startNode = val.nodes.find((node) => node.type === 'startNode');
|
||||
const startNode = val.nodes.find((node: any) => node.type === 'startNode');
|
||||
if (!startNode) {
|
||||
throw new Error('流程缺少开始节点');
|
||||
}
|
||||
return startNode;
|
||||
};
|
||||
}
|
||||
|
||||
/** 添加参数项 */
|
||||
const addParam = () => {
|
||||
function addParam() {
|
||||
params4Test.value.push({ key: '', value: '' });
|
||||
};
|
||||
}
|
||||
|
||||
/** 删除参数项 */
|
||||
const removeParam = (index) => {
|
||||
function removeParam(index: number) {
|
||||
params4Test.value.splice(index, 1);
|
||||
};
|
||||
}
|
||||
|
||||
/** 类型转换函数 */
|
||||
const convertParamValue = (value, dataType) => {
|
||||
function convertParamValue(value: string, dataType: string) {
|
||||
if (value === '') return null; // 空值处理
|
||||
|
||||
switch (dataType) {
|
||||
case 'Number': {
|
||||
const num = Number(value);
|
||||
if (isNaN(num)) throw new Error('非数字格式');
|
||||
if (!isNumber(num)) throw new Error('非数字格式');
|
||||
return num;
|
||||
}
|
||||
case 'String': {
|
||||
@@ -157,24 +158,24 @@ const convertParamValue = (value, dataType) => {
|
||||
case 'Object': {
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
} catch (error_) {
|
||||
throw new Error(`JSON格式错误: ${error_.message}`);
|
||||
} catch (error: any) {
|
||||
throw new Error(`JSON格式错误: ${error.message}`);
|
||||
}
|
||||
}
|
||||
default: {
|
||||
throw new Error(`不支持的类型: ${dataType}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
/** 表单校验 */
|
||||
const validate = async () => {
|
||||
async function validate() {
|
||||
// 获取最新的流程数据
|
||||
if (!workflowData.value) {
|
||||
throw new Error('请设计流程');
|
||||
}
|
||||
workflowData.value = tinyflowRef.value.getData();
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
defineExpose({ validate });
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user