@chenhui996/gg-cli 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/template/zhiguan/.editorconfig +16 -0
  2. package/dist/template/zhiguan/.env +1 -0
  3. package/dist/template/zhiguan/.env.development +4 -0
  4. package/dist/template/zhiguan/.env.production +4 -0
  5. package/dist/template/zhiguan/.env.test +4 -0
  6. package/dist/template/zhiguan/.prettierignore +34 -0
  7. package/dist/template/zhiguan/.prettierrc +14 -0
  8. package/dist/template/zhiguan/README.md +183 -0
  9. package/dist/template/zhiguan/docs/Git/345/274/200/345/217/221/350/247/204/350/214/203.md +105 -0
  10. package/dist/template/zhiguan/docs/React/345/274/200/345/217/221/350/247/204/350/214/203.md +81 -0
  11. package/dist/template/zhiguan/docs/TypeScript/345/274/200/345/217/221/350/247/204/350/214/203.md +119 -0
  12. package/dist/template/zhiguan/docs//345/211/215/347/253/257/346/227/245/345/277/227/344/270/216/347/233/221/346/216/247/345/237/213/347/202/271/350/247/204/350/214/203.md +136 -0
  13. package/dist/template/zhiguan/docs//345/215/225/345/205/203/346/265/213/350/257/225/350/247/204/350/214/203.md +131 -0
  14. package/dist/template/zhiguan/docs//351/241/271/347/233/256/347/233/256/345/275/225/347/273/223/346/236/204/350/247/204/350/214/203.md +93 -0
  15. package/dist/template/zhiguan/eslint.config.js +27 -0
  16. package/dist/template/zhiguan/index.html +13 -0
  17. package/dist/template/zhiguan/package.json +60 -0
  18. package/dist/template/zhiguan/public/favicon.svg +1 -0
  19. package/dist/template/zhiguan/public/icons.svg +24 -0
  20. package/dist/template/zhiguan/src/api/user.ts +21 -0
  21. package/dist/template/zhiguan/src/assets/Frame 20.png +0 -0
  22. package/dist/template/zhiguan/src/assets/react.svg +1 -0
  23. package/dist/template/zhiguan/src/components/Chart/index.tsx +22 -0
  24. package/dist/template/zhiguan/src/components/ErrorBoundary/index.tsx +82 -0
  25. package/dist/template/zhiguan/src/layouts/BasicLayout.tsx +174 -0
  26. package/dist/template/zhiguan/src/main.tsx +38 -0
  27. package/dist/template/zhiguan/src/pages/404.test.tsx +20 -0
  28. package/dist/template/zhiguan/src/pages/404.tsx +32 -0
  29. package/dist/template/zhiguan/src/pages/about/index.tsx +8 -0
  30. package/dist/template/zhiguan/src/pages/calendar/index.tsx +8 -0
  31. package/dist/template/zhiguan/src/pages/dashboard/index.tsx +72 -0
  32. package/dist/template/zhiguan/src/pages/home/index.less +59 -0
  33. package/dist/template/zhiguan/src/pages/home/index.tsx +217 -0
  34. package/dist/template/zhiguan/src/pages/settings/index.tsx +8 -0
  35. package/dist/template/zhiguan/src/pages/workspace/index.tsx +8 -0
  36. package/dist/template/zhiguan/src/router/index.tsx +81 -0
  37. package/dist/template/zhiguan/src/setupTests.ts +1 -0
  38. package/dist/template/zhiguan/src/store/useCounterStore.ts +24 -0
  39. package/dist/template/zhiguan/src/style.less +3 -0
  40. package/dist/template/zhiguan/src/utils/request/index.ts +108 -0
  41. package/dist/template/zhiguan/src/vite-env.d.ts +12 -0
  42. package/dist/template/zhiguan/tsconfig.app.json +34 -0
  43. package/dist/template/zhiguan/tsconfig.json +7 -0
  44. package/dist/template/zhiguan/tsconfig.node.json +26 -0
  45. package/dist/template/zhiguan/vite.config.ts +77 -0
  46. package/package.json +1 -1
  47. package/dist/template/operations-tem/package-lock.json +0 -6413
