mirror of
https://github.com/whyour/qinglong.git
synced 2026-07-17 17:54:32 +08:00
修复调试脚本日志丢失
This commit is contained in:
@@ -35,6 +35,7 @@ import { useOutletContext } from '@umijs/max';
|
||||
import { SharedContext } from '@/layouts';
|
||||
import useTableScrollHeight from '@/hooks/useTableScrollHeight';
|
||||
import dayjs from 'dayjs';
|
||||
import WebSocketManager from '@/utils/websocket';
|
||||
|
||||
const { Text } = Typography;
|
||||
const { Search } = Input;
|
||||
@@ -87,8 +88,7 @@ const StatusMap: Record<number, { icon: React.ReactNode; color: string }> = {
|
||||
};
|
||||
|
||||
const Dependence = () => {
|
||||
const { headerStyle, isPhone, socketMessage } =
|
||||
useOutletContext<SharedContext>();
|
||||
const { headerStyle, isPhone } = useOutletContext<SharedContext>();
|
||||
const columns: any = [
|
||||
{
|
||||
title: intl.get('序号'),
|
||||
@@ -109,11 +109,12 @@ const Dependence = () => {
|
||||
width: 120,
|
||||
dataIndex: 'status',
|
||||
render: (text: string, record: any, index: number) => {
|
||||
console.log(record.status);
|
||||
return (
|
||||
<Space size="middle" style={{ cursor: 'text' }}>
|
||||
<Tag
|
||||
color={StatusMap[record.status].color}
|
||||
icon={StatusMap[record.status].icon}
|
||||
color={StatusMap[record.status]?.color}
|
||||
icon={StatusMap[record.status]?.icon}
|
||||
style={{ marginRight: 0 }}
|
||||
>
|
||||
{intl.get(Status[record.status])}
|
||||
@@ -395,63 +396,62 @@ const Dependence = () => {
|
||||
}
|
||||
}, [logDependence]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!socketMessage) return;
|
||||
const { type, message, references } = socketMessage;
|
||||
if (
|
||||
type === 'installDependence' &&
|
||||
message.includes('开始时间') &&
|
||||
references.length > 0
|
||||
) {
|
||||
const result = [...value];
|
||||
for (let i = 0; i < references.length; i++) {
|
||||
const index = value.findIndex((x) => x.id === references[i]);
|
||||
if (index !== -1) {
|
||||
result.splice(index, 1, {
|
||||
...value[index],
|
||||
status: message.includes('安装') ? Status.安装中 : Status.删除中,
|
||||
});
|
||||
}
|
||||
}
|
||||
setValue(result);
|
||||
const handleMessage = useCallback((payload: any) => {
|
||||
const { message, references } = payload;
|
||||
let status: number | undefined = undefined;
|
||||
if (message.includes('开始时间') && references.length > 0) {
|
||||
status = message.includes('安装') ? Status.安装中 : Status.删除中;
|
||||
}
|
||||
if (
|
||||
type === 'installDependence' &&
|
||||
message.includes('结束时间') &&
|
||||
references.length > 0
|
||||
) {
|
||||
let status;
|
||||
if (message.includes('结束时间') && references.length > 0) {
|
||||
if (message.includes('安装')) {
|
||||
status = message.includes('成功') ? Status.已安装 : Status.安装失败;
|
||||
} else {
|
||||
status = message.includes('成功') ? Status.已删除 : Status.删除失败;
|
||||
}
|
||||
const result = [...value];
|
||||
for (let i = 0; i < references.length; i++) {
|
||||
const index = value.findIndex((x) => x.id === references[i]);
|
||||
if (index !== -1) {
|
||||
result.splice(index, 1, {
|
||||
...value[index],
|
||||
status,
|
||||
});
|
||||
}
|
||||
}
|
||||
setValue(result);
|
||||
|
||||
if (status === Status.已删除) {
|
||||
setTimeout(() => {
|
||||
const _result = [...value];
|
||||
for (let i = 0; i < references.length; i++) {
|
||||
const index = value.findIndex((x) => x.id === references[i]);
|
||||
if (index !== -1) {
|
||||
_result.splice(index, 1);
|
||||
setValue((p) => {
|
||||
const _result = [...p];
|
||||
for (let i = 0; i < references.length; i++) {
|
||||
const index = p.findIndex((x) => x.id === references[i]);
|
||||
if (index !== -1) {
|
||||
_result.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
setValue(_result);
|
||||
return _result;
|
||||
});
|
||||
}, 5000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, [socketMessage]);
|
||||
if (typeof status === 'number') {
|
||||
setValue((p) => {
|
||||
const result = [...p];
|
||||
for (let i = 0; i < references.length; i++) {
|
||||
const index = p.findIndex((x) => x.id === references[i]);
|
||||
if (index !== -1) {
|
||||
result.splice(index, 1, {
|
||||
...p[index],
|
||||
status,
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const ws = WebSocketManager.getInstance();
|
||||
ws.subscribe('installDependence', handleMessage);
|
||||
ws.subscribe('uninstallDependence', handleMessage);
|
||||
|
||||
return () => {
|
||||
ws.unsubscribe('installDependence', handleMessage);
|
||||
ws.unsubscribe('uninstallDependence', handleMessage);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const onTabChange = (activeKey: string) => {
|
||||
setSelectedRowIds([]);
|
||||
@@ -548,24 +548,25 @@ const Dependence = () => {
|
||||
dependence={editedDependence}
|
||||
defaultType={type}
|
||||
/>
|
||||
<DependenceLogModal
|
||||
visible={isLogModalVisible}
|
||||
handleCancel={(needRemove?: boolean) => {
|
||||
setIsLogModalVisible(false);
|
||||
if (needRemove) {
|
||||
const index = value.findIndex((x) => x.id === logDependence.id);
|
||||
const result = [...value];
|
||||
if (index !== -1) {
|
||||
result.splice(index, 1);
|
||||
setValue(result);
|
||||
{logDependence && (
|
||||
<DependenceLogModal
|
||||
visible={isLogModalVisible}
|
||||
handleCancel={(needRemove?: boolean) => {
|
||||
setIsLogModalVisible(false);
|
||||
if (needRemove) {
|
||||
const index = value.findIndex((x) => x.id === logDependence.id);
|
||||
const result = [...value];
|
||||
if (index !== -1) {
|
||||
result.splice(index, 1);
|
||||
setValue(result);
|
||||
}
|
||||
} else if ([...value].map((x) => x.id).includes(logDependence.id)) {
|
||||
getDependenceDetail(logDependence);
|
||||
}
|
||||
} else if ([...value].map((x) => x.id).includes(logDependence.id)) {
|
||||
getDependenceDetail(logDependence);
|
||||
}
|
||||
}}
|
||||
socketMessage={socketMessage}
|
||||
dependence={logDependence}
|
||||
/>
|
||||
}}
|
||||
dependence={logDependence}
|
||||
/>
|
||||
)}
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,17 +9,16 @@ import {
|
||||
} from '@ant-design/icons';
|
||||
import { PageLoading } from '@ant-design/pro-layout';
|
||||
import Ansi from 'ansi-to-react';
|
||||
import WebSocketManager from '@/utils/websocket';
|
||||
|
||||
const DependenceLogModal = ({
|
||||
dependence,
|
||||
handleCancel,
|
||||
visible,
|
||||
socketMessage,
|
||||
}: {
|
||||
dependence?: any;
|
||||
visible: boolean;
|
||||
handleCancel: (needRemove?: boolean) => void;
|
||||
socketMessage: any;
|
||||
}) => {
|
||||
const [value, setValue] = useState<string>('');
|
||||
const [executing, setExecuting] = useState<any>(true);
|
||||
@@ -54,7 +53,7 @@ const DependenceLogModal = ({
|
||||
code === 200 &&
|
||||
localStorage.getItem('logDependence') === String(dependence.id)
|
||||
) {
|
||||
const log = (data.log || []).join('') as string;
|
||||
const log = (data?.log || []).join('') as string;
|
||||
setValue(log);
|
||||
setExecuting(!log.includes('结束时间'));
|
||||
setIsRemoveFailed(log.includes('删除失败'));
|
||||
@@ -95,21 +94,25 @@ const DependenceLogModal = ({
|
||||
}
|
||||
}, [dependence]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!socketMessage || !dependence) return;
|
||||
const { type, message, references } = socketMessage;
|
||||
if (
|
||||
type === 'installDependence' &&
|
||||
references.length > 0 &&
|
||||
references.includes(dependence.id)
|
||||
) {
|
||||
const handleMessage = (payload: any) => {
|
||||
const { message, references } = payload;
|
||||
if (references.length > 0 && references.includes(dependence.id)) {
|
||||
if (message.includes('结束时间')) {
|
||||
setExecuting(false);
|
||||
setIsRemoveFailed(message.includes('删除失败'));
|
||||
}
|
||||
setValue(`${value}${message}`);
|
||||
setValue((p) => `${p}${message}`);
|
||||
}
|
||||
}, [socketMessage]);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const ws = WebSocketManager.getInstance();
|
||||
ws.subscribe('installDependence', handleMessage);
|
||||
|
||||
return () => {
|
||||
ws.unsubscribe('installDependence', handleMessage);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setIsPhone(document.body.clientWidth < 768);
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import intl from 'react-intl-universal';
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import React, {
|
||||
useEffect,
|
||||
useState,
|
||||
useRef,
|
||||
useCallback,
|
||||
useReducer,
|
||||
} from 'react';
|
||||
import { Drawer, Button, Tabs, Badge, Select, TreeSelect } from 'antd';
|
||||
import { request } from '@/utils/http';
|
||||
import config from '@/utils/config';
|
||||
@@ -9,6 +15,7 @@ import SaveModal from './saveModal';
|
||||
import SettingModal from './setting';
|
||||
import { useTheme } from '@/utils/hooks';
|
||||
import { getEditorMode, logEnded } from '@/utils';
|
||||
import WebSocketManager from '@/utils/websocket';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
@@ -18,12 +25,10 @@ const EditModal = ({
|
||||
content,
|
||||
handleCancel,
|
||||
visible,
|
||||
socketMessage,
|
||||
}: {
|
||||
treeData?: any;
|
||||
content?: string;
|
||||
visible: boolean;
|
||||
socketMessage: any;
|
||||
currentNode: any;
|
||||
handleCancel: () => void;
|
||||
}) => {
|
||||
@@ -34,12 +39,11 @@ const EditModal = ({
|
||||
const [saveModalVisible, setSaveModalVisible] = useState<boolean>(false);
|
||||
const [settingModalVisible, setSettingModalVisible] =
|
||||
useState<boolean>(false);
|
||||
const [log, setLog] = useState<string>('');
|
||||
const [log, setLog] = useState('');
|
||||
const { theme } = useTheme();
|
||||
const editorRef = useRef<any>(null);
|
||||
const [isRunning, setIsRunning] = useState(false);
|
||||
const [currentPid, setCurrentPid] = useState(null);
|
||||
|
||||
const cancel = () => {
|
||||
handleCancel();
|
||||
};
|
||||
@@ -104,28 +108,25 @@ const EditModal = ({
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!socketMessage) {
|
||||
return;
|
||||
}
|
||||
|
||||
let { type, message: _message, references } = socketMessage;
|
||||
|
||||
if (type !== 'manuallyRunScript') {
|
||||
return;
|
||||
}
|
||||
|
||||
const handleMessage = useCallback((payload: any) => {
|
||||
let { message: _message } = payload;
|
||||
if (logEnded(_message)) {
|
||||
setTimeout(() => {
|
||||
setIsRunning(false);
|
||||
}, 300);
|
||||
}
|
||||
|
||||
if (log) {
|
||||
_message = `\n${_message}`;
|
||||
}
|
||||
setLog(`${log}${_message}`);
|
||||
}, [socketMessage]);
|
||||
setLog(p=>`${p}${_message}`);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const ws = WebSocketManager.getInstance();
|
||||
ws.subscribe('manuallyRunScript', handleMessage);
|
||||
|
||||
return () => {
|
||||
ws.unsubscribe('manuallyRunScript', handleMessage);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setLog('');
|
||||
|
||||
@@ -48,7 +48,7 @@ import { langs } from '@uiw/codemirror-extensions-langs';
|
||||
const { Text } = Typography;
|
||||
|
||||
const Script = () => {
|
||||
const { headerStyle, isPhone, theme, socketMessage } =
|
||||
const { headerStyle, isPhone, theme } =
|
||||
useOutletContext<SharedContext>();
|
||||
const [value, setValue] = useState(intl.get('请选择脚本文件'));
|
||||
const [select, setSelect] = useState<string>('');
|
||||
@@ -591,16 +591,15 @@ const Script = () => {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<EditModal
|
||||
{isLogModalVisible && <EditModal
|
||||
visible={isLogModalVisible}
|
||||
treeData={data}
|
||||
currentNode={currentNode}
|
||||
content={value}
|
||||
socketMessage={socketMessage}
|
||||
handleCancel={() => {
|
||||
setIsLogModalVisible(false);
|
||||
}}
|
||||
/>
|
||||
/>}
|
||||
<EditScriptNameModal
|
||||
visible={isAddFileModalVisible}
|
||||
treeData={data}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import intl from 'react-intl-universal';
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import React, { useEffect, useState, useRef, useCallback } from 'react';
|
||||
import { Statistic, Modal, Tag, Button, Spin, message } from 'antd';
|
||||
import { request } from '@/utils/http';
|
||||
import config from '@/utils/config';
|
||||
import WebSocketManager from '@/utils/websocket';
|
||||
import Ansi from 'ansi-to-react';
|
||||
|
||||
const { Countdown } = Statistic;
|
||||
|
||||
const CheckUpdate = ({ socketMessage, systemInfo }: any) => {
|
||||
const CheckUpdate = ({ systemInfo }: any) => {
|
||||
const [updateLoading, setUpdateLoading] = useState(false);
|
||||
const [value, setValue] = useState('');
|
||||
const modalRef = useRef<any>();
|
||||
@@ -149,17 +151,8 @@ const CheckUpdate = ({ socketMessage, systemInfo }: any) => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!modalRef.current || !socketMessage) {
|
||||
return;
|
||||
}
|
||||
const { type, message: _message, references } = socketMessage;
|
||||
|
||||
if (type !== 'updateSystemVersion') {
|
||||
return;
|
||||
}
|
||||
|
||||
const newMessage = `${value}${_message}`;
|
||||
const updateFailed = newMessage.includes('失败');
|
||||
if (!value) return;
|
||||
const updateFailed = value.includes('失败,请检查');
|
||||
|
||||
modalRef.current.update({
|
||||
maskClosable: updateFailed,
|
||||
@@ -167,29 +160,46 @@ const CheckUpdate = ({ socketMessage, systemInfo }: any) => {
|
||||
okButtonProps: { disabled: !updateFailed },
|
||||
content: (
|
||||
<>
|
||||
<pre>{newMessage}</pre>
|
||||
<pre>
|
||||
<Ansi>{value}</Ansi>
|
||||
</pre>
|
||||
<div id="log-identifier" style={{ paddingBottom: 5 }}></div>
|
||||
</>
|
||||
),
|
||||
});
|
||||
}, [value]);
|
||||
|
||||
if (updateFailed && !value.includes('失败,请检查')) {
|
||||
const handleMessage = useCallback((payload: any) => {
|
||||
let { message: _message } = payload;
|
||||
const updateFailed = _message.includes('失败,请检查');
|
||||
|
||||
if (updateFailed) {
|
||||
message.error(intl.get('更新失败,请检查网络及日志或稍后再试'));
|
||||
}
|
||||
|
||||
setValue(newMessage);
|
||||
|
||||
document.getElementById('log-identifier') &&
|
||||
setTimeout(() => {
|
||||
document
|
||||
.getElementById('log-identifier')!
|
||||
.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
.querySelector('#log-identifier')!
|
||||
.scrollIntoView({ behavior: 'smooth' });
|
||||
}, 600);
|
||||
|
||||
if (_message.includes('更新包下载成功')) {
|
||||
setTimeout(() => {
|
||||
showReloadModal();
|
||||
}, 1000);
|
||||
}
|
||||
}, [socketMessage]);
|
||||
|
||||
setValue((p) => `${p}${_message}`);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const ws = WebSocketManager.getInstance();
|
||||
ws.subscribe('updateSystemVersion', handleMessage);
|
||||
|
||||
return () => {
|
||||
ws.unsubscribe('updateSystemVersion', handleMessage);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -46,7 +46,6 @@ const Setting = () => {
|
||||
theme,
|
||||
reloadUser,
|
||||
reloadTheme,
|
||||
socketMessage,
|
||||
systemInfo,
|
||||
} = useOutletContext<SharedContext>();
|
||||
const columns = [
|
||||
@@ -376,7 +375,6 @@ const Setting = () => {
|
||||
children: (
|
||||
<Other
|
||||
reloadTheme={reloadTheme}
|
||||
socketMessage={socketMessage}
|
||||
systemInfo={systemInfo}
|
||||
/>
|
||||
),
|
||||
|
||||
@@ -24,9 +24,8 @@ import useProgress from './progress';
|
||||
|
||||
const Other = ({
|
||||
systemInfo,
|
||||
socketMessage,
|
||||
reloadTheme,
|
||||
}: Pick<SharedContext, 'socketMessage' | 'reloadTheme' | 'systemInfo'>) => {
|
||||
}: Pick<SharedContext, 'reloadTheme' | 'systemInfo'>) => {
|
||||
const defaultTheme = localStorage.getItem('qinglong_dark_theme') || 'auto';
|
||||
const [systemConfig, setSystemConfig] = useState<{
|
||||
logRemoveFrequency?: number | null;
|
||||
@@ -274,7 +273,7 @@ const Other = ({
|
||||
</Upload>
|
||||
</Form.Item>
|
||||
<Form.Item label={intl.get('检查更新')} name="update">
|
||||
<CheckUpdate systemInfo={systemInfo} socketMessage={socketMessage} />
|
||||
<CheckUpdate systemInfo={systemInfo} />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import intl from 'react-intl-universal';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import {
|
||||
Button,
|
||||
message,
|
||||
@@ -36,6 +36,7 @@ import './index.less';
|
||||
import SubscriptionLogModal from './logModal';
|
||||
import { SharedContext } from '@/layouts';
|
||||
import useTableScrollHeight from '@/hooks/useTableScrollHeight';
|
||||
import WebSocketManager from '@/utils/websocket';
|
||||
|
||||
const { Text, Paragraph } = Typography;
|
||||
const { Search } = Input;
|
||||
@@ -61,8 +62,7 @@ export enum SubscriptionType {
|
||||
}
|
||||
|
||||
const Subscription = () => {
|
||||
const { headerStyle, isPhone, socketMessage } =
|
||||
useOutletContext<SharedContext>();
|
||||
const { headerStyle, isPhone } = useOutletContext<SharedContext>();
|
||||
|
||||
const columns: any = [
|
||||
{
|
||||
@@ -508,23 +508,31 @@ const Subscription = () => {
|
||||
: 'subscription';
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!socketMessage) return;
|
||||
const { type, message, references } = socketMessage;
|
||||
if (type === 'runSubscriptionEnd' && references.length > 0) {
|
||||
const result = [...value];
|
||||
const handleMessage = useCallback((payload: any) => {
|
||||
const { message, references } = payload;
|
||||
setValue((p) => {
|
||||
const result = [...p];
|
||||
for (let i = 0; i < references.length; i++) {
|
||||
const index = value.findIndex((x) => x.id === references[i]);
|
||||
const index = p.findIndex((x) => x.id === references[i]);
|
||||
if (index !== -1) {
|
||||
result.splice(index, 1, {
|
||||
...value[index],
|
||||
...p[index],
|
||||
status: SubscriptionStatus.idle,
|
||||
});
|
||||
}
|
||||
}
|
||||
setValue(result);
|
||||
}
|
||||
}, [socketMessage]);
|
||||
return result;
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const ws = WebSocketManager.getInstance();
|
||||
ws.subscribe('runSubscriptionEnd', handleMessage);
|
||||
|
||||
return () => {
|
||||
ws.unsubscribe('runSubscriptionEnd', handleMessage);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (logSubscription) {
|
||||
|
||||
Reference in New Issue
Block a user