feat: 完整的教务系统功能更新
- 添加面试模拟功能:视频播放、评分展示、滑动交互 - 实现1v1求职策略:导师信息更新、直播纪要功能 - 完善项目库和简历面试功能:添加详细的mock数据 - 更新课后作业页面:灰度显示、课程链接 - 个人档案和主页数据:万圆的完整个人信息 - 修复各类语法错误和数据结构问题 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
38
.claude/settings.local.json
Normal file
38
.claude/settings.local.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"mcp__serena__replace_regex",
|
||||
"mcp__ide__getDiagnostics",
|
||||
"Bash(node:*)",
|
||||
"Bash(cat:*)",
|
||||
"Bash(grep:*)",
|
||||
"Bash(npx eslint:*)",
|
||||
"Bash(npm run dev:*)",
|
||||
"Bash(python3:*)",
|
||||
"Bash(pip3 install:*)",
|
||||
"Bash(/usr/bin/python3:*)",
|
||||
"mcp__serena__think_about_whether_you_are_done",
|
||||
"mcp__serena__activate_project",
|
||||
"Bash(npm install:*)",
|
||||
"Bash(pnpm add:*)",
|
||||
"Bash(lsof:*)",
|
||||
"mcp__serena__search_for_pattern",
|
||||
"mcp__serena__find_symbol",
|
||||
"Bash(npx babel-node:*)",
|
||||
"Bash(curl:*)",
|
||||
"Bash(sed:*)",
|
||||
"Read(///**)",
|
||||
"mcp__serena__find_file",
|
||||
"mcp__serena__list_dir",
|
||||
"mcp__serena__read_file",
|
||||
"mcp__serena__replace_symbol_body",
|
||||
"mcp__serena__execute_shell_command",
|
||||
"mcp__serena__get_symbols_overview",
|
||||
"mcp__serena__create_text_file",
|
||||
"Bash(git remote add:*)",
|
||||
"Bash(git add:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
BIN
.serena/cache/typescript/document_symbols_cache_v23-06-25.pkl
vendored
Normal file
BIN
.serena/cache/typescript/document_symbols_cache_v23-06-25.pkl
vendored
Normal file
Binary file not shown.
68
.serena/project.yml
Normal file
68
.serena/project.yml
Normal file
@@ -0,0 +1,68 @@
|
||||
# language of the project (csharp, python, rust, java, typescript, go, cpp, or ruby)
|
||||
# * For C, use cpp
|
||||
# * For JavaScript, use typescript
|
||||
# Special requirements:
|
||||
# * csharp: Requires the presence of a .sln file in the project folder.
|
||||
language: typescript
|
||||
|
||||
# whether to use the project's gitignore file to ignore files
|
||||
# Added on 2025-04-07
|
||||
ignore_all_files_in_gitignore: true
|
||||
# list of additional paths to ignore
|
||||
# same syntax as gitignore, so you can use * and **
|
||||
# Was previously called `ignored_dirs`, please update your config if you are using that.
|
||||
# Added (renamed) on 2025-04-07
|
||||
ignored_paths: []
|
||||
|
||||
# whether the project is in read-only mode
|
||||
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
|
||||
# Added on 2025-04-18
|
||||
read_only: false
|
||||
|
||||
|
||||
# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
|
||||
# Below is the complete list of tools for convenience.
|
||||
# To make sure you have the latest list of tools, and to view their descriptions,
|
||||
# execute `uv run scripts/print_tool_overview.py`.
|
||||
#
|
||||
# * `activate_project`: Activates a project by name.
|
||||
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
|
||||
# * `create_text_file`: Creates/overwrites a file in the project directory.
|
||||
# * `delete_lines`: Deletes a range of lines within a file.
|
||||
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
|
||||
# * `execute_shell_command`: Executes a shell command.
|
||||
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
|
||||
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
|
||||
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
|
||||
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
|
||||
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
|
||||
# * `initial_instructions`: Gets the initial instructions for the current project.
|
||||
# Should only be used in settings where the system prompt cannot be set,
|
||||
# e.g. in clients you have no control over, like Claude Desktop.
|
||||
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
|
||||
# * `insert_at_line`: Inserts content at a given line in a file.
|
||||
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
|
||||
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
|
||||
# * `list_memories`: Lists memories in Serena's project-specific memory store.
|
||||
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
|
||||
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
|
||||
# * `read_file`: Reads a file within the project directory.
|
||||
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
|
||||
# * `remove_project`: Removes a project from the Serena configuration.
|
||||
# * `replace_lines`: Replaces a range of lines within a file with new content.
|
||||
# * `replace_symbol_body`: Replaces the full definition of a symbol.
|
||||
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
|
||||
# * `search_for_pattern`: Performs a search for a pattern in the project.
|
||||
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
|
||||
# * `switch_modes`: Activates modes by providing a list of their names
|
||||
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
|
||||
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
|
||||
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
|
||||
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
|
||||
excluded_tools: []
|
||||
|
||||
# initial prompt for the project. It will always be given to the LLM upon activating the project
|
||||
# (contrary to the memories, which are loaded on demand).
|
||||
initial_prompt: ""
|
||||
|
||||
project_name: "frontend"
|
||||
BIN
1v1定制求职策略锁定.png
Normal file
BIN
1v1定制求职策略锁定.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 457 KiB |
@@ -22,6 +22,7 @@
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-echarts": "^0.1.1",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-redux": "^9.2.0",
|
||||
"react-router-dom": "^7.7.1",
|
||||
"redux": "^5.0.1"
|
||||
|
||||
684
pnpm-lock.yaml
generated
684
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,7 @@ export default ({ className = "", isLock = false }) => {
|
||||
src="//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp"
|
||||
/>
|
||||
</Avatar>
|
||||
<span className="teacher-name">赵老师</span>
|
||||
<span className="teacher-name">魏立慧</span>
|
||||
<span className="teacher-tag">教育体系认知</span>
|
||||
<div className="living-data">
|
||||
<div className="living-data-item">
|
||||
@@ -54,7 +54,7 @@ export default ({ className = "", isLock = false }) => {
|
||||
</div>
|
||||
<div className="living-data-item">
|
||||
<span>观看</span>
|
||||
<span>300000人</span>
|
||||
<span>3000人</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -63,17 +63,16 @@ export default ({ className = "", isLock = false }) => {
|
||||
<div className="courses-video-player-teacher-introduce">
|
||||
<p className="title icon1">导师介绍</p>
|
||||
<p className="teacher-introduce">
|
||||
这是一段导师介绍这是一段导师介绍这是一段导师介绍这是一段导师介绍这是一段导师介绍这是
|
||||
一段导师介绍这是一段导师介绍这是一段导师介绍这是一段导师介绍这是
|
||||
一段导师介绍这是一段导师介绍这是一段导师介绍这是一段导师介绍
|
||||
企业资深一线HR,专注于为求职者提供一对一的个性化指导。通过真实招聘视角,深入剖析个人优势与短板、传授面试技巧、规划职业定位与发展路径,帮助学生快速提升求职竞争力。求职策略以实用落地为核心,注重互动交流与角色定位,让学员在轻松氛围中获得直击痛点的求职策略。
|
||||
</p>
|
||||
</div>
|
||||
<div className="courses-video-player-teacher-tags">
|
||||
<p className="title icon2">教师专长</p>
|
||||
<ul className="teacher-tags">
|
||||
<li>一般般</li>
|
||||
<li>一般般</li>
|
||||
<li>一般般</li>
|
||||
<li>深谙用人逻辑</li>
|
||||
<li>擅长挖掘优势</li>
|
||||
<li>沟通真诚自然</li>
|
||||
<li>点评直击要害</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
74
src/components/FileIcon/index.css
Normal file
74
src/components/FileIcon/index.css
Normal file
@@ -0,0 +1,74 @@
|
||||
.file-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.file-icon-fold {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 0 12px 12px 0;
|
||||
border-color: transparent #fff transparent transparent;
|
||||
}
|
||||
|
||||
.file-icon-text {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
/* PDF - 红色 */
|
||||
.file-icon-pdf {
|
||||
background: linear-gradient(135deg, #ff4d4d 0%, #cc0000 100%);
|
||||
}
|
||||
|
||||
.file-icon-pdf .file-icon-fold {
|
||||
border-right-color: #ffcccc;
|
||||
}
|
||||
|
||||
/* Word文档 - 蓝色 */
|
||||
.file-icon-doc {
|
||||
background: linear-gradient(135deg, #2196f3 0%, #1565c0 100%);
|
||||
}
|
||||
|
||||
.file-icon-doc .file-icon-fold {
|
||||
border-right-color: #bbdefb;
|
||||
}
|
||||
|
||||
/* PPT - 橙色 */
|
||||
.file-icon-ppt {
|
||||
background: linear-gradient(135deg, #ff9800 0%, #e65100 100%);
|
||||
}
|
||||
|
||||
.file-icon-ppt .file-icon-fold {
|
||||
border-right-color: #ffe0b2;
|
||||
}
|
||||
|
||||
/* Excel - 绿色 */
|
||||
.file-icon-excel {
|
||||
background: linear-gradient(135deg, #4caf50 0%, #2e7d32 100%);
|
||||
}
|
||||
|
||||
.file-icon-excel .file-icon-fold {
|
||||
border-right-color: #c8e6c9;
|
||||
}
|
||||
|
||||
/* 默认 - 灰色 */
|
||||
.file-icon-default {
|
||||
background: linear-gradient(135deg, #9e9e9e 0%, #616161 100%);
|
||||
}
|
||||
|
||||
.file-icon-default .file-icon-fold {
|
||||
border-right-color: #e0e0e0;
|
||||
}
|
||||
48
src/components/FileIcon/index.jsx
Normal file
48
src/components/FileIcon/index.jsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import "./index.css";
|
||||
|
||||
const FileIcon = ({ type = "doc" }) => {
|
||||
const getIconClass = () => {
|
||||
switch(type) {
|
||||
case 'pdf':
|
||||
return 'file-icon-pdf';
|
||||
case 'doc':
|
||||
case 'docx':
|
||||
return 'file-icon-doc';
|
||||
case 'ppt':
|
||||
case 'pptx':
|
||||
return 'file-icon-ppt';
|
||||
case 'excel':
|
||||
case 'xlsx':
|
||||
return 'file-icon-excel';
|
||||
default:
|
||||
return 'file-icon-default';
|
||||
}
|
||||
};
|
||||
|
||||
const getIconText = () => {
|
||||
switch(type) {
|
||||
case 'pdf':
|
||||
return 'PDF';
|
||||
case 'doc':
|
||||
case 'docx':
|
||||
return 'DOC';
|
||||
case 'ppt':
|
||||
case 'pptx':
|
||||
return 'PPT';
|
||||
case 'excel':
|
||||
case 'xlsx':
|
||||
return 'XLS';
|
||||
default:
|
||||
return 'FILE';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`file-icon ${getIconClass()}`}>
|
||||
<div className="file-icon-fold"></div>
|
||||
<div className="file-icon-text">{getIconText()}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FileIcon;
|
||||
@@ -1,43 +1,52 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { mockData } from "@/data/mockData";
|
||||
import "./index.css";
|
||||
|
||||
const LiveSummary = ({ className = "", showBtn = false, isLiving = true }) => {
|
||||
const navigate = useNavigate();
|
||||
const { jobStrategyNotes } = mockData;
|
||||
|
||||
const handleClickBtn = () => {
|
||||
navigate("/job-strategy-detail");
|
||||
};
|
||||
|
||||
// 根据type分组keyPoints
|
||||
const groupedPoints = jobStrategyNotes.keyPoints.reduce((acc, point) => {
|
||||
const typeMap = {
|
||||
strategy: "策略建议",
|
||||
advice: "专家建议",
|
||||
technique: "核心技巧",
|
||||
timeline: "时间规划",
|
||||
qa: "答疑解惑"
|
||||
};
|
||||
|
||||
const groupName = typeMap[point.type] || point.type;
|
||||
|
||||
if (!acc[groupName]) {
|
||||
acc[groupName] = [];
|
||||
}
|
||||
acc[groupName].push(point);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return (
|
||||
<div className={`${className} live-summary-wrapper`}>
|
||||
<p className={`live-summary-title ${!isLiving && "not-living"}`}>
|
||||
直播摘要
|
||||
{jobStrategyNotes.title}
|
||||
</p>
|
||||
<ul className="live-summary-list">
|
||||
<li className="live-summary-item">
|
||||
<p className="live-summary-item-title">通用技巧</p>
|
||||
{Object.entries(groupedPoints).slice(0, 3).map(([groupName, points]) => (
|
||||
<li className="live-summary-item" key={groupName}>
|
||||
<p className="live-summary-item-title">{groupName}</p>
|
||||
<ul className="live-summary-item-content-list">
|
||||
<li className="live-summary-item-content-item">1. 通用技巧1</li>
|
||||
<li className="live-summary-item-content-item">1. 通用技巧1</li>
|
||||
<li className="live-summary-item-content-item">1. 通用技巧1</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li className="live-summary-item">
|
||||
<p className="live-summary-item-title">通用技巧</p>
|
||||
<ul className="live-summary-item-content-list">
|
||||
<li className="live-summary-item-content-item">1. 通用技巧1</li>
|
||||
<li className="live-summary-item-content-item">1. 通用技巧1</li>
|
||||
<li className="live-summary-item-content-item">1. 通用技巧1</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li className="live-summary-item">
|
||||
<p className="live-summary-item-title">通用技巧</p>
|
||||
<ul className="live-summary-item-content-list">
|
||||
<li className="live-summary-item-content-item">1. 通用技巧1</li>
|
||||
<li className="live-summary-item-content-item">1. 通用技巧1</li>
|
||||
<li className="live-summary-item-content-item">1. 通用技巧1</li>
|
||||
{points.slice(0, 3).map((point) => (
|
||||
<li className="live-summary-item-content-item" key={point.id}>
|
||||
<span style={{fontWeight: "600"}}>{point.time}</span> - {point.title}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{showBtn && (
|
||||
<div
|
||||
|
||||
1917
src/data/mockData.js
1917
src/data/mockData.js
File diff suppressed because it is too large
Load Diff
3575
src/data/mockData.js.backup_before_csv
Normal file
3575
src/data/mockData.js.backup_before_csv
Normal file
File diff suppressed because it is too large
Load Diff
4362
src/data/mockData.js.backup_before_remove_iot
Normal file
4362
src/data/mockData.js.backup_before_remove_iot
Normal file
File diff suppressed because it is too large
Load Diff
17
src/mocks/dashboardMock.js
Normal file
17
src/mocks/dashboardMock.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import { mockData } from "@/data/mockData";
|
||||
|
||||
// Mock Dashboard Statistics
|
||||
export const getDashboardStatisticsMock = () => {
|
||||
return {
|
||||
success: true,
|
||||
data: mockData.dashboardStatistics,
|
||||
};
|
||||
};
|
||||
|
||||
// Mock Profile Overview
|
||||
export const getProfileOverviewMock = () => {
|
||||
return {
|
||||
success: true,
|
||||
data: mockData.profileOverview,
|
||||
};
|
||||
};
|
||||
487
src/mocks/projectLibraryMock.js
Normal file
487
src/mocks/projectLibraryMock.js
Normal file
File diff suppressed because one or more lines are too long
5507
src/mocks/resumeInterviewMock.js
Normal file
5507
src/mocks/resumeInterviewMock.js
Normal file
File diff suppressed because it is too large
Load Diff
5145
src/mocks/resumeInterviewMock.js.backup
Normal file
5145
src/mocks/resumeInterviewMock.js.backup
Normal file
File diff suppressed because it is too large
Load Diff
6369
src/mocks/resumeInterviewMock.js.backup2
Normal file
6369
src/mocks/resumeInterviewMock.js.backup2
Normal file
File diff suppressed because it is too large
Load Diff
5638
src/mocks/resumeInterviewMock.js.backup3
Normal file
5638
src/mocks/resumeInterviewMock.js.backup3
Normal file
File diff suppressed because it is too large
Load Diff
7372
src/mocks/resumeInterviewMock.js.backup_final
Normal file
7372
src/mocks/resumeInterviewMock.js.backup_final
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ import { useState, useCallback } from "react";
|
||||
import JobList from "@/pages/CompanyJobsPage/components/JobList";
|
||||
import InfiniteScroll from "@/components/InfiniteScroll";
|
||||
import { getJobsList } from "@/services";
|
||||
import { mapJobList } from "@/utils/dataMapper";
|
||||
|
||||
import "./index.css";
|
||||
|
||||
const PAGE_SIZE = 20;
|
||||
@@ -19,9 +19,9 @@ const CompanyJobsListPage = () => {
|
||||
isActive: true,
|
||||
});
|
||||
if (res.success) {
|
||||
const mappedJobs = mapJobList(res.data);
|
||||
// Mock数据已经是前端格式,不需要映射
|
||||
setJobs((prevList) => {
|
||||
const newList = [...prevList, ...mappedJobs];
|
||||
const newList = [...prevList, ...res.data];
|
||||
if (res.total === newList?.length) {
|
||||
setListHasMore(false);
|
||||
} else {
|
||||
|
||||
@@ -1,26 +1,40 @@
|
||||
import { useState, useCallback } from "react";
|
||||
import { useState, useCallback, useEffect } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { Input } from "@arco-design/web-react";
|
||||
import Modal from "@/components/Modal";
|
||||
import InfiniteScroll from "@/components/InfiniteScroll";
|
||||
import toast from "@/components/Toast";
|
||||
import FILEICON from "@/assets/images/CompanyJobsPage/file_icon.png";
|
||||
import ResumeInfoModal from "../ResumeInfoModal";
|
||||
import { getResumesList } from "@/services";
|
||||
import { getResumesList, submitResume, getPageData } from "@/services";
|
||||
import "./index.css";
|
||||
|
||||
const InputSearch = Input.Search;
|
||||
const PAGE_SIZE = 10;
|
||||
|
||||
export default ({ visible, onClose, data }) => {
|
||||
export default ({ visible, onClose, data, directToResume = false }) => {
|
||||
const studentInfo = useSelector((state) => state.student.studentInfo);
|
||||
const [resumeModalShow, setResumeModalShow] = useState(false);
|
||||
const [resumeModalShow, setResumeModalShow] = useState(directToResume);
|
||||
const [resumeInfoModalShow, setResumeInfoModalShow] = useState(false);
|
||||
const [resumeInfoData, setResumeInfoData] = useState(null);
|
||||
const [resumeList, setResumeList] = useState([]); // 简历列表
|
||||
const [listPage, setListPage] = useState(1);
|
||||
const [listHasMore, setListHasMore] = useState(true);
|
||||
|
||||
// 处理directToResume参数变化
|
||||
useEffect(() => {
|
||||
if (visible && directToResume) {
|
||||
setResumeModalShow(true);
|
||||
} else if (visible && !directToResume) {
|
||||
setResumeModalShow(false);
|
||||
}
|
||||
}, [visible, directToResume]);
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setResumeModalShow(false);
|
||||
setResumeList([]); // 清空简历列表
|
||||
setListPage(1); // 重置分页
|
||||
setListHasMore(true); // 重置加载更多状态
|
||||
onClose();
|
||||
};
|
||||
|
||||
@@ -28,7 +42,7 @@ export default ({ visible, onClose, data }) => {
|
||||
const res = await getResumesList({
|
||||
page: listPage,
|
||||
pageSize: PAGE_SIZE,
|
||||
studentId: studentInfo?.id,
|
||||
studentId: studentInfo?.id
|
||||
});
|
||||
if (res.success) {
|
||||
setResumeList((prevList) => {
|
||||
@@ -55,17 +69,88 @@ export default ({ visible, onClose, data }) => {
|
||||
};
|
||||
|
||||
// 选择简历投递
|
||||
const userResumesClick = (item) => {
|
||||
// todo
|
||||
console.log(item);
|
||||
const userResumesClick = async (item) => {
|
||||
try {
|
||||
// 调用投递服务
|
||||
const result = await submitResume({
|
||||
resumeId: item.id,
|
||||
jobId: data?.id,
|
||||
studentId: studentInfo?.id,
|
||||
resumeTitle: item.title,
|
||||
jobPosition: data?.position,
|
||||
company: data?.company
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
// 投递成功,显示成功提示
|
||||
toast.success(`简历"${item.title}"投递成功!`);
|
||||
|
||||
// 关闭模态框
|
||||
handleCloseModal();
|
||||
|
||||
// 输出投递成功信息
|
||||
console.log('投递成功', {
|
||||
applicationId: result.data.applicationId,
|
||||
resumeId: item.id,
|
||||
jobId: data?.id,
|
||||
resumeTitle: item.title,
|
||||
jobPosition: data?.position,
|
||||
submittedAt: result.data.submittedAt
|
||||
});
|
||||
} else {
|
||||
toast.error(result.message || '投递失败,请重试');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
toast.error('投递失败,请重试');
|
||||
console.error('投递失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 点击简历详情
|
||||
const userResumesBtnClick = (e, item) => {
|
||||
const userResumesBtnClick = async (e, item) => {
|
||||
e.stopPropagation();
|
||||
setResumeInfoModalShow(true);
|
||||
|
||||
try {
|
||||
// 获取岗位与面试题页面的数据
|
||||
const pageDataResponse = await getPageData();
|
||||
|
||||
if (pageDataResponse.success) {
|
||||
const pageData = pageDataResponse.data;
|
||||
|
||||
// 直接使用简历列表中的模板数据
|
||||
const selectedTemplate = item.template;
|
||||
|
||||
// 找到对应的行业信息
|
||||
const matchedIndustry = pageData.industries?.find(industry =>
|
||||
industry.name === item.industry
|
||||
);
|
||||
|
||||
// 传递数据给 ResumeInfoModal
|
||||
const resumeData = {
|
||||
selectedTemplate,
|
||||
studentResume: pageData.myResume,
|
||||
industry: matchedIndustry,
|
||||
jobPosition: item.position
|
||||
};
|
||||
|
||||
console.log('加载简历数据:', {
|
||||
resumeTitle: item.title,
|
||||
position: item.position,
|
||||
industry: item.industry
|
||||
});
|
||||
|
||||
setResumeInfoData(resumeData);
|
||||
setResumeInfoModalShow(true);
|
||||
} else {
|
||||
toast.error('加载简历数据失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取简历数据失败:', error);
|
||||
toast.error('加载简历数据失败');
|
||||
}
|
||||
};;;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal visible={visible} onClose={handleCloseModal}>
|
||||
@@ -141,16 +226,22 @@ export default ({ visible, onClose, data }) => {
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
{data?.description && (
|
||||
{data?.details?.description && (
|
||||
<div className="job-info-modal-content-position-info-description">
|
||||
<p className="description-title">岗位描述</p>
|
||||
<p className="description-content">{data?.description}</p>
|
||||
<p className="description-content">{data?.details?.description}</p>
|
||||
</div>
|
||||
)}
|
||||
{data?.requirements && (
|
||||
<div className="job-info-modal-content-position-info-description">
|
||||
<p className="description-title">岗位要求</p>
|
||||
<p className="description-content">{data?.requirements}</p>
|
||||
{data?.details?.requirements?.length > 0 && (
|
||||
<div className="job-info-modal-content-position-info-requirements">
|
||||
<p className="requirements-title">岗位要求</p>
|
||||
<ul className="requirements-content">
|
||||
{data?.details?.requirements?.map((item, index) => (
|
||||
<li key={index} className="requirements-item">
|
||||
{index + 1}. {item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
{/* {data?.details?.requirements?.length > 0 && (
|
||||
@@ -165,11 +256,11 @@ export default ({ visible, onClose, data }) => {
|
||||
</ul>
|
||||
</div>
|
||||
)} */}
|
||||
{data?.company?.industry && (
|
||||
{data?.details?.companyInfo && (
|
||||
<div className="job-info-modal-content-position-info-companyInfo">
|
||||
<p className="companyInfo-title">公司介绍</p>
|
||||
<p className="companyInfo-content">
|
||||
{data?.company?.industry}
|
||||
{data?.details?.companyInfo}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
@@ -186,8 +277,11 @@ export default ({ visible, onClose, data }) => {
|
||||
</Modal>
|
||||
<ResumeInfoModal
|
||||
visible={resumeInfoModalShow}
|
||||
data={null}
|
||||
onClose={() => setResumeInfoModalShow(false)}
|
||||
data={resumeInfoData}
|
||||
onClose={() => {
|
||||
setResumeInfoModalShow(false);
|
||||
setResumeInfoData(null);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -8,12 +8,15 @@ import "./index.css";
|
||||
export default ({ className = "", data = [], backgroundColor }) => {
|
||||
const [jobInfoData, setJobInfoData] = useState(undefined);
|
||||
const [jobInfoModalVisible, setJobInfoModalVisible] = useState(false);
|
||||
const [directToResume, setDirectToResume] = useState(false);
|
||||
|
||||
const handleJobClick = async (e, item) => {
|
||||
e.stopPropagation();
|
||||
const res = await getJobsDetail(item.id);
|
||||
if (res.success) {
|
||||
setJobInfoData(mapJob(res.data));
|
||||
// Mock数据已经是前端格式,不需要映射
|
||||
setJobInfoData(res.data);
|
||||
setDirectToResume(false); // 点击岗位条目,显示详情
|
||||
setJobInfoModalVisible(true);
|
||||
} else {
|
||||
toast.error(res.message);
|
||||
@@ -25,6 +28,21 @@ export default ({ className = "", data = [], backgroundColor }) => {
|
||||
setJobInfoModalVisible(false);
|
||||
};
|
||||
|
||||
// 直接投递按钮点击事件
|
||||
const handleDeliverClick = async (e, item) => {
|
||||
e.stopPropagation(); // 阻止冒泡到li的点击事件
|
||||
|
||||
// 获取岗位详情然后打开投递弹窗
|
||||
const res = await getJobsDetail(item.id);
|
||||
if (res.success) {
|
||||
setJobInfoData(res.data);
|
||||
setDirectToResume(true); // 点击投递按钮,直接显示简历选择界面
|
||||
setJobInfoModalVisible(true);
|
||||
} else {
|
||||
toast.error(res.message);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ul className={`company-jobs-page-left-list ${className}`}>
|
||||
@@ -56,7 +74,10 @@ export default ({ className = "", data = [], backgroundColor }) => {
|
||||
<p className="company-jobs-info-position-salary">
|
||||
{item?.salary}
|
||||
</p>
|
||||
<button className="company-jobs-btn">
|
||||
<button
|
||||
className="company-jobs-btn"
|
||||
onClick={(e) => handleDeliverClick(e, item)}
|
||||
>
|
||||
<i />
|
||||
<span>投递</span>
|
||||
</button>
|
||||
@@ -68,6 +89,7 @@ export default ({ className = "", data = [], backgroundColor }) => {
|
||||
data={jobInfoData}
|
||||
visible={jobInfoModalVisible}
|
||||
onClose={onClickJobInfoModalClose}
|
||||
directToResume={directToResume}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -96,7 +96,8 @@
|
||||
|
||||
.educational-experience-list-item {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
min-height: 24px;
|
||||
height: auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@@ -105,7 +106,8 @@
|
||||
> p {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.school-name {
|
||||
@@ -146,7 +148,8 @@
|
||||
|
||||
.project-info-wrapper {
|
||||
width: 100%;
|
||||
height: 46px;
|
||||
min-height: 46px;
|
||||
height: auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
@@ -196,6 +199,8 @@
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
text-align: left;
|
||||
line-height: 1.5;
|
||||
word-wrap: break-word;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@@ -208,7 +213,8 @@
|
||||
|
||||
> p {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
min-height: 24px;
|
||||
height: auto;
|
||||
line-height: 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
@@ -217,8 +223,9 @@
|
||||
}
|
||||
> li {
|
||||
width: 100%;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
min-height: 22px;
|
||||
height: auto;
|
||||
line-height: 1.5;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #1d2129;
|
||||
@@ -249,8 +256,9 @@
|
||||
|
||||
.skill-name {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
min-height: 24px;
|
||||
height: auto;
|
||||
line-height: 1.5;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #4e5969;
|
||||
@@ -267,8 +275,10 @@
|
||||
|
||||
.core-capabilities-list-item {
|
||||
width: 100%;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
min-height: 22px;
|
||||
height: auto;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 5px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #1d2129;
|
||||
@@ -278,21 +288,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
.personal-summary-list {
|
||||
.personal-summary-list,
|
||||
.personal-summary-content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
> li {
|
||||
> li,
|
||||
> p {
|
||||
width: 100%;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
min-height: 22px;
|
||||
height: auto;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 5px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #1d2129;
|
||||
text-align: left;
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
.corresponding-course-units-list {
|
||||
@@ -308,7 +324,8 @@
|
||||
|
||||
.corresponding-course-units-list-item {
|
||||
width: 100%;
|
||||
height: 72px;
|
||||
min-height: 72px;
|
||||
height: auto;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #e5e6eb;
|
||||
border-radius: 8px;
|
||||
|
||||
@@ -13,6 +13,47 @@ export default ({ visible, onClose, data }) => {
|
||||
onClose();
|
||||
};
|
||||
|
||||
// 获取当前简历数据
|
||||
const currentTemplate = data?.selectedTemplate;
|
||||
const studentInfo = currentTemplate?.studentInfo;
|
||||
const positionTitle = currentTemplate?.position || "岗位名称";
|
||||
|
||||
// 转换数据格式
|
||||
let resumeData = {
|
||||
educational_experience: ["相关专业大学 本科"],
|
||||
project_experience: [],
|
||||
core_skills: [],
|
||||
compound_skills: [],
|
||||
personal_summary: "暂无个人总结"
|
||||
};
|
||||
|
||||
if (studentInfo) {
|
||||
// 处理教育经历
|
||||
resumeData.educational_experience = studentInfo.educational_experience || ["相关专业大学 本科"];
|
||||
|
||||
// 处理项目经历
|
||||
if (studentInfo.project_experience) {
|
||||
if (Array.isArray(studentInfo.project_experience)) {
|
||||
// 如果已经是数组格式
|
||||
resumeData.project_experience = studentInfo.project_experience;
|
||||
} else if (typeof studentInfo.project_experience === 'object') {
|
||||
// 如果是对象格式,转换为数组
|
||||
const proj = studentInfo.project_experience;
|
||||
resumeData.project_experience = [
|
||||
{
|
||||
name: proj.project_name || proj.position || "实习项目",
|
||||
description: proj.description || "参与项目实施"
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 处理核心技能和复合技能
|
||||
resumeData.core_skills = studentInfo.core_skills || [];
|
||||
resumeData.compound_skills = studentInfo.compound_skills || [];
|
||||
resumeData.personal_summary = studentInfo.personal_summary || "具有扎实的专业基础和实践经验";
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal visible={visible} onClose={handleCloseModal}>
|
||||
<div className="resume-info-modal">
|
||||
@@ -28,95 +69,80 @@ export default ({ visible, onClose, data }) => {
|
||||
<Radio value="2">个人修改版</Radio>
|
||||
<Radio value="3">个人修改版</Radio>
|
||||
</Radio.Group>
|
||||
<p className="resume-info-modal-title">非标自动化工程师</p>
|
||||
<p className="resume-info-modal-title">{positionTitle}</p>
|
||||
<ul className="resume-info-moda-list">
|
||||
{/* 教育经历 */}
|
||||
{resumeData.educational_experience && resumeData.educational_experience.length > 0 && (
|
||||
<li className="resume-info-moda-item">
|
||||
<p className="resume-info-moda-item-title">教育经历</p>
|
||||
<ul className="educational-experience-list">
|
||||
<li className="educational-experience-list-item">
|
||||
<p className="school-name">北京理工大学</p>
|
||||
<p className="study-time">2018.09 - 2022.07</p>
|
||||
</li>
|
||||
<li className="educational-experience-list-item">
|
||||
<p className="school-name">北京理工大学</p>
|
||||
<p className="study-time">2018.09 - 2022.07</p>
|
||||
{resumeData.educational_experience.map((edu, index) => (
|
||||
<li key={index} className="educational-experience-list-item">
|
||||
<p className="school-name">{edu}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
)}
|
||||
{/* 项目经历 */}
|
||||
{resumeData.project_experience && resumeData.project_experience.length > 0 && (
|
||||
<li className="resume-info-moda-item">
|
||||
<p className="resume-info-moda-item-title">项目经历</p>
|
||||
<ul className="project-experience-list">
|
||||
<li className="project-experience-list-item">
|
||||
{resumeData.project_experience.map((project, index) => (
|
||||
<li key={index} className="project-experience-list-item">
|
||||
<div className="project-info-wrapper">
|
||||
<div className="project-info">
|
||||
<p className="project-name">项目名称</p>
|
||||
<p className="project-company">单位:xxxxxx</p>
|
||||
<p className="project-name">{project.name || `项目${index + 1}`}</p>
|
||||
</div>
|
||||
<p className="project-time">2022.09 - 2023.07</p>
|
||||
</div>
|
||||
<p className="project-desc">
|
||||
1. 负责室内平面设计项目的创意和实施2.
|
||||
与团队合作,确保设计质量和项目进度 3.
|
||||
持续关注设计趋势,提升设计技能 1.
|
||||
具备出色的沟通能力和团队协作精神 2.
|
||||
能够高效完成任务,对工作细节有高度关注 3.
|
||||
具有不断学习和适应新挑战的能力
|
||||
加分项:有以下行业经验:建筑设计
|
||||
{project.description}
|
||||
</p>
|
||||
<ul className="job-responsibilities-list">
|
||||
<p>岗位职责</p>
|
||||
<li>1.负责室内平面设计项目的创意和实施</li>
|
||||
<li>2.与团队合作,确保设计质量和项目进度</li>
|
||||
<li>3.持续关注设计趋势,提升设计技能</li>
|
||||
</ul>
|
||||
</li>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
)}
|
||||
{/* 专业技能 */}
|
||||
<li className="resume-info-moda-item">
|
||||
<p className="resume-info-moda-item-title">专业技能</p>
|
||||
<ul className="professional-skills-list">
|
||||
{resumeData.core_skills && resumeData.core_skills.length > 0 && (
|
||||
<li className="professional-skills-list-item">
|
||||
<p className="skill-name">核心能力</p>
|
||||
<div className="core-capabilities-list">
|
||||
<p className="core-capabilities-list-item">
|
||||
1. 负责室内平面设计项目的创意和实施
|
||||
</p>
|
||||
<p className="core-capabilities-list-item">
|
||||
2. 与团队合作,确保设计质量和项目进度
|
||||
</p>
|
||||
<p className="core-capabilities-list-item">
|
||||
3. 持续关注设计趋势,提升设计技能
|
||||
{resumeData.core_skills.map((skill, index) => (
|
||||
<p key={index} className="core-capabilities-list-item">
|
||||
{skill}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
{resumeData.compound_skills && resumeData.compound_skills.length > 0 && (
|
||||
<li className="professional-skills-list-item">
|
||||
<p className="skill-name">复核能力</p>
|
||||
<p className="skill-name">复合能力</p>
|
||||
<div className="core-capabilities-list">
|
||||
<p className="core-capabilities-list-item">
|
||||
1. 负责室内平面设计项目的创意和实施
|
||||
</p>
|
||||
<p className="core-capabilities-list-item">
|
||||
2. 与团队合作,确保设计质量和项目进度
|
||||
</p>
|
||||
<p className="core-capabilities-list-item">
|
||||
3. 持续关注设计趋势,提升设计技能
|
||||
{resumeData.compound_skills.map((skill, index) => (
|
||||
<p key={index} className="core-capabilities-list-item">
|
||||
{skill}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</li>
|
||||
{/* 个人总结 */}
|
||||
{resumeData.personal_summary && resumeData.personal_summary.trim() !== '' && (
|
||||
<li className="resume-info-moda-item">
|
||||
<p className="resume-info-moda-item-title">个人总结</p>
|
||||
<ul className="personal-summary-list">
|
||||
<li>1. 负责室内平面设计项目的创意和实施</li>
|
||||
<li>2. 与团队合作,确保设计质量和项目进度</li>
|
||||
<li>3. 持续关注设计趋势,提升设计技能</li>
|
||||
</ul>
|
||||
<div className="personal-summary-content">
|
||||
<p>{resumeData.personal_summary}</p>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
{/* 对应课程单元 */}
|
||||
<li className="resume-info-moda-item">
|
||||
<p className="resume-info-moda-item-title">对应课程单元</p>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useState, useEffect } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Spin, Empty } from "@arco-design/web-react";
|
||||
import { mapJobList, mapInterviewList } from "@/utils/dataMapper";
|
||||
// import { mapJobList, mapInterviewList } from "@/utils/dataMapper"; // 不再需要映射器,mock数据已经是前端格式
|
||||
import InfiniteScroll from "@/components/InfiniteScroll";
|
||||
import toast from "@/components/Toast";
|
||||
import JobList from "./components/JobList";
|
||||
@@ -40,22 +40,22 @@ const CompanyJobsPage = () => {
|
||||
if (res?.success) {
|
||||
// 设置岗位数据
|
||||
if (res.data?.jobs) {
|
||||
const mappedJobs = mapJobList(res.data.jobs.list || []);
|
||||
setJobs(mappedJobs);
|
||||
// Mock数据已经是前端格式,直接使用不需要映射
|
||||
const jobs = res.data.jobs.list || [];
|
||||
setJobs(jobs);
|
||||
setJobsListHasMore(res.data.jobs.hasMore);
|
||||
if (mappedJobs.length > 0) {
|
||||
if (jobs.length > 0) {
|
||||
setJobsListPage(2); // 下次从第2页开始
|
||||
}
|
||||
}
|
||||
|
||||
// 设置面试数据
|
||||
if (res.data?.interviews && studentInfo?.id) {
|
||||
const mappedInterviews = mapInterviewList(
|
||||
res.data.interviews.list || []
|
||||
);
|
||||
setInterviews(mappedInterviews);
|
||||
// Mock数据已经是前端格式,直接使用不需要映射
|
||||
const interviews = res.data.interviews.list || [];
|
||||
setInterviews(interviews);
|
||||
setInterviewsHasMore(res.data.interviews.hasMore);
|
||||
if (mappedInterviews.length > 0) {
|
||||
if (interviews.length > 0) {
|
||||
setInterviewsPage(2); // 下次从第2页开始
|
||||
}
|
||||
}
|
||||
@@ -93,13 +93,14 @@ const CompanyJobsPage = () => {
|
||||
status: "SCHEDULED",
|
||||
});
|
||||
if (res.success) {
|
||||
const mappedInterviews = mapInterviewList(res.data || []);
|
||||
// Mock数据已经是前端格式,直接使用
|
||||
const interviews = res.data || [];
|
||||
setInterviews((prevList) => {
|
||||
// 去重处理:过滤掉已存在的数据
|
||||
const existingIds = new Set(
|
||||
prevList.map((interview) => interview.id)
|
||||
);
|
||||
const newInterviews = mappedInterviews.filter(
|
||||
const newInterviews = interviews.filter(
|
||||
(interview) => !existingIds.has(interview.id)
|
||||
);
|
||||
|
||||
@@ -140,11 +141,12 @@ const CompanyJobsPage = () => {
|
||||
});
|
||||
|
||||
if (res?.success) {
|
||||
const mappedJobs = mapJobList(res.data);
|
||||
// Mock数据已经是前端格式,直接使用
|
||||
const jobs = res.data;
|
||||
setJobs((prevList) => {
|
||||
// 去重处理:过滤掉已存在的数据
|
||||
const existingIds = new Set(prevList.map((job) => job.id));
|
||||
const newJobs = mappedJobs.filter((job) => !existingIds.has(job.id));
|
||||
const newJobs = jobs.filter((job) => !existingIds.has(job.id));
|
||||
|
||||
const newList = [...prevList, ...newJobs];
|
||||
if (res.total <= newList?.length) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Avatar, Skeleton, Empty } from "@arco-design/web-react";
|
||||
import { Avatar, Empty, Skeleton } from "@arco-design/web-react";
|
||||
import "./index.css";
|
||||
|
||||
const TaskList = ({ tasks = [], selectedDate, loading }) => {
|
||||
|
||||
@@ -6,7 +6,18 @@ import "./index.css";
|
||||
const HomeworkPage = () => {
|
||||
const { homework } = mockData;
|
||||
|
||||
const handleClickBtn = () => {};
|
||||
const handleClickBtn = (sectionId, itemId) => {
|
||||
// 只有复合能力培养的第一个项目(展会策划教学)可以点击
|
||||
if (sectionId === 1 && itemId === 1) {
|
||||
window.open("https://du9uay.github.io/zhanhui/", "_blank");
|
||||
}
|
||||
};
|
||||
|
||||
// 判断是否应该显示灰色图片和禁用按钮
|
||||
const isDisabled = (sectionId, itemId) => {
|
||||
// 只有复合能力培养的第一个项目是启用状态
|
||||
return !(sectionId === 1 && itemId === 1);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="homework-page-wrapper">
|
||||
@@ -24,13 +35,23 @@ const HomeworkPage = () => {
|
||||
alt="icon"
|
||||
src={ICON1}
|
||||
className="homework-page-content-list-content-item-icon"
|
||||
style={{
|
||||
filter: isDisabled(item.id, contentItem.id) ? "grayscale(100%)" : "none",
|
||||
opacity: isDisabled(item.id, contentItem.id) ? 0.6 : 1
|
||||
}}
|
||||
/>
|
||||
<p className="homework-page-content-list-content-item-name">
|
||||
{contentItem.name}
|
||||
</p>
|
||||
<div
|
||||
className="homework-page-content-list-content-item-btn"
|
||||
onClick={() => handleClickBtn()}
|
||||
className={`homework-page-content-list-content-item-btn ${
|
||||
isDisabled(item.id, contentItem.id) ? "disabled" : ""
|
||||
}`}
|
||||
onClick={() => !isDisabled(item.id, contentItem.id) && handleClickBtn(item.id, contentItem.id)}
|
||||
style={{
|
||||
cursor: isDisabled(item.id, contentItem.id) ? "not-allowed" : "pointer",
|
||||
opacity: isDisabled(item.id, contentItem.id) ? 0.5 : 1
|
||||
}}
|
||||
>
|
||||
完成作业
|
||||
</div>
|
||||
|
||||
@@ -5,13 +5,57 @@ import "./index.css";
|
||||
|
||||
// 滑动阈值(向上滑动超过这个距离触发切换)
|
||||
const SWIPE_THRESHOLD = 100;
|
||||
export default () => {
|
||||
export default ({ selectedItem = "求职面试初体验" }) => {
|
||||
const [isSlide, setIsSlide] = useState(false);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [startY, setStartY] = useState(0);
|
||||
const [currentY, setCurrentY] = useState(0);
|
||||
const slideRef = useRef(null);
|
||||
|
||||
// 根据选中项目获取对应的视频URL
|
||||
const getVideoUrl = () => {
|
||||
switch(selectedItem) {
|
||||
case "求职面试初体验":
|
||||
return "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/video/teach_sys/interview_offline_vedio/recuUpJSOKoqAm.mov";
|
||||
case "未来的自己":
|
||||
return "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/video/teach_sys/interview_offline_vedio/recuUpJT02CMM5.mp4";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
// 判断是否是锁定的面试模拟项目
|
||||
const isLockedItem = () => {
|
||||
return selectedItem?.includes("线下面试模拟");
|
||||
};
|
||||
|
||||
// 根据选中项目获取评价数据
|
||||
const getEvaluationData = () => {
|
||||
if (selectedItem === "未来的自己") {
|
||||
return {
|
||||
totalScore: 92,
|
||||
professionalScore: 39.5,
|
||||
performanceScore: 55.0,
|
||||
radarData: [10, 9, 10, 9],
|
||||
title: "优秀表现评价",
|
||||
content: `在专业能力方面,候选人对相关专业知识掌握扎实,能够深入且准确地回答与项目经验相关的复杂问题。在描述具体项目时,不仅能清晰说明自己的职责和成果,还能主动分析项目中的技术难点和解决方案,体现出优秀的实践操作能力和技术思维。对行业前沿动态有深入了解,能够结合实际工作提出创新性见解。
|
||||
|
||||
沟通表达上,候选人语言表达流畅自然,逻辑思维清晰有条理,能够积极主动地与面试官互动。在面对开放性问题时展现出良好的思维发散能力,回答层次分明,重点突出,表现出强烈的学习意愿和职业发展规划意识。整体表现超出预期,具备优秀的职场素养。`
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
totalScore: 85,
|
||||
professionalScore: 38.0,
|
||||
performanceScore: 50.0,
|
||||
radarData: [9, 8, 9, 9],
|
||||
title: "基础面试评价",
|
||||
content: `在专业能力方面,候选人对 [岗位相关专业知识] 有基本掌握,能够清晰回答与过往项目经验相关的问题,例如在描述 [具体项目] 时,能准确说明自己承担的职责和达成的成果,体现出一定的实践操作能力。但在深入探讨 [某一专业难点] 时,表述略显浅显,对行业前沿动态的了解不够全面,专业深度有提升空间。
|
||||
|
||||
沟通表达上,候选人语言流畅,逻辑较为清晰,能够主动回应面试官的问题,展现出良好的沟通意愿。不过在面对一些开放性问题时,思维发散性稍弱,回答的层次感不够突出,有时会出现表述重复的情况。`
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// 处理触摸/鼠标开始
|
||||
const handleStart = (clientY) => {
|
||||
setIsDragging(true);
|
||||
@@ -27,15 +71,25 @@ export default () => {
|
||||
if (!isDragging) return;
|
||||
|
||||
setCurrentY(clientY);
|
||||
const diffY = startY - clientY; // 计算向上滑动的距离
|
||||
const diffY = startY - clientY; // 正值表示向上滑动,负值表示向下滑动
|
||||
|
||||
// 只允许向上滑动,限制最大滑动距离
|
||||
if (diffY > 0) {
|
||||
if (isSlide) {
|
||||
// 在评价界面时,只允许向下滑动
|
||||
if (diffY < 0) {
|
||||
const translateY = Math.min(Math.abs(diffY), 150);
|
||||
if (slideRef.current) {
|
||||
slideRef.current.style.transform = `translateY(${translateY}px)`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 在视频界面时,只允许向上滑动,且只对懵懂初试的项目生效
|
||||
if (diffY > 0 && (selectedItem === "求职面试初体验" || selectedItem === "未来的自己")) {
|
||||
const translateY = Math.min(diffY, 150);
|
||||
if (slideRef.current) {
|
||||
slideRef.current.style.transform = `translateY(-${translateY}px)`;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 处理触摸/鼠标结束
|
||||
@@ -51,16 +105,33 @@ export default () => {
|
||||
slideRef.current.style.transform = "";
|
||||
}
|
||||
|
||||
// 检查是否达到滑动阈值
|
||||
// 检查滑动方向和阈值
|
||||
if (isSlide) {
|
||||
// 在评价界面时,向下滑动返回视频界面
|
||||
if (diffY < -SWIPE_THRESHOLD) {
|
||||
handleSwipeDown();
|
||||
}
|
||||
} else {
|
||||
// 在视频界面时,向上滑动到评价界面
|
||||
if (diffY > SWIPE_THRESHOLD) {
|
||||
handleSwipeUp();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 向上滑动事件处理
|
||||
const handleSwipeUp = () => {
|
||||
// 只有懵懂初试的项目可以上滑查看评价
|
||||
if (selectedItem === "求职面试初体验" || selectedItem === "未来的自己") {
|
||||
console.log("触发向上滑动切换");
|
||||
setIsSlide(true);
|
||||
}
|
||||
};
|
||||
|
||||
// 向下滑动事件处理
|
||||
const handleSwipeDown = () => {
|
||||
console.log("触发向下滑动返回");
|
||||
setIsSlide(false);
|
||||
};
|
||||
|
||||
// 鼠标事件处理
|
||||
@@ -126,38 +197,54 @@ export default () => {
|
||||
}`}
|
||||
>
|
||||
{isSlide ? (
|
||||
<div className="interview-evaluation-wrapper">
|
||||
<div
|
||||
className="interview-evaluation-wrapper"
|
||||
ref={slideRef}
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseMove={handleMouseMove}
|
||||
onMouseUp={handleMouseUp}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchMove={handleTouchMove}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
style={{
|
||||
cursor: "grab",
|
||||
userSelect: "none",
|
||||
WebkitUserSelect: "none",
|
||||
touchAction: "pan-x",
|
||||
}}
|
||||
>
|
||||
<div className="interview-evaluation-charts-wrapper">
|
||||
<div className="interview-rating-header">
|
||||
<span className="interview-rating-header-title">面试评分</span>
|
||||
</div>
|
||||
<div className="charts-content">
|
||||
<div className="charts-content-top">
|
||||
<ScoreChart className="score-chart" value={85} />
|
||||
<ScoreChart className="score-chart" value={getEvaluationData().totalScore} />
|
||||
<div className="score-info">
|
||||
<div className="score-info-item item1">
|
||||
<span className="score-info-item-title">
|
||||
专业能力评分(40)
|
||||
</span>
|
||||
<span className="score-info-item-value">38.00</span>
|
||||
<span className="score-info-item-value">{getEvaluationData().professionalScore}</span>
|
||||
</div>
|
||||
<div className="score-info-item item2">
|
||||
<span className="score-info-item-title">
|
||||
现场表现评分(60)
|
||||
</span>
|
||||
<span className="score-info-item-value">50.00</span>
|
||||
<span className="score-info-item-value">{getEvaluationData().performanceScore}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="charts-content-bottom">
|
||||
<RadarChart
|
||||
className="radar-chart"
|
||||
data={[9, 8, 9, 9]}
|
||||
data={getEvaluationData().radarData}
|
||||
indicator={[
|
||||
{ name: "{a|核心知识掌握}\n{b|与精准应用}", max: 10 },
|
||||
{ name: "{a|问题分析、方案设计}\n{b|与成果表达}", max: 10 },
|
||||
{ name: "{a|产业认知与行业}\n{b|趋势洞察}", max: 10 },
|
||||
{ name: "{a|企业工作流}\n{b|理解与实践}", max: 10 },
|
||||
{ name: "{a|核心知识掌握}\\n{b|与精准应用}", max: 10 },
|
||||
{ name: "{a|问题分析、方案设计}\\n{b|与成果表达}", max: 10 },
|
||||
{ name: "{a|产业认知与行业}\\n{b|趋势洞察}", max: 10 },
|
||||
{ name: "{a|企业工作流}\\n{b|理解与实践}", max: 10 },
|
||||
]}
|
||||
/>
|
||||
<RadarChart className="radar-chart" />
|
||||
@@ -166,16 +253,10 @@ export default () => {
|
||||
</div>
|
||||
<div className="interview-evaluation-text-wrapper">
|
||||
<div className="interview-rating-header">
|
||||
<span className="interview-rating-header-title">面试评分</span>
|
||||
<span className="interview-rating-header-title">{getEvaluationData().title}</span>
|
||||
</div>
|
||||
<div className="interview-rating-text">
|
||||
在专业能力方面,候选人对 [岗位相关专业知识]
|
||||
有基本掌握,能够清晰回答与过往项目经验相关的问题,例如在描述
|
||||
[具体项目]
|
||||
时,能准确说明自己承担的职责和达成的成果,体现出一定的实践操作能力。但在深入探讨
|
||||
[某一专业难点]
|
||||
时,表述略显浅显,对行业前沿动态的了解不够全面,专业深度有提升空间。
|
||||
沟通表达上,候选人语言流畅,逻辑较为清晰,能够主动回应面试官的问题,展现出良好的沟通意愿。不过在面对一些开放性问题时,思维发散性稍弱,回答的层次感不够突出,有时会出现表述重复的情况。
|
||||
{getEvaluationData().content}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -203,7 +284,11 @@ export default () => {
|
||||
</span>
|
||||
</div>
|
||||
<div className="interview-rating-video">
|
||||
<video src="" controls></video>
|
||||
{isLockedItem() ? (
|
||||
<img src="/线下面试模拟锁定.png" alt="线下面试模拟锁定" style={{width: "100%", height: "100%", objectFit: "cover"}} />
|
||||
) : (
|
||||
<video src={getVideoUrl()} controls></video>
|
||||
)}
|
||||
</div>
|
||||
<div className="interview-rating-slide">
|
||||
<i />
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import { useState } from "react";
|
||||
import { Timeline } from "@arco-design/web-react";
|
||||
import "./index.css";
|
||||
|
||||
const TimelineItem = Timeline.Item;
|
||||
|
||||
export default ({ data }) => {
|
||||
export default ({ onItemSelect }) => {
|
||||
const [selectedItem, setSelectedItem] = useState("求职面试初体验");
|
||||
|
||||
const handleItemClick = (itemName) => {
|
||||
setSelectedItem(itemName);
|
||||
onItemSelect && onItemSelect(itemName);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mock-interview-wrapper">
|
||||
<p className="mock-interview-title">面试模拟</p>
|
||||
@@ -17,24 +25,32 @@ export default ({ data }) => {
|
||||
<TimelineItem
|
||||
lineType="dashed"
|
||||
dot={
|
||||
<div className="time-line-dot-icon time-line-dot-icon-active" />
|
||||
<div className={`time-line-dot-icon ${selectedItem === "求职面试初体验" ? "time-line-dot-icon-active" : ""}`} />
|
||||
}
|
||||
>
|
||||
<div className="time-line-item time-line-item-active">
|
||||
<p>终生学习系统</p>
|
||||
<div
|
||||
className={`time-line-item ${selectedItem === "求职面试初体验" ? "time-line-item-active" : ""}`}
|
||||
onClick={() => handleItemClick("求职面试初体验")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<p>求职面试初体验</p>
|
||||
<div className="time-line-item-info">
|
||||
这里是文本评价,经过我们的交谈我们觉得你跟我们的意向很匹配
|
||||
初次接触面试环境,体验真实面试流程,了解自身在面试中的基本表现和待提升的方面
|
||||
</div>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
<TimelineItem
|
||||
lineType="dashed"
|
||||
dot={<div className="time-line-dot-icon" />}
|
||||
dot={<div className={`time-line-dot-icon ${selectedItem === "未来的自己" ? "time-line-dot-icon-active" : ""}`} />}
|
||||
>
|
||||
<div className="time-line-item">
|
||||
<p>终生学习系统</p>
|
||||
<div
|
||||
className={`time-line-item ${selectedItem === "未来的自己" ? "time-line-item-active" : ""}`}
|
||||
onClick={() => handleItemClick("未来的自己")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<p>未来的自己</p>
|
||||
<div className="time-line-item-info">
|
||||
这里是文本评价,经过我们的交谈我们觉得你跟我们的意向很匹配
|
||||
经过系统训练后的面试表现,展示个人成长和进步,体现出更强的职场竞争力和专业素养
|
||||
</div>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
@@ -43,31 +59,67 @@ export default ({ data }) => {
|
||||
<li className="mock-interview-item">
|
||||
<p className="mock-interview-item-title">
|
||||
<i className="mock-interview-item-title-icon" />
|
||||
<span>懵懂初试</span>
|
||||
<span>有备而战</span>
|
||||
</p>
|
||||
<Timeline>
|
||||
<TimelineItem
|
||||
lineType="dashed"
|
||||
dot={
|
||||
<div className="time-line-dot-icon time-line-dot-icon-active" />
|
||||
}
|
||||
dot={<div className={`time-line-dot-icon ${selectedItem === "第一次线下面试模拟" ? "time-line-dot-icon-active" : ""}`} />}
|
||||
>
|
||||
<div className="time-line-item time-line-item-active">
|
||||
<p>终生学习系统</p>
|
||||
<div className="time-line-item-info">
|
||||
这里是文本评价,经过我们的交谈我们觉得你跟我们的意向很匹配
|
||||
</div>
|
||||
<div
|
||||
className={`time-line-item ${selectedItem === "第一次线下面试模拟" ? "time-line-item-active" : ""}`}
|
||||
onClick={() => handleItemClick("第一次线下面试模拟")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<p>第一次线下面试模拟</p>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
<TimelineItem
|
||||
lineType="dashed"
|
||||
dot={<div className="time-line-dot-icon" />}
|
||||
dot={<div className={`time-line-dot-icon ${selectedItem === "第二次线下面试模拟" ? "time-line-dot-icon-active" : ""}`} />}
|
||||
>
|
||||
<div className="time-line-item">
|
||||
<p>终生学习系统</p>
|
||||
<div className="time-line-item-info">
|
||||
这里是文本评价,经过我们的交谈我们觉得你跟我们的意向很匹配
|
||||
<div
|
||||
className={`time-line-item ${selectedItem === "第二次线下面试模拟" ? "time-line-item-active" : ""}`}
|
||||
onClick={() => handleItemClick("第二次线下面试模拟")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<p>第二次线下面试模拟</p>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
<TimelineItem
|
||||
lineType="dashed"
|
||||
dot={<div className={`time-line-dot-icon ${selectedItem === "第三次线下面试模拟" ? "time-line-dot-icon-active" : ""}`} />}
|
||||
>
|
||||
<div
|
||||
className={`time-line-item ${selectedItem === "第三次线下面试模拟" ? "time-line-item-active" : ""}`}
|
||||
onClick={() => handleItemClick("第三次线下面试模拟")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<p>第三次线下面试模拟</p>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
<TimelineItem
|
||||
lineType="dashed"
|
||||
dot={<div className={`time-line-dot-icon ${selectedItem === "第四次线下面试模拟" ? "time-line-dot-icon-active" : ""}`} />}
|
||||
>
|
||||
<div
|
||||
className={`time-line-item ${selectedItem === "第四次线下面试模拟" ? "time-line-item-active" : ""}`}
|
||||
onClick={() => handleItemClick("第四次线下面试模拟")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<p>第四次线下面试模拟</p>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
<TimelineItem
|
||||
lineType="dashed"
|
||||
dot={<div className={`time-line-dot-icon ${selectedItem === "第五次线下面试模拟" ? "time-line-dot-icon-active" : ""}`} />}
|
||||
>
|
||||
<div
|
||||
className={`time-line-item ${selectedItem === "第五次线下面试模拟" ? "time-line-item-active" : ""}`}
|
||||
onClick={() => handleItemClick("第五次线下面试模拟")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<p>第五次线下面试模拟</p>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
</Timeline>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import { useState } from "react";
|
||||
import MockInterview from "./components/MockInterview";
|
||||
import InterviewRating from "./components/InterviewRating";
|
||||
import "./index.css";
|
||||
|
||||
const InterviewSimulationPage = () => {
|
||||
const [selectedItem, setSelectedItem] = useState("求职面试初体验");
|
||||
|
||||
return (
|
||||
<div className="interview-simulation-page">
|
||||
<MockInterview />
|
||||
<InterviewRating />
|
||||
<MockInterview onItemSelect={setSelectedItem} />
|
||||
<InterviewRating selectedItem={selectedItem} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -155,13 +155,13 @@ const JobStrategyDetailPage = () => {
|
||||
>
|
||||
{activeItem === "1" && (
|
||||
<>
|
||||
<TargetPosition />
|
||||
<TargetPosition locked={true} />
|
||||
<div className="slide-wrapper">
|
||||
<div className="slide-text">左滑查看曲线就业方案</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{activeItem === "2" && <CurvedEmployment />}
|
||||
{activeItem === "2" && <CurvedEmployment locked={true} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,13 @@ const PersonalProfile = () => {
|
||||
// 更新Redux中的学生信息
|
||||
const studentInfo = {
|
||||
...data.studentInfo,
|
||||
myRank: data.ranking.myRank,
|
||||
realName: data.studentInfo.name,
|
||||
studentNo: data.studentInfo.studentId,
|
||||
mbtiType: data.studentInfo.mbti || 'ENFJ',
|
||||
myRank: {
|
||||
...data.ranking.myRank,
|
||||
score: data.studentInfo.credits,
|
||||
},
|
||||
classInfo: data.ranking.classInfo,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,104 +1,7 @@
|
||||
.user-portfolio-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
|
||||
.user-portfolio-wrapper {
|
||||
width: 1120px;
|
||||
height: 790px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
|
||||
.user-portfolio-search-area {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
|
||||
.ser-portfolio-searc {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
border: 1px solid #2c7aff;
|
||||
|
||||
span {
|
||||
background-color: #fff;
|
||||
}
|
||||
input {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-portfolio-list {
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
padding: 20px 0;
|
||||
|
||||
.user-portfolio-item:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.user-portfolio-item {
|
||||
flex-shrink: 0;
|
||||
width: 340px;
|
||||
height: 82px;
|
||||
box-sizing: border-box;
|
||||
padding: 15px 20px;
|
||||
border-radius: 8px;
|
||||
background-color: #f7f8fa;
|
||||
border: 1px solid #e5e6eb;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
> span {
|
||||
border: 1px solid #2c7aff;
|
||||
background-color: #e8f3ff;
|
||||
height: 20px;
|
||||
border-radius: 2px;
|
||||
padding: 0 8px;
|
||||
box-sizing: border-box;
|
||||
color: #2c7aff;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.user-portfolio-item-content {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
|
||||
> p {
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
> span {
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #2c7aff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +1,17 @@
|
||||
import { Input } from "@arco-design/web-react";
|
||||
import { useState } from "react";
|
||||
import { mockData } from "@/data/mockData";
|
||||
import ProjectCasesModal from "@/pages/ProjectLibraryPage/components/ProjectCasesModal";
|
||||
import "./index.css";
|
||||
|
||||
const InputSearch = Input.Search;
|
||||
const { projectLibrary } = mockData;
|
||||
|
||||
const Portfolio = () => {
|
||||
const [modalData, setModalData] = useState(undefined);
|
||||
const [projectCasesModalVisible, setProjectCasesModalVisible] =
|
||||
useState(false);
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setProjectCasesModalVisible(false);
|
||||
setModalData(undefined);
|
||||
};
|
||||
|
||||
const onSearch = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
const handleClickBtn = (item) => {
|
||||
setModalData(item);
|
||||
setProjectCasesModalVisible(true);
|
||||
console.log("点击了详情按钮");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="user-portfolio-page">
|
||||
<div className="user-portfolio-wrapper">
|
||||
<div className="user-portfolio-search-area">
|
||||
<InputSearch
|
||||
className="ser-portfolio-search"
|
||||
onSearch={onSearch}
|
||||
searchButton="搜索"
|
||||
/>
|
||||
</div>
|
||||
<ul className="user-portfolio-list">
|
||||
{projectLibrary?.projects?.map((item) => (
|
||||
<li className="user-portfolio-item" key={item.id}>
|
||||
<span>{item.subtitle}</span>
|
||||
<div className="user-portfolio-item-content">
|
||||
<p>{item.title}</p>
|
||||
<span onClick={() => handleClickBtn(item)}>详情 > </span>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<ProjectCasesModal
|
||||
data={modalData}
|
||||
visible={projectCasesModalVisible}
|
||||
onClose={handleCloseModal}
|
||||
<iframe
|
||||
src="https://du9uay.github.io/personal-resume-wenlv/"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100vh",
|
||||
border: "none",
|
||||
display: "block"
|
||||
}}
|
||||
title="个人简历"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -60,13 +60,15 @@
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: fit-content;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 3px;
|
||||
width: 79px;
|
||||
width: 100%;
|
||||
height: 5px;
|
||||
opacity: 0.1;
|
||||
border-radius: 5px;
|
||||
@@ -191,17 +193,19 @@
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
|
||||
.attachment-list-item {
|
||||
width: 337px;
|
||||
min-width: 300px;
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
height: 80px;
|
||||
border: 1px solid #e5e6eb;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
background-color: #f7f8fa;
|
||||
margin-right: 20px;
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
padding: 10px 40px 10px 10px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
@@ -223,22 +227,35 @@
|
||||
.attachment-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin-right: 5px;
|
||||
margin-right: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.file-icon {
|
||||
margin-right: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.attachment-info {
|
||||
width: 200px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
margin-right: 10px;
|
||||
|
||||
> p {
|
||||
width: 100%;
|
||||
line-height: 28px;
|
||||
text-align: left;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #09090b;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
> span {
|
||||
line-height: 20px;
|
||||
@@ -250,6 +267,122 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Markdown内容样式 */
|
||||
.project-cases-modal-markdown-content {
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
color: #1d2129;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: #1d2129;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
h1 { font-size: 24px; }
|
||||
h2 { font-size: 20px; }
|
||||
h3 { font-size: 18px; }
|
||||
h4 { font-size: 16px; }
|
||||
h5 { font-size: 14px; }
|
||||
h6 { font-size: 14px; }
|
||||
|
||||
p {
|
||||
margin: 8px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin: 8px 0;
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 4px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
ul li {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
ol li {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #f7f8fa;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-family: 'Consolas', 'Monaco', monospace;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #f7f8fa;
|
||||
border: 1px solid #e5e6eb;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
overflow-x: auto;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #0275f2;
|
||||
padding-left: 16px;
|
||||
margin: 12px 0;
|
||||
color: #4e5969;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #e5e6eb;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1px solid #e5e6eb;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #f7f8fa;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0275f2;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import Modal from "@/components/Modal";
|
||||
import PDFICON from "@/assets/images/Common/pdf_icon.png";
|
||||
import FileIcon from "@/components/FileIcon";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import "./index.css";
|
||||
|
||||
export default ({ visible, onClose, data }) => {
|
||||
@@ -7,6 +9,13 @@ export default ({ visible, onClose, data }) => {
|
||||
onClose();
|
||||
};
|
||||
|
||||
// 将换行符转换为Markdown格式
|
||||
const formatMarkdownContent = (content) => {
|
||||
if (!content) return "";
|
||||
// 将 \n 替换为实际的换行符
|
||||
return content.replace(/\\n/g, '\n');
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal visible={visible} onClose={handleCloseModal}>
|
||||
<div className="project-cases-modal">
|
||||
@@ -17,77 +26,96 @@ export default ({ visible, onClose, data }) => {
|
||||
<li className="project-cases-modal-item">
|
||||
<p className="project-cases-modal-item-title">项目概述</p>
|
||||
<p className="project-cases-modal-item-text">
|
||||
本项目是长安汽车换代CS95(代号CD569)中的车机系统测试项目,基于腾讯车载互联平台,整合QQ音乐、喜马拉雅FM、酷我音乐、导航、远程控制等29个智能功能模块,
|
||||
旨在为车主提供便捷舒适的智能出行体验。项目中本人重点负责影音娱乐、行车记录及微信APP模块的测试工作,主要通过台架测试与仿真手段,验证系统功能稳定性与使用便捷性。
|
||||
{data?.overview || "暂无项目概述"}
|
||||
</p>
|
||||
</li>
|
||||
{/* 适用岗位 */}
|
||||
<li className="project-cases-modal-item">
|
||||
<p className="project-cases-modal-item-title">适用岗位</p>
|
||||
<ul className="project-cases-modal-horizontal-list">
|
||||
<li className="high-count-list-item">
|
||||
<span className="high">高阶岗</span>
|
||||
<p>测试工程师</p>
|
||||
{data?.applicablePositions?.map((pos, index) => (
|
||||
<li key={index} className="high-count-list-item">
|
||||
<span className={pos.level === '初级' ? 'low' : pos.level === '中级' ? 'medium' : 'high'}>
|
||||
{pos.level}
|
||||
</span>
|
||||
<p>{pos.position}</p>
|
||||
</li>
|
||||
)) || (
|
||||
<li className="high-count-list-item">
|
||||
<span className="medium">高阶岗</span>
|
||||
<p>测试工程师</p>
|
||||
</li>
|
||||
<li className="high-count-list-item">
|
||||
<span className="low">高阶岗</span>
|
||||
<p>测试工程师</p>
|
||||
</li>
|
||||
<li className="high-count-list-item">
|
||||
<span className="low">高阶岗</span>
|
||||
<p>测试工程师</p>
|
||||
<span className="medium">暂无</span>
|
||||
<p>适用岗位信息</p>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</li>
|
||||
{/* 对应课程 */}
|
||||
{/* 对应单元 */}
|
||||
<li className="project-cases-modal-item">
|
||||
<p className="project-cases-modal-item-title">适用岗位</p>
|
||||
<p className="project-cases-modal-item-title">对应单元</p>
|
||||
<ul className="project-cases-modal-horizontal-list">
|
||||
{data?.units?.map((unit, index) => (
|
||||
<li key={index} className="class-list-item">
|
||||
<div className="class-list-item-title">
|
||||
<i />
|
||||
<span>{unit}</span>
|
||||
</div>
|
||||
</li>
|
||||
)) || (
|
||||
<li className="class-list-item">
|
||||
<div className="class-list-item-title">
|
||||
<i />
|
||||
<span>物联网就业管家课程</span>
|
||||
<span>暂无对应单元信息</span>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</li>
|
||||
{/* 项目整体流程介绍 */}
|
||||
{/* 项目整体流程介绍 - Markdown格式 */}
|
||||
<li className="project-cases-modal-item">
|
||||
<p className="project-cases-modal-item-title">项目整体流程介绍</p>
|
||||
<p className="project-cases-modal-item-text">
|
||||
1. 需求分析:
|
||||
测试流程的起点,需深入理解产品需求文档和系统设计说明,明确各功能模块的业务逻辑、接口调用和交互方式。
|
||||
例如,在车载系统中,需要分析导航、影音、远程控制等模块的使用场景、输入输出以及与硬件(如摄像头、音响、控制器)的依赖关系。
|
||||
2. 需求分析:
|
||||
测试流程的起点,需深入理解产品需求文档和系统设计说明,明确各功能模块的业务逻辑、接口调用和交互方式。
|
||||
例如,在车载系统中,需要分析导航、影音、远程控制等模块的使用场景、输入输出以及与硬件(如摄像头、音响、控制器)的依赖关系。
|
||||
</p>
|
||||
<div className="project-cases-modal-markdown-content">
|
||||
{data?.process ? (
|
||||
<ReactMarkdown>{formatMarkdownContent(data.process)}</ReactMarkdown>
|
||||
) : (
|
||||
<p className="project-cases-modal-item-text">暂无项目流程介绍</p>
|
||||
)}
|
||||
</div>
|
||||
</li>
|
||||
{/* 项目案例关键技术点 */}
|
||||
{/* 项目案例关键技术点 - Markdown格式 */}
|
||||
<li className="project-cases-modal-item">
|
||||
<p className="project-cases-modal-item-title">项目案例关键技术点</p>
|
||||
<p className="project-cases-modal-item-text">
|
||||
1. 需求分析: 测试流程的起点{" "}
|
||||
</p>
|
||||
<p className="project-cases-modal-item-text">
|
||||
1. 需求分析: 测试流程的起点{" "}
|
||||
</p>
|
||||
<div className="project-cases-modal-markdown-content">
|
||||
{data?.keyPoints ? (
|
||||
<ReactMarkdown>{formatMarkdownContent(data.keyPoints)}</ReactMarkdown>
|
||||
) : (
|
||||
<p className="project-cases-modal-item-text">暂无关键技术点</p>
|
||||
)}
|
||||
</div>
|
||||
</li>
|
||||
{/* 附件 */}
|
||||
<li className="project-cases-modal-item">
|
||||
<p className="project-cases-modal-item-title">附件</p>
|
||||
<ul className="project-cases-modal-attachment-list">
|
||||
{data?.attachments?.map((attachment, index) => (
|
||||
<li key={index} className="attachment-list-item">
|
||||
{attachment.type ? (
|
||||
<FileIcon type={attachment.type} />
|
||||
) : (
|
||||
<img src={PDFICON} alt="icon" className="attachment-icon" />
|
||||
)}
|
||||
<div className="attachment-info">
|
||||
<p>{attachment.name}</p>
|
||||
<span>{attachment.size}</span>
|
||||
</div>
|
||||
</li>
|
||||
)) || (
|
||||
<li className="attachment-list-item">
|
||||
<img src={PDFICON} alt="icon" className="attachment-icon" />
|
||||
<div className="attachment-info">
|
||||
<p>项目测试用例.pdf</p>
|
||||
<span>2220kb</span>
|
||||
<p>暂无附件</p>
|
||||
<span>0kb</span>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -64,7 +64,8 @@
|
||||
flex-direction: column;
|
||||
|
||||
.project-library-item-title {
|
||||
width: 100%;
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
border: 1px solid #2c7aff;
|
||||
background-color: #e8f3ff;
|
||||
height: 20px;
|
||||
|
||||
@@ -28,9 +28,8 @@ const ProjectLibrary = () => {
|
||||
if (item?.id) {
|
||||
const res = await getProjectsdetail(item.id);
|
||||
if (res.success) {
|
||||
// todo
|
||||
// setProjectList();
|
||||
// setProjectCasesModalVisible(true);
|
||||
setModalData(res.data);
|
||||
setProjectCasesModalVisible(true);
|
||||
} else {
|
||||
toast.error(res.message);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
}
|
||||
.interview-questions-modal-list {
|
||||
width: 100%;
|
||||
max-height: 600px;
|
||||
max-height: 560px;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -88,10 +88,23 @@
|
||||
font-weight: 400;
|
||||
text-align: left;
|
||||
margin-top: 10px;
|
||||
line-height: 1.6;
|
||||
> span {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.interview-questions-modal-meta {
|
||||
font-size: 14px;
|
||||
color: #86909c;
|
||||
font-weight: 400;
|
||||
text-align: left;
|
||||
margin-top: 10px;
|
||||
> span {
|
||||
font-weight: 600;
|
||||
color: #4e5969;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,25 +10,34 @@ export default ({ visible, onClose, data }) => {
|
||||
<Modal visible={visible} onClose={handleCloseModal}>
|
||||
<div className="interview-questions-modal">
|
||||
<i className="close-icon" onClick={handleCloseModal} />
|
||||
<p className="interview-questions-modal-title">{data?.name}面试题</p>
|
||||
<p className="interview-questions-modal-title">{data?.name}岗位群面试题</p>
|
||||
<p className="interview-questions-modal-subtitle">
|
||||
在1V1定制求职策略阶段,企业HR会为您讲解面试题
|
||||
</p>
|
||||
<ul className="interview-questions-modal-list">
|
||||
<li className="interview-questions-modal-item">
|
||||
{data?.questions?.map((question, index) => (
|
||||
<li key={question.id} className="interview-questions-modal-item">
|
||||
<p className="interview-questions-modal-question">
|
||||
<span>问题:</span>
|
||||
{data?.question?.question}
|
||||
<span>问题{index + 1}:</span>
|
||||
{question.question}
|
||||
</p>
|
||||
<p className="interview-questions-modal-answer">
|
||||
<span>解答:</span>
|
||||
这是一个{data?.question?.difficulty?.toLowerCase()}难度的
|
||||
{data?.question?.category}相关问题。
|
||||
针对这类问题,建议从以下几个方面来回答: 1.
|
||||
理解问题的核心概念和背景 2. 结合实际项目经验进行说明 3.
|
||||
展示对相关技术的深入理解 4. 提及可能的优化或改进方案
|
||||
{question.answer}
|
||||
</p>
|
||||
{question.difficulty && (
|
||||
<p className="interview-questions-modal-meta">
|
||||
<span>难度:</span>{question.difficulty}
|
||||
{question.tags && question.tags.length > 0 && (
|
||||
<>
|
||||
<span style={{marginLeft: '20px'}}>标签:</span>
|
||||
{question.tags.join('、')}
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
height: 56px;
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
overflow-x: auto;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
padding: 0 20px;
|
||||
z-index: 10;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
|
||||
|
||||
.active {
|
||||
color: #2c7aff !important;
|
||||
@@ -31,20 +32,45 @@
|
||||
.navigation-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
width: 100%;
|
||||
scroll-behavior: smooth;
|
||||
|
||||
/* 隐藏滚动条但保留滚动功能 */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari, Opera */
|
||||
}
|
||||
}
|
||||
|
||||
.resume-interview-navigation-item {
|
||||
margin-right: 20px;
|
||||
width: 101px;
|
||||
margin-right: 12px;
|
||||
min-width: fit-content;
|
||||
white-space: nowrap;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 100px;
|
||||
padding: 5 16px;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
color: #4e5969;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
background-color: #f7f8fa;
|
||||
color: #2c7aff;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,11 @@ const ResumeInterviewPage = () => {
|
||||
const handlePositionClick = (position, industry) => {
|
||||
// Find resume templates for this industry
|
||||
const templates = pageData.resumeTemplates[industry.name] || [];
|
||||
// 首先根据岗位名称精确匹配
|
||||
const selectedTemplate =
|
||||
templates.find((t) => t.level === position.level) || templates[0];
|
||||
templates.find((t) => t.position === position.title) ||
|
||||
templates.find((t) => t.level === position.level) ||
|
||||
templates[0];
|
||||
|
||||
setResumeModalData({
|
||||
selectedTemplate,
|
||||
@@ -61,7 +64,7 @@ const ResumeInterviewPage = () => {
|
||||
};
|
||||
|
||||
const filterPositions = (positions) => {
|
||||
return positions.filter((position) => position.name.toLowerCase());
|
||||
return positions.filter((position) => position.title?.toLowerCase());
|
||||
};
|
||||
|
||||
// 获取页面数据
|
||||
@@ -71,6 +74,7 @@ const ResumeInterviewPage = () => {
|
||||
setLoading(true);
|
||||
const response = await getPageData();
|
||||
if (response.success) {
|
||||
console.log('页面数据加载成功:', response.data);
|
||||
setPageData(response.data);
|
||||
// 设置默认选中第一个行业
|
||||
if (response.data.industries && response.data.industries.length > 0) {
|
||||
@@ -111,6 +115,28 @@ const ResumeInterviewPage = () => {
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, [pageData?.industries]);
|
||||
|
||||
// 添加鼠标滚轮横向滚动功能
|
||||
useEffect(() => {
|
||||
const navigation = document.querySelector('.resume-interview-navigation');
|
||||
if (!navigation) return;
|
||||
|
||||
const handleWheel = (e) => {
|
||||
const tabs = navigation.querySelector('.navigation-tabs');
|
||||
if (!tabs) return;
|
||||
|
||||
// 检查是否在导航栏区域
|
||||
if (e.currentTarget === navigation || navigation.contains(e.target)) {
|
||||
if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
|
||||
e.preventDefault();
|
||||
tabs.scrollLeft += e.deltaY * 0.5; // 减慢滚动速度使其更平滑
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
navigation.addEventListener('wheel', handleWheel, { passive: false });
|
||||
return () => navigation.removeEventListener('wheel', handleWheel);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="resume-interview-page">
|
||||
{loading ? (
|
||||
@@ -151,7 +177,7 @@ const ResumeInterviewPage = () => {
|
||||
>
|
||||
<span>{position.level}</span>
|
||||
<div className="job-name">
|
||||
<p>{position.name}</p>
|
||||
<p>{position.title}</p>
|
||||
<span>详情 ></span>
|
||||
</div>
|
||||
</li>
|
||||
@@ -163,7 +189,7 @@ const ResumeInterviewPage = () => {
|
||||
key={question.id}
|
||||
className="resume-item"
|
||||
onClick={() =>
|
||||
handleQuestionClick({ ...item, question })
|
||||
handleQuestionClick({ ...item, questions: question.subQuestions || [question] })
|
||||
}
|
||||
>
|
||||
<p>{question.question}</p>
|
||||
|
||||
323
src/pages/ResumeInterviewPage/staticData.js
Normal file
323
src/pages/ResumeInterviewPage/staticData.js
Normal file
@@ -0,0 +1,323 @@
|
||||
// 静态数据 - 直接定义在组件中,不依赖外部接口
|
||||
|
||||
export const staticPageData = {
|
||||
// 行业列表
|
||||
industries: [
|
||||
{
|
||||
id: "homestay",
|
||||
name: "民宿经营",
|
||||
positions: [
|
||||
{
|
||||
id: "homestay_1",
|
||||
title: "民宿管家",
|
||||
level: "初级",
|
||||
department: "民宿经营",
|
||||
type: "全职",
|
||||
experience: "1-3年",
|
||||
education: "本科",
|
||||
salary: "6-10K",
|
||||
location: "北京"
|
||||
},
|
||||
{
|
||||
id: "homestay_2",
|
||||
title: "民宿客房管家",
|
||||
level: "中级",
|
||||
department: "民宿经营",
|
||||
type: "全职",
|
||||
experience: "1-3年",
|
||||
education: "本科",
|
||||
salary: "8-12K",
|
||||
location: "北京"
|
||||
},
|
||||
{
|
||||
id: "homestay_3",
|
||||
title: "民宿运营专员",
|
||||
level: "高级",
|
||||
department: "民宿经营",
|
||||
type: "全职",
|
||||
experience: "3-5年",
|
||||
education: "本科",
|
||||
salary: "10-15K",
|
||||
location: "北京"
|
||||
}
|
||||
],
|
||||
questions: [
|
||||
{
|
||||
id: "homestay_q1",
|
||||
question: "民宿行业面试题",
|
||||
subQuestions: [
|
||||
{
|
||||
question: "如何提升民宿的入住率?",
|
||||
answer: "通过优化OTA平台展示、提升服务质量、季节性定价策略等方式提升入住率。"
|
||||
},
|
||||
{
|
||||
question: "如何处理客户投诉?",
|
||||
answer: "及时响应、诚恳道歉、解决问题、适当补偿、后续跟进。"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "hotel",
|
||||
name: "酒店经营",
|
||||
positions: [
|
||||
{
|
||||
id: "hotel_1",
|
||||
title: "酒店餐饮主管",
|
||||
level: "中级",
|
||||
department: "酒店经营",
|
||||
type: "全职",
|
||||
experience: "3-5年",
|
||||
education: "本科",
|
||||
salary: "10-15K",
|
||||
location: "北京"
|
||||
},
|
||||
{
|
||||
id: "hotel_2",
|
||||
title: "酒店大堂副理",
|
||||
level: "高级",
|
||||
department: "酒店经营",
|
||||
type: "全职",
|
||||
experience: "3-5年",
|
||||
education: "本科",
|
||||
salary: "12-18K",
|
||||
location: "北京"
|
||||
},
|
||||
{
|
||||
id: "hotel_3",
|
||||
title: "餐厅运营经理",
|
||||
level: "高级",
|
||||
department: "酒店经营",
|
||||
type: "全职",
|
||||
experience: "5年以上",
|
||||
education: "本科",
|
||||
salary: "15-20K",
|
||||
location: "北京"
|
||||
}
|
||||
],
|
||||
questions: [
|
||||
{
|
||||
id: "hotel_q1",
|
||||
question: "酒店管理面试题",
|
||||
subQuestions: [
|
||||
{
|
||||
question: "如何提升酒店服务质量?",
|
||||
answer: "建立服务标准、员工培训、客户反馈机制、持续改进。"
|
||||
},
|
||||
{
|
||||
question: "如何管理酒店团队?",
|
||||
answer: "明确职责、激励机制、培训发展、团队建设。"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
// 简历模板
|
||||
resumeTemplates: {
|
||||
"民宿经营": [
|
||||
{
|
||||
position: "民宿管家",
|
||||
level: "初级",
|
||||
studentInfo: {
|
||||
educational_experience: ["旅游管理专业 本科", "XX大学 2020-2024"],
|
||||
project_experience: [
|
||||
{
|
||||
name: "民宿运营管理项目",
|
||||
description: "负责民宿日常运营管理,包括客房清洁、客户服务、订单管理等工作,提升客户满意度和复购率。"
|
||||
},
|
||||
{
|
||||
name: "民宿平台运营实习",
|
||||
description: "在XX民宿平台实习期间,负责房源上架、价格调整、评价管理等工作,熟悉OTA平台运营流程。"
|
||||
}
|
||||
],
|
||||
core_skills: [
|
||||
"熟悉民宿运营管理流程",
|
||||
"掌握OTA平台操作",
|
||||
"良好的客户服务意识",
|
||||
"具备基础的财务管理能力",
|
||||
"了解民宿相关法规政策"
|
||||
],
|
||||
compound_skills: [
|
||||
"新媒体营销能力:能够运营社交媒体账号,制作推广内容",
|
||||
"数据分析能力:能够分析入住率、客单价等运营数据",
|
||||
"危机处理能力:能够妥善处理客户投诉和突发事件",
|
||||
"团队协作能力:能够与清洁、维修等团队良好配合"
|
||||
],
|
||||
personal_summary: "本人毕业于旅游管理专业,对民宿行业充满热情。通过实习和项目经历,积累了丰富的民宿运营经验,熟悉OTA平台操作和客户服务流程。希望能在民宿管家岗位上发挥专业优势,为客户提供优质的住宿体验。"
|
||||
}
|
||||
},
|
||||
{
|
||||
position: "民宿客房管家",
|
||||
level: "中级",
|
||||
studentInfo: {
|
||||
educational_experience: ["酒店管理专业 本科", "XX大学 2019-2023"],
|
||||
project_experience: [
|
||||
{
|
||||
name: "精品民宿客房管理项目",
|
||||
description: "负责20间客房的日常管理,制定清洁标准和流程,培训清洁人员,确保客房品质达到五星级标准。"
|
||||
},
|
||||
{
|
||||
name: "民宿品质提升项目",
|
||||
description: "参与民宿软装升级项目,优化客房布局和用品配置,提升客户入住体验,好评率提升15%。"
|
||||
}
|
||||
],
|
||||
core_skills: [
|
||||
"精通客房管理标准和流程",
|
||||
"掌握客房清洁和布置技巧",
|
||||
"熟悉客房用品采购和管理",
|
||||
"具备团队管理能力",
|
||||
"了解客房安全和卫生规范"
|
||||
],
|
||||
compound_skills: [
|
||||
"审美设计能力:能够进行客房软装搭配和空间优化",
|
||||
"成本控制能力:能够控制客房运营成本,提高利润率",
|
||||
"培训能力:能够培训和指导清洁团队",
|
||||
"质量管理能力:建立和执行客房质量检查体系"
|
||||
],
|
||||
personal_summary: "具有扎实的酒店管理专业背景,专注于客房管理领域。通过系统学习和实践,掌握了客房管理的各个环节,能够独立负责民宿客房的运营管理。追求细节完美,致力于为客户创造舒适的居住环境。"
|
||||
}
|
||||
},
|
||||
{
|
||||
position: "民宿运营专员",
|
||||
level: "高级",
|
||||
studentInfo: {
|
||||
educational_experience: ["旅游管理专业 本科", "XX大学 2018-2022", "工商管理 辅修"],
|
||||
project_experience: [
|
||||
{
|
||||
name: "连锁民宿运营管理",
|
||||
description: "负责5家连锁民宿的整体运营,包括营销推广、收益管理、服务标准制定等,年营收增长30%。"
|
||||
},
|
||||
{
|
||||
name: "民宿品牌建设项目",
|
||||
description: "参与民宿品牌定位和营销策略制定,建立会员体系,提升品牌知名度和客户忠诚度。"
|
||||
}
|
||||
],
|
||||
core_skills: [
|
||||
"精通民宿运营管理全流程",
|
||||
"掌握收益管理和定价策略",
|
||||
"熟悉数字化营销和推广",
|
||||
"具备数据分析和决策能力",
|
||||
"了解民宿行业发展趋势"
|
||||
],
|
||||
compound_skills: [
|
||||
"战略规划能力:能够制定民宿发展战略和运营计划",
|
||||
"品牌营销能力:能够进行品牌定位和营销推广",
|
||||
"财务管理能力:能够进行预算管理和成本控制",
|
||||
"项目管理能力:能够管理多个民宿项目同时运营",
|
||||
"商务谈判能力:能够与供应商、合作方进行商务谈判"
|
||||
],
|
||||
personal_summary: "拥有旅游管理和工商管理双重背景,对民宿运营有深入理解。通过多年实践,积累了丰富的民宿运营和管理经验,擅长通过数据分析优化运营策略,提升经营效益。希望在民宿运营专员岗位上,推动民宿品牌化、连锁化发展。"
|
||||
}
|
||||
}
|
||||
],
|
||||
"酒店经营": [
|
||||
{
|
||||
position: "酒店餐饮主管",
|
||||
level: "中级",
|
||||
studentInfo: {
|
||||
educational_experience: ["酒店管理专业 本科", "XX大学 2018-2022"],
|
||||
project_experience: [
|
||||
{
|
||||
name: "五星级酒店餐饮部实习",
|
||||
description: "在XX五星级酒店餐饮部实习6个月,参与西餐厅和中餐厅的运营管理,协助制定服务标准和流程。"
|
||||
},
|
||||
{
|
||||
name: "酒店宴会服务项目",
|
||||
description: "负责大型宴会的策划和执行,包括婚宴、商务宴请等,成功服务超过50场宴会活动。"
|
||||
}
|
||||
],
|
||||
core_skills: [
|
||||
"熟悉餐饮运营管理",
|
||||
"掌握食品安全标准",
|
||||
"了解成本控制方法",
|
||||
"具备团队管理能力",
|
||||
"熟悉餐饮服务礼仪"
|
||||
],
|
||||
compound_skills: [
|
||||
"菜单设计能力:能够根据市场需求设计菜单",
|
||||
"供应链管理:了解食材采购和库存管理",
|
||||
"活动策划能力:能够策划主题餐饮活动",
|
||||
"客户关系维护:建立和维护VIP客户关系"
|
||||
],
|
||||
personal_summary: "酒店管理专业毕业,对餐饮管理充满热情。通过系统学习和实习经历,掌握了餐饮运营的各个环节。注重服务品质和客户体验,致力于打造优质的餐饮服务。"
|
||||
}
|
||||
},
|
||||
{
|
||||
position: "酒店大堂副理",
|
||||
level: "高级",
|
||||
studentInfo: {
|
||||
educational_experience: ["酒店管理专业 本科", "XX大学 2017-2021", "英语专业 辅修"],
|
||||
project_experience: [
|
||||
{
|
||||
name: "国际品牌酒店前厅管理",
|
||||
description: "在XX国际品牌酒店担任前厅主管,管理前台、礼宾、行李等部门,确保客户服务质量。"
|
||||
},
|
||||
{
|
||||
name: "酒店服务质量提升项目",
|
||||
description: "主导实施服务质量提升项目,建立服务标准体系,客户满意度提升至95%以上。"
|
||||
}
|
||||
],
|
||||
core_skills: [
|
||||
"精通前厅运营管理",
|
||||
"掌握客户服务标准",
|
||||
"熟悉PMS系统操作",
|
||||
"具备危机处理能力",
|
||||
"流利的中英文沟通"
|
||||
],
|
||||
compound_skills: [
|
||||
"跨部门协调能力:能够协调各部门资源满足客户需求",
|
||||
"培训管理能力:制定培训计划,提升团队服务水平",
|
||||
"收益管理:了解房价策略和收益优化",
|
||||
"品牌管理:维护酒店品牌形象和声誉"
|
||||
],
|
||||
personal_summary: "具有扎实的酒店管理专业背景和国际视野,熟悉国际品牌酒店运营标准。通过多年前厅管理经验,培养了卓越的服务意识和管理能力。追求服务excellence,致力于为客户创造难忘的入住体验。"
|
||||
}
|
||||
},
|
||||
{
|
||||
position: "餐厅运营经理",
|
||||
level: "高级",
|
||||
studentInfo: {
|
||||
educational_experience: ["工商管理专业 本科", "XX大学 2016-2020", "餐饮管理 专业认证"],
|
||||
project_experience: [
|
||||
{
|
||||
name: "连锁餐厅运营管理",
|
||||
description: "负责3家连锁餐厅的整体运营,包括人员管理、成本控制、营销推广等,年营业额超过2000万。"
|
||||
},
|
||||
{
|
||||
name: "餐厅品牌升级项目",
|
||||
description: "主导餐厅品牌升级项目,包括菜单优化、装修改造、服务流程再造,营业额增长40%。"
|
||||
}
|
||||
],
|
||||
core_skills: [
|
||||
"精通餐厅运营管理",
|
||||
"掌握财务分析和预算",
|
||||
"熟悉食品成本控制",
|
||||
"具备市场营销能力",
|
||||
"了解餐饮行业法规"
|
||||
],
|
||||
compound_skills: [
|
||||
"战略规划:制定餐厅发展战略和扩张计划",
|
||||
"供应链优化:建立稳定的供应商体系",
|
||||
"数字化运营:运用数据分析优化运营决策",
|
||||
"品牌建设:打造餐厅品牌和文化",
|
||||
"投资分析:评估新店投资回报率"
|
||||
],
|
||||
personal_summary: "工商管理背景,专注餐饮行业多年。具有丰富的餐厅运营和管理经验,擅长通过精细化管理提升运营效率和盈利能力。注重创新和品质,致力于打造有竞争力的餐饮品牌。"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// 我的简历
|
||||
myResume: {
|
||||
name: "张三",
|
||||
position: "应聘岗位",
|
||||
education: "本科",
|
||||
major: "旅游管理",
|
||||
skills: ["运营管理", "客户服务", "数据分析"],
|
||||
experience: "具有相关实习经验"
|
||||
}
|
||||
};
|
||||
@@ -1,47 +1,135 @@
|
||||
import request from "@/utils/request";
|
||||
import { mockData } from "@/data/mockData";
|
||||
|
||||
// 获取企业内推岗位页面聚合数据
|
||||
export async function getCompanyJobsPageData(params) {
|
||||
return request({
|
||||
url: `/api/company-jobs/page-data`,
|
||||
method: "GET",
|
||||
params,
|
||||
// 使用mock数据
|
||||
return Promise.resolve({
|
||||
success: true,
|
||||
data: {
|
||||
jobs: {
|
||||
list: mockData.companyJobs.companyPositions || [],
|
||||
hasMore: false,
|
||||
total: mockData.companyJobs.companyPositions?.length || 0
|
||||
},
|
||||
interviews: {
|
||||
list: mockData.companyJobs.internalPositions || [],
|
||||
hasMore: false,
|
||||
total: mockData.companyJobs.internalPositions?.length || 0
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取企业内推岗位
|
||||
export async function getJobsList(params) {
|
||||
return request({
|
||||
url: `/api/jobs`,
|
||||
method: "GET",
|
||||
params,
|
||||
// 使用mock数据
|
||||
const allJobs = mockData.companyJobs.companyPositions || [];
|
||||
const page = params.page || 1;
|
||||
const pageSize = params.pageSize || 10;
|
||||
const startIndex = (page - 1) * pageSize;
|
||||
const endIndex = startIndex + pageSize;
|
||||
const pageJobs = allJobs.slice(startIndex, endIndex);
|
||||
|
||||
return Promise.resolve({
|
||||
success: true,
|
||||
data: pageJobs,
|
||||
total: allJobs.length,
|
||||
page: page,
|
||||
pageSize: pageSize
|
||||
});
|
||||
}
|
||||
|
||||
// 获取企业内推岗位详情
|
||||
export async function getJobsDetail(id) {
|
||||
return request({
|
||||
url: `/api/jobs/${id}`,
|
||||
method: "GET",
|
||||
// 使用mock数据
|
||||
const allJobs = mockData.companyJobs.companyPositions || [];
|
||||
const job = allJobs.find(job => job.id === id);
|
||||
|
||||
if (job) {
|
||||
return Promise.resolve({
|
||||
success: true,
|
||||
data: job
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve({
|
||||
success: false,
|
||||
message: "岗位不存在"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 获取企业内推岗位面试
|
||||
export async function getInterviewsList(params) {
|
||||
return request({
|
||||
url: `/api/interviews`,
|
||||
method: "GET",
|
||||
params,
|
||||
// 使用mock数据
|
||||
const allInterviews = mockData.companyJobs.internalPositions || [];
|
||||
const page = params.page || 1;
|
||||
const pageSize = params.pageSize || 10;
|
||||
const startIndex = (page - 1) * pageSize;
|
||||
const endIndex = startIndex + pageSize;
|
||||
const pageInterviews = allInterviews.slice(startIndex, endIndex);
|
||||
|
||||
return Promise.resolve({
|
||||
success: true,
|
||||
data: pageInterviews,
|
||||
total: allInterviews.length,
|
||||
page: page,
|
||||
pageSize: pageSize
|
||||
});
|
||||
}
|
||||
|
||||
// 获取简历列表
|
||||
export async function getResumesList(params) {
|
||||
return request({
|
||||
url: `/api/resumes`,
|
||||
method: "GET",
|
||||
params: params,
|
||||
try {
|
||||
// 获取岗位与面试题页面的数据
|
||||
const { getMockPageData } = await import("@/mocks/resumeInterviewMock");
|
||||
const pageData = getMockPageData();
|
||||
|
||||
// 收集所有行业的所有简历模板
|
||||
const allResumeTemplates = [];
|
||||
|
||||
if (pageData.industries && pageData.resumeTemplates) {
|
||||
pageData.industries.forEach(industry => {
|
||||
const templates = pageData.resumeTemplates[industry.name] || [];
|
||||
templates.forEach(template => {
|
||||
allResumeTemplates.push({
|
||||
id: `template_${industry.id}_${template.position}`,
|
||||
title: `${template.position}简历`, // 使用岗位名称作为简历标题
|
||||
position: template.position,
|
||||
industry: industry.name,
|
||||
level: template.level || "初级",
|
||||
skills: template.studentInfo?.core_skills || [],
|
||||
template: template
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 分页处理
|
||||
const page = params.page || 1;
|
||||
const pageSize = params.pageSize || 10;
|
||||
const startIndex = (page - 1) * pageSize;
|
||||
const endIndex = startIndex + pageSize;
|
||||
const pageResumes = allResumeTemplates.slice(startIndex, endIndex);
|
||||
|
||||
return Promise.resolve({
|
||||
success: true,
|
||||
data: pageResumes,
|
||||
total: allResumeTemplates.length,
|
||||
page: page,
|
||||
pageSize: pageSize
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取简历列表失败:', error);
|
||||
// 如果获取失败,返回空列表
|
||||
return Promise.resolve({
|
||||
success: true,
|
||||
data: [],
|
||||
total: 0,
|
||||
page: 1,
|
||||
pageSize: 10
|
||||
});
|
||||
}
|
||||
}
|
||||
// 获取简历详情
|
||||
export async function getResumesDetail(id) {
|
||||
@@ -50,3 +138,21 @@ export async function getResumesDetail(id) {
|
||||
method: "GET",
|
||||
});
|
||||
}
|
||||
|
||||
// 投递简历
|
||||
export async function submitResume(params) {
|
||||
// 模拟投递请求
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
success: true,
|
||||
message: "投递成功",
|
||||
data: {
|
||||
applicationId: Date.now(), // 模拟申请ID
|
||||
submittedAt: new Date().toISOString(),
|
||||
status: "submitted"
|
||||
}
|
||||
});
|
||||
}, 800); // 模拟网络延迟
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,8 +2,23 @@ import request from "@/utils/request";
|
||||
|
||||
// 获取当前登录学生信息
|
||||
export async function getLoginStudentInfo() {
|
||||
return request({
|
||||
url: `/api/students/me`,
|
||||
method: "GET",
|
||||
});
|
||||
// 使用mock数据,避免API请求失败
|
||||
return Promise.resolve({
|
||||
success: true,
|
||||
data: {
|
||||
id: "1",
|
||||
name: "张三",
|
||||
studentId: "2021001",
|
||||
major: "旅游管理",
|
||||
class: "旅游管理2021级1班",
|
||||
email: "zhangsan@example.com",
|
||||
phone: "13800138000"
|
||||
}
|
||||
});
|
||||
|
||||
// 原API请求代码(暂时注释)
|
||||
// return request({
|
||||
// url: `/api/students/me`,
|
||||
// method: "GET",
|
||||
// });
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
getInterviewsList,
|
||||
getResumesList,
|
||||
getResumesDetail,
|
||||
submitResume,
|
||||
} from "./companyJobs";
|
||||
import { getLoginStudentInfo } from "./global";
|
||||
import {
|
||||
@@ -21,7 +22,7 @@ import {
|
||||
getMyRanking,
|
||||
getProfileOverview,
|
||||
} from "./personalProfile";
|
||||
import {} from "./resumeInterview";
|
||||
import { getPageData } from "./resumeInterview";
|
||||
|
||||
export {
|
||||
// 仪表盘相关
|
||||
@@ -49,4 +50,8 @@ export {
|
||||
getInterviewsList, // 获取面试列表
|
||||
getResumesList, // 获取简历列表
|
||||
getResumesDetail, // 获取简历详情
|
||||
submitResume, // 投递简历
|
||||
|
||||
// 简历面试相关
|
||||
getPageData, // 获取岗位与面试题页面数据
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import request from "@/utils/request";
|
||||
import { mockData } from "@/data/mockData";
|
||||
|
||||
// 获取当前登录学生学习进度
|
||||
export async function getLoginStudentProgress() {
|
||||
@@ -10,11 +11,18 @@ export async function getLoginStudentProgress() {
|
||||
|
||||
// 获取仪表板统计信息
|
||||
export async function getDashboardStatistics() {
|
||||
return request({
|
||||
url: `/api/dashboard/stats`,
|
||||
method: "GET",
|
||||
namespace: "globalLoading",
|
||||
// 直接返回mockData中的数据
|
||||
return Promise.resolve({
|
||||
success: true,
|
||||
data: mockData.dashboardStatistics,
|
||||
});
|
||||
|
||||
// 原API调用(暂时注释)
|
||||
// return request({
|
||||
// url: `/api/dashboard/stats`,
|
||||
// method: "GET",
|
||||
// namespace: "globalLoading",
|
||||
// });
|
||||
}
|
||||
|
||||
// 获取当前学生班级排名
|
||||
@@ -36,8 +44,15 @@ export async function getMyRanking() {
|
||||
|
||||
// 获取个人档案完整数据 (新接口)
|
||||
export async function getProfileOverview() {
|
||||
return request({
|
||||
url: `/api/profile/overview`,
|
||||
method: "GET",
|
||||
// 直接返回mockData中的数据
|
||||
return Promise.resolve({
|
||||
success: true,
|
||||
data: mockData.profileOverview,
|
||||
});
|
||||
|
||||
// 原API调用(暂时注释)
|
||||
// return request({
|
||||
// url: `/api/profile/overview`,
|
||||
// method: "GET",
|
||||
// });
|
||||
}
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
import request from "@/utils/request";
|
||||
import { getMockProjectsList, getMockProjectDetail } from "@/mocks/projectLibraryMock";
|
||||
|
||||
// 获取项目列表
|
||||
export async function getProjectsList(params) {
|
||||
const USE_MOCK = true;
|
||||
if (USE_MOCK) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(getMockProjectsList(params));
|
||||
}, 300);
|
||||
});
|
||||
}
|
||||
return request({
|
||||
url: `/api/projects`,
|
||||
method: "GET",
|
||||
@@ -10,6 +20,14 @@ export async function getProjectsList(params) {
|
||||
|
||||
// 获取项目详情
|
||||
export async function getProjectsdetail(id) {
|
||||
const USE_MOCK = true;
|
||||
if (USE_MOCK) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(getMockProjectDetail(id));
|
||||
}, 200);
|
||||
});
|
||||
}
|
||||
return request({
|
||||
url: `/api/projects/${id}`,
|
||||
method: "GET",
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
import request from "@/utils/request";
|
||||
import { getMockPageData } from "@/mocks/resumeInterviewMock";
|
||||
|
||||
// Get all page data for resume-interview page
|
||||
export const getPageData = () => {
|
||||
export const getPageData = async () => {
|
||||
// 使用mock数据
|
||||
const USE_MOCK = true;
|
||||
|
||||
if (USE_MOCK) {
|
||||
// 包装mock数据以匹配API返回格式
|
||||
const mockData = getMockPageData();
|
||||
return {
|
||||
success: true,
|
||||
data: mockData
|
||||
};
|
||||
}
|
||||
|
||||
return request({
|
||||
url: "/api/resume-interview",
|
||||
method: "GET"
|
||||
|
||||
209
内推岗位.csv
Normal file
209
内推岗位.csv
Normal file
@@ -0,0 +1,209 @@
|
||||
内推岗位名称,薪资,工作地点,学历要求,招聘人数,截止时间,职位标签,职位描述,任职要求,公司介绍
|
||||
品牌公关,8-10k,东莞,本科及以上,4人,2025/7/11 17:00,"公关媒介代理商/服务商(乙方), 市场营销, 甲方品牌公关经验, 媒介投放经验, 优秀的传播策划能力","1、策划并执行品牌公关活动,提升公司在行业内的品牌形象和知名度;
|
||||
2、建立并维护媒体关系,有效管理危机公关,确保公司信息准确传达;
|
||||
3、组织和参与各类行业会议、展览及活动,扩大品牌影响力;
|
||||
4、监测并分析市场动态及竞争对手公关策略,为公司品牌发展提供参考。","1、本科及以上学历,市场营销、新闻传播、公共关系等相关专业优先;
|
||||
2、1年以上品牌公关或相关领域工作经验,有石油化工行业背景者优先;
|
||||
3、具备出色的沟通能力及谈判技巧,能独立处理媒体关系和公关危机;
|
||||
4、具有较强的创意策划能力和项目管理经验,能够带领团队完成高质量的项目。","我与我(广州)科技有限公司成立于2021年,是一家充满活力与创新精神的年轻企业。公司坐落于繁华都市中的甲级创意园内,多路公交及地铁8号线可直达。我们拥有一间充满现代气息的办公室,这里不仅是我们的工作场所,更是创意与灵感碰撞的火花源地。
|
||||
我们的团队由一群年轻、热爱美妆、追求时尚的年轻人组成;
|
||||
我们专注于彩妆、美妆及护肤产品的研发与销售,希望通过缤纷的色彩和独特的风格,为女性打造个性且精致的妆容;
|
||||
我们坚持选用高品质的材料,先进的技术,深入洞察女性最切实需求,打造极具高性价比且精致的产品;
|
||||
我们坚持孵化更多品牌产品,凭借对美的独到见解和市场趋势的敏锐洞察,致力于为消费者带来更高品质及更个性化的体验。
|
||||
在这里,每一份努力都汇聚成美丽的力量,让美丽触手可及,期待您的加入。"
|
||||
文创产品设计师,6-11k,佛山,本科及以上,8人,2025/6/23 11:00,"手绘, 1-3年插画经验, 有插画经验/技能, 带薪假期, 年终奖, 年终奖, 大小周","1. 负责公司文创品牌的产品设计,制作打样稿。产品包括所有类目本册,胶带,贴纸,礼盒等创意类文创产品 ;
|
||||
2. 能独立完成平面图,能根据运营策略将文案与平面设计进行深度融合;
|
||||
3. 本人热爱文创行业且了解国内,韩国的文创市场热度和趋势;
|
||||
4. 能独立制作产品开发提案并进行相关产品的创作,保证设计版权的原创性;
|
||||
5. 对产品设计有自己的观点和见解,具备独立完成设计项目的能力。","1. 本科及以上,设计相关专业,有成功的文创设计案例者优先。
|
||||
2. 熟练掌握各类设计软件,如AI 、Photoshop等,具备扎实设计功底与文案转化能力。
|
||||
3. 熟悉国内外(含韩国)文创市场,热爱文创行业,有独立设计思维与创新力。
|
||||
4. 注重细节,执行力强,具备用户思维与团队协作能力。","哇赛优尚(广东)品牌管理有限公司是一家集开发设计、生产和销售为一体的品牌公司,专营文创文玩类商品。公司创始人自1994年开始经营贴纸产品以来,公司逐步成立生产基地,创立自有品牌,IP代理生产销售和开发授权原创IP及周边产品,深耕贴纸文创行业30年,为全国文具玩具精品百货等相关连锁终端渠道提供服务,致力于成为文创文玩领域的领航者!
|
||||
公司现有员工100多人,拥有年轻创新的95后设计团队近20人,专注于原创产品的设计开发。公司拥有“哇噻优尚”“Inamazy”等自主品牌,拥有“Melon、SULI、RuRu”多个原创IP,拥有二十几件版权登记和专利证书。公司旗下吉登生产基地是迪士尼官方Fama认证工厂,通过ISO9001和佛山市环评报告认证。
|
||||
公司是集合原创开发、文创用品自主设计、版权运营为一体的综合型文创品牌企业,专营文化用品及礼品、创意文教用品的线下及线上销售。企业提倡“无限惊喜,治愈生活”的品牌理念,致力于为对生活有追求、有热情的年轻一族,打造出富有创意的IP形象与精致实用的文创产品,为他们的生活创造更多的惊喜与美好!"
|
||||
旅游计调专员,6-8k,滁州,大专及以上,8人,2025/6/28 14:00,"OTA平台接单, 组团社, 需要计调经验, 旅游行业资源, 维护同业客户, 不需要出差/跟团出游","1、负责旅游团队的全程计调工作,行程规划、资源调配与协调;
|
||||
2、与客户进行有效沟通,了解客户需求,提供专业的旅游咨询与解决方案;
|
||||
3、监控旅游服务质量,及时处理行程中的突发情况,确保客户满意度;
|
||||
4、与供应商建立并维护良好的合作关系,确保资源的稳定与优惠;","1、具备较强的组织协调能力和解决问题的能力;
|
||||
2、热爱旅游行业,具有良好的服务意识和团队合作精神;
|
||||
3、熟练使用办公软件,具备良好的文案撰写和数据分析能力;
|
||||
4、有旅游行业相关工作经验者优先考虑。","广西驴友邦信息科技有限公司成立于2013年,前身为桂林佳音旅游,是一家集旅行社+互联网+科技为一体的新型互联网旅游科技公司。
|
||||
公司自成立以来一直践行“让旅游更美好”这一理念,多年来专注打造高品质的纯玩旅游产品,并以独特的互联网+旅游+科技为核心的经营模式,充分利用各大旅游乎台及短视频直播等载体,通过十年的深耕拓展,一跃成为头部的旅行品牌。
|
||||
公司本着以创新谋发展的宗旨,依托桂林旅游辐射全国,不断复制壮大,目前已分别在新疆、西藏、四川青海、云南五个旅游大省创立了全资子公司。公司还致力于开辟全球市场,产品线路遍布世界各地,年交易规模超过2亿。
|
||||
未来公司将继续恪守并弘扬企业价值观和企业文化,追求极致、务实敢为,以优质的产品和服务回馈客户需求,努力使驴友邦成为中国领先的旅游品牌。"
|
||||
活动策划师,6-9k,苏州,大专及以上,7人,2025/7/12 9:00,"文案策划, 策划, B端客户, 活动策划","1、根据客户提供的业务信息撰写输出活动策划全案;
|
||||
2、负责与客户的前期沟通,协助项目部完成提案,向客户初步阐述方案内的创意及流程;
|
||||
3、根据活动需求进行资料,资源的搜集、整合,协助主案撰写活动策划全案、活动主题;
|
||||
4、将活动策划全案转化落地为活动执行案,细化活动执行流程,
|
||||
5、提供最有性价比的执行方式或创意,制定具体执行方案,能把控协助统筹执行落地;
|
||||
6、与设计、执行等团队成员高度配合,结合活动举办地点完成方案创意的执行,协助设计师和执行人员进行相关的设计和制作;","1、有活动策划经验,类目不限,愿意长期从事策划方向,大专及以上学历
|
||||
2、文字功底强,工作效率高,学习能力强
|
||||
3、逻辑思维能力比较强,创新及创意能力强,洞察力强","磁力文化,雇主品牌建设落地解决方案领导者.以“让企业组织更信任”为使命,致力于为企业打造更有吸引力的雇主品牌.专注于以创意内容为核心,以创意驱动传播,以数字互联网为平台,为企业提供全场景的雇主品牌服务.围绕以员工价值主张(EVP-Employee Value Proposition),以员工为核心,以体验为基础,与期望相结合,以贴近受众群体的表达方式。核心部门:客户服务中心、创意研发中心、项目管理中心、技术中心。涉及业务范围:企业文化活动、福利、文化宣传、文化咨询
|
||||
目前拥有三家全资子公司:乐游团建、闪一点传媒、上上礼礼品"
|
||||
二次元周边店店长,8-9k,上海,大专及以上,2人,2025/8/5 17:00,"损耗管理, 员工培训, 五险一金, 1-3年门店店长经验, 连锁门店经验","1、了解公司对门店管理的经营标准(店务标准、陈列标准、货品管理、管理红线、门店标准化制度)以及各项规章制度;
|
||||
2、规划及监督店铺人员配置数量,负责门店员工的日常工作、员工能力提升及培养工作;
|
||||
3、维护公司品牌形象及为顾客提供优质的服务(包括但不仅限于:接待顾客、解答顾客查询、处理投诉及提供售后服务等);
|
||||
4、管理门店商品进销存,清楚店铺货品流转情况, 店铺货品正常周转,确保商品库存合理,产品陈列储存恰当,查验产品,保证产品品质,做好商品台账;
|
||||
5、较强的团队管理能力和沟通能力,及时解决基本的员工关系事件;
|
||||
6、积极主动配合上级领导处理门店相关事宜,态度端正,情绪稳定 。","1、大专或同等以上学历,并持有营业员上岗证、健康证;
|
||||
2、三年或以上零售店铺管理经验,有潮玩品牌或相似品类销售工作背景者优先;
|
||||
3、能熟练操作计算机、POS系统及Microsoft Office办公软件;
|
||||
4、具备高度的责任心及店铺人员管理理念,主动性强并能承受工作压力;
|
||||
5、须了解、认同并实践“优质服务”理念;
|
||||
6、有亲和力,语言表达沟通能力强;
|
||||
7、诚实守信,忠诚度高,热忱于零售工作并适应其工作节奏;
|
||||
8、对二次元文化有一定了解者优先。","雪叶是主做游戏&动漫周边产品,并致力于IP衍生品研发的电商平台;是集代运营,产品开发,创意设计于一身的综合服务公司;
|
||||
目前合作有食物语、卡拉比丘、天涯明月刀、光与夜之恋,仙剑奇侠传、王者荣耀等十几个知名品牌;品类涉及手办模型、毛绒玩偶、3C数码、服装配饰等;"
|
||||
宠物店店长,6-9k,泸州,大专及以上,2人,2025/7/20 22:00,"1-3年门店店长经验, 不需要晚班/夜班, 员工培训, 连锁门店经验, 业绩管理","1.熟练掌握宠物店前台接待、销售的各项工作;
|
||||
2.带领团队达到公司各项工作指标;
|
||||
3.监督管理门店日常运营达到公司要求:礼仪,分工,卫生,安全,业绩等;
|
||||
4.监督管理门店团队,正向引导,定期培训考核,提升团队综合能力;
|
||||
5.监督管理门店安全,包括服务安全,客诉安全,人员安全,财务安全等;
|
||||
6.监督管理门店商品,耗材等进销存;
|
||||
7.监督管理门店客户服务,客户维护,降低客户流失率;
|
||||
8.制作并分析门店各项运营报表,对公司决策提供数据支持;
|
||||
9.与公司其他部门协作完成各项工作;
|
||||
10.完成公司交办的其他相关工作。","1.喜爱小动物,对待小动物有爱心,有耐心,有责任心;
|
||||
2.同岗位从业经验1年以上;
|
||||
3.亲和力,沟通理解能力,普通话表达能力佳;
|
||||
4.思维敏捷,服务意识,团队意识,职业素养佳;
|
||||
5.积极上进,吃苦耐劳,执行力佳;
|
||||
6.熟悉基本电脑操作及办公软件操作,如word ,excel,钉钉等。
|
||||
7.有相关工作经验者优先录用;","厉害宠物公司简介:公司旗下分别有帕帕拉兹宠物、独角兽宠物、强力猫宠物以及厉害宠物医院服务品牌。公司于2015年在成都正式成立,于2021年完成千万级天使轮投资。为顾客提供宠物的相关服务,是一家集宠物食品用品销售、洗澡美容、护理、宠物酒店住宿、游泳竞赛玩乐, 宠物售卖、宠物主人交流放松 的宠物休闲中心。目前在成都有30余家直营店和加盟店, 以“一生的陪伴与呵护”为口号,力求全方位发展。
|
||||
|
||||
从外部装修环境,门店设计细节都能击中用户,想会员所想,用心服务好每一位客人,宠物超市超低价格品质保障,打造连锁品牌体量优势,做到网状覆盖,线上运营,实现足不出户即可满足宠物一切衣食住行,做到全方位一条龙。为提高运营效率, 自主开发一套管理系统,实现门店管理信息化。"
|
||||
客房经理,6-8k,海南,大专及以上,8人,2025/6/3 5:00,"包住, 客房管理经验, 经济型, 餐补, 普通话标准","1、负责客房部的日常管理工作,确保服务质量和客房清洁达到高标准;
|
||||
2、监督客房清洁、客房服务和设备维护,确保所有设施处于良好状态;
|
||||
3、培训和发展部门员工,提升团队的专业技能和服务意识;
|
||||
4、制定和实施客房部的运营计划,优化工作流程,提高工作效率;
|
||||
5、处理客户反馈和投诉,改善客户体验,确保客户满意度。","1、具备酒店管理或相关领域的专业背景,至少3年客房管理经验;
|
||||
2、熟悉客房服务流程和标准,有较强的组织能力和团队领导力;
|
||||
3、优秀的沟通能力和问题解决能力,能够处理突发事件;
|
||||
4、注重细节,具有良好的客户服务意识和高度的责任心;
|
||||
5、能够适应灵活的工作时间,包括周末和节假日。",马氏集团坐落于著名的“武术之乡”——河北沧州,由知名企业家马千里先生创建于1995年,总部位于狮城标志性建筑之一管业大厦,现有员工500余名,总资产达6亿余元,年营业额1.8亿余元,年上缴利税约800万元,总营业面积7万余平方米。集团下辖7个子公司,是一家以引进和经营国际国内顶尖高端品牌为主,专业致力于餐饮、酒店管理运营的大型综合性企业集团。
|
||||
民宿客房管家,6-8k,黄冈,大专及以上,10人,2025/7/25 13:00,"包住, 星级酒店经验, 全勤奖, 普通话标准","1、负责民宿客房的日常清洁与维护,确保提供舒适的住宿环境;
|
||||
2、检查客房设施,及时发现并解决潜在问题,保障客房服务质量;
|
||||
3、协助处理客房内的简单维修工作,保持卫生和整洁;
|
||||
4、驾驶工作用车,接送客人","1、会熟练驾驶手动挡汽车
|
||||
2、会基础客房水电维修
|
||||
3、具备良好的服务意识和沟通技巧,能够热情接待每一位客人;
|
||||
4、有责任心,注重细节,能够独立完成客房清洁和准备工作;
|
||||
5、有相关工作经验者优先,但愿意学习和适应民宿行业者也可;
|
||||
6、身体健康,能适应灵活的工作时间,包括周末和节假日;
|
||||
7、热爱自然,对乡村生活有一定的了解和兴趣,能够与团队良好合作。",纵横寓是一家颠覆传统 开启全新房屋管理模式的租赁公司<E585AC>未来5年到10年将发展遍布23个省会城市,每个城市设置总部和6家签约中心,整体规模达到3000人以上。我公司将人力资源储备作为战略发展第一要务。公司为员工提供完善的福利计划、系统的培训和晋升机制<E69CBA><E588B6>如果你是充满理想,品行正直,渴望成就人生的年轻人,诚邀加入我们的团队!
|
||||
ip运营,8-13k,河南,大专及以上,4人,2025/8/19 3:00,"短视频运营, 客资转化, IP打造","1.熟悉抖音平台运营规则和玩法,负责 IP 、账号打造。
|
||||
2.负责媒体内容运营以及推广,打造个人 ip 垂直领域内容。
|
||||
3.负责公司老板的个人 ip 打造,视频为主。
|
||||
4.善于挖掘用户痛点,需求点,能很好的把文案,用户的痛点,产品特色,有效结合,从而提出建设性意见,调整内容方向和推广方案。
|
||||
5.打造粉丝运营以及变现能力,并推动0-1的落地执行。","1.拥有3 年以上 IP 运营相关经验,熟悉 IP 孵化、内容运营、商业化变现等全流程,有成功打造知名 IP 的案例者优先。
|
||||
2.具备敏锐的市场洞察力和战略思维,能够准确把握 IP 行业的发展趋势,为公司 IP 战略提供前瞻性建议。
|
||||
3.拥有出色的团队管理能力和沟通协调能力,能够带领团队高效协作,同时与公司内部各部门及外部合作伙伴建立良好的合作关系。
|
||||
4.对建材领域有浓厚兴趣,具备创新精神,能为 IP 运营注入新鲜创意。",河南豪莱特集团是河南豪莱特装饰工程有限公司旗下品牌。河南豪莱特装饰工程有限公司于2022年03月31日创办,公司创立于河南省郑州市新郑市孟庄镇第一幼儿园东南侧150米2号;全心致力于一般项目:建筑装饰材料销售、建筑材料销售、有色金属合金销售、金属材料销售、金属制品销售、高性能有色金属及合金材料销售、金属结构销售、建筑用金属配件销售、金属工具销售、金属切割及焊接设备销售、五金产品零售、门窗销售、轻质建筑材料销售、金属切削加工服务、金属门窗工程施工、园林绿化工程施工等服务。公司性质为有限责任公司(自然人独资),注册资本500万人民币,
|
||||
品牌推广专员,7-10k,海口,大专及以上,7人,2025/9/10 8:00,"销售工作经验, 直播, 可接受外勤和出差","1. 负责公司品牌形象的推广与建设,提升品牌知名度和美誉度;
|
||||
2. 策划并执行线上线下品牌营销活动,增强用户互动和品牌忠诚度;
|
||||
3. 监测市场动态及竞争对手品牌策略,为品牌调整提供有效建议;
|
||||
4. 协调内外部资源,确保品牌推广活动的顺利进行和效果最大化;
|
||||
5. 维护并拓展媒体关系,提升品牌在目标受众中的影响力。","1. 相关专业优先;
|
||||
2. 具备良好的创意策划能力和文案撰写技巧,能够独立完成品牌推广方案;
|
||||
3. 熟悉社交媒体运营及数字营销工具,有成功案例者优先;
|
||||
4. 具有较强的沟通协调能力,能够高效推进项目执行;
|
||||
5. 对市场趋势敏感,具备较强的数据分析能力和问题解决能力。",海南老友通讯坐落于海口市龙华区金龙路7号兴业银行大厦B座1303。隶属于香港路尚集团,是一家集移动支付、AI人工智能科技研发、日用百货贸易,投资管理为一体的综合型企业。一直秉承着创业的激情与梦想,在变化莫测的市场中,不断变革,不断创新,不断超越,经过几十年的蜕变与发展成功打造出<路尚>,<路易百纳>,< 海灵顿>,<芙德里娜>,<胡芙>等自主品牌,并与李时珍、蓝月亮、袋鼠皮具、民生银行、兴业银行、海南银行、广发银行、平安银行等国内外知名企业品牌进行深度战略合作。从单一的公司结构发展到今天公司覆盖全国93个城市近237家分公司的集团企业。老友通讯主要运营通讯业务,范围遍布全国各个大中型城市,目前已与深圳电信,海南联通等达成战略合作协议。致力于全国更多城市的电信、联通业务拓展和深度合作,未来主要服务于国内电信、移动、联通三大运营商。二十年来我们集团管理层都是从内部提升,给予企业内部员工更大的发展空间。在这里没有人能限制你赚钱的能力和对成功的渴望。我们不仅像天使基金一样为“未来企业家”提供资金支持,更为他们提供能力成长所需资源,如完善的轮岗轮部门培训、系统的实践、成长期的收入保障。 公司人性化的管理为员工定期组织各种国内外的旅行,并有丰厚职位津贴、绩效奖金、带薪年假、住房补助、奖车奖房计划等。海口公司向全国培养输送了二十几名职业经理人,为集团的发展做出了巨大贡献,被集团誉为:职业经理人的摇篮! 结合国家最大自贸港的建设,根据集团的战略规划,现在大力度布局华南自贸港地区拓展更多的分公司与新部门,欢迎有志之士加入我们果知数字科技的大家庭。让我们一起合一、共赢、卓越、创造属于我们的佳绩!
|
||||
社群运营,6-11k,贺州,大专及以上,12人,2025/6/25 13:00,"接受居家办公, 用户精细化运营, 数据分析能力","1.负责社群的日常运营管理,确保社群活跃度;
|
||||
2.策划并执行社群相关活动,增强社群成员的参与感和归属感;
|
||||
3.监控社群动态,及时处理社群内的各类问题;
|
||||
4.收集和分析社群反馈,为社群运营策略提供参考;
|
||||
5.与其他部门合作,共同提升社群运营效果。","1.具备良好的沟通能力和团队合作精神;
|
||||
2.对社群运营有浓厚的兴趣,能够灵活运用社群工具;
|
||||
3.具有较强的问题解决能力,能够迅速应对社群中的突发事件;
|
||||
4.拥有良好的数据分析能力,能够根据数据调整运营策略;
|
||||
5.具备创新思维,能够不断优化社群运营方案。","湖南元特企业管理服务有限公司是一家专注于为年轻人以及有梦想敢于拼搏的人提供全方位创业支持的新型企业管理服务平台。我们深刻理解当代年轻人在创业初期面临的资金短缺、经验不足、资源匮乏、后端服务等核心痛点,因此创新性地提出了“0投资0风险0门槛”的创业扶持模式,旨在彻底打破传统创业的高投资高风险高门槛壁垒,让每一个有梦想的人都能平等获得创业机会。
|
||||
|
||||
在数字经济蓬勃发展的时代背景下,我们整合了超过200家战略合作伙伴资源,构建起包含项目孵化、技能培训、渠道共享、法律咨询、品牌推广、中后端运行、在内的十二大赋能体系。通过独创的""创业帮扶""服务模式,创业者无需承担场地租金、设备采购、人员工资等传统成本,即可通过我们的共享创业平台开展业务。目前我们已经成功孵化了涵盖电商运营、新媒体营销、拓客渠道、创意引流、人工智能Ai获客系统、等领域的36个前端运营体系化,能达到极高的成效,让天下没有难做的生意!
|
||||
|
||||
我们的专业团队由资深创业导师、行业专家和成功企业家组成,平均拥有10年以上企业服务经验。区别于传统孵化器,我们更注重实战能力的培养,通过""理论培训+项目实操+资源对接+一对一帮扶""的四维成长路径,帮助创业者在真实商业环境中快速成长。同时,我们与多家风险投资机构建立了深度合作,为优质项目提供后续融资支持,真正实现从0到1再到100的全程陪伴扶持式成长。"
|
||||
演出执行经理,6-8k,武汉,本科及以上,8人,2025/7/7 8:00,"活动执行统筹经验, 一般企业, 艺术/文化展","1. 负责演出现场执行工作,确保演出顺利进行;
|
||||
2. 整理演出项目报批材料,确保所有相关事项符合标准;
|
||||
3. 与团队成员进行有效沟通,协调演出各版块事项;
|
||||
4. 负责演出物料的输出与新媒体运营工作。","1. 具备演出执行经验;
|
||||
2. 熟悉文化产业管理或演出制作等相关专业;
|
||||
3. 具有良好的文案撰写能力和语言表达能力,能够有效进行沟通与协作;
|
||||
4. 对工作细心负责,思维敏捷;
|
||||
5. 熟练掌握OFFICE、WPS等办公软件;
|
||||
6. 能够承受工作压力,具有良好的执行应变能力。",新东联合文化成立于2016年,主营文化演出、会议会展、场馆运营、体育赛事,专注于组织举办各类大型文体活动,并致力于繁荣文化演出市场,活跃大众文化生活。截至2025年,新东联合组织举办各类文体活动超过300场,观众累计超过100万人次。运营活动类型包括大型巡演、大型会议、品牌发布会、明星见面会、体育赛事等。曾连续获得第七届世界军人运动会拳击比赛、女子篮球比赛“优质供应商”、演出市场年度贡献奖等荣誉称号,在世界级文体活动中展现了企业的专业与实力。
|
||||
新媒体运营专员,6-10k,呼伦贝尔,大专及以上,13人,2025/8/15 16:00,"电商, 团队管理经验, 策划热点事件, 短视频运营","1、负责公司新媒体平台(抖音,视频号等)的内容策划与日常运营;
|
||||
2、撰写创意文案,制作吸引人的图文、视频内容,提升品牌曝光度和用户互动;
|
||||
3、监控和分析新媒体平台的数据表现,根据反馈调整运营策略;
|
||||
4、策划并执行线上活动,增强粉丝活跃度和用户粘性;
|
||||
5、与团队协作,确保品牌信息的一致性和传播效果的最大化。","1、熟悉主流社交媒体运营机制,有成功的新媒体运营案例;
|
||||
2、具备良好的文案撰写能力,能够独立完成内容创作;
|
||||
3、对新媒体趋势有敏锐的洞察力,能够把握用户喜好;
|
||||
4、数据分析能力强,能够通过数据指导内容优化;
|
||||
5、具有良好的团队合作精神,能够高效沟通并快速响应市场变化。",本公司深耕直播及短视频拍摄等网红孵化业务,自2020年7月创立至今,根据主播需求为主播提供包括但不限于直播技巧培训、短视频拍摄、线下直播间场地等特色服务。公会拥有直播运营经验丰富地成熟团队,日常主要帮助主播打造直播人设、优化直播内容;短视频团队,主要负责短视频拍摄、剪辑、脚本策划等内容;全方位服务于主播,提升主播内容生产及流量获取能力。
|
||||
餐厅运营经理,8-13k,渭南,大专及以上,7人,2025/9/2 21:00,"餐厅运营, 品类运营, 运营部门管理, 有餐饮店长经验, 活动策划","1、负责餐厅日常运营管理工作,确保服务质量和食品安全标准;
|
||||
2、优化餐厅运营流程,提升顾客满意度和营业额;
|
||||
3、管理并培训员工,提升团队的专业技能和服务意识;
|
||||
4、监控成本控制,确保财务目标的实现;
|
||||
5、处理顾客反馈和投诉,维护品牌形象。","1、具备餐饮行业相关管理岗位经验,熟悉餐厅运营流程;
|
||||
2、出色的团队领导能力和沟通技巧,能够激励团队达成目标;
|
||||
3、优秀的解决问题能力,能够在高压环境下作出快速决策;
|
||||
4、熟悉财务报表和成本控制,具备良好的数据分析能力;
|
||||
5、热爱餐饮行业,对顾客服务有深刻理解并追求卓越。负责自营大学档口餐厅","陕西候鸟家园国际旅行社有限公司是上海生道堂旗下的旅居养老健康高端服务品牌,坐落于西安市未央区凤城一路雅荷花园中环大厦A座,上海生道堂成立于2010年,在北京、上海、重庆、黄山、海南、四川、陕西等地设立多个分支机构,生道堂是一家集中医药研究、基地疗养、健康管理、社区养老、生命监护、候鸟式养生、养老、旅居等健康研究管理机构,将中医与养老相集合的新型健康养老产业,是生道堂未来发展的方向,未来生道堂陆续在全国乃至世界各地,建立舒适高品质的候鸟式养生养老基地。
|
||||
陕西候鸟家园秉承“敬老爱老、真诚奉献、孝行天下”的企业宗旨,建立一个以健康、快乐为宗旨,以旅游旅居为核心,以健康服务为根本的,为老服务产业体系,争取在6年内,在中国建立500家旅居基地,国外一百多家旅居基地的家园,让客户家人到哪里都感到家的温暖与细致服务,并提供健康服务与养老服务一体化的,成为为天下老人健康、快乐做出贡献的有价值的伟大公司!"
|
||||
景区运营专员,6-8k,四川成都,大专及以上,9人,2025/6/30 7:00,"业务运营, OTA平台, 经验一年以内","1、切换工作:在规定时间内完成项目所有链路对接及切换工作(票务系统链路、核销链路、回款链路、发票链路);
|
||||
2、线上运营:门票上下架、渠道筛查、POI信息维护;
|
||||
3、线下执行:项目线下票口切换工作、线下活动执行所需要的物料落地;
|
||||
4、沟通协调:协调各方如景区、上级、驻场同事等解决项目运营过程中遇到的任何问题;
|
||||
5、数据统筹:核销数据汇总,同期对比,原因分析","1.具备文旅行业相关工作经验,熟悉景区运营管理、票务系统及线上线下运营流程;有景区、OTA平台(如抖音、携程、美团等)工作经验者优先考虑
|
||||
2.具备良好的沟通协调能力,能够高效对接多方资源(如景区、上级部门、驻场团队),推动项目落地;
|
||||
3.优秀的执行力与问题解决能力,能够在规定时间内完成复杂链路的切换及线下执行任务;
|
||||
4.熟悉数据统计与分析方法,能独立完成核销数据汇总、对比及原因分析,为运营决策提供支持;
|
||||
5.具备一定的线上运营意识,了解渠道管理、POI信息维护及相关操作;
|
||||
6.工作认真负责,具备较强的责任心与抗压能力,适应临时性任务安排,能接受短期出差;",成都所见所得传媒集团有限公司总部位于成都高新区,注册于2022年4月,是国内领先的“新媒体+文旅集团”。 集团业务涵盖直播电商、数字文旅、品牌管理、MCN+娱乐等,于2023年开创文旅RBF合作模式并正式开展文旅业务,重点从事文化、旅游及运营业务,业务模式以RBF业务为主。是全球首个文旅RBF模式,服务于中国境内各大景区、旅游、演出、体育POI。
|
||||
会展策划师,6-7.5k,西安,大专及以上,5人,2025/7/18 14:00,"展馆策划, 多媒体文案策划, 脚本分镜策划, 文案策划, PS","1、负责展厅项目(如政府规划馆、博物馆、企业展厅、各类主题展馆等)相关展馆的理念、内容等创意策划;并针对客户需求进行方向确定、整体策划、提案;文案的策划、创意、撰写与执行(尤其是创意脚本);设计过程中的管控和进度推进,如:时间节点、多方沟通协调、汇报;项目案场效果跟进;
|
||||
2、独立跟进项目,负责向客户提案讲解,参与项目招投标流程;
|
||||
3、参与项目考察及前期调研工作,并进行相关资料的收集与整理;
|
||||
4、能够统筹完成各类大案,负责项目的创意构思和营销策略、推广的总体思路、有效的把握项目进程;
|
||||
5、根据策划方案指导设计人员进行空间、平面等设计工作。配合市场客服部工作需要,和相关人员完成客户需求;
|
||||
6、文笔流畅,善于撰写脚本创作,有较强的文字驾驭能力和创意能力;具有较强的分析判断能力文字组织能力、方案策划能力、谈判能力以及公关能力;
|
||||
7、对展厅类项目有较好的见解,能完成大型展览展示创意策划;
|
||||
8、用PPT、WORD等制作策划方案;","1、大专以上学历,会展策划、多媒体艺术、空间设计、广告传播、中文等相关专业;
|
||||
2、1年以上策划工作经验;2年以上大型展馆(规划馆、博物馆、科技馆、主题馆等)主案策展经验;对展厅类项目有较好的见解,能完成大型展览展示策划设计;能够准确了解客户要求,把握策划方向;
|
||||
3、有较强的理解能力、策略分析能力、文字撰写能力、协调能力;责任心强;较强的PPT制作能力;具有一定的审美;对新的互动科技有兴趣;
|
||||
4、诚实敬业,有激情、工作认真负责,责任心强,具备较强的团队合作精神,思维活跃积极向上;
|
||||
5、根据策划方案指导设计人员进行空间、平面等设计工作。配合市场客服部工作需要,和相关设计人员完成客户需求;
|
||||
6、文字功底深厚,具有独立提案能力;创意型策略人才,准确了解客户要求,能正确把握策划方向。对展览展示有独到的理解能力,对展览展示空间设计有一定程度的了解;","西安西缘网络科技有限公司(以下简称“西缘科技)成立于2018年1月,公司以人工智能(AI)和虚拟现实(VR)技术创新研发的国家高新技术企业。产品应用领域覆盖文旅、教育、医疗、党政机关、企事业单位。
|
||||
成立至今,已成功实施落成项目2300余例,拥有丰富的硬件产品研发、软件技术开发,多媒体内容制作的经验。
|
||||
西缘科技将致力于成为国内教育、科普、文旅与科技跨界融合的一流高端服务商,为各界合作伙伴打造领先的产品,树立品牌标杆,为客户提供更加优质的产品和服务。"
|
||||
商业会展执行专员,7-10k,武汉,大专及以上,10人,2025/8/9 19:00,"会展策划执行经验, 可接受出差, 会展活动, 公关会展专业","1、独立开展项目调研、立项、运营、实施工作;
|
||||
2、组织开展招商、邀观、重大活动自办、引进工作;
|
||||
3、与政府部门/主协办单位/展馆/行业协会/媒体机构等开展对接并维护公共关系;
|
||||
4、展会项目的现场管理,含主场服务组织、配套商务服务的组织实施、项目预算结算管理;","1、2年以上展览(含会议)项目管理经验,熟悉会展的立项实施流程
|
||||
2、具备带领团队完成新项目开拓的拓展能力;
|
||||
3、具备文案写作、策划案写作能力;
|
||||
4、具备良好的沟通能力,敏锐的分析及判断能力;
|
||||
5、性格开朗,态度积极,能承受较强的工作压力,有创业激情,对环境及岗位适应能力强;英语六级者优先",武汉食和岛网络科技有限公司成立于2016年,是一家“致力于食材展览,服务于食材流通”的食材展业综合服务公司,创建了食材商务服务营销平台,为餐饮食材供需双方提供高效互动。食和岛旗下会展品牌“良之隆·中国食材电商节”创立于2008年,曾荣获2017年度中国十佳品牌展会项目大奖,在2018年11月成为了湖北省第一家获得国际展览联盟(简称UFI )会员认证的会展品牌,在2019年9月正式成为国际大会及会议协会(简称ICCA)的会员单位,成为湖北省唯一获得“双料”国际认证的会展公司,逐步打开国际展览及会议市场,国际化进程稳步提升。
|
||||
文创产品策划师,6-9k,丽水,大专及以上,7人,2025/9/13 23:00,"文创成品, C端产品, 策略产品, 传统文化","1.负责公司文创产品开发、策划,配合制定公司文创产品线的发展策略;
|
||||
2.具有研究市场趋势,挖掘潜在的市场需求,结合公司资源和公司内部优势,提出并落地文创产品项目,包括但不限于文化创意设计、包装策划等能力;
|
||||
3.对材料和结构呈现有深入的理解;
|
||||
4.文创产品的创意构思、内容策划、落地执行等全过程;
|
||||
5.及时反馈及完成公司交办的相关工作。","1.喜欢传统文化,热爱文创行业,具有3年以上相关工作经验,熟悉各类文创产品,具备较强的市场敏感性和产品设计能力;
|
||||
2.具备良好的沟通协调能力,能够与公司内部团队、外部合作伙伴进行有效沟通,推动文创产品线的发展;
|
||||
3.具有敏锐的市场洞察能力,能够准确判断市场趋势,为公司提供决策支持;
|
||||
4.具有较强的学习能力和创新思维,敢于尝试新事物,对手工艺、非遗文化、潮流设计等有深入了解或实践经验;
|
||||
5.对文创产品生产过程、工艺有了解,具有较强的生产过程控制和协调能力。","不止设计事务所成立于2015年4月,2020年底成立杭州分公司。丽水公司现有团队成员20人,杭州公司32人。
|
||||
本公司致力于为品牌方、企事业单位提供视觉设计服务与营销策划建议。
|
||||
涉及业务如:品牌VI设计、应用物料设计、文创产品研发、h5动画、mg动画、视频特效、商业产品摄影、展厅规划、网页网站等设计类项目。先后服务于新西兰贸发局,新西兰航空,新西兰旅游局,维珍航空,宁波市环保局,宁波市卫生局,丽水市供电公司、敦煌研究院等企事业单位和商业公"
|
||||
SEO专员,6-8k,苏州,大专及以上,6人,2025/6/17 10:00,"搜索引擎优化, 百度","1. SEO规划与实施,提升公司网站在自然搜索中的排名;
|
||||
2. 制定并执行营销方案,增加公司的营销曝光度;
|
||||
3. 分析数据和趋势,提出可行的优化建议并跟踪实现效果。","1. 深入了解常用搜索引擎算法规则,并能根据其变化及时制定相应的优化方案;
|
||||
2. 熟练掌握SEO工具,例如:Google Analytics、Baidu Tongji等;
|
||||
3. 具备良好的沟通能力和团队协作精神,能够积极推动SEO中心与其他部门紧密配合。",广东双鹰玩具实业有限公司创立于1988年,专注于互动遥控和科技积木两大品类,经过30多年的发展,成为国内领先的高端玩具制造商,集研发、生产、销售、品牌于一体,拥有员工1000名以上,2大核心生产基地,2016-2021年相继成立北京、深圳分公司负责品牌传播和产品设计。
|
||||
酒店餐饮主管,8-9k,重庆,大专及以上,2人,2025/7/22 15:00,"酒店管理经验, 包住","1. 负责酒店餐饮部门的整体运营管理,确保服务质量和顾客满意度;
|
||||
2. 制定并执行餐饮部门的营销策略,提升餐厅营业额;
|
||||
3. 监督食材采购、库存管理及成本控制,保证食品安全与高效运营;
|
||||
4. 指导并培训餐饮团队,提升团队专业能力和工作效率;
|
||||
5. 协调各部门间合作,优化顾客就餐体验。","1. 具备出色的领导能力和团队管理经验,能够激励团队达成目标;
|
||||
2. 熟悉餐饮业务运作流程,有成本控制意识及食品安全管理经验;
|
||||
3. 优秀的沟通能力和客户服务意识,能够处理顾客投诉和意见;
|
||||
4. 具有较强的市场洞察力和创新能力,能够开发新菜品及营销方案;
|
||||
5. 能够在快节奏的工作环境中保持冷静,有效解决问题。",湖北金狮酒店管理有限公司成立于1998年,历经二十七年的发展,目前旗下有金狮酒店、鑫金狮酒店、孝感人家酒店等三大商务型连锁酒店,六家直营门店家常菜品牌“福味馆”,在孝感当地具有影响力和较高的市场美誉度。
|
||||
|
50
岗位对应单元.csv
Normal file
50
岗位对应单元.csv
Normal file
@@ -0,0 +1,50 @@
|
||||
岗位名称,查询单元名称(复合能力),查询单元名称(垂直能力)
|
||||
宠物店店长,文旅与供应链基础,宠物乐园式门店经营与创新
|
||||
宠物营养师,文旅服务:形象、沟通与体验的融合艺术,宠物乐园式门店经营与创新
|
||||
二次元周边选品专员,文旅与供应链基础,二次元周边店经营与粉丝经济构建
|
||||
二次元周边店店员,文旅服务:形象、沟通与体验的融合艺术,二次元周边店经营与粉丝经济构建
|
||||
二次元周边店店长,文旅与供应链基础,二次元周边店经营与粉丝经济构建
|
||||
会展策划师,活动策划基础,消费电子展品牌策划与执行
|
||||
会展执行助理,活动策划基础,消费电子展品牌策划与执行
|
||||
会展讲解员,文旅服务:形象、沟通与体验的融合艺术,消费电子展品牌策划与执行
|
||||
会展营销, 全栈新媒体运营赋能文旅营销,品牌招商展全案策划与招商运营
|
||||
商业会展执行专员,文旅服务:形象、沟通与体验的融合艺术,品牌招商展全案策划与招商运营
|
||||
漫展策划师,活动策划基础,漫展与二次元活动策划与执行
|
||||
活动执行,文旅服务:形象、沟通与体验的融合艺术,商业活动全程策划执行与运营优化
|
||||
活动策划师,活动策划基础,商业活动策略设计与创意策划
|
||||
景区运营专员,智慧文旅应用,项目全周期运营管理
|
||||
文旅运营总监助理,文旅与供应链基础,项目全周期运营管理
|
||||
酒店餐饮主管,文旅与供应链基础,酒店项目经营与品牌塑造
|
||||
酒店运营专员,智慧文旅应用,酒店项目经营与品牌塑造
|
||||
客房经理,文旅服务:形象、沟通与体验的融合艺术,酒店项目经营与品牌塑造
|
||||
酒店大堂副理,文旅服务:形象、沟通与体验的融合艺术,酒店项目经营与品牌塑造
|
||||
餐厅运营经理,文旅服务:形象、沟通与体验的融合艺术,酒店项目经营与品牌塑造
|
||||
露营地运营专员,文旅与供应链基础,露营地规划与经营管理
|
||||
旅游规划师,活动策划基础,文旅项目策划与设计
|
||||
旅游计调专员,文旅与供应链基础,文旅项目策划与设计
|
||||
文旅项目投资拓展管培生,文旅与供应链基础,财务控制与风险防范
|
||||
民宿管家,文旅服务:形象、沟通与体验的融合艺术,民宿运营策划与个性化体验
|
||||
民宿客房管家,文旅服务:形象、沟通与体验的融合艺术,民宿运营策划与个性化体验
|
||||
民宿运营专员,"活动策划基础,文旅与供应链基础,AIGC人工智能生成内容",民宿运营策划与个性化体验
|
||||
品牌策划运营专员, 全栈新媒体运营赋能文旅营销,营销传播与品牌推广
|
||||
品牌公关, 全栈新媒体运营赋能文旅营销,营销传播与品牌推广
|
||||
品牌推广专员," 全栈新媒体运营赋能文旅营销,商业设计基础",营销传播与品牌推广
|
||||
ip运营, 全栈新媒体运营赋能文旅营销,文旅衍生文创产品设计
|
||||
IP运营总监助理, 全栈新媒体运营赋能文旅营销,文旅衍生文创产品设计
|
||||
品牌公关管培生, 全栈新媒体运营赋能文旅营销,营销传播与品牌推广
|
||||
文创产品策划师,"商业设计基础,AIGC人工智能生成内容",文旅衍生文创产品设计
|
||||
文创产品设计师,"商业设计基础,AIGC人工智能生成内容",文旅衍生文创产品设计
|
||||
文创产品设计师助理,"商业设计基础,AIGC人工智能生成内容",文旅衍生文创产品设计
|
||||
新媒体运营专员, 全栈新媒体运营赋能文旅营销,营销传播与品牌推广
|
||||
网络运营专员, 全栈新媒体运营赋能文旅营销,营销传播与品牌推广
|
||||
社群运营, 全栈新媒体运营赋能文旅营销,营销传播与品牌推广
|
||||
直播中控, 全栈新媒体运营赋能文旅营销,短视频与自媒体运营
|
||||
直播助理, 全栈新媒体运营赋能文旅营销,短视频与自媒体运营
|
||||
SEO专员, 全栈新媒体运营赋能文旅营销,营销传播与品牌推广
|
||||
SEM专员, 全栈新媒体运营赋能文旅营销,营销传播与品牌推广
|
||||
赛事礼仪,文旅服务:形象、沟通与体验的融合艺术,体育赛事经纪职业认知与服务实务
|
||||
赛事经纪,文旅服务:形象、沟通与体验的融合艺术,体育赛事经纪职业认知与服务实务
|
||||
赛事编辑," 全栈新媒体运营赋能文旅营销,AIGC人工智能生成内容",体育赛事经纪职业认知与服务实务
|
||||
艺人经纪人,文旅服务:形象、沟通与体验的融合艺术,演艺经纪基础实务与从业规范
|
||||
演出执行经理,"文旅服务:形象、沟通与体验的融合艺术,活动策划基础",商业活动全程策划执行与运营优化
|
||||
场馆运营人员,"文旅服务:形象、沟通与体验的融合艺术,活动策划基础,智慧文旅应用",商业活动全程策划执行与运营优化
|
||||
|
BIN
线下面试模拟锁定.png
Normal file
BIN
线下面试模拟锁定.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 456 KiB |
404
课程表.csv
Normal file
404
课程表.csv
Normal file
@@ -0,0 +1,404 @@
|
||||
课程名称,❌单元名称
|
||||
教育体系认知,岗位体系认知
|
||||
现代文旅类企业的管理体系,岗位体系认知
|
||||
专科生的职业规划,岗位体系认知
|
||||
文旅产业认知课,产业认知课
|
||||
行业详解:旅游行业,产业认知课
|
||||
行业详解:酒店与民宿行业,产业认知课
|
||||
行业详解:活动与会展行业,产业认知课
|
||||
行业详解:文化服务行业,产业认知课
|
||||
现代文旅产业生态图谱,旅游产业全景与文旅基础知识
|
||||
文旅政策法规与风险管理,旅游产业全景与文旅基础知识
|
||||
旅游产品与旅游资源,旅游产业全景与文旅基础知识
|
||||
游客行为心理学基础,旅游产业全景与文旅基础知识
|
||||
可持续旅游发展,旅游产业全景与文旅基础知识
|
||||
单元小结,旅游产业全景与文旅基础知识
|
||||
文旅场景职业形象IP塑造,文旅服务:形象、沟通与体验的融合艺术
|
||||
情境化服务体验设计,文旅服务:形象、沟通与体验的融合艺术
|
||||
政务商务接待专项礼仪,文旅服务:形象、沟通与体验的融合艺术
|
||||
文旅服务中的非语言表达,文旅服务:形象、沟通与体验的融合艺术
|
||||
服务沟通技巧与表达训练,文旅服务:形象、沟通与体验的融合艺术
|
||||
多元文化下的服务表达差异,文旅服务:形象、沟通与体验的融合艺术
|
||||
单元小结,文旅服务:形象、沟通与体验的融合艺术
|
||||
供应链管理的内容,文旅与供应链基础
|
||||
文旅资源调度,文旅与供应链基础
|
||||
文旅产品全生命周期管理,文旅与供应链基础
|
||||
文旅商品供应链,文旅与供应链基础
|
||||
住宿业资源协同,文旅与供应链基础
|
||||
小型文旅项目的供应链角色模拟,文旅与供应链基础
|
||||
文旅项目供应链特征,文旅与供应链基础
|
||||
文旅供应链中的B2B与B2C模式,文旅与供应链基础
|
||||
单元小结,文旅与供应链基础
|
||||
现代设计行业的发展现状,商业设计基础
|
||||
设计基础,商业设计基础
|
||||
字体设计与中文字体情绪表达,商业设计基础
|
||||
商业平面色彩搭配,商业设计基础
|
||||
平面设计构图,商业设计基础
|
||||
图像编辑工具:Photoshop,商业设计基础
|
||||
矢量与标志设计:Illustrator,商业设计基础
|
||||
快速设计工具使用:Canva,商业设计基础
|
||||
移动端视觉原型设计:Figma,商业设计基础
|
||||
视频剪辑入门:剪映,商业设计基础
|
||||
单元小结,商业设计基础
|
||||
AIGC发展简史与基本逻辑,AIGC人工智能生成内容
|
||||
AIGC的基本概念与各领域的应用,AIGC人工智能生成内容
|
||||
AIGC语言模型:chatgpt的灵活应用,AIGC人工智能生成内容
|
||||
AIGC生成内容的版权问题与合规使用,AIGC人工智能生成内容
|
||||
AIGC图像生成模型:Stable Diffusion Al摄影和平面设计,AIGC人工智能生成内容
|
||||
AIGC图像生成模型:Stable Diffusion的应用操作,AIGC人工智能生成内容
|
||||
AIGC视频应用:音视频生成与AI自动剪辑,AIGC人工智能生成内容
|
||||
AI词曲创作:suno,AIGC人工智能生成内容
|
||||
单元小结,AIGC人工智能生成内容
|
||||
新媒体应用传播学, 全栈新媒体运营赋能文旅营销
|
||||
新媒体故事结构入门, 全栈新媒体运营赋能文旅营销
|
||||
新媒体产品策划, 全栈新媒体运营赋能文旅营销
|
||||
平台账号经营与内容赛道, 全栈新媒体运营赋能文旅营销
|
||||
各平台变现方式与具体方法, 全栈新媒体运营赋能文旅营销
|
||||
内容运营:短视频的制作工具, 全栈新媒体运营赋能文旅营销
|
||||
内容运营:短视频制作内容对标, 全栈新媒体运营赋能文旅营销
|
||||
直播运营:直播间的搭建, 全栈新媒体运营赋能文旅营销
|
||||
品牌运营:当地文化IP数字化传播, 全栈新媒体运营赋能文旅营销
|
||||
品牌运营:跨界营销创新, 全栈新媒体运营赋能文旅营销
|
||||
私域运营:私域流量池的运营, 全栈新媒体运营赋能文旅营销
|
||||
单元小结, 全栈新媒体运营赋能文旅营销
|
||||
活动类型与功能认知,活动策划基础
|
||||
受众定位与主题创意方法,活动策划基础
|
||||
活动宣传渠道与推广方式,活动策划基础
|
||||
活动文案写作与表达技巧,活动策划基础
|
||||
活动流程设计与时间节点把控,活动策划基础
|
||||
活动场地选择与布置基础,活动策划基础
|
||||
活动预算与资源统筹,活动策划基础
|
||||
应急预案与活动风险管理,活动策划基础
|
||||
活动复盘报告撰写与数据分析方法,活动策划基础
|
||||
单元小结,活动策划基础
|
||||
智慧文旅概论,智慧文旅应用
|
||||
OTA平台运营,智慧文旅应用
|
||||
票务分销平台,智慧文旅应用
|
||||
景区智能导览系统,智慧文旅应用
|
||||
智能导览设备运用,智慧文旅应用
|
||||
智慧酒店/智慧景区体验场景模拟,智慧文旅应用
|
||||
单元小结,智慧文旅应用
|
||||
文旅经营行业行业讲解,职业规划课
|
||||
文旅经营行业位职业发展认知,职业规划课
|
||||
个人职业目标与发展路径规划,职业规划课
|
||||
文旅产业概论与发展趋势,文旅项目策划与设计
|
||||
市场调研方法与工具,文旅项目策划与设计
|
||||
项目选址与资源价值评估,文旅项目策划与设计
|
||||
目标客群定位策略,文旅项目策划与设计
|
||||
创意概念与主题开发,文旅项目策划与设计
|
||||
功能定位与业态组合,文旅项目策划与设计
|
||||
可行性研究报告编制,文旅项目策划与设计
|
||||
政策法规与报批流程,文旅项目策划与设计
|
||||
财务可行性与投资测算,文旅项目策划与设计
|
||||
策划阶段风险提示与调整,文旅项目策划与设计
|
||||
AI 辅助市场分析技巧,文旅项目策划与设计
|
||||
全周期运营管理概论,项目全周期运营管理
|
||||
组织架构与职责矩阵,项目全周期运营管理
|
||||
标准化流程设计,项目全周期运营管理
|
||||
人力资源规划与绩效,项目全周期运营管理
|
||||
运营期资产与设施维护,项目全周期运营管理
|
||||
客户体验与服务质量管理体系,项目全周期运营管理
|
||||
产品活动与内容运营,项目全周期运营管理
|
||||
流量管理与动线优化,项目全周期运营管理
|
||||
数据监测与 KPI 体系,项目全周期运营管理
|
||||
供应链与合作伙伴管理,项目全周期运营管理
|
||||
安全管理与应急预案,项目全周期运营管理
|
||||
AI 客服机器人应用,项目全周期运营管理
|
||||
文旅项目财务管理基础,财务控制与风险防范
|
||||
预算编制与现金流预测,财务控制与风险防范
|
||||
成本控制关键点讲解,财务控制与风险防范
|
||||
税务规划与合规管理,财务控制与风险防范
|
||||
投资回收期与现金流测算,财务控制与风险防范
|
||||
合同条款与债务管理,财务控制与风险防范
|
||||
内部审计与财务监督,财务控制与风险防范
|
||||
法规政策风险识别,财务控制与风险防范
|
||||
危机应对与退出机制,财务控制与风险防范
|
||||
文旅品牌战略与定位,营销传播与品牌推广
|
||||
目标市场细分与人群画像,营销传播与品牌推广
|
||||
品牌视觉与故事表达,营销传播与品牌推广
|
||||
营销渠道分类与策略设计,营销传播与品牌推广
|
||||
社交媒体与 UGC 运营,营销传播与品牌推广
|
||||
新媒体内容策划,营销传播与品牌推广
|
||||
短视频与直播运营,营销传播与品牌推广
|
||||
媒体公关与协作策略,营销传播与品牌推广
|
||||
区域联动与跨界合作,营销传播与品牌推广
|
||||
营销预算与投放评估,营销传播与品牌推广
|
||||
品牌资产管理与迭代,营销传播与品牌推广
|
||||
AI 内容创作辅助,营销传播与品牌推广
|
||||
酒店业态与市场趋势概论,酒店项目经营与品牌塑造
|
||||
品牌定位与价值主张,酒店项目经营与品牌塑造
|
||||
目标客群与需求洞察,酒店项目经营与品牌塑造
|
||||
服务流程与质量标准,酒店项目经营与品牌塑造
|
||||
房务与收益管理基础,酒店项目经营与品牌塑造
|
||||
餐饮与配套业态协同,酒店项目经营与品牌塑造
|
||||
直销渠道与会员运营,酒店项目经营与品牌塑造
|
||||
供应链与成本优化,酒店项目经营与品牌塑造
|
||||
危机公关与声誉维护,酒店项目经营与品牌塑造
|
||||
品牌升级与再投资评估,酒店项目经营与品牌塑造
|
||||
AI 辅助收益与定价优化,酒店项目经营与品牌塑造
|
||||
综合方案汇报与案例点评,酒店项目经营与品牌塑造
|
||||
民宿行业生态与政策导向,民宿运营策划与个性化体验
|
||||
区域文化与选址评估,民宿运营策划与个性化体验
|
||||
特色主题与空间设计,民宿运营策划与个性化体验
|
||||
体验场景与活动策划,民宿运营策划与个性化体验
|
||||
运营模式与服务设计,民宿运营策划与个性化体验
|
||||
渠道分销与内容运营,民宿运营策划与个性化体验
|
||||
合规安全与风险控制,民宿运营策划与个性化体验
|
||||
AI 客群洞察与定价辅助,民宿运营策划与个性化体验
|
||||
方案演练与复盘,民宿运营策划与个性化体验
|
||||
花艺市场与消费趋势,花店经营与视觉营销
|
||||
品牌定位与选品策略,花店经营与视觉营销
|
||||
陈列设计与视觉营销,花店经营与视觉营销
|
||||
品牌形象系统,花店经营与视觉营销
|
||||
时令节日与主题系列策划,花店经营与视觉营销
|
||||
渠道运营与线上推广,花店经营与视觉营销
|
||||
高级花艺设计技巧,花店经营与视觉营销
|
||||
鲜花供应链与品质控制,花店经营与视觉营销
|
||||
成本结构与定价体系,花店经营与视觉营销
|
||||
门店诊断与展示汇报,花店经营与视觉营销
|
||||
AI 精准营销与会员推荐,花店经营与视觉营销
|
||||
露营地市场与规范体系,露营地规划与经营管理
|
||||
场地功能与动线设计,露营地规划与经营管理
|
||||
设施配置与安全准则,露营地规划与经营管理
|
||||
合规管理与许可证办理,露营地规划与经营管理
|
||||
客群定位与体验策划,露营地规划与经营管理
|
||||
社群营销与活动策划,露营地规划与经营管理
|
||||
露营差异化活动设计与组织,露营地规划与经营管理
|
||||
品牌建设与形象塑造,露营地规划与经营管理
|
||||
露营地品牌建设与形象塑造,露营地规划与经营管理
|
||||
供应链架构与采购管理,露营地规划与经营管理
|
||||
风险应急与服务管理,露营地规划与经营管理
|
||||
宠物经济现状与趋势,宠物乐园式门店经营与创新
|
||||
新型商业模式定位,宠物乐园式门店经营与创新
|
||||
品类规划与空间布局,宠物乐园式门店经营与创新
|
||||
服务项目与体验设计,宠物乐园式门店经营与创新
|
||||
宠物健康与安全规范,宠物乐园式门店经营与创新
|
||||
社群运营与会员体系,宠物乐园式门店经营与创新
|
||||
供应链与品牌合作解析,宠物乐园式门店经营与创新
|
||||
门店营销与跨界活动,宠物乐园式门店经营与创新
|
||||
成本控制与定价策略,宠物乐园式门店经营与创新
|
||||
危机与舆情管理,宠物乐园式门店经营与创新
|
||||
AI 宠物健康监测辅助,宠物乐园式门店经营与创新
|
||||
二次元文化与消费生态,二次元周边店经营与粉丝经济构建
|
||||
IP 价值评估与授权流程,二次元周边店经营与粉丝经济构建
|
||||
产品策划与系列化开发,二次元周边店经营与粉丝经济构建
|
||||
主题空间与沉浸体验,二次元周边店经营与粉丝经济构建
|
||||
联名营销活动策划与执行,二次元周边店经营与粉丝经济构建
|
||||
电商平台与渠道策略,二次元周边店经营与粉丝经济构建
|
||||
线下展会与跨界 IP 合作策划,二次元周边店经营与粉丝经济构建
|
||||
供应链管理与品质控制,二次元周边店经营与粉丝经济构建
|
||||
成本管理与盈利分析,二次元周边店经营与粉丝经济构建
|
||||
会员体系建构与社群运营,二次元周边店经营与粉丝经济构建
|
||||
风险合规与版权保护,二次元周边店经营与粉丝经济构建
|
||||
AI 智能推荐与个性化营销,二次元周边店经营与粉丝经济构建
|
||||
活动策划行业讲解,职业规划课
|
||||
活动策划行业岗位职业发展认知,职业规划课
|
||||
个人职业目标与发展路径规划,职业规划课
|
||||
文旅商业活动概论,商业活动策略设计与创意策划
|
||||
受众洞察与市场分析,商业活动策略设计与创意策划
|
||||
活动定位与价值主张,商业活动策略设计与创意策划
|
||||
创意主题与故事化设计,商业活动策略设计与创意策划
|
||||
品牌 IP 与形象塑造,商业活动策略设计与创意策划
|
||||
合作伙伴与赞助方案设计,商业活动策略设计与创意策划
|
||||
法规合规与风险评估,商业活动策略设计与创意策划
|
||||
预算编制与资源整合,商业活动策略设计与创意策划
|
||||
整合营销传播策划,商业活动策略设计与创意策划
|
||||
策划案撰写与提案技巧,商业活动策略设计与创意策划
|
||||
AI 辅助创意与洞察,商业活动策略设计与创意策划
|
||||
项目时间线与里程碑规划,商业活动全程策划执行与运营优化
|
||||
场地选择与供应商协调,商业活动全程策划执行与运营优化
|
||||
现场动线与流程设计,商业活动全程策划执行与运营优化
|
||||
物料设计与场景布置概览,商业活动全程策划执行与运营优化
|
||||
安全管控与应急预案,商业活动全程策划执行与运营优化
|
||||
现场客户体验管理,商业活动全程策划执行与运营优化
|
||||
数据采集与成效评估,商业活动全程策划执行与运营优化
|
||||
运营复盘与持续改进,商业活动全程策划执行与运营优化
|
||||
关键绩效指标与ROI评估,商业活动全程策划执行与运营优化
|
||||
运营优化策略与流程改进,商业活动全程策划执行与运营优化
|
||||
AI 驱动运营优化,商业活动全程策划执行与运营优化
|
||||
商业设计类型与视觉表达,商业空间与文创产品设计
|
||||
品牌视觉识别系统概述,商业空间与文创产品设计
|
||||
商业设计数字化工具,商业空间与文创产品设计
|
||||
设计项目沟通、提案与交付流程,商业空间与文创产品设计
|
||||
商业空间设计原理,商业空间与文创产品设计
|
||||
动线规划与体验旅程,商业空间与文创产品设计
|
||||
材质、灯光与色彩策略,商业空间与文创产品设计
|
||||
文创产品开发流程,商业空间与文创产品设计
|
||||
产品原型与效果表达,商业空间与文创产品设计
|
||||
包装与展示设计,商业空间与文创产品设计
|
||||
商业模式与运营策略,商业空间与文创产品设计
|
||||
AIGC 辅助设计与视觉创意生成,商业空间与文创产品设计
|
||||
新媒体生态与平台特点,短视频与自媒体运营
|
||||
账号定位与品牌人设,短视频与自媒体运营
|
||||
内容策划与选题技巧,短视频与自媒体运营
|
||||
剧本写作与故事板,短视频与自媒体运营
|
||||
拍摄基础与镜头语言,短视频与自媒体运营
|
||||
剪辑节奏与声音设计,短视频与自媒体运营
|
||||
平台算法与流量运营,短视频与自媒体运营
|
||||
社群互动与粉丝经济,短视频与自媒体运营
|
||||
商业变现模式与合规流程,短视频与自媒体运营
|
||||
营销预算与投放评估,短视频与自媒体运营
|
||||
品牌资产管理与迭代,短视频与自媒体运营
|
||||
AI 内容创作辅助,短视频与自媒体运营
|
||||
漫展市场与粉丝文化概论,漫展与二次元活动策划与执行
|
||||
IP 授权与版权合作管理,漫展与二次元活动策划与执行
|
||||
主题创意与故事化设计,漫展与二次元活动策划与执行
|
||||
场馆规划与动线管理,漫展与二次元活动策划与执行
|
||||
Cosplay 赛事组织与评审,漫展与二次元活动策划与执行
|
||||
嘉宾管理与签售排期,漫展与二次元活动策划与执行
|
||||
周边商品开发与供应链协同,漫展与二次元活动策划与执行
|
||||
观众互动与粉丝经济运营,漫展与二次元活动策划与执行
|
||||
宣发与跨平台内容协同,漫展与二次元活动策划与执行
|
||||
成本控制与效果复盘,漫展与二次元活动策划与执行
|
||||
AI 画像与精准内容推送,漫展与二次元活动策划与执行
|
||||
音乐节类型与品牌定位,户外音乐节主题策划与流程统筹
|
||||
场地评估与政府审批,户外音乐节主题策划与流程统筹
|
||||
演出阵容策划与排期管理,户外音乐节主题策划与流程统筹
|
||||
舞台与视听系统配置,户外音乐节主题策划与流程统筹
|
||||
观众容量与安全防护,户外音乐节主题策划与流程统筹
|
||||
票务定价与分销渠道,户外音乐节主题策划与流程统筹
|
||||
现场志愿者与运营机制,户外音乐节主题策划与流程统筹
|
||||
赞助招商与品牌激活,户外音乐节主题策划与流程统筹
|
||||
媒体传播与UGC运营,户外音乐节主题策划与流程统筹
|
||||
数据复盘与收益模型优化,户外音乐节主题策划与流程统筹
|
||||
AI 人流预测与智能调度,户外音乐节主题策划与流程统筹
|
||||
城市品牌与赛事价值,城市 IP 赛事活动整合与策划
|
||||
政府协同与资源整合,城市 IP 赛事活动整合与策划
|
||||
赛事路线设计与地标利用,城市 IP 赛事活动整合与策划
|
||||
商业模式与赞助体系,城市 IP 赛事活动整合与策划
|
||||
媒体矩阵与社交议程,城市 IP 赛事活动整合与策划
|
||||
粉丝经济与周边活动,城市 IP 赛事活动整合与策划
|
||||
赛事服务与志愿者体系,城市 IP 赛事活动整合与策划
|
||||
经济溢出评估与城市形象提升,城市 IP 赛事活动整合与策划
|
||||
风险管理与持续改进,城市 IP 赛事活动整合与策划
|
||||
AI 交通流模拟与观赛体验优化,城市 IP 赛事活动整合与策划
|
||||
展会主题与品牌定位,消费电子展品牌策划与执行
|
||||
展区规划与动线设计,消费电子展品牌策划与执行
|
||||
新品发布会策划,消费电子展品牌策划与执行
|
||||
高层对接与 B2B 洽谈,消费电子展品牌策划与执行
|
||||
观众体验与互动区运营,消费电子展品牌策划与执行
|
||||
媒体公关与国际报道,消费电子展品牌策划与执行
|
||||
数据采集与商机管理,消费电子展品牌策划与执行
|
||||
展后商机跟进与 CRM 管理,消费电子展品牌策划与执行
|
||||
效果评估与改进计划,消费电子展品牌策划与执行
|
||||
AI 数字导览与多语种客服,消费电子展品牌策划与执行
|
||||
招商展定位与目标设定,品牌招商展全案策划与招商运营
|
||||
核心客商画像与邀约策略,品牌招商展全案策划与招商运营
|
||||
展陈布局与洽谈分区,品牌招商展全案策划与招商运营
|
||||
政策理解与谈判技巧,品牌招商展全案策划与招商运营
|
||||
合同管理与风险控制,品牌招商展全案策划与招商运营
|
||||
招商宣传与媒体合作,品牌招商展全案策划与招商运营
|
||||
现场接待与服务标准,品牌招商展全案策划与招商运营
|
||||
成本-收益评估与优化,品牌招商展全案策划与招商运营
|
||||
数据追踪与续约策略,品牌招商展全案策划与招商运营
|
||||
展会公关与舆情管理,品牌招商展全案策划与招商运营
|
||||
AI 潜在客户评分与跟进,品牌招商展全案策划与招商运营
|
||||
街区定位与体验经济概论,商业街区打卡空间视觉呈现
|
||||
打卡场景策划与动线设计,商业街区打卡空间视觉呈现
|
||||
视觉主题与材质运用,商业街区打卡空间视觉呈现
|
||||
灯光氛围与夜间经济,商业街区打卡空间视觉呈现
|
||||
互动装置与社交传播,商业街区打卡空间视觉呈现
|
||||
快闪与时令主题更新,商业街区打卡空间视觉呈现
|
||||
店铺协同布置与品牌联名,商业街区打卡空间视觉呈现
|
||||
安全与运营管理,商业街区打卡空间视觉呈现
|
||||
数据监测与热区分析,商业街区打卡空间视觉呈现
|
||||
效果评估与商业迭代计划,商业街区打卡空间视觉呈现
|
||||
AI 个性化导览与AR滤镜应用,商业街区打卡空间视觉呈现
|
||||
文创市场趋势与标杆案例,文旅衍生文创产品设计
|
||||
文化元素提炼与故事化,文旅衍生文创产品设计
|
||||
系列化产品策划与品类规划,文旅衍生文创产品设计
|
||||
设计语言与包装创意,文旅衍生文创产品设计
|
||||
材质选择与供应链协同,文旅衍生文创产品设计
|
||||
版权合规与 IP 运营,文旅衍生文创产品设计
|
||||
销售渠道与定价策略,文旅衍生文创产品设计
|
||||
消费者调研与产品迭代方法,文旅衍生文创产品设计
|
||||
电商平台运营与数据反哺机制,文旅衍生文创产品设计
|
||||
AI 概念图生成与快速打样,文旅衍生文创产品设计
|
||||
文化服务行业概述,职业规划课
|
||||
文化服务行业岗位职业发展认知,职业规划课
|
||||
个人职业目标与发展路径规划,职业规划课
|
||||
演艺项目运作全流程解析,演艺经纪基础实务与从业规范
|
||||
艺人签约流程与经纪合同要点,演艺经纪基础实务与从业规范
|
||||
艺人形象定位与品牌管理,演艺经纪基础实务与从业规范
|
||||
商演活动统筹与执行实务,演艺经纪基础实务与从业规范
|
||||
新媒体时代艺人营销,演艺经纪基础实务与从业规范
|
||||
宣发合作与媒体公关基础,演艺经纪基础实务与从业规范
|
||||
法律法规与行业规范,演艺经纪基础实务与从业规范
|
||||
经纪人与经纪公司合作模式解析,演艺经纪基础实务与从业规范
|
||||
艺人危机公关与突发事件处理,演艺经纪基础实务与从业规范
|
||||
职业伦理与保密协议,演艺经纪基础实务与从业规范
|
||||
体育赛事类型全景解析(职业/业余/青训),体育赛事经纪职业认知与服务实务
|
||||
运动员签约流程与合同管理,体育赛事经纪职业认知与服务实务
|
||||
赛事IP运营全流程,体育赛事经纪职业认知与服务实务
|
||||
体育赞助合同精讲,体育赛事经纪职业认知与服务实务
|
||||
赛事落地执行管控,体育赛事经纪职业认知与服务实务
|
||||
电子竞技经纪专项,体育赛事经纪职业认知与服务实务
|
||||
媒体传播与社交平台运营策略,体育赛事经纪职业认知与服务实务
|
||||
体育经纪法律法规与职业道德规范,体育赛事经纪职业认知与服务实务
|
||||
家政服务标准与礼仪,家庭服务技能
|
||||
家居6S管理法,家庭服务技能
|
||||
家庭清洁标准化流程与消杀技巧,家庭服务技能
|
||||
高效家庭收纳与空间利用技巧,家庭服务技能
|
||||
各类人群饮食营养配餐基础,家庭服务技能
|
||||
中/西餐基础烹饪与健康搭配,家庭服务技能
|
||||
宠物、儿童及老年人照护实务,家庭服务技能
|
||||
家庭安全隐患识别与应对,家庭服务技能
|
||||
沟通技巧与客户关系管理,家庭服务技能
|
||||
家政服务法律风险与合同知识,家庭服务技能
|
||||
教培机构组织结构与岗位职责,教培机构运营与教务支持
|
||||
教培行业政策合规红线,教培机构运营与教务支持
|
||||
教务人员基本职业素养与沟通技巧,教培机构运营与教务支持
|
||||
招生活动策划与渠道布局,教培机构运营与教务支持
|
||||
课程产品设计方法论,教培机构运营与教务支持
|
||||
学员日常服务与满意度维护,教培机构运营与教务支持
|
||||
家校沟通与家长运营技巧,教培机构运营与教务支持
|
||||
教培数据分析与转介绍策略,教培机构运营与教务支持
|
||||
教培短视频与社群工具,教培机构运营与教务支持
|
||||
演艺经纪行业发展概况与职业路径,艺人IP孵化与商业开发实操
|
||||
艺人IP价值模型与市场趋势解析,艺人IP孵化与商业开发实操
|
||||
艺人形象定位与人设打造方法,艺人IP孵化与商业开发实操
|
||||
虚拟偶像全流程开发,艺人IP孵化与商业开发实操
|
||||
内容策略设计:短视频/直播/综艺路径,艺人IP孵化与商业开发实操
|
||||
社交媒体矩阵搭建与粉丝运营,艺人IP孵化与商业开发实操
|
||||
艺人品牌合作模型与报价策略,艺人IP孵化与商业开发实操
|
||||
IP授权、联名与跨界合作实务,艺人IP孵化与商业开发实操
|
||||
IP授权、联名与跨界合作实务,艺人IP孵化与商业开发实操
|
||||
商业转化路径设计(演出、电商、代言),艺人IP孵化与商业开发实操
|
||||
IP维权与合同风险规避,艺人IP孵化与商业开发实操
|
||||
数据化运营:粉丝画像与商业决策,艺人IP孵化与商业开发实操
|
||||
中国体育产业政策与市场图谱,传统体育赛事商业开发
|
||||
本地/传统体育资源调研与策划,传统体育赛事商业开发
|
||||
赛事商业模式设计(赛事+展会+节庆),传统体育赛事商业开发
|
||||
赛事赞助招商方案设计与路演技巧,传统体育赛事商业开发
|
||||
合作资源包装与品牌权益矩阵设计,传统体育赛事商业开发
|
||||
体育赛事票务运营与增值服务开发,传统体育赛事商业开发
|
||||
赛事传播策略与媒体资源整合,传统体育赛事商业开发
|
||||
城市文旅融合开发,传统体育赛事商业开发
|
||||
青少年培训商业化嫁接,传统体育赛事商业开发
|
||||
赛事周边衍生品与文创开发,传统体育赛事商业开发
|
||||
传统赛事“破圈”营销,传统体育赛事商业开发
|
||||
电竞产业结构与热门IP商业模式,电竞IP商业化与运营执行
|
||||
电竞战队/主播IP运营分析,电竞IP商业化与运营执行
|
||||
电竞内容矩阵与流量增长策略,电竞IP商业化与运营执行
|
||||
电竞联赛/赛事招商实务,电竞IP商业化与运营执行
|
||||
电竞品牌合作模式与资源交换,电竞IP商业化与运营执行
|
||||
直播平台规则与流量分发机制,电竞IP商业化与运营执行
|
||||
电竞选手签约流程与权益管理,电竞IP商业化与运营执行
|
||||
电竞周边产品设计与授权路径,电竞IP商业化与运营执行
|
||||
电竞社群与粉丝运营,电竞IP商业化与运营执行
|
||||
高端家政行业全景与职业化发展趋势,高端家政定制服务与职业化运营
|
||||
家政定制化服务方案设计,高端家政定制服务与职业化运营
|
||||
私人定制家政服务流程与标准,高端家政定制服务与职业化运营
|
||||
高端家庭服务场景模拟,高端家政定制服务与职业化运营
|
||||
组织化运营:家政公司与客户关系管理,高端家政定制服务与职业化运营
|
||||
家政人员选拔与人才培养路径,高端家政定制服务与职业化运营
|
||||
职业化团队管理,高端家政定制服务与职业化运营
|
||||
高端服务案例解析,高端家政定制服务与职业化运营
|
||||
教培行业政策趋势与服务逻辑解析,教培服务与运营实务
|
||||
教学产品结构与课程设计方法,教培服务与运营实务
|
||||
教务服务流程设计与标准化执行,教培服务与运营实务
|
||||
家校沟通与客户满意度管理,教培服务与运营实务
|
||||
招生活动策划与转化漏斗管理,教培服务与运营实务
|
||||
教培CRM与营销自动化工具使用,教培服务与运营实务
|
||||
私域社群运营与续报提升策略,教培服务与运营实务
|
||||
视频内容/短视频带课流量,教培服务与运营实务
|
||||
|
2266
项目案例文旅.csv
Normal file
2266
项目案例文旅.csv
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user