params) {
+ var stocks = stockService.list();
+ var stocksMap = stocks.stream().collect(Collectors.toMap(Stock::getCode, stock -> stock));
+ tuShareService.stockList()
+ .data()
+ .items()
+ .forEach(item -> {
+ var code = item.get(0);
+ var name = item.get(1);
+ var fullname = item.get(2);
+ var market = EnumUtil.fromString(Stock.Market.class, item.get(3));
+ var industry = item.get(4);
+ var listed = StrUtil.equals("L", item.get(5));
+ if (stocksMap.containsKey(code)) {
+ var stock = stocksMap.get(code);
+ stock.setName(name);
+ stock.setFullname(fullname);
+ stock.setMarket(market);
+ stock.setIndustry(industry);
+ stock.setListed(listed);
+ } else {
+ var stock = new Stock();
+ stock.setCode(code);
+ stock.setName(name);
+ stock.setFullname(fullname);
+ stock.setMarket(market);
+ stock.setIndustry(industry);
+ stock.setListed(listed);
+ stocks.add(stock);
+ }
+ });
+ stockService.save(stocks);
+ return null;
+ }
+}
diff --git a/leopard-web/src/index.tsx b/leopard-web/src/index.tsx
index 8af70b3..d09fd21 100644
--- a/leopard-web/src/index.tsx
+++ b/leopard-web/src/index.tsx
@@ -2,13 +2,15 @@ import {createRoot} from 'react-dom/client'
import {createHashRouter, Navigate, type RouteObject, RouterProvider} from 'react-router'
import './index.scss'
import './components/amis/Registry.ts'
-import Overview from "./pages/Overview.tsx";
-import Root from "./pages/Root.tsx";
-import Test from "./pages/Test.tsx";
-import StockList from "./pages/stock/StockList.tsx";
-import StockDetail from './pages/stock/StockDetail.tsx';
-import TaskList from "./pages/task/TaskList.tsx";
-import TaskAdd from './pages/task/TaskAdd.tsx';
+import Overview from './pages/Overview.tsx'
+import Root from './pages/Root.tsx'
+import Test from './pages/Test.tsx'
+import StockList from './pages/stock/StockList.tsx'
+import StockDetail from './pages/stock/StockDetail.tsx'
+import TaskList from './pages/task/TaskList.tsx'
+import TaskAdd from './pages/task/TaskAdd.tsx'
+import TaskTemplateList from './pages/task/TaskTemplateList.tsx'
+import TaskTemplateSave from './pages/task/TaskTemplateSave.tsx'
const routes: RouteObject[] = [
{
@@ -37,16 +39,12 @@ const routes: RouteObject[] = [
{
path: 'detail/:id',
Component: StockDetail,
- }
- ]
+ },
+ ],
},
{
path: 'task',
children: [
- {
- index: true,
- element: ,
- },
{
path: 'list',
Component: TaskList,
@@ -55,12 +53,25 @@ const routes: RouteObject[] = [
path: 'add',
Component: TaskAdd,
},
- ]
+ {
+ path: 'template',
+ children: [
+ {
+ path: 'list',
+ Component: TaskTemplateList,
+ },
+ {
+ path: 'save/:id',
+ Component: TaskTemplateSave,
+ },
+ ],
+ },
+ ],
},
{
path: 'test',
Component: Test,
- }
+ },
],
},
]
diff --git a/leopard-web/src/pages/Root.tsx b/leopard-web/src/pages/Root.tsx
index 6cd295f..0ae20d8 100644
--- a/leopard-web/src/pages/Root.tsx
+++ b/leopard-web/src/pages/Root.tsx
@@ -44,6 +44,16 @@ const menus = {
path: '/task',
name: '任务',
icon: ,
+ routes: [
+ {
+ path: '/task/list',
+ name: '任务列表',
+ },
+ {
+ path: '/task/template/list',
+ name: '任务模板',
+ }
+ ]
},
{
path: '/test',
diff --git a/leopard-web/src/pages/task/TaskTemplateList.tsx b/leopard-web/src/pages/task/TaskTemplateList.tsx
new file mode 100644
index 0000000..93f04de
--- /dev/null
+++ b/leopard-web/src/pages/task/TaskTemplateList.tsx
@@ -0,0 +1,113 @@
+import React from 'react'
+import {amisRender, commonInfo, crudCommonOptions, paginationTemplate, remoteMappings} from '../../util/amis.tsx'
+import {useNavigate} from 'react-router'
+
+function TaskTemplateList() {
+ const navigate = useNavigate()
+ return (
+
+ {amisRender(
+ {
+ type: 'page',
+ title: '任务模板',
+ body: [
+ {
+ type: 'crud',
+ api: {
+ method: 'post',
+ url: `${commonInfo.baseUrl}/task_template/list`,
+ data: {
+ page: {
+ index: '${page}',
+ size: '${perPage}',
+ },
+ },
+ },
+ ...crudCommonOptions(),
+ ...paginationTemplate(
+ 15,
+ undefined,
+ [
+ {
+ type: 'action',
+ label: '',
+ icon: 'fa fa-plus',
+ tooltip: '添加模板',
+ tooltipPlacement: 'top',
+ onEvent: {
+ click: {
+ actions: [
+ {
+ actionType: 'custom',
+ // @ts-ignore
+ script: (context, action, event) => {
+ navigate('/task/template/save/-1')
+ },
+ },
+ ],
+ },
+ },
+ },
+ ],
+ ),
+ columns: [
+ {
+ name: 'name',
+ label: '名称',
+ width: 150,
+ },
+ {
+ name: 'description',
+ label: '描述',
+ },
+ {
+ name: 'type',
+ label: '类型',
+ width: 100,
+ ...remoteMappings('task_template_type', 'type'),
+ },
+ {
+ type: 'operation',
+ label: '操作',
+ width: 100,
+ buttons: [
+ {
+ type: 'action',
+ label: '详情',
+ level: 'link',
+ onEvent: {
+ click: {
+ actions: [
+ {
+ actionType: 'custom',
+ // @ts-ignore
+ script: (context, action, event) => {
+ navigate(`/task/template/save/${context.props.data['id']}`)
+ },
+ },
+ ],
+ },
+ },
+ },
+ {
+ className: 'text-danger',
+ type: 'action',
+ label: '删除',
+ level: 'link',
+ actionType: 'ajax',
+ api: `get:${commonInfo.baseUrl}/task_template/remove/\${id}`,
+ confirmText: '确认删除模板[${name}]?',
+ confirmTitle: "删除",
+ }
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ )}
+
+ )
+}
+
+export default React.memo(TaskTemplateList)
\ No newline at end of file
diff --git a/leopard-web/src/pages/task/TaskTemplateSave.tsx b/leopard-web/src/pages/task/TaskTemplateSave.tsx
new file mode 100644
index 0000000..ee51af5
--- /dev/null
+++ b/leopard-web/src/pages/task/TaskTemplateSave.tsx
@@ -0,0 +1,96 @@
+import React from 'react'
+import {amisRender, commonInfo, remoteOptions} from '../../util/amis.tsx'
+import {useNavigate, useParams} from 'react-router'
+
+function TaskTemplateSave() {
+ const navigate = useNavigate()
+ const {id} = useParams()
+ return (
+
+ {amisRender(
+ {
+ type: 'page',
+ title: '任务模板添加',
+ body: [
+ {
+ debug: commonInfo.debug,
+ type: 'form',
+ api: `post:${commonInfo.baseUrl}/task_template/save`,
+ initApi: `get:${commonInfo.baseUrl}/task_template/detail/${id}`,
+ initFetchOn: `${id} !== -1`,
+ wrapWithPanel: false,
+ mode: 'horizontal',
+ labelAlign: 'left',
+ onEvent: {
+ submitSucc: {
+ actions: [
+ {
+ actionType: 'custom',
+ // @ts-ignore
+ script: (context, action, event) => {
+ navigate(-1)
+ },
+ },
+ ]
+ }
+ },
+ body: [
+ {
+ type: 'hidden',
+ name: 'id',
+ },
+ {
+ type: 'input-text',
+ name: 'name',
+ label: '名称',
+ require: true,
+ clearable: true,
+ },
+ {
+ type: 'textarea',
+ name: 'description',
+ label: '描述',
+ require: true,
+ clearable: true,
+ },
+ {
+ name: 'type',
+ label: '任务类型',
+ require: true,
+ selectFirst: true,
+ ...remoteOptions('select', 'task_template_type'),
+ },
+ {
+ visibleOn: 'type === \'CLASS\'',
+ type: 'input-text',
+ name: 'clazz',
+ label: '类路径',
+ require: true,
+ clearable: true,
+ },
+ {
+ type: 'button-toolbar',
+ buttons: [
+ {
+ type: 'action',
+ label: '提交',
+ actionType: 'submit',
+ level: 'primary',
+ },
+ {
+ type: 'action',
+ label: '重置',
+ actionType: 'reset',
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ )}
+
+ )
+}
+
+export default React.memo(TaskTemplateSave)
\ No newline at end of file