## 问题概览
- 缺失模块：`@/mock/temp/commentDetail` 导致 TS2307（src/components/business/comment-widget/index.vue:46）。
- 事件类型不匹配：`emit('search', ...)` 未在 `defineEmits` 中声明载荷（activity-search、player-search）。
- 缺少类型声明：`crypto-js/md5` 导致 TS7016（login）。
- 返回类型不一致：登录接口不含 `refreshToken` 导致 TS2339（login）。
- 表格数据类型为 `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 build`，expect：无 TS 错误；资源正常打包。
- 运行本地：`npm run dev`，检查各页面：
  - 评论组件能正常发布与回复。
  - 搜索模块能正常触发，父组件收到带载荷的 `search` 事件。
  - 登录页能正常登录并存储 `token`。
  - Guild、Banner、Product 列表渲染正常，分页操作无类型报错。

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

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