feat(all): 初始化版本
This commit is contained in:
9
leopard-web/src/pages/Overview.tsx
Normal file
9
leopard-web/src/pages/Overview.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import React from "react";
|
||||
|
||||
function Overview() {
|
||||
return (
|
||||
<div className="overview"></div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(Overview)
|
||||
130
leopard-web/src/pages/Root.tsx
Normal file
130
leopard-web/src/pages/Root.tsx
Normal file
@@ -0,0 +1,130 @@
|
||||
import {
|
||||
DeploymentUnitOutlined,
|
||||
InfoCircleOutlined,
|
||||
MoneyCollectOutlined,
|
||||
UnorderedListOutlined
|
||||
} from "@ant-design/icons";
|
||||
import {type AppItemProps, ProLayout} from '@ant-design/pro-components'
|
||||
import {ConfigProvider} from 'antd'
|
||||
import {dateFormat} from 'licia'
|
||||
import React, {useMemo} from 'react'
|
||||
import {NavLink, Outlet, useLocation} from 'react-router'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const ProLayoutDiv = styled.div`
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
.ant-menu-sub > .ant-menu-item {
|
||||
//padding-left: 28px !important;
|
||||
}
|
||||
`
|
||||
const apps: AppItemProps[] = []
|
||||
|
||||
const menus = {
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: '概览',
|
||||
icon: <InfoCircleOutlined/>,
|
||||
routes: [
|
||||
{
|
||||
path: '/overview',
|
||||
name: '概览',
|
||||
icon: <InfoCircleOutlined/>,
|
||||
},
|
||||
{
|
||||
path: '/stock',
|
||||
name: '股票',
|
||||
icon: <MoneyCollectOutlined/>,
|
||||
}, {
|
||||
path: '/task',
|
||||
name: '任务',
|
||||
icon: <UnorderedListOutlined/>,
|
||||
},
|
||||
{
|
||||
path: '/test',
|
||||
name: '测试',
|
||||
icon: <DeploymentUnitOutlined/>,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const Root: React.FC = () => {
|
||||
const location = useLocation()
|
||||
const currentYear = useMemo(() => dateFormat(new Date(), 'yyyy'), [])
|
||||
return (
|
||||
<ProLayoutDiv>
|
||||
<ProLayout
|
||||
collapsed={false}
|
||||
collapsedButtonRender={() => <></>}
|
||||
siderWidth={180}
|
||||
token={{
|
||||
colorTextAppListIcon: '#dfdfdf',
|
||||
colorTextAppListIconHover: '#ffffff',
|
||||
header: {
|
||||
colorBgHeader: '#292f33',
|
||||
colorHeaderTitle: '#ffffff',
|
||||
colorTextMenu: '#dfdfdf',
|
||||
colorTextMenuSecondary: '#dfdfdf',
|
||||
colorTextMenuSelected: '#ffffff',
|
||||
colorTextMenuActive: '#ffffff',
|
||||
colorBgMenuItemSelected: '#22272b',
|
||||
colorTextRightActionsItem: '#dfdfdf',
|
||||
},
|
||||
pageContainer: {
|
||||
paddingBlockPageContainerContent: 0,
|
||||
paddingInlinePageContainerContent: 0,
|
||||
marginBlockPageContainerContent: 0,
|
||||
marginInlinePageContainerContent: 0,
|
||||
},
|
||||
}}
|
||||
appList={apps}
|
||||
breakpoint={false}
|
||||
disableMobile={true}
|
||||
logo={<img src="icon.png" alt="logo"/>}
|
||||
title="金钱豹"
|
||||
route={menus}
|
||||
location={{pathname: location.pathname}}
|
||||
menu={{type: 'sub'}}
|
||||
menuItemRender={(item, defaultDom) =>
|
||||
<NavLink to={item.path || '/'}>{defaultDom}</NavLink>
|
||||
}
|
||||
fixSiderbar={true}
|
||||
layout="side"
|
||||
splitMenus={true}
|
||||
style={{minHeight: '100vh'}}
|
||||
contentStyle={{backgroundColor: 'white', padding: '10px 10px 10px 20px'}}
|
||||
menuFooterRender={props => {
|
||||
return (
|
||||
<div className="text-xs text-center" style={{userSelect: 'none', msUserSelect: 'none'}}>
|
||||
{props?.collapsed
|
||||
? undefined
|
||||
: <div>© 2023-{currentYear} 兰缘小妖</div>}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
components: {
|
||||
Card: {
|
||||
bodyPadding: 0,
|
||||
bodyPaddingSM: 0,
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Outlet/>
|
||||
</ConfigProvider>
|
||||
</ProLayout>
|
||||
</ProLayoutDiv>
|
||||
)
|
||||
}
|
||||
|
||||
export default Root
|
||||
10
leopard-web/src/pages/Test.tsx
Normal file
10
leopard-web/src/pages/Test.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from "react";
|
||||
|
||||
function Test() {
|
||||
return (
|
||||
<div className="test">
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(Test)
|
||||
39
leopard-web/src/pages/stock/StockDetail.tsx
Normal file
39
leopard-web/src/pages/stock/StockDetail.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import React from 'react'
|
||||
import {useParams} from 'react-router'
|
||||
import {amisRender, commonInfo, remoteMappings} from '../../util/amis.tsx'
|
||||
|
||||
function StockDetail() {
|
||||
const {id} = useParams()
|
||||
return (
|
||||
<div className="stock-detail">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'page',
|
||||
title: '股票详情(${code} ${name})',
|
||||
initApi: `get:${commonInfo.baseUrl}/stock/detail/${id}`,
|
||||
body: [
|
||||
{
|
||||
type: 'property',
|
||||
items: [
|
||||
{label: '编码', content: '${code}'},
|
||||
{label: '名称', content: '${name}'},
|
||||
{label: '全名', content: '${fullname}'},
|
||||
{
|
||||
label: '市场',
|
||||
content: {
|
||||
...remoteMappings('stock_market', 'market'),
|
||||
value: '${market}',
|
||||
},
|
||||
},
|
||||
{label: '行业', content: '${industry}'},
|
||||
],
|
||||
},
|
||||
{type: 'divider'},
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(StockDetail)
|
||||
159
leopard-web/src/pages/stock/StockList.tsx
Normal file
159
leopard-web/src/pages/stock/StockList.tsx
Normal file
@@ -0,0 +1,159 @@
|
||||
import React from 'react'
|
||||
import {
|
||||
amisRender,
|
||||
commonInfo,
|
||||
crudCommonOptions,
|
||||
paginationTemplate,
|
||||
remoteMappings,
|
||||
remoteOptions,
|
||||
} from '../../util/amis.tsx'
|
||||
import {useNavigate} from 'react-router'
|
||||
|
||||
function StockList() {
|
||||
const navigate = useNavigate()
|
||||
return (
|
||||
<div className="stock-list">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'page',
|
||||
title: '股票列表',
|
||||
body: [
|
||||
{
|
||||
type: 'crud',
|
||||
api: {
|
||||
method: 'post',
|
||||
url: `${commonInfo.baseUrl}/stock/list`,
|
||||
data: {
|
||||
query: {
|
||||
contain: {
|
||||
code: '${filter_code|default:undefined}',
|
||||
name: '${filter_keyword|default:undefined}',
|
||||
fullname: '${filter_keyword|default:undefined}',
|
||||
},
|
||||
inside: {
|
||||
market: '${filter_market|default:undefined}',
|
||||
industry: '${filter_industry|default:undefined}',
|
||||
},
|
||||
},
|
||||
page: {
|
||||
index: '${page}',
|
||||
size: '${perPage}',
|
||||
},
|
||||
sort: [
|
||||
{
|
||||
column: 'code',
|
||||
direction: 'ASC',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
...crudCommonOptions(),
|
||||
...paginationTemplate(15, undefined, ['filter-toggler']),
|
||||
filterTogglable: true,
|
||||
filterDefaultVisible: false,
|
||||
filter: {
|
||||
title: '快速搜索',
|
||||
mode: 'default',
|
||||
columnCount: 4,
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'filter_code',
|
||||
label: '编号',
|
||||
placeholder: '请输入编号',
|
||||
clearable: true,
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'filter_keyword',
|
||||
label: '关键字',
|
||||
placeholder: '请输入关键字',
|
||||
clearable: true,
|
||||
},
|
||||
{
|
||||
name: 'filter_market',
|
||||
label: '市场',
|
||||
...remoteOptions('select', 'stock_market'),
|
||||
multiple: true,
|
||||
extractValue: true,
|
||||
joinValues: false,
|
||||
clearable: true,
|
||||
checkAll: true,
|
||||
checkAllBySearch: true,
|
||||
defaultCheckAll: true,
|
||||
},
|
||||
{
|
||||
name: 'filter_industry',
|
||||
label: '行业',
|
||||
...remoteOptions('select', 'stock_industry'),
|
||||
searchable: true,
|
||||
multiple: true,
|
||||
extractValue: true,
|
||||
joinValues: false,
|
||||
clearable: true,
|
||||
checkAll: true,
|
||||
checkAllBySearch: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
name: 'code',
|
||||
label: '编号',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
label: '简称',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
name: 'fullname',
|
||||
label: '全名',
|
||||
},
|
||||
{
|
||||
name: 'market',
|
||||
label: '市场',
|
||||
width: 100,
|
||||
...remoteMappings('stock_market', 'market'),
|
||||
},
|
||||
{
|
||||
name: 'industry',
|
||||
label: '行业',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
type: 'operation',
|
||||
label: '操作',
|
||||
width: 100,
|
||||
buttons: [
|
||||
{
|
||||
type: 'action',
|
||||
label: '详情',
|
||||
level: 'link',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'custom',
|
||||
// @ts-ignore
|
||||
script: (context, action, event) => {
|
||||
navigate(`/stock/detail/${context.props.data['id']}`)
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(StockList)
|
||||
27
leopard-web/src/pages/task/TaskAdd.tsx
Normal file
27
leopard-web/src/pages/task/TaskAdd.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from 'react'
|
||||
import {amisRender, commonInfo} from '../../util/amis.tsx'
|
||||
|
||||
function TaskAdd() {
|
||||
return (
|
||||
<div className="task-add">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'page',
|
||||
title: '任务添加',
|
||||
body: [
|
||||
{
|
||||
debug: commonInfo.debug,
|
||||
type: 'form',
|
||||
wrapWithPanel: false,
|
||||
mode: 'horizontal',
|
||||
labelAlign: 'left',
|
||||
body: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(TaskAdd)
|
||||
113
leopard-web/src/pages/task/TaskList.tsx
Normal file
113
leopard-web/src/pages/task/TaskList.tsx
Normal file
@@ -0,0 +1,113 @@
|
||||
import React from 'react'
|
||||
import {amisRender, commonInfo, crudCommonOptions, paginationTemplate, remoteMappings} from '../../util/amis.tsx'
|
||||
import {useNavigate} from 'react-router'
|
||||
|
||||
function TaskList() {
|
||||
const navigate = useNavigate()
|
||||
return (
|
||||
<div className="task-list">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'page',
|
||||
title: '任务列表',
|
||||
body: [
|
||||
{
|
||||
type: 'crud',
|
||||
api: {
|
||||
method: 'post',
|
||||
url: `${commonInfo.baseUrl}/task/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/add')
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
),
|
||||
columns: [
|
||||
{
|
||||
name: 'name',
|
||||
label: '简称',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: '描述',
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
label: '状态',
|
||||
width: 100,
|
||||
...remoteMappings('task_status', 'status'),
|
||||
},
|
||||
{
|
||||
name: 'launchedTime',
|
||||
label: '启动时间',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
name: 'finishedTime',
|
||||
label: '结束时间',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
type: 'operation',
|
||||
label: '操作',
|
||||
width: 100,
|
||||
buttons: [
|
||||
{
|
||||
type: 'action',
|
||||
label: '详情',
|
||||
level: 'link',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'custom',
|
||||
// @ts-ignore
|
||||
script: (context, action, event) => {
|
||||
navigate(`/task/detail/${context.props.data['id']}`)
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(TaskList)
|
||||
Reference in New Issue
Block a user