07-学成在线修改/查询课程的基本信息和营销信息

修改/查询单个课程信息

界面原型

第一步: 用户进入课程列表查询页面,点击编辑按钮编辑课程的相关信息

在这里插入图片描述

第二步: 进入编辑界面显示出当前编辑课程的信息,其中课程营销信息不是必填项,修改成功后会自动进入课程计划编辑页面

在这里插入图片描述

查询课程信息

请求/响应数据模型

使用Http Client测试,根据课程Id查询课程信息,查询结果为单条课程信息对象CourseBaseInfoDto

// 根据课程Id查询课程信息
GET {{content_host}}/content/course/22
Content-Type: application/json

根据查询的响应结果定义对应的响应模型类CourseBaseInfoDto,由于其大部分信息来自课程基本信息表,所以我们可以将定义的响应结果模型类继承CourseBase

  • 大分类名称和小分类名称来自于课程分类表,需要根据请求参数中携带的大分类Id和小分类Id从数据库中获取
// 响应结果
HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Sat, 04 Feb 2023 07:06:22 GMT
Keep-Alive: timeout=60
Connection: keep-alive
    
{
  "id": 22,
  "companyId": 1232141425,
  "companyName": null,
  "name": "大数据2",
  "users": "具有一定的java基础",
  "tags": null,
  "mt": "1-6",
  "st": "1-6-1",
  "grade": "200001",
  "teachmode": "200002",
  "description": "111111大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据大数据",
  "pic": "https://cdn.educba.com/academy/wp-content/uploads/2018/08/Spring-BOOT-Interview-questions.jpg",
  "createDate": "2019-09-04 09:56:19",
  "changeDate": "2022-09-16 07:59:57",
  "createPeople": null,
  "changePeople": null,
  "auditStatus": "202001",
  "status": "203001",
  "charge": "201001",
  "price": 11.0,
  "originalPrice": 1111.0,
  "qq": "334455",
  "wechat": "223321",
  "phone": "1333333",
  "validDays": 33,
  "mtName": "云计算/大数据",
  "stName": "Spark"
}

查询课程基本/营销信息

第一步: 在api工程中定义接口,根据课程Id查询课程信息

@ApiOperation("根据课程id查询课程基础信息")
@GetMapping("/course/{courseId}")
public CourseBaseInfoDto getCourseBaseById(@PathVariable Long courseId) {
    return courseBaseInfoService.getCourseBaseInfo(courseId);
}

第二步: 在service工程中编写service接口及其实现类,将新增课程时实现的方法getCourseBaseInfo声明为Service接口的方法

/**
 * 根据课程id查询课程基本信息
 * @param courseId  课程id
 * @return
 */
CourseBaseInfoDto getCourseBaseInfo(Long courseId);
public interface CourseBaseInfoService {
    CourseBaseInfoDto getCourseBaseInfo(Long courseId);
}

private CourseBaseInfoDto getCourseBaseInfo(Long courseId) {
    // 创建CourseBaseInfoDto对象
    CourseBaseInfoDto courseBaseInfoDto = new CourseBaseInfoDto();
    // 1. 根据课程id查询课程基本信息
    CourseBase courseBase = courseBaseMapper.selectById(courseId);
    if (courseBase == null)
        return null;
    // 1.1 拷贝属性
    BeanUtils.copyProperties(courseBase, courseBaseInfoDto);
    // 2. 根据课程id查询课程营销信息
    CourseMarket courseMarket = courseMarketMapper.selectById(courseId);
    // 2.1 拷贝属性
    if (courseMarket != null)
        BeanUtils.copyProperties(courseMarket, courseBaseInfoDto);
    // 3. 查询课程分类名称并封装到到CourseBaseInfoDto对象中
    // 3.1 根据小分类id(1-1-1)查询对应的课程分类对象
    CourseCategory courseCategoryBySt = courseCategoryMapper.selectById(courseBase.getSt());
    // 3.2 设置课程的小分类名称
    courseBaseInfoDto.setStName(courseCategoryBySt.getName());
    // 3.3 根据大分类id(1-1)查询对应的课程分类对象
    CourseCategory courseCategoryByMt = courseCategoryMapper.selectById(courseBase.getMt());
    // 3.4 设置课程大分类名称
    courseBaseInfoDto.setMtName(courseCategoryByMt.getName());
    // 返回CourseBaseInfoDto对象
    return courseBaseInfoDto;
}

