mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-09 07:00:48 +08:00
feat: add config for appstore (#8524)
This commit is contained in:
parent
4ecdbcb01f
commit
f94a04b067
31 changed files with 240 additions and 178 deletions
|
@ -142,3 +142,20 @@ func loadLocalConn() (*ssh.SSHClient, error) {
|
|||
}
|
||||
return ssh.NewClient(connInDB)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Load system setting by key
|
||||
// @Param key path string true "key"
|
||||
// @Success 200 {object} dto.SettingInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /settings/get/{key} [get]
|
||||
func (b *BaseApi) GetSettingByKey(c *gin.Context) {
|
||||
key := c.Param("key")
|
||||
if len(key) == 0 {
|
||||
helper.BadRequest(c, errors.New("key is empty"))
|
||||
return
|
||||
}
|
||||
value := settingService.GetSettingByKey(key)
|
||||
helper.SuccessWithData(c, value)
|
||||
}
|
||||
|
|
|
@ -129,5 +129,6 @@ type AppUpdateVersion struct {
|
|||
}
|
||||
|
||||
type AppstoreUpdate struct {
|
||||
DefaultDomain string `json:"defaultDomain"`
|
||||
Scope string `json:"scope" validate:"required,oneof=UninstallDeleteImage UpgradeBackup UninstallDeleteBackup"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
|
|
@ -165,5 +165,7 @@ type AppConfig struct {
|
|||
}
|
||||
|
||||
type AppstoreConfig struct {
|
||||
DefaultDomain string `json:"defaultDomain"`
|
||||
UninstallDeleteImage string `json:"uninstallDeleteImage"`
|
||||
UpgradeBackup string `json:"upgradeBackup"`
|
||||
UninstallDeleteBackup string `json:"uninstallDeleteBackup"`
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ func (s *SettingRepo) UpdateOrCreate(key, value string) error {
|
|||
result := global.DB.Where("key = ?", key).First(&setting)
|
||||
if result.Error != nil {
|
||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||
return global.DB.Create(&model.Setting{Key: key, Value: value}).Error
|
||||
return global.DB.Debug().Create(&model.Setting{Key: key, Value: value}).Error
|
||||
}
|
||||
return result.Error
|
||||
}
|
||||
|
|
|
@ -1160,12 +1160,22 @@ func (a AppService) SyncAppListFromRemote(taskID string) (err error) {
|
|||
|
||||
func (a AppService) UpdateAppstoreConfig(req request.AppstoreUpdate) error {
|
||||
settingService := NewISettingService()
|
||||
return settingService.Update("AppDefaultDomain", req.DefaultDomain)
|
||||
return settingService.Update(req.Scope, req.Status)
|
||||
}
|
||||
|
||||
func (a AppService) GetAppstoreConfig() (*response.AppstoreConfig, error) {
|
||||
defaultDomain, _ := settingRepo.Get(settingRepo.WithByKey("AppDefaultDomain"))
|
||||
res := &response.AppstoreConfig{}
|
||||
res.DefaultDomain = defaultDomain.Value
|
||||
res.UninstallDeleteImage, _ = settingRepo.GetValueByKey("UninstallDeleteImage")
|
||||
if res.UninstallDeleteImage == "" {
|
||||
res.UninstallDeleteImage = "False"
|
||||
}
|
||||
res.UpgradeBackup, _ = settingRepo.GetValueByKey("UpgradeBackup")
|
||||
if res.UpgradeBackup == "" {
|
||||
res.UpgradeBackup = "False"
|
||||
}
|
||||
res.UninstallDeleteBackup, _ = settingRepo.GetValueByKey("UninstallDeleteBackup")
|
||||
if res.UninstallDeleteBackup == "" {
|
||||
res.UninstallDeleteBackup = "False"
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ type ISettingService interface {
|
|||
TestConnByInfo(req dto.SSHConnData) bool
|
||||
SaveConnInfo(req dto.SSHConnData) error
|
||||
GetSystemProxy() (*dto.SystemProxy, error)
|
||||
GetSettingByKey(key string) string
|
||||
}
|
||||
|
||||
func NewISettingService() ISettingService {
|
||||
|
@ -136,3 +137,13 @@ func (u *SettingService) GetSystemProxy() (*dto.SystemProxy, error) {
|
|||
systemProxy.Password, _ = encrypt.StringDecrypt(passwd)
|
||||
return &systemProxy, nil
|
||||
}
|
||||
|
||||
func (u *SettingService) GetSettingByKey(key string) string {
|
||||
switch key {
|
||||
case "SystemIP":
|
||||
value, _ := settingRepo.GetValueByKey(key)
|
||||
return value
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ func UseI18n() gin.HandlerFunc {
|
|||
return func(context *gin.Context) {
|
||||
lang := context.GetHeader("Accept-Language")
|
||||
if lang == "" {
|
||||
lang = "zh"
|
||||
lang = "en"
|
||||
}
|
||||
global.I18n = i18n.NewLocalizer(bundle, lang)
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ func (s *SettingRouter) InitRouter(Router *gin.RouterGroup) {
|
|||
settingRouter.POST("/search", baseApi.GetSettingInfo)
|
||||
settingRouter.GET("/search/available", baseApi.GetSystemAvailable)
|
||||
settingRouter.POST("/update", baseApi.UpdateSetting)
|
||||
settingRouter.GET("/get/:key", baseApi.GetSettingByKey)
|
||||
|
||||
settingRouter.GET("/snapshot/load", baseApi.LoadSnapshotData)
|
||||
settingRouter.POST("/snapshot", baseApi.CreateSnapshot)
|
||||
|
|
|
@ -113,7 +113,7 @@ func UseI18n() gin.HandlerFunc {
|
|||
return func(context *gin.Context) {
|
||||
lang := context.GetHeader("Accept-Language")
|
||||
if lang == "" {
|
||||
lang = "zh"
|
||||
lang = "en"
|
||||
}
|
||||
global.I18n = i18n.NewLocalizer(bundle, lang)
|
||||
}
|
||||
|
@ -176,3 +176,7 @@ func GetMsgWithMapForCmd(key string, maps map[string]interface{}) string {
|
|||
return content
|
||||
}
|
||||
}
|
||||
|
||||
func GetLanguageFromDB() {
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"crypto/tls"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/core/init/db"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
@ -13,7 +14,6 @@ import (
|
|||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
"github.com/1Panel-dev/1Panel/core/i18n"
|
||||
"github.com/1Panel-dev/1Panel/core/init/cron"
|
||||
"github.com/1Panel-dev/1Panel/core/init/db"
|
||||
"github.com/1Panel-dev/1Panel/core/init/hook"
|
||||
"github.com/1Panel-dev/1Panel/core/init/lang"
|
||||
"github.com/1Panel-dev/1Panel/core/init/log"
|
||||
|
@ -29,9 +29,9 @@ import (
|
|||
|
||||
func Start() {
|
||||
viper.Init()
|
||||
db.Init()
|
||||
i18n.Init()
|
||||
log.Init()
|
||||
db.Init()
|
||||
migration.Init()
|
||||
validator.Init()
|
||||
lang.Init()
|
||||
|
|
|
@ -295,7 +295,14 @@ export namespace App {
|
|||
}
|
||||
|
||||
export interface AppStoreConfig {
|
||||
defaultDomain: string;
|
||||
uninstallDeleteImage: string;
|
||||
uninstallDeleteBackup: string;
|
||||
upgradeBackup: string;
|
||||
}
|
||||
|
||||
export interface AppStoreConfigUpdate {
|
||||
scope: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface CustomAppStoreConfig {
|
||||
|
|
|
@ -115,7 +115,7 @@ export const getAppStoreConfig = () => {
|
|||
return http.get<App.AppStoreConfig>(`apps/store/config`);
|
||||
};
|
||||
|
||||
export const updateAppStoreConfig = (req: App.AppStoreConfig) => {
|
||||
export const updateAppStoreConfig = (req: App.AppStoreConfigUpdate) => {
|
||||
return http.post(`apps/store/update`, req);
|
||||
};
|
||||
|
||||
|
|
|
@ -60,6 +60,9 @@ export const updateAgentSetting = (param: Setting.SettingUpdate) => {
|
|||
export const getAgentSettingInfo = () => {
|
||||
return http.post<Setting.SettingInfo>(`/settings/search`);
|
||||
};
|
||||
export const getAgentSettingByKey = (key: string) => {
|
||||
return http.get<string>(`/settings/get/${key}`);
|
||||
};
|
||||
|
||||
// core
|
||||
export const getSettingInfo = () => {
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
<template>
|
||||
<DrawerPro v-model="open" size="large" :header="$t('menu.msgCenter')" @close="handleClose">
|
||||
<DrawerPro
|
||||
v-model="open"
|
||||
size="large"
|
||||
:header="$t('menu.msgCenter')"
|
||||
:resource="globalStore.currentNode"
|
||||
@close="handleClose"
|
||||
>
|
||||
<template #content>
|
||||
<LayoutContent v-loading="loading" :title="$t('logs.task')">
|
||||
<template #rightToolBar>
|
||||
|
@ -50,6 +56,8 @@ import { reactive, ref } from '@vue/runtime-core';
|
|||
import { Log } from '@/api/interface/log';
|
||||
import TaskLog from '@/components/log/task/index.vue';
|
||||
import bus from '@/global/bus';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const open = ref(false);
|
||||
const handleClose = () => {
|
||||
|
|
|
@ -2130,6 +2130,9 @@ const message = {
|
|||
specifyIP: 'Bind Host IP',
|
||||
specifyIPHelper:
|
||||
'Set the host address/network interface to bind the port (if you are not sure about this, please do not fill it in)',
|
||||
uninstallDeleteBackup: 'Uninstall App Deletes Backup',
|
||||
uninstallDeleteImage: 'Uninstall App Deletes Image',
|
||||
upgradeBackup: 'Backup Before Upgrading App',
|
||||
},
|
||||
website: {
|
||||
primaryDomain: 'Primary Domain',
|
||||
|
|
|
@ -2035,6 +2035,9 @@ const message = {
|
|||
specifyIP: 'ホスト IP をバインド',
|
||||
specifyIPHelper:
|
||||
'ポートにバインドするホストアドレス/ネットワークインターフェースを設定します(この機能がわからない場合は、入力しないでください)',
|
||||
uninstallDeleteBackup: 'アプリをアンインストールしてバックアップを削除',
|
||||
uninstallDeleteImage: 'アプリをアンインストールしてイメージを削除',
|
||||
upgradeBackup: 'アプリのアップグレード前にバックアップ',
|
||||
},
|
||||
website: {
|
||||
primaryDomain: 'プライマリドメイン',
|
||||
|
|
|
@ -2000,6 +2000,9 @@ const message = {
|
|||
specifyIP: '호스트 IP 바인딩',
|
||||
specifyIPHelper:
|
||||
'포트 바인딩을 위한 호스트 주소/네트워크 인터페이스를 설정합니다 (이 기능을 잘 모를 경우, 입력하지 마십시오)',
|
||||
uninstallDeleteBackup: '앱 제거 및 백업 삭제',
|
||||
uninstallDeleteImage: '앱 제거 및 이미지 삭제',
|
||||
upgradeBackup: '앱 업그레이드 전 백업',
|
||||
},
|
||||
website: {
|
||||
primaryDomain: '기본 도메인',
|
||||
|
|
|
@ -2088,6 +2088,9 @@ const message = {
|
|||
specifyIP: 'Bind IP Hos',
|
||||
specifyIPHelper:
|
||||
'Tetapkan alamat hos/antara muka rangkaian untuk mengikat port (jika anda tidak pasti mengenai ini, jangan isi)',
|
||||
uninstallDeleteBackup: 'Cop Terhapus Semasa Nyahpasang Aplikasi',
|
||||
uninstallDeleteImage: 'Imej Terhapus Semasa Nyahpasang Aplikasi',
|
||||
upgradeBackup: 'Sandaran Sebelum Naik Taraf Aplikasi',
|
||||
},
|
||||
website: {
|
||||
primaryDomain: 'Domain Utama',
|
||||
|
|
|
@ -2080,6 +2080,9 @@ const message = {
|
|||
specifyIP: 'Vincular IP do Host',
|
||||
specifyIPHelper:
|
||||
'Defina o endereço do host/interface de rede para vincular a porta (se você não tiver certeza sobre isso, por favor, não preencha)',
|
||||
uninstallDeleteBackup: 'Desinstalar Aplicativo Deleta Backup',
|
||||
uninstallDeleteImage: 'Desinstalar Aplicativo Deleta Imagem',
|
||||
upgradeBackup: 'Fazer Backup Antes de Atualizar o Aplicativo',
|
||||
},
|
||||
website: {
|
||||
primaryDomain: 'Domínio principal',
|
||||
|
|
|
@ -2081,6 +2081,9 @@ const message = {
|
|||
specifyIP: 'Привязать IP хоста',
|
||||
specifyIPHelper:
|
||||
'Установите адрес хоста/сетевого интерфейса для привязки порта (если вы не уверены в этом, пожалуйста, не заполняйте)',
|
||||
uninstallDeleteBackup: 'Деинсталляция приложения удаляет резервную копию',
|
||||
uninstallDeleteImage: 'Деинсталляция приложения удаляет образ',
|
||||
upgradeBackup: 'Резервное копирование перед обновлением приложения',
|
||||
},
|
||||
website: {
|
||||
primaryDomain: 'Основной домен',
|
||||
|
|
|
@ -1970,6 +1970,9 @@ const message = {
|
|||
ignoreVersion: '忽略指定版本',
|
||||
specifyIP: '綁定主機 IP',
|
||||
specifyIPHelper: '設置端口綁定的主機地址/網卡(如果你不清楚這個的作用,請不要填寫)',
|
||||
uninstallDeleteBackup: '卸載應用刪除備份',
|
||||
uninstallDeleteImage: '卸載應用刪除鏡像',
|
||||
upgradeBackup: '升級應用前備份',
|
||||
},
|
||||
website: {
|
||||
primaryDomain: '主域名',
|
||||
|
|
|
@ -1960,6 +1960,9 @@ const message = {
|
|||
ignoreVersion: '忽略指定版本',
|
||||
specifyIP: '绑定主机 IP',
|
||||
specifyIPHelper: '设置端口绑定的主机地址/网卡(如果你不清楚这个的作用,请不要填写)',
|
||||
uninstallDeleteBackup: '卸载应用删除备份',
|
||||
uninstallDeleteImage: '卸载应用删除镜像',
|
||||
upgradeBackup: '升级应用前备份',
|
||||
},
|
||||
website: {
|
||||
primaryDomain: '主域名',
|
||||
|
|
|
@ -14,8 +14,6 @@ import i18n from '@/lang';
|
|||
import { onMounted, ref } from 'vue';
|
||||
import { searchAppInstalled } from '@/api/modules/app';
|
||||
import bus from '@/global/bus';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
let showButton = ref(false);
|
||||
|
||||
let buttons = [
|
||||
|
@ -32,9 +30,6 @@ let buttons = [
|
|||
path: '/apps/upgrade',
|
||||
count: 0,
|
||||
},
|
||||
];
|
||||
|
||||
const settingButtons = [
|
||||
{
|
||||
label: i18n.global.t('commons.button.set'),
|
||||
path: '/apps/setting',
|
||||
|
@ -56,10 +51,6 @@ const search = () => {
|
|||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (globalStore.isProductPro) {
|
||||
buttons = buttons.concat(settingButtons);
|
||||
}
|
||||
|
||||
search();
|
||||
bus.on('upgrade', () => {
|
||||
showButton.value = false;
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
import { FormInstance } from 'element-plus';
|
||||
import { onBeforeUnmount, ref } from 'vue';
|
||||
import { App } from '@/api/interface/app';
|
||||
import { installedOp } from '@/api/modules/app';
|
||||
import { getAppStoreConfig, installedOp } from '@/api/modules/app';
|
||||
import i18n from '@/lang';
|
||||
import bus from '@/global/bus';
|
||||
import TaskLog from '@/components/log/task/index.vue';
|
||||
|
@ -79,13 +79,14 @@ const handleClose = () => {
|
|||
};
|
||||
|
||||
const acceptParams = async (app: App.AppInstallDto) => {
|
||||
const config = await getAppStoreConfig();
|
||||
deleteReq.value = {
|
||||
operate: 'delete',
|
||||
installId: 0,
|
||||
deleteBackup: false,
|
||||
deleteBackup: config.data.uninstallDeleteBackup === 'True',
|
||||
forceDelete: false,
|
||||
deleteDB: true,
|
||||
deleteImage: false,
|
||||
deleteImage: config.data.uninstallDeleteImage === 'True',
|
||||
taskID: uuidv4(),
|
||||
};
|
||||
deleteInfo.value = '';
|
||||
|
|
|
@ -14,13 +14,19 @@
|
|||
{{ $t('commons.button.edit') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<el-input v-else v-model="appConfigUpdate.webUI" :placeholder="$t('app.webUIPlaceholder')">
|
||||
<template #append>
|
||||
<el-button type="primary" @click="updateAppConfig">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<span class="flex" v-else>
|
||||
<el-input v-model="webUI.domain" :placeholder="$t('app.webUIPlaceholder')">
|
||||
<template #prepend>
|
||||
<el-select v-model="webUI.protocol" class="pre-select">
|
||||
<el-option label="http" value="http://" />
|
||||
<el-option label="https" value="https://" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button type="primary" @click="updateAppConfig" class="ml-2">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item v-for="(param, key) in params" :label="getLabel(param)" :key="key">
|
||||
<span>{{ param.showValue && param.showValue != '' ? param.showValue : param.value }}</span>
|
||||
|
@ -125,7 +131,7 @@ import { reactive, ref } from 'vue';
|
|||
import { FormInstance } from 'element-plus';
|
||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { getLabel } from '@/utils/util';
|
||||
import { getLabel, splitHttp } from '@/utils/util';
|
||||
import i18n from '@/lang';
|
||||
|
||||
interface ParamProps {
|
||||
|
@ -141,6 +147,7 @@ interface EditForm extends App.InstallParams {
|
|||
default: any;
|
||||
}
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
const open = ref(false);
|
||||
const loading = ref(false);
|
||||
const params = ref<EditForm[]>();
|
||||
|
@ -164,6 +171,10 @@ const appConfigUpdate = ref<App.AppConfigUpdate>({
|
|||
webUI: '',
|
||||
});
|
||||
const openConfig = ref(false);
|
||||
const webUI = reactive({
|
||||
protocol: 'http://',
|
||||
domain: '',
|
||||
});
|
||||
|
||||
const acceptParams = async (props: ParamProps) => {
|
||||
submitModel.value.installId = props.id;
|
||||
|
@ -177,6 +188,7 @@ const acceptParams = async (props: ParamProps) => {
|
|||
};
|
||||
|
||||
const handleClose = () => {
|
||||
emit('close');
|
||||
open.value = false;
|
||||
};
|
||||
const editParam = () => {
|
||||
|
@ -227,6 +239,11 @@ const get = async () => {
|
|||
paramModel.value.isHostMode = res.data.hostMode;
|
||||
paramModel.value.specifyIP = res.data.specifyIP;
|
||||
appConfigUpdate.value.webUI = res.data.webUI;
|
||||
if (res.data.webUI != '') {
|
||||
const httpConfig = splitHttp(res.data.webUI);
|
||||
webUI.domain = httpConfig.url;
|
||||
webUI.protocol = httpConfig.proto;
|
||||
}
|
||||
appType.value = res.data.type;
|
||||
} catch (error) {
|
||||
} finally {
|
||||
|
@ -272,10 +289,13 @@ const submit = async (formEl: FormInstance) => {
|
|||
};
|
||||
|
||||
const updateAppConfig = async () => {
|
||||
if (!webUI.domain || webUI.domain === '') {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await updateInstallConfig({
|
||||
installID: Number(paramData.value.id),
|
||||
webUI: appConfigUpdate.value.webUI,
|
||||
webUI: webUI.protocol + webUI.domain,
|
||||
});
|
||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||
handleClose();
|
||||
|
|
|
@ -413,13 +413,13 @@
|
|||
<Uploads ref="uploadRef" />
|
||||
<AppResources ref="checkRef" @close="search" />
|
||||
<AppDelete ref="deleteRef" @close="search" />
|
||||
<AppParams ref="appParamRef" />
|
||||
<AppParams ref="appParamRef" @close="search" />
|
||||
<AppUpgrade ref="upgradeRef" @close="search" />
|
||||
<PortJumpDialog ref="dialogPortJumpRef" />
|
||||
<AppIgnore ref="ignoreRef" @close="search" />
|
||||
<ComposeLogs ref="composeLogRef" />
|
||||
<TaskLog ref="taskLogRef" @close="search" />
|
||||
<Detail ref="detailRef" />
|
||||
<Detail ref="detailRef" @close="search" />
|
||||
<IgnoreApp ref="ignoreAppRef" @close="search" />
|
||||
</template>
|
||||
|
||||
|
@ -430,7 +430,6 @@ import {
|
|||
syncInstalledApp,
|
||||
appInstalledDeleteCheck,
|
||||
getAppTags,
|
||||
getAppStoreConfig,
|
||||
} from '@/api/modules/app';
|
||||
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
|
@ -453,6 +452,7 @@ import { toFolder } from '@/global/business';
|
|||
import TaskLog from '@/components/log/task/index.vue';
|
||||
import Detail from '@/views/app-store/detail/index.vue';
|
||||
import IgnoreApp from '@/views/app-store/installed/ignore/create/index.vue';
|
||||
import { getAgentSettingByKey } from '@/api/modules/setting';
|
||||
|
||||
const data = ref<any>();
|
||||
const loading = ref(false);
|
||||
|
@ -773,9 +773,9 @@ const openLog = (row: any) => {
|
|||
|
||||
const getConfig = async () => {
|
||||
try {
|
||||
const res = await getAppStoreConfig();
|
||||
if (res.data.defaultDomain != '') {
|
||||
defaultLink.value = res.data.defaultDomain;
|
||||
const res = await getAgentSettingByKey('SystemIP');
|
||||
if (res.data != '') {
|
||||
defaultLink.value = res.data;
|
||||
}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { App } from '@/api/interface/app';
|
||||
import { getAppUpdateVersions, ignoreUpgrade, installedOp } from '@/api/modules/app';
|
||||
import { getAppStoreConfig, getAppUpdateVersions, ignoreUpgrade, installedOp } from '@/api/modules/app';
|
||||
import i18n from '@/lang';
|
||||
import { ElMessageBox, FormInstance } from 'element-plus';
|
||||
import { reactive, ref, onBeforeUnmount } from 'vue';
|
||||
|
@ -156,10 +156,11 @@ const getNewCompose = (compose: string) => {
|
|||
}
|
||||
};
|
||||
|
||||
const initData = () => {
|
||||
const initData = async () => {
|
||||
const config = await getAppStoreConfig();
|
||||
newCompose.value = '';
|
||||
useNewCompose.value = false;
|
||||
operateReq.backup = true;
|
||||
operateReq.backup = config.data.upgradeBackup == 'True';
|
||||
operateReq.pullImage = true;
|
||||
operateReq.dockerCompose = '';
|
||||
};
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
<template>
|
||||
<DrawerPro v-model="drawerVisible" :header="$t('app.defaultWebDomain')" @close="handleClose" size="small">
|
||||
<el-form ref="formRef" label-position="top" :model="form" :rules="rules" @submit.prevent v-loading="loading">
|
||||
<el-form-item :label="$t('app.defaultWebDomain')" prop="defaultDomain">
|
||||
<el-input v-model="form.defaultDomain"></el-input>
|
||||
<span class="input-help">{{ $t('app.defaultWebDomainHepler') }}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="handleClose()">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="submit()">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</DrawerPro>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { updateAppStoreConfig } from '@/api/modules/app';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
||||
const emit = defineEmits<{ (e: 'close'): void }>();
|
||||
const drawerVisible = ref();
|
||||
const loading = ref();
|
||||
const form = reactive({
|
||||
defaultDomain: '',
|
||||
});
|
||||
const rules = reactive({
|
||||
defaultDomain: [Rules.requiredInput, Rules.ipV4V6OrDomain],
|
||||
});
|
||||
const formRef = ref<FormInstance>();
|
||||
interface DialogProps {
|
||||
domain: string;
|
||||
}
|
||||
|
||||
const acceptParams = (config: DialogProps): void => {
|
||||
form.defaultDomain = config.domain;
|
||||
drawerVisible.value = true;
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
drawerVisible.value = false;
|
||||
emit('close');
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
if (!formRef.value) return;
|
||||
await formRef.value.validate(async (valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
const req = {
|
||||
defaultDomain: form.defaultDomain,
|
||||
};
|
||||
await updateAppStoreConfig(req);
|
||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||
} catch (error) {
|
||||
} finally {
|
||||
loading.value = false;
|
||||
handleClose();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
|
@ -12,15 +12,32 @@
|
|||
>
|
||||
<el-row>
|
||||
<el-col :xs="24" :sm="20" :md="15" :lg="12" :xl="12">
|
||||
<el-form-item :label="$t('app.defaultWebDomain')" prop="defaultDomain">
|
||||
<el-input v-model="config.defaultDomain" disabled>
|
||||
<template #append>
|
||||
<el-button @click="setDefaultDomain()" icon="Setting">
|
||||
{{ $t('commons.button.set') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<span class="input-help">{{ $t('app.defaultWebDomainHepler') }}</span>
|
||||
<el-form-item :label="$t('app.uninstallDeleteBackup')" prop="uninstallDeleteBackup">
|
||||
<el-switch
|
||||
v-model="config.uninstallDeleteBackup"
|
||||
active-value="True"
|
||||
inactive-value="False"
|
||||
:loading="loading"
|
||||
@change="updateConfig('UninstallDeleteBackup', config.uninstallDeleteBackup)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('app.uninstallDeleteImage')" prop="uninstallDeleteImage">
|
||||
<el-switch
|
||||
v-model="config.uninstallDeleteImage"
|
||||
active-value="True"
|
||||
inactive-value="False"
|
||||
:loading="loading"
|
||||
@change="updateConfig('UninstallDeleteImage', config.uninstallDeleteImage)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('app.upgradeBackup')" prop="upgradeBackup">
|
||||
<el-switch
|
||||
v-model="config.upgradeBackup"
|
||||
active-value="True"
|
||||
inactive-value="False"
|
||||
:loading="loading"
|
||||
@change="updateConfig('UpgradeBackup', config.upgradeBackup)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<CustomSetting v-if="globalStore.isProductPro" />
|
||||
</el-col>
|
||||
|
@ -28,35 +45,38 @@
|
|||
</el-form>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
<DefaultDomain ref="domainRef" @close="search" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getAppStoreConfig, getCurrentNodeCustomAppConfig } from '@/api/modules/app';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { getAppStoreConfig, getCurrentNodeCustomAppConfig, updateAppStoreConfig } from '@/api/modules/app';
|
||||
import { FormRules } from 'element-plus';
|
||||
import CustomSetting from '@/xpack/views/appstore/index.vue';
|
||||
import DefaultDomain from './default-domain/index.vue';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import i18n from '@/lang';
|
||||
|
||||
const globalStore = GlobalStore();
|
||||
const rules = ref<FormRules>({
|
||||
defaultDomain: [Rules.domainOrIP],
|
||||
});
|
||||
const rules = ref<FormRules>({});
|
||||
const config = ref({
|
||||
defaultDomain: '',
|
||||
uninstallDeleteImage: '',
|
||||
uninstallDeleteBackup: '',
|
||||
upgradeBackup: '',
|
||||
});
|
||||
const loading = ref(false);
|
||||
const configForm = ref();
|
||||
const domainRef = ref();
|
||||
const useCustomApp = ref(false);
|
||||
const isInitializing = ref(true);
|
||||
|
||||
const search = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getAppStoreConfig();
|
||||
if (res.data.defaultDomain != '') {
|
||||
config.value.defaultDomain = res.data.defaultDomain;
|
||||
if (res && res.data) {
|
||||
isInitializing.value = true;
|
||||
config.value = res.data;
|
||||
setTimeout(() => {
|
||||
isInitializing.value = false;
|
||||
}, 0);
|
||||
}
|
||||
} catch (error) {
|
||||
} finally {
|
||||
|
@ -64,12 +84,6 @@ const search = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
const setDefaultDomain = () => {
|
||||
domainRef.value.acceptParams({
|
||||
domain: config.value.defaultDomain,
|
||||
});
|
||||
};
|
||||
|
||||
const getNodeConfig = async () => {
|
||||
if (globalStore.isMasterProductPro) {
|
||||
return;
|
||||
|
@ -80,6 +94,25 @@ const getNodeConfig = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
const updateConfig = async (scope: string, value: string) => {
|
||||
if (isInitializing.value) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
const req = {
|
||||
scope: scope,
|
||||
status: value,
|
||||
};
|
||||
await updateAppStoreConfig(req);
|
||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||
search();
|
||||
} catch (error) {
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
search();
|
||||
getNodeConfig();
|
||||
|
|
|
@ -23,40 +23,36 @@
|
|||
</template>
|
||||
</el-alert>
|
||||
<el-form :model="form" ref="formRef" @submit.prevent v-loading="loading" label-position="top" :rules="rules">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('setting.apiKey')" prop="apiKey">
|
||||
<el-input v-model="form.apiKey" readonly>
|
||||
<template #suffix>
|
||||
<CopyButton type="icon" :content="form.apiKey" class="w-30" />
|
||||
</template>
|
||||
<template #append>
|
||||
<el-button @click="resetApiKey()">
|
||||
{{ $t('commons.button.reset') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<span class="input-help">{{ $t('setting.apiKeyHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.ipWhiteList')" prop="ipWhiteList">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:placeholder="$t('setting.ipWhiteListEgs')"
|
||||
:rows="4"
|
||||
v-model="form.ipWhiteList"
|
||||
/>
|
||||
<span class="input-help">{{ $t('setting.ipWhiteListHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.apiKeyValidityTime')" prop="apiKeyValidityTime">
|
||||
<el-input :placeholder="$t('setting.apiKeyValidityTimeEgs')" v-model="form.apiKeyValidityTime">
|
||||
<template #append>{{ $t('commons.units.minute') }}</template>
|
||||
</el-input>
|
||||
<span class="input-help">
|
||||
{{ $t('setting.apiKeyValidityTimeHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item :label="$t('setting.apiKey')" prop="apiKey">
|
||||
<el-input v-model="form.apiKey" readonly>
|
||||
<template #suffix>
|
||||
<CopyButton type="icon" :content="form.apiKey" class="w-30" />
|
||||
</template>
|
||||
<template #append>
|
||||
<el-button @click="resetApiKey()">
|
||||
{{ $t('commons.button.reset') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<span class="input-help">{{ $t('setting.apiKeyHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.ipWhiteList')" prop="ipWhiteList">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:placeholder="$t('setting.ipWhiteListEgs')"
|
||||
:rows="4"
|
||||
v-model="form.ipWhiteList"
|
||||
/>
|
||||
<span class="input-help">{{ $t('setting.ipWhiteListHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.apiKeyValidityTime')" prop="apiKeyValidityTime">
|
||||
<el-input :placeholder="$t('setting.apiKeyValidityTimeEgs')" v-model="form.apiKeyValidityTime">
|
||||
<template #append>{{ $t('commons.units.minute') }}</template>
|
||||
</el-input>
|
||||
<span class="input-help">
|
||||
{{ $t('setting.apiKeyValidityTimeHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
|
|
|
@ -686,7 +686,7 @@ const changeType = (type: string) => {
|
|||
switch (type) {
|
||||
case 'deployment':
|
||||
website.value.appType = 'installed';
|
||||
if (appInstalls.value && appInstalls.value.length > 0) {
|
||||
if (appInstalls.value && appInstalls.value.length > 0 && appInstalls.value[0].status === 'Running') {
|
||||
website.value.appInstallId = appInstalls.value[0].id;
|
||||
}
|
||||
break;
|
||||
|
@ -713,7 +713,12 @@ const searchAppInstalled = (appType: string) => {
|
|||
getAppInstalled({ type: appType, unused: true, all: true, page: 1, pageSize: 100 }).then((res) => {
|
||||
appInstalls.value = res.data.items;
|
||||
website.value.appInstallId = undefined;
|
||||
if (appType == 'website' && res.data.items && res.data.items.length > 0) {
|
||||
if (
|
||||
appType == 'website' &&
|
||||
res.data.items &&
|
||||
res.data.items.length > 0 &&
|
||||
res.data.items[0].status === 'Running'
|
||||
) {
|
||||
website.value.appInstallId = res.data.items[0].id;
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue