فهرست منبع

AI: 会友信息管理和考勤系统

D8D AI 1 سال پیش
والد
کامیت
b40f415f2d
7فایلهای تغییر یافته به همراه297 افزوده شده و 29 حذف شده
  1. 21 22
      package.json
  2. 30 7
      src/App.tsx
  3. 30 0
      src/components/Sidebar.tsx
  4. 50 0
      src/pages/AttendanceRecords.tsx
  5. 34 0
      src/pages/Dashboard.tsx
  6. 53 0
      src/pages/DeviceManagement.tsx
  7. 79 0
      src/pages/MemberManagement.tsx

+ 21 - 22
package.json

@@ -1,33 +1,32 @@
 {
-  "name": "vite-react-typescript-starter",
+  "name": "attendance-management-system",
   "private": true,
-  "version": "0.0.0",
+  "version": "1.0.0",
   "type": "module",
   "scripts": {
     "dev": "vite",
-    "build": "vite build",
-    "lint": "eslint .",
+    "build": "tsc && vite build",
+    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
     "preview": "vite preview"
   },
   "dependencies": {
-    "lucide-react": "^0.344.0",
-    "react": "^18.3.1",
-    "react-dom": "^18.3.1"
+    "react": "^18.2.0",
+    "react-dom": "^18.2.0",
+    "react-router-dom": "^6.16.0",
+    "axios": "^1.5.0",
+    "antd": "^5.9.0",
+    "@ant-design/icons": "^5.2.6"
   },
   "devDependencies": {
-    "@eslint/js": "^9.9.1",
-    "@types/react": "^18.3.5",
-    "@types/react-dom": "^18.3.0",
-    "@vitejs/plugin-react": "^4.3.1",
-    "autoprefixer": "^10.4.18",
-    "eslint": "^9.9.1",
-    "eslint-plugin-react-hooks": "^5.1.0-rc.0",
-    "eslint-plugin-react-refresh": "^0.4.11",
-    "globals": "^15.9.0",
-    "postcss": "^8.4.35",
-    "tailwindcss": "^3.4.1",
-    "typescript": "^5.5.3",
-    "typescript-eslint": "^8.3.0",
-    "vite": "^5.4.2"
+    "@types/react": "^18.2.15",
+    "@types/react-dom": "^18.2.7",
+    "@typescript-eslint/eslint-plugin": "^6.0.0",
+    "@typescript-eslint/parser": "^6.0.0",
+    "@vitejs/plugin-react": "^4.0.3",
+    "eslint": "^8.45.0",
+    "eslint-plugin-react-hooks": "^4.6.0",
+    "eslint-plugin-react-refresh": "^0.4.3",
+    "typescript": "^5.0.2",
+    "vite": "^4.4.5"
   }
-}
+}

+ 30 - 7
src/App.tsx

@@ -1,11 +1,34 @@
-import React from 'react'
+import React from 'react';
+import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
+import { Layout } from 'antd';
+import Sidebar from './components/Sidebar';
+import Dashboard from './pages/Dashboard';
+import MemberManagement from './pages/MemberManagement';
+import AttendanceRecords from './pages/AttendanceRecords';
+import DeviceManagement from './pages/DeviceManagement';
 
-function App() {
+const { Content } = Layout;
+
+const App: React.FC = () => {
   return (
-    <div className="min-h-screen bg-gray-100 flex items-center justify-center">
-      <p className="text-xl font-semibold">开始编辑,看看魔法如何发生 :)</p>
-    </div>
-  )
+    <Router>
+      <Layout style={{ minHeight: '100vh' }}>
+        <Sidebar />
+        <Layout>
+          <Content style={{ margin: '24px 16px 0' }}>
+            <div style={{ padding: 24, minHeight: 360, background: '#fff' }}>
+              <Routes>
+                <Route path="/" element={<Dashboard />} />
+                <Route path="/members" element={<MemberManagement />} />
+                <Route path="/attendance" element={<AttendanceRecords />} />
+                <Route path="/devices" element={<DeviceManagement />} />
+              </Routes>
+            </div>
+          </Content>
+        </Layout>
+      </Layout>
+    </Router>
+  );
 }
 
-export default App
+export default App;

+ 30 - 0
src/components/Sidebar.tsx

@@ -0,0 +1,30 @@
+import React from 'react';
+import { Layout, Menu } from 'antd';
+import { Link } from 'react-router-dom';
+import { DashboardOutlined, TeamOutlined, ScheduleOutlined, ApiOutlined } from '@ant-design/icons';
+
+const { Sider } = Layout;
+
+const Sidebar: React.FC = () => {
+  return (
+    <Sider breakpoint="lg" collapsedWidth="0">
+      <div className="logo" />
+      <Menu theme="dark" mode="inline" defaultSelectedKeys={['1']}>
+        <Menu.Item key="1" icon={<DashboardOutlined />}>
+          <Link to="/">仪表盘</Link>
+        </Menu.Item>
+        <Menu.Item key="2" icon={<TeamOutlined />}>
+          <Link to="/members">会友管理</Link>
+        </Menu.Item>
+        <Menu.Item key="3" icon={<ScheduleOutlined />}>
+          <Link to="/attendance">考勤记录</Link>
+        </Menu.Item>
+        <Menu.Item key="4" icon={<ApiOutlined />}>
+          <Link to="/devices">设备管理</Link>
+        </Menu.Item>
+      </Menu>
+    </Sider>
+  );
+}
+
+export default Sidebar;