@@ -0,0 +1,82 @@
1
+ import { Component, type ErrorInfo, type ReactNode } from 'react';
2
+ import { Result, Button } from 'antd';
3
+
4
+ interface Props {
5
+ children?: ReactNode;
6
+ fallback?: ReactNode;
7
+ }
8
+
9
+ interface State {
10
+ hasError: boolean;
11
+ error?: Error;
12
+ }
13
+
14
+ /**
15
+ * 全局错误边界组件 (Error Boundary)
16
+ * 用于捕获 React 组件树中的渲染错误,防止整个应用白屏崩溃
17
+ * 同时可在此处进行错误日志上报
18
+ */
19
+ export class ErrorBoundary extends Component<Props, State> {
20
+ public state: State = {
21
+ hasError: false,
22
+ };
23
+
24
+ public static getDerivedStateFromError(error: Error): State {
25
+ // 更新 state 以致于下一次渲染能够显示降级后的 UI
26
+ return { hasError: true, error };
27
+ }
28
+
29
+ public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
30
+ // 在这里你可以将错误日志上报给服务器
31
+ console.error('Uncaught error in React component tree:', error, errorInfo);
32
+
33
+ // 示例:如果在生产环境,调用监控 SDK
34
+ // if (import.meta.env.PROD) {
35
+ // logService.error('REACT_RENDER_ERROR', { error, errorInfo });
36
+ // }
37
+ }
38
+
39
+ private handleReset = () => {
40
+ // 重置错误状态,尝试恢复组件渲染
41
+ this.setState({ hasError: false, error: undefined });
42
+ // 也可以选择刷新整个页面
43
+ // window.location.reload();
44
+ };
45
+
46
+ public render() {
47
+ if (this.state.hasError) {
48
+ // 渲染自定义的降级 UI,或者使用默认的 500 页面
49
+ if (this.props.fallback) {
50
+ return this.props.fallback;
51
+ }
52
+
53
+ return (
54
+ <Result
55
+ status="500"
56
+ title="抱歉,页面加载出错了"
57
+ subTitle={
58
+ import.meta.env.DEV
59
+ ? this.state.error?.message
60
+ : "我们正在努力修复此问题,请稍后再试。"
61
+ }
62
+ extra={
63
+ <Button type="primary" onClick={this.handleReset}>
64
+ 重试
65
+ </Button>
66
+ }
67
+ style={{
68
+ height: '100%',
69
+ display: 'flex',
70
+ flexDirection: 'column',
71
+ justifyContent: 'center',
72
+ background: '#fff',
73
+ borderRadius: 8,
74
+ margin: 24,
75
+ }}
76
+ />
77
+ );
78
+ }
79
+
80
+ return this.props.children;
81
+ }
82
+ }
@@ -0,0 +1,174 @@
1
+ import { Outlet, Link, useLocation, useNavigate } from 'react-router-dom';
2
+ import { Layout, Menu, Avatar, Badge, Space, Typography, Button } from 'antd';
3
+ import {
4
+ MessageOutlined,
5
+ AppstoreOutlined,
6
+ FolderOutlined,
7
+ CalendarOutlined,
8
+ SettingOutlined,
9
+ BellOutlined,
10
+ UserOutlined,
11
+ } from '@ant-design/icons';
12
+
13
+ const { Header, Content, Sider } = Layout;
14
+ const { Text } = Typography;
15
+
16
+ /**
17
+ * 侧边栏菜单配置
18
+ * 使用数据驱动的方式定义菜单项,方便后续扩展
19
+ * @property {string} key - 路由路径,用于 Link 跳转和菜单高亮
20
+ * @property {ReactNode} icon - 菜单图标组件
21
+ * @property {string} label - 菜单显示名称
22
+ */
23
+ const MENU_ITEMS = [
24
+ {
25
+ key: '/',
26
+ icon: <MessageOutlined />,
27
+ label: '聊天',
28
+ },
29
+ {
30
+ key: '/dashboard',
31
+ icon: <AppstoreOutlined />,
32
+ label: '功能大厅',
33
+ },
34
+ {
35
+ key: '/workspace', // 暂未实现
36
+ icon: <FolderOutlined />,
37
+ label: '工作空间',
38
+ },
39
+ {
40
+ key: '/calendar', // 暂未实现
41
+ icon: <CalendarOutlined />,
42
+ label: '日历',
43
+ },
44
+ ];
45
+
46
+ /**
47
+ * 基础布局组件 (BasicLayout)
48
+ *
49
+ * 整体布局结构:
50
+ * - Sider (左侧侧边栏)
51
+ * - Logo
52
+ * - Menu (动态渲染)
53
+ * - UserProfile (底部固定)
54
+ * - Layout (右侧主体)
55
+ * - Header (顶部导航)
56
+ * - Content (路由出口 Outlet)
57
+ *
58
+ * @returns {JSX.Element} 布局组件
59
+ */
60
+ export default function BasicLayout() {
61
+ // 获取当前路由路径,用于菜单高亮
62
+ const location = useLocation();
63
+ // 路由跳转钩子,用于编程式导航
64
+ const navigate = useNavigate();
65
+
66
+ // 渲染侧边栏底部用户信息区域
67
+ const renderUserProfile = () => (
68
+ <div
69
+ style={{
70
+ padding: '16px',
71
+ display: 'flex',
72
+ alignItems: 'center',
73
+ justifyContent: 'space-between',
74
+ }}
75
+ >
76
+ <Space>
77
+ <Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=1" icon={<UserOutlined />} />
78
+ <Text strong style={{ fontSize: 14 }}>
79
+ 国泰海通-张三
80
+ </Text>
81
+ </Space>
82
+ <Button type="text" icon={<SettingOutlined />} onClick={() => navigate('/settings')} />
83
+ </div>
84
+ );
85
+
86
+ return (
87
+ <Layout style={{ minHeight: '100vh', position: 'relative' }}>
88
+ {/* 左侧侧边栏 */}
89
+ <Sider
90
+ width={240}
91
+ theme="light"
92
+ style={{
93
+ borderRight: '1px solid #f0f0f0',
94
+ }}
95
+ >
96
+ <div
97
+ style={{ display: 'flex', flexDirection: 'column', height: '100%', position: 'relative' }}
98
+ >
99
+ {/* Logo 区域 */}
100
+ <div
101
+ style={{
102
+ height: 64,
103
+ display: 'flex',
104
+ alignItems: 'center',
105
+ paddingLeft: 24,
106
+ fontSize: 20,
107
+ fontWeight: 'bold',
108
+ color: '#333',
109
+ }}
110
+ >
111
+ PILOTCORE
112
+ </div>
113
+
114
+ {/* 菜单区域 - flex: 1 撑满剩余空间 */}
115
+ <div style={{ flex: 1, overflowY: 'auto' }}>
116
+ <Menu
117
+ mode="inline"
118
+ selectedKeys={[location.pathname]}
119
+ style={{ borderRight: 0, paddingBottom: 16, borderBottom: '1px solid #f0f0f0' }}
120
+ items={MENU_ITEMS.map((item) => ({
121
+ ...item,
122
+ label: <Link to={item.key}>{item.label}</Link>,
123
+ }))}
124
+ />
125
+ </div>
126
+
127
+ {/* 底部用户信息 */}
128
+ <div style={{ position: 'absolute', bottom: 0, width: '100%' }}>
129
+ {renderUserProfile()}
130
+ </div>
131
+ </div>
132
+ </Sider>
133
+
134
+ {/* 右侧主体区域 */}
135
+ <Layout>
136
+ {/* 顶部导航栏 */}
137
+ <Header
138
+ style={{
139
+ padding: '0 24px',
140
+ display: 'flex',
141
+ justifyContent: 'flex-end',
142
+ alignItems: 'center',
143
+ backgroundColor: 'transparent', // 透明背景融入整体
144
+ }}
145
+ >
146
+ <Space size={24}>
147
+ {/* 通知图标 */}
148
+ <Badge count={3} offset={[2, 2]} color="#1677ff">
149
+ <Button
150
+ icon={<BellOutlined />}
151
+ shape="circle"
152
+ style={{
153
+ border: 'none',
154
+ background: '#fff',
155
+ boxShadow: '0 2px 8px rgba(0,0,0,0.05)',
156
+ }}
157
+ />
158
+ </Badge>
159
+ </Space>
160
+ </Header>
161
+
162
+ {/* 内容区域 */}
163
+ <Content
164
+ style={{
165
+ margin: '0 24px 24px',
166
+ minHeight: 280,
167
+ }}
168
+ >
169
+ <Outlet />
170
+ </Content>
171
+ </Layout>
172
+ </Layout>
173
+ );
174
+ }
@@ -0,0 +1,38 @@
1
+ import { createRoot } from 'react-dom/client';
2
+ import { RouterProvider } from 'react-router-dom';
3
+ import { ConfigProvider } from 'antd';
4
+ import zhCN from 'antd/locale/zh_CN';
5
+ import { router } from '@/router';
6
+ import { ErrorBoundary } from '@/components/ErrorBoundary';
7
+ import 'antd/dist/reset.css';
8
+ import './style.less';
9
+
10
+ createRoot(document.getElementById('root')!).render(
11
+ <ErrorBoundary>
12
+ <ConfigProvider
13
+ locale={zhCN}
14
+ theme={{
15
+ token: {
16
+ colorPrimary: '#4F46E5', // 调整为更接近设计稿的深蓝色
17
+ borderRadius: 8, // 全局圆角
18
+ colorBgLayout: '#F9FAFB', // 极淡的背景灰
19
+ },
20
+ components: {
21
+ Layout: {
22
+ siderBg: '#ffffff', // 侧边栏白色背景
23
+ headerBg: '#ffffff', // 顶栏白色背景
24
+ },
25
+ Menu: {
26
+ itemSelectedBg: '#EFF6FF', // 选中项浅蓝背景
27
+ itemSelectedColor: '#4F46E5', // 选中项文字颜色
28
+ },
29
+ Card: {
30
+ borderRadiusLG: 12, // 卡片大圆角
31
+ },
32
+ },
33
+ }}
34
+ >
35
+ <RouterProvider router={router} />
36
+ </ConfigProvider>
37
+ </ErrorBoundary>,
38
+ );
@@ -0,0 +1,20 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { render, screen } from '@testing-library/react';
3
+ import NotFound from './404.js';
4
+ import { BrowserRouter } from 'react-router-dom';
5
+
6
+ describe('NotFound (404) 页面组件', () => {
7
+ it('应当正确渲染 404 状态码和提示信息', () => {
8
+ // Arrange: 渲染组件 (需要包裹在 Router 中因为内部使用了 useNavigate)
9
+ render(
10
+ <BrowserRouter>
11
+ <NotFound />
12
+ </BrowserRouter>
13
+ );
14
+
15
+ // Assert: 验证页面中是否出现了 404 和相关提示文字
16
+ expect(screen.getByText('404')).toBeInTheDocument();
17
+ expect(screen.getByText('抱歉,您访问的页面不存在。')).toBeInTheDocument();
18
+ expect(screen.getByRole('button', { name: '返回首页' })).toBeInTheDocument();
19
+ });
20
+ });
@@ -0,0 +1,32 @@
1
+ import { Button, Result } from 'antd';
2
+ import { useNavigate } from 'react-router-dom';
3
+
4
+ /**
5
+ * 404 页面组件
6
+ * 当用户访问不存在的路由时展示
7
+ */
8
+ export default function NotFound() {
9
+ const navigate = useNavigate();
10
+
11
+ return (
12
+ <Result
13
+ status="404"
14
+ title="404"
15
+ subTitle="抱歉,您访问的页面不存在。"
16
+ extra={
17
+ <Button type="primary" onClick={() => navigate('/')}>
18
+ 返回首页
19
+ </Button>
20
+ }
21
+ style={{
22
+ height: '100%',
23
+ display: 'flex',
24
+ flexDirection: 'column',
25
+ justifyContent: 'center',
26
+ background: '#fff',
27
+ borderRadius: 8,
28
+ margin: 24,
29
+ }}
30
+ />
31
+ );
32
+ }
@@ -0,0 +1,8 @@
1
+ export default function About() {
2
+ return (
3
+ <div>
4
+ <h2>About Page</h2>
5
+ <p>This is a modern React template generated by gg-cli.</p>
6
+ </div>
7
+ );
8
+ }
@@ -0,0 +1,8 @@
1
+ export default function Workspace() {
2
+ return (
3
+ <div>
4
+ <h2>Calendar Page</h2>
5
+ <p>This is a modern React template generated by gg-cli.</p>
6
+ </div>
7
+ );
8
+ }
@@ -0,0 +1,72 @@
1
+ import { Card, Row, Col } from 'antd';
2
+ import Chart from '@/components/Chart';
3
+ import type { EChartsOption } from 'echarts';
4
+
5
+ export default function Dashboard() {
6
+ // 柱状图配置
7
+ const barOption: EChartsOption = {
8
+ title: { text: '周访问量' },
9
+ tooltip: { trigger: 'axis' },
10
+ xAxis: {
11
+ type: 'category',
12
+ data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
13
+ },
14
+ yAxis: { type: 'value' },
15
+ series: [
16
+ {
17
+ data: [120, 200, 150, 80, 70, 110, 130],
18
+ type: 'bar',
19
+ itemStyle: { color: '#1677ff' },
20
+ },
21
+ ],
22
+ };
23
+
24
+ // 饼图配置
25
+ const pieOption: EChartsOption = {
26
+ title: { text: '用户来源' },
27
+ tooltip: { trigger: 'item' },
28
+ legend: { top: 'bottom' },
29
+ series: [
30
+ {
31
+ name: 'Access From',
32
+ type: 'pie',
33
+ radius: ['40%', '70%'],
34
+ avoidLabelOverlap: false,
35
+ itemStyle: {
36
+ borderRadius: 10,
37
+ borderColor: '#fff',
38
+ borderWidth: 2,
39
+ },
40
+ label: { show: false, position: 'center' },
41
+ emphasis: {
42
+ label: { show: true, fontSize: 20, fontWeight: 'bold' },
43
+ },
44
+ data: [
45
+ { value: 1048, name: 'Search Engine' },
46
+ { value: 735, name: 'Direct' },
47
+ { value: 580, name: 'Email' },
48
+ { value: 484, name: 'Union Ads' },
49
+ { value: 300, name: 'Video Ads' },
50
+ ],
51
+ },
52
+ ],
53
+ };
54
+
55
+ return (
56
+ <div>
57
+ <h2 style={{ marginBottom: 24 }}>数据看板 (Dashboard)</h2>
58
+ <Row gutter={[24, 24]}>
59
+ <Col xs={24} md={12}>
60
+ <Card styles={{ body: { height: 400, padding: 0 } }}>
61
+ <Chart option={barOption} />
62
+ </Card>
63
+ </Col>
64
+ <Col xs={24} md={12}>
65
+ <Card styles={{ body: { height: 400, padding: 0 } }}>
66
+ <Chart option={pieOption} />
67
+ </Card>
68
+ </Col>
69
+ </Row>
70
+ </div>
71
+ );
72
+ }
@@ -0,0 +1,59 @@
1
+ .home-page {
2
+ padding: 20px 0;
3
+
4
+ .welcome-header {
5
+ text-align: center;
6
+ margin-bottom: 40px;
7
+ margin-top: 40px;
8
+
9
+ h2.ant-typography {
10
+ margin-bottom: 8px;
11
+ }
12
+ }
13
+
14
+ .search-section {
15
+ max-width: 800px;
16
+ margin: 0 auto 48px;
17
+
18
+ .search-box {
19
+ background: #fff;
20
+ border-radius: 12px;
21
+ padding: 8px 8px 8px 16px;
22
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.03);
23
+ border: 1px solid #f0f0f0;
24
+ display: flex;
25
+ align-items: center;
26
+
27
+ .search-icon {
28
+ font-size: 18px;
29
+ color: #999;
30
+ margin-right: 12px;
31
+ }
32
+
33
+ .search-input {
34
+ flex: 1;
35
+ font-size: 14px;
36
+ }
37
+
38
+ .search-btn {
39
+ margin-left: 8px;
40
+ }
41
+ }
42
+
43
+ .search-tags {
44
+ margin-top: 16px;
45
+ display: flex;
46
+ gap: 8px;
47
+ justify-content: flex-start;
48
+ padding-left: 4px;
49
+
50
+ .tag-item {
51
+ border-radius: 16px;
52
+ padding: 4px 12px;
53
+ border: 1px solid #e5e7eb;
54
+ background: #fff;
55
+ cursor: pointer;
56
+ }
57
+ }
58
+ }
59
+ }