函数构建按钮

This commit is contained in:
ChenYi 2025-12-19 15:45:19 +08:00
parent 821abb0740
commit e365da3531
2 changed files with 173 additions and 13 deletions

View File

@ -5,15 +5,17 @@ import type { VxeGridProps } from '#/adapter/vxe-table';
import { h, nextTick, onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { Page, useVbenModal, z } from '@vben/common-ui';
import { message as Message, Tag } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
postDeviceThingModelManagementBuildAnalysisScriptByIdAsync,
postDeviceThingModelManagementCreateAsync,
postDeviceThingModelManagementDeleteAsync,
postDeviceThingModelManagementMessageAnalysisTestAsync,
postDeviceThingModelManagementPageAsync,
postDeviceThingModelManagementUpdateAsync,
} from '#/api-client';
@ -234,6 +236,71 @@ const [EditForm, editFormApi] = useVbenForm({
wrapperClass: 'grid-cols-2',
});
//
const [TestScriptModal, testScriptModalApi] = useVbenModal({
draggable: true,
footer: true,
showCancelButton: true,
showConfirmButton: true,
onConfirm: submitTestScript,
onBeforeClose: () => {
return true;
},
onCancel: () => {
testScriptModalApi.close();
},
});
//
const [TestScriptForm, testScriptFormApi] = useVbenForm({
collapsed: false,
commonConfig: {
labelWidth: 110,
componentProps: {
class: 'w-4/5',
},
},
layout: 'horizontal',
schema: [
{
component: 'Input',
fieldName: 'functionName',
label: '函数名称',
rules: z
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
componentProps: {
placeholder: $t('common.pleaseInput') + '函数名称',
},
},
{
component: 'Textarea',
fieldName: 'functionCode',
label: '函数代码',
rules: z
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
componentProps: {
rows: 8,
placeholder: $t('common.pleaseInput') + '函数代码',
},
},
{
component: 'Textarea',
fieldName: 'parameters',
label: '函数参数JSON格式',
componentProps: {
rows: 6,
placeholder: '请输入函数参数JSON格式例如{"key1": "value1", "key2": "value2"}',
},
},
],
showCollapseButton: false,
showDefaultActions: false,
wrapperClass: 'grid-cols-1',
});
//
const testResult = ref<string>('');
// /
async function submit() {
const isEdit = !!editRow.value.id;
@ -311,6 +378,86 @@ const openAddModal = async () => {
thingModelModalApi.open();
};
//
function openTestScriptModal() {
testScriptFormApi.resetForm();
testResult.value = '';
testScriptModalApi.open();
}
//
async function buildAndOpenTestScript(record: any) {
if (!record.id) {
Message.warning('设备端物模型ID不存在');
return;
}
try {
const resp =
await postDeviceThingModelManagementBuildAnalysisScriptByIdAsync({
body: { id: record.id },
});
console.log('函数构建接口返回:', resp.data);
//
//
await testScriptFormApi.setValues({
functionName: resp.data?.functionName || '',
functionCode: resp.data?.functionCode || '',
parameters: '', //
});
testResult.value = ''; //
// 使 nextTick
await nextTick();
testScriptModalApi.open();
Message.success('函数构建成功');
} catch (error) {
console.error('函数构建失败:', error);
Message.error('函数构建失败');
}
}
//
async function submitTestScript() {
const { valid } = await testScriptFormApi.validate();
if (!valid) return;
const formValues = await testScriptFormApi.getValues();
// parameters JSON
let parameters: any = null;
if (formValues.parameters) {
try {
parameters = JSON.parse(formValues.parameters);
} catch (error) {
Message.error('函数参数格式错误请输入有效的JSON格式');
return;
}
}
const fetchParams: any = {
functionName: formValues.functionName,
functionCode: formValues.functionCode,
...(parameters && { parameters }),
};
try {
const resp = await postDeviceThingModelManagementMessageAnalysisTestAsync({
body: fetchParams,
});
// JSON
testResult.value = JSON.stringify(resp.data || {}, null, 2);
Message.success('测试执行成功');
} catch (error) {
console.error('函数脚本测试失败:', error);
testResult.value = `测试失败: ${error instanceof Error ? error.message : String(error)}`;
Message.error('函数脚本测试失败');
}
}
//
async function onDel(record: any) {
try {
@ -377,6 +524,13 @@ onMounted(async () => {
onClick: openAddModal.bind(null),
auth: ['AbpIdentity.Users.Create'],
},
{
label: '函数脚本测试',
type: 'default',
icon: 'ant-design:code-outlined',
onClick: openTestScriptModal,
auth: ['AbpIdentity.Users.Create'],
},
]"
/>
</template>
@ -418,6 +572,14 @@ onMounted(async () => {
auth: ['AbpIdentity.Users.Update'],
onClick: openCommandModal.bind(null, row),
},
{
label: '函数构建',
type: 'link',
size: 'small',
icon: 'ant-design:code-outlined',
auth: ['AbpIdentity.Users.Update'],
onClick: buildAndOpenTestScript.bind(null, row),
},
{
label: $t('common.delete'),
icon: 'ant-design:delete-outlined',
@ -446,6 +608,15 @@ onMounted(async () => {
>
<component :is="editRow.id ? EditForm : AddForm" />
</ThingModelModal>
<!-- 函数脚本测试弹窗 -->
<TestScriptModal title="函数脚本测试" class="w-[900px]">
<TestScriptForm />
<div v-if="testResult" class="mt-4">
<div class="mb-2 font-semibold">测试结果</div>
<pre class="bg-gray-50 p-4 rounded border overflow-auto max-h-96 text-sm">{{ testResult }}</pre>
</div>
</TestScriptModal>
</Page>
</template>

View File

@ -135,17 +135,6 @@ export const tableSchema = computed(() => [
minWidth: 160,
showOverflow: 'tooltip',
},
{
field: 'parsingSequence',
title: '解析顺序',
minWidth: 120,
showOverflow: 'tooltip',
formatter: ({ cellValue }: { cellValue: any }) => {
if (cellValue === 1) return '正序';
if (cellValue === 2) return '高低位反转';
return cellValue ?? '-';
},
},
{
field: 'functionAnalysisFlag',
title: '解析启用',
@ -163,7 +152,7 @@ export const tableSchema = computed(() => [
{
field: 'action',
title: $t('common.action'),
width: 200,
width: 360,
fixed: 'right',
slots: { default: 'action' },
},