feat: Unified runtime environment status (#7978)

This commit is contained in:
zhengkunwang 2025-02-24 17:20:07 +08:00 committed by GitHub
parent ff32281257
commit e6c1094c08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 222 additions and 234 deletions

View file

@ -8,26 +8,27 @@ import (
) )
type RuntimeDTO struct { type RuntimeDTO struct {
ID uint `json:"id"` ID uint `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Resource string `json:"resource"` Resource string `json:"resource"`
AppDetailID uint `json:"appDetailID"` AppDetailID uint `json:"appDetailID"`
AppID uint `json:"appID"` AppID uint `json:"appID"`
Source string `json:"source"` Source string `json:"source"`
Status string `json:"status"` Status string `json:"status"`
Type string `json:"type"` Type string `json:"type"`
Image string `json:"image"` Image string `json:"image"`
Params map[string]interface{} `json:"params"` Params map[string]interface{} `json:"params"`
Message string `json:"message"` Message string `json:"message"`
Version string `json:"version"` Version string `json:"version"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
CodeDir string `json:"codeDir"` CodeDir string `json:"codeDir"`
AppParams []AppParam `json:"appParams"` AppParams []AppParam `json:"appParams"`
Port string `json:"port"` Port string `json:"port"`
Path string `json:"path"` Path string `json:"path"`
ExposedPorts []request.ExposedPort `json:"exposedPorts"` ExposedPorts []request.ExposedPort `json:"exposedPorts"`
Environments []request.Environment `json:"environments"` Environments []request.Environment `json:"environments"`
Volumes []request.Volume `json:"volumes"` Volumes []request.Volume `json:"volumes"`
ContainerStatus string `json:"containerStatus"`
} }
type PackageScripts struct { type PackageScripts struct {

View file

@ -119,7 +119,7 @@ func handleRuntimeRecover(runtime *model.Runtime, recoverFile string, isRollback
} }
oldRuntime.ID = runtime.ID oldRuntime.ID = runtime.ID
oldRuntime.Status = constant.RuntimeStarting oldRuntime.Status = constant.StatusStarting
if err := runtimeRepo.Save(&oldRuntime); err != nil { if err := runtimeRepo.Save(&oldRuntime); err != nil {
global.LOG.Errorf("save db app install failed, err: %v", err) global.LOG.Errorf("save db app install failed, err: %v", err)
return err return err

View file

@ -102,7 +102,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
Resource: create.Resource, Resource: create.Resource,
Type: create.Type, Type: create.Type,
Version: create.Version, Version: create.Version,
Status: constant.RuntimeNormal, Status: constant.StatusNormal,
} }
return nil, runtimeRepo.Create(context.Background(), runtime) return nil, runtimeRepo.Create(context.Background(), runtime)
} }
@ -196,14 +196,17 @@ func (r *RuntimeService) Page(req request.RuntimeSearch) (int64, []response.Runt
if err != nil { if err != nil {
return 0, nil, err return 0, nil, err
} }
if err = SyncRuntimesStatus(runtimes); err != nil {
return 0, nil, err
}
for _, runtime := range runtimes { for _, runtime := range runtimes {
runtimeDTO := response.NewRuntimeDTO(runtime) runtimeDTO := response.NewRuntimeDTO(runtime)
runtimeDTO.Params = make(map[string]interface{}) runtimeDTO.Params = make(map[string]interface{})
envs, err := gotenv.Unmarshal(runtime.Env) envMap, err := gotenv.Unmarshal(runtime.Env)
if err != nil { if err != nil {
return 0, nil, err return 0, nil, err
} }
for k, v := range envs { for k, v := range envMap {
runtimeDTO.Params[k] = v runtimeDTO.Params[k] = v
} }
res = append(res, runtimeDTO) res = append(res, runtimeDTO)
@ -498,7 +501,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
switch runtime.Type { switch runtime.Type {
case constant.RuntimePHP: case constant.RuntimePHP:
runtime.Image = req.Image runtime.Image = req.Image
runtime.Status = constant.RuntimeBuildIng runtime.Status = constant.StatusBuilding
_ = runtimeRepo.Save(runtime) _ = runtimeRepo.Save(runtime)
client, err := docker.NewClient() client, err := docker.NewClient()
if err != nil { if err != nil {
@ -514,7 +517,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
runtime.Version = req.Version runtime.Version = req.Version
runtime.CodeDir = req.CodeDir runtime.CodeDir = req.CodeDir
runtime.Port = strings.Join(hostPorts, ",") runtime.Port = strings.Join(hostPorts, ",")
runtime.Status = constant.RuntimeReCreating runtime.Status = constant.StatusReCreating
_ = runtimeRepo.Save(runtime) _ = runtimeRepo.Save(runtime)
go reCreateRuntime(runtime) go reCreateRuntime(runtime)
} }
@ -559,7 +562,7 @@ func (r *RuntimeService) OperateRuntime(req request.RuntimeOperate) error {
} }
defer func() { defer func() {
if err != nil { if err != nil {
runtime.Status = constant.RuntimeError runtime.Status = constant.StatusError
runtime.Message = err.Error() runtime.Message = err.Error()
_ = runtimeRepo.Save(runtime) _ = runtimeRepo.Save(runtime)
} }
@ -576,7 +579,7 @@ func (r *RuntimeService) OperateRuntime(req request.RuntimeOperate) error {
if err = runComposeCmdWithLog(req.Operate, runtime.GetComposePath(), runtime.GetLogPath()); err != nil { if err = runComposeCmdWithLog(req.Operate, runtime.GetComposePath(), runtime.GetLogPath()); err != nil {
return err return err
} }
runtime.Status = constant.RuntimeStopped runtime.Status = constant.StatusStopped
case constant.RuntimeRestart: case constant.RuntimeRestart:
if err = restartRuntime(runtime); err != nil { if err = restartRuntime(runtime); err != nil {
return err return err
@ -661,7 +664,7 @@ func (r *RuntimeService) SyncForRestart() error {
return err return err
} }
for _, runtime := range runtimes { for _, runtime := range runtimes {
if runtime.Status == constant.RuntimeBuildIng || runtime.Status == constant.RuntimeReCreating || runtime.Status == constant.RuntimeStarting || runtime.Status == constant.RuntimeCreating { if runtime.Status == constant.StatusBuilding || runtime.Status == constant.StatusReCreating || runtime.Status == constant.StatusStarting || runtime.Status == constant.StatusCreating {
runtime.Status = constant.SystemRestart runtime.Status = constant.SystemRestart
runtime.Message = "System restart causing interrupt" runtime.Message = "System restart causing interrupt"
_ = runtimeRepo.Save(&runtime) _ = runtimeRepo.Save(&runtime)

View file

@ -55,7 +55,7 @@ func handleRuntime(create request.RuntimeCreate, runtime *model.Runtime, fileOp
} }
runtime.DockerCompose = string(composeContent) runtime.DockerCompose = string(composeContent)
runtime.Env = string(envContent) runtime.Env = string(envContent)
runtime.Status = constant.RuntimeCreating runtime.Status = constant.StatusCreating
runtime.CodeDir = create.CodeDir runtime.CodeDir = create.CodeDir
nodeDetail, err := appDetailRepo.GetFirst(repo.WithByID(runtime.AppDetailID)) nodeDetail, err := appDetailRepo.GetFirst(repo.WithByID(runtime.AppDetailID))
@ -89,7 +89,7 @@ func handlePHP(create request.RuntimeCreate, runtime *model.Runtime, fileOp file
runtime.DockerCompose = string(composeContent) runtime.DockerCompose = string(composeContent)
runtime.Env = string(envContent) runtime.Env = string(envContent)
runtime.Params = string(forms) runtime.Params = string(forms)
runtime.Status = constant.RuntimeBuildIng runtime.Status = constant.StatusBuilding
go buildRuntime(runtime, "", "", false) go buildRuntime(runtime, "", "", false)
return return
@ -97,14 +97,14 @@ func handlePHP(create request.RuntimeCreate, runtime *model.Runtime, fileOp file
func startRuntime(runtime *model.Runtime) { func startRuntime(runtime *model.Runtime) {
if err := runComposeCmdWithLog("up", runtime.GetComposePath(), runtime.GetLogPath()); err != nil { if err := runComposeCmdWithLog("up", runtime.GetComposePath(), runtime.GetLogPath()); err != nil {
runtime.Status = constant.RuntimeError runtime.Status = constant.StatusError
runtime.Message = err.Error() runtime.Message = err.Error()
_ = runtimeRepo.Save(runtime) _ = runtimeRepo.Save(runtime)
return return
} }
if err := SyncRuntimeContainerStatus(runtime); err != nil { if err := SyncRuntimeContainerStatus(runtime); err != nil {
runtime.Status = constant.RuntimeError runtime.Status = constant.StatusError
runtime.Message = err.Error() runtime.Message = err.Error()
_ = runtimeRepo.Save(runtime) _ = runtimeRepo.Save(runtime)
return return
@ -115,7 +115,7 @@ func reCreateRuntime(runtime *model.Runtime) {
var err error var err error
defer func() { defer func() {
if err != nil { if err != nil {
runtime.Status = constant.RuntimeError runtime.Status = constant.StatusError
runtime.Message = err.Error() runtime.Message = err.Error()
_ = runtimeRepo.Save(runtime) _ = runtimeRepo.Save(runtime)
} }
@ -155,6 +155,45 @@ func runComposeCmdWithLog(operate string, composePath string, logPath string) er
return nil return nil
} }
func SyncRuntimesStatus(runtimes []model.Runtime) error {
cli, err := docker.NewClient()
if err != nil {
return err
}
defer cli.Close()
var containerNames []string
runtimeContainer := make(map[string]int)
for index, runtime := range runtimes {
containerNames = append(containerNames, runtime.ContainerName)
runtimeContainer["/"+runtime.ContainerName] = index
}
containers, err := cli.ListContainersByName(containerNames)
if err != nil {
return err
}
for _, contain := range containers {
if index, ok := runtimeContainer[contain.Names[0]]; ok {
switch contain.State {
case "exited":
runtimes[index].Status = constant.StatusError
case "running":
runtimes[index].Status = constant.StatusRunning
case "paused":
runtimes[index].Status = constant.StatusStopped
case "restarting":
runtimes[index].Status = constant.StatusRestarting
}
delete(runtimeContainer, contain.Names[0])
}
}
for _, index := range runtimeContainer {
if runtimes[index].Status != constant.StatusBuilding {
runtimes[index].Status = constant.StatusStopped
}
}
return nil
}
func SyncRuntimeContainerStatus(runtime *model.Runtime) error { func SyncRuntimeContainerStatus(runtime *model.Runtime) error {
env, err := gotenv.Unmarshal(runtime.Env) env, err := gotenv.Unmarshal(runtime.Env)
if err != nil { if err != nil {
@ -182,14 +221,14 @@ func SyncRuntimeContainerStatus(runtime *model.Runtime) error {
switch container.State { switch container.State {
case "exited": case "exited":
runtime.Status = constant.RuntimeError runtime.Status = constant.StatusError
case "running": case "running":
runtime.Status = constant.RuntimeRunning runtime.Status = constant.StatusRunning
case "paused": case "paused":
runtime.Status = constant.RuntimeStopped runtime.Status = constant.StatusStopped
default: default:
if runtime.Status != constant.RuntimeBuildIng { if runtime.Status != constant.StatusBuilding {
runtime.Status = constant.RuntimeStopped runtime.Status = constant.StatusStopped
} }
} }
@ -232,7 +271,7 @@ func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebu
err = cmd.Run() err = cmd.Run()
if err != nil { if err != nil {
runtime.Status = constant.RuntimeError runtime.Status = constant.StatusError
runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + stderrBuf.String() runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + stderrBuf.String()
if errors.Is(ctx.Err(), context.DeadlineExceeded) { if errors.Is(ctx.Err(), context.DeadlineExceeded) {
runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + buserr.New("ErrCmdTimeout").Error() runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + buserr.New("ErrCmdTimeout").Error()
@ -286,7 +325,7 @@ func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebu
} }
if out, err := compose.Up(composePath); err != nil { if out, err := compose.Up(composePath); err != nil {
runtime.Status = constant.RuntimeStartErr runtime.Status = constant.StatusStartErr
runtime.Message = out runtime.Message = out
} else { } else {
extensions := getRuntimeEnv(runtime.Env, "PHP_EXTENSIONS") extensions := getRuntimeEnv(runtime.Env, "PHP_EXTENSIONS")
@ -294,13 +333,13 @@ func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebu
installCmd := fmt.Sprintf("docker exec -i %s %s %s", runtime.ContainerName, "install-ext", extensions) installCmd := fmt.Sprintf("docker exec -i %s %s %s", runtime.ContainerName, "install-ext", extensions)
err = cmd2.ExecWithLogFile(installCmd, 60*time.Minute, logPath) err = cmd2.ExecWithLogFile(installCmd, 60*time.Minute, logPath)
if err != nil { if err != nil {
runtime.Status = constant.RuntimeError runtime.Status = constant.StatusError
runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + err.Error() runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + err.Error()
_ = runtimeRepo.Save(runtime) _ = runtimeRepo.Save(runtime)
return return
} }
} }
runtime.Status = constant.RuntimeRunning runtime.Status = constant.StatusRunning
} }
} }
_ = runtimeRepo.Save(runtime) _ = runtimeRepo.Save(runtime)

View file

@ -4,17 +4,6 @@ const (
ResourceLocal = "local" ResourceLocal = "local"
ResourceAppstore = "appstore" ResourceAppstore = "appstore"
RuntimeNormal = "normal"
RuntimeError = "error"
RuntimeBuildIng = "building"
RuntimeStarting = "starting"
RuntimeRunning = "running"
RuntimeReCreating = "recreating"
RuntimeStopped = "stopped"
RuntimeUnhealthy = "unhealthy"
RuntimeCreating = "creating"
RuntimeStartErr = "startErr"
RuntimePHP = "php" RuntimePHP = "php"
RuntimeNode = "node" RuntimeNode = "node"
RuntimeJava = "java" RuntimeJava = "java"

View file

@ -1,17 +1,26 @@
package constant package constant
const ( const (
StatusRunning = "Running" StatusRunning = "Running"
StatusDone = "Done" StatusDone = "Done"
StatusWaiting = "Waiting" StatusWaiting = "Waiting"
StatusSuccess = "Success" StatusSuccess = "Success"
StatusFailed = "Failed" StatusFailed = "Failed"
StatusUploading = "Uploading" StatusUploading = "Uploading"
StatusEnable = "Enable" StatusEnable = "Enable"
StatusDisable = "Disable" StatusDisable = "Disable"
StatusNone = "None" StatusNone = "None"
StatusDeleted = "Deleted" StatusDeleted = "Deleted"
StatusExecuting = "Executing" StatusExecuting = "Executing"
StatusBuilding = "Building"
StatusReCreating = "Recreating"
StatusStopped = "Stopped"
StatusCreating = "Creating"
StatusStartErr = "StartErr"
StatusNormal = "Normal"
StatusError = "Error"
StatusStarting = "Starting"
StatusRestarting = "ReStarting"
OrderDesc = "descending" OrderDesc = "descending"
OrderAsc = "ascending" OrderAsc = "ascending"

View file

@ -1,9 +1,9 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 4776196 */ font-family: "iconfont"; /* Project id 4776196 */
src: url('iconfont.woff2?t=1739873339591') format('woff2'), src: url('iconfont.woff2?t=1740384606757') format('woff2'),
url('iconfont.woff?t=1739873339591') format('woff'), url('iconfont.woff?t=1740384606757') format('woff'),
url('iconfont.ttf?t=1739873339591') format('truetype'), url('iconfont.ttf?t=1740384606757') format('truetype'),
url('iconfont.svg?t=1739873339591#iconfont') format('svg'); url('iconfont.svg?t=1740384606757#iconfont') format('svg');
} }
.iconfont { .iconfont {

View file

@ -16,10 +16,10 @@
@click="onOperate('start')" @click="onOperate('start')"
:disabled="data.status === 'Installing'" :disabled="data.status === 'Installing'"
> >
{{ $t('app.start') }} {{ $t('commons.operate.start') }}
</el-button> </el-button>
<el-button type="primary" v-if="data.status === 'Running'" link @click="onOperate('stop')"> <el-button type="primary" v-if="data.status === 'Running'" link @click="onOperate('stop')">
{{ $t('app.stop') }} {{ $t('commons.operate.stop') }}
</el-button> </el-button>
<el-divider direction="vertical" /> <el-divider direction="vertical" />
<el-button <el-button
@ -28,7 +28,7 @@
:disabled="data.status === 'Installing'" :disabled="data.status === 'Installing'"
@click="onOperate('restart')" @click="onOperate('restart')"
> >
{{ $t('commons.button.restart') }} {{ $t('commons.operate.restart') }}
</el-button> </el-button>
<el-divider direction="vertical" /> <el-divider direction="vertical" />
<el-button <el-button
@ -38,7 +38,7 @@
@click="onOperate('reload')" @click="onOperate('reload')"
:disabled="data.status !== 'Running'" :disabled="data.status !== 'Running'"
> >
{{ $t('app.reload') }} {{ $t('commons.operate.reload') }}
</el-button> </el-button>
<el-divider v-if="data.app === 'OpenResty'" direction="vertical" /> <el-divider v-if="data.app === 'OpenResty'" direction="vertical" />
<el-button <el-button
@ -136,8 +136,8 @@ const onCheck = async (key: any, name: any) => {
const onOperate = async (operation: string) => { const onOperate = async (operation: string) => {
operateReq.operate = operation; operateReq.operate = operation;
ElMessageBox.confirm( ElMessageBox.confirm(
i18n.global.t('app.operatorHelper', [i18n.global.t('app.' + operation)]), i18n.global.t('app.operatorHelper', [i18n.global.t('commons.operate.' + operation)]),
i18n.global.t('app.' + operation), i18n.global.t('commons.operate.' + operation),
{ {
confirmButtonText: i18n.global.t('commons.button.confirm'), confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'), cancelButtonText: i18n.global.t('commons.button.cancel'),

View file

@ -294,7 +294,7 @@ const message = {
executing: 'Executing', executing: 'Executing',
installerr: 'Installation failed', installerr: 'Installation failed',
applyerror: 'Apply failed', applyerror: 'Apply failed',
interrupt: 'Interrupted', systemrestart: 'Interrupted',
}, },
units: { units: {
second: 'Second', second: 'Second',
@ -1871,9 +1871,6 @@ const message = {
author: 'Author', author: 'Author',
source: 'Source', source: 'Source',
appName: 'Application Name', appName: 'Application Name',
start: 'Start',
stop: 'Stop',
rebuild: 'Rebuild',
deleteWarn: deleteWarn:
'The delete operation will delete all data and backups together. This operation cannot be rolled back. Do you want to continue? ', 'The delete operation will delete all data and backups together. This operation cannot be rolled back. Do you want to continue? ',
syncSuccess: 'Sync successfully', syncSuccess: 'Sync successfully',

View file

@ -288,7 +288,7 @@ const message = {
executing: '実行中', executing: '実行中',
installerr: 'インストールに失敗しました', installerr: 'インストールに失敗しました',
applyerror: '適用に失敗しました', applyerror: '適用に失敗しました',
interrupt: '中断', systemrestart: '中断',
}, },
units: { units: {
second: '2番目|2番目|', second: '2番目|2番目|',
@ -1729,9 +1729,6 @@ const message = {
author: '著者', author: '著者',
source: 'ソース', source: 'ソース',
appName: 'アプリケーション名', appName: 'アプリケーション名',
start: '始める',
stop: '停止',
rebuild: '再構築します',
deleteWarn: deleteWarn:
'削除操作はすべてのデータとバックアップを一緒に削除しますこの操作はロールバックすることはできません続けたいですか', '削除操作はすべてのデータとバックアップを一緒に削除しますこの操作はロールバックすることはできません続けたいですか',
syncSuccess: '正常に同期しました', syncSuccess: '正常に同期しました',

View file

@ -289,7 +289,7 @@ const message = {
executing: '실행 ', executing: '실행 ',
installerr: '설치 실패', installerr: '설치 실패',
applyerror: '적용 실패', applyerror: '적용 실패',
interrupt: '중단됨', systemrestart: '중단됨',
}, },
units: { units: {
second: ' | | ', second: ' | | ',
@ -1699,9 +1699,6 @@ const message = {
author: '저자', author: '저자',
source: '출처', source: '출처',
appName: '애플리케이션 이름', appName: '애플리케이션 이름',
start: '시작',
stop: '중지',
rebuild: '재빌드',
deleteWarn: deleteWarn:
'삭제 작업은 모든 데이터와 백업을 함께 삭제합니다. 작업은 되돌릴 없습니다. 계속 하시겠습니까?', '삭제 작업은 모든 데이터와 백업을 함께 삭제합니다. 작업은 되돌릴 없습니다. 계속 하시겠습니까?',
syncSuccess: '동기화 성공', syncSuccess: '동기화 성공',

View file

@ -295,7 +295,7 @@ const message = {
executing: 'Melaksanakan', executing: 'Melaksanakan',
installerr: 'Pemasangan gagal', installerr: 'Pemasangan gagal',
applyerror: 'Permohonan gagal', applyerror: 'Permohonan gagal',
interrupt: 'Dihentikan', systemrestart: 'Dihentikan',
}, },
units: { units: {
second: 'saat | saat | saat', second: 'saat | saat | saat',
@ -1786,9 +1786,6 @@ const message = {
author: 'Pengarang', author: 'Pengarang',
source: 'Sumber', source: 'Sumber',
appName: 'Nama Aplikasi', appName: 'Nama Aplikasi',
start: 'Mula',
stop: 'Henti',
rebuild: 'Bina Semula',
deleteWarn: deleteWarn:
'Operasi memadam akan memadam semua data dan sandaran bersama. Operasi ini tidak boleh dipulihkan. Adakah anda mahu meneruskan?', 'Operasi memadam akan memadam semua data dan sandaran bersama. Operasi ini tidak boleh dipulihkan. Adakah anda mahu meneruskan?',
syncSuccess: 'Disegerakkan dengan berjaya', syncSuccess: 'Disegerakkan dengan berjaya',

View file

@ -293,7 +293,7 @@ const message = {
executing: 'Executando', executing: 'Executando',
installerr: 'Falha na instalação', installerr: 'Falha na instalação',
applyerror: 'Falha na aplicação', applyerror: 'Falha na aplicação',
interrupt: 'Interrompido', systemrestart: 'Interrompido',
}, },
units: { units: {
second: 'segundo | segundos | segundos', second: 'segundo | segundos | segundos',
@ -1773,9 +1773,6 @@ const message = {
author: 'Autor', author: 'Autor',
source: 'Fonte', source: 'Fonte',
appName: 'Nome do Aplicativo', appName: 'Nome do Aplicativo',
start: 'Iniciar',
stop: 'Parar',
rebuild: 'Reconstruir',
deleteWarn: deleteWarn:
'A operação de exclusão excluirá todos os dados e backups juntos. Esta operação não pode ser desfeita. Deseja continuar?', 'A operação de exclusão excluirá todos os dados e backups juntos. Esta operação não pode ser desfeita. Deseja continuar?',
syncSuccess: 'Sincronizado com sucesso', syncSuccess: 'Sincronizado com sucesso',

View file

@ -289,7 +289,7 @@ const message = {
executing: 'Выполнение', executing: 'Выполнение',
installerr: 'Ошибка установки', installerr: 'Ошибка установки',
applyerror: 'Ошибка применения', applyerror: 'Ошибка применения',
interrupt: 'Прервано', systemrestart: 'Прервано',
}, },
units: { units: {
second: ' секунда | секунда | секунд', second: ' секунда | секунда | секунд',
@ -1769,9 +1769,6 @@ const message = {
author: 'Автор', author: 'Автор',
source: 'Источник', source: 'Источник',
appName: 'Название приложения', appName: 'Название приложения',
start: 'Запустить',
stop: 'Остановить',
rebuild: 'Пересобрать',
deleteWarn: deleteWarn:
'Операция удаления удалит все данные и резервные копии. Эту операцию нельзя отменить. Хотите продолжить?', 'Операция удаления удалит все данные и резервные копии. Эту операцию нельзя отменить. Хотите продолжить?',
syncSuccess: 'Синхронизация выполнена успешно', syncSuccess: 'Синхронизация выполнена успешно',

View file

@ -288,7 +288,7 @@ const message = {
executing: '執行中', executing: '執行中',
installerr: '安裝失敗', installerr: '安裝失敗',
applyerror: '申請失敗', applyerror: '申請失敗',
interrupt: '中斷', systemrestart: '中斷',
}, },
units: { units: {
second: '秒', second: '秒',
@ -1756,9 +1756,6 @@ const message = {
author: '作者', author: '作者',
source: '來源', source: '來源',
appName: '應用名稱', appName: '應用名稱',
start: '啟動',
stop: '停止',
rebuild: '重建',
deleteWarn: '刪除操作會把所有數據和備份一並刪除此操作不可回滾是否繼續', deleteWarn: '刪除操作會把所有數據和備份一並刪除此操作不可回滾是否繼續',
syncSuccess: '同步成功', syncSuccess: '同步成功',
canUpgrade: '可升級', canUpgrade: '可升級',

View file

@ -76,6 +76,14 @@ const message = {
down: '停止', down: '停止',
up: '启动', up: '启动',
}, },
operate: {
start: '启动',
stop: '停止',
restart: '重启',
reload: '重载',
rebuild: '重建',
sync: '同步',
},
search: { search: {
timeStart: '开始时间', timeStart: '开始时间',
timeEnd: '结束时间', timeEnd: '结束时间',
@ -286,7 +294,7 @@ const message = {
executing: '执行中', executing: '执行中',
installerr: '安装失败', installerr: '安装失败',
applyerror: '申请失败', applyerror: '申请失败',
interrupt: '中断', systemrestart: '中断',
}, },
units: { units: {
second: '秒', second: '秒',
@ -1723,9 +1731,6 @@ const message = {
author: '作者', author: '作者',
source: '来源', source: '来源',
appName: '应用名称', appName: '应用名称',
start: '启动',
stop: '停止',
rebuild: '重建',
deleteWarn: '删除操作会把所有数据和备份一并删除此操作不可回滚是否继续', deleteWarn: '删除操作会把所有数据和备份一并删除此操作不可回滚是否继续',
syncSuccess: '同步成功', syncSuccess: '同步成功',
canUpgrade: '可升级', canUpgrade: '可升级',

View file

@ -539,8 +539,8 @@ const operate = async () => {
const onOperate = async (operation: string) => { const onOperate = async (operation: string) => {
ElMessageBox.confirm( ElMessageBox.confirm(
i18n.global.t('app.operatorHelper', [i18n.global.t('app.' + operation)]), i18n.global.t('app.operatorHelper', [i18n.global.t('commons.operate.' + operation)]),
i18n.global.t('app.' + operation), i18n.global.t('commons.operate.' + operation),
{ {
confirmButtonText: i18n.global.t('commons.button.confirm'), confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'), cancelButtonText: i18n.global.t('commons.button.cancel'),
@ -553,7 +553,7 @@ const onOperate = async (operation: string) => {
const buttons = [ const buttons = [
{ {
label: i18n.global.t('commons.button.sync'), label: i18n.global.t('commons.operate.sync'),
click: (row: any) => { click: (row: any) => {
openOperate(row, 'sync'); openOperate(row, 'sync');
}, },
@ -567,7 +567,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('app.rebuild'), label: i18n.global.t('commons.operate.rebuild'),
click: (row: any) => { click: (row: any) => {
openOperate(row, 'rebuild'); openOperate(row, 'rebuild');
}, },
@ -581,7 +581,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('commons.button.restart'), label: i18n.global.t('commons.operate.restart'),
click: (row: any) => { click: (row: any) => {
openOperate(row, 'restart'); openOperate(row, 'restart');
}, },
@ -595,7 +595,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('app.start'), label: i18n.global.t('commons.operate.start'),
click: (row: any) => { click: (row: any) => {
openOperate(row, 'start'); openOperate(row, 'start');
}, },
@ -611,7 +611,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('app.stop'), label: i18n.global.t('commons.operate.stop'),
click: (row: any) => { click: (row: any) => {
openOperate(row, 'stop'); openOperate(row, 'stop');
}, },

View file

@ -0,0 +1,27 @@
<template>
<el-popover v-if="showMessage" placement="bottom" :width="400" trigger="hover" :content="row.message">
<template #reference>
<Status :key="row.status" :status="row.status" />
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status" />
</div>
</template>
<script setup>
import { defineProps, computed } from 'vue';
import Status from '@/components/status/index.vue';
const props = defineProps({
row: {
type: Object,
required: true,
},
});
const showMessage = computed(() => {
return props.row.status === 'Error' || props.row.status === 'SystemRestart';
});
</script>

View file

@ -53,25 +53,15 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status"> <el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }"> <template #default="{ row }">
<el-popover <RuntimeStatus :row="row" />
v-if="row.status === 'error'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px"> <el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px">
<template #default="{ row }"> <template #default="{ row }">
<el-button @click="openLog(row)" link type="primary">{{ $t('website.check') }}</el-button> <el-button @click="openLog(row)" link type="primary" v-if="row.status != 'Stopped'">
{{ $t('website.check') }}
</el-button>
<span v-else>-</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -107,7 +97,6 @@ import { Runtime } from '@/api/interface/runtime';
import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime'; import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { dateFormat } from '@/utils/util'; import { dateFormat } from '@/utils/util';
import OperateDonet from '@/views/website/runtime/dotnet/operate/index.vue'; import OperateDonet from '@/views/website/runtime/dotnet/operate/index.vue';
import Status from '@/components/status/index.vue';
import Delete from '@/views/website/runtime/delete/index.vue'; import Delete from '@/views/website/runtime/delete/index.vue';
import i18n from '@/lang'; import i18n from '@/lang';
import RouterMenu from '../index.vue'; import RouterMenu from '../index.vue';
@ -118,6 +107,7 @@ import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue'; import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import { GlobalStore } from '@/store'; import { GlobalStore } from '@/store';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
let timer: NodeJS.Timer | null = null; let timer: NodeJS.Timer | null = null;
const loading = ref(false); const loading = ref(false);
@ -147,7 +137,7 @@ const req = reactive<Runtime.RuntimeReq>({
}); });
const buttons = [ const buttons = [
{ {
label: i18n.global.t('app.stop'), label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id); operateRuntime('down', row.id);
}, },
@ -156,7 +146,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('app.start'), label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id); operateRuntime('up', row.id);
}, },
@ -165,7 +155,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('commons.button.restart'), label: i18n.global.t('commons.operate.restart'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('restart', row.id); operateRuntime('restart', row.id);
}, },
@ -238,8 +228,8 @@ const goDashboard = async (port: any, protocol: string) => {
const operateRuntime = async (operate: string, ID: number) => { const operateRuntime = async (operate: string, ID: number) => {
try { try {
const action = await ElMessageBox.confirm( const action = await ElMessageBox.confirm(
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.button.' + operate)]), i18n.global.t('runtime.operatorHelper', [i18n.global.t('ommons.operate.' + operate)]),
i18n.global.t('commons.button.' + operate), i18n.global.t('ommons.operate.' + operate),
{ {
confirmButtonText: i18n.global.t('commons.button.confirm'), confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'), cancelButtonText: i18n.global.t('commons.button.cancel'),

View file

@ -53,26 +53,15 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status"> <el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }"> <template #default="{ row }">
<el-popover <RuntimeStatus :row="row" />
v-if="row.status === 'error'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
popper-class="max-h-[300px] overflow-auto"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px"> <el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px">
<template #default="{ row }"> <template #default="{ row }">
<el-button @click="openLog(row)" link type="primary">{{ $t('website.check') }}</el-button> <el-button @click="openLog(row)" link type="primary" v-if="row.status != 'Stopped'">
{{ $t('website.check') }}
</el-button>
<span v-else>-</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -108,7 +97,6 @@ import { Runtime } from '@/api/interface/runtime';
import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime'; import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { dateFormat } from '@/utils/util'; import { dateFormat } from '@/utils/util';
import Operate from '@/views/website/runtime/go/operate/index.vue'; import Operate from '@/views/website/runtime/go/operate/index.vue';
import Status from '@/components/status/index.vue';
import Delete from '@/views/website/runtime/delete/index.vue'; import Delete from '@/views/website/runtime/delete/index.vue';
import i18n from '@/lang'; import i18n from '@/lang';
import RouterMenu from '../index.vue'; import RouterMenu from '../index.vue';
@ -118,6 +106,7 @@ import { Promotion } from '@element-plus/icons-vue';
import PortJumpDialog from '@/components/port-jump/index.vue'; import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue'; import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
let timer: NodeJS.Timer | null = null; let timer: NodeJS.Timer | null = null;
const loading = ref(false); const loading = ref(false);
@ -142,7 +131,7 @@ const req = reactive<Runtime.RuntimeReq>({
}); });
const buttons = [ const buttons = [
{ {
label: i18n.global.t('app.stop'), label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id); operateRuntime('down', row.id);
}, },
@ -151,7 +140,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('app.start'), label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id); operateRuntime('up', row.id);
}, },
@ -233,8 +222,8 @@ const goDashboard = async (port: any, protocol: string) => {
const operateRuntime = async (operate: string, ID: number) => { const operateRuntime = async (operate: string, ID: number) => {
try { try {
const action = await ElMessageBox.confirm( const action = await ElMessageBox.confirm(
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.button.' + operate)]), i18n.global.t('runtime.operatorHelper', [i18n.global.t('ommons.operate.' + operate)]),
i18n.global.t('commons.button.' + operate), i18n.global.t('ommons.operate.' + operate),
{ {
confirmButtonText: i18n.global.t('commons.button.confirm'), confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'), cancelButtonText: i18n.global.t('commons.button.cancel'),

View file

@ -53,25 +53,15 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status"> <el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }"> <template #default="{ row }">
<el-popover <RuntimeStatus :row="row" />
v-if="row.status === 'error'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px"> <el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px">
<template #default="{ row }"> <template #default="{ row }">
<el-button @click="openLog(row)" link type="primary">{{ $t('website.check') }}</el-button> <el-button @click="openLog(row)" link type="primary" v-if="row.status != 'Stopped'">
{{ $t('website.check') }}
</el-button>
<span v-else>-</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -107,7 +97,6 @@ import { Runtime } from '@/api/interface/runtime';
import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime'; import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { dateFormat } from '@/utils/util'; import { dateFormat } from '@/utils/util';
import OperateJava from '@/views/website/runtime/java/operate/index.vue'; import OperateJava from '@/views/website/runtime/java/operate/index.vue';
import Status from '@/components/status/index.vue';
import Delete from '@/views/website/runtime/delete/index.vue'; import Delete from '@/views/website/runtime/delete/index.vue';
import i18n from '@/lang'; import i18n from '@/lang';
import RouterMenu from '../index.vue'; import RouterMenu from '../index.vue';
@ -117,6 +106,7 @@ import { Promotion } from '@element-plus/icons-vue';
import PortJumpDialog from '@/components/port-jump/index.vue'; import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue'; import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
let timer: NodeJS.Timer | null = null; let timer: NodeJS.Timer | null = null;
const loading = ref(false); const loading = ref(false);
@ -141,7 +131,7 @@ const req = reactive<Runtime.RuntimeReq>({
}); });
const buttons = [ const buttons = [
{ {
label: i18n.global.t('app.stop'), label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id); operateRuntime('down', row.id);
}, },
@ -150,7 +140,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('app.start'), label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id); operateRuntime('up', row.id);
}, },
@ -232,8 +222,8 @@ const goDashboard = async (port: any, protocol: string) => {
const operateRuntime = async (operate: string, ID: number) => { const operateRuntime = async (operate: string, ID: number) => {
try { try {
const action = await ElMessageBox.confirm( const action = await ElMessageBox.confirm(
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.button.' + operate)]), i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.operate' + operate)]),
i18n.global.t('commons.button.' + operate), i18n.global.t('commons.operate.' + operate),
{ {
confirmButtonText: i18n.global.t('commons.button.confirm'), confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'), cancelButtonText: i18n.global.t('commons.button.cancel'),

View file

@ -53,25 +53,15 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status"> <el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }"> <template #default="{ row }">
<el-popover <RuntimeStatus :row="row" />
v-if="row.status === 'error'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px"> <el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px">
<template #default="{ row }"> <template #default="{ row }">
<el-button @click="openLog(row)" link type="primary">{{ $t('website.check') }}</el-button> <el-button @click="openLog(row)" link type="primary" v-if="row.status != 'Stopped'">
{{ $t('website.check') }}
</el-button>
<span v-else>-</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -108,7 +98,6 @@ import { Runtime } from '@/api/interface/runtime';
import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime'; import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { dateFormat } from '@/utils/util'; import { dateFormat } from '@/utils/util';
import OperateNode from '@/views/website/runtime/node/operate/index.vue'; import OperateNode from '@/views/website/runtime/node/operate/index.vue';
import Status from '@/components/status/index.vue';
import Delete from '@/views/website/runtime/delete/index.vue'; import Delete from '@/views/website/runtime/delete/index.vue';
import i18n from '@/lang'; import i18n from '@/lang';
import RouterMenu from '../index.vue'; import RouterMenu from '../index.vue';
@ -119,6 +108,7 @@ import { Promotion } from '@element-plus/icons-vue';
import PortJumpDialog from '@/components/port-jump/index.vue'; import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue'; import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
let timer: NodeJS.Timer | null = null; let timer: NodeJS.Timer | null = null;
const loading = ref(false); const loading = ref(false);
@ -153,7 +143,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('app.stop'), label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id); operateRuntime('down', row.id);
}, },
@ -162,7 +152,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('app.start'), label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id); operateRuntime('up', row.id);
}, },
@ -248,8 +238,8 @@ const goDashboard = async (port: any, protocol: string) => {
const operateRuntime = async (operate: string, ID: number) => { const operateRuntime = async (operate: string, ID: number) => {
try { try {
const action = await ElMessageBox.confirm( const action = await ElMessageBox.confirm(
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.button.' + operate)]), i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.operate.' + operate)]),
i18n.global.t('commons.button.' + operate), i18n.global.t('commons.operate.' + operate),
{ {
confirmButtonText: i18n.global.t('commons.button.confirm'), confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'), cancelButtonText: i18n.global.t('commons.button.cancel'),

View file

@ -66,20 +66,7 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status"> <el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }"> <template #default="{ row }">
<el-popover <RuntimeStatus :row="row" />
v-if="row.status === 'error' || row.status === 'systemRestart'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.button.log')" prop=""> <el-table-column :label="$t('commons.button.log')" prop="">
@ -134,12 +121,12 @@ import ExtManagement from './extension-management/index.vue';
import Extensions from './extension-template/index.vue'; import Extensions from './extension-template/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue'; import AppResources from '@/views/website/runtime/php/check/index.vue';
import CreateRuntime from '@/views/website/runtime/php/create/index.vue'; import CreateRuntime from '@/views/website/runtime/php/create/index.vue';
import Status from '@/components/status/index.vue';
import RouterMenu from '../index.vue'; import RouterMenu from '../index.vue';
import Log from '@/components/log-dialog/index.vue'; import Log from '@/components/log-dialog/index.vue';
import ComposeLogs from '@/components/compose-log/index.vue'; import ComposeLogs from '@/components/compose-log/index.vue';
import Config from '@/views/website/runtime/php/config/index.vue'; import Config from '@/views/website/runtime/php/config/index.vue';
import Supervisor from '@/views/website/runtime/php/supervisor/index.vue'; import Supervisor from '@/views/website/runtime/php/supervisor/index.vue';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
const paginationConfig = reactive({ const paginationConfig = reactive({
cacheSizeKey: 'runtime-page-size', cacheSizeKey: 'runtime-page-size',
@ -177,7 +164,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('app.stop'), label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id); operateRuntime('down', row.id);
}, },
@ -186,7 +173,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('app.start'), label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id); operateRuntime('up', row.id);
}, },
@ -277,7 +264,7 @@ const openSupervisor = (row: Runtime.Runtime) => {
}; };
const openLog = (row: Runtime.RuntimeDTO) => { const openLog = (row: Runtime.RuntimeDTO) => {
if (row.status == 'running') { if (row.status == 'Running') {
composeLogRef.value.acceptParams({ compose: row.path + '/docker-compose.yml', resource: row.name }); composeLogRef.value.acceptParams({ compose: row.path + '/docker-compose.yml', resource: row.name });
} else { } else {
logRef.value.acceptParams({ id: row.id, type: 'php', tail: row.status == 'building', heightDiff: 220 }); logRef.value.acceptParams({ id: row.id, type: 'php', tail: row.status == 'building', heightDiff: 220 });

View file

@ -53,25 +53,15 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status"> <el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }"> <template #default="{ row }">
<el-popover <RuntimeStatus :row="row" />
v-if="row.status === 'error'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px"> <el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px">
<template #default="{ row }"> <template #default="{ row }">
<el-button @click="openLog(row)" link type="primary">{{ $t('website.check') }}</el-button> <el-button @click="openLog(row)" link type="primary" v-if="row.status != 'Stopped'">
{{ $t('website.check') }}
</el-button>
<span v-else>-</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -107,7 +97,6 @@ import { Runtime } from '@/api/interface/runtime';
import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime'; import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { dateFormat } from '@/utils/util'; import { dateFormat } from '@/utils/util';
import Operate from '@/views/website/runtime/python/operate/index.vue'; import Operate from '@/views/website/runtime/python/operate/index.vue';
import Status from '@/components/status/index.vue';
import Delete from '@/views/website/runtime/delete/index.vue'; import Delete from '@/views/website/runtime/delete/index.vue';
import i18n from '@/lang'; import i18n from '@/lang';
import RouterMenu from '../index.vue'; import RouterMenu from '../index.vue';
@ -117,6 +106,7 @@ import { Promotion } from '@element-plus/icons-vue';
import PortJumpDialog from '@/components/port-jump/index.vue'; import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue'; import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
let timer: NodeJS.Timer | null = null; let timer: NodeJS.Timer | null = null;
const loading = ref(false); const loading = ref(false);
@ -141,7 +131,7 @@ const req = reactive<Runtime.RuntimeReq>({
}); });
const buttons = [ const buttons = [
{ {
label: i18n.global.t('app.stop'), label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id); operateRuntime('down', row.id);
}, },
@ -150,7 +140,7 @@ const buttons = [
}, },
}, },
{ {
label: i18n.global.t('app.start'), label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) { click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id); operateRuntime('up', row.id);
}, },
@ -232,8 +222,8 @@ const goDashboard = async (port: any, protocol: string) => {
const operateRuntime = async (operate: string, ID: number) => { const operateRuntime = async (operate: string, ID: number) => {
try { try {
const action = await ElMessageBox.confirm( const action = await ElMessageBox.confirm(
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.button.' + operate)]), i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.operate.' + operate)]),
i18n.global.t('commons.button.' + operate), i18n.global.t('commons.operate.' + operate),
{ {
confirmButtonText: i18n.global.t('commons.button.confirm'), confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'), cancelButtonText: i18n.global.t('commons.button.cancel'),