当前位置: 首页 > article >正文

fastapi+angular就业管理系统

说明:
我计划用fastapi+angular实现毕业生就业管理系统,
1.mysql写数据库表,创建表,插入数据,写查询语句
2.fastapi写后端接口,在postman里面测试
3.angular前端展示

效果图:
在这里插入图片描述

step1:sql


-- 1. 院系表
CREATE TABLE department (
                            dept_id INT AUTO_INCREMENT PRIMARY KEY,
                            dept_name VARCHAR(50) NOT NULL UNIQUE,
                            dean VARCHAR(20),
                            office_phone VARCHAR(20)
);

-- 2. 专业表
CREATE TABLE major (
                       major_id INT AUTO_INCREMENT PRIMARY KEY,
                       dept_id INT NOT NULL,
                       major_name VARCHAR(50) NOT NULL,
                       years INT,
                       FOREIGN KEY (dept_id) REFERENCES department(dept_id)
);

-- 3. 企业表
CREATE TABLE company (
                         company_id INT AUTO_INCREMENT PRIMARY KEY,
                         name VARCHAR(100) NOT NULL UNIQUE,
                         industry VARCHAR(50),
                         address VARCHAR(200),
                         scale ENUM('小型','中型','大型'),
                         hr_name VARCHAR(20),
                         hr_phone VARCHAR(20)
);

-- 4. 用户表(合并学生表)
CREATE TABLE user (
                      user_id VARCHAR(20) PRIMARY KEY,
                      password VARCHAR(100) NOT NULL,
                      role ENUM('student','company','admin') NOT NULL,
                      name VARCHAR(50) NOT NULL,
                      gender ENUM('男','女'),
                      major_id INT,
                      phone VARCHAR(20),
                      email VARCHAR(50),
                      employment_status ENUM('已就业','待就业','升学','创业'),
                      ref_id INT, -- 企业用户关联公司ID
                      FOREIGN KEY (major_id) REFERENCES major(major_id),
                      FOREIGN KEY (ref_id) REFERENCES company(company_id)
);

-- 5. 招聘信息表
CREATE TABLE job_post (
                          post_id INT AUTO_INCREMENT PRIMARY KEY,
                          company_id INT NOT NULL,
                          job_title VARCHAR(50) NOT NULL,
                          job_type VARCHAR(20),
                          salary_range VARCHAR(20),
                          post_date DATE,
                          end_date DATE,
                          FOREIGN KEY (company_id) REFERENCES company(company_id)
);

-- 6. 投递记录表
CREATE TABLE application (
                             apply_id INT AUTO_INCREMENT PRIMARY KEY,
                             user_id VARCHAR(20) NOT NULL,
                             post_id INT NOT NULL,
                             apply_time DATETIME DEFAULT CURRENT_TIMESTAMP,
                             status ENUM('已投递','已查看','已面试','已录用'),
                             FOREIGN KEY (user_id) REFERENCES user(user_id),
                             FOREIGN KEY (post_id) REFERENCES job_post(post_id)
);

-- 7. 就业记录表
CREATE TABLE employment (
                            employ_id INT AUTO_INCREMENT PRIMARY KEY,
                            user_id VARCHAR(20) NOT NULL,  -- 移除了UNIQUE约束
                            company_id INT NOT NULL,
                            post_id INT,
                            salary DECIMAL(10,2),
                            sign_date DATE,
                            is_current BOOLEAN DEFAULT TRUE, -- 新增字段标识当前任职状态
                            FOREIGN KEY (user_id) REFERENCES user(user_id),
                            FOREIGN KEY (company_id) REFERENCES company(company_id),
                            FOREIGN KEY (post_id) REFERENCES job_post(post_id)
);



-- 院系表
INSERT INTO department (dept_name, dean, office_phone) VALUES
                                                           ('计算机学院', '张老师', '028-12345678'),
                                                           ('经济学院', '李老师', '028-23456789'),
                                                           ('机械学院', '王老师', '028-34567890'),
                                                           ('外语学院', '赵老师', '028-45678901'),
                                                           ('医学院', '孙老师', '028-56789012'),
                                                           ('法学院', '周老师', '028-67890123'),
                                                           ('艺术学院', '吴老师', '028-78901234'),
                                                           ('化工学院', '郑老师', '028-89012345'),
                                                           ('管理学院', '廖老师', '028-90123456'),
                                                           ('建筑学院', '孟老师', '028-01234567');

