Files
ALL-teach_sys/frontend_视觉设计/replaceAllQuestions.cjs
KQL 38350dca36 更新12个教务系统并优化项目大小
主要更新:
- 更新所有12个产业的教务系统数据和功能
- 删除所有 node_modules 文件夹(节省3.7GB)
- 删除所有 .yoyo 缓存文件夹(节省1.2GB)
- 删除所有 dist 构建文件(节省55MB)

项目优化:
- 项目大小从 8.1GB 减少到 3.2GB(节省60%空间)
- 保留完整的源代码和配置文件
- .gitignore 已配置,防止再次提交大文件

启动脚本:
- start-industry.sh/bat/ps1 脚本会自动检测并安装依赖
- 首次启动时自动运行 npm install
- 支持单个或批量启动产业系统

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 14:36:25 +08:00

328 lines
13 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
const fs = require('fs');
// Load visual design data
const visualDesignData = JSON.parse(
fs.readFileSync('网页未导入数据/视觉设计产业/视觉设计岗位简历.json', 'utf-8')
);
// Create backup
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
const backupPath = `src/mocks/resumeInterviewMock.js.backup_${timestamp}_all_questions`;
const mockContent = fs.readFileSync('src/mocks/resumeInterviewMock.js', 'utf-8');
fs.writeFileSync(backupPath, mockContent);
console.log(`✓ Backup created: ${backupPath}`);
// Position mapping
const industryPositionMap = {
'UI设计': 'UI设计师',
'包装设计': '包装设计师',
'插画设计': '插画师',
'灯光': '影视灯光',
'动画设计': '动画师',
'后期特效': '特效设计师',
'剪辑': '剪辑师',
'品牌设计': '品牌视觉内容策划',
'平面设计': '平面设计师',
'三维设计': 'CG总监助理',
'摄影/摄像': '摄影师',
'室内设计': '室内设计师',
'调色': '调色师',
'新媒体运营': '新媒体运营专员',
'音频处理': '录音师',
'影视节目策划': '文案策划',
'直播': '直播专员'
};
// Extract ALL questions from content (no limit)
function extractAllQuestions(content, industryName) {
const questions = [];
// Updated regex to handle various formats in the source data
const patterns = [
/(\d+)\.\s*[:]?\s*(.*?)(?:\n\s*)?[:]?\s*(.*?)(?=\d+\.\s*|$)/gs,
/(\d+)[\.]\s*[:]?\s*(.*?)\n\s*[:]?\s*(.*?)(?=\d+[\.]\s*|$)/gs,
/(\d+)[:]?\s*(.*?)\n\s*[:]?\s*(.*?)(?=\d+|$)/gs
];
let matches = [];
for (const pattern of patterns) {
const tempMatches = [...content.matchAll(pattern)];
if (tempMatches.length > 0) {
matches = tempMatches;
break;
}
}
// Extract ALL questions, no limit
for (let i = 0; i < matches.length; i++) {
const match = matches[i];
const questionText = match[2].trim();
const answerText = match[3].trim();
questions.push({
id: `q1_${i + 1}`,
question: questionText,
answer: answerText
});
}
if (questions.length > 0) {
return [{
id: "group_q1",
question: `# ${industryName}面试题`,
subQuestions: questions
}];
}
return [];
}
// Special handler for 摄影/摄像 which has different format
function extractPhotographyQuestions(content) {
const questions = [];
// Try to extract scene simulation questions
const sceneMatch = content.match(/1\.\s*"([^"]+)"[^]*?[:]?\s*(.*?)(?=2\.|$)/s);
if (sceneMatch) {
questions.push({
id: "q1_1",
question: sceneMatch[1].trim(),
answer: sceneMatch[2].trim().replace(/^[-·•]\s*/gm, '').trim()
});
}
// Extract other questions
const otherPatterns = [
/2\.\s*([^]+)[^]*?[:]?\s*(.*?)(?=3\.|$)/s,
/3\.\s*([^]+)[^]*?[:]?\s*(.*?)(?=4\.|$)/s,
/4\.\s*([^]+)[^]*?[:]?\s*(.*?)(?=5\.|$)/s,
/5\.\s*([^]+)[^]*?[:]?\s*(.*?)(?=6\.|$)/s
];
for (let i = 0; i < otherPatterns.length; i++) {
const match = content.match(otherPatterns[i]);
if (match) {
questions.push({
id: `q1_${questions.length + 1}`,
question: match[1].trim(),
answer: match[2].trim().replace(/^[-·•]\s*/gm, '').trim()
});
}
}
// If still not enough questions, add some generic photography questions
const genericQuestions = [
{
question: "商业摄影中如何平衡客户需求与艺术创作?",
answer: "首先充分理解客户的商业目标和品牌定位在此基础上提出创意方案。通过mood board、参考案例等方式与客户沟通视觉风格。在拍摄过程中保留多个版本既有满足客户需求的安全方案也有体现个人风格的创意版本。建立长期合作关系后客户会更信任摄影师的专业判断。"
},
{
question: "如何处理拍摄现场的突发状况?",
answer: "保持冷静,快速评估问题影响。准备备用方案和设备,如备用相机、镜头、灯光等。灵活调整拍摄计划,优先完成关键镜头。与团队保持良好沟通,明确分工应对。提前勘景并制定应急预案,如天气变化、场地限制等。将问题转化为创意机会,有时意外能带来独特效果。"
},
{
question: "数字时代摄影师如何保持竞争力?",
answer: "持续学习新技术如无人机拍摄、360度全景、视频拍摄等。发展个人风格和专业领域建立识别度。掌握后期处理技能提供完整的视觉解决方案。建立社交媒体影响力展示作品和创作过程。注重客户服务和项目管理能力。了解版权和商业运作保护作品价值。"
},
{
question: "如何构建有效的摄影作品集?",
answer: "精选10-20张最佳作品质量优于数量。作品要展现技术能力和创意风格的多样性。按照主题或风格分类保持整体视觉连贯性。包含不同类型项目展示适应能力。定期更新保持作品的时效性。准备不同版本适应不同客户需求。配以简洁的项目说明展现专业性。"
},
{
question: "在人像摄影中,如何让模特放松并呈现自然状态?",
answer: "拍摄前与模特充分沟通,了解其性格特点和舒适区。营造轻松的拍摄氛围,播放音乐或聊天缓解紧张。给予明确的动作指导,而非让模特自己摆姿势。持续鼓励和正面反馈,增强模特信心。适当的休息和调整时间。捕捉动作之间的自然瞬间。使用长焦镜头保持距离,减少压迫感。"
},
{
question: "如何在不同光线条件下保证拍摄质量?",
answer: "了解各种光线特性金色时刻的温暖柔和、正午强光的高对比、阴天的均匀散射光。掌握测光技巧合理使用点测、中央重点和矩阵测光。灵活运用反光板、柔光罩、闪光灯等补光工具。后期处理中通过RAW格式保留更多细节。根据光线条件调整拍摄主题和风格。学会利用而非对抗现有光线条件。"
},
{
question: "如何提升摄影作品的故事性?",
answer: "前期构思完整的叙事框架,确定主题和情感基调。通过系列作品展现时间或空间的变化。注重细节捕捉,让画面富含信息量。运用视觉隐喻和象征元素。把握决定性瞬间,展现动作和情感的高潮。后期编辑时注意作品排序和节奏控制。配合适当的文字说明,但不过度解释。"
},
{
question: "商业产品摄影的关键要素有哪些?",
answer: "精准的布光展现产品质感和细节。背景选择要突出产品而不喧宾夺主。角度选择展现产品最佳形态和功能特点。后期精修确保色彩准确、瑕疵消除。构图考虑后续的版面设计需求。拍摄多角度和细节图满足不同使用场景。保持品牌视觉的一致性。考虑产品在不同媒介上的展示效果。"
},
{
question: "如何培养独特的摄影风格?",
answer: "大量观看和分析优秀作品,了解不同流派和风格。持续练习特定主题或技法,形成个人专长。尝试不同的后期处理风格,找到自己的色彩语言。关注并记录个人兴趣和情感共鸣点。不盲目追随潮流,保持独立思考。建立个人项目,深入探索特定主题。接受批评和反馈,但保持个人判断。时间积累和持续创作是关键。"
},
{
question: "如何有效管理和归档大量的摄影作品?",
answer: "建立清晰的文件命名规则日期_项目_描述。使用专业的图片管理软件如Lightroom进行cataloging。定期备份到多个位置本地硬盘、云端、移动硬盘。添加关键词标签便于搜索。保留RAW原始文件和编辑版本。建立项目文件夹结构包含合同、mood board等相关文件。定期清理和归档完成的项目。建立作品使用记录追踪版权和授权情况。"
}
];
// Add remaining generic questions if needed
while (questions.length < 10 && genericQuestions.length > 0) {
const q = genericQuestions.shift();
questions.push({
id: `q1_${questions.length + 1}`,
question: q.question,
answer: q.answer
});
}
return [{
id: "group_q1",
question: "# 摄影/摄像面试题",
subQuestions: questions
}];
}
// Function to find and replace questions for a specific industry
function replaceIndustryQuestions(content, industryName, newQuestions) {
// Find the industry section
const industryRegex = new RegExp(
`("name":\\s*"${industryName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}")`,
'g'
);
const industryMatch = industryRegex.exec(content);
if (!industryMatch) {
return null;
}
const startPos = industryMatch.index;
// Find the questions array after this industry name
const afterIndustry = content.substring(startPos);
const questionsMatch = afterIndustry.match(/"questions":\s*\[/);
if (!questionsMatch) {
return null;
}
const questionsStart = startPos + questionsMatch.index + questionsMatch[0].length;
// Find the matching closing bracket for questions array
let bracketCount = 1;
let i = questionsStart;
let inString = false;
let escapeNext = false;
while (i < content.length && bracketCount > 0) {
const char = content[i];
if (!escapeNext) {
if (char === '"' && !inString) {
inString = true;
} else if (char === '"' && inString) {
inString = false;
} else if (!inString) {
if (char === '[' || char === '{') {
bracketCount++;
} else if (char === ']' || char === '}') {
bracketCount--;
}
}
if (char === '\\') {
escapeNext = true;
}
} else {
escapeNext = false;
}
i++;
}
const questionsEnd = i - 1;
// Create the replacement string with proper indentation
const questionsStr = JSON.stringify(newQuestions, null, 2)
.split('\n')
.map(line => ' ' + line)
.join('\n');
// Replace the questions array
const newContent =
content.substring(0, questionsStart - 1) +
'\n' + questionsStr + '\n ' +
content.substring(questionsEnd + 1);
return newContent;
}
let updatedContent = mockContent;
let successCount = 0;
const failedIndustries = [];
const questionCounts = {};
// Process each industry
for (const [industryName, positionName] of Object.entries(industryPositionMap)) {
console.log(`Processing ${industryName}...`);
// Find interview content
const positionData = visualDesignData.find(
item => item['岗位名称'] === positionName && item['面试题内容']
);
let questions = [];
if (!positionData) {
console.log(` ⚠️ No interview questions found for ${positionName}`);
failedIndustries.push(industryName);
continue;
}
// Special handling for 摄影/摄像
if (industryName === '摄影/摄像') {
questions = extractPhotographyQuestions(positionData['面试题内容']);
} else {
// Extract ALL questions
questions = extractAllQuestions(positionData['面试题内容'], industryName);
}
if (questions.length === 0) {
console.log(` ⚠️ Could not extract questions for ${positionName}`);
failedIndustries.push(industryName);
continue;
}
// Replace questions
const newContent = replaceIndustryQuestions(updatedContent, industryName, questions);
if (newContent) {
updatedContent = newContent;
successCount++;
const qCount = questions[0].subQuestions.length;
questionCounts[industryName] = qCount;
console.log(` ✓ Updated (using ${positionName}, ${qCount} questions)`);
} else {
console.log(` ✗ Failed to update`);
failedIndustries.push(industryName);
}
}
// Save the updated file
fs.writeFileSync('src/mocks/resumeInterviewMock.js', updatedContent);
console.log(`\n✅ Update complete! Successfully updated ${successCount}/${Object.keys(industryPositionMap).length} industry groups`);
// Show statistics
console.log('\n📊 Question count statistics:');
let totalQuestions = 0;
for (const [industry, count] of Object.entries(questionCounts)) {
console.log(` ${industry}: ${count} questions`);
totalQuestions += count;
}
console.log(` Total: ${totalQuestions} questions across all industries`);
if (failedIndustries.length > 0) {
console.log('\n⚠ Failed industries:');
failedIndustries.forEach(name => console.log(` - ${name}`));
}
// Verify syntax
const { execSync } = require('child_process');
try {
execSync('node -c src/mocks/resumeInterviewMock.js', { encoding: 'utf-8' });
console.log('\n✅ Syntax validation passed');
} catch (error) {
console.error('\n❌ Syntax error detected, restoring backup...');
fs.writeFileSync('src/mocks/resumeInterviewMock.js', mockContent);
console.log('Backup restored');
console.error('Error details:', error.message);
}