bindbox-game/.trae/documents/修复 Admin 前端构建 TypeScript 错误.md
邹方成 8141a47690
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
feat(称号系统): 新增称号管理功能与抽奖效果集成
- 新增系统称号模板与效果配置表及相关CRUD接口
- 实现用户称号分配与抽奖效果应用逻辑
- 优化抽奖接口支持用户ID参数以应用称号效果
- 新增称号管理前端页面与分配功能
- 修复Windows时区错误与JSON字段初始化问题
- 移除无用管理接口代码并更新文档说明
2025-11-16 11:37:40 +08:00

4.3 KiB
Raw Blame History

问题概览

  • 缺失模块:@/mock/temp/commentDetail 导致 TS2307src/components/business/comment-widget/index.vue:46
  • 事件类型不匹配:emit('search', ...) 未在 defineEmits 中声明载荷activity-search、player-search
  • 缺少类型声明:crypto-js/md5 导致 TS7016login
  • 返回类型不一致:登录接口不含 refreshToken 导致 TS2339login
  • 表格数据类型为 unknown[] 与组件期望 Record<string, any>[] 不匹配guild、banner、product

修复方案(不改接口协议,最小改动)

  • 缺失模块补齐:新增 web/admin/src/mock/temp/commentDetail.ts,导出 Comment 类型与 commentList: Ref<Comment[]>
    • 使 src/components/business/comment-widget/index.vue:46 的导入可解析。
  • 事件类型声明完善:在以下文件的 defineEmits 中为 search 声明载荷类型 Props['modelValue']
    • src/views/activity/manage/modules/activity-search.vue:93-101,148-151
    • src/views/player-manage/modules/player-search.vue:82-90,136-139
  • crypto-js/md5 提供类型:新增 web/admin/src/types/shims-crypto-js.d.ts 内容:declare module 'crypto-js/md5';
    • 保证 src/views/auth/login/index.vue:117 类型可解析。
  • 登录返回类型与使用一致化:修改登录页不解构 refreshToken,仅解构 token 并调用 userStore.setToken(token)
    • src/views/auth/login/index.vue:223-236;当前后端返回结构为 { token, is_super }(参考后端 internal/service/admin/login.go:22-25,62-63 与前端 src/api/auth.ts:8-14)。
  • 表格数据类型注解:在各视图的 apiFn 显式标注返回类型为 Promise<Api.Common.PaginatedResponse<...>>,使 useTable 能推导出 TRecord,从而 data 类型为记录数组:
    • Guild 列表:src/views/guild/manage/index.vue:137-173,返回 PaginatedResponse<{ id; name; owner_id; ... }>
    • Banner 列表:src/views/operations/banner/index.vue:77-98,返回 PaginatedResponse<BannerItem>src/api/banner.ts:3-10)。
    • Product 分类:src/views/product/categories/index.vue:80-102,返回 PaginatedResponse<{ id; name; parent_id; status }>
    • Product 列表:src/views/product/list/index.vue(同样模式)。
    • 若不方便标注,临时方案:在模板传参处显式断言 :data="data as Record<string, any>[]"(不推荐,先按注解方案处理)。

具体改动明细

  • 新增 src/mock/temp/commentDetail.ts
    • 导出 export interface Comment { id:number; author:string; content:string; timestamp:string; replies: Comment[] }
    • export const commentList = ref<Comment[]>([])(保持与组件 comments.value.push(...) 一致)。
  • 更新事件声明:
    • activity-search.vue defineEmits<Emits>() 中将 (e: 'search'): void 改为 (e: 'search', value: Props['modelValue']): void
    • player-search.vue 同步调整。
  • 新增类型声明文件:src/types/shims-crypto-js.d.ts 写入 declare module 'crypto-js/md5';
  • 登录页使用调整:
    • 改为 const { token } = await fetchLogin(...),并调用 userStore.setToken(token)
  • useTable 返回类型注解:在上述 4 个视图 apiFn 的返回 then 中显式声明返回值类型为 Api.Common.PaginatedResponse<...>

验证步骤

  • 安装依赖后(若需要):npm i --save-dev @types/crypto-js(可省略,因已加 shims
  • 执行 npm run buildexpect无 TS 错误;资源正常打包。
  • 运行本地:npm run dev,检查各页面:
    • 评论组件能正常发布与回复。
    • 搜索模块能正常触发,父组件收到带载荷的 search 事件。
    • 登录页能正常登录并存储 token
    • Guild、Banner、Product 列表渲染正常,分页操作无类型报错。

影响面与风险

  • 均为类型与前端视图层改动,不涉及后端接口或数据结构变更。
  • crypto-js 类型通过 shims 解决,不强依赖 @types 包。
  • useTable 类型注解只提升类型推导,不改变运行时行为。

后续优化建议

  • 统一在 api/* 层将后端分页响应封装为 Api.Common.PaginatedResponse<T>,视图层的 apiFn 直接返回该类型,减少重复 then 转换与类型注解。
  • 为常见搜索子组件抽取 Emits 模板,避免事件签名遗漏。