绩效评分技能 (Performance Evaluation) 自动化处理团队月度绩效考核Excel文件,整合TAPD缺陷查询、Excel处理和智能体团队协作。 Agent 团队配置 使用 Agent 工具创建智能体团队,并行处理不同任务: | 角色 | 模型 | 职责 | |------|------|------| | 数据处理员 | glm-5 | Excel读写、表格格式化、数据合并 | | tapd操作员 | MiniMax-M2.5 | TAPD API调用、缺陷查询、URL生成 | | 绩效评估员 | kimi-k2.5 | 评分计算、系数计算、汇总表更新 | 快速启动 工作流程 Phase 1: 表格合并与格式化 1. 合并成员表格到工作簿 2. 修复标题: "[月份]绩效考核表" 3. 设置考核周期: "YYYY.M.D-YYYY.M.D" 4. 移除空白行列 Phase 2: 绩效评分 1. 检查上级评分,若为空则填入自评分 2. 查询TAPD缺陷数据 - 生产质量: 开发人员=姓名, version report=线上版本, 排除closed|rejected - 测试质量: 开发人员=姓名, version report=测试版本, 排除closed|rejected 3. 参考"评分等级"列计算上级评分 4. 填入TAPD URL链接 Phase 3:…

, name):\n return name\n \n # 排除词 - 用于识别非姓名部分(如部门、日期等)\n exclude_words = ['年', '月', '日', '组', '部', '门', '绩效', '考核', '前端', '后端', '测试', '研发', '中心', '交易', '业务线']\n \n # 尝试用多种分隔符分割:_ 、 · 、 -\n # 统一替换为下划线便于处理\n normalized = name.replace('·', '_').replace('-', '_')\n parts = normalized.split('_')\n \n # 过滤掉空部分\n parts = [p for p in parts if p]\n \n if len(parts) > 1:\n # 首先查找不包含排除词的姓名部分\n for part in parts:\n if re.match(r'^[一-龥]{2,4}

绩效评分技能 (Performance Evaluation) 自动化处理团队月度绩效考核Excel文件,整合TAPD缺陷查询、Excel处理和智能体团队协作。 Agent 团队配置 使用 Agent 工具创建智能体团队,并行处理不同任务: | 角色 | 模型 | 职责 | |------|------|------| | 数据处理员 | glm-5 | Excel读写、表格格式化、数据合并 | | tapd操作员 | MiniMax-M2.5 | TAPD API调用、缺陷查询、URL生成 | | 绩效评估员 | kimi-k2.5 | 评分计算、系数计算、汇总表更新 | 快速启动 工作流程 Phase 1: 表格合并与格式化 1. 合并成员表格到工作簿 2. 修复标题: "[月份]绩效考核表" 3. 设置考核周期: "YYYY.M.D-YYYY.M.D" 4. 移除空白行列 Phase 2: 绩效评分 1. 检查上级评分,若为空则填入自评分 2. 查询TAPD缺陷数据 - 生产质量: 开发人员=姓名, version report=线上版本, 排除closed|rejected - 测试质量: 开发人员=姓名, version report=测试版本, 排除closed|rejected 3. 参考"评分等级"列计算上级评分 4. 填入TAPD URL链接 Phase 3:…

, part):\n if not any(word in part for word in exclude_words):\n return part\n # 如果没找到,再返回第一个匹配的2-4字符中文部分\n for part in parts:\n if re.match(r'^[一-龥]{2,4}

绩效评分技能 (Performance Evaluation) 自动化处理团队月度绩效考核Excel文件,整合TAPD缺陷查询、Excel处理和智能体团队协作。 Agent 团队配置 使用 Agent 工具创建智能体团队,并行处理不同任务: | 角色 | 模型 | 职责 | |------|------|------| | 数据处理员 | glm-5 | Excel读写、表格格式化、数据合并 | | tapd操作员 | MiniMax-M2.5 | TAPD API调用、缺陷查询、URL生成 | | 绩效评估员 | kimi-k2.5 | 评分计算、系数计算、汇总表更新 | 快速启动 工作流程 Phase 1: 表格合并与格式化 1. 合并成员表格到工作簿 2. 修复标题: "[月份]绩效考核表" 3. 设置考核周期: "YYYY.M.D-YYYY.M.D" 4. 移除空白行列 Phase 2: 绩效评分 1. 检查上级评分,若为空则填入自评分 2. 查询TAPD缺陷数据 - 生产质量: 开发人员=姓名, version report=线上版本, 排除closed|rejected - 测试质量: 开发人员=姓名, version report=测试版本, 排除closed|rejected 3. 参考"评分等级"列计算上级评分 4. 填入TAPD URL链接 Phase 3:…

