二一(GIT4)、echarts(地图)、黑马就业数据平台(学生页-增 删 改)

时间:2024-12-10 14:44:17

1. echarts 地图

  • echarts社区:makeapie echarts社区图表可视化案例

  • 社区模板代码地址:自定义 tooltip-轮播 - category-work,series-map地图,tooltip提示框,visualMap视觉映射 - makeapie echarts社区图表可视化案例

// todo: 籍贯分布 地图
function renderProvince(provinceData) {
  // console.log(provinceData);

  const chartDom = document.querySelector("#map");
  const myEchart = echarts.init(chartDom);
  const dataList = [
    { name: "南海诸岛", value: 0 },
    { name: "北京", value: 0 },
    { name: "天津", value: 0 },
    { name: "上海", value: 0 },
    { name: "重庆", value: 0 },
    { name: "河北", value: 0 },
    { name: "河南", value: 0 },
    { name: "云南", value: 0 },
    { name: "辽宁", value: 0 },
    { name: "黑龙江", value: 0 },
    { name: "湖南", value: 0 },
    { name: "安徽", value: 0 },
    { name: "山东", value: 0 },
    { name: "*", value: 0 },
    { name: "江苏", value: 0 },
    { name: "浙江", value: 0 },
    { name: "江西", value: 0 },
    { name: "湖北", value: 0 },
    { name: "广西", value: 0 },
    { name: "甘肃", value: 0 },
    { name: "山西", value: 0 },
    { name: "内蒙古", value: 0 },
    { name: "陕西", value: 0 },
    { name: "吉林", value: 0 },
    { name: "福建", value: 0 },
    { name: "贵州", value: 0 },
    { name: "广东", value: 0 },
    { name: "青海", value: 0 },
    { name: "*", value: 0 },
    { name: "四川", value: 0 },
    { name: "宁夏", value: 0 },
    { name: "海南", value: 0 },
    { name: "*", value: 0 },
    { name: "香港", value: 0 },
    { name: "澳门", value: 0 },
  ];
  // * 接口数据带省/自治区等字,不能直接拿来用 需双层遍历,将接口数据赋值给dataList内对应数据
  dataList.forEach((item) => {
    provinceData.forEach((res) => {
      // * includes() 返回值为布尔型
      if (res.name.includes(item.name)) {
        item.value = res.value;
      }
    });
  });
  const option = {
    title: {
      text: "籍贯分布",
      top: 10,
      left: 10,
      textStyle: {
        fontSize: 16,
      },
    },
    tooltip: {
      trigger: "item",
      formatter: "{b}: {c} 位学员",
      borderColor: "transparent",
      backgroundColor: "rgba(0,0,0,0.5)",
      textStyle: {
        color: "#fff",
      },
    },
    visualMap: {
      min: 0,
      max: 6,
      left: "left",
      bottom: "20",
      text: ["6", "0"],
      inRange: {
        color: ["#ffffff", "#0075F0"],
      },
      show: true,
      left: 40,
    },
    geo: {
      map: "china",
      roam: false,
      zoom: 1.0,
      label: {
        normal: {
          show: true,
          fontSize: "10",
          color: "rgba(0,0,0,0.7)",
        },
      },
      itemStyle: {
        normal: {
          borderColor: "rgba(0, 0, 0, 0.2)",
          color: "#e0ffff",
        },
        emphasis: {
          areaColor: "#34D39A",
          shadowOffsetX: 0,
          shadowOffsetY: 0,
          shadowBlur: 20,
          borderWidth: 0,
          shadowColor: "rgba(0, 0, 0, 0.5)",
        },
      },
    },
    series: [
      {
        name: "籍贯分布",
        type: "map",
        geoIndex: 0,
        data: dataList,
      },
    ],
  };
  myEchart.setOption(option);
}

2. 黑马就业数据平台

学生页增删改

// 调用函数 判断是否有token(登录校验)
checkLogin();

// 渲染用户名
renderName(1);

// 退出登录
logout();

// * 渲染学生信息 增删改之后需再次渲染 → 封装函数
// * 获取服务器学生列表 并渲染到页面
async function render() {
  // 已设置请求拦截器
  const res = await axios.get("/students");
  const str = res.data
    .map((item) => {
      const {
        id,
        name,
        age,
        gender,
        group,
        hope_salary,
        salary,
        province,
        city,
        area,
      } = item;
      return `
        <tr>
          <td>${name}</td>
          <td>${age}</td>
          <td>${gender === 0 ? "男" : "女"}</td>
          <td>第${group}组</td>
          <td>${hope_salary}</td>
          <td>${salary}</td>
          <td>${province + city + area}</td>
          <td data-id="${id}">
            <a href="javascript:;" class="text-success mr-3"><i class="bi bi-pen"></i></a>
            <a href="javascript:;" class="text-danger"><i class="bi bi-trash"></i></a>
          </td>
        </tr>
      `;
    })
    .join("");
  document.querySelector(".list").innerHTML = str;
  document.querySelector(".total").innerHTML = res.data.length;
}
render();

// 模态框
const modalDom = document.querySelector("#modal");
const modal = new bootstrap.Modal(modalDom);
// modal.show();

