Compare commits
10 Commits
0da7dd17af
...
e2e11ad659
| Author | SHA1 | Date | |
|---|---|---|---|
| e2e11ad659 | |||
| c8fdf572ce | |||
| e96e1842a8 | |||
| b8ac27f9bb | |||
| e5985e625d | |||
| e60ba995b9 | |||
| a6d74d60c7 | |||
| 517dfc9a79 | |||
| 20deca3135 | |||
| 61c7748d7e |
+1
-1
@@ -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
|
||||
|
||||
@@ -6,8 +6,6 @@ dist/
|
||||
src-tauri/target/
|
||||
src-tauri/gen/schemas/
|
||||
|
||||
# Tauri icons (generated)
|
||||
src-tauri/icons/
|
||||
|
||||
# Environment
|
||||
.env
|
||||
|
||||
@@ -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` 建置錯誤
|
||||
|
||||
@@ -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"
|
||||
@@ -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 |
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user