-- 专业表
INSERT INTO major (dept_id, major_name, years) VALUES
                                                   (1, '软件工程',4),(1,'人工智能',4),(2,'金融学',4),(2,'国际贸易',4),
                                                   (3,'机械工程',4),(4,'英语',4),(5,'临床医学',5),(6,'法学',4),
                                                   (7,'视觉传达',4),(8,'化学工程',4);

-- 企业表
INSERT INTO company (name, industry, address, scale, hr_name, hr_phone) VALUES
                                                                            ('Tencent Technology', '互联网', 'Shenzhen', '大型', '马先生', '0755-12345678'),
                                                                            ('Huawei Technologies', '通信', 'Shenzhen', '大型', '任先生', '0755-23456789'),
                                                                            ('China Merchants Bank', '金融', 'Shenzhen', '大型', '李女士', '0755-34567890'),
                                                                            ('ByteDance', '互联网', 'Beijing', '大型', '张先生', '010-12345678'),
                                                                            ('BYD Auto', '制造业', 'Shenzhen', '大型', '王先生', '0755-45678901'),
                                                                            ('New Oriental Education', '教育', 'Beijing', '大型', '周女士', '010-23456789'),
                                                                            ('Vanke Real Estate', '房地产', 'Shenzhen', '大型', '陈先生', '0755-56789012'),
                                                                            ('Sany Heavy Industry', '制造业', 'Changsha', '大型', '梁先生', '0731-1234567'),
                                                                            ('Hikvision', '安防', 'Hangzhou', '大型', '胡先生', '0571-1234567'),
                                                                            ('Gree Electric', '家电', 'Zhuhai', '大型', '董女士', '0756-1234567');


-- 用户表
INSERT INTO user VALUES
                     ('S2020001', 'pass123', 'student', '王小明', '男', 1, '13800010001', 'wangxm@edu.cn', '已就业', NULL),
                     ('S2020002', 'pass123', 'student', '李红', '女', 1, '13800010002', 'lih@edu.cn', '待就业', NULL),
                     ('S2020003', 'pass123', 'student', '张伟', '男', 3, '13800010003', 'zhangw@edu.cn', '已就业', NULL),
                     ('C1001', 'pass123', 'company', '腾讯科技HR', NULL, NULL, NULL, 'hr@tencent.com', NULL, 1),
                     ('C1002', 'pass123', 'company', '华为HR', NULL, NULL, NULL, 'hr@huawei.com', NULL, 2),
                     ('admin', 'admin123', 'admin', '系统管理员', NULL, NULL, NULL, 'admin@edu.cn', NULL, NULL),
                     ('S2020004', 'pass123', 'student', '陈芳', '女', 6, '13800010004', 'chenf@edu.cn', '升学', NULL),
                     ('S2020005', 'pass123', 'student', '刘洋', '男', 5, '13800010005', 'liuy@edu.cn', '创业', NULL),
                     ('S2020006', 'pass123', 'student', '周杰', '男', 2, '13800010006', 'zhouj@edu.cn', '已就业', NULL),
                     ('S2020007', 'pass123', 'student', '吴敏', '女', 4, '13800010007', 'wum@edu.cn', '待就业', NULL);


-- 补充四个专业的学生数据(临床医学、法学、视觉传达、化学工程)
INSERT INTO user (user_id, password, role, name, gender, major_id, phone, email, employment_status, ref_id) VALUES
-- 临床医学专业(major_id=7)
('S2020008', 'pass123', 'student', '张医生', '男', 7, '13800010011', 'zhangys@edu.cn', '已就业', NULL),
('S2020009', 'pass123', 'student', '李护士', '女', 7, '13800010012', 'lihs@edu.cn', '待就业', NULL),

-- 法学专业(major_id=8)
('S2020010', 'pass123', 'student', '王律师', '男', 8, '13800010013', 'wangls@edu.cn', '已就业', NULL),
('S2020011', 'pass123', 'student', '赵法务', '女', 8, '13800010014', 'zhaofw@edu.cn', '升学', NULL),

