Build lightweight AI agent admin

This commit is contained in:
Codex
2026-06-08 18:14:59 +08:00
commit e164840f43
2530 changed files with 435693 additions and 0 deletions
@@ -0,0 +1,2 @@
export { default as LinkedField } from './linked-field.vue';
export * from './types';
@@ -0,0 +1,104 @@
<script lang="ts" setup>
import type { LinkedFieldEmits, LinkedFieldProps } from './types';
import { computed, watch } from 'vue';
import { $t } from '@vben/locales';
import { ElInput } from 'element-plus';
defineOptions({
name: 'LinkedField',
});
const props = withDefaults(defineProps<LinkedFieldProps>(), {
placeholder: '',
disabled: true,
});
const emit = defineEmits<LinkedFieldEmits>();
// 计算显示值
const displayValue = computed(() => {
if (!props.sourceField || !props.displayField || !props.formData) {
return '';
}
// 获取源字段的值(可能是选中项的完整对象或者ID)
const sourceValue = props.formData[props.sourceField];
if (!sourceValue) {
return '';
}
// 如果源字段值是对象,直接从中取 displayField
if (typeof sourceValue === 'object' && sourceValue !== null) {
return sourceValue[props.displayField] ?? '';
}
// 如果源字段值是数组(多选),取第一个的 displayField
if (Array.isArray(sourceValue) && sourceValue.length > 0) {
const firstItem = sourceValue[0];
if (typeof firstItem === 'object' && firstItem !== null) {
return firstItem[props.displayField] ?? '';
}
}
// 如果有 _selectedItem 存储的完整对象
const selectedItemKey = `${props.sourceField}_selectedItem`;
const selectedItem = props.formData[selectedItemKey];
if (selectedItem && typeof selectedItem === 'object') {
return selectedItem[props.displayField] ?? '';
}
// 如果有 _selectedItems 存储的完整对象数组
const selectedItemsKey = `${props.sourceField}_selectedItems`;
const selectedItems = props.formData[selectedItemsKey];
if (Array.isArray(selectedItems) && selectedItems.length > 0) {
const firstItem = selectedItems[0];
if (typeof firstItem === 'object' && firstItem !== null) {
return firstItem[props.displayField] ?? '';
}
}
return '';
});
// 监听显示值变化,更新 modelValue
// 注意:当 displayValue 为空但已有保存的 modelValue 时(如编辑回显场景),不覆盖
watch(
displayValue,
(newVal) => {
if (newVal !== props.modelValue) {
if (newVal) {
emit('update:modelValue', newVal);
emit('change', newVal);
} else if (!props.modelValue) {
emit('update:modelValue', undefined);
emit('change', undefined);
}
}
},
{ immediate: true },
);
</script>
<template>
<div class="linked-field-wrapper">
<ElInput
:model-value="displayValue || props.modelValue"
:placeholder="
placeholder || $t('form-design.attribute.linkedFieldPlaceholder')
"
:disabled="true"
readonly
class="linked-field"
/>
</div>
</template>
<style scoped>
.linked-field :deep(.el-input__inner) {
cursor: default;
}
</style>
@@ -0,0 +1,18 @@
export interface LinkedFieldProps {
modelValue?: number | string;
// 源字段(选择组件的字段名)
sourceField?: string;
// 要显示的字段名(从选中项中取哪个字段的值)
displayField?: string;
// 表单数据
formData?: Record<string, any>;
// 占位符
placeholder?: string;
// 是否禁用
disabled?: boolean;
}
export interface LinkedFieldEmits {
(e: 'update:modelValue', value: number | string | undefined): void;
(e: 'change', value: number | string | undefined): void;
}