mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 00:09:16 +08:00
feat(appstore): Add Synchronization of Main Node Application Store Pa… (#7612)
This commit is contained in:
parent
68698217ee
commit
b1fbdcc566
@ -251,22 +251,22 @@ func (t *Task) Logf(format string, v ...any) {
|
||||
}
|
||||
|
||||
func (t *Task) LogFailed(msg string) {
|
||||
t.Logger.Printf(msg + i18n.GetMsgByKey("Failed"))
|
||||
t.Logger.Println(msg + i18n.GetMsgByKey("Failed"))
|
||||
}
|
||||
|
||||
func (t *Task) LogFailedWithErr(msg string, err error) {
|
||||
t.Logger.Printf(fmt.Sprintf("%s %s : %s", msg, i18n.GetMsgByKey("Failed"), err.Error()))
|
||||
t.Logger.Println(fmt.Sprintf("%s %s : %s", msg, i18n.GetMsgByKey("Failed"), err.Error()))
|
||||
}
|
||||
|
||||
func (t *Task) LogSuccess(msg string) {
|
||||
t.Logger.Printf(msg + i18n.GetMsgByKey("Success"))
|
||||
t.Logger.Println(msg + i18n.GetMsgByKey("Success"))
|
||||
}
|
||||
func (t *Task) LogSuccessF(format string, v ...any) {
|
||||
t.Logger.Printf(fmt.Sprintf(format, v...) + i18n.GetMsgByKey("Success"))
|
||||
t.Logger.Println(fmt.Sprintf(format, v...) + i18n.GetMsgByKey("Success"))
|
||||
}
|
||||
|
||||
func (t *Task) LogStart(msg string) {
|
||||
t.Logger.Printf(fmt.Sprintf("%s%s", i18n.GetMsgByKey("Start"), msg))
|
||||
t.Logger.Println(fmt.Sprintf("%s%s", i18n.GetMsgByKey("Start"), msg))
|
||||
}
|
||||
|
||||
func (t *Task) LogWithOps(operate, msg string) {
|
||||
|
@ -65,3 +65,14 @@ func WithMap(Key string, maps map[string]interface{}, err error) BusinessError {
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func WithName(Key string, name string) BusinessError {
|
||||
paramMap := map[string]interface{}{}
|
||||
if name != "" {
|
||||
paramMap["name"] = name
|
||||
}
|
||||
return BusinessError{
|
||||
Msg: Key,
|
||||
Map: paramMap,
|
||||
}
|
||||
}
|
||||
|
@ -161,3 +161,11 @@ func DownloadFileWithProxy(url, dst string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Stat(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -268,4 +268,9 @@ export namespace App {
|
||||
export interface AppStoreConfig {
|
||||
defaultDomain: string;
|
||||
}
|
||||
|
||||
export interface CustomAppStoreConfig {
|
||||
status: string;
|
||||
imagePrefix: string;
|
||||
}
|
||||
}
|
||||
|
@ -122,3 +122,7 @@ export const UpdateAppStoreConfig = (req: App.AppStoreConfig) => {
|
||||
export const SyncCutomAppStore = (req: App.AppStoreSync) => {
|
||||
return http.post(`/custom/app/sync`, req);
|
||||
};
|
||||
|
||||
export const getCurrentNodeCustomAppConfig = () => {
|
||||
return http.get<App.CustomAppStoreConfig>(`/custom/app/config`);
|
||||
};
|
||||
|
@ -114,6 +114,8 @@ import { Backup } from '@/api/interface/backup';
|
||||
import router from '@/routers';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import TaskLog from '@/components/task-log/index.vue';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const selects = ref<any>([]);
|
||||
const loading = ref();
|
||||
@ -306,7 +308,7 @@ const onDownload = async (row: Backup.RecordInfo) => {
|
||||
fileName: row.fileName,
|
||||
};
|
||||
await downloadBackupRecord(params).then(async (res) => {
|
||||
downloadFile(res.data);
|
||||
downloadFile(res.data, globalStore.currentNode);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, useSlots } from 'vue';
|
||||
defineOptions({ name: 'DrawerPro' });
|
||||
defineOptions({ name: 'DialogPro' });
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
|
@ -34,6 +34,8 @@
|
||||
import { nextTick, onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import { downloadFile } from '@/utils/util';
|
||||
import { ReadByLine } from '@/api/modules/files';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
interface LogProps {
|
||||
id?: number;
|
||||
@ -146,7 +148,7 @@ const changeLoading = () => {
|
||||
|
||||
const onDownload = async () => {
|
||||
changeLoading();
|
||||
downloadFile(logPath.value);
|
||||
downloadFile(logPath.value, globalStore.currentNode);
|
||||
changeLoading();
|
||||
};
|
||||
|
||||
|
@ -1859,6 +1859,7 @@ const message = {
|
||||
defaultWebDomainHepler: '默认访问用于应用端口跳转,例如应用端口为 8080 则跳转地址为http(s)://默认访问地址:8080',
|
||||
webUIConfig: '请在应用参数或者应用商店设置处添加访问地址',
|
||||
toLink: '跳转',
|
||||
customAppHelper: '当前使用的是主节点应用商店包,修改配置请在主节点操作',
|
||||
},
|
||||
website: {
|
||||
website: '网站',
|
||||
|
@ -51,6 +51,7 @@ const GlobalStore = defineStore({
|
||||
state.themeConfig.isGold ||
|
||||
(state.themeConfig.theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches),
|
||||
isDarkGoldTheme: (state) => state.themeConfig.isGold && state.isMasterProductPro,
|
||||
isMaster: (state) => state.currentNode === 'local',
|
||||
},
|
||||
actions: {
|
||||
setOpenMenuTabs(openMenuTabs: boolean) {
|
||||
|
@ -519,10 +519,33 @@ export function toLowerCase(str: string) {
|
||||
return str.toLowerCase();
|
||||
}
|
||||
|
||||
export function downloadFile(filePath: string) {
|
||||
let url = `${import.meta.env.VITE_API_URL as string}/files/download?`;
|
||||
let path = encodeURIComponent(filePath);
|
||||
window.open(url + 'path=' + path, '_blank');
|
||||
export function downloadFile(filePath: string, currentNode: string) {
|
||||
const url = `${import.meta.env.VITE_API_URL as string}/files/download`;
|
||||
const path = encodeURIComponent(filePath);
|
||||
|
||||
fetch(`${url}?path=${path}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
CurrentNode: currentNode,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.blob();
|
||||
})
|
||||
.then((blob) => {
|
||||
const downloadUrl = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = downloadUrl;
|
||||
a.download = filePath.split('/').pop() || 'downloaded-file';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
window.URL.revokeObjectURL(downloadUrl);
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
export function downloadWithContent(content: string, fileName: string) {
|
||||
|
@ -175,7 +175,14 @@
|
||||
<script lang="ts" setup>
|
||||
import { App } from '@/api/interface/app';
|
||||
import { onMounted, reactive, ref, computed } from 'vue';
|
||||
import { GetAppTags, SearchApp, SyncApp, SyncCutomAppStore, SyncLocalApp } from '@/api/modules/app';
|
||||
import {
|
||||
GetAppTags,
|
||||
SearchApp,
|
||||
SyncApp,
|
||||
SyncCutomAppStore,
|
||||
SyncLocalApp,
|
||||
getCurrentNodeCustomAppConfig,
|
||||
} from '@/api/modules/app';
|
||||
import Install from '../detail/install/index.vue';
|
||||
import router from '@/routers';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
@ -184,7 +191,6 @@ import { getLanguage, newUUID } from '@/utils/util';
|
||||
import Detail from '../detail/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 { isProductPro } = storeToRefs(globalStore);
|
||||
@ -350,7 +356,7 @@ onMounted(async () => {
|
||||
}
|
||||
search(req);
|
||||
if (isProductPro.value) {
|
||||
const res = await GetCustomAppStoreConfig();
|
||||
const res = await getCurrentNodeCustomAppConfig();
|
||||
if (res && res.data) {
|
||||
syncCustomAppstore.value = res.data.status === 'enable';
|
||||
}
|
||||
|
@ -28,7 +28,10 @@
|
||||
</el-input>
|
||||
<span class="input-help">{{ $t('app.defaultWebDomainHepler') }}</span>
|
||||
</el-form-item>
|
||||
<CustomSetting v-if="isProductPro" />
|
||||
<CustomSetting v-if="isProductPro && globalStore.isMaster" />
|
||||
<el-form-item v-if="!globalStore.isMaster && useCustomApp">
|
||||
<el-text type="warning">{{ $t('app.customAppHelper') }}</el-text>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
@ -38,7 +41,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { GetAppStoreConfig } from '@/api/modules/app';
|
||||
import { GetAppStoreConfig, getCurrentNodeCustomAppConfig } from '@/api/modules/app';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { FormRules } from 'element-plus';
|
||||
import CustomSetting from '@/xpack/views/appstore/index.vue';
|
||||
@ -59,6 +62,7 @@ const loading = ref(false);
|
||||
const configForm = ref();
|
||||
const protocol = ref('http://');
|
||||
const domainRef = ref();
|
||||
const useCustomApp = ref(false);
|
||||
|
||||
function getUrl(url: string) {
|
||||
const regex = /^(https?:\/\/)(.*)/;
|
||||
@ -99,7 +103,18 @@ const setDefaultDomain = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const getNodeConfig = async () => {
|
||||
if (globalStore.isMaster) {
|
||||
return;
|
||||
}
|
||||
const res = await getCurrentNodeCustomAppConfig();
|
||||
if (res && res.data) {
|
||||
useCustomApp.value = res.data.status === 'enable';
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
search();
|
||||
getNodeConfig();
|
||||
});
|
||||
</script>
|
||||
|
@ -54,6 +54,8 @@ import i18n from '@/lang';
|
||||
import { downloadBackupRecord, searchBackupRecordsByCronjob } from '@/api/modules/backup';
|
||||
import { Backup } from '@/api/interface/backup';
|
||||
import { MsgError } from '@/utils/message';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const selects = ref<any>([]);
|
||||
const loading = ref();
|
||||
@ -116,7 +118,7 @@ const onDownload = async (row: Backup.RecordInfo) => {
|
||||
await downloadBackupRecord(params)
|
||||
.then(async (res) => {
|
||||
loading.value = false;
|
||||
downloadFile(res.data);
|
||||
downloadFile(res.data, globalStore.currentNode);
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
|
@ -311,7 +311,7 @@ import {
|
||||
RemoveFavorite,
|
||||
SearchFavorite,
|
||||
} from '@/api/modules/files';
|
||||
import { computeSize, copyText, dateFormat, downloadFile, getFileType, getIcon, getRandomStr } from '@/utils/util';
|
||||
import { computeSize, copyText, dateFormat, getFileType, getIcon, getRandomStr, downloadFile } from '@/utils/util';
|
||||
import { StarFilled, Star, Top, Right, Close } from '@element-plus/icons-vue';
|
||||
import { File } from '@/api/interface/file';
|
||||
import { Mimetypes, Languages } from '@/global/mimetype';
|
||||
@ -810,7 +810,7 @@ const openPaste = () => {
|
||||
};
|
||||
|
||||
const openDownload = (file: File.File) => {
|
||||
downloadFile(file.path);
|
||||
downloadFile(file.path, globalStore.currentNode);
|
||||
};
|
||||
|
||||
const openDetail = (row: File.File) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user