2.4-学成在线内容管理之项目实战

news2024/9/23 15:30:36

内容管理模块

文章目录

  • 内容管理模块
    • 9 项目实战
      • 9.1 实战环境
        • 9.1.1 实战流程
      • 9.2 删除课程计划
        • 9.2.1 需求分析
        • 9.2.2 接口定义
        • 9.2.3 接口开发
        • 9.2.4 接口测试
      • 9.3 课程计划排序
        • 9.3.1 需求分析
        • 9.3.2 接口定义
        • 9.3.3 接口开发
        • 9.3.4 接口测试
      • 9.4 师资管理
        • 9.4.1 需求分析
        • 9.4.2 接口定义
        • 9.4.3 接口开发
      • 9.4.4 接口测试
      • 9.5 删除课程
        • 9.5.1 需求分析
        • 9.5.2 接口定义
        • 9.5.3 接口开发
        • 9.5.4 接口测试

9 项目实战

9.1 实战环境

9.1.1 实战流程

项目实战是模拟企业实际开发的场景,自己参考文档独立完成开发任务,项目实战可以有效的培养自己面对需求进行分析与开发的能力。
这部分要完成的内容包括

添加课程、添加课程计划、添加师资信息
修改课程、修改课程计划、修改师资信息
删除课程、删除课程计划、删除师资信息
课程计划上移、下移功能

9.2 删除课程计划

9.2.1 需求分析

课程计划添加成功,如果课程还没有提交时可以删除课程计划。
在这里插入图片描述

删除第一级别的大章节时要求大章节下边没有小章节时方可删除。
删除第二级别的小章节的同时需要将teachplan_media表关联的信息也删除。

9.2.2 接口定义

删除课程计划的接口定义:
传入课程计划id进行删除操作。

Java
Request URL: /content/teachplan/246
Request Method: DELETE

如果失败返回:
{"errCode":"120409","errMessage":"课程计划信息还有子级信息,无法操作"}

如果成功:状态码200,不返回信息

9.2.3 接口开发

定义接口如下

@ApiOperation("课程计划删除")
@DeleteMapping("/content/teachplan/{teachplanId}")
public void deleteTeachplan(@PathVariable Long teachplanId) {
    
}

接口开发
定义删除课程计划的接口

void deleteTeachplan(Long teachplanId);

对应的接口实现

@Override
public void deleteTeachplan(Long teachplanId) {
    if (teachplanId == null)
        XueChengPlusException.cast("课程计划id为空");
    Teachplan teachplan = teachplanMapper.selectById(teachplanId);
    // 判断当前课程计划是章还是节
    Integer grade = teachplan.getGrade();
    // 当前课程计划为章
    if (grade == 1) {
        // 查询当前课程计划下是否有小节
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        // select * from teachplan where parentid = {当前章计划id}
        queryWrapper.eq(Teachplan::getParentid, teachplanId);
        // 获取一下查询的条目数
        Integer count = teachplanMapper.selectCount(queryWrapper);
        // 如果当前章下还有小节,则抛异常
        if (count > 0)
            XueChengPlusException.cast("课程计划信息还有子级信息,无法操作");
        teachplanMapper.deleteById(teachplanId);
    } else {
        // 课程计划为节
        teachplanMapper.deleteById(teachplanId);
        LambdaQueryWrapper<TeachplanMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TeachplanMedia::getTeachplanId, teachplanId);
        teachplanMediaMapper.delete(queryWrapper);
    }
}

完善Controller层接口

@ApiOperation("课程计划删除")
@DeleteMapping("/teachplan/{teachplanId}")
public void deleteTeachplan(@PathVariable Long teachplanId) {
    teachplanService.deleteTeachplan(teachplanId);
}
9.2.4 接口测试

首先使用httpclient工具进行测试

Java
### 删除课程计划
DELETE {{content_host}}/content/teachplan/43

分以下情况测试:
1、删除大章节,大章节下有小章节时不允许删除。
2、删除大章节,大单节下没有小章节时可以正常删除。
3、删除小章节,同时将关联的信息进行删除。

9.3 课程计划排序

9.3.1 需求分析

课程计划新增后默认排在同级别最后,课程计划排序功能是可以灵活调整课程计划的显示顺序,如下图:
在这里插入图片描述

