feat: Refactor service management scripts to use a unified dev script

- Added package.json to manage development scripts.
- Updated restart-services.ps1 to call the new dev script for starting services.
- Refactored start-admin.ps1, start-backend.ps1, start-frontend.ps1, and start-mcp.ps1 to utilize the dev script for starting respective services.
- Enhanced stop-services.ps1 to improve process termination logic by matching command patterns.
This commit is contained in:
2026-03-29 21:36:13 +08:00
parent 84f82c2a7e
commit 92a85eef20
137 changed files with 14181 additions and 2691 deletions

View File

@@ -57,10 +57,20 @@ fn is_blank(value: &Option<String>) -> bool {
}
fn matches_legacy_ai_defaults(settings: &site_settings::Model) -> bool {
settings.ai_provider.as_deref().map(str::trim) == Some("openai-compatible")
&& settings.ai_api_base.as_deref().map(str::trim) == Some("https://api.openai.com/v1")
&& settings.ai_chat_model.as_deref().map(str::trim) == Some("gpt-4.1-mini")
&& is_blank(&settings.ai_api_key)
let provider = settings.ai_provider.as_deref().map(str::trim);
let api_base = settings.ai_api_base.as_deref().map(str::trim);
let chat_model = settings.ai_chat_model.as_deref().map(str::trim);
(provider == Some("openai-compatible")
&& api_base == Some("https://api.openai.com/v1")
&& chat_model == Some("gpt-4.1-mini")
&& is_blank(&settings.ai_api_key))
|| (provider == Some("newapi")
&& matches!(
api_base,
Some("https://cliproxy.ai.init.cool") | Some("https://cliproxy.ai.init.cool/v1")
)
&& chat_model == Some("gpt-5.4"))
}
async fn sync_site_settings(ctx: &AppContext, base: &Path) -> Result<()> {
@@ -80,6 +90,27 @@ async fn sync_site_settings(ctx: &AppContext, base: &Path) -> Result<()> {
})
.filter(|items| !items.is_empty())
.map(|items| serde_json::json!(items));
let music_playlist = seed["music_playlist"]
.as_array()
.map(|items| {
items
.iter()
.filter_map(|item| {
let title = item["title"].as_str()?.trim();
let url = item["url"].as_str()?.trim();
if title.is_empty() || url.is_empty() {
None
} else {
Some(serde_json::json!({
"title": title,
"url": url,
}))
}
})
.collect::<Vec<_>>()
})
.filter(|items| !items.is_empty())
.map(serde_json::Value::Array);
let existing = site_settings::Entity::find()
.order_by_asc(site_settings::Column::Id)
@@ -138,9 +169,16 @@ async fn sync_site_settings(ctx: &AppContext, base: &Path) -> Result<()> {
if existing.tech_stack.is_none() {
model.tech_stack = Set(tech_stack);
}
if existing.music_playlist.is_none() {
model.music_playlist = Set(music_playlist);
}
if existing.ai_enabled.is_none() {
model.ai_enabled = Set(seed["ai_enabled"].as_bool());
}
if existing.paragraph_comments_enabled.is_none() {
model.paragraph_comments_enabled =
Set(seed["paragraph_comments_enabled"].as_bool().or(Some(true)));
}
if should_upgrade_legacy_ai_defaults {
model.ai_provider = Set(as_optional_string(&seed["ai_provider"]));
model.ai_api_base = Set(as_optional_string(&seed["ai_api_base"]));
@@ -194,7 +232,11 @@ async fn sync_site_settings(ctx: &AppContext, base: &Path) -> Result<()> {
social_email: Set(as_optional_string(&seed["social_email"])),
location: Set(as_optional_string(&seed["location"])),
tech_stack: Set(tech_stack),
music_playlist: Set(music_playlist),
ai_enabled: Set(seed["ai_enabled"].as_bool()),
paragraph_comments_enabled: Set(seed["paragraph_comments_enabled"]
.as_bool()
.or(Some(true))),
ai_provider: Set(as_optional_string(&seed["ai_provider"])),
ai_api_base: Set(as_optional_string(&seed["ai_api_base"])),
ai_api_key: Set(as_optional_string(&seed["ai_api_key"])),