文章目录

  • 1.EasyExcel
    • 1.1Excel导入导出的应用场景
    • 1.2 EasyExcel简介
    • 1.2创建一个项目,实现EasyExcel对Excel的写操作
      • 1.2.1创建一个普通的maven项目
      • 1.2.2引入相关的依赖
      • 1.2.3创建实体类
      • 1.2.4实现写操作
    • 1.3EasyExcel读操作
      • 1.3.1. 创建一个实体类
      • 1.3.2创建读取操作的监听器
      • 1.3.3进行测试
  • 2. 课程分类管理
    • 2.1添加课程分类后端
      • 2.1.1用代码生成器生成相应的代码
      • 2.1.2实体类
      • 2.1.3controller层
      • 2.1.4service层
      • 2.1.5 mapper层
      • 2.1.6Excel表格数据的读取
    • 2.2添加课程分类的前端
      • 2.2.1添加课程分类的路由
      • 2.2.2创建课程分类页面,修改路由对应的页面路径
      • 2.2.3上传分类列表前端的编写
    • 2.3 课程列表功能
      • 2.3.1后端部分
      • 2.3.2前端部分

1.EasyExcel

1.1Excel导入导出的应用场景

  1. 数据导入:减轻录入工作量
  2. 数据导出:统计信息归档
  3. 数据传输:异构系统之间数据传输

1.2 EasyExcel简介

  • Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc。
  • EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
  • EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)。

1.2创建一个项目,实现EasyExcel对Excel的写操作

我创建了如下图所示的表

1.2.1创建一个普通的maven项目

我创建在servicemodule下的easy-eacel下

1.2.2引入相关的依赖

   <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.1</version></dependency></dependencies>

1.2.3创建实体类

设置表头和添加的字段

@Data
public class DemoData {//设置Excel表头名称@ExcelProperty("学生编号")private Integer sno;//设置表头名称@ExcelProperty("学生姓名")private String sname;
}

1.2.4实现写操作

public class TextExcel {public static void main(String[] args) {//实现Excel文件的写操作//这是文件夹的地址及名称String filename="F:\\write.xls";//创建要写入数据的list集合ArrayList<DemoData> demoDataArrayList = new ArrayList<>();for(int i=0;i<10;i++){DemoData demoData = new DemoData();demoData.setSno(i);demoData.setSname("Stu"+i*i);demoDataArrayList.add(demoData);}//调用EasyExcel里面的方法实现写操作//write方法的两个参数 第一个文件路径名称 第二个是实体类//.sheet是设置sheet的名字 dowrite的写入的内容EasyExcel.write(filename,DemoData.class).sheet("学生列表").doWrite(demoDataArrayList);}
}

1.3EasyExcel读操作

1.3.1. 创建一个实体类

创建一个名为DemoData1的实体类

@Data
public class DemoData1 {//设置Excel表头名称@ExcelProperty(value = "学生编号",index = 0)private Integer sno;//设置表头名称@ExcelProperty(value = "学生姓名",index = 1)private String sname;
}

1.3.2创建读取操作的监听器

我创建了一个名为TextExcel1的类

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;import java.util.Map;public class TextExcel1 extends AnalysisEventListener<DemoData1> {//一行一行读取Excel内容@Overridepublic void invoke(DemoData1 demoData1, AnalysisContext analysisContext) {System.out.println("数据"+demoData1);}//读取完成之后@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}//读取表头信息@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {System.out.println("表头:"+headMap);}
}

1.3.3进行测试

import com.alibaba.excel.EasyExcel;public class Text {public static void main(String[] args) {//实现Excel读操作String filename="F:\\write.xls";EasyExcel.read(filename,DemoData1.class,new TextExcel1()).sheet().doRead();}
}

2. 课程分类管理

从后台导入课程,将课程分为一级和二级课程并进行管理

2.1添加课程分类后端

对Excel表中的数据存入分级数据库中

2.1.1用代码生成器生成相应的代码

@Testpublic void run() {// 1、创建代码生成器AutoGenerator mpg = new AutoGenerator();// 2、全局配置GlobalConfig gc = new GlobalConfig();String projectPath = System.getProperty("user.dir");gc.setOutputDir("D:\\study-spring-boot\\guli\\service\\service_edu"+ "/src/main/java");gc.setAuthor("testjava");//作者gc.setOpen(false); //生成后是否打开资源管理器gc.setFileOverride(false); //重新生成时文件是否覆盖gc.setServiceName("%sService");    //去掉Service接口的首字母Igc.setIdType(IdType.ID_WORKER); //主键策略gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型gc.setSwagger2(true);//开启Swagger2模式mpg.setGlobalConfig(gc);// 3、数据源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8");dsc.setDriverName("com.mysql.cj.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("root");dsc.setDbType(DbType.MYSQL);mpg.setDataSource(dsc);// 4、包配置PackageConfig pc = new PackageConfig();pc.setModuleName("eduservice"); //模块名pc.setParent("com.blb");pc.setController("controller");pc.setEntity("domain");pc.setService("service");pc.setMapper("mapper");mpg.setPackageInfo(pc);// 5、策略配置StrategyConfig strategy = new StrategyConfig();strategy.setInclude("edu_subject");strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作strategy.setRestControllerStyle(true); //restful api风格控制器strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符mpg.setStrategy(strategy);// 6、执行mpg.execute();}

2.1.2实体类

package com.blb.eduservice.domain;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;import java.io.Serializable;
import java.util.Date;@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="EduSubject对象", description="课程科目")
public class EduSubject implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "课程类别ID")@TableId(value = "id", type = IdType.ID_WORKER_STR)private String id;@ApiModelProperty(value = "类别名称")private String title;@ApiModelProperty(value = "父ID")private String parentId;@ApiModelProperty(value = "排序字段")private Integer sort;@TableField(fill = FieldFill.INSERT)@ApiModelProperty(value = "创建时间")private Date gmtCreate;@TableField(fill = FieldFill.INSERT_UPDATE)@ApiModelProperty(value = "更新时间")private Date gmtModified;}

