2 Commits

Author SHA1 Message Date
v-zhangjc9
64ef5514b4 feat(ai-web): 完成执行任务的创建 2025-07-04 19:31:24 +08:00
v-zhangjc9
4f1dc84405 feat(web): 调整侧边栏实现 2025-07-04 10:54:45 +08:00
6 changed files with 105 additions and 24 deletions

View File

@@ -2,19 +2,22 @@ package com.lanyuanxiaoyao.service.ai.web.controller.task;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisResponse;
import com.lanyuanxiaoyao.service.ai.web.base.controller.SimpleControllerSupport;
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleItem;
import com.lanyuanxiaoyao.service.ai.web.entity.FlowTask;
import com.lanyuanxiaoyao.service.ai.web.entity.FlowTaskTemplate;
import com.lanyuanxiaoyao.service.ai.web.service.task.FlowTaskService;
import com.lanyuanxiaoyao.service.ai.web.service.task.FlowTaskTemplateService;
import java.util.Map;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.mapstruct.Context;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -22,15 +25,23 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("flow_task")
public class TaskController extends SimpleControllerSupport<FlowTask, TaskController.SaveItem, TaskController.ListItem, TaskController.DetailItem> {
private final FlowTaskService flowTaskService;
private final FlowTaskTemplateService flowTaskTemplateService;
private final ObjectMapper mapper;
public TaskController(FlowTaskService flowTaskService, FlowTaskTemplateService flowTaskTemplateService, Jackson2ObjectMapperBuilder builder) {
super(flowTaskService);
this.flowTaskService = flowTaskService;
this.flowTaskTemplateService = flowTaskTemplateService;
this.mapper = builder.build();
}
@GetMapping("input_data/{id}")
public AmisResponse<?> getInputSchema(@PathVariable("id") Long id) throws JsonProcessingException {
var task = flowTaskService.detailOrThrow(id);
return AmisResponse.responseSuccess(mapper.readValue(task.getInput(), Map.class));
}
@Override
protected SaveItemMapper<FlowTask, SaveItem> saveItemMapper() {
return item -> {
@@ -45,13 +56,13 @@ public class TaskController extends SimpleControllerSupport<FlowTask, TaskContro
@Override
protected ListItemMapper<FlowTask, ListItem> listItemMapper() {
ListItem.Mapper map = Mappers.getMapper(ListItem.Mapper.class);
return task -> map.from(task, mapper);
return map::from;
}
@Override
protected DetailItemMapper<FlowTask, DetailItem> detailItemMapper() {
DetailItem.Mapper map = Mappers.getMapper(DetailItem.Mapper.class);
return task -> map.from(task, mapper);
return map::from;
}
@Data
@@ -64,17 +75,14 @@ public class TaskController extends SimpleControllerSupport<FlowTask, TaskContro
@EqualsAndHashCode(callSuper = true)
public static class ListItem extends SimpleItem {
private Long templateId;
private Object input;
private String templateName;
private FlowTask.Status status;
@org.mapstruct.Mapper
public static abstract class Mapper {
@Mapping(target = "templateId", source = "task.template.id")
public abstract ListItem from(FlowTask task, @Context ObjectMapper mapper) throws JsonProcessingException;
protected Object mapInput(String input, @Context ObjectMapper mapper) throws JsonProcessingException {
return mapper.readValue(input, Object.class);
}
@Mapping(target = "templateName", source = "task.template.name")
public abstract ListItem from(FlowTask task);
}
}
@@ -87,7 +95,8 @@ public class TaskController extends SimpleControllerSupport<FlowTask, TaskContro
@org.mapstruct.Mapper
public static abstract class Mapper extends ListItem.Mapper {
@Mapping(target = "templateId", source = "task.template.id")
public abstract DetailItem from(FlowTask task, @Context ObjectMapper mapper) throws JsonProcessingException;
@Mapping(target = "templateName", source = "task.template.name")
public abstract DetailItem from(FlowTask task);
}
}
}

View File

@@ -15,6 +15,8 @@ import lombok.extern.slf4j.Slf4j;
import org.mapstruct.Context;
import org.mapstruct.factory.Mappers;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -33,6 +35,12 @@ public class TaskTemplateController extends SimpleControllerSupport<FlowTaskTemp
this.mapper = builder.build();
}
@GetMapping("input_schema/{id}")
public AmisResponse<?> getInputSchema(@PathVariable("id") Long id) throws JsonProcessingException {
var template = flowTaskTemplateService.detailOrThrow(id);
return AmisResponse.responseSuccess(mapper.readValue(template.getInputSchema(), Map.class));
}
@PostMapping("update_flow_graph")
public AmisResponse<?> updateFlowGraph(@RequestBody UpdateGraphItem item) throws JsonProcessingException {
flowTaskTemplateService.updateFlowGraph(item.getId(), mapper.writeValueAsString(item.getGraph()));
@@ -41,7 +49,7 @@ public class TaskTemplateController extends SimpleControllerSupport<FlowTaskTemp
@Override
protected SaveItemMapper<FlowTaskTemplate, SaveItem> saveItemMapper() {
SaveItem.Mapper map = Mappers.getMapper(SaveItem.Mapper.class);
var map = Mappers.getMapper(SaveItem.Mapper.class);
return item -> map.from(item, mapper);
}
@@ -52,7 +60,7 @@ public class TaskTemplateController extends SimpleControllerSupport<FlowTaskTemp
@Override
protected DetailItemMapper<FlowTaskTemplate, DetailItem> detailItemMapper() {
DetailItem.Mapper map = Mappers.getMapper(DetailItem.Mapper.class);
var map = Mappers.getMapper(DetailItem.Mapper.class);
return template -> map.from(template, mapper);
}

View File

@@ -16,7 +16,7 @@ public class FlowTaskTemplateService extends SimpleServiceSupport<FlowTaskTempla
@Transactional(rollbackFor = Exception.class)
public void updateFlowGraph(Long id, String flowGraph) {
FlowTaskTemplate template = detailOrThrow(id);
var template = detailOrThrow(id);
template.setFlowGraph(flowGraph);
save(template);
}

View File

@@ -1,7 +1,7 @@
import {type AppItemProps, ProLayout} from '@ant-design/pro-components'
import {ConfigProvider} from 'antd'
import {dateFormat} from 'licia'
import React, {useMemo} from 'react'
import React, {useMemo, useState} from 'react'
import {Outlet, useLocation, useNavigate} from 'react-router'
import styled from 'styled-components'
import {menus} from '../route.tsx'
@@ -14,7 +14,7 @@ const ProLayoutDiv = styled.div`
margin: 0;
.ant-menu-sub > .ant-menu-item {
padding-left: 16px !important;
//padding-left: 28px !important;
}
`
@@ -52,10 +52,13 @@ const apps: AppItemProps[] = [
const App: React.FC = () => {
const navigate = useNavigate()
const location = useLocation()
const [collapsed, setCollapsed] = useState<boolean>(false)
const currentYear = useMemo(() => dateFormat(new Date(), 'yyyy'), [])
return (
<ProLayoutDiv>
<ProLayout
collapsed={collapsed}
onCollapse={setCollapsed}
siderWidth={180}
token={{
colorTextAppListIcon: '#dfdfdf',
@@ -78,7 +81,6 @@ const App: React.FC = () => {
},
}}
appList={apps}
defaultCollapsed={false}
breakpoint={false}
disableMobile={true}
logo={<img src="icon.png" alt="logo"/>}
@@ -86,11 +88,12 @@ const App: React.FC = () => {
route={menus}
location={{pathname: location.pathname}}
menu={{type: 'sub'}}
menuItemRender={(item) => {
menuItemRender={(item, defaultDom) => {
return (
<div onClick={() => navigate(item.path || '/')}>
{item.icon}
<span className="ml-2">{item.name}</span>
{/*<span className="align-center">{item.icon}</span>*/}
{/*<span className="ml-2">{item.name}</span>*/}
{defaultDom}
</div>
)
}}

View File

@@ -1,9 +1,9 @@
import {isEmpty, isEqual} from 'licia'
import React from 'react'
import {useParams} from 'react-router'
import styled from 'styled-components'
import {amisRender, commonInfo, horizontalFormOptions} from '../../../../util/amis.tsx'
import {generateInputForm, typeMap} from '../InputSchema.tsx'
import { useParams } from 'react-router'
const TemplateEditDiv = styled.div`
.antd-EditorControl {
@@ -54,7 +54,7 @@ const FlowTaskTemplateEdit: React.FC = () => {
actionType: 'setValue',
args: {
value: {
inputPreview: generateInputForm(inputSchema),
inputPreview: generateInputForm(inputSchema, '入参表单预览'),
},
},
})
@@ -75,6 +75,8 @@ const FlowTaskTemplateEdit: React.FC = () => {
label: '名称',
required: true,
clearable: true,
maxLength: 10,
showCounter: true,
},
{
type: 'textarea',
@@ -82,6 +84,8 @@ const FlowTaskTemplateEdit: React.FC = () => {
label: '描述',
required: true,
clearable: true,
maxLength: 500,
showCounter: true,
},
{
type: 'group',

View File

@@ -10,8 +10,8 @@ import {isEqual} from 'licia'
export const commonInfo = {
debug: isEqual(import.meta.env.MODE, 'development'),
baseUrl: 'http://132.126.207.130:35690/hudi_services/service_web',
// baseAiUrl: 'http://132.126.207.130:35690/hudi_services/service_ai_web',
baseAiUrl: 'http://localhost:8080',
baseAiUrl: 'http://132.126.207.130:35690/hudi_services/service_ai_web',
// baseAiUrl: 'http://localhost:8080',
authorizationHeaders: {
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
'Content-Type': 'application/json',
@@ -278,7 +278,7 @@ export function horizontalFormOptions() {
return {
mode: 'horizontal',
horizontal: {
leftFixed: 'sm'
leftFixed: 'sm',
},
}
}
@@ -2517,4 +2517,61 @@ export function time(field: string) {
export function pictureFromIds(field: string) {
return `\${ARRAYMAP(${field},id => '${commonInfo.baseAiUrl}/upload/download/' + id)}`
}
const formInputFileStaticColumns = [
{
name: 'filename',
label: '文件名',
},
{
type: 'operation',
label: '操作',
width: 140,
buttons: [
{
type: 'action',
label: '预览',
level: 'link',
icon: 'fas fa-eye'
},
{
type: 'action',
label: '下载',
level: 'link',
icon: 'fa fa-download',
actionType: 'ajax',
// api: {
// ...apiGet('${base}/upload/download/${id}'),
// responseType: 'blob',
// }
}
]
}
]
export function formInputSingleFileStatic(field: string, label: string) {
return {
visibleOn: '${static}',
type: 'control',
label: label,
required: true,
body: {
type: 'table',
source: `\${${field}|asArray}`,
columns: formInputFileStaticColumns,
},
}
}
export function formInputMultiFileStatic(field: string, label: string) {
return {
visibleOn: '${static}',
type: 'input-table',
label: label,
name: field,
required: true,
resizable: false,
columns: formInputFileStaticColumns,
}
}