修改课程信息

请求/响应数据模型

根据课程Id修改课程信息,根据请求参数定义对应的请求模型类EditCourseDto中

PUT /content/course
Content-Type: application/json
// 将请求参数封装到EditCourseDto对象中
{
    "id": 40,
    "companyName": null,
    "name": "SpringBoot核心",
    "users": "Spring Boot初学者",
    "tags": "Spring项目的快速构建",
    "mt": "1-3",
    "st": "1-3-2",
    "grade": "200003",
    "teachmode": "201001",
    "description": "课程系统性地深度探讨 Spring Boot 核心特性,引导小伙伴对 Java 规范的重视,启发对技术原理性的思考,掌握排查问题的技能,以及学习阅读源码的方法和技巧,全面提升研发能力,进军架构师队伍。",
    "pic": "https://cdn.educba.com/academy/wp-content/uploads/2018/08/Spring-BOOT-Interview-questions.jpg",
    "charge": "201001",
    "price": 0.01
}

修改课程信息时比新增课程多了课程Id,因为需要根据课程id去数据库中更新课程基本信息表和课程营销表中对应的信息并保存数据

@Data
@ApiModel(value = "EditCourseDto", description = "修改课程基本信息")
public class EditCourseDto extends AddCourseDto{
    @ApiModelProperty(value = "课程id", required = true)
    private Long id;
}

根据响应结果定义对应的响应模型类CourseBaseInfoDto

// 修改成功的响应结果是一个CourseBaseInfoDto对象
{
    "id": 40,
    "companyId": 1232141425,
    "companyName": null,
    "name": "SpringBoot核心",
    "users": "Spring Boot初学者",
    "tags": "Spring项目的快速构建",
    "mt": "1-3",
    "mtName": null,
    "st": "1-3-2",
    "stName": null,
    "grade": "200003",
    "teachmode": "201001",
    "description": "课程系统性地深度探讨 Spring Boot 核心特性,引导小伙伴对 Java 规范的重视,启发对技术原理性的思考,掌握排查问题的技能,以及学习阅读源码的方法和技巧,全面提升研发能力,进军架构师队伍。",
    "pic": "https://cdn.educba.com/academy/wp-content/uploads/2018/08/Spring-BOOT-Interview-questions.jpg",
    "createDate": "2019-09-10 16:05:39",
    "changeDate": "2022-09-09 07:27:48",
    "createPeople": null,
    "changePeople": null,
    "auditStatus": "202004",
    "status": "203001",
    "coursePubId": 21,
    "coursePubDate": null,
    "charge": "201001",
    "price": 0.01
}

修改课程基本/营销信息

第一步: 在api工程中定义接口,将修改后的json格式的课程基本/营销信息保存到对应的课程信息表和课程营销表

@ApiOperation("修改课程基础信息接口")
@PutMapping("/course")
public CourseBaseInfoDto modifyCourseBase(@RequestBody EditCourseDto editCourseDto) {
    Long companyId = 22L;
    return courseBaseInfoService.updateCourseBase(companyId, editCourseDto);
}

第二步: 编写Service接口CourseBaseInfoService及其实现类CourseBaseInfoServiceImpl

/**
     * 修改课程信息
     * @param companyId 机构id,本机构只能修改本机构课程
     * @return
     */
CourseBaseInfoDto updateCourseBase(Long companyId, EditCourseDto editCourseDto);

第三步: 这里需要使用MP中IService提供的saveOrUpdate方法,然后注入到CourseBaseInfoServiceImpl

public interface CourseMarketService extends IService<CourseMarket> {   
}

@Service
public class CourseMarketServiceImpl extends ServiceImpl<CourseMarketMapper, CourseMarket> implements CourseMarketService {
}
// 操作course_market
@Autowired
CourseMarketService courseMarketService;

