19. Make a lab appointment

Making laboratory reservations is a prerogative of teachers. So we should log in with the teacher role.

1. Front-end

1.1. Create a laboratory reservation page

You can copy and paste our previous code in AddList.vue and then modify it

<template>
  <div>
    <div style="min-height: 500px; justify-content: center;position: relative" id="map" />
    <!-- 对话框 -->
    <el-dialog v-model="dialogVisible" title="添加实验室">
      <el-form ref="addFormRef" :model="addForm" :rules="rules" label-width="100px" class="ruleForm" status-icon>
        <el-form-item label="实验室名称" prop="title">
          <el-input v-model="addForm.title" />
        </el-form-item>
        <el-form-item label="容纳人数" prop="capacity">
          <el-input v-model="addForm.capacity" type="number" />
        </el-form-item>
        <!-- 下拉列表 -->
        <el-form-item label="实验室类型" prop="lab_type">
          <el-select v-model="addForm.lab_type" class="m-2" placeholder="请选择实验室类型" size="large" style="width: 100%;">
            <el-option v-for="item in LabType" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="所属学院" prop="college_type">
          <el-select v-model="addForm.college_type" class="m-2" placeholder="请选择学院" size="large" style="width: 100%;">
            <el-option v-for="item in CollegeType" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleConfirm()">
            更新
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { onMounted, ref, reactive } from "vue";
import { Scene, ImageLayer, PointLayer, Popup } from '@antv/l7';
import { Map } from '@antv/l7-maps';
import { LabType, CollegeType } from '../../util/type'
import axios from "axios";

let scene, popup;
onMounted(() => {
  // 创建Scene场景
  scene = new Scene({
    id: 'map',
    map: new Map({
      // center中心坐标,很关键,将来这个中心坐标的位置就是500,500的这样一个位置。将来我们要靠它来计算我们的偏移量的。
      center: [500, 500],
      // zoom放大:现在是放大3倍
      zoom: 3,
      version: 'SIMPLE',
      mapSize: 1000,
      // 最大是5倍
      maxZoom: 5,
      // 最小是2倍
      minZoom: 2,
      pitchEnabled: false,
      // 旋转:禁用
      rotateEnabled: false
    })
  });
  // 设置背景颜色
  scene.setBgColor('rgb(94, 182, 140)');

  // 创建imagelayer图片场景
  const imagelayer = new ImageLayer({}).source(
    '/bg.jpg',
    {
      parser: {
        type: 'image',
        // 左下角它的一个坐标位置360✖400
        // 右上角的是640✖600
        extent: [360, 400, 640, 600]
      }
    }
  );
  scene.on('loaded', () => {
    getList()
    scene.addLayer(imagelayer);

  });
})
const getList = async () => {
  var res = await axios.get("/adminapi/labs")
  // console.log(res.data);

  // map映射我们想要的结构
  var list = res.data.map(item => ({
    x: item.x,
    y: item.y,
    t: "预约"+item.title
  }))
  // 调用文字标注方法
  addTextLayer(list)
}

// 添加
const dialogVisible = ref(false)
const addFormRef = ref()
const addForm = reactive({
  title: "",
  capacity: "",
  lab_type: "",
  college_type: "",
  x: 0,
  y: 0
})
const rules = reactive({
  title: [
    { required: true, message: '请输入实验室名称', trigger: 'blur' }
  ],
  capacity: [
    { required: true, message: '请输入容纳人数', trigger: 'blur' }
  ],
  lab_type: [
    { required: true, message: '请选择实验室类型', trigger: 'blur' }
  ],
  college_type: [
    { required: true, message: '请选择学院类型', trigger: 'blur' }
  ]
})

const handleConfirm = () => {
  addFormRef.value.validate(async (valid) => {
    if (valid) {
      dialogVisible.value = false
      console.log(addForm);
      // 发送axios.post
      await axios.post(`/adminapi/labs`, addForm)
      // 添加文字标注
      addTextLayer([
        {
          "x": addForm.x,
          "y": addForm.y,
          "t": addForm.title
        }
      ])
    }
  })
}
const addTextLayer = (data) => {
  const textlayer = new PointLayer({ zIndex: 2 })
    .source(
      data,
      {
        parser: {
          type: 'json',
          x: 'x',
          y: 'y'
        }
      }
    )
    .shape('t', 'text')
    .size(14)
    .active({
      color: '#00f',
      mix: 0.9
    })
    .color('rgb(13,71,161)')
    .style({
      textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
      spacing: 2, // 字符间距
      fontWeight: '800',
      padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
      stroke: '#ffffff', // 描边颜色
      strokeWidth: 2, // 描边宽度
      textAllowOverlap: true
    });
  scene.addLayer(textlayer);
}
</script>

