jcloud/dashboard/src2/components/site/InstallAppDialog.vue

237 lines
6.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<Dialog
v-model="show"
:options="{
title: '在您的站点上安装应用',
size: '4xl'
}"
>
<template #body-content>
<ObjectList :options="listOptions" />
</template>
</Dialog>
</template>
<script>
import { getCachedDocumentResource, createResource } from 'jingrow-ui';
import { defineAsyncComponent, h } from 'vue';
import { toast } from 'vue-sonner';
import { renderDialog } from '../../utils/components';
import router from '../../router';
import ObjectList from '../ObjectList.vue';
import { getToastErrorMessage } from '../../utils/toast';
export default {
props: {
site: {
type: String,
required: true
}
},
emits: ['installed'],
components: {
ObjectList
},
data() {
return {
show: true,
currentApp: null,
retryCount: 0
};
},
resources: {
// 添加API资源定义检查应用是否可安装
checkAppInstallable() {
return {
url: 'jcloud.api.site.check_app_installable',
params: {
name: this.site,
app: this.currentApp
},
auto: false
};
}
},
computed: {
$site() {
return getCachedDocumentResource('Site', this.site);
},
listOptions() {
const handleInstall = async row => {
if (this.$site.installApp.loading) return;
// 设置当前应用以便资源可以使用
this.currentApp = row.app;
this.retryCount = 0
// 打印关键变量进行调试
console.log('=== 安装应用调试信息 ===');
console.log('站点名称:', this.site);
console.log('应用ID:', this.currentApp);
console.log('站点对象:', this.$site);
console.log('站点plan:', this.$site.pg?.plan);
console.log('=== 调试信息结束 ===');
try {
// 尝试获取应用安装权限信息最多重试2次
let checkResult = null;
let apiCalled = false;
while (!checkResult && this.retryCount < 3) {
console.log(`正在调用check_app_installable API... (尝试 ${this.retryCount + 1}/3)`);
apiCalled = true;
await this.$resources.checkAppInstallable.submit();
console.log('API调用完成状态:', {
loading: this.$resources.checkAppInstallable.loading,
error: this.$resources.checkAppInstallable.error
});
// 获取检查结果
checkResult = this.$resources.checkAppInstallable.data;
console.log('API返回结果:', checkResult);
// 如果返回结果为null且未达到最大重试次数等待500ms后重试
if (!checkResult && this.retryCount < 2) {
this.retryCount++;
console.log(`API返回null将在500ms后重试(${this.retryCount}/2)...`);
await new Promise(resolve => setTimeout(resolve, 500));
} else {
break;
}
}
// 检查返回结果是否有效
if (!checkResult) {
console.error('API返回结果无效已达到最大重试次数');
toast.error('应用安装权限验证失败,安装已取消');
return;
}
// 检查应用是否可安装
console.log('应用可安装?', checkResult.installable);
console.log('required_plan_level:', checkResult.required_plan_level);
console.log('current_plan_level:', checkResult.current_plan_level);
// 如果结果显示不可安装,显示错误信息并退出
if (checkResult.installable !== true) {
console.log('应用不可安装,显示错误信息');
const subscriptionTypeMap = {
2: 'Pro',
3: 'Business',
4: 'Enterprise',
5: 'Ultimate'
};
const requiredPlan = subscriptionTypeMap[checkResult.required_plan_level] ||
`Level ${checkResult.required_plan_level}`;
toast.error(`无法安装此应用,需要${requiredPlan}或更高级别的站点计划。请先升级您的站点计划。`);
return;
}
// 如果可安装,执行安装
console.log('应用可安装,开始安装流程');
await toast.promise(
this.$site.installApp.submit({
app: row.app
}),
{
loading: '正在创建安装任务...',
success: jobId => {
console.log('安装任务创建成功jobId:', jobId);
this.$emit('installed');
this.show = false;
try {
if (jobId) {
router.push({
name: 'Site Job',
params: {
name: this.site,
id: String(jobId)
}
}).catch(err => {
console.error('导航到作业页面失败:', err);
});
}
} catch (err) {
console.error('处理作业ID时出错:', err);
}
return '应用安装任务已创建';
},
error: e => {
console.error('安装过程中出错:', e);
return getToastErrorMessage(e);
}
}
);
} catch (error) {
console.error('检查应用安装权限失败:', error);
toast.error('无法验证安装权限,安装已取消');
}
};
return {
label: '应用',
fieldname: 'app',
fieldtype: 'ListSelection',
emptyStateMessage:
'未找到应用' +
(!this.$site.pg?.group_public
? '。请从您的工作台添加它们。'
: ''),
columns: [
{
label: '标题',
fieldname: 'title',
class: 'font-medium',
width: 2,
format: (value, row) => value || row.app_title
},
{
label: '仓库',
fieldname: 'repository_owner',
class: 'text-gray-600',
width: '10rem'
},
{
label: '版本',
fieldname: 'branch',
class: 'text-gray-600',
width: '20rem'
},
{
label: '',
fieldname: '',
align: 'right',
type: 'Button',
width: '5rem',
Button({ row }) {
return {
label: '安装',
onClick: () => {
handleInstall(row);
}
};
}
}
],
resource: () => {
return {
url: 'jcloud.api.site.available_apps',
params: {
name: this.site
},
auto: true
};
}
};
}
}
};
</script>