/**
* 修改课程信息
* @param companyId 机构id,本机构只能修改本机构课程
* @return
*/
@Override
@Transactional
public CourseBaseInfoDto updateCourseBase(Long companyId, EditCourseDto editCourseDto) {
    // 1.判断当前要修改课程的是否属于当前机构
    Long courseId = editCourseDto.getId();
    // 根据课程Id获取修改课程在数据库中对应的课程基本信息对象
    CourseBase courseBase = courseBaseMapper.selectById(courseId);    
    // 校验课程id
    if (courseBase == null){
        XueChengException.cast("课程不存在");
    }
    // 校验机构与课程是否对应
    if (!companyId.equals(courseBase.getCompanyId())) {
        XueChengPlusException.cast("只允许修改本机构的课程");
    }
    // 2.将请求参数中封装的课程基本信息拷贝到courseBase对象中
    BeanUtils.copyProperties(editCourseDto, courseBase);
    // 设置课程基本信息的更新时间
    courseBase.setChangeDate(LocalDateTime.now());
    // 将修改后的课程基本信息对象保存到数据库
    courseBaseMapper.updateById(courseBase);
    // 3.根据课程Id获取修改课程在数据库中对应的课程营销信息对象
    CourseMarket courseMarket = courseMarketMapper.selectById(courseId);
    // 由于课程营销信息不是必填项,故这里先判断一下
    if (courseMarket == null) {
        // 如果没有课程营销信息创建并设置为当前课程的Id,如果有课程营销信息那么它的Id一定是课程Id(我们就是根据课程Id查的)
        courseMarket = new CourseMarket();
        courseMarket.setId(courseId);
    }
    // 4.将请求参数中封装的课程营销信息拷贝到courseMarket对象中
    BeanUtils.copyProperties(editCourseDto, courseMarket);
    // 将修改后的课程营销信息对象保存到数据库并对价格进行校验
    int insert = saveCourseMarket(courseMarket);   
    // 5.查询更新后的课程基本信息和营销信息并封装到CourseBaseInfoDto对象中,然后返回给前端
    return getCourseBaseInfo(courseId);
}

第四步: 在新增课程和修改课程中都对课程营销信息进行了保存,并且都校验了课程营销信息的价格字段,所以可以将这部分代码进行抽取

/**
     * @description 保存营销信息的校验
     * @param courseMarket 营销信息
     * @return
     * @author xiaoming
     * @date 2023/1/21 21:46
    */
private int saveCourseMarket(CourseMarket courseMarket) {
    // 获取课程收费状态并设置
    String charge = courseMarket.getCharge();
    if(StringUtils.isBlank(charge)){
        XueChengException.cast("请设置收费规则");
    }
    // 如果课程收费,则判断价格是否正常
    if(charge.equals("201001")){
        Float price = courseMarket.getPrice();
        Float originalPrice = courseMarket.getOriginalPrice();
        if(originalPrice == null || originalPrice <= 0 || price == null || price.floatValue() <= 0){
            XueChengException.cast("课程设置了收费价格不能为空且必须大于0");
        }
    }
    // 如果课程免费,则判断价格是否正常
    if (charge.equals("201000")){
        Float price = courseMarket.getPrice();
        Float originalPrice = courseMarket.getOriginalPrice();
        if((originalPrice != null && originalPrice != 0) || (price != null && price.floatValue() != 0)){
            XueChengException.cast("课程设置了免费,请勿添加金额");
        }
        courseMarket.setPrice(0f);
        courseMarket.setOriginalPrice(0f);
    }
    // 由于添加课程时课程营销信息不是必填项,所以应该是课程营销信息表中有则更新无则插入
    boolean flag = courseMarketService.saveOrUpdate(courseMarket);
    return flag ? 1 : -1;
}

使用BaseMapper提供的方法实现有则更新无则插入

// 操作course_market
@Autowired
CourseMarketService courseMarketService;

