Vue系列第七篇:Element UI之el-main,el-table,el-dialog,el-pagination,el-breadcrumb等控件使用

本篇实现主页面功能,包括主页面排版布局,学生管理模块实现,后台接口实现等功能。

目录

1.运行效果

1.1登录页面

1.2主页面

 1.3学生管理 - 信息列表

1.4学生管理 - 信息管理

 1.5学生管理 - 作业列表

1.6学生管理 - 作业管理

2.前端代码

2.1 代码结构

 2.2 代码实现

3.后端代码

3.1 代码结构

3.2 代码实现

4.其他

4.1 vscode快速编写正则表达式


1.运行效果

1.1登录页面

1.2主页面

 1.3学生管理 - 信息列表

 

 

1.4学生管理 - 信息管理

 1.5学生管理 - 作业列表

1.6学生管理 - 作业管理

2.前端代码

2.1 代码结构

 2.2 代码实现

src/api/api.js

//业务服务调用接口封装import service from '../service.js'
//npm i qs -D
import qs from 'qs'//登录接口
export function login(data) {return service({method: 'post',url: '/login',data})
}//学生信息查询接口
export function students(params) {return service({method: 'get',url: '/api/students',params})
}//删除学生信息
export function delstudentsbyid(id) {return service({method: 'get',//此处应用模板字符串传参url: `/api/students/del?id=${id}`})
}export function delstudentsbyreqid(id) {return service({method: 'get',//此处应用模板字符串传参url: `/api/students/del/${id}`})
}export function addStudent(data) {//data = qs.stringify(data)return service({method: 'post',url: '/api/info',data})
}export function updateStudent(data) {return service({method: 'post',url: '/api/updateinfo',data})
}export function getInfo() {return service({method: 'get',url: '/api/getinfo'})
}export function delinfo(id) {return service({method: 'get',//此处应用模板字符串传参url: `/api/info/del/id=${id}`})
}

src/components/common/students/InfoList.vue

<!-- 信息列表页面 -->
<template><div class="infoList"><!-- 新增表单 --><el-form :inline="true" :model="form" class="demo-form-inline" size="small"><el-form-item><el-button type="primary" @click="add('form')">新增</el-button></el-form-item></el-form><el-table:data="tableData"borderstyle="width: 100%"><el-table-columnprop="name"label="姓名"align="center"></el-table-column><el-table-columnprop="age"label="年龄"align="center"></el-table-column><el-table-columnprop="sex"label="性别"align="center"></el-table-column><el-table-columnprop="father"label="父亲"align="center"></el-table-column><el-table-columnprop="mother"label="母亲"align="center"></el-table-column><el-table-columnprop="time"label="入校时间"align="center"></el-table-column><el-table-columnprop="address"label="家庭住址"align="center"></el-table-column><el-table-columnprop="phone"label="联系方式"align="center"></el-table-column><!-- scope.row表示点击的当前行,包含当前行的所有数据 --><el-table-columnlabel="操作" align="center"><template slot-scope="scope"><el-button type="danger" size="mini" icon="el-icon-edit"@click="edit(scope.row)"></el-button><el-button type="danger" size="mini" icon="el-icon-delete"@click="del(scope.row)"></el-button></template></el-table-column></el-table><el-dialog :title="state ? '添加学生信息' : '修改学生信息'" :visible.sync="dialogFormVisible" width="500px"><el-form :model="form" :rules="rules" ref="form"><el-form-item label="姓名" :label-width="formLabelWidth" prop="name"><el-input v-model="form.name" autocomplete="off"></el-input></el-form-item><el-form-item label="年龄" :label-width="formLabelWidth" prop="age"><el-input v-model="form.age" autocomplete="off"></el-input></el-form-item><el-form-item label="性别" :label-width="formLabelWidth" prop="sex"><el-radio v-model="form.sex" label="1">男</el-radio><el-radio v-model="form.sex" label="2">女</el-radio></el-form-item><el-form-item label="父亲" :label-width="formLabelWidth" prop="father"><el-input v-model="form.father" autocomplete="off"></el-input></el-form-item><el-form-item label="母亲" :label-width="formLabelWidth" prop="mother"><el-input v-model="form.mother" autocomplete="off"></el-input></el-form-item><el-form-item label="入校时间" :label-width="formLabelWidth" prop="time"><el-date-pickerv-model="form.time"format="yyyy 年 MM 月 dd 日"type="date"placeholder="选择日期"></el-date-picker></el-form-item><el-form-item label="家庭住址" :label-width="formLabelWidth" prop="address"><el-input v-model="form.address" autocomplete="off"></el-input></el-form-item><el-form-item label="联系方式" :label-width="formLabelWidth" prop="phone"><el-input v-model="form.phone" autocomplete="off"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="closeForm('form')">取消</el-button><el-button type="primary" @click="sure('form')">确认</el-button></span></el-dialog></div>
</template><script>
import { addStudent, getInfo, updateStudent, delinfo } from '@/api/api.js'export default {data() {return {tableData: [],dialogFormVisible: false,form: {name: '',age: '',sex: '1',father: '',mother: '',time: '',address: '',phone: ''},formLabelWidth: "80px",rules: {name: [{required: true, message: '请输入姓名'}],age: [{required: true, message: '请输入年龄'}],sex: [{required: true, message: '请选择性别'}],time: [{required: true, message: '请选择入校时间'}],address: [{required: true, message: '请输入家庭住址'}],phone: [{required: true, message: '请输入联系方式'}]},total: 0,state: true}},created() {this.getData()},methods: {getData() {getInfo().then((res) => {if (res.data.status === 200) {this.tableData = res.data.datathis.total = res.data.total}})},add(form) {this.state = truethis.form = {name: '',age: '',sex: '1',father: '',mother: '',time: '',address: '',phone: ''}//this.$refs[form].resetFields()this.dialogFormVisible = true},edit(row) {this.state = false//此处需要扩展赋值this.form = {...row}this.dialogFormVisible = true},del(row) {this.$alert("确定要删除吗?", "提示", {confirmButtonText: '确定',callback: () => {delinfo(row.id).then(res => {if (res.data.status === 200) {this.getData()this.$message({message: res.data.msg, type: "success"})}})}})delinfo},closeForm(form) {//清调校验规则this.$refs[form].resetFields()this.dialogFormVisible = false},sure(form) {this.$refs[form].validate(valid => {if (valid) {console.log(form, this.form)if (this.state) {addStudent(this.form).then((res) => {console.log(res)if (res.data.status === 200) {this.getData()this.dialogFormVisible = falsethis.$refs[form].resetFields()this.$message({message: res.data.msg, type: "success"})}})}else {updateStudent(this.form).then((res) => {console.log(res)if (res.data.status === 200) {this.getData()this.dialogFormVisible = falsethis.$refs[form].resetFields()this.$message({message: res.data.msg, type: "success"})}})}}})}}}
</script><style lang="scss">
.infoList {.demo-form-inline, .el-form-item {text-align: left;}.el-pagination {text-align: left;margin-top: 20px;}}
</style>

src/components/common/students/InfoLists.vue

<!-- 信息管理页面 -->
<template><div class="infoList"><!-- 新增表单 --><el-form :inline="true" :model="form" class="demo-form-inline" size="small"><el-form-item><el-button type="primary" @click="add('form')">新增</el-button></el-form-item></el-form><el-table:data="tableData"borderstyle="width: 100%"><el-table-columnprop="name"label="姓名"align="center"></el-table-column><el-table-columnprop="age"label="年龄"align="center"></el-table-column><el-table-columnprop="sex"label="性别"align="center"></el-table-column><el-table-columnprop="father"label="父亲"align="center"></el-table-column><el-table-columnprop="mother"label="母亲"align="center"></el-table-column><el-table-columnprop="time"label="入校时间"align="center"></el-table-column><el-table-columnprop="address"label="家庭住址"align="center"></el-table-column><el-table-columnprop="phone"label="联系方式"align="center"></el-table-column><!-- scope.row表示点击的当前行,包含当前行的所有数据 --><el-table-columnlabel="操作" align="center"><template slot-scope="scope"><el-button type="danger" size="mini" icon="el-icon-edit"@click="edit(scope.row)"></el-button><el-button type="danger" size="mini" icon="el-icon-delete"@click="del(scope.row)"></el-button></template></el-table-column></el-table><el-dialog :title="state ? '添加学生信息' : '修改学生信息'" :visible.sync="dialogFormVisible" width="500px"><el-form :model="form" :rules="rules" ref="form"><el-form-item label="姓名" :label-width="formLabelWidth" prop="name"><el-input v-model="form.name" autocomplete="off"></el-input></el-form-item><el-form-item label="年龄" :label-width="formLabelWidth" prop="age"><el-input v-model="form.age" autocomplete="off"></el-input></el-form-item><el-form-item label="性别" :label-width="formLabelWidth" prop="sex"><el-radio v-model="form.sex" label="1">男</el-radio><el-radio v-model="form.sex" label="2">女</el-radio></el-form-item><el-form-item label="父亲" :label-width="formLabelWidth" prop="father"><el-input v-model="form.father" autocomplete="off"></el-input></el-form-item><el-form-item label="母亲" :label-width="formLabelWidth" prop="mother"><el-input v-model="form.mother" autocomplete="off"></el-input></el-form-item><el-form-item label="入校时间" :label-width="formLabelWidth" prop="time"><el-date-pickerv-model="form.time"format="yyyy 年 MM 月 dd 日"type="date"placeholder="选择日期"></el-date-picker></el-form-item><el-form-item label="家庭住址" :label-width="formLabelWidth" prop="address"><el-input v-model="form.address" autocomplete="off"></el-input></el-form-item><el-form-item label="联系方式" :label-width="formLabelWidth" prop="phone"><el-input v-model="form.phone" autocomplete="off"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="closeForm('form')">取消</el-button><el-button type="primary" @click="sure('form')">确认</el-button></span></el-dialog></div>
</template><script>
import { getData, changeInfo, delData } from '@/utils/table.js'export default {data() {return {tableData: [],dialogFormVisible: false,form: {name: '',age: '',sex: '1',father: '',mother: '',time: '',address: '',phone: ''},formLabelWidth: "80px",rules: {name: [{required: true, message: '请输入姓名'}],age: [{required: true, message: '请输入年龄'}],sex: [{required: true, message: '请选择性别'}],time: [{required: true, message: '请选择入校时间'}],address: [{required: true, message: '请输入家庭住址'}],phone: [{required: true, message: '请输入联系方式'}]},total: 0,state: true}},created() {getData(this, '/api/getinfo')},methods: {add(form) {this.state = truethis.form = {name: '',age: '',sex: '1',father: '',mother: '',time: '',address: '',phone: ''}//this.$refs[form].resetFields()this.dialogFormVisible = true},edit(row) {this.state = false//此处需要扩展赋值this.form = {...row}this.dialogFormVisible = true},del(row) {console.log("row.id", row.id)delData(this, "/api/info/del/", row.id, getData, '/api/getinfo')},closeForm(form) {//清调校验规则this.$refs[form].resetFields()this.dialogFormVisible = false},sure(form) {this.$refs[form].validate(valid => {if (valid) {console.log(form, this.form)let url = ""this.state ? url = '/api/info' : url = '/api/updateinfo'changeInfo(this, 'post', url, this.form, getData, '/api/getinfo')}})}}}
</script><style lang="scss">
.infoList {.demo-form-inline, .el-form-item {text-align: left;}.el-pagination {text-align: left;margin-top: 20px;}}
</style>

src/components/common/students/StudentList.vue

<!-- 学生列表页面 -->
<template><div class="studentList"><!-- 查询重置表单 --><el-form :inline="true" :model="formInline" class="demo-form-inline" size="small"><el-form-item label="姓名"><el-input v-model="formInline.name" placeholder="姓名查询"></el-input></el-form-item><el-form-item><el-button type="primary" @click="onFind">查询</el-button></el-form-item><el-form-item><el-button type="primary" @click="onReset">重置</el-button></el-form-item></el-form><!-- 学生列表 --><el-table:data="compData"borderstyle="width: 100%"><el-table-columnprop="name"label="姓名"align="center"></el-table-column><el-table-columnprop="age"label="年龄"align="center"></el-table-column><el-table-columnprop="sex_text"label="性别"align="center"></el-table-column><el-table-columnprop="number"label="学号"align="center"></el-table-column><el-table-columnprop="class"label="班级"align="center"></el-table-column><el-table-columnprop="state_text"label="状态"align="center"></el-table-column><el-table-columnprop="address"label="住址"align="center"></el-table-column><el-table-columnprop="phone"label="电话"align="center"></el-table-column><!-- scope.row表示点击的当前行,包含当前行的所有数据 --><el-table-columnlabel="操作" align="center"><template slot-scope="scope"><el-button type="danger" size="mini" icon="el-icon-delete"@click="del(scope.row)"></el-button></template></el-table-column></el-table><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page.sync="currentPage":page-sizes="[10, 20, 30, 50]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination></div>
</template><script>
import { students, delstudentsbyreqid } from '@/api/api.js'export default {data() {return {tableData: [],currentPage: 1,pageSize: 10,total: 0,formInline: {name: ''}}},computed: {compData() {return this.tableData.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize)}},created() {this.getData()},methods: {onFind() {console.log(this.formInline)this.getData(this.formInline)},onReset() {console.log(this.formInline)this.formInline = {}this.getData(this.formInline)},handleSizeChange(val) {this.pageSize = valthis.currentPage = 1},handleCurrentChange(val) {this.currentPage = val},getData(param) {students(param).then((res) => {console.log(res)if (res.data.status === 200) {this.total = res.data.totalthis.tableData = res.data.datathis.tableData.forEach(item => {//尽量不要修改原始数据,因为原始数据后面可能会用item.sex === 1 ? item.sex_text = "男" : item.sex_text = "女"item.state === 1 ? item.state_text = "已入学" : item.state === 2? item.state_text = "未入学" : item.state_text = "休学中"})}})},del(row) {console.log(row, row.id, row.address)delstudentsbyreqid(row.id).then((res) => {console.log(res)if (res.data.status === 200) {this.$message({message: "删除数据成功", type: "success"})//删除成功后再重新请求一次this.getData()}})},onSubmit() {console.log('submit!')}}}
</script><style>.studentList {.demo-form-inline, .el-form-item {text-align: left;}.el-pagination {text-align: left;margin-top: 20px;}}
</style>

src/components/common/students/WorkList.vue

<!-- 作业列表页面 -->
<template><div class="workList"><el-table :data="tableData" v-loading="loading" border style="width: 100%"><el-table-columnprop="id"label="用户ID"align="center"></el-table-column><el-table-columnprop="userId"label="所属班级"align="center"></el-table-column><el-table-columnprop="title"label="作业名称"align="center"></el-table-column><el-table-columnprop="completed_text"label="完成情况"align="center"></el-table-column></el-table><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="page":page-sizes="[10, 20, 30, 50]":page-size="size"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination></div>
</template><script>
import { getTableData } from '@/utils/table.js'export default {data() {return {tableData: [],total: 0,page: 1,size: 10,loading: true}},created() {//采用后端分页方法getTableData(this, '/api/works', {page: this.page, size: this.size}, ['completed'])},methods: {handleSizeChange(val) {this.size = valthis.page = 1getTableData(this, '/api/works', {page: this.page, size: val}, ['completed'])},handleCurrentChange(val) {this.page = valgetTableData(this, '/api/works', {page: val, size: this.size}, ['completed'])},}}
</script><style lang="scss">.workList {.el-pagination {text-align: left;margin-top: 20px;}}
</style>

src/components/common/students/WorkMent.vue

<!-- 作业管理页面 -->
<template><div class="workMent"><el-table :data="tableData" v-loading="loading" border style="width: 100%"><el-table-columnprop="id"label="用户ID"align="center"></el-table-column><el-table-columnprop="userId"label="所属班级"align="center"></el-table-column><el-table-columnprop="title"label="作业名称"align="center"></el-table-column><el-table-columnprop="completed_text"label="完成情况"align="center"></el-table-column></el-table><!-- 通过传参调用分页子组件 模块化和组件化思想 total url由当前页面传递给子组件Page --><Page :total="total" :url="url" /></div>
</template><script>
import Page from '../Pageing.vue'export default {//注册分页组件Pagecomponents: {Page},data() {return {tableData: [],total: 0,loading: true,url: '/api/works'}}}
</script><style lang="scss">.workMent {.el-pagination {text-align: left;margin-top: 20px;}}
</style>

src/components/common/Breadcrumb.vue

<template><div class="footer"><!-- el-card包裹是为了好看而已  组件中属性名前面:表明该属性的值是动态获取的--><el-card><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item v-for="(item, index) in $route.matched" :key="index">{{item.name}}</el-breadcrumb-item></el-breadcrumb></el-card></div>
</template>

src/components/common/Footer.vue

<template><div class="footer"><el-card> welcome to 2023</el-card></div>
</template><script>export default {data() {return {}}}
</script><style lang='scss'></style>

src/components/common/Header.vue

<template><div class="header"><el-header><div class="title">业务后台管理系统</div><div>{{name}}</div></el-header></div>
</template><script>
import { getToken } from '@/utils/dealtoken.js'
export default {data() {return {name: ""}},created() {this.name = getToken('username')}
}
</script><style lang='scss'>
.header {.el-header {background-color: #409eff;color: #333;text-align: center;line-height: 60px;display: flex;justify-content: space-between;.title {width: 200px;font-size: 24px;}}
}
</style>

src/components/common/Menu.vue

<template><div class="menu"><el-aside width="200px"> <el-menurouterdefault-active="2"class="el-menu-vertical-demo"background-color="#409eff"text-color="#fff"active-text-color="#ffd04b"><template v-for="(item, index) in menus"><el-submenu :index="index + ''" :key="index" v-if="!item.hidden"><template slot="title"><i :class="item.iconClass"></i><span>{{item.name}}</span></template><el-menu-item-group v-for="(child, index) in item.children" :key="index"><el-menu-item :index="child.path"><i :class="item.iconClass"></i>{{child.name}}</el-menu-item></el-menu-item-group></el-submenu></template></el-menu></el-aside>  </div>
</template><script>export default {data() {return {menus: []}},created() {console.log(this.$router.options.routes)this.menus = [...this.$router.options.routes]}}
</script><style lang='scss'>
.menu {.el-aside {height: 100%;.el-menu {height: 100%;.fa {margin-right: 10px;}}//解决左右.el-submenu .el-menu-item {min-width: 0;}}
}
</style>

src/components/common/Pageing.vue (封装的分页组件)

<!-- 分页管理组件封装 -->
<!-- 为了多个页面复用,将路由引入 :url="url" -->
<template><div class="pageMent"><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="page":page-sizes="[10, 20, 30, 50]":page-size="size"layout="total, sizes, prev, pager, next, jumper":total="total":url="url"></el-pagination></div>
</template><script>
import { getTableData } from '@/utils/table.js'export default {//校验外部传入参数,props用来接收父组件传递进来的参数props: {"total": Number,"url": String},data() {return {page: 1,    //当前页size: 10   //每页显示条数}},created() {//console.log("this", this)//采用后端分页方法,this.$parent代表父页面getTableData(this.$parent, this.url, {page: this.page, size: this.size}, ['completed'])},methods: {handleSizeChange(val) {this.size = valthis.page = 1getTableData(this.$parent, this.url, {page: this.page, size: val}, ['completed'])},handleCurrentChange(val) {this.page = valgetTableData(this.$parent, this.url, {page: val, size: this.size}, ['completed'])},}}
</script><style lang="scss">.pageMent {.el-pagination {text-align: left;margin-top: 20px;}}
</style>

src/components/Home.vue

<template><div class="home"><Header /><el-container class="content"><Menu /><el-container><Bread /><el-main><div class="cont"><!-- 添加菜单路由出口 --><router-view></router-view></div></el-main><el-footer><Footer /></el-footer></el-container></el-container></div>
</template><script>
import Menu from "@/components/common/Menu"
import Footer from "./common/Footer.vue"
import Header from "./common/Header.vue"
import Bread from "./common/Breadcrumb.vue"export default {components: {Header,Footer,Menu,Bread},data() {return {}}
}
</script><style lang="scss">.home {width: 100%;height: 100%;.content {position: absolute;width: 100%;top: 60px;bottom: 0;.cont {margin: 20px 0;}}}
//@import url('../assets/css/reset.css')
</style>

src/components/Login.vue

<template><div class="login"><el-card class="box-card"><div slot="header" class="clearfix"><span>业务后台管理系统</span></div><el-form label-width="100px" :model="form" ref="form" :rules='rules'><el-form-item label="用户名" prop='username'><el-input v-model="form.username"></el-input></el-form-item><el-form-item label="密码" prop='password'><el-input type='password' v-model="form.password"></el-input></el-form-item><el-form-item><el-button type='primary' @click="login('form')">登录</el-button></el-form-item></el-form></el-card></div>
</template>/*
原生AJAX和Axios在使用上存在一定的区别。Axios可以支持多种方式,包括浏览器环境、node环境,而AJAX则只能在浏览器环境中使用。
Axios还支持多种请求方式,包括GET、POST、PUT、DELETE等;而AJAX只能支持GET和POST方式发送请求。此外,Axios还可以拦截请求和响应。
*/<script>//登录验证的封装
import {login} from '@/api/api.js'
import {nameRule, passRule} from '../utils/validate.js'
import {setToken} from '@/utils/dealtoken.js'export default {data () {return {form: {username: "",password: ""},rules: {username: [{validator: nameRule, required: true, trigger: "blur"}],password: [{validator: passRule, required: true, trigger: "blur"}]}}},methods: {login(form) {this.$refs[form].validate((valid) => {if (valid) {console.log(this.form)login(this.form).then(res => {if (res.data.status === 200) {setToken('token', res.data.token)setToken('username', res.data.Name)this.$message({message: res.data.msg, type: 'success'})this.$router.push('/home')}})} else {console.error(this.form)}})}}
}
</script><style lang='scss'>.login {width: 100%;height: 100%;position: absolute;//background: #409EFF;background: url('../assets/logo.png') center no-repeat;.el-card {background: #65768557;}.box-card {width: 450px;margin: 200px auto;color: #fff;.el-form .el-form-item_label {color: #fff;}.el-card_header {font-size: 34px;}.el-button {width: 100%;}}}
</style>

src/components/NotFound.vue

<template><div class="notfound"><div class="big">页面不见了!</div><div>首页瞧瞧,点击<router-link to="/">这里</router-link>进入首页.</div></div></template><script>export default {data() {return {};},};</script><style lang='scss'>.notfound {width: 100%;height: 100%;position: absolute;background: #409EFF;background: url('../assets/404page.jpg') center no-repeat;}</style>

src/router/index.js

import Vue from 'vue'
import Home from '@/components/Home'
import VueRouter from 'vue-router'Vue.use(VueRouter)const routes = [{ path: '/', redirect: '/login', hidden: true, component: () => import('@/components/Login') },{ path: '/login', name: 'Login', hidden: true, component: () => import('@/components/Login') },{ path: '/home', name: '学生管理',iconClass: 'fa fa-users',redirect: '/home/student',component: Home,children: [{path: '/home/student',name: '学生列表',iconClass: 'fa fa-list',component: () => import('@/components/common/students/StudentList')},{path: '/home/info',name: '信息列表',iconClass: 'fa fa-list-alt',component: () => import('@/components/common/students/InfoList')},{path: '/home/infoman',name: '信息管理',iconClass: 'fa fa-list-alt',component: () => import('@/components/common/students/InfoLists')},{path: '/home/work',name: '作业列表',iconClass: 'fa fa-list-ul',component: () => import('@/components/common/students/WorkList')},{path: '/home/works',name: '作业管理',iconClass: 'fa fa-th-list',component: () => import('@/components/common/students/WorkMent')}]},{ path: '/data', name: '数据分析',iconClass: 'fa fa-bar-chart',component: Home,children: [{path: '/data/dataview',name: '数据概览',iconClass: 'fa fa-line-chart',component: () => import('@/components/common/dataanalyse/DataView')},{path: '/data/mapview',name: '视图概览',iconClass: 'fa fa-line-chart',component: () => import('@/components/common/dataanalyse/MapView')},{path: '/data/score',name: '分数视图',iconClass: 'fa fa-line-chart',component: () => import('@/components/common/dataanalyse/ScoreMap')},{path: '/data/travel',name: '旅游视图',iconClass: 'fa fa-line-chart',component: () => import('@/components/common/dataanalyse/TravelMap')}]},{ path: '/users', name: '用户中心',iconClass: 'fa fa-user',component: Home,children: [{path: '/users/user',name: '数据概览',iconClass: 'fa fa-user',component: () => import('@/components/common/users/User')}]},{ path: '*', name: 'NotFound',  hidden: true, component: () => import('@/components/NotFound') }
]export default new VueRouter({mode: 'history',routes: routes
})

src/utils/dealtoken.js

// Token的封装 Token存放在localStorage
export function setToken(tokenkey, token) {console.log(tokenkey, token)return localStorage.setItem(tokenkey, token)
}export function getToken(tokenkey) {console.log(tokenkey)return localStorage.getItem(tokenkey)
}export function removeToken(tokenkey) {return localStorage.removeItem(tokenkey)
}

src/utils/table.js

//表格操作封装import { call } from "file-loader"//获取表格数据
export function getData (root, url, params) {root.service.get(url, {params: params || {}}).then(res => {if (res.data.status === 200) {root.tableData = res.data.dataroot.total = res.data.total}}).catch(err => {throw err})
}//新增或修改表格数据
export function changeInfo (root, method, url, form, callback, callurl) {root.service[method](url, form).then(res => {if (res.data.status === 200) {callback(root, callurl)root.dialogFormVisible = falseroot.$refs['form'].resetFields()root.$message({message: res.data.msg, type: "success"})}}).catch(err => {throw err})
}//删除方法封装
export function delData (root, url, id, callback, callurl) {root.$alert("确定要删除吗?", "提示", {confirmButtonText: '确定',callback: () => {root.service.get(url + id).then(res => {if (res.data.status === 200) {callback(root, callurl)root.$message({message: res.data.msg, type: "success"})}})}}).catch(err => {throw err})
}//作业列表获取数据封装
export function getTableData (root, url, params, arr) {root.service.get(url, {params: params || {}}).then(res => {if (res.data.status === 200) {root.tableData = res.data.dataroot.total = res.data.totalroot.tableData.map(item => {arr.map(aItem => [item[aItem] ? item[aItem + '_text'] = '是' :  item[aItem + '_text'] = '否'])})root.loading = false}}).catch(err => {throw err})
}

src/utils/validate.js

//用户名匹配
export function nameRule (rule, value, callback) {let reg = /(^[a-zA-Z0-9]{4,10}$)/;if (value === "") {callback(new Error("请输入用户名"));} else if (!reg.test(value)) {callback(new Error("请输入4-10用户名"));} else {callback();}
}//密码匹配
export function passRule (rule, value, callback) {let pass = /^\S*(?=\S{6,12})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*? ])\S*$/;if (value === "") {callback(new Error("请输入密码"));} else if (!pass.test(value)) {callback(new Error("请输入6-12位密码需要包含大小写和数字及特殊字符"));} else {callback();}
}

src/App.vue

<template>
<div>
<router-view></router-view>
</div>
</template>

src/main.js


import Vue from 'vue'
import App from './App'
import 'font-awesome/css/font-awesome.min.css'
//import axios from 'axios'
import router from './router'
import service from './service'// 挂载到原型就可以全局使用
//Vue.prototype.axios = axios
Vue.prototype.service = service
//Vue.config.productionTip = falseimport ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)new Vue({router,render: h => h(App)
}).$mount('#myapp')

src/service.js

import axios from "axios";
import { getToken } from "@/utils/dealtoken.js"
import { Promise } from 'core-js'
import { Message } from "element-ui";// axios二次封装const service = axios.create({// baseURL还可以使用代理baseURL: 'http://127.0.0.1:8181', timeout: 3000
})// 请求拦截器
service.interceptors.request.use((config) => {//对请求做一些额外处理config.headers['token'] = getToken('token')config.headers['username'] = getToken('username')return config
}, (error) => {return Promise.reject(error)
})// 响应拦截器
service.interceptors.response.use((response) => {//对响应做一些处理let {status, msg} = response.dataif (status != 200) {Message({message: msg || 'error', type: 'warning'})}console.log(response, status, msg)return response
}, (error) => {return Promise.reject(error)
})export default service

index.html

<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>demo</title></head><body><div id="myapp"></div><!-- built files will be auto injected --></body>
</html>

3.后端代码

3.1 代码结构

3.2 代码实现

controller/login.go

package controllerimport ("encoding/json""fmt""io/ioutil""net/http""path/filepath""github.com/gin-gonic/gin"
)// post  http://127.0.0.1:8181/login
// axios.post 和 post json处理
func LoginPost(ctx *gin.Context) {fmt.Println("ctx", ctx)fmt.Println("ctx.Request", ctx.Request)version := ctx.DefaultQuery("version", "V1.0.0.1")//前端使用axios直接传递form时,axios会默认使用json,必须使用下面方式获取json数据,解析后再使用data, _ := ioutil.ReadAll(ctx.Request.Body)fmt.Println("data", data)type UserInfo struct {Username stringPassword string}var u UserInfoerr := json.Unmarshal(data, &u)if err != nil {fmt.Println(err)}username := u.Usernamepassword := u.Passwordfmt.Println("login info:: ", version, username, password)if username == "123456" && password == "1234abcdE@" {ctx.JSON(http.StatusOK, gin.H{"status":   200,"Name":     username,"Password": password,"msg":      "登录成功","token":    "abcd1234ABCD",})} else {ctx.JSON(http.StatusOK, gin.H{"status":   -1,"Name":     username,"Password": password,"msg":      "用户名或密码错误",})}
}// http://127.0.0.1:8181/formlogin
// form表单提交处理 application/x-www-form-urlencoded 或者 application/form-data
func FormLoginPost(ctx *gin.Context) {fmt.Println("ctx", ctx)fmt.Println("ctx.Request", ctx.Request)username := ctx.PostForm("username")password := ctx.PostForm("password")fmt.Println("FormLoginPost :: ", username, password)if username == "123456" && password == "1234abcdE@" {ctx.JSON(http.StatusOK, gin.H{"status":   200,"Name":     username,"Password": password,"msg":      "登录成功","token":    "abcd1234ABCD",})} else {ctx.JSON(http.StatusOK, gin.H{"status":   -1,"Name":     username,"Password": password,"msg":      "用户名或密码错误",})}
}// form表单提交文件上传处理 multipart/form-data
func UploadFile(ctx *gin.Context) {file, _ := ctx.FormFile("uploadfile")fmt.Println(file.Filename)file_path := "upload/" + filepath.Base(file.Filename)fmt.Println(file_path)ctx.SaveUploadedFile(file, file_path)ctx.String(http.StatusOK, "上传成功")
}

controller/student.go

package controllerimport ("encoding/json""fmt""io/ioutil""net/http""github.com/gin-gonic/gin"
)/*
type User struct {Name string `json:"name"`Age int `json:"age"`
}user := User{"Tom", 18}
jsonData, err := json.Marshal(user)
if err != nil {
c.AbortWithError(500, err)
}
c.Data(200, "application/json", jsonData)
*//*
在 Go 语言中,可以使用内置的 copy 函数来将数组转换为切片。
// 将 arr 转换为切片
arr := [3]int{1, 2, 3}
sl := make([]int, len(arr))
copy(sl, arr[:])// 将切片转换为数组
var arr2 [3]int
copy(arr2[:], sl)
*/var students = []map[string]interface{}{{"id": 1, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 2, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 3, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 4, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 5, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 6, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 7, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 8, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 9, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 10, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 11, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 12, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 13, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 14, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 15, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 16, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 17, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 18, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 19, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 20, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 21, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 22, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 23, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 24, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 25, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 26, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 27, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 28, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 29, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 30, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 31, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 32, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 33, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 34, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 35, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 36, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 37, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 38, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 39, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 40, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 41, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 42, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 43, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 44, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 45, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 46, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 47, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 48, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},{"id": 47, "name": "张三", "age": 10, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "北京市 朝阳区", "phone": "18818812345"},{"id": 50, "name": "李四", "age": 11, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 2, "address": "天津市 朝阳区", "phone": "18818812345"},{"id": 51, "name": "王五", "age": 12, "sex": 2, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 3, "address": "上海市 朝阳区", "phone": "18818812345"},{"id": 52, "name": "赵六", "age": 9, "sex": 1, "time": "2023-08-05", "father": "爸爸", "mother": "妈妈", "number": 2, "class": 2, "state": 1, "address": "重庆市 朝阳区", "phone": "18818812345"},
}// get  http://127.0.0.1:8181/api/students
func GetStudentList(ctx *gin.Context) {name := ctx.Query("name")fmt.Println("name :: ", name)//sex: 1 -> 男 2 -> 女//state: 1:已入学 2:未入学 3:休学中selstudents := []map[string]interface{}{}if len(name) != 0 {for index, value := range students {if value["name"] == name {selstudents = append(selstudents, students[index])}}} else {for index, _ := range students {selstudents = append(selstudents, students[index])}}/*selstudents := list.New()if len(name) != 0 {for _, value := range students {if value["name"] == name {selstudents.PushBack(value)}}} else {for _, value := range students {selstudents.PushBack(value)}}selstudents.Len()*/ctx.JSON(http.StatusOK, gin.H{"status": 200,"msg":    "获取学生信息成功","data":   selstudents,"total":  len(selstudents),})
}// GET请求 http://127.0.0.1:8181/api/students/del?id=1
func DelStudent(ctx *gin.Context) {id := ctx.Query("id")fmt.Println("del student id :: ", id)ctx.JSON(http.StatusOK, gin.H{"status": 200,"msg":    "删除学生信息成功","id":     id,})
}// GET请求 http://127.0.0.1:8181/api/students/del/1
func DelStudentByReq(ctx *gin.Context) {// 使用Param获取URL参数id := ctx.Param("id")// 返回请求参数ctx.JSON(200, gin.H{"status": 200,"msg":    "删除学生信息成功","id":     id,})
}type UserInfo struct {Name    string //`json:"name"`Age     string //`json:"age"`Sex     string //`json:"sex"`Father  string //`json:"father"`Mother  string //`json:"mother"`Time    string //`json:"time"`Address string //`json:"address"`Phone   string //`json:"phone"`
}func AddStudent(ctx *gin.Context) {data, _ := ioutil.ReadAll(ctx.Request.Body)var u UserInfoerr := json.Unmarshal(data, &u)if err != nil {fmt.Println(err)}fmt.Println("AddStudent :: ", u.Name, u.Age, u.Sex, u.Father, u.Mother, u.Time, u.Address, u.Phone)ctx.JSON(http.StatusOK, gin.H{"status": 200,"name":   u.Name,"msg":    "增加成功",})}// get  http://127.0.0.1:8181/api/getinfo
func GetInfo(ctx *gin.Context) {name := ctx.Query("name")fmt.Println("name :: ", name)//sex: 1 -> 男 2 -> 女//state: 1:已入学 2:未入学 3:休学中selstudents := []map[string]interface{}{}if len(name) != 0 {for index, value := range students {if value["name"] == name {selstudents = append(selstudents, students[index])}}} else {for index, _ := range students {selstudents = append(selstudents, students[index])}}ctx.JSON(http.StatusOK, gin.H{"status": 200,"msg":    "获取学生信息成功","data":   selstudents,"total":  len(selstudents),})
}func UpdateStudent(ctx *gin.Context) {data, _ := ioutil.ReadAll(ctx.Request.Body)var u UserInfoerr := json.Unmarshal(data, &u)if err != nil {fmt.Println(err)}fmt.Println("UpdateStudent :: ", u.Name, u.Age, u.Sex, u.Father, u.Mother, u.Time, u.Address, u.Phone)ctx.JSON(http.StatusOK, gin.H{"status": 200,"name":   u.Name,"msg":    "修改成功",})}// GET请求 http://127.0.0.1:8181/api/info/del/1
func DelIfo(ctx *gin.Context) {// 使用Param获取URL参数id := ctx.Param("id")// 返回请求参数ctx.JSON(200, gin.H{"status": 200,"msg":    "删除信息成功","id":     id,})
}var works = []map[string]interface{}{{"id": 1, "userId": 110, "title": "JS", "completed": true},{"id": 2, "userId": 111, "title": "C++", "completed": false},{"id": 3, "userId": 112, "title": "Java", "completed": true},{"id": 4, "userId": 113, "title": "Golang", "completed": false},{"id": 1, "userId": 110, "title": "JS", "completed": true},{"id": 2, "userId": 111, "title": "C++", "completed": false},{"id": 3, "userId": 112, "title": "Java", "completed": true},{"id": 4, "userId": 113, "title": "Golang", "completed": false},{"id": 1, "userId": 110, "title": "JS", "completed": true},{"id": 2, "userId": 111, "title": "C++", "completed": false},{"id": 3, "userId": 112, "title": "Java", "completed": true},{"id": 4, "userId": 113, "title": "Golang", "completed": false},{"id": 1, "userId": 110, "title": "JS", "completed": true},{"id": 2, "userId": 111, "title": "C++", "completed": false},{"id": 3, "userId": 112, "title": "Java", "completed": true},{"id": 4, "userId": 113, "title": "Golang", "completed": false},{"id": 1, "userId": 110, "title": "JS", "completed": true},{"id": 2, "userId": 111, "title": "C++", "completed": false},{"id": 3, "userId": 112, "title": "Java", "completed": true},{"id": 4, "userId": 113, "title": "Golang", "completed": false},{"id": 1, "userId": 110, "title": "JS", "completed": true},{"id": 2, "userId": 111, "title": "C++", "completed": false},{"id": 3, "userId": 112, "title": "Java", "completed": true},{"id": 4, "userId": 113, "title": "Golang", "completed": false},{"id": 1, "userId": 110, "title": "JS", "completed": true},{"id": 2, "userId": 111, "title": "C++", "completed": false},{"id": 3, "userId": 112, "title": "Java", "completed": true},{"id": 4, "userId": 113, "title": "Golang", "completed": false},
}// get请求,支持分页查询
func Works(ctx *gin.Context) {page := ctx.Query("page")size := ctx.Query("size")fmt.Println("Works :: ", page, size)//数据分页处理ctx.JSON(200, gin.H{"status": 200,"msg":    "获取作业成功","data":   works,"total":  len(works),})
}

server.go

package mainimport ("main/controller""net/http""github.com/gin-contrib/cors""github.com/gin-gonic/gin"
)/*
// 错误: server.go:4:2: package main/controller is not in GOROOT (/home/tiger/go/go/src/main/controller)
go mod init main//错误: server.go:7:2: no required module provides package github.com/gin-gonic/gin; to add it:
go get github.com/gin-gonic/gin//处理跨域框架
go get github.com/gin-contrib/cors
*//*
当客户端(尤其是基于 Web 的客户端)想要访问 API 时,服务器会决定允许哪些客户端发送请求。这是通过使用称为 CORS 来完成的,它代表跨源资源共享。
跨域资源共享 (CORS) 是一种机制,允许从提供第一个资源的域之外的另一个域请求网页上的受限资源。
*/func CrosHandler() gin.HandlerFunc {return func(context *gin.Context) {context.Writer.Header().Set("Access-Control-Allow-Origin", "*")context.Header("Access-Control-Allow-Origin", "*") // 设置允许访问所有域context.Header("Access-Control-Allow-Methods", "POST,GET,OPTIONS,PUT,DELETE,UPDATE")context.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma,token,openid,opentoken")context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar")context.Header("Access-Control-Max-Age", "172800")context.Header("Access-Control-Allow-Credentials", "true")context.Set("content-type", "application/json") //设置返回格式是json//处理请求context.Next()}
}// http://127.0.0.1:8181/ping
// http://127.0.0.1:8181/index
func main() {r := gin.Default()// 设置全局跨域访问//r.Use(CrosHandler())//cors处理跨域corsConfig := cors.DefaultConfig()corsConfig.AllowCredentials = truecorsConfig.AllowHeaders = []string{"content-type", "Origin", "token", "username"}corsConfig.AllowOrigins = []string{"http://localhost:8080", "http://localhost:8081"}corsConfig.AllowMethods = []string{"POST", "GET", "OPTIONS", "PUT", "DELETE", "UPDATE"}r.Use(cors.New(corsConfig))//r.Use(cors.Default())// 返回一个json数据r.GET("/ping", func(c *gin.Context) {c.JSON(200, gin.H{"message": "pong","num":     888,})})// 返回一个html页面r.LoadHTMLGlob("templates/*")r.GET("/index", func(c *gin.Context) {c.HTML(http.StatusOK, "index.html", nil)})r.POST("/login", controller.LoginPost)r.POST("/formlogin", controller.FormLoginPost)r.POST("/upload", controller.UploadFile)r.GET("/api/students", controller.GetStudentList)r.GET("/api/students/del", controller.DelStudent)r.GET("/api/students/del/:id", controller.DelStudentByReq)r.POST("/api/info", controller.AddStudent)r.GET("/api/getinfo", controller.GetInfo)r.POST("api/updateinfo", controller.UpdateStudent)r.GET("/api/info/del/:id", controller.DelIfo)r.GET("api/works", controller.Works)//r.Run()  // <===> r.Run(":8080")  监听并在 0.0.0.0:8080 上启动服务r.Run(":8181")
}

4.其他

4.1 vscode快速编写正则表达式

安装any-rule插件

ctrl shift p 调出正则表达式选择

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/78188.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HDFS介绍

目录 ​编辑 一、HDFS基础 1.1 概述 1.2 HDFS的设计目标 1.2.1 硬件故障 1.2.2 流式数据访问 1.2.3 超大数据集 1.2.4 简单的一致性模型 1.2.5 移动计算而不是移动数据 1.2.6 跨异构硬件和软件平台的可移植性 1.3 基础概念 1.3.1 块&#xff08;Block&#xff09; 1.3.2 复制…

Spring集成Junit

目录 1、简介 2、Junit存在的问题 3、回顾Junit注解 4、集成步骤 4.1、导入坐标 4.2、Runwith 4.3、ContextConfiguration 4.4、Autowired 4.5、Test 4.6、代码 5、补充说明 5.1、Runwith 5.2、BlockJUnit4ClassRunner 5.3、没有配置Runwith ⭐作者介绍&#xff1…

DROP USER c##xyt CASCADE > ORA-01940: 无法删除当前连接的用户

多创建了一个用户&#xff0c;想要给它删除掉 一 上执行过程&#xff0c;确实删除成功了 Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing optionsSQL> DR…

前端必知:38.对BFC的认识与理解

目录 什么是BFC BFC的特点 BFC 的布局规则 创建一个BFC的方法 什么是BFC BFC&#xff08;Block Formatting Context&#xff09;是 CSS 中的一个概念&#xff0c;用于描述页面中块级元素如何布局和相互影响的规则和上下文。BFC 是页面渲染时创建的一个独立的布局环境&…

OPENCV C++(一) 二进制和灰度原理 处理每个像素点值的方法

#include <opencv2/opencv.hpp> using namespace std; using namespace cv;必须包含的头文件&#xff01; 才能开始编写代码 读取相片 一般来说加个保护程序 不至于出error和卡死 Mat image imread("test.webp"); //存放自己图像的路径 if (image.empty()){p…

深入理解缓存 TLB 原理

今天分享一篇TLB的好文章&#xff0c;希望大家夯实基本功&#xff0c;让我们一起深入理解计算机系统。 TLB 是 translation lookaside buffer 的简称。首先&#xff0c;我们知道 MMU 的作用是把虚拟地址转换成物理地址。 MMU工作原理 虚拟地址和物理地址的映射关系存储在页表…

mysql二进制方式升级8.0.34

一、概述 mysql8.0.33 存在如下高危漏洞&#xff0c;需要通过升级版本修复漏洞 Oracle MySQL Cluster 安全漏洞(CVE-2023-0361) mysql/8.0.33 Apache Skywalking <8.3 SQL注入漏洞 二、查看mysql版本及安装包信息 [rootlocalhost mysql]# mysql -V mysql Ver 8.0.33 fo…

Cilium系列-13-启用XDP加速及Cilium性能调优总结

系列文章 Cilium 系列文章 前言 将 Kubernetes 的 CNI 从其他组件切换为 Cilium, 已经可以有效地提升网络的性能. 但是通过对 Cilium 不同模式的切换/功能的启用, 可以进一步提升 Cilium 的网络性能. 具体调优项包括不限于: 启用本地路由(Native Routing)完全替换 KubeProx…

express学习笔记7 - docker跟mysql篇

安装Docker和Navicat Docker 进官⽹https://docs.docker.com/get-docker/ 选择机型安装即可。 Navicat&#xff08;也可以在网上找个破解版本&#xff09; 进官⽹https://www.navicat.com/en/products/navicat-premium 安装完之后连接新建⼀个数据库连接 然后再⾥⾯新建⼀个数…

zookeeper的部署

一 先下载zookeeper 二 解压包 三 修改配置文件 四 把配好文件传到其他的节点上面 五 在每个节点的dataDir指定的目录下创建一个 myid 的文件 六 配置zook的启动脚本 七 设置开机自启 八 分别启动 九查看当前状态service zookeeper status 十 总结 一 先下载zookeeper …

Zebec 创始人 Sam 对话社区,“Zebec 生态发展”主题 AMA 回顾总结

近日&#xff0c;Zebec Protocol 创始人 Sam 作为嘉宾&#xff0c;与社区进行了以“Zebec 生态发展”为主题的 AMA 对话。Sam 在线上访谈上对 Zebec 路线图、Zebec 质押、NautChain通证进行了解读&#xff0c;并对 Zebec 的进展、生态建设的愿景进行了展望。本文将对本次 AMA 进…

PtahDAO:全球首个DAO治理资产信托计划的金融平台

金融科技是当今世界最具创新力和影响力的领域之一&#xff0c;区块链技术作为金融科技的核心驱动力&#xff0c;正在颠覆传统的金融模式&#xff0c;为全球用户提供更加普惠、便捷、安全的金融服务。在这个变革的浪潮中&#xff0c;PtahDAO&#xff08;普塔道&#xff09;作为全…

【cluster_block_exception】写操作elasticsearch索引报错

【cluster_block_exception】操作elasticsearch索引b报错 背景导致原因&#xff1a;解决方法&#xff1a; 背景 今天线上elk的数据太多&#xff0c;服务器的空间不足了。所以打算删除一些没用用的数据。我是用下面的request&#xff1a; POST /{index_name}/_delete_by_query…

==和equals():比较对象等不等?

引言&#xff1a; 在编程中&#xff0c;我们常常需要判断两个对象是否相等。而在Java中&#xff0c;有两种常用的方法&#xff1a;使用""运算符和调用equals()方法。这两个方法有什么区别呢&#xff1f;它们又有哪些有趣的应用呢&#xff1f;让我们一起来探索一下吧&…

怎么维护好自己的电脑

你的电脑已经成为你工作、学习、娱乐的最佳工具之一&#xff0c;但是如果你不做好电脑维护工作&#xff0c;就可能面临着电脑变慢、蓝屏、崩溃等问题。在这篇文章中&#xff0c;我们将介绍10个电脑维护步骤&#xff0c;让你的电脑更加稳定&#xff01; 为什么需要电脑维护&…

数据结构:双向链表的实现(C实现)

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》 文章目录 前言 一、实现思路1.节点的结构(ListNode)2.新节点的创建(BuyListNode)3.头结点的创建(ListCreate)4.双向链表的销毁(ListDestroy)5.双向链表的打印(ListPrint)6.双向链表的尾插(ListPu…

解决单节点es索引yellow

现象 单节点的es&#xff0c;自动创建索引后&#xff0c;默认副本个数为1&#xff0c;索引状态为yellow 临时解决 修改副本个数为0 永久解决 方法1、修改elasticsearch.yml文件&#xff0c;添加配置并重启es number_of_replicas&#xff1a;副本分片数&#xff0c;默认…

SpringBoot之logback-spring.xml详细配置

《logback官网》 各种指导文件&#xff0c;有空自己去看&#xff0c;比如&#xff1a;我们需要调整的是布局&#xff0c;直接看Layouts。 pom.xml <!-- 环境配置 --><profiles><profile><id>dev</id><properties><spring.profiles.a…

K8s operator从0到1实战

Operator基础知识 Kubernetes Operator是一种用于管理和扩展Kubernetes应用程序的模式和工具。它们是一种自定义的Kubernetes控制器&#xff0c;可以根据特定的应用程序需求和业务逻辑扩展Kubernetes功能。 Kubernetes Operator基于Kubernetes的控制器模式&#xff0c;通过自…

使用webpack建立React+TS项目

之前写过类似的文章&#xff0c;这次看到一本新书里也介绍了这个知识点&#xff0c;故尝试之。 Refer: 《Learn React With TypeScript - A Beginners Guide To Reactive Web Development With React 18 and TypeScript》chapter3 Creating a project with webpack 1.先建立一…