上移表示将课程计划向上移动。
下移表示将课程计划向下移动。
向上移动后和上边同级的课程计划交换位置,可以将两个课程计划的排序字段值进行交换。
向下移动后和下边同级的课程计划交换位置,可以将两个课程计划的排序字段值进行交换。

9.3.2 接口定义

接口示例如下:
向下移动:

Java
Request URL: http://localhost:8601/api/content/teachplan/movedown/43
Request Method: POST
参数1:movedown  为 移动类型,表示向下移动
参数243为课程计划id

向上移动:

Java
Request URL: http://localhost:8601/api/content/teachplan/moveup/43
Request Method: POST
参数1:moveup 为 移动类型,表示向上移动
参数243为课程计划id

每次移动传递两个参数:
1、移动类型: movedown和moveup
2、课程计划id

9.3.3 接口开发
void orderByTeachplan(String moveType, Long teachplanId);
@Transactional
@Override
public void orderByTeachplan(String moveType, Long teachplanId) {
    Teachplan teachplan = teachplanMapper.selectById(teachplanId);
    // 获取层级和当前orderby,章节移动和小节移动的处理方式不同
    Integer grade = teachplan.getGrade();
    Integer orderby = teachplan.getOrderby();
    // 章节移动是比较同一课程id下的orderby
    Long courseId = teachplan.getCourseId();
    // 小节移动是比较同一章节id下的orderby
    Long parentid = teachplan.getParentid();
    if ("moveup".equals(moveType)) {
        if (grade == 1) {
            // 章节上移,找到上一个章节的orderby,然后与其交换orderby
            // SELECT * FROM teachplan WHERE courseId = 117 AND grade = 1  AND orderby < 1 ORDER BY orderby DESC LIMIT 1
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getGrade, 1)
                    .eq(Teachplan::getCourseId, courseId)
                    .lt(Teachplan::getOrderby, orderby)
                    .orderByDesc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
            exchangeOrderby(teachplan, tmp);
        } else if (grade == 2) {
            // 小节上移
            // SELECT * FROM teachplan WHERE parentId = 268 AND orderby < 5 ORDER BY orderby DESC LIMIT 1
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getParentid, parentid)
                    .lt(Teachplan::getOrderby, orderby)
                    .orderByDesc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
            exchangeOrderby(teachplan, tmp);
        }

    } else if ("movedown".equals(moveType)) {
        if (grade == 1) {
            // 章节下移
            // SELECT * FROM teachplan WHERE courseId = 117 AND grade = 1 AND orderby > 1 ORDER BY orderby ASC LIMIT 1
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getCourseId, courseId)
                    .eq(Teachplan::getGrade, grade)
                    .gt(Teachplan::getOrderby, orderby)
                    .orderByAsc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
            exchangeOrderby(teachplan, tmp);
        } else if (grade == 2) {
            // 小节下移
            // SELECT * FROM teachplan WHERE parentId = 268 AND orderby > 1 ORDER BY orderby ASC LIMIT 1
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getParentid, parentid)
                    .gt(Teachplan::getOrderby, orderby)
                    .orderByAsc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
            exchangeOrderby(teachplan, tmp);
        }
    }
}

/**
 * 交换两个Teachplan的orderby
 * @param teachplan 
 * @param tmp 
 */
private void exchangeOrderby(Teachplan teachplan, Teachplan tmp) {
    if (tmp == null)
        XueChengPlusException.cast("已经到头啦,不能再移啦");
    else {
        // 交换orderby,更新
        Integer orderby = teachplan.getOrderby();
        Integer tmpOrderby = tmp.getOrderby();
        teachplan.setOrderby(tmpOrderby);
        tmp.setOrderby(orderby);
        teachplanMapper.updateById(tmp);
        teachplanMapper.updateById(teachplan);
    }
}

controller

