将应用商店的用户实例保存到数据库

This commit is contained in:
panshuxiao
2025-09-07 10:34:06 +08:00
repo.diff.parent d86772249c
repo.diff.commit c0e4044dab
repo.diff.stats_desc%!(EXTRA int=9, int=651, int=173)

repo.diff.view_file

@@ -128,6 +128,25 @@
font-size: 1em !important;
}
}
/* 修复应用详情页面中网站和仓库按钮的文字对齐问题 */
#app-details-modal .ui.buttons .ui.button {
display: flex !important;
align-items: center !important;
justify-content: center !important;
height: 2.5em !important;
line-height: 1 !important;
}
#app-details-modal .ui.buttons .ui.button i.icon {
margin-right: 0.5em !important;
line-height: 1 !important;
}
#app-details-modal .ui.buttons .ui.button:not(.icon) {
padding-left: 1em !important;
padding-right: 1em !important;
}
</style>
<div class="ui stackable grid">
@@ -331,7 +350,7 @@
<div class="actions">
<div class="ui button" onclick="closeDetailsModal()">{{ctx.Locale.Tr "cancel"}}</div>
<div class="ui primary button" onclick="updateInstalledAppFromDetails()">更新应用</div>
<div class="ui orange button" onclick="stopCurrentAppFromDetails()">暂停应用</div>
<div class="ui orange button" id="pause-resume-btn" onclick="togglePauseResumeFromDetails()">暂停应用</div>
<div class="ui red button" onclick="uninstallCurrentAppFromDetails()">卸载应用</div>
</div>
</div>
@@ -1046,8 +1065,8 @@ async function checkAppInstallStatus(app) {
const replicas = data.replicas ?? data.status?.replicas ?? 0;
const readyReplicas = data.readyReplicas ?? data.status?.readyReplicas ?? 0;
// 判断是否已安装且就绪
const isInstalled = phase !== 'Not Installed' && phase !== 'Unknown' && (replicas === 0 || readyReplicas > 0);
// 判断是否已安装(包括暂停状态)
const isInstalled = phase !== 'Not Installed' && phase !== 'Unknown';
if (isInstalled) {
installBtn.className = 'ui green compact button disabled';
@@ -1087,41 +1106,54 @@ function uninstallCurrentAppFromDetails() {
uninstallForm.submit();
}
// 暂停应用(从详情弹窗触发)
function stopCurrentAppFromDetails() {
// 暂停/恢复应用(从详情弹窗触发)
function togglePauseResumeFromDetails() {
if (!currentApp) return;
const appId = currentApp.id || currentApp.app_id;
// 根据当前状态决定操作
const isRunning = currentAppStatus && currentAppStatus.replicas > 0;
const action = isRunning ? 'stop' : 'resume';
const actionText = isRunning ? '暂停' : '恢复';
const confirmText = isRunning ?
'确定要暂停应用吗?暂停后应用将停止运行,但数据会保留。' :
'确定要恢复应用吗?应用将重新开始运行。';
// 显示确认对话框
if (!confirm('确定要暂停应用吗?暂停后应用将停止运行,但数据会保留。')) {
if (!confirm(confirmText)) {
return;
}
// 创建暂停应用的请求
const stopForm = document.createElement('form');
stopForm.method = 'POST';
stopForm.action = `/user/settings/appstore/stop/${appId}`;
// 创建暂停/恢复应用的请求
const form = document.createElement('form');
form.method = 'POST';
form.action = `/user/settings/appstore/${action}/${appId}`;
const csrfInput = document.createElement('input');
csrfInput.type = 'hidden';
csrfInput.name = '_csrf';
csrfInput.value = document.querySelector('meta[name="_csrf"]')?.content || '';
stopForm.appendChild(csrfInput);
form.appendChild(csrfInput);
const appIdInput = document.createElement('input');
appIdInput.type = 'hidden';
appIdInput.name = 'app_id';
appIdInput.value = appId;
stopForm.appendChild(appIdInput);
form.appendChild(appIdInput);
const redirectInput = document.createElement('input');
redirectInput.type = 'hidden';
redirectInput.name = 'redirect_to';
redirectInput.value = window.location.pathname;
stopForm.appendChild(redirectInput);
form.appendChild(redirectInput);
document.body.appendChild(stopForm);
stopForm.submit();
document.body.appendChild(form);
form.submit();
}
// 暂停应用(从详情弹窗触发)- 保留向后兼容
function stopCurrentAppFromDetails() {
togglePauseResumeFromDetails();
}
// 加载并渲染运行状态(基于 K8s Application CRD
@@ -1169,13 +1201,13 @@ async function loadAndRenderAppStatus(app) {
// 根据应用状态动态控制操作按钮的显示
function updateActionButtonsVisibility() {
const updateBtn = document.querySelector('#app-details-modal .ui.primary.button[onclick="updateInstalledAppFromDetails()"]');
const stopBtn = document.querySelector('#app-details-modal .ui.orange.button[onclick="stopCurrentAppFromDetails()"]');
const pauseResumeBtn = document.getElementById('pause-resume-btn');
const uninstallBtn = document.querySelector('#app-details-modal .ui.red.button[onclick="uninstallCurrentAppFromDetails()"]');
if (!currentAppStatus) {
// 状态未知,隐藏所有操作按钮
if (updateBtn) updateBtn.style.display = 'none';
if (stopBtn) stopBtn.style.display = 'none';
if (pauseResumeBtn) pauseResumeBtn.style.display = 'none';
if (uninstallBtn) uninstallBtn.style.display = 'none';
return;
}
@@ -1189,9 +1221,21 @@ function updateActionButtonsVisibility() {
updateBtn.style.display = isInstalled ? 'inline-block' : 'none';
}
// 暂停按钮:只有正在运行的应用才能暂停
if (stopBtn) {
stopBtn.style.display = isRunning ? 'inline-block' : 'none';
// 暂停/恢复按钮:已安装的应用可以暂停或恢复
if (pauseResumeBtn) {
if (isInstalled) {
pauseResumeBtn.style.display = 'inline-block';
// 根据应用状态更新按钮文本和样式
if (isRunning) {
pauseResumeBtn.textContent = '暂停应用';
pauseResumeBtn.className = 'ui orange button';
} else if (isStopped) {
pauseResumeBtn.textContent = '恢复应用';
pauseResumeBtn.className = 'ui green button';
}
} else {
pauseResumeBtn.style.display = 'none';
}
}
// 卸载按钮:只有已安装的应用才能卸载
@@ -1295,49 +1339,9 @@ async function installApp() {
installBtn.disabled = true;
}
// 异步提交,成功后更新按钮状态
try {
const formData = new FormData(installForm);
const response = await fetch(installForm.action, {
method: 'POST',
body: formData
});
if (response.ok) {
// 安装成功,更新按钮状态
const appId = currentApp.id || currentApp.app_id;
const cardInstallBtn = document.getElementById(`install-btn-${appId}`);
if (cardInstallBtn) {
cardInstallBtn.className = 'ui green compact button disabled';
cardInstallBtn.innerHTML = '<i class="check icon"></i>已安装';
cardInstallBtn.onclick = null;
}
closeInstallModal();
// 显示成功消息
alert('应用安装成功!');
} else {
// 安装失败,恢复按钮状态
if (installBtn) {
installBtn.className = 'ui primary button';
installBtn.textContent = '安装应用';
installBtn.disabled = false;
}
const errorData = await response.json();
alert('安装失败: ' + (errorData.error || '未知错误'));
}
} catch (error) {
// 网络错误,恢复按钮状态
if (installBtn) {
installBtn.className = 'ui primary button';
installBtn.textContent = '安装应用';
installBtn.disabled = false;
}
alert('安装失败: ' + error.message);
}
// 清理表单
document.body.removeChild(installForm);
// 与卸载一致:使用表单直接提交,后端重定向以显示绿色提示
installForm.submit();
return;
}
function showAddAppModal() {