IDEA + SSM + SpringBoot + Vue + Element UIは、クラス管理の追加、削除、変更、および検査を実現します

環境建設

SQL

CREATE TABLE `tb_class` (
  `c_id` varchar(32) NOT NULL COMMENT '班级ID',
  `c_name` varchar(50) DEFAULT NULL COMMENT '班级名称',
  `desc` varchar(200) DEFAULT NULL COMMENT '班级描述',
  PRIMARY KEY (`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `tb_class` */

insert  into `tb_class`(`c_id`,`c_name`,`desc`) values ('22','22','22'),('c001','Java12班','花儿222'),('c002','Java34班','艺术223'),('c003','虚拟的班级','111');

お問い合わせ

フロントエンド

  • -要件:すべての単純なクエリ
  • -手順:
  •   -ステップ1:すべてのクラスをクエリする関数を作成します
  •   -ステップ2:ページが正常に読み込まれた後に呼び出されます
  •   -ステップ3:クエリ結果を表示する
  • - 達成
<template>
  <div>
    <!-- 1.4 班级列表 start -->
    <el-table
      :data="classesList"
      stripe
      style="width: 100%">
      <el-table-column
        prop="cid"
        label="编号"
        width="180">
      </el-table-column>
      <el-table-column
        prop="cname"
        label="班级名称"
        width="180">
      </el-table-column>
      <el-table-column
        prop="desc"
        label="描述"
        width="280">
      </el-table-column>
      <el-table-column
        label="操作">
        <template slot-scope="scope">
          <!-- scope.$index, scope.row -->
          <el-button size="mini">编辑</el-button>
          <el-button size="mini" type="danger">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 1.4 班级列表 end -->
  </div>
</template>

<script>
// 1.0 导入axios
import axios from 'axios'
export default {
  data() {
    return {
      classesList: [],      // 1.1 班级列表
    }
  },
  methods: {
    async selectAllClasses() {  //1.2 查询班级
      // ajax 查询班级
      let url = `http://localhost:8888/classes`
      let { data:baseResult } = await axios.get(url)
      // 保存数据
      this.classesList = baseResult.data
    }
  },
  mounted() {
    // 1.3 调用班级
    this.selectAllClasses()
  },
}
</script>

<style>

</style>

後部

ClassesMapper:

package com.czxy.mapper;

import com.czxy.domain.Classes;
import tk.mybatis.mapper.common.Mapper;

@org.apache.ibatis.annotations.Mapper
public interface ClassesMapper extends Mapper<Classes> {
}

ClassesService:

package com.czxy.service;

import com.czxy.domain.Classes;

import java.util.List;

public interface ClassesService {

    /**
     * 查询所有班级
     * @return
     */
    public List<Classes> selectAllClasses();

}

ClassesServiceImpl:

package com.czxy.service.impl;

import com.czxy.domain.Classes;
import com.czxy.mapper.ClassesMapper;
import com.czxy.service.ClassesService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;



@Service
@Transactional
public class ClassesServiceImpl implements ClassesService {

    @Resource
    private ClassesMapper classesMapper;

    @Override
    public List<Classes> selectAllClasses() {
        return classesMapper.selectAll();
    }

}

ClassesController:

package com.czxy.controller;

import com.czxy.domain.Classes;
import com.czxy.service.ClassesService;
import com.czxy.vo.BaseResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;


@RestController
@RequestMapping("/classes")
@CrossOrigin
public class ClassesController {

    @Resource
    private ClassesService classesService;

    @GetMapping
    public BaseResult selectAll(){
        List<Classes> list = classesService.selectAllClasses();
        return BaseResult.ok("查询成功",list);
    }
}

追加:ポップアップ

フロントエンド

  • 要件:ポップアップを使用して追加を完了します
  • ステップ:
  • ステップ1:ポップアップをコピーし、コード(変数)をデバッグします
  • ステップ2:ポップアップ表示変数、フォーム変数を宣言する(フォームバインディング)
  • ステップ3:関数を追加し、ボタンでバインドする
  • 達成
