300 lines
12 KiB
Python
300 lines
12 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
import json
|
|||
|
|
import os
|
|||
|
|
from datetime import datetime
|
|||
|
|
|
|||
|
|
# 读取视觉设计岗位简历.json文件获取所有面试题
|
|||
|
|
json_file = '网页未导入数据/视觉设计产业/视觉设计岗位简历.json'
|
|||
|
|
mock_file = 'src/mocks/resumeInterviewMock.js'
|
|||
|
|
|
|||
|
|
print("正在读取所有产业的面试题和答案...")
|
|||
|
|
with open(json_file, 'r', encoding='utf-8') as f:
|
|||
|
|
positions_data = json.load(f)
|
|||
|
|
|
|||
|
|
# 创建产业到面试题的映射
|
|||
|
|
industry_questions = {}
|
|||
|
|
|
|||
|
|
# 产业名称映射(每个岗位对应的产业)
|
|||
|
|
position_to_industry = {
|
|||
|
|
"包装设计师": "包装设计",
|
|||
|
|
"插画师": "插画设计",
|
|||
|
|
"影视灯光": "灯光",
|
|||
|
|
"角色原画师": "动画设计",
|
|||
|
|
"场景原画师": "动画设计",
|
|||
|
|
"二维动画师": "动画设计",
|
|||
|
|
"三维动画师": "动画设计",
|
|||
|
|
"三维动作师": "动画设计",
|
|||
|
|
"分镜绘制": "动画设计",
|
|||
|
|
"特效设计师": "后期特效",
|
|||
|
|
"后期合成": "后期特效",
|
|||
|
|
"剪辑师": "剪辑",
|
|||
|
|
"剪辑助理": "剪辑",
|
|||
|
|
"导演助理": "剪辑",
|
|||
|
|
"品牌视觉内容策划": "品牌设计",
|
|||
|
|
"品牌设计师": "品牌设计",
|
|||
|
|
"标志设计师": "品牌设计",
|
|||
|
|
"平面设计师": "平面设计",
|
|||
|
|
"书籍装帧设计师": "平面设计",
|
|||
|
|
"广告设计师": "平面设计",
|
|||
|
|
"3D建模师": "三维设计",
|
|||
|
|
"三维模型师": "三维设计",
|
|||
|
|
"三维材质师": "三维设计",
|
|||
|
|
"三维灯光师": "三维设计",
|
|||
|
|
"三维绑定师": "三维设计",
|
|||
|
|
"三维渲染师": "三维设计",
|
|||
|
|
"影视摄像": "摄影/摄像",
|
|||
|
|
"影视摄影": "摄影/摄像",
|
|||
|
|
"室内设计师": "室内设计",
|
|||
|
|
"调色师": "调色",
|
|||
|
|
"自媒体运营专员": "新媒体运营",
|
|||
|
|
"新媒体内容策划": "新媒体运营",
|
|||
|
|
"社交媒体运营": "新媒体运营",
|
|||
|
|
"音效设计师": "音频处理",
|
|||
|
|
"音频编辑师": "音频处理",
|
|||
|
|
"配音配乐师": "音频处理",
|
|||
|
|
"导演": "影视节目策划",
|
|||
|
|
"编剧": "影视节目策划",
|
|||
|
|
"直播运营": "直播",
|
|||
|
|
"直播策划": "直播",
|
|||
|
|
"主持人": "直播"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 提取每个岗位的面试题
|
|||
|
|
for position in positions_data:
|
|||
|
|
position_name = position.get("岗位名称", "")
|
|||
|
|
if position_name in position_to_industry:
|
|||
|
|
industry = position_to_industry[position_name]
|
|||
|
|
|
|||
|
|
# 如果这个产业还没有数据,就提取
|
|||
|
|
if industry not in industry_questions:
|
|||
|
|
interview_content = position.get("面试题内容", "")
|
|||
|
|
if 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 or ':' in line_stripped):
|
|||
|
|
# 保存上一个问题
|
|||
|
|
if current_question:
|
|||
|
|
answer = current_answer.strip()
|
|||
|
|
# 限制答案长度
|
|||
|
|
if len(answer) > 500:
|
|||
|
|
cut_point = 500
|
|||
|
|
for sep in ['。', ';', '. ', ',']:
|
|||
|
|
pos = answer[:500].rfind(sep)
|
|||
|
|
if pos > 300:
|
|||
|
|
cut_point = pos + 1
|
|||
|
|
break
|
|||
|
|
answer = answer[:cut_point]
|
|||
|
|
|
|||
|
|
questions.append({
|
|||
|
|
'question': current_question,
|
|||
|
|
'answer': answer if answer else "请根据您的实际经验和项目情况进行回答。"
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
# 提取新问题
|
|||
|
|
if '问题:' in line_stripped:
|
|||
|
|
parts = line_stripped.split('问题:', 1)
|
|||
|
|
current_question = parts[1].strip() if len(parts) > 1 else ""
|
|||
|
|
elif '问题:' in line_stripped:
|
|||
|
|
parts = line_stripped.split('问题:', 1)
|
|||
|
|
current_question = parts[1].strip() if len(parts) > 1 else ""
|
|||
|
|
elif ':' in line_stripped:
|
|||
|
|
parts = line_stripped.split(':', 1)
|
|||
|
|
current_question = parts[1].strip() if len(parts) > 1 else ""
|
|||
|
|
elif '. ' in line_stripped:
|
|||
|
|
parts = line_stripped.split('. ', 1)
|
|||
|
|
current_question = parts[1].strip() if len(parts) > 1 else ""
|
|||
|
|
|
|||
|
|
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 ':' in line_stripped)):
|
|||
|
|
collecting_answer = False
|
|||
|
|
elif 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) > 500:
|
|||
|
|
cut_point = 500
|
|||
|
|
for sep in ['。', ';', '. ', ',']:
|
|||
|
|
pos = answer[:500].rfind(sep)
|
|||
|
|
if pos > 300:
|
|||
|
|
cut_point = pos + 1
|
|||
|
|
break
|
|||
|
|
answer = answer[:cut_point]
|
|||
|
|
|
|||
|
|
questions.append({
|
|||
|
|
'question': current_question,
|
|||
|
|
'answer': answer if answer else "请根据您的实际经验和项目情况进行回答。"
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if questions:
|
|||
|
|
industry_questions[industry] = questions
|
|||
|
|
print(f"提取了 {industry} 的 {len(questions)} 个问题")
|
|||
|
|
|
|||
|
|
# 创建备份
|
|||
|
|
backup_file = f"{mock_file}.backup_other_safe_{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"\n已创建备份:{backup_file}")
|
|||
|
|
|
|||
|
|
# 逐个产业更新
|
|||
|
|
print("\n开始逐个更新产业面试题...")
|
|||
|
|
successful_updates = []
|
|||
|
|
failed_updates = []
|
|||
|
|
|
|||
|
|
# 产业ID映射
|
|||
|
|
industry_id_map = {
|
|||
|
|
"包装设计": 2,
|
|||
|
|
"插画设计": 3,
|
|||
|
|
"灯光": 4,
|
|||
|
|
"动画设计": 5,
|
|||
|
|
"后期特效": 6,
|
|||
|
|
"剪辑": 7,
|
|||
|
|
"品牌设计": 8,
|
|||
|
|
"平面设计": 9,
|
|||
|
|
"三维设计": 10,
|
|||
|
|
"摄影/摄像": 11,
|
|||
|
|
"室内设计": 12,
|
|||
|
|
"调色": 13,
|
|||
|
|
"新媒体运营": 14,
|
|||
|
|
"音频处理": 15,
|
|||
|
|
"影视节目策划": 16,
|
|||
|
|
"直播": 17
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for industry, questions in industry_questions.items():
|
|||
|
|
if industry == "UI设计":
|
|||
|
|
continue # 跳过已更新的UI设计
|
|||
|
|
|
|||
|
|
print(f"\n处理 {industry}...")
|
|||
|
|
|
|||
|
|
# 读取当前内容
|
|||
|
|
with open(mock_file, 'r', encoding='utf-8') as f:
|
|||
|
|
content = f.read()
|
|||
|
|
|
|||
|
|
# 构建subQuestions数组
|
|||
|
|
sub_questions = []
|
|||
|
|
for i, qa in enumerate(questions, 1):
|
|||
|
|
question_text = qa['question'].replace('"', '\\"').replace('\n', ' ')
|
|||
|
|
answer_text = qa['answer'].replace('"', '\\"').replace('\n', ' ')
|
|||
|
|
|
|||
|
|
industry_num = industry_id_map.get(industry, 2)
|
|||
|
|
sub_questions.append({
|
|||
|
|
"id": f"q{industry_num}_{i}",
|
|||
|
|
"question": question_text,
|
|||
|
|
"answer": answer_text
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
# 构建完整的questions结构
|
|||
|
|
new_questions_obj = {
|
|||
|
|
"id": f"group_q{industry_id_map.get(industry, 2)}",
|
|||
|
|
"question": f"# {industry}面试题",
|
|||
|
|
"subQuestions": sub_questions
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 查找并替换该产业的questions数组
|
|||
|
|
import re
|
|||
|
|
|
|||
|
|
# 查找产业的questions位置
|
|||
|
|
pattern = rf'("name":\s*"{re.escape(industry)}"[^}}]*?"questions":\s*\[)'
|
|||
|
|
match = re.search(pattern, content, re.DOTALL)
|
|||
|
|
|
|||
|
|
if match:
|
|||
|
|
# 找到questions数组的开始
|
|||
|
|
start_pos = match.end()
|
|||
|
|
|
|||
|
|
# 找到对应的结束括号
|
|||
|
|
bracket_count = 1
|
|||
|
|
end_pos = start_pos
|
|||
|
|
while bracket_count > 0 and end_pos < len(content):
|
|||
|
|
if content[end_pos] == '[':
|
|||
|
|
bracket_count += 1
|
|||
|
|
elif content[end_pos] == ']':
|
|||
|
|
bracket_count -= 1
|
|||
|
|
end_pos += 1
|
|||
|
|
|
|||
|
|
if bracket_count == 0:
|
|||
|
|
# 生成新的questions数组内容
|
|||
|
|
questions_json = json.dumps([new_questions_obj], ensure_ascii=False, indent=6)
|
|||
|
|
# 调整缩进
|
|||
|
|
lines = questions_json.split('\n')
|
|||
|
|
formatted_lines = []
|
|||
|
|
for line in lines:
|
|||
|
|
if line.strip():
|
|||
|
|
formatted_lines.append(' ' + line)
|
|||
|
|
else:
|
|||
|
|
formatted_lines.append('')
|
|||
|
|
questions_json = '\n'.join(formatted_lines)
|
|||
|
|
|
|||
|
|
# 替换内容
|
|||
|
|
new_content = content[:start_pos-1] + questions_json + content[end_pos-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" ❌ {industry} 更新后语法错误,回滚")
|
|||
|
|
with open(mock_file, 'w', encoding='utf-8') as f:
|
|||
|
|
f.write(content) # 恢复原内容
|
|||
|
|
failed_updates.append(industry)
|
|||
|
|
else:
|
|||
|
|
print(f" ✓ {industry} 更新成功 ({len(sub_questions)} 个问题)")
|
|||
|
|
successful_updates.append(industry)
|
|||
|
|
else:
|
|||
|
|
print(f" ✗ 未能正确解析 {industry} 的questions数组")
|
|||
|
|
failed_updates.append(industry)
|
|||
|
|
else:
|
|||
|
|
print(f" ✗ 未找到产业:{industry}")
|
|||
|
|
failed_updates.append(industry)
|
|||
|
|
|
|||
|
|
# 输出结果
|
|||
|
|
print("\n" + "="*50)
|
|||
|
|
print("更新完成!")
|
|||
|
|
print(f"成功更新:{len(successful_updates)} 个产业")
|
|||
|
|
if successful_updates:
|
|||
|
|
print(" - " + "\n - ".join(successful_updates))
|
|||
|
|
if failed_updates:
|
|||
|
|
print(f"\n失败更新:{len(failed_updates)} 个产业")
|
|||
|
|
print(" - " + "\n - ".join(failed_updates))
|
|||
|
|
|
|||
|
|
# 最终语法验证
|
|||
|
|
print("\n最终语法验证...")
|
|||
|
|
result = os.popen(f'node -c {mock_file} 2>&1').read()
|
|||
|
|
if result:
|
|||
|
|
print(f"❌ 最终文件有语法错误")
|
|||
|
|
print(result)
|
|||
|
|
else:
|
|||
|
|
print("✓ 所有语法验证通过")
|
|||
|
|
print("视觉设计产业面试题更新任务完成!")
|