Compare commits
3 Commits
e6182b6c36
...
v3.0.37
| Author | SHA1 | Date | |
|---|---|---|---|
| 61673809c8 | |||
| 31eadfc38c | |||
| caad50d831 |
@@ -27,7 +27,8 @@ export default {
|
|||||||
dedupe: ['tslib']
|
dedupe: ['tslib']
|
||||||
}),
|
}),
|
||||||
commonjs({
|
commonjs({
|
||||||
transformMixedEsModules: true
|
transformMixedEsModules: true,
|
||||||
|
ignoreDynamicRequires: true
|
||||||
}),
|
}),
|
||||||
json(),
|
json(),
|
||||||
terser({
|
terser({
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ export class Core {
|
|||||||
return res.status(400).json({ status: 400, message: "缺少 path 参数" });
|
return res.status(400).json({ status: 400, message: "缺少 path 参数" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { ModCheckService } = await import('./dearth/index.js');
|
const { ModCheckService } = await import('./dearth/index');
|
||||||
const checkService = new ModCheckService(modsPath);
|
const checkService = new ModCheckService(modsPath);
|
||||||
const results = await checkService.checkMods();
|
const results = await checkService.checkMods();
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ export class Core {
|
|||||||
bundleName: bundleName.trim()
|
bundleName: bundleName.trim()
|
||||||
});
|
});
|
||||||
|
|
||||||
const { ModCheckService } = await import('./dearth/index.js');
|
const { ModCheckService } = await import('./dearth/index');
|
||||||
const checkService = new ModCheckService(folderPath);
|
const checkService = new ModCheckService(folderPath);
|
||||||
const results = await checkService.checkModsWithBundle(bundleName.trim());
|
const results = await checkService.checkModsWithBundle(bundleName.trim());
|
||||||
|
|
||||||
@@ -295,7 +295,7 @@ export class Core {
|
|||||||
// 获取模板列表
|
// 获取模板列表
|
||||||
this.app.get('/templates', async (req, res) => {
|
this.app.get('/templates', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const templateModule = await import('./template/index.js');
|
const templateModule = await import('./template/index');
|
||||||
const TemplateManager = (templateModule as any).TemplateManager;
|
const TemplateManager = (templateModule as any).TemplateManager;
|
||||||
const templateManager = new TemplateManager();
|
const templateManager = new TemplateManager();
|
||||||
const templates = await templateManager.getTemplates();
|
const templates = await templateManager.getTemplates();
|
||||||
@@ -321,7 +321,7 @@ export class Core {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateModule = await import('./template/index.js');
|
const templateModule = await import('./template/index');
|
||||||
const TemplateManager = (templateModule as any).TemplateManager;
|
const TemplateManager = (templateModule as any).TemplateManager;
|
||||||
const templateManager = new TemplateManager();
|
const templateManager = new TemplateManager();
|
||||||
|
|
||||||
@@ -353,7 +353,7 @@ export class Core {
|
|||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
|
|
||||||
const templateModule = await import('./template/index.js');
|
const templateModule = await import('./template/index');
|
||||||
const TemplateService = (templateModule as any).TemplateService;
|
const TemplateService = (templateModule as any).TemplateService;
|
||||||
const templateService = new TemplateService();
|
const templateService = new TemplateService();
|
||||||
|
|
||||||
@@ -385,7 +385,7 @@ export class Core {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateModule = await import('./template/index.js');
|
const templateModule = await import('./template/index');
|
||||||
const TemplateManager = (templateModule as any).TemplateManager;
|
const TemplateManager = (templateModule as any).TemplateManager;
|
||||||
const templateManager = new TemplateManager();
|
const templateManager = new TemplateManager();
|
||||||
|
|
||||||
@@ -414,7 +414,7 @@ export class Core {
|
|||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const path = await import('path');
|
const path = await import('path');
|
||||||
const { exec } = await import('child_process');
|
const { exec } = await import('child_process');
|
||||||
const templateModule = await import('./template/index.js');
|
const templateModule = await import('./template/index');
|
||||||
const TemplateManager = (templateModule as any).TemplateManager;
|
const TemplateManager = (templateModule as any).TemplateManager;
|
||||||
|
|
||||||
const templateManager = new TemplateManager();
|
const templateManager = new TemplateManager();
|
||||||
@@ -449,7 +449,7 @@ export class Core {
|
|||||||
this.app.get('/templates/:id/export', async (req, res) => {
|
this.app.get('/templates/:id/export', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const templateModule = await import('./template/index.js');
|
const templateModule = await import('./template/index');
|
||||||
const TemplateManager = (templateModule as any).TemplateManager;
|
const TemplateManager = (templateModule as any).TemplateManager;
|
||||||
const templateManager = new TemplateManager();
|
const templateManager = new TemplateManager();
|
||||||
|
|
||||||
@@ -491,7 +491,7 @@ export class Core {
|
|||||||
return res.status(400).json({ status: 400, message: "只支持 .zip 文件" });
|
return res.status(400).json({ status: 400, message: "只支持 .zip 文件" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateModule = await import('./template/index.js');
|
const templateModule = await import('./template/index');
|
||||||
const TemplateManager = (templateModule as any).TemplateManager;
|
const TemplateManager = (templateModule as any).TemplateManager;
|
||||||
const templateManager = new TemplateManager();
|
const templateManager = new TemplateManager();
|
||||||
|
|
||||||
@@ -631,7 +631,7 @@ export class Core {
|
|||||||
unlinkSync(tempFilePath);
|
unlinkSync(tempFilePath);
|
||||||
|
|
||||||
// 导入模板
|
// 导入模板
|
||||||
const templateModule = await import('./template/index.js');
|
const templateModule = await import('./template/index');
|
||||||
const TemplateManager = (templateModule as any).TemplateManager;
|
const TemplateManager = (templateModule as any).TemplateManager;
|
||||||
const templateManager = new TemplateManager();
|
const templateManager = new TemplateManager();
|
||||||
|
|
||||||
@@ -661,8 +661,8 @@ export class Core {
|
|||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const error = err as Error;
|
const error = err as Error;
|
||||||
const { requestId } = req.body;
|
const { requestId, url } = req.body;
|
||||||
logger.error("/templates/install-from-url 路由错误", error);
|
logger.error("/templates/install-from-url 路由错误", { error: error.message, stack: error.stack, url });
|
||||||
|
|
||||||
// 发送错误信息到SSE连接
|
// 发送错误信息到SSE连接
|
||||||
if (sseConnections.has(requestId)) {
|
if (sseConnections.has(requestId)) {
|
||||||
@@ -670,7 +670,8 @@ export class Core {
|
|||||||
sseRes.write(`data: ${JSON.stringify({
|
sseRes.write(`data: ${JSON.stringify({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
status: 500,
|
status: 500,
|
||||||
message: "安装模板失败"
|
message: "安装模板失败",
|
||||||
|
details: error.message
|
||||||
})}\n\n`);
|
})}\n\n`);
|
||||||
sseRes.end();
|
sseRes.end();
|
||||||
sseConnections.delete(requestId);
|
sseConnections.delete(requestId);
|
||||||
@@ -679,7 +680,11 @@ export class Core {
|
|||||||
// 清理下载状态
|
// 清理下载状态
|
||||||
downloadStates.delete(requestId);
|
downloadStates.delete(requestId);
|
||||||
|
|
||||||
res.status(500).json({ status: 500, message: "安装模板失败" });
|
res.status(500).json({
|
||||||
|
status: 500,
|
||||||
|
message: "安装模板失败",
|
||||||
|
details: error.message
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -716,7 +721,7 @@ export class Core {
|
|||||||
const { default: got } = await import('got');
|
const { default: got } = await import('got');
|
||||||
|
|
||||||
// 从指定URL获取模板商店数据
|
// 从指定URL获取模板商店数据
|
||||||
const response = await got('http://dex.xcclyc.cn/template/template_stor.json');
|
const response = await got('http://git.xcclyc.cn/xcclyc/DeEarthX-CE-Tems/raw/branch/main/template_stor.json');
|
||||||
const data = JSON.parse(response.body);
|
const data = JSON.parse(response.body);
|
||||||
|
|
||||||
// 确保返回的数据结构符合前端预期
|
// 确保返回的数据结构符合前端预期
|
||||||
|
|||||||
@@ -550,7 +550,7 @@ export class ModCheckService {
|
|||||||
jarData = fs.readFileSync(file.filename);
|
jarData = fs.readFileSync(file.filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { yauzl_promise } = await import("../utils/ziplib.js");
|
const { yauzl_promise } = await import("../utils/ziplib");
|
||||||
const zipEntries = await yauzl_promise(jarData);
|
const zipEntries = await yauzl_promise(jarData);
|
||||||
|
|
||||||
for (const entry of zipEntries) {
|
for (const entry of zipEntries) {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export async function mlsetup(ml: string, mcv: string, mlv: string, path: string
|
|||||||
messageWS.serverInstallStep(`Applying Template: ${template}`, 1, totalSteps);
|
messageWS.serverInstallStep(`Applying Template: ${template}`, 1, totalSteps);
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateModule = await import('../template/index.js');
|
const templateModule = await import('../template/index');
|
||||||
const TemplateManager = (templateModule as any).TemplateManager;
|
const TemplateManager = (templateModule as any).TemplateManager;
|
||||||
const templateManager = new TemplateManager();
|
const templateManager = new TemplateManager();
|
||||||
const templates = await templateManager.getTemplates();
|
const templates = await templateManager.getTemplates();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"common": {
|
"common": {
|
||||||
"app_name": "DeEarthX",
|
"app_name": "DeEarthX-CE ",
|
||||||
"version": "版本",
|
"version": "版本",
|
||||||
"status_loading": "启动中",
|
"status_loading": "启动中",
|
||||||
"status_success": "正常",
|
"status_success": "正常",
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
"step1_title": "解压整合包",
|
"step1_title": "解压整合包",
|
||||||
"step1_desc": "解压内容并下载文件",
|
"step1_desc": "解压内容并下载文件",
|
||||||
"step2_title": "筛选模组",
|
"step2_title": "筛选模组",
|
||||||
"step2_desc": "DeEarthX 的核心功能",
|
"step2_desc": "DeEarthX-CE 的核心功能",
|
||||||
"step3_title": "下载服务端",
|
"step3_title": "下载服务端",
|
||||||
"step3_desc": "安装模组加载器服务端",
|
"step3_desc": "安装模组加载器服务端",
|
||||||
"step4_title": "完成",
|
"step4_title": "完成",
|
||||||
@@ -171,8 +171,8 @@
|
|||||||
"store_load_failed": "加载模板商店失败"
|
"store_load_failed": "加载模板商店失败"
|
||||||
},
|
},
|
||||||
"setting": {
|
"setting": {
|
||||||
"title": "DeEarthX 设置",
|
"title": "DeEarthX-CE 设置",
|
||||||
"subtitle": "让 DeEarthX V3 更适合你!",
|
"subtitle": "让 DeEarthX-CE V3 更适合你!",
|
||||||
"category_filter": "模组筛选设置",
|
"category_filter": "模组筛选设置",
|
||||||
"category_mirror": "下载源设置",
|
"category_mirror": "下载源设置",
|
||||||
"category_system": "系统管理设置",
|
"category_system": "系统管理设置",
|
||||||
@@ -210,7 +210,7 @@
|
|||||||
"config_invalid_format": "配置文件格式无效"
|
"config_invalid_format": "配置文件格式无效"
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "关于 DeEarthX",
|
"title": "关于 DeEarthX-CE",
|
||||||
"subtitle": "专业的 Minecraft 整合包服务端制作工具",
|
"subtitle": "专业的 Minecraft 整合包服务端制作工具",
|
||||||
"about_software": "关于软件",
|
"about_software": "关于软件",
|
||||||
"current_version": "当前版本:",
|
"current_version": "当前版本:",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "3.0.36",
|
"version": "3.0.37",
|
||||||
"buildTime": "2026-03-15",
|
"buildTime": "2026-03-17",
|
||||||
"author": "xcclyc"
|
"author": "xcclyc"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,51 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="tw:h-full tw:w-full tw:flex tw:flex-col tw:justify-center tw:items-center">
|
<div class="tw:h-screen tw:w-full tw:flex tw:flex-col tw:justify-center tw:items-center tw:bg-gradient-to-br tw:from-gray-50 tw:to-gray-100">
|
||||||
<div class="tw:w-32 tw:h-32 tw:mb-8">
|
<div class="tw:w-32 tw:h-32 tw:mb-8">
|
||||||
<svg class="w-32 h-32 mb-4" viewBox="0 0 120 120">
|
<svg class="w-32 h-32 mb-4 tw:transition-all tw:duration-300 tw:hover:scale-110" viewBox="0 0 120 120">
|
||||||
<circle cx="60" cy="60" r="50" fill="#ef4444" />
|
<circle cx="60" cy="60" r="50" fill="#ef4444" class="tw:opacity-80" />
|
||||||
<path d="M40,40 L80,80 M80,40 L40,80" stroke="white" stroke-width="10" stroke-linecap="round" />
|
<path d="M40,40 L80,80 M80,40 L40,80" stroke="white" stroke-width="10" stroke-linecap="round" class="tw:opacity-90" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="tw:text-2xl tw:font-bold tw:text-center tw:mb-6 tw:text-red-500">Error</p>
|
<h1 class="tw:text-3xl tw:font-bold tw:text-center tw:mb-6 tw:text-red-500">错误提示</h1>
|
||||||
<div class="tw:w-1/2 tw:max-w-md tw:bg-white tw:p-6 tw:rounded-lg tw:shadow-lg">
|
<div class="tw:w-1/2 tw:max-w-md tw:bg-white tw:p-8 tw:rounded-xl tw:shadow-xl tw:border tw:border-gray-100 tw:transition-all tw:duration-300 tw:hover:shadow-2xl">
|
||||||
<p class="tw:text-sm tw:text-center tw:text-gray-500 mb-4">
|
<div class="tw:text-center tw:mb-6">
|
||||||
|
<p class="tw:text-lg tw:font-medium tw:text-gray-700 mb-2">
|
||||||
{{ errorMessage }}
|
{{ errorMessage }}
|
||||||
</p>
|
</p>
|
||||||
<div v-if="errorCode" class="tw:text-sm tw:text-center tw:text-gray-500 mb-6">
|
<div v-if="errorCode" class="tw:inline-block tw:px-4 tw:py-1 tw:bg-red-50 tw:text-red-600 tw:rounded-full tw:text-sm tw:font-medium mt-2">
|
||||||
错误码:{{ errorCode }}
|
错误码:{{ errorCode }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="suggestions.length > 0" class="tw:mt-6">
|
</div>
|
||||||
<p class="tw:text-sm tw:font-medium tw:text-gray-700 mb-2">建议解决方案:</p>
|
<div v-if="suggestions.length > 0" class="tw:mt-6 tw:bg-gray-50 tw:p-4 tw:rounded-lg">
|
||||||
<ul class="tw:text-xs tw:text-gray-600 tw:list-disc tw:pl-5">
|
<p class="tw:text-sm tw:font-medium tw:text-gray-700 mb-3">建议解决方案:</p>
|
||||||
<li v-for="(suggestion, index) in suggestions" :key="index" class="tw:mb-1">
|
<ul class="tw:text-sm tw:text-gray-600">
|
||||||
{{ suggestion }}
|
<li v-for="(suggestion, index) in suggestions" :key="index" class="tw:mb-2 tw:flex tw:items-start">
|
||||||
|
<span class="tw:w-5 tw:h-5 tw:flex tw:items-center tw:justify-center tw:bg-red-100 tw:text-red-500 tw:rounded-full tw:mr-3 tw:mt-0.5">
|
||||||
|
{{ index + 1 }}
|
||||||
|
</span>
|
||||||
|
<span>{{ suggestion }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:mt-6 tw:flex tw:justify-center tw:gap-4">
|
<div class="tw:mt-8 tw:flex tw:justify-center tw:gap-4">
|
||||||
<button
|
<button
|
||||||
class="tw:px-4 tw:py-2 tw:bg-[#67eac3] tw:text-gray-800 tw:rounded-md tw:hover:bg-[#56d9b0] tw:transition-colors"
|
class="tw:px-6 tw:py-2.5 tw:bg-[#67eac3] tw:text-gray-800 tw:rounded-lg tw:hover:bg-[#56d9b0] tw:transition-all tw:duration-300 tw:font-medium tw:shadow-sm tw:hover:shadow"
|
||||||
@click="goBack"
|
@click="goBack"
|
||||||
>
|
>
|
||||||
返回首页
|
返回首页
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="errorCode"
|
v-if="errorCode"
|
||||||
class="tw:px-4 tw:py-2 tw:bg-[#67eac3] tw:text-gray-800 tw:rounded-md tw:hover:bg-[#56d9b0] tw:transition-colors"
|
class="tw:px-6 tw:py-2.5 tw:bg-white tw:text-[#67eac3] tw:rounded-lg tw:hover:bg-gray-50 tw:transition-all tw:duration-300 tw:font-medium tw:shadow-sm tw:hover:shadow tw:border tw:border-[#67eac3]"
|
||||||
@click="openErrorDoc"
|
@click="openErrorDoc"
|
||||||
>
|
>
|
||||||
文档帮助
|
文档帮助
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="tw:mt-8 tw:text-xs tw:text-gray-400">
|
||||||
|
DeEarthX Core © {{ new Date().getFullYear() }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted, computed } from 'vue';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import { PlusOutlined, DeleteOutlined, FolderOutlined, ExclamationCircleOutlined, EditOutlined, UploadOutlined, DownloadOutlined } from '@ant-design/icons-vue';
|
import { PlusOutlined, DeleteOutlined, FolderOutlined, ExclamationCircleOutlined, EditOutlined, UploadOutlined, DownloadOutlined } from '@ant-design/icons-vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
@@ -25,6 +25,8 @@ interface StoreTemplate {
|
|||||||
description: string;
|
description: string;
|
||||||
size: string;
|
size: string;
|
||||||
downloadUrls: string[];
|
downloadUrls: string[];
|
||||||
|
version: string;
|
||||||
|
tag: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const templates = ref<Template[]>([]);
|
const templates = ref<Template[]>([]);
|
||||||
@@ -81,6 +83,29 @@ async function testDownloadSpeed(urls: string[]): Promise<string> {
|
|||||||
const storeTemplates = ref<StoreTemplate[]>([]);
|
const storeTemplates = ref<StoreTemplate[]>([]);
|
||||||
const storeLoading = ref(false);
|
const storeLoading = ref(false);
|
||||||
const activeTab = ref('local'); // 'local' 或 'store'
|
const activeTab = ref('local'); // 'local' 或 'store'
|
||||||
|
const selectedTag = ref<string>('all'); // 'all', 'dex', 'CE'
|
||||||
|
const searchKeyword = ref('');
|
||||||
|
|
||||||
|
// 过滤后的模板
|
||||||
|
const filteredStoreTemplates = computed(() => {
|
||||||
|
let filtered = storeTemplates.value;
|
||||||
|
|
||||||
|
// 按标签筛选
|
||||||
|
if (selectedTag.value !== 'all') {
|
||||||
|
filtered = filtered.filter(template => template.tag === selectedTag.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按关键词搜索
|
||||||
|
if (searchKeyword.value) {
|
||||||
|
const keyword = searchKeyword.value.toLowerCase();
|
||||||
|
filtered = filtered.filter(template =>
|
||||||
|
template.name.toLowerCase().includes(keyword) ||
|
||||||
|
template.description.toLowerCase().includes(keyword)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
});
|
||||||
|
|
||||||
const newTemplate = ref({
|
const newTemplate = ref({
|
||||||
name: '',
|
name: '',
|
||||||
@@ -533,7 +558,9 @@ async function downloadAndInstallTemplate(template: StoreTemplate) {
|
|||||||
// 关闭通知
|
// 关闭通知
|
||||||
message.destroy(notificationKey);
|
message.destroy(notificationKey);
|
||||||
|
|
||||||
message.error(data.message || t('template.install_failed'));
|
const errorMessage = data.message || t('template.install_failed');
|
||||||
|
const errorDetails = data.details ? ` (${data.details})` : '';
|
||||||
|
message.error(errorMessage + errorDetails);
|
||||||
// 重置状态
|
// 重置状态
|
||||||
downloadLoading.value = false;
|
downloadLoading.value = false;
|
||||||
showDownloadProgress.value = false;
|
showDownloadProgress.value = false;
|
||||||
@@ -583,7 +610,7 @@ onMounted(() => {
|
|||||||
<div class="tw:flex tw:justify-between tw:items-center tw:mb-6">
|
<div class="tw:flex tw:justify-between tw:items-center tw:mb-6">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="tw:text-2xl tw:font-bold tw:text-gray-800">{{ t('template.title') }}</h1>
|
<h1 class="tw:text-2xl tw:font-bold tw:text-gray-800">{{ t('template.title') }}</h1>
|
||||||
<p class="tw:text-gray-600 tw:mt-1">{{ t('template.description') }}</p>
|
<p class="tw:text-gray-600 tw:mt-1">可选 | 模板是DeEarthX的一种扩展方式,用于快速生成服务端和增加稳定性</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:flex tw:gap-2">
|
<div class="tw:flex tw:gap-2">
|
||||||
<a-upload
|
<a-upload
|
||||||
@@ -672,7 +699,27 @@ onMounted(() => {
|
|||||||
|
|
||||||
<!-- 模板商店 -->
|
<!-- 模板商店 -->
|
||||||
<a-spin v-if="activeTab === 'store'" :spinning="storeLoading">
|
<a-spin v-if="activeTab === 'store'" :spinning="storeLoading">
|
||||||
<div v-if="storeTemplates.length === 0 && !storeLoading" class="tw:text-center tw:py-16 tw:text-gray-500">
|
<!-- 搜索和筛选 -->
|
||||||
|
<div v-if="storeTemplates.length > 0 && !storeLoading" class="tw:flex tw:flex-wrap tw:justify-between tw:items-center tw:mb-4">
|
||||||
|
<div class="tw:flex tw:gap-2">
|
||||||
|
<a-radio-group v-model:value="selectedTag" class="tw-mr-4">
|
||||||
|
<a-radio-button value="all">全部</a-radio-button>
|
||||||
|
<a-radio-button value="dex">官方</a-radio-button>
|
||||||
|
<a-radio-button value="CE">社区</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</div>
|
||||||
|
<a-input-search
|
||||||
|
v-model:value="searchKeyword"
|
||||||
|
placeholder="搜索模板"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p class="tw:text-xs tw:text-gray-400 tw:mt-1">社区提供的模板官方未经检测,请自行选择使用</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="filteredStoreTemplates.length === 0 && !storeLoading" class="tw:text-center tw:py-16 tw:text-gray-500">
|
||||||
<DownloadOutlined style="font-size: 64px; margin-bottom: 16px;" />
|
<DownloadOutlined style="font-size: 64px; margin-bottom: 16px;" />
|
||||||
<p class="tw:text-lg">{{ t('template.store_empty') }}</p>
|
<p class="tw:text-lg">{{ t('template.store_empty') }}</p>
|
||||||
<p class="tw:text-sm tw:mt-2">{{ t('template.store_empty_hint') }}</p>
|
<p class="tw:text-sm tw:mt-2">{{ t('template.store_empty_hint') }}</p>
|
||||||
@@ -680,16 +727,24 @@ onMounted(() => {
|
|||||||
|
|
||||||
<div v-else class="tw:grid tw:grid-cols-1 md:tw:grid-cols-2 lg:tw:grid-cols-3 tw:gap-4">
|
<div v-else class="tw:grid tw:grid-cols-1 md:tw:grid-cols-2 lg:tw:grid-cols-3 tw:gap-4">
|
||||||
<div
|
<div
|
||||||
v-for="template in storeTemplates"
|
v-for="template in filteredStoreTemplates"
|
||||||
:key="template.id"
|
:key="template.id"
|
||||||
class="tw:bg-white tw:rounded-lg tw:shadow-md tw:p-5 tw:h-48 tw:flex tw:flex-col tw:border tw:border-gray-200 tw:transition-all tw:duration-300 hover:tw:shadow-lg hover:tw:border-blue-300"
|
class="tw:bg-white tw:rounded-lg tw:shadow-md tw:p-5 tw:h-48 tw:flex tw:flex-col tw:border tw:border-gray-200 tw:transition-all tw:duration-300 hover:tw:shadow-lg hover:tw:border-blue-300"
|
||||||
>
|
>
|
||||||
<div class="tw:flex-1 tw:overflow-hidden">
|
<div class="tw:flex-1 tw:overflow-hidden">
|
||||||
<div class="tw:flex tw:justify-between tw:items-start tw:mb-2">
|
<div class="tw:flex tw:justify-between tw:items-start tw:mb-2">
|
||||||
<h3 class="tw:text-lg tw:font-semibold tw:truncate tw:flex-1 tw:mr-2">{{ template.name }}</h3>
|
<h3 class="tw:text-lg tw:font-semibold tw:truncate tw:flex-1 tw:mr-2">{{ template.name }}</h3>
|
||||||
|
<div class="tw:flex tw:gap-2">
|
||||||
<a-tag color="green" size="small">{{ template.size }}</a-tag>
|
<a-tag color="green" size="small">{{ template.size }}</a-tag>
|
||||||
|
<a-tag :color="template.tag === 'dex' ? 'blue' : 'orange'" size="small">
|
||||||
|
{{ template.tag === 'dex' ? '官方' : '社区' }}
|
||||||
|
</a-tag>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="tw:text-sm tw:text-gray-600 tw:line-clamp-2 tw:mb-3">{{ template.description }}</p>
|
<p class="tw:text-sm tw:text-gray-600 tw:line-clamp-2 tw:mb-3">{{ template.description }}</p>
|
||||||
|
<div class="tw:flex tw:justify-between tw:text-xs tw:text-gray-500">
|
||||||
|
<span>版本: {{ template.version }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:flex tw:justify-end tw:mt-4 tw:pt-4 tw:border-t tw:border-gray-100">
|
<div class="tw:flex tw:justify-end tw:mt-4 tw:pt-4 tw:border-t tw:border-gray-100">
|
||||||
<a-button type="primary" size="small" @click="downloadAndInstallTemplate(template)">
|
<a-button type="primary" size="small" @click="downloadAndInstallTemplate(template)">
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
"size": "108.6MB",
|
"size": "108.6MB",
|
||||||
"downloadUrls": [
|
"downloadUrls": [
|
||||||
"https://pan.xcclyc.cn/f/pjfR/xccdex-official-fabric-1.20.1-0.18.4.zip"
|
"https://pan.xcclyc.cn/f/pjfR/xccdex-official-fabric-1.20.1-0.18.4.zip"
|
||||||
]
|
],
|
||||||
|
"version": "0.18.4",
|
||||||
|
"tag": "dex"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
|
|
||||||
socialLinks: [
|
socialLinks: [
|
||||||
{ icon: 'github', link: 'https://github.com' }
|
{ icon: 'gitea', link: 'https://git.xcclyc.cn/xcclyc/DeEarthX-CE' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
**可能原因**:
|
**可能原因**:
|
||||||
- 后端服务无法启动
|
- 后端服务无法启动
|
||||||
- 可能是权限问题
|
- 可能是权限问题(不要安装在C盘哦~)
|
||||||
- 可能是文件损坏
|
- 可能是文件损坏
|
||||||
- 可能是端口被占用
|
- 可能是端口被占用
|
||||||
|
|
||||||
@@ -254,3 +254,13 @@
|
|||||||
- 错误码仅用于参考,具体错误原因可能因环境不同而有所差异
|
- 错误码仅用于参考,具体错误原因可能因环境不同而有所差异
|
||||||
- 如遇到持续的错误,请检查系统环境和网络连接
|
- 如遇到持续的错误,请检查系统环境和网络连接
|
||||||
- 定期更新应用程序以获取最新的错误处理机制
|
- 定期更新应用程序以获取最新的错误处理机制
|
||||||
|
|
||||||
|
## 其它
|
||||||
|
|
||||||
|
如果解决不了,请向QQ群反馈,你需要反馈(CE或者主版本群都可以):
|
||||||
|
```
|
||||||
|
你好,我有XXX问题,错误码XXX
|
||||||
|
我的安装路径是XXX
|
||||||
|
环境是WindowsXXX,Java版本XXX
|
||||||
|
程序是XXX版本(CE或者主版本)
|
||||||
|
```
|
||||||
@@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
## 基本问题
|
## 基本问题
|
||||||
|
|
||||||
|
### 错误码
|
||||||
|
|
||||||
|
错误码是DeEarthX-CE用于分辨的码
|
||||||
|
|
||||||
|
错误码信息:[错误码](../api/error-codes.html)
|
||||||
|
|
||||||
|
如果下面解决不了你的问题,你可以看看上面的错误码
|
||||||
|
|
||||||
### DeEarthX-CE 是什么?
|
### DeEarthX-CE 是什么?
|
||||||
|
|
||||||
DeEarthX-CE 是一个功能强大的 Minecraft 模组管理工具,旨在简化模组的安装、更新和管理流程。它支持多个模组平台,提供智能的模组过滤功能,并允许用户创建和管理模组包模板。
|
DeEarthX-CE 是一个功能强大的 Minecraft 模组管理工具,旨在简化模组的安装、更新和管理流程。它支持多个模组平台,提供智能的模组过滤功能,并允许用户创建和管理模组包模板。
|
||||||
@@ -94,4 +102,13 @@ DeEarthX-CE 支持 Windows 10/11、macOS 10.15+ 和 Linux (Ubuntu 20.04+) 操作
|
|||||||
|
|
||||||
- 查看应用日志获取详细错误信息
|
- 查看应用日志获取详细错误信息
|
||||||
- 访问 GitHub Issues 页面提交问题
|
- 访问 GitHub Issues 页面提交问题
|
||||||
- 加入社区 Discord 服务器寻求帮助
|
|
||||||
|
## 其它
|
||||||
|
|
||||||
|
如果解决不了,请向QQ群反馈,你需要反馈(CE或者主版本群都可以):
|
||||||
|
```
|
||||||
|
你好,我有XXX问题,错误码XXX
|
||||||
|
我的安装路径是XXX
|
||||||
|
环境是WindowsXXX,Java版本XXX
|
||||||
|
程序是XXX版本(CE或者主版本)
|
||||||
|
```
|
||||||
@@ -77,6 +77,5 @@
|
|||||||
|
|
||||||
### 权限错误
|
### 权限错误
|
||||||
|
|
||||||
- 确保应用有足够的权限访问 Minecraft 目录
|
|
||||||
- 在 Windows 上尝试以管理员身份运行
|
- 在 Windows 上尝试以管理员身份运行
|
||||||
- 在 macOS 上检查应用权限设置
|
- 在 macOS 上检查应用权限设置
|
||||||
Reference in New Issue
Block a user