fix when worker process exited, ui no reflection

This commit is contained in:
geekgeekrun
2026-02-08 18:22:12 +08:00
parent 3eeea2e5c7
commit c298904d25
5 changed files with 132 additions and 84 deletions
@@ -17,3 +17,9 @@ export enum RECHAT_LLM_FALLBACK {
SEND_LOOK_FORWARD_EMOTION = 1, SEND_LOOK_FORWARD_EMOTION = 1,
EXIT_REMINDER_PROGRAM = 2 EXIT_REMINDER_PROGRAM = 2
} }
export enum RUNNING_STATUS_ENUM {
RUNNING = 0,
NORMAL_EXITED = 1,
ERROR_EXITED = 2
}
@@ -197,22 +197,7 @@ export default function initIpc() {
return return
} }
if (message.type === 'worker-exited') { if (message.type === 'worker-exited') {
switch(message.code) { mainWindow?.webContents.send('worker-exited', message)
case AUTO_CHAT_ERROR_EXIT_CODE.PUPPETEER_IS_NOT_EXECUTABLE: {
mainWindow?.webContents.send('need-to-check-runtime-dependencies')
daemonEE.off('message', handler)
break
}
case AUTO_CHAT_ERROR_EXIT_CODE.LOGIN_STATUS_INVALID: {
mainWindow?.webContents.send('check-boss-zhipin-cookie-file')
daemonEE.off('message', handler)
break
}
case AUTO_CHAT_ERROR_EXIT_CODE.NORMAL: {
daemonEE.off('message', handler)
break
}
}
} }
}) })
return { runRecordId } return { runRecordId }
@@ -226,22 +211,7 @@ export default function initIpc() {
return return
} }
if (message.type === 'worker-exited') { if (message.type === 'worker-exited') {
switch(message.code) { mainWindow?.webContents.send('worker-exited', message)
case AUTO_CHAT_ERROR_EXIT_CODE.PUPPETEER_IS_NOT_EXECUTABLE: {
mainWindow?.webContents.send('need-to-check-runtime-dependencies')
daemonEE.off('message', handler)
break
}
case AUTO_CHAT_ERROR_EXIT_CODE.LOGIN_STATUS_INVALID: {
mainWindow?.webContents.send('check-boss-zhipin-cookie-file')
daemonEE.off('message', handler)
break
}
case AUTO_CHAT_ERROR_EXIT_CODE.NORMAL: {
daemonEE.off('message', handler)
break
}
}
} }
}) })
return { runRecordId } return { runRecordId }
@@ -9,7 +9,15 @@
<!-- v-if="stepsForRender.some(it => ['todo', 'pending', 'rejected'].includes(it.status))" --> <!-- v-if="stepsForRender.some(it => ['todo', 'pending', 'rejected'].includes(it.status))" -->
<div> <div>
<ul m0 pl0> <ul m0 pl0>
<li list-style-none v-for="item in stepsForRender" flex justify-start pt4px pb4px> <li
v-for="(item, index) in stepsForRender"
:key="index"
list-style-none
flex
justify-start
pt4px
pb4px
>
<div> <div>
<span v-if="item.status === 'todo'">🕐</span> <span v-if="item.status === 'todo'">🕐</span>
<span v-if="item.status === 'pending'">👉</span> <span v-if="item.status === 'pending'">👉</span>
@@ -21,18 +29,24 @@
</ul> </ul>
</div> </div>
<div flex justify-between items-center w-full> <div flex justify-between items-center w-full>
<div>任务运行中</div>
<div> <div>
<slot name="op-buttons" /> {{ runningStatusTextMapByCode[currentRunningStatus] }}
</div>
<div>
<slot name="op-buttons" :current-running-status="currentRunningStatus" />
</div> </div>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { useTaskManagerStore } from '@renderer/store' // import { useTaskManagerStore } from '@renderer/store'
import { getAutoStartChatSteps } from '../../../../common/prerequisite-step-by-step-check' import { getAutoStartChatSteps } from '../../../../common/prerequisite-step-by-step-check'
import { computed, onUnmounted, ref, watch } from 'vue' import { computed, onUnmounted, ref, watch } from 'vue'
import {
AUTO_CHAT_ERROR_EXIT_CODE,
RUNNING_STATUS_ENUM
} from '../../../../common/enums/auto-start-chat'
const props = defineProps({ const props = defineProps({
workerId: { workerId: {
type: String type: String
@@ -41,43 +55,42 @@ const props = defineProps({
type: Number type: Number
} }
}) })
const taskManagerStore = useTaskManagerStore() // const taskManagerStore = useTaskManagerStore()
const runingTaskInfo = computed(() => { // const runingTaskInfo = computed(() => {
return taskManagerStore.runningTasks?.find(it => { // return taskManagerStore.runningTasks?.find((it) => {
return it.workerId === props.workerId // return it.workerId === props.workerId
}) // })
}) // })
const steps = ref([]) const steps = ref([])
const stepsForRender = computed(() => { const stepsForRender = computed(() => {
const clonedSteps = JSON.parse( const clonedSteps = JSON.parse(JSON.stringify(steps.value))
JSON.stringify(steps.value) if (clonedSteps.some((it) => it.status === 'rejected')) {
)
if (clonedSteps.some(it => it.status === 'rejected')) {
return clonedSteps return clonedSteps
} }
const lastFulfilledIndex = clonedSteps.findLastIndex(it => it.status === 'fulfilled') const lastFulfilledIndex = clonedSteps.findLastIndex((it) => it.status === 'fulfilled')
if (lastFulfilledIndex + 1 < clonedSteps.length) { if (lastFulfilledIndex + 1 < clonedSteps.length) {
clonedSteps[lastFulfilledIndex + 1].status = 'pending' clonedSteps[lastFulfilledIndex + 1].status = 'pending'
} }
return clonedSteps return clonedSteps
}) })
function fillEmptySteps () { const runningStatusTextMapByCode = {
const arr = getAutoStartChatSteps() [RUNNING_STATUS_ENUM.RUNNING]: '正在运行中',
arr.forEach(it => it.status = 'todo') [RUNNING_STATUS_ENUM.NORMAL_EXITED]: '程序已正常退出',
steps.value = arr [RUNNING_STATUS_ENUM.ERROR_EXITED]: '程序异常退出'
} }
watch( const currentRunningStatus = ref(RUNNING_STATUS_ENUM.RUNNING)
() => props.runRecordId, function fillEmptySteps() {
fillEmptySteps, const arr = getAutoStartChatSteps()
{ arr.forEach((it) => (it.status = 'todo'))
immediate: true steps.value = arr
} currentRunningStatus.value = RUNNING_STATUS_ENUM.RUNNING
) }
watch(() => props.runRecordId, fillEmptySteps, {
immediate: true
})
const { ipcRenderer } = electron const { ipcRenderer } = electron
function messageHandler(ev, { data }) {
function messageHandler (ev, { data }) {
if ( if (
data.type !== 'prerequisite-step-by-step-checkstep-by-step-check' || data.type !== 'prerequisite-step-by-step-checkstep-by-step-check' ||
data.runRecordId !== props.runRecordId data.runRecordId !== props.runRecordId
@@ -85,7 +98,7 @@ function messageHandler (ev, { data }) {
return return
} }
const { id: stepId, status: stepStatus } = data.step const { id: stepId, status: stepStatus } = data.step
const targetStep = steps.value.find(it => it.id === stepId) const targetStep = steps.value.find((it) => it.id === stepId)
if (!targetStep) { if (!targetStep) {
return return
} }
@@ -95,12 +108,28 @@ const unListenMessage = ipcRenderer.on('worker-to-gui-message', messageHandler)
onUnmounted(unListenMessage) onUnmounted(unListenMessage)
const isDialogVisible = ref(false) const isDialogVisible = ref(false)
const show = () => {
isDialogVisible.value = true
}
const hide = () => {
isDialogVisible.value = false
}
defineExpose({ defineExpose({
show() { show,
isDialogVisible.value = true hide
}, })
hide() { ipcRenderer.on('worker-exited', (ev, payload) => {
isDialogVisible.value = false const { workerId, code } = payload
if (
workerId !== props.workerId
// || runRecordId !== props.runRecordId
) {
return
}
if (code !== AUTO_CHAT_ERROR_EXIT_CODE.NORMAL) {
currentRunningStatus.value = RUNNING_STATUS_ENUM.ERROR_EXITED
} else {
currentRunningStatus.value = RUNNING_STATUS_ENUM.NORMAL_EXITED
} }
}) })
</script> </script>
@@ -115,7 +144,7 @@ defineExpose({
background-color: transparent; background-color: transparent;
background-image: radial-gradient(transparent 1px, #fff 1px); background-image: radial-gradient(transparent 1px, #fff 1px);
background-size: 4px 4px; background-size: 4px 4px;
.el-overlay-dialog { .el-overlay-dialog {
position: absolute; position: absolute;
pointer-events: all; pointer-events: all;
@@ -134,4 +163,4 @@ defineExpose({
} }
} }
} }
</style> </style>
@@ -1121,14 +1121,29 @@
worker-id="geekAutoStartWithBossMain" worker-id="geekAutoStartWithBossMain"
:run-record-id="runRecordId" :run-record-id="runRecordId"
> >
<template #op-buttons> <template #op-buttons="{ currentRunningStatus }">
<el-button <div>
type="danger" <template v-if="currentRunningStatus === RUNNING_STATUS_ENUM.RUNNING">
plain <el-button
:loading="isStopButtonLoading" type="danger"
@click="handleStopButtonClick" plain
>结束任务</el-button :loading="isStopButtonLoading"
> @click="handleStopButtonClick"
>结束任务</el-button
>
</template>
<template v-else>
<el-button
type="primary"
@click="
() => {
runningOverlayRef?.hide?.()
}
"
>关闭</el-button
>
</template>
</div>
</template> </template>
</RuningOverlay> </RuningOverlay>
</div> </div>
@@ -1165,6 +1180,7 @@ import conditions from '@geekgeekrun/geek-auto-start-chat-with-boss/internal-con
import JobSourceDragOrderer from '../../../features/JobSourceDragOrderer/index.vue' import JobSourceDragOrderer from '../../../features/JobSourceDragOrderer/index.vue'
import expectJobFilterTemplateList from './expectJobFilterTemplateList' import expectJobFilterTemplateList from './expectJobFilterTemplateList'
import RuningOverlay from '@renderer/features/RunningOverlay/index.vue' import RuningOverlay from '@renderer/features/RunningOverlay/index.vue'
import { RUNNING_STATUS_ENUM } from '../../../../../common/enums/auto-start-chat'
const gtagRenderer = (name, params?: object) => { const gtagRenderer = (name, params?: object) => {
return baseGtagRenderer(name, { return baseGtagRenderer(name, {
@@ -236,9 +236,34 @@
pointerEvents: 'none' pointerEvents: 'none'
}" }"
> >
<RuningOverlay worker-id="geekAutoStartWithBossMain" :run-record-id="runRecordId" ref="runningOverlayRef"> <RuningOverlay
<template #op-buttons> ref="runningOverlayRef"
<el-button type="danger" plain @click="handleStopButtonClick" :loading="isStopButtonLoading">结束任务</el-button> worker-id="readNoReplyAutoReminderMain"
:run-record-id="runRecordId"
>
<template #op-buttons="{ currentRunningStatus }">
<div>
<template v-if="currentRunningStatus === RUNNING_STATUS_ENUM.RUNNING">
<el-button
type="danger"
plain
:loading="isStopButtonLoading"
@click="handleStopButtonClick"
>结束任务</el-button
>
</template>
<template v-else>
<el-button
type="primary"
@click="
() => {
runningOverlayRef?.hide?.()
}
"
>关闭</el-button
>
</template>
</div>
</template> </template>
</RuningOverlay> </RuningOverlay>
</div> </div>
@@ -251,7 +276,8 @@ import { dayjs, ElForm, ElMessage, ElMessageBox, ElSelect, ElOption } from 'elem
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { import {
RECHAT_CONTENT_SOURCE, RECHAT_CONTENT_SOURCE,
RECHAT_LLM_FALLBACK RECHAT_LLM_FALLBACK,
RUNNING_STATUS_ENUM
} from '../../../../common/enums/auto-start-chat' } from '../../../../common/enums/auto-start-chat'
import { gtagRenderer as baseGtagRenderer } from '@renderer/utils/gtag' import { gtagRenderer as baseGtagRenderer } from '@renderer/utils/gtag'
import mittBus from '../../utils/mitt' import mittBus from '../../utils/mitt'
@@ -498,7 +524,9 @@ const handleSubmit = async () => {
try { try {
runningOverlayRef.value?.show() runningOverlayRef.value?.show()
const { runRecordId: rrId } = await electron.ipcRenderer.invoke('run-read-no-reply-auto-reminder') const { runRecordId: rrId } = await electron.ipcRenderer.invoke(
'run-read-no-reply-auto-reminder'
)
runRecordId.value = rrId runRecordId.value = rrId
} catch (err) { } catch (err) {
if (err instanceof Error && err.message.includes('NEED_TO_CHECK_RUNTIME_DEPENDENCIES')) { if (err instanceof Error && err.message.includes('NEED_TO_CHECK_RUNTIME_DEPENDENCIES')) {
@@ -639,8 +667,7 @@ const handleStopButtonClick = async () => {
try { try {
electron.ipcRenderer.invoke('stop-read-no-reply-auto-reminder') electron.ipcRenderer.invoke('stop-read-no-reply-auto-reminder')
runningOverlayRef.value?.hide() runningOverlayRef.value?.hide()
} } finally {
finally {
isStopButtonLoading.value = false isStopButtonLoading.value = false
} }
} }