mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-09-07 16:37:06 +08:00
add page to show running task
This commit is contained in:
+12
-8
@@ -162,10 +162,10 @@ function handleMessage(socket, message) {
|
|||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
});
|
});
|
||||||
|
|
||||||
// 如果是心跳,更新最后心跳时间
|
// // 如果是心跳,更新最后心跳时间
|
||||||
if (message.type === 'worker-heartbeat') {
|
// if (message.type === 'worker-heartbeat') {
|
||||||
workerInfo.lastHeartbeat = Date.now();
|
// workerInfo.lastHeartbeat = Date.now();
|
||||||
}
|
// }
|
||||||
} else {
|
} else {
|
||||||
sendResponse(socket, _callbackUuid, { error: '未注册的工具进程连接' });
|
sendResponse(socket, _callbackUuid, { error: '未注册的工具进程连接' });
|
||||||
}
|
}
|
||||||
@@ -328,9 +328,10 @@ function startWorker({ workerId, command, args, env }, restartCount = 0) {
|
|||||||
status: 'running',
|
status: 'running',
|
||||||
startTime: Date.now(),
|
startTime: Date.now(),
|
||||||
restartCount, // 使用传入的重启次数
|
restartCount, // 使用传入的重启次数
|
||||||
socket: null, // 工具进程的TCP连接,稍后由工具进程注册
|
// socket: null, // 工具进程的TCP连接,稍后由工具进程注册
|
||||||
lastHeartbeat: null,
|
// lastHeartbeat: null,
|
||||||
command,
|
command,
|
||||||
|
args,
|
||||||
env,
|
env,
|
||||||
workerId,
|
workerId,
|
||||||
}
|
}
|
||||||
@@ -388,8 +389,11 @@ function getWorkersStatus() {
|
|||||||
status: workerInfo.status,
|
status: workerInfo.status,
|
||||||
uptime: Date.now() - workerInfo.startTime,
|
uptime: Date.now() - workerInfo.startTime,
|
||||||
restartCount: workerInfo.restartCount || 0,
|
restartCount: workerInfo.restartCount || 0,
|
||||||
connected: workerInfo.socket !== null && !workerInfo.socket.destroyed,
|
// connected: workerInfo.socket !== null && !workerInfo.socket.destroyed,
|
||||||
lastHeartbeat: workerInfo.lastHeartbeat
|
// lastHeartbeat: workerInfo.lastHeartbeat,
|
||||||
|
command: workerInfo.command,
|
||||||
|
args: workerInfo.args,
|
||||||
|
pid: workerInfo.process?.pid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
@@ -129,16 +129,6 @@ export function sendToDaemon(message, {
|
|||||||
// sendToDaemon({ type: 'start-worker', workerId, command, args, env });
|
// sendToDaemon({ type: 'start-worker', workerId, command, args, env });
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// // IPC处理:停止工具进程
|
|
||||||
// ipcMain.on('stop-worker', (event, workerId) => {
|
|
||||||
// sendToDaemon({ type: 'stop-worker', workerId });
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // IPC处理:获取所有工具进程状态
|
|
||||||
// ipcMain.on('get-workers-status', () => {
|
|
||||||
// sendToDaemon({ type: 'get-status' });
|
|
||||||
// });
|
|
||||||
|
|
||||||
app.on('window-all-closed', () => {
|
app.on('window-all-closed', () => {
|
||||||
if (daemonClient) {
|
if (daemonClient) {
|
||||||
daemonClient.destroy();
|
daemonClient.destroy();
|
||||||
@@ -149,4 +139,4 @@ app.on('before-quit', () => {
|
|||||||
if (daemonClient) {
|
if (daemonClient) {
|
||||||
daemonClient.destroy();
|
daemonClient.destroy();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -423,6 +423,31 @@ export default function initIpc() {
|
|||||||
mainWindow?.webContents.send('read-no-reply-auto-reminder-stopped')
|
mainWindow?.webContents.send('read-no-reply-auto-reminder-stopped')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('get-task-manager-list', async () => {
|
||||||
|
const result = await sendToDaemon(
|
||||||
|
{
|
||||||
|
type: 'get-status'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
needCallback: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
|
||||||
|
// IPC处理:停止工具进程
|
||||||
|
ipcMain.handle('stop-task', async (_, workerId) => {
|
||||||
|
await sendToDaemon(
|
||||||
|
{
|
||||||
|
type: 'stop-worker',
|
||||||
|
workerId
|
||||||
|
},
|
||||||
|
{
|
||||||
|
needCallback: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
let subProcessOfBossZhipinLoginPageWithPreloadExtension: ChildProcess | null = null
|
let subProcessOfBossZhipinLoginPageWithPreloadExtension: ChildProcess | null = null
|
||||||
ipcMain.on('launch-bosszhipin-login-page-with-preload-extension', async () => {
|
ipcMain.on('launch-bosszhipin-login-page-with-preload-extension', async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
<template>
|
||||||
|
<div class="task-item" flex>
|
||||||
|
<div>
|
||||||
|
<img height="160" width="256" />
|
||||||
|
</div>
|
||||||
|
<div ml-40px>
|
||||||
|
<dl>
|
||||||
|
<dt>workerId</dt>
|
||||||
|
<dd>{{ task.workerId }}</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt>status</dt>
|
||||||
|
<dd>{{ task.status }}</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt>重启次数</dt>
|
||||||
|
<dd>{{ task.restartCount }}</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt>已运行时间</dt>
|
||||||
|
<dd>{{ task.uptime ?? '-' }} 毫秒</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt>命令行</dt>
|
||||||
|
<dd>{{ task.command }} {{ task.args.join(' ') }}</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt>PID</dt>
|
||||||
|
<dd>{{ task.pid }}</dd>
|
||||||
|
</dl>
|
||||||
|
<el-button type="danger" @click="stopTask(task.workerId)">结束任务</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { PropType } from 'vue'
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
task: {
|
||||||
|
type: Object as PropType<any>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const { ipcRenderer } = electron
|
||||||
|
const stopTask = async (workerId: string) => {
|
||||||
|
await ipcRenderer.invoke('stop-task', workerId)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.task-item {
|
||||||
|
font-size: 14px;
|
||||||
|
overflow: hidden;
|
||||||
|
dl {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
dt {
|
||||||
|
width: 6em;
|
||||||
|
flex: 0 0 6em;
|
||||||
|
}
|
||||||
|
dd {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div v-for="task in runningTasks" :key="task.workerId">
|
||||||
|
<div>
|
||||||
|
<TaskManagerItem :task="task" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useTaskManagerStore } from '@renderer/store'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import TaskManagerItem from './Item.vue'
|
||||||
|
|
||||||
|
const taskManagerStore = useTaskManagerStore()
|
||||||
|
const runningTasks = computed(() => taskManagerStore.runningTasks?.workers || [])
|
||||||
|
</script>
|
||||||
@@ -1,53 +1,29 @@
|
|||||||
<template><RouterView :status="currentStatus" /></template>
|
<template><RouterView :status="currentStatus" /></template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ElMessage } from 'element-plus'
|
import { ref, onMounted } from 'vue'
|
||||||
import { ref, onMounted, onUnmounted } from 'vue'
|
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { ipcRenderer } = electron
|
|
||||||
|
|
||||||
const currentStatus = ref('')
|
const currentStatus = ref('')
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const promise = Promise.resolve()
|
switch (route.query.flow) {
|
||||||
promise
|
case 'geek-auto-start-chat-with-boss': {
|
||||||
.then(() => {
|
router.replace({
|
||||||
switch (route.query.flow) {
|
path: '/geekAutoStartChatWithBoss/runningStatus'
|
||||||
case 'geek-auto-start-chat-with-boss': {
|
})
|
||||||
router.replace({
|
break
|
||||||
path: '/geekAutoStartChatWithBoss/runningStatus'
|
}
|
||||||
})
|
case 'read-no-reply-reminder': {
|
||||||
break
|
router.replace({
|
||||||
}
|
path: '/geekAutoStartChatWithBoss/runningStatusForReadNoReplyReminder'
|
||||||
case 'read-no-reply-reminder': {
|
})
|
||||||
router.replace({
|
break
|
||||||
path: '/geekAutoStartChatWithBoss/runningStatusForReadNoReplyReminder'
|
}
|
||||||
})
|
default: {
|
||||||
break
|
router.replace('/')
|
||||||
}
|
}
|
||||||
default: {
|
}
|
||||||
router.replace('/')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(async (err) => {
|
|
||||||
if (err instanceof Error && err.message.includes('NEED_TO_CHECK_RUNTIME_DEPENDENCIES')) {
|
|
||||||
ElMessage.error({
|
|
||||||
message: `核心组件损坏,正在尝试修复`
|
|
||||||
})
|
|
||||||
router.replace('/')
|
|
||||||
}
|
|
||||||
console.error(err)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const needToCheckRuntimeDependenciesHandler = () => {
|
|
||||||
router.replace('/')
|
|
||||||
}
|
|
||||||
|
|
||||||
ipcRenderer.on('need-to-check-runtime-dependencies', needToCheckRuntimeDependenciesHandler)
|
|
||||||
onUnmounted(() => {
|
|
||||||
ipcRenderer.removeListener('need-to-check-runtime-dependencies', needToCheckRuntimeDependenciesHandler)
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1049,12 +1049,15 @@
|
|||||||
<el-button @click="handleSave">仅保存配置</el-button>
|
<el-button @click="handleSave">仅保存配置</el-button>
|
||||||
<el-button type="primary" @click="handleSubmit"> 保存配置,并开始求职! </el-button>
|
<el-button type="primary" @click="handleSubmit"> 保存配置,并开始求职! </el-button>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button @click="handleStopButtonClick">结束任务</el-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onBeforeUnmount, ref, watch, nextTick } from 'vue'
|
import { computed, onBeforeUnmount, ref, watch, nextTick, onUnmounted } from 'vue'
|
||||||
import { ElForm, ElMessage } from 'element-plus'
|
import { ElForm, ElMessage } from 'element-plus'
|
||||||
import { QuestionFilled } from '@element-plus/icons-vue'
|
import { QuestionFilled } from '@element-plus/icons-vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
@@ -1445,13 +1448,28 @@ const handleSubmit = async () => {
|
|||||||
delete clonedFormContent.__jobSourceList
|
delete clonedFormContent.__jobSourceList
|
||||||
await electron.ipcRenderer.invoke('save-config-file-from-ui', JSON.stringify(clonedFormContent))
|
await electron.ipcRenderer.invoke('save-config-file-from-ui', JSON.stringify(clonedFormContent))
|
||||||
mittBus.emit('auto-start-chat-with-boss-config-saved')
|
mittBus.emit('auto-start-chat-with-boss-config-saved')
|
||||||
router.replace({
|
|
||||||
path: '/geekAutoStartChatWithBoss/prepareRun',
|
|
||||||
query: { flow: 'geek-auto-start-chat-with-boss' }
|
|
||||||
})
|
|
||||||
gtagRenderer('config_saved_and_launch_auto_start_chat', {
|
gtagRenderer('config_saved_and_launch_auto_start_chat', {
|
||||||
has_dingtalk_robot_token: !!formContent.value?.dingtalkRobotAccessToken
|
has_dingtalk_robot_token: !!formContent.value?.dingtalkRobotAccessToken
|
||||||
})
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
await electron.ipcRenderer.invoke('run-geek-auto-start-chat-with-boss')
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof Error && err.message.includes('NEED_TO_CHECK_RUNTIME_DEPENDENCIES')) {
|
||||||
|
gtagRenderer('gascwb_cannot_run_for_corrupt')
|
||||||
|
ElMessage.error({
|
||||||
|
message: `核心组件损坏,正在尝试修复`
|
||||||
|
})
|
||||||
|
router.replace('/')
|
||||||
|
}
|
||||||
|
console.error(err)
|
||||||
|
gtagRenderer('gascwb_cannot_run_for_unknown_error', { err })
|
||||||
|
}
|
||||||
|
|
||||||
|
// {
|
||||||
|
// path: '/geekAutoStartChatWithBoss/prepareRun',
|
||||||
|
// query: { flow: 'geek-auto-start-chat-with-boss' }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
gtagRenderer('save_config_clicked', {
|
gtagRenderer('save_config_clicked', {
|
||||||
@@ -1803,6 +1821,22 @@ const combineRecommendJobFilterTypeOptions = [
|
|||||||
value: 2
|
value: 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const needToCheckRuntimeDependenciesHandler = () => {
|
||||||
|
router.replace('/')
|
||||||
|
}
|
||||||
|
electron.ipcRenderer.on('need-to-check-runtime-dependencies', needToCheckRuntimeDependenciesHandler)
|
||||||
|
onUnmounted(() => {
|
||||||
|
electron.ipcRenderer.removeListener(
|
||||||
|
'need-to-check-runtime-dependencies',
|
||||||
|
needToCheckRuntimeDependenciesHandler
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleStopButtonClick = async () => {
|
||||||
|
gtagRenderer('gascwb_stop_button_clicked')
|
||||||
|
electron.ipcRenderer.invoke('stop-geek-auto-start-chat-with-boss')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -219,6 +219,9 @@
|
|||||||
<el-form-item class="last-form-item">
|
<el-form-item class="last-form-item">
|
||||||
<el-button type="primary" @click="handleSubmit">开始提醒</el-button>
|
<el-button type="primary" @click="handleSubmit">开始提醒</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<div>
|
||||||
|
<el-button @click="handleStopButtonClick">结束任务</el-button>
|
||||||
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -471,10 +474,25 @@ const handleSubmit = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
gtagRenderer('run_read_no_reply_reminder_launched')
|
gtagRenderer('run_read_no_reply_reminder_launched')
|
||||||
router.replace({
|
|
||||||
path: '/geekAutoStartChatWithBoss/prepareRun',
|
try {
|
||||||
query: { flow: 'read-no-reply-reminder' }
|
await electron.ipcRenderer.invoke('run-read-no-reply-auto-reminder')
|
||||||
})
|
} catch (err) {
|
||||||
|
if (err instanceof Error && err.message.includes('NEED_TO_CHECK_RUNTIME_DEPENDENCIES')) {
|
||||||
|
gtagRenderer('rnrr_cannot_run_for_corrupt')
|
||||||
|
ElMessage.error({
|
||||||
|
message: `核心组件损坏,正在尝试修复`
|
||||||
|
})
|
||||||
|
router.replace('/')
|
||||||
|
}
|
||||||
|
console.error(err)
|
||||||
|
gtagRenderer('rnrr_cannot_run_for_unknown_error', { err })
|
||||||
|
}
|
||||||
|
|
||||||
|
// {
|
||||||
|
// path: '/geekAutoStartChatWithBoss/prepareRun',
|
||||||
|
// query: { flow: 'read-no-reply-reminder' }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
function handleThrottleIntervalMinutesBlur() {
|
function handleThrottleIntervalMinutesBlur() {
|
||||||
if (formContent.value.autoReminder.throttleIntervalMinutes < 3) {
|
if (formContent.value.autoReminder.throttleIntervalMinutes < 3) {
|
||||||
@@ -559,6 +577,22 @@ async function handleTestEffectClicked() {
|
|||||||
autoReminderConfig: JSON.parse(JSON.stringify(formContent.value.autoReminder))
|
autoReminderConfig: JSON.parse(JSON.stringify(formContent.value.autoReminder))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const needToCheckRuntimeDependenciesHandler = () => {
|
||||||
|
router.replace('/')
|
||||||
|
}
|
||||||
|
electron.ipcRenderer.on('need-to-check-runtime-dependencies', needToCheckRuntimeDependenciesHandler)
|
||||||
|
onUnmounted(() => {
|
||||||
|
electron.ipcRenderer.removeListener(
|
||||||
|
'need-to-check-runtime-dependencies',
|
||||||
|
needToCheckRuntimeDependenciesHandler
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleStopButtonClick = async () => {
|
||||||
|
gtagRenderer('rnrr_stop_button_clicked')
|
||||||
|
electron.ipcRenderer.invoke('stop-read-no-reply-auto-reminder')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<template>
|
||||||
|
<TaskManagerList />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import TaskManagerList from '../../features/TaskManager/List.vue'
|
||||||
|
</script>
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
<div class="flex h100vh">
|
<div class="flex h100vh">
|
||||||
<div class="flex flex-col min-w200px w200px pt30px pl30px aside-nav of-hidden">
|
<div class="flex flex-col min-w200px w200px pt30px pl30px aside-nav of-hidden">
|
||||||
<div class="nav-list flex-1 of-auto">
|
<div class="nav-list flex-1 of-auto">
|
||||||
|
<RouterLink to="./TaskManager">任务管理</RouterLink>
|
||||||
<RouterLink to="./GeekAutoStartChatWithBoss">
|
<RouterLink to="./GeekAutoStartChatWithBoss">
|
||||||
Boss炸弹
|
Boss炸弹
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
@@ -136,7 +137,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<RouterView v-slot="{ Component }" class="flex-1">
|
<RouterView v-slot="{ Component }" class="flex-1 of-hidden">
|
||||||
<KeepAlive>
|
<KeepAlive>
|
||||||
<component :is="Component" />
|
<component :is="Component" />
|
||||||
</KeepAlive>
|
</KeepAlive>
|
||||||
@@ -151,7 +152,7 @@ import { TopRight, QuestionFilled } from '@element-plus/icons-vue'
|
|||||||
import useBuildInfo from '@renderer/hooks/useBuildInfo'
|
import useBuildInfo from '@renderer/hooks/useBuildInfo'
|
||||||
import { debounce } from 'lodash-es'
|
import { debounce } from 'lodash-es'
|
||||||
import { gtagRenderer } from '@renderer/utils/gtag'
|
import { gtagRenderer } from '@renderer/utils/gtag'
|
||||||
import { useUpdateStore } from '../../store/index'
|
import { useUpdateStore, useTaskManagerStore } from '../../store/index'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const unmountedCbs: Array<InstanceType<typeof Function>> = []
|
const unmountedCbs: Array<InstanceType<typeof Function>> = []
|
||||||
@@ -217,6 +218,9 @@ function handleViewNewReleaseClick() {
|
|||||||
gtagRenderer('click_view_release_form_nav')
|
gtagRenderer('click_view_release_form_nav')
|
||||||
electron.ipcRenderer.send('open-external-link', updateStore.availableNewRelease!.releasePageUrl)
|
electron.ipcRenderer.send('open-external-link', updateStore.availableNewRelease!.releasePageUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const taskManagerStore = useTaskManagerStore()
|
||||||
|
void taskManagerStore
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -43,6 +43,13 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
component: () => import('@renderer/page/MainLayout/index.vue'),
|
component: () => import('@renderer/page/MainLayout/index.vue'),
|
||||||
redirect: '/main-layout/GeekAutoStartChatWithBoss',
|
redirect: '/main-layout/GeekAutoStartChatWithBoss',
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
path: 'taskManager',
|
||||||
|
component: () => import('@renderer/page/MainLayout/TaskManager.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '任务管理'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'GeekAutoStartChatWithBoss',
|
path: 'GeekAutoStartChatWithBoss',
|
||||||
component: () => import('@renderer/page/MainLayout/GeekAutoStartChatWithBoss/index.vue'),
|
component: () => import('@renderer/page/MainLayout/GeekAutoStartChatWithBoss/index.vue'),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { NewReleaseInfo } from '../../../common/types/update'
|
import { NewReleaseInfo } from '../../../common/types/update'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
import { throttle } from 'lodash-es'
|
||||||
|
|
||||||
export const useUpdateStore = defineStore('update', () => {
|
export const useUpdateStore = defineStore('update', () => {
|
||||||
const availableNewRelease = ref<NewReleaseInfo | null>(null)
|
const availableNewRelease = ref<NewReleaseInfo | null>(null)
|
||||||
@@ -18,3 +19,16 @@ export const useUpdateStore = defineStore('update', () => {
|
|||||||
setInterval(checkUpdate, 30 * 30 * 1000)
|
setInterval(checkUpdate, 30 * 30 * 1000)
|
||||||
return { availableNewRelease }
|
return { availableNewRelease }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const useTaskManagerStore = defineStore('taskManager', () => {
|
||||||
|
const runningTasks = ref<unknown[]>([])
|
||||||
|
function getRunningTasks() {
|
||||||
|
const { ipcRenderer } = electron
|
||||||
|
ipcRenderer.invoke('get-task-manager-list').then(res => {
|
||||||
|
runningTasks.value = res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const throttledGetRunningTasks = throttle(getRunningTasks, 2000)
|
||||||
|
setInterval(throttledGetRunningTasks, 2 * 1000)
|
||||||
|
return { runningTasks, getRunningTasks: throttledGetRunningTasks }
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user