mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-14 01:34:47 +08:00
feat: 应用增加 Web 访问地址 (#6248)
This commit is contained in:
parent
4ac5ff7cf0
commit
53cfb2e755
@ -325,3 +325,24 @@ func (b *BaseApi) IgnoreUpgrade(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
helper.SuccessWithOutData(c)
|
helper.SuccessWithOutData(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags App
|
||||||
|
// @Summary Update app config
|
||||||
|
// @Description 更新应用配置
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.AppConfigUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /apps/installed/config/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["installID","webUI"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用配置更新 [installID]","formatEN":"Application config update [installID]"}
|
||||||
|
func (b *BaseApi) UpdateAppConfig(c *gin.Context) {
|
||||||
|
var req request.AppConfigUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := appInstallService.UpdateAppConfig(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithOutData(c)
|
||||||
|
}
|
||||||
|
@ -37,6 +37,8 @@ type AppContainerConfig struct {
|
|||||||
HostMode bool `json:"hostMode"`
|
HostMode bool `json:"hostMode"`
|
||||||
PullImage bool `json:"pullImage"`
|
PullImage bool `json:"pullImage"`
|
||||||
GpuConfig bool `json:"gpuConfig"`
|
GpuConfig bool `json:"gpuConfig"`
|
||||||
|
WebUI string `json:"webUI"`
|
||||||
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppInstalledSearch struct {
|
type AppInstalledSearch struct {
|
||||||
@ -103,6 +105,11 @@ type AppInstalledUpdate struct {
|
|||||||
AppContainerConfig
|
AppContainerConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AppConfigUpdate struct {
|
||||||
|
InstallID uint `json:"installID" validate:"required"`
|
||||||
|
WebUI string `json:"webUI"`
|
||||||
|
}
|
||||||
|
|
||||||
type AppInstalledIgnoreUpgrade struct {
|
type AppInstalledIgnoreUpgrade struct {
|
||||||
DetailID uint `json:"detailID" validate:"required"`
|
DetailID uint `json:"detailID" validate:"required"`
|
||||||
Operate string `json:"operate" validate:"required,oneof=cancel ignore"`
|
Operate string `json:"operate" validate:"required,oneof=cancel ignore"`
|
||||||
|
@ -120,6 +120,7 @@ type AppInstallDTO struct {
|
|||||||
AppType string `json:"appType"`
|
AppType string `json:"appType"`
|
||||||
AppStatus string `json:"appStatus"`
|
AppStatus string `json:"appStatus"`
|
||||||
DockerCompose string `json:"dockerCompose"`
|
DockerCompose string `json:"dockerCompose"`
|
||||||
|
WebUI string `json:"webUI"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
App AppDetail `json:"app"`
|
App AppDetail `json:"app"`
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,9 @@ type AppInstall struct {
|
|||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
ContainerName string `json:"containerName" gorm:"not null"`
|
ContainerName string `json:"containerName" gorm:"not null"`
|
||||||
ServiceName string `json:"serviceName" gorm:"not null"`
|
ServiceName string `json:"serviceName" gorm:"not null"`
|
||||||
HttpPort int `json:"httpPort" gorm:"not null"`
|
HttpPort int `json:"httpPort"`
|
||||||
HttpsPort int `json:"httpsPort" gorm:"not null"`
|
HttpsPort int `json:"httpsPort"`
|
||||||
|
WebUI string `json:"webUI"`
|
||||||
App App `json:"app" gorm:"-:migration"`
|
App App `json:"app" gorm:"-:migration"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ type IAppInstallService interface {
|
|||||||
GetDefaultConfigByKey(key, name string) (string, error)
|
GetDefaultConfigByKey(key, name string) (string, error)
|
||||||
DeleteCheck(installId uint) ([]dto.AppResource, error)
|
DeleteCheck(installId uint) ([]dto.AppResource, error)
|
||||||
|
|
||||||
|
UpdateAppConfig(req request.AppConfigUpdate) error
|
||||||
GetInstallList() ([]dto.AppInstallInfo, error)
|
GetInstallList() ([]dto.AppInstallInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,6 +305,18 @@ func (a *AppInstallService) Operate(req request.AppInstalledOperate) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *AppInstallService) UpdateAppConfig(req request.AppConfigUpdate) error {
|
||||||
|
installed, err := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
installed.WebUI = ""
|
||||||
|
if req.WebUI != "" {
|
||||||
|
installed.WebUI = req.WebUI
|
||||||
|
}
|
||||||
|
return appInstallRepo.Save(context.Background(), &installed)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *AppInstallService) Update(req request.AppInstalledUpdate) error {
|
func (a *AppInstallService) Update(req request.AppInstalledUpdate) error {
|
||||||
installed, err := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallId))
|
installed, err := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -767,6 +780,8 @@ func (a *AppInstallService) GetParams(id uint) (*response.AppConfig, error) {
|
|||||||
}
|
}
|
||||||
res.AppContainerConfig = config
|
res.AppContainerConfig = config
|
||||||
res.HostMode = isHostModel(install.DockerCompose)
|
res.HostMode = isHostModel(install.DockerCompose)
|
||||||
|
res.WebUI = install.WebUI
|
||||||
|
res.Type = install.App.Type
|
||||||
return &res, nil
|
return &res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1363,6 +1363,7 @@ func handleInstalled(appInstallList []model.AppInstall, updated bool, sync bool)
|
|||||||
AppType: installed.App.Type,
|
AppType: installed.App.Type,
|
||||||
Path: installed.GetPath(),
|
Path: installed.GetPath(),
|
||||||
CreatedAt: installed.CreatedAt,
|
CreatedAt: installed.CreatedAt,
|
||||||
|
WebUI: installed.WebUI,
|
||||||
App: response.AppDetail{
|
App: response.AppDetail{
|
||||||
Github: installed.App.Github,
|
Github: installed.App.Github,
|
||||||
Website: installed.App.Website,
|
Website: installed.App.Website,
|
||||||
|
@ -20,6 +20,7 @@ func Init() {
|
|||||||
migrations.UpdateWebsiteDomain,
|
migrations.UpdateWebsiteDomain,
|
||||||
migrations.UpdateApp,
|
migrations.UpdateApp,
|
||||||
migrations.AddTaskDB,
|
migrations.AddTaskDB,
|
||||||
|
migrations.UpdateAppInstall,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
@ -251,3 +251,11 @@ var UpdateApp = &gormigrate.Migration{
|
|||||||
&model.App{})
|
&model.App{})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var UpdateAppInstall = &gormigrate.Migration{
|
||||||
|
ID: "20240828-update-app-install",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
return tx.AutoMigrate(
|
||||||
|
&model.AppInstall{})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -38,5 +38,6 @@ func (a *AppRouter) InitRouter(Router *gin.RouterGroup) {
|
|||||||
appRouter.POST("/installed/ignore", baseApi.IgnoreUpgrade)
|
appRouter.POST("/installed/ignore", baseApi.IgnoreUpgrade)
|
||||||
appRouter.GET("/ignored/detail", baseApi.GetIgnoredApp)
|
appRouter.GET("/ignored/detail", baseApi.GetIgnoredApp)
|
||||||
appRouter.POST("/installed/update/versions", baseApi.GetUpdateVersions)
|
appRouter.POST("/installed/update/versions", baseApi.GetUpdateVersions)
|
||||||
|
appRouter.POST("/installed/config/update", baseApi.UpdateAppConfig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,6 +239,8 @@ export namespace App {
|
|||||||
allowPort: boolean;
|
allowPort: boolean;
|
||||||
dockerCompose: string;
|
dockerCompose: string;
|
||||||
hostMode?: boolean;
|
hostMode?: boolean;
|
||||||
|
type: string;
|
||||||
|
webUI: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IgnoredApp {
|
export interface IgnoredApp {
|
||||||
@ -256,4 +258,9 @@ export namespace App {
|
|||||||
export interface AppStoreSync {
|
export interface AppStoreSync {
|
||||||
taskID: string;
|
taskID: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AppConfigUpdate {
|
||||||
|
installID: number;
|
||||||
|
webUI: string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,3 +106,7 @@ export const IgnoreUpgrade = (req: any) => {
|
|||||||
export const GetIgnoredApp = () => {
|
export const GetIgnoredApp = () => {
|
||||||
return http.get<App.IgnoredApp>(`apps/ignored/detail`);
|
return http.get<App.IgnoredApp>(`apps/ignored/detail`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const UpdateInstallConfig = (req: App.AppConfigUpdate) => {
|
||||||
|
return http.post(`apps/installed/config/update`, req);
|
||||||
|
};
|
||||||
|
@ -1883,6 +1883,8 @@ const message = {
|
|||||||
gpuConfig: 'Enable GPU Support',
|
gpuConfig: 'Enable GPU Support',
|
||||||
gpuConfigHelper:
|
gpuConfigHelper:
|
||||||
'Please ensure the machine has an NVIDIA GPU and that NVIDIA drivers and the NVIDIA Docker Container Toolkit are installed',
|
'Please ensure the machine has an NVIDIA GPU and that NVIDIA drivers and the NVIDIA Docker Container Toolkit are installed',
|
||||||
|
webUI: 'Web Access Address',
|
||||||
|
webUIPlaceholder: 'For example: http://example.com:8080/login',
|
||||||
},
|
},
|
||||||
website: {
|
website: {
|
||||||
website: 'Website',
|
website: 'Website',
|
||||||
|
@ -1748,6 +1748,8 @@ const message = {
|
|||||||
memoryRequiredHelper: '目前應用記憶體需求 {0}',
|
memoryRequiredHelper: '目前應用記憶體需求 {0}',
|
||||||
gpuConfig: '開啟 GPU 支援',
|
gpuConfig: '開啟 GPU 支援',
|
||||||
gpuConfigHelper: '請確保機器有 NVIDIA GPU 並且安裝 NVIDIA 驅動 和 NVIDIA docker Container Toolkit',
|
gpuConfigHelper: '請確保機器有 NVIDIA GPU 並且安裝 NVIDIA 驅動 和 NVIDIA docker Container Toolkit',
|
||||||
|
webUI: 'Web 訪問地址',
|
||||||
|
webUIPlaceholder: '例如:http://example.com:8080/login',
|
||||||
},
|
},
|
||||||
website: {
|
website: {
|
||||||
website: '網站',
|
website: '網站',
|
||||||
|
@ -1749,6 +1749,8 @@ const message = {
|
|||||||
memoryRequiredHelper: '当前应用内存需求 {0}',
|
memoryRequiredHelper: '当前应用内存需求 {0}',
|
||||||
gpuConfig: '开启 GPU 支持',
|
gpuConfig: '开启 GPU 支持',
|
||||||
gpuConfigHelper: '请确保机器有 NVIDIA GPU 并且安装 NVIDIA 驱动 和 NVIDIA docker Container Toolkit',
|
gpuConfigHelper: '请确保机器有 NVIDIA GPU 并且安装 NVIDIA 驱动 和 NVIDIA docker Container Toolkit',
|
||||||
|
webUI: 'Web 访问地址',
|
||||||
|
webUIPlaceholder: '例如:http://example.com:8080/login',
|
||||||
},
|
},
|
||||||
website: {
|
website: {
|
||||||
website: '网站',
|
website: '网站',
|
||||||
|
@ -5,15 +5,29 @@
|
|||||||
{{ edit ? $t('app.detail') : $t('commons.button.edit') }}
|
{{ edit ? $t('app.detail') : $t('commons.button.edit') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<el-descriptions border :column="1" v-if="!edit">
|
<div v-if="!edit">
|
||||||
<el-descriptions-item v-for="(param, key) in params" :label="getLabel(param)" :key="key">
|
<el-descriptions border :column="1">
|
||||||
<span>{{ param.showValue && param.showValue != '' ? param.showValue : param.value }}</span>
|
<el-descriptions-item v-for="(param, key) in params" :label="getLabel(param)" :key="key">
|
||||||
</el-descriptions-item>
|
<span>{{ param.showValue && param.showValue != '' ? param.showValue : param.value }}</span>
|
||||||
</el-descriptions>
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<el-form label-position="top" class="mt-2">
|
||||||
|
<el-form-item v-if="appType == 'website'" :label="$t('app.webUI')">
|
||||||
|
<el-input v-model="appConfigUpdate.webUI" :placeholder="$t('app.webUIPlaceholder')"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" :disabled="loading" @click="updateAppConfig">
|
||||||
|
{{ $t('commons.button.confirm') }}
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
<div v-else v-loading="loading">
|
<div v-else v-loading="loading">
|
||||||
<el-alert :title="$t('app.updateHelper')" type="warning" :closable="false" class="common-prompt" />
|
<el-alert :title="$t('app.updateHelper')" type="warning" :closable="false" class="common-prompt" />
|
||||||
<el-form @submit.prevent ref="paramForm" :model="paramModel" label-position="top" :rules="rules">
|
<el-form @submit.prevent ref="paramForm" :model="paramModel" label-position="top" :rules="rules">
|
||||||
|
<el-form-item v-if="appType == 'website'" :label="$t('app.webUI')">
|
||||||
|
<el-input v-model="appConfigUpdate.webUI" :placeholder="$t('app.webUIPlaceholder')"></el-input>
|
||||||
|
</el-form-item>
|
||||||
<div v-for="(p, index) in params" :key="index">
|
<div v-for="(p, index) in params" :key="index">
|
||||||
<el-form-item :prop="p.key" :label="getLabel(p)">
|
<el-form-item :prop="p.key" :label="getLabel(p)">
|
||||||
<el-input
|
<el-input
|
||||||
@ -93,7 +107,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { App } from '@/api/interface/app';
|
import { App } from '@/api/interface/app';
|
||||||
import { GetAppInstallParams, UpdateAppInstallParams } from '@/api/modules/app';
|
import { GetAppInstallParams, UpdateAppInstallParams, UpdateInstallConfig } from '@/api/modules/app';
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { FormInstance } from 'element-plus';
|
import { FormInstance } from 'element-plus';
|
||||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||||
@ -128,7 +142,14 @@ const rules = reactive({
|
|||||||
memoryLimit: [Rules.requiredInput, checkNumberRange(0, 9999999999)],
|
memoryLimit: [Rules.requiredInput, checkNumberRange(0, 9999999999)],
|
||||||
containerName: [Rules.containerName],
|
containerName: [Rules.containerName],
|
||||||
});
|
});
|
||||||
const submitModel = ref<any>({});
|
const submitModel = ref<any>({
|
||||||
|
webUI: '',
|
||||||
|
});
|
||||||
|
const appType = ref('');
|
||||||
|
const appConfigUpdate = ref<App.AppConfigUpdate>({
|
||||||
|
installID: 0,
|
||||||
|
webUI: '',
|
||||||
|
});
|
||||||
|
|
||||||
const acceptParams = async (props: ParamProps) => {
|
const acceptParams = async (props: ParamProps) => {
|
||||||
submitModel.value.installId = props.id;
|
submitModel.value.installId = props.id;
|
||||||
@ -188,6 +209,8 @@ const get = async () => {
|
|||||||
paramModel.value.advanced = false;
|
paramModel.value.advanced = false;
|
||||||
paramModel.value.dockerCompose = res.data.dockerCompose;
|
paramModel.value.dockerCompose = res.data.dockerCompose;
|
||||||
paramModel.value.isHostMode = res.data.hostMode;
|
paramModel.value.isHostMode = res.data.hostMode;
|
||||||
|
appConfigUpdate.value.webUI = res.data.webUI;
|
||||||
|
appType.value = res.data.type;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@ -240,6 +263,17 @@ const submit = async (formEl: FormInstance) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateAppConfig = async () => {
|
||||||
|
try {
|
||||||
|
await UpdateInstallConfig({
|
||||||
|
installID: Number(paramData.value.id),
|
||||||
|
webUI: appConfigUpdate.value.webUI,
|
||||||
|
});
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||||
|
handleClose();
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
defineExpose({ acceptParams });
|
defineExpose({ acceptParams });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -175,6 +175,22 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</span>
|
</span>
|
||||||
|
<span class="ml-1">
|
||||||
|
<el-tooltip
|
||||||
|
v-if="installed.webUI !== ''"
|
||||||
|
effect="dark"
|
||||||
|
:content="installed.webUI"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
@click="toLink(installed.webUI)"
|
||||||
|
>
|
||||||
|
<el-icon><Promotion /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</span>
|
||||||
|
|
||||||
<el-button
|
<el-button
|
||||||
class="h-button"
|
class="h-button"
|
||||||
@ -650,6 +666,10 @@ const openLog = (row: any) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toLink = (link: string) => {
|
||||||
|
window.open(link, '_blank');
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const path = router.currentRoute.value.path;
|
const path = router.currentRoute.value.path;
|
||||||
if (path == '/apps/upgrade') {
|
if (path == '/apps/upgrade') {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user