2.1.3controller层

@RestController
@RequestMapping("/eduservice/subject")
@CrossOrigin
@Api(tags = "课程分类")
public class EduSubjectController {@Autowiredprivate EduSubjectService eduSubjectService;//添加课程分类//获取上传文件,将文件内容读取出来@PostMapping("/addObject")@ApiOperation("添加课程")public Res addSubject(MultipartFile file){//上传过来的Excel文件eduSubjectService.saveSubject(file,eduSubjectService);return Res.ok();}}

2.1.4service层

@Service
public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {//添加课程分类@Overridepublic void saveSubject(MultipartFile file,EduSubjectService eduSubjectService) {try {InputStream inputStream = file.getInputStream();EasyExcel.read(inputStream, SubjectData.class,new SubjectExcelLisiten(eduSubjectService)).sheet().doRead();} catch (IOException e) {e.printStackTrace();}}
}

2.1.5 mapper层

public interface EduSubjectMapper extends BaseMapper<EduSubject> {}

2.1.6Excel表格数据的读取

@Data
public class SubjectData {@ExcelProperty(index = 0)private String oneSubjectName;@ExcelProperty(index =1)private String twoSubjectName;
}

读取的监听器

package com.blb.eduservice.listen;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.blb.eduservice.domain.EduSubject;
import com.blb.eduservice.domain.excel.SubjectData;
import com.blb.eduservice.service.EduSubjectService;public class SubjectExcelLisiten extends AnalysisEventListener<SubjectData> {//SubjectExcelLisiten不能交给spring进行管理 需要自己new 不能注入其他对象public EduSubjectService eduSubjectService;public SubjectExcelLisiten() {}public SubjectExcelLisiten(EduSubjectService eduSubjectService) {this.eduSubjectService = eduSubjectService;}//读取表中的内容@Overridepublic void invoke(SubjectData subjectData, AnalysisContext analysisContext) {if(subjectData==null){return ;}//一行一行读取每次取两个值 分别为一级分类 二级分类EduSubject oneSubject = this.exitOneSubject(eduSubjectService, subjectData.getOneSubjectName());if(oneSubject==null)//没有相同的一级分类 进行添加{oneSubject = new EduSubject();oneSubject.setParentId("0");oneSubject.setTitle(subjectData.getOneSubjectName());eduSubjectService.save(oneSubject);}String parentId = oneSubject.getId();EduSubject twoSubject = this.exitTwoSubject(eduSubjectService, subjectData.getTwoSubjectName(), parentId);if(twoSubject==null){twoSubject=new EduSubject();twoSubject.setParentId(parentId);twoSubject.setTitle(subjectData.getTwoSubjectName());eduSubjectService.save(twoSubject);}}//判断一级分类不能重复添加private EduSubject exitOneSubject (EduSubjectService eduSubjectService,String name){QueryWrapper<EduSubject> queryWrapper=new QueryWrapper<>();queryWrapper.eq("title",name);queryWrapper.eq("parent_id","0");EduSubject oneSubject = eduSubjectService.getOne(queryWrapper);return oneSubject;}//判断二级分类不能重复添加private EduSubject exitTwoSubject (EduSubjectService eduSubjectService,String name,String pid){QueryWrapper<EduSubject> queryWrapper=new QueryWrapper<>();queryWrapper.eq("title",name);queryWrapper.eq("parent_id",pid);EduSubject twoSubject = eduSubjectService.getOne(queryWrapper);return twoSubject;}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}
}

2.2添加课程分类的前端

2.2.1添加课程分类的路由