-- 视觉传达专业(major_id=9)
('S2020012', 'pass123', 'student', '陈设计', '男', 9, '13800010015', 'chensj@edu.cn', '创业', NULL),
('S2020013', 'pass123', 'student', '刘美工', '女', 9, '13800010016', 'liumg@edu.cn', '已就业', NULL),

-- 化学工程专业(major_id=10)
('S2020014', 'pass123', 'student', '黄化学', '男', 10, '13800010017', 'huanghx@edu.cn', '待就业', NULL),
('S2020015', 'pass123', 'student', '周实验', '女', 10, '13800010018', 'zhousy@edu.cn', '已就业', NULL),
('S2020016', 'pass123', 'student', '吴化工', '男', 10, '13800010019', 'wuhg@edu.cn', '待就业', NULL),
('S2020017', 'pass123', 'student', '郑材料', '女', 10, '13800010020', 'zhengcl@edu.cn', '升学', NULL);

-- 招聘信息表
INSERT INTO job_post (company_id, job_title, job_type, salary_range, post_date, end_date) VALUES
                                                                                              (1,'Java开发','技术岗','15-25K','2024-03-01','2024-06-30'),
                                                                                              (1,'产品经理','产品岗','20-35K','2024-03-05','2024-06-30'),
                                                                                              (2,'5G工程师','技术岗','18-30K','2024-03-10','2024-06-30'),
                                                                                              (3,'金融分析','金融岗','25-40K','2024-03-15','2024-06-30'),
                                                                                              (4,'前端开发','技术岗','16-28K','2024-03-20','2024-06-30'),
                                                                                              (5,'汽车设计','技术岗','20-35K','2024-03-25','2024-06-30'),
                                                                                              (6,'英语教师','教育岗','12-20K','2024-04-01','2024-06-30'),
                                                                                              (7,'建筑设计师','设计岗','18-30K','2024-04-05','2024-06-30'),
                                                                                              (8,'机械工程师','技术岗','15-25K','2024-04-10','2024-06-30'),
                                                                                              (9,'算法工程师','技术岗','30-50K','2024-04-15','2024-06-30');

-- 投递记录表
INSERT INTO application (user_id, post_id, status) VALUES
                                                       ('S2020001',1,'已录用'),
                                                       ('S2020001',3,'已投递'),
                                                       ('S2020002',7,'已查看'),
                                                       ('S2020001',5,'已投递'),
                                                       ('S2020002',2,'已投递'),
                                                       ('S2020001',8,'已查看'),
                                                       ('S2020002',4,'已投递'),
                                                       ('S2020001',6,'已查看'),
                                                       ('S2020002',9,'已投递'),
                                                       ('S2020001',10,'已录用');

-- 就业记录表
-- 添加10条就业记录测试数据
INSERT INTO employment (user_id, company_id, post_id, salary, sign_date, is_current) VALUES
('S2020001', 2, 3, 20000, '2024-05-01', TRUE),
('S2020001', 3, 4, 24000, '2023-10-01', FALSE),
('S2020002', 4, 5, 18000, '2024-05-02', TRUE),
('S2020002', 2, 3, 21000, '2024-04-28', TRUE),
('S2020003', 5, 6, 22000, '2024-04-20', FALSE),
('S2020003', 7, 8, 23000, '2024-05-03', TRUE),
('S2020004', 6, 7, 15000, '2024-03-15', FALSE),
('S2020005', 8, 9, 25000, '2024-05-05', TRUE),
('S2020006', 9, 10, 28000, '2024-04-25', TRUE),
('S2020007', 10, NULL, 26000, '2024-05-10', TRUE);

# 1. 根据学生ID查就业情况
SELECT
    u.name AS student_name,
    c.name AS company_name,
    j.job_title,
    e.salary,
    e.sign_date
FROM user u
         LEFT JOIN employment e ON u.user_id = e.user_id AND e.is_current = TRUE
         LEFT JOIN company c ON e.company_id = c.company_id
         LEFT JOIN job_post j ON e.post_id = j.post_id
WHERE u.user_id = 'S2020002';

