实现创建节点功能并测试通过
This commit is contained in:
parent
cb89e9306c
commit
423dda59c3
@ -1,6 +1,7 @@
|
||||
import axios from 'axios'
|
||||
|
||||
import type { AIAgent, AgentExecutionResult } from '../types'
|
||||
import { get_session_api_headers } from './auth'
|
||||
|
||||
// 重新导出类型,供其他模块使用
|
||||
export type { AIAgent, AgentExecutionResult }
|
||||
@ -160,4 +161,24 @@ export const updateAgentApi = async (name: string, data: Partial<AIAgent>): Prom
|
||||
console.error("Error in updateAgentApi:", error)
|
||||
throw new Error(error.response?.data?.message || error.message || '更新AI Agent失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 创建 AI Agent(通用 PageType 接口,使用会话 + 认证头)
|
||||
export const createAgent = async (data: Record<string, any>): Promise<{ success: boolean; data?: any; message?: string }> => {
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${BACKEND_SERVER_URL}/api/data/AI Agent`,
|
||||
data,
|
||||
{
|
||||
headers: get_session_api_headers(),
|
||||
withCredentials: true
|
||||
}
|
||||
)
|
||||
|
||||
const message = response.data?.message
|
||||
return { success: true, data: message || response.data }
|
||||
} catch (error: any) {
|
||||
console.error('Error in createAgent:', error)
|
||||
return { success: false, message: error.response?.data?.message || error.message || '创建AI Agent失败' }
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,18 @@
|
||||
import { LoginRequest, LoginResponse, UserInfo } from './types'
|
||||
// 本文件内自定义认证相关类型,避免外部依赖耦合
|
||||
export interface LoginResponse {
|
||||
message: string
|
||||
user: UserInfo
|
||||
}
|
||||
|
||||
export interface UserInfo {
|
||||
id: string
|
||||
username: string
|
||||
email: string
|
||||
avatar: string
|
||||
first_name: string
|
||||
last_name: string
|
||||
user_type: string
|
||||
}
|
||||
|
||||
// 获取Session用户信息(从Cookie)
|
||||
export function getSessionUser(): string | null {
|
||||
@ -77,3 +91,11 @@ export const logoutApi = async (): Promise<void> => {
|
||||
credentials: 'include'
|
||||
})
|
||||
}
|
||||
|
||||
// 仅使用会话Cookie的最小鉴权头部(不影响现有API Key逻辑)
|
||||
export function get_session_api_headers() {
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
}
|
||||
|
||||
26
frontend/src/shared/api/nodes.ts
Normal file
26
frontend/src/shared/api/nodes.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import axios from 'axios'
|
||||
import { get_session_api_headers } from './auth'
|
||||
|
||||
const BACKEND_SERVER_URL = ''
|
||||
|
||||
// 创建节点(通用 PageType 接口,使用会话 + 认证头)
|
||||
export const createNode = async (data: Record<string, any>): Promise<{ success: boolean; data?: any; message?: string }> => {
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${BACKEND_SERVER_URL}/api/data/AI Node Schema`,
|
||||
data,
|
||||
{
|
||||
headers: get_session_api_headers(),
|
||||
withCredentials: true
|
||||
}
|
||||
)
|
||||
|
||||
const message = response.data?.message
|
||||
return { success: true, data: message || response.data }
|
||||
} catch (error: any) {
|
||||
console.error('Error in createNode:', error)
|
||||
return { success: false, message: error.response?.data?.message || error.message || '创建节点失败' }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,11 +26,11 @@
|
||||
<div class="property-group">
|
||||
<div class="property-item">
|
||||
<label>{{ t('Node Type') }}</label>
|
||||
<input type="text" v-model="nodeRecord.node_type" readonly />
|
||||
<input type="text" v-model="nodeRecord.node_type" />
|
||||
</div>
|
||||
<div class="property-item">
|
||||
<label>{{ t('Node Label') }}</label>
|
||||
<input type="text" v-model="nodeRecord.node_type" />
|
||||
<input type="text" v-model="nodeRecord.node_label" />
|
||||
</div>
|
||||
<div class="property-item">
|
||||
<label>{{ t('Node Icon') }}</label>
|
||||
@ -95,6 +95,7 @@ const route = useRoute()
|
||||
const message = useMessage()
|
||||
|
||||
const nodeName = computed(() => String(route.params.name || ''))
|
||||
const isNew = computed(() => nodeName.value === 'new' || nodeName.value === '')
|
||||
const loading = ref(true)
|
||||
const saving = ref(false)
|
||||
const nodeRecord = ref<any>({})
|
||||
@ -110,7 +111,14 @@ const schemaText = ref('')
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
// 获取节点记录(包含所有字段)
|
||||
if (isNew.value) {
|
||||
// 新建模式:初始化空对象,不请求后端
|
||||
nodeRecord.value = { node_type: '', node_label: '', node_icon: '', node_color: '#6b7280', node_group: '', node_component: '', node_description: '', status: 'Draft' }
|
||||
schema.value = {}
|
||||
schemaText.value = JSON.stringify(schema.value, null, 2)
|
||||
return
|
||||
}
|
||||
// 编辑模式:获取节点记录(包含所有字段)
|
||||
const recordRes = await fetch(`/api/action/jingrow.ai.utils.node_schema.get_node_record?name=${encodeURIComponent(nodeName.value)}`)
|
||||
const recordData = await recordRes.json()
|
||||
nodeRecord.value = recordData.message || recordData.data || {}
|
||||
@ -136,22 +144,51 @@ async function save() {
|
||||
}
|
||||
saving.value = true
|
||||
try {
|
||||
// 准备完整的节点数据
|
||||
const nodeData = {
|
||||
...nodeRecord.value,
|
||||
node_schema: schemaBody
|
||||
if (isNew.value) {
|
||||
// 创建模式:调用通用数据接口创建,成功后跳转到详情
|
||||
const res = await fetch('/api/data/AI Node Schema', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({
|
||||
node_type: nodeRecord.value.node_type,
|
||||
node_label: nodeRecord.value.node_label,
|
||||
node_icon: nodeRecord.value.node_icon,
|
||||
node_color: nodeRecord.value.node_color,
|
||||
node_group: nodeRecord.value.node_group,
|
||||
node_component: nodeRecord.value.node_component,
|
||||
node_description: nodeRecord.value.node_description,
|
||||
status: nodeRecord.value.status || 'Draft',
|
||||
node_schema: schemaBody
|
||||
})
|
||||
})
|
||||
const data = await res.json()
|
||||
const created = data?.message ?? data
|
||||
const newName = created?.name
|
||||
?? created?.data?.name
|
||||
?? created?.message?.name
|
||||
?? created?.document?.name
|
||||
if (newName) {
|
||||
window.location.href = `/nodes/${encodeURIComponent(newName)}`
|
||||
return
|
||||
}
|
||||
// 如果解析不到 name,但请求成功,则给出成功提示并返回列表
|
||||
if (res.ok) {
|
||||
// 退回列表页
|
||||
window.location.href = '/nodes'
|
||||
return
|
||||
}
|
||||
throw new Error('create failed')
|
||||
}
|
||||
|
||||
// 调用更新API
|
||||
// 编辑模式:更新
|
||||
const nodeData = { ...nodeRecord.value, node_schema: schemaBody }
|
||||
const res = await fetch('/api/action/jingrow.ai.utils.node_schema.update_node', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name: nodeName.value, node_data: nodeData })
|
||||
})
|
||||
const data = await res.json()
|
||||
if (data.exc || data._server_messages) {
|
||||
throw new Error('save failed')
|
||||
}
|
||||
if (data.exc || data._server_messages) throw new Error('save failed')
|
||||
await load()
|
||||
} catch (e) {
|
||||
message.error(t('Save failed, please check permission and server logs'))
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
<button class="refresh-btn" @click="reload" :disabled="loading">
|
||||
<i :class="loading ? 'fa fa-spinner fa-spin' : 'fa fa-refresh'"></i>
|
||||
</button>
|
||||
<button class="create-btn" @click="createNode">
|
||||
<button class="create-btn" @click="handleCreateNode" :disabled="creating || loading">
|
||||
<i class="fa fa-plus"></i>
|
||||
{{ t('Create Node') }}
|
||||
</button>
|
||||
@ -125,9 +125,11 @@ import { ref, onMounted, computed, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { t } from '../../shared/i18n'
|
||||
import { NInput, NSelect, NPagination } from 'naive-ui'
|
||||
import { createNode } from '../../shared/api/nodes'
|
||||
|
||||
const router = useRouter()
|
||||
const loading = ref(true)
|
||||
const creating = ref(false)
|
||||
const nodes = ref<any[]>([])
|
||||
const allNodes = ref<any[]>([]) // 保存所有原始数据
|
||||
const total = ref(0)
|
||||
@ -246,8 +248,9 @@ function openDetail(name: string) {
|
||||
router.push({ name: 'NodeDetail', params: { name } })
|
||||
}
|
||||
|
||||
function createNode() {
|
||||
router.push({ name: 'NodeCreate' })
|
||||
function handleCreateNode() {
|
||||
// 仅跳转到新建模式,由详情页保存时再创建后端记录
|
||||
router.push({ name: 'NodeDetail', params: { name: 'new' } })
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user