<template>
  <div>
    <!-- 2.4 添加按钮 -->
    <el-button type="primary" round @click="openAddDialog">添加</el-button>
    <!-- 1.4 班级列表 start -->
    <el-table
      :data="classesList"
      stripe
      style="width: 100%">
      <el-table-column
        prop="cid"
        label="编号"
        width="180">
      </el-table-column>
      <el-table-column
        prop="cname"
        label="班级名称"
        width="180">
      </el-table-column>
      <el-table-column
        prop="desc"
        label="描述"
        width="280">
      </el-table-column>
      <el-table-column
        label="操作">
        <template slot-scope="scope">
          <!-- scope.$index, scope.row -->
          <el-button size="mini">编辑</el-button>
          <el-button size="mini" type="danger">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 1.4 班级列表 end -->

    <!-- 2.1 添加弹出框 start -->
    <el-dialog title="添加班级" :visible.sync="classesAddVisible">
      <el-form :model="classes" label-width="80px">
        <el-form-item label="班级编号">
          <el-input v-model="classes.cid"></el-input>
        </el-form-item>
        <el-form-item label="班级名称">
          <el-input v-model="classes.cname"></el-input>
        </el-form-item>
        <el-form-item label="班级描述">
          <el-input type="textarea" v-model="classes.desc"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="classesAddVisible = false">取 消</el-button>
        <el-button type="primary" @click="addClasses">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 2.1 添加弹出框 end -->
  </div>
</template>

<script>
// 1.0 导入axios
import axios from 'axios'
export default {
  data() {
    return {
      classesList: [],            // 1.1 班级列表
      classesAddVisible: false,    // 2.2 添加弹出框的变量
      classes: {},                // 2.3 班级表单
    }
  },
  methods: {
    async selectAllClasses() {  //1.2 查询班级
      // ajax 查询班级
      let url = `http://localhost:8888/classes`
      let { data:baseResult } = await axios.get(url)
      // 保存数据
      this.classesList = baseResult.data
    },
    openAddDialog() {       //2.5 显示弹出框
      this.classesAddVisible = true
    },
    async addClasses() {          //2.6 添加班级
      // ajax
      var url = `http://localhost:8888/classes`
      let { data: baseResult } = await axios.post(url, this.classes) 
      // 处理结果
      if(baseResult.code == 20000) {
        // 成功
        // 提示
        this.$message.success(baseResult.message)
        // 刷新页面
        this.selectAllClasses()
        // 关闭弹出框
        this.classesAddVisible = false
      } else {
        // 失败
        this.$message.error(baseResult.message)
      }
    }
  },
  mounted() {
    // 1.3 调用班级
    this.selectAllClasses()
  },
}
</script>

<style>

</style>

後部

ClassesService

package com.czxy.service;

import com.czxy.domain.Classes;

import java.util.List;

public interface ClassesService {

    /**
     * 添加 | 修改 班级
     * @return
     */
    public boolean addClasses(Classes classes);
}

ClassesServiceImpl

package com.czxy.service.impl;

import com.czxy.domain.Classes;
import com.czxy.mapper.ClassesMapper;
import com.czxy.service.ClassesService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;


@Service
@Transactional
public class ClassesServiceImpl implements ClassesService {
    @Override
    public boolean addClasses(Classes classes) {
        Classes cls = classesMapper.selectByPrimaryKey(classes.getCid());
        int result;
        if(cls != null){
            result = classesMapper.updateByPrimaryKey(classes);
        }else{
            result = classesMapper.insert(classes);
        }

        return result == 1;
    }

}

ClassesController

package com.czxy.controller;

import com.czxy.domain.Classes;
import com.czxy.service.ClassesService;
import com.czxy.vo.BaseResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;


@RestController
@RequestMapping("/classes")
@CrossOrigin
public class ClassesController {

