Просмотр исходного кода

feat(V1.0.5.B): 完善Buff扫货功能和优化Steam绑定流程

- 新增Buff选品视图的数据展示和筛选功能
- 优化Steam绑定视图的用户交互体验
- 更新Tauri客户端API命令和配置管理
- 完善构建脚本和文档
- 修复编译输出文件的版本同步

Made-with: Cursor
wuzilong 6 месяцев назад
Родитель
Сommit
0bb539a216
36 измененных файлов с 162 добавлено и 45 удалено
  1. 1 1
      Untitled
  2. 3 3
      backend-client-bak/app/API日志记录功能使用指南.md
  3. 2 2
      backend-client-bak/start.ps1
  4. 2 2
      backend-client-bak/start.sh
  5. 3 3
      backend-client/app/API日志记录功能使用指南.md
  6. 2 2
      backend-client/start.sh
  7. 1 1
      backend-client/start_prod.sh
  8. 3 3
      client-tauri/BUILD-EXE-GUIDE.md
  9. 1 1
      client-tauri/BUILD-GUIDE.md
  10. 1 1
      client-tauri/build-devtools.ps1
  11. 1 1
      client-tauri/build-prod.ps1
  12. 1 1
      client-tauri/build-release.ps1
  13. 1 1
      client-tauri/default-config.json
  14. 2 2
      client-tauri/do-build.ps1
  15. 1 1
      client-tauri/src-tauri/src/api_client.rs
  16. 46 0
      client-tauri/src-tauri/src/commands.rs
  17. 1 1
      client-tauri/src-tauri/src/commands/api_client.rs
  18. 3 3
      client-tauri/src-tauri/src/config.rs
  19. 1 0
      client-tauri/src-tauri/src/main.rs
  20. 41 3
      client-tauri/src/views/BuffSelectionView.vue
  21. 3 3
      client-tauri/src/views/SettingsView.vue
  22. 39 7
      client-tauri/src/views/SteamBindView.vue
  23. 1 1
      client-tauri/standalone-build.ps1
  24. BIN
      steam-client/steamAPI/bin/Debug/net8.0/SteamAuth.dll
  25. BIN
      steam-client/steamAPI/bin/Debug/net8.0/SteamAuth.pdb
  26. BIN
      steam-client/steamAPI/bin/Debug/net8.0/steamAPI.dll
  27. BIN
      steam-client/steamAPI/bin/Debug/net8.0/steamAPI.exe
  28. BIN
      steam-client/steamAPI/bin/Debug/net8.0/steamAPI.pdb
  29. BIN
      steam-client/steamAPI/obj/Debug/net8.0/apphost.exe
  30. BIN
      steam-client/steamAPI/obj/Debug/net8.0/ref/steamAPI.dll
  31. BIN
      steam-client/steamAPI/obj/Debug/net8.0/refint/steamAPI.dll
  32. 1 1
      steam-client/steamAPI/obj/Debug/net8.0/steamAPI.AssemblyInfo.cs
  33. 1 1
      steam-client/steamAPI/obj/Debug/net8.0/steamAPI.AssemblyInfoInputs.cache
  34. BIN
      steam-client/steamAPI/obj/Debug/net8.0/steamAPI.csproj.AssemblyReference.cache
  35. BIN
      steam-client/steamAPI/obj/Debug/net8.0/steamAPI.dll
  36. BIN
      steam-client/steamAPI/obj/Debug/net8.0/steamAPI.pdb

+ 1 - 1
Untitled

@@ -1 +1 @@
-http://125.122.32.114:9000
+http://192.168.2.54:9000

+ 3 - 3
backend-client-bak/app/API日志记录功能使用指南.md

