《程序猿入职必会(4) · Vue 完成 CURD 案例 》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

文章目录

    • 写在前面的话
    • 教师信息管理 CURD
      • 前文回顾
      • 日期格式化
      • 前端代码生成
      • 代码修修补补
    • 前端知识拓展
      • 图形化方式创建 Vue
      • 整合路由 Vue-Router
    • 总结陈词

CSDN.gif

写在前面的话

本系列博文已连载到第三回,通过前三回博文,我们已完成了前后端基础服务的搭建,也完成后端的完整接口清单,前端还差一些,本篇博文,把前端功能补充完整,让它像那么回事。
本篇博文,还有几个目标要完成:

  • 回顾一下之前三篇文章,将一些知识点补充一下;
  • 针对需求内容,把前端服务的CURD功能丰富起来;
  • 对部分前端细节不到位的地方进行修复,同时分享相关经验;

加油,程序猿,保持住Tempo,开干,玩的就是真实!

关联文章:
《程序猿入职必会(1) · 搭建拥有数据交互的 SpringBoot 》
《程序猿入职必会(2) · 搭建具备前端展示效果的 Vue》
《程序猿入职必会(3) · SpringBoot 各层功能完善 》
《程序猿入职必会(4) · Vue 完成 CURD 案例 》
《程序猿入职必会(5) · CURD 页面细节规范 》
《程序猿入职必会(6) · 返回结果统一封装》


教师信息管理 CURD

Tips:一直说CURD、CURD的,行业内的默认术语,如果有小伙伴不知道这是什么,那大概是代表创建(Create)、更新(Update)、读取(Read)和删除(Delete)操作的集合,可以指代某个实体表对应的维护页面,也是程序猿最基础的拧螺丝工作。

前文回顾

先回顾一下之前第二篇的结尾,我们引入 ElementUI 后,实现的效果如下。
效果还可以,不过只是功能的冰山一角。
image.png
不对,登记时间怎么是这个鬼样子?先给它修正,不然很别扭。

日期格式化

实现日期格式化可以后端来,也可以前端。

后端实现效果
Step1、引入 fastjson 依赖

<fastjson.version>2.0.33</fastjson.version><!-- JSON处理 -->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version>
</dependency>

Step2、实体类添加注释

@JSONField(format = "yyyy-MM-dd HH:mm")
private java.util.Date createdTime;

Step3、前端正常展示

<span>{{ scope.row.createdTime}}</span>

效果如下:
image.png

前端实现效果
使用vue的管道符实现,代码如下:

<span>{{ scope.row.createdTime | timeFilter}}</span>timeFilter(time) {// 这边将字符串进行日期转换
}

前端代码生成

这里先使用代码生成器生成教师实体对应的前端基础页面和接口,不然一个个写是挺耗时的,也比较基础。
企业实际开发中,这部分代码通常也是代码生成或者CV其他代码,再进行调整。
先来一段完整的Vue:

