fix: 删除应用增加提示

This commit is contained in:
zhengkunwang223 2022-12-01 19:25:02 +08:00 committed by zhengkunwang223
parent 098b735c7a
commit c61e2cb191
12 changed files with 176 additions and 7 deletions

View File

@ -53,6 +53,22 @@ func (b *BaseApi) CheckAppInstalled(c *gin.Context) {
helper.SuccessWithData(c, checkData)
}
func (b *BaseApi) DeleteCheck(c *gin.Context) {
appInstallId, err := helper.GetIntParamByKey(c, "appInstallId")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
checkData, err := appInstallService.DeleteCheck(appInstallId)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, checkData)
}
func (b *BaseApi) SyncInstalled(c *gin.Context) {
if err := appInstallService.SyncAll(); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)

View File

@ -177,3 +177,8 @@ type AppFormFields struct {
Default string `json:"default"`
EnvKey string `json:"env_variable"`
}
type AppResource struct {
Type string `json:"type"`
Name string `json:"name"`
}

View File

@ -17,6 +17,12 @@ func (a AppInstallResourceRpo) WithAppInstallId(appInstallId uint) DBOption {
}
}
func (a AppInstallResourceRpo) WithLinkId(linkId uint) DBOption {
return func(db *gorm.DB) *gorm.DB {
return db.Where("link_id = ?", linkId)
}
}
func (a AppInstallResourceRpo) GetBy(opts ...DBOption) ([]model.AppInstallResource, error) {
db := global.DB.Model(&model.AppInstallResource{})
var resources []model.AppInstallResource

View File

@ -295,6 +295,58 @@ func (a AppInstallService) ChangeAppPort(req dto.PortUpdate) error {
return nil
}
func (a AppInstallService) DeleteCheck(installId uint) ([]dto.AppResource, error) {
var res []dto.AppResource
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
if err != nil {
return nil, err
}
app, err := appRepo.GetFirst(commonRepo.WithByID(appInstall.AppId))
if err != nil {
return nil, err
}
if app.Type == "website" {
websites, _ := websiteRepo.GetBy(websiteRepo.WithAppInstallId(appInstall.ID))
for _, website := range websites {
res = append(res, dto.AppResource{
Type: "website",
Name: website.PrimaryDomain,
})
}
}
if app.Key == "nginx" {
websites, _ := websiteRepo.GetBy()
for _, website := range websites {
res = append(res, dto.AppResource{
Type: "website",
Name: website.PrimaryDomain,
})
}
}
if app.Type == "runtime" {
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithLinkId(appInstall.ID))
for _, resource := range resources {
linkInstall, _ := appInstallRepo.GetFirst(commonRepo.WithByID(resource.AppInstallId))
res = append(res, dto.AppResource{
Type: "app",
Name: linkInstall.Name,
})
}
}
if app.Key == "mysql" {
databases, _ := mysqlRepo.List()
for _, database := range databases {
res = append(res, dto.AppResource{
Type: "database",
Name: database.Name,
})
}
}
return res, nil
}
func syncById(installId uint) error {
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
if err != nil {

View File

@ -175,6 +175,10 @@ func deleteAppInstall(ctx context.Context, install model.AppInstall) error {
if err := deleteLink(ctx, &install); err != nil {
return err
}
backups, _ := appInstallBackupRepo.GetBy(appInstallBackupRepo.WithAppInstallID(install.ID))
for _, backup := range backups {
_ = op.DeleteDir(backup.Path)
}
if err := appInstallBackupRepo.Delete(ctx, appInstallBackupRepo.WithAppInstallID(install.ID)); err != nil {
return err
}

View File

@ -22,6 +22,7 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) {
appRouter.POST("/install", baseApi.InstallApp)
appRouter.GET("/installed/:appInstallId/versions", baseApi.GetUpdateVersions)
appRouter.GET("/installed/check/:key", baseApi.CheckAppInstalled)
appRouter.GET("/installed/delete/check/:appInstallId", baseApi.DeleteCheck)
appRouter.POST("/installed", baseApi.SearchAppInstalled)
appRouter.POST("/installed/op", baseApi.OperateInstalled)
appRouter.POST("/installed/sync", baseApi.SyncInstalled)

View File

@ -98,6 +98,11 @@ export namespace App {
containerName: string;
}
export interface AppInstallResource {
type: string;
name: string;
}
export interface AppInstalledOp {
installId: number;
operate: string;

View File

@ -34,6 +34,10 @@ export const CheckAppInstalled = (key: string) => {
return http.get<App.CheckInstalled>(`apps/installed/check/${key}`);
};
export const AppInstalledDeleteCheck = (appInstallId: number) => {
return http.get<App.AppInstallResource[]>(`apps/installed/delete/check/${appInstallId}`);
};
export const GetAppInstalled = (search: App.AppInstalledSearch) => {
return http.post<App.AppInstalled[]>('apps/installed', search);
};

View File

@ -3,31 +3,31 @@
<div class="app-content" v-if="data.isExist">
<el-card class="app-card" v-loading="loading">
<el-row :gutter="20">
<el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1">
<el-col :lg="2" :xl="1">
<div>
<el-tag effect="dark" type="success">{{ data.app }}</el-tag>
</div>
</el-col>
<el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2">
<el-col :lg="4" :xl="2">
<div>
{{ $t('app.version') }}:
<el-tag type="info">{{ data.version }}</el-tag>
</div>
</el-col>
<el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2">
<el-col :lg="4" :xl="2">
<div>
{{ $t('commons.table.status') }}:
<el-tag type="success">{{ data.status }}</el-tag>
</div>
</el-col>
<el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2">
<el-col :lg="8" :xl="4">
<div>
{{ $t('website.lastBackupAt') }}:
<el-tag v-if="data.lastBackupAt != ''" type="info">{{ data.lastBackupAt }}</el-tag>
<span else>{{ $t('website.null') }}</span>
<span v-else>{{ $t('website.null') }}</span>
</div>
</el-col>
<el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="6">
<el-col :lg="4" :xl="6">
<el-button type="primary" link @click="onOperate('restart')">{{ $t('app.restart') }}</el-button>
<el-divider direction="vertical" />
<el-button type="primary" link @click="setting">{{ $t('commons.button.set') }}</el-button>

View File

@ -733,6 +733,10 @@ export default {
gotoInstalled: '去安装',
search: '搜索',
limitHelper: '该应用已安装不支持重复安装',
deleteHelper: '应用已经关联以下资源无法删除',
checkTitle: '提示',
website: '网站',
database: '数据库',
},
website: {
website: '网站',

View File

@ -0,0 +1,54 @@
<template>
<el-dialog
v-model="open"
:title="$t('app.checkTitle')"
width="50%"
:close-on-click-modal="false"
:destroy-on-close="true"
>
<el-row>
<el-alert type="warning" :description="$t('app.deleteHelper')" center show-icon :closable="false" />
<el-col :span="12" :offset="6">
<br />
<el-descriptions border :column="1">
<el-descriptions-item v-for="(item, key) in map" :key="key" :label="$t('app.' + item[0])">
{{ map.get(item[0]).toString() }}
</el-descriptions-item>
</el-descriptions>
</el-col>
</el-row>
</el-dialog>
</template>
<script lang="ts" setup>
import { App } from '@/api/interface/app';
import { ref } from 'vue';
interface InstallRrops {
items: App.AppInstallResource[];
}
const installData = ref<InstallRrops>({
items: [],
});
let open = ref(false);
let map = new Map();
const acceptParams = (props: InstallRrops) => {
map.clear();
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;
};
defineExpose({
acceptParams,
});
</script>

View File

@ -104,17 +104,25 @@
</template>
</el-dialog>
<Backups ref="backupRef" @close="search"></Backups>
<AppResources ref="checkRef"></AppResources>
</el-card>
</template>
<script lang="ts" setup>
import { SearchAppInstalled, InstalledOp, SyncInstalledApp, GetAppUpdateVersions } from '@/api/modules/app';
import {
SearchAppInstalled,
InstalledOp,
SyncInstalledApp,
GetAppUpdateVersions,
AppInstalledDeleteCheck,
} from '@/api/modules/app';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import ComplexTable from '@/components/complex-table/index.vue';
import { dateFromat } from '@/utils/util';
import i18n from '@/lang';
import { ElMessage, ElMessageBox } from 'element-plus';
import Backups from './backups.vue';
import AppResources from './check/index.vue';
import { App } from '@/api/interface/app';
let data = ref<any>();
@ -133,6 +141,7 @@ let operateReq = reactive({
});
let versions = ref<App.VersionDetail[]>();
const backupRef = ref();
const checkRef = ref();
let searchName = ref('');
const sync = () => {
@ -171,6 +180,15 @@ const openOperate = (row: any, op: string) => {
}
open.value = true;
});
} else if (op == 'delete') {
AppInstalledDeleteCheck(row.id).then((res) => {
const items = res.data;
if (res.data && res.data.length > 0) {
checkRef.value.acceptParams({ items: items });
} else {
onOperate(op);
}
});
} else {
onOperate(op);
}