/**
* 修改课程信息
* @param companyId 机构id,本机构只能修改本机构课程
* @return
*/
@Override
@Transactional
public CourseBaseInfoDto updateCourseBase(Long companyId, EditCourseDto editCourseDto) {
    // 1.判断当前要修改课程的是否属于当前机构
    Long courseId = editCourseDto.getId();
    // 根据课程Id获取修改课程在数据库中对应的课程基本信息对象
    CourseBase courseBase = courseBaseMapper.selectById(courseId);
    if (!companyId.equals(courseBase.getCompanyId())) {
        XueChengPlusException.cast("只允许修改本机构的课程");
    }
    // 2.将请求参数中封装的课程基本信息拷贝到courseBase对象中
    BeanUtils.copyProperties(editCourseDto, courseBase);
    // 设置课程基本信息的更新时间
    courseBase.setChangeDate(LocalDateTime.now());
    // 将修改后的课程基本信息对象保存到数据库
    courseBaseMapper.updateById(courseBase);
    // 3.根据课程Id获取修改课程在数据库中对应的课程营销信息对象
    CourseMarket courseMarketNew = new CourseMarket();
    BeanUtils.copyProperties(editCourseDto, courseMarketNew);
    CourseMarket courseMarket = courseMarketMapper.selectById(courseId);
    // 从数据库查询营销信息,存在则更新不存在则添加
    if(courseMarket == null){
        // 插入数据库
        int insert = courseMarketMapper.insert(courseMarketNew);
        return insert;
    }else{
        // 将courseMarketNew拷贝到courseMarket
        BeanUtils.copyProperties(courseMarketNew,courseMarket);
        courseMarket.setId(courseMarketNew.getId());
        // 更新
        int i = courseMarketMapper.updateById(courseMarket);
        return i;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

89基于matlab的人工蜂群和粒子群混合优化的路径规划算法

基于matlab的人工蜂群和粒子群混合优化的路径规划算法&#xff0c;起点和终点确定的前提下&#xff0c;在障碍物中寻找最佳路径。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 89人工蜂群和粒子群混合优化 (xiaohongshu.com)https://www.xiaohongshu.com/e…

【Vue】绝了!这生命周期流程真...

hello&#xff0c;我是小索奇&#xff0c;精心制作的Vue系列持续发放&#xff0c;涵盖大量的经验和示例&#xff0c;如果对您有用&#xff0c;可以点赞收藏哈~ 生命周期 Vue.js 组件生命周期&#xff1a; 生命周期函数&#xff08;钩子&#xff09;就是给我们提供了一些特定的…

Android flutter项目 启动优化实战(二)利用 App Startup 优化项目和使用flutterboost中的问题解决

背景 书接上回&#xff1a; Android flutter项目 启动优化实战&#xff08;一&#xff09;使用benchmark分析项目 已经分析出了问题: 1.缩短总时长&#xff08;解决黑屏问题、懒启动、优化流程&#xff09;、2.优化启动项&#xff08;使用App Startup&#xff09;、3.提升用…

java基础-IO

1、基础概念 1.1、文件(File) 文件的读写可以说是开发中必不可少的部分&#xff0c;因为系统会存在大量处理设备上的数据&#xff0c;这里的设备指硬盘&#xff0c;内存&#xff0c;键盘录入&#xff0c;网络传输等。当然这里需要考虑的问题不仅仅是实现&#xff0c;还包括同步…

【问题系列】消费者与MQ连接断开问题解决方案(一)

1. 问题描述 当使用RabbitMQ作为中间件&#xff0c;而消费者为服务时&#xff0c;可能会出现以下情况&#xff1a;在长时间没有消息传递后&#xff0c;消费者与RabbitMQ之间出现连接断开&#xff0c;导致无法处理新消息。解决这一问题的方法是重启Python消费者服务&#xff0c;…

redis运维(二十二)redis 的扩展应用 lua(四)

一 最佳实践 ① 铺垫 最佳实践&#xff1a;1、把redis操作所需的key通过KEYS进行参数传递2、其它的lua脚本所需的参数通过ARGV进行传递. redis lua脚本原理 Redis Lua脚本的执行原理 ② 删除指定的脚本缓存 ③ redis集群模式下使用lua脚本注意事项 1、常见报错现象 C…

草图大师sketchup道路怎么快速种树?

草图大师sketchup道路怎么快速种树&#xff1f;草图大师中的道路图纸想要在道路两旁种树&#xff0c;该怎么快速给道路种树呢&#xff1f;下面我们就来看看详细的教程&#xff0c;需要的朋友可以参考下 草图大师sketchup中想要快速种树&#xff0c;该怎么种多棵树呢&#xff1…

别太担心,人类只是把一小部分理性和感性放到了AI里

尽管人工智能&#xff08;AI&#xff09;在许多方面已经取得了重大进展&#xff0c;但它仍然无法完全复制人类的理性和感性。AI目前主要侧重于处理逻辑和分析任务&#xff0c;而人类则具有更复杂的思维能力和情感经验。 人类已经成功地将一些可以数据化和程序化的理性和感性特征…

JavaEE进阶学习:Bean 作用域和生命周期

1.Bean 作用域 .通过一个案例来看 Bean 作用域的问题 假设现在有一个公共的 Bean&#xff0c;提供给 A 用户和 B 用户使用&#xff0c;然而在使用的途中 A 用户却“悄悄”地修改了公共 Bean 的数据&#xff0c;导致 B 用户在使用时发生了预期之外的逻辑错误。 我们预期的结果…

leaflet对线设置渐变色

效果展示&#xff1a; 引用leaflet-polycolor组件 npm install leaflet-polycolor .vue文件中使用 import leafletPolycolor from leaflet-polycolor; leafletPolycolor(L); const latLngs [[37.03, 111.92], [37.53444, 111.98555], [36.88, 112.12], [37.53444, 112.24], […

Redis深入理解-主从架构下内核数据结构、主从同步以及主节点选举

Redis 主从挂载后的内核数据结构分析 主节点中&#xff0c;会通过 clusteNode 中的 slaves 来记录该主节点包含了哪些从节点&#xff0c;这个 slaves 是一个指向 *clusterNode[] 数组的数据结构从节点中&#xff0c;会通过 clusterNode 中的 slaveof 来记录该从节点属于哪个主…

04_Flutter自定义Slider滑块

04_Flutter自定义Slider滑块 一.Slider控件基本用法 Column(mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[Text("sliderValue: ${_sliderValue.toInt()}"),Slider(value: _sliderValue,min: 0,max: 100,divisions: 10,thumbColor: Colors.…

《微信小程序开发从入门到实战》学习三十四

4.2 云开发JSON数据库 MySQL、Oracle之类的“关系型数据库”。JSON数据库是“非关系型数据库”&#xff0c;没有行表列的概念。 4.2.1 JSON数据库基本概念 集合:一个数据库有多个集合&#xff0c;一个集合存储通常是同一类数据&#xff0c;可看作为JSON数组&#xff0c;数组…

webpack具体实现--未完

1、前端模块打包工具webpack webpack 是 Webpack 的核心模块&#xff0c;webpack-cli 是 Webpack 的 CLI 程序&#xff0c;用来在命令行中调用 Webpack。webpack-cli 所提供的 CLI 程序就会出现在 node_modules/.bin 目录当中&#xff0c;我们可以通过 npx 快速找到 CLI 并运行…

Chrome 访问不了项目?10080端口 ERR_UNSAFE_PORT:问题原因 / 解决方案

文章目录 被禁用端口列表解决方法方法一、更换端口 / 使用代理 / 使用域名方法二、对浏览器下手WindowsMac 最近有客户反馈&#xff0c;在chrome浏览器中访问不了项目&#xff0c;其他浏览器都是正常的。 &#xff1f;奇了怪了&#xff0c;难道客户对chrome做了什么操作&#x…

Asp.net core WebApi 配置自定义swaggerUI和中文注释

1.创建asp.net core webApi项目 默认会引入swagger的Nuget包 <PackageReference Include"Swashbuckle.AspNetCore" Version"6.2.3" />2.配置基本信息和中文注释&#xff08;默认是没有中文注释的&#xff09; 2.1创建一个新的controller using Micr…

直接插入排序和希尔排序

前言 我们前面几期介绍了线性和非线性的基本数据结构。例如顺序表、链表、栈和队列、二叉树等~&#xff01;本期和接下来的几期我们来详解介绍各个排序的概念、实现以及性能分析&#xff01; 本期内容 排序的概念以及其运用 常见的排序算法 直接插入排序 希尔排序 一、排序的…

Leetcode算法系列| 3. 无重复字符的最长子串

目录 1.题目2.题解C# 解法一&#xff1a;滑动窗口算法C# 解法二&#xff1a;索引寻找Java 解法一&#xff1a;滑动窗口算法Java 解法二&#xff1a;遍历字符串 1.题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例1: 输入: s "ab…

力扣141-环形链表

文章目录 力扣141-环形链表示例代码实现要点剖析 力扣141-环形链表 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测…

源码剖析 Spring Security 的实现原理

Spring Security 是一个轻量级的安全框架&#xff0c;可以和 Spring 项目很好地集成&#xff0c;提供了丰富的身份认证和授权相关的功能&#xff0c;而且还能防止一些常见的网络攻击。我在工作中有很多项目都使用了 Spring Security 框架&#xff0c;但基本上都是浅尝辄止&…