<template><div class="app-container"><!-- 表头 查询与新增 --><el-row><el-col :span="24"><div class="filter-container"><el-input placeholder="关键词过滤" v-model="listQuery.query" style="width: 200px;" class="filter-item"@keyup.enter.native="handleFilter"/><el-select v-model="listQuery.validFlag" placeholder="有效标志" clearable class="filter-item" style="width: 150px"@change="handleFilter"><el-option v-for="(value, key) in statusOptions" :key="key" :label="value" :value="key"/></el-select><el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">搜索</el-button><el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-circle-plus-outline"@click="handleCreate">新增</el-button></div></el-col></el-row><!-- 表格list --><el-row><el-col :span="24" :gutter="24"><el-table:row-class-name="rowClassName"v-loading="listLoading":key="tableKey":data="list"element-loading-text="Loading"borderfit:height="tableHeight"style="width: 100%;"highlight-current-row><el-table-column align="center" label="序号" width="80"><template slot-scope="scope">{{ scope.$index }}</template></el-table-column><el-table-column show-overflow-tooltip label="教师编号" show-overflow-tooltip min-width="10%" align="center"><template slot-scope="scope">{{ scope.row.teaCode }}</template></el-table-column><el-table-column show-overflow-tooltip label="教师名称" show-overflow-tooltip min-width="10%" align="center"><template slot-scope="scope">{{ scope.row.teaName }}</template></el-table-column><el-table-column show-overflow-tooltip label="教师头像" show-overflow-tooltip min-width="10%" align="center"><template slot-scope="scope">{{ scope.row.teaImg }}</template></el-table-column><el-table-column show-overflow-tooltip label="教师电话" show-overflow-tooltip min-width="10%" align="center"><template slot-scope="scope">{{ scope.row.teaPhone }}</template></el-table-column><el-table-column show-overflow-tooltip label="教师学科" show-overflow-tooltip min-width="10%" align="center"><template slot-scope="scope">{{ scope.row.stuItem }}</template></el-table-column><el-table-column show-overflow-tooltip label="教师身份" show-overflow-tooltip min-width="10%" align="center"><template slot-scope="scope">{{ scope.row.teaType }}</template></el-table-column><el-table-column show-overflow-tooltip label="教师配置" show-overflow-tooltip min-width="10%" align="center"><template slot-scope="scope">{{ scope.row.teaConfig }}</template></el-table-column><el-table-column show-overflow-tooltip label="排序号" show-overflow-tooltip min-width="10%" align="center"><template slot-scope="scope">{{ scope.row.sortNo }}</template></el-table-column><el-table-column show-overflow-tooltip class-name="status-col" label="创建时间" min-width="20%" align="center"><template slot-scope="scope"><i class="el-icon-time"/><span>{{ scope.row.createdTime }}</span></template></el-table-column><el-table-column show-overflow-tooltip class-name="status-col" label="修改时间" min-width="20%" align="center"><template slot-scope="scope"><i class="el-icon-time"/><span>{{ scope.row.modifiedTime }}</span></template></el-table-column><el-table-column show-overflow-tooltip class-name="status-col" label="有效标志" min-width="10%" align="center"><template slot-scope="scope"><el-tag :type="scope.row.validFlag | statusFilter">{{ scope.row.validFlag | validFilter }}</el-tag></template></el-table-column><el-table-column label="操作" align="center" width="180" class-name="small-padding fixed-width"><template slot-scope="scope"><el-button size="mini" type="primary" @click="handleUpdate(scope.row)">编辑</el-button><el-button size="mini" type="danger" @click="handleDelete(scope.row)">删除</el-button></template></el-table-column></el-table></el-col></el-row><!-- 分页控件 --><pagination v-show="total>0" :total="total":page.sync="listQuery.pageNum":limit.sync="listQuery.pageSize"layout="total, sizes, prev, pager, next"style="float:right;"@pagination="fetchData"/><!-- 编辑弹窗 --><el-dialog:close-on-click-modal="false":title="textMap[dialogStatus]":visible.sync="dialogFormVisible"><el-formref="dataForm":rules="rules":model="temp"label-position="right"label-width="100px"style=""><el-row :gutter="20"><el-col :span="12"><el-form-item label="教师编号" label-width="105px" prop="teaCode"><el-input v-model="temp.teaCode" :disabled="dialogStatus === 'update'"/></el-form-item></el-col></el-row><el-row :gutter="20"><el-col :span="12"><el-form-item label="教师名称" label-width="105px" prop="teaName"><el-input v-model="temp.teaName"/></el-form-item></el-col><el-col :span="12"><el-form-item label="教师头像" label-width="105px" prop="teaImg"><el-input v-model="temp.teaImg"/></el-form-item></el-col></el-row><el-row :gutter="20"><el-col :span="12"><el-form-item label="教师电话" label-width="105px" prop="teaPhone"><el-input v-model="temp.teaPhone"/></el-form-item></el-col><el-col :span="12"><el-form-item label="教师学科" label-width="105px" prop="stuItem"><el-input v-model="temp.stuItem"/></el-form-item></el-col></el-row><el-row :gutter="20"><el-col :span="12"><el-form-item label="教师身份" label-width="105px" prop="teaType"><el-input v-model="temp.teaType"/></el-form-item></el-col><el-col :span="12"><el-form-item label="教师配置" label-width="105px" prop="teaConfig"><el-input v-model="temp.teaConfig"/></el-form-item></el-col></el-row><el-row :gutter="20"><el-col :span="12"><el-form-item label="排序号" label-width="105px" prop="sortNo"><el-input v-model.number="temp.sortNo"/></el-form-item></el-col><el-col :span="12"></el-col></el-row><el-row :gutter="20"><el-col :span="12"></el-col><el-col :span="12"><el-form-item label="有效标志" label-width="105px"><el-switchv-model="validSwitch"active-color="#13ce66"inactive-color="#ff4949"></el-switch></el-form-item></el-col></el-row></el-form><div slot="footer" class="dialog-footer"><el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">确认</el-button><el-button @click="dialogFormVisible = false">取消</el-button></div></el-dialog></div>
</template><script>
import ZyTeacherInfoApi from '@/api/study/ZyTeacherInfoApi'
import waves from '@/directive/waves' // Waves directive
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
export default {directives: { waves },components: { Pagination },filters: {statusFilter(status) {const statusMap = {1: 'success',2: 'blue',3: 'warning',4: 'info',0: 'danger'}return statusMap[status]},commonFilter(status, data) {if (status) {return data[status].text || data[status]} else {return ''}},validFilter(status) {const statusMap = {1: '有效',0: '作废'}return statusMap[status]},timeFilter(time) {if (time) {return new Date(time).Format('yyyy-MM-dd hh:mm:ss')} else {return ''}}},data() {return {tableKey: 0,//表格key值list: null, //表格对象listLoading: true, //表格加载框total: 0, //分页总数tableHeight: window.innerHeight - 220, //表格高度listQuery: { //表格查询对象pageNum: 1,pageSize: 10,query: '',validFlag: undefined,teaCode: ''},temp: {}, //编辑框临时变量statusOptions: { //有效无效下拉框'1': '有效','0': '作废'},dialogFormVisible: false, //编辑框显示dialogStatus: '', //编辑框更新插入状态textMap: { //编辑框标题update: '编辑',create: '创建'},rules: { //编辑框校验规则teaCode: [{ required: true, message: '请输入教师编号', trigger: 'change' }],teaName: [{ required: true, message: '请输入教师名称', trigger: 'change' }],teaImg: [{ required: true, message: '请输入教师头像', trigger: 'change' }],teaPhone: [{ required: true, message: '请输入教师电话', trigger: 'change' }],stuItem: [{ required: true, message: '请输入教师学科', trigger: 'change' }],teaType: [{ required: true, message: '请输入教师身份', trigger: 'change' }],teaConfig: [{ required: true, message: '请输入教师配置', trigger: 'change' }],sortNo: [{type: 'number', required: false, message: '排序号必须为整数值', transform(value) {if (value === '' || value === null) {return 0}if (_.isInteger(value)) {return value} else {return false}}}],validFlag: [{ required: true, message: '请输入有效标志', trigger: 'change' }]}}},computed: {validSwitch: {// getterget: function() {return this.temp.validFlag === '1'},// setterset: function(newValue) {if (newValue) {this.temp.validFlag = '1'} else {this.temp.validFlag = '0'}}}},created() {this.fetchData()},methods: {/*** 获取表格数据*/fetchData() {let that = thisthis.listLoading = truethis.$http.all([ZyTeacherInfoApi.getPage(this.listQuery)]).then(this.$http.spread(function(perms) {that.list = perms.rowsthat.total = perms.totalthat.listLoading = false}))},/*** 新增弹窗*/handleCreate() {this.resetTemp()this.dialogStatus = 'create'this.dialogFormVisible = truethis.$nextTick(() => {this.$refs['dataForm'].clearValidate()})},/*** 清空弹窗内容*/resetTemp() {this.temp = {teaCode: '',teaName: '',teaImg: '',teaPhone: '',stuItem: '',teaType: '',teaConfig: '',sortNo: '',createdTime: '',modifiedTime: '',validFlag: '1'}},/*** 确定新增*/createData() {let that = thisthis.$refs['dataForm'].validate((valid) => {if (valid) {ZyTeacherInfoApi.insert(this.temp).then(() => {this.dialogFormVisible = falsethis.$notify({title: '成功',message: '创建成功',type: 'success',duration: 1000,onClose() {that.fetchData()}})})}})},/*** 编辑弹窗*/handleUpdate(row) {this.temp = Object.assign({}, row)this.dialogStatus = 'update'this.dialogFormVisible = truethis.$nextTick(() => {this.$refs['dataForm'].clearValidate()})},/*** 确认编辑*/updateData() {let that = thisthis.$refs['dataForm'].validate((valid) => {if (valid) {const tempData = Object.assign({}, this.temp)ZyTeacherInfoApi.update(tempData).then(() => {this.dialogFormVisible = falsethis.$notify({title: '成功',message: '更新成功',type: 'success',duration: 1000,onClose() {that.fetchData()}})})}})},/*** 删除操作*/handleDelete(row) {let that = thisZyTeacherInfoApi.remove({ teaCode: row.teaCode }).then(() => {this.$notify({title: '成功',message: '删除成功',type: 'success',duration: 1000,onClose() {that.fetchData()}})})},/*** 搜索过滤*/handleFilter() {this.listQuery.pageNum = 1this.fetchData()},rowClassName({ rowIndex }) {return rowIndex % 2 === 0 ? 'warning-row' : 'success-row'}}
}
</script><style>
.el-table .warning-row {background-color: #fff7e6;
}.el-table .success-row {background-color: #f0f9eb;
}
</style>

再来一段完整的api:

import request from '@/utils/request'export default {getList(params) {return request({url: '/zyTeacherInfo/', method: 'get', params})},get(params) {return request({url: '/zyTeacherInfo/' + params.teaCode, method: 'get', params})},getPage(params) {return request({url: '/zyTeacherInfo/page', method: 'get', params})},update(params) {return request({url: '/zyTeacherInfo/update', method: 'post', params})},insert(params) {return request({url: '/zyTeacherInfo/insert', method: 'post', params})},remove(params) {return request({url: '/zyTeacherInfo/delete', method: 'post', params})}
}

接着配一下路由,router.js

Tips:路由前面可能还没介绍,后续专题介绍。

{path: '/tea', component: () => import('@/views/study/ZyTeacherInfoManage'), hidden: true
},

最后,看一下效果,有那么回事吧。
image.png
image.png
操作一下增删改查,基本功能都正常,你敢相信,使用一套合适的代码生成器,仅仅几分钟就可以实现一个CURD功能。

代码修修补补

虽然功能全部正常,但是要拿去交差还是要完善一些。

【查询页面调整】
首先,表格页面代码生成的是全部字段,先把不重要的字段去掉,效果如下:image.png
表单元素太紧凑了,加一点间距,上一篇文章刚介绍了《企业实战分享 · CodeGeeX 初体验》,给它一个机会,练练手,如下所示:
image.png
生成很快,试试,效果如下图:
image.png
啧啧,什么鬼,没理解我意图,直接用 span 拆开间距了,也可能我没说清楚。
那给ChatGpt一个机会:
image.png
效果如下图,好像还不错,就这样吧。
image.png

【分页查询功能】
代码生成器是没办法那么智能知道你想用哪些字段作为搜索条件,当然生成的时候,给字段添加一些额外标识就另说,但感觉这样效率更低,还不如生成之后再来调整。
这边设计代码生成器的时候,固定保留了一个模糊搜索框和有效标志下拉框,可以覆盖大部分场景的最小需要。
看一下对应前端代码:
1、前端定义listQuery对象代表查询入参,传递query和validFlag两个属性,点击搜索触发handleFilter逻辑。
2、触发的JS逻辑,其实就是利用基于axios封装的请求工具,异步请求相关接口获取分页数据。

Tips:关于前端请求后端的工具封装,后续专栏介绍。

<el-input placeholder="关键词过滤" v-model="listQuery.query" class="filter-item input-item"@keyup.enter.native="handleFilter"
/>
<el-select v-model="listQuery.validFlag" placeholder="有效标志" clearable class="filter-item select-item"@change="handleFilter"><el-option v-for="(value, key) in statusOptions" :key="key" :label="value" :value="key"/>
</el-select>
<el-button v-waves class="filter-item button-item" type="primary" icon="el-icon-search" @click="handleFilter">搜索
</el-button>
/*** 搜索过滤*/
handleFilter() {this.listQuery.pageNum = 1this.fetchData()
},/*** 获取表格数据*/
fetchData() {let that = thisthis.listLoading = truethis.$http.all([ZyTeacherInfoApi.getPage(this.listQuery)]).then(this.$http.spread(function(perms) {that.list = perms.rowsthat.total = perms.totalthat.listLoading = false}))
},

再看看后端代码:
1、这边是借助PageHelper插件,轻松实现分页效果;
2、第二段是XML里面的SQL写法,参考一下即可,根据query模糊搜索,根据validFlag是精确查询;

@Service
public class ZyTeacherInfoService extends CrudService<ZyTeacherInfo, ZyTeacherInfoMapper> {/*** 获取用户分页列表** @param query    搜索关键词* @param pageInfo 分页实体* @param zyTeacherInfo 实体入参* @return 用户列表*/public PageInfo<ZyTeacherInfo> findListPage(String query, PageInfo pageInfo, ZyTeacherInfo zyTeacherInfo) {PageHelper.startPage(pageInfo);List<ZyTeacherInfo> zyTeacherInfolist = this.dao.findListPage(query, zyTeacherInfo);return new PageInfo<>(zyTeacherInfolist);}
}@Mapper
public interface ZyTeacherInfoMapper extends BaseMapper<ZyTeacherInfo> {/*** 分页获取教师信息表列表** @param query 搜索关键词* @param zyTeacherInfo 查询实体* @return 用户列表*/List<ZyTeacherInfo> findListPage(@Param("query") String query, @Param("model") ZyTeacherInfo zyTeacherInfo);
}
<!-- 分页查询教师信息表列表 -->
<select id="findListPage" resultType="zyTeacherInfo">selectt.*fromzy_teacher_info twhere 1=1<if test="query != null and query != ''">AND (INSTR(t.TEA_NAME , #{query})>0 OR t.TEA_CODE = #{query})</if><if test="model.validFlag != null and model.validFlag != ''">and t.VALID_FLAG = #{model.validFlag}</if>
</select>

【关于增删改】
这部分属于基操,前面示例都能看懂,这边以更新为例简单说明。
前端:
1、填写完表单信息,触发updateData函数,先针对表单信息做一个校验(参考ElementUI);
2、触发 ZyTeacherInfoApi 接口,该接口也是利用 Axios,触发 Post 请求,调用后端;

updateData() {let that = thisthis.$refs['dataForm'].validate((valid) => {if (valid) {const tempData = Object.assign({}, this.temp)ZyTeacherInfoApi.update(tempData).then(() => {this.dialogFormVisible = falsethis.$notify({title: '成功',message: '更新成功',type: 'success',duration: 1000,onClose() {that.fetchData()}})})}})
},update(params) {return request({url: '/zyTeacherInfo/update', method: 'post', params})
},

后端:好像没什么特别的,就是正常的 MyBatis - Update,搞定!


前端知识拓展

图形化方式创建 Vue

在这篇博文《程序猿学会 Vue · 基础与实战篇》中,介绍创建Vue项目的多种方式,漏介绍了一种图形化。
命令行输入:vue ui
会自动打开一个图形化页面,如下图,按步骤傻瓜式操作即可。

Tips:好像也没有什么特别的,不详细介绍。
Tips:SpringBoot也有类似界面,总之就是越来越简单了,怎么傻瓜怎么来。

image.png


整合路由 Vue-Router

【安装使用】
Step1、安装路由
npm install vue-router

Step2、编写路由配置文件,/router/index.js

import {createRouter, createWebHashHistory} from 'vue-router'
import HomeView from '../views/Home.vue'const routes = [{path: '/home', name: 'home', component: HomeView
}, {path: '/about', name: 'about', component: () => import('../views/About.vue')
}]const router = createRouter({history: createWebHashHistory(), routes
})export default router

Step3、引入上述 JS,在 main.js 操作

// 引入路由
import router from './router/index.js'
app.use(router)

Step4、效果使用
App.vue 页面在合适地方添加:
地址栏输入/home或/about,内容会随之变化。


总结陈词

本系列博文更新到第四篇了,基本实现了教师的CURD功能。
接下来几篇博文将针对其中涉及的几个框架封装知识点进行专题说明。
总之,目标是帮助初入职场的大家,快速适应企业开发,多一些机会。
💗 如果觉得内容还可以,麻烦点个关注不迷路,您的鼓励是我创作的动力。

CSDN_END.gif

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

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

相关文章

【C++刷题】优选算法——队列+宽搜

N 叉树的层序遍历 vector<vector<int>> levelOrder(Node* root) {vector<vector<int>> ret;if (root nullptr) return ret;queue<Node*> q;q.push(root);ret.push_back({root->val});int size 1;while (!q.empty()) {vector<int> v…

【机器学习】Jupyter Notebook如何使用之基本步骤和进阶操作

引言 Jupyter Notebook 是一个交互式计算环境&#xff0c;它允许创建包含代码、文本和可视化内容的文档 文章目录 引言一、基本步骤1.1 启动 Jupyter Notebook1.2 使用 Jupyter Notebook 仪表板1.3 在笔记本中工作1.4 常用快捷键1.5 导出和分享笔记本 二、进阶用法2.1 组织笔…

从零开始学习网络安全渗透测试之基础入门篇——(二)Web架构前后端分离站Docker容器站OSS存储负载均衡CDN加速反向代理WAF防护

Web架构 Web架构是指构建和管理Web应用程序的方法和模式。随着技术的发展&#xff0c;Web架构也在不断演进。当前&#xff0c;最常用的Web架构包括以下几种&#xff1a; 单页面应用&#xff08;SPA&#xff09;&#xff1a; 特点&#xff1a;所有用户界面逻辑和数据处理都包含…

劝你不要上自动化立体库,非要上,砸锅了吧

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 在当今这个科技日新月异的时代&#xff0c;自动化立体库作为仓储物流领域的佼佼者&#xff0c;以其高效、精准、节省人力的优势&#xff0c;吸引…

Windows下帆软BI(finebi)单机部署移植(Tomcat)攻略

一、基础环境 操作系统&#xff1a;Windows 10 64bit 帆软BI 版本&#xff1a;V9.0/V10.0 HTTP工具&#xff1a;Tomcat 外置数据库&#xff1a;Oracle 11g 实验内容&#xff1a;将已经部署好的帆软BI从一台电脑移植到另一台电脑 二、前期准备 1、做好外置数据库移植&…

【Three.js基础学习】17.imported-models

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 课程回顾&#xff1a; 如何在three.js 中引入不同的模型&#xff1f; 1. 格式 &#xff08;不同的格式&#xff09; https://en.wikipedia.org/wiki/List_of_file_form…

杭州东网约车管理再出行方面取得的显著成效

随着科技的飞速发展&#xff0c;网约车已成为人们日常出行的重要选择。在杭州这座美丽的城市&#xff0c;网约车服务更是如雨后春笋般蓬勃发展。特别是杭州东站&#xff0c;作为杭州的重要交通枢纽&#xff0c;网约车管理显得尤为重要。近日&#xff0c;沧穹科技郑重宣告已助力…

达梦数据库系列—33.日志总结

目录 1、SQL日志 SQL 日志开启 SQL日志分析 2、Redo日志 3、归档日志 联机配置归档 手动配置归档 归档信息的查看 清理归档日志 4、闪回 查看闪回功能状态 开启闪回 闪回查询 5、其他事件日志 数据库实例日志 DMAP进程日志 数据库备份日志 dmwatcher日志 dm…

【STM32本科毕业设计】基于STM32的多功能MP3播放器设计

目录 一. 概述二. 系统硬件设计2.1 整体设计思路2.2 硬件器件的选择2.2.1 MP3解码芯片选择 2.2.2 收音机芯片选择2.2.3 温度传感器选择2.2.4 彩灯驱动芯片选择2.2.5 音效处理芯片选择2.2.6 EEPROM芯片选择2.2.7 功率放大芯片选择2.2.8 电源芯片选择2.2.9 人机交互设备选择 2.3 …

Django学习第一天(如何创建和运行app)

前置知识&#xff1a; URL组成部分详解&#xff1a; 一个url由以下几部分组成&#xff1a; scheme&#xff1a;//host:port/path/?query-stringxxx#anchor scheme:代表的是访问的协议&#xff0c;一般为http或者ftp等 host&#xff1a;主机名&#xff0c;域名&#xff0c;…

Spring Security学习笔记(二)Spring Security认证和鉴权

前言&#xff1a;本系列博客基于Spring Boot 2.6.x依赖的Spring Security5.6.x版本 上一篇博客介绍了Spring Security的整体架构&#xff0c;本篇博客要讲的是Spring Security的认证和鉴权两个重要的机制。 UsernamePasswordAuthenticationFilter和BasicAuthenticationFilter是…

【JVM基础05】——组成-能不能解释一下方法区?

目录 1- 引言&#xff1a;方法区概述1-1 方法区是什么&#xff1f;(What)1-2 为什么用方法区&#xff1f;方法区的作用 (Why) 2- ⭐核心&#xff1a;详解方法区(How)2-1 能不能解释一下方法区&#xff1f;2-2 元空间内存溢出问题2-3 什么是常量池&#xff1f;2-4 运行时常量池 …

SAP PP学习笔记31 - 计划运行的步骤2 - Scheduling(日程计算),BOM Explosion(BOM展开)

上一章讲了计划运行的5大步骤中的前两步&#xff0c;计算净需求和计算批量大小。 SAP PP学习笔记30 - 计划运行的步骤1 - Net requirements calculation 计算净需求(主要讲了安全库存要素)&#xff0c;Lot-size calculation 计算批量大小-CSDN博客 本章继续讲计划运行的后面几…

360:从安全卫士到智能生活——一个科技巨头的成长之路

自2005年成立以来&#xff0c;360公司&#xff0c;全称北京奇虎科技有限公司&#xff0c;已经成为中国乃至全球科技领域的一股不可忽视的力量。从最初的互联网安全服务提供商&#xff0c;到如今涉足智能硬件、云计算、大数据、人工智能等领域的多元化科技公司&#xff0c;360的…

**卷积神经网络典型CNN**

LeNet&#xff1a;最早用于数字识别的CNN AlexNet&#xff1a;2012年ILSVRC比赛冠军&#xff0c;远超第二名的CNN&#xff0c;比LeNet更深&#xff0c;用多层小卷积叠加来替换单个的大卷积 ZF Net&#xff1a;2013ILSVRC冠军 GoogleNet&#xff1a;2014ILSVRC冠军 VGGNet&a…

Unity UGUI 之 自动布局组件

本文仅作学习笔记与交流&#xff0c;不作任何商业用途 本文包括但不限于unity官方手册&#xff0c;唐老狮&#xff0c;麦扣教程知识&#xff0c;引用会标记&#xff0c;如有不足还请斧正 本文在发布时间选用unity 2022.3.8稳定版本&#xff0c;请注意分别 1.什么是自动布局组件…

【Node.js入门精要】从零开始的开发之旅

说明文档&#xff1a;Node.js 教程_w3cschool 概念 Node.js 是一个开源、跨平台的 JavaScript 运行时环境&#xff0c;基于 Chrome 的 V8 引擎构建&#xff0c;专为构建高性能和可扩展的网络应用程序而设计的服务端语言。它采用事件驱动、非阻塞 I/O 模型&#xff0c;能够处理大…

GB28181摄像头管理平台WVP视频平台SQL注入漏洞复现 [附POC]

文章目录 GB28181摄像头管理平台WVP视频平台SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 GB28181摄像头管理平台WVP视频平台SQL注入漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利用文章内…

Unity UGUI 之 Mask

本文仅作学习笔记与交流&#xff0c;不作任何商业用途 本文包括但不限于unity官方手册&#xff0c;唐老狮&#xff0c;麦扣教程知识&#xff0c;引用会标记&#xff0c;如有不足还请斧正 本文在发布时间选用unity 2022.3.8稳定版本&#xff0c;请注意分别 1.什么是遮罩 遮罩是一…

运算符 、、|、|| 、短路符【|| 、】<< 、>>

》》》&&是逻辑与运算符&#xff0c;|| 是逻辑或运算符 &#xff01;是逻辑非运算符 逻辑与运算符&#xff1a;全为真&#xff08;1&#xff09;即结果为真&#xff08;1&#xff09;&#xff0c;一个为假即全为假&#xff08;0&#xff09; 逻辑或运算符&#xff1a;…