import React, { useEffect, useState, useMemo, useCallback } from 'react'; import { Card, Form, Input, Button, Space, message, Spin, Switch, Alert, Descriptions, Tag, Tabs, Drawer, Tree, Checkbox, Select, TreeSelect, Modal, DatePicker, InputNumber, Table, Popconfirm, } from 'antd'; import { SaveOutlined, ApiOutlined, CheckCircleOutlined, CloseCircleOutlined, SyncOutlined, ReloadOutlined, PlusOutlined, } from '@ant-design/icons'; import type { DataNode } from 'antd/es/tree'; import api from '../../api'; interface DingTalkConfig { agentId: string; appSecret: string; corpId: string; startEnable: boolean; } interface DingOrgTreeNodeExt { id: number; name: string; parentId: number; children: DingOrgTreeNodeExt[]; users: Array<{ userid: string; name: string; mobile: string; deptIds: number[] }>; } interface RoleItem { id: number; name: string; status: number; } interface OrgTreeNodeRaw { id: number; name: string; children?: OrgTreeNodeRaw[]; } interface OrgTreeResponse { success: boolean; data: OrgTreeNodeRaw[]; } interface OrgTreeWithUsersResponse { success: boolean; data: DingOrgTreeNodeExt[]; } interface ImportUsersResponse { success: boolean; data: { teacherCount: number; studentCount: number; classCount: number; skipped: number; warnings: string[]; }; } interface ClassMarkForm { deptId: number; name: string; code: string; classType: string; startDate?: string; endDate?: string; maxStudents?: number; notes?: string; } const UserTreeNode: React.FC<{ u: { userid: string; name: string; mobile: string }; isTeacher: boolean; onToggle: () => void; roleId: number | undefined; defaultRoleId: number | null; roles: Array<{ id: number; name: string }>; onRoleChange: (roleId: number) => void; }> = React.memo(({ u, isTeacher, onToggle, roleId, defaultRoleId, roles, onRoleChange }) => ( 老师 {u.name} {u.mobile && {u.mobile}} {isTeacher && ( ), }, { key: 'bindings', label: '钉钉绑定', children: (
用户绑定管理
( {r.user?.name || '-'} {r.user?.username} ), }, { title: '钉钉用户ID', dataIndex: 'dingUserId', key: 'dingUserId' }, { title: '钉钉名称', dataIndex: 'dingName', key: 'dingName', render: (v: string | null) => v || '-' }, { title: '钉钉手机', dataIndex: 'dingMobile', key: 'dingMobile', render: (v: string | null) => v || '-' }, { title: '操作', key: 'actions', render: (_: unknown, r: typeof bindings[number]) => ( handleUnbind(r.id)} okText="解绑" okType="danger"> ), }, ]} pagination={{ pageSize: 20 }} locale={{ emptyText: '暂无绑定记录' }} /> { setBindModalOpen(false); bindForm.resetFields(); }} confirmLoading={bindSubmitting} >
), }, ...syncTabItems, ]; return ( {verified === true && } color="success">已连接} {verified === false && } color="error">未连接} }> ); }; export default IntegrationConfigPage;