Repository navigation
fix: [Portal] Portal name and logo settings have not taken effect - #7832
Conversation
| <h4 class="truncate">{{name}}</h4> | ||
| </div> | ||
| <!-- 收起左侧 --> | ||
| <MkTooltip content="收起侧边栏"> |
There was a problem hiding this comment.
Review
1. 🐞 Potential runtime error (bug)
const meta: any = authStore.authProfile?.meta
return meta.portal_name || '智能体门户'authStore.authProfile?.meta only guards authProfile. If authProfile is undefined/null → meta is undefined → meta.portal_name throws TypeError: Cannot read properties of undefined.
Fix:
const portalName = computed(() => authStore.authProfile?.meta?.portal_name || '智能体门户')Also drop : any — use a proper type, e.g. { portal_name?: string }.
2. 🐞 Pinia destructuring breaks reactivity
const { auth: authStore } = useStore()Destructuring a store loses reactivity for reassigned references. If store.auth is ever replaced with a new object, authStore keeps pointing at the stale one, and both computeds silently stop updating.
Preferred:
const store = useStore()
// then use store.auth.authProfileor const { auth } = storeToRefs(store) if auth is state.
3. ⚠️ Unused import + wrong module path
import auth from '@/api/chat/auth.ts'authis never used → ESLintno-unused-varsfailure.- Importing with an explicit
.tsextension is non-standard in Vite/TS source (fine forallowImportingTsExtensions, but inconsistent here). Remove the import entirely if unused.
4. ⚠️ Naming
nameandlogoare very generic and risk collisions in<script setup>scope (andnameis a common conflict withwindow.name/ componentname). PreferportalName/portalLogo.
5. 💅 Formatting / lint
const logo=computed(()=>{
return authStore.authProfile?.logo
})- Missing spaces around
=and=>(Prettier). - Inconsistent indentation (4 spaces vs 2-space file style).
||'智能体门户'missing a space.- Prefer the expression body for
logo:computed(() => authStore.authProfile?.logo).
6. 🌐 i18n
'智能体门户' is hardcoded. If this project is localized, use the i18n t() key (check how the previous hardcoded string was handled — if it was also hardcoded, at least extract a constant).
7. 🔍 PortalIcon :icon="logo"
logomay beundefined; confirm the prop is optional andPortalIconhas a sensible default/fallback (emptysrccan render a broken-image).- Consider a fallback:
computed(() => authStore.authProfile?.logo ?? defaultLogo). - Also confirm the prop name is really
icon(notsrc/url) — passing an unknown prop silently produces an attribute on the root element.
8. 🧹 Minor
computedisn't imported in the shown diff — verifyunplugin-auto-importcovers it, otherwise addimport { computed } from 'vue'.- The two computeds can be merged, but separate is fine and arguably clearer.
- Consider moving the
authStore/portal metadata read into a dedicated composable (e.g.usePortalMeta()) — it's likely reused by the header/favicon/title logic elsewhere.
Suggested final version
import { storeToRefs } from 'pinia'
import { useStore } from '@/stores/chat/index'
const store = useStore()
const portalName = computed(
() => store.auth.authProfile?.meta?.portal_name || '智能体门户'
)
const portalLogo = computed(() => store.auth.authProfile?.logo)<PortalIcon :icon="portalLogo" />
<h4 class="truncate">{{ portalName }}</h4>| "meta": {"portal_name": portal.name}, | ||
| "logo": portal.logo or "./favicon.ico", | ||
| }, | ||
| **result, |
There was a problem hiding this comment.
Review of the Diff
Potential Issues
-
Inconsistent
metasemantics between branches- Branch 1 returns
"meta": {"portal_name": ""}, branch 2 returns"meta": {"portal_name": portal.name}. - If both branches serve the same endpoint (
profile()), clients must handleportal_namebeing either empty or populated. This is acceptable only if Branch 1 truly has no portal context (e.g., unauthenticated/default profile). Confirm that assumption.
- Branch 1 returns
-
portal.namemay beNoneor missing- If
nameis nullable, the API may return"portal_name": null(or raiseAttributeErrorifportalisNone). - Safer:
"portal_name": getattr(portal, "name", "") or "".
- If
-
Silent override by
**result"meta"is defined before**result. In Python, later keys win, so ifresultever contains a"meta"key it will silently replace the one set here. Verifyresultnever includesmeta, or movemetaafter**resultif you intend it to win.
-
Repeated DB call per request
get_key_pair_by_sql().get("key")is invoked on everyprofile()call (and possibly twice if both branches execute). Consider caching the key pair (e.g.,functools.lru_cacheor a short-TTL cache) since RSA keys rarely change.
-
Branch divergence / duplication
- The two config blocks differ in
login_value,default_value,meta, andlogo, but sharersa_key. This duplication invites drift (e.g., someone will update one and forget the other). Consider building a base dict and merging branch-specific overrides.
- The two config blocks differ in
-
Indentation in the second hunk looks slightly off
- The second hunk's
"login_value"etc. are indented less than the first branch's block. Verify both blocks are aligned within their parent dict; Python will still parse but it suggests the branches may be at different nesting levels — confirm they're both intended as sibling return values.
- The second hunk's
Optimization Suggestions
- Extract a helper/constant:
DEFAULT_META = {"portal_name": ""}andDEFAULT_LOGO = "./favicon.ico"to keep branches consistent. - Use
portal.name or ""(orgetattr) to guarantee a string type in the response schema. - Cache or memoize
get_key_pair_by_sql()result. - If
auth_configis fetched per-request, consider whetherlogin_valueanddefault_valueneed consistency validation (e.g.,typeshould be present inlogin_value), since an unexpectedtypecould produce an invalid default.
Minor
"meta": {"portal_name": ""}vs.None: empty string is fine, but document the contract so the frontend doesn't render a blank label unintentionally.
Overall the change is small and likely fine; the main risks are (a) inconsistent/absent portal_name, (b) portal.name nullability, and (c) the **result override order.
fix: [Portal] Portal name and logo settings have not taken effect