# 自动找工作系统 - 功能实施总结 **更新时间**: 2025-12-27 --- ## 已完成功能概览 本文档总结了最近完成的两个主要功能模块: 1. **价格套餐管理系统** 2. **AI调用记录与Token追踪系统** --- ## 一、价格套餐管理系统 ### 功能描述 将原本硬编码在 `api/controller_front/config.js` 中的价格套餐数据迁移到数据库,并提供完整的后台管理界面。 ### 实施文件清单 #### 数据库层 - ✅ `_sql/create_pricing_plans_table.sql` - 数据表创建脚本 - ✅ `_sql/insert_pricing_plans_data.sql` - 初始数据插入脚本 - ✅ `api/model/pricing_plans.js` - Sequelize 数据模型 #### 后端API层 - ✅ `api/controller_admin/pricing_plans.js` - 后台管理API(5个端点) - `POST /pricing_plans/list` - 分页查询 - `GET /pricing_plans/detail` - 获取详情 - `POST /pricing_plans/create` - 创建套餐 - `POST /pricing_plans/update` - 更新套餐 - `POST /pricing_plans/delete` - 删除套餐(软删除) - ✅ `api/controller_front/config.js` (修改第90-136行) - 前端API改为数据库查询 #### 前端层 - ✅ `admin/src/api/system/pricing_plans_server.js` - API服务层 - ✅ `admin/src/views/system/pricing_plans.vue` - 管理界面组件 - ✅ `admin/src/router/component-map.js` (新增映射) - 组件注册 ### 数据库表结构 ```sql CREATE TABLE `pricing_plans` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(100) NOT NULL COMMENT '套餐名称', `duration` VARCHAR(50) NOT NULL COMMENT '时长描述', `days` INT(11) NOT NULL COMMENT '天数(-1表示永久)', `price` DECIMAL(10,2) NOT NULL COMMENT '价格', `original_price` DECIMAL(10,2) NULL COMMENT '原价', `unit` VARCHAR(20) NOT NULL DEFAULT '元', `discount` VARCHAR(50) NULL COMMENT '折扣描述', `features` TEXT NOT NULL COMMENT '功能列表(JSON格式)', `featured` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否推荐', `is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否启用', `sort_order` INT(11) NOT NULL DEFAULT 0 COMMENT '排序顺序', `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `last_modify_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `is_delete` TINYINT(1) NOT NULL DEFAULT 0, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### 初始数据 系统预置了4个价格套餐: 1. **体验套餐** - 7天 - ¥28 2. **月度套餐** - 30天 - ¥99(推荐) 3. **季度套餐** - 90天 - ¥269 4. **终生套餐** - 永久 - ¥888 ### 菜单位置 **用户管理** → **价格套餐管理** ### 关键实现细节 #### 前端接口向后兼容 `GET /api/config/pricing-plans` 接口保持原有响应格式: ```javascript [ { "id": 1, "name": "体验套餐", "duration": "7天", "days": 7, "price": 28, "originalPrice": 28, "unit": "元", "features": ["7天使用权限", "全功能体验", "技术支持"], "featured": false } ] ``` #### 状态控制逻辑 - 前端API仅返回 `is_active = 1` 且 `is_delete = 0` 的套餐 - 按照 `sort_order` ASC, `id` ASC 排序 - Features字段从JSON字符串自动解析为数组 #### 表单组件修复 修复了单选按钮组件使用方式(重要): ```javascript // ❌ 错误写法 { title: '是否推荐', key: 'featured', type: 'radio', // 错误 options: [...] } // ✅ 正确写法 { title: '是否推荐', key: 'featured', com: 'Radio', // 正确 options: [ { value: 1, label: '推荐' }, { value: 0, label: '普通' } ] } ``` --- ## 二、AI调用记录与Token追踪系统 ### 功能描述 为所有AI调用添加自动记录功能,追踪Token使用量、调用成本、响应时间等关键指标,并提供后台管理和统计分析界面。 ### 实施文件清单 #### 数据库层 - ✅ `_sql/create_ai_call_records_table.sql` - 数据表创建脚本 - ✅ `api/model/ai_call_records.js` - Sequelize 数据模型 #### 服务层 - ✅ `api/services/ai_call_recorder.js` - AI调用记录服务 - ✅ `api/services/ai_service.js` - AI服务(集成Token记录) #### 后端API层 - ✅ `api/controller_admin/ai_call_records.js` - 后台管理API(5个端点) - `POST /ai_call_records/list` - 分页查询 - `GET /ai_call_records/detail` - 获取详情 - `GET /ai_call_records/stats` - 统计分析 - `POST /ai_call_records/delete` - 删除记录 - `POST /ai_call_records/batch_delete` - 批量删除 #### 前端层 - ✅ `admin/src/api/system/ai_call_records_server.js` - API服务层 - ✅ `admin/src/views/system/ai_call_records.vue` - 管理界面组件 - ✅ `admin/src/router/component-map.js` (新增映射) - 组件注册 ### 数据库表结构 ```sql CREATE TABLE `ai_call_records` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `user_id` INT(11) NULL COMMENT '用户ID', `sn_code` VARCHAR(100) NULL COMMENT '设备SN码', `service_type` VARCHAR(50) NOT NULL COMMENT '服务类型:chat/completion/embedding', `model_name` VARCHAR(100) NOT NULL COMMENT '模型名称', `prompt_tokens` INT(11) NOT NULL DEFAULT 0 COMMENT '输入Token数', `completion_tokens` INT(11) NOT NULL DEFAULT 0 COMMENT '输出Token数', `total_tokens` INT(11) NOT NULL DEFAULT 0 COMMENT '总Token数', `request_content` TEXT NULL COMMENT '请求内容', `response_content` TEXT NULL COMMENT '响应内容', `cost_amount` DECIMAL(10,4) NULL COMMENT '费用(元)', `status` VARCHAR(20) NOT NULL DEFAULT 'success' COMMENT '状态:success/failed', `error_message` TEXT NULL COMMENT '错误信息', `response_time` INT(11) NULL COMMENT '响应时间(毫秒)', `api_provider` VARCHAR(50) NULL DEFAULT 'qwen' COMMENT 'API提供商', `business_type` VARCHAR(50) NULL COMMENT '业务类型', `reference_id` VARCHAR(100) NULL COMMENT '关联业务ID', `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `last_modify_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `is_delete` TINYINT(1) NOT NULL DEFAULT 0, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### AI服务集成 #### 使用的AI服务 系统使用 **阿里云DashScope API (Qwen 2.5)**,而非DeepSeek。 **关键配置:** ```javascript // api/services/ai_service.js class aiService { constructor() { this.apiKey = config.ai?.apiKey || process.env.DASHSCOPE_API_KEY; this.apiUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions'; this.model = config.ai?.model || 'qwen-turbo'; this.maxRetries = 3; } } ``` #### 环境变量配置 在 `.env` 文件中配置: ```bash AI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxx AI_MODEL=qwen-turbo # 可选:qwen-turbo, qwen-plus, qwen-max, qwen-long ``` 详细配置说明见:[docs/ai_service_config.md](ai_service_config.md:1) #### Token记录集成 AI服务的 `callAPI()` 方法自动记录所有调用: ```javascript async callAPI(prompt, options = {}) { const startTime = Date.now(); // ... 调用API ... // 成功时自动记录Token使用量 this.recordAiCall({ user_id: options.user_id, sn_code: options.sn_code, service_type: options.service_type || 'completion', model_name: this.model, prompt_tokens: usage.prompt_tokens || 0, completion_tokens: usage.completion_tokens || 0, total_tokens: usage.total_tokens || 0, cost_amount: this.calculateCost(usage.total_tokens || 0), status: 'success', response_time: responseTime, api_provider: 'qwen', business_type: options.business_type, reference_id: options.reference_id }).catch(err => { console.warn('记录AI调用失败(不影响主流程):', err.message); }); } ``` #### 业务类型分类 系统中的AI调用按业务类型分类: | 业务类型 | 说明 | 调用方法 | |---------|------|---------| | `job_analysis` | 岗位分析 | `analyzeJob()` | | `chat_generation` | 聊天内容生成 | `generateChatContent()` | | `resume_analysis` | 简历分析 | `analyzeResume()` | | `interview_invitation` | 面试邀约 | `generateInterviewInvitation()` | | `outsourcing_detection` | 外包检测 | `identifyOutsourcingJob()` | #### 成本计算 基于Qwen模型定价: ```javascript calculateCost(totalTokens) { // qwen-turbo: ¥0.003/1000 tokens // qwen-plus: ¥0.004/1000 tokens // qwen-max: ¥0.12/1000 tokens const pricePerThousand = 0.003; return (totalTokens / 1000) * pricePerThousand; } ``` ### 管理界面功能 #### 筛选功能 - 按用户ID搜索 - 按设备SN码搜索 - 按业务类型筛选 - 按服务类型筛选 - 按状态筛选 - 按时间范围筛选 #### 统计功能 - 总调用次数 - Token总使用量(输入/输出/总计) - 总费用统计 - 平均响应时间 - 成功率统计 #### 操作功能 - 查看详情(完整请求/响应内容) - 单条删除 - 批量删除 ### 菜单位置 **系统设置** → **AI调用记录** --- ## 三、关键技术点总结 ### 1. 组件注册规范 前端Vue组件必须在 `admin/src/router/component-map.js` 中注册: ```javascript // 导入组件 import PricingPlans from '@/views/system/pricing_plans.vue' import AiCallRecords from '@/views/system/ai_call_records.vue' // 注册映射 const componentMap = { 'system/pricing_plans': PricingPlans, 'system/ai_call_records': AiCallRecords, } ``` ### 2. 表单控件使用规范 使用 `com` 字段而非 `type` 字段: ```javascript // 单选按钮 { com: 'Radio', options: [...] } // 文本输入框 { com: 'Input' } // 文本域 { com: 'TextArea' } // 数字输入框 { com: 'InputNumber' } // 下拉选择 { com: 'Select', options: [...] } ``` ### 3. 数据库软删除模式 所有查询必须包含 `is_delete = 0` 条件: ```javascript const list = await model.findAll({ where: { is_delete: 0, // ... 其他条件 } }); ``` ### 4. 时间戳管理 使用手动管理而非Sequelize自动管理: ```javascript // 模型定义 { timestamps: false, // 禁用自动时间戳 // 手动定义时间字段 create_time: { type: DataTypes.DATE }, last_modify_time: { type: DataTypes.DATE } } // 创建时手动设置 const now = new Date(); await model.create({ // ... 其他字段 create_time: now, last_modify_time: now }); ``` ### 5. JSON字段处理 数据库存储为TEXT类型,应用层处理JSON序列化: ```javascript // 保存时 const data = { features: JSON.stringify(['功能1', '功能2']) }; // 读取时 const features = JSON.parse(record.features || '[]'); ``` ### 6. 异步记录模式 日志/记录类操作使用异步非阻塞模式: ```javascript // 使用 .catch() 而非 try-catch,避免阻塞主流程 this.recordAiCall(params).catch(err => { console.warn('记录失败(不影响主流程):', err.message); }); // 主流程继续执行 return result; ``` --- ## 四、部署检查清单 ### 数据库层 - [ ] 执行 `create_pricing_plans_table.sql` - [ ] 执行 `insert_pricing_plans_data.sql` - [ ] 执行 `create_ai_call_records_table.sql` - [ ] 验证表创建成功 ### 后端层 - [ ] 重启Node.js服务以加载新模型 - [ ] 验证模型加载:`Framework.getModels()` - [ ] 配置环境变量 `AI_API_KEY` 和 `AI_MODEL` - [ ] 测试后台API端点 ### 前端层 - [ ] 重新编译前端代码 - [ ] 验证组件注册成功 - [ ] 刷新浏览器缓存 - [ ] 测试管理界面功能 ### 菜单系统 - [ ] 验证"价格套餐管理"菜单显示 - [ ] 验证"AI调用记录"菜单显示 - [ ] 测试菜单跳转功能 ### 功能测试 - [ ] 价格套餐CRUD操作 - [ ] 前端API `/config/pricing-plans` 返回数据库数据 - [ ] AI调用自动记录Token - [ ] AI调用记录管理界面 - [ ] 统计功能准确性 --- ## 五、已知问题与注意事项 ### 1. 组件热更新 修改组件映射后需要: - 重启前端开发服务器 - 清除浏览器缓存 - 刷新页面 ### 2. AI服务配置 **重要**:系统使用阿里云DashScope API,不是DeepSeek。 必须配置正确的环境变量: ```bash AI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxx # 阿里云API Key AI_MODEL=qwen-turbo # Qwen模型 ``` ### 3. Token记录异步 Token记录失败不会影响AI调用主流程,但会打印警告日志。如果需要确保记录成功,应检查数据库连接和表结构。 ### 4. 成本计算 当前成本计算使用固定价格(qwen-turbo: ¥0.003/1000 tokens),如果切换到其他模型,需要修改 `calculateCost()` 方法。 ### 5. 数据备份 AI调用记录表会快速增长,建议: - 定期归档历史数据 - 设置数据保留策略(如只保留最近90天) - 建立定期备份机制 --- ## 六、文件路径索引 ### 价格套餐系统 **数据库** - `_sql/create_pricing_plans_table.sql` - `_sql/insert_pricing_plans_data.sql` **后端** - `api/model/pricing_plans.js` - `api/controller_admin/pricing_plans.js` - `api/controller_front/config.js` (修改第90-136行) **前端** - `admin/src/api/system/pricing_plans_server.js` - `admin/src/views/system/pricing_plans.vue` ### AI调用记录系统 **数据库** - `_sql/create_ai_call_records_table.sql` **后端** - `api/model/ai_call_records.js` - `api/services/ai_call_recorder.js` - `api/services/ai_service.js` (完全重写) - `api/controller_admin/ai_call_records.js` **前端** - `admin/src/api/system/ai_call_records_server.js` - `admin/src/views/system/ai_call_records.vue` ### 公共配置 - `admin/src/router/component-map.js` (新增两个组件映射) - `config/config.js` (AI配置项) - `.env` (环境变量) ### 文档 - `docs/ai_service_config.md` (AI服务配置说明) - `docs/implementation_summary.md` (本文档) --- ## 七、维护建议 ### 日常维护 1. **监控Token使用量** - 定期查看AI调用记录统计 - 关注异常高额调用 - 优化高频调用场景 2. **价格套餐调整** - 根据市场情况调整价格 - 通过后台界面快速上下架套餐 - 使用排序功能控制显示顺序 3. **数据清理** - 定期归档或删除历史AI调用记录 - 清理已删除的套餐数据(物理删除) ### 性能优化 1. **数据库索引** - AI调用记录表按需添加索引(user_id, sn_code, create_time) - 定期分析查询性能 2. **缓存策略** - 考虑对前端API `/config/pricing-plans` 添加缓存 - 缓存有效期建议5-10分钟 3. **日志归档** - 建立AI调用记录的归档机制 - 超过一定时间的数据转移到历史表 --- **文档版本**: 1.0 **最后更新**: 2025-12-27 **维护者**: 开发团队