# 2. 各专业就业率
SELECT
    m.major_name,
    COUNT(u.user_id) AS total_students,
    SUM(CASE WHEN u.employment_status = '已就业' THEN 1 ELSE 0 END) AS employed_count,
    ROUND(SUM(CASE WHEN u.employment_status = '已就业' THEN 1 ELSE 0 END) / COUNT(u.user_id) * 100, 2) AS employment_rate
FROM user u
         JOIN major m ON u.major_id = m.major_id
GROUP BY m.major_name;

# 3. 各院系就业率统计
SELECT
    d.dept_name,
    COUNT(u.user_id) AS total_students,
    SUM(CASE WHEN u.employment_status = '已就业' THEN 1 ELSE 0 END) AS employed_count,
    ROUND(SUM(CASE WHEN u.employment_status = '已就业' THEN 1 ELSE 0 END) / COUNT(u.user_id) * 100, 2) AS employment_rate
FROM user u
         JOIN major m ON u.major_id = m.major_id
         JOIN department d ON m.dept_id = d.dept_id
GROUP BY d.dept_name;

# 4. 热门岗位分析
SELECT
    j.job_title,
    COUNT(DISTINCT a.apply_id) AS apply_count,
    COUNT(DISTINCT e.employ_id) AS hire_count
FROM job_post j
         LEFT JOIN application a ON j.post_id = a.post_id
         LEFT JOIN employment e ON j.post_id = e.post_id
GROUP BY j.post_id
ORDER BY apply_count DESC;

# 5. 未就业学生名单
SELECT
    u.user_id AS student_id,
    u.name,
    m.major_name,
    d.dept_name
FROM user u
         JOIN major m ON u.major_id = m.major_id
         JOIN department d ON m.dept_id = d.dept_id
WHERE u.employment_status = '待就业';

# 6. 企业招聘就业分析
SELECT
    c.name AS company_name,
    COUNT(DISTINCT j.post_id) AS job_postings,
    COUNT(DISTINCT a.apply_id) AS applications_received,
    COUNT(DISTINCT e.employ_id) AS hires_made
FROM company c
         LEFT JOIN job_post j ON c.company_id = j.company_id
         LEFT JOIN application a ON j.post_id = a.post_id
         LEFT JOIN employment e ON j.post_id = e.post_id
GROUP BY c.company_id
ORDER BY job_postings DESC;

step2:后端fastapi写接口 C:\Users\Administrator\PycharmProjects\FastAPIProject\main.py

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
import pymysql.cursors

app = FastAPI()

# CORS配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:4200"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 数据库配置
DB_CONFIG = {
    'host': 'localhost',
    'user': 'root',
    'password': '123456',
    'db': 'school_db',  # 替换为实际数据库名
    'charset': 'utf8mb4',
    'cursorclass': pymysql.cursors.DictCursor
}

def query_db(query: str, params=None):
    try:
        connection = pymysql.connect(**DB_CONFIG)
        with connection.cursor() as cursor:
            cursor.execute(query, params or ())
            result = cursor.fetchall()
        connection.close()
        return result
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

# 1. 学生就业情况查询
@app.get("/student_employment/{student_id}")
async def get_student_employment(student_id: str):
    query = """
    SELECT 
        u.name AS student_name,
        c.name AS company_name,
        j.job_title,
        e.salary,
        e.sign_date
    FROM user u
    LEFT JOIN employment e ON u.user_id = e.user_id AND e.is_current = TRUE
    LEFT JOIN company c ON e.company_id = c.company_id
    LEFT JOIN job_post j ON e.post_id = j.post_id
    WHERE u.user_id = %s
    """
    return {"data": query_db(query, (student_id,))}

# 2. 专业就业率统计
@app.get("/major_stats")
async def get_major_employment_rates():
    query = """
    SELECT
        m.major_name,
        COUNT(u.user_id) AS total_students,
        SUM(u.employment_status = '已就业') AS employed_count,
        ROUND(SUM(u.employment_status = '已就业') / COUNT(u.user_id) * 100, 2) AS employment_rate
    FROM user u
    JOIN major m ON u.major_id = m.major_id
    GROUP BY m.major_name
    """
    return {"data": query_db(query)}

