fix: 删除 PHP 和 Node.js 运行环境的提示信息优化 (#4790)

* fix: 删除 PHP 和 Node.js 运行环境的提示信息优化

* fix: 代码优化

* fix: 代码优化

---------

Co-authored-by: zhoujunhong <1298308460@qq.com>
This commit is contained in:
John Bro 2024-04-30 11:58:49 +08:00 committed by GitHub
parent 5c46c26dd5
commit e47d449b1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 188 additions and 12 deletions

View File

@ -76,6 +76,20 @@ func (b *BaseApi) DeleteRuntime(c *gin.Context) {
helper.SuccessWithOutData(c)
}
func (b *BaseApi) DeleteRuntimeCheck(c *gin.Context) {
runTimeId, err := helper.GetIntParamByKey(c, "runTimeId")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
checkData, err := runtimeService.DeleteCheck(runTimeId)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, checkData)
}
// @Tags Runtime
// @Summary Update runtime
// @Description 更新运行环境

View File

@ -44,6 +44,7 @@ type IRuntimeService interface {
OperateNodeModules(req request.NodeModuleOperateReq) error
SyncForRestart() error
SyncRuntimeStatus() error
DeleteCheck(installID uint) ([]dto.AppResource, error)
}
func NewRuntimeService() IRuntimeService {
@ -177,6 +178,18 @@ func (r *RuntimeService) Page(req request.RuntimeSearch) (int64, []response.Runt
return total, res, nil
}
func (r *RuntimeService) DeleteCheck(runTimeId uint) ([]dto.AppResource, error) {
var res []dto.AppResource
websites, _ := websiteRepo.GetBy(websiteRepo.WithRuntimeID(runTimeId))
for _, website := range websites {
res = append(res, dto.AppResource{
Type: "website",
Name: website.PrimaryDomain,
})
}
return res, nil
}
func (r *RuntimeService) Delete(runtimeDelete request.RuntimeDelete) error {
runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(runtimeDelete.ID))
if err != nil {

View File

@ -15,6 +15,7 @@ func (r *RuntimeRouter) InitRouter(Router *gin.RouterGroup) {
baseApi := v1.ApiGroupApp.BaseApi
{
groupRouter.GET("/installed/delete/check/:runTimeId", baseApi.DeleteRuntimeCheck)
groupRouter.POST("/search", baseApi.SearchRuntimes)
groupRouter.POST("", baseApi.CreateRuntime)
groupRouter.POST("/del", baseApi.DeleteRuntime)

View File

@ -2,6 +2,7 @@ import http from '@/api';
import { ResPage, ReqPage } from '../interface';
import { Runtime } from '../interface/runtime';
import { TimeoutEnum } from '@/enums/http-enum';
import { App } from '@/api/interface/app';
export const SearchRuntimes = (req: Runtime.RuntimeReq) => {
return http.post<ResPage<Runtime.RuntimeDTO>>(`/runtimes/search`, req);
@ -15,6 +16,10 @@ export const DeleteRuntime = (req: Runtime.RuntimeDelete) => {
return http.post<any>(`/runtimes/del`, req);
};
export const RuntimeDeleteCheck = (runTimeId: number) => {
return http.get<App.AppInstallResource[]>(`runtimes/installed/delete/check/${runTimeId}`);
};
export const GetRuntime = (id: number) => {
return http.get<Runtime.RuntimeDTO>(`/runtimes/${id}`);
};

View File

@ -84,13 +84,14 @@
<ComposeLogs ref="composeLogRef" />
<PortJumpDialog ref="dialogPortJumpRef" />
<Modules ref="moduleRef" />
<AppResources ref="checkRef" @close="search" />
</div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import { Runtime } from '@/api/interface/runtime';
import { OperateRuntime, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { dateFormat } from '@/utils/util';
import OperateNode from '@/views/website/runtime/node/operate/index.vue';
import Status from '@/components/status/index.vue';
@ -102,6 +103,7 @@ import router from '@/routers/router';
import ComposeLogs from '@/components/compose-log/index.vue';
import { Promotion } from '@element-plus/icons-vue';
import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue';
let timer: NodeJS.Timer | null = null;
const loading = ref(false);
@ -111,6 +113,7 @@ const deleteRef = ref();
const dialogPortJumpRef = ref();
const composeLogRef = ref();
const moduleRef = ref();
const checkRef = ref();
const paginationConfig = reactive({
cacheSizeKey: 'runtime-page-size',
@ -209,7 +212,14 @@ const openDetail = (row: Runtime.Runtime) => {
};
const openDelete = async (row: Runtime.Runtime) => {
deleteRef.value.acceptParams(row.id, row.name);
RuntimeDeleteCheck(row.id).then(async (res) => {
const items = res.data;
if (res.data && res.data.length > 0) {
checkRef.value.acceptParams({ items: items, key: 'website', installID: row.id });
} else {
deleteRef.value.acceptParams(row.id, row.name);
}
});
};
const openLog = (row: any) => {

View File

@ -0,0 +1,122 @@
<template>
<el-dialog v-model="open" :title="$t('app.checkTitle')" width="50%" :close-on-click-modal="false">
<el-row>
<el-col :span="20" :offset="2" v-if="open">
<el-alert
type="error"
:description="$t('app.deleteHelper', [$t('runtime.runtime')])"
center
show-icon
:closable="false"
/>
<br />
<el-descriptions border :column="1">
<el-descriptions-item v-for="(item, key) in map" :key="key">
<template #label>
<a href="javascript:void(0);" @click="toPage(item[0])">{{ $t('app.' + item[0]) }}</a>
</template>
<span class="resources">
{{ map.get(item[0]).toString() }}
</span>
</el-descriptions-item>
</el-descriptions>
<div v-if="installData.key === 'openresty'" class="mt-5">
<el-checkbox v-model="forceDelete" label="true">{{ $t('app.forceDelete') }}</el-checkbox>
<ErrPrompt :title="$t('app.openrestyDeleteHelper')" />
</div>
</el-col>
</el-row>
<template #footer v-if="forceDelete">
<span class="dialog-footer">
<el-button @click="open = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button type="primary" @click="onConfirm">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { App } from '@/api/interface/app';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { DeleteRuntime } from '@/api/modules/runtime';
const router = useRouter();
interface CheckRrops {
items: App.AppInstallResource[];
installID: Number;
key: string;
}
const installData = ref<CheckRrops>({
items: [],
installID: 0,
key: '',
});
const open = ref(false);
const map = new Map();
const forceDelete = ref(false);
const em = defineEmits(['close']);
const acceptParams = (props: CheckRrops) => {
map.clear();
forceDelete.value = false;
installData.value.installID = props.installID;
installData.value.key = props.key;
installData.value.items = [];
installData.value.items = props.items;
installData.value.items.forEach((item) => {
if (map.has(item.type)) {
const array = map.get(item.type);
array.push(item.name);
map.set(item.type, array);
} else {
map.set(item.type, [item.name]);
}
});
open.value = true;
};
const toPage = (key: string) => {
if (key === 'website') {
router.push({ name: 'Website' });
}
};
const onConfirm = () => {
ElMessageBox.confirm(
i18n.global.t('app.operatorHelper', [i18n.global.t('app.delete')]),
i18n.global.t('app.delete'),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
},
).then(() => {
const params = {
id: installData.value.installID.valueOf(),
forceDelete: true,
};
DeleteRuntime(params).then(() => {
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
open.value = false;
em('close', open);
});
});
};
defineExpose({
acceptParams,
});
</script>
<style scoped>
.resources {
word-break: break-all;
}
</style>

View File

@ -79,13 +79,14 @@
<OpDialog ref="opRef" @search="search" />
<Log ref="logRef" @close="search" />
<Extensions ref="extensionsRef" @close="search" />
<AppResources ref="checkRef" @close="search" />
</div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import { Runtime } from '@/api/interface/runtime';
import { DeleteRuntime, SearchRuntimes } from '@/api/modules/runtime';
import { DeleteRuntime, RuntimeDeleteCheck, SearchRuntimes } from '@/api/modules/runtime';
import { dateFormat, toLowerCase } from '@/utils/util';
import CreateRuntime from '@/views/website/runtime/php/create/index.vue';
import Status from '@/components/status/index.vue';
@ -93,6 +94,7 @@ import i18n from '@/lang';
import RouterMenu from '../index.vue';
import Log from '@/components/log-dialog/index.vue';
import Extensions from './extensions/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue';
const paginationConfig = reactive({
cacheSizeKey: 'runtime-page-size',
@ -111,6 +113,8 @@ const opRef = ref();
const logRef = ref();
const extensionsRef = ref();
const checkRef = ref();
const buttons = [
{
label: i18n.global.t('commons.button.edit'),
@ -167,15 +171,22 @@ const openExtensions = () => {
};
const openDelete = async (row: Runtime.Runtime) => {
opRef.value.acceptParams({
title: i18n.global.t('commons.msg.deleteTitle'),
names: [row.name],
msg: i18n.global.t('commons.msg.operatorHelper', [
i18n.global.t('website.runtime'),
i18n.global.t('commons.button.delete'),
]),
api: DeleteRuntime,
params: { id: row.id, forceDelete: true },
RuntimeDeleteCheck(row.id).then(async (res) => {
const items = res.data;
if (res.data && res.data.length > 0) {
checkRef.value.acceptParams({ items: items, key: 'website', installID: row.id });
} else {
opRef.value.acceptParams({
title: i18n.global.t('commons.msg.deleteTitle'),
names: [row.name],
msg: i18n.global.t('commons.msg.operatorHelper', [
i18n.global.t('website.runtime'),
i18n.global.t('commons.button.delete'),
]),
api: DeleteRuntime,
params: { id: row.id, forceDelete: true },
});
}
});
};