@Transactional
@Override
public void orderByTeachplan(String moveType, Long teachplanId) {
    Teachplan teachplan = teachplanMapper.selectById(teachplanId);
    // 获取层级和当前orderby,章节移动和小节移动的处理方式不同
    Integer grade = teachplan.getGrade();
    Integer orderby = teachplan.getOrderby();
    // 章节移动是比较同一课程id下的orderby
    Long courseId = teachplan.getCourseId();
    // 小节移动是比较同一章节id下的orderby
    Long parentid = teachplan.getParentid();
    if ("moveup".equals(moveType)) {
        if (grade == 1) {
            // 章节上移,找到上一个章节的orderby,然后与其交换orderby
            // SELECT * FROM teachplan WHERE courseId = 117 AND grade = 1  AND orderby < 1 ORDER BY orderby DESC LIMIT 1
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getGrade, 1)
                    .eq(Teachplan::getCourseId, courseId)
                    .lt(Teachplan::getOrderby, orderby)
                    .orderByDesc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
            exchangeOrderby(teachplan, tmp);
        } else if (grade == 2) {
            // 小节上移
            // SELECT * FROM teachplan WHERE parentId = 268 AND orderby < 5 ORDER BY orderby DESC LIMIT 1
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getParentid, parentid)
                    .lt(Teachplan::getOrderby, orderby)
                    .orderByDesc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
            exchangeOrderby(teachplan, tmp);
        }

    } else if ("movedown".equals(moveType)) {
        if (grade == 1) {
            // 章节下移
            // SELECT * FROM teachplan WHERE courseId = 117 AND grade = 1 AND orderby > 1 ORDER BY orderby ASC LIMIT 1
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getCourseId, courseId)
                    .eq(Teachplan::getGrade, grade)
                    .gt(Teachplan::getOrderby, orderby)
                    .orderByAsc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
            exchangeOrderby(teachplan, tmp);
        } else if (grade == 2) {
            // 小节下移
            // SELECT * FROM teachplan WHERE parentId = 268 AND orderby > 1 ORDER BY orderby ASC LIMIT 1
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getParentid, parentid)
                    .gt(Teachplan::getOrderby, orderby)
                    .orderByAsc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
            exchangeOrderby(teachplan, tmp);
        }
    }
}

/**
 * 交换两个Teachplan的orderby
 * @param teachplan 
 * @param tmp 
 */
private void exchangeOrderby(Teachplan teachplan, Teachplan tmp) {
    if (tmp == null)
        XueChengPlusException.cast("已经到头啦,不能再移啦");
    else {
        // 交换orderby,更新
        Integer orderby = teachplan.getOrderby();
        Integer tmpOrderby = tmp.getOrderby();
        teachplan.setOrderby(tmpOrderby);
        tmp.setOrderby(orderby);
        teachplanMapper.updateById(tmp);
        teachplanMapper.updateById(teachplan);
    }
}
9.3.4 接口测试

该功能可直接进行前后端联调,可以立即看到 效果。
1、向上移动测试
先找一个上边有课程计划的进行测试,向上移动后两个交换顺序。
再找最上边的课程计划向上移动,操作后位置不变因为已经在最上边了。
2、向下移动测试
先找一个下边有课程计划的进行测试,向下移动后两个交换顺序。
再找最下边的课程计划向下移动,操作后位置不变因为已经在最下边了。

9.4 师资管理

9.4.1 需求分析

在课程计划维护界面点击下一步进入师资管理界面:
在这里插入图片描述

点击添加教师打开添加界面,如下图,不用实现上传照片。
在这里插入图片描述

添加成功查询教师信息如下:
在这里插入图片描述

在这个界面可以删除老师,也可以点击编辑,修改教师信息:
在这里插入图片描述

注意: 只允许向机构自己的课程中添加老师、删除老师。 机构id统一使用:1232141425L

9.4.2 接口定义

1、查询教师接口请求示例

Java
get /courseTeacher/list/75
75为课程id,请求参数为课程id

响应结果
[{"id":23,"courseId":75,"teacherName":"张老师","position":"讲师","introduction":"张老师教师简介张老师教师简介张老师教师简介张老师教师简介","photograph":null,"createDate":null}]

2、添加教师请求示例

Java
post  /courseTeacher

请求参数:
{
  "courseId": 75,
  "teacherName": "王老师",
  "position": "教师职位",
  "introduction": "教师简介"
}
响应结果:
{"id":24,"courseId":75,"teacherName":"王老师","position":"教师职位","introduction":"教师简介","photograph":null,"createDate":null}

3、修改教师

Java
put /courseTeacher
请求参数:
{
  "id": 24,
  "courseId": 75,
  "teacherName": "王老师",
  "position": "教师职位",
  "introduction": "教师简介",
  "photograph": null,
  "createDate": null
}
响应:
{"id":24,"courseId":75,"teacherName":"王老师","position":"教师职位","introduction":"教师简介","photograph":null,"createDate":null}