# 3. 院系就业率统计
@app.get("/dept_stats")
async def get_department_employment_rates():
    query = """
    SELECT
        d.dept_name,
        COUNT(u.user_id) AS total_students,
        SUM(u.employment_status = '已就业') AS employed_count,
        ROUND(SUM(u.employment_status = '已就业') / COUNT(u.user_id) * 100, 2) AS employment_rate
    FROM user u
    JOIN major m ON u.major_id = m.major_id
    JOIN department d ON m.dept_id = d.dept_id
    GROUP BY d.dept_name
    """
    return {"data": query_db(query)}

# 4. 热门岗位分析
@app.get("/jobs/hot")
async def get_hot_jobs():
    query = """
    SELECT
        j.job_title,
        COUNT(DISTINCT a.apply_id) AS apply_count,
        COUNT(DISTINCT e.employ_id) AS hire_count
    FROM job_post j
    LEFT JOIN application a ON j.post_id = a.post_id
    LEFT JOIN employment e ON j.post_id = e.post_id
    GROUP BY j.post_id
    ORDER BY apply_count DESC
    """
    return {"data": query_db(query)}

# 5. 未就业学生名单
@app.get("/unemployed_students")
async def get_unemployed_students():
    query = """
    SELECT
        u.user_id AS student_id,
        u.name,
        m.major_name,
        d.dept_name
    FROM user u
    JOIN major m ON u.major_id = m.major_id
    JOIN department d ON m.dept_id = d.dept_id
    WHERE u.employment_status = '待就业'
    """
    return {"data": query_db(query)}

# 6. 企业招聘分析
@app.get("/company_stats")
async def get_company_recruitment():
    query = """
    SELECT
        c.name AS company_name,
        COUNT(DISTINCT j.post_id) AS job_postings,
        COUNT(DISTINCT a.apply_id) AS applications_received,
        COUNT(DISTINCT e.employ_id) AS hires_made
    FROM company c
    LEFT JOIN job_post j ON c.company_id = j.company_id
    LEFT JOIN application a ON j.post_id = a.post_id
    LEFT JOIN employment e ON j.post_id = e.post_id
    GROUP BY c.company_id
    ORDER BY job_postings DESC
    """
    return {"data": query_db(query)}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

step3:postman测试fastapi写的接口,验证接口是否正确

 http://localhost:8000/company_stats

 {
    "data": [
        {
            "company_name": "Tencent Technology",
            "job_postings": 2,
            "applications_received": 2,
            "hires_made": 0
        },
        {
            "company_name": "Huawei Technologies",
            "job_postings": 1,
            "applications_received": 1,
            "hires_made": 2
        },
        {
            "company_name": "China Merchants Bank",
            "job_postings": 1,
            "applications_received": 1,
            "hires_made": 1
        },
        {
            "company_name": "ByteDance",
            "job_postings": 1,
            "applications_received": 1,
            "hires_made": 1
        },
        {
            "company_name": "BYD Auto",
            "job_postings": 1,
            "applications_received": 1,
            "hires_made": 1
        },
        {
            "company_name": "New Oriental Education",
            "job_postings": 1,
            "applications_received": 1,
            "hires_made": 1
        },
        {
            "company_name": "Vanke Real Estate",
            "job_postings": 1,
            "applications_received": 1,
            "hires_made": 1
        },
        {
            "company_name": "Sany Heavy Industry",
            "job_postings": 1,
            "applications_received": 1,
            "hires_made": 1
        },
        {
            "company_name": "Hikvision",
            "job_postings": 1,
            "applications_received": 1,
            "hires_made": 1
        },
        {
            "company_name": "Gree Electric",
            "job_postings": 0,
            "applications_received": 0,
            "hires_made": 0
        }
    ]
}


http://localhost:8000/unemployed_students

{
    "data": [
        {
            "student_id": "S2020002",
            "name": "李红",
            "major_name": "软件工程",
            "dept_name": "计算机学院"
        },
        {
            "student_id": "S2020007",
            "name": "吴敏",
            "major_name": "国际贸易",
            "dept_name": "经济学院"
        },
        {
            "student_id": "S2020009",
            "name": "李护士",
            "major_name": "临床医学",
            "dept_name": "医学院"
        },
        {
            "student_id": "S2020014",
            "name": "黄化学",
            "major_name": "化学工程",
            "dept_name": "化工学院"
        },
        {
            "student_id": "S2020016",
            "name": "吴化工",
            "major_name": "化学工程",
            "dept_name": "化工学院"
        }
    ]
}