, part):\n return part\n \n # 尝试查找连续的中文字符(2-4个)\n matches = re.findall(r'[一-龥]{2,4}', name)\n if matches:\n # 返回最可能是姓名的部分(通常不包含排除关键词)\n for match in matches:\n if not any(word in match for word in exclude_words):\n return match\n # 如果都被排除了,返回最后一个匹配项\n if matches:\n return matches[-1]\n \n # 无法提取,返回原文件名(去掉后缀)\n return name\n\ndef fix_title(ws, month: int) -> tuple[bool, str]:\n \"\"\"修复标题月份\n\n Returns:\n (是否修改, 原值)\n \"\"\"\n title = ws[\"A1\"].value\n if not title:\n return False, \"\"\n\n title_str = str(title)\n\n # 修复 \"x月\" → 实际月份\n if \"x月\" in title_str:\n new_title = title_str.replace(\"x月\", f\"{month}月\")\n ws[\"A1\"] = new_title\n return True, title_str\n\n # 检查月份是否正确\n match = re.search(r\"(\\d+)月绩效考核表\", title_str)\n if match:\n current_month = int(match.group(1))\n if current_month != month:\n new_title = title_str.replace(f\"{current_month}月\", f\"{month}月\")\n ws[\"A1\"] = new_title\n return True, title_str\n\n return False, \"\"\n\n\ndef fix_period(ws, year: int, month: int) -> tuple[bool, str]:\n \"\"\"修复考核周期\n\n Returns:\n (是否修改, 原值)\n \"\"\"\n period = ws[\"J2\"].value\n if not period:\n return False, \"\"\n\n period_str = str(period)\n expected_period = generate_period(year, month)\n\n # 检查是否需要修复\n needs_fix = False\n\n # 检查年份错误 (2025 → 2026)\n if str(year - 1) in period_str:\n needs_fix = True\n\n # 检查月份错误\n if f\".{month}.\" not in period_str:\n needs_fix = True\n\n # 检查是否是预期的周期\n if period_str != expected_period:\n needs_fix = True\n\n if needs_fix:\n ws[\"J2\"] = expected_period\n return True, period_str\n\n return False, \"\"\n\n\ndef fix_name(ws, sheet_name: str) -> tuple[bool, str]:\n \"\"\"修复姓名字段,确保与工作表名称一致\n \n Returns:\n (是否修改, 原值)\n \"\"\"\n # B2 单元格应该包含姓名\n current_name = ws['B2'].value\n \n if current_name != sheet_name:\n ws['B2'] = sheet_name\n return True, str(current_name) if current_name else \"\"\n \n return False, \"\"\n\n\ndef copy_sheet(src_ws, dst_ws):\n \"\"\"复制工作表内容和格式\"\"\"\n # 复制所有单元格\n for row in src_ws.iter_rows():\n for cell in row:\n new_cell = dst_ws.cell(row=cell.row, column=cell.column, value=cell.value)\n\n if cell.has_style:\n new_cell.font = copy(cell.font)\n new_cell.border = copy(cell.border)\n new_cell.fill = copy(cell.fill)\n new_cell.number_format = cell.number_format\n new_cell.protection = copy(cell.protection)\n new_cell.alignment = copy(cell.alignment)\n\n # 复制列宽\n for col_letter, col_dim in src_ws.column_dimensions.items():\n dst_ws.column_dimensions[col_letter].width = col_dim.width\n dst_ws.column_dimensions[col_letter].hidden = col_dim.hidden\n\n # 复制行高\n for row_num, row_dim in src_ws.row_dimensions.items():\n dst_ws.row_dimensions[row_num].height = row_dim.height\n dst_ws.row_dimensions[row_num].hidden = row_dim.hidden\n\n # 复制合并单元格\n for merged_range in src_ws.merged_cells.ranges:\n dst_ws.merge_cells(str(merged_range))\n\n\ndef merge_individual_files(\n input_dir: str, output_path: str, month: int, year: int, dry_run: bool = False\n):\n \"\"\"合并个人表格到工作簿\"\"\"\n print(\"=== 绩效考核表合并处理 ===\\n\")\n\n # 查找个人表格文件\n input_path = Path(input_dir)\n individual_files = list(input_path.glob(\"*.xlsx\"))\n # 排除汇总文件(仅排除包含\"前端组\"的文件,不排除个人绩效表)\n individual_files = [\n f for f in individual_files if \"前端组\" not in f.name\n ]\n\n if not individual_files:\n print(f\"错误: 在 {input_dir} 中未找到个人表格文件\")\n return\n\n print(f\"找到 {len(individual_files)} 个个人表格:\\n\")\n for f in individual_files:\n name = extract_name_from_filename(f.name)\n print(f\" - {f.name} → {name}\")\n # 加载或创建工作簿\n if os.path.exists(output_path):\n wb = load_workbook(output_path)\n print(f\"\\n加载现有工作簿: {output_path}\")\n else:\n print(f\"\\n错误: 输出文件不存在: {output_path}\")\n return\n\n print(f\"\\n1. 处理成员表格:\\n\")\n\n changes = []\n\n for file_path in individual_files:\n # 从文件名中提取姓名作为工作表名\n sheet_name = extract_name_from_filename(file_path.name)\n \n # 加载源文件\n src_wb = load_workbook(file_path)\n src_ws = src_wb.active\n\n # 删除已存在的工作表\n if sheet_name in wb.sheetnames:\n del wb[sheet_name]\n\n # 创建新工作表\n dst_ws = wb.create_sheet(sheet_name)\n\n # 复制内容\n copy_sheet(src_ws, dst_ws)\n\n # 修复标题\n title_fixed, old_title = fix_title(dst_ws, month)\n if title_fixed:\n changes.append(\n f\" [{sheet_name}] 标题: '{old_title}' → '{dst_ws['A1'].value}'\"\n )\n\n # 修复考核周期\n period_fixed, old_period = fix_period(dst_ws, year, month)\n if period_fixed:\n changes.append(\n f\" [{sheet_name}] 考核周期: '{old_period}' → '{dst_ws['J2'].value}'\"\n )\n\n # 修复姓名字段\n name_fixed, old_name = fix_name(dst_ws, sheet_name)\n if name_fixed:\n changes.append(\n f\" [{sheet_name}] 姓名: '{old_name}' → '{sheet_name}'\"\n )\n\n if not title_fixed and not period_fixed and not name_fixed:\n print(f\" [{sheet_name}] ✓ 无需修正\")\n # 打印修改记录\n for change in changes:\n print(change)\n\n # 更新汇总表\n print(f\"\\n2. 更新汇总表:\")\n if \"汇总\" in wb.sheetnames:\n summary_ws = wb[\"汇总\"]\n header = summary_ws[\"A1\"].value\n if header:\n header_str = str(header)\n # 更新月份\n old_month_match = re.search(r\"(\\d+)\\s*月\", header_str)\n if old_month_match:\n old_month = old_month_match.group(1)\n if int(old_month) != month:\n # 格式化月份(保持原有空格格式)\n new_header = re.sub(r\"\\d+\\s*月\", f\"{month:02d} 月\", header_str)\n # 更新年份\n if str(year) not in new_header:\n new_header = re.sub(r\"\\d{4}年\", f\"{year}年\", new_header)\n summary_ws[\"A1\"] = new_header\n print(f\" 汇总表标题: '{header_str}' → '{new_header}'\")\n else:\n print(f\" 汇总表月份已是 {month} 月\")\n\n # 保存\n print(f\"\\n3. 保存文件:\")\n if not dry_run:\n wb.save(output_path)\n print(f\" ✓ 已保存: {output_path}\")\n else:\n print(f\" [预览模式] 未保存\")\n\n # 验证\n print(f\"\\n4. 验证结果:\")\n wb = load_workbook(output_path)\n for file_path in individual_files:\n sheet_name = extract_name_from_filename(file_path.name)\n if sheet_name in wb.sheetnames:\n ws = wb[sheet_name]\n print(f\" [{sheet_name}] 标题: {ws['A1'].value} | 周期: {ws['J2'].value}\")\n else:\n print(f\" [{sheet_name}] ❌ 未找到\")\n\n print(f\"\\n=== 处理完成 ===\")\n\n\ndef fix_existing_file(file_path: str, month: int, year: int, dry_run: bool = False):\n \"\"\"仅修复现有工作簿中的问题\"\"\"\n print(\"=== 绩效考核表修复处理 ===\\n\")\n\n wb = load_workbook(file_path)\n print(f\"加载文件: {file_path}\")\n print(f\"工作表: {wb.sheetnames}\\n\")\n\n print(\"1. 修复成员表格:\\n\")\n\n changes = []\n\n # 处理所有成员工作表(排除汇总)\n for sheet_name in wb.sheetnames:\n if sheet_name == \"汇总\":\n continue\n\n ws = wb[sheet_name]\n\n # 检查是否是绩效表(有标题)\n if not ws[\"A1\"].value or \"绩效考核表\" not in str(ws[\"A1\"].value):\n continue\n\n # 修复标题\n title_fixed, old_title = fix_title(ws, month)\n if title_fixed:\n changes.append(f\" [{sheet_name}] 标题: '{old_title}' → '{ws['A1'].value}'\")\n\n # 修复考核周期\n period_fixed, old_period = fix_period(ws, year, month)\n if period_fixed:\n changes.append(\n f\" [{sheet_name}] 考核周期: '{old_period}' → '{ws['J2'].value}'\"\n )\n\n # 修复姓名字段\n name_fixed, old_name = fix_name(ws, sheet_name)\n if name_fixed:\n changes.append(\n f\" [{sheet_name}] 姓名: '{old_name}' → '{sheet_name}'\"\n )\n\n if not title_fixed and not period_fixed and not name_fixed:\n print(f\" [{sheet_name}] ✓ 无需修正\")\n\n for change in changes:\n print(change)\n\n # 更新汇总表\n print(f\"\\n2. 更新汇总表:\")\n if \"汇总\" in wb.sheetnames:\n summary_ws = wb[\"汇总\"]\n header = summary_ws[\"A1\"].value\n if header:\n header_str = str(header)\n old_month_match = re.search(r\"(\\d+)\\s*月\", header_str)\n if old_month_match:\n old_month = int(old_month_match.group(1))\n if old_month != month:\n new_header = re.sub(r\"\\d+\\s*月\", f\"{month:02d} 月\", header_str)\n if str(year) not in new_header:\n new_header = re.sub(r\"\\d{4}年\", f\"{year}年\", new_header)\n summary_ws[\"A1\"] = new_header\n print(f\" 汇总表标题: '{header_str}' → '{new_header}'\")\n\n # 保存\n print(f\"\\n3. 保存文件:\")\n if not dry_run:\n wb.save(file_path)\n print(f\" ✓ 已保存: {file_path}\")\n else:\n print(f\" [预览模式] 未保存\")\n\n print(f\"\\n=== 处理完成 ===\")\n\n\ndef main():\n parser = argparse.ArgumentParser(description=\"绩效考核表合并与修复工具\")\n\n # 模式选择\n mode_group = parser.add_mutually_exclusive_group(required=True)\n mode_group.add_argument(\"--input-dir\", help=\"个人表格所在目录(合并模式)\")\n mode_group.add_argument(\"--file\", help=\"现有工作簿路径(仅修复模式)\")\n\n # 参数\n parser.add_argument(\"--output\", help=\"输出文件路径(合并模式)\")\n parser.add_argument(\"--month\", type=int, required=True, help=\"月份 (1-12)\")\n parser.add_argument(\"--year\", type=int, help=\"年份(默认当前年)\")\n parser.add_argument(\"--dry-run\", action=\"store_true\", help=\"预览模式,不保存文件\")\n\n args = parser.parse_args()\n\n # 默认年份\n import datetime\n\n year = args.year or datetime.datetime.now().year\n\n if args.input_dir:\n # 合并模式\n output = args.output or os.path.join(\n args.input_dir, f\"研发中心-{args.month}月份-前端组计划.xlsx\"\n )\n merge_individual_files(args.input_dir, output, args.month, year, args.dry_run)\n else:\n # 仅修复模式\n fix_existing_file(args.file, args.month, year, args.dry_run)\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":14910,"content_sha256":"974b29e3450aab002b1d260b6f465f2541e0a1cf55d06677273a7068d6292337"},{"filename":"scripts/process_performance.py","content":"#!/usr/bin/env python3\n\"\"\"\n绩效Excel数据处理脚本\n\n功能:\n1. 修复标题和考核周期格式\n2. 查询TAPD缺陷数据并生成URL\n3. 计算绩效系数\n4. 更新汇总表\n\n用法:\n python3 process_performance.py --file \"绩效表.xlsx\" --month 2 --year 2026\n\"\"\"\n\nimport sys\nimport os\nimport argparse\nimport calendar\nfrom typing import Dict, List, Optional\n\nimport openpyxl\n\n# 添加 tapd-idle scripts 目录到路径\nscript_dir = os.path.dirname(os.path.abspath(__file__))\n# script_dir = .../performance-evaluation/scripts\n# skills_dir = .../skills\nskills_dir = os.path.dirname(os.path.dirname(script_dir))\ntapd_scripts = os.path.join(skills_dir, 'tapd-idle', 'scripts')\nsys.path.insert(0, tapd_scripts)\n\ntry:\n from tapd_client import TAPDClient\nexcept ImportError:\n TAPDClient = None\n print(\"警告: 无法导入 TAPDClient,TAPD 查询功能将被禁用\")\n\n# 配置\nWORKSPACE_ID = os.getenv('TAPD_WORKSPACE_ID', '50372234') # 聚宝赞项目\nTAPD_BASE_URL = 'https://www.tapd.cn'\n\n# 特殊成员(上级评分在K列)\nSPECIAL_COL_MEMBERS = {'陈方杰', '刘奕君'}\n\n\ndef calculate_coefficient(score: float) -> float:\n \"\"\"计算绩效系数\"\"\"\n if score > 116:\n return 1.2\n elif score >= 106:\n return 1.1\n elif score >= 91:\n return 1.0\n elif score >= 81:\n return 0.9\n else:\n return 0.8\n\n\ndef get_member_sheets(wb) -> List[str]:\n \"\"\"获取所有成员工作表名称(排除汇总)\"\"\"\n return [name for name in wb.sheetnames if name != '汇总']\n\n\ndef fix_title(ws, sheet_name: str, month: int) -> bool:\n \"\"\"修复工作表标题\"\"\"\n correct_title = f\"{month}月绩效考核表\"\n current_title = ws['A1'].value\n\n if current_title != correct_title:\n ws['A1'].value = correct_title\n print(f\" [{sheet_name}] 标题: '{current_title}' -> '{correct_title}'\")\n return True\n return False\n\n\ndef fix_period(ws, sheet_name: str, year: int, month: int) -> bool:\n \"\"\"修复考核周期\"\"\"\n # 获取月份的最后一天\n last_day = calendar.monthrange(year, month)[1]\n correct_period = f\"{year}.{month}.1-{year}.{month}.{last_day}\"\n current_period = ws['J2'].value\n\n if current_period != correct_period:\n ws['J2'].value = correct_period\n print(f\" [{sheet_name}] 考核周期: '{current_period}' -> '{correct_period}'\")\n return True\n return False\n\n\ndef fill_supervisor_rating(ws, sheet_name: str) -> bool:\n \"\"\"填写缺失的上级评分(如果上级评分为空,则填入自评分)\"\"\"\n # J9: 生产质量上级评分, J10: 测试质量上级评分\n # 自评分在同一行的不同列(假设在I列)\n changes = False\n\n for row in [9, 10]:\n supervisor_cell = ws.cell(row=row, column=10) # J列\n self_cell = ws.cell(row=row, column=9) # I列(假设)\n\n if supervisor_cell.value is None and self_cell.value is not None:\n try:\n self_score = float(self_cell.value)\n supervisor_cell.value = self_score\n print(f\" [{sheet_name}] J{row}: 上级评分 = {self_score} (来自自评)\")\n changes = True\n except (ValueError, TypeError):\n pass\n\n return changes\n\n\ndef build_tapd_url(developer: str, version_report: str, created_range: str) -> str:\n \"\"\"构建TAPD缺陷查询URL\n\n 注意:TAPD前端URL使用 queryToken 机制,需要在浏览器中手动设置过滤条件。\n 这里返回的是缺陷列表基础URL。\n \"\"\"\n # TAPD前端缺陷列表基础URL\n return f\"{TAPD_BASE_URL}/tapd_fe/{WORKSPACE_ID}/bug/list\"\n\n\ndef query_tapd_bugs(client, developer: str, version_report: str, created_range: str) -> Dict:\n \"\"\"查询TAPD缺陷并返回数量和URL\"\"\"\n if client is None:\n return {'count': 0, 'url': build_tapd_url(developer, version_report, created_range)}\n\n try:\n import time\n time.sleep(0.5) # 避免API限流\n\n params = {\n 'workspace_id': WORKSPACE_ID,\n 'de': developer, # API参数: de = 开发人员\n 'version_report': version_report,\n 'created': created_range,\n 'limit': 100,\n 'fields': 'id,title,developer,version_report,created'\n }\n\n count_result = client.get_bug_count(params)\n count = count_result.get('data', {}).get('count', 0)\n\n return {\n 'count': count,\n 'url': build_tapd_url(developer, version_report, created_range)\n }\n except Exception as e:\n print(f\" 查询失败: {e}\")\n return {'count': 0, 'url': build_tapd_url(developer, version_report, created_range)}\n\n\ndef fill_tapd_urls(ws, sheet_name: str, client, created_range: str) -> bool:\n \"\"\"查询TAPD缺陷并填入URL\"\"\"\n changes = False\n\n # 查询生产质量(线上版本)\n prod_result = query_tapd_bugs(client, sheet_name, '线上版本', created_range)\n print(f\" 生产质量(线上版本): {prod_result['count']}条\")\n\n # 查询测试质量(测试版本)\n test_result = query_tapd_bugs(client, sheet_name, '测试版本', created_range)\n print(f\" 测试质量(测试版本): {test_result['count']}条\")\n\n # 填入URL到K列\n if prod_result['url']:\n ws['K9'].value = prod_result['url']\n changes = True\n if test_result['url']:\n ws['K10'].value = test_result['url']\n changes = True\n\n return changes\n\n\ndef get_superior_scores(wb) -> Dict[str, float]:\n \"\"\"从各成员工作表提取上级评分\"\"\"\n member_sheets = get_member_sheets(wb)\n results = {}\n\n for name in member_sheets:\n ws = wb[name]\n score_col = 11 if name in SPECIAL_COL_MEMBERS else 10\n\n score = None\n for row_idx in range(ws.max_row, 0, -1):\n cell_value = ws.cell(row=row_idx, column=score_col).value\n if cell_value is not None:\n try:\n score_float = float(cell_value)\n if score_float > 50: # 上级评分通常 > 50\n score = score_float\n break\n except (ValueError, TypeError):\n continue\n\n if score is not None:\n results[name] = score\n print(f\" {name}: 上级评分 = {score}\")\n else:\n print(f\" {name}: 未找到上级评分\")\n\n return results\n\n\ndef update_summary(wb, scores: Dict[str, float]) -> bool:\n \"\"\"更新汇总表\"\"\"\n if '汇总' not in wb.sheetnames:\n print(\"警告: 未找到汇总工作表\")\n return False\n\n ws = wb['汇总']\n changes = False\n\n # 获取汇总表中已有成员及其行号\n existing_members = {}\n for row_idx in range(3, 20):\n name = ws.cell(row=row_idx, column=4).value\n if name:\n existing_members[name] = row_idx\n\n # 找到最后一个有效成员行\n last_member_row = max(existing_members.values()) if existing_members else 14\n next_row = last_member_row + 1\n seq = len(existing_members)\n\n print(\"\\n更新汇总表:\")\n\n for name, score in scores.items():\n # 跳过分数为0的情况\n if score == 0:\n print(f\" {name}: 上级评分为0,保留原有分数\")\n continue\n\n coefficient = calculate_coefficient(score)\n\n if name in existing_members:\n row = existing_members[name]\n old_score = ws.cell(row=row, column=5).value\n ws.cell(row=row, column=5).value = score\n ws.cell(row=row, column=6).value = coefficient\n print(f\" {name}: {old_score} -> {score}, 系数={coefficient}\")\n changes = True\n else:\n # 新增记录\n seq += 1\n ws.cell(row=next_row, column=1).value = seq\n ws.cell(row=next_row, column=3).value = '前端开发'\n ws.cell(row=next_row, column=4).value = name\n ws.cell(row=next_row, column=5).value = score\n ws.cell(row=next_row, column=6).value = coefficient\n print(f\" {name}: 新增记录,分数={score}, 系数={coefficient}\")\n next_row += 1\n changes = True\n\n return changes\n\n\ndef process_excel(\n filepath: str,\n month: int,\n year: int,\n fix_format: bool = True,\n query_tapd: bool = True,\n update_summary_flag: bool = True,\n dry_run: bool = False,\n output_path: Optional[str] = None\n) -> bool:\n \"\"\"处理绩效Excel文件\"\"\"\n print(f\"=== 绩效考核表处理开始 ===\\n\")\n print(f\"加载文件: {filepath}\")\n\n try:\n wb = openpyxl.load_workbook(filepath)\n except Exception as e:\n print(f\"错误: 无法加载文件 - {e}\")\n return False\n\n member_sheets = get_member_sheets(wb)\n print(f\"找到 {len(member_sheets)} 个成员工作表\")\n\n # 初始化TAPD客户端\n client = None\n if query_tapd and TAPDClient:\n try:\n client = TAPDClient()\n print(\"TAPD客户端已连接\")\n except Exception as e:\n print(f\"TAPD连接失败: {e}\")\n print(\"将跳过TAPD URL填充\")\n\n # 计算日期范围\n last_day = calendar.monthrange(year, month)[1]\n created_range = f\"{year}-{month:02d}-01~{year}-{month:02d}-{last_day}\"\n\n changes = False\n\n # Phase 1: 修复格式\n if fix_format:\n print(f\"\\n1. 修复标题和考核周期:\")\n for sheet_name in member_sheets:\n ws = wb[sheet_name]\n if fix_title(ws, sheet_name, month):\n changes = True\n if fix_period(ws, sheet_name, year, month):\n changes = True\n\n # Phase 2: 查询TAPD并填入URL\n if query_tapd:\n print(f\"\\n2. 查询TAPD缺陷数据:\")\n for sheet_name in member_sheets:\n ws = wb[sheet_name]\n print(f\" [{sheet_name}]\")\n if fill_tapd_urls(ws, sheet_name, client, created_range):\n changes = True\n\n # Phase 3: 更新汇总表\n if update_summary_flag:\n print(f\"\\n3. 提取上级评分:\")\n scores = get_superior_scores(wb)\n\n if update_summary(wb, scores):\n changes = True\n\n # 保存文件\n if changes and not dry_run:\n output = output_path or filepath\n print(f\"\\n保存文件: {output}\")\n wb.save(output)\n print(\"文件已保存\")\n elif dry_run:\n print(\"\\n[预览模式] 未保存变更\")\n else:\n print(\"\\n无需变更\")\n\n print(\"\\n=== 处理完成 ===\")\n return True\n\n\ndef main():\n parser = argparse.ArgumentParser(description='绩效Excel数据处理脚本')\n parser.add_argument('--file', required=True, help='绩效表格路径')\n parser.add_argument('--month', type=int, required=True, help='月份 (1-12)')\n parser.add_argument('--year', type=int, default=2026, help='年份 (默认当前年)')\n parser.add_argument('--fix-format', action='store_true', help='仅修复格式')\n parser.add_argument('--calculate-scores', action='store_true', help='仅计算评分')\n parser.add_argument('--update-summary', action='store_true', help='仅更新汇总表')\n parser.add_argument('--dry-run', action='store_true', help='预览变更不执行')\n parser.add_argument('--output', help='输出文件路径')\n\n args = parser.parse_args()\n\n # 根据参数决定执行哪些步骤\n fix_format = True\n query_tapd = True\n update_summary_flag = True\n\n if args.fix_format or args.calculate_scores or args.update_summary:\n fix_format = args.fix_format\n query_tapd = args.calculate_scores or args.fix_format\n update_summary_flag = args.update_summary or args.calculate_scores\n\n process_excel(\n filepath=args.file,\n month=args.month,\n year=args.year,\n fix_format=fix_format,\n query_tapd=query_tapd,\n update_summary_flag=update_summary_flag,\n dry_run=args.dry_run,\n output_path=args.output\n )\n\n\nif __name__ == '__main__':\n main()","content_type":"text/x-python; charset=utf-8","language":"python","size":12010,"content_sha256":"0a56c13e87e92a8585284db0809d3f0cf0810647bf67df53f5710535fbb594c0"},{"filename":"scripts/requirements.txt","content":"openpyxl>=3.1.0\nrequests>=2.25.0","content_type":"text/plain; charset=utf-8","language":null,"size":32,"content_sha256":"b2e64de13921c53fae1a29839248503d9487b2a4bac037ed56e5bfb72dde2255"},{"filename":"scripts/tapd_helper.py","content":"#!/usr/bin/env python3\n\"\"\"\nTAPD 查询辅助脚本\n\n功能:\n1. 查询缺陷数据\n2. 生成TAPD URL\n3. 统计缺陷数量\n\n用法:\n python3 tapd_helper.py query-bugs --developer \"姓名\" --version \"线上版本\" --created \"2026-02-01~2026-02-28\"\n python3 tapd_helper.py build-url --developer \"姓名\" --version \"线上版本\" --created \"2026-02-01~2026-02-28\"\n python3 tapd_helper.py count-bugs --developer \"姓名\" --version \"线上版本\" --created \"2026-02-01~2026-02-28\"\n\"\"\"\n\nimport sys\nimport os\nimport argparse\nimport json\n\n# 添加 tapd-idle scripts 目录到路径\nscript_dir = os.path.dirname(os.path.abspath(__file__))\n# script_dir = .../performance-evaluation/scripts\n# skills_dir = .../skills\nskills_dir = os.path.dirname(os.path.dirname(script_dir))\ntapd_scripts = os.path.join(skills_dir, 'tapd-idle', 'scripts')\nsys.path.insert(0, tapd_scripts)\n\ntry:\n from tapd_client import TAPDClient\nexcept ImportError:\n print(\"错误: 无法导入 TAPDClient\")\n print(\"请确保 tapd-idle 技能已安装\")\n sys.exit(1)\n\n# 配置\nWORKSPACE_ID = os.getenv('TAPD_WORKSPACE_ID', '50372234') # 聚宝赞项目\nTAPD_BASE_URL = 'https://www.tapd.cn'\n\n\ndef build_tapd_url(developer: str, version_report: str, created_range: str) -> str:\n \"\"\"构建TAPD缺陷查询URL\n\n 注意:TAPD前端URL使用 queryToken 机制,需要通过浏览器操作保存筛选条件后生成。\n 这里返回的是缺陷列表基础URL,附带筛选条件作为URL锚点供参考。\n 用户需要在前端手动设置过滤条件,或使用\"保存筛选\"功能生成可分享的链接。\n \"\"\"\n # TAPD前端缺陷列表基础URL\n base_url = f\"{TAPD_BASE_URL}/tapd_fe/{WORKSPACE_ID}/bug/list\"\n\n # 构建筛选条件字符串(用于提示用户)\n filters = []\n if developer:\n filters.append(f\"开发人员=\\\"{developer}\\\"\")\n if version_report:\n filters.append(f\"发现版本=\\\"{version_report}\\\"\")\n if created_range:\n filters.append(f\"创建时间=\\\"{created_range}\\\"\")\n\n filter_note = \" | \".join(filters) if filters else \"\"\n\n # 返回基础URL和筛选条件说明\n # 实际使用时需要用户在前端手动设置筛选条件\n return base_url\n\n\ndef query_bugs(developer: str, version_report: str, created_range: str, fields: str = None) -> dict:\n \"\"\"查询TAPD缺陷\"\"\"\n client = TAPDClient()\n\n params = {\n 'workspace_id': WORKSPACE_ID,\n 'de': developer, # API参数: de = 开发人员\n 'version_report': version_report,\n 'created': created_range,\n 'limit': 100\n }\n\n if fields:\n params['fields'] = fields\n else:\n params['fields'] = 'id,title,developer,version_report,created,status,severity'\n\n result = client.get_bug(params)\n\n # 同时获取数量\n count_result = client.get_bug_count(params)\n count = count_result.get('data', {}).get('count', 0)\n\n # 构建筛选条件说明\n filter_conditions = []\n if developer:\n filter_conditions.append(f\"开发人员=\\\"{developer}\\\"\")\n if version_report:\n filter_conditions.append(f\"发现版本=\\\"{version_report}\\\"\")\n if created_range:\n filter_conditions.append(f\"创建时间=\\\"{created_range}\\\"\")\n filter_note = \" | \".join(filter_conditions) if filter_conditions else \"\"\n\n return {\n 'count': count,\n 'bugs': result.get('data', []),\n 'url': build_tapd_url(developer, version_report, created_range),\n 'filter_note': filter_note # 筛选条件说明\n }\n\n\ndef count_bugs(developer: str, version_report: str, created_range: str) -> int:\n \"\"\"统计缺陷数量\"\"\"\n client = TAPDClient()\n\n params = {\n 'workspace_id': WORKSPACE_ID,\n 'de': developer, # API参数: de = 开发人员\n 'version_report': version_report,\n 'created': created_range\n }\n\n result = client.get_bug_count(params)\n return result.get('data', {}).get('count', 0)\n\n\ndef main():\n parser = argparse.ArgumentParser(description='TAPD查询辅助脚本')\n subparsers = parser.add_subparsers(dest='command', help='可用命令')\n\n # query-bugs 命令\n query_parser = subparsers.add_parser('query-bugs', help='查询缺陷')\n query_parser.add_argument('--developer', required=True, help='开发人员姓名')\n query_parser.add_argument('--version', required=True, help='发现版本(线上版本/测试版本)')\n query_parser.add_argument('--created', required=True, help='创建时间范围(如 2026-02-01~2026-02-28)')\n query_parser.add_argument('--fields', help='返回字段(逗号分隔)')\n query_parser.add_argument('--json', action='store_true', help='输出JSON格式')\n\n # build-url 命令\n url_parser = subparsers.add_parser('build-url', help='生成TAPD URL')\n url_parser.add_argument('--developer', required=True, help='开发人员姓名')\n url_parser.add_argument('--version', required=True, help='发现版本')\n url_parser.add_argument('--created', required=True, help='创建时间范围')\n\n # count-bugs 命令\n count_parser = subparsers.add_parser('count-bugs', help='统计缺陷数量')\n count_parser.add_argument('--developer', required=True, help='开发人员姓名')\n count_parser.add_argument('--version', required=True, help='发现版本')\n count_parser.add_argument('--created', required=True, help='创建时间范围')\n\n args = parser.parse_args()\n\n if not args.command:\n parser.print_help()\n return\n\n try:\n if args.command == 'query-bugs':\n result = query_bugs(args.developer, args.version, args.created, args.fields)\n\n if args.json:\n print(json.dumps(result, ensure_ascii=False, indent=2))\n else:\n print(f\"缺陷数量: {result['count']}\")\n print(f\"TAPD URL: {result['url']}\")\n print(f\"\\n缺陷列表:\")\n for bug in result['bugs']:\n bug_data = bug.get('Bug', bug)\n print(f\" - {bug_data.get('id')}: {bug_data.get('title')}\")\n\n elif args.command == 'build-url':\n url = build_tapd_url(args.developer, args.version, args.created)\n print(url)\n\n elif args.command == 'count-bugs':\n count = count_bugs(args.developer, args.version, args.created)\n print(count)\n\n except Exception as e:\n print(f\"错误: {e}\")\n sys.exit(1)\n\n\nif __name__ == '__main__':\n main()","content_type":"text/x-python; charset=utf-8","language":"python","size":6485,"content_sha256":"6226b105a60cf939ec9ba7ba99ea632e1134dbf4585e7e5309ff73c1fce84128"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"绩效评分技能 (Performance Evaluation)","type":"text"}]},{"type":"paragraph","content":[{"text":"自动化处理团队月度绩效考核Excel文件,整合TAPD缺陷查询、Excel处理和智能体团队协作。","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Agent 团队配置","type":"text"}]},{"type":"paragraph","content":[{"text":"使用 Agent 工具创建智能体团队,并行处理不同任务:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"角色","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"模型","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"职责","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"数据处理员","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"glm-5","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Excel读写、表格格式化、数据合并","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"tapd操作员","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MiniMax-M2.5","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"TAPD API调用、缺陷查询、URL生成","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"绩效评估员","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"kimi-k2.5","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"评分计算、系数计算、汇总表更新","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"快速启动","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# 合并个人表格到工作簿(推荐)\npython3 scripts/merge_sheets.py --input-dir \"bech/3m/\" --month 3 --year 2026\n\n# 仅修复现有工作簿中的标题和日期\npython3 scripts/merge_sheets.py --file \"绩效表格.xlsx\" --month 3 --fix-only\n\n# 预览模式(不保存文件)\npython3 scripts/merge_sheets.py --input-dir \"bech/3m/\" --month 3 --dry-run","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"工作流程","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 1: 表格合并与格式化","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"合并成员表格到工作簿","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"修复标题: \"[月份]绩效考核表\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"设置考核周期: \"YYYY.M.D-YYYY.M.D\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"移除空白行列","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 2: 绩效评分","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"检查上级评分,若为空则填入自评分","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"查询TAPD缺陷数据","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"生产质量: 开发人员=姓名, version_report=线上版本, 排除closed|rejected","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"测试质量: 开发人员=姓名, version_report=测试版本, 排除closed|rejected","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"参考\"评分等级\"列计算上级评分","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"填入TAPD URL链接","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 3: 汇总表更新","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"提取成员上级评分","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"计算绩效系数(见 coefficient_rules.md)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"更新或新增汇总记录","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"环境配置","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# TAPD API 凭证(用于查询缺陷数据)\nexport TAPD_ACCESS_TOKEN=\"你的个人访问令牌\" # 推荐\n# 或\nexport TAPD_API_USER=\"API账号\"\nexport TAPD_API_PASSWORD=\"API密钥\"\n\n# 项目配置\nexport TAPD_WORKSPACE_ID=\"50372234\" # 聚宝赞项目","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Excel 单元格结构","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"成员工作表","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"单元格","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"内容","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A1","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"标题 (如 \"2月绩效考核表\")","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"J2","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"考核周期 (如 \"2026.2.1-2026.2.28\")","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"J9","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"生产质量上级评分","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"J10","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"测试质量上级评分","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"K9","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"生产质量TAPD URL","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"K10","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"测试质量TAPD URL","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"特殊情况","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"陈方杰、刘奕君的上级评分在K列(第11列)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"汇总工作表","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"列","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"内容","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"序号","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"B","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"部门 (合并单元格)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"C","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"岗位","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"D","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"姓名","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"E","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"绩效分数","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"F","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"绩效系数","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"绩效系数规则","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"分数范围","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"绩效系数","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":">116","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.2","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"106-115","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.1","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"91-105","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.0","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"81-90","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0.9","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"≤80","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0.8","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"与 tapd-idle 技能集成","type":"text"}]},{"type":"paragraph","content":[{"text":"本技能依赖 ","type":"text"},{"text":"tapd-idle","type":"text","marks":[{"type":"code_inline"}]},{"text":" 技能提供的 TAPDClient 类:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# 从 tapd-idle 导入 TAPD 客户端\nimport sys\nsys.path.insert(0, '/path/to/.agents/skills/tapd-idle/scripts')\nfrom tapd_client import TAPDClient\n\nclient = TAPDClient()\n# API参数: de = 开发人员(不是 developer)\nbugs = client.get_bug({'workspace_id': '50372234', 'de': '姓名'})","type":"text"}]},{"type":"paragraph","content":[{"text":"API参数对照","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"查询字段","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"API参数","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"说明","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"开发人员","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"de","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"缺陷的开发人员","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"处理人","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"current_owner","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"缺陷的处理人","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"发现版本","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"version_report","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"缺陷发现的版本","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"创建时间","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"created","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"创建时间范围","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"注意","type":"text","marks":[{"type":"strong"}]},{"text":":TAPD前端URL使用 ","type":"text"},{"text":"queryToken","type":"text","marks":[{"type":"code_inline"}]},{"text":" 机制保存筛选条件,无法通过简单URL参数生成可分享的链接。需要在浏览器中手动设置筛选条件后使用\"保存筛选\"功能。","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"文件结构","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"performance-evaluation/\n├── SKILL.md # 技能主文件\n├── package.json # 版本信息\n├── .cursorrules # Cursor规则\n├── scripts/\n│ ├── requirements.txt # openpyxl>=3.1.0, requests>=2.25.0\n│ ├── process_performance.py # 主处理脚本\n│ └── tapd_helper.py # TAPD查询辅助函数\n└── references/\n ├── excel_structure.md # Excel单元格位置定义\n └── coefficient_rules.md # 绩效系数计算规则","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"命令详解","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"process_performance.py","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"python3 scripts/process_performance.py [选项]\n\n选项:\n --file PATH 绩效表格路径 (必需)\n --month MONTH 月份 (1-12)\n --year YEAR 年份 (默认当前年)\n --fix-format 仅修复格式\n --calculate-scores 仅计算评分\n --update-summary 仅更新汇总表\n --dry-run 预览变更不执行\n --output PATH 输出文件路径 (默认覆盖原文件)","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"tapd_helper.py","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# 查询缺陷\npython3 scripts/tapd_helper.py query-bugs --developer \"姓名\" --version \"线上版本\" --created \"2026-02-01~2026-02-28\"\n\n# 生成TAPD URL\npython3 scripts/tapd_helper.py build-url --developer \"姓名\" --version \"线上版本\" --created \"2026-02-01~2026-02-28\"\n\n# 统计缺陷数量\npython3 scripts/tapd_helper.py count-bugs --developer \"姓名\" --version \"线上版本\" --created \"2026-02-01~2026-02-28\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"merge_sheets.py","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"python3 scripts/merge_sheets.py [选项]\n\n选项:\n --input-dir DIR 个人表格所在目录(合并模式)\n --file PATH 现有工作簿路径(仅修复模式)\n --output PATH 输出文件路径(合并模式,可选)\n --month MONTH 月份 (1-12, 必需)\n --year YEAR 年份(默认当前年)\n --dry-run 预览模式,不保存文件","type":"text"}]},{"type":"paragraph","content":[{"text":"功能说明","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"合并模式","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"--input-dir","type":"text","marks":[{"type":"code_inline"}]},{"text":"):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"扫描目录下所有 ","type":"text"},{"text":".xlsx","type":"text","marks":[{"type":"code_inline"}]},{"text":" 文件(排除汇总文件)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"合并到指定工作簿,替换同名工作表","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"自动修复标题月份和考核周期","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"仅修复模式","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"--file","type":"text","marks":[{"type":"code_inline"}]},{"text":"):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"修复现有工作簿中的标题和日期错误","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"不合并新文件","type":"text"}]}]}]}]}]},{"type":"paragraph","content":[{"text":"自动修复规则","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"问题","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"修复规则","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"标题 \"x月\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"替换为指定月份","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"标题月份错误","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"替换为正确月份","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"年份 2025","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"替换为 2026","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"月份错误","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"替换为正确月份","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"汇总表月份","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"更新为指定月份","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"姓名字段错误","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"更新为工作表名称","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"文件名姓名提取","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"paragraph","content":[{"text":"支持从包含额外信息的文件名中提取姓名:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"文件名格式","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"提取结果","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"周树梧.xlsx","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"周树梧","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"前端组_周树梧.xlsx","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"周树梧","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2026年3月_周树梧.xlsx","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"周树梧","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"周树梧_绩效.xlsx","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"周树梧","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"3月_周树梧_前端.xlsx","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"周树梧","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"提取规则:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"纯姓名文件名(2-4个中文字符)直接返回","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"下划线分割时,查找2-4个中文字符的部分","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"排除包含年、月、组、部门等关键词的部分","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"无法提取时返回原文件名(去掉后缀)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"错误处理","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"错误类型","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"处理方式","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"TAPD连接失败","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"跳过URL填充,继续处理其他任务","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"单元格为空","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"保留原值或填入默认值","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"工作表不存在","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"打印警告,跳过该成员","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"环境变量未设置","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"提示用户配置TAPD凭证","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"示例使用场景","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"场景1: 完整处理流程","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"python3 scripts/process_performance.py \\\n --file \"bech/2m/研发中心-2月份-前端组绩效.xlsx\" \\\n --month 2 --year 2026","type":"text"}]},{"type":"paragraph","content":[{"text":"输出:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"=== 绩效考核表处理开始 ===\n\n加载文件: bech/2m/研发中心-2月份-前端组绩效.xlsx\n\n1. 修复标题月份错误:\n [吴铝] 标题: '1月绩效考核表' -> '2月绩效考核表'\n [李金涛] 标题: '1月绩效考核表' -> '2月绩效考核表'\n\n2. 修复考核周期错误:\n [吴铝] 考核周期: '2026.1.1-2026.1.31' -> '2026.2.1-2026.2.28'\n\n3. 查询TAPD bug数据:\n [吴铝] 生产质量: 3条, 测试质量: 2条\n [文武] 生产质量: 1条, 测试质量: 0条\n\n4. 更新汇总表:\n 吴铝: 95 -> 95, 系数=1.0\n 文武: 88 -> 88, 系数=0.9\n\n=== 处理完成 ===","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"场景2: 仅查询TAPD数据","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"python3 scripts/tapd_helper.py query-bugs \\\n --developer \"吴铝\" \\\n --version \"线上版本\" \\\n --created \"2026-02-01~2026-02-28\"","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"参考文档","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/excel_structure.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Excel单元格详细位置","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/coefficient_rules.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - 绩效系数计算规则","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"../tapd-idle/SKILL.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - TAPD技能使用指南","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","author":"@skillopedia","source":{"stars":1,"repo_name":"toy-skills","origin_url":"https://github.com/wvlvik/toy-skills/blob/HEAD/.agents/skills/performance-evaluation/SKILL.md","repo_owner":"wvlvik","body_sha256":"80d5a4015f30881d435d30505cd2549a9524372645677b4d80ce1631a3812fa9","cluster_key":"6e6a92706c00576190ceb5301f1394f696a1d4e43f6a3bbdfd0ff10ebbaf42a0","clean_bundle":{"format":"clean-skill-bundle-v1","source":"wvlvik/toy-skills/.agents/skills/performance-evaluation/SKILL.md","attachments":[{"id":"d1fe1fe0-af9a-55ce-97f7-b56a9a2fb990","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d1fe1fe0-af9a-55ce-97f7-b56a9a2fb990/attachment","path":".cursorrules","size":6428,"sha256":"b8cdf18c5deeae4c4c68e350ef2f5f58106bfae6173104c038fc0001ea1edd8e","contentType":"text/plain; charset=utf-8"},{"id":"a063da47-d234-59a0-9146-be7813e62761","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/a063da47-d234-59a0-9146-be7813e62761/attachment.json","path":"package.json","size":633,"sha256":"51b2f9c17e37101bf1f1de45dccb15d50319893837348376bbc6fdc8df97f95d","contentType":"application/json; charset=utf-8"},{"id":"ac9d71c5-f1b5-5a5e-9b83-a41a4b843e91","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ac9d71c5-f1b5-5a5e-9b83-a41a4b843e91/attachment.md","path":"references/coefficient_rules.md","size":2337,"sha256":"e0baa9dfa20dd8c2d03cd6c4d59156d459ffb7b35f89afdbdf81e20cd8dc81ee","contentType":"text/markdown; charset=utf-8"},{"id":"ab62a887-dfa8-53b8-b10d-5fd314967662","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ab62a887-dfa8-53b8-b10d-5fd314967662/attachment.md","path":"references/excel_structure.md","size":2861,"sha256":"bb943dd1d9331916bc693775de70e32ee7f02225341995c8e7a82a404843e9dd","contentType":"text/markdown; charset=utf-8"},{"id":"fd1d6da3-7fbf-5c4c-a32e-b37038f3cf27","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/fd1d6da3-7fbf-5c4c-a32e-b37038f3cf27/attachment.py","path":"scripts/merge_sheets.py","size":14910,"sha256":"974b29e3450aab002b1d260b6f465f2541e0a1cf55d06677273a7068d6292337","contentType":"text/x-python; charset=utf-8"},{"id":"a7c05db3-fc32-561a-848a-22b60e7eb453","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/a7c05db3-fc32-561a-848a-22b60e7eb453/attachment.py","path":"scripts/process_performance.py","size":12010,"sha256":"0a56c13e87e92a8585284db0809d3f0cf0810647bf67df53f5710535fbb594c0","contentType":"text/x-python; charset=utf-8"},{"id":"8d6d2209-cbe2-5e82-a305-9d45dc878b8c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8d6d2209-cbe2-5e82-a305-9d45dc878b8c/attachment.txt","path":"scripts/requirements.txt","size":32,"sha256":"b2e64de13921c53fae1a29839248503d9487b2a4bac037ed56e5bfb72dde2255","contentType":"text/plain; charset=utf-8"},{"id":"21d25008-361f-5771-8440-fd507998db28","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/21d25008-361f-5771-8440-fd507998db28/attachment.py","path":"scripts/tapd_helper.py","size":6485,"sha256":"6226b105a60cf939ec9ba7ba99ea632e1134dbf4585e7e5309ff73c1fce84128","contentType":"text/x-python; charset=utf-8"}],"bundle_sha256":"fcdb480ae01a47d7722ddc52d7eeb613154283c42c04a136097f1417ef80b5c6","attachment_count":8,"text_attachments":7,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":1,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":".agents/skills/performance-evaluation/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"general","category_label":"General"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"general","import_tag":"clean-skills-v1","_yaml_error":"YAMLException: bad indentation of a mapping entry (2:160)\n\n 1 | ... \n 2 | ... 接 (3) 计算绩效系数 (4) 更新汇总表。Triggers: \"绩效\", \"考核\", \"评分\", \"绩效表\", \"coef ...\n-----------------------------------------^"}},"renderedAt":1782979457806}

绩效评分技能 (Performance Evaluation) 自动化处理团队月度绩效考核Excel文件,整合TAPD缺陷查询、Excel处理和智能体团队协作。 Agent 团队配置 使用 Agent 工具创建智能体团队,并行处理不同任务: | 角色 | 模型 | 职责 | |------|------|------| | 数据处理员 | glm-5 | Excel读写、表格格式化、数据合并 | | tapd操作员 | MiniMax-M2.5 | TAPD API调用、缺陷查询、URL生成 | | 绩效评估员 | kimi-k2.5 | 评分计算、系数计算、汇总表更新 | 快速启动 工作流程 Phase 1: 表格合并与格式化 1. 合并成员表格到工作簿 2. 修复标题: "[月份]绩效考核表" 3. 设置考核周期: "YYYY.M.D-YYYY.M.D" 4. 移除空白行列 Phase 2: 绩效评分 1. 检查上级评分,若为空则填入自评分 2. 查询TAPD缺陷数据 - 生产质量: 开发人员=姓名, version report=线上版本, 排除closed|rejected - 测试质量: 开发人员=姓名, version report=测试版本, 排除closed|rejected 3. 参考"评分等级"列计算上级评分 4. 填入TAPD URL链接 Phase 3:…