4、删除教师

delete /ourseTeacher/course/75/26

75:课程id
26:教师id,即course_teacher表的主键
请求参数:课程id、教师id

响应:状态码200,不返回信息
9.4.3 接口开发

从接口示例中可以看到,新增和删除用的是同一个接口,判断请求是新增还是删除,是根据请求参数中是否传递了id来决定的
请求参数中没有id,则为新增教师
请求参数中有id,则为修改教师

@Slf4j
@RestController
@Api(value = "教师信息相关接口", tags = "教师信息相关接口")
public class CourseTeacherController {
    @Autowired
    private CourseTeacherService courseTeacherService;

    @ApiOperation("查询教师信息接口")
    @GetMapping("/courseTeacher/list/{courseId}")
    public List<CourseTeacher> getCourseTeacherList(@PathVariable Long courseId) {
        return null;
    }

    @ApiOperation("添加/修改教师信息接口")
    @PostMapping("/courseTeacher")
    public CourseTeacher saveCourseTeacher(@RequestBody CourseTeacher courseTeacher) {
        return null;
    }

    @ApiOperation("删除教师信息接口")
    @DeleteMapping("/courseTeacher/course/{courseId}/{teacherId}")
    public void deleteCourseTeacher(@PathVariable Long courseId, @PathVariable Long teacherId) {

    }
}
public interface CourseTeacherService {
    List<CourseTeacher> getCourseTeacherList(Long courseId);

    CourseTeacher saveCourseTeacher(CourseTeacher courseTeacher);

    void deleteCourseTeacher(Long courseId, Long teacherId);
}
@Slf4j
@Service
public class CourseTeacherServiceImpl implements CourseTeacherService {
    @Autowired
    private CourseTeacherMapper courseTeacherMapper;

    @Override
    public List<CourseTeacher> getCourseTeacherList(Long courseId) {
        // SELECT * FROM course_teacher WHERE course_id = 117
        LambdaQueryWrapper<CourseTeacher> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseTeacher::getCourseId, courseId);
        List<CourseTeacher> courseTeachers = courseTeacherMapper.selectList(queryWrapper);
        return courseTeachers;
    }

    @Transactional
    @Override
    public CourseTeacher saveCourseTeacher(CourseTeacher courseTeacher) {
        Long id = courseTeacher.getId();
        if (id == null) {
            // id为null,新增教师
            CourseTeacher teacher = new CourseTeacher();
            BeanUtils.copyProperties(courseTeacher, teacher);
            teacher.setCreateDate(LocalDateTime.now());
            int flag = courseTeacherMapper.insert(teacher);
            if (flag <= 0)
                XueChengPlusException.cast("新增失败");
            return getCourseTeacher(teacher);
        } else {
            // id不为null,修改教师
            CourseTeacher teacher = courseTeacherMapper.selectById(id);
            BeanUtils.copyProperties(courseTeacher, teacher);
            int flag = courseTeacherMapper.updateById(teacher);
            if (flag <= 0)
                XueChengPlusException.cast("修改失败");
            return getCourseTeacher(teacher);
        }
    }

    @Override
    public void deleteCourseTeacher(Long courseId, Long teacherId) {
        LambdaQueryWrapper<CourseTeacher> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseTeacher::getId, teacherId);
        queryWrapper.eq(CourseTeacher::getCourseId, courseId);
        int flag = courseTeacherMapper.delete(queryWrapper);
        if (flag < 0)
            XueChengPlusException.cast("删除失败");
    }

    public CourseTeacher getCourseTeacher(CourseTeacher courseTeacher) {
        return courseTeacherMapper.selectById(courseTeacher.getId());
    }
}

9.4.4 接口测试

1、添加教师
2、查询教师
3、修改教师
4、删除教师

9.5 删除课程

9.5.1 需求分析

课程的审核状态为未提交时方可删除。
删除课程需要删除课程相关的基本信息、营销信息、课程计划、课程教师信息。

9.5.2 接口定义

删除课程接口

