Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions ui/src/api/admin/workspace/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,18 @@ const putApplication = (applicationId: string, data: ApplicationFormPayload) =>
return put<ApplicationFormPayload, ApplicationDetail>(`${getPrefix()}/${applicationId}`, data)
}

/** 发布工作空间智能体。 */
const putApplicationPublish = (applicationId: string) => {
return put<Record<string, never>, ApplicationDetail>(
`${getPrefix()}/${applicationId}/publish`,
{},
)
}

export default {
getApplicationPage,
getApplicationDetail,
postApplicationImport,
putApplication,
putApplicationPublish,
}
Binary file added ui/src/assets/login-animation/1bottom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/login-animation/2circle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/login-animation/3line.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/login-animation/4robot.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/login-animation/5panel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
50 changes: 50 additions & 0 deletions ui/src/components/COMPONENT_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ src/components/
├── mk-date-range/
│ ├── index.vue # 日期预设与自定义日期区间组合筛选器,手动导入
│ └── types.ts # 日期筛选结果类型
├── mk-dynamics-form/
│ ├── index.ts # 动态表单、表单配置器及组件内类型的公开入口
│ ├── index.vue # 根据字段配置渲染和校验动态表单
│ ├── type.ts # 组件内部及调用方共享的字段配置类型
│ ├── enums.ts # 字段类型和显隐比较选项
│ ├── FormItem.vue # 字段组件调度层,仅供组件内部使用
│ ├── items/ # 运行时字段实现,仅供组件内部使用
│ └── constructor/ # 字段配置器、变量选择器及配置项实现
├── mk-search-list/
│ └── index.vue # 搜索框与剩余空间滚动列表,手动导入
├── mk-form-list/
Expand All @@ -108,6 +116,7 @@ Vue 模板中使用,不需要手动导入。其他共享组件必须从具体
import MkSearchList from '@/components/mk-search-list/index.vue'
import MkFormList from '@/components/mk-form-list/index.vue'
import MkDateRange from '@/components/mk-date-range/index.vue'
import { MkDynamicsForm, MkDynamicsFormConstructor } from '@/components/mk-dynamics-form'
import LogoFull from '@/components/mk-logo/LogoFull.vue'
import LogoIcon from '@/components/mk-logo/LogoIcon.vue'
import PythonCodeEditor from '@/components/codemirror-editor/python.vue'
Expand Down Expand Up @@ -811,6 +820,47 @@ function selectItem(item: SearchListItem, index: number) {
`props` 中未传的字段保留默认值,例如只传
`:props="{ label: 'title' }"` 时,唯一值字段仍为 `id`。

### MkDynamicsForm、MkDynamicsFormConstructor

`MkDynamicsForm` 根据字段配置渲染动态表单,统一维护字段值、默认值、显隐规则和表单校验;
`MkDynamicsFormConstructor` 用于新增或编辑单个字段配置。该组件族位于 `components` 直属目录,
使用方必须从 `@/components/mk-dynamics-form` 手动导入,不安装为 Vue 插件,也不全局注册其内部
字段组件。

组件专用类型和选项常量维护在 `mk-dynamics-form/type.ts` 与 `mk-dynamics-form/enums.ts`,不放入
项目级 `api/types`、`api/enums` 或 `constants`。使用方统一从组件 `index.ts` 获取公开组件、类型
和字段类型选项,不深层导入内部文件。

```vue
<script setup lang="ts">
import { ref } from 'vue'
import {
MkDynamicsForm,
type DynamicFormRecord,
type FormField,
} from '@/components/mk-dynamics-form'

const formFields = ref<FormField[]>([])
const formValue = ref<DynamicFormRecord>({})
</script>

<template>
<MkDynamicsForm v-model="formValue" :render-data="formFields" />
</template>
```

公开入口包含 `MkDynamicsForm`、`MkDynamicsFormConstructor`、`dynamicFormTypeOptions`、
`visibilityCompareOptions` 和组件专用类型。`FormItem.vue`、`items/`、`constructor/items/` 与
`constructor/visibility/` 均为内部实现,业务代码不应深层导入。

`MkDynamicsForm` 的主要 Props 为 `modelValue`、`renderData`、`otherParams`、`view`、
`defaultItemWidth` 和 `parentField`,公开 `validate()`、`render()`、`initDefaultData()` 与
`ruleFormRef`。`MkDynamicsFormConstructor` 接收 `modelValue`、`fieldTypeOptions`、
`enableVisibility` 和 `leftOptions`,公开 `validate()`、`getData()` 与 `render()`。

字段配置中的动态校验器和表格行表达式属于受信任的服务端协议,只允许加载可信配置;普通业务
输入不得作为脚本传入。

## 跨页面业务组件

业务组件可以调用其固定业务 API,但应将通用展示部分拆成内部纯 UI 组件;页面继续负责资源列表
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<template>
<el-form-item label="时间类型" required>
<el-select
@change="type_change"
v-model="formValue.type"
placeholder="请选择时间类型"
>
<el-option
v-for="input_type in type_list"
:key="input_type.value"
:label="input_type.label"
:value="input_type.value"
/>
</el-select>
</el-form-item>
<el-form-item label="格式" required>
<el-select
v-model="formValue.format"
filterable
default-first-option
allow-create
placeholder="请选择格式"
>
<el-option
v-for="input_type in type_dict[formValue.type]"
:key="input_type.value"
:label="input_type.value"
:value="input_type.value"
/>
</el-select>
</el-form-item>
<el-form-item
class="defaultValueItem"
:required="formValue.required"
prop="default_value"
label="默认值"
:rules="
formValue.required
? [
{
required: true,
message: '默认值为必填属性',
},
]
: []
"
>
<div class="defaultValueCheckbox">
<el-checkbox
v-model="formValue.show_default_value"
label="显示默认值"
/>
</div>
<el-date-picker
v-model="formValue.default_value"
:type="formValue.type"
placeholder="选择日期"
:format="formValue.format"
:value-format="formValue.format"
/>
</el-form-item>
</template>
<script setup lang="ts">
import { computed, onBeforeMount } from 'vue'
const type_list = [
{
label: '年',
value: 'year',
},
{
label: '月',
value: 'month',
},
{
label: '日期',
value: 'date',
},
{
label: '日期时间',
value: 'datetime',
},
]
const type_dict: any = {
year: [{ value: 'YYYY' }],
month: [{ value: 'YYYY-MM' }],
date: [{ value: 'YYYY-MM-DD' }],
datetime: [{ value: 'YYYY-MM-DD HH:mm:ss' }],
}

const type_change = () => {
formValue.value.format = type_dict[formValue.value.type][0].value
formValue.value.default_value = moment().format(formValue.value.format)
}
const props = defineProps<{
modelValue: any
}>()
const emit = defineEmits(['update:modelValue'])
const formValue = computed({
set: (item) => {
emit('update:modelValue', item)
},
get: () => {
return props.modelValue
},
})

const getData = () => {
return {
input_type: 'DatePicker',
attrs: {
type: formValue.value.type,
format: formValue.value.format,
'value-format': formValue.value.format,
},
default_value: formValue.value.default_value,
show_default_value: formValue.value.show_default_value,
}
}
const rander = (form_data: any) => {
formValue.value.type = form_data.attrs.type
formValue.value.format = form_data.attrs?.format
formValue.value.default_value = form_data.default_value
}
defineExpose({ getData, rander })
onBeforeMount(() => {
formValue.value.type = 'datetime'
formValue.value.format = 'YYYY-MM-DD HH:mm:ss'
formValue.value.default_value = moment().format(formValue.value.format)
if (formValue.value.show_default_value === undefined) {
formValue.value.show_default_value = true
}
})
</script>
<style lang="scss" scoped>
.defaultValueItem {
position: relative;
.defaultValueCheckbox {
position: absolute;
right: 0;
top: -35px;
}
}
</style>
Loading
Loading