293 lines
9.5 KiB
Python
293 lines
9.5 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
import json
|
|||
|
|
import os
|
|||
|
|
from datetime import datetime
|
|||
|
|
|
|||
|
|
# 产业名称到岗位名称的映射
|
|||
|
|
industry_to_position = {
|
|||
|
|
"插画设计": "插画师",
|
|||
|
|
"灯光": "影视灯光",
|
|||
|
|
"动画设计": "角色原画师",
|
|||
|
|
"后期特效": "特效设计师",
|
|||
|
|
"剪辑": "剪辑师",
|
|||
|
|
"品牌设计": "品牌视觉内容策划",
|
|||
|
|
"平面设计": "平面设计师",
|
|||
|
|
"三维设计": "3D建模师",
|
|||
|
|
"摄影/摄像": "影视摄像",
|
|||
|
|
"室内设计": "室内设计师",
|
|||
|
|
"调色": "调色师",
|
|||
|
|
"新媒体运营": "自媒体运营专员",
|
|||
|
|
"音频处理": "音效设计师",
|
|||
|
|
"影视节目策划": "导演",
|
|||
|
|
"直播": "直播运营"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
def extract_questions(interview_content):
|
|||
|
|
"""提取面试题和答案"""
|
|||
|
|
questions = []
|
|||
|
|
lines = interview_content.split('\n')
|
|||
|
|
current_question = None
|
|||
|
|
current_answer = ''
|
|||
|
|
collecting_answer = False
|
|||
|
|
|
|||
|
|
for line in lines:
|
|||
|
|
line_stripped = line.strip()
|
|||
|
|
|
|||
|
|
# 检测问题行
|
|||
|
|
if line_stripped and line_stripped[0].isdigit() and '. 问题' in line_stripped:
|
|||
|
|
# 保存上一个问题
|
|||
|
|
if current_question:
|
|||
|
|
answer = current_answer.strip()
|
|||
|
|
# 限制答案长度
|
|||
|
|
if len(answer) > 400:
|
|||
|
|
cut_point = 400
|
|||
|
|
for sep in ['。', ';', '. ']:
|
|||
|
|
pos = answer[:400].rfind(sep)
|
|||
|
|
if pos > 200:
|
|||
|
|
cut_point = pos + 1
|
|||
|
|
break
|
|||
|
|
answer = answer[:cut_point] + "..."
|
|||
|
|
|
|||
|
|
questions.append({
|
|||
|
|
'question': current_question,
|
|||
|
|
'answer': answer if answer else "请根据您的实际经验和项目情况进行回答。"
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
# 提取新问题
|
|||
|
|
parts = line_stripped.split('问题:', 1)
|
|||
|
|
if len(parts) > 1:
|
|||
|
|
current_question = parts[1].strip()
|
|||
|
|
else:
|
|||
|
|
parts = line_stripped.split('问题:', 1)
|
|||
|
|
if len(parts) > 1:
|
|||
|
|
current_question = parts[1].strip()
|
|||
|
|
else:
|
|||
|
|
current_question = line_stripped
|
|||
|
|
|
|||
|
|
current_answer = ''
|
|||
|
|
collecting_answer = False
|
|||
|
|
|
|||
|
|
# 检测答案开始
|
|||
|
|
elif any(marker in line for marker in ['参考回答:', '参考答案:', '答案:']):
|
|||
|
|
collecting_answer = True
|
|||
|
|
for marker in ['参考回答:', '参考答案:', '答案:']:
|
|||
|
|
if marker in line:
|
|||
|
|
answer_part = line.split(marker, 1)[1].strip()
|
|||
|
|
if answer_part:
|
|||
|
|
current_answer = answer_part
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
# 收集答案内容
|
|||
|
|
elif collecting_answer and line.strip():
|
|||
|
|
if (line_stripped and line_stripped[0].isdigit() and '. 问题' in line_stripped) or line_stripped.startswith('#'):
|
|||
|
|
collecting_answer = False
|
|||
|
|
else:
|
|||
|
|
if current_answer:
|
|||
|
|
current_answer += ' '
|
|||
|
|
current_answer += line.strip()
|
|||
|
|
|
|||
|
|
# 保存最后一个问题
|
|||
|
|
if current_question:
|
|||
|
|
answer = current_answer.strip()
|
|||
|
|
if len(answer) > 400:
|
|||
|
|
cut_point = 400
|
|||
|
|
for sep in ['。', ';', '. ']:
|
|||
|
|
pos = answer[:400].rfind(sep)
|
|||
|
|
if pos > 200:
|
|||
|
|
cut_point = pos + 1
|
|||
|
|
break
|
|||
|
|
answer = answer[:cut_point] + "..."
|
|||
|
|
|
|||
|
|
questions.append({
|
|||
|
|
'question': current_question,
|
|||
|
|
'answer': answer if answer else "请根据您的实际经验和项目情况进行回答。"
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
return questions[:16] # 最多16个问题
|
|||
|
|
|
|||
|
|
def update_industry(industry_name, position_name):
|
|||
|
|
"""更新单个产业的面试题"""
|
|||
|
|
# 读取源数据
|
|||
|
|
with open('网页未导入数据/视觉设计产业/视觉设计岗位简历.json', 'r', encoding='utf-8') as f:
|
|||
|
|
positions_data = json.load(f)
|
|||
|
|
|
|||
|
|
# 找到对应岗位
|
|||
|
|
position_data = None
|
|||
|
|
for position in positions_data:
|
|||
|
|
if position.get("岗位名称") == position_name:
|
|||
|
|
position_data = position
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
if not position_data:
|
|||
|
|
print(f" ✗ 未找到岗位:{position_name}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
interview_content = position_data.get("面试题内容", "")
|
|||
|
|
if not interview_content:
|
|||
|
|
print(f" ✗ {position_name} 没有面试题内容")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
# 提取面试题
|
|||
|
|
questions = extract_questions(interview_content)
|
|||
|
|
if not questions:
|
|||
|
|
print(f" ✗ {position_name} 没有有效的面试题")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
print(f" 找到 {len(questions)} 个面试题")
|
|||
|
|
|
|||
|
|
# 读取mock文件
|
|||
|
|
mock_file = 'src/mocks/resumeInterviewMock.js'
|
|||
|
|
with open(mock_file, 'r', encoding='utf-8') as f:
|
|||
|
|
content = f.read()
|
|||
|
|
|
|||
|
|
# 查找产业位置 - questions在positions数组的第一个元素里
|
|||
|
|
search_start = f'"name": "{industry_name}"'
|
|||
|
|
start_pos = content.find(search_start)
|
|||
|
|
|
|||
|
|
if start_pos == -1:
|
|||
|
|
print(f" ✗ 未找到产业:{industry_name}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
# 找到positions数组
|
|||
|
|
positions_pos = content.find('"positions":', start_pos)
|
|||
|
|
if positions_pos == -1 or positions_pos > start_pos + 200:
|
|||
|
|
print(f" ✗ 未找到positions字段")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
# 找到第一个position对象中的questions
|
|||
|
|
first_position = content.find('{', positions_pos + 12) # 跳过"positions": [
|
|||
|
|
if first_position == -1:
|
|||
|
|
print(f" ✗ 未找到position对象")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
# 找到questions数组
|
|||
|
|
questions_pos = content.find('"questions":', first_position)
|
|||
|
|
if questions_pos == -1:
|
|||
|
|
# 检查下一个产业之前是否有questions
|
|||
|
|
next_industry = content.find('"name":', start_pos + 10)
|
|||
|
|
if next_industry == -1:
|
|||
|
|
next_industry = len(content)
|
|||
|
|
|
|||
|
|
if questions_pos == -1 or questions_pos > next_industry:
|
|||
|
|
print(f" ✗ 未找到questions字段")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
# 找到questions数组的开始和结束
|
|||
|
|
array_start = content.find('[', questions_pos)
|
|||
|
|
if array_start == -1:
|
|||
|
|
print(f" ✗ 未找到questions数组")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
# 找到对应的结束括号
|
|||
|
|
bracket_count = 0
|
|||
|
|
in_string = False
|
|||
|
|
escape_next = False
|
|||
|
|
array_end = array_start
|
|||
|
|
|
|||
|
|
for i in range(array_start, len(content)):
|
|||
|
|
char = content[i]
|
|||
|
|
|
|||
|
|
if escape_next:
|
|||
|
|
escape_next = False
|
|||
|
|
continue
|
|||
|
|
|
|||
|
|
if char == '\\':
|
|||
|
|
escape_next = True
|
|||
|
|
continue
|
|||
|
|
|
|||
|
|
if char == '"' and not in_string:
|
|||
|
|
in_string = True
|
|||
|
|
elif char == '"' and in_string:
|
|||
|
|
in_string = False
|
|||
|
|
elif not in_string:
|
|||
|
|
if char == '[':
|
|||
|
|
bracket_count += 1
|
|||
|
|
elif char == ']':
|
|||
|
|
bracket_count -= 1
|
|||
|
|
if bracket_count == 0:
|
|||
|
|
array_end = i
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
# 构建新的questions数组
|
|||
|
|
sub_questions = []
|
|||
|
|
for idx, qa in enumerate(questions, 1):
|
|||
|
|
sub_question = {
|
|||
|
|
"id": f"q{idx}",
|
|||
|
|
"question": qa['question'].replace('"', '\\"'),
|
|||
|
|
"answer": qa['answer'].replace('"', '\\"')
|
|||
|
|
}
|
|||
|
|
sub_questions.append(sub_question)
|
|||
|
|
|
|||
|
|
# 创建新的questions结构
|
|||
|
|
new_questions = [{
|
|||
|
|
"id": "group_q1",
|
|||
|
|
"question": f"# {industry_name}面试题",
|
|||
|
|
"subQuestions": sub_questions
|
|||
|
|
}]
|
|||
|
|
|
|||
|
|
# 生成JSON字符串,使用适当的缩进
|
|||
|
|
new_json = json.dumps(new_questions, ensure_ascii=False, indent=10)
|
|||
|
|
# 调整缩进以匹配文件格式
|
|||
|
|
lines = new_json.split('\n')
|
|||
|
|
adjusted_lines = []
|
|||
|
|
for line in lines:
|
|||
|
|
if line.strip():
|
|||
|
|
adjusted_lines.append(' ' + line) # 添加适当的缩进
|
|||
|
|
new_json = '\n'.join(adjusted_lines).strip()
|
|||
|
|
|
|||
|
|
# 替换内容
|
|||
|
|
new_content = content[:array_start] + new_json + content[array_end+1:]
|
|||
|
|
|
|||
|
|
# 写入文件
|
|||
|
|
with open(mock_file, 'w', encoding='utf-8') as f:
|
|||
|
|
f.write(new_content)
|
|||
|
|
|
|||
|
|
# 验证语法
|
|||
|
|
result = os.popen(f'node -c {mock_file} 2>&1').read()
|
|||
|
|
if result:
|
|||
|
|
print(f" ❌ 语法错误,恢复原内容")
|
|||
|
|
with open(mock_file, 'w', encoding='utf-8') as f:
|
|||
|
|
f.write(content)
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
print(f" ✓ 成功更新")
|
|||
|
|
return True
|
|||
|
|
|
|||
|
|
# 主程序
|
|||
|
|
print("开始批量更新剩余产业的面试题...\n")
|
|||
|
|
|
|||
|
|
# 创建总备份
|
|||
|
|
mock_file = 'src/mocks/resumeInterviewMock.js'
|
|||
|
|
backup_file = f"{mock_file}.backup_all_fixed_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
|
|||
|
|
with open(mock_file, 'r', encoding='utf-8') as f:
|
|||
|
|
original_content = f.read()
|
|||
|
|
with open(backup_file, 'w', encoding='utf-8') as f:
|
|||
|
|
f.write(original_content)
|
|||
|
|
print(f"已创建总备份:{backup_file}\n")
|
|||
|
|
|
|||
|
|
success_count = 0
|
|||
|
|
failed = []
|
|||
|
|
|
|||
|
|
for industry_name, position_name in industry_to_position.items():
|
|||
|
|
print(f"正在更新 {industry_name} ({position_name})...")
|
|||
|
|
if update_industry(industry_name, position_name):
|
|||
|
|
success_count += 1
|
|||
|
|
else:
|
|||
|
|
failed.append(industry_name)
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# 最终验证
|
|||
|
|
print("最终语法验证...")
|
|||
|
|
result = os.popen(f'node -c {mock_file} 2>&1').read()
|
|||
|
|
if result:
|
|||
|
|
print(f"❌ 最终验证失败,恢复备份")
|
|||
|
|
with open(backup_file, 'r', encoding='utf-8') as f:
|
|||
|
|
content = f.read()
|
|||
|
|
with open(mock_file, 'w', encoding='utf-8') as f:
|
|||
|
|
f.write(content)
|
|||
|
|
print("已恢复备份")
|
|||
|
|
else:
|
|||
|
|
print("✓ 所有更新验证通过")
|
|||
|
|
print(f"\n总结:成功更新 {success_count} 个产业")
|
|||
|
|
if failed:
|
|||
|
|
print(f"失败:{', '.join(failed)}")
|