http://localhost:8000/jobs/hot

{
    "data": [
        {
            "job_title": "Java开发",
            "apply_count": 1,
            "hire_count": 0
        },
        {
            "job_title": "产品经理",
            "apply_count": 1,
            "hire_count": 0
        },
        {
            "job_title": "5G工程师",
            "apply_count": 1,
            "hire_count": 2
        },
        {
            "job_title": "金融分析",
            "apply_count": 1,
            "hire_count": 1
        },
        {
            "job_title": "前端开发",
            "apply_count": 1,
            "hire_count": 1
        },
        {
            "job_title": "汽车设计",
            "apply_count": 1,
            "hire_count": 1
        },
        {
            "job_title": "英语教师",
            "apply_count": 1,
            "hire_count": 1
        },
        {
            "job_title": "建筑设计师",
            "apply_count": 1,
            "hire_count": 1
        },
        {
            "job_title": "机械工程师",
            "apply_count": 1,
            "hire_count": 1
        },
        {
            "job_title": "算法工程师",
            "apply_count": 1,
            "hire_count": 1
        }
    ]
}


http://localhost:8000/dept_stats

{
    "data": [
        {
            "dept_name": "计算机学院",
            "total_students": 3,
            "employed_count": 2,
            "employment_rate": 66.67
        },
        {
            "dept_name": "经济学院",
            "total_students": 2,
            "employed_count": 1,
            "employment_rate": 50.0
        },
        {
            "dept_name": "机械学院",
            "total_students": 1,
            "employed_count": 0,
            "employment_rate": 0.0
        },
        {
            "dept_name": "外语学院",
            "total_students": 1,
            "employed_count": 0,
            "employment_rate": 0.0
        },
        {
            "dept_name": "医学院",
            "total_students": 2,
            "employed_count": 1,
            "employment_rate": 50.0
        },
        {
            "dept_name": "法学院",
            "total_students": 2,
            "employed_count": 1,
            "employment_rate": 50.0
        },
        {
            "dept_name": "艺术学院",
            "total_students": 2,
            "employed_count": 1,
            "employment_rate": 50.0
        },
        {
            "dept_name": "化工学院",
            "total_students": 4,
            "employed_count": 1,
            "employment_rate": 25.0
        }
    ]
}


http://localhost:8000/major_stats

{
    "data": [
        {
            "major_name": "软件工程",
            "total_students": 2,
            "employed_count": 1,
            "employment_rate": 50.0
        },
        {
            "major_name": "人工智能",
            "total_students": 1,
            "employed_count": 1,
            "employment_rate": 100.0
        },
        {
            "major_name": "金融学",
            "total_students": 1,
            "employed_count": 1,
            "employment_rate": 100.0
        },
        {
            "major_name": "国际贸易",
            "total_students": 1,
            "employed_count": 0,
            "employment_rate": 0.0
        },
        {
            "major_name": "机械工程",
            "total_students": 1,
            "employed_count": 0,
            "employment_rate": 0.0
        },
        {
            "major_name": "英语",
            "total_students": 1,
            "employed_count": 0,
            "employment_rate": 0.0
        },
        {
            "major_name": "临床医学",
            "total_students": 2,
            "employed_count": 1,
            "employment_rate": 50.0
        },
        {
            "major_name": "法学",
            "total_students": 2,
            "employed_count": 1,
            "employment_rate": 50.0
        },
        {
            "major_name": "视觉传达",
            "total_students": 2,
            "employed_count": 1,
            "employment_rate": 50.0
        },
        {
            "major_name": "化学工程",
            "total_students": 4,
            "employed_count": 1,
            "employment_rate": 25.0
        }
    ]
}

http://localhost:8000/student_employment/S2020002

