| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- import React from 'react';
- import { Modal, Button, Space, Typography, message } from 'antd';
- import {
- PoweroffOutlined,
- LogoutOutlined,
- CloseOutlined,
- } from '@ant-design/icons';
- import { useDispatch } from 'react-redux';
- import { clearUserInfo } from '../states/user_info';
- const { Text } = Typography;
- interface ExitModalProps {
- visible: boolean;
- onClose: () => void;
- }
- declare global {
- interface Window {
- electronAPI: {
- exitApp: () => Promise<{ success: boolean }>;
- shutdownSystem: () => Promise<{
- success: boolean;
- error?: string;
- requiresAdmin?: boolean;
- }>;
- checkCameraPermission?: () => Promise<boolean>;
- requestCameraPermission?: () => Promise<boolean>;
- };
- }
- }
- const ExitModal: React.FC<ExitModalProps> = ({ visible, onClose }) => {
- const dispatch = useDispatch();
- const handleExit = async (type: 'close' | 'logout' | 'shutdown') => {
- // 对危险操作进行二次确认
- const isDangerousOperation = type === 'shutdown' || type === 'logout';
- if (isDangerousOperation) {
- const confirmMessages = {
- shutdown: {
- title: '确认关机',
- content: '确定要关闭系统吗?此操作将关闭计算机。',
- },
- logout: {
- title: '确认注销',
- content: '确定要注销当前用户吗?您将退出登录状态。',
- },
- };
- const config = confirmMessages[type];
- Modal.confirm({
- title: config.title,
- content: config.content,
- okText: '确认',
- cancelText: '取消',
- centered: true,
- onOk: async () => {
- await executeAction(type);
- },
- });
- return;
- }
- // 非危险操作直接执行
- await executeAction(type);
- };
- const executeAction = async (type: 'close' | 'logout' | 'shutdown') => {
- try {
- let result;
- let actionName = '';
- switch (type) {
- case 'close':
- actionName = '关闭程序';
- result = await window.electronAPI.exitApp();
- break;
- case 'logout':
- actionName = '注销用户';
- // 应用级注销:清除 Redux 用户状态
- dispatch(clearUserInfo());
- message.success('已退出登录');
- onClose();
- return; // 直接返回,不需要后续处理
- case 'shutdown':
- actionName = '关机';
- result = await window.electronAPI.shutdownSystem();
- break;
- default:
- return;
- }
- if (result && result.success) {
- message.success(`${actionName}操作已执行`);
- if (type === 'close') {
- // 关闭程序操作会直接退出,不需要关闭弹框
- return;
- }
- } else if (result) {
- // 处理不同类型的错误
- if (result.requiresAdmin) {
- message.warning({
- content: `${actionName}需要管理员权限,请以管理员身份运行程序后重试`,
- duration: 5,
- });
- } else {
- message.error({
- content: `${actionName}失败: ${result.error || '未知错误'}`,
- duration: 4,
- });
- }
- }
- } catch (error) {
- console.error('系统操作失败:', error);
- message.error({
- content: '操作失败,请检查网络连接后重试',
- duration: 3,
- });
- }
- onClose();
- };
- return (
- <Modal
- data-testid="exit-modal"
- title="选择退出方式"
- open={visible}
- onCancel={onClose}
- footer={null}
- centered
- width={400}
- >
- <div style={{ textAlign: 'center', padding: '20px 0' }}>
- <Text type="secondary" style={{ marginBottom: 24, display: 'block' }}>
- 请选择您希望执行的操作
- </Text>
- <Space direction="vertical" size="large" style={{ width: '100%' }}>
- <Button
- data-testid="exit-modal-close-button"
- type="default"
- size="large"
- icon={<CloseOutlined />}
- onClick={() => handleExit('close')}
- style={{
- width: '100%',
- height: 48,
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- }}
- >
- 关闭程序
- </Button>
- <Button
- data-testid="exit-modal-logout-button"
- type="default"
- size="large"
- icon={<LogoutOutlined />}
- onClick={() => handleExit('logout')}
- style={{
- width: '100%',
- height: 48,
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- }}
- >
- 注销用户
- </Button>
- <Button
- data-testid="exit-modal-shutdown-button"
- type="default"
- size="large"
- icon={<PoweroffOutlined />}
- onClick={() => handleExit('shutdown')}
- danger
- style={{
- width: '100%',
- height: 48,
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- }}
- >
- 关机
- </Button>
- <Button
- data-testid="exit-modal-cancel-button"
- type="default"
- size="large"
- onClick={onClose}
- style={{
- width: '100%',
- height: 48,
- marginTop: 16,
- }}
- >
- 取消
- </Button>
- </Space>
- </div>
- </Modal>
- );
- };
- export default ExitModal;
|