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

View File

@@ -17,3 +17,9 @@ export enum RECHAT_LLM_FALLBACK {
SEND_LOOK_FORWARD_EMOTION = 1,
EXIT_REMINDER_PROGRAM = 2
}
export enum RUNNING_STATUS_ENUM {
RUNNING = 0,
NORMAL_EXITED = 1,
ERROR_EXITED = 2
}

View File

@@ -197,22 +197,7 @@ export default function initIpc() {
return
}
if (message.type === 'worker-exited') {
switch(message.code) {
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
}
}
mainWindow?.webContents.send('worker-exited', message)
}
})
return { runRecordId }
@@ -226,22 +211,7 @@ export default function initIpc() {
return
}
if (message.type === 'worker-exited') {
switch(message.code) {
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
}
}
mainWindow?.webContents.send('worker-exited', message)
}
})
return { runRecordId }

View File

@@ -9,7 +9,15 @@
<!-- v-if="stepsForRender.some(it => ['todo', 'pending', 'rejected'].includes(it.status))" -->
<div>
<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>
<span v-if="item.status === 'todo'">🕐</span>
<span v-if="item.status === 'pending'">👉</span>
@@ -21,18 +29,24 @@
</ul>
</div>
<div flex justify-between items-center w-full>
<div>任务运行中</div>
<div>
<slot name="op-buttons" />
{{ runningStatusTextMapByCode[currentRunningStatus] }}
</div>
<div>
<slot name="op-buttons" :current-running-status="currentRunningStatus" />
</div>
</div>
</el-dialog>
</template>
<script lang="ts" setup>
import { useTaskManagerStore } from '@renderer/store'
// import { useTaskManagerStore } from '@renderer/store'
import { getAutoStartChatSteps } from '../../../../common/prerequisite-step-by-step-check'
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({
workerId: {
type: String
@@ -41,43 +55,42 @@ const props = defineProps({
type: Number
}
})
const taskManagerStore = useTaskManagerStore()
const runingTaskInfo = computed(() => {
return taskManagerStore.runningTasks?.find(it => {
return it.workerId === props.workerId
})
})
// const taskManagerStore = useTaskManagerStore()
// const runingTaskInfo = computed(() => {
// return taskManagerStore.runningTasks?.find((it) => {
// return it.workerId === props.workerId
// })
// })
const steps = ref([])
const stepsForRender = computed(() => {
const clonedSteps = JSON.parse(
JSON.stringify(steps.value)
)
if (clonedSteps.some(it => it.status === 'rejected')) {
const clonedSteps = JSON.parse(JSON.stringify(steps.value))
if (clonedSteps.some((it) => it.status === 'rejected')) {
return clonedSteps
}
const lastFulfilledIndex = clonedSteps.findLastIndex(it => it.status === 'fulfilled')
const lastFulfilledIndex = clonedSteps.findLastIndex((it) => it.status === 'fulfilled')
if (lastFulfilledIndex + 1 < clonedSteps.length) {
clonedSteps[lastFulfilledIndex + 1].status = 'pending'
}
return clonedSteps
})
function fillEmptySteps () {
const arr = getAutoStartChatSteps()
arr.forEach(it => it.status = 'todo')
steps.value = arr
const runningStatusTextMapByCode = {
[RUNNING_STATUS_ENUM.RUNNING]: '正在运行中',
[RUNNING_STATUS_ENUM.NORMAL_EXITED]: '程序已正常退出',
[RUNNING_STATUS_ENUM.ERROR_EXITED]: '程序异常退出'
}
watch(
() => props.runRecordId,
fillEmptySteps,
{
immediate: true
}
)
const currentRunningStatus = ref(RUNNING_STATUS_ENUM.RUNNING)
function fillEmptySteps() {
const arr = getAutoStartChatSteps()
arr.forEach((it) => (it.status = 'todo'))
steps.value = arr
currentRunningStatus.value = RUNNING_STATUS_ENUM.RUNNING
}
watch(() => props.runRecordId, fillEmptySteps, {
immediate: true
})
const { ipcRenderer } = electron
function messageHandler (ev, { data }) {
function messageHandler(ev, { data }) {
if (
data.type !== 'prerequisite-step-by-step-checkstep-by-step-check' ||
data.runRecordId !== props.runRecordId
@@ -85,7 +98,7 @@ function messageHandler (ev, { data }) {
return
}
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) {
return
}
@@ -95,12 +108,28 @@ const unListenMessage = ipcRenderer.on('worker-to-gui-message', messageHandler)
onUnmounted(unListenMessage)
const isDialogVisible = ref(false)
const show = () => {
isDialogVisible.value = true
}
const hide = () => {
isDialogVisible.value = false
}
defineExpose({
show() {
isDialogVisible.value = true
},
hide() {
isDialogVisible.value = false
show,
hide
})
ipcRenderer.on('worker-exited', (ev, payload) => {
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>
@@ -115,7 +144,7 @@ defineExpose({
background-color: transparent;
background-image: radial-gradient(transparent 1px, #fff 1px);
background-size: 4px 4px;
.el-overlay-dialog {
position: absolute;
pointer-events: all;
@@ -134,4 +163,4 @@ defineExpose({
}
}
}
</style>
</style>

View File

@@ -1121,14 +1121,29 @@
worker-id="geekAutoStartWithBossMain"
:run-record-id="runRecordId"
>
<template #op-buttons>
<el-button
type="danger"
plain
:loading="isStopButtonLoading"
@click="handleStopButtonClick"
>结束任务</el-button
>
<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>
</RuningOverlay>
</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 expectJobFilterTemplateList from './expectJobFilterTemplateList'
import RuningOverlay from '@renderer/features/RunningOverlay/index.vue'
import { RUNNING_STATUS_ENUM } from '../../../../../common/enums/auto-start-chat'
const gtagRenderer = (name, params?: object) => {
return baseGtagRenderer(name, {

View File

@@ -236,9 +236,34 @@
pointerEvents: 'none'
}"
>
<RuningOverlay worker-id="geekAutoStartWithBossMain" :run-record-id="runRecordId" ref="runningOverlayRef">
<template #op-buttons>
<el-button type="danger" plain @click="handleStopButtonClick" :loading="isStopButtonLoading">结束任务</el-button>
<RuningOverlay
ref="runningOverlayRef"
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>
</RuningOverlay>
</div>
@@ -251,7 +276,8 @@ import { dayjs, ElForm, ElMessage, ElMessageBox, ElSelect, ElOption } from 'elem
import { useRouter } from 'vue-router'
import {
RECHAT_CONTENT_SOURCE,
RECHAT_LLM_FALLBACK
RECHAT_LLM_FALLBACK,
RUNNING_STATUS_ENUM
} from '../../../../common/enums/auto-start-chat'
import { gtagRenderer as baseGtagRenderer } from '@renderer/utils/gtag'
import mittBus from '../../utils/mitt'
@@ -498,7 +524,9 @@ const handleSubmit = async () => {
try {
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
} catch (err) {
if (err instanceof Error && err.message.includes('NEED_TO_CHECK_RUNTIME_DEPENDENCIES')) {
@@ -639,8 +667,7 @@ const handleStopButtonClick = async () => {
try {
electron.ipcRenderer.invoke('stop-read-no-reply-auto-reminder')
runningOverlayRef.value?.hide()
}
finally {
} finally {
isStopButtonLoading.value = false
}
}