Java
delete  /course/87
87为课程id
请求参数:课程id
响应:状态码200,不返回信息
9.5.3 接口开发
@ApiOperation("删除课程")
@DeleteMapping("/course/{courseId}")
public void deleteCourse(@PathVariable Long courseId) {
    Long companyId = 1232141425L;
    courseBaseInfoService.delectCourse(companyId,courseId);
}
void delectCourse(Long companyId, Long courseId);
@Transactional
@Override
public void delectCourse(Long companyId, Long courseId) {
    CourseBase courseBase = courseBaseMapper.selectById(courseId);
    if (!companyId.equals(courseBase.getCompanyId()))
        XueChengPlusException.cast("只允许删除本机构的课程");
    // 删除课程教师信息
    LambdaQueryWrapper<CourseTeacher> teacherLambdaQueryWrapper = new LambdaQueryWrapper<>();
    teacherLambdaQueryWrapper.eq(CourseTeacher::getCourseId, courseId);
    courseTeacherMapper.delete(teacherLambdaQueryWrapper);
    // 删除课程计划
    LambdaQueryWrapper<Teachplan> teachplanLambdaQueryWrapper = new LambdaQueryWrapper<>();
    teachplanLambdaQueryWrapper.eq(Teachplan::getCourseId, courseId);
    teachplanMapper.delete(teachplanLambdaQueryWrapper);
    // 删除营销信息
    courseMarketMapper.deleteById(courseId);
    // 删除课程基本信息
    courseBaseMapper.deleteById(courseId);
}
9.5.4 接口测试

找到一门课程进行删除,删除后从数据库确认课程基本信息、课程营销信息、课程计划、课程计划关联信息、课程师资是否删除成功。
当我们删除本机构课程时,会将课程对应的教师信息、课程计划、营销信息、课程基本信息均删除

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

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

相关文章

第2节、让电机转起来【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;本节介绍用简单的方式&#xff0c;让步进电机转起来。其目的之一是对电机转动有直观的感受&#xff0c;二是熟悉整个开发流程。本系列教程必要的51单片机基础包括IO口操作、中断、定时器三个部分&#…

2020年通信工程师初级 综合能力 真题

文章目录 第1章 通信职业道德&#xff0c;1-4第2章 法律法规&#xff0c;5-16第3章 计算机应用基础&#xff0c;第5章 现代通信网&#xff0c;38英语题&#xff0c;91 第1章 通信职业道德&#xff0c;1-4 1、职业道德在形式上具有()特点。 A.一致性 B.统一性 C.多样性 D.一般性…

基于SpringBoot+Vue的外卖点餐管理系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

人生,总要读几本好书!

以前&#xff0c;没有重视过读书的重要性 但是自从进入老马的陪伴群之后&#xff0c;听了老马的一路成长经历&#xff0c;才发现&#xff0c;所谓的一鸣惊人&#xff0c;都是厚积薄发的表现 大佬们在出人头地之前&#xff0c;都是有过很长一段时间的自我提升的 这个提升的方…

如何利用边缘计算网关进行机床数据采集,以提高数据采集的效率和准确性-天拓四方

边缘计算网关集成了数据采集、处理和传输功能的嵌入式设备。它位于传感器和执行器组成的设备层与云计算平台之间&#xff0c;能够实时处理和响应本地设备的数据请求&#xff0c;减轻云平台的压力&#xff0c;提高数据处理的速度和效率。同时&#xff0c;边缘计算网关还可以将处…

Qt 的安装以及项目的创建

目录 Qt简介Qt 开发环境安装的过程环境变量的配置Qt SDK 中的重要的工具创建一个 Qt 项目 Qt简介 开始安装教程前&#xff0c;首先来了解一下什么是QT。 QT&#xff08;Quick Thought&#xff09;是一个基于Qt库的快速应用程序开发框架。它提供了一套完整的开发工具和库&…

DataX详解和架构介绍

系列文章目录 一、 DataX详解和架构介绍 二、 DataX源码分析 JobContainer 三、DataX源码分析 TaskGroupContainer 四、DataX源码分析 TaskExecutor 五、DataX源码分析 reader 六、DataX源码分析 writer 七、DataX源码分析 Channel 文章目录 系列文章目录DataX是什么&#xff…

spring boot(2.4.x之前版本)和spring cloud项目中配置文件的作用

为了防止理解问题&#xff0c;pom.xml 版本依赖如下 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!--…

【开源】SpringBoot框架开发城市桥梁道路管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询城市桥梁4.2 新增城市桥梁4.3 编辑城市桥梁4.4 删除城市桥梁4.5 查询单个城市桥梁 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的城市桥梁道路管理系统&#xff0c;支持…