{
    "data": [
        {
            "student_name": "李红",
            "company_name": "ByteDance",
            "job_title": "前端开发",
            "salary": 18000.0,
            "sign_date": "2024-05-02"
        },
        {
            "student_name": "李红",
            "company_name": "Huawei Technologies",
            "job_title": "5G工程师",
            "salary": 21000.0,
            "sign_date": "2024-04-28"
        }
    ]
}


step4:接下来写前端angular

step5:service统一http接口 C:\Users\Administrator\WebstormProjects\untitled4\src\app\job\employment.service.ts

// employment.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class EmploymentService {
  private apiUrl = 'http://localhost:8000';

  constructor(private http: HttpClient) { }

  getStudentEmployment(id: string): Observable<any> {
    return this.http.get(`${this.apiUrl}/student_employment/${id}`);
  }

  getMajorStats(): Observable<any> {
    return this.http.get(`${this.apiUrl}/major_stats`);
  }

  getDepartmentStats(): Observable<any> {
    return this.http.get(`${this.apiUrl}/dept_stats`);
  }

  getHotJobs(): Observable<any> {
    return this.http.get(`${this.apiUrl}/jobs/hot`);
  }

  getUnemployed(): Observable<any> {
    return this.http.get(`${this.apiUrl}/unemployed_students`);
  }

  getCompanyStats(): Observable<any> {
    return this.http.get(`${this.apiUrl}/company_stats`);
  }
}

step6:主界面 C:\Users\Administrator\WebstormProjects\untitled4\src\app\job\job.component.ts

import { Component ,OnInit} from '@angular/core';

import { EmploymentService } from './employment.service';
import {FormsModule} from '@angular/forms';
import {CurrencyPipe, DatePipe, NgForOf, NgIf} from '@angular/common';

@Component({
  selector: 'app-job',
  imports: [
    FormsModule,
    NgIf,
    NgForOf,
    CurrencyPipe,
    DatePipe
  ],
  templateUrl: './job.component.html',
  styleUrl: './job.component.css'
})
export class JobComponent implements OnInit {
  studentEmployment: any[] = [];
  majorStats: any[] = [];
  departmentStats: any[] = [];
  hotJobs: any[] = [];
  unemployedStudents: any[] = [];
  companyStats: any[] = [];
  selectedStudentId = 'S2020002';

  constructor(private employmentService: EmploymentService) {}

  ngOnInit() {
    this.loadAllData();
  }

  loadAllData() {
    this.employmentService.getStudentEmployment(this.selectedStudentId)
      .subscribe(res => this.studentEmployment = res.data);

    this.employmentService.getMajorStats()
      .subscribe(res => this.majorStats = res.data);

    this.employmentService.getDepartmentStats()
      .subscribe(res => this.departmentStats = res.data);

    this.employmentService.getHotJobs()
      .subscribe(res => this.hotJobs = res.data);

    this.employmentService.getUnemployed()
      .subscribe(res => this.unemployedStudents = res.data);

    this.employmentService.getCompanyStats()
      .subscribe(res => this.companyStats = res.data);
  }
}

step7:布局 C:\Users\Administrator\WebstormProjects\untitled4\src\app\job\job.component.html