+ 50 - 0
src/pages/AttendanceRecords.tsx

@@ -0,0 +1,50 @@
+import React from 'react';
+import { Table, DatePicker } from 'antd';
+
+const { RangePicker } = DatePicker;
+
+const AttendanceRecords: React.FC = () => {
+  const columns = [
+    {
+      title: '姓名',
+      dataIndex: 'name',
+      key: 'name',
+    },
+    {
+      title: '日期',
+      dataIndex: 'date',
+      key: 'date',
+    },
+    {
+      title: '签到时间',
+      dataIndex: 'checkInTime',
+      key: 'checkInTime',
+    },
+    {
+      title: '签退时间',
+      dataIndex: 'checkOutTime',
+      key: 'checkOutTime',
+    },
+  ];
+
+  const data = [
+    {
+      key: '1',
+      name: '张三',
+      date: '2024-10-29',
+      checkInTime: '09:00:00',
+      checkOutTime: '18:00:00',
+    },
+    // 更多数据...
+  ];
+
+  return (
+    <div>
+      <h1>考勤记录</h1>
+      <RangePicker style={{ marginBottom: 16 }} />
+      <Table columns={columns} dataSource={data} />
+    </div>
+  );
+}
+
+export default AttendanceRecords;

+ 34 - 0
src/pages/Dashboard.tsx

@@ -0,0 +1,34 @@
+import React from 'react';
+import { Card, Row, Col, Statistic } from 'antd';
+
+const Dashboard: React.FC = () => {
+  return (
+    <div>
+      <h1>仪表盘</h1>
+      <Row gutter={16}>
+        <Col span={6}>
+          <Card>
+            <Statistic title="总会友数" value={112} />
+          </Card>
+        </Col>
+        <Col span={6}>
+          <Card>
+            <Statistic title="今日出勤" value={78} />
+          </Card>
+        </Col>
+        <Col span={6}>
+          <Card>
+            <Statistic title="本月新增会友" value={5} />
+          </Card>
+        </Col>
+        <Col span={6}>
+          <Card>
+            <Statistic title="在线设备" value={3} />
+          </Card>
+        </Col>
+      </Row>
+    </div>
+  );
+}
+
+export default Dashboard;

+ 53 - 0
src/pages/DeviceManagement.tsx

@@ -0,0 +1,53 @@
+import React from 'react';
+import { Table, Button, Tag } from 'antd';
+
+const DeviceManagement: React.FC = () => {
+  const columns = [
+    {
+      title: '设备ID',
+      dataIndex: 'id',
+      key: 'id',
+    },
+    {
+      title: 'IP地址',
+      dataIndex: 'ip',
+      key: 'ip',
+    },
+    {
+      title: '状态',
+      dataIndex: 'status',
+      key: 'status',
+      render: (status: string) => (
+        <Tag color={status === '在线' ? 'green' : 'red'}>
+          {status}
+        </Tag>
+      ),
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: () => (
+        <Button type="link">配置</Button>
+      ),
+    },
+  ];
+
+  const data = [
+    {
+      key: '1',
+      id: 'DEVICE001',
+      ip: '192.168.1.100',
+      status: '在线',
+    },
+    // 更多数据...
+  ];
+
+  return (
+    <div>
+      <h1>设备管理</h1>
+      <Table columns={columns} dataSource={data} />
+    </div>
+  );
+}
+
+export default DeviceManagement;

+ 79 - 0
src/pages/MemberManagement.tsx

@@ -0,0 +1,79 @@
+import React, { useState } from 'react';
+import { Table, Button, Modal, Form, Input } from 'antd';
+
+const MemberManagement: React.FC = () => {
+  const [isModalVisible, setIsModalVisible] = useState(false);
+
+  const columns = [
+    {
+      title: '姓名',
+      dataIndex: 'name',
+      key: 'name',
+    },
+    {
+      title: '身份证号',
+      dataIndex: 'idNumber',
+      key: 'idNumber',
+    },
+    {
+      title: '手机号',
+      dataIndex: 'phone',
+      key: 'phone',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: () => (
+        <Button type="link">编辑</Button>
+      ),
+    },
+  ];
+
+  const data = [
+    {
+      key: '1',
+      name: '张三',
+      idNumber: '310000199001011234',
+      phone: '13800138000',
+    },
+    // 更多数据...
+  ];
+
+  const handleAddMember = () => {
+    setIsModalVisible(true);
+  };
+
+  const handleOk = () => {
+    setIsModalVisible(false);
+    // 处理添加会友逻辑
+  };
+
+  const handleCancel = () => {
+    setIsModalVisible(false);
+  };
+
+  return (
+    <div>
+      <h1>会友管理</h1>
+      <Button type="primary" onClick={handleAddMember} style={{ marginBottom: 16 }}>
+        添加会友
+      </Button>
+      <Table columns={columns} dataSource={data} />
+      <Modal title="添加会友" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
+        <Form>
+          <Form.Item name="name" label="姓名" rules={[{ required: true }]}>
+            <Input />
+          </Form.Item>
+          <Form.Item name="idNumber" label="身份证号" rules={[{ required: true }]}>
+            <Input />
+          </Form.Item>
+          <Form.Item name="phone" label="手机号" rules={[{ required: true }]}>
+            <Input />
+          </Form.Item>
+        </Form>
+      </Modal>
+    </div>
+  );
+}
+
+export default MemberManagement;