// * 省市区
// 根据name获取元素 属性选择器[name=province]
const province = document.querySelector("[name=province]");
// console.log(province);
const city = document.querySelector("[name=city]");
const area = document.querySelector("[name=area]");
async function getPCA() {
  const resP = await axios.get("/api/province");
  // console.log(resP);
  // 省份数据渲染
  province.innerHTML =
    `<option value="">--省份--</option>` +
    resP.list
      .map((item) => {
        return `<option value="${item}">${item}</option>`;
      })
      .join("");

  // 省份区域值变化时
  let pname = "";
  province.addEventListener("change", async function () {
    pname = province.value;
    // console.log(pname);

    const resC = await axios.get("/api/city", { params: { pname } });
    // console.log(resC);
    // 城市数据渲染
    city.innerHTML =
      `<option value="">--城市--</option>` +
      resC.list
        .map((item) => {
          return `<option value="${item}">${item}</option>`;
        })
        .join("");
    area.innerHTML = `<option value="">--地区--</option>`;
  });

  city.addEventListener("change", async function () {
    pname = province.value;
    let cname = city.value;
    const resA = await axios.get("/api/area", { params: { pname, cname } });
    // 地区数据渲染
    area.innerHTML =
      `<option value="">--地区--</option>` +
      resA.list
        .map((item) => {
          return `<option value="${item}">${item}</option>`;
        })
        .join("");
  });
}
getPCA();

// todo: 编辑与删除(事件委托) 代码有点长,函数封装后调用
document.querySelector(".list").addEventListener("click", function (e) {
  // 删除
  if (e.target.classList.contains("bi-trash")) {
    // console.log("删除");
    del(e.target.parentNode.parentNode.dataset.id);
  }
  // 编辑
  if (e.target.classList.contains("bi-pen")) {
    // console.log("编辑");
    edit(e.target.parentNode.parentNode.dataset.id);
    modalDom.dataset.id = e.target.parentNode.parentNode.dataset.id;
  }
});

// todo: 删除函数
async function del(id) {
  // confirm() 返回值为布尔型
  if (confirm("确定要删除吗?")) {
    await axios.delete(`/students/${id}`);
    showToast("删除成功");
    render();
  }
}

// todo: 编辑函数(点击)
// let editID = null;
async function edit(id) {
  // modalDom.dataset.id = e.target.parentNode.parentNode.dataset.id;
  // editID = id;
  // 模态框标题修改
  document.querySelector(".modal-title").innerHTML = "编辑学员";
  // 从服务器根据id获取学生详情
  const res = await axios.get(`/students/${id}`);

  // * 数据回显
  // console.log(res.data);
  // 1. 普通数据
  const keys = ["age", "group", "hope_salary", "name", "salary"];
  keys.forEach((key) => {
    document.querySelector(`[name=${key}]`).value = res.data[key];
  });

  // 2. 性别
  /* if (res.data.gender === 0) {
    document.querySelector("#cb01").checked = true;
  } else {
    document.querySelector("#cb02").checked = true;
  } */
  // document.querySelector(`#cb0${res.data.gender + 1}`).checked = true;
  const { gender } = res.data;
  const cks = document.querySelectorAll("[name=gender]");
  cks[gender].checked = true;

  // 3. 省市区
  province.value = res.data.province;

  const resC = await axios.get("/api/city", {
    params: { pname: res.data.province },
  });
  city.innerHTML =
    `<option value="">--城市--</option>` +
    resC.list
      .map((item) => {
        return `<option value="${item}">${item}</option>`;
      })
      .join("");
  city.value = res.data.city;

  const resA = await axios.get("/api/area", {
    params: { pname: res.data.province, cname: res.data.city },
  });
  area.innerHTML =
    `<option value="">--地区--</option>` +
    resA.list
      .map((item) => {
        return `<option value="${item}">${item}</option>`;
      })
      .join("");
  area.value = res.data.area;

  modal.show();
}

// todo: 新增学生
document.querySelector(".bi-plus").addEventListener("click", function () {
  // console.log(11);
  // dataset.id会将赋给其的值自动转换为字符串
  modalDom.dataset.id = "";
  // 使用removeAttribute方法来移除DOM元素的自定义属性
  // modalDom.removeAttribute("data-id");
  document.querySelector(".modal-title").innerHTML = "添加学员";
  city.innerHTML = `<option value="">--城市--</option>`;
  area.innerHTML = `<option value="">--地区--</option>`;
  modal.show();
});

// todo: 添加学生&修改学生 提交
document.querySelector("#submit").addEventListener("click", function () {
  const form = document.querySelector("#form");
  const data = serialize(form, { hash: true, empty: true });
  // 表单收集到的数据类型和服务器要求的不一致 → 数据类型转换
  data.age = +data.age;
  data.hope_salary = +data.hope_salary;
  data.salary = +data.salary;
  data.gender = +data.gender;
  data.group = +data.group;

  // 将新添数据发送到服务器
  /* if (document.querySelector(".modal-title").innerHTML.includes("添加")) {
    addStu(data);
  } else {
    editSubmit(data);
  } */
  if (modalDom.dataset.id) {
    // console.log("编辑");
    editSubmit(data);
  } else {
    // console.log("添加");
    addStu(data);
  }
  modal.hide();
  // 清空表单
  form.reset();
  /* 
  // 添加成功后 → 清空表单数据
  document.querySelectorAll(".form-control").forEach((item) => {
    item.value = "";
  });
  // 清空省市区数据
  city.innerHTML = `<option value="">--城市--</option>`;
  area.innerHTML = `<option value="">--地区--</option>`;
  // 清空性别选中状态
  document.querySelectorAll(".form-check-input").forEach((item) => {
    item.checked = false;
  }); 
  */
});

// todo: 点击确定 添加数据
async function addStu(data) {
  const res = await axios.post("/students", data);
  showToast(res.message);
  render();
}

// todo: 点击确定 修改数据
async function editSubmit(data) {
  // const res = await axios.put(`/students/${editID}`, data);
  const res = await axios.put(`/students/${modalDom.dataset.id}`, data);
  showToast(res.message);
  render();
}