<!-- app.component.html -->
<div class="dashboard-container">
  <!-- 学生就业查询 -->
  <section class="card">
    <h2>学生就业查询</h2>
    <div class="search-box">
      <input [(ngModel)]="selectedStudentId" placeholder="输入学号">
      <button (click)="loadAllData()">查询</button>
    </div>
    <table *ngIf="studentEmployment.length > 0">
      <thead>
      <tr>
        <th>姓名</th>
        <th>企业</th>
        <th>岗位</th>
        <th>薪资</th>
        <th>入职日期</th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let item of studentEmployment">
        <td>{{item.student_name}}</td>
        <td>{{item.company_name}}</td>
        <td>{{item.job_title}}</td>
        <td>{{ item.salary  | currency:'CNY':'symbol' }}</td>
        <td>{{ item.sign_date| date:'medium' }}</td>
      </tr>
      </tbody>
    </table>
  </section>

  <!-- 专业就业率 -->
  <section class="card">
    <h2>专业就业率</h2>
    <table>
      <thead>
      <tr>
        <th>专业</th>
        <th>总人数</th>
        <th>就业率</th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let item of majorStats">
        <td>{{item.major_name}}</td>
        <td>{{item.total_students}}</td>
        <td>{{item.employment_rate}}%</td>
      </tr>
      </tbody>
    </table>
  </section>

  <!-- 院系就业统计 -->
  <section class="card">
    <h2>院系就业统计</h2>
    <table>
      <thead>
      <tr>
        <th>院系</th>
        <th>总人数</th>
        <th>就业率</th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let item of departmentStats">
        <td>{{item.dept_name}}</td>
        <td>{{item.total_students}}</td>
        <td>{{item.employment_rate}}%</td>
      </tr>
      </tbody>
    </table>
  </section>

  <!-- 热门岗位分析 -->
  <section class="card">
    <h2>热门岗位分析</h2>
    <table>
      <thead>
      <tr>
        <th>岗位名称</th>
        <th>投递次数</th>
        <th>录用人数</th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let job of hotJobs">
        <td>{{ job.job_title }}</td>
        <td>{{ job.apply_count }}</td>
        <td>{{ job.hire_count }}</td>
      </tr>
      </tbody>
    </table>
  </section>

  <!-- 未就业名单 -->
  <section class="card">
    <h2>未就业学生名单</h2>
    <table>
      <thead>
      <tr>
        <th>学号</th>
        <th>姓名</th>
        <th>专业</th>
        <th>院系</th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let item of unemployedStudents">
        <td>{{item.student_id}}</td>
        <td>{{item.name}}</td>
        <td>{{item.major_name}}</td>
        <td>{{item.dept_name}}</td>
      </tr>
      </tbody>
    </table>
  </section>

  <!-- 企业招聘分析 -->
  <section class="card">
    <h2>企业招聘分析</h2>
    <table>
      <thead>
      <tr>
        <th>企业名称</th>
        <th>岗位数</th>
        <th>收到简历</th>
        <th>实际录用</th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let item of companyStats">
        <td>{{item.company_name}}</td>
        <td>{{item.job_postings}}</td>
        <td>{{item.applications_received}}</td>
        <td>{{item.hires_made}}</td>
      </tr>
      </tbody>
    </table>
  </section>
</div>

step8:css C:\Users\Administrator\WebstormProjects\untitled4\src\app\job\job.component.css

/* app.component.css */
.dashboard-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 20px;
  padding: 20px;
}

.card {
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  padding: 20px;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 15px;
}

th, td {
  padding: 12px;
  text-align: left;
  border-bottom: 1px solid #ddd;
}

th {
  background-color: #f5f5f5;
}

.search-box {
  margin-bottom: 20px;
  display: flex;
  gap: 10px;
}

input {
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  flex: 1;
}

button {
  padding: 8px 16px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.chart-section {
  grid-column: 1 / -1;
}

.chart-container {
  height: 400px;
}

end


http://www.kler.cn/a/576130.html

相关文章:

  • 慕慕手记项目日记 2025-3-7 项目基本环境搭建
  • 如何用FFmpeg高效拉流(避坑指南)
  • 捣鼓180天,我写了一个相册小程序
  • Zypher Network :基于零知识证明方案为 AI 赋予可信框架
  • leetcode麻烦又易忘记题目
  • Python Flask框架学习汇编
  • ReferenceError: assignment to undeclared variable xxx
  • C/C++基础知识复习(50)
  • 九、Redis 并发控制:单线程原理与 Pipeline 批量优化
  • 部署Nagios Core服務器安裝好了部署了aapenal 作為網頁服務器設定了防火墻可視化的軟件來每日監測服務器的狀況.
  • 计算机毕业设计SpringBoot+Vue.js周边游平台(源码+文档+PPT+讲解)
  • createrepo centos通过nginx搭建本地源
  • 实现NTLM relay攻击工具的Python代码示例
  • TensorFlow的pb模型
  • 如何在PHP爬虫中处理异常情况的详细指南
  • Python基于Django的图书馆管理系统【附源码、文档说明】
  • SpringMVC 的配置及拦截器
  • 推荐一个基于Koin, Ktor Paging等组件的KMM Compose Multiplatform项目
  • macOS常用网络管理配置命令
  • ReAct论文阅读笔记总结