feat: Enhance installation script and download functionality
- Add support for a force installation mode in the install script, allowing users to overwrite existing configurations and databases. - Improve database setup logic to ensure existing users and databases are only dropped during a force installation. - Introduce a new API endpoint to list available download files, enhancing the user experience on the download page by only displaying existing files. - Update HTML templates to reflect the availability of download files dynamically.
This commit is contained in:
@@ -32,6 +32,24 @@ pub struct ClientBuild {
|
||||
pub status: String,
|
||||
}
|
||||
|
||||
/// 列出 downloads 目录下可用的文件名(供下载页仅对存在的文件显示「下载」)
|
||||
pub async fn list_download_files() -> Json<Vec<String>> {
|
||||
let downloads_dir = std::env::var("DOWNLOADS_DIR").unwrap_or_else(|_| "./downloads".to_string());
|
||||
let mut names = Vec::new();
|
||||
if let Ok(mut rd) = tokio::fs::read_dir(&downloads_dir).await {
|
||||
while let Ok(Some(entry)) = rd.next_entry().await {
|
||||
if let Ok(meta) = entry.metadata().await {
|
||||
if meta.is_file() {
|
||||
if let Ok(name) = entry.file_name().into_string() {
|
||||
names.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Json(names)
|
||||
}
|
||||
|
||||
pub async fn get_client_config(State(state): State<Arc<AppState>>) -> Json<ClientConfig> {
|
||||
let config = state.server_config.read().unwrap();
|
||||
|
||||
@@ -103,8 +121,8 @@ pub async fn download_page(State(state): State<Arc<AppState>>) -> Html<String> {
|
||||
<div class="text-5xl mb-4">🪟</div>
|
||||
<h3 class="text-xl font-semibold mb-2">Windows</h3>
|
||||
<p class="text-gray-500 text-sm mb-4">Windows 10/11</p>
|
||||
<a href="{server_url}/api/v1/download/FunMC-{version}-windows-x64.exe"
|
||||
class="inline-block w-full py-3 px-4 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors font-medium">
|
||||
<a href="{server_url}/api/v1/download/FunMC-{version}-windows-x64.exe" data-download-file="FunMC-{version}-windows-x64.exe"
|
||||
class="dl-link inline-block w-full py-3 px-4 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors font-medium">
|
||||
下载 .exe
|
||||
</a>
|
||||
</div>
|
||||
@@ -117,12 +135,12 @@ pub async fn download_page(State(state): State<Arc<AppState>>) -> Html<String> {
|
||||
<h3 class="text-xl font-semibold mb-2">macOS</h3>
|
||||
<p class="text-gray-500 text-sm mb-4">macOS 11+</p>
|
||||
<div class="space-y-2">
|
||||
<a href="{server_url}/api/v1/download/FunMC-{version}-macos-arm64.dmg"
|
||||
class="inline-block w-full py-3 px-4 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors font-medium">
|
||||
<a href="{server_url}/api/v1/download/FunMC-{version}-macos-arm64.dmg" data-download-file="FunMC-{version}-macos-arm64.dmg"
|
||||
class="dl-link inline-block w-full py-3 px-4 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors font-medium">
|
||||
Apple Silicon
|
||||
</a>
|
||||
<a href="{server_url}/api/v1/download/FunMC-{version}-macos-x64.dmg"
|
||||
class="inline-block w-full py-2 px-4 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors text-sm">
|
||||
<a href="{server_url}/api/v1/download/FunMC-{version}-macos-x64.dmg" data-download-file="FunMC-{version}-macos-x64.dmg"
|
||||
class="dl-link inline-block w-full py-2 px-4 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors text-sm">
|
||||
Intel Mac
|
||||
</a>
|
||||
</div>
|
||||
@@ -135,8 +153,8 @@ pub async fn download_page(State(state): State<Arc<AppState>>) -> Html<String> {
|
||||
<div class="text-5xl mb-4">🐧</div>
|
||||
<h3 class="text-xl font-semibold mb-2">Linux</h3>
|
||||
<p class="text-gray-500 text-sm mb-4">Ubuntu/Debian/Fedora</p>
|
||||
<a href="{server_url}/api/v1/download/FunMC-{version}-linux-x64.AppImage"
|
||||
class="inline-block w-full py-3 px-4 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors font-medium">
|
||||
<a href="{server_url}/api/v1/download/FunMC-{version}-linux-x64.AppImage" data-download-file="FunMC-{version}-linux-x64.AppImage"
|
||||
class="dl-link inline-block w-full py-3 px-4 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors font-medium">
|
||||
下载 AppImage
|
||||
</a>
|
||||
</div>
|
||||
@@ -151,8 +169,8 @@ pub async fn download_page(State(state): State<Arc<AppState>>) -> Html<String> {
|
||||
<div class="text-center">
|
||||
<div class="text-4xl mb-3">🤖</div>
|
||||
<h4 class="font-semibold mb-2">Android</h4>
|
||||
<a href="{server_url}/api/v1/download/FunMC-{version}-android.apk"
|
||||
class="inline-block w-full py-2 px-4 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors">
|
||||
<a href="{server_url}/api/v1/download/FunMC-{version}-android.apk" data-download-file="FunMC-{version}-android.apk"
|
||||
class="dl-link inline-block w-full py-2 px-4 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors">
|
||||
下载 APK
|
||||
</a>
|
||||
</div>
|
||||
@@ -186,6 +204,20 @@ pub async fn download_page(State(state): State<Arc<AppState>>) -> Html<String> {
|
||||
魔幻方开发 · FunMC
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function(){{
|
||||
var apiBase = window.location.origin + '/api/v1';
|
||||
fetch(apiBase + '/download/list').then(function(r){{ return r.json(); }}).then(function(list){{
|
||||
var set = new Set(list || []);
|
||||
document.querySelectorAll('a.dl-link[data-download-file]').forEach(function(a){{
|
||||
var name = a.getAttribute('data-download-file');
|
||||
if (!set.has(name)) {{
|
||||
a.outerHTML = '<span class="inline-block w-full py-3 px-4 bg-gray-300 text-gray-500 rounded-lg cursor-not-allowed">暂无</span>';
|
||||
}}
|
||||
}});
|
||||
}}).catch(function(){{}});
|
||||
}})();
|
||||
</script>
|
||||
</body>
|
||||
</html>"##,
|
||||
server_name = config.server_name,
|
||||
|
||||
Reference in New Issue
Block a user