mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-14 01:34:47 +08:00
feat: 应用商店支持使用自定的应用包 (#6697)
This commit is contained in:
parent
72311617d9
commit
07bdcdc91b
@ -45,6 +45,7 @@ type AppDto struct {
|
|||||||
Github string `json:"github"`
|
Github string `json:"github"`
|
||||||
Website string `json:"website"`
|
Website string `json:"website"`
|
||||||
GpuSupport bool `json:"gpuSupport"`
|
GpuSupport bool `json:"gpuSupport"`
|
||||||
|
Recommend int `json:"recommend"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TagDTO struct {
|
type TagDTO struct {
|
||||||
|
@ -30,6 +30,7 @@ type IAppRepo interface {
|
|||||||
Create(ctx context.Context, app *model.App) error
|
Create(ctx context.Context, app *model.App) error
|
||||||
Save(ctx context.Context, app *model.App) error
|
Save(ctx context.Context, app *model.App) error
|
||||||
BatchDelete(ctx context.Context, apps []model.App) error
|
BatchDelete(ctx context.Context, apps []model.App) error
|
||||||
|
DeleteByIDs(ctx context.Context, ids []uint) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIAppRepo() IAppRepo {
|
func NewIAppRepo() IAppRepo {
|
||||||
@ -91,7 +92,7 @@ func (a AppRepo) Page(page, size int, opts ...DBOption) (int64, []model.App, err
|
|||||||
var apps []model.App
|
var apps []model.App
|
||||||
db := getDb(opts...).Model(&model.App{})
|
db := getDb(opts...).Model(&model.App{})
|
||||||
count := int64(0)
|
count := int64(0)
|
||||||
db = db.Count(&count)
|
db = db.Count(&count).Debug()
|
||||||
err := db.Limit(size).Offset(size * (page - 1)).Preload("AppTags").Find(&apps).Error
|
err := db.Limit(size).Offset(size * (page - 1)).Preload("AppTags").Find(&apps).Error
|
||||||
return count, apps, err
|
return count, apps, err
|
||||||
}
|
}
|
||||||
@ -137,3 +138,7 @@ func (a AppRepo) Save(ctx context.Context, app *model.App) error {
|
|||||||
func (a AppRepo) BatchDelete(ctx context.Context, apps []model.App) error {
|
func (a AppRepo) BatchDelete(ctx context.Context, apps []model.App) error {
|
||||||
return getTx(ctx).Omit(clause.Associations).Delete(&apps).Error
|
return getTx(ctx).Omit(clause.Associations).Delete(&apps).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a AppRepo) DeleteByIDs(ctx context.Context, ids []uint) error {
|
||||||
|
return getTx(ctx).Where("id in (?)", ids).Delete(&model.App{}).Error
|
||||||
|
}
|
||||||
|
@ -19,6 +19,7 @@ type IAppDetailRepo interface {
|
|||||||
Update(ctx context.Context, detail model.AppDetail) error
|
Update(ctx context.Context, detail model.AppDetail) error
|
||||||
BatchCreate(ctx context.Context, details []model.AppDetail) error
|
BatchCreate(ctx context.Context, details []model.AppDetail) error
|
||||||
DeleteByAppIds(ctx context.Context, appIds []uint) error
|
DeleteByAppIds(ctx context.Context, appIds []uint) error
|
||||||
|
DeleteByIDs(ctx context.Context, appIds []uint) error
|
||||||
GetBy(opts ...DBOption) ([]model.AppDetail, error)
|
GetBy(opts ...DBOption) ([]model.AppDetail, error)
|
||||||
BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error
|
BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error
|
||||||
BatchDelete(ctx context.Context, appDetails []model.AppDetail) error
|
BatchDelete(ctx context.Context, appDetails []model.AppDetail) error
|
||||||
@ -64,6 +65,10 @@ func (a AppDetailRepo) DeleteByAppIds(ctx context.Context, appIds []uint) error
|
|||||||
return getTx(ctx).Where("app_id in (?)", appIds).Delete(&model.AppDetail{}).Error
|
return getTx(ctx).Where("app_id in (?)", appIds).Delete(&model.AppDetail{}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a AppDetailRepo) DeleteByIDs(ctx context.Context, appIds []uint) error {
|
||||||
|
return getTx(ctx).Where("id in (?)", appIds).Delete(&model.AppDetail{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
func (a AppDetailRepo) GetBy(opts ...DBOption) ([]model.AppDetail, error) {
|
func (a AppDetailRepo) GetBy(opts ...DBOption) ([]model.AppDetail, error) {
|
||||||
var details []model.AppDetail
|
var details []model.AppDetail
|
||||||
err := getDb(opts...).Find(&details).Error
|
err := getDb(opts...).Find(&details).Error
|
||||||
|
@ -2,6 +2,7 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
)
|
)
|
||||||
@ -15,12 +16,21 @@ type IAppTagRepo interface {
|
|||||||
DeleteAll(ctx context.Context) error
|
DeleteAll(ctx context.Context) error
|
||||||
GetByAppId(appId uint) ([]model.AppTag, error)
|
GetByAppId(appId uint) ([]model.AppTag, error)
|
||||||
GetByTagIds(tagIds []uint) ([]model.AppTag, error)
|
GetByTagIds(tagIds []uint) ([]model.AppTag, error)
|
||||||
|
DeleteBy(ctx context.Context, opts ...DBOption) error
|
||||||
|
|
||||||
|
WithByTagID(tagID uint) DBOption
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIAppTagRepo() IAppTagRepo {
|
func NewIAppTagRepo() IAppTagRepo {
|
||||||
return &AppTagRepo{}
|
return &AppTagRepo{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a AppTagRepo) WithByTagID(tagID uint) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
return g.Where("tag_id = ?", tagID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (a AppTagRepo) BatchCreate(ctx context.Context, tags []*model.AppTag) error {
|
func (a AppTagRepo) BatchCreate(ctx context.Context, tags []*model.AppTag) error {
|
||||||
return getTx(ctx).Create(&tags).Error
|
return getTx(ctx).Create(&tags).Error
|
||||||
}
|
}
|
||||||
@ -48,3 +58,7 @@ func (a AppTagRepo) GetByTagIds(tagIds []uint) ([]model.AppTag, error) {
|
|||||||
}
|
}
|
||||||
return appTags, nil
|
return appTags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a AppTagRepo) DeleteBy(ctx context.Context, opts ...DBOption) error {
|
||||||
|
return getTx(ctx, opts...).Delete(&model.AppTag{}).Error
|
||||||
|
}
|
||||||
|
@ -16,6 +16,9 @@ type ITagRepo interface {
|
|||||||
GetByIds(ids []uint) ([]model.Tag, error)
|
GetByIds(ids []uint) ([]model.Tag, error)
|
||||||
GetByKeys(keys []string) ([]model.Tag, error)
|
GetByKeys(keys []string) ([]model.Tag, error)
|
||||||
GetByAppId(appId uint) ([]model.Tag, error)
|
GetByAppId(appId uint) ([]model.Tag, error)
|
||||||
|
DeleteByID(ctx context.Context, id uint) error
|
||||||
|
Create(ctx context.Context, tag *model.Tag) error
|
||||||
|
Save(ctx context.Context, tag *model.Tag) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewITagRepo() ITagRepo {
|
func NewITagRepo() ITagRepo {
|
||||||
@ -61,3 +64,15 @@ func (t TagRepo) GetByAppId(appId uint) ([]model.Tag, error) {
|
|||||||
}
|
}
|
||||||
return tags, nil
|
return tags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t TagRepo) DeleteByID(ctx context.Context, id uint) error {
|
||||||
|
return getTx(ctx).Where("id = ?", id).Delete(&model.Tag{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t TagRepo) Create(ctx context.Context, tag *model.Tag) error {
|
||||||
|
return getTx(ctx).Create(tag).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t TagRepo) Save(ctx context.Context, tag *model.Tag) error {
|
||||||
|
return getTx(ctx).Save(tag).Error
|
||||||
|
}
|
||||||
|
@ -120,6 +120,7 @@ func (a AppService) PageApp(req request.AppSearch) (interface{}, error) {
|
|||||||
Website: ap.Website,
|
Website: ap.Website,
|
||||||
Github: ap.Github,
|
Github: ap.Github,
|
||||||
GpuSupport: ap.GpuSupport,
|
GpuSupport: ap.GpuSupport,
|
||||||
|
Recommend: ap.Recommend,
|
||||||
}
|
}
|
||||||
appDTOs = append(appDTOs, appDTO)
|
appDTOs = append(appDTOs, appDTO)
|
||||||
appTags, err := appTagRepo.GetByAppId(ap.ID)
|
appTags, err := appTagRepo.GetByAppId(ap.ID)
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx"
|
"github.com/1Panel-dev/1Panel/agent/utils/nginx"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx/parser"
|
"github.com/1Panel-dev/1Panel/agent/utils/nginx/parser"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -403,27 +404,6 @@ func deleteAppInstall(deleteReq request.AppInstallDelete) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch install.App.Key {
|
switch install.App.Key {
|
||||||
case constant.AppOpenresty:
|
|
||||||
//TODO 删除 Openresty 不再删除网站
|
|
||||||
//websites, _ := websiteRepo.List()
|
|
||||||
//for _, website := range websites {
|
|
||||||
// if website.AppInstallID > 0 {
|
|
||||||
// websiteAppInstall, _ := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
|
||||||
// if websiteAppInstall.AppId > 0 {
|
|
||||||
// websiteApp, _ := appRepo.GetFirst(commonRepo.WithByID(websiteAppInstall.AppId))
|
|
||||||
// if websiteApp.Type == constant.RuntimePHP {
|
|
||||||
// go func() {
|
|
||||||
// _, _ = compose.Down(websiteAppInstall.GetComposePath())
|
|
||||||
// _ = op.DeleteDir(websiteAppInstall.GetPath())
|
|
||||||
// }()
|
|
||||||
// _ = appInstallRepo.Delete(ctx, websiteAppInstall)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//_ = websiteRepo.DeleteAll(ctx)
|
|
||||||
//_ = websiteDomainRepo.DeleteAll(ctx)
|
|
||||||
//xpack.RemoveTamper("")
|
|
||||||
case constant.AppMysql, constant.AppMariaDB:
|
case constant.AppMysql, constant.AppMariaDB:
|
||||||
_ = mysqlRepo.Delete(ctx, mysqlRepo.WithByMysqlName(install.Name))
|
_ = mysqlRepo.Delete(ctx, mysqlRepo.WithByMysqlName(install.Name))
|
||||||
case constant.AppPostgresql:
|
case constant.AppPostgresql:
|
||||||
@ -1045,7 +1025,15 @@ func upApp(task *task.Task, appInstall *model.AppInstall, pullImages bool) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
imagePrefix := xpack.GetImagePrefix()
|
||||||
for _, image := range images {
|
for _, image := range images {
|
||||||
|
if imagePrefix != "" {
|
||||||
|
lastSlashIndex := strings.LastIndex(image, "/")
|
||||||
|
if lastSlashIndex != -1 {
|
||||||
|
image = image[lastSlashIndex+1:]
|
||||||
|
}
|
||||||
|
image = imagePrefix + "/" + image
|
||||||
|
}
|
||||||
task.Log(i18n.GetWithName("PullImageStart", image))
|
task.Log(i18n.GetWithName("PullImageStart", image))
|
||||||
if out, err = cmd.ExecWithTimeOut("docker pull "+image, 20*time.Minute); err != nil {
|
if out, err = cmd.ExecWithTimeOut("docker pull "+image, 20*time.Minute); err != nil {
|
||||||
if out != "" {
|
if out != "" {
|
||||||
@ -1555,6 +1543,22 @@ func addDockerComposeCommonParam(composeMap map[string]interface{}, serviceName
|
|||||||
if !serviceValid {
|
if !serviceValid {
|
||||||
return buserr.New(constant.ErrFileParse)
|
return buserr.New(constant.ErrFileParse)
|
||||||
}
|
}
|
||||||
|
imagePreFix := xpack.GetImagePrefix()
|
||||||
|
if imagePreFix != "" {
|
||||||
|
for _, service := range services {
|
||||||
|
serviceValue := service.(map[string]interface{})
|
||||||
|
if image, ok := serviceValue["image"]; ok {
|
||||||
|
imageStr := image.(string)
|
||||||
|
lastSlashIndex := strings.LastIndex(imageStr, "/")
|
||||||
|
if lastSlashIndex != -1 {
|
||||||
|
imageStr = imageStr[lastSlashIndex+1:]
|
||||||
|
}
|
||||||
|
imageStr = imagePreFix + "/" + imageStr
|
||||||
|
serviceValue["image"] = imageStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
service, serviceExist := services[serviceName]
|
service, serviceExist := services[serviceName]
|
||||||
if !serviceExist {
|
if !serviceExist {
|
||||||
return buserr.New(constant.ErrFileParse)
|
return buserr.New(constant.ErrFileParse)
|
||||||
|
@ -70,7 +70,11 @@ MoveSiteDir: "The current upgrade requires migrating the OpenResty website direc
|
|||||||
MoveSiteToDir: "Migrate the website directory to {{ .name }}"
|
MoveSiteToDir: "Migrate the website directory to {{ .name }}"
|
||||||
ErrMoveSiteDir: "Failed to migrate the website directory"
|
ErrMoveSiteDir: "Failed to migrate the website directory"
|
||||||
MoveSiteDirSuccess: "Successfully migrated the website directory"
|
MoveSiteDirSuccess: "Successfully migrated the website directory"
|
||||||
DeleteRuntimePHP: "Delete PHP runtime environment"
|
DeleteRuntimePHP: "Delete PHP runtime environment",
|
||||||
|
CustomAppStoreNotConfig: "Please configure the offline package address in the app store settings",
|
||||||
|
CustomAppStoreNotFound: "Failed to retrieve app store package, please check if it exists",
|
||||||
|
CustomAppStoreFileValid: "App store package must be in .tar.gz format"
|
||||||
|
|
||||||
|
|
||||||
#file
|
#file
|
||||||
ErrFileCanNotRead: "File can not read"
|
ErrFileCanNotRead: "File can not read"
|
||||||
|
@ -71,7 +71,11 @@ MoveSiteDir: "當前升級需要遷移 OpenResty 網站目錄"
|
|||||||
MoveSiteToDir: "遷移網站目錄到 {{ .name }}"
|
MoveSiteToDir: "遷移網站目錄到 {{ .name }}"
|
||||||
ErrMoveSiteDir: "遷移網站目錄失敗"
|
ErrMoveSiteDir: "遷移網站目錄失敗"
|
||||||
MoveSiteDirSuccess: "遷移網站目錄成功"
|
MoveSiteDirSuccess: "遷移網站目錄成功"
|
||||||
DeleteRuntimePHP: "刪除運行環境 PHP 版本"
|
DeleteRuntimePHP: "刪除運行環境 PHP 版本",
|
||||||
|
CustomAppStoreNotConfig: "請在應用商店設置離線包地址",
|
||||||
|
CustomAppStoreNotFound: "應用商店包獲取失敗,請檢查是否存在",
|
||||||
|
CustomAppStoreFileValid: "應用商店包需要 .tar.gz 格式"
|
||||||
|
|
||||||
|
|
||||||
#file
|
#file
|
||||||
ErrFileCanNotRead: "此文件不支持預覽"
|
ErrFileCanNotRead: "此文件不支持預覽"
|
||||||
|
@ -71,6 +71,9 @@ MoveSiteToDir: "迁移网站目录到 {{ .name }}"
|
|||||||
ErrMoveSiteDir: "迁移网站目录失败"
|
ErrMoveSiteDir: "迁移网站目录失败"
|
||||||
MoveSiteDirSuccess: "迁移网站目录成功"
|
MoveSiteDirSuccess: "迁移网站目录成功"
|
||||||
DeleteRuntimePHP: "删除 PHP 运行环境"
|
DeleteRuntimePHP: "删除 PHP 运行环境"
|
||||||
|
CustomAppStoreNotConfig: "请在应用商店设置离线包地址"
|
||||||
|
CustomAppStoreNotFound: "应用商店包获取失败,请检查是否存在"
|
||||||
|
CustomAppStoreFileValid: "应用商店包需要 .tar.gz 格式"
|
||||||
|
|
||||||
#file
|
#file
|
||||||
ErrFileCanNotRead: "此文件不支持预览"
|
ErrFileCanNotRead: "此文件不支持预览"
|
||||||
|
@ -43,3 +43,7 @@ func InitNodeData(tx *gorm.DB) (bool, string, error) { return true, "127.0.0.1",
|
|||||||
func RequestToMaster(reqUrl, reqMethod string, reqBody io.Reader) (interface{}, error) {
|
func RequestToMaster(reqUrl, reqMethod string, reqBody io.Reader) (interface{}, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetImagePrefix() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
@ -118,3 +118,7 @@ export const GetAppStoreConfig = () => {
|
|||||||
export const UpdateAppStoreConfig = (req: App.AppStoreConfig) => {
|
export const UpdateAppStoreConfig = (req: App.AppStoreConfig) => {
|
||||||
return http.post(`apps/store/update`, req);
|
return http.post(`apps/store/update`, req);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const SyncCutomAppStore = (req: App.AppStoreSync) => {
|
||||||
|
return http.post(`/custom/app/sync`, req);
|
||||||
|
};
|
||||||
|
@ -175,7 +175,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { App } from '@/api/interface/app';
|
import { App } from '@/api/interface/app';
|
||||||
import { onMounted, reactive, ref, computed } from 'vue';
|
import { onMounted, reactive, ref, computed } from 'vue';
|
||||||
import { GetAppTags, SearchApp, SyncApp, SyncLocalApp } from '@/api/modules/app';
|
import { GetAppTags, SearchApp, SyncApp, SyncCutomAppStore, SyncLocalApp } from '@/api/modules/app';
|
||||||
import Install from '../detail/install/index.vue';
|
import Install from '../detail/install/index.vue';
|
||||||
import router from '@/routers';
|
import router from '@/routers';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
@ -183,8 +183,11 @@ import { GlobalStore } from '@/store';
|
|||||||
import { getLanguage, newUUID } from '@/utils/util';
|
import { getLanguage, newUUID } from '@/utils/util';
|
||||||
import Detail from '../detail/index.vue';
|
import Detail from '../detail/index.vue';
|
||||||
import TaskLog from '@/components/task-log/index.vue';
|
import TaskLog from '@/components/task-log/index.vue';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { GetCustomAppStoreConfig } from '@/xpack/api/modules/app';
|
||||||
|
|
||||||
const globalStore = GlobalStore();
|
const globalStore = GlobalStore();
|
||||||
|
const { isProductPro } = storeToRefs(globalStore);
|
||||||
|
|
||||||
const mobile = computed(() => {
|
const mobile = computed(() => {
|
||||||
return globalStore.isMobile();
|
return globalStore.isMobile();
|
||||||
@ -221,6 +224,7 @@ const moreTag = ref('');
|
|||||||
const mainHeight = ref(0);
|
const mainHeight = ref(0);
|
||||||
const detailRef = ref();
|
const detailRef = ref();
|
||||||
const taskLogRef = ref();
|
const taskLogRef = ref();
|
||||||
|
const syncCustomAppstore = ref(false);
|
||||||
|
|
||||||
const search = async (req: App.AppReq) => {
|
const search = async (req: App.AppReq) => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@ -265,25 +269,29 @@ const openTaskLog = (taskID: string) => {
|
|||||||
taskLogRef.value.openWithTaskID(taskID);
|
taskLogRef.value.openWithTaskID(taskID);
|
||||||
};
|
};
|
||||||
|
|
||||||
const sync = () => {
|
const sync = async () => {
|
||||||
syncing.value = true;
|
syncing.value = true;
|
||||||
const taskID = newUUID();
|
const taskID = newUUID();
|
||||||
const syncReq = {
|
const syncReq = {
|
||||||
taskID: taskID,
|
taskID: taskID,
|
||||||
};
|
};
|
||||||
SyncApp(syncReq)
|
try {
|
||||||
.then((res) => {
|
let res;
|
||||||
if (res.message != '') {
|
if (isProductPro.value && syncCustomAppstore.value) {
|
||||||
MsgSuccess(res.message);
|
res = await SyncCutomAppStore(syncReq);
|
||||||
} else {
|
} else {
|
||||||
openTaskLog(taskID);
|
res = await SyncApp(syncReq);
|
||||||
}
|
}
|
||||||
canUpdate.value = false;
|
if (res.message != '') {
|
||||||
search(req);
|
MsgSuccess(res.message);
|
||||||
})
|
} else {
|
||||||
.finally(() => {
|
openTaskLog(taskID);
|
||||||
syncing.value = false;
|
}
|
||||||
});
|
canUpdate.value = false;
|
||||||
|
search(req);
|
||||||
|
} finally {
|
||||||
|
syncing.value = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const syncLocal = () => {
|
const syncLocal = () => {
|
||||||
@ -329,7 +337,7 @@ const searchByName = () => {
|
|||||||
search(req);
|
search(req);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
if (router.currentRoute.value.query.install) {
|
if (router.currentRoute.value.query.install) {
|
||||||
installKey.value = String(router.currentRoute.value.query.install);
|
installKey.value = String(router.currentRoute.value.query.install);
|
||||||
const params = {
|
const params = {
|
||||||
@ -340,6 +348,12 @@ onMounted(() => {
|
|||||||
installRef.value.acceptParams(params);
|
installRef.value.acceptParams(params);
|
||||||
}
|
}
|
||||||
search(req);
|
search(req);
|
||||||
|
if (isProductPro.value) {
|
||||||
|
const res = await GetCustomAppStoreConfig();
|
||||||
|
if (res && res.data) {
|
||||||
|
syncCustomAppstore.value = res.data.status === 'enable';
|
||||||
|
}
|
||||||
|
}
|
||||||
mainHeight.value = window.innerHeight - 380;
|
mainHeight.value = window.innerHeight - 380;
|
||||||
window.onresize = () => {
|
window.onresize = () => {
|
||||||
return (() => {
|
return (() => {
|
||||||
|
@ -0,0 +1,87 @@
|
|||||||
|
<template>
|
||||||
|
<DrawerPro v-model="drawerVisible" :header="$t('app.defaultWebDomain')" :back="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">
|
||||||
|
<template #prepend>
|
||||||
|
<el-select v-model="protocol" placeholder="Select" class="p-w-100">
|
||||||
|
<el-option label="HTTP" value="http://" />
|
||||||
|
<el-option label="HTTPS" value="https://" />
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
</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],
|
||||||
|
});
|
||||||
|
const formRef = ref<FormInstance>();
|
||||||
|
const protocol = ref('http://');
|
||||||
|
interface DialogProps {
|
||||||
|
protocol: string;
|
||||||
|
domain: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const acceptParams = (config: DialogProps): void => {
|
||||||
|
form.defaultDomain = config.domain;
|
||||||
|
protocol.value;
|
||||||
|
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 {
|
||||||
|
let defaultDomain = '';
|
||||||
|
if (form.defaultDomain) {
|
||||||
|
defaultDomain = protocol.value + form.defaultDomain;
|
||||||
|
}
|
||||||
|
const req = {
|
||||||
|
defaultDomain: defaultDomain,
|
||||||
|
};
|
||||||
|
await UpdateAppStoreConfig(req);
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||||
|
} catch (error) {
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
handleClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams,
|
||||||
|
});
|
||||||
|
</script>
|
@ -4,7 +4,7 @@
|
|||||||
<el-form
|
<el-form
|
||||||
:model="config"
|
:model="config"
|
||||||
label-position="left"
|
label-position="left"
|
||||||
label-width="150px"
|
label-width="180px"
|
||||||
class="ml-2.5"
|
class="ml-2.5"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
@ -15,32 +15,39 @@
|
|||||||
<el-form-item :label="$t('app.defaultWebDomain')" prop="defaultDomain">
|
<el-form-item :label="$t('app.defaultWebDomain')" prop="defaultDomain">
|
||||||
<el-input v-model="config.defaultDomain">
|
<el-input v-model="config.defaultDomain">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<el-select v-model="protocol" placeholder="Select" class="p-w-100">
|
<el-select v-model="protocol" placeholder="Select" class="p-w-100" disabled>
|
||||||
<el-option label="HTTP" value="http://" />
|
<el-option label="HTTP" value="http://" />
|
||||||
<el-option label="HTTPS" value="https://" />
|
<el-option label="HTTPS" value="https://" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
|
<template #append>
|
||||||
|
<el-button @click="setDefaultDomain()" icon="Setting">
|
||||||
|
{{ $t('commons.button.set') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<span class="input-help">{{ $t('app.defaultWebDomainHepler') }}</span>
|
<span class="input-help">{{ $t('app.defaultWebDomainHepler') }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<CustomSetting v-if="isProductPro" />
|
||||||
<el-button type="primary" :disabled="loading" @click="submit()">
|
|
||||||
{{ $t('commons.button.confirm') }}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
|
<DefaultDomain ref="domainRef" @close="search" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { GetAppStoreConfig, UpdateAppStoreConfig } from '@/api/modules/app';
|
import { GetAppStoreConfig } from '@/api/modules/app';
|
||||||
import { Rules } from '@/global/form-rules';
|
import { Rules } from '@/global/form-rules';
|
||||||
import i18n from '@/lang';
|
|
||||||
import { MsgSuccess } from '@/utils/message';
|
|
||||||
import { FormRules } from 'element-plus';
|
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 { storeToRefs } from 'pinia';
|
||||||
|
|
||||||
|
const globalStore = GlobalStore();
|
||||||
|
const { isProductPro } = storeToRefs(globalStore);
|
||||||
|
|
||||||
const rules = ref<FormRules>({
|
const rules = ref<FormRules>({
|
||||||
defaultDomain: [Rules.domainOrIP],
|
defaultDomain: [Rules.domainOrIP],
|
||||||
@ -51,12 +58,11 @@ const config = ref({
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const configForm = ref();
|
const configForm = ref();
|
||||||
const protocol = ref('http://');
|
const protocol = ref('http://');
|
||||||
|
const domainRef = ref();
|
||||||
|
|
||||||
function getUrl(url: string) {
|
function getUrl(url: string) {
|
||||||
const regex = /^(https?:\/\/)(.*)/;
|
const regex = /^(https?:\/\/)(.*)/;
|
||||||
|
|
||||||
const match = url.match(regex);
|
const match = url.match(regex);
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
const protocol = match[1];
|
const protocol = match[1];
|
||||||
const remainder = match[2];
|
const remainder = match[2];
|
||||||
@ -86,28 +92,10 @@ const search = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const submit = async () => {
|
const setDefaultDomain = () => {
|
||||||
if (!configForm.value) return;
|
domainRef.value.acceptParams({
|
||||||
await configForm.value.validate(async (valid) => {
|
domain: config.value.defaultDomain,
|
||||||
if (!valid) {
|
protocol: protocol.value,
|
||||||
return;
|
|
||||||
}
|
|
||||||
loading.value = true;
|
|
||||||
try {
|
|
||||||
let defaultDomain = '';
|
|
||||||
if (config.value.defaultDomain) {
|
|
||||||
defaultDomain = protocol.value + config.value.defaultDomain;
|
|
||||||
}
|
|
||||||
const req = {
|
|
||||||
defaultDomain: defaultDomain,
|
|
||||||
};
|
|
||||||
await UpdateAppStoreConfig(req);
|
|
||||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
|
||||||
} catch (error) {
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
search();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user