fix: avatar list fixes — full-width table, absolute photo URLs, global token balance
- Table width set to 100% - Photo URLs resolved to absolute paths using AVATAR_BACKEND_URL - Token balance now reads from global token_account table - Config: added AVATAR_BACKEND_URL setting
This commit is contained in:
@@ -28,6 +28,9 @@ class Settings(BaseSettings):
|
|||||||
# 数字分身 SQLite 数据库路径(直连数字分身应用的 SQLite)
|
# 数字分身 SQLite 数据库路径(直连数字分身应用的 SQLite)
|
||||||
AVATAR_DB_PATH: str = os.getenv("AVATAR_DB_PATH", "")
|
AVATAR_DB_PATH: str = os.getenv("AVATAR_DB_PATH", "")
|
||||||
|
|
||||||
|
# 数字分身后端服务地址(用于拼接头像等文件 URL)
|
||||||
|
AVATAR_BACKEND_URL: str = os.getenv("AVATAR_BACKEND_URL", "")
|
||||||
|
|
||||||
# 日志目录
|
# 日志目录
|
||||||
LOG_DIR: str = "/app/logs"
|
LOG_DIR: str = "/app/logs"
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,28 @@ def is_available() -> bool:
|
|||||||
return engine is not None
|
return engine is not None
|
||||||
|
|
||||||
|
|
||||||
|
def _resolve_photo_url(photo_url: str) -> str:
|
||||||
|
"""将相对路径的头像 URL 补全为绝对路径"""
|
||||||
|
if not photo_url:
|
||||||
|
return ""
|
||||||
|
if photo_url.startswith(("http://", "https://")):
|
||||||
|
return photo_url
|
||||||
|
base = settings.AVATAR_BACKEND_URL
|
||||||
|
if base:
|
||||||
|
base = base.rstrip("/")
|
||||||
|
return f"{base}{photo_url}"
|
||||||
|
return photo_url
|
||||||
|
|
||||||
|
|
||||||
|
def _get_global_token_balance(db: Session) -> int:
|
||||||
|
"""获取全局 token_account 余额(单行表)"""
|
||||||
|
try:
|
||||||
|
result = db.execute(text("SELECT balance FROM token_account LIMIT 1")).fetchone()
|
||||||
|
return result.balance if result and result.balance else 0
|
||||||
|
except Exception:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
class AvatarService:
|
class AvatarService:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -97,6 +119,7 @@ class AvatarService:
|
|||||||
rows = db.execute(query, params).fetchall()
|
rows = db.execute(query, params).fetchall()
|
||||||
|
|
||||||
items = []
|
items = []
|
||||||
|
global_token = _get_global_token_balance(db)
|
||||||
for row in rows:
|
for row in rows:
|
||||||
config = {}
|
config = {}
|
||||||
if row.config:
|
if row.config:
|
||||||
@@ -113,10 +136,10 @@ class AvatarService:
|
|||||||
"name": row.name,
|
"name": row.name,
|
||||||
"display_name": row.display_name,
|
"display_name": row.display_name,
|
||||||
"description": row.description or "",
|
"description": row.description or "",
|
||||||
"photo_url": row.photo_url or "",
|
"photo_url": _resolve_photo_url(row.photo_url),
|
||||||
"emoji": row.emoji or "🤖",
|
"emoji": row.emoji or "🤖",
|
||||||
"status": row.status or "active",
|
"status": row.status or "active",
|
||||||
"token_balance": row.token_balance or 0,
|
"token_balance": global_token or (row.token_balance or 0),
|
||||||
"config": config,
|
"config": config,
|
||||||
"owner_nickname": row.owner_nickname or "",
|
"owner_nickname": row.owner_nickname or "",
|
||||||
"owner_phone": row.owner_phone or "",
|
"owner_phone": row.owner_phone or "",
|
||||||
@@ -155,15 +178,16 @@ class AvatarService:
|
|||||||
elif isinstance(row.config, dict):
|
elif isinstance(row.config, dict):
|
||||||
config = row.config
|
config = row.config
|
||||||
|
|
||||||
|
global_token = _get_global_token_balance(db)
|
||||||
return {
|
return {
|
||||||
"id": row.id,
|
"id": row.id,
|
||||||
"name": row.name,
|
"name": row.name,
|
||||||
"display_name": row.display_name,
|
"display_name": row.display_name,
|
||||||
"description": row.description or "",
|
"description": row.description or "",
|
||||||
"photo_url": row.photo_url or "",
|
"photo_url": _resolve_photo_url(row.photo_url),
|
||||||
"emoji": row.emoji or "🤖",
|
"emoji": row.emoji or "🤖",
|
||||||
"status": row.status or "active",
|
"status": row.status or "active",
|
||||||
"token_balance": row.token_balance or 0,
|
"token_balance": global_token or (row.token_balance or 0),
|
||||||
"config": config,
|
"config": config,
|
||||||
"owner_nickname": row.owner_nickname or "",
|
"owner_nickname": row.owner_nickname or "",
|
||||||
"owner_phone": row.owner_phone or "",
|
"owner_phone": row.owner_phone or "",
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ onUnmounted(() => window.removeEventListener('page-refresh', loadAvatars))
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.filter-bar { display: flex; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
|
.filter-bar { display: flex; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
|
||||||
.data-table { border-radius: 8px; overflow: hidden; }
|
.data-table { border-radius: 8px; overflow: hidden; width: 100%; }
|
||||||
|
|
||||||
/* Detail panel */
|
/* Detail panel */
|
||||||
.detail-header { display: flex; align-items: center; }
|
.detail-header { display: flex; align-items: center; }
|
||||||
|
|||||||
Reference in New Issue
Block a user