Compare commits

...

10 Commits

11 changed files with 87 additions and 13 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# Portal Development Environment
VITE_APP_TITLE=Momentry Portal (Development)
VITE_API_BASE_URL=http://127.0.0.1:3002
VITE_API_BASE_URL=http://192.168.110.201:3002
VITE_API_KEY=muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69
-2
View File
@@ -6,8 +6,6 @@ dist/
src-tauri/target/
src-tauri/gen/schemas/
# Tauri icons (generated)
src-tauri/icons/
# Environment
.env
+16
View File
@@ -1,5 +1,9 @@
# Momentry Portal — AGENTS.md
## 其他專案(M4mini
- **markbase** — M4mini 上正在開發的重要專案
## 開發指令
| 用途 | 指令 |
@@ -31,6 +35,18 @@
- API 設定存於 `localStorage('portal_config')`
- 401 回應會自動清除登入狀態並跳回 `/login`
## 跨機器推送與測試(M4mini → M5Max128
Gitea 伺服器在 `m5max128.local:3000`admin / `AccusysTest!`)。開發在 M4mini 進行,測試在 M5Max128
```bash
# 一鍵推送 + 部署 + 建置
./deploy.sh [commit message]
# 或手動
git commit -am "..." && git push
ssh accusys@m5max128.local "cd ~/momentry_portal && git pull && npm run build"
```
## 注意事項
- `tsconfig.json` 啟用 `strict` + `noUnusedLocals` + `noUnusedParameters` — 未使用的變數/參數會造成 `vue-tsc` 建置錯誤
Executable
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
REMOTE_USER="accusys"
REMOTE_HOST="m5max128.local"
REMOTE_DIR="~/momentry_portal"
if ! git diff --quiet --cached; then
echo ":: Unstaged changes detected. Stage or stash them first."
echo " git add -A && git stash"
exit 1
fi
if [ -n "$(git status --porcelain)" ]; then
echo ":: Uncommitted changes found."
if [ $# -ge 1 ]; then
git add -A && git commit -m "$*"
else
git add -A && git commit -m "deploy: $(date '+%Y-%m-%d %H:%M')"
fi
fi
echo ":: Pushing to Gitea..."
git push
echo ":: Deploying to ${REMOTE_HOST}..."
ssh "${REMOTE_USER}@${REMOTE_HOST}" \
"export PATH=\"\$HOME/.local/bin:\$PATH\" && eval \"\$(fnm env --use-on-cd)\" && \
cd ${REMOTE_DIR} && \
git pull && \
npm run build"
echo ":: Done"
+1
View File
@@ -2,6 +2,7 @@
"name": "momentry-portal",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
Binary file not shown.

After

Width:  |  Height:  |  Size: 104 B

+2 -3
View File
@@ -1,6 +1,5 @@
use crate::config::get_config;
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Serialize, Deserialize)]
pub struct SearchRequest {
@@ -54,7 +53,7 @@ pub async fn search_videos(
mode: Some(search_mode.clone()),
};
let url = format!("{}/api/v1/search", config.api_base_url);
let url = format!("{}/api/v1/search/universal", config.api_base_url);
let response = client
.post(&url)
@@ -113,7 +112,7 @@ pub async fn search_chunks(query: String, uuid: Option<String>) -> Result<Search
let client = reqwest::Client::new();
// Backend expects uuid in the body, not query params
let url = format!("{}/api/v1/search", config.api_base_url);
let url = format!("{}/api/v1/search/universal", config.api_base_url);
let mut request_body = serde_json::json!({
"query": query,
+1 -1
View File
@@ -50,7 +50,7 @@ pub async fn translate_text(
println!("[Translate] Sending to llama.cpp server...");
let response = client
.post("http://127.0.0.1:8081/v1/chat/completions")
.post("http://127.0.0.1:8082/v1/chat/completions")
.header("Content-Type", "application/json")
.json(&payload)
.send()
-1
View File
@@ -127,7 +127,6 @@ function isTauri(): boolean {
function handleSessionExpired() {
console.warn("Session expired or connection error, redirecting to login...");
localStorage.removeItem('momentry_user');
localStorage.removeItem('portal_config');
localStorage.removeItem('momentry_api_key');
if (window.location.pathname !== '/login') {
window.location.href = '/login';
+23 -3
View File
@@ -115,9 +115,29 @@ const loadDetail = async () => {
detail.value = result
profile.value = result.profile || {}
videos.value = result.videos || []
} catch (error) {
console.error('Failed to load identity detail:', error)
alert('載入失敗: ' + error)
} catch {
// Fallback: some API servers crash on /api/v1/identity/:uuid
try {
const config = getCurrentConfig()
const result = await httpFetch<any>(`${config.api_base_url}/api/v1/identities?uuid=${identityId.value}&page_size=1`)
const identity = (result.identities || [])[0]
if (identity) {
detail.value = identity
const meta = identity.metadata || {}
profile.value = {
name: identity.name,
character_name: meta.tmdb_character,
aliases: meta.tmdb_aliases,
gender: meta.tmdb_gender === 1 ? 'Female' : meta.tmdb_gender === 2 ? 'Male' : undefined,
age: meta.tmdb_birthday ? `${new Date().getFullYear() - new Date(meta.tmdb_birthday).getFullYear()} yrs` : undefined,
}
videos.value = []
} else {
throw new Error('Identity not found')
}
} catch (fallbackError) {
console.error('Failed to load identity detail:', fallbackError)
}
} finally {
loading.value = false
}
+10 -2
View File
@@ -143,21 +143,27 @@ const customUrl = ref('')
const selectedUrl = ref('')
function initSelectedServer() {
// Reset api_key from env defaults to clear any stale key
localStorage.removeItem('portal_config')
const config = getCurrentConfig()
const currentUrl = config.api_base_url
const matched = serverPresets.find(s => s.url === currentUrl)
if (matched) {
selectedUrl.value = matched.url
showCustomUrl.value = false
saveConfig({ ...config, api_base_url: matched.url })
} else {
selectedUrl.value = currentUrl
customUrl.value = currentUrl
showCustomUrl.value = true
saveConfig({ ...config })
}
}
function selectServer(srv: ServerPreset) {
selectedUrl.value = srv.url
// Reset api_key from env to avoid using a stale key
localStorage.removeItem('portal_config')
const config = getCurrentConfig()
saveConfig({ ...config, api_base_url: srv.url })
}
@@ -178,6 +184,8 @@ function toggleCustom() {
function onCustomUrlInput() {
selectedUrl.value = customUrl.value
// Reset api_key from env
localStorage.removeItem('portal_config')
const config = getCurrentConfig()
saveConfig({ ...config, api_base_url: customUrl.value })
}
@@ -199,6 +207,7 @@ const handleLogin = async () => {
let apiUrl = selectedUrl.value
if (showCustomUrl.value && customUrl.value) {
apiUrl = customUrl.value
localStorage.removeItem('portal_config')
const config = getCurrentConfig()
saveConfig({ ...config, api_base_url: customUrl.value })
}
@@ -217,8 +226,7 @@ const handleLogin = async () => {
if (data.success) {
localStorage.setItem('momentry_user', JSON.stringify(data.user))
localStorage.setItem('momentry_api_key', data.api_key)
const config = getCurrentConfig()
saveConfig({ ...config, api_key: data.api_key })
// Keep the existing api_key from config/env (login response key may be a placeholder)
const redirect = (route.query.redirect as string) || '/home'
router.push(redirect)
} else {