mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-11-09 11:10:34 +08:00
feat: Add MySQL master-slave installation feature (#9505)
This commit is contained in:
parent
7d5f0aa906
commit
c391177d34
30 changed files with 295 additions and 56 deletions
|
|
@ -327,3 +327,25 @@ func (b *BaseApi) UpdateAppConfig(c *gin.Context) {
|
|||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Get app install info
|
||||
// @Accept json
|
||||
// @Param appInstallId path integer true "App install id"
|
||||
// @Success 200 {object} dto.AppInstallInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /apps/installed/info/:appInstallId [get]
|
||||
func (b *BaseApi) GetAppInstallInfo(c *gin.Context) {
|
||||
appInstallId, err := helper.GetIntParamByKey(c, "appInstallId")
|
||||
if err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
info, err := appInstallService.GetAppInstallInfo(appInstallId)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, info)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,6 +129,19 @@ type AppInstallDTO struct {
|
|||
Container string `json:"container"`
|
||||
}
|
||||
|
||||
type AppInstallInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
HttpPort int `json:"HttpPort"`
|
||||
Container string `json:"container"`
|
||||
ComposePath string `json:"composePath"`
|
||||
|
||||
Env map[string]interface{} `json:"env"`
|
||||
}
|
||||
|
||||
type DatabaseConn struct {
|
||||
Status string `json:"status"`
|
||||
Username string `json:"username"`
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ type IAppInstallService interface {
|
|||
|
||||
UpdateAppConfig(req request.AppConfigUpdate) error
|
||||
GetInstallList() ([]dto.AppInstallInfo, error)
|
||||
GetAppInstallInfo(appInstallID uint) (*response.AppInstallInfo, error)
|
||||
}
|
||||
|
||||
func NewIAppInstalledService() IAppInstallService {
|
||||
|
|
@ -898,3 +899,29 @@ func updateInstallInfoInDB(appKey, appName, param string, value interface{}) err
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AppInstallService) GetAppInstallInfo(installID uint) (*response.AppInstallInfo, error) {
|
||||
appInstall, _ := appInstallRepo.GetFirst(repo.WithByID(installID))
|
||||
if appInstall.ID == 0 {
|
||||
return &response.AppInstallInfo{
|
||||
Status: constant.StatusDeleted,
|
||||
}, nil
|
||||
}
|
||||
var envMap map[string]interface{}
|
||||
err := json.Unmarshal([]byte(appInstall.Env), &envMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := &response.AppInstallInfo{
|
||||
ID: appInstall.ID,
|
||||
Name: appInstall.Name,
|
||||
Version: appInstall.Version,
|
||||
Container: appInstall.ContainerName,
|
||||
HttpPort: appInstall.HttpPort,
|
||||
Status: appInstall.Status,
|
||||
Message: appInstall.Message,
|
||||
Env: envMap,
|
||||
ComposePath: appInstall.GetComposePath(),
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -974,8 +974,8 @@ func runScript(task *task.Task, appInstall *model.AppInstall, operate string) er
|
|||
logStr := i18n.GetWithName("ExecShell", operate)
|
||||
task.LogStart(logStr)
|
||||
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(10*time.Minute), cmd.WithScriptPath(scriptPath), cmd.WithWorkDir(workDir))
|
||||
out, err := cmdMgr.RunWithStdout("bash")
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(10*time.Minute), cmd.WithWorkDir(workDir))
|
||||
out, err := cmdMgr.RunWithStdoutBashCf(scriptPath)
|
||||
if err != nil {
|
||||
if out != "" {
|
||||
err = errors.New(out)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ func (a *AppRouter) InitRouter(Router *gin.RouterGroup) {
|
|||
appRouter.POST("/installed/params/update", baseApi.UpdateInstalled)
|
||||
appRouter.POST("/installed/update/versions", baseApi.GetUpdateVersions)
|
||||
appRouter.POST("/installed/config/update", baseApi.UpdateAppConfig)
|
||||
appRouter.GET("/installed/info/:appInstallId", baseApi.GetAppInstallInfo)
|
||||
|
||||
appRouter.POST("/installed/ignore", baseApi.IgnoreAppUpgrade)
|
||||
appRouter.GET("/ignored/detail", baseApi.ListAppIgnored)
|
||||
|
|
|
|||
|
|
@ -45,16 +45,19 @@ type SubTask struct {
|
|||
}
|
||||
|
||||
const (
|
||||
TaskUpgrade = "TaskUpgrade"
|
||||
TaskAddNode = "TaskAddNode"
|
||||
TaskSync = "TaskSync"
|
||||
TaskRsync = "TaskRsync"
|
||||
TaskUpgrade = "TaskUpgrade"
|
||||
TaskAddNode = "TaskAddNode"
|
||||
TaskSync = "TaskSync"
|
||||
TaskRsync = "TaskRsync"
|
||||
TaskInstallCluster = "TaskInstallCluster"
|
||||
TaskCreateCluster = "TaskCreateCluster"
|
||||
)
|
||||
|
||||
const (
|
||||
TaskScopeSystem = "System"
|
||||
TaskScopeScript = "Script"
|
||||
TaskScopeSystem = "System"
|
||||
TaskScopeScript = "Script"
|
||||
TaskScopeNodeFile = "NodeFile"
|
||||
TaskScopeCluster = "Cluster"
|
||||
)
|
||||
|
||||
func GetTaskName(resourceName, operate, scope string) string {
|
||||
|
|
|
|||
|
|
@ -176,3 +176,8 @@ var DynamicRoutes = []string{
|
|||
var CertStore atomic.Value
|
||||
|
||||
var DaemonJsonPath = "/etc/docker/daemon.json"
|
||||
|
||||
const (
|
||||
RoleMaster = "master"
|
||||
RoleSlave = "slave"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -19,4 +19,8 @@ const (
|
|||
|
||||
StatusEnable = "Enable"
|
||||
StatusDisable = "Disable"
|
||||
|
||||
StatusInstalling = "Installing"
|
||||
StatusNormal = "Normal"
|
||||
StatusDeleted = "Deleted"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ package helper
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/core/app/model"
|
||||
"gorm.io/gorm"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||
)
|
||||
|
|
@ -53,3 +57,41 @@ func LoadMenus() string {
|
|||
menu, _ := json.Marshal(item)
|
||||
return string(menu)
|
||||
}
|
||||
|
||||
func AddMenu(newMenu dto.ShowMenu, parentMenuID string, tx *gorm.DB) error {
|
||||
var menuJSON string
|
||||
if err := tx.Model(&model.Setting{}).Where("key = ?", "HideMenu").Pluck("value", &menuJSON).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.Contains(menuJSON, fmt.Sprintf(`"%s"`, newMenu.Label)) && strings.Contains(menuJSON, fmt.Sprintf(`"%s"`, newMenu.Path)) {
|
||||
return nil
|
||||
}
|
||||
var menus []dto.ShowMenu
|
||||
if err := json.Unmarshal([]byte(menuJSON), &menus); err != nil {
|
||||
return tx.Model(&model.Setting{}).
|
||||
Where("key = ?", "HideMenu").
|
||||
Update("value", LoadMenus()).Error
|
||||
}
|
||||
for i, menu := range menus {
|
||||
if menu.ID == parentMenuID {
|
||||
exists := false
|
||||
for _, child := range menu.Children {
|
||||
if child.ID == newMenu.ID {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
menus[i].Children = append([]dto.ShowMenu{newMenu}, menus[i].Children...)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
updatedJSON, err := json.Marshal(menus)
|
||||
if err != nil {
|
||||
return tx.Model(&model.Setting{}).
|
||||
Where("key = ?", "HideMenu").
|
||||
Update("value", LoadMenus()).Error
|
||||
}
|
||||
return tx.Model(&model.Setting{}).Where("key = ?", "HideMenu").Update("value", string(updatedJSON)).Error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ func Init() {
|
|||
migrations.UpdateGoogle,
|
||||
migrations.UpdateXpackHideMenu,
|
||||
migrations.UpdateOnedrive,
|
||||
migrations.AddClusterMenu,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
|
|
|||
|
|
@ -489,3 +489,17 @@ var UpdateOnedrive = &gormigrate.Migration{
|
|||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var AddClusterMenu = &gormigrate.Migration{
|
||||
ID: "20250707-add-cluster-menu",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return helper.AddMenu(dto.ShowMenu{
|
||||
ID: "120",
|
||||
Disabled: false,
|
||||
Title: "xpack.cluster.cluster",
|
||||
IsShow: true,
|
||||
Label: "Cluster",
|
||||
Path: "/xpack/cluster",
|
||||
}, "11", tx)
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
"codemirror": "^6.0.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"echarts": "^5.5.0",
|
||||
"element-plus": "2.9.8",
|
||||
"element-plus": "2.9.9",
|
||||
"fit2cloud-ui-plus": "^1.2.2",
|
||||
"highlight.js": "^11.9.0",
|
||||
"js-base64": "^3.7.7",
|
||||
|
|
|
|||
|
|
@ -151,6 +151,17 @@ export namespace App {
|
|||
webUI: string;
|
||||
}
|
||||
|
||||
export interface AppInstalledInfo {
|
||||
id: number;
|
||||
name: string;
|
||||
version: string;
|
||||
status: string;
|
||||
message: string;
|
||||
httpPort: number;
|
||||
container: string;
|
||||
env: { [key: string]: string };
|
||||
}
|
||||
|
||||
export interface AppInstallDto {
|
||||
id: number;
|
||||
name: string;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ export const getAppByKey = (key: string) => {
|
|||
return http.get<App.AppDTO>('apps/' + key);
|
||||
};
|
||||
|
||||
export const getAppByKeyWithNode = (key: string, node: string) => {
|
||||
return http.get<App.AppDTO>('apps/' + key + `?operateNode=${node}`);
|
||||
};
|
||||
|
||||
export const getAppTags = () => {
|
||||
return http.get<App.Tag[]>('apps/tags');
|
||||
};
|
||||
|
|
@ -59,14 +63,19 @@ export const checkAppInstalled = (key: string, name: string) => {
|
|||
return http.post<App.CheckInstalled>(`apps/installed/check`, { key: key, name: name });
|
||||
};
|
||||
|
||||
export const appInstalledDeleteCheck = (appInstallId: number) => {
|
||||
return http.get<App.AppInstallResource[]>(`apps/installed/delete/check/${appInstallId}`);
|
||||
export const appInstalledDeleteCheck = (appInstallId: number, node?: string) => {
|
||||
const params = node ? `?operateNode=${node}` : '';
|
||||
return http.get<App.AppInstallResource[]>(`apps/installed/delete/check/${appInstallId}${params}`);
|
||||
};
|
||||
|
||||
export const getAppInstalled = (search: App.AppInstalledSearch) => {
|
||||
return http.post<ResPage<App.AppInstalled>>('apps/installed/search', search);
|
||||
};
|
||||
|
||||
export const getAppInstalledByID = (installID: number, node: string) => {
|
||||
return http.get<App.AppInstalledInfo>(`apps/installed/info/${installID}?operateNode=${node}`);
|
||||
};
|
||||
|
||||
export const installedOp = (op: App.AppInstalledOp) => {
|
||||
return http.post<any>('apps/installed/op', op, TimeoutEnum.T_40S);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -126,8 +126,9 @@ export const loadMFA = (param: Setting.MFARequest) => {
|
|||
export const bindMFA = (param: Setting.MFABind) => {
|
||||
return http.post(`/core/settings/mfa/bind`, param);
|
||||
};
|
||||
export const getAppStoreConfig = () => {
|
||||
return http.get<App.AppStoreConfig>(`/core/settings/apps/store/config`);
|
||||
export const getAppStoreConfig = (node?: string) => {
|
||||
const params = node ? `?operateNode=${node}` : '';
|
||||
return http.get<App.AppStoreConfig>(`/core/settings/apps/store/config${params}`);
|
||||
};
|
||||
export const updateAppStoreConfig = (req: App.AppStoreConfigUpdate) => {
|
||||
return http.post(`/core/settings/apps/store/update`, req);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
:compose="compose"
|
||||
:resource="resource"
|
||||
:container="container"
|
||||
:node="node"
|
||||
:highlightDiff="highlightDiff"
|
||||
/>
|
||||
</template>
|
||||
|
|
@ -36,11 +37,13 @@ const globalStore = GlobalStore();
|
|||
const logVisible = ref(false);
|
||||
const compose = ref('');
|
||||
const highlightDiff = ref(320);
|
||||
const node = ref('');
|
||||
|
||||
interface DialogProps {
|
||||
compose: string;
|
||||
resource: string;
|
||||
container: string;
|
||||
node: string;
|
||||
}
|
||||
|
||||
const defaultProps = defineProps({
|
||||
|
|
@ -75,6 +78,7 @@ const acceptParams = (props: DialogProps): void => {
|
|||
compose.value = props.compose;
|
||||
resource.value = props.resource;
|
||||
container.value = props.container;
|
||||
node.value = props.node;
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,10 @@ const props = defineProps({
|
|||
type: Number,
|
||||
default: 320,
|
||||
},
|
||||
node: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const styleVars = computed(() => ({
|
||||
|
|
@ -137,6 +141,9 @@ const searchLogs = async () => {
|
|||
}
|
||||
logs.value = [];
|
||||
let currentNode = globalStore.currentNode;
|
||||
if (props.node && props.node !== '') {
|
||||
currentNode = props.node;
|
||||
}
|
||||
let url = `/api/v2/containers/search/log?container=${logSearch.container}&since=${logSearch.mode}&tail=${logSearch.tail}&follow=${logSearch.isWatch}&operateNode=${currentNode}`;
|
||||
if (logSearch.compose !== '') {
|
||||
url = `/api/v2/containers/search/log?compose=${logSearch.compose}&since=${logSearch.mode}&tail=${logSearch.tail}&follow=${logSearch.isWatch}&operateNode=${currentNode}`;
|
||||
|
|
|
|||
|
|
@ -3628,6 +3628,14 @@ const message = {
|
|||
exchange: 'File Exchange',
|
||||
exchangeConfirm: "Do you want to transfer the file/folder {1} from {0} node to {2} node's {3} directory?",
|
||||
},
|
||||
cluster: {
|
||||
cluster: 'Application High Availability',
|
||||
name: 'Cluster Name',
|
||||
addCluster: 'Add Cluster',
|
||||
installNode: 'Install Node',
|
||||
master: 'Master Node',
|
||||
slave: 'Slave Node',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3491,6 +3491,14 @@ const message = {
|
|||
exchange: 'ファイル交換',
|
||||
exchangeConfirm: '{0} ノードのファイル/フォルダ {1} を {2} ノードの {3} ディレクトリに転送しますか?',
|
||||
},
|
||||
cluster: {
|
||||
cluster: 'アプリケーションの高可用性',
|
||||
name: 'クラスタ名',
|
||||
addCluster: 'クラスタを追加',
|
||||
installNode: 'ノードをインストール',
|
||||
master: 'マスターノード',
|
||||
slave: 'スレーブノード',
|
||||
},
|
||||
},
|
||||
};
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -3429,6 +3429,14 @@ const message = {
|
|||
exchange: '파일 교환',
|
||||
exchangeConfirm: '{0} 노드의 파일/폴더 {1}을(를) {2} 노드의 {3} 디렉토리로 전송하시겠습니까?',
|
||||
},
|
||||
cluster: {
|
||||
cluster: '애플리케이션 고가용성',
|
||||
name: '클러스터 이름',
|
||||
addCluster: '클러스터 추가',
|
||||
installNode: '노드 설치',
|
||||
master: '마스터 노드',
|
||||
slave: '슬레이브 노드',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3572,6 +3572,14 @@ const message = {
|
|||
exchange: 'Pertukaran Fail',
|
||||
exchangeConfirm: 'Adakah anda mahu memindahkan fail/folder {1} dari node {0} ke direktori {3} node {2}?',
|
||||
},
|
||||
cluster: {
|
||||
cluster: 'Aplikasi Tinggi Ketersediaan',
|
||||
name: 'Nama Kluster',
|
||||
addCluster: 'Tambah Kluster',
|
||||
installNode: 'Pasang Node',
|
||||
master: 'Node Utama',
|
||||
slave: 'Node Hamba',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3579,6 +3579,14 @@ const message = {
|
|||
exchange: 'Troca de Arquivos',
|
||||
exchangeConfirm: 'Deseja transferir o arquivo/pasta {1} do nó {0} para o diretório {3} do nó {2}?',
|
||||
},
|
||||
cluster: {
|
||||
cluster: 'Alta Disponibilidade de Aplicações',
|
||||
name: 'Nome do Cluster',
|
||||
addCluster: 'Adicionar Cluster',
|
||||
installNode: 'Instalar Nó',
|
||||
master: 'Nó Mestre',
|
||||
slave: 'Nó Escravo',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3570,6 +3570,14 @@ const message = {
|
|||
exchange: 'Обмен файлами',
|
||||
exchangeConfirm: 'Хотите перенести файл/папку {1} с узла {0} в каталог {3} узла {2}?',
|
||||
},
|
||||
cluster: {
|
||||
cluster: 'Высокая доступность приложений',
|
||||
name: 'Имя кластера',
|
||||
addCluster: 'Добавить кластер',
|
||||
installNode: 'Установить узел',
|
||||
master: 'Главный узел',
|
||||
slave: 'Подчиненный узел',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3669,6 +3669,14 @@ const message = {
|
|||
exchange: 'Dosya Değişimi',
|
||||
exchangeConfirm: '{0} düğümünden {1} dosya/klasörünü {2} düğümünün {3} dizinine aktarmak istiyor musunuz?',
|
||||
},
|
||||
cluster: {
|
||||
cluster: 'Высокая доступность приложений',
|
||||
name: 'Имя кластера',
|
||||
addCluster: 'Добавить кластер',
|
||||
installNode: 'Установить узел',
|
||||
master: 'Главный узел',
|
||||
slave: 'Подчиненный узел',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3377,6 +3377,14 @@ const message = {
|
|||
exchange: '文件對傳',
|
||||
exchangeConfirm: '是否將 {0} 節點文件/文件夾 {1} 傳輸到 {2} 節點 {3} 目錄?',
|
||||
},
|
||||
cluster: {
|
||||
cluster: '應用高可用',
|
||||
name: '集群名稱',
|
||||
addCluster: '添加集群',
|
||||
installNode: '安裝節點',
|
||||
master: '主節點',
|
||||
slave: '從節點',
|
||||
},
|
||||
},
|
||||
};
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -3357,6 +3357,14 @@ const message = {
|
|||
exchange: '文件对传',
|
||||
exchangeConfirm: '是否将 {0} 节点文件/文件夹 {1} 传输到 {2} 节点 {3} 目录?',
|
||||
},
|
||||
cluster: {
|
||||
cluster: '应用高可用',
|
||||
name: '集群名称',
|
||||
addCluster: '添加集群',
|
||||
installNode: '安装节点',
|
||||
master: '主节点',
|
||||
slave: '从节点',
|
||||
},
|
||||
},
|
||||
};
|
||||
export default {
|
||||
|
|
|
|||
28
frontend/src/utils/app.ts
Normal file
28
frontend/src/utils/app.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { jumpToPath } from './util';
|
||||
import router from '@/routers';
|
||||
|
||||
export const jumpToInstall = (type: string, key: string) => {
|
||||
switch (type) {
|
||||
case 'php':
|
||||
case 'node':
|
||||
case 'java':
|
||||
case 'go':
|
||||
case 'python':
|
||||
case 'dotnet':
|
||||
jumpToPath(router, '/websites/runtimes/' + type);
|
||||
return true;
|
||||
}
|
||||
switch (key) {
|
||||
case 'mysql-cluster':
|
||||
console.log('jumpToInstall mysql-cluster');
|
||||
jumpToPath(router, '/xpack/cluster/mysql');
|
||||
return true;
|
||||
case 'redis-cluster':
|
||||
jumpToPath(router, '/xpack/cluster/redis');
|
||||
return true;
|
||||
case 'postgres-cluster':
|
||||
jumpToPath(router, '/xpack/cluster/postgres');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
|
@ -132,13 +132,14 @@ import Install from '../detail/install/index.vue';
|
|||
import router from '@/routers';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { newUUID, jumpToPath } from '@/utils/util';
|
||||
import { newUUID } from '@/utils/util';
|
||||
import Detail from '../detail/index.vue';
|
||||
import TaskLog from '@/components/log/task/index.vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import bus from '@/global/bus';
|
||||
import Tags from '@/views/app-store/components/tag.vue';
|
||||
import DockerStatus from '@/views/container/docker-status/index.vue';
|
||||
import { jumpToInstall } from '@/utils/app';
|
||||
|
||||
const globalStore = GlobalStore();
|
||||
const { isProductPro } = storeToRefs(globalStore);
|
||||
|
|
@ -208,20 +209,11 @@ const search = async (req: App.AppReq) => {
|
|||
};
|
||||
|
||||
const openInstall = (app: App.App) => {
|
||||
switch (app.type) {
|
||||
case 'php':
|
||||
case 'node':
|
||||
case 'java':
|
||||
case 'go':
|
||||
case 'python':
|
||||
case 'dotnet':
|
||||
jumpToPath(router, '/websites/runtimes/' + app.type);
|
||||
break;
|
||||
default:
|
||||
const params = {
|
||||
app: app,
|
||||
};
|
||||
installRef.value.acceptParams(params);
|
||||
if (!jumpToInstall(app.type, app.key)) {
|
||||
const params = {
|
||||
app: app,
|
||||
};
|
||||
installRef.value.acceptParams(params);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ import { getAppByKey, getAppDetail } from '@/api/modules/app';
|
|||
import MdEditor from 'md-editor-v3';
|
||||
import { ref } from 'vue';
|
||||
import Install from './install/index.vue';
|
||||
import router from '@/routers';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { computeSizeFromMB, jumpToPath } from '@/utils/util';
|
||||
import { computeSizeFromMB } from '@/utils/util';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { jumpToInstall } from '@/utils/app';
|
||||
|
||||
const globalStore = GlobalStore();
|
||||
const { isDarkTheme } = storeToRefs(globalStore);
|
||||
|
|
@ -131,21 +131,12 @@ const toLink = (link: string) => {
|
|||
};
|
||||
|
||||
const openInstall = () => {
|
||||
switch (app.value.type) {
|
||||
case 'php':
|
||||
case 'node':
|
||||
case 'java':
|
||||
case 'go':
|
||||
case 'python':
|
||||
case 'dotnet':
|
||||
jumpToPath(router, '/websites/runtimes/' + app.value.type);
|
||||
break;
|
||||
default:
|
||||
const params = {
|
||||
app: app.value,
|
||||
};
|
||||
installRef.value.acceptParams(params);
|
||||
open.value = false;
|
||||
if (!jumpToInstall(app.value.type, app.value.key)) {
|
||||
const params = {
|
||||
app: app.value,
|
||||
};
|
||||
installRef.value.acceptParams(params);
|
||||
open.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ import { ref } from 'vue';
|
|||
import { useRouter } from 'vue-router';
|
||||
import { toFolder } from '@/global/business';
|
||||
import { jumpToPath } from '@/utils/util';
|
||||
import { jumpToInstall } from '@/utils/app';
|
||||
|
||||
const router = useRouter();
|
||||
const globalStore = GlobalStore();
|
||||
|
|
@ -209,17 +210,8 @@ const acceptParams = (): void => {
|
|||
};
|
||||
|
||||
const goInstall = (key: string, type: string) => {
|
||||
switch (type) {
|
||||
case 'php':
|
||||
case 'node':
|
||||
case 'java':
|
||||
case 'go':
|
||||
case 'python':
|
||||
case 'dotnet':
|
||||
router.push({ path: '/websites/runtimes/' + type });
|
||||
break;
|
||||
default:
|
||||
router.push({ name: 'AppAll', query: { install: key } });
|
||||
if (!jumpToInstall(type, key)) {
|
||||
router.push({ name: 'AppAll', query: { install: key } });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue