mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-24 02:59:16 +08:00
parent
0ac2b9df7a
commit
10427ddd65
@ -130,6 +130,22 @@ func (b *BaseApi) GetAppDetailByID(c *gin.Context) {
|
||||
helper.SuccessWithData(c, appDetailDTO)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Get Ignore App
|
||||
// @Description 获取忽略的应用版本
|
||||
// @Accept json
|
||||
// @Success 200 {object} response.IgnoredApp
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/ingored [get]
|
||||
func (b *BaseApi) GetIgnoredApp(c *gin.Context) {
|
||||
res, err := appService.GetIgnoredApp()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Install app
|
||||
// @Description 安装应用
|
||||
|
@ -67,8 +67,8 @@ type AppInstalledUpdate struct {
|
||||
}
|
||||
|
||||
type AppInstalledIgnoreUpgrade struct {
|
||||
InstallId uint `json:"installId" validate:"required"`
|
||||
DetailId uint `json:"detailId" validate:"required"`
|
||||
DetailID uint `json:"detailID" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required,oneof=cancel ignore"`
|
||||
}
|
||||
|
||||
type PortUpdate struct {
|
||||
|
@ -48,6 +48,13 @@ type AppDetailDTO struct {
|
||||
Image string `json:"image"`
|
||||
}
|
||||
|
||||
type IgnoredApp struct {
|
||||
Icon string `json:"icon"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
DetailID uint `json:"detailID"`
|
||||
}
|
||||
|
||||
type AppInstalledDTO struct {
|
||||
model.AppInstall
|
||||
Total int `json:"total"`
|
||||
|
@ -13,6 +13,7 @@ type AppDetailRepo struct {
|
||||
type IAppDetailRepo interface {
|
||||
WithVersion(version string) DBOption
|
||||
WithAppId(id uint) DBOption
|
||||
WithIgnored() DBOption
|
||||
GetFirst(opts ...DBOption) (model.AppDetail, error)
|
||||
Update(ctx context.Context, detail model.AppDetail) error
|
||||
BatchCreate(ctx context.Context, details []model.AppDetail) error
|
||||
@ -31,12 +32,19 @@ func (a AppDetailRepo) WithVersion(version string) DBOption {
|
||||
return g.Where("version = ?", version)
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppDetailRepo) WithAppId(id uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("app_id = ?", id)
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppDetailRepo) WithIgnored() DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("ignore_upgrade = 1")
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppDetailRepo) GetFirst(opts ...DBOption) (model.AppDetail, error) {
|
||||
var detail model.AppDetail
|
||||
err := getDb(opts...).Model(&model.AppDetail{}).Find(&detail).Error
|
||||
|
@ -39,6 +39,7 @@ type IAppService interface {
|
||||
GetAppUpdate() (*response.AppUpdateRes, error)
|
||||
GetAppDetailByID(id uint) (*response.AppDetailDTO, error)
|
||||
SyncAppListFromLocal()
|
||||
GetIgnoredApp() ([]response.IgnoredApp, error)
|
||||
}
|
||||
|
||||
func NewIAppService() IAppService {
|
||||
@ -232,6 +233,27 @@ func (a AppService) GetAppDetailByID(id uint) (*response.AppDetailDTO, error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a AppService) GetIgnoredApp() ([]response.IgnoredApp, error) {
|
||||
var res []response.IgnoredApp
|
||||
details, _ := appDetailRepo.GetBy(appDetailRepo.WithIgnored())
|
||||
if len(details) == 0 {
|
||||
return res, nil
|
||||
}
|
||||
for _, detail := range details {
|
||||
app, err := appRepo.GetFirst(commonRepo.WithByID(detail.AppId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, response.IgnoredApp{
|
||||
Name: app.Name,
|
||||
Version: detail.Version,
|
||||
DetailID: detail.ID,
|
||||
Icon: app.Icon,
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (appInstall *model.AppInstall, err error) {
|
||||
if err = docker.CreateDefaultDockerNetwork(); err != nil {
|
||||
err = buserr.WithDetail(constant.Err1PanelNetworkFailed, err.Error(), nil)
|
||||
|
@ -359,7 +359,7 @@ func (a *AppInstallService) IgnoreUpgrade(req request.AppInstalledIgnoreUpgrade)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
appDetail.IgnoreUpgrade = true
|
||||
appDetail.IgnoreUpgrade = req.Operate == "ignore"
|
||||
return appDetailRepo.Update(context.Background(), appDetail)
|
||||
}
|
||||
|
||||
|
@ -37,5 +37,6 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) {
|
||||
appRouter.GET("/installed/params/:appInstallId", baseApi.GetParams)
|
||||
appRouter.POST("/installed/params/update", baseApi.UpdateInstalled)
|
||||
appRouter.POST("/installed/ignore", baseApi.IgnoreUpgrade)
|
||||
appRouter.GET("/ignored/detail", baseApi.GetIgnoredApp)
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -187,4 +187,11 @@ export namespace App {
|
||||
allowPort: boolean;
|
||||
dockerCompose: string;
|
||||
}
|
||||
|
||||
export interface IgnoredApp {
|
||||
name: string;
|
||||
detailID: number;
|
||||
version: string;
|
||||
icon: string;
|
||||
}
|
||||
}
|
||||
|
@ -93,3 +93,7 @@ export const UpdateAppInstallParams = (req: any) => {
|
||||
export const IgnoreUpgrade = (req: any) => {
|
||||
return http.post<any>(`apps/installed/ignore`, req);
|
||||
};
|
||||
|
||||
export const GetIgnoredApp = () => {
|
||||
return http.get<App.IgnoredApp>(`apps/ignored/detail`);
|
||||
};
|
||||
|
@ -44,7 +44,7 @@ const message = {
|
||||
refresh: 'Refresh',
|
||||
get: 'Get',
|
||||
upgrade: 'Upgrade',
|
||||
ignoreUpgrade: 'Ignore upgrade',
|
||||
ignore: 'Ignore upgrade',
|
||||
copy: 'Copy',
|
||||
random: 'Random',
|
||||
},
|
||||
@ -1198,6 +1198,9 @@ const message = {
|
||||
'Currently, if the port external access is not checked, it will not be able to access through the external network IP: port. Do you want to continue?',
|
||||
restoreWarn:
|
||||
'The restore operation will delete the current data of the application and restart it. This operation cannot be rolled back, continue?',
|
||||
showIgnore: 'View ignore application',
|
||||
cancelIgnore: 'Cancel ignore',
|
||||
ignoreList: 'ignore list',
|
||||
},
|
||||
website: {
|
||||
website: 'Website',
|
||||
|
@ -44,7 +44,7 @@ const message = {
|
||||
refresh: '刷新',
|
||||
get: '獲取',
|
||||
upgrade: '升級',
|
||||
ignoreUpgrade: '忽略升級',
|
||||
ignore: '忽略升級',
|
||||
copy: '復製',
|
||||
random: '隨機密碼',
|
||||
},
|
||||
@ -1139,6 +1139,9 @@ const message = {
|
||||
upgradeHelper: '異常應用需要先同步到正常狀態',
|
||||
installWarn: '當前未勾選端口外部訪問,將無法通過外網IP:端口訪問,是否繼續? ',
|
||||
restoreWarn: '恢復操作將刪除該應用當前數據並重啟。此操作不可回滾,是否繼續?',
|
||||
showIgnore: '查看忽略應用',
|
||||
cancelIgnore: '取消忽略',
|
||||
ignoreList: '忽略列表',
|
||||
},
|
||||
website: {
|
||||
website: '網站',
|
||||
|
@ -44,7 +44,7 @@ const message = {
|
||||
refresh: '刷新',
|
||||
get: '获取',
|
||||
upgrade: '升级',
|
||||
ignoreUpgrade: '忽略升级',
|
||||
ignore: '忽略升级',
|
||||
copy: '复制',
|
||||
random: '随机密码',
|
||||
},
|
||||
@ -1145,6 +1145,9 @@ const message = {
|
||||
upgradeHelper: '异常应用需要先同步到正常状态',
|
||||
installWarn: '当前未勾选端口外部访问,将无法通过外网IP:端口访问,是否继续?',
|
||||
restoreWarn: '恢复操作将删除该应用当前数据并重启。此操作不可回滚,是否继续?',
|
||||
showIgnore: '查看忽略应用',
|
||||
cancelIgnore: '取消忽略',
|
||||
ignoreList: '忽略列表',
|
||||
},
|
||||
website: {
|
||||
website: '网站',
|
||||
|
85
frontend/src/views/app-store/installed/ignore/index.vue
Normal file
85
frontend/src/views/app-store/installed/ignore/index.vue
Normal file
@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<el-drawer :close-on-click-modal="false" v-model="open" size="30%">
|
||||
<template #header>
|
||||
<Header :header="$t('app.ignoreList')" :back="handleClose"></Header>
|
||||
</template>
|
||||
<el-row :gutter="5">
|
||||
<el-col v-for="(app, index) in apps" :key="index">
|
||||
<el-card class="app-margin">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-avatar shape="square" :size="60" :src="'data:image/png;base64,' + app.icon" />
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<span>{{ app.name }}</span>
|
||||
<div class="app-margin">
|
||||
<el-tag>{{ app.version }}</el-tag>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-button type="primary" link @click="cancelIngore(app.detailID)">
|
||||
{{ $t('app.cancelIgnore') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { GetIgnoredApp, IgnoreUpgrade } from '@/api/modules/app';
|
||||
import { ref } from 'vue';
|
||||
import Header from '@/components/drawer-header/index.vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import i18n from '@/lang';
|
||||
|
||||
const open = ref(false);
|
||||
const loading = ref(false);
|
||||
const apps = ref();
|
||||
const em = defineEmits(['close']);
|
||||
|
||||
const handleClose = () => {
|
||||
open.value = false;
|
||||
em('close', open);
|
||||
};
|
||||
|
||||
const acceptParams = () => {
|
||||
open.value = true;
|
||||
getApps();
|
||||
};
|
||||
|
||||
const getApps = async () => {
|
||||
try {
|
||||
const res = await GetIgnoredApp();
|
||||
apps.value = res.data;
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
const cancelIngore = async (id: number) => {
|
||||
loading.value = true;
|
||||
await IgnoreUpgrade({ detailID: id, operate: 'cancel' })
|
||||
.then(() => {
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.finally(() => {
|
||||
getApps();
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.app-margin {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
@ -46,6 +46,9 @@
|
||||
<el-button @click="sync" type="primary" link v-if="mode === 'installed' && data != null">
|
||||
{{ $t('app.sync') }}
|
||||
</el-button>
|
||||
<el-button @click="openIngore" type="primary" link v-if="mode === 'upgrade'">
|
||||
{{ $t('app.showIgnore') }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template #main>
|
||||
@ -164,10 +167,10 @@
|
||||
plain
|
||||
round
|
||||
size="small"
|
||||
@click="openOperate(installed, 'ignoreUpgrade')"
|
||||
@click="openOperate(installed, 'ignore')"
|
||||
v-if="mode === 'upgrade'"
|
||||
>
|
||||
{{ $t('commons.button.ignoreUpgrade') }}
|
||||
{{ $t('commons.button.ignore') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="h-button"
|
||||
@ -239,8 +242,8 @@
|
||||
<AppDelete ref="deleteRef" @close="search" />
|
||||
<AppParams ref="appParamRef" />
|
||||
<AppUpgrade ref="upgradeRef" @close="search" />
|
||||
|
||||
<PortJumpDialog ref="dialogPortJumpRef" />
|
||||
<AppIgnore ref="ignoreRef" @close="search" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@ -261,6 +264,7 @@ import AppResources from './check/index.vue';
|
||||
import AppDelete from './delete/index.vue';
|
||||
import AppParams from './detail/index.vue';
|
||||
import AppUpgrade from './upgrade/index.vue';
|
||||
import AppIgnore from './ignore/index.vue';
|
||||
import { App } from '@/api/interface/app';
|
||||
import Status from '@/components/status/index.vue';
|
||||
import { getAge } from '@/utils/util';
|
||||
@ -289,6 +293,7 @@ const checkRef = ref();
|
||||
const deleteRef = ref();
|
||||
const appParamRef = ref();
|
||||
const upgradeRef = ref();
|
||||
const ignoreRef = ref();
|
||||
const dialogPortJumpRef = ref();
|
||||
const tags = ref<App.Tag[]>([]);
|
||||
const activeTag = ref('all');
|
||||
@ -348,7 +353,7 @@ const goDashboard = async (port: any) => {
|
||||
const openOperate = (row: any, op: string) => {
|
||||
operateReq.installId = row.id;
|
||||
operateReq.operate = op;
|
||||
if (op == 'upgrade' || op == 'ignoreUpgrade') {
|
||||
if (op == 'upgrade' || op == 'ignore') {
|
||||
upgradeRef.value.acceptParams(row.id, row.name, op);
|
||||
} else if (op == 'delete') {
|
||||
AppInstalledDeleteCheck(row.id).then(async (res) => {
|
||||
@ -364,6 +369,10 @@ const openOperate = (row: any, op: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
const openIngore = () => {
|
||||
ignoreRef.value.acceptParams();
|
||||
};
|
||||
|
||||
const operate = async () => {
|
||||
open.value = false;
|
||||
loading.value = true;
|
||||
|
6
go.mod
6
go.mod
@ -47,7 +47,7 @@ require (
|
||||
github.com/subosito/gotenv v1.4.1
|
||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a
|
||||
github.com/swaggo/gin-swagger v1.5.3
|
||||
github.com/swaggo/swag v1.8.4
|
||||
github.com/swaggo/swag v1.16.1
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.41
|
||||
github.com/xlzd/gotp v0.0.0-20220817083547-a63b9d03d72f
|
||||
golang.org/x/crypto v0.9.0
|
||||
@ -245,11 +245,11 @@ require (
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/image v0.5.0 // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/mod v0.9.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/term v0.8.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
golang.org/x/tools v0.6.0 // indirect
|
||||
golang.org/x/tools v0.7.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
|
||||
google.golang.org/grpc v1.53.0 // indirect
|
||||
|
6
go.sum
6
go.sum
@ -845,6 +845,8 @@ github.com/swaggo/gin-swagger v1.5.3/go.mod h1:3XJKSfHjDMB5dBo/0rrTXidPmgLeqsX89
|
||||
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
|
||||
github.com/swaggo/swag v1.8.4 h1:oGB351qH1JqUqK1tsMYEE5qTBbPk394BhsZxmUfebcI=
|
||||
github.com/swaggo/swag v1.8.4/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBnseg=
|
||||
github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
|
||||
github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.194/go.mod h1:yrBKWhChnDqNz1xuXdSbWXG56XawEq0G5j1lg4VwBD4=
|
||||
@ -1011,6 +1013,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -1202,6 +1206,8 @@ golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
Loading…
Reference in New Issue
Block a user