    @Resource
    private ClassesService classesService;

    @PostMapping
    public BaseResult addupdateClasses(@RequestBody Classes classes){
        try {
            boolean b = classesService.addClasses(classes);
            if(b){
                return BaseResult.ok("添加 | 编辑 成功");
            }else{
                return BaseResult.error("添加 | 编辑 失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return BaseResult.error(e.getMessage());
        }
    }

}

変更:引き出し

フロントエンド

  • 要件:ドロワーを使用して変更機能を完了します
  • ステップ
  • ステップ1:[変更]ボタンをクリックしてすすり泣きを開き、IDで詳細を照会します。フォームをエコーする必要があります
  • ステップ2:フォームのバインド
  • 手順3:[OK]ボタンを変更する
  • 達成
<template>
  <div>
    <!-- 2.4 添加按钮 -->
    <el-button type="primary" round @click="openAddDialog">添加</el-button>
    <!-- 1.4 班级列表 start -->
    <el-table
      :data="classesList"
      stripe
      style="width: 100%">
      <el-table-column
        prop="cid"
        label="编号"
        width="180">
      </el-table-column>
      <el-table-column
        prop="cname"
        label="班级名称"
        width="180">
      </el-table-column>
      <el-table-column
        prop="desc"
        label="描述"
        width="280">
      </el-table-column>
      <el-table-column
        label="操作">
        <template slot-scope="scope">
          <!-- scope.$index, scope.row -->
          <!-- 3.1 打开编辑抽屉 -->
          <el-button size="mini" @click="openEditDrawer(scope.row.cid)">编辑</el-button>
          <el-button size="mini" type="danger">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 1.4 班级列表 end -->

    <!-- 2.1 添加弹出框 start -->
    <el-dialog title="添加班级" :visible.sync="classesAddVisible">
      <el-form :model="classes" label-width="80px">
        <el-form-item label="班级编号">
          <el-input v-model="classes.cid"></el-input>
        </el-form-item>
        <el-form-item label="班级名称">
          <el-input v-model="classes.cname"></el-input>
        </el-form-item>
        <el-form-item label="班级描述">
          <el-input type="textarea" v-model="classes.desc"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="classesAddVisible = false">取 消</el-button>
        <el-button type="primary" @click="addClasses">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 2.1 添加弹出框 end -->

    <!-- 3.3 抽屉 start -->
    <el-drawer
      title="修改班级"
      :visible.sync="classesEditDrawerVisible"
      direction="rtl">
      <!-- 修改表单 start -->
      <el-form :model="classes" label-width="80px">
        <el-form-item label="班级编号">
          <el-input v-model="classes.cid"></el-input>
        </el-form-item>
        <el-form-item label="班级名称">
          <el-input v-model="classes.cname"></el-input>
        </el-form-item>
        <el-form-item label="班级描述">
          <el-input type="textarea" v-model="classes.desc"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="editClasses">立即创建</el-button>
          <el-button @click="classesEditDrawerVisible = false">取消</el-button>
        </el-form-item>
      </el-form>
      <!-- 修改表单 end -->
    </el-drawer>
    <!-- 3.3 抽屉 end -->
  </div>
</template>

<script>
// 1.0 导入axios
import axios from 'axios'
export default {
  data() {
    return {
      classesList: [],            // 1.1 班级列表
      classesAddVisible: false,    // 2.2 添加弹出框的变量
      classes: {},                // 2.3 班级表单
      classesEditDrawerVisible: false,  // 3.4 抽屉变量
    }
  },
  methods: {
    async selectAllClasses() {  //1.2 查询班级
      // ajax 查询班级
      let url = `http://localhost:8888/classes`
      let { data:baseResult } = await axios.get(url)
      // 保存数据
      this.classesList = baseResult.data
    },
    openAddDialog() {       //2.5 显示弹出框
      this.classesAddVisible = true
    },
    async addClasses() {          //2.6 添加班级
      // ajax
      var url = `http://localhost:8888/classes`
      let { data: baseResult } = await axios.post(url, this.classes) 
      // 处理结果
      if(baseResult.code == 20000) {
        // 成功
        // 提示
        this.$message.success(baseResult.message)
        // 刷新页面
        this.selectAllClasses()
        // 关闭弹出框
        this.classesAddVisible = false
      } else {
        // 失败
        this.$message.error(baseResult.message)
      }
    },
    async openEditDrawer(cid) {  //3.2 打开编辑抽屉函数
      // 打开抽屉
      this.classesEditDrawerVisible = true
      // 查询详情
      let url = `http://localhost:8888/classes/${cid}`
      let { data: baseResult } = await axios.get(url)
      this.classes = baseResult.data
    },
    async editClasses() {   //3.4 修改班级函数
      // ajax
      var url = `http://localhost:8888/classes`
      let { data: baseResult } = await axios.put(url, this.classes) 
      // 处理结果
      if(baseResult.code == 20000) {
        // 成功
        // 提示
        this.$message.success(baseResult.message)
        // 刷新页面
        this.selectAllClasses()
        // 关闭抽屉
        this.classesEditDrawerVisible = false
      } else {
        // 失败
        this.$message.error(baseResult.message)
      }
    }
  },
  mounted() {
    // 1.3 调用班级
    this.selectAllClasses()
  },
}
</script>

<style>

</style>

後部

ClassesService

package com.czxy.service;

import com.czxy.domain.Classes;

import java.util.List;

public interface ClassesService {

    /**
     * 添加 | 修改 班级
     * @return
     */
    public boolean addClasses(Classes classes);

    /**
     * 查询指定班级
     * @param cid
     * @return
     */
    public Classes selectById(String cid);

}

ClassesServiceImpl

package com.czxy.service.impl;

import com.czxy.domain.Classes;
import com.czxy.mapper.ClassesMapper;
import com.czxy.service.ClassesService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;


@Service
@Transactional
public class ClassesServiceImpl implements ClassesService {

    @Resource
    private ClassesMapper classesMapper;

    @Override
    public boolean addClasses(Classes classes) {
        Classes cls = classesMapper.selectByPrimaryKey(classes.getCid());
        int result;
        if(cls != null){
            result = classesMapper.updateByPrimaryKey(classes);
        }else{
            result = classesMapper.insert(classes);
        }

        return result == 1;
    }

    @Override
    public Classes selectById(String cid) {
        Classes classes = classesMapper.selectByPrimaryKey(cid);
        return classes;
    }

}

ClassesServiceController

package com.czxy.controller;

import com.czxy.domain.Classes;
import com.czxy.service.ClassesService;
import com.czxy.vo.BaseResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Author 刘嘉俊
 * @Date 2022/3/21
 */
@RestController
@RequestMapping("/classes")
@CrossOrigin
public class ClassesController {

    @Resource
    private ClassesService classesService;


    @PostMapping
    public BaseResult addupdateClasses(@RequestBody Classes classes){
        try {
            boolean b = classesService.addClasses(classes);
            if(b){
                return BaseResult.ok("添加 | 编辑 成功");
            }else{
                return BaseResult.error("添加 | 编辑 失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return BaseResult.error(e.getMessage());
        }
    }

    @GetMapping("/{cid}")
    public BaseResult selectById(@PathVariable("cid") String cid){
        System.out.println(cid);
        Classes classes = classesService.selectById(cid);
        return BaseResult.ok("查询成功",classes);
    }
}

消去

基本的なスキル

  • 要件:削除ボタンをクリックして、削除操作を完了します

  • 達成

<template>
  <div>
    <!-- 2.4 添加按钮 -->
    <el-button type="primary" round @click="openAddDialog">添加</el-button>
    <!-- 1.4 班级列表 start -->
    <el-table
      :data="classesList"
      stripe
      style="width: 100%">
      <el-table-column
        prop="cid"
        label="编号"
        width="180">
      </el-table-column>
      <el-table-column
        prop="cname"
        label="班级名称"
        width="180">
      </el-table-column>
      <el-table-column
        prop="desc"
        label="描述"
        width="280">
      </el-table-column>
      <el-table-column
        label="操作">
        <template slot-scope="scope">
          <!-- scope.$index, scope.row -->
          <!-- 3.1 打开编辑抽屉 -->
          <el-button size="mini" @click="openEditDrawer(scope.row.cid)">编辑</el-button>
          <!-- 4.1 删除 -->
          <el-button size="mini" @click="deleteClasses(scope.row.cid)" type="danger">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 1.4 班级列表 end -->

    <!-- 2.1 添加弹出框 start -->
    <el-dialog title="添加班级" :visible.sync="classesAddVisible">
      <el-form :model="classes" label-width="80px">
        <el-form-item label="班级编号">
          <el-input v-model="classes.cid"></el-input>
        </el-form-item>
        <el-form-item label="班级名称">
          <el-input v-model="classes.cname"></el-input>
        </el-form-item>
        <el-form-item label="班级描述">
          <el-input type="textarea" v-model="classes.desc"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="classesAddVisible = false">取 消</el-button>
        <el-button type="primary" @click="addClasses">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 2.1 添加弹出框 end -->

    <!-- 3.3 抽屉 start -->
    <el-drawer
      title="修改班级"
      :visible.sync="classesEditDrawerVisible"
      direction="rtl">
      <!-- 修改表单 start -->
      <el-form :model="classes" label-width="80px">
        <el-form-item label="班级编号">
          <el-input v-model="classes.cid"></el-input>
        </el-form-item>
        <el-form-item label="班级名称">
          <el-input v-model="classes.cname"></el-input>
        </el-form-item>
        <el-form-item label="班级描述">
          <el-input type="textarea" v-model="classes.desc"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="editClasses">立即创建</el-button>
          <el-button @click="classesEditDrawerVisible = false">取消</el-button>
        </el-form-item>
      </el-form>
      <!-- 修改表单 end -->
    </el-drawer>
    <!-- 3.3 抽屉 end -->
  </div>
</template>

<script>
// 1.0 导入axios
import axios from 'axios'
export default {
  data() {
    return {
      classesList: [],            // 1.1 班级列表
      classesAddVisible: false,    // 2.2 添加弹出框的变量
      classes: {},                // 2.3 班级表单
      classesEditDrawerVisible: false,  // 3.4 抽屉变量
    }
  },
  methods: {
    async selectAllClasses() {  //1.2 查询班级
      // ajax 查询班级
      let url = `http://localhost:8888/classes`
      let { data:baseResult } = await axios.get(url)
      // 保存数据
      this.classesList = baseResult.data
    },
    openAddDialog() {       //2.5 显示弹出框
      this.classesAddVisible = true
    },
    async addClasses() {          //2.6 添加班级
      // ajax
      var url = `http://localhost:8888/classes`
      let { data: baseResult } = await axios.post(url, this.classes) 
      // 处理结果
      if(baseResult.code == 20000) {
        // 成功
        // 提示
        this.$message.success(baseResult.message)
        // 刷新页面
        this.selectAllClasses()
        // 关闭弹出框
        this.classesAddVisible = false
      } else {
        // 失败
        this.$message.error(baseResult.message)
      }
    },
    async openEditDrawer(cid) {  //3.2 打开编辑抽屉函数
      // 打开抽屉
      this.classesEditDrawerVisible = true
      // 查询详情
      let url = `http://localhost:8888/classes/${cid}`
      let { data: baseResult } = await axios.get(url)
      this.classes = baseResult.data
    },
    async editClasses() {   //3.4 修改班级函数
      // ajax
      var url = `http://localhost:8888/classes`
      let { data: baseResult } = await axios.put(url, this.classes) 
      // 处理结果
      if(baseResult.code == 20000) {
        // 成功
        // 提示
        this.$message.success(baseResult.message)
        // 刷新页面
        this.selectAllClasses()
        // 关闭抽屉
        this.classesEditDrawerVisible = false
      } else {
        // 失败
        this.$message.error(baseResult.message)
      }
    },
    deleteClasses(cid) {    // 4.2 删除功能
      // 询问
      this.$confirm('您确定要删除么?', '删除提示', {
        type: 'warning'
      }).then(async () => {
        // 确认
        let url = `http://localhost:8888/classes/${cid}`
        let { data:baseResult } = await axios.delete(url)
        if(baseResult.code == 20000) {
          // 成功
          this.$message.success(baseResult.message)
          // 刷新
          this.selectAllClasses()
        } else {
          // 失败
          this.$message.error(baseResult.message)
        }
      }).catch(() => {
        // 
        this.$message.info('用户已取消')         
      });
    }
  },
  mounted() {
    // 1.3 调用班级
    this.selectAllClasses()
  },
}
</script>

<style>

</style>

関連情報を確認する

  • 要件:関連データがある場合は、最初にクエリを実行してから、プロンプトを表示します

  • ステップ:

    • ステップ1:指定されたクラスの学生にクエリを提供するように学生マッパーを変更します

    • ステップ2:データ検証のためにクラスサービスを変更する

  • ステップ1:指定されたクラスの学生にクエリを提供するように学生マッパーを変更します

package com.czxy.mapper;

import com.czxy.domain.Student;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import tk.mybatis.mapper.common.Mapper;

import java.util.List;


@org.apache.ibatis.annotations.Mapper
public interface StudentMapper extends Mapper<Student> {

    /**
     * 通过班级id查询
     * @param classesId
     * @return
     */
    @Select("SELECT *,s_id AS sid , c_id AS cid FROM tb_student WHERE c_id = #{classesId}")
    public List<Student> selectAllByCid(@Param("classesId") String classesId);
}

ステップ2:データ検証のためにクラスサービスを変更する

    @Override
    public boolean delete(String cid) {
        // 校验:查询,如果有数据抛异常
        List<Student> studentList = studentMapper.selectAllByCid(cid);
        if(studentList.size() > 0 ) {
            // 有关联数据,不允许删除
            throw new RuntimeException("班级关联学生,请先删除学生!");
        }
        // 删除班级
        int delete = classesMapper.deleteByPrimaryKey(cid);
        return delete == 1;
    }

 構成クラス

BaseResult

package com.czxy.vo;


import java.util.HashMap;
import java.util.Map;


public class BaseResult<T> {

    //成功状态码
    public static final int OK = 20000;
    //失败状态码
    public static final int ERROR = 0;

    //返回码
    private Integer code;
    //返回消息
    private String message;

    //存放数据
    private T data;
    //其他数据
    private Map<String,Object> other = new HashMap<>();

    public BaseResult() {

    }

    public BaseResult(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
    public BaseResult(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /**
     * 快捷成功BaseResult对象
     * @param message
     * @return
     */
    public static BaseResult ok(String message){
        return new BaseResult<>(BaseResult.OK , message);
    }

    public static BaseResult ok(String message, Object data){
        return new BaseResult<>(BaseResult.OK , message, data );
    }

    /**
     * 快捷失败BaseResult对象
     * @param message
     * @return
     */
    public static BaseResult error(String message){
        return new BaseResult(BaseResult.ERROR , message);
    }

    /**
     * 自定义数据区域
     * @param key
     * @param msg
     * @return
     */
    public BaseResult append(String key , Object msg){
        other.put(key , msg);
        return this;
    }

    public Integer getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    public T getData() {
        return data;
    }

    public Map<String, Object> getOther() {
        return other;
    }
}

おすすめ

転載: blog.csdn.net/weixin_45481821/article/details/123636755