1
0

feat(all): 初始化版本

This commit is contained in:
2025-08-30 10:10:11 +08:00
commit 7f3b61b854
55 changed files with 11289 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
import React from "react";
function Overview() {
return (
<div className="overview"></div>
)
}
export default React.memo(Overview)

View 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

View File

@@ -0,0 +1,10 @@
import React from "react";
function Test() {
return (
<div className="test">
</div>
)
}
export default React.memo(Test)

View 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)

View 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)

View 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)

View 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)