结构体的特殊声明和自引用

结构体的特殊声明 结构体我们通常是这么声明的&#xff1a; struct Student { char name[20]; int age; int num; }; 或者 struct Student { char name[20]; int age; int num; }s1, s2; 这是我们正常的声明方式&#xff0c; 也是正规的声明方式&#xff0c; 第二…

第三百一十一回

文章目录 1. 概念介绍2. 使用方法3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何在输入框中提示错误"相关的内容&#xff0c;本章回中将介绍如何在输入框中处理光标.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在使用TextField组件作为…

【亿级数据专题】「高并发架构」盘点本年度探索对外服务的百万请求量的高可靠消息服务设计实现

盘点本年度探索对外服务的百万请求量的高可靠消息服务设计实现 前提回顾消息服务逻辑架构运作流程消息路由系统数据存储系统BitCask结构异地存储容灾 推送系统数据消费模式推、拉模式的切换 实现低延时推送快速确认消息三层存储结构HeapMemoryDirectMemory 总结和展望 前提回顾…

【Mybatis】从0学习Mybatis(2)

前言 本篇文章是从0学习Mybatis的第一篇文章&#xff0c;由于篇幅太长CSDN会限流&#xff0c;因此我打算分开两期来写&#xff0c;这是第二期&#xff01;第一期在这儿&#xff1a;【Mybatis】从0学习Mybatis&#xff08;1&#xff09;-CSDN博客 1.什么是ResultMap结果映射&am…

力扣热门100题 - 5.最长回文子串

力扣热门100题 - 5.最长回文子串 题目描述&#xff1a;示例&#xff1a;提示&#xff1a;解题思路&#xff1a;&#xff08;动态规划&#xff09;代码&#xff1a; 题目链接&#xff1a;5. 最长回文子串 题目描述&#xff1a; 给你一个字符串 s&#xff0c;找到 s 中最长的回…

Python爬虫requests库详解

使用 requests 上一节中&#xff0c;我们了解了 urllib 的基本用法&#xff0c;但是其中确实有不方便的地方&#xff0c;比如处理网页验证和 Cookies 时&#xff0c;需要写 Opener 和 Handler 来处理。为了更加方便地实现这些操作&#xff0c;就有了更为强大的库 requests&…

「HarmonyOS」CustomDialogController自定义弹窗使用方法

需求背景&#xff1a; 在开发的过程中&#xff0c;总会遇到一些功能需要使用到弹窗进行信息的输入和修改&#xff0c;如用户个人信息的修改&#xff1b;在UI设计上每个App通常都会有各自的样式&#xff0c;而不是使用系统的标准样式&#xff0c;所以通常我们需要进行自定义弹窗…

TryHackMe-Net Sec Challenge练习

本文相关的TryHackMe实验房间链接&#xff1a;TryHackMe | Why Subscribe nmap nmap -T5 -p- 10.10.90.32 -T5 扫描速度 -p- 全端口扫描 答题&#xff1a; 这题叫我们找藏在http服务下的flag&#xff0c;根据上面扫出来的端口&#xff0c;所以我们开始搞80 这里简单介绍一下…

2.6 假期作业

分布编译 -ESc iso 1.预处理:头文件展开&#xff0c;宏替换&#xff0c;删除注释&#xff0c;不会查找语法错误 例&#xff1a;gcc -E 1.c -o 1.i 2.编译&#xff1a;生成汇编文件&#xff0c;会查找语法错误 例&#xff1a;gcc -S 1.i -o 1.s 3.汇编&#xff1a;生成二…

亚马逊认证考试系列 - 知识点 - LightSail介绍

一、引言 在当今云计算的时代&#xff0c;亚马逊网络服务&#xff08;AWS&#xff09;已成为业界领先的云服务提供商。其中&#xff0c;LightSail服务是AWS为简化云计算的入门和使用而推出的一项服务。它特别适合那些想要快速搭建网站、开发环境或小型应用的用户。通过LightSa…

代码随想录算法训练营第二八天 | 分割 子集

目录 复原IP地址子集子集 II LeetCode 93.复原IP地址 LeetCode 78.子集 LeetCode 90.子集II 复原IP地址 一些字符串的基本操作不会 s.insert(i 1, ‘.’); s.deleteCharAt(i 1); class Solution {List<String> result new ArrayList<>();public List<St…