diff --git a/cmd/ohos/HomeAgent/entry/src/main/ets/common/ConnStore.ets b/cmd/ohos/HomeAgent/entry/src/main/ets/common/ConnStore.ets index 8b0a299..49e62b4 100644 --- a/cmd/ohos/HomeAgent/entry/src/main/ets/common/ConnStore.ets +++ b/cmd/ohos/HomeAgent/entry/src/main/ets/common/ConnStore.ets @@ -1,7 +1,7 @@ import { preferences } from '@kit.ArkData'; import { Context } from '@kit.AbilityKit'; import { deviceInfo } from '@kit.BasicServicesKit'; -import { ConnectionConfig, AppSettings, emptySettings, defaultConnection } from '../model/Model'; +import { ConnectionConfig, AppSettings, emptySettings, defaultConnection, normalizeBaseUrl } from '../model/Model'; const PREF_NAME: string = 'homeagent_prefs'; const KEY_CONNECTIONS: string = 'connections_json'; @@ -31,6 +31,12 @@ export class ConnStore { } catch (e) { this.connections = []; } + // 存量数据可能是旧版本存进去的裸域名或带尾斜杠的地址,读出来时一并规范化, + // 否则老用户升级后仍然会拼出错误的请求地址。 + for (let i = 0; i < this.connections.length; i++) { + const c: ConnectionConfig = this.connections[i]; + c.url = normalizeBaseUrl(c.url); + } } const settingsJson: string = await this.prefs.get(KEY_SETTINGS, '') as string; if (settingsJson.length > 0) { @@ -42,18 +48,8 @@ export class ConnStore { } } - // 首次启动时预置默认连接(用户后端),避免所有页面空白 - async ensureDefaultConnection(): Promise { - await this.load(); - if (this.connections.length > 0) { - return; - } - const conn: ConnectionConfig = defaultConnection(); - conn.id = 'default'; - this.connections.push(conn); - this.settings.currentConnId = conn.id; - await this.save(); - } + // 不预置任何连接:地址与密钥属于用户私有配置,不能随源码分发。 + // 连接列表为空时各页面走"尚未配置后端连接"的统一提示,用户到设置页添加。 getConnections(): ConnectionConfig[] { return this.connections; @@ -82,7 +78,7 @@ export class ConnStore { const conn: ConnectionConfig = defaultConnection(); conn.id = Date.now().toString(36) + Math.floor(Math.random() * 10000).toString(36); conn.name = name; - conn.url = url; + conn.url = normalizeBaseUrl(url); conn.apiKey = apiKey; conn.type = 'webui'; this.connections.push(conn); @@ -99,7 +95,7 @@ export class ConnStore { const c: ConnectionConfig = this.connections[i]; if (c.id === id) { c.name = name; - c.url = url; + c.url = normalizeBaseUrl(url); c.apiKey = apiKey; break; } diff --git a/cmd/ohos/HomeAgent/entry/src/main/ets/entryability/EntryAbility.ets b/cmd/ohos/HomeAgent/entry/src/main/ets/entryability/EntryAbility.ets index bcc6163..7962c91 100644 --- a/cmd/ohos/HomeAgent/entry/src/main/ets/entryability/EntryAbility.ets +++ b/cmd/ohos/HomeAgent/entry/src/main/ets/entryability/EntryAbility.ets @@ -81,7 +81,6 @@ export default class EntryAbility extends UIAbility { windowStage.getMainWindow((err: BusinessError, win: window.Window) => { if (err.code !== 0) { connStore.init(this.context).then(async () => { - await connStore.ensureDefaultConnection(); const cur = connStore.getCurrentConnection(); if (cur !== null) { apiClient.setConnection(cur); @@ -100,7 +99,6 @@ export default class EntryAbility extends UIAbility { console.warn('[HomeAgent] setWindowLayoutFullScreen failed: ' + (e as Error).message); } connStore.init(this.context).then(async () => { - await connStore.ensureDefaultConnection(); const cur = connStore.getCurrentConnection(); if (cur !== null) { apiClient.setConnection(cur); diff --git a/cmd/ohos/HomeAgent/entry/src/main/ets/model/Model.ets b/cmd/ohos/HomeAgent/entry/src/main/ets/model/Model.ets index b291562..d12dad6 100644 --- a/cmd/ohos/HomeAgent/entry/src/main/ets/model/Model.ets +++ b/cmd/ohos/HomeAgent/entry/src/main/ets/model/Model.ets @@ -163,12 +163,45 @@ export function emptySettings(): AppSettings { return s; } +/** + * 规范化用户填写的后端地址。 + * + * 用户习惯直接敲域名(homeagent.example.xyz)或粘贴带路径的地址。 + * 三件事必须在存库前做掉,否则请求会以各种方式失败: + * + * 1) 补协议,且默认 https。 + * 很多反代把 http 整站 302 到别的主机(例如门户站 www.xxx), + * 重定向后的主机没有 API,客户端只会拿到 404 页面而不是 401/200, + * 表现为"连接直接失败"且看不出原因。默认 https 可以绕过整类问题。 + * 只有明确写了 http:// 的内网地址才走明文。 + * 2) 去掉结尾斜杠,避免拼出 //api/v1。 + * 3) 去掉用户误粘的 /api/v1 后缀,避免拼成 /api/v1/api/v1。 + */ +export function normalizeBaseUrl(raw: string): string { + let u: string = raw.trim(); + if (u.length === 0) { + return ''; + } + const lower: string = u.toLowerCase(); + if (!lower.startsWith('http://') && !lower.startsWith('https://')) { + u = 'https://' + u; + } + u = u.replace(/\/+$/, ''); + u = u.replace(/\/api\/v1$/, ''); + return u; +} + +/** + * 新建连接用的空白模板。 + * 这里不能写死任何地址或密钥:源码是公开的,硬编码等于把内网地址和访问凭据一起发布。 + * 地址与 API Key 由用户在「设置 - 连接」里填写,未配置时各页面统一提示(见 UserError.MSG_NO_CONN)。 + */ export function defaultConnection(): ConnectionConfig { const c: ConnectionConfig = { id: '', name: 'HomeAgent', - url: 'http://192.168.2.60:8080', - apiKey: 'jinrui233719', + url: '', + apiKey: '', type: 'webui', }; return c; diff --git a/cmd/ohos/HomeAgent/entry/src/main/ets/pages/SettingsPage.ets b/cmd/ohos/HomeAgent/entry/src/main/ets/pages/SettingsPage.ets index de3ad16..d2222dc 100644 --- a/cmd/ohos/HomeAgent/entry/src/main/ets/pages/SettingsPage.ets +++ b/cmd/ohos/HomeAgent/entry/src/main/ets/pages/SettingsPage.ets @@ -854,7 +854,7 @@ export struct SettingsPage { .onChange((v: string) => { this.editName = v; }) - TextInput({ placeholder: '地址 (如 http://192.168.1.100:8080)', text: this.editUrl }) + TextInput({ placeholder: '地址 (域名或 http://192.168.1.100:8080)', text: this.editUrl }) .height(36).fontSize(13).fontColor(this.palette().textPrimary) .placeholderColor(this.palette().textMuted).backgroundColor(this.palette().bgInput) .borderRadius(RADIUS_SM).border({ width: 1, color: this.palette().border })