@@ -38,7 +38,7 @@ backend-client/
 ```json
 {
     "timestamp": "2026-02-02 18:30:45.123",  // 时间戳(精确到毫秒)
-    "endpoint": "http://125.122.32.114:9000/api/v1/auth/login",  // 接口路径
+    "endpoint": "http://192.168.2.54:9000/api/v1/auth/login",  // 接口路径
     "method": "POST",                         // HTTP方法
     "user_id": 1,                             // 用户ID(可为null)
     "client_ip": "192.168.1.100",             // 客户端IP
@@ -202,8 +202,8 @@ loguru_logger.add(
 控制台会同时输出简化的日志信息:
 
 ```
-[API请求] POST http://125.122.32.114:9000/api/v1/auth/login - 请求数据(密文): eyJ...
-[API响应] POST http://125.122.32.114:9000/api/v1/auth/login - 响应数据(密文): eyJ... - 执行时间: 105ms
+[API请求] POST http://192.168.2.54:9000/api/v1/auth/login - 请求数据(密文): eyJ...
+[API响应] POST http://192.168.2.54:9000/api/v1/auth/login - 响应数据(密文): eyJ... - 执行时间: 105ms
 ```
 
 ### 3. 文件日志

+ 2 - 2
backend-client-bak/start.ps1

@@ -69,8 +69,8 @@ if ($connection) {
 }
 
 Write-Host ""
-Write-Host "API地址: http://125.122.32.114:9000" -ForegroundColor $CYAN
-Write-Host "API文档: http://125.122.32.114:9000/docs" -ForegroundColor $CYAN
+Write-Host "API地址: http://192.168.2.54:9000" -ForegroundColor $CYAN
+Write-Host "API文档: http://192.168.2.54:9000/docs" -ForegroundColor $CYAN
 Write-Host ""
 Write-Host "按 Ctrl+C 停止服务" -ForegroundColor $YELLOW
 Write-Host ""

+ 2 - 2
backend-client-bak/start.sh

@@ -44,10 +44,10 @@ echo -e "${GREEN}启动模式:$MODE${NC}"
 
 if [ "$MODE" = "dev" ]; then
     echo -e "${GREEN}启动客户端开发服务器...${NC}"
-    echo -e "${YELLOW}API文档:http://125.122.32.114:9000/docs${NC}"
+    echo -e "${YELLOW}API文档:http://192.168.2.54:9000/docs${NC}"
     uvicorn app.main:app --reload --host 0.0.0.0 --port 9000
 else
     echo -e "${GREEN}启动客户端生产服务器...${NC}"
-    echo -e "${YELLOW}API文档:http://125.122.32.114:9000/docs${NC}"
+    echo -e "${YELLOW}API文档:http://192.168.2.54:9000/docs${NC}"
     uvicorn app.main:app --host 0.0.0.0 --port 9000 --workers 4
 fi

+ 3 - 3
backend-client/app/API日志记录功能使用指南.md

@@ -38,7 +38,7 @@ backend-client/
 ```json
 {
     "timestamp": "2026-02-02 18:30:45.123",  // 时间戳(精确到毫秒)
-    "endpoint": "http://125.122.32.114:9000/api/v1/auth/login",  // 接口路径
+    "endpoint": "http://192.168.2.54:9000/api/v1/auth/login",  // 接口路径
     "method": "POST",                         // HTTP方法
     "user_id": 1,                             // 用户ID(可为null)
     "client_ip": "192.168.1.100",             // 客户端IP
@@ -202,8 +202,8 @@ loguru_logger.add(
 控制台会同时输出简化的日志信息:
 
 ```
-[API请求] POST http://125.122.32.114:9000/api/v1/auth/login - 请求数据(密文): eyJ...
-[API响应] POST http://125.122.32.114:9000/api/v1/auth/login - 响应数据(密文): eyJ... - 执行时间: 105ms
+[API请求] POST http://192.168.2.54:9000/api/v1/auth/login - 请求数据(密文): eyJ...
+[API响应] POST http://192.168.2.54:9000/api/v1/auth/login - 响应数据(密文): eyJ... - 执行时间: 105ms
 ```
 
 ### 3. 文件日志

+ 2 - 2
backend-client/start.sh

@@ -44,10 +44,10 @@ echo -e "${GREEN}启动模式:$MODE${NC}"
 
 if [ "$MODE" = "dev" ]; then
     echo -e "${GREEN}启动客户端开发服务器...${NC}"
-    echo -e "${YELLOW}API文档:http://125.122.32.114:9000/docs${NC}"
+    echo -e "${YELLOW}API文档:http://192.168.2.54:9000/docs${NC}"
     uvicorn app.main:app --reload --host 0.0.0.0 --port 9000
 else
     echo -e "${GREEN}启动客户端生产服务器...${NC}"
-    echo -e "${YELLOW}API文档:http://125.122.32.114:9000/docs${NC}"
+    echo -e "${YELLOW}API文档:http://192.168.2.54:9000/docs${NC}"
     uvicorn app.main:app --host 0.0.0.0 --port 9000 --workers 4
 fi

+ 1 - 1
backend-client/start_prod.sh

@@ -67,5 +67,5 @@ if ! "$PYTHON_BIN" -c "import uvicorn" > /dev/null 2>&1; then
 fi
 
 printf '%b\n' "${GREEN}启动客户端生产服务器...${NC}"
-printf '%b\n' "${YELLOW}API 文档:http://125.122.32.114:9000/docs${NC}"
+printf '%b\n' "${YELLOW}API 文档:http://192.168.2.54:9000/docs${NC}"
 exec "$PYTHON_BIN" -m uvicorn app.main:app --host 0.0.0.0 --port 9000 --workers 4

+ 3 - 3
client-tauri/BUILD-EXE-GUIDE.md

@@ -78,7 +78,7 @@ $env:RUSTFLAGS = "-C target-feature=+crt-static"  # 静态链接 C 运行时库
 . (Join-Path $ProjectRoot "scripts\set-openssl-static-env.ps1")
 
 # 2. 设置 API 地址
-$env:DEFAULT_BACKEND_API_URL = "http://125.122.32.114:9000"
+$env:DEFAULT_BACKEND_API_URL = "http://192.168.2.54:9000"
 
 # 3. 安装前端依赖
 npm install --silent
@@ -96,7 +96,7 @@ $nsisFiles = Get-ChildItem -Path "src-tauri\target\release\bundle\nsis" -Filter
 ```powershell
 # 与 build-release 类似的配置,用于生产环境
 . (Join-Path $PSScriptRoot "scripts\set-openssl-static-env.ps1")
-$env:DEFAULT_BACKEND_API_URL = "http://125.122.32.114:9000"
+$env:DEFAULT_BACKEND_API_URL = "http://192.168.2.54:9000"
 npm run tauri build
 ```
 
@@ -138,7 +138,7 @@ cd client-tauri
 .\build-release.ps1
 
 # 方式三:设置 API 后构建
-$env:DEFAULT_BACKEND_API_URL="http://125.122.32.114:9000"
+$env:DEFAULT_BACKEND_API_URL="http://192.168.2.54:9000"
 npm run tauri:build
 ```
 

+ 1 - 1
client-tauri/BUILD-GUIDE.md

@@ -310,7 +310,7 @@ Set-Location $PSScriptRoot
 # 与 build-prod 一致:静态链接 OpenSSL
 . (Join-Path $PSScriptRoot "scripts\set-openssl-static-env.ps1")
 
-$env:DEFAULT_BACKEND_API_URL = "http://125.122.32.114:9000"
+$env:DEFAULT_BACKEND_API_URL = "http://192.168.2.54:9000"
 
 # 启用 devtools(右键菜单、检查按钮)
 $env:TAURI_DEVTOOLS = "1"

+ 1 - 1
client-tauri/build-devtools.ps1

@@ -54,7 +54,7 @@ Write-Host "OPENSSL_LIB_DIR: $env:OPENSSL_LIB_DIR"
 Write-Host "OPENSSL_STATIC: $env:OPENSSL_STATIC"
 Write-Host "========================================" -ForegroundColor Cyan
 
-$env:DEFAULT_BACKEND_API_URL = "http://125.122.32.114:9000"
+$env:DEFAULT_BACKEND_API_URL = "http://192.168.2.54:9000"
 $env:TAURI_DEVTOOLS = "1"
 
 Write-Host ""

+ 1 - 1
client-tauri/build-prod.ps1

@@ -5,7 +5,7 @@ Set-Location $PSScriptRoot
 # 与 build-release 一致:静态链接 OpenSSL,避免目标机缺少 libcrypto-3-x64.dll
 . (Join-Path $PSScriptRoot "scripts\set-openssl-static-env.ps1")
 
-$env:DEFAULT_BACKEND_API_URL = "http://125.122.32.114:9000"
+$env:DEFAULT_BACKEND_API_URL = "http://192.168.2.54:9000"
 Write-Host "开始打包,API 地址: $env:DEFAULT_BACKEND_API_URL"
 npm run tauri build
 Write-Host "打包完成"

+ 1 - 1
client-tauri/build-release.ps1

@@ -3,7 +3,7 @@
 $ErrorActionPreference = "Stop"
 
 $ProjectRoot = $PSScriptRoot
-$APIUrl = "http://125.122.32.114:9000"
+$APIUrl = "http://192.168.2.54:9000"
 
 # OpenSSL 静态链接(与 .cargo/config.toml +crt-static 一致)
 . (Join-Path $ProjectRoot "scripts\set-openssl-static-env.ps1")

+ 1 - 1
client-tauri/default-config.json

@@ -1,6 +1,6 @@
 {
   "api": {
-    "base_url": "http://125.122.32.114:9000",
+    "base_url": "http://192.168.2.54:9000",
     "timeout": 30,
     "software_code": "buff-xp-steam-sh"
   },

+ 2 - 2
client-tauri/do-build.ps1

@@ -2,7 +2,7 @@ $ErrorActionPreference = "Continue"
 [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
 Write-Host "========================================"
 Write-Host "开始打包 client-tauri"
-Write-Host "API 地址: http://125.122.32.114:9000"
+Write-Host "API 地址: http://192.168.2.54:9000"
 Write-Host "========================================"
 
 Set-Location $PSScriptRoot
@@ -15,7 +15,7 @@ try {
     exit 1
 }
 
-$env:DEFAULT_BACKEND_API_URL = "http://125.122.32.114:9000"
+$env:DEFAULT_BACKEND_API_URL = "http://192.168.2.54:9000"
 
 Write-Host "开始执行 npm run tauri build..."
 npm run tauri build

+ 1 - 1
client-tauri/src-tauri/src/api_client.rs

@@ -26,7 +26,7 @@ pub struct ApiConfig {
 impl Default for ApiConfig {
     fn default() -> Self {
         ApiConfig {
-            base_url: "http://125.122.32.114:9000".to_string(),
+            base_url: "http://192.168.2.54:9000".to_string(),
             timeout: 30,
             software_code: "buff-xp-steam-sh".to_string(),
         }

+ 46 - 0
client-tauri/src-tauri/src/commands.rs

@@ -424,6 +424,52 @@ pub async fn update_account_is_us_account(
     Ok(())
 }
 
+/// 更新账号的充值卡价比例
+#[tauri::command]
+pub async fn update_account_card_rate(
+    steamUsername: String,
+    cardRate: Option<f64>,
+) -> Result<(), String> {
+    let steam_msg_dir = get_steam_msg_dir()?;
+    let accounts_file = steam_msg_dir.join(ACCOUNTS_JSON);
+
+    if !accounts_file.exists() {
+        return Err("账号文件不存在".to_string());
+    }
+
+    let text = fs::read_to_string(&accounts_file).map_err(|e| format!("读取账号文件失败: {}", e))?;
+    let mut root: serde_json::Value =
+        serde_json::from_str(&text).unwrap_or(serde_json::json!({ "accounts": {} }));
+
+    let accounts = root
+        .get_mut("accounts")
+        .and_then(|a| a.as_object_mut())
+        .ok_or("账号数据结构异常")?;
+
+    let entry = accounts
+        .get_mut(&steamUsername)
+        .and_then(|v| v.as_object_mut())
+        .ok_or_else(|| format!("未找到账号 {}", steamUsername))?;
+
+    match cardRate {
+        Some(rate) => {
+            entry.insert(
+                "card_rate".to_string(),
+                serde_json::json!(rate),
+            );
+        }
+        None => {
+            entry.remove("card_rate");
+        }
+    }
+
+    let content =
+        serde_json::to_string_pretty(&root).map_err(|e| format!("序列化失败: {}", e))?;
+    fs::write(&accounts_file, content).map_err(|e| format!("写入账号文件失败: {}", e))?;
+
+    Ok(())
+}
+
 /// 将指定账号的 maFile 复制到用户选择的路径(下载 maFile)
 #[tauri::command]
 pub async fn export_mafile_to_path(steam_username: String, dest_path: String) -> Result<(), String> {

+ 1 - 1
client-tauri/src-tauri/src/commands/api_client.rs

@@ -62,7 +62,7 @@ pub struct SecureApiClient {
 impl Default for ApiClientConfig {
     fn default() -> Self {
         Self {
-            api_url: String::from("http://125.122.32.114:9000"),
+            api_url: String::from("http://192.168.2.54:9000"),
             timeout_seconds: 30,
             timestamp_tolerance_seconds: 300,  // 5分钟容忍范围
         }

+ 3 - 3
client-tauri/src-tauri/src/config.rs

@@ -1,7 +1,7 @@
 use serde::{Deserialize, Serialize};
 use std::fs;
 
-const FALLBACK_BACKEND_API_BASE_URL: &str = "http://125.122.32.114:9000";
+const FALLBACK_BACKEND_API_BASE_URL: &str = "http://192.168.2.54:9000";
 const FALLBACK_STEAM_API_BASE_URL: &str = "http://localhost:5000";
 
 fn normalize_base_url(raw: &str, fallback: &str) -> String {
@@ -77,9 +77,9 @@ impl AppConfig {
             {
                 // 保持 IP 地址形式,只更新端口
                 if config.api.base_url.starts_with("http://127.0.0.1") {
-                    config.api.base_url = "http://125.122.32.114:9000".to_string();
+                    config.api.base_url = "http://192.168.2.54:9000".to_string();
                 } else {
-                    config.api.base_url = "http://125.122.32.114:9000".to_string();
+                    config.api.base_url = "http://192.168.2.54:9000".to_string();
                 }
                 let _ = config.save();
             }

+ 1 - 0
client-tauri/src-tauri/src/main.rs

@@ -183,6 +183,7 @@ fn main() {
                 list_project_steam_accounts,
                 delete_project_steam_account,
                 update_account_is_us_account,
+                update_account_card_rate,
                 export_mafile_to_path,
                 get_steam_wallet_balance,
                 read_proxy_config,

+ 41 - 3
client-tauri/src/views/BuffSelectionView.vue

@@ -521,6 +521,18 @@
                   </span>
                 </span>
               </template>
+              <template v-else-if="column.key === 'cardRate'">
+                <a-input-number
+                  :value="record.cardRate"
+                  :min="0"
+                  :max="10"
+                  :precision="2"
+                  size="small"
+                  style="width: 60px;"
+                  placeholder="比例"
+                  @change="(val: number | null) => handleBoundSteamCardRateChange(record, val)"
+                />
+              </template>
               <template v-else-if="column.key === 'status'">
                 <a-tag v-if="isAutoRelogining(record.steam_username)" color="processing">
                   自动登录中
@@ -1191,12 +1203,14 @@ type BoundSteamApiAccount = {
 type BoundSteamLocalAccount = {
   steam_account?: string
   steamLoginSecure?: string
+  card_rate?: number | null
 }
 type BoundSteamRow = {
   id: number
   steam_username: string
   steam_id: string
   hasSteamLoginSecure: boolean
+  cardRate?: number | null
 }
 const boundSteamLoading = ref(false)
 const boundSteamAccounts = ref<BoundSteamRow[]>([])
@@ -1537,9 +1551,10 @@ const sweepColumns = [
   { title: '扫货时间', dataIndex: 'created_at', key: 'created_at', minWidth: 160, resizable: true }
 ]
 const boundSteamColumns = [
-  { title: 'Steam ID', dataIndex: 'steam_id', key: 'steam_id', width: 220 },
-  { title: 'Steam 账号', dataIndex: 'steam_username', key: 'steam_username', width: 180 },
+  { title: 'Steam ID', dataIndex: 'steam_id', key: 'steam_id', width: 150 },
+  { title: 'Steam 账号', dataIndex: 'steam_username', key: 'steam_username', width: 120 },
   { title: '余额', key: 'balance', width: 120 },
+  { title: '充值卡价比例', key: 'cardRate', width: 100 },
   { title: '状态', key: 'status', width: 120 },
   { title: '操作', key: 'action', width: 180 }
 ]
@@ -2088,6 +2103,22 @@ async function handleBoundSteamRelogin(record: BoundSteamRow) {
   }
 }
 
+async function handleBoundSteamCardRateChange(record: BoundSteamRow, rate: number | null) {
+  try {
+    await invoke('update_account_card_rate', {
+      steamUsername: record.steam_username,
+      cardRate: rate
+    })
+    const idx = boundSteamAccounts.value.findIndex(a => a.steam_username === record.steam_username)
+    if (idx !== -1) {
+      boundSteamAccounts.value[idx].cardRate = rate
+    }
+    message.success('充值卡价比例已保存')
+  } catch (err: any) {
+    message.error(err?.message || err?.toString() || '保存失败')
+  }
+}
+
 async function loadBoundSteamAccounts(autoRefreshBalances: boolean = true) {
   const userId = authStore.userId
   if (!userId) {
@@ -2111,13 +2142,20 @@ async function loadBoundSteamAccounts(autoRefreshBalances: boolean = true) {
         .filter((item) => item.steam_account && item.steamLoginSecure)
         .map((item) => String(item.steam_account))
     )
+    const localCardRateMap: Record<string, number | null> = {}
+    for (const item of localList) {
+      if (item.steam_account) {
+        localCardRateMap[item.steam_account] = item.card_rate ?? null
+      }
+    }
     const boundList = (apiRes.data || [])
       .filter((item) => !!item.steam_id && String(item.steam_id).trim() !== '')
       .map((item) => ({
         id: item.id,
         steam_username: item.steam_username,
         steam_id: String(item.steam_id),
-        hasSteamLoginSecure: localSecureSet.has(item.steam_username)
+        hasSteamLoginSecure: localSecureSet.has(item.steam_username),
+        cardRate: localCardRateMap[item.steam_username] ?? null
       }))
     boundSteamAccounts.value = boundList
     // 初始化账号选择状态(默认全选)

+ 3 - 3
client-tauri/src/views/SettingsView.vue

@@ -20,7 +20,7 @@
             placeholder="请输入API服务器地址"
             :disabled="saving"
           />
-          <div class="form-hint">例如: http://125.122.32.114:9000</div>
+          <div class="form-hint">例如: http://192.168.2.54:9000</div>
         </div>
 
         <div class="form-group">
@@ -176,7 +176,7 @@ const updateTitle = ref('')
 
 // API设置
 const apiSettings = reactive({
-  baseUrl: 'http://125.122.32.114:9000',
+  baseUrl: 'http://192.168.2.54:9000',
   softwareCode: 'buff-xp-steam-sh',
   timeout: 30
 })
@@ -223,7 +223,7 @@ async function saveSettings() {
 
 // 重置设置
 function resetSettings() {
-  apiSettings.baseUrl = 'http://125.122.32.114:9000'
+  apiSettings.baseUrl = 'http://192.168.2.54:9000'
   apiSettings.softwareCode = 'buff-xp-steam-sh'
   apiSettings.timeout = 30
   securitySettings.autoRenewSession = true

+ 39 - 7
client-tauri/src/views/SteamBindView.vue

@@ -84,10 +84,11 @@
           <table class="account-table">
             <thead>
               <tr>
-                <th>Steam ID</th>
-                <th>Steam 账号</th>
+                <th style="width: 120px;">Steam ID</th>
+                <th style="width: 120px;">Steam 账号</th>
                 <th>Steam 密码</th>
                 <th>余额</th>
+                <th>充值卡价比例</th>
                 <th>是否美国账号</th>
                 <th>状态</th>
                 <th>操作</th>
@@ -99,6 +100,18 @@
                 <td>{{ account.steam_username }}</td>
                 <td>{{ account.passwordDisplay }}</td>
                 <td>{{ balanceDisplay(account) }}</td>
+                <td>
+                  <a-input-number
+                    :value="account.cardRate"
+                    :min="0"
+                    :max="10"
+                    :precision="2"
+                    size="small"
+                    style="width: 70px;"
+                    placeholder="比例"
+                    @change="(val: number | null) => handleCardRateChange(account, val)"
+                  />
+                </td>
                 <td>
                   <a-switch
                     :checked="account.isUsAccount"
@@ -226,6 +239,7 @@ interface DisplayAccount extends SteamAccount {
   hasLocalMaFile: boolean
   hasSteamLoginSecure: boolean
   isUsAccount: boolean
+  cardRate?: number | null
 }
 
 interface AccountLimit {
@@ -245,8 +259,8 @@ const downloadingId = ref<number | null>(null)
 const refreshingBalanceUsername = ref<string | null>(null)
 const reloginUsername = ref<string | null>(null)
 const steamAccounts = ref<SteamAccount[]>([])
-/** 本地账号:steam_username -> { steam_password, steam_guard_path, steamLoginSecure?, is_us_account? } */
-const localAccountsMap = ref<Record<string, { steam_password?: string; steam_guard_path?: string; steamLoginSecure?: string; is_us_account?: boolean }>>({})
+/** 本地账号:steam_username -> { steam_password, steam_guard_path, steamLoginSecure?, is_us_account?, card_rate? } */
+const localAccountsMap = ref<Record<string, { steam_password?: string; steam_guard_path?: string; steamLoginSecure?: string; is_us_account?: boolean; card_rate?: number | null }>>({})
 /** 余额缓存:steam_username -> { amount (美分), currency } */
 const balanceMap = ref<Record<string, { amount: string; currency: string }>>({})
 const accountLimit = reactive<AccountLimit>({
@@ -295,7 +309,8 @@ const displayAccounts = computed<DisplayAccount[]>(() => {
       isBound: !!(a.steam_id && String(a.steam_id).trim()),
       hasLocalMaFile,
       hasSteamLoginSecure,
-      isUsAccount: localInfo?.is_us_account ?? true
+      isUsAccount: localInfo?.is_us_account ?? true,
+      cardRate: localInfo?.card_rate ?? null
     }
   })
 })
@@ -326,6 +341,22 @@ async function handleToggleUsAccount(account: DisplayAccount, isUs: boolean) {
   }
 }
 
+/** 更新充值卡价比例 */
+async function handleCardRateChange(account: DisplayAccount, rate: number | null) {
+  try {
+    await invoke('update_account_card_rate', {
+      steamUsername: account.steam_username,
+      cardRate: rate
+    })
+    if (localAccountsMap.value[account.steam_username]) {
+      localAccountsMap.value[account.steam_username].card_rate = rate
+    }
+    message.success('充值卡价比例已保存')
+  } catch (err: any) {
+    message.error(err?.message || err?.toString() || '保存失败')
+  }
+}
+
 /** 刷新余额:通过本地 steamAPI 查询余额,统一使用 steamAPI 代理出口 */
 async function handleRefreshBalance(account: DisplayAccount) {
   if (!account.hasSteamLoginSecure) {
@@ -426,11 +457,12 @@ async function loadSteamAccounts() {
       steam_guard_path?: string
       steamLoginSecure?: string
       is_us_account?: boolean
+      card_rate?: number | null
     }>
-    const map: Record<string, { steam_password?: string; steam_guard_path?: string; steamLoginSecure?: string; is_us_account?: boolean }> = {}
+    const map: Record<string, { steam_password?: string; steam_guard_path?: string; steamLoginSecure?: string; is_us_account?: boolean; card_rate?: number | null }> = {}
     for (const item of localList) {
       const name = item.steam_account
-      if (name) map[name] = { steam_password: item.steam_password, steam_guard_path: item.steam_guard_path, steamLoginSecure: item.steamLoginSecure, is_us_account: item.is_us_account }
+      if (name) map[name] = { steam_password: item.steam_password, steam_guard_path: item.steam_guard_path, steamLoginSecure: item.steamLoginSecure, is_us_account: item.is_us_account, card_rate: item.card_rate }
     }
     localAccountsMap.value = map
   } catch (err: any) {

+ 1 - 1
client-tauri/standalone-build.ps1

@@ -9,7 +9,7 @@ Write-Host "========================================" -ForegroundColor Cyan
 Write-Host "`n[1/4] Setting OpenSSL static build environment..." -ForegroundColor Yellow
 . (Join-Path $PSScriptRoot "scripts\set-openssl-static-env.ps1")
 
-$env:DEFAULT_BACKEND_API_URL = "http://125.122.32.114:9000"
+$env:DEFAULT_BACKEND_API_URL = "http://192.168.2.54:9000"
 Write-Host "API URL: $env:DEFAULT_BACKEND_API_URL" -ForegroundColor Cyan
 
 $env:RUSTFLAGS = "-C target-feature=+crt-static"

BIN
steam-client/steamAPI/bin/Debug/net8.0/SteamAuth.dll


BIN
steam-client/steamAPI/bin/Debug/net8.0/SteamAuth.pdb


BIN
steam-client/steamAPI/bin/Debug/net8.0/steamAPI.dll


BIN
steam-client/steamAPI/bin/Debug/net8.0/steamAPI.exe


BIN
steam-client/steamAPI/bin/Debug/net8.0/steamAPI.pdb


BIN
steam-client/steamAPI/obj/Debug/net8.0/apphost.exe


BIN
steam-client/steamAPI/obj/Debug/net8.0/ref/steamAPI.dll


BIN
steam-client/steamAPI/obj/Debug/net8.0/refint/steamAPI.dll


+ 1 - 1
steam-client/steamAPI/obj/Debug/net8.0/steamAPI.AssemblyInfo.cs

@@ -14,7 +14,7 @@ using System.Reflection;
 [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
 [assembly: System.Reflection.AssemblyDescriptionAttribute("Steam login verification local service")]
 [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
-[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+bd07a19572f7266474c6123926b9261b543c0eed")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1c4c8fe5a0532c35669acf21160663a5e7aebd97")]
 [assembly: System.Reflection.AssemblyProductAttribute("steamAPI")]
 [assembly: System.Reflection.AssemblyTitleAttribute("steamAPI")]
 [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

+ 1 - 1
steam-client/steamAPI/obj/Debug/net8.0/steamAPI.AssemblyInfoInputs.cache

@@ -1 +1 @@
-92389b5c8e3efae4b2a634acf0e2b519d7a3eaabf4a03d5354cb6137883886d5
+af6d7129d986a6dbf2f156abd62a5f9159cd783574345eb2c02cc14495fe1a90

BIN
steam-client/steamAPI/obj/Debug/net8.0/steamAPI.csproj.AssemblyReference.cache


BIN
steam-client/steamAPI/obj/Debug/net8.0/steamAPI.dll


BIN
steam-client/steamAPI/obj/Debug/net8.0/steamAPI.pdb