--- inclusion: manual --- # OfferPie Chrome Extension 项目结构说明 ## 1️⃣ 项目整体层次 ``` offferpie_google_extension/ │ ├─ package.json # 依赖 + manifest 权限配置 ├─ tsconfig.json # TypeScript 配置(继承 Plasmo 模板) ├─ .prettierrc.cjs # 代码格式化配置 │ ├─ assets/ # 静态资源(图标等) │ ├─ icon.png │ └─ icon1.png │ └─ src/ # 源码主目录 ├─ config.ts # **环境配置**(多环境切换:dev/prod) ├─ constants.ts # **全局常量**(消息类型、存储 Key、缓存时间等) │ ├─ background/ # **Background Service Worker** │ └─ index.ts # 后台服务(监听图标点击、处理 Cookie 读取消息、安装事件) │ ├─ contents/ # **Content Scripts**(注入到目标网页的脚本) │ └─ sidebar.tsx # 侧边栏入口(Shadow DOM 样式隔离,监听消息控制显隐) │ ├─ components/ # **UI 组件** │ ├─ SidebarPanel.tsx # 侧边栏面板组件 │ └─ SidebarPanel.scss # 侧边栏样式 │ ├─ api/ # **接口层**(REST API 请求封装) │ ├─ request.ts # 通用请求方法(自动带 Token、统一错误处理、支持路径/query/body 参数) │ ├─ dataApi.ts # Java 后端接口(业务 CRUD) │ └─ aiApi.ts # Python AI 后端接口(AI 能力) │ ├─ utils/ # **工具层**(无业务依赖的通用工具) │ ├─ cookie.ts # Cookie 读取(通过消息中转 Background 获取) │ ├─ storage.ts # Chrome Storage 封装(chrome.storage.local 读写删) │ └─ auth.ts # 登录状态检查(带缓存,全局共享) │ └─ lib/ # **业务逻辑层**(具体业务功能实现) ├─ autofill.ts # 自动填表逻辑 ├─ dom.ts # DOM 操作工具 ├─ formMatcher.ts # 表单匹配器 ├─ pickerDetector.ts # 选择器检测 ├─ pickerFill.ts # 选择器填充 ├─ datePicker.ts # 日期选择器处理 ├─ resumeDataHelper.ts # 简历数据辅助 ├─ resumeUpload.ts # 简历上传 ├─ constants.ts # 业务常量 └─ types.ts # 业务类型定义 ``` ## 2️⃣ 各层模块职责 | 层级 | 主要职责 | 关键文件 | |------|----------|----------| | **config** | 环境配置管理,支持 dev/prod 切换 | `config.ts`(dataBaseApi、aiBaseApi、cookieSourceUrl) | | **constants** | 全局常量定义 | `constants.ts`(MSG_TYPES、STORAGE_KEYS、LOGIN_CHECK_INTERVAL) | | **background** | 后台事件处理:图标点击、Cookie 读取中转、安装事件 | `background/index.ts` | | **contents** | 注入目标网页的脚本,负责 UI 渲染和页面交互 | `contents/sidebar.tsx`(侧边栏面板注入) | | **components** | 可复用 React UI 组件 | `SidebarPanel.tsx` | | **api** | 接口请求封装,自动携带 Token,统一错误处理 | `request.ts`(通用封装)、`dataApi.ts`(Java 端)、`aiApi.ts`(Python 端) | | **utils** | 无业务依赖的通用工具 | `cookie.ts`(Cookie 获取)、`storage.ts`(持久化存储)、`auth.ts`(登录检查) | | **lib** | 具体业务功能实现(自动填表、DOM 操作、简历处理等) | `autofill.ts`、`formMatcher.ts`、`resumeUpload.ts` 等 | ## 3️⃣ 技术栈 | 类别 | 技术选型 | 说明 | |------|----------|------| | **扩展框架** | Plasmo 0.90 | Chrome MV3 扩展开发框架,约定式文件结构 | | **UI 框架** | React 19 | 组件化 UI 开发 | | **UI 组件库** | Arco Design (web-react) | 字节跳动 React 组件库 | | **语言** | TypeScript 5.8 | 类型安全 | | **样式** | SCSS | 组件样式,通过 Shadow DOM 隔离 | ## 4️⃣ Plasmo 框架约定 | 文件/目录 | 框架行为 | |-----------|----------| | `src/background/index.ts` | 自动注册为 Background Service Worker | | `src/contents/*.tsx` | 自动注册为 Content Script(带 UI,Shadow DOM 隔离) | | `src/contents/*.ts` | 自动注册为 Content Script(纯逻辑,无 UI) | | `popup.tsx`(未使用) | 点击图标弹出的小窗口 | | `options.tsx`(未使用) | 扩展设置页 | | `sidepanel.tsx`(未使用) | 浏览器侧边栏面板 | | `package.json → manifest` | 自动合并生成 manifest.json | ## 5️⃣ 通信架构 ``` Content Script(页面内) │ │ chrome.runtime.sendMessage │ ← GET_TOKEN / GET_COOKIES → ▼ Background Service Worker(后台) │ │ chrome.cookies.get / getAll ▼ Chrome Cookie Store(公司网站域名下的 Cookie) ``` - Content Script 不直接读 Cookie,统一通过 Background 中转 - Background 按需唤醒,处理完消息后自动休眠 - Token 从公司网站 Cookie 中获取,复用页面登录状态 ## 6️⃣ 鉴权机制 - **Token 来源**:通过 `chrome.cookies.get` 从公司网站域名(cookieSourceUrl)读取名为 `Token` 的 Cookie - **请求携带**:`api/request.ts` 每次请求前自动获取 Token,塞入请求头 `Token` 字段 - **登录检查**:`utils/auth.ts` 提供 `ensureLogin()` 方法,调用后端 `checkLogin` 接口验证 Token 有效性 - **缓存策略**:登录检查结果缓存到 `chrome.storage.local`,5 分钟内全局不重复请求;失败立即清缓存 ## 7️⃣ 与后端的关系 | 后端 | 基础地址 | 用途 | |------|----------|------| | **Java 端**(back-end) | `http://localhost:8080/api` | 业务 CRUD:用户、简历、岗位、投递等 | | **Python AI 端**(offerpie_python_ai) | `http://localhost:8000` | AI 能力:智能分析、简历解析、对话等 | - 两个后端共享同一套 Token 鉴权体系 - 插件通过读取公司网站 Cookie 复用登录状态,无需单独登录 ## 8️⃣ Manifest 权限 | 权限 | 用途 | |------|------| | `activeTab` | 访问当前活动标签页 | | `storage` | 使用 chrome.storage.local 持久化数据 | | `tabs` | 操作标签页(发送消息等) | | `cookies` | 读取公司网站域名下的 Cookie(获取 Token) | | `host_permissions: ` | Content Script 注入所有页面 + 跨域请求 | ## 9️⃣ 构建与运行 - **安装依赖**:`npm install` - **开发模式**:`npm run dev`(热更新,产物在 `build/chrome-mv3-dev`) - **生产构建**:`npm run build`(产物在 `build/chrome-mv3-prod`) - **打包发布**:`npm run package`(生成 zip) - **加载到 Chrome**:`chrome://extensions` → 开发者模式 → 加载已解压的扩展程序 → 选择 build 目录