<style></style>

 The appointment information for laboratory No. 3 is displayed. It corresponds to the name of our laboratory list one by one, and the geographical location has not changed.

Create a new laboratory through the administrator account. When you make an appointment using the teacher role, we will be able to see the new reserved laboratory.

 1.2. Click the text to pop up a dialog box

Text binding click event

 Clicking on the text directly prints out the corresponding object, so text binding event response can be supported in geographical visualization, and the formal parameters also give us the information we need. In the feature, there are title, x, and y, which are included in the feature. Package. We can dynamically change the title on the dialog box based on the feature obtained at this time.

 1.3. Modify the fields and verification rules in the dialog box

 1.4. Get the currently clicked item and display the dialog box

 1.5. Reservation of classes and reasons for reservation

1.6. Appointment time

1.6.1. Change the font to Chinese

1.6.2. Disable date selection functiondisabledDate

This component has not been used up yet. After we select a certain day, there should be time to select a callback. In this callback, we should judge whether a certain class on this day is optional. If it is not optional, disable it. , but this function requires the cooperation of the backend.

 1.7. Testing

Let’s test whether the front end can submit data

 All submitted.

 2. Backend creation interface

2.1. Create a table in the database

0 under review, 1 passed review 2 rejected  

 2.2, pojo layer

 2.3, dao layer

 2.4、xml

2.5. Service layer

 2.6, controller layer

 2.7. Test after running

 3. Add code to the front end

The lab_id field and book_username field are now missing in the frontend.

We import useUserStore, deconstruct the user object, which is the current logged-in user information. When we click to confirm, add book_username, which is our user.username, pass it to the backend, and expand the original thing "..." Open in an object.

 Add new field id to list

The front-end and back-end are completed, let's implement the reservation laboratory together

 4. Message prompt

 5. Disabled during classes

5.1. Callback function

 If our backend passes in the corresponding lab_id and book_time, then it should filter out all the data of this laboratory on this day and return it to us. Then the front end needs to retrieve it, because the data it returns must contain the lesson book_class, so what our front end receives is our lesson array. If the array it gives us is not a complete array, we can directly perform a filter. Okay, then we can use this array to control which item in our drop-down list is disabled, so a front-end should give it such data.

Note: The backend needs to control that book_state is not equal to 2 when querying the database. The data we submit to the backend has a state to reserve the review status of the laboratory. When book_state is 0, the data should be returned, because it is under review at this time. , so others cannot make an appointment. If its value is 1 and the review is passed, then it is even less possible for others to make an appointment. If the value is 2, the review fails and the administrator rejects it. Others or the current person can still make an appointment and write down the reasons carefully.

Therefore, when querying the database at the back end, the value of book_state must be filtered and judged. It cannot be equal to 2, so it can only be equal to 0 and 1.

Note: The front end cannot use get when sending requests to the back end, but must use post, because the book_time we need to pass in here, the back end receives a date type, but because our axios will do the date when making the get request A conversion, forcibly converting the date format into a string, cannot be obtained by the backend in the get parameter, so there may be some problems here.

In the post request, the time sent in axios will be automatically converted to ISO 8601 format. Pass it to the backend and receive it normally.

This format represents a string of dates and times with a uniform format and legibility. This ensures that time data is parsed and processed correctly across different systems and languages.

The ISO 8601 format is a date and time representation format defined by the International Organization for Standardization (ISO). It uses the form 'YYYY-MM-DD' to represent dates, and can be expanded to include time, time zone and other related information. The format is designed to provide a unified way to represent dates and times so that various countries and regions can easily parse and exchange date and time information.

 5.2. Backend creation interface

 test

5.3. Front-end

​​​​​​​​​​​​​​

 

Guess you like

Origin blog.csdn.net/m0_65436732/article/details/133544919