 {path: '/subject',component: Layout,redirect: '/subject/list',name: '课程分类管理',meta: { title: '课程分类管理', icon: 'example' },children: [{path: 'list',name: '课程分类列表',component: () => import('@/views/edu/subject/list'),meta: { title: '课程分类列表', icon: 'table' }},{path: 'save',name: '添加课程分类',component: () => import('@/views/edu/subject/save'),meta: { title: '添加课程分类', icon: 'tree' }}]},

2.2.2创建课程分类页面,修改路由对应的页面路径

在views/edu/subject下创建两个文件分别为list.vue和save.vue

2.2.3上传分类列表前端的编写

save.vue

<template><div class="app-container"><el-form label-width="120px"><el-form-item label="讲师名称"><el-input v-model="teacher.name"/></el-form-item><el-form-item label="讲师排序"><el-input-number v-model="teacher.sort" controls-position="right" min="0"/></el-form-item><el-form-item label="讲师头衔"><el-select v-model="teacher.level" clearable placeholder="请选择"><!--数据类型一定要和取出的json中的一致,否则没法回填因此,这里value使用动态绑定的值,保证其数据类型是number--><el-option :value="1" label="高级讲师"/><el-option :value="2" label="首席讲师"/></el-select></el-form-item><el-form-item label="讲师资历"><el-input v-model="teacher.career"/></el-form-item><el-form-item label="讲师简介"><el-input v-model="teacher.intro" :rows="10" type="textarea"/></el-form-item><!-- 讲师头像:TODO --><!-- 讲师头像 -->
<el-form-item label="讲师头像"><!-- 头衔缩略图 --><pan-thumb :image="teacher.avatar"/><!-- 文件上传按钮 --><el-button type="primary" icon="el-icon-upload" @click="imagecropperShow=true">更换头像</el-button><!--
v-show:是否显示上传组件
:key:类似于id,如果一个页面多个图片上传控件,可以做区分
:url:后台上传的url地址
@close:关闭上传组件
@crop-upload-success:上传成功后的回调 --><image-cropperv-show="imagecropperShow":width="300":height="300":key="imagecropperKey":url="BASE_API+'/eduoss/fileoss'"field="file"@close="close"@crop-upload-success="cropSuccess"/>
</el-form-item><el-form-item><el-button :disabled="saveBtnDisabled" type="primary" @click="saveOrUpdate">保存</el-button></el-form-item></el-form></div>
</template>
<script>
import teacherApi from '@/api/edu/teacher'
import ImageCropper from '@/components/ImageCropper'
import PanThumb from '@/components/PanThumb'
export default {components: { ImageCropper, PanThumb },data(){return {teacher: {},imagecropperShow:false,//上传弹框组件是否显示imagecropperKey:0,//上传组件key值BASE_API:process.env.BASE_API, //dev.env.jd里面的地址saveBtnDisabled:false //报存按钮是否禁用}},created(){//渲染页面之前执行this.init()},watch:{ //监听$route(to,from)   //路由变化方式,路由发生变化方法会执行{this.init()}},methods: {close(){//关闭弹窗的方法this.imagecropperShow=falsethis.imagecropperKey=this.imagecropperKey+1},cropSuccess(data)//上传成功的方法{this.imagecropperShow=false//上传接口返回图片地址console.log(data.url)this.teacher.avatar=data.urlthis.imagecropperKey=this.imagecropperKey+1},init(){if(this.$route.params && this.$route.params.id){const id=this.$route.params.id;this.getInfo(id)}else{this.teacher={}}},saveOrUpdate(){//判断是否有id 有id修改  没有id添加if(this.teacher.id){this.updateTeacher()}else{this.saveTeacher()}},saveTeacher(){teacherApi.addTeacher(this.teacher).then(response=>{//提示信息this.$message({type: 'success',message: '添加成功!'});//回到列表页面 路由跳转this.$router.push({path: '/teacher/table'})})},//根据讲师id查询信息getInfo(id){console.log(id)teacherApi.getTeacherById(id).then(response => {this.teacher=response.data.eduTeacher})},//修改讲师信息updateTeacher(){teacherApi.updateTeacher(this.teacher).then(response => {//提示信息this.$message({type: 'success',message: '修改成功!'});//页面跳转this.$router.push({path: '/teacher/table'})})}}}
</script>

2.3 课程列表功能

为了前端便于得到下图的效果,将数据分为一级分类和二级分类,他们的关系是一个一级分类里面可以有多个二级分类

2.3.1后端部分

在实体类里面建一个subject包,subject包下分别创建名为OneSubject和TwoSubject的实体类
TwoSubject

//二级分类
@Data
public class TwoSubject {//idprivate String id;//题private String title;}

OneSubject

@Data
public class OneSubject {//id private String id;//标题private String title;//一个一级分类里面有多个二级分类private List<TwoSubject> children =new ArrayList<>();}

controller部分

 @GetMapping("/getAllSubject")@ApiOperation("得到所有课程的分类信息")public Res getAllSubject(){List<OneSubject> list= eduSubjectService.getOneTwoSubject();HashMap<String, Object> hashMap = new HashMap<>();hashMap.put("list",list);return Res.ok().data(hashMap);}

service层代码

    //课程分类列表@Overridepublic List<OneSubject> getOneTwoSubject() {//查找所有的一级分类QueryWrapper<EduSubject> wrapperOne=new QueryWrapper<>();wrapperOne.eq("parent_id","0");List<EduSubject> oneList = eduSubjectMapper.selectList(wrapperOne);//查找所有的二级分类QueryWrapper<EduSubject> wrapperTwo=new QueryWrapper<>();wrapperTwo.ne("parent_id","0");List<EduSubject> twoList = eduSubjectMapper.selectList(wrapperTwo);ArrayList<OneSubject> finalList = new ArrayList<>();//封装一级分类 查询一级分类的list集合 得到每一个一级对象 获取每个一级分类的值for(EduSubject eduSubject:oneList){OneSubject oneSubject = new OneSubject();//把EduSubject中的值封装到OneSubjectBeanUtils.copyProperties(eduSubject,oneSubject);//封装二级分类String id = oneSubject.getId();ArrayList<TwoSubject> twoSubjectList = new ArrayList<>();for(EduSubject eduSubject1:twoList){//得到父idString parentId = eduSubject1.getParentId();if(id.equals(parentId)){TwoSubject twoSubject = new TwoSubject();BeanUtils.copyProperties(eduSubject1,twoSubject);twoSubjectList.add(twoSubject);}}oneSubject.setChildren(twoSubjectList);finalList.add(oneSubject);}return finalList;}

2.3.2前端部分

  1. 创建一个请求信息
    在src/api/edu目录下创建subject.js的目录用来请求

subject.js

import request from '@/utils/request'export default{getSubjectList(){return request({url:"/eduservice/subject/getAllSubject",method:"get"})}
}

views/subject/list.vue

<template><div class="app-container"><el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;" /><el-treeref="tree2":data="data2":props="defaultProps":filter-node-method="filterNode"class="filter-tree"default-expand-all/></div>
</template><script>
import subject from '@/api/edu/subject'
export default {data() {return {filterText: '',data2: [],//返回所有的数据defaultProps: {children: 'children',label: 'title'}}},watch: {filterText(val) {this.$refs.tree2.filter(val)}},created() {this.getAllSubjects()},methods: {getAllSubjects() {subject.getSubjectList().then(response => {console.log(response.data.list)this.data2=response.data.list})},filterNode(value, data) {if (!value) return truereturn data.title.toLowerCase().indexOf(value.toLowerCase()) !== -1}}
}
</script>

笔记实时更新中,若有不足之处请及时之处

尚硅谷在线教育六:尚硅谷在线教育课程分类管理开发相关推荐

  1. 教育机构如何提升在线教育技术能力? | 云+社区技术沙龙

    教育机构如何提升在线教育技术能力? 如何给用户稳定.清晰流畅的在线互动体验? AI和大数据的发展会给行业带来哪些变革? 腾讯云结合自身优势,从在线教育的业务营销.教学业务应用与管理方面助力行业合伙发展 ...

  2. 在线教育直播系统 一对一在线直播平台解决方案

    在线教育直播系统 一对一在线直播平台解决方案 在线教育直播系统功能模块 在线教育直播系统讲师端功能 在线教育直播系统学生端功能 一对一在线教育系统功能介绍 一对一在线教育系统优势 在线教育直播系统功能 ...

  3. IOS音视频(四十六)离线在线语音识别方案

    IOS音视频(四十六)离线在线语音识别方案 IOS音视频(四十六)离线在线语音识别方案 方案一:Siri语音识别 Siri语音识别简介 Siri语音识别功能类介绍 Siri语音识别功能集成 方案二:百 ...

  4. 下面哪项属于计算机在教育教学中的应用,东师现代教育技术18秋在线作业2答案...

    现代教育技术18秋在线作业2-0005 试卷总分:100    得分:0 一. 单选题 (共 10 道试题,共 25 分) 1.不仅具有路由的功能,而且能对两个网络段中使用不同传输协议的数据进行互相的 ...

  5. 基于html5的在线教育,基于HTML5的在线学习系统的设计与实现

    基于HTML5的在线学习系统的设计与实现 发布时间:2019-11-18所属分类:科技论文浏览:1次 摘 要: 摘 要: 在线课程学习网站的发展迅速,吸引了广大用户.基于 HTML5 的在线学习系统经 ...

  6. 北师大计算机在线作业9,北师大网络教育《计算机动画》在线作业-20210614020942.pdf-原创力文档...

    北师大网络教育<计算机动画>在线作业 以下哪个工具不可以用来绘制或者调整路径 ( ) . [线条工具] [铅笔工具] [选择工具] [手形工具] 如果想要改变绘制图形的线条颜色 , 应该使 ...

  7. 在线教育20年:在线教育的未来发展趋势

    作者:刘燕.即构科技在线教育产品首席架构师,在线教育行业资深应用专家,服务在线教育行业近20年. 文章为刘燕基于多年的行业观察,结合在即构科技服务多家头部教育客户的经验,分享对在线教育行业未来演变的思 ...

  8. itutorgroup:在线教育与传统线下教育的七大区别你知多少?

    说起教育培训行业,现在已经分为两大阵营了,一是传统的线下培训,另一个则是最近几年大火的在线教育,为什么会这样呢?两者有什么区别呢?为什么现在越来越多的人开始选择在线教育,传统的线下培训输在哪里呢?下面 ...

  9. 在线教育公司指标体系-以某教育公司为例

    最近想找教育行业的数据指标体系学习,但是几乎找不到,所以想先自己尝试建一个,因为学了某教育公司的课程,所以就考虑以这家公司为例建立数据指标体系. 建立指标体系,首先考虑北极星指标的选取和拆解,然后考虑 ...

最新文章

  1. java注解机制_Java 注解机制
  2. ubuntu 16.04 更新后搜狗输入法无法输入中文的问题
  3. 【Python刷题】_6
  4. 【MongoDB】递归获取字段更新表达式,更新复杂数据类型对象
  5. mysql 5.6 生产my.cnf_一个生产可用的mysql参数文件my.cnf
  6. laravel基础课程---14、表单验证(lavarel如何进行表单验证)
  7. 关于linux交换分区的增大
  8. Nginx解决服务器宕机问题
  9. 第13章 集成学习和随机森林 学习笔记下 随机森林和集成学习
  10. AdapterView详解
  11. 解决ttf-mscorefonts-installer无法安装的问题
  12. iOS开发-代码分析工具之Infer
  13. javascript检测5到10位数的QQ号
  14. 【Godot】通过属性检查器显示对应节点的脚本属性
  15. 建筑师又在用人工智能做什么?(2019年第三期)
  16. 《区块链技术与应用》读书笔记
  17. 寻路问题——找到从起点到终点路径
  18. Laravel 报错 file_put_contents(): failed to open stream......解决
  19. WIN8.1下Prolific USB-to-Serial Comm Port驱动黄色感叹号问题
  20. 2020数学建模国赛B题穿越沙漠个人解析

热门文章

  1. 面对市场寒冬,汽车零部件企业如何运用邓氏编码赢取更多的商机?
  2. 王者qq服务器能和微信一起吗,王者荣耀微信和qq能一起玩吗 qq和微信数据互通吗...
  3. 音频文件如何转换成MP3格式?一分钟教你搞定
  4. 提取百度新闻的标题、网址、日期和来源
  5. ElementUI轮播图指示器设置为图片
  6. 微信零钱明细删除后服务器有记录吗,微信零钱明细怎么删除记录?教你微信零钱明细记录如何删除...
  7. c语言综合程序设计省市邮政编码,《C语言程序设计课程设计报告》_课程教学大纲...
  8. python使用蓝牙与HC05通讯(pybluez调用socket、模拟串口)
  9. 学完C语言,学什么, 怎么学,之后学什么
